9 date 93.02.26.21.58.57; author jromine; state Exp;
14 date 92.12.14.17.10.25; author jromine; state Exp;
19 date 92.11.24.18.34.21; author jromine; state Exp;
24 date 92.11.11.22.04.17; author jromine; state Exp;
29 date 92.11.04.00.39.01; author jromine; state Exp;
34 date 92.05.12.21.55.14; author jromine; state Exp;
39 date 92.02.10.19.57.26; author jromine; state Exp;
44 date 92.02.10.18.12.35; author jromine; state Exp;
49 date 90.04.05.14.56.21; author sources; state Exp;
54 date 90.03.12.14.01.42; author sources; state Exp;
59 date 90.02.08.14.22.47; author sources; state Exp;
64 date 90.02.05.14.23.59; author sources; state Exp;
69 date 90.01.10.10.49.19; author sources; state Exp;
74 date 89.11.17.16.02.21; author sources; state Exp;
79 date 89.09.22.13.50.35; author sources; state Exp;
84 date 89.09.22.13.48.40; author sources; state Exp;
89 date 89.09.20.10.36.27; author sources; state Exp;
94 date 89.06.02.12.56.11; author sources; state Exp;
99 date 89.05.05.19.41.14; author sources; state Exp;
113 @/* bbc.c - ZOTnet BBoard checker */
115 static char ident[] = "@@(#)$Id: bbc.c,v 2.12 1992/12/14 17:10:25 jromine Exp jromine $";
119 #include "../zotnet/bboards.h"
122 #include "../zotnet/mts.h"
127 #define sigmask(s) (1 << ((s) - 1))
132 #include <sys/types.h>
133 #include <sys/stat.h>
135 #include <sys/wait.h>
136 #include <sys/time.h>
137 #include <sys/resource.h>
143 #define RCFILE ".bbrc"
149 static struct swit switches[] = {
173 "mshproc program", 4,
181 "file BBoardsfile", 4,
221 struct bbcount *left;
222 struct bbcount *right;
229 static int changed = 0;
231 static int quitting = 0;
233 static int archivesw = 0;
234 static int checksw = 0;
235 static int protsw = 1;
236 static int quietsw = 0;
237 static int readsw = 0;
238 static int topicsw = 0;
239 static int verbosw = 0;
241 static int didpop = OK;
243 static char *user = BBOARDS;
244 static char *host = NULL;
246 extern char response[];
248 extern char *getusr ();
249 static char **getip ();
252 TYPESIG sigser (), hupser ();
256 static TYPESIG tstpser ();
259 static char *rcfile=NULL;
262 static struct bbcount *bbc = NULL;
263 static struct bboard *bbl = NULL;
265 struct bbcount *add_count (), *seek_count ();
266 struct bboard *getbbaux (), *getbbvis ();
267 static void bbreset();
271 extern int called_bbc;
304 setlocale(LC_ALL, "");
306 invo_name = r1bindex (argv[0], '/');
308 mts_init (invo_name);
309 if (popbbhost && *popbbhost)
311 if (popbbuser && *popbbuser)
312 user = popbbuser, rpop = 0;
314 if ((cp = m_find (invo_name)) != NULL) {
315 ap = brkstring (cp = getcpy (cp), " ", "\n");
316 ap = copyip (ap, arguments);
320 (void) copyip (argv + 1, ap);
323 (void) setbbent (SB_STAY);
327 while (cp = *argp++) {
329 switch (smatch (++cp, switches)) {
331 ambigsw (cp, switches);
337 (void) sprintf (buffer,
338 "%s [bboards ...] [switches] [switches for mshproc]",
340 help (buffer, switches);
345 checksw = readsw = 0;
349 readsw = topicsw = 0;
353 checksw = topicsw = 0;
380 if (!(mshproc = *argp++) || *mshproc == '-')
381 adios (NULLCP, "missing argument to %s", argp[-2]);
385 if (!(rc = *argp++) || *rc == '-')
386 adios (NULLCP, "missing argument to %s", argp[-2]);
393 if (!(cp = *argp++) || *cp == '-')
394 adios (NULLCP, "missing argument to %s", argp[-2]);
395 if (!setbbinfo (user, cp, 1))
396 adios (NULLCP, "setbbinfo(%s, %s, 1) failed -- %s",
397 user, cp, getbberr ());
400 if (!(user = *argp++) || *user == '-')
401 adios (NULLCP, "missing argument to %s", argp[-2]);
405 if (!(host = *argp++) || *host == '-')
406 adios (NULLCP, "missing argument to %s", argp[-2]);
419 adios (NULLCP, "too many bboards, starting with %s", cp);
427 host = NULL, didpop = OK;
429 (void) setuid (getuid ());
432 if (!m_find ("path"))
433 free (path ("./", TFOLDER));
437 for (bbp = 0; cp = bbs[bbp]; bbp++)
458 if (didpop != OK && pop_quit () == NOTOK)
459 adios (NULLCP, "%s", response);
470 register struct bboard *bb;
472 printf ("%16s %s %s\n", "BBoard", "Items",
473 verbosw ? "Interesting Facts" : "Last Update");
474 printf ("%16s %s %s\n", "------", "-----",
475 verbosw ? "-----------------" : "-----------");
477 for (bb = bbl ? bbl : getbbvis ();
479 bb = bbl ? bb -> bb_link : getbbvis ()) {
480 printf ("%16s %5d %s\n",
481 bb -> bb_name, bb -> bb_maxima,
482 bb -> bb_date ? bb -> bb_date : "no deliveries");
486 for (ap = bb -> bb_aka; *ap; ap++)
487 cp = add (*ap, cp ? add (", ", cp) : cp);
492 printv ("Leaders", *bb -> bb_leader);
493 for (ap = bb -> bb_leader + 1; *ap; ap++)
494 printv (NULLCP, *ap);
495 printv ("File", bb -> bb_file);
496 printv ("Archive", bb -> bb_archive);
497 printv ("Info", bb -> bb_info);
498 printv ("Map", bb -> bb_map);
499 printv ("Password", bb -> bb_passwd);
500 if (strcmp (bb -> bb_name, bb -> bb_addr))
501 printv ("Address", bb -> bb_addr);
502 if (strcmp (*bb -> bb_leader, bb -> bb_request))
503 printv ("Request", bb -> bb_request);
505 printv ("Relay", bb -> bb_relay);
506 if (*bb -> bb_dist) {
508 (void) getbbdist (bb, action);
511 if (cp = getbberr ())
512 printv ("Error", cp);
514 printb (bb -> bb_flags & ~BB_SEEN);
528 (void) sprintf (buffer, "%s: ", key);
531 printf ("%*s%-*s", 25, "", 10, buffer);
533 printf ("%s", value);
534 (void) putchar ('\n');
538 int action (local, domain)
539 register char *local,
544 (void) sprintf (buffer, "%s@@%s", local, domain);
545 printv (changed++ ? NULL : "Dist", buffer);
555 printv ("Flags", sprintb (buffer, flags, BBITS));
561 #define grammar(a,b,c) (a == 1 ? b : c)
562 #define plural(d) grammar(d, "", "s")
565 register struct bboard *bb;
567 for (bb = bbl; bb; bb = bb -> bb_link) {
568 diff = bb -> bb_maxima - bb -> bb_count;
571 printf ("%s -- %d item%s unseen\n",
572 bb -> bb_name, diff, plural (diff));
575 if (bb -> bb_maxima == 0)
576 printf ("%s -- empty\n", bb -> bb_name);
578 if (bb -> bb_count == 0)
579 printf ("%s -- %d item%sseen)\n",
580 bb -> bb_name, bb -> bb_maxima,
581 grammar (bb -> bb_maxima, " (un", "s (none "));
584 printf ("%s -- %d item%s (all seen)\n",
585 bb -> bb_name, bb -> bb_maxima,
586 plural (bb -> bb_maxima));
588 printf ("%s -- %d item%s unseen\n",
589 bb -> bb_name, diff, plural (diff));
603 register struct bboard *bb;
605 vec[0] = r1bindex (mshproc, '/');
607 tstat = signal (SIGTSTP, tstpser);
610 for (bb = bbl; bb && !quitting; bb = bb -> bb_link) {
611 diff = bb -> bb_maxima - bb -> bb_count;
612 if (bb -> bb_maxima == 0) {
614 printf ("%s -- empty\n", bb -> bb_name);
620 "Oops! looks like someone reset %s -- assuming all unseen\n",
622 diff = bb -> bb_maxima;
625 if (verbosw || archivesw || diff > 0)
626 bbread (bb, vecp, vec);
629 printf ("%s -- %d item%s (all seen)\n",
630 bb -> bb_name, bb -> bb_maxima,
631 plural (bb -> bb_maxima));
636 (void) signal (SIGTSTP, tstat);
655 bbread (bb, vecp, vec)
656 register struct bboard *bb;
674 if (bb -> bb_flags & BB_REMOTE) {
675 if (pop_xtnd (xtnd1, "%s %s", archivesw ? "archive" : "bboards",
676 bb -> bb_name) == NOTOK) {
677 advise (NULLCP, "%s", response);
680 if (pop_stat (&nmsgs, &nbytes) == NOTOK)
681 adios (NULLCP, "%s", response);
684 printf ("%s -- empty\n", bb -> bb_name);
687 if (pop_fd (buf4, buf5) == NOTOK)
688 adios (NULLCP, "%s", response);
692 if (stat (archivesw ? bb -> bb_archive : bb -> bb_file, &st) != NOTOK
697 if (pipe (pd) == NOTOK)
698 adios ("pipe", "unable to");
699 (void) sprintf (buf3, "%d", getpid ());
702 switch (child_id = fork ()) {
704 adios ("fork", "unable to");
708 (void) close (pd[0]);
709 (void) sprintf (buf1, "%d", bb -> bb_count + 1);
710 (void) sprintf (buf2, "%d", pd[1]);
711 vec[vecp++] = "-idname";
712 vec[vecp++] = bb -> bb_name;
713 vec[vecp++] = "-idstart";
715 vec[vecp++] = "-idstop";
717 vec[vecp++] = "-idquit";
721 if (bb -> bb_flags & BB_REMOTE) {
722 vec[vecp++] = "-popread";
724 vec[vecp++] = "-popwrite";
728 vec[vecp++] = archivesw ? bb -> bb_archive : bb -> bb_file;
730 execvp (mshproc, vec);
731 fprintf (stderr, "unable to exec ");
740 (void) close (pd[1]);
741 pgmread (pd[0], child_id, bb);
744 (void) pidXwait (child_id, mshproc);
750 pgmread (pd, child_id, bb)
753 register struct bboard *bb;
758 TYPESIG (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
760 struct bbcount *selected;
762 estat = signal (SIGEMT, sigser);
763 hstat = signal (SIGHUP, hupser);
764 istat = signal (SIGINT, SIG_IGN);
765 qstat = signal (SIGQUIT, SIG_IGN);
766 tstat = signal (SIGTERM, sigser);
768 while ((n = read (pd, buffer, sizeof buffer)) == NOTOK && errno == EINTR)
771 (void) pidXwait (child_id, mshproc);
773 (void) signal (SIGEMT, estat);
774 (void) signal (SIGHUP, hstat);
775 (void) signal (SIGINT, istat);
776 (void) signal (SIGQUIT, qstat);
777 (void) signal (SIGTERM, tstat);
781 if (sscanf (buffer, "%d %d", &i, &j) != 2 || i <= 0 || j <= 0)
784 if ((selected = seek_count (bbc, bb -> bb_name)) == NULL) {
785 bbc = add_count (bbc, bb -> bb_name, i);
790 if (i > selected -> count) {
791 selected -> count = i;
796 if (bb -> bb_maxima > j && i >= j)/* bbl... */
798 if (i != selected -> count) {
799 selected -> count = i;
812 (void) signal (i, sigser);
823 static int armed = 0;
826 (void) signal (i, hupser);
829 if (!armed++) /* tick tock... */
830 alarm ((unsigned int) 30);
844 if ((cp = rc ? rc : getenv ("MHBBRC")) && *cp) {
845 rcfile = path (cp, TFILE);
847 (void) m_putenv ("MHBBRC", rcfile);
850 rcfile = concat (mypath, "/", RCFILE, NULLCP);
852 if ((bbrc = fopen (rcfile, "r")) == NULL)
854 adios (rcfile, "unable to read");
858 for (state = FLD;;) {
859 switch (state = m_getfld (state, key, value, sizeof value, bbrc)) {
862 make_lower (key, key);
863 bbc = add_count (bbc, key, atoi (value));
869 admonish (NULLCP, "bad format: %s", rcfile);
877 if (ferror (bbrc) && !feof (bbrc))
878 admonish (rcfile, "error reading");
879 (void) fclose (bbrc);
885 TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
891 hstat = signal (SIGHUP, SIG_IGN);
892 istat = signal (SIGINT, SIG_IGN);
893 qstat = signal (SIGQUIT, SIG_IGN);
894 tstat = signal (SIGTERM, SIG_IGN);
896 if ((bbrc = fopen (rcfile, "w")) == NULL)
897 adios (rcfile, "unable to write");
901 adios (rcfile, "error writing");
902 (void) fclose (bbrc);
904 (void) signal (SIGHUP, hstat);
905 (void) signal (SIGINT, istat);
906 (void) signal (SIGQUIT, qstat);
907 (void) signal (SIGTERM, tstat);
915 register struct bbcount *p;
920 fprintf (bbrc, "%s: %d\n", p -> key, p -> count);
921 rcput (bbrc, p -> left);
922 rcput (bbrc, p -> right);
928 static TYPESIG tstpser (sig)
932 #if defined(BSD42) && !defined(WAITINT)
941 waitpid(tstpid, &w, WUNTRACED);
943 while ((pid = wait3 (&w, WUNTRACED, (struct rusage *) 0)) != NOTOK
948 (void) signal (SIGTSTP, SIG_DFL);
950 (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
953 (void) kill (getpid (), sig);
956 (void) sigblock (sigmask (SIGTSTP));
958 (void) signal (SIGTSTP, tstpser);
963 static void bbreset (bb, i)
964 register struct bboard *bb;
967 struct bbcount *selected;
970 if ((selected = seek_count (bbc, bb -> bb_name)) == NULL)
971 bbc = add_count (bbc, bb -> bb_name, i);
973 selected -> count = i;
978 struct bbcount *add_count (p, w, i)
979 register struct bbcount *p;
986 p = (struct bbcount *) malloc (sizeof *p);
988 adios (NULLCP,"insufficient memory");
989 p -> key = getcpy (w);
991 p -> left = p -> right = NULL;
994 if ((cond = strcmp (w, p -> key)) < 0)
995 p -> left = add_count (p -> left, w, i);
998 p -> right = add_count (p -> right, w, i);
1004 struct bbcount *seek_count (p, w)
1005 register struct bbcount *p;
1010 if (p == NULL || (cond = strcmp (w, p -> key)) == 0)
1013 return seek_count (cond < 0 ? p -> left : p -> right, w);
1018 default_bboards () {
1022 register int i = bbp;
1028 if (!archivesw && ((cp = m_find ("bboards")) != NULL)) {
1030 for (ap = brkstring (cp = getcpy (cp), " ", "\n"); *ap; ap++)
1032 for (ap = getip (cp); *ap; ap++)
1040 add_bb (bbs[i++], OK);
1046 advise (NULLCP, "please fix the %s: entry in your %s file",
1047 "bboards", mh_profile);
1051 bbs[bbp++] = "system";
1055 add_bb ("system", NOTOK);
1057 add_bb ("general", NOTOK);
1059 add_bb ("ics.system", NOTOK);
1060 add_bb ("ics.general", NOTOK);
1078 register struct bboard *bb;
1079 static struct bboard *tail = NULL;
1082 if ((bb = getbbaux (s)) == NULL)
1086 adios (NULLCP, "no such bboard as '%s'", s);
1088 if (bb -> bb_flags & BB_SEEN) {
1090 admonish (NULLCP, "duplicate bboard '%s'", s);
1095 bb -> bb_flags |= BB_SEEN;
1098 tail -> bb_link = bb;
1107 static struct bboard *Bhead = NULL;
1108 static struct bboard *Btail = NULL;
1110 static int xtnd2 (s)
1115 register struct bboard *bb;
1117 if (sscanf (s, "%s %d", name, &maxima) != 2)
1118 adios (NULLCP, "XTND2 botch: %s", s);
1120 if ((bb = (struct bboard *) calloc (1, sizeof *bb)) == NULL)
1121 adios (NULLCP, "insufficient memory");
1122 bb -> bb_name = getcpy (name);
1124 if (index(name, '.')) {
1126 bb -> bb_aka = getip (name);
1127 for (cp = *bb -> bb_aka; *cp; cp++)
1132 if ((bb -> bb_aka = (char **) calloc (1, sizeof *bb -> bb_aka)) == NULL)
1133 adios (NULLCP, "insufficient memory");
1134 *bb -> bb_aka = NULL;
1138 bb -> bb_file = bb -> bb_archive = bb -> bb_info = bb -> bb_map = "";
1139 bb -> bb_passwd = "";
1141 if ((bb -> bb_leader = (char **) calloc (1, sizeof *bb -> bb_leader))
1143 adios (NULLCP, "insufficient memory");
1144 *bb -> bb_leader = NULL;
1146 bb -> bb_leader = getip ("usenet");
1148 bb -> bb_addr = bb -> bb_request = bb -> bb_relay = "";
1149 if ((bb -> bb_dist = (char **) calloc (1, sizeof *bb -> bb_dist)) == NULL)
1150 adios (NULLCP, "insufficient memory");
1151 *bb -> bb_dist = NULL;
1152 bb -> bb_flags = BB_REMOTE;
1154 bb -> bb_maxima = maxima;
1156 bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL;
1159 Btail -> bb_chain = bb;
1169 static int xtnd3 (s)
1172 static int bbs_int = 0;
1173 static struct bboard *bb;
1175 switch (bbs_int++) {
1177 for (bb = Bhead; bb; bb = bb -> bb_chain)
1178 if (strcmp (bb -> bb_name, s) == 0)
1181 adios (NULLCP, "XTND3 botch");
1183 free (bb -> bb_name);
1184 bb -> bb_name = getcpy (s);
1188 free ((char *) bb -> bb_aka);
1189 bb -> bb_aka = getip (s);
1192 bb -> bb_file = getcpy (s);
1195 bb -> bb_archive = getcpy (s);
1198 bb -> bb_info = getcpy (s);
1201 bb -> bb_map = getcpy (s);
1204 bb -> bb_passwd = getcpy (s);
1207 if (bb -> bb_leader)
1208 free ((char *) bb -> bb_leader);
1209 bb -> bb_leader = getip (s);
1212 bb -> bb_addr = getcpy (s);
1215 bb -> bb_request = getcpy (s);
1218 bb -> bb_relay = getcpy (s);
1222 free ((char *) bb -> bb_dist);
1223 bb -> bb_dist = getip (s);
1226 bb -> bb_flags = bb -> bb_maxima = 0;
1227 (void) sscanf (s, "%o %d", &bb -> bb_flags, &bb -> bb_maxima);
1228 bb -> bb_flags |= BB_REMOTE;
1231 bb -> bb_date = getcpy (s);
1240 static char **getip (s)
1247 for (p = ap = brkstring (getcpy (s), " ", "\n"); *p; p++)
1250 q = (char **) calloc ((unsigned) (p - ap + 1), sizeof *q);
1252 adios (NULLCP, "insufficient memory");
1254 for (p = ap, ap = q; *p; *q++ = *p++)
1263 static struct bboard *rover = NULL;
1265 struct bboard *getbbpop () {
1269 register struct bboard *bb;
1271 if (didpop != NOTOK && ((bb = getbbent ()) || !host))
1274 if (Bhead == NULL) {
1275 snoop = (cp = getenv ("MHPOPDEBUG")) && *cp;
1282 if (strcmp (user, popbbuser) == 0)
1285 ruserpass (host, &user, &pass);
1286 if (didpop != NOTOK)
1289 if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
1290 adios (NULLCP, "%s", response);
1292 (void) setuid (getuid ());
1293 if (pop_xtnd (xtnd2, "bboards") == NOTOK)
1294 adios (NULLCP, "%s", response);
1295 if (topicsw && verbosw) /* could optimize here */
1296 for (bb = Bhead; bb; bb = bb -> bb_chain)
1297 if (pop_xtnd (xtnd3, "x-bboards %s", bb -> bb_name) == NOTOK)
1298 adios (NULLCP, "%s", response);
1303 rover = rover -> bb_chain;
1307 #define getbbent getbbpop
1312 struct bboard *getbbaux (s)
1316 int nlatch = host ? 1 : 0;
1319 register struct bbcount *selected;
1320 register struct bboard *bb;
1321 static struct bboard *head = NULL,
1324 for (bb = head; bb; bb = bb -> bb_next) {
1325 if (strcmp (bb -> bb_name, s) == 0)
1327 for (ap = bb -> bb_aka; *ap; ap++)
1328 if (strcmp (*ap, s) == 0)
1335 while (bb = getbbent ()) {
1336 if ((selected = seek_count (bbc, bb -> bb_name)) != NULL)
1337 bb -> bb_count = selected -> count;
1340 if (!(bb -> bb_flags & BB_REMOTE))
1342 if ((bb = getbbcpy (bb)) == NULL)
1343 adios (NULLCP, "insufficient memory");
1345 tail -> bb_next = bb;
1350 if (strcmp (bb -> bb_name, s) == 0) {
1352 bb -> bb_flags &= ~BB_SEEN;
1355 for (ap = bb -> bb_aka; *ap; ap++)
1356 if (strcmp (*ap, s) == 0)
1361 if (nlatch && pop_xtnd (xtnd2, "bboards %s", s) != NOTOK) {
1372 struct bboard *getbbvis () {
1373 register struct bboard *bb;
1375 while (bb = getbbent ())
1376 if (!(bb -> bb_flags & BB_INVIS)
1377 && (access (bb -> bb_file, 04) != NOTOK || errno != EACCES))
1392 static char ident[] = "@@(#)$Id: bbc.c,v 2.11 1992/11/24 18:34:21 jromine Exp jromine $";
1395 int sigser (), action ();
1399 static int tstpser ();
1408 static int tstpser (sig)
1419 static char ident[] = "@@(#)$Id: bbc.c,v 2.10 1992/11/11 22:04:17 jromine Exp jromine $";
1431 @use union wait under BSD42 only
1436 static char ident[] = "@@(#)$Id: bbc.c,v 2.9 1992/11/04 00:39:01 jromine Exp jromine $";
1439 char *getusr (), **getip ();
1454 static char ident[] = "@@(#)$Id: bbc.c,v 2.8 1992/05/12 21:55:14 jromine Exp jromine $";
1463 @move misplaced #endif
1468 static char ident[] = "@@(#)$Id: bbc.c,v 2.7 1992/02/10 19:57:26 jromine Exp jromine $";
1475 (void) putenv ("MHBBRC", rcfile);
1486 static char ident[] = "@@(#)$Id: bbc.c,v 2.6 1992/02/10 18:12:35 jromine Exp $";
1496 add "localdomain" tailor option
1501 static char ident[] = "@@(#)$Id: bbc.c,v 2.5 1990/04/05 14:56:21 sources Exp jromine $";
1515 static char ident[] = "@@(#)$Id:$";
1575 @don't always add "general" to list of bbs.
1580 int (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
1583 int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
1589 @changes for SUN40 shared libraries and NNTP under bbc
1609 @*** empty log message ***
1613 static char *mshproc = "/usr/local/nmsh";
1632 @*** empty log message ***
1641 @*** empty log message ***
1647 "user BBoardsuser", 4,