]> skyeroc.xyz Git - dgamelaunch/commitdiff
Define menu_max_idle_time option to kill dgl when the user idles too long. From...
authorPasi Kallinen <paxed@alt.org>
Tue, 2 Mar 2010 18:32:57 +0000 (18:32 +0000)
committerPasi Kallinen <paxed@alt.org>
Tue, 2 Mar 2010 18:32:57 +0000 (18:32 +0000)
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@531 db0b04b0-f4d1-0310-9a6d-de3e77497b0e

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

index 17061af6c658ec16fd7a9cbc7d114d303f9dbb48..b5e7b53cf813a46561f9c2548014c8453f706480 100644 (file)
--- a/config.l
+++ b/config.l
@@ -65,6 +65,7 @@ WHITE         [\t ]*
 "maxusers"     { return TYPE_MAX; }
 "maxnicklen"   { return TYPE_MAXNICKLEN; }
 "allow_new_nicks"      { return TYPE_ALLOW_REGISTRATION; }
+"menu_max_idle_time"   { return TYPE_MENU_MAX_IDLE_TIME; }
 
 
 menu           { return TYPE_DEFINE_MENU; }
index e10b990e1359488b040303b161989d49c113f8d4..77d8b13e793c85d2091e76c08767571d473c9c1a 100644 (file)
--- a/config.y
+++ b/config.y
@@ -41,7 +41,7 @@ static const char* lookup_token (int t);
 %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 TYPE_MAX_IDLE_TIME
+%token TYPE_MAX_IDLE_TIME TYPE_MENU_MAX_IDLE_TIME
 %token <s> TYPE_VALUE
 %token <i> TYPE_NUMBER TYPE_CMDQUEUENAME
 %type  <kt> KeyType
@@ -252,6 +252,10 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']'
       }
       break;
 
+  case TYPE_MENU_MAX_IDLE_TIME:
+      globalconfig.menu_max_idle_time = $3;
+      break;
+
     default:
       fprintf(stderr, "%s:%d: token %s does not take a number, bailing out\n",
         config, line, lookup_token($1)); 
@@ -524,6 +528,7 @@ KeyType : TYPE_SUSER        { $$ = TYPE_SUSER; }
        | TYPE_SGID     { $$ = TYPE_SGID; }
        | TYPE_MAX      { $$ = TYPE_MAX; }
        | TYPE_MAXNICKLEN       { $$ = TYPE_MAXNICKLEN; }
+        | TYPE_MENU_MAX_IDLE_TIME      { $$ = TYPE_MENU_MAX_IDLE_TIME; }
        | TYPE_PATH_CHROOT      { $$ = TYPE_PATH_CHROOT; }
        | TYPE_ALLOW_REGISTRATION       { $$ = TYPE_ALLOW_REGISTRATION; }
        | TYPE_PATH_GAME        { $$ = TYPE_PATH_GAME; }
@@ -554,6 +559,7 @@ const char* lookup_token (int t)
     case TYPE_SGID: return "shed_gid";
     case TYPE_MAX: return "maxusers";
     case TYPE_MAXNICKLEN: return "maxnicklen";
+    case TYPE_MENU_MAX_IDLE_TIME: return "menu_max_idle_time";
     case TYPE_PATH_CHROOT: return "chroot_path";
     case TYPE_PATH_GAME: return "game_path";
     case TYPE_NAME_GAME: return "game_name";
index 244ebd1e311ffa27ca6c05ed5fa230a78f678621..53c8e6e635491b4f2eb1d11d13b5d61984fef92f 100644 (file)
@@ -96,6 +96,7 @@ extern int editor_main (int argc, char **argv);
 /* global variables */
 
 char * __progname;
+int  g_idle_alarm_enabled = 0;
 
 #ifndef USE_SQLITE3
 int f_num = 0;
@@ -261,6 +262,42 @@ catch_sighup (int signum)
 
 /* ************************************************************* */
 
