BSD 4_3 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 30 Oct 1985 11:14:14 +0000 (03:14 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 30 Oct 1985 11:14:14 +0000 (03:14 -0800)
Work on file usr/contrib/mh/uip/bbl.c

Synthesized-from: CSRG/cd1/4.3

usr/contrib/mh/uip/bbl.c [new file with mode: 0644]

diff --git a/usr/contrib/mh/uip/bbl.c b/usr/contrib/mh/uip/bbl.c
new file mode 100644 (file)
index 0000000..f60e2b1
--- /dev/null
@@ -0,0 +1,586 @@
+/* bbl.c - ease the tasks of a BBleader */
+
+#include "../h/mh.h"
+#include "../zotnet/bboards.h"
+#include <ctype.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#ifndef        BSD42
+#ifndef        SYS5
+#include <ndir.h>
+#else  SYS5
+#include <dir.h>
+#endif SYS5
+#else  BSD42
+#include <sys/dir.h>
+#endif BSD42
+#include <sys/stat.h>
+
+/* \f */
+
+static struct swit switches[] = {
+#define        SHELLSW 0
+    "shell program", 0,
+
+#define        VERBSW  1
+    "verbose", 0,
+#define        NVERBSW 2
+    "noverbose", 0,
+
+#define        HELPSW  3
+    "help", 4,
+
+    NULL, NULL
+};
+
+/* \f */
+
+static int     verbosw = 0;
+
+static int     sub_ok = 0;
+
+static char   *bboards = BBOARDS;
+
+static char   *cwd = NULL;
+
+static char   *current_folder = NULL;
+
+static char   *bbfolder = NULL;
+static char    subfolder[BUFSIZ];
+
+static struct stat bbstat;
+static struct stat substat;
+
+static char   *shell = "/bin/sh";
+
+static struct bboard  *bb = NULL;
+
+
+#ifdef SYS5
+struct passwd  *getpwnam (), *getpwuid ();
+#endif SYS5
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv)
+int     argc;
+char  **argv;
+{
+    char   *cp,
+          **ap,
+          **argp,
+            buffer[80],
+           *arguments[MAXARGS];
+    struct passwd  *pw;
+
+    invo_name = r1bindex (argv[0], '/');
+    if ((cp = m_find (invo_name)) != NULL) {
+       ap = brkstring (cp = getcpy (cp), " ", "\n");
+       ap = copyip (ap, arguments);
+    }
+    else
+       ap = arguments;
+    (void) copyip (argv + 1, ap);
+    argp = arguments;
+
+    if ((shell = getenv ("SHELL")) == NULL)
+       if ((pw = getpwuid (getuid ())) != NULL
+               && pw -> pw_shell
+               && *pw -> pw_shell)
+           shell = getcpy (pw -> pw_shell);
+
+    if ((pw = getpwnam (bboards)) == NULL)
+       adios (NULLCP, "no entry for ~%s", bboards);
+    if (pw -> pw_uid != geteuid ())
+       adios (NULLCP, "not running setuid to %s", bboards);
+
+    current_folder = (cp = m_find (pfolder)) ? getcpy (cp) : defalt;
+
+/* \f */
+
+    while (cp = *argp++) {
+       if (*cp == '-')
+           switch (smatch (++cp, switches)) {
+               case AMBIGSW: 
+                   ambigsw (cp, switches);
+                   done (1);
+               case UNKWNSW: 
+                   adios (NULLCP, "-%s unknown", cp);
+               case HELPSW: 
+                   (void) sprintf (buffer, "%s [+folder] [switches] bboard",
+                           invo_name);
+                   help (buffer, switches);
+                   done (1);
+
+               case SHELLSW: 
+                   if (!(shell = *argp++) || *shell == '-')
+                       adios (NULLCP, "missing argument to %s", argp[-2]);
+                   continue;
+
+               case VERBSW: 
+                   verbosw++;
+                   continue;
+               case NVERBSW: 
+                   verbosw = 0;
+                   continue;
+           }
+       if (*cp == '+')
+           if (bbfolder)
+               adios (NULLCP, "only one folder at a time!");
+           else
+               bbfolder = cp;
+       else
+           if (bb != NULL)
+               adios (NULLCP, "only one BBoard a time!");
+           else
+               if ((bb = getbbnam (cp)) == NULL
+                       && (bb = getbbaka (cp)) == NULL)
+                   adios (NULLCP, "no such BBoard as '%s'", cp);
+    }
+
+/* \f */
+
+    if (!bb)
+       adios (NULLCP, "no BBoard specified");
+    if (!bbfolder)
+       bbfolder = "+bbl";
+    (void) sprintf (subfolder, "%s/arc", bbfolder);
+
+    if (!m_find ("path"))
+       free (path ("./", TFOLDER));
+    cwd = getcpy (pwd ());
+
+    process ();
+
+    m_replace (pfolder, current_folder);
+    m_update ();
+
+    done (0);
+}
+
+/* \f */
+
+process () {
+    int     child_id;
+    char    buffer[BUFSIZ];
+
+    if (!ldrbb (bb) && !ldrchk (bb))
+       return;
+
+    if (stat (bb -> bb_file, &bbstat) == NOTOK)
+       adios (NULLCP, "no such file as %s", bb -> bb_file);
+
+    if (stat (bb -> bb_archive, &substat) != NOTOK
+           && substat.st_size > 0)
+       sub_ok++;
+/*  else */
+    substat.st_mode = bbstat.st_mode;/* archive should always match */
+    substat.st_gid = bbstat.st_gid;/* actual bboard mode & gid */
+
+/* do subfolder first, since you will lose otherwise... */
+    (void) sprintf (buffer, "Remove messages currently in %s? ", subfolder);
+    if (check_folder (subfolder) && getanswer (buffer))
+       rmf (subfolder);
+
+    (void) sprintf (buffer, "Remove messages currently in %s? ", bbfolder);
+    if (check_folder (bbfolder) && getanswer (buffer))
+       rmf (bbfolder);
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           adios ("fork", "unable to");
+
+       case OK: 
+           do_child ();        /* NOTREACHED */
+
+       default: 
+           do_parent (child_id);
+           break;
+    }
+}
+
+/* \f */
+
+int     check_folder (folder)
+char   *folder;
+{
+    char   *maildir;
+    struct stat st;
+    struct msgs *mp;
+
+    maildir = m_maildir (folder + 1);
+
+    if (stat (maildir, &st) == NOTOK)
+       return 0;
+
+    if ((st.st_mode & S_IFMT) != S_IFDIR)
+       adios (NULLCP, "not a directory '%s'", maildir);
+    check_mode (maildir, (st.st_mode | 0555) & 0777);
+
+    if (chdir (maildir) == NOTOK)
+       adios (maildir, "unable to change to");
+    if (!(mp = m_gmsg (folder + 1)))
+       adios (NULLCP, "unable to read %s", folder);
+
+    if (chdir (cwd) == NOTOK)
+       admonish (cwd, "could not change back to");
+    return (mp -> hghmsg != 0);
+}
+
+/* \f */
+
+do_parent (child_id)
+int     child_id;
+{
+    int     zap = 0;
+    char    buffer[BUFSIZ];
+
+    if (pidwait (child_id, NOTOK) == NOTOK)
+       done (1);
+
+    (void) putchar ('\n');
+
+    (void) check_folder (bbfolder);
+    if (getanswer ("Incorporate changes? "))
+       update (&bbstat, bb -> bb_file, bbfolder, bb -> bb_info, bb -> bb_map);
+    (void) sprintf (buffer, "Remove %s? ", bbfolder);
+    if (getanswer (buffer))
+       zap++;
+
+    if (check_folder (subfolder)) {
+       if (getanswer ("Update archives? "))
+           update (&substat, bb -> bb_archive, subfolder, NULLCP, NULLCP);
+    (void) sprintf (buffer, "Remove %s? ", subfolder);
+    if (getanswer (buffer))
+       rmf (subfolder);
+    }
+    else
+       if (sub_ok
+               && getanswer ("Remove archives? ")
+               && getanswer ("Are you sure? "))
+           if (unlink (bb -> bb_archive) == NOTOK)
+               admonish (bb -> bb_archive, "unable to remove %s");
+    if (zap)
+       rmf (bbfolder);
+}
+
+/* \f */
+
+check_mode (dir, mode)
+char   *dir;
+unsigned int    mode;
+{
+    int     child_id;
+    struct stat st;
+    struct direct  *dp;
+    DIR * dd;
+
+    if (verbosw)
+       fprintf (stderr, "chmod %o %s\n", mode, dir);
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           adios ("fork", "unable to");
+
+       case OK: 
+           (void) setgid (getgid ());
+           (void) setuid (getuid ());
+
+           if (chmod (dir, (int) mode) == NOTOK)
+               adios (dir, "unable to change mode of");
+           if (chdir (dir) == NOTOK)
+               adios (dir, "unable to change to");
+           if ((dd = opendir (dir)) == NULL)
+               adios (dir, "unable to read");
+           while (dp = readdir (dd))
+               if (dp -> d_name[0] != '.') {
+                   if (stat (dp -> d_name, &st) == NOTOK) {
+                       admonish (dp -> d_name, "unable to stat");
+                       continue;
+                   }
+                   if (chmod (dp -> d_name, (int) ((st.st_mode | 0444) & 0777))
+                           == NOTOK)
+                       admonish (dp -> d_name, "unable to change mode of");
+               }
+           closedir (dd);
+           done (0);
+
+       default: 
+           if (pidwait (child_id, OK))
+               done (1);
+           break;
+    }
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+update (stp, file, folder, info, map)
+struct stat *stp;
+char   *file,
+       *folder,
+       *info,
+       *map;
+{
+    int     fd;
+    struct stat st;
+
+    if (stat (file, &st) != NOTOK
+           && st.st_mtime != stp -> st_mtime) {
+       printf ("File '%s' has changed...\n", file);
+       if (getanswer ("Append to it instead? "))
+           goto work;
+       else
+           if (!getanswer ("Still update it? "))
+               return;
+    }
+    if ((fd = creat (file, BBMODE)) == NOTOK)
+       adios (file, "unable to re-create");
+    else {
+       (void) close (fd);
+       if (map)
+           (void) unlink (map);
+    }
+#ifdef notdef
+    if (info)
+       check_info (folder, info);
+#endif notdef
+
+work: ;
+    pack (folder, file);
+    if (chmod (file, (int) (stp -> st_mode & 0777)) == NOTOK)
+       admonish (file, "unable to change mode of");
+    if (stat (file, &st) != NOTOK && st.st_gid != stp -> st_gid)
+       chgrp (file, stp -> st_gid);
+}
+
+/* \f */
+
+#ifdef notdef
+check_info (folder, info)
+char   *folder,
+       *info;
+{
+    int     id,
+            state;
+    char   *hdrptr,
+           *maildir,
+           *msgnam,
+            posted[BUFSIZ],
+            name[NAMESZ],
+            buf[BUFSIZ];
+    struct msgs *mp;
+    FILE * fp;
+
+    if (chdir (maildir = m_maildir (folder + 1)) == NOTOK)
+       adios (maildir, "unable to change to");
+
+    if (!(mp = m_gmsg (folder + 1)))
+       adios (NULL, "unable to read %s", folder);
+    if (mp -> hghmsg) {
+       if ((fp = fopen (msgnam = m_name (mp -> hghmsg), "r")) == NULL)
+           adios (NULL, "unable to read message %s in %s",
+                   msgnam, folder);
+       id = 0;
+       posted[0] = NULL;
+       for (state = FLD;;) {
+           switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
+               case FLD: 
+               case FLDEOF: 
+               case FLDPLUS: 
+                   hdrptr = add (buf, NULL);
+                   while (state == FLDPLUS) {
+                       state = m_getfld (state, name, buf, sizeof buf, fp);
+                       hdrptr = add (buf, hdrptr);
+                   }
+                   if (uleq (name, "BBoard-ID")) {
+                       id = atoi (buf);
+                       if (id > 0 && posted[0])
+                           break;
+                   }
+                   if (uleq (name, "BB-Posted")) {
+                       strncpy (posted, buf, sizeof posted - 2);
+                       if (posted[strlen (posted) - 1] == '\n')
+                           posted[strlen (posted) - 1] = NULL;
+                       if (id > 0 && posted[0])
+                           break;
+                   }
+                   continue;
+
+               default: 
+                   admonish (NULL, "unable to find BBoard-info in message %s",
+                           msgnam);
+                   (void) fclose (fp);
+                   goto no_risk;
+           }
+           break;
+       }
+       (void) fclose (fp);
+
+       if (verbosw)
+           fprintf (stderr,
+                   "[ Highest message has %s%d and\n\t\t      %s%s ]\n",
+                   "BBoard-ID: ", id, "BB-Posted: ", posted);
+
+       if ((fp = lkfopen (info, "w")) == NULL)
+           adios (info, "unable to lock and fopen");
+       fprintf (fp, "%d\n%s\n", id, posted);
+       (void) lkfclose (fp, info);
+    }
+
+no_risk: ;
+    if (chdir (cwd) == NOTOK)
+       admonish (cwd, "could not change back to");
+}
+#endif notdef
+
+/* \f */
+
+pack (folder, file)
+char   *folder,
+       *file;
+{
+    int     child_id;
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           admonish ("fork", "unable to");
+           return;
+
+       case OK: 
+           if (verbosw)
+               fprintf (stderr, "pack %s -file %s\n", folder, file);
+
+           execlp (packproc, r1bindex (packproc, '/'),
+                   folder, "-file", file, NULLCP);
+           fprintf (stderr, "unable to exec ");
+           perror (packproc);
+           _exit (-1);
+
+       default: 
+           (void) pidXwait (child_id, packproc);
+           break;
+    }
+}
+
+/* \f */
+
+chgrp (file, gid)
+char   *file;
+short  gid;
+{
+    int     child_id;
+    char    group[BUFSIZ];
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           admonish ("fork", "unable to");
+           return;
+
+       case OK: 
+           (void) setuid (geteuid ());/* make sure chgrp works */
+           (void) sprintf (group, "%d", gid);
+           if (verbosw)
+               fprintf (stderr, "chgrp %s %s\n", group, file);
+
+           execlp ("/bin/chgrp", "chgrp", group, file, NULLCP);
+           fprintf (stderr, "unable to exec ");
+           perror ("/bin/chgrp");
+           _exit (-1);
+
+       default: 
+           (void) pidXwait (child_id, "chgrp");
+           break;
+    }
+}
+
+/* \f */
+
+rmf (folder)
+char   *folder;
+{
+    int     child_id;
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           admonish ("fork", "unable to");
+           return;
+
+       case OK: 
+           (void) setgid (getgid ());
+           (void) setuid (getuid ());
+           if (verbosw)
+               fprintf (stderr, "rmf %s\n", folder);
+
+           execlp (rmfproc, r1bindex (rmfproc, '/'), folder, NULLCP);
+           fprintf (stderr, "unable to exec ");
+           perror (rmfproc);
+           _exit (-1);
+
+       default: 
+           (void) pidXwait (child_id, rmfproc);
+           break;
+    }
+}
+
+/* \f */
+
+do_child () {
+    char    buffer[BUFSIZ];
+
+    (void) setgid (getgid ());         /* become the user, not bboards */
+    (void) setuid (getuid ());
+
+    inc (bb -> bb_file, bbfolder);
+    if (sub_ok)
+       inc (bb -> bb_archive, subfolder);
+/*  else
+       create the folder */
+
+    if (verbosw)
+       (void) putchar ('\n');
+    printf ("[ Working folder is %s, Archive folder is %s ]\n",
+           bbfolder, subfolder);
+    printf ("[ Type CTRL-D to finish ]\n");
+
+    m_replace (pfolder, bbfolder + 1);
+    m_update ();
+
+    (void) sprintf (buffer, "=> %s: %s", invo_name, bb -> bb_name);
+    execlp (shell, buffer, NULLCP);
+    fprintf (stderr, "unable to exec ");
+    perror (shell);
+    _exit (-1);
+}
+
+/* \f */
+
+inc (file, folder)
+char   *file,
+       *folder;
+{
+    int     child_id;
+
+    switch (child_id = fork ()) {
+       case NOTOK: 
+           adios ("fork", "unable to");
+
+       case OK: 
+           if (verbosw)
+               fprintf (stderr, "inc %s -file %s -silent\n", folder, file);
+           execlp (incproc, r1bindex (incproc, '/'),
+                   folder, "-file", file, "-silent", NULLCP);
+           fprintf (stderr, "unable to exec ");
+           perror (incproc);
+           _exit (-1);
+
+       default: 
+           if (pidXwait (child_id, incproc))
+               done (1);
+           break;
+    }
+}