Define menu_max_idle_time option to kill dgl when the user idles too long. From Darshan Shaligram

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@531 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2010-03-02 18:32:57 +00:00
parent 9934d365bd
commit ef7d6eb846
8 changed files with 76 additions and 16 deletions

View File

@ -65,6 +65,7 @@ WHITE [\t ]*
"maxusers" { return TYPE_MAX; } "maxusers" { return TYPE_MAX; }
"maxnicklen" { return TYPE_MAXNICKLEN; } "maxnicklen" { return TYPE_MAXNICKLEN; }
"allow_new_nicks" { return TYPE_ALLOW_REGISTRATION; } "allow_new_nicks" { return TYPE_ALLOW_REGISTRATION; }
"menu_max_idle_time" { return TYPE_MENU_MAX_IDLE_TIME; }
menu { return TYPE_DEFINE_MENU; } menu { return TYPE_DEFINE_MENU; }

View File

@ -41,7 +41,7 @@ static const char* lookup_token (int t);
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_TTYREC %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 TYPE_MAX_IDLE_TIME %token TYPE_MAX_IDLE_TIME TYPE_MENU_MAX_IDLE_TIME
%token <s> TYPE_VALUE %token <s> TYPE_VALUE
%token <i> TYPE_NUMBER TYPE_CMDQUEUENAME %token <i> TYPE_NUMBER TYPE_CMDQUEUENAME
%type <kt> KeyType %type <kt> KeyType
@ -252,6 +252,10 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']'
} }
break; break;
case TYPE_MENU_MAX_IDLE_TIME:
globalconfig.menu_max_idle_time = $3;
break;
default: default:
fprintf(stderr, "%s:%d: token %s does not take a number, bailing out\n", fprintf(stderr, "%s:%d: token %s does not take a number, bailing out\n",
config, line, lookup_token($1)); config, line, lookup_token($1));
@ -524,6 +528,7 @@ KeyType : TYPE_SUSER { $$ = TYPE_SUSER; }
| TYPE_SGID { $$ = TYPE_SGID; } | TYPE_SGID { $$ = TYPE_SGID; }
| TYPE_MAX { $$ = TYPE_MAX; } | TYPE_MAX { $$ = TYPE_MAX; }
| TYPE_MAXNICKLEN { $$ = TYPE_MAXNICKLEN; } | TYPE_MAXNICKLEN { $$ = TYPE_MAXNICKLEN; }
| TYPE_MENU_MAX_IDLE_TIME { $$ = TYPE_MENU_MAX_IDLE_TIME; }
| TYPE_PATH_CHROOT { $$ = TYPE_PATH_CHROOT; } | TYPE_PATH_CHROOT { $$ = TYPE_PATH_CHROOT; }
| TYPE_ALLOW_REGISTRATION { $$ = TYPE_ALLOW_REGISTRATION; } | TYPE_ALLOW_REGISTRATION { $$ = TYPE_ALLOW_REGISTRATION; }
| TYPE_PATH_GAME { $$ = TYPE_PATH_GAME; } | TYPE_PATH_GAME { $$ = TYPE_PATH_GAME; }
@ -554,6 +559,7 @@ const char* lookup_token (int t)
case TYPE_SGID: return "shed_gid"; case TYPE_SGID: return "shed_gid";
case TYPE_MAX: return "maxusers"; case TYPE_MAX: return "maxusers";
case TYPE_MAXNICKLEN: return "maxnicklen"; 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_CHROOT: return "chroot_path";
case TYPE_PATH_GAME: return "game_path"; case TYPE_PATH_GAME: return "game_path";
case TYPE_NAME_GAME: return "game_name"; case TYPE_NAME_GAME: return "game_name";

View File

@ -96,6 +96,7 @@ extern int editor_main (int argc, char **argv);
/* global variables */ /* global variables */
char * __progname; char * __progname;
int g_idle_alarm_enabled = 0;
#ifndef USE_SQLITE3 #ifndef USE_SQLITE3
int f_num = 0; 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 * char *
bannerstrmangle(char *buf, char *fromstr, char *tostr) bannerstrmangle(char *buf, char *fromstr, char *tostr)
{ {
@ -499,7 +536,7 @@ inprogressmenu (int gameid)
refresh (); refresh ();
switch ((menuchoice = getch ())) switch ((menuchoice = dgl_getch ()))
{ {
case '*': case '*':
if (len > 0) { if (len > 0) {
@ -717,7 +754,7 @@ change_email ()
else if (check_email (buf)) else if (check_email (buf))
{ {
mvprintw (8, 1, "Changing email address to '%s'. Confirm (y/n): ", buf); mvprintw (8, 1, "Changing email address to '%s'. Confirm (y/n): ", buf);
if (getch() == 'y') if (dgl_getch() == 'y')
{ {
free(me->email); free(me->email);
me->email = strdup(buf); me->email = strdup(buf);
@ -727,7 +764,7 @@ change_email ()
else else
{ {
mvaddstr(9, 1, "No changes made. Press any key to continue..."); mvaddstr(9, 1, "No changes made. Press any key to continue...");
getch(); dgl_getch();
return; return;
} }
} }
@ -915,7 +952,7 @@ domailuser (char *username)
mvaddstr (9, 1, "This scroll appears to be blank."); mvaddstr (9, 1, "This scroll appears to be blank.");
mvaddstr (10, 1, "(Aborting your message.)"); mvaddstr (10, 1, "(Aborting your message.)");
mvaddstr (12, 1, "--More--"); mvaddstr (12, 1, "--More--");
getch (); dgl_getch ();
return; return;
} }
@ -927,7 +964,7 @@ domailuser (char *username)
"(Couldn't open %s'%c spool file. Aborting.)", "(Couldn't open %s'%c spool file. Aborting.)",
username, (username[strlen (username) - 1] != 's') ? 's' : 0); username, (username[strlen (username) - 1] != 's') ? 's' : 0);
mvaddstr (12, 1, "--More--"); mvaddstr (12, 1, "--More--");
getch (); dgl_getch ();
return; return;
} }
@ -942,7 +979,7 @@ domailuser (char *username)
mvaddstr (10, 1, mvaddstr (10, 1,
"(Received a weird error from fcntl. Aborting.)"); "(Received a weird error from fcntl. Aborting.)");
mvaddstr (12, 1, "--More--"); mvaddstr (12, 1, "--More--");
getch (); dgl_getch ();
return; return;
} }
sleep (1); sleep (1);
@ -1125,7 +1162,7 @@ newuser ()
mvaddstr (5, 1, "Sorry, too many users have registered now."); mvaddstr (5, 1, "Sorry, too many users have registered now.");
mvaddstr (6, 1, "You might email the server administrator."); mvaddstr (6, 1, "You might email the server administrator.");
mvaddstr (7, 1, "Press return to return to the menu. "); mvaddstr (7, 1, "Press return to return to the menu. ");
getch (); dgl_getch ();
return; return;
} }
@ -1811,7 +1848,7 @@ purge_stale_locks (int game)
for (seconds = HUP_WAIT - 1; seconds >= 0; seconds--) for (seconds = HUP_WAIT - 1; seconds >= 0; seconds--)
{ {
if (getch() != ERR) if (dgl_getch() != ERR)
{ {
nocbreak(); /* leave half-delay */ nocbreak(); /* leave half-delay */
cbreak(); cbreak();
@ -1846,7 +1883,7 @@ purge_stale_locks (int game)
mvprintw (3, 1, mvprintw (3, 1,
"Couldn't terminate one of your stale %s processes gracefully.", myconfig[game]->game_name); "Couldn't terminate one of your stale %s processes gracefully.", myconfig[game]->game_name);
mvaddstr (4, 1, "Force its termination? [yn] "); mvaddstr (4, 1, "Force its termination? [yn] ");
if (tolower (getch ()) == 'y') if (tolower (dgl_getch ()) == 'y')
{ {
kill (pid, SIGTERM); kill (pid, SIGTERM);
break; break;
@ -1885,6 +1922,7 @@ runmenuloop(struct dg_menu *menu)
ban.lines = NULL; ban.lines = NULL;
ban.len = 0; ban.len = 0;
idle_alarm_set_enabled(1);
loadbanner(menu->banner_fn, &ban); loadbanner(menu->banner_fn, &ban);
while (1) { while (1) {
if (doclear) { if (doclear) {
@ -1895,7 +1933,7 @@ runmenuloop(struct dg_menu *menu)
if (menu->cursor_x >= 0 && menu->cursor_y >= 0) if (menu->cursor_x >= 0 && menu->cursor_y >= 0)
mvprintw(menu->cursor_y, menu->cursor_x, ""); mvprintw(menu->cursor_y, menu->cursor_x, "");
refresh(); refresh();
userchoice = getch(); userchoice = dgl_getch();
if (userchoice == ERR) return 1; if (userchoice == ERR) return 1;
tmpopt = menu->options; tmpopt = menu->options;
while (tmpopt) { while (tmpopt) {

View File

@ -124,6 +124,7 @@ struct dg_globalconfig
struct dg_cmdpart *cmdqueue[NUM_DGLTIMES]; struct dg_cmdpart *cmdqueue[NUM_DGLTIMES];
struct dg_menulist *menulist; struct dg_menulist *menulist;
int menu_max_idle_time;
}; };
typedef enum 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); 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);
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 inprogressmenu(int gameid);
extern void change_email(void); extern void change_email(void);
extern int changepw(int dowrite); extern int changepw(int dowrite);

View File

@ -257,6 +257,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
myargv[2] = 0; myargv[2] = 0;
endwin(); endwin();
idle_alarm_set_enabled(0);
child = fork(); child = fork();
if (child == -1) { if (child == -1) {
perror("fork"); perror("fork");
@ -267,6 +268,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
exit(0); exit(0);
} else } else
waitpid(child, NULL, 0); waitpid(child, NULL, 0);
idle_alarm_set_enabled(1);
refresh(); refresh();
check_retard(1); check_retard(1);
} }
@ -306,7 +308,9 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
int i; int i;
for (i = 0; i < num_games; i++) { for (i = 0; i < num_games; i++) {
if ((!strcmp(myconfig[i]->game_name, p1) || !strcmp(myconfig[i]->shortname, p1)) && myconfig[i]->rcfile) { if ((!strcmp(myconfig[i]->game_name, p1) || !strcmp(myconfig[i]->shortname, p1)) && myconfig[i]->rcfile) {
idle_alarm_set_enabled(0);
editoptions(i); editoptions(i);
idle_alarm_set_enabled(1);
check_retard(1); check_retard(1);
break; break;
} }
@ -342,6 +346,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
myconfig[userchoice]->bin_args[i] = tmpstr; myconfig[userchoice]->bin_args[i] = tmpstr;
} }
idle_alarm_set_enabled(0);
/* launch program */ /* launch program */
ttyrec_main (userchoice, me->username, ttyrec_main (userchoice, me->username,
dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL), 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 */ /* 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);
idle_alarm_set_enabled(1);
setproctitle ("%s", me->username); setproctitle ("%s", me->username);
initcurses (); initcurses ();

View File

@ -58,6 +58,12 @@ banner = "/dgl-banner"
shed_uid = 5 shed_uid = 5
shed_gid = 60 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 # 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 # that stores the user database, and lockfile is only used internally by
# dgamelaunch. # dgamelaunch.

View File

@ -194,7 +194,7 @@ ttyread (FILE * fp, Header * h, char **buf, int pread)
if (kbhit()) if (kbhit())
{ {
const int c = wgetch(stdscr); const int c = dgl_getch();
const int action = ttyplay_keyboard_action(c); const int action = ttyplay_keyboard_action(c);
if (action != READ_DATA) if (action != READ_DATA)
return (action); return (action);
@ -262,6 +262,7 @@ ttypread (FILE * fp, Header * h, char **buf, int pread)
*/ */
while ((action = ttyread (fp, h, buf, 1)) == READ_EOF) while ((action = ttyread (fp, h, buf, 1)) == READ_EOF)
{ {
idle_alarm_reset();
fflush(stdout); fflush(stdout);
clearerr (fp); clearerr (fp);
#ifdef HAVE_KQUEUE #ifdef HAVE_KQUEUE
@ -318,9 +319,7 @@ ttypread (FILE * fp, Header * h, char **buf, int pread)
} }
if (doread) if (doread)
{ /* user hits a character? */ { /* user hits a character? */
char c; const int c = dgl_getch();
read (STDIN_FILENO, &c, 1); /* drain the character */
action = ttyplay_keyboard_action(c); action = ttyplay_keyboard_action(c);
if (action != READ_DATA) if (action != READ_DATA)
return action; return action;

View File

@ -167,6 +167,7 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
} }
unlink (ipfile); unlink (ipfile);
child = 0;
return 0; return 0;
} }