/* * Remove matching entry from the spool. */ static void dlr_spool_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { Octstr *os, *hash, *dir, *filename; /* determine target dir and filename via hash */ os = octstr_duplicate(smsc); octstr_append(os, ts); hash = our_hash_func(os); octstr_destroy(os); /* determine target dir */ dir = octstr_format("%S/%ld", spool_dir, octstr_hash_key(hash) % MAX_DIRS); /* get msg surrogate filename */ filename = get_msg_filename(dir, hash, dst); octstr_destroy(dir); octstr_destroy(hash); /* if there was no filename, then we didn't find it */ if (filename == NULL) { return; } /* remove the file from the file system */ if (unlink(octstr_get_cstr(filename)) == -1) { error(errno, "Could not unlink file `%s'.", octstr_get_cstr(filename)); octstr_destroy(filename); return; } counter_decrease(counter); octstr_destroy(filename); }
/* * Find matching entry in our spool and return the dlr_entry. */ static struct dlr_entry *dlr_spool_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { struct dlr_entry *ret = NULL; Octstr *os, *hash, *dir, *filename = NULL; Msg *msg; /* determine target dir and filename via hash */ os = octstr_duplicate(smsc); octstr_append(os, ts); hash = our_hash_func(os); octstr_destroy(os); /* determine target dir */ dir = octstr_format("%S/%ld", spool_dir, octstr_hash_key(hash) % MAX_DIRS); /* get content of msg surrogate */ os = get_msg_surrogate(dir, hash, dst, &filename); octstr_destroy(dir); octstr_destroy(hash); /* if there was no content */ if (os == NULL) { octstr_destroy(filename); return NULL; } /* unpack */ if ((msg = store_msg_unpack(os)) == NULL) { octstr_destroy(os); error(0, "Could not unpack DLR message `%s'", octstr_get_cstr(filename)); octstr_destroy(filename); return ret; } octstr_destroy(os); octstr_destroy(filename); #define MAP(to, from) \ to = from; \ from = NULL; /* map values to a struct dlr_entry */ ret = dlr_entry_create(); MAP(ret->smsc, msg->sms.smsc_id); MAP(ret->timestamp, msg->sms.foreign_id); MAP(ret->source, msg->sms.sender); MAP(ret->destination, msg->sms.receiver); MAP(ret->service, msg->sms.service); MAP(ret->url, msg->sms.dlr_url); MAP(ret->boxc_id, msg->sms.boxc_id); ret->mask = msg->sms.dlr_mask; msg_destroy(msg); return ret; }
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; }
/* * Adds a struct dlr_entry to the spool directory. */ static void dlr_spool_add(struct dlr_entry *dlr) { Msg *msg; Octstr *os, *hash, *dir, *filename; int fd; size_t wrc; #define MAP(to, from) \ to = from; \ from = NULL; /* create a common message structure to contain our values */ msg = msg_create(sms); msg->sms.sms_type = report_mt; MAP(msg->sms.smsc_id, dlr->smsc); MAP(msg->sms.foreign_id, dlr->timestamp); MAP(msg->sms.sender, dlr->source); MAP(msg->sms.receiver, dlr->destination); MAP(msg->sms.service, dlr->service); MAP(msg->sms.dlr_url, dlr->url); MAP(msg->sms.boxc_id, dlr->boxc_id); msg->sms.dlr_mask = dlr->mask; /* we got all values, destroy the structure now */ dlr_entry_destroy(dlr); /* create hash value */ os = octstr_duplicate(msg->sms.smsc_id); octstr_append(os, msg->sms.foreign_id); hash = our_hash_func(os); octstr_destroy(os); /* target directory */ dir = octstr_format("%S/%ld", spool_dir, octstr_hash_key(hash) % MAX_DIRS); 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(hash); return; } /* * Now also add the hex value of the destination. * This will be the part we look later into while * DLR resolving. */ os = octstr_duplicate(msg->sms.receiver); octstr_binary_to_hex(os, 0); octstr_append(hash, os); octstr_destroy(os); /* target file */ filename = octstr_format("%S/%S", dir, hash); octstr_destroy(dir); octstr_destroy(hash); 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); return; } /* pack and write content to file */ os = store_msg_pack(msg); msg_destroy(msg); 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 DLR 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; } wrc += rc; } close(fd); counter_increase(counter); octstr_destroy(filename); octstr_destroy(os); }