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