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