]> skyeroc.xyz Git - dgamelaunch/commitdiff
Add per-game configurable ttyrec-dir; If it's not defined for some game,
authorPasi Kallinen <paxed@alt.org>
Sat, 17 Oct 2009 20:26:56 +0000 (20:26 +0000)
committerPasi Kallinen <paxed@alt.org>
Sat, 17 Oct 2009 20:26:56 +0000 (20:26 +0000)
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

config.l
config.y
configure.ac
dgamelaunch.c
dgamelaunch.h
dgl-common.c
examples/dgamelaunch.conf
ttyrec.c

index 8ffd76bfc5968e083ffeda61d0d3f2851b4627ea..e94f2522b859dbdf9edfda722ccc6dbdbd626ce6 100644 (file)
--- a/config.l
+++ b/config.l
@@ -83,6 +83,7 @@ cursor                { return TYPE_CURSOR; }
 "inprogressdir" { return TYPE_PATH_INPROGRESS; }
 "game_args"    { return TYPE_GAME_ARGS; }
 "rc_fmt"       { return TYPE_RC_FMT; }
+"ttyrecdir"    { return TYPE_PATH_TTYREC; }
 server_id      { return TYPE_SERVER_ID; }
 sortmode       { return TYPE_WATCH_SORTMODE; }
 commands       { return TYPE_CMDQUEUE; }
index 9474bd09d9bbe2fb655b7e002ce81e075750ed12..065a783889528f7f316d2b3be2bb634e6b11be37 100644 (file)
--- a/config.y
+++ b/config.y
@@ -38,7 +38,7 @@ static const char* lookup_token (int t);
 %token TYPE_ALLOW_REGISTRATION
 %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_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_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR
 %token <s> TYPE_VALUE
@@ -364,6 +364,11 @@ game_definition : TYPE_CMDQUEUE
                myconfig[ncnf]->spool = strdup($3);
                break;
 
+           case TYPE_PATH_TTYREC:
+               if (myconfig[ncnf]->ttyrecdir) free(myconfig[ncnf]->ttyrecdir);
+               myconfig[ncnf]->ttyrecdir = strdup($3);
+               break;
+
            case TYPE_PATH_GAME:
                if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
                myconfig[ncnf]->game_path = strdup ($3);
@@ -519,6 +524,7 @@ KeyType : TYPE_SUSER        { $$ = TYPE_SUSER; }
        | TYPE_PATH_SPOOL       { $$ = TYPE_PATH_SPOOL; }
        | TYPE_PATH_BANNER      { $$ = TYPE_PATH_BANNER; }
        | TYPE_PATH_CANNED      { $$ = TYPE_PATH_CANNED; }
+       | TYPE_PATH_TTYREC      { $$ = TYPE_PATH_TTYREC; }
        | TYPE_PATH_PASSWD      { $$ = TYPE_PATH_PASSWD; }
        | TYPE_PATH_LOCKFILE    { $$ = TYPE_PATH_LOCKFILE; }
        | 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_BANNER: return "banner";
     case TYPE_PATH_CANNED: return "rc_template";
+    case TYPE_PATH_TTYREC: return "ttyrecdir";
     case TYPE_PATH_INPROGRESS: return "inprogressdir";
     case TYPE_GAME_ARGS: return "game_args";
     case TYPE_RC_FMT: return "rc_fmt";
index fab5ca113f5756b8395124f45f3c92c3bc7b995c..b5b8b85ab0d808516ad46484e1d3c9ea20b257dc 100644 (file)
@@ -72,6 +72,16 @@ AC_ARG_ENABLE(enable-virus,
 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_HELP_STRING([--enable-sqlite], [Use SQLite for the database instead of flat text file.])],
 [], [])
