1*294Seric # include <stdio.h> 2*294Seric # include <pwd.h> 3*294Seric # include "dlvrmail.h" 4*294Seric # include <whoami.h> 5*294Seric 6*294Seric /* 7*294Seric ** CONF.C -- Delivermail Configuration Tables. 8*294Seric ** 9*294Seric ** Defines the configuration of this installation. 10*294Seric ** 11*294Seric ** The first table describes available mailers. This is 12*294Seric ** just a list of argument vectors, with the following 13*294Seric ** codes embedded: 14*294Seric ** $u -- insert the user name. 15*294Seric ** $h -- insert the host name. 16*294Seric ** $f -- insert the from person name. 17*294Seric ** $c -- insert the hop count. 18*294Seric ** This stuff is interpreted in buildmail. There are two 19*294Seric ** important conventions here: entry zero must be the 20*294Seric ** local mailer & entry one must be the shell. 21*294Seric ** 22*294Seric ** The second table gives a list of special characters. This 23*294Seric ** table is scanned linearly by parse() until an entry is 24*294Seric ** found using one of the magic characters. Other fields 25*294Seric ** give more information on how to handle it. 26*294Seric ** 27*294Seric ** Defined Constants: 28*294Seric ** M_* -- indices into Mailer, used only in this module. 29*294Seric ** 30*294Seric ** Defines: 31*294Seric ** Mailer -- the mailer descriptor table. 32*294Seric ** ParseTab -- the parse table. 33*294Seric ** 34*294Seric ** Notes: 35*294Seric ** Ingres 11/70 version. 36*294Seric ** 37*294Seric ** History: 38*294Seric ** 3/5/80 -- Generalized to use <whoami.h>. 39*294Seric ** 12/26/79 -- written for Ingres 11/70. 40*294Seric */ 41*294Seric 42*294Seric 43*294Seric 44*294Seric 45*294Seric 46*294Seric # ifdef ING70 47*294Seric static char *BerkLocal[] = { "i", "ingres", "ing70", NULL }; 48*294Seric char *MyLocNam = "Ing70"; 49*294Seric # define HASARPA 50*294Seric # define V6 51*294Seric # endif ING70 52*294Seric 53*294Seric # ifdef INGVAX 54*294Seric /* untested */ 55*294Seric static char *BerkLocal[] = { "j", "ingvax", NULL }; 56*294Seric char *MyLocNam = "IngVax"; 57*294Seric # endif INGVAX 58*294Seric 59*294Seric # ifdef CSVAX 60*294Seric /* untested */ 61*294Seric static char *BerkLocal[] = { "v", "csvax", "vax", NULL }; 62*294Seric char *MyLocNam = "CSVax"; 63*294Seric # define HASUUCP 64*294Seric # define NETV6MAIL 65*294Seric # endif CSVAX 66*294Seric 67*294Seric # ifdef CORY 68*294Seric /* untested */ 69*294Seric static char *BerkLocal[] = { "y", "cory", NULL }; 70*294Seric char *MyLocNam = "Cory"; 71*294Seric # endif CORY 72*294Seric 73*294Seric # ifdef IMAGE 74*294Seric /* untested */ 75*294Seric static char *BerkLocal[] = { "m", "image", NULL }; 76*294Seric char *MyLocNam = "Image"; 77*294Seric # define V6 78*294Seric # endif IMAGE 79*294Seric 80*294Seric # ifdef ESVAX 81*294Seric /* untested */ 82*294Seric static char *BerkLocal[] = { "o", "esvax", NULL }; 83*294Seric char *MyLocNam = "ESVax"; 84*294Seric # endif ESVAX 85*294Seric 86*294Seric # ifdef EECS40 87*294Seric /* untested */ 88*294Seric static char *BerkLocal[] = { "z", "eecs40", NULL }; 89*294Seric char *MyLocNam = "EECS40"; 90*294Seric # define V6 91*294Seric # endif EECS40 92*294Seric 93*294Seric struct mailer Mailer[] = 94*294Seric { 95*294Seric /* local mail -- must be #0 */ 96*294Seric { 97*294Seric # ifdef NETV6MAIL 98*294Seric "/usr/net/bin/v6mail", 99*294Seric # else 100*294Seric "/bin/mail", 101*294Seric # endif 102*294Seric M_ROPT|M_NOHOST|M_STRIPQ, EX_NOUSER, NULL, 103*294Seric { "...local%mail", "-d", "$u", NULL } 104*294Seric }, 105*294Seric /* pipes through programs -- must be #1 */ 106*294Seric { 107*294Seric "/bin/csh", 108*294Seric M_HDR|M_NOHOST, EX_UNAVAIL, NULL, 109*294Seric { "...prog%mail", "-fc", "$u", NULL } 110*294Seric }, 111*294Seric /* local berkeley mail */ 112*294Seric { 113*294Seric "/usr/net/bin/sendberkmail", 114*294Seric M_FOPT|M_HDR, EX_UNAVAIL, BerkLocal, 115*294Seric { "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL } 116*294Seric }, 117*294Seric /* arpanet mail */ 118*294Seric { 119*294Seric "/usr/lib/mailers/arpa", 120*294Seric 0, 0, NULL, 121*294Seric { "...arpa%mail", "$f", "$h", "$u", NULL } 122*294Seric }, 123*294Seric /* uucp mail (cheat & use Bell's v7 mail) */ 124*294Seric { 125*294Seric # ifdef UCKMAIL 126*294Seric "/bin/badmail", 127*294Seric # else 128*294Seric "/bin/mail", 129*294Seric # endif 130*294Seric M_ROPT|M_NOHOST|M_STRIPQ, EX_NOUSER, NULL, 131*294Seric # ifdef DUMBMAIL 132*294Seric { "...uucp%mail", "$h!$u", NULL } 133*294Seric # else 134*294Seric { "...uucp%mail", "-d", "$h!$u", NULL } 135*294Seric # endif DUMBMAIL 136*294Seric }, 137*294Seric }; 138*294Seric 139*294Seric # define M_LOCAL 0 140*294Seric # define M_BERK 2 141*294Seric # define M_ARPA 3 142*294Seric # define M_UUCP 4 143*294Seric 144*294Seric 145*294Seric 146*294Seric struct parsetab ParseTab[] = 147*294Seric { 148*294Seric ':', M_BERK, P_ONE, NULL, 149*294Seric # ifdef HASARPA 150*294Seric '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 151*294Seric # else 152*294Seric '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 153*294Seric # endif HASARPA 154*294Seric '^', -1, P_MAP, "!", 155*294Seric # ifdef HASUUCP 156*294Seric '!', M_UUCP, 0, NULL, 157*294Seric # else 158*294Seric '!', M_BERK, P_MOVE, "csvax", 159*294Seric # endif HASUUCP 160*294Seric '.', -1, P_MAP|P_ONE, ":", 161*294Seric '\0', M_LOCAL, P_MOVE, "", 162*294Seric }; 163*294Seric /* 164*294Seric ** GETNAME -- Get the current users login name. 165*294Seric ** 166*294Seric ** This is in config.c because it is somewhat machine dependent. 167*294Seric ** Examine it carefully for your installation. 168*294Seric ** 169*294Seric ** Algorithm: 170*294Seric ** See if the person is logged in. If so, return 171*294Seric ** the name s/he is logged in as. 172*294Seric ** Look up the user id in /etc/passwd. If found, 173*294Seric ** return that name. 174*294Seric ** Return NULL. 175*294Seric ** 176*294Seric ** Parameters: 177*294Seric ** none 178*294Seric ** 179*294Seric ** Returns: 180*294Seric ** The login name of this user. 181*294Seric ** NULL if this person is noone. 182*294Seric ** 183*294Seric ** Side Effects: 184*294Seric ** none 185*294Seric ** 186*294Seric ** Requires: 187*294Seric ** getlogin (sys) 188*294Seric ** getpwuid (sys) 189*294Seric ** getuid (sys) 190*294Seric ** 191*294Seric ** Called By: 192*294Seric ** main 193*294Seric ** 194*294Seric ** History: 195*294Seric ** 12/26/79 -- written. 196*294Seric */ 197*294Seric 198*294Seric char * 199*294Seric getname() 200*294Seric { 201*294Seric register char *p; 202*294Seric register struct passwd *w; 203*294Seric extern char *getlogin(); 204*294Seric extern struct passwd *getpwuid(); 205*294Seric static char namebuf[9]; 206*294Seric 207*294Seric p = getlogin(); 208*294Seric if (p != NULL && p[0] != '\0') 209*294Seric return (p); 210*294Seric # ifdef V6 211*294Seric w = getpwuid(getuid() & 0377); 212*294Seric # else 213*294Seric w = getpwuid(getuid()); 214*294Seric # endif V6 215*294Seric if (w != NULL) 216*294Seric { 217*294Seric strcpy(namebuf, w->pw_name); 218*294Seric return (namebuf); 219*294Seric } 220*294Seric return (NULL); 221*294Seric } 222*294Seric 223*294Seric # ifdef V6 224*294Seric /* 225*294Seric ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 226*294Seric ** 227*294Seric ** Returns the pathname of the user's tty. Returns NULL if 228*294Seric ** the user is not logged in or if s/he has write permission 229*294Seric ** denied. 230*294Seric ** 231*294Seric ** Parameters: 232*294Seric ** none 233*294Seric ** 234*294Seric ** Returns: 235*294Seric ** pathname of the user's tty. 236*294Seric ** NULL if not logged in or write permission denied. 237*294Seric ** 238*294Seric ** Side Effects: 239*294Seric ** none. 240*294Seric ** 241*294Seric ** WARNING: 242*294Seric ** Return value is in a local buffer. 243*294Seric ** 244*294Seric ** Requires: 245*294Seric ** stat (sys) 246*294Seric ** ttyn (sys) 247*294Seric ** open (sys) 248*294Seric ** read (sys) 249*294Seric ** close (sys) 250*294Seric ** seek (sys) 251*294Seric ** 252*294Seric ** Called By: 253*294Seric ** savemail 254*294Seric ** 255*294Seric ** History: 256*294Seric ** 1/12/80 -- written. 257*294Seric */ 258*294Seric 259*294Seric # include <sys/types.h> 260*294Seric # include <sys/stat.h> 261*294Seric 262*294Seric char * 263*294Seric ttypath() 264*294Seric { 265*294Seric struct stat stbuf; 266*294Seric register int i; 267*294Seric static char pathn[] = "/dev/ttyx"; 268*294Seric extern int errno; 269*294Seric 270*294Seric /* compute the pathname of the controlling tty */ 271*294Seric if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 272*294Seric { 273*294Seric errno = 0; 274*294Seric return (NULL); 275*294Seric } 276*294Seric pathn[8] = i; 277*294Seric 278*294Seric /* see if we have write permission */ 279*294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 280*294Seric { 281*294Seric errno = 0; 282*294Seric return (NULL); 283*294Seric } 284*294Seric 285*294Seric /* see if the user is logged in */ 286*294Seric if (getlogin() == NULL) 287*294Seric return (NULL); 288*294Seric 289*294Seric /* looks good */ 290*294Seric return (pathn); 291*294Seric } 292*294Seric /* 293*294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 294*294Seric ** 295*294Seric ** This is included here because it is standard in v7, but we 296*294Seric ** need it in v6. 297*294Seric ** 298*294Seric ** Algorithm: 299*294Seric ** Open /dev/null to create a descriptor. 300*294Seric ** Close that descriptor. 301*294Seric ** Copy the existing fd into the descriptor. 302*294Seric ** 303*294Seric ** Parameters: 304*294Seric ** fd -- the open file descriptor. 305*294Seric ** type -- "r", "w", or whatever. 306*294Seric ** 307*294Seric ** Returns: 308*294Seric ** The file descriptor it creates. 309*294Seric ** 310*294Seric ** Side Effects: 311*294Seric ** none 312*294Seric ** 313*294Seric ** Requires: 314*294Seric ** fopen (sys) 315*294Seric ** 316*294Seric ** Called By: 317*294Seric ** deliver 318*294Seric ** 319*294Seric ** Notes: 320*294Seric ** The mode of fd must match "type". 321*294Seric */ 322*294Seric 323*294Seric FILE * 324*294Seric fdopen(fd, type) 325*294Seric int fd; 326*294Seric char *type; 327*294Seric { 328*294Seric register FILE *f; 329*294Seric 330*294Seric f = fopen("/dev/null", type); 331*294Seric close(fileno(f)); 332*294Seric fileno(f) = fd; 333*294Seric return (f); 334*294Seric } 335*294Seric /* 336*294Seric ** INDEX -- Return pointer to character in string 337*294Seric ** 338*294Seric ** For V7 compatibility. 339*294Seric ** 340*294Seric ** Parameters: 341*294Seric ** s -- a string to scan. 342*294Seric ** c -- a character to look for. 343*294Seric ** 344*294Seric ** Returns: 345*294Seric ** If c is in s, returns the address of the first 346*294Seric ** instance of c in s. 347*294Seric ** NULL if c is not in s. 348*294Seric ** 349*294Seric ** Side Effects: 350*294Seric ** none. 351*294Seric ** 352*294Seric ** Requires: 353*294Seric ** none. 354*294Seric ** 355*294Seric ** History: 356*294Seric ** 3/14/80 -- written. Why isn't this in -lS? 357*294Seric */ 358*294Seric 359*294Seric index(s, c) 360*294Seric register char *s; 361*294Seric register char c; 362*294Seric { 363*294Seric while (*s != '\0') 364*294Seric { 365*294Seric if (*s++ == c) 366*294Seric return (--s); 367*294Seric } 368*294Seric return (NULL); 369*294Seric } 370*294Seric # endif V6 371*294Seric 372*294Seric # ifndef V6 373*294Seric /* 374*294Seric ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 375*294Seric ** 376*294Seric ** Returns the pathname of the user's tty. Returns NULL if 377*294Seric ** the user is not logged in or if s/he has write permission 378*294Seric ** denied. 379*294Seric ** 380*294Seric ** Parameters: 381*294Seric ** none 382*294Seric ** 383*294Seric ** Returns: 384*294Seric ** pathname of the user's tty. 385*294Seric ** NULL if not logged in or write permission denied. 386*294Seric ** 387*294Seric ** Side Effects: 388*294Seric ** none. 389*294Seric ** 390*294Seric ** WARNING: 391*294Seric ** Return value is in a local buffer. 392*294Seric ** 393*294Seric ** Requires: 394*294Seric ** stat (sys) 395*294Seric ** ttyn (sys) 396*294Seric ** open (sys) 397*294Seric ** read (sys) 398*294Seric ** close (sys) 399*294Seric ** seek (sys) 400*294Seric ** 401*294Seric ** Called By: 402*294Seric ** savemail 403*294Seric ** 404*294Seric ** History: 405*294Seric ** 1/12/80 -- written. 406*294Seric */ 407*294Seric 408*294Seric # include <sys/types.h> 409*294Seric # include <sys/stat.h> 410*294Seric 411*294Seric char * 412*294Seric ttypath() 413*294Seric { 414*294Seric struct stat stbuf; 415*294Seric register char *pathn; 416*294Seric extern int errno; 417*294Seric extern char *ttyname(); 418*294Seric 419*294Seric /* compute the pathname of the controlling tty */ 420*294Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 421*294Seric { 422*294Seric errno = 0; 423*294Seric return (NULL); 424*294Seric } 425*294Seric 426*294Seric /* see if we have write permission */ 427*294Seric if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode)) 428*294Seric { 429*294Seric errno = 0; 430*294Seric return (NULL); 431*294Seric } 432*294Seric 433*294Seric /* see if the user is logged in */ 434*294Seric if (getlogin() == NULL) 435*294Seric return (NULL); 436*294Seric 437*294Seric /* looks good */ 438*294Seric return (pathn); 439*294Seric } 440*294Seric # endif V6 441