⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mime.c

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 C
字号:
/*                                                                        * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.      *                                                                        * This file is part of the PIXIL Operating Environment                  *                                                                        * The use, copying and distribution of this file is governed by one     * of two licenses, the PIXIL Commercial License, or the GNU General     * Public License, version 2.                                            *                                                                        * Licensees holding a valid PIXIL Commercial License may use this file  * in accordance with the PIXIL Commercial License Agreement provided    * with the Software. Others are governed under the terms of the GNU    * General Public License version 2.                                     *                                                                        * This file may be distributed and/or modified under the terms of the   * GNU General Public License version 2 as published by the Free         * Software Foundation and appearing in the file LICENSE.GPL included    * in the packaging of this file.                                       *                                                                        * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING   * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A             * PARTICULAR PURPOSE.                                                   *                                                                        * RESTRICTED RIGHTS LEGEND                                              *                                                                      * Use, duplication, or disclosure by the government is subject to       * restriction as set forth in paragraph (b)(3)(b) of the Rights in      * Technical Data and Computer Software clause in DAR 7-104.9(a).        *                                                                       * See http://www.pixil.org/gpl/ for GPL licensing        * information.                                                          *                                                                       * See http://www.pixil.org/license.html or               * email cetsales@centurysoftware.com for information about the PIXIL    * Commercial License Agreement, or if any conditions of this licensing  * are not clear to you.                                                 */#include <stdlib.h>#include <string.h>#include "nxmail.h"#include "rfc822.h"#include "mime.h"#include "str_util.h"/* This is a local structure that holds all of the mime information *//* that the client may not care about.  This cuts down on each      *//* body section carrying around a huge mime header structure that   *//* is basically useless                                             */typedef struct{    char type[50];    char bound[100];    char name[50];    char description[50];    int encoding;    int charset;}local_mimeheader_t;/* These are all of the possible 1.1 MIME fields.  Most we can ignore, but those we care about */static char *mime_find_next_section(char *buffer, char *boundary){    char linebuf[1024];    char *curptr = buffer;    while (1) {	char *nextptr;	if (!curptr)	    return (0);		/* Nothing there, bail */	/* Grab the line and strip the endline */	nextptr = str_getline(curptr, linebuf, 1024);	/* Jump in two dashes */	if (linebuf[0] == '-' && linebuf[1] == '-') {	    if (!strncmp(linebuf + 2, boundary, strlen(boundary))) {		/* It is a boundary.  Is it the last one? */		if (linebuf[2 + strlen(boundary)] == '-')		    return (0);		else		    return (curptr);	    }	}	curptr = nextptr;    }}voidmime_ignore(char *inptr, local_mimeheader_t * header){    return;}voidmime_description(char *inptr, local_mimeheader_t * header){    strncpy(header->description, inptr, 50);}voidmime_contentEncoding(char *inptr, local_mimeheader_t * header){    /* Determine the various encoding schemes here */    /* Right now we only handle BASE64 */    str_lcase(inptr, strlen(inptr));    if (!strncmp(inptr, "base64", strlen("base64")))	header->encoding = NXMAIL_ENCODING_BASE64;    else	header->encoding = NXMAIL_ENCODING_NONE;    return;}voidmime_charset(char *inptr, local_mimeheader_t * header){}voidmime_boundary(char *inptr, local_mimeheader_t * header){    /* Watch out for the quotes! */    char *ptr = inptr + 1;    /* Look for the other quote, igoring any escaped quotes */    while (*ptr) {	if (*ptr == '"' && *(ptr - 1) != '\\')	    break;	ptr++;    }    if (!*ptr)	return;    strncpy(header->bound, inptr + 1, (int) (ptr - inptr) - 1);}voidmime_name(char *inptr, local_mimeheader_t * header){    strncpy(header->name, inptr, 50);}struct{    char keyword[10];    void (*callback) (char *, local_mimeheader_t * header);}content_keyword[] ={    {    "charset", mime_charset}    , {    "name", mime_name}    , {    "boundary", mime_boundary}    , {    "<none>", 0}};/* Stupid content type has a million entries all it own, so we need *//* to do parsing within parsing */voidmime_contentType(char *inptr, local_mimeheader_t * header){    char *field;    char *curptr;    /* Get the first entry, which is the content type */    curptr = str_getfield(inptr, ';', &field);    if (field)	strcpy(header->type, field);    str_lcase(header->type, strlen(header->type));    /* Now, parse the other items */    while (curptr) {	char *keyword, *value;	curptr = str_getfield(curptr, ';', &field);	if (str_parsefield(field, '=', &keyword, &value)) {	    int count = 0;	    str_lcase(keyword, strlen(keyword));	    /* Go through the content keywords */	    while (content_keyword[count].callback) {		if (!strncmp(keyword, content_keyword[count].keyword,			     strlen(content_keyword[count].keyword))) {		    content_keyword[count].callback(value, header);		    break;		}		if (content_keyword[count].callback == 0)		    break;		count++;	    }	}    }    return;}struct{    char keyword[30];    void (*callback) (char *, local_mimeheader_t * header);}mime_keywords[] ={    {    "--", mime_ignore}    , {    "accept", mime_ignore}    , {    "accept-charset", mime_ignore}    , {    "accept-encoding", mime_ignore}    , {    "accept-language", mime_ignore}    , {    "accept-ranges", mime_ignore}    , {    "authorization", mime_ignore}    , {    "cache-control", mime_ignore}    , {    "connection", mime_ignore}    , {    "content-encoding", mime_contentEncoding}    , {    "content-length", mime_ignore}    , {    "content-range", mime_ignore}    , {    "content-transfer-encoding", mime_contentEncoding}    , {    "content-type", mime_contentType}    , {    "content-description", mime_description}    , {    "digest-MessageDigest", mime_ignore}    , {    "keep-alive", mime_ignore}    , {    "link", mime_ignore}    , {    "location", mime_ignore}    , {    "max-forwards", mime_ignore}    , {    "mime-version", mime_ignore}    , {    "pragma", mime_ignore}    , {    "protocol", mime_ignore}    , {    "protocol-info", mime_ignore}    , {    "protocol-request", mime_ignore}    , {    "proxy-authenticate", mime_ignore}    , {    "proxy-authorization", mime_ignore}    , {    "public", mime_ignore}    , {    "range", mime_ignore}    , {    "referer", mime_ignore}    , {    "retry-after", mime_ignore}    , {    "server", mime_ignore}    , {    "trailer", mime_ignore}    , {    "transfer-encoding", mime_ignore}    , {    "upgrade", mime_ignore}    , {    "user-agent", mime_ignore}    , {    "vary", mime_ignore}    , {    "via", mime_ignore}    , {    "warning", mime_ignore}    , {    "www-authenticate", mime_ignore}    , {    "authentication-info", mime_ignore}    , {    "proxy-authentication-info", mime_ignore}    , {    "<none>", 0}};char *mime_parse_header(char *input, local_mimeheader_t * header){    char linebuf[1024];    char *keyword, *value;    char *pos = input;    while (pos) {	int count = 0;	if (!pos)	    return (0);		/* Nothing there, bail out early */	/* Get the line from the input buffer */	pos = str_getline(pos, linebuf, 1024);	if (strlen(linebuf) == 0)	    break;	/* Parse it */	if (str_parsefield(linebuf, ':', &keyword, &value)) {	    str_lcase(keyword, strlen(keyword));	    while (mime_keywords[count].callback) {		if (!strncmp(keyword, mime_keywords[count].keyword,			     strlen(mime_keywords[count].keyword))) {		    mime_keywords[count].callback(value, header);		    break;		}		count++;	    }	}    }    return (pos);}nxmail_body_t *mime_parse_section(char *input, int sectionsize, local_mimeheader_t * header){    local_mimeheader_t localheader;    nxmail_body_t *body;    char *bodyptr;    bzero(&localheader, sizeof(local_mimeheader_t));    /* Create a body structure */    body = nxmail_alloc_body_struct(sectionsize);    if (!body)	return (0);    /* Now, check out the section header */    bodyptr = mime_parse_header(input, &localheader);    if (!bodyptr) {	free(body);	return (0);    }    /* Store the mime information */    strcpy(body->mimeheader.type, localheader.type);    strcpy(body->mimeheader.description, localheader.description);    strcpy(body->mimeheader.name, localheader.name);    body->mimeheader.encoding = localheader.encoding;    body->mimeheader.charset = localheader.charset;    body->text = bodyptr;    body->size = (input + sectionsize) - bodyptr;    return (body);}/* This function parses the given message into a series of body sections for each mime type */voidmime_parse_message(char *message, int msgsize, nxmail_header_t * header,		   nxmail_body_t ** body){    char *curptr = message;    local_mimeheader_t localheader;    bzero(&localheader, sizeof(local_mimeheader_t));    /* Step 1:  Go through the main header again, looking for mime related keywords */    curptr = mime_parse_header(curptr, &localheader);    /* The curptr should be pointing at the start of the message, but we're going to cheat */    /* and grab the offset from the nxmail_header_t, just to be safe */    curptr = message + header->offset;    /* Easiest case.  No mime encoding at all.  Call it a text/plain and bail */    if (!strlen(localheader.type)) {	int size;	nxmail_body_t *bodyptr;	sprintf(header->mimeheader.type, "text/plain");	header->mimeheader.encoding = NXMAIL_ENCODING_NONE;	header->mimeheader.charset = NXMAIL_CHARSET_USASCII;	size = (int) (header->msgsize);	bodyptr = *body = nxmail_alloc_body_struct(size);	bodyptr->size = size;	bodyptr->text = curptr;	return;    }    /* MIME encoding was specified.  If the mimetype is not multipart/, then */    /* assume its all one big happy message */    if (strncmp(localheader.type, "multipart", strlen("multipart"))) {	int size;	nxmail_body_t *bodyptr;	strcpy(header->mimeheader.type, localheader.type);	header->mimeheader.encoding = localheader.encoding;	header->mimeheader.charset = localheader.charset;	size = (int) (header->msgsize);	bodyptr = *body = nxmail_alloc_body_struct(size);	bodyptr->size = size;	bodyptr->text = curptr;	return;    }    /* So its a multipart message.  Find the first section */    curptr = mime_find_next_section(curptr, localheader.bound);    /* No message.  Thats not right.... */    while (1) {	char linebuf[1024];	char *nextptr;	nxmail_body_t *section = 0;	int size = 0;	if (!curptr)	    return;	/* First order of business, get rid of the boundary line */	curptr = str_getline(curptr, linebuf, 1024);	if (!curptr)	    return;	/* Now find the next section */	nextptr = mime_find_next_section(curptr, localheader.bound);	if (!nextptr)	    size = (int) ((message + msgsize) - curptr);	else	    size = (int) (nextptr - curptr);	/* Now parse the section */	if (!*body) {	    *body = mime_parse_section(curptr, size, &localheader);	    section = *body;	} else {	    section->next = mime_parse_section(curptr, size, &localheader);	    if (section->next)		section = section->next;	}	/* Go back around for the next section */	curptr = nextptr;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -