|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.