Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

bb_store_file.c File Reference

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include "gwlib/gwlib.h"
#include "msg.h"
#include "bearerbox.h"
#include "sms.h"

Include dependency graph for bb_store_file.c:

Include dependency graph

Go to the source code of this file.

Functions

void write_msg (Msg *msg)
int read_msg (Msg **msg, Octstr *os, long *off)
int open_file (Octstr *name)
int rename_store (void)
int do_dump (void)
void store_dumper (void *arg)
Octstrstore_file_status (int status_type)
long store_file_messages (void)
int store_to_dict (Msg *msg)
int store_file_save (Msg *msg)
int store_file_save_ack (Msg *msg, ack_status_t status)
int store_file_load (void(*receive_msg)(Msg *))
int store_file_dump (void)
void store_file_shutdown (void)
int store_file_init (const Octstr *fname, long dump_freq)

Variables

FILE * file = NULL
Octstrfilename = NULL
Octstrnewfile = NULL
Octstrbakfile = NULL
Mutexfile_mutex = NULL
long cleanup_thread = -1
long dump_frequency = 0
Dictsms_dict = NULL
int active = 1
time_t last_dict_mod = 0
Listloaded


Function Documentation

int do_dump void   )  [static]
 

Definition at line 176 of file bb_store_file.c.

References dict_get(), dict_keys(), file, filename, gwlist_destroy(), gwlist_get(), gwlist_len(), newfile, octstr_destroy_item(), open_file(), rename_store(), sms_dict, and write_msg().

Referenced by store_file_dump(), and store_file_load().

00177 {
00178     Octstr *key;
00179     Msg *msg;
00180     List *sms_list;
00181     long l;
00182 
00183     if (filename == NULL)
00184         return 0;
00185 
00186     /* create a new store-file and save all non-acknowledged
00187      * messages into it
00188      */
00189     if (open_file(newfile)==-1)
00190         return -1;
00191 
00192     sms_list = dict_keys(sms_dict);
00193     for (l=0; l < gwlist_len(sms_list); l++) {
00194         key = gwlist_get(sms_list, l);
00195         msg = dict_get(sms_dict, key);
00196         if (msg != NULL)
00197             write_msg(msg);
00198     }
00199     fflush(file);
00200     gwlist_destroy(sms_list, octstr_destroy_item);
00201 
00202     /* rename old storefile as .bak, and then new as regular file
00203      * without .new ending */
00204 
00205     return rename_store();
00206 }

Here is the call graph for this function:

int open_file Octstr name  )  [static]
 

Definition at line 146 of file bb_store_file.c.

References error(), file, name, and octstr_get_cstr.

Referenced by do_dump(), and store_file_load().

00147 {
00148     file = fopen(octstr_get_cstr(name), "w");
00149     if (file == NULL) {
00150         error(errno, "Failed to open '%s' for writing, cannot create store-file",
00151           octstr_get_cstr(name));
00152         return -1;
00153     }
00154     return 0;
00155 }

Here is the call graph for this function:

int read_msg Msg **  msg,
Octstr os,
long *  off
[static]
 

Definition at line 118 of file bb_store_file.c.

References decode_network_long(), error(), gw_assert, octstr_copy, octstr_destroy(), octstr_get_many_chars(), octstr_len(), and store_msg_unpack.

Referenced by store_file_load().

00119 {
00120     unsigned char buf[4];
00121     long i;
00122     Octstr *pack;
00123 
00124     gw_assert(*off >= 0);
00125     if (*off + 4 > octstr_len(os)) {
00126         error(0, "Packet too short while unpacking Msg.");
00127         return -1;
00128     }
00129 
00130     octstr_get_many_chars((char*)buf, os, *off, 4);
00131     i = decode_network_long(buf);
00132     *off  +=  4;
00133     
00134     pack = octstr_copy(os, *off, i);
00135     *off += octstr_len(pack);
00136     *msg = store_msg_unpack(pack);
00137     octstr_destroy(pack);
00138     
00139     if (!*msg)
00140         return -1;
00141     
00142     return 0;
00143 }

Here is the call graph for this function:

int rename_store void   )  [static]
 

Definition at line 158 of file bb_store_file.c.

References bakfile, error(), filename, newfile, and octstr_get_cstr.

Referenced by do_dump().

