Exemplo n.º 1
0
Arquivo: e.c Projeto: knusbaum/Wily
/* Handle all the messages coming from wily.
 */
void
domsg(Msg *m)
{
	switch(m->mtype) {
	case 'R':
		handleread(m);
		break;
	default:
		/* ignore whatever we don't specifically handle */
		if(debug) {
			printf("message received and ignored: ");
			msg_print(m);
		}
		break;	
	}
}
Exemplo 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;
}
Exemplo n.º 3
0
int
main(int argc, char *argv[])
{
	struct pollfd pfd[1];
	char *ep, *cp;
	int on = 1;
	int send_time = 180;	/* Default time, 180 seconds (3 minutes) */
	struct sockaddr_in m_sin;
	uid_t unpriv_uid;
	gid_t unpriv_gid;
	long tmp;
	time_t delta = 0;
	struct timeval next, now;

	if (getuid())
		errx(1, "not super user");

	run_as(&unpriv_uid, &unpriv_gid);

	argv++; argc--;
	while (argc > 0 && *argv[0] == '-') {
		if (strcmp(*argv, "-m") == 0) {
			if (argc > 1 && *(argv + 1)[0] != '-') {
				/* Argument has been given */
				argv++, argc--;
				multicast_mode = SCOPED_MULTICAST;
				tmp = strtol(*argv, &ep, 10);
				if (*ep != '\0' || tmp < INT_MIN || tmp > INT_MAX)
					errx(1, "invalid ttl: %s", *argv);
				multicast_scope = (int)tmp;
				if (multicast_scope > MAX_MULTICAST_SCOPE)
					errx(1, "ttl must not exceed %u",
					MAX_MULTICAST_SCOPE);
			}
			else multicast_mode = PER_INTERFACE_MULTICAST;
		} else if (strcmp(*argv, "-g") == 0) {
			if (argc > 1 && *(argv + 1)[0] != '-') {
				argv++, argc--;
				send_time = (int)strtol(*argv, &ep, 10);
				if (send_time <= 0)
					errx(1, "time must be greater than 0");

				if (ep[0] != '\0') {
					if (ep[1] != '\0')
						errx(1, "invalid argument: %s", *argv);
					if (*ep == 'M' || *ep == 'm') {
						/* Time in minutes. */
						send_time *= 60;
					} else
						errx(1, "invalid argument: %s", *argv);
				}

				if (send_time > 180)
					errx(1, "cannot be greater than 180 seconds (3 minutes)");
			} else
				errx(1, "missing argument");
		} else if (strcmp(*argv, "-i") == 0)
			insecure_mode = 1;
		else if (strcmp(*argv, "-l") == 0)
			quiet_mode = 1;
		else if (strcmp(*argv, "-p") == 0)
			iff_flag = 0;
		else
			usage();
		argv++, argc--;
	}
	if (argc > 0)
		usage();
#ifndef DEBUG
        struct pidfh *pfh = NULL;
        pfh = pidfile_open(NULL, 600, NULL);
	daemon(1, 0);
        pidfile_write(pfh);
#endif
	signal(SIGHUP, hup);
	openlog("rwhod", LOG_PID, LOG_DAEMON);
	sp = getservbyname("who", "udp");
	if (sp == NULL)
		quit("udp/who: unknown service", WITHOUT_ERRNO);

	if (chdir(_PATH_RWHODIR) < 0)
		quit(_PATH_RWHODIR, WITH_ERRNO);

	/*
	 * Establish host name as returned by system.
	 */
	if (gethostname(myname, sizeof(myname)) < 0)
		quit("gethostname", WITH_ERRNO);

	if ((cp = strchr(myname, '.')) != NULL)
		*cp = '\0';
	strlcpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname));
	utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
	if (utmpf < 0)
		quit(_PATH_UTMP, WITH_ERRNO);

	getboottime();
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		quit("socket", WITH_ERRNO);

	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
		quit("setsockopt SO_BROADCAST", WITH_ERRNO);

	memset(&m_sin, 0, sizeof(m_sin));
	m_sin.sin_len = sizeof(m_sin);
	m_sin.sin_family = AF_INET;
	m_sin.sin_port = sp->s_port;
	if (bind(s, (struct sockaddr *)&m_sin, sizeof(m_sin)) < 0)
		quit("bind", WITH_ERRNO);

	setgid(unpriv_gid);
	setgroups(1, &unpriv_gid);	/* XXX BOGUS groups[0] = egid */
	setuid(unpriv_uid);
	if (!configure(s))
		exit(1);

	if (!quiet_mode) {
		send_host_information();
		delta = send_time;
		gettimeofday(&now, NULL);
		timeadd(&now, delta, &next);
	}

	pfd[0].fd = s;
	pfd[0].events = POLLIN;
 
	for (;;) {
		int n;

		n = poll(pfd, 1, 1000);

		if (onsighup) {
			onsighup = 0;
			getboottime();
		}

		if (n == 1)
			handleread(s);
		if (!quiet_mode) {
			gettimeofday(&now, NULL);
			if (now.tv_sec > next.tv_sec) {
				send_host_information();
				timeadd(&now, delta, &next);
			}
		}
	}
}
Exemplo n.º 4
0
int main(int argc,  char *argv[])
{
	struct sockaddr_in sockname;
	int max = -1, omax;	     /* the biggest value sd. for select */
	int sd;			     /* our listen socket */
	fd_set *readable = NULL , *writable = NULL; /* fd_sets for select */
	u_short port;
	u_long p;
	char *ep;
	int i;

	/*
	 * first, figure out what port we will listen on - it should
	 * be our first parameter.
	 */

	if (argc != 2)
		usage();
		errno = 0;
        p = strtoul(argv[1], &ep, 10);
        if (*argv[1] == '\0' || *ep != '\0') {
		/* parameter wasn't a number, or was empty */
		fprintf(stderr, "%s - not a number\n", argv[1]);
		usage();
	}
        if ((errno == ERANGE && p == ULONG_MAX) || (p > USHRT_MAX)) {
		/* It's a number, but it either can't fit in an unsigned
		 * long, or is too big for an unsigned short
		 */
		fprintf(stderr, "%s - value out of range\n", argv[1]);
		usage();
	}
	/* now safe to do this */
	port = p;

	/* now before we get going, decide if we want to daemonize, that
	 * is, run in the background like a real system process
	 */
#ifndef DEBUG
	/* don't daemonize if we compile with -DDEBUG */
	if (daemon(1, 0) == -1)
		err(1, "daemon() failed");
#endif

	/* now off to the races - let's set up our listening socket */
	memset(&sockname, 0, sizeof(sockname));
	sockname.sin_family = AF_INET;
	sockname.sin_port = htons(port);
	sockname.sin_addr.s_addr = htonl(INADDR_ANY);
	sd=socket(AF_INET,SOCK_STREAM,0);
	if ( sd == -1)
		err(1, "socket failed");

	if (bind(sd, (struct sockaddr *) &sockname, sizeof(sockname)) == -1)
		err(1, "bind failed");

	if (listen(sd,3) == -1)
		err(1, "listen failed");

	/* 
	 * We're now bound, and listening for connections on "sd".
	 * Each call to "accept" will return us a descriptor talking to
	 * a connected client.
	 */

	/*
	 * finally - the main loop.  accept connections and deal with 'em
	 */
#ifndef DEBUG
	/*
	 * since we'll be running as a daemon if we're not compiled with
	 * -DDEBUG, we better not be using printf - since stdout will be
	 * unusable
	 */
	printf("Server up and listening for connections on port %u\n", port);
#endif	

	/* initialize all our connection structures */
	for (i = 0; i < MAXCONN; i++)
		closecon(&connections[i], 1);

	for(;;) {
		int i;
		int maxfd = -1; /* the biggest value sd we are interested in.*/

		/*
		 * first we have to initialize the fd_sets to keep
		 * track of readable and writable sockets. we have
		 * to make sure we have fd_sets that are big enough
		 * to hold our largest valued socket descriptor.
		 * so first, we find the max value by iterating through
		 * all the connections, and then we allocate fd sets
		 * that are big enough, if they aren't already.
		 */
		omax = max;
		max = sd; /* the listen socket */

		for (i = 0; i < MAXCONN; i++) {
			if (connections[i].sd > max)
				max = connections[i].sd;
		}
		if (max > omax) {
			/* we need bigger fd_sets allocated */

			/* free the old ones - does nothing if they are NULL */
			free(readable);
			free(writable);

			/*
			 * this is how to allocate fd_sets for select
			 */
			readable = (fd_set *)calloc(howmany(max + 1, NFDBITS),
			    sizeof(fd_mask));
			if (readable == NULL)
				err(1, "out of memory");
			writable = (fd_set *)calloc(howmany(max + 1, NFDBITS),
			    sizeof(fd_mask));
			if (writable == NULL)
				err(1, "out of memory");
			omax = max;
			/*
			 * note that calloc always returns 0'ed memory,
			 * (unlike malloc) so these sets are all set to 0
			 * and ready to go
			 */
		} else {
			/*
			 * our allocated sets are big enough, just make
			 * sure they are cleared to 0. 
			 */
			memset(readable, 0, howmany(max+1, NFDBITS) *
			    sizeof(fd_mask));
			memset(writable, 0, howmany(max+1, NFDBITS) *
			    sizeof(fd_mask));
		}

		/*
		 * Now, we decide which sockets we are interested
		 * in reading and writing, by setting the corresponding
		 * bit in the readable and writable fd_sets.
		 */

		/*
		 * we are always interesting in reading from the
		 * listening socket. so put it in the read set.
		 */

		FD_SET(sd, readable);
		if (maxfd < sd)
			maxfd = sd;

		/*
		 * now go through the list of connections, and if we
		 * are interested in reading from, or writing to, the
		 * connection's socket, put it in the readable, or
		 * writable fd_set - in preparation to call select
		 * to tell us which ones we can read and write to.
		 */
		for (i = 0; i<MAXCONN; i++) {
			if (connections[i].state == STATE_READING) {
				FD_SET(connections[i].sd, readable);
				if (maxfd < connections[i].sd)
					maxfd = connections[i].sd;
			}
			if (connections[i].state == STATE_WRITING) {
				FD_SET(connections[i].sd, writable);
				if (maxfd < connections[i].sd)
					maxfd = connections[i].sd;
			}
		}

		/*
		 * finally, we can call select. we have filled in "readable"
		 * and "writable" with everything we are interested in, and
		 * when select returns, it will indicate in each fd_set
		 * which sockets are readable and writable
		 */
		i = select(maxfd + 1, readable, writable, NULL,NULL);
		if (i == -1  && errno != EINTR)
			err(1, "select failed");
		if (i > 0) {

			/* something is readable or writable... */

			/*
			 * First things first.  check the listen socket.
			 * If it was readable - we have a new connection
			 * to accept.
			 */

			if (FD_ISSET(sd, readable)) {
				struct con *cp;
				int newsd;
				socklen_t slen;
				struct sockaddr_in sa;

				slen = sizeof(sa);
				newsd = accept(sd, (struct sockaddr *)&sa,
				    &slen);
				if (newsd == -1)
					err(1, "accept failed");

				cp = get_free_conn();
				if (cp == NULL) {
					/*
					 * we have no connection structures
					 * so we close connection to our
					 * client to not leave him hanging
					 * because we are too busy to
					 * service his request
					 */
					close(newsd);
				} else {
					/*
					 * ok, if this worked, we now have a
					 * new connection. set him up to be
					 * READING so we do something with him
					 */
					cp->state = STATE_READING;
					cp->sd = newsd;
					cp->slen = slen;
					memcpy(&cp->sa, &sa, sizeof(sa));
				}
			}
			/*
			 * now, iterate through all of our connections,
			 * check to see if they are readble or writable,
			 * and if so, do a read or write accordingly 
			 */
			for (i = 0; i<MAXCONN; i++) {
				if ((connections[i].state == STATE_READING) &&
				    FD_ISSET(connections[i].sd, readable))
					handleread(&connections[i]);
				if ((connections[i].state == STATE_WRITING) &&
				    FD_ISSET(connections[i].sd, writable))
					handlewrite(&connections[i]);
			}
		}
	}
}
Exemplo n.º 5
0
static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
{
	int i, j;
	int gotit;
	struct asyncreq *ar;

	if (uae_sem_trywait (&async_sem)) {
		uaenet_int_requested = 0;
		uaenet_int_late = 1;
		return 0;
	}
	for (i = 0; i < MAX_OPEN_DEVICES; i++)
		pdevst[i].tmp = 0;

	for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) {
		struct s2devstruct *dev = &devst[i];
		struct s2packet *p;
		if (dev->online) {
			while (dev->readqueue) {
				uae_u16 type;
				p = dev->readqueue;
				type = (p->data[2 * ADDR_SIZE] << 8) | p->data[2 * ADDR_SIZE + 1];
				ar = dev->ar;
				gotit = 0;
				while (ar) {
					if (!ar->ready) {
						uaecptr request = ar->request;
						int command = get_word (request + 28);
						uae_u32 packettype = get_long (request + 32 + 4);
						if (command == CMD_READ && (packettype == type || (packettype <= 1500 && type <= 1500))) {
							struct priv_s2devstruct *pdev = getps2devstruct (request);
							if (pdev && pdev->tmp == 0) {
								if (handleread (ctx, pdev, request, p->data, p->len, command)) {
									if (log_net)
										write_log (_T("-> %p Accepted, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len);
									ar->ready = 1;
									write_comm_pipe_u32 (&dev->requests, request, 1);
									dev->packetsreceived++;
									gotit = 1;
									pdev->tmp = 1;
								} else {
									if (log_net)
										write_log (_T("-> %p PacketFilter() rejected, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len);
									pdev->tmp = -1;
								}
							}
						}
					}
					ar = ar->next;
				}
				ar = dev->ar;
				while (ar) {
					if (!ar->ready) {
						uaecptr request = ar->request;
						int command = get_word (request + 28);
						if (command == S2_READORPHAN) {
							struct priv_s2devstruct *pdev = getps2devstruct (request);
							if (pdev && pdev->tmp <= 0) {
								if (log_net)
									write_log (_T("-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n"), p, request, p->len);
								handleread (ctx, pdev, request, p->data, p->len, command);
								ar->ready = 1;
								write_comm_pipe_u32 (&dev->requests, request, 1);
								dev->packetsreceived++;
								dev->unknowntypesreceived++;
								gotit = 1;
								pdev->tmp = 1;
							}
						}
					}
					ar = ar->next;
				}
				if (!gotit) {
					if (log_net)
						write_log (_T("-> %p packet dropped, LEN=%d\n"), p, p->len);
					for (j = 0; j < MAX_OPEN_DEVICES; j++) {
						if (pdevst[j].unit == dev->unit) {
							if (pdevst[j].tracks[type])
								pdevst[j].packetsdropped++;
						}
					}
				}
				dev->readqueue = dev->readqueue->next;
				freepacket (p);
			}
		} else {
			while (dev->readqueue) {
				p = dev->readqueue;
				dev->readqueue = dev->readqueue->next;
				freepacket (p);
			}
		}

		ar = dev->ar;
		while (ar) {
			if (!ar->ready) {
				uaecptr request = ar->request;
				int command = get_word (request + 28);
				if (command == S2_ONLINE) {
					struct priv_s2devstruct *pdev = getps2devstruct (request);
					dev->packetsreceived = 0;
					dev->packetssent = 0;
					dev->baddata = 0;
					dev->overruns = 0;
					dev->unknowntypesreceived = 0;
					dev->reconfigurations = 0;
					if (pdev && pdev->timerbase) {
						m68k_areg (regs, 0) = pdev->tempbuf;
						CallLib (ctx, pdev->timerbase, -0x42); /* GetSysTime() */
					} else {
						put_long (pdev->tempbuf + 0, 0);
						put_long (pdev->tempbuf + 4, 0);
					}
					dev->online_secs = get_long (pdev->tempbuf + 0);
					dev->online_micro = get_long (pdev->tempbuf + 4);
					checkevents (dev, S2EVENT_ONLINE, 0);
					dev->online = 1;
					ar->ready = 1;
					write_comm_pipe_u32 (&dev->requests, request, 1);
					uaenet_vsync_requested--;
				} else if (command == CMD_FLUSH) {
					/* do not reply CMD_FLUSH until all other requests are gone */
					if (dev->ar->next == NULL) {
						if (log_net)
							write_log (_T("CMD_FLUSH replied %08x\n"), request);
						ar->ready = 1;
						write_comm_pipe_u32 (&dev->requests, request, 1);
						uaenet_vsync_requested--;
					} else {
						struct priv_s2devstruct *pdev = getps2devstruct (request);
						if (pdev) {
							dev->flush_timeout--;
							if (dev->flush_timeout <= 0) {
								dev->flush_timeout = FLUSH_TIMEOUT;
								if (dev->flush_timeout_cnt > 1)
									write_log (_T("WARNING: %s:%d CMD_FLUSH possibly frozen..\n"), getdevname(), pdev->unit);
								dev->flush_timeout_cnt++;
								flush (pdev);
							}
						}
					}
				}
			}
			ar = ar->next;
		}
	}
	if (uaenet_int_late)
		uaenet_int_requested = 1;
	else
		uaenet_int_requested = 0;
	uaenet_int_late = 0;
	uae_sem_post (&async_sem);
	return 0;
}