xref: /netbsd/games/atc/main.c (revision 7a2ed764)
1*7a2ed764Sdholland /*	$NetBSD: main.c,v 1.20 2009/08/12 04:48:03 dholland Exp $	*/
2101657d1Scgd 
361f28255Scgd /*-
4101657d1Scgd  * Copyright (c) 1990, 1993
5101657d1Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * This code is derived from software contributed to Berkeley by
861f28255Scgd  * Ed James.
961f28255Scgd  *
1061f28255Scgd  * Redistribution and use in source and binary forms, with or without
1161f28255Scgd  * modification, are permitted provided that the following conditions
1261f28255Scgd  * are met:
1361f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1461f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1561f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1661f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1761f28255Scgd  *    documentation and/or other materials provided with the distribution.
18e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1961f28255Scgd  *    may be used to endorse or promote products derived from this software
2061f28255Scgd  *    without specific prior written permission.
2161f28255Scgd  *
2261f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2361f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2461f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2561f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2661f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2761f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2861f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2961f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3061f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3161f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3261f28255Scgd  * SUCH DAMAGE.
3361f28255Scgd  */
3461f28255Scgd 
3561f28255Scgd /*
3661f28255Scgd  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
3761f28255Scgd  *
3861f28255Scgd  * Copy permission is hereby granted provided that this notice is
3961f28255Scgd  * retained on all partial or complete copies.
4061f28255Scgd  *
4161f28255Scgd  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
4261f28255Scgd  */
4361f28255Scgd 
44ca57cf90Slukem #include <sys/cdefs.h>
4561f28255Scgd #ifndef lint
462fe2731dSlukem __COPYRIGHT("@(#) Copyright (c) 1990, 1993\
472fe2731dSlukem  The Regents of the University of California.  All rights reserved.");
4861f28255Scgd #endif /* not lint */
4961f28255Scgd 
5061f28255Scgd #ifndef lint
51101657d1Scgd #if 0
52101657d1Scgd static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 5/31/93";
53101657d1Scgd #else
54*7a2ed764Sdholland __RCSID("$NetBSD: main.c,v 1.20 2009/08/12 04:48:03 dholland Exp $");
55101657d1Scgd #endif
5661f28255Scgd #endif /* not lint */
5761f28255Scgd 
5861f28255Scgd #include "include.h"
5961f28255Scgd #include "pathnames.h"
6061f28255Scgd 
61a3807f8fSchristos extern FILE	*yyin;
62ca57cf90Slukem 
63*7a2ed764Sdholland static int read_file(const char *);
64*7a2ed764Sdholland static const char *default_game(void);
65*7a2ed764Sdholland static const char *okay_game(const char *);
66*7a2ed764Sdholland static int list_games(void);
67*7a2ed764Sdholland 
68ca57cf90Slukem int
694931378aSjmc main(int argc, char *argv[])
7061f28255Scgd {
71d64494c7Sdholland 	unsigned long		seed;
7261f28255Scgd 	int			f_usage = 0, f_list = 0, f_showscore = 0;
7361f28255Scgd 	int			f_printpath = 0;
74a9d35e83Shubertf 	const char		*file = NULL;
75c5a4ae7aSmjl 	int			ch;
76ca2582cfSmycroft 	struct sigaction	sa;
7761f28255Scgd #ifdef BSD
7861f28255Scgd 	struct itimerval	itv;
7961f28255Scgd #endif
8061f28255Scgd 
81d5f85ed9Shubertf 	/* Open the score file then revoke setgid privileges */
82d5f85ed9Shubertf 	open_score_file();
83b0282a1eSrpaulo 	(void)setgid(getgid());
84d5f85ed9Shubertf 
85d64494c7Sdholland 	start_time = time(NULL);
86d64494c7Sdholland 	seed = start_time;
8761f28255Scgd 
88ca1e1e9cSjnemeth 	while ((ch = getopt(argc, argv, ":u?lstpg:f:r:")) != -1) {
89c5a4ae7aSmjl 		switch (ch) {
9061f28255Scgd 		case '?':
9161f28255Scgd 		case 'u':
92c5a4ae7aSmjl 		default:
9361f28255Scgd 			f_usage++;
9461f28255Scgd 			break;
9561f28255Scgd 		case 'l':
9661f28255Scgd 			f_list++;
9761f28255Scgd 			break;
9861f28255Scgd 		case 's':
9961f28255Scgd 		case 't':
10061f28255Scgd 			f_showscore++;
10161f28255Scgd 			break;
10261f28255Scgd 		case 'p':
10361f28255Scgd 			f_printpath++;
10461f28255Scgd 			break;
10561f28255Scgd 		case 'r':
106c5a4ae7aSmjl 			seed = atoi(optarg);
10761f28255Scgd 			break;
10861f28255Scgd 		case 'f':
10961f28255Scgd 		case 'g':
110c5a4ae7aSmjl 			file = optarg;
11161f28255Scgd 			break;
112c5a4ae7aSmjl 		}
113c5a4ae7aSmjl 	}
1144931378aSjmc 	if (optind < argc)
11561f28255Scgd 		f_usage++;
116d64494c7Sdholland 	srandom(seed);
11761f28255Scgd 
11861f28255Scgd 	if (f_usage)
119b0282a1eSrpaulo 		(void)fprintf(stderr,
12061f28255Scgd 		    "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
1214931378aSjmc 		    argv[0]);
12261f28255Scgd 	if (f_showscore)
123b0282a1eSrpaulo 		(void)log_score(1);
12461f28255Scgd 	if (f_list)
125b0282a1eSrpaulo 		(void)list_games();
12661f28255Scgd 	if (f_printpath) {
12761f28255Scgd 		char	buf[100];
12861f28255Scgd 
129ca1e1e9cSjnemeth 		(void)strlcpy(buf, _PATH_GAMES, 100);
130b0282a1eSrpaulo 		(void)puts(buf);
13161f28255Scgd 	}
13261f28255Scgd 
13361f28255Scgd 	if (f_usage || f_showscore || f_list || f_printpath)
13461f28255Scgd 		exit(0);
13561f28255Scgd 
13661f28255Scgd 	if (file == NULL)
13761f28255Scgd 		file = default_game();
13861f28255Scgd 	else
13961f28255Scgd 		file = okay_game(file);
14061f28255Scgd 
14161f28255Scgd 	if (file == NULL || read_file(file) < 0)
14261f28255Scgd 		exit(1);
14361f28255Scgd 
14461f28255Scgd 	init_gr();
14561f28255Scgd 	setup_screen(sp);
14661f28255Scgd 
147b0282a1eSrpaulo 	(void)addplane();
14861f28255Scgd 
149b0282a1eSrpaulo 	(void)signal(SIGINT, quit);
150b0282a1eSrpaulo 	(void)signal(SIGQUIT, quit);
15161f28255Scgd #ifdef BSD
152b0282a1eSrpaulo 	(void)signal(SIGTSTP, SIG_IGN);
15361f28255Scgd #endif
154b0282a1eSrpaulo 	(void)signal(SIGHUP, log_score_quit);
155b0282a1eSrpaulo 	(void)signal(SIGTERM, log_score_quit);
15661f28255Scgd 
157b0282a1eSrpaulo 	(void)tcgetattr(fileno(stdin), &tty_start);
158ca2582cfSmycroft 	tty_new = tty_start;
159ca2582cfSmycroft 	tty_new.c_lflag &= ~(ICANON|ECHO);
1600056c879Shubertf 	tty_new.c_iflag |= ICRNL;
16161f28255Scgd 	tty_new.c_cc[VMIN] = 1;
16261f28255Scgd 	tty_new.c_cc[VTIME] = 0;
163b0282a1eSrpaulo 	(void)tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
16461f28255Scgd 
165ca2582cfSmycroft 	sa.sa_handler = update;
166b0282a1eSrpaulo 	(void)sigemptyset(&sa.sa_mask);
167b0282a1eSrpaulo 	(void)sigaddset(&sa.sa_mask, SIGALRM);
168b0282a1eSrpaulo 	(void)sigaddset(&sa.sa_mask, SIGINT);
169ca2582cfSmycroft 	sa.sa_flags = 0;
170b0282a1eSrpaulo 	(void)sigaction(SIGALRM, &sa, (struct sigaction *)0);
17161f28255Scgd 
17261f28255Scgd #ifdef BSD
17361f28255Scgd 	itv.it_value.tv_sec = 0;
17461f28255Scgd 	itv.it_value.tv_usec = 1;
17561f28255Scgd 	itv.it_interval.tv_sec = sp->update_secs;
17661f28255Scgd 	itv.it_interval.tv_usec = 0;
177b0282a1eSrpaulo 	(void)setitimer(ITIMER_REAL, &itv, NULL);
17861f28255Scgd #endif
17961f28255Scgd #ifdef SYSV
18061f28255Scgd 	alarm(sp->update_secs);
18161f28255Scgd #endif
18261f28255Scgd 
18361f28255Scgd 	for (;;) {
18461f28255Scgd 		if (getcommand() != 1)
18561f28255Scgd 			planewin();
18661f28255Scgd 		else {
18761f28255Scgd #ifdef BSD
18861f28255Scgd 			itv.it_value.tv_sec = 0;
18961f28255Scgd 			itv.it_value.tv_usec = 0;
190b0282a1eSrpaulo 			(void)setitimer(ITIMER_REAL, &itv, NULL);
19161f28255Scgd #endif
19261f28255Scgd #ifdef SYSV
19361f28255Scgd 			alarm(0);
19461f28255Scgd #endif
19561f28255Scgd 
196ca57cf90Slukem 			update(0);
19761f28255Scgd 
19861f28255Scgd #ifdef BSD
19961f28255Scgd 			itv.it_value.tv_sec = sp->update_secs;
20061f28255Scgd 			itv.it_value.tv_usec = 0;
20161f28255Scgd 			itv.it_interval.tv_sec = sp->update_secs;
20261f28255Scgd 			itv.it_interval.tv_usec = 0;
203b0282a1eSrpaulo 			(void)setitimer(ITIMER_REAL, &itv, NULL);
20461f28255Scgd #endif
20561f28255Scgd #ifdef SYSV
20661f28255Scgd 			alarm(sp->update_secs);
20761f28255Scgd #endif
20861f28255Scgd 		}
20961f28255Scgd 	}
21061f28255Scgd }
21161f28255Scgd 
212*7a2ed764Sdholland static int
2134931378aSjmc read_file(const char *s)
21461f28255Scgd {
21561f28255Scgd 	int		retval;
21661f28255Scgd 
2174931378aSjmc 	filename = s;
21861f28255Scgd 	yyin = fopen(s, "r");
21961f28255Scgd 	if (yyin == NULL) {
22036b47bd3Slukem 		warn("fopen %s", s);
22161f28255Scgd 		return (-1);
22261f28255Scgd 	}
22361f28255Scgd 	retval = yyparse();
224b0282a1eSrpaulo 	(void)fclose(yyin);
22561f28255Scgd 
22661f28255Scgd 	if (retval != 0)
22761f28255Scgd 		return (-1);
22861f28255Scgd 	else
22961f28255Scgd 		return (0);
23061f28255Scgd }
23161f28255Scgd 
232*7a2ed764Sdholland static const char *
2334931378aSjmc default_game(void)
23461f28255Scgd {
23561f28255Scgd 	FILE		*fp;
23661f28255Scgd 	static char	file[256];
23761f28255Scgd 	char		line[256], games[256];
23861f28255Scgd 
239ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
240ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
24161f28255Scgd 
24261f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
24336b47bd3Slukem 		warn("fopen %s", games);
24461f28255Scgd 		return (NULL);
24561f28255Scgd 	}
24661f28255Scgd 	if (fgets(line, sizeof(line), fp) == NULL) {
247b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: no default game available\n", games);
248f09b76beSchristos 		fclose(fp);
24961f28255Scgd 		return (NULL);
25061f28255Scgd 	}
251b0282a1eSrpaulo 	(void)fclose(fp);
25261f28255Scgd 	line[strlen(line) - 1] = '\0';
253ca1e1e9cSjnemeth 	(void)strlcpy(file, _PATH_GAMES, 256);
254ca1e1e9cSjnemeth 	(void)strlcat(file, line, 256);
25561f28255Scgd 	return (file);
25661f28255Scgd }
25761f28255Scgd 
258*7a2ed764Sdholland static const char *
2594931378aSjmc okay_game(const char *s)
26061f28255Scgd {
26161f28255Scgd 	FILE		*fp;
26261f28255Scgd 	static char	file[256];
263a9d35e83Shubertf 	const char	*ret = NULL;
264a9d35e83Shubertf 	char		line[256], games[256];
26561f28255Scgd 
266ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
267ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
26861f28255Scgd 
26961f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
27036b47bd3Slukem 		warn("fopen %s", games);
27161f28255Scgd 		return (NULL);
27261f28255Scgd 	}
27361f28255Scgd 	while (fgets(line, sizeof(line), fp) != NULL) {
27461f28255Scgd 		line[strlen(line) - 1] = '\0';
27561f28255Scgd 		if (strcmp(s, line) == 0) {
276ca1e1e9cSjnemeth 			(void)strlcpy(file, _PATH_GAMES, 256);
277ca1e1e9cSjnemeth 			(void)strlcat(file, line, 256);
27861f28255Scgd 			ret = file;
27961f28255Scgd 			break;
28061f28255Scgd 		}
28161f28255Scgd 	}
282b0282a1eSrpaulo 	(void)fclose(fp);
28361f28255Scgd 	if (ret == NULL) {
28461f28255Scgd 		test_mode = 1;
28561f28255Scgd 		ret = s;
286b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: %s: game not found\n", games, s);
287b0282a1eSrpaulo 		(void)fprintf(stderr, "Your score will not be logged.\n");
288b0282a1eSrpaulo 		(void)sleep(2);	/* give the guy time to read it */
28961f28255Scgd 	}
29061f28255Scgd 	return (ret);
29161f28255Scgd }
29261f28255Scgd 
293*7a2ed764Sdholland static int
2944931378aSjmc list_games(void)
29561f28255Scgd {
29661f28255Scgd 	FILE		*fp;
29761f28255Scgd 	char		line[256], games[256];
29861f28255Scgd 	int		num_games = 0;
29961f28255Scgd 
300ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
301ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
30261f28255Scgd 
30361f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
30436b47bd3Slukem 		warn("fopen %s", games);
30561f28255Scgd 		return (-1);
30661f28255Scgd 	}
307b0282a1eSrpaulo 	(void)puts("available games:");
30861f28255Scgd 	while (fgets(line, sizeof(line), fp) != NULL) {
309b0282a1eSrpaulo 		(void)printf("	%s", line);
31061f28255Scgd 		num_games++;
31161f28255Scgd 	}
312b0282a1eSrpaulo 	(void)fclose(fp);
31361f28255Scgd 	if (num_games == 0) {
314b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: no games available\n", games);
31561f28255Scgd 		return (-1);
31661f28255Scgd 	}
31761f28255Scgd 	return (0);
31861f28255Scgd }
319