4 * Copyright (c) 1997 Ben Harrison, and others
6 * This software may be copied and distributed for educational, research,
7 * and not for profit purposes provided that this copyright and statement
8 * are included in all such copies.
15 * Some machines have a "main()" function in their "main-xxx.c" file,
16 * all the others use this file for their "main()" function.
20 #if !defined(MACINTOSH) && !defined(WINDOWS) && !defined(ACORN)
26 #endif /* USE_SCRIPT */
30 * A hook for "quit()".
32 * Close down, then fall back into "quit()".
34 static void quit_hook(cptr s)
39 for (j = 8 - 1; j >= 0; j--)
42 if (!angband_term[j]) continue;
45 term_nuke(angband_term[j]);
52 * Set the stack size (for the Amiga)
56 __near long __stack = 32768L;
61 * Set the stack size and overlay buffer (see main-286.c")
65 extern unsigned _stklen = 32768U;
66 extern unsigned _ovrbuffer = 0x1500;
69 #ifdef PRIVATE_USER_PATH
72 * Create an ".angband/" directory in the users home directory.
74 * ToDo: Add error handling.
75 * ToDo: Only create the directories when actually writing files.
77 static void create_user_dir(void)
80 char subdirpath[1024];
85 /* Get an absolute path from the filename */
86 path_parse(dirpath, 1024, PRIVATE_USER_PATH);
88 /* Create the ~/.angband/ directory */
91 /* Build the path to the variant-specific sub-directory */
92 path_build(subdirpath, 1024, dirpath, VERSION_NAME);
94 /* Create the directory */
95 mkdir(subdirpath, 0700);
101 #endif /* PRIVATE_USER_PATH */
105 * Initialize and verify the file paths, and the score file.
107 * Use the ANGBAND_PATH environment var if possible, else use
108 * DEFAULT_PATH, and in either case, branch off appropriately.
110 * First, we'll look for the ANGBAND_PATH environment variable,
111 * and then look for the files in there. If that doesn't work,
112 * we'll try the DEFAULT_PATH constant. So be sure that one of
113 * these two things works...
115 * We must ensure that the path ends with "PATH_SEP" if needed,
116 * since the "init_file_paths()" function will simply append the
117 * relevant "sub-directory names" to the given path.
119 * Note that the "path" must be "Angband:" for the Amiga, and it
120 * is ignored for "VM/ESA", so I just combined the two.
122 * Make sure that the path doesn't overflow the buffer. We have
123 * to leave enough space for the path separator, directory, and
126 static void init_stuff(void)
130 #if defined(AMIGA) || defined(VM)
132 /* Hack -- prepare "path" */
133 strcpy(path, "Angband:");
135 #else /* AMIGA / VM */
139 /* Get the environment variable */
140 tail = getenv("ANGBAND_PATH");
142 /* Use the angband_path, or a default */
143 strncpy(path, tail ? tail : DEFAULT_PATH, 511);
145 /* Make sure it's terminated */
148 /* Hack -- Add a path separator (only if needed) */
149 if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
151 #endif /* AMIGA / VM */
154 init_file_paths(path);
160 * Handle a "-d<what>=<path>" option
162 * The "<what>" can be any string starting with the same letter as the
163 * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
165 * The "<path>" can be any legal path for the given system, and should
166 * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
168 static void change_path(cptr info)
172 /* Find equal sign */
173 s = strchr(info, '=');
175 /* Verify equal sign */
176 if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
179 switch (tolower(info[0]))
183 string_free(ANGBAND_DIR_APEX);
184 ANGBAND_DIR_APEX = string_make(s+1);
190 string_free(ANGBAND_DIR_FILE);
191 ANGBAND_DIR_FILE = string_make(s+1);
197 string_free(ANGBAND_DIR_HELP);
198 ANGBAND_DIR_HELP = string_make(s+1);
204 string_free(ANGBAND_DIR_INFO);
205 ANGBAND_DIR_INFO = string_make(s+1);
211 string_free(ANGBAND_DIR_USER);
212 ANGBAND_DIR_USER = string_make(s+1);
218 string_free(ANGBAND_DIR_XTRA);
219 ANGBAND_DIR_XTRA = string_make(s+1);
223 #ifdef VERIFY_SAVEFILE
230 quit_fmt("Restricted option '-d%s'", info);
233 #else /* VERIFY_SAVEFILE */
237 string_free(ANGBAND_DIR_BONE);
238 ANGBAND_DIR_BONE = string_make(s+1);
244 string_free(ANGBAND_DIR_DATA);
245 ANGBAND_DIR_DATA = string_make(s+1);
251 string_free(ANGBAND_DIR_EDIT);
252 ANGBAND_DIR_EDIT = string_make(s+1);
258 string_free(ANGBAND_DIR_SAVE);
259 ANGBAND_DIR_SAVE = string_make(s+1);
265 string_free(ANGBAND_DIR_SCRIPT);
266 ANGBAND_DIR_SCRIPT = string_make(s+1);
270 #endif /* VERIFY_SAVEFILE */
274 quit_fmt("Bad semantics in '-d%s'", info);
281 * Simple "main" function for multiple platforms.
283 * Note the special "--" option which terminates the processing of
284 * standard options. All non-standard options (if any) are passed
285 * directly to the "init_xxx()" function.
287 int main(int argc, char *argv[])
293 bool new_game = FALSE;
302 /* Save the "program name" XXX XXX XXX */
306 /* Attempt to use XMS (or EMS) memory for swap space */
307 if (_OvrInitExt(0L, 0L))
309 _OvrInitEms(0, 0, 64);
316 /* Default permissions on files */
327 /* Get the file paths */
333 /* Get the user id (?) */
334 player_uid = getuid();
337 /* Mega-Hack -- Factor group id */
338 player_uid += (getgid() * 1000);
343 # ifdef _POSIX_SAVED_IDS
345 /* Save some info for later */
346 player_euid = geteuid();
347 player_egid = getegid();
351 # if 0 /* XXX XXX XXX */
353 /* Redundant setting necessary in case root is running the game */
354 /* If not root or game not setuid the following two calls do nothing */
356 if (setgid(getegid()) != 0)
358 quit("setgid(): cannot set permissions correctly!");
361 if (setuid(geteuid()) != 0)
363 quit("setuid(): cannot set permissions correctly!");
375 /* Initialize the "time" checker */
376 if (check_time_init() || check_time())
378 quit("The gates to Angband are closed (bad time).");
381 /* Initialize the "load" checker */
382 if (check_load_init() || check_load())
384 quit("The gates to Angband are closed (bad load).");
387 /* Acquire the "user name" as a default player name */
389 user_name(player_name, player_uid);
390 #else /* ANGBAND_2_8_1 */
391 user_name(op_ptr->full_name, player_uid);
392 #endif /* ANGBAND_2_8_1 */
394 #ifdef PRIVATE_USER_PATH
396 /* Create a directory for the users files. */
399 #endif /* PRIVATE_USER_PATH */
404 /* Process the command line arguments */
405 for (i = 1; args && (i < argc); i++)
407 /* Require proper options */
408 if (argv[i][0] != '-') goto usage;
444 /* HACK - Graphics mode switches on the original tiles */
445 arg_graphics = GRAPHICS_ORIGINAL;
452 arg_force_roguelike = TRUE;
459 arg_force_original = TRUE;
466 show_score = atoi(&argv[i][2]);
467 if (show_score <= 0) show_score = 10;
474 if (!argv[i][2]) goto usage;
476 strcpy(player_name, &argv[i][2]);
477 #else /* ANGBAND_2_8_1 */
479 /* Get the savefile name */
480 strncpy(op_ptr->full_name, &argv[i][2], 32);
482 /* Make sure it's terminated */
483 op_ptr->full_name[31] = '\0';
485 #endif /* ANGBAND_2_8_1 */
491 if (!argv[i][2]) goto usage;
498 arg_monochrome = TRUE;
505 change_path(&argv[i][2]);
513 if (!argv[i][2]) goto usage;
514 chuukei_server = TRUE;
515 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
522 if (!argv[i][2]) goto usage;
523 chuukei_client = TRUE;
524 connect_chuukei_server(&argv[i][2]);
541 /* Dump usage information */
542 puts("Usage: angband [options] [-- subopts]");
543 puts(" -n Start a new character");
544 puts(" -f Request fiddle mode");
545 puts(" -w Request wizard mode");
546 puts(" -v Request sound mode");
547 puts(" -g Request graphics mode");
548 puts(" -o Request original keyset");
549 puts(" -r Request rogue-like keyset");
550 puts(" -M Request monochrome mode");
551 puts(" -s<num> Show <num> high scores");
552 puts(" -u<who> Use your <who> savefile");
553 puts(" -m<sys> Force 'main-<sys>.c' usage");
554 puts(" -d<def> Define a 'lib' dir sub-path");
556 /* Actually abort the process */
562 /* Hack -- Forget standard args */
570 /* Process the player name */
571 process_player_name(TRUE);
575 /* Install "quit" hook */
576 quit_aux = quit_hook;
579 /* Drop privs (so X11 will work correctly) */
584 /* Attempt to use the "main-xaw.c" support */
585 if (!done && (!mstr || (streq(mstr, "xaw"))))
587 extern errr init_xaw(int, char**);
588 if (0 == init_xaw(argc, argv))
597 /* Attempt to use the "main-x11.c" support */
598 if (!done && (!mstr || (streq(mstr, "x11"))))
600 extern errr init_x11(int, char**);
601 if (0 == init_x11(argc, argv))
610 /* Attempt to use the "main-gcu.c" support */
611 if (!done && (!mstr || (streq(mstr, "gcu"))))
613 extern errr init_gcu(int, char**);
614 if (0 == init_gcu(argc, argv))
623 /* Attempt to use the "main-cap.c" support */
624 if (!done && (!mstr || (streq(mstr, "cap"))))
626 extern errr init_cap(int, char**);
627 if (0 == init_cap(argc, argv))
637 /* Attempt to use the "main-dos.c" support */
638 if (!done && (!mstr || (streq(mstr, "dos"))))
640 extern errr init_dos(void);
650 /* Attempt to use the "main-ibm.c" support */
651 if (!done && (!mstr || (streq(mstr, "ibm"))))
653 extern errr init_ibm(void);
664 /* Attempt to use the "main-emx.c" support */
665 if (!done && (!mstr || (streq(mstr, "emx"))))
667 extern errr init_emx(void);
678 /* Attempt to use the "main-sla.c" support */
679 if (!done && (!mstr || (streq(mstr, "sla"))))
681 extern errr init_sla(void);
692 /* Attempt to use the "main-lsl.c" support */
693 if (!done && (!mstr || (streq(mstr, "lsl"))))
695 extern errr init_lsl(void);
706 /* Attempt to use the "main-ami.c" support */
707 if (!done && (!mstr || (streq(mstr, "ami"))))
709 extern errr init_ami(void);
720 /* Attempt to use the "main-vme.c" support */
721 if (!done && (!mstr || (streq(mstr, "vme"))))
723 extern errr init_vme(void);
733 /* Grab privs (dropped above for X11) */
737 /* Make sure we have a display! */
738 if (!done) quit("Unable to prepare any 'display module'!");
741 /* Hack -- If requested, display scores and quit */
742 if (show_score > 0) display_scores(0, show_score);
745 /* Catch nasty signals */
751 /* Wait for response */