index 07b1e4807821c3d4befec1cd9bec2934a9181adb..4297ac9952d2a81aadab51698afaeadb3b93d11e 100644 (file)
@@ -149,15 +149,20 @@ void
 ttyrec_getpty ()
 {
 #ifdef HAVE_OPENPTY
-  if (openpty (&master, &slave, NULL, NULL, NULL) == -1)
-    graceful_exit (62);
+    if (openpty (&master, &slave, NULL, NULL, NULL) == -1) {
+       debug_write("cannot openpty");
+       graceful_exit (62);
+    }
 #else
-  if ((master = open ("/dev/ptmx", O_RDWR)) < 0)
-    graceful_exit (62);
+    if ((master = open ("/dev/ptmx", O_RDWR)) < 0) {
+       debug_write("cannot open /dev/ptmx");
+       graceful_exit (62);
+    }
   grantpt (master);
   unlockpt (master);
   if ((slave = open ((const char *) ptsname (master), O_RDWR)) < 0)
     {
+       debug_write("cannot open master ptsname");
       graceful_exit (65);
     }
 #endif
@@ -219,15 +224,17 @@ gen_inprogress_lock (int game, pid_t pid, char* ttyrec_filename)
   fl.l_start = 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));
 
-  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);
 
   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);
+  }
 
   write (fd, filebuf, strlen (filebuf));
 
@@ -245,6 +252,7 @@ catch_sighup (int signum)
       kill (child, SIGHUP);
       sleep (5);
     }
+  debug_write("catchup sighup");
   graceful_exit (2);
 }
 
@@ -478,8 +486,10 @@ inprogressmenu (int gameid)
               /* reuse the char* */
               replacestr = strchr (ttyrecname, ':');
 
-              if (!replacestr)
+              if (!replacestr) {
+                 debug_write("inprogressmenu replacestr");
                 graceful_exit (145);
+             }
 
               /*replacestr[0] = '/';*/
 
@@ -622,8 +632,10 @@ changepw (int dowrite)
   int error = 2;
 
   /* 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. */
+  }
 
   while (error)
     {
@@ -656,8 +668,10 @@ changepw (int dowrite)
       if (*buf == '\0')
         return 0;
 
-      if (strchr (buf, ':') != NULL)
+      if (strchr (buf, ':') != NULL) {
+         debug_write("cannot have ':' in passwd");
         graceful_exit (112);
+      }
 
       mvaddstr (12, 1, "And again:");
       mvaddstr (13, 1, "=> ");
@@ -700,11 +714,13 @@ wall_email(char *from, char *msg)
 
     if (strlen(from) < 1) {
        fprintf(stderr, "Error: wall: 'from' username is too short!\n");
+       debug_write("wall: 'from' username too short");
        graceful_exit(121);
     }
 
     if (strlen(msg) >= 80) {
        fprintf(stderr, "Error: wall: message too long!\n");
+       debug_write("wall: message too long");
        graceful_exit(120);
     }
 
@@ -712,6 +728,7 @@ wall_email(char *from, char *msg)
 
     if (len == 0) {
        fprintf(stderr, "Error: wall: no one's logged in!\n");
+       debug_write("wall: no people playing");
        graceful_exit(118);
     }
 
@@ -1162,15 +1179,21 @@ readfile (int nolock)
   if (!nolock)
     {
       fpl = fopen (globalconfig.lockfile, "r");
-      if (!fpl)
+      if (!fpl) {
+         debug_write("cannot fopen lockfile");
         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);
+      }
     }
 
   fp = fopen (globalconfig.passwd, "r");
-  if (!fp)
+  if (!fp) {
+      debug_write("cannot fopen passwd file");
     graceful_exit (106);
+  }
 
   /* once per name in the file */
   while (fgets (buf, 1200, fp))
@@ -1191,8 +1214,10 @@ readfile (int nolock)
             return 1;
           users[f_num]->username[(b - n)] = *b;
           b++;
-          if ((b - n) >= 21)
+          if ((b - n) >= 21) {
+             debug_write("name field too long");
             graceful_exit (100);
+         }
         }
 
       /* advance to next field */
