/** @brief MIMEツール @file mime_tool.c @author Fumi.Iseki (C) @date 2005 12/25 */ #include "protocol.h" #include "mime_tool.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////// // /** char* get_mime_boundary(tList* list) ヘッダリスト list から mime boundary を探し出す. @verbatim mime boundary 自身は先頭に '--' が付加されて返される. @endverbatim @param list ヘッダリスト @return '––' + MIME Boundary */ char* get_mime_boundary(tList* list) { int i; char* str; char* pp; Buffer buf; buf = search_protocol_header_value(list, (char*)MIME_CONTENTTYPE_LINE, (char*)MIME_BOUNDARY_LINE, 1); if (buf.buf==NULL) return NULL; pp = (char*)buf.buf; pp += strlen(MIME_BOUNDARY_LINE); if (*pp=='\"') pp++; str = (char*)malloc(strlen((const char*)pp)+3); memset(str, 0, strlen((const char*)pp)+3); str[0] = '-'; str[1] = '-'; strncpy(str+2, pp, strlen((const char*)pp)); i = 2; while (str[i]!='\0' && str[i]!='\"') i++; str[i] = '\0'; free_Buffer(&buf); return str; } /** tList* get_mime_filename(FILE* fp, char* bndry) ファイルから mime boundaryを探し出し,Content-Type行の内容をリストに格納して返す. 複数行に渡る場合も結合して返す. @param fp ファイルポインタ @param bndry '––' + MIMEの境界文字列 @return キー部にファイル名の入ったリスト */ tList* get_mime_filename(FILE* fp, char* bndry) { tList* lp = NULL; tList* ln = NULL; char* pt; Buffer mime, buf; fseek(fp, 0, SEEK_SET); buf = make_Buffer(LBUF); fgets_Buffer(&buf, fp); // ファイルから MIMEヘッダを抽出 while (!feof(fp)) { if (!strcmp((char*)buf.buf, bndry)) { // mime boundary を見つけた fgets_Buffer(&buf, fp); while(!feof(fp)) { ln = lp; lp = get_protocol_header_list_seq(lp, buf, ';', FALSE, FALSE); fgets_Buffer(&buf, fp); if (ln==lp) break; } } else { fgets_Buffer(&buf, fp); } } free_Buffer(&buf); lp = find_tList_top(lp); mime = init_Buffer(); // MIME_CONTEMT_LINE を取り出す. if (lp!=NULL) { int i, nn = 1; tList* lt = NULL; ln = NULL; Loop { mime = search_protocol_header(lp, (char*)MIME_CONTENT_LINE, nn); if (mime.buf==NULL) break; pt = strstrcase((char*)mime.buf, MIME_NAMEEQ_LINE); // name= if (pt!=NULL) { pt += strlen(MIME_NAMEEQ_LINE); } else { pt = strstrcase((char*)mime.buf, MIME_FILENAMESTAR_LINE); // filename* if (pt!=NULL) { i = 0; while(pt[i]!='\0' && pt[i]!='=') i++; if (pt[i]=='=') pt += i + 1; } } if (pt!=NULL) { pt = decode_mime_string(pt); // デコード if (pt!=NULL) { // リストに格納 lt = add_tList_node_str(lt, pt, NULL); if (ln==NULL) ln = lt; free(pt); } } nn++; free_Buffer(&mime); } } del_all_tList(&lp); return ln; } /** tList* get_mime_filenameffn(char* fname, char* bndry) ファイルから mime boundaryを探し出し,CONTENT-TYPE行の内容をリストに格納して返す. 複数行に渡る場合も結合して返す. @param fname ファイル名 @param bndry '––' + MIMEの境界文字列 @return キー部にファイル名の入ったリスト */ tList* get_mime_filenameffn(char* fname, char* bndry) { tList* lp; FILE* fp; if (bndry==NULL) return NULL; fp = fopen(fname, "rb"); if (fp==NULL) return NULL; lp = get_mime_filename(fp, bndry); fclose(fp); return lp; } /** char* decode_mime_rfc2047(char* mime) RFC2047で定義された文字列をデコードする.文字列全体が," " で括られていても可. 文字列中には余分な空白は無く,行間はCR+LF(またはLF)で区切られているものとする. エンコードされていない文字列が混在してもデコード可. @param mime デコードされる文字列. @return デコードされた文字列. */ char* decode_mime_rfc2047(char* mime) { char* buf; char* ppb; char* dec; char* ppd; char* str; char* ret; int i, j, len, decf=0, sz; if (mime==NULL) return NULL; buf = ppb = (char*)malloc(strlen((const char*)mime)+1); if (buf==NULL) return NULL; memcpy(buf, mime, strlen(mime)); buf[strlen(mime)] = '\0'; dec = ppd = (char*)malloc(strlen((const char*)mime)+1); if (dec==NULL) { free(buf); return NULL; } memset(dec, 0, strlen((const char*)mime)+1); if (ppb[0]=='"') ppb++; i = 0; while(ppb[i]!='\0' && ppb[i]!='"') i++; ppb[i] = '\0'; while (ppb[0]!='\0') { str = awk(ppb, '?', 1); len = strlen((const char*)str); if (str[len-1]=='=') { // エンコードの開始地点 =? len--; str[len] = '\0'; for (i=0, j=0; i