Add CRASHREPORT, show contact form on panic/impossible
When calling panic() or impossible(), create the option of opening a browser window with most of the fields already populated. Code for MacOS and linux is included; other ports are affected by argument change to early_init which are done but not tested. To enable, define CRASHREPORT in config.h and set CRASHREPORTURL in sysconf to (for the moment at least) http[s]://www.nethack.org/common/contactcr.html Adds --grep-defined option to makedefs for Makefiles. Adds "bid" (binary identifier), an MD4 of the main nethack binary. This is ONLY for helping (in the future) contact.html to set the "NetHack from" field automatically for our own binaries. This can be faked, but the user can lie so nothing lost. There's nothing magic about MD4; other ports can use anything that prodcues a long apparently random string we can match against. - new option --bidshow for us to get the MD4 of a released binary so I can add it to the website. Only available in wizard mode and not in nethack.6. - typo macos -> macosx in hints file No support for packaging builds as I'm not sure what that would look like. Adds a javascript helper for MacOS. Adds a lua helper for linux (and builds and installs nhlua).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 allmain.c $NHDT-Date: 1688415115 2023/07/03 20:11:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.219 $ */
|
||||
/* NetHack 3.7 allmain.c $NHDT-Date: 1693359544 2023/08/30 01:39:04 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.220 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -26,9 +26,14 @@ static void debug_fields(const char *);
|
||||
static void dump_enums(void);
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
early_init(void)
|
||||
early_init(int argc UNUSED, char *argv[] UNUSED)
|
||||
{
|
||||
#ifdef CRASHREPORT
|
||||
// Do this as early as possible, but let ports do other things first.
|
||||
crashreport_init(argc, argv);
|
||||
#endif
|
||||
decl_globals_init();
|
||||
objects_globals_init();
|
||||
monst_globals_init();
|
||||
@@ -906,6 +911,9 @@ static const struct early_opt earlyopts[] = {
|
||||
#ifdef WIN32
|
||||
{ ARG_WINDOWS, "windows", 4, TRUE },
|
||||
#endif
|
||||
#ifdef CRASHREPORT
|
||||
{ ARG_BIDSHOW, "bidshow", 7, FALSE },
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -990,6 +998,11 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg)
|
||||
dump_glyphids();
|
||||
return 2;
|
||||
#endif
|
||||
#ifdef CRASHREPORT
|
||||
case ARG_BIDSHOW:
|
||||
crashreport_bidshow();
|
||||
return 2;
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
case ARG_WINDOWS:
|
||||
if (extended_opt) {
|
||||
|
||||
263
src/end.c
263
src/end.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 end.c $NHDT-Date: 1685863329 2023/06/04 07:22:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ */
|
||||
/* NetHack 3.7 end.c $NHDT-Date: 1693519356 2023/08/31 22:02:36 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.277 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -47,7 +47,7 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
||||
#define done_stopprint gp.program_state.stopprint
|
||||
|
||||
#ifndef PANICTRACE
|
||||
#define NH_abort NH_abort_
|
||||
#define NH_abort(x) NH_abort_
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
@@ -77,6 +77,10 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
||||
* gdb: +gives more detailed information
|
||||
* +works on more OS versions
|
||||
* -requires -g, which may preclude -O on some compilers
|
||||
*
|
||||
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
|
||||
* we gather the stacktrace (etc) and launch a helper to submit a bug report
|
||||
* otherwise we just use stdout. Requires libc for now.
|
||||
*/
|
||||
#ifdef SYSCF
|
||||
#define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
|
||||
@@ -94,11 +98,11 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void NH_abort(void);
|
||||
static void NH_abort(char *);
|
||||
#ifndef NO_SIGNAL
|
||||
static void panictrace_handler(int);
|
||||
#endif
|
||||
static boolean NH_panictrace_libc(void);
|
||||
static boolean NH_panictrace_libc(char *);
|
||||
static boolean NH_panictrace_gdb(void);
|
||||
|
||||
#ifndef NO_SIGNAL
|
||||
@@ -126,7 +130,7 @@ panictrace_handler(int sig_unused UNUSED)
|
||||
|
||||
f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1);
|
||||
nhUse(f2); /* what could we do if write to fd#2 (stderr) fails */
|
||||
NH_abort(); /* ... and we're already in the process of quitting? */
|
||||
NH_abort(NULL); /* ... and we're already in the process of quitting? */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -166,7 +170,7 @@ panictrace_setsignals(boolean set)
|
||||
#endif /* NO_SIGNAL */
|
||||
|
||||
static void
|
||||
NH_abort(void)
|
||||
NH_abort(char *why)
|
||||
{
|
||||
int gdb_prio = SYSOPT_PANICTRACE_GDB;
|
||||
int libc_prio = SYSOPT_PANICTRACE_LIBC;
|
||||
@@ -183,9 +187,9 @@ NH_abort(void)
|
||||
gdb_prio++;
|
||||
|
||||
if (gdb_prio > libc_prio) {
|
||||
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
|
||||
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc(why)));
|
||||
} else {
|
||||
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
|
||||
(void) (NH_panictrace_libc(why) || (gdb_prio && NH_panictrace_gdb()));
|
||||
}
|
||||
|
||||
#else /* VMS */
|
||||
@@ -203,9 +207,230 @@ NH_abort(void)
|
||||
NH_abort_();
|
||||
}
|
||||
|
||||
/* Build a URL with a query string and try to launch a new browser window
|
||||
* to report from panic() or impossible(). Requires libc support for
|
||||
* the stacktrace. Uses memory on the stack to avoid memory allocation
|
||||
* (but libc can still do anything it wants). */
|
||||
|
||||
/* size of argument list for execve(2) */
|
||||
#define SWR_LINES 20
|
||||
/* max stack frames and header lines (details field) */
|
||||
#define SWR_FRAMES 20
|
||||
#define SWR_ADD(line) {if(xargc<(SWR_LINES-1)) xargv[xargc++] = line;}
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
# include <fcntl.h>
|
||||
# ifdef MACOS
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
# define HASH_PRAGMA_START
|
||||
# define HASH_PRAGMA_END
|
||||
# define HASH_CONTEXT CC_MD4_CTX
|
||||
# define HASH_INIT(ctx) CC_MD4_Init(ctx)
|
||||
# define HASH_UPDATE(ctx, ptr, len) CC_MD4_Update(ctx, ptr, len)
|
||||
# define HASH_FINISH(ctx, out) CC_MD4_Final(out, ctx)
|
||||
# define HASH_RESULT_SIZE CC_MD4_DIGEST_LENGTH
|
||||
# endif
|
||||
# ifdef __linux__
|
||||
# include <openssl/md4.h>
|
||||
# define HASH_PRAGMA_START \
|
||||
_Pragma("GCC diagnostic push"); \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
|
||||
# define HASH_CONTEXT MD4_CTX
|
||||
# define HASH_INIT(ctx) MD4_Init(ctx)
|
||||
# define HASH_UPDATE(ctx, ptr, len) MD4_Update(ctx, ptr, len)
|
||||
# define HASH_FINISH(ctx, out) MD4_Final(out, ctx)
|
||||
# define HASH_RESULT_SIZE MD4_DIGEST_LENGTH
|
||||
|
||||
# endif
|
||||
// Binary ID - Use only as a hint to contact.html for recognizing our own
|
||||
// binaries. This is easily spoofed!
|
||||
static char bid[(2*HASH_RESULT_SIZE)+1];
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
crashreport_init(int argc UNUSED, char *argv[] UNUSED){
|
||||
unsigned char tmp[HASH_RESULT_SIZE];
|
||||
HASH_PRAGMA_START
|
||||
HASH_CONTEXT ctx;
|
||||
HASH_INIT(&ctx);
|
||||
#ifdef MACOS
|
||||
char *binfile = argv[0];
|
||||
if(!binfile || !*binfile){
|
||||
# ifdef BETA
|
||||
// If this triggers, investigate CFBundleGetMainBundle
|
||||
// or CFBundleCopyExecutableURL.
|
||||
raw_print("BETA warning: crashreport_init called without useful info");
|
||||
# endif
|
||||
goto skip;
|
||||
}
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
char binfile[PATH_MAX+1];
|
||||
int len = readlink("/proc/self/exe", binfile, sizeof(binfile)-1);
|
||||
if(len>0) {
|
||||
binfile[len] = '\0';
|
||||
} else {
|
||||
goto skip;
|
||||
}
|
||||
#endif
|
||||
int fd = open(binfile, O_RDONLY, 0);
|
||||
if(fd == -1) {
|
||||
# ifdef BETA
|
||||
raw_printf("open e=%s",strerror(errno));
|
||||
# endif
|
||||
goto skip;
|
||||
}
|
||||
int segsize;
|
||||
char segment[4096];
|
||||
while(0 < (segsize = read(fd, segment,sizeof(segment)))){
|
||||
HASH_UPDATE(&ctx, segment, segsize);
|
||||
}
|
||||
HASH_FINISH(&ctx, tmp);
|
||||
close(fd);
|
||||
|
||||
char *p = bid;
|
||||
unsigned char *in = &tmp[0];
|
||||
char cnt=HASH_RESULT_SIZE;
|
||||
while(cnt--){
|
||||
p += snprintf(p, HASH_RESULT_SIZE-(p-bid), "%02x",*(in++));
|
||||
}
|
||||
*p = '\0';
|
||||
return;
|
||||
skip:
|
||||
strncpy((char *)bid,"unknown",sizeof(bid)-1);
|
||||
HASH_PRAGMA_END
|
||||
}
|
||||
#undef HASH_CONTEXT
|
||||
#undef HASH_INIT
|
||||
#undef HASH_UPDATE
|
||||
#undef HASH_FINISH
|
||||
#undef HASH_RESULT_SIZE
|
||||
#undef HASH_PRAGMA_START
|
||||
#undef HASH_PRAGMA_END
|
||||
|
||||
void
|
||||
crashreport_bidshow(void){
|
||||
raw_print(bid);
|
||||
}
|
||||
|
||||
boolean
|
||||
submit_web_report(const char *msg, char *why){
|
||||
if(sysopt.crashreporturl){
|
||||
const char *xargv[SWR_LINES];
|
||||
char version[100];
|
||||
char versionstring[200]; // used twice as a temp
|
||||
int xargc = 0;
|
||||
char wholetrace[SWR_LINES*80]; // XXX roughly 71 on MacOS, plus buffer
|
||||
int prelines = 0; // count of lines in trace header
|
||||
char nbuf[6]; // number buffer
|
||||
extern char **environ;
|
||||
pid_t pid;
|
||||
|
||||
SWR_ADD(CRASHREPORT);
|
||||
SWR_ADD(sysopt.crashreporturl);
|
||||
// then pairs of key value
|
||||
// subject, generate something useful
|
||||
SWR_ADD("subject");
|
||||
snprintf(version, sizeof(version), "%s report for NetHack %s",
|
||||
msg, version_string(versionstring, sizeof(versionstring)));
|
||||
SWR_ADD(version);
|
||||
// name: someday, this might be stored in nethackcnf
|
||||
// email: someday, this might be stored in nethackcnf
|
||||
// gitver, pull from version.c
|
||||
SWR_ADD("gitver");
|
||||
SWR_ADD(getversionstring(versionstring, sizeof(versionstring)));
|
||||
// hardware: leave for user
|
||||
// software: leave for user
|
||||
// comments: leave for user
|
||||
// details: stack trace
|
||||
SWR_ADD("details");
|
||||
|
||||
// XXX header for wholetrace - what other info do we want?
|
||||
// NB: prelines not tested against size of SWR_FRAMES.
|
||||
#define SWR_HDR(line) \
|
||||
if(endp<&wholetrace[sizeof(wholetrace)]){ \
|
||||
endp+=snprintf(endp, sizeof(wholetrace)-(endp-wholetrace), "%s\n",line); \
|
||||
prelines++; \
|
||||
}
|
||||
#define SWR_HDRnonl(line) \
|
||||
if(endp<&wholetrace[sizeof(wholetrace)]){ \
|
||||
endp+=snprintf(endp, sizeof(wholetrace)-(endp-wholetrace), "%s",line); \
|
||||
}
|
||||
char *endp = wholetrace;
|
||||
wholetrace[0] = 0;
|
||||
if(why){
|
||||
SWR_HDR(why);
|
||||
}
|
||||
|
||||
SWR_HDRnonl("bid: ");
|
||||
SWR_HDR(bid);
|
||||
|
||||
void *bt[SWR_FRAMES];
|
||||
int count, x;
|
||||
char **info, buf[BUFSZ];
|
||||
|
||||
count = backtrace(bt, SIZE(bt));
|
||||
info = backtrace_symbols(bt, count);
|
||||
for (x = 0; x < count; x++) {
|
||||
copynchars(buf, info[x], (int) sizeof buf - 1);
|
||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||
(void) strsubst(buf, " ", "");
|
||||
(void) strsubst(buf, " ", "");
|
||||
snprintf(endp, SWR_FRAMES*80-(endp-wholetrace), "[%02lu] %s\n",
|
||||
(unsigned long) x, buf);
|
||||
endp = eos(endp);
|
||||
}
|
||||
*(endp-1) = '\0'; // remove last newline
|
||||
SWR_ADD(wholetrace);
|
||||
|
||||
// detailrows min(actual,50) Guess since we can't know the
|
||||
// width of the window.
|
||||
SWR_ADD("detailrows");
|
||||
(void)snprintf(nbuf,sizeof(nbuf),"%d",count+prelines);
|
||||
SWR_ADD(nbuf);
|
||||
xargv[xargc++] = 0; // terminate array
|
||||
|
||||
pid = fork();
|
||||
if( pid == 0 ){
|
||||
execve(CRASHREPORT, (char * const *)xargv, environ);
|
||||
char err[100];
|
||||
sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
|
||||
raw_print(err);
|
||||
} else {
|
||||
int status;
|
||||
errno=0;
|
||||
// XXX do we _really_ know this is the right pid?
|
||||
(void)waitpid(pid, &status, 0);
|
||||
if(status){ // XXX check could be more precise
|
||||
#if 0
|
||||
// Not useful at the moment. XXX
|
||||
char err[100];
|
||||
sprintf(err, "pid=%d e=%d status=%0x",wpid,errno,status);
|
||||
raw_print(err);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* free(info); -- Don't risk it. */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif // CRASHREPORT
|
||||
#undef SWR_ADD
|
||||
#undef SWR_FRAMES
|
||||
#undef SWR_HDR
|
||||
#undef SWR_LINES
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
NH_panictrace_libc(void)
|
||||
NH_panictrace_libc(char *why UNUSED)
|
||||
{
|
||||
#ifdef CRASHREPORT
|
||||
if(submit_web_report("Panic",why)) return TRUE;
|
||||
#endif
|
||||
|
||||
#ifdef PANICTRACE_LIBC
|
||||
void *bt[20];
|
||||
int count, x;
|
||||
@@ -375,7 +600,7 @@ done2(void)
|
||||
(*soundprocs.sound_exit_nhsound)("done2");
|
||||
|
||||
exit_nhwindows((char *) 0);
|
||||
NH_abort();
|
||||
NH_abort(NULL);
|
||||
} else if (c == 'q')
|
||||
done_stopprint++;
|
||||
}
|
||||
@@ -618,11 +843,12 @@ DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
ATTRNORETURN void
|
||||
panic VA_DECL(const char *, str)
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
VA_START(str);
|
||||
VA_INIT(str, char *);
|
||||
|
||||
if (gp.program_state.panicking++)
|
||||
NH_abort(); /* avoid loops - this should never happen*/
|
||||
NH_abort(NULL); /* avoid loops - this should never happen*/
|
||||
|
||||
if (iflags.window_inited) {
|
||||
raw_print("\r\nOops...");
|
||||
@@ -651,6 +877,7 @@ panic VA_DECL(const char *, str)
|
||||
? "."
|
||||
: "\nand it may be possible to rebuild.";
|
||||
|
||||
// XXX this is probably wrong if defined(CRASHREPORT)
|
||||
if (sysopt.support)
|
||||
raw_printf("To report this error, %s%s", sysopt.support,
|
||||
maybe_rebuild);
|
||||
@@ -674,19 +901,19 @@ panic VA_DECL(const char *, str)
|
||||
}
|
||||
}
|
||||
#endif /* !MICRO */
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
|
||||
(void) vsnprintf(buf, sizeof buf, str, VA_ARGS);
|
||||
raw_print(buf);
|
||||
paniclog("panic", buf);
|
||||
}
|
||||
(void) vsnprintf(buf, sizeof buf, str, VA_ARGS);
|
||||
raw_print(buf);
|
||||
paniclog("panic", buf);
|
||||
|
||||
#ifdef WIN32
|
||||
interject(INTERJECT_PANIC);
|
||||
#endif
|
||||
#if defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32)
|
||||
# ifndef CRASHREPORT
|
||||
if (wizard)
|
||||
NH_abort(); /* generate core dump */
|
||||
# endif
|
||||
NH_abort(buf); /* generate core dump */
|
||||
#endif
|
||||
VA_END();
|
||||
really_done(PANICKED);
|
||||
|
||||
13
src/files.c
13
src/files.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 files.c $NHDT-Date: 1680625799 2023/04/04 16:29:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */
|
||||
/* NetHack 3.7 files.c $NHDT-Date: 1693083234 2023/08/26 20:53:54 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.378 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -194,6 +194,7 @@ static boolean cnf_line_PANICTRACE_LIBC(char *);
|
||||
static boolean cnf_line_PANICTRACE_GDB(char *);
|
||||
static boolean cnf_line_GDBPATH(char *);
|
||||
static boolean cnf_line_GREPPATH(char *);
|
||||
static boolean cnf_line_CRASHREPORTURL(char *);
|
||||
static boolean cnf_line_SAVEFORMAT(char *);
|
||||
static boolean cnf_line_BONESFORMAT(char *);
|
||||
static boolean cnf_line_ACCESSIBILITY(char *);
|
||||
@@ -3011,6 +3012,15 @@ cnf_line_GREPPATH(char *bufp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
cnf_line_CRASHREPORTURL(char *bufp)
|
||||
{
|
||||
if (sysopt.crashreporturl)
|
||||
free((genericptr_t) sysopt.crashreporturl);
|
||||
sysopt.crashreporturl = dupstr(bufp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
cnf_line_SAVEFORMAT(char *bufp)
|
||||
{
|
||||
@@ -3253,6 +3263,7 @@ static const struct match_config_line_stmt {
|
||||
CNFL_S(LIVELOG, 7),
|
||||
CNFL_S(PANICTRACE_LIBC, 15),
|
||||
CNFL_S(PANICTRACE_GDB, 14),
|
||||
CNFL_S(CRASHREPORTURL, 13),
|
||||
CNFL_S(GDBPATH, 7),
|
||||
CNFL_S(GREPPATH, 7),
|
||||
CNFL_S(SAVEFORMAT, 10),
|
||||
|
||||
21
src/pline.c
21
src/pline.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 pline.c $NHDT-Date: 1646255375 2022/03/02 21:09:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.109 $ */
|
||||
/* NetHack 3.7 pline.c $NHDT-Date: 1693083243 2023/08/26 20:54:03 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.124 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -505,6 +505,7 @@ impossible(const char *s, ...)
|
||||
{
|
||||
va_list the_args;
|
||||
char pbuf[BIGBUFSZ]; /* will be chopped down to BUFSZ-1 if longer */
|
||||
char pbuf2[BUFSZ];
|
||||
|
||||
va_start(the_args, s);
|
||||
if (gp.program_state.in_impossible)
|
||||
@@ -521,16 +522,26 @@ impossible(const char *s, ...)
|
||||
gp.pline_flags = URGENT_MESSAGE;
|
||||
pline("%s", pbuf);
|
||||
gp.pline_flags = 0;
|
||||
/* reuse pbuf[] */
|
||||
Strcpy(pbuf, "Program in disorder!");
|
||||
|
||||
Strcpy(pbuf2, "Program in disorder!");
|
||||
if (gp.program_state.something_worth_saving)
|
||||
Strcat(pbuf, " (Saving and reloading may fix this problem.)");
|
||||
pline("%s", pbuf);
|
||||
Strcat(pbuf2, " (Saving and reloading may fix this problem.)");
|
||||
pline("%s", pbuf2);
|
||||
pline("Please report these messages to %s.", DEVTEAM_EMAIL);
|
||||
if (sysopt.support) {
|
||||
pline("Alternatively, contact local support: %s", sysopt.support);
|
||||
}
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
if(sysopt.crashreporturl){
|
||||
boolean report = ('y' == yn_function("Report now?","yn",'n',FALSE));
|
||||
raw_print(""); // prove to the user the character was accepted
|
||||
if(report){
|
||||
submit_web_report("Impossible", pbuf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gp.program_state.in_impossible = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 sys.c $NHDT-Date: 1596498215 2020/08/03 23:43:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */
|
||||
/* NetHack 3.7 sys.c $NHDT-Date: 1693083254 2023/08/26 20:54:14 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.63 $ */
|
||||
/* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -70,6 +70,7 @@ sys_early_init(void)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
sysopt.crashreporturl = NULL;
|
||||
|
||||
sysopt.check_save_uid = 1;
|
||||
sysopt.check_plname = 0;
|
||||
|
||||
Reference in New Issue
Block a user