⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hunt.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Hunt *  Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold *  San Francisco, California */# include	<errno.h># if !defined(USE_CURSES) && defined(BSD_RELEASE) && BSD_RELEASE >= 44# include	<termios.h>static struct termios saved_tty;# endif# include	<curses.h># include	<string.h># include	"hunt.h"# include	<signal.h># include	<ctype.h># include	<sys/stat.h># include	<sys/time.h>/* * Some old versions of curses don't have these defined */# if !defined(cbreak) && (!defined(BSD_RELEASE) || BSD_RELEASE < 44)# define	cbreak()	crmode()# endif# if !defined(USE_CURSES) || !defined(TERMINFO)# define	beep()		(void) putchar(CTRL('G'))# endif# if !defined(USE_CURSES)# undef		refresh# define	refresh()	(void) fflush(stdout);# endif# ifdef USE_CURSES# define	clear_eol()	clrtoeol()# define	put_ch		addch# define	put_str		addstr# endif#if !defined(BSD_RELEASE) || BSD_RELEASE < 44extern int	_putchar();#endifFLAG	Last_player = FALSE;# ifdef MONITORFLAG	Am_monitor = FALSE;# endifchar	Buf[BUFSIZ];int	Socket;# ifdef INTERNETchar	*Sock_host;char	*use_port;FLAG	Query_driver = FALSE;char	*Send_message = NULL;FLAG	Show_scores = FALSE;# endifSOCKET	Daemon;# ifdef	INTERNET# define	DAEMON_SIZE	(sizeof Daemon)# else# define	DAEMON_SIZE	(sizeof Daemon - 1)# endifchar	map_key[256];			/* what to map keys to */FLAG	no_beep;static char	name[NAMELEN];static char	team = ' ';static int	in_visual;extern int	cur_row, cur_col;extern char	*tgoto();# ifdef INTERNETextern	SOCKET	*list_drivers();# endif/* * main: *	Main program for local process */main(ac, av)int	ac;char	**av;{	char		*term;	int		c;	extern int	errno;	extern int	Otto_mode;	extern int	optind;	extern char	*optarg;	long		enter_status;	SIGNAL_TYPE	intr(), sigterm(), sigemt(), tstp();	long		env_init(), quit();	enter_status = env_init((long) Q_CLOAK);	while ((c = getopt(ac, av, "Sbcfh:l:mn:op:qst:w:")) != EOF) {		switch (c) {		case 'l':	/* rsh compatibility */		case 'n':			(void) strncpy(name, optarg, NAMELEN);			break;		case 't':			team = *optarg;			if (!isdigit(team)) {				fprintf(stderr, "Team names must be numeric\n");				team = ' ';			}			break;		case 'o':# ifndef OTTO			fputs("The -o flag is reserved for future use.\n",				stderr);			goto usage;# else			Otto_mode = TRUE;			break;# endif		case 'm':# ifdef MONITOR			Am_monitor = TRUE;# else			fputs("The monitor was not compiled in.\n", stderr);# endif			break;# ifdef INTERNET		case 'S':			Show_scores = TRUE;			break;		case 'q':	/* query whether hunt is running */			Query_driver = TRUE;			break;		case 'w':			Send_message = optarg;			break;		case 'h':			Sock_host = optarg;			break;		case 'p':			use_port = optarg;			Test_port = atoi(use_port);			break;# else		case 'S':		case 'q':		case 'w':		case 'h':		case 'p':			fputs("Need TCP/IP for S, q, w, h, and p options.\n",				stderr);			break;# endif		case 'c':			enter_status = Q_CLOAK;			break;		case 'f':# ifdef FLY			enter_status = Q_FLY;# else			fputs("The flying code was not compiled in.\n", stderr);# endif			break;		case 's':			enter_status = Q_SCAN;			break;		case 'b':			no_beep = !no_beep;			break;		default:		usage:			fputs("usage:\thunt [-qmcsfS] [-n name] [-t team] [-p port] [-w message] [host]\n",			stderr);			exit(1);		}	}# ifdef INTERNET	if (optind + 1 < ac)		goto usage;	else if (optind + 1 == ac)		Sock_host = av[ac - 1];# else	if (optind > ac)		goto usage;# endif# ifdef INTERNET	if (Show_scores) {		SOCKET	*hosts;		for (hosts = list_drivers(); hosts->sin_port != 0; hosts += 1)			dump_scores(*hosts);		exit(0);	}	if (Query_driver) {		SOCKET	*hosts;		for (hosts = list_drivers(); hosts->sin_port != 0; hosts += 1) {			struct	hostent	*hp;			int	num_players;			hp = gethostbyaddr((char *) &hosts->sin_addr,					sizeof hosts->sin_addr, AF_INET);			num_players = ntohs(hosts->sin_port);			printf("%d player%s hunting on %s!\n",				num_players, (num_players == 1) ? "" : "s",				hp != NULL ? hp->h_name :				inet_ntoa(hosts->sin_addr));		}		exit(0);	}# endif# ifdef OTTO	if (Otto_mode)		(void) strncpy(name, "otto", NAMELEN);	else# endif	fill_in_blanks();	(void) fflush(stdout);	if (!isatty(0) || (term = getenv("TERM")) == NULL) {		fprintf(stderr, "no terminal type\n");		exit(1);	}# ifdef USE_CURSES	initscr();	(void) noecho();	(void) cbreak();# else /* !USE_CURSES */# if !defined(BSD_RELEASE) || BSD_RELEASE < 44	_tty_ch = 0;# endif	gettmode();	(void) setterm(term);	(void) noecho();	(void) cbreak();# if defined(BSD_RELEASE) && BSD_RELEASE >= 44	tcgetattr(0, &saved_tty);# endif	_puts(TI);	_puts(VS);# endif /* !USE_CURSES */	in_visual = TRUE;	if (LINES < SCREEN_HEIGHT || COLS < SCREEN_WIDTH)		leave(1, "Need a larger window");	clear_the_screen();	(void) signal(SIGINT, intr);	(void) signal(SIGTERM, sigterm);	(void) signal(SIGEMT, sigemt);	(void) signal(SIGPIPE, SIG_IGN);#if !defined(USE_CURSES) && defined(SIGTSTP)	(void) signal(SIGTSTP, tstp);#endif	for (;;) {# ifdef	INTERNET		find_driver(TRUE);		if (Daemon.sin_port == 0)			leave(1, "Game not found, try again");	jump_in:		do {			int	option;			Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);			if (Socket < 0) {				perror("socket");				exit(1);			}			option = 1;			if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK,			    &option, sizeof option) < 0)				perror("setsockopt loopback");			errno = 0;			if (connect(Socket, (struct sockaddr *) &Daemon,			    DAEMON_SIZE) < 0) {				if (errno != ECONNREFUSED) {					perror("connect");					leave(1, "connect");				}			}			else				break;			sleep(1);		} while (close(Socket) == 0);# else /* !INTERNET */		/*		 * set up a socket		 */		if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) {			perror("socket");			exit(1);		}		/*		 * attempt to connect the socket to a name; if it fails that		 * usually means that the driver isn't running, so we start		 * up the driver.		 */		Daemon.sun_family = SOCK_FAMILY;		(void) strcpy(Daemon.sun_path, Sock_name);		if (connect(Socket, &Daemon, DAEMON_SIZE) < 0) {			if (errno != ENOENT) {				perror("connect");				leave(1, "connect2");			}			start_driver();			do {				(void) close(Socket);				if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) {					perror("socket");					exit(1);				}				sleep(2);			} while (connect(Socket, &Daemon, DAEMON_SIZE) < 0);		}# endif		do_connect(name, team, enter_status);# ifdef INTERNET		if (Send_message != NULL) {			do_message();			if (enter_status == Q_MESSAGE)				break;			Send_message = NULL;			/* don't continue as that will call find_driver */			goto jump_in;		}# endif		playit();		if ((enter_status = quit(enter_status)) == Q_QUIT)			break;	}	leave(0, (char *) NULL);	/* NOTREACHED */}# ifdef INTERNET# ifdef BROADCASTbroadcast_vec(s, vector)	int			s;		/* socket */	struct	sockaddr	**vector;{	char			if_buf[BUFSIZ];	struct	ifconf		ifc;	struct	ifreq		*ifr;	unsigned int		n;	int			vec_cnt;	*vector = NULL;	ifc.ifc_len = sizeof if_buf;	ifc.ifc_buf = if_buf;	if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)		return 0;	vec_cnt = 0;	n = ifc.ifc_len / sizeof (struct ifreq);	*vector = (struct sockaddr *) malloc(n * sizeof (struct sockaddr));	for (ifr = ifc.ifc_req; n != 0; n--, ifr++)		if (ioctl(s, SIOCGIFBRDADDR, ifr) >= 0)			memcpy(&(*vector)[vec_cnt++], &ifr->ifr_addr,				sizeof (struct sockaddr));	return vec_cnt;}# endifSOCKET	*list_drivers(){	int			option;	u_short			msg;	u_short			port_num;	static SOCKET		test;	int			test_socket;	int			namelen;	char			local_name[256];	static			initial = TRUE;	static struct in_addr	local_address;	register struct hostent	*hp;	extern int		errno;# ifdef BROADCAST	static	int		brdc;	static	SOCKET		*brdv;# else	u_long			local_net;# endif	int			i;	static	SOCKET		*listv;	static	unsigned int	listmax;	unsigned int		listc;	int			mask;	struct timeval		wait;	if (initial) {			/* do one time initialization */# ifndef BROADCAST		sethostent(1);		/* don't bother to close host file */# endif		if (gethostname(local_name, sizeof local_name) < 0) {			leave(1, "Sorry, I have no name.");			/* NOTREACHED */		}		if ((hp = gethostbyname(local_name)) == NULL) {			leave(1, "Can't find myself.");			/* NOTREACHED */		}		local_address = * ((struct in_addr *) hp->h_addr);		listmax = 20;		listv = (SOCKET *) malloc(listmax * sizeof (SOCKET));	} else if (Sock_host != NULL)		return listv;		/* address already valid */	test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);	if (test_socket < 0) {		perror("socket");		leave(1, "socket system call failed");		/* NOTREACHED */	}	test.sin_family = SOCK_FAMILY;	test.sin_port = htons(Test_port);	listc = 0;	if (Sock_host != NULL) {	/* explicit host given */		if ((hp = gethostbyname(Sock_host)) == NULL) {			leave(1, "Unknown host");			/* NOTREACHED */		}		test.sin_addr = *((struct in_addr *) hp->h_addr);		goto test_one_host;	}	if (!initial) {		/* favor host of previous session by broadcasting to it first */		test.sin_addr = Daemon.sin_addr;		msg = htons(C_PLAYER);		/* Must be playing! */		(void) sendto(test_socket, (char *) &msg, sizeof msg, 0,		    (struct sockaddr *) &test, DAEMON_SIZE);	}# ifdef BROADCAST	if (initial)		brdc = broadcast_vec(test_socket, (struct sockaddr **) &brdv);	if (brdc <= 0) {		initial = FALSE;		test.sin_addr = local_address;		goto test_one_host;	}# ifdef SO_BROADCAST	/* Sun's will broadcast even though this option can't be set */	option = 1;	if (setsockopt(test_socket, SOL_SOCKET, SO_BROADCAST,	    &option, sizeof option) < 0) {		perror("setsockopt broadcast");		leave(1, "setsockopt broadcast");		/* NOTREACHED */	}# endif	/* send broadcast packets on all interfaces */	msg = htons(C_TESTMSG());	for (i = 0; i < brdc; i++) {		test.sin_addr = brdv[i].sin_addr;		if (sendto(test_socket, (char *) &msg, sizeof msg, 0,		    (struct sockaddr *) &test, DAEMON_SIZE) < 0) {			perror("sendto");			leave(1, "sendto");			/* NOTREACHED */		}	}# else /* !BROADCAST */	/* loop thru all hosts on local net and send msg to them. */	msg = htons(C_TESTMSG());	local_net = inet_netof(local_address);	sethostent(0);		/* rewind host file */	while (hp = gethostent()) {		if (local_net == inet_netof(* ((struct in_addr *) hp->h_addr))){			test.sin_addr = * ((struct in_addr *) hp->h_addr);			(void) sendto(test_socket, (char *) &msg, sizeof msg, 0,			    (struct sockaddr *) &test, DAEMON_SIZE);		}	}# endifget_response:	namelen = DAEMON_SIZE;	errno = 0;	wait.tv_sec = 1;	wait.tv_usec = 0;	for (;;) {		if (listc + 1 >= listmax) {			listmax += 20;			listv = (SOCKET *) realloc((char *) listv,						listmax * sizeof(SOCKET));		}		mask = 1 << test_socket;		if (select(test_socket + 1, &mask, NULL, NULL, &wait) == 1		&& recvfrom(test_socket, (char *) &port_num, sizeof port_num,			0, (struct sockaddr *) &listv[listc], &namelen) > 0) {			/*			 * Note that we do *not* convert from network to host			 * order since the port number *should* be in network			 * order:			 */			for (i = 0; i < listc; i += 1)				if (listv[listc].sin_addr.s_addr				== listv[i].sin_addr.s_addr)					break;			if (i == listc)				listv[listc++].sin_port = port_num;			continue;		}		if (errno != 0 && errno != EINTR) {			perror("select/recvfrom");			leave(1, "select/recvfrom");			/* NOTREACHED */		}		/* terminate list with local address */		listv[listc].sin_family = SOCK_FAMILY;		listv[listc].sin_addr = local_address;		listv[listc].sin_port = htons(0);		(void) close(test_socket);		initial = FALSE;		return listv;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -