OSDN Git Service

[Refactor] #37353 使われていないVERIFY_SAVEFILEを削除 / Removed unused preprocessors VERIFY_SAV...
[hengband/hengband.git] / src / main.c
1 /* File: main.c */
2
3 /*
4  * Copyright (c) 1997 Ben Harrison, and others
5  *
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.
9  */
10
11 #include "angband.h"
12 #include "core.h"
13 #include "files.h"
14 #include "inet.h"
15 #include "init.h"
16 #include "scores.h"
17 #include "term.h"
18
19 /*
20  * Available graphic modes
21  */
22 #define GRAPHICS_NONE       0
23 #define GRAPHICS_ORIGINAL   1
24 #define GRAPHICS_ADAM_BOLT  2
25 #define GRAPHICS_HENGBAND   3
26
27 /*
28  * Some machines have a "main()" function in their "main-xxx.c" file,
29  * all the others use this file for their "main()" function.
30  */
31
32
33 #if !defined(WINDOWS)
34
35
36 /*
37  * A hook for "quit()".
38  *
39  * Close down, then fall back into "quit()".
40  */
41 static void quit_hook(concptr s)
42 {
43         int j;
44
45         /* Unused */
46         (void)s;
47
48         /* Scan windows */
49         for (j = 8 - 1; j >= 0; j--)
50         {
51                 /* Unused */
52                 if (!angband_term[j]) continue;
53
54                 /* Nuke it */
55                 term_nuke(angband_term[j]);
56         }
57 }
58
59
60 /*
61  * Set the stack size and overlay buffer (see main-286.c")
62  */
63 #ifdef PRIVATE_USER_PATH
64
65 /*
66  * Create an ".angband/" directory in the users home directory.
67  *
68  * ToDo: Add error handling.
69  * ToDo: Only create the directories when actually writing files.
70  */
71 static void create_user_dir(void)
72 {
73         char dirpath[1024];
74         char subdirpath[1024];
75
76         /* Get an absolute path from the filename */
77         path_parse(dirpath, 1024, PRIVATE_USER_PATH);
78
79         /* Create the ~/.angband/ directory */
80         mkdir(dirpath, 0700);
81
82         /* Build the path to the variant-specific sub-directory */
83         path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
84
85         /* Create the directory */
86         mkdir(subdirpath, 0700);
87 }
88
89 #endif /* PRIVATE_USER_PATH */
90
91
92 /*
93  * Initialize and verify the file paths, and the score file.
94  *
95  * Use the ANGBAND_PATH environment var if possible, else use
96  * DEFAULT_PATH, and in either case, branch off appropriately.
97  *
98  * First, we'll look for the ANGBAND_PATH environment variable,
99  * and then look for the files in there.  If that doesn't work,
100  * we'll try the DEFAULT_PATH constant.  So be sure that one of
101  * these two things works...
102  *
103  * We must ensure that the path ends with "PATH_SEP" if needed,
104  * since the "init_file_paths()" function will simply append the
105  * relevant "sub-directory names" to the given path.
106  *
107  * Make sure that the path doesn't overflow the buffer.  We have
108  * to leave enough space for the path separator, directory, and
109  * filenames.
110  */
111 static void init_stuff(void)
112 {
113         char path[1024];
114
115         concptr tail;
116
117         /* Get the environment variable */
118         tail = getenv("ANGBAND_PATH");
119
120         /* Use the angband_path, or a default */
121         strncpy(path, tail ? tail : DEFAULT_PATH, 511);
122
123         /* Make sure it's terminated */
124         path[511] = '\0';
125
126         /* Hack -- Add a path separator (only if needed) */
127         if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
128
129         /* Initialize */
130         init_file_paths(path);
131 }
132
133
134
135 /*
136  * Handle a "-d<what>=<path>" option
137  *
138  * The "<what>" can be any string starting with the same letter as the
139  * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
140  *
141  * The "<path>" can be any legal path for the given system, and should
142  * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
143  */
144 static void change_path(concptr info)
145 {
146         concptr s;
147
148         /* Find equal sign */
149         s = my_strchr(info, '=');
150
151         /* Verify equal sign */
152         if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
153
154         /* Analyze */
155         switch (tolower(info[0]))
156         {
157                 case 'a':
158                 {
159                         string_free(ANGBAND_DIR_APEX);
160                         ANGBAND_DIR_APEX = string_make(s+1);
161                         break;
162                 }
163
164                 case 'f':
165                 {
166                         string_free(ANGBAND_DIR_FILE);
167                         ANGBAND_DIR_FILE = string_make(s+1);
168                         break;
169                 }
170
171                 case 'h':
172                 {
173                         string_free(ANGBAND_DIR_HELP);
174                         ANGBAND_DIR_HELP = string_make(s+1);
175                         break;
176                 }
177
178                 case 'i':
179                 {
180                         string_free(ANGBAND_DIR_INFO);
181                         ANGBAND_DIR_INFO = string_make(s+1);
182                         break;
183                 }
184
185                 case 'u':
186                 {
187                         string_free(ANGBAND_DIR_USER);
188                         ANGBAND_DIR_USER = string_make(s+1);
189                         break;
190                 }
191
192                 case 'x':
193                 {
194                         string_free(ANGBAND_DIR_XTRA);
195                         ANGBAND_DIR_XTRA = string_make(s+1);
196                         break;
197                 }
198
199                 case 'b':
200                 {
201                         string_free(ANGBAND_DIR_BONE);
202                         ANGBAND_DIR_BONE = string_make(s+1);
203                         break;
204                 }
205
206                 case 'd':
207                 {
208                         string_free(ANGBAND_DIR_DATA);
209                         ANGBAND_DIR_DATA = string_make(s+1);
210                         break;
211                 }
212
213                 case 'e':
214                 {
215                         string_free(ANGBAND_DIR_EDIT);
216                         ANGBAND_DIR_EDIT = string_make(s+1);
217                         break;
218                 }
219
220                 case 's':
221                 {
222                         string_free(ANGBAND_DIR_SAVE);
223                         ANGBAND_DIR_SAVE = string_make(s+1);
224                         break;
225                 }
226
227                 case 'z':
228                 {
229                         string_free(ANGBAND_DIR_SCRIPT);
230                         ANGBAND_DIR_SCRIPT = string_make(s+1);
231                         break;
232                 }
233
234                 default:
235                 {
236                         quit_fmt("Bad semantics in '-d%s'", info);
237                 }
238         }
239 }
240
241
242 /*
243  * Simple "main" function for multiple platforms.
244  *
245  * Note the special "--" option which terminates the processing of
246  * standard options.  All non-standard options (if any) are passed
247  * directly to the "init_xxx()" function.
248  */
249 int main(int argc, char *argv[])
250 {
251         int i;
252
253         bool done = FALSE;
254         bool new_game = FALSE;
255         int show_score = 0;
256         concptr mstr = NULL;
257         bool args = TRUE;
258
259         /* Save the "program name" XXX XXX XXX */
260         argv0 = argv[0];
261
262 #ifdef SET_UID
263
264         /* Default permissions on files */
265         (void)umask(022);
266
267 #endif
268
269
270         /* Get the file paths */
271         init_stuff();
272
273
274 #ifdef SET_UID
275
276         /* Get the user id (?) */
277         p_ptr->player_uid = getuid();
278
279 #ifdef VMS
280         /* Mega-Hack -- Factor group id */
281         p_ptr->player_uid += (getgid() * 1000);
282 #endif
283
284 # ifdef SAFE_SETUID
285
286 #  ifdef _POSIX_SAVED_IDS
287
288         /* Save some info for later */
289         p_ptr->player_euid = geteuid();
290         p_ptr->player_egid = getegid();
291
292 #  endif
293
294 #  if 0 /* XXX XXX XXX */
295
296         /* Redundant setting necessary in case root is running the game */
297         /* If not root or game not setuid the following two calls do nothing */
298
299         if (setgid(getegid()) != 0)
300         {
301                 quit("setgid(): cannot set permissions correctly!");
302         }
303
304         if (setuid(geteuid()) != 0)
305         {
306                 quit("setuid(): cannot set permissions correctly!");
307         }
308
309 #  endif
310
311 # endif
312
313 #endif
314
315
316         /* Drop permissions */
317         safe_setuid_drop();
318
319
320 #ifdef SET_UID
321
322         /* Acquire the "user name" as a default player name */
323         user_name(p_ptr->name, p_ptr->player_uid);
324
325 #ifdef PRIVATE_USER_PATH
326
327         /* Create a directory for the users files. */
328         create_user_dir();
329
330 #endif /* PRIVATE_USER_PATH */
331
332 #endif /* SET_UID */
333
334
335         /* Process the command line arguments */
336         for (i = 1; args && (i < argc); i++)
337         {
338                 /* Require proper options */
339                 if (argv[i][0] != '-') goto usage;
340
341                 /* Analyze option */
342                 switch (argv[i][1])
343                 {
344                         case 'N':
345                         case 'n':
346                         {
347                                 new_game = TRUE;
348                                 break;
349                         }
350
351                         case 'F':
352                         case 'f':
353                         {
354                                 arg_fiddle = TRUE;
355                                 break;
356                         }
357
358                         case 'W':
359                         case 'w':
360                         {
361                                 arg_wizard = TRUE;
362                                 break;
363                         }
364
365                         case 'B':
366                         case 'b':
367                         {
368                                 arg_music = TRUE;
369                                 break;
370                         }
371
372                         case 'V':
373                         case 'v':
374                         {
375                                 arg_sound = TRUE;
376                                 break;
377                         }
378
379                         case 'G':
380                         case 'g':
381                         {
382                                 /* HACK - Graphics mode switches on the original tiles */
383                                 arg_graphics = GRAPHICS_ORIGINAL;
384                                 break;
385                         }
386
387                         case 'R':
388                         case 'r':
389                         {
390                                 arg_force_roguelike = TRUE;
391                                 break;
392                         }
393
394                         case 'O':
395                         case 'o':
396                         {
397                                 arg_force_original = TRUE;
398                                 break;
399                         }
400
401                         case 'S':
402                         case 's':
403                         {
404                                 show_score = atoi(&argv[i][2]);
405                                 if (show_score <= 0) show_score = 10;
406                                 break;
407                         }
408
409                         case 'u':
410                         case 'U':
411                         {
412                                 if (!argv[i][2]) goto usage;
413                                 strcpy(p_ptr->name, &argv[i][2]);
414                                 break;
415                         }
416
417                         case 'm':
418                         {
419                                 if (!argv[i][2]) goto usage;
420                                 mstr = &argv[i][2];
421                                 break;
422                         }
423
424                         case 'M':
425                         {
426                                 arg_monochrome = TRUE;
427                                 break;
428                         }
429
430                         case 'd':
431                         case 'D':
432                         {
433                                 change_path(&argv[i][2]);
434                                 break;
435                         }
436
437 #ifdef CHUUKEI
438                         case 'p':
439                         case 'P':
440                         {
441                                 if (!argv[i][2]) goto usage;
442                                 chuukei_server = TRUE;
443                                 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
444                                 break;
445                         }
446
447                         case 'c':
448                         case 'C':
449                         {
450                                 if (!argv[i][2]) goto usage;
451                                 chuukei_client = TRUE;
452                                 connect_chuukei_server(&argv[i][2]);
453                                 break;
454                         }
455 #endif
456
457                         case 'x':
458                         {
459                                 if (!argv[i][2]) goto usage;
460                                 prepare_browse_movie(&argv[i][2]);
461                                 break;
462                         }                       
463
464                         case '-':
465                         {
466                                 argv[i] = argv[0];
467                                 argc = argc - i;
468                                 argv = argv + i;
469                                 args = FALSE;
470                                 break;
471                         }
472
473                         default:
474                         usage:
475                         {
476                                 /* Dump usage information */
477                                 puts("Usage: angband [options] [-- subopts]");
478                                 puts("  -n       Start a new character");
479                                 puts("  -f       Request fiddle mode");
480                                 puts("  -w       Request wizard mode");
481                                 puts("  -b       Request BGM mode");
482                                 puts("  -v       Request sound mode");
483                                 puts("  -g       Request graphics mode");
484                                 puts("  -o       Request original keyset");
485                                 puts("  -r       Request rogue-like keyset");
486                                 puts("  -M       Request monochrome mode");
487                                 puts("  -s<num>  Show <num> high scores");
488                                 puts("  -u<who>  Use your <who> savefile");
489                                 puts("  -m<sys>  Force 'main-<sys>.c' usage");
490                                 puts("  -d<def>  Define a 'lib' dir sub-path");
491                                 puts("");
492
493 #ifdef USE_X11
494                                 puts("  -mx11    To use X11");
495                                 puts("  --       Sub options");
496                                 puts("  -- -d    Set display name");
497                                 puts("  -- -o    Request old 8x8 tile graphics");
498                                 puts("  -- -a    Request Adam Bolt 16x16 tile graphics");
499                                 puts("  -- -b    Request Bigtile graphics mode");
500                                 puts("  -- -s    Turn off smoothscaling graphics");
501                                 puts("  -- -n#   Number of terms to use");
502                                 puts("");
503 #endif /* USE_X11 */
504
505 #ifdef USE_GCU
506                                 puts("  -mgcu    To use GCU (GNU Curses)");
507 #endif /* USE_GCU */
508
509 #ifdef USE_CAP
510                                 puts("  -mcap    To use CAP (\"Termcap\" calls)");
511 #endif /* USE_CAP */
512
513                                 /* Actually abort the process */
514                                 quit(NULL);
515                         }
516                 }
517         }
518
519         /* Hack -- Forget standard args */
520         if (args)
521         {
522                 argc = 1;
523                 argv[1] = NULL;
524         }
525
526
527         /* Process the player name */
528         process_player_name(p_ptr,TRUE);
529
530
531
532         /* Install "quit" hook */
533         quit_aux = quit_hook;
534
535
536
537 #ifdef USE_XAW
538         /* Attempt to use the "main-xaw.c" support */
539         if (!done && (!mstr || (streq(mstr, "xaw"))))
540         {
541                 extern errr init_xaw(int, char**);
542                 if (0 == init_xaw(argc, argv))
543                 {
544                         ANGBAND_SYS = "xaw";
545                         done = TRUE;
546                 }
547         }
548 #endif
549
550 #ifdef USE_X11
551         /* Attempt to use the "main-x11.c" support */
552         if (!done && (!mstr || (streq(mstr, "x11"))))
553         {
554                 extern errr init_x11(int, char**);
555                 if (0 == init_x11(argc, argv))
556                 {
557                         ANGBAND_SYS = "x11";
558                         done = TRUE;
559                 }
560         }
561 #endif
562
563 #ifdef USE_GCU
564         /* Attempt to use the "main-gcu.c" support */
565         if (!done && (!mstr || (streq(mstr, "gcu"))))
566         {
567                 extern errr init_gcu(int, char**);
568                 if (0 == init_gcu(argc, argv))
569                 {
570                         ANGBAND_SYS = "gcu";
571                         done = TRUE;
572                 }
573         }
574 #endif
575
576 #ifdef USE_CAP
577         /* Attempt to use the "main-cap.c" support */
578         if (!done && (!mstr || (streq(mstr, "cap"))))
579         {
580                 extern errr init_cap(int, char**);
581                 if (0 == init_cap(argc, argv))
582                 {
583                         ANGBAND_SYS = "cap";
584                         done = TRUE;
585                 }
586         }
587 #endif
588
589         /* Make sure we have a display! */
590         if (!done) quit("Unable to prepare any 'display module'!");
591
592
593         /* Hack -- If requested, display scores and quit */
594         if (show_score > 0) display_scores(0, show_score);
595
596
597         /* Catch nasty signals */
598         signals_init();
599
600         /* Initialize */
601         init_angband(p_ptr);
602
603         /* Wait for response */
604         pause_line(23);
605
606         /* Play the game */
607         play_game(p_ptr, new_game);
608
609         /* Quit */
610         quit(NULL);
611
612         /* Exit */
613         return (0);
614 }
615
616 #endif
617
618
619