|
|
1.1 root 1: /* bbc.c - ZOTnet BBoard checker */
2:
3: #include "../h/mh.h"
4: #include "../zotnet/bboards.h"
5: #include <stdio.h>
6: #ifdef BPOP
7: #include "../zotnet/mts.h"
8: #endif BPOP
9: #include <errno.h>
10: #include <signal.h>
11: #ifndef sigmask
12: #define sigmask(s) (1 << ((s) - 1))
13: #endif not sigmask
14: #include <sys/types.h>
15: #include <sys/stat.h>
16: #ifdef SIGTSTP
17: #include <sys/wait.h>
18: #include <sys/time.h>
19: #include <sys/resource.h>
20: #endif SIGTSTP
21:
22:
23: #define RCFILE ".bbrc"
24:
25: #define NBB 100
26:
27: /* */
28:
29: static struct swit switches[] = {
30: #define TOPICSW 0
31: "topics", 6,
32: #define CHECKSW 1
33: "check", 5,
34: #define READSW 2
35: "read", 4,
36:
37: #define QUIETSW 3
38: "quiet", 4,
39: #define VERBOSW 4
40: "verbose", 4,
41:
42: #define ARCHSW 5
43: "archive", 4,
44: #define NOARCH 6
45: "noarchive", 3,
46:
47: #define PROTSW 7
48: "protocol", 4,
49: #define NPROTSW 8
50: "noprotocol", 3,
51:
52: #define PROGSW 9
53: "mshproc program", 4,
54:
55: #define RCSW 10
56: "rcfile rcfile", 4,
57: #define NRCSW 11
58: "norcfile", 3,
59:
60: #define FILESW 12
61: "file BBoardsfile", 4,
62: #define USERSW 13
63: "user BBoardsuser", 4,
64:
65: #define HOSTSW 14
66: "host host",
67: #ifndef BPOP
68: -4,
69: #else BPOP
70: 4,
71: #endif BPOP
72: #define RPOPSW 15
73: "rpop",
74: #ifndef RPOP
75: -4,
76: #else RPOP
77: 4,
78: #endif RPOP
79: #define NRPOPSW 16
80: "norpop",
81: #ifndef RPOP
82: -6,
83: #else RPOP
84: 6,
85: #endif RPOP
86:
87: #define HELPSW 17
88: "help", 4,
89:
90: NULL, NULL
91: };
92:
93: struct bbcount {
94: char *key;
95: int count;
96: struct bbcount *left;
97: struct bbcount *right;
98: };
99:
100: /* */
101:
102: extern int errno;
103:
104: static int changed = 0;
105: static int quitting = 0;
106:
107: static int archivesw = 0;
108: static int checksw = 0;
109: static int protsw = 1;
110: static int quietsw = 0;
111: static int readsw = 0;
112: static int topicsw = 0;
113: static int verbosw = 0;
114:
115: static int didpop = OK;
116: static int rpop = 1;
117: static char *user = BBOARDS;
118: static char *host = NULL;
119: #ifdef BPOP
120: extern char response[];
121:
122: char *getusr (), **getip ();
123: #endif BPOP
124:
125: int sigser (), action ();
126: #ifdef SIGTSTP
127: int tstpid;
128: int tstpser ();
129: #endif SIGTSTP
130:
131: static char *rcfile;
132:
133:
134: static struct bbcount *bbc = NULL;
135: static struct bboard *bbl = NULL;
136:
137: struct bbcount *add_count (), *seek_count ();
138: struct bboard *getbbaux (), *getbbvis ();
139:
140: /* */
141:
142: /* ARGSUSED */
143:
144: main (argc, argv)
145: int argc;
146: char **argv;
147: {
148: int bbp = 0,
149: vecp = 1;
150: char *cp,
151: *rc,
152: **ap,
153: **argp,
154: buffer[80],
155: *arguments[MAXARGS],
156: *bbs[NBB + 1],
157: *vec[MAXARGS];
158:
159: invo_name = r1bindex (argv[0], '/');
160: #ifdef BPOP
161: mts_init (invo_name);
162: if (popbbhost && *popbbhost)
163: host = popbbhost;
164: if (popbbuser && *popbbuser)
165: user = popbbuser, rpop = 0;
166: #endif BPOP
167: if ((cp = m_find (invo_name)) != NULL) {
168: ap = brkstring (cp = getcpy (cp), " ", "\n");
169: ap = copyip (ap, arguments);
170: }
171: else
172: ap = arguments;
173: (void) copyip (argv + 1, ap);
174: argp = arguments;
175:
176: (void) setbbent (SB_STAY);
177:
178: /* */
179:
180: while (cp = *argp++) {
181: if (*cp == '-')
182: switch (smatch (++cp, switches)) {
183: case AMBIGSW:
184: ambigsw (cp, switches);
185: done (1);
186: case UNKWNSW:
187: vec[vecp++] = --cp;
188: continue;
189: case HELPSW:
190: (void) sprintf (buffer,
191: "%s [bboards ...] [switches] [switches for mshproc]",
192: invo_name);
193: help (buffer, switches);
194: done (1);
195:
196: case TOPICSW:
197: topicsw++;
198: checksw = readsw = 0;
199: continue;
200: case CHECKSW:
201: checksw++;
202: readsw = topicsw = 0;
203: continue;
204: case READSW:
205: readsw++;
206: checksw = topicsw = 0;
207: continue;
208:
209: case ARCHSW:
210: archivesw++;
211: continue;
212: case NOARCH:
213: archivesw = 0;
214: continue;
215:
216: case PROTSW:
217: protsw++;
218: continue;
219: case NPROTSW:
220: protsw = 0;
221: continue;
222:
223: case QUIETSW:
224: quietsw++;
225: verbosw = 0;
226: continue;
227: case VERBOSW:
228: verbosw++;
229: quietsw = 0;
230: continue;
231:
232: case PROGSW:
233: if (!(mshproc = *argp++) || *mshproc == '-')
234: adios (NULLCP, "missing argument to %s", argp[-2]);
235: continue;
236:
237: case RCSW:
238: if (!(rc = *argp++) || *rc == '-')
239: adios (NULLCP, "missing argument to %s", argp[-2]);
240: continue;
241: case NRCSW:
242: rc = NULL;
243: continue;
244:
245: case FILESW:
246: if (!(cp = *argp++) || *cp == '-')
247: adios (NULLCP, "missing argument to %s", argp[-2]);
248: if (!setbbinfo (user, cp, 1))
249: adios (NULLCP, "setbbinfo(%s, %s, 1) failed -- %s",
250: user, cp, getbberr ());
251: continue;
252: case USERSW:
253: if (!(user = *argp++) || *user == '-')
254: adios (NULLCP, "missing argument to %s", argp[-2]);
255: continue;
256:
257: case HOSTSW:
258: if (!(host = *argp++) || *host == '-')
259: adios (NULLCP, "missing argument to %s", argp[-2]);
260: didpop = NOTOK;
261: continue;
262: case RPOPSW:
263: rpop++;
264: continue;
265: case NRPOPSW:
266: rpop = 0;
267: continue;
268: }
269: if (bbp < NBB)
270: bbs[bbp++] = cp;
271: else
272: adios (NULLCP, "too many bboards, starting with %s", cp);
273: }
274: bbs[bbp] = NULL;
275:
276: /* */
277:
278: #ifdef BPOP
279: if (!*host)
280: host = NULL, didpop = OK;
281: if (!host || !rpop)
282: (void) setuid (getuid ());
283: #endif BPOP
284:
285: if (!m_find ("path"))
286: free (path ("./", TFOLDER));
287:
288: rcinit (rc);
289:
290: for (bbp = 0; cp = bbs[bbp]; bbp++)
291: add_bb (cp, NOTOK);
292:
293: if (topicsw)
294: topics ();
295: else {
296: default_bboards ();
297: if (checksw)
298: check ();
299: else
300: process (vecp, vec);
301: }
302:
303: #ifdef BPOP
304: if (didpop != OK && pop_quit () == NOTOK)
305: adios (NULLCP, "%s", response);
306: #endif BPOP
307:
308: done (0);
309: }
310:
311: /* */
312:
313: topics () {
314: register char *cp,
315: **ap;
316: register struct bboard *bb;
317:
318: printf ("%16s %s %s\n", "BBoard", "Items",
319: verbosw ? "Interesting Facts" : "Last Update");
320: printf ("%16s %s %s\n", "------", "-----",
321: verbosw ? "-----------------" : "-----------");
322:
323: for (bb = bbl ? bbl : getbbvis ();
324: bb;
325: bb = bbl ? bb -> bb_link : getbbvis ()) {
326: printf ("%16s %5d %s\n",
327: bb -> bb_name, bb -> bb_maxima, bb -> bb_date);
328: if (verbosw) {
329: if (*bb -> bb_aka) {
330: cp = NULL;
331: for (ap = bb -> bb_aka; *ap; ap++)
332: cp = add (*ap, cp ? add (", ", cp) : cp);
333: printv ("AKA", cp);
334: free (cp);
335: }
336:
337: printv ("Leaders", *bb -> bb_leader);
338: for (ap = bb -> bb_leader + 1; *ap; ap++)
339: printv (NULLCP, *ap);
340: printv ("File", bb -> bb_file);
341: printv ("Archive", bb -> bb_archive);
342: printv ("Info", bb -> bb_info);
343: printv ("Map", bb -> bb_map);
344: printv ("Password", bb -> bb_passwd);
345: if (strcmp (bb -> bb_name, bb -> bb_addr))
346: printv ("Address", bb -> bb_addr);
347: if (strcmp (*bb -> bb_leader, bb -> bb_request))
348: printv ("Request", bb -> bb_request);
349: if (*bb -> bb_relay)
350: printv ("Relay", bb -> bb_relay);
351: if (*bb -> bb_dist) {
352: changed = 0;
353: (void) getbbdist (bb, action);
354: if (!changed)
355: printv ("Dist", "");
356: if (cp = getbberr ())
357: printv ("Error", cp);
358: }
359: printb (bb -> bb_flags);
360: }
361: }
362: }
363:
364: /* */
365:
366: printv (key, value)
367: register char *key,
368: *value;
369: {
370: char buffer[BUFSIZ];
371:
372: if (key)
373: (void) sprintf (buffer, "%s: ", key);
374: else
375: buffer[0] = '\0';
376: printf ("%*s%-*s", 25, "", 10, buffer);
377: if (value && *value)
378: printf ("%s", value);
379: (void) putchar ('\n');
380: }
381:
382:
383: int action (local, domain)
384: register char *local,
385: *domain;
386: {
387: char buffer[BUFSIZ];
388:
389: (void) sprintf (buffer, "%s@%s", local, domain);
390: printv (changed++ ? NULL : "Dist", buffer);
391: return 0;
392: }
393:
394:
395: printb (flags)
396: unsigned int flags;
397: {
398: char buffer[BUFSIZ];
399:
400: printv ("Flags", sprintb (buffer, flags, BBITS));
401: }
402:
403: /* */
404:
405: check () {
406: #define grammar(a,b,c) (a == 1 ? b : c)
407: #define plural(d) grammar(d, "", "s")
408:
409: int diff;
410: register struct bboard *bb;
411:
412: for (bb = bbl; bb; bb = bb -> bb_link) {
413: diff = bb -> bb_maxima - bb -> bb_count;
414: if (quietsw) {
415: if (diff > 0)
416: printf ("%s -- %d item%s unseen\n",
417: bb -> bb_name, diff, plural (diff));
418: }
419: else
420: if (bb -> bb_maxima == 0)
421: printf ("%s -- empty\n", bb -> bb_name);
422: else
423: if (bb -> bb_count == 0)
424: printf ("%s -- %d item%sseen)\n",
425: bb -> bb_name, bb -> bb_maxima,
426: grammar (bb -> bb_maxima, " (un", "s (none "));
427: else
428: if (diff <= 0)
429: printf ("%s -- %d item%s (all seen)\n",
430: bb -> bb_name, bb -> bb_maxima,
431: plural (bb -> bb_maxima));
432: else
433: printf ("%s -- %d item%s unseen\n",
434: bb -> bb_name, diff, plural (diff));
435: }
436: }
437:
438: /* */
439:
440: process (vecp, vec)
441: int vecp;
442: char *vec[];
443: {
444: int diff;
445: #ifdef SIGTSTP
446: int (*tstat) ();
447: #endif SIGTSTP
448: register struct bboard *bb;
449:
450: vec[0] = r1bindex (mshproc, '/');
451: #ifdef SIGTSTP
452: tstat = signal (SIGTSTP, tstpser);
453: #endif SIGTSTP
454:
455: for (bb = bbl; bb && !quitting; bb = bb -> bb_link) {
456: diff = bb -> bb_maxima - bb -> bb_count;
457: if (bb -> bb_maxima == 0) {
458: if (!quietsw)
459: printf ("%s -- empty\n", bb -> bb_name);
460: continue;
461: }
462: else
463: if (verbosw || archivesw || diff > 0)
464: bbread (bb, vecp, vec);
465: else
466: if (!quietsw)
467: printf ("%s -- %d item%s (all seen)\n",
468: bb -> bb_name, bb -> bb_maxima,
469: plural (bb -> bb_maxima));
470:
471: };
472:
473: #ifdef SIGTSTP
474: (void) signal (SIGTSTP, tstat);
475: #endif SIGTSTP
476: rcend ();
477: }
478:
479: /* */
480:
481: #ifdef BPOP
482: /* ARGSUSED */
483:
484: static int xtnd1 (s)
485: char *s;
486: {
487: return OK;
488: }
489: #endif BPOP
490:
491: /* */
492:
493: bbread (bb, vecp, vec)
494: register struct bboard *bb;
495: int vecp;
496: char *vec[];
497: {
498: int child_id,
499: pd[2];
500: char buf1[BUFSIZ],
501: buf2[BUFSIZ],
502: buf3[BUFSIZ];
503: #ifdef BPOP
504: int nmsgs,
505: nbytes;
506: char buf4[BUFSIZ],
507: buf5[BUFSIZ];
508: #endif BPOP
509: struct stat st;
510:
511: #ifdef BPOP
512: if (bb -> bb_flags & BB_REMOTE) {
513: if (pop_xtnd (xtnd1, "%s %s", archivesw ? "archive" : "bboards",
514: bb -> bb_name) == NOTOK) {
515: advise (NULLCP, "%s", response);
516: return;
517: }
518: if (pop_stat (&nmsgs, &nbytes) == NOTOK)
519: adios (NULLCP, "%s", response);
520: if (nmsgs == 0)
521: return;
522: if (pop_fd (buf4, buf5) == NOTOK)
523: adios (NULLCP, "%s", response);
524: }
525: else
526: #endif BPOP
527: if (stat (archivesw ? bb -> bb_archive : bb -> bb_file, &st) != NOTOK
528: && st.st_size == 0)
529: return;
530:
531: if (protsw) {
532: if (pipe (pd) == NOTOK)
533: adios ("pipe", "unable to");
534: (void) sprintf (buf3, "%d", getpid ());
535: }
536:
537: switch (child_id = fork ()) {
538: case NOTOK:
539: adios ("fork", "unable to");
540:
541: case OK:
542: if (protsw) {
543: (void) close (pd[0]);
544: (void) sprintf (buf1, "%d", bb -> bb_count + 1);
545: (void) sprintf (buf2, "%d", pd[1]);
546: vec[vecp++] = "-idname";
547: vec[vecp++] = bb -> bb_name;
548: vec[vecp++] = "-idstart";
549: vec[vecp++] = buf1;
550: vec[vecp++] = "-idstop";
551: vec[vecp++] = buf2;
552: vec[vecp++] = "-idquit";
553: vec[vecp++] = buf3;
554: }
555: #ifdef BPOP
556: if (bb -> bb_flags & BB_REMOTE) {
557: vec[vecp++] = "-popread";
558: vec[vecp++] = buf4;
559: vec[vecp++] = "-popwrite";
560: vec[vecp++] = buf5;
561: }
562: #endif BPOP
563: vec[vecp++] = archivesw ? bb -> bb_archive : bb -> bb_file;
564: vec[vecp] = NULL;
565: execvp (mshproc, vec);
566: fprintf (stderr, "unable to exec ");
567: perror (mshproc);
568: _exit (-1);
569:
570: default:
571: #ifdef SIGTSTP
572: tstpid = child_id;
573: #endif SIGTSTP
574: if (protsw) {
575: (void) close (pd[1]);
576: pgmread (pd[0], child_id, bb);
577: }
578: else
579: (void) pidXwait (child_id, mshproc);
580: }
581: }
582:
583: /* */
584:
585: pgmread (pd, child_id, bb)
586: int pd,
587: child_id;
588: register struct bboard *bb;
589: {
590: int i,
591: j,
592: n;
593: int (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
594: char buffer[BUFSIZ];
595: struct bbcount *selected;
596:
597: estat = signal (SIGEMT, sigser);
598: hstat = signal (SIGHUP, SIG_IGN);
599: istat = signal (SIGINT, SIG_IGN);
600: qstat = signal (SIGQUIT, SIG_IGN);
601: tstat = signal (SIGTERM, sigser);
602:
603: while ((n = read (pd, buffer, sizeof buffer)) == NOTOK && errno == EINTR)
604: continue;
605: (void) close (pd);
606: (void) pidXwait (child_id, mshproc);
607:
608: (void) signal (SIGEMT, estat);
609: (void) signal (SIGHUP, hstat);
610: (void) signal (SIGINT, istat);
611: (void) signal (SIGQUIT, qstat);
612: (void) signal (SIGTERM, tstat);
613:
614: if (n <= 0)
615: return;
616: if (sscanf (buffer, "%d %d", &i, &j) != 2 || i <= 0 || j <= 0)
617: return;
618:
619: if ((selected = seek_count (bbc, bb -> bb_name)) == NULL) {
620: bbc = add_count (bbc, bb -> bb_name, i);
621: changed++;
622: }
623: else
624: if (archivesw) {
625: if (i > selected -> count) {
626: selected -> count = i;
627: changed++;
628: }
629: }
630: else {
631: if (bb -> bb_maxima > j && i >= j)/* bbl... */
632: i = bb -> bb_maxima;
633: if (i != selected -> count) {
634: selected -> count = i;
635: changed++;
636: }
637: }
638: }
639:
640:
641: /* ARGSUSED */
642:
643: int sigser (i)
644: int i;
645: {
646: #ifndef BSD42
647: (void) signal (i, sigser);
648: #endif not BSD42
649: quitting++;
650: }
651:
652: /* */
653:
654: rcinit (rc)
655: register char *rc;
656: {
657: int state;
658: register char *cp;
659: char key[NAMESZ],
660: value[BUFSIZ];
661: register FILE *bbrc;
662:
663: if ((cp = rc ? rc : getenv ("MHBBRC")) && *cp) {
664: rcfile = path (cp, TFILE);
665: if (*cp != '/')
666: (void) putenv ("MHBBRC", rcfile);
667: }
668: else
669: rcfile = concat (mypath, "/", RCFILE, NULLCP);
670:
671: if ((bbrc = fopen (rcfile, "r")) == NULL)
672: if (cp && *cp)
673: adios (rcfile, "unable to read");
674: else
675: return;
676:
677: for (state = FLD;;) {
678: switch (state = m_getfld (state, key, value, sizeof value, bbrc)) {
679: case FLD:
680: case FLDEOF:
681: make_lower (key, key);
682: bbc = add_count (bbc, key, atoi (value));
683: if (state == FLDEOF)
684: break;
685: continue;
686:
687: default:
688: admonish (NULLCP, "bad format: %s", rcfile);
689: case FILEEOF:
690: break;
691: }
692:
693: break;
694: }
695:
696: if (ferror (bbrc))
697: admonish (rcfile, "error reading");
698: (void) fclose (bbrc);
699: }
700:
701: /* */
702:
703: rcend () {
704: int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
705: register FILE *bbrc;
706:
707: if (!changed)
708: return;
709:
710: hstat = signal (SIGHUP, SIG_IGN);
711: istat = signal (SIGINT, SIG_IGN);
712: qstat = signal (SIGQUIT, SIG_IGN);
713: tstat = signal (SIGTERM, SIG_IGN);
714:
715: if ((bbrc = fopen (rcfile, "w")) == NULL)
716: adios (rcfile, "unable to write");
717: rcput (bbrc, bbc);
718:
719: if (ferror (bbrc))
720: adios (rcfile, "error writing");
721: (void) fclose (bbrc);
722:
723: (void) signal (SIGHUP, hstat);
724: (void) signal (SIGINT, istat);
725: (void) signal (SIGQUIT, qstat);
726: (void) signal (SIGTERM, tstat);
727:
728: changed = 0;
729: }
730:
731:
732: rcput (bbrc, p)
733: register FILE *bbrc;
734: register struct bbcount *p;
735: {
736: if (p == NULL)
737: return;
738:
739: fprintf (bbrc, "%s: %d\n", p -> key, p -> count);
740: rcput (bbrc, p -> left);
741: rcput (bbrc, p -> right);
742: }
743:
744: /* */
745:
746: #ifdef SIGTSTP
747: static int tstpser (sig)
748: int sig;
749: {
750: int pid;
751: union wait w;
752:
753: rcend ();
754:
755: while ((pid = wait3 (&w, WUNTRACED, (struct rusage *) 0)) != NOTOK
756: && pid != tstpid)
757: continue;
758:
759: (void) signal (SIGTSTP, SIG_DFL);
760: #ifdef BSD42
761: (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
762: #endif BSD42
763:
764: (void) kill (getpid (), sig);
765:
766: #ifdef BSD42
767: (void) sigblock (sigmask (SIGTSTP));
768: #endif BSD42
769: (void) signal (SIGTSTP, tstpser);
770: }
771: #endif SIGTSTP
772:
773: /* */
774:
775: struct bbcount *add_count (p, w, i)
776: register struct bbcount *p;
777: register char *w;
778: int i;
779: {
780: int cond;
781:
782: if (p == NULL) {
783: p = (struct bbcount *) malloc (sizeof *p);
784: if (p == NULL)
785: adios (NULLCP,"insufficient memory");
786: p -> key = getcpy (w);
787: p -> count = i;
788: p -> left = p -> right = NULL;
789: }
790: else
791: if ((cond = strcmp (w, p -> key)) < 0)
792: p -> left = add_count (p -> left, w, i);
793: else
794: if (cond > 0)
795: p -> right = add_count (p -> right, w, i);
796:
797: return p;
798: }
799:
800:
801: struct bbcount *seek_count (p, w)
802: register struct bbcount *p;
803: register char *w;
804: {
805: int cond;
806:
807: if (p == NULL || (cond = strcmp (w, p -> key)) == 0)
808: return p;
809: else
810: return seek_count (cond < 0 ? p -> left : p -> right, w);
811: }
812:
813: /* */
814:
815: default_bboards () {
816: register char *cp,
817: **ap;
818:
819: if (bbl != NULL)
820: return;
821:
822: if (!archivesw && ((cp = m_find ("bboards")) != NULL)) {
823: #ifndef BPOP
824: for (ap = brkstring (cp = getcpy (cp), " ", "\n"); *ap; ap++)
825: #else BPOP
826: for (ap = getip (cp); *ap; ap++)
827: #endif BPOP
828: add_bb (*ap, OK);
829: #ifndef BPOP
830: free (cp);
831: #endif not BPOP
832: }
833: else
834: add_bb ("system", NOTOK);
835:
836: if (bbl == NULL)
837: done (1);
838: }
839:
840: /* */
841:
842: add_bb (s, hush)
843: register char *s;
844: int hush;
845: {
846: register struct bboard *bb;
847: static struct bboard *tail = NULL;
848:
849: make_lower (s, s);
850: if ((bb = getbbaux (s)) == NULL)
851: if (hush == OK)
852: return;
853: else
854: adios (NULLCP, "no such bboard as '%s'", s);
855:
856: if (tail != NULL)
857: tail -> bb_link = bb;
858: if (bbl == NULL)
859: bbl = bb;
860: tail = bb;
861: }
862:
863: /* */
864:
865: #ifdef BPOP
866: static struct bboard *Bhead = NULL;
867: static struct bboard *Btail = NULL;
868:
869: static int xtnd2 (s)
870: char *s;
871: {
872: int maxima;
873: char name[BUFSIZ];
874: register struct bboard *bb;
875:
876: if (sscanf (s, "%s %d", name, &maxima) != 2)
877: adios (NULLCP, "XTND2 botch: %s", s);
878:
879: if ((bb = (struct bboard *) calloc (1, sizeof *bb)) == NULL)
880: adios (NULLCP, "insufficient memory");
881: bb -> bb_name = getcpy (name);
882: if ((bb -> bb_aka = (char **) calloc (1, sizeof *bb -> bb_aka)) == NULL)
883: adios (NULLCP, "insufficient memory");
884: *bb -> bb_aka = NULL;
885: bb -> bb_file = bb -> bb_archive = bb -> bb_info = bb -> bb_map = "";
886: bb -> bb_passwd = "";
887: if ((bb -> bb_leader = (char **) calloc (1, sizeof *bb -> bb_leader))
888: == NULL)
889: adios (NULLCP, "insufficient memory");
890: *bb -> bb_leader = NULL;
891: bb -> bb_addr = bb -> bb_request = bb -> bb_relay = "";
892: if ((bb -> bb_dist = (char **) calloc (1, sizeof *bb -> bb_dist)) == NULL)
893: adios (NULLCP, "insufficient memory");
894: *bb -> bb_dist = NULL;
895: bb -> bb_flags = BB_REMOTE;
896: bb -> bb_count = 0;
897: bb -> bb_maxima = maxima;
898: bb -> bb_date = "";
899: bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL;
900:
901: if (Btail != NULL)
902: Btail -> bb_chain = bb;
903: if (Bhead == NULL)
904: Bhead = bb;
905: Btail = bb;
906:
907: return OK;
908: }
909:
910: /* */
911:
912: static int xtnd3 (s)
913: char *s;
914: {
915: static int bbs = 0;
916: static struct bboard *bb;
917:
918: switch (bbs++) {
919: case 0:
920: for (bb = Bhead; bb; bb = bb -> bb_chain)
921: if (strcmp (bb -> bb_name, s) == 0)
922: break;
923: if (bb == NULL)
924: adios (NULLCP, "XTND3 botch");
925:
926: free (bb -> bb_name);
927: bb -> bb_name = getcpy (s);
928: break;
929: case 1:
930: if (bb -> bb_aka)
931: free ((char *) bb -> bb_aka);
932: bb -> bb_aka = getip (s);
933: break;
934: case 2:
935: bb -> bb_file = getcpy (s);
936: break;
937: case 3:
938: bb -> bb_archive = getcpy (s);
939: break;
940: case 4:
941: bb -> bb_info = getcpy (s);
942: break;
943: case 5:
944: bb -> bb_map = getcpy (s);
945: break;
946: case 6:
947: bb -> bb_passwd = getcpy (s);
948: break;
949: case 7:
950: if (bb -> bb_leader)
951: free ((char *) bb -> bb_leader);
952: bb -> bb_leader = getip (s);
953: break;
954: case 8:
955: bb -> bb_addr = getcpy (s);
956: break;
957: case 9:
958: bb -> bb_request = getcpy (s);
959: break;
960: case 10:
961: bb -> bb_relay = getcpy (s);
962: break;
963: case 11:
964: if (bb -> bb_dist)
965: free ((char *) bb -> bb_dist);
966: bb -> bb_dist = getip (s);
967: break;
968: case 12:
969: bb -> bb_flags = bb -> bb_maxima = 0;
970: (void) sscanf (s, "%o %d", &bb -> bb_flags, &bb -> bb_maxima);
971: bb -> bb_flags |= BB_REMOTE;
972: break;
973: case 13:
974: bb -> bb_date = getcpy (s);
975: bbs = 0;
976: break;
977: }
978:
979: return OK;
980: }
981:
982:
983: static char **getip (s)
984: char *s;
985: {
986: register char **ap,
987: **p,
988: **q;
989:
990: for (p = ap = brkstring (getcpy (s), " ", "\n"); *p; p++)
991: continue;
992:
993: q = (char **) calloc ((unsigned) (p - ap + 1), sizeof *q);
994: if (q == NULL)
995: adios (NULLCP, "insufficient memory");
996:
997: for (p = ap, ap = q; *p; *q++ = *p++)
998: continue;
999: *q = NULL;
1000:
1001: return ap;
1002: }
1003:
1004: /* */
1005:
1006: static struct bboard *rover = NULL;
1007:
1008: struct bboard *getbbpop () {
1009: int snoop;
1010: char *cp,
1011: *pass = NULL;
1012: register struct bboard *bb;
1013:
1014: if (didpop != NOTOK && ((bb = getbbent ()) || !host))
1015: return bb;
1016:
1017: if (Bhead == NULL) {
1018: snoop = (cp = getenv ("MHPOPDEBUG")) && *cp;
1019: if (rpop) {
1020: if (user == NULL)
1021: user = getusr ();
1022: pass = getusr ();
1023: }
1024: else
1025: if (strcmp (user, popbbuser) == 0)
1026: pass = user;
1027: else
1028: ruserpass (host, &user, &pass);
1029: if (didpop != NOTOK)
1030: didpop = DONE;
1031:
1032: if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
1033: adios (NULLCP, "%s", response);
1034: if (rpop)
1035: (void) setuid (getuid ());
1036: if (pop_xtnd (xtnd2, "bboards") == NOTOK)
1037: adios (NULLCP, "%s", response);
1038: if (topicsw && verbosw) /* could optimize here */
1039: for (bb = Bhead; bb; bb = bb -> bb_chain)
1040: if (pop_xtnd (xtnd3, "x-bboards %s", bb -> bb_name) == NOTOK)
1041: adios (NULLCP, "%s", response);
1042: rover = Bhead;
1043: }
1044:
1045: if (bb = rover)
1046: rover = rover -> bb_chain;
1047: return bb;
1048: }
1049:
1050: #define getbbent getbbpop
1051: #endif BPOP
1052:
1053: /* */
1054:
1055: struct bboard *getbbaux (s)
1056: register char *s;
1057: {
1058: #ifdef BPOP
1059: int nlatch = host ? 1 : 0;
1060: #endif BPOP
1061: register char **ap;
1062: register struct bbcount *selected;
1063: register struct bboard *bb;
1064: static struct bboard *head = NULL,
1065: *tail = NULL;
1066:
1067: for (bb = head; bb; bb = bb -> bb_next) {
1068: if (strcmp (bb -> bb_name, s) == 0)
1069: return bb;
1070: for (ap = bb -> bb_aka; *ap; ap++)
1071: if (strcmp (*ap, s) == 0)
1072: return bb;
1073: }
1074:
1075: #ifdef BPOP
1076: one_more_time: ;
1077: #endif BPOP
1078: while (bb = getbbent ()) {
1079: if ((selected = seek_count (bbc, bb -> bb_name)) != NULL)
1080: bb -> bb_count = selected -> count;
1081:
1082: #ifdef BPOP
1083: if (!(bb -> bb_flags & BB_REMOTE))
1084: #endif BPOP
1085: if ((bb = getbbcpy (bb)) == NULL)
1086: adios (NULLCP, "insufficient memory");
1087: if (tail != NULL)
1088: tail -> bb_next = bb;
1089: if (head == NULL)
1090: head = bb;
1091: tail = bb;
1092:
1093: if (strcmp (bb -> bb_name, s) == 0)
1094: return bb;
1095: for (ap = bb -> bb_aka; *ap; ap++)
1096: if (strcmp (*ap, s) == 0)
1097: return bb;
1098: }
1099:
1100: #ifdef BPOP
1101: if (nlatch && pop_xtnd (xtnd2, "bboards %s", s) != NOTOK) {
1102: rover = Bhead;
1103: nlatch = 0;
1104: goto one_more_time;
1105: }
1106: #endif BPOP
1107:
1108: return NULL;
1109: }
1110:
1111:
1112: struct bboard *getbbvis () {
1113: register struct bboard *bb;
1114:
1115: while (bb = getbbent ())
1116: if (!(bb -> bb_flags & BB_INVIS)
1117: && (access (bb -> bb_file, 04) != NOTOK || errno != EACCES))
1118: break;
1119:
1120: return bb;
1121: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.