122698Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 642825Sbostic * %sccs.include.redist.c% 733728Sbostic */ 822698Sdist 922698Sdist #ifndef lint 10*57359Seric static char sccsid[] = "@(#)conf.c 6.2 (Berkeley) 12/30/92"; 1133728Sbostic #endif /* not lint */ 1222698Sdist 1314881Seric # include <sys/ioctl.h> 1436928Sbostic # include <pwd.h> 153309Seric # include "sendmail.h" 1640980Sbostic # include "pathnames.h" 17404Seric 18294Seric /* 193309Seric ** CONF.C -- Sendmail Configuration Tables. 20294Seric ** 21294Seric ** Defines the configuration of this installation. 22294Seric ** 231388Seric ** Configuration Variables: 242897Seric ** HdrInfo -- a table describing well-known header fields. 252897Seric ** Each entry has the field name and some flags, 264147Seric ** which are described in sendmail.h. 274093Seric ** 284093Seric ** Notes: 294093Seric ** I have tried to put almost all the reasonable 304093Seric ** configuration information into the configuration 314093Seric ** file read at runtime. My intent is that anything 324093Seric ** here is a function of the version of UNIX you 334093Seric ** are running, or is really static -- for example 344093Seric ** the headers are a superset of widely used 354093Seric ** protocols. If you find yourself playing with 364093Seric ** this file too much, you may be making a mistake! 37294Seric */ 38294Seric 39294Seric 40294Seric 41294Seric 424437Seric /* 432897Seric ** Header info table 443057Seric ** Final (null) entry contains the flags used for any other field. 454147Seric ** 464147Seric ** Not all of these are actually handled specially by sendmail 474147Seric ** at this time. They are included as placeholders, to let 484147Seric ** you know that "someday" I intend to have sendmail do 494147Seric ** something with them. 502897Seric */ 512897Seric 522897Seric struct hdrinfo HdrInfo[] = 532897Seric { 548060Seric /* originator fields, most to least significant */ 5511417Seric "resent-sender", H_FROM|H_RESENT, 5611417Seric "resent-from", H_FROM|H_RESENT, 5725686Seric "resent-reply-to", H_FROM|H_RESENT, 589055Seric "sender", H_FROM, 599055Seric "from", H_FROM, 6025686Seric "reply-to", H_FROM, 619055Seric "full-name", H_ACHECK, 62*57359Seric "return-receipt-to", H_FROM /* |H_RECEIPTTO */, 63*57359Seric "errors-to", H_FROM|H_ERRORSTO, 648060Seric /* destination fields */ 659055Seric "to", H_RCPT, 6611417Seric "resent-to", H_RCPT|H_RESENT, 679055Seric "cc", H_RCPT, 6811417Seric "resent-cc", H_RCPT|H_RESENT, 699055Seric "bcc", H_RCPT|H_ACHECK, 7011417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 7156215Seric "apparently-to", H_RCPT, 728060Seric /* message identification and control */ 7311417Seric "message-id", 0, 7411417Seric "resent-message-id", H_RESENT, 759055Seric "message", H_EOH, 769055Seric "text", H_EOH, 7711417Seric /* date fields */ 7811417Seric "date", 0, 7911417Seric "resent-date", H_RESENT, 808060Seric /* trace fields */ 819055Seric "received", H_TRACE|H_FORCE, 829055Seric "via", H_TRACE|H_FORCE, 839055Seric "mail-from", H_TRACE|H_FORCE, 848060Seric 859055Seric NULL, 0, 862897Seric }; 874166Seric 884166Seric 894166Seric /* 904166Seric ** ARPANET error message numbers. 914166Seric */ 924166Seric 937956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 947956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 957956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 967956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 974282Seric 984282Seric 994282Seric 1004282Seric /* 1014282Seric ** Location of system files/databases/etc. 1024282Seric */ 1034282Seric 10440980Sbostic char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */ 10540980Sbostic char *FreezeFile = _PATH_SENDMAILFC; /* frozen version of above */ 1069039Seric 1079064Seric 1089064Seric 1099039Seric /* 11024943Seric ** Miscellaneous stuff. 1119039Seric */ 1129039Seric 11324943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 11424943Seric /* 11524943Seric ** SETDEFAULTS -- set default values 11624943Seric ** 11724943Seric ** Because of the way freezing is done, these must be initialized 11824943Seric ** using direct code. 11924943Seric ** 12024943Seric ** Parameters: 12124943Seric ** none. 12224943Seric ** 12324943Seric ** Returns: 12424943Seric ** none. 12524943Seric ** 12624943Seric ** Side Effects: 12724943Seric ** Initializes a bunch of global variables to their 12824943Seric ** default values. 12924943Seric */ 13024943Seric 13124943Seric setdefaults() 13224943Seric { 13324943Seric QueueLA = 8; 13424943Seric QueueFactor = 10000; 13524943Seric RefuseLA = 12; 13624943Seric SpaceSub = ' '; 13724981Seric WkRecipFact = 1000; 13824981Seric WkClassFact = 1800; 13925812Seric WkTimeFact = 9000; 14057142Seric FileMode = (getuid() != geteuid()) ? 0644 : 0600; 14124981Seric DefUid = 1; 14224981Seric DefGid = 1; 14347284Seric CheckpointInterval = 10; 14457142Seric MaxHopCount = 17; 14552105Seric SendMode = SM_FORK; 14652105Seric ErrorMode = EM_PRINT; 14752106Seric EightBit = FALSE; 14854967Seric MaxMciCache = 1; 14954967Seric MciCacheTimeout = 300; 15040973Sbostic setdefuser(); 15153654Seric setupmaps(); 15224943Seric } 153294Seric 15440973Sbostic 1554326Seric /* 15640973Sbostic ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 15740973Sbostic */ 15840973Sbostic 15940973Sbostic setdefuser() 16040973Sbostic { 16140973Sbostic struct passwd *defpwent; 16240973Sbostic 16340973Sbostic if (DefUser != NULL) 16440973Sbostic free(DefUser); 16540973Sbostic if ((defpwent = getpwuid(DefUid)) != NULL) 16640973Sbostic DefUser = newstr(defpwent->pw_name); 16740973Sbostic else 16840973Sbostic DefUser = newstr("nobody"); 16940973Sbostic } 17053654Seric /* 17153654Seric ** SETUPMAPS -- set up map classes 17253654Seric ** 17353654Seric ** Since these are compiled in, they cannot be in the config file. 17453654Seric ** 17553654Seric */ 17640973Sbostic 17753654Seric setupmaps() 17853654Seric { 17953654Seric register STAB *s; 18056836Seric extern bool host_map_init(); 18153654Seric extern char *maphostname(); 18240973Sbostic 18353654Seric /* set up host name lookup map */ 18453654Seric s = stab("host", ST_MAPCLASS, ST_ENTER); 18556836Seric s->s_mapclass.map_init = host_map_init; 18653654Seric s->s_mapclass.map_lookup = maphostname; 18753654Seric 18853654Seric /* 18953654Seric ** Set up other map classes. 19053654Seric */ 19153654Seric 19253654Seric # ifdef DBM_MAP 19353654Seric /* dbm file access */ 19453654Seric { 19556836Seric extern bool dbm_map_init(); 19653654Seric extern char *dbm_map_lookup(); 19753654Seric 19853654Seric s = stab("dbm", ST_MAPCLASS, ST_ENTER); 19953654Seric s->s_mapclass.map_init = dbm_map_init; 20053654Seric s->s_mapclass.map_lookup = dbm_map_lookup; 20153654Seric } 20253654Seric # endif 20353654Seric 20453654Seric # ifdef BTREE_MAP 20553654Seric /* new database file access -- btree files */ 20653654Seric { 20756823Seric extern bool bt_map_init(); 20856823Seric extern char *db_map_lookup(); 20953654Seric 21053654Seric s = stab("btree", ST_MAPCLASS, ST_ENTER); 21153654Seric s->s_mapclass.map_init = bt_map_init; 21256823Seric s->s_mapclass.map_lookup = db_map_lookup; 21353654Seric } 21453654Seric # endif 21553654Seric 21653654Seric # ifdef HASH_MAP 21753654Seric /* new database file access -- hash files */ 21853654Seric { 21956823Seric extern bool hash_map_init(); 22056823Seric extern char *db_map_lookup(); 22153654Seric 22253654Seric s = stab("hash", ST_MAPCLASS, ST_ENTER); 22353654Seric s->s_mapclass.map_init = hash_map_init; 22456823Seric s->s_mapclass.map_lookup = db_map_lookup; 22553654Seric } 22653654Seric # endif 22753654Seric 22857208Seric # ifdef NIS_MAP 22957208Seric /* NIS map access */ 23057208Seric { 23157208Seric extern bool nis_map_init(); 23257208Seric extern char *nis_map_lookup(); 23357208Seric 23457208Seric s = stab("nis", ST_MAPCLASS, ST_ENTER); 23557208Seric s->s_mapclass.map_init = nis_map_init; 23657208Seric s->s_mapclass.map_lookup = nis_map_lookup; 23757208Seric } 23857208Seric # endif 23957208Seric 24053654Seric # ifdef USERDB_MAP 24153654Seric /* user database */ 24253654Seric { 24356836Seric extern bool udb_map_init(); 24453654Seric extern char *udb_map_lookup(); 24553654Seric 24653654Seric s = stab("udb", ST_MAPCLASS, ST_ENTER); 24753654Seric s->s_mapclass.map_init = udb_map_init; 24853654Seric s->s_mapclass.map_lookup = udb_map_lookup; 24953654Seric } 25053654Seric # endif 25153654Seric } 25253654Seric /* 25356836Seric ** HOST_MAP_INIT -- initialize host class structures 25456836Seric */ 25556836Seric 25656836Seric bool 25756836Seric host_map_init(map, mapname, args) 25856836Seric MAP *map; 25956836Seric char *mapname; 26056836Seric char *args; 26156836Seric { 26256836Seric register char *p = args; 26356836Seric 26456836Seric for (;;) 26556836Seric { 26656836Seric while (isspace(*p)) 26756836Seric p++; 26856836Seric if (*p != '-') 26956836Seric break; 27056836Seric switch (*++p) 27156836Seric { 27256836Seric case 'a': 27356836Seric map->map_app = ++p; 27456836Seric break; 27556836Seric } 27656836Seric while (*p != '\0' && !isspace(*p)) 27756836Seric p++; 27856836Seric if (*p != '\0') 27956836Seric *p++ = '\0'; 28056836Seric } 28156836Seric if (map->map_app != NULL) 28256836Seric map->map_app = newstr(map->map_app); 28356836Seric return TRUE; 28456836Seric } 28556836Seric 28656836Seric /* 2874326Seric ** GETRUID -- get real user id (V7) 2884326Seric */ 2894326Seric 2904326Seric getruid() 2914326Seric { 2929274Seric if (OpMode == MD_DAEMON) 2934536Seric return (RealUid); 2944536Seric else 2954536Seric return (getuid()); 2964326Seric } 2974326Seric 2984326Seric 2994326Seric /* 3004326Seric ** GETRGID -- get real group id (V7). 3014326Seric */ 3024326Seric 3034326Seric getrgid() 3044326Seric { 3059274Seric if (OpMode == MD_DAEMON) 3064536Seric return (RealGid); 3074536Seric else 3084536Seric return (getgid()); 3094326Seric } 31053654Seric /* 3119369Seric ** USERNAME -- return the user id of the logged in user. 3129369Seric ** 3139369Seric ** Parameters: 3149369Seric ** none. 3159369Seric ** 3169369Seric ** Returns: 3179369Seric ** The login name of the logged in user. 3189369Seric ** 3199369Seric ** Side Effects: 3209369Seric ** none. 3219369Seric ** 3229369Seric ** Notes: 3239369Seric ** The return value is statically allocated. 3249369Seric */ 3259369Seric 3269369Seric char * 3279369Seric username() 3289369Seric { 32917469Seric static char *myname = NULL; 3309369Seric extern char *getlogin(); 33119904Smiriam register struct passwd *pw; 3329369Seric 33317469Seric /* cache the result */ 33417469Seric if (myname == NULL) 33517469Seric { 33617469Seric myname = getlogin(); 33717469Seric if (myname == NULL || myname[0] == '\0') 33817469Seric { 33917469Seric 34017469Seric pw = getpwuid(getruid()); 34117469Seric if (pw != NULL) 34240993Sbostic myname = newstr(pw->pw_name); 34317469Seric } 34419904Smiriam else 34519904Smiriam { 34619873Smiriam 34740993Sbostic myname = newstr(myname); 34840993Sbostic if ((pw = getpwnam(myname)) == NULL || 34940993Sbostic getuid() != pw->pw_uid) 35019904Smiriam { 35119873Smiriam pw = getpwuid(getuid()); 35224945Seric if (pw != NULL) 35340993Sbostic myname = newstr(pw->pw_name); 35419873Smiriam } 35519873Smiriam } 35617469Seric if (myname == NULL || myname[0] == '\0') 35717469Seric { 35817469Seric syserr("Who are you?"); 35917469Seric myname = "postmaster"; 36017469Seric } 36117469Seric } 36217469Seric 36317469Seric return (myname); 3649369Seric } 3659369Seric /* 3664190Seric ** TTYPATH -- Get the path of the user's tty 367294Seric ** 368294Seric ** Returns the pathname of the user's tty. Returns NULL if 369294Seric ** the user is not logged in or if s/he has write permission 370294Seric ** denied. 371294Seric ** 372294Seric ** Parameters: 373294Seric ** none 374294Seric ** 375294Seric ** Returns: 376294Seric ** pathname of the user's tty. 377294Seric ** NULL if not logged in or write permission denied. 378294Seric ** 379294Seric ** Side Effects: 380294Seric ** none. 381294Seric ** 382294Seric ** WARNING: 383294Seric ** Return value is in a local buffer. 384294Seric ** 385294Seric ** Called By: 386294Seric ** savemail 387294Seric */ 388294Seric 389294Seric # include <sys/stat.h> 390294Seric 391294Seric char * 392294Seric ttypath() 393294Seric { 394294Seric struct stat stbuf; 395294Seric register char *pathn; 396294Seric extern char *ttyname(); 3974081Seric extern char *getlogin(); 398294Seric 399294Seric /* compute the pathname of the controlling tty */ 4009369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 4019369Seric (pathn = ttyname(0)) == NULL) 402294Seric { 403294Seric errno = 0; 404294Seric return (NULL); 405294Seric } 406294Seric 407294Seric /* see if we have write permission */ 4082967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 409294Seric { 410294Seric errno = 0; 411294Seric return (NULL); 412294Seric } 413294Seric 414294Seric /* see if the user is logged in */ 415294Seric if (getlogin() == NULL) 416294Seric return (NULL); 417294Seric 418294Seric /* looks good */ 419294Seric return (pathn); 420294Seric } 4212967Seric /* 4222967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4232967Seric ** 4242967Seric ** This routine can be supplied on a per-installation basis 4252967Seric ** to determine whether a person is allowed to send a message. 4262967Seric ** This allows restriction of certain types of internet 4272967Seric ** forwarding or registration of users. 4282967Seric ** 4292967Seric ** If the hosts are found to be incompatible, an error 4302967Seric ** message should be given using "usrerr" and FALSE should 4312967Seric ** be returned. 4322967Seric ** 4334288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4344288Seric ** function; this should be done on huge messages. 4354288Seric ** 4362967Seric ** Parameters: 4372967Seric ** to -- the person being sent to. 4382967Seric ** 4392967Seric ** Returns: 4402967Seric ** TRUE -- ok to send. 4412967Seric ** FALSE -- not ok. 4422967Seric ** 4432967Seric ** Side Effects: 4442967Seric ** none (unless you include the usrerr stuff) 4452967Seric */ 4462967Seric 4472967Seric bool 44855012Seric checkcompat(to, e) 4492967Seric register ADDRESS *to; 45055012Seric register ENVELOPE *e; 4512967Seric { 45212133Seric # ifdef lint 45312133Seric if (to == NULL) 45412133Seric to++; 45512133Seric # endif lint 45610698Seric # ifdef EXAMPLE_CODE 45710698Seric /* this code is intended as an example only */ 4584437Seric register STAB *s; 4594437Seric 4604437Seric s = stab("arpa", ST_MAILER, ST_FIND); 46155012Seric if (s != NULL && e->e_from.q_mailer != LocalMailer && 4629369Seric to->q_mailer == s->s_mailer) 4634437Seric { 4644437Seric usrerr("No ARPA mail through this machine: see your system administration"); 46510698Seric /* NoReturn = TRUE; to supress return copy */ 4664437Seric return (FALSE); 4674437Seric } 46856795Seric # endif /* EXAMPLE_CODE */ 4692967Seric return (TRUE); 4702967Seric } 4719369Seric /* 4729369Seric ** HOLDSIGS -- arrange to hold all signals 4739369Seric ** 4749369Seric ** Parameters: 4759369Seric ** none. 4769369Seric ** 4779369Seric ** Returns: 4789369Seric ** none. 4799369Seric ** 4809369Seric ** Side Effects: 4819369Seric ** Arranges that signals are held. 4829369Seric */ 4839369Seric 4849369Seric holdsigs() 4859369Seric { 4869369Seric } 4879369Seric /* 4889369Seric ** RLSESIGS -- arrange to release all signals 4899369Seric ** 4909369Seric ** This undoes the effect of holdsigs. 4919369Seric ** 4929369Seric ** Parameters: 4939369Seric ** none. 4949369Seric ** 4959369Seric ** Returns: 4969369Seric ** none. 4979369Seric ** 4989369Seric ** Side Effects: 4999369Seric ** Arranges that signals are released. 5009369Seric */ 5019369Seric 5029369Seric rlsesigs() 5039369Seric { 5049369Seric } 50514872Seric /* 50614872Seric ** GETLA -- get the current load average 50714872Seric ** 50814881Seric ** This code stolen from la.c. 50914881Seric ** 51014872Seric ** Parameters: 51114872Seric ** none. 51214872Seric ** 51314872Seric ** Returns: 51414872Seric ** The current load average as an integer. 51514872Seric ** 51614872Seric ** Side Effects: 51714872Seric ** none. 51814872Seric */ 51914872Seric 52051920Seric /* try to guess what style of load average we have */ 52151920Seric #define LA_ZERO 1 /* always return load average as zero */ 52251920Seric #define LA_INT 2 /* read kmem for avenrun; interpret as int */ 52351920Seric #define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ 52451920Seric #define LA_SUBR 4 /* call getloadavg */ 52514872Seric 52651920Seric #ifndef LA_TYPE 52751920Seric # if defined(sun) 52851920Seric # define LA_TYPE LA_INT 52951920Seric # endif 53051920Seric # if defined(mips) 53151920Seric /* Ultrix or RISC/os */ 53251920Seric # define LA_TYPE LA_INT 53351920Seric # define LA_AVENRUN "avenrun" 53451920Seric # endif 53551920Seric # if defined(hpux) 53651920Seric # define LA_TYPE LA_FLOAT 53751920Seric # endif 53851920Seric # if defined(BSD) 53951920Seric # define LA_TYPE LA_SUBR 54051920Seric # endif 54151920Seric 54251920Seric # ifndef LA_TYPE 54351920Seric # define LA_TYPE LA_ZERO 54451920Seric # endif 54551920Seric #endif 54651920Seric 54751920Seric #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) 54851920Seric 54914872Seric #include <nlist.h> 55051920Seric #include <fcntl.h> 55114872Seric 55251920Seric #ifndef LA_AVENRUN 55351920Seric #define LA_AVENRUN "_avenrun" 55451920Seric #endif 55551920Seric 55651920Seric /* _PATH_UNIX should be defined in <paths.h> */ 55751920Seric #ifndef _PATH_UNIX 55851920Seric # if defined(hpux) 55951920Seric # define _PATH_UNIX "/hp-ux" 56051920Seric # endif 56151920Seric # if defined(mips) && !defined(ultrix) 56251920Seric /* powerful RISC/os */ 56351920Seric # define _PATH_UNIX "/unix" 56451920Seric # endif 56551920Seric # ifndef _PATH_UNIX 56651920Seric # define _PATH_UNIX "/vmunix" 56751920Seric # endif 56851920Seric #endif 56951920Seric 57014872Seric struct nlist Nl[] = 57114872Seric { 57251920Seric { LA_AVENRUN }, 57314872Seric #define X_AVENRUN 0 57414872Seric { 0 }, 57514872Seric }; 57614872Seric 57751920Seric #if (LA_TYPE == LA_INT) && !defined(FSHIFT) 57851920Seric # define FSHIFT 8 57951920Seric # define FSCALE (1 << FSHIFT) 58051920Seric #endif 58140930Srick 58214872Seric getla() 58314872Seric { 58414872Seric static int kmem = -1; 58551920Seric #if LA_TYPE == LA_INT 58624943Seric long avenrun[3]; 58751920Seric #else 58851920Seric double avenrun[3]; 58951920Seric #endif 59025615Seric extern off_t lseek(); 59114872Seric 59214872Seric if (kmem < 0) 59314872Seric { 59424945Seric kmem = open("/dev/kmem", 0, 0); 59514872Seric if (kmem < 0) 59614872Seric return (-1); 59751920Seric (void) fcntl(kmem, F_SETFD, 1); 59851920Seric nlist(_PATH_UNIX, Nl); 59914872Seric if (Nl[0].n_type == 0) 60014872Seric return (-1); 60114872Seric } 60224945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 60323118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 60419967Seric { 60519967Seric /* thank you Ian */ 60619967Seric return (-1); 60719967Seric } 60851920Seric #if LA_TYPE == LA_INT 60924943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 61051920Seric #else 61151920Seric return ((int) (avenrun[0] + 0.5)); 61251920Seric #endif 61314872Seric } 61414872Seric 61551773Seric #else 61651920Seric #if LA_TYPE == LA_SUBR 61751773Seric 61851773Seric getla() 61951773Seric { 62051920Seric double avenrun[3]; 62151920Seric 62251920Seric if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 62351920Seric return (-1); 62451920Seric return ((int) (avenrun[0] + 0.5)); 62551773Seric } 62651773Seric 62751773Seric #else 62851773Seric 62951773Seric getla() 63051773Seric { 63151920Seric return (0); 63251773Seric } 63351773Seric 63451773Seric #endif 63551773Seric #endif 63624943Seric /* 63724943Seric ** SHOULDQUEUE -- should this message be queued or sent? 63824943Seric ** 63924943Seric ** Compares the message cost to the load average to decide. 64024943Seric ** 64124943Seric ** Parameters: 64224943Seric ** pri -- the priority of the message in question. 64324943Seric ** 64424943Seric ** Returns: 64524943Seric ** TRUE -- if this message should be queued up for the 64624943Seric ** time being. 64724943Seric ** FALSE -- if the load is low enough to send this message. 64824943Seric ** 64924943Seric ** Side Effects: 65024943Seric ** none. 65124943Seric */ 65224943Seric 65324943Seric bool 65424943Seric shouldqueue(pri) 65524943Seric long pri; 65624943Seric { 65751920Seric if (CurrentLA < QueueLA) 65824943Seric return (FALSE); 65951920Seric return (pri > (QueueFactor / (CurrentLA - QueueLA + 1))); 66024943Seric } 66124943Seric /* 66253037Seric ** REFUSECONNECTIONS -- decide if connections should be refused 66353037Seric ** 66453037Seric ** Parameters: 66553037Seric ** none. 66653037Seric ** 66753037Seric ** Returns: 66853037Seric ** TRUE if incoming SMTP connections should be refused 66953037Seric ** (for now). 67053037Seric ** FALSE if we should accept new work. 67153037Seric ** 67253037Seric ** Side Effects: 67353037Seric ** none. 67453037Seric */ 67553037Seric 67653037Seric bool 67753037Seric refuseconnections() 67853037Seric { 67953037Seric /* this is probably too simplistic */ 68053037Seric return (CurrentLA > RefuseLA); 68153037Seric } 68253037Seric /* 68324943Seric ** SETPROCTITLE -- set process title for ps 68424943Seric ** 68524943Seric ** Parameters: 68624943Seric ** fmt -- a printf style format string. 68724943Seric ** a, b, c -- possible parameters to fmt. 68824943Seric ** 68924943Seric ** Returns: 69024943Seric ** none. 69124943Seric ** 69224943Seric ** Side Effects: 69324943Seric ** Clobbers argv of our main procedure so ps(1) will 69424943Seric ** display the title. 69524943Seric */ 69624943Seric 69724943Seric /*VARARGS1*/ 69856852Seric setproctitle(fmt VA_ARG_FORMAL) 69924943Seric char *fmt; 70056852Seric VA_ARG_DECL 70124943Seric { 70224943Seric # ifdef SETPROCTITLE 70324943Seric register char *p; 70425049Seric register int i; 70556852Seric char buf[MAXLINE]; 70656852Seric VA_LOCAL_DECL 70724943Seric extern char **Argv; 70824943Seric extern char *LastArgv; 70924943Seric 71054996Seric p = buf; 71124943Seric 71254996Seric /* print sendmail: heading for grep */ 71354996Seric (void) strcpy(p, "sendmail: "); 71454996Seric p += strlen(p); 71524943Seric 71654996Seric /* print the argument string */ 71756852Seric VA_START(fmt); 71856852Seric (void) vsprintf(p, fmt, ap); 71956852Seric VA_END; 72054996Seric 72125049Seric i = strlen(buf); 72254996Seric if (i > LastArgv - Argv[0] - 2) 72325049Seric { 72454996Seric i = LastArgv - Argv[0] - 2; 72525049Seric buf[i] = '\0'; 72625049Seric } 72754996Seric (void) strcpy(Argv[0], buf); 72854997Seric p = &Argv[0][i]; 72924943Seric while (p < LastArgv) 73024943Seric *p++ = ' '; 73156795Seric # endif /* SETPROCTITLE */ 73224943Seric } 73325698Seric /* 73425698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 73525698Seric ** 73625698Seric ** Parameters: 73725698Seric ** none. 73825698Seric ** 73925698Seric ** Returns: 74025698Seric ** none. 74125698Seric ** 74225698Seric ** Side Effects: 74325698Seric ** Picks up extant zombies. 74425698Seric */ 74525698Seric 74625698Seric # include <sys/wait.h> 74725698Seric 74846928Sbostic void 74925698Seric reapchild() 75025698Seric { 75125698Seric # ifdef WNOHANG 75225698Seric union wait status; 75325698Seric 75446928Sbostic while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0) 75525698Seric continue; 75656795Seric # else /* WNOHANG */ 75725698Seric auto int status; 75825698Seric 75946928Sbostic while (wait((int *)&status) > 0) 76025698Seric continue; 76156795Seric # endif /* WNOHANG */ 76225698Seric } 76355418Seric /* 76455418Seric ** UNSETENV -- remove a variable from the environment 76555418Seric ** 76655418Seric ** Not needed on newer systems. 76755418Seric ** 76855418Seric ** Parameters: 76955418Seric ** name -- the string name of the environment variable to be 77055418Seric ** deleted from the current environment. 77155418Seric ** 77255418Seric ** Returns: 77355418Seric ** none. 77455418Seric ** 77555418Seric ** Globals: 77655418Seric ** environ -- a pointer to the current environment. 77755418Seric ** 77855418Seric ** Side Effects: 77955418Seric ** Modifies environ. 78055418Seric */ 78155418Seric 78255418Seric #ifdef UNSETENV 78355418Seric 78455418Seric void 78555418Seric unsetenv(name) 78655418Seric char *name; 78755418Seric { 78855418Seric extern char **environ; 78955418Seric register char **pp; 79055418Seric int len = strlen(name); 79155418Seric 79255418Seric for (pp = environ; *pp != NULL; pp++) 79355418Seric { 79455418Seric if (strncmp(name, *pp, len) == 0 && 79555418Seric ((*pp)[len] == '=' || (*pp)[len] == '\0')) 79655418Seric break; 79755418Seric } 79855418Seric 79955418Seric for (; *pp != NULL; pp++) 80055418Seric *pp = pp[1]; 80155418Seric } 80255418Seric 80355418Seric #endif /* UNSETENV */ 80456215Seric /* 80556215Seric ** GETDTABLESIZE -- return number of file descriptors 80656215Seric ** 80756215Seric ** Only on non-BSD systems 80856215Seric ** 80956215Seric ** Parameters: 81056215Seric ** none 81156215Seric ** 81256215Seric ** Returns: 81356215Seric ** size of file descriptor table 81456215Seric ** 81556215Seric ** Side Effects: 81656215Seric ** none 81756215Seric */ 81856215Seric 81956215Seric #ifdef SYSTEM5 82056215Seric 82156215Seric int 82256215Seric getdtablesize() 82356215Seric { 82456215Seric return NOFILE; 82556215Seric } 82656215Seric 82756215Seric #endif 828