80 #define SQL_SHUTDOWN 1 91 #if !defined(HAVE_MSSQL) && !defined(HAVE_MYSQL) && !defined(HAVE_PGSQL) && !defined(HAVE_SDB) && \ 92 !defined(HAVE_SQLITE) && !defined(HAVE_SQLITE3) && !defined(HAVE_ORACLE) 93 #error You need support for at least one DB engine. Please recompile Kannel. 97 #define SLEEP_BETWEEN_EMPTY_SELECTS 1.0 98 #define DEFAULT_LIMIT_PER_CYCLE 10 100 typedef struct _boxc {
105 volatile sig_atomic_t
alive;
121 #define OCTSTR(name) \ 122 if (octstr_compare(octstr_imm(#name), variable) == 0) \ 124 #define SINGLE_GROUP(name, fields) \ 125 if (octstr_compare(octstr_imm(#name), group) == 0) { \ 126 if (octstr_compare(groupstr, variable) == 0) \ 131 #define MULTI_GROUP(name, fields) \ 132 if (octstr_compare(octstr_imm(#name), group) == 0) { \ 133 if (octstr_compare(groupstr, variable) == 0) \ 150 #define SINGLE_GROUP(name, fields) \ 151 if (octstr_compare(octstr_imm(#name), query) == 0) \ 153 #define MULTI_GROUP(name, fields) \ 154 if (octstr_compare(octstr_imm(#name), query) == 0) \ 214 while (boxconn->
alive) {
252 error(0,
"Couldn't write Msg to box <%s>, disconnecting",
279 debug(
"sqlbox", 0,
"smsbox_to_bearerbox: sms received");
284 msg_escaped->sms.validity = (msg_escaped->sms.validity - time(NULL))/60;
286 msg_escaped->sms.deferred = (msg_escaped->sms.deferred - time(NULL))/60;
300 if (
msg->admin.boxc_id != NULL) {
304 msg->admin.boxc_id = NULL;
306 debug(
"sqlbox", 0,
"smsbox_to_bearerbox: got boxc_id <%s> from <%s>",
320 boxc = gw_malloc(
sizeof(
Boxc));
353 struct sockaddr_in client_addr;
356 client_addr_len =
sizeof(client_addr);
358 newfd = accept(fd, (
struct sockaddr *)&client_addr, &client_addr_len);
406 debug(
"sqlbox", 0,
"bearerbox_to_smsbox: connection to bearerbox died.");
413 debug(
"sqlbox", 0,
"bearerbox_to_smsbox: Bearerbox told us to shutdown.");
420 debug(
"sqlbox", 0,
"bearerbox_to_smsbox: catch an heartbeat - we are alive");
457 if (newconn == NULL) {
458 panic(0,
"Socket accept failed");
467 error(0,
"Failed to start a new thread, disconnecting client <%s>",
488 if (ret == -1 || !timeout)
497 }
else if (ret < 0) {
498 if(errno==EINTR)
continue;
499 if(errno==EAGAIN)
continue;
500 error(errno,
"wait_for_connections failed");
533 debug(
"sqlbox", 0,
"bearerbox_to_sql: connection to bearerbox died.");
538 debug(
"sqlbox", 0,
"bearerbox_to_sql: catch an heartbeat - we are alive");
547 debug(
"sqlbox", 0,
"bearerbox_to_sql: Bearerbox told us to shutdown.");
565 mack->ack.time =
msg->sms.time;
583 error(0,
"Could not charset process message, dropping it!");
592 msg->sms.validity = time(NULL) +
msg->sms.validity * 60;
594 msg->sms.deferred = time(NULL) +
msg->sms.deferred * 60;
602 msg->sms.validity = (
msg->sms.validity - time(NULL))/60;
604 msg->sms.deferred = (
msg->sms.deferred - time(NULL))/60;
618 List *qlist, *save_list;
629 error(0,
"Could not charset process message, dropping it!");
638 msg->sms.validity = time(NULL) +
msg->sms.validity * 60;
640 msg->sms.deferred = time(NULL) +
msg->sms.deferred * 60;
645 msg->sms.validity = (
msg->sms.validity - time(NULL))/60;
647 msg->sms.deferred = (
msg->sms.deferred - time(NULL))/60;
668 boxc = gw_malloc(
sizeof(
Boxc));
707 panic(0,
"Could not open sqlbox port %d",
port);
740 error(0,
"SIGINT received, aborting program...");
746 warning(0,
"SIGHUP received, catching and re-opening logs");
755 warning(0,
"SIGQUIT received, reporting memory usage.");
763 struct sigaction act;
766 sigemptyset(&act.sa_mask);
768 sigaction(SIGINT, &act, NULL);
769 sigaction(SIGQUIT, &act, NULL);
770 sigaction(SIGHUP, &act, NULL);
771 sigaction(SIGPIPE, &act, NULL);
796 panic(0,
"Missing or bad 'bearerbox-port' in sqlbox group");
804 panic(0,
"No 'sqlbox' group in configuration");
835 if (logfile != NULL) {
836 info(0,
"Starting to log to file %s level %ld",
844 panic(0,
"No proper SQL server defined.");
853 if (strcmp(argv[i],
"-H")==0 || strcmp(argv[i],
"--tryhttp")==0) {
862 int main(
int argc,
char **argv)
872 if (argv[cf_index] == NULL) {
904 execvp(argv[0], argv);
void error(int err, const char *fmt,...)
static void sqlboxc_run(void *arg)
void info(int err, const char *fmt,...)
static long limit_per_cycle
Msg * msg_duplicate(Msg *msg)
static int bearerbox_port_ssl
static Octstr * bearerbox_host
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited)
Connection * connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
static void sql_to_bearerbox(void *arg)
gw_assert(wtls_machine->packet_to_send !=NULL)
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
static void setup_signal_handlers(void)
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
void gwlist_produce(List *list, void *item)
#define SLEEP_BETWEEN_EMPTY_SELECTS
void gwthread_join(long thread)
long gwlist_len(List *list)
static Msg * read_from_box(Connection *conn, Boxc *boxconn)
static void smsbox_to_bearerbox(void *arg)
int octstr_url_decode(Octstr *ostr)
#define cfg_get(grp, varname)
static int sqlbox_is_allowed_in_group(Octstr *group, Octstr *variable)
static void signal_handler(int signum)
int gwthread_shouldhandlesignal(int signal)
static int charset_processing(Msg *msg)
#define octstr_get_cstr(ostr)
#define gw_sql_fetch_msg_list
static volatile sig_atomic_t restart_sqlbox
Cfg * cfg_create(Octstr *filename)
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
Connection * bearerbox_connection
volatile sig_atomic_t alive
static void sql_list(Boxc *boxc)
static int check_args(int i, int argc, char **argv)
void msg_destroy_item(void *msg)
Octstr * octstr_imm(const char *cstr)
void cfg_add_hooks(void *allowed, void *single)
void cfg_destroy(Cfg *cfg)
void conn_config_ssl(CfgGroup *grp)
void gwlist_remove_producer(List *list)
void conn_destroy(Connection *conn)
#define octstr_duplicate(ostr)
static Boxc * accept_boxc(int fd, int ssl)
void uuid_copy(uuid_t dst, const uuid_t src)
static void bearerbox_to_smsbox(void *arg)
void msg_destroy(Msg *msg)
int make_server_socket(int port, const char *interface_name)
void warning(int err, const char *fmt,...)
#define DEFAULT_LIMIT_PER_CYCLE
void octstr_destroy(Octstr *ostr)
char filename[FILENAME_MAX+1]
#define gwthread_create(func, arg)
#define octstr_create(cstr)
#define gw_sql_save_msg(message, table)
void gwthread_sleep(double seconds)
static volatile sig_atomic_t sqlbox_status
#define SMS_PARAM_UNDEFINED
static void boxc_destroy(Boxc *boxc)
int main(int argc, char **argv)
int conn_write_withlen(Connection *conn, Octstr *data)
static void run_sqlbox(void *arg)
int gwthread_pollfd(int fd, int events, double timeout)
static void init_sqlbox(Cfg *cfg)
struct server_type * sqlbox_init_sql(Cfg *cfg)
void report_versions(const char *boxname)
int log_open(char *filename, int level, enum excl_state excl)
static int sqlbox_port_ssl
long octstr_len(const Octstr *ostr)
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
void * gwlist_consume(List *list)
static void identify_to_bearerbox(Boxc *conn)
Octstr * host_ip(struct sockaddr_in addr)
Connection * smsbox_connection
static void sql_single(Boxc *boxc)
void debug(const char *place, int err, const char *fmt,...)
static void bearerbox_to_sql(void *arg)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
void gwlib_shutdown(void)
Octstr * msg_pack(Msg *msg)
static long bearerbox_port
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
void gwlist_add_producer(List *list)
#define BB_DEFAULT_SMSBOX_PORT
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
static Octstr * global_sender
struct server_type * sql_type
static XMLRPCDocument * msg
static int sqlbox_is_single_group(Octstr *query)
Connection * conn_wrap_fd(int fd, int ssl)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)