Add per-game configurable ttyrec-dir; If it's not defined for some game,
no ttyrecs are saved for that game, and those games cannot be spectated. Add more debugging output to dgldebug.log -file Add configure option --enable-debugfile to enable or disable the debugging log. git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@468 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
parent
592b966d78
commit
972bb6fa6b
1
config.l
1
config.l
|
@ -83,6 +83,7 @@ cursor { return TYPE_CURSOR; }
|
||||||
"inprogressdir" { return TYPE_PATH_INPROGRESS; }
|
"inprogressdir" { return TYPE_PATH_INPROGRESS; }
|
||||||
"game_args" { return TYPE_GAME_ARGS; }
|
"game_args" { return TYPE_GAME_ARGS; }
|
||||||
"rc_fmt" { return TYPE_RC_FMT; }
|
"rc_fmt" { return TYPE_RC_FMT; }
|
||||||
|
"ttyrecdir" { return TYPE_PATH_TTYREC; }
|
||||||
server_id { return TYPE_SERVER_ID; }
|
server_id { return TYPE_SERVER_ID; }
|
||||||
sortmode { return TYPE_WATCH_SORTMODE; }
|
sortmode { return TYPE_WATCH_SORTMODE; }
|
||||||
commands { return TYPE_CMDQUEUE; }
|
commands { return TYPE_CMDQUEUE; }
|
||||||
|
|
9
config.y
9
config.y
|
@ -38,7 +38,7 @@ static const char* lookup_token (int t);
|
||||||
%token TYPE_ALLOW_REGISTRATION
|
%token TYPE_ALLOW_REGISTRATION
|
||||||
%token TYPE_PATH_GAME TYPE_NAME_GAME TYPE_PATH_DGLDIR TYPE_PATH_SPOOL
|
%token TYPE_PATH_GAME TYPE_NAME_GAME TYPE_PATH_DGLDIR TYPE_PATH_SPOOL
|
||||||
%token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT
|
%token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT
|
||||||
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE
|
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_TTYREC
|
||||||
%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
|
%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
|
||||||
%token TYPE_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR
|
%token TYPE_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR
|
||||||
%token <s> TYPE_VALUE
|
%token <s> TYPE_VALUE
|
||||||
|
@ -364,6 +364,11 @@ game_definition : TYPE_CMDQUEUE
|
||||||
myconfig[ncnf]->spool = strdup($3);
|
myconfig[ncnf]->spool = strdup($3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TYPE_PATH_TTYREC:
|
||||||
|
if (myconfig[ncnf]->ttyrecdir) free(myconfig[ncnf]->ttyrecdir);
|
||||||
|
myconfig[ncnf]->ttyrecdir = strdup($3);
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_PATH_GAME:
|
case TYPE_PATH_GAME:
|
||||||
if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
|
if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
|
||||||
myconfig[ncnf]->game_path = strdup ($3);
|
myconfig[ncnf]->game_path = strdup ($3);
|
||||||
|
@ -519,6 +524,7 @@ KeyType : TYPE_SUSER { $$ = TYPE_SUSER; }
|
||||||
| TYPE_PATH_SPOOL { $$ = TYPE_PATH_SPOOL; }
|
| TYPE_PATH_SPOOL { $$ = TYPE_PATH_SPOOL; }
|
||||||
| TYPE_PATH_BANNER { $$ = TYPE_PATH_BANNER; }
|
| TYPE_PATH_BANNER { $$ = TYPE_PATH_BANNER; }
|
||||||
| TYPE_PATH_CANNED { $$ = TYPE_PATH_CANNED; }
|
| TYPE_PATH_CANNED { $$ = TYPE_PATH_CANNED; }
|
||||||
|
| TYPE_PATH_TTYREC { $$ = TYPE_PATH_TTYREC; }
|
||||||
| TYPE_PATH_PASSWD { $$ = TYPE_PATH_PASSWD; }
|
| TYPE_PATH_PASSWD { $$ = TYPE_PATH_PASSWD; }
|
||||||
| TYPE_PATH_LOCKFILE { $$ = TYPE_PATH_LOCKFILE; }
|
| TYPE_PATH_LOCKFILE { $$ = TYPE_PATH_LOCKFILE; }
|
||||||
| TYPE_PATH_INPROGRESS { $$ = TYPE_PATH_INPROGRESS; }
|
| TYPE_PATH_INPROGRESS { $$ = TYPE_PATH_INPROGRESS; }
|
||||||
|
@ -548,6 +554,7 @@ const char* lookup_token (int t)
|
||||||
case TYPE_PATH_SPOOL: return "spooldir";
|
case TYPE_PATH_SPOOL: return "spooldir";
|
||||||
case TYPE_PATH_BANNER: return "banner";
|
case TYPE_PATH_BANNER: return "banner";
|
||||||
case TYPE_PATH_CANNED: return "rc_template";
|
case TYPE_PATH_CANNED: return "rc_template";
|
||||||
|
case TYPE_PATH_TTYREC: return "ttyrecdir";
|
||||||
case TYPE_PATH_INPROGRESS: return "inprogressdir";
|
case TYPE_PATH_INPROGRESS: return "inprogressdir";
|
||||||
case TYPE_GAME_ARGS: return "game_args";
|
case TYPE_GAME_ARGS: return "game_args";
|
||||||
case TYPE_RC_FMT: return "rc_fmt";
|
case TYPE_RC_FMT: return "rc_fmt";
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -72,6 +72,16 @@ AC_ARG_ENABLE(enable-virus,
|
||||||
AC_SUBST(EDITOR)
|
AC_SUBST(EDITOR)
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(enable-debugfile,
|
||||||
|
[AC_HELP_STRING([--enable-debugfile], [Enable debugging output to a file.])],
|
||||||
|
[], [])
|
||||||
|
|
||||||
|
if test "$enable_debugfile" = yes; then
|
||||||
|
AC_MSG_RESULT([Enabling debugging output to a file.])
|
||||||
|
AC_DEFINE(USE_DEBUGFILE,1,[Output debugging into to a file in chroot.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(enable-sqlite,
|
AC_ARG_ENABLE(enable-sqlite,
|
||||||
[AC_HELP_STRING([--enable-sqlite], [Use SQLite for the database instead of flat text file.])],
|
[AC_HELP_STRING([--enable-sqlite], [Use SQLite for the database instead of flat text file.])],
|
||||||
[], [])
|
[], [])
|
||||||
|
|
119
dgamelaunch.c
119
dgamelaunch.c
|
@ -149,15 +149,20 @@ void
|
||||||
ttyrec_getpty ()
|
ttyrec_getpty ()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_OPENPTY
|
#ifdef HAVE_OPENPTY
|
||||||
if (openpty (&master, &slave, NULL, NULL, NULL) == -1)
|
if (openpty (&master, &slave, NULL, NULL, NULL) == -1) {
|
||||||
graceful_exit (62);
|
debug_write("cannot openpty");
|
||||||
|
graceful_exit (62);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if ((master = open ("/dev/ptmx", O_RDWR)) < 0)
|
if ((master = open ("/dev/ptmx", O_RDWR)) < 0) {
|
||||||
graceful_exit (62);
|
debug_write("cannot open /dev/ptmx");
|
||||||
|
graceful_exit (62);
|
||||||
|
}
|
||||||
grantpt (master);
|
grantpt (master);
|
||||||
unlockpt (master);
|
unlockpt (master);
|
||||||
if ((slave = open ((const char *) ptsname (master), O_RDWR)) < 0)
|
if ((slave = open ((const char *) ptsname (master), O_RDWR)) < 0)
|
||||||
{
|
{
|
||||||
|
debug_write("cannot open master ptsname");
|
||||||
graceful_exit (65);
|
graceful_exit (65);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,15 +224,17 @@ gen_inprogress_lock (int game, pid_t pid, char* ttyrec_filename)
|
||||||
fl.l_start = 0;
|
fl.l_start = 0;
|
||||||
fl.l_len = 0;
|
fl.l_len = 0;
|
||||||
|
|
||||||
len = strlen(dgl_format_str(game, me, myconfig[game]->inprogressdir)) + strlen(me->username) + strlen(ttyrec_filename) + 13;
|
len = strlen(dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL)) + strlen(me->username) + strlen(ttyrec_filename) + 13;
|
||||||
lockfile = calloc(len, sizeof(char));
|
lockfile = calloc(len, sizeof(char));
|
||||||
|
|
||||||
snprintf (lockfile, len, "%s%s:%s", dgl_format_str(game, me, myconfig[game]->inprogressdir),
|
snprintf (lockfile, len, "%s%s:%s", dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL),
|
||||||
me->username, ttyrec_filename);
|
me->username, ttyrec_filename);
|
||||||
|
|
||||||
fd = open (lockfile, O_WRONLY | O_CREAT, 0644);
|
fd = open (lockfile, O_WRONLY | O_CREAT, 0644);
|
||||||
if (fcntl (fd, F_SETLKW, &fl) == -1)
|
if (fcntl (fd, F_SETLKW, &fl) == -1) {
|
||||||
|
debug_write("cannot fnctl inprogress-lock");
|
||||||
graceful_exit (68);
|
graceful_exit (68);
|
||||||
|
}
|
||||||
|
|
||||||
write (fd, filebuf, strlen (filebuf));
|
write (fd, filebuf, strlen (filebuf));
|
||||||
|
|
||||||
|
@ -245,6 +252,7 @@ catch_sighup (int signum)
|
||||||
kill (child, SIGHUP);
|
kill (child, SIGHUP);
|
||||||
sleep (5);
|
sleep (5);
|
||||||
}
|
}
|
||||||
|
debug_write("catchup sighup");
|
||||||
graceful_exit (2);
|
graceful_exit (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,8 +486,10 @@ inprogressmenu (int gameid)
|
||||||
/* reuse the char* */
|
/* reuse the char* */
|
||||||
replacestr = strchr (ttyrecname, ':');
|
replacestr = strchr (ttyrecname, ':');
|
||||||
|
|
||||||
if (!replacestr)
|
if (!replacestr) {
|
||||||
|
debug_write("inprogressmenu replacestr");
|
||||||
graceful_exit (145);
|
graceful_exit (145);
|
||||||
|
}
|
||||||
|
|
||||||
/*replacestr[0] = '/';*/
|
/*replacestr[0] = '/';*/
|
||||||
|
|
||||||
|
@ -622,8 +632,10 @@ changepw (int dowrite)
|
||||||
int error = 2;
|
int error = 2;
|
||||||
|
|
||||||
/* A precondition is that struct `me' exists because we can be not-yet-logged-in. */
|
/* A precondition is that struct `me' exists because we can be not-yet-logged-in. */
|
||||||
if (!me)
|
if (!me) {
|
||||||
|
debug_write("no 'me' in changepw");
|
||||||
graceful_exit (122); /* Die. */
|
graceful_exit (122); /* Die. */
|
||||||
|
}
|
||||||
|
|
||||||
while (error)
|
while (error)
|
||||||
{
|
{
|
||||||
|
@ -656,8 +668,10 @@ changepw (int dowrite)
|
||||||
if (*buf == '\0')
|
if (*buf == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (strchr (buf, ':') != NULL)
|
if (strchr (buf, ':') != NULL) {
|
||||||
|
debug_write("cannot have ':' in passwd");
|
||||||
graceful_exit (112);
|
graceful_exit (112);
|
||||||
|
}
|
||||||
|
|
||||||
mvaddstr (12, 1, "And again:");
|
mvaddstr (12, 1, "And again:");
|
||||||
mvaddstr (13, 1, "=> ");
|
mvaddstr (13, 1, "=> ");
|
||||||
|
@ -700,11 +714,13 @@ wall_email(char *from, char *msg)
|
||||||
|
|
||||||
if (strlen(from) < 1) {
|
if (strlen(from) < 1) {
|
||||||
fprintf(stderr, "Error: wall: 'from' username is too short!\n");
|
fprintf(stderr, "Error: wall: 'from' username is too short!\n");
|
||||||
|
debug_write("wall: 'from' username too short");
|
||||||
graceful_exit(121);
|
graceful_exit(121);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(msg) >= 80) {
|
if (strlen(msg) >= 80) {
|
||||||
fprintf(stderr, "Error: wall: message too long!\n");
|
fprintf(stderr, "Error: wall: message too long!\n");
|
||||||
|
debug_write("wall: message too long");
|
||||||
graceful_exit(120);
|
graceful_exit(120);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,6 +728,7 @@ wall_email(char *from, char *msg)
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
fprintf(stderr, "Error: wall: no one's logged in!\n");
|
fprintf(stderr, "Error: wall: no one's logged in!\n");
|
||||||
|
debug_write("wall: no people playing");
|
||||||
graceful_exit(118);
|
graceful_exit(118);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,15 +1179,21 @@ readfile (int nolock)
|
||||||
if (!nolock)
|
if (!nolock)
|
||||||
{
|
{
|
||||||
fpl = fopen (globalconfig.lockfile, "r");
|
fpl = fopen (globalconfig.lockfile, "r");
|
||||||
if (!fpl)
|
if (!fpl) {
|
||||||
|
debug_write("cannot fopen lockfile");
|
||||||
graceful_exit (106);
|
graceful_exit (106);
|
||||||
if (fcntl (fileno (fpl), F_SETLKW, &fl) == -1)
|
}
|
||||||
|
if (fcntl (fileno (fpl), F_SETLKW, &fl) == -1) {
|
||||||
|
debug_write("cannot fcntl lockfile");
|
||||||
graceful_exit (114);
|
graceful_exit (114);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen (globalconfig.passwd, "r");
|
fp = fopen (globalconfig.passwd, "r");
|
||||||
if (!fp)
|
if (!fp) {
|
||||||
|
debug_write("cannot fopen passwd file");
|
||||||
graceful_exit (106);
|
graceful_exit (106);
|
||||||
|
}
|
||||||
|
|
||||||
/* once per name in the file */
|
/* once per name in the file */
|
||||||
while (fgets (buf, 1200, fp))
|
while (fgets (buf, 1200, fp))
|
||||||
|
@ -1191,8 +1214,10 @@ readfile (int nolock)
|
||||||
return 1;
|
return 1;
|
||||||
users[f_num]->username[(b - n)] = *b;
|
users[f_num]->username[(b - n)] = *b;
|
||||||
b++;
|
b++;
|
||||||
if ((b - n) >= 21)
|
if ((b - n) >= 21) {
|
||||||
|
debug_write("name field too long");
|
||||||
graceful_exit (100);
|
graceful_exit (100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance to next field */
|
/* advance to next field */
|
||||||
|
@ -1204,8 +1229,10 @@ readfile (int nolock)
|
||||||
{
|
{
|
||||||
users[f_num]->email[(b - n)] = *b;
|
users[f_num]->email[(b - n)] = *b;
|
||||||
b++;
|
b++;
|
||||||
if ((b - n) > 80)
|
if ((b - n) > 80) {
|
||||||
|
debug_write("email field too long");
|
||||||
graceful_exit (101);
|
graceful_exit (101);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance to next field */
|
/* advance to next field */
|
||||||
|
@ -1217,8 +1244,10 @@ readfile (int nolock)
|
||||||
{
|
{
|
||||||
users[f_num]->password[(b - n)] = *b;
|
users[f_num]->password[(b - n)] = *b;
|
||||||
b++;
|
b++;
|
||||||
if ((b - n) >= 20)
|
if ((b - n) >= 20) {
|
||||||
|
debug_write("passwd field too long");
|
||||||
graceful_exit (102);
|
graceful_exit (102);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance to next field */
|
/* advance to next field */
|
||||||
|
@ -1230,8 +1259,10 @@ readfile (int nolock)
|
||||||
{
|
{
|
||||||
users[f_num]->env[(b - n)] = *b;
|
users[f_num]->env[(b - n)] = *b;
|
||||||
b++;
|
b++;
|
||||||
if ((b - n) >= 1024)
|
if ((b - n) >= 1024) {
|
||||||
|
debug_write("env field too long");
|
||||||
graceful_exit (102);
|
graceful_exit (102);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f_num++;
|
f_num++;
|
||||||
|
@ -1239,6 +1270,7 @@ readfile (int nolock)
|
||||||
if (f_num > globalconfig.max)
|
if (f_num > globalconfig.max)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"ERROR: number of users in database exceeds maximum. Exiting.\n");
|
fprintf(stderr,"ERROR: number of users in database exceeds maximum. Exiting.\n");
|
||||||
|
debug_write("too many users in database");
|
||||||
graceful_exit (109);
|
graceful_exit (109);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1329,6 +1361,7 @@ userexist (char *cname, int isnew)
|
||||||
ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
|
ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
debug_write("sqlite3_open failed");
|
||||||
graceful_exit(109);
|
graceful_exit(109);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,6 +1381,7 @@ userexist (char *cname, int isnew)
|
||||||
|
|
||||||
if (ret != SQLITE_OK) {
|
if (ret != SQLITE_OK) {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
debug_write("sqlite3_exec failed");
|
||||||
graceful_exit(108);
|
graceful_exit(108);
|
||||||
}
|
}
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
@ -1413,14 +1447,14 @@ editoptions (int game)
|
||||||
char *myargv[3];
|
char *myargv[3];
|
||||||
pid_t editor;
|
pid_t editor;
|
||||||
|
|
||||||
rcfile = fopen (dgl_format_str(game, me, myconfig[game]->rc_fmt), "r");
|
rcfile = fopen (dgl_format_str(game, me, myconfig[game]->rc_fmt, NULL), "r");
|
||||||
if (!rcfile)
|
if (!rcfile)
|
||||||
write_canned_rcfile (game, dgl_format_str(game, me, myconfig[game]->rc_fmt));
|
write_canned_rcfile (game, dgl_format_str(game, me, myconfig[game]->rc_fmt, NULL));
|
||||||
|
|
||||||
/* use whatever editor_main to edit */
|
/* use whatever editor_main to edit */
|
||||||
|
|
||||||
myargv[0] = "";
|
myargv[0] = "";
|
||||||
myargv[1] = dgl_format_str(game, me, myconfig[game]->rc_fmt);
|
myargv[1] = dgl_format_str(game, me, myconfig[game]->rc_fmt, NULL);
|
||||||
myargv[2] = 0;
|
myargv[2] = 0;
|
||||||
|
|
||||||
endwin ();
|
endwin ();
|
||||||
|
@ -1430,6 +1464,7 @@ editoptions (int game)
|
||||||
if (editor == -1)
|
if (editor == -1)
|
||||||
{
|
{
|
||||||
perror("fork");
|
perror("fork");
|
||||||
|
debug_write("edit fork failed");
|
||||||
graceful_exit(114);
|
graceful_exit(114);
|
||||||
}
|
}
|
||||||
else if (editor == 0)
|
else if (editor == 0)
|
||||||
|
@ -1472,11 +1507,13 @@ writefile (int requirenew)
|
||||||
if (!fpl)
|
if (!fpl)
|
||||||
{
|
{
|
||||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
debug_write("writefile locking failed");
|
||||||
graceful_exit (115);
|
graceful_exit (115);
|
||||||
}
|
}
|
||||||
if (fcntl (fileno (fpl), F_SETLK, &fl))
|
if (fcntl (fileno (fpl), F_SETLK, &fl))
|
||||||
{
|
{
|
||||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
debug_write("writefile fcntl failed");
|
||||||
graceful_exit (107);
|
graceful_exit (107);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,6 +1526,7 @@ writefile (int requirenew)
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
debug_write("passwd file fopen failed");
|
||||||
graceful_exit (104);
|
graceful_exit (104);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1503,6 +1541,7 @@ writefile (int requirenew)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fclose(fpl);
|
fclose(fpl);
|
||||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
debug_write("two users registering at the same time");
|
||||||
graceful_exit (111);
|
graceful_exit (111);
|
||||||
}
|
}
|
||||||
fprintf (fp, "%s:%s:%s:%s\n", me->username, me->email, me->password,
|
fprintf (fp, "%s:%s:%s:%s\n", me->username, me->email, me->password,
|
||||||
|
@ -1525,6 +1564,7 @@ writefile (int requirenew)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fclose(fpl);
|
fclose(fpl);
|
||||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
debug_write("too many users in passwd db already");
|
||||||
graceful_exit (116);
|
graceful_exit (116);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1554,6 +1594,7 @@ writefile (int requirenew)
|
||||||
ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
|
ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
debug_write("writefile sqlite3_open failed");
|
||||||
graceful_exit(107);
|
graceful_exit(107);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,6 +1605,7 @@ writefile (int requirenew)
|
||||||
|
|
||||||
if (ret != SQLITE_OK) {
|
if (ret != SQLITE_OK) {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
debug_write("writefile sqlite3_exec failed");
|
||||||
graceful_exit(106);
|
graceful_exit(106);
|
||||||
}
|
}
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
@ -1588,10 +1630,12 @@ purge_stale_locks (int game)
|
||||||
size_t len;
|
size_t len;
|
||||||
short firsttime = 1;
|
short firsttime = 1;
|
||||||
|
|
||||||
dir = strdup(dgl_format_str(game, me, myconfig[game]->inprogressdir));
|
dir = strdup(dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL));
|
||||||
|
|
||||||
if (!(pdir = opendir (dir)))
|
if (!(pdir = opendir (dir))) {
|
||||||
|
debug_write("purge_stale_locks dir open failed");
|
||||||
graceful_exit (200);
|
graceful_exit (200);
|
||||||
|
}
|
||||||
|
|
||||||
free(dir);
|
free(dir);
|
||||||
|
|
||||||
|
@ -1609,24 +1653,29 @@ purge_stale_locks (int game)
|
||||||
|
|
||||||
colon = strchr (dent->d_name, ':');
|
colon = strchr (dent->d_name, ':');
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
if (!colon)
|
if (!colon) {
|
||||||
|
debug_write("purge_stale_locks !colon");
|
||||||
graceful_exit (201);
|
graceful_exit (201);
|
||||||
|
}
|
||||||
if (colon - dent->d_name != strlen(me->username))
|
if (colon - dent->d_name != strlen(me->username))
|
||||||
continue;
|
continue;
|
||||||
if (strncmp (dent->d_name, me->username, colon - dent->d_name))
|
if (strncmp (dent->d_name, me->username, colon - dent->d_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
len = strlen (dent->d_name) + strlen(dgl_format_str(game, me, myconfig[game]->inprogressdir)) + 1;
|
len = strlen (dent->d_name) + strlen(dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL)) + 1;
|
||||||
fn = malloc (len);
|
fn = malloc (len);
|
||||||
|
|
||||||
snprintf (fn, len, "%s%s", dgl_format_str(game, me, myconfig[game]->inprogressdir), dent->d_name);
|
snprintf (fn, len, "%s%s", dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL), dent->d_name);
|
||||||
|
|
||||||
if (!(ipfile = fopen (fn, "r")))
|
if (!(ipfile = fopen (fn, "r"))) {
|
||||||
|
debug_write("purge_stale_locks fopen inprogressdir fail");
|
||||||
graceful_exit (202);
|
graceful_exit (202);
|
||||||
|
}
|
||||||
|
|
||||||
if (fgets (buf, 16, ipfile) == NULL)
|
if (fgets (buf, 16, ipfile) == NULL) {
|
||||||
|
debug_write("purge_stale_locks fgets ipfile fail");
|
||||||
graceful_exit (203);
|
graceful_exit (203);
|
||||||
|
}
|
||||||
|
|
||||||
fclose (ipfile);
|
fclose (ipfile);
|
||||||
|
|
||||||
|
@ -1692,6 +1741,7 @@ purge_stale_locks (int game)
|
||||||
endwin ();
|
endwin ();
|
||||||
fprintf (stderr, "Sorry, no %s for you now, please "
|
fprintf (stderr, "Sorry, no %s for you now, please "
|
||||||
"contact the admin.\n", myconfig[game]->game_name);
|
"contact the admin.\n", myconfig[game]->game_name);
|
||||||
|
debug_write("could not terminate stale processes");
|
||||||
graceful_exit (1);
|
graceful_exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1743,6 +1793,7 @@ runmenuloop(struct dg_menu *menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_retard(0)) {
|
if (check_retard(0)) {
|
||||||
|
debug_write("retard");
|
||||||
graceful_exit(119);
|
graceful_exit(119);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1946,8 +1997,10 @@ main (int argc, char** argv)
|
||||||
if (wall_email_str) {
|
if (wall_email_str) {
|
||||||
char *emailfrom = wall_email_str;
|
char *emailfrom = wall_email_str;
|
||||||
char *emailmsg = strchr(wall_email_str, ':');
|
char *emailmsg = strchr(wall_email_str, ':');
|
||||||
if (!emailmsg)
|
if (!emailmsg) {
|
||||||
|
debug_write("wall: no mail msg");
|
||||||
graceful_exit(117);
|
graceful_exit(117);
|
||||||
|
}
|
||||||
*emailmsg = '\0';
|
*emailmsg = '\0';
|
||||||
emailmsg++;
|
emailmsg++;
|
||||||
if (emailmsg)
|
if (emailmsg)
|
||||||
|
@ -1974,11 +2027,15 @@ main (int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* simple login routine, uses ncurses */
|
/* simple login routine, uses ncurses */
|
||||||
if (readfile (0))
|
if (readfile (0)) {
|
||||||
|
debug_write("log in fail");
|
||||||
graceful_exit (110);
|
graceful_exit (110);
|
||||||
|
}
|
||||||
|
|
||||||
if (nhauth)
|
if (nhauth) {
|
||||||
|
debug_write("nhauth");
|
||||||
graceful_exit (authenticate ());
|
graceful_exit (authenticate ());
|
||||||
|
}
|
||||||
|
|
||||||
if (auth)
|
if (auth)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct dg_config
|
||||||
char* game_name;
|
char* game_name;
|
||||||
char* shortname;
|
char* shortname;
|
||||||
char* rcfile;
|
char* rcfile;
|
||||||
|
char* ttyrecdir;
|
||||||
char* spool;
|
char* spool;
|
||||||
char* inprogressdir;
|
char* inprogressdir;
|
||||||
int num_args; /* # of bin_args */
|
int num_args; /* # of bin_args */
|
||||||
|
@ -182,7 +183,7 @@ extern void catch_sighup(int signum);
|
||||||
extern void loadbanner(char *fname, struct dg_banner *ban);
|
extern void loadbanner(char *fname, struct dg_banner *ban);
|
||||||
extern void drawbanner(struct dg_banner *ban, unsigned int start_line, unsigned int howmany);
|
extern void drawbanner(struct dg_banner *ban, unsigned int start_line, unsigned int howmany);
|
||||||
extern int check_retard(int reset);
|
extern int check_retard(int reset);
|
||||||
extern char *dgl_format_str(int game, struct dg_user *me, char *str);
|
extern char *dgl_format_str(int game, struct dg_user *me, char *str, char *plrname);
|
||||||
|
|
||||||
extern struct dg_menu *dgl_find_menu(char *menuname);
|
extern struct dg_menu *dgl_find_menu(char *menuname);
|
||||||
|
|
||||||
|
@ -190,6 +191,12 @@ extern int dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user
|
||||||
|
|
||||||
extern struct dg_game **populate_games(int game, int *l, struct dg_user *me);
|
extern struct dg_game **populate_games(int game, int *l, struct dg_user *me);
|
||||||
|
|
||||||
|
#ifdef USE_DEBUGFILE
|
||||||
|
extern void debug_write(char *str);
|
||||||
|
#else
|
||||||
|
#define debug_write(str)
|
||||||
|
#endif
|
||||||
|
|
||||||
extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode sortmode);
|
extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode sortmode);
|
||||||
|
|
||||||
int runmenuloop(struct dg_menu *menu);
|
int runmenuloop(struct dg_menu *menu);
|
||||||
|
|
76
dgl-common.c
76
dgl-common.c
|
@ -41,6 +41,7 @@ struct dg_config defconfig = {
|
||||||
/* max = */ /*64000,*/
|
/* max = */ /*64000,*/
|
||||||
/* savefilefmt = */ /*"",*/ /* don't do this by default */
|
/* savefilefmt = */ /*"",*/ /* don't do this by default */
|
||||||
/* inprogressdir = */ "%rinprogress/",
|
/* inprogressdir = */ "%rinprogress/",
|
||||||
|
NULL,
|
||||||
/* num_args = */ 0,
|
/* num_args = */ 0,
|
||||||
/* bin_args = */ NULL,
|
/* bin_args = */ NULL,
|
||||||
/* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
|
/* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
|
||||||
|
@ -86,12 +87,12 @@ dgl_find_menu(char *menuname)
|
||||||
/*
|
/*
|
||||||
* replace following codes with variables:
|
* replace following codes with variables:
|
||||||
* %u == shed_uid (number)
|
* %u == shed_uid (number)
|
||||||
* %n == user name (string)
|
* %n == user name (string; gotten from 'me', or from 'plrname' if 'me' is null)
|
||||||
* %r == chroot (string) (aka "dglroot" config var)
|
* %r == chroot (string) (aka "dglroot" config var)
|
||||||
* %g == game name
|
* %g == game name
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
dgl_format_str(int game, struct dg_user *me, char *str)
|
dgl_format_str(int game, struct dg_user *me, char *str, char *plrname)
|
||||||
{
|
{
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
char *f, *p, *end;
|
char *f, *p, *end;
|
||||||
|
@ -113,11 +114,14 @@ dgl_format_str(int game, struct dg_user *me, char *str)
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
if (me) snprintf (p, end + 1 - p, "%s", me->username);
|
if (me) snprintf (p, end + 1 - p, "%s", me->username);
|
||||||
|
else if (plrname) snprintf(p, end + 1 - p, "%s", plrname);
|
||||||
|
else return NULL;
|
||||||
while (*p != '\0')
|
while (*p != '\0')
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
if (game >= 0 && game < num_games && myconfig[game]) snprintf (p, end + 1 - p, "%s", myconfig[game]->game_name);
|
if (game >= 0 && game < num_games && myconfig[game]) snprintf (p, end + 1 - p, "%s", myconfig[game]->game_name);
|
||||||
|
else return NULL;
|
||||||
while (*p != '\0')
|
while (*p != '\0')
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
|
@ -166,8 +170,8 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
|
||||||
return_from_submenu = 0;
|
return_from_submenu = 0;
|
||||||
|
|
||||||
while (tmp && !return_from_submenu) {
|
while (tmp && !return_from_submenu) {
|
||||||
if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1));
|
if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1, NULL));
|
||||||
if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2));
|
if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2, NULL));
|
||||||
|
|
||||||
switch (tmp->cmd) {
|
switch (tmp->cmd) {
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -222,6 +226,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
|
||||||
child = fork();
|
child = fork();
|
||||||
if (child == -1) {
|
if (child == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
|
debug_write("exec-command fork failed");
|
||||||
graceful_exit(114);
|
graceful_exit(114);
|
||||||
} else if (child == 0) {
|
} else if (child == 0) {
|
||||||
execvp(p1, myargv);
|
execvp(p1, myargv);
|
||||||
|
@ -252,6 +257,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
|
||||||
if (!loggedin && globalconfig.allow_registration) newuser();
|
if (!loggedin && globalconfig.allow_registration) newuser();
|
||||||
break;
|
break;
|
||||||
case DGLCMD_QUIT:
|
case DGLCMD_QUIT:
|
||||||
|
debug_write("command: quit");
|
||||||
graceful_exit(0);
|
graceful_exit(0);
|
||||||
/* break; */
|
/* break; */
|
||||||
case DGLCMD_SUBMENU:
|
case DGLCMD_SUBMENU:
|
||||||
|
@ -281,8 +287,8 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
|
||||||
if (!strcmp(myconfig[userchoice]->game_name, p1) || !strcmp(myconfig[userchoice]->shortname, p1)) {
|
if (!strcmp(myconfig[userchoice]->game_name, p1) || !strcmp(myconfig[userchoice]->shortname, p1)) {
|
||||||
if (purge_stale_locks(userchoice)) {
|
if (purge_stale_locks(userchoice)) {
|
||||||
if (myconfig[userchoice]->rcfile) {
|
if (myconfig[userchoice]->rcfile) {
|
||||||
if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt), R_OK) == -1)
|
if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL), R_OK) == -1)
|
||||||
write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt));
|
write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname);
|
setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname);
|
||||||
|
@ -297,13 +303,15 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
|
||||||
|
|
||||||
/* fix the variables in the arguments */
|
/* fix the variables in the arguments */
|
||||||
for (i = 0; i < myconfig[userchoice]->num_args; i++) {
|
for (i = 0; i < myconfig[userchoice]->num_args; i++) {
|
||||||
tmpstr = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i]));
|
tmpstr = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i], NULL));
|
||||||
free(myconfig[userchoice]->bin_args[i]);
|
free(myconfig[userchoice]->bin_args[i]);
|
||||||
myconfig[userchoice]->bin_args[i] = tmpstr;
|
myconfig[userchoice]->bin_args[i] = tmpstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* launch program */
|
/* launch program */
|
||||||
ttyrec_main (userchoice, me->username, dgl_format_str(userchoice, me, "%ruserdata/%n/ttyrec"), gen_ttyrec_filename());
|
ttyrec_main (userchoice, me->username,
|
||||||
|
dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL),
|
||||||
|
gen_ttyrec_filename());
|
||||||
|
|
||||||
/* lastly, run the generic "do these when a game is left" commands */
|
/* lastly, run the generic "do these when a game is left" commands */
|
||||||
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMEEND], userchoice, me);
|
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMEEND], userchoice, me);
|
||||||
|
@ -359,6 +367,19 @@ sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_DEBUGFILE
|
||||||
|
void
|
||||||
|
debug_write(char *str)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
fp = fopen("/dgldebug.log", "a");
|
||||||
|
if (!fp) return;
|
||||||
|
fprintf(fp, "%s\n", str);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* USE_DEBUGFILE */
|
||||||
|
|
||||||
struct dg_game **
|
struct dg_game **
|
||||||
populate_games (int xgame, int *l, struct dg_user *me)
|
populate_games (int xgame, int *l, struct dg_user *me)
|
||||||
{
|
{
|
||||||
|
@ -382,19 +403,27 @@ populate_games (int xgame, int *l, struct dg_user *me)
|
||||||
|
|
||||||
for (game = ((xgame < 0) ? 0 : xgame); game < ((xgame <= 0) ? num_games : (xgame+1)); game++) {
|
for (game = ((xgame < 0) ? 0 : xgame); game < ((xgame <= 0) ? num_games : (xgame+1)); game++) {
|
||||||
|
|
||||||
dir = strdup(dgl_format_str(game, me, myconfig[game]->inprogressdir));
|
dir = strdup(dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL));
|
||||||
|
if (!dir) continue;
|
||||||
|
|
||||||
if (!(pdir = opendir (dir)))
|
if (!(pdir = opendir (dir))) {
|
||||||
graceful_exit (140);
|
debug_write("cannot open inprogress-dir");
|
||||||
|
graceful_exit (140);
|
||||||
|
}
|
||||||
|
|
||||||
while ((pdirent = readdir (pdir)))
|
while ((pdirent = readdir (pdir)))
|
||||||
{
|
{
|
||||||
|
char *inprog = NULL;
|
||||||
if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
|
if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
is_nhext = !strcmp (pdirent->d_name + strlen (pdirent->d_name) - 6, ".nhext");
|
is_nhext = !strcmp (pdirent->d_name + strlen (pdirent->d_name) - 6, ".nhext");
|
||||||
|
|
||||||
snprintf (fullname, 130, "%s%s", dgl_format_str(game, me, myconfig[game]->inprogressdir), pdirent->d_name);
|
inprog = dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL);
|
||||||
|
|
||||||
|
if (!inprog) continue;
|
||||||
|
|
||||||
|
snprintf (fullname, 130, "%s%s", inprog, pdirent->d_name);
|
||||||
|
|
||||||
fd = 0;
|
fd = 0;
|
||||||
/* O_RDWR here should be O_RDONLY, but we need to test for
|
/* O_RDWR here should be O_RDONLY, but we need to test for
|
||||||
|
@ -406,15 +435,22 @@ populate_games (int xgame, int *l, struct dg_user *me)
|
||||||
/* stat to check idle status */
|
/* stat to check idle status */
|
||||||
if (!is_nhext)
|
if (!is_nhext)
|
||||||
{
|
{
|
||||||
|
char *ttrecdir = NULL;
|
||||||
strncpy(playername, pdirent->d_name, 29);
|
strncpy(playername, pdirent->d_name, 29);
|
||||||
playername[29] = '\0';
|
playername[29] = '\0';
|
||||||
if ((replacestr = strchr(playername, ':')))
|
if ((replacestr = strchr(playername, ':')))
|
||||||
*replacestr = '\0';
|
*replacestr = '\0';
|
||||||
|
|
||||||
replacestr = strchr(pdirent->d_name, ':');
|
replacestr = strchr(pdirent->d_name, ':');
|
||||||
if (!replacestr) graceful_exit(145);
|
if (!replacestr) {
|
||||||
|
debug_write("inprogress-filename does not have ':'");
|
||||||
|
graceful_exit(145);
|
||||||
|
}
|
||||||
replacestr++;
|
replacestr++;
|
||||||
snprintf (ttyrecname, 130, "%suserdata/%s/ttyrec/%s", globalconfig.dglroot, playername, replacestr);
|
|
||||||
|
ttrecdir = dgl_format_str(game, me, myconfig[game]->ttyrecdir, playername);
|
||||||
|
if (!ttrecdir) continue;
|
||||||
|
snprintf (ttyrecname, 130, "%s%s", ttrecdir, replacestr);
|
||||||
}
|
}
|
||||||
if (is_nhext || !stat (ttyrecname, &pstat))
|
if (is_nhext || !stat (ttyrecname, &pstat))
|
||||||
{
|
{
|
||||||
|
@ -423,9 +459,10 @@ populate_games (int xgame, int *l, struct dg_user *me)
|
||||||
games[len] = malloc (sizeof (struct dg_game));
|
games[len] = malloc (sizeof (struct dg_game));
|
||||||
games[len]->ttyrec_fn = strdup (ttyrecname);
|
games[len]->ttyrec_fn = strdup (ttyrecname);
|
||||||
|
|
||||||
if (!(replacestr = strchr (pdirent->d_name, ':')))
|
if (!(replacestr = strchr (pdirent->d_name, ':'))) {
|
||||||
graceful_exit (146);
|
debug_write("inprogress-filename does not have ':', pt. 2");
|
||||||
else
|
graceful_exit (146);
|
||||||
|
} else
|
||||||
*replacestr = '\0';
|
*replacestr = '\0';
|
||||||
|
|
||||||
games[len]->name = malloc (strlen (pdirent->d_name) + 1);
|
games[len]->name = malloc (strlen (pdirent->d_name) + 1);
|
||||||
|
@ -547,6 +584,7 @@ create_config ()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
|
fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
|
||||||
|
debug_write("cannot read config file");
|
||||||
graceful_exit(104);
|
graceful_exit(104);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -562,7 +600,8 @@ create_config ()
|
||||||
fclose(config_file);
|
fclose(config_file);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
|
fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
|
||||||
graceful_exit(104);
|
debug_write("cannot read default config file");
|
||||||
|
graceful_exit(105);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -576,6 +615,7 @@ create_config ()
|
||||||
if (!myconfig) /* a parse error occurred */
|
if (!myconfig) /* a parse error occurred */
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: configuration parsing failed\n");
|
fprintf(stderr, "ERROR: configuration parsing failed\n");
|
||||||
|
debug_write("config file parsing failed");
|
||||||
graceful_exit(113);
|
graceful_exit(113);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,11 @@ DEFINE {
|
||||||
|
|
||||||
inprogressdir = "%rinprogress-nh343/"
|
inprogressdir = "%rinprogress-nh343/"
|
||||||
|
|
||||||
|
# The place where ttyrecs are stored for this game.
|
||||||
|
# If this is not defined, ttyrecs are not saved for this game.
|
||||||
|
# Leaving this undefined also means the games cannot be spectated.
|
||||||
|
ttyrecdir = "%ruserdata/%n/ttyrec/"
|
||||||
|
|
||||||
|
|
||||||
# back up savefile
|
# back up savefile
|
||||||
commands = cp "/nh343/var/save/%u%n.gz" "/nh343/var/save/%u%n.gz.bak",
|
commands = cp "/nh343/var/save/%u%n.gz" "/nh343/var/save/%u%n.gz.bak",
|
||||||
|
|
15
ttyrec.c
15
ttyrec.c
|
@ -91,6 +91,21 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
|
||||||
|
|
||||||
child = subchild = input_child = 0;
|
child = subchild = input_child = 0;
|
||||||
|
|
||||||
|
if (!ttyrec_path) {
|
||||||
|
child = fork();
|
||||||
|
if (child < 0) {
|
||||||
|
perror ("fork");
|
||||||
|
fail ();
|
||||||
|
}
|
||||||
|
if (child == 0) {
|
||||||
|
execvp (myconfig[game]->game_path, myconfig[game]->bin_args);
|
||||||
|
} else {
|
||||||
|
int status;
|
||||||
|
(void) wait(&status);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ttyrec_path[strlen(ttyrec_path)-1] == '/')
|
if (ttyrec_path[strlen(ttyrec_path)-1] == '/')
|
||||||
snprintf (dirname, 100, "%s%s", ttyrec_path, ttyrec_filename);
|
snprintf (dirname, 100, "%s%s", ttyrec_path, ttyrec_filename);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue