Annotation of 43BSD/usr.lib/sendmail/src/conf.c, revision 1.1.1.1

1.1       root        1: /*
                      2: **  Sendmail
                      3: **  Copyright (c) 1983  Eric P. Allman
                      4: **  Berkeley, California
                      5: **
                      6: **  Copyright (c) 1983 Regents of the University of California.
                      7: **  All rights reserved.  The Berkeley software License Agreement
                      8: **  specifies the terms and conditions for redistribution.
                      9: */
                     10: 
                     11: #ifndef lint
                     12: static char    SccsId[] = "@(#)conf.c  5.14 (Berkeley) 1/10/86";
                     13: #endif not lint
                     14: 
                     15: # include <pwd.h>
                     16: # include <sys/ioctl.h>
                     17: # ifdef sun
                     18: # include <sys/param.h>
                     19: # endif sun
                     20: # include "sendmail.h"
                     21: 
                     22: /*
                     23: **  CONF.C -- Sendmail Configuration Tables.
                     24: **
                     25: **     Defines the configuration of this installation.
                     26: **
                     27: **     Compilation Flags:
                     28: **             V6 -- running on a version 6 system.  This determines
                     29: **                     whether to define certain routines between
                     30: **                     the two systems.  If you are running a funny
                     31: **                     system, e.g., V6 with long tty names, this
                     32: **                     should be checked carefully.
                     33: **             VMUNIX -- running on a Berkeley UNIX system.
                     34: **
                     35: **     Configuration Variables:
                     36: **             HdrInfo -- a table describing well-known header fields.
                     37: **                     Each entry has the field name and some flags,
                     38: **                     which are described in sendmail.h.
                     39: **
                     40: **     Notes:
                     41: **             I have tried to put almost all the reasonable
                     42: **             configuration information into the configuration
                     43: **             file read at runtime.  My intent is that anything
                     44: **             here is a function of the version of UNIX you
                     45: **             are running, or is really static -- for example
                     46: **             the headers are a superset of widely used
                     47: **             protocols.  If you find yourself playing with
                     48: **             this file too much, you may be making a mistake!
                     49: */
                     50: 
                     51: 
                     52: 
                     53: 
                     54: /*
                     55: **  Header info table
                     56: **     Final (null) entry contains the flags used for any other field.
                     57: **
                     58: **     Not all of these are actually handled specially by sendmail
                     59: **     at this time.  They are included as placeholders, to let
                     60: **     you know that "someday" I intend to have sendmail do
                     61: **     something with them.
                     62: */
                     63: 
                     64: struct hdrinfo HdrInfo[] =
                     65: {
                     66:                /* originator fields, most to least significant  */
                     67:        "resent-sender",        H_FROM|H_RESENT,
                     68:        "resent-from",          H_FROM|H_RESENT,
                     69:        "resent-reply-to",      H_FROM|H_RESENT,
                     70:        "sender",               H_FROM,
                     71:        "from",                 H_FROM,
                     72:        "reply-to",             H_FROM,
                     73:        "full-name",            H_ACHECK,
                     74:        "return-receipt-to",    H_FROM,
                     75:        "errors-to",            H_FROM,
                     76:                /* destination fields */
                     77:        "to",                   H_RCPT,
                     78:        "resent-to",            H_RCPT|H_RESENT,
                     79:        "cc",                   H_RCPT,
                     80:        "resent-cc",            H_RCPT|H_RESENT,
                     81:        "bcc",                  H_RCPT|H_ACHECK,
                     82:        "resent-bcc",           H_RCPT|H_ACHECK|H_RESENT,
                     83:                /* message identification and control */
                     84:        "message-id",           0,
                     85:        "resent-message-id",    H_RESENT,
                     86:        "message",              H_EOH,
                     87:        "text",                 H_EOH,
                     88:                /* date fields */
                     89:        "date",                 0,
                     90:        "resent-date",          H_RESENT,
                     91:                /* trace fields */
                     92:        "received",             H_TRACE|H_FORCE,
                     93:        "via",                  H_TRACE|H_FORCE,
                     94:        "mail-from",            H_TRACE|H_FORCE,
                     95: 
                     96:        NULL,                   0,
                     97: };
                     98: 
                     99: 
                    100: /*
                    101: **  ARPANET error message numbers.
                    102: */
                    103: 
                    104: char   Arpa_Info[] =           "050";  /* arbitrary info */
                    105: char   Arpa_TSyserr[] =        "451";  /* some (transient) system error */
                    106: char   Arpa_PSyserr[] =        "554";  /* some (permanent) system error */
                    107: char   Arpa_Usrerr[] =         "554";  /* some (fatal) user error */
                    108: 
                    109: 
                    110: 
                    111: /*
                    112: **  Location of system files/databases/etc.
                    113: */
                    114: 
                    115: char   *ConfFile =     "/usr/lib/sendmail.cf"; /* runtime configuration */
                    116: char   *FreezeFile =   "/usr/lib/sendmail.fc"; /* frozen version of above */
                    117: 
                    118: 
                    119: 
                    120: /*
                    121: **  Miscellaneous stuff.
                    122: */
                    123: 
                    124: int    DtableSize =    50;             /* max open files; reset in 4.2bsd */
                    125: /*
                    126: **  SETDEFAULTS -- set default values
                    127: **
                    128: **     Because of the way freezing is done, these must be initialized
                    129: **     using direct code.
                    130: **
                    131: **     Parameters:
                    132: **             none.
                    133: **
                    134: **     Returns:
                    135: **             none.
                    136: **
                    137: **     Side Effects:
                    138: **             Initializes a bunch of global variables to their
                    139: **             default values.
                    140: */
                    141: 
                    142: setdefaults()
                    143: {
                    144:        QueueLA = 8;
                    145:        QueueFactor = 10000;
                    146:        RefuseLA = 12;
                    147:        SpaceSub = ' ';
                    148:        WkRecipFact = 1000;
                    149:        WkClassFact = 1800;
                    150:        WkTimeFact = 9000;
                    151:        FileMode = 0644;
                    152:        DefUid = 1;
                    153:        DefGid = 1;
                    154: }
                    155: 
                    156: # ifdef V6
                    157: /*
                    158: **  TTYNAME -- return name of terminal.
                    159: **
                    160: **     Parameters:
                    161: **             fd -- file descriptor to check.
                    162: **
                    163: **     Returns:
                    164: **             pointer to full path of tty.
                    165: **             NULL if no tty.
                    166: **
                    167: **     Side Effects:
                    168: **             none.
                    169: */
                    170: 
                    171: char *
                    172: ttyname(fd)
                    173:        int fd;
                    174: {
                    175:        register char tn;
                    176:        static char pathn[] = "/dev/ttyx";
                    177: 
                    178:        /* compute the pathname of the controlling tty */
                    179:        if ((tn = ttyn(fd)) == NULL)
                    180:        {
                    181:                errno = 0;
                    182:                return (NULL);
                    183:        }
                    184:        pathn[8] = tn;
                    185:        return (pathn);
                    186: }
                    187: /*
                    188: **  FDOPEN -- Open a stdio file given an open file descriptor.
                    189: **
                    190: **     This is included here because it is standard in v7, but we
                    191: **     need it in v6.
                    192: **
                    193: **     Algorithm:
                    194: **             Open /dev/null to create a descriptor.
                    195: **             Close that descriptor.
                    196: **             Copy the existing fd into the descriptor.
                    197: **
                    198: **     Parameters:
                    199: **             fd -- the open file descriptor.
                    200: **             type -- "r", "w", or whatever.
                    201: **
                    202: **     Returns:
                    203: **             The file descriptor it creates.
                    204: **
                    205: **     Side Effects:
                    206: **             none
                    207: **
                    208: **     Called By:
                    209: **             deliver
                    210: **
                    211: **     Notes:
                    212: **             The mode of fd must match "type".
                    213: */
                    214: 
                    215: FILE *
                    216: fdopen(fd, type)
                    217:        int fd;
                    218:        char *type;
                    219: {
                    220:        register FILE *f;
                    221: 
                    222:        f = fopen("/dev/null", type);
                    223:        (void) close(fileno(f));
                    224:        fileno(f) = fd;
                    225:        return (f);
                    226: }
                    227: /*
                    228: **  INDEX -- Return pointer to character in string
                    229: **
                    230: **     For V7 compatibility.
                    231: **
                    232: **     Parameters:
                    233: **             s -- a string to scan.
                    234: **             c -- a character to look for.
                    235: **
                    236: **     Returns:
                    237: **             If c is in s, returns the address of the first
                    238: **                     instance of c in s.
                    239: **             NULL if c is not in s.
                    240: **
                    241: **     Side Effects:
                    242: **             none.
                    243: */
                    244: 
                    245: char *
                    246: index(s, c)
                    247:        register char *s;
                    248:        register char c;
                    249: {
                    250:        while (*s != '\0')
                    251:        {
                    252:                if (*s++ == c)
                    253:                        return (--s);
                    254:        }
                    255:        return (NULL);
                    256: }
                    257: /*
                    258: **  UMASK -- fake the umask system call.
                    259: **
                    260: **     Since V6 always acts like the umask is zero, we will just
                    261: **     assume the same thing.
                    262: */
                    263: 
                    264: /*ARGSUSED*/
                    265: umask(nmask)
                    266: {
                    267:        return (0);
                    268: }
                    269: 
                    270: 
                    271: /*
                    272: **  GETRUID -- get real user id.
                    273: */
                    274: 
                    275: getruid()
                    276: {
                    277:        return (getuid() & 0377);
                    278: }
                    279: 
                    280: 
                    281: /*
                    282: **  GETRGID -- get real group id.
                    283: */
                    284: 
                    285: getrgid()
                    286: {
                    287:        return (getgid() & 0377);
                    288: }
                    289: 
                    290: 
                    291: /*
                    292: **  GETEUID -- get effective user id.
                    293: */
                    294: 
                    295: geteuid()
                    296: {
                    297:        return ((getuid() >> 8) & 0377);
                    298: }
                    299: 
                    300: 
                    301: /*
                    302: **  GETEGID -- get effective group id.
                    303: */
                    304: 
                    305: getegid()
                    306: {
                    307:        return ((getgid() >> 8) & 0377);
                    308: }
                    309: 
                    310: # endif V6
                    311: 
                    312: # ifndef V6
                    313: 
                    314: /*
                    315: **  GETRUID -- get real user id (V7)
                    316: */
                    317: 
                    318: getruid()
                    319: {
                    320:        if (OpMode == MD_DAEMON)
                    321:                return (RealUid);
                    322:        else
                    323:                return (getuid());
                    324: }
                    325: 
                    326: 
                    327: /*
                    328: **  GETRGID -- get real group id (V7).
                    329: */
                    330: 
                    331: getrgid()
                    332: {
                    333:        if (OpMode == MD_DAEMON)
                    334:                return (RealGid);
                    335:        else
                    336:                return (getgid());
                    337: }
                    338: 
                    339: # endif V6
                    340: /*
                    341: **  USERNAME -- return the user id of the logged in user.
                    342: **
                    343: **     Parameters:
                    344: **             none.
                    345: **
                    346: **     Returns:
                    347: **             The login name of the logged in user.
                    348: **
                    349: **     Side Effects:
                    350: **             none.
                    351: **
                    352: **     Notes:
                    353: **             The return value is statically allocated.
                    354: */
                    355: 
                    356: char *
                    357: username()
                    358: {
                    359:        static char *myname = NULL;
                    360:        extern char *getlogin();
                    361:        register struct passwd *pw;
                    362:        extern struct passwd *getpwuid();
                    363: 
                    364:        /* cache the result */
                    365:        if (myname == NULL)
                    366:        {
                    367:                myname = getlogin();
                    368:                if (myname == NULL || myname[0] == '\0')
                    369:                {
                    370: 
                    371:                        pw = getpwuid(getruid());
                    372:                        if (pw != NULL)
                    373:                                myname = pw->pw_name;
                    374:                }
                    375:                else
                    376:                {
                    377: 
                    378:                        pw = getpwnam(myname);
                    379:                        if(getuid() != pw->pw_uid)
                    380:                        {
                    381:                                pw = getpwuid(getuid());
                    382:                                if (pw != NULL)
                    383:                                        myname = pw->pw_name;
                    384:                        }
                    385:                }
                    386:                if (myname == NULL || myname[0] == '\0')
                    387:                {
                    388:                        syserr("Who are you?");
                    389:                        myname = "postmaster";
                    390:                }
                    391:        }
                    392: 
                    393:        return (myname);
                    394: }
                    395: /*
                    396: **  TTYPATH -- Get the path of the user's tty
                    397: **
                    398: **     Returns the pathname of the user's tty.  Returns NULL if
                    399: **     the user is not logged in or if s/he has write permission
                    400: **     denied.
                    401: **
                    402: **     Parameters:
                    403: **             none
                    404: **
                    405: **     Returns:
                    406: **             pathname of the user's tty.
                    407: **             NULL if not logged in or write permission denied.
                    408: **
                    409: **     Side Effects:
                    410: **             none.
                    411: **
                    412: **     WARNING:
                    413: **             Return value is in a local buffer.
                    414: **
                    415: **     Called By:
                    416: **             savemail
                    417: */
                    418: 
                    419: # include <sys/stat.h>
                    420: 
                    421: char *
                    422: ttypath()
                    423: {
                    424:        struct stat stbuf;
                    425:        register char *pathn;
                    426:        extern char *ttyname();
                    427:        extern char *getlogin();
                    428: 
                    429:        /* compute the pathname of the controlling tty */
                    430:        if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
                    431:            (pathn = ttyname(0)) == NULL)
                    432:        {
                    433:                errno = 0;
                    434:                return (NULL);
                    435:        }
                    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: **  CHECKCOMPAT -- check for From and To person compatible.
                    453: **
                    454: **     This routine can be supplied on a per-installation basis
                    455: **     to determine whether a person is allowed to send a message.
                    456: **     This allows restriction of certain types of internet
                    457: **     forwarding or registration of users.
                    458: **
                    459: **     If the hosts are found to be incompatible, an error
                    460: **     message should be given using "usrerr" and FALSE should
                    461: **     be returned.
                    462: **
                    463: **     'NoReturn' can be set to suppress the return-to-sender
                    464: **     function; this should be done on huge messages.
                    465: **
                    466: **     Parameters:
                    467: **             to -- the person being sent to.
                    468: **
                    469: **     Returns:
                    470: **             TRUE -- ok to send.
                    471: **             FALSE -- not ok.
                    472: **
                    473: **     Side Effects:
                    474: **             none (unless you include the usrerr stuff)
                    475: */
                    476: 
                    477: bool
                    478: checkcompat(to)
                    479:        register ADDRESS *to;
                    480: {
                    481: # ifdef lint
                    482:        if (to == NULL)
                    483:                to++;
                    484: # endif lint
                    485: # ifdef EXAMPLE_CODE
                    486:        /* this code is intended as an example only */
                    487:        register STAB *s;
                    488: 
                    489:        s = stab("arpa", ST_MAILER, ST_FIND);
                    490:        if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
                    491:            to->q_mailer == s->s_mailer)
                    492:        {
                    493:                usrerr("No ARPA mail through this machine: see your system administration");
                    494:                /* NoReturn = TRUE; to supress return copy */
                    495:                return (FALSE);
                    496:        }
                    497: # endif EXAMPLE_CODE
                    498:        return (TRUE);
                    499: }
                    500: /*
                    501: **  HOLDSIGS -- arrange to hold all signals
                    502: **
                    503: **     Parameters:
                    504: **             none.
                    505: **
                    506: **     Returns:
                    507: **             none.
                    508: **
                    509: **     Side Effects:
                    510: **             Arranges that signals are held.
                    511: */
                    512: 
                    513: holdsigs()
                    514: {
                    515: }
                    516: /*
                    517: **  RLSESIGS -- arrange to release all signals
                    518: **
                    519: **     This undoes the effect of holdsigs.
                    520: **
                    521: **     Parameters:
                    522: **             none.
                    523: **
                    524: **     Returns:
                    525: **             none.
                    526: **
                    527: **     Side Effects:
                    528: **             Arranges that signals are released.
                    529: */
                    530: 
                    531: rlsesigs()
                    532: {
                    533: }
                    534: /*
                    535: **  GETLA -- get the current load average
                    536: **
                    537: **     This code stolen from la.c.
                    538: **
                    539: **     Parameters:
                    540: **             none.
                    541: **
                    542: **     Returns:
                    543: **             The current load average as an integer.
                    544: **
                    545: **     Side Effects:
                    546: **             none.
                    547: */
                    548: 
                    549: #ifdef VMUNIX
                    550: 
                    551: #include <nlist.h>
                    552: 
                    553: struct nlist Nl[] =
                    554: {
                    555:        { "_avenrun" },
                    556: #define        X_AVENRUN       0
                    557:        { 0 },
                    558: };
                    559: 
                    560: getla()
                    561: {
                    562:        static int kmem = -1;
                    563: # ifdef sun
                    564:        long avenrun[3];
                    565: # else
                    566:        double avenrun[3];
                    567: # endif
                    568:        extern off_t lseek();
                    569: 
                    570:        if (kmem < 0)
                    571:        {
                    572:                kmem = open("/dev/kmem", 0, 0);
                    573:                if (kmem < 0)
                    574:                        return (-1);
                    575:                (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
                    576:                nlist("/vmunix", Nl);
                    577:                if (Nl[0].n_type == 0)
                    578:                        return (-1);
                    579:        }
                    580:        if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
                    581:            read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
                    582:        {
                    583:                /* thank you Ian */
                    584:                return (-1);
                    585:        }
                    586: # ifdef sun
                    587:        return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
                    588: # else
                    589:        return ((int) (avenrun[0] + 0.5));
                    590: # endif
                    591: }
                    592: 
                    593: #else VMUNIX
                    594: 
                    595: getla()
                    596: {
                    597:        return (0);
                    598: }
                    599: 
                    600: #endif VMUNIX
                    601: /*
                    602: **  SHOULDQUEUE -- should this message be queued or sent?
                    603: **
                    604: **     Compares the message cost to the load average to decide.
                    605: **
                    606: **     Parameters:
                    607: **             pri -- the priority of the message in question.
                    608: **
                    609: **     Returns:
                    610: **             TRUE -- if this message should be queued up for the
                    611: **                     time being.
                    612: **             FALSE -- if the load is low enough to send this message.
                    613: **
                    614: **     Side Effects:
                    615: **             none.
                    616: */
                    617: 
                    618: bool
                    619: shouldqueue(pri)
                    620:        long pri;
                    621: {
                    622:        int la;
                    623: 
                    624:        la = getla();
                    625:        if (la < QueueLA)
                    626:                return (FALSE);
                    627:        return (pri > (QueueFactor / (la - QueueLA + 1)));
                    628: }
                    629: /*
                    630: **  SETPROCTITLE -- set process title for ps
                    631: **
                    632: **     Parameters:
                    633: **             fmt -- a printf style format string.
                    634: **             a, b, c -- possible parameters to fmt.
                    635: **
                    636: **     Returns:
                    637: **             none.
                    638: **
                    639: **     Side Effects:
                    640: **             Clobbers argv of our main procedure so ps(1) will
                    641: **             display the title.
                    642: */
                    643: 
                    644: /*VARARGS1*/
                    645: setproctitle(fmt, a, b, c)
                    646:        char *fmt;
                    647: {
                    648: # ifdef SETPROCTITLE
                    649:        register char *p;
                    650:        register int i;
                    651:        extern char **Argv;
                    652:        extern char *LastArgv;
                    653:        char buf[MAXLINE];
                    654: 
                    655:        (void) sprintf(buf, fmt, a, b, c);
                    656: 
                    657:        /* make ps print "(sendmail)" */
                    658:        p = Argv[0];
                    659:        *p++ = '-';
                    660: 
                    661:        i = strlen(buf);
                    662:        if (i > LastArgv - p - 2)
                    663:        {
                    664:                i = LastArgv - p - 2;
                    665:                buf[i] = '\0';
                    666:        }
                    667:        (void) strcpy(p, buf);
                    668:        p += i;
                    669:        while (p < LastArgv)
                    670:                *p++ = ' ';
                    671: # endif SETPROCTITLE
                    672: }
                    673: /*
                    674: **  REAPCHILD -- pick up the body of my child, lest it become a zombie
                    675: **
                    676: **     Parameters:
                    677: **             none.
                    678: **
                    679: **     Returns:
                    680: **             none.
                    681: **
                    682: **     Side Effects:
                    683: **             Picks up extant zombies.
                    684: */
                    685: 
                    686: # ifdef VMUNIX
                    687: # include <sys/wait.h>
                    688: # endif VMUNIX
                    689: 
                    690: reapchild()
                    691: {
                    692: # ifdef WNOHANG
                    693:        union wait status;
                    694: 
                    695:        while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
                    696:                continue;
                    697: # else WNOHANG
                    698:        auto int status;
                    699: 
                    700:        while (wait(&status) > 0)
                    701:                continue;
                    702: # endif WNOHANG
                    703: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.