📄 bb_store.c
字号:
(msg->sms.sms_type == mo ? "MO" : msg->sms.sms_type == mt_push ? "MT-PUSH" : msg->sms.sms_type == mt_reply ? "MT-REPLY" : msg->sms.sms_type == report_mo ? "DLR-MO" : msg->sms.sms_type == report_mt ? "DLR-MT" : ""), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (msg->sms.sender ? octstr_get_cstr(msg->sms.sender) : ""), (msg->sms.receiver ? octstr_get_cstr(msg->sms.receiver) : ""), (msg->sms.smsc_id ? octstr_get_cstr(msg->sms.smsc_id) : ""), (msg->sms.boxc_id ? octstr_get_cstr(msg->sms.boxc_id) : ""), (msg->sms.udhdata ? octstr_get_cstr(msg->sms.udhdata) : ""), (msg->sms.msgdata ? octstr_get_cstr(msg->sms.msgdata) : "")); if (msg->sms.udhdata) octstr_hex_to_binary(msg->sms.udhdata); if (msg->sms.msgdata && (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 || (msg->sms.coding == DC_UNDEF && msg->sms.udhdata))) octstr_hex_to_binary(msg->sms.msgdata); } } list_unlock(sms_store);finish: /* set the type based footer */ if (status_type == BBSTATUS_HTML) { octstr_append_cstr(ret,"</table>"); } return ret;}long store_messages(void){ return (sms_store ? list_len(sms_store) : -1);}int store_save(Msg *msg){ Msg *copy; /* always set msg id and timestamp */ if (msg_type(msg) == sms && uuid_is_null(msg->sms.id)) uuid_generate(msg->sms.id); if (msg_type(msg) == sms && msg->sms.time == MSG_PARAM_UNDEFINED) time(&msg->sms.time); if (filename == NULL) return 0; if (msg_type(msg) == sms) { copy = msg_duplicate(msg); list_produce(sms_store, copy); } else if (msg_type(msg) == ack) { copy = msg_duplicate(msg); list_produce(ack_store, copy); } else return -1; /* write to file, too */ mutex_lock(file_mutex); write_msg(msg); fflush(file); mutex_unlock(file_mutex); return 0;}int store_save_ack(Msg *msg, ack_status_t status){ Msg *mack; /* only sms are handled */ if (!msg || msg_type(msg) != sms) return -1; if (filename == NULL) return 0; mack = msg_create(ack); if (!mack) return -1; mack->ack.time = msg->sms.time; uuid_copy(mack->ack.id, msg->sms.id); mack->ack.nack = status; /* write to file */ mutex_lock(file_mutex); write_msg(mack); mutex_unlock(file_mutex); list_produce(ack_store, mack); return 0;}int store_load(void){ List *keys; Octstr *store_file, *pack, *key; Dict *msg_hash; Msg *msg, *dmsg, *copy; int retval, msgs; long end, pos; long store_size; char id[UUID_STR_LEN + 1]; if (filename == NULL) return 0; list_lock(ack_store); list_lock(sms_store); while((msg = list_extract_first(sms_store))!=NULL) msg_destroy(msg); while((msg = list_extract_first(ack_store))!=NULL) msg_destroy(msg); mutex_lock(file_mutex); if (file != NULL) { fclose(file); file = NULL; } store_file = octstr_read_file(octstr_get_cstr(filename)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(filename)); else { store_file = octstr_read_file(octstr_get_cstr(newfile)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(newfile)); else { store_file = octstr_read_file(octstr_get_cstr(bakfile)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(bakfile)); else { info(0, "Cannot open any store file, starting new one"); retval = open_file(filename); list_unlock(sms_store); list_unlock(ack_store); mutex_unlock(file_mutex); return retval; } } } info(0, "Store-file size %ld, starting to unpack%s", octstr_len(store_file), octstr_len(store_file) > 10000 ? " (may take awhile)" : ""); msg_hash = dict_create(101, msg_destroy_item); /* XXX should be different? */ pos = 0; msgs = 0; while ((end = octstr_search_char(store_file, '\n', pos)) != -1) { pack = octstr_copy(store_file, pos, end-pos); pos = end+1; if (octstr_url_decode(pack) == -1) { debug("bb.store", 0, "Garbage at store-file, skipped"); octstr_destroy(pack); continue; } msg = msg_unpack(pack); octstr_destroy(pack); if (msg == NULL) { continue; } if (msg_type(msg) == sms) { uuid_unparse(msg->sms.id, id); key = octstr_create(id); dict_put(msg_hash, key, msg); octstr_destroy(key); msgs++; } else if (msg_type(msg) == ack) { uuid_unparse(msg->sms.id, id); key = octstr_create(id); dmsg = dict_remove(msg_hash, key); if (dmsg != NULL) msg_destroy(dmsg); else info(0, "Acknowledge of non-existant message found '%s', " "discarded", octstr_get_cstr(key)); msg_destroy(msg); octstr_destroy(key); } else { warning(0, "Strange message in store-file, discarded, " "dump follows:"); msg_dump(msg, 0); msg_destroy(msg); } } octstr_destroy(store_file); store_size = dict_key_count(msg_hash); info(0, "Retrieved %d messages, non-acknowledged messages: %ld", msgs, store_size); /* now create a new sms_store out of messages left */ keys = dict_keys(msg_hash); while((key = list_extract_first(keys))!=NULL) { msg = dict_remove(msg_hash, key); octstr_destroy(key); if (msg_type(msg) != sms) { error(0, "Found non sms message in dictionary!"); msg_dump(msg, 0); msg_destroy(msg); continue; } copy = msg_duplicate(msg); list_produce(sms_store, copy); if (msg->sms.sms_type == mo || msg->sms.sms_type == report_mo) { list_produce(incoming_sms, msg); } else if (msg->sms.sms_type == mt_push || msg->sms.sms_type == mt_reply || msg->sms.sms_type == report_mt) { list_produce(outgoing_sms, msg); } else { msg_dump(msg,0); msg_destroy(msg); } } list_destroy(keys, NULL); /* Finally, generate new store file out of left messages */ retval = do_dump(); mutex_unlock(file_mutex); /* destroy the hash */ dict_destroy(msg_hash); list_unlock(ack_store); list_unlock(sms_store); return retval;}int store_dump(void){ int retval; list_lock(ack_store); list_lock(sms_store); debug("bb.store", 0, "Dumping %ld messages and %ld acks to store", list_len(sms_store), list_len(ack_store)); mutex_lock(file_mutex); if (file != NULL) { fclose(file); file = NULL; } retval = do_dump(); mutex_unlock(file_mutex); list_unlock(ack_store); list_unlock(sms_store); return retval;}int store_init(const Octstr *fname){ if (fname == NULL) return 0; /* we are done */ if (octstr_len(fname) > (FILENAME_MAX-5)) panic(0, "Store file filename too long: `%s', failed to init.", octstr_get_cstr(fname)); filename = octstr_duplicate(fname); newfile = octstr_format("%s.new", octstr_get_cstr(filename)); bakfile = octstr_format("%s.bak", octstr_get_cstr(filename)); sms_store = list_create(); ack_store = list_create(); file_mutex = mutex_create(); list_add_producer(ack_store); if ((cleanup_thread = gwthread_create(store_cleanup, NULL))==-1) panic(0, "Failed to create a cleanup thread!"); return 0;}void store_shutdown(void){ if (filename == NULL) return; list_remove_producer(ack_store);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -