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*57402Seric static char sccsid[] = "@(#)conf.c 6.4 (Berkeley) 01/02/93"; 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, 6257359Seric "return-receipt-to", H_FROM /* |H_RECEIPTTO */, 6357359Seric "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(); 152*57402Seric setupmailers(); 15324943Seric } 154294Seric 15540973Sbostic 1564326Seric /* 15740973Sbostic ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 15840973Sbostic */ 15940973Sbostic 16040973Sbostic setdefuser() 16140973Sbostic { 16240973Sbostic struct passwd *defpwent; 16357386Seric static char defuserbuf[40]; 16440973Sbostic 16557386Seric DefUser = defuserbuf; 16640973Sbostic if ((defpwent = getpwuid(DefUid)) != NULL) 16757386Seric strcpy(defuserbuf, defpwent->pw_name); 16840973Sbostic else 16957386Seric strcpy(defuserbuf, "nobody"); 17040973Sbostic } 17153654Seric /* 17253654Seric ** SETUPMAPS -- set up map classes 17353654Seric ** 17453654Seric ** Since these are compiled in, they cannot be in the config file. 17553654Seric ** 17653654Seric */ 17740973Sbostic 17853654Seric setupmaps() 17953654Seric { 18053654Seric register STAB *s; 18156836Seric extern bool host_map_init(); 18253654Seric extern char *maphostname(); 18340973Sbostic 18453654Seric /* set up host name lookup map */ 18553654Seric s = stab("host", ST_MAPCLASS, ST_ENTER); 18656836Seric s->s_mapclass.map_init = host_map_init; 18753654Seric s->s_mapclass.map_lookup = maphostname; 18853654Seric 18953654Seric /* 19053654Seric ** Set up other map classes. 19153654Seric */ 19253654Seric 19353654Seric # ifdef DBM_MAP 19453654Seric /* dbm file access */ 19553654Seric { 19656836Seric extern bool dbm_map_init(); 19753654Seric extern char *dbm_map_lookup(); 19853654Seric 19953654Seric s = stab("dbm", ST_MAPCLASS, ST_ENTER); 20053654Seric s->s_mapclass.map_init = dbm_map_init; 20153654Seric s->s_mapclass.map_lookup = dbm_map_lookup; 20253654Seric } 20353654Seric # endif 20453654Seric 20553654Seric # ifdef BTREE_MAP 20653654Seric /* new database file access -- btree files */ 20753654Seric { 20856823Seric extern bool bt_map_init(); 20956823Seric extern char *db_map_lookup(); 21053654Seric 21153654Seric s = stab("btree", ST_MAPCLASS, ST_ENTER); 21253654Seric s->s_mapclass.map_init = bt_map_init; 21356823Seric s->s_mapclass.map_lookup = db_map_lookup; 21453654Seric } 21553654Seric # endif 21653654Seric 21753654Seric # ifdef HASH_MAP 21853654Seric /* new database file access -- hash files */ 21953654Seric { 22056823Seric extern bool hash_map_init(); 22156823Seric extern char *db_map_lookup(); 22253654Seric 22353654Seric s = stab("hash", ST_MAPCLASS, ST_ENTER); 22453654Seric s->s_mapclass.map_init = hash_map_init; 22556823Seric s->s_mapclass.map_lookup = db_map_lookup; 22653654Seric } 22753654Seric # endif 22853654Seric 22957208Seric # ifdef NIS_MAP 23057208Seric /* NIS map access */ 23157208Seric { 23257208Seric extern bool nis_map_init(); 23357208Seric extern char *nis_map_lookup(); 23457208Seric 23557208Seric s = stab("nis", ST_MAPCLASS, ST_ENTER); 23657208Seric s->s_mapclass.map_init = nis_map_init; 23757208Seric s->s_mapclass.map_lookup = nis_map_lookup; 23857208Seric } 23957208Seric # endif 24057208Seric 24153654Seric # ifdef USERDB_MAP 24253654Seric /* user database */ 24353654Seric { 24456836Seric extern bool udb_map_init(); 24553654Seric extern char *udb_map_lookup(); 24653654Seric 24753654Seric s = stab("udb", ST_MAPCLASS, ST_ENTER); 24853654Seric s->s_mapclass.map_init = udb_map_init; 24953654Seric s->s_mapclass.map_lookup = udb_map_lookup; 25053654Seric } 25153654Seric # endif 25253654Seric } 25353654Seric /* 25456836Seric ** HOST_MAP_INIT -- initialize host class structures 25556836Seric */ 25656836Seric 25756836Seric bool 25856836Seric host_map_init(map, mapname, args) 25956836Seric MAP *map; 26056836Seric char *mapname; 26156836Seric char *args; 26256836Seric { 26356836Seric register char *p = args; 26456836Seric 26556836Seric for (;;) 26656836Seric { 26756836Seric while (isspace(*p)) 26856836Seric p++; 26956836Seric if (*p != '-') 27056836Seric break; 27156836Seric switch (*++p) 27256836Seric { 27356836Seric case 'a': 27456836Seric map->map_app = ++p; 27556836Seric break; 27656836Seric } 27756836Seric while (*p != '\0' && !isspace(*p)) 27856836Seric p++; 27956836Seric if (*p != '\0') 28056836Seric *p++ = '\0'; 28156836Seric } 28256836Seric if (map->map_app != NULL) 28356836Seric map->map_app = newstr(map->map_app); 28456836Seric return TRUE; 28556836Seric } 286*57402Seric /* 287*57402Seric ** SETUPMAILERS -- initialize default mailers 288*57402Seric */ 28956836Seric 290*57402Seric setupmailers() 291*57402Seric { 292*57402Seric char buf[100]; 293*57402Seric 294*57402Seric strcpy(buf, "*file*, P=/dev/null, F=lsDEu, A=FILE"); 295*57402Seric makemailer(buf); 296*57402Seric 297*57402Seric strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE"); 298*57402Seric makemailer(buf); 299*57402Seric } 30056836Seric /* 3014326Seric ** GETRUID -- get real user id (V7) 3024326Seric */ 3034326Seric 3044326Seric getruid() 3054326Seric { 3069274Seric if (OpMode == MD_DAEMON) 3074536Seric return (RealUid); 3084536Seric else 3094536Seric return (getuid()); 3104326Seric } 3114326Seric 3124326Seric 3134326Seric /* 3144326Seric ** GETRGID -- get real group id (V7). 3154326Seric */ 3164326Seric 3174326Seric getrgid() 3184326Seric { 3199274Seric if (OpMode == MD_DAEMON) 3204536Seric return (RealGid); 3214536Seric else 3224536Seric return (getgid()); 3234326Seric } 32453654Seric /* 3259369Seric ** USERNAME -- return the user id of the logged in user. 3269369Seric ** 3279369Seric ** Parameters: 3289369Seric ** none. 3299369Seric ** 3309369Seric ** Returns: 3319369Seric ** The login name of the logged in user. 3329369Seric ** 3339369Seric ** Side Effects: 3349369Seric ** none. 3359369Seric ** 3369369Seric ** Notes: 3379369Seric ** The return value is statically allocated. 3389369Seric */ 3399369Seric 3409369Seric char * 3419369Seric username() 3429369Seric { 34317469Seric static char *myname = NULL; 3449369Seric extern char *getlogin(); 34519904Smiriam register struct passwd *pw; 3469369Seric 34717469Seric /* cache the result */ 34817469Seric if (myname == NULL) 34917469Seric { 35017469Seric myname = getlogin(); 35117469Seric if (myname == NULL || myname[0] == '\0') 35217469Seric { 35317469Seric 35417469Seric pw = getpwuid(getruid()); 35517469Seric if (pw != NULL) 35640993Sbostic myname = newstr(pw->pw_name); 35717469Seric } 35819904Smiriam else 35919904Smiriam { 36019873Smiriam 36140993Sbostic myname = newstr(myname); 36240993Sbostic if ((pw = getpwnam(myname)) == NULL || 36340993Sbostic getuid() != pw->pw_uid) 36419904Smiriam { 36519873Smiriam pw = getpwuid(getuid()); 36624945Seric if (pw != NULL) 36740993Sbostic myname = newstr(pw->pw_name); 36819873Smiriam } 36919873Smiriam } 37017469Seric if (myname == NULL || myname[0] == '\0') 37117469Seric { 37217469Seric syserr("Who are you?"); 37317469Seric myname = "postmaster"; 37417469Seric } 37517469Seric } 37617469Seric 37717469Seric return (myname); 3789369Seric } 3799369Seric /* 3804190Seric ** TTYPATH -- Get the path of the user's tty 381294Seric ** 382294Seric ** Returns the pathname of the user's tty. Returns NULL if 383294Seric ** the user is not logged in or if s/he has write permission 384294Seric ** denied. 385294Seric ** 386294Seric ** Parameters: 387294Seric ** none 388294Seric ** 389294Seric ** Returns: 390294Seric ** pathname of the user's tty. 391294Seric ** NULL if not logged in or write permission denied. 392294Seric ** 393294Seric ** Side Effects: 394294Seric ** none. 395294Seric ** 396294Seric ** WARNING: 397294Seric ** Return value is in a local buffer. 398294Seric ** 399294Seric ** Called By: 400294Seric ** savemail 401294Seric */ 402294Seric 403294Seric # include <sys/stat.h> 404294Seric 405294Seric char * 406294Seric ttypath() 407294Seric { 408294Seric struct stat stbuf; 409294Seric register char *pathn; 410294Seric extern char *ttyname(); 4114081Seric extern char *getlogin(); 412294Seric 413294Seric /* compute the pathname of the controlling tty */ 4149369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 4159369Seric (pathn = ttyname(0)) == NULL) 416294Seric { 417294Seric errno = 0; 418294Seric return (NULL); 419294Seric } 420294Seric 421294Seric /* see if we have write permission */ 4222967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 423294Seric { 424294Seric errno = 0; 425294Seric return (NULL); 426294Seric } 427294Seric 428294Seric /* see if the user is logged in */ 429294Seric if (getlogin() == NULL) 430294Seric return (NULL); 431294Seric 432294Seric /* looks good */ 433294Seric return (pathn); 434294Seric } 4352967Seric /* 4362967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4372967Seric ** 4382967Seric ** This routine can be supplied on a per-installation basis 4392967Seric ** to determine whether a person is allowed to send a message. 4402967Seric ** This allows restriction of certain types of internet 4412967Seric ** forwarding or registration of users. 4422967Seric ** 4432967Seric ** If the hosts are found to be incompatible, an error 4442967Seric ** message should be given using "usrerr" and FALSE should 4452967Seric ** be returned. 4462967Seric ** 4474288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4484288Seric ** function; this should be done on huge messages. 4494288Seric ** 4502967Seric ** Parameters: 4512967Seric ** to -- the person being sent to. 4522967Seric ** 4532967Seric ** Returns: 4542967Seric ** TRUE -- ok to send. 4552967Seric ** FALSE -- not ok. 4562967Seric ** 4572967Seric ** Side Effects: 4582967Seric ** none (unless you include the usrerr stuff) 4592967Seric */ 4602967Seric 4612967Seric bool 46255012Seric checkcompat(to, e) 4632967Seric register ADDRESS *to; 46455012Seric register ENVELOPE *e; 4652967Seric { 46612133Seric # ifdef lint 46712133Seric if (to == NULL) 46812133Seric to++; 46912133Seric # endif lint 47010698Seric # ifdef EXAMPLE_CODE 47110698Seric /* this code is intended as an example only */ 4724437Seric register STAB *s; 4734437Seric 4744437Seric s = stab("arpa", ST_MAILER, ST_FIND); 47555012Seric if (s != NULL && e->e_from.q_mailer != LocalMailer && 4769369Seric to->q_mailer == s->s_mailer) 4774437Seric { 4784437Seric usrerr("No ARPA mail through this machine: see your system administration"); 47910698Seric /* NoReturn = TRUE; to supress return copy */ 4804437Seric return (FALSE); 4814437Seric } 48256795Seric # endif /* EXAMPLE_CODE */ 4832967Seric return (TRUE); 4842967Seric } 4859369Seric /* 4869369Seric ** HOLDSIGS -- arrange to hold all signals 4879369Seric ** 4889369Seric ** Parameters: 4899369Seric ** none. 4909369Seric ** 4919369Seric ** Returns: 4929369Seric ** none. 4939369Seric ** 4949369Seric ** Side Effects: 4959369Seric ** Arranges that signals are held. 4969369Seric */ 4979369Seric 4989369Seric holdsigs() 4999369Seric { 5009369Seric } 5019369Seric /* 5029369Seric ** RLSESIGS -- arrange to release all signals 5039369Seric ** 5049369Seric ** This undoes the effect of holdsigs. 5059369Seric ** 5069369Seric ** Parameters: 5079369Seric ** none. 5089369Seric ** 5099369Seric ** Returns: 5109369Seric ** none. 5119369Seric ** 5129369Seric ** Side Effects: 5139369Seric ** Arranges that signals are released. 5149369Seric */ 5159369Seric 5169369Seric rlsesigs() 5179369Seric { 5189369Seric } 51914872Seric /* 52014872Seric ** GETLA -- get the current load average 52114872Seric ** 52214881Seric ** This code stolen from la.c. 52314881Seric ** 52414872Seric ** Parameters: 52514872Seric ** none. 52614872Seric ** 52714872Seric ** Returns: 52814872Seric ** The current load average as an integer. 52914872Seric ** 53014872Seric ** Side Effects: 53114872Seric ** none. 53214872Seric */ 53314872Seric 53451920Seric /* try to guess what style of load average we have */ 53551920Seric #define LA_ZERO 1 /* always return load average as zero */ 53651920Seric #define LA_INT 2 /* read kmem for avenrun; interpret as int */ 53751920Seric #define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ 53851920Seric #define LA_SUBR 4 /* call getloadavg */ 53914872Seric 54051920Seric #ifndef LA_TYPE 54151920Seric # if defined(sun) 54251920Seric # define LA_TYPE LA_INT 54351920Seric # endif 54451920Seric # if defined(mips) 54551920Seric /* Ultrix or RISC/os */ 54651920Seric # define LA_TYPE LA_INT 54751920Seric # define LA_AVENRUN "avenrun" 54851920Seric # endif 54951920Seric # if defined(hpux) 55051920Seric # define LA_TYPE LA_FLOAT 55151920Seric # endif 55251920Seric # if defined(BSD) 55351920Seric # define LA_TYPE LA_SUBR 55451920Seric # endif 55551920Seric 55651920Seric # ifndef LA_TYPE 55751920Seric # define LA_TYPE LA_ZERO 55851920Seric # endif 55951920Seric #endif 56051920Seric 56151920Seric #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) 56251920Seric 56314872Seric #include <nlist.h> 56451920Seric #include <fcntl.h> 56514872Seric 56651920Seric #ifndef LA_AVENRUN 56751920Seric #define LA_AVENRUN "_avenrun" 56851920Seric #endif 56951920Seric 57051920Seric /* _PATH_UNIX should be defined in <paths.h> */ 57151920Seric #ifndef _PATH_UNIX 57251920Seric # if defined(hpux) 57351920Seric # define _PATH_UNIX "/hp-ux" 57451920Seric # endif 57551920Seric # if defined(mips) && !defined(ultrix) 57651920Seric /* powerful RISC/os */ 57751920Seric # define _PATH_UNIX "/unix" 57851920Seric # endif 57951920Seric # ifndef _PATH_UNIX 58051920Seric # define _PATH_UNIX "/vmunix" 58151920Seric # endif 58251920Seric #endif 58351920Seric 58414872Seric struct nlist Nl[] = 58514872Seric { 58651920Seric { LA_AVENRUN }, 58714872Seric #define X_AVENRUN 0 58814872Seric { 0 }, 58914872Seric }; 59014872Seric 59151920Seric #if (LA_TYPE == LA_INT) && !defined(FSHIFT) 59251920Seric # define FSHIFT 8 59351920Seric # define FSCALE (1 << FSHIFT) 59451920Seric #endif 59540930Srick 59614872Seric getla() 59714872Seric { 59814872Seric static int kmem = -1; 59951920Seric #if LA_TYPE == LA_INT 60024943Seric long avenrun[3]; 60151920Seric #else 60251920Seric double avenrun[3]; 60351920Seric #endif 60425615Seric extern off_t lseek(); 60514872Seric 60614872Seric if (kmem < 0) 60714872Seric { 60824945Seric kmem = open("/dev/kmem", 0, 0); 60914872Seric if (kmem < 0) 61014872Seric return (-1); 61151920Seric (void) fcntl(kmem, F_SETFD, 1); 61251920Seric nlist(_PATH_UNIX, Nl); 61314872Seric if (Nl[0].n_type == 0) 61414872Seric return (-1); 61514872Seric } 61624945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 61723118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 61819967Seric { 61919967Seric /* thank you Ian */ 62019967Seric return (-1); 62119967Seric } 62251920Seric #if LA_TYPE == LA_INT 62324943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 62451920Seric #else 62551920Seric return ((int) (avenrun[0] + 0.5)); 62651920Seric #endif 62714872Seric } 62814872Seric 62951773Seric #else 63051920Seric #if LA_TYPE == LA_SUBR 63151773Seric 63251773Seric getla() 63351773Seric { 63451920Seric double avenrun[3]; 63551920Seric 63651920Seric if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 63751920Seric return (-1); 63851920Seric return ((int) (avenrun[0] + 0.5)); 63951773Seric } 64051773Seric 64151773Seric #else 64251773Seric 64351773Seric getla() 64451773Seric { 64551920Seric return (0); 64651773Seric } 64751773Seric 64851773Seric #endif 64951773Seric #endif 65024943Seric /* 65124943Seric ** SHOULDQUEUE -- should this message be queued or sent? 65224943Seric ** 65324943Seric ** Compares the message cost to the load average to decide. 65424943Seric ** 65524943Seric ** Parameters: 65624943Seric ** pri -- the priority of the message in question. 65724943Seric ** 65824943Seric ** Returns: 65924943Seric ** TRUE -- if this message should be queued up for the 66024943Seric ** time being. 66124943Seric ** FALSE -- if the load is low enough to send this message. 66224943Seric ** 66324943Seric ** Side Effects: 66424943Seric ** none. 66524943Seric */ 66624943Seric 66724943Seric bool 66824943Seric shouldqueue(pri) 66924943Seric long pri; 67024943Seric { 67151920Seric if (CurrentLA < QueueLA) 67224943Seric return (FALSE); 67351920Seric return (pri > (QueueFactor / (CurrentLA - QueueLA + 1))); 67424943Seric } 67524943Seric /* 67653037Seric ** REFUSECONNECTIONS -- decide if connections should be refused 67753037Seric ** 67853037Seric ** Parameters: 67953037Seric ** none. 68053037Seric ** 68153037Seric ** Returns: 68253037Seric ** TRUE if incoming SMTP connections should be refused 68353037Seric ** (for now). 68453037Seric ** FALSE if we should accept new work. 68553037Seric ** 68653037Seric ** Side Effects: 68753037Seric ** none. 68853037Seric */ 68953037Seric 69053037Seric bool 69153037Seric refuseconnections() 69253037Seric { 69353037Seric /* this is probably too simplistic */ 69453037Seric return (CurrentLA > RefuseLA); 69553037Seric } 69653037Seric /* 69724943Seric ** SETPROCTITLE -- set process title for ps 69824943Seric ** 69924943Seric ** Parameters: 70024943Seric ** fmt -- a printf style format string. 70124943Seric ** a, b, c -- possible parameters to fmt. 70224943Seric ** 70324943Seric ** Returns: 70424943Seric ** none. 70524943Seric ** 70624943Seric ** Side Effects: 70724943Seric ** Clobbers argv of our main procedure so ps(1) will 70824943Seric ** display the title. 70924943Seric */ 71024943Seric 71124943Seric /*VARARGS1*/ 71256852Seric setproctitle(fmt VA_ARG_FORMAL) 71324943Seric char *fmt; 71456852Seric VA_ARG_DECL 71524943Seric { 71624943Seric # ifdef SETPROCTITLE 71724943Seric register char *p; 71825049Seric register int i; 71956852Seric char buf[MAXLINE]; 72056852Seric VA_LOCAL_DECL 72124943Seric extern char **Argv; 72224943Seric extern char *LastArgv; 72324943Seric 72454996Seric p = buf; 72524943Seric 72654996Seric /* print sendmail: heading for grep */ 72754996Seric (void) strcpy(p, "sendmail: "); 72854996Seric p += strlen(p); 72924943Seric 73054996Seric /* print the argument string */ 73156852Seric VA_START(fmt); 73256852Seric (void) vsprintf(p, fmt, ap); 73356852Seric VA_END; 73454996Seric 73525049Seric i = strlen(buf); 73654996Seric if (i > LastArgv - Argv[0] - 2) 73725049Seric { 73854996Seric i = LastArgv - Argv[0] - 2; 73925049Seric buf[i] = '\0'; 74025049Seric } 74154996Seric (void) strcpy(Argv[0], buf); 74254997Seric p = &Argv[0][i]; 74324943Seric while (p < LastArgv) 74424943Seric *p++ = ' '; 74556795Seric # endif /* SETPROCTITLE */ 74624943Seric } 74725698Seric /* 74825698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 74925698Seric ** 75025698Seric ** Parameters: 75125698Seric ** none. 75225698Seric ** 75325698Seric ** Returns: 75425698Seric ** none. 75525698Seric ** 75625698Seric ** Side Effects: 75725698Seric ** Picks up extant zombies. 75825698Seric */ 75925698Seric 76025698Seric # include <sys/wait.h> 76125698Seric 76246928Sbostic void 76325698Seric reapchild() 76425698Seric { 76525698Seric # ifdef WNOHANG 76625698Seric union wait status; 76725698Seric 76846928Sbostic while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0) 76925698Seric continue; 77056795Seric # else /* WNOHANG */ 77125698Seric auto int status; 77225698Seric 77346928Sbostic while (wait((int *)&status) > 0) 77425698Seric continue; 77556795Seric # endif /* WNOHANG */ 77625698Seric } 77755418Seric /* 77855418Seric ** UNSETENV -- remove a variable from the environment 77955418Seric ** 78055418Seric ** Not needed on newer systems. 78155418Seric ** 78255418Seric ** Parameters: 78355418Seric ** name -- the string name of the environment variable to be 78455418Seric ** deleted from the current environment. 78555418Seric ** 78655418Seric ** Returns: 78755418Seric ** none. 78855418Seric ** 78955418Seric ** Globals: 79055418Seric ** environ -- a pointer to the current environment. 79155418Seric ** 79255418Seric ** Side Effects: 79355418Seric ** Modifies environ. 79455418Seric */ 79555418Seric 79655418Seric #ifdef UNSETENV 79755418Seric 79855418Seric void 79955418Seric unsetenv(name) 80055418Seric char *name; 80155418Seric { 80255418Seric extern char **environ; 80355418Seric register char **pp; 80455418Seric int len = strlen(name); 80555418Seric 80655418Seric for (pp = environ; *pp != NULL; pp++) 80755418Seric { 80855418Seric if (strncmp(name, *pp, len) == 0 && 80955418Seric ((*pp)[len] == '=' || (*pp)[len] == '\0')) 81055418Seric break; 81155418Seric } 81255418Seric 81355418Seric for (; *pp != NULL; pp++) 81455418Seric *pp = pp[1]; 81555418Seric } 81655418Seric 81755418Seric #endif /* UNSETENV */ 81856215Seric /* 81956215Seric ** GETDTABLESIZE -- return number of file descriptors 82056215Seric ** 82156215Seric ** Only on non-BSD systems 82256215Seric ** 82356215Seric ** Parameters: 82456215Seric ** none 82556215Seric ** 82656215Seric ** Returns: 82756215Seric ** size of file descriptor table 82856215Seric ** 82956215Seric ** Side Effects: 83056215Seric ** none 83156215Seric */ 83256215Seric 83356215Seric #ifdef SYSTEM5 83456215Seric 83556215Seric int 83656215Seric getdtablesize() 83756215Seric { 83856215Seric return NOFILE; 83956215Seric } 84056215Seric 84156215Seric #endif 842