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.3 2006/08/08 15:03:02 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