xref: /netbsd/games/atc/main.c (revision abca1099)
1*abca1099Srillig /*	$NetBSD: main.c,v 1.25 2021/05/02 12:50:43 rillig 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*abca1099Srillig __RCSID("$NetBSD: main.c,v 1.25 2021/05/02 12:50:43 rillig Exp $");
55101657d1Scgd #endif
5661f28255Scgd #endif /* not lint */
5761f28255Scgd 
58220f2cd3Sdholland #include <stdio.h>
59220f2cd3Sdholland #include <stdlib.h>
60220f2cd3Sdholland #include <string.h>
61220f2cd3Sdholland #include <signal.h>
62220f2cd3Sdholland #include <termios.h>
63220f2cd3Sdholland #include <getopt.h>
64220f2cd3Sdholland #include <err.h>
65220f2cd3Sdholland 
6661f28255Scgd #include "pathnames.h"
67220f2cd3Sdholland #include "def.h"
68220f2cd3Sdholland #include "struct.h"
69220f2cd3Sdholland #include "extern.h"
70220f2cd3Sdholland #include "tunable.h"
7161f28255Scgd 
72a3807f8fSchristos extern FILE	*yyin;
73ca57cf90Slukem 
747a2ed764Sdholland static int read_file(const char *);
757a2ed764Sdholland static const char *default_game(void);
767a2ed764Sdholland static const char *okay_game(const char *);
777a2ed764Sdholland static int list_games(void);
7833e21aacSdholland static void quit(int);
797a2ed764Sdholland 
80ca57cf90Slukem int
main(int argc,char * argv[])814931378aSjmc main(int argc, char *argv[])
8261f28255Scgd {
83d64494c7Sdholland 	unsigned long		seed;
8461f28255Scgd 	int			f_usage = 0, f_list = 0, f_showscore = 0;
8561f28255Scgd 	int			f_printpath = 0;
86a9d35e83Shubertf 	const char		*file = NULL;
87c5a4ae7aSmjl 	int			ch;
88ca2582cfSmycroft 	struct sigaction	sa;
8961f28255Scgd #ifdef BSD
9061f28255Scgd 	struct itimerval	itv;
9161f28255Scgd #endif
9261f28255Scgd 
93d5f85ed9Shubertf 	/* Open the score file then revoke setgid privileges */
94d5f85ed9Shubertf 	open_score_file();
95b0282a1eSrpaulo 	(void)setgid(getgid());
96d5f85ed9Shubertf 
97d64494c7Sdholland 	start_time = time(NULL);
98d64494c7Sdholland 	seed = start_time;
9961f28255Scgd 
100ca1e1e9cSjnemeth 	while ((ch = getopt(argc, argv, ":u?lstpg:f:r:")) != -1) {
101c5a4ae7aSmjl 		switch (ch) {
10261f28255Scgd 		case '?':
10361f28255Scgd 		case 'u':
104c5a4ae7aSmjl 		default:
105ac6377faSdholland 			f_usage = 1;
10661f28255Scgd 			break;
10761f28255Scgd 		case 'l':
108ac6377faSdholland 			f_list = 1;
10961f28255Scgd 			break;
11061f28255Scgd 		case 's':
11161f28255Scgd 		case 't':
112ac6377faSdholland 			f_showscore = 1;
11361f28255Scgd 			break;
11461f28255Scgd 		case 'p':
115ac6377faSdholland 			f_printpath = 1;
11661f28255Scgd 			break;
11761f28255Scgd 		case 'r':
118c5a4ae7aSmjl 			seed = atoi(optarg);
11961f28255Scgd 			break;
12061f28255Scgd 		case 'f':
12161f28255Scgd 		case 'g':
122c5a4ae7aSmjl 			file = optarg;
12361f28255Scgd 			break;
124c5a4ae7aSmjl 		}
125c5a4ae7aSmjl 	}
1264931378aSjmc 	if (optind < argc)
127ac6377faSdholland 		f_usage = 1;
128d64494c7Sdholland 	srandom(seed);
12961f28255Scgd 
13061f28255Scgd 	if (f_usage)
131b0282a1eSrpaulo 		(void)fprintf(stderr,
13261f28255Scgd 		    "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
1334931378aSjmc 		    argv[0]);
13461f28255Scgd 	if (f_showscore)
135b0282a1eSrpaulo 		(void)log_score(1);
13661f28255Scgd 	if (f_list)
137b0282a1eSrpaulo 		(void)list_games();
13861f28255Scgd 	if (f_printpath) {
13961f28255Scgd 		char	buf[100];
14061f28255Scgd 
141ca1e1e9cSjnemeth 		(void)strlcpy(buf, _PATH_GAMES, 100);
142b0282a1eSrpaulo 		(void)puts(buf);
14361f28255Scgd 	}
14461f28255Scgd 
14561f28255Scgd 	if (f_usage || f_showscore || f_list || f_printpath)
14661f28255Scgd 		exit(0);
14761f28255Scgd 
14861f28255Scgd 	if (file == NULL)
14961f28255Scgd 		file = default_game();
15061f28255Scgd 	else
15161f28255Scgd 		file = okay_game(file);
15261f28255Scgd 
15361f28255Scgd 	if (file == NULL || read_file(file) < 0)
15461f28255Scgd 		exit(1);
15561f28255Scgd 
15661f28255Scgd 	init_gr();
15761f28255Scgd 	setup_screen(sp);
15861f28255Scgd 
159ebb2bc86Sdholland 	addplane();
16061f28255Scgd 
161b0282a1eSrpaulo 	(void)signal(SIGINT, quit);
162b0282a1eSrpaulo 	(void)signal(SIGQUIT, quit);
16361f28255Scgd #ifdef BSD
164b0282a1eSrpaulo 	(void)signal(SIGTSTP, SIG_IGN);
16561f28255Scgd #endif
166b0282a1eSrpaulo 	(void)signal(SIGHUP, log_score_quit);
167b0282a1eSrpaulo 	(void)signal(SIGTERM, log_score_quit);
16861f28255Scgd 
169b0282a1eSrpaulo 	(void)tcgetattr(fileno(stdin), &tty_start);
170ca2582cfSmycroft 	tty_new = tty_start;
171ca2582cfSmycroft 	tty_new.c_lflag &= ~(ICANON|ECHO);
1720056c879Shubertf 	tty_new.c_iflag |= ICRNL;
17361f28255Scgd 	tty_new.c_cc[VMIN] = 1;
17461f28255Scgd 	tty_new.c_cc[VTIME] = 0;
175b0282a1eSrpaulo 	(void)tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
17661f28255Scgd 
177ca2582cfSmycroft 	sa.sa_handler = update;
178b0282a1eSrpaulo 	(void)sigemptyset(&sa.sa_mask);
179b0282a1eSrpaulo 	(void)sigaddset(&sa.sa_mask, SIGALRM);
180b0282a1eSrpaulo 	(void)sigaddset(&sa.sa_mask, SIGINT);
181ca2582cfSmycroft 	sa.sa_flags = 0;
182b0282a1eSrpaulo 	(void)sigaction(SIGALRM, &sa, (struct sigaction *)0);
18361f28255Scgd 
18461f28255Scgd #ifdef BSD
18561f28255Scgd 	itv.it_value.tv_sec = 0;
18661f28255Scgd 	itv.it_value.tv_usec = 1;
18761f28255Scgd 	itv.it_interval.tv_sec = sp->update_secs;
18861f28255Scgd 	itv.it_interval.tv_usec = 0;
189b0282a1eSrpaulo 	(void)setitimer(ITIMER_REAL, &itv, NULL);
19061f28255Scgd #endif
19161f28255Scgd #ifdef SYSV
19261f28255Scgd 	alarm(sp->update_secs);
19361f28255Scgd #endif
19461f28255Scgd 
19561f28255Scgd 	for (;;) {
19661f28255Scgd 		if (getcommand() != 1)
19761f28255Scgd 			planewin();
19861f28255Scgd 		else {
19961f28255Scgd #ifdef BSD
20061f28255Scgd 			itv.it_value.tv_sec = 0;
20161f28255Scgd 			itv.it_value.tv_usec = 0;
202b0282a1eSrpaulo 			(void)setitimer(ITIMER_REAL, &itv, NULL);
20361f28255Scgd #endif
20461f28255Scgd #ifdef SYSV
20561f28255Scgd 			alarm(0);
20661f28255Scgd #endif
20761f28255Scgd 
208ca57cf90Slukem 			update(0);
20961f28255Scgd 
21061f28255Scgd #ifdef BSD
21161f28255Scgd 			itv.it_value.tv_sec = sp->update_secs;
21261f28255Scgd 			itv.it_value.tv_usec = 0;
21361f28255Scgd 			itv.it_interval.tv_sec = sp->update_secs;
21461f28255Scgd 			itv.it_interval.tv_usec = 0;
215b0282a1eSrpaulo 			(void)setitimer(ITIMER_REAL, &itv, NULL);
21661f28255Scgd #endif
21761f28255Scgd #ifdef SYSV
21861f28255Scgd 			alarm(sp->update_secs);
21961f28255Scgd #endif
22061f28255Scgd 		}
22161f28255Scgd 	}
22261f28255Scgd }
22361f28255Scgd 
2247a2ed764Sdholland static int
read_file(const char * s)2254931378aSjmc read_file(const char *s)
22661f28255Scgd {
22761f28255Scgd 	int		retval;
22861f28255Scgd 
2294931378aSjmc 	filename = s;
23061f28255Scgd 	yyin = fopen(s, "r");
23161f28255Scgd 	if (yyin == NULL) {
23236b47bd3Slukem 		warn("fopen %s", s);
23361f28255Scgd 		return (-1);
23461f28255Scgd 	}
23561f28255Scgd 	retval = yyparse();
236b0282a1eSrpaulo 	(void)fclose(yyin);
23761f28255Scgd 
23861f28255Scgd 	if (retval != 0)
23961f28255Scgd 		return (-1);
24061f28255Scgd 	else
24161f28255Scgd 		return (0);
24261f28255Scgd }
24361f28255Scgd 
2447a2ed764Sdholland static const char *
default_game(void)2454931378aSjmc default_game(void)
24661f28255Scgd {
24761f28255Scgd 	FILE		*fp;
24861f28255Scgd 	static char	file[256];
24961f28255Scgd 	char		line[256], games[256];
25061f28255Scgd 
251ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
252ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
25361f28255Scgd 
25461f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
25536b47bd3Slukem 		warn("fopen %s", games);
25661f28255Scgd 		return (NULL);
25761f28255Scgd 	}
25861f28255Scgd 	if (fgets(line, sizeof(line), fp) == NULL) {
259b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: no default game available\n", games);
260f09b76beSchristos 		fclose(fp);
26161f28255Scgd 		return (NULL);
26261f28255Scgd 	}
263b0282a1eSrpaulo 	(void)fclose(fp);
26461f28255Scgd 	line[strlen(line) - 1] = '\0';
265ca1e1e9cSjnemeth 	(void)strlcpy(file, _PATH_GAMES, 256);
266ca1e1e9cSjnemeth 	(void)strlcat(file, line, 256);
26761f28255Scgd 	return (file);
26861f28255Scgd }
26961f28255Scgd 
2707a2ed764Sdholland static const char *
okay_game(const char * s)2714931378aSjmc okay_game(const char *s)
27261f28255Scgd {
27361f28255Scgd 	FILE		*fp;
27461f28255Scgd 	static char	file[256];
275a9d35e83Shubertf 	const char	*ret = NULL;
276a9d35e83Shubertf 	char		line[256], games[256];
27761f28255Scgd 
278ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
279ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
28061f28255Scgd 
28161f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
28236b47bd3Slukem 		warn("fopen %s", games);
28361f28255Scgd 		return (NULL);
28461f28255Scgd 	}
28561f28255Scgd 	while (fgets(line, sizeof(line), fp) != NULL) {
28661f28255Scgd 		line[strlen(line) - 1] = '\0';
28761f28255Scgd 		if (strcmp(s, line) == 0) {
288ca1e1e9cSjnemeth 			(void)strlcpy(file, _PATH_GAMES, 256);
289ca1e1e9cSjnemeth 			(void)strlcat(file, line, 256);
29061f28255Scgd 			ret = file;
29161f28255Scgd 			break;
29261f28255Scgd 		}
29361f28255Scgd 	}
294b0282a1eSrpaulo 	(void)fclose(fp);
29561f28255Scgd 	if (ret == NULL) {
29661f28255Scgd 		test_mode = 1;
29761f28255Scgd 		ret = s;
298b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: %s: game not found\n", games, s);
299b0282a1eSrpaulo 		(void)fprintf(stderr, "Your score will not be logged.\n");
300b0282a1eSrpaulo 		(void)sleep(2);	/* give the guy time to read it */
30161f28255Scgd 	}
30261f28255Scgd 	return (ret);
30361f28255Scgd }
30461f28255Scgd 
3057a2ed764Sdholland static int
list_games(void)3064931378aSjmc list_games(void)
30761f28255Scgd {
30861f28255Scgd 	FILE		*fp;
30961f28255Scgd 	char		line[256], games[256];
31061f28255Scgd 	int		num_games = 0;
31161f28255Scgd 
312ca1e1e9cSjnemeth 	(void)strlcpy(games, _PATH_GAMES, 256);
313ca1e1e9cSjnemeth 	(void)strlcat(games, GAMES, 256);
31461f28255Scgd 
31561f28255Scgd 	if ((fp = fopen(games, "r")) == NULL) {
31636b47bd3Slukem 		warn("fopen %s", games);
31761f28255Scgd 		return (-1);
31861f28255Scgd 	}
319b0282a1eSrpaulo 	(void)puts("available games:");
32061f28255Scgd 	while (fgets(line, sizeof(line), fp) != NULL) {
321b0282a1eSrpaulo 		(void)printf("	%s", line);
32261f28255Scgd 		num_games++;
32361f28255Scgd 	}
324b0282a1eSrpaulo 	(void)fclose(fp);
32561f28255Scgd 	if (num_games == 0) {
326b0282a1eSrpaulo 		(void)fprintf(stderr, "%s: no games available\n", games);
32761f28255Scgd 		return (-1);
32861f28255Scgd 	}
32961f28255Scgd 	return (0);
33061f28255Scgd }
33133e21aacSdholland 
33233e21aacSdholland /* ARGSUSED */
33333e21aacSdholland static void
quit(int dummy __unused)33433e21aacSdholland quit(int dummy __unused)
33533e21aacSdholland {
33633e21aacSdholland 	int c;
33733e21aacSdholland #ifdef BSD
33833e21aacSdholland 	struct itimerval	itv;
33933e21aacSdholland #endif
34033e21aacSdholland 	ioaskquit();
34133e21aacSdholland 	c = getAChar();
34233e21aacSdholland 	if (c == EOF || c == 'y') {
34333e21aacSdholland 		/* disable timer */
34433e21aacSdholland #ifdef BSD
34533e21aacSdholland 		itv.it_value.tv_sec = 0;
34633e21aacSdholland 		itv.it_value.tv_usec = 0;
34733e21aacSdholland 		(void)setitimer(ITIMER_REAL, &itv, NULL);
34833e21aacSdholland #endif
34933e21aacSdholland #ifdef SYSV
35033e21aacSdholland 		alarm(0);
35133e21aacSdholland #endif
35233e21aacSdholland 		shutdown_gr();
35333e21aacSdholland 		(void)log_score(0);
35433e21aacSdholland 		exit(0);
35533e21aacSdholland 	}
35633e21aacSdholland 	ionoquit();
35733e21aacSdholland }
358