📄 mime.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * mime.c - Implement MIME multipart/related handling * * References: * RFC 2387 (The MIME Multipart/Related Content-type) * RFC 2025 (Multipurpose Internet Mail Extensions [MIME]) * * See gwlib/mime.h for more details on the implementation. * * Stipe Tolj <tolj@wapme-systems.de> */#include <string.h>#include <limits.h>#include <ctype.h>#include "gwlib/gwlib.h"#include "gwlib/mime.h"/******************************************************************** * Creation and destruction routines. */MIMEEntity *mime_entity_create(void) { MIMEEntity *e; e = gw_malloc(sizeof(MIMEEntity)); e->headers = http_create_empty_headers(); e->multiparts = list_create(); e->body = NULL; e->start = NULL; return e;}void static mime_entity_destroy_item(void *e){ mime_entity_destroy(e);}void mime_entity_destroy(MIMEEntity *e) { gw_assert(e != NULL); if (e->headers != NULL) list_destroy(e->headers, octstr_destroy_item); if (e->multiparts != NULL) list_destroy(e->multiparts, mime_entity_destroy_item); octstr_destroy(e->body); e->start = NULL; /* will be destroyed on it's own via list_destroy */ gw_free(e);} /******************************************************************** * Helper routines. Some are derived from gwlib/http.[ch] *//* * Read some headers, i.e., until the first empty line (read and discard * the empty line as well). Return -1 for error, 0 for all headers read. */static int read_mime_headers(ParseContext *context, List *headers){ Octstr *line, *prev; if (list_len(headers) == 0) prev = NULL; else prev = list_get(headers, list_len(headers) - 1); for (;;) { line = parse_get_line(context); if (line == NULL) { return -1; } if (octstr_len(line) == 0) { octstr_destroy(line); break; } if (isspace(octstr_get_char(line, 0)) && prev != NULL) { octstr_append(prev, line); octstr_destroy(line); } else { list_append(headers, line); prev = line; } } return 0;}/******************************************************************** * Mapping function from other data types, mainly Octstr and HTTP. */static Octstr *mime_entity_to_octstr_real(MIMEEntity *m, unsigned int level){ Octstr *mime, *value, *boundary; List *headers; long i; gw_assert(m != NULL && m->headers != NULL); mime = octstr_create(""); /* * First of all check if we have further MIME entity dependencies, * which means we have further MIMEEntities in our m->multiparts * list. If no, then add headers and body and return. This is the * easy case. Otherwise we have to loop inside our entities. */ if (list_len(m->multiparts) == 0) { for (i = 0; i < list_len(m->headers); i++) { octstr_append(mime, list_get(m->headers, i)); octstr_append(mime, octstr_imm("\r\n")); } octstr_append(mime, octstr_imm("\r\n")); if (m->body != NULL) octstr_append(mime, m->body); goto finished; } /* * Check if we have an boundary parameter already in the * Content-Type header. If no, add one, otherwise parse which one * we should use. * XXX this can be astracted as function in gwlib/http.[ch]. */ headers = http_header_duplicate(m->headers); value = http_header_value(headers, octstr_imm("Content-Type")); boundary = http_get_header_parameter(value, octstr_imm("boundary")); if (boundary == NULL) { boundary = octstr_format("_MIME_boundary-%d-%ld_%c_%c_bd%d", random(), (long)time(NULL), 'A' + (random()%26), 'a'+(random() % 26), random()); octstr_append(value, octstr_imm("; boundary=")); octstr_append(value, boundary); http_header_remove_all(headers, "Content-Type"); http_header_add(headers, "Content-Type", octstr_get_cstr(value)); http_header_add(headers, "MIME-Version", "1.0"); } octstr_destroy(value); /* headers */ for (i = 0; i < list_len(headers); i++) { octstr_append(mime, list_get(headers, i)); octstr_append(mime, octstr_imm("\r\n")); } http_destroy_headers(headers); /* loop through all MIME multipart entities of this entity */ for (i = 0; i < list_len(m->multiparts); i++) { MIMEEntity *e = list_get(m->multiparts, i); Octstr *body; if (i != 0) octstr_append(mime, octstr_imm("\r\n")); octstr_append(mime, octstr_imm("\r\n--")); octstr_append(mime, boundary); octstr_append(mime, octstr_imm("\r\n")); /* call ourself to produce the MIME entity body */ body = mime_entity_to_octstr_real(e, level + 1); octstr_append(mime, body); octstr_destroy(body); } /* add the last boundary statement, but hive an EOL * if we are on the top of the recursion stack. */ /* if (level > 0) */ octstr_append(mime, octstr_imm("\r\n")); octstr_append(mime, octstr_imm("\r\n--")); octstr_append(mime, boundary); octstr_append(mime, octstr_imm("--\r\n")); octstr_destroy(boundary);finished: return mime;}Octstr *mime_entity_to_octstr(MIMEEntity *m){ Octstr *mime;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -