3 * getbbent.c -- subroutines for accessing the BBoards file
8 #include "h/mh.h" /* for snprintf() */
38 #define NCOLON 9 /* currently 10 fields per entry */
44 #define ARCHIVE "archive"
45 #define CNTFILE ".cnt"
46 #define DSTFILE ".dist"
47 #define MAPFILE ".map"
49 static int BBuid = -1;
51 static unsigned int BBflags = SB_NULL;
53 static char BBName[BUFSIZ] = BBOARDS;
54 static char BBDir[BUFSIZ] = "";
55 static char BBData[BUFSIZ] = "";
57 static FILE *BBfile = NULL;
59 static struct bboard BB;
60 static struct bboard *bb = &BB;
62 static int BBload = 1;
64 static char BBFile[BUFSIZ];
65 static char BBArchive[BUFSIZ];
66 static char BBInfo[BUFSIZ];
67 static char BBMap[BUFSIZ];
68 static char *BBAkas[MaxBBAka];
69 static char *BBLeaders[MaxBBLdr];
70 static char *BBDists[MaxBBDist];
71 static char BBAddr[BUFSIZ];
72 static char BBRequest[BUFSIZ];
73 static char BBDate[BUFSIZ];
74 static char BBErrors[BUFSIZ];
89 static int setbbaux (char *, char *);
90 static int setpwaux (struct passwd *, char *);
91 static void BBread (void);
92 static int getbbitem (struct bboard *, char *, int (*)());
93 static int bblose (char *, ...);
94 static char *bbskip (char *, char);
95 static char *our_getcpy (char *);
99 setbbfile (char *file, int f)
102 return setbbinfo (BBOARDS, file, f);
104 strncpy (BBData, file, sizeof(BBData));
114 setbbinfo (char *user, char *file, int f)
116 register struct passwd *pw;
118 if ((pw = getpwnam (user)) == NULL) {
119 snprintf (BBErrors, sizeof(BBErrors), "unknown user: %s", user);
123 return setpwinfo (pw, file, f);
128 setpwinfo (struct passwd *pw, char *file, int f)
130 if (!setpwaux (pw, file))
141 setbbaux (char *name, char *file)
143 register struct passwd *pw;
145 if ((pw = getpwnam (name)) == NULL) {
146 snprintf (BBErrors, sizeof(BBErrors), "unknown user: %s", name);
150 return setpwaux (pw, file);
155 setpwaux (struct passwd *pw, char *file)
157 strncpy (BBName, pw->pw_name, sizeof(BBName));
159 strncpy (BBDir, pw->pw_dir, sizeof(BBDir));
160 snprintf (BBData, sizeof(BBData), "%s/%s",
161 *file != '/' ? BBDir : "",
162 *file != '/' ? file : file + 1);
173 if (BBfile == NULL) {
174 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
177 if ((BBfile = fopen (BBData, "r")) == NULL) {
178 snprintf (BBErrors, sizeof(BBErrors), "unable to open: %s", BBData);
186 return (BBfile != NULL);
193 if (BBfile != NULL && !(BBflags & SB_STAY)) {
207 if (BBfile == NULL) {
208 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
211 if (stat (BBData, &st) == NOTOK) {
212 snprintf (BBErrors, sizeof(BBErrors), "unable to stat: %s", BBData);
216 if (fstat (fileno (BBfile), &st) == NOTOK) {
217 snprintf (BBErrors, sizeof(BBErrors), "unable to fstat: %s", BBData);
222 return ((long) st.st_mtime);
230 register char *p, *q, *r, *d, *f, **s;
231 static char line[BUFSIZ];
233 if (BBfile == NULL && !setbbent (SB_NULL))
237 if ((p = fgets (line, sizeof line, BBfile)) == NULL)
240 for (q = p, count = 0; *q != 0 && *q != NEWLINE; q++)
244 if (count != NCOLON) {
246 if (q = strchr(p, NEWLINE))
248 ll_log (logptr, LLOGTMP, "bad entry in %s: %s", BBData, p);
249 #endif /* MMDFONLY */
254 p = q = bbskip (p, COLON);
255 p = bb->bb_file = bbskip (p, COLON);
256 bb->bb_archive = bb->bb_info = bb->bb_map = "";
257 p = bb->bb_passwd = bbskip (p, COLON);
258 p = r = bbskip (p, COLON);
259 p = bb->bb_addr = bbskip (p, COLON);
260 p = bb->bb_request = bbskip (p, COLON);
261 p = bb->bb_relay = bbskip (p, COLON);
262 p = d = bbskip (p, COLON);
263 p = f = bbskip (p, COLON);
266 s = bb->bb_aka = BBAkas;
269 q = bbskip (q, COMMA);
273 s = bb->bb_leader = BBLeaders;
275 if (!(BBflags & SB_FAST)) {
283 r = bbskip (r, COMMA);
288 s = bb->bb_dist = BBDists;
291 d = bbskip (d, COMMA);
296 sscanf (f, "%o", &bb->bb_flags);
298 bb->bb_flags = BB_NULL;
299 bb->bb_count = bb->bb_maxima = 0;
301 bb->bb_next = bb->bb_link = bb->bb_chain = NULL;
305 * Only do a BBread on bboards that the user has expressed an
306 * interest in, if we were called by bbc.
309 register char **ap, *cp;
315 for (bbp = 0; cp = bbs[bbp]; bbp++) {
316 if (!strcmp(bb->bb_name, cp)) {
320 for (ap = bb->bb_aka; *ap; ap++)
321 if (!strcmp(*ap, cp)) {
338 getbbnam (char *name)
340 register struct bboard *b = NULL;
342 if (!setbbent (SB_NULL))
345 while ((b = getbbent ()) && strcmp (name, b->bb_name))
361 register struct bboard *b = NULL;
363 if (!setbbent (SB_NULL))
366 while ((b = getbbent ()) != NULL)
367 for (ap = b->bb_aka; *ap; ap++)
368 if (strcmp (aka, *ap) == 0)
385 register char *cp, *dp, *p, *r;
387 static char line[BUFSIZ];
388 register FILE * info;
390 if (BBflags & SB_FAST)
393 p = strchr(bb->bb_request, '@');
394 r = strchr(bb->bb_addr, '@');
397 if (*bb->bb_request == '-') {
398 if (p == NULL && r && *r == '@')
399 snprintf (BBRequest, sizeof(BBRequest), "%s%s%s", bb->bb_name, bb->bb_request, r);
401 snprintf (BBRequest, sizeof(BBRequest), "%s%s", bb->bb_name, bb->bb_request);
404 if (p == NULL && r && *r == '@' && *bb->bb_request)
405 snprintf (BBRequest, sizeof(BBRequest), "%s%s", bb->bb_request, r);
408 bb->bb_request = BBRequest;
410 if (*bb->bb_request == 0)
411 bb->bb_request = *bb->bb_addr ? bb->bb_addr
414 if (*bb->bb_addr == '@') {
415 snprintf (BBAddr, sizeof(BBAddr), "%s%s", bb->bb_name, bb->bb_addr);
416 bb->bb_addr = BBAddr;
419 if (*bb->bb_addr == 0)
420 bb->bb_addr = bb->bb_name;
422 if (*bb->bb_file == 0)
424 if (*bb->bb_file != '/') {
425 snprintf (BBFile, sizeof(BBFile), "%s/%s", BBDir, bb->bb_file);
426 bb->bb_file = BBFile;
429 if ((cp = strrchr(bb->bb_file, '/')) == NULL || *++cp == 0) {
433 snprintf (prf, sizeof(prf), "%.*s", cp - bb->bb_file, bb->bb_file);
435 if ((dp = strchr(cp, '.')) == NULL)
436 dp = cp + strlen (cp);
438 snprintf (BBArchive, sizeof(BBArchive), "%s%s/%s", prf, ARCHIVE, cp);
439 bb->bb_archive = BBArchive;
440 snprintf (BBInfo, sizeof(BBInfo), "%s.%.*s%s", prf, dp - cp, cp, CNTFILE);
441 bb->bb_info = BBInfo;
442 snprintf (BBMap, sizeof(BBMap), "%s.%.*s%s", prf, dp - cp, cp, MAPFILE);
445 if ((info = fopen (bb->bb_info, "r")) == NULL)
448 if (fgets (line, sizeof line, info) && (i = atoi (line)) > 0)
449 bb->bb_maxima = (unsigned) i;
450 if (!feof (info) && fgets (line, sizeof line, info)) {
451 strncpy (BBDate, line, sizeof(BBData));
452 if ((cp = strchr(BBDate, NEWLINE)))
454 bb->bb_date = BBDate;
462 ldrbb (struct bboard *b)
464 register char *p, **q, **r;
465 static uid_t uid = 0;
466 static gid_t gid = 0;
467 static char username[10] = "";
468 register struct passwd *pw;
469 register struct group *gr;
473 if (BBuid == -1 && !setbbaux (BBOARDS, BBDB))
476 if (username[0] == 0) {
477 if ((pw = getpwuid (uid = getuid ())) == NULL)
480 strncpy (username, pw->pw_name, sizeof(username));
489 if ((gr = getgrnam (++p)) == NULL)
491 if (gid == gr->gr_gid)
495 if (strcmp (username, p) == 0)
499 if (strcmp (username, p) == 0)
507 ldrchk (struct bboard *b)
512 if (*b->bb_passwd == 0)
515 if (strcmp (b->bb_passwd,
516 crypt (nmh_getpass ("Password: "), b->bb_passwd)) == 0)
519 fprintf (stderr, "Sorry\n");
525 getbbcpy (struct bboard *bp)
527 register char **p, **q;
528 register struct bboard *b;
533 b = (struct bboard *) malloc ((unsigned) sizeof *b);
537 b->bb_name = our_getcpy (bp->bb_name);
538 b->bb_file = our_getcpy (bp->bb_file);
539 b->bb_archive = our_getcpy (bp->bb_archive);
540 b->bb_info = our_getcpy (bp->bb_info);
541 b->bb_map = our_getcpy (bp->bb_map);
542 b->bb_passwd = our_getcpy (bp->bb_passwd);
543 b->bb_flags = bp->bb_flags;
544 b->bb_count = bp->bb_count;
545 b->bb_maxima = bp->bb_maxima;
546 b->bb_date = our_getcpy (bp->bb_date);
547 b->bb_addr = our_getcpy (bp->bb_addr);
548 b->bb_request = our_getcpy (bp->bb_request);
549 b->bb_relay = our_getcpy (bp->bb_relay);
551 for (p = bp->bb_aka; *p; p++)
554 q = (char **) calloc ((unsigned) (p - bp->bb_aka + 1), sizeof *q);
557 for (p = bp->bb_aka; *p; *q++ = our_getcpy (*p++))
561 for (p = bp->bb_leader; *p; p++)
564 q = (char **) calloc ((unsigned) (p - bp->bb_leader + 1), sizeof *q);
567 for (p = bp->bb_leader; *p; *q++ = our_getcpy (*p++))
571 for (p = bp->bb_dist; *p; p++)
574 q = (char **) calloc ((unsigned) (p - bp->bb_dist + 1), sizeof *q);
577 for (p = bp->bb_dist; *p; *q++ = our_getcpy (*p++))
581 b->bb_next = bp->bb_next;
582 b->bb_link = bp->bb_link;
583 b->bb_chain = bp->bb_chain;
590 getbbdist (struct bboard *bb, int (*action)())
596 for (dp = bb->bb_dist; *dp; dp++)
597 if ((result = getbbitem (bb, *dp, action)))
606 return (BBErrors[0] ? BBErrors : NULL);
611 getbbitem (struct bboard *bb, char *item, int (*action)())
614 register char *cp, *dp, *hp, *np;
630 if ((cp = strrchr(bb->bb_file, '/')) == NULL || *++cp == 0) {
634 snprintf (prf, sizeof(prf), "%.*s", cp - bb->bb_file, bb->bb_file);
636 if ((dp = strchr(cp, '.')) == NULL)
637 dp = cp + strlen (cp);
638 snprintf (file, sizeof(file), "%s.%.*s%s", prf, dp - cp, cp, DSTFILE);
643 snprintf (file, sizeof(file), "%s/%s", BBDir, item);
648 if ((fp = fopen (hp, "r")) == NULL)
649 return bblose ("unable to read file %s", hp);
650 while (fgets (buffer, sizeof buffer, fp)) {
651 if ((np = strchr(buffer, '\n')))
653 if ((result = getbbitem (bb, buffer, action))) {
655 bblose ("error with file %s, item %s", hp, buffer);
663 if ((hp = strrchr(item, '@'))) {
665 strncpy (mbox, item, sizeof(mbox));
666 strncpy (host, hp, sizeof(host));
670 snprintf (mbox, sizeof(mbox), "%s%s", DISTADR, bb->bb_name);
671 strncpy (host, item, sizeof(host));
673 if ((result = (*action) (mbox, host)))
674 bblose ("action (%s, %s) returned 0%o", mbox, host, result);
681 bblose (char *fmt, ...)
686 if (BBErrors[0] == 0)
687 vsnprintf (BBErrors, sizeof(BBErrors), fmt, ap);
695 make_lower (char *s1, char *s2)
701 *s1++ = isupper (*s2) ? tolower (*s2) : *s2;
707 bbskip (char *p, char c)
712 while (*p && *p != c)
730 len = strlen (s) + 1;
731 if ((p = malloc (len)))