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 } 339