@@ -1204,8 +1229,10 @@ readfile (int nolock)
         {
           users[f_num]->email[(b - n)] = *b;
           b++;
-          if ((b - n) > 80)
+          if ((b - n) > 80) {
+             debug_write("email field too long");
             graceful_exit (101);
+         }
         }
 
       /* advance to next field */
@@ -1217,8 +1244,10 @@ readfile (int nolock)
         {
           users[f_num]->password[(b - n)] = *b;
           b++;
-          if ((b - n) >= 20)
+          if ((b - n) >= 20) {
+             debug_write("passwd field too long");
             graceful_exit (102);
+         }
         }
 
       /* advance to next field */
@@ -1230,8 +1259,10 @@ readfile (int nolock)
         {
           users[f_num]->env[(b - n)] = *b;
           b++;
-          if ((b - n) >= 1024)
+          if ((b - n) >= 1024) {
+             debug_write("env field too long");
             graceful_exit (102);
+         }
         }
 
       f_num++;
@@ -1239,6 +1270,7 @@ readfile (int nolock)
       if (f_num > globalconfig.max)
       {
        fprintf(stderr,"ERROR: number of users in database exceeds maximum. Exiting.\n");
+       debug_write("too many users in database");
         graceful_exit (109);
       }
     }
@@ -1329,6 +1361,7 @@ userexist (char *cname, int isnew)
     ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
     if (ret) {
        sqlite3_close(db);
+       debug_write("sqlite3_open failed");
        graceful_exit(109);
     }
 
@@ -1348,6 +1381,7 @@ userexist (char *cname, int isnew)
 
     if (ret != SQLITE_OK) {
        sqlite3_close(db);
+       debug_write("sqlite3_exec failed");
        graceful_exit(108);
     }
     sqlite3_close(db);
@@ -1413,14 +1447,14 @@ editoptions (int game)
   char *myargv[3];
   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)
-      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 */
 
   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;
 
   endwin ();
@@ -1430,6 +1464,7 @@ editoptions (int game)
   if (editor == -1)
   {
     perror("fork");
+    debug_write("edit fork failed");
     graceful_exit(114);
   }
   else if (editor == 0)
@@ -1472,11 +1507,13 @@ writefile (int requirenew)
   if (!fpl)
     {
       sigprocmask(SIG_SETMASK, &oldmask, NULL);
+      debug_write("writefile locking failed");
       graceful_exit (115);
     }
   if (fcntl (fileno (fpl), F_SETLK, &fl))
     {
       sigprocmask(SIG_SETMASK, &oldmask, NULL);
+      debug_write("writefile fcntl failed");
       graceful_exit (107);
     }
 
@@ -1489,6 +1526,7 @@ writefile (int requirenew)
   if (!fp)
     {
       sigprocmask(SIG_SETMASK, &oldmask, NULL);
+      debug_write("passwd file fopen failed");
       graceful_exit (104);
     }
 
@@ -1503,6 +1541,7 @@ writefile (int requirenew)
              fclose(fp);
              fclose(fpl);
               sigprocmask(SIG_SETMASK, &oldmask, NULL);
+             debug_write("two users registering at the same time");
               graceful_exit (111);
             }
           fprintf (fp, "%s:%s:%s:%s\n", me->username, me->email, me->password,
@@ -1525,6 +1564,7 @@ writefile (int requirenew)
           fclose(fp);
          fclose(fpl);
           sigprocmask(SIG_SETMASK, &oldmask, NULL);
+         debug_write("too many users in passwd db already");
           graceful_exit (116);
        }
     }
@@ -1554,6 +1594,7 @@ writefile (int requirenew)
     ret = sqlite3_open(USE_SQLITE_DB, &db); /* FIXME: use globalconfig->passwd? */
     if (ret) {
        sqlite3_close(db);
+       debug_write("writefile sqlite3_open failed");
        graceful_exit(107);
     }
 
