Files
nethack/sys/share/pcsys.c
T
nhmall 309afb2eb2 add support for a unique game identifier
A 37 character field for holding a unique identifier is added
to the save file, as well as to an ancestor field in bones files.

Since it requires installation of libuuid package on Linux,
it requires an exlicit WANT_NHUUID=1 on the Make command line there.
Without the libuuid support, the saved nhuuid is empty, which should
be harmless.

This also moves the save and restore of gm.moves higher up so that it
already has a value the first time it is used against a relative saved
timestamp.

Invalidates savefiles and bones files due to new fields.

I need to get this committed before I can test out the macOS portion,
so there may be some build issues there briefly (hopefully), and
follow-up commits to resolve them.

Increments EDITLEVEL.
2026-04-25 14:48:49 -04:00

302 lines
6.5 KiB
C

/* NetHack 3.7 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */
/* Copyright (c) 2012 by Michael Allison */
/* NetHack may be freely redistributed. See license for details. */
/*
* System related functions for MSDOS, OS/2, TOS
*/
#define NEED_VARARGS
#include "hack.h"
#include "wintty.h"
#include <fcntl.h>
#if !defined(MSDOS) && !defined(WIN_CE) && !defined(CROSS_TO_AMIGA)
#include <process.h>
#endif
#if defined(__GO32__) || defined(CROSS_TO_AMIGA)
#define P_WAIT 0
#define P_NOWAIT 1
#endif
#ifdef TOS
#include <osbind.h>
#endif
#if defined(MSDOS) && !defined(__GO32__)
#define findfirst findfirst_file
#define findnext findnext_file
#define filesize filesize_nh
#endif
static void msexit(void);
#ifdef MOVERLAY
extern void __far __cdecl _movepause(void);
extern void __far __cdecl _moveresume(void);
extern unsigned short __far __cdecl _movefpause;
extern unsigned short __far __cdecl _movefpaused;
#define __MOVE_PAUSE_DISK 2 /* Represents the executable file */
#define __MOVE_PAUSE_CACHE 4 /* Represents the cache memory */
#endif /* MOVERLAY */
FILE * fopenp(const char *name, const char *mode);
#if defined(MICRO)
void
flushout(void)
{
(void) fflush(stdout);
return;
}
static const char *COMSPEC =
#ifdef TOS
"SHELL";
#else
"COMSPEC";
#endif
#define getcomspec() nh_getenv(COMSPEC)
#ifdef SHELL
int
dosh(void)
{
#ifndef NOCWD_ASSUMPTIONS
extern char orgdir[];
#endif
char *comspec;
#ifndef __GO32__
int spawnstat;
#endif
#if defined(MSDOS) && defined(NO_TERMS)
int grmode = iflags.grmode;
#endif
if ((comspec = getcomspec())) {
#ifndef TOS /* TOS has a variety of shells */
suspend_nhwindows(
"To return to NetHack, enter \"exit\" at the system prompt.\n");
#else
#if defined(MSDOS) && defined(NO_TERMS)
grmode = iflags.grmode;
#endif
suspend_nhwindows((char *) 0);
#endif /* TOS */
#ifndef NOCWD_ASSUMPTIONS
chdirx(orgdir, 0);
#endif
#ifdef __GO32__
if (system(comspec) < 0) { /* wsu@eecs.umich.edu */
#else
#ifdef MOVERLAY
/* Free the cache memory used by overlays, close .exe */
_movefpause |= __MOVE_PAUSE_DISK;
_movefpause |= __MOVE_PAUSE_CACHE;
_movepause();
#endif
spawnstat = spawnl(P_WAIT, comspec, comspec, (char *) 0);
#ifdef MOVERLAY
_moveresume();
#endif
if (spawnstat < 0) {
#endif
raw_printf("Can't spawn \"%s\"!", comspec);
getreturn("to continue");
}
#ifdef TOS
/* Some shells (e.g. Gulam) turn the cursor off when they exit */
if (iflags.BIOS)
(void) Cursconf(1, -1);
#endif
#ifndef NOCWD_ASSUMPTIONS
chdirx(hackdir, 0);
#endif
get_scr_size(); /* maybe the screen mode changed (TH) */
#if defined(MSDOS) && defined(NO_TERMS)
if (grmode)
gr_init();
#endif
resume_nhwindows();
} else
pline("Can't find %s.", COMSPEC);
return 0;
}
#endif /* SHELL */
#endif /* MICRO */
/*
* Add a backslash to any name not ending in /, \ or : There must
* be room for the \
*/
void
append_slash(char *name)
{
char *ptr;
if (!*name)
return;
ptr = name + (strlen(name) - 1);
if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
*++ptr = '\\';
*++ptr = '\0';
}
return;
}
void
get_nhuuid(void)
{
unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
if (svn.nhuuid[0])
return;
/* FIXME: fill in a useful valie UUID somehow */
Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp);
}
void
free_nhuuid(void)
{
int i;
for (i = 0; i < SIZE(svn.nhuuid); i++) {
svn.nhuuid[i] = 0;
}
}
void
getreturn(const char *str)
{
#ifdef TOS
msmsg("Hit <Return> %s.", str);
#else
#ifdef CROSS_TO_AMIGA
(void) printf("Hit <Enter> %s.", str);
#else
msmsg("Hit <Enter> %s.", str);
#endif
#endif
while (pgetchar() != '\n')
;
return;
}
void msmsg
VA_DECL(const char *, fmt)
{
VA_START(fmt);
VA_INIT(fmt, const char *);
#if defined(MSDOS) && defined(NO_TERMS)
if (iflags.grmode)
gr_finish();
#endif
Vprintf(fmt, VA_ARGS);
flushout();
VA_END();
return;
}
/*
* Follow the PATH, trying to fopen the file.
*/
#ifdef TOS
#ifdef __MINT__
#define PATHSEP ':'
#else
#define PATHSEP ','
#endif
#else
#define PATHSEP ';'
#endif
FILE *
fopenp(const char *name, const char *mode)
{
char buf[BUFSIZ], *bp, *pp, lastch = 0;
FILE *fp;
/* Try the default directory first. Then look along PATH.
*/
(void) strncpy(buf, name, BUFSIZ - 1);
buf[BUFSIZ - 1] = '\0';
if ((fp = fopen(buf, mode)))
return fp;
else {
int ccnt = 0;
pp = getenv("PATH");
while (pp && *pp) {
bp = buf;
while (*pp && *pp != PATHSEP) {
lastch = *bp++ = *pp++;
ccnt++;
}
if (lastch != '\\' && lastch != '/') {
*bp++ = '\\';
ccnt++;
}
(void) strncpy(bp, name, (BUFSIZ - ccnt) - 2);
bp[BUFSIZ - ccnt - 1] = '\0';
if ((fp = fopen(buf, mode)))
return fp;
if (*pp)
pp++;
}
}
#ifdef OS2_CODEVIEW /* one more try for hackdir */
(void) strncpy(buf, hackdir, BUFSZ);
buf[BUFSZ - 1] = '\0';
if ((strlen(name) + 1 + strlen(buf)) < BUFSZ - 1) {
append_slash(buf);
Strcat(buf, name);
} else
impossible("fopenp() buffer too small for complete filename!");
if (fp = fopen(buf, mode))
return fp;
#endif
return (FILE *) 0;
}
#if defined(MICRO) || defined(OS2)
void
nethack_exit(int code)
{
msexit();
exit(code);
}
/* Chdir back to original directory
*/
#ifdef TOS
extern boolean run_from_desktop; /* set in pcmain.c */
#endif
static void
msexit(void)
{
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
extern char orgdir[];
#endif
flushout();
#ifndef TOS
enable_ctrlP(); /* in case this wasn't done */
#endif
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
chdir(orgdir); /* chdir, not chdirx */
chdrive(orgdir);
#endif
#ifdef TOS
if (run_from_desktop)
getreturn("to continue"); /* so the user can read the score list */
if (colors_changed)
restore_colors();
#endif
wait_synch();
term_curs_set(1);
return;
}
#endif /* MICRO || OS2 */