xref: /netbsd-src/games/atc/main.c (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: main.c,v 1.12 2001/02/05 00:22:52 christos 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.12 2001/02/05 00:22:52 christos Exp $");
59 #endif
60 #endif /* not lint */
61 
62 #include "include.h"
63 #include "pathnames.h"
64 
65 extern FILE	*yyin;
66 
67 int
68 main(ac, av)
69 	int	 ac;
70 	char	*av[];
71 {
72 	int			seed;
73 	int			f_usage = 0, f_list = 0, f_showscore = 0;
74 	int			f_printpath = 0;
75 	const char		*file = NULL;
76 	int			ch;
77 	struct sigaction	sa;
78 #ifdef BSD
79 	struct itimerval	itv;
80 #endif
81 
82 	/* Open the score file then revoke setgid privileges */
83 	open_score_file();
84 	setgid(getgid());
85 
86 	start_time = seed = time(NULL);
87 
88 	while ((ch = getopt(ac, av, "ulstpg:f:r:")) != -1) {
89 		switch (ch) {
90 		case '?':
91 		case 'u':
92 		default:
93 			f_usage++;
94 			break;
95 		case 'l':
96 			f_list++;
97 			break;
98 		case 's':
99 		case 't':
100 			f_showscore++;
101 			break;
102 		case 'p':
103 			f_printpath++;
104 			break;
105 		case 'r':
106 			seed = atoi(optarg);
107 			break;
108 		case 'f':
109 		case 'g':
110 			file = optarg;
111 			break;
112 		}
113 	}
114 	if (optind < ac)
115 		f_usage++;
116 	srandom(seed);
117 
118 	if (f_usage)
119 		fprintf(stderr,
120 		    "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
121 			av[0]);
122 	if (f_showscore)
123 		log_score(1);
124 	if (f_list)
125 		list_games();
126 	if (f_printpath) {
127 		char	buf[100];
128 
129 		strcpy(buf, _PATH_GAMES);
130 		buf[strlen(buf) - 1] = '\0';
131 		puts(buf);
132 	}
133 
134 	if (f_usage || f_showscore || f_list || f_printpath)
135 		exit(0);
136 
137 	if (file == NULL)
138 		file = default_game();
139 	else
140 		file = okay_game(file);
141 
142 	if (file == NULL || read_file(file) < 0)
143 		exit(1);
144 
145 	init_gr();
146 	setup_screen(sp);
147 
148 	addplane();
149 
150 	signal(SIGINT, quit);
151 	signal(SIGQUIT, quit);
152 #ifdef BSD
153 	signal(SIGTSTP, SIG_IGN);
154 	signal(SIGSTOP, SIG_IGN);
155 #endif
156 	signal(SIGHUP, log_score_quit);
157 	signal(SIGTERM, log_score_quit);
158 
159 	tcgetattr(fileno(stdin), &tty_start);
160 	tty_new = tty_start;
161 	tty_new.c_lflag &= ~(ICANON|ECHO);
162 	tty_new.c_iflag |= ICRNL;
163 	tty_new.c_cc[VMIN] = 1;
164 	tty_new.c_cc[VTIME] = 0;
165 	tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
166 
167 	sa.sa_handler = update;
168 	sigemptyset(&sa.sa_mask);
169 	sigaddset(&sa.sa_mask, SIGALRM);
170 	sigaddset(&sa.sa_mask, SIGINT);
171 	sa.sa_flags = 0;
172 	sigaction(SIGALRM, &sa, (struct sigaction *)0);
173 
174 #ifdef BSD
175 	itv.it_value.tv_sec = 0;
176 	itv.it_value.tv_usec = 1;
177 	itv.it_interval.tv_sec = sp->update_secs;
178 	itv.it_interval.tv_usec = 0;
179 	setitimer(ITIMER_REAL, &itv, NULL);
180 #endif
181 #ifdef SYSV
182 	alarm(sp->update_secs);
183 #endif
184 
185 	for (;;) {
186 		if (getcommand() != 1)
187 			planewin();
188 		else {
189 #ifdef BSD
190 			itv.it_value.tv_sec = 0;
191 			itv.it_value.tv_usec = 0;
192 			setitimer(ITIMER_REAL, &itv, NULL);
193 #endif
194 #ifdef SYSV
195 			alarm(0);
196 #endif
197 
198 			update(0);
199 
200 #ifdef BSD
201 			itv.it_value.tv_sec = sp->update_secs;
202 			itv.it_value.tv_usec = 0;
203 			itv.it_interval.tv_sec = sp->update_secs;
204 			itv.it_interval.tv_usec = 0;
205 			setitimer(ITIMER_REAL, &itv, NULL);
206 #endif
207 #ifdef SYSV
208 			alarm(sp->update_secs);
209 #endif
210 		}
211 	}
212 }
213 
214 int
215 read_file(s)
216 	const char	*s;
217 {
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