mime.c (157001) | mime.c (159609) |
---|---|
1/* | 1/* |
2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. | 2 * Copyright (c) 1998-2003, 2006 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.139 2006/03/01 18:07:45 ca Exp $") | 17SM_RCSID("@(#)$Id: mime.c,v 8.142.2.1 2006/05/23 01:32:08 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 --- 49 unchanged lines hidden (view full) --- 75** 76** Parameters: 77** mci -- mailer connection information. 78** header -- the header for this body part. 79** e -- envelope. 80** boundaries -- the currently pending message boundaries. 81** NULL if we are processing the outer portion. 82** flags -- to tweak processing. | 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 --- 49 unchanged lines hidden (view full) --- 75** 76** Parameters: 77** mci -- mailer connection information. 78** header -- the header for this body part. 79** e -- envelope. 80** boundaries -- the currently pending message boundaries. 81** NULL if we are processing the outer portion. 82** flags -- to tweak processing. |
83** level -- recursion level. |
|
83** 84** Returns: 85** An indicator of what terminated the message part: 86** MBT_FINAL -- the final boundary 87** MBT_INTERMED -- an intermediate boundary 88** MBT_NOTSEP -- an end of file 89** SM_IO_EOF -- I/O error occurred 90*/ 91 92struct args 93{ 94 char *a_field; /* name of field */ 95 char *a_value; /* value of that field */ 96}; 97 98int | 84** 85** Returns: 86** An indicator of what terminated the message part: 87** MBT_FINAL -- the final boundary 88** MBT_INTERMED -- an intermediate boundary 89** MBT_NOTSEP -- an end of file 90** SM_IO_EOF -- I/O error occurred 91*/ 92 93struct args 94{ 95 char *a_field; /* name of field */ 96 char *a_value; /* value of that field */ 97}; 98 99int |
99mime8to7(mci, header, e, boundaries, flags) | 100mime8to7(mci, header, e, boundaries, flags, level) |
100 register MCI *mci; 101 HDR *header; 102 register ENVELOPE *e; 103 char **boundaries; 104 int flags; | 101 register MCI *mci; 102 HDR *header; 103 register ENVELOPE *e; 104 char **boundaries; 105 int flags; |
106 int level; |
|
105{ 106 register char *p; 107 int linelen; 108 int bt; 109 off_t offset; 110 size_t sectionsize, sectionhighbits; 111 int i; 112 char *type; --- 4 unchanged lines hidden (view full) --- 117 char *bp; 118 bool use_qp = false; 119 struct args argv[MAXMIMEARGS]; 120 char bbuf[128]; 121 char buf[MAXLINE]; 122 char pvpbuf[MAXLINE]; 123 extern unsigned char MimeTokenTab[256]; 124 | 107{ 108 register char *p; 109 int linelen; 110 int bt; 111 off_t offset; 112 size_t sectionsize, sectionhighbits; 113 int i; 114 char *type; --- 4 unchanged lines hidden (view full) --- 119 char *bp; 120 bool use_qp = false; 121 struct args argv[MAXMIMEARGS]; 122 char bbuf[128]; 123 char buf[MAXLINE]; 124 char pvpbuf[MAXLINE]; 125 extern unsigned char MimeTokenTab[256]; 126 |
127 if (level > MAXMIMENESTING) 128 { 129 if (!bitset(EF_TOODEEP, e->e_flags)) 130 { 131 if (tTd(43, 4)) 132 sm_dprintf("mime8to7: too deep, level=%d\n", 133 level); 134 usrerr("mime8to7: recursion level %d exceeded", 135 level); 136 e->e_flags |= EF_DONT_MIME|EF_TOODEEP; 137 } 138 } |
|
125 if (tTd(43, 1)) 126 { 127 sm_dprintf("mime8to7: flags = %x, boundaries =", flags); 128 if (boundaries[0] == NULL) 129 sm_dprintf(" <none>"); 130 else 131 { 132 for (i = 0; boundaries[i] != NULL; i++) --- 75 unchanged lines hidden (view full) --- 208 } 209 210 /* check for disaster cases */ 211 if (type == NULL) 212 type = "-none-"; 213 if (subtype == NULL) 214 subtype = "-none-"; 215 | 139 if (tTd(43, 1)) 140 { 141 sm_dprintf("mime8to7: flags = %x, boundaries =", flags); 142 if (boundaries[0] == NULL) 143 sm_dprintf(" <none>"); 144 else 145 { 146 for (i = 0; boundaries[i] != NULL; i++) --- 75 unchanged lines hidden (view full) --- 222 } 223 224 /* check for disaster cases */ 225 if (type == NULL) 226 type = "-none-"; 227 if (subtype == NULL) 228 subtype = "-none-"; 229 |
216 /* don't propogate some flags more than one level into the message */ | 230 /* don't propagate some flags more than one level into the message */ |
217 flags &= ~M87F_DIGEST; 218 219 /* 220 ** Check for cases that can not be encoded. 221 ** 222 ** For example, you can't encode certain kinds of types 223 ** or already-encoded messages. If we find this case, 224 ** just copy it through. --- 12 unchanged lines hidden (view full) --- 237 238 /* 239 ** Multipart requires special processing. 240 ** 241 ** Do a recursive descent into the message. 242 */ 243 244 if (sm_strcasecmp(type, "multipart") == 0 && | 231 flags &= ~M87F_DIGEST; 232 233 /* 234 ** Check for cases that can not be encoded. 235 ** 236 ** For example, you can't encode certain kinds of types 237 ** or already-encoded messages. If we find this case, 238 ** just copy it through. --- 12 unchanged lines hidden (view full) --- 251 252 /* 253 ** Multipart requires special processing. 254 ** 255 ** Do a recursive descent into the message. 256 */ 257 258 if (sm_strcasecmp(type, "multipart") == 0 && |
245 (!bitset(M87F_NO8BIT, flags) || bitset(M87F_NO8TO7, flags))) | 259 (!bitset(M87F_NO8BIT, flags) || bitset(M87F_NO8TO7, flags)) && 260 !bitset(EF_TOODEEP, e->e_flags) 261 ) |
246 { 247 248 if (sm_strcasecmp(subtype, "digest") == 0) 249 flags |= M87F_DIGEST; 250 251 for (i = 0; i < argc; i++) 252 { 253 if (sm_strcasecmp(argv[i].a_field, "boundary") == 0) --- 27 unchanged lines hidden (view full) --- 281 bbuf); 282 for (i = 0; i < MAXMIMENESTING; i++) 283 { 284 if (boundaries[i] == NULL) 285 break; 286 } 287 if (i >= MAXMIMENESTING) 288 { | 262 { 263 264 if (sm_strcasecmp(subtype, "digest") == 0) 265 flags |= M87F_DIGEST; 266 267 for (i = 0; i < argc; i++) 268 { 269 if (sm_strcasecmp(argv[i].a_field, "boundary") == 0) --- 27 unchanged lines hidden (view full) --- 297 bbuf); 298 for (i = 0; i < MAXMIMENESTING; i++) 299 { 300 if (boundaries[i] == NULL) 301 break; 302 } 303 if (i >= MAXMIMENESTING) 304 { |
289 usrerr("mime8to7: multipart nesting boundary too deep"); | 305 if (tTd(43, 4)) 306 sm_dprintf("mime8to7: too deep, i=%d\n", i); 307 if (!bitset(EF_TOODEEP, e->e_flags)) 308 usrerr("mime8to7: multipart nesting boundary too deep"); |
290 291 /* avoid bounce loops */ | 309 310 /* avoid bounce loops */ |
292 e->e_flags |= EF_DONT_MIME; | 311 e->e_flags |= EF_DONT_MIME|EF_TOODEEP; |
293 } 294 else 295 { 296 boundaries[i] = bbuf; 297 boundaries[i + 1] = NULL; 298 } 299 mci->mci_flags |= MCIF_INMIME; 300 --- 27 unchanged lines hidden (view full) --- 328 sm_dprintf(" ...%s\n", buf); 329 collect(e->e_dfp, false, &hdr, e, false); 330 if (tTd(43, 101)) 331 putline("+++after collect", mci); 332 if (!putheader(mci, hdr, e, flags)) 333 goto writeerr; 334 if (tTd(43, 101)) 335 putline("+++after putheader", mci); | 312 } 313 else 314 { 315 boundaries[i] = bbuf; 316 boundaries[i + 1] = NULL; 317 } 318 mci->mci_flags |= MCIF_INMIME; 319 --- 27 unchanged lines hidden (view full) --- 347 sm_dprintf(" ...%s\n", buf); 348 collect(e->e_dfp, false, &hdr, e, false); 349 if (tTd(43, 101)) 350 putline("+++after collect", mci); 351 if (!putheader(mci, hdr, e, flags)) 352 goto writeerr; 353 if (tTd(43, 101)) 354 putline("+++after putheader", mci); |
336 bt = mime8to7(mci, hdr, e, boundaries, flags); | 355 bt = mime8to7(mci, hdr, e, boundaries, flags, 356 level + 1); |
337 if (bt == SM_IO_EOF) 338 goto writeerr; 339 } 340 (void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--"); 341 if (!putline(buf, mci)) 342 goto writeerr; 343 if (tTd(43, 35)) 344 sm_dprintf(" ...%s\n", buf); --- 24 unchanged lines hidden (view full) --- 369 /* 370 ** Message/xxx types -- recurse exactly once. 371 ** 372 ** Class 's' is predefined to have "rfc822" only. 373 */ 374 375 if (sm_strcasecmp(type, "message") == 0) 376 { | 357 if (bt == SM_IO_EOF) 358 goto writeerr; 359 } 360 (void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--"); 361 if (!putline(buf, mci)) 362 goto writeerr; 363 if (tTd(43, 35)) 364 sm_dprintf(" ...%s\n", buf); --- 24 unchanged lines hidden (view full) --- 389 /* 390 ** Message/xxx types -- recurse exactly once. 391 ** 392 ** Class 's' is predefined to have "rfc822" only. 393 */ 394 395 if (sm_strcasecmp(type, "message") == 0) 396 { |
377 if (!wordinclass(subtype, 's')) | 397 if (!wordinclass(subtype, 's') || 398 bitset(EF_TOODEEP, e->e_flags)) |
378 { 379 flags |= M87F_NO8BIT; 380 } 381 else 382 { 383 auto HDR *hdr = NULL; 384 385 if (!putline("", mci)) --- 6 unchanged lines hidden (view full) --- 392 if (!putheader(mci, hdr, e, flags)) 393 goto writeerr; 394 if (tTd(43, 101)) 395 putline("+++after putheader", mci); 396 if (hvalue("MIME-Version", hdr) == NULL && 397 !bitset(M87F_NO8TO7, flags) && 398 !putline("MIME-Version: 1.0", mci)) 399 goto writeerr; | 399 { 400 flags |= M87F_NO8BIT; 401 } 402 else 403 { 404 auto HDR *hdr = NULL; 405 406 if (!putline("", mci)) --- 6 unchanged lines hidden (view full) --- 413 if (!putheader(mci, hdr, e, flags)) 414 goto writeerr; 415 if (tTd(43, 101)) 416 putline("+++after putheader", mci); 417 if (hvalue("MIME-Version", hdr) == NULL && 418 !bitset(M87F_NO8TO7, flags) && 419 !putline("MIME-Version: 1.0", mci)) 420 goto writeerr; |
400 bt = mime8to7(mci, hdr, e, boundaries, flags); | 421 bt = mime8to7(mci, hdr, e, boundaries, flags, 422 level + 1); |
401 mci->mci_flags &= ~MCIF_INMIME; 402 return bt; 403 } 404 } 405 406 /* 407 ** Non-compound body type 408 ** --- 891 unchanged lines hidden --- | 423 mci->mci_flags &= ~MCIF_INMIME; 424 return bt; 425 } 426 } 427 428 /* 429 ** Non-compound body type 430 ** --- 891 unchanged lines hidden --- |