Sigrid Solveig Haflínudóttirr32: fix a warning (thanks be0ba)8a4304a2 years agoHistory
1164 lines · 21.6 KB · C
RawDownload
#include <stdint.h>#include <string.h>#include "c9/proto.h" enum{	Svver = 1<<0,}; #define safestrlen(s) (s == NULL ? 0 : (uint32_t)strlen(s))#define maxread(c) (c->msize-4-4-1-2)#define maxwrite(c) maxread(c) static voidw08(uint8_t **p, uint8_t x){	(*p)[0] = x;	*p += 1;} static voidw16(uint8_t **p, uint16_t x){	(*p)[0] = x;	(*p)[1] = x>>8;	*p += 2;} static voidw32(uint8_t **p, uint32_t x){	(*p)[0] = x;	(*p)[1] = x>>8;	(*p)[2] = x>>16;	(*p)[3] = x>>24;	*p += 4;} static voidw64(uint8_t **p, uint64_t x){	(*p)[0] = x;	(*p)[1] = x>>8;	(*p)[2] = x>>16;	(*p)[3] = x>>24;	(*p)[4] = x>>32;	(*p)[5] = x>>40;	(*p)[6] = x>>48;	(*p)[7] = x>>56;	*p += 8;} static voidwcs(uint8_t **p, const char *s, int len){	w16(p, len);	if(s != NULL){		memmove(*p, s, len);		*p += len;	}} static uint8_tr08(uint8_t **p){	*p += 1;	return (*p)[-1];} static uint16_tr16(uint8_t **p){	*p += 2;	return (*p)[-2]<<0 | (*p)[-1]<<8;} static uint32_tr32(uint8_t **p){	*p += 4;	return (*p)[-4]<<0 | (*p)[-3]<<8 | (*p)[-2]<<16 | (uint32_t)((*p)[-1])<<24;} static uint64_tr64(uint8_t **p){	uint64_t v; 	v = r32(p);	v |= (uint64_t)r32(p)<<32;	return v;} #ifndef C9_NO_CLIENT static C9errornewtag(C9ctx *c, C9ttype type, C9tag *tag){	uint32_t i; 	if(type == Tversion){		*tag = 0xffff;		return 0;	} 	if(c->lowfreetag < C9maxtags){		uint32_t d = c->lowfreetag / C9tagsbits, m = c->lowfreetag % C9tagsbits;		if((c->tags[d] & 1<<m) != 0){			c->tags[d] &= ~(1<<m);			*tag = c->lowfreetag++;			return 0;		}	} 	for(i = 0; i < (int)sizeof(c->tags)/sizeof(c->tags[0]); i++){		uint32_t x, j;		if((x = c->tags[i]) == 0)			continue;		for(j = 0; j < C9tagsbits; j++){			if((x & (1<<j)) != 0){				c->tags[i] &= ~(1<<j);				*tag = i*C9tagsbits + j;				c->lowfreetag = *tag + 1;				return 0;			}		}	} 	c->error(c,  "newtag: no free tags");	return C9Etag;} static intfreetag(C9ctx *c, C9tag tag){	if(tag != 0xffff){		uint32_t d = tag / C9tagsbits, m = tag % C9tagsbits;		if(tag >= C9maxtags){			c->error(c, "freetag: invalid tag %ud", (uint32_t)tag);			return -1;		}		if((c->tags[d] & 1<<m) != 0){			c->error(c, "freetag: double free for tag %ud", (uint32_t)tag);			return -1;		}		if(c->lowfreetag > tag)			c->lowfreetag = tag;		c->tags[d] |= 1<<m;	}	return 0;} static uint8_t *T(C9ctx *c, uint32_t size, C9ttype type, C9tag *tag, C9error *err){	uint8_t *p = NULL; 	if(size > c->msize-4-1-2){		c->error(c, "T: invalid size %ud", size);		*err = C9Esize;	}else if((*err = newtag(c, type, tag)) == 0){		size += 4+1+2;		if((p = c->begin(c, size)) == NULL){			c->error(c, "T: no buffer for %ud bytes", size);			freetag(c, *tag);			*err = C9Ebuf;		}else{			*err = 0;			w32(&p, size);			w08(&p, type);			w16(&p, *tag);		}	}	return p;} C9errorc9version(C9ctx *c, C9tag *tag, uint32_t msize){	uint8_t *b;	C9error err; 	if(msize < C9minmsize){		c->error(c, "c9version: msize too small: %ud", msize);		return C9Einit;	}	memset(c->tags, 0xff, sizeof(c->tags));	memset(c->flush, 0xff, sizeof(c->flush));	c->lowfreetag = 0;	c->msize = msize; 	if((b = T(c, 4+2+6, Tversion, tag, &err)) != NULL){		w32(&b, msize);		wcs(&b, "9P2000", 6);		err = c->end(c);	}	return err;} C9errorc9auth(C9ctx *c, C9tag *tag, C9fid afid, const char *uname, const char *aname){	uint8_t *b;	uint32_t ulen = safestrlen(uname), alen = safestrlen(aname);	C9error err; 	if(ulen > C9maxstr || alen > C9maxstr){		c->error(c, "c9auth: string too long: %ud chars", ulen > alen ? ulen : alen);		return C9Estr;	}	if((b = T(c, 4+2+ulen+2+alen, Tauth, tag, &err)) != NULL){		w32(&b, afid);		wcs(&b, uname, ulen);		wcs(&b, aname, alen);		err = c->end(c);	}	return err;} C9errorc9flush(C9ctx *c, C9tag *tag, C9tag oldtag){	uint8_t *b;	C9error err;	int i; 	for(i = 0; i < C9maxflush && c->flush[i] != (uint32_t)~0; i++);	if(i == C9maxflush){		c->error(c, "c9flush: no free flush slots");		return C9Eflush;	}	if((b = T(c, 2, Tflush, tag, &err)) != NULL){		w16(&b, oldtag);		err = c->end(c);		if(err == 0)			c->flush[i] = (uint32_t)oldtag<<16 | *tag;	}	return err;} C9errorc9attach(C9ctx *c, C9tag *tag, C9fid fid, C9fid afid, const char *uname, const char *aname){	uint32_t ulen = safestrlen(uname), alen = safestrlen(aname);	uint8_t *b;	C9error err; 	if(ulen > C9maxstr || alen > C9maxstr){		c->error(c, "c9attach: string too long: %ud chars", ulen > alen ? ulen : alen);		return C9Estr;	}	if((b = T(c, 4+4+2+ulen+2+alen, Tattach, tag, &err)) != NULL){		w32(&b, fid);		w32(&b, afid);		wcs(&b, uname, ulen);		wcs(&b, aname, alen);		err = c->end(c);	}	return err;} C9errorc9walk(C9ctx *c, C9tag *tag, C9fid fid, C9fid newfid, const char *path[]){	uint32_t i, j, sz;	uint32_t len[C9maxpathel];	uint8_t *b;	C9error err; 	for(sz = i = 0; i < (int)sizeof(len)/sizeof(len[0]) && path[i] != NULL; i++){		len[i] = safestrlen(path[i]);		if(len[i] == 0 || len[i] > C9maxstr){			c->error(c, "c9walk: invalid path element: %ud chars", len[i]);			return C9Epath;		}		sz += 2 + len[i];	}	if(path[i] != NULL){		c->error(c, "c9walk: invalid elements !(0 <= %ud <= %ud)", i, C9maxpathel);		return C9Epath;	} 	if((b = T(c, 4+4+2+sz, Twalk, tag, &err)) != NULL){		w32(&b, fid);		w32(&b, newfid);		w16(&b, i);		for(j = 0; j < i; j++)			wcs(&b, path[j], len[j]);		err = c->end(c);	}	return err;} C9errorc9open(C9ctx *c, C9tag *tag, C9fid fid, C9mode mode){	uint8_t *b;	C9error err; 	if((b = T(c, 4+1, Topen, tag, &err)) != NULL){		w32(&b, fid);		w08(&b, mode);		err = c->end(c);	}	return err;} C9errorc9create(C9ctx *c, C9tag *tag, C9fid fid, const char *name, uint32_t perm, C9mode mode){	uint32_t nlen = strlen(name);	uint8_t *b;	C9error err; 	if(nlen == 0 || nlen > C9maxstr){		c->error(c, "c9create: invalid name: %ud chars", nlen);		return C9Epath;	}	if((b = T(c, 4+2+nlen+4+1, Tcreate, tag, &err)) != NULL){		w32(&b, fid);		wcs(&b, name, nlen);		w32(&b, perm);		w08(&b, mode);		err = c->end(c);	}	return err;} C9errorc9read(C9ctx *c, C9tag *tag, C9fid fid, uint64_t offset, uint32_t count){	uint8_t *b;	C9error err; 	if((b = T(c, 4+8+4, Tread, tag, &err)) != NULL){		w32(&b, fid);		w64(&b, offset);		w32(&b, count);		err = c->end(c);	}	return err;} C9errorc9write(C9ctx *c, C9tag *tag, C9fid fid, uint64_t offset, const void *in, uint32_t count){	uint8_t *b;	C9error err; 	if((b = T(c, 4+8+4+count, Twrite, tag, &err)) != NULL){		w32(&b, fid);		w64(&b, offset);		w32(&b, count);		memmove(b, in, count);		err = c->end(c);	}	return err;} C9errorc9wrstr(C9ctx *c, C9tag *tag, C9fid fid, const char *s){	return c9write(c, tag, fid, 0, s, strlen(s));} C9errorc9clunk(C9ctx *c, C9tag *tag, C9fid fid){	uint8_t *b;	C9error err; 	if((b = T(c, 4, Tclunk, tag, &err)) != NULL){		w32(&b, fid);		err = c->end(c);	}	return err;} C9errorc9remove(C9ctx *c, C9tag *tag, C9fid fid){	uint8_t *b;	C9error err; 	if((b = T(c, 4, Tremove, tag, &err)) != NULL){		w32(&b, fid);		err = c->end(c);	}	return err;} C9errorc9stat(C9ctx *c, C9tag *tag, C9fid fid){	uint8_t *b;	C9error err; 	if((b = T(c, 4, Tstat, tag, &err)) != NULL){		w32(&b, fid);		err = c->end(c);	}	return err;} C9errorc9wstat(C9ctx *c, C9tag *tag, C9fid fid, const C9stat *s){	uint32_t nlen = safestrlen(s->name), ulen = safestrlen(s->uid), glen = safestrlen(s->gid);	uint32_t unusedsz = 2+4+13, statsz = unusedsz+4+4+4+8+2+nlen+2+ulen+2+glen+2;	uint8_t *b;	C9error err; 	if(nlen == 0 || nlen > C9maxstr){		c->error(c, "c9wstat: invalid name: %ud chars", nlen);		return C9Epath;	}	if(ulen > C9maxstr || glen > C9maxstr){		c->error(c, "c9wstat: string too long: %ud chars", ulen > glen ? ulen : glen);		return C9Estr;	}	if((b = T(c, 4+2+2+statsz, Twstat, tag, &err)) != NULL){		w32(&b, fid);		w16(&b, statsz+2);		w16(&b, statsz);		memset(b, 0xff, unusedsz); /* leave type(2), dev(4) and qid(13) unchanged */		b += unusedsz;		w32(&b, s->mode);		w32(&b, s->atime);		w32(&b, s->mtime);		w64(&b, s->size);		wcs(&b, s->name, nlen);		wcs(&b, s->uid, ulen);		wcs(&b, s->gid, glen);		wcs(&b, NULL, 0); /* muid unchanged */		err = c->end(c);	}	return err;} C9errorc9proc(C9ctx *c){	uint32_t i, sz, cnt, msize;	uint8_t *b;	int err;	C9r r; 	err = -1;	if((b = c->read(c, 4, &err)) == NULL){		if(err != 0)			c->error(c, "c9proc: short read");		return err == 0 ? 0 : C9Epkt;	} 	sz = r32(&b);	if(sz < 7 || sz > c->msize){		c->error(c, "c9proc: invalid packet size !(7 <= %ud <= %ud)", sz, c->msize);		return C9Epkt;	}	sz -= 4;	err = -1;	if((b = c->read(c, sz, &err)) == NULL){		if(err != 0)			c->error(c, "c9proc: short read");		return err == 0 ? 0 : C9Epkt;	} 	r.type = r08(&b);	r.tag = r16(&b);	if(r.type != Rversion){		if(r.tag >= C9maxtags){			c->error(c, "c9proc: invalid tag %ud", (uint32_t)r.tag);			return C9Epkt;		}		if(freetag(c, r.tag) != 0)			return C9Etag;	}	sz -= 3;	r.numqid = 0; 	switch(r.type){	case Rread:		if(sz < 4 || (cnt = r32(&b)) > sz-4)			goto error;		r.read.data = b;		r.read.size = cnt;		c->r(c, &r);		break; 	case Rwrite:		if(sz < 4 || (cnt = r32(&b)) > c->msize)			goto error;		r.write.size = cnt;		c->r(c, &r);		break; 	case Rwalk:		if(sz < 2 || (cnt = r16(&b))*13 > sz-2)			goto error;		if(cnt > C9maxpathel){

Lines 1–500 of 1164.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t