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". 192355Seric ** Also, only v6mail has the "/dev/mail" stuff 202355Seric ** in it (for biff(1)). 211388Seric ** V6 -- running on a version 6 system. This determines 221388Seric ** whether to define certain routines between 231388Seric ** the two systems. If you are running a funny 241388Seric ** system, e.g., V6 with long tty names, this 251388Seric ** should be checked carefully. 261573Seric ** DUMBMAIL -- set if your /bin/mail doesn't have the 271573Seric ** -d flag. 28294Seric ** 291388Seric ** Configuration Variables: 301573Seric ** ArpaHost -- the arpanet name of the host through 311573Seric ** which arpanet mail will be sent. 321388Seric ** MyLocName -- the name of the host on a local network. 331388Seric ** This is used to disambiguate the contents of 341388Seric ** ArpaHost among many hosts who may be sharing 351388Seric ** a gateway. 362099Seric ** DaemonName -- the name of this agent for use in 372099Seric ** error messages, typically "~MAILER~DAEMON~" 382099Seric ** at this host on the local net. 391573Seric ** ArpaLocal -- a list of local names for this host on 401573Seric ** the arpanet. Only functional if HASARPA set. 411573Seric ** UucpLocal -- ditto for the Arpanet. 421573Seric ** BerkLocal -- ditto for the Berknet. 431388Seric ** Mailer -- a table of mailers known to the system. 441388Seric ** The fields are: 451388Seric ** - the pathname of the mailer. 461388Seric ** - a list of flags describing the properties 471388Seric ** of this mailer: 481388Seric ** M_FOPT -- if set, the mailer has a picky "-f" 491388Seric ** option. In this mode, the mailer will 501388Seric ** only accept the "-f" option if the 511388Seric ** sender is actually "root", "network", 521388Seric ** and possibly (but not necessarily) if 531388Seric ** the -f argument matches the real sender. 541388Seric ** The effect is that if the "-f" option 551388Seric ** is given to delivermail then it will be 561388Seric ** passed through (as arguments 1 & 2) to 571388Seric ** the mailer. 581388Seric ** M_ROPT -- identical to M_FOPT, except uses 591388Seric ** -r instead. 601388Seric ** M_QUIET -- if set, don't print a message if 611388Seric ** the mailer returns bad status. 621388Seric ** M_RESTR -- if set, this mailer is restricted 631388Seric ** to use by "daemon"; otherwise, we do a 641388Seric ** setuid(getuid()) before calling the 651388Seric ** mailer. 661388Seric ** M_HDR -- if set, the mailer wants us to 671388Seric ** insert a UNIX "From" line before 681388Seric ** outputing. 691827Seric ** M_FHDR -- if set, the header that we 701827Seric ** generate will be used literally, so 711827Seric ** we must force it to be correct. The 721827Seric ** effect is that we generate a header 731827Seric ** even if one exists. 741388Seric ** M_NOHOST -- if set, this mailer doesn't care 751388Seric ** about the host part (e.g., the local 761388Seric ** mailer). 771388Seric ** M_STRIPQ -- if set, strip quote (`"') 781388Seric ** characters out of parameters as you 791388Seric ** transliterate them into the argument 801388Seric ** vector. For example, the local mailer 811388Seric ** is called directly, so these should be 821388Seric ** stripped, but the program-mailer (i.e., 831388Seric ** csh) should leave them in. 84*2897Seric ** M_NEEDDATE -- this mailer requires a Date: 85*2897Seric ** field in the message. 86*2897Seric ** M_NEEDFROM -- this mailer requires a From: 87*2897Seric ** field in the message. 88*2897Seric ** M_MSGID -- this mailer requires a Message-Id 89*2897Seric ** field in the message. 90*2897Seric ** M_COMMAS -- this mailer wants comma- 91*2897Seric ** seperated To: and Cc: fields. 92*2897Seric ** M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID| 93*2897Seric ** M_COMMAS. 941388Seric ** - an exit status to use as the code for the 951388Seric ** error message print if the mailer returns 961388Seric ** something we don't understand. 971388Seric ** - A list of names that are to be considered 981388Seric ** "local" (and hence are stripped off) for 991388Seric ** this mailer. 1001388Seric ** - An argument vector to be passed to the 1011388Seric ** mailer with the following substitutions: 1021388Seric ** $f - the from person name. 1031388Seric ** $u - the target user name. 1041388Seric ** $h - the target user host. 1051388Seric ** $c - the hop count. 1061388Seric ** >>>>>>>>>> Entry zero must be for the local 1071388Seric ** >> NOTE >> mailer and entry one must be for 1081388Seric ** >>>>>>>>>> the shell. 1091388Seric ** ParseTab -- a table driving the parsing process. Each 1101388Seric ** entry contains: 1111388Seric ** - a character that will trigger this entry. 1121388Seric ** - an index into the Mailer table. 1131388Seric ** - a word of flags, described in dlvrmail.h. 1141388Seric ** - an argument. If we have P_MAP, it is the 1151388Seric ** character to turn the trigger character into. 1161388Seric ** If we have P_MOVE, it is the site to send it 1171388Seric ** to, using the mailer specified above. 1181573Seric ** This table will almost certainly have to be 1191573Seric ** changed on your site if you have anything more 1201573Seric ** than the UUCP net. 121*2897Seric ** HdrInfo -- a table describing well-known header fields. 122*2897Seric ** Each entry has the field name and some flags, 123*2897Seric ** which can be: 124*2897Seric ** H_CONCAT -- if there is more than one field 125*2897Seric ** of this name, turn it into a comma- 126*2897Seric ** seperated list. 127*2897Seric ** H_DELETE -- delete this field. 128294Seric */ 129294Seric 130294Seric 131294Seric 132294Seric 133*2897Seric static char SccsId[] = "@(#)conf.c 3.1 03/04/81"; 134294Seric 1351388Seric 1361388Seric bool UseMsgId = FALSE; /* don't put message id's in anywhere */ 1371388Seric 1381388Seric # include <whoami.h> /* definitions of machine id's at berkeley */ 1391388Seric 1401573Seric # ifdef BERKELEY 1412099Seric 1421573Seric char *ArpaHost = "Berkeley"; /* host name of gateway on Arpanet */ 143*2897Seric char *UucpHost = "ucbvax"; /* host name of gateway on UUCP net */ 144*2897Seric # define BerkHost MyLocName /* host name of gateway on Berk net */ 1452355Seric # define NETV6MAIL /* use /usr/net/bin/v6mail for local delivery */ 1462099Seric 1471573Seric # else BERKELEY 1482099Seric 1491573Seric char *ArpaHost = "[unknown]"; 1501573Seric char *MyLocName = sysname; 1511573Seric # define HASUUCP /* default to having UUCP net */ 1521573Seric char *UucpLocal[] = { sysname, NULL }; 1532099Seric 1541573Seric # endif BERKELEY 1551573Seric 1562099Seric 1572099Seric /* Specific Configurations for Berkeley Machines */ 1582099Seric 1592099Seric /* Berkeley people: mail changes to csvax:eric or they will be lost! */ 1602099Seric 161294Seric # ifdef ING70 162294Seric static char *BerkLocal[] = { "i", "ingres", "ing70", NULL }; 1632099Seric char *ArpaLocal = { "berkeley", "ucb", NULL }; 1641206Seric char *MyLocName = "Ing70"; 1652098Seric char *DaemonName = "Ing70:~MAILER~DAEMON~"; 166294Seric # define HASARPA 167294Seric # define V6 168294Seric # endif ING70 169294Seric 170294Seric # ifdef INGVAX 171294Seric static char *BerkLocal[] = { "j", "ingvax", NULL }; 1721206Seric char *MyLocName = "IngVax"; 1732098Seric char *DaemonName = "IngVax:~MAILER~DAEMON~"; 174294Seric # endif INGVAX 175294Seric 176294Seric # ifdef CSVAX 177294Seric static char *BerkLocal[] = { "v", "csvax", "vax", NULL }; 178590Seric static char *UucpLocal[] = { "ucbvax", "ernie", NULL }; 1791206Seric char *MyLocName = "CSVAX"; 1802098Seric char *DaemonName = "CSVAX:~MAILER~DAEMON~"; 181294Seric # define HASUUCP 182294Seric # endif CSVAX 183294Seric 1842355Seric # ifdef ARPAVAX 1852355Seric static char *BerkLocal[] = { "r", "arpavax", NULL }; 1862355Seric char *MyLocName = "ARPAVAX"; 1872355Seric char *DaemonName = "ARPAVAX:~MAILER~DAEMON~"; 1882355Seric # endif ARPAVAX 1892355Seric 190294Seric # ifdef CORY 191294Seric static char *BerkLocal[] = { "y", "cory", NULL }; 1921206Seric char *MyLocName = "Cory"; 1932098Seric char *DaemonName = "Cory:~MAILER~DAEMON~"; 194294Seric # endif CORY 195294Seric 1962420Seric # ifdef ONYX 1972420Seric static char *BerkLocal[[] = { "x", "onyx", NULL }; 1982420Seric char *MyLocName = "Onyx"; 1992420Seric char *DaemonName = "Onyx:~MAILER~DAEMON~"; 2002420Seric # endif ONYX 2012420Seric 202294Seric # ifdef IMAGE 203294Seric /* untested */ 204294Seric static char *BerkLocal[] = { "m", "image", NULL }; 2051206Seric char *MyLocName = "Image"; 2062098Seric char *DaemonName = "Image:~MAILER~DAEMON~"; 207294Seric # define V6 208294Seric # endif IMAGE 209294Seric 210294Seric # ifdef ESVAX 211294Seric static char *BerkLocal[] = { "o", "esvax", NULL }; 2121206Seric char *MyLocName = "ESVAX"; 2132098Seric char *DaemonName = "ESVAX:~MAILER~DAEMON~"; 214294Seric # endif ESVAX 215294Seric 216294Seric # ifdef EECS40 217294Seric /* untested */ 218294Seric static char *BerkLocal[] = { "z", "eecs40", NULL }; 2191206Seric char *MyLocName = "EECS40"; 2202098Seric char *DaemonName = "EECS40:~MAILER~DAEMON~"; 221294Seric # define V6 222294Seric # endif EECS40 223294Seric 224590Seric 225590Seric # ifndef HASARPA 226590Seric # define ArpaLocal NULL 227590Seric # endif HASARPA 228590Seric 229590Seric # ifndef HASUUCP 230590Seric # define UucpLocal NULL 231590Seric # endif HASUUCP 232590Seric 233590Seric 234294Seric struct mailer Mailer[] = 235294Seric { 236294Seric /* local mail -- must be #0 */ 237294Seric { 238294Seric # ifdef NETV6MAIL 239294Seric "/usr/net/bin/v6mail", 240294Seric # else 241294Seric "/bin/mail", 242294Seric # endif 243*2897Seric M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, EX_NOUSER, NULL, 244*2897Seric "$f", NULL, 245294Seric { "...local%mail", "-d", "$u", NULL } 246294Seric }, 247294Seric /* pipes through programs -- must be #1 */ 248294Seric { 249294Seric "/bin/csh", 2501827Seric M_HDR|M_FHDR|M_NOHOST, EX_UNAVAILABLE, NULL, 251*2897Seric "$f", NULL, 252294Seric { "...prog%mail", "-fc", "$u", NULL } 253294Seric }, 254294Seric /* local berkeley mail */ 255294Seric { 256294Seric "/usr/net/bin/sendberkmail", 2571596Seric M_FOPT|M_HDR|M_STRIPQ, EX_UNAVAILABLE, BerkLocal, 258*2897Seric "$B:$f", NULL, 259294Seric { "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL } 260294Seric }, 261294Seric /* arpanet mail */ 262294Seric { 263294Seric "/usr/lib/mailers/arpa", 264*2897Seric M_STRIPQ|M_ARPAFMT, 0, ArpaLocal, 265*2897Seric "$f@$A", NULL, 266294Seric { "...arpa%mail", "$f", "$h", "$u", NULL } 267294Seric }, 268294Seric /* uucp mail (cheat & use Bell's v7 mail) */ 269294Seric { 270294Seric "/bin/mail", 271917Seric M_ROPT|M_STRIPQ, EX_NOUSER, UucpLocal, 272*2897Seric "$U!$f", NULL, 273294Seric # ifdef DUMBMAIL 274294Seric { "...uucp%mail", "$h!$u", NULL } 275294Seric # else 276294Seric { "...uucp%mail", "-d", "$h!$u", NULL } 277294Seric # endif DUMBMAIL 278294Seric }, 279294Seric }; 280294Seric 281294Seric # define M_LOCAL 0 282294Seric # define M_BERK 2 283294Seric # define M_ARPA 3 284294Seric # define M_UUCP 4 285294Seric 286294Seric 287294Seric 2881573Seric # ifdef BERKELEY 289294Seric struct parsetab ParseTab[] = 290294Seric { 291294Seric ':', M_BERK, P_ONE, NULL, 292294Seric # ifdef HASARPA 293294Seric '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 294294Seric # else 295294Seric '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 296294Seric # endif HASARPA 297294Seric '^', -1, P_MAP, "!", 298294Seric # ifdef HASUUCP 299294Seric '!', M_UUCP, 0, NULL, 300294Seric # else 301294Seric '!', M_BERK, P_MOVE, "csvax", 302294Seric # endif HASUUCP 303294Seric '.', -1, P_MAP|P_ONE, ":", 304294Seric '\0', M_LOCAL, P_MOVE, "", 305294Seric }; 3061573Seric # else BERKELEY 3071573Seric struct parsetab ParseTab[] = 3081573Seric { 3091573Seric # ifdef HASARPA 3101573Seric '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 3111573Seric # endif HASARPA 3121573Seric # ifdef HASUUCP 3131573Seric '^', -1, P_MAP, "!", 3141573Seric '!', M_UUCP, 0, NULL, 3151573Seric # endif HASUUCP 3161573Seric '\0', M_LOCAL, P_MOVE, "", 3171573Seric }; 3181573Seric # endif BERKELEY 319*2897Seric 320*2897Seric 321*2897Seric /* 322*2897Seric ** Header info table 323*2897Seric */ 324*2897Seric 325*2897Seric struct hdrinfo HdrInfo[] = 326*2897Seric { 327*2897Seric "date", 0, 328*2897Seric "from", 0, 329*2897Seric "to", H_CONCAT, 330*2897Seric "cc", H_CONCAT, 331*2897Seric "subject", 0, 332*2897Seric "message-id", 0, 333*2897Seric NULL, 0 334*2897Seric }; 335294Seric /* 336*2897Seric ** INITMACS -- initialize predefined macros. 337*2897Seric ** 338*2897Seric ** Parameters: 339*2897Seric ** none. 340*2897Seric ** 341*2897Seric ** Returns: 342*2897Seric ** none. 343*2897Seric ** 344*2897Seric ** Side Effects: 345*2897Seric ** Macros array gets initialized. 346*2897Seric */ 347*2897Seric 348*2897Seric char *Macro[26]; 349*2897Seric 350*2897Seric # define MACRO(x) Macro[x - 'A'] 351*2897Seric 352*2897Seric initmacs() 353*2897Seric { 354*2897Seric MACRO('A') = ArpaHost; 355*2897Seric MACRO('B') = BerkHost; 356*2897Seric MACRO('U') = UucpHost; 357*2897Seric } 358*2897Seric /* 359294Seric ** GETNAME -- Get the current users login name. 360294Seric ** 361294Seric ** This is in config.c because it is somewhat machine dependent. 362294Seric ** Examine it carefully for your installation. 363294Seric ** 364294Seric ** Algorithm: 365294Seric ** See if the person is logged in. If so, return 366294Seric ** the name s/he is logged in as. 367294Seric ** Look up the user id in /etc/passwd. If found, 368294Seric ** return that name. 369294Seric ** Return NULL. 370294Seric ** 371294Seric ** Parameters: 372294Seric ** none 373294Seric ** 374294Seric ** Returns: 375294Seric ** The login name of this user. 376294Seric ** NULL if this person is noone. 377294Seric ** 378294Seric ** Side Effects: 379294Seric ** none 380294Seric ** 381294Seric ** Called By: 382294Seric ** main 383294Seric */ 384294Seric 385294Seric char * 386294Seric getname() 387294Seric { 388294Seric register char *p; 389294Seric register struct passwd *w; 390294Seric extern char *getlogin(); 391294Seric extern struct passwd *getpwuid(); 392294Seric static char namebuf[9]; 393294Seric 394294Seric p = getlogin(); 395294Seric if (p != NULL && p[0] != '\0') 396294Seric return (p); 397294Seric # ifdef V6 398294Seric w = getpwuid(getuid() & 0377); 399294Seric # else 400294Seric w = getpwuid(getuid()); 401294Seric # endif V6 402294Seric if (w != NULL) 403294Seric { 404294Seric strcpy(namebuf, w->pw_name); 405294Seric return (namebuf); 406294Seric } 407294Seric return (NULL); 408294Seric } 409294Seric 410294Seric # ifdef V6 411294Seric /* 412294Seric ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 413294Seric ** 414294Seric ** Returns the pathname of the user's tty. Returns NULL if 415294Seric ** the user is not logged in or if s/he has write permission 416294Seric ** denied. 417294Seric ** 418294Seric ** Parameters: 419294Seric ** none 420294Seric ** 421294Seric ** Returns: 422294Seric ** pathname of the user's tty. 423294Seric ** NULL if not logged in or write permission denied. 424294Seric ** 425294Seric ** Side Effects: 426294Seric ** none. 427294Seric ** 428294Seric ** WARNING: 429294Seric ** Return value is in a local buffer. 430294Seric ** 431294Seric ** Called By: 432294Seric ** savemail 433294Seric */ 434294Seric 435294Seric # include <sys/types.h> 436294Seric # include <sys/stat.h> 437294Seric 438294Seric char * 439294Seric ttypath() 440294Seric { 441294Seric struct stat stbuf; 442294Seric register int i; 443294Seric static char pathn[] = "/dev/ttyx"; 444294Seric extern int errno; 445294Seric 446294Seric /* compute the pathname of the controlling tty */ 447294Seric if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 448294Seric { 449294Seric errno = 0; 450294Seric return (NULL); 451294Seric } 452294Seric pathn[8] = i; 453294Seric 454294Seric /* see if we have write permission */ 455294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 456294Seric { 457294Seric errno = 0; 458294Seric return (NULL); 459294Seric } 460294Seric 461294Seric /* see if the user is logged in */ 462294Seric if (getlogin() == NULL) 463294Seric return (NULL); 464294Seric 465294Seric /* looks good */ 466294Seric return (pathn); 467294Seric } 468294Seric /* 469294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 470294Seric ** 471294Seric ** This is included here because it is standard in v7, but we 472294Seric ** need it in v6. 473294Seric ** 474294Seric ** Algorithm: 475294Seric ** Open /dev/null to create a descriptor. 476294Seric ** Close that descriptor. 477294Seric ** Copy the existing fd into the descriptor. 478294Seric ** 479294Seric ** Parameters: 480294Seric ** fd -- the open file descriptor. 481294Seric ** type -- "r", "w", or whatever. 482294Seric ** 483294Seric ** Returns: 484294Seric ** The file descriptor it creates. 485294Seric ** 486294Seric ** Side Effects: 487294Seric ** none 488294Seric ** 489294Seric ** Called By: 490294Seric ** deliver 491294Seric ** 492294Seric ** Notes: 493294Seric ** The mode of fd must match "type". 494294Seric */ 495294Seric 496294Seric FILE * 497294Seric fdopen(fd, type) 498294Seric int fd; 499294Seric char *type; 500294Seric { 501294Seric register FILE *f; 502294Seric 503294Seric f = fopen("/dev/null", type); 504294Seric close(fileno(f)); 505294Seric fileno(f) = fd; 506294Seric return (f); 507294Seric } 508294Seric /* 509294Seric ** INDEX -- Return pointer to character in string 510294Seric ** 511294Seric ** For V7 compatibility. 512294Seric ** 513294Seric ** Parameters: 514294Seric ** s -- a string to scan. 515294Seric ** c -- a character to look for. 516294Seric ** 517294Seric ** Returns: 518294Seric ** If c is in s, returns the address of the first 519294Seric ** instance of c in s. 520294Seric ** NULL if c is not in s. 521294Seric ** 522294Seric ** Side Effects: 523294Seric ** none. 524294Seric */ 525294Seric 526294Seric index(s, c) 527294Seric register char *s; 528294Seric register char c; 529294Seric { 530294Seric while (*s != '\0') 531294Seric { 532294Seric if (*s++ == c) 533294Seric return (--s); 534294Seric } 535294Seric return (NULL); 536294Seric } 537294Seric # endif V6 538294Seric 539294Seric # ifndef V6 540294Seric /* 541294Seric ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 542294Seric ** 543294Seric ** Returns the pathname of the user's tty. Returns NULL if 544294Seric ** the user is not logged in or if s/he has write permission 545294Seric ** denied. 546294Seric ** 547294Seric ** Parameters: 548294Seric ** none 549294Seric ** 550294Seric ** Returns: 551294Seric ** pathname of the user's tty. 552294Seric ** NULL if not logged in or write permission denied. 553294Seric ** 554294Seric ** Side Effects: 555294Seric ** none. 556294Seric ** 557294Seric ** WARNING: 558294Seric ** Return value is in a local buffer. 559294Seric ** 560294Seric ** Called By: 561294Seric ** savemail 562294Seric */ 563294Seric 564294Seric # include <sys/types.h> 565294Seric # include <sys/stat.h> 566294Seric 567294Seric char * 568294Seric ttypath() 569294Seric { 570294Seric struct stat stbuf; 571294Seric register char *pathn; 572294Seric extern int errno; 573294Seric extern char *ttyname(); 574294Seric 575294Seric /* compute the pathname of the controlling tty */ 576294Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 577294Seric { 578294Seric errno = 0; 579294Seric return (NULL); 580294Seric } 581294Seric 582294Seric /* see if we have write permission */ 583294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 584294Seric { 585294Seric errno = 0; 586294Seric return (NULL); 587294Seric } 588294Seric 589294Seric /* see if the user is logged in */ 590294Seric if (getlogin() == NULL) 591294Seric return (NULL); 592294Seric 593294Seric /* looks good */ 594294Seric return (pathn); 595294Seric } 596294Seric # endif V6 597