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