00001
00009 #include "protocol.h"
00010 #include "mime_tool.h"
00011
00012
00013
00015
00016
00029 char* get_mime_boundary(tList* list)
00030 {
00031 int i;
00032 char* str;
00033 char* pp;
00034 Buffer buf;
00035
00036 buf = search_protocol_header_value(list, (char*)MIME_CONTENTTYPE_LINE, (char*)MIME_BOUNDARY_LINE, 1);
00037 if (buf.buf==NULL) return NULL;
00038 pp = (char*)buf.buf;
00039
00040 pp += strlen(MIME_BOUNDARY_LINE);
00041 if (*pp=='\"') pp++;
00042
00043 str = (char*)malloc(strlen((const char*)pp)+3);
00044 memset(str, 0, strlen((const char*)pp)+3);
00045 str[0] = '-';
00046 str[1] = '-';
00047 strncpy(str+2, pp, strlen((const char*)pp));
00048
00049 i = 2;
00050 while (str[i]!='\0' && str[i]!='\"') i++;
00051 str[i] = '\0';
00052
00053 free_Buffer(&buf);
00054 return str;
00055 }
00056
00057
00058
00070 tList* get_mime_filename(FILE* fp, char* bndry)
00071 {
00072 tList* lp = NULL;
00073 tList* ln = NULL;
00074 char* pt;
00075 Buffer mime, buf;
00076
00077
00078 fseek(fp, 0, SEEK_SET);
00079
00080 buf = make_Buffer(LBUF);
00081 fgets_Buffer(&buf, fp);
00082
00083
00084 while (!feof(fp)) {
00085 if (!strcmp((char*)buf.buf, bndry)) {
00086 fgets_Buffer(&buf, fp);
00087 while(!feof(fp)) {
00088 ln = lp;
00089 lp = get_protocol_header_list_seq(lp, buf, ';', FALSE, FALSE);
00090 fgets_Buffer(&buf, fp);
00091 if (ln==lp) break;
00092 }
00093 }
00094 else {
00095 fgets_Buffer(&buf, fp);
00096 }
00097 }
00098 free_Buffer(&buf);
00099 lp = find_tList_top(lp);
00100
00101 mime = init_Buffer();
00102
00103
00104 if (lp!=NULL) {
00105 int i, nn = 1;
00106 tList* lt = NULL;
00107 ln = NULL;
00108
00109 Loop {
00110 mime = search_protocol_header(lp, (char*)MIME_CONTENT_LINE, nn);
00111 if (mime.buf==NULL) break;
00112
00113 pt = strstrcase((char*)mime.buf, MIME_NAMEEQ_LINE);
00114 if (pt!=NULL) {
00115 pt += strlen(MIME_NAMEEQ_LINE);
00116 }
00117 else {
00118 pt = strstrcase((char*)mime.buf, MIME_FILENAMESTAR_LINE);
00119 if (pt!=NULL) {
00120 i = 0;
00121 while(pt[i]!='\0' && pt[i]!='=') i++;
00122 if (pt[i]=='=') pt += i + 1;
00123 }
00124 }
00125
00126 if (pt!=NULL) {
00127 pt = decode_mime_string(pt);
00128 if (pt!=NULL) {
00129 lt = add_tList_node_str(lt, pt, NULL);
00130 if (ln==NULL) ln = lt;
00131 free(pt);
00132 }
00133 }
00134
00135 nn++;
00136 free_Buffer(&mime);
00137 }
00138 }
00139
00140 del_all_tList(&lp);
00141 return ln;
00142 }
00143
00144
00145
00157 tList* get_mime_filenameffn(char* fname, char* bndry)
00158 {
00159 tList* lp;
00160 FILE* fp;
00161
00162 if (bndry==NULL) return NULL;
00163
00164 fp = fopen(fname, "rb");
00165 if (fp==NULL) return NULL;
00166
00167 lp = get_mime_filename(fp, bndry);
00168 fclose(fp);
00169
00170 return lp;
00171 }
00172
00173
00174
00186 char* decode_mime_rfc2047(char* mime)
00187 {
00188 char* buf;
00189 char* ppb;
00190 char* dec;
00191 char* ppd;
00192 char* str;
00193 char* ret;
00194 int i, j, len, decf=0, sz;
00195
00196 if (mime==NULL) return NULL;
00197
00198 buf = ppb = (char*)malloc(strlen((const char*)mime)+1);
00199 if (buf==NULL) return NULL;
00200 memcpy(buf, mime, strlen(mime));
00201 buf[strlen(mime)] = '\0';
00202
00203 dec = ppd = (char*)malloc(strlen((const char*)mime)+1);
00204 if (dec==NULL) {
00205 free(buf);
00206 return NULL;
00207 }
00208 memset(dec, 0, strlen((const char*)mime)+1);
00209
00210 if (ppb[0]=='"') ppb++;
00211 i = 0;
00212 while(ppb[i]!='\0' && ppb[i]!='"') i++;
00213 ppb[i] = '\0';
00214
00215 while (ppb[0]!='\0') {
00216 str = awk(ppb, '?', 1);
00217 len = strlen((const char*)str);
00218 if (str[len-1]=='=') {
00219 len--;
00220 str[len] = '\0';
00221 for (i=0, j=0; i<len; i++) {
00222 if (str[i]!=CHAR_CR && str[i]!=CHAR_LF) ppd[j++] = str[i];
00223 }
00224 ppd += j;
00225 ppb += len + 2;
00226
00227 free(str);
00228 str = awk(ppb, '?', 1);
00229 if (str==NULL) {
00230 free(dec);
00231 free(buf);
00232 return NULL;
00233 }
00234 if (strcasecmp(MIME_ISO2022JP_LINE, str)) {
00235 free(str);
00236 free(dec);
00237 free(buf);
00238 return NULL;
00239 }
00240 ppb += strlen(MIME_ISO2022JP_LINE) + 1;
00241
00242 i++;
00243 free(str);
00244 str = awk(ppb, '?', 1);
00245 if (str==NULL) {
00246 free(dec);
00247 free(buf);
00248 return NULL;
00249 }
00250 if (!strcasecmp("B", str)) decf = 1;
00251 else if (!strcasecmp("Q", str)) decf = 2;
00252 else {
00253 free(str);
00254 free(dec);
00255 free(buf);
00256 return NULL;
00257 }
00258 ppb += 2;
00259
00260 i++;
00261 free(str);
00262 str = awk(ppb, '?', 1);
00263 if (str==NULL) {
00264 free(dec);
00265 free(buf);
00266 return NULL;
00267 }
00268 len = strlen((const char*)str);
00269 if (ppb[len+1]!='=') {
00270 free(str);
00271 free(dec);
00272 free(buf);
00273 return NULL;
00274 }
00275 ppb += len + 2;
00276
00277 ret = NULL;
00278 if (decf==1) ret = (char*)decode_base64((unsigned char*)str, &sz);
00279 else if (decf==2) ret = (char*)decode_quoted_printable((unsigned char*)str, &sz);
00280 if (ret==NULL) {
00281 free(str);
00282 free(dec);
00283 free(buf);
00284 return NULL;
00285 }
00286 memcpy(ppd, ret, sz);
00287 ppd += sz;
00288
00289 free(str);
00290 free(ret);
00291 decf = 0;
00292 }
00293 else {
00294 if (len==0) break;
00295 for (i=0, j=0; i<len; i++) {
00296 if (str[i]!=CHAR_CR && str[i]!=CHAR_LF) ppd[j++] = str[i];
00297 }
00298 ppd += j;
00299 ppb += len;
00300 }
00301 }
00302
00303 return dec;
00304 }
00305
00306
00307
00319 char* decode_mime_rfc2231(char* mime)
00320 {
00321 char* buf;
00322 char* dec;
00323 int i, j, sz;
00324
00325 if (mime==NULL) return NULL;
00326
00327 buf = awk(mime, '\'', 1);
00328 if (buf==NULL) return NULL;
00329 if (strcasecmp(MIME_ISO2022JP_LINE, buf)) {
00330 free(buf);
00331 return NULL;
00332 }
00333 mime += strlen(MIME_ISO2022JP_LINE) + 1;
00334 free(buf);
00335
00336 buf = awk(mime, '\'', 1);
00337 if (buf==NULL) return NULL;
00338 if (strcasecmp("JA", buf)) {
00339 return NULL;
00340 }
00341 mime += strlen("JA") + 1;
00342 free(buf);
00343
00344 buf = (char*)malloc(strlen((const char*)mime)+1);
00345 if (buf==NULL) return NULL;
00346 memset(buf, 0, strlen((const char*)mime)+1);
00347
00348 i = j = 0;
00349 while(mime[i]!='\0') {
00350 if (mime[i]!=' ' && mime[i]!=';' && mime[i]!=CHAR_CR && mime[i]!=CHAR_LF) buf[j++] = mime[i];
00351 i++;
00352 }
00353
00354 dec = (char*)decode_urlenc((unsigned char*)buf, &sz);
00355 if (dec!=NULL) dec[sz] = '\0';
00356 free(buf);
00357
00358 return dec;
00359 }
00360
00361
00362
00369 char* decode_mime_string(char* mime)
00370 {
00371 int kind;
00372 char* buf=NULL;
00373
00374 kind = get_mime_enckind(mime);
00375 if (kind==MIME_ERR_ENCODE) return NULL;
00376
00377 if (kind==MIME_UNKNOWN_ENCODE) {
00378 int i, j, len;
00379 char* str;
00380
00381 len = strlen((const char*)mime);
00382 str = (char*)malloc(len+1);
00383 if (str==NULL) return NULL;
00384
00385 i = j = 0;
00386 while(mime[i]!='\0') {
00387 if (mime[i]!=CHAR_CR && mime[i]!=CHAR_LF) str[j++] = mime[i];
00388 i++;
00389 }
00390 str[j] = '\0';
00391
00392 len = strlen(str);
00393 buf = (char*)malloc(len+1);
00394 if (buf==NULL) {
00395 free(str);
00396 return NULL;
00397 }
00398 if (str[0]=='\"' && str[len-1]=='\"' && str[len-2]!='\\') {
00399 memcpy(buf, str+1, len-2);
00400 buf[len-2] = '\0';
00401 }
00402 else {
00403 memcpy(buf, str, len);
00404 buf[len] = '\0';
00405 }
00406 free(str);
00407 }
00408
00409 else if (kind==MIME_BASE64_ENCODE || kind==MIME_QUTDPRNTBL_ENCODE) {
00410 buf = decode_mime_rfc2047(mime);
00411 }
00412
00413 else if (kind==MIME_URL_ENCODE) {
00414 int i, j;
00415 char* str;
00416
00417 str = (char*)malloc(strlen(mime)+1);
00418 if (str!=NULL) {
00419 memset(str, 0, strlen(mime)+1);
00420 i = j = 0;
00421 while(mime[i]!='\0') {
00422 str[j++] = mime[i];
00423 if (mime[i]==CHAR_LF) {
00424 while(mime[i]!='\0' && mime[i]!='=') i++;
00425 if (mime[i]=='=') i++;
00426 }
00427 else i++;
00428 }
00429 buf = decode_mime_rfc2231(str);
00430 free(str);
00431 }
00432 }
00433
00434 return buf;
00435 }
00436
00437
00438
00451 char* encode_mime_string(char* str, int kind)
00452 {
00453 char* buf;
00454 Buffer mime;
00455
00456 mime = make_Buffer(LBUF);
00457 if (mime.buf==NULL) return NULL;
00458
00459 if (kind==MIME_BASE64_ENCODE) {
00460 buf = (char*)encode_base64((unsigned char*)str, -1);
00461 if (buf==NULL) {
00462 free_Buffer(&mime);
00463 return NULL;
00464 }
00465 copy_s2Buffer(MIME_BASE64, &mime);
00466 cat_s2Buffer(buf, &mime);
00467 cat_s2Buffer("?=", &mime);
00468 free(buf);
00469 }
00470
00471 else if (kind==MIME_QUTDPRNTBL_ENCODE) {
00472 buf = (char*)encode_quoted_printable((unsigned char*)str, -1);
00473 if (buf==NULL) {
00474 free_Buffer(&mime);
00475 return NULL;
00476 }
00477 copy_s2Buffer(MIME_QUTDPRNTBL, &mime);
00478 cat_s2Buffer(buf, &mime);
00479 cat_s2Buffer("?=", &mime);
00480 free(buf);
00481 }
00482
00483 else if (kind==MIME_URL_ENCODE) {
00484 buf = (char*)encode_urlenc((unsigned char*)str, -1);
00485 if (buf==NULL) {
00486 free_Buffer(&mime);
00487 return NULL;
00488 }
00489 copy_s2Buffer(MIME_RFC2231, &mime);
00490 cat_s2Buffer(buf, &mime);
00491 free(buf);
00492 }
00493
00494 else {
00495 copy_s2Buffer(str, &mime);
00496 }
00497
00498 return (char*)mime.buf;
00499 }
00500
00501
00502
00520 int get_mime_enckind(char* mime)
00521 {
00522 unsigned char* ps;
00523 unsigned char* pe;
00524
00525 if (mime==NULL) return MIME_ERR_ENCODE;
00526
00527 if ((ps=(unsigned char*)strstrcase((const char*)mime, MIME_BASE64))!=NULL) {
00528 if ((pe=(unsigned char*)strstr((const char*)mime, "?="))!=NULL) {
00529 if (pe>ps+strlen(MIME_BASE64)) {
00530 return MIME_BASE64_ENCODE;
00531 }
00532 }
00533 }
00534
00535 if (strstrcase(mime, MIME_QUTDPRNTBL)!=NULL) {
00536 return MIME_QUTDPRNTBL_ENCODE;
00537 }
00538
00539 if (strstrcase(mime, MIME_RFC2231)!=NULL) {
00540 return MIME_URL_ENCODE;
00541 }
00542
00543 return MIME_UNKNOWN_ENCODE;
00544 }
00545