home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65 / src / conf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  10.8 KB  |  566 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted provided
  7.  * that: (1) source distributions retain this entire copyright notice and
  8.  * comment, and (2) distributions including binaries display the following
  9.  * acknowledgement:  ``This product includes software developed by the
  10.  * University of California, Berkeley and its contributors'' in the
  11.  * documentation or other materials provided with the distribution and in
  12.  * all advertising materials mentioning features or use of this software.
  13.  * Neither the name of the University nor the names of its contributors may
  14.  * be used to endorse or promote products derived from this software without
  15.  * specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)conf.c    5.26 (Berkeley) 6/1/90";
  23. #endif /* not lint */
  24.  
  25. # include <sys/ioctl.h>
  26. # include <sys/param.h>
  27. # include <pwd.h>
  28. # include "sendmail.h"
  29. # include "pathnames.h"
  30.  
  31. /*
  32. **  CONF.C -- Sendmail Configuration Tables.
  33. **
  34. **    Defines the configuration of this installation.
  35. **
  36. **    Compilation Flags:
  37. **        VMUNIX -- running on a Berkeley UNIX system.
  38. **
  39. **    Configuration Variables:
  40. **        HdrInfo -- a table describing well-known header fields.
  41. **            Each entry has the field name and some flags,
  42. **            which are described in sendmail.h.
  43. **
  44. **    Notes:
  45. **        I have tried to put almost all the reasonable
  46. **        configuration information into the configuration
  47. **        file read at runtime.  My intent is that anything
  48. **        here is a function of the version of UNIX you
  49. **        are running, or is really static -- for example
  50. **        the headers are a superset of widely used
  51. **        protocols.  If you find yourself playing with
  52. **        this file too much, you may be making a mistake!
  53. */
  54.  
  55.  
  56.  
  57.  
  58. /*
  59. **  Header info table
  60. **    Final (null) entry contains the flags used for any other field.
  61. **
  62. **    Not all of these are actually handled specially by sendmail
  63. **    at this time.  They are included as placeholders, to let
  64. **    you know that "someday" I intend to have sendmail do
  65. **    something with them.
  66. */
  67.  
  68. struct hdrinfo    HdrInfo[] =
  69. {
  70.         /* originator fields, most to least significant  */
  71.     "resent-sender",    H_FROM|H_RESENT,
  72.     "resent-from",        H_FROM|H_RESENT,
  73.     "resent-reply-to",    H_FROM|H_RESENT,
  74.     "sender",        H_FROM,
  75.     "from",            H_FROM,
  76.     "reply-to",        H_FROM,
  77.     "full-name",        H_ACHECK,
  78.     "return-receipt-to",    H_FROM,
  79.     "errors-to",        H_FROM,
  80.         /* destination fields */
  81.     "to",            H_RCPT,
  82.     "resent-to",        H_RCPT|H_RESENT,
  83.     "cc",            H_RCPT,
  84.     "resent-cc",        H_RCPT|H_RESENT,
  85.     "bcc",            H_RCPT|H_ACHECK,
  86.     "resent-bcc",        H_RCPT|H_ACHECK|H_RESENT,
  87.         /* message identification and control */
  88.     "message-id",        0,
  89.     "resent-message-id",    H_RESENT,
  90.     "message",        H_EOH,
  91.     "text",            H_EOH,
  92.         /* date fields */
  93.     "date",            0,
  94.     "resent-date",        H_RESENT,
  95.         /* trace fields */
  96.     "received",        H_TRACE|H_FORCE,
  97.     "via",            H_TRACE|H_FORCE,
  98.     "mail-from",        H_TRACE|H_FORCE,
  99.  
  100.     NULL,            0,
  101. };
  102.  
  103.  
  104. /*
  105. **  ARPANET error message numbers.
  106. */
  107.  
  108. char    Arpa_Info[] =        "050";    /* arbitrary info */
  109. char    Arpa_TSyserr[] =    "451";    /* some (transient) system error */
  110. char    Arpa_PSyserr[] =    "554";    /* some (permanent) system error */
  111. char    Arpa_Usrerr[] =        "554";    /* some (fatal) user error */
  112.  
  113.  
  114.  
  115. /*
  116. **  Location of system files/databases/etc.
  117. */
  118.  
  119. char    *ConfFile =    _PATH_SENDMAILCF;    /* runtime configuration */
  120. char    *FreezeFile =    _PATH_SENDMAILFC;    /* frozen version of above */
  121.  
  122.  
  123.  
  124. /*
  125. **  Miscellaneous stuff.
  126. */
  127.  
  128. int    DtableSize =    50;        /* max open files; reset in 4.2bsd */
  129. extern int la;                /* load average */
  130. /*
  131. **  SETDEFAULTS -- set default values
  132. **
  133. **    Because of the way freezing is done, these must be initialized
  134. **    using direct code.
  135. **
  136. **    Parameters:
  137. **        none.
  138. **
  139. **    Returns:
  140. **        none.
  141. **
  142. **    Side Effects:
  143. **        Initializes a bunch of global variables to their
  144. **        default values.
  145. */
  146.  
  147. setdefaults()
  148. {
  149.     QueueLA = 8;
  150.     QueueFactor = 10000;
  151.     RefuseLA = 12;
  152.     SpaceSub = ' ';
  153.     WkRecipFact = 1000;
  154.     WkClassFact = 1800;
  155.     WkTimeFact = 9000;
  156.     FileMode = 0644;
  157.     DefUid = 1;
  158.     DefGid = 1;
  159.     setdefuser();
  160. }
  161.  
  162.  
  163. /*
  164. **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
  165. */
  166.  
  167. setdefuser()
  168. {
  169.     struct passwd *defpwent;
  170.  
  171.     if (DefUser != NULL)
  172.         free(DefUser);
  173.     if ((defpwent = getpwuid(DefUid)) != NULL)
  174.         DefUser = newstr(defpwent->pw_name);
  175.     else
  176.         DefUser = newstr("nobody");
  177. }
  178.  
  179.  
  180. /*
  181. **  GETRUID -- get real user id (V7)
  182. */
  183.  
  184. getruid()
  185. {
  186.     if (OpMode == MD_DAEMON)
  187.         return (RealUid);
  188.     else
  189.         return (getuid());
  190. }
  191.  
  192.  
  193. /*
  194. **  GETRGID -- get real group id (V7).
  195. */
  196.  
  197. getrgid()
  198. {
  199.     if (OpMode == MD_DAEMON)
  200.         return (RealGid);
  201.     else
  202.         return (getgid());
  203. }
  204.  
  205. /*
  206. **  USERNAME -- return the user id of the logged in user.
  207. **
  208. **    Parameters:
  209. **        none.
  210. **
  211. **    Returns:
  212. **        The login name of the logged in user.
  213. **
  214. **    Side Effects:
  215. **        none.
  216. **
  217. **    Notes:
  218. **        The return value is statically allocated.
  219. */
  220.  
  221. char *
  222. username()
  223. {
  224.     static char *myname = NULL;
  225.     extern char *getlogin();
  226.     register struct passwd *pw;
  227.     extern struct passwd *getpwuid();
  228.  
  229.     /* cache the result */
  230.     if (myname == NULL)
  231.     {
  232.         myname = getlogin();
  233.         if (myname == NULL || myname[0] == '\0')
  234.         {
  235.  
  236.             pw = getpwuid(getruid());
  237.             if (pw != NULL)
  238.                 myname = newstr(pw->pw_name);
  239.         }
  240.         else
  241.         {
  242.  
  243.             myname = newstr(myname);
  244.             if ((pw = getpwnam(myname)) == NULL ||
  245.                   getuid() != pw->pw_uid)
  246.             {
  247.                 pw = getpwuid(getuid());
  248.                 if (pw != NULL)
  249.                     myname = newstr(pw->pw_name);
  250.             }
  251.         }
  252.         if (myname == NULL || myname[0] == '\0')
  253.         {
  254.             syserr("Who are you?");
  255.             myname = "postmaster";
  256.         }
  257.     }
  258.  
  259.     return (myname);
  260. }
  261. /*
  262. **  TTYPATH -- Get the path of the user's tty
  263. **
  264. **    Returns the pathname of the user's tty.  Returns NULL if
  265. **    the user is not logged in or if s/he has write permission
  266. **    denied.
  267. **
  268. **    Parameters:
  269. **        none
  270. **
  271. **    Returns:
  272. **        pathname of the user's tty.
  273. **        NULL if not logged in or write permission denied.
  274. **
  275. **    Side Effects:
  276. **        none.
  277. **
  278. **    WARNING:
  279. **        Return value is in a local buffer.
  280. **
  281. **    Called By:
  282. **        savemail
  283. */
  284.  
  285. # include <sys/stat.h>
  286.  
  287. char *
  288. ttypath()
  289. {
  290.     struct stat stbuf;
  291.     register char *pathn;
  292.     extern char *ttyname();
  293.     extern char *getlogin();
  294.  
  295.     /* compute the pathname of the controlling tty */
  296.     if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
  297.         (pathn = ttyname(0)) == NULL)
  298.     {
  299.         errno = 0;
  300.         return (NULL);
  301.     }
  302.  
  303.     /* see if we have write permission */
  304.     if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
  305.     {
  306.         errno = 0;
  307.         return (NULL);
  308.     }
  309.  
  310.     /* see if the user is logged in */
  311.     if (getlogin() == NULL)
  312.         return (NULL);
  313.  
  314.     /* looks good */
  315.     return (pathn);
  316. }
  317. /*
  318. **  CHECKCOMPAT -- check for From and To person compatible.
  319. **
  320. **    This routine can be supplied on a per-installation basis
  321. **    to determine whether a person is allowed to send a message.
  322. **    This allows restriction of certain types of internet
  323. **    forwarding or registration of users.
  324. **
  325. **    If the hosts are found to be incompatible, an error
  326. **    message should be given using "usrerr" and FALSE should
  327. **    be returned.
  328. **
  329. **    'NoReturn' can be set to suppress the return-to-sender
  330. **    function; this should be done on huge messages.
  331. **
  332. **    Parameters:
  333. **        to -- the person being sent to.
  334. **
  335. **    Returns:
  336. **        TRUE -- ok to send.
  337. **        FALSE -- not ok.
  338. **
  339. **    Side Effects:
  340. **        none (unless you include the usrerr stuff)
  341. */
  342.  
  343. bool
  344. checkcompat(to)
  345.     register ADDRESS *to;
  346. {
  347. # ifdef lint
  348.     if (to == NULL)
  349.         to++;
  350. # endif lint
  351. # ifdef EXAMPLE_CODE
  352.     /* this code is intended as an example only */
  353.     register STAB *s;
  354.  
  355.     s = stab("arpa", ST_MAILER, ST_FIND);
  356.     if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
  357.         to->q_mailer == s->s_mailer)
  358.     {
  359.         usrerr("No ARPA mail through this machine: see your system administration");
  360.         /* NoReturn = TRUE; to supress return copy */
  361.         return (FALSE);
  362.     }
  363. # endif EXAMPLE_CODE
  364.     return (TRUE);
  365. }
  366. /*
  367. **  HOLDSIGS -- arrange to hold all signals
  368. **
  369. **    Parameters:
  370. **        none.
  371. **
  372. **    Returns:
  373. **        none.
  374. **
  375. **    Side Effects:
  376. **        Arranges that signals are held.
  377. */
  378.  
  379. holdsigs()
  380. {
  381. }
  382. /*
  383. **  RLSESIGS -- arrange to release all signals
  384. **
  385. **    This undoes the effect of holdsigs.
  386. **
  387. **    Parameters:
  388. **        none.
  389. **
  390. **    Returns:
  391. **        none.
  392. **
  393. **    Side Effects:
  394. **        Arranges that signals are released.
  395. */
  396.  
  397. rlsesigs()
  398. {
  399. }
  400. /*
  401. **  GETLA -- get the current load average
  402. **
  403. **    This code stolen from la.c.
  404. **
  405. **    Parameters:
  406. **        none.
  407. **
  408. **    Returns:
  409. **        The current load average as an integer.
  410. **
  411. **    Side Effects:
  412. **        none.
  413. */
  414.  
  415. #ifndef sun
  416.  
  417. getla()
  418. {
  419.     double avenrun[3];
  420.  
  421.     if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
  422.         return (0);
  423.     return ((int) (avenrun[0] + 0.5));
  424. }
  425.  
  426. #else /* sun */
  427.  
  428. #include <nlist.h>
  429.  
  430. struct    nlist Nl[] =
  431. {
  432.     { "_avenrun" },
  433. #define    X_AVENRUN    0
  434.     { 0 },
  435. };
  436.  
  437.  
  438. extern int la;
  439.  
  440. getla()
  441. {
  442.     static int kmem = -1;
  443.     long avenrun[3];
  444.     extern off_t lseek();
  445.  
  446.     if (kmem < 0)
  447.     {
  448.         kmem = open("/dev/kmem", 0, 0);
  449.         if (kmem < 0)
  450.             return (-1);
  451.         (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
  452.         nlist("/vmunix", Nl);
  453.         if (Nl[0].n_type == 0)
  454.             return (-1);
  455.     }
  456.     if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
  457.         read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
  458.     {
  459.         /* thank you Ian */
  460.         return (-1);
  461.     }
  462.     return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
  463. }
  464.  
  465. #endif /* sun */
  466. /*
  467. **  SHOULDQUEUE -- should this message be queued or sent?
  468. **
  469. **    Compares the message cost to the load average to decide.
  470. **
  471. **    Parameters:
  472. **        pri -- the priority of the message in question.
  473. **
  474. **    Returns:
  475. **        TRUE -- if this message should be queued up for the
  476. **            time being.
  477. **        FALSE -- if the load is low enough to send this message.
  478. **
  479. **    Side Effects:
  480. **        none.
  481. */
  482.  
  483. bool
  484. shouldqueue(pri)
  485.     long pri;
  486. {
  487.     if (la < QueueLA)
  488.         return (FALSE);
  489.     return (pri > (QueueFactor / (la - QueueLA + 1)));
  490. }
  491. /*
  492. **  SETPROCTITLE -- set process title for ps
  493. **
  494. **    Parameters:
  495. **        fmt -- a printf style format string.
  496. **        a, b, c -- possible parameters to fmt.
  497. **
  498. **    Returns:
  499. **        none.
  500. **
  501. **    Side Effects:
  502. **        Clobbers argv of our main procedure so ps(1) will
  503. **        display the title.
  504. */
  505.  
  506. /*VARARGS1*/
  507. setproctitle(fmt, a, b, c)
  508.     char *fmt;
  509. {
  510. # ifdef SETPROCTITLE
  511.     register char *p;
  512.     register int i;
  513.     extern char **Argv;
  514.     extern char *LastArgv;
  515.     char buf[MAXLINE];
  516.  
  517.     (void) sprintf(buf, fmt, a, b, c);
  518.  
  519.     /* make ps print "(sendmail)" */
  520.     p = Argv[0];
  521.     *p++ = '-';
  522.  
  523.     i = strlen(buf);
  524.     if (i > LastArgv - p - 2)
  525.     {
  526.         i = LastArgv - p - 2;
  527.         buf[i] = '\0';
  528.     }
  529.     (void) strcpy(p, buf);
  530.     p += i;
  531.     while (p < LastArgv)
  532.         *p++ = ' ';
  533. # endif SETPROCTITLE
  534. }
  535. /*
  536. **  REAPCHILD -- pick up the body of my child, lest it become a zombie
  537. **
  538. **    Parameters:
  539. **        none.
  540. **
  541. **    Returns:
  542. **        none.
  543. **
  544. **    Side Effects:
  545. **        Picks up extant zombies.
  546. */
  547.  
  548. # ifdef VMUNIX
  549. # include <sys/wait.h>
  550. # endif VMUNIX
  551.  
  552. reapchild()
  553. {
  554. # ifdef WNOHANG
  555.     union wait status;
  556.  
  557.     while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
  558.         continue;
  559. # else WNOHANG
  560.     auto int status;
  561.  
  562.     while (wait(&status) > 0)
  563.         continue;
  564. # endif WNOHANG
  565. }
  566.