00159 {
00160     if (rename(octstr_get_cstr(filename), octstr_get_cstr(bakfile)) == -1) {
00161         if (errno != ENOENT) {
00162             error(errno, "Failed to rename old store '%s' as '%s'",
00163             octstr_get_cstr(filename), octstr_get_cstr(bakfile));
00164             return -1;
00165         }
00166     }
00167     if (rename(octstr_get_cstr(newfile), octstr_get_cstr(filename)) == -1) {
00168         error(errno, "Failed to rename new store '%s' as '%s'",
00169               octstr_get_cstr(newfile), octstr_get_cstr(filename));
00170         return -1;
00171     }
00172     return 0;
00173 }

Here is the call graph for this function:

void store_dumper void *  arg  )  [static]
 

Definition at line 213 of file bb_store_file.c.

References bakfile, dict_destroy(), dump_frequency, file, file_mutex, filename, gwthread_sleep(), last_dict_mod, mutex_destroy(), newfile, octstr_destroy(), sms_dict, and store_dump.

Referenced by store_file_load().

00214 {
00215     time_t now;
00216     int busy = 0;
00217 
00218     while (active) {
00219         now = time(NULL);
00220         /*
00221          * write store to file up to each N. second, providing
00222          * that something happened or if we are constantly busy.
00223          */
00224         if (now - last_dict_mod > dump_frequency || busy) {
00225             store_dump();
00226             /* 
00227              * make sure that no new dump is done for a while unless
00228              * something happens. This moves the trigger in the future
00229              * and allows the if statement to pass if nothing happened
00230              * in the mean time while sleeping. The busy flag is needed
00231              * to garantee we do dump in case we are constantly busy
00232              * and hence the difference between now and last dict
00233              * operation is less then dump frequency, otherwise we
00234              * would never dump. This is for constant high load.
00235              */
00236             last_dict_mod = time(NULL) + 3600*24;
00237             busy = 0;
00238         } else {
00239             busy = (now - last_dict_mod) > 0;
00240         }
00241         gwthread_sleep(dump_frequency);
00242     }
00243     store_dump();
00244     if (file != NULL)
00245        fclose(file);
00246     octstr_destroy(filename);
00247     octstr_destroy(newfile);
00248     octstr_destroy(bakfile);
00249     mutex_destroy(file_mutex);
00250 
00251     dict_destroy(sms_dict);
00252     /* set all vars to NULL */
00253     filename = newfile = bakfile = NULL;
00254     file_mutex = NULL;
00255     sms_dict = NULL;
00256 }

Here is the call graph for this function:

int store_file_dump void   )  [static]
 

Definition at line 559 of file bb_store_file.c.

References debug(), dict_key_count(), do_dump(), file, file_mutex, mutex_lock, mutex_unlock, and sms_dict.

00560 {
00561     int retval;
00562 
00563     debug("bb.store", 0, "Dumping %ld messages to store",
00564       dict_key_count(sms_dict));
00565     mutex_lock(file_mutex);
00566     if (file != NULL) {
00567         fclose(file);
00568         file = NULL;
00569     }
00570     retval = do_dump();
00571     mutex_unlock(file_mutex);
00572 
00573     return retval;
00574 }

Here is the call graph for this function:

int store_file_init const Octstr fname,
long  dump_freq
 

Definition at line 592 of file bb_store_file.c.

References active, bakfile, dict_create(), dump_frequency, file_mutex, filename, gwlist_add_producer(), gwlist_create, loaded, msg_destroy_item(), mutex_create, newfile, octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_len(), panic, sms_dict, store_dump, store_load, store_messages, store_save, store_save_ack, store_shutdown, and store_status.

Referenced by store_init().

00593 {
00594     /* Initialize function pointers */
00595     store_messages = store_file_messages;
00596     store_save = store_file_save;
00597     store_save_ack = store_file_save_ack;
00598     store_load = store_file_load;
00599     store_dump = store_file_dump;
00600     store_shutdown = store_file_shutdown;
00601     store_status = store_file_status;
00602 
00603     if (fname == NULL)
00604         return 0; /* we are done */
00605 
00606     if (octstr_len(fname) > (FILENAME_MAX-5))
00607         panic(0, "Store file filename too long: `%s', failed to init.",
00608           octstr_get_cstr(fname));
00609 
00610     filename = octstr_duplicate(fname);
00611     newfile = octstr_format("%s.new", octstr_get_cstr(filename));
00612     bakfile = octstr_format("%s.bak", octstr_get_cstr(filename));
00613 
00614     sms_dict = dict_create(1024, msg_destroy_item);
00615 
00616     if (dump_freq > 0)
00617         dump_frequency = dump_freq;
00618     else
00619         dump_frequency = BB_STORE_DEFAULT_DUMP_FREQ;
00620 
00621     file_mutex = mutex_create();
00622     active = 1;
00623 
00624     loaded = gwlist_create();
00625     gwlist_add_producer(loaded);
00626 
00627     return 0;
00628 }

Here is the call graph for this function:

int store_file_load void(*)(Msg *)  receive_msg  )  [static]
 

Definition at line 460 of file bb_store_file.c.

References bakfile, cleanup_thread, dict_key_count(), dict_keys(), dict_remove(), do_dump(), error(), file, file_mutex, filename, gwlist_destroy(), gwlist_extract_first(), gwlist_remove_producer(), gwthread_create, info(), loaded, msg_destroy(), msg_dump(), msg_type, mutex_lock, mutex_unlock, newfile, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, octstr_len(), octstr_read_file(), open_file(), panic, read_msg(), sms_dict, store_dumper(), store_to_dict(), and warning().

00461 {
00462     List *keys;
00463     Octstr *store_file, *key;
00464     Msg *msg;
00465     int retval, msgs;
00466     long end, pos;
00467 
00468     if (filename == NULL)
00469         return 0;
00470 
00471     mutex_lock(file_mutex);
00472     if (file != NULL) {
00473         fclose(file);
00474         file = NULL;
00475     }
00476 
00477     store_file = octstr_read_file(octstr_get_cstr(filename));
00478     if (store_file != NULL)
00479         info(0, "Loading store file `%s'", octstr_get_cstr(filename));
00480     else {
00481         store_file = octstr_read_file(octstr_get_cstr(newfile));
00482         if (store_file != NULL)
00483             info(0, "Loading store file `%s'", octstr_get_cstr(newfile));
00484         else {
00485             store_file = octstr_read_file(octstr_get_cstr(bakfile));
00486             if (store_file != NULL)
00487                    info(0, "Loading store file `%s'", octstr_get_cstr(bakfile));
00488             else {
00489                 info(0, "Cannot open any store file, starting a new one");
00490                 retval = open_file(filename);
00491                 goto end;
00492             }
00493         }
00494     }
00495 
00496     info(0, "Store-file size %ld, starting to unpack%s", octstr_len(store_file),
00497         octstr_len(store_file) > 10000 ? " (may take awhile)" : "");
00498 
00499 
00500     pos = 0;
00501     msgs = 0;
00502     end = octstr_len(store_file);
00503     
00504     while (pos < end) {
00505         if (read_msg(&msg, store_file, &pos) == -1) {
00506             error(0, "Garbage at store-file, skipped.");
00507             continue;
00508         }
00509         if (msg_type(msg) == sms) {
00510             store_to_dict(msg);
00511             msgs++;
00512         } else if (msg_type(msg) == ack) {
00513             store_to_dict(msg);
00514         } else {
00515             warning(0, "Strange message in store-file, discarded, "
00516                 "dump follows:");
00517             msg_dump(msg, 0);
00518         }
00519         msg_destroy(msg);
00520     }
00521     octstr_destroy(store_file);
00522 
00523     info(0, "Retrieved %d messages, non-acknowledged messages: %ld",
00524         msgs, dict_key_count(sms_dict));
00525 
00526     /* now create a new sms_store out of messages left */
00527 
00528     keys = dict_keys(sms_dict);
00529     while ((key = gwlist_extract_first(keys)) != NULL) {
00530         msg = dict_remove(sms_dict, key);
00531         if (store_to_dict(msg) != -1) {
00532             receive_msg(msg);
00533         } else {
00534             error(0, "Found unknown message type in store file.");
00535             msg_dump(msg, 0);
00536             msg_destroy(msg);
00537         }
00538         octstr_destroy(key);
00539     }
00540     gwlist_destroy(keys, octstr_destroy_item);
00541 
00542     /* Finally, generate new store file out of left messages */
00543     retval = do_dump();
00544 
00545 end:
00546     mutex_unlock(file_mutex);
00547 
00548     /* allow using of store */
00549     gwlist_remove_producer(loaded);
00550 
00551     /* start dumper thread */
00552     if ((cleanup_thread = gwthread_create(store_dumper, NULL))==-1)
00553         panic(0, "Failed to create a cleanup thread!");
00554 
00555     return retval;
00556 }

