Blob
1 /*2 * For decoding the files that get passed to validateattachment.3 * NOT a general mime decoder.4 */5 #include <u.h>6 #include <libc.h>7 #include <bio.h>9 enum { None, Base64, Quoted };10 static int decquoted(char *out, char *in, char *e);12 void13 main(void)14 {15 Biobuf b, b1;16 char *p, *encoding;17 int e, len;19 Binit(&b, 0, OREAD);20 Binit(&b1, 1, OWRITE);22 /* header */23 encoding = nil;24 while((p = Brdstr(&b, '\n', 1)) != nil){25 if(p[0] == 0)26 break;27 if(cistrncmp(p, "Content-Transfer-Encoding: ", 27) == 0)28 encoding = strdup(p+27);29 free(p);30 }32 e = None;33 if(encoding == nil)34 e = None;35 else if(strcmp(encoding, "base64") == 0)36 e = Base64;37 else if(strcmp(encoding, "quoted-printable") == 0)38 e = Quoted;40 while((p = Brdstr(&b, '\n', 0)) != nil){41 if(strncmp(p, "--", 2) == 0 && e != None)42 break;43 len = strlen(p);44 switch(e){45 case None:46 break;47 case Base64:48 len = dec64((uchar*)p, len, p, len);49 break;50 case Quoted:51 len = decquoted(p, p, p+len);52 break;53 }54 Bwrite(&b1, p, len);55 free(p);56 }57 exits(0);58 }60 /*61 * decode quoted62 */63 enum64 {65 Self= 1,66 Hex= 267 };68 uchar tableqp[256];70 static void71 initquoted(void)72 {73 int c;75 memset(tableqp, 0, 256);76 for(c = ' '; c <= '<'; c++)77 tableqp[c] = Self;78 for(c = '>'; c <= '~'; c++)79 tableqp[c] = Self;80 tableqp['\t'] = Self;81 tableqp['='] = Hex;82 }84 static int85 hex2int(int x)86 {87 if(x >= '0' && x <= '9')88 return x - '0';89 if(x >= 'A' && x <= 'F')90 return (x - 'A') + 10;91 if(x >= 'a' && x <= 'f')92 return (x - 'a') + 10;93 return 0;94 }96 static char*97 decquotedline(char *out, char *in, char *e)98 {99 int c, soft;101 /* dump trailing white space */102 while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))103 e--;105 /* trailing '=' means no newline */106 if(*e == '='){107 soft = 1;108 e--;109 } else110 soft = 0;112 while(in <= e){113 c = (*in++) & 0xff;114 switch(tableqp[c]){115 case Self:116 *out++ = c;117 break;118 case Hex:119 c = hex2int(*in++)<<4;120 c |= hex2int(*in++);121 *out++ = c;122 break;123 }124 }125 if(!soft)126 *out++ = '\n';127 *out = 0;129 return out;130 }132 static int133 decquoted(char *out, char *in, char *e)134 {135 char *p, *nl;137 if(tableqp[' '] == 0)138 initquoted();140 p = out;141 while((nl = strchr(in, '\n')) != nil && nl < e){142 p = decquotedline(p, in, nl);143 in = nl + 1;144 }145 if(in < e)146 p = decquotedline(p, in, e-1);148 /* make sure we end with a new line */149 if(*(p-1) != '\n'){150 *p++ = '\n';151 *p = 0;152 }154 return p - out;155 }