Committing this, currently broken, shouldn't be within 5 minutes
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@248 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
parent
89181d3dcd
commit
901a5ea38a
|
@ -1,4 +1,5 @@
|
|||
dgamelaunch
|
||||
dgl-wall
|
||||
nethackstub
|
||||
tags
|
||||
cscope.out
|
||||
|
|
45
Makefile
45
Makefile
|
@ -41,18 +41,23 @@ LDFLAGS =
|
|||
CFLAGS = -g3 $(optimize) -Wall -Wno-unused $(DEFS)
|
||||
INSTALL = install -c
|
||||
DEFS = -DVERSION=\"$(VERSION)\" -DDEFCONFIG=\"$(DEFCONFIG)\"
|
||||
SRCS = $(EDITOR) ttyrec.c dgamelaunch.c io.c ttyplay.c mygetnstr.c stripgfx.c strlcpy.c strlcat.c y.tab.c lex.yy.c
|
||||
SRCS = $(EDITOR) dgl-common.c ttyrec.c dgamelaunch.c io.c ttyplay.c mygetnstr.c stripgfx.c strlcpy.c strlcat.c y.tab.c lex.yy.c
|
||||
EXTRA_SRCS = nethackstub.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
WALL_OBJS = y.tab.o lex.yy.o dgl-common.o dgl-wall.o strlcat.o strlcpy.o
|
||||
LIBS = -lcurses -lcrypt $(LUTIL) -ll
|
||||
|
||||
all: $(NAME)
|
||||
all: $(NAME) dgl-wall
|
||||
|
||||
$(NAME): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
dgl-wall: $(WALL_OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(WALL_OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(NAME) nethackstub
|
||||
rm -f editors/*.o *.o .#* *~ y.tab.* lex.yy.c
|
||||
rm -f $(NAME) nethackstub dgl-wall
|
||||
rm -f editors/*.o *.o .#* *~ y.tab.* lex.yy.c Makefile.dep
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 $(NAME) $(SBINDIR)
|
||||
|
@ -70,24 +75,30 @@ y.tab.c y.tab.h: config.y
|
|||
lex.yy.o: lex.yy.c
|
||||
y.tab.o: y.tab.c
|
||||
|
||||
dist: clean
|
||||
dist: dep clean
|
||||
rm -rf $(NAME)-$(VERSION)
|
||||
(cd .. && ln -sf $(CURDIR) $(NAME)-$(VERSION))
|
||||
(cd .. && tar $(addprefix --exclude ,$(exclusions)) -chzf $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION))
|
||||
rm -f ../$(NAME)-$(VERSION)
|
||||
@echo "Created source release $(NAME)-$(VERSION).tar.gz"
|
||||
|
||||
# Dependencies - we may auto-generate later
|
||||
|
||||
dep: y.tab.c lex.yy.c
|
||||
@sed -e '/^# Source code dependencies/,$$d' < Makefile > Makefile.dep
|
||||
@echo "# Source code dependencies" >> Makefile.dep
|
||||
$(CC) -MM $(SRCS) $(EXTRA_SRCS) >> Makefile.dep
|
||||
mv Makefile.dep Makefile
|
||||
|
||||
# Source code dependencies
|
||||
ee.o: ee.c
|
||||
io.o: io.c ttyrec.h
|
||||
last_char_is.o: last_char_is.c
|
||||
mygetnstr.o: mygetnstr.c
|
||||
nethackstub.o: nethackstub.c
|
||||
stripgfx.o: stripgfx.c stripgfx.h
|
||||
strlcat.o: strlcat.c
|
||||
strlcpy.o: strlcpy.c
|
||||
ttyplay.o: ttyplay.c dgamelaunch.h ttyplay.h ttyrec.h io.h stripgfx.h
|
||||
dgl-common.o: dgl-common.c dgamelaunch.h
|
||||
ttyrec.o: ttyrec.c dgamelaunch.h ttyrec.h io.h
|
||||
virus.o: virus.c last_char_is.c
|
||||
y.tab.o: y.tab.c dgamelaunch.h
|
||||
dgamelaunch.o: dgamelaunch.c dgamelaunch.h ttyplay.h ttyrec.h y.tab.h
|
||||
io.o: io.c ttyrec.h
|
||||
ttyplay.o: ttyplay.c dgamelaunch.h ttyplay.h ttyrec.h io.h stripgfx.h
|
||||
mygetnstr.o: mygetnstr.c
|
||||
stripgfx.o: stripgfx.c stripgfx.h
|
||||
strlcpy.o: strlcpy.c
|
||||
strlcat.o: strlcat.c
|
||||
y.tab.o: y.tab.c dgamelaunch.h
|
||||
lex.yy.o: lex.yy.c y.tab.h dgamelaunch.h
|
||||
nethackstub.o: nethackstub.c
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
# define NOSTREAMS
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
struct dg_user
|
||||
{
|
||||
char *username;
|
||||
|
@ -89,6 +93,11 @@ extern void writefile(int requirenew);
|
|||
extern void graceful_exit(int status);
|
||||
extern int purge_stale_locks(void);
|
||||
extern void menuloop(void);
|
||||
#if !defined(BSD) && !defined(__linux__)
|
||||
extern int mysetenv (const char* name, const char* value, int overwrite);
|
||||
#else
|
||||
# define mysetenv setenv
|
||||
#endif
|
||||
|
||||
/* strlcpy.c */
|
||||
extern size_t strlcpy (char *dst, const char *src, size_t siz);
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/* Functions common to both dgamelaunch itself and dgl-wall. */
|
||||
|
||||
#include "dgamelaunch.h"
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
extern FILE* yyin;
|
||||
extern int yyparse ();
|
||||
|
||||
/* Data structures */
|
||||
struct dg_config *myconfig = NULL;
|
||||
struct dg_config defconfig = {
|
||||
/* chroot = */ "/var/lib/dgamelaunch/",
|
||||
/* nethack = */ "/bin/nethack",
|
||||
/* dglroot = */ "/dgldir/",
|
||||
/* lockfile = */ "/dgl-lock",
|
||||
/* passwd = */ "/dgl-login",
|
||||
/* banner = */ "/dgl-banner",
|
||||
/* rcfile = */ "/dgl-default-rcfile",
|
||||
/* spool = */ "/var/mail/",
|
||||
/* shed_user = */ "games",
|
||||
/* shed_group = */ "games",
|
||||
/* shed_uid = */ 5,
|
||||
/* shed_gid = */ 60, /* games:games in Debian */
|
||||
/* max = */ 64000
|
||||
};
|
||||
|
||||
char* config = NULL;
|
||||
int silent = 0;
|
||||
int set_max = 0; /* XXX */
|
||||
int loggedin = 0;
|
||||
char *chosen_name;
|
||||
|
||||
struct dg_game **
|
||||
populate_games (int *l)
|
||||
{
|
||||
int fd, len;
|
||||
DIR *pdir;
|
||||
struct dirent *pdirent;
|
||||
struct stat pstat;
|
||||
char fullname[130], ttyrecname[130];
|
||||
char *replacestr, *dir;
|
||||
struct dg_game **games = NULL;
|
||||
struct flock fl = { 0 };
|
||||
size_t slen;
|
||||
|
||||
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)))
|
||||
graceful_exit (140);
|
||||
|
||||
while ((pdirent = readdir (pdir)))
|
||||
{
|
||||
if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
|
||||
continue;
|
||||
|
||||
snprintf (fullname, 130, "%sinprogress/%s", myconfig->dglroot, pdirent->d_name);
|
||||
|
||||
fd = 0;
|
||||
/* O_RDWR here should be O_RDONLY, but we need to test for
|
||||
* an exclusive lock */
|
||||
fd = open (fullname, O_RDWR);
|
||||
if ((fd > 0) && fcntl (fd, F_SETLK, &fl) == -1)
|
||||
{
|
||||
|
||||
/* stat to check idle status */
|
||||
snprintf (ttyrecname, 130, "%sttyrec/%s", myconfig->dglroot, pdirent->d_name);
|
||||
replacestr = strchr (ttyrecname, ':');
|
||||
if (!replacestr)
|
||||
graceful_exit (145);
|
||||
replacestr[0] = '/';
|
||||
if (!stat (ttyrecname, &pstat))
|
||||
{
|
||||
/* now it's a valid game for sure */
|
||||
games = realloc (games, sizeof (struct dg_game) * (len + 1));
|
||||
games[len] = malloc (sizeof (struct dg_game));
|
||||
games[len]->ttyrec_fn = strdup (pdirent->d_name);
|
||||
|
||||
if (!(replacestr = strchr (pdirent->d_name, ':')))
|
||||
graceful_exit (146);
|
||||
else
|
||||
*replacestr = '\0';
|
||||
|
||||
games[len]->name = malloc (strlen (pdirent->d_name) + 1);
|
||||
strlcpy (games[len]->name, pdirent->d_name,
|
||||
strlen (pdirent->d_name) + 1);
|
||||
|
||||
games[len]->date = malloc (11);
|
||||
strlcpy (games[len]->date, replacestr + 1, 11);
|
||||
|
||||
games[len]->time = malloc (9);
|
||||
strlcpy (games[len]->time, replacestr + 12, 9);
|
||||
|
||||
games[len]->idle_time = pstat.st_mtime;
|
||||
|
||||
len++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clean dead ones */
|
||||
unlink (fullname);
|
||||
}
|
||||
fl.l_type = F_UNLCK;
|
||||
|
||||
fcntl (fd, F_SETLK, &fl);
|
||||
|
||||
fl.l_type = F_WRLCK;
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
closedir (pdir);
|
||||
*l = len;
|
||||
return games;
|
||||
}
|
||||
|
||||
void
|
||||
create_config ()
|
||||
{
|
||||
FILE *config_file = NULL;
|
||||
|
||||
if (config)
|
||||
{
|
||||
if ((config_file = fopen(config, "r")) != NULL)
|
||||
{
|
||||
yyin = config_file;
|
||||
yyparse();
|
||||
fclose(config_file);
|
||||
free (config);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
|
||||
graceful_exit(104);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!myconfig) /* a parse error occurred */
|
||||
{
|
||||
myconfig = &defconfig;
|
||||
return;
|
||||
}
|
||||
/* Fill the rest with defaults */
|
||||
if (!myconfig->shed_user && myconfig->shed_uid == -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 == -1)
|
||||
{
|
||||
struct group *gr;
|
||||
if ((gr = getgrnam(defconfig.shed_group)))
|
||||
myconfig->shed_gid = gr->gr_gid;
|
||||
else
|
||||
myconfig->shed_gid = defconfig.shed_gid;
|
||||
}
|
||||
|
||||
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->nethack) myconfig->nethack = defconfig.nethack;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
myconfig = &defconfig;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BSD) && !defined(__linux__)
|
||||
int
|
||||
mysetenv (const char* name, const char* value, int overwrite)
|
||||
{
|
||||
int retval;
|
||||
char *buf = NULL;
|
||||
|
||||
if (getenv(name) == NULL || overwrite)
|
||||
{
|
||||
size_t len = strlen(name) + 1 + strlen(value) + 1; /* NAME=VALUE\0 */
|
||||
buf = malloc(len);
|
||||
snprintf(buf, len, "%s=%s", name, value);
|
||||
retval = putenv(buf);
|
||||
}
|
||||
else
|
||||
retval = -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
graceful_exit (int status)
|
||||
{
|
||||
/*FILE *fp;
|
||||
if (status != 1)
|
||||
{
|
||||
fp = fopen ("/crash.log", "a");
|
||||
char buf[100];
|
||||
sprintf (buf, "graceful_exit called with status %d", status);
|
||||
fputs (buf, fp);
|
||||
}
|
||||
This doesn't work. Ever.
|
||||
*/
|
||||
exit (status);
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/* dgl-wall sends a message to all logged in users. If you specified a
|
||||
* configuration file to dgamelaunch, you must do so as well for dgl-wall,
|
||||
* or else the message won't be sent. */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include "dgamelaunch.h"
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
int c, i, len;
|
||||
char* config = NULL, buf[80], *ptr = buf, *from = NULL;
|
||||
struct dg_game ** games = NULL;
|
||||
struct flock fl = { 0 };
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
FILE* spool = NULL;
|
||||
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
while ((c = getopt(argc, argv, "f:F:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
config = strdup(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
from = strdup(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (from == NULL)
|
||||
from = pw->pw_name;
|
||||
|
||||
while (optind < argc)
|
||||
{
|
||||
if (strlen(buf) >= 80)
|
||||
{
|
||||
fprintf(stderr, "Error: Message is too long! (80 chars max)\n");
|
||||
return 1;
|
||||
}
|
||||
else if (strlen(buf) != 0)
|
||||
strlcat (buf, " ", 80);
|
||||
strlcat (buf, argv[optind++], 80);
|
||||
}
|
||||
|
||||
if (strlen(buf) == 0)
|
||||
{
|
||||
fprintf(stderr, "Error: no message?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
create_config();
|
||||
|
||||
if (chroot (myconfig->chroot))
|
||||
{
|
||||
perror("Couldn't change root directory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chdir ("/"))
|
||||
{
|
||||
perror("Couldn't chdir to root directory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
games = populate_games (&len);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
fprintf(stderr, "Error: no one's logged in!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char* fname = NULL;
|
||||
size_t len;
|
||||
|
||||
len = strlen(myconfig->spool) + strlen(games[i]->name) + 2;
|
||||
fname = malloc (len + 1);
|
||||
|
||||
snprintf(fname, len, "%s/%s", myconfig->spool, games[i]->name);
|
||||
|
||||
if ((spool = fopen(fname, "a")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "Warning: couldn't open mailbox for %s.\n", games[i]->name);
|
||||
free (fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (fcntl (fileno(spool), F_SETLK, &fl) == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
fprintf (stderr, "Warning: fcntl errored out trying to lock mailbox for %s\n",
|
||||
games[i]->name);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/* Now that we have the lock, begin the write */
|
||||
|
||||
fprintf(spool, "%s:%s\n", from, buf);
|
||||
fclose(spool);
|
||||
free(fname);
|
||||
}
|
||||
|
||||
puts("Message sent successfully.");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue