1 # include <stdio.h> 2 # include <pwd.h> 3 # include "postbox.h" 4 5 /* 6 ** CONF.C -- Postbox 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 ** Also, only v6mail has the "/dev/mail" stuff 20 ** in it (for biff(1)). 21 ** V6 -- running on a version 6 system. This determines 22 ** whether to define certain routines between 23 ** the two systems. If you are running a funny 24 ** system, e.g., V6 with long tty names, this 25 ** should be checked carefully. 26 ** DUMBMAIL -- set if your /bin/mail doesn't have the 27 ** -d flag. 28 ** 29 ** Configuration Variables: 30 ** ArpaHost -- the arpanet name of the host through 31 ** which arpanet mail will be sent. 32 ** MyLocName -- the name of the host on a local network. 33 ** This is used to disambiguate the contents of 34 ** ArpaHost among many hosts who may be sharing 35 ** a gateway. 36 ** DaemonName -- the name of this agent for use in 37 ** error messages, typically "~MAILER~DAEMON~" 38 ** at this host on the local net. 39 ** ArpaLocal -- a list of local names for this host on 40 ** the arpanet. Only functional if HASARPA set. 41 ** UucpLocal -- ditto for the Arpanet. 42 ** BerkLocal -- ditto for the Berknet. 43 ** Mailer -- a table of mailers known to the system. 44 ** The fields are: 45 ** - the pathname of the mailer. 46 ** - a list of flags describing the properties 47 ** of this mailer: 48 ** M_FOPT -- if set, the mailer has a picky "-f" 49 ** option. In this mode, the mailer will 50 ** only accept the "-f" option if the 51 ** sender is actually "root", "network", 52 ** and possibly (but not necessarily) if 53 ** the -f argument matches the real sender. 54 ** The effect is that if the "-f" option 55 ** is given to postbox then it will be 56 ** passed through (as arguments 1 & 2) to 57 ** the mailer. 58 ** M_ROPT -- identical to M_FOPT, except uses 59 ** -r instead. 60 ** M_QUIET -- if set, don't print a message if 61 ** the mailer returns bad status. 62 ** M_RESTR -- if set, this mailer is restricted 63 ** to use by "daemon"; otherwise, we do a 64 ** setuid(getuid()) before calling the 65 ** mailer. 66 ** M_HDR -- if set, the mailer wants us to 67 ** insert a UNIX "From" line before 68 ** outputing. 69 ** M_FHDR -- if set, the header that we 70 ** generate will be used literally, so 71 ** we must force it to be correct. The 72 ** effect is that we generate a header 73 ** even if one exists. 74 ** M_NOHOST -- if set, this mailer doesn't care 75 ** about the host part (e.g., the local 76 ** mailer). 77 ** M_STRIPQ -- if set, strip quote (`"') 78 ** characters out of parameters as you 79 ** transliterate them into the argument 80 ** vector. For example, the local mailer 81 ** is called directly, so these should be 82 ** stripped, but the program-mailer (i.e., 83 ** csh) should leave them in. 84 ** M_NEEDDATE -- this mailer requires a Date: 85 ** field in the message. 86 ** M_NEEDFROM -- this mailer requires a From: 87 ** field in the message. 88 ** M_MSGID -- this mailer requires a Message-Id 89 ** field in the message. 90 ** M_COMMAS -- this mailer wants comma- 91 ** seperated To: and Cc: fields. 92 ** M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID| 93 ** M_COMMAS. 94 ** - an exit status to use as the code for the 95 ** error message print if the mailer returns 96 ** something we don't understand. 97 ** - A list of names that are to be considered 98 ** "local" (and hence are stripped off) for 99 ** this mailer. 100 ** - An argument vector to be passed to the 101 ** mailer with the following substitutions: 102 ** $f - the from person name. 103 ** $u - the target user name. 104 ** $h - the target user host. 105 ** $c - the hop count. 106 ** >>>>>>>>>> Entry zero must be for the local 107 ** >> NOTE >> mailer and entry one must be for 108 ** >>>>>>>>>> the shell. 109 ** ParseTab -- a table driving the parsing process. Each 110 ** entry contains: 111 ** - a character that will trigger this entry. 112 ** - an index into the Mailer table. 113 ** - a word of flags, described in postbox.h. 114 ** - an argument. If we have P_MAP, it is the 115 ** character to turn the trigger character into. 116 ** If we have P_MOVE, it is the site to send it 117 ** to, using the mailer specified above. 118 ** This table will almost certainly have to be 119 ** changed on your site if you have anything more 120 ** than the UUCP net. 121 ** HdrInfo -- a table describing well-known header fields. 122 ** Each entry has the field name and some flags, 123 ** which can be: 124 ** - H_EOH -- this field is equivalent to a blank 125 ** line; i.e., it signifies end of header. 126 ** - H_DELETE -- delete this field. 127 ** There is also a field pointing to a pointer 128 ** that should be set to point to this header. 129 */ 130 131 132 133 134 static char SccsId[] = "@(#)conf.c 3.6 03/07/81"; 135 136 137 # include <whoami.h> /* definitions of machine id's at berkeley */ 138 139 # ifdef BERKELEY 140 141 char *ArpaHost = "Berkeley"; /* host name of gateway on Arpanet */ 142 # define BerkHost MyLocName /* host name of gateway on Berk net */ 143 # define NETV6MAIL /* use /usr/net/bin/v6mail for local delivery */ 144 145 /* Specific Configurations for Berkeley Machines */ 146 147 /* Berkeley people: mail changes to ingvax:eric or they will be lost! */ 148 149 # ifdef ING70 150 # include "c.ing70.h" 151 # endif ING70 152 153 # ifdef INGVAX 154 # include "c.ingvax.h" 155 # endif INGVAX 156 157 # ifdef CSVAX 158 # include "c.csvax.h" 159 # endif CSVAX 160 161 # ifdef ARPAVAX 162 # include "c.arpavax.h" 163 # endif ARPAVAX 164 165 # ifdef CORY 166 # include "c.cory.h" 167 # endif CORY 168 169 # ifdef ONYX 170 # include "c.onyx.h" 171 # endif ONYX 172 173 # ifdef IMAGE 174 # include "c.image.h" 175 # endif IMAGE 176 177 # ifdef ESVAX 178 # include "c.esvax.h" 179 # endif ESVAX 180 181 # ifdef EECS40 182 # include "c.eecs40.h" 183 # endif EECS40 184 185 # else BERKELEY 186 187 char *ArpaHost = "[unknown]"; 188 char *MyLocName = sysname; 189 # define HASUUCP /* default to having UUCP net */ 190 char *UucpLocal[] = { sysname, NULL }; 191 # define BerkMerge NULL /* don't merge any berknet sites */ 192 # define UucpMerge NULL /* don't merge any UUCP sites */ 193 194 # endif BERKELEY 195 196 197 198 # ifndef HASARPA 199 # define ArpaLocal NULL 200 # endif HASARPA 201 202 # ifndef HASUUCP 203 # define UucpLocal NULL 204 # endif HASUUCP 205 206 207 /* local mail -- must be #0 */ 208 static char *LocalArgv[] = 209 { 210 "...local%mail", 211 "-d", 212 "$u", 213 NULL 214 }; 215 216 static struct mailer LocalMailer = 217 { 218 # ifdef NETV6MAIL 219 "/usr/net/bin/v6mail", 220 # else 221 "/bin/mail", 222 # endif 223 M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, EX_NOUSER, NULL, 224 "$f", NULL, LocalArgv, 225 }; 226 227 /* pipes through programs -- must be #1 */ 228 static char *ProgArgv[] = 229 { 230 "...prog%mail", 231 "-fc", 232 "$u", 233 NULL 234 }; 235 236 static struct mailer ProgMailer = 237 { 238 "/bin/csh", 239 M_HDR|M_FHDR|M_NOHOST, EX_UNAVAILABLE, NULL, 240 "$f", NULL, ProgArgv, 241 }; 242 243 /* local berkeley mail */ 244 static char *BerkArgv[] = 245 { 246 "...berk%mail", 247 "-m", 248 "$h", 249 "-t", 250 "$u", 251 "-h", 252 "$c", 253 NULL 254 }; 255 256 static struct mailer BerkMailer = 257 { 258 "/usr/net/bin/sendberkmail", 259 M_FOPT|M_HDR|M_STRIPQ, EX_UNAVAILABLE, BerkLocal, 260 "$B:$f", BerkMerge, BerkArgv, 261 }; 262 263 /* arpanet mail */ 264 static char *ArpaArgv[] = 265 { 266 "...arpa%mail", 267 "$f", 268 "$h", 269 "$u", 270 NULL 271 }; 272 273 static struct mailer ArpaMailer = 274 { 275 "/usr/lib/mailers/arpa", 276 M_STRIPQ|M_ARPAFMT, 0, ArpaLocal, 277 "$f@$A", NULL, ArpaArgv, 278 }; 279 280 /* uucp mail (cheat & use Bell's v7 mail) */ 281 static char *UucpArgv[] = 282 { 283 "...uucp%mail", 284 # ifdef DUMBMAIL 285 "-d", 286 # endif DUMBMAIL 287 "$h!$u", 288 NULL 289 }; 290 291 static struct mailer UucpMailer = 292 { 293 "/bin/mail", 294 M_ROPT|M_STRIPQ, EX_NOUSER, UucpLocal, 295 "$U!$f", UucpMerge, UucpArgv, 296 }; 297 298 struct mailer *Mailer[] = 299 { 300 &LocalMailer, /* 0 -- must be 0 */ 301 &ProgMailer, /* 1 -- must be 1 */ 302 &BerkMailer, /* 2 */ 303 &ArpaMailer, /* 3 */ 304 &UucpMailer, /* 4 */ 305 }; 306 307 # define NMAILERS (sizeof Mailer / sizeof Mailer[0]) 308 309 # define M_LOCAL 0 310 # define M_PROG 1 311 # define M_BERK 2 312 # define M_ARPA 3 313 # define M_UUCP 4 314 315 /* list of messages for each mailer (sorted by host) */ 316 ADDRESS MailList[NMAILERS]; 317 318 319 320 # ifdef BERKELEY 321 struct parsetab ParseTab[] = 322 { 323 ':', M_BERK, P_ONE, NULL, 324 # ifdef HASARPA 325 '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 326 # else 327 '@', M_BERK, P_HLAST|P_USR_UPPER|P_MOVE, "ing70", 328 # endif HASARPA 329 '^', -1, P_MAP, "!", 330 # ifdef HASUUCP 331 '!', M_UUCP, 0, NULL, 332 # else 333 '!', M_BERK, P_MOVE, "csvax", 334 # endif HASUUCP 335 '.', -1, P_MAP|P_ONE, ":", 336 '\0', M_LOCAL, P_MOVE, "", 337 }; 338 # else BERKELEY 339 struct parsetab ParseTab[] = 340 { 341 # ifdef HASARPA 342 '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, 343 # endif HASARPA 344 # ifdef HASUUCP 345 '^', -1, P_MAP, "!", 346 '!', M_UUCP, 0, NULL, 347 # endif HASUUCP 348 '\0', M_LOCAL, P_MOVE, "", 349 }; 350 # endif BERKELEY 351 352 353 /* 354 ** Header info table 355 ** Final (null) entry contains the flags used for any other field. 356 */ 357 358 struct hdrinfo HdrInfo[] = 359 { 360 "date", 0, NULL, 361 "from", 0, NULL, 362 "to", 0, NULL, 363 "cc", 0, NULL, 364 "subject", 0, NULL, 365 "message-id", 0, &MsgId, 366 "message", H_EOH, NULL, 367 NULL, 0, NULL, 368 }; 369 /* 370 ** INITMACS -- initialize predefined macros. 371 ** 372 ** Parameters: 373 ** none. 374 ** 375 ** Returns: 376 ** none. 377 ** 378 ** Side Effects: 379 ** Macros array gets initialized. 380 */ 381 382 char *Macro[26]; 383 384 # define MACRO(x) Macro[x - 'A'] 385 386 initmacs() 387 { 388 MACRO('A') = ArpaHost; 389 MACRO('B') = BerkHost; 390 MACRO('U') = UucpHost; 391 } 392 393 # ifdef V6 394 /* 395 ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 396 ** 397 ** Returns the pathname of the user's tty. Returns NULL if 398 ** the user is not logged in or if s/he has write permission 399 ** denied. 400 ** 401 ** Parameters: 402 ** none 403 ** 404 ** Returns: 405 ** pathname of the user's tty. 406 ** NULL if not logged in or write permission denied. 407 ** 408 ** Side Effects: 409 ** none. 410 ** 411 ** WARNING: 412 ** Return value is in a local buffer. 413 ** 414 ** Called By: 415 ** savemail 416 */ 417 418 # include <sys/types.h> 419 # include <sys/stat.h> 420 421 char * 422 ttypath() 423 { 424 struct stat stbuf; 425 register int i; 426 static char pathn[] = "/dev/ttyx"; 427 extern int errno; 428 429 /* compute the pathname of the controlling tty */ 430 if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 431 { 432 errno = 0; 433 return (NULL); 434 } 435 pathn[8] = i; 436 437 /* see if we have write permission */ 438 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 439 { 440 errno = 0; 441 return (NULL); 442 } 443 444 /* see if the user is logged in */ 445 if (getlogin() == NULL) 446 return (NULL); 447 448 /* looks good */ 449 return (pathn); 450 } 451 /* 452 ** FDOPEN -- Open a stdio file given an open file descriptor. 453 ** 454 ** This is included here because it is standard in v7, but we 455 ** need it in v6. 456 ** 457 ** Algorithm: 458 ** Open /dev/null to create a descriptor. 459 ** Close that descriptor. 460 ** Copy the existing fd into the descriptor. 461 ** 462 ** Parameters: 463 ** fd -- the open file descriptor. 464 ** type -- "r", "w", or whatever. 465 ** 466 ** Returns: 467 ** The file descriptor it creates. 468 ** 469 ** Side Effects: 470 ** none 471 ** 472 ** Called By: 473 ** deliver 474 ** 475 ** Notes: 476 ** The mode of fd must match "type". 477 */ 478 479 FILE * 480 fdopen(fd, type) 481 int fd; 482 char *type; 483 { 484 register FILE *f; 485 486 f = fopen("/dev/null", type); 487 close(fileno(f)); 488 fileno(f) = fd; 489 return (f); 490 } 491 /* 492 ** INDEX -- Return pointer to character in string 493 ** 494 ** For V7 compatibility. 495 ** 496 ** Parameters: 497 ** s -- a string to scan. 498 ** c -- a character to look for. 499 ** 500 ** Returns: 501 ** If c is in s, returns the address of the first 502 ** instance of c in s. 503 ** NULL if c is not in s. 504 ** 505 ** Side Effects: 506 ** none. 507 */ 508 509 index(s, c) 510 register char *s; 511 register char c; 512 { 513 while (*s != '\0') 514 { 515 if (*s++ == c) 516 return (--s); 517 } 518 return (NULL); 519 } 520 # endif V6 521 522 # ifndef V6 523 /* 524 ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 525 ** 526 ** Returns the pathname of the user's tty. Returns NULL if 527 ** the user is not logged in or if s/he has write permission 528 ** denied. 529 ** 530 ** Parameters: 531 ** none 532 ** 533 ** Returns: 534 ** pathname of the user's tty. 535 ** NULL if not logged in or write permission denied. 536 ** 537 ** Side Effects: 538 ** none. 539 ** 540 ** WARNING: 541 ** Return value is in a local buffer. 542 ** 543 ** Called By: 544 ** savemail 545 */ 546 547 # include <sys/types.h> 548 # include <sys/stat.h> 549 550 char * 551 ttypath() 552 { 553 struct stat stbuf; 554 register char *pathn; 555 extern int errno; 556 extern char *ttyname(); 557 558 /* compute the pathname of the controlling tty */ 559 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 560 { 561 errno = 0; 562 return (NULL); 563 } 564 565 /* see if we have write permission */ 566 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 567 { 568 errno = 0; 569 return (NULL); 570 } 571 572 /* see if the user is logged in */ 573 if (getlogin() == NULL) 574 return (NULL); 575 576 /* looks good */ 577 return (pathn); 578 } 579 # endif V6 580 /* 581 ** CHECKCOMPAT -- check for From and To person compatible. 582 ** 583 ** This routine can be supplied on a per-installation basis 584 ** to determine whether a person is allowed to send a message. 585 ** This allows restriction of certain types of internet 586 ** forwarding or registration of users. 587 ** 588 ** If the hosts are found to be incompatible, an error 589 ** message should be given using "usrerr" and FALSE should 590 ** be returned. 591 ** 592 ** Parameters: 593 ** to -- the person being sent to. 594 ** 595 ** Returns: 596 ** TRUE -- ok to send. 597 ** FALSE -- not ok. 598 ** 599 ** Side Effects: 600 ** none (unless you include the usrerr stuff) 601 */ 602 603 bool 604 checkcompat(to) 605 register ADDRESS *to; 606 { 607 return (TRUE); 608 } 609