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