tnew files - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 97a5e5f2dd40eff09cb650c91c21f680b6d4206a
 (DIR) parent 9e37bb03b38a732af1897289b2f519dbd74cd371
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 23 Nov 2003 18:25:35 +0000
       
       new files
       
       Diffstat:
         A include/bin.h                       |      13 +++++++++++++
         A include/fcall.h                     |     120 +++++++++++++++++++++++++++++++
         A include/flate.h                     |      41 +++++++++++++++++++++++++++++++
         A include/httpd.h                     |     280 +++++++++++++++++++++++++++++++
         A include/ip.h                        |     123 +++++++++++++++++++++++++++++++
         A include/libsec.h                    |     340 +++++++++++++++++++++++++++++++
         M include/plumb.h                     |       2 ++
         A include/regexp.h                    |       1 +
         A include/venti.h                     |     414 ++++++++++++++++++++++++++++++
       
       9 files changed, 1334 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/include/bin.h b/include/bin.h
       t@@ -0,0 +1,13 @@
       +/*
       +#pragma        lib        "libbin.a"
       +#pragma        src        "/sys/src/libbin"
       +*/
       +
       +#ifndef _HAVE_BIN
       +typedef struct Bin                Bin;
       +#define _HAVE_BIN
       +#endif
       +
       +void        *binalloc(Bin **, ulong size, int zero);
       +void        *bingrow(Bin **, void *op, ulong osize, ulong size, int zero);
       +void        binfree(Bin **);
 (DIR) diff --git a/include/fcall.h b/include/fcall.h
       t@@ -0,0 +1,120 @@
       +/*
       +#pragma        src        "/sys/src/libc/9sys"
       +#pragma        lib        "libc.a"
       +*/
       +
       +#define        VERSION9P        "9P2000"
       +
       +#define        MAXWELEM        16
       +
       +typedef
       +struct        Fcall
       +{
       +        uchar        type;
       +        u32int        fid;
       +        ushort        tag;
       +        u32int        msize;                /* Tversion, Rversion */
       +        char        *version;        /* Tversion, Rversion */
       +        ushort        oldtag;                /* Tflush */
       +        char        *ename;                /* Rerror */
       +        Qid        qid;                /* Rattach, Ropen, Rcreate */
       +        u32int        iounit;                /* Ropen, Rcreate */
       +        Qid        aqid;                /* Rauth */
       +        u32int        afid;                /* Tauth, Tattach */
       +        char        *uname;                /* Tauth, Tattach */
       +        char        *aname;                /* Tauth, Tattach */
       +        u32int        perm;                /* Tcreate */ 
       +        char        *name;                /* Tcreate */
       +        uchar        mode;                /* Tcreate, Topen */
       +        u32int        newfid;                /* Twalk */
       +        ushort        nwname;                /* Twalk */
       +        char        *wname[MAXWELEM];        /* Twalk */
       +        ushort        nwqid;                /* Rwalk */
       +        Qid        wqid[MAXWELEM];                /* Rwalk */
       +        vlong        offset;                /* Tread, Twrite */
       +        u32int        count;                /* Tread, Twrite, Rread */
       +        char        *data;                /* Twrite, Rread */
       +        ushort        nstat;                /* Twstat, Rstat */
       +        uchar        *stat;                /* Twstat, Rstat */
       +} Fcall;
       +
       +
       +#define        GBIT8(p)        ((p)[0])
       +#define        GBIT16(p)        ((p)[0]|((p)[1]<<8))
       +#define        GBIT32(p)        ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
       +#define        GBIT64(p)        ((vlong)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
       +                                ((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
       +
       +#define        PBIT8(p,v)        (p)[0]=(v)
       +#define        PBIT16(p,v)        (p)[0]=(v);(p)[1]=(v)>>8
       +#define        PBIT32(p,v)        (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
       +#define        PBIT64(p,v)        (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
       +                        (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
       +
       +#define        BIT8SZ                1
       +#define        BIT16SZ                2
       +#define        BIT32SZ                4
       +#define        BIT64SZ                8
       +#define        QIDSZ        (BIT8SZ+BIT32SZ+BIT64SZ)
       +
       +/* STATFIXLEN includes leading 16-bit count */
       +/* The count, however, excludes itself; total size is BIT16SZ+count */
       +#define STATFIXLEN        (BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+1*BIT64SZ)        /* amount of fixed length data in a stat buffer */
       +
       +#define        NOTAG                (ushort)~0U        /* Dummy tag */
       +#define        NOFID                (u32int)~0U        /* Dummy fid */
       +#define        IOHDRSZ                24        /* ample room for Twrite/Rread header (iounit) */
       +
       +enum
       +{
       +        Tversion =        100,
       +        Rversion,
       +        Tauth =                102,
       +        Rauth,
       +        Tattach =        104,
       +        Rattach,
       +        Terror =        106,        /* illegal */
       +        Rerror,
       +        Tflush =        108,
       +        Rflush,
       +        Twalk =                110,
       +        Rwalk,
       +        Topen =                112,
       +        Ropen,
       +        Tcreate =        114,
       +        Rcreate,
       +        Tread =                116,
       +        Rread,
       +        Twrite =        118,
       +        Rwrite,
       +        Tclunk =        120,
       +        Rclunk,
       +        Tremove =        122,
       +        Rremove,
       +        Tstat =                124,
       +        Rstat,
       +        Twstat =        126,
       +        Rwstat,
       +        Tmax,
       +};
       +
       +uint        convM2S(uchar*, uint, Fcall*);
       +uint        convS2M(Fcall*, uchar*, uint);
       +uint        sizeS2M(Fcall*);
       +
       +int        statcheck(uchar *abuf, uint nbuf);
       +uint        convM2D(uchar*, uint, Dir*, char*);
       +uint        convD2M(Dir*, uchar*, uint);
       +uint        sizeD2M(Dir*);
       +
       +int        fcallfmt(Fmt*);
       +int        dirfmt(Fmt*);
       +int        dirmodefmt(Fmt*);
       +
       +int        read9pmsg(int, void*, uint);
       +
       +/*
       +#pragma        varargck        type        "F"        Fcall*
       +#pragma        varargck        type        "M"        ulong
       +#pragma        varargck        type        "D"        Dir*
       +*/
 (DIR) diff --git a/include/flate.h b/include/flate.h
       t@@ -0,0 +1,41 @@
       +/*
       +#pragma        lib        "libflate.a"
       +#pragma        src        "/sys/src/libflate"
       +*/
       +
       +/*
       + * errors from deflate, deflateinit, deflateblock,
       + * inflate, inflateinit, inflateblock.
       + * convertable to a string by flateerr
       + */
       +enum
       +{
       +        FlateOk                        = 0,
       +        FlateNoMem                = -1,
       +        FlateInputFail                = -2,
       +        FlateOutputFail                = -3,
       +        FlateCorrupted                = -4,
       +        FlateInternal                = -5,
       +};
       +
       +int        deflateinit(void);
       +int        deflate(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug);
       +
       +int        inflateinit(void);
       +int        inflate(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*));
       +
       +int        inflateblock(uchar *dst, int dsize, uchar *src, int ssize);
       +int        deflateblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug);
       +
       +int        deflatezlib(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug);
       +int        inflatezlib(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*));
       +
       +int        inflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize);
       +int        deflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug);
       +
       +char        *flateerr(int err);
       +
       +ulong        *mkcrctab(ulong);
       +ulong        blockcrc(ulong *tab, ulong crc, void *buf, int n);
       +
       +ulong        adler32(ulong adler, void *buf, int n);
 (DIR) diff --git a/include/httpd.h b/include/httpd.h
       t@@ -0,0 +1,280 @@
       +/*
       +#pragma        lib        "libhttpd.a"
       +#pragma        src        "/sys/src/libhttpd"
       +*/
       +
       +typedef struct HConnect                HConnect;
       +typedef struct HContent                HContent;
       +typedef struct HContents        HContents;
       +typedef struct HETag                HETag;
       +typedef struct HFields                HFields;
       +typedef struct Hio                Hio;
       +typedef struct Htmlesc                Htmlesc;
       +typedef struct HttpHead                HttpHead;
       +typedef struct HttpReq                HttpReq;
       +typedef struct HRange                HRange;
       +typedef struct HSPairs                HSPairs;
       +
       +#ifndef _HAVE_BIN
       +typedef struct Bin                Bin;
       +#define _HAVE_BIN
       +#endif
       +
       +enum
       +{
       +        HMaxWord        = 32*1024,
       +        HBufSize        = 32*1024,
       +
       +        /*
       +         * error messages
       +         */
       +        HInternal        = 0,
       +        HTempFail,
       +        HUnimp,
       +        HBadReq,
       +        HBadSearch,
       +        HNotFound,
       +        HUnauth,
       +        HSyntax,
       +        HNoSearch,
       +        HNoData,
       +        HExpectFail,
       +        HUnkVers,
       +        HBadCont,
       +        HOK,
       +};
       +
       +/*
       + * table of html character escape codes
       + */
       +struct Htmlesc
       +{
       +        char                *name;
       +        Rune                value;
       +};
       +
       +struct HContent
       +{
       +        HContent        *next;
       +        char                *generic;
       +        char                *specific;
       +        float                q;                        /* desirability of this kind of file */
       +        int                mxb;                        /* max uchars until worthless */
       +};
       +
       +struct HContents
       +{
       +        HContent        *type;
       +        HContent         *encoding;
       +};
       +
       +/*
       + * generic http header with a list of tokens,
       + * each with an optional list of parameters
       + */
       +struct HFields
       +{
       +        char                *s;
       +        HSPairs                *params;
       +        HFields                *next;
       +};
       +
       +/*
       + * list of pairs a strings
       + * used for tag=val pairs for a search or form submission,
       + * and attribute=value pairs in headers.
       + */
       +struct HSPairs
       +{
       +        char                *s;
       +        char                *t;
       +        HSPairs                *next;
       +};
       +
       +/*
       + * byte ranges within a file
       + */
       +struct HRange
       +{
       +        int                suffix;                        /* is this a suffix request? */
       +        ulong                start;
       +        ulong                stop;                        /* ~0UL -> not given */
       +        HRange                *next;
       +};
       +
       +/*
       + * list of http/1.1 entity tags
       + */
       +struct HETag
       +{
       +        char                *etag;
       +        int                weak;
       +        HETag                *next;
       +};
       +
       +/*
       + * HTTP custom IO
       + * supports chunked transfer encoding
       + * and initialization of the input buffer from a string.
       + */
       +enum
       +{
       +        Hnone,
       +        Hread,
       +        Hend,
       +        Hwrite,
       +        Herr,
       +
       +        Hsize = HBufSize
       +};
       +
       +struct Hio {
       +        Hio                *hh;                        /* next lower layer Hio, or nil if reads from fd */
       +        int                fd;                        /* associated file descriptor */
       +        ulong                seek;                        /* of start */
       +        uchar                state;                        /* state of the file */
       +        uchar                xferenc;                /* chunked transfer encoding state */
       +        uchar                *pos;                        /* current position in the buffer */
       +        uchar                *stop;                        /* last character active in the buffer */
       +        uchar                *start;                        /* start of data buffer */
       +        ulong                bodylen;                /* remaining length of message body */
       +        uchar                buf[Hsize+32];
       +};
       +
       +/*
       + * request line
       + */
       +struct HttpReq
       +{
       +        char                *meth;
       +        char                *uri;
       +        char                *urihost;
       +        char                *search;
       +        int                vermaj;
       +        int                vermin;
       +};
       +
       +/*
       + * header lines
       + */
       +struct HttpHead
       +{
       +        int                closeit;                /* http1.1 close connection after this request? */
       +        uchar                persist;                /* http/1.1 requests a persistent connection */
       +
       +        uchar                expectcont;                /* expect a 100-continue */
       +        uchar                expectother;                /* expect anything else; should reject with ExpectFail */
       +        ulong                contlen;                /* if != ~0UL, length of included message body */
       +        HFields                *transenc;                /* if present, encoding of included message body */
       +        char                *client;
       +        char                *host;
       +        HContent        *okencode;
       +        HContent        *oklang;
       +        HContent        *oktype;
       +        HContent        *okchar;
       +        ulong                ifmodsince;
       +        ulong                ifunmodsince;
       +        ulong                ifrangedate;
       +        HETag                *ifmatch;
       +        HETag                *ifnomatch;
       +        HETag                *ifrangeetag;
       +        HRange                *range;
       +        char                *authuser;                /* authorization info */
       +        char                *authpass;
       +
       +        /*
       +         * experimental headers
       +         */
       +        int                fresh_thresh;
       +        int                fresh_have;
       +};
       +
       +/*
       + * all of the state for a particular connection
       + */
       +struct HConnect
       +{
       +        void                *private;                /* for the library clients */
       +        void                (*replog)(HConnect*, char*, ...);        /* called when reply sent */
       +
       +        HttpReq                req;
       +        HttpHead        head;
       +
       +        Bin                *bin;
       +
       +        ulong                reqtime;                /* time at start of request */
       +        char                xferbuf[HBufSize];        /* buffer for making up or transferring data */
       +        uchar                header[HBufSize + 2];        /* room for \n\0 */
       +        uchar                *hpos;
       +        uchar                *hstop;
       +        Hio                hin;
       +        Hio                hout;
       +};
       +
       +/*
       + * configuration for all connections within the server
       + */
       +extern        char*                hmydomain;
       +extern        char*                hversion;
       +extern        Htmlesc                htmlesc[];
       +
       +/*
       + * .+2,/^$/ | sort -bd +1
       + */
       +void                        *halloc(HConnect *c, ulong size);
       +Hio                        *hbodypush(Hio *hh, ulong len, HFields *te);
       +int                        hbuflen(Hio *h, void *p);
       +int                        hcheckcontent(HContent*, HContent*, char*, int);
       +void                        hclose(Hio*);
       +ulong                        hdate2sec(char*);
       +int                        hdatefmt(Fmt*);
       +int                        hfail(HConnect*, int, ...);
       +int                        hflush(Hio*);
       +int                        hgetc(Hio*);
       +int                        hgethead(HConnect *c, int many);
       +int                        hinit(Hio*, int, int);
       +int                        hiserror(Hio *h);
       +int                        hload(Hio*, char*);
       +char                        *hlower(char*);
       +HContent                *hmkcontent(HConnect *c, char *generic, char *specific, HContent *next);
       +HFields                        *hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next);
       +char                        *hmkmimeboundary(HConnect *c);
       +HSPairs                        *hmkspairs(HConnect *c, char *s, char *t, HSPairs *next);
       +int                        hmoved(HConnect *c, char *uri);
       +void                        hokheaders(HConnect *c);
       +int                        hparseheaders(HConnect*, int timeout);
       +HSPairs                        *hparsequery(HConnect *c, char *search);
       +int                        hparsereq(HConnect *c, int timeout);
       +int                        hprint(Hio*, char*, ...);
       +int                        hputc(Hio*, int);
       +void                        *hreadbuf(Hio *h, void *vsave);
       +int                        hredirected(HConnect *c, char *how, char *uri);
       +void                        hreqcleanup(HConnect *c);
       +HFields                        *hrevhfields(HFields *hf);
       +HSPairs                        *hrevspairs(HSPairs *sp);
       +char                        *hstrdup(HConnect *c, char *s);
       +int                        http11(HConnect*);
       +int                        httpfmt(Fmt*);
       +char                        *httpunesc(HConnect *c, char *s);
       +int                        hunallowed(HConnect *, char *allowed);
       +int                        hungetc(Hio *h);
       +char                        *hunload(Hio*);
       +int                        hurlfmt(Fmt*);
       +char                        *hurlunesc(HConnect *c, char *s);
       +int                        hwrite(Hio*, void*, int);
       +int                        hxferenc(Hio*, int);
       +
       +/*
       +#pragma                        varargck        argpos        hprint        2
       +*/
       +/*
       + * D is httpd format date conversion
       + * U is url escape convertsion
       + * H is html escape conversion
       + */
       +/*
       +#pragma        varargck        type        "D"        long
       +#pragma        varargck        type        "D"        ulong
       +#pragma        varargck        type        "U"        char*
       +#pragma        varargck        type        "H"        char*
       +*/
 (DIR) diff --git a/include/ip.h b/include/ip.h
       t@@ -0,0 +1,123 @@
       +/*
       +#pragma        src        "/sys/src/libip"
       +#pragma        lib        "libip.a"
       +#pragma        varargck        type        "I"        uchar*
       +#pragma        varargck        type        "V"        uchar*
       +#pragma        varargck        type        "E"        uchar*
       +#pragma        varargck        type        "M"        uchar*
       +*/
       +enum 
       +{
       +        IPaddrlen=        16,
       +        IPv4addrlen=        4,
       +        IPv4off=        12,
       +        IPllen=                4,
       +};
       +
       +/*
       + *  for reading /net/ipifc
       + */
       +typedef struct Ipifc Ipifc;
       +typedef struct Iplifc Iplifc;
       +typedef struct Ipv6rp Ipv6rp;
       +
       +/* local address */
       +struct Iplifc
       +{
       +        Iplifc        *next;
       +
       +        /* per address on the ip interface */
       +        uchar        ip[IPaddrlen];
       +        uchar        mask[IPaddrlen];
       +        uchar        net[IPaddrlen];                /* ip & mask */
       +        ulong        preflt;                        /* preferred lifetime */
       +        ulong        validlt;                /* valid lifetime */
       +};
       +
       +/* default values, one per stack */
       +struct Ipv6rp
       +{
       +        int        mflag;
       +        int        oflag;
       +        int         maxraint;
       +        int        minraint;
       +        int        linkmtu;
       +        int        reachtime;
       +        int        rxmitra;
       +        int        ttl;
       +        int        routerlt;        
       +};
       +
       +/* actual interface */
       +struct Ipifc
       +{
       +        Ipifc        *next;
       +        Iplifc        *lifc;
       +
       +        /* per ip interface */
       +        int        index;                        /* number of interface in ipifc dir */
       +        char        dev[64];
       +        uchar        sendra6;                /* on == send router adv */
       +        uchar        recvra6;                /* on == rcv router adv */
       +        int        mtu;
       +        ulong        pktin;
       +        ulong        pktout;
       +        ulong        errin;
       +        ulong        errout;
       +        Ipv6rp        rp;
       +};
       +
       +/*
       + *  user level udp headers
       + */
       +enum 
       +{
       +        Udphdrsize=        36,        /* size of a Udphdr */
       +};
       +
       +typedef struct Udphdr Udphdr;
       +struct Udphdr
       +{
       +        uchar        raddr[IPaddrlen];        /* remote address and port */
       +        uchar        laddr[IPaddrlen];        /* local address and port */
       +        uchar        rport[2];
       +        uchar        lport[2];
       +};
       +
       +uchar*        defmask(uchar*);
       +void        maskip(uchar*, uchar*, uchar*);
       +int        eipfmt(Fmt*);
       +int        isv4(uchar*);
       +ulong        parseip(uchar*, char*);
       +ulong        parseipmask(uchar*, char*);
       +char*        v4parseip(uchar*, char*);
       +char*        v4parsecidr(uchar*, uchar*, char*);
       +int        parseether(uchar*, char*);
       +int        myipaddr(uchar*, char*);
       +int        myetheraddr(uchar*, char*);
       +int        equivip(uchar*, uchar*);
       +
       +Ipifc*        readipifc(char*, Ipifc*, int);
       +
       +void        hnputl(void*, uint);
       +void        hnputs(void*, ushort);
       +uint        nhgetl(void*);
       +ushort        nhgets(void*);
       +ushort        ptclbsum(uchar*, int);
       +
       +int        v6tov4(uchar*, uchar*);
       +void        v4tov6(uchar*, uchar*);
       +
       +#define        ipcmp(x, y) memcmp(x, y, IPaddrlen)
       +#define        ipmove(x, y) memmove(x, y, IPaddrlen)
       +
       +extern uchar IPv4bcast[IPaddrlen];
       +extern uchar IPv4bcastobs[IPaddrlen];
       +extern uchar IPv4allsys[IPaddrlen];
       +extern uchar IPv4allrouter[IPaddrlen];
       +extern uchar IPnoaddr[IPaddrlen];
       +extern uchar v4prefix[IPaddrlen];
       +extern uchar IPallbits[IPaddrlen];
       +
       +#define CLASS(p) ((*(uchar*)(p))>>6)
       +
 (DIR) diff --git a/include/libsec.h b/include/libsec.h
       t@@ -0,0 +1,340 @@
       +/*
       +#pragma        lib        "libsec.a"
       +#pragma        src        "/sys/src/libsec"
       +*/
       +
       +#ifndef _MPINT
       +typedef struct mpint mpint;
       +#endif
       +
       +/////////////////////////////////////////////////////////
       +// AES definitions
       +/////////////////////////////////////////////////////////
       +
       +enum
       +{
       +        AESbsize=        16,
       +        AESmaxkey=        32,
       +        AESmaxrounds=        14
       +};
       +
       +typedef struct AESstate AESstate;
       +struct AESstate
       +{
       +        ulong        setup;
       +        int        rounds;
       +        int        keybytes;
       +        uchar        key[AESmaxkey];                /* unexpanded key */
       +        u32int        ekey[4*(AESmaxrounds + 1)];        /* encryption key */
       +        u32int        dkey[4*(AESmaxrounds + 1)];        /* decryption key */
       +        uchar        ivec[AESbsize];        /* initialization vector */
       +};
       +
       +void        setupAESstate(AESstate *s, uchar key[], int keybytes, uchar *ivec);
       +void        aesCBCencrypt(uchar *p, int len, AESstate *s);
       +void        aesCBCdecrypt(uchar *p, int len, AESstate *s);
       +
       +/////////////////////////////////////////////////////////
       +// Blowfish Definitions
       +/////////////////////////////////////////////////////////
       +
       +enum
       +{
       +        BFbsize        = 8,
       +        BFrounds        = 16
       +};
       +
       +// 16-round Blowfish
       +typedef struct BFstate BFstate;
       +struct BFstate
       +{
       +        ulong        setup;
       +
       +        uchar        key[56];
       +        uchar        ivec[8];
       +
       +        u32int         pbox[BFrounds+2];
       +        u32int        sbox[1024];
       +};
       +
       +void        setupBFstate(BFstate *s, uchar key[], int keybytes, uchar *ivec);
       +void        bfCBCencrypt(uchar*, int, BFstate*);
       +void        bfCBCdecrypt(uchar*, int, BFstate*);
       +void        bfECBencrypt(uchar*, int, BFstate*);
       +void        bfECBdecrypt(uchar*, int, BFstate*);
       +
       +/////////////////////////////////////////////////////////
       +// DES definitions
       +/////////////////////////////////////////////////////////
       +
       +enum
       +{
       +        DESbsize=        8
       +};
       +
       +// single des
       +typedef struct DESstate DESstate;
       +struct DESstate
       +{
       +        ulong        setup;
       +        uchar        key[8];                /* unexpanded key */
       +        ulong        expanded[32];        /* expanded key */
       +        uchar        ivec[8];        /* initialization vector */
       +};
       +
       +void        setupDESstate(DESstate *s, uchar key[8], uchar *ivec);
       +void        des_key_setup(uchar[8], ulong[32]);
       +void        block_cipher(ulong*, uchar*, int);
       +void        desCBCencrypt(uchar*, int, DESstate*);
       +void        desCBCdecrypt(uchar*, int, DESstate*);
       +void        desECBencrypt(uchar*, int, DESstate*);
       +void        desECBdecrypt(uchar*, int, DESstate*);
       +
       +// for backward compatibility with 7 byte DES key format
       +void        des56to64(uchar *k56, uchar *k64);
       +void        des64to56(uchar *k64, uchar *k56);
       +void        key_setup(uchar[7], ulong[32]);
       +
       +// triple des encrypt/decrypt orderings
       +enum {
       +        DES3E=                0,
       +        DES3D=                1,
       +        DES3EEE=        0,
       +        DES3EDE=        2,
       +        DES3DED=        5,
       +        DES3DDD=        7
       +};
       +
       +typedef struct DES3state DES3state;
       +struct DES3state
       +{
       +        ulong        setup;
       +        uchar        key[3][8];                /* unexpanded key */
       +        ulong        expanded[3][32];        /* expanded key */
       +        uchar        ivec[8];                /* initialization vector */
       +};
       +
       +void        setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec);
       +void        triple_block_cipher(ulong keys[3][32], uchar*, int);
       +void        des3CBCencrypt(uchar*, int, DES3state*);
       +void        des3CBCdecrypt(uchar*, int, DES3state*);
       +void        des3ECBencrypt(uchar*, int, DES3state*);
       +void        des3ECBdecrypt(uchar*, int, DES3state*);
       +
       +/////////////////////////////////////////////////////////
       +// digests
       +/////////////////////////////////////////////////////////
       +
       +enum
       +{
       +        SHA1dlen=        20,        /* SHA digest length */
       +        MD4dlen=        16,        /* MD4 digest length */
       +        MD5dlen=        16        /* MD5 digest length */
       +};
       +
       +typedef struct DigestState DigestState;
       +struct DigestState
       +{
       +        ulong len;
       +        u32int state[5];
       +        uchar buf[128];
       +        int blen;
       +        char malloced;
       +        char seeded;
       +};
       +typedef struct DigestState SHAstate;        /* obsolete name */
       +typedef struct DigestState SHA1state;
       +typedef struct DigestState MD5state;
       +typedef struct DigestState MD4state;
       +
       +DigestState* md4(uchar*, ulong, uchar*, DigestState*);
       +DigestState* md5(uchar*, ulong, uchar*, DigestState*);
       +DigestState* sha1(uchar*, ulong, uchar*, DigestState*);
       +DigestState* hmac_md5(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
       +DigestState* hmac_sha1(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
       +char* sha1pickle(SHA1state*);
       +SHA1state* sha1unpickle(char*);
       +
       +/////////////////////////////////////////////////////////
       +// random number generation
       +/////////////////////////////////////////////////////////
       +void        genrandom(uchar *buf, int nbytes);
       +void        prng(uchar *buf, int nbytes);
       +ulong        fastrand(void);
       +ulong        nfastrand(ulong);
       +
       +/////////////////////////////////////////////////////////
       +// primes
       +/////////////////////////////////////////////////////////
       +void        genprime(mpint *p, int n, int accuracy); // generate an n bit probable prime
       +void        gensafeprime(mpint *p, mpint *alpha, int n, int accuracy);        // prime and generator
       +void        genstrongprime(mpint *p, int n, int accuracy);        // generate an n bit strong prime
       +void        DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen]);
       +int        probably_prime(mpint *n, int nrep);        // miller-rabin test
       +int        smallprimetest(mpint *p);                // returns -1 if not prime, 0 otherwise
       +
       +/////////////////////////////////////////////////////////
       +// rc4
       +/////////////////////////////////////////////////////////
       +typedef struct RC4state RC4state;
       +struct RC4state
       +{
       +         uchar state[256];
       +         uchar x;
       +         uchar y;
       +};
       +
       +void        setupRC4state(RC4state*, uchar*, int);
       +void        rc4(RC4state*, uchar*, int);
       +void        rc4skip(RC4state*, int);
       +void        rc4back(RC4state*, int);
       +
       +/////////////////////////////////////////////////////////
       +// rsa
       +/////////////////////////////////////////////////////////
       +typedef struct RSApub RSApub;
       +typedef struct RSApriv RSApriv;
       +
       +// public/encryption key
       +struct RSApub
       +{
       +        mpint        *n;        // modulus
       +        mpint        *ek;        // exp (encryption key)
       +};
       +
       +// private/decryption key
       +struct RSApriv
       +{
       +        RSApub        pub;
       +
       +        mpint        *dk;        // exp (decryption key)
       +
       +        // precomputed values to help with chinese remainder theorem calc
       +        mpint        *p;
       +        mpint        *q;
       +        mpint        *kp;        // dk mod p-1
       +        mpint        *kq;        // dk mod q-1
       +        mpint        *c2;        // (inv p) mod q
       +};
       +
       +RSApriv*        rsagen(int nlen, int elen, int rounds);
       +mpint*                rsaencrypt(RSApub *k, mpint *in, mpint *out);
       +mpint*                rsadecrypt(RSApriv *k, mpint *in, mpint *out);
       +RSApub*                rsapuballoc(void);
       +void                rsapubfree(RSApub*);
       +RSApriv*        rsaprivalloc(void);
       +void                rsaprivfree(RSApriv*);
       +RSApub*                rsaprivtopub(RSApriv*);
       +RSApub*                X509toRSApub(uchar*, int, char*, int);
       +RSApriv*        asn1toRSApriv(uchar*, int);
       +uchar*                decodepem(char *s, char *type, int *len);
       +uchar*                X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
       +
       +/////////////////////////////////////////////////////////
       +// elgamal
       +/////////////////////////////////////////////////////////
       +typedef struct EGpub EGpub;
       +typedef struct EGpriv EGpriv;
       +typedef struct EGsig EGsig;
       +
       +// public/encryption key
       +struct EGpub
       +{
       +        mpint        *p;        // modulus
       +        mpint        *alpha;        // generator
       +        mpint        *key;        // (encryption key) alpha**secret mod p
       +};
       +
       +// private/decryption key
       +struct EGpriv
       +{
       +        EGpub        pub;
       +        mpint        *secret; // (decryption key)
       +};
       +
       +// signature
       +struct EGsig
       +{
       +        mpint        *r, *s;
       +};
       +
       +EGpriv*                eggen(int nlen, int rounds);
       +mpint*                egencrypt(EGpub *k, mpint *in, mpint *out);
       +mpint*                egdecrypt(EGpriv *k, mpint *in, mpint *out);
       +EGsig*                egsign(EGpriv *k, mpint *m);
       +int                egverify(EGpub *k, EGsig *sig, mpint *m);
       +EGpub*                egpuballoc(void);
       +void                egpubfree(EGpub*);
       +EGpriv*                egprivalloc(void);
       +void                egprivfree(EGpriv*);
       +EGsig*                egsigalloc(void);
       +void                egsigfree(EGsig*);
       +EGpub*                egprivtopub(EGpriv*);
       +
       +/////////////////////////////////////////////////////////
       +// dsa
       +/////////////////////////////////////////////////////////
       +typedef struct DSApub DSApub;
       +typedef struct DSApriv DSApriv;
       +typedef struct DSAsig DSAsig;
       +
       +// public/encryption key
       +struct DSApub
       +{
       +        mpint        *p;        // modulus
       +        mpint        *q;        // group order, q divides p-1
       +        mpint        *alpha;        // group generator
       +        mpint        *key;        // (encryption key) alpha**secret mod p
       +};
       +
       +// private/decryption key
       +struct DSApriv
       +{
       +        DSApub        pub;
       +        mpint        *secret; // (decryption key)
       +};
       +
       +// signature
       +struct DSAsig
       +{
       +        mpint        *r, *s;
       +};
       +
       +DSApriv*        dsagen(DSApub *opub);
       +DSAsig*                dsasign(DSApriv *k, mpint *m);
       +int                dsaverify(DSApub *k, DSAsig *sig, mpint *m);
       +DSApub*                dsapuballoc(void);
       +void                dsapubfree(DSApub*);
       +DSApriv*        dsaprivalloc(void);
       +void                dsaprivfree(DSApriv*);
       +DSAsig*                dsasigalloc(void);
       +void                dsasigfree(DSAsig*);
       +DSApub*                dsaprivtopub(DSApriv*);
       +
       +/////////////////////////////////////////////////////////
       +// TLS
       +/////////////////////////////////////////////////////////
       +typedef struct Thumbprint{
       +        struct Thumbprint *next;
       +        uchar sha1[SHA1dlen];
       +} Thumbprint;
       +
       +typedef struct TLSconn{
       +        char dir[40];  // connection directory
       +        uchar *cert;   // certificate (local on input, remote on output)
       +        uchar *sessionID;
       +        int certlen, sessionIDlen;
       +        int (*trace)(char*fmt, ...);
       +} TLSconn;
       +
       +// tlshand.c
       +extern int tlsClient(int fd, TLSconn *c);
       +extern int tlsServer(int fd, TLSconn *c);
       +
       +// thumb.c
       +extern Thumbprint* initThumbprints(char *ok, char *crl);
       +extern void freeThumbprints(Thumbprint *ok);
       +extern int okThumbprint(uchar *sha1, Thumbprint *ok);
       +
       +// readcert.c
       +extern uchar *readcert(char *filename, int *pcertlen);
 (DIR) diff --git a/include/plumb.h b/include/plumb.h
       t@@ -1,5 +1,7 @@
       +/*
        #pragma        lib        "libplumb.a"
        #pragma        src        "/sys/src/libplumb"
       +*/
        
        /*
         * Message format:
 (DIR) diff --git a/include/regexp.h b/include/regexp.h
       t@@ -0,0 +1 @@
       +#include <regexp9.h>
 (DIR) diff --git a/include/venti.h b/include/venti.h
       t@@ -0,0 +1,414 @@
       +/* XXX should be own library? */
       +/*
       + * Packets
       + */
       +enum
       +{
       +        MaxFragSize = 9*1024,
       +};
       +
       +typedef struct Packet Packet;
       +Packet *packetalloc(void);
       +void packetfree(Packet*);
       +Packet *packetforeign(uchar *buf, int n, void (*free)(void *a), void *a);
       +Packet *packetdup(Packet*, int offset, int n);
       +Packet *packetsplit(Packet*, int n);
       +int packetconsume(Packet*, uchar *buf, int n);
       +int packettrim(Packet*, int offset, int n);
       +uchar *packetheader(Packet*, int n);
       +uchar *packettrailer(Packet*, int n);
       +int packetprefix(Packet*, uchar *buf, int n);
       +int packetappend(Packet*, uchar *buf, int n);
       +int packetconcat(Packet*, Packet*);
       +uchar *packetpeek(Packet*, uchar *buf, int offset, int n);
       +int packetcopy(Packet*, uchar *buf, int offset, int n);
       +int packetfragments(Packet*, IOchunk*, int nio, int offset);
       +uint packetsize(Packet*);
       +uint packetasize(Packet*);
       +int packetcompact(Packet*);
       +int packetcmp(Packet*, Packet*);
       +void packetstats(void);
       +void packetsha1(Packet*, uchar sha1[20]);
       +
       +/* XXX begin actual venti.h */
       +
       +/*
       +#pragma lib "libnventi.a"
       +#pragma src "/sys/src/libnventi"
       +*/
       +
       +typedef struct VtFcall VtFcall;
       +typedef struct VtSha1 VtSha1;
       +typedef struct VtConn VtConn;
       +typedef struct VtEntry VtEntry;
       +typedef struct VtRoot VtRoot;
       +
       +/*
       + * Fundamental constants.
       + */
       +enum
       +{
       +        VtScoreSize = 20,
       +        VtMaxStringSize = 1024,
       +        VtMaxFileSize = (1ULL<<48) - 1,
       +        VtMaxLumpSize        = 56*1024,
       +        VtPointerDepth        = 7,
       +};
       +
       +/* 
       + * Strings in packets.
       + */
       +int vtputstring(Packet*, char*);
       +int vtgetstring(Packet*, char**);
       +
       +/*
       + * Block types.
       + * 
       + * The initial Venti protocol had a much
       + * less regular list of block types.
       + * VtToDiskType converts from new to old.
       + */
       +enum
       +{
       +        VtDataType        = 0<<3,
       +        /* VtDataType+1, ... */
       +        VtDirType        = 1<<3,
       +        /* VtDirType+1, ... */
       +        VtRootType        = 2<<3,
       +        VtCorruptType,
       +        VtMaxType,
       +
       +        VtTypeDepthMask = 7,
       +};
       +
       +/* convert to/from on-disk type numbers */
       +uint vttodisktype(uint);
       +uint vtfromdisktype(uint);
       +
       +/*
       + * VtEntry describes a Venti stream
       + */
       +enum
       +{
       +        VtEntryActive = 1<<0,                /* entry is in use */
       +        VtEntryDir = 1<<1,                /* a directory */
       +        VtEntryDepthShift = 2,                /* shift for pointer depth */
       +        VtEntryDepthMask = 7<<2,        /* mask for pointer depth */
       +        VtEntryLocal = 1<<5,                /* for local storage only */
       +};
       +enum
       +{
       +        VtEntrySize = 40,
       +};
       +struct VtEntry
       +{
       +        ulong gen;                        /* generation number */
       +        ushort psize;                        /* pointer block size */
       +        ushort dsize;                        /* data block size */
       +        uchar type;
       +        uchar flags;
       +        uvlong size;
       +        uchar score[VtScoreSize];
       +};
       +
       +void vtentrypack(VtEntry*, uchar*, int index);
       +int vtentryunpack(VtEntry*, uchar*, int index);
       +
       +struct VtRoot
       +{
       +        char name[128];
       +        char type[128];
       +        uchar score[VtScoreSize];        /* to a Dir block */
       +        ushort blocksize;                /* maximum block size */
       +        uchar prev[VtScoreSize];        /* last root block */
       +};
       +
       +enum
       +{
       +        VtRootSize = 300,
       +        VtRootVersion = 2,
       +};
       +
       +void vtrootpack(VtRoot*, uchar*);
       +int vtrootunpack(VtRoot*, uchar*);
       +
       +/*
       + * score of zero length block
       + */
       +extern uchar vtzeroscore[VtScoreSize];
       +
       +/*
       + * zero extend and truncate blocks
       + */
       +void vtzeroextend(int type, uchar *buf, uint n, uint nn);
       +uint vtzerotruncate(int type, uchar *buf, uint n);
       +
       +/*
       + * parse score: mungs s
       + */
       +int vtparsescore(char *s, uint len, char **prefix, uchar[VtScoreSize]);
       +
       +/*
       + * formatting
       + * other than noted, these formats all ignore
       + * the width and precision arguments, and all flags
       + *
       + * V        a venti score
       + */
       +/* #pragma        varargck        type        "V"                uchar* */
       +
       +int vtscorefmt(Fmt*);
       +
       +/*
       + * error-checking malloc et al.
       + */
       +void vtfree(void *);
       +void *vtmalloc(int);
       +void *vtmallocz(int);
       +void *vtrealloc(void *p, int);
       +void *vtbrk(int n);
       +char *vtstrdup(char *);
       +
       +/*
       + * Venti protocol
       + */
       +
       +/*
       + * Crypto strengths
       + */
       +enum
       +{
       +        VtCryptoStrengthNone,
       +        VtCryptoStrengthAuth,
       +        VtCryptoStrengthWeak,
       +        VtCryptoStrengthStrong,
       +};
       +
       +/*
       + * Crypto suites
       + */
       +enum
       +{
       +        VtCryptoNone,
       +        VtCryptoSSL3,
       +        VtCryptoTLS1,
       +        VtCryptoMax,
       +};
       +
       +/* 
       + * Codecs
       + */
       +enum
       +{
       +        VtCodecNone,
       +        VtCodecDeflate,
       +        VtCodecThwack,
       +        VtCodecMax
       +};
       +
       +enum
       +{
       +        VtRerror        = 1,
       +        VtTping                = 2,
       +        VtRping,
       +        VtThello        = 4,
       +        VtRhello,
       +        VtTgoodbye        = 6,
       +        VtRgoodbye,        /* not used */
       +        VtTauth0        = 8,
       +        VtRauth0,
       +        VtTauth1        = 10,
       +        VtRauth1,
       +        VtTread                = 12,
       +        VtRread,
       +        VtTwrite        = 14,
       +        VtRwrite,
       +        VtTsync                = 16,
       +        VtRsync,
       +
       +        VtTmax
       +};
       +
       +struct VtFcall
       +{
       +        uchar        type;
       +        uchar        tag;
       +
       +        char        *error;        /* Rerror */
       +
       +        char        *version;        /* Thello */
       +        char        *uid;                /* Thello */
       +        uchar        strength;        /* Thello */
       +        uchar        *crypto;        /* Thello */
       +        uint        ncrypto;        /* Thello */
       +        uchar        *codec;                /* Thello */
       +        uint        ncodec;                /* Thello */
       +        char        *sid;                /* Rhello */
       +        uchar        rcrypto;        /* Rhello */
       +        uchar        rcodec;                /* Rhello */
       +        uchar        *auth;                /* TauthX, RauthX */
       +        uint        nauth;                /* TauthX, RauthX */
       +        uchar        score[VtScoreSize];        /* Tread, Rwrite */
       +        uchar        dtype;                /* Tread, Twrite */
       +        ushort        count;                /* Tread */
       +        Packet        *data;                /* Rread, Twrite */
       +};
       +
       +Packet *vtfcallpack(VtFcall*);
       +int vtfcallunpack(VtFcall*, Packet*);
       +void vtfcallclear(VtFcall*);
       +int vtfcallfmt(Fmt*);
       +
       +enum
       +{
       +        VtStateAlloc,
       +        VtStateConnected,
       +        VtStateClosed,
       +};
       +
       +struct VtConn
       +{
       +        QLock        lk;
       +        QLock        inlk;
       +        QLock        outlk;
       +        int        debug;
       +        int        infd;
       +        int        outfd;
       +        int        muxer;
       +        void        *writeq;
       +        void        *readq;
       +        int        state;
       +        void *wait[256];
       +        uint        ntag;
       +        uint        nsleep;
       +        Packet        *part;
       +        Rendez        tagrend;
       +        Rendez        rpcfork;
       +        char        *version;
       +        char        *uid;
       +        char *sid;
       +};
       +
       +VtConn *vtconn(int infd, int outfd);
       +VtConn *vtdial(char*);
       +void vtfreeconn(VtConn*);
       +int vtsend(VtConn*, Packet*);
       +Packet *vtrecv(VtConn*);
       +int vtversion(VtConn *z);
       +void vtdebug(VtConn *z, char*, ...);
       +void vthangup(VtConn *z);
       +/* #pragma varargck argpos vtdebug 2 */
       +
       +/* server */
       +typedef struct VtSrv VtSrv;
       +typedef struct VtReq VtReq;
       +struct VtReq
       +{
       +        VtFcall tx;
       +        VtFcall rx;
       +/* private */
       +        VtSrv *srv;
       +        void *sc;
       +};
       +
       +int vtsrvhello(VtConn*);
       +VtSrv *vtlisten(char *addr);
       +VtReq *vtgetreq(VtSrv*);
       +void vtrespond(VtReq*);
       +
       +/* client */
       +Packet *vtrpc(VtConn*, Packet*);
       +void vtrecvproc(void*);        /* VtConn* */
       +void vtsendproc(void*);        /* VtConn* */
       +
       +int vtconnect(VtConn*);
       +int vthello(VtConn*);
       +int vtread(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
       +int vtwrite(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
       +Packet *vtreadpacket(VtConn*, uchar score[VtScoreSize], uint type, int n);
       +int vtwritepacket(VtConn*, uchar score[VtScoreSize], uint type, Packet *p);
       +int vtsync(VtConn*);
       +int vtping(VtConn*);
       +
       +/*
       + * Data blocks and block cache.
       + */
       +enum
       +{
       +        NilBlock = ~0,
       +};
       +
       +typedef struct VtBlock VtBlock;
       +typedef struct VtCache VtCache;
       +
       +struct VtBlock
       +{
       +        VtCache        *c;
       +        QLock        lk;
       +
       +        uchar        *data;
       +        uchar        score[VtScoreSize];
       +        uchar        type;        /* BtXXX */
       +
       +        /* internal to cache */
       +        int                nlock;
       +        int                iostate;
       +        int                ref;
       +        u32int        heap;
       +        VtBlock        *next;
       +        VtBlock        **prev;
       +        u32int        used;
       +        u32int        used2;
       +        u32int        addr;
       +
       +        /* internal to efile (HACK) */
       +        int                decrypted;
       +};
       +
       +u32int vtglobaltolocal(uchar[VtScoreSize]);
       +void vtlocaltoglobal(u32int, uchar[VtScoreSize]);
       +
       +VtCache *vtcachealloc(VtConn*, int blocksize, ulong nblocks, int mode);
       +void vtcachefree(VtCache*);
       +VtBlock *vtcachelocal(VtCache*, u32int addr, int type);
       +VtBlock *vtcacheglobal(VtCache*, uchar[VtScoreSize], int type);
       +VtBlock *vtcacheallocblock(VtCache*, int type);
       +void vtblockput(VtBlock*);
       +u32int vtcacheblocksize(VtCache*);
       +int vtblockwrite(VtBlock*);
       +VtBlock *vtblockcopy(VtBlock*);
       +void vtblockduplock(VtBlock*);
       +
       +/*
       + * Hash tree file tree.
       + */
       +typedef struct VtFile VtFile;
       +
       +enum
       +{
       +        VtOREAD,
       +        VtOWRITE,
       +        VtORDWR,
       +        VtOCREATE = 0x100,
       +};
       +
       +VtFile *vtfileopenroot(VtCache*, VtEntry*);
       +VtFile *vtfilecreateroot(VtCache*, int psize, int dsize, int type);
       +VtFile *vtfileopen(VtFile*, u32int, int);
       +VtFile *vtfilecreate(VtFile*, int psize, int dsize, int dir);
       +VtBlock *vtfileblock(VtFile*, u32int, int mode);
       +int vtfileblockhash(VtFile*, u32int, uchar[VtScoreSize]);
       +long vtfileread(VtFile*, void*, long, vlong);
       +long vtfilewrite(VtFile*, void*, long, vlong);
       +int vtfileflush(VtFile*);
       +void vtfileincref(VtFile*);
       +void vtfileclose(VtFile*);
       +int vtfilegetentry(VtFile*, VtEntry*);
       +int vtfileblockscore(VtFile*, u32int, uchar[VtScoreSize]);
       +u32int vtfilegetdirsize(VtFile*);
       +int vtfilesetdirsize(VtFile*, u32int);
       +void        vtfileunlock(VtFile*);
       +int vtfilelock(VtFile*, int);
       +int vtfilelock2(VtFile*, VtFile*, int);
       +int vtfileflushbefore(VtFile*, u64int);
       +