|
|
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: { ! 168: int child_id; ! 169: char buffer[BUFSIZ]; ! 170: ! 171: if (!ldrbb (bb) && !ldrchk (bb)) ! 172: return; ! 173: ! 174: if (stat (bb -> bb_file, &bbstat) == NOTOK) ! 175: adios (NULLCP, "no such file as %s", bb -> bb_file); ! 176: ! 177: if (stat (bb -> bb_archive, &substat) != NOTOK ! 178: && substat.st_size > 0) ! 179: sub_ok++; ! 180: /* else */ ! 181: substat.st_mode = bbstat.st_mode;/* archive should always match */ ! 182: substat.st_gid = bbstat.st_gid;/* actual bboard mode & gid */ ! 183: ! 184: /* do subfolder first, since you will lose otherwise... */ ! 185: (void) sprintf (buffer, "Remove messages currently in %s? ", subfolder); ! 186: if (check_folder (subfolder) && getanswer (buffer)) ! 187: rmf (subfolder); ! 188: ! 189: (void) sprintf (buffer, "Remove messages currently in %s? ", bbfolder); ! 190: if (check_folder (bbfolder) && getanswer (buffer)) ! 191: rmf (bbfolder); ! 192: ! 193: switch (child_id = fork ()) { ! 194: case NOTOK: ! 195: adios ("fork", "unable to"); ! 196: ! 197: case OK: ! 198: do_child (); /* NOTREACHED */ ! 199: ! 200: default: ! 201: do_parent (child_id); ! 202: break; ! 203: } ! 204: } ! 205: ! 206: /* */ ! 207: ! 208: check_folder(folder) ! 209: char *folder; ! 210: { ! 211: char *maildir; ! 212: struct stat st; ! 213: struct msgs *mp; ! 214: ! 215: maildir = m_maildir (folder + 1); ! 216: ! 217: if (stat (maildir, &st) == NOTOK) ! 218: return 0; ! 219: ! 220: if ((st.st_mode & S_IFMT) != S_IFDIR) ! 221: adios (NULLCP, "not a directory '%s'", maildir); ! 222: check_mode (maildir, (st.st_mode | 0555) & 0777); ! 223: ! 224: if (chdir (maildir) == NOTOK) ! 225: adios (maildir, "unable to change to"); ! 226: if (!(mp = m_gmsg (folder + 1))) ! 227: adios (NULLCP, "unable to read %s", folder); ! 228: ! 229: if (chdir (cwd) == NOTOK) ! 230: admonish (cwd, "could not change back to"); ! 231: return (mp -> hghmsg != 0); ! 232: } ! 233: ! 234: /* */ ! 235: ! 236: do_parent(child_id) ! 237: int child_id; ! 238: { ! 239: int zap = 0; ! 240: char buffer[BUFSIZ]; ! 241: ! 242: if (pidwait (child_id, NOTOK) == NOTOK) ! 243: done (1); ! 244: ! 245: (void) putchar ('\n'); ! 246: ! 247: (void) check_folder (bbfolder); ! 248: if (getanswer ("Incorporate changes? ")) ! 249: update (&bbstat, bb -> bb_file, bbfolder, bb -> bb_info, bb -> bb_map); ! 250: (void) sprintf (buffer, "Remove %s? ", bbfolder); ! 251: if (getanswer (buffer)) ! 252: zap++; ! 253: ! 254: if (check_folder (subfolder)) { ! 255: if (getanswer ("Update archives? ")) ! 256: update (&substat, bb -> bb_archive, subfolder, NULLCP, NULLCP); ! 257: (void) sprintf (buffer, "Remove %s? ", subfolder); ! 258: if (getanswer (buffer)) ! 259: rmf (subfolder); ! 260: } ! 261: else ! 262: if (sub_ok ! 263: && getanswer ("Remove archives? ") ! 264: && getanswer ("Are you sure? ")) ! 265: if (unlink (bb -> bb_archive) == NOTOK) ! 266: admonish (bb -> bb_archive, "unable to remove %s"); ! 267: if (zap) ! 268: rmf (bbfolder); ! 269: } ! 270: ! 271: /* */ ! 272: ! 273: check_mode(dir, mode) ! 274: char *dir; ! 275: unsigned int mode; ! 276: { ! 277: int child_id; ! 278: struct stat st; ! 279: struct direct *dp; ! 280: DIR * dd; ! 281: ! 282: if (verbosw) ! 283: fprintf (stderr, "chmod %o %s\n", mode, dir); ! 284: ! 285: switch (child_id = fork ()) { ! 286: case NOTOK: ! 287: adios ("fork", "unable to"); ! 288: ! 289: case OK: ! 290: (void) setgid (getgid ()); ! 291: (void) setuid (getuid ()); ! 292: ! 293: if (chmod (dir, (int) mode) == NOTOK) ! 294: adios (dir, "unable to change mode of"); ! 295: if (chdir (dir) == NOTOK) ! 296: adios (dir, "unable to change to"); ! 297: if ((dd = opendir (dir)) == NULL) ! 298: adios (dir, "unable to read"); ! 299: while (dp = readdir (dd)) ! 300: if (dp -> d_name[0] != '.') { ! 301: if (stat (dp -> d_name, &st) == NOTOK) { ! 302: admonish (dp -> d_name, "unable to stat"); ! 303: continue; ! 304: } ! 305: if (chmod (dp -> d_name, (int) ((st.st_mode | 0444) & 0777)) ! 306: == NOTOK) ! 307: admonish (dp -> d_name, "unable to change mode of"); ! 308: } ! 309: closedir (dd); ! 310: done (0); ! 311: ! 312: default: ! 313: if (pidwait (child_id, OK)) ! 314: done (1); ! 315: break; ! 316: } ! 317: } ! 318: ! 319: /* */ ! 320: ! 321: /* ARGSUSED */ ! 322: ! 323: update(stp, file, folder, info, map) ! 324: struct stat *stp; ! 325: char *file, *folder, *info, *map; ! 326: { ! 327: int fd; ! 328: struct stat st; ! 329: ! 330: if (stat (file, &st) != NOTOK ! 331: && st.st_mtime != stp -> st_mtime) { ! 332: printf ("File '%s' has changed...\n", file); ! 333: if (getanswer ("Append to it instead? ")) ! 334: goto work; ! 335: else ! 336: if (!getanswer ("Still update it? ")) ! 337: return; ! 338: } ! 339: if ((fd = creat (file, BBMODE)) == NOTOK) ! 340: adios (file, "unable to re-create"); ! 341: else { ! 342: (void) close (fd); ! 343: if (map) ! 344: (void) unlink (map); ! 345: } ! 346: #ifdef notdef ! 347: if (info) ! 348: check_info (folder, info); ! 349: #endif notdef ! 350: ! 351: work: ; ! 352: pack (folder, file); ! 353: if (chmod (file, (int) (stp -> st_mode & 0777)) == NOTOK) ! 354: admonish (file, "unable to change mode of"); ! 355: if (stat (file, &st) != NOTOK && st.st_gid != stp -> st_gid) ! 356: chgrp (file, stp -> st_gid); ! 357: } ! 358: ! 359: /* */ ! 360: ! 361: #ifdef notdef ! 362: check_info(folder, info) ! 363: char *folder, *info; ! 364: { ! 365: int id, ! 366: state; ! 367: char *hdrptr, ! 368: *maildir, ! 369: *msgnam, ! 370: posted[BUFSIZ], ! 371: name[NAMESZ], ! 372: buf[BUFSIZ]; ! 373: struct msgs *mp; ! 374: FILE * fp; ! 375: ! 376: if (chdir (maildir = m_maildir (folder + 1)) == NOTOK) ! 377: adios (maildir, "unable to change to"); ! 378: ! 379: if (!(mp = m_gmsg (folder + 1))) ! 380: adios (NULL, "unable to read %s", folder); ! 381: if (mp -> hghmsg) { ! 382: if ((fp = fopen (msgnam = m_name (mp -> hghmsg), "r")) == NULL) ! 383: adios (NULL, "unable to read message %s in %s", ! 384: msgnam, folder); ! 385: id = 0; ! 386: posted[0] = NULL; ! 387: for (state = FLD;;) { ! 388: switch (state = m_getfld (state, name, buf, sizeof buf, fp)) { ! 389: case FLD: ! 390: case FLDEOF: ! 391: case FLDPLUS: ! 392: hdrptr = add (buf, NULL); ! 393: while (state == FLDPLUS) { ! 394: state = m_getfld (state, name, buf, sizeof buf, fp); ! 395: hdrptr = add (buf, hdrptr); ! 396: } ! 397: if (uleq (name, "BBoard-ID")) { ! 398: id = atoi (buf); ! 399: if (id > 0 && posted[0]) ! 400: break; ! 401: } ! 402: if (uleq (name, "BB-Posted")) { ! 403: strncpy (posted, buf, sizeof posted - 2); ! 404: if (posted[strlen (posted) - 1] == '\n') ! 405: posted[strlen (posted) - 1] = NULL; ! 406: if (id > 0 && posted[0]) ! 407: break; ! 408: } ! 409: continue; ! 410: ! 411: default: ! 412: admonish (NULL, "unable to find BBoard-info in message %s", ! 413: msgnam); ! 414: (void) fclose (fp); ! 415: goto no_risk; ! 416: } ! 417: break; ! 418: } ! 419: (void) fclose (fp); ! 420: ! 421: if (verbosw) ! 422: fprintf (stderr, ! 423: "[ Highest message has %s%d and\n\t\t %s%s ]\n", ! 424: "BBoard-ID: ", id, "BB-Posted: ", posted); ! 425: ! 426: if ((fp = lkfopen (info, "w")) == NULL) ! 427: adios (info, "unable to lock and fopen"); ! 428: fprintf (fp, "%d\n%s\n", id, posted); ! 429: (void) lkfclose (fp, info); ! 430: } ! 431: ! 432: no_risk: ; ! 433: if (chdir (cwd) == NOTOK) ! 434: admonish (cwd, "could not change back to"); ! 435: } ! 436: #endif notdef ! 437: ! 438: /* */ ! 439: ! 440: pack(folder, file) ! 441: char *folder, *file; ! 442: { ! 443: int child_id; ! 444: ! 445: switch (child_id = fork ()) { ! 446: case NOTOK: ! 447: admonish ("fork", "unable to"); ! 448: return; ! 449: ! 450: case OK: ! 451: if (verbosw) ! 452: fprintf (stderr, "pack %s -file %s\n", folder, file); ! 453: ! 454: execlp (packproc, r1bindex (packproc, '/'), ! 455: folder, "-file", file, NULLCP); ! 456: fprintf (stderr, "unable to exec "); ! 457: perror (packproc); ! 458: _exit (-1); ! 459: ! 460: default: ! 461: (void) pidXwait (child_id, packproc); ! 462: break; ! 463: } ! 464: } ! 465: ! 466: /* */ ! 467: ! 468: chgrp(file, gid) ! 469: char *file; ! 470: short gid; ! 471: { ! 472: int child_id; ! 473: char group[BUFSIZ]; ! 474: ! 475: switch (child_id = fork ()) { ! 476: case NOTOK: ! 477: admonish ("fork", "unable to"); ! 478: return; ! 479: ! 480: case OK: ! 481: (void) setuid (geteuid ());/* make sure chgrp works */ ! 482: (void) sprintf (group, "%d", gid); ! 483: if (verbosw) ! 484: fprintf (stderr, "chgrp %s %s\n", group, file); ! 485: ! 486: execlp ("/bin/chgrp", "chgrp", group, file, NULLCP); ! 487: fprintf (stderr, "unable to exec "); ! 488: perror ("/bin/chgrp"); ! 489: _exit (-1); ! 490: ! 491: default: ! 492: (void) pidXwait (child_id, "chgrp"); ! 493: break; ! 494: } ! 495: } ! 496: ! 497: /* */ ! 498: ! 499: rmf(folder) ! 500: char *folder; ! 501: { ! 502: int child_id; ! 503: ! 504: switch (child_id = fork ()) { ! 505: case NOTOK: ! 506: admonish ("fork", "unable to"); ! 507: return; ! 508: ! 509: case OK: ! 510: (void) setgid (getgid ()); ! 511: (void) setuid (getuid ()); ! 512: if (verbosw) ! 513: fprintf (stderr, "rmf %s\n", folder); ! 514: ! 515: execlp (rmfproc, r1bindex (rmfproc, '/'), folder, NULLCP); ! 516: fprintf (stderr, "unable to exec "); ! 517: perror (rmfproc); ! 518: _exit (-1); ! 519: ! 520: default: ! 521: (void) pidXwait (child_id, rmfproc); ! 522: break; ! 523: } ! 524: } ! 525: ! 526: /* */ ! 527: ! 528: do_child() ! 529: { ! 530: char buffer[BUFSIZ]; ! 531: ! 532: (void) setgid (getgid ()); /* become the user, not bboards */ ! 533: (void) setuid (getuid ()); ! 534: ! 535: inc (bb -> bb_file, bbfolder); ! 536: if (sub_ok) ! 537: inc (bb -> bb_archive, subfolder); ! 538: /* else ! 539: create the folder */ ! 540: ! 541: if (verbosw) ! 542: (void) putchar ('\n'); ! 543: printf ("[ Working folder is %s, Archive folder is %s ]\n", ! 544: bbfolder, subfolder); ! 545: printf ("[ Type CTRL-D to finish ]\n"); ! 546: ! 547: m_replace (pfolder, bbfolder + 1); ! 548: m_update (); ! 549: ! 550: (void) sprintf (buffer, "=> %s: %s", invo_name, bb -> bb_name); ! 551: execlp (shell, buffer, NULLCP); ! 552: fprintf (stderr, "unable to exec "); ! 553: perror (shell); ! 554: _exit (-1); ! 555: } ! 556: ! 557: /* */ ! 558: ! 559: inc(file, folder) ! 560: char *file, *folder; ! 561: { ! 562: int child_id; ! 563: ! 564: switch (child_id = fork ()) { ! 565: case NOTOK: ! 566: adios ("fork", "unable to"); ! 567: ! 568: case OK: ! 569: if (verbosw) ! 570: fprintf (stderr, "inc %s -file %s -silent\n", folder, file); ! 571: execlp (incproc, r1bindex (incproc, '/'), ! 572: folder, "-file", file, "-silent", NULLCP); ! 573: fprintf (stderr, "unable to exec "); ! 574: perror (incproc); ! 575: _exit (-1); ! 576: ! 577: default: ! 578: if (pidXwait (child_id, incproc)) ! 579: done (1); ! 580: break; ! 581: } ! 582: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.