xref: /netbsd-src/games/atc/main.c (revision 481fca6e59249d8ffcf24fef7cfbe7b131bfb080)
1 /*	$NetBSD: main.c,v 1.11 2000/05/08 07:56:01 mycroft Exp $	*/
2 
3 /*-
4  * Copyright (c) 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Ed James.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38 
39 /*
40  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
41  *
42  * Copy permission is hereby granted provided that this notice is
43  * retained on all partial or complete copies.
44  *
45  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
46  */
47 
48 #include <sys/cdefs.h>
49 #ifndef lint
50 __COPYRIGHT("@(#) Copyright (c) 1990, 1993\n\
51 	The Regents of the University of California.  All rights reserved.\n");
52 #endif /* not lint */
53 
54 #ifndef lint
55 #if 0
56 static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 5/31/93";
57 #else
58 __RCSID("$NetBSD: main.c,v 1.11 2000/05/08 07:56:01 mycroft Exp $");
59 #endif
60 #endif /* not lint */
61 
62 #include "include.h"
63 #include "pathnames.h"
64 
65 
66 int
67 main(ac, av)
68 	int	 ac;
69 	char	*av[];
70 {
71 	int			seed;
72 	int			f_usage = 0, f_list = 0, f_showscore = 0;
73 	int			f_printpath = 0;
74 	const char		*file = NULL;
75 	int			ch;
76 	struct sigaction	sa;
77 #ifdef BSD
78 	struct itimerval	itv;
79 #endif
80 
81 	/* Open the score file then revoke setgid privileges */
82 	open_score_file();
83 	setgid(getgid());
84 
85 	start_time = seed = time(NULL);
86 
87 	while ((ch = getopt(ac, av, "ulstpg:f:r:")) != -1) {
88 		switch (ch) {
89 		case '?':
90 		case 'u':
91 		default:
92 			f_usage++;
93 			break;
94 		case 'l':
95 			f_list++;
96 			break;
97 		case 's':
98 		case 't':
99 			f_showscore++;
100 			break;
101 		case 'p':
102 			f_printpath++;
103 			break;
104 		case 'r':
105 			seed = atoi(optarg);
106 			break;
107 		case 'f':
108 		case 'g':
109 			file = optarg;
110 			break;
111 		}
112 	}
113 	if (optind < ac)
114 		f_usage++;
115 	srandom(seed);
116 
117 	if (f_usage)
118 		fprintf(stderr,
119 		    "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
120 			av[0]);
121 	if (f_showscore)
122 		log_score(1);
123 	if (f_list)
124 		list_games();
125 	if (f_printpath) {
126 		char	buf[100];
127 
128 		strcpy(buf, _PATH_GAMES);
129 		buf[strlen(buf) - 1] = '\0';
130 		puts(buf);
131 	}
132 
133 	if (f_usage || f_showscore || f_list || f_printpath)
134 		exit(0);
135 
136 	if (file == NULL)
137 		file = default_game();
138 	else
139 		file = okay_game(file);
140 
141 	if (file == NULL || read_file(file) < 0)
142 		exit(1);
143 
144 	init_gr();
145 	setup_screen(sp);
146 
147 	addplane();
148 
149 	signal(SIGINT, quit);
150 	signal(SIGQUIT, quit);
151 #ifdef BSD
152 	signal(SIGTSTP, SIG_IGN);
153 	signal(SIGSTOP, SIG_IGN);
154 #endif
155 	signal(SIGHUP, log_score_quit);
156 	signal(SIGTERM, log_score_quit);
157 
158 	tcgetattr(fileno(stdin), &tty_start);
159 	tty_new = tty_start;
160 	tty_new.c_lflag &= ~(ICANON|ECHO);
161 	tty_new.c_iflag |= ICRNL;
162 	tty_new.c_cc[VMIN] = 1;
163 	tty_new.c_cc[VTIME] = 0;
164 	tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
165 
166 	sa.sa_handler = update;
167 	sigemptyset(&sa.sa_mask);
168 	sigaddset(&sa.sa_mask, SIGALRM);
169 	sigaddset(&sa.sa_mask, SIGINT);
170 	sa.sa_flags = 0;
171 	sigaction(SIGALRM, &sa, (struct sigaction *)0);
172 
173 #ifdef BSD
174 	itv.it_value.tv_sec = 0;
175 	itv.it_value.tv_usec = 1;
176 	itv.it_interval.tv_sec = sp->update_secs;
177 	itv.it_interval.tv_usec = 0;
178 	setitimer(ITIMER_REAL, &itv, NULL);
179 #endif
180 #ifdef SYSV
181 	alarm(sp->update_secs);
182 #endif
183 
184 	for (;;) {
185 		if (getcommand() != 1)
186 			planewin();
187 		else {
188 #ifdef BSD
189 			itv.it_value.tv_sec = 0;
190 			itv.it_value.tv_usec = 0;
191 			setitimer(ITIMER_REAL, &itv, NULL);
192 #endif
193 #ifdef SYSV
194 			alarm(0);
195 #endif
196 
197 			update(0);
198 
199 #ifdef BSD
200 			itv.it_value.tv_sec = sp->update_secs;
201 			itv.it_value.tv_usec = 0;
202 			itv.it_interval.tv_sec = sp->update_secs;
203 			itv.it_interval.tv_usec = 0;
204 			setitimer(ITIMER_REAL, &itv, NULL);
205 #endif
206 #ifdef SYSV
207 			alarm(sp->update_secs);
208 #endif
209 		}
210 	}
211 }
212 
213 int
214 read_file(s)
215 	const char	*s;
216 {
217 	extern FILE	*yyin;
218 	int		retval;
219 
220 	file = s;
221 	yyin = fopen(s, "r");
222 	if (yyin == NULL) {
223 		warn("fopen %s", s);
224 		return (-1);
225 	}
226 	retval = yyparse();
227 	fclose(yyin);
228 
229 	if (retval != 0)
230 		return (-1);
231 	else
232 		return (0);
233 }
234 
235 const char	*
236 default_game()
237 {
238 	FILE		*fp;
239 	static char	file[256];
240 	char		line[256], games[256];
241 
242 	strcpy(games, _PATH_GAMES);
243 	strcat(games, GAMES);
244 
245 	if ((fp = fopen(games, "r")) == NULL) {
246 		warn("fopen %s", games);
247 		return (NULL);
248 	}
249 	if (fgets(line, sizeof(line), fp) == NULL) {
250 		fprintf(stderr, "%s: no default game available\n", games);
251 		return (NULL);
252 	}
253 	fclose(fp);
254 	line[strlen(line) - 1] = '\0';
255 	strcpy(file, _PATH_GAMES);
256 	strcat(file, line);
257 	return (file);
258 }
259 
260 const char	*
261 okay_game(s)
262 	const char	*s;
263 {
264 	FILE		*fp;
265 	static char	file[256];
266 	const char	*ret = NULL;
267 	char		line[256], games[256];
268 
269 	strcpy(games, _PATH_GAMES);
270 	strcat(games, GAMES);
271 
272 	if ((fp = fopen(games, "r")) == NULL) {
273 		warn("fopen %s", games);
274 		return (NULL);
275 	}
276 	while (fgets(line, sizeof(line), fp) != NULL) {
277 		line[strlen(line) - 1] = '\0';
278 		if (strcmp(s, line) == 0) {
279 			strcpy(file, _PATH_GAMES);
280 			strcat(file, line);
281 			ret = file;
282 			break;
283 		}
284 	}
285 	fclose(fp);
286 	if (ret == NULL) {
287 		test_mode = 1;
288 		ret = s;
289 		fprintf(stderr, "%s: %s: game not found\n", games, s);
290 		fprintf(stderr, "Your score will not be logged.\n");
291 		sleep(2);	/* give the guy time to read it */
292 	}
293 	return (ret);
294 }
295 
296 int
297 list_games()
298 {
299 	FILE		*fp;
300 	char		line[256], games[256];
301 	int		num_games = 0;
302 
303 	strcpy(games, _PATH_GAMES);
304 	strcat(games, GAMES);
305 
306 	if ((fp = fopen(games, "r")) == NULL) {
307 		warn("fopen %s", games);
308 		return (-1);
309 	}
310 	puts("available games:");
311 	while (fgets(line, sizeof(line), fp) != NULL) {
312 		printf("	%s", line);
313 		num_games++;
314 	}
315 	fclose(fp);
316 	if (num_games == 0) {
317 		fprintf(stderr, "%s: no games available\n", games);
318 		return (-1);
319 	}
320 	return (0);
321 }
322