Octstr *mime_entity_body(MIMEEntity *m) { Octstr *os, *body; ParseContext *context; MIMEEntity *e; gw_assert(m != NULL && m->headers != NULL); /* For non-multipart, return body directly. */ if (mime_entity_num_parts(m) == 0) return octstr_duplicate(m->body); os = mime_entity_to_octstr(m); context = parse_context_create(os); e = mime_entity_create(); /* parse the headers up to the body */ if ((read_mime_headers(context, e->headers) != 0) || e->headers == NULL) { debug("mime.parse",0,"Failed to read MIME headers in Octstr block:"); octstr_dump(os, 0); mime_entity_destroy(e); parse_context_destroy(context); return NULL; } /* the rest is the body */ body = parse_get_rest(context); octstr_destroy(os); mime_entity_destroy(e); parse_context_destroy(context); return body; }
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; }
/* Remove part i in list of body parts. */ void mime_entity_remove_part(MIMEEntity *e, int i) { MIMEEntity *m; gw_assert(e != NULL); gw_assert(i >= 0); gw_assert(i < gwlist_len(e->multiparts)); m = gwlist_get(e->multiparts, i); gwlist_delete(e->multiparts, i, 1); if (m == e->start) e->start = NULL; mime_entity_destroy(m); }
/* Replace part i in list of body parts. Old one will be deleted */ void mime_entity_replace_part(MIMEEntity *e, int i, MIMEEntity *newpart) { MIMEEntity *m; gw_assert(e != NULL); gw_assert(i >= 0); gw_assert(i < gwlist_len(e->multiparts)); m = gwlist_get(e->multiparts, i); gwlist_delete(e->multiparts, i, 1); gwlist_insert(e->multiparts, i, mime_entity_duplicate(newpart)); if (m == e->start) e->start = NULL; mime_entity_destroy(m); }
int main(int argc, char *argv[]) { Octstr *fname, *s; int cfidx; int msize; List *h = NULL; if (argc < 2) return -1; mms_lib_init(); cfidx = get_and_set_debugs(argc, argv, find_own); if (argv[cfidx] == NULL) fname = octstr_imm("mmsc.conf"); else fname = octstr_create(argv[cfidx]); mms_info(0, "mmssend", NULL, "----------------------------------------"); mms_info(0, "mmssend", NULL, " MMSC Message sender runner version %s starting", MMSC_VERSION); /* Load settings. */ settings = mms_load_mmsc_settings(fname, &proxyrelays,1); if (!settings) panic(0, "No global MMSC configuration, or failed to read conf from <%s>!", octstr_get_cstr(fname)); octstr_destroy(fname); if (from == NULL || to == NULL) { mms_error(0, "mmssend", NULL, "Sender and recipient addresses required!\n"); exit(-1); } else { /* fix up 'to' list */ List *l = gwlist_create(); Octstr *x; while ((x = gwlist_extract_first(to)) != NULL) { octstr_strip_blanks(x); _mms_fixup_address(&x, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); gwlist_append(l, x); } gwlist_destroy(to, NULL); to = l; } /* fix from address. */ _mms_fixup_address(&from, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); #if 0 mms_start_profile_engine(octstr_get_cstr(settings->ua_profile_cache_dir)); #endif if (data) { /* try and detect if we are looking at plain text (mime-encoded) or binary encoded message. */ int ch = octstr_get_char(data, 0); if (isprint(ch)) { MIMEEntity *mime = mime_octstr_to_entity(data); if (mime) { m = mms_frommime(mime); mime_entity_destroy(mime); } } else m = mms_frombinary_ex(data, from ? from : octstr_imm("anon@anon"), octstr_get_cstr(settings->unified_prefix), settings->strip_prefixes); if (m) mms_msgdump(m,1); msize = octstr_len(data); octstr_destroy(data); } else msize = 0; if (!m) panic(0, "No Message supplied, or failed to decode binary data!"); h = http_create_empty_headers(); http_header_add(h, "X-Mbuni-Tool", "mmssend"); http_header_add(h, "X-Mbuni-CalledFrom", "Terminal"); if (binfo) { mms_info(0, "add.info", NULL, "Adding extra headers billing info `X-Mms-Binfo' :"); http_header_add(h, "X-Mms-Binfo", octstr_get_cstr(binfo)); } s = settings->qfs->mms_queue_add(from, to, NULL, NULL, NULL, time(NULL), time(NULL) + settings->default_msgexpiry, m, NULL, NULL, NULL, NULL, NULL, h, dlr, octstr_get_cstr(settings->global_queuedir), "MM3", settings->host_alias); if (savetommbox) mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir), octstr_get_cstr(from), m, NULL, octstr_imm("Sent")); mms_log("Received", from, to, msize, s, NULL, NULL, "MM3",NULL,NULL); printf("Queued: %s, mmbox=%s\n", octstr_get_cstr(s), mmbox ? octstr_get_cstr(mmbox) : ""); octstr_destroy(s); http_destroy_headers(h); mms_cleanup_mmsc_settings(settings); mms_lib_shutdown(); return 0; }
int main(int argc, char **argv) { Octstr *filename = NULL; unsigned long num = 1, j; int opt; Octstr *mime, *mime2; MIMEEntity *m; gwlib_init(); while ((opt = getopt(argc, argv, "hv:n:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'n': num = atoi(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (optind == argc) { help(); exit(0); } filename = octstr_create(argv[argc-1]); mime = octstr_read_file(octstr_get_cstr(filename)); for (j = 1; j <= num; j++) { info(0,"MIME Octstr from file `%s':", octstr_get_cstr(filename)); octstr_dump(mime, 0); m = mime_octstr_to_entity(mime); mime_entity_dump(m); mime2 = mime_entity_to_octstr(m); info(0, "MIME Octstr after reconstruction:"); octstr_dump(mime2, 0); if (octstr_compare(mime, mime2) != 0) { error(0, "MIME content from file `%s' and reconstruction differs!", octstr_get_cstr(filename)); } else { info(0, "MIME Octstr compare result has been successfull."); } octstr_destroy(mime2); mime_entity_destroy(m); } /* num times */ octstr_destroy(filename); gwlib_shutdown(); return 0; }
void static mime_entity_destroy_item(void *e) { mime_entity_destroy(e); }
/* * This routine is used for mime_[http|octstr]_to_entity() in order to * reduce code duplication. Basically the only difference is how the headers * are parsed or passed to the resulting MIMEEntity representation. */ static MIMEEntity *mime_something_to_entity(Octstr *mime, List *headers) { MIMEEntity *e; ParseContext *context; Octstr *value, *boundary, *start; int len = 0; debug("mime.parse",0,"mime_something_to_entity"); octstr_dump(mime,0); gw_assert(mime != NULL); value = boundary = start = NULL; context = parse_context_create(mime); e = mime_entity_create(); /* parse the headers up to the body. If we have headers already passed * from our caller, then duplicate them and continue */ if (headers != NULL) { /* we have some headers to duplicate, first ensure we destroy * the list from the previous creation inside mime_entity_create() */ http_destroy_headers(e->headers); e->headers = http_header_duplicate(headers); } else { /* parse the headers out of the mime block */ if ((read_mime_headers(context, e->headers) != 0) || e->headers == NULL) { debug("mime.parse",0,"Failed to read MIME headers in Octstr block:"); octstr_dump(mime, 0); mime_entity_destroy(e); parse_context_destroy(context); return NULL; } } /* * Now check if the body is a multipart. This is indicated by an 'boundary' * parameter in the 'Content-Type' value. If yes, call ourself for the * multipart entities after parsing them. */ value = http_header_value(e->headers, octstr_imm("Content-Type")); debug("mime.parse",0,"value: %s", octstr_get_cstr(value)); boundary = http_get_header_parameter(value, octstr_imm("boundary")); debug("mime.parse",0,"boundary: %s", octstr_get_cstr(boundary)); start = get_start_param(value); /* Beware that we need *unquoted* strings to compare against in the * following parsing sections. */ if (boundary && (len = octstr_len(boundary)) > 0 && octstr_get_char(boundary, 0) == '"' && octstr_get_char(boundary, len-1) == '"') { octstr_delete(boundary, 0, 1); octstr_delete(boundary, len-2, 1); } debug("mime.parse",0, "Boundrary is %s", octstr_get_cstr(boundary)); if (boundary != NULL) { /* we have a multipart block as body, parse the boundary blocks */ Octstr *entity, *seperator, *os; /* loop by all boundary blocks we have in the body */ seperator = octstr_create("--"); octstr_append(seperator, boundary); while ((entity = parse_get_seperated_block(context, seperator)) != NULL) { MIMEEntity *m; int del2 = 0; /* we have still linefeeds at the beginning and end that we * need to remove, these are from the separator. * We check if it is LF only or CRLF! */ del2 = (octstr_get_char(entity, 0) == '\r'); if (del2) octstr_delete(entity, 0, 2); else octstr_delete(entity, 0, 1); /* we assume the same mechanism applies to beginning and end -- * seems reasonable! */ if (del2) octstr_delete(entity, octstr_len(entity) - 2, 2); else octstr_delete(entity, octstr_len(entity) - 1, 1); debug("mime.parse",0,"MIME multipart: Parsing entity:"); octstr_dump(entity, 0); /* call ourself for this MIME entity and inject to list */ if ((m = mime_octstr_to_entity(entity))) { gwlist_append(e->multiparts, m); /* check if this entity is our start entity (in terms of related) * and set our start pointer to it */ if (cid_matches(m->headers, start)) { /* set only if none has been set before */ e->start = (e->start == NULL) ? m : e->start; } } octstr_destroy(entity); } /* ok, we parsed all blocks, we expect to see now the end boundary */ octstr_append_cstr(seperator, "--"); os = parse_get_line(context); if (os != NULL && octstr_compare(os, seperator) != 0) { debug("mime.parse",0,"Failed to see end boundary, parsed line is '%s'.", octstr_get_cstr(os)); } octstr_destroy(seperator); octstr_destroy(os); } else { /* we don't have boundaries, so this is no multipart block, * pass the body to the MIME entity. */ e->body = parse_get_rest(context); } parse_context_destroy(context); octstr_destroy(value); octstr_destroy(boundary); octstr_destroy(start); return e; }