URI: 
       tnew - 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
       ---
   DIR commit 20bd3ca2e2bc7c1b284a5a52e72a32530529d234
   DIR parent 0e6fee11c89b146aa5419bbdf26514bc34bdaf81
  HTML Author: rsc <devnull@localhost>
       Date:   Sun,  9 Apr 2006 00:24:28 +0000
       
       new
       
       Diffstat:
         M src/cmd/upas/vf/mkfile              |       6 +++---
         A src/cmd/upas/vf/unvf.c              |     156 +++++++++++++++++++++++++++++++
         M src/cmd/upas/vf/vf.c                |      24 ++++++++++++++++--------
       
       3 files changed, 175 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/src/cmd/upas/vf/mkfile b/src/cmd/upas/vf/mkfile
       t@@ -1,8 +1,8 @@
        <$PLAN9/src/mkhdr
        
       -TARG=vf
       +TARG=vf unvf
        
       -OFILES=vf.$O\
       +OFILES=
        
        LIB=../common/libcommon.a\
        
       t@@ -16,5 +16,5 @@ UPDATE=\
                $HFILES\
                ${OFILES:%.$O=%.c}\
        
       -<$PLAN9/src/mkone
       +<$PLAN9/src/mkmany
        CFLAGS=$CFLAGS -I../common
   DIR diff --git a/src/cmd/upas/vf/unvf.c b/src/cmd/upas/vf/unvf.c
       t@@ -0,0 +1,156 @@
       +/*
       + * For decoding the files that get passed to validateattachment.
       + * NOT a general mime decoder.
       + */
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +
       +enum { None, Base64, Quoted };
       +static int decquoted(char *out, char *in, char *e);
       +
       +void
       +main(void)
       +{
       +        Biobuf b, b1;
       +        char *p, *encoding;
       +        int e, len;
       +        
       +        Binit(&b, 0, OREAD);
       +        Binit(&b1, 1, OWRITE);
       +        
       +        /* header */
       +        encoding = nil;
       +        while((p = Brdstr(&b, '\n', 1)) != nil){
       +                if(p[0] == 0)
       +                        break;
       +                if(strncmp(p, "Content-Transfer-Encoding: ", 27) == 0)
       +                        encoding = strdup(p+27);
       +                free(p);
       +        }
       +
       +        e = None;
       +        if(encoding == nil)
       +                e = None;
       +        else if(strcmp(encoding, "base64") == 0)
       +                e = Base64;
       +        else if(strcmp(encoding, "quoted-printable") == 0)
       +                e = Quoted;
       +
       +        while((p = Brdstr(&b, '\n', 0)) != nil){
       +                if(strncmp(p, "--", 2) == 0 && e != None)
       +                        break;
       +                len = strlen(p);
       +                switch(e){
       +                case None:
       +                        break;
       +                case Base64:
       +                        len = dec64((uchar*)p, len, p, len);
       +                        break;
       +                case Quoted:
       +                        len = decquoted(p, p, p+len);
       +                        break;
       +                }
       +                Bwrite(&b1, p, len);
       +                free(p);
       +        }
       +        exits(0);
       +}
       +
       +/*
       + *  decode quoted 
       + */
       +enum
       +{
       +        Self=        1,
       +        Hex=        2
       +};
       +uchar        tableqp[256];
       +
       +static void
       +initquoted(void)
       +{
       +        int c;
       +
       +        memset(tableqp, 0, 256);
       +        for(c = ' '; c <= '<'; c++)
       +                tableqp[c] = Self;
       +        for(c = '>'; c <= '~'; c++)
       +                tableqp[c] = Self;
       +        tableqp['\t'] = Self;
       +        tableqp['='] = Hex;
       +}
       +
       +static int
       +hex2int(int x)
       +{
       +        if(x >= '0' && x <= '9')
       +                return x - '0';
       +        if(x >= 'A' && x <= 'F')
       +                return (x - 'A') + 10;
       +        if(x >= 'a' && x <= 'f')
       +                return (x - 'a') + 10;
       +        return 0;
       +}
       +
       +static char*
       +decquotedline(char *out, char *in, char *e)
       +{
       +        int c, soft;
       +
       +        /* dump trailing white space */
       +        while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))
       +                e--;
       +
       +        /* trailing '=' means no newline */
       +        if(*e == '='){
       +                soft = 1;
       +                e--;
       +        } else
       +                soft = 0;
       +
       +        while(in <= e){
       +                c = (*in++) & 0xff;
       +                switch(tableqp[c]){
       +                case Self:
       +                        *out++ = c;
       +                        break;
       +                case Hex:
       +                        c = hex2int(*in++)<<4;
       +                        c |= hex2int(*in++);
       +                        *out++ = c;
       +                        break;
       +                }
       +        }
       +        if(!soft)
       +                *out++ = '\n';
       +        *out = 0;
       +
       +        return out;
       +}
       +
       +static int
       +decquoted(char *out, char *in, char *e)
       +{
       +        char *p, *nl;
       +
       +        if(tableqp[' '] == 0)
       +                initquoted();
       +
       +        p = out;
       +        while((nl = strchr(in, '\n')) != nil && nl < e){
       +                p = decquotedline(p, in, nl);
       +                in = nl + 1;
       +        }
       +        if(in < e)
       +                p = decquotedline(p, in, e-1);
       +
       +        /* make sure we end with a new line */
       +        if(*(p-1) != '\n'){
       +                *p++ = '\n';
       +                *p = 0;
       +        }
       +
       +        return p - out;
       +}
       +
   DIR diff --git a/src/cmd/upas/vf/vf.c b/src/cmd/upas/vf/vf.c
       t@@ -5,6 +5,11 @@
        #include "common.h"
        #include <ctype.h>
        
       +enum {
       +        Accept = 0xA,
       +        Discard = 0xD,
       +};
       +
        Biobuf in;
        Biobuf out;
        
       t@@ -400,12 +405,12 @@ savetmp(Part *p)
                char buf[40], *name;
                int fd;
                
       -        strcpy(buf, "/tmp/vf.XXXXXXXXXXX");
       -        name = mktemp(buf);
       -        if((fd = create(name, OWRITE|OEXCL, 0666)) < 0){
       +        strcpy(buf, "/var/tmp/vf.XXXXXXXXXXX");
       +        if((fd = mkstemp(buf)) < 0){
                        fprint(2, "error creating temporary file: %r\n");
                        refuse();
                }
       +        name = buf;
                close(fd);
                if(save(p, name) < 0){
                        fprint(2, "error saving temporary file: %r\n");
       t@@ -433,10 +438,13 @@ runchecker(Part *p)
                int pid;
                char *name;
                Waitmsg *w;
       +        static char *val;
                
       -        if(access("/mail/lib/validateattachment", AEXEC) < 0)
       +        if(val == nil)
       +                val = unsharp("#9/mail/lib/validateattachment");
       +        if(val == nil || access(val, AEXEC) < 0)
                        return 0;
       -        
       +
                name = savetmp(p);
                fprint(2, "run checker %s\n", name);
                switch(pid = fork()){
       t@@ -444,7 +452,7 @@ runchecker(Part *p)
                        sysfatal("fork: %r");
                case 0:
                        dup(2, 1);
       -                execl("/mail/lib/validateattachment", "validateattachment", name, nil);
       +                execl(val, "validateattachment", name, nil);
                        _exits("exec failed");
                }
        
       t@@ -462,11 +470,11 @@ runchecker(Part *p)
                }
                if(p->filename)
                        name = s_to_c(p->filename);
       -        if(strstr(w->msg, "discard")){
       +        if(atoi(w->msg) == Discard){
                        syslog(0, "mail", "vf validateattachment rejected %s", name);
                        refuse();
                }
       -        if(strstr(w->msg, "accept")){
       +        if(atoi(w->msg) == Accept){
                        syslog(0, "mail", "vf validateattachment accepted %s", name);
                        return 1;
                }