14 static char EBigString[] = "string too long";
15 static char EBigPacket[] = "packet too long";
16 static char ENullString[] = "missing string";
17 static char EBadVersion[] = "bad format in version string";
19 static Packet *vtRPC(VtSession *z, int op, Packet *p);
27 z = vtMemAllocZ(sizeof(VtSession));
28 z->lk = vtLockAlloc();
29 // z->inHash = vtSha1Alloc();
30 z->inLock = vtLockAlloc();
31 z->part = packetAlloc();
32 // z->outHash = vtSha1Alloc();
33 z->outLock = vtLockAlloc();
35 z->uid = vtStrDup("anonymous");
36 z->sid = vtStrDup("anonymous");
44 z->cstate = VtStateAlloc;
53 vtConnected(VtSession *z)
55 return z->cstate == VtStateConnected;
59 vtDisconnect(VtSession *z, int error)
64 vtDebug(z, "vtDisconnect\n");
66 if(z->cstate == VtStateConnected && !error && z->vtbl == nil) {
69 b = packetHeader(p, 2);
77 z->cstate = VtStateClosed;
93 vtSha1Free(z->inHash);
94 vtLockFree(z->inLock);
96 vtSha1Free(z->outHash);
97 vtLockFree(z->outLock);
102 memset(z, 0, sizeof(VtSession));
109 vtGetUid(VtSession *s)
115 vtGetSid(VtSession *z)
121 vtSetDebug(VtSession *z, int debug)
132 vtSetFd(VtSession *z, int fd)
135 if(z->cstate != VtStateAlloc) {
136 vtSetError("bad state");
148 vtGetFd(VtSession *z)
154 vtSetCryptoStrength(VtSession *z, int c)
156 if(z->cstate != VtStateAlloc) {
157 vtSetError("bad state");
160 if(c != VtCryptoStrengthNone) {
161 vtSetError("not supported yet");
168 vtGetCryptoStrength(VtSession *s)
170 return s->cryptoStrength;
174 vtSetCompression(VtSession *z, int fd)
177 if(z->cstate != VtStateAlloc) {
178 vtSetError("bad state");
188 vtGetCompression(VtSession *s)
190 return s->compression;
194 vtGetCrypto(VtSession *s)
200 vtGetCodec(VtSession *s)
206 vtGetVersion(VtSession *z)
213 for(i=0; vtVersions[i].version; i++)
214 if(vtVersions[i].version == v)
215 return vtVersions[i].s;
222 vtVersionRead(VtSession *z, char *prefix, int *ret)
225 char buf[VtMaxStringSize];
232 if(p >= buf + sizeof(buf)) {
233 vtSetError(EBadVersion);
236 if(!vtFdReadFully(z->fd, (uchar*)&c, 1))
239 vtSha1Update(z->inHash, (uchar*)&c, 1);
244 if(c < ' ' || *q && c != *q) {
245 vtSetError(EBadVersion);
253 vtDebug(z, "version string in: %s\n", buf);
255 p = buf + strlen(prefix);
257 for(pp=p; *pp && *pp != ':' && *pp != '-'; pp++)
259 for(i=0; vtVersions[i].version; i++) {
260 if(strlen(vtVersions[i].s) != pp-p)
262 if(memcmp(vtVersions[i].s, p, pp-p) == 0) {
263 *ret = vtVersions[i].version;
275 vtRecvPacket(VtSession *z)
282 if(z->cstate != VtStateConnected) {
283 vtSetError("session not connected");
289 /* get enough for head size */
290 size = packetSize(p);
292 b = packetTrailer(p, MaxFragSize);
294 n = vtFdRead(z->fd, b, MaxFragSize);
298 packetTrim(p, 0, size);
301 if(!packetConsume(p, buf, 2))
303 len = (buf[0] << 8) | buf[1];
310 b = packetTrailer(p, n);
311 if(!vtFdReadFully(z->fd, b, n))
315 p = packetSplit(p, len);
324 vtSendPacket(VtSession *z, Packet *p)
333 vtSetError(EBigPacket);
339 packetPrefix(p, buf, 2);
342 n = packetFragments(p, &ioc, 1, 0);
345 if(!vtFdWrite(z->fd, ioc.addr, ioc.len)) {
349 packetConsume(p, nil, n);
357 vtGetString(Packet *p, char **ret)
363 if(!packetConsume(p, buf, 2))
365 n = (buf[0]<<8) + buf[1];
366 if(n > VtMaxStringSize) {
367 vtSetError(EBigString);
371 setmalloctag(s, getcallerpc(&p));
372 if(!packetConsume(p, (uchar*)s, n)) {
382 vtAddString(Packet *p, char *s)
388 vtSetError(ENullString);
392 if(n > VtMaxStringSize) {
393 vtSetError(EBigString);
398 packetAppend(p, buf, 2);
399 packetAppend(p, (uchar*)s, n);
404 vtConnect(VtSession *z, char *password)
406 char buf[VtMaxStringSize], *p, *ep, *prefix;
411 if(z->cstate != VtStateAlloc) {
412 vtSetError("bad session state");
417 vtSetError("%s", z->fderror);
422 /* be a little anal */
428 ep = buf + sizeof(buf);
429 p = seprint(p, ep, "%s", prefix);
431 for(i=0; vtVersions[i].version; i++) {
434 p = seprint(p, ep, "%s", vtVersions[i].s);
436 p = seprint(p, ep, "-libventi\n");
437 assert(p-buf < sizeof(buf));
439 vtSha1Update(z->outHash, (uchar*)buf, p-buf);
440 if(!vtFdWrite(z->fd, (uchar*)buf, p-buf))
443 vtDebug(z, "version string out: %s", buf);
445 if(!vtVersionRead(z, prefix, &z->version))
448 vtDebug(z, "version = %d: %s\n", z->version, vtGetVersion(z));
451 vtUnlock(z->outLock);
452 z->cstate = VtStateConnected;
466 vtUnlock(z->outLock);
467 z->cstate = VtStateClosed;