]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/bboards/getbbent.c
Always check that mktemp()/mktemp2() succeeds before trying to
[nmh] / docs / historical / mh-6.8.5 / zotnet / bboards / getbbent.c
1 /* getbbent.c - subroutines for accessing the BBoards file */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: getbbent.c,v 1.14 1992/12/15 00:20:22 jromine Exp $";
4 #endif /* lint */
5
6 /* LINTLIBRARY */
7
8 #include "bboards.h"
9 #ifndef MMDFONLY
10 #include "../h/strings.h"
11 #include <sys/types.h>
12 #else /* MMDFONLY */
13 #include "util.h"
14 #include "mmdf.h"
15 #include "strings.h"
16 #endif /* MMDFONLY */
17 #include <ctype.h>
18 #include <pwd.h>
19 #include <grp.h>
20 #include <stdio.h>
21 #include <sys/stat.h>
22
23
24 #ifndef MMDFONLY
25 #define NOTOK (-1)
26 #define OK 0
27 #endif /* not MMDFONLY */
28
29
30 #define MaxBBAka 100
31 #define MaxBBLdr 100
32 #define MaxBBDist 100
33
34
35 #define NCOLON 9 /* currently 10 fields per entry */
36
37 #define COLON ':'
38 #define COMMA ','
39 #define NEWLINE '\n'
40
41
42 #define ARCHIVE "archive"
43 #define CNTFILE ".cnt"
44 #define DSTFILE ".dist"
45 #define MAPFILE ".map"
46
47 /* \f */
48
49 static int BBuid = -1;
50
51 static unsigned int BBflags = SB_NULL;
52
53 static char BBName[BUFSIZ] = BBOARDS;
54 static char BBDir[BUFSIZ] = "";
55 static char BBData[BUFSIZ] = "";
56
57 static FILE *BBfile = NULL;
58
59
60 static struct bboard BB;
61 static struct bboard *bb = &BB;
62
63 static int BBload = 1;
64
65 static char BBFile[BUFSIZ];
66 static char BBArchive[BUFSIZ];
67 static char BBInfo[BUFSIZ];
68 static char BBMap[BUFSIZ];
69 static char *BBAkas[MaxBBAka];
70 static char *BBLeaders[MaxBBLdr];
71 static char *BBDists[MaxBBDist];
72 static char BBAddr[BUFSIZ];
73 static char BBRequest[BUFSIZ];
74 static char BBDate[BUFSIZ];
75 static char BBErrors[BUFSIZ];
76
77 #ifdef MMDFONLY
78 extern LLog *logptr;
79 #endif /* MMDFONLY */
80
81 static char *bbskip (), *getcpy ();
82
83 #if defined(__STDC__) && defined(SVR4)
84 #include <crypt.h>
85 #endif
86 #if defined(UNISTD) || defined(_AIX)
87 #include <unistd.h>
88 #else
89 #ifndef __STDC__
90 char *crypt (), *getpass ();
91 struct group *getgrnam ();
92 #ifdef SYS5
93 struct passwd *getpwnam (), *getpwuid ();
94 #endif
95 #endif /* !__STDC__ */
96 #endif /* _AIX */
97 static int setpwaux(), getbbitem(), bblose();
98 static void BBread();
99
100 #ifdef UCL
101 int called_bbc = 0;
102 char *bbs[101];
103 #endif
104 /* \f */
105
106 int setbbfile (file, f)
107 register char *file;
108 register int f;
109 {
110 if (BBuid == -1)
111 return setbbinfo (BBOARDS, file, f);
112
113 (void) strcpy (BBData, file);
114
115 BBflags = SB_NULL;
116 (void) endbbent ();
117
118 return setbbent (f);
119 }
120
121 /* \f */
122
123 int setbbinfo (user, file, f)
124 register char *user,
125 *file;
126 register int f;
127 {
128 register struct passwd *pw;
129
130 if ((pw = getpwnam (user)) == NULL) {
131 (void) sprintf (BBErrors, "unknown user: %s", user);
132 return 0;
133 }
134
135 return setpwinfo (pw, file, f);
136 }
137
138
139 int setpwinfo (pw, file, f)
140 register struct passwd *pw;
141 register char *file;
142 register int f;
143 {
144 if (!setpwaux (pw, file))
145 return 0;
146
147 BBflags = SB_NULL;
148 (void) endbbent ();
149
150 return setbbent (f);
151 }
152
153 /* \f */
154
155 static int setbbaux (name, file)
156 register char *name,
157 *file;
158 {
159 register struct passwd *pw;
160
161 if ((pw = getpwnam (name)) == NULL) {
162 (void) sprintf (BBErrors, "unknown user: %s", name);
163 return 0;
164 }
165
166 return setpwaux (pw, file);
167 }
168
169
170 static int setpwaux (pw, file)
171 register struct passwd *pw;
172 register char *file;
173 {
174 (void) strcpy (BBName, pw -> pw_name);
175 BBuid = pw -> pw_uid;
176 (void) strcpy (BBDir, pw -> pw_dir);
177 (void) sprintf (BBData, "%s/%s",
178 *file != '/' ? BBDir : "",
179 *file != '/' ? file : file + 1);
180
181 BBflags = SB_NULL;
182
183 return 1;
184 }
185
186 /* \f */
187
188 int setbbent (f)
189 register int f;
190 {
191 if (BBfile == NULL) {
192 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
193 return 0;
194
195 if ((BBfile = fopen (BBData, "r")) == NULL) {
196 (void) sprintf (BBErrors, "unable to open: %s", BBData);
197 return 0;
198 }
199 }
200 else
201 rewind (BBfile);
202
203 BBflags |= f;
204 return (BBfile != NULL);
205 }
206
207
208 int endbbent () {
209 if (BBfile != NULL && !(BBflags & SB_STAY)) {
210 (void) fclose (BBfile);
211 BBfile = NULL;
212 }
213
214 return 1;
215 }
216
217
218 long getbbtime () {
219 struct stat st;
220
221 if (BBfile == NULL) {
222 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
223 return 0;
224
225 if (stat (BBData, &st) == NOTOK) {
226 (void) sprintf (BBErrors, "unable to stat: %s", BBData);
227 return 0;
228 }
229 }
230 else
231 if (fstat (fileno (BBfile), &st) == NOTOK) {
232 (void) sprintf (BBErrors, "unable to fstat: %s", BBData);
233 return 0;
234 }
235
236 return ((long) st.st_mtime);
237 }
238
239 /* \f */
240
241 struct bboard *getbbent () {
242 register int count;
243 register char *p,
244 *q,
245 *r,
246 *d,
247 *f,
248 **s;
249 static char line[BUFSIZ];
250
251 if (BBfile == NULL && !setbbent (SB_NULL))
252 return NULL;
253
254 retry: ;
255 if ((p = fgets (line, sizeof line, BBfile)) == NULL)
256 return NULL;
257
258 for (q = p, count = 0; *q != 0 && *q != NEWLINE; q++)
259 if (*q == COLON)
260 count++;
261
262 if (count != NCOLON) {
263 #ifdef MMDFONLY
264 if (q = index (p, NEWLINE))
265 *q = 0;
266 ll_log (logptr, LLOGTMP, "bad entry in %s: %s", BBData, p);
267 #endif /* MMDFONLY */
268 goto retry;
269 }
270
271 bb -> bb_name = p;
272 p = q = bbskip (p, COLON);
273 p = bb -> bb_file = bbskip (p, COLON);
274 bb -> bb_archive = bb -> bb_info = bb -> bb_map = "";
275 p = bb -> bb_passwd = bbskip (p, COLON);
276 p = r = bbskip (p, COLON);
277 p = bb -> bb_addr = bbskip (p, COLON);
278 p = bb -> bb_request = bbskip (p, COLON);
279 p = bb -> bb_relay = bbskip (p, COLON);
280 p = d = bbskip (p, COLON);
281 p = f = bbskip (p, COLON);
282 (void) bbskip (p, NEWLINE);
283
284 s = bb -> bb_aka = BBAkas;
285 while (*q) {
286 *s++ = q;
287 q = bbskip (q, COMMA);
288 }
289 *s = 0;
290
291 s = bb -> bb_leader = BBLeaders;
292 if (*r == 0) {
293 if (!(BBflags & SB_FAST)) {
294 *s++ = BBName;
295 *s = 0;
296 }
297 }
298 else {
299 while (*r) {
300 *s++ = r;
301 r = bbskip (r, COMMA);
302 }
303 *s = 0;
304 }
305
306 s = bb -> bb_dist = BBDists;
307 while (*d) {
308 *s++ = d;
309 d = bbskip (d, COMMA);
310 }
311 *s = 0;
312
313 if (*f)
314 (void) sscanf (f, "%o", &bb -> bb_flags);
315 else
316 bb -> bb_flags = BB_NULL;
317 bb -> bb_count = bb -> bb_maxima = 0;
318 bb -> bb_date = NULL;
319 bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL;
320
321 #ifdef UCL
322 /*
323 * Only do a BBread on bboards that the user has expressed an
324 * interest in, if we were called by bbc.
325 */
326 if (BBload) {
327 register char **ap, *cp;
328 register int bbp;
329
330 if (called_bbc == 0)
331 BBread();
332 else {
333 for (bbp = 0; cp = bbs[bbp]; bbp++) {
334 if (!strcmp(bb->bb_name, cp)) {
335 BBread();
336 break;
337 }
338 for (ap = bb->bb_aka; *ap; ap++)
339 if (!strcmp(*ap, cp)) {
340 BBread();
341 break;
342 }
343 }
344 }
345 }
346 #else
347 if (BBload)
348 BBread ();
349 #endif
350
351 return bb;
352 }
353
354 /* \f */
355
356 struct bboard *getbbnam (name)
357 register char *name;
358 {
359 register struct bboard *b = NULL;
360
361 if (!setbbent (SB_NULL))
362 return NULL;
363 BBload = 0;
364 while ((b = getbbent ()) && strcmp (name, b -> bb_name))
365 continue;
366 BBload = 1;
367 (void) endbbent ();
368
369 if (b != NULL)
370 BBread ();
371
372 return b;
373 }
374
375
376 struct bboard *getbbaka (aka)
377 register char *aka;
378 {
379 register char **ap;
380 register struct bboard *b = NULL;
381
382 if (!setbbent (SB_NULL))
383 return NULL;
384 BBload = 0;
385 while ((b = getbbent ()) != NULL)
386 for (ap = b -> bb_aka; *ap; ap++)
387 if (strcmp (aka, *ap) == 0)
388 goto hit;
389 hit: ;
390 BBload = 1;
391 (void) endbbent ();
392
393 if (b != NULL)
394 BBread ();
395
396 return b;
397 }
398
399 /* \f */
400
401 static void BBread ()
402 {
403 register int i;
404 register char *cp,
405 *dp,
406 *p,
407 *r;
408 char prf[BUFSIZ];
409 static char line[BUFSIZ];
410 register FILE * info;
411
412 if (BBflags & SB_FAST)
413 return;
414
415 p = index (bb -> bb_request, '@');
416 r = index (bb -> bb_addr, '@');
417 BBRequest[0] = 0;
418
419 if (*bb -> bb_request == '-')
420 if (p == NULL && r && *r == '@')
421 (void) sprintf (BBRequest, "%s%s%s",
422 bb -> bb_name, bb -> bb_request, r);
423 else
424 (void) sprintf (BBRequest, "%s%s",
425 bb -> bb_name, bb -> bb_request);
426 else
427 if (p == NULL && r && *r == '@' && *bb -> bb_request)
428 (void) sprintf (BBRequest, "%s%s", bb -> bb_request, r);
429
430 if (BBRequest[0])
431 bb -> bb_request = BBRequest;
432 else
433 if (*bb -> bb_request == 0)
434 bb -> bb_request = *bb -> bb_addr ? bb -> bb_addr
435 : bb -> bb_leader[0];
436
437 if (*bb -> bb_addr == '@') {
438 (void) sprintf (BBAddr, "%s%s", bb -> bb_name, bb -> bb_addr);
439 bb -> bb_addr = BBAddr;
440 }
441 else
442 if (*bb -> bb_addr == 0)
443 bb -> bb_addr = bb -> bb_name;
444
445 if (*bb -> bb_file == 0)
446 return;
447 if (*bb -> bb_file != '/') {
448 (void) sprintf (BBFile, "%s/%s", BBDir, bb -> bb_file);
449 bb -> bb_file = BBFile;
450 }
451
452 if ((cp = rindex (bb -> bb_file, '/')) == NULL || *++cp == 0)
453 (void) strcpy (prf, ""), cp = bb -> bb_file;
454 else
455 (void) sprintf (prf, "%.*s", cp - bb -> bb_file, bb -> bb_file);
456 if ((dp = index (cp, '.')) == NULL)
457 dp = cp + strlen (cp);
458
459 (void) sprintf (BBArchive, "%s%s/%s", prf, ARCHIVE, cp);
460 bb -> bb_archive = BBArchive;
461 (void) sprintf (BBInfo, "%s.%.*s%s", prf, dp - cp, cp, CNTFILE);
462 bb -> bb_info = BBInfo;
463 (void) sprintf (BBMap, "%s.%.*s%s", prf, dp - cp, cp, MAPFILE);
464 bb -> bb_map = BBMap;
465
466 if ((info = fopen (bb -> bb_info, "r")) == NULL)
467 return;
468
469 if (fgets (line, sizeof line, info) && (i = atoi (line)) > 0)
470 bb -> bb_maxima = (unsigned) i;
471 if (!feof (info) && fgets (line, sizeof line, info)) {
472 (void) strcpy (BBDate, line);
473 if (cp = index (BBDate, NEWLINE))
474 *cp = 0;
475 bb -> bb_date = BBDate;
476 }
477
478 (void) fclose (info);
479 }
480
481 /* \f */
482
483 int ldrbb (b)
484 register struct bboard *b;
485 {
486 register char *p,
487 **q,
488 **r;
489 static int uid = 0,
490 gid = 0;
491 static char username[10] = "";
492 register struct passwd *pw;
493 register struct group *gr;
494
495 if (b == NULL)
496 return 0;
497 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
498 return 0;
499
500 if (username[0] == 0) {
501 if ((pw = getpwuid (uid = getuid ())) == NULL)
502 return 0;
503 gid = getgid ();
504 (void) strcpy (username, pw -> pw_name);
505 }
506
507 if (uid == BBuid)
508 return 1;
509
510 q = b -> bb_leader;
511 while (p = *q++)
512 if (*p == '=') {
513 if ((gr = getgrnam (++p)) == NULL)
514 continue;
515 if (gid == gr -> gr_gid)
516 return 1;
517 r = gr -> gr_mem;
518 while (p = *r++)
519 if (strcmp (username, p) == 0)
520 return 1;
521 }
522 else
523 if (strcmp (username, p) == 0)
524 return 1;
525
526 return 0;
527 }
528
529 /* \f */
530
531 int ldrchk (b)
532 register struct bboard *b;
533 {
534 if (b == NULL)
535 return 0;
536
537 if (*b -> bb_passwd == 0)
538 return 1;
539
540 if (strcmp (b -> bb_passwd,
541 crypt (getpass ("Password: "), b -> bb_passwd)) == 0)
542 return 1;
543
544 fprintf (stderr, "Sorry\n");
545 return 0;
546 }
547
548 /* \f */
549
550 struct bboard *getbbcpy (bp)
551 register struct bboard *bp;
552 {
553 register char **p,
554 **q;
555 register struct bboard *b;
556
557 if (bp == NULL)
558 return NULL;
559
560 b = (struct bboard *) malloc ((unsigned) sizeof *b);
561 if (b == NULL)
562 return NULL;
563
564 b -> bb_name = getcpy (bp -> bb_name);
565 b -> bb_file = getcpy (bp -> bb_file);
566 b -> bb_archive = getcpy (bp -> bb_archive);
567 b -> bb_info = getcpy (bp -> bb_info);
568 b -> bb_map = getcpy (bp -> bb_map);
569 b -> bb_passwd = getcpy (bp -> bb_passwd);
570 b -> bb_flags = bp -> bb_flags;
571 b -> bb_count = bp -> bb_count;
572 b -> bb_maxima = bp -> bb_maxima;
573 b -> bb_date = getcpy (bp -> bb_date);
574 b -> bb_addr = getcpy (bp -> bb_addr);
575 b -> bb_request = getcpy (bp -> bb_request);
576 b -> bb_relay = getcpy (bp -> bb_relay);
577
578 for (p = bp -> bb_aka; *p; p++)
579 continue;
580 b -> bb_aka =
581 q = (char **) calloc ((unsigned) (p - bp -> bb_aka + 1), sizeof *q);
582 if (q == NULL)
583 return NULL;
584 for (p = bp -> bb_aka; *p; *q++ = getcpy (*p++))
585 continue;
586 *q = NULL;
587
588 for (p = bp -> bb_leader; *p; p++)
589 continue;
590 b -> bb_leader =
591 q = (char **) calloc ((unsigned) (p - bp -> bb_leader + 1), sizeof *q);
592 if (q == NULL)
593 return NULL;
594 for (p = bp -> bb_leader; *p; *q++ = getcpy (*p++))
595 continue;
596 *q = NULL;
597
598 for (p = bp -> bb_dist; *p; p++)
599 continue;
600 b -> bb_dist =
601 q = (char **) calloc ((unsigned) (p - bp -> bb_dist + 1), sizeof *q);
602 if (q == NULL)
603 return NULL;
604 for (p = bp -> bb_dist; *p; *q++ = getcpy (*p++))
605 continue;
606 *q = NULL;
607
608 b -> bb_next = bp -> bb_next;
609 b -> bb_link = bp -> bb_link;
610 b -> bb_chain = bp -> bb_chain;
611
612 return b;
613 }
614
615 /* \f */
616
617 int getbbdist (bb, action)
618 register struct bboard *bb;
619 register int (*action) ();
620 {
621 register int result;
622 register char **dp;
623
624 BBErrors[0] = 0;
625 for (dp = bb -> bb_dist; *dp; dp++)
626 if (result = getbbitem (bb, *dp, action))
627 return result;
628
629 return result;
630 }
631
632 char *getbberr () {
633 return (BBErrors[0] ? BBErrors : NULL);
634 }
635
636 /* \f */
637
638 static int getbbitem (bb, item, action)
639 register struct bboard *bb;
640 register char *item;
641 register int (*action) ();
642 {
643 register int result;
644 register char *cp,
645 *dp,
646 *hp,
647 *np;
648 char mbox[BUFSIZ],
649 buffer[BUFSIZ],
650 file[BUFSIZ],
651 host[BUFSIZ],
652 prf[BUFSIZ];
653 register FILE *fp;
654
655 switch (*item) {
656 case '*':
657 switch (*++item) {
658 case '/':
659 hp = item;
660 break;
661
662 case 0:
663 if ((cp = rindex (bb -> bb_file, '/')) == NULL || *++cp == 0)
664 (void) strcpy (prf, ""), cp = bb -> bb_file;
665 else
666 (void) sprintf (prf, "%.*s", cp - bb -> bb_file, bb -> bb_file);
667 if ((dp = index (cp, '.')) == NULL)
668 dp = cp + strlen (cp);
669 (void) sprintf (file, "%s.%.*s%s", prf, dp - cp, cp, DSTFILE);
670 hp = file;
671 break;
672
673 default:
674 (void) sprintf (file, "%s/%s", BBDir, item);
675 hp = file;
676 break;
677 }
678
679 if ((fp = fopen (hp, "r")) == NULL)
680 return bblose ("unable to read file %s", hp);
681 while (fgets (buffer, sizeof buffer, fp)) {
682 if (np = index (buffer, '\n'))
683 *np = 0;
684 if (result = getbbitem (bb, buffer, action)) {
685 (void) fclose (fp);
686 (void) bblose ("error with file %s, item %s", hp, buffer);
687 return result;
688 }
689 }
690 (void) fclose (fp);
691 return OK;
692
693 default:
694 if (hp = rindex (item, '@')) {
695 *hp++ = 0;
696 (void) strcpy (mbox, item);
697 (void) strcpy (host, hp);
698 *--hp = '@';
699 }
700 else {
701 (void) sprintf (mbox, "%s%s", DISTADR, bb -> bb_name);
702 (void) strcpy (host, item);
703 }
704 if (result = (*action) (mbox, host))
705 (void) bblose ("action (%s, %s) returned 0%o", mbox, host, result);
706 return result;
707 }
708 }
709
710 /* \f */
711
712 /* VARARGS1 */
713
714 static int bblose (fmt, a, b, c)
715 char *fmt,
716 *a,
717 *b,
718 *c;
719 {
720 if (BBErrors[0] == 0)
721 (void) sprintf (BBErrors, fmt, a, b, c);
722
723 return NOTOK;
724 }
725
726 /* \f */
727
728 void make_lower (s1, s2)
729 register char *s1,
730 *s2;
731 {
732 if (s1 == NULL || s2 == NULL)
733 return;
734
735 for (; *s2; s2++)
736 *s1++ = isupper (*s2) ? tolower (*s2) : *s2;
737 *s1 = 0;
738 }
739
740 /* \f */
741
742 static char *bbskip (p, c)
743 register char *p,
744 c;
745 {
746 if (p == NULL)
747 return NULL;
748
749 while (*p && *p != c)
750 p++;
751 if (*p)
752 *p++ = 0;
753
754 return p;
755 }
756
757
758 static char *getcpy (s)
759 register char *s;
760 {
761 register char *p;
762
763 if (s == NULL)
764 return NULL;
765
766 if (p = malloc ((unsigned) (strlen (s) + 1)))
767 (void) strcpy (p, s);
768 return p;
769 }