1 /* bbl.c - ease the tasks of a BBleader */
3 static char ident[] = "@(#)$Id: bbl.c,v 2.4 1992/11/04 00:39:25 jromine Exp $";
7 #include "../h/local.h"
8 #include "../zotnet/bboards.h"
18 static struct swit switches[] = {
35 static int verbosw = 0;
37 static int sub_ok = 0;
39 static char *bboards = BBOARDS;
41 static char *cwd = NULL;
43 static char *current_folder = NULL;
45 static char *bbfolder = NULL;
46 static char subfolder[BUFSIZ];
48 static struct stat bbstat;
49 static struct stat substat;
51 static char *shell = "/bin/sh";
53 static struct bboard *bb = NULL;
58 struct passwd *getpwnam (), *getpwuid ();
78 setlocale(LC_ALL, "");
80 invo_name = r1bindex (argv[0], '/');
81 if ((cp = m_find (invo_name)) != NULL) {
82 ap = brkstring (cp = getcpy (cp), " ", "\n");
83 ap = copyip (ap, arguments);
87 (void) copyip (argv + 1, ap);
90 if ((shell = getenv ("SHELL")) == NULL)
91 if ((pw = getpwuid (getuid ())) != NULL
94 shell = getcpy (pw -> pw_shell);
96 if ((pw = getpwnam (bboards)) == NULL)
97 adios (NULLCP, "no entry for ~%s", bboards);
98 if (pw -> pw_uid != geteuid ())
99 adios (NULLCP, "not running setuid to %s", bboards);
101 current_folder = ((cp = m_find (pfolder)) || (cp = m_find (inbox)))
102 ? getcpy (cp) : defalt;
106 while (cp = *argp++) {
108 switch (smatch (++cp, switches)) {
110 ambigsw (cp, switches);
113 adios (NULLCP, "-%s unknown", cp);
115 (void) sprintf (buffer, "%s [+folder] [switches] bboard",
117 help (buffer, switches);
121 if (!(shell = *argp++) || *shell == '-')
122 adios (NULLCP, "missing argument to %s", argp[-2]);
134 adios (NULLCP, "only one folder at a time!");
139 adios (NULLCP, "only one BBoard a time!");
141 if ((bb = getbbnam (cp)) == NULL
142 && (bb = getbbaka (cp)) == NULL)
143 adios (NULLCP, "no such BBoard as '%s'", cp);
149 adios (NULLCP, "no BBoard specified");
152 (void) sprintf (subfolder, "%s/arc", bbfolder);
154 if (!m_find ("path"))
155 free (path ("./", TFOLDER));
156 cwd = getcpy (pwd ());
160 m_replace (pfolder, current_folder);
172 if (!ldrbb (bb) && !ldrchk (bb))
175 if (stat (bb -> bb_file, &bbstat) == NOTOK)
176 adios (NULLCP, "no such file as %s", bb -> bb_file);
178 if (stat (bb -> bb_archive, &substat) != NOTOK
179 && substat.st_size > 0)
182 substat.st_mode = bbstat.st_mode;/* archive should always match */
183 substat.st_gid = bbstat.st_gid;/* actual bboard mode & gid */
185 /* do subfolder first, since you will lose otherwise... */
186 (void) sprintf (buffer, "Remove messages currently in %s? ", subfolder);
187 if (check_folder (subfolder) && getanswer (buffer))
190 (void) sprintf (buffer, "Remove messages currently in %s? ", bbfolder);
191 if (check_folder (bbfolder) && getanswer (buffer))
194 switch (child_id = fork ()) {
196 adios ("fork", "unable to");
199 do_child (); /* NOTREACHED */
202 do_parent (child_id);
209 int check_folder (folder)
216 maildir = m_maildir (folder + 1);
218 if (stat (maildir, &st) == NOTOK)
221 if ((st.st_mode & S_IFMT) != S_IFDIR)
222 adios (NULLCP, "not a directory '%s'", maildir);
223 check_mode (maildir, (st.st_mode | 0555) & 0777);
225 if (chdir (maildir) == NOTOK)
226 adios (maildir, "unable to change to");
227 if (!(mp = m_gmsg (folder + 1)))
228 adios (NULLCP, "unable to read %s", folder);
230 if (chdir (cwd) == NOTOK)
231 admonish (cwd, "could not change back to");
232 return (mp -> hghmsg != 0);
243 if (pidwait (child_id, NOTOK) == NOTOK)
246 (void) putchar ('\n');
248 (void) check_folder (bbfolder);
249 if (getanswer ("Incorporate changes? "))
250 update (&bbstat, bb -> bb_file, bbfolder, bb -> bb_info, bb -> bb_map);
251 (void) sprintf (buffer, "Remove %s? ", bbfolder);
252 if (getanswer (buffer))
255 if (check_folder (subfolder)) {
256 if (getanswer ("Update archives? "))
257 update (&substat, bb -> bb_archive, subfolder, NULLCP, NULLCP);
258 (void) sprintf (buffer, "Remove %s? ", subfolder);
259 if (getanswer (buffer))
264 && getanswer ("Remove archives? ")
265 && getanswer ("Are you sure? "))
266 if (unlink (bb -> bb_archive) == NOTOK)
267 admonish (bb -> bb_archive, "unable to remove %s");
274 check_mode (dir, mode)
288 fprintf (stderr, "chmod %o %s\n", mode, dir);
290 switch (child_id = fork ()) {
292 adios ("fork", "unable to");
295 (void) setgid (getgid ());
296 (void) setuid (getuid ());
298 if (chmod (dir, (int) mode) == NOTOK)
299 adios (dir, "unable to change mode of");
300 if (chdir (dir) == NOTOK)
301 adios (dir, "unable to change to");
302 if ((dd = opendir (dir)) == NULL)
303 adios (dir, "unable to read");
304 while (dp = readdir (dd))
305 if (dp -> d_name[0] != '.') {
306 if (stat (dp -> d_name, &st) == NOTOK) {
307 admonish (dp -> d_name, "unable to stat");
310 if (chmod (dp -> d_name, (int) ((st.st_mode | 0444) & 0777))
312 admonish (dp -> d_name, "unable to change mode of");
318 if (pidwait (child_id, OK))
328 update (stp, file, folder, info, map)
338 if (stat (file, &st) != NOTOK
339 && st.st_mtime != stp -> st_mtime) {
340 printf ("File '%s' has changed...\n", file);
341 if (getanswer ("Append to it instead? "))
344 if (!getanswer ("Still update it? "))
347 if ((fd = creat (file, BBMODE)) == NOTOK)
348 adios (file, "unable to re-create");
356 check_info (folder, info);
361 if (chmod (file, (int) (stp -> st_mode & 0777)) == NOTOK)
362 admonish (file, "unable to change mode of");
363 if (stat (file, &st) != NOTOK && st.st_gid != stp -> st_gid)
364 chgrp (file, stp -> st_gid);
370 check_info (folder, info)
385 if (chdir (maildir = m_maildir (folder + 1)) == NOTOK)
386 adios (maildir, "unable to change to");
388 if (!(mp = m_gmsg (folder + 1)))
389 adios (NULL, "unable to read %s", folder);
391 if ((fp = fopen (msgnam = m_name (mp -> hghmsg), "r")) == NULL)
392 adios (NULL, "unable to read message %s in %s",
396 for (state = FLD;;) {
397 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
401 hdrptr = add (buf, NULL);
402 while (state == FLDPLUS) {
403 state = m_getfld (state, name, buf, sizeof buf, fp);
404 hdrptr = add (buf, hdrptr);
406 if (uleq (name, "BBoard-ID")) {
408 if (id > 0 && posted[0])
411 if (uleq (name, "BB-Posted")) {
412 strncpy (posted, buf, sizeof posted - 2);
413 if (posted[strlen (posted) - 1] == '\n')
414 posted[strlen (posted) - 1] = NULL;
415 if (id > 0 && posted[0])
421 admonish (NULL, "unable to find BBoard-info in message %s",
432 "[ Highest message has %s%d and\n\t\t %s%s ]\n",
433 "BBoard-ID: ", id, "BB-Posted: ", posted);
435 if ((fp = lkfopen (info, "w")) == NULL)
436 adios (info, "unable to lock and fopen");
437 fprintf (fp, "%d\n%s\n", id, posted);
438 (void) lkfclose (fp, info);
442 if (chdir (cwd) == NOTOK)
443 admonish (cwd, "could not change back to");
455 switch (child_id = fork ()) {
457 admonish ("fork", "unable to");
462 fprintf (stderr, "pack %s -file %s\n", folder, file);
464 execlp (packproc, r1bindex (packproc, '/'),
465 folder, "-file", file, NULLCP);
466 fprintf (stderr, "unable to exec ");
471 (void) pidXwait (child_id, packproc);
485 switch (child_id = fork ()) {
487 admonish ("fork", "unable to");
491 (void) setuid (geteuid ());/* make sure chgrp works */
492 (void) sprintf (group, "%d", gid);
494 fprintf (stderr, "chgrp %s %s\n", group, file);
496 execlp ("/bin/chgrp", "chgrp", group, file, NULLCP);
497 fprintf (stderr, "unable to exec ");
498 perror ("/bin/chgrp");
502 (void) pidXwait (child_id, "chgrp");
514 switch (child_id = fork ()) {
516 admonish ("fork", "unable to");
520 (void) setgid (getgid ());
521 (void) setuid (getuid ());
523 fprintf (stderr, "rmf %s\n", folder);
525 execlp (rmfproc, r1bindex (rmfproc, '/'), folder, NULLCP);
526 fprintf (stderr, "unable to exec ");
531 (void) pidXwait (child_id, rmfproc);
541 (void) setgid (getgid ()); /* become the user, not bboards */
542 (void) setuid (getuid ());
544 inc (bb -> bb_file, bbfolder);
546 inc (bb -> bb_archive, subfolder);
551 (void) putchar ('\n');
552 printf ("[ Working folder is %s, Archive folder is %s ]\n",
553 bbfolder, subfolder);
554 printf ("[ Type CTRL-D to finish ]\n");
556 m_replace (pfolder, bbfolder + 1);
559 (void) sprintf (buffer, "=> %s: %s", invo_name, bb -> bb_name);
560 execlp (shell, buffer, NULLCP);
561 fprintf (stderr, "unable to exec ");
574 switch (child_id = fork ()) {
576 adios ("fork", "unable to");
580 fprintf (stderr, "inc %s -file %s -silent\n", folder, file);
581 execlp (incproc, r1bindex (incproc, '/'),
582 folder, "-file", file, "-silent", NULLCP);
583 fprintf (stderr, "unable to exec ");
588 if (pidXwait (child_id, incproc))