URI:
       tunvf.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tunvf.c (2429B)
       ---
            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>
            8 
            9 enum { None, Base64, Quoted };
           10 static int decquoted(char *out, char *in, char *e);
           11 
           12 void
           13 main(void)
           14 {
           15         Biobuf b, b1;
           16         char *p, *encoding;
           17         int e, len;
           18 
           19         Binit(&b, 0, OREAD);
           20         Binit(&b1, 1, OWRITE);
           21 
           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         }
           31 
           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;
           39 
           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 }
           59 
           60 /*
           61  *  decode quoted
           62  */
           63 enum
           64 {
           65         Self=        1,
           66         Hex=        2
           67 };
           68 uchar        tableqp[256];
           69 
           70 static void
           71 initquoted(void)
           72 {
           73         int c;
           74 
           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 }
           83 
           84 static int
           85 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 }
           95 
           96 static char*
           97 decquotedline(char *out, char *in, char *e)
           98 {
           99         int c, soft;
          100 
          101         /* dump trailing white space */
          102         while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))
          103                 e--;
          104 
          105         /* trailing '=' means no newline */
          106         if(*e == '='){
          107                 soft = 1;
          108                 e--;
          109         } else
          110                 soft = 0;
          111 
          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;
          128 
          129         return out;
          130 }
          131 
          132 static int
          133 decquoted(char *out, char *in, char *e)
          134 {
          135         char *p, *nl;
          136 
          137         if(tableqp[' '] == 0)
          138                 initquoted();
          139 
          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);
          147 
          148         /* make sure we end with a new line */
          149         if(*(p-1) != '\n'){
          150                 *p++ = '\n';
          151                 *p = 0;
          152         }
          153 
          154         return p - out;
          155 }