Ejemplo n.º 1
0
Archivo: aoi.c Proyecto: lhw/wargame
int
main(int argc, char *argv[])
{
	int ch, daemon = 0, s;
	struct passwd *pw;
	struct sockaddr_in sin;
	pid_t pid;

	while ((ch = getopt(argc, argv, "c:df:hp:u:")) != -1) {
		switch (ch) {
		case 'c':
			chrootdir = optarg;
			break;
		case 'd':
			daemon = 1;
			break;
		case 'f':
			filesdir = optarg;
			break;
		case 'p':
			port = atoi(optarg);
			break;
		case 'u':
			user = optarg;
			break;
		case '?':
		case 'h':
			usage();
			break;
		}
	}

	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		err(1, "socket");

	memset(&sin, 0, sizeof(sin));
	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);

	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		err(1, "bind");
	if (listen(s, 5) < 0)
		err(1, "listen");

	if ((pw = getpwnam(user)) == NULL)
		err(1, "getpwnam");

	if (chroot(chrootdir) < 0)
		err(1, "chroot");
	if (chdir("/") < 0)
		err(1, "chdir");

	if(setgroups(1, &pw->pw_gid) ||
	   setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
           setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
		err(1, "can't drop privileges");

	endpwent();

	if (daemon) {
		switch (pid = fork()) {
		case -1:
			err(1, "cannot fork");
		case 0:
			break;
		default:
			printf("pid: %d\n", pid);
			exit(0);
		}
	}

	for (;;) {
		int c;
		ssize_t n;
		char buf[1024];
		struct sockaddr_in cin;
		socklen_t len = sizeof(cin);

		if ((c = accept(s, (struct sockaddr *)&cin, &len)) < 0)
			err(1, "accept");
		pid = fork();
		if (pid < 0)
			err(1, "fork");
		if (pid = 0)
			continue;
		
		while ((n = recv(c, buf, sizeof(buf), 0)) > 0) {
			if (n > 0)
				buf[n-1] = '\0';
			handlecommand(c, buf);
			memset(buf, 0, sizeof(buf));
		}
		//return;
	}
}
Ejemplo n.º 2
0
static void idle(struct net_device *dev)
{
	unsigned long flags;
	int state;
	/* FIXME This is initialized to shut the warning up, but I need to
	 * think this through again.
	 */
	struct xmitQel *q = NULL;
	int oops;
	int i;
	int base = dev->base_addr;

	spin_lock_irqsave(&txqueue_lock, flags);
	if(QInIdle) {
		spin_unlock_irqrestore(&txqueue_lock, flags);
		return;
	}
	QInIdle = 1;
	spin_unlock_irqrestore(&txqueue_lock, flags);

	/* this tri-states the IRQ line */
	(void) inb_p(base+6);

	oops = 100;

loop:
	if (0>oops--) { 
		printk("idle: looped too many times\n");
		goto done;
	}

	state = inb_p(base+6);
	if (state != inb_p(base+6)) goto loop;

	switch(state) {
		case 0xfc:
			/* incoming command */
			if (debug & DEBUG_LOWER) printk("idle: fc\n");
			handlefc(dev); 
			break;
		case 0xfd:
			/* incoming data */
			if(debug & DEBUG_LOWER) printk("idle: fd\n");
			handlefd(dev); 
			break;
		case 0xf9:
			/* result ready */
			if (debug & DEBUG_LOWER) printk("idle: f9\n");
			if(!mboxinuse[0]) {
				mboxinuse[0] = 1;
				qels[0].cbuf = rescbuf;
				qels[0].cbuflen = 2;
				qels[0].dbuf = resdbuf;
				qels[0].dbuflen = 2;
				qels[0].QWrite = 0;
				qels[0].mailbox = 0;
				enQ(&qels[0]);
			}
			inb_p(dev->base_addr+1);
			inb_p(dev->base_addr+0);
			if( wait_timeout(dev,0xf9) )
				printk("timed out idle f9\n");
			break;
		case 0xf8:
			/* ?? */
			if (xmQhd) {
				inb_p(dev->base_addr+1);
				inb_p(dev->base_addr+0);
				if(wait_timeout(dev,0xf8) )
					printk("timed out idle f8\n");
			} else {
				goto done;
			}
			break;
		case 0xfa:
			/* waiting for command */
			if(debug & DEBUG_LOWER) printk("idle: fa\n");
			if (xmQhd) {
				q=deQ();
				memcpy(ltdmacbuf,q->cbuf,q->cbuflen);
				ltdmacbuf[1] = q->mailbox;
				if (debug>1) { 
					int n;
					printk("ltpc: sent command     ");
					n = q->cbuflen;
					if (n>100) n=100;
					for(i=0;i<n;i++)
						printk("%02x ",ltdmacbuf[i]);
					printk("\n");
				}
				handlecommand(dev);
					if(0xfa==inb_p(base+6)) {
						/* we timed out, so return */
						goto done;
					} 
			} else {
				/* we don't seem to have a command */
				if (!mboxinuse[0]) {
					mboxinuse[0] = 1;
					qels[0].cbuf = rescbuf;
					qels[0].cbuflen = 2;
					qels[0].dbuf = resdbuf;
					qels[0].dbuflen = 2;
					qels[0].QWrite = 0;
					qels[0].mailbox = 0;
					enQ(&qels[0]);
				} else {
					printk("trouble: response command already queued\n");
					goto done;
				}
			} 
			break;
		case 0Xfb:
			/* data transfer ready */
			if(debug & DEBUG_LOWER) printk("idle: fb\n");
			if(q->QWrite) {
				memcpy(ltdmabuf,q->dbuf,q->dbuflen);
				handlewrite(dev);
			} else {
				handleread(dev);
				/* non-zero mailbox numbers are for
				   commmands, 0 is for GETRESULT
				   requests */
				if(q->mailbox) {
					memcpy(q->dbuf,ltdmabuf,q->dbuflen);
				} else { 
					/* this was a result */
					mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1];
					mboxinuse[0]=0;
				}
			}
			break;
	}
	goto loop;

done:
	QInIdle=0;

	/* now set the interrupts back as appropriate */
	/* the first read takes it out of tri-state (but still high) */
	/* the second resets it */
	/* note that after this point, any read of base+6 will
	   trigger an interrupt */

	if (dev->irq) {
		inb_p(base+7);
		inb_p(base+7);
	}
	return;
}