static int call(char *clone, char *dest, DS *ds) { int fd, cfd, n; char name[Maxpath], data[Maxpath], err[ERRMAX], *p; cfd = kopen(clone, ORDWR); if(cfd < 0){ kerrstr(err, sizeof err); kwerrstr("%s (%s)", err, clone); return -1; } /* get directory name */ n = kread(cfd, name, sizeof(name)-1); if(n < 0){ kerrstr(err, sizeof err); kclose(cfd); kwerrstr("read %s: %s", clone, err); return -1; } name[n] = 0; for(p = name; *p == ' '; p++) ; sprint(name, "%ld", strtoul(p, 0, 0)); p = strrchr(clone, '/'); *p = 0; if(ds->dir) snprint(ds->dir, NETPATHLEN, "%s/%s", clone, name); snprint(data, sizeof(data), "%s/%s/data", clone, name); /* connect */ if(ds->local) snprint(name, sizeof(name), "connect %s %s", dest, ds->local); else snprint(name, sizeof(name), "connect %s", dest); if(kwrite(cfd, name, strlen(name)) < 0){ err[0] = 0; kerrstr(err, sizeof err); kclose(cfd); kwerrstr("%s (%s)", err, name); return -1; } /* open data connection */ fd = kopen(data, ORDWR); if(fd < 0){ err[0] = 0; kerrstr(err, sizeof err); kwerrstr("%s (%s)", err, data); kclose(cfd); return -1; } if(ds->cfdp) *ds->cfdp = cfd; else kclose(cfd); return fd; }
static int csdial(DS *ds) { int n, fd, rv; char *p, buf[Maxstring], clone[Maxpath], err[ERRMAX], besterr[ERRMAX]; /* * open connection server */ snprint(buf, sizeof(buf), "%s/cs", ds->netdir); fd = kopen(buf, ORDWR); if(fd < 0){ /* no connection server, don't translate */ snprint(clone, sizeof(clone), "%s/%s/clone", ds->netdir, ds->proto); return call(clone, ds->rem, ds); } /* * ask connection server to translate */ sprint(buf, "%s!%s", ds->proto, ds->rem); if(kwrite(fd, buf, strlen(buf)) < 0){ kerrstr(err, sizeof err); kclose(fd); kwerrstr("%s (%s)", err, buf); return -1; } /* * loop through each address from the connection server till * we get one that works. */ *besterr = 0; strcpy(err, Egreg); rv = -1; kseek(fd, 0, 0); while((n = kread(fd, buf, sizeof(buf) - 1)) > 0){ buf[n] = 0; p = strchr(buf, ' '); if(p == 0) continue; *p++ = 0; rv = call(buf, p, ds); if(rv >= 0) break; err[0] = 0; kerrstr(err, sizeof err); if(strstr(err, "does not exist") == 0) memmove(besterr, err, sizeof besterr); } kclose(fd); if(rv < 0 && *besterr) kerrstr(besterr, sizeof besterr); else kerrstr(err, sizeof err); return rv; }
/* * call up the connection server and get a translation */ static int nettrans(char *addr, char *naddr, int na, char *file, int nf) { int i, fd; char buf[Maxpath]; char netdir[NETPATHLEN]; char *p, *p2; long n; /* * parse, get network directory */ p = strchr(addr, '!'); if(p == 0){ kwerrstr("bad dial string: %s", addr); return -1; } if(*addr != '/'){ strcpy(netdir, "/net"); } else { for(p2 = p; *p2 != '/'; p2--) ; i = p2 - addr; if(i == 0 || i >= sizeof(netdir)){ kwerrstr("bad dial string: %s", addr); return -1; } strncpy(netdir, addr, i); netdir[i] = 0; addr = p2 + 1; } /* * ask the connection server */ sprint(buf, "%s/cs", netdir); fd = kopen(buf, ORDWR); if(fd < 0) return identtrans(netdir, addr, naddr, na, file, nf); if(kwrite(fd, addr, strlen(addr)) < 0){ kclose(fd); return -1; } kseek(fd, 0, 0); n = kread(fd, buf, sizeof(buf)-1); kclose(fd); if(n <= 0) return -1; buf[n] = 0; /* * parse the reply */ p = strchr(buf, ' '); if(p == 0) return -1; *p++ = 0; strncpy(naddr, p, na); naddr[na-1] = 0; strncpy(file, buf, nf); file[nf-1] = 0; return 0; }
Font* buildfont(Display *d, char *buf, char *name) { Font *fnt; Cachefont *c; char *s, *t; ulong min, max; int offset; char badform[] = "bad font format: number expected (char position %d)"; s = buf; fnt = malloc(sizeof(Font)); if(fnt == 0) return 0; memset(fnt, 0, sizeof(Font)); fnt->display = d; fnt->name = strdup(name); fnt->ncache = NFCACHE+NFLOOK; fnt->nsubf = NFSUBF; fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0])); fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0])); if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){ Err2: free(fnt->name); free(fnt->cache); free(fnt->subf); free(fnt->sub); free(fnt); return 0; } fnt->height = strtol(s, &s, 0); s = skip(s); fnt->ascent = strtol(s, &s, 0); s = skip(s); if(fnt->height<=0 || fnt->ascent<=0){ kwerrstr("bad height or ascent in font file"); goto Err2; } fnt->width = 0; fnt->nsub = 0; fnt->sub = 0; memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0])); memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0])); fnt->age = 1; do{ /* must be looking at a number now */ if(*s<'0' || '9'<*s){ kwerrstr(badform, s-buf); goto Err3; } min = strtol(s, &s, 0); s = skip(s); /* must be looking at a number now */ if(*s<'0' || '9'<*s){ kwerrstr(badform, s-buf); goto Err3; } max = strtol(s, &s, 0); s = skip(s); if(*s==0 || min>=Runemax || max>=Runemax || min>max){ kwerrstr("illegal subfont range"); Err3: freefont(fnt); return 0; } t = s; offset = strtol(s, &t, 0); if(t>s && (*t==' ' || *t=='\t' || *t=='\n')) s = skip(t); else offset = 0; fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*)); if(fnt->sub == 0){ /* realloc manual says fnt->sub may have been destroyed */ fnt->nsub = 0; goto Err3; } c = malloc(sizeof(Cachefont)); if(c == 0) goto Err3; fnt->sub[fnt->nsub] = c; c->min = min; c->max = max; c->offset = offset; t = s; while(*s && *s!=' ' && *s!='\n' && *s!='\t') s++; *s++ = 0; c->subfontname = 0; c->name = strdup(t); if(c->name == 0){ free(c); goto Err3; } s = skip(s); fnt->nsub++; }while(*s); return fnt; }
Module* parsemod(char *path, uchar *code, ulong length, Dir *dir) { Heap *h; Inst *ip; Type *pt; String *s; Module *m; Array *ary; ulong ul[2]; WORD lo, hi; int lsize, id, v, entry, entryt, tnp, tsz, siglen; int de, pc, i, n, isize, dsize, hsize, dasp; uchar *mod, sm, *istream, **isp, *si, *addr, *dastack[DADEPTH]; Link *l; istream = code; isp = &istream; m = malloc(sizeof(Module)); if(m == nil) return nil; m->dev = dir->dev; m->dtype = dir->type; m->qid = dir->qid; m->mtime = dir->mtime; m->origmp = H; m->pctab = nil; switch(operand(isp)) { default: kwerrstr("bad magic"); goto bad; case SMAGIC: siglen = operand(isp); n = length-(*isp-code); if(n < 0 || siglen > n){ kwerrstr("corrupt signature"); goto bad; } if(verifysigner(*isp, siglen, *isp+siglen, n-siglen) == 0) { kwerrstr("security violation"); goto bad; } *isp += siglen; break; case XMAGIC: if(mustbesigned(path, code, length, dir)){ kwerrstr("security violation: not signed"); goto bad; } break; } m->rt = operand(isp); m->ss = operand(isp); isize = operand(isp); dsize = operand(isp); hsize = operand(isp); lsize = operand(isp); entry = operand(isp); entryt = operand(isp); if(isize < 0 || dsize < 0 || hsize < 0 || lsize < 0) { kwerrstr("implausible Dis file"); goto bad; } m->nprog = isize; m->prog = mallocz(isize*sizeof(Inst), 0); if(m->prog == nil) { kwerrstr(exNomem); goto bad; } m->ref = 1; ip = m->prog; for(i = 0; i < isize; i++) { ip->op = *istream++; ip->add = *istream++; ip->reg = 0; ip->s.imm = 0; ip->d.imm = 0; switch(ip->add & ARM) { case AXIMM: case AXINF: case AXINM: ip->reg = operand(isp); break; } switch(UXSRC(ip->add)) { case SRC(AFP): case SRC(AMP): case SRC(AIMM): ip->s.ind = operand(isp); break; case SRC(AIND|AFP): case SRC(AIND|AMP): ip->s.i.f = operand(isp); ip->s.i.s = operand(isp); break; } switch(UXDST(ip->add)) { case DST(AFP): case DST(AMP): ip->d.ind = operand(isp); break; case DST(AIMM): ip->d.ind = operand(isp); if(brpatch(ip, m) == 0) { kwerrstr("bad branch addr"); goto bad; } break; case DST(AIND|AFP): case DST(AIND|AMP): ip->d.i.f = operand(isp); ip->d.i.s = operand(isp); break; } ip++; } m->ntype = hsize; m->type = malloc(hsize*sizeof(Type*)); if(m->type == nil) { kwerrstr(exNomem); goto bad; } for(i = 0; i < hsize; i++) { id = operand(isp); if(id > hsize) { kwerrstr("heap id range"); goto bad; } tsz = operand(isp); tnp = operand(isp); if(tsz < 0 || tnp < 0 || tnp > 128*1024){ kwerrstr("implausible Dis file"); goto bad; } pt = dtype(freeheap, tsz, istream, tnp); if(pt == nil) { kwerrstr(exNomem); goto bad; } istream += tnp; m->type[id] = pt; } if(dsize != 0) { pt = m->type[0]; if(pt == 0 || pt->size != dsize) { kwerrstr("bad desc for mp"); goto bad; } h = heapz(pt); m->origmp = H2D(uchar*, h); }