]> skyeroc.xyz Git - dgamelaunch/commitdiff
Committing this, currently broken, shouldn't be within 5 minutes
authorJoshua Kwan <joshk@triplehelix.org>
Sun, 22 Feb 2004 05:57:36 +0000 (05:57 +0000)
committerJoshua Kwan <joshk@triplehelix.org>
Sun, 22 Feb 2004 05:57:36 +0000 (05:57 +0000)
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@248 db0b04b0-f4d1-0310-9a6d-de3e77497b0e

.cvsignore
Makefile
dgamelaunch.h
dgl-common.c [new file with mode: 0644]
dgl-wall.c [new file with mode: 0644]

index 9e0d0751b7664dde5e602ea6ac9b0853fa21a9b7..e5d53f5b0ba4300b4d37497ec34a5bcf96b96aad 100644 (file)
@@ -1,4 +1,5 @@
 dgamelaunch
+dgl-wall
 nethackstub
 tags
 cscope.out
index c07ccf179aebf54a543465b3b560e63742dabb6e..64c223b91c822a9a1c18a07a4523d0381ab34ab6 100644 (file)
--- a/Makefile
+++ b/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
+dgl-common.o: dgl-common.c dgamelaunch.h
+ttyrec.o: ttyrec.c dgamelaunch.h ttyrec.h io.h
+dgamelaunch.o: dgamelaunch.c dgamelaunch.h ttyplay.h ttyrec.h y.tab.h
 io.o: io.c ttyrec.h
-last_char_is.o: last_char_is.c
+ttyplay.o: ttyplay.c dgamelaunch.h ttyplay.h ttyrec.h io.h stripgfx.h
 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
-ttyrec.o: ttyrec.c dgamelaunch.h ttyrec.h io.h
-virus.o: virus.c last_char_is.c
+strlcat.o: strlcat.c
 y.tab.o: y.tab.c dgamelaunch.h
-dgamelaunch.o: dgamelaunch.c dgamelaunch.h ttyplay.h ttyrec.h y.tab.h
+lex.yy.o: lex.yy.c y.tab.h dgamelaunch.h
+nethackstub.o: nethackstub.c
index 147a72ec9620de852ed117b24cc93b9d397ed782..8a5583daac95ef250de80415a2326d1577f2ba53 100644 (file)
 # 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);
diff --git a/dgl-common.c b/dgl-common.c
new file mode 100644 (file)
index 0000000..72278c6
--- /dev/null
@@ -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);
+}
diff --git a/dgl-wall.c b/dgl-wall.c
new file mode 100644 (file)
index 0000000..47dea17
--- /dev/null
@@ -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;
+}
+