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*57208Seric static char sccsid[] = "@(#)conf.c 5.48 (Berkeley) 12/18/92"; 1133728Sbostic #endif /* not lint */ 1222698Sdist 1314881Seric # include <sys/ioctl.h> 1424943Seric # include <sys/param.h> 1536928Sbostic # include <pwd.h> 163309Seric # include "sendmail.h" 1740980Sbostic # include "pathnames.h" 18404Seric 19294Seric /* 203309Seric ** CONF.C -- Sendmail Configuration Tables. 21294Seric ** 22294Seric ** Defines the configuration of this installation. 23294Seric ** 241388Seric ** Configuration Variables: 252897Seric ** HdrInfo -- a table describing well-known header fields. 262897Seric ** Each entry has the field name and some flags, 274147Seric ** which are described in sendmail.h. 284093Seric ** 294093Seric ** Notes: 304093Seric ** I have tried to put almost all the reasonable 314093Seric ** configuration information into the configuration 324093Seric ** file read at runtime. My intent is that anything 334093Seric ** here is a function of the version of UNIX you 344093Seric ** are running, or is really static -- for example 354093Seric ** the headers are a superset of widely used 364093Seric ** protocols. If you find yourself playing with 374093Seric ** this file too much, you may be making a mistake! 38294Seric */ 39294Seric 40294Seric 41294Seric 42294Seric 434437Seric /* 442897Seric ** Header info table 453057Seric ** Final (null) entry contains the flags used for any other field. 464147Seric ** 474147Seric ** Not all of these are actually handled specially by sendmail 484147Seric ** at this time. They are included as placeholders, to let 494147Seric ** you know that "someday" I intend to have sendmail do 504147Seric ** something with them. 512897Seric */ 522897Seric 532897Seric struct hdrinfo HdrInfo[] = 542897Seric { 558060Seric /* originator fields, most to least significant */ 5611417Seric "resent-sender", H_FROM|H_RESENT, 5711417Seric "resent-from", H_FROM|H_RESENT, 5825686Seric "resent-reply-to", H_FROM|H_RESENT, 599055Seric "sender", H_FROM, 609055Seric "from", H_FROM, 6125686Seric "reply-to", H_FROM, 629055Seric "full-name", H_ACHECK, 639055Seric "return-receipt-to", H_FROM, 649055Seric "errors-to", H_FROM, 658060Seric /* destination fields */ 669055Seric "to", H_RCPT, 6711417Seric "resent-to", H_RCPT|H_RESENT, 689055Seric "cc", H_RCPT, 6911417Seric "resent-cc", H_RCPT|H_RESENT, 709055Seric "bcc", H_RCPT|H_ACHECK, 7111417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 7256215Seric "apparently-to", H_RCPT, 738060Seric /* message identification and control */ 7411417Seric "message-id", 0, 7511417Seric "resent-message-id", H_RESENT, 769055Seric "message", H_EOH, 779055Seric "text", H_EOH, 7811417Seric /* date fields */ 7911417Seric "date", 0, 8011417Seric "resent-date", H_RESENT, 818060Seric /* trace fields */ 829055Seric "received", H_TRACE|H_FORCE, 839055Seric "via", H_TRACE|H_FORCE, 849055Seric "mail-from", H_TRACE|H_FORCE, 858060Seric 869055Seric NULL, 0, 872897Seric }; 884166Seric 894166Seric 904166Seric /* 914166Seric ** ARPANET error message numbers. 924166Seric */ 934166Seric 947956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 957956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 967956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 977956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 984282Seric 994282Seric 1004282Seric 1014282Seric /* 1024282Seric ** Location of system files/databases/etc. 1034282Seric */ 1044282Seric 10540980Sbostic char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */ 10640980Sbostic char *FreezeFile = _PATH_SENDMAILFC; /* frozen version of above */ 1079039Seric 1089064Seric 1099064Seric 1109039Seric /* 11124943Seric ** Miscellaneous stuff. 1129039Seric */ 1139039Seric 11424943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 11524943Seric /* 11624943Seric ** SETDEFAULTS -- set default values 11724943Seric ** 11824943Seric ** Because of the way freezing is done, these must be initialized 11924943Seric ** using direct code. 12024943Seric ** 12124943Seric ** Parameters: 12224943Seric ** none. 12324943Seric ** 12424943Seric ** Returns: 12524943Seric ** none. 12624943Seric ** 12724943Seric ** Side Effects: 12824943Seric ** Initializes a bunch of global variables to their 12924943Seric ** default values. 13024943Seric */ 13124943Seric 13224943Seric setdefaults() 13324943Seric { 13424943Seric QueueLA = 8; 13524943Seric QueueFactor = 10000; 13624943Seric RefuseLA = 12; 13724943Seric SpaceSub = ' '; 13824981Seric WkRecipFact = 1000; 13924981Seric WkClassFact = 1800; 14025812Seric WkTimeFact = 9000; 14157142Seric FileMode = (getuid() != geteuid()) ? 0644 : 0600; 14224981Seric DefUid = 1; 14324981Seric DefGid = 1; 14447284Seric CheckpointInterval = 10; 14557142Seric MaxHopCount = 17; 14652105Seric SendMode = SM_FORK; 14752105Seric ErrorMode = EM_PRINT; 14852106Seric EightBit = FALSE; 14954967Seric MaxMciCache = 1; 15054967Seric MciCacheTimeout = 300; 15140973Sbostic setdefuser(); 15253654Seric setupmaps(); 15324943Seric } 154294Seric 15540973Sbostic 1564326Seric /* 15740973Sbostic ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 15840973Sbostic */ 15940973Sbostic 16040973Sbostic setdefuser() 16140973Sbostic { 16240973Sbostic struct passwd *defpwent; 16340973Sbostic 16440973Sbostic if (DefUser != NULL) 16540973Sbostic free(DefUser); 16640973Sbostic if ((defpwent = getpwuid(DefUid)) != NULL) 16740973Sbostic DefUser = newstr(defpwent->pw_name); 16840973Sbostic else 16940973Sbostic DefUser = newstr("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 229*57208Seric # ifdef NIS_MAP 230*57208Seric /* NIS map access */ 231*57208Seric { 232*57208Seric extern bool nis_map_init(); 233*57208Seric extern char *nis_map_lookup(); 234*57208Seric 235*57208Seric s = stab("nis", ST_MAPCLASS, ST_ENTER); 236*57208Seric s->s_mapclass.map_init = nis_map_init; 237*57208Seric s->s_mapclass.map_lookup = nis_map_lookup; 238*57208Seric } 239*57208Seric # endif 240*57208Seric 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 } 28656836Seric 28756836Seric /* 2884326Seric ** GETRUID -- get real user id (V7) 2894326Seric */ 2904326Seric 2914326Seric getruid() 2924326Seric { 2939274Seric if (OpMode == MD_DAEMON) 2944536Seric return (RealUid); 2954536Seric else 2964536Seric return (getuid()); 2974326Seric } 2984326Seric 2994326Seric 3004326Seric /* 3014326Seric ** GETRGID -- get real group id (V7). 3024326Seric */ 3034326Seric 3044326Seric getrgid() 3054326Seric { 3069274Seric if (OpMode == MD_DAEMON) 3074536Seric return (RealGid); 3084536Seric else 3094536Seric return (getgid()); 3104326Seric } 31153654Seric /* 3129369Seric ** USERNAME -- return the user id of the logged in user. 3139369Seric ** 3149369Seric ** Parameters: 3159369Seric ** none. 3169369Seric ** 3179369Seric ** Returns: 3189369Seric ** The login name of the logged in user. 3199369Seric ** 3209369Seric ** Side Effects: 3219369Seric ** none. 3229369Seric ** 3239369Seric ** Notes: 3249369Seric ** The return value is statically allocated. 3259369Seric */ 3269369Seric 3279369Seric char * 3289369Seric username() 3299369Seric { 33017469Seric static char *myname = NULL; 3319369Seric extern char *getlogin(); 33219904Smiriam register struct passwd *pw; 3339369Seric 33417469Seric /* cache the result */ 33517469Seric if (myname == NULL) 33617469Seric { 33717469Seric myname = getlogin(); 33817469Seric if (myname == NULL || myname[0] == '\0') 33917469Seric { 34017469Seric 34117469Seric pw = getpwuid(getruid()); 34217469Seric if (pw != NULL) 34340993Sbostic myname = newstr(pw->pw_name); 34417469Seric } 34519904Smiriam else 34619904Smiriam { 34719873Smiriam 34840993Sbostic myname = newstr(myname); 34940993Sbostic if ((pw = getpwnam(myname)) == NULL || 35040993Sbostic getuid() != pw->pw_uid) 35119904Smiriam { 35219873Smiriam pw = getpwuid(getuid()); 35324945Seric if (pw != NULL) 35440993Sbostic myname = newstr(pw->pw_name); 35519873Smiriam } 35619873Smiriam } 35717469Seric if (myname == NULL || myname[0] == '\0') 35817469Seric { 35917469Seric syserr("Who are you?"); 36017469Seric myname = "postmaster"; 36117469Seric } 36217469Seric } 36317469Seric 36417469Seric return (myname); 3659369Seric } 3669369Seric /* 3674190Seric ** TTYPATH -- Get the path of the user's tty 368294Seric ** 369294Seric ** Returns the pathname of the user's tty. Returns NULL if 370294Seric ** the user is not logged in or if s/he has write permission 371294Seric ** denied. 372294Seric ** 373294Seric ** Parameters: 374294Seric ** none 375294Seric ** 376294Seric ** Returns: 377294Seric ** pathname of the user's tty. 378294Seric ** NULL if not logged in or write permission denied. 379294Seric ** 380294Seric ** Side Effects: 381294Seric ** none. 382294Seric ** 383294Seric ** WARNING: 384294Seric ** Return value is in a local buffer. 385294Seric ** 386294Seric ** Called By: 387294Seric ** savemail 388294Seric */ 389294Seric 390294Seric # include <sys/stat.h> 391294Seric 392294Seric char * 393294Seric ttypath() 394294Seric { 395294Seric struct stat stbuf; 396294Seric register char *pathn; 397294Seric extern char *ttyname(); 3984081Seric extern char *getlogin(); 399294Seric 400294Seric /* compute the pathname of the controlling tty */ 4019369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 4029369Seric (pathn = ttyname(0)) == NULL) 403294Seric { 404294Seric errno = 0; 405294Seric return (NULL); 406294Seric } 407294Seric 408294Seric /* see if we have write permission */ 4092967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 410294Seric { 411294Seric errno = 0; 412294Seric return (NULL); 413294Seric } 414294Seric 415294Seric /* see if the user is logged in */ 416294Seric if (getlogin() == NULL) 417294Seric return (NULL); 418294Seric 419294Seric /* looks good */ 420294Seric return (pathn); 421294Seric } 4222967Seric /* 4232967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4242967Seric ** 4252967Seric ** This routine can be supplied on a per-installation basis 4262967Seric ** to determine whether a person is allowed to send a message. 4272967Seric ** This allows restriction of certain types of internet 4282967Seric ** forwarding or registration of users. 4292967Seric ** 4302967Seric ** If the hosts are found to be incompatible, an error 4312967Seric ** message should be given using "usrerr" and FALSE should 4322967Seric ** be returned. 4332967Seric ** 4344288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4354288Seric ** function; this should be done on huge messages. 4364288Seric ** 4372967Seric ** Parameters: 4382967Seric ** to -- the person being sent to. 4392967Seric ** 4402967Seric ** Returns: 4412967Seric ** TRUE -- ok to send. 4422967Seric ** FALSE -- not ok. 4432967Seric ** 4442967Seric ** Side Effects: 4452967Seric ** none (unless you include the usrerr stuff) 4462967Seric */ 4472967Seric 4482967Seric bool 44955012Seric checkcompat(to, e) 4502967Seric register ADDRESS *to; 45155012Seric register ENVELOPE *e; 4522967Seric { 45312133Seric # ifdef lint 45412133Seric if (to == NULL) 45512133Seric to++; 45612133Seric # endif lint 45710698Seric # ifdef EXAMPLE_CODE 45810698Seric /* this code is intended as an example only */ 4594437Seric register STAB *s; 4604437Seric 4614437Seric s = stab("arpa", ST_MAILER, ST_FIND); 46255012Seric if (s != NULL && e->e_from.q_mailer != LocalMailer && 4639369Seric to->q_mailer == s->s_mailer) 4644437Seric { 4654437Seric usrerr("No ARPA mail through this machine: see your system administration"); 46610698Seric /* NoReturn = TRUE; to supress return copy */ 4674437Seric return (FALSE); 4684437Seric } 46956795Seric # endif /* EXAMPLE_CODE */ 4702967Seric return (TRUE); 4712967Seric } 4729369Seric /* 4739369Seric ** HOLDSIGS -- arrange to hold all signals 4749369Seric ** 4759369Seric ** Parameters: 4769369Seric ** none. 4779369Seric ** 4789369Seric ** Returns: 4799369Seric ** none. 4809369Seric ** 4819369Seric ** Side Effects: 4829369Seric ** Arranges that signals are held. 4839369Seric */ 4849369Seric 4859369Seric holdsigs() 4869369Seric { 4879369Seric } 4889369Seric /* 4899369Seric ** RLSESIGS -- arrange to release all signals 4909369Seric ** 4919369Seric ** This undoes the effect of holdsigs. 4929369Seric ** 4939369Seric ** Parameters: 4949369Seric ** none. 4959369Seric ** 4969369Seric ** Returns: 4979369Seric ** none. 4989369Seric ** 4999369Seric ** Side Effects: 5009369Seric ** Arranges that signals are released. 5019369Seric */ 5029369Seric 5039369Seric rlsesigs() 5049369Seric { 5059369Seric } 50614872Seric /* 50714872Seric ** GETLA -- get the current load average 50814872Seric ** 50914881Seric ** This code stolen from la.c. 51014881Seric ** 51114872Seric ** Parameters: 51214872Seric ** none. 51314872Seric ** 51414872Seric ** Returns: 51514872Seric ** The current load average as an integer. 51614872Seric ** 51714872Seric ** Side Effects: 51814872Seric ** none. 51914872Seric */ 52014872Seric 52151920Seric /* try to guess what style of load average we have */ 52251920Seric #define LA_ZERO 1 /* always return load average as zero */ 52351920Seric #define LA_INT 2 /* read kmem for avenrun; interpret as int */ 52451920Seric #define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ 52551920Seric #define LA_SUBR 4 /* call getloadavg */ 52614872Seric 52751920Seric #ifndef LA_TYPE 52851920Seric # if defined(sun) 52951920Seric # define LA_TYPE LA_INT 53051920Seric # endif 53151920Seric # if defined(mips) 53251920Seric /* Ultrix or RISC/os */ 53351920Seric # define LA_TYPE LA_INT 53451920Seric # define LA_AVENRUN "avenrun" 53551920Seric # endif 53651920Seric # if defined(hpux) 53751920Seric # define LA_TYPE LA_FLOAT 53851920Seric # endif 53951920Seric # if defined(BSD) 54051920Seric # define LA_TYPE LA_SUBR 54151920Seric # endif 54251920Seric 54351920Seric # ifndef LA_TYPE 54451920Seric # define LA_TYPE LA_ZERO 54551920Seric # endif 54651920Seric #endif 54751920Seric 54851920Seric #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) 54951920Seric 55014872Seric #include <nlist.h> 55151920Seric #include <fcntl.h> 55214872Seric 55351920Seric #ifndef LA_AVENRUN 55451920Seric #define LA_AVENRUN "_avenrun" 55551920Seric #endif 55651920Seric 55751920Seric /* _PATH_UNIX should be defined in <paths.h> */ 55851920Seric #ifndef _PATH_UNIX 55951920Seric # if defined(hpux) 56051920Seric # define _PATH_UNIX "/hp-ux" 56151920Seric # endif 56251920Seric # if defined(mips) && !defined(ultrix) 56351920Seric /* powerful RISC/os */ 56451920Seric # define _PATH_UNIX "/unix" 56551920Seric # endif 56651920Seric # ifndef _PATH_UNIX 56751920Seric # define _PATH_UNIX "/vmunix" 56851920Seric # endif 56951920Seric #endif 57051920Seric 57114872Seric struct nlist Nl[] = 57214872Seric { 57351920Seric { LA_AVENRUN }, 57414872Seric #define X_AVENRUN 0 57514872Seric { 0 }, 57614872Seric }; 57714872Seric 57851920Seric #if (LA_TYPE == LA_INT) && !defined(FSHIFT) 57951920Seric # define FSHIFT 8 58051920Seric # define FSCALE (1 << FSHIFT) 58151920Seric #endif 58240930Srick 58314872Seric getla() 58414872Seric { 58514872Seric static int kmem = -1; 58651920Seric #if LA_TYPE == LA_INT 58724943Seric long avenrun[3]; 58851920Seric #else 58951920Seric double avenrun[3]; 59051920Seric #endif 59125615Seric extern off_t lseek(); 59214872Seric 59314872Seric if (kmem < 0) 59414872Seric { 59524945Seric kmem = open("/dev/kmem", 0, 0); 59614872Seric if (kmem < 0) 59714872Seric return (-1); 59851920Seric (void) fcntl(kmem, F_SETFD, 1); 59951920Seric nlist(_PATH_UNIX, Nl); 60014872Seric if (Nl[0].n_type == 0) 60114872Seric return (-1); 60214872Seric } 60324945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 60423118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 60519967Seric { 60619967Seric /* thank you Ian */ 60719967Seric return (-1); 60819967Seric } 60951920Seric #if LA_TYPE == LA_INT 61024943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 61151920Seric #else 61251920Seric return ((int) (avenrun[0] + 0.5)); 61351920Seric #endif 61414872Seric } 61514872Seric 61651773Seric #else 61751920Seric #if LA_TYPE == LA_SUBR 61851773Seric 61951773Seric getla() 62051773Seric { 62151920Seric double avenrun[3]; 62251920Seric 62351920Seric if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 62451920Seric return (-1); 62551920Seric return ((int) (avenrun[0] + 0.5)); 62651773Seric } 62751773Seric 62851773Seric #else 62951773Seric 63051773Seric getla() 63151773Seric { 63251920Seric return (0); 63351773Seric } 63451773Seric 63551773Seric #endif 63651773Seric #endif 63724943Seric /* 63824943Seric ** SHOULDQUEUE -- should this message be queued or sent? 63924943Seric ** 64024943Seric ** Compares the message cost to the load average to decide. 64124943Seric ** 64224943Seric ** Parameters: 64324943Seric ** pri -- the priority of the message in question. 64424943Seric ** 64524943Seric ** Returns: 64624943Seric ** TRUE -- if this message should be queued up for the 64724943Seric ** time being. 64824943Seric ** FALSE -- if the load is low enough to send this message. 64924943Seric ** 65024943Seric ** Side Effects: 65124943Seric ** none. 65224943Seric */ 65324943Seric 65424943Seric bool 65524943Seric shouldqueue(pri) 65624943Seric long pri; 65724943Seric { 65851920Seric if (CurrentLA < QueueLA) 65924943Seric return (FALSE); 66051920Seric return (pri > (QueueFactor / (CurrentLA - QueueLA + 1))); 66124943Seric } 66224943Seric /* 66353037Seric ** REFUSECONNECTIONS -- decide if connections should be refused 66453037Seric ** 66553037Seric ** Parameters: 66653037Seric ** none. 66753037Seric ** 66853037Seric ** Returns: 66953037Seric ** TRUE if incoming SMTP connections should be refused 67053037Seric ** (for now). 67153037Seric ** FALSE if we should accept new work. 67253037Seric ** 67353037Seric ** Side Effects: 67453037Seric ** none. 67553037Seric */ 67653037Seric 67753037Seric bool 67853037Seric refuseconnections() 67953037Seric { 68053037Seric /* this is probably too simplistic */ 68153037Seric return (CurrentLA > RefuseLA); 68253037Seric } 68353037Seric /* 68424943Seric ** SETPROCTITLE -- set process title for ps 68524943Seric ** 68624943Seric ** Parameters: 68724943Seric ** fmt -- a printf style format string. 68824943Seric ** a, b, c -- possible parameters to fmt. 68924943Seric ** 69024943Seric ** Returns: 69124943Seric ** none. 69224943Seric ** 69324943Seric ** Side Effects: 69424943Seric ** Clobbers argv of our main procedure so ps(1) will 69524943Seric ** display the title. 69624943Seric */ 69724943Seric 69824943Seric /*VARARGS1*/ 69956852Seric setproctitle(fmt VA_ARG_FORMAL) 70024943Seric char *fmt; 70156852Seric VA_ARG_DECL 70224943Seric { 70324943Seric # ifdef SETPROCTITLE 70424943Seric register char *p; 70525049Seric register int i; 70656852Seric char buf[MAXLINE]; 70756852Seric VA_LOCAL_DECL 70824943Seric extern char **Argv; 70924943Seric extern char *LastArgv; 71024943Seric 71154996Seric p = buf; 71224943Seric 71354996Seric /* print sendmail: heading for grep */ 71454996Seric (void) strcpy(p, "sendmail: "); 71554996Seric p += strlen(p); 71624943Seric 71754996Seric /* print the argument string */ 71856852Seric VA_START(fmt); 71956852Seric (void) vsprintf(p, fmt, ap); 72056852Seric VA_END; 72154996Seric 72225049Seric i = strlen(buf); 72354996Seric if (i > LastArgv - Argv[0] - 2) 72425049Seric { 72554996Seric i = LastArgv - Argv[0] - 2; 72625049Seric buf[i] = '\0'; 72725049Seric } 72854996Seric (void) strcpy(Argv[0], buf); 72954997Seric p = &Argv[0][i]; 73024943Seric while (p < LastArgv) 73124943Seric *p++ = ' '; 73256795Seric # endif /* SETPROCTITLE */ 73324943Seric } 73425698Seric /* 73525698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 73625698Seric ** 73725698Seric ** Parameters: 73825698Seric ** none. 73925698Seric ** 74025698Seric ** Returns: 74125698Seric ** none. 74225698Seric ** 74325698Seric ** Side Effects: 74425698Seric ** Picks up extant zombies. 74525698Seric */ 74625698Seric 74725698Seric # include <sys/wait.h> 74825698Seric 74946928Sbostic void 75025698Seric reapchild() 75125698Seric { 75225698Seric # ifdef WNOHANG 75325698Seric union wait status; 75425698Seric 75546928Sbostic while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0) 75625698Seric continue; 75756795Seric # else /* WNOHANG */ 75825698Seric auto int status; 75925698Seric 76046928Sbostic while (wait((int *)&status) > 0) 76125698Seric continue; 76256795Seric # endif /* WNOHANG */ 76325698Seric } 76455418Seric /* 76555418Seric ** UNSETENV -- remove a variable from the environment 76655418Seric ** 76755418Seric ** Not needed on newer systems. 76855418Seric ** 76955418Seric ** Parameters: 77055418Seric ** name -- the string name of the environment variable to be 77155418Seric ** deleted from the current environment. 77255418Seric ** 77355418Seric ** Returns: 77455418Seric ** none. 77555418Seric ** 77655418Seric ** Globals: 77755418Seric ** environ -- a pointer to the current environment. 77855418Seric ** 77955418Seric ** Side Effects: 78055418Seric ** Modifies environ. 78155418Seric */ 78255418Seric 78355418Seric #ifdef UNSETENV 78455418Seric 78555418Seric void 78655418Seric unsetenv(name) 78755418Seric char *name; 78855418Seric { 78955418Seric extern char **environ; 79055418Seric register char **pp; 79155418Seric int len = strlen(name); 79255418Seric 79355418Seric for (pp = environ; *pp != NULL; pp++) 79455418Seric { 79555418Seric if (strncmp(name, *pp, len) == 0 && 79655418Seric ((*pp)[len] == '=' || (*pp)[len] == '\0')) 79755418Seric break; 79855418Seric } 79955418Seric 80055418Seric for (; *pp != NULL; pp++) 80155418Seric *pp = pp[1]; 80255418Seric } 80355418Seric 80455418Seric #endif /* UNSETENV */ 80556215Seric /* 80656215Seric ** GETDTABLESIZE -- return number of file descriptors 80756215Seric ** 80856215Seric ** Only on non-BSD systems 80956215Seric ** 81056215Seric ** Parameters: 81156215Seric ** none 81256215Seric ** 81356215Seric ** Returns: 81456215Seric ** size of file descriptor table 81556215Seric ** 81656215Seric ** Side Effects: 81756215Seric ** none 81856215Seric */ 81956215Seric 82056215Seric #ifdef SYSTEM5 82156215Seric 82256215Seric int 82356215Seric getdtablesize() 82456215Seric { 82556215Seric return NOFILE; 82656215Seric } 82756215Seric 82856215Seric #endif 829