1c2aa98e2SPeter Wemm /* 2c2aa98e2SPeter Wemm * Copyright (c) 1998 Sendmail, Inc. All rights reserved. 3c2aa98e2SPeter Wemm * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 4c2aa98e2SPeter Wemm * Copyright (c) 1988, 1993 5c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved. 6c2aa98e2SPeter Wemm * 7c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set 8c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of 9c2aa98e2SPeter Wemm * the sendmail distribution. 10c2aa98e2SPeter Wemm * 11c2aa98e2SPeter Wemm */ 12c2aa98e2SPeter Wemm 13c2aa98e2SPeter Wemm #ifndef lint 14e01d6f61SPeter Wemm static char sccsid[] = "@(#)conf.c 8.452 (Berkeley) 1/26/1999"; 15c2aa98e2SPeter Wemm #endif /* not lint */ 16c2aa98e2SPeter Wemm 17c2aa98e2SPeter Wemm # include "sendmail.h" 18c2aa98e2SPeter Wemm # include "pathnames.h" 19c2aa98e2SPeter Wemm # include <sys/ioctl.h> 20c2aa98e2SPeter Wemm # include <sys/param.h> 21c2aa98e2SPeter Wemm # include <limits.h> 22c2aa98e2SPeter Wemm 23c2aa98e2SPeter Wemm /* 24c2aa98e2SPeter Wemm ** CONF.C -- Sendmail Configuration Tables. 25c2aa98e2SPeter Wemm ** 26c2aa98e2SPeter Wemm ** Defines the configuration of this installation. 27c2aa98e2SPeter Wemm ** 28c2aa98e2SPeter Wemm ** Configuration Variables: 29c2aa98e2SPeter Wemm ** HdrInfo -- a table describing well-known header fields. 30c2aa98e2SPeter Wemm ** Each entry has the field name and some flags, 31c2aa98e2SPeter Wemm ** which are described in sendmail.h. 32c2aa98e2SPeter Wemm ** 33c2aa98e2SPeter Wemm ** Notes: 34c2aa98e2SPeter Wemm ** I have tried to put almost all the reasonable 35c2aa98e2SPeter Wemm ** configuration information into the configuration 36c2aa98e2SPeter Wemm ** file read at runtime. My intent is that anything 37c2aa98e2SPeter Wemm ** here is a function of the version of UNIX you 38c2aa98e2SPeter Wemm ** are running, or is really static -- for example 39c2aa98e2SPeter Wemm ** the headers are a superset of widely used 40c2aa98e2SPeter Wemm ** protocols. If you find yourself playing with 41c2aa98e2SPeter Wemm ** this file too much, you may be making a mistake! 42c2aa98e2SPeter Wemm */ 43c2aa98e2SPeter Wemm 44c2aa98e2SPeter Wemm 45c2aa98e2SPeter Wemm /* 46c2aa98e2SPeter Wemm ** Header info table 47c2aa98e2SPeter Wemm ** Final (null) entry contains the flags used for any other field. 48c2aa98e2SPeter Wemm ** 49c2aa98e2SPeter Wemm ** Not all of these are actually handled specially by sendmail 50c2aa98e2SPeter Wemm ** at this time. They are included as placeholders, to let 51c2aa98e2SPeter Wemm ** you know that "someday" I intend to have sendmail do 52c2aa98e2SPeter Wemm ** something with them. 53c2aa98e2SPeter Wemm */ 54c2aa98e2SPeter Wemm 55c2aa98e2SPeter Wemm struct hdrinfo HdrInfo[] = 56c2aa98e2SPeter Wemm { 57c2aa98e2SPeter Wemm /* originator fields, most to least significant */ 58c2aa98e2SPeter Wemm { "resent-sender", H_FROM|H_RESENT }, 59c2aa98e2SPeter Wemm { "resent-from", H_FROM|H_RESENT }, 60c2aa98e2SPeter Wemm { "resent-reply-to", H_FROM|H_RESENT }, 61c2aa98e2SPeter Wemm { "sender", H_FROM }, 62c2aa98e2SPeter Wemm { "from", H_FROM }, 63c2aa98e2SPeter Wemm { "reply-to", H_FROM }, 64c2aa98e2SPeter Wemm { "errors-to", H_FROM|H_ERRORSTO }, 65c2aa98e2SPeter Wemm { "full-name", H_ACHECK }, 66c2aa98e2SPeter Wemm { "return-receipt-to", H_RECEIPTTO }, 67c2aa98e2SPeter Wemm 68c2aa98e2SPeter Wemm /* destination fields */ 69c2aa98e2SPeter Wemm { "to", H_RCPT }, 70c2aa98e2SPeter Wemm { "resent-to", H_RCPT|H_RESENT }, 71c2aa98e2SPeter Wemm { "cc", H_RCPT }, 72c2aa98e2SPeter Wemm { "resent-cc", H_RCPT|H_RESENT }, 73c2aa98e2SPeter Wemm { "bcc", H_RCPT|H_BCC }, 74c2aa98e2SPeter Wemm { "resent-bcc", H_RCPT|H_BCC|H_RESENT }, 75c2aa98e2SPeter Wemm { "apparently-to", H_RCPT }, 76c2aa98e2SPeter Wemm 77c2aa98e2SPeter Wemm /* message identification and control */ 78c2aa98e2SPeter Wemm { "message-id", 0 }, 79c2aa98e2SPeter Wemm { "resent-message-id", H_RESENT }, 80c2aa98e2SPeter Wemm { "message", H_EOH }, 81c2aa98e2SPeter Wemm { "text", H_EOH }, 82c2aa98e2SPeter Wemm 83c2aa98e2SPeter Wemm /* date fields */ 84c2aa98e2SPeter Wemm { "date", 0 }, 85c2aa98e2SPeter Wemm { "resent-date", H_RESENT }, 86c2aa98e2SPeter Wemm 87c2aa98e2SPeter Wemm /* trace fields */ 88c2aa98e2SPeter Wemm { "received", H_TRACE|H_FORCE }, 89c2aa98e2SPeter Wemm { "x400-received", H_TRACE|H_FORCE }, 90c2aa98e2SPeter Wemm { "via", H_TRACE|H_FORCE }, 91c2aa98e2SPeter Wemm { "mail-from", H_TRACE|H_FORCE }, 92c2aa98e2SPeter Wemm 93c2aa98e2SPeter Wemm /* miscellaneous fields */ 94c2aa98e2SPeter Wemm { "comments", H_FORCE|H_ENCODABLE }, 95c2aa98e2SPeter Wemm { "return-path", H_FORCE|H_ACHECK }, 96c2aa98e2SPeter Wemm { "content-transfer-encoding", H_CTE }, 97c2aa98e2SPeter Wemm { "content-type", H_CTYPE }, 98c2aa98e2SPeter Wemm { "content-length", H_ACHECK }, 99c2aa98e2SPeter Wemm { "subject", H_ENCODABLE }, 100c2aa98e2SPeter Wemm 101c2aa98e2SPeter Wemm { NULL, 0 } 102c2aa98e2SPeter Wemm }; 103c2aa98e2SPeter Wemm 104c2aa98e2SPeter Wemm 105c2aa98e2SPeter Wemm 106c2aa98e2SPeter Wemm /* 107c2aa98e2SPeter Wemm ** Privacy values 108c2aa98e2SPeter Wemm */ 109c2aa98e2SPeter Wemm 110c2aa98e2SPeter Wemm struct prival PrivacyValues[] = 111c2aa98e2SPeter Wemm { 112c2aa98e2SPeter Wemm { "public", PRIV_PUBLIC }, 113c2aa98e2SPeter Wemm { "needmailhelo", PRIV_NEEDMAILHELO }, 114c2aa98e2SPeter Wemm { "needexpnhelo", PRIV_NEEDEXPNHELO }, 115c2aa98e2SPeter Wemm { "needvrfyhelo", PRIV_NEEDVRFYHELO }, 116c2aa98e2SPeter Wemm { "noexpn", PRIV_NOEXPN }, 117c2aa98e2SPeter Wemm { "novrfy", PRIV_NOVRFY }, 118c2aa98e2SPeter Wemm { "restrictmailq", PRIV_RESTRICTMAILQ }, 119c2aa98e2SPeter Wemm { "restrictqrun", PRIV_RESTRICTQRUN }, 120c2aa98e2SPeter Wemm { "noetrn", PRIV_NOETRN }, 121c2aa98e2SPeter Wemm { "noverb", PRIV_NOVERB }, 122c2aa98e2SPeter Wemm { "authwarnings", PRIV_AUTHWARNINGS }, 123c2aa98e2SPeter Wemm { "noreceipts", PRIV_NORECEIPTS }, 124c2aa98e2SPeter Wemm { "goaway", PRIV_GOAWAY }, 125c2aa98e2SPeter Wemm { NULL, 0 } 126c2aa98e2SPeter Wemm }; 127c2aa98e2SPeter Wemm 128c2aa98e2SPeter Wemm /* 129c2aa98e2SPeter Wemm ** DontBlameSendmail values 130c2aa98e2SPeter Wemm */ 131c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] = 132c2aa98e2SPeter Wemm { 133c2aa98e2SPeter Wemm { "safe", DBS_SAFE }, 134c2aa98e2SPeter Wemm { "assumesafechown", DBS_ASSUMESAFECHOWN }, 135c2aa98e2SPeter Wemm { "groupwritabledirpathsafe", DBS_GROUPWRITABLEDIRPATHSAFE }, 136c2aa98e2SPeter Wemm { "groupwritableforwardfilesafe", 137c2aa98e2SPeter Wemm DBS_GROUPWRITABLEFORWARDFILESAFE }, 138c2aa98e2SPeter Wemm { "groupwritableincludefilesafe", 139c2aa98e2SPeter Wemm DBS_GROUPWRITABLEINCLUDEFILESAFE }, 140c2aa98e2SPeter Wemm { "groupwritablealiasfile", DBS_GROUPWRITABLEALIASFILE }, 141c2aa98e2SPeter Wemm { "worldwritablealiasfile", DBS_WORLDWRITABLEALIASFILE }, 142c2aa98e2SPeter Wemm { "forwardfileinunsafedirpath", DBS_FORWARDFILEINUNSAFEDIRPATH }, 143c2aa98e2SPeter Wemm { "includefileinunsafedirpath", DBS_INCLUDEFILEINUNSAFEDIRPATH }, 144c2aa98e2SPeter Wemm { "mapinunsafedirpath", DBS_MAPINUNSAFEDIRPATH }, 145c2aa98e2SPeter Wemm { "linkedaliasfileinwritabledir", 146c2aa98e2SPeter Wemm DBS_LINKEDALIASFILEINWRITABLEDIR }, 147c2aa98e2SPeter Wemm { "linkedclassfileinwritabledir", 148c2aa98e2SPeter Wemm DBS_LINKEDCLASSFILEINWRITABLEDIR }, 149c2aa98e2SPeter Wemm { "linkedforwardfileinwritabledir", 150c2aa98e2SPeter Wemm DBS_LINKEDFORWARDFILEINWRITABLEDIR }, 151c2aa98e2SPeter Wemm { "linkedincludefileinwritabledir", 152c2aa98e2SPeter Wemm DBS_LINKEDINCLUDEFILEINWRITABLEDIR }, 153c2aa98e2SPeter Wemm { "linkedmapinwritabledir", DBS_LINKEDMAPINWRITABLEDIR }, 154c2aa98e2SPeter Wemm { "linkedserviceswitchfileinwritabledir", 155c2aa98e2SPeter Wemm DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR }, 156c2aa98e2SPeter Wemm { "filedeliverytohardlink", DBS_FILEDELIVERYTOHARDLINK }, 157c2aa98e2SPeter Wemm { "filedeliverytosymlink", DBS_FILEDELIVERYTOSYMLINK }, 158c2aa98e2SPeter Wemm { "writemaptohardlink", DBS_WRITEMAPTOHARDLINK }, 159c2aa98e2SPeter Wemm { "writemaptosymlink", DBS_WRITEMAPTOSYMLINK }, 160c2aa98e2SPeter Wemm { "writestatstohardlink", DBS_WRITESTATSTOHARDLINK }, 161c2aa98e2SPeter Wemm { "writestatstosymlink", DBS_WRITESTATSTOSYMLINK }, 162c2aa98e2SPeter Wemm { "forwardfileingroupwritabledirpath", 163c2aa98e2SPeter Wemm DBS_FORWARDFILEINGROUPWRITABLEDIRPATH }, 164c2aa98e2SPeter Wemm { "includefileingroupwritabledirpath", 165c2aa98e2SPeter Wemm DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH }, 166c2aa98e2SPeter Wemm { "classfileinunsafedirpath", DBS_CLASSFILEINUNSAFEDIRPATH }, 167c2aa98e2SPeter Wemm { "errorheaderinunsafedirpath", DBS_ERRORHEADERINUNSAFEDIRPATH }, 168c2aa98e2SPeter Wemm { "helpfileinunsafedirpath", DBS_HELPFILEINUNSAFEDIRPATH }, 169c2aa98e2SPeter Wemm { "forwardfileinunsafedirpathsafe", 170c2aa98e2SPeter Wemm DBS_FORWARDFILEINUNSAFEDIRPATHSAFE }, 171c2aa98e2SPeter Wemm { "includefileinunsafedirpathsafe", 172c2aa98e2SPeter Wemm DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE }, 173c2aa98e2SPeter Wemm { "runprograminunsafedirpath", DBS_RUNPROGRAMINUNSAFEDIRPATH }, 174c2aa98e2SPeter Wemm { "runwritableprogram", DBS_RUNWRITABLEPROGRAM }, 175c2aa98e2SPeter Wemm { NULL, 0 } 176c2aa98e2SPeter Wemm }; 177c2aa98e2SPeter Wemm 178c2aa98e2SPeter Wemm 179c2aa98e2SPeter Wemm /* 180c2aa98e2SPeter Wemm ** Miscellaneous stuff. 181c2aa98e2SPeter Wemm */ 182c2aa98e2SPeter Wemm 183c2aa98e2SPeter Wemm int DtableSize = 50; /* max open files; reset in 4.2bsd */ 184c2aa98e2SPeter Wemm /* 185c2aa98e2SPeter Wemm ** SETDEFAULTS -- set default values 186c2aa98e2SPeter Wemm ** 187c2aa98e2SPeter Wemm ** Because of the way freezing is done, these must be initialized 188c2aa98e2SPeter Wemm ** using direct code. 189c2aa98e2SPeter Wemm ** 190c2aa98e2SPeter Wemm ** Parameters: 191c2aa98e2SPeter Wemm ** e -- the default envelope. 192c2aa98e2SPeter Wemm ** 193c2aa98e2SPeter Wemm ** Returns: 194c2aa98e2SPeter Wemm ** none. 195c2aa98e2SPeter Wemm ** 196c2aa98e2SPeter Wemm ** Side Effects: 197c2aa98e2SPeter Wemm ** Initializes a bunch of global variables to their 198c2aa98e2SPeter Wemm ** default values. 199c2aa98e2SPeter Wemm */ 200c2aa98e2SPeter Wemm 201c2aa98e2SPeter Wemm #define MINUTES * 60 202c2aa98e2SPeter Wemm #define HOURS * 60 MINUTES 203c2aa98e2SPeter Wemm #define DAYS * 24 HOURS 204c2aa98e2SPeter Wemm 205c2aa98e2SPeter Wemm #ifndef _PATH_VARTMP 206c2aa98e2SPeter Wemm # define _PATH_VARTMP "/usr/tmp/" 207c2aa98e2SPeter Wemm #endif 208c2aa98e2SPeter Wemm 209c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION 210c2aa98e2SPeter Wemm # define MAXRULERECURSION 50 /* max ruleset recursion depth */ 211c2aa98e2SPeter Wemm #endif 212c2aa98e2SPeter Wemm 213c2aa98e2SPeter Wemm void 214c2aa98e2SPeter Wemm setdefaults(e) 215c2aa98e2SPeter Wemm register ENVELOPE *e; 216c2aa98e2SPeter Wemm { 217c2aa98e2SPeter Wemm int i; 218c2aa98e2SPeter Wemm struct passwd *pw; 219c2aa98e2SPeter Wemm char buf[MAXNAME]; 220c2aa98e2SPeter Wemm extern void setdefuser __P((void)); 221c2aa98e2SPeter Wemm extern void setupmaps __P((void)); 222c2aa98e2SPeter Wemm extern void setupmailers __P((void)); 223c2aa98e2SPeter Wemm extern void setupheaders __P((void)); 224c2aa98e2SPeter Wemm 225c2aa98e2SPeter Wemm SpaceSub = ' '; /* option B */ 226c2aa98e2SPeter Wemm QueueLA = 8; /* option x */ 227c2aa98e2SPeter Wemm RefuseLA = 12; /* option X */ 228c2aa98e2SPeter Wemm WkRecipFact = 30000L; /* option y */ 229c2aa98e2SPeter Wemm WkClassFact = 1800L; /* option z */ 230c2aa98e2SPeter Wemm WkTimeFact = 90000L; /* option Z */ 231c2aa98e2SPeter Wemm QueueFactor = WkRecipFact * 20; /* option q */ 232c2aa98e2SPeter Wemm FileMode = (RealUid != geteuid()) ? 0644 : 0600; 233c2aa98e2SPeter Wemm /* option F */ 234c2aa98e2SPeter Wemm 235c2aa98e2SPeter Wemm if (((pw = getpwnam("mailnull")) != NULL && pw->pw_uid != 0) || 236c2aa98e2SPeter Wemm ((pw = getpwnam("sendmail")) != NULL && pw->pw_uid != 0) || 237c2aa98e2SPeter Wemm ((pw = getpwnam("daemon")) != NULL && pw->pw_uid != 0)) 238c2aa98e2SPeter Wemm { 239c2aa98e2SPeter Wemm DefUid = pw->pw_uid; /* option u */ 240c2aa98e2SPeter Wemm DefGid = pw->pw_gid; /* option g */ 241c2aa98e2SPeter Wemm DefUser = newstr(pw->pw_name); 242c2aa98e2SPeter Wemm } 243c2aa98e2SPeter Wemm else 244c2aa98e2SPeter Wemm { 245c2aa98e2SPeter Wemm DefUid = 1; /* option u */ 246c2aa98e2SPeter Wemm DefGid = 1; /* option g */ 247c2aa98e2SPeter Wemm setdefuser(); 248c2aa98e2SPeter Wemm } 24976b7bf71SPeter Wemm TrustedUid = 0; 250c2aa98e2SPeter Wemm if (tTd(37, 4)) 251c2aa98e2SPeter Wemm printf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n", 252c2aa98e2SPeter Wemm DefUser != NULL ? DefUser : "<1:1>", 253c2aa98e2SPeter Wemm (int) DefUid, (int) DefGid); 254c2aa98e2SPeter Wemm CheckpointInterval = 10; /* option C */ 255c2aa98e2SPeter Wemm MaxHopCount = 25; /* option h */ 256c2aa98e2SPeter Wemm e->e_sendmode = SM_FORK; /* option d */ 257c2aa98e2SPeter Wemm e->e_errormode = EM_PRINT; /* option e */ 258c2aa98e2SPeter Wemm SevenBitInput = FALSE; /* option 7 */ 259c2aa98e2SPeter Wemm MaxMciCache = 1; /* option k */ 260c2aa98e2SPeter Wemm MciCacheTimeout = 5 MINUTES; /* option K */ 261c2aa98e2SPeter Wemm LogLevel = 9; /* option L */ 262c2aa98e2SPeter Wemm inittimeouts(NULL); /* option r */ 263c2aa98e2SPeter Wemm PrivacyFlags = PRIV_PUBLIC; /* option p */ 264c2aa98e2SPeter Wemm DontBlameSendmail = DBS_SAFE; /* DontBlameSendmail option */ 265c2aa98e2SPeter Wemm #if MIME8TO7 266c2aa98e2SPeter Wemm MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */ 267c2aa98e2SPeter Wemm #else 268c2aa98e2SPeter Wemm MimeMode = MM_PASS8BIT; 269c2aa98e2SPeter Wemm #endif 270c2aa98e2SPeter Wemm for (i = 0; i < MAXTOCLASS; i++) 271c2aa98e2SPeter Wemm { 272c2aa98e2SPeter Wemm TimeOuts.to_q_return[i] = 5 DAYS; /* option T */ 273c2aa98e2SPeter Wemm TimeOuts.to_q_warning[i] = 0; /* option T */ 274c2aa98e2SPeter Wemm } 275c2aa98e2SPeter Wemm ServiceSwitchFile = "/etc/service.switch"; 276c2aa98e2SPeter Wemm ServiceCacheMaxAge = (time_t) 10; 277c2aa98e2SPeter Wemm HostsFile = _PATH_HOSTS; 278c2aa98e2SPeter Wemm PidFile = newstr(_PATH_SENDMAILPID); 279c2aa98e2SPeter Wemm MustQuoteChars = "@,;:\\()[].'"; 280c2aa98e2SPeter Wemm MciInfoTimeout = 30 MINUTES; 281c2aa98e2SPeter Wemm MaxRuleRecursion = MAXRULERECURSION; 282c2aa98e2SPeter Wemm MaxAliasRecursion = 10; 283c2aa98e2SPeter Wemm MaxMacroRecursion = 10; 284c2aa98e2SPeter Wemm ColonOkInAddr = TRUE; 285c2aa98e2SPeter Wemm DontLockReadFiles = TRUE; 286c2aa98e2SPeter Wemm DoubleBounceAddr = "postmaster"; 287e01d6f61SPeter Wemm MaxHeadersLength = MAXHDRSLEN; 288c2aa98e2SPeter Wemm snprintf(buf, sizeof buf, "%s%sdead.letter", 289c2aa98e2SPeter Wemm _PATH_VARTMP, 290c2aa98e2SPeter Wemm _PATH_VARTMP[sizeof _PATH_VARTMP - 2] == '/' ? "" : "/"); 291c2aa98e2SPeter Wemm DeadLetterDrop = newstr(buf); 292c2aa98e2SPeter Wemm #ifdef HESIOD_INIT 293c2aa98e2SPeter Wemm HesiodContext = NULL; 294c2aa98e2SPeter Wemm #endif 29576b7bf71SPeter Wemm ControlSocketName = NULL; 296c2aa98e2SPeter Wemm setupmaps(); 297c2aa98e2SPeter Wemm setupmailers(); 298c2aa98e2SPeter Wemm setupheaders(); 299c2aa98e2SPeter Wemm } 300c2aa98e2SPeter Wemm 301c2aa98e2SPeter Wemm 302c2aa98e2SPeter Wemm /* 303c2aa98e2SPeter Wemm ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 304c2aa98e2SPeter Wemm */ 305c2aa98e2SPeter Wemm 306c2aa98e2SPeter Wemm void 307c2aa98e2SPeter Wemm setdefuser() 308c2aa98e2SPeter Wemm { 309c2aa98e2SPeter Wemm struct passwd *defpwent; 310c2aa98e2SPeter Wemm static char defuserbuf[40]; 311c2aa98e2SPeter Wemm 312c2aa98e2SPeter Wemm DefUser = defuserbuf; 313c2aa98e2SPeter Wemm defpwent = sm_getpwuid(DefUid); 314c2aa98e2SPeter Wemm snprintf(defuserbuf, sizeof defuserbuf, "%s", 315c2aa98e2SPeter Wemm defpwent == NULL ? "nobody" : defpwent->pw_name); 316c2aa98e2SPeter Wemm if (tTd(37, 4)) 317c2aa98e2SPeter Wemm printf("setdefuser: DefUid=%d, DefUser=%s\n", 318c2aa98e2SPeter Wemm (int) DefUid, DefUser); 319c2aa98e2SPeter Wemm } 320c2aa98e2SPeter Wemm /* 321c2aa98e2SPeter Wemm ** SETUPMAILERS -- initialize default mailers 322c2aa98e2SPeter Wemm */ 323c2aa98e2SPeter Wemm 324c2aa98e2SPeter Wemm void 325c2aa98e2SPeter Wemm setupmailers() 326c2aa98e2SPeter Wemm { 327c2aa98e2SPeter Wemm char buf[100]; 328c2aa98e2SPeter Wemm 329c2aa98e2SPeter Wemm strcpy(buf, "prog, P=/bin/sh, F=lsoDq9, T=DNS/RFC822/X-Unix, A=sh -c \201u"); 330c2aa98e2SPeter Wemm makemailer(buf); 331c2aa98e2SPeter Wemm 332c2aa98e2SPeter Wemm strcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=DNS/RFC822/X-Unix, A=FILE \201u"); 333c2aa98e2SPeter Wemm makemailer(buf); 334c2aa98e2SPeter Wemm 335c2aa98e2SPeter Wemm strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u"); 336c2aa98e2SPeter Wemm makemailer(buf); 337c2aa98e2SPeter Wemm } 338c2aa98e2SPeter Wemm /* 339c2aa98e2SPeter Wemm ** SETUPMAPS -- set up map classes 340c2aa98e2SPeter Wemm */ 341c2aa98e2SPeter Wemm 342c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \ 343c2aa98e2SPeter Wemm { \ 344c2aa98e2SPeter Wemm extern bool parse __P((MAP *, char *)); \ 345c2aa98e2SPeter Wemm extern bool open __P((MAP *, int)); \ 346c2aa98e2SPeter Wemm extern void close __P((MAP *)); \ 347c2aa98e2SPeter Wemm extern char *lookup __P((MAP *, char *, char **, int *)); \ 348c2aa98e2SPeter Wemm extern void store __P((MAP *, char *, char *)); \ 349c2aa98e2SPeter Wemm s = stab(name, ST_MAPCLASS, ST_ENTER); \ 350c2aa98e2SPeter Wemm s->s_mapclass.map_cname = name; \ 351c2aa98e2SPeter Wemm s->s_mapclass.map_ext = ext; \ 352c2aa98e2SPeter Wemm s->s_mapclass.map_cflags = flags; \ 353c2aa98e2SPeter Wemm s->s_mapclass.map_parse = parse; \ 354c2aa98e2SPeter Wemm s->s_mapclass.map_open = open; \ 355c2aa98e2SPeter Wemm s->s_mapclass.map_close = close; \ 356c2aa98e2SPeter Wemm s->s_mapclass.map_lookup = lookup; \ 357c2aa98e2SPeter Wemm s->s_mapclass.map_store = store; \ 358c2aa98e2SPeter Wemm } 359c2aa98e2SPeter Wemm 360c2aa98e2SPeter Wemm void 361c2aa98e2SPeter Wemm setupmaps() 362c2aa98e2SPeter Wemm { 363c2aa98e2SPeter Wemm register STAB *s; 364c2aa98e2SPeter Wemm 365c2aa98e2SPeter Wemm #ifdef NEWDB 366c2aa98e2SPeter Wemm MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, 367c2aa98e2SPeter Wemm map_parseargs, hash_map_open, db_map_close, 368c2aa98e2SPeter Wemm db_map_lookup, db_map_store); 369c2aa98e2SPeter Wemm 370c2aa98e2SPeter Wemm MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE, 371c2aa98e2SPeter Wemm map_parseargs, bt_map_open, db_map_close, 372c2aa98e2SPeter Wemm db_map_lookup, db_map_store); 373c2aa98e2SPeter Wemm #endif 374c2aa98e2SPeter Wemm 375c2aa98e2SPeter Wemm #ifdef NDBM 376c2aa98e2SPeter Wemm MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE, 377c2aa98e2SPeter Wemm map_parseargs, ndbm_map_open, ndbm_map_close, 378c2aa98e2SPeter Wemm ndbm_map_lookup, ndbm_map_store); 379c2aa98e2SPeter Wemm #endif 380c2aa98e2SPeter Wemm 381c2aa98e2SPeter Wemm #ifdef NIS 382c2aa98e2SPeter Wemm MAPDEF("nis", NULL, MCF_ALIASOK, 383c2aa98e2SPeter Wemm map_parseargs, nis_map_open, null_map_close, 384c2aa98e2SPeter Wemm nis_map_lookup, null_map_store); 385c2aa98e2SPeter Wemm #endif 386c2aa98e2SPeter Wemm 387c2aa98e2SPeter Wemm #ifdef NISPLUS 388c2aa98e2SPeter Wemm MAPDEF("nisplus", NULL, MCF_ALIASOK, 389c2aa98e2SPeter Wemm map_parseargs, nisplus_map_open, null_map_close, 390c2aa98e2SPeter Wemm nisplus_map_lookup, null_map_store); 391c2aa98e2SPeter Wemm #endif 392c2aa98e2SPeter Wemm #ifdef LDAPMAP 393c2aa98e2SPeter Wemm MAPDEF("ldapx", NULL, 0, 394c2aa98e2SPeter Wemm ldap_map_parseargs, ldap_map_open, ldap_map_close, 395c2aa98e2SPeter Wemm ldap_map_lookup, null_map_store); 396c2aa98e2SPeter Wemm #endif 397c2aa98e2SPeter Wemm 398c2aa98e2SPeter Wemm #ifdef HESIOD 399c2aa98e2SPeter Wemm MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY, 400c2aa98e2SPeter Wemm map_parseargs, hes_map_open, null_map_close, 401c2aa98e2SPeter Wemm hes_map_lookup, null_map_store); 402c2aa98e2SPeter Wemm #endif 403c2aa98e2SPeter Wemm 404c2aa98e2SPeter Wemm #if NETINFO 405c2aa98e2SPeter Wemm MAPDEF("netinfo", NULL, MCF_ALIASOK, 406c2aa98e2SPeter Wemm map_parseargs, ni_map_open, null_map_close, 407c2aa98e2SPeter Wemm ni_map_lookup, null_map_store); 408c2aa98e2SPeter Wemm #endif 409c2aa98e2SPeter Wemm 410c2aa98e2SPeter Wemm #if 0 411c2aa98e2SPeter Wemm MAPDEF("dns", NULL, 0, 412c2aa98e2SPeter Wemm dns_map_init, null_map_open, null_map_close, 413c2aa98e2SPeter Wemm dns_map_lookup, null_map_store); 414c2aa98e2SPeter Wemm #endif 415c2aa98e2SPeter Wemm 416c2aa98e2SPeter Wemm #if NAMED_BIND 417c2aa98e2SPeter Wemm /* best MX DNS lookup */ 418c2aa98e2SPeter Wemm MAPDEF("bestmx", NULL, MCF_OPTFILE, 419c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 420c2aa98e2SPeter Wemm bestmx_map_lookup, null_map_store); 421c2aa98e2SPeter Wemm #endif 422c2aa98e2SPeter Wemm 423c2aa98e2SPeter Wemm MAPDEF("host", NULL, 0, 424c2aa98e2SPeter Wemm host_map_init, null_map_open, null_map_close, 425c2aa98e2SPeter Wemm host_map_lookup, null_map_store); 426c2aa98e2SPeter Wemm 427c2aa98e2SPeter Wemm MAPDEF("text", NULL, MCF_ALIASOK, 428c2aa98e2SPeter Wemm map_parseargs, text_map_open, null_map_close, 429c2aa98e2SPeter Wemm text_map_lookup, null_map_store); 430c2aa98e2SPeter Wemm 431c2aa98e2SPeter Wemm MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY, 432c2aa98e2SPeter Wemm map_parseargs, stab_map_open, null_map_close, 433c2aa98e2SPeter Wemm stab_map_lookup, stab_map_store); 434c2aa98e2SPeter Wemm 435c2aa98e2SPeter Wemm MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE, 436c2aa98e2SPeter Wemm map_parseargs, impl_map_open, impl_map_close, 437c2aa98e2SPeter Wemm impl_map_lookup, impl_map_store); 438c2aa98e2SPeter Wemm 439c2aa98e2SPeter Wemm /* access to system passwd file */ 440c2aa98e2SPeter Wemm MAPDEF("user", NULL, MCF_OPTFILE, 441c2aa98e2SPeter Wemm map_parseargs, user_map_open, null_map_close, 442c2aa98e2SPeter Wemm user_map_lookup, null_map_store); 443c2aa98e2SPeter Wemm 444c2aa98e2SPeter Wemm /* dequote map */ 445c2aa98e2SPeter Wemm MAPDEF("dequote", NULL, 0, 446c2aa98e2SPeter Wemm dequote_init, null_map_open, null_map_close, 447c2aa98e2SPeter Wemm dequote_map, null_map_store); 448c2aa98e2SPeter Wemm 449c2aa98e2SPeter Wemm #ifdef MAP_REGEX 450c2aa98e2SPeter Wemm MAPDEF("regex", NULL, 0, 451c2aa98e2SPeter Wemm regex_map_init, null_map_open, null_map_close, 452c2aa98e2SPeter Wemm regex_map_lookup, null_map_store); 453c2aa98e2SPeter Wemm #endif 454c2aa98e2SPeter Wemm 455c2aa98e2SPeter Wemm #if USERDB 456c2aa98e2SPeter Wemm /* user database */ 457c2aa98e2SPeter Wemm MAPDEF("userdb", ".db", 0, 458c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 459c2aa98e2SPeter Wemm udb_map_lookup, null_map_store); 460c2aa98e2SPeter Wemm #endif 461c2aa98e2SPeter Wemm 462c2aa98e2SPeter Wemm /* arbitrary programs */ 463c2aa98e2SPeter Wemm MAPDEF("program", NULL, MCF_ALIASOK, 464c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 465c2aa98e2SPeter Wemm prog_map_lookup, null_map_store); 466c2aa98e2SPeter Wemm 467c2aa98e2SPeter Wemm /* sequenced maps */ 468c2aa98e2SPeter Wemm MAPDEF("sequence", NULL, MCF_ALIASOK, 469c2aa98e2SPeter Wemm seq_map_parse, null_map_open, null_map_close, 470c2aa98e2SPeter Wemm seq_map_lookup, seq_map_store); 471c2aa98e2SPeter Wemm 472c2aa98e2SPeter Wemm /* switched interface to sequenced maps */ 473c2aa98e2SPeter Wemm MAPDEF("switch", NULL, MCF_ALIASOK, 474c2aa98e2SPeter Wemm map_parseargs, switch_map_open, null_map_close, 475c2aa98e2SPeter Wemm seq_map_lookup, seq_map_store); 476c2aa98e2SPeter Wemm 477c2aa98e2SPeter Wemm /* null map lookup -- really for internal use only */ 478c2aa98e2SPeter Wemm MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE, 479c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 480c2aa98e2SPeter Wemm null_map_lookup, null_map_store); 481c2aa98e2SPeter Wemm 482c2aa98e2SPeter Wemm #if _FFR_MAP_SYSLOG 483c2aa98e2SPeter Wemm /* syslog map -- logs information to syslog */ 484c2aa98e2SPeter Wemm MAPDEF("syslog", NULL, 0, 485c2aa98e2SPeter Wemm syslog_map_parseargs, null_map_open, null_map_close, 486c2aa98e2SPeter Wemm syslog_map_lookup, null_map_store); 487c2aa98e2SPeter Wemm #endif 488c2aa98e2SPeter Wemm } 489c2aa98e2SPeter Wemm 490c2aa98e2SPeter Wemm #undef MAPDEF 491c2aa98e2SPeter Wemm /* 492c2aa98e2SPeter Wemm ** INITHOSTMAPS -- initial host-dependent maps 493c2aa98e2SPeter Wemm ** 494c2aa98e2SPeter Wemm ** This should act as an interface to any local service switch 495c2aa98e2SPeter Wemm ** provided by the host operating system. 496c2aa98e2SPeter Wemm ** 497c2aa98e2SPeter Wemm ** Parameters: 498c2aa98e2SPeter Wemm ** none 499c2aa98e2SPeter Wemm ** 500c2aa98e2SPeter Wemm ** Returns: 501c2aa98e2SPeter Wemm ** none 502c2aa98e2SPeter Wemm ** 503c2aa98e2SPeter Wemm ** Side Effects: 504c2aa98e2SPeter Wemm ** Should define maps "host" and "users" as necessary 505c2aa98e2SPeter Wemm ** for this OS. If they are not defined, they will get 506c2aa98e2SPeter Wemm ** a default value later. It should check to make sure 507c2aa98e2SPeter Wemm ** they are not defined first, since it's possible that 508c2aa98e2SPeter Wemm ** the config file has provided an override. 509c2aa98e2SPeter Wemm */ 510c2aa98e2SPeter Wemm 511c2aa98e2SPeter Wemm void 512c2aa98e2SPeter Wemm inithostmaps() 513c2aa98e2SPeter Wemm { 514c2aa98e2SPeter Wemm register int i; 515c2aa98e2SPeter Wemm int nmaps; 516c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 517c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 518c2aa98e2SPeter Wemm char buf[MAXLINE]; 519c2aa98e2SPeter Wemm 520c2aa98e2SPeter Wemm /* 521c2aa98e2SPeter Wemm ** Set up default hosts maps. 522c2aa98e2SPeter Wemm */ 523c2aa98e2SPeter Wemm 524c2aa98e2SPeter Wemm #if 0 525c2aa98e2SPeter Wemm nmaps = switch_map_find("hosts", maptype, mapreturn); 526c2aa98e2SPeter Wemm for (i = 0; i < nmaps; i++) 527c2aa98e2SPeter Wemm { 528c2aa98e2SPeter Wemm if (strcmp(maptype[i], "files") == 0 && 529c2aa98e2SPeter Wemm stab("hosts.files", ST_MAP, ST_FIND) == NULL) 530c2aa98e2SPeter Wemm { 531c2aa98e2SPeter Wemm strcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts"); 532c2aa98e2SPeter Wemm (void) makemapentry(buf); 533c2aa98e2SPeter Wemm } 534c2aa98e2SPeter Wemm #if NAMED_BIND 535c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "dns") == 0 && 536c2aa98e2SPeter Wemm stab("hosts.dns", ST_MAP, ST_FIND) == NULL) 537c2aa98e2SPeter Wemm { 538c2aa98e2SPeter Wemm strcpy(buf, "hosts.dns dns A"); 539c2aa98e2SPeter Wemm (void) makemapentry(buf); 540c2aa98e2SPeter Wemm } 541c2aa98e2SPeter Wemm #endif 542c2aa98e2SPeter Wemm #ifdef NISPLUS 543c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nisplus") == 0 && 544c2aa98e2SPeter Wemm stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) 545c2aa98e2SPeter Wemm { 546c2aa98e2SPeter Wemm strcpy(buf, "hosts.nisplus nisplus -k name -v address -d hosts.org_dir"); 547c2aa98e2SPeter Wemm (void) makemapentry(buf); 548c2aa98e2SPeter Wemm } 549c2aa98e2SPeter Wemm #endif 550c2aa98e2SPeter Wemm #ifdef NIS 551c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nis") == 0 && 552c2aa98e2SPeter Wemm stab("hosts.nis", ST_MAP, ST_FIND) == NULL) 553c2aa98e2SPeter Wemm { 554c2aa98e2SPeter Wemm strcpy(buf, "hosts.nis nis -d -k 0 -v 1 hosts.byname"); 555c2aa98e2SPeter Wemm (void) makemapentry(buf); 556c2aa98e2SPeter Wemm } 557c2aa98e2SPeter Wemm #endif 558c2aa98e2SPeter Wemm #if NETINFO 559c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "netinfo") == 0) && 560c2aa98e2SPeter Wemm stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) 561c2aa98e2SPeter Wemm { 562c2aa98e2SPeter Wemm strcpy(buf, "hosts.netinfo netinfo -v name /machines"); 563c2aa98e2SPeter Wemm (void) makemapentry(buf); 564c2aa98e2SPeter Wemm } 565c2aa98e2SPeter Wemm #endif 566c2aa98e2SPeter Wemm } 567c2aa98e2SPeter Wemm #endif 568c2aa98e2SPeter Wemm 569c2aa98e2SPeter Wemm /* 570c2aa98e2SPeter Wemm ** Make sure we have a host map. 571c2aa98e2SPeter Wemm */ 572c2aa98e2SPeter Wemm 573c2aa98e2SPeter Wemm if (stab("host", ST_MAP, ST_FIND) == NULL) 574c2aa98e2SPeter Wemm { 575c2aa98e2SPeter Wemm /* user didn't initialize: set up host map */ 576c2aa98e2SPeter Wemm strcpy(buf, "host host"); 577c2aa98e2SPeter Wemm #if NAMED_BIND 578c2aa98e2SPeter Wemm if (ConfigLevel >= 2) 579c2aa98e2SPeter Wemm strcat(buf, " -a."); 580c2aa98e2SPeter Wemm #endif 581c2aa98e2SPeter Wemm (void) makemapentry(buf); 582c2aa98e2SPeter Wemm } 583c2aa98e2SPeter Wemm 584c2aa98e2SPeter Wemm /* 585c2aa98e2SPeter Wemm ** Set up default aliases maps 586c2aa98e2SPeter Wemm */ 587c2aa98e2SPeter Wemm 588c2aa98e2SPeter Wemm nmaps = switch_map_find("aliases", maptype, mapreturn); 589c2aa98e2SPeter Wemm for (i = 0; i < nmaps; i++) 590c2aa98e2SPeter Wemm { 591c2aa98e2SPeter Wemm if (strcmp(maptype[i], "files") == 0 && 592c2aa98e2SPeter Wemm stab("aliases.files", ST_MAP, ST_FIND) == NULL) 593c2aa98e2SPeter Wemm { 594c2aa98e2SPeter Wemm strcpy(buf, "aliases.files null"); 595c2aa98e2SPeter Wemm (void) makemapentry(buf); 596c2aa98e2SPeter Wemm } 597c2aa98e2SPeter Wemm #ifdef NISPLUS 598c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nisplus") == 0 && 599c2aa98e2SPeter Wemm stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) 600c2aa98e2SPeter Wemm { 601c2aa98e2SPeter Wemm strcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion -d mail_aliases.org_dir"); 602c2aa98e2SPeter Wemm (void) makemapentry(buf); 603c2aa98e2SPeter Wemm } 604c2aa98e2SPeter Wemm #endif 605c2aa98e2SPeter Wemm #ifdef NIS 606c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nis") == 0 && 607c2aa98e2SPeter Wemm stab("aliases.nis", ST_MAP, ST_FIND) == NULL) 608c2aa98e2SPeter Wemm { 609c2aa98e2SPeter Wemm strcpy(buf, "aliases.nis nis -d mail.aliases"); 610c2aa98e2SPeter Wemm (void) makemapentry(buf); 611c2aa98e2SPeter Wemm } 612c2aa98e2SPeter Wemm #endif 613c2aa98e2SPeter Wemm #ifdef NETINFO 614c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "netinfo") == 0 && 615c2aa98e2SPeter Wemm stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) 616c2aa98e2SPeter Wemm { 617c2aa98e2SPeter Wemm strcpy(buf, "aliases.netinfo netinfo -z, /aliases"); 618c2aa98e2SPeter Wemm (void) makemapentry(buf); 619c2aa98e2SPeter Wemm } 620c2aa98e2SPeter Wemm #endif 621c2aa98e2SPeter Wemm #ifdef HESIOD 622c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "hesiod") == 0 && 623c2aa98e2SPeter Wemm stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) 624c2aa98e2SPeter Wemm { 625c2aa98e2SPeter Wemm strcpy(buf, "aliases.hesiod hesiod aliases"); 626c2aa98e2SPeter Wemm (void) makemapentry(buf); 627c2aa98e2SPeter Wemm } 628c2aa98e2SPeter Wemm #endif 629c2aa98e2SPeter Wemm } 630c2aa98e2SPeter Wemm if (stab("aliases", ST_MAP, ST_FIND) == NULL) 631c2aa98e2SPeter Wemm { 632c2aa98e2SPeter Wemm strcpy(buf, "aliases switch aliases"); 633c2aa98e2SPeter Wemm (void) makemapentry(buf); 634c2aa98e2SPeter Wemm } 635c2aa98e2SPeter Wemm 636c2aa98e2SPeter Wemm #if 0 /* "user" map class is a better choice */ 637c2aa98e2SPeter Wemm /* 638c2aa98e2SPeter Wemm ** Set up default users maps. 639c2aa98e2SPeter Wemm */ 640c2aa98e2SPeter Wemm 641c2aa98e2SPeter Wemm nmaps = switch_map_find("passwd", maptype, mapreturn); 642c2aa98e2SPeter Wemm for (i = 0; i < nmaps; i++) 643c2aa98e2SPeter Wemm { 644c2aa98e2SPeter Wemm if (strcmp(maptype[i], "files") == 0 && 645c2aa98e2SPeter Wemm stab("users.files", ST_MAP, ST_FIND) == NULL) 646c2aa98e2SPeter Wemm { 647c2aa98e2SPeter Wemm strcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd"); 648c2aa98e2SPeter Wemm (void) makemapentry(buf); 649c2aa98e2SPeter Wemm } 650c2aa98e2SPeter Wemm #ifdef NISPLUS 651c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nisplus") == 0 && 652c2aa98e2SPeter Wemm stab("users.nisplus", ST_MAP, ST_FIND) == NULL) 653c2aa98e2SPeter Wemm { 654c2aa98e2SPeter Wemm strcpy(buf, "users.nisplus nisplus -m -kname -vhome -d passwd.org_dir"); 655c2aa98e2SPeter Wemm (void) makemapentry(buf); 656c2aa98e2SPeter Wemm } 657c2aa98e2SPeter Wemm #endif 658c2aa98e2SPeter Wemm #ifdef NIS 659c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nis") == 0 && 660c2aa98e2SPeter Wemm stab("users.nis", ST_MAP, ST_FIND) == NULL) 661c2aa98e2SPeter Wemm { 662c2aa98e2SPeter Wemm strcpy(buf, "users.nis nis -m -d passwd.byname"); 663c2aa98e2SPeter Wemm (void) makemapentry(buf); 664c2aa98e2SPeter Wemm } 665c2aa98e2SPeter Wemm #endif 666c2aa98e2SPeter Wemm #ifdef HESIOD 667c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "hesiod") == 0) && 668c2aa98e2SPeter Wemm stab("users.hesiod", ST_MAP, ST_FIND) == NULL) 669c2aa98e2SPeter Wemm { 670c2aa98e2SPeter Wemm strcpy(buf, "users.hesiod hesiod"); 671c2aa98e2SPeter Wemm (void) makemapentry(buf); 672c2aa98e2SPeter Wemm } 673c2aa98e2SPeter Wemm #endif 674c2aa98e2SPeter Wemm } 675c2aa98e2SPeter Wemm if (stab("users", ST_MAP, ST_FIND) == NULL) 676c2aa98e2SPeter Wemm { 677c2aa98e2SPeter Wemm strcpy(buf, "users switch -m passwd"); 678c2aa98e2SPeter Wemm (void) makemapentry(buf); 679c2aa98e2SPeter Wemm } 680c2aa98e2SPeter Wemm #endif 681c2aa98e2SPeter Wemm } 682c2aa98e2SPeter Wemm /* 683c2aa98e2SPeter Wemm ** SWITCH_MAP_FIND -- find the list of types associated with a map 684c2aa98e2SPeter Wemm ** 685c2aa98e2SPeter Wemm ** This is the system-dependent interface to the service switch. 686c2aa98e2SPeter Wemm ** 687c2aa98e2SPeter Wemm ** Parameters: 688c2aa98e2SPeter Wemm ** service -- the name of the service of interest. 689c2aa98e2SPeter Wemm ** maptype -- an out-array of strings containing the types 690c2aa98e2SPeter Wemm ** of access to use for this service. There can 691c2aa98e2SPeter Wemm ** be at most MAXMAPSTACK types for a single service. 692c2aa98e2SPeter Wemm ** mapreturn -- an out-array of return information bitmaps 693c2aa98e2SPeter Wemm ** for the map. 694c2aa98e2SPeter Wemm ** 695c2aa98e2SPeter Wemm ** Returns: 696c2aa98e2SPeter Wemm ** The number of map types filled in, or -1 for failure. 697c2aa98e2SPeter Wemm */ 698c2aa98e2SPeter Wemm 699c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) 700c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_ 701c2aa98e2SPeter Wemm #endif 702c2aa98e2SPeter Wemm 703c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_ 704c2aa98e2SPeter Wemm # include <nsswitch.h> 705c2aa98e2SPeter Wemm #endif 706c2aa98e2SPeter Wemm 707c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha)) 708c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_ 709c2aa98e2SPeter Wemm #endif 710c2aa98e2SPeter Wemm 711c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_ 712c2aa98e2SPeter Wemm # include <sys/svcinfo.h> 713c2aa98e2SPeter Wemm #endif 714c2aa98e2SPeter Wemm 715c2aa98e2SPeter Wemm int 716c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn) 717c2aa98e2SPeter Wemm char *service; 718c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 719c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 720c2aa98e2SPeter Wemm { 721c2aa98e2SPeter Wemm int svcno; 722c2aa98e2SPeter Wemm 723c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_ 724c2aa98e2SPeter Wemm struct __nsw_switchconfig *nsw_conf; 725c2aa98e2SPeter Wemm enum __nsw_parse_err pserr; 726c2aa98e2SPeter Wemm struct __nsw_lookup *lk; 727c2aa98e2SPeter Wemm static struct __nsw_lookup lkp0 = 728c2aa98e2SPeter Wemm { "files", {1, 0, 0, 0}, NULL, NULL }; 729c2aa98e2SPeter Wemm static struct __nsw_switchconfig lkp_default = 730c2aa98e2SPeter Wemm { 0, "sendmail", 3, &lkp0 }; 731c2aa98e2SPeter Wemm 732c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 733c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 734c2aa98e2SPeter Wemm 735c2aa98e2SPeter Wemm if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL) 736c2aa98e2SPeter Wemm lk = lkp_default.lookups; 737c2aa98e2SPeter Wemm else 738c2aa98e2SPeter Wemm lk = nsw_conf->lookups; 739c2aa98e2SPeter Wemm svcno = 0; 740c2aa98e2SPeter Wemm while (lk != NULL) 741c2aa98e2SPeter Wemm { 742c2aa98e2SPeter Wemm maptype[svcno] = lk->service_name; 743c2aa98e2SPeter Wemm if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN) 744c2aa98e2SPeter Wemm mapreturn[MA_NOTFOUND] |= 1 << svcno; 745c2aa98e2SPeter Wemm if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN) 746c2aa98e2SPeter Wemm mapreturn[MA_TRYAGAIN] |= 1 << svcno; 747c2aa98e2SPeter Wemm if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN) 748c2aa98e2SPeter Wemm mapreturn[MA_TRYAGAIN] |= 1 << svcno; 749c2aa98e2SPeter Wemm svcno++; 750c2aa98e2SPeter Wemm lk = lk->next; 751c2aa98e2SPeter Wemm } 752c2aa98e2SPeter Wemm return svcno; 753c2aa98e2SPeter Wemm #endif 754c2aa98e2SPeter Wemm 755c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_ 756c2aa98e2SPeter Wemm struct svcinfo *svcinfo; 757c2aa98e2SPeter Wemm int svc; 758c2aa98e2SPeter Wemm 759c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 760c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 761c2aa98e2SPeter Wemm 762c2aa98e2SPeter Wemm svcinfo = getsvc(); 763c2aa98e2SPeter Wemm if (svcinfo == NULL) 764c2aa98e2SPeter Wemm goto punt; 765c2aa98e2SPeter Wemm if (strcmp(service, "hosts") == 0) 766c2aa98e2SPeter Wemm svc = SVC_HOSTS; 767c2aa98e2SPeter Wemm else if (strcmp(service, "aliases") == 0) 768c2aa98e2SPeter Wemm svc = SVC_ALIASES; 769c2aa98e2SPeter Wemm else if (strcmp(service, "passwd") == 0) 770c2aa98e2SPeter Wemm svc = SVC_PASSWD; 771c2aa98e2SPeter Wemm else 772c2aa98e2SPeter Wemm return -1; 773c2aa98e2SPeter Wemm for (svcno = 0; svcno < SVC_PATHSIZE; svcno++) 774c2aa98e2SPeter Wemm { 775c2aa98e2SPeter Wemm switch (svcinfo->svcpath[svc][svcno]) 776c2aa98e2SPeter Wemm { 777c2aa98e2SPeter Wemm case SVC_LOCAL: 778c2aa98e2SPeter Wemm maptype[svcno] = "files"; 779c2aa98e2SPeter Wemm break; 780c2aa98e2SPeter Wemm 781c2aa98e2SPeter Wemm case SVC_YP: 782c2aa98e2SPeter Wemm maptype[svcno] = "nis"; 783c2aa98e2SPeter Wemm break; 784c2aa98e2SPeter Wemm 785c2aa98e2SPeter Wemm case SVC_BIND: 786c2aa98e2SPeter Wemm maptype[svcno] = "dns"; 787c2aa98e2SPeter Wemm break; 788c2aa98e2SPeter Wemm 789c2aa98e2SPeter Wemm #ifdef SVC_HESIOD 790c2aa98e2SPeter Wemm case SVC_HESIOD: 791c2aa98e2SPeter Wemm maptype[svcno] = "hesiod"; 792c2aa98e2SPeter Wemm break; 793c2aa98e2SPeter Wemm #endif 794c2aa98e2SPeter Wemm 795c2aa98e2SPeter Wemm case SVC_LAST: 796c2aa98e2SPeter Wemm return svcno; 797c2aa98e2SPeter Wemm } 798c2aa98e2SPeter Wemm } 799c2aa98e2SPeter Wemm return svcno; 800c2aa98e2SPeter Wemm #endif 801c2aa98e2SPeter Wemm 802c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) 803c2aa98e2SPeter Wemm /* 804c2aa98e2SPeter Wemm ** Fall-back mechanism. 805c2aa98e2SPeter Wemm */ 806c2aa98e2SPeter Wemm 807c2aa98e2SPeter Wemm STAB *st; 808c2aa98e2SPeter Wemm time_t now = curtime(); 809c2aa98e2SPeter Wemm 810c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 811c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 812c2aa98e2SPeter Wemm 813c2aa98e2SPeter Wemm if ((now - ServiceCacheTime) > (time_t) ServiceCacheMaxAge) 814c2aa98e2SPeter Wemm { 815c2aa98e2SPeter Wemm /* (re)read service switch */ 816c2aa98e2SPeter Wemm register FILE *fp; 817c2aa98e2SPeter Wemm int sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK; 818c2aa98e2SPeter Wemm 819c2aa98e2SPeter Wemm if (!bitset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR, DontBlameSendmail)) 820c2aa98e2SPeter Wemm sff |= SFF_NOWLINK; 821c2aa98e2SPeter Wemm 822c2aa98e2SPeter Wemm if (ConfigFileRead) 823c2aa98e2SPeter Wemm ServiceCacheTime = now; 824c2aa98e2SPeter Wemm fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff); 825c2aa98e2SPeter Wemm if (fp != NULL) 826c2aa98e2SPeter Wemm { 827c2aa98e2SPeter Wemm char buf[MAXLINE]; 828c2aa98e2SPeter Wemm 829c2aa98e2SPeter Wemm while (fgets(buf, sizeof buf, fp) != NULL) 830c2aa98e2SPeter Wemm { 831c2aa98e2SPeter Wemm register char *p; 832c2aa98e2SPeter Wemm 833c2aa98e2SPeter Wemm p = strpbrk(buf, "#\n"); 834c2aa98e2SPeter Wemm if (p != NULL) 835c2aa98e2SPeter Wemm *p = '\0'; 836c2aa98e2SPeter Wemm p = strpbrk(buf, " \t"); 837c2aa98e2SPeter Wemm if (p != NULL) 838c2aa98e2SPeter Wemm *p++ = '\0'; 839c2aa98e2SPeter Wemm if (buf[0] == '\0') 840c2aa98e2SPeter Wemm continue; 84176b7bf71SPeter Wemm if (p == NULL) 84276b7bf71SPeter Wemm { 84376b7bf71SPeter Wemm sm_syslog(LOG_ERR, NOQID, 84476b7bf71SPeter Wemm "Bad line on %.100s: %.100s", 84576b7bf71SPeter Wemm ServiceSwitchFile, 84676b7bf71SPeter Wemm buf); 84776b7bf71SPeter Wemm continue; 84876b7bf71SPeter Wemm } 849c2aa98e2SPeter Wemm while (isspace(*p)) 850c2aa98e2SPeter Wemm p++; 851c2aa98e2SPeter Wemm if (*p == '\0') 852c2aa98e2SPeter Wemm continue; 853c2aa98e2SPeter Wemm 854c2aa98e2SPeter Wemm /* 855c2aa98e2SPeter Wemm ** Find/allocate space for this service entry. 856c2aa98e2SPeter Wemm ** Space for all of the service strings 857c2aa98e2SPeter Wemm ** are allocated at once. This means 858c2aa98e2SPeter Wemm ** that we only have to free the first 859c2aa98e2SPeter Wemm ** one to free all of them. 860c2aa98e2SPeter Wemm */ 861c2aa98e2SPeter Wemm 862c2aa98e2SPeter Wemm st = stab(buf, ST_SERVICE, ST_ENTER); 863c2aa98e2SPeter Wemm if (st->s_service[0] != NULL) 864c2aa98e2SPeter Wemm free((void *) st->s_service[0]); 865c2aa98e2SPeter Wemm p = newstr(p); 866c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPSTACK; ) 867c2aa98e2SPeter Wemm { 868c2aa98e2SPeter Wemm if (*p == '\0') 869c2aa98e2SPeter Wemm break; 870c2aa98e2SPeter Wemm st->s_service[svcno++] = p; 871c2aa98e2SPeter Wemm p = strpbrk(p, " \t"); 872c2aa98e2SPeter Wemm if (p == NULL) 873c2aa98e2SPeter Wemm break; 874c2aa98e2SPeter Wemm *p++ = '\0'; 875c2aa98e2SPeter Wemm while (isspace(*p)) 876c2aa98e2SPeter Wemm p++; 877c2aa98e2SPeter Wemm } 878c2aa98e2SPeter Wemm if (svcno < MAXMAPSTACK) 879c2aa98e2SPeter Wemm st->s_service[svcno] = NULL; 880c2aa98e2SPeter Wemm } 881c2aa98e2SPeter Wemm fclose(fp); 882c2aa98e2SPeter Wemm } 883c2aa98e2SPeter Wemm } 884c2aa98e2SPeter Wemm 885c2aa98e2SPeter Wemm /* look up entry in cache */ 886c2aa98e2SPeter Wemm st = stab(service, ST_SERVICE, ST_FIND); 887c2aa98e2SPeter Wemm if (st != NULL && st->s_service[0] != NULL) 888c2aa98e2SPeter Wemm { 889c2aa98e2SPeter Wemm /* extract data */ 890c2aa98e2SPeter Wemm svcno = 0; 891c2aa98e2SPeter Wemm while (svcno < MAXMAPSTACK) 892c2aa98e2SPeter Wemm { 893c2aa98e2SPeter Wemm maptype[svcno] = st->s_service[svcno]; 894c2aa98e2SPeter Wemm if (maptype[svcno++] == NULL) 895c2aa98e2SPeter Wemm break; 896c2aa98e2SPeter Wemm } 897c2aa98e2SPeter Wemm return --svcno; 898c2aa98e2SPeter Wemm } 899c2aa98e2SPeter Wemm #endif 900c2aa98e2SPeter Wemm 901c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) 902c2aa98e2SPeter Wemm /* if the service file doesn't work, use an absolute fallback */ 903c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_ 904c2aa98e2SPeter Wemm punt: 905c2aa98e2SPeter Wemm # endif 906c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 907c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 908c2aa98e2SPeter Wemm svcno = 0; 909c2aa98e2SPeter Wemm if (strcmp(service, "aliases") == 0) 910c2aa98e2SPeter Wemm { 911c2aa98e2SPeter Wemm maptype[svcno++] = "files"; 912c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES 913c2aa98e2SPeter Wemm # ifdef NISPLUS 914c2aa98e2SPeter Wemm maptype[svcno++] = "nisplus"; 915c2aa98e2SPeter Wemm # endif 916c2aa98e2SPeter Wemm # ifdef NIS 917c2aa98e2SPeter Wemm maptype[svcno++] = "nis"; 918c2aa98e2SPeter Wemm # endif 919c2aa98e2SPeter Wemm # endif 920c2aa98e2SPeter Wemm return svcno; 921c2aa98e2SPeter Wemm } 922c2aa98e2SPeter Wemm if (strcmp(service, "hosts") == 0) 923c2aa98e2SPeter Wemm { 924c2aa98e2SPeter Wemm # if NAMED_BIND 925c2aa98e2SPeter Wemm maptype[svcno++] = "dns"; 926c2aa98e2SPeter Wemm # else 927c2aa98e2SPeter Wemm # if defined(sun) && !defined(BSD) 928c2aa98e2SPeter Wemm /* SunOS */ 929c2aa98e2SPeter Wemm maptype[svcno++] = "nis"; 930c2aa98e2SPeter Wemm # endif 931c2aa98e2SPeter Wemm # endif 932c2aa98e2SPeter Wemm maptype[svcno++] = "files"; 933c2aa98e2SPeter Wemm return svcno; 934c2aa98e2SPeter Wemm } 935c2aa98e2SPeter Wemm return -1; 936c2aa98e2SPeter Wemm #endif 937c2aa98e2SPeter Wemm } 938c2aa98e2SPeter Wemm /* 939c2aa98e2SPeter Wemm ** USERNAME -- return the user id of the logged in user. 940c2aa98e2SPeter Wemm ** 941c2aa98e2SPeter Wemm ** Parameters: 942c2aa98e2SPeter Wemm ** none. 943c2aa98e2SPeter Wemm ** 944c2aa98e2SPeter Wemm ** Returns: 945c2aa98e2SPeter Wemm ** The login name of the logged in user. 946c2aa98e2SPeter Wemm ** 947c2aa98e2SPeter Wemm ** Side Effects: 948c2aa98e2SPeter Wemm ** none. 949c2aa98e2SPeter Wemm ** 950c2aa98e2SPeter Wemm ** Notes: 951c2aa98e2SPeter Wemm ** The return value is statically allocated. 952c2aa98e2SPeter Wemm */ 953c2aa98e2SPeter Wemm 954c2aa98e2SPeter Wemm char * 955c2aa98e2SPeter Wemm username() 956c2aa98e2SPeter Wemm { 957c2aa98e2SPeter Wemm static char *myname = NULL; 958c2aa98e2SPeter Wemm extern char *getlogin(); 959c2aa98e2SPeter Wemm register struct passwd *pw; 960c2aa98e2SPeter Wemm 961c2aa98e2SPeter Wemm /* cache the result */ 962c2aa98e2SPeter Wemm if (myname == NULL) 963c2aa98e2SPeter Wemm { 964c2aa98e2SPeter Wemm myname = getlogin(); 965c2aa98e2SPeter Wemm if (myname == NULL || myname[0] == '\0') 966c2aa98e2SPeter Wemm { 967c2aa98e2SPeter Wemm pw = sm_getpwuid(RealUid); 968c2aa98e2SPeter Wemm if (pw != NULL) 969c2aa98e2SPeter Wemm myname = newstr(pw->pw_name); 970c2aa98e2SPeter Wemm } 971c2aa98e2SPeter Wemm else 972c2aa98e2SPeter Wemm { 973c2aa98e2SPeter Wemm uid_t uid = RealUid; 974c2aa98e2SPeter Wemm 975c2aa98e2SPeter Wemm myname = newstr(myname); 976c2aa98e2SPeter Wemm if ((pw = sm_getpwnam(myname)) == NULL || 977c2aa98e2SPeter Wemm (uid != 0 && uid != pw->pw_uid)) 978c2aa98e2SPeter Wemm { 979c2aa98e2SPeter Wemm pw = sm_getpwuid(uid); 980c2aa98e2SPeter Wemm if (pw != NULL) 981c2aa98e2SPeter Wemm myname = newstr(pw->pw_name); 982c2aa98e2SPeter Wemm } 983c2aa98e2SPeter Wemm } 984c2aa98e2SPeter Wemm if (myname == NULL || myname[0] == '\0') 985c2aa98e2SPeter Wemm { 986c2aa98e2SPeter Wemm syserr("554 Who are you?"); 987c2aa98e2SPeter Wemm myname = "postmaster"; 988c2aa98e2SPeter Wemm } 989c2aa98e2SPeter Wemm } 990c2aa98e2SPeter Wemm 991c2aa98e2SPeter Wemm return (myname); 992c2aa98e2SPeter Wemm } 993c2aa98e2SPeter Wemm /* 994c2aa98e2SPeter Wemm ** TTYPATH -- Get the path of the user's tty 995c2aa98e2SPeter Wemm ** 996c2aa98e2SPeter Wemm ** Returns the pathname of the user's tty. Returns NULL if 997c2aa98e2SPeter Wemm ** the user is not logged in or if s/he has write permission 998c2aa98e2SPeter Wemm ** denied. 999c2aa98e2SPeter Wemm ** 1000c2aa98e2SPeter Wemm ** Parameters: 1001c2aa98e2SPeter Wemm ** none 1002c2aa98e2SPeter Wemm ** 1003c2aa98e2SPeter Wemm ** Returns: 1004c2aa98e2SPeter Wemm ** pathname of the user's tty. 1005c2aa98e2SPeter Wemm ** NULL if not logged in or write permission denied. 1006c2aa98e2SPeter Wemm ** 1007c2aa98e2SPeter Wemm ** Side Effects: 1008c2aa98e2SPeter Wemm ** none. 1009c2aa98e2SPeter Wemm ** 1010c2aa98e2SPeter Wemm ** WARNING: 1011c2aa98e2SPeter Wemm ** Return value is in a local buffer. 1012c2aa98e2SPeter Wemm ** 1013c2aa98e2SPeter Wemm ** Called By: 1014c2aa98e2SPeter Wemm ** savemail 1015c2aa98e2SPeter Wemm */ 1016c2aa98e2SPeter Wemm 1017c2aa98e2SPeter Wemm char * 1018c2aa98e2SPeter Wemm ttypath() 1019c2aa98e2SPeter Wemm { 1020c2aa98e2SPeter Wemm struct stat stbuf; 1021c2aa98e2SPeter Wemm register char *pathn; 1022c2aa98e2SPeter Wemm extern char *ttyname(); 1023c2aa98e2SPeter Wemm extern char *getlogin(); 1024c2aa98e2SPeter Wemm 1025c2aa98e2SPeter Wemm /* compute the pathname of the controlling tty */ 1026c2aa98e2SPeter Wemm if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 1027c2aa98e2SPeter Wemm (pathn = ttyname(0)) == NULL) 1028c2aa98e2SPeter Wemm { 1029c2aa98e2SPeter Wemm errno = 0; 1030c2aa98e2SPeter Wemm return (NULL); 1031c2aa98e2SPeter Wemm } 1032c2aa98e2SPeter Wemm 1033c2aa98e2SPeter Wemm /* see if we have write permission */ 1034c2aa98e2SPeter Wemm if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode)) 1035c2aa98e2SPeter Wemm { 1036c2aa98e2SPeter Wemm errno = 0; 1037c2aa98e2SPeter Wemm return (NULL); 1038c2aa98e2SPeter Wemm } 1039c2aa98e2SPeter Wemm 1040c2aa98e2SPeter Wemm /* see if the user is logged in */ 1041c2aa98e2SPeter Wemm if (getlogin() == NULL) 1042c2aa98e2SPeter Wemm return (NULL); 1043c2aa98e2SPeter Wemm 1044c2aa98e2SPeter Wemm /* looks good */ 1045c2aa98e2SPeter Wemm return (pathn); 1046c2aa98e2SPeter Wemm } 1047c2aa98e2SPeter Wemm /* 1048c2aa98e2SPeter Wemm ** CHECKCOMPAT -- check for From and To person compatible. 1049c2aa98e2SPeter Wemm ** 1050c2aa98e2SPeter Wemm ** This routine can be supplied on a per-installation basis 1051c2aa98e2SPeter Wemm ** to determine whether a person is allowed to send a message. 1052c2aa98e2SPeter Wemm ** This allows restriction of certain types of internet 1053c2aa98e2SPeter Wemm ** forwarding or registration of users. 1054c2aa98e2SPeter Wemm ** 1055c2aa98e2SPeter Wemm ** If the hosts are found to be incompatible, an error 1056c2aa98e2SPeter Wemm ** message should be given using "usrerr" and an EX_ code 1057c2aa98e2SPeter Wemm ** should be returned. You can also set to->q_status to 1058c2aa98e2SPeter Wemm ** a DSN-style status code. 1059c2aa98e2SPeter Wemm ** 1060c2aa98e2SPeter Wemm ** EF_NO_BODY_RETN can be set in e->e_flags to suppress the 1061c2aa98e2SPeter Wemm ** body during the return-to-sender function; this should be done 1062c2aa98e2SPeter Wemm ** on huge messages. This bit may already be set by the ESMTP 1063c2aa98e2SPeter Wemm ** protocol. 1064c2aa98e2SPeter Wemm ** 1065c2aa98e2SPeter Wemm ** Parameters: 1066c2aa98e2SPeter Wemm ** to -- the person being sent to. 1067c2aa98e2SPeter Wemm ** 1068c2aa98e2SPeter Wemm ** Returns: 1069c2aa98e2SPeter Wemm ** an exit status 1070c2aa98e2SPeter Wemm ** 1071c2aa98e2SPeter Wemm ** Side Effects: 1072c2aa98e2SPeter Wemm ** none (unless you include the usrerr stuff) 1073c2aa98e2SPeter Wemm */ 1074c2aa98e2SPeter Wemm 1075c2aa98e2SPeter Wemm int 1076c2aa98e2SPeter Wemm checkcompat(to, e) 1077c2aa98e2SPeter Wemm register ADDRESS *to; 1078c2aa98e2SPeter Wemm register ENVELOPE *e; 1079c2aa98e2SPeter Wemm { 1080c2aa98e2SPeter Wemm # ifdef lint 1081c2aa98e2SPeter Wemm if (to == NULL) 1082c2aa98e2SPeter Wemm to++; 1083c2aa98e2SPeter Wemm # endif /* lint */ 1084c2aa98e2SPeter Wemm 1085c2aa98e2SPeter Wemm if (tTd(49, 1)) 1086c2aa98e2SPeter Wemm printf("checkcompat(to=%s, from=%s)\n", 1087c2aa98e2SPeter Wemm to->q_paddr, e->e_from.q_paddr); 1088c2aa98e2SPeter Wemm 1089c2aa98e2SPeter Wemm # ifdef EXAMPLE_CODE 1090c2aa98e2SPeter Wemm /* this code is intended as an example only */ 1091c2aa98e2SPeter Wemm register STAB *s; 1092c2aa98e2SPeter Wemm 1093c2aa98e2SPeter Wemm s = stab("arpa", ST_MAILER, ST_FIND); 1094c2aa98e2SPeter Wemm if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 && 1095c2aa98e2SPeter Wemm to->q_mailer == s->s_mailer) 1096c2aa98e2SPeter Wemm { 1097c2aa98e2SPeter Wemm usrerr("553 No ARPA mail through this machine: see your system administration"); 1098c2aa98e2SPeter Wemm /* e->e_flags |= EF_NO_BODY_RETN; to supress body on return */ 1099c2aa98e2SPeter Wemm to->q_status = "5.7.1"; 1100c2aa98e2SPeter Wemm return (EX_UNAVAILABLE); 1101c2aa98e2SPeter Wemm } 1102c2aa98e2SPeter Wemm # endif /* EXAMPLE_CODE */ 1103c2aa98e2SPeter Wemm return (EX_OK); 1104c2aa98e2SPeter Wemm } 1105c2aa98e2SPeter Wemm /* 1106c2aa98e2SPeter Wemm ** SETSIGNAL -- set a signal handler 1107c2aa98e2SPeter Wemm ** 1108c2aa98e2SPeter Wemm ** This is essentially old BSD "signal(3)". 1109c2aa98e2SPeter Wemm */ 1110c2aa98e2SPeter Wemm 1111c2aa98e2SPeter Wemm sigfunc_t 1112c2aa98e2SPeter Wemm setsignal(sig, handler) 1113c2aa98e2SPeter Wemm int sig; 1114c2aa98e2SPeter Wemm sigfunc_t handler; 1115c2aa98e2SPeter Wemm { 1116c2aa98e2SPeter Wemm #if defined(SYS5SIGNALS) || defined(BSD4_3) 1117c2aa98e2SPeter Wemm # ifdef BSD4_3 1118c2aa98e2SPeter Wemm return signal(sig, handler); 1119c2aa98e2SPeter Wemm # else 1120c2aa98e2SPeter Wemm return sigset(sig, handler); 1121c2aa98e2SPeter Wemm # endif 1122c2aa98e2SPeter Wemm #else 1123c2aa98e2SPeter Wemm struct sigaction n, o; 1124c2aa98e2SPeter Wemm 1125c2aa98e2SPeter Wemm bzero(&n, sizeof n); 1126c2aa98e2SPeter Wemm # if USE_SA_SIGACTION 1127c2aa98e2SPeter Wemm n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler; 1128c2aa98e2SPeter Wemm n.sa_flags = SA_RESTART|SA_SIGINFO; 1129c2aa98e2SPeter Wemm # else 1130c2aa98e2SPeter Wemm n.sa_handler = handler; 1131c2aa98e2SPeter Wemm # ifdef SA_RESTART 1132c2aa98e2SPeter Wemm n.sa_flags = SA_RESTART; 1133c2aa98e2SPeter Wemm # endif 1134c2aa98e2SPeter Wemm # endif 1135c2aa98e2SPeter Wemm if (sigaction(sig, &n, &o) < 0) 1136c2aa98e2SPeter Wemm return SIG_ERR; 1137c2aa98e2SPeter Wemm return o.sa_handler; 1138c2aa98e2SPeter Wemm #endif 1139c2aa98e2SPeter Wemm } 1140c2aa98e2SPeter Wemm /* 1141c2aa98e2SPeter Wemm ** BLOCKSIGNAL -- hold a signal to prevent delivery 1142c2aa98e2SPeter Wemm ** 1143c2aa98e2SPeter Wemm ** Parameters: 1144c2aa98e2SPeter Wemm ** sig -- the signal to block. 1145c2aa98e2SPeter Wemm ** 1146c2aa98e2SPeter Wemm ** Returns: 1147c2aa98e2SPeter Wemm ** 1 signal was previously blocked 1148c2aa98e2SPeter Wemm ** 0 signal was not previously blocked 1149c2aa98e2SPeter Wemm ** -1 on failure. 1150c2aa98e2SPeter Wemm */ 1151c2aa98e2SPeter Wemm 1152c2aa98e2SPeter Wemm int 1153c2aa98e2SPeter Wemm blocksignal(sig) 1154c2aa98e2SPeter Wemm int sig; 1155c2aa98e2SPeter Wemm { 1156c2aa98e2SPeter Wemm #ifdef BSD4_3 1157c2aa98e2SPeter Wemm # ifndef sigmask 1158c2aa98e2SPeter Wemm # define sigmask(s) (1 << ((s) - 1)) 1159c2aa98e2SPeter Wemm # endif 1160c2aa98e2SPeter Wemm return (sigblock(sigmask(sig)) & sigmask(sig)) != 0; 1161c2aa98e2SPeter Wemm #else 1162c2aa98e2SPeter Wemm # ifdef ALTOS_SYSTEM_V 1163c2aa98e2SPeter Wemm sigfunc_t handler; 1164c2aa98e2SPeter Wemm 1165c2aa98e2SPeter Wemm handler = sigset(sig, SIG_HOLD); 1166c2aa98e2SPeter Wemm if (handler == SIG_ERR) 1167c2aa98e2SPeter Wemm return -1; 1168c2aa98e2SPeter Wemm else 1169c2aa98e2SPeter Wemm return handler == SIG_HOLD; 1170c2aa98e2SPeter Wemm # else 1171c2aa98e2SPeter Wemm sigset_t sset, oset; 1172c2aa98e2SPeter Wemm 1173c2aa98e2SPeter Wemm sigemptyset(&sset); 1174c2aa98e2SPeter Wemm sigaddset(&sset, sig); 1175c2aa98e2SPeter Wemm if (sigprocmask(SIG_BLOCK, &sset, &oset) < 0) 1176c2aa98e2SPeter Wemm return -1; 1177c2aa98e2SPeter Wemm else 1178c2aa98e2SPeter Wemm return sigismember(&oset, sig); 1179c2aa98e2SPeter Wemm # endif 1180c2aa98e2SPeter Wemm #endif 1181c2aa98e2SPeter Wemm } 1182c2aa98e2SPeter Wemm /* 1183c2aa98e2SPeter Wemm ** RELEASESIGNAL -- release a held signal 1184c2aa98e2SPeter Wemm ** 1185c2aa98e2SPeter Wemm ** Parameters: 1186c2aa98e2SPeter Wemm ** sig -- the signal to release. 1187c2aa98e2SPeter Wemm ** 1188c2aa98e2SPeter Wemm ** Returns: 1189c2aa98e2SPeter Wemm ** 1 signal was previously blocked 1190c2aa98e2SPeter Wemm ** 0 signal was not previously blocked 1191c2aa98e2SPeter Wemm ** -1 on failure. 1192c2aa98e2SPeter Wemm */ 1193c2aa98e2SPeter Wemm 1194c2aa98e2SPeter Wemm int 1195c2aa98e2SPeter Wemm releasesignal(sig) 1196c2aa98e2SPeter Wemm int sig; 1197c2aa98e2SPeter Wemm { 1198c2aa98e2SPeter Wemm #ifdef BSD4_3 1199c2aa98e2SPeter Wemm return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0; 1200c2aa98e2SPeter Wemm #else 1201c2aa98e2SPeter Wemm # ifdef ALTOS_SYSTEM_V 1202c2aa98e2SPeter Wemm sigfunc_t handler; 1203c2aa98e2SPeter Wemm 1204c2aa98e2SPeter Wemm handler = sigset(sig, SIG_HOLD); 1205c2aa98e2SPeter Wemm if (sigrelse(sig) < 0) 1206c2aa98e2SPeter Wemm return -1; 1207c2aa98e2SPeter Wemm else 1208c2aa98e2SPeter Wemm return handler == SIG_HOLD; 1209c2aa98e2SPeter Wemm # else 1210c2aa98e2SPeter Wemm sigset_t sset, oset; 1211c2aa98e2SPeter Wemm 1212c2aa98e2SPeter Wemm sigemptyset(&sset); 1213c2aa98e2SPeter Wemm sigaddset(&sset, sig); 1214c2aa98e2SPeter Wemm if (sigprocmask(SIG_UNBLOCK, &sset, &oset) < 0) 1215c2aa98e2SPeter Wemm return -1; 1216c2aa98e2SPeter Wemm else 1217c2aa98e2SPeter Wemm return sigismember(&oset, sig); 1218c2aa98e2SPeter Wemm # endif 1219c2aa98e2SPeter Wemm #endif 1220c2aa98e2SPeter Wemm } 1221c2aa98e2SPeter Wemm /* 1222c2aa98e2SPeter Wemm ** HOLDSIGS -- arrange to hold all signals 1223c2aa98e2SPeter Wemm ** 1224c2aa98e2SPeter Wemm ** Parameters: 1225c2aa98e2SPeter Wemm ** none. 1226c2aa98e2SPeter Wemm ** 1227c2aa98e2SPeter Wemm ** Returns: 1228c2aa98e2SPeter Wemm ** none. 1229c2aa98e2SPeter Wemm ** 1230c2aa98e2SPeter Wemm ** Side Effects: 1231c2aa98e2SPeter Wemm ** Arranges that signals are held. 1232c2aa98e2SPeter Wemm */ 1233c2aa98e2SPeter Wemm 1234c2aa98e2SPeter Wemm void 1235c2aa98e2SPeter Wemm holdsigs() 1236c2aa98e2SPeter Wemm { 1237c2aa98e2SPeter Wemm } 1238c2aa98e2SPeter Wemm /* 1239c2aa98e2SPeter Wemm ** RLSESIGS -- arrange to release all signals 1240c2aa98e2SPeter Wemm ** 1241c2aa98e2SPeter Wemm ** This undoes the effect of holdsigs. 1242c2aa98e2SPeter Wemm ** 1243c2aa98e2SPeter Wemm ** Parameters: 1244c2aa98e2SPeter Wemm ** none. 1245c2aa98e2SPeter Wemm ** 1246c2aa98e2SPeter Wemm ** Returns: 1247c2aa98e2SPeter Wemm ** none. 1248c2aa98e2SPeter Wemm ** 1249c2aa98e2SPeter Wemm ** Side Effects: 1250c2aa98e2SPeter Wemm ** Arranges that signals are released. 1251c2aa98e2SPeter Wemm */ 1252c2aa98e2SPeter Wemm 1253c2aa98e2SPeter Wemm void 1254c2aa98e2SPeter Wemm rlsesigs() 1255c2aa98e2SPeter Wemm { 1256c2aa98e2SPeter Wemm } 1257c2aa98e2SPeter Wemm /* 1258c2aa98e2SPeter Wemm ** INIT_MD -- do machine dependent initializations 1259c2aa98e2SPeter Wemm ** 1260c2aa98e2SPeter Wemm ** Systems that have global modes that should be set should do 1261c2aa98e2SPeter Wemm ** them here rather than in main. 1262c2aa98e2SPeter Wemm */ 1263c2aa98e2SPeter Wemm 1264c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1265c2aa98e2SPeter Wemm # include <compat.h> 1266c2aa98e2SPeter Wemm #endif 1267c2aa98e2SPeter Wemm 1268c2aa98e2SPeter Wemm #if SHARE_V1 1269c2aa98e2SPeter Wemm # include <shares.h> 1270c2aa98e2SPeter Wemm #endif 1271c2aa98e2SPeter Wemm 1272c2aa98e2SPeter Wemm void 1273c2aa98e2SPeter Wemm init_md(argc, argv) 1274c2aa98e2SPeter Wemm int argc; 1275c2aa98e2SPeter Wemm char **argv; 1276c2aa98e2SPeter Wemm { 1277c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1278c2aa98e2SPeter Wemm setcompat(getcompat() | COMPAT_BSDPROT); 1279c2aa98e2SPeter Wemm #endif 1280c2aa98e2SPeter Wemm 1281c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS 1282c2aa98e2SPeter Wemm init_md_sun(); 1283c2aa98e2SPeter Wemm #endif 1284c2aa98e2SPeter Wemm 1285c2aa98e2SPeter Wemm #if _CONVEX_SOURCE 1286c2aa98e2SPeter Wemm /* keep gethostby*() from stripping the local domain name */ 1287c2aa98e2SPeter Wemm set_domain_trim_off(); 1288c2aa98e2SPeter Wemm #endif 1289c2aa98e2SPeter Wemm #ifdef __QNX__ 1290c2aa98e2SPeter Wemm /* 1291c2aa98e2SPeter Wemm ** Due to QNX's network distributed nature, you can target a tcpip 1292c2aa98e2SPeter Wemm ** stack on a different node in the qnx network; this patch lets 1293c2aa98e2SPeter Wemm ** this feature work. The __sock_locate() must be done before the 1294c2aa98e2SPeter Wemm ** environment is clear. 1295c2aa98e2SPeter Wemm */ 1296c2aa98e2SPeter Wemm __sock_locate(); 1297c2aa98e2SPeter Wemm #endif 1298c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_) 1299c2aa98e2SPeter Wemm set_auth_parameters(argc, argv); 1300c2aa98e2SPeter Wemm 1301c2aa98e2SPeter Wemm # ifdef _SCO_unix_ 1302c2aa98e2SPeter Wemm /* 1303c2aa98e2SPeter Wemm ** This is required for highest security levels (the kernel 1304c2aa98e2SPeter Wemm ** won't let it call set*uid() or run setuid binaries without 1305c2aa98e2SPeter Wemm ** it). It may be necessary on other SECUREWARE systems. 1306c2aa98e2SPeter Wemm */ 1307c2aa98e2SPeter Wemm 1308c2aa98e2SPeter Wemm if (getluid() == -1) 1309c2aa98e2SPeter Wemm setluid(0); 1310c2aa98e2SPeter Wemm # endif 1311c2aa98e2SPeter Wemm #endif 1312c2aa98e2SPeter Wemm 1313c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT 1314c2aa98e2SPeter Wemm VendorCode = VENDOR_DEFAULT; 1315c2aa98e2SPeter Wemm #else 1316c2aa98e2SPeter Wemm VendorCode = VENDOR_BERKELEY; 1317c2aa98e2SPeter Wemm #endif 1318c2aa98e2SPeter Wemm } 1319c2aa98e2SPeter Wemm /* 1320c2aa98e2SPeter Wemm ** INIT_VENDOR_MACROS -- vendor-dependent macro initializations 1321c2aa98e2SPeter Wemm ** 1322c2aa98e2SPeter Wemm ** Called once, on startup. 1323c2aa98e2SPeter Wemm ** 1324c2aa98e2SPeter Wemm ** Parameters: 1325c2aa98e2SPeter Wemm ** e -- the global envelope. 1326c2aa98e2SPeter Wemm ** 1327c2aa98e2SPeter Wemm ** Returns: 1328c2aa98e2SPeter Wemm ** none. 1329c2aa98e2SPeter Wemm ** 1330c2aa98e2SPeter Wemm ** Side Effects: 1331c2aa98e2SPeter Wemm ** vendor-dependent. 1332c2aa98e2SPeter Wemm */ 1333c2aa98e2SPeter Wemm 1334c2aa98e2SPeter Wemm void 1335c2aa98e2SPeter Wemm init_vendor_macros(e) 1336c2aa98e2SPeter Wemm register ENVELOPE *e; 1337c2aa98e2SPeter Wemm { 1338c2aa98e2SPeter Wemm } 1339c2aa98e2SPeter Wemm /* 1340c2aa98e2SPeter Wemm ** GETLA -- get the current load average 1341c2aa98e2SPeter Wemm ** 1342c2aa98e2SPeter Wemm ** This code stolen from la.c. 1343c2aa98e2SPeter Wemm ** 1344c2aa98e2SPeter Wemm ** Parameters: 1345c2aa98e2SPeter Wemm ** none. 1346c2aa98e2SPeter Wemm ** 1347c2aa98e2SPeter Wemm ** Returns: 1348c2aa98e2SPeter Wemm ** The current load average as an integer. 1349c2aa98e2SPeter Wemm ** 1350c2aa98e2SPeter Wemm ** Side Effects: 1351c2aa98e2SPeter Wemm ** none. 1352c2aa98e2SPeter Wemm */ 1353c2aa98e2SPeter Wemm 1354c2aa98e2SPeter Wemm /* try to guess what style of load average we have */ 1355c2aa98e2SPeter Wemm #define LA_ZERO 1 /* always return load average as zero */ 1356c2aa98e2SPeter Wemm #define LA_INT 2 /* read kmem for avenrun; interpret as long */ 1357c2aa98e2SPeter Wemm #define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ 1358c2aa98e2SPeter Wemm #define LA_SUBR 4 /* call getloadavg */ 1359c2aa98e2SPeter Wemm #define LA_MACH 5 /* MACH load averages (as on NeXT boxes) */ 1360c2aa98e2SPeter Wemm #define LA_SHORT 6 /* read kmem for avenrun; interpret as short */ 1361c2aa98e2SPeter Wemm #define LA_PROCSTR 7 /* read string ("1.17") from /proc/loadavg */ 1362c2aa98e2SPeter Wemm #define LA_READKSYM 8 /* SVR4: use MIOC_READKSYM ioctl call */ 1363c2aa98e2SPeter Wemm #define LA_DGUX 9 /* special DGUX implementation */ 1364c2aa98e2SPeter Wemm #define LA_HPUX 10 /* special HPUX implementation */ 1365c2aa98e2SPeter Wemm #define LA_IRIX6 11 /* special IRIX 6.2 implementation */ 1366c2aa98e2SPeter Wemm #define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */ 1367c2aa98e2SPeter Wemm #define LA_DEVSHORT 13 /* read short from a device */ 1368c2aa98e2SPeter Wemm #define LA_ALPHAOSF 14 /* Digital UNIX (OSF/1 on Alpha) table() call */ 1369c2aa98e2SPeter Wemm 1370c2aa98e2SPeter Wemm /* do guesses based on general OS type */ 1371c2aa98e2SPeter Wemm #ifndef LA_TYPE 1372c2aa98e2SPeter Wemm # define LA_TYPE LA_ZERO 1373c2aa98e2SPeter Wemm #endif 1374c2aa98e2SPeter Wemm 1375c2aa98e2SPeter Wemm #ifndef FSHIFT 1376c2aa98e2SPeter Wemm # if defined(unixpc) 1377c2aa98e2SPeter Wemm # define FSHIFT 5 1378c2aa98e2SPeter Wemm # endif 1379c2aa98e2SPeter Wemm 1380c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX) 1381c2aa98e2SPeter Wemm # define FSHIFT 10 1382c2aa98e2SPeter Wemm # endif 1383c2aa98e2SPeter Wemm 1384c2aa98e2SPeter Wemm #endif 1385c2aa98e2SPeter Wemm 1386c2aa98e2SPeter Wemm #ifndef FSHIFT 1387c2aa98e2SPeter Wemm # define FSHIFT 8 1388c2aa98e2SPeter Wemm #endif 1389c2aa98e2SPeter Wemm 1390c2aa98e2SPeter Wemm #ifndef FSCALE 1391c2aa98e2SPeter Wemm # define FSCALE (1 << FSHIFT) 1392c2aa98e2SPeter Wemm #endif 1393c2aa98e2SPeter Wemm 1394c2aa98e2SPeter Wemm #ifndef LA_AVENRUN 1395c2aa98e2SPeter Wemm # ifdef SYSTEM5 1396c2aa98e2SPeter Wemm # define LA_AVENRUN "avenrun" 1397c2aa98e2SPeter Wemm # else 1398c2aa98e2SPeter Wemm # define LA_AVENRUN "_avenrun" 1399c2aa98e2SPeter Wemm # endif 1400c2aa98e2SPeter Wemm #endif 1401c2aa98e2SPeter Wemm 1402c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */ 1403c2aa98e2SPeter Wemm #ifndef _PATH_KMEM 1404c2aa98e2SPeter Wemm # define _PATH_KMEM "/dev/kmem" 1405c2aa98e2SPeter Wemm #endif 1406c2aa98e2SPeter Wemm 1407c2aa98e2SPeter Wemm #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) 1408c2aa98e2SPeter Wemm 1409c2aa98e2SPeter Wemm #include <nlist.h> 1410c2aa98e2SPeter Wemm 1411c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */ 1412c2aa98e2SPeter Wemm #ifndef _PATH_UNIX 1413c2aa98e2SPeter Wemm # if defined(SYSTEM5) 1414c2aa98e2SPeter Wemm # define _PATH_UNIX "/unix" 1415c2aa98e2SPeter Wemm # else 1416c2aa98e2SPeter Wemm # define _PATH_UNIX "/vmunix" 1417c2aa98e2SPeter Wemm # endif 1418c2aa98e2SPeter Wemm #endif 1419c2aa98e2SPeter Wemm 1420c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1421c2aa98e2SPeter Wemm struct nlist Nl[2]; 1422c2aa98e2SPeter Wemm #else 1423c2aa98e2SPeter Wemm struct nlist Nl[] = 1424c2aa98e2SPeter Wemm { 1425c2aa98e2SPeter Wemm { LA_AVENRUN }, 1426c2aa98e2SPeter Wemm { 0 }, 1427c2aa98e2SPeter Wemm }; 1428c2aa98e2SPeter Wemm #endif 1429c2aa98e2SPeter Wemm #define X_AVENRUN 0 1430c2aa98e2SPeter Wemm 1431c2aa98e2SPeter Wemm int 1432c2aa98e2SPeter Wemm getla() 1433c2aa98e2SPeter Wemm { 1434c2aa98e2SPeter Wemm static int kmem = -1; 1435c2aa98e2SPeter Wemm #if LA_TYPE == LA_INT 1436c2aa98e2SPeter Wemm long avenrun[3]; 1437c2aa98e2SPeter Wemm #else 1438c2aa98e2SPeter Wemm # if LA_TYPE == LA_SHORT 1439c2aa98e2SPeter Wemm short avenrun[3]; 1440c2aa98e2SPeter Wemm # else 1441c2aa98e2SPeter Wemm double avenrun[3]; 1442c2aa98e2SPeter Wemm # endif 1443c2aa98e2SPeter Wemm #endif 1444c2aa98e2SPeter Wemm extern int errno; 1445c2aa98e2SPeter Wemm extern off_t lseek(); 1446c2aa98e2SPeter Wemm 1447c2aa98e2SPeter Wemm if (kmem < 0) 1448c2aa98e2SPeter Wemm { 1449c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1450c2aa98e2SPeter Wemm strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN); 1451c2aa98e2SPeter Wemm Nl[1].n_name[0] = '\0'; 1452c2aa98e2SPeter Wemm #endif 1453c2aa98e2SPeter Wemm 1454c2aa98e2SPeter Wemm #if defined(_AIX3) || defined(_AIX4) 1455c2aa98e2SPeter Wemm if (knlist(Nl, 1, sizeof Nl[0]) < 0) 1456c2aa98e2SPeter Wemm #else 1457c2aa98e2SPeter Wemm if (nlist(_PATH_UNIX, Nl) < 0) 1458c2aa98e2SPeter Wemm #endif 1459c2aa98e2SPeter Wemm { 1460c2aa98e2SPeter Wemm if (tTd(3, 1)) 1461c2aa98e2SPeter Wemm printf("getla: nlist(%s): %s\n", _PATH_UNIX, 1462c2aa98e2SPeter Wemm errstring(errno)); 1463c2aa98e2SPeter Wemm return (-1); 1464c2aa98e2SPeter Wemm } 1465c2aa98e2SPeter Wemm if (Nl[X_AVENRUN].n_value == 0) 1466c2aa98e2SPeter Wemm { 1467c2aa98e2SPeter Wemm if (tTd(3, 1)) 1468c2aa98e2SPeter Wemm printf("getla: nlist(%s, %s) ==> 0\n", 1469c2aa98e2SPeter Wemm _PATH_UNIX, LA_AVENRUN); 1470c2aa98e2SPeter Wemm return (-1); 1471c2aa98e2SPeter Wemm } 1472c2aa98e2SPeter Wemm #ifdef NAMELISTMASK 1473c2aa98e2SPeter Wemm Nl[X_AVENRUN].n_value &= NAMELISTMASK; 1474c2aa98e2SPeter Wemm #endif 1475c2aa98e2SPeter Wemm 1476c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, 0, 0); 1477c2aa98e2SPeter Wemm if (kmem < 0) 1478c2aa98e2SPeter Wemm { 1479c2aa98e2SPeter Wemm if (tTd(3, 1)) 1480c2aa98e2SPeter Wemm printf("getla: open(/dev/kmem): %s\n", 1481c2aa98e2SPeter Wemm errstring(errno)); 1482c2aa98e2SPeter Wemm return (-1); 1483c2aa98e2SPeter Wemm } 1484c2aa98e2SPeter Wemm (void) fcntl(kmem, F_SETFD, 1); 1485c2aa98e2SPeter Wemm } 1486c2aa98e2SPeter Wemm if (tTd(3, 20)) 1487c2aa98e2SPeter Wemm printf("getla: symbol address = %#lx\n", 1488c2aa98e2SPeter Wemm (u_long) Nl[X_AVENRUN].n_value); 1489c2aa98e2SPeter Wemm if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 || 1490c2aa98e2SPeter Wemm read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 1491c2aa98e2SPeter Wemm { 1492c2aa98e2SPeter Wemm /* thank you Ian */ 1493c2aa98e2SPeter Wemm if (tTd(3, 1)) 1494c2aa98e2SPeter Wemm printf("getla: lseek or read: %s\n", errstring(errno)); 1495c2aa98e2SPeter Wemm return (-1); 1496c2aa98e2SPeter Wemm } 1497c2aa98e2SPeter Wemm # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) 1498c2aa98e2SPeter Wemm if (tTd(3, 5)) 1499c2aa98e2SPeter Wemm { 1500c2aa98e2SPeter Wemm # if LA_TYPE == LA_SHORT 1501c2aa98e2SPeter Wemm printf("getla: avenrun = %d", avenrun[0]); 1502c2aa98e2SPeter Wemm if (tTd(3, 15)) 1503c2aa98e2SPeter Wemm printf(", %d, %d", avenrun[1], avenrun[2]); 1504c2aa98e2SPeter Wemm # else 1505c2aa98e2SPeter Wemm printf("getla: avenrun = %ld", avenrun[0]); 1506c2aa98e2SPeter Wemm if (tTd(3, 15)) 1507c2aa98e2SPeter Wemm printf(", %ld, %ld", avenrun[1], avenrun[2]); 1508c2aa98e2SPeter Wemm # endif 1509c2aa98e2SPeter Wemm printf("\n"); 1510c2aa98e2SPeter Wemm } 1511c2aa98e2SPeter Wemm if (tTd(3, 1)) 1512c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1513c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1514c2aa98e2SPeter Wemm # else /* LA_TYPE == LA_FLOAT */ 1515c2aa98e2SPeter Wemm if (tTd(3, 5)) 1516c2aa98e2SPeter Wemm { 1517c2aa98e2SPeter Wemm printf("getla: avenrun = %g", avenrun[0]); 1518c2aa98e2SPeter Wemm if (tTd(3, 15)) 1519c2aa98e2SPeter Wemm printf(", %g, %g", avenrun[1], avenrun[2]); 1520c2aa98e2SPeter Wemm printf("\n"); 1521c2aa98e2SPeter Wemm } 1522c2aa98e2SPeter Wemm if (tTd(3, 1)) 1523c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (avenrun[0] +0.5)); 1524c2aa98e2SPeter Wemm return ((int) (avenrun[0] + 0.5)); 1525c2aa98e2SPeter Wemm # endif 1526c2aa98e2SPeter Wemm } 1527c2aa98e2SPeter Wemm 1528c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_INT or LA_SHORT or LA_FLOAT */ 1529c2aa98e2SPeter Wemm 1530c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM 1531c2aa98e2SPeter Wemm 1532c2aa98e2SPeter Wemm # include <sys/ksym.h> 1533c2aa98e2SPeter Wemm 1534c2aa98e2SPeter Wemm getla() 1535c2aa98e2SPeter Wemm { 1536c2aa98e2SPeter Wemm static int kmem = -1; 1537c2aa98e2SPeter Wemm long avenrun[3]; 1538c2aa98e2SPeter Wemm extern int errno; 1539c2aa98e2SPeter Wemm struct mioc_rksym mirk; 1540c2aa98e2SPeter Wemm 1541c2aa98e2SPeter Wemm if (kmem < 0) 1542c2aa98e2SPeter Wemm { 1543c2aa98e2SPeter Wemm kmem = open("/dev/kmem", 0, 0); 1544c2aa98e2SPeter Wemm if (kmem < 0) 1545c2aa98e2SPeter Wemm { 1546c2aa98e2SPeter Wemm if (tTd(3, 1)) 1547c2aa98e2SPeter Wemm printf("getla: open(/dev/kmem): %s\n", 1548c2aa98e2SPeter Wemm errstring(errno)); 1549c2aa98e2SPeter Wemm return (-1); 1550c2aa98e2SPeter Wemm } 1551c2aa98e2SPeter Wemm (void) fcntl(kmem, F_SETFD, 1); 1552c2aa98e2SPeter Wemm } 1553c2aa98e2SPeter Wemm mirk.mirk_symname = LA_AVENRUN; 1554c2aa98e2SPeter Wemm mirk.mirk_buf = avenrun; 1555c2aa98e2SPeter Wemm mirk.mirk_buflen = sizeof(avenrun); 1556c2aa98e2SPeter Wemm if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0) 1557c2aa98e2SPeter Wemm { 1558c2aa98e2SPeter Wemm if (tTd(3, 1)) 1559c2aa98e2SPeter Wemm printf("getla: ioctl(MIOC_READKSYM) failed: %s\n", 1560c2aa98e2SPeter Wemm errstring(errno)); 1561c2aa98e2SPeter Wemm return -1; 1562c2aa98e2SPeter Wemm } 1563c2aa98e2SPeter Wemm if (tTd(3, 5)) 1564c2aa98e2SPeter Wemm { 1565c2aa98e2SPeter Wemm printf("getla: avenrun = %d", avenrun[0]); 1566c2aa98e2SPeter Wemm if (tTd(3, 15)) 1567c2aa98e2SPeter Wemm printf(", %d, %d", avenrun[1], avenrun[2]); 1568c2aa98e2SPeter Wemm printf("\n"); 1569c2aa98e2SPeter Wemm } 1570c2aa98e2SPeter Wemm if (tTd(3, 1)) 1571c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1572c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1573c2aa98e2SPeter Wemm } 1574c2aa98e2SPeter Wemm 1575c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */ 1576c2aa98e2SPeter Wemm 1577c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX 1578c2aa98e2SPeter Wemm 1579c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h> 1580c2aa98e2SPeter Wemm 1581c2aa98e2SPeter Wemm int 1582c2aa98e2SPeter Wemm getla() 1583c2aa98e2SPeter Wemm { 1584c2aa98e2SPeter Wemm struct dg_sys_info_load_info load_info; 1585c2aa98e2SPeter Wemm 1586c2aa98e2SPeter Wemm dg_sys_info((long *)&load_info, 1587c2aa98e2SPeter Wemm DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); 1588c2aa98e2SPeter Wemm 1589c2aa98e2SPeter Wemm if (tTd(3, 1)) 1590c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (load_info.one_minute + 0.5)); 1591c2aa98e2SPeter Wemm 1592c2aa98e2SPeter Wemm return((int) (load_info.one_minute + 0.5)); 1593c2aa98e2SPeter Wemm } 1594c2aa98e2SPeter Wemm 1595c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */ 1596c2aa98e2SPeter Wemm 1597c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX 1598c2aa98e2SPeter Wemm 1599c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */ 1600c2aa98e2SPeter Wemm struct pst_dynamic; 1601c2aa98e2SPeter Wemm struct pst_status; 1602c2aa98e2SPeter Wemm struct pst_static; 1603c2aa98e2SPeter Wemm struct pst_vminfo; 1604c2aa98e2SPeter Wemm struct pst_diskinfo; 1605c2aa98e2SPeter Wemm struct pst_processor; 1606c2aa98e2SPeter Wemm struct pst_lv; 1607c2aa98e2SPeter Wemm struct pst_swapinfo; 1608c2aa98e2SPeter Wemm 1609c2aa98e2SPeter Wemm # include <sys/param.h> 1610c2aa98e2SPeter Wemm # include <sys/pstat.h> 1611c2aa98e2SPeter Wemm 1612c2aa98e2SPeter Wemm int 1613c2aa98e2SPeter Wemm getla() 1614c2aa98e2SPeter Wemm { 1615c2aa98e2SPeter Wemm struct pst_dynamic pstd; 1616c2aa98e2SPeter Wemm 1617c2aa98e2SPeter Wemm if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic), 1618c2aa98e2SPeter Wemm (size_t) 1, 0) == -1) 1619c2aa98e2SPeter Wemm return 0; 1620c2aa98e2SPeter Wemm 1621c2aa98e2SPeter Wemm if (tTd(3, 1)) 1622c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5)); 1623c2aa98e2SPeter Wemm 1624c2aa98e2SPeter Wemm return (int) (pstd.psd_avg_1_min + 0.5); 1625c2aa98e2SPeter Wemm } 1626c2aa98e2SPeter Wemm 1627c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */ 1628c2aa98e2SPeter Wemm 1629c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR 1630c2aa98e2SPeter Wemm 1631c2aa98e2SPeter Wemm int 1632c2aa98e2SPeter Wemm getla() 1633c2aa98e2SPeter Wemm { 1634c2aa98e2SPeter Wemm double avenrun[3]; 1635c2aa98e2SPeter Wemm 1636c2aa98e2SPeter Wemm if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 1637c2aa98e2SPeter Wemm { 1638c2aa98e2SPeter Wemm if (tTd(3, 1)) 1639c2aa98e2SPeter Wemm perror("getla: getloadavg failed:"); 1640c2aa98e2SPeter Wemm return (-1); 1641c2aa98e2SPeter Wemm } 1642c2aa98e2SPeter Wemm if (tTd(3, 1)) 1643c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (avenrun[0] +0.5)); 1644c2aa98e2SPeter Wemm return ((int) (avenrun[0] + 0.5)); 1645c2aa98e2SPeter Wemm } 1646c2aa98e2SPeter Wemm 1647c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */ 1648c2aa98e2SPeter Wemm 1649c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH 1650c2aa98e2SPeter Wemm 1651c2aa98e2SPeter Wemm /* 1652c2aa98e2SPeter Wemm ** This has been tested on NEXTSTEP release 2.1/3.X. 1653c2aa98e2SPeter Wemm */ 1654c2aa98e2SPeter Wemm 1655c2aa98e2SPeter Wemm #if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 1656c2aa98e2SPeter Wemm # include <mach/mach.h> 1657c2aa98e2SPeter Wemm #else 1658c2aa98e2SPeter Wemm # include <mach.h> 1659c2aa98e2SPeter Wemm #endif 1660c2aa98e2SPeter Wemm 1661c2aa98e2SPeter Wemm int 1662c2aa98e2SPeter Wemm getla() 1663c2aa98e2SPeter Wemm { 1664c2aa98e2SPeter Wemm processor_set_t default_set; 1665c2aa98e2SPeter Wemm kern_return_t error; 1666c2aa98e2SPeter Wemm unsigned int info_count; 1667c2aa98e2SPeter Wemm struct processor_set_basic_info info; 1668c2aa98e2SPeter Wemm host_t host; 1669c2aa98e2SPeter Wemm 1670c2aa98e2SPeter Wemm error = processor_set_default(host_self(), &default_set); 1671c2aa98e2SPeter Wemm if (error != KERN_SUCCESS) 1672c2aa98e2SPeter Wemm { 1673c2aa98e2SPeter Wemm if (tTd(3, 1)) 1674c2aa98e2SPeter Wemm perror("getla: processor_set_default failed:"); 1675c2aa98e2SPeter Wemm return -1; 1676c2aa98e2SPeter Wemm } 1677c2aa98e2SPeter Wemm info_count = PROCESSOR_SET_BASIC_INFO_COUNT; 1678c2aa98e2SPeter Wemm if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, 1679c2aa98e2SPeter Wemm &host, (processor_set_info_t)&info, 1680c2aa98e2SPeter Wemm &info_count) != KERN_SUCCESS) 1681c2aa98e2SPeter Wemm { 1682c2aa98e2SPeter Wemm if (tTd(3, 1)) 1683c2aa98e2SPeter Wemm perror("getla: processor_set_info failed:"); 1684c2aa98e2SPeter Wemm return -1; 1685c2aa98e2SPeter Wemm } 1686c2aa98e2SPeter Wemm if (tTd(3, 1)) 1687c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE); 1688c2aa98e2SPeter Wemm return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE; 1689c2aa98e2SPeter Wemm } 1690c2aa98e2SPeter Wemm 1691c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */ 1692c2aa98e2SPeter Wemm 1693c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR 1694c2aa98e2SPeter Wemm 1695c2aa98e2SPeter Wemm /* 1696c2aa98e2SPeter Wemm ** Read /proc/loadavg for the load average. This is assumed to be 1697c2aa98e2SPeter Wemm ** in a format like "0.15 0.12 0.06". 1698c2aa98e2SPeter Wemm ** 1699c2aa98e2SPeter Wemm ** Initially intended for Linux. This has been in the kernel 1700c2aa98e2SPeter Wemm ** since at least 0.99.15. 1701c2aa98e2SPeter Wemm */ 1702c2aa98e2SPeter Wemm 1703c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG 1704c2aa98e2SPeter Wemm # define _PATH_LOADAVG "/proc/loadavg" 1705c2aa98e2SPeter Wemm # endif 1706c2aa98e2SPeter Wemm 1707c2aa98e2SPeter Wemm int 1708c2aa98e2SPeter Wemm getla() 1709c2aa98e2SPeter Wemm { 1710c2aa98e2SPeter Wemm double avenrun; 1711c2aa98e2SPeter Wemm register int result; 1712c2aa98e2SPeter Wemm FILE *fp; 1713c2aa98e2SPeter Wemm 1714c2aa98e2SPeter Wemm fp = fopen(_PATH_LOADAVG, "r"); 1715c2aa98e2SPeter Wemm if (fp == NULL) 1716c2aa98e2SPeter Wemm { 1717c2aa98e2SPeter Wemm if (tTd(3, 1)) 1718c2aa98e2SPeter Wemm printf("getla: fopen(%s): %s\n", 1719c2aa98e2SPeter Wemm _PATH_LOADAVG, errstring(errno)); 1720c2aa98e2SPeter Wemm return -1; 1721c2aa98e2SPeter Wemm } 1722c2aa98e2SPeter Wemm result = fscanf(fp, "%lf", &avenrun); 1723c2aa98e2SPeter Wemm fclose(fp); 1724c2aa98e2SPeter Wemm if (result != 1) 1725c2aa98e2SPeter Wemm { 1726c2aa98e2SPeter Wemm if (tTd(3, 1)) 1727c2aa98e2SPeter Wemm printf("getla: fscanf() = %d: %s\n", 1728c2aa98e2SPeter Wemm result, errstring(errno)); 1729c2aa98e2SPeter Wemm return -1; 1730c2aa98e2SPeter Wemm } 1731c2aa98e2SPeter Wemm 1732c2aa98e2SPeter Wemm if (tTd(3, 1)) 1733c2aa98e2SPeter Wemm printf("getla(): %.2f\n", avenrun); 1734c2aa98e2SPeter Wemm 1735c2aa98e2SPeter Wemm return ((int) (avenrun + 0.5)); 1736c2aa98e2SPeter Wemm } 1737c2aa98e2SPeter Wemm 1738c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */ 1739c2aa98e2SPeter Wemm 1740c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6 1741c2aa98e2SPeter Wemm #include <sys/sysmp.h> 1742c2aa98e2SPeter Wemm 1743c2aa98e2SPeter Wemm int getla(void) 1744c2aa98e2SPeter Wemm { 1745c2aa98e2SPeter Wemm static int kmem = -1; 1746c2aa98e2SPeter Wemm int avenrun[3]; 1747c2aa98e2SPeter Wemm 1748c2aa98e2SPeter Wemm if (kmem < 0) 1749c2aa98e2SPeter Wemm { 1750c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, 0, 0); 1751c2aa98e2SPeter Wemm if (kmem < 0) 1752c2aa98e2SPeter Wemm { 1753c2aa98e2SPeter Wemm if (tTd(3, 1)) 1754c2aa98e2SPeter Wemm printf("getla: open(%s): %s\n", _PATH_KMEM, 1755c2aa98e2SPeter Wemm errstring(errno)); 1756c2aa98e2SPeter Wemm return -1; 1757c2aa98e2SPeter Wemm } 1758c2aa98e2SPeter Wemm (void) fcntl(kmem, F_SETFD, 1); 1759c2aa98e2SPeter Wemm } 1760c2aa98e2SPeter Wemm 1761c2aa98e2SPeter Wemm if (lseek(kmem, (sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff), SEEK_SET) == -1 || 1762c2aa98e2SPeter Wemm read(kmem, (char *)avenrun, sizeof(avenrun)) < sizeof(avenrun)) 1763c2aa98e2SPeter Wemm { 1764c2aa98e2SPeter Wemm if (tTd(3, 1)) 1765c2aa98e2SPeter Wemm printf("getla: lseek or read: %s\n", 1766c2aa98e2SPeter Wemm errstring(errno)); 1767c2aa98e2SPeter Wemm return -1; 1768c2aa98e2SPeter Wemm } 1769c2aa98e2SPeter Wemm if (tTd(3, 5)) 1770c2aa98e2SPeter Wemm { 1771c2aa98e2SPeter Wemm printf("getla: avenrun = %ld", (long int) avenrun[0]); 1772c2aa98e2SPeter Wemm if (tTd(3, 15)) 1773c2aa98e2SPeter Wemm printf(", %ld, %ld", 1774c2aa98e2SPeter Wemm (long int) avenrun[1], (long int) avenrun[2]); 1775c2aa98e2SPeter Wemm printf("\n"); 1776c2aa98e2SPeter Wemm } 1777c2aa98e2SPeter Wemm 1778c2aa98e2SPeter Wemm if (tTd(3, 1)) 1779c2aa98e2SPeter Wemm printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1780c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1781c2aa98e2SPeter Wemm 1782c2aa98e2SPeter Wemm } 1783c2aa98e2SPeter Wemm #endif 1784c2aa98e2SPeter Wemm 1785c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT 1786c2aa98e2SPeter Wemm 1787c2aa98e2SPeter Wemm #include <kstat.h> 1788c2aa98e2SPeter Wemm 1789c2aa98e2SPeter Wemm int 1790c2aa98e2SPeter Wemm getla() 1791c2aa98e2SPeter Wemm { 1792c2aa98e2SPeter Wemm static kstat_ctl_t *kc = NULL; 1793c2aa98e2SPeter Wemm static kstat_t *ksp = NULL; 1794c2aa98e2SPeter Wemm kstat_named_t *ksn; 1795c2aa98e2SPeter Wemm int la; 1796c2aa98e2SPeter Wemm 1797c2aa98e2SPeter Wemm if (kc == NULL) /* if not initialized before */ 1798c2aa98e2SPeter Wemm kc = kstat_open(); 1799c2aa98e2SPeter Wemm if (kc == NULL) 1800c2aa98e2SPeter Wemm { 1801c2aa98e2SPeter Wemm if (tTd(3, 1)) 1802c2aa98e2SPeter Wemm printf("getla: kstat_open(): %s\n", 1803c2aa98e2SPeter Wemm errstring(errno)); 1804c2aa98e2SPeter Wemm return -1; 1805c2aa98e2SPeter Wemm } 1806c2aa98e2SPeter Wemm if (ksp == NULL) 1807c2aa98e2SPeter Wemm ksp = kstat_lookup(kc, "unix", 0, "system_misc"); 1808c2aa98e2SPeter Wemm if (ksp == NULL) 1809c2aa98e2SPeter Wemm { 1810c2aa98e2SPeter Wemm if (tTd(3, 1)) 1811c2aa98e2SPeter Wemm printf("getla: kstat_lookup(): %s\n", 1812c2aa98e2SPeter Wemm errstring(errno)); 1813c2aa98e2SPeter Wemm return -1; 1814c2aa98e2SPeter Wemm } 1815c2aa98e2SPeter Wemm if (kstat_read(kc, ksp, NULL) < 0) 1816c2aa98e2SPeter Wemm { 1817c2aa98e2SPeter Wemm if (tTd(3, 1)) 1818c2aa98e2SPeter Wemm printf("getla: kstat_read(): %s\n", 1819c2aa98e2SPeter Wemm errstring(errno)); 1820c2aa98e2SPeter Wemm return -1; 1821c2aa98e2SPeter Wemm } 1822c2aa98e2SPeter Wemm ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min"); 1823c2aa98e2SPeter Wemm la = ((double)ksn->value.ul + FSCALE/2) / FSCALE; 1824c2aa98e2SPeter Wemm /* kstat_close(kc); /o do not close for fast access */ 1825c2aa98e2SPeter Wemm return la; 1826c2aa98e2SPeter Wemm } 1827c2aa98e2SPeter Wemm 1828c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */ 1829c2aa98e2SPeter Wemm 1830c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT 1831c2aa98e2SPeter Wemm 1832c2aa98e2SPeter Wemm /* 1833c2aa98e2SPeter Wemm ** Read /dev/table/avenrun for the load average. This should contain 1834c2aa98e2SPeter Wemm ** three shorts for the 1, 5, and 15 minute loads. We only read the 1835c2aa98e2SPeter Wemm ** first, since that's all we care about. 1836c2aa98e2SPeter Wemm ** 1837c2aa98e2SPeter Wemm ** Intended for SCO OpenServer 5. 1838c2aa98e2SPeter Wemm */ 1839c2aa98e2SPeter Wemm 1840c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN 1841c2aa98e2SPeter Wemm # define _PATH_AVENRUN "/dev/table/avenrun" 1842c2aa98e2SPeter Wemm # endif 1843c2aa98e2SPeter Wemm 1844c2aa98e2SPeter Wemm int 1845c2aa98e2SPeter Wemm getla() 1846c2aa98e2SPeter Wemm { 1847c2aa98e2SPeter Wemm static int afd = -1; 1848c2aa98e2SPeter Wemm short avenrun; 1849c2aa98e2SPeter Wemm int loadav; 1850c2aa98e2SPeter Wemm int r; 1851c2aa98e2SPeter Wemm 1852c2aa98e2SPeter Wemm errno = EBADF; 1853c2aa98e2SPeter Wemm 1854c2aa98e2SPeter Wemm if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1) 1855c2aa98e2SPeter Wemm { 1856c2aa98e2SPeter Wemm if (errno != EBADF) 1857c2aa98e2SPeter Wemm return -1; 1858c2aa98e2SPeter Wemm afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC); 1859c2aa98e2SPeter Wemm if (afd < 0) 1860c2aa98e2SPeter Wemm { 1861c2aa98e2SPeter Wemm sm_syslog(LOG_ERR, NOQID, 1862c2aa98e2SPeter Wemm "can't open %s: %m", 1863c2aa98e2SPeter Wemm _PATH_AVENRUN); 1864c2aa98e2SPeter Wemm return -1; 1865c2aa98e2SPeter Wemm } 1866c2aa98e2SPeter Wemm } 1867c2aa98e2SPeter Wemm 1868c2aa98e2SPeter Wemm r = read(afd, &avenrun, sizeof avenrun); 1869c2aa98e2SPeter Wemm 1870c2aa98e2SPeter Wemm if (tTd(3, 5)) 1871c2aa98e2SPeter Wemm printf("getla: avenrun = %d\n", avenrun); 1872c2aa98e2SPeter Wemm loadav = (int) (avenrun + FSCALE/2) >> FSHIFT; 1873c2aa98e2SPeter Wemm if (tTd(3, 1)) 1874c2aa98e2SPeter Wemm printf("getla: %d\n", loadav); 1875c2aa98e2SPeter Wemm return loadav; 1876c2aa98e2SPeter Wemm } 1877c2aa98e2SPeter Wemm 1878c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */ 1879c2aa98e2SPeter Wemm 1880c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF 1881c2aa98e2SPeter Wemm struct rtentry; 1882c2aa98e2SPeter Wemm struct mbuf; 1883c2aa98e2SPeter Wemm # include <sys/table.h> 1884c2aa98e2SPeter Wemm 1885c2aa98e2SPeter Wemm int getla() 1886c2aa98e2SPeter Wemm { 1887c2aa98e2SPeter Wemm int ave = 0; 1888c2aa98e2SPeter Wemm struct tbl_loadavg tab; 1889c2aa98e2SPeter Wemm 1890c2aa98e2SPeter Wemm if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1) 1891c2aa98e2SPeter Wemm { 1892c2aa98e2SPeter Wemm if (tTd(3, 1)) 1893c2aa98e2SPeter Wemm printf("getla: table %s\n", errstring(errno)); 1894c2aa98e2SPeter Wemm return (-1); 1895c2aa98e2SPeter Wemm } 1896c2aa98e2SPeter Wemm 1897c2aa98e2SPeter Wemm if (tTd(3, 1)) 1898c2aa98e2SPeter Wemm printf("getla: scale = %d\n", tab.tl_lscale); 1899c2aa98e2SPeter Wemm 1900c2aa98e2SPeter Wemm if (tab.tl_lscale) 1901c2aa98e2SPeter Wemm ave = (tab.tl_avenrun.l[0] + (tab.tl_lscale/2)) / tab.tl_lscale; 1902c2aa98e2SPeter Wemm else 1903c2aa98e2SPeter Wemm ave = (int) (tab.tl_avenrun.d[0] + 0.5); 1904c2aa98e2SPeter Wemm 1905c2aa98e2SPeter Wemm if (tTd(3, 1)) 1906c2aa98e2SPeter Wemm printf("getla: %d\n", ave); 1907c2aa98e2SPeter Wemm 1908c2aa98e2SPeter Wemm return ave; 1909c2aa98e2SPeter Wemm } 1910c2aa98e2SPeter Wemm 1911c2aa98e2SPeter Wemm #endif 1912c2aa98e2SPeter Wemm 1913c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO 1914c2aa98e2SPeter Wemm 1915c2aa98e2SPeter Wemm int 1916c2aa98e2SPeter Wemm getla() 1917c2aa98e2SPeter Wemm { 1918c2aa98e2SPeter Wemm if (tTd(3, 1)) 1919c2aa98e2SPeter Wemm printf("getla: ZERO\n"); 1920c2aa98e2SPeter Wemm return (0); 1921c2aa98e2SPeter Wemm } 1922c2aa98e2SPeter Wemm 1923c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */ 1924c2aa98e2SPeter Wemm 1925c2aa98e2SPeter Wemm /* 1926c2aa98e2SPeter Wemm * Copyright 1989 Massachusetts Institute of Technology 1927c2aa98e2SPeter Wemm * 1928c2aa98e2SPeter Wemm * Permission to use, copy, modify, distribute, and sell this software and its 1929c2aa98e2SPeter Wemm * documentation for any purpose is hereby granted without fee, provided that 1930c2aa98e2SPeter Wemm * the above copyright notice appear in all copies and that both that 1931c2aa98e2SPeter Wemm * copyright notice and this permission notice appear in supporting 1932c2aa98e2SPeter Wemm * documentation, and that the name of M.I.T. not be used in advertising or 1933c2aa98e2SPeter Wemm * publicity pertaining to distribution of the software without specific, 1934c2aa98e2SPeter Wemm * written prior permission. M.I.T. makes no representations about the 1935c2aa98e2SPeter Wemm * suitability of this software for any purpose. It is provided "as is" 1936c2aa98e2SPeter Wemm * without express or implied warranty. 1937c2aa98e2SPeter Wemm * 1938c2aa98e2SPeter Wemm * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 1939c2aa98e2SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 1940c2aa98e2SPeter Wemm * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1941c2aa98e2SPeter Wemm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1942c2aa98e2SPeter Wemm * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1943c2aa98e2SPeter Wemm * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1944c2aa98e2SPeter Wemm * 1945c2aa98e2SPeter Wemm * Authors: Many and varied... 1946c2aa98e2SPeter Wemm */ 1947c2aa98e2SPeter Wemm 1948c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */ 1949c2aa98e2SPeter Wemm #ifndef lint 1950c2aa98e2SPeter Wemm static char rcsid[] = "@(#)$Id: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $"; 1951c2aa98e2SPeter Wemm #endif /* !lint */ 1952c2aa98e2SPeter Wemm 1953c2aa98e2SPeter Wemm #ifdef apollo 1954c2aa98e2SPeter Wemm # undef volatile 1955c2aa98e2SPeter Wemm # include <apollo/base.h> 1956c2aa98e2SPeter Wemm 1957c2aa98e2SPeter Wemm /* ARGSUSED */ 1958c2aa98e2SPeter Wemm int getloadavg( call_data ) 1959c2aa98e2SPeter Wemm caddr_t call_data; /* pointer to (double) return value */ 1960c2aa98e2SPeter Wemm { 1961c2aa98e2SPeter Wemm double *avenrun = (double *) call_data; 1962c2aa98e2SPeter Wemm int i; 1963c2aa98e2SPeter Wemm status_$t st; 1964c2aa98e2SPeter Wemm long loadav[3]; 1965c2aa98e2SPeter Wemm proc1_$get_loadav(loadav, &st); 1966c2aa98e2SPeter Wemm *avenrun = loadav[0] / (double) (1 << 16); 1967c2aa98e2SPeter Wemm return(0); 1968c2aa98e2SPeter Wemm } 1969c2aa98e2SPeter Wemm # endif /* apollo */ 1970c2aa98e2SPeter Wemm /* 1971c2aa98e2SPeter Wemm ** SHOULDQUEUE -- should this message be queued or sent? 1972c2aa98e2SPeter Wemm ** 1973c2aa98e2SPeter Wemm ** Compares the message cost to the load average to decide. 1974c2aa98e2SPeter Wemm ** 1975c2aa98e2SPeter Wemm ** Parameters: 1976c2aa98e2SPeter Wemm ** pri -- the priority of the message in question. 1977c2aa98e2SPeter Wemm ** ctime -- the message creation time. 1978c2aa98e2SPeter Wemm ** 1979c2aa98e2SPeter Wemm ** Returns: 1980c2aa98e2SPeter Wemm ** TRUE -- if this message should be queued up for the 1981c2aa98e2SPeter Wemm ** time being. 1982c2aa98e2SPeter Wemm ** FALSE -- if the load is low enough to send this message. 1983c2aa98e2SPeter Wemm ** 1984c2aa98e2SPeter Wemm ** Side Effects: 1985c2aa98e2SPeter Wemm ** none. 1986c2aa98e2SPeter Wemm */ 1987c2aa98e2SPeter Wemm 1988c2aa98e2SPeter Wemm extern int get_num_procs_online __P((void)); 1989c2aa98e2SPeter Wemm 1990c2aa98e2SPeter Wemm bool 1991c2aa98e2SPeter Wemm shouldqueue(pri, ctime) 1992c2aa98e2SPeter Wemm long pri; 1993c2aa98e2SPeter Wemm time_t ctime; 1994c2aa98e2SPeter Wemm { 1995c2aa98e2SPeter Wemm bool rval; 1996c2aa98e2SPeter Wemm int queuela = QueueLA * get_num_procs_online(); 1997c2aa98e2SPeter Wemm 1998c2aa98e2SPeter Wemm if (tTd(3, 30)) 1999c2aa98e2SPeter Wemm printf("shouldqueue: CurrentLA=%d, pri=%ld: ", CurrentLA, pri); 2000c2aa98e2SPeter Wemm if (CurrentLA < queuela) 2001c2aa98e2SPeter Wemm { 2002c2aa98e2SPeter Wemm if (tTd(3, 30)) 2003c2aa98e2SPeter Wemm printf("FALSE (CurrentLA < QueueLA)\n"); 2004c2aa98e2SPeter Wemm return (FALSE); 2005c2aa98e2SPeter Wemm } 2006c2aa98e2SPeter Wemm #if 0 /* this code is reported to cause oscillation around RefuseLA */ 2007c2aa98e2SPeter Wemm if (CurrentLA >= RefuseLA && QueueLA < RefuseLA) 2008c2aa98e2SPeter Wemm { 2009c2aa98e2SPeter Wemm if (tTd(3, 30)) 2010c2aa98e2SPeter Wemm printf("TRUE (CurrentLA >= RefuseLA)\n"); 2011c2aa98e2SPeter Wemm return (TRUE); 2012c2aa98e2SPeter Wemm } 2013c2aa98e2SPeter Wemm #endif 2014c2aa98e2SPeter Wemm rval = pri > (QueueFactor / (CurrentLA - queuela + 1)); 2015c2aa98e2SPeter Wemm if (tTd(3, 30)) 2016c2aa98e2SPeter Wemm printf("%s (by calculation)\n", rval ? "TRUE" : "FALSE"); 2017c2aa98e2SPeter Wemm return rval; 2018c2aa98e2SPeter Wemm } 2019c2aa98e2SPeter Wemm /* 2020c2aa98e2SPeter Wemm ** REFUSECONNECTIONS -- decide if connections should be refused 2021c2aa98e2SPeter Wemm ** 2022c2aa98e2SPeter Wemm ** Parameters: 2023c2aa98e2SPeter Wemm ** port -- port number (for error messages only) 2024c2aa98e2SPeter Wemm ** 2025c2aa98e2SPeter Wemm ** Returns: 2026c2aa98e2SPeter Wemm ** TRUE if incoming SMTP connections should be refused 2027c2aa98e2SPeter Wemm ** (for now). 2028c2aa98e2SPeter Wemm ** FALSE if we should accept new work. 2029c2aa98e2SPeter Wemm ** 2030c2aa98e2SPeter Wemm ** Side Effects: 2031c2aa98e2SPeter Wemm ** Sets process title when it is rejecting connections. 2032c2aa98e2SPeter Wemm */ 2033c2aa98e2SPeter Wemm 2034c2aa98e2SPeter Wemm bool 2035c2aa98e2SPeter Wemm refuseconnections(port) 2036c2aa98e2SPeter Wemm int port; 2037c2aa98e2SPeter Wemm { 2038c2aa98e2SPeter Wemm int refusela = RefuseLA * get_num_procs_online(); 2039c2aa98e2SPeter Wemm time_t now; 2040c2aa98e2SPeter Wemm static time_t lastconn = (time_t) 0; 2041c2aa98e2SPeter Wemm static int conncnt = 0; 2042c2aa98e2SPeter Wemm extern bool enoughdiskspace __P((long)); 2043c2aa98e2SPeter Wemm 2044c2aa98e2SPeter Wemm #ifdef XLA 2045c2aa98e2SPeter Wemm if (!xla_smtp_ok()) 2046c2aa98e2SPeter Wemm return TRUE; 2047c2aa98e2SPeter Wemm #endif 2048c2aa98e2SPeter Wemm 2049c2aa98e2SPeter Wemm now = curtime(); 2050c2aa98e2SPeter Wemm if (now != lastconn) 2051c2aa98e2SPeter Wemm { 2052c2aa98e2SPeter Wemm lastconn = now; 2053c2aa98e2SPeter Wemm conncnt = 0; 2054c2aa98e2SPeter Wemm } 2055c2aa98e2SPeter Wemm else if (conncnt++ > ConnRateThrottle && ConnRateThrottle > 0) 2056c2aa98e2SPeter Wemm { 2057c2aa98e2SPeter Wemm /* sleep to flatten out connection load */ 205876b7bf71SPeter Wemm sm_setproctitle(TRUE, "deferring connections on port %d: %d per second", 2059c2aa98e2SPeter Wemm port, ConnRateThrottle); 2060c2aa98e2SPeter Wemm if (LogLevel >= 14) 2061c2aa98e2SPeter Wemm sm_syslog(LOG_INFO, NOQID, 2062c2aa98e2SPeter Wemm "deferring connections on port %d: %d per second", 2063c2aa98e2SPeter Wemm port, ConnRateThrottle); 2064c2aa98e2SPeter Wemm sleep(1); 2065c2aa98e2SPeter Wemm } 2066c2aa98e2SPeter Wemm 2067c2aa98e2SPeter Wemm CurrentLA = getla(); 2068c2aa98e2SPeter Wemm if (CurrentLA >= refusela) 2069c2aa98e2SPeter Wemm { 207076b7bf71SPeter Wemm sm_setproctitle(TRUE, "rejecting connections on port %d: load average: %d", 2071c2aa98e2SPeter Wemm port, CurrentLA); 2072c2aa98e2SPeter Wemm if (LogLevel >= 14) 2073c2aa98e2SPeter Wemm sm_syslog(LOG_INFO, NOQID, 2074c2aa98e2SPeter Wemm "rejecting connections on port %d: load average: %d", 2075c2aa98e2SPeter Wemm port, CurrentLA); 2076c2aa98e2SPeter Wemm return TRUE; 2077c2aa98e2SPeter Wemm } 2078c2aa98e2SPeter Wemm 2079c2aa98e2SPeter Wemm if (!enoughdiskspace(MinBlocksFree + 1)) 2080c2aa98e2SPeter Wemm { 208176b7bf71SPeter Wemm sm_setproctitle(TRUE, "rejecting connections on port %d: min free: %d", 2082c2aa98e2SPeter Wemm port, MinBlocksFree); 2083c2aa98e2SPeter Wemm if (LogLevel >= 14) 2084c2aa98e2SPeter Wemm sm_syslog(LOG_INFO, NOQID, 2085c2aa98e2SPeter Wemm "rejecting connections on port %d: min free: %d", 2086c2aa98e2SPeter Wemm port, MinBlocksFree); 2087c2aa98e2SPeter Wemm return TRUE; 2088c2aa98e2SPeter Wemm } 2089c2aa98e2SPeter Wemm 2090c2aa98e2SPeter Wemm if (MaxChildren > 0 && CurChildren >= MaxChildren) 2091c2aa98e2SPeter Wemm { 2092c2aa98e2SPeter Wemm proc_list_probe(); 2093c2aa98e2SPeter Wemm if (CurChildren >= MaxChildren) 2094c2aa98e2SPeter Wemm { 209576b7bf71SPeter Wemm sm_setproctitle(TRUE, "rejecting connections on port %d: %d children, max %d", 2096c2aa98e2SPeter Wemm port, CurChildren, MaxChildren); 2097c2aa98e2SPeter Wemm if (LogLevel >= 14) 2098c2aa98e2SPeter Wemm sm_syslog(LOG_INFO, NOQID, 2099c2aa98e2SPeter Wemm "rejecting connections on port %d: %d children, max %d", 2100c2aa98e2SPeter Wemm port, CurChildren, MaxChildren); 2101c2aa98e2SPeter Wemm return TRUE; 2102c2aa98e2SPeter Wemm } 2103c2aa98e2SPeter Wemm } 2104c2aa98e2SPeter Wemm 2105c2aa98e2SPeter Wemm return FALSE; 2106c2aa98e2SPeter Wemm } 2107c2aa98e2SPeter Wemm /* 2108c2aa98e2SPeter Wemm ** SETPROCTITLE -- set process title for ps 2109c2aa98e2SPeter Wemm ** 2110c2aa98e2SPeter Wemm ** Parameters: 2111c2aa98e2SPeter Wemm ** fmt -- a printf style format string. 2112c2aa98e2SPeter Wemm ** a, b, c -- possible parameters to fmt. 2113c2aa98e2SPeter Wemm ** 2114c2aa98e2SPeter Wemm ** Returns: 2115c2aa98e2SPeter Wemm ** none. 2116c2aa98e2SPeter Wemm ** 2117c2aa98e2SPeter Wemm ** Side Effects: 2118c2aa98e2SPeter Wemm ** Clobbers argv of our main procedure so ps(1) will 2119c2aa98e2SPeter Wemm ** display the title. 2120c2aa98e2SPeter Wemm */ 2121c2aa98e2SPeter Wemm 2122c2aa98e2SPeter Wemm #define SPT_NONE 0 /* don't use it at all */ 2123c2aa98e2SPeter Wemm #define SPT_REUSEARGV 1 /* cover argv with title information */ 2124c2aa98e2SPeter Wemm #define SPT_BUILTIN 2 /* use libc builtin */ 2125c2aa98e2SPeter Wemm #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ 2126c2aa98e2SPeter Wemm #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ 2127c2aa98e2SPeter Wemm #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ 2128c2aa98e2SPeter Wemm #define SPT_SCO 6 /* write kernel u. area */ 2129c2aa98e2SPeter Wemm #define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ 2130c2aa98e2SPeter Wemm 2131c2aa98e2SPeter Wemm #ifndef SPT_TYPE 2132c2aa98e2SPeter Wemm # define SPT_TYPE SPT_REUSEARGV 2133c2aa98e2SPeter Wemm #endif 2134c2aa98e2SPeter Wemm 2135c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN 2136c2aa98e2SPeter Wemm 2137c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2138c2aa98e2SPeter Wemm # include <sys/pstat.h> 2139c2aa98e2SPeter Wemm # endif 2140c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS 2141c2aa98e2SPeter Wemm # include <machine/vmparam.h> 2142c2aa98e2SPeter Wemm # include <sys/exec.h> 2143c2aa98e2SPeter Wemm # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ 2144c2aa98e2SPeter Wemm # undef SPT_TYPE 2145c2aa98e2SPeter Wemm # define SPT_TYPE SPT_REUSEARGV 2146c2aa98e2SPeter Wemm # else 2147c2aa98e2SPeter Wemm # ifndef NKPDE /* FreeBSD 2.0 */ 2148c2aa98e2SPeter Wemm # define NKPDE 63 2149c2aa98e2SPeter Wemm typedef unsigned int *pt_entry_t; 2150c2aa98e2SPeter Wemm # endif 2151c2aa98e2SPeter Wemm # endif 2152c2aa98e2SPeter Wemm # endif 2153c2aa98e2SPeter Wemm 2154c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV 2155c2aa98e2SPeter Wemm # define SETPROC_STATIC static 2156c2aa98e2SPeter Wemm # else 2157c2aa98e2SPeter Wemm # define SETPROC_STATIC 2158c2aa98e2SPeter Wemm # endif 2159c2aa98e2SPeter Wemm 2160c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS 2161c2aa98e2SPeter Wemm # include <sys/sysmips.h> 2162c2aa98e2SPeter Wemm # include <sys/sysnews.h> 2163c2aa98e2SPeter Wemm # endif 2164c2aa98e2SPeter Wemm 2165c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 2166c2aa98e2SPeter Wemm # include <sys/immu.h> 2167c2aa98e2SPeter Wemm # include <sys/dir.h> 2168c2aa98e2SPeter Wemm # include <sys/user.h> 2169c2aa98e2SPeter Wemm # include <sys/fs/s5param.h> 2170c2aa98e2SPeter Wemm # if PSARGSZ > MAXLINE 2171c2aa98e2SPeter Wemm # define SPT_BUFSIZE PSARGSZ 2172c2aa98e2SPeter Wemm # endif 2173c2aa98e2SPeter Wemm # endif 2174c2aa98e2SPeter Wemm 2175c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR 2176c2aa98e2SPeter Wemm # define SPT_PADCHAR ' ' 2177c2aa98e2SPeter Wemm # endif 2178c2aa98e2SPeter Wemm 217976b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ 218076b7bf71SPeter Wemm 2181c2aa98e2SPeter Wemm # ifndef SPT_BUFSIZE 2182c2aa98e2SPeter Wemm # define SPT_BUFSIZE MAXLINE 2183c2aa98e2SPeter Wemm # endif 2184c2aa98e2SPeter Wemm 2185c2aa98e2SPeter Wemm /* 2186c2aa98e2SPeter Wemm ** Pointers for setproctitle. 2187c2aa98e2SPeter Wemm ** This allows "ps" listings to give more useful information. 2188c2aa98e2SPeter Wemm */ 2189c2aa98e2SPeter Wemm 2190c2aa98e2SPeter Wemm char **Argv = NULL; /* pointer to argument vector */ 2191c2aa98e2SPeter Wemm char *LastArgv = NULL; /* end of argv */ 2192c2aa98e2SPeter Wemm 2193c2aa98e2SPeter Wemm void 2194c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp) 2195c2aa98e2SPeter Wemm int argc; 2196c2aa98e2SPeter Wemm char **argv; 2197c2aa98e2SPeter Wemm char **envp; 2198c2aa98e2SPeter Wemm { 2199c2aa98e2SPeter Wemm register int i, envpsize = 0; 2200c2aa98e2SPeter Wemm extern char **environ; 2201c2aa98e2SPeter Wemm 2202c2aa98e2SPeter Wemm /* 2203c2aa98e2SPeter Wemm ** Move the environment so setproctitle can use the space at 2204c2aa98e2SPeter Wemm ** the top of memory. 2205c2aa98e2SPeter Wemm */ 2206c2aa98e2SPeter Wemm 2207c2aa98e2SPeter Wemm for (i = 0; envp[i] != NULL; i++) 2208c2aa98e2SPeter Wemm envpsize += strlen(envp[i]) + 1; 2209c2aa98e2SPeter Wemm environ = (char **) xalloc(sizeof (char *) * (i + 1)); 2210c2aa98e2SPeter Wemm for (i = 0; envp[i] != NULL; i++) 2211c2aa98e2SPeter Wemm environ[i] = newstr(envp[i]); 2212c2aa98e2SPeter Wemm environ[i] = NULL; 2213c2aa98e2SPeter Wemm 2214c2aa98e2SPeter Wemm /* 2215c2aa98e2SPeter Wemm ** Save start and extent of argv for setproctitle. 2216c2aa98e2SPeter Wemm */ 2217c2aa98e2SPeter Wemm 2218c2aa98e2SPeter Wemm Argv = argv; 2219c2aa98e2SPeter Wemm 2220c2aa98e2SPeter Wemm /* 2221c2aa98e2SPeter Wemm ** Determine how much space we can use for setproctitle. 2222c2aa98e2SPeter Wemm ** Use all contiguous argv and envp pointers starting at argv[0] 2223c2aa98e2SPeter Wemm */ 2224c2aa98e2SPeter Wemm for (i = 0; i < argc; i++) 2225c2aa98e2SPeter Wemm { 2226c2aa98e2SPeter Wemm if (i==0 || LastArgv + 1 == argv[i]) 2227c2aa98e2SPeter Wemm LastArgv = argv[i] + strlen(argv[i]); 2228c2aa98e2SPeter Wemm else 2229c2aa98e2SPeter Wemm continue; 2230c2aa98e2SPeter Wemm } 2231c2aa98e2SPeter Wemm for (i=0; envp[i] != NULL; i++) 2232c2aa98e2SPeter Wemm { 2233c2aa98e2SPeter Wemm if (LastArgv + 1 == envp[i]) 2234c2aa98e2SPeter Wemm LastArgv = envp[i] + strlen(envp[i]); 2235c2aa98e2SPeter Wemm else 2236c2aa98e2SPeter Wemm continue; 2237c2aa98e2SPeter Wemm } 2238c2aa98e2SPeter Wemm } 2239c2aa98e2SPeter Wemm 2240c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN 2241c2aa98e2SPeter Wemm 2242c2aa98e2SPeter Wemm 2243c2aa98e2SPeter Wemm /*VARARGS1*/ 2244c2aa98e2SPeter Wemm void 2245c2aa98e2SPeter Wemm # ifdef __STDC__ 2246c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...) 2247c2aa98e2SPeter Wemm # else 2248c2aa98e2SPeter Wemm setproctitle(fmt, va_alist) 2249c2aa98e2SPeter Wemm const char *fmt; 2250c2aa98e2SPeter Wemm va_dcl 2251c2aa98e2SPeter Wemm # endif 2252c2aa98e2SPeter Wemm { 2253c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE 2254c2aa98e2SPeter Wemm register char *p; 2255c2aa98e2SPeter Wemm register int i; 2256c2aa98e2SPeter Wemm SETPROC_STATIC char buf[SPT_BUFSIZE]; 2257c2aa98e2SPeter Wemm VA_LOCAL_DECL 2258c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2259c2aa98e2SPeter Wemm union pstun pst; 2260c2aa98e2SPeter Wemm # endif 2261c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 2262c2aa98e2SPeter Wemm off_t seek_off; 2263c2aa98e2SPeter Wemm static int kmem = -1; 2264c2aa98e2SPeter Wemm static int kmempid = -1; 2265c2aa98e2SPeter Wemm struct user u; 2266c2aa98e2SPeter Wemm # endif 2267c2aa98e2SPeter Wemm 2268c2aa98e2SPeter Wemm p = buf; 2269c2aa98e2SPeter Wemm 2270c2aa98e2SPeter Wemm /* print sendmail: heading for grep */ 2271c2aa98e2SPeter Wemm (void) strcpy(p, "sendmail: "); 2272c2aa98e2SPeter Wemm p += strlen(p); 2273c2aa98e2SPeter Wemm 2274c2aa98e2SPeter Wemm /* print the argument string */ 2275c2aa98e2SPeter Wemm VA_START(fmt); 2276c2aa98e2SPeter Wemm (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap); 2277c2aa98e2SPeter Wemm VA_END; 2278c2aa98e2SPeter Wemm 2279c2aa98e2SPeter Wemm i = strlen(buf); 2280c2aa98e2SPeter Wemm 2281c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2282c2aa98e2SPeter Wemm pst.pst_command = buf; 2283c2aa98e2SPeter Wemm pstat(PSTAT_SETCMD, pst, i, 0, 0); 2284c2aa98e2SPeter Wemm # endif 2285c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS 2286c2aa98e2SPeter Wemm PS_STRINGS->ps_nargvstr = 1; 2287c2aa98e2SPeter Wemm PS_STRINGS->ps_argvstr = buf; 2288c2aa98e2SPeter Wemm # endif 2289c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS 2290c2aa98e2SPeter Wemm sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); 2291c2aa98e2SPeter Wemm # endif 2292c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 2293c2aa98e2SPeter Wemm if (kmem < 0 || kmempid != getpid()) 2294c2aa98e2SPeter Wemm { 2295c2aa98e2SPeter Wemm if (kmem >= 0) 2296c2aa98e2SPeter Wemm close(kmem); 2297c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, O_RDWR, 0); 2298c2aa98e2SPeter Wemm if (kmem < 0) 2299c2aa98e2SPeter Wemm return; 2300c2aa98e2SPeter Wemm (void) fcntl(kmem, F_SETFD, 1); 2301c2aa98e2SPeter Wemm kmempid = getpid(); 2302c2aa98e2SPeter Wemm } 2303c2aa98e2SPeter Wemm buf[PSARGSZ - 1] = '\0'; 2304c2aa98e2SPeter Wemm seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; 2305c2aa98e2SPeter Wemm if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) 2306c2aa98e2SPeter Wemm (void) write(kmem, buf, PSARGSZ); 2307c2aa98e2SPeter Wemm # endif 2308c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_REUSEARGV 2309c2aa98e2SPeter Wemm if (i > LastArgv - Argv[0] - 2) 2310c2aa98e2SPeter Wemm { 2311c2aa98e2SPeter Wemm i = LastArgv - Argv[0] - 2; 2312c2aa98e2SPeter Wemm buf[i] = '\0'; 2313c2aa98e2SPeter Wemm } 2314c2aa98e2SPeter Wemm (void) strcpy(Argv[0], buf); 2315c2aa98e2SPeter Wemm p = &Argv[0][i]; 2316c2aa98e2SPeter Wemm while (p < LastArgv) 2317c2aa98e2SPeter Wemm *p++ = SPT_PADCHAR; 2318c2aa98e2SPeter Wemm Argv[1] = NULL; 2319c2aa98e2SPeter Wemm # endif 2320c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_CHANGEARGV 2321c2aa98e2SPeter Wemm Argv[0] = buf; 2322c2aa98e2SPeter Wemm Argv[1] = 0; 2323c2aa98e2SPeter Wemm # endif 2324c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */ 2325c2aa98e2SPeter Wemm } 2326c2aa98e2SPeter Wemm 2327c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */ 2328c2aa98e2SPeter Wemm /* 232976b7bf71SPeter Wemm ** SM_SETPROCTITLE -- set process task and set process title for ps 233076b7bf71SPeter Wemm ** 233176b7bf71SPeter Wemm ** Possibly set process status and call setproctitle() to 233276b7bf71SPeter Wemm ** change the ps display. 233376b7bf71SPeter Wemm ** 233476b7bf71SPeter Wemm ** Parameters: 233576b7bf71SPeter Wemm ** status -- whether or not to store as process status 233676b7bf71SPeter Wemm ** fmt -- a printf style format string. 233776b7bf71SPeter Wemm ** a, b, c -- possible parameters to fmt. 233876b7bf71SPeter Wemm ** 233976b7bf71SPeter Wemm ** Returns: 234076b7bf71SPeter Wemm ** none. 234176b7bf71SPeter Wemm */ 234276b7bf71SPeter Wemm 234376b7bf71SPeter Wemm /*VARARGS2*/ 234476b7bf71SPeter Wemm void 234576b7bf71SPeter Wemm # ifdef __STDC__ 234676b7bf71SPeter Wemm sm_setproctitle(bool status, const char *fmt, ...) 234776b7bf71SPeter Wemm # else 234876b7bf71SPeter Wemm sm_setproctitle(status, fmt, va_alist) 234976b7bf71SPeter Wemm bool status; 235076b7bf71SPeter Wemm const char *fmt; 235176b7bf71SPeter Wemm va_dcl 235276b7bf71SPeter Wemm #endif 235376b7bf71SPeter Wemm { 235476b7bf71SPeter Wemm char buf[SPT_BUFSIZE]; 235576b7bf71SPeter Wemm 235676b7bf71SPeter Wemm VA_LOCAL_DECL 235776b7bf71SPeter Wemm /* print the argument string */ 235876b7bf71SPeter Wemm VA_START(fmt); 235976b7bf71SPeter Wemm (void) vsnprintf(buf, SPT_BUFSIZE, fmt, ap); 236076b7bf71SPeter Wemm VA_END; 236176b7bf71SPeter Wemm 236276b7bf71SPeter Wemm if (status) 236376b7bf71SPeter Wemm proc_list_set(getpid(), buf); 236476b7bf71SPeter Wemm setproctitle("%s", buf); 236576b7bf71SPeter Wemm } 236676b7bf71SPeter Wemm /* 2367c2aa98e2SPeter Wemm ** WAITFOR -- wait for a particular process id. 2368c2aa98e2SPeter Wemm ** 2369c2aa98e2SPeter Wemm ** Parameters: 2370c2aa98e2SPeter Wemm ** pid -- process id to wait for. 2371c2aa98e2SPeter Wemm ** 2372c2aa98e2SPeter Wemm ** Returns: 2373c2aa98e2SPeter Wemm ** status of pid. 2374c2aa98e2SPeter Wemm ** -1 if pid never shows up. 2375c2aa98e2SPeter Wemm ** 2376c2aa98e2SPeter Wemm ** Side Effects: 2377c2aa98e2SPeter Wemm ** none. 2378c2aa98e2SPeter Wemm */ 2379c2aa98e2SPeter Wemm 2380c2aa98e2SPeter Wemm int 2381c2aa98e2SPeter Wemm waitfor(pid) 2382c2aa98e2SPeter Wemm pid_t pid; 2383c2aa98e2SPeter Wemm { 2384c2aa98e2SPeter Wemm #ifdef WAITUNION 2385c2aa98e2SPeter Wemm union wait st; 2386c2aa98e2SPeter Wemm #else 2387c2aa98e2SPeter Wemm auto int st; 2388c2aa98e2SPeter Wemm #endif 2389c2aa98e2SPeter Wemm pid_t i; 2390c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_) 2391c2aa98e2SPeter Wemm int savesig; 2392c2aa98e2SPeter Wemm #endif 2393c2aa98e2SPeter Wemm 2394c2aa98e2SPeter Wemm do 2395c2aa98e2SPeter Wemm { 2396c2aa98e2SPeter Wemm errno = 0; 2397c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_) 2398c2aa98e2SPeter Wemm savesig = releasesignal(SIGCHLD); 2399c2aa98e2SPeter Wemm #endif 2400c2aa98e2SPeter Wemm i = wait(&st); 2401c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_) 2402c2aa98e2SPeter Wemm if (savesig > 0) 2403c2aa98e2SPeter Wemm blocksignal(SIGCHLD); 2404c2aa98e2SPeter Wemm #endif 2405c2aa98e2SPeter Wemm if (i > 0) 2406c2aa98e2SPeter Wemm proc_list_drop(i); 2407c2aa98e2SPeter Wemm } while ((i >= 0 || errno == EINTR) && i != pid); 2408c2aa98e2SPeter Wemm if (i < 0) 2409c2aa98e2SPeter Wemm return -1; 2410c2aa98e2SPeter Wemm #ifdef WAITUNION 2411c2aa98e2SPeter Wemm return st.w_status; 2412c2aa98e2SPeter Wemm #else 2413c2aa98e2SPeter Wemm return st; 2414c2aa98e2SPeter Wemm #endif 2415c2aa98e2SPeter Wemm } 2416c2aa98e2SPeter Wemm /* 2417c2aa98e2SPeter Wemm ** REAPCHILD -- pick up the body of my child, lest it become a zombie 2418c2aa98e2SPeter Wemm ** 2419c2aa98e2SPeter Wemm ** Parameters: 2420c2aa98e2SPeter Wemm ** sig -- the signal that got us here (unused). 2421c2aa98e2SPeter Wemm ** 2422c2aa98e2SPeter Wemm ** Returns: 2423c2aa98e2SPeter Wemm ** none. 2424c2aa98e2SPeter Wemm ** 2425c2aa98e2SPeter Wemm ** Side Effects: 2426c2aa98e2SPeter Wemm ** Picks up extant zombies. 2427c2aa98e2SPeter Wemm */ 2428c2aa98e2SPeter Wemm 2429c2aa98e2SPeter Wemm SIGFUNC_DECL 2430c2aa98e2SPeter Wemm reapchild(sig) 2431c2aa98e2SPeter Wemm int sig; 2432c2aa98e2SPeter Wemm { 2433c2aa98e2SPeter Wemm int olderrno = errno; 2434c2aa98e2SPeter Wemm pid_t pid; 2435c2aa98e2SPeter Wemm # ifdef HASWAITPID 2436c2aa98e2SPeter Wemm auto int status; 2437c2aa98e2SPeter Wemm int count; 2438c2aa98e2SPeter Wemm 2439c2aa98e2SPeter Wemm count = 0; 2440c2aa98e2SPeter Wemm while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 2441c2aa98e2SPeter Wemm { 2442c2aa98e2SPeter Wemm if (count++ > 1000) 2443c2aa98e2SPeter Wemm { 2444c2aa98e2SPeter Wemm if (LogLevel > 0) 2445c2aa98e2SPeter Wemm sm_syslog(LOG_ALERT, NOQID, 2446c2aa98e2SPeter Wemm "reapchild: waitpid loop: pid=%d, status=%x", 2447c2aa98e2SPeter Wemm pid, status); 2448c2aa98e2SPeter Wemm break; 2449c2aa98e2SPeter Wemm } 2450c2aa98e2SPeter Wemm proc_list_drop(pid); 2451c2aa98e2SPeter Wemm } 2452c2aa98e2SPeter Wemm # else 2453c2aa98e2SPeter Wemm # ifdef WNOHANG 2454c2aa98e2SPeter Wemm union wait status; 2455c2aa98e2SPeter Wemm 2456c2aa98e2SPeter Wemm while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0) 2457c2aa98e2SPeter Wemm proc_list_drop(pid); 2458c2aa98e2SPeter Wemm # else /* WNOHANG */ 2459c2aa98e2SPeter Wemm auto int status; 2460c2aa98e2SPeter Wemm 2461c2aa98e2SPeter Wemm /* 2462c2aa98e2SPeter Wemm ** Catch one zombie -- we will be re-invoked (we hope) if there 2463c2aa98e2SPeter Wemm ** are more. Unreliable signals probably break this, but this 2464c2aa98e2SPeter Wemm ** is the "old system" situation -- waitpid or wait3 are to be 2465c2aa98e2SPeter Wemm ** strongly preferred. 2466c2aa98e2SPeter Wemm */ 2467c2aa98e2SPeter Wemm 2468c2aa98e2SPeter Wemm if ((pid = wait(&status)) > 0) 2469c2aa98e2SPeter Wemm proc_list_drop(pid); 2470c2aa98e2SPeter Wemm # endif /* WNOHANG */ 2471c2aa98e2SPeter Wemm # endif 2472c2aa98e2SPeter Wemm # ifdef SYS5SIGNALS 2473c2aa98e2SPeter Wemm (void) setsignal(SIGCHLD, reapchild); 2474c2aa98e2SPeter Wemm # endif 2475c2aa98e2SPeter Wemm errno = olderrno; 2476c2aa98e2SPeter Wemm return SIGFUNC_RETURN; 2477c2aa98e2SPeter Wemm } 2478c2aa98e2SPeter Wemm /* 2479c2aa98e2SPeter Wemm ** PUTENV -- emulation of putenv() in terms of setenv() 2480c2aa98e2SPeter Wemm ** 2481c2aa98e2SPeter Wemm ** Not needed on Posix-compliant systems. 2482c2aa98e2SPeter Wemm ** This doesn't have full Posix semantics, but it's good enough 2483c2aa98e2SPeter Wemm ** for sendmail. 2484c2aa98e2SPeter Wemm ** 2485c2aa98e2SPeter Wemm ** Parameter: 2486c2aa98e2SPeter Wemm ** env -- the environment to put. 2487c2aa98e2SPeter Wemm ** 2488c2aa98e2SPeter Wemm ** Returns: 2489c2aa98e2SPeter Wemm ** none. 2490c2aa98e2SPeter Wemm */ 2491c2aa98e2SPeter Wemm 2492c2aa98e2SPeter Wemm #ifdef NEEDPUTENV 2493c2aa98e2SPeter Wemm 2494c2aa98e2SPeter Wemm # if NEEDPUTENV == 2 /* no setenv(3) call available */ 2495c2aa98e2SPeter Wemm 2496c2aa98e2SPeter Wemm int 2497c2aa98e2SPeter Wemm putenv(str) 2498c2aa98e2SPeter Wemm char *str; 2499c2aa98e2SPeter Wemm { 2500c2aa98e2SPeter Wemm char **current; 2501c2aa98e2SPeter Wemm int matchlen, envlen=0; 2502c2aa98e2SPeter Wemm char *tmp; 2503c2aa98e2SPeter Wemm char **newenv; 2504c2aa98e2SPeter Wemm static int first=1; 2505c2aa98e2SPeter Wemm extern char **environ; 2506c2aa98e2SPeter Wemm 2507c2aa98e2SPeter Wemm /* 2508c2aa98e2SPeter Wemm * find out how much of str to match when searching 2509c2aa98e2SPeter Wemm * for a string to replace. 2510c2aa98e2SPeter Wemm */ 2511c2aa98e2SPeter Wemm if ((tmp = strchr(str, '=')) == NULL || tmp == str) 2512c2aa98e2SPeter Wemm matchlen = strlen(str); 2513c2aa98e2SPeter Wemm else 2514c2aa98e2SPeter Wemm matchlen = (int) (tmp - str); 2515c2aa98e2SPeter Wemm ++matchlen; 2516c2aa98e2SPeter Wemm 2517c2aa98e2SPeter Wemm /* 2518c2aa98e2SPeter Wemm * Search for an existing string in the environment and find the 2519c2aa98e2SPeter Wemm * length of environ. If found, replace and exit. 2520c2aa98e2SPeter Wemm */ 2521c2aa98e2SPeter Wemm for (current=environ; *current; current++) { 2522c2aa98e2SPeter Wemm ++envlen; 2523c2aa98e2SPeter Wemm 2524c2aa98e2SPeter Wemm if (strncmp(str, *current, matchlen) == 0) { 2525c2aa98e2SPeter Wemm /* found it, now insert the new version */ 2526c2aa98e2SPeter Wemm *current = (char *)str; 2527c2aa98e2SPeter Wemm return(0); 2528c2aa98e2SPeter Wemm } 2529c2aa98e2SPeter Wemm } 2530c2aa98e2SPeter Wemm 2531c2aa98e2SPeter Wemm /* 2532c2aa98e2SPeter Wemm * There wasn't already a slot so add space for a new slot. 2533c2aa98e2SPeter Wemm * If this is our first time through, use malloc(), else realloc(). 2534c2aa98e2SPeter Wemm */ 2535c2aa98e2SPeter Wemm if (first) { 2536c2aa98e2SPeter Wemm newenv = (char **) malloc(sizeof(char *) * (envlen + 2)); 2537c2aa98e2SPeter Wemm if (newenv == NULL) 2538c2aa98e2SPeter Wemm return(-1); 2539c2aa98e2SPeter Wemm 2540c2aa98e2SPeter Wemm first=0; 2541c2aa98e2SPeter Wemm (void) memcpy(newenv, environ, sizeof(char *) * envlen); 2542c2aa98e2SPeter Wemm } else { 2543c2aa98e2SPeter Wemm newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2)); 2544c2aa98e2SPeter Wemm if (newenv == NULL) 2545c2aa98e2SPeter Wemm return(-1); 2546c2aa98e2SPeter Wemm } 2547c2aa98e2SPeter Wemm 2548c2aa98e2SPeter Wemm /* actually add in the new entry */ 2549c2aa98e2SPeter Wemm environ = newenv; 2550c2aa98e2SPeter Wemm environ[envlen] = (char *)str; 2551c2aa98e2SPeter Wemm environ[envlen+1] = NULL; 2552c2aa98e2SPeter Wemm 2553c2aa98e2SPeter Wemm return(0); 2554c2aa98e2SPeter Wemm } 2555c2aa98e2SPeter Wemm 2556c2aa98e2SPeter Wemm #else /* implement putenv() in terms of setenv() */ 2557c2aa98e2SPeter Wemm 2558c2aa98e2SPeter Wemm int 2559c2aa98e2SPeter Wemm putenv(env) 2560c2aa98e2SPeter Wemm char *env; 2561c2aa98e2SPeter Wemm { 2562c2aa98e2SPeter Wemm char *p; 2563c2aa98e2SPeter Wemm int l; 2564c2aa98e2SPeter Wemm char nbuf[100]; 2565c2aa98e2SPeter Wemm 2566c2aa98e2SPeter Wemm p = strchr(env, '='); 2567c2aa98e2SPeter Wemm if (p == NULL) 2568c2aa98e2SPeter Wemm return 0; 2569c2aa98e2SPeter Wemm l = p - env; 2570c2aa98e2SPeter Wemm if (l > sizeof nbuf - 1) 2571c2aa98e2SPeter Wemm l = sizeof nbuf - 1; 2572c2aa98e2SPeter Wemm bcopy(env, nbuf, l); 2573c2aa98e2SPeter Wemm nbuf[l] = '\0'; 2574c2aa98e2SPeter Wemm return setenv(nbuf, ++p, 1); 2575c2aa98e2SPeter Wemm } 2576c2aa98e2SPeter Wemm 2577c2aa98e2SPeter Wemm # endif 2578c2aa98e2SPeter Wemm #endif 2579c2aa98e2SPeter Wemm /* 2580c2aa98e2SPeter Wemm ** UNSETENV -- remove a variable from the environment 2581c2aa98e2SPeter Wemm ** 2582c2aa98e2SPeter Wemm ** Not needed on newer systems. 2583c2aa98e2SPeter Wemm ** 2584c2aa98e2SPeter Wemm ** Parameters: 2585c2aa98e2SPeter Wemm ** name -- the string name of the environment variable to be 2586c2aa98e2SPeter Wemm ** deleted from the current environment. 2587c2aa98e2SPeter Wemm ** 2588c2aa98e2SPeter Wemm ** Returns: 2589c2aa98e2SPeter Wemm ** none. 2590c2aa98e2SPeter Wemm ** 2591c2aa98e2SPeter Wemm ** Globals: 2592c2aa98e2SPeter Wemm ** environ -- a pointer to the current environment. 2593c2aa98e2SPeter Wemm ** 2594c2aa98e2SPeter Wemm ** Side Effects: 2595c2aa98e2SPeter Wemm ** Modifies environ. 2596c2aa98e2SPeter Wemm */ 2597c2aa98e2SPeter Wemm 2598c2aa98e2SPeter Wemm #ifndef HASUNSETENV 2599c2aa98e2SPeter Wemm 2600c2aa98e2SPeter Wemm void 2601c2aa98e2SPeter Wemm unsetenv(name) 2602c2aa98e2SPeter Wemm char *name; 2603c2aa98e2SPeter Wemm { 2604c2aa98e2SPeter Wemm extern char **environ; 2605c2aa98e2SPeter Wemm register char **pp; 2606c2aa98e2SPeter Wemm int len = strlen(name); 2607c2aa98e2SPeter Wemm 2608c2aa98e2SPeter Wemm for (pp = environ; *pp != NULL; pp++) 2609c2aa98e2SPeter Wemm { 2610c2aa98e2SPeter Wemm if (strncmp(name, *pp, len) == 0 && 2611c2aa98e2SPeter Wemm ((*pp)[len] == '=' || (*pp)[len] == '\0')) 2612c2aa98e2SPeter Wemm break; 2613c2aa98e2SPeter Wemm } 2614c2aa98e2SPeter Wemm 2615c2aa98e2SPeter Wemm for (; *pp != NULL; pp++) 2616c2aa98e2SPeter Wemm *pp = pp[1]; 2617c2aa98e2SPeter Wemm } 2618c2aa98e2SPeter Wemm 2619c2aa98e2SPeter Wemm #endif 2620c2aa98e2SPeter Wemm /* 2621c2aa98e2SPeter Wemm ** GETDTABLESIZE -- return number of file descriptors 2622c2aa98e2SPeter Wemm ** 2623c2aa98e2SPeter Wemm ** Only on non-BSD systems 2624c2aa98e2SPeter Wemm ** 2625c2aa98e2SPeter Wemm ** Parameters: 2626c2aa98e2SPeter Wemm ** none 2627c2aa98e2SPeter Wemm ** 2628c2aa98e2SPeter Wemm ** Returns: 2629c2aa98e2SPeter Wemm ** size of file descriptor table 2630c2aa98e2SPeter Wemm ** 2631c2aa98e2SPeter Wemm ** Side Effects: 2632c2aa98e2SPeter Wemm ** none 2633c2aa98e2SPeter Wemm */ 2634c2aa98e2SPeter Wemm 2635c2aa98e2SPeter Wemm #ifdef SOLARIS 2636c2aa98e2SPeter Wemm # include <sys/resource.h> 2637c2aa98e2SPeter Wemm #endif 2638c2aa98e2SPeter Wemm 2639c2aa98e2SPeter Wemm int 2640c2aa98e2SPeter Wemm getdtsize() 2641c2aa98e2SPeter Wemm { 2642c2aa98e2SPeter Wemm #ifdef RLIMIT_NOFILE 2643c2aa98e2SPeter Wemm struct rlimit rl; 2644c2aa98e2SPeter Wemm 2645c2aa98e2SPeter Wemm if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) 2646c2aa98e2SPeter Wemm return rl.rlim_cur; 2647c2aa98e2SPeter Wemm #endif 2648c2aa98e2SPeter Wemm 2649c2aa98e2SPeter Wemm # ifdef HASGETDTABLESIZE 2650c2aa98e2SPeter Wemm return getdtablesize(); 2651c2aa98e2SPeter Wemm # else 2652c2aa98e2SPeter Wemm # ifdef _SC_OPEN_MAX 2653c2aa98e2SPeter Wemm return sysconf(_SC_OPEN_MAX); 2654c2aa98e2SPeter Wemm # else 2655c2aa98e2SPeter Wemm return NOFILE; 2656c2aa98e2SPeter Wemm # endif 2657c2aa98e2SPeter Wemm # endif 2658c2aa98e2SPeter Wemm } 2659c2aa98e2SPeter Wemm /* 2660c2aa98e2SPeter Wemm ** UNAME -- get the UUCP name of this system. 2661c2aa98e2SPeter Wemm */ 2662c2aa98e2SPeter Wemm 2663c2aa98e2SPeter Wemm #ifndef HASUNAME 2664c2aa98e2SPeter Wemm 2665c2aa98e2SPeter Wemm int 2666c2aa98e2SPeter Wemm uname(name) 2667c2aa98e2SPeter Wemm struct utsname *name; 2668c2aa98e2SPeter Wemm { 2669c2aa98e2SPeter Wemm FILE *file; 2670c2aa98e2SPeter Wemm char *n; 2671c2aa98e2SPeter Wemm 2672c2aa98e2SPeter Wemm name->nodename[0] = '\0'; 2673c2aa98e2SPeter Wemm 2674c2aa98e2SPeter Wemm /* try /etc/whoami -- one line with the node name */ 2675c2aa98e2SPeter Wemm if ((file = fopen("/etc/whoami", "r")) != NULL) 2676c2aa98e2SPeter Wemm { 2677c2aa98e2SPeter Wemm (void) fgets(name->nodename, NODE_LENGTH + 1, file); 2678c2aa98e2SPeter Wemm (void) fclose(file); 2679c2aa98e2SPeter Wemm n = strchr(name->nodename, '\n'); 2680c2aa98e2SPeter Wemm if (n != NULL) 2681c2aa98e2SPeter Wemm *n = '\0'; 2682c2aa98e2SPeter Wemm if (name->nodename[0] != '\0') 2683c2aa98e2SPeter Wemm return (0); 2684c2aa98e2SPeter Wemm } 2685c2aa98e2SPeter Wemm 2686c2aa98e2SPeter Wemm /* try /usr/include/whoami.h -- has a #define somewhere */ 2687c2aa98e2SPeter Wemm if ((file = fopen("/usr/include/whoami.h", "r")) != NULL) 2688c2aa98e2SPeter Wemm { 2689c2aa98e2SPeter Wemm char buf[MAXLINE]; 2690c2aa98e2SPeter Wemm 2691c2aa98e2SPeter Wemm while (fgets(buf, MAXLINE, file) != NULL) 2692c2aa98e2SPeter Wemm if (sscanf(buf, "#define sysname \"%*[^\"]\"", 2693c2aa98e2SPeter Wemm NODE_LENGTH, name->nodename) > 0) 2694c2aa98e2SPeter Wemm break; 2695c2aa98e2SPeter Wemm (void) fclose(file); 2696c2aa98e2SPeter Wemm if (name->nodename[0] != '\0') 2697c2aa98e2SPeter Wemm return (0); 2698c2aa98e2SPeter Wemm } 2699c2aa98e2SPeter Wemm 2700c2aa98e2SPeter Wemm #ifdef TRUST_POPEN 2701c2aa98e2SPeter Wemm /* 2702c2aa98e2SPeter Wemm ** Popen is known to have security holes. 2703c2aa98e2SPeter Wemm */ 2704c2aa98e2SPeter Wemm 2705c2aa98e2SPeter Wemm /* try uuname -l to return local name */ 2706c2aa98e2SPeter Wemm if ((file = popen("uuname -l", "r")) != NULL) 2707c2aa98e2SPeter Wemm { 2708c2aa98e2SPeter Wemm (void) fgets(name, NODE_LENGTH + 1, file); 2709c2aa98e2SPeter Wemm (void) pclose(file); 2710c2aa98e2SPeter Wemm n = strchr(name, '\n'); 2711c2aa98e2SPeter Wemm if (n != NULL) 2712c2aa98e2SPeter Wemm *n = '\0'; 2713c2aa98e2SPeter Wemm if (name->nodename[0] != '\0') 2714c2aa98e2SPeter Wemm return (0); 2715c2aa98e2SPeter Wemm } 2716c2aa98e2SPeter Wemm #endif 2717c2aa98e2SPeter Wemm 2718c2aa98e2SPeter Wemm return (-1); 2719c2aa98e2SPeter Wemm } 2720c2aa98e2SPeter Wemm #endif /* HASUNAME */ 2721c2aa98e2SPeter Wemm /* 2722c2aa98e2SPeter Wemm ** INITGROUPS -- initialize groups 2723c2aa98e2SPeter Wemm ** 2724c2aa98e2SPeter Wemm ** Stub implementation for System V style systems 2725c2aa98e2SPeter Wemm */ 2726c2aa98e2SPeter Wemm 2727c2aa98e2SPeter Wemm #ifndef HASINITGROUPS 2728c2aa98e2SPeter Wemm 2729c2aa98e2SPeter Wemm initgroups(name, basegid) 2730c2aa98e2SPeter Wemm char *name; 2731c2aa98e2SPeter Wemm int basegid; 2732c2aa98e2SPeter Wemm { 2733c2aa98e2SPeter Wemm return 0; 2734c2aa98e2SPeter Wemm } 2735c2aa98e2SPeter Wemm 2736c2aa98e2SPeter Wemm #endif 2737c2aa98e2SPeter Wemm /* 2738c2aa98e2SPeter Wemm ** SETGROUPS -- set group list 2739c2aa98e2SPeter Wemm ** 2740c2aa98e2SPeter Wemm ** Stub implementation for systems that don't have group lists 2741c2aa98e2SPeter Wemm */ 2742c2aa98e2SPeter Wemm 2743c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX 2744c2aa98e2SPeter Wemm 2745c2aa98e2SPeter Wemm int 2746c2aa98e2SPeter Wemm setgroups(ngroups, grouplist) 2747c2aa98e2SPeter Wemm int ngroups; 2748c2aa98e2SPeter Wemm GIDSET_T grouplist[]; 2749c2aa98e2SPeter Wemm { 2750c2aa98e2SPeter Wemm return 0; 2751c2aa98e2SPeter Wemm } 2752c2aa98e2SPeter Wemm 2753c2aa98e2SPeter Wemm #endif 2754c2aa98e2SPeter Wemm /* 2755c2aa98e2SPeter Wemm ** SETSID -- set session id (for non-POSIX systems) 2756c2aa98e2SPeter Wemm */ 2757c2aa98e2SPeter Wemm 2758c2aa98e2SPeter Wemm #ifndef HASSETSID 2759c2aa98e2SPeter Wemm 2760c2aa98e2SPeter Wemm pid_t 2761c2aa98e2SPeter Wemm setsid __P ((void)) 2762c2aa98e2SPeter Wemm { 2763c2aa98e2SPeter Wemm #ifdef TIOCNOTTY 2764c2aa98e2SPeter Wemm int fd; 2765c2aa98e2SPeter Wemm 2766c2aa98e2SPeter Wemm fd = open("/dev/tty", O_RDWR, 0); 2767c2aa98e2SPeter Wemm if (fd >= 0) 2768c2aa98e2SPeter Wemm { 2769c2aa98e2SPeter Wemm (void) ioctl(fd, (int) TIOCNOTTY, (char *) 0); 2770c2aa98e2SPeter Wemm (void) close(fd); 2771c2aa98e2SPeter Wemm } 2772c2aa98e2SPeter Wemm #endif /* TIOCNOTTY */ 2773c2aa98e2SPeter Wemm # ifdef SYS5SETPGRP 2774c2aa98e2SPeter Wemm return setpgrp(); 2775c2aa98e2SPeter Wemm # else 2776c2aa98e2SPeter Wemm return setpgid(0, getpid()); 2777c2aa98e2SPeter Wemm # endif 2778c2aa98e2SPeter Wemm } 2779c2aa98e2SPeter Wemm 2780c2aa98e2SPeter Wemm #endif 2781c2aa98e2SPeter Wemm /* 2782c2aa98e2SPeter Wemm ** FSYNC -- dummy fsync 2783c2aa98e2SPeter Wemm */ 2784c2aa98e2SPeter Wemm 2785c2aa98e2SPeter Wemm #ifdef NEEDFSYNC 2786c2aa98e2SPeter Wemm 2787c2aa98e2SPeter Wemm fsync(fd) 2788c2aa98e2SPeter Wemm int fd; 2789c2aa98e2SPeter Wemm { 2790c2aa98e2SPeter Wemm # ifdef O_SYNC 2791c2aa98e2SPeter Wemm return fcntl(fd, F_SETFL, O_SYNC); 2792c2aa98e2SPeter Wemm # else 2793c2aa98e2SPeter Wemm /* nothing we can do */ 2794c2aa98e2SPeter Wemm return 0; 2795c2aa98e2SPeter Wemm # endif 2796c2aa98e2SPeter Wemm } 2797c2aa98e2SPeter Wemm 2798c2aa98e2SPeter Wemm #endif 2799c2aa98e2SPeter Wemm /* 2800c2aa98e2SPeter Wemm ** DGUX_INET_ADDR -- inet_addr for DG/UX 2801c2aa98e2SPeter Wemm ** 2802c2aa98e2SPeter Wemm ** Data General DG/UX version of inet_addr returns a struct in_addr 2803c2aa98e2SPeter Wemm ** instead of a long. This patches things. Only needed on versions 2804c2aa98e2SPeter Wemm ** prior to 5.4.3. 2805c2aa98e2SPeter Wemm */ 2806c2aa98e2SPeter Wemm 2807c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2 2808c2aa98e2SPeter Wemm 2809c2aa98e2SPeter Wemm #undef inet_addr 2810c2aa98e2SPeter Wemm 2811c2aa98e2SPeter Wemm long 2812c2aa98e2SPeter Wemm dgux_inet_addr(host) 2813c2aa98e2SPeter Wemm char *host; 2814c2aa98e2SPeter Wemm { 2815c2aa98e2SPeter Wemm struct in_addr haddr; 2816c2aa98e2SPeter Wemm 2817c2aa98e2SPeter Wemm haddr = inet_addr(host); 2818c2aa98e2SPeter Wemm return haddr.s_addr; 2819c2aa98e2SPeter Wemm } 2820c2aa98e2SPeter Wemm 2821c2aa98e2SPeter Wemm #endif 2822c2aa98e2SPeter Wemm /* 2823c2aa98e2SPeter Wemm ** GETOPT -- for old systems or systems with bogus implementations 2824c2aa98e2SPeter Wemm */ 2825c2aa98e2SPeter Wemm 2826c2aa98e2SPeter Wemm #ifdef NEEDGETOPT 2827c2aa98e2SPeter Wemm 2828c2aa98e2SPeter Wemm /* 2829c2aa98e2SPeter Wemm * Copyright (c) 1985 Regents of the University of California. 2830c2aa98e2SPeter Wemm * All rights reserved. The Berkeley software License Agreement 2831c2aa98e2SPeter Wemm * specifies the terms and conditions for redistribution. 2832c2aa98e2SPeter Wemm */ 2833c2aa98e2SPeter Wemm 2834c2aa98e2SPeter Wemm 2835c2aa98e2SPeter Wemm /* 2836c2aa98e2SPeter Wemm ** this version hacked to add `atend' flag to allow state machine 2837c2aa98e2SPeter Wemm ** to reset if invoked by the program to scan args for a 2nd time 2838c2aa98e2SPeter Wemm */ 2839c2aa98e2SPeter Wemm 2840c2aa98e2SPeter Wemm #if defined(LIBC_SCCS) && !defined(lint) 2841c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86"; 2842c2aa98e2SPeter Wemm #endif /* LIBC_SCCS and not lint */ 2843c2aa98e2SPeter Wemm 2844c2aa98e2SPeter Wemm #include <stdio.h> 2845c2aa98e2SPeter Wemm 2846c2aa98e2SPeter Wemm /* 2847c2aa98e2SPeter Wemm * get option letter from argument vector 2848c2aa98e2SPeter Wemm */ 2849c2aa98e2SPeter Wemm #ifdef _CONVEX_SOURCE 2850c2aa98e2SPeter Wemm extern int optind, opterr, optopt; 2851c2aa98e2SPeter Wemm extern char *optarg; 2852c2aa98e2SPeter Wemm #else 2853c2aa98e2SPeter Wemm int opterr = 1; /* if error message should be printed */ 2854c2aa98e2SPeter Wemm int optind = 1; /* index into parent argv vector */ 2855c2aa98e2SPeter Wemm int optopt = 0; /* character checked for validity */ 2856c2aa98e2SPeter Wemm char *optarg = NULL; /* argument associated with option */ 2857c2aa98e2SPeter Wemm #endif 2858c2aa98e2SPeter Wemm 2859c2aa98e2SPeter Wemm #define BADCH (int)'?' 2860c2aa98e2SPeter Wemm #define EMSG "" 2861c2aa98e2SPeter Wemm #define tell(s) if (opterr) {fputs(*nargv,stderr);fputs(s,stderr); \ 2862c2aa98e2SPeter Wemm fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);} 2863c2aa98e2SPeter Wemm 2864c2aa98e2SPeter Wemm int 2865c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr) 2866c2aa98e2SPeter Wemm int nargc; 2867c2aa98e2SPeter Wemm char *const *nargv; 2868c2aa98e2SPeter Wemm const char *ostr; 2869c2aa98e2SPeter Wemm { 2870c2aa98e2SPeter Wemm static char *place = EMSG; /* option letter processing */ 2871c2aa98e2SPeter Wemm static char atend = 0; 2872c2aa98e2SPeter Wemm register char *oli = NULL; /* option letter list index */ 2873c2aa98e2SPeter Wemm 2874c2aa98e2SPeter Wemm if (atend) { 2875c2aa98e2SPeter Wemm atend = 0; 2876c2aa98e2SPeter Wemm place = EMSG; 2877c2aa98e2SPeter Wemm } 2878c2aa98e2SPeter Wemm if(!*place) { /* update scanning pointer */ 2879c2aa98e2SPeter Wemm if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) { 2880c2aa98e2SPeter Wemm atend++; 2881c2aa98e2SPeter Wemm return -1; 2882c2aa98e2SPeter Wemm } 2883c2aa98e2SPeter Wemm if (*place == '-') { /* found "--" */ 2884c2aa98e2SPeter Wemm ++optind; 2885c2aa98e2SPeter Wemm atend++; 2886c2aa98e2SPeter Wemm return -1; 2887c2aa98e2SPeter Wemm } 2888c2aa98e2SPeter Wemm } /* option letter okay? */ 2889c2aa98e2SPeter Wemm if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) { 2890c2aa98e2SPeter Wemm if (!*place) ++optind; 2891c2aa98e2SPeter Wemm tell(": illegal option -- "); 2892c2aa98e2SPeter Wemm } 2893c2aa98e2SPeter Wemm if (oli && *++oli != ':') { /* don't need argument */ 2894c2aa98e2SPeter Wemm optarg = NULL; 2895c2aa98e2SPeter Wemm if (!*place) ++optind; 2896c2aa98e2SPeter Wemm } 2897c2aa98e2SPeter Wemm else { /* need an argument */ 2898c2aa98e2SPeter Wemm if (*place) optarg = place; /* no white space */ 2899c2aa98e2SPeter Wemm else if (nargc <= ++optind) { /* no arg */ 2900c2aa98e2SPeter Wemm place = EMSG; 2901c2aa98e2SPeter Wemm tell(": option requires an argument -- "); 2902c2aa98e2SPeter Wemm } 2903c2aa98e2SPeter Wemm else optarg = nargv[optind]; /* white space */ 2904c2aa98e2SPeter Wemm place = EMSG; 2905c2aa98e2SPeter Wemm ++optind; 2906c2aa98e2SPeter Wemm } 2907c2aa98e2SPeter Wemm return(optopt); /* dump back option letter */ 2908c2aa98e2SPeter Wemm } 2909c2aa98e2SPeter Wemm 2910c2aa98e2SPeter Wemm #endif 2911c2aa98e2SPeter Wemm /* 2912c2aa98e2SPeter Wemm ** VFPRINTF, VSPRINTF -- for old 4.3 BSD systems missing a real version 2913c2aa98e2SPeter Wemm */ 2914c2aa98e2SPeter Wemm 2915c2aa98e2SPeter Wemm #ifdef NEEDVPRINTF 2916c2aa98e2SPeter Wemm 2917c2aa98e2SPeter Wemm #define MAXARG 16 2918c2aa98e2SPeter Wemm 2919c2aa98e2SPeter Wemm vfprintf(fp, fmt, ap) 2920c2aa98e2SPeter Wemm FILE *fp; 2921c2aa98e2SPeter Wemm char *fmt; 2922c2aa98e2SPeter Wemm char **ap; 2923c2aa98e2SPeter Wemm { 2924c2aa98e2SPeter Wemm char *bp[MAXARG]; 2925c2aa98e2SPeter Wemm int i = 0; 2926c2aa98e2SPeter Wemm 2927c2aa98e2SPeter Wemm while (*ap && i < MAXARG) 2928c2aa98e2SPeter Wemm bp[i++] = *ap++; 2929c2aa98e2SPeter Wemm fprintf(fp, fmt, bp[0], bp[1], bp[2], bp[3], 2930c2aa98e2SPeter Wemm bp[4], bp[5], bp[6], bp[7], 2931c2aa98e2SPeter Wemm bp[8], bp[9], bp[10], bp[11], 2932c2aa98e2SPeter Wemm bp[12], bp[13], bp[14], bp[15]); 2933c2aa98e2SPeter Wemm } 2934c2aa98e2SPeter Wemm 2935c2aa98e2SPeter Wemm vsprintf(s, fmt, ap) 2936c2aa98e2SPeter Wemm char *s; 2937c2aa98e2SPeter Wemm char *fmt; 2938c2aa98e2SPeter Wemm char **ap; 2939c2aa98e2SPeter Wemm { 2940c2aa98e2SPeter Wemm char *bp[MAXARG]; 2941c2aa98e2SPeter Wemm int i = 0; 2942c2aa98e2SPeter Wemm 2943c2aa98e2SPeter Wemm while (*ap && i < MAXARG) 2944c2aa98e2SPeter Wemm bp[i++] = *ap++; 2945c2aa98e2SPeter Wemm sprintf(s, fmt, bp[0], bp[1], bp[2], bp[3], 2946c2aa98e2SPeter Wemm bp[4], bp[5], bp[6], bp[7], 2947c2aa98e2SPeter Wemm bp[8], bp[9], bp[10], bp[11], 2948c2aa98e2SPeter Wemm bp[12], bp[13], bp[14], bp[15]); 2949c2aa98e2SPeter Wemm } 2950c2aa98e2SPeter Wemm 2951c2aa98e2SPeter Wemm #endif 2952c2aa98e2SPeter Wemm /* 2953c2aa98e2SPeter Wemm ** USERSHELLOK -- tell if a user's shell is ok for unrestricted use 2954c2aa98e2SPeter Wemm ** 2955c2aa98e2SPeter Wemm ** Parameters: 2956c2aa98e2SPeter Wemm ** user -- the name of the user we are checking. 2957c2aa98e2SPeter Wemm ** shell -- the user's shell from /etc/passwd 2958c2aa98e2SPeter Wemm ** 2959c2aa98e2SPeter Wemm ** Returns: 2960c2aa98e2SPeter Wemm ** TRUE -- if it is ok to use this for unrestricted access. 2961c2aa98e2SPeter Wemm ** FALSE -- if the shell is restricted. 2962c2aa98e2SPeter Wemm */ 2963c2aa98e2SPeter Wemm 2964c2aa98e2SPeter Wemm #if !HASGETUSERSHELL 2965c2aa98e2SPeter Wemm 2966c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS 2967c2aa98e2SPeter Wemm # define _PATH_SHELLS "/etc/shells" 2968c2aa98e2SPeter Wemm # endif 2969c2aa98e2SPeter Wemm 2970c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4) 2971c2aa98e2SPeter Wemm # include <userconf.h> 2972c2aa98e2SPeter Wemm # if _AIX4 >= 40200 2973c2aa98e2SPeter Wemm # include <userpw.h> 2974c2aa98e2SPeter Wemm # endif 2975c2aa98e2SPeter Wemm # include <usersec.h> 2976c2aa98e2SPeter Wemm # endif 2977c2aa98e2SPeter Wemm 2978c2aa98e2SPeter Wemm char *DefaultUserShells[] = 2979c2aa98e2SPeter Wemm { 2980c2aa98e2SPeter Wemm "/bin/sh", /* standard shell */ 2981c2aa98e2SPeter Wemm "/usr/bin/sh", 2982c2aa98e2SPeter Wemm "/bin/csh", /* C shell */ 2983c2aa98e2SPeter Wemm "/usr/bin/csh", 2984c2aa98e2SPeter Wemm #ifdef __hpux 2985c2aa98e2SPeter Wemm # ifdef V4FS 2986c2aa98e2SPeter Wemm "/usr/bin/rsh", /* restricted Bourne shell */ 2987c2aa98e2SPeter Wemm "/usr/bin/ksh", /* Korn shell */ 2988c2aa98e2SPeter Wemm "/usr/bin/rksh", /* restricted Korn shell */ 2989c2aa98e2SPeter Wemm "/usr/bin/pam", 2990c2aa98e2SPeter Wemm "/usr/bin/keysh", /* key shell (extended Korn shell) */ 2991c2aa98e2SPeter Wemm "/usr/bin/posix/sh", 2992c2aa98e2SPeter Wemm # else 2993c2aa98e2SPeter Wemm "/bin/rsh", /* restricted Bourne shell */ 2994c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 2995c2aa98e2SPeter Wemm "/bin/rksh", /* restricted Korn shell */ 2996c2aa98e2SPeter Wemm "/bin/pam", 2997c2aa98e2SPeter Wemm "/usr/bin/keysh", /* key shell (extended Korn shell) */ 2998c2aa98e2SPeter Wemm "/bin/posix/sh", 2999c2aa98e2SPeter Wemm # endif 3000c2aa98e2SPeter Wemm #endif 3001c2aa98e2SPeter Wemm #if defined(_AIX3) || defined(_AIX4) 3002c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3003c2aa98e2SPeter Wemm "/usr/bin/ksh", 3004c2aa98e2SPeter Wemm "/bin/tsh", /* trusted shell */ 3005c2aa98e2SPeter Wemm "/usr/bin/tsh", 3006c2aa98e2SPeter Wemm "/bin/bsh", /* Bourne shell */ 3007c2aa98e2SPeter Wemm "/usr/bin/bsh", 3008c2aa98e2SPeter Wemm #endif 300976b7bf71SPeter Wemm #if defined(__svr4__) || defined(__svr5__) 3010c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3011c2aa98e2SPeter Wemm "/usr/bin/ksh", 3012c2aa98e2SPeter Wemm #endif 3013c2aa98e2SPeter Wemm #ifdef sgi 3014c2aa98e2SPeter Wemm "/sbin/sh", /* SGI's shells really live in /sbin */ 3015c2aa98e2SPeter Wemm "/sbin/csh", 3016c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3017c2aa98e2SPeter Wemm "/sbin/ksh", 3018c2aa98e2SPeter Wemm "/usr/bin/ksh", 3019c2aa98e2SPeter Wemm "/bin/tcsh", /* Extended csh */ 3020c2aa98e2SPeter Wemm "/usr/bin/tcsh", 3021c2aa98e2SPeter Wemm #endif 3022c2aa98e2SPeter Wemm NULL 3023c2aa98e2SPeter Wemm }; 3024c2aa98e2SPeter Wemm 3025c2aa98e2SPeter Wemm #endif 3026c2aa98e2SPeter Wemm 3027c2aa98e2SPeter Wemm #define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/" 3028c2aa98e2SPeter Wemm 3029c2aa98e2SPeter Wemm bool 3030c2aa98e2SPeter Wemm usershellok(user, shell) 3031c2aa98e2SPeter Wemm char *user; 3032c2aa98e2SPeter Wemm char *shell; 3033c2aa98e2SPeter Wemm { 3034c2aa98e2SPeter Wemm #if HASGETUSERSHELL 3035c2aa98e2SPeter Wemm register char *p; 3036c2aa98e2SPeter Wemm extern char *getusershell(); 3037c2aa98e2SPeter Wemm 3038c2aa98e2SPeter Wemm if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || 3039c2aa98e2SPeter Wemm ConfigLevel <= 1) 3040c2aa98e2SPeter Wemm return TRUE; 3041c2aa98e2SPeter Wemm 3042c2aa98e2SPeter Wemm setusershell(); 3043c2aa98e2SPeter Wemm while ((p = getusershell()) != NULL) 3044c2aa98e2SPeter Wemm if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0) 3045c2aa98e2SPeter Wemm break; 3046c2aa98e2SPeter Wemm endusershell(); 3047c2aa98e2SPeter Wemm return p != NULL; 3048c2aa98e2SPeter Wemm #else 3049c2aa98e2SPeter Wemm # if USEGETCONFATTR 3050c2aa98e2SPeter Wemm auto char *v; 3051c2aa98e2SPeter Wemm # endif 3052c2aa98e2SPeter Wemm register FILE *shellf; 3053c2aa98e2SPeter Wemm char buf[MAXLINE]; 3054c2aa98e2SPeter Wemm 3055c2aa98e2SPeter Wemm if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || 3056c2aa98e2SPeter Wemm ConfigLevel <= 1) 3057c2aa98e2SPeter Wemm return TRUE; 3058c2aa98e2SPeter Wemm 3059c2aa98e2SPeter Wemm # if USEGETCONFATTR 3060c2aa98e2SPeter Wemm /* 3061c2aa98e2SPeter Wemm ** Naturally IBM has a "better" idea..... 3062c2aa98e2SPeter Wemm ** 3063c2aa98e2SPeter Wemm ** What a crock. This interface isn't documented, it is 3064c2aa98e2SPeter Wemm ** considered part of the security library (-ls), and it 3065c2aa98e2SPeter Wemm ** only works if you are running as root (since the list 3066c2aa98e2SPeter Wemm ** of valid shells is obviously a source of great concern). 3067c2aa98e2SPeter Wemm ** I recommend that you do NOT define USEGETCONFATTR, 3068c2aa98e2SPeter Wemm ** especially since you are going to have to set up an 3069c2aa98e2SPeter Wemm ** /etc/shells anyhow to handle the cases where getconfattr 3070c2aa98e2SPeter Wemm ** fails. 3071c2aa98e2SPeter Wemm */ 3072c2aa98e2SPeter Wemm 3073c2aa98e2SPeter Wemm if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL) 3074c2aa98e2SPeter Wemm { 3075c2aa98e2SPeter Wemm while (*v != '\0') 3076c2aa98e2SPeter Wemm { 3077c2aa98e2SPeter Wemm if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0) 3078c2aa98e2SPeter Wemm return TRUE; 3079c2aa98e2SPeter Wemm v += strlen(v) + 1; 3080c2aa98e2SPeter Wemm } 3081c2aa98e2SPeter Wemm return FALSE; 3082c2aa98e2SPeter Wemm } 3083c2aa98e2SPeter Wemm # endif 3084c2aa98e2SPeter Wemm 3085c2aa98e2SPeter Wemm shellf = fopen(_PATH_SHELLS, "r"); 3086c2aa98e2SPeter Wemm if (shellf == NULL) 3087c2aa98e2SPeter Wemm { 3088c2aa98e2SPeter Wemm /* no /etc/shells; see if it is one of the std shells */ 3089c2aa98e2SPeter Wemm char **d; 3090c2aa98e2SPeter Wemm 3091c2aa98e2SPeter Wemm if (errno != ENOENT && LogLevel > 3) 3092c2aa98e2SPeter Wemm sm_syslog(LOG_ERR, NOQID, 3093c2aa98e2SPeter Wemm "usershellok: cannot open %s: %s", 3094c2aa98e2SPeter Wemm _PATH_SHELLS, errstring(errno)); 3095c2aa98e2SPeter Wemm 3096c2aa98e2SPeter Wemm for (d = DefaultUserShells; *d != NULL; d++) 3097c2aa98e2SPeter Wemm { 3098c2aa98e2SPeter Wemm if (strcmp(shell, *d) == 0) 3099c2aa98e2SPeter Wemm return TRUE; 3100c2aa98e2SPeter Wemm } 3101c2aa98e2SPeter Wemm return FALSE; 3102c2aa98e2SPeter Wemm } 3103c2aa98e2SPeter Wemm 3104c2aa98e2SPeter Wemm while (fgets(buf, sizeof buf, shellf) != NULL) 3105c2aa98e2SPeter Wemm { 3106c2aa98e2SPeter Wemm register char *p, *q; 3107c2aa98e2SPeter Wemm 3108c2aa98e2SPeter Wemm p = buf; 3109c2aa98e2SPeter Wemm while (*p != '\0' && *p != '#' && *p != '/') 3110c2aa98e2SPeter Wemm p++; 3111c2aa98e2SPeter Wemm if (*p == '#' || *p == '\0') 3112c2aa98e2SPeter Wemm continue; 3113c2aa98e2SPeter Wemm q = p; 3114c2aa98e2SPeter Wemm while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p))) 3115c2aa98e2SPeter Wemm p++; 3116c2aa98e2SPeter Wemm *p = '\0'; 3117c2aa98e2SPeter Wemm if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0) 3118c2aa98e2SPeter Wemm { 3119c2aa98e2SPeter Wemm fclose(shellf); 3120c2aa98e2SPeter Wemm return TRUE; 3121c2aa98e2SPeter Wemm } 3122c2aa98e2SPeter Wemm } 3123c2aa98e2SPeter Wemm fclose(shellf); 3124c2aa98e2SPeter Wemm return FALSE; 3125c2aa98e2SPeter Wemm #endif 3126c2aa98e2SPeter Wemm } 3127c2aa98e2SPeter Wemm /* 3128c2aa98e2SPeter Wemm ** FREEDISKSPACE -- see how much free space is on the queue filesystem 3129c2aa98e2SPeter Wemm ** 3130c2aa98e2SPeter Wemm ** Only implemented if you have statfs. 3131c2aa98e2SPeter Wemm ** 3132c2aa98e2SPeter Wemm ** Parameters: 3133c2aa98e2SPeter Wemm ** dir -- the directory in question. 3134c2aa98e2SPeter Wemm ** bsize -- a variable into which the filesystem 3135c2aa98e2SPeter Wemm ** block size is stored. 3136c2aa98e2SPeter Wemm ** 3137c2aa98e2SPeter Wemm ** Returns: 3138c2aa98e2SPeter Wemm ** The number of bytes free on the queue filesystem. 3139c2aa98e2SPeter Wemm ** -1 if the statfs call fails. 3140c2aa98e2SPeter Wemm ** 3141c2aa98e2SPeter Wemm ** Side effects: 3142c2aa98e2SPeter Wemm ** Puts the filesystem block size into bsize. 3143c2aa98e2SPeter Wemm */ 3144c2aa98e2SPeter Wemm 3145c2aa98e2SPeter Wemm /* statfs types */ 3146c2aa98e2SPeter Wemm #define SFS_NONE 0 /* no statfs implementation */ 3147c2aa98e2SPeter Wemm #define SFS_USTAT 1 /* use ustat */ 3148c2aa98e2SPeter Wemm #define SFS_4ARGS 2 /* use four-argument statfs call */ 3149c2aa98e2SPeter Wemm #define SFS_VFS 3 /* use <sys/vfs.h> implementation */ 3150c2aa98e2SPeter Wemm #define SFS_MOUNT 4 /* use <sys/mount.h> implementation */ 3151c2aa98e2SPeter Wemm #define SFS_STATFS 5 /* use <sys/statfs.h> implementation */ 3152c2aa98e2SPeter Wemm #define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */ 3153c2aa98e2SPeter Wemm 3154c2aa98e2SPeter Wemm #ifndef SFS_TYPE 3155c2aa98e2SPeter Wemm # define SFS_TYPE SFS_NONE 3156c2aa98e2SPeter Wemm #endif 3157c2aa98e2SPeter Wemm 3158c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_USTAT 3159c2aa98e2SPeter Wemm # include <ustat.h> 3160c2aa98e2SPeter Wemm #endif 3161c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS 3162c2aa98e2SPeter Wemm # include <sys/statfs.h> 3163c2aa98e2SPeter Wemm #endif 3164c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_VFS 3165c2aa98e2SPeter Wemm # include <sys/vfs.h> 3166c2aa98e2SPeter Wemm #endif 3167c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_MOUNT 3168c2aa98e2SPeter Wemm # include <sys/mount.h> 3169c2aa98e2SPeter Wemm #endif 3170c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_STATVFS 3171c2aa98e2SPeter Wemm # include <sys/statvfs.h> 3172c2aa98e2SPeter Wemm #endif 3173c2aa98e2SPeter Wemm 3174c2aa98e2SPeter Wemm long 3175c2aa98e2SPeter Wemm freediskspace(dir, bsize) 3176c2aa98e2SPeter Wemm char *dir; 3177c2aa98e2SPeter Wemm long *bsize; 3178c2aa98e2SPeter Wemm { 3179c2aa98e2SPeter Wemm #if SFS_TYPE != SFS_NONE 3180c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT 3181c2aa98e2SPeter Wemm struct ustat fs; 3182c2aa98e2SPeter Wemm struct stat statbuf; 3183c2aa98e2SPeter Wemm # define FSBLOCKSIZE DEV_BSIZE 3184c2aa98e2SPeter Wemm # define SFS_BAVAIL f_tfree 3185c2aa98e2SPeter Wemm # else 3186c2aa98e2SPeter Wemm # if defined(ultrix) 3187c2aa98e2SPeter Wemm struct fs_data fs; 3188c2aa98e2SPeter Wemm # define SFS_BAVAIL fd_bfreen 3189c2aa98e2SPeter Wemm # define FSBLOCKSIZE 1024L 3190c2aa98e2SPeter Wemm # else 3191c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS 3192c2aa98e2SPeter Wemm struct statvfs fs; 3193c2aa98e2SPeter Wemm # define FSBLOCKSIZE fs.f_frsize 3194c2aa98e2SPeter Wemm # else 3195c2aa98e2SPeter Wemm struct statfs fs; 3196c2aa98e2SPeter Wemm # define FSBLOCKSIZE fs.f_bsize 3197c2aa98e2SPeter Wemm # endif 3198c2aa98e2SPeter Wemm # endif 3199c2aa98e2SPeter Wemm # endif 3200c2aa98e2SPeter Wemm # ifndef SFS_BAVAIL 3201c2aa98e2SPeter Wemm # define SFS_BAVAIL f_bavail 3202c2aa98e2SPeter Wemm # endif 3203c2aa98e2SPeter Wemm 3204c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT 3205c2aa98e2SPeter Wemm if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0) 3206c2aa98e2SPeter Wemm # else 3207c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_4ARGS 3208c2aa98e2SPeter Wemm if (statfs(dir, &fs, sizeof fs, 0) == 0) 3209c2aa98e2SPeter Wemm # else 3210c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS 3211c2aa98e2SPeter Wemm if (statvfs(dir, &fs) == 0) 3212c2aa98e2SPeter Wemm # else 3213c2aa98e2SPeter Wemm # if defined(ultrix) 3214c2aa98e2SPeter Wemm if (statfs(dir, &fs) > 0) 3215c2aa98e2SPeter Wemm # else 3216c2aa98e2SPeter Wemm if (statfs(dir, &fs) == 0) 3217c2aa98e2SPeter Wemm # endif 3218c2aa98e2SPeter Wemm # endif 3219c2aa98e2SPeter Wemm # endif 3220c2aa98e2SPeter Wemm # endif 3221c2aa98e2SPeter Wemm { 3222c2aa98e2SPeter Wemm if (bsize != NULL) 3223c2aa98e2SPeter Wemm *bsize = FSBLOCKSIZE; 3224c2aa98e2SPeter Wemm if (fs.SFS_BAVAIL <= 0) 3225c2aa98e2SPeter Wemm return 0; 3226c2aa98e2SPeter Wemm else if (fs.SFS_BAVAIL > LONG_MAX) 3227c2aa98e2SPeter Wemm return LONG_MAX; 3228c2aa98e2SPeter Wemm else 3229c2aa98e2SPeter Wemm return (long) fs.SFS_BAVAIL; 3230c2aa98e2SPeter Wemm } 3231c2aa98e2SPeter Wemm #endif 3232c2aa98e2SPeter Wemm return (-1); 3233c2aa98e2SPeter Wemm } 3234c2aa98e2SPeter Wemm /* 3235c2aa98e2SPeter Wemm ** ENOUGHDISKSPACE -- is there enough free space on the queue fs? 3236c2aa98e2SPeter Wemm ** 3237c2aa98e2SPeter Wemm ** Only implemented if you have statfs. 3238c2aa98e2SPeter Wemm ** 3239c2aa98e2SPeter Wemm ** Parameters: 3240c2aa98e2SPeter Wemm ** msize -- the size to check against. If zero, we don't yet 3241c2aa98e2SPeter Wemm ** know how big the message will be, so just check for 3242c2aa98e2SPeter Wemm ** a "reasonable" amount. 3243c2aa98e2SPeter Wemm ** 3244c2aa98e2SPeter Wemm ** Returns: 3245c2aa98e2SPeter Wemm ** TRUE if there is enough space. 3246c2aa98e2SPeter Wemm ** FALSE otherwise. 3247c2aa98e2SPeter Wemm */ 3248c2aa98e2SPeter Wemm 3249c2aa98e2SPeter Wemm bool 3250c2aa98e2SPeter Wemm enoughdiskspace(msize) 3251c2aa98e2SPeter Wemm long msize; 3252c2aa98e2SPeter Wemm { 3253c2aa98e2SPeter Wemm long bfree, bsize; 3254c2aa98e2SPeter Wemm 3255c2aa98e2SPeter Wemm if (MinBlocksFree <= 0 && msize <= 0) 3256c2aa98e2SPeter Wemm { 3257c2aa98e2SPeter Wemm if (tTd(4, 80)) 3258c2aa98e2SPeter Wemm printf("enoughdiskspace: no threshold\n"); 3259c2aa98e2SPeter Wemm return TRUE; 3260c2aa98e2SPeter Wemm } 3261c2aa98e2SPeter Wemm 3262c2aa98e2SPeter Wemm if ((bfree = freediskspace(QueueDir, &bsize)) >= 0) 3263c2aa98e2SPeter Wemm { 3264c2aa98e2SPeter Wemm if (tTd(4, 80)) 3265c2aa98e2SPeter Wemm printf("enoughdiskspace: bavail=%ld, need=%ld\n", 3266c2aa98e2SPeter Wemm bfree, msize); 3267c2aa98e2SPeter Wemm 3268c2aa98e2SPeter Wemm /* convert msize to block count */ 3269c2aa98e2SPeter Wemm msize = msize / bsize + 1; 3270c2aa98e2SPeter Wemm if (MinBlocksFree >= 0) 3271c2aa98e2SPeter Wemm msize += MinBlocksFree; 3272c2aa98e2SPeter Wemm 3273c2aa98e2SPeter Wemm if (bfree < msize) 3274c2aa98e2SPeter Wemm { 3275c2aa98e2SPeter Wemm if (LogLevel > 0) 3276c2aa98e2SPeter Wemm sm_syslog(LOG_ALERT, CurEnv->e_id, 3277c2aa98e2SPeter Wemm "low on space (have %ld, %s needs %ld in %s)", 3278c2aa98e2SPeter Wemm bfree, 3279c2aa98e2SPeter Wemm CurHostName == NULL ? "SMTP-DAEMON" : CurHostName, 3280c2aa98e2SPeter Wemm msize, QueueDir); 3281c2aa98e2SPeter Wemm return FALSE; 3282c2aa98e2SPeter Wemm } 3283c2aa98e2SPeter Wemm } 3284c2aa98e2SPeter Wemm else if (tTd(4, 80)) 3285c2aa98e2SPeter Wemm printf("enoughdiskspace failure: min=%ld, need=%ld: %s\n", 3286c2aa98e2SPeter Wemm MinBlocksFree, msize, errstring(errno)); 3287c2aa98e2SPeter Wemm return TRUE; 3288c2aa98e2SPeter Wemm } 3289c2aa98e2SPeter Wemm /* 3290c2aa98e2SPeter Wemm ** TRANSIENTERROR -- tell if an error code indicates a transient failure 3291c2aa98e2SPeter Wemm ** 3292c2aa98e2SPeter Wemm ** This looks at an errno value and tells if this is likely to 3293c2aa98e2SPeter Wemm ** go away if retried later. 3294c2aa98e2SPeter Wemm ** 3295c2aa98e2SPeter Wemm ** Parameters: 3296c2aa98e2SPeter Wemm ** err -- the errno code to classify. 3297c2aa98e2SPeter Wemm ** 3298c2aa98e2SPeter Wemm ** Returns: 3299c2aa98e2SPeter Wemm ** TRUE if this is probably transient. 3300c2aa98e2SPeter Wemm ** FALSE otherwise. 3301c2aa98e2SPeter Wemm */ 3302c2aa98e2SPeter Wemm 3303c2aa98e2SPeter Wemm bool 3304c2aa98e2SPeter Wemm transienterror(err) 3305c2aa98e2SPeter Wemm int err; 3306c2aa98e2SPeter Wemm { 3307c2aa98e2SPeter Wemm switch (err) 3308c2aa98e2SPeter Wemm { 3309c2aa98e2SPeter Wemm case EIO: /* I/O error */ 3310c2aa98e2SPeter Wemm case ENXIO: /* Device not configured */ 3311c2aa98e2SPeter Wemm case EAGAIN: /* Resource temporarily unavailable */ 3312c2aa98e2SPeter Wemm case ENOMEM: /* Cannot allocate memory */ 3313c2aa98e2SPeter Wemm case ENODEV: /* Operation not supported by device */ 3314c2aa98e2SPeter Wemm case ENFILE: /* Too many open files in system */ 3315c2aa98e2SPeter Wemm case EMFILE: /* Too many open files */ 3316c2aa98e2SPeter Wemm case ENOSPC: /* No space left on device */ 3317c2aa98e2SPeter Wemm #ifdef ETIMEDOUT 3318c2aa98e2SPeter Wemm case ETIMEDOUT: /* Connection timed out */ 3319c2aa98e2SPeter Wemm #endif 3320c2aa98e2SPeter Wemm #ifdef ESTALE 3321c2aa98e2SPeter Wemm case ESTALE: /* Stale NFS file handle */ 3322c2aa98e2SPeter Wemm #endif 3323c2aa98e2SPeter Wemm #ifdef ENETDOWN 3324c2aa98e2SPeter Wemm case ENETDOWN: /* Network is down */ 3325c2aa98e2SPeter Wemm #endif 3326c2aa98e2SPeter Wemm #ifdef ENETUNREACH 3327c2aa98e2SPeter Wemm case ENETUNREACH: /* Network is unreachable */ 3328c2aa98e2SPeter Wemm #endif 3329c2aa98e2SPeter Wemm #ifdef ENETRESET 3330c2aa98e2SPeter Wemm case ENETRESET: /* Network dropped connection on reset */ 3331c2aa98e2SPeter Wemm #endif 3332c2aa98e2SPeter Wemm #ifdef ECONNABORTED 3333c2aa98e2SPeter Wemm case ECONNABORTED: /* Software caused connection abort */ 3334c2aa98e2SPeter Wemm #endif 3335c2aa98e2SPeter Wemm #ifdef ECONNRESET 3336c2aa98e2SPeter Wemm case ECONNRESET: /* Connection reset by peer */ 3337c2aa98e2SPeter Wemm #endif 3338c2aa98e2SPeter Wemm #ifdef ENOBUFS 3339c2aa98e2SPeter Wemm case ENOBUFS: /* No buffer space available */ 3340c2aa98e2SPeter Wemm #endif 3341c2aa98e2SPeter Wemm #ifdef ESHUTDOWN 3342c2aa98e2SPeter Wemm case ESHUTDOWN: /* Can't send after socket shutdown */ 3343c2aa98e2SPeter Wemm #endif 3344c2aa98e2SPeter Wemm #ifdef ECONNREFUSED 3345c2aa98e2SPeter Wemm case ECONNREFUSED: /* Connection refused */ 3346c2aa98e2SPeter Wemm #endif 3347c2aa98e2SPeter Wemm #ifdef EHOSTDOWN 3348c2aa98e2SPeter Wemm case EHOSTDOWN: /* Host is down */ 3349c2aa98e2SPeter Wemm #endif 3350c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH 3351c2aa98e2SPeter Wemm case EHOSTUNREACH: /* No route to host */ 3352c2aa98e2SPeter Wemm #endif 3353c2aa98e2SPeter Wemm #ifdef EDQUOT 3354c2aa98e2SPeter Wemm case EDQUOT: /* Disc quota exceeded */ 3355c2aa98e2SPeter Wemm #endif 3356c2aa98e2SPeter Wemm #ifdef EPROCLIM 3357c2aa98e2SPeter Wemm case EPROCLIM: /* Too many processes */ 3358c2aa98e2SPeter Wemm #endif 3359c2aa98e2SPeter Wemm #ifdef EUSERS 3360c2aa98e2SPeter Wemm case EUSERS: /* Too many users */ 3361c2aa98e2SPeter Wemm #endif 3362c2aa98e2SPeter Wemm #ifdef EDEADLK 3363c2aa98e2SPeter Wemm case EDEADLK: /* Resource deadlock avoided */ 3364c2aa98e2SPeter Wemm #endif 3365c2aa98e2SPeter Wemm #ifdef EISCONN 3366c2aa98e2SPeter Wemm case EISCONN: /* Socket already connected */ 3367c2aa98e2SPeter Wemm #endif 3368c2aa98e2SPeter Wemm #ifdef EINPROGRESS 3369c2aa98e2SPeter Wemm case EINPROGRESS: /* Operation now in progress */ 3370c2aa98e2SPeter Wemm #endif 3371c2aa98e2SPeter Wemm #ifdef EALREADY 3372c2aa98e2SPeter Wemm case EALREADY: /* Operation already in progress */ 3373c2aa98e2SPeter Wemm #endif 3374c2aa98e2SPeter Wemm #ifdef EADDRINUSE 3375c2aa98e2SPeter Wemm case EADDRINUSE: /* Address already in use */ 3376c2aa98e2SPeter Wemm #endif 3377c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL 3378c2aa98e2SPeter Wemm case EADDRNOTAVAIL: /* Can't assign requested address */ 3379c2aa98e2SPeter Wemm #endif 3380c2aa98e2SPeter Wemm #ifdef ETXTBSY 3381c2aa98e2SPeter Wemm case ETXTBSY: /* (Apollo) file locked */ 3382c2aa98e2SPeter Wemm #endif 3383c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) 3384c2aa98e2SPeter Wemm case ENOSR: /* Out of streams resources */ 3385c2aa98e2SPeter Wemm #endif 3386c2aa98e2SPeter Wemm case E_SM_OPENTIMEOUT: /* PSEUDO: open timed out */ 3387c2aa98e2SPeter Wemm return TRUE; 3388c2aa98e2SPeter Wemm } 3389c2aa98e2SPeter Wemm 3390c2aa98e2SPeter Wemm /* nope, must be permanent */ 3391c2aa98e2SPeter Wemm return FALSE; 3392c2aa98e2SPeter Wemm } 3393c2aa98e2SPeter Wemm /* 3394c2aa98e2SPeter Wemm ** LOCKFILE -- lock a file using flock or (shudder) fcntl locking 3395c2aa98e2SPeter Wemm ** 3396c2aa98e2SPeter Wemm ** Parameters: 3397c2aa98e2SPeter Wemm ** fd -- the file descriptor of the file. 3398c2aa98e2SPeter Wemm ** filename -- the file name (for error messages). 3399c2aa98e2SPeter Wemm ** ext -- the filename extension. 3400c2aa98e2SPeter Wemm ** type -- type of the lock. Bits can be: 3401c2aa98e2SPeter Wemm ** LOCK_EX -- exclusive lock. 3402c2aa98e2SPeter Wemm ** LOCK_NB -- non-blocking. 3403c2aa98e2SPeter Wemm ** 3404c2aa98e2SPeter Wemm ** Returns: 3405c2aa98e2SPeter Wemm ** TRUE if the lock was acquired. 3406c2aa98e2SPeter Wemm ** FALSE otherwise. 3407c2aa98e2SPeter Wemm */ 3408c2aa98e2SPeter Wemm 3409c2aa98e2SPeter Wemm bool 3410c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type) 3411c2aa98e2SPeter Wemm int fd; 3412c2aa98e2SPeter Wemm char *filename; 3413c2aa98e2SPeter Wemm char *ext; 3414c2aa98e2SPeter Wemm int type; 3415c2aa98e2SPeter Wemm { 3416c2aa98e2SPeter Wemm int i; 3417c2aa98e2SPeter Wemm int save_errno; 3418c2aa98e2SPeter Wemm # if !HASFLOCK 3419c2aa98e2SPeter Wemm int action; 3420c2aa98e2SPeter Wemm struct flock lfd; 3421c2aa98e2SPeter Wemm 3422c2aa98e2SPeter Wemm if (ext == NULL) 3423c2aa98e2SPeter Wemm ext = ""; 3424c2aa98e2SPeter Wemm 3425c2aa98e2SPeter Wemm bzero(&lfd, sizeof lfd); 3426c2aa98e2SPeter Wemm if (bitset(LOCK_UN, type)) 3427c2aa98e2SPeter Wemm lfd.l_type = F_UNLCK; 3428c2aa98e2SPeter Wemm else if (bitset(LOCK_EX, type)) 3429c2aa98e2SPeter Wemm lfd.l_type = F_WRLCK; 3430c2aa98e2SPeter Wemm else 3431c2aa98e2SPeter Wemm lfd.l_type = F_RDLCK; 3432c2aa98e2SPeter Wemm 3433c2aa98e2SPeter Wemm if (bitset(LOCK_NB, type)) 3434c2aa98e2SPeter Wemm action = F_SETLK; 3435c2aa98e2SPeter Wemm else 3436c2aa98e2SPeter Wemm action = F_SETLKW; 3437c2aa98e2SPeter Wemm 3438c2aa98e2SPeter Wemm if (tTd(55, 60)) 3439c2aa98e2SPeter Wemm printf("lockfile(%s%s, action=%d, type=%d): ", 3440c2aa98e2SPeter Wemm filename, ext, action, lfd.l_type); 3441c2aa98e2SPeter Wemm 3442c2aa98e2SPeter Wemm while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR) 3443c2aa98e2SPeter Wemm continue; 3444c2aa98e2SPeter Wemm if (i >= 0) 3445c2aa98e2SPeter Wemm { 3446c2aa98e2SPeter Wemm if (tTd(55, 60)) 3447c2aa98e2SPeter Wemm printf("SUCCESS\n"); 3448c2aa98e2SPeter Wemm return TRUE; 3449c2aa98e2SPeter Wemm } 3450c2aa98e2SPeter Wemm save_errno = errno; 3451c2aa98e2SPeter Wemm 3452c2aa98e2SPeter Wemm if (tTd(55, 60)) 3453c2aa98e2SPeter Wemm printf("(%s) ", errstring(save_errno)); 3454c2aa98e2SPeter Wemm 3455c2aa98e2SPeter Wemm /* 3456c2aa98e2SPeter Wemm ** On SunOS, if you are testing using -oQ/tmp/mqueue or 3457c2aa98e2SPeter Wemm ** -oA/tmp/aliases or anything like that, and /tmp is mounted 3458c2aa98e2SPeter Wemm ** as type "tmp" (that is, served from swap space), the 3459c2aa98e2SPeter Wemm ** previous fcntl will fail with "Invalid argument" errors. 3460c2aa98e2SPeter Wemm ** Since this is fairly common during testing, we will assume 3461c2aa98e2SPeter Wemm ** that this indicates that the lock is successfully grabbed. 3462c2aa98e2SPeter Wemm */ 3463c2aa98e2SPeter Wemm 3464c2aa98e2SPeter Wemm if (save_errno == EINVAL) 3465c2aa98e2SPeter Wemm { 3466c2aa98e2SPeter Wemm if (tTd(55, 60)) 3467c2aa98e2SPeter Wemm printf("SUCCESS\n"); 3468c2aa98e2SPeter Wemm return TRUE; 3469c2aa98e2SPeter Wemm } 3470c2aa98e2SPeter Wemm 3471c2aa98e2SPeter Wemm if (!bitset(LOCK_NB, type) || (save_errno != EACCES && save_errno != EAGAIN)) 3472c2aa98e2SPeter Wemm { 3473c2aa98e2SPeter Wemm int omode = -1; 3474c2aa98e2SPeter Wemm # ifdef F_GETFL 3475c2aa98e2SPeter Wemm (void) fcntl(fd, F_GETFL, &omode); 3476c2aa98e2SPeter Wemm errno = save_errno; 3477c2aa98e2SPeter Wemm # endif 3478c2aa98e2SPeter Wemm syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", 3479c2aa98e2SPeter Wemm filename, ext, fd, type, omode, geteuid()); 3480c2aa98e2SPeter Wemm dumpfd(fd, TRUE, TRUE); 3481c2aa98e2SPeter Wemm } 3482c2aa98e2SPeter Wemm # else 3483c2aa98e2SPeter Wemm if (ext == NULL) 3484c2aa98e2SPeter Wemm ext = ""; 3485c2aa98e2SPeter Wemm 3486c2aa98e2SPeter Wemm if (tTd(55, 60)) 3487c2aa98e2SPeter Wemm printf("lockfile(%s%s, type=%o): ", filename, ext, type); 3488c2aa98e2SPeter Wemm 3489c2aa98e2SPeter Wemm while ((i = flock(fd, type)) < 0 && errno == EINTR) 3490c2aa98e2SPeter Wemm continue; 3491c2aa98e2SPeter Wemm if (i >= 0) 3492c2aa98e2SPeter Wemm { 3493c2aa98e2SPeter Wemm if (tTd(55, 60)) 3494c2aa98e2SPeter Wemm printf("SUCCESS\n"); 3495c2aa98e2SPeter Wemm return TRUE; 3496c2aa98e2SPeter Wemm } 3497c2aa98e2SPeter Wemm save_errno = errno; 3498c2aa98e2SPeter Wemm 3499c2aa98e2SPeter Wemm if (tTd(55, 60)) 3500c2aa98e2SPeter Wemm printf("(%s) ", errstring(save_errno)); 3501c2aa98e2SPeter Wemm 3502c2aa98e2SPeter Wemm if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK) 3503c2aa98e2SPeter Wemm { 3504c2aa98e2SPeter Wemm int omode = -1; 3505c2aa98e2SPeter Wemm # ifdef F_GETFL 3506c2aa98e2SPeter Wemm (void) fcntl(fd, F_GETFL, &omode); 3507c2aa98e2SPeter Wemm errno = save_errno; 3508c2aa98e2SPeter Wemm # endif 3509c2aa98e2SPeter Wemm syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", 3510c2aa98e2SPeter Wemm filename, ext, fd, type, omode, geteuid()); 3511c2aa98e2SPeter Wemm dumpfd(fd, TRUE, TRUE); 3512c2aa98e2SPeter Wemm } 3513c2aa98e2SPeter Wemm # endif 3514c2aa98e2SPeter Wemm if (tTd(55, 60)) 3515c2aa98e2SPeter Wemm printf("FAIL\n"); 3516c2aa98e2SPeter Wemm errno = save_errno; 3517c2aa98e2SPeter Wemm return FALSE; 3518c2aa98e2SPeter Wemm } 3519c2aa98e2SPeter Wemm /* 3520c2aa98e2SPeter Wemm ** CHOWNSAFE -- tell if chown is "safe" (executable only by root) 3521c2aa98e2SPeter Wemm ** 3522c2aa98e2SPeter Wemm ** Unfortunately, given that we can't predict other systems on which 3523c2aa98e2SPeter Wemm ** a remote mounted (NFS) filesystem will be mounted, the answer is 3524c2aa98e2SPeter Wemm ** almost always that this is unsafe. 3525c2aa98e2SPeter Wemm ** 3526c2aa98e2SPeter Wemm ** Note also that many operating systems have non-compliant 3527c2aa98e2SPeter Wemm ** implementations of the _POSIX_CHOWN_RESTRICTED variable and the 3528c2aa98e2SPeter Wemm ** fpathconf() routine. According to IEEE 1003.1-1990, if 3529c2aa98e2SPeter Wemm ** _POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then 3530c2aa98e2SPeter Wemm ** no non-root process can give away the file. However, vendors 3531c2aa98e2SPeter Wemm ** don't take NFS into account, so a comfortable value of 3532c2aa98e2SPeter Wemm ** _POSIX_CHOWN_RESTRICTED tells us nothing. 3533c2aa98e2SPeter Wemm ** 3534c2aa98e2SPeter Wemm ** Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf() 3535c2aa98e2SPeter Wemm ** even on files where chown is not restricted. Many systems get 3536c2aa98e2SPeter Wemm ** this wrong on NFS-based filesystems (that is, they say that chown 3537c2aa98e2SPeter Wemm ** is restricted [safe] on NFS filesystems where it may not be, since 3538c2aa98e2SPeter Wemm ** other systems can access the same filesystem and do file giveaway; 3539c2aa98e2SPeter Wemm ** only the NFS server knows for sure!) Hence, it is important to 3540c2aa98e2SPeter Wemm ** get the value of SAFENFSPATHCONF correct -- it should be defined 3541c2aa98e2SPeter Wemm ** _only_ after testing (see test/t_pathconf.c) a system on an unsafe 3542c2aa98e2SPeter Wemm ** NFS-based filesystem to ensure that you can get meaningful results. 3543c2aa98e2SPeter Wemm ** If in doubt, assume unsafe! 3544c2aa98e2SPeter Wemm ** 3545c2aa98e2SPeter Wemm ** You may also need to tweak IS_SAFE_CHOWN -- it should be a 3546c2aa98e2SPeter Wemm ** condition indicating whether the return from pathconf indicates 3547c2aa98e2SPeter Wemm ** that chown is safe (typically either > 0 or >= 0 -- there isn't 3548c2aa98e2SPeter Wemm ** even any agreement about whether a zero return means that a file 3549c2aa98e2SPeter Wemm ** is or is not safe). It defaults to "> 0". 3550c2aa98e2SPeter Wemm ** 3551c2aa98e2SPeter Wemm ** If the parent directory is safe (writable only by owner back 3552c2aa98e2SPeter Wemm ** to the root) then we can relax slightly and trust fpathconf 3553c2aa98e2SPeter Wemm ** in more circumstances. This is really a crock -- if this is an 3554c2aa98e2SPeter Wemm ** NFS mounted filesystem then we really know nothing about the 3555c2aa98e2SPeter Wemm ** underlying implementation. However, most systems pessimize and 3556c2aa98e2SPeter Wemm ** return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which 3557c2aa98e2SPeter Wemm ** we interpret as unsafe, as we should. Thus, this heuristic gets 3558c2aa98e2SPeter Wemm ** us into a possible problem only on systems that have a broken 3559c2aa98e2SPeter Wemm ** pathconf implementation and which are also poorly configured 3560c2aa98e2SPeter Wemm ** (have :include: files in group- or world-writable directories). 3561c2aa98e2SPeter Wemm ** 3562c2aa98e2SPeter Wemm ** Parameters: 3563c2aa98e2SPeter Wemm ** fd -- the file descriptor to check. 3564c2aa98e2SPeter Wemm ** safedir -- set if the parent directory is safe. 3565c2aa98e2SPeter Wemm ** 3566c2aa98e2SPeter Wemm ** Returns: 3567c2aa98e2SPeter Wemm ** TRUE -- if the chown(2) operation is "safe" -- that is, 3568c2aa98e2SPeter Wemm ** only root can chown the file to an arbitrary user. 3569c2aa98e2SPeter Wemm ** FALSE -- if an arbitrary user can give away a file. 3570c2aa98e2SPeter Wemm */ 3571c2aa98e2SPeter Wemm 3572c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN 3573c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN > 0 3574c2aa98e2SPeter Wemm #endif 3575c2aa98e2SPeter Wemm 3576c2aa98e2SPeter Wemm bool 3577c2aa98e2SPeter Wemm chownsafe(fd, safedir) 3578c2aa98e2SPeter Wemm int fd; 3579c2aa98e2SPeter Wemm bool safedir; 3580c2aa98e2SPeter Wemm { 3581c2aa98e2SPeter Wemm #if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ 3582c2aa98e2SPeter Wemm (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H)) 3583c2aa98e2SPeter Wemm int rval; 3584c2aa98e2SPeter Wemm 3585c2aa98e2SPeter Wemm /* give the system administrator a chance to override */ 3586c2aa98e2SPeter Wemm if (bitset(DBS_ASSUMESAFECHOWN, DontBlameSendmail)) 3587c2aa98e2SPeter Wemm return TRUE; 3588c2aa98e2SPeter Wemm 3589c2aa98e2SPeter Wemm /* 3590c2aa98e2SPeter Wemm ** Some systems (e.g., SunOS) seem to have the call and the 3591c2aa98e2SPeter Wemm ** #define _PC_CHOWN_RESTRICTED, but don't actually implement 3592c2aa98e2SPeter Wemm ** the call. This heuristic checks for that. 3593c2aa98e2SPeter Wemm */ 3594c2aa98e2SPeter Wemm 3595c2aa98e2SPeter Wemm errno = 0; 3596c2aa98e2SPeter Wemm rval = fpathconf(fd, _PC_CHOWN_RESTRICTED); 3597c2aa98e2SPeter Wemm # if SAFENFSPATHCONF 3598c2aa98e2SPeter Wemm return errno == 0 && rval IS_SAFE_CHOWN; 3599c2aa98e2SPeter Wemm # else 3600c2aa98e2SPeter Wemm return safedir && errno == 0 && rval IS_SAFE_CHOWN; 3601c2aa98e2SPeter Wemm # endif 3602c2aa98e2SPeter Wemm #else 3603c2aa98e2SPeter Wemm return bitset(DBS_ASSUMESAFECHOWN, DontBlameSendmail); 3604c2aa98e2SPeter Wemm #endif 3605c2aa98e2SPeter Wemm } 3606c2aa98e2SPeter Wemm /* 3607c2aa98e2SPeter Wemm ** RESETLIMITS -- reset system controlled resource limits 3608c2aa98e2SPeter Wemm ** 3609c2aa98e2SPeter Wemm ** This is to avoid denial-of-service attacks 3610c2aa98e2SPeter Wemm ** 3611c2aa98e2SPeter Wemm ** Parameters: 3612c2aa98e2SPeter Wemm ** none 3613c2aa98e2SPeter Wemm ** 3614c2aa98e2SPeter Wemm ** Returns: 3615c2aa98e2SPeter Wemm ** none 3616c2aa98e2SPeter Wemm */ 3617c2aa98e2SPeter Wemm 3618c2aa98e2SPeter Wemm #if HASSETRLIMIT 3619c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H 3620c2aa98e2SPeter Wemm # include <sys/time.h> 3621c2aa98e2SPeter Wemm # endif 3622c2aa98e2SPeter Wemm # include <sys/resource.h> 3623c2aa98e2SPeter Wemm #endif 3624c2aa98e2SPeter Wemm #ifndef FD_SETSIZE 3625c2aa98e2SPeter Wemm # define FD_SETSIZE 256 3626c2aa98e2SPeter Wemm #endif 3627c2aa98e2SPeter Wemm 3628c2aa98e2SPeter Wemm void 3629c2aa98e2SPeter Wemm resetlimits() 3630c2aa98e2SPeter Wemm { 3631c2aa98e2SPeter Wemm #if HASSETRLIMIT 3632c2aa98e2SPeter Wemm struct rlimit lim; 3633c2aa98e2SPeter Wemm 3634c2aa98e2SPeter Wemm lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; 3635c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_CPU, &lim); 3636c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_FSIZE, &lim); 3637c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE 3638c2aa98e2SPeter Wemm lim.rlim_cur = lim.rlim_max = FD_SETSIZE; 3639c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_NOFILE, &lim); 3640c2aa98e2SPeter Wemm # endif 3641c2aa98e2SPeter Wemm #else 3642c2aa98e2SPeter Wemm # if HASULIMIT 3643c2aa98e2SPeter Wemm (void) ulimit(2, 0x3fffff); 3644c2aa98e2SPeter Wemm (void) ulimit(4, FD_SETSIZE); 3645c2aa98e2SPeter Wemm # endif 3646c2aa98e2SPeter Wemm #endif 3647c2aa98e2SPeter Wemm errno = 0; 3648c2aa98e2SPeter Wemm } 3649c2aa98e2SPeter Wemm /* 3650c2aa98e2SPeter Wemm ** GETCFNAME -- return the name of the .cf file. 3651c2aa98e2SPeter Wemm ** 3652c2aa98e2SPeter Wemm ** Some systems (e.g., NeXT) determine this dynamically. 3653c2aa98e2SPeter Wemm */ 3654c2aa98e2SPeter Wemm 3655c2aa98e2SPeter Wemm char * 3656c2aa98e2SPeter Wemm getcfname() 3657c2aa98e2SPeter Wemm { 3658c2aa98e2SPeter Wemm 3659c2aa98e2SPeter Wemm if (ConfFile != NULL) 3660c2aa98e2SPeter Wemm return ConfFile; 3661c2aa98e2SPeter Wemm #if NETINFO 3662c2aa98e2SPeter Wemm { 3663c2aa98e2SPeter Wemm extern char *ni_propval __P((char *, char *, char *, char *, int)); 3664c2aa98e2SPeter Wemm char *cflocation; 3665c2aa98e2SPeter Wemm 3666c2aa98e2SPeter Wemm cflocation = ni_propval("/locations", NULL, "sendmail", 3667c2aa98e2SPeter Wemm "sendmail.cf", '\0'); 3668c2aa98e2SPeter Wemm if (cflocation != NULL) 3669c2aa98e2SPeter Wemm return cflocation; 3670c2aa98e2SPeter Wemm } 3671c2aa98e2SPeter Wemm #endif 3672c2aa98e2SPeter Wemm 3673c2aa98e2SPeter Wemm return _PATH_SENDMAILCF; 3674c2aa98e2SPeter Wemm } 3675c2aa98e2SPeter Wemm /* 3676c2aa98e2SPeter Wemm ** SETVENDOR -- process vendor code from V configuration line 3677c2aa98e2SPeter Wemm ** 3678c2aa98e2SPeter Wemm ** Parameters: 3679c2aa98e2SPeter Wemm ** vendor -- string representation of vendor. 3680c2aa98e2SPeter Wemm ** 3681c2aa98e2SPeter Wemm ** Returns: 3682c2aa98e2SPeter Wemm ** TRUE -- if ok. 3683c2aa98e2SPeter Wemm ** FALSE -- if vendor code could not be processed. 3684c2aa98e2SPeter Wemm ** 3685c2aa98e2SPeter Wemm ** Side Effects: 3686c2aa98e2SPeter Wemm ** It is reasonable to set mode flags here to tweak 3687c2aa98e2SPeter Wemm ** processing in other parts of the code if necessary. 3688c2aa98e2SPeter Wemm ** For example, if you are a vendor that uses $%y to 3689c2aa98e2SPeter Wemm ** indicate YP lookups, you could enable that here. 3690c2aa98e2SPeter Wemm */ 3691c2aa98e2SPeter Wemm 3692c2aa98e2SPeter Wemm bool 3693c2aa98e2SPeter Wemm setvendor(vendor) 3694c2aa98e2SPeter Wemm char *vendor; 3695c2aa98e2SPeter Wemm { 3696c2aa98e2SPeter Wemm if (strcasecmp(vendor, "Berkeley") == 0) 3697c2aa98e2SPeter Wemm { 3698c2aa98e2SPeter Wemm VendorCode = VENDOR_BERKELEY; 3699c2aa98e2SPeter Wemm return TRUE; 3700c2aa98e2SPeter Wemm } 3701c2aa98e2SPeter Wemm 3702c2aa98e2SPeter Wemm /* add vendor extensions here */ 3703c2aa98e2SPeter Wemm 3704c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS 3705c2aa98e2SPeter Wemm if (strcasecmp(vendor, "Sun") == 0) 3706c2aa98e2SPeter Wemm { 3707c2aa98e2SPeter Wemm VendorCode = VENDOR_SUN; 3708c2aa98e2SPeter Wemm return TRUE; 3709c2aa98e2SPeter Wemm } 3710c2aa98e2SPeter Wemm #endif 3711c2aa98e2SPeter Wemm 371276b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE) 371376b7bf71SPeter Wemm if (strcasecmp(vendor, VENDOR_NAME) == 0) 371476b7bf71SPeter Wemm { 371576b7bf71SPeter Wemm VendorCode = VENDOR_CODE; 371676b7bf71SPeter Wemm return TRUE; 371776b7bf71SPeter Wemm } 371876b7bf71SPeter Wemm #endif 371976b7bf71SPeter Wemm 3720c2aa98e2SPeter Wemm return FALSE; 3721c2aa98e2SPeter Wemm } 3722c2aa98e2SPeter Wemm /* 372376b7bf71SPeter Wemm ** GETVENDOR -- return vendor name based on vendor code 372476b7bf71SPeter Wemm ** 372576b7bf71SPeter Wemm ** Parameters: 372676b7bf71SPeter Wemm ** vendorcode -- numeric representation of vendor. 372776b7bf71SPeter Wemm ** 372876b7bf71SPeter Wemm ** Returns: 372976b7bf71SPeter Wemm ** string containing vendor name. 373076b7bf71SPeter Wemm */ 373176b7bf71SPeter Wemm 373276b7bf71SPeter Wemm char * 373376b7bf71SPeter Wemm getvendor(vendorcode) 373476b7bf71SPeter Wemm int vendorcode; 373576b7bf71SPeter Wemm { 373676b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE) 373776b7bf71SPeter Wemm /* 373876b7bf71SPeter Wemm ** Can't have the same switch case twice so need to 373976b7bf71SPeter Wemm ** handle VENDOR_CODE outside of switch. It might 374076b7bf71SPeter Wemm ** match one of the existing VENDOR_* codes. 374176b7bf71SPeter Wemm */ 374276b7bf71SPeter Wemm 374376b7bf71SPeter Wemm if (vendorcode == VENDOR_CODE) 374476b7bf71SPeter Wemm return VENDOR_NAME; 374576b7bf71SPeter Wemm #endif 374676b7bf71SPeter Wemm 374776b7bf71SPeter Wemm switch (vendorcode) 374876b7bf71SPeter Wemm { 374976b7bf71SPeter Wemm case VENDOR_BERKELEY: 375076b7bf71SPeter Wemm return "Berkeley"; 375176b7bf71SPeter Wemm 375276b7bf71SPeter Wemm case VENDOR_SUN: 375376b7bf71SPeter Wemm return "Sun"; 375476b7bf71SPeter Wemm 375576b7bf71SPeter Wemm case VENDOR_HP: 375676b7bf71SPeter Wemm return "HP"; 375776b7bf71SPeter Wemm 375876b7bf71SPeter Wemm case VENDOR_IBM: 375976b7bf71SPeter Wemm return "IBM"; 376076b7bf71SPeter Wemm 376176b7bf71SPeter Wemm case VENDOR_SENDMAIL: 376276b7bf71SPeter Wemm return "Sendmail"; 376376b7bf71SPeter Wemm 376476b7bf71SPeter Wemm default: 376576b7bf71SPeter Wemm return "Unknown"; 376676b7bf71SPeter Wemm } 376776b7bf71SPeter Wemm } 376876b7bf71SPeter Wemm /* 3769c2aa98e2SPeter Wemm ** VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults 3770c2aa98e2SPeter Wemm ** 3771c2aa98e2SPeter Wemm ** Vendor_pre_defaults is called before reading the configuration 3772c2aa98e2SPeter Wemm ** file; vendor_post_defaults is called immediately after. 3773c2aa98e2SPeter Wemm ** 3774c2aa98e2SPeter Wemm ** Parameters: 3775c2aa98e2SPeter Wemm ** e -- the global environment to initialize. 3776c2aa98e2SPeter Wemm ** 3777c2aa98e2SPeter Wemm ** Returns: 3778c2aa98e2SPeter Wemm ** none. 3779c2aa98e2SPeter Wemm */ 3780c2aa98e2SPeter Wemm 3781c2aa98e2SPeter Wemm #if SHARE_V1 3782c2aa98e2SPeter Wemm int DefShareUid; /* default share uid to run as -- unused??? */ 3783c2aa98e2SPeter Wemm #endif 3784c2aa98e2SPeter Wemm 3785c2aa98e2SPeter Wemm void 3786c2aa98e2SPeter Wemm vendor_pre_defaults(e) 3787c2aa98e2SPeter Wemm ENVELOPE *e; 3788c2aa98e2SPeter Wemm { 3789c2aa98e2SPeter Wemm #if SHARE_V1 3790c2aa98e2SPeter Wemm /* OTHERUID is defined in shares.h, do not be alarmed */ 3791c2aa98e2SPeter Wemm DefShareUid = OTHERUID; 3792c2aa98e2SPeter Wemm #endif 3793c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) 3794c2aa98e2SPeter Wemm sun_pre_defaults(e); 3795c2aa98e2SPeter Wemm #endif 3796c2aa98e2SPeter Wemm #ifdef apollo 3797c2aa98e2SPeter Wemm /* stupid domain/os can't even open /etc/sendmail.cf without this */ 3798c2aa98e2SPeter Wemm setuserenv("ISP", NULL); 3799c2aa98e2SPeter Wemm setuserenv("SYSTYPE", NULL); 3800c2aa98e2SPeter Wemm #endif 3801c2aa98e2SPeter Wemm } 3802c2aa98e2SPeter Wemm 3803c2aa98e2SPeter Wemm 3804c2aa98e2SPeter Wemm void 3805c2aa98e2SPeter Wemm vendor_post_defaults(e) 3806c2aa98e2SPeter Wemm ENVELOPE *e; 3807c2aa98e2SPeter Wemm { 3808c2aa98e2SPeter Wemm #ifdef __QNX__ 3809c2aa98e2SPeter Wemm char *p; 3810c2aa98e2SPeter Wemm 3811c2aa98e2SPeter Wemm /* Makes sure the SOCK environment variable remains */ 3812c2aa98e2SPeter Wemm if (p = getextenv("SOCK")) 3813c2aa98e2SPeter Wemm setuserenv("SOCK", p); 3814c2aa98e2SPeter Wemm #endif 3815c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) 3816c2aa98e2SPeter Wemm sun_post_defaults(e); 3817c2aa98e2SPeter Wemm #endif 3818c2aa98e2SPeter Wemm } 3819c2aa98e2SPeter Wemm /* 3820c2aa98e2SPeter Wemm ** VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode 3821c2aa98e2SPeter Wemm */ 3822c2aa98e2SPeter Wemm 3823c2aa98e2SPeter Wemm void 3824c2aa98e2SPeter Wemm vendor_daemon_setup(e) 3825c2aa98e2SPeter Wemm ENVELOPE *e; 3826c2aa98e2SPeter Wemm { 3827c2aa98e2SPeter Wemm #if SECUREWARE 3828c2aa98e2SPeter Wemm if (getluid() != -1) 3829c2aa98e2SPeter Wemm { 3830c2aa98e2SPeter Wemm usrerr("Daemon cannot have LUID"); 383176b7bf71SPeter Wemm finis(FALSE, EX_USAGE); 3832c2aa98e2SPeter Wemm } 3833c2aa98e2SPeter Wemm #endif /* SECUREWARE */ 3834c2aa98e2SPeter Wemm } 3835c2aa98e2SPeter Wemm /* 3836c2aa98e2SPeter Wemm ** VENDOR_SET_UID -- do setup for setting a user id 3837c2aa98e2SPeter Wemm ** 3838c2aa98e2SPeter Wemm ** This is called when we are still root. 3839c2aa98e2SPeter Wemm ** 3840c2aa98e2SPeter Wemm ** Parameters: 3841c2aa98e2SPeter Wemm ** uid -- the uid we are about to become. 3842c2aa98e2SPeter Wemm ** 3843c2aa98e2SPeter Wemm ** Returns: 3844c2aa98e2SPeter Wemm ** none. 3845c2aa98e2SPeter Wemm */ 3846c2aa98e2SPeter Wemm 3847c2aa98e2SPeter Wemm void 3848c2aa98e2SPeter Wemm vendor_set_uid(uid) 3849c2aa98e2SPeter Wemm UID_T uid; 3850c2aa98e2SPeter Wemm { 3851c2aa98e2SPeter Wemm /* 3852c2aa98e2SPeter Wemm ** We need to setup the share groups (lnodes) 3853c2aa98e2SPeter Wemm ** and and auditing inforation (luid's) 3854c2aa98e2SPeter Wemm ** before we loose our ``root''ness. 3855c2aa98e2SPeter Wemm */ 3856c2aa98e2SPeter Wemm #if SHARE_V1 3857c2aa98e2SPeter Wemm if (setupshares(uid, syserr) != 0) 3858c2aa98e2SPeter Wemm syserr("Unable to set up shares"); 3859c2aa98e2SPeter Wemm #endif 3860c2aa98e2SPeter Wemm #if SECUREWARE 3861c2aa98e2SPeter Wemm (void) setup_secure(uid); 3862c2aa98e2SPeter Wemm #endif 3863c2aa98e2SPeter Wemm } 3864c2aa98e2SPeter Wemm /* 3865c2aa98e2SPeter Wemm ** VALIDATE_CONNECTION -- check connection for rationality 3866c2aa98e2SPeter Wemm ** 3867c2aa98e2SPeter Wemm ** If the connection is rejected, this routine should log an 3868c2aa98e2SPeter Wemm ** appropriate message -- but should never issue any SMTP protocol. 3869c2aa98e2SPeter Wemm ** 3870c2aa98e2SPeter Wemm ** Parameters: 3871c2aa98e2SPeter Wemm ** sap -- a pointer to a SOCKADDR naming the peer. 3872c2aa98e2SPeter Wemm ** hostname -- the name corresponding to sap. 3873c2aa98e2SPeter Wemm ** e -- the current envelope. 3874c2aa98e2SPeter Wemm ** 3875c2aa98e2SPeter Wemm ** Returns: 3876c2aa98e2SPeter Wemm ** error message from rejection. 3877c2aa98e2SPeter Wemm ** NULL if not rejected. 3878c2aa98e2SPeter Wemm */ 3879c2aa98e2SPeter Wemm 3880c2aa98e2SPeter Wemm #if TCPWRAPPERS 3881c2aa98e2SPeter Wemm # include <tcpd.h> 3882c2aa98e2SPeter Wemm 3883c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */ 3884c2aa98e2SPeter Wemm int allow_severity = LOG_INFO; 3885c2aa98e2SPeter Wemm int deny_severity = LOG_NOTICE; 3886c2aa98e2SPeter Wemm #endif 3887c2aa98e2SPeter Wemm 3888c2aa98e2SPeter Wemm #if DAEMON 3889c2aa98e2SPeter Wemm char * 3890c2aa98e2SPeter Wemm validate_connection(sap, hostname, e) 3891c2aa98e2SPeter Wemm SOCKADDR *sap; 3892c2aa98e2SPeter Wemm char *hostname; 3893c2aa98e2SPeter Wemm ENVELOPE *e; 3894c2aa98e2SPeter Wemm { 3895c2aa98e2SPeter Wemm #if TCPWRAPPERS 3896c2aa98e2SPeter Wemm char *host; 3897c2aa98e2SPeter Wemm #endif 3898c2aa98e2SPeter Wemm 3899c2aa98e2SPeter Wemm if (tTd(48, 3)) 3900c2aa98e2SPeter Wemm printf("validate_connection(%s, %s)\n", 3901c2aa98e2SPeter Wemm hostname, anynet_ntoa(sap)); 3902c2aa98e2SPeter Wemm 3903c2aa98e2SPeter Wemm if (rscheck("check_relay", hostname, anynet_ntoa(sap), e) != EX_OK) 3904c2aa98e2SPeter Wemm { 3905c2aa98e2SPeter Wemm static char reject[BUFSIZ*2]; 3906c2aa98e2SPeter Wemm extern char MsgBuf[]; 3907c2aa98e2SPeter Wemm 3908c2aa98e2SPeter Wemm if (tTd(48, 4)) 3909c2aa98e2SPeter Wemm printf(" ... validate_connection: BAD (rscheck)\n"); 3910c2aa98e2SPeter Wemm 3911c2aa98e2SPeter Wemm if (strlen(MsgBuf) > 5) 3912c2aa98e2SPeter Wemm { 3913c2aa98e2SPeter Wemm if (isascii(MsgBuf[0]) && isdigit(MsgBuf[0]) && 3914c2aa98e2SPeter Wemm isascii(MsgBuf[1]) && isdigit(MsgBuf[1]) && 3915c2aa98e2SPeter Wemm isascii(MsgBuf[2]) && isdigit(MsgBuf[2])) 3916c2aa98e2SPeter Wemm strcpy(reject, &MsgBuf[4]); 3917c2aa98e2SPeter Wemm else 3918c2aa98e2SPeter Wemm strcpy(reject, MsgBuf); 3919c2aa98e2SPeter Wemm } 3920c2aa98e2SPeter Wemm else 3921c2aa98e2SPeter Wemm strcpy(reject, "Access denied"); 3922c2aa98e2SPeter Wemm 3923c2aa98e2SPeter Wemm return reject; 3924c2aa98e2SPeter Wemm } 3925c2aa98e2SPeter Wemm 3926c2aa98e2SPeter Wemm #if TCPWRAPPERS 3927c2aa98e2SPeter Wemm if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']') 3928c2aa98e2SPeter Wemm host = "unknown"; 3929c2aa98e2SPeter Wemm else 3930c2aa98e2SPeter Wemm host = hostname; 3931c2aa98e2SPeter Wemm if (!hosts_ctl("sendmail", host, anynet_ntoa(sap), STRING_UNKNOWN)) 3932c2aa98e2SPeter Wemm { 3933c2aa98e2SPeter Wemm if (tTd(48, 4)) 3934c2aa98e2SPeter Wemm printf(" ... validate_connection: BAD (tcpwrappers)\n"); 3935c2aa98e2SPeter Wemm if (LogLevel >= 4) 3936c2aa98e2SPeter Wemm sm_syslog(LOG_NOTICE, NOQID, 3937c2aa98e2SPeter Wemm "tcpwrappers (%s, %s) rejection", 3938c2aa98e2SPeter Wemm host, anynet_ntoa(sap)); 3939c2aa98e2SPeter Wemm return "Access denied"; 3940c2aa98e2SPeter Wemm } 3941c2aa98e2SPeter Wemm #endif 3942c2aa98e2SPeter Wemm if (tTd(48, 4)) 3943c2aa98e2SPeter Wemm printf(" ... validate_connection: OK\n"); 3944c2aa98e2SPeter Wemm return NULL; 3945c2aa98e2SPeter Wemm } 3946c2aa98e2SPeter Wemm 3947c2aa98e2SPeter Wemm #endif 3948c2aa98e2SPeter Wemm /* 3949c2aa98e2SPeter Wemm ** STRTOL -- convert string to long integer 3950c2aa98e2SPeter Wemm ** 3951c2aa98e2SPeter Wemm ** For systems that don't have it in the C library. 3952c2aa98e2SPeter Wemm ** 3953c2aa98e2SPeter Wemm ** This is taken verbatim from the 4.4-Lite C library. 3954c2aa98e2SPeter Wemm */ 3955c2aa98e2SPeter Wemm 3956c2aa98e2SPeter Wemm #ifdef NEEDSTRTOL 3957c2aa98e2SPeter Wemm 3958c2aa98e2SPeter Wemm #if defined(LIBC_SCCS) && !defined(lint) 3959c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; 3960c2aa98e2SPeter Wemm #endif /* LIBC_SCCS and not lint */ 3961c2aa98e2SPeter Wemm 3962c2aa98e2SPeter Wemm /* 3963c2aa98e2SPeter Wemm * Convert a string to a long integer. 3964c2aa98e2SPeter Wemm * 3965c2aa98e2SPeter Wemm * Ignores `locale' stuff. Assumes that the upper and lower case 3966c2aa98e2SPeter Wemm * alphabets and digits are each contiguous. 3967c2aa98e2SPeter Wemm */ 3968c2aa98e2SPeter Wemm 3969c2aa98e2SPeter Wemm long 3970c2aa98e2SPeter Wemm strtol(nptr, endptr, base) 3971c2aa98e2SPeter Wemm const char *nptr; 3972c2aa98e2SPeter Wemm char **endptr; 3973c2aa98e2SPeter Wemm register int base; 3974c2aa98e2SPeter Wemm { 3975c2aa98e2SPeter Wemm register const char *s = nptr; 3976c2aa98e2SPeter Wemm register unsigned long acc; 3977c2aa98e2SPeter Wemm register int c; 3978c2aa98e2SPeter Wemm register unsigned long cutoff; 3979c2aa98e2SPeter Wemm register int neg = 0, any, cutlim; 3980c2aa98e2SPeter Wemm 3981c2aa98e2SPeter Wemm /* 3982c2aa98e2SPeter Wemm * Skip white space and pick up leading +/- sign if any. 3983c2aa98e2SPeter Wemm * If base is 0, allow 0x for hex and 0 for octal, else 3984c2aa98e2SPeter Wemm * assume decimal; if base is already 16, allow 0x. 3985c2aa98e2SPeter Wemm */ 3986c2aa98e2SPeter Wemm do { 3987c2aa98e2SPeter Wemm c = *s++; 3988c2aa98e2SPeter Wemm } while (isspace(c)); 3989c2aa98e2SPeter Wemm if (c == '-') { 3990c2aa98e2SPeter Wemm neg = 1; 3991c2aa98e2SPeter Wemm c = *s++; 3992c2aa98e2SPeter Wemm } else if (c == '+') 3993c2aa98e2SPeter Wemm c = *s++; 3994c2aa98e2SPeter Wemm if ((base == 0 || base == 16) && 3995c2aa98e2SPeter Wemm c == '0' && (*s == 'x' || *s == 'X')) { 3996c2aa98e2SPeter Wemm c = s[1]; 3997c2aa98e2SPeter Wemm s += 2; 3998c2aa98e2SPeter Wemm base = 16; 3999c2aa98e2SPeter Wemm } 4000c2aa98e2SPeter Wemm if (base == 0) 4001c2aa98e2SPeter Wemm base = c == '0' ? 8 : 10; 4002c2aa98e2SPeter Wemm 4003c2aa98e2SPeter Wemm /* 4004c2aa98e2SPeter Wemm * Compute the cutoff value between legal numbers and illegal 4005c2aa98e2SPeter Wemm * numbers. That is the largest legal value, divided by the 4006c2aa98e2SPeter Wemm * base. An input number that is greater than this value, if 4007c2aa98e2SPeter Wemm * followed by a legal input character, is too big. One that 4008c2aa98e2SPeter Wemm * is equal to this value may be valid or not; the limit 4009c2aa98e2SPeter Wemm * between valid and invalid numbers is then based on the last 4010c2aa98e2SPeter Wemm * digit. For instance, if the range for longs is 4011c2aa98e2SPeter Wemm * [-2147483648..2147483647] and the input base is 10, 4012c2aa98e2SPeter Wemm * cutoff will be set to 214748364 and cutlim to either 4013c2aa98e2SPeter Wemm * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 4014c2aa98e2SPeter Wemm * a value > 214748364, or equal but the next digit is > 7 (or 8), 4015c2aa98e2SPeter Wemm * the number is too big, and we will return a range error. 4016c2aa98e2SPeter Wemm * 4017c2aa98e2SPeter Wemm * Set any if any `digits' consumed; make it negative to indicate 4018c2aa98e2SPeter Wemm * overflow. 4019c2aa98e2SPeter Wemm */ 4020c2aa98e2SPeter Wemm cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 4021c2aa98e2SPeter Wemm cutlim = cutoff % (unsigned long)base; 4022c2aa98e2SPeter Wemm cutoff /= (unsigned long)base; 4023c2aa98e2SPeter Wemm for (acc = 0, any = 0;; c = *s++) { 4024c2aa98e2SPeter Wemm if (isdigit(c)) 4025c2aa98e2SPeter Wemm c -= '0'; 4026c2aa98e2SPeter Wemm else if (isalpha(c)) 4027c2aa98e2SPeter Wemm c -= isupper(c) ? 'A' - 10 : 'a' - 10; 4028c2aa98e2SPeter Wemm else 4029c2aa98e2SPeter Wemm break; 4030c2aa98e2SPeter Wemm if (c >= base) 4031c2aa98e2SPeter Wemm break; 4032c2aa98e2SPeter Wemm if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 4033c2aa98e2SPeter Wemm any = -1; 4034c2aa98e2SPeter Wemm else { 4035c2aa98e2SPeter Wemm any = 1; 4036c2aa98e2SPeter Wemm acc *= base; 4037c2aa98e2SPeter Wemm acc += c; 4038c2aa98e2SPeter Wemm } 4039c2aa98e2SPeter Wemm } 4040c2aa98e2SPeter Wemm if (any < 0) { 4041c2aa98e2SPeter Wemm acc = neg ? LONG_MIN : LONG_MAX; 4042c2aa98e2SPeter Wemm errno = ERANGE; 4043c2aa98e2SPeter Wemm } else if (neg) 4044c2aa98e2SPeter Wemm acc = -acc; 4045c2aa98e2SPeter Wemm if (endptr != 0) 4046c2aa98e2SPeter Wemm *endptr = (char *)(any ? s - 1 : nptr); 4047c2aa98e2SPeter Wemm return (acc); 4048c2aa98e2SPeter Wemm } 4049c2aa98e2SPeter Wemm 4050c2aa98e2SPeter Wemm #endif 4051c2aa98e2SPeter Wemm /* 4052c2aa98e2SPeter Wemm ** STRSTR -- find first substring in string 4053c2aa98e2SPeter Wemm ** 4054c2aa98e2SPeter Wemm ** Parameters: 4055c2aa98e2SPeter Wemm ** big -- the big (full) string. 4056c2aa98e2SPeter Wemm ** little -- the little (sub) string. 4057c2aa98e2SPeter Wemm ** 4058c2aa98e2SPeter Wemm ** Returns: 4059c2aa98e2SPeter Wemm ** A pointer to the first instance of little in big. 4060c2aa98e2SPeter Wemm ** big if little is the null string. 4061c2aa98e2SPeter Wemm ** NULL if little is not contained in big. 4062c2aa98e2SPeter Wemm */ 4063c2aa98e2SPeter Wemm 4064c2aa98e2SPeter Wemm #ifdef NEEDSTRSTR 4065c2aa98e2SPeter Wemm 4066c2aa98e2SPeter Wemm char * 4067c2aa98e2SPeter Wemm strstr(big, little) 4068c2aa98e2SPeter Wemm char *big; 4069c2aa98e2SPeter Wemm char *little; 4070c2aa98e2SPeter Wemm { 4071c2aa98e2SPeter Wemm register char *p = big; 4072c2aa98e2SPeter Wemm int l; 4073c2aa98e2SPeter Wemm 4074c2aa98e2SPeter Wemm if (*little == '\0') 4075c2aa98e2SPeter Wemm return big; 4076c2aa98e2SPeter Wemm l = strlen(little); 4077c2aa98e2SPeter Wemm 4078c2aa98e2SPeter Wemm while ((p = strchr(p, *little)) != NULL) 4079c2aa98e2SPeter Wemm { 4080c2aa98e2SPeter Wemm if (strncmp(p, little, l) == 0) 4081c2aa98e2SPeter Wemm return p; 4082c2aa98e2SPeter Wemm p++; 4083c2aa98e2SPeter Wemm } 4084c2aa98e2SPeter Wemm return NULL; 4085c2aa98e2SPeter Wemm } 4086c2aa98e2SPeter Wemm 4087c2aa98e2SPeter Wemm #endif 4088c2aa98e2SPeter Wemm /* 4089c2aa98e2SPeter Wemm ** SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX 4090c2aa98e2SPeter Wemm ** 4091c2aa98e2SPeter Wemm ** Some operating systems have wierd problems with the gethostbyXXX 4092c2aa98e2SPeter Wemm ** routines. For example, Solaris versions at least through 2.3 4093c2aa98e2SPeter Wemm ** don't properly deliver a canonical h_name field. This tries to 4094c2aa98e2SPeter Wemm ** work around these problems. 4095c2aa98e2SPeter Wemm */ 4096c2aa98e2SPeter Wemm 4097c2aa98e2SPeter Wemm struct hostent * 4098c2aa98e2SPeter Wemm sm_gethostbyname(name) 4099c2aa98e2SPeter Wemm char *name; 4100c2aa98e2SPeter Wemm { 4101c2aa98e2SPeter Wemm struct hostent *h; 4102c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) 4103c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203 4104c2aa98e2SPeter Wemm static struct hostent hp; 4105c2aa98e2SPeter Wemm static char buf[1000]; 4106c2aa98e2SPeter Wemm extern struct hostent *_switch_gethostbyname_r(); 4107c2aa98e2SPeter Wemm 4108c2aa98e2SPeter Wemm if (tTd(61, 10)) 4109c2aa98e2SPeter Wemm printf("_switch_gethostbyname_r(%s)... ", name); 4110c2aa98e2SPeter Wemm h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); 4111c2aa98e2SPeter Wemm # else 4112c2aa98e2SPeter Wemm extern struct hostent *__switch_gethostbyname(); 4113c2aa98e2SPeter Wemm 4114c2aa98e2SPeter Wemm if (tTd(61, 10)) 4115c2aa98e2SPeter Wemm printf("__switch_gethostbyname(%s)... ", name); 4116c2aa98e2SPeter Wemm h = __switch_gethostbyname(name); 4117c2aa98e2SPeter Wemm # endif 4118c2aa98e2SPeter Wemm #else 4119c2aa98e2SPeter Wemm int nmaps; 4120c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 4121c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 4122c2aa98e2SPeter Wemm char hbuf[MAXNAME]; 4123c2aa98e2SPeter Wemm 4124c2aa98e2SPeter Wemm if (tTd(61, 10)) 4125c2aa98e2SPeter Wemm printf("gethostbyname(%s)... ", name); 4126c2aa98e2SPeter Wemm h = gethostbyname(name); 4127c2aa98e2SPeter Wemm if (h == NULL) 4128c2aa98e2SPeter Wemm { 4129c2aa98e2SPeter Wemm if (tTd(61, 10)) 4130c2aa98e2SPeter Wemm printf("failure\n"); 4131c2aa98e2SPeter Wemm 4132c2aa98e2SPeter Wemm nmaps = switch_map_find("hosts", maptype, mapreturn); 4133c2aa98e2SPeter Wemm while (--nmaps >= 0) 4134c2aa98e2SPeter Wemm if (strcmp(maptype[nmaps], "nis") == 0 || 4135c2aa98e2SPeter Wemm strcmp(maptype[nmaps], "files") == 0) 4136c2aa98e2SPeter Wemm break; 4137c2aa98e2SPeter Wemm if (nmaps >= 0) 4138c2aa98e2SPeter Wemm { 4139c2aa98e2SPeter Wemm /* try short name */ 4140c2aa98e2SPeter Wemm if (strlen(name) > (SIZE_T) sizeof hbuf - 1) 4141c2aa98e2SPeter Wemm return NULL; 4142c2aa98e2SPeter Wemm strcpy(hbuf, name); 4143c2aa98e2SPeter Wemm shorten_hostname(hbuf); 4144c2aa98e2SPeter Wemm 4145c2aa98e2SPeter Wemm /* if it hasn't been shortened, there's no point */ 4146c2aa98e2SPeter Wemm if (strcmp(hbuf, name) != 0) 4147c2aa98e2SPeter Wemm { 4148c2aa98e2SPeter Wemm if (tTd(61, 10)) 4149c2aa98e2SPeter Wemm printf("gethostbyname(%s)... ", hbuf); 4150c2aa98e2SPeter Wemm h = gethostbyname(hbuf); 4151c2aa98e2SPeter Wemm } 4152c2aa98e2SPeter Wemm } 4153c2aa98e2SPeter Wemm } 4154c2aa98e2SPeter Wemm #endif 4155c2aa98e2SPeter Wemm if (tTd(61, 10)) 4156c2aa98e2SPeter Wemm { 4157c2aa98e2SPeter Wemm if (h == NULL) 4158c2aa98e2SPeter Wemm printf("failure\n"); 4159c2aa98e2SPeter Wemm else 4160c2aa98e2SPeter Wemm printf("%s\n", h->h_name); 4161c2aa98e2SPeter Wemm } 4162c2aa98e2SPeter Wemm return h; 4163c2aa98e2SPeter Wemm } 4164c2aa98e2SPeter Wemm 4165c2aa98e2SPeter Wemm struct hostent * 4166c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type) 4167c2aa98e2SPeter Wemm char *addr; 4168c2aa98e2SPeter Wemm int len; 4169c2aa98e2SPeter Wemm int type; 4170c2aa98e2SPeter Wemm { 4171c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) 4172c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203 4173c2aa98e2SPeter Wemm static struct hostent hp; 4174c2aa98e2SPeter Wemm static char buf[1000]; 4175c2aa98e2SPeter Wemm extern struct hostent *_switch_gethostbyaddr_r(); 4176c2aa98e2SPeter Wemm 4177c2aa98e2SPeter Wemm return _switch_gethostbyaddr_r(addr, len, type, &hp, buf, sizeof(buf), &h_errno); 4178c2aa98e2SPeter Wemm # else 4179c2aa98e2SPeter Wemm extern struct hostent *__switch_gethostbyaddr(); 4180c2aa98e2SPeter Wemm 4181c2aa98e2SPeter Wemm return __switch_gethostbyaddr(addr, len, type); 4182c2aa98e2SPeter Wemm # endif 4183c2aa98e2SPeter Wemm #else 4184c2aa98e2SPeter Wemm return gethostbyaddr(addr, len, type); 4185c2aa98e2SPeter Wemm #endif 4186c2aa98e2SPeter Wemm } 4187c2aa98e2SPeter Wemm /* 4188c2aa98e2SPeter Wemm ** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid 4189c2aa98e2SPeter Wemm */ 4190c2aa98e2SPeter Wemm 4191c2aa98e2SPeter Wemm struct passwd * 4192c2aa98e2SPeter Wemm sm_getpwnam(user) 4193c2aa98e2SPeter Wemm char *user; 4194c2aa98e2SPeter Wemm { 4195c2aa98e2SPeter Wemm #ifdef _AIX4 4196c2aa98e2SPeter Wemm extern struct passwd *_getpwnam_shadow(const char *, const int); 4197c2aa98e2SPeter Wemm 4198c2aa98e2SPeter Wemm return _getpwnam_shadow(user, 0); 4199c2aa98e2SPeter Wemm #else 4200c2aa98e2SPeter Wemm return getpwnam(user); 4201c2aa98e2SPeter Wemm #endif 4202c2aa98e2SPeter Wemm } 4203c2aa98e2SPeter Wemm 4204c2aa98e2SPeter Wemm struct passwd * 4205c2aa98e2SPeter Wemm sm_getpwuid(uid) 4206c2aa98e2SPeter Wemm UID_T uid; 4207c2aa98e2SPeter Wemm { 4208c2aa98e2SPeter Wemm #if defined(_AIX4) && 0 4209c2aa98e2SPeter Wemm extern struct passwd *_getpwuid_shadow(const int, const int); 4210c2aa98e2SPeter Wemm 4211c2aa98e2SPeter Wemm return _getpwuid_shadow(uid,0); 4212c2aa98e2SPeter Wemm #else 4213c2aa98e2SPeter Wemm return getpwuid(uid); 4214c2aa98e2SPeter Wemm #endif 4215c2aa98e2SPeter Wemm } 4216c2aa98e2SPeter Wemm /* 4217c2aa98e2SPeter Wemm ** SECUREWARE_SETUP_SECURE -- Convex SecureWare setup 4218c2aa98e2SPeter Wemm ** 4219c2aa98e2SPeter Wemm ** Set up the trusted computing environment for C2 level security 4220c2aa98e2SPeter Wemm ** under SecureWare. 4221c2aa98e2SPeter Wemm ** 4222c2aa98e2SPeter Wemm ** Parameters: 4223c2aa98e2SPeter Wemm ** uid -- uid of the user to initialize in the TCB 4224c2aa98e2SPeter Wemm ** 4225c2aa98e2SPeter Wemm ** Returns: 4226c2aa98e2SPeter Wemm ** none 4227c2aa98e2SPeter Wemm ** 4228c2aa98e2SPeter Wemm ** Side Effects: 4229c2aa98e2SPeter Wemm ** Initialized the user in the trusted computing base 4230c2aa98e2SPeter Wemm */ 4231c2aa98e2SPeter Wemm 4232c2aa98e2SPeter Wemm #if SECUREWARE 4233c2aa98e2SPeter Wemm 4234c2aa98e2SPeter Wemm # include <sys/security.h> 4235c2aa98e2SPeter Wemm # include <prot.h> 4236c2aa98e2SPeter Wemm 4237c2aa98e2SPeter Wemm void 4238c2aa98e2SPeter Wemm secureware_setup_secure(uid) 4239c2aa98e2SPeter Wemm UID_T uid; 4240c2aa98e2SPeter Wemm { 4241c2aa98e2SPeter Wemm int rc; 4242c2aa98e2SPeter Wemm 4243c2aa98e2SPeter Wemm if (getluid() != -1) 4244c2aa98e2SPeter Wemm return; 4245c2aa98e2SPeter Wemm 4246c2aa98e2SPeter Wemm if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN) 4247c2aa98e2SPeter Wemm { 4248c2aa98e2SPeter Wemm switch (rc) 4249c2aa98e2SPeter Wemm { 4250c2aa98e2SPeter Wemm case SSI_NO_PRPW_ENTRY: 4251c2aa98e2SPeter Wemm syserr("No protected passwd entry, uid = %d", uid); 4252c2aa98e2SPeter Wemm break; 4253c2aa98e2SPeter Wemm 4254c2aa98e2SPeter Wemm case SSI_LOCKED: 4255c2aa98e2SPeter Wemm syserr("Account has been disabled, uid = %d", uid); 4256c2aa98e2SPeter Wemm break; 4257c2aa98e2SPeter Wemm 4258c2aa98e2SPeter Wemm case SSI_RETIRED: 4259c2aa98e2SPeter Wemm syserr("Account has been retired, uid = %d", uid); 4260c2aa98e2SPeter Wemm break; 4261c2aa98e2SPeter Wemm 4262c2aa98e2SPeter Wemm case SSI_BAD_SET_LUID: 4263c2aa98e2SPeter Wemm syserr("Could not set LUID, uid = %d", uid); 4264c2aa98e2SPeter Wemm break; 4265c2aa98e2SPeter Wemm 4266c2aa98e2SPeter Wemm case SSI_BAD_SET_PRIVS: 4267c2aa98e2SPeter Wemm syserr("Could not set kernel privs, uid = %d", uid); 4268c2aa98e2SPeter Wemm 4269c2aa98e2SPeter Wemm default: 4270c2aa98e2SPeter Wemm syserr("Unknown return code (%d) from set_secure_info(%d)", 4271c2aa98e2SPeter Wemm rc, uid); 4272c2aa98e2SPeter Wemm break; 4273c2aa98e2SPeter Wemm } 427476b7bf71SPeter Wemm finis(FALSE, EX_NOPERM); 4275c2aa98e2SPeter Wemm } 4276c2aa98e2SPeter Wemm } 4277c2aa98e2SPeter Wemm #endif /* SECUREWARE */ 4278c2aa98e2SPeter Wemm /* 427976b7bf71SPeter Wemm ** ADD_LOCAL_HOST_NAMES -- Add a hostname to class 'w' based on IP address 428076b7bf71SPeter Wemm ** 428176b7bf71SPeter Wemm ** Add hostnames to class 'w' based on the IP address read from 428276b7bf71SPeter Wemm ** the network interface. 428376b7bf71SPeter Wemm ** 428476b7bf71SPeter Wemm ** Parameters: 428576b7bf71SPeter Wemm ** sa -- a pointer to a SOCKADDR containing the address 428676b7bf71SPeter Wemm ** 428776b7bf71SPeter Wemm ** Returns: 428876b7bf71SPeter Wemm ** 0 if successful, -1 if host lookup fails. 428976b7bf71SPeter Wemm */ 429076b7bf71SPeter Wemm 429176b7bf71SPeter Wemm int 429276b7bf71SPeter Wemm add_hostnames(sa) 429376b7bf71SPeter Wemm SOCKADDR *sa; 429476b7bf71SPeter Wemm { 429576b7bf71SPeter Wemm struct hostent *hp; 429676b7bf71SPeter Wemm 429776b7bf71SPeter Wemm /* lookup name with IP address */ 429876b7bf71SPeter Wemm switch (sa->sa.sa_family) 429976b7bf71SPeter Wemm { 430076b7bf71SPeter Wemm case AF_INET: 430176b7bf71SPeter Wemm hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr, 430276b7bf71SPeter Wemm sizeof(sa->sin.sin_addr), sa->sa.sa_family); 430376b7bf71SPeter Wemm break; 430476b7bf71SPeter Wemm 430576b7bf71SPeter Wemm default: 430676b7bf71SPeter Wemm #if _FFR_LOG_UNSUPPORTED_FAMILIES 430776b7bf71SPeter Wemm /* XXX: Give warning about unsupported family */ 430876b7bf71SPeter Wemm if (LogLevel > 3) 430976b7bf71SPeter Wemm sm_syslog(LOG_WARNING, NOQID, 431076b7bf71SPeter Wemm "Unsupported address family %d: %.100s", 431176b7bf71SPeter Wemm sa->sa.sa_family, anynet_ntoa(sa)); 431276b7bf71SPeter Wemm #endif 431376b7bf71SPeter Wemm return -1; 431476b7bf71SPeter Wemm } 431576b7bf71SPeter Wemm 431676b7bf71SPeter Wemm if (hp == NULL) 431776b7bf71SPeter Wemm { 431876b7bf71SPeter Wemm int save_errno = errno; 431976b7bf71SPeter Wemm 432076b7bf71SPeter Wemm if (LogLevel > 3) 432176b7bf71SPeter Wemm sm_syslog(LOG_WARNING, NOQID, 432276b7bf71SPeter Wemm "gethostbyaddr(%.100s) failed: %d\n", 432376b7bf71SPeter Wemm anynet_ntoa(sa), 432476b7bf71SPeter Wemm #if NAMED_BIND 432576b7bf71SPeter Wemm h_errno 432676b7bf71SPeter Wemm #else 432776b7bf71SPeter Wemm -1 432876b7bf71SPeter Wemm #endif 432976b7bf71SPeter Wemm ); 433076b7bf71SPeter Wemm errno = save_errno; 433176b7bf71SPeter Wemm return -1; 433276b7bf71SPeter Wemm } 433376b7bf71SPeter Wemm 433476b7bf71SPeter Wemm /* save its cname */ 433576b7bf71SPeter Wemm if (!wordinclass((char *) hp->h_name, 'w')) 433676b7bf71SPeter Wemm { 433776b7bf71SPeter Wemm setclass('w', (char *) hp->h_name); 433876b7bf71SPeter Wemm if (tTd(0, 4)) 433976b7bf71SPeter Wemm printf("\ta.k.a.: %s\n", hp->h_name); 434076b7bf71SPeter Wemm } 434176b7bf71SPeter Wemm 434276b7bf71SPeter Wemm /* save all it aliases name */ 434376b7bf71SPeter Wemm while (*hp->h_aliases) 434476b7bf71SPeter Wemm { 434576b7bf71SPeter Wemm if (!wordinclass(*hp->h_aliases, 'w')) 434676b7bf71SPeter Wemm { 434776b7bf71SPeter Wemm setclass('w', *hp->h_aliases); 434876b7bf71SPeter Wemm if (tTd(0, 4)) 434976b7bf71SPeter Wemm printf("\ta.k.a.: %s\n", *hp->h_aliases); 435076b7bf71SPeter Wemm } 435176b7bf71SPeter Wemm hp->h_aliases++; 435276b7bf71SPeter Wemm } 435376b7bf71SPeter Wemm return 0; 435476b7bf71SPeter Wemm } 435576b7bf71SPeter Wemm /* 4356c2aa98e2SPeter Wemm ** LOAD_IF_NAMES -- load interface-specific names into $=w 4357c2aa98e2SPeter Wemm ** 4358c2aa98e2SPeter Wemm ** Parameters: 4359c2aa98e2SPeter Wemm ** none. 4360c2aa98e2SPeter Wemm ** 4361c2aa98e2SPeter Wemm ** Returns: 4362c2aa98e2SPeter Wemm ** none. 4363c2aa98e2SPeter Wemm ** 4364c2aa98e2SPeter Wemm ** Side Effects: 4365c2aa98e2SPeter Wemm ** Loads $=w with the names of all the interfaces. 4366c2aa98e2SPeter Wemm */ 4367c2aa98e2SPeter Wemm 4368c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN 4369c2aa98e2SPeter Wemm struct rtentry; 4370c2aa98e2SPeter Wemm struct mbuf; 4371c2aa98e2SPeter Wemm # include <arpa/inet.h> 4372c2aa98e2SPeter Wemm # ifndef SUNOS403 4373c2aa98e2SPeter Wemm # include <sys/time.h> 4374c2aa98e2SPeter Wemm # endif 4375c2aa98e2SPeter Wemm # if _AIX4 >= 40300 4376c2aa98e2SPeter Wemm # undef __P 4377c2aa98e2SPeter Wemm # endif 4378c2aa98e2SPeter Wemm # include <net/if.h> 4379c2aa98e2SPeter Wemm #endif 4380c2aa98e2SPeter Wemm 4381c2aa98e2SPeter Wemm void 4382c2aa98e2SPeter Wemm load_if_names() 4383c2aa98e2SPeter Wemm { 4384c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN 4385c2aa98e2SPeter Wemm int s; 4386c2aa98e2SPeter Wemm int i; 4387c2aa98e2SPeter Wemm struct ifconf ifc; 4388c2aa98e2SPeter Wemm int numifs; 4389c2aa98e2SPeter Wemm 4390c2aa98e2SPeter Wemm s = socket(AF_INET, SOCK_DGRAM, 0); 4391c2aa98e2SPeter Wemm if (s == -1) 4392c2aa98e2SPeter Wemm return; 4393c2aa98e2SPeter Wemm 4394c2aa98e2SPeter Wemm /* get the list of known IP address from the kernel */ 4395c2aa98e2SPeter Wemm # if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN 4396c2aa98e2SPeter Wemm if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0) 4397c2aa98e2SPeter Wemm { 4398c2aa98e2SPeter Wemm /* can't get number of interfaces -- fall back */ 4399c2aa98e2SPeter Wemm if (tTd(0, 4)) 4400c2aa98e2SPeter Wemm printf("SIOCGIFNUM failed: %s\n", errstring(errno)); 4401c2aa98e2SPeter Wemm numifs = -1; 4402c2aa98e2SPeter Wemm } 4403c2aa98e2SPeter Wemm else if (tTd(0, 42)) 4404c2aa98e2SPeter Wemm printf("system has %d interfaces\n", numifs); 4405c2aa98e2SPeter Wemm if (numifs < 0) 4406c2aa98e2SPeter Wemm # endif 4407c2aa98e2SPeter Wemm numifs = 512; 4408c2aa98e2SPeter Wemm 4409c2aa98e2SPeter Wemm if (numifs <= 0) 4410c2aa98e2SPeter Wemm { 4411c2aa98e2SPeter Wemm close(s); 4412c2aa98e2SPeter Wemm return; 4413c2aa98e2SPeter Wemm } 4414c2aa98e2SPeter Wemm ifc.ifc_len = numifs * sizeof (struct ifreq); 4415c2aa98e2SPeter Wemm ifc.ifc_buf = xalloc(ifc.ifc_len); 4416c2aa98e2SPeter Wemm if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) 4417c2aa98e2SPeter Wemm { 4418c2aa98e2SPeter Wemm if (tTd(0, 4)) 4419c2aa98e2SPeter Wemm printf("SIOGIFCONF failed: %s\n", errstring(errno)); 4420c2aa98e2SPeter Wemm close(s); 4421c2aa98e2SPeter Wemm return; 4422c2aa98e2SPeter Wemm } 4423c2aa98e2SPeter Wemm 4424c2aa98e2SPeter Wemm /* scan the list of IP address */ 4425c2aa98e2SPeter Wemm if (tTd(0, 40)) 4426c2aa98e2SPeter Wemm printf("scanning for interface specific names, ifc_len=%d\n", 4427c2aa98e2SPeter Wemm ifc.ifc_len); 4428c2aa98e2SPeter Wemm 4429c2aa98e2SPeter Wemm for (i = 0; i < ifc.ifc_len; ) 4430c2aa98e2SPeter Wemm { 4431c2aa98e2SPeter Wemm struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i]; 443276b7bf71SPeter Wemm SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr; 4433c2aa98e2SPeter Wemm struct in_addr ia; 4434c2aa98e2SPeter Wemm #ifdef SIOCGIFFLAGS 4435c2aa98e2SPeter Wemm struct ifreq ifrf; 4436c2aa98e2SPeter Wemm #endif 4437c2aa98e2SPeter Wemm char ip_addr[256]; 4438c2aa98e2SPeter Wemm extern char *inet_ntoa(); 4439c2aa98e2SPeter Wemm 4440c2aa98e2SPeter Wemm #ifdef BSD4_4_SOCKADDR 444176b7bf71SPeter Wemm if (sa->sa.sa_len > sizeof ifr->ifr_addr) 444276b7bf71SPeter Wemm i += sizeof ifr->ifr_name + sa->sa.sa_len; 4443c2aa98e2SPeter Wemm else 4444c2aa98e2SPeter Wemm #endif 4445c2aa98e2SPeter Wemm i += sizeof *ifr; 4446c2aa98e2SPeter Wemm 4447c2aa98e2SPeter Wemm if (tTd(0, 20)) 444876b7bf71SPeter Wemm printf("%s\n", anynet_ntoa(sa)); 4449c2aa98e2SPeter Wemm 4450c2aa98e2SPeter Wemm if (ifr->ifr_addr.sa_family != AF_INET) 4451c2aa98e2SPeter Wemm continue; 4452c2aa98e2SPeter Wemm 4453c2aa98e2SPeter Wemm #ifdef SIOCGIFFLAGS 4454c2aa98e2SPeter Wemm bzero(&ifrf, sizeof(struct ifreq)); 4455c2aa98e2SPeter Wemm strncpy(ifrf.ifr_name, ifr->ifr_name, sizeof(ifrf.ifr_name)); 4456c2aa98e2SPeter Wemm ioctl(s, SIOCGIFFLAGS, (char *) &ifrf); 4457c2aa98e2SPeter Wemm if (tTd(0, 41)) 4458c2aa98e2SPeter Wemm printf("\tflags: %x\n", ifrf.ifr_flags); 4459c2aa98e2SPeter Wemm # define IFRFREF ifrf 4460c2aa98e2SPeter Wemm #else 4461c2aa98e2SPeter Wemm # define IFRFREF (*ifr) 4462c2aa98e2SPeter Wemm #endif 4463c2aa98e2SPeter Wemm if (!bitset(IFF_UP, IFRFREF.ifr_flags)) 4464c2aa98e2SPeter Wemm continue; 4465c2aa98e2SPeter Wemm 4466c2aa98e2SPeter Wemm /* extract IP address from the list*/ 446776b7bf71SPeter Wemm ia = sa->sin.sin_addr; 4468c2aa98e2SPeter Wemm if (ia.s_addr == INADDR_ANY || ia.s_addr == INADDR_NONE) 4469c2aa98e2SPeter Wemm { 4470c2aa98e2SPeter Wemm message("WARNING: interface %s is UP with %s address", 4471c2aa98e2SPeter Wemm ifr->ifr_name, inet_ntoa(ia)); 4472c2aa98e2SPeter Wemm continue; 4473c2aa98e2SPeter Wemm } 4474c2aa98e2SPeter Wemm 4475c2aa98e2SPeter Wemm /* save IP address in text from */ 4476c2aa98e2SPeter Wemm (void) snprintf(ip_addr, sizeof ip_addr, "[%.*s]", 44771ec86adfSBruce Evans (int)sizeof ip_addr - 3, 4478c2aa98e2SPeter Wemm inet_ntoa(ia)); 4479c2aa98e2SPeter Wemm if (!wordinclass(ip_addr, 'w')) 4480c2aa98e2SPeter Wemm { 4481c2aa98e2SPeter Wemm setclass('w', ip_addr); 4482c2aa98e2SPeter Wemm if (tTd(0, 4)) 4483c2aa98e2SPeter Wemm printf("\ta.k.a.: %s\n", ip_addr); 4484c2aa98e2SPeter Wemm } 4485c2aa98e2SPeter Wemm 4486c2aa98e2SPeter Wemm /* skip "loopback" interface "lo" */ 4487c2aa98e2SPeter Wemm if (bitset(IFF_LOOPBACK, IFRFREF.ifr_flags)) 4488c2aa98e2SPeter Wemm continue; 4489c2aa98e2SPeter Wemm 449076b7bf71SPeter Wemm (void) add_hostnames(sa); 4491c2aa98e2SPeter Wemm } 4492c2aa98e2SPeter Wemm free(ifc.ifc_buf); 4493c2aa98e2SPeter Wemm close(s); 4494c2aa98e2SPeter Wemm # undef IFRFREF 4495c2aa98e2SPeter Wemm #endif 4496c2aa98e2SPeter Wemm } 4497c2aa98e2SPeter Wemm /* 4498c2aa98e2SPeter Wemm ** GET_NUM_PROCS_ONLINE -- return the number of processors currently online 4499c2aa98e2SPeter Wemm ** 4500c2aa98e2SPeter Wemm ** Parameters: 4501c2aa98e2SPeter Wemm ** none. 4502c2aa98e2SPeter Wemm ** 4503c2aa98e2SPeter Wemm ** Returns: 4504c2aa98e2SPeter Wemm ** The number of processors online. 4505c2aa98e2SPeter Wemm */ 4506c2aa98e2SPeter Wemm 4507c2aa98e2SPeter Wemm int 4508c2aa98e2SPeter Wemm get_num_procs_online() 4509c2aa98e2SPeter Wemm { 4510c2aa98e2SPeter Wemm int nproc = 0; 4511c2aa98e2SPeter Wemm 4512c2aa98e2SPeter Wemm #if _FFR_SCALE_LA_BY_NUM_PROCS 4513c2aa98e2SPeter Wemm #ifdef _SC_NPROCESSORS_ONLN 4514c2aa98e2SPeter Wemm nproc = (int) sysconf(_SC_NPROCESSORS_ONLN); 4515c2aa98e2SPeter Wemm #endif 4516c2aa98e2SPeter Wemm #endif 4517c2aa98e2SPeter Wemm if (nproc <= 0) 4518c2aa98e2SPeter Wemm nproc = 1; 4519c2aa98e2SPeter Wemm return nproc; 4520c2aa98e2SPeter Wemm } 4521c2aa98e2SPeter Wemm /* 4522c2aa98e2SPeter Wemm ** SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE 4523c2aa98e2SPeter Wemm ** 4524c2aa98e2SPeter Wemm ** Parameters: 4525c2aa98e2SPeter Wemm ** level -- syslog level 4526c2aa98e2SPeter Wemm ** id -- envelope ID or NULL (NOQUEUE) 4527c2aa98e2SPeter Wemm ** fmt -- format string 4528c2aa98e2SPeter Wemm ** arg... -- arguments as implied by fmt. 4529c2aa98e2SPeter Wemm ** 4530c2aa98e2SPeter Wemm ** Returns: 4531c2aa98e2SPeter Wemm ** none 4532c2aa98e2SPeter Wemm */ 4533c2aa98e2SPeter Wemm 4534c2aa98e2SPeter Wemm /* VARARGS3 */ 4535c2aa98e2SPeter Wemm void 4536c2aa98e2SPeter Wemm # ifdef __STDC__ 4537c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...) 4538c2aa98e2SPeter Wemm # else 4539c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist) 4540c2aa98e2SPeter Wemm int level; 4541c2aa98e2SPeter Wemm const char *id; 4542c2aa98e2SPeter Wemm const char *fmt; 4543c2aa98e2SPeter Wemm va_dcl 4544c2aa98e2SPeter Wemm #endif 4545c2aa98e2SPeter Wemm { 4546c2aa98e2SPeter Wemm static char *buf = NULL; 4547c2aa98e2SPeter Wemm static size_t bufsize = MAXLINE; 4548c2aa98e2SPeter Wemm char *begin, *end; 4549c2aa98e2SPeter Wemm int seq = 1; 4550c2aa98e2SPeter Wemm int idlen; 4551c2aa98e2SPeter Wemm extern int SnprfOverflow; 4552c2aa98e2SPeter Wemm extern int SyslogErrno; 4553c2aa98e2SPeter Wemm extern char *DoprEnd; 4554c2aa98e2SPeter Wemm VA_LOCAL_DECL 455576b7bf71SPeter Wemm extern void sm_dopr __P((char *, const char *, va_list)); 4556c2aa98e2SPeter Wemm 4557c2aa98e2SPeter Wemm SyslogErrno = errno; 4558c2aa98e2SPeter Wemm if (id == NULL) 4559c2aa98e2SPeter Wemm { 4560c2aa98e2SPeter Wemm id = "NOQUEUE"; 4561c2aa98e2SPeter Wemm idlen = 9; 4562c2aa98e2SPeter Wemm } 4563c2aa98e2SPeter Wemm else if (strcmp(id, NOQID) == 0) 4564c2aa98e2SPeter Wemm { 4565c2aa98e2SPeter Wemm id = ""; 4566c2aa98e2SPeter Wemm idlen = 0; 4567c2aa98e2SPeter Wemm } 4568c2aa98e2SPeter Wemm else 4569c2aa98e2SPeter Wemm idlen = strlen(id + 2); 4570c2aa98e2SPeter Wemm bufalloc: 4571c2aa98e2SPeter Wemm if (buf == NULL) 4572c2aa98e2SPeter Wemm buf = (char *) xalloc(sizeof(char) * bufsize); 4573c2aa98e2SPeter Wemm 4574c2aa98e2SPeter Wemm /* do a virtual vsnprintf into buf */ 4575c2aa98e2SPeter Wemm VA_START(fmt); 4576c2aa98e2SPeter Wemm buf[0] = 0; 4577c2aa98e2SPeter Wemm DoprEnd = buf + bufsize - 1; 4578c2aa98e2SPeter Wemm SnprfOverflow = 0; 4579c2aa98e2SPeter Wemm sm_dopr(buf, fmt, ap); 4580c2aa98e2SPeter Wemm *DoprEnd = '\0'; 4581c2aa98e2SPeter Wemm VA_END; 4582c2aa98e2SPeter Wemm /* end of virtual vsnprintf */ 4583c2aa98e2SPeter Wemm 4584c2aa98e2SPeter Wemm if (SnprfOverflow) 4585c2aa98e2SPeter Wemm { 4586c2aa98e2SPeter Wemm /* String too small, redo with correct size */ 4587c2aa98e2SPeter Wemm bufsize += SnprfOverflow + 1; 4588c2aa98e2SPeter Wemm free(buf); 4589c2aa98e2SPeter Wemm buf = NULL; 4590c2aa98e2SPeter Wemm goto bufalloc; 4591c2aa98e2SPeter Wemm } 4592c2aa98e2SPeter Wemm if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE) 4593c2aa98e2SPeter Wemm { 4594c2aa98e2SPeter Wemm #if LOG 4595c2aa98e2SPeter Wemm if (*id == '\0') 4596c2aa98e2SPeter Wemm syslog(level, "%s", buf); 4597c2aa98e2SPeter Wemm else 4598c2aa98e2SPeter Wemm syslog(level, "%s: %s", id, buf); 4599c2aa98e2SPeter Wemm #else 4600c2aa98e2SPeter Wemm /*XXX should do something more sensible */ 4601c2aa98e2SPeter Wemm if (*id == '\0') 4602c2aa98e2SPeter Wemm fprintf(stderr, "%s\n", buf); 4603c2aa98e2SPeter Wemm else 4604c2aa98e2SPeter Wemm fprintf(stderr, "%s: %s\n", id, buf); 4605c2aa98e2SPeter Wemm #endif 4606c2aa98e2SPeter Wemm return; 4607c2aa98e2SPeter Wemm } 4608c2aa98e2SPeter Wemm 4609c2aa98e2SPeter Wemm begin = buf; 4610c2aa98e2SPeter Wemm while (*begin != '\0' && 4611c2aa98e2SPeter Wemm (strlen(begin) + idlen + 5) > SYSLOG_BUFSIZE) 4612c2aa98e2SPeter Wemm { 4613c2aa98e2SPeter Wemm char save; 4614c2aa98e2SPeter Wemm 4615c2aa98e2SPeter Wemm if (seq == 999) 4616c2aa98e2SPeter Wemm { 4617c2aa98e2SPeter Wemm /* Too many messages */ 4618c2aa98e2SPeter Wemm break; 4619c2aa98e2SPeter Wemm } 4620c2aa98e2SPeter Wemm end = begin + SYSLOG_BUFSIZE - idlen - 12; 4621c2aa98e2SPeter Wemm while (end > begin) 4622c2aa98e2SPeter Wemm { 4623c2aa98e2SPeter Wemm /* Break on comma or space */ 4624c2aa98e2SPeter Wemm if (*end == ',' || *end == ' ') 4625c2aa98e2SPeter Wemm { 4626c2aa98e2SPeter Wemm end++; /* Include separator */ 4627c2aa98e2SPeter Wemm break; 4628c2aa98e2SPeter Wemm } 4629c2aa98e2SPeter Wemm end--; 4630c2aa98e2SPeter Wemm } 4631c2aa98e2SPeter Wemm /* No separator, break midstring... */ 4632c2aa98e2SPeter Wemm if (end == begin) 4633c2aa98e2SPeter Wemm end = begin + SYSLOG_BUFSIZE - idlen - 12; 4634c2aa98e2SPeter Wemm save = *end; 4635c2aa98e2SPeter Wemm *end = 0; 4636c2aa98e2SPeter Wemm #if LOG 4637c2aa98e2SPeter Wemm syslog(level, "%s[%d]: %s ...", id, seq++, begin); 4638c2aa98e2SPeter Wemm #else 4639c2aa98e2SPeter Wemm fprintf(stderr, "%s[%d]: %s ...\n", id, seq++, begin); 4640c2aa98e2SPeter Wemm #endif 4641c2aa98e2SPeter Wemm *end = save; 4642c2aa98e2SPeter Wemm begin = end; 4643c2aa98e2SPeter Wemm } 4644c2aa98e2SPeter Wemm if (seq == 999) 4645c2aa98e2SPeter Wemm #if LOG 4646c2aa98e2SPeter Wemm syslog(level, "%s[%d]: log terminated, too many parts", id, seq); 4647c2aa98e2SPeter Wemm #else 4648c2aa98e2SPeter Wemm fprintf(stderr, "%s[%d]: log terminated, too many parts\n", id, seq); 4649c2aa98e2SPeter Wemm #endif 4650c2aa98e2SPeter Wemm else if (*begin != '\0') 4651c2aa98e2SPeter Wemm #if LOG 4652c2aa98e2SPeter Wemm syslog(level, "%s[%d]: %s", id, seq, begin); 4653c2aa98e2SPeter Wemm #else 4654c2aa98e2SPeter Wemm fprintf(stderr, "%s[%d]: %s\n", id, seq, begin); 4655c2aa98e2SPeter Wemm #endif 4656c2aa98e2SPeter Wemm } 4657c2aa98e2SPeter Wemm /* 4658c2aa98e2SPeter Wemm ** HARD_SYSLOG -- call syslog repeatedly until it works 4659c2aa98e2SPeter Wemm ** 4660c2aa98e2SPeter Wemm ** Needed on HP-UX, which apparently doesn't guarantee that 4661c2aa98e2SPeter Wemm ** syslog succeeds during interrupt handlers. 4662c2aa98e2SPeter Wemm */ 4663c2aa98e2SPeter Wemm 4664c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11) 4665c2aa98e2SPeter Wemm 4666c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES 100 4667c2aa98e2SPeter Wemm # undef syslog 4668c2aa98e2SPeter Wemm # ifdef V4FS 4669c2aa98e2SPeter Wemm # define XCNST const 4670c2aa98e2SPeter Wemm # define CAST (const char *) 4671c2aa98e2SPeter Wemm # else 4672c2aa98e2SPeter Wemm # define XCNST 4673c2aa98e2SPeter Wemm # define CAST 4674c2aa98e2SPeter Wemm # endif 4675c2aa98e2SPeter Wemm 4676c2aa98e2SPeter Wemm void 4677c2aa98e2SPeter Wemm # ifdef __STDC__ 4678c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...) 4679c2aa98e2SPeter Wemm # else 4680c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist) 4681c2aa98e2SPeter Wemm int pri; 4682c2aa98e2SPeter Wemm XCNST char *msg; 4683c2aa98e2SPeter Wemm va_dcl 4684c2aa98e2SPeter Wemm # endif 4685c2aa98e2SPeter Wemm { 4686c2aa98e2SPeter Wemm int i; 4687c2aa98e2SPeter Wemm char buf[SYSLOG_BUFSIZE]; 4688c2aa98e2SPeter Wemm VA_LOCAL_DECL; 4689c2aa98e2SPeter Wemm 4690c2aa98e2SPeter Wemm VA_START(msg); 4691c2aa98e2SPeter Wemm vsnprintf(buf, sizeof buf, msg, ap); 4692c2aa98e2SPeter Wemm VA_END; 4693c2aa98e2SPeter Wemm 4694c2aa98e2SPeter Wemm for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; ) 4695c2aa98e2SPeter Wemm continue; 4696c2aa98e2SPeter Wemm } 4697c2aa98e2SPeter Wemm 4698c2aa98e2SPeter Wemm # undef CAST 4699c2aa98e2SPeter Wemm #endif 4700c2aa98e2SPeter Wemm /* 4701c2aa98e2SPeter Wemm ** LOCAL_HOSTNAME_LENGTH 4702c2aa98e2SPeter Wemm ** 4703c2aa98e2SPeter Wemm ** This is required to get sendmail to compile against BIND 4.9.x 4704c2aa98e2SPeter Wemm ** on Ultrix. 4705c2aa98e2SPeter Wemm */ 4706c2aa98e2SPeter Wemm 4707c2aa98e2SPeter Wemm #if defined(ultrix) && NAMED_BIND 4708c2aa98e2SPeter Wemm 4709c2aa98e2SPeter Wemm # include <resolv.h> 4710c2aa98e2SPeter Wemm # if __RES >= 19931104 && __RES < 19950621 4711c2aa98e2SPeter Wemm 4712c2aa98e2SPeter Wemm int 4713c2aa98e2SPeter Wemm local_hostname_length(hostname) 4714c2aa98e2SPeter Wemm char *hostname; 4715c2aa98e2SPeter Wemm { 4716c2aa98e2SPeter Wemm int len_host, len_domain; 4717c2aa98e2SPeter Wemm 4718c2aa98e2SPeter Wemm if (!*_res.defdname) 4719c2aa98e2SPeter Wemm res_init(); 4720c2aa98e2SPeter Wemm len_host = strlen(hostname); 4721c2aa98e2SPeter Wemm len_domain = strlen(_res.defdname); 4722c2aa98e2SPeter Wemm if (len_host > len_domain && 4723c2aa98e2SPeter Wemm (strcasecmp(hostname + len_host - len_domain,_res.defdname) == 0) && 4724c2aa98e2SPeter Wemm hostname[len_host - len_domain - 1] == '.') 4725c2aa98e2SPeter Wemm return len_host - len_domain - 1; 4726c2aa98e2SPeter Wemm else 4727c2aa98e2SPeter Wemm return 0; 4728c2aa98e2SPeter Wemm } 4729c2aa98e2SPeter Wemm 4730c2aa98e2SPeter Wemm # endif 4731c2aa98e2SPeter Wemm #endif 4732c2aa98e2SPeter Wemm /* 4733c2aa98e2SPeter Wemm ** Compile-Time options 4734c2aa98e2SPeter Wemm */ 4735c2aa98e2SPeter Wemm 4736c2aa98e2SPeter Wemm char *CompileOptions[] = 4737c2aa98e2SPeter Wemm { 4738c2aa98e2SPeter Wemm #ifdef HESIOD 4739c2aa98e2SPeter Wemm "HESIOD", 4740c2aa98e2SPeter Wemm #endif 4741c2aa98e2SPeter Wemm #if HES_GETMAILHOST 4742c2aa98e2SPeter Wemm "HES_GETMAILHOST", 4743c2aa98e2SPeter Wemm #endif 4744c2aa98e2SPeter Wemm #ifdef LDAPMAP 4745c2aa98e2SPeter Wemm "LDAPMAP", 4746c2aa98e2SPeter Wemm #endif 4747c2aa98e2SPeter Wemm #ifdef MAP_REGEX 4748c2aa98e2SPeter Wemm "MAP_REGEX", 4749c2aa98e2SPeter Wemm #endif 4750c2aa98e2SPeter Wemm #if LOG 4751c2aa98e2SPeter Wemm "LOG", 4752c2aa98e2SPeter Wemm #endif 4753c2aa98e2SPeter Wemm #if MATCHGECOS 4754c2aa98e2SPeter Wemm "MATCHGECOS", 4755c2aa98e2SPeter Wemm #endif 4756c2aa98e2SPeter Wemm #if MIME7TO8 4757c2aa98e2SPeter Wemm "MIME7TO8", 4758c2aa98e2SPeter Wemm #endif 4759c2aa98e2SPeter Wemm #if MIME8TO7 4760c2aa98e2SPeter Wemm "MIME8TO7", 4761c2aa98e2SPeter Wemm #endif 4762c2aa98e2SPeter Wemm #if NAMED_BIND 4763c2aa98e2SPeter Wemm "NAMED_BIND", 4764c2aa98e2SPeter Wemm #endif 4765c2aa98e2SPeter Wemm #ifdef NDBM 4766c2aa98e2SPeter Wemm "NDBM", 4767c2aa98e2SPeter Wemm #endif 4768c2aa98e2SPeter Wemm #if NETINET 4769c2aa98e2SPeter Wemm "NETINET", 4770c2aa98e2SPeter Wemm #endif 4771c2aa98e2SPeter Wemm #if NETINFO 4772c2aa98e2SPeter Wemm "NETINFO", 4773c2aa98e2SPeter Wemm #endif 4774c2aa98e2SPeter Wemm #if NETISO 4775c2aa98e2SPeter Wemm "NETISO", 4776c2aa98e2SPeter Wemm #endif 4777c2aa98e2SPeter Wemm #if NETNS 4778c2aa98e2SPeter Wemm "NETNS", 4779c2aa98e2SPeter Wemm #endif 4780c2aa98e2SPeter Wemm #if NETUNIX 4781c2aa98e2SPeter Wemm "NETUNIX", 4782c2aa98e2SPeter Wemm #endif 4783c2aa98e2SPeter Wemm #if NETX25 4784c2aa98e2SPeter Wemm "NETX25", 4785c2aa98e2SPeter Wemm #endif 4786c2aa98e2SPeter Wemm #ifdef NEWDB 4787c2aa98e2SPeter Wemm "NEWDB", 4788c2aa98e2SPeter Wemm #endif 4789c2aa98e2SPeter Wemm #ifdef NIS 4790c2aa98e2SPeter Wemm "NIS", 4791c2aa98e2SPeter Wemm #endif 4792c2aa98e2SPeter Wemm #ifdef NISPLUS 4793c2aa98e2SPeter Wemm "NISPLUS", 4794c2aa98e2SPeter Wemm #endif 4795c2aa98e2SPeter Wemm #if QUEUE 4796c2aa98e2SPeter Wemm "QUEUE", 4797c2aa98e2SPeter Wemm #endif 4798c2aa98e2SPeter Wemm #if SCANF 4799c2aa98e2SPeter Wemm "SCANF", 4800c2aa98e2SPeter Wemm #endif 4801c2aa98e2SPeter Wemm #if SMTP 4802c2aa98e2SPeter Wemm "SMTP", 4803c2aa98e2SPeter Wemm #endif 4804c2aa98e2SPeter Wemm #if SMTPDEBUG 4805c2aa98e2SPeter Wemm "SMTPDEBUG", 4806c2aa98e2SPeter Wemm #endif 4807c2aa98e2SPeter Wemm #ifdef SUID_ROOT_FILES_OK 4808c2aa98e2SPeter Wemm "SUID_ROOT_FILES_OK", 4809c2aa98e2SPeter Wemm #endif 4810c2aa98e2SPeter Wemm #if TCPWRAPPERS 4811c2aa98e2SPeter Wemm "TCPWRAPPERS", 4812c2aa98e2SPeter Wemm #endif 4813c2aa98e2SPeter Wemm #if USERDB 4814c2aa98e2SPeter Wemm "USERDB", 4815c2aa98e2SPeter Wemm #endif 4816c2aa98e2SPeter Wemm #if XDEBUG 4817c2aa98e2SPeter Wemm "XDEBUG", 4818c2aa98e2SPeter Wemm #endif 4819c2aa98e2SPeter Wemm #ifdef XLA 4820c2aa98e2SPeter Wemm "XLA", 4821c2aa98e2SPeter Wemm #endif 4822c2aa98e2SPeter Wemm NULL 4823c2aa98e2SPeter Wemm }; 4824c2aa98e2SPeter Wemm 4825c2aa98e2SPeter Wemm 4826c2aa98e2SPeter Wemm /* 4827c2aa98e2SPeter Wemm ** OS compile options. 4828c2aa98e2SPeter Wemm */ 4829c2aa98e2SPeter Wemm 4830c2aa98e2SPeter Wemm char *OsCompileOptions[] = 4831c2aa98e2SPeter Wemm { 4832c2aa98e2SPeter Wemm #if BOGUS_O_EXCL 4833c2aa98e2SPeter Wemm "BOGUS_O_EXCL", 4834c2aa98e2SPeter Wemm #endif 4835c2aa98e2SPeter Wemm #if HASFCHMOD 4836c2aa98e2SPeter Wemm "HASFCHMOD", 4837c2aa98e2SPeter Wemm #endif 4838c2aa98e2SPeter Wemm #if HASFLOCK 4839c2aa98e2SPeter Wemm "HASFLOCK", 4840c2aa98e2SPeter Wemm #endif 4841c2aa98e2SPeter Wemm #if HASGETDTABLESIZE 4842c2aa98e2SPeter Wemm "HASGETDTABLESIZE", 4843c2aa98e2SPeter Wemm #endif 4844c2aa98e2SPeter Wemm #if HASGETUSERSHELL 4845c2aa98e2SPeter Wemm "HASGETUSERSHELL", 4846c2aa98e2SPeter Wemm #endif 4847c2aa98e2SPeter Wemm #if HASINITGROUPS 4848c2aa98e2SPeter Wemm "HASINITGROUPS", 4849c2aa98e2SPeter Wemm #endif 4850c2aa98e2SPeter Wemm #if HASLSTAT 4851c2aa98e2SPeter Wemm "HASLSTAT", 4852c2aa98e2SPeter Wemm #endif 4853c2aa98e2SPeter Wemm #if HASSETREUID 4854c2aa98e2SPeter Wemm "HASSETREUID", 4855c2aa98e2SPeter Wemm #endif 4856c2aa98e2SPeter Wemm #if HASSETRLIMIT 4857c2aa98e2SPeter Wemm "HASSETRLIMIT", 4858c2aa98e2SPeter Wemm #endif 4859c2aa98e2SPeter Wemm #if HASSETSID 4860c2aa98e2SPeter Wemm "HASSETSID", 4861c2aa98e2SPeter Wemm #endif 4862c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT 4863c2aa98e2SPeter Wemm "HASSETUSERCONTEXT", 4864c2aa98e2SPeter Wemm #endif 4865c2aa98e2SPeter Wemm #if HASSETVBUF 4866c2aa98e2SPeter Wemm "HASSETVBUF", 4867c2aa98e2SPeter Wemm #endif 4868c2aa98e2SPeter Wemm #if HASSNPRINTF 4869c2aa98e2SPeter Wemm "HASSNPRINTF", 4870c2aa98e2SPeter Wemm #endif 4871c2aa98e2SPeter Wemm #if HAS_ST_GEN 4872c2aa98e2SPeter Wemm "HAS_ST_GEN", 4873c2aa98e2SPeter Wemm #endif 4874c2aa98e2SPeter Wemm #if HASSTRERROR 4875c2aa98e2SPeter Wemm "HASSTRERROR", 4876c2aa98e2SPeter Wemm #endif 4877c2aa98e2SPeter Wemm #if HASULIMIT 4878c2aa98e2SPeter Wemm "HASULIMIT", 4879c2aa98e2SPeter Wemm #endif 4880c2aa98e2SPeter Wemm #if HASUNAME 4881c2aa98e2SPeter Wemm "HASUNAME", 4882c2aa98e2SPeter Wemm #endif 4883c2aa98e2SPeter Wemm #if HASUNSETENV 4884c2aa98e2SPeter Wemm "HASUNSETENV", 4885c2aa98e2SPeter Wemm #endif 4886c2aa98e2SPeter Wemm #if HASWAITPID 4887c2aa98e2SPeter Wemm "HASWAITPID", 4888c2aa98e2SPeter Wemm #endif 4889c2aa98e2SPeter Wemm #if IDENTPROTO 4890c2aa98e2SPeter Wemm "IDENTPROTO", 4891c2aa98e2SPeter Wemm #endif 4892c2aa98e2SPeter Wemm #if IP_SRCROUTE 4893c2aa98e2SPeter Wemm "IP_SRCROUTE", 4894c2aa98e2SPeter Wemm #endif 4895c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL 4896c2aa98e2SPeter Wemm "LOCK_ON_OPEN", 4897c2aa98e2SPeter Wemm #endif 4898c2aa98e2SPeter Wemm #if NEEDFSYNC 4899c2aa98e2SPeter Wemm "NEEDFSYNC", 4900c2aa98e2SPeter Wemm #endif 4901c2aa98e2SPeter Wemm #if NOFTRUNCATE 4902c2aa98e2SPeter Wemm "NOFTRUNCATE", 4903c2aa98e2SPeter Wemm #endif 4904c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H 4905c2aa98e2SPeter Wemm "RLIMIT_NEEDS_SYS_TIME_H", 4906c2aa98e2SPeter Wemm #endif 4907c2aa98e2SPeter Wemm #if SAFENFSPATHCONF 4908c2aa98e2SPeter Wemm "SAFENFSPATHCONF", 4909c2aa98e2SPeter Wemm #endif 4910c2aa98e2SPeter Wemm #if SECUREWARE 4911c2aa98e2SPeter Wemm "SECUREWARE", 4912c2aa98e2SPeter Wemm #endif 4913c2aa98e2SPeter Wemm #if SHARE_V1 4914c2aa98e2SPeter Wemm "SHARE_V1", 4915c2aa98e2SPeter Wemm #endif 4916c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN 4917c2aa98e2SPeter Wemm "SIOCGIFCONF_IS_BROKEN", 4918c2aa98e2SPeter Wemm #endif 4919c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN 4920c2aa98e2SPeter Wemm "SIOCGIFNUM_IS_BROKEN", 4921c2aa98e2SPeter Wemm #endif 4922c2aa98e2SPeter Wemm #if SYS5SETPGRP 4923c2aa98e2SPeter Wemm "SYS5SETPGRP", 4924c2aa98e2SPeter Wemm #endif 4925c2aa98e2SPeter Wemm #if SYSTEM5 4926c2aa98e2SPeter Wemm "SYSTEM5", 4927c2aa98e2SPeter Wemm #endif 4928c2aa98e2SPeter Wemm #if USE_SA_SIGACTION 4929c2aa98e2SPeter Wemm "USE_SA_SIGACTION", 4930c2aa98e2SPeter Wemm #endif 4931c2aa98e2SPeter Wemm #if USE_SIGLONGJMP 4932c2aa98e2SPeter Wemm "USE_SIGLONGJMP", 4933c2aa98e2SPeter Wemm #endif 4934c2aa98e2SPeter Wemm #if USESETEUID 4935c2aa98e2SPeter Wemm "USESETEUID", 4936c2aa98e2SPeter Wemm #endif 4937c2aa98e2SPeter Wemm NULL 4938c2aa98e2SPeter Wemm }; 4939