@@ -1564,6 +1605,7 @@ writefile (int requirenew)
 
     if (ret != SQLITE_OK) {
        sqlite3_close(db);
+       debug_write("writefile sqlite3_exec failed");
        graceful_exit(106);
     }
     sqlite3_close(db);
@@ -1588,10 +1630,12 @@ purge_stale_locks (int game)
   size_t len;
   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);
+  }
 
   free(dir);
 
@@ -1609,24 +1653,29 @@ purge_stale_locks (int game)
 
       colon = strchr (dent->d_name, ':');
       /* should never happen */
-      if (!colon)
+      if (!colon) {
+         debug_write("purge_stale_locks !colon");
         graceful_exit (201);
-
+      }
       if (colon - dent->d_name != strlen(me->username))
         continue;
       if (strncmp (dent->d_name, me->username, colon - dent->d_name))
         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);
 
-      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);
+      }
 
-      if (fgets (buf, 16, ipfile) == NULL)
+      if (fgets (buf, 16, ipfile) == NULL) {
+         debug_write("purge_stale_locks fgets ipfile fail");
         graceful_exit (203);
+      }
 
       fclose (ipfile);
 
@@ -1692,6 +1741,7 @@ purge_stale_locks (int game)
                   endwin ();
                   fprintf (stderr, "Sorry, no %s for you now, please "
                            "contact the admin.\n", myconfig[game]->game_name);
+                 debug_write("could not terminate stale processes");
                   graceful_exit (1);
                 }
             }
@@ -1743,6 +1793,7 @@ runmenuloop(struct dg_menu *menu)
        }
 
        if (check_retard(0)) {
+           debug_write("retard");
            graceful_exit(119);
        }
     }
@@ -1946,8 +1997,10 @@ main (int argc, char** argv)
   if (wall_email_str) {
       char *emailfrom = wall_email_str;
       char *emailmsg = strchr(wall_email_str, ':');
-      if (!emailmsg)
+      if (!emailmsg) {
+         debug_write("wall: no mail msg");
          graceful_exit(117);
+      }
       *emailmsg = '\0';
       emailmsg++;
       if (emailmsg)
@@ -1974,11 +2027,15 @@ main (int argc, char** argv)
     }
 
   /* simple login routine, uses ncurses */
-  if (readfile (0))
+  if (readfile (0)) {
+      debug_write("log in fail");
     graceful_exit (110);
+  }
 
-  if (nhauth)
+  if (nhauth) {
+      debug_write("nhauth");
     graceful_exit (authenticate ());
+  }
 
   if (auth)
   {
index 3a6fe193c04630ad80df741753dd7aebafafc725..7872fc99eb9f3a05e09b7f1a5baa3425e399e206 100644 (file)
@@ -89,6 +89,7 @@ struct dg_config
   char* game_name;
   char* shortname;
   char* rcfile;
+  char* ttyrecdir;
   char* spool;
   char* inprogressdir;
     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 drawbanner(struct dg_banner *ban, unsigned int start_line, unsigned int howmany);
 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);
 
@@ -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);
 
+#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);
 
 int runmenuloop(struct dg_menu *menu);
index 3647ab59f04e90381fafbc69f6077d7bec1db473..b4aca6df9c1509dc668940b3685cb4f4a10787f0 100644 (file)
@@ -41,6 +41,7 @@ struct dg_config defconfig = {
   /* max = */ /*64000,*/
   /* savefilefmt = */ /*"",*/ /* don't do this by default */
   /* inprogressdir = */ "%rinprogress/",
+  NULL,
   /* num_args = */ 0,
   /* bin_args = */ NULL,
   /* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
@@ -86,12 +87,12 @@ dgl_find_menu(char *menuname)
 /*
  * replace following codes with variables:
  * %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)
  * %g == game name
  */
 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];
     char *f, *p, *end;
@@ -113,11 +114,14 @@ dgl_format_str(int game, struct dg_user *me, char *str)
                break;
            case 'n':
                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')
                    p++;
                break;
            case 'g':
                if (game >= 0 && game < num_games && myconfig[game]) snprintf (p, end + 1 - p, "%s", myconfig[game]->game_name);
