Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
void
osproc(Proc *p)
{
	pthread_t pid;

	if(pthread_create(&pid, nil, tramp, p)){
		oserrstr();
		panic("osproc: %r");
	}
	sched_yield();
}
Beispiel #4
0
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;
	}
}
Beispiel #5
0
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);
}
Beispiel #6
0
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();
}
Beispiel #7
0
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
}
Beispiel #8
0
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();
}
Beispiel #9
0
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();
}
Beispiel #10
0
void
oserror(void)
{
	oserrstr();
	nexterror();
}
Beispiel #11
0
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;
}
Beispiel #12
0
void
oserror(void)
{
	oserrstr(up->env->errstr, ERRMAX);
	error(up->env->errstr);
}