606 lines · 10.3 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "headers.h" #define BUFFER 1#define STRUCT 2#define PUSHED 4 struct SmbBuffer {	uchar *buf;	ulong realmaxlen;	ulong maxlen;	ulong rn;	ulong wn;	ulong savewn;	int flags;}; voidsmbbufferreset(SmbBuffer *s){	if (s == nil)		return;	s->rn = 0;	s->wn = 0;	s->flags &= ~PUSHED;} voidsmbbuffersetbuf(SmbBuffer *s, void *p, ulong maxlen){	s->realmaxlen = s->maxlen = maxlen;	if (s->buf) {		if (s->flags & BUFFER)			free(s->buf);		s->buf = nil;	}	s->flags &= ~BUFFER;	if (p)		s->buf = p;	else {		s->buf = smbemalloc(maxlen);		s->flags |= BUFFER;	}	smbbufferreset(s);} SmbBuffer *smbbufferinit(void *base, void *bdata, ulong blen){	SmbBuffer *b;	b = smbemalloc(sizeof(*b));	b->buf = base;	b->flags = STRUCT;		b->rn = (uchar *)bdata - (uchar *)base;	b->wn = b->rn + blen;	b->realmaxlen = b->maxlen = b->wn;	return b;} intsmbbufferalignl2(SmbBuffer *s, int al2){	ulong mask, newn;	mask = (1 << al2) - 1;	newn = (s->wn + mask) & ~mask;	if (newn != s->wn) {		if (newn > s->maxlen)			return 0;		s->wn = newn;	}	return 1;} intsmbbufferputb(SmbBuffer *s, uchar b){	if (s->wn >= s->maxlen)		return 0;	s->buf[s->wn++] = b;	return 1;} ulongsmbbufferspace(SmbBuffer *sess){	return sess->maxlen - sess->wn;} intsmbbufferoffsetputs(SmbBuffer *sess, ulong offset, ushort s){	if (offset + 2 > sess->wn)		return 0;	smbhnputs(sess->buf + offset, s);	return 1;} intsmbbufferputs(SmbBuffer *sess, ushort s){	if (sess->wn + sizeof(ushort) > sess->maxlen)		return 0;	smbhnputs(sess->buf + sess->wn, s);	sess->wn += sizeof(ushort);	return 1;} intsmbbufferputl(SmbBuffer *s, ulong l){	if (s->wn + sizeof(ulong) > s->maxlen)		return 0;	smbhnputl(s->buf + s->wn, l);	s->wn += sizeof(ulong);	return 1;} intsmbbufferputv(SmbBuffer *s, vlong v){	if (s->wn + sizeof(vlong) > s->maxlen)		return 0;	smbhnputv(s->buf + s->wn, v);	s->wn += sizeof(vlong);	return 1;} intsmbbufferputbytes(SmbBuffer *s, void *data, ulong datalen){	if (s->wn + datalen > s->maxlen)		return 0;	if (data)		memcpy(s->buf + s->wn, data, datalen);	s->wn += datalen;	return 1;} intsmbbufferputstring(SmbBuffer *b, SmbPeerInfo *p, ulong flags, char *string){	int n = smbstringput(p, flags, b->buf, b->wn, b->maxlen, string);	if (n <= 0)		return 0;	b->wn += n;	return 1;} intsmbbufferputstrn(SmbBuffer *s, char *string, int size, int upcase){	int n = smbstrnput(s->buf, s->wn, s->maxlen, string, size, upcase);	if (n <= 0)		return 0;	s->wn += n;	return 1;} ulongsmbbufferwriteoffset(SmbBuffer *s){	return s->wn;} ulongsmbbufferwritemaxoffset(SmbBuffer *s){	return s->maxlen;} ulongsmbbufferreadoffset(SmbBuffer *s){	return s->rn;} void *smbbufferreadpointer(SmbBuffer *s){	return s->buf + s->rn;} void *smbbufferwritepointer(SmbBuffer *s){	return s->buf + s->wn;} ulongsmbbufferwritespace(SmbBuffer *b){	return b->maxlen - b->wn;} SmbBuffer *smbbuffernew(ulong maxlen){	SmbBuffer *b;	b = smbemalloc(sizeof(SmbBuffer));	b->buf = smbemalloc(maxlen);	b->realmaxlen = b->maxlen = maxlen;	b->rn = 0;	b->wn = 0;	b->flags = STRUCT | BUFFER;	return b;} voidsmbbufferfree(SmbBuffer **bp){	SmbBuffer *b = *bp;	if (b) {		if (b->flags & BUFFER) {			free(b->buf);			b->buf = nil;			b->flags &= ~BUFFER;		}		if (b->flags & STRUCT)			free(b);		*bp = nil;	}} uchar *smbbufferbase(SmbBuffer *b){	return b->buf;} intsmbbuffergetbytes(SmbBuffer *b, void *buf, ulong len){	if (b->rn + len > b->wn)		return 0;	if (buf)		memcpy(buf, b->buf + b->rn, len);	b->rn += len;	return 1;} voidsmbbuffersetreadlen(SmbBuffer *b, ulong len){	b->wn = b->rn + len;} intsmbbuffertrimreadlen(SmbBuffer *b, ulong len){	if (b->rn + len > b->wn)		return 0;	else if (b->rn + len < b->wn)		b->wn = b->rn + len;	return 1;} intsmbbuffergets(SmbBuffer *b, ushort *sp){	if (b->rn + 2 > b->wn)		return 0;	*sp = smbnhgets(b->buf + b->rn);	b->rn += 2;	return 1;} intsmbbuffergetstrn(SmbBuffer *b, ushort size, char **sp){	uchar *np;	if (size > b->wn - b->rn)		return 0;	np = memchr(b->buf + b->rn, 0, size);	if (np == nil)		return 0;	*sp = strdup((char *)b->buf + b->rn);	b->rn += size;	return 1;} intsmbbuffergetstr(SmbBuffer *b, ulong flags, char **sp){	int c;	char *p;	uchar *np; 	np = memchr(b->buf + b->rn, 0, b->wn - b->rn);	if (np == nil)		return 0;	*sp = strdup((char *)b->buf + b->rn);	for (p = *sp; *p != 0; p++) {		c = *p;		if (c >= 'a' && c <= 'z' && (flags & SMB_STRING_UPCASE))			*p = toupper(c);		else if (c == '/' && (flags & SMB_STRING_REVPATH))			*p = '\\';		else if (c == '\\' && (flags & SMB_STRING_PATH))			*p = '/';		else if (smbglobals.convertspace){			if (c == 0xa0 && (flags & SMB_STRING_REVPATH))				*p = ' ';			else if (c == ' ' && (flags & SMB_STRING_PATH))				*p = 0xa0;		}	}	b->rn = np - b->buf + 1;	return 1;} intsmbbuffergetstrinline(SmbBuffer *b, char **sp){	uchar *np;	np = memchr(b->buf + b->rn, 0, b->wn - b->rn);	if (np == nil)		return 0;	*sp = (char *)b->buf + b->rn;	b->rn = np - b->buf + 1;	return 1;} intsmbbuffergetucs2(SmbBuffer *b, ulong flags, char **sp){	uchar *bdata = b->buf + b->rn;	uchar *edata = b->buf + b->wn;	Rune r;	int l;	char *p, *q;	uchar *savebdata;	int first; 	l = 0;	if ((flags & SMB_STRING_UNALIGNED) == 0 && (bdata - b->buf) & 1)		bdata++;	savebdata = bdata;	first = 1;	do {		if (bdata + 2 > edata) {			l++;			break;		}		r = smbnhgets(bdata); bdata += 2;		if (first && (flags & SMB_STRING_PATH) && r != '\\')			l++;		first = 0;		if (flags & SMB_STRING_CONVERT_MASK)			r = smbruneconvert(r, flags);		l += runelen(r);	} while (r != 0);	p = smbemalloc(l);	bdata = savebdata;	q = p;	first = 1;	do {		if (bdata + 2 > edata) {			*q = 0;			break;		}		r = smbnhgets(bdata); bdata += 2;		if (first && (flags & SMB_STRING_PATH) && r != '\\')			*q++ = '/';		first = 0;		if (flags & SMB_STRING_CONVERT_MASK)			r = smbruneconvert(r, flags);		q += runetochar(q, &r);	} while (r != 0);	b->rn = bdata - b->buf;	*sp = p;	return 1;} intsmbbuffergetstring(SmbBuffer *b, SmbHeader *h, ulong flags, char **sp){	if (flags & SMB_STRING_UNICODE)		return smbbuffergetucs2(b, flags, sp);	else if (flags & SMB_STRING_ASCII)		return smbbuffergetstr(b, flags, sp);	else if (h->flags2 & SMB_FLAGS2_UNICODE)		return smbbuffergetucs2(b, flags, sp);	else		return smbbuffergetstr(b, flags, sp);} void *smbbufferpointer(SmbBuffer *b, ulong offset){	return b->buf + offset;} intsmbbuffergetb(SmbBuffer *b, uchar *bp){	if (b->rn < b->wn) {		*bp = b->buf[b->rn++];		return 1;	}	return 0;} intsmbbuffergetl(SmbBuffer *b, ulong *lp){	if (b->rn + 4 <= b->wn) {		*lp = smbnhgetl(b->buf + b->rn);		b->rn += 4;		return 1;	}	return 0;} intsmbbuffergetv(SmbBuffer *b, vlong *vp){	if (b->rn + 8 <= b->wn) {		*vp = smbnhgetv(b->buf + b->rn);		b->rn += 8;		return 1;	}	return 0;} ulongsmbbufferreadspace(SmbBuffer *b){	return b->wn - b->rn;} voidsmbbufferwritelimit(SmbBuffer *b, ulong limit){	if (b->rn + limit < b->maxlen)		b->maxlen = b->rn + limit;} intsmbbufferreadskipto(SmbBuffer *b, ulong offset){	if (offset < b->rn || offset >= b->wn)		return 0;	b->rn = offset;	return 1;} intsmbbufferpushreadlimit(SmbBuffer *b, ulong limit){	if (b->flags & PUSHED)		return 0;	if (limit > b->wn || limit < b->rn)		return 0;	b->savewn = b->wn;	b->wn = limit;	b->flags |= PUSHED;	return 1;} intsmbbufferpopreadlimit(SmbBuffer *b){	if ((b->flags & PUSHED) == 0)		return 0;	b->wn = b->savewn;	b->flags &= ~PUSHED;	return 1;} intsmbbufferwritebackup(SmbBuffer *b, ulong offset){	if (offset >= b->rn && offset <= b->wn) {		b->wn = offset;		return 1;	}	return 0;} intsmbbufferreadbackup(SmbBuffer *b, ulong offset){	if (offset <= b->rn) {		b->rn = offset;		return 1;	}	return 0;} intsmbbufferfixuprelatives(SmbBuffer *b, ulong fixupoffset){

Lines 1–500 of 606.