Here is the call graph for this function:

long store_file_messages void   )  [static]
 

Definition at line 364 of file bb_store_file.c.

References dict_key_count(), and sms_dict.

00365 {
00366     return (sms_dict ? dict_key_count(sms_dict) : -1);
00367 }

Here is the call graph for this function:

int store_file_save Msg msg  )  [static]
 

Definition at line 409 of file bb_store_file.c.

References file, file_mutex, filename, gwlist_consume(), loaded, mutex_lock, mutex_unlock, store_to_dict(), and write_msg().

00410 {
00411     if (filename == NULL)
00412         return 0;
00413 
00414     /* block here until store not loaded */
00415     gwlist_consume(loaded);
00416 
00417     /* lock file_mutex in order to have dict and file in sync */
00418     mutex_lock(file_mutex);
00419     if (store_to_dict(msg) == -1) {
00420         mutex_unlock(file_mutex);
00421         return -1;
00422     }
00423     
00424     /* write to file, too */
00425     write_msg(msg);
00426     fflush(file);
00427     mutex_unlock(file_mutex);
00428 
00429     return 0;
00430 }

Here is the call graph for this function:

int store_file_save_ack Msg msg,
ack_status_t  status
[static]
 

Definition at line 433 of file bb_store_file.c.

References ack, filename, msg_create, msg_destroy(), msg_type, store_save, and uuid_copy().

00434 {
00435     Msg *mack;
00436     int ret;
00437 
00438     /* only sms are handled */
00439     if (!msg || msg_type(msg) != sms)
00440         return -1;
00441 
00442     if (filename == NULL)
00443         return 0;
00444 
00445     mack = msg_create(ack);
00446     if (!mack)
00447         return -1;
00448 
00449     mack->ack.time = msg->sms.time;
00450     uuid_copy(mack->ack.id, msg->sms.id);
00451     mack->ack.nack = status;
00452 
00453     ret = store_save(mack);
00454     msg_destroy(mack);
00455 
00456     return ret;
00457 }

Here is the call graph for this function:

void store_file_shutdown void   )  [static]
 

Definition at line 577 of file bb_store_file.c.

References active, cleanup_thread, filename, gwlist_destroy(), gwthread_join(), gwthread_wakeup(), and loaded.

00578 {
00579     if (filename == NULL)
00580         return;
00581 
00582     active = 0;
00583     gwthread_wakeup(cleanup_thread);
00584     /* wait for cleanup thread */
00585     if (cleanup_thread != -1)
00586         gwthread_join(cleanup_thread);
00587 
00588     gwlist_destroy(loaded, NULL);
00589 }

Here is the call graph for this function:

Octstr* store_file_status int  status_type  )  [static]
 

Definition at line 261 of file bb_store_file.c.

References DC_8BIT, DC_UCS2, DC_UNDEF, dict_get(), dict_keys(), filename, gw_gmtime(), gw_localtime(), gwlist_destroy(), gwlist_get(), gwlist_len(), mo, msg_type, mt_push, mt_reply, octstr_append_cstr(), octstr_binary_to_hex(), octstr_create, octstr_destroy_item(), octstr_format_append(), octstr_get_cstr, octstr_hex_to_binary(), report_mo, report_mt, sms_dict, UUID_STR_LEN, and uuid_unparse().

