int so_socket(int type, unsigned char *addr) { int fd, one; switch(type) { default: error("bad protocol type"); case S_TCP: type = SOCK_STREAM; break; case S_UDP: type = SOCK_DGRAM; break; } fd = socket(family(addr), type, 0); if(fd < 0) oserror(); one = 1; if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){ oserrstr(); print("setsockopt: %r"); } return fd; }
static void cmdproc(void *a) { Conv *c; int n; char status[ERRMAX]; void *t; c = a; qlock(&c->l); if(Debug) print("f[0]=%q f[1]=%q\n", c->cmd->f[0], c->cmd->f[1]); if(waserror()){ if(Debug) print("failed: %q\n", up->env->errstr); kstrdup(&c->error, up->env->errstr); c->state = "Done"; qunlock(&c->l); Wakeup(&c->startr); pexit("cmdproc", 0); } t = oscmd(c->cmd->f+1, c->nice, c->dir, c->fd); if(t == nil) oserror(); c->child = t; /* to allow oscmdkill */ poperror(); qunlock(&c->l); Wakeup(&c->startr); if(Debug) print("started\n"); while(waserror()) oscmdkill(t); osenter(); n = oscmdwait(t, status, sizeof(status)); osleave(); if(n < 0){ oserrstr(up->genbuf, sizeof(up->genbuf)); n = snprint(status, sizeof(status), "0 0 0 0 %q", up->genbuf); } qlock(&c->l); c->child = nil; oscmdfree(t); if(Debug){ status[n]=0; print("done %d %d %d: %q\n", c->fd[0], c->fd[1], c->fd[2], status); } if(c->inuse > 0){ c->state = "Done"; if(c->waitq != nil) qproduce(c->waitq, status, n); }else closeconv(c); qunlock(&c->l); pexit("", 0); }
void osproc(Proc *p) { pthread_t pid; if(pthread_create(&pid, nil, tramp, p)){ oserrstr(); panic("osproc: %r"); } sched_yield(); }
long ipread(Chan *ch, void *a, long n, vlong offset) { int r; Conv *c; Proto *x; uchar ip[4]; char buf[128], *p; /*print("ipread %s %lux\n", c2name(ch), (long)ch->qid.path);*/ p = a; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcs: return csread(ch, a, n, offset); case Qprotodir: case Qtopdir: case Qconvdir: return devdirread(ch, a, n, 0, 0, ipgen); case Qctl: sprint(buf, "%d", CONV(ch->qid)); return readstr(offset, p, n, buf); case Qremote: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; hnputl(ip, c->raddr); sprint(buf, "%I!%d\n", ip, c->rport); return readstr(offset, p, n, buf); case Qlocal: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; hnputl(ip, c->laddr); sprint(buf, "%I!%d\n", ip, c->lport); return readstr(offset, p, n, buf); case Qstatus: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->r.ref, c->state); return readstr(offset, p, n, buf); case Qdata: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; r = so_recv(c->sfd, a, n, 0); if(r < 0){ oserrstr(); nexterror(); } return r; } }
static void fserr(Fsinfo *f) { int n; char *p; oserrstr(up->env->errstr, ERRMAX); if(f != nil && *up->env->errstr == '\'' && (n = strlen(f->root)) > 1){ /* don't reveal full names */ if(strncmp(up->env->errstr+1, f->root, n-1) == 0){ p = up->env->errstr+1+n; memmove(up->env->errstr+1, p, strlen(p)+1); } } error(up->env->errstr); }
void so_bind(int fd, int su, unsigned short port, unsigned char *addr) { int i, one; struct sockaddr_storage ss; one = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){ oserrstr(); print("setsockopt: %r"); } if(su) { for(i = 600; i < 1024; i++) { memset(&ss, 0, sizeof(ss)); ss.ss_family = family(addr); switch(ss.ss_family){ case AF_INET: ((struct sockaddr_in*)&ss)->sin_port = i; break; case AF_INET6: ((struct sockaddr_in6*)&ss)->sin6_port = i; break; } if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) return; } oserror(); } memset(&ss, 0, sizeof(ss)); ss.ss_family = family(addr); switch(ss.ss_family){ case AF_INET: hnputs(&((struct sockaddr_in*)&ss)->sin_port, port); break; case AF_INET6: hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port); break; } if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); }
void arpadd(char *ipaddr, char *eaddr, int n) { #ifdef SIOCGARP struct arpreq a; struct sockaddr_in pa; int s; uchar addr[IPaddrlen]; s = socket(AF_INET, SOCK_DGRAM, 0); memset(&a, 0, sizeof(a)); memset(&pa, 0, sizeof(pa)); pa.sin_family = AF_INET; pa.sin_port = 0; parseip(addr, ipaddr); if(!isv4(addr)){ close(s); error(Ebadarg); } memmove(&pa.sin_addr, ipaddr+IPv4off, IPv4addrlen); memmove(&a.arp_pa, &pa, sizeof(pa)); while(ioctl(s, SIOCGARP, &a) != -1) { ioctl(s, SIOCDARP, &a); memset(&a.arp_ha, 0, sizeof(a.arp_ha)); } a.arp_ha.sa_family = AF_UNSPEC; parsemac((uchar*)a.arp_ha.sa_data, eaddr, 6); a.arp_flags = ATF_PERM; if(ioctl(s, SIOCSARP, &a) == -1) { oserrstr(up->env->errstr, ERRMAX); close(s); error(up->env->errstr); } close(s); #else error("arp not implemented"); #endif }
void so_bind(int fd, int su, uchar *addr, ushort port) { int i, one; struct sockaddr_storage sa; struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6*)&sa; one = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0) { oserrstr(up->genbuf, sizeof(up->genbuf)); print("setsockopt: %s", up->genbuf); } if(su) { for(i = 600; i < 1024; i++) { memset(&sa, 0, sizeof(sa)); sin6->sin6_family = AF_INET6; memmove(&sin6->sin6_addr, addr, IPaddrlen); hnputs(&sin6->sin6_port, i); if(bind(fd, (struct sockaddr*)sin6, sizeof(*sin6)) >= 0) return; } oserror(); } memset(&sa, 0, sizeof(sa)); sin6->sin6_family = AF_INET6; memmove(&sin6->sin6_addr, addr, IPaddrlen); hnputs(&sin6->sin6_port, port); if(bind(fd, (struct sockaddr*)sin6, sizeof(*sin6)) < 0) oserror(); }
void so_bind(int fd, int su, uchar *addr, ushort port) { int i, one; struct sockaddr sa; struct sockaddr_in *sin; sin = (struct sockaddr_in*)&sa; one = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0) { oserrstr(up->genbuf, sizeof(up->genbuf)); print("setsockopt: %s", up->genbuf); } if(su) { for(i = 600; i < 1024; i++) { memset(&sa, 0, sizeof(sa)); sin->sin_family = AF_INET; memmove(&sin->sin_addr.s_addr, addr+IPv4off, IPv4addrlen); hnputs(&sin->sin_port, i); if(bind(fd, &sa, sizeof(sa)) >= 0) return; } oserror(); } memset(&sa, 0, sizeof(sa)); sin->sin_family = AF_INET; memmove(&sin->sin_addr.s_addr, addr+IPv4off, IPv4addrlen); hnputs(&sin->sin_port, port); if(bind(fd, &sa, sizeof(sa)) < 0) oserror(); }
void oserror(void) { oserrstr(); nexterror(); }
long ipwrite(Chan *ch, void *a, long n, vlong offset) { Conv *c; Proto *x; int r, nf; char *p, *fields[3], buf[128]; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcs: return cswrite(ch, a, n, offset); case Qctl: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; nf = tokenize(buf, fields, 3); if(strcmp(fields[0], "connect") == 0){ switch(nf) { default: error("bad args to connect"); case 2: p = setraddrport(c, fields[1]); if(p != 0) error(p); break; case 3: p = setraddrport(c, fields[1]); if(p != 0) error(p); c->lport = atoi(fields[2]); setlport(c); break; } so_connect(c->sfd, c->raddr, c->rport); setladdr(c); c->state = "Established"; return n; } if(strcmp(fields[0], "announce") == 0) { switch(nf){ default: error("bad args to announce"); case 2: setladdrport(c, fields[1]); break; } so_listen(c->sfd); c->state = "Announced"; return n; } if(strcmp(fields[0], "bind") == 0){ switch(nf){ default: error("bad args to bind"); case 2: c->lport = atoi(fields[1]); break; } setlport(c); return n; } error("bad control message"); case Qdata: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; r = so_send(c->sfd, a, n, 0); if(r < 0){ oserrstr(); nexterror(); } return r; } return n; }
void oserror(void) { oserrstr(up->env->errstr, ERRMAX); error(up->env->errstr); }