diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/cifs/pack.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/cifs/pack.c')
-rwxr-xr-x | sys/src/cmd/cifs/pack.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/sys/src/cmd/cifs/pack.c b/sys/src/cmd/cifs/pack.c new file mode 100755 index 000000000..1f0230220 --- /dev/null +++ b/sys/src/cmd/cifs/pack.c @@ -0,0 +1,463 @@ +/* packet packing and unpacking */ +#include <u.h> +#include <libc.h> +#include <ctype.h> +#include "cifs.h" + +void * +pmem(Pkt *p, void *v, int len) +{ + uchar *str = v; + void *s = p->pos; + + if(!len || !v) + return s; + while(len--) + *p->pos++ = *str++; + return s; +} + +void * +ppath(Pkt *p, char *str) +{ + char c; + Rune r; + void *s = p->pos; + + if(!str) + return s; + + if(p->s->caps & CAP_UNICODE){ + if(((p->pos - p->buf) % 2) != 0) /* pad to even offset */ + p8(p, 0); + while(*str){ + str += chartorune(&r, str); + if(r == L'/') + r = L'\\'; + pl16(p, r); + } + pl16(p, 0); + } else { + while((c = *str++) != 0){ + if(c == '/') + c = '\\'; + *p->pos++ = c; + } + *p->pos++ = 0; + } + return s; +} + +void * +pstr(Pkt *p, char *str) +{ + void *s = p->pos; + Rune r; + + if(!str) + return s; + + if(p->s->caps & CAP_UNICODE){ + if(((p->pos - p->buf) % 2) != 0) + p8(p, 0); /* pad to even offset */ + while(*str){ + str += chartorune(&r, str); + pl16(p, r); + } + pl16(p, 0); + } else { + while(*str) + *p->pos++ = *str++; + *p->pos++ = 0; + } + return s; +} + +void * +pascii(Pkt *p, char *str) +{ + void *s = p->pos; + + while(*str) + *p->pos++ = *str++; + *p->pos++ = 0; + return s; +} + + +void * +pl64(Pkt *p, uvlong n) +{ + void *s = p->pos; + + *p->pos++ = n; + *p->pos++ = n >> 8; + *p->pos++ = n >> 16; + *p->pos++ = n >> 24; + *p->pos++ = n >> 32; + *p->pos++ = n >> 40; + *p->pos++ = n >> 48; + *p->pos++ = n >> 56; + return s; +} + +void * +pb32(Pkt *p, uint n) +{ + void *s = p->pos; + + *p->pos++ = n >> 24; + *p->pos++ = n >> 16; + *p->pos++ = n >> 8; + *p->pos++ = n; + return s; +} + +void * +pl32(Pkt *p, uint n) +{ + void *s = p->pos; + + *p->pos++ = n; + *p->pos++ = n >> 8; + *p->pos++ = n >> 16; + *p->pos++ = n >> 24; + return s; +} + +void * +pb16(Pkt *p, uint n) +{ + void *s = p->pos; + + *p->pos++ = n >> 8; + *p->pos++ = n; + return s; +} + +void * +pl16(Pkt *p, uint n) +{ + void *s = p->pos; + + *p->pos++ = n; + *p->pos++ = n >> 8; + return s; +} + +void * +p8(Pkt *p, uint n) +{ + void *s = p->pos; + + *p->pos++ = n; + return s; +} + +/* + * Encode a Netbios name + */ +void * +pname(Pkt *p, char *name, char pad) +{ + int i, done = 0; + char c; + void *s = p->pos; + + *p->pos++ = ' '; + for(i = 0; i < 16; i++) { + c = pad; + if(!done && name[i] == '\0') + done = 1; + if(!done) + c = islower(name[i])? toupper(name[i]): name[i]; + *p->pos++ = ((uchar)c >> 4) + 'A'; + *p->pos++ = (c & 0xf) + 'A'; + } + *p->pos++ = '\0'; + return s; +} + +void * +pvtime(Pkt *p, uvlong n) +{ + void *s = p->pos; + + n += 11644473600LL; + n *= 10000000LL; + + pl32(p, n); + pl32(p, n >> 32); + return s; +} + +void * +pdatetime(Pkt *p, long utc) +{ + void *s = p->pos; + Tm *tm = localtime(utc); + int t = tm->hour << 11 | tm->min << 5 | (tm->sec / 2); + int d = (tm->year - 80) << 9 | (tm->mon + 1) << 5 | tm->mday; + + /* + * bug in word swapping in Win95 requires this + */ + if(p->s->caps & CAP_NT_SMBS){ + pl16(p, d); + pl16(p, t); + } else{ + pl16(p, t); + pl16(p, d); + } + return s; +} + + +void +gmem(Pkt *p, void *v, int n) +{ + uchar *str = v; + + if(!n || !v) + return; + while(n-- && p->pos < p->eop) + *str++ = *p->pos++; +} + +/* + * note len is the length of the source string in + * in runes or bytes, in ASCII mode this is also the size + * of the output buffer but this is not so in Unicode mode! + */ +void +gstr(Pkt *p, char *str, int n) +{ + int i; + Rune r; + + if(!n || !str) + return; + + if(p->s->caps & CAP_UNICODE){ + i = 0; + while(*p->pos && n && p->pos < p->eop){ + r = gl16(p); + i += runetochar(str +i, &r); + n -= 2; + } + *(str + i) = 0; + + while(*p->pos && p->pos < p->eop) + gl16(p); + /* + * some versions of windows terminate a rune string + * with a single nul so we do a dangerous hack... + */ + if(p->pos[1]) + g8(p); + else + gl16(p); + } else { + while(*p->pos && n-- && p->pos < p->eop) + *str++ = *p->pos++; + *str = 0; + while(*p->pos++ && p->pos < p->eop) + continue; + } +} + +void +gascii(Pkt *p, char *str, int n) +{ + if(!n || !str) + return; + + while(*p->pos && n-- && p->pos < p->eop) + *str++ = *p->pos++; + *str = 0; + while(*p->pos++ && p->pos < p->eop) + continue; +} + + +uvlong +gl64(Pkt *p) +{ + uvlong n; + + if(p->pos + 8 > p->eop) + return 0; + + n = (uvlong)*p->pos++; + n |= (uvlong)*p->pos++ << 8; + n |= (uvlong)*p->pos++ << 16; + n |= (uvlong)*p->pos++ << 24; + n |= (uvlong)*p->pos++ << 32; + n |= (uvlong)*p->pos++ << 40; + n |= (uvlong)*p->pos++ << 48; + n |= (uvlong)*p->pos++ << 56; + return n; +} + +uvlong +gb48(Pkt *p) +{ + uvlong n; + + if(p->pos + 6 > p->eop) + return 0; + + n = (uvlong)*p->pos++ << 40; + n |= (uvlong)*p->pos++ << 24; + n |= (uvlong)*p->pos++ << 32; + n |= (uvlong)*p->pos++ << 16; + n |= (uvlong)*p->pos++ << 8; + n |= (uvlong)*p->pos++; + return n; +} + +uint +gb32(Pkt *p) +{ + uint n; + + if(p->pos + 4 > p->eop) + return 0; + + n = (uint)*p->pos++ << 24; + n |= (uint)*p->pos++ << 16; + n |= (uint)*p->pos++ << 8; + n |= (uint)*p->pos++; + return n; +} + +uint +gl32(Pkt *p) +{ + uint n; + + if(p->pos + 4 > p->eop) + return 0; + + n = (uint)*p->pos++; + n |= (uint)*p->pos++ << 8; + n |= (uint)*p->pos++ << 16; + n |= (uint)*p->pos++ << 24; + return n; +} + +uint +gb16(Pkt *p) +{ + uint n; + + if(p->pos + 2 > p->eop) + return 0; + n = (uint)*p->pos++ << 8; + n |= (uint)*p->pos++; + return n; +} + +uint +gl16(Pkt *p) +{ + uint n; + + if(p->pos + 2 > p->eop) + return 0; + n = (uint)*p->pos++; + n |= (uint)*p->pos++ << 8; + return n; +} + +uint +g8(Pkt *p) +{ + if(p->pos + 1 > p->eop) + return 0; + return (uint)*p->pos++; +} + +long +gdatetime(Pkt *p) +{ + Tm tm; + uint d, t; + + if(p->pos + 4 > p->eop) + return 0; + + /* + * bug in word swapping in Win95 requires this + */ + if(p->s->caps & CAP_NT_SMBS){ + d = gl16(p); + t = gl16(p); + }else{ + t = gl16(p); + d = gl16(p); + } + + tm.year = 80 + (d >> 9); + tm.mon = ((d >> 5) & 017) - 1; + tm.mday = d & 037; + tm.zone[0] = 0; + tm.tzoff = p->s->tz; + + tm.hour = t >> 11; + tm.min = (t >> 5) & 63; + tm.sec = (t & 31) << 1; + + return tm2sec(&tm); +} + +long +gvtime(Pkt *p) +{ + uvlong vl; + + if(p->pos + 8 > p->eop) + return 0; + + vl = (uvlong)gl32(p); + vl |= (uvlong)gl32(p) << 32; + + vl /= 10000000LL; + vl -= 11644473600LL; + return vl; +} + +void +gconv(Pkt *p, int conv, char *str, int n) +{ + int off; + uchar *pos; + + off = gl32(p) & 0xffff; + if(off == 0 || p->tdata - conv + off > p->eop){ + memset(str, 0, n); + return; + } + + pos = p->pos; + p->pos = p->tdata - conv + off; + gascii(p, str, n); + p->pos = pos; +} + +void +goff(Pkt *p, uchar *base, char *str, int n) +{ + int off; + uchar *pos; + + off = gl16(p); + if(off == 0 || base + off > p->eop){ + memset(str, 0, n); + return; + } + pos = p->pos; + p->pos = base + off; + gstr(p, str, n); + p->pos = pos; +} |