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/vnc/proto.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vnc/proto.c')
-rwxr-xr-x | sys/src/cmd/vnc/proto.c | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/sys/src/cmd/vnc/proto.c b/sys/src/cmd/vnc/proto.c new file mode 100755 index 000000000..277525034 --- /dev/null +++ b/sys/src/cmd/vnc/proto.c @@ -0,0 +1,294 @@ +#include "vnc.h" + +#define SHORT(p) (((p)[0]<<8)|((p)[1])) +#define LONG(p) ((SHORT(p)<<16)|SHORT(p+2)) + +uchar zero[64]; + +Vnc* +vncinit(int fd, int cfd, Vnc *v) +{ + if(v == nil) + v = mallocz(sizeof(*v), 1); + Binit(&v->in, fd, OREAD); + Binit(&v->out, fd, OWRITE); + v->datafd = fd; + v->ctlfd = cfd; + return v; +} + +void +vncterm(Vnc *v) +{ + Bterm(&v->out); + Bterm(&v->in); +} + +void +vncflush(Vnc *v) +{ + if(Bflush(&v->out) < 0){ + if(verbose > 1) + fprint(2, "hungup while sending flush: %r\n"); + vnchungup(v); + } +} + +uchar +vncrdchar(Vnc *v) +{ + uchar buf[1]; + + vncrdbytes(v, buf, 1); + return buf[0]; +} + +ushort +vncrdshort(Vnc *v) +{ + uchar buf[2]; + + vncrdbytes(v, buf, 2); + return SHORT(buf); +} + +ulong +vncrdlong(Vnc *v) +{ + uchar buf[4]; + + vncrdbytes(v, buf, 4); + return LONG(buf); +} + +Point +vncrdpoint(Vnc *v) +{ + Point p; + + p.x = vncrdshort(v); + p.y = vncrdshort(v); + return p; +} + +Rectangle +vncrdrect(Vnc *v) +{ + Rectangle r; + + r.min.x = vncrdshort(v); + r.min.y = vncrdshort(v); + r.max.x = r.min.x + vncrdshort(v); + r.max.y = r.min.y + vncrdshort(v); + return r; +} + +Rectangle +vncrdcorect(Vnc *v) +{ + Rectangle r; + + r.min.x = vncrdchar(v); + r.min.y = vncrdchar(v); + r.max.x = r.min.x + vncrdchar(v); + r.max.y = r.min.y + vncrdchar(v); + return r; +} + +void +vncrdbytes(Vnc *v, void *a, int n) +{ + if(Bread(&v->in, a, n) != n){ + if(verbose > 1) + fprint(2, "hungup while reading\n"); + vnchungup(v); + } +} + +Pixfmt +vncrdpixfmt(Vnc *v) +{ + Pixfmt fmt; + uchar pad[3]; + + fmt.bpp = vncrdchar(v); + fmt.depth = vncrdchar(v); + fmt.bigendian = vncrdchar(v); + fmt.truecolor = vncrdchar(v); + fmt.red.max = vncrdshort(v); + fmt.green.max = vncrdshort(v); + fmt.blue.max = vncrdshort(v); + fmt.red.shift = vncrdchar(v); + fmt.green.shift = vncrdchar(v); + fmt.blue.shift = vncrdchar(v); + vncrdbytes(v, pad, 3); + return fmt; +} + +char* +vncrdstring(Vnc *v) +{ + ulong len; + char *s; + + len = vncrdlong(v); + s = malloc(len+1); + assert(s != nil); + + vncrdbytes(v, s, len); + s[len] = '\0'; + return s; +} + +/* + * on the server side of the negotiation protocol, we read + * the client response and then run the negotiated function. + * in some cases (e.g., TLS) the negotiated function needs to + * use v->datafd directly and be sure that no data has been + * buffered away in the Bio. since we know the client is waiting + * for our response, it won't have sent any until we respond. + * thus we read the response with vncrdstringx, which goes + * behind bio's back. + */ +char* +vncrdstringx(Vnc *v) +{ + char tmp[4]; + char *s; + ulong len; + + assert(Bbuffered(&v->in) == 0); + if(readn(v->datafd, tmp, 4) != 4){ + fprint(2, "cannot rdstringx: %r"); + vnchungup(v); + } + len = LONG(tmp); + s = malloc(len+1); + assert(s != nil); + if(readn(v->datafd, s, len) != len){ + fprint(2, "cannot rdstringx len %lud: %r", len); + vnchungup(v); + } + s[len] = '\0'; + return s; +} + +void +vncwrstring(Vnc *v, char *s) +{ + ulong len; + + len = strlen(s); + vncwrlong(v, len); + vncwrbytes(v, s, len); +} + +void +vncwrbytes(Vnc *v, void *a, int n) +{ + if(Bwrite(&v->out, a, n) < 0){ + if(verbose > 1) + fprint(2, "hungup while writing bytes\n"); + vnchungup(v); + } +} + +void +vncwrlong(Vnc *v, ulong u) +{ + uchar buf[4]; + + buf[0] = u>>24; + buf[1] = u>>16; + buf[2] = u>>8; + buf[3] = u; + vncwrbytes(v, buf, 4); +} + +void +vncwrshort(Vnc *v, ushort u) +{ + uchar buf[2]; + + buf[0] = u>>8; + buf[1] = u; + vncwrbytes(v, buf, 2); +} + +void +vncwrchar(Vnc *v, uchar c) +{ + vncwrbytes(v, &c, 1); +} + +void +vncwrpixfmt(Vnc *v, Pixfmt *fmt) +{ + vncwrchar(v, fmt->bpp); + vncwrchar(v, fmt->depth); + vncwrchar(v, fmt->bigendian); + vncwrchar(v, fmt->truecolor); + vncwrshort(v, fmt->red.max); + vncwrshort(v, fmt->green.max); + vncwrshort(v, fmt->blue.max); + vncwrchar(v, fmt->red.shift); + vncwrchar(v, fmt->green.shift); + vncwrchar(v, fmt->blue.shift); + vncwrbytes(v, zero, 3); +} + +void +vncwrrect(Vnc *v, Rectangle r) +{ + vncwrshort(v, r.min.x); + vncwrshort(v, r.min.y); + vncwrshort(v, r.max.x-r.min.x); + vncwrshort(v, r.max.y-r.min.y); +} + +void +vncwrpoint(Vnc *v, Point p) +{ + vncwrshort(v, p.x); + vncwrshort(v, p.y); +} + +void +vnclock(Vnc *v) +{ + qlock(v); +} + +void +vncunlock(Vnc *v) +{ + qunlock(v); +} + +void +hexdump(void *a, int n) +{ + uchar *p, *ep; + + p = a; + ep = p+n; + + for(; p<ep; p++) + print("%.2ux ", *p); + print("\n"); +} + +void +vncgobble(Vnc *v, long n) +{ + uchar buf[8192]; + long m; + + while(n > 0){ + m = n; + if(m > sizeof(buf)) + m = sizeof(buf); + vncrdbytes(v, buf, m); + n -= m; + } +} |