+-configurable environment variables for when the game is launched
+-configurable rcfilefmt and default rcfile name
+-configurable stuff: max user name len, allowed chars in usernames,
+ allow mailing, allow char stripping, ...
+-allow different banners for different games
+
- Flags for operators/staff/admins or (optionally) user-bans.
- Localization of variables, code clean up
"shed_gid" { return TYPE_SGID; }
"maxusers" { return TYPE_MAX; }
+"game_num" { return TYPE_GAMENUM; }
+
"chroot_path" { return TYPE_PATH_CHROOT; }
"game_name" { return TYPE_NAME_GAME; }
"game_path" { return TYPE_PATH_GAME; }
"passwd" { return TYPE_PATH_PASSWD; }
"lockfile" { return TYPE_PATH_LOCKFILE; }
"savefilefmt" { return TYPE_PATH_SAVEFILEFMT; }
+"inprogressdir" { return TYPE_PATH_INPROGRESS; }
+"game_args" { return TYPE_GAME_ARGS; }
+"rc_fmt" { return TYPE_RC_FMT; }
\n { line++; col = 0; }
extern char *yytext;
extern unsigned int line, col;
+extern int num_games;
+int ncnf = 0;
+
static const char* lookup_token (int t);
%}
%token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX
%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_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT TYPE_GAMENUM
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_SAVEFILEFMT
-%token TYPE_MALSTRING
+%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
%token <s> TYPE_VALUE
%token <i> TYPE_NUMBER
%type <kt> KeyType
KeyPair: 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)
{
- myconfig = calloc(1, sizeof(struct dg_config));
- myconfig->shed_uid = (uid_t)-1;
- myconfig->shed_gid = (gid_t)-1;
+ 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)
{
case TYPE_SGROUP:
- if (myconfig->shed_gid != (gid_t)-1)
+ if (globalconfig.shed_gid != (gid_t)-1)
break;
-
- myconfig->shed_group = strdup($3);
+
+ globalconfig.shed_group = strdup($3);
if ((gr = getgrnam($3)) != NULL)
{
- myconfig->shed_gid = gr->gr_gid;
+ globalconfig.shed_gid = gr->gr_gid;
if (!silent)
fprintf(stderr, "%s:%d: suggest replacing 'shed_group = \"%s\"' line with 'shed_gid = %d'\n",
config, line, $3, gr->gr_gid);
if (!silent)
fprintf(stderr, "%s:%d: no such group '%s'\n", config, line, $3);
}
-
+
break;
case TYPE_SUSER:
- if (myconfig->shed_uid != (uid_t)-1)
+ if (globalconfig.shed_uid != (uid_t)-1)
break;
-
+
if (!strcmp($3, "root"))
{
fprintf(stderr, "%s:%d: I refuse to run as root! Aborting.\n", config, line);
graceful_exit(1);
}
- myconfig->shed_user = strdup($3);
+ globalconfig.shed_user = strdup($3);
if ((usr = getpwnam($3)) != NULL)
{
if (usr->pw_uid != 0)
{
- myconfig->shed_uid = usr->pw_uid;
+ globalconfig.shed_uid = usr->pw_uid;
if (!silent)
fprintf(stderr, "%s:%d: suggest replacing 'shed_user = \"%s\"' line with 'shed_uid = %d'\n",
config, line, $3, usr->pw_uid);
break;
case TYPE_PATH_CHROOT:
- if (myconfig->chroot) free(myconfig->chroot);
- myconfig->chroot = strdup ($3);
+ if (globalconfig.chroot) free(globalconfig.chroot);
+ globalconfig.chroot = strdup ($3);
break;
case TYPE_PATH_GAME:
- if (myconfig->game_path) free(myconfig->game_path);
- myconfig->game_path = strdup ($3);
+ if (myconfig[ncnf]->game_path) free(myconfig[ncnf]->game_path);
+ myconfig[ncnf]->game_path = strdup ($3);
break;
case TYPE_NAME_GAME:
- if (myconfig->game_name) free (myconfig->game_name);
- myconfig->game_name = strdup($3);
+ if (myconfig[ncnf]->game_name) free (myconfig[ncnf]->game_name);
+ myconfig[ncnf]->game_name = strdup($3);
break;
case TYPE_PATH_DGLDIR:
- if (myconfig->dglroot) free(myconfig->dglroot);
- myconfig->dglroot = strdup ($3);
+ if (globalconfig.dglroot) free(globalconfig.dglroot);
+ globalconfig.dglroot = strdup($3);
break;
case TYPE_PATH_BANNER:
- if (myconfig->banner) free(myconfig->banner);
- myconfig->banner = strdup($3);
+ if (globalconfig.banner) free(globalconfig.banner);
+ globalconfig.banner = strdup($3);
break;
case TYPE_PATH_CANNED:
- if (myconfig->rcfile) free(myconfig->rcfile);
- myconfig->rcfile = strdup($3);
+ if (myconfig[ncnf]->rcfile) free(myconfig[ncnf]->rcfile);
+ myconfig[ncnf]->rcfile = strdup($3);
break;
case TYPE_PATH_SPOOL:
- if (myconfig->spool) free (myconfig->spool);
- myconfig->spool = strdup($3);
+ if (myconfig[ncnf]->spool) free (myconfig[ncnf]->spool);
+ myconfig[ncnf]->spool = strdup($3);
break;
case TYPE_PATH_LOCKFILE:
- if (myconfig->lockfile) free (myconfig->lockfile);
- myconfig->lockfile = strdup($3);
+ if (myconfig[ncnf]->lockfile) free (myconfig[ncnf]->lockfile);
+ myconfig[ncnf]->lockfile = strdup($3);
break;
case TYPE_PATH_PASSWD:
- if (myconfig->passwd) free(myconfig->passwd);
- myconfig->passwd = strdup($3);
+ if (myconfig[ncnf]->passwd) free(myconfig[ncnf]->passwd);
+ myconfig[ncnf]->passwd = strdup($3);
break;
case TYPE_PATH_SAVEFILEFMT:
- if (myconfig->savefilefmt) free(myconfig->savefilefmt);
- myconfig->savefilefmt = strdup($3);
+ 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));
exit(1);
-
+
}
free($3);
}
| 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)
{
- myconfig = calloc(1, sizeof(struct dg_config));
- myconfig->shed_uid = (uid_t)-1;
- myconfig->shed_gid = (gid_t)-1;
+ 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)
{
case TYPE_SUID:
- if (!silent && myconfig->shed_uid != (uid_t)-1 && myconfig->shed_uid != $3)
+ if (!silent && globalconfig.shed_uid != (uid_t)-1 && globalconfig.shed_uid != $3)
fprintf(stderr, "%s:%d: 'shed_uid = %lu' entry overrides old setting %d\n",
- config, line, $3, myconfig->shed_uid);
+ config, line, $3, globalconfig.shed_uid);
/* Naive user protection - do not allow running as user root */
if ($3 == 0)
graceful_exit(1);
}
- myconfig->shed_uid = $3;
+ globalconfig.shed_uid = $3;
break;
case TYPE_SGID:
- if (!silent && myconfig->shed_gid != (gid_t)-1 && myconfig->shed_gid != $3)
+ 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, myconfig->shed_gid);
+ config, line, $3, globalconfig.shed_gid);
- myconfig->shed_gid = $3;
+ 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;
break;
case TYPE_MAX:
- set_max = 1; /* XXX XXX */
- myconfig->max = $3;
+ globalconfig.max = $3;
break;
default:
| TYPE_SUID { $$ = TYPE_SUID; }
| TYPE_SGID { $$ = TYPE_SGID; }
| TYPE_MAX { $$ = TYPE_MAX; }
+ | TYPE_GAMENUM { $$ = TYPE_GAMENUM; }
| TYPE_PATH_CHROOT { $$ = TYPE_PATH_CHROOT; }
| TYPE_PATH_GAME { $$ = TYPE_PATH_GAME; }
| TYPE_NAME_GAME { $$ = TYPE_NAME_GAME; }
| TYPE_PATH_PASSWD { $$ = TYPE_PATH_PASSWD; }
| TYPE_PATH_LOCKFILE { $$ = TYPE_PATH_LOCKFILE; }
| TYPE_PATH_SAVEFILEFMT { $$ = TYPE_PATH_SAVEFILEFMT; }
+ | TYPE_PATH_INPROGRESS { $$ = TYPE_PATH_INPROGRESS; }
+ | TYPE_GAME_ARGS { $$ = TYPE_GAME_ARGS; }
+ | TYPE_RC_FMT { $$ = TYPE_RC_FMT; }
;
%%
case TYPE_SUID: return "shed_uid";
case TYPE_SGID: return "shed_gid";
case TYPE_MAX: return "maxusers";
+ case TYPE_GAMENUM: return "game_num";
case TYPE_PATH_CHROOT: return "chroot_path";
case TYPE_PATH_GAME: return "game_path";
case TYPE_NAME_GAME: return "game_name";
case TYPE_PATH_BANNER: return "banner";
case TYPE_PATH_CANNED: return "rc_template";
case TYPE_PATH_SAVEFILEFMT: return "savefilefmt";
+ case TYPE_PATH_INPROGRESS: return "inprogressdir";
+ case TYPE_GAME_ARGS: return "game_args";
+ case TYPE_RC_FMT: return "rc_fmt";
default: abort();
}
}
/* global variables */
char * __progname;
-char rcfilename[80];
+/*char rcfilename[80];*/
int f_num = 0;
struct dg_user **users = NULL;
/* ************************************************************* */
char*
-gen_inprogress_lock (pid_t pid, char* ttyrec_filename)
+gen_inprogress_lock (int game, pid_t pid, char* ttyrec_filename)
{
char *lockfile = NULL, filebuf[80];
int fd;
fl.l_start = 0;
fl.l_len = 0;
- len = strlen(myconfig->dglroot) + strlen(me->username) + strlen(ttyrec_filename) + 13;
+ len = strlen(globalconfig.dglroot) + strlen(me->username) + strlen(ttyrec_filename) + 13;
lockfile = calloc(len, sizeof(char));
- snprintf (lockfile, len, "%sinprogress/%s:%s", myconfig->dglroot,
+ snprintf (lockfile, len, "%s%s%s:%s", globalconfig.dglroot, myconfig[game]->inprogressdir,
me->username, ttyrec_filename);
fd = open (lockfile, O_WRONLY | O_CREAT, 0644);
/* ************************************************************* */
void
-loadbanner (struct dg_banner *ban)
+loadbanner (int game, struct dg_banner *ban)
{
FILE *bannerfile;
char buf[80];
memset (buf, 0, 80);
- bannerfile = fopen (myconfig->banner, "r");
+ bannerfile = fopen (globalconfig.banner, "r");
if (!bannerfile)
{
ban->lines[0] =
strdup ("### dgamelaunch " PACKAGE_VERSION
" - network console game launcher");
- len = strlen(myconfig->banner) + ARRAY_SIZE("### NOTE: administrator has not installed a file");
+ len = strlen(globalconfig.banner) + ARRAY_SIZE("### NOTE: administrator has not installed a file");
ban->lines[1] = malloc(len);
- snprintf(ban->lines[1], len, "### NOTE: administrator has not installed a %s file", myconfig->banner);
+ snprintf(ban->lines[1], len, "### NOTE: administrator has not installed a %s file", globalconfig.banner);
return;
}
if (!loaded_banner)
{
- loadbanner (&banner);
+ loadbanner (0, &banner);
loaded_banner = 1;
}
}
void
-inprogressmenu ()
+inprogressmenu (int gameid)
{
int i, menuchoice, len = 20, offset = 0, doresizewin = 0;
time_t ctime;
int is_nhext[14];
sigset_t oldmask, toblock;
- games = populate_games (&len);
+ games = populate_games (gameid, &len);
while (1)
{
break;
/* valid choice has been made */
- snprintf (ttyrecname, 130, "%sttyrec/%s", myconfig->dglroot,
+ snprintf (ttyrecname, 130, "%sttyrec/%s", globalconfig.dglroot,
games[menuchoice - 97 + offset]->ttyrec_fn);
chosen_name = strdup (games[menuchoice - 97 + offset]->name);
}
}
- games = populate_games (&len);
+ games = populate_games (gameid, &len);
}
}
FILE *user_spool = NULL;
time_t now;
int mail_empty = 1;
+ int game;
struct flock fl = { 0 };
fl.l_type = F_WRLCK;
assert (loggedin);
- len = strlen(myconfig->spool) + strlen (username) + 1;
+ game = 0; /*TODO: find_curr_player_game(username) */
+
+ if (strlen(myconfig[game]->spool) < 1) return;
+
+ len = strlen(myconfig[game]->spool) + strlen (username) + 1;
spool_fn = malloc (len + 1);
time (&now);
- snprintf (spool_fn, len + 1, "%s/%s", myconfig->spool, username);
+ snprintf (spool_fn, len + 1, "%s/%s", myconfig[game]->spool, username);
/* print the enter your message line */
clear ();
return;
}
+void
+drawgamemenu(int game)
+{
+ static int flood = 0;
+
+ if (loggedin) {
+
+ clear();
+
+ drawbanner(1,0);
+
+ mvprintw(banner.len + 2, 1, "Logged in as: %s", me->username);
+
+ mvaddstr (banner.len + 4, 1, "c) Change password");
+ mvaddstr (banner.len + 5, 1, "e) Change email address");
+ mvaddstr (banner.len + 6, 1, "w) Watch games in progress");
+ if (myconfig[game]->rcfile)
+ mvprintw (banner.len + 7, 1, "o) Edit options for %s", myconfig[game]->game_name);
+ mvprintw (banner.len + 8, 1, "p) Play %s", myconfig[game]->game_name);
+ mvaddstr (banner.len + 9, 1, "q) Return to previous menu");
+ mvaddstr (banner.len + 11, 1, "=> ");
+
+ refresh ();
+ }
+
+ /* for retarded clients */
+ flood++;
+ if (flood >= 20)
+ {
+ endwin();
+ graceful_exit (119);
+ }
+
+}
+
void
drawmenu ()
{
static int flood = 0;
+ int game = 0;
clear ();
mvprintw (banner.len + 2, 1, "Logged in as: %s", me->username);
mvaddstr (banner.len + 4, 1, "c) Change password");
mvaddstr (banner.len + 5, 1, "e) Change email address");
- mvaddstr (banner.len + 6, 1, "o) Edit option file");
- mvaddstr (banner.len + 7, 1, "w) Watch games in progress");
- mvprintw (banner.len + 8, 1, "p) Play %s!", myconfig->game_name);
- mvaddstr (banner.len + 9, 1, "q) Quit");
- mvaddstr (banner.len + 11, 1, "=> ");
+ mvaddstr (banner.len + 6, 1, "w) Watch games in progress");
+ if (num_games >= 1)
+ for (game = 0; (game <= num_games) && myconfig && myconfig[game] && myconfig[game]->game_name; game++)
+ mvprintw (banner.len + 7 + game, 1, "%c) Go to %s menu", '1'+game, myconfig[game]->game_name);
+ else {
+ if (myconfig[0]->rcfile)
+ mvprintw (banner.len + 7, 1, "o) Edit options");
+ mvprintw (banner.len + 8, 1, "p) Play %s", myconfig[0]->game_name);
+ }
+ mvaddstr (banner.len + 9 + game, 1, "q) Quit");
+ mvaddstr (banner.len + 11 + game, 1, "=> ");
}
else
{
mvaddstr (banner.len + 5, 1, "r) Register new user");
mvaddstr (banner.len + 6, 1, "w) Watch games in progress");
mvaddstr (banner.len + 7, 1, "q) Quit");
- mvaddstr (banner.len + 9, 1, "=> ");
+ mvaddstr (banner.len + 11, 1, "=> ");
}
refresh ();
if (passwordgood(pass))
{
loggedin = 1;
- snprintf (rcfilename, 80, "%srcfiles/%s.nethackrc", myconfig->dglroot, me->username);
setproctitle ("%s", me->username);
}
}
if (passwordgood (pw_buf))
{
loggedin = 1;
- snprintf (rcfilename, 80, "%srcfiles/%s.nethackrc", myconfig->dglroot, me->username);
setproctitle ("%s", me->username);
}
else
loggedin = 0;
- if (f_num >= myconfig->max)
+ if (f_num >= globalconfig.max)
{
clear ();
loggedin = 1;
- snprintf (rcfilename, 80, "%srcfiles/%s.nethackrc", myconfig->dglroot, me->username);
setproctitle ("%s", me->username);
- if (access (rcfilename, R_OK) == -1)
- write_canned_rcfile (rcfilename);
-
/* create their ttyrec dir */
- snprintf (dirname, 100, "%sttyrec/%s", myconfig->dglroot, me->username);
+ snprintf (dirname, 100, "%sttyrec/%s", globalconfig.dglroot, me->username);
if (access (dirname, F_OK) != 0)
mkdir (dirname, 0755);
if (!nolock)
{
- fpl = fopen (myconfig->lockfile, "r");
+ fpl = fopen (myconfig[0]->lockfile, "r");
if (!fpl)
graceful_exit (106);
if (fcntl (fileno (fpl), F_SETLKW, &fl) == -1)
graceful_exit (114);
}
- fp = fopen (myconfig->passwd, "r");
+ fp = fopen (myconfig[0]->passwd, "r");
if (!fp)
graceful_exit (106);
f_num++;
/* prevent a buffer overrun here */
- if (f_num > myconfig->max)
+ if (f_num > globalconfig.max)
{
fprintf(stderr,"ERROR: number of users in database exceeds maximum. Exiting.\n");
graceful_exit (109);
/* ************************************************************* */
void
-write_canned_rcfile (char *target)
+write_canned_rcfile (int game, char *target)
{
FILE *canned, *newfile;
char buf[1024], *rfn;
size_t bytes, len;
- len = strlen(myconfig->rcfile) + 2;
+ len = strlen(myconfig[game]->rcfile) + 2;
rfn = malloc(len);
- snprintf (rfn, len, "/%s", myconfig->rcfile);
+ snprintf (rfn, len, "/%s", myconfig[game]->rcfile);
if (!(newfile = fopen (target, "w")))
{
mvaddstr (13, 1,
"You don't know how to write that! You write \"%s was here\" and the scroll disappears.");
mvaddstr (14, 1,
- "(Sorry, but I couldn't open one of the nethackrc files. This is a bug.)");
+ "(Sorry, but I couldn't open one of the config files. This is a bug.)");
return;
}
void
-editoptions ()
+editoptions (int game)
{
FILE *rcfile;
char *myargv[3];
pid_t editor;
- rcfile = fopen (rcfilename, "r");
- if (!rcfile) /* should not really happen except for old users */
- write_canned_rcfile (rcfilename);
+ rcfile = fopen (dgl_format_str(game, me, myconfig[game]->rc_fmt), "r");
+ if (!rcfile)
+ write_canned_rcfile (game, dgl_format_str(game, me, myconfig[game]->rc_fmt));
/* use whatever editor_main to edit */
myargv[0] = "";
- myargv[1] = rcfilename;
+ myargv[1] = dgl_format_str(game, me, myconfig[game]->rc_fmt);
myargv[2] = 0;
endwin ();
sigaddset(&toblock, SIGTERM);
sigprocmask(SIG_BLOCK, &toblock, &oldmask);
- fpl = fopen (myconfig->lockfile, "r+");
+ fpl = fopen (myconfig[0]->lockfile, "r+");
if (!fpl)
{
sigprocmask(SIG_SETMASK, &oldmask, NULL);
freefile ();
readfile (1);
- fp = fopen (myconfig->passwd, "w");
+ fp = fopen (myconfig[0]->passwd, "w");
if (!fp)
{
sigprocmask(SIG_SETMASK, &oldmask, NULL);
}
if (loggedin && !my_done)
{ /* new entry */
- if (f_num < myconfig->max)
+ if (f_num < globalconfig.max)
fprintf (fp, "%s:%s:%s:%s\n", me->username, me->email, me->password,
me->env);
else /* Oops, someone else registered the last available slot first */
/* ************************************************************* */
/* ************************************************************* */
+
/*
* Backup the savefile, if configured.
* Returns non-zero if successful, otherwise an error message has been
* given already.
*/
int
-backup_savefile (void)
+backup_savefile (int game)
{
- char buf[1024];
- char *f, *p, *end;
+ /*char buf[1024];*/
+ char *f, *p, *end, *buf;
int ispercent = 0, n;
int in, out;
- f = myconfig->savefilefmt;
+ f = myconfig[game]->savefilefmt;
if (*f == '\0')
return 1;
if (me == NULL)
graceful_exit (147);
+ buf = dgl_format_str(game, me, f);
p = buf;
- end = buf + sizeof(buf) - 10; /* make sure we can add .bak */
- while (*f)
- {
- if (ispercent)
- {
- switch (*f)
- {
- case 'u':
- snprintf (p, end + 1 - p, "%d", myconfig->shed_uid);
- while (*p != '\0')
- p++;
- break;
- case 'n':
- snprintf (p, end + 1 - p, "%s", me->username);
- while (*p != '\0')
- p++;
- break;
- default:
- *p = *f;
- if (p < end)
- p++;
- }
- ispercent = 0;
- }
- else
- {
- if (*f == '%')
- ispercent = 1;
- else
- {
- *p = *f;
- if (p < end)
- p++;
- }
- }
- f++;
- }
- *p = '\0';
+ p += strlen(buf);
/*fprintf(stderr, "***\n[SAVEFILE=%s]\n***\n", buf);
sleep(3);*/
}
int
-purge_stale_locks (void)
+purge_stale_locks (int game)
{
DIR *pdir;
struct dirent *dent;
size_t len;
short firsttime = 1;
- len = strlen(myconfig->dglroot) + ARRAY_SIZE("inprogress/") + 1;
+ len = strlen(globalconfig.dglroot) + strlen(myconfig[game]->inprogressdir) + 1;
dir = malloc(len);
- snprintf(dir, len, "%sinprogress/", myconfig->dglroot);
-
+ snprintf(dir, len, "%s%s", globalconfig.dglroot, myconfig[game]->inprogressdir);
+
if (!(pdir = opendir (dir)))
graceful_exit (200);
pid_t pid;
size_t len;
int seconds = 0;
-
+
if (!strcmp (dent->d_name, ".") || !strcmp (dent->d_name, ".."))
continue;
if (strncmp (dent->d_name, me->username, colon - dent->d_name))
continue;
- len = strlen (dent->d_name) + strlen(myconfig->dglroot) + 12;
+ len = strlen (dent->d_name) + strlen(globalconfig.dglroot) + 12;
fn = malloc (len);
- snprintf (fn, len, "%sinprogress/%s", myconfig->dglroot, dent->d_name);
+ snprintf (fn, len, "%s%s%s", globalconfig.dglroot, myconfig[game]->inprogressdir, dent->d_name);
+
+ fprintf (stderr, "ERR:'%s'\n", fn);
if (!(ipfile = fopen (fn, "r")))
graceful_exit (202);
#define HUP_WAIT 10 /* seconds before HUPPING */
mvprintw (3, 1,
"There are some stale %s processes, will recover in %d seconds.",
- myconfig->game_name, HUP_WAIT);
+ myconfig[game]->game_name, HUP_WAIT);
mvaddstr (4, 1,
"Press a key NOW if you don't want this to happen!");
- move (3, 58); /* pedantry */
+ move (3, 51 + strlen(myconfig[game]->game_name)); /* pedantry */
halfdelay(10);
-
+
for (seconds = HUP_WAIT - 1; seconds >= 0; seconds--)
{
if (getch() != ERR)
cbreak();
return 0;
}
- mvprintw (3, 57, "%d%s", seconds, (seconds > 9) ? "" : " ");
+ mvprintw (3, 50 + strlen(myconfig[game]->game_name), "%d%s", seconds, (seconds > 9) ? "" : " ");
}
nocbreak();
cbreak();
-
+
firsttime = 0;
}
if (seconds == 10)
{
mvprintw (3, 1,
- "Couldn't terminate one of your stale %s processes gracefully.", myconfig->game_name);
+ "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')
{
{
endwin ();
fprintf (stderr, "Sorry, no %s for you now, please "
- "contact the admin.\n", myconfig->game_name);
+ "contact the admin.\n", myconfig[game]->game_name);
graceful_exit (1);
}
}
return 1;
}
-void
-menuloop (void)
+int
+gamemenuloop(int game)
{
int userchoice = 0;
- while ((userchoice != 'p') | (!loggedin))
+ while (1)
{
- drawmenu ();
+ drawgamemenu (game);
userchoice = getch ();
switch (tolower (userchoice))
{
+ default:
+ break;
+ case 'p':
+ if (loggedin)
+ return 1;
+ break;
case 'c':
if (loggedin)
changepw (1);
change_email();
break;
case 'w':
- inprogressmenu ();
- break;
- case 'o':
- if (loggedin)
- editoptions ();
+ inprogressmenu (game);
break;
+ case 'o':
+ if (loggedin && myconfig[game]->rcfile)
+ editoptions (game);
+ break;
case 'q':
- endwin ();
- graceful_exit(0);
+ return 0;
+ /* endwin ();
+ graceful_exit(0);*/
/* break; */
case 'r':
if (!loggedin) /*not visible to loggedin */
case 'l':
if (!loggedin) /* not visible to loggedin */
loginprompt (0);
- break;
}
}
+ return 0;
}
+int
+menuloop (void)
+{
+ int userchoice = 0;
+ while (1)
+ {
+ drawmenu ();
+ userchoice = getch ();
+
+ if ((num_games >= 1) && loggedin && (userchoice >= '1') && (userchoice <= ('1'+num_games))) {
+ int game = userchoice - '1';
+ if (myconfig[game] && myconfig[game]->game_name) {
+ if (gamemenuloop(game)) return game;
+ }
+ } else {
+ switch (tolower (userchoice))
+ {
+ default:
+ break;
+ case 'c':
+ if (loggedin)
+ changepw (1);
+ break;
+ case 'e':
+ if (loggedin)
+ change_email();
+ break;
+ case 'w':
+ inprogressmenu (-1);
+ break;
+ case 'o':
+ if (loggedin && (num_games == 0) && myconfig[0]->rcfile)
+ editoptions(0);
+ break;
+ case 'p':
+ if (loggedin && (num_games == 0))
+ return 0;
+ break;
+ case 'q':
+ endwin ();
+ graceful_exit(0);
+ /* break; */
+ case 'r':
+ if (!loggedin) /*not visible to loggedin */
+ newuser ();
+ break;
+ case 'l':
+ if (!loggedin) /* not visible to loggedin */
+ loginprompt (0);
+ }
+ }
+ }
+ return -1;
+}
+
+
int
authenticate ()
{
me = users[me_index];
if (passwordgood (pw_buf))
{
- games = populate_games (&len);
+ games = populate_games (-1, &len);
for (i = 0; i < len; i++)
if (!strcmp (games[i]->name, user_buf))
{
return 1;
}
win.ws_row = win.ws_col = 0;
- gen_inprogress_lock (getppid (), gen_nhext_filename ());
+ gen_inprogress_lock (0, getppid (), gen_nhext_filename ());
return 0;
}
}
unsigned int len;
int c;
int nhext = 0, nhauth = 0;
+ int userchoice;
#ifndef HAVE_SETPROCTITLE
/* save argc, argv */
if (!nhext && !nhauth)
ttyrec_getpty ();
- if (geteuid () != myconfig->shed_uid)
+ if (geteuid () != globalconfig.shed_uid)
{
/* chroot */
- if (chroot (myconfig->chroot))
+ if (chroot (globalconfig.chroot))
{
perror ("cannot change root directory");
graceful_exit (1);
}
/* shed privs. this is done immediately after chroot. */
- if (setgroups (1, &myconfig->shed_gid) == -1)
+ if (setgroups (1, &globalconfig.shed_gid) == -1)
{
perror ("setgroups");
graceful_exit (1);
}
- if (setgid (myconfig->shed_gid) == -1)
+ if (setgid (globalconfig.shed_gid) == -1)
{
perror ("setgid");
graceful_exit (1);
}
- if (setuid (myconfig->shed_uid) == -1)
+ if (setuid (globalconfig.shed_uid) == -1)
{
perror ("setuid");
graceful_exit (1);
{
char *myargv[3];
- myargv[0] = myconfig->game_path;
+ myargv[0] = myconfig[0]->game_path;
myargv[1] = "--proxy";
myargv[2] = 0;
- execvp (myconfig->game_path, myargv);
- perror (myconfig->game_path);
+ execvp (myconfig[0]->game_path, myargv);
+ perror (myconfig[0]->game_path);
graceful_exit (1);
}
}
initcurses ();
- menuloop();
+
+ userchoice = menuloop();
assert (loggedin);
- while (!purge_stale_locks())
- menuloop();
+ if ((userchoice >= 0) && (userchoice <= num_games)) {
+ while (!purge_stale_locks(userchoice)) {
+ userchoice = gamemenuloop(userchoice);
+ }
+ if (!((userchoice >= 0) && (userchoice <= num_games)))
+ graceful_exit (1);
+ } else {
+ graceful_exit (1);
+ }
+
+ 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));
+ }
setproctitle ("%s [playing]", me->username);
endwin ();
signal(SIGWINCH, SIG_DFL);
- if (!backup_savefile ())
+ if (!backup_savefile (userchoice))
graceful_exit (5);
/* environment */
- snprintf (atrcfilename, 81, "@%s", rcfilename);
+ if (myconfig[userchoice]->rcfile) {
+ snprintf (atrcfilename, 81, "@%s", dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt));
+ mysetenv ("NETHACKOPTIONS", atrcfilename, 1);
+ }
- len = strlen(myconfig->spool) + strlen (me->username) + 1;
+ len = strlen(myconfig[userchoice]->spool) + strlen (me->username) + 1;
spool = malloc (len + 1);
- snprintf (spool, len + 1, "%s/%s", myconfig->spool, me->username);
+ snprintf (spool, len + 1, "%s/%s", myconfig[userchoice]->spool, me->username);
- mysetenv ("NETHACKOPTIONS", atrcfilename, 1);
mysetenv ("MAIL", spool, 1);
mysetenv ("SIMPLEMAIL", "1", 1);
free (spool);
+ /* fix the variables in the arguments */
+ for (i = 0; i < myconfig[userchoice]->num_args; i++) {
+ char *tmp = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i]));
+ free(myconfig[userchoice]->bin_args[i]);
+ myconfig[userchoice]->bin_args[i] = tmp;
+ }
+
/* launch program */
- ttyrec_main (me->username, gen_ttyrec_filename());
+ ttyrec_main (userchoice, me->username, gen_ttyrec_filename());
/* NOW we can safely kill this */
freefile ();
+ /*
+ printf("config:'%s'\n", config);
+
+ printf("chroot:'%s'\n", globalconfig.chroot);
+ printf("gamepath:'%s'\n", myconfig[userchoice]->game_path);
+ printf("game:'%s'\n", myconfig[userchoice]->game_name);
+ printf("dglroot:'%s'\n", globalconfig.dglroot);
+ printf("lockfile:'%s'\n", myconfig[userchoice]->lockfile);
+ printf("passwd:'%s'\n", myconfig[userchoice]->passwd);
+ printf("banner:'%s'\n", globalconfig.banner);
+ printf("rcfile:'%s'\n", myconfig[userchoice]->rcfile);
+ printf("spool:'%s'\n", myconfig[userchoice]->spool);
+ printf("savefilefmt:'%s'\n", myconfig[userchoice]->savefilefmt);
+ printf("dgl_format_str(savefilefmt):'%s'\n", dgl_format_str(userchoice, myconfig[userchoice]->savefilefmt));
+ printf("inprogressdir:'%s'\n", myconfig[userchoice]->inprogressdir);
+ */
+
if (me)
free (me);
graceful_exit (1);
+
return 1;
}
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
+
+/* max # of different games playable from within this dgl */
+#define DIFF_GAMES 3
+
struct dg_user
{
char *username;
struct dg_config
{
- char* chroot;
char* game_path;
char* game_name;
- char* dglroot;
char* lockfile;
char* passwd;
- char* banner;
char* rcfile;
char* spool;
- char* shed_user;
- char* shed_group;
- uid_t shed_uid;
- gid_t shed_gid;
- unsigned long max;
char* savefilefmt;
+ char* inprogressdir;
+ int num_args; /* # of bin_args */
+ char **bin_args; /* args for game binary */
+ char *rc_fmt;
+};
+
+struct dg_globalconfig
+{
+ char* chroot;
+ char* dglroot;
+ char* banner;
+ unsigned long max;
+ char* shed_user;
+ char* shed_group;
+ uid_t shed_uid;
+ gid_t shed_gid;
};
/* Global variables */
extern char* config; /* file path */
-extern struct dg_config *myconfig;
+extern struct dg_config **myconfig;
extern char *chosen_name;
extern int loggedin;
extern int silent;
extern int set_max;
+extern struct dg_globalconfig globalconfig;
+
+extern int num_games;
+
/* dgamelaunch.c */
extern void create_config(void);
extern void ttyrec_getmaster(void);
extern char *gen_ttyrec_filename(void);
-extern char *gen_inprogress_lock(pid_t pid, char *ttyrec_filename);
+extern char *gen_inprogress_lock(int game, pid_t pid, char *ttyrec_filename);
extern void catch_sighup(int signum);
-extern void loadbanner(struct dg_banner *ban);
+extern void loadbanner(int game, struct dg_banner *ban);
extern void drawbanner(unsigned int start_line, unsigned int howmany);
-extern struct dg_game **populate_games(int *l);
-extern void inprogressmenu(void);
+extern char *dgl_format_str(int game, struct dg_user *me, char *str);
+extern struct dg_game **populate_games(int game, int *l);
+extern void inprogressmenu(int gameid);
extern void change_email(void);
extern int changepw(int dowrite);
extern void domailuser(char *username);
extern int passwordgood(char *cpw);
extern int readfile(int nolock);
extern int userexist(char *cname);
-extern void write_canned_rcfile(char *target);
-extern void editoptions(void);
+extern void write_canned_rcfile(int game, char *target);
+extern void editoptions(int game);
extern void writefile(int requirenew);
extern void graceful_exit(int status);
-extern int purge_stale_locks(void);
-extern void menuloop(void);
+extern int purge_stale_locks(int game);
+extern int menuloop(void);
extern void ttyrec_getpty(void);
#if !defined(BSD) && !defined(__linux__)
extern int mysetenv (const char* name, const char* value, int overwrite);
extern int yyparse ();
/* Data structures */
-struct dg_config *myconfig = NULL;
+struct dg_config **myconfig = NULL;
struct dg_config defconfig = {
- /* chroot = */ "/var/lib/dgamelaunch/",
+ /* chroot = */ /*"/var/lib/dgamelaunch/",*/
/* game_path = */ "/bin/nethack",
/* game_name = */ "NetHack",
- /* dglroot = */ "/dgldir/",
+ /* dglroot = *//* "/dgldir/",*/
/* lockfile = */ "/dgl-lock",
/* passwd = */ "/dgl-login",
- /* banner = */ "/dgl-banner",
- /* rcfile = */ "/dgl-default-rcfile",
+ /* banner = */ /*"/dgl-banner",*/
+ /* rcfile = */ NULL, /*"/dgl-default-rcfile",*/
/* spool = */ "/var/mail/",
- /* shed_user = */ "games",
- /* shed_group = */ "games",
- /* shed_uid = */ 5,
- /* shed_gid = */ 60, /* games:games in Debian */
- /* max = */ 64000,
- /* savefilefmt = */ "" /* don't do this by default */
+ /* shed_user = */ /*"games",*/
+ /* shed_group = */ /*"games",*/
+ /* shed_uid = *//* 5,*/
+ /* shed_gid = */ /*60,*/ /* games:games in Debian */
+ /* max = */ /*64000,*/
+ /* savefilefmt = */ "", /* don't do this by default */
+ /* inprogressdir = */ "inprogress/",
+ /* num_args = */ 0,
+ /* bin_args = */ NULL,
+ /* rc_fmt = */ "%rrcfiles/%n.nethackrc" /* [dglroot]rcfiles/[username].nethackrc */
};
char* config = NULL;
int silent = 0;
-int set_max = 0; /* XXX */
+/*int set_max = 0;*/ /* XXX */
int loggedin = 0;
char *chosen_name;
+int num_games = 0;
+
+struct dg_globalconfig globalconfig;
+
+/*
+ * replace following codes with variables:
+ * %u == shed_uid (number)
+ * %n == user name (string)
+ * %r == chroot (string)
+ */
+char *
+dgl_format_str(int game, struct dg_user *me, char *str)
+{
+ static char buf[1024];
+ char *f, *p, *end;
+ int ispercent = 0;
+
+ if (!str) return NULL;
+
+ f = str;
+ p = buf;
+ end = buf + sizeof(buf) - 10;
+
+ while (*f) {
+ if (ispercent) {
+ switch (*f) {
+ case 'u':
+ snprintf (p, end + 1 - p, "%d", globalconfig.shed_uid);
+ while (*p != '\0')
+ p++;
+ break;
+ case 'n':
+ snprintf (p, end + 1 - p, "%s", me->username);
+ while (*p != '\0')
+ p++;
+ break;
+ case 'r':
+ snprintf (p, end + 1 - p, "%s", globalconfig.dglroot);
+ while (*p != '\0')
+ p++;
+ break;
+ default:
+ *p = *f;
+ if (p < end)
+ p++;
+ }
+ ispercent = 0;
+ } else {
+ if (*f == '%')
+ ispercent = 1;
+ else {
+ *p = *f;
+ if (p < end)
+ p++;
+ }
+ }
+ f++;
+ }
+ *p = '\0';
+
+ return buf;
+}
+
struct dg_game **
-populate_games (int *l)
+populate_games (int xgame, int *l)
{
int fd, len, n, is_nhext, pid;
DIR *pdir;
struct flock fl = { 0 };
size_t slen;
+ int game;
+
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
len = 0;
-
- slen = strlen(myconfig->dglroot) + ARRAY_SIZE("inprogress/") + 1;
- dir = malloc(slen);
- snprintf(dir, slen, "%sinprogress/", myconfig->dglroot);
- if (!(pdir = opendir (dir)))
+ for (game = ((xgame < 0) ? 0 : xgame); game <= ((xgame < 0) ? num_games : xgame); game++) {
+
+ slen = strlen(globalconfig.dglroot) + strlen(myconfig[game]->inprogressdir) + 1;
+ dir = malloc(slen);
+ snprintf(dir, slen, "%s%s", globalconfig.dglroot, myconfig[game]->inprogressdir);
+
+ if (!(pdir = opendir (dir)))
graceful_exit (140);
- while ((pdirent = readdir (pdir)))
+ while ((pdirent = readdir (pdir)))
{
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, "%sinprogress/%s", myconfig->dglroot, pdirent->d_name);
+ snprintf (fullname, 130, "%s%s%s", globalconfig.dglroot, myconfig[game]->inprogressdir, pdirent->d_name);
fd = 0;
/* O_RDWR here should be O_RDONLY, but we need to test for
/* stat to check idle status */
if (!is_nhext)
{
- snprintf (ttyrecname, 130, "%sttyrec/%s", myconfig->dglroot, pdirent->d_name);
+ snprintf (ttyrecname, 130, "%sttyrec/%s", globalconfig.dglroot, pdirent->d_name);
replacestr = strchr (ttyrecname, ':');
if (!replacestr)
graceful_exit (145);
fl.l_type = F_WRLCK;
}
- closedir (pdir);
+ closedir (pdir);
+ }
*l = len;
return games;
}
create_config ()
{
FILE *config_file = NULL;
+ int tmp;
if (config)
{
else
{
#ifdef DEFCONFIG
+ /* fprintf(stderr, "DEFCONFIG: %s\n", DEFCONFIG);*/
config = DEFCONFIG;
if ((config_file = fopen(DEFCONFIG, "r")) != NULL)
{
yyin = config_file;
+ /* fprintf(stderr, "PARSING\n");*/
yyparse();
+ /* fprintf(stderr, "PARSED\n");*/
fclose(config_file);
}
#else
- myconfig = &defconfig;
+ /* fprintf(stderr, "NO DEFCONFIG\n");*/
+ myconfig = calloc(DIFF_GAMES, sizeof(myconfig[0]));
+ for (tmp = 0; tmp < DIFF_GAMES; tmp++)
+ myconfig[tmp] = NULL;
+ myconfig[0] = &defconfig;
return;
#endif
}
if (!myconfig) /* a parse error occurred */
{
- myconfig = &defconfig;
+ /* fprintf(stderr, "PARSE ERROR\n");*/
+ myconfig = calloc(DIFF_GAMES, sizeof(myconfig[0]));
+ for (tmp = 0; tmp < DIFF_GAMES; tmp++)
+ myconfig[tmp] = NULL;
+ myconfig[0] = &defconfig;
return;
}
/* Fill the rest with defaults */
- if (!myconfig->shed_user && myconfig->shed_uid == (uid_t)-1)
- {
- struct passwd *pw;
- if ((pw = getpwnam(defconfig.shed_user)))
- myconfig->shed_uid = pw->pw_uid;
- else
- myconfig->shed_uid = defconfig.shed_uid;
- }
- if (!myconfig->shed_group && myconfig->shed_gid == (gid_t)-1)
- {
- struct group *gr;
- if ((gr = getgrnam(defconfig.shed_group)))
- myconfig->shed_gid = gr->gr_gid;
- else
- myconfig->shed_gid = defconfig.shed_gid;
+ for (tmp = 0; tmp < DIFF_GAMES; tmp++) {
+
+ if (!myconfig[tmp]->game_path) myconfig[tmp]->game_path = defconfig.game_path;
+ if (!myconfig[tmp]->game_name) myconfig[tmp]->game_name = defconfig.game_name;
+ if (!myconfig[tmp]->rcfile) myconfig[tmp]->rcfile = defconfig.rcfile;
+ if (!myconfig[tmp]->spool) myconfig[tmp]->spool = defconfig.spool;
+ if (!myconfig[tmp]->passwd) myconfig[tmp]->passwd = defconfig.passwd;
+ if (!myconfig[tmp]->lockfile) myconfig[tmp]->lockfile = defconfig.lockfile;
+ if (!myconfig[tmp]->savefilefmt) myconfig[tmp]->savefilefmt = defconfig.savefilefmt;
+ if (!myconfig[tmp]->inprogressdir) myconfig[tmp]->inprogressdir = defconfig.inprogressdir;
+
+
}
- if (myconfig->max == 0 && !set_max) myconfig->max = defconfig.max;
- if (!myconfig->banner) myconfig->banner = defconfig.banner;
- if (!myconfig->chroot) myconfig->chroot = defconfig.chroot;
- if (!myconfig->game_path) myconfig->game_path = defconfig.game_path;
- if (!myconfig->game_name) myconfig->game_name = defconfig.game_name;
- if (!myconfig->dglroot) myconfig->dglroot = defconfig.dglroot;
- if (!myconfig->rcfile) myconfig->rcfile = defconfig.rcfile;
- if (!myconfig->spool) myconfig->spool = defconfig.spool;
- if (!myconfig->passwd) myconfig->passwd = defconfig.passwd;
- if (!myconfig->lockfile) myconfig->lockfile = defconfig.lockfile;
- if (!myconfig->savefilefmt) myconfig->savefilefmt = defconfig.savefilefmt;
+ if (!globalconfig.chroot) globalconfig.chroot = "/var/lib/dgamelaunch/";
+
+ if (globalconfig.max == 0) globalconfig.max = 64000;
+ if (!globalconfig.dglroot) globalconfig.dglroot = "/dgldir/";
+ if (!globalconfig.banner) globalconfig.banner = "/dgl-banner";
+
+ if (!globalconfig.shed_user && globalconfig.shed_uid == (uid_t)-1)
+ {
+ struct passwd *pw;
+ if ((pw = getpwnam("games")))
+ globalconfig.shed_uid = pw->pw_uid;
+ else
+ globalconfig.shed_uid = 5; /* games uid in debian */
+ }
+
+ if (!globalconfig.shed_group && globalconfig.shed_gid == (gid_t)-1)
+ {
+ struct group *gr;
+ if ((gr = getgrnam("games")))
+ globalconfig.shed_gid = gr->gr_gid;
+ else
+ globalconfig.shed_gid = 60; /* games gid in debian */
+ }
+
}
create_config();
- if (chroot (myconfig->chroot))
+ if (chroot (globalconfig.chroot))
{
perror("Couldn't change root directory");
return 1;
return 1;
}
- games = populate_games (&len);
+ games = populate_games (-1, &len);
if (len == 0)
{
char* fname = NULL;
size_t len;
- len = strlen(myconfig->spool) + strlen(games[i]->name) + 2;
+ len = strlen(myconfig[0]->spool) + strlen(games[i]->name) + 2;
fname = malloc (len + 1);
- snprintf(fname, len, "%s/%s", myconfig->spool, games[i]->name);
+ snprintf(fname, len, "%s/%s", myconfig[0]->spool, games[i]->name);
if ((spool = fopen(fname, "a")) == NULL)
{
# are allowed, such as this. Each configuration option will be explained
# along with its default value.
+
+
+# Global config variables:
+
+
+# Max amount of registered users to allow.
+maxusers = 64000
+
+# Path to a prepared chroot jail.
+chroot_path = "/var/lib/dgamelaunch/"
+
+# From inside the jail, dgamelaunch's working directory for rcfiles/ttyrec/etc
+dglroot = "/dgldir/"
+
+# From inside the jail, location of a banner file that contains no more than
+# 14 lines of 80-column width text. Any more will be truncated.
+banner = "/dgl-banner"
+
# The following two options are fairly insecure. They will force us to
# load the password/group database into memory while still having root
# privileges. Replace them with shed_uid/shed_gid entries as soon as
shed_uid = 5
shed_gid = 60
-# Max amount of registered users to allow.
-maxusers = 64000
-# Path to a prepared chroot jail.
-chroot_path = "/var/lib/dgamelaunch/"
+
+# Next, we'll define one game's data:
+
# From inside the jail, the location of the binary to be launched.
-game_path = "/bin/nethack"
-game_name = "NetHack"
+game_path = "/bin/nethackstub"
+game_name = "NetHack stub"
-# From inside the jail, dgamelaunch's working directory for rcfiles/ttyrec/etc
-dglroot = "/dgldir/"
+# arguments for when we exec the binary
+game_args = "/bin/nethackstub"
+game_args = "foo"
+game_args = "user:%n"
+game_args = "shed_uid:%u"
+game_args = "bar"
# From inside the jail, where dgamelaunch should put mail - should match up with
# NetHack settings.
spooldir = "/var/mail/"
-# From inside the jail, location of a banner file that contains no more than
-# 14 lines of 80-column width text. Any more will be truncated.
-banner = "/dgl-banner"
-
# From inside the jail, the default .nethackrc that is copied for new users.
-rc_template = "/dgl-default-rcfile"
+# rc_template = "/dgl-default-rcfile"
# 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
# decimal representation of shed_uid, %n is replaced by the player's
# user name. Before starting the game, this file is copied to its name
# with ".bak" appended. Set to an empty string to disable this copying.
+
+savefilefmt = "/var/games/nethack/save/%u%n.gz"
+
+# make sure the inprogress dir actually exists. default is "inprogress/"
+# each game you define here must have it's own.
+inprogressdir = "inprogress/"
+
+
+
+#
+# the second game
+#
+#
+game_num = 1
+
+game_path = "/bin/nethack"
+game_name = "NetHack 3.4.3"
+
+game_args = "/bin/nethack"
+game_args = "-u"
+game_args = "%n"
+
+spooldir = "/var/mail/"
+rc_template = "/dgl-default-rcfile"
+# format where player rc files are saved.
+# %r == dglroot
+# %n == user name
+rc_fmt = "%rrcfiles/%n.nethackrc"
+passwd = "/dgl-login"
+lockfile = "/dgl-lock"
savefilefmt = "/var/games/nethack/save/%u%n.gz"
+inprogressdir = "inprogress/"
int uflg;
int
-ttyrec_main (char *username, char* ttyrec_filename)
+ttyrec_main (int game, char *username, char* ttyrec_filename)
{
char dirname[100];
- snprintf (dirname, 100, "%sttyrec/%s/%s", myconfig->dglroot, username,
+ snprintf (dirname, 100, "%sttyrec/%s/%s", globalconfig.dglroot, username,
ttyrec_filename);
atexit(&remove_ipfile);
if (child)
{
close (slave);
- ipfile = gen_inprogress_lock (child, ttyrec_filename);
+ ipfile = gen_inprogress_lock (game, child, ttyrec_filename);
dooutput ();
}
else
- doshell (username);
+ doshell (game, username);
}
doinput ();
}
void
-doshell (char *username)
+doshell (int game, char *username)
{
- char *argv1 = myconfig->game_path;
- char *argv2 = "-u";
- char *myargv[10];
-
getslave ();
(void) close (master);
(void) fclose (fscript);
(void) dup2 (slave, 2);
(void) close (slave);
- myargv[0] = argv1;
- myargv[1] = argv2;
- myargv[2] = username;
- myargv[3] = 0;
-
- execvp (myconfig->game_path, myargv);
+ execvp (myconfig[game]->game_path, myconfig[game]->bin_args);
fail ();
}
extern void getslave (void);
extern void doinput (void);
extern void dooutput (void);
-extern void doshell (char *);
+extern void doshell (int, char *);
extern void finish (int);
extern void remove_ipfile (void);
-extern int ttyrec_main(char *username, char *ttyrec_filename);
+extern int ttyrec_main(int, char *username, char *ttyrec_filename);
extern pid_t child; /* nethack process */
extern int master, slave;