Beispiel #1
0
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;
}
Beispiel #2
0
static unsigned long next_wsp_session_id(void) {
	return counter_increase(session_id_counter);
}
Beispiel #3
0
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;
}