aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:25:35 +0000
committerrsc <devnull@localhost>2003-11-23 18:25:35 +0000
commit97a5e5f2dd40eff09cb650c91c21f680b6d4206a (patch)
tree1a5b4768a225e33683b1b8562b9dfa9f8d14e176
parent9e37bb03b38a732af1897289b2f519dbd74cd371 (diff)
downloadplan9port-97a5e5f2dd40eff09cb650c91c21f680b6d4206a.tar.gz
plan9port-97a5e5f2dd40eff09cb650c91c21f680b6d4206a.tar.bz2
plan9port-97a5e5f2dd40eff09cb650c91c21f680b6d4206a.zip
new files
-rw-r--r--include/bin.h13
-rw-r--r--include/fcall.h120
-rw-r--r--include/flate.h41
-rw-r--r--include/httpd.h280
-rw-r--r--include/ip.h123
-rw-r--r--include/libsec.h340
-rw-r--r--include/plumb.h2
-rw-r--r--include/regexp.h1
-rw-r--r--include/venti.h414
9 files changed, 1334 insertions, 0 deletions
diff --git a/include/bin.h b/include/bin.h
new file mode 100644
index 00000000..6b9f2bd4
--- /dev/null
+++ b/include/bin.h
@@ -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 **);
diff --git a/include/fcall.h b/include/fcall.h
new file mode 100644
index 00000000..93f46d4c
--- /dev/null
+++ b/include/fcall.h
@@ -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*
+*/
diff --git a/include/flate.h b/include/flate.h
new file mode 100644
index 00000000..79c888c2
--- /dev/null
+++ b/include/flate.h
@@ -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);
diff --git a/include/httpd.h b/include/httpd.h
new file mode 100644
index 00000000..d75c5801
--- /dev/null
+++ b/include/httpd.h
@@ -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*
+*/
diff --git a/include/ip.h b/include/ip.h
new file mode 100644
index 00000000..af82c993
--- /dev/null
+++ b/include/ip.h
@@ -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)
+
diff --git a/include/libsec.h b/include/libsec.h
new file mode 100644
index 00000000..17b2b651
--- /dev/null
+++ b/include/libsec.h
@@ -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);
diff --git a/include/plumb.h b/include/plumb.h
index abc56d08..e0b1132f 100644
--- a/include/plumb.h
+++ b/include/plumb.h
@@ -1,5 +1,7 @@
+/*
#pragma lib "libplumb.a"
#pragma src "/sys/src/libplumb"
+*/
/*
* Message format:
diff --git a/include/regexp.h b/include/regexp.h
new file mode 100644
index 00000000..59a57665
--- /dev/null
+++ b/include/regexp.h
@@ -0,0 +1 @@
+#include <regexp9.h>
diff --git a/include/venti.h b/include/venti.h
new file mode 100644
index 00000000..8e79c4b0
--- /dev/null
+++ b/include/venti.h
@@ -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);
+