349 lines · 5.8 KB · C
RawDownload
#include <bio.h>#include <mp.h>#include <libsec.h>#include <flate.h>#include <regexp.h> typedef struct Conn	Conn;typedef struct Hash	Hash;typedef struct Delta	Delta;typedef struct Ocommit	Ocommit;typedef struct Otree	Otree;typedef struct Object	Object;typedef struct Objset	Objset;typedef struct Pack	Pack;typedef struct Buf	Buf;typedef struct Dirent	Dirent;typedef struct Idxent	Idxent;typedef struct Objlist	Objlist;typedef struct Dtab	Dtab;typedef struct Dblock	Dblock;typedef struct Objq	Objq;typedef struct Qelt	Qelt;typedef struct Idxent	Idxent; enum {	Pathmax		= 512,	Npackcache	= 32,	Hashsz		= 20,	Pktmax		= 65536,	KiB		= 1024,	MiB		= 1024*KiB,}; enum {	GNone	= 0,	GCommit	= 1,	GTree	= 2,	GBlob	= 3,	GTag	= 4,	GOdelta	= 6,	GRdelta	= 7,}; enum {	Cloaded	= 1 << 0,	Cidx	= 1 << 1,	Ccache	= 1 << 2,	Cexist	= 1 << 3,	Cparsed	= 1 << 5,	Cthin	= 1 << 6,}; enum {	ConnGit,	ConnGit9,	ConnSsh,	ConnHttp,}; struct Objlist {	int idx; 	int fd;	int state;	int stage; 	Dir *top;	int ntop;	int topidx;	Dir *loose;	int nloose;	int looseidx;	Dir *pack;	int npack;	int packidx;	int nent;	int entidx;}; struct Hash {	uchar h[20];}; struct Conn {	int type;	int rfd;	int wfd; 	/* capabilities */	char	symfrom[256];	char	symto[256];	char	multiack;	char	sideband;	char	sideband64k;	char	report; 	/* only used by http */	int cfd;	char *url;	/* note, first GET uses a different url */	char *dir;	char *direction;}; struct Dirent {	char *name;	int mode;	Hash h;	char ismod;	char islink;}; struct Object {	/* Git data */	Hash	hash;	int	type; 	/* Cache */	int	id;	int	flag;	int	refs;	Object	*next;	Object	*prev; 	/* For indexing */	vlong	off;	vlong	len;	u32int	crc; 	/* Everything below here gets cleared */	char	*all;	char	*data;	/* size excludes header */	vlong	size; 	/* Significant win on memory use */	union {		Ocommit	*commit;		Otree	*tree;	};}; struct Otree {	/* Tree */	Dirent	*ent;	int	nent;}; struct Ocommit {	/* Commit */	Hash	*parent;	int	nparent;	Hash	tree;	char	*author;	char	*committer;	char	*msg;	int	nmsg;	vlong	ctime;	vlong	mtime;}; struct Objset {	Object	**obj;	int	nobj;	int	sz;}; struct Qelt {	Object	*o;	vlong	ctime;	int	color;}; struct Objq {	Qelt	*heap;	int	nheap;	int	heapsz;}; struct Dtab {	Object	*o;	uchar	*base;	int	nbase;	Dblock	*b;	int	nb;	int	sz;}; struct Dblock {	uchar	*buf;	int	len;	int	off;	u64int	hash;}; struct Delta {	int	cpy;	int	off;	int	len;}; struct Idxent {	char	*path;	Qid	qid;	int	mode;	int	order;	char	state;}; #define GETBE16(b)\		((((b)[0] & 0xFFul) <<  8) | \		 (((b)[1] & 0xFFul) <<  0)) #define GETBE32(b)\		((((b)[0] & 0xFFul) << 24) | \		 (((b)[1] & 0xFFul) << 16) | \		 (((b)[2] & 0xFFul) <<  8) | \		 (((b)[3] & 0xFFul) <<  0))#define GETBE64(b)\		((((b)[0] & 0xFFull) << 56) | \		 (((b)[1] & 0xFFull) << 48) | \		 (((b)[2] & 0xFFull) << 40) | \		 (((b)[3] & 0xFFull) << 32) | \		 (((b)[4] & 0xFFull) << 24) | \		 (((b)[5] & 0xFFull) << 16) | \		 (((b)[6] & 0xFFull) <<  8) | \		 (((b)[7] & 0xFFull) <<  0)) #define PUTBE16(b, n)\	do{ \		(b)[0] = (n) >> 8; \		(b)[1] = (n) >> 0; \	} while(0) #define PUTBE32(b, n)\	do{ \		(b)[0] = (n) >> 24; \		(b)[1] = (n) >> 16; \		(b)[2] = (n) >> 8; \		(b)[3] = (n) >> 0; \	} while(0) #define PUTBE64(b, n)\	do{ \		(b)[0] = (n) >> 56; \		(b)[1] = (n) >> 48; \		(b)[2] = (n) >> 40; \		(b)[3] = (n) >> 32; \		(b)[4] = (n) >> 24; \		(b)[5] = (n) >> 16; \		(b)[6] = (n) >> 8; \		(b)[7] = (n) >> 0; \	} while(0) #define QDIR(qid)	((int)(qid)->path & (0xff))#define isblank(c) \	(((c) != '\n') && isspace(c)) extern Reprog	*authorpat;extern Objset	objcache;extern vlong	cachemax;extern Hash	Zhash;extern int	chattygit;extern int	interactive;extern int	gitdirmode; #pragma varargck type "H" Hash#pragma varargck type "T" int#pragma varargck type "O" Object*#pragma varargck type "Q" Qidint Hfmt(Fmt*);int Tfmt(Fmt*);int Ofmt(Fmt*);int Qfmt(Fmt*); void gitinit(char*, int, int*); /* object io */int	resolverefs(Hash **, char *);int	resolveref(Hash *, char *);int	listrefs(Hash **, char ***);Object	*ancestor(Object *, Object *);int	findtwixt(Hash *, int, Hash *, int, Object ***, int *);Object	*readobject(Hash);Object	*clearedobject(Hash, int);int	expandprefix(Hash*, Hash, int);void	parseobject(Object *);int	indexpack(char *, char *, Hash);int	writepack(int, Hash*, int, Hash*, int, Hash*);int	hasheq(Hash *, Hash *);Object	*ref(Object *);void	unref(Object *);void	cache(Object *);Object	*emptydir(void);int	entcmp(void*, void*); /* object sets */void	osinit(Objset *);void	osclear(Objset *);void	osadd(Objset *, Object *);int	oshas(Objset *, Hash);Object	*osfind(Objset *, Hash); /* object listing */Objlist	*mkols(void);int	olsnext(Objlist *, Hash *);void	olsfree(Objlist *); /* util functions */#define dprint(lvl, ...) \	if(chattygit >= lvl) _dprint(__VA_ARGS__)void	_dprint(char *, ...);void	*eamalloc(ulong, ulong);void	*emalloc(ulong);void	*earealloc(void *, ulong, ulong);void	*erealloc(void *, ulong);char	*estrdup(char *);int	slurpdir(char *, Dir **);int	hparse(Hash *, char *);int	hassuffix(char *, char *);int	swapsuffix(char *, int, char *, char *, char *);char	*strip(char *);int	showprogress(int, int);u64int	murmurhash2(void*, usize);Qid	parseqid(char*);int	charval(int); /* packing */void	dtinit(Dtab *, Object*);void	dtclear(Dtab*);Delta*	deltify(Object*, Dtab*, int*); /* proto handling */int	readpkt(Conn*, char*, int);int	writepkt(Conn*, char*, int);int	fmtpkt(Conn*, char*, ...);int	flushpkt(Conn*);void	initconn(Conn*, int, int);int	gitconnect(Conn *, char *, char *);int	readphase(Conn *);int	writephase(Conn *);void	closeconn(Conn *);void	parsecaps(char *, Conn *);int	okref(char*); /* queues */void	qinit(Objq*);void	qclear(Objq*);void	qput(Objq*, Object*, int);int	qpop(Objq*, Qelt*);