00262 {
00263     char *frmt;
00264     Octstr *ret, *key;
00265     unsigned long l;
00266     struct tm tm;
00267     Msg *msg;
00268     List *keys;
00269     char id[UUID_STR_LEN + 1];
00270 
00271     ret = octstr_create("");
00272 
00273     /* set the type based header */
00274     if (status_type == BBSTATUS_HTML) {
00275         octstr_append_cstr(ret, "<table border=1>\n"
00276             "<tr><td>SMS ID</td><td>Type</td><td>Time</td><td>Sender</td><td>Receiver</td>"
00277             "<td>SMSC ID</td><td>BOX ID</td><td>UDH</td><td>Message</td>"
00278             "</tr>\n");
00279     } else if (status_type == BBSTATUS_TEXT) {
00280         octstr_append_cstr(ret, "[SMS ID] [Type] [Time] [Sender] [Receiver] [SMSC ID] [BOX ID] [UDH] [Message]\n");
00281     }
00282    
00283     /* if there is no store-file, then don't loop in sms_store */
00284     if (filename == NULL)
00285         goto finish;
00286 
00287     keys = dict_keys(sms_dict);
00288 
00289     for (l = 0; l < gwlist_len(keys); l++) {
00290         key = gwlist_get(keys, l);
00291         msg = dict_get(sms_dict, key);
00292         if (msg == NULL)
00293             continue;
00294 
00295         if (msg_type(msg) == sms) {
00296 
00297             if (status_type == BBSTATUS_HTML) {
00298                 frmt = "<tr><td>%s</td><td>%s</td>"
00299                        "<td>%04d-%02d-%02d %02d:%02d:%02d</td>"
00300                        "<td>%s</td><td>%s</td><td>%s</td>"
00301                        "<td>%s</td><td>%s</td><td>%s</td></tr>\n";
00302             } else if (status_type == BBSTATUS_XML) {
00303                 frmt = "<message>\n\t<id>%s</id>\n\t<type>%s</type>\n\t"
00304                        "<time>%04d-%02d-%02d %02d:%02d:%02d</time>\n\t"
00305                        "<sender>%s</sender>\n\t"
00306                        "<receiver>%s</receiver>\n\t<smsc-id>%s</smsc-id>\n\t"
00307                        "<box-id>%s</box-id>\n\t"
00308                        "<udh-data>%s</udh-data>\n\t<msg-data>%s</msg-data>\n\t"
00309                        "</message>\n";
00310             } else {
00311                 frmt = "[%s] [%s] [%04d-%02d-%02d %02d:%02d:%02d] [%s] [%s] [%s] [%s] [%s] [%s]\n";
00312             }
00313 
00314             /* transform the time value */
00315 #if LOG_TIMESTAMP_LOCALTIME
00316             tm = gw_localtime(msg->sms.time);
00317 #else
00318             tm = gw_gmtime(msg->sms.time);
00319 #endif
00320             if (msg->sms.udhdata)
00321                 octstr_binary_to_hex(msg->sms.udhdata, 1);
00322             if (msg->sms.msgdata &&
00323                 (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 ||
00324                 (msg->sms.coding == DC_UNDEF && msg->sms.udhdata)))
00325                 octstr_binary_to_hex(msg->sms.msgdata, 1);
00326 
00327             uuid_unparse(msg->sms.id, id);
00328 
00329             octstr_format_append(ret, frmt, id,
00330                 (msg->sms.sms_type == mo ? "MO" :
00331                  msg->sms.sms_type == mt_push ? "MT-PUSH" :
00332                  msg->sms.sms_type == mt_reply ? "MT-REPLY" :
00333                  msg->sms.sms_type == report_mo ? "DLR-MO" :
00334                  msg->sms.sms_type == report_mt ? "DLR-MT" : ""),
00335                  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
00336                  tm.tm_hour, tm.tm_min, tm.tm_sec,
00337                 (msg->sms.sender ? octstr_get_cstr(msg->sms.sender) : ""),
00338                 (msg->sms.receiver ? octstr_get_cstr(msg->sms.receiver) : ""),
00339                 (msg->sms.smsc_id ? octstr_get_cstr(msg->sms.smsc_id) : ""),
00340                 (msg->sms.boxc_id ? octstr_get_cstr(msg->sms.boxc_id) : ""),
00341                 (msg->sms.udhdata ? octstr_get_cstr(msg->sms.udhdata) : ""),
00342                 (msg->sms.msgdata ? octstr_get_cstr(msg->sms.msgdata) : ""));
00343 
00344             if (msg->sms.udhdata)
00345                 octstr_hex_to_binary(msg->sms.udhdata);
00346             if (msg->sms.msgdata &&
00347                 (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 ||
00348                 (msg->sms.coding == DC_UNDEF && msg->sms.udhdata)))
00349                 octstr_hex_to_binary(msg->sms.msgdata);
00350         }
00351     }
00352     gwlist_destroy(keys, octstr_destroy_item);
00353 
00354 finish:
00355     /* set the type based footer */
00356     if (status_type == BBSTATUS_HTML) {
00357         octstr_append_cstr(ret,"</table>");
00358     }
00359 
00360     return ret;
00361 }

Here is the call graph for this function:

int store_to_dict Msg msg  )  [static]
 

Definition at line 370 of file bb_store_file.c.

References dict_put(), dict_remove(), last_dict_mod, msg_destroy(), msg_duplicate(), msg_type, octstr_create, octstr_destroy(), sms, sms_dict, uuid_generate(), uuid_is_null(), UUID_STR_LEN, uuid_unparse(), and warning().

