extern void FDECL()

in sys/vms/vmsmain.c [21:230]


extern void FDECL(VAXC$ESTABLISH,
                         (vms_handler_type (*) (genericptr_t, genericptr_t)));
static vms_handler_type FDECL(vms_handler, (genericptr_t, genericptr_t));
#include <ssdef.h> /* system service status codes */
#endif

static void NDECL(wd_message);
static boolean wiz_error_flag = FALSE;

int
main(argc, argv)
int argc;
char *argv[];
{
    register int fd;
#ifdef CHDIR
    register char *dir;
#endif
    boolean resuming = FALSE; /* assume new game */

#ifdef SECURE /* this should be the very first code executed */
    privoff();
    fflush((FILE *) 0); /* force stdio to init itself */
    privon();
#endif

    sys_early_init();

    atexit(byebye);
    hname = argv[0];
    hname = vms_basename(hname); /* name used in 'usage' type messages */
    hackpid = getpid();
    (void) umask(0);

    choose_windows(DEFAULT_WINDOW_SYS);

#ifdef CHDIR /* otherwise no chdir() */
    /*
     * See if we must change directory to the playground.
     * (Perhaps hack is installed with privs and playground is
     *  inaccessible for the player.)
     * The logical name HACKDIR is overridden by a
     *  -d command line option (must be the first option given)
     */
    dir = nh_getenv("NETHACKDIR");
    if (!dir)
        dir = nh_getenv("HACKDIR");
#endif
    if (argc > 1) {
#ifdef CHDIR
        if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
            /* avoid matching "-dec" for DECgraphics; since the man page
             * says -d directory, hope nobody's using -desomething_else
             */
            argc--;
            argv++;
            dir = argv[0] + 2;
            if (*dir == '=' || *dir == ':')
                dir++;
            if (!*dir && argc > 1) {
                argc--;
                argv++;
                dir = argv[0];
            }
            if (!*dir)
                error("Flag -d must be followed by a directory name.");
        }
        if (argc > 1)
#endif /* CHDIR */

            /*
             * Now we know the directory containing 'record' and
             * may do a prscore().
             */
            if (!strncmp(argv[1], "-s", 2)) {
#ifdef CHDIR
                chdirx(dir, FALSE);
#endif
#ifdef SYSCF
                initoptions();
#endif
                prscore(argc, argv);
                exit(EXIT_SUCCESS);
            }
    }

#ifdef CHDIR
    /* move to the playground directory; 'termcap' might be found there */
    chdirx(dir, TRUE);
#endif

#ifdef SECURE
    /* disable installed privs while loading nethack.cnf and termcap,
       and also while initializing terminal [$assign("TT:")]. */
    privoff();
#endif
    initoptions();
    init_nhwindows(&argc, argv);
    whoami();
#ifdef SECURE
    privon();
#endif

    /*
     * It seems you really want to play.
     */
    u.uhp = 1; /* prevent RIP on early quits */
#ifndef SAVE_ON_FATAL_ERROR
    /* used to clear hangup stuff while still giving standard traceback */
    VAXC$ESTABLISH(vms_handler);
#endif
    sethanguphandler(hangup);

    process_options(argc, argv); /* command line options */

    /* wizard mode access is deferred until here */
    set_playmode(); /* sets plname to "wizard" for wizard mode */
    /* strip role,race,&c suffix; calls askname() if plname[] is empty
       or holds a generic user name like "player" or "games" */
    plnamesuffix();

    if (wizard) {
        /* use character name rather than lock letter for file names */
        locknum = 0;
    } else {
        /* suppress interrupts while processing lock file */
        (void) signal(SIGQUIT, SIG_IGN);
        (void) signal(SIGINT, SIG_IGN);
    }
    /*
     * getlock() complains and quits if there is already a game
     * in progress for current character name (when locknum == 0)
     * or if there are too many active games (when locknum > 0).
     * When proceeding, it creates an empty <lockname>.0 file to
     * designate the current game.
     * getlock() constructs <lockname> based on the character
     * name (for !locknum) or on first available of alock, block,
     * clock, &c not currently in use in the playground directory
     * (for locknum > 0).
     */
    getlock();

    dlb_init(); /* must be before newgame() */

    /*
     *  Initialize the vision system.  This must be before mklev() on a
     *  new game or before a level restore on a saved game.
     */
    vision_init();

    display_gamewindows();

/*
 * First, try to find and restore a save file for specified character.
 * We'll return here if new game player_selection() renames the hero.
 */
attempt_restore:
    if ((fd = restore_saved_game()) >= 0) {
        const char *fq_save = fqname(SAVEF, SAVEPREFIX, 1);

        (void) chmod(fq_save, 0); /* disallow parallel restores */
        (void) signal(SIGINT, (SIG_RET_TYPE) done1);
#ifdef NEWS
        if (iflags.news) {
            display_file(NEWS, FALSE);
            iflags.news = FALSE; /* in case dorecover() fails */
        }
#endif
        pline("Restoring save file...");
        mark_synch(); /* flush output */
        if (dorecover(fd)) {
            resuming = TRUE; /* not starting new game */
            wd_message();
            if (discover || wizard) {
                if (yn("Do you want to keep the save file?") == 'n')
                    (void) delete_savefile();
                else
                    (void) chmod(fq_save, FCMASK); /* back to readable */
            }
        }
    }

    if (!resuming) {
        /* new game:  start by choosing role, race, etc;
           player might change the hero's name while doing that,
           in which case we try to restore under the new name
           and skip selection this time if that didn't succeed */
        if (!iflags.renameinprogress) {
            player_selection();
            if (iflags.renameinprogress) {
                /* player has renamed the hero while selecting role;
                   if locking alphabetically, the existing lock file
                   can still be used; otherwise, discard current one
                   and create another for the new character name */
                if (!locknum) {
                    delete_levelfile(0); /* remove empty lock file */
                    getlock();
                }
                goto attempt_restore;
            }
        }
        newgame();
        wd_message();
    }

    moveloop(resuming);
    exit(EXIT_SUCCESS);
    /*NOTREACHED*/
    return 0;
}