1: /* bbl.c - ease the tasks of a BBleader */
   2: 
   3: #include "../h/mh.h"
   4: #include "../zotnet/bboards.h"
   5: #include <ctype.h>
   6: #include <pwd.h>
   7: #include <stdio.h>
   8: #include <sys/types.h>
   9: #ifndef BSD42
  10: #ifndef SYS5
  11: #include <ndir.h>
  12: #else   SYS5
  13: #include <dir.h>
  14: #endif	SYS5
  15: #else   BSD42
  16: #include <sys/dir.h>
  17: #endif	BSD42
  18: #include <sys/stat.h>
  19: 
  20: /*  */
  21: 
  22: static struct swit switches[] = {
  23: #define SHELLSW 0
  24:     "shell program", 0,
  25: 
  26: #define VERBSW  1
  27:     "verbose", 0,
  28: #define NVERBSW 2
  29:     "noverbose", 0,
  30: 
  31: #define HELPSW  3
  32:     "help", 4,
  33: 
  34:     NULL, NULL
  35: };
  36: 
  37: /*  */
  38: 
  39: static  int     verbosw = 0;
  40: 
  41: static  int     sub_ok = 0;
  42: 
  43: static  char   *bboards = BBOARDS;
  44: 
  45: static  char   *cwd = NULL;
  46: 
  47: static  char   *current_folder = NULL;
  48: 
  49: static  char   *bbfolder = NULL;
  50: static  char    subfolder[BUFSIZ];
  51: 
  52: static  struct stat bbstat;
  53: static  struct stat substat;
  54: 
  55: static  char   *shell = "/bin/sh";
  56: 
  57: static  struct bboard  *bb = NULL;
  58: 
  59: 
  60: #ifdef  SYS5
  61: struct  passwd  *getpwnam (), *getpwuid ();
  62: #endif	SYS5
  63: 
  64: /*  */
  65: 
  66: /* ARGSUSED */
  67: 
  68: main (argc, argv)
  69: int     argc;
  70: char  **argv;
  71: {
  72:     char   *cp,
  73:           **ap,
  74:           **argp,
  75:             buffer[80],
  76:            *arguments[MAXARGS];
  77:     struct passwd  *pw;
  78: 
  79:     invo_name = r1bindex (argv[0], '/');
  80:     if ((cp = m_find (invo_name)) != NULL) {
  81:     ap = brkstring (cp = getcpy (cp), " ", "\n");
  82:     ap = copyip (ap, arguments);
  83:     }
  84:     else
  85:     ap = arguments;
  86:     (void) copyip (argv + 1, ap);
  87:     argp = arguments;
  88: 
  89:     if ((shell = getenv ("SHELL")) == NULL)
  90:     if ((pw = getpwuid (getuid ())) != NULL
  91:         && pw -> pw_shell
  92:         && *pw -> pw_shell)
  93:         shell = getcpy (pw -> pw_shell);
  94: 
  95:     if ((pw = getpwnam (bboards)) == NULL)
  96:     adios (NULLCP, "no entry for ~%s", bboards);
  97:     if (pw -> pw_uid != geteuid ())
  98:     adios (NULLCP, "not running setuid to %s", bboards);
  99: 
 100:     current_folder = (cp = m_find (pfolder)) ? getcpy (cp) : defalt;
 101: 
 102: /*  */
 103: 
 104:     while (cp = *argp++) {
 105:     if (*cp == '-')
 106:         switch (smatch (++cp, switches)) {
 107:         case AMBIGSW:
 108:             ambigsw (cp, switches);
 109:             done (1);
 110:         case UNKWNSW:
 111:             adios (NULLCP, "-%s unknown", cp);
 112:         case HELPSW:
 113:             (void) sprintf (buffer, "%s [+folder] [switches] bboard",
 114:                 invo_name);
 115:             help (buffer, switches);
 116:             done (1);
 117: 
 118:         case SHELLSW:
 119:             if (!(shell = *argp++) || *shell == '-')
 120:             adios (NULLCP, "missing argument to %s", argp[-2]);
 121:             continue;
 122: 
 123:         case VERBSW:
 124:             verbosw++;
 125:             continue;
 126:         case NVERBSW:
 127:             verbosw = 0;
 128:             continue;
 129:         }
 130:     if (*cp == '+')
 131:         if (bbfolder)
 132:         adios (NULLCP, "only one folder at a time!");
 133:         else
 134:         bbfolder = cp;
 135:     else
 136:         if (bb != NULL)
 137:         adios (NULLCP, "only one BBoard a time!");
 138:         else
 139:         if ((bb = getbbnam (cp)) == NULL
 140:             && (bb = getbbaka (cp)) == NULL)
 141:             adios (NULLCP, "no such BBoard as '%s'", cp);
 142:     }
 143: 
 144: /*  */
 145: 
 146:     if (!bb)
 147:     adios (NULLCP, "no BBoard specified");
 148:     if (!bbfolder)
 149:     bbfolder = "+bbl";
 150:     (void) sprintf (subfolder, "%s/arc", bbfolder);
 151: 
 152:     if (!m_find ("path"))
 153:     free (path ("./", TFOLDER));
 154:     cwd = getcpy (pwd ());
 155: 
 156:     process ();
 157: 
 158:     m_replace (pfolder, current_folder);
 159:     m_update ();
 160: 
 161:     done (0);
 162: }
 163: 
 164: /*  */
 165: 
 166: process () {
 167:     int     child_id;
 168:     char    buffer[BUFSIZ];
 169: 
 170:     if (!ldrbb (bb) && !ldrchk (bb))
 171:     return;
 172: 
 173:     if (stat (bb -> bb_file, &bbstat) == NOTOK)
 174:     adios (NULLCP, "no such file as %s", bb -> bb_file);
 175: 
 176:     if (stat (bb -> bb_archive, &substat) != NOTOK
 177:         && substat.st_size > 0)
 178:     sub_ok++;
 179: /*  else */
 180:     substat.st_mode = bbstat.st_mode;/* archive should always match */
 181:     substat.st_gid = bbstat.st_gid;/* actual bboard mode & gid */
 182: 
 183: /* do subfolder first, since you will lose otherwise... */
 184:     (void) sprintf (buffer, "Remove messages currently in %s? ", subfolder);
 185:     if (check_folder (subfolder) && getanswer (buffer))
 186:     rmf (subfolder);
 187: 
 188:     (void) sprintf (buffer, "Remove messages currently in %s? ", bbfolder);
 189:     if (check_folder (bbfolder) && getanswer (buffer))
 190:     rmf (bbfolder);
 191: 
 192:     switch (child_id = fork ()) {
 193:     case NOTOK:
 194:         adios ("fork", "unable to");
 195: 
 196:     case OK:
 197:         do_child ();    /* NOTREACHED */
 198: 
 199:     default:
 200:         do_parent (child_id);
 201:         break;
 202:     }
 203: }
 204: 
 205: /*  */
 206: 
 207: int     check_folder (folder)
 208: char   *folder;
 209: {
 210:     char   *maildir;
 211:     struct stat st;
 212:     struct msgs *mp;
 213: 
 214:     maildir = m_maildir (folder + 1);
 215: 
 216:     if (stat (maildir, &st) == NOTOK)
 217:     return 0;
 218: 
 219:     if ((st.st_mode & S_IFMT) != S_IFDIR)
 220:     adios (NULLCP, "not a directory '%s'", maildir);
 221:     check_mode (maildir, (st.st_mode | 0555) & 0777);
 222: 
 223:     if (chdir (maildir) == NOTOK)
 224:     adios (maildir, "unable to change to");
 225:     if (!(mp = m_gmsg (folder + 1)))
 226:     adios (NULLCP, "unable to read %s", folder);
 227: 
 228:     if (chdir (cwd) == NOTOK)
 229:     admonish (cwd, "could not change back to");
 230:     return (mp -> hghmsg != 0);
 231: }
 232: 
 233: /*  */
 234: 
 235: do_parent (child_id)
 236: int     child_id;
 237: {
 238:     int     zap = 0;
 239:     char    buffer[BUFSIZ];
 240: 
 241:     if (pidwait (child_id, NOTOK) == NOTOK)
 242:     done (1);
 243: 
 244:     (void) putchar ('\n');
 245: 
 246:     (void) check_folder (bbfolder);
 247:     if (getanswer ("Incorporate changes? "))
 248:     update (&bbstat, bb -> bb_file, bbfolder, bb -> bb_info, bb -> bb_map);
 249:     (void) sprintf (buffer, "Remove %s? ", bbfolder);
 250:     if (getanswer (buffer))
 251:     zap++;
 252: 
 253:     if (check_folder (subfolder)) {
 254:     if (getanswer ("Update archives? "))
 255:         update (&substat, bb -> bb_archive, subfolder, NULLCP, NULLCP);
 256:     (void) sprintf (buffer, "Remove %s? ", subfolder);
 257:     if (getanswer (buffer))
 258:     rmf (subfolder);
 259:     }
 260:     else
 261:     if (sub_ok
 262:         && getanswer ("Remove archives? ")
 263:         && getanswer ("Are you sure? "))
 264:         if (unlink (bb -> bb_archive) == NOTOK)
 265:         admonish (bb -> bb_archive, "unable to remove %s");
 266:     if (zap)
 267:     rmf (bbfolder);
 268: }
 269: 
 270: /*  */
 271: 
 272: check_mode (dir, mode)
 273: char   *dir;
 274: unsigned int    mode;
 275: {
 276:     int     child_id;
 277:     struct stat st;
 278:     struct direct  *dp;
 279:     DIR * dd;
 280: 
 281:     if (verbosw)
 282:     fprintf (stderr, "chmod %o %s\n", mode, dir);
 283: 
 284:     switch (child_id = fork ()) {
 285:     case NOTOK:
 286:         adios ("fork", "unable to");
 287: 
 288:     case OK:
 289:         (void) setgid (getgid ());
 290:         (void) setuid (getuid ());
 291: 
 292:         if (chmod (dir, (int) mode) == NOTOK)
 293:         adios (dir, "unable to change mode of");
 294:         if (chdir (dir) == NOTOK)
 295:         adios (dir, "unable to change to");
 296:         if ((dd = opendir (dir)) == NULL)
 297:         adios (dir, "unable to read");
 298:         while (dp = readdir (dd))
 299:         if (dp -> d_name[0] != '.') {
 300:             if (stat (dp -> d_name, &st) == NOTOK) {
 301:             admonish (dp -> d_name, "unable to stat");
 302:             continue;
 303:             }
 304:             if (chmod (dp -> d_name, (int) ((st.st_mode | 0444) & 0777))
 305:                 == NOTOK)
 306:             admonish (dp -> d_name, "unable to change mode of");
 307:         }
 308:         closedir (dd);
 309:         done (0);
 310: 
 311:     default:
 312:         if (pidwait (child_id, OK))
 313:         done (1);
 314:         break;
 315:     }
 316: }
 317: 
 318: /*  */
 319: 
 320: /* ARGSUSED */
 321: 
 322: update (stp, file, folder, info, map)
 323: struct stat *stp;
 324: char   *file,
 325:        *folder,
 326:        *info,
 327:        *map;
 328: {
 329:     int     fd;
 330:     struct stat st;
 331: 
 332:     if (stat (file, &st) != NOTOK
 333:         && st.st_mtime != stp -> st_mtime) {
 334:     printf ("File '%s' has changed...\n", file);
 335:     if (getanswer ("Append to it instead? "))
 336:         goto work;
 337:     else
 338:         if (!getanswer ("Still update it? "))
 339:         return;
 340:     }
 341:     if ((fd = creat (file, BBMODE)) == NOTOK)
 342:     adios (file, "unable to re-create");
 343:     else {
 344:     (void) close (fd);
 345:     if (map)
 346:         (void) unlink (map);
 347:     }
 348: #ifdef  notdef
 349:     if (info)
 350:     check_info (folder, info);
 351: #endif	notdef
 352: 
 353: work: ;
 354:     pack (folder, file);
 355:     if (chmod (file, (int) (stp -> st_mode & 0777)) == NOTOK)
 356:     admonish (file, "unable to change mode of");
 357:     if (stat (file, &st) != NOTOK && st.st_gid != stp -> st_gid)
 358:     chgrp (file, stp -> st_gid);
 359: }
 360: 
 361: /*  */
 362: 
 363: #ifdef  notdef
 364: check_info (folder, info)
 365: char   *folder,
 366:        *info;
 367: {
 368:     int     id,
 369:             state;
 370:     char   *hdrptr,
 371:            *maildir,
 372:            *msgnam,
 373:             posted[BUFSIZ],
 374:             name[NAMESZ],
 375:             buf[BUFSIZ];
 376:     struct msgs *mp;
 377:     FILE * fp;
 378: 
 379:     if (chdir (maildir = m_maildir (folder + 1)) == NOTOK)
 380:     adios (maildir, "unable to change to");
 381: 
 382:     if (!(mp = m_gmsg (folder + 1)))
 383:     adios (NULL, "unable to read %s", folder);
 384:     if (mp -> hghmsg) {
 385:     if ((fp = fopen (msgnam = m_name (mp -> hghmsg), "r")) == NULL)
 386:         adios (NULL, "unable to read message %s in %s",
 387:             msgnam, folder);
 388:     id = 0;
 389:     posted[0] = NULL;
 390:     for (state = FLD;;) {
 391:         switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
 392:         case FLD:
 393:         case FLDEOF:
 394:         case FLDPLUS:
 395:             hdrptr = add (buf, NULL);
 396:             while (state == FLDPLUS) {
 397:             state = m_getfld (state, name, buf, sizeof buf, fp);
 398:             hdrptr = add (buf, hdrptr);
 399:             }
 400:             if (uleq (name, "BBoard-ID")) {
 401:             id = atoi (buf);
 402:             if (id > 0 && posted[0])
 403:                 break;
 404:             }
 405:             if (uleq (name, "BB-Posted")) {
 406:             strncpy (posted, buf, sizeof posted - 2);
 407:             if (posted[strlen (posted) - 1] == '\n')
 408:                 posted[strlen (posted) - 1] = NULL;
 409:             if (id > 0 && posted[0])
 410:                 break;
 411:             }
 412:             continue;
 413: 
 414:         default:
 415:             admonish (NULL, "unable to find BBoard-info in message %s",
 416:                 msgnam);
 417:             (void) fclose (fp);
 418:             goto no_risk;
 419:         }
 420:         break;
 421:     }
 422:     (void) fclose (fp);
 423: 
 424:     if (verbosw)
 425:         fprintf (stderr,
 426:             "[ Highest message has %s%d and\n\t\t      %s%s ]\n",
 427:             "BBoard-ID: ", id, "BB-Posted: ", posted);
 428: 
 429:     if ((fp = lkfopen (info, "w")) == NULL)
 430:         adios (info, "unable to lock and fopen");
 431:     fprintf (fp, "%d\n%s\n", id, posted);
 432:     (void) lkfclose (fp, info);
 433:     }
 434: 
 435: no_risk: ;
 436:     if (chdir (cwd) == NOTOK)
 437:     admonish (cwd, "could not change back to");
 438: }
 439: #endif	notdef
 440: 
 441: /*  */
 442: 
 443: pack (folder, file)
 444: char   *folder,
 445:        *file;
 446: {
 447:     int     child_id;
 448: 
 449:     switch (child_id = fork ()) {
 450:     case NOTOK:
 451:         admonish ("fork", "unable to");
 452:         return;
 453: 
 454:     case OK:
 455:         if (verbosw)
 456:         fprintf (stderr, "pack %s -file %s\n", folder, file);
 457: 
 458:         execlp (packproc, r1bindex (packproc, '/'),
 459:             folder, "-file", file, NULLCP);
 460:         fprintf (stderr, "unable to exec ");
 461:         perror (packproc);
 462:         _exit (-1);
 463: 
 464:     default:
 465:         (void) pidXwait (child_id, packproc);
 466:         break;
 467:     }
 468: }
 469: 
 470: /*  */
 471: 
 472: chgrp (file, gid)
 473: char   *file;
 474: short   gid;
 475: {
 476:     int     child_id;
 477:     char    group[BUFSIZ];
 478: 
 479:     switch (child_id = fork ()) {
 480:     case NOTOK:
 481:         admonish ("fork", "unable to");
 482:         return;
 483: 
 484:     case OK:
 485:         (void) setuid (geteuid ());/* make sure chgrp works */
 486:         (void) sprintf (group, "%d", gid);
 487:         if (verbosw)
 488:         fprintf (stderr, "chgrp %s %s\n", group, file);
 489: 
 490:         execlp ("/bin/chgrp", "chgrp", group, file, NULLCP);
 491:         fprintf (stderr, "unable to exec ");
 492:         perror ("/bin/chgrp");
 493:         _exit (-1);
 494: 
 495:     default:
 496:         (void) pidXwait (child_id, "chgrp");
 497:         break;
 498:     }
 499: }
 500: 
 501: /*  */
 502: 
 503: rmf (folder)
 504: char   *folder;
 505: {
 506:     int     child_id;
 507: 
 508:     switch (child_id = fork ()) {
 509:     case NOTOK:
 510:         admonish ("fork", "unable to");
 511:         return;
 512: 
 513:     case OK:
 514:         (void) setgid (getgid ());
 515:         (void) setuid (getuid ());
 516:         if (verbosw)
 517:         fprintf (stderr, "rmf %s\n", folder);
 518: 
 519:         execlp (rmfproc, r1bindex (rmfproc, '/'), folder, NULLCP);
 520:         fprintf (stderr, "unable to exec ");
 521:         perror (rmfproc);
 522:         _exit (-1);
 523: 
 524:     default:
 525:         (void) pidXwait (child_id, rmfproc);
 526:         break;
 527:     }
 528: }
 529: 
 530: /*  */
 531: 
 532: do_child () {
 533:     char    buffer[BUFSIZ];
 534: 
 535:     (void) setgid (getgid ());      /* become the user, not bboards */
 536:     (void) setuid (getuid ());
 537: 
 538:     inc (bb -> bb_file, bbfolder);
 539:     if (sub_ok)
 540:     inc (bb -> bb_archive, subfolder);
 541: /*  else
 542: 	create the folder */
 543: 
 544:     if (verbosw)
 545:     (void) putchar ('\n');
 546:     printf ("[ Working folder is %s, Archive folder is %s ]\n",
 547:         bbfolder, subfolder);
 548:     printf ("[ Type CTRL-D to finish ]\n");
 549: 
 550:     m_replace (pfolder, bbfolder + 1);
 551:     m_update ();
 552: 
 553:     (void) sprintf (buffer, "=> %s: %s", invo_name, bb -> bb_name);
 554:     execlp (shell, buffer, NULLCP);
 555:     fprintf (stderr, "unable to exec ");
 556:     perror (shell);
 557:     _exit (-1);
 558: }
 559: 
 560: /*  */
 561: 
 562: inc (file, folder)
 563: char   *file,
 564:        *folder;
 565: {
 566:     int     child_id;
 567: 
 568:     switch (child_id = fork ()) {
 569:     case NOTOK:
 570:         adios ("fork", "unable to");
 571: 
 572:     case OK:
 573:         if (verbosw)
 574:         fprintf (stderr, "inc %s -file %s -silent\n", folder, file);
 575:         execlp (incproc, r1bindex (incproc, '/'),
 576:             folder, "-file", file, "-silent", NULLCP);
 577:         fprintf (stderr, "unable to exec ");
 578:         perror (incproc);
 579:         _exit (-1);
 580: 
 581:     default:
 582:         if (pidXwait (child_id, incproc))
 583:         done (1);
 584:         break;
 585:     }
 586: }

Defined functions

check_folder defined in line 207; used 4 times
check_info defined in line 364; used 1 times
check_mode defined in line 272; used 1 times
chgrp defined in line 472; used 1 times
do_child defined in line 532; used 1 times
do_parent defined in line 235; used 1 times
inc defined in line 562; used 2 times
main defined in line 68; never used
pack defined in line 443; used 1 times
process defined in line 166; used 1 times
rmf defined in line 503; used 4 times
update defined in line 322; used 2 times

Defined variables

bb defined in line 57; used 18 times
bbfolder defined in line 49; used 15 times
bboards defined in line 43; used 3 times
bbstat defined in line 52; used 4 times
current_folder defined in line 47; used 2 times
cwd defined in line 45; used 5 times
shell defined in line 55; used 6 times
sub_ok defined in line 41; used 3 times
subfolder defined in line 50; used 10 times
substat defined in line 53; used 5 times
switches defined in line 22; used 3 times
verbosw defined in line 39; used 9 times

Defined macros

HELPSW defined in line 31; never used
NVERBSW defined in line 28; never used
SHELLSW defined in line 23; never used
VERBSW defined in line 26; never used
Last modified: 1985-10-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1827
Valid CSS Valid XHTML 1.0 Strict