1*02e7c0b9Schristos /* $NetBSD: main.c,v 1.34 2022/06/27 18:48:49 christos Exp $ */
26045e6e0Scgd
361f28255Scgd /*
46045e6e0Scgd * Copyright (c) 1980, 1993
56045e6e0Scgd * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
329007937fSlukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
342fe2731dSlukem __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
352fe2731dSlukem The Regents of the University of California. All rights reserved.");
3661f28255Scgd #endif /* not lint */
3761f28255Scgd
3861f28255Scgd #ifndef lint
396045e6e0Scgd #if 0
406045e6e0Scgd static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
416045e6e0Scgd #else
42*02e7c0b9Schristos __RCSID("$NetBSD: main.c,v 1.34 2022/06/27 18:48:49 christos Exp $");
436045e6e0Scgd #endif
4461f28255Scgd #endif /* not lint */
4561f28255Scgd
46a4cc1f4fSdholland #include <ctype.h>
47a4cc1f4fSdholland #include <curses.h>
48*02e7c0b9Schristos #include <string.h>
49a4cc1f4fSdholland #include <err.h>
50a4cc1f4fSdholland #include <errno.h>
51a4cc1f4fSdholland #include <fcntl.h>
52a4cc1f4fSdholland #include <signal.h>
53a4cc1f4fSdholland #include <stdlib.h>
548a0aa42dSdholland #include <time.h>
55a4cc1f4fSdholland #include <unistd.h>
5661f28255Scgd #include "robots.h"
5761f28255Scgd
581b1c2fdcSchristos extern const char *Scorefile;
591b1c2fdcSchristos extern int Max_per_uid;
601b1c2fdcSchristos
615305281bSdholland static bool another(void);
625305281bSdholland
639007937fSlukem int
main(int argc,char ** argv)64f5d4590cSdholland main(int argc, char **argv)
6561f28255Scgd {
66f5d4590cSdholland const char *word;
679007937fSlukem bool show_only;
685367f340Sjsm int score_wfd; /* high score writable file descriptor */
695367f340Sjsm int score_err = 0; /* hold errno from score file open */
70f5d4590cSdholland int maximum = 0;
714b76b450Schristos int ch, i;
725367f340Sjsm
735367f340Sjsm score_wfd = open(Scorefile, O_RDWR);
745367f340Sjsm if (score_wfd < 0)
755367f340Sjsm score_err = errno;
765367f340Sjsm else if (score_wfd < 3)
775367f340Sjsm exit(1);
785367f340Sjsm
795367f340Sjsm /* Revoke setgid privileges */
80f9eca697Smycroft setgid(getgid());
8161f28255Scgd
82a4cc1f4fSdholland show_only = false;
8318dfb39eSchristos Num_games = 1;
84f5d4590cSdholland
85f5d4590cSdholland while ((ch = getopt(argc, argv, "Aajnrst")) != -1) {
86f5d4590cSdholland switch (ch) {
87f5d4590cSdholland case 'A':
88f5d4590cSdholland Auto_bot = true;
89f5d4590cSdholland break;
90f5d4590cSdholland case 'a':
91f5d4590cSdholland Start_level = 4;
92f5d4590cSdholland break;
93f5d4590cSdholland case 'j':
94f5d4590cSdholland Jump = true;
95f5d4590cSdholland break;
96f5d4590cSdholland case 'n':
97f5d4590cSdholland Num_games++;
98f5d4590cSdholland break;
99f5d4590cSdholland case 'r':
100f5d4590cSdholland Real_time = true;
101f5d4590cSdholland break;
102f5d4590cSdholland case 's':
103f5d4590cSdholland show_only = true;
104f5d4590cSdholland break;
105f5d4590cSdholland case 't':
106f5d4590cSdholland Teleport = true;
107f5d4590cSdholland break;
108f5d4590cSdholland default:
109f5d4590cSdholland errx(1,
110f5d4590cSdholland "Usage: robots [-Aajnrst] [maximum] [scorefile]");
111f5d4590cSdholland break;
112f5d4590cSdholland }
113f5d4590cSdholland }
114f5d4590cSdholland
115f5d4590cSdholland for (i = optind; i < argc; i++) {
116f5d4590cSdholland word = argv[i];
117f5d4590cSdholland if (isdigit((unsigned char)word[0])) {
118f5d4590cSdholland maximum = atoi(word);
119f5d4590cSdholland } else {
120f5d4590cSdholland Scorefile = word;
121f5d4590cSdholland Max_per_uid = maximum;
1225367f340Sjsm if (score_wfd >= 0)
1235367f340Sjsm close(score_wfd);
1245367f340Sjsm score_wfd = open(Scorefile, O_RDWR);
1255367f340Sjsm if (score_wfd < 0)
1265367f340Sjsm score_err = errno;
12761f28255Scgd #ifdef FANCY
128f5d4590cSdholland word = strrchr(Scorefile, '/');
129f5d4590cSdholland if (word == NULL)
130f5d4590cSdholland word = Scorefile;
131f5d4590cSdholland if (strcmp(word, "pattern_roll") == 0)
132a4cc1f4fSdholland Pattern_roll = true;
133f5d4590cSdholland else if (strcmp(word, "stand_still") == 0)
134a4cc1f4fSdholland Stand_still = true;
13561f28255Scgd if (Pattern_roll || Stand_still)
136a4cc1f4fSdholland Teleport = true;
13761f28255Scgd #endif
13861f28255Scgd }
13961f28255Scgd }
14061f28255Scgd
14161f28255Scgd if (show_only) {
14261f28255Scgd show_score();
14361f28255Scgd exit(0);
14461f28255Scgd /* NOTREACHED */
14561f28255Scgd }
14661f28255Scgd
1475367f340Sjsm if (score_wfd < 0) {
1485367f340Sjsm errno = score_err;
1495367f340Sjsm warn("%s", Scorefile);
1505367f340Sjsm warnx("High scores will not be recorded!");
1515367f340Sjsm sleep(2);
1525367f340Sjsm }
1535367f340Sjsm
154432ec044Sdrochner if (!initscr())
155432ec044Sdrochner errx(0, "couldn't initialize screen");
15661f28255Scgd signal(SIGINT, quit);
157d82bd70cSblymn cbreak();
15861f28255Scgd noecho();
15961f28255Scgd nonl();
16061f28255Scgd if (LINES != Y_SIZE || COLS != X_SIZE) {
16161f28255Scgd if (LINES < Y_SIZE || COLS < X_SIZE) {
16261f28255Scgd endwin();
16361f28255Scgd printf("Need at least a %dx%d screen\n",
16461f28255Scgd Y_SIZE, X_SIZE);
16561f28255Scgd exit(1);
16661f28255Scgd }
16761f28255Scgd delwin(stdscr);
16861f28255Scgd stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
16961f28255Scgd }
17061f28255Scgd
17161f28255Scgd if (Real_time)
17261f28255Scgd signal(SIGALRM, move_robots);
17361f28255Scgd do {
17418dfb39eSchristos while (Num_games--) {
17561f28255Scgd init_field();
17661f28255Scgd for (Level = Start_level; !Dead; Level++) {
17761f28255Scgd make_level();
17861f28255Scgd play_level();
17918dfb39eSchristos if (Auto_bot)
18018dfb39eSchristos sleep(1);
18161f28255Scgd }
18261f28255Scgd move(My_pos.y, My_pos.x);
18361f28255Scgd printw("AARRrrgghhhh....");
18461f28255Scgd refresh();
18518dfb39eSchristos if (Auto_bot)
18618dfb39eSchristos sleep(1);
1875367f340Sjsm score(score_wfd);
18818dfb39eSchristos if (Auto_bot)
18918dfb39eSchristos sleep(1);
19018dfb39eSchristos refresh();
19118dfb39eSchristos }
1925c54ba1bSjsm Num_games = 1;
19318dfb39eSchristos } while (!Auto_bot && another());
1949007937fSlukem quit(0);
1959007937fSlukem /* NOTREACHED */
1969007937fSlukem return(0);
19761f28255Scgd }
19861f28255Scgd
19961f28255Scgd /*
20061f28255Scgd * quit:
20161f28255Scgd * Leave the program elegantly.
20261f28255Scgd */
20361f28255Scgd void
quit(int dummy __unused)20430870bd5Sdholland quit(int dummy __unused)
20561f28255Scgd {
20661f28255Scgd endwin();
20761f28255Scgd exit(0);
20861f28255Scgd /* NOTREACHED */
20961f28255Scgd }
21061f28255Scgd
21161f28255Scgd /*
21261f28255Scgd * another:
21361f28255Scgd * See if another game is desired
21461f28255Scgd */
2155305281bSdholland static bool
another(void)21630870bd5Sdholland another(void)
21761f28255Scgd {
2189007937fSlukem int y;
21961f28255Scgd
22061f28255Scgd #ifdef FANCY
22161f28255Scgd if ((Stand_still || Pattern_roll) && !Newscore)
222a4cc1f4fSdholland return true;
22361f28255Scgd #endif
22461f28255Scgd
22561f28255Scgd if (query("Another game?")) {
22661f28255Scgd if (Full_clear) {
22761f28255Scgd for (y = 1; y <= Num_scores; y++) {
22861f28255Scgd move(y, 1);
22961f28255Scgd clrtoeol();
23061f28255Scgd }
23161f28255Scgd refresh();
23261f28255Scgd }
233a4cc1f4fSdholland return true;
23461f28255Scgd }
235a4cc1f4fSdholland return false;
23661f28255Scgd }
237