+int
+dgl_getch(void)
+{
+    const int c = getch();
+    idle_alarm_reset();
+    return c;
+}
+
+/* ************************************************************* */
+
+static void
+dgl_idle_kill(int signal)
+{
+    kill(0, SIGHUP);
+}
+
+void
+idle_alarm_set_enabled(int enabled)
+{
+    signal(SIGALRM, SIG_IGN);
+    g_idle_alarm_enabled = enabled;
+    idle_alarm_reset();
+    if (enabled)
+        signal(SIGALRM, dgl_idle_kill);
+}
+
+void
+idle_alarm_reset(void)
+{
+    if (g_idle_alarm_enabled && globalconfig.menu_max_idle_time > 0)
+        alarm(globalconfig.menu_max_idle_time);
+}
+
+/* ************************************************************* */
+
+
 char *
 bannerstrmangle(char *buf, char *fromstr, char *tostr)
 {
@@ -499,7 +536,7 @@ inprogressmenu (int gameid)
 
       refresh ();
 
-      switch ((menuchoice = getch ()))
+      switch ((menuchoice = dgl_getch ()))
         {
        case '*':
            if (len > 0) {
@@ -717,7 +754,7 @@ change_email ()
     else if (check_email (buf))
     {
       mvprintw (8, 1, "Changing email address to '%s'. Confirm (y/n): ", buf);
-      if (getch() == 'y')
+      if (dgl_getch() == 'y')
       {
        free(me->email);
        me->email = strdup(buf);
@@ -727,7 +764,7 @@ change_email ()
       else
       {
        mvaddstr(9, 1, "No changes made. Press any key to continue...");
-       getch();
+       dgl_getch();
        return;
       }
     }
@@ -915,7 +952,7 @@ domailuser (char *username)
       mvaddstr (9, 1, "This scroll appears to be blank.");
       mvaddstr (10, 1, "(Aborting your message.)");
       mvaddstr (12, 1, "--More--");
-      getch ();
+      dgl_getch ();
       return;
     }
 
@@ -927,7 +964,7 @@ domailuser (char *username)
                 "(Couldn't open %s'%c spool file.  Aborting.)",
                 username, (username[strlen (username) - 1] != 's') ? 's' : 0);
       mvaddstr (12, 1, "--More--");
-      getch ();
+      dgl_getch ();
       return;
     }
 
@@ -942,7 +979,7 @@ domailuser (char *username)
           mvaddstr (10, 1,
                     "(Received a weird error from fcntl.  Aborting.)");
          mvaddstr (12, 1, "--More--");
-          getch ();
+          dgl_getch ();
           return;
         }
       sleep (1);
@@ -1125,7 +1162,7 @@ newuser ()
       mvaddstr (5, 1, "Sorry, too many users have registered now.");
       mvaddstr (6, 1, "You might email the server administrator.");
       mvaddstr (7, 1, "Press return to return to the menu. ");
-      getch ();
+      dgl_getch ();
 
       return;
   }
