1: /* mts.c - definitions for the mail transport system */ 2: 3: /* LINTLIBRARY */ 4: 5: #undef NETWORK 6: #if defined(BSD41A) || defined(BSD42) 7: #define NETWORK 8: #endif not (defined(BSD41A) || defined(BSD42)) 9: 10: #include "../h/strings.h" 11: #include <ctype.h> 12: #include <stdio.h> 13: #include "mts.h" 14: #ifdef NETWORK 15: #ifdef BSD42 16: #include <netdb.h> 17: #endif BSD42 18: #else not NETWORK 19: #ifndef SYS5 20: #include <whoami.h> 21: #else SYS5 22: #include <sys/utsname.h> 23: #endif SYS5 24: #endif not NETWORK 25: #include <pwd.h> 26: 27: 28: #define NOTOK (-1) 29: #define OK 0 30: 31: #define NULLCP ((char *) 0) 32: 33: extern int errno; 34: 35: char *tailor_value (); 36: 37: 38: #ifdef SYS5 39: #define index strchr 40: #define rindex strrchr 41: #endif SYS5 42: 43: char *index (), *malloc (), *mktemp (), *rindex (), *strcpy (); 44: 45: struct passwd *getpwuid (); 46: 47: /* */ 48: 49: /* 50: *mmdfldir and *uucpldir are the maildrop directories. If maildrops 51: are kept in the user's home directory, then these should be empty 52: strings. In this case, the appropriate ...lfil array should contain 53: the name of the file in the user's home directory. Usually, this is 54: something like ".mail". 55: */ 56: 57: static char *mtstailor = "/usr/new/lib/mh/mtstailor"; 58: 59: static char *localname = ""; 60: static char *systemname = ""; 61: #ifdef MF 62: static char *UUCPchan = ""; 63: #endif MF 64: char *mmdfldir = "/usr/spool/mail"; 65: char *mmdflfil = ""; 66: char *uucpldir = "/usr/spool/mail"; 67: char *uucplfil = ""; 68: 69: 70: char *mmdlm1 = "\001\001\001\001\n"; 71: char *mmdlm2 = "\001\001\001\001\n"; 72: 73: 74: static int MMailids = 0; 75: static char *mmailid = "0"; 76: 77: 78: #ifdef MF 79: char *umincproc = "/usr/new/lib/mh/uminc"; 80: #else MF 81: char *umincproc = NULL; 82: #endif MF 83: 84: 85: int lockstyle = LOK_UNIX; 86: static char *lkstyle = "0"; 87: char *lockldir = ""; 88: 89: /* */ 90: 91: /* MTS specific variables */ 92: 93: #ifdef MHMTS 94: char *Mailqdir = "/usr/spool/netmail"; 95: char *TMailqdir = "/usr/tmp"; 96: int Syscpy = 1; 97: static char *syscpy = "1"; 98: char *Overseer = "root"; 99: char *Mailer = "root"; 100: char *Fromtmp = "/tmp/rml.f.XXXXXX"; 101: char *Msgtmp = "/tmp/rml.m.XXXXXX"; 102: char *Errtmp = "/tmp/rml.e.XXXXXX"; 103: int Tmpmode = 0600; 104: static char *tmpmode = "0600"; 105: char *Okhosts = "/usr/new/lib/mh/Rmail.OkHosts"; 106: char *Okdests = "/usr/new/lib/mh/Rmail.OkDests"; 107: #endif MHMTS 108: 109: #ifdef MMDFMTS 110: #endif MMDFMTS 111: 112: #ifdef SENDMTS 113: char *hostable = "/usr/new/lib/mh/hosts"; 114: char *sendmail = "/usr/lib/sendmail"; 115: #endif SENDMTS 116: 117: 118: /* SMTP/POP stuff */ 119: 120: char *servers = "localhost \01localnet"; 121: char *pophost = ""; 122: 123: 124: /* BBoards-specific variables */ 125: 126: char *bb_domain = ""; 127: 128: 129: /* POP BBoards-specific variables */ 130: 131: #ifdef BPOP 132: char *popbbhost = ""; 133: char *popbbuser = ""; 134: char *popbblist = "/usr/new/lib/mh/hosts.popbb"; 135: #endif BPOP 136: 137: 138: /* MailDelivery */ 139: 140: char *maildelivery = "/usr/new/lib/mh/maildelivery"; 141: 142: 143: /* Aliasing Facility (doesn't belong here) */ 144: 145: int Everyone = NOTOK; 146: static char *everyone = "-1"; 147: char *NoShell = ""; 148: 149: /* */ 150: 151: /* customize the MTS settings for MH by reading /usr/new/lib/mh/mtstailor */ 152: 153: static struct bind { 154: char *keyword; 155: char **value; 156: } binds[] = { 157: "localname", &localname, 158: "systemname", &systemname, 159: #ifdef MF 160: "uucpchan", &UUCPchan, 161: #endif MF 162: "mmdfldir", &mmdfldir, 163: "mmdflfil", &mmdflfil, 164: "uucpldir", &uucpldir, 165: "uucplfil", &uucplfil, 166: "mmdelim1", &mmdlm1, 167: "mmdelim2", &mmdlm2, 168: "mmailid", &mmailid, 169: "umincproc", &umincproc, 170: "lockstyle", &lkstyle, 171: "lockldir", &lockldir, 172: 173: #ifdef MHMTS 174: "mailqdir", &Mailqdir, 175: "tmailqdir", &TMailqdir, 176: "syscpy", &syscpy, 177: "overseer", &Overseer, 178: "mailer", &Mailer, 179: "fromtmp", &Fromtmp, 180: "msgtmp", &Msgtmp, 181: "errtmp", &Errtmp, 182: "tmpmode", &tmpmode, 183: "okhosts", &Okhosts, 184: "okdests", &Okdests, 185: #endif MHMTS 186: 187: #ifdef MMDFMTS 188: #endif MMDFMTS 189: 190: #ifdef SENDMTS 191: "hostable", &hostable, 192: "sendmail", &sendmail, 193: #endif SENDMTS 194: 195: "servers", &servers, 196: "pophost", &pophost, 197: 198: "bbdomain", &bb_domain, 199: 200: #ifdef BPOP 201: "popbbhost", &popbbhost, 202: "popbbuser", &popbbuser, 203: "popbblist", &popbblist, 204: #endif BPOP 205: 206: "maildelivery", &maildelivery, 207: 208: "everyone", &everyone, 209: "noshell", &NoShell, 210: 211: NULL 212: }; 213: 214: /* */ 215: 216: /* I'd like to use m_getfld() here, but not all programs loading mts.o may be 217: MH-style programs... */ 218: 219: /* ARGSUSED */ 220: 221: mts_init (name) 222: char *name; 223: { 224: register char *bp, 225: *cp; 226: char buffer[BUFSIZ]; 227: register struct bind *b; 228: register FILE *fp; 229: static int inited = 0; 230: 231: if (inited++ || (fp = fopen (mtstailor, "r")) == NULL) 232: return; 233: 234: while (fgets (buffer, sizeof buffer, fp)) { 235: if ((cp = index (buffer, '\n')) == NULL) 236: break; 237: *cp = NULL; 238: if (*buffer == '#' || *buffer == NULL) 239: continue; 240: if ((bp = index (buffer, ':')) == NULL) 241: break; 242: *bp++ = NULL; 243: while (isspace (*bp)) 244: *bp++ = NULL; 245: 246: for (b = binds; b -> keyword; b++) 247: if (strcmp (buffer, b -> keyword) == 0) 248: break; 249: if (b -> keyword && (cp = tailor_value (bp))) 250: *b -> value = cp; 251: } 252: 253: (void) fclose (fp); 254: 255: MMailids = atoi (mmailid); 256: if ((lockstyle = atoi (lkstyle)) < LOK_UNIX || lockstyle > LOK_MMDF) 257: lockstyle = LOK_UNIX; 258: #ifdef MHMTS 259: Syscpy = atoi (syscpy); 260: (void) sscanf (tmpmode, "0%o", &Tmpmode); 261: #endif MHMTS 262: Everyone = atoi (everyone); 263: } 264: 265: /* */ 266: 267: #define QUOTE '\\' 268: #define grot(x) case 'x': *bp = '\x'; break 269: 270: static char *tailor_value (s) 271: register char *s; 272: { 273: register int i, 274: r; 275: register char *bp; 276: char buffer[BUFSIZ]; 277: 278: for (bp = buffer; *s; bp++, s++) 279: if (*s != QUOTE) 280: *bp = *s; 281: else 282: switch (*++s) { 283: grot (b); 284: grot (f); 285: grot (n); 286: grot (t); 287: 288: case NULL: s--; 289: case QUOTE: 290: *bp = QUOTE; 291: break; 292: 293: default: 294: if (!isdigit (*s)) { 295: *bp++ = QUOTE; 296: *bp = *s; 297: } 298: r = *s != '0' ? 10 : 8; 299: for (i = 0; isdigit (*s); s++) 300: i = i * r + *s - '0'; 301: s--; 302: *bp = toascii (i); 303: break; 304: } 305: *bp = NULL; 306: 307: bp = malloc ((unsigned) (strlen (buffer) + 1)); 308: if (bp != NULL) 309: (void) strcpy (bp, buffer); 310: 311: return bp; 312: } 313: 314: /* */ 315: 316: char *LocalName () { 317: #ifdef BSD41A 318: char *myname; 319: #endif BSD41A 320: #ifdef BSD42 321: register struct hostent *hp; 322: #endif BSD42 323: #ifdef SYS5 324: struct utsname name; 325: #endif SYS5 326: static char buffer[BUFSIZ] = ""; 327: 328: if (buffer[0]) 329: return buffer; 330: 331: mts_init ("mts"); 332: if (*localname) 333: return strcpy (buffer, localname); 334: 335: #ifdef locname 336: (void) strcpy (buffer, locname); 337: #else not locname 338: #ifdef NETWORK 339: #ifdef BSD41A 340: myname = "myname"; 341: if (rhost (&myname) == -1) 342: (void) gethostname (buffer, sizeof buffer); 343: else { 344: (void) strcpy (buffer, myname); 345: free (myname); 346: } 347: #endif BSD41A 348: #ifdef BSD42 349: (void) gethostname (buffer, sizeof buffer); 350: sethostent (1); 351: if (hp = gethostbyname (buffer)) 352: (void) strcpy (buffer, hp -> h_name); 353: #endif BSD42 354: #else not NETWORK 355: #ifndef SYS5 356: (void) strcpy (buffer, SystemName ()); 357: #else SYS5 358: (void) uname (&name); 359: (void) strcpy (buffer, name.nodename); 360: #endif SYS5 361: #endif not NETWORK 362: #endif not locname 363: 364: return buffer; 365: } 366: 367: /* */ 368: 369: char *SystemName () { 370: #ifdef SYS5 371: struct utsname name; 372: #endif SYS5 373: static char buffer[BUFSIZ] = ""; 374: 375: if (buffer[0]) 376: return buffer; 377: 378: mts_init ("mts"); 379: if (*systemname) 380: return strcpy (buffer, systemname); 381: 382: #ifdef sysname 383: (void) strcpy (buffer, sysname); 384: #else sysname 385: #ifndef SYS5 386: (void) gethostname (buffer, sizeof buffer); 387: #else SYS5 388: (void) uname (&name); 389: (void) strcpy (buffer, name.nodename); 390: #endif SYS5 391: #endif sysname 392: 393: return buffer; 394: } 395: 396: /* */ 397: 398: char *UucpChan () { 399: #ifdef MF 400: static char buffer[BUFSIZ] = ""; 401: #endif MF 402: 403: #ifndef MF 404: return NULL; 405: #else MF 406: if (buffer[0]) 407: return buffer; 408: 409: mts_init ("mts"); 410: if (*UUCPchan) 411: return strcpy (buffer, UUCPchan); 412: 413: #ifdef uucpchan 414: (void) strcpy (buffer, uucpchan); 415: #else uucpchan 416: (void) strcpy (buffer, "uucp"); 417: #endif uucpchan 418: return buffer; 419: #endif MF 420: } 421: 422: /* */ 423: 424: #ifdef ALTOS 425: gethostname (name, len) 426: register char *name; 427: register int len; 428: { 429: register char *cp; 430: register FILE *fp; 431: 432: if (fp = fopen ("/etc/systemid", "r")) { 433: if (fgets (name, len, fp)) { 434: if (cp = index (name, '\n')) 435: *cp = NULL; 436: (void) fclose (fp); 437: return OK; 438: } 439: (void) fclose (fp); 440: } 441: (void) strncpy (name, "altos", len); 442: 443: return OK; 444: } 445: #endif ALTOS 446: 447: /* */ 448: 449: static char username[BUFSIZ] = ""; 450: static char fullname[BUFSIZ] = ""; 451: 452: 453: char *getusr () { 454: register char *cp, 455: *np; 456: register struct passwd *pw; 457: 458: if (username[0]) 459: return username; 460: 461: if ((pw = getpwuid (getuid ())) == NULL 462: || pw -> pw_name == NULL 463: || *pw -> pw_name == NULL) { 464: (void) strcpy (username, "intruder"); 465: (void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ()); 466: return username; 467: } 468: 469: if (MMailids) { 470: np = pw -> pw_gecos; 471: for (cp = fullname; *np && *np != '<'; *cp++ = *np++) 472: continue; 473: *cp = NULL; 474: if (*np) 475: np++; 476: for (cp = username; *np && *np != '>'; *cp++ = *np++) 477: continue; 478: *cp = NULL; 479: } 480: if (MMailids == 0 || *np == NULL) { 481: (void) strcpy (username, pw -> pw_name); 482: fullname[0] = NULL; 483: } 484: if ((cp = getenv ("SIGNATURE")) && *cp) 485: (void) strcpy (fullname, cp); 486: 487: return username; 488: } 489: 490: 491: char *getfullname () { 492: if (username[0] == NULL) 493: (void) getusr (); 494: 495: return fullname; 496: } 497: 498: /* */ 499: 500: #ifdef SYS5 501: #ifndef notdef /* Supposedly this works, I prefer the 502: recursive solution... */ 503: 504: #include <fcntl.h> 505: 506: int dup2 (d1, d2) 507: register int d1, 508: d2; 509: { 510: int d; 511: 512: if (d1 == d2) 513: return OK; 514: 515: (void) close (d2); 516: if ((d = fcntl (d1, F_DUPFD, d2)) == NOTOK) 517: return NOTOK; 518: if (d == d2) 519: return OK; 520: 521: errno = 0; 522: return NOTOK; 523: } 524: 525: #else notdef 526: int dup2 (d1, d2) 527: register int d1, 528: d2; 529: { 530: if (d1 == d2) 531: return OK; 532: 533: (void) close (d2); 534: return dup2aux (d1, d2); 535: } 536: 537: 538: static int dup2aux (d1, d2) 539: register int d1, 540: d2; 541: { 542: int d, 543: i, 544: eindex; 545: 546: if ((d = dup (d1)) == NOTOK) 547: return NOTOK; 548: if (d == d2) 549: return OK; 550: 551: i = dup2aux (d1, d2); 552: eindex = errno; 553: (void) close (d); 554: errno = eindex; 555: return i; 556: } 557: #endif notdef 558: #endif SYS5