static int store_spool_save(Msg *msg) { char id[UUID_STR_LEN + 1]; Octstr *id_s; /* 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 (spool == NULL) return 0; /* blocke here if store still not loaded */ gwlist_consume(loaded); switch(msg_type(msg)) { case sms: { Octstr *os = store_msg_pack(msg); Octstr *filename, *dir; int fd; size_t wrc; if (os == NULL) { error(0, "Could not pack message."); return -1; } uuid_unparse(msg->sms.id, id); id_s = octstr_create(id); dir = octstr_format("%S/%ld", spool, octstr_hash_key(id_s) % MAX_DIRS); octstr_destroy(id_s); if (mkdir(octstr_get_cstr(dir), S_IRUSR|S_IWUSR|S_IXUSR) == -1 && errno != EEXIST) { error(errno, "Could not create directory `%s'.", octstr_get_cstr(dir)); octstr_destroy(dir); octstr_destroy(os); return -1; } filename = octstr_format("%S/%s", dir, id); octstr_destroy(dir); if ((fd = open(octstr_get_cstr(filename), O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) == -1) { error(errno, "Could not open file `%s'.", octstr_get_cstr(filename)); octstr_destroy(filename); octstr_destroy(os); return -1; } for (wrc = 0; wrc < octstr_len(os); ) { size_t rc = write(fd, octstr_get_cstr(os) + wrc, octstr_len(os) - wrc); if (rc == -1) { /* remove file */ error(errno, "Could not write message to `%s'.", octstr_get_cstr(filename)); close(fd); if (unlink(octstr_get_cstr(filename)) == -1) error(errno, "Oops, Could not remove failed file `%s'.", octstr_get_cstr(filename)); octstr_destroy(os); octstr_destroy(filename); return -1; } wrc += rc; } close(fd); counter_increase(counter); octstr_destroy(filename); octstr_destroy(os); break; } case ack: { Octstr *filename; uuid_unparse(msg->ack.id, id); id_s = octstr_create(id); filename = octstr_format("%S/%ld/%s", spool, octstr_hash_key(id_s) % MAX_DIRS, id); octstr_destroy(id_s); if (unlink(octstr_get_cstr(filename)) == -1) { error(errno, "Could not unlink file `%s'.", octstr_get_cstr(filename)); octstr_destroy(filename); return -1; } counter_decrease(counter); octstr_destroy(filename); break; } default: return -1; } return 0; }
static unsigned long next_wsp_session_id(void) { return counter_increase(session_id_counter); }
int smscconn_send(SMSCConn *conn, Msg *msg) { int ret = -1; List *parts = NULL; gw_assert(conn != NULL); mutex_lock(conn->flow_mutex); if (conn->status == SMSCCONN_DEAD || conn->why_killed != SMSCCONN_ALIVE) { mutex_unlock(conn->flow_mutex); return -1; } /* if this a retry of splitted message, don't unify prefix and don't try to split */ if (msg->sms.split_parts == NULL) { /* normalize the destination number for this smsc */ char *uf = conn->unified_prefix ? octstr_get_cstr(conn->unified_prefix) : NULL; normalize_number(uf, &(msg->sms.receiver)); /* split msg */ parts = sms_split(msg, NULL, NULL, NULL, NULL, 1, counter_increase(split_msg_counter) & 0xff, 0xff, MAX_SMS_OCTETS); if (list_len(parts) == 1) { /* don't create split_parts of sms fit into one */ list_destroy(parts, msg_destroy_item); parts = NULL; } } if (parts == NULL) ret = conn->send_msg(conn, msg); else { long i, parts_len = list_len(parts); struct split_parts *split = gw_malloc(sizeof(*split)); /* must duplicate, because smsc2_route will destroy this msg */ split->orig = msg_duplicate(msg); split->parts_left = counter_create(); split->status = SMSCCONN_SUCCESS; counter_set(split->parts_left, parts_len); debug("bb.sms.splits", 0, "new split_parts created %p", split); for (i = 0; i < parts_len; i++) { msg = list_get(parts, i); msg->sms.split_parts = split; ret = conn->send_msg(conn, msg); if (ret < 0) { if (i == 0) { counter_destroy(split->parts_left); list_destroy(parts, msg_destroy_item); gw_free(split); mutex_unlock(conn->flow_mutex); return ret; } /* * Some parts were sent. So handle this within * bb_smscconn_XXX(). */ split->status = SMSCCONN_FAILED_REJECTED; while (++i < parts_len) { msg_destroy(list_get(parts, i)); counter_decrease(split->parts_left); } warning(0, "Could not send all parts of a split message"); break; } } list_destroy(parts, NULL); } mutex_unlock(conn->flow_mutex); return ret; }