@@ -1811,7 +1848,7 @@ purge_stale_locks (int game)
 
        for (seconds = HUP_WAIT - 1; seconds >= 0; seconds--)
        {
-         if (getch() != ERR)
+         if (dgl_getch() != ERR)
          {
            nocbreak(); /* leave half-delay */
            cbreak();
@@ -1846,7 +1883,7 @@ purge_stale_locks (int game)
               mvprintw (3, 1,
                         "Couldn't terminate one of your stale %s processes gracefully.", myconfig[game]->game_name);
               mvaddstr (4, 1, "Force its termination? [yn] ");
-              if (tolower (getch ()) == 'y')
+              if (tolower (dgl_getch ()) == 'y')
                 {
                   kill (pid, SIGTERM);
                   break;
@@ -1885,6 +1922,7 @@ runmenuloop(struct dg_menu *menu)
     ban.lines = NULL;
     ban.len = 0;
 
+    idle_alarm_set_enabled(1);
     loadbanner(menu->banner_fn, &ban);
     while (1) {
        if (doclear) {
@@ -1895,7 +1933,7 @@ runmenuloop(struct dg_menu *menu)
        if (menu->cursor_x >= 0 && menu->cursor_y >= 0)
            mvprintw(menu->cursor_y, menu->cursor_x, "");
        refresh();
-       userchoice = getch();
+       userchoice = dgl_getch();
        if (userchoice == ERR) return 1;
        tmpopt = menu->options;
        while (tmpopt) {
index 636808ebe10383d5c6955eddc3f9b23b320c6e19..b78cd42464ca2d9a02bacde15078984c0131fe6a 100644 (file)
@@ -124,6 +124,7 @@ struct dg_globalconfig
     struct dg_cmdpart *cmdqueue[NUM_DGLTIMES];
 
     struct dg_menulist *menulist;
+    int menu_max_idle_time;
 };
 
 typedef enum
@@ -219,7 +220,9 @@ extern void debug_write(char *str);
 extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode sortmode);
 
 int runmenuloop(struct dg_menu *menu);
-
+extern int dgl_getch(void);
+extern void idle_alarm_set_enabled(int enabled);
+extern void idle_alarm_reset(void);
 extern void inprogressmenu(int gameid);
 extern void change_email(void);
 extern int changepw(int dowrite);
index bd5110869f070c0132d151f5618ec10b58aea01b..dd45c154ad7abf4a32a26fc2a6f89b22d6008123 100644 (file)
@@ -257,6 +257,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
                myargv[2] = 0;
 
                endwin();
+               idle_alarm_set_enabled(0);
                child = fork();
                if (child == -1) {
                    perror("fork");
@@ -267,6 +268,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
                    exit(0);
                } else
                    waitpid(child, NULL, 0);
+               idle_alarm_set_enabled(1);
                refresh();
                check_retard(1);
            }
@@ -306,7 +308,9 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
                int i;
                for (i = 0; i < num_games; i++) {
                    if ((!strcmp(myconfig[i]->game_name, p1) || !strcmp(myconfig[i]->shortname, p1)) && myconfig[i]->rcfile) {
+                       idle_alarm_set_enabled(0);
                        editoptions(i);
+                       idle_alarm_set_enabled(1);
                        check_retard(1);
                        break;
                    }
@@ -342,6 +346,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
                                myconfig[userchoice]->bin_args[i] = tmpstr;
                            }
 
+                           idle_alarm_set_enabled(0);
                            /* launch program */
                            ttyrec_main (userchoice, me->username,
                                         dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL),
@@ -349,6 +354,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
 
                            /* lastly, run the generic "do these when a game is left" commands */
                            dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMEEND], userchoice, me);
+                           idle_alarm_set_enabled(1);
 
                            setproctitle ("%s", me->username);
                            initcurses ();
index 827c64562c490deb79603454aabfce1d09983a17..1bd6d555b7922aeb7e9fd96def3e7279982cab47 100644 (file)
@@ -58,6 +58,12 @@ banner = "/dgl-banner"
 shed_uid = 5
 shed_gid = 60
 
+# Maximum time in seconds user can idle in the dgamelaunch menus
+# before dgl exits. Default value is 0, which disables the idling timer.
+# Does not apply to external programs or config editors.
+# For setting game idle time, use max_idle_time in the game DEFINE.
+# menu_max_idle_time = 1024
+
 # The defaults are usually just fine for this. passwd refers to the file
 # that stores the user database, and lockfile is only used internally by
 # dgamelaunch.
index 35347eee59af16c73dfb0167df1d48f4f2d08371..99aa70a85a7455bebd4a1f84412acfec87077d33 100644 (file)
--- a/ttyplay.c
+++ b/ttyplay.c
@@ -194,7 +194,7 @@ ttyread (FILE * fp, Header * h, char **buf, int pread)
 
   if (kbhit())
       {
-         const int c = wgetch(stdscr);
+         const int c = dgl_getch();
          const int action = ttyplay_keyboard_action(c);
          if (action != READ_DATA)
              return (action);
@@ -262,6 +262,7 @@ ttypread (FILE * fp, Header * h, char **buf, int pread)
    */
   while ((action = ttyread (fp, h, buf, 1)) == READ_EOF)
     {
+      idle_alarm_reset();
       fflush(stdout);
       clearerr (fp);
 #ifdef HAVE_KQUEUE
@@ -318,9 +319,7 @@ ttypread (FILE * fp, Header * h, char **buf, int pread)
        }
       if (doread)
         {                       /* user hits a character? */
-          char c;
-          read (STDIN_FILENO, &c, 1); /* drain the character */
-
+         const int c = dgl_getch();
          action = ttyplay_keyboard_action(c);
          if (action != READ_DATA)
              return action;
index ea9f0d7713c912c1701081c3683fc387ab1ceda1..318e2d77404b719c0f11a09ea19a10fc22e7596a 100644 (file)
--- a/ttyrec.c
+++ b/ttyrec.c
@@ -167,6 +167,7 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
   }
 
   unlink (ipfile);
+  child = 0;
 
   return 0;
 }