Initial import from FreeBSD RELENG_4:
[games.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. 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
37 /*
38  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
39  *
40  * Copy permission is hereby granted provided that this notice is
41  * retained on all partial or complete copies.
42  *
43  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
44  */
45
46 #ifndef lint
47 static const char copyright[] =
48 "@(#) Copyright (c) 1990, 1993\n\
49         The Regents of the University of California.  All rights reserved.\n";
50 #endif /* not lint */
51
52 #ifndef lint
53 #if 0
54 static char sccsid[] = "@(#)main.c      8.1 (Berkeley) 5/31/93";
55 #endif
56 static const char rcsid[] =
57  "$FreeBSD: src/games/atc/main.c,v 1.9 1999/11/30 03:48:21 billf Exp $";
58 #endif /* not lint */
59
60 #include <string.h>
61 #include "include.h"
62 #include "pathnames.h"
63
64 main(ac, av)
65         int     ac;
66         char    *av[];
67 {
68         int                     seed = 0;
69         int                     f_usage = 0, f_list = 0, f_showscore = 0;
70         int                     f_printpath = 0;
71         const char              *file = NULL;
72         char                    *name, *ptr;
73 #ifdef BSD
74         struct itimerval        itv;
75 #endif
76         extern const char       *default_game(), *okay_game();
77         extern void             log_score(), quit(), update();
78
79         /* Open the score file then revoke setgid privileges */
80         open_score_file();
81         setregid(getgid(), getgid());
82
83         start_time = time(0);
84
85         name = *av++;
86         while (*av) {
87 #ifndef SAVEDASH
88                 if (**av == '-')
89                         *++*av;
90                 else
91                         break;
92 #endif
93                 ptr = *av++;
94                 while (*ptr) {
95                         switch (*ptr) {
96                         case '?':
97                         case 'u':
98                                 f_usage++;
99                                 break;
100                         case 'l':
101                                 f_list++;
102                                 break;
103                         case 's':
104                         case 't':
105                                 f_showscore++;
106                                 break;
107                         case 'p':
108                                 f_printpath++;
109                                 break;
110                         case 'r':
111                                 srandom(atoi(*av));
112                                 seed = 1;
113                                 av++;
114                                 break;
115                         case 'f':
116                         case 'g':
117                                 file = *av;
118                                 av++;
119                                 break;
120                         default:
121                                 fprintf(stderr, "Unknown option '%c'\n", *ptr);
122                                 f_usage++;
123                                 break;
124                         }
125                         ptr++;
126                 }
127         }
128         if (!seed)
129                 srandomdev();
130
131         if (f_usage)
132                 fprintf(stderr,
133                     "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
134                         name);
135         if (f_showscore)
136                 log_score(1);
137         if (f_list)
138                 list_games();
139         if (f_printpath) {
140                 char    buf[100];
141
142                 strcpy(buf, _PATH_GAMES);
143                 buf[strlen(buf) - 1] = '\0';
144                 puts(buf);
145         }
146
147         if (f_usage || f_showscore || f_list || f_printpath)
148                 exit(0);
149
150         if (file == NULL)
151                 file = default_game();
152         else
153                 file = okay_game(file);
154
155         if (file == NULL || read_file(file) < 0)
156                 exit(1);
157
158         init_gr();
159         setup_screen(sp);
160
161         addplane();
162
163         signal(SIGINT, quit);
164         signal(SIGQUIT, quit);
165 #ifdef BSD
166         signal(SIGTSTP, SIG_IGN);
167         signal(SIGSTOP, SIG_IGN);
168 #endif
169         signal(SIGHUP, log_score);
170         signal(SIGTERM, log_score);
171
172 #ifdef BSD
173         ioctl(fileno(stdin), TIOCGETP, &tty_start);
174         bcopy(&tty_start, &tty_new, sizeof(tty_new));
175         tty_new.sg_flags |= CBREAK;
176         tty_new.sg_flags &= ~ECHO;
177         ioctl(fileno(stdin), TIOCSETP, &tty_new);
178 #endif
179
180 #ifdef SYSV
181         ioctl(fileno(stdin), TCGETA, &tty_start);
182         bcopy(&tty_start, &tty_new, sizeof(tty_new));
183         tty_new.c_lflag &= ~ICANON;
184         tty_new.c_lflag &= ~ECHO;
185         tty_new.c_cc[VMIN] = 1;
186         tty_new.c_cc[VTIME] = 0;
187         ioctl(fileno(stdin), TCSETAW, &tty_new);
188 #endif
189
190         signal(SIGALRM, update);
191
192 #ifdef BSD
193         itv.it_value.tv_sec = 0;
194         itv.it_value.tv_usec = 1;
195         itv.it_interval.tv_sec = sp->update_secs;
196         itv.it_interval.tv_usec = 0;
197         setitimer(ITIMER_REAL, &itv, NULL);
198 #endif
199 #ifdef SYSV
200         alarm(sp->update_secs);
201 #endif
202
203         for (;;) {
204                 if (getcommand() != 1)
205                         planewin();
206                 else {
207 #ifdef BSD
208                         itv.it_value.tv_sec = 0;
209                         itv.it_value.tv_usec = 0;
210                         setitimer(ITIMER_REAL, &itv, NULL);
211 #endif
212 #ifdef SYSV
213                         alarm(0);
214 #endif
215
216                         update();
217
218 #ifdef BSD
219                         itv.it_value.tv_sec = sp->update_secs;
220                         itv.it_value.tv_usec = 0;
221                         itv.it_interval.tv_sec = sp->update_secs;
222                         itv.it_interval.tv_usec = 0;
223                         setitimer(ITIMER_REAL, &itv, NULL);
224 #endif
225 #ifdef SYSV
226                         alarm(sp->update_secs);
227 #endif
228                 }
229         }
230 }
231
232 read_file(s)
233         const char      *s;
234 {
235         extern FILE     *yyin;
236         int             retval;
237
238         file = s;
239         yyin = fopen(s, "r");
240         if (yyin == NULL) {
241                 perror(s);
242                 return (-1);
243         }
244         retval = yyparse();
245         fclose(yyin);
246
247         if (retval != 0)
248                 return (-1);
249         else
250                 return (0);
251 }
252
253 const char      *
254 default_game()
255 {
256         FILE            *fp;
257         static char     file[256];
258         char            line[256], games[256];
259
260         strcpy(games, _PATH_GAMES);
261         strcat(games, GAMES);
262
263         if ((fp = fopen(games, "r")) == NULL) {
264                 perror(games);
265                 return (NULL);
266         }
267         if (fgets(line, sizeof(line), fp) == NULL) {
268                 fprintf(stderr, "%s: no default game available\n", games);
269                 return (NULL);
270         }
271         fclose(fp);
272         line[strlen(line) - 1] = '\0';
273         strcpy(file, _PATH_GAMES);
274         strcat(file, line);
275         return (file);
276 }
277
278 const char      *
279 okay_game(s)
280         char    *s;
281 {
282         FILE            *fp;
283         static char     file[256];
284         const char      *ret = NULL;
285         char            line[256], games[256];
286
287         strcpy(games, _PATH_GAMES);
288         strcat(games, GAMES);
289
290         if ((fp = fopen(games, "r")) == NULL) {
291                 perror(games);
292                 return (NULL);
293         }
294         while (fgets(line, sizeof(line), fp) != NULL) {
295                 line[strlen(line) - 1] = '\0';
296                 if (strcmp(s, line) == 0) {
297                         strcpy(file, _PATH_GAMES);
298                         strcat(file, line);
299                         ret = file;
300                         break;
301                 }
302         }
303         fclose(fp);
304         if (ret == NULL) {
305                 test_mode = 1;
306                 ret = s;
307                 fprintf(stderr, "%s: %s: game not found\n", games, s);
308                 fprintf(stderr, "Your score will not be logged.\n");
309                 sleep(2);       /* give the guy time to read it */
310         }
311         return (ret);
312 }
313
314 list_games()
315 {
316         FILE            *fp;
317         char            line[256], games[256];
318         int             num_games = 0;
319
320         strcpy(games, _PATH_GAMES);
321         strcat(games, GAMES);
322
323         if ((fp = fopen(games, "r")) == NULL) {
324                 perror(games);
325                 return (-1);
326         }
327         puts("available games:");
328         while (fgets(line, sizeof(line), fp) != NULL) {
329                 printf("        %s", line);
330                 num_games++;
331         }
332         fclose(fp);
333         if (num_games == 0) {
334                 fprintf(stderr, "%s: no games available\n", games);
335                 return (-1);
336         }
337         return (0);
338 }