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