Referenced by store_file_load(), and store_file_save().

00371 {
00372     Msg *copy;
00373     Octstr *uuid_os;
00374     char id[UUID_STR_LEN + 1];
00375     
00376     /* always set msg id and timestamp */
00377     if (msg_type(msg) == sms && uuid_is_null(msg->sms.id))
00378         uuid_generate(msg->sms.id);
00379 
00380     if (msg_type(msg) == sms && msg->sms.time == MSG_PARAM_UNDEFINED)
00381         time(&msg->sms.time);
00382 
00383     if (msg_type(msg) == sms) {
00384         copy = msg_duplicate(msg);
00385         
00386         uuid_unparse(copy->sms.id, id);
00387         uuid_os = octstr_create(id);
00388         
00389         dict_put(sms_dict, uuid_os, copy);
00390         octstr_destroy(uuid_os);
00391         last_dict_mod = time(NULL);
00392     } else if (msg_type(msg) == ack) {
00393         uuid_unparse(msg->ack.id, id);
00394         uuid_os = octstr_create(id);
00395         copy = dict_remove(sms_dict, uuid_os);
00396         octstr_destroy(uuid_os);
00397         if (copy == NULL) {
00398             warning(0, "bb_store: get ACK of message not found "
00399                    "from store, strange?");
00400         } else {
00401             msg_destroy(copy);
00402             last_dict_mod = time(NULL);
00403         }
00404     } else
00405         return -1;
00406     return 0;
00407 }

Here is the call graph for this function:

void write_msg Msg msg  )  [static]
 

Definition at line 102 of file bb_store_file.c.

References encode_network_long(), file, octstr_destroy(), octstr_insert_data(), octstr_len(), octstr_print(), and store_msg_pack.

Referenced by do_dump(), and store_file_save().

00103 {
00104     Octstr *pack;
00105     unsigned char buf[4];
00106     
00107     pack = store_msg_pack(msg);
00108     encode_network_long(buf, octstr_len(pack));
00109     octstr_insert_data(pack, 0, (char*)buf, 4);
00110 
00111     octstr_print(file, pack);
00112     fflush(file);
00113 
00114     octstr_destroy(pack);
00115 }

Here is the call graph for this function:


Variable Documentation

int active = 1 [static]
 

Definition at line 97 of file bb_store_file.c.

Referenced by store_file_init(), and store_file_shutdown().

Octstr* bakfile = NULL [static]
 

Definition at line 90 of file bb_store_file.c.

Referenced by rename_store(), store_dumper(), store_file_init(), and store_file_load().

long cleanup_thread = -1 [static]
 

Definition at line 92 of file bb_store_file.c.

Referenced by store_file_load(), and store_file_shutdown().

long dump_frequency = 0 [static]
 

Definition at line 93 of file bb_store_file.c.

Referenced by store_dumper(), and store_file_init().

FILE* file = NULL [static]
 

Definition at line 87 of file bb_store_file.c.

Referenced by do_dump(), open_file(), store_dumper(), store_file_dump(), store_file_load(), store_file_save(), and write_msg().

Mutex* file_mutex = NULL [static]
 

Definition at line 91 of file bb_store_file.c.

Referenced by store_dumper(), store_file_dump(), store_file_init(), store_file_load(), and store_file_save().

Octstr* filename = NULL [static]
 

Definition at line 88 of file bb_store_file.c.

Referenced by do_dump(), rename_store(), store_dumper(), store_file_init(), store_file_load(), store_file_save(), store_file_save_ack(), store_file_shutdown(), and store_file_status().

time_t last_dict_mod = 0 [static]
 

Definition at line 98 of file bb_store_file.c.

Referenced by store_dumper(), and store_to_dict().

List* loaded [static]
 

Definition at line 99 of file bb_store_file.c.

Referenced by store_file_init(), store_file_load(), store_file_save(), and store_file_shutdown().

Octstr* newfile = NULL [static]
 

Definition at line 89 of file bb_store_file.c.

Referenced by do_dump(), rename_store(), store_dumper(), store_file_init(), and store_file_load().

Dict* sms_dict = NULL [static]
 

Definition at line 95 of file bb_store_file.c.

Referenced by do_dump(), store_dumper(), store_file_dump(), store_file_init(), store_file_load(), store_file_messages(), store_file_status(), and store_to_dict().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.