📄 bb_store.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * bb_store.c : bearerbox box SMS storage/retrieval module * * Kalle Marjola 2001 for project Kannel */#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"/* passed from bearerbox core */extern List *incoming_sms;extern List *outgoing_sms;extern List *flow_threads;static FILE *file = NULL;static Octstr *filename = NULL;static Octstr *newfile = NULL;static Octstr *bakfile = NULL;static Mutex *file_mutex = NULL;static long cleanup_thread;static List *sms_store;static List *ack_store;static void write_msg(Msg *msg){ Octstr *pack, *line; pack = msg_pack(msg); line = octstr_duplicate(pack); octstr_url_encode(line); octstr_print(file, line); fprintf(file, "\n"); octstr_destroy(pack); octstr_destroy(line);}static int open_file(Octstr *name){ file = fopen(octstr_get_cstr(name), "w"); if (file == NULL) { error(errno, "Failed to open '%s' for writing, cannot create store-file", octstr_get_cstr(name)); return -1; } return 0;}static int rename_store(void){ if (rename(octstr_get_cstr(filename), octstr_get_cstr(bakfile)) == -1) { if (errno != ENOENT) { error(errno, "Failed to rename old store '%s' as '%s'", octstr_get_cstr(filename), octstr_get_cstr(bakfile)); return -1; } } if (rename(octstr_get_cstr(newfile), octstr_get_cstr(filename)) == -1) { error(errno, "Failed to rename new store '%s' as '%s'", octstr_get_cstr(newfile), octstr_get_cstr(filename)); return -1; } return 0;}static int do_dump(void){ Msg *msg; long l; if (filename == NULL) return 0; /* create a new store-file and save all non-acknowledged * messages into it */ if (open_file(newfile)==-1) return -1; for (l=0; l < list_len(sms_store); l++) { msg = list_get(sms_store, l); write_msg(msg); } for (l=0; l < list_len(ack_store); l++) { msg = list_get(ack_store, l); write_msg(msg); } fflush(file); /* rename old storefile as .bak, and then new as regular file * without .new ending */ return rename_store();}static int cmp_msgs(void *item, void *pattern) { Msg *smsm, *ackm; ackm = pattern; smsm = item; if (uuid_compare(ackm->ack.id, smsm->sms.id) == 0) return 1; else return 0;}/* * thread to cleanup store and to write it to file now and then */static void store_cleanup(void *arg){ Msg *ack; List *match; time_t last, now; long len; int cleanup = 0; list_add_producer(flow_threads); last = time(NULL); while((ack = list_consume(ack_store)) != NULL) { list_lock(sms_store); match = list_extract_matching(sms_store, ack, cmp_msgs); list_unlock(sms_store); msg_destroy(ack); if (match == NULL) { warning(0, "bb_store: get ACK of message not found " "from store, strange?"); continue; } if (list_len(match) > 1) warning(0, "bb-store cleanup: Found %ld matches!?", list_len(match)); list_destroy(match, msg_destroy_item); len = list_len(ack_store); if (len > 100) cleanup = 1; now = time(NULL); /* * write store to file up to each 10. second, providing * that something happened, of course */ if (now - last > 10 || (len == 0 && cleanup)) { store_dump(); last = now; if (len == 0) cleanup = 0; } } store_dump(); if (file != NULL) fclose(file); octstr_destroy(filename); octstr_destroy(newfile); octstr_destroy(bakfile); mutex_destroy(file_mutex); list_destroy(ack_store, msg_destroy_item); list_destroy(sms_store, msg_destroy_item); /* set all vars to NULL */ filename = newfile = bakfile = NULL; file_mutex = NULL; ack_store = sms_store = NULL; list_remove_producer(flow_threads);}/*------------------------------------------------------*/Octstr *store_status(int status_type){ char *frmt; Octstr *ret; unsigned long l; struct tm tm; Msg *msg; char id[UUID_STR_LEN + 1]; ret = octstr_create(""); /* set the type based header */ if (status_type == BBSTATUS_HTML) { octstr_append_cstr(ret, "<table border=1>\n" "<tr><td>SMS ID</td><td>Type</td><td>Time</td><td>Sender</td><td>Receiver</td>" "<td>SMSC ID</td><td>BOX ID</td><td>UDH</td><td>Message</td>" "</tr>\n"); } else if (status_type == BBSTATUS_TEXT) { octstr_append_cstr(ret, "[SMS ID] [Type] [Time] [Sender] [Receiver] [SMSC ID] [BOX ID] [UDH] [Message]\n"); } /* if there is no store-file, then don't loop in sms_store */ if (filename == NULL) goto finish; list_lock(sms_store); for (l = 0; l < list_len(sms_store); l++) { msg = list_get(sms_store, l); if (msg_type(msg) == sms) { if (status_type == BBSTATUS_HTML) { frmt = "<tr><td>%s</td><td>%s</td>" "<td>%04d-%02d-%02d %02d:%02d:%02d</td>" "<td>%s</td><td>%s</td><td>%s</td>" "<td>%s</td><td>%s</td><td>%s</td></tr>\n"; } else if (status_type == BBSTATUS_XML) { frmt = "<message>\n\t<id>%s</id>\n\t<type>%s</type>\n\t" "<time>%04d-%02d-%02d %02d:%02d:%02d</time>\n\t" "<sender>%s</sender>\n\t" "<receiver>%s</receiver>\n\t<smsc-id>%s</smsc-id>\n\t" "<box-id>%s</box-id>\n\t" "<udh-data>%s</udh-data>\n\t<msg-data>%s</msg-data>\n\t" "</message>\n"; } else { frmt = "[%s] [%s] [%04d-%02d-%02d %02d:%02d:%02d] [%s] [%s] [%s] [%s] [%s] [%s]\n"; } /* transform the time value */#if LOG_TIMESTAMP_LOCALTIME tm = gw_localtime(msg->sms.time);#else tm = gw_gmtime(msg->sms.time);#endif if (msg->sms.udhdata) octstr_binary_to_hex(msg->sms.udhdata, 1); if (msg->sms.msgdata && (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 || (msg->sms.coding == DC_UNDEF && msg->sms.udhdata))) octstr_binary_to_hex(msg->sms.msgdata, 1); uuid_unparse(msg->sms.id, id); octstr_format_append(ret, frmt, id,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -