mime.c (182352) | mime.c (249729) |
---|---|
1/* | 1/* |
2 * Copyright (c) 1998-2003, 2006 Sendmail, Inc. and its suppliers. | 2 * Copyright (c) 1998-2003, 2006, 2013 Sendmail, Inc. and its suppliers. |
3 * All rights reserved. 4 * Copyright (c) 1994, 1996-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14#include <sendmail.h> 15#include <string.h> 16 | 3 * All rights reserved. 4 * Copyright (c) 1994, 1996-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14#include <sendmail.h> 15#include <string.h> 16 |
17SM_RCSID("@(#)$Id: mime.c,v 8.147 2007/09/26 23:29:11 ca Exp $") | 17SM_RCSID("@(#)$Id: mime.c,v 8.148 2013/03/12 15:24:53 ca Exp $") |
18 19/* 20** MIME support. 21** 22** I am indebted to John Beck of Hewlett-Packard, who contributed 23** his code to me for inclusion. As it turns out, I did not use 24** his code since he used a "minimum change" approach that used 25** several temp files, and I wanted a "minimum impact" approach --- 76 unchanged lines hidden (view full) --- 102 HDR *header; 103 register ENVELOPE *e; 104 char **boundaries; 105 int flags; 106 int level; 107{ 108 register char *p; 109 int linelen; | 18 19/* 20** MIME support. 21** 22** I am indebted to John Beck of Hewlett-Packard, who contributed 23** his code to me for inclusion. As it turns out, I did not use 24** his code since he used a "minimum change" approach that used 25** several temp files, and I wanted a "minimum impact" approach --- 76 unchanged lines hidden (view full) --- 102 HDR *header; 103 register ENVELOPE *e; 104 char **boundaries; 105 int flags; 106 int level; 107{ 108 register char *p; 109 int linelen; |
110 int blen; |
|
110 int bt; 111 off_t offset; 112 size_t sectionsize, sectionhighbits; 113 int i; 114 char *type; 115 char *subtype; 116 char *cte; 117 char **pvp; --- 199 unchanged lines hidden (view full) --- 317 } 318 mci->mci_flags |= MCIF_INMIME; 319 320 /* skip the early "comment" prologue */ 321 if (!putline("", mci)) 322 goto writeerr; 323 mci->mci_flags &= ~MCIF_INHEADER; 324 bt = MBT_FINAL; | 111 int bt; 112 off_t offset; 113 size_t sectionsize, sectionhighbits; 114 int i; 115 char *type; 116 char *subtype; 117 char *cte; 118 char **pvp; --- 199 unchanged lines hidden (view full) --- 318 } 319 mci->mci_flags |= MCIF_INMIME; 320 321 /* skip the early "comment" prologue */ 322 if (!putline("", mci)) 323 goto writeerr; 324 mci->mci_flags &= ~MCIF_INHEADER; 325 bt = MBT_FINAL; |
325 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf)) 326 != NULL) | 326 while ((blen = sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, 327 sizeof(buf))) >= 0) |
327 { 328 bt = mimeboundary(buf, boundaries); 329 if (bt != MBT_NOTSEP) 330 break; | 328 { 329 bt = mimeboundary(buf, boundaries); 330 if (bt != MBT_NOTSEP) 331 break; |
331 if (!putxline(buf, strlen(buf), mci, | 332 if (!putxline(buf, blen, mci, |
332 PXLF_MAPFROM|PXLF_STRIP8BIT)) 333 goto writeerr; 334 if (tTd(43, 99)) 335 sm_dprintf(" ...%s", buf); 336 } 337 if (sm_io_eof(e->e_dfp)) 338 bt = MBT_FINAL; 339 while (bt != MBT_FINAL) --- 21 unchanged lines hidden (view full) --- 361 if (!putline(buf, mci)) 362 goto writeerr; 363 if (tTd(43, 35)) 364 sm_dprintf(" ...%s\n", buf); 365 boundaries[i] = NULL; 366 mci->mci_flags &= ~MCIF_INMIME; 367 368 /* skip the late "comment" epilogue */ | 333 PXLF_MAPFROM|PXLF_STRIP8BIT)) 334 goto writeerr; 335 if (tTd(43, 99)) 336 sm_dprintf(" ...%s", buf); 337 } 338 if (sm_io_eof(e->e_dfp)) 339 bt = MBT_FINAL; 340 while (bt != MBT_FINAL) --- 21 unchanged lines hidden (view full) --- 362 if (!putline(buf, mci)) 363 goto writeerr; 364 if (tTd(43, 35)) 365 sm_dprintf(" ...%s\n", buf); 366 boundaries[i] = NULL; 367 mci->mci_flags &= ~MCIF_INMIME; 368 369 /* skip the late "comment" epilogue */ |
369 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf)) 370 != NULL) | 370 while ((blen = sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, 371 sizeof(buf))) >= 0) |
371 { 372 bt = mimeboundary(buf, boundaries); 373 if (bt != MBT_NOTSEP) 374 break; | 372 { 373 bt = mimeboundary(buf, boundaries); 374 if (bt != MBT_NOTSEP) 375 break; |
375 if (!putxline(buf, strlen(buf), mci, | 376 if (!putxline(buf, blen, mci, |
376 PXLF_MAPFROM|PXLF_STRIP8BIT)) 377 goto writeerr; 378 if (tTd(43, 99)) 379 sm_dprintf(" ...%s", buf); 380 } 381 if (sm_io_eof(e->e_dfp)) 382 bt = MBT_FINAL; 383 if (tTd(43, 3)) --- 54 unchanged lines hidden (view full) --- 438 { 439 /* remember where we were */ 440 offset = sm_io_tell(e->e_dfp, SM_TIME_DEFAULT); 441 if (offset == -1) 442 syserr("mime8to7: cannot sm_io_tell on %cf%s", 443 DATAFL_LETTER, e->e_id); 444 445 /* do a scan of this body type to count character types */ | 377 PXLF_MAPFROM|PXLF_STRIP8BIT)) 378 goto writeerr; 379 if (tTd(43, 99)) 380 sm_dprintf(" ...%s", buf); 381 } 382 if (sm_io_eof(e->e_dfp)) 383 bt = MBT_FINAL; 384 if (tTd(43, 3)) --- 54 unchanged lines hidden (view full) --- 439 { 440 /* remember where we were */ 441 offset = sm_io_tell(e->e_dfp, SM_TIME_DEFAULT); 442 if (offset == -1) 443 syserr("mime8to7: cannot sm_io_tell on %cf%s", 444 DATAFL_LETTER, e->e_id); 445 446 /* do a scan of this body type to count character types */ |
446 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf)) 447 != NULL) | 447 while ((blen = sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, 448 sizeof(buf))) >= 0) |
448 { 449 if (mimeboundary(buf, boundaries) != MBT_NOTSEP) 450 break; | 449 { 450 if (mimeboundary(buf, boundaries) != MBT_NOTSEP) 451 break; |
451 for (p = buf; *p != '\0'; p++) | 452 for (i = 0; i < blen; i++) |
452 { 453 /* count bytes with the high bit set */ 454 sectionsize++; | 453 { 454 /* count bytes with the high bit set */ 455 sectionsize++; |
455 if (bitset(0200, *p)) | 456 if (bitset(0200, buf[i])) |
456 sectionhighbits++; 457 } 458 459 /* 460 ** Heuristic: if 1/4 of the first 4K bytes are 8-bit, 461 ** assume base64. This heuristic avoids double-reading 462 ** large graphics or video files. 463 */ --- 53 unchanged lines hidden (view full) --- 517 if (!putline(buf, mci)) 518 goto writeerr; 519 if (tTd(43, 36)) 520 sm_dprintf(" ...%s\n", buf); 521 } 522 if (!putline("", mci)) 523 goto writeerr; 524 mci->mci_flags &= ~MCIF_INHEADER; | 457 sectionhighbits++; 458 } 459 460 /* 461 ** Heuristic: if 1/4 of the first 4K bytes are 8-bit, 462 ** assume base64. This heuristic avoids double-reading 463 ** large graphics or video files. 464 */ --- 53 unchanged lines hidden (view full) --- 518 if (!putline(buf, mci)) 519 goto writeerr; 520 if (tTd(43, 36)) 521 sm_dprintf(" ...%s\n", buf); 522 } 523 if (!putline("", mci)) 524 goto writeerr; 525 mci->mci_flags &= ~MCIF_INHEADER; |
525 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf)) 526 != NULL) | 526 while ((blen = sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, 527 sizeof(buf))) >= 0) |
527 { 528 if (!bitset(MCIF_INLONGLINE, mci->mci_flags)) 529 { 530 bt = mimeboundary(buf, boundaries); 531 if (bt != MBT_NOTSEP) 532 break; 533 } | 528 { 529 if (!bitset(MCIF_INLONGLINE, mci->mci_flags)) 530 { 531 bt = mimeboundary(buf, boundaries); 532 if (bt != MBT_NOTSEP) 533 break; 534 } |
534 if (!putxline(buf, strlen(buf), mci, | 535 if (!putxline(buf, blen, mci, |
535 PXLF_MAPFROM|PXLF_NOADDEOL)) 536 goto writeerr; 537 } 538 if (sm_io_eof(e->e_dfp)) 539 bt = MBT_FINAL; 540 } 541 else if (!MapNLtoCRLF || 542 (sectionsize / 8 < sectionhighbits && !use_qp)) --- 485 unchanged lines hidden (view full) --- 1028# define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) 1029 1030bool 1031mime7to8(mci, header, e) 1032 register MCI *mci; 1033 HDR *header; 1034 register ENVELOPE *e; 1035{ | 536 PXLF_MAPFROM|PXLF_NOADDEOL)) 537 goto writeerr; 538 } 539 if (sm_io_eof(e->e_dfp)) 540 bt = MBT_FINAL; 541 } 542 else if (!MapNLtoCRLF || 543 (sectionsize / 8 < sectionhighbits && !use_qp)) --- 485 unchanged lines hidden (view full) --- 1029# define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) 1030 1031bool 1032mime7to8(mci, header, e) 1033 register MCI *mci; 1034 HDR *header; 1035 register ENVELOPE *e; 1036{ |
1036 int pxflags; | 1037 int pxflags, blen; |
1037 register char *p; 1038 char *cte; 1039 char **pvp; 1040 unsigned char *fbufp; 1041 char buf[MAXLINE]; 1042 unsigned char fbuf[MAXLINE + 1]; 1043 char pvpbuf[MAXLINE]; 1044 extern unsigned char MimeTokenTab[256]; --- 16 unchanged lines hidden (view full) --- 1061 (void) sm_snprintf(buf, sizeof(buf), 1062 "Content-Transfer-Encoding: %s", p); 1063 if (!putline(buf, mci)) 1064 goto writeerr; 1065 } 1066 if (!putline("", mci)) 1067 goto writeerr; 1068 mci->mci_flags &= ~MCIF_INHEADER; | 1038 register char *p; 1039 char *cte; 1040 char **pvp; 1041 unsigned char *fbufp; 1042 char buf[MAXLINE]; 1043 unsigned char fbuf[MAXLINE + 1]; 1044 char pvpbuf[MAXLINE]; 1045 extern unsigned char MimeTokenTab[256]; --- 16 unchanged lines hidden (view full) --- 1062 (void) sm_snprintf(buf, sizeof(buf), 1063 "Content-Transfer-Encoding: %s", p); 1064 if (!putline(buf, mci)) 1065 goto writeerr; 1066 } 1067 if (!putline("", mci)) 1068 goto writeerr; 1069 mci->mci_flags &= ~MCIF_INHEADER; |
1069 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf)) 1070 != NULL) | 1070 while ((blen = sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, 1071 sizeof(buf))) >= 0) |
1071 { | 1072 { |
1072 if (!putline(buf, mci)) | 1073 if (!putxline(buf, blen, mci, PXLF_MAPFROM)) |
1073 goto writeerr; 1074 } 1075 return true; 1076 } 1077 cataddr(pvp, NULL, buf, sizeof(buf), '\0', false); 1078 cte = sm_rpool_strdup_x(e->e_rpool, buf); 1079 1080 mci->mci_flags |= MCIF_INHEADER; --- 91 unchanged lines hidden (view full) --- 1172 else 1173 { 1174 int off; 1175 1176 /* quoted-printable */ 1177 pxflags |= PXLF_NOADDEOL; 1178 fbufp = fbuf; 1179 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, | 1074 goto writeerr; 1075 } 1076 return true; 1077 } 1078 cataddr(pvp, NULL, buf, sizeof(buf), '\0', false); 1079 cte = sm_rpool_strdup_x(e->e_rpool, buf); 1080 1081 mci->mci_flags |= MCIF_INHEADER; --- 91 unchanged lines hidden (view full) --- 1173 else 1174 { 1175 int off; 1176 1177 /* quoted-printable */ 1178 pxflags |= PXLF_NOADDEOL; 1179 fbufp = fbuf; 1180 while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, |
1180 sizeof(buf)) != NULL) | 1181 sizeof(buf)) >= 0) |
1181 { 1182 off = mime_fromqp((unsigned char *) buf, &fbufp, 1183 &fbuf[MAXLINE] - fbufp); 1184again: 1185 if (off < -1) 1186 continue; 1187 1188 if (fbufp - fbuf > 0) --- 137 unchanged lines hidden --- | 1182 { 1183 off = mime_fromqp((unsigned char *) buf, &fbufp, 1184 &fbuf[MAXLINE] - fbufp); 1185again: 1186 if (off < -1) 1187 continue; 1188 1189 if (fbufp - fbuf > 0) --- 137 unchanged lines hidden --- |