#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:

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) |
| Octstr * | store_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 |
| Octstr * | filename = NULL |
| Octstr * | newfile = NULL |
| Octstr * | bakfile = NULL |
| Mutex * | file_mutex = NULL |
| long | cleanup_thread = -1 |
| long | dump_frequency = 0 |
| Dict * | sms_dict = NULL |
| int | active = 1 |
| time_t | last_dict_mod = 0 |
| List * | loaded |
|
|
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:

|
|
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:

|
||||||||||||||||
|
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:

|
|
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:

|
|
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:

|
|
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:

|
||||||||||||
|
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:

|
|
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:

|
|
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:

|
|
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:

|
||||||||||||
|
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:

|
|
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:

|
|
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:

|
|
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:

|
|
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:

|
|
Definition at line 97 of file bb_store_file.c. Referenced by store_file_init(), and store_file_shutdown(). |
|
|
Definition at line 90 of file bb_store_file.c. Referenced by rename_store(), store_dumper(), store_file_init(), and store_file_load(). |
|
|
Definition at line 92 of file bb_store_file.c. Referenced by store_file_load(), and store_file_shutdown(). |
|
|
Definition at line 93 of file bb_store_file.c. Referenced by store_dumper(), and store_file_init(). |
|
|
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(). |
|
|
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(). |
|
|
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(). |
|
|
Definition at line 98 of file bb_store_file.c. Referenced by store_dumper(), and store_to_dict(). |
|
|
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(). |
|
|
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(). |
|
|
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(). |