/** * Function: ixp_sendmsg * Function: ixp_recvmsg * * These functions read and write messages to and from the given * file descriptors. * * ixp_sendmsg writes the data at P<msg>->pos upto P<msg>->end. * If the call returns non-zero, all data is assured to have * been written. * * ixp_recvmsg first reads a 32 bit, little-endian length from * P<fd> and then reads a message of that length (including the * 4 byte size specifier) into the buffer at P<msg>->data, so * long as the size is less than P<msg>->size. * * Returns: * These functions return the number of bytes read or * written, or 0 on error. Errors are stored in * F<ixp_errbuf>. */ uint ixp_sendmsg(int fd, IxpMsg *msg) { int r; msg->pos = msg->data; while(msg->pos < msg->end) { r = thread->write(fd, msg->pos, msg->end - msg->pos); if(r < 1) { if(errno == EINTR) continue; werrstr("broken pipe: %s", ixp_errbuf()); return 0; } msg->pos += r; } return msg->pos - msg->data; }
int get4(Map *map, uvlong addr, uint32 *x) { if (!map) { werrstr("get4: invalid map"); return -1; } if (map->nsegs == 1 && map->seg[0].fd < 0) { *x = addr; return 1; } if (mget(map, addr, x, 4) < 0) return -1; *x = machdata->swal(*x); return 1; }
static int mread(int fd, IxpMsg *msg, uint count) { int r, n; n = msg->end - msg->pos; if(n <= 0) { werrstr("buffer full"); return -1; } if(n > count) n = count; r = thread->read(fd, msg->pos, n); if(r > 0) msg->pos += r; return r; }
/* * the file is locked already * f->msource is unlocked */ static File * dirLookup(File *f, char *elem) { int i; MetaBlock mb; MetaEntry me; Block *b; Source *meta; File *ff; u32int bo, nb; meta = f->msource; b = nil; if(!sourceLock(meta, -1)) return nil; nb = (sourceGetSize(meta)+meta->dsize-1)/meta->dsize; for(bo=0; bo<nb; bo++){ b = sourceBlock(meta, bo, OReadOnly); if(b == nil) goto Err; if(!mbUnpack(&mb, b->data, meta->dsize)) goto Err; if(mbSearch(&mb, elem, &i, &me)){ ff = fileAlloc(f->fs); if(!deUnpack(&ff->dir, &me)){ fileFree(ff); goto Err; } sourceUnlock(meta); blockPut(b); ff->boff = bo; ff->mode = f->mode; ff->issnapshot = f->issnapshot; return ff; } blockPut(b); b = nil; } werrstr(ENoFile); /* fall through */ Err: sourceUnlock(meta); blockPut(b); return nil; }
static Ndbtuple* doquery(int fd, char *dn, char *type) { char buf[1024]; int n; Ndbtuple *t, *first, *last; seek(fd, 0, 0); snprint(buf, sizeof(buf), "!%s %s", dn, type); if(write(fd, buf, strlen(buf)) < 0) return nil; seek(fd, 0, 0); first = last = nil; for(;;){ n = read(fd, buf, sizeof(buf)-2); if(n <= 0) break; if(buf[n-1] != '\n') buf[n++] = '\n'; /* ndbparsline needs a trailing new line */ buf[n] = 0; /* check for the error condition */ if(buf[0] == '!'){ werrstr("%s", buf+1); return nil; } t = _ndbparseline(buf); if(t != nil){ if(first) last->entry = t; else first = t; last = t; while(last->entry) last = last->entry; } } ndbsetmalloctag(first, getcallerpc(&fd)); return first; }
int get2(Map *map, uvlong addr, ushort *x) { if (!map) { werrstr("get2: invalid map"); return -1; } if (map->nsegs == 1 && map->seg[0].fd < 0) { *x = addr; return 1; } if (mget(map, addr, x, 2) < 0) return -1; *x = machdata->swab(*x); return 1; }
int p9open(char *name, int mode) { int cexec, rclose; int fd, umode, lock, rdwr; rdwr = mode&3; umode = rdwr; cexec = mode&OCEXEC; rclose = mode&ORCLOSE; lock = mode&OLOCK; mode &= ~(3|OCEXEC|ORCLOSE|OLOCK); if(mode&OTRUNC){ umode |= O_TRUNC; mode ^= OTRUNC; } if(mode&ODIRECT){ umode |= O_DIRECT; mode ^= ODIRECT; } if(mode&ONONBLOCK){ /* windows doesn't have/need it */ sysfatal("umode |= O_NONBLOCK"); mode ^= ONONBLOCK; } if(mode&OAPPEND){ umode |= O_APPEND; mode ^= OAPPEND; } if(mode){ werrstr("mode 0x%x not supported", mode); return -1; } fd = open(name, umode); if(fd >= 0){ /* see create.c */ if(lock) sysfatal("open(OLOCK)"); if(cexec) sysfatal("open(OCEXEC)"); if(rclose) remove(name); } return fd; }
int nntpresponse(Netbuf *n, int e, char *cmd) { int r; char *p; for(;;){ p = Nrdline(n); if(p==nil){ strcpy(n->response, "early nntp eof"); return -1; } r = atoi(p); if(r/100 == 1){ /* BUG? */ fprint(2, "%s\n", p); continue; } break; } strecpy(n->response, n->response+sizeof(n->response), p); if((r=atoi(p)) == 0){ close(n->fd); n->fd = -1; fprint(2, "bad nntp response: %s\n", p); werrstr("bad nntp response"); return -1; } n->code = r; if(0 < e && e<10 && r/100 != e){ fprint(2, "%s: expected %dxx: got %s\n", cmd, e, n->response); return -1; } if(10 <= e && e<100 && r/10 != e){ fprint(2, "%s: expected %dx: got %s\n", cmd, e, n->response); return -1; } if(100 <= e && r != e){ fprint(2, "%s: expected %d: got %s\n", cmd, e, n->response); return -1; } return r; }
/* * Elf binaries. */ static int elfdotout(int fd, Fhdr *fp, ExecHdr *hp) { // Ehdr *ep; E64hdr *ep; /* bitswap the header according to the DATA format */ ep = &hp->e; // if(ep->ident[CLASS] == ELFCLASS32) // return elf32dotout(fd, fp, hp); // else if(ep->ident[CLASS] == ELFCLASS64) if(ep->ident[CLASS] == ELFCLASS64) return elf64dotout(fd, fp, hp); // werrstr("bad ELF class - not 32- nor 64-bit"); werrstr("bad ELF class - not 64-bit"); return 0; }
static int mkindices(VtEntry *e, u32int bn, int *index) { int i, np; memset(index, 0, (VtPointerDepth+1)*sizeof(int)); np = e->psize/VtScoreSize; for(i=0; bn > 0; i++){ if(i >= VtPointerDepth){ werrstr("bad address 0x%lux", (ulong)bn); return -1; } index[i] = bn % np; bn /= np; } return i; }
static int readn(int fd, IxpMsg *msg, uint count) { uint num; int r; num = count; while(num > 0) { r = mread(fd, msg, num); if(r == -1 && errno == EINTR) continue; if(r == 0) { werrstr("broken pipe"); return count - num; } num -= r; } return count - num; }
int delpart(char *s) { Part *p; for (p = tab; p < tab + nelem(tab); p++) if(p->inuse && strcmp(p->name, s) == 0) break; if(p == tab + nelem(tab)){ werrstr("partition not found"); return -1; } p->inuse = 0; free(p->name); p->name = nil; return 0; }
Map * newmap(Map *map, int n) { int size; size = sizeof(Map)+(n-1)*sizeof(struct segment); if (map == 0) map = malloc(size); else map = realloc(map, size); if (map == 0) { werrstr("out of memory: %r"); return 0; } memset(map, 0, size); map->nsegs = n; return map; }
int vnchandshake(Vnc *v) { char msg[VerLen+1]; msg[VerLen] = 0; vncrdbytes(v, msg, VerLen); if(strncmp(msg, "RFB ", 4) != 0){ werrstr("bad rfb version \"%s\"", msg); return -1; } if(verbose) fprint(2, "server version: %s", msg); strcpy(msg, version); vncwrbytes(v, msg, VerLen); vncflush(v); return 0; }
int delpart(char *s) { int i; for(i=0; i<nelem(tab); i++) if(tab[i].inuse && strcmp(tab[i].name, s) == 0) break; if(i==nelem(tab)){ werrstr("partition not found"); return -1; } tab[i].inuse = 0; free(tab[i].name); tab[i].name = 0; return 0; }
int dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s) { DwarfSym compunit = { }; if (dwarfenumunit(d, unit, &compunit) < 0) { return -1; } do { if (compunit.attrs.tag == tag) { *s = compunit; return 0; } if (dwarflookupchildtag(d, &compunit, tag, s) == 0) return 0; } while(dwarfnextsym(d, &compunit) == 0); werrstr("symbol with tag 0x%lux not found", tag); return -1; }
char* Nrdline(Netbuf *n) { char *p; int l; n->lineno++; Bflush(&n->bw); if((p = Brdline(&n->br, '\n')) == nil){ werrstr("nntp eof"); return nil; } p[l=Blinelen(&n->br)-1] = '\0'; if(l > 0 && p[l-1] == '\r') p[l-1] = '\0'; if(netdebug) fprint(2, "-> %s\n", p); return p; }
/* An inline function picks off the calls to dwarfget128 for 1-byte encodings, * more than by far the common case (99.999% on most binaries!). */ ulong dwarfget128(DwarfBuf *b) { static int nbad; ulong c, d; if(b->p == nil) return 0; c = *b->p++; if(!(c&0x80)) {n1++; return c; } c &= ~0x80; d = *b->p++; c |= (d&0x7F)<<7; if(!(d&0x80)) {n2++; return c; } d = *b->p++; c |= (d&0x7F)<<14; if(!(d&0x80)) {n3++; return c; } d = *b->p++; c |= (d&0x7F)<<21; if(!(d&0x80)) {n4++; return c; } d = *b->p++; c |= (d&0x7F)<<28; if(!(d&0x80)) {n5++; return c; } while(b->p<b->ep && *b->p&0x80) b->p++; if(++nbad == 1) werrstr("dwarf: overflow during parsing of uleb128 integer"); return c; }
static int _pcall1(Pcall *tx, Pcall *rx, uint16 timeoutms, uint16 preamblems, uint tries) { int rv; if(tagseqidx == nelem(tagseq)){ werrstr("ran out of tags"); return -1; } tx->tag = tagseq[tagseqidx]; do rv = _ptxrx(tx, rx, timeoutms, preamblems); while(--tries > 0 && rv == 0); if(rv == 1) ++tagseqidx; return rv; }
char* vtSetError(char* fmt, ...) { Thread *p; char *s; va_list args; p = threadLookup(); va_start(args, fmt); s = vsmprint(fmt, args); vtMemFree(p->error); p->error = s; va_end(args); if(ERROR) fprint(2, "vtSetError: %s\n", p->error); werrstr("%s", p->error); return p->error; }
int myetheraddr(uchar *to, char *dev) { Ipifc *ifclist, *ifc; ifclist = readipifc(nil, nil, -1); for(ifc=ifclist; ifc; ifc=ifc->next){ if(dev && strcmp(ifc->dev, dev) != 0) continue; if(memcmp(zea, ifc->ether, 6) == 0) continue; memmove(to, ifc->ether, 6); freeipifc(ifclist); return 0; } freeipifc(ifclist); werrstr("no ethernet devices"); return -1; }
int p9listen(char *dir, char *newdir) { int fd, one; if((fd = _p9netfd(dir)) < 0){ werrstr("bad 'directory' in listen: %s", dir); return -1; } if((fd = accept(fd, nil, nil)) < 0) return -1; one = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one); putfd(newdir, fd); return fd; }
Key* plan9authkey(Attr *a) { char *dom; Key *k; /* * The only important part of a is dom. * We don't care, for example, about user name. */ dom = strfindattr(a, "dom"); if(dom) k = keylookup("proto=p9sk1 role=server user? dom=%q", dom); else k = keylookup("proto=p9sk1 role=server user? dom?"); if(k == nil) werrstr("could not find plan 9 auth key dom %q", dom); return k; }
void* muxrpc(Mux *mux, void *tx) { int tag; Muxrpc *r; void *p; if((r = allocmuxrpc(mux)) == nil) return nil; if((tag = tagmuxrpc(r, tx)) < 0) return nil; qlock(&mux->lk); /* wait for our packet */ while(mux->muxer && mux->muxer != r && !r->p) rsleep(&r->r); /* if not done, there's no muxer: start muxing */ if(!r->p){ if(mux->muxer != nil && mux->muxer != r) abort(); mux->muxer = r; while(!r->p){ qunlock(&mux->lk); _muxrecv(mux, 1, &p); if(p == nil){ /* eof -- just give up and pass the buck */ qlock(&mux->lk); dequeue(mux, r); break; } muxmsgandqlock(mux, p); } electmuxer(mux); } p = r->p; puttag(mux, r); qunlock(&mux->lk); if(p == nil) werrstr("unexpected eof"); return p; }
static int mmcreaddiscinfo(Drive *drive, void *data, int nbytes) { uchar cmd[10]; int n; memset(cmd, 0, sizeof(cmd)); cmd[0] = ScmdRdiscinfo; cmd[7] = nbytes>>8; cmd[8] = nbytes; n = scsi(drive, cmd, sizeof(cmd), data, nbytes, Sread); if(n < 24) { if(n >= 0) werrstr("rdiscinfo returns %d", n); return -1; } return n; }
/* * make factotum add wep keys to an 802.11 device */ int auth_wep(char *dev, char *fmt, ...) { AuthRpc *rpc; char *params, *p; int fd; va_list arg; int rv; rv = -1; if(dev == nil){ werrstr("no device specified"); return rv; } fd = open("/mnt/factotum/rpc", ORDWR); if(fd < 0) return rv; rpc = auth_allocrpc(fd); if(rpc != nil){ quotefmtinstall(); /* just in case */ va_start(arg, fmt); params = vsmprint(fmt, arg); va_end(arg); if(params != nil){ p = smprint("proto=wep %s", params); if(p != nil){ if(auth_rpc(rpc, "start", p, strlen(p)) == ARok && auth_rpc(rpc, "write", dev, strlen(dev)) == ARok) rv = 0; free(p); } free(params); } auth_freerpc(rpc); } close(fd); return rv; }
/* * plan9 authentication followed by rc4 encryption */ static int p9auth(int fd) { uchar key[16]; uchar digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; int i; AuthInfo *ai; procsetname("%s: auth_proxy proto=%q role=client %s", origargs, p9authproto, keyspec); ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", p9authproto, keyspec); if(ai == nil) return -1; memmove(key+4, ai->secret, ai->nsecret); if(ealgs == nil) return fd; /* exchange random numbers */ srand(truerand()); for(i = 0; i < 4; i++) key[i] = rand(); procsetname("writing p9 key"); if(write(fd, key, 4) != 4) return -1; procsetname("reading p9 key"); if(readn(fd, key+12, 4) != 4) return -1; /* scramble into two secrets */ sha1(key, sizeof(key), digest, nil); mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); /* set up encryption */ procsetname("pushssl"); i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil); if(i < 0) werrstr("can't establish ssl connection: %r"); return i; }
static int httprcode(HttpState *hs) { int n; char *p; char buf[256]; n = readline(&hs->b, buf, sizeof(buf)-1); if(n <= 0) return n; if(httpdebug) fprint(2, "-> %s\n", buf); p = strchr(buf, ' '); if(memcmp(buf, "HTTP/", 5) != 0 || p == nil){ werrstr("bad response from server"); return -1; } buf[n] = 0; return atoi(p+1); }
static int getlock(char *lock) { char buf[ERRMAX]; int i, fd; enum { SECS = 200 }; for(i=0; i<SECS*10; i++){ fd = wcreate(lock, ORDWR, DMEXCL|0666); if(fd >= 0) return fd; buf[0] = '\0'; rerrstr(buf, sizeof buf); if(strstr(buf, "locked") == nil) break; sleep(1000/10); } werrstr("couldn't acquire lock %s: %r", lock); return -1; }
int get1(Map *map, uint64_t addr, uint8_t *x, int size) { uint8_t *cp; if (!map) { werrstr("get1: invalid map"); return -1; } if (map->nsegs == 1 && map->seg[0].fd < 0) { cp = (uint8_t*)&addr; while (cp < (uint8_t*)(&addr+1) && size-- > 0) *x++ = *cp++; while (size-- > 0) *x++ = 0; } else return mget(map, addr, x, size); return 1; }