1294Seric # include <stdio.h> 2294Seric # include <pwd.h> 3294Seric # include "dlvrmail.h" 4404Seric 5294Seric /* 6294Seric ** CONF.C -- Delivermail Configuration Tables. 7294Seric ** 8294Seric ** Defines the configuration of this installation. 9294Seric ** 101388Seric ** Compilation Flags: 111388Seric ** HASARPA -- set if this machine has a connection to 121388Seric ** the Arpanet. 131388Seric ** HASUUCP -- set if this machine has a connection to 141388Seric ** the UUCP network. 151388Seric ** NETV6MAIL -- set if you want to use "v6mail" that 161388Seric ** comes with the Berkeley network. Normally 171388Seric ** /bin/mail will work fine, but around Berkeley 181388Seric ** we use v6mail because it is a "fixed target". 191388Seric ** V6 -- running on a version 6 system. This determines 201388Seric ** whether to define certain routines between 211388Seric ** the two systems. If you are running a funny 221388Seric ** system, e.g., V6 with long tty names, this 231388Seric ** should be checked carefully. 241573Seric ** DUMBMAIL -- set if your /bin/mail doesn't have the 251573Seric ** -d flag. 26294Seric ** 271388Seric ** Configuration Variables: 281573Seric ** ArpaHost -- the arpanet name of the host through 291573Seric ** which arpanet mail will be sent. 301388Seric ** MyLocName -- the name of the host on a local network. 311388Seric ** This is used to disambiguate the contents of 321388Seric ** ArpaHost among many hosts who may be sharing 331388Seric ** a gateway. 341573Seric ** ArpaLocal -- a list of local names for this host on 351573Seric ** the arpanet. Only functional if HASARPA set. 361573Seric ** UucpLocal -- ditto for the Arpanet. 371573Seric ** BerkLocal -- ditto for the Berknet. 381388Seric ** Mailer -- a table of mailers known to the system. 391388Seric ** The fields are: 401388Seric ** - the pathname of the mailer. 411388Seric ** - a list of flags describing the properties 421388Seric ** of this mailer: 431388Seric ** M_FOPT -- if set, the mailer has a picky "-f" 441388Seric ** option. In this mode, the mailer will 451388Seric ** only accept the "-f" option if the 461388Seric ** sender is actually "root", "network", 471388Seric ** and possibly (but not necessarily) if 481388Seric ** the -f argument matches the real sender. 491388Seric ** The effect is that if the "-f" option 501388Seric ** is given to delivermail then it will be 511388Seric ** passed through (as arguments 1 & 2) to 521388Seric ** the mailer. 531388Seric ** M_ROPT -- identical to M_FOPT, except uses 541388Seric ** -r instead. 551388Seric ** M_QUIET -- if set, don't print a message if 561388Seric ** the mailer returns bad status. 571388Seric ** M_RESTR -- if set, this mailer is restricted 581388Seric ** to use by "daemon"; otherwise, we do a 591388Seric ** setuid(getuid()) before calling the 601388Seric ** mailer. 611388Seric ** M_HDR -- if set, the mailer wants us to 621388Seric ** insert a UNIX "From" line before 631388Seric ** outputing. 641388Seric ** M_NOHOST -- if set, this mailer doesn't care 651388Seric ** about the host part (e.g., the local 661388Seric ** mailer). 671388Seric ** M_STRIPQ -- if set, strip quote (`"') 681388Seric ** characters out of parameters as you 691388Seric ** transliterate them into the argument 701388Seric ** vector. For example, the local mailer 711388Seric ** is called directly, so these should be 721388Seric ** stripped, but the program-mailer (i.e., 731388Seric ** csh) should leave them in. 741388Seric ** - an exit status to use as the code for the 751388Seric ** error message print if the mailer returns 761388Seric ** something we don't understand. 771388Seric ** - A list of names that are to be considered 781388Seric ** "local" (and hence are stripped off) for 791388Seric ** this mailer. 801388Seric ** - An argument vector to be passed to the 811388Seric ** mailer with the following substitutions: 821388Seric ** $f - the from person name. 831388Seric ** $u - the target user name. 841388Seric ** $h - the target user host. 851388Seric ** $c - the hop count. 861388Seric ** >>>>>>>>>> Entry zero must be for the local 871388Seric ** >> NOTE >> mailer and entry one must be for 881388Seric ** >>>>>>>>>> the shell. 891388Seric ** ParseTab -- a table driving the parsing process. Each 901388Seric ** entry contains: 911388Seric ** - a character that will trigger this entry. 921388Seric ** - an index into the Mailer table. 931388Seric ** - a word of flags, described in dlvrmail.h. 941388Seric ** - an argument. If we have P_MAP, it is the 951388Seric ** character to turn the trigger character into. 961388Seric ** If we have P_MOVE, it is the site to send it 971388Seric ** to, using the mailer specified above. 981573Seric ** This table will almost certainly have to be 991573Seric ** changed on your site if you have anything more 1001573Seric ** than the UUCP net. 101294Seric */ 102294Seric 103294Seric 104294Seric 105294Seric 106*1596Seric static char SccsId[] = "@(#)conf.c 1.10 10/21/80"; 107294Seric 1081388Seric 1091388Seric bool UseMsgId = FALSE; /* don't put message id's in anywhere */ 1101388Seric 1111388Seric # include <whoami.h> /* definitions of machine id's at berkeley */ 1121388Seric 1131573Seric # ifdef BERKELEY 1141573Seric char *ArpaHost = "Berkeley"; /* host name of gateway on Arpanet */ 1151573Seric # else BERKELEY 1161573Seric char *ArpaHost = "[unknown]"; 1171573Seric char *MyLocName = sysname; 1181573Seric # define HASUUCP /* default to having UUCP net */ 1191573Seric char *UucpLocal[] = { sysname, NULL }; 1201573Seric # endif BERKELEY 1211573Seric 122294Seric # ifdef ING70 123294Seric static char *BerkLocal[] = { "i", "ingres", "ing70", NULL }; 124590Seric # define ArpaLocal NULL 1251206Seric char *MyLocName = "Ing70"; 126294Seric # define HASARPA 127294Seric # define V6 128294Seric # endif ING70 129294Seric 130294Seric # ifdef INGVAX 131294Seric static char *BerkLocal[] = { "j", "ingvax", NULL }; 1321206Seric char *MyLocName = "IngVax"; 133294Seric # endif INGVAX 134294Seric 135294Seric # ifdef CSVAX 136294Seric static char *BerkLocal[] = { "v", "csvax", "vax", NULL }; 137590Seric static char *UucpLocal[] = { "ucbvax", "ernie", NULL }; 1381206Seric char *MyLocName = "CSVAX"; 139294Seric # define HASUUCP 140294Seric # define NETV6MAIL 141294Seric # endif CSVAX 142294Seric 143294Seric # ifdef CORY 144294Seric /* untested */ 145294Seric static char *BerkLocal[] = { "y", "cory", NULL }; 1461206Seric char *MyLocName = "Cory"; 147294Seric # endif CORY 148294Seric 149294Seric # ifdef IMAGE 150294Seric /* untested */ 151294Seric static char *BerkLocal[] = { "m", "image", NULL }; 1521206Seric char *MyLocName = "Image"; 153294Seric # define V6 154294Seric # endif IMAGE 155294Seric 156294Seric # ifdef ESVAX 157294Seric /* untested */ 158294Seric static char *BerkLocal[] = { "o", "esvax", NULL }; 1591206Seric char *MyLocName = "ESVAX"; 160294Seric # endif ESVAX 161294Seric 162294Seric # ifdef EECS40 163294Seric /* untested */ 164294Seric static char *BerkLocal[] = { "z", "eecs40", NULL }; 1651206Seric char *MyLocName = "EECS40"; 166294Seric # define V6 167294Seric # endif EECS40 168294Seric 169590Seric 170590Seric # ifndef HASARPA 171590Seric # define ArpaLocal NULL 172590Seric # endif HASARPA 173590Seric 174590Seric # ifndef HASUUCP 175590Seric # define UucpLocal NULL 176590Seric # endif HASUUCP 177590Seric 178590Seric 179294Seric struct mailer Mailer[] = 180294Seric { 181294Seric /* local mail -- must be #0 */ 182294Seric { 183294Seric # ifdef NETV6MAIL 184294Seric "/usr/net/bin/v6mail", 185294Seric # else 186294Seric "/bin/mail", 187294Seric # endif 188294Seric M_ROPT|M_NOHOST|M_STRIPQ, EX_NOUSER, NULL, 189294Seric { "...local%mail", "-d", "$u", NULL } 190294Seric }, 191294Seric /* pipes through programs -- must be #1 */ 192294Seric { 193294Seric "/bin/csh", 194*1596Seric M_HDR|M_NOHOST, EX_UNAVAILABLE, NULL, 195294Seric { "...prog%mail", "-fc", "$u", NULL } 196294Seric }, 197294Seric /* local berkeley mail */ 198294Seric { 199294Seric "/usr/net/bin/sendberkmail", 200*1596Seric M_FOPT|M_HDR|M_STRIPQ, EX_UNAVAILABLE, BerkLocal, 201294Seric { "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL } 202294Seric }, 203294Seric /* arpanet mail */ 204294Seric { 205294Seric "/usr/lib/mailers/arpa", 206590Seric M_STRIPQ, 0, ArpaLocal, 207294Seric { "...arpa%mail", "$f", "$h", "$u", NULL } 208294Seric }, 209294Seric /* uucp mail (cheat & use Bell's v7 mail) */ 210294Seric { 211294Seric "/bin/mail", 212917Seric M_ROPT|M_STRIPQ, EX_NOUSER, UucpLocal, 213294Seric # ifdef DUMBMAIL 214294Seric { "...uucp%mail", "$h!$u", NULL } 215294Seric # else 216294Seric { "...uucp%mail", "-d", "$h!$u", NULL } 217294Seric # endif DUMBMAIL 218294Seric }, 219294Seric }; 220294Seric 221294Seric # define M_LOCAL 0 222294Seric # define M_BERK 2 223294Seric # define M_ARPA 3 224294Seric # define M_UUCP 4 225294Seric 226294Seric 227294Seric 2281573Seric # ifdef BERKELEY 229294Seric struct parsetab ParseTab[] = 230294Seric { 231294Seric ':', M_BERK, P_ONE, NULL, 232294Seric # ifdef HASARPA 233294Seric '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 234294Seric # else 235294Seric '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 236294Seric # endif HASARPA 237294Seric '^', -1, P_MAP, "!", 238294Seric # ifdef HASUUCP 239294Seric '!', M_UUCP, 0, NULL, 240294Seric # else 241294Seric '!', M_BERK, P_MOVE, "csvax", 242294Seric # endif HASUUCP 243294Seric '.', -1, P_MAP|P_ONE, ":", 244294Seric '\0', M_LOCAL, P_MOVE, "", 245294Seric }; 2461573Seric # else BERKELEY 2471573Seric struct parsetab ParseTab[] = 2481573Seric { 2491573Seric # ifdef HASARPA 2501573Seric '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 2511573Seric # endif HASARPA 2521573Seric # ifdef HASUUCP 2531573Seric '^', -1, P_MAP, "!", 2541573Seric '!', M_UUCP, 0, NULL, 2551573Seric # endif HASUUCP 2561573Seric '\0', M_LOCAL, P_MOVE, "", 2571573Seric }; 2581573Seric # endif BERKELEY 259294Seric /* 260294Seric ** GETNAME -- Get the current users login name. 261294Seric ** 262294Seric ** This is in config.c because it is somewhat machine dependent. 263294Seric ** Examine it carefully for your installation. 264294Seric ** 265294Seric ** Algorithm: 266294Seric ** See if the person is logged in. If so, return 267294Seric ** the name s/he is logged in as. 268294Seric ** Look up the user id in /etc/passwd. If found, 269294Seric ** return that name. 270294Seric ** Return NULL. 271294Seric ** 272294Seric ** Parameters: 273294Seric ** none 274294Seric ** 275294Seric ** Returns: 276294Seric ** The login name of this user. 277294Seric ** NULL if this person is noone. 278294Seric ** 279294Seric ** Side Effects: 280294Seric ** none 281294Seric ** 282294Seric ** Called By: 283294Seric ** main 284294Seric */ 285294Seric 286294Seric char * 287294Seric getname() 288294Seric { 289294Seric register char *p; 290294Seric register struct passwd *w; 291294Seric extern char *getlogin(); 292294Seric extern struct passwd *getpwuid(); 293294Seric static char namebuf[9]; 294294Seric 295294Seric p = getlogin(); 296294Seric if (p != NULL && p[0] != '\0') 297294Seric return (p); 298294Seric # ifdef V6 299294Seric w = getpwuid(getuid() & 0377); 300294Seric # else 301294Seric w = getpwuid(getuid()); 302294Seric # endif V6 303294Seric if (w != NULL) 304294Seric { 305294Seric strcpy(namebuf, w->pw_name); 306294Seric return (namebuf); 307294Seric } 308294Seric return (NULL); 309294Seric } 310294Seric 311294Seric # ifdef V6 312294Seric /* 313294Seric ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 314294Seric ** 315294Seric ** Returns the pathname of the user's tty. Returns NULL if 316294Seric ** the user is not logged in or if s/he has write permission 317294Seric ** denied. 318294Seric ** 319294Seric ** Parameters: 320294Seric ** none 321294Seric ** 322294Seric ** Returns: 323294Seric ** pathname of the user's tty. 324294Seric ** NULL if not logged in or write permission denied. 325294Seric ** 326294Seric ** Side Effects: 327294Seric ** none. 328294Seric ** 329294Seric ** WARNING: 330294Seric ** Return value is in a local buffer. 331294Seric ** 332294Seric ** Called By: 333294Seric ** savemail 334294Seric */ 335294Seric 336294Seric # include <sys/types.h> 337294Seric # include <sys/stat.h> 338294Seric 339294Seric char * 340294Seric ttypath() 341294Seric { 342294Seric struct stat stbuf; 343294Seric register int i; 344294Seric static char pathn[] = "/dev/ttyx"; 345294Seric extern int errno; 346294Seric 347294Seric /* compute the pathname of the controlling tty */ 348294Seric if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 349294Seric { 350294Seric errno = 0; 351294Seric return (NULL); 352294Seric } 353294Seric pathn[8] = i; 354294Seric 355294Seric /* see if we have write permission */ 356294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 357294Seric { 358294Seric errno = 0; 359294Seric return (NULL); 360294Seric } 361294Seric 362294Seric /* see if the user is logged in */ 363294Seric if (getlogin() == NULL) 364294Seric return (NULL); 365294Seric 366294Seric /* looks good */ 367294Seric return (pathn); 368294Seric } 369294Seric /* 370294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 371294Seric ** 372294Seric ** This is included here because it is standard in v7, but we 373294Seric ** need it in v6. 374294Seric ** 375294Seric ** Algorithm: 376294Seric ** Open /dev/null to create a descriptor. 377294Seric ** Close that descriptor. 378294Seric ** Copy the existing fd into the descriptor. 379294Seric ** 380294Seric ** Parameters: 381294Seric ** fd -- the open file descriptor. 382294Seric ** type -- "r", "w", or whatever. 383294Seric ** 384294Seric ** Returns: 385294Seric ** The file descriptor it creates. 386294Seric ** 387294Seric ** Side Effects: 388294Seric ** none 389294Seric ** 390294Seric ** Called By: 391294Seric ** deliver 392294Seric ** 393294Seric ** Notes: 394294Seric ** The mode of fd must match "type". 395294Seric */ 396294Seric 397294Seric FILE * 398294Seric fdopen(fd, type) 399294Seric int fd; 400294Seric char *type; 401294Seric { 402294Seric register FILE *f; 403294Seric 404294Seric f = fopen("/dev/null", type); 405294Seric close(fileno(f)); 406294Seric fileno(f) = fd; 407294Seric return (f); 408294Seric } 409294Seric /* 410294Seric ** INDEX -- Return pointer to character in string 411294Seric ** 412294Seric ** For V7 compatibility. 413294Seric ** 414294Seric ** Parameters: 415294Seric ** s -- a string to scan. 416294Seric ** c -- a character to look for. 417294Seric ** 418294Seric ** Returns: 419294Seric ** If c is in s, returns the address of the first 420294Seric ** instance of c in s. 421294Seric ** NULL if c is not in s. 422294Seric ** 423294Seric ** Side Effects: 424294Seric ** none. 425294Seric */ 426294Seric 427294Seric index(s, c) 428294Seric register char *s; 429294Seric register char c; 430294Seric { 431294Seric while (*s != '\0') 432294Seric { 433294Seric if (*s++ == c) 434294Seric return (--s); 435294Seric } 436294Seric return (NULL); 437294Seric } 438294Seric # endif V6 439294Seric 440294Seric # ifndef V6 441294Seric /* 442294Seric ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 443294Seric ** 444294Seric ** Returns the pathname of the user's tty. Returns NULL if 445294Seric ** the user is not logged in or if s/he has write permission 446294Seric ** denied. 447294Seric ** 448294Seric ** Parameters: 449294Seric ** none 450294Seric ** 451294Seric ** Returns: 452294Seric ** pathname of the user's tty. 453294Seric ** NULL if not logged in or write permission denied. 454294Seric ** 455294Seric ** Side Effects: 456294Seric ** none. 457294Seric ** 458294Seric ** WARNING: 459294Seric ** Return value is in a local buffer. 460294Seric ** 461294Seric ** Called By: 462294Seric ** savemail 463294Seric */ 464294Seric 465294Seric # include <sys/types.h> 466294Seric # include <sys/stat.h> 467294Seric 468294Seric char * 469294Seric ttypath() 470294Seric { 471294Seric struct stat stbuf; 472294Seric register char *pathn; 473294Seric extern int errno; 474294Seric extern char *ttyname(); 475294Seric 476294Seric /* compute the pathname of the controlling tty */ 477294Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 478294Seric { 479294Seric errno = 0; 480294Seric return (NULL); 481294Seric } 482294Seric 483294Seric /* see if we have write permission */ 484294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 485294Seric { 486294Seric errno = 0; 487294Seric return (NULL); 488294Seric } 489294Seric 490294Seric /* see if the user is logged in */ 491294Seric if (getlogin() == NULL) 492294Seric return (NULL); 493294Seric 494294Seric /* looks good */ 495294Seric return (pathn); 496294Seric } 497294Seric # endif V6 498