"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; }
%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
}
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));
| 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; }
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";
/* global variables */
char * __progname;
+int g_idle_alarm_enabled = 0;
#ifndef USE_SQLITE3
int f_num = 0;
/* ************************************************************* */
+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)
{
refresh ();
- switch ((menuchoice = getch ()))
+ switch ((menuchoice = dgl_getch ()))
{
case '*':
if (len > 0) {
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);
else
{
mvaddstr(9, 1, "No changes made. Press any key to continue...");
- getch();
+ dgl_getch();
return;
}
}
mvaddstr (9, 1, "This scroll appears to be blank.");
mvaddstr (10, 1, "(Aborting your message.)");
mvaddstr (12, 1, "--More--");
- getch ();
+ dgl_getch ();
return;
}
"(Couldn't open %s'%c spool file. Aborting.)",
username, (username[strlen (username) - 1] != 's') ? 's' : 0);
mvaddstr (12, 1, "--More--");
- getch ();
+ dgl_getch ();
return;
}
mvaddstr (10, 1,
"(Received a weird error from fcntl. Aborting.)");
mvaddstr (12, 1, "--More--");
- getch ();
+ dgl_getch ();
return;
}
sleep (1);
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;
}
for (seconds = HUP_WAIT - 1; seconds >= 0; seconds--)
{
- if (getch() != ERR)
+ if (dgl_getch() != ERR)
{
nocbreak(); /* leave half-delay */
cbreak();
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;
ban.lines = NULL;
ban.len = 0;
+ idle_alarm_set_enabled(1);
loadbanner(menu->banner_fn, &ban);
while (1) {
if (doclear) {
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) {
struct dg_cmdpart *cmdqueue[NUM_DGLTIMES];
struct dg_menulist *menulist;
+ int menu_max_idle_time;
};
typedef enum
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);
myargv[2] = 0;
endwin();
+ idle_alarm_set_enabled(0);
child = fork();
if (child == -1) {
perror("fork");
exit(0);
} else
waitpid(child, NULL, 0);
+ idle_alarm_set_enabled(1);
refresh();
check_retard(1);
}
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;
}
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),
/* 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 ();
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.
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);
*/
while ((action = ttyread (fp, h, buf, 1)) == READ_EOF)
{
+ idle_alarm_reset();
fflush(stdout);
clearerr (fp);
#ifdef HAVE_KQUEUE
}
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;
}
unlink (ipfile);
+ child = 0;
return 0;
}