+               else return NULL;
                while (*p != '\0')
                    p++;
                break;
@@ -166,8 +170,8 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
     return_from_submenu = 0;
 
     while (tmp && !return_from_submenu) {
-       if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1));
-       if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2));
+       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, NULL));
 
        switch (tmp->cmd) {
        default: break;
@@ -222,6 +226,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
                child = fork();
                if (child == -1) {
                    perror("fork");
+                   debug_write("exec-command fork failed");
                    graceful_exit(114);
                } else if (child == 0) {
                    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();
            break;
        case DGLCMD_QUIT:
+           debug_write("command: quit");
            graceful_exit(0);
            /* break; */
        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 (purge_stale_locks(userchoice)) {
                            if (myconfig[userchoice]->rcfile) {
-                               if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt), R_OK) == -1)
-                                   write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt));
+                               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, NULL));
                            }
 
                            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 */
                            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]);
                                myconfig[userchoice]->bin_args[i] = tmpstr;
                            }
 
                            /* 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 */
                            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;
 }
 
+#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 **
 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++) {
 
-   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)))
-    graceful_exit (140);
+      if (!(pdir = opendir (dir))) {
+         debug_write("cannot open inprogress-dir");
+         graceful_exit (140);
+      }
 
    while ((pdirent = readdir (pdir)))
     {
+       char *inprog = NULL;
       if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
         continue;
 
       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;
       /* 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 */
          if (!is_nhext)
            {
+               char *ttrecdir = NULL;
                strncpy(playername, pdirent->d_name, 29);
                playername[29] = '\0';
                if ((replacestr = strchr(playername, ':')))
                    *replacestr = '\0';
 
               replacestr = strchr(pdirent->d_name, ':');
-              if (!replacestr) graceful_exit(145);
+              if (!replacestr) {
+                 debug_write("inprogress-filename does not have ':'");
+                 graceful_exit(145);
+             }
               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))
             {
@@ -423,9 +459,10 @@ populate_games (int xgame, int *l, struct dg_user *me)
               games[len] = malloc (sizeof (struct dg_game));
               games[len]->ttyrec_fn = strdup (ttyrecname);
 
-              if (!(replacestr = strchr (pdirent->d_name, ':')))
-                graceful_exit (146);
-              else
+              if (!(replacestr = strchr (pdirent->d_name, ':'))) {
+                 debug_write("inprogress-filename does not have ':', pt. 2");
+                 graceful_exit (146);
+              } else
                 *replacestr = '\0';
 
               games[len]->name = malloc (strlen (pdirent->d_name) + 1);
@@ -547,6 +584,7 @@ create_config ()
     else
     {
       fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
+      debug_write("cannot read config file");
       graceful_exit(104);
       return;
     }
@@ -562,7 +600,8 @@ create_config ()
       fclose(config_file);
     } else {
        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;
     }
 #else
@@ -576,6 +615,7 @@ create_config ()
   if (!myconfig) /* a parse error occurred */
   {
       fprintf(stderr, "ERROR: configuration parsing failed\n");
+      debug_write("config file parsing failed");
       graceful_exit(113);
   }
 
index 6a33d2d3b604dd0a03beb1ea979486918ad3f0a8..c40a32c1962b007c6eb2e7187d3c25ad2d63ba3c 100644 (file)
@@ -213,6 +213,11 @@ DEFINE {
 
   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
   commands = cp "/nh343/var/save/%u%n.gz" "/nh343/var/save/%u%n.gz.bak",
index 9e348a70e1866b86ce08a875a778d0d95fa472e7..28af7e37cff06169e5caeb5866067572f48fc1be 100644 (file)
--- a/ttyrec.c
+++ b/ttyrec.c
@@ -91,6 +91,21 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
 
   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] == '/')
       snprintf (dirname, 100, "%s%s", ttyrec_path, ttyrec_filename);
   else