Two new things:

1) Allow admin to define some commands that are run when something happens.
   format is

commands [ <time> ] = <command> ...

<time> can be one of:
 login     = when user logs in
 dglstart  = when someone telnets in
 register  = when a new user is registered
 gamestart = when a game is started

<command> is:
 mkdir "foo"       = creates a directory "foo"
 chdir "foo"       = changes current work dir to "foo"
 cp "foo" "bar"    = copies file "foo" to "bar"
 unlink "foo"      = deletes file "foo"
 setenv "foo "bar" = sets environment variable "foo" to "bar"

For example

commands[login] = mkdir "foo", unlink "bar", setenv "Z" "foo"


You can also define per-game commands that are executed when
the game is started.


2) Defining game info in the config file has changed slightly.
   Put "DEFINE { ... }" around the game-specific stuff.

See the example config file.



git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@391 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2008-01-01 17:03:05 +00:00
parent 41d038ef3e
commit 24cb396d16
7 changed files with 376 additions and 122 deletions

1
TODO
View File

@ -1,3 +1,4 @@
-allow setting the default watch-screen sortmode in config file.
-allow admin to define series of actions dgl makes when user does
something. for example, do "mkdir dgldir/rcfiles/$nick" and
"cp defaultrc dgldir/rcfiles/$nick/" when a new nick is registered.

View File

@ -17,7 +17,7 @@ unsigned int line = 1, col = 0;
NEGNUMBER -[0-9]+
NUMBER [0-9]+
VALUE \".*\"
VALUE \"[^"]*\"
MALSTRING \"[^\"\n]*\n
WHITE [\t ]*
COMMENT ^#.*
@ -51,6 +51,11 @@ COMMENT ^#.*
{COMMENT} { }
"=" { return '='; }
"," { return ','; }
"[" { return '['; }
"]" { return ']'; }
"{" { return '{'; }
"}" { return '}'; }
"shed_user" { return TYPE_SUSER; }
"shed_group" { return TYPE_SGROUP; }
"shed_uid" { return TYPE_SUID; }
@ -59,7 +64,6 @@ COMMENT ^#.*
"maxnicklen" { return TYPE_MAXNICKLEN; }
"allow_new_nicks" { return TYPE_ALLOW_REGISTRATION; }
"game_num" { return TYPE_GAMENUM; }
"chroot_path" { return TYPE_PATH_CHROOT; }
"game_name" { return TYPE_NAME_GAME; }
@ -77,6 +81,18 @@ COMMENT ^#.*
"inprogressdir" { return TYPE_PATH_INPROGRESS; }
"game_args" { return TYPE_GAME_ARGS; }
"rc_fmt" { return TYPE_RC_FMT; }
commands { return TYPE_CMDQUEUE; }
dglstart { yylval.i = DGLTIME_DGLSTART; return TYPE_CMDQUEUENAME; }
login { yylval.i = DGLTIME_LOGIN; return TYPE_CMDQUEUENAME; }
register { yylval.i = DGLTIME_REGISTER; return TYPE_CMDQUEUENAME; }
game_start { yylval.i = DGLTIME_GAMESTART; return TYPE_CMDQUEUENAME; }
cmdmkdir { yylval.i = DGLCMD_MKDIR; return TYPE_DGLCMD1; }
cmdchdir { yylval.i = DGLCMD_CHDIR; return TYPE_DGLCMD1; }
cmdcp { yylval.i = DGLCMD_CP; return TYPE_DGLCMD1; }
cmdunlink { yylval.i = DGLCMD_UNLINK; return TYPE_DGLCMD1; }
cmdsetenv { yylval.i = DGLCMD_SETENV; return TYPE_DGLCMD2; }
DEFINE { return TYPE_DEFINE_GAME; }
\n { line++; col = 0; }

307
config.y
View File

@ -19,6 +19,8 @@ extern unsigned int line, col;
extern int num_games;
int ncnf = 0;
struct dg_cmdpart *curr_cmdqueue;
int cmdqueue_num = -1;
static const char* lookup_token (int t);
@ -34,12 +36,15 @@ static const char* lookup_token (int t);
%token TYPE_PATH_CHDIR TYPE_PATH_MKDIR TYPE_GAME_SHORT_NAME
%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 TYPE_GAMENUM
%token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_SAVEFILEFMT
%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
%token TYPE_CMDQUEUE
%token <s> TYPE_VALUE
%token <i> TYPE_NUMBER
%token <i> TYPE_NUMBER TYPE_CMDQUEUENAME
%type <kt> KeyType
%token <i> TYPE_DGLCMD1 TYPE_DGLCMD2
%token TYPE_DEFINE_GAME
%%
@ -51,26 +56,39 @@ KeyPairs: KeyPairs KeyPair
| KeyPair
;
KeyPair: KeyType '=' TYPE_VALUE {
KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']'
{
int qnum = $<i>3;
if (globalconfig.cmdqueue[qnum]) {
fprintf(stderr, "%s:%d: command queue defined twice, bailing out\n",
config, line);
exit(1);
}
cmdqueue_num = qnum;
}
'=' cmdlist
{
/*
struct dg_cmdpart *tmp = curr_cmdqueue;
while (tmp) {
fprintf(stderr, "cmd=%i, p1=%s, p2=%s\n", tmp->cmd, tmp->param1, tmp->param2);
tmp = tmp->next;
}
*/
globalconfig.cmdqueue[cmdqueue_num] = curr_cmdqueue;
}
| definegame
{
/* nothing */
}
| KeyType '=' TYPE_VALUE {
struct group* gr;
struct passwd* usr;
if (ncnf < 0 || ncnf >= DIFF_GAMES) {
fprintf(stderr, "%s:%d: illegal game number, bailing out\n",
config, line);
exit(1);
}
if (!myconfig)
{
int tmp;
myconfig = calloc(DIFF_GAMES, sizeof(myconfig[0]));
for (tmp = 0; tmp < DIFF_GAMES; tmp++) {
myconfig[tmp] = calloc(1, sizeof(struct dg_config));
}
globalconfig.shed_uid = (uid_t)-1;
globalconfig.shed_gid = (gid_t)-1;
}
globalconfig.shed_uid = (uid_t)-1;
globalconfig.shed_gid = (gid_t)-1;
switch ($1)
{
@ -130,30 +148,7 @@ KeyPair: KeyType '=' TYPE_VALUE {
globalconfig.chroot = strdup ($3);
break;
case TYPE_PATH_GAME:
if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
myconfig[ncnf]->game_path = strdup ($3);
break;
case TYPE_NAME_GAME:
if (myconfig[ncnf]->game_name) free (myconfig[ncnf]->game_name);
myconfig[ncnf]->game_name = strdup($3);
break;
case TYPE_GAME_SHORT_NAME:
if (myconfig[ncnf]->shortname) free (myconfig[ncnf]->shortname);
myconfig[ncnf]->shortname = strdup($3);
break;
case TYPE_PATH_CHDIR:
if (myconfig[ncnf]->chdir) free(myconfig[ncnf]->chdir);
myconfig[ncnf]->chdir = strdup ($3);
break;
case TYPE_PATH_MKDIR:
if (myconfig[ncnf]->mkdir) free(myconfig[ncnf]->mkdir);
myconfig[ncnf]->mkdir = strdup ($3);
break;
case TYPE_PATH_DGLDIR:
if (globalconfig.dglroot) free(globalconfig.dglroot);
@ -165,16 +160,6 @@ KeyPair: KeyType '=' TYPE_VALUE {
globalconfig.banner = strdup($3);
break;
case TYPE_PATH_CANNED:
if (myconfig[ncnf]->rcfile) free(myconfig[ncnf]->rcfile);
myconfig[ncnf]->rcfile = strdup($3);
break;
case TYPE_PATH_SPOOL:
if (myconfig[ncnf]->spool) free (myconfig[ncnf]->spool);
myconfig[ncnf]->spool = strdup($3);
break;
case TYPE_PATH_LOCKFILE:
if (globalconfig.lockfile) free (globalconfig.lockfile);
globalconfig.lockfile = strdup($3);
@ -185,39 +170,6 @@ KeyPair: KeyType '=' TYPE_VALUE {
globalconfig.passwd = strdup($3);
break;
case TYPE_PATH_SAVEFILEFMT:
if (myconfig[ncnf]->savefilefmt) free(myconfig[ncnf]->savefilefmt);
myconfig[ncnf]->savefilefmt = strdup($3);
break;
case TYPE_RC_FMT:
if (myconfig[ncnf]->rc_fmt) free(myconfig[ncnf]->rc_fmt);
myconfig[ncnf]->rc_fmt = strdup($3);
break;
case TYPE_PATH_INPROGRESS:
if (myconfig[ncnf]->inprogressdir) free(myconfig[ncnf]->inprogressdir);
myconfig[ncnf]->inprogressdir = strdup($3);
break;
case TYPE_GAME_ARGS:
{
char **tmpargs;
if (myconfig[ncnf]->bin_args) {
myconfig[ncnf]->num_args++;
tmpargs = calloc((myconfig[ncnf]->num_args+1), sizeof(char *));
memcpy(tmpargs, myconfig[ncnf]->bin_args, (myconfig[ncnf]->num_args * sizeof(char *)));
free(myconfig[ncnf]->bin_args);
myconfig[ncnf]->bin_args = tmpargs;
} else {
myconfig[ncnf]->num_args = 1;
myconfig[ncnf]->bin_args = calloc(2, sizeof(char *));
}
myconfig[ncnf]->bin_args[(myconfig[ncnf]->num_args)-1] = strdup($3);
myconfig[ncnf]->bin_args[(myconfig[ncnf]->num_args)] = 0;
}
break;
default:
fprintf(stderr, "%s:%d: token %s does not take a string, bailing out\n",
config, line, lookup_token($1));
@ -230,22 +182,8 @@ KeyPair: KeyType '=' TYPE_VALUE {
| KeyType '=' TYPE_MALSTRING {}
| KeyType '=' TYPE_NUMBER {
if (ncnf < 0 || ncnf >= DIFF_GAMES) {
fprintf(stderr, "%s:%d: illegal game number, bailing out\n",
config, line);
exit(1);
}
if (!myconfig)
{
int tmp;
myconfig = calloc(DIFF_GAMES, sizeof(myconfig[0]));
for (tmp = 0; tmp < DIFF_GAMES; tmp++) {
myconfig[tmp] = calloc(1, sizeof(struct dg_config));
}
globalconfig.shed_uid = (uid_t)-1;
globalconfig.shed_gid = (gid_t)-1;
}
switch ($1)
{
@ -260,7 +198,7 @@ KeyPair: KeyType '=' TYPE_VALUE {
fprintf(stderr, "%s:%d: I refuse to run as uid 0 (root)! Aborting.\n", config, line);
graceful_exit(1);
}
globalconfig.shed_uid = $3;
break;
@ -268,19 +206,8 @@ KeyPair: KeyType '=' TYPE_VALUE {
if (!silent && globalconfig.shed_gid != (gid_t)-1 && globalconfig.shed_gid != $3)
fprintf(stderr, "%s:%d: 'shed_gid = %lu' entry overrides old setting %d\n",
config, line, $3, globalconfig.shed_gid);
globalconfig.shed_gid = $3;
break;
case TYPE_GAMENUM:
if (($3 < 0) || ($3 >= DIFF_GAMES)) {
fprintf(stderr, "%s:%d: illegal game number, bailing out\n",
config, line);
exit(1);
}
ncnf = $3;
if (ncnf > num_games)
num_games = ncnf;
globalconfig.shed_gid = $3;
break;
case TYPE_ALLOW_REGISTRATION:
@ -302,13 +229,168 @@ KeyPair: KeyType '=' TYPE_VALUE {
}
};
game_definition : TYPE_CMDQUEUE
{
if (myconfig[ncnf]->cmdqueue) {
fprintf(stderr, "%s:%d: command queue defined twice, bailing out\n",
config, line);
exit(1);
}
}
'=' cmdlist
{
myconfig[ncnf]->cmdqueue = curr_cmdqueue;
}
| KeyType '=' TYPE_VALUE
{
switch ( $1 ) {
case TYPE_PATH_CANNED:
if (myconfig[ncnf]->rcfile) free(myconfig[ncnf]->rcfile);
myconfig[ncnf]->rcfile = strdup($3);
break;
case TYPE_PATH_SPOOL:
if (myconfig[ncnf]->spool) free (myconfig[ncnf]->spool);
myconfig[ncnf]->spool = strdup($3);
break;
case TYPE_PATH_GAME:
if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
myconfig[ncnf]->game_path = strdup ($3);
break;
case TYPE_NAME_GAME:
if (myconfig[ncnf]->game_name) free (myconfig[ncnf]->game_name);
myconfig[ncnf]->game_name = strdup($3);
break;
case TYPE_GAME_SHORT_NAME:
if (myconfig[ncnf]->shortname) free (myconfig[ncnf]->shortname);
myconfig[ncnf]->shortname = strdup($3);
break;
case TYPE_PATH_CHDIR:
if (myconfig[ncnf]->chdir) free(myconfig[ncnf]->chdir);
myconfig[ncnf]->chdir = strdup ($3);
break;
case TYPE_PATH_MKDIR:
if (myconfig[ncnf]->mkdir) free(myconfig[ncnf]->mkdir);
myconfig[ncnf]->mkdir = strdup ($3);
break;
case TYPE_PATH_SAVEFILEFMT:
if (myconfig[ncnf]->savefilefmt) free(myconfig[ncnf]->savefilefmt);
myconfig[ncnf]->savefilefmt = strdup($3);
break;
case TYPE_RC_FMT:
if (myconfig[ncnf]->rc_fmt) free(myconfig[ncnf]->rc_fmt);
myconfig[ncnf]->rc_fmt = strdup($3);
break;
case TYPE_PATH_INPROGRESS:
if (myconfig[ncnf]->inprogressdir) free(myconfig[ncnf]->inprogressdir);
myconfig[ncnf]->inprogressdir = strdup($3);
break;
case TYPE_GAME_ARGS:
{
char **tmpargs;
if (myconfig[ncnf]->bin_args) {
myconfig[ncnf]->num_args++;
tmpargs = calloc((myconfig[ncnf]->num_args+1), sizeof(char *));
memcpy(tmpargs, myconfig[ncnf]->bin_args, (myconfig[ncnf]->num_args * sizeof(char *)));
free(myconfig[ncnf]->bin_args);
myconfig[ncnf]->bin_args = tmpargs;
} else {
myconfig[ncnf]->num_args = 1;
myconfig[ncnf]->bin_args = calloc(2, sizeof(char *));
}
myconfig[ncnf]->bin_args[(myconfig[ncnf]->num_args)-1] = strdup($3);
myconfig[ncnf]->bin_args[(myconfig[ncnf]->num_args)] = 0;
}
break;
default:
fprintf(stderr, "%s:%d: token does not belong into game definition, bailing out\n",
config, line);
exit(1);
}
}
;
game_definitions : game_definitions game_definition
| game_definition
;
definegame : TYPE_DEFINE_GAME '{'
{
if ((ncnf < 0) || (ncnf >= DIFF_GAMES)) {
fprintf(stderr, "%s:%d: too many games defined, bailing out\n",
config, line);
exit(1);
}
if (!myconfig) {
int tmp;
myconfig = calloc(DIFF_GAMES, sizeof(myconfig[0]));
for (tmp = 0; tmp < DIFF_GAMES; tmp++) {
myconfig[tmp] = calloc(1, sizeof(struct dg_config));
}
}
}
game_definitions '}'
{
ncnf++;
num_games = ncnf;
}
;
cmdlist : cmdlist ',' dglcmd
| dglcmd
;
dglcmd : TYPE_DGLCMD1 TYPE_VALUE
{
struct dg_cmdpart *tmp = malloc(sizeof(struct dg_cmdpart));
if (tmp) {
struct dg_cmdpart *foo = curr_cmdqueue;
if (foo) {
while (foo->next) foo = foo->next;
foo->next = tmp;
} else curr_cmdqueue = tmp;
tmp->next = NULL;
tmp->param1 = strdup( $2 );
tmp->param2 = NULL;
tmp->cmd = $<i>1;
}
}
| TYPE_DGLCMD2 TYPE_VALUE TYPE_VALUE
{
struct dg_cmdpart *tmp = malloc(sizeof(struct dg_cmdpart));
if (tmp) {
struct dg_cmdpart *foo = curr_cmdqueue;
if (foo) {
while (foo->next) foo = foo->next;
foo->next = tmp;
} else curr_cmdqueue = tmp;
tmp->next = NULL;
tmp->param1 = strdup( $2 );
tmp->param2 = strdup( $3 );
tmp->cmd = $<i>1;
}
}
;
KeyType : TYPE_SUSER { $$ = TYPE_SUSER; }
| TYPE_SGROUP { $$ = TYPE_SGROUP; }
| TYPE_SUID { $$ = TYPE_SUID; }
| TYPE_SGID { $$ = TYPE_SGID; }
| TYPE_MAX { $$ = TYPE_MAX; }
| TYPE_MAXNICKLEN { $$ = TYPE_MAXNICKLEN; }
| TYPE_GAMENUM { $$ = TYPE_GAMENUM; }
| TYPE_PATH_CHROOT { $$ = TYPE_PATH_CHROOT; }
| TYPE_ALLOW_REGISTRATION { $$ = TYPE_ALLOW_REGISTRATION; }
| TYPE_PATH_GAME { $$ = TYPE_PATH_GAME; }
@ -340,7 +422,6 @@ const char* lookup_token (int t)
case TYPE_SGID: return "shed_gid";
case TYPE_MAX: return "maxusers";
case TYPE_MAXNICKLEN: return "maxnicklen";
case TYPE_GAMENUM: return "game_num";
case TYPE_PATH_CHROOT: return "chroot_path";
case TYPE_PATH_CHDIR: return "chdir";
case TYPE_PATH_MKDIR: return "mkdir";

View File

@ -884,6 +884,7 @@ autologin (char* user, char *pass)
if (passwordgood(pass)) {
loggedin = 1;
setproctitle ("%s", me->username);
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_LOGIN], 0, me);
}
}
}
@ -949,6 +950,7 @@ loginprompt (int from_ttyplay)
{
loggedin = 1;
setproctitle ("%s", me->username);
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_LOGIN], 0, me);
}
else
{
@ -1109,11 +1111,16 @@ newuser ()
setproctitle ("%s", me->username);
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_REGISTER], 0, me);
/* create their ttyrec dir */
/*
snprintf (dirname, 100, "%sttyrec/%s", globalconfig.dglroot, me->username);
if (access (dirname, F_OK) != 0)
mkdir (dirname, 0755);
*/
writefile (1);
}
@ -2051,6 +2058,8 @@ main (int argc, char** argv)
}
}
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_DGLSTART], 0, NULL);
if (nhext)
{
char *myargv[3];
@ -2116,6 +2125,11 @@ main (int argc, char** argv)
endwin ();
signal(SIGWINCH, SIG_DFL);
/* first run the generic "do these when a game is started" commands */
dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMESTART], userchoice, me);
/* then run the game-specific commands */
dgl_exec_cmdqueue(myconfig[userchoice]->cmdqueue, userchoice, me);
if (!backup_savefile (userchoice))
graceful_exit (5);
@ -2183,6 +2197,8 @@ main (int argc, char** argv)
if (me)
free (me);
/* FIXME: free data in globalconfig */
graceful_exit (1);
return 1;

View File

@ -16,6 +16,23 @@
/* max # of different games playable from within this dgl */
#define DIFF_GAMES 4
typedef enum
{
DGLTIME_DGLSTART = 0, /* when someone telnets in */
DGLTIME_LOGIN, /* right after user login */
DGLTIME_REGISTER, /* right after new nick is registered */
DGLTIME_GAMESTART, /* right before a game is started */
NUM_DGLTIMES
} dglcmd_times;
struct dg_cmdpart
{
dglcmd_times cmd;
char *param1;
char *param2;
struct dg_cmdpart *next;
};
struct dg_user
{
#ifdef USE_SQLITE3
@ -59,6 +76,7 @@ struct dg_config
int num_args; /* # of bin_args */
char **bin_args; /* args for game binary */
char *rc_fmt;
struct dg_cmdpart *cmdqueue;
};
struct dg_globalconfig
@ -75,8 +93,19 @@ struct dg_globalconfig
char* passwd;
char* lockfile;
int allow_registration; /* allow registering new nicks */
struct dg_cmdpart *cmdqueue[NUM_DGLTIMES];
};
typedef enum
{
DGLCMD_NONE = 0,
DGLCMD_MKDIR, /* mkdir foo */
DGLCMD_CHDIR, /* chdir foo */
DGLCMD_CP, /* cp foo bar */
DGLCMD_UNLINK, /* unlink foo */
DGLCMD_SETENV /* setenv foo bar */
} dglcmd_actions;
typedef enum
{
@ -115,6 +144,9 @@ extern void catch_sighup(int signum);
extern void loadbanner(int game, struct dg_banner *ban);
extern void drawbanner(unsigned int start_line, unsigned int howmany);
extern char *dgl_format_str(int game, struct dg_user *me, char *str);
extern int dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me);
extern struct dg_game **populate_games(int game, int *l);
extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode sortmode);

View File

@ -39,7 +39,8 @@ struct dg_config defconfig = {
/* inprogressdir = */ "inprogress/",
/* num_args = */ 0,
/* bin_args = */ NULL,
/* rc_fmt = */ "%rrcfiles/%n.nethackrc" /* [dglroot]rcfiles/[username].nethackrc */
/* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
/* cmdqueue = */ NULL
};
char* config = NULL;
@ -55,7 +56,8 @@ struct dg_globalconfig globalconfig;
* replace following codes with variables:
* %u == shed_uid (number)
* %n == user name (string)
* %r == chroot (string)
* %r == chroot (string) (aka "dglroot" config var)
* %g == game name
*/
char *
dgl_format_str(int game, struct dg_user *me, char *str)
@ -79,7 +81,12 @@ dgl_format_str(int game, struct dg_user *me, char *str)
p++;
break;
case 'n':
snprintf (p, end + 1 - p, "%s", me->username);
if (me) snprintf (p, end + 1 - p, "%s", me->username);
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);
while (*p != '\0')
p++;
break;
@ -110,6 +117,65 @@ dgl_format_str(int game, struct dg_user *me, char *str)
return buf;
}
int
dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
{
int i;
struct dg_cmdpart *tmp = queue;
if (!queue) return 1;
while (tmp) {
char *p1 = NULL; /* FIXME: should probably use fixed-size buffers instead of doing strdup() every time */
char *p2 = NULL;
if (tmp->param1) p1 = strdup(dgl_format_str(game, me, tmp->param1));
if (tmp->param2) p2 = strdup(dgl_format_str(game, me, tmp->param2));
switch (tmp->cmd) {
default: break;
case DGLCMD_MKDIR:
if (p1 && (access(p1, F_OK) != 0)) mkdir(p1, 0755);
break;
case DGLCMD_UNLINK:
if (p1 && (access(p1, F_OK) != 0)) unlink(p1);
break;
case DGLCMD_CHDIR:
if (p1) chdir(p1);
break;
case DGLCMD_CP:
if (p1 && p2) {
FILE *cannedf, *newfile;
char buf[1024];
size_t bytes;
/* FIXME: use nethack-themed error messages here, as per write_canned_rcfile() */
if (!(newfile = fopen (p2, "w"))) return 1;
if (!(cannedf = fopen (p1, "r"))) return 1;
while ((bytes = fread (buf, 1, 1024, cannedf)) > 0) {
if (fwrite (buf, 1, bytes, newfile) != bytes) {
if (ferror (newfile)) {
fclose (cannedf);
fclose (newfile);
return 1;
}
}
}
fclose (cannedf);
fclose (newfile);
}
break;
case DGLCMD_SETENV:
if (p1 && p2) mysetenv(p1, p2, 1);
break;
}
free(p1);
free(p2);
tmp = tmp->next;
}
return 0;
}
static int
sort_game_username(const void *g1, const void *g2)
@ -397,4 +463,8 @@ create_config ()
globalconfig.shed_gid = 60; /* games gid in debian */
}
for (tmp = 0; tmp < NUM_DGLTIMES; tmp++) {
globalconfig.cmdqueue[0] = NULL;
}
}

View File

@ -54,9 +54,36 @@ passwd = "/dgl-login"
lockfile = "/dgl-lock"
#
# define some commands that are run when something happens. format is
# commands [ <time> ] = <command> ...
#
# <time> can be one of:
# login = when user logs in
# dglstart = when someone telnets in
# register = when a new user is registered
# gamestart = when a game is started
#
# <command> is:
# mkdir "foo" = creates a directory "foo"
# chdir "foo" = changes current work dir to "foo"
# cp "foo" "bar" = copies file "foo" to "bar"
# unlink "foo" = deletes file "foo"
# setenv "foo "bar" = sets environment variable "foo" to "bar"
#
# eg. commands[login] = mkdir "foo", unlink "bar", setenv "Z" "foo"
#
# create the user's ttyrec dir when they register
commands[register] = cmdmkdir "%rttyrec/%n"
# Next, we'll define one game's data:
DEFINE {
# From inside the jail, the location of the binary to be launched.
game_path = "/bin/nethackstub"
@ -93,13 +120,19 @@ savefilefmt = "/var/games/nethack/save/%u%n.gz"
# each game you define here must have it's own.
inprogressdir = "inprogress-nethackstub/"
# We can also define per-game commands, that are executed
# when teh game starts:
# commands = chdir "/dgldir", mkdir "foo_%u_%g"
}
#
# the second game
#
#
game_num = 1
DEFINE {
game_path = "/bin/nethack"
game_name = "NetHack 3.4.3"
@ -118,13 +151,15 @@ rc_fmt = "%rrcfiles/%n.nethackrc"
savefilefmt = "/var/games/nethack/save/%u%n.gz"
inprogressdir = "inprogress-nethack/"
}
#
# third game
#
#
game_num = 2
DEFINE {
game_path = "/bin/crawlss017"
game_name = "Crawl Stone Soup 0.1.7"
short_name = "Cr017"
@ -148,12 +183,15 @@ rc_template = "/dgl-default-rcfile.crawl"
rc_fmt = "%rrcfiles/%n.crawlrc"
inprogressdir = "inprogress-crawlss017/"
}
#
# fourth game
#
#
game_num = 3
DEFINE {
game_path = "/bin/crawlss020"
game_name = "Crawl Stone Soup 0.2.0"
short_name = "Cr020"
@ -177,4 +215,4 @@ rc_template = "/dgl-default-rcfile.crawl"
rc_fmt = "/crawlss020/plr/%n/%n.crawlrc"
inprogressdir = "inprogress-crawlss020/"
}