VtConn* vtconn(int infd, int outfd) { VtConn *z; NetConnInfo *nci; z = vtmallocz(sizeof(VtConn)); z->tagrend.l = &z->lk; z->rpcfork.l = &z->lk; z->infd = infd; z->outfd = outfd; z->part = packetalloc(); nci = getnetconninfo(nil, infd); if(nci == nil) snprint(z->addr, sizeof z->addr, "/dev/fd/%d", infd); else{ strecpy(z->addr, z->addr+sizeof z->addr, nci->raddr); freenetconninfo(nci); } return z; }
NetConnInfo* getnetconninfo(const char *dir, int fd) { NetConnInfo *nci; char *cp; Dir *d; char spec[10]; char path[128]; char netname[128], *p; /* get a directory address via fd */ if(dir == nil || *dir == 0){ if(fd2path(fd, path, sizeof(path)) < 0) return nil; cp = strrchr(path, '/'); if(cp == nil) return nil; *cp = 0; dir = path; } nci = mallocz(sizeof *nci, 1); if(nci == nil) return nil; /* copy connection directory */ nci->dir = strdup(dir); if(nci->dir == nil) goto err; /* get netroot */ nci->root = strdup(dir); if(nci->root == nil) goto err; cp = strchr(nci->root+1, '/'); if(cp == nil) goto err; *cp = 0; /* figure out bind spec */ d = dirstat(nci->dir); if(d != nil){ sprint(spec, "#%C%d", d->type, d->dev); nci->spec = strdup(spec); } if(nci->spec == nil) nci->spec = unknown; free(d); /* get the two end points */ getendpoint(nci->dir, "local", &nci->lsys, &nci->lserv); if(nci->lsys == nil || nci->lserv == nil) goto err; getendpoint(nci->dir, "remote", &nci->rsys, &nci->rserv); if(nci->rsys == nil || nci->rserv == nil) goto err; strecpy(netname, netname+sizeof netname, nci->dir); if((p = strrchr(netname, '/')) != nil) *p = 0; if(strncmp(netname, "/net/", 5) == 0) memmove(netname, netname+5, strlen(netname+5)+1); nci->laddr = smprint("%s!%s!%s", netname, nci->lsys, nci->lserv); nci->raddr = smprint("%s!%s!%s", netname, nci->rsys, nci->rserv); if(nci->laddr == nil || nci->raddr == nil) goto err; return nci; err: freenetconninfo(nci); return nil; }