1: /* aliasbr.c - new aliasing mechanism */ 2: 3: #include "../h/mh.h" 4: #include "../h/aliasbr.h" 5: #include <ctype.h> 6: #include <grp.h> 7: #include <pwd.h> 8: #include <stdio.h> 9: 10: 11: static int akvis; 12: static char *akerrst; 13: 14: struct aka *akahead = NULL; 15: struct aka *akatail = NULL; 16: 17: struct home *homehead = NULL; 18: struct home *hometail = NULL; 19: 20: char *scanp (), *getp (), *seekp (), *akval (), *getalias (); 21: struct aka *akalloc (); 22: struct home *hmalloc (); 23: 24: 25: struct passwd *getpwent (); 26: struct group *getgrnam (), *getgrgid (); 27: 28: /* */ 29: 30: char *akvalue (s) 31: register char *s; 32: { 33: register char *v; 34: 35: if (akahead == NULL) 36: (void) alias (AliasFile); 37: 38: akvis = -1; 39: v = akval (akahead, s); 40: if (akvis == -1) 41: akvis = 0; 42: return v; 43: } 44: 45: 46: int akvisible () { 47: return akvis; 48: } 49: 50: /* */ 51: 52: char *akresult (ak) 53: register struct aka *ak; 54: { 55: register char *cp = NULL, 56: *dp, 57: *pp; 58: register struct adr *ad; 59: 60: for (ad = ak -> ak_addr; ad; ad = ad -> ad_next) { 61: pp = ad -> ad_local ? akval (ak -> ak_next, ad -> ad_text) 62: : getcpy (ad -> ad_text); 63: 64: if (dp = cp) { 65: cp = concat (cp, ",", pp, NULLCP); 66: free (dp); 67: free (pp); 68: } 69: else 70: cp = pp; 71: } 72: 73: if (akvis == -1) 74: akvis = ak -> ak_visible; 75: return cp; 76: } 77: 78: 79: static char *akval (ak, s) 80: register struct aka *ak; 81: register char *s; 82: { 83: for (; ak; ak = ak -> ak_next) 84: if (aleq (s, ak -> ak_name)) 85: return akresult (ak); 86: 87: return getcpy (s); 88: } 89: 90: 91: static int aleq (string, aliasent) 92: register char *string, 93: *aliasent; 94: { 95: register char c; 96: 97: while (c = *string++) 98: if (*aliasent == '*') 99: return 1; 100: else 101: if ((c | 040) != (*aliasent | 040)) 102: return 0; 103: else 104: aliasent++; 105: 106: return (*aliasent == NULL || *aliasent == '*'); 107: } 108: 109: /* */ 110: 111: int alias (file) 112: register char *file; 113: { 114: int i; 115: register char *bp, 116: *cp, 117: *pp; 118: char lc, 119: *ap; 120: register struct aka *ak = NULL; 121: register FILE *fp; 122: 123: if (*file != '/' && *file != '.') 124: file = libpath (file); 125: if ((fp = fopen (file, "r")) == NULL) { 126: akerrst = file; 127: return AK_NOFILE; 128: } 129: 130: while (vfgets (fp, &ap) == OK) { 131: bp = ap; 132: switch (*(pp = scanp (bp))) { 133: case '<': /* recurse a level */ 134: if (!*(cp = getp (pp + 1))) { 135: akerrst = "'<' without alias-file"; 136: (void) fclose (fp); 137: return AK_ERROR; 138: } 139: if ((i = alias (cp) != AK_OK)) { 140: (void) fclose (fp); 141: return i; 142: } 143: 144: case ':': /* comment */ 145: case ';': 146: case NULL: 147: continue; 148: } 149: 150: akerrst = bp; 151: if (!*(cp = seekp (pp, &lc, &ap))) { 152: (void) fclose (fp); 153: return AK_ERROR; 154: } 155: if (!(ak = akalloc (cp))) { 156: (void) fclose (fp); 157: return AK_LIMIT; 158: } 159: switch (lc) { 160: case ':': 161: ak -> ak_visible = 0; 162: break; 163: 164: case ';': 165: ak -> ak_visible = 1; 166: break; 167: 168: default: 169: (void) fclose (fp); 170: return AK_ERROR; 171: } 172: 173: switch (*(pp = scanp (ap))) { 174: case NULL: /* EOL */ 175: (void) fclose (fp); 176: return AK_ERROR; 177: 178: case '<': /* read values from file */ 179: if (!*(cp = getp (pp + 1))) { 180: (void) fclose (fp); 181: return AK_ERROR; 182: } 183: if (!addfile (ak, cp)) { 184: (void) fclose (fp); 185: return AK_NOFILE; 186: } 187: break; 188: 189: case '=': /* UNIX group */ 190: if (!*(cp = getp (pp + 1))) { 191: (void) fclose (fp); 192: return AK_ERROR; 193: } 194: if (!addgroup (ak, cp)) { 195: (void) fclose (fp); 196: return AK_NOGROUP; 197: } 198: break; 199: 200: case '+': /* UNIX group members */ 201: if (!*(cp = getp (pp + 1))) { 202: (void) fclose (fp); 203: return AK_ERROR; 204: } 205: if (!addmember (ak, cp)) { 206: (void) fclose (fp); 207: return AK_NOGROUP; 208: } 209: break; 210: 211: case '*': /* Everyone */ 212: (void) addall (ak); 213: break; 214: 215: default: /* list */ 216: while (cp = getalias (pp)) 217: add_aka (ak, cp); 218: break; 219: } 220: } 221: 222: (void) fclose (fp); 223: return AK_OK; 224: } 225: 226: /* */ 227: 228: char *akerror (i) 229: int i; 230: { 231: static char buffer[BUFSIZ]; 232: 233: switch (i) { 234: case AK_NOFILE: 235: (void) sprintf (buffer, "unable to read '%s'", akerrst); 236: break; 237: 238: case AK_ERROR: 239: (void) sprintf (buffer, "error in line '%s'", akerrst); 240: break; 241: 242: case AK_LIMIT: 243: (void) sprintf (buffer, "out of memory while on '%s'", akerrst); 244: break; 245: 246: case AK_NOGROUP: 247: (void) sprintf (buffer, "no such group as '%s'", akerrst); 248: break; 249: 250: default: 251: (void) sprintf (buffer, "unknown error (%d)", i); 252: break; 253: } 254: 255: return buffer; 256: } 257: 258: /* */ 259: 260: static char *scanp (p) 261: register char *p; 262: { 263: while (isspace (*p)) 264: p++; 265: return p; 266: } 267: 268: 269: static char *getp (p) 270: register char *p; 271: { 272: register char *cp = scanp (p); 273: 274: p = cp; 275: while (!isspace (*cp) && *cp) 276: cp++; 277: *cp = NULL; 278: 279: return p; 280: } 281: 282: 283: static char *seekp (p, c, a) 284: register char *p, 285: *c, 286: **a; 287: { 288: register char *cp = scanp (p); 289: 290: p = cp; 291: while (!isspace (*cp) && *cp && *cp != ':' && *cp != ';') 292: cp++; 293: *c = *cp; 294: *cp++ = NULL; 295: *a = cp; 296: 297: return p; 298: } 299: 300: /* */ 301: 302: static int addfile (ak, file) 303: register struct aka *ak; 304: register char *file; 305: { 306: register char *cp; 307: char buffer[BUFSIZ]; 308: register FILE *fp; 309: 310: if ((fp = fopen (libpath (file), "r")) == NULL) { 311: akerrst = file; 312: return NULL; 313: } 314: 315: while (fgets (buffer, sizeof buffer, fp) != NULL) 316: while (cp = getalias (buffer)) 317: add_aka (ak, cp); 318: 319: (void) fclose (fp); 320: return 1; 321: } 322: 323: /* */ 324: 325: static int addgroup (ak, grp) 326: register struct aka *ak; 327: register char *grp; 328: { 329: register char *gp; 330: register struct group *gr = getgrnam (grp); 331: register struct home *hm = NULL; 332: 333: if (!gr) 334: gr = getgrgid (atoi (grp)); 335: if (!gr) { 336: akerrst = grp; 337: return NULL; 338: } 339: 340: if (homehead == NULL) 341: init_pw (); 342: 343: while (gp = *gr -> gr_mem++) 344: for (hm = homehead; hm; hm = hm -> h_next) 345: if (!strcmp (hm -> h_name, gp)) { 346: add_aka (ak, hm -> h_name); 347: break; 348: } 349: 350: return 1; 351: } 352: 353: /* */ 354: 355: static int addmember (ak, grp) 356: register struct aka *ak; 357: register char *grp; 358: { 359: int gid; 360: register struct group *gr = getgrnam (grp); 361: register struct home *hm = NULL; 362: 363: if (gr) 364: gid = gr -> gr_gid; 365: else { 366: gid = atoi (grp); 367: gr = getgrgid (gid); 368: } 369: if (!gr) { 370: akerrst = grp; 371: return NULL; 372: } 373: 374: if (homehead == NULL) 375: init_pw (); 376: 377: for (hm = homehead; hm; hm = hm -> h_next) 378: if (hm -> h_gid == gid) 379: add_aka (ak, hm -> h_name); 380: 381: return 1; 382: } 383: 384: /* */ 385: 386: static int addall (ak) 387: register struct aka *ak; 388: { 389: int noshell = NoShell == NULLCP || *NoShell == NULL; 390: register struct home *hm; 391: 392: if (homehead == NULL) 393: init_pw (); 394: if (Everyone < 0) 395: Everyone = EVERYONE; 396: 397: for (hm = homehead; hm; hm = hm -> h_next) 398: if (hm -> h_uid > Everyone 399: && (noshell || strcmp (hm -> h_shell, NoShell))) 400: add_aka (ak, hm -> h_name); 401: 402: return homehead != NULL; 403: } 404: 405: /* */ 406: 407: static char *getalias (addrs) 408: register char *addrs; 409: { 410: register char *pp, 411: *qp; 412: static char *cp = NULL; 413: 414: if (cp == NULL) 415: cp = addrs; 416: else 417: if (*cp == NULL) 418: return (cp = NULL); 419: 420: for (pp = cp; isspace (*pp); pp++) 421: continue; 422: if (*pp == NULL) 423: return (cp = NULL); 424: for (qp = pp; *qp != NULL && *qp != ','; qp++) 425: continue; 426: if (*qp == ',') 427: *qp++ = NULL; 428: for (cp = qp, qp--; qp > pp; qp--) 429: if (*qp != NULL) 430: if (isspace (*qp)) 431: *qp = NULL; 432: else 433: break; 434: 435: return pp; 436: } 437: 438: /* */ 439: 440: static add_aka (ak, pp) 441: register struct aka *ak; 442: register char *pp; 443: { 444: register struct adr *ad, 445: *ld; 446: 447: for (ad = ak -> ak_addr, ld = NULL; ad; ld = ad, ad = ad -> ad_next) 448: if (!strcmp (pp, ad -> ad_text)) 449: return; 450: 451: ad = (struct adr *) malloc (sizeof *ad); 452: if (ad == NULL) 453: return; 454: ad -> ad_text = getcpy (pp); 455: ad -> ad_local = index (pp, '@') == NULL && index (pp, '!') == NULL; 456: ad -> ad_next = NULL; 457: if (ak -> ak_addr) 458: ld -> ad_next = ad; 459: else 460: ak -> ak_addr = ad; 461: } 462: 463: 464: init_pw () { 465: register struct passwd *pw; 466: 467: (void) setpwent (); 468: 469: while (pw = getpwent ()) 470: if (!hmalloc (pw)) 471: break; 472: 473: (void) endpwent (); 474: } 475: 476: /* */ 477: 478: static struct aka *akalloc (id) 479: register char *id; 480: { 481: register struct aka *p = (struct aka *) malloc (sizeof *p); 482: 483: if (!p) 484: return NULL; 485: 486: p -> ak_name = getcpy (id); 487: p -> ak_visible = 0; 488: p -> ak_addr = NULL; 489: p -> ak_next = NULL; 490: if (akatail != NULL) 491: akatail -> ak_next = p; 492: if (akahead == NULL) 493: akahead = p; 494: akatail = p; 495: 496: return p; 497: } 498: 499: 500: static struct home *hmalloc (pw) 501: struct passwd *pw; 502: { 503: register struct home *p = (struct home *) malloc (sizeof *p); 504: 505: if (!p) 506: return NULL; 507: 508: p -> h_name = getcpy (pw -> pw_name); 509: p -> h_uid = pw -> pw_uid; 510: p -> h_gid = pw -> pw_gid; 511: p -> h_home = getcpy (pw -> pw_dir); 512: p -> h_shell = getcpy (pw -> pw_shell); 513: #ifdef BSD42 514: p -> h_ngrps = 0; 515: #endif BSD42 516: p -> h_next = NULL; 517: if (hometail != NULL) 518: hometail -> h_next = p; 519: if (homehead == NULL) 520: homehead = p; 521: hometail = p; 522: 523: return p; 524: } 525: 526: /* */ 527: 528: #ifndef MMDFMTS 529: struct home *seek_home (name) 530: register char *name; 531: { 532: register struct home *hp; 533: 534: if (homehead == NULL) 535: init_pw (); 536: 537: for (hp = homehead; hp; hp = hp -> h_next) 538: if (uleq (name, hp -> h_name)) 539: return hp; 540: 541: return NULL; 542: } 543: #endif MMDFMTS