?? rfc822.c
字號:
PARAMETER **param; if (body) switch (body->type) { case TYPEMULTIPART: /* multi-part */ for (param = &body->parameter; *param && strcmp ((*param)->attribute,"BOUNDARY"); param = &(*param)->next); if (!*param) { /* cookie not set up yet? */ char tmp[MAILTMPLEN]; /* make cookie not in BASE64 or QUOTEPRINT*/ sprintf (tmp,"%ld-%ld-%ld=:%ld",(long) gethostid (),random (),time (0), (long) getpid ()); (*param) = mail_newbody_parameter (); (*param)->attribute = cpystr ("BOUNDARY"); (*param)->value = cpystr (tmp); } part = body->nested.part; /* encode body parts */ do rfc822_encode_body_7bit (env,&part->body); while (part = part->next); /* until done */ break; case TYPEMESSAGE: /* encapsulated message */ switch (body->encoding) { case ENC7BIT: break; case ENC8BIT: mm_log ("8-bit included message in 7-bit message body",WARN); break; case ENCBINARY: mm_log ("Binary included message in 7-bit message body",WARN); break; default: fatal ("Invalid rfc822_encode_body_7bit message encoding"); } break; /* can't change encoding */ default: /* all else has some encoding */ switch (body->encoding) { case ENC8BIT: /* encode 8BIT into QUOTED-PRINTABLE */ /* remember old 8-bit contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_8bit (body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCQUOTEDPRINTABLE; fs_give (&f); /* flush old binary contents */ break; case ENCBINARY: /* encode binary into BASE64 */ /* remember old binary contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_binary ((void *) body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCBASE64; fs_give (&f); /* flush old binary contents */ default: /* otherwise OK */ break; } break; }}/* Encode a body for 8BIT transmittal * Accepts: envelope * body */void rfc822_encode_body_8bit (ENVELOPE *env,BODY *body){ void *f; PART *part; PARAMETER **param; if (body) switch (body->type) { case TYPEMULTIPART: /* multi-part */ for (param = &body->parameter; *param && strcmp ((*param)->attribute,"BOUNDARY"); param = &(*param)->next); if (!*param) { /* cookie not set up yet? */ char tmp[MAILTMPLEN]; /* make cookie not in BASE64 or QUOTEPRINT*/ sprintf (tmp,"%ld-%ld-%ld=:%ld",(long) gethostid (),random (),time (0), (long) getpid ()); (*param) = mail_newbody_parameter (); (*param)->attribute = cpystr ("BOUNDARY"); (*param)->value = cpystr (tmp); } part = body->nested.part; /* encode body parts */ do rfc822_encode_body_8bit (env,&part->body); while (part = part->next); /* until done */ break; case TYPEMESSAGE: /* encapsulated message */ switch (body->encoding) { case ENC7BIT: case ENC8BIT: break; case ENCBINARY: mm_log ("Binary included message in 8-bit message body",WARN); break; default: fatal ("Invalid rfc822_encode_body_7bit message encoding"); } break; /* can't change encoding */ default: /* other type, encode binary into BASE64 */ if (body->encoding == ENCBINARY) { /* remember old binary contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_binary ((void *) body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCBASE64; fs_give (&f); /* flush old binary contents */ } break; }}/* Output RFC 822 body * Accepts: body * I/O routine * stream for I/O routine * Returns: T if successful, NIL if failure */long rfc822_output_body (BODY *body,soutr_t f,void *s){ PART *part; PARAMETER *param; char *cookie = NIL; char tmp[MAILTMPLEN]; char *t; switch (body->type) { case TYPEMULTIPART: /* multipart gets special handling */ part = body->nested.part; /* first body part */ /* find cookie */ for (param = body->parameter; param && !cookie; param = param->next) if (!strcmp (param->attribute,"BOUNDARY")) cookie = param->value; if (!cookie) cookie = "-"; /* yucky default */ do { /* for each part */ /* build cookie */ sprintf (t = tmp,"--%s\015\012",cookie); /* append mini-header */ rfc822_write_body_header (&t,&part->body); strcat (t,"\015\012"); /* write terminating blank line */ /* output cookie, mini-header, and contents */ if (!((*f) (s,tmp) && rfc822_output_body (&part->body,f,s))) return NIL; } while (part = part->next);/* until done */ /* output trailing cookie */ sprintf (t = tmp,"--%s--",cookie); break; default: /* all else is text now */ t = (char *) body->contents.text.data; break; } /* output final stuff */ if (t && *t && !((*f) (s,t) && (*f) (s,"\015\012"))) return NIL; return LONGT;}/* Convert BASE64 contents to binary * Accepts: source * length of source * pointer to return destination length * Returns: destination as binary or NIL if error */void *rfc822_base64 (unsigned char *src,unsigned long srcl,unsigned long *len){ char c; void *ret = fs_get ((size_t) (*len = 4 + ((srcl * 3) / 4))); char *d = (char *) ret; int e = 0; memset (ret,0,(size_t) *len); /* initialize block */ *len = 0; /* in case we return an error */ while (srcl--) { /* until run out of characters */ c = *src++; /* simple-minded decode */ if (isupper (c)) c -= 'A'; else if (islower (c)) c -= 'a' - 26; else if (isdigit (c)) c -= '0' - 52; else if (c == '+') c = 62; else if (c == '/') c = 63; else if (c == '=') { /* padding */ switch (e++) { /* check quantum position */ case 3: e = 0; /* restart quantum */ break; case 2: if (*src == '=') break; default: /* impossible quantum position */ fs_give (&ret); return NIL; } continue; } else continue; /* junk character */ switch (e++) { /* install based on quantum position */ case 0: *d = c << 2; /* byte 1: high 6 bits */ break; case 1: *d++ |= c >> 4; /* byte 1: low 2 bits */ *d = c << 4; /* byte 2: high 4 bits */ break; case 2: *d++ |= c >> 2; /* byte 2: low 4 bits */ *d = c << 6; /* byte 3: high 2 bits */ break; case 3: *d++ |= c; /* byte 3: low 6 bits */ e = 0; /* reinitialize mechanism */ break; } } *len = d - (char *) ret; /* calculate data length */ return ret; /* return the string */}/* Convert binary contents to BASE64 * Accepts: source * length of source * pointer to return destination length * Returns: destination as BASE64 */unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len){ unsigned char *ret,*d; unsigned char *s = (unsigned char *) src; char *v = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned long i = ((srcl + 2) / 3) * 4; *len = i += 2 * ((i / 60) + 1); d = ret = (unsigned char *) fs_get ((size_t) ++i); for (i = 0; srcl; s += 3) { /* process tuplets */ *d++ = v[s[0] >> 2]; /* byte 1: high 6 bits (1) */ /* byte 2: low 2 bits (1), high 4 bits (2) */ *d++ = v[((s[0] << 4) + (--srcl ? (s[1] >> 4) : 0)) & 0x3f]; /* byte 3: low 4 bits (2), high 2 bits (3) */ *d++ = srcl ? v[((s[1] << 2) + (--srcl ? (s[2] >> 6) : 0)) & 0x3f] : '='; /* byte 4: low 6 bits (3) */ *d++ = srcl ? v[s[2] & 0x3f] : '='; if (srcl) srcl--; /* count third character if processed */ if ((++i) == 15) { /* output 60 characters? */ i = 0; /* restart line break count, insert CRLF */ *d++ = '\015'; *d++ = '\012'; } } *d++ = '\015'; *d++ = '\012'; /* insert final CRLF */ *d = '\0'; /* tie off string */ if (((unsigned long) (d - ret)) != *len) fatal ("rfc822_binary logic flaw"); return ret; /* return the resulting string */}/* Convert QUOTED-PRINTABLE contents to 8BIT * Accepts: source * length of source * pointer to return destination length * Returns: destination as 8-bit text or NIL if error */unsigned char *rfc822_qprint (unsigned char *src,unsigned long srcl, unsigned long *len){ unsigned char *ret = (unsigned char *) fs_get ((size_t) srcl + 1); unsigned char *d = ret; unsigned char *t = d; unsigned char *s = src; unsigned char c,e; *len = 0; /* in case we return an error */ /* until run out of characters */ while (((unsigned long) (s - src)) < srcl) { switch (c = *s++) { /* what type of character is it? */ case '=': /* quoting character */ if (((unsigned long) (s - src)) < srcl) switch (c = *s++) { case '\0': /* end of data */ s--; /* back up pointer */ break; case '\015': /* non-significant line break */ t = d; /* accept any leading spaces */ if ((((unsigned long) (s - src)) < srcl) && (*s == '\012')) s++; break; default: /* two hex digits then */ if (!(isxdigit (c) && (((unsigned long) (s - src)) < srcl) && (e = *s++) && isxdigit (e))) { fs_give ((void **) &ret); return NIL; } if (isdigit (c)) c -= '0'; else c -= (isupper (c) ? 'A' - 10 : 'a' - 10); if (isdigit (e)) e -= '0'; else e -= (isupper (e) ? 'A' - 10 : 'a' - 10); *d++ = e + (c << 4); /* merge the two hex digits */ t = d; /* note point of non-space */ break; } break; case ' ': /* space, possibly bogus */ *d++ = c; /* stash the space but don't update s */ break; case '\015': /* end of line */ d = t; /* slide back to last non-space, drop in */ default: *d++ = c; /* stash the character */ t = d; /* note point of non-space */ } } *d = '\0'; /* tie off results */ *len = d - ret; /* calculate length */ return ret; /* return the string */}/* Convert 8BIT contents to QUOTED-PRINTABLE * Accepts: source * length of source * pointer to return destination length * Returns: destination as quoted-printable text */#define MAXL (size_t) 75 /* 76th position only used by continuation = */unsigned char *rfc822_8bit (unsigned char *src,unsigned long srcl, unsigned long *len){ unsigned long lp = 0; unsigned char *ret = (unsigned char *) fs_get ((size_t) (3*srcl + (6*srcl)/MAXL + 3)); unsigned char *d = ret; char *hex = "0123456789ABCDEF"; unsigned char c; while (srcl--) { /* for each character */ /* true line break? */ if (((c = *src++) == '\015') && (*src == '\012') && srcl) { *d++ = '\015'; *d++ = *src++; srcl--; lp = 0; /* reset line count */ } else { /* not a line break */ /* quoting required? */ if (iscntrl (c) || (c == 0x7f) || (c & 0x80) || (c == '=') || ((c == ' ') && (*src == '\015'))) { if ((lp += 3) > MAXL) { /* yes, would line overflow? */ *d++ = '='; *d++ = '\015'; *d++ = '\012'; lp = 3; /* set line count */ } *d++ = '='; /* quote character */ *d++ = hex[c >> 4]; /* high order 4 bits */ *d++ = hex[c & 0xf]; /* low order 4 bits */ } else { /* ordinary character */ if ((++lp) > MAXL) { /* would line overflow? */ *d++ = '='; *d++ = '\015'; *d++ = '\012'; lp = 1; /* set line count */ } *d++ = c; /* ordinary character */ } } } *d = '\0'; /* tie off destination */ *len = d - ret; /* calculate true size */ /* try to give some space back */ fs_resize ((void **) &ret,(size_t) *len + 1); return ret;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -