1: # include <stdio.h> 2: # include <pwd.h> 3: # include "dlvrmail.h" 4: 5: /* 6: ** CONF.C -- Delivermail Configuration Tables. 7: ** 8: ** Defines the configuration of this installation. 9: ** 10: ** Compilation Flags: 11: ** HASARPA -- set if this machine has a connection to 12: ** the Arpanet. 13: ** HASUUCP -- set if this machine has a connection to 14: ** the UUCP network. 15: ** NETV6MAIL -- set if you want to use "v6mail" that 16: ** comes with the Berkeley network. Normally 17: ** /bin/mail will work fine, but around Berkeley 18: ** we use v6mail because it is a "fixed target". 19: ** V6 -- running on a version 6 system. This determines 20: ** whether to define certain routines between 21: ** the two systems. If you are running a funny 22: ** system, e.g., V6 with long tty names, this 23: ** should be checked carefully. 24: ** DUMBMAIL -- set if your /bin/mail doesn't have the 25: ** -d flag. 26: ** 27: ** Configuration Variables: 28: ** ArpaHost -- the arpanet name of the host through 29: ** which arpanet mail will be sent. 30: ** MyLocName -- the name of the host on a local network. 31: ** This is used to disambiguate the contents of 32: ** ArpaHost among many hosts who may be sharing 33: ** a gateway. 34: ** DaemonName -- the name of this agent for use in 35: ** error messages, typically "~MAILER~DAEMON~" 36: ** at this host on the local net. 37: ** ArpaLocal -- a list of local names for this host on 38: ** the arpanet. Only functional if HASARPA set. 39: ** UucpLocal -- ditto for the Arpanet. 40: ** BerkLocal -- ditto for the Berknet. 41: ** Mailer -- a table of mailers known to the system. 42: ** The fields are: 43: ** - the pathname of the mailer. 44: ** - a list of flags describing the properties 45: ** of this mailer: 46: ** M_FOPT -- if set, the mailer has a picky "-f" 47: ** option. In this mode, the mailer will 48: ** only accept the "-f" option if the 49: ** sender is actually "root", "network", 50: ** and possibly (but not necessarily) if 51: ** the -f argument matches the real sender. 52: ** The effect is that if the "-f" option 53: ** is given to delivermail then it will be 54: ** passed through (as arguments 1 & 2) to 55: ** the mailer. 56: ** M_ROPT -- identical to M_FOPT, except uses 57: ** -r instead. 58: ** M_QUIET -- if set, don't print a message if 59: ** the mailer returns bad status. 60: ** M_RESTR -- if set, this mailer is restricted 61: ** to use by "daemon"; otherwise, we do a 62: ** setuid(getuid()) before calling the 63: ** mailer. 64: ** M_HDR -- if set, the mailer wants us to 65: ** insert a UNIX "From" line before 66: ** outputing. 67: ** M_FHDR -- if set, the header that we 68: ** generate will be used literally, so 69: ** we must force it to be correct. The 70: ** effect is that we generate a header 71: ** even if one exists. 72: ** M_NOHOST -- if set, this mailer doesn't care 73: ** about the host part (e.g., the local 74: ** mailer). 75: ** M_STRIPQ -- if set, strip quote (`"') 76: ** characters out of parameters as you 77: ** transliterate them into the argument 78: ** vector. For example, the local mailer 79: ** is called directly, so these should be 80: ** stripped, but the program-mailer (i.e., 81: ** csh) should leave them in. 82: ** - an exit status to use as the code for the 83: ** error message print if the mailer returns 84: ** something we don't understand. 85: ** - A list of names that are to be considered 86: ** "local" (and hence are stripped off) for 87: ** this mailer. 88: ** - An argument vector to be passed to the 89: ** mailer with the following substitutions: 90: ** $f - the from person name. 91: ** $u - the target user name. 92: ** $h - the target user host. 93: ** $c - the hop count. 94: ** >>>>>>>>>> Entry zero must be for the local 95: ** >> NOTE >> mailer and entry one must be for 96: ** >>>>>>>>>> the shell. 97: ** ParseTab -- a table driving the parsing process. Each 98: ** entry contains: 99: ** - a character that will trigger this entry. 100: ** - an index into the Mailer table. 101: ** - a word of flags, described in dlvrmail.h. 102: ** - an argument. If we have P_MAP, it is the 103: ** character to turn the trigger character into. 104: ** If we have P_MOVE, it is the site to send it 105: ** to, using the mailer specified above. 106: ** This table will almost certainly have to be 107: ** changed on your site if you have anything more 108: ** than the UUCP net. 109: */ 110: 111: 112: 113: 114: static char SccsId[] = "@(#)conf.c 2.4 1/10/81"; 115: 116: 117: bool UseMsgId = FALSE; /* don't put message id's in anywhere */ 118: 119: # include <whoami.h> /* definitions of machine id's at berkeley */ 120: 121: # ifdef BERKELEY 122: 123: char *ArpaHost = "Berkeley"; /* host name of gateway on Arpanet */ 124: 125: # else BERKELEY 126: 127: char *ArpaHost = "[unknown]"; 128: char *MyLocName = sysname; 129: # define HASUUCP /* default to having UUCP net */ 130: char *UucpLocal[] = { sysname, NULL }; 131: 132: # endif BERKELEY 133: 134: 135: /* Specific Configurations for Berkeley Machines */ 136: 137: /* Berkeley people: mail changes to csvax:eric or they will be lost! */ 138: 139: # ifdef ING70 140: static char *BerkLocal[] = { "i", "ingres", "ing70", NULL }; 141: char *ArpaLocal = { "berkeley", "ucb", NULL }; 142: char *MyLocName = "Ing70"; 143: char *DaemonName = "Ing70:~MAILER~DAEMON~"; 144: # define HASARPA 145: # define V6 146: # endif ING70 147: 148: # ifdef INGVAX 149: static char *BerkLocal[] = { "j", "ingvax", NULL }; 150: char *MyLocName = "IngVax"; 151: char *DaemonName = "IngVax:~MAILER~DAEMON~"; 152: # endif INGVAX 153: 154: # ifdef CSVAX 155: static char *BerkLocal[] = { "v", "csvax", "vax", NULL }; 156: static char *UucpLocal[] = { "ucbvax", "ernie", NULL }; 157: char *MyLocName = "CSVAX"; 158: char *DaemonName = "CSVAX:~MAILER~DAEMON~"; 159: # define HASUUCP 160: # define NETV6MAIL 161: # endif CSVAX 162: 163: # ifdef CORY 164: static char *BerkLocal[] = { "y", "cory", NULL }; 165: char *MyLocName = "Cory"; 166: char *DaemonName = "Cory:~MAILER~DAEMON~"; 167: # endif CORY 168: 169: # ifdef IMAGE 170: /* untested */ 171: static char *BerkLocal[] = { "m", "image", NULL }; 172: char *MyLocName = "Image"; 173: char *DaemonName = "Image:~MAILER~DAEMON~"; 174: # define V6 175: # endif IMAGE 176: 177: # ifdef ESVAX 178: static char *BerkLocal[] = { "o", "esvax", NULL }; 179: char *MyLocName = "ESVAX"; 180: char *DaemonName = "ESVAX:~MAILER~DAEMON~"; 181: # endif ESVAX 182: 183: # ifdef EECS40 184: /* untested */ 185: static char *BerkLocal[] = { "z", "eecs40", NULL }; 186: char *MyLocName = "EECS40"; 187: char *DaemonName = "EECS40:~MAILER~DAEMON~"; 188: # define V6 189: # endif EECS40 190: 191: 192: # ifndef HASARPA 193: # define ArpaLocal NULL 194: # endif HASARPA 195: 196: # ifndef HASUUCP 197: # define UucpLocal NULL 198: # endif HASUUCP 199: 200: 201: struct mailer Mailer[] = 202: { 203: /* local mail -- must be #0 */ 204: { 205: # ifdef NETV6MAIL 206: "/usr/net/bin/v6mail", 207: # else 208: "/bin/mail", 209: # endif 210: M_ROPT|M_NOHOST|M_STRIPQ, EX_NOUSER, NULL, 211: { "...local%mail", "-d", "$u", NULL } 212: }, 213: /* pipes through programs -- must be #1 */ 214: { 215: "/bin/csh", 216: M_HDR|M_FHDR|M_NOHOST, EX_UNAVAILABLE, NULL, 217: { "...prog%mail", "-fc", "$u", NULL } 218: }, 219: /* local berkeley mail */ 220: { 221: "/usr/net/bin/sendberkmail", 222: M_FOPT|M_HDR|M_STRIPQ, EX_UNAVAILABLE, BerkLocal, 223: { "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL } 224: }, 225: /* arpanet mail */ 226: { 227: "/usr/lib/mailers/arpa", 228: M_STRIPQ, 0, ArpaLocal, 229: { "...arpa%mail", "$f", "$h", "$u", NULL } 230: }, 231: /* uucp mail (cheat & use Bell's v7 mail) */ 232: { 233: "/bin/mail", 234: M_ROPT|M_STRIPQ, EX_NOUSER, UucpLocal, 235: # ifdef DUMBMAIL 236: { "...uucp%mail", "$h!$u", NULL } 237: # else 238: { "...uucp%mail", "-d", "$h!$u", NULL } 239: # endif DUMBMAIL 240: }, 241: }; 242: 243: # define M_LOCAL 0 244: # define M_BERK 2 245: # define M_ARPA 3 246: # define M_UUCP 4 247: 248: 249: 250: # ifdef BERKELEY 251: struct parsetab ParseTab[] = 252: { 253: ':', M_BERK, P_ONE, NULL, 254: # ifdef HASARPA 255: '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 256: # else 257: '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 258: # endif HASARPA 259: '^', -1, P_MAP, "!", 260: # ifdef HASUUCP 261: '!', M_UUCP, 0, NULL, 262: # else 263: '!', M_BERK, P_MOVE, "csvax", 264: # endif HASUUCP 265: '.', -1, P_MAP|P_ONE, ":", 266: '\0', M_LOCAL, P_MOVE, "", 267: }; 268: # else BERKELEY 269: struct parsetab ParseTab[] = 270: { 271: # ifdef HASARPA 272: '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 273: # endif HASARPA 274: # ifdef HASUUCP 275: '^', -1, P_MAP, "!", 276: '!', M_UUCP, 0, NULL, 277: # endif HASUUCP 278: '\0', M_LOCAL, P_MOVE, "", 279: }; 280: # endif BERKELEY 281: /* 282: ** GETNAME -- Get the current users login name. 283: ** 284: ** This is in config.c because it is somewhat machine dependent. 285: ** Examine it carefully for your installation. 286: ** 287: ** Algorithm: 288: ** See if the person is logged in. If so, return 289: ** the name s/he is logged in as. 290: ** Look up the user id in /etc/passwd. If found, 291: ** return that name. 292: ** Return NULL. 293: ** 294: ** Parameters: 295: ** none 296: ** 297: ** Returns: 298: ** The login name of this user. 299: ** NULL if this person is noone. 300: ** 301: ** Side Effects: 302: ** none 303: ** 304: ** Called By: 305: ** main 306: */ 307: 308: char * 309: getname() 310: { 311: register char *p; 312: register struct passwd *w; 313: extern struct passwd *getpwuid(); 314: static char namebuf[9]; 315: 316: # ifdef V6 317: w = getpwuid(getuid() & 0377); 318: # else 319: w = getpwuid(getuid()); 320: # endif V6 321: if (w != NULL) 322: { 323: strcpy(namebuf, w->pw_name); 324: return (namebuf); 325: } 326: return (NULL); 327: } 328: 329: # ifdef V6 330: /* 331: ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 332: ** 333: ** Returns the pathname of the user's tty. Returns NULL if 334: ** the user is not logged in or if s/he has write permission 335: ** denied. 336: ** 337: ** Parameters: 338: ** none 339: ** 340: ** Returns: 341: ** pathname of the user's tty. 342: ** NULL if not logged in or write permission denied. 343: ** 344: ** Side Effects: 345: ** none. 346: ** 347: ** WARNING: 348: ** Return value is in a local buffer. 349: ** 350: ** Called By: 351: ** savemail 352: */ 353: 354: # include <sys/types.h> 355: # include <sys/stat.h> 356: 357: char * 358: ttypath() 359: { 360: struct stat stbuf; 361: register int i; 362: static char pathn[] = "/dev/ttyx"; 363: extern int errno; 364: 365: /* compute the pathname of the controlling tty */ 366: if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 367: { 368: errno = 0; 369: return (NULL); 370: } 371: pathn[8] = i; 372: 373: /* see if we have write permission */ 374: if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 375: { 376: errno = 0; 377: return (NULL); 378: } 379: 380: /* see if the user is logged in */ 381: if (getlogin() == NULL) 382: return (NULL); 383: 384: /* looks good */ 385: return (pathn); 386: } 387: /* 388: ** FDOPEN -- Open a stdio file given an open file descriptor. 389: ** 390: ** This is included here because it is standard in v7, but we 391: ** need it in v6. 392: ** 393: ** Algorithm: 394: ** Open /dev/null to create a descriptor. 395: ** Close that descriptor. 396: ** Copy the existing fd into the descriptor. 397: ** 398: ** Parameters: 399: ** fd -- the open file descriptor. 400: ** type -- "r", "w", or whatever. 401: ** 402: ** Returns: 403: ** The file descriptor it creates. 404: ** 405: ** Side Effects: 406: ** none 407: ** 408: ** Called By: 409: ** deliver 410: ** 411: ** Notes: 412: ** The mode of fd must match "type". 413: */ 414: 415: FILE * 416: fdopen(fd, type) 417: int fd; 418: char *type; 419: { 420: register FILE *f; 421: 422: f = fopen("/dev/null", type); 423: close(fileno(f)); 424: fileno(f) = fd; 425: return (f); 426: } 427: /* 428: ** INDEX -- Return pointer to character in string 429: ** 430: ** For V7 compatibility. 431: ** 432: ** Parameters: 433: ** s -- a string to scan. 434: ** c -- a character to look for. 435: ** 436: ** Returns: 437: ** If c is in s, returns the address of the first 438: ** instance of c in s. 439: ** NULL if c is not in s. 440: ** 441: ** Side Effects: 442: ** none. 443: */ 444: 445: index(s, c) 446: register char *s; 447: register char c; 448: { 449: while (*s != '\0') 450: { 451: if (*s++ == c) 452: return (--s); 453: } 454: return (NULL); 455: } 456: # endif V6 457: 458: # ifndef V6 459: /* 460: ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 461: ** 462: ** Returns the pathname of the user's tty. Returns NULL if 463: ** the user is not logged in or if s/he has write permission 464: ** denied. 465: ** 466: ** Parameters: 467: ** none 468: ** 469: ** Returns: 470: ** pathname of the user's tty. 471: ** NULL if not logged in or write permission denied. 472: ** 473: ** Side Effects: 474: ** none. 475: ** 476: ** WARNING: 477: ** Return value is in a local buffer. 478: ** 479: ** Called By: 480: ** savemail 481: */ 482: 483: # include <sys/types.h> 484: # include <sys/stat.h> 485: 486: char * 487: ttypath() 488: { 489: struct stat stbuf; 490: register char *pathn; 491: extern int errno; 492: extern char *ttyname(); 493: 494: /* compute the pathname of the controlling tty */ 495: if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 496: { 497: errno = 0; 498: return (NULL); 499: } 500: 501: /* see if we have write permission */ 502: if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 503: { 504: errno = 0; 505: return (NULL); 506: } 507: 508: /* see if the user is logged in */ 509: if (getlogin() == NULL) 510: return (NULL); 511: 512: /* looks good */ 513: return (pathn); 514: } 515: # endif V6