static int mms_queue_replacedata(MmsEnvelope *e, MmsMsg *m) { Octstr *tfname; Octstr *ms; struct qfile_t *qfs; int ret = 0; if (!e) return -1; qfs = e->qfs_data; tfname = octstr_format(".%c%s.%ld.%d", MDF, qfs->name + 1, time(NULL), random()); ms = mms_tobinary(m); if (writemmsdata(ms, octstr_get_cstr(tfname), qfs->subdir, qfs->dir) < 0) ret = -1; else { Octstr *fname = octstr_format("%s/%s%c%s", qfs->dir, qfs->subdir, MDF, qfs->name + 1); Octstr *tmpf = octstr_format("%s/%s%S", qfs->dir, qfs->subdir, tfname); if (rename(octstr_get_cstr(tmpf), octstr_get_cstr(fname)) < 0) { error(0, "mms_replacedata: Failed to write data file %s: error = %s\n", octstr_get_cstr(tmpf), strerror(errno)); ret = -1; unlink(octstr_get_cstr(tmpf)); /* remove it. */ } octstr_destroy(fname); octstr_destroy(tmpf); } octstr_destroy(ms); octstr_destroy(tfname); return ret; }
static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh, *ph = NULL; Octstr *body = NULL, *rbody = NULL; Octstr *mms; MIMEEntity *form_data = make_multipart_formdata(); mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); mms = mms_tobinary(m); add_multipart_form_field(form_data, "to", "text/plain", NULL, to); add_multipart_form_field(form_data, "from", "text/plain", NULL, from); add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms); rh = mime_entity_headers(form_data); body = mime_entity_body(form_data); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { ret = rbody ? octstr_duplicate(rbody) : NULL; if (ret) octstr_strip_blanks(ret); } *retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(mms); mime_entity_destroy(form_data); return ret; }
static void start_push(Octstr *rcpt_to, int isphonenum, MmsEnvelope *e, MmsMsg *msg) { List *pheaders; static unsigned char ct; /* Transaction counter -- do we need it? */ Octstr *to = NULL; Octstr *pduhdr = octstr_create(""); Octstr *s = NULL; info(0, "mms2mobile.startpush: notification to %s\n", octstr_get_cstr(rcpt_to)); if (!rcpt_to) { error(0, "mobilesender: Queue entry %s has no recipient address!", e->xqfname); goto done; } else to = octstr_duplicate(rcpt_to); ct++; octstr_append_char(pduhdr, ct); /* Pushd id */ octstr_append_char(pduhdr, 0x06); /* PUSH */ #if 1 octstr_append_char(pduhdr, 1 + 1 + 1); octstr_append_char(pduhdr, 0xbe); /* content type. */ #else octstr_append_char(pduhdr, 1 + 1 + sizeof "application/vnd.wap.mms-message"); /*header length. */ octstr_append_cstr(pduhdr, "application/vnd.wap.mms-message"); octstr_append_char(pduhdr, 0x0); /* string terminator. */ #endif octstr_append_char(pduhdr, 0xaf); /* push application ID header and value follows. */ octstr_append_char(pduhdr, 0x84); /* ... */ s = mms_tobinary(msg); if (isphonenum) { Octstr *url; octstr_url_encode(to); octstr_url_encode(s); #if 0 octstr_dump(pduhdr, 0); #endif octstr_url_encode(pduhdr); url = octstr_format("%S&text=%S%S&to=%S&udh=%%06%%05%%04%%0B%%84%%23%%F0", settings->sendsms_url, pduhdr, s, to); pheaders = http_create_empty_headers(); http_header_add(pheaders, "Connection", "close"); http_header_add(pheaders, "User-Agent", MM_NAME "/" MMSC_VERSION); http_start_request(httpcaller, HTTP_METHOD_GET, url, pheaders, NULL, 0, e, NULL); http_destroy_headers(pheaders); octstr_destroy(url); } else { /* An IP Address: Send packet, forget. */ Octstr *addr = udp_create_address(to, WAPPUSH_PORT); int sock = udp_client_socket(); if (sock > 0) { MmsEnvelopeTo *xto = gwlist_get(e->to,0); octstr_append(pduhdr, s); #if 0 octstr_dump(pduhdr, 0); #endif udp_sendto(sock, pduhdr, addr); close(sock); /* ?? */ mms_log2("Notify", octstr_imm("system"), to, -1, e ? e->msgId : NULL, NULL, NULL, "MM1", NULL,NULL); e = update_env_success(e, xto); } else { e = update_env_failed(e); error(0, "push to %s:%d failed: %s", octstr_get_cstr(to), WAPPUSH_PORT, strerror(errno)); } octstr_destroy(addr); if (e) settings->qfs->mms_queue_free_env(e); } done: octstr_destroy(to); octstr_destroy(pduhdr); octstr_destroy(s); }
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, char *vasid, List *hdrs, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL, *resp = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh = http_create_empty_headers(), *ph = NULL; Octstr *body = NULL, *rbody = NULL, *xver = NULL; char *msgtype; mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); http_header_remove_all(rh, "X-Mms-Allow-Adaptations"); http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to)); http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from)); xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); octstr_destroy(xver); if (mtype == MMS_MSGTYPE_SEND_REQ || mtype == MMS_MSGTYPE_RETRIEVE_CONF) { msgtype = "MultiMediaMessage"; mms_make_sendreq(m); /* ensure it is a sendreq. */ } else if (mtype == MMS_MSGTYPE_DELIVERY_IND) msgtype = "DeliveryReport"; else msgtype = "ReadReply"; http_header_add(rh, "X-NOKIA-MMSC-Message-Type", msgtype); if (hdrs) http_header_combine(rh, hdrs); /* If specified, then update and pass on. */ http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message"); /* Patch the message FROM and TO fields. */ mms_replace_header_value(m, "From", octstr_get_cstr(from)); mms_replace_header_value(m, "To", octstr_get_cstr(to)); mms_replace_header_value(m,"X-Mms-Transaction-ID", transid ? octstr_get_cstr(transid) : "000"); body = mms_tobinary(m); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { MmsMsg *mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL; resp = octstr_imm("Ok"); if (mresp && mms_messagetype(mresp) == MMS_MSGTYPE_SEND_CONF) resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status")); if (octstr_case_compare(resp, octstr_imm("ok")) != 0) hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */ else if (mresp) ret = mms_get_header_value(mresp, octstr_imm("Message-ID")); mms_destroy(mresp); } if (hstatus < 0) ret = NULL; else { hstatus = http_status_class(hstatus); if (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus == HTTP_STATUS_CLIENT_ERROR) ret = NULL; else if (!ret) ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id")); } *retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); #if 0 mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]", octstr_get_cstr(mmc->id), hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)"); #endif http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(resp); return ret; }
MmsEnvelope *mms_queue_create_envelope(Octstr *from, List *to, Octstr *subject, Octstr *fromproxy, Octstr *viaproxy, time_t senddate, time_t expirydate, Octstr *token, Octstr *vaspid, Octstr *vasid, Octstr *url1, Octstr *url2, List *hdrs, int dlr, Octstr *mmscname, MmsMsg *m, char *xqfname, char *src_interface, int extra_space, Octstr **binary_mms) { MmsEnvelope *e; Octstr *msgid = NULL, *ms = NULL, *r, *xfrom; int mtype = -1, i, n; if (m) { mtype = mms_messagetype(m); /* Get MsgID, Fixup if not there and needed. */ if ((msgid = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL && xqfname) { msgid = mms_make_msgid(xqfname, mmscname); if (mtype == MMS_MSGTYPE_SEND_REQ) mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); } ms = mms_tobinary(m); } xfrom = copy_and_clean_address(from); e = gw_malloc(extra_space + sizeof *e); /* Make envelope, clear it. */ memset(e, 0, sizeof *e); e->qfs_data = (void *)(e+1); /* pointer to data object for module. */ e->msgtype = mtype; e->from = xfrom; e->created = time(NULL); e->sendt = senddate; e->expiryt = expirydate ? expirydate : time(NULL) + DEFAULT_EXPIRE; e->lasttry = 0; e->attempts = 0; e->lastaccess = 0; e->fromproxy = fromproxy ? octstr_duplicate(fromproxy) : NULL; e->viaproxy = viaproxy ? octstr_duplicate(viaproxy) : NULL; e->subject = subject ? octstr_duplicate(subject) : NULL; e->to = gwlist_create(); e->msize = ms ? octstr_len(ms) : 0; e->msgId = msgid; e->token = token ? octstr_duplicate(token) : NULL; e->vaspid = vaspid ? octstr_duplicate(vaspid) : NULL; e->vasid = vasid ? octstr_duplicate(vasid) : NULL; e->url1 = url1 ? octstr_duplicate(url1) : NULL; e->url2 = url2 ? octstr_duplicate(url2) : NULL; e->hdrs = hdrs ? http_header_duplicate(hdrs) : NULL; e->dlr = dlr; strncpy(e->src_interface, src_interface ? src_interface : "", sizeof e->src_interface); if (xqfname) strncpy(e->xqfname, xqfname, sizeof e->xqfname); for (i = 0, n = to ? gwlist_len(to) : 0; i<n; i++) if ((r = gwlist_get(to, i)) != NULL && (r = copy_and_clean_address(r)) != NULL) { MmsEnvelopeTo *t = gw_malloc(sizeof *t); t->rcpt = r; t->process = 1; gwlist_append(e->to, t); } if (binary_mms) *binary_mms = ms; else octstr_destroy(ms); return e; }
int mms_mmbox_modmsg(char *mmbox_root, char *user, Octstr *msgref, Octstr *state, List *flag_cmds) { Octstr *sdf = octstr_duplicate(msgref); Octstr *fname = NULL, *ftmp = NULL; Octstr *home = user_mmbox_dir(mmbox_root,user); Octstr *s = NULL; List *flags = NULL; Octstr *nstate = NULL; int ifd = -1, nifd, tmpfd = -1; MmsMsg *m = NULL; int res = -1; int msize; octstr_replace(sdf, octstr_imm("-"), octstr_imm("/")); if (!home) goto done; ifd = open_mmbox_index(octstr_get_cstr(home),1); if (ifd < 0) goto done; fname = octstr_format("%S/%S", home, sdf); s = octstr_read_file(octstr_get_cstr(fname)); if ( s == NULL || octstr_len(s) == 0) { error(0, "mmbox.mod: failed to read data file [%s] - %s!", octstr_get_cstr(fname), strerror(errno)); goto done; } m = mms_frombinary(s, octstr_imm("anon@anon")); if (!m) { error(0, "mmbox.mod: failed to read data file [%s]!", octstr_get_cstr(fname)); goto done; } if (state == NULL) nstate = mms_get_header_value(m, octstr_imm("X-Mms-MM-State")); else { nstate = octstr_duplicate(state); mms_replace_header_value(m, "X-Mms-MM-State", octstr_get_cstr(nstate)); } flags = mms_get_header_values(m, octstr_imm("X-Mms-MM-Flags")); flags = make_mm_flags(flags, flag_cmds); mms_replace_header_values(m, "X-Mms-MM-Flags", flags); ftmp = octstr_format("%S.%ld.%d", fname, time(NULL), getpid()); tmpfd = open(octstr_get_cstr(ftmp), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); if (tmpfd < 0) goto done; s = mms_tobinary(m); msize = octstr_len(s); octstr_write_to_socket(tmpfd, s); rename(octstr_get_cstr(ftmp), octstr_get_cstr(fname)); unlock_and_close(tmpfd); if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_MOD, sdf, nstate, flags, msize)) < 0) { /* Not good, we wrote but could not update the index file. scream. */ error(0, "mmbox.mod: failed to update index file, home is %s!", octstr_get_cstr(home)); goto done; } ifd = nifd; res = 0; done: if (ifd > 0) unlock_and_close(ifd); if (fname) octstr_destroy(fname); if (ftmp) octstr_destroy(ftmp); if (sdf) octstr_destroy(sdf); if (s) octstr_destroy(s); if (home) octstr_destroy(home); if (nstate) octstr_destroy(nstate); if (flags) gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); if (m) mms_destroy(m); return res; }
Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, List *flag_cmds, Octstr *dfltstate) { int ifd = -1, nifd, dfd = -1; char df[128]; Octstr *home = user_mmbox_dir(mmbox_root,user); Octstr *s = octstr_create(""), *sdf = NULL; List *flags = NULL; Octstr *state = NULL; int msize; if (!home) goto done; ifd = open_mmbox_index(octstr_get_cstr(home),1); if (ifd < 0) goto done; if ((dfd = mkdf(df, octstr_get_cstr(home))) < 0) { error(0, "mmbox_add: failed to create data file, home=%s - %s!", octstr_get_cstr(home), strerror(errno)); goto done; } state = mms_get_header_value(msg, octstr_imm("X-Mms-MM-State")); flags = make_mm_flags(mms_get_header_values(msg, octstr_imm("X-Mms-MM-Flags")), flag_cmds); if (state == NULL) state = dfltstate ? octstr_duplicate(dfltstate) : octstr_create("Sent"); mms_replace_header_values(msg, "X-Mms-MM-Flags", flags); mms_replace_header_value(msg, "X-Mms-MM-State", octstr_get_cstr(state)); s = mms_tobinary(msg); msize = octstr_len(s); octstr_write_to_socket(dfd, s); sdf = octstr_create(df); if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_ADD, sdf, state, flags, msize)) < 0 ) { char fbuf[256]; sprintf(fbuf, "%s/%s", octstr_get_cstr(home), df); unlink(fbuf); octstr_destroy(sdf); sdf = NULL; goto done; } ifd = nifd; octstr_replace(sdf, octstr_imm("/"), octstr_imm("-")); done: if (dfd > 0) unlock_and_close(dfd); if (ifd > 0) unlock_and_close(ifd); if (s) octstr_destroy(s); if (home) octstr_destroy(home); if (state) octstr_destroy(state); if (flags) gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); return sdf; }
static void do_mm1_push(Octstr *rcpt_to, int isphonenum, MmsEnvelope *e, MmsMsg *msg) { List *pheaders; static unsigned char ct; /* Transaction counter -- do we need it? */ Octstr *to = NULL; Octstr *pduhdr = octstr_create(""); Octstr *s = NULL; if (!rcpt_to) { mms_error(0, "MM1", NULL, "mobilesender: Queue entry %s has no recipient address!", e->xqfname); goto done; } else to = octstr_duplicate(rcpt_to); ct++; octstr_append_char(pduhdr, ct); /* Pushd id */ octstr_append_char(pduhdr, 0x06); /* PUSH */ #if 1 octstr_append_char(pduhdr, 1 + 1 + 1); octstr_append_char(pduhdr, 0xbe); /* content type. */ #else octstr_append_char(pduhdr, 1 + 1 + strlen("application/vnd.wap.mms-message") + 1); /*header length. */ octstr_append_cstr(pduhdr, "application/vnd.wap.mms-message"); octstr_append_char(pduhdr, 0x0); /* string terminator. */ #endif octstr_append_char(pduhdr, 0xaf); /* push application ID header and value follows. */ octstr_append_char(pduhdr, 0x84); /* ... */ s = mms_tobinary(msg); if (isphonenum) { Octstr *url = octstr_format("%S&text=%E%E&to=%E&udh=%%06%%05%%04%%0B%%84%%23%%F0", settings->sendsms_url, pduhdr, s, to); int status; List *rph = NULL; Octstr *rbody = NULL; MmsEnvelopeTo *xto = gwlist_get(e->to, 0); pheaders = http_create_empty_headers(); http_header_add(pheaders, "Connection", "close"); http_header_add(pheaders, "User-Agent", MM_NAME "/" MMSC_VERSION); if ((status = mms_url_fetch_content(HTTP_METHOD_GET, url, pheaders, NULL, &rph, &rbody)) < 0 || http_status_class(status) != HTTP_STATUS_SUCCESSFUL) { mms_error(0, "MM1", NULL, " Push[%s] from %s, to %s, failed, HTTP code => %d", e->xqfname, octstr_get_cstr(e->from), octstr_get_cstr(to), status); e = update_env(e,xto,0); } else { /* Successful push. */ mms_log2("Notify", octstr_imm("system"), to, -1, e ? e->msgId : NULL, NULL, NULL, "MM1", NULL,NULL); e = update_env(e, xto, 1); } http_destroy_headers(pheaders); http_destroy_headers(rph); octstr_destroy(rbody); octstr_destroy(url); } else { /* An IP Address: Send packet, forget. */ Octstr *addr = udp_create_address(to, WAPPUSH_PORT); int sock = udp_client_socket(); MmsEnvelopeTo *xto = gwlist_get(e->to,0); if (sock > 0) { octstr_append(pduhdr, s); #if 0 octstr_dump(pduhdr, 0); #endif udp_sendto(sock, pduhdr, addr); close(sock); /* ?? */ mms_log2("Notify", octstr_imm("system"), to, -1, e ? e->msgId : NULL, NULL, NULL, "MM1", NULL,NULL); e = update_env(e, xto, 1); } else { e = update_env(e, xto, 0); mms_error(0, "MM1", NULL, "push to %s:%d failed: %s", octstr_get_cstr(to), WAPPUSH_PORT, strerror(errno)); } octstr_destroy(addr); } done: octstr_destroy(to); octstr_destroy(pduhdr); octstr_destroy(s); if (e) settings->qfs->mms_queue_free_env(e); }