1c2aa98e2SPeter Wemm /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 1998-2013 Proofpoint, Inc. and its suppliers. 33299c2f1SGregory Neil Shapiro * All rights reserved. 4c2aa98e2SPeter Wemm * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5c2aa98e2SPeter Wemm * Copyright (c) 1988, 1993 6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved. 7c2aa98e2SPeter Wemm * 8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set 9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of 10c2aa98e2SPeter Wemm * the sendmail distribution. 11c2aa98e2SPeter Wemm * 12c2aa98e2SPeter Wemm */ 13c2aa98e2SPeter Wemm 1412ed1c7cSGregory Neil Shapiro #include <sendmail.h> 1512ed1c7cSGregory Neil Shapiro 16da7d7b9cSGregory Neil Shapiro SM_RCSID("@(#)$Id: conf.c,v 8.1192 2014-01-27 18:23:21 ca Exp $") 17c2aa98e2SPeter Wemm 18951742c4SGregory Neil Shapiro #include <sm/sendmail.h> 193299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h> 207660b554SGregory Neil Shapiro #if NEWDB 217660b554SGregory Neil Shapiro # include "sm/bdb.h" 227660b554SGregory Neil Shapiro #endif /* NEWDB */ 233299c2f1SGregory Neil Shapiro 24951742c4SGregory Neil Shapiro #include <daemon.h> 25951742c4SGregory Neil Shapiro #include "map.h" 26951742c4SGregory Neil Shapiro 27567a2fc9SGregory Neil Shapiro #ifdef DEC 28567a2fc9SGregory Neil Shapiro # if NETINET6 29567a2fc9SGregory Neil Shapiro /* for the IPv6 device lookup */ 30567a2fc9SGregory Neil Shapiro # define _SOCKADDR_LEN 31567a2fc9SGregory Neil Shapiro # include <macros.h> 32567a2fc9SGregory Neil Shapiro # endif /* NETINET6 */ 33567a2fc9SGregory Neil Shapiro #endif /* DEC */ 34567a2fc9SGregory Neil Shapiro 35c2aa98e2SPeter Wemm # include <sys/ioctl.h> 36c2aa98e2SPeter Wemm # include <sys/param.h> 373299c2f1SGregory Neil Shapiro 38c2aa98e2SPeter Wemm #include <limits.h> 393299c2f1SGregory Neil Shapiro #if NETINET || NETINET6 403299c2f1SGregory Neil Shapiro # include <arpa/inet.h> 413299c2f1SGregory Neil Shapiro #endif /* NETINET || NETINET6 */ 423299c2f1SGregory Neil Shapiro #if HASULIMIT && defined(HPUX11) 433299c2f1SGregory Neil Shapiro # include <ulimit.h> 443299c2f1SGregory Neil Shapiro #endif /* HASULIMIT && defined(HPUX11) */ 453299c2f1SGregory Neil Shapiro 463299c2f1SGregory Neil Shapiro static void setupmaps __P((void)); 473299c2f1SGregory Neil Shapiro static void setupmailers __P((void)); 4812ed1c7cSGregory Neil Shapiro static void setupqueues __P((void)); 493299c2f1SGregory Neil Shapiro static int get_num_procs_online __P((void)); 50684b2a5fSGregory Neil Shapiro static int add_hostnames __P((SOCKADDR *)); 51684b2a5fSGregory Neil Shapiro 52684b2a5fSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE 536f9c8e5bSGregory Neil Shapiro static struct hostent *sm_getipnodebyname __P((const char *, int, int, int *)); 546f9c8e5bSGregory Neil Shapiro static struct hostent *sm_getipnodebyaddr __P((const void *, size_t, int, int *)); 556f9c8e5bSGregory Neil Shapiro #else /* NETINET6 && NEEDSGETIPNODE */ 566f9c8e5bSGregory Neil Shapiro #define sm_getipnodebyname getipnodebyname 576f9c8e5bSGregory Neil Shapiro #define sm_getipnodebyaddr getipnodebyaddr 58684b2a5fSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */ 593299c2f1SGregory Neil Shapiro 60c2aa98e2SPeter Wemm 61c2aa98e2SPeter Wemm /* 62c2aa98e2SPeter Wemm ** CONF.C -- Sendmail Configuration Tables. 63c2aa98e2SPeter Wemm ** 64c2aa98e2SPeter Wemm ** Defines the configuration of this installation. 65c2aa98e2SPeter Wemm ** 66c2aa98e2SPeter Wemm ** Configuration Variables: 67c2aa98e2SPeter Wemm ** HdrInfo -- a table describing well-known header fields. 68c2aa98e2SPeter Wemm ** Each entry has the field name and some flags, 69c2aa98e2SPeter Wemm ** which are described in sendmail.h. 70c2aa98e2SPeter Wemm ** 71c2aa98e2SPeter Wemm ** Notes: 72c2aa98e2SPeter Wemm ** I have tried to put almost all the reasonable 73c2aa98e2SPeter Wemm ** configuration information into the configuration 74c2aa98e2SPeter Wemm ** file read at runtime. My intent is that anything 75c2aa98e2SPeter Wemm ** here is a function of the version of UNIX you 76c2aa98e2SPeter Wemm ** are running, or is really static -- for example 77c2aa98e2SPeter Wemm ** the headers are a superset of widely used 78c2aa98e2SPeter Wemm ** protocols. If you find yourself playing with 79c2aa98e2SPeter Wemm ** this file too much, you may be making a mistake! 80c2aa98e2SPeter Wemm */ 81c2aa98e2SPeter Wemm 82c2aa98e2SPeter Wemm 83c2aa98e2SPeter Wemm /* 84c2aa98e2SPeter Wemm ** Header info table 85c2aa98e2SPeter Wemm ** Final (null) entry contains the flags used for any other field. 86c2aa98e2SPeter Wemm ** 87c2aa98e2SPeter Wemm ** Not all of these are actually handled specially by sendmail 88c2aa98e2SPeter Wemm ** at this time. They are included as placeholders, to let 89c2aa98e2SPeter Wemm ** you know that "someday" I intend to have sendmail do 90c2aa98e2SPeter Wemm ** something with them. 91c2aa98e2SPeter Wemm */ 92c2aa98e2SPeter Wemm 93c2aa98e2SPeter Wemm struct hdrinfo HdrInfo[] = 94c2aa98e2SPeter Wemm { 95c2aa98e2SPeter Wemm /* originator fields, most to least significant */ 963299c2f1SGregory Neil Shapiro { "resent-sender", H_FROM|H_RESENT, NULL }, 973299c2f1SGregory Neil Shapiro { "resent-from", H_FROM|H_RESENT, NULL }, 983299c2f1SGregory Neil Shapiro { "resent-reply-to", H_FROM|H_RESENT, NULL }, 993299c2f1SGregory Neil Shapiro { "sender", H_FROM, NULL }, 1003299c2f1SGregory Neil Shapiro { "from", H_FROM, NULL }, 1013299c2f1SGregory Neil Shapiro { "reply-to", H_FROM, NULL }, 1023299c2f1SGregory Neil Shapiro { "errors-to", H_FROM|H_ERRORSTO, NULL }, 1033299c2f1SGregory Neil Shapiro { "full-name", H_ACHECK, NULL }, 1043299c2f1SGregory Neil Shapiro { "return-receipt-to", H_RECEIPTTO, NULL }, 105bfb62e91SGregory Neil Shapiro { "delivery-receipt-to", H_RECEIPTTO, NULL }, 10612ed1c7cSGregory Neil Shapiro { "disposition-notification-to", H_FROM, NULL }, 107c2aa98e2SPeter Wemm 108c2aa98e2SPeter Wemm /* destination fields */ 1093299c2f1SGregory Neil Shapiro { "to", H_RCPT, NULL }, 1103299c2f1SGregory Neil Shapiro { "resent-to", H_RCPT|H_RESENT, NULL }, 1113299c2f1SGregory Neil Shapiro { "cc", H_RCPT, NULL }, 1123299c2f1SGregory Neil Shapiro { "resent-cc", H_RCPT|H_RESENT, NULL }, 1133299c2f1SGregory Neil Shapiro { "bcc", H_RCPT|H_BCC, NULL }, 1143299c2f1SGregory Neil Shapiro { "resent-bcc", H_RCPT|H_BCC|H_RESENT, NULL }, 1153299c2f1SGregory Neil Shapiro { "apparently-to", H_RCPT, NULL }, 116c2aa98e2SPeter Wemm 117c2aa98e2SPeter Wemm /* message identification and control */ 1183299c2f1SGregory Neil Shapiro { "message-id", 0, NULL }, 1193299c2f1SGregory Neil Shapiro { "resent-message-id", H_RESENT, NULL }, 1203299c2f1SGregory Neil Shapiro { "message", H_EOH, NULL }, 1213299c2f1SGregory Neil Shapiro { "text", H_EOH, NULL }, 122c2aa98e2SPeter Wemm 123c2aa98e2SPeter Wemm /* date fields */ 1243299c2f1SGregory Neil Shapiro { "date", 0, NULL }, 1253299c2f1SGregory Neil Shapiro { "resent-date", H_RESENT, NULL }, 126c2aa98e2SPeter Wemm 127c2aa98e2SPeter Wemm /* trace fields */ 1283299c2f1SGregory Neil Shapiro { "received", H_TRACE|H_FORCE, NULL }, 1293299c2f1SGregory Neil Shapiro { "x400-received", H_TRACE|H_FORCE, NULL }, 1303299c2f1SGregory Neil Shapiro { "via", H_TRACE|H_FORCE, NULL }, 1313299c2f1SGregory Neil Shapiro { "mail-from", H_TRACE|H_FORCE, NULL }, 132c2aa98e2SPeter Wemm 133c2aa98e2SPeter Wemm /* miscellaneous fields */ 1343299c2f1SGregory Neil Shapiro { "comments", H_FORCE|H_ENCODABLE, NULL }, 1353299c2f1SGregory Neil Shapiro { "return-path", H_FORCE|H_ACHECK|H_BINDLATE, NULL }, 1363299c2f1SGregory Neil Shapiro { "content-transfer-encoding", H_CTE, NULL }, 1373299c2f1SGregory Neil Shapiro { "content-type", H_CTYPE, NULL }, 1383299c2f1SGregory Neil Shapiro { "content-length", H_ACHECK, NULL }, 1393299c2f1SGregory Neil Shapiro { "subject", H_ENCODABLE, NULL }, 1403299c2f1SGregory Neil Shapiro { "x-authentication-warning", H_FORCE, NULL }, 141c2aa98e2SPeter Wemm 1423299c2f1SGregory Neil Shapiro { NULL, 0, NULL } 143c2aa98e2SPeter Wemm }; 144c2aa98e2SPeter Wemm 145c2aa98e2SPeter Wemm 146c2aa98e2SPeter Wemm 147c2aa98e2SPeter Wemm /* 148c2aa98e2SPeter Wemm ** Privacy values 149c2aa98e2SPeter Wemm */ 150c2aa98e2SPeter Wemm 151c2aa98e2SPeter Wemm struct prival PrivacyValues[] = 152c2aa98e2SPeter Wemm { 153c2aa98e2SPeter Wemm { "public", PRIV_PUBLIC }, 154c2aa98e2SPeter Wemm { "needmailhelo", PRIV_NEEDMAILHELO }, 155c2aa98e2SPeter Wemm { "needexpnhelo", PRIV_NEEDEXPNHELO }, 156c2aa98e2SPeter Wemm { "needvrfyhelo", PRIV_NEEDVRFYHELO }, 157c2aa98e2SPeter Wemm { "noexpn", PRIV_NOEXPN }, 158c2aa98e2SPeter Wemm { "novrfy", PRIV_NOVRFY }, 15912ed1c7cSGregory Neil Shapiro { "restrictexpand", PRIV_RESTRICTEXPAND }, 160c2aa98e2SPeter Wemm { "restrictmailq", PRIV_RESTRICTMAILQ }, 161c2aa98e2SPeter Wemm { "restrictqrun", PRIV_RESTRICTQRUN }, 162c2aa98e2SPeter Wemm { "noetrn", PRIV_NOETRN }, 163c2aa98e2SPeter Wemm { "noverb", PRIV_NOVERB }, 164c2aa98e2SPeter Wemm { "authwarnings", PRIV_AUTHWARNINGS }, 165c2aa98e2SPeter Wemm { "noreceipts", PRIV_NORECEIPTS }, 1663299c2f1SGregory Neil Shapiro { "nobodyreturn", PRIV_NOBODYRETN }, 167c2aa98e2SPeter Wemm { "goaway", PRIV_GOAWAY }, 168684b2a5fSGregory Neil Shapiro { "noactualrecipient", PRIV_NOACTUALRECIPIENT }, 169c2aa98e2SPeter Wemm { NULL, 0 } 170c2aa98e2SPeter Wemm }; 171c2aa98e2SPeter Wemm 172c2aa98e2SPeter Wemm /* 173c2aa98e2SPeter Wemm ** DontBlameSendmail values 174c2aa98e2SPeter Wemm */ 17512ed1c7cSGregory Neil Shapiro 176c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] = 177c2aa98e2SPeter Wemm { 178c2aa98e2SPeter Wemm { "safe", DBS_SAFE }, 179c2aa98e2SPeter Wemm { "assumesafechown", DBS_ASSUMESAFECHOWN }, 180c2aa98e2SPeter Wemm { "groupwritabledirpathsafe", DBS_GROUPWRITABLEDIRPATHSAFE }, 181c2aa98e2SPeter Wemm { "groupwritableforwardfilesafe", 182c2aa98e2SPeter Wemm DBS_GROUPWRITABLEFORWARDFILESAFE }, 183c2aa98e2SPeter Wemm { "groupwritableincludefilesafe", 184c2aa98e2SPeter Wemm DBS_GROUPWRITABLEINCLUDEFILESAFE }, 185c2aa98e2SPeter Wemm { "groupwritablealiasfile", DBS_GROUPWRITABLEALIASFILE }, 186c2aa98e2SPeter Wemm { "worldwritablealiasfile", DBS_WORLDWRITABLEALIASFILE }, 187c2aa98e2SPeter Wemm { "forwardfileinunsafedirpath", DBS_FORWARDFILEINUNSAFEDIRPATH }, 188c2aa98e2SPeter Wemm { "includefileinunsafedirpath", DBS_INCLUDEFILEINUNSAFEDIRPATH }, 189c2aa98e2SPeter Wemm { "mapinunsafedirpath", DBS_MAPINUNSAFEDIRPATH }, 190c2aa98e2SPeter Wemm { "linkedaliasfileinwritabledir", 191c2aa98e2SPeter Wemm DBS_LINKEDALIASFILEINWRITABLEDIR }, 192c2aa98e2SPeter Wemm { "linkedclassfileinwritabledir", 193c2aa98e2SPeter Wemm DBS_LINKEDCLASSFILEINWRITABLEDIR }, 194c2aa98e2SPeter Wemm { "linkedforwardfileinwritabledir", 195c2aa98e2SPeter Wemm DBS_LINKEDFORWARDFILEINWRITABLEDIR }, 196c2aa98e2SPeter Wemm { "linkedincludefileinwritabledir", 197c2aa98e2SPeter Wemm DBS_LINKEDINCLUDEFILEINWRITABLEDIR }, 198c2aa98e2SPeter Wemm { "linkedmapinwritabledir", DBS_LINKEDMAPINWRITABLEDIR }, 199c2aa98e2SPeter Wemm { "linkedserviceswitchfileinwritabledir", 200c2aa98e2SPeter Wemm DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR }, 201c2aa98e2SPeter Wemm { "filedeliverytohardlink", DBS_FILEDELIVERYTOHARDLINK }, 202c2aa98e2SPeter Wemm { "filedeliverytosymlink", DBS_FILEDELIVERYTOSYMLINK }, 203c2aa98e2SPeter Wemm { "writemaptohardlink", DBS_WRITEMAPTOHARDLINK }, 204c2aa98e2SPeter Wemm { "writemaptosymlink", DBS_WRITEMAPTOSYMLINK }, 205c2aa98e2SPeter Wemm { "writestatstohardlink", DBS_WRITESTATSTOHARDLINK }, 206c2aa98e2SPeter Wemm { "writestatstosymlink", DBS_WRITESTATSTOSYMLINK }, 207c2aa98e2SPeter Wemm { "forwardfileingroupwritabledirpath", 208c2aa98e2SPeter Wemm DBS_FORWARDFILEINGROUPWRITABLEDIRPATH }, 209c2aa98e2SPeter Wemm { "includefileingroupwritabledirpath", 210c2aa98e2SPeter Wemm DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH }, 211c2aa98e2SPeter Wemm { "classfileinunsafedirpath", DBS_CLASSFILEINUNSAFEDIRPATH }, 212c2aa98e2SPeter Wemm { "errorheaderinunsafedirpath", DBS_ERRORHEADERINUNSAFEDIRPATH }, 213c2aa98e2SPeter Wemm { "helpfileinunsafedirpath", DBS_HELPFILEINUNSAFEDIRPATH }, 214c2aa98e2SPeter Wemm { "forwardfileinunsafedirpathsafe", 215c2aa98e2SPeter Wemm DBS_FORWARDFILEINUNSAFEDIRPATHSAFE }, 216c2aa98e2SPeter Wemm { "includefileinunsafedirpathsafe", 217c2aa98e2SPeter Wemm DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE }, 218c2aa98e2SPeter Wemm { "runprograminunsafedirpath", DBS_RUNPROGRAMINUNSAFEDIRPATH }, 219c2aa98e2SPeter Wemm { "runwritableprogram", DBS_RUNWRITABLEPROGRAM }, 2203299c2f1SGregory Neil Shapiro { "nonrootsafeaddr", DBS_NONROOTSAFEADDR }, 2213299c2f1SGregory Neil Shapiro { "truststickybit", DBS_TRUSTSTICKYBIT }, 2223299c2f1SGregory Neil Shapiro { "dontwarnforwardfileinunsafedirpath", 2233299c2f1SGregory Neil Shapiro DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH }, 2243299c2f1SGregory Neil Shapiro { "insufficiententropy", DBS_INSUFFICIENTENTROPY }, 22512ed1c7cSGregory Neil Shapiro { "groupreadablesasldbfile", DBS_GROUPREADABLESASLDBFILE }, 22612ed1c7cSGregory Neil Shapiro { "groupwritablesasldbfile", DBS_GROUPWRITABLESASLDBFILE }, 227d995d2baSGregory Neil Shapiro { "groupwritableforwardfile", DBS_GROUPWRITABLEFORWARDFILE }, 228d995d2baSGregory Neil Shapiro { "groupwritableincludefile", DBS_GROUPWRITABLEINCLUDEFILE }, 229d995d2baSGregory Neil Shapiro { "worldwritableforwardfile", DBS_WORLDWRITABLEFORWARDFILE }, 230d995d2baSGregory Neil Shapiro { "worldwritableincludefile", DBS_WORLDWRITABLEINCLUDEFILE }, 23112ed1c7cSGregory Neil Shapiro { "groupreadablekeyfile", DBS_GROUPREADABLEKEYFILE }, 232da7d7b9cSGregory Neil Shapiro { "groupreadabledefaultauthinfofile", 23312ed1c7cSGregory Neil Shapiro DBS_GROUPREADABLEAUTHINFOFILE }, 234c2aa98e2SPeter Wemm { NULL, 0 } 235c2aa98e2SPeter Wemm }; 236c2aa98e2SPeter Wemm 237c2aa98e2SPeter Wemm /* 238c2aa98e2SPeter Wemm ** Miscellaneous stuff. 239c2aa98e2SPeter Wemm */ 240c2aa98e2SPeter Wemm 241c2aa98e2SPeter Wemm int DtableSize = 50; /* max open files; reset in 4.2bsd */ 24212ed1c7cSGregory Neil Shapiro /* 243c2aa98e2SPeter Wemm ** SETDEFAULTS -- set default values 244c2aa98e2SPeter Wemm ** 24512ed1c7cSGregory Neil Shapiro ** Some of these must be initialized using direct code since they 24612ed1c7cSGregory Neil Shapiro ** depend on run-time values. So let's do all of them this way. 247c2aa98e2SPeter Wemm ** 248c2aa98e2SPeter Wemm ** Parameters: 249c2aa98e2SPeter Wemm ** e -- the default envelope. 250c2aa98e2SPeter Wemm ** 251c2aa98e2SPeter Wemm ** Returns: 252c2aa98e2SPeter Wemm ** none. 253c2aa98e2SPeter Wemm ** 254c2aa98e2SPeter Wemm ** Side Effects: 255c2aa98e2SPeter Wemm ** Initializes a bunch of global variables to their 256c2aa98e2SPeter Wemm ** default values. 257c2aa98e2SPeter Wemm */ 258c2aa98e2SPeter Wemm 259c2aa98e2SPeter Wemm #define MINUTES * 60 260c2aa98e2SPeter Wemm #define HOURS * 60 MINUTES 261c2aa98e2SPeter Wemm #define DAYS * 24 HOURS 262c2aa98e2SPeter Wemm 263c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION 264c2aa98e2SPeter Wemm # define MAXRULERECURSION 50 /* max ruleset recursion depth */ 2653299c2f1SGregory Neil Shapiro #endif /* ! MAXRULERECURSION */ 266c2aa98e2SPeter Wemm 267c2aa98e2SPeter Wemm void 268c2aa98e2SPeter Wemm setdefaults(e) 269c2aa98e2SPeter Wemm register ENVELOPE *e; 270c2aa98e2SPeter Wemm { 271c2aa98e2SPeter Wemm int i; 2723299c2f1SGregory Neil Shapiro int numprocs; 273c2aa98e2SPeter Wemm struct passwd *pw; 274c2aa98e2SPeter Wemm 2753299c2f1SGregory Neil Shapiro numprocs = get_num_procs_online(); 276c2aa98e2SPeter Wemm SpaceSub = ' '; /* option B */ 2773299c2f1SGregory Neil Shapiro QueueLA = 8 * numprocs; /* option x */ 2783299c2f1SGregory Neil Shapiro RefuseLA = 12 * numprocs; /* option X */ 279c2aa98e2SPeter Wemm WkRecipFact = 30000L; /* option y */ 280c2aa98e2SPeter Wemm WkClassFact = 1800L; /* option z */ 281c2aa98e2SPeter Wemm WkTimeFact = 90000L; /* option Z */ 282c2aa98e2SPeter Wemm QueueFactor = WkRecipFact * 20; /* option q */ 28312ed1c7cSGregory Neil Shapiro QueueMode = QM_NORMAL; /* what queue items to act upon */ 284c2aa98e2SPeter Wemm FileMode = (RealUid != geteuid()) ? 0644 : 0600; 285c2aa98e2SPeter Wemm /* option F */ 2863299c2f1SGregory Neil Shapiro QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600; 2873299c2f1SGregory Neil Shapiro /* option QueueFileMode */ 288c2aa98e2SPeter Wemm 2893299c2f1SGregory Neil Shapiro if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) || 2903299c2f1SGregory Neil Shapiro ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) || 2913299c2f1SGregory Neil Shapiro ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0)) 292c2aa98e2SPeter Wemm { 293c2aa98e2SPeter Wemm DefUid = pw->pw_uid; /* option u */ 294c2aa98e2SPeter Wemm DefGid = pw->pw_gid; /* option g */ 295c2aa98e2SPeter Wemm DefUser = newstr(pw->pw_name); 296c2aa98e2SPeter Wemm } 297c2aa98e2SPeter Wemm else 298c2aa98e2SPeter Wemm { 299c2aa98e2SPeter Wemm DefUid = 1; /* option u */ 300c2aa98e2SPeter Wemm DefGid = 1; /* option g */ 301c2aa98e2SPeter Wemm setdefuser(); 302c2aa98e2SPeter Wemm } 30376b7bf71SPeter Wemm TrustedUid = 0; 304c2aa98e2SPeter Wemm if (tTd(37, 4)) 305da7d7b9cSGregory Neil Shapiro sm_dprintf("setdefaults: DefUser=%s, DefUid=%ld, DefGid=%ld\n", 306c2aa98e2SPeter Wemm DefUser != NULL ? DefUser : "<1:1>", 307da7d7b9cSGregory Neil Shapiro (long) DefUid, (long) DefGid); 308c2aa98e2SPeter Wemm CheckpointInterval = 10; /* option C */ 309c2aa98e2SPeter Wemm MaxHopCount = 25; /* option h */ 3103299c2f1SGregory Neil Shapiro set_delivery_mode(SM_FORK, e); /* option d */ 311c2aa98e2SPeter Wemm e->e_errormode = EM_PRINT; /* option e */ 31212ed1c7cSGregory Neil Shapiro e->e_qgrp = NOQGRP; 31312ed1c7cSGregory Neil Shapiro e->e_qdir = NOQDIR; 31412ed1c7cSGregory Neil Shapiro e->e_xfqgrp = NOQGRP; 31512ed1c7cSGregory Neil Shapiro e->e_xfqdir = NOQDIR; 3163299c2f1SGregory Neil Shapiro e->e_ctime = curtime(); 31712ed1c7cSGregory Neil Shapiro SevenBitInput = false; /* option 7 */ 318c2aa98e2SPeter Wemm MaxMciCache = 1; /* option k */ 319c2aa98e2SPeter Wemm MciCacheTimeout = 5 MINUTES; /* option K */ 320c2aa98e2SPeter Wemm LogLevel = 9; /* option L */ 32112ed1c7cSGregory Neil Shapiro #if MILTER 32212ed1c7cSGregory Neil Shapiro MilterLogLevel = -1; 32312ed1c7cSGregory Neil Shapiro #endif /* MILTER */ 32412ed1c7cSGregory Neil Shapiro inittimeouts(NULL, false); /* option r */ 325c2aa98e2SPeter Wemm PrivacyFlags = PRIV_PUBLIC; /* option p */ 32612ed1c7cSGregory Neil Shapiro MeToo = true; /* option m */ 32712ed1c7cSGregory Neil Shapiro SendMIMEErrors = true; /* option f */ 32812ed1c7cSGregory Neil Shapiro SuperSafe = SAFE_REALLY; /* option s */ 3293299c2f1SGregory Neil Shapiro clrbitmap(DontBlameSendmail); /* DontBlameSendmail option */ 330c2aa98e2SPeter Wemm #if MIME8TO7 331c2aa98e2SPeter Wemm MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */ 3323299c2f1SGregory Neil Shapiro #else /* MIME8TO7 */ 333c2aa98e2SPeter Wemm MimeMode = MM_PASS8BIT; 3343299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */ 335c2aa98e2SPeter Wemm for (i = 0; i < MAXTOCLASS; i++) 336c2aa98e2SPeter Wemm { 337c2aa98e2SPeter Wemm TimeOuts.to_q_return[i] = 5 DAYS; /* option T */ 338c2aa98e2SPeter Wemm TimeOuts.to_q_warning[i] = 0; /* option T */ 339c2aa98e2SPeter Wemm } 3403299c2f1SGregory Neil Shapiro ServiceSwitchFile = "/etc/mail/service.switch"; 341c2aa98e2SPeter Wemm ServiceCacheMaxAge = (time_t) 10; 342c2aa98e2SPeter Wemm HostsFile = _PATH_HOSTS; 343c2aa98e2SPeter Wemm PidFile = newstr(_PATH_SENDMAILPID); 344c2aa98e2SPeter Wemm MustQuoteChars = "@,;:\\()[].'"; 345c2aa98e2SPeter Wemm MciInfoTimeout = 30 MINUTES; 346c2aa98e2SPeter Wemm MaxRuleRecursion = MAXRULERECURSION; 347c2aa98e2SPeter Wemm MaxAliasRecursion = 10; 348c2aa98e2SPeter Wemm MaxMacroRecursion = 10; 34912ed1c7cSGregory Neil Shapiro ColonOkInAddr = true; 35012ed1c7cSGregory Neil Shapiro DontLockReadFiles = true; 35112ed1c7cSGregory Neil Shapiro DontProbeInterfaces = DPI_PROBEALL; 352c2aa98e2SPeter Wemm DoubleBounceAddr = "postmaster"; 353e01d6f61SPeter Wemm MaxHeadersLength = MAXHDRSLEN; 35472936242SGregory Neil Shapiro MaxMimeHeaderLength = MAXLINE; 35572936242SGregory Neil Shapiro MaxMimeFieldLength = MaxMimeHeaderLength / 2; 3563299c2f1SGregory Neil Shapiro MaxForwardEntries = 0; 35712ed1c7cSGregory Neil Shapiro FastSplit = 1; 358567a2fc9SGregory Neil Shapiro MaxNOOPCommands = MAXNOOPCOMMANDS; 3593299c2f1SGregory Neil Shapiro #if SASL 3603299c2f1SGregory Neil Shapiro AuthMechanisms = newstr(AUTH_MECHANISMS); 361bfb62e91SGregory Neil Shapiro AuthRealm = NULL; 36212ed1c7cSGregory Neil Shapiro MaxSLBits = INT_MAX; 3633299c2f1SGregory Neil Shapiro #endif /* SASL */ 36412ed1c7cSGregory Neil Shapiro #if STARTTLS 36512ed1c7cSGregory Neil Shapiro TLS_Srv_Opts = TLS_I_SRV; 366da7d7b9cSGregory Neil Shapiro if (NULL == EVP_digest) 367da7d7b9cSGregory Neil Shapiro EVP_digest = EVP_md5(); 368*76d46bbbSHiroki Sato Srv_SSL_Options = SSL_OP_ALL; 369*76d46bbbSHiroki Sato Clt_SSL_Options = SSL_OP_ALL 370*76d46bbbSHiroki Sato # ifdef SSL_OP_NO_SSLv2 371*76d46bbbSHiroki Sato | SSL_OP_NO_SSLv2 372*76d46bbbSHiroki Sato # endif 373*76d46bbbSHiroki Sato # ifdef SSL_OP_NO_TICKET 374*76d46bbbSHiroki Sato | SSL_OP_NO_TICKET 375*76d46bbbSHiroki Sato # endif 376*76d46bbbSHiroki Sato ; 377*76d46bbbSHiroki Sato # ifdef SSL_OP_TLSEXT_PADDING 378*76d46bbbSHiroki Sato /* SSL_OP_TLSEXT_PADDING breaks compatibility with some sites */ 379*76d46bbbSHiroki Sato Srv_SSL_Options &= ~SSL_OP_TLSEXT_PADDING; 380*76d46bbbSHiroki Sato Clt_SSL_Options &= ~SSL_OP_TLSEXT_PADDING; 381*76d46bbbSHiroki Sato # endif /* SSL_OP_TLSEXT_PADDING */ 38212ed1c7cSGregory Neil Shapiro #endif /* STARTTLS */ 383c2aa98e2SPeter Wemm #ifdef HESIOD_INIT 384c2aa98e2SPeter Wemm HesiodContext = NULL; 3853299c2f1SGregory Neil Shapiro #endif /* HESIOD_INIT */ 3863299c2f1SGregory Neil Shapiro #if NETINET6 3873299c2f1SGregory Neil Shapiro /* Detect if IPv6 is available at run time */ 3883299c2f1SGregory Neil Shapiro i = socket(AF_INET6, SOCK_STREAM, 0); 3893299c2f1SGregory Neil Shapiro if (i >= 0) 3903299c2f1SGregory Neil Shapiro { 3913299c2f1SGregory Neil Shapiro InetMode = AF_INET6; 3923299c2f1SGregory Neil Shapiro (void) close(i); 3933299c2f1SGregory Neil Shapiro } 3943299c2f1SGregory Neil Shapiro else 3953299c2f1SGregory Neil Shapiro InetMode = AF_INET; 396da7d7b9cSGregory Neil Shapiro #if !IPV6_FULL 397da7d7b9cSGregory Neil Shapiro UseCompressedIPv6Addresses = true; 398da7d7b9cSGregory Neil Shapiro #endif 3993299c2f1SGregory Neil Shapiro #else /* NETINET6 */ 4003299c2f1SGregory Neil Shapiro InetMode = AF_INET; 4013299c2f1SGregory Neil Shapiro #endif /* NETINET6 */ 40276b7bf71SPeter Wemm ControlSocketName = NULL; 403951742c4SGregory Neil Shapiro memset(&ConnectOnlyTo, '\0', sizeof(ConnectOnlyTo)); 4043299c2f1SGregory Neil Shapiro DataFileBufferSize = 4096; 4053299c2f1SGregory Neil Shapiro XscriptFileBufferSize = 4096; 4063299c2f1SGregory Neil Shapiro for (i = 0; i < MAXRWSETS; i++) 4073299c2f1SGregory Neil Shapiro RuleSetNames[i] = NULL; 40812ed1c7cSGregory Neil Shapiro #if MILTER 4093299c2f1SGregory Neil Shapiro InputFilters[0] = NULL; 41012ed1c7cSGregory Neil Shapiro #endif /* MILTER */ 4112ef40764SGregory Neil Shapiro RejectLogInterval = 3 HOURS; 412bfb62e91SGregory Neil Shapiro #if REQUIRES_DIR_FSYNC 4132ef40764SGregory Neil Shapiro RequiresDirfsync = true; 414bfb62e91SGregory Neil Shapiro #endif /* REQUIRES_DIR_FSYNC */ 4159bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY 4169bd497b8SGregory Neil Shapiro BadRcptThrottleDelay = 1; 4179bd497b8SGregory Neil Shapiro #endif /* _FFR_RCPTTHROTDELAY */ 418bfb62e91SGregory Neil Shapiro ConnectionRateWindowSize = 60; 419da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 420da7d7b9cSGregory Neil Shapiro BounceQueue = NOQGRP; 421da7d7b9cSGregory Neil Shapiro #endif /* _FFR_BOUNCE_QUEUE */ 422c2aa98e2SPeter Wemm setupmaps(); 42312ed1c7cSGregory Neil Shapiro setupqueues(); 424c2aa98e2SPeter Wemm setupmailers(); 425c2aa98e2SPeter Wemm setupheaders(); 426c2aa98e2SPeter Wemm } 427c2aa98e2SPeter Wemm 428c2aa98e2SPeter Wemm 429c2aa98e2SPeter Wemm /* 430c2aa98e2SPeter Wemm ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 431c2aa98e2SPeter Wemm */ 432c2aa98e2SPeter Wemm 433c2aa98e2SPeter Wemm void 434c2aa98e2SPeter Wemm setdefuser() 435c2aa98e2SPeter Wemm { 436c2aa98e2SPeter Wemm struct passwd *defpwent; 437c2aa98e2SPeter Wemm static char defuserbuf[40]; 438c2aa98e2SPeter Wemm 439c2aa98e2SPeter Wemm DefUser = defuserbuf; 440c2aa98e2SPeter Wemm defpwent = sm_getpwuid(DefUid); 44112ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(defuserbuf, 44212ed1c7cSGregory Neil Shapiro (defpwent == NULL || defpwent->pw_name == NULL) 44312ed1c7cSGregory Neil Shapiro ? "nobody" : defpwent->pw_name, 444951742c4SGregory Neil Shapiro sizeof(defuserbuf)); 445c2aa98e2SPeter Wemm if (tTd(37, 4)) 446da7d7b9cSGregory Neil Shapiro sm_dprintf("setdefuser: DefUid=%ld, DefUser=%s\n", 447da7d7b9cSGregory Neil Shapiro (long) DefUid, DefUser); 448c2aa98e2SPeter Wemm } 44912ed1c7cSGregory Neil Shapiro /* 45012ed1c7cSGregory Neil Shapiro ** SETUPQUEUES -- initialize default queues 45112ed1c7cSGregory Neil Shapiro ** 45212ed1c7cSGregory Neil Shapiro ** The mqueue QUEUE structure gets filled in after readcf() but 45312ed1c7cSGregory Neil Shapiro ** we need something to point to now for the mailer setup, 45412ed1c7cSGregory Neil Shapiro ** which use "mqueue" as default queue. 45512ed1c7cSGregory Neil Shapiro */ 45612ed1c7cSGregory Neil Shapiro 45712ed1c7cSGregory Neil Shapiro static void 45812ed1c7cSGregory Neil Shapiro setupqueues() 45912ed1c7cSGregory Neil Shapiro { 46012ed1c7cSGregory Neil Shapiro char buf[100]; 46112ed1c7cSGregory Neil Shapiro 46212ed1c7cSGregory Neil Shapiro MaxRunnersPerQueue = 1; 463951742c4SGregory Neil Shapiro (void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof(buf)); 46412ed1c7cSGregory Neil Shapiro makequeue(buf, false); 46512ed1c7cSGregory Neil Shapiro } 46612ed1c7cSGregory Neil Shapiro /* 467c2aa98e2SPeter Wemm ** SETUPMAILERS -- initialize default mailers 468c2aa98e2SPeter Wemm */ 469c2aa98e2SPeter Wemm 4703299c2f1SGregory Neil Shapiro static void 471c2aa98e2SPeter Wemm setupmailers() 472c2aa98e2SPeter Wemm { 473c2aa98e2SPeter Wemm char buf[100]; 474c2aa98e2SPeter Wemm 47512ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u", 476951742c4SGregory Neil Shapiro sizeof(buf)); 477c2aa98e2SPeter Wemm makemailer(buf); 478c2aa98e2SPeter Wemm 47912ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u", 480951742c4SGregory Neil Shapiro sizeof(buf)); 481c2aa98e2SPeter Wemm makemailer(buf); 482c2aa98e2SPeter Wemm 48312ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u", 484951742c4SGregory Neil Shapiro sizeof(buf)); 485c2aa98e2SPeter Wemm makemailer(buf); 4863299c2f1SGregory Neil Shapiro initerrmailers(); 487c2aa98e2SPeter Wemm } 48812ed1c7cSGregory Neil Shapiro /* 489c2aa98e2SPeter Wemm ** SETUPMAPS -- set up map classes 490c2aa98e2SPeter Wemm */ 491c2aa98e2SPeter Wemm 492c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \ 493c2aa98e2SPeter Wemm { \ 494c2aa98e2SPeter Wemm extern bool parse __P((MAP *, char *)); \ 495c2aa98e2SPeter Wemm extern bool open __P((MAP *, int)); \ 496c2aa98e2SPeter Wemm extern void close __P((MAP *)); \ 497c2aa98e2SPeter Wemm extern char *lookup __P((MAP *, char *, char **, int *)); \ 498c2aa98e2SPeter Wemm extern void store __P((MAP *, char *, char *)); \ 499c2aa98e2SPeter Wemm s = stab(name, ST_MAPCLASS, ST_ENTER); \ 500c2aa98e2SPeter Wemm s->s_mapclass.map_cname = name; \ 501c2aa98e2SPeter Wemm s->s_mapclass.map_ext = ext; \ 502c2aa98e2SPeter Wemm s->s_mapclass.map_cflags = flags; \ 503c2aa98e2SPeter Wemm s->s_mapclass.map_parse = parse; \ 504c2aa98e2SPeter Wemm s->s_mapclass.map_open = open; \ 505c2aa98e2SPeter Wemm s->s_mapclass.map_close = close; \ 506c2aa98e2SPeter Wemm s->s_mapclass.map_lookup = lookup; \ 507c2aa98e2SPeter Wemm s->s_mapclass.map_store = store; \ 508c2aa98e2SPeter Wemm } 509c2aa98e2SPeter Wemm 5103299c2f1SGregory Neil Shapiro static void 511c2aa98e2SPeter Wemm setupmaps() 512c2aa98e2SPeter Wemm { 513c2aa98e2SPeter Wemm register STAB *s; 514c2aa98e2SPeter Wemm 51512ed1c7cSGregory Neil Shapiro #if NEWDB 5167660b554SGregory Neil Shapiro # if DB_VERSION_MAJOR > 1 5177660b554SGregory Neil Shapiro int major_v, minor_v, patch_v; 5187660b554SGregory Neil Shapiro 5197660b554SGregory Neil Shapiro (void) db_version(&major_v, &minor_v, &patch_v); 5207660b554SGregory Neil Shapiro if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR) 5217660b554SGregory Neil Shapiro { 5227660b554SGregory Neil Shapiro errno = 0; 5237660b554SGregory Neil Shapiro syserr("Berkeley DB version mismatch: compiled against %d.%d.%d, run-time linked against %d.%d.%d", 5247660b554SGregory Neil Shapiro DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH, 5257660b554SGregory Neil Shapiro major_v, minor_v, patch_v); 5267660b554SGregory Neil Shapiro } 5277660b554SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR > 1 */ 5287660b554SGregory Neil Shapiro 529c2aa98e2SPeter Wemm MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, 530c2aa98e2SPeter Wemm map_parseargs, hash_map_open, db_map_close, 531c2aa98e2SPeter Wemm db_map_lookup, db_map_store); 532c2aa98e2SPeter Wemm 533c2aa98e2SPeter Wemm MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE, 534c2aa98e2SPeter Wemm map_parseargs, bt_map_open, db_map_close, 535c2aa98e2SPeter Wemm db_map_lookup, db_map_store); 5363299c2f1SGregory Neil Shapiro #endif /* NEWDB */ 537c2aa98e2SPeter Wemm 53812ed1c7cSGregory Neil Shapiro #if NDBM 539c2aa98e2SPeter Wemm MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE, 540c2aa98e2SPeter Wemm map_parseargs, ndbm_map_open, ndbm_map_close, 541c2aa98e2SPeter Wemm ndbm_map_lookup, ndbm_map_store); 5423299c2f1SGregory Neil Shapiro #endif /* NDBM */ 543c2aa98e2SPeter Wemm 54412ed1c7cSGregory Neil Shapiro #if NIS 545c2aa98e2SPeter Wemm MAPDEF("nis", NULL, MCF_ALIASOK, 546c2aa98e2SPeter Wemm map_parseargs, nis_map_open, null_map_close, 547c2aa98e2SPeter Wemm nis_map_lookup, null_map_store); 5483299c2f1SGregory Neil Shapiro #endif /* NIS */ 549c2aa98e2SPeter Wemm 55012ed1c7cSGregory Neil Shapiro #if NISPLUS 551c2aa98e2SPeter Wemm MAPDEF("nisplus", NULL, MCF_ALIASOK, 552c2aa98e2SPeter Wemm map_parseargs, nisplus_map_open, null_map_close, 553c2aa98e2SPeter Wemm nisplus_map_lookup, null_map_store); 5543299c2f1SGregory Neil Shapiro #endif /* NISPLUS */ 5553299c2f1SGregory Neil Shapiro 55612ed1c7cSGregory Neil Shapiro #if LDAPMAP 55712ed1c7cSGregory Neil Shapiro MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST, 5583299c2f1SGregory Neil Shapiro ldapmap_parseargs, ldapmap_open, ldapmap_close, 5593299c2f1SGregory Neil Shapiro ldapmap_lookup, null_map_store); 5603299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */ 5613299c2f1SGregory Neil Shapiro 56212ed1c7cSGregory Neil Shapiro #if PH_MAP 56312ed1c7cSGregory Neil Shapiro MAPDEF("ph", NULL, MCF_NOTPERSIST, 5643299c2f1SGregory Neil Shapiro ph_map_parseargs, ph_map_open, ph_map_close, 5653299c2f1SGregory Neil Shapiro ph_map_lookup, null_map_store); 5663299c2f1SGregory Neil Shapiro #endif /* PH_MAP */ 5673299c2f1SGregory Neil Shapiro 5683299c2f1SGregory Neil Shapiro #if MAP_NSD 5693299c2f1SGregory Neil Shapiro /* IRIX 6.5 nsd support */ 5703299c2f1SGregory Neil Shapiro MAPDEF("nsd", NULL, MCF_ALIASOK, 5713299c2f1SGregory Neil Shapiro map_parseargs, null_map_open, null_map_close, 5723299c2f1SGregory Neil Shapiro nsd_map_lookup, null_map_store); 5733299c2f1SGregory Neil Shapiro #endif /* MAP_NSD */ 574c2aa98e2SPeter Wemm 57512ed1c7cSGregory Neil Shapiro #if HESIOD 576c2aa98e2SPeter Wemm MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY, 57712ed1c7cSGregory Neil Shapiro map_parseargs, hes_map_open, hes_map_close, 578c2aa98e2SPeter Wemm hes_map_lookup, null_map_store); 5793299c2f1SGregory Neil Shapiro #endif /* HESIOD */ 580c2aa98e2SPeter Wemm 581c2aa98e2SPeter Wemm #if NETINFO 582c2aa98e2SPeter Wemm MAPDEF("netinfo", NULL, MCF_ALIASOK, 583c2aa98e2SPeter Wemm map_parseargs, ni_map_open, null_map_close, 584c2aa98e2SPeter Wemm ni_map_lookup, null_map_store); 5853299c2f1SGregory Neil Shapiro #endif /* NETINFO */ 586c2aa98e2SPeter Wemm 587c2aa98e2SPeter Wemm #if 0 588c2aa98e2SPeter Wemm MAPDEF("dns", NULL, 0, 589c2aa98e2SPeter Wemm dns_map_init, null_map_open, null_map_close, 590c2aa98e2SPeter Wemm dns_map_lookup, null_map_store); 5913299c2f1SGregory Neil Shapiro #endif /* 0 */ 592c2aa98e2SPeter Wemm 593c2aa98e2SPeter Wemm #if NAMED_BIND 59412ed1c7cSGregory Neil Shapiro # if DNSMAP 595320f00e7SGregory Neil Shapiro # if _FFR_DNSMAP_ALIASABLE 596320f00e7SGregory Neil Shapiro MAPDEF("dns", NULL, MCF_ALIASOK, 597320f00e7SGregory Neil Shapiro dns_map_parseargs, dns_map_open, null_map_close, 598320f00e7SGregory Neil Shapiro dns_map_lookup, null_map_store); 599320f00e7SGregory Neil Shapiro # else /* _FFR_DNSMAP_ALIASABLE */ 60012ed1c7cSGregory Neil Shapiro MAPDEF("dns", NULL, 0, 60112ed1c7cSGregory Neil Shapiro dns_map_parseargs, dns_map_open, null_map_close, 60212ed1c7cSGregory Neil Shapiro dns_map_lookup, null_map_store); 603320f00e7SGregory Neil Shapiro # endif /* _FFR_DNSMAP_ALIASABLE */ 60412ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */ 60512ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */ 60612ed1c7cSGregory Neil Shapiro 60712ed1c7cSGregory Neil Shapiro #if NAMED_BIND 608c2aa98e2SPeter Wemm /* best MX DNS lookup */ 609c2aa98e2SPeter Wemm MAPDEF("bestmx", NULL, MCF_OPTFILE, 610c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 611c2aa98e2SPeter Wemm bestmx_map_lookup, null_map_store); 6123299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */ 613c2aa98e2SPeter Wemm 614c2aa98e2SPeter Wemm MAPDEF("host", NULL, 0, 615c2aa98e2SPeter Wemm host_map_init, null_map_open, null_map_close, 616c2aa98e2SPeter Wemm host_map_lookup, null_map_store); 617c2aa98e2SPeter Wemm 618c2aa98e2SPeter Wemm MAPDEF("text", NULL, MCF_ALIASOK, 619c2aa98e2SPeter Wemm map_parseargs, text_map_open, null_map_close, 620c2aa98e2SPeter Wemm text_map_lookup, null_map_store); 621c2aa98e2SPeter Wemm 622c2aa98e2SPeter Wemm MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY, 623c2aa98e2SPeter Wemm map_parseargs, stab_map_open, null_map_close, 624c2aa98e2SPeter Wemm stab_map_lookup, stab_map_store); 625c2aa98e2SPeter Wemm 626c2aa98e2SPeter Wemm MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE, 627c2aa98e2SPeter Wemm map_parseargs, impl_map_open, impl_map_close, 628c2aa98e2SPeter Wemm impl_map_lookup, impl_map_store); 629c2aa98e2SPeter Wemm 630c2aa98e2SPeter Wemm /* access to system passwd file */ 631c2aa98e2SPeter Wemm MAPDEF("user", NULL, MCF_OPTFILE, 632c2aa98e2SPeter Wemm map_parseargs, user_map_open, null_map_close, 633c2aa98e2SPeter Wemm user_map_lookup, null_map_store); 634c2aa98e2SPeter Wemm 635c2aa98e2SPeter Wemm /* dequote map */ 636c2aa98e2SPeter Wemm MAPDEF("dequote", NULL, 0, 637c2aa98e2SPeter Wemm dequote_init, null_map_open, null_map_close, 638c2aa98e2SPeter Wemm dequote_map, null_map_store); 639c2aa98e2SPeter Wemm 64012ed1c7cSGregory Neil Shapiro #if MAP_REGEX 641c2aa98e2SPeter Wemm MAPDEF("regex", NULL, 0, 642c2aa98e2SPeter Wemm regex_map_init, null_map_open, null_map_close, 643c2aa98e2SPeter Wemm regex_map_lookup, null_map_store); 6443299c2f1SGregory Neil Shapiro #endif /* MAP_REGEX */ 645c2aa98e2SPeter Wemm 646c2aa98e2SPeter Wemm #if USERDB 647c2aa98e2SPeter Wemm /* user database */ 648c2aa98e2SPeter Wemm MAPDEF("userdb", ".db", 0, 649c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 650c2aa98e2SPeter Wemm udb_map_lookup, null_map_store); 6513299c2f1SGregory Neil Shapiro #endif /* USERDB */ 652c2aa98e2SPeter Wemm 653c2aa98e2SPeter Wemm /* arbitrary programs */ 654c2aa98e2SPeter Wemm MAPDEF("program", NULL, MCF_ALIASOK, 655c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 656c2aa98e2SPeter Wemm prog_map_lookup, null_map_store); 657c2aa98e2SPeter Wemm 658c2aa98e2SPeter Wemm /* sequenced maps */ 659c2aa98e2SPeter Wemm MAPDEF("sequence", NULL, MCF_ALIASOK, 660c2aa98e2SPeter Wemm seq_map_parse, null_map_open, null_map_close, 661c2aa98e2SPeter Wemm seq_map_lookup, seq_map_store); 662c2aa98e2SPeter Wemm 663c2aa98e2SPeter Wemm /* switched interface to sequenced maps */ 664c2aa98e2SPeter Wemm MAPDEF("switch", NULL, MCF_ALIASOK, 665c2aa98e2SPeter Wemm map_parseargs, switch_map_open, null_map_close, 666c2aa98e2SPeter Wemm seq_map_lookup, seq_map_store); 667c2aa98e2SPeter Wemm 668c2aa98e2SPeter Wemm /* null map lookup -- really for internal use only */ 669c2aa98e2SPeter Wemm MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE, 670c2aa98e2SPeter Wemm map_parseargs, null_map_open, null_map_close, 671c2aa98e2SPeter Wemm null_map_lookup, null_map_store); 672c2aa98e2SPeter Wemm 673c2aa98e2SPeter Wemm /* syslog map -- logs information to syslog */ 674c2aa98e2SPeter Wemm MAPDEF("syslog", NULL, 0, 675c2aa98e2SPeter Wemm syslog_map_parseargs, null_map_open, null_map_close, 676c2aa98e2SPeter Wemm syslog_map_lookup, null_map_store); 6773299c2f1SGregory Neil Shapiro 6783299c2f1SGregory Neil Shapiro /* macro storage map -- rulesets can set macros */ 6793299c2f1SGregory Neil Shapiro MAPDEF("macro", NULL, 0, 6803299c2f1SGregory Neil Shapiro dequote_init, null_map_open, null_map_close, 6813299c2f1SGregory Neil Shapiro macro_map_lookup, null_map_store); 6823299c2f1SGregory Neil Shapiro 6833299c2f1SGregory Neil Shapiro /* arithmetic map -- add/subtract/compare */ 6843299c2f1SGregory Neil Shapiro MAPDEF("arith", NULL, 0, 6853299c2f1SGregory Neil Shapiro dequote_init, null_map_open, null_map_close, 6863299c2f1SGregory Neil Shapiro arith_map_lookup, null_map_store); 6873299c2f1SGregory Neil Shapiro 6885dd76dd0SGregory Neil Shapiro /* "arpa" map -- IP -> arpa */ 6895dd76dd0SGregory Neil Shapiro MAPDEF("arpa", NULL, 0, 6905dd76dd0SGregory Neil Shapiro dequote_init, null_map_open, null_map_close, 6915dd76dd0SGregory Neil Shapiro arpa_map_lookup, null_map_store); 6925dd76dd0SGregory Neil Shapiro 693bfb62e91SGregory Neil Shapiro #if SOCKETMAP 694bfb62e91SGregory Neil Shapiro /* arbitrary daemons */ 695bfb62e91SGregory Neil Shapiro MAPDEF("socket", NULL, MCF_ALIASOK, 696bfb62e91SGregory Neil Shapiro map_parseargs, socket_map_open, socket_map_close, 697bfb62e91SGregory Neil Shapiro socket_map_lookup, null_map_store); 698bfb62e91SGregory Neil Shapiro #endif /* SOCKETMAP */ 699bfb62e91SGregory Neil Shapiro 700951742c4SGregory Neil Shapiro #if _FFR_DPRINTF_MAP 701951742c4SGregory Neil Shapiro /* dprintf map -- logs information to syslog */ 702951742c4SGregory Neil Shapiro MAPDEF("dprintf", NULL, 0, 703951742c4SGregory Neil Shapiro dprintf_map_parseargs, null_map_open, null_map_close, 704951742c4SGregory Neil Shapiro dprintf_map_lookup, null_map_store); 705951742c4SGregory Neil Shapiro #endif /* _FFR_DPRINTF_MAP */ 706951742c4SGregory Neil Shapiro 7073299c2f1SGregory Neil Shapiro if (tTd(38, 2)) 7083299c2f1SGregory Neil Shapiro { 7093299c2f1SGregory Neil Shapiro /* bogus map -- always return tempfail */ 7103299c2f1SGregory Neil Shapiro MAPDEF("bogus", NULL, MCF_ALIASOK|MCF_OPTFILE, 7113299c2f1SGregory Neil Shapiro map_parseargs, null_map_open, null_map_close, 7123299c2f1SGregory Neil Shapiro bogus_map_lookup, null_map_store); 7133299c2f1SGregory Neil Shapiro } 714c2aa98e2SPeter Wemm } 715c2aa98e2SPeter Wemm 716c2aa98e2SPeter Wemm #undef MAPDEF 71712ed1c7cSGregory Neil Shapiro /* 718c2aa98e2SPeter Wemm ** INITHOSTMAPS -- initial host-dependent maps 719c2aa98e2SPeter Wemm ** 720c2aa98e2SPeter Wemm ** This should act as an interface to any local service switch 721c2aa98e2SPeter Wemm ** provided by the host operating system. 722c2aa98e2SPeter Wemm ** 723c2aa98e2SPeter Wemm ** Parameters: 724c2aa98e2SPeter Wemm ** none 725c2aa98e2SPeter Wemm ** 726c2aa98e2SPeter Wemm ** Returns: 727c2aa98e2SPeter Wemm ** none 728c2aa98e2SPeter Wemm ** 729c2aa98e2SPeter Wemm ** Side Effects: 730c2aa98e2SPeter Wemm ** Should define maps "host" and "users" as necessary 731c2aa98e2SPeter Wemm ** for this OS. If they are not defined, they will get 732c2aa98e2SPeter Wemm ** a default value later. It should check to make sure 733c2aa98e2SPeter Wemm ** they are not defined first, since it's possible that 734c2aa98e2SPeter Wemm ** the config file has provided an override. 735c2aa98e2SPeter Wemm */ 736c2aa98e2SPeter Wemm 737c2aa98e2SPeter Wemm void 738c2aa98e2SPeter Wemm inithostmaps() 739c2aa98e2SPeter Wemm { 740c2aa98e2SPeter Wemm register int i; 741c2aa98e2SPeter Wemm int nmaps; 742c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 743c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 744c2aa98e2SPeter Wemm char buf[MAXLINE]; 745c2aa98e2SPeter Wemm 746c2aa98e2SPeter Wemm /* 747c2aa98e2SPeter Wemm ** Make sure we have a host map. 748c2aa98e2SPeter Wemm */ 749c2aa98e2SPeter Wemm 750c2aa98e2SPeter Wemm if (stab("host", ST_MAP, ST_FIND) == NULL) 751c2aa98e2SPeter Wemm { 752c2aa98e2SPeter Wemm /* user didn't initialize: set up host map */ 753951742c4SGregory Neil Shapiro (void) sm_strlcpy(buf, "host host", sizeof(buf)); 754c2aa98e2SPeter Wemm #if NAMED_BIND 755c2aa98e2SPeter Wemm if (ConfigLevel >= 2) 756951742c4SGregory Neil Shapiro (void) sm_strlcat(buf, " -a. -D", sizeof(buf)); 7573299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */ 758c2aa98e2SPeter Wemm (void) makemapentry(buf); 759c2aa98e2SPeter Wemm } 760c2aa98e2SPeter Wemm 761c2aa98e2SPeter Wemm /* 762c2aa98e2SPeter Wemm ** Set up default aliases maps 763c2aa98e2SPeter Wemm */ 764c2aa98e2SPeter Wemm 765c2aa98e2SPeter Wemm nmaps = switch_map_find("aliases", maptype, mapreturn); 766c2aa98e2SPeter Wemm for (i = 0; i < nmaps; i++) 767c2aa98e2SPeter Wemm { 768c2aa98e2SPeter Wemm if (strcmp(maptype[i], "files") == 0 && 769c2aa98e2SPeter Wemm stab("aliases.files", ST_MAP, ST_FIND) == NULL) 770c2aa98e2SPeter Wemm { 77112ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.files null", 772951742c4SGregory Neil Shapiro sizeof(buf)); 773c2aa98e2SPeter Wemm (void) makemapentry(buf); 774c2aa98e2SPeter Wemm } 77512ed1c7cSGregory Neil Shapiro #if NISPLUS 776c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nisplus") == 0 && 777c2aa98e2SPeter Wemm stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) 778c2aa98e2SPeter Wemm { 77912ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir", 780951742c4SGregory Neil Shapiro sizeof(buf)); 781c2aa98e2SPeter Wemm (void) makemapentry(buf); 782c2aa98e2SPeter Wemm } 7833299c2f1SGregory Neil Shapiro #endif /* NISPLUS */ 78412ed1c7cSGregory Neil Shapiro #if NIS 785c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "nis") == 0 && 786c2aa98e2SPeter Wemm stab("aliases.nis", ST_MAP, ST_FIND) == NULL) 787c2aa98e2SPeter Wemm { 78812ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.nis nis mail.aliases", 789951742c4SGregory Neil Shapiro sizeof(buf)); 790c2aa98e2SPeter Wemm (void) makemapentry(buf); 791c2aa98e2SPeter Wemm } 7923299c2f1SGregory Neil Shapiro #endif /* NIS */ 7933299c2f1SGregory Neil Shapiro #if NETINFO 794c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "netinfo") == 0 && 795c2aa98e2SPeter Wemm stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) 796c2aa98e2SPeter Wemm { 79712ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases", 798951742c4SGregory Neil Shapiro sizeof(buf)); 799c2aa98e2SPeter Wemm (void) makemapentry(buf); 800c2aa98e2SPeter Wemm } 8013299c2f1SGregory Neil Shapiro #endif /* NETINFO */ 80212ed1c7cSGregory Neil Shapiro #if HESIOD 803c2aa98e2SPeter Wemm else if (strcmp(maptype[i], "hesiod") == 0 && 804c2aa98e2SPeter Wemm stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) 805c2aa98e2SPeter Wemm { 80612ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases", 807951742c4SGregory Neil Shapiro sizeof(buf)); 808c2aa98e2SPeter Wemm (void) makemapentry(buf); 809c2aa98e2SPeter Wemm } 8103299c2f1SGregory Neil Shapiro #endif /* HESIOD */ 811951742c4SGregory Neil Shapiro #if LDAPMAP && defined(SUN_EXTENSIONS) && \ 812951742c4SGregory Neil Shapiro defined(SUN_SIMPLIFIED_LDAP) && HASLDAPGETALIASBYNAME 813951742c4SGregory Neil Shapiro else if (strcmp(maptype[i], "ldap") == 0 && 814951742c4SGregory Neil Shapiro stab("aliases.ldap", ST_MAP, ST_FIND) == NULL) 815951742c4SGregory Neil Shapiro { 8169bd497b8SGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup", 817951742c4SGregory Neil Shapiro sizeof buf); 818951742c4SGregory Neil Shapiro (void) makemapentry(buf); 819951742c4SGregory Neil Shapiro } 820951742c4SGregory Neil Shapiro #endif /* LDAPMAP && defined(SUN_EXTENSIONS) && ... */ 821c2aa98e2SPeter Wemm } 822c2aa98e2SPeter Wemm if (stab("aliases", ST_MAP, ST_FIND) == NULL) 823c2aa98e2SPeter Wemm { 824951742c4SGregory Neil Shapiro (void) sm_strlcpy(buf, "aliases switch aliases", sizeof(buf)); 825c2aa98e2SPeter Wemm (void) makemapentry(buf); 826c2aa98e2SPeter Wemm } 827951742c4SGregory Neil Shapiro } 828c2aa98e2SPeter Wemm 82912ed1c7cSGregory Neil Shapiro /* 830c2aa98e2SPeter Wemm ** SWITCH_MAP_FIND -- find the list of types associated with a map 831c2aa98e2SPeter Wemm ** 832c2aa98e2SPeter Wemm ** This is the system-dependent interface to the service switch. 833c2aa98e2SPeter Wemm ** 834c2aa98e2SPeter Wemm ** Parameters: 835c2aa98e2SPeter Wemm ** service -- the name of the service of interest. 836c2aa98e2SPeter Wemm ** maptype -- an out-array of strings containing the types 837c2aa98e2SPeter Wemm ** of access to use for this service. There can 838c2aa98e2SPeter Wemm ** be at most MAXMAPSTACK types for a single service. 839c2aa98e2SPeter Wemm ** mapreturn -- an out-array of return information bitmaps 840c2aa98e2SPeter Wemm ** for the map. 841c2aa98e2SPeter Wemm ** 842c2aa98e2SPeter Wemm ** Returns: 843c2aa98e2SPeter Wemm ** The number of map types filled in, or -1 for failure. 8443299c2f1SGregory Neil Shapiro ** 8453299c2f1SGregory Neil Shapiro ** Side effects: 8463299c2f1SGregory Neil Shapiro ** Preserves errno so nothing in the routine clobbers it. 847c2aa98e2SPeter Wemm */ 848c2aa98e2SPeter Wemm 849c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) 850c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_ 8513299c2f1SGregory Neil Shapiro #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */ 852c2aa98e2SPeter Wemm 85312ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH 85412ed1c7cSGregory Neil Shapiro # ifdef __hpux 85512ed1c7cSGregory Neil Shapiro # define _USE_SUN_NSSWITCH_ 85612ed1c7cSGregory Neil Shapiro # endif /* __hpux */ 85712ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */ 85812ed1c7cSGregory Neil Shapiro 859c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_ 860c2aa98e2SPeter Wemm # include <nsswitch.h> 8613299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */ 862c2aa98e2SPeter Wemm 863c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha)) 864c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_ 8653299c2f1SGregory Neil Shapiro #endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */ 866c2aa98e2SPeter Wemm 867c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_ 868c2aa98e2SPeter Wemm # include <sys/svcinfo.h> 8693299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */ 870c2aa98e2SPeter Wemm 871c2aa98e2SPeter Wemm int 872c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn) 873c2aa98e2SPeter Wemm char *service; 874c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 875c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 876c2aa98e2SPeter Wemm { 877c46d91b7SGregory Neil Shapiro int svcno = 0; 8783299c2f1SGregory Neil Shapiro int save_errno = errno; 879c2aa98e2SPeter Wemm 880c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_ 881c2aa98e2SPeter Wemm struct __nsw_switchconfig *nsw_conf; 882c2aa98e2SPeter Wemm enum __nsw_parse_err pserr; 883c2aa98e2SPeter Wemm struct __nsw_lookup *lk; 884c2aa98e2SPeter Wemm static struct __nsw_lookup lkp0 = 885c2aa98e2SPeter Wemm { "files", {1, 0, 0, 0}, NULL, NULL }; 886c2aa98e2SPeter Wemm static struct __nsw_switchconfig lkp_default = 887c2aa98e2SPeter Wemm { 0, "sendmail", 3, &lkp0 }; 888c2aa98e2SPeter Wemm 889c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 890c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 891c2aa98e2SPeter Wemm 892c2aa98e2SPeter Wemm if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL) 893c2aa98e2SPeter Wemm lk = lkp_default.lookups; 894c2aa98e2SPeter Wemm else 895c2aa98e2SPeter Wemm lk = nsw_conf->lookups; 896c2aa98e2SPeter Wemm svcno = 0; 897c46d91b7SGregory Neil Shapiro while (lk != NULL && svcno < MAXMAPSTACK) 898c2aa98e2SPeter Wemm { 899c2aa98e2SPeter Wemm maptype[svcno] = lk->service_name; 900c2aa98e2SPeter Wemm if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN) 901c2aa98e2SPeter Wemm mapreturn[MA_NOTFOUND] |= 1 << svcno; 902c2aa98e2SPeter Wemm if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN) 903c2aa98e2SPeter Wemm mapreturn[MA_TRYAGAIN] |= 1 << svcno; 904c2aa98e2SPeter Wemm if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN) 905c2aa98e2SPeter Wemm mapreturn[MA_TRYAGAIN] |= 1 << svcno; 906c2aa98e2SPeter Wemm svcno++; 907c2aa98e2SPeter Wemm lk = lk->next; 908c2aa98e2SPeter Wemm } 9093299c2f1SGregory Neil Shapiro errno = save_errno; 910c2aa98e2SPeter Wemm return svcno; 9113299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */ 912c2aa98e2SPeter Wemm 913c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_ 914c2aa98e2SPeter Wemm struct svcinfo *svcinfo; 915c2aa98e2SPeter Wemm int svc; 916c2aa98e2SPeter Wemm 917c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 918c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 919c2aa98e2SPeter Wemm 920c2aa98e2SPeter Wemm svcinfo = getsvc(); 921c2aa98e2SPeter Wemm if (svcinfo == NULL) 922c2aa98e2SPeter Wemm goto punt; 923c2aa98e2SPeter Wemm if (strcmp(service, "hosts") == 0) 924c2aa98e2SPeter Wemm svc = SVC_HOSTS; 925c2aa98e2SPeter Wemm else if (strcmp(service, "aliases") == 0) 926c2aa98e2SPeter Wemm svc = SVC_ALIASES; 927c2aa98e2SPeter Wemm else if (strcmp(service, "passwd") == 0) 928c2aa98e2SPeter Wemm svc = SVC_PASSWD; 929c2aa98e2SPeter Wemm else 9303299c2f1SGregory Neil Shapiro { 9313299c2f1SGregory Neil Shapiro errno = save_errno; 932c2aa98e2SPeter Wemm return -1; 9333299c2f1SGregory Neil Shapiro } 934c46d91b7SGregory Neil Shapiro for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++) 935c2aa98e2SPeter Wemm { 936c2aa98e2SPeter Wemm switch (svcinfo->svcpath[svc][svcno]) 937c2aa98e2SPeter Wemm { 938c2aa98e2SPeter Wemm case SVC_LOCAL: 939c2aa98e2SPeter Wemm maptype[svcno] = "files"; 940c2aa98e2SPeter Wemm break; 941c2aa98e2SPeter Wemm 942c2aa98e2SPeter Wemm case SVC_YP: 943c2aa98e2SPeter Wemm maptype[svcno] = "nis"; 944c2aa98e2SPeter Wemm break; 945c2aa98e2SPeter Wemm 946c2aa98e2SPeter Wemm case SVC_BIND: 947c2aa98e2SPeter Wemm maptype[svcno] = "dns"; 948c2aa98e2SPeter Wemm break; 949c2aa98e2SPeter Wemm 950c2aa98e2SPeter Wemm # ifdef SVC_HESIOD 951c2aa98e2SPeter Wemm case SVC_HESIOD: 952c2aa98e2SPeter Wemm maptype[svcno] = "hesiod"; 953c2aa98e2SPeter Wemm break; 9543299c2f1SGregory Neil Shapiro # endif /* SVC_HESIOD */ 955c2aa98e2SPeter Wemm 956c2aa98e2SPeter Wemm case SVC_LAST: 9573299c2f1SGregory Neil Shapiro errno = save_errno; 958c2aa98e2SPeter Wemm return svcno; 959c2aa98e2SPeter Wemm } 960c2aa98e2SPeter Wemm } 9613299c2f1SGregory Neil Shapiro errno = save_errno; 962c2aa98e2SPeter Wemm return svcno; 9633299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */ 964c2aa98e2SPeter Wemm 965c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) 966c2aa98e2SPeter Wemm /* 967c2aa98e2SPeter Wemm ** Fall-back mechanism. 968c2aa98e2SPeter Wemm */ 969c2aa98e2SPeter Wemm 970c2aa98e2SPeter Wemm STAB *st; 97112ed1c7cSGregory Neil Shapiro static time_t servicecachetime; /* time service switch was cached */ 972c2aa98e2SPeter Wemm time_t now = curtime(); 973c2aa98e2SPeter Wemm 974c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 975c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 976c2aa98e2SPeter Wemm 97712ed1c7cSGregory Neil Shapiro if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge) 978c2aa98e2SPeter Wemm { 979c2aa98e2SPeter Wemm /* (re)read service switch */ 98012ed1c7cSGregory Neil Shapiro register SM_FILE_T *fp; 9813299c2f1SGregory Neil Shapiro long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK; 982c2aa98e2SPeter Wemm 9833299c2f1SGregory Neil Shapiro if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR, 9843299c2f1SGregory Neil Shapiro DontBlameSendmail)) 985c2aa98e2SPeter Wemm sff |= SFF_NOWLINK; 986c2aa98e2SPeter Wemm 987c2aa98e2SPeter Wemm if (ConfigFileRead) 98812ed1c7cSGregory Neil Shapiro servicecachetime = now; 989c2aa98e2SPeter Wemm fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff); 990c2aa98e2SPeter Wemm if (fp != NULL) 991c2aa98e2SPeter Wemm { 992c2aa98e2SPeter Wemm char buf[MAXLINE]; 993c2aa98e2SPeter Wemm 99412ed1c7cSGregory Neil Shapiro while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, 995552d4955SGregory Neil Shapiro sizeof(buf)) >= 0) 996c2aa98e2SPeter Wemm { 997c2aa98e2SPeter Wemm register char *p; 998c2aa98e2SPeter Wemm 999c2aa98e2SPeter Wemm p = strpbrk(buf, "#\n"); 1000c2aa98e2SPeter Wemm if (p != NULL) 1001c2aa98e2SPeter Wemm *p = '\0'; 10029bd497b8SGregory Neil Shapiro #ifndef SM_NSSWITCH_DELIMS 10039bd497b8SGregory Neil Shapiro # define SM_NSSWITCH_DELIMS " \t" 10049bd497b8SGregory Neil Shapiro #endif /* SM_NSSWITCH_DELIMS */ 10059bd497b8SGregory Neil Shapiro p = strpbrk(buf, SM_NSSWITCH_DELIMS); 1006c2aa98e2SPeter Wemm if (p != NULL) 1007c2aa98e2SPeter Wemm *p++ = '\0'; 1008c2aa98e2SPeter Wemm if (buf[0] == '\0') 1009c2aa98e2SPeter Wemm continue; 101076b7bf71SPeter Wemm if (p == NULL) 101176b7bf71SPeter Wemm { 101276b7bf71SPeter Wemm sm_syslog(LOG_ERR, NOQID, 101376b7bf71SPeter Wemm "Bad line on %.100s: %.100s", 101476b7bf71SPeter Wemm ServiceSwitchFile, 101576b7bf71SPeter Wemm buf); 101676b7bf71SPeter Wemm continue; 101776b7bf71SPeter Wemm } 10189bd497b8SGregory Neil Shapiro while (isascii(*p) && isspace(*p)) 1019c2aa98e2SPeter Wemm p++; 1020c2aa98e2SPeter Wemm if (*p == '\0') 1021c2aa98e2SPeter Wemm continue; 1022c2aa98e2SPeter Wemm 1023c2aa98e2SPeter Wemm /* 1024c2aa98e2SPeter Wemm ** Find/allocate space for this service entry. 1025c2aa98e2SPeter Wemm ** Space for all of the service strings 1026c2aa98e2SPeter Wemm ** are allocated at once. This means 1027c2aa98e2SPeter Wemm ** that we only have to free the first 1028c2aa98e2SPeter Wemm ** one to free all of them. 1029c2aa98e2SPeter Wemm */ 1030c2aa98e2SPeter Wemm 1031c2aa98e2SPeter Wemm st = stab(buf, ST_SERVICE, ST_ENTER); 1032c2aa98e2SPeter Wemm if (st->s_service[0] != NULL) 103312ed1c7cSGregory Neil Shapiro sm_free((void *) st->s_service[0]); /* XXX */ 1034c2aa98e2SPeter Wemm p = newstr(p); 1035c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPSTACK; ) 1036c2aa98e2SPeter Wemm { 1037c2aa98e2SPeter Wemm if (*p == '\0') 1038c2aa98e2SPeter Wemm break; 1039c2aa98e2SPeter Wemm st->s_service[svcno++] = p; 1040c2aa98e2SPeter Wemm p = strpbrk(p, " \t"); 1041c2aa98e2SPeter Wemm if (p == NULL) 1042c2aa98e2SPeter Wemm break; 1043c2aa98e2SPeter Wemm *p++ = '\0'; 10449bd497b8SGregory Neil Shapiro while (isascii(*p) && isspace(*p)) 1045c2aa98e2SPeter Wemm p++; 1046c2aa98e2SPeter Wemm } 1047c2aa98e2SPeter Wemm if (svcno < MAXMAPSTACK) 1048c2aa98e2SPeter Wemm st->s_service[svcno] = NULL; 1049c2aa98e2SPeter Wemm } 105012ed1c7cSGregory Neil Shapiro (void) sm_io_close(fp, SM_TIME_DEFAULT); 1051c2aa98e2SPeter Wemm } 1052c2aa98e2SPeter Wemm } 1053c2aa98e2SPeter Wemm 1054c2aa98e2SPeter Wemm /* look up entry in cache */ 1055c2aa98e2SPeter Wemm st = stab(service, ST_SERVICE, ST_FIND); 1056c2aa98e2SPeter Wemm if (st != NULL && st->s_service[0] != NULL) 1057c2aa98e2SPeter Wemm { 1058c2aa98e2SPeter Wemm /* extract data */ 1059c2aa98e2SPeter Wemm svcno = 0; 1060c2aa98e2SPeter Wemm while (svcno < MAXMAPSTACK) 1061c2aa98e2SPeter Wemm { 1062c2aa98e2SPeter Wemm maptype[svcno] = st->s_service[svcno]; 1063c2aa98e2SPeter Wemm if (maptype[svcno++] == NULL) 1064c2aa98e2SPeter Wemm break; 1065c2aa98e2SPeter Wemm } 10663299c2f1SGregory Neil Shapiro errno = save_errno; 1067c2aa98e2SPeter Wemm return --svcno; 1068c2aa98e2SPeter Wemm } 10693299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */ 1070c2aa98e2SPeter Wemm 1071c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) 1072c2aa98e2SPeter Wemm /* if the service file doesn't work, use an absolute fallback */ 1073c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_ 1074c2aa98e2SPeter Wemm punt: 10753299c2f1SGregory Neil Shapiro # endif /* _USE_DEC_SVC_CONF_ */ 1076c2aa98e2SPeter Wemm for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) 1077c2aa98e2SPeter Wemm mapreturn[svcno] = 0; 1078c2aa98e2SPeter Wemm svcno = 0; 1079c2aa98e2SPeter Wemm if (strcmp(service, "aliases") == 0) 1080c2aa98e2SPeter Wemm { 1081c2aa98e2SPeter Wemm maptype[svcno++] = "files"; 10823299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) 10833299c2f1SGregory Neil Shapiro maptype[svcno++] = "netinfo"; 10843299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */ 1085c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES 108612ed1c7cSGregory Neil Shapiro # if NISPLUS 1087c2aa98e2SPeter Wemm maptype[svcno++] = "nisplus"; 10883299c2f1SGregory Neil Shapiro # endif /* NISPLUS */ 108912ed1c7cSGregory Neil Shapiro # if NIS 1090c2aa98e2SPeter Wemm maptype[svcno++] = "nis"; 10913299c2f1SGregory Neil Shapiro # endif /* NIS */ 10923299c2f1SGregory Neil Shapiro # endif /* AUTO_NIS_ALIASES */ 10933299c2f1SGregory Neil Shapiro errno = save_errno; 1094c2aa98e2SPeter Wemm return svcno; 1095c2aa98e2SPeter Wemm } 1096c2aa98e2SPeter Wemm if (strcmp(service, "hosts") == 0) 1097c2aa98e2SPeter Wemm { 1098c2aa98e2SPeter Wemm # if NAMED_BIND 1099c2aa98e2SPeter Wemm maptype[svcno++] = "dns"; 11003299c2f1SGregory Neil Shapiro # else /* NAMED_BIND */ 1101c2aa98e2SPeter Wemm # if defined(sun) && !defined(BSD) 1102c2aa98e2SPeter Wemm /* SunOS */ 1103c2aa98e2SPeter Wemm maptype[svcno++] = "nis"; 11043299c2f1SGregory Neil Shapiro # endif /* defined(sun) && !defined(BSD) */ 11053299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */ 11063299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) 11073299c2f1SGregory Neil Shapiro maptype[svcno++] = "netinfo"; 11083299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */ 1109c2aa98e2SPeter Wemm maptype[svcno++] = "files"; 11103299c2f1SGregory Neil Shapiro errno = save_errno; 1111c2aa98e2SPeter Wemm return svcno; 1112c2aa98e2SPeter Wemm } 11133299c2f1SGregory Neil Shapiro errno = save_errno; 1114c2aa98e2SPeter Wemm return -1; 11153299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) */ 1116c2aa98e2SPeter Wemm } 111712ed1c7cSGregory Neil Shapiro /* 1118c2aa98e2SPeter Wemm ** USERNAME -- return the user id of the logged in user. 1119c2aa98e2SPeter Wemm ** 1120c2aa98e2SPeter Wemm ** Parameters: 1121c2aa98e2SPeter Wemm ** none. 1122c2aa98e2SPeter Wemm ** 1123c2aa98e2SPeter Wemm ** Returns: 1124c2aa98e2SPeter Wemm ** The login name of the logged in user. 1125c2aa98e2SPeter Wemm ** 1126c2aa98e2SPeter Wemm ** Side Effects: 1127c2aa98e2SPeter Wemm ** none. 1128c2aa98e2SPeter Wemm ** 1129c2aa98e2SPeter Wemm ** Notes: 1130c2aa98e2SPeter Wemm ** The return value is statically allocated. 1131c2aa98e2SPeter Wemm */ 1132c2aa98e2SPeter Wemm 1133c2aa98e2SPeter Wemm char * 1134c2aa98e2SPeter Wemm username() 1135c2aa98e2SPeter Wemm { 1136c2aa98e2SPeter Wemm static char *myname = NULL; 1137c2aa98e2SPeter Wemm extern char *getlogin(); 1138c2aa98e2SPeter Wemm register struct passwd *pw; 1139c2aa98e2SPeter Wemm 1140c2aa98e2SPeter Wemm /* cache the result */ 1141c2aa98e2SPeter Wemm if (myname == NULL) 1142c2aa98e2SPeter Wemm { 1143c2aa98e2SPeter Wemm myname = getlogin(); 1144c2aa98e2SPeter Wemm if (myname == NULL || myname[0] == '\0') 1145c2aa98e2SPeter Wemm { 1146c2aa98e2SPeter Wemm pw = sm_getpwuid(RealUid); 1147c2aa98e2SPeter Wemm if (pw != NULL) 114812ed1c7cSGregory Neil Shapiro myname = pw->pw_name; 1149c2aa98e2SPeter Wemm } 1150c2aa98e2SPeter Wemm else 1151c2aa98e2SPeter Wemm { 1152c2aa98e2SPeter Wemm uid_t uid = RealUid; 1153c2aa98e2SPeter Wemm 1154c2aa98e2SPeter Wemm if ((pw = sm_getpwnam(myname)) == NULL || 1155c2aa98e2SPeter Wemm (uid != 0 && uid != pw->pw_uid)) 1156c2aa98e2SPeter Wemm { 1157c2aa98e2SPeter Wemm pw = sm_getpwuid(uid); 1158c2aa98e2SPeter Wemm if (pw != NULL) 115912ed1c7cSGregory Neil Shapiro myname = pw->pw_name; 1160c2aa98e2SPeter Wemm } 1161c2aa98e2SPeter Wemm } 1162c2aa98e2SPeter Wemm if (myname == NULL || myname[0] == '\0') 1163c2aa98e2SPeter Wemm { 11643299c2f1SGregory Neil Shapiro syserr("554 5.3.0 Who are you?"); 1165c2aa98e2SPeter Wemm myname = "postmaster"; 1166c2aa98e2SPeter Wemm } 116712ed1c7cSGregory Neil Shapiro else if (strpbrk(myname, ",;:/|\"\\") != NULL) 116812ed1c7cSGregory Neil Shapiro myname = addquotes(myname, NULL); 116912ed1c7cSGregory Neil Shapiro else 117012ed1c7cSGregory Neil Shapiro myname = sm_pstrdup_x(myname); 1171c2aa98e2SPeter Wemm } 11723299c2f1SGregory Neil Shapiro return myname; 1173c2aa98e2SPeter Wemm } 117412ed1c7cSGregory Neil Shapiro /* 1175c2aa98e2SPeter Wemm ** TTYPATH -- Get the path of the user's tty 1176c2aa98e2SPeter Wemm ** 1177c2aa98e2SPeter Wemm ** Returns the pathname of the user's tty. Returns NULL if 1178c2aa98e2SPeter Wemm ** the user is not logged in or if s/he has write permission 1179c2aa98e2SPeter Wemm ** denied. 1180c2aa98e2SPeter Wemm ** 1181c2aa98e2SPeter Wemm ** Parameters: 1182c2aa98e2SPeter Wemm ** none 1183c2aa98e2SPeter Wemm ** 1184c2aa98e2SPeter Wemm ** Returns: 1185c2aa98e2SPeter Wemm ** pathname of the user's tty. 1186c2aa98e2SPeter Wemm ** NULL if not logged in or write permission denied. 1187c2aa98e2SPeter Wemm ** 1188c2aa98e2SPeter Wemm ** Side Effects: 1189c2aa98e2SPeter Wemm ** none. 1190c2aa98e2SPeter Wemm ** 1191c2aa98e2SPeter Wemm ** WARNING: 1192c2aa98e2SPeter Wemm ** Return value is in a local buffer. 1193c2aa98e2SPeter Wemm ** 1194c2aa98e2SPeter Wemm ** Called By: 1195c2aa98e2SPeter Wemm ** savemail 1196c2aa98e2SPeter Wemm */ 1197c2aa98e2SPeter Wemm 1198c2aa98e2SPeter Wemm char * 1199c2aa98e2SPeter Wemm ttypath() 1200c2aa98e2SPeter Wemm { 1201c2aa98e2SPeter Wemm struct stat stbuf; 1202c2aa98e2SPeter Wemm register char *pathn; 1203c2aa98e2SPeter Wemm extern char *ttyname(); 1204c2aa98e2SPeter Wemm extern char *getlogin(); 1205c2aa98e2SPeter Wemm 1206c2aa98e2SPeter Wemm /* compute the pathname of the controlling tty */ 1207c2aa98e2SPeter Wemm if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 1208c2aa98e2SPeter Wemm (pathn = ttyname(0)) == NULL) 1209c2aa98e2SPeter Wemm { 1210c2aa98e2SPeter Wemm errno = 0; 12113299c2f1SGregory Neil Shapiro return NULL; 1212c2aa98e2SPeter Wemm } 1213c2aa98e2SPeter Wemm 1214c2aa98e2SPeter Wemm /* see if we have write permission */ 1215c2aa98e2SPeter Wemm if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode)) 1216c2aa98e2SPeter Wemm { 1217c2aa98e2SPeter Wemm errno = 0; 12183299c2f1SGregory Neil Shapiro return NULL; 1219c2aa98e2SPeter Wemm } 1220c2aa98e2SPeter Wemm 1221c2aa98e2SPeter Wemm /* see if the user is logged in */ 1222c2aa98e2SPeter Wemm if (getlogin() == NULL) 12233299c2f1SGregory Neil Shapiro return NULL; 1224c2aa98e2SPeter Wemm 1225c2aa98e2SPeter Wemm /* looks good */ 12263299c2f1SGregory Neil Shapiro return pathn; 1227c2aa98e2SPeter Wemm } 122812ed1c7cSGregory Neil Shapiro /* 1229c2aa98e2SPeter Wemm ** CHECKCOMPAT -- check for From and To person compatible. 1230c2aa98e2SPeter Wemm ** 1231c2aa98e2SPeter Wemm ** This routine can be supplied on a per-installation basis 1232c2aa98e2SPeter Wemm ** to determine whether a person is allowed to send a message. 1233c2aa98e2SPeter Wemm ** This allows restriction of certain types of internet 1234c2aa98e2SPeter Wemm ** forwarding or registration of users. 1235c2aa98e2SPeter Wemm ** 1236c2aa98e2SPeter Wemm ** If the hosts are found to be incompatible, an error 1237c2aa98e2SPeter Wemm ** message should be given using "usrerr" and an EX_ code 1238c2aa98e2SPeter Wemm ** should be returned. You can also set to->q_status to 1239c2aa98e2SPeter Wemm ** a DSN-style status code. 1240c2aa98e2SPeter Wemm ** 1241c2aa98e2SPeter Wemm ** EF_NO_BODY_RETN can be set in e->e_flags to suppress the 1242c2aa98e2SPeter Wemm ** body during the return-to-sender function; this should be done 1243c2aa98e2SPeter Wemm ** on huge messages. This bit may already be set by the ESMTP 1244c2aa98e2SPeter Wemm ** protocol. 1245c2aa98e2SPeter Wemm ** 1246c2aa98e2SPeter Wemm ** Parameters: 1247c2aa98e2SPeter Wemm ** to -- the person being sent to. 1248c2aa98e2SPeter Wemm ** 1249c2aa98e2SPeter Wemm ** Returns: 1250c2aa98e2SPeter Wemm ** an exit status 1251c2aa98e2SPeter Wemm ** 1252c2aa98e2SPeter Wemm ** Side Effects: 1253c2aa98e2SPeter Wemm ** none (unless you include the usrerr stuff) 1254c2aa98e2SPeter Wemm */ 1255c2aa98e2SPeter Wemm 1256c2aa98e2SPeter Wemm int 1257c2aa98e2SPeter Wemm checkcompat(to, e) 1258c2aa98e2SPeter Wemm register ADDRESS *to; 1259c2aa98e2SPeter Wemm register ENVELOPE *e; 1260c2aa98e2SPeter Wemm { 1261c2aa98e2SPeter Wemm if (tTd(49, 1)) 126212ed1c7cSGregory Neil Shapiro sm_dprintf("checkcompat(to=%s, from=%s)\n", 1263c2aa98e2SPeter Wemm to->q_paddr, e->e_from.q_paddr); 1264c2aa98e2SPeter Wemm 1265c2aa98e2SPeter Wemm #ifdef EXAMPLE_CODE 1266c2aa98e2SPeter Wemm /* this code is intended as an example only */ 1267c2aa98e2SPeter Wemm register STAB *s; 1268c2aa98e2SPeter Wemm 1269c2aa98e2SPeter Wemm s = stab("arpa", ST_MAILER, ST_FIND); 1270c2aa98e2SPeter Wemm if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 && 1271c2aa98e2SPeter Wemm to->q_mailer == s->s_mailer) 1272c2aa98e2SPeter Wemm { 1273c2aa98e2SPeter Wemm usrerr("553 No ARPA mail through this machine: see your system administration"); 12743299c2f1SGregory Neil Shapiro /* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */ 1275c2aa98e2SPeter Wemm to->q_status = "5.7.1"; 12763299c2f1SGregory Neil Shapiro return EX_UNAVAILABLE; 1277c2aa98e2SPeter Wemm } 1278c2aa98e2SPeter Wemm #endif /* EXAMPLE_CODE */ 12793299c2f1SGregory Neil Shapiro return EX_OK; 1280c2aa98e2SPeter Wemm } 1281951742c4SGregory Neil Shapiro 1282951742c4SGregory Neil Shapiro #ifdef SUN_EXTENSIONS 1283951742c4SGregory Neil Shapiro static void 1284951742c4SGregory Neil Shapiro init_md_sun() 1285951742c4SGregory Neil Shapiro { 1286951742c4SGregory Neil Shapiro struct stat sbuf; 1287951742c4SGregory Neil Shapiro 1288951742c4SGregory Neil Shapiro /* Check for large file descriptor */ 1289951742c4SGregory Neil Shapiro if (fstat(fileno(stdin), &sbuf) < 0) 1290951742c4SGregory Neil Shapiro { 1291951742c4SGregory Neil Shapiro if (errno == EOVERFLOW) 1292951742c4SGregory Neil Shapiro { 1293951742c4SGregory Neil Shapiro perror("stdin"); 1294951742c4SGregory Neil Shapiro exit(EX_NOINPUT); 1295951742c4SGregory Neil Shapiro } 1296951742c4SGregory Neil Shapiro } 1297951742c4SGregory Neil Shapiro } 1298951742c4SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */ 1299951742c4SGregory Neil Shapiro 13003299c2f1SGregory Neil Shapiro /* 1301c2aa98e2SPeter Wemm ** INIT_MD -- do machine dependent initializations 1302c2aa98e2SPeter Wemm ** 1303c2aa98e2SPeter Wemm ** Systems that have global modes that should be set should do 1304c2aa98e2SPeter Wemm ** them here rather than in main. 1305c2aa98e2SPeter Wemm */ 1306c2aa98e2SPeter Wemm 1307c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1308c2aa98e2SPeter Wemm # include <compat.h> 13093299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */ 1310c2aa98e2SPeter Wemm 1311c2aa98e2SPeter Wemm #if SHARE_V1 1312c2aa98e2SPeter Wemm # include <shares.h> 13133299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */ 1314c2aa98e2SPeter Wemm 1315c2aa98e2SPeter Wemm void 1316c2aa98e2SPeter Wemm init_md(argc, argv) 1317c2aa98e2SPeter Wemm int argc; 1318c2aa98e2SPeter Wemm char **argv; 1319c2aa98e2SPeter Wemm { 1320c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE 1321c2aa98e2SPeter Wemm setcompat(getcompat() | COMPAT_BSDPROT); 13223299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */ 1323c2aa98e2SPeter Wemm 1324c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS 1325c2aa98e2SPeter Wemm init_md_sun(); 13263299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */ 1327c2aa98e2SPeter Wemm 1328c2aa98e2SPeter Wemm #if _CONVEX_SOURCE 1329c2aa98e2SPeter Wemm /* keep gethostby*() from stripping the local domain name */ 1330c2aa98e2SPeter Wemm set_domain_trim_off(); 13313299c2f1SGregory Neil Shapiro #endif /* _CONVEX_SOURCE */ 1332951742c4SGregory Neil Shapiro #if defined(__QNX__) && !defined(__QNXNTO__) 1333c2aa98e2SPeter Wemm /* 1334c2aa98e2SPeter Wemm ** Due to QNX's network distributed nature, you can target a tcpip 1335c2aa98e2SPeter Wemm ** stack on a different node in the qnx network; this patch lets 1336c2aa98e2SPeter Wemm ** this feature work. The __sock_locate() must be done before the 1337c2aa98e2SPeter Wemm ** environment is clear. 1338c2aa98e2SPeter Wemm */ 1339c2aa98e2SPeter Wemm __sock_locate(); 13403299c2f1SGregory Neil Shapiro #endif /* __QNX__ */ 1341c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_) 1342c2aa98e2SPeter Wemm set_auth_parameters(argc, argv); 1343c2aa98e2SPeter Wemm 1344c2aa98e2SPeter Wemm # ifdef _SCO_unix_ 1345c2aa98e2SPeter Wemm /* 1346c2aa98e2SPeter Wemm ** This is required for highest security levels (the kernel 1347c2aa98e2SPeter Wemm ** won't let it call set*uid() or run setuid binaries without 1348c2aa98e2SPeter Wemm ** it). It may be necessary on other SECUREWARE systems. 1349c2aa98e2SPeter Wemm */ 1350c2aa98e2SPeter Wemm 1351c2aa98e2SPeter Wemm if (getluid() == -1) 1352c2aa98e2SPeter Wemm setluid(0); 13533299c2f1SGregory Neil Shapiro # endif /* _SCO_unix_ */ 13543299c2f1SGregory Neil Shapiro #endif /* SECUREWARE || defined(_SCO_unix_) */ 13553299c2f1SGregory Neil Shapiro 1356c2aa98e2SPeter Wemm 1357c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT 1358c2aa98e2SPeter Wemm VendorCode = VENDOR_DEFAULT; 13593299c2f1SGregory Neil Shapiro #else /* VENDOR_DEFAULT */ 1360c2aa98e2SPeter Wemm VendorCode = VENDOR_BERKELEY; 13613299c2f1SGregory Neil Shapiro #endif /* VENDOR_DEFAULT */ 1362c2aa98e2SPeter Wemm } 136312ed1c7cSGregory Neil Shapiro /* 1364c2aa98e2SPeter Wemm ** INIT_VENDOR_MACROS -- vendor-dependent macro initializations 1365c2aa98e2SPeter Wemm ** 1366c2aa98e2SPeter Wemm ** Called once, on startup. 1367c2aa98e2SPeter Wemm ** 1368c2aa98e2SPeter Wemm ** Parameters: 1369c2aa98e2SPeter Wemm ** e -- the global envelope. 1370c2aa98e2SPeter Wemm ** 1371c2aa98e2SPeter Wemm ** Returns: 1372c2aa98e2SPeter Wemm ** none. 1373c2aa98e2SPeter Wemm ** 1374c2aa98e2SPeter Wemm ** Side Effects: 1375c2aa98e2SPeter Wemm ** vendor-dependent. 1376c2aa98e2SPeter Wemm */ 1377c2aa98e2SPeter Wemm 1378c2aa98e2SPeter Wemm void 1379c2aa98e2SPeter Wemm init_vendor_macros(e) 1380c2aa98e2SPeter Wemm register ENVELOPE *e; 1381c2aa98e2SPeter Wemm { 1382c2aa98e2SPeter Wemm } 138312ed1c7cSGregory Neil Shapiro /* 1384c2aa98e2SPeter Wemm ** GETLA -- get the current load average 1385c2aa98e2SPeter Wemm ** 1386c2aa98e2SPeter Wemm ** This code stolen from la.c. 1387c2aa98e2SPeter Wemm ** 1388c2aa98e2SPeter Wemm ** Parameters: 1389c2aa98e2SPeter Wemm ** none. 1390c2aa98e2SPeter Wemm ** 1391c2aa98e2SPeter Wemm ** Returns: 1392c2aa98e2SPeter Wemm ** The current load average as an integer. 1393c2aa98e2SPeter Wemm ** 1394c2aa98e2SPeter Wemm ** Side Effects: 1395c2aa98e2SPeter Wemm ** none. 1396c2aa98e2SPeter Wemm */ 1397c2aa98e2SPeter Wemm 1398c2aa98e2SPeter Wemm /* try to guess what style of load average we have */ 1399c2aa98e2SPeter Wemm #define LA_ZERO 1 /* always return load average as zero */ 1400c2aa98e2SPeter Wemm #define LA_INT 2 /* read kmem for avenrun; interpret as long */ 1401c2aa98e2SPeter Wemm #define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */ 1402c2aa98e2SPeter Wemm #define LA_SUBR 4 /* call getloadavg */ 1403c2aa98e2SPeter Wemm #define LA_MACH 5 /* MACH load averages (as on NeXT boxes) */ 1404c2aa98e2SPeter Wemm #define LA_SHORT 6 /* read kmem for avenrun; interpret as short */ 1405c2aa98e2SPeter Wemm #define LA_PROCSTR 7 /* read string ("1.17") from /proc/loadavg */ 1406c2aa98e2SPeter Wemm #define LA_READKSYM 8 /* SVR4: use MIOC_READKSYM ioctl call */ 1407c2aa98e2SPeter Wemm #define LA_DGUX 9 /* special DGUX implementation */ 1408c2aa98e2SPeter Wemm #define LA_HPUX 10 /* special HPUX implementation */ 1409c2aa98e2SPeter Wemm #define LA_IRIX6 11 /* special IRIX 6.2 implementation */ 1410c2aa98e2SPeter Wemm #define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */ 1411c2aa98e2SPeter Wemm #define LA_DEVSHORT 13 /* read short from a device */ 1412c2aa98e2SPeter Wemm #define LA_ALPHAOSF 14 /* Digital UNIX (OSF/1 on Alpha) table() call */ 1413c46d91b7SGregory Neil Shapiro #define LA_PSET 15 /* Solaris per-processor-set load average */ 1414188b7d28SGregory Neil Shapiro #define LA_LONGLONG 17 /* read kmem for avenrun; interpret as long long */ 1415c2aa98e2SPeter Wemm 1416c2aa98e2SPeter Wemm /* do guesses based on general OS type */ 1417c2aa98e2SPeter Wemm #ifndef LA_TYPE 1418c2aa98e2SPeter Wemm # define LA_TYPE LA_ZERO 14193299c2f1SGregory Neil Shapiro #endif /* ! LA_TYPE */ 1420c2aa98e2SPeter Wemm 1421c2aa98e2SPeter Wemm #ifndef FSHIFT 1422c2aa98e2SPeter Wemm # if defined(unixpc) 1423c2aa98e2SPeter Wemm # define FSHIFT 5 14243299c2f1SGregory Neil Shapiro # endif /* defined(unixpc) */ 1425c2aa98e2SPeter Wemm 1426c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX) 1427c2aa98e2SPeter Wemm # define FSHIFT 10 14283299c2f1SGregory Neil Shapiro # endif /* defined(__alpha) || defined(IRIX) */ 1429c2aa98e2SPeter Wemm 14303299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */ 1431c2aa98e2SPeter Wemm 1432c2aa98e2SPeter Wemm #ifndef FSHIFT 1433c2aa98e2SPeter Wemm # define FSHIFT 8 14343299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */ 1435c2aa98e2SPeter Wemm 1436c2aa98e2SPeter Wemm #ifndef FSCALE 1437c2aa98e2SPeter Wemm # define FSCALE (1 << FSHIFT) 14383299c2f1SGregory Neil Shapiro #endif /* ! FSCALE */ 1439c2aa98e2SPeter Wemm 1440c2aa98e2SPeter Wemm #ifndef LA_AVENRUN 1441c2aa98e2SPeter Wemm # ifdef SYSTEM5 1442c2aa98e2SPeter Wemm # define LA_AVENRUN "avenrun" 14433299c2f1SGregory Neil Shapiro # else /* SYSTEM5 */ 1444c2aa98e2SPeter Wemm # define LA_AVENRUN "_avenrun" 14453299c2f1SGregory Neil Shapiro # endif /* SYSTEM5 */ 14463299c2f1SGregory Neil Shapiro #endif /* ! LA_AVENRUN */ 1447c2aa98e2SPeter Wemm 1448c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */ 1449c2aa98e2SPeter Wemm #ifndef _PATH_KMEM 1450c2aa98e2SPeter Wemm # define _PATH_KMEM "/dev/kmem" 14513299c2f1SGregory Neil Shapiro #endif /* ! _PATH_KMEM */ 1452c2aa98e2SPeter Wemm 1453188b7d28SGregory Neil Shapiro #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) 1454c2aa98e2SPeter Wemm 1455c2aa98e2SPeter Wemm # include <nlist.h> 1456c2aa98e2SPeter Wemm 1457c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */ 1458c2aa98e2SPeter Wemm # ifndef _PATH_UNIX 1459c2aa98e2SPeter Wemm # if defined(SYSTEM5) 1460c2aa98e2SPeter Wemm # define _PATH_UNIX "/unix" 14613299c2f1SGregory Neil Shapiro # else /* defined(SYSTEM5) */ 1462c2aa98e2SPeter Wemm # define _PATH_UNIX "/vmunix" 14633299c2f1SGregory Neil Shapiro # endif /* defined(SYSTEM5) */ 14643299c2f1SGregory Neil Shapiro # endif /* ! _PATH_UNIX */ 1465c2aa98e2SPeter Wemm 1466c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE 1467c2aa98e2SPeter Wemm struct nlist Nl[2]; 14683299c2f1SGregory Neil Shapiro # else /* _AUX_SOURCE */ 1469c2aa98e2SPeter Wemm struct nlist Nl[] = 1470c2aa98e2SPeter Wemm { 1471c2aa98e2SPeter Wemm { LA_AVENRUN }, 1472c2aa98e2SPeter Wemm { 0 }, 1473c2aa98e2SPeter Wemm }; 14743299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */ 1475c2aa98e2SPeter Wemm # define X_AVENRUN 0 1476c2aa98e2SPeter Wemm 147712ed1c7cSGregory Neil Shapiro int 1478c2aa98e2SPeter Wemm getla() 1479c2aa98e2SPeter Wemm { 148012ed1c7cSGregory Neil Shapiro int j; 1481c2aa98e2SPeter Wemm static int kmem = -1; 1482c2aa98e2SPeter Wemm # if LA_TYPE == LA_INT 1483c2aa98e2SPeter Wemm long avenrun[3]; 14843299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_INT */ 1485c2aa98e2SPeter Wemm # if LA_TYPE == LA_SHORT 1486c2aa98e2SPeter Wemm short avenrun[3]; 1487188b7d28SGregory Neil Shapiro # else 1488188b7d28SGregory Neil Shapiro # if LA_TYPE == LA_LONGLONG 1489188b7d28SGregory Neil Shapiro long long avenrun[3]; 1490188b7d28SGregory Neil Shapiro # else /* LA_TYPE == LA_LONGLONG */ 1491c2aa98e2SPeter Wemm double avenrun[3]; 1492188b7d28SGregory Neil Shapiro # endif /* LA_TYPE == LA_LONGLONG */ 14933299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_SHORT */ 14943299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_INT */ 1495c2aa98e2SPeter Wemm extern off_t lseek(); 1496c2aa98e2SPeter Wemm 1497c2aa98e2SPeter Wemm if (kmem < 0) 1498c2aa98e2SPeter Wemm { 1499c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE 150012ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN, 1501951742c4SGregory Neil Shapiro sizeof(Nl[X_AVENRUN].n_name)); 1502c2aa98e2SPeter Wemm Nl[1].n_name[0] = '\0'; 15033299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */ 1504c2aa98e2SPeter Wemm 1505c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4) 1506951742c4SGregory Neil Shapiro if (knlist(Nl, 1, sizeof(Nl[0])) < 0) 15073299c2f1SGregory Neil Shapiro # else /* defined(_AIX3) || defined(_AIX4) */ 1508c2aa98e2SPeter Wemm if (nlist(_PATH_UNIX, Nl) < 0) 15093299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */ 1510c2aa98e2SPeter Wemm { 1511c2aa98e2SPeter Wemm if (tTd(3, 1)) 151212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX, 151312ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 15143299c2f1SGregory Neil Shapiro return -1; 1515c2aa98e2SPeter Wemm } 1516c2aa98e2SPeter Wemm if (Nl[X_AVENRUN].n_value == 0) 1517c2aa98e2SPeter Wemm { 1518c2aa98e2SPeter Wemm if (tTd(3, 1)) 151912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: nlist(%s, %s) ==> 0\n", 1520c2aa98e2SPeter Wemm _PATH_UNIX, LA_AVENRUN); 15213299c2f1SGregory Neil Shapiro return -1; 1522c2aa98e2SPeter Wemm } 1523c2aa98e2SPeter Wemm # ifdef NAMELISTMASK 1524c2aa98e2SPeter Wemm Nl[X_AVENRUN].n_value &= NAMELISTMASK; 15253299c2f1SGregory Neil Shapiro # endif /* NAMELISTMASK */ 1526c2aa98e2SPeter Wemm 1527c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, 0, 0); 1528c2aa98e2SPeter Wemm if (kmem < 0) 1529c2aa98e2SPeter Wemm { 1530c2aa98e2SPeter Wemm if (tTd(3, 1)) 153112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: open(/dev/kmem): %s\n", 153212ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 15333299c2f1SGregory Neil Shapiro return -1; 1534c2aa98e2SPeter Wemm } 153512ed1c7cSGregory Neil Shapiro if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || 153612ed1c7cSGregory Neil Shapiro fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) 153712ed1c7cSGregory Neil Shapiro { 153812ed1c7cSGregory Neil Shapiro if (tTd(3, 1)) 153912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", 154012ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 154112ed1c7cSGregory Neil Shapiro (void) close(kmem); 154212ed1c7cSGregory Neil Shapiro kmem = -1; 154312ed1c7cSGregory Neil Shapiro return -1; 154412ed1c7cSGregory Neil Shapiro } 1545c2aa98e2SPeter Wemm } 1546c2aa98e2SPeter Wemm if (tTd(3, 20)) 154712ed1c7cSGregory Neil Shapiro sm_dprintf("getla: symbol address = %#lx\n", 154812ed1c7cSGregory Neil Shapiro (unsigned long) Nl[X_AVENRUN].n_value); 1549c2aa98e2SPeter Wemm if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 || 1550e3793f76SGregory Neil Shapiro read(kmem, (char *) avenrun, sizeof(avenrun)) != sizeof(avenrun)) 1551c2aa98e2SPeter Wemm { 1552c2aa98e2SPeter Wemm /* thank you Ian */ 1553c2aa98e2SPeter Wemm if (tTd(3, 1)) 155412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: lseek or read: %s\n", 155512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 15563299c2f1SGregory Neil Shapiro return -1; 1557c2aa98e2SPeter Wemm } 1558188b7d28SGregory Neil Shapiro # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) 1559c2aa98e2SPeter Wemm if (tTd(3, 5)) 1560c2aa98e2SPeter Wemm { 1561c2aa98e2SPeter Wemm # if LA_TYPE == LA_SHORT 156212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %d", avenrun[0]); 1563c2aa98e2SPeter Wemm if (tTd(3, 15)) 156412ed1c7cSGregory Neil Shapiro sm_dprintf(", %d, %d", avenrun[1], avenrun[2]); 15653299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_SHORT */ 1566188b7d28SGregory Neil Shapiro # if LA_TYPE == LA_LONGLONG 1567188b7d28SGregory Neil Shapiro sm_dprintf("getla: avenrun = %lld", avenrun[0]); 1568188b7d28SGregory Neil Shapiro if (tTd(3, 15)) 1569188b7d28SGregory Neil Shapiro sm_dprintf(", %lld, %lld", avenrun[1], avenrun[2]); 1570188b7d28SGregory Neil Shapiro # else /* LA_TYPE == LA_LONGLONG */ 157112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %ld", avenrun[0]); 1572c2aa98e2SPeter Wemm if (tTd(3, 15)) 157312ed1c7cSGregory Neil Shapiro sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]); 1574188b7d28SGregory Neil Shapiro # endif /* LA_TYPE == LA_LONGLONG */ 15753299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_SHORT */ 157612ed1c7cSGregory Neil Shapiro sm_dprintf("\n"); 1577c2aa98e2SPeter Wemm } 1578c2aa98e2SPeter Wemm if (tTd(3, 1)) 157912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", 15803299c2f1SGregory Neil Shapiro (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1581c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1582188b7d28SGregory Neil Shapiro # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */ 1583c2aa98e2SPeter Wemm if (tTd(3, 5)) 1584c2aa98e2SPeter Wemm { 158512ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %g", avenrun[0]); 1586c2aa98e2SPeter Wemm if (tTd(3, 15)) 158712ed1c7cSGregory Neil Shapiro sm_dprintf(", %g, %g", avenrun[1], avenrun[2]); 158812ed1c7cSGregory Neil Shapiro sm_dprintf("\n"); 1589c2aa98e2SPeter Wemm } 1590c2aa98e2SPeter Wemm if (tTd(3, 1)) 159112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); 1592c2aa98e2SPeter Wemm return ((int) (avenrun[0] + 0.5)); 1593188b7d28SGregory Neil Shapiro # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */ 1594c2aa98e2SPeter Wemm } 1595c2aa98e2SPeter Wemm 1596188b7d28SGregory Neil Shapiro #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */ 1597c2aa98e2SPeter Wemm 1598c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM 1599c2aa98e2SPeter Wemm 1600c2aa98e2SPeter Wemm # include <sys/ksym.h> 1601c2aa98e2SPeter Wemm 160212ed1c7cSGregory Neil Shapiro int 1603c2aa98e2SPeter Wemm getla() 1604c2aa98e2SPeter Wemm { 160512ed1c7cSGregory Neil Shapiro int j; 1606c2aa98e2SPeter Wemm static int kmem = -1; 1607c2aa98e2SPeter Wemm long avenrun[3]; 1608c2aa98e2SPeter Wemm struct mioc_rksym mirk; 1609c2aa98e2SPeter Wemm 1610c2aa98e2SPeter Wemm if (kmem < 0) 1611c2aa98e2SPeter Wemm { 1612c2aa98e2SPeter Wemm kmem = open("/dev/kmem", 0, 0); 1613c2aa98e2SPeter Wemm if (kmem < 0) 1614c2aa98e2SPeter Wemm { 1615c2aa98e2SPeter Wemm if (tTd(3, 1)) 161612ed1c7cSGregory Neil Shapiro sm_dprintf("getla: open(/dev/kmem): %s\n", 161712ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 16183299c2f1SGregory Neil Shapiro return -1; 1619c2aa98e2SPeter Wemm } 162012ed1c7cSGregory Neil Shapiro if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || 162112ed1c7cSGregory Neil Shapiro fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) 162212ed1c7cSGregory Neil Shapiro { 162312ed1c7cSGregory Neil Shapiro if (tTd(3, 1)) 162412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", 162512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 162612ed1c7cSGregory Neil Shapiro (void) close(kmem); 162712ed1c7cSGregory Neil Shapiro kmem = -1; 162812ed1c7cSGregory Neil Shapiro return -1; 162912ed1c7cSGregory Neil Shapiro } 1630c2aa98e2SPeter Wemm } 1631c2aa98e2SPeter Wemm mirk.mirk_symname = LA_AVENRUN; 1632c2aa98e2SPeter Wemm mirk.mirk_buf = avenrun; 1633c2aa98e2SPeter Wemm mirk.mirk_buflen = sizeof(avenrun); 1634c2aa98e2SPeter Wemm if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0) 1635c2aa98e2SPeter Wemm { 1636c2aa98e2SPeter Wemm if (tTd(3, 1)) 163712ed1c7cSGregory Neil Shapiro sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n", 163812ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1639c2aa98e2SPeter Wemm return -1; 1640c2aa98e2SPeter Wemm } 1641c2aa98e2SPeter Wemm if (tTd(3, 5)) 1642c2aa98e2SPeter Wemm { 164312ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %d", avenrun[0]); 1644c2aa98e2SPeter Wemm if (tTd(3, 15)) 164512ed1c7cSGregory Neil Shapiro sm_dprintf(", %d, %d", avenrun[1], avenrun[2]); 164612ed1c7cSGregory Neil Shapiro sm_dprintf("\n"); 1647c2aa98e2SPeter Wemm } 1648c2aa98e2SPeter Wemm if (tTd(3, 1)) 164912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", 16503299c2f1SGregory Neil Shapiro (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1651c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1652c2aa98e2SPeter Wemm } 1653c2aa98e2SPeter Wemm 1654c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */ 1655c2aa98e2SPeter Wemm 1656c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX 1657c2aa98e2SPeter Wemm 1658c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h> 1659c2aa98e2SPeter Wemm 166012ed1c7cSGregory Neil Shapiro int 1661c2aa98e2SPeter Wemm getla() 1662c2aa98e2SPeter Wemm { 1663c2aa98e2SPeter Wemm struct dg_sys_info_load_info load_info; 1664c2aa98e2SPeter Wemm 1665c2aa98e2SPeter Wemm dg_sys_info((long *)&load_info, 1666c2aa98e2SPeter Wemm DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); 1667c2aa98e2SPeter Wemm 1668c2aa98e2SPeter Wemm if (tTd(3, 1)) 166912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5)); 1670c2aa98e2SPeter Wemm 1671c2aa98e2SPeter Wemm return ((int) (load_info.one_minute + 0.5)); 1672c2aa98e2SPeter Wemm } 1673c2aa98e2SPeter Wemm 1674c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */ 1675c2aa98e2SPeter Wemm 1676c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX 1677c2aa98e2SPeter Wemm 1678c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */ 1679c2aa98e2SPeter Wemm struct pst_dynamic; 1680c2aa98e2SPeter Wemm struct pst_status; 1681c2aa98e2SPeter Wemm struct pst_static; 1682c2aa98e2SPeter Wemm struct pst_vminfo; 1683c2aa98e2SPeter Wemm struct pst_diskinfo; 1684c2aa98e2SPeter Wemm struct pst_processor; 1685c2aa98e2SPeter Wemm struct pst_lv; 1686c2aa98e2SPeter Wemm struct pst_swapinfo; 1687c2aa98e2SPeter Wemm 1688c2aa98e2SPeter Wemm # include <sys/param.h> 1689c2aa98e2SPeter Wemm # include <sys/pstat.h> 1690c2aa98e2SPeter Wemm 169112ed1c7cSGregory Neil Shapiro int 1692c2aa98e2SPeter Wemm getla() 1693c2aa98e2SPeter Wemm { 1694c2aa98e2SPeter Wemm struct pst_dynamic pstd; 1695c2aa98e2SPeter Wemm 1696c2aa98e2SPeter Wemm if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic), 1697c2aa98e2SPeter Wemm (size_t) 1, 0) == -1) 1698c2aa98e2SPeter Wemm return 0; 1699c2aa98e2SPeter Wemm 1700c2aa98e2SPeter Wemm if (tTd(3, 1)) 170112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5)); 1702c2aa98e2SPeter Wemm 1703c2aa98e2SPeter Wemm return (int) (pstd.psd_avg_1_min + 0.5); 1704c2aa98e2SPeter Wemm } 1705c2aa98e2SPeter Wemm 1706c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */ 1707c2aa98e2SPeter Wemm 1708c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR 1709c2aa98e2SPeter Wemm 171012ed1c7cSGregory Neil Shapiro int 1711c2aa98e2SPeter Wemm getla() 1712c2aa98e2SPeter Wemm { 1713c2aa98e2SPeter Wemm double avenrun[3]; 1714c2aa98e2SPeter Wemm 1715c2aa98e2SPeter Wemm if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 1716c2aa98e2SPeter Wemm { 1717c2aa98e2SPeter Wemm if (tTd(3, 1)) 171812ed1c7cSGregory Neil Shapiro sm_dprintf("getla: getloadavg failed: %s", 171912ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 17203299c2f1SGregory Neil Shapiro return -1; 1721c2aa98e2SPeter Wemm } 1722c2aa98e2SPeter Wemm if (tTd(3, 1)) 172312ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); 1724c2aa98e2SPeter Wemm return ((int) (avenrun[0] + 0.5)); 1725c2aa98e2SPeter Wemm } 1726c2aa98e2SPeter Wemm 1727c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */ 1728c2aa98e2SPeter Wemm 1729c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH 1730c2aa98e2SPeter Wemm 1731c2aa98e2SPeter Wemm /* 1732c2aa98e2SPeter Wemm ** This has been tested on NEXTSTEP release 2.1/3.X. 1733c2aa98e2SPeter Wemm */ 1734c2aa98e2SPeter Wemm 1735c2aa98e2SPeter Wemm # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 1736c2aa98e2SPeter Wemm # include <mach/mach.h> 17373299c2f1SGregory Neil Shapiro # else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */ 1738c2aa98e2SPeter Wemm # include <mach.h> 17393299c2f1SGregory Neil Shapiro # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */ 1740c2aa98e2SPeter Wemm 174112ed1c7cSGregory Neil Shapiro int 1742c2aa98e2SPeter Wemm getla() 1743c2aa98e2SPeter Wemm { 1744c2aa98e2SPeter Wemm processor_set_t default_set; 1745c2aa98e2SPeter Wemm kern_return_t error; 1746c2aa98e2SPeter Wemm unsigned int info_count; 1747c2aa98e2SPeter Wemm struct processor_set_basic_info info; 1748c2aa98e2SPeter Wemm host_t host; 1749c2aa98e2SPeter Wemm 1750c2aa98e2SPeter Wemm error = processor_set_default(host_self(), &default_set); 1751c2aa98e2SPeter Wemm if (error != KERN_SUCCESS) 1752c2aa98e2SPeter Wemm { 1753c2aa98e2SPeter Wemm if (tTd(3, 1)) 175412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: processor_set_default failed: %s", 175512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1756c2aa98e2SPeter Wemm return -1; 1757c2aa98e2SPeter Wemm } 1758c2aa98e2SPeter Wemm info_count = PROCESSOR_SET_BASIC_INFO_COUNT; 1759c2aa98e2SPeter Wemm if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, 1760c2aa98e2SPeter Wemm &host, (processor_set_info_t)&info, 1761c2aa98e2SPeter Wemm &info_count) != KERN_SUCCESS) 1762c2aa98e2SPeter Wemm { 1763c2aa98e2SPeter Wemm if (tTd(3, 1)) 176412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: processor_set_info failed: %s", 176512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1766c2aa98e2SPeter Wemm return -1; 1767c2aa98e2SPeter Wemm } 1768c2aa98e2SPeter Wemm if (tTd(3, 1)) 176912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", 17703299c2f1SGregory Neil Shapiro (int) ((info.load_average + (LOAD_SCALE / 2)) / 17713299c2f1SGregory Neil Shapiro LOAD_SCALE)); 1772c2aa98e2SPeter Wemm return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE; 1773c2aa98e2SPeter Wemm } 1774c2aa98e2SPeter Wemm 1775c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */ 1776c2aa98e2SPeter Wemm 1777c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR 177812ed1c7cSGregory Neil Shapiro # if SM_CONF_BROKEN_STRTOD 177912ed1c7cSGregory Neil Shapiro ERROR: This OS has most likely a broken strtod() implemenentation. 178012ed1c7cSGregory Neil Shapiro ERROR: The function is required for getla(). 178112ed1c7cSGregory Neil Shapiro ERROR: Check the compilation options _LA_PROCSTR and 178212ed1c7cSGregory Neil Shapiro ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _). 178312ed1c7cSGregory Neil Shapiro # endif /* SM_CONF_BROKEN_STRTOD */ 1784c2aa98e2SPeter Wemm 1785c2aa98e2SPeter Wemm /* 1786c2aa98e2SPeter Wemm ** Read /proc/loadavg for the load average. This is assumed to be 1787c2aa98e2SPeter Wemm ** in a format like "0.15 0.12 0.06". 1788c2aa98e2SPeter Wemm ** 1789c2aa98e2SPeter Wemm ** Initially intended for Linux. This has been in the kernel 1790c2aa98e2SPeter Wemm ** since at least 0.99.15. 1791c2aa98e2SPeter Wemm */ 1792c2aa98e2SPeter Wemm 1793c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG 1794c2aa98e2SPeter Wemm # define _PATH_LOADAVG "/proc/loadavg" 17953299c2f1SGregory Neil Shapiro # endif /* ! _PATH_LOADAVG */ 1796c2aa98e2SPeter Wemm 179712ed1c7cSGregory Neil Shapiro int 1798c2aa98e2SPeter Wemm getla() 1799c2aa98e2SPeter Wemm { 1800c2aa98e2SPeter Wemm double avenrun; 1801c2aa98e2SPeter Wemm register int result; 180212ed1c7cSGregory Neil Shapiro SM_FILE_T *fp; 1803c2aa98e2SPeter Wemm 180412ed1c7cSGregory Neil Shapiro fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY, 180512ed1c7cSGregory Neil Shapiro NULL); 1806c2aa98e2SPeter Wemm if (fp == NULL) 1807c2aa98e2SPeter Wemm { 1808c2aa98e2SPeter Wemm if (tTd(3, 1)) 180912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: sm_io_open(%s): %s\n", 181012ed1c7cSGregory Neil Shapiro _PATH_LOADAVG, sm_errstring(errno)); 1811c2aa98e2SPeter Wemm return -1; 1812c2aa98e2SPeter Wemm } 181312ed1c7cSGregory Neil Shapiro result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun); 181412ed1c7cSGregory Neil Shapiro (void) sm_io_close(fp, SM_TIME_DEFAULT); 1815c2aa98e2SPeter Wemm if (result != 1) 1816c2aa98e2SPeter Wemm { 1817c2aa98e2SPeter Wemm if (tTd(3, 1)) 181812ed1c7cSGregory Neil Shapiro sm_dprintf("getla: sm_io_fscanf() = %d: %s\n", 181912ed1c7cSGregory Neil Shapiro result, sm_errstring(errno)); 1820c2aa98e2SPeter Wemm return -1; 1821c2aa98e2SPeter Wemm } 1822c2aa98e2SPeter Wemm 1823c2aa98e2SPeter Wemm if (tTd(3, 1)) 182412ed1c7cSGregory Neil Shapiro sm_dprintf("getla(): %.2f\n", avenrun); 1825c2aa98e2SPeter Wemm 1826c2aa98e2SPeter Wemm return ((int) (avenrun + 0.5)); 1827c2aa98e2SPeter Wemm } 1828c2aa98e2SPeter Wemm 1829c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */ 1830c2aa98e2SPeter Wemm 1831c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6 18323299c2f1SGregory Neil Shapiro 1833c2aa98e2SPeter Wemm # include <sys/sysmp.h> 1834c2aa98e2SPeter Wemm 1835bfb62e91SGregory Neil Shapiro # ifdef _UNICOSMP 1836bfb62e91SGregory Neil Shapiro # define CAST_SYSMP(x) (x) 1837bfb62e91SGregory Neil Shapiro # else /* _UNICOSMP */ 1838bfb62e91SGregory Neil Shapiro # define CAST_SYSMP(x) ((x) & 0x7fffffff) 1839bfb62e91SGregory Neil Shapiro # endif /* _UNICOSMP */ 1840bfb62e91SGregory Neil Shapiro 184112ed1c7cSGregory Neil Shapiro int 184212ed1c7cSGregory Neil Shapiro getla(void) 1843c2aa98e2SPeter Wemm { 184412ed1c7cSGregory Neil Shapiro int j; 1845c2aa98e2SPeter Wemm static int kmem = -1; 1846c2aa98e2SPeter Wemm int avenrun[3]; 1847c2aa98e2SPeter Wemm 1848c2aa98e2SPeter Wemm if (kmem < 0) 1849c2aa98e2SPeter Wemm { 1850c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, 0, 0); 1851c2aa98e2SPeter Wemm if (kmem < 0) 1852c2aa98e2SPeter Wemm { 1853c2aa98e2SPeter Wemm if (tTd(3, 1)) 185412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM, 185512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1856c2aa98e2SPeter Wemm return -1; 1857c2aa98e2SPeter Wemm } 185812ed1c7cSGregory Neil Shapiro if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || 185912ed1c7cSGregory Neil Shapiro fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) 186012ed1c7cSGregory Neil Shapiro { 186112ed1c7cSGregory Neil Shapiro if (tTd(3, 1)) 186212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", 186312ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 186412ed1c7cSGregory Neil Shapiro (void) close(kmem); 186512ed1c7cSGregory Neil Shapiro kmem = -1; 186612ed1c7cSGregory Neil Shapiro return -1; 186712ed1c7cSGregory Neil Shapiro } 1868c2aa98e2SPeter Wemm } 1869c2aa98e2SPeter Wemm 1870bfb62e91SGregory Neil Shapiro if (lseek(kmem, CAST_SYSMP(sysmp(MP_KERNADDR, MPKA_AVENRUN)), SEEK_SET) 1871bfb62e91SGregory Neil Shapiro == -1 || 1872e3793f76SGregory Neil Shapiro read(kmem, (char *) avenrun, sizeof(avenrun)) != sizeof(avenrun)) 1873c2aa98e2SPeter Wemm { 1874c2aa98e2SPeter Wemm if (tTd(3, 1)) 187512ed1c7cSGregory Neil Shapiro sm_dprintf("getla: lseek or read: %s\n", 187612ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1877c2aa98e2SPeter Wemm return -1; 1878c2aa98e2SPeter Wemm } 1879c2aa98e2SPeter Wemm if (tTd(3, 5)) 1880c2aa98e2SPeter Wemm { 188112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]); 1882c2aa98e2SPeter Wemm if (tTd(3, 15)) 188312ed1c7cSGregory Neil Shapiro sm_dprintf(", %ld, %ld", 1884c2aa98e2SPeter Wemm (long int) avenrun[1], (long int) avenrun[2]); 188512ed1c7cSGregory Neil Shapiro sm_dprintf("\n"); 1886c2aa98e2SPeter Wemm } 1887c2aa98e2SPeter Wemm 1888c2aa98e2SPeter Wemm if (tTd(3, 1)) 188912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", 18903299c2f1SGregory Neil Shapiro (int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1891c2aa98e2SPeter Wemm return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 1892c2aa98e2SPeter Wemm 1893c2aa98e2SPeter Wemm } 18943299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_IRIX6 */ 1895c2aa98e2SPeter Wemm 1896c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT 1897c2aa98e2SPeter Wemm 1898c2aa98e2SPeter Wemm # include <kstat.h> 1899c2aa98e2SPeter Wemm 190012ed1c7cSGregory Neil Shapiro int 1901c2aa98e2SPeter Wemm getla() 1902c2aa98e2SPeter Wemm { 1903c2aa98e2SPeter Wemm static kstat_ctl_t *kc = NULL; 1904c2aa98e2SPeter Wemm static kstat_t *ksp = NULL; 1905c2aa98e2SPeter Wemm kstat_named_t *ksn; 1906c2aa98e2SPeter Wemm int la; 1907c2aa98e2SPeter Wemm 1908c2aa98e2SPeter Wemm if (kc == NULL) /* if not initialized before */ 1909c2aa98e2SPeter Wemm kc = kstat_open(); 1910c2aa98e2SPeter Wemm if (kc == NULL) 1911c2aa98e2SPeter Wemm { 1912c2aa98e2SPeter Wemm if (tTd(3, 1)) 191312ed1c7cSGregory Neil Shapiro sm_dprintf("getla: kstat_open(): %s\n", 191412ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1915c2aa98e2SPeter Wemm return -1; 1916c2aa98e2SPeter Wemm } 1917c2aa98e2SPeter Wemm if (ksp == NULL) 1918c2aa98e2SPeter Wemm ksp = kstat_lookup(kc, "unix", 0, "system_misc"); 1919c2aa98e2SPeter Wemm if (ksp == NULL) 1920c2aa98e2SPeter Wemm { 1921c2aa98e2SPeter Wemm if (tTd(3, 1)) 192212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: kstat_lookup(): %s\n", 192312ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1924c2aa98e2SPeter Wemm return -1; 1925c2aa98e2SPeter Wemm } 1926c2aa98e2SPeter Wemm if (kstat_read(kc, ksp, NULL) < 0) 1927c2aa98e2SPeter Wemm { 1928c2aa98e2SPeter Wemm if (tTd(3, 1)) 192912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: kstat_read(): %s\n", 193012ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 1931c2aa98e2SPeter Wemm return -1; 1932c2aa98e2SPeter Wemm } 1933c2aa98e2SPeter Wemm ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min"); 1934c2aa98e2SPeter Wemm la = ((double) ksn->value.ul + FSCALE/2) / FSCALE; 1935c2aa98e2SPeter Wemm /* kstat_close(kc); /o do not close for fast access */ 1936c2aa98e2SPeter Wemm return la; 1937c2aa98e2SPeter Wemm } 1938c2aa98e2SPeter Wemm 1939c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */ 1940c2aa98e2SPeter Wemm 1941c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT 1942c2aa98e2SPeter Wemm 1943c2aa98e2SPeter Wemm /* 1944c2aa98e2SPeter Wemm ** Read /dev/table/avenrun for the load average. This should contain 1945c2aa98e2SPeter Wemm ** three shorts for the 1, 5, and 15 minute loads. We only read the 1946c2aa98e2SPeter Wemm ** first, since that's all we care about. 1947c2aa98e2SPeter Wemm ** 1948c2aa98e2SPeter Wemm ** Intended for SCO OpenServer 5. 1949c2aa98e2SPeter Wemm */ 1950c2aa98e2SPeter Wemm 1951c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN 1952c2aa98e2SPeter Wemm # define _PATH_AVENRUN "/dev/table/avenrun" 19533299c2f1SGregory Neil Shapiro # endif /* ! _PATH_AVENRUN */ 1954c2aa98e2SPeter Wemm 195512ed1c7cSGregory Neil Shapiro int 1956c2aa98e2SPeter Wemm getla() 1957c2aa98e2SPeter Wemm { 1958c2aa98e2SPeter Wemm static int afd = -1; 1959c2aa98e2SPeter Wemm short avenrun; 1960c2aa98e2SPeter Wemm int loadav; 1961c2aa98e2SPeter Wemm int r; 1962c2aa98e2SPeter Wemm 1963c2aa98e2SPeter Wemm errno = EBADF; 1964c2aa98e2SPeter Wemm 1965c2aa98e2SPeter Wemm if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1) 1966c2aa98e2SPeter Wemm { 1967c2aa98e2SPeter Wemm if (errno != EBADF) 1968c2aa98e2SPeter Wemm return -1; 1969c2aa98e2SPeter Wemm afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC); 1970c2aa98e2SPeter Wemm if (afd < 0) 1971c2aa98e2SPeter Wemm { 1972c2aa98e2SPeter Wemm sm_syslog(LOG_ERR, NOQID, 197312ed1c7cSGregory Neil Shapiro "can't open %s: %s", 197412ed1c7cSGregory Neil Shapiro _PATH_AVENRUN, sm_errstring(errno)); 1975c2aa98e2SPeter Wemm return -1; 1976c2aa98e2SPeter Wemm } 1977c2aa98e2SPeter Wemm } 1978c2aa98e2SPeter Wemm 1979951742c4SGregory Neil Shapiro r = read(afd, &avenrun, sizeof(avenrun)); 1980e3793f76SGregory Neil Shapiro if (r != sizeof(avenrun)) 1981e3793f76SGregory Neil Shapiro { 1982e3793f76SGregory Neil Shapiro sm_syslog(LOG_ERR, NOQID, 1983e3793f76SGregory Neil Shapiro "can't read %s: %s", _PATH_AVENRUN, 1984e3793f76SGregory Neil Shapiro r == -1 ? sm_errstring(errno) : "short read"); 1985e3793f76SGregory Neil Shapiro return -1; 1986e3793f76SGregory Neil Shapiro } 1987c2aa98e2SPeter Wemm 1988c2aa98e2SPeter Wemm if (tTd(3, 5)) 198912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: avenrun = %d\n", avenrun); 1990c2aa98e2SPeter Wemm loadav = (int) (avenrun + FSCALE/2) >> FSHIFT; 1991c2aa98e2SPeter Wemm if (tTd(3, 1)) 199212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", loadav); 1993c2aa98e2SPeter Wemm return loadav; 1994c2aa98e2SPeter Wemm } 1995c2aa98e2SPeter Wemm 1996c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */ 1997c2aa98e2SPeter Wemm 1998c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF 1999c2aa98e2SPeter Wemm struct rtentry; 2000c2aa98e2SPeter Wemm struct mbuf; 2001c2aa98e2SPeter Wemm # include <sys/table.h> 2002c2aa98e2SPeter Wemm 200312ed1c7cSGregory Neil Shapiro int 200412ed1c7cSGregory Neil Shapiro getla() 2005c2aa98e2SPeter Wemm { 2006c2aa98e2SPeter Wemm int ave = 0; 2007c2aa98e2SPeter Wemm struct tbl_loadavg tab; 2008c2aa98e2SPeter Wemm 2009c2aa98e2SPeter Wemm if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1) 2010c2aa98e2SPeter Wemm { 2011c2aa98e2SPeter Wemm if (tTd(3, 1)) 201212ed1c7cSGregory Neil Shapiro sm_dprintf("getla: table %s\n", sm_errstring(errno)); 20133299c2f1SGregory Neil Shapiro return -1; 2014c2aa98e2SPeter Wemm } 2015c2aa98e2SPeter Wemm 2016c2aa98e2SPeter Wemm if (tTd(3, 1)) 201712ed1c7cSGregory Neil Shapiro sm_dprintf("getla: scale = %d\n", tab.tl_lscale); 2018c2aa98e2SPeter Wemm 2019c2aa98e2SPeter Wemm if (tab.tl_lscale) 20203299c2f1SGregory Neil Shapiro ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) / 20213299c2f1SGregory Neil Shapiro tab.tl_lscale); 2022c2aa98e2SPeter Wemm else 20233299c2f1SGregory Neil Shapiro ave = (int) (tab.tl_avenrun.d[2] + 0.5); 2024c2aa98e2SPeter Wemm 2025c2aa98e2SPeter Wemm if (tTd(3, 1)) 202612ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", ave); 2027c2aa98e2SPeter Wemm 2028c2aa98e2SPeter Wemm return ave; 2029c2aa98e2SPeter Wemm } 2030c2aa98e2SPeter Wemm 20313299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_ALPHAOSF */ 2032c2aa98e2SPeter Wemm 2033c46d91b7SGregory Neil Shapiro #if LA_TYPE == LA_PSET 2034c46d91b7SGregory Neil Shapiro 203512ed1c7cSGregory Neil Shapiro int 2036c46d91b7SGregory Neil Shapiro getla() 2037c46d91b7SGregory Neil Shapiro { 2038c46d91b7SGregory Neil Shapiro double avenrun[3]; 2039c46d91b7SGregory Neil Shapiro 2040c46d91b7SGregory Neil Shapiro if (pset_getloadavg(PS_MYID, avenrun, 2041c46d91b7SGregory Neil Shapiro sizeof(avenrun) / sizeof(avenrun[0])) < 0) 2042c46d91b7SGregory Neil Shapiro { 2043c46d91b7SGregory Neil Shapiro if (tTd(3, 1)) 204412ed1c7cSGregory Neil Shapiro sm_dprintf("getla: pset_getloadavg failed: %s", 204512ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 2046c46d91b7SGregory Neil Shapiro return -1; 2047c46d91b7SGregory Neil Shapiro } 2048c46d91b7SGregory Neil Shapiro if (tTd(3, 1)) 204912ed1c7cSGregory Neil Shapiro sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); 2050c46d91b7SGregory Neil Shapiro return ((int) (avenrun[0] + 0.5)); 2051c46d91b7SGregory Neil Shapiro } 2052c46d91b7SGregory Neil Shapiro 2053c46d91b7SGregory Neil Shapiro #endif /* LA_TYPE == LA_PSET */ 2054c46d91b7SGregory Neil Shapiro 2055c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO 2056c2aa98e2SPeter Wemm 205712ed1c7cSGregory Neil Shapiro int 2058c2aa98e2SPeter Wemm getla() 2059c2aa98e2SPeter Wemm { 2060c2aa98e2SPeter Wemm if (tTd(3, 1)) 206112ed1c7cSGregory Neil Shapiro sm_dprintf("getla: ZERO\n"); 20623299c2f1SGregory Neil Shapiro return 0; 2063c2aa98e2SPeter Wemm } 2064c2aa98e2SPeter Wemm 2065c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */ 2066c2aa98e2SPeter Wemm 2067c2aa98e2SPeter Wemm /* 2068c2aa98e2SPeter Wemm * Copyright 1989 Massachusetts Institute of Technology 2069c2aa98e2SPeter Wemm * 2070c2aa98e2SPeter Wemm * Permission to use, copy, modify, distribute, and sell this software and its 2071c2aa98e2SPeter Wemm * documentation for any purpose is hereby granted without fee, provided that 2072c2aa98e2SPeter Wemm * the above copyright notice appear in all copies and that both that 2073c2aa98e2SPeter Wemm * copyright notice and this permission notice appear in supporting 2074c2aa98e2SPeter Wemm * documentation, and that the name of M.I.T. not be used in advertising or 2075c2aa98e2SPeter Wemm * publicity pertaining to distribution of the software without specific, 2076c2aa98e2SPeter Wemm * written prior permission. M.I.T. makes no representations about the 2077c2aa98e2SPeter Wemm * suitability of this software for any purpose. It is provided "as is" 2078c2aa98e2SPeter Wemm * without express or implied warranty. 2079c2aa98e2SPeter Wemm * 2080c2aa98e2SPeter Wemm * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 2081c2aa98e2SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 2082c2aa98e2SPeter Wemm * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 2083c2aa98e2SPeter Wemm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 2084c2aa98e2SPeter Wemm * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 2085c2aa98e2SPeter Wemm * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2086c2aa98e2SPeter Wemm * 2087c2aa98e2SPeter Wemm * Authors: Many and varied... 2088c2aa98e2SPeter Wemm */ 2089c2aa98e2SPeter Wemm 2090c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */ 2091c2aa98e2SPeter Wemm #ifndef lint 209212ed1c7cSGregory Neil Shapiro SM_UNUSED(static char rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $"; 2093c2aa98e2SPeter Wemm #endif /* ! lint */ 2094c2aa98e2SPeter Wemm 2095c2aa98e2SPeter Wemm #ifdef apollo 2096c2aa98e2SPeter Wemm # undef volatile 2097c2aa98e2SPeter Wemm # include <apollo/base.h> 2098c2aa98e2SPeter Wemm 2099c2aa98e2SPeter Wemm /* ARGSUSED */ 2100c2aa98e2SPeter Wemm int getloadavg( call_data ) 2101c2aa98e2SPeter Wemm caddr_t call_data; /* pointer to (double) return value */ 2102c2aa98e2SPeter Wemm { 2103c2aa98e2SPeter Wemm double *avenrun = (double *) call_data; 2104c2aa98e2SPeter Wemm int i; 2105c2aa98e2SPeter Wemm status_$t st; 2106c2aa98e2SPeter Wemm long loadav[3]; 210712ed1c7cSGregory Neil Shapiro 2108c2aa98e2SPeter Wemm proc1_$get_loadav(loadav, &st); 2109c2aa98e2SPeter Wemm *avenrun = loadav[0] / (double) (1 << 16); 21103299c2f1SGregory Neil Shapiro return 0; 2111c2aa98e2SPeter Wemm } 2112c2aa98e2SPeter Wemm #endif /* apollo */ 211312ed1c7cSGregory Neil Shapiro /* 211412ed1c7cSGregory Neil Shapiro ** SM_GETLA -- get the current load average 21153299c2f1SGregory Neil Shapiro ** 21163299c2f1SGregory Neil Shapiro ** Parameters: 211712ed1c7cSGregory Neil Shapiro ** none 21183299c2f1SGregory Neil Shapiro ** 21193299c2f1SGregory Neil Shapiro ** Returns: 212012ed1c7cSGregory Neil Shapiro ** none 21213299c2f1SGregory Neil Shapiro ** 21223299c2f1SGregory Neil Shapiro ** Side Effects: 212312ed1c7cSGregory Neil Shapiro ** Set CurrentLA to the current load average. 212412ed1c7cSGregory Neil Shapiro ** Set {load_avg} in GlobalMacros to the current load average. 21253299c2f1SGregory Neil Shapiro */ 21263299c2f1SGregory Neil Shapiro 212712ed1c7cSGregory Neil Shapiro void 212812ed1c7cSGregory Neil Shapiro sm_getla() 21293299c2f1SGregory Neil Shapiro { 21303299c2f1SGregory Neil Shapiro char labuf[8]; 21313299c2f1SGregory Neil Shapiro 213212ed1c7cSGregory Neil Shapiro CurrentLA = getla(); 2133951742c4SGregory Neil Shapiro (void) sm_snprintf(labuf, sizeof(labuf), "%d", CurrentLA); 213412ed1c7cSGregory Neil Shapiro macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf); 21353299c2f1SGregory Neil Shapiro } 213612ed1c7cSGregory Neil Shapiro /* 2137c2aa98e2SPeter Wemm ** SHOULDQUEUE -- should this message be queued or sent? 2138c2aa98e2SPeter Wemm ** 2139c2aa98e2SPeter Wemm ** Compares the message cost to the load average to decide. 2140c2aa98e2SPeter Wemm ** 214112ed1c7cSGregory Neil Shapiro ** Note: Do NOT change this API! It is documented in op.me 214212ed1c7cSGregory Neil Shapiro ** and theoretically the user can change this function... 214312ed1c7cSGregory Neil Shapiro ** 2144c2aa98e2SPeter Wemm ** Parameters: 2145c2aa98e2SPeter Wemm ** pri -- the priority of the message in question. 214612ed1c7cSGregory Neil Shapiro ** ct -- the message creation time (unused, but see above). 2147c2aa98e2SPeter Wemm ** 2148c2aa98e2SPeter Wemm ** Returns: 214912ed1c7cSGregory Neil Shapiro ** true -- if this message should be queued up for the 2150c2aa98e2SPeter Wemm ** time being. 215112ed1c7cSGregory Neil Shapiro ** false -- if the load is low enough to send this message. 2152c2aa98e2SPeter Wemm ** 2153c2aa98e2SPeter Wemm ** Side Effects: 2154c2aa98e2SPeter Wemm ** none. 2155c2aa98e2SPeter Wemm */ 2156c2aa98e2SPeter Wemm 21573299c2f1SGregory Neil Shapiro /* ARGSUSED1 */ 2158c2aa98e2SPeter Wemm bool 21593299c2f1SGregory Neil Shapiro shouldqueue(pri, ct) 2160c2aa98e2SPeter Wemm long pri; 21613299c2f1SGregory Neil Shapiro time_t ct; 2162c2aa98e2SPeter Wemm { 2163c2aa98e2SPeter Wemm bool rval; 2164567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT 2165567a2fc9SGregory Neil Shapiro long memfree; 2166567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 2167c2aa98e2SPeter Wemm 2168c2aa98e2SPeter Wemm if (tTd(3, 30)) 216912ed1c7cSGregory Neil Shapiro sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ", 21703299c2f1SGregory Neil Shapiro CurrentLA, pri); 2171567a2fc9SGregory Neil Shapiro 2172567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT 2173567a2fc9SGregory Neil Shapiro if (QueueLowMem > 0 && 2174567a2fc9SGregory Neil Shapiro sm_memstat_get(MemoryResource, &memfree) >= 0 && 2175567a2fc9SGregory Neil Shapiro memfree < QueueLowMem) 2176567a2fc9SGregory Neil Shapiro { 2177567a2fc9SGregory Neil Shapiro if (tTd(3, 30)) 2178355d91e3SGregory Neil Shapiro sm_dprintf("true (memfree=%ld < QueueLowMem=%ld)\n", 2179567a2fc9SGregory Neil Shapiro memfree, QueueLowMem); 2180567a2fc9SGregory Neil Shapiro return true; 2181567a2fc9SGregory Neil Shapiro } 2182567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 21833299c2f1SGregory Neil Shapiro if (CurrentLA < QueueLA) 2184c2aa98e2SPeter Wemm { 2185c2aa98e2SPeter Wemm if (tTd(3, 30)) 218612ed1c7cSGregory Neil Shapiro sm_dprintf("false (CurrentLA < QueueLA)\n"); 218712ed1c7cSGregory Neil Shapiro return false; 2188c2aa98e2SPeter Wemm } 21893299c2f1SGregory Neil Shapiro rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1)); 2190c2aa98e2SPeter Wemm if (tTd(3, 30)) 219112ed1c7cSGregory Neil Shapiro sm_dprintf("%s (by calculation)\n", rval ? "true" : "false"); 2192c2aa98e2SPeter Wemm return rval; 2193c2aa98e2SPeter Wemm } 2194951742c4SGregory Neil Shapiro 219512ed1c7cSGregory Neil Shapiro /* 2196c2aa98e2SPeter Wemm ** REFUSECONNECTIONS -- decide if connections should be refused 2197c2aa98e2SPeter Wemm ** 2198c2aa98e2SPeter Wemm ** Parameters: 21993299c2f1SGregory Neil Shapiro ** e -- the current envelope. 2200951742c4SGregory Neil Shapiro ** dn -- number of daemon. 220112ed1c7cSGregory Neil Shapiro ** active -- was this daemon actually active? 2202c2aa98e2SPeter Wemm ** 2203c2aa98e2SPeter Wemm ** Returns: 220412ed1c7cSGregory Neil Shapiro ** true if incoming SMTP connections should be refused 2205c2aa98e2SPeter Wemm ** (for now). 220612ed1c7cSGregory Neil Shapiro ** false if we should accept new work. 2207c2aa98e2SPeter Wemm ** 2208c2aa98e2SPeter Wemm ** Side Effects: 2209c2aa98e2SPeter Wemm ** Sets process title when it is rejecting connections. 2210c2aa98e2SPeter Wemm */ 2211c2aa98e2SPeter Wemm 2212c2aa98e2SPeter Wemm bool 2213951742c4SGregory Neil Shapiro refuseconnections(e, dn, active) 22143299c2f1SGregory Neil Shapiro ENVELOPE *e; 2215951742c4SGregory Neil Shapiro int dn; 221612ed1c7cSGregory Neil Shapiro bool active; 2217c2aa98e2SPeter Wemm { 221812ed1c7cSGregory Neil Shapiro static time_t lastconn[MAXDAEMONS]; 221912ed1c7cSGregory Neil Shapiro static int conncnt[MAXDAEMONS]; 22202ef40764SGregory Neil Shapiro static time_t firstrejtime[MAXDAEMONS]; 22212ef40764SGregory Neil Shapiro static time_t nextlogtime[MAXDAEMONS]; 2222951742c4SGregory Neil Shapiro int limit; 2223567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT 2224567a2fc9SGregory Neil Shapiro long memfree; 2225567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 222612ed1c7cSGregory Neil Shapiro 222712ed1c7cSGregory Neil Shapiro #if XLA 2228c2aa98e2SPeter Wemm if (!xla_smtp_ok()) 222912ed1c7cSGregory Neil Shapiro return true; 22303299c2f1SGregory Neil Shapiro #endif /* XLA */ 2231c2aa98e2SPeter Wemm 2232951742c4SGregory Neil Shapiro SM_ASSERT(dn >= 0); 2233951742c4SGregory Neil Shapiro SM_ASSERT(dn < MAXDAEMONS); 223412ed1c7cSGregory Neil Shapiro if (ConnRateThrottle > 0) 223512ed1c7cSGregory Neil Shapiro { 223612ed1c7cSGregory Neil Shapiro time_t now; 223712ed1c7cSGregory Neil Shapiro 223812ed1c7cSGregory Neil Shapiro now = curtime(); 223912ed1c7cSGregory Neil Shapiro if (active) 224012ed1c7cSGregory Neil Shapiro { 2241951742c4SGregory Neil Shapiro if (now != lastconn[dn]) 224212ed1c7cSGregory Neil Shapiro { 2243951742c4SGregory Neil Shapiro lastconn[dn] = now; 2244951742c4SGregory Neil Shapiro conncnt[dn] = 1; 224512ed1c7cSGregory Neil Shapiro } 2246951742c4SGregory Neil Shapiro else if (conncnt[dn]++ > ConnRateThrottle) 224712ed1c7cSGregory Neil Shapiro { 224812ed1c7cSGregory Neil Shapiro #define D_MSG_CRT "deferring connections on daemon %s: %d per second" 224912ed1c7cSGregory Neil Shapiro /* sleep to flatten out connection load */ 225012ed1c7cSGregory Neil Shapiro sm_setproctitle(true, e, D_MSG_CRT, 2251951742c4SGregory Neil Shapiro Daemons[dn].d_name, 2252951742c4SGregory Neil Shapiro ConnRateThrottle); 225312ed1c7cSGregory Neil Shapiro if (LogLevel > 8) 225412ed1c7cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, D_MSG_CRT, 2255951742c4SGregory Neil Shapiro Daemons[dn].d_name, 2256951742c4SGregory Neil Shapiro ConnRateThrottle); 225712ed1c7cSGregory Neil Shapiro (void) sleep(1); 225812ed1c7cSGregory Neil Shapiro } 225912ed1c7cSGregory Neil Shapiro } 2260951742c4SGregory Neil Shapiro else if (now != lastconn[dn]) 2261951742c4SGregory Neil Shapiro conncnt[dn] = 0; 226212ed1c7cSGregory Neil Shapiro } 226312ed1c7cSGregory Neil Shapiro 2264567a2fc9SGregory Neil Shapiro 2265567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT 2266567a2fc9SGregory Neil Shapiro if (RefuseLowMem > 0 && 2267567a2fc9SGregory Neil Shapiro sm_memstat_get(MemoryResource, &memfree) >= 0 && 2268567a2fc9SGregory Neil Shapiro memfree < RefuseLowMem) 2269567a2fc9SGregory Neil Shapiro { 2270567a2fc9SGregory Neil Shapiro # define R_MSG_LM "rejecting connections on daemon %s: free memory: %ld" 2271951742c4SGregory Neil Shapiro sm_setproctitle(true, e, R_MSG_LM, Daemons[dn].d_name, memfree); 2272567a2fc9SGregory Neil Shapiro if (LogLevel > 8) 2273951742c4SGregory Neil Shapiro sm_syslog(LOG_NOTICE, NOQID, R_MSG_LM, 2274951742c4SGregory Neil Shapiro Daemons[dn].d_name, memfree); 2275567a2fc9SGregory Neil Shapiro return true; 2276567a2fc9SGregory Neil Shapiro } 2277567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 227812ed1c7cSGregory Neil Shapiro sm_getla(); 2279951742c4SGregory Neil Shapiro limit = (Daemons[dn].d_refuseLA != DPO_NOTSET) ? 2280951742c4SGregory Neil Shapiro Daemons[dn].d_refuseLA : RefuseLA; 2281951742c4SGregory Neil Shapiro if (limit > 0 && CurrentLA >= limit) 2282c2aa98e2SPeter Wemm { 22832ef40764SGregory Neil Shapiro time_t now; 22842ef40764SGregory Neil Shapiro 228512ed1c7cSGregory Neil Shapiro # define R_MSG_LA "rejecting connections on daemon %s: load average: %d" 2286bfb62e91SGregory Neil Shapiro # define R2_MSG_LA "have been rejecting connections on daemon %s for %s" 2287951742c4SGregory Neil Shapiro sm_setproctitle(true, e, R_MSG_LA, Daemons[dn].d_name, 2288951742c4SGregory Neil Shapiro CurrentLA); 228912ed1c7cSGregory Neil Shapiro if (LogLevel > 8) 2290951742c4SGregory Neil Shapiro sm_syslog(LOG_NOTICE, NOQID, R_MSG_LA, 2291951742c4SGregory Neil Shapiro Daemons[dn].d_name, CurrentLA); 22922ef40764SGregory Neil Shapiro now = curtime(); 2293951742c4SGregory Neil Shapiro if (firstrejtime[dn] == 0) 22942ef40764SGregory Neil Shapiro { 2295951742c4SGregory Neil Shapiro firstrejtime[dn] = now; 2296951742c4SGregory Neil Shapiro nextlogtime[dn] = now + RejectLogInterval; 22972ef40764SGregory Neil Shapiro } 2298951742c4SGregory Neil Shapiro else if (nextlogtime[dn] < now) 22992ef40764SGregory Neil Shapiro { 2300951742c4SGregory Neil Shapiro sm_syslog(LOG_ERR, NOQID, R2_MSG_LA, Daemons[dn].d_name, 2301951742c4SGregory Neil Shapiro pintvl(now - firstrejtime[dn], true)); 2302951742c4SGregory Neil Shapiro nextlogtime[dn] = now + RejectLogInterval; 23032ef40764SGregory Neil Shapiro } 230412ed1c7cSGregory Neil Shapiro return true; 230512ed1c7cSGregory Neil Shapiro } 23062ef40764SGregory Neil Shapiro else 2307951742c4SGregory Neil Shapiro firstrejtime[dn] = 0; 230812ed1c7cSGregory Neil Shapiro 2309951742c4SGregory Neil Shapiro limit = (Daemons[dn].d_delayLA != DPO_NOTSET) ? 2310951742c4SGregory Neil Shapiro Daemons[dn].d_delayLA : DelayLA; 2311951742c4SGregory Neil Shapiro if (limit > 0 && CurrentLA >= limit) 231212ed1c7cSGregory Neil Shapiro { 231312ed1c7cSGregory Neil Shapiro time_t now; 231412ed1c7cSGregory Neil Shapiro static time_t log_delay = (time_t) 0; 231512ed1c7cSGregory Neil Shapiro 231612ed1c7cSGregory Neil Shapiro # define MIN_DELAY_LOG 90 /* wait before logging this again */ 231712ed1c7cSGregory Neil Shapiro # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d" 231812ed1c7cSGregory Neil Shapiro /* sleep to flatten out connection load */ 23199bd497b8SGregory Neil Shapiro sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name, 23209bd497b8SGregory Neil Shapiro CurrentLA, limit); 232112ed1c7cSGregory Neil Shapiro if (LogLevel > 8 && (now = curtime()) > log_delay) 232212ed1c7cSGregory Neil Shapiro { 232312ed1c7cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, D_MSG_LA, 2324951742c4SGregory Neil Shapiro Daemons[dn].d_name, CurrentLA, limit); 232512ed1c7cSGregory Neil Shapiro log_delay = now + MIN_DELAY_LOG; 232612ed1c7cSGregory Neil Shapiro } 232712ed1c7cSGregory Neil Shapiro (void) sleep(1); 2328c2aa98e2SPeter Wemm } 2329c2aa98e2SPeter Wemm 2330951742c4SGregory Neil Shapiro limit = (Daemons[dn].d_maxchildren != DPO_NOTSET) ? 2331951742c4SGregory Neil Shapiro Daemons[dn].d_maxchildren : MaxChildren; 2332951742c4SGregory Neil Shapiro if (limit > 0 && CurChildren >= limit) 2333c2aa98e2SPeter Wemm { 2334c2aa98e2SPeter Wemm proc_list_probe(); 2335951742c4SGregory Neil Shapiro if (CurChildren >= limit) 2336c2aa98e2SPeter Wemm { 233712ed1c7cSGregory Neil Shapiro #define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d" 233812ed1c7cSGregory Neil Shapiro sm_setproctitle(true, e, R_MSG_CHILD, 2339951742c4SGregory Neil Shapiro Daemons[dn].d_name, CurChildren, 2340951742c4SGregory Neil Shapiro limit); 234112ed1c7cSGregory Neil Shapiro if (LogLevel > 8) 234212ed1c7cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD, 2343951742c4SGregory Neil Shapiro Daemons[dn].d_name, CurChildren, 2344951742c4SGregory Neil Shapiro limit); 234512ed1c7cSGregory Neil Shapiro return true; 2346c2aa98e2SPeter Wemm } 2347c2aa98e2SPeter Wemm } 234812ed1c7cSGregory Neil Shapiro return false; 2349c2aa98e2SPeter Wemm } 2350951742c4SGregory Neil Shapiro 235112ed1c7cSGregory Neil Shapiro /* 2352c2aa98e2SPeter Wemm ** SETPROCTITLE -- set process title for ps 2353c2aa98e2SPeter Wemm ** 2354c2aa98e2SPeter Wemm ** Parameters: 2355c2aa98e2SPeter Wemm ** fmt -- a printf style format string. 2356c2aa98e2SPeter Wemm ** a, b, c -- possible parameters to fmt. 2357c2aa98e2SPeter Wemm ** 2358c2aa98e2SPeter Wemm ** Returns: 2359c2aa98e2SPeter Wemm ** none. 2360c2aa98e2SPeter Wemm ** 2361c2aa98e2SPeter Wemm ** Side Effects: 2362c2aa98e2SPeter Wemm ** Clobbers argv of our main procedure so ps(1) will 2363c2aa98e2SPeter Wemm ** display the title. 2364c2aa98e2SPeter Wemm */ 2365c2aa98e2SPeter Wemm 2366c2aa98e2SPeter Wemm #define SPT_NONE 0 /* don't use it at all */ 2367c2aa98e2SPeter Wemm #define SPT_REUSEARGV 1 /* cover argv with title information */ 2368c2aa98e2SPeter Wemm #define SPT_BUILTIN 2 /* use libc builtin */ 2369c2aa98e2SPeter Wemm #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ 2370c2aa98e2SPeter Wemm #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ 2371c2aa98e2SPeter Wemm #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ 2372c2aa98e2SPeter Wemm #define SPT_SCO 6 /* write kernel u. area */ 2373c2aa98e2SPeter Wemm #define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ 2374c2aa98e2SPeter Wemm 2375c2aa98e2SPeter Wemm #ifndef SPT_TYPE 2376c2aa98e2SPeter Wemm # define SPT_TYPE SPT_REUSEARGV 23773299c2f1SGregory Neil Shapiro #endif /* ! SPT_TYPE */ 23783299c2f1SGregory Neil Shapiro 2379c2aa98e2SPeter Wemm 2380c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN 2381c2aa98e2SPeter Wemm 2382c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2383c2aa98e2SPeter Wemm # include <sys/pstat.h> 23843299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */ 2385c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS 2386c2aa98e2SPeter Wemm # include <machine/vmparam.h> 2387c2aa98e2SPeter Wemm # include <sys/exec.h> 2388c2aa98e2SPeter Wemm # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ 2389c2aa98e2SPeter Wemm # undef SPT_TYPE 2390c2aa98e2SPeter Wemm # define SPT_TYPE SPT_REUSEARGV 23913299c2f1SGregory Neil Shapiro # else /* ! PS_STRINGS */ 2392c2aa98e2SPeter Wemm # ifndef NKPDE /* FreeBSD 2.0 */ 2393c2aa98e2SPeter Wemm # define NKPDE 63 2394c2aa98e2SPeter Wemm typedef unsigned int *pt_entry_t; 23953299c2f1SGregory Neil Shapiro # endif /* ! NKPDE */ 23963299c2f1SGregory Neil Shapiro # endif /* ! PS_STRINGS */ 23973299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */ 2398c2aa98e2SPeter Wemm 2399c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV 2400c2aa98e2SPeter Wemm # define SETPROC_STATIC static 24013299c2f1SGregory Neil Shapiro # else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */ 2402c2aa98e2SPeter Wemm # define SETPROC_STATIC 24033299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */ 2404c2aa98e2SPeter Wemm 2405c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS 2406c2aa98e2SPeter Wemm # include <sys/sysmips.h> 2407c2aa98e2SPeter Wemm # include <sys/sysnews.h> 24083299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SYSMIPS */ 2409c2aa98e2SPeter Wemm 2410c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 2411c2aa98e2SPeter Wemm # include <sys/immu.h> 2412c2aa98e2SPeter Wemm # include <sys/dir.h> 2413c2aa98e2SPeter Wemm # include <sys/user.h> 2414c2aa98e2SPeter Wemm # include <sys/fs/s5param.h> 2415c2aa98e2SPeter Wemm # if PSARGSZ > MAXLINE 2416c2aa98e2SPeter Wemm # define SPT_BUFSIZE PSARGSZ 24173299c2f1SGregory Neil Shapiro # endif /* PSARGSZ > MAXLINE */ 24183299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */ 2419c2aa98e2SPeter Wemm 2420c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR 2421c2aa98e2SPeter Wemm # define SPT_PADCHAR ' ' 24223299c2f1SGregory Neil Shapiro # endif /* ! SPT_PADCHAR */ 2423c2aa98e2SPeter Wemm 242476b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ 242576b7bf71SPeter Wemm 2426c2aa98e2SPeter Wemm #ifndef SPT_BUFSIZE 2427c2aa98e2SPeter Wemm # define SPT_BUFSIZE MAXLINE 24283299c2f1SGregory Neil Shapiro #endif /* ! SPT_BUFSIZE */ 2429c2aa98e2SPeter Wemm 243088ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN 243188ad41d4SGregory Neil Shapiro 243288ad41d4SGregory Neil Shapiro /* 243388ad41d4SGregory Neil Shapiro ** It looks like the Compaq Tru64 5.1A now aligns argv and envp to 243488ad41d4SGregory Neil Shapiro ** 64 bit alignment, so unless each piece of argv and envp is a multiple 243588ad41d4SGregory Neil Shapiro ** of 8 bytes (including terminating NULL), initsetproctitle() won't use 243688ad41d4SGregory Neil Shapiro ** any of the space beyond argv[0]. Be sure to set SPT_ALIGN_SIZE if 243788ad41d4SGregory Neil Shapiro ** you use this FFR. 243888ad41d4SGregory Neil Shapiro */ 243988ad41d4SGregory Neil Shapiro 244088ad41d4SGregory Neil Shapiro # ifdef SPT_ALIGN_SIZE 2441f848909fSGregory Neil Shapiro # define SPT_ALIGN(x, align) (((((x) + SPT_ALIGN_SIZE) >> (align)) << (align)) - 1) 244288ad41d4SGregory Neil Shapiro # else /* SPT_ALIGN_SIZE */ 244388ad41d4SGregory Neil Shapiro # define SPT_ALIGN(x, align) (x) 244488ad41d4SGregory Neil Shapiro # endif /* SPT_ALIGN_SIZE */ 244588ad41d4SGregory Neil Shapiro #else /* _FFR_SPT_ALIGN */ 244688ad41d4SGregory Neil Shapiro # define SPT_ALIGN(x, align) (x) 244788ad41d4SGregory Neil Shapiro #endif /* _FFR_SPT_ALIGN */ 244888ad41d4SGregory Neil Shapiro 2449c2aa98e2SPeter Wemm /* 2450c2aa98e2SPeter Wemm ** Pointers for setproctitle. 2451c2aa98e2SPeter Wemm ** This allows "ps" listings to give more useful information. 2452c2aa98e2SPeter Wemm */ 2453c2aa98e2SPeter Wemm 24543299c2f1SGregory Neil Shapiro static char **Argv = NULL; /* pointer to argument vector */ 24553299c2f1SGregory Neil Shapiro static char *LastArgv = NULL; /* end of argv */ 24563299c2f1SGregory Neil Shapiro #if SPT_TYPE != SPT_BUILTIN 24573299c2f1SGregory Neil Shapiro static void setproctitle __P((const char *, ...)); 24583299c2f1SGregory Neil Shapiro #endif /* SPT_TYPE != SPT_BUILTIN */ 2459c2aa98e2SPeter Wemm 2460c2aa98e2SPeter Wemm void 2461c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp) 2462c2aa98e2SPeter Wemm int argc; 2463c2aa98e2SPeter Wemm char **argv; 2464c2aa98e2SPeter Wemm char **envp; 2465c2aa98e2SPeter Wemm { 246612ed1c7cSGregory Neil Shapiro register int i; 246788ad41d4SGregory Neil Shapiro int align; 2468c2aa98e2SPeter Wemm extern char **environ; 2469c2aa98e2SPeter Wemm 2470c2aa98e2SPeter Wemm /* 2471c2aa98e2SPeter Wemm ** Move the environment so setproctitle can use the space at 2472c2aa98e2SPeter Wemm ** the top of memory. 2473c2aa98e2SPeter Wemm */ 2474c2aa98e2SPeter Wemm 24759d8fddc1SGregory Neil Shapiro if (envp != NULL) 24769d8fddc1SGregory Neil Shapiro { 2477c2aa98e2SPeter Wemm for (i = 0; envp[i] != NULL; i++) 247812ed1c7cSGregory Neil Shapiro continue; 2479c2aa98e2SPeter Wemm environ = (char **) xalloc(sizeof(char *) * (i + 1)); 2480c2aa98e2SPeter Wemm for (i = 0; envp[i] != NULL; i++) 2481c2aa98e2SPeter Wemm environ[i] = newstr(envp[i]); 2482c2aa98e2SPeter Wemm environ[i] = NULL; 24839d8fddc1SGregory Neil Shapiro } 2484c2aa98e2SPeter Wemm 2485c2aa98e2SPeter Wemm /* 2486c2aa98e2SPeter Wemm ** Save start and extent of argv for setproctitle. 2487c2aa98e2SPeter Wemm */ 2488c2aa98e2SPeter Wemm 2489c2aa98e2SPeter Wemm Argv = argv; 2490c2aa98e2SPeter Wemm 2491c2aa98e2SPeter Wemm /* 2492c2aa98e2SPeter Wemm ** Determine how much space we can use for setproctitle. 2493c2aa98e2SPeter Wemm ** Use all contiguous argv and envp pointers starting at argv[0] 2494c2aa98e2SPeter Wemm */ 249588ad41d4SGregory Neil Shapiro 249688ad41d4SGregory Neil Shapiro align = -1; 249788ad41d4SGregory Neil Shapiro # if _FFR_SPT_ALIGN 249888ad41d4SGregory Neil Shapiro # ifdef SPT_ALIGN_SIZE 249988ad41d4SGregory Neil Shapiro for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1) 250088ad41d4SGregory Neil Shapiro align++; 250188ad41d4SGregory Neil Shapiro # endif /* SPT_ALIGN_SIZE */ 250288ad41d4SGregory Neil Shapiro # endif /* _FFR_SPT_ALIGN */ 250388ad41d4SGregory Neil Shapiro 2504c2aa98e2SPeter Wemm for (i = 0; i < argc; i++) 2505c2aa98e2SPeter Wemm { 2506c2aa98e2SPeter Wemm if (i == 0 || LastArgv + 1 == argv[i]) 250788ad41d4SGregory Neil Shapiro LastArgv = argv[i] + SPT_ALIGN(strlen(argv[i]), align); 2508c2aa98e2SPeter Wemm } 25099d8fddc1SGregory Neil Shapiro for (i = 0; LastArgv != NULL && envp != NULL && envp[i] != NULL; i++) 2510c2aa98e2SPeter Wemm { 2511c2aa98e2SPeter Wemm if (LastArgv + 1 == envp[i]) 251288ad41d4SGregory Neil Shapiro LastArgv = envp[i] + SPT_ALIGN(strlen(envp[i]), align); 2513c2aa98e2SPeter Wemm } 2514c2aa98e2SPeter Wemm } 2515c2aa98e2SPeter Wemm 2516c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN 2517c2aa98e2SPeter Wemm 2518c2aa98e2SPeter Wemm /*VARARGS1*/ 25193299c2f1SGregory Neil Shapiro static void 2520c2aa98e2SPeter Wemm # ifdef __STDC__ 2521c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...) 25223299c2f1SGregory Neil Shapiro # else /* __STDC__ */ 2523c2aa98e2SPeter Wemm setproctitle(fmt, va_alist) 2524c2aa98e2SPeter Wemm const char *fmt; 2525c2aa98e2SPeter Wemm va_dcl 25263299c2f1SGregory Neil Shapiro # endif /* __STDC__ */ 2527c2aa98e2SPeter Wemm { 2528c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE 2529c2aa98e2SPeter Wemm register int i; 25303299c2f1SGregory Neil Shapiro register char *p; 2531c2aa98e2SPeter Wemm SETPROC_STATIC char buf[SPT_BUFSIZE]; 253212ed1c7cSGregory Neil Shapiro SM_VA_LOCAL_DECL 2533c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2534c2aa98e2SPeter Wemm union pstun pst; 25353299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */ 2536c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 253712ed1c7cSGregory Neil Shapiro int j; 2538c2aa98e2SPeter Wemm off_t seek_off; 2539c2aa98e2SPeter Wemm static int kmem = -1; 2540c0c4794dSGregory Neil Shapiro static pid_t kmempid = -1; 2541c2aa98e2SPeter Wemm struct user u; 25423299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */ 2543c2aa98e2SPeter Wemm 2544c2aa98e2SPeter Wemm p = buf; 2545c2aa98e2SPeter Wemm 2546c2aa98e2SPeter Wemm /* print sendmail: heading for grep */ 254712ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p)); 2548c2aa98e2SPeter Wemm p += strlen(p); 2549c2aa98e2SPeter Wemm 2550c2aa98e2SPeter Wemm /* print the argument string */ 255112ed1c7cSGregory Neil Shapiro SM_VA_START(ap, fmt); 255212ed1c7cSGregory Neil Shapiro (void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap); 255312ed1c7cSGregory Neil Shapiro SM_VA_END(ap); 2554c2aa98e2SPeter Wemm 255512ed1c7cSGregory Neil Shapiro i = (int) strlen(buf); 255612ed1c7cSGregory Neil Shapiro if (i < 0) 255712ed1c7cSGregory Neil Shapiro return; 2558c2aa98e2SPeter Wemm 2559c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT 2560c2aa98e2SPeter Wemm pst.pst_command = buf; 2561c2aa98e2SPeter Wemm pstat(PSTAT_SETCMD, pst, i, 0, 0); 25623299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */ 2563c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS 2564c2aa98e2SPeter Wemm PS_STRINGS->ps_nargvstr = 1; 2565c2aa98e2SPeter Wemm PS_STRINGS->ps_argvstr = buf; 25663299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */ 2567c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS 2568c2aa98e2SPeter Wemm sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); 25693299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SYSMIPS */ 2570c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO 257112ed1c7cSGregory Neil Shapiro if (kmem < 0 || kmempid != CurrentPid) 2572c2aa98e2SPeter Wemm { 2573c2aa98e2SPeter Wemm if (kmem >= 0) 2574c46d91b7SGregory Neil Shapiro (void) close(kmem); 2575c2aa98e2SPeter Wemm kmem = open(_PATH_KMEM, O_RDWR, 0); 2576c2aa98e2SPeter Wemm if (kmem < 0) 2577c2aa98e2SPeter Wemm return; 257812ed1c7cSGregory Neil Shapiro if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || 257912ed1c7cSGregory Neil Shapiro fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) 258012ed1c7cSGregory Neil Shapiro { 258112ed1c7cSGregory Neil Shapiro (void) close(kmem); 258212ed1c7cSGregory Neil Shapiro kmem = -1; 258312ed1c7cSGregory Neil Shapiro return; 258412ed1c7cSGregory Neil Shapiro } 258512ed1c7cSGregory Neil Shapiro kmempid = CurrentPid; 2586c2aa98e2SPeter Wemm } 2587c2aa98e2SPeter Wemm buf[PSARGSZ - 1] = '\0'; 2588c2aa98e2SPeter Wemm seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; 2589c2aa98e2SPeter Wemm if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) 2590c2aa98e2SPeter Wemm (void) write(kmem, buf, PSARGSZ); 25913299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */ 2592c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_REUSEARGV 25933299c2f1SGregory Neil Shapiro if (LastArgv == NULL) 25943299c2f1SGregory Neil Shapiro return; 25953299c2f1SGregory Neil Shapiro 2596c2aa98e2SPeter Wemm if (i > LastArgv - Argv[0] - 2) 2597c2aa98e2SPeter Wemm { 2598c2aa98e2SPeter Wemm i = LastArgv - Argv[0] - 2; 2599c2aa98e2SPeter Wemm buf[i] = '\0'; 2600c2aa98e2SPeter Wemm } 260112ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(Argv[0], buf, i + 1); 2602c2aa98e2SPeter Wemm p = &Argv[0][i]; 2603c2aa98e2SPeter Wemm while (p < LastArgv) 2604c2aa98e2SPeter Wemm *p++ = SPT_PADCHAR; 2605c2aa98e2SPeter Wemm Argv[1] = NULL; 26063299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_REUSEARGV */ 2607c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_CHANGEARGV 2608c2aa98e2SPeter Wemm Argv[0] = buf; 2609c2aa98e2SPeter Wemm Argv[1] = 0; 26103299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_CHANGEARGV */ 2611c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */ 2612c2aa98e2SPeter Wemm } 2613c2aa98e2SPeter Wemm 2614c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */ 261512ed1c7cSGregory Neil Shapiro /* 261676b7bf71SPeter Wemm ** SM_SETPROCTITLE -- set process task and set process title for ps 261776b7bf71SPeter Wemm ** 261876b7bf71SPeter Wemm ** Possibly set process status and call setproctitle() to 261976b7bf71SPeter Wemm ** change the ps display. 262076b7bf71SPeter Wemm ** 262176b7bf71SPeter Wemm ** Parameters: 262276b7bf71SPeter Wemm ** status -- whether or not to store as process status 26233299c2f1SGregory Neil Shapiro ** e -- the current envelope. 262476b7bf71SPeter Wemm ** fmt -- a printf style format string. 262576b7bf71SPeter Wemm ** a, b, c -- possible parameters to fmt. 262676b7bf71SPeter Wemm ** 262776b7bf71SPeter Wemm ** Returns: 262876b7bf71SPeter Wemm ** none. 262976b7bf71SPeter Wemm */ 263076b7bf71SPeter Wemm 26316f9c8e5bSGregory Neil Shapiro /*VARARGS3*/ 263276b7bf71SPeter Wemm void 263376b7bf71SPeter Wemm #ifdef __STDC__ 26343299c2f1SGregory Neil Shapiro sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...) 26353299c2f1SGregory Neil Shapiro #else /* __STDC__ */ 26363299c2f1SGregory Neil Shapiro sm_setproctitle(status, e, fmt, va_alist) 263776b7bf71SPeter Wemm bool status; 26383299c2f1SGregory Neil Shapiro ENVELOPE *e; 263976b7bf71SPeter Wemm const char *fmt; 264076b7bf71SPeter Wemm va_dcl 26413299c2f1SGregory Neil Shapiro #endif /* __STDC__ */ 264276b7bf71SPeter Wemm { 264376b7bf71SPeter Wemm char buf[SPT_BUFSIZE]; 264412ed1c7cSGregory Neil Shapiro SM_VA_LOCAL_DECL 26453299c2f1SGregory Neil Shapiro 264676b7bf71SPeter Wemm /* print the argument string */ 264712ed1c7cSGregory Neil Shapiro SM_VA_START(ap, fmt); 2648951742c4SGregory Neil Shapiro (void) sm_vsnprintf(buf, sizeof(buf), fmt, ap); 264912ed1c7cSGregory Neil Shapiro SM_VA_END(ap); 265076b7bf71SPeter Wemm 265176b7bf71SPeter Wemm if (status) 265212ed1c7cSGregory Neil Shapiro proc_list_set(CurrentPid, buf); 26533299c2f1SGregory Neil Shapiro 26543299c2f1SGregory Neil Shapiro if (ProcTitlePrefix != NULL) 26553299c2f1SGregory Neil Shapiro { 26563299c2f1SGregory Neil Shapiro char prefix[SPT_BUFSIZE]; 26573299c2f1SGregory Neil Shapiro 2658951742c4SGregory Neil Shapiro expand(ProcTitlePrefix, prefix, sizeof(prefix), e); 26593299c2f1SGregory Neil Shapiro setproctitle("%s: %s", prefix, buf); 26603299c2f1SGregory Neil Shapiro } 26613299c2f1SGregory Neil Shapiro else 266276b7bf71SPeter Wemm setproctitle("%s", buf); 266376b7bf71SPeter Wemm } 266412ed1c7cSGregory Neil Shapiro /* 2665c2aa98e2SPeter Wemm ** WAITFOR -- wait for a particular process id. 2666c2aa98e2SPeter Wemm ** 2667c2aa98e2SPeter Wemm ** Parameters: 2668c2aa98e2SPeter Wemm ** pid -- process id to wait for. 2669c2aa98e2SPeter Wemm ** 2670c2aa98e2SPeter Wemm ** Returns: 2671c2aa98e2SPeter Wemm ** status of pid. 2672c2aa98e2SPeter Wemm ** -1 if pid never shows up. 2673c2aa98e2SPeter Wemm ** 2674c2aa98e2SPeter Wemm ** Side Effects: 2675c2aa98e2SPeter Wemm ** none. 2676c2aa98e2SPeter Wemm */ 2677c2aa98e2SPeter Wemm 2678c2aa98e2SPeter Wemm int 2679c2aa98e2SPeter Wemm waitfor(pid) 2680c2aa98e2SPeter Wemm pid_t pid; 2681c2aa98e2SPeter Wemm { 268212ed1c7cSGregory Neil Shapiro int st; 268312ed1c7cSGregory Neil Shapiro pid_t i; 268412ed1c7cSGregory Neil Shapiro 268512ed1c7cSGregory Neil Shapiro do 268612ed1c7cSGregory Neil Shapiro { 268712ed1c7cSGregory Neil Shapiro errno = 0; 268812ed1c7cSGregory Neil Shapiro i = sm_wait(&st); 268912ed1c7cSGregory Neil Shapiro if (i > 0) 269012ed1c7cSGregory Neil Shapiro proc_list_drop(i, st, NULL); 269112ed1c7cSGregory Neil Shapiro } while ((i >= 0 || errno == EINTR) && i != pid); 269212ed1c7cSGregory Neil Shapiro if (i < 0) 269312ed1c7cSGregory Neil Shapiro return -1; 269412ed1c7cSGregory Neil Shapiro return st; 269512ed1c7cSGregory Neil Shapiro } 269612ed1c7cSGregory Neil Shapiro /* 269712ed1c7cSGregory Neil Shapiro ** SM_WAIT -- wait 269812ed1c7cSGregory Neil Shapiro ** 269912ed1c7cSGregory Neil Shapiro ** Parameters: 270012ed1c7cSGregory Neil Shapiro ** status -- pointer to status (return value) 270112ed1c7cSGregory Neil Shapiro ** 270212ed1c7cSGregory Neil Shapiro ** Returns: 270312ed1c7cSGregory Neil Shapiro ** pid 270412ed1c7cSGregory Neil Shapiro */ 270512ed1c7cSGregory Neil Shapiro 270612ed1c7cSGregory Neil Shapiro pid_t 270712ed1c7cSGregory Neil Shapiro sm_wait(status) 270812ed1c7cSGregory Neil Shapiro int *status; 270912ed1c7cSGregory Neil Shapiro { 2710c2aa98e2SPeter Wemm # ifdef WAITUNION 2711c2aa98e2SPeter Wemm union wait st; 27123299c2f1SGregory Neil Shapiro # else /* WAITUNION */ 2713c2aa98e2SPeter Wemm auto int st; 27143299c2f1SGregory Neil Shapiro # endif /* WAITUNION */ 2715c2aa98e2SPeter Wemm pid_t i; 2716c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_) 2717c2aa98e2SPeter Wemm int savesig; 27183299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ 2719c2aa98e2SPeter Wemm 2720c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_) 272112ed1c7cSGregory Neil Shapiro savesig = sm_releasesignal(SIGCHLD); 27223299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ 2723c2aa98e2SPeter Wemm i = wait(&st); 2724c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_) 2725c2aa98e2SPeter Wemm if (savesig > 0) 272612ed1c7cSGregory Neil Shapiro sm_blocksignal(SIGCHLD); 27273299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ 2728c2aa98e2SPeter Wemm # ifdef WAITUNION 272912ed1c7cSGregory Neil Shapiro *status = st.w_status; 27303299c2f1SGregory Neil Shapiro # else /* WAITUNION */ 273112ed1c7cSGregory Neil Shapiro *status = st; 27323299c2f1SGregory Neil Shapiro # endif /* WAITUNION */ 273312ed1c7cSGregory Neil Shapiro return i; 2734c2aa98e2SPeter Wemm } 273512ed1c7cSGregory Neil Shapiro /* 2736c2aa98e2SPeter Wemm ** REAPCHILD -- pick up the body of my child, lest it become a zombie 2737c2aa98e2SPeter Wemm ** 2738c2aa98e2SPeter Wemm ** Parameters: 2739c2aa98e2SPeter Wemm ** sig -- the signal that got us here (unused). 2740c2aa98e2SPeter Wemm ** 2741c2aa98e2SPeter Wemm ** Returns: 2742c2aa98e2SPeter Wemm ** none. 2743c2aa98e2SPeter Wemm ** 2744c2aa98e2SPeter Wemm ** Side Effects: 2745c2aa98e2SPeter Wemm ** Picks up extant zombies. 27463299c2f1SGregory Neil Shapiro ** Control socket exits may restart/shutdown daemon. 2747c0c4794dSGregory Neil Shapiro ** 2748c0c4794dSGregory Neil Shapiro ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 2749c0c4794dSGregory Neil Shapiro ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 2750c0c4794dSGregory Neil Shapiro ** DOING. 2751c2aa98e2SPeter Wemm */ 2752c2aa98e2SPeter Wemm 27533299c2f1SGregory Neil Shapiro /* ARGSUSED0 */ 2754c2aa98e2SPeter Wemm SIGFUNC_DECL 2755c2aa98e2SPeter Wemm reapchild(sig) 2756c2aa98e2SPeter Wemm int sig; 2757c2aa98e2SPeter Wemm { 27583299c2f1SGregory Neil Shapiro int save_errno = errno; 27593299c2f1SGregory Neil Shapiro int st; 2760c2aa98e2SPeter Wemm pid_t pid; 27613299c2f1SGregory Neil Shapiro # if HASWAITPID 2762c2aa98e2SPeter Wemm auto int status; 2763c2aa98e2SPeter Wemm int count; 2764c2aa98e2SPeter Wemm 2765c2aa98e2SPeter Wemm count = 0; 2766c2aa98e2SPeter Wemm while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 2767c2aa98e2SPeter Wemm { 27683299c2f1SGregory Neil Shapiro st = status; 2769c2aa98e2SPeter Wemm if (count++ > 1000) 2770c2aa98e2SPeter Wemm break; 27713299c2f1SGregory Neil Shapiro # else /* HASWAITPID */ 2772c2aa98e2SPeter Wemm # ifdef WNOHANG 277312ed1c7cSGregory Neil Shapiro union wait status; 277412ed1c7cSGregory Neil Shapiro 2775c2aa98e2SPeter Wemm while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0) 27763299c2f1SGregory Neil Shapiro { 27773299c2f1SGregory Neil Shapiro st = status.w_status; 2778c2aa98e2SPeter Wemm # else /* WNOHANG */ 277912ed1c7cSGregory Neil Shapiro auto int status; 278012ed1c7cSGregory Neil Shapiro 2781c2aa98e2SPeter Wemm /* 2782c2aa98e2SPeter Wemm ** Catch one zombie -- we will be re-invoked (we hope) if there 2783c2aa98e2SPeter Wemm ** are more. Unreliable signals probably break this, but this 2784c2aa98e2SPeter Wemm ** is the "old system" situation -- waitpid or wait3 are to be 2785c2aa98e2SPeter Wemm ** strongly preferred. 2786c2aa98e2SPeter Wemm */ 2787c2aa98e2SPeter Wemm 2788c2aa98e2SPeter Wemm if ((pid = wait(&status)) > 0) 27893299c2f1SGregory Neil Shapiro { 27903299c2f1SGregory Neil Shapiro st = status; 2791c2aa98e2SPeter Wemm # endif /* WNOHANG */ 27923299c2f1SGregory Neil Shapiro # endif /* HASWAITPID */ 27933299c2f1SGregory Neil Shapiro /* Drop PID and check if it was a control socket child */ 279412ed1c7cSGregory Neil Shapiro proc_list_drop(pid, st, NULL); 27953299c2f1SGregory Neil Shapiro } 2796c0c4794dSGregory Neil Shapiro FIX_SYSV_SIGNAL(sig, reapchild); 27973299c2f1SGregory Neil Shapiro errno = save_errno; 2798c2aa98e2SPeter Wemm return SIGFUNC_RETURN; 2799c2aa98e2SPeter Wemm } 2800c2aa98e2SPeter Wemm /* 2801da7d7b9cSGregory Neil Shapiro ** GETDTSIZE -- return number of file descriptors 2802c2aa98e2SPeter Wemm ** 2803c2aa98e2SPeter Wemm ** Only on non-BSD systems 2804c2aa98e2SPeter Wemm ** 2805c2aa98e2SPeter Wemm ** Parameters: 2806c2aa98e2SPeter Wemm ** none 2807c2aa98e2SPeter Wemm ** 2808c2aa98e2SPeter Wemm ** Returns: 2809c2aa98e2SPeter Wemm ** size of file descriptor table 2810c2aa98e2SPeter Wemm ** 2811c2aa98e2SPeter Wemm ** Side Effects: 2812c2aa98e2SPeter Wemm ** none 2813c2aa98e2SPeter Wemm */ 2814c2aa98e2SPeter Wemm 2815c2aa98e2SPeter Wemm #ifdef SOLARIS 2816c2aa98e2SPeter Wemm # include <sys/resource.h> 28173299c2f1SGregory Neil Shapiro #endif /* SOLARIS */ 2818c2aa98e2SPeter Wemm 2819c2aa98e2SPeter Wemm int 2820c2aa98e2SPeter Wemm getdtsize() 2821c2aa98e2SPeter Wemm { 2822c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE 2823c2aa98e2SPeter Wemm struct rlimit rl; 2824c2aa98e2SPeter Wemm 2825c2aa98e2SPeter Wemm if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) 2826c2aa98e2SPeter Wemm return rl.rlim_cur; 28273299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */ 2828c2aa98e2SPeter Wemm 28293299c2f1SGregory Neil Shapiro # if HASGETDTABLESIZE 2830c2aa98e2SPeter Wemm return getdtablesize(); 28313299c2f1SGregory Neil Shapiro # else /* HASGETDTABLESIZE */ 2832c2aa98e2SPeter Wemm # ifdef _SC_OPEN_MAX 2833c2aa98e2SPeter Wemm return sysconf(_SC_OPEN_MAX); 28343299c2f1SGregory Neil Shapiro # else /* _SC_OPEN_MAX */ 2835c2aa98e2SPeter Wemm return NOFILE; 28363299c2f1SGregory Neil Shapiro # endif /* _SC_OPEN_MAX */ 28373299c2f1SGregory Neil Shapiro # endif /* HASGETDTABLESIZE */ 2838c2aa98e2SPeter Wemm } 283912ed1c7cSGregory Neil Shapiro /* 2840c2aa98e2SPeter Wemm ** UNAME -- get the UUCP name of this system. 2841c2aa98e2SPeter Wemm */ 2842c2aa98e2SPeter Wemm 28433299c2f1SGregory Neil Shapiro #if !HASUNAME 2844c2aa98e2SPeter Wemm 2845c2aa98e2SPeter Wemm int 2846c2aa98e2SPeter Wemm uname(name) 2847c2aa98e2SPeter Wemm struct utsname *name; 2848c2aa98e2SPeter Wemm { 284912ed1c7cSGregory Neil Shapiro SM_FILE_T *file; 2850c2aa98e2SPeter Wemm char *n; 2851c2aa98e2SPeter Wemm 2852c2aa98e2SPeter Wemm name->nodename[0] = '\0'; 2853c2aa98e2SPeter Wemm 2854c2aa98e2SPeter Wemm /* try /etc/whoami -- one line with the node name */ 285512ed1c7cSGregory Neil Shapiro if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami", 285612ed1c7cSGregory Neil Shapiro SM_IO_RDONLY, NULL)) != NULL) 2857c2aa98e2SPeter Wemm { 285812ed1c7cSGregory Neil Shapiro (void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename, 285912ed1c7cSGregory Neil Shapiro NODE_LENGTH + 1); 286012ed1c7cSGregory Neil Shapiro (void) sm_io_close(file, SM_TIME_DEFAULT); 2861c2aa98e2SPeter Wemm n = strchr(name->nodename, '\n'); 2862c2aa98e2SPeter Wemm if (n != NULL) 2863c2aa98e2SPeter Wemm *n = '\0'; 2864c2aa98e2SPeter Wemm if (name->nodename[0] != '\0') 28653299c2f1SGregory Neil Shapiro return 0; 2866c2aa98e2SPeter Wemm } 2867c2aa98e2SPeter Wemm 2868c2aa98e2SPeter Wemm /* try /usr/include/whoami.h -- has a #define somewhere */ 286912ed1c7cSGregory Neil Shapiro if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, 287012ed1c7cSGregory Neil Shapiro "/usr/include/whoami.h", SM_IO_RDONLY, NULL)) 287112ed1c7cSGregory Neil Shapiro != NULL) 2872c2aa98e2SPeter Wemm { 2873c2aa98e2SPeter Wemm char buf[MAXLINE]; 2874c2aa98e2SPeter Wemm 287588ad41d4SGregory Neil Shapiro while (sm_io_fgets(file, SM_TIME_DEFAULT, 2876552d4955SGregory Neil Shapiro buf, sizeof(buf)) >= 0) 28773299c2f1SGregory Neil Shapiro { 287812ed1c7cSGregory Neil Shapiro if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"", 2879c2aa98e2SPeter Wemm NODE_LENGTH, name->nodename) > 0) 2880c2aa98e2SPeter Wemm break; 28813299c2f1SGregory Neil Shapiro } 288212ed1c7cSGregory Neil Shapiro (void) sm_io_close(file, SM_TIME_DEFAULT); 2883c2aa98e2SPeter Wemm if (name->nodename[0] != '\0') 28843299c2f1SGregory Neil Shapiro return 0; 2885c2aa98e2SPeter Wemm } 2886c2aa98e2SPeter Wemm 28873299c2f1SGregory Neil Shapiro return -1; 2888c2aa98e2SPeter Wemm } 28893299c2f1SGregory Neil Shapiro #endif /* !HASUNAME */ 289012ed1c7cSGregory Neil Shapiro /* 2891c2aa98e2SPeter Wemm ** INITGROUPS -- initialize groups 2892c2aa98e2SPeter Wemm ** 2893c2aa98e2SPeter Wemm ** Stub implementation for System V style systems 2894c2aa98e2SPeter Wemm */ 2895c2aa98e2SPeter Wemm 28963299c2f1SGregory Neil Shapiro #if !HASINITGROUPS 2897c2aa98e2SPeter Wemm 2898c2aa98e2SPeter Wemm initgroups(name, basegid) 2899c2aa98e2SPeter Wemm char *name; 2900c2aa98e2SPeter Wemm int basegid; 2901c2aa98e2SPeter Wemm { 2902c2aa98e2SPeter Wemm return 0; 2903c2aa98e2SPeter Wemm } 2904c2aa98e2SPeter Wemm 29053299c2f1SGregory Neil Shapiro #endif /* !HASINITGROUPS */ 290612ed1c7cSGregory Neil Shapiro /* 2907c2aa98e2SPeter Wemm ** SETGROUPS -- set group list 2908c2aa98e2SPeter Wemm ** 2909c2aa98e2SPeter Wemm ** Stub implementation for systems that don't have group lists 2910c2aa98e2SPeter Wemm */ 2911c2aa98e2SPeter Wemm 2912c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX 2913c2aa98e2SPeter Wemm 2914c2aa98e2SPeter Wemm int 2915c2aa98e2SPeter Wemm setgroups(ngroups, grouplist) 2916c2aa98e2SPeter Wemm int ngroups; 2917c2aa98e2SPeter Wemm GIDSET_T grouplist[]; 2918c2aa98e2SPeter Wemm { 2919c2aa98e2SPeter Wemm return 0; 2920c2aa98e2SPeter Wemm } 2921c2aa98e2SPeter Wemm 29223299c2f1SGregory Neil Shapiro #endif /* ! NGROUPS_MAX */ 292312ed1c7cSGregory Neil Shapiro /* 2924c2aa98e2SPeter Wemm ** SETSID -- set session id (for non-POSIX systems) 2925c2aa98e2SPeter Wemm */ 2926c2aa98e2SPeter Wemm 29273299c2f1SGregory Neil Shapiro #if !HASSETSID 2928c2aa98e2SPeter Wemm 2929c2aa98e2SPeter Wemm pid_t 2930c2aa98e2SPeter Wemm setsid __P ((void)) 2931c2aa98e2SPeter Wemm { 2932c2aa98e2SPeter Wemm # ifdef TIOCNOTTY 2933c2aa98e2SPeter Wemm int fd; 2934c2aa98e2SPeter Wemm 2935c2aa98e2SPeter Wemm fd = open("/dev/tty", O_RDWR, 0); 2936c2aa98e2SPeter Wemm if (fd >= 0) 2937c2aa98e2SPeter Wemm { 2938d995d2baSGregory Neil Shapiro (void) ioctl(fd, TIOCNOTTY, (char *) 0); 2939c2aa98e2SPeter Wemm (void) close(fd); 2940c2aa98e2SPeter Wemm } 2941c2aa98e2SPeter Wemm # endif /* TIOCNOTTY */ 2942c2aa98e2SPeter Wemm # ifdef SYS5SETPGRP 2943c2aa98e2SPeter Wemm return setpgrp(); 29443299c2f1SGregory Neil Shapiro # else /* SYS5SETPGRP */ 294512ed1c7cSGregory Neil Shapiro return setpgid(0, CurrentPid); 29463299c2f1SGregory Neil Shapiro # endif /* SYS5SETPGRP */ 2947c2aa98e2SPeter Wemm } 2948c2aa98e2SPeter Wemm 29493299c2f1SGregory Neil Shapiro #endif /* !HASSETSID */ 295012ed1c7cSGregory Neil Shapiro /* 2951c2aa98e2SPeter Wemm ** FSYNC -- dummy fsync 2952c2aa98e2SPeter Wemm */ 2953c2aa98e2SPeter Wemm 29543299c2f1SGregory Neil Shapiro #if NEEDFSYNC 2955c2aa98e2SPeter Wemm 2956c2aa98e2SPeter Wemm fsync(fd) 2957c2aa98e2SPeter Wemm int fd; 2958c2aa98e2SPeter Wemm { 2959c2aa98e2SPeter Wemm # ifdef O_SYNC 2960c2aa98e2SPeter Wemm return fcntl(fd, F_SETFL, O_SYNC); 29613299c2f1SGregory Neil Shapiro # else /* O_SYNC */ 2962c2aa98e2SPeter Wemm /* nothing we can do */ 2963c2aa98e2SPeter Wemm return 0; 29643299c2f1SGregory Neil Shapiro # endif /* O_SYNC */ 2965c2aa98e2SPeter Wemm } 2966c2aa98e2SPeter Wemm 29673299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */ 296812ed1c7cSGregory Neil Shapiro /* 2969c2aa98e2SPeter Wemm ** DGUX_INET_ADDR -- inet_addr for DG/UX 2970c2aa98e2SPeter Wemm ** 2971c2aa98e2SPeter Wemm ** Data General DG/UX version of inet_addr returns a struct in_addr 2972c2aa98e2SPeter Wemm ** instead of a long. This patches things. Only needed on versions 2973c2aa98e2SPeter Wemm ** prior to 5.4.3. 2974c2aa98e2SPeter Wemm */ 2975c2aa98e2SPeter Wemm 2976c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2 2977c2aa98e2SPeter Wemm 2978c2aa98e2SPeter Wemm # undef inet_addr 2979c2aa98e2SPeter Wemm 2980c2aa98e2SPeter Wemm long 2981c2aa98e2SPeter Wemm dgux_inet_addr(host) 2982c2aa98e2SPeter Wemm char *host; 2983c2aa98e2SPeter Wemm { 2984c2aa98e2SPeter Wemm struct in_addr haddr; 2985c2aa98e2SPeter Wemm 2986c2aa98e2SPeter Wemm haddr = inet_addr(host); 2987c2aa98e2SPeter Wemm return haddr.s_addr; 2988c2aa98e2SPeter Wemm } 2989c2aa98e2SPeter Wemm 29903299c2f1SGregory Neil Shapiro #endif /* DGUX_5_4_2 */ 299112ed1c7cSGregory Neil Shapiro /* 2992c2aa98e2SPeter Wemm ** GETOPT -- for old systems or systems with bogus implementations 2993c2aa98e2SPeter Wemm */ 2994c2aa98e2SPeter Wemm 299512ed1c7cSGregory Neil Shapiro #if !SM_CONF_GETOPT 2996c2aa98e2SPeter Wemm 2997c2aa98e2SPeter Wemm /* 2998c2aa98e2SPeter Wemm * Copyright (c) 1985 Regents of the University of California. 2999c2aa98e2SPeter Wemm * All rights reserved. The Berkeley software License Agreement 3000c2aa98e2SPeter Wemm * specifies the terms and conditions for redistribution. 3001c2aa98e2SPeter Wemm */ 3002c2aa98e2SPeter Wemm 3003c2aa98e2SPeter Wemm 3004c2aa98e2SPeter Wemm /* 3005c2aa98e2SPeter Wemm ** this version hacked to add `atend' flag to allow state machine 3006c2aa98e2SPeter Wemm ** to reset if invoked by the program to scan args for a 2nd time 3007c2aa98e2SPeter Wemm */ 3008c2aa98e2SPeter Wemm 3009c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint) 3010c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86"; 30113299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */ 3012c2aa98e2SPeter Wemm 3013c2aa98e2SPeter Wemm /* 301412ed1c7cSGregory Neil Shapiro ** get option letter from argument vector 3015c2aa98e2SPeter Wemm */ 3016c2aa98e2SPeter Wemm # ifdef _CONVEX_SOURCE 3017c2aa98e2SPeter Wemm extern int optind, opterr, optopt; 3018c2aa98e2SPeter Wemm extern char *optarg; 30193299c2f1SGregory Neil Shapiro # else /* _CONVEX_SOURCE */ 3020c2aa98e2SPeter Wemm int opterr = 1; /* if error message should be printed */ 3021c2aa98e2SPeter Wemm int optind = 1; /* index into parent argv vector */ 3022c2aa98e2SPeter Wemm int optopt = 0; /* character checked for validity */ 3023c2aa98e2SPeter Wemm char *optarg = NULL; /* argument associated with option */ 30243299c2f1SGregory Neil Shapiro # endif /* _CONVEX_SOURCE */ 3025c2aa98e2SPeter Wemm 3026c2aa98e2SPeter Wemm # define BADCH (int)'?' 3027c2aa98e2SPeter Wemm # define EMSG "" 302812ed1c7cSGregory Neil Shapiro # define tell(s) if (opterr) \ 302912ed1c7cSGregory Neil Shapiro {sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \ 303012ed1c7cSGregory Neil Shapiro (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \ 303112ed1c7cSGregory Neil Shapiro (void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \ 303212ed1c7cSGregory Neil Shapiro (void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \ 303312ed1c7cSGregory Neil Shapiro return BADCH;} 3034c2aa98e2SPeter Wemm 3035c2aa98e2SPeter Wemm int 3036c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr) 3037c2aa98e2SPeter Wemm int nargc; 3038c2aa98e2SPeter Wemm char *const *nargv; 3039c2aa98e2SPeter Wemm const char *ostr; 3040c2aa98e2SPeter Wemm { 3041c2aa98e2SPeter Wemm static char *place = EMSG; /* option letter processing */ 3042c2aa98e2SPeter Wemm static char atend = 0; 3043c2aa98e2SPeter Wemm register char *oli = NULL; /* option letter list index */ 3044c2aa98e2SPeter Wemm 3045c2aa98e2SPeter Wemm if (atend) { 3046c2aa98e2SPeter Wemm atend = 0; 3047c2aa98e2SPeter Wemm place = EMSG; 3048c2aa98e2SPeter Wemm } 3049c2aa98e2SPeter Wemm if(!*place) { /* update scanning pointer */ 3050c2aa98e2SPeter Wemm if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) { 3051c2aa98e2SPeter Wemm atend++; 3052c2aa98e2SPeter Wemm return -1; 3053c2aa98e2SPeter Wemm } 3054c2aa98e2SPeter Wemm if (*place == '-') { /* found "--" */ 3055c2aa98e2SPeter Wemm ++optind; 3056c2aa98e2SPeter Wemm atend++; 3057c2aa98e2SPeter Wemm return -1; 3058c2aa98e2SPeter Wemm } 3059c2aa98e2SPeter Wemm } /* option letter okay? */ 3060c2aa98e2SPeter Wemm if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) { 3061c2aa98e2SPeter Wemm if (!*place) ++optind; 3062c2aa98e2SPeter Wemm tell(": illegal option -- "); 3063c2aa98e2SPeter Wemm } 3064c2aa98e2SPeter Wemm if (oli && *++oli != ':') { /* don't need argument */ 3065c2aa98e2SPeter Wemm optarg = NULL; 3066c2aa98e2SPeter Wemm if (!*place) ++optind; 3067c2aa98e2SPeter Wemm } 3068c2aa98e2SPeter Wemm else { /* need an argument */ 3069c2aa98e2SPeter Wemm if (*place) optarg = place; /* no white space */ 3070c2aa98e2SPeter Wemm else if (nargc <= ++optind) { /* no arg */ 3071c2aa98e2SPeter Wemm place = EMSG; 3072c2aa98e2SPeter Wemm tell(": option requires an argument -- "); 3073c2aa98e2SPeter Wemm } 3074c2aa98e2SPeter Wemm else optarg = nargv[optind]; /* white space */ 3075c2aa98e2SPeter Wemm place = EMSG; 3076c2aa98e2SPeter Wemm ++optind; 3077c2aa98e2SPeter Wemm } 307812ed1c7cSGregory Neil Shapiro return optopt; /* dump back option letter */ 3079c2aa98e2SPeter Wemm } 3080c2aa98e2SPeter Wemm 308112ed1c7cSGregory Neil Shapiro #endif /* !SM_CONF_GETOPT */ 308212ed1c7cSGregory Neil Shapiro /* 3083c2aa98e2SPeter Wemm ** USERSHELLOK -- tell if a user's shell is ok for unrestricted use 3084c2aa98e2SPeter Wemm ** 3085c2aa98e2SPeter Wemm ** Parameters: 3086c2aa98e2SPeter Wemm ** user -- the name of the user we are checking. 3087c2aa98e2SPeter Wemm ** shell -- the user's shell from /etc/passwd 3088c2aa98e2SPeter Wemm ** 3089c2aa98e2SPeter Wemm ** Returns: 309012ed1c7cSGregory Neil Shapiro ** true -- if it is ok to use this for unrestricted access. 309112ed1c7cSGregory Neil Shapiro ** false -- if the shell is restricted. 3092c2aa98e2SPeter Wemm */ 3093c2aa98e2SPeter Wemm 3094c2aa98e2SPeter Wemm #if !HASGETUSERSHELL 3095c2aa98e2SPeter Wemm 3096c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS 3097c2aa98e2SPeter Wemm # define _PATH_SHELLS "/etc/shells" 30983299c2f1SGregory Neil Shapiro # endif /* ! _PATH_SHELLS */ 3099c2aa98e2SPeter Wemm 3100c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4) 3101c2aa98e2SPeter Wemm # include <userconf.h> 3102c2aa98e2SPeter Wemm # if _AIX4 >= 40200 3103c2aa98e2SPeter Wemm # include <userpw.h> 31043299c2f1SGregory Neil Shapiro # endif /* _AIX4 >= 40200 */ 3105c2aa98e2SPeter Wemm # include <usersec.h> 31063299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */ 3107c2aa98e2SPeter Wemm 31083299c2f1SGregory Neil Shapiro static char *DefaultUserShells[] = 3109c2aa98e2SPeter Wemm { 3110c2aa98e2SPeter Wemm "/bin/sh", /* standard shell */ 311112ed1c7cSGregory Neil Shapiro # ifdef MPE 311212ed1c7cSGregory Neil Shapiro "/SYS/PUB/CI", 311312ed1c7cSGregory Neil Shapiro # else /* MPE */ 3114c2aa98e2SPeter Wemm "/usr/bin/sh", 3115c2aa98e2SPeter Wemm "/bin/csh", /* C shell */ 3116c2aa98e2SPeter Wemm "/usr/bin/csh", 311712ed1c7cSGregory Neil Shapiro # endif /* MPE */ 3118c2aa98e2SPeter Wemm # ifdef __hpux 3119c2aa98e2SPeter Wemm # ifdef V4FS 3120c2aa98e2SPeter Wemm "/usr/bin/rsh", /* restricted Bourne shell */ 3121c2aa98e2SPeter Wemm "/usr/bin/ksh", /* Korn shell */ 3122c2aa98e2SPeter Wemm "/usr/bin/rksh", /* restricted Korn shell */ 3123c2aa98e2SPeter Wemm "/usr/bin/pam", 3124c2aa98e2SPeter Wemm "/usr/bin/keysh", /* key shell (extended Korn shell) */ 3125c2aa98e2SPeter Wemm "/usr/bin/posix/sh", 31263299c2f1SGregory Neil Shapiro # else /* V4FS */ 3127c2aa98e2SPeter Wemm "/bin/rsh", /* restricted Bourne shell */ 3128c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3129c2aa98e2SPeter Wemm "/bin/rksh", /* restricted Korn shell */ 3130c2aa98e2SPeter Wemm "/bin/pam", 3131c2aa98e2SPeter Wemm "/usr/bin/keysh", /* key shell (extended Korn shell) */ 3132c2aa98e2SPeter Wemm "/bin/posix/sh", 313372936242SGregory Neil Shapiro "/sbin/sh", 31343299c2f1SGregory Neil Shapiro # endif /* V4FS */ 31353299c2f1SGregory Neil Shapiro # endif /* __hpux */ 3136c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4) 3137c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3138c2aa98e2SPeter Wemm "/usr/bin/ksh", 3139c2aa98e2SPeter Wemm "/bin/tsh", /* trusted shell */ 3140c2aa98e2SPeter Wemm "/usr/bin/tsh", 3141c2aa98e2SPeter Wemm "/bin/bsh", /* Bourne shell */ 3142c2aa98e2SPeter Wemm "/usr/bin/bsh", 31433299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */ 314476b7bf71SPeter Wemm # if defined(__svr4__) || defined(__svr5__) 3145c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3146c2aa98e2SPeter Wemm "/usr/bin/ksh", 31473299c2f1SGregory Neil Shapiro # endif /* defined(__svr4__) || defined(__svr5__) */ 3148c2aa98e2SPeter Wemm # ifdef sgi 3149c2aa98e2SPeter Wemm "/sbin/sh", /* SGI's shells really live in /sbin */ 31509d8fddc1SGregory Neil Shapiro "/usr/bin/sh", 31512ef40764SGregory Neil Shapiro "/sbin/bsh", /* classic Bourne shell */ 31529d8fddc1SGregory Neil Shapiro "/bin/bsh", 31539d8fddc1SGregory Neil Shapiro "/usr/bin/bsh", 31549d8fddc1SGregory Neil Shapiro "/sbin/csh", /* standard csh */ 31559d8fddc1SGregory Neil Shapiro "/bin/csh", 31569d8fddc1SGregory Neil Shapiro "/usr/bin/csh", 31572ef40764SGregory Neil Shapiro "/sbin/jsh", /* classic Bourne shell w/ job control*/ 31589d8fddc1SGregory Neil Shapiro "/bin/jsh", 31599d8fddc1SGregory Neil Shapiro "/usr/bin/jsh", 3160c2aa98e2SPeter Wemm "/bin/ksh", /* Korn shell */ 3161c2aa98e2SPeter Wemm "/sbin/ksh", 3162c2aa98e2SPeter Wemm "/usr/bin/ksh", 31639d8fddc1SGregory Neil Shapiro "/sbin/tcsh", /* Extended csh */ 31649d8fddc1SGregory Neil Shapiro "/bin/tcsh", 3165c2aa98e2SPeter Wemm "/usr/bin/tcsh", 31663299c2f1SGregory Neil Shapiro # endif /* sgi */ 3167c2aa98e2SPeter Wemm NULL 3168c2aa98e2SPeter Wemm }; 3169c2aa98e2SPeter Wemm 31703299c2f1SGregory Neil Shapiro #endif /* !HASGETUSERSHELL */ 3171c2aa98e2SPeter Wemm 3172c2aa98e2SPeter Wemm #define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/" 3173c2aa98e2SPeter Wemm 3174c2aa98e2SPeter Wemm bool 3175c2aa98e2SPeter Wemm usershellok(user, shell) 3176c2aa98e2SPeter Wemm char *user; 3177c2aa98e2SPeter Wemm char *shell; 3178c2aa98e2SPeter Wemm { 3179c2aa98e2SPeter Wemm # if HASGETUSERSHELL 3180c2aa98e2SPeter Wemm register char *p; 3181c2aa98e2SPeter Wemm extern char *getusershell(); 3182c2aa98e2SPeter Wemm 3183c2aa98e2SPeter Wemm if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || 3184c2aa98e2SPeter Wemm ConfigLevel <= 1) 318512ed1c7cSGregory Neil Shapiro return true; 3186c2aa98e2SPeter Wemm 3187c2aa98e2SPeter Wemm setusershell(); 3188c2aa98e2SPeter Wemm while ((p = getusershell()) != NULL) 3189c2aa98e2SPeter Wemm if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0) 3190c2aa98e2SPeter Wemm break; 3191c2aa98e2SPeter Wemm endusershell(); 3192c2aa98e2SPeter Wemm return p != NULL; 31933299c2f1SGregory Neil Shapiro # else /* HASGETUSERSHELL */ 3194c2aa98e2SPeter Wemm # if USEGETCONFATTR 3195c2aa98e2SPeter Wemm auto char *v; 31963299c2f1SGregory Neil Shapiro # endif /* USEGETCONFATTR */ 319712ed1c7cSGregory Neil Shapiro register SM_FILE_T *shellf; 3198c2aa98e2SPeter Wemm char buf[MAXLINE]; 3199c2aa98e2SPeter Wemm 3200c2aa98e2SPeter Wemm if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || 3201c2aa98e2SPeter Wemm ConfigLevel <= 1) 320212ed1c7cSGregory Neil Shapiro return true; 3203c2aa98e2SPeter Wemm 3204c2aa98e2SPeter Wemm # if USEGETCONFATTR 3205c2aa98e2SPeter Wemm /* 3206c2aa98e2SPeter Wemm ** Naturally IBM has a "better" idea..... 3207c2aa98e2SPeter Wemm ** 3208c2aa98e2SPeter Wemm ** What a crock. This interface isn't documented, it is 3209c2aa98e2SPeter Wemm ** considered part of the security library (-ls), and it 3210c2aa98e2SPeter Wemm ** only works if you are running as root (since the list 3211c2aa98e2SPeter Wemm ** of valid shells is obviously a source of great concern). 3212c2aa98e2SPeter Wemm ** I recommend that you do NOT define USEGETCONFATTR, 3213c2aa98e2SPeter Wemm ** especially since you are going to have to set up an 3214c2aa98e2SPeter Wemm ** /etc/shells anyhow to handle the cases where getconfattr 3215c2aa98e2SPeter Wemm ** fails. 3216c2aa98e2SPeter Wemm */ 3217c2aa98e2SPeter Wemm 3218c2aa98e2SPeter Wemm if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL) 3219c2aa98e2SPeter Wemm { 3220c2aa98e2SPeter Wemm while (*v != '\0') 3221c2aa98e2SPeter Wemm { 3222c2aa98e2SPeter Wemm if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0) 322312ed1c7cSGregory Neil Shapiro return true; 3224c2aa98e2SPeter Wemm v += strlen(v) + 1; 3225c2aa98e2SPeter Wemm } 322612ed1c7cSGregory Neil Shapiro return false; 3227c2aa98e2SPeter Wemm } 32283299c2f1SGregory Neil Shapiro # endif /* USEGETCONFATTR */ 3229c2aa98e2SPeter Wemm 323012ed1c7cSGregory Neil Shapiro shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS, 323112ed1c7cSGregory Neil Shapiro SM_IO_RDONLY, NULL); 3232c2aa98e2SPeter Wemm if (shellf == NULL) 3233c2aa98e2SPeter Wemm { 3234c2aa98e2SPeter Wemm /* no /etc/shells; see if it is one of the std shells */ 3235c2aa98e2SPeter Wemm char **d; 3236c2aa98e2SPeter Wemm 3237c2aa98e2SPeter Wemm if (errno != ENOENT && LogLevel > 3) 3238c2aa98e2SPeter Wemm sm_syslog(LOG_ERR, NOQID, 3239c2aa98e2SPeter Wemm "usershellok: cannot open %s: %s", 324012ed1c7cSGregory Neil Shapiro _PATH_SHELLS, sm_errstring(errno)); 3241c2aa98e2SPeter Wemm 3242c2aa98e2SPeter Wemm for (d = DefaultUserShells; *d != NULL; d++) 3243c2aa98e2SPeter Wemm { 3244c2aa98e2SPeter Wemm if (strcmp(shell, *d) == 0) 324512ed1c7cSGregory Neil Shapiro return true; 3246c2aa98e2SPeter Wemm } 324712ed1c7cSGregory Neil Shapiro return false; 3248c2aa98e2SPeter Wemm } 3249c2aa98e2SPeter Wemm 3250552d4955SGregory Neil Shapiro while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) 3251c2aa98e2SPeter Wemm { 3252c2aa98e2SPeter Wemm register char *p, *q; 3253c2aa98e2SPeter Wemm 3254c2aa98e2SPeter Wemm p = buf; 3255c2aa98e2SPeter Wemm while (*p != '\0' && *p != '#' && *p != '/') 3256c2aa98e2SPeter Wemm p++; 3257c2aa98e2SPeter Wemm if (*p == '#' || *p == '\0') 3258c2aa98e2SPeter Wemm continue; 3259c2aa98e2SPeter Wemm q = p; 3260c2aa98e2SPeter Wemm while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p))) 3261c2aa98e2SPeter Wemm p++; 3262c2aa98e2SPeter Wemm *p = '\0'; 3263c2aa98e2SPeter Wemm if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0) 3264c2aa98e2SPeter Wemm { 326512ed1c7cSGregory Neil Shapiro (void) sm_io_close(shellf, SM_TIME_DEFAULT); 326612ed1c7cSGregory Neil Shapiro return true; 3267c2aa98e2SPeter Wemm } 3268c2aa98e2SPeter Wemm } 326912ed1c7cSGregory Neil Shapiro (void) sm_io_close(shellf, SM_TIME_DEFAULT); 327012ed1c7cSGregory Neil Shapiro return false; 32713299c2f1SGregory Neil Shapiro # endif /* HASGETUSERSHELL */ 3272c2aa98e2SPeter Wemm } 327312ed1c7cSGregory Neil Shapiro /* 3274c2aa98e2SPeter Wemm ** FREEDISKSPACE -- see how much free space is on the queue filesystem 3275c2aa98e2SPeter Wemm ** 3276c2aa98e2SPeter Wemm ** Only implemented if you have statfs. 3277c2aa98e2SPeter Wemm ** 3278c2aa98e2SPeter Wemm ** Parameters: 3279c2aa98e2SPeter Wemm ** dir -- the directory in question. 3280c2aa98e2SPeter Wemm ** bsize -- a variable into which the filesystem 3281c2aa98e2SPeter Wemm ** block size is stored. 3282c2aa98e2SPeter Wemm ** 3283c2aa98e2SPeter Wemm ** Returns: 32843299c2f1SGregory Neil Shapiro ** The number of blocks free on the queue filesystem. 3285c2aa98e2SPeter Wemm ** -1 if the statfs call fails. 3286c2aa98e2SPeter Wemm ** 3287c2aa98e2SPeter Wemm ** Side effects: 3288c2aa98e2SPeter Wemm ** Puts the filesystem block size into bsize. 3289c2aa98e2SPeter Wemm */ 3290c2aa98e2SPeter Wemm 3291c2aa98e2SPeter Wemm /* statfs types */ 3292c2aa98e2SPeter Wemm # define SFS_NONE 0 /* no statfs implementation */ 3293c2aa98e2SPeter Wemm # define SFS_USTAT 1 /* use ustat */ 3294c2aa98e2SPeter Wemm # define SFS_4ARGS 2 /* use four-argument statfs call */ 3295c2aa98e2SPeter Wemm # define SFS_VFS 3 /* use <sys/vfs.h> implementation */ 3296c2aa98e2SPeter Wemm # define SFS_MOUNT 4 /* use <sys/mount.h> implementation */ 3297c2aa98e2SPeter Wemm # define SFS_STATFS 5 /* use <sys/statfs.h> implementation */ 3298c2aa98e2SPeter Wemm # define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */ 3299c2aa98e2SPeter Wemm 3300c2aa98e2SPeter Wemm # ifndef SFS_TYPE 3301c2aa98e2SPeter Wemm # define SFS_TYPE SFS_NONE 33023299c2f1SGregory Neil Shapiro # endif /* ! SFS_TYPE */ 3303c2aa98e2SPeter Wemm 3304c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT 3305c2aa98e2SPeter Wemm # include <ustat.h> 33063299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */ 3307c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS 3308c2aa98e2SPeter Wemm # include <sys/statfs.h> 33093299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */ 3310c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_VFS 3311c2aa98e2SPeter Wemm # include <sys/vfs.h> 33123299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_VFS */ 3313c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_MOUNT 3314c2aa98e2SPeter Wemm # include <sys/mount.h> 33153299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_MOUNT */ 3316c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS 3317c2aa98e2SPeter Wemm # include <sys/statvfs.h> 33183299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_STATVFS */ 3319c2aa98e2SPeter Wemm 3320c2aa98e2SPeter Wemm long 3321c2aa98e2SPeter Wemm freediskspace(dir, bsize) 3322951742c4SGregory Neil Shapiro const char *dir; 3323c2aa98e2SPeter Wemm long *bsize; 3324c2aa98e2SPeter Wemm { 332512ed1c7cSGregory Neil Shapiro # if SFS_TYPE == SFS_NONE 332612ed1c7cSGregory Neil Shapiro if (bsize != NULL) 332712ed1c7cSGregory Neil Shapiro *bsize = 4096L; 332812ed1c7cSGregory Neil Shapiro 332912ed1c7cSGregory Neil Shapiro /* assume free space is plentiful */ 333012ed1c7cSGregory Neil Shapiro return (long) LONG_MAX; 333112ed1c7cSGregory Neil Shapiro # else /* SFS_TYPE == SFS_NONE */ 3332c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT 3333c2aa98e2SPeter Wemm struct ustat fs; 3334c2aa98e2SPeter Wemm struct stat statbuf; 3335c2aa98e2SPeter Wemm # define FSBLOCKSIZE DEV_BSIZE 3336c2aa98e2SPeter Wemm # define SFS_BAVAIL f_tfree 33373299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_USTAT */ 3338c2aa98e2SPeter Wemm # if defined(ultrix) 3339c2aa98e2SPeter Wemm struct fs_data fs; 3340c2aa98e2SPeter Wemm # define SFS_BAVAIL fd_bfreen 3341c2aa98e2SPeter Wemm # define FSBLOCKSIZE 1024L 33423299c2f1SGregory Neil Shapiro # else /* defined(ultrix) */ 3343c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS 3344c2aa98e2SPeter Wemm struct statvfs fs; 3345c2aa98e2SPeter Wemm # define FSBLOCKSIZE fs.f_frsize 33463299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_STATVFS */ 3347c2aa98e2SPeter Wemm struct statfs fs; 3348c2aa98e2SPeter Wemm # define FSBLOCKSIZE fs.f_bsize 33493299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_STATVFS */ 33503299c2f1SGregory Neil Shapiro # endif /* defined(ultrix) */ 33513299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */ 3352c2aa98e2SPeter Wemm # ifndef SFS_BAVAIL 3353c2aa98e2SPeter Wemm # define SFS_BAVAIL f_bavail 33543299c2f1SGregory Neil Shapiro # endif /* ! SFS_BAVAIL */ 3355c2aa98e2SPeter Wemm 3356c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT 3357c2aa98e2SPeter Wemm if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0) 33583299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_USTAT */ 3359c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_4ARGS 3360951742c4SGregory Neil Shapiro if (statfs(dir, &fs, sizeof(fs), 0) == 0) 33613299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_4ARGS */ 3362c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS 3363c2aa98e2SPeter Wemm if (statvfs(dir, &fs) == 0) 33643299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_STATVFS */ 3365c2aa98e2SPeter Wemm # if defined(ultrix) 3366c2aa98e2SPeter Wemm if (statfs(dir, &fs) > 0) 33673299c2f1SGregory Neil Shapiro # else /* defined(ultrix) */ 3368c2aa98e2SPeter Wemm if (statfs(dir, &fs) == 0) 33693299c2f1SGregory Neil Shapiro # endif /* defined(ultrix) */ 33703299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_STATVFS */ 33713299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_4ARGS */ 33723299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */ 3373c2aa98e2SPeter Wemm { 3374c2aa98e2SPeter Wemm if (bsize != NULL) 3375c2aa98e2SPeter Wemm *bsize = FSBLOCKSIZE; 3376c2aa98e2SPeter Wemm if (fs.SFS_BAVAIL <= 0) 3377c2aa98e2SPeter Wemm return 0; 3378c2aa98e2SPeter Wemm else if (fs.SFS_BAVAIL > LONG_MAX) 33793299c2f1SGregory Neil Shapiro return (long) LONG_MAX; 3380c2aa98e2SPeter Wemm else 3381c2aa98e2SPeter Wemm return (long) fs.SFS_BAVAIL; 3382c2aa98e2SPeter Wemm } 33833299c2f1SGregory Neil Shapiro return -1; 338412ed1c7cSGregory Neil Shapiro # endif /* SFS_TYPE == SFS_NONE */ 3385c2aa98e2SPeter Wemm } 338612ed1c7cSGregory Neil Shapiro /* 338712ed1c7cSGregory Neil Shapiro ** ENOUGHDISKSPACE -- is there enough free space on the queue file systems? 3388c2aa98e2SPeter Wemm ** 3389c2aa98e2SPeter Wemm ** Parameters: 3390c2aa98e2SPeter Wemm ** msize -- the size to check against. If zero, we don't yet 3391c2aa98e2SPeter Wemm ** know how big the message will be, so just check for 3392c2aa98e2SPeter Wemm ** a "reasonable" amount. 339312ed1c7cSGregory Neil Shapiro ** e -- envelope, or NULL -- controls logging 3394c2aa98e2SPeter Wemm ** 3395c2aa98e2SPeter Wemm ** Returns: 339612ed1c7cSGregory Neil Shapiro ** true if in every queue group there is at least one 339712ed1c7cSGregory Neil Shapiro ** queue directory whose file system contains enough free space. 339812ed1c7cSGregory Neil Shapiro ** false otherwise. 339912ed1c7cSGregory Neil Shapiro ** 340012ed1c7cSGregory Neil Shapiro ** Side Effects: 340112ed1c7cSGregory Neil Shapiro ** If there is not enough disk space and e != NULL 340212ed1c7cSGregory Neil Shapiro ** then sm_syslog is called. 3403c2aa98e2SPeter Wemm */ 3404c2aa98e2SPeter Wemm 3405c2aa98e2SPeter Wemm bool 340612ed1c7cSGregory Neil Shapiro enoughdiskspace(msize, e) 3407c2aa98e2SPeter Wemm long msize; 340812ed1c7cSGregory Neil Shapiro ENVELOPE *e; 3409c2aa98e2SPeter Wemm { 341012ed1c7cSGregory Neil Shapiro int i; 3411c2aa98e2SPeter Wemm 34129bd497b8SGregory Neil Shapiro #if _FFR_TESTS 34139bd497b8SGregory Neil Shapiro if (tTd(4, 101)) 34149bd497b8SGregory Neil Shapiro return false; 34159bd497b8SGregory Neil Shapiro #endif /* _FFR_TESTS */ 3416c2aa98e2SPeter Wemm if (MinBlocksFree <= 0 && msize <= 0) 3417c2aa98e2SPeter Wemm { 3418c2aa98e2SPeter Wemm if (tTd(4, 80)) 341912ed1c7cSGregory Neil Shapiro sm_dprintf("enoughdiskspace: no threshold\n"); 342012ed1c7cSGregory Neil Shapiro return true; 3421c2aa98e2SPeter Wemm } 3422c2aa98e2SPeter Wemm 342312ed1c7cSGregory Neil Shapiro filesys_update(); 342412ed1c7cSGregory Neil Shapiro for (i = 0; i < NumQueue; ++i) 3425c2aa98e2SPeter Wemm { 342612ed1c7cSGregory Neil Shapiro if (pickqdir(Queue[i], msize, e) < 0) 342712ed1c7cSGregory Neil Shapiro return false; 3428c2aa98e2SPeter Wemm } 342912ed1c7cSGregory Neil Shapiro return true; 3430c2aa98e2SPeter Wemm } 343112ed1c7cSGregory Neil Shapiro /* 3432c2aa98e2SPeter Wemm ** TRANSIENTERROR -- tell if an error code indicates a transient failure 3433c2aa98e2SPeter Wemm ** 3434c2aa98e2SPeter Wemm ** This looks at an errno value and tells if this is likely to 3435c2aa98e2SPeter Wemm ** go away if retried later. 3436c2aa98e2SPeter Wemm ** 3437c2aa98e2SPeter Wemm ** Parameters: 3438c2aa98e2SPeter Wemm ** err -- the errno code to classify. 3439c2aa98e2SPeter Wemm ** 3440c2aa98e2SPeter Wemm ** Returns: 344112ed1c7cSGregory Neil Shapiro ** true if this is probably transient. 344212ed1c7cSGregory Neil Shapiro ** false otherwise. 3443c2aa98e2SPeter Wemm */ 3444c2aa98e2SPeter Wemm 3445c2aa98e2SPeter Wemm bool 3446c2aa98e2SPeter Wemm transienterror(err) 3447c2aa98e2SPeter Wemm int err; 3448c2aa98e2SPeter Wemm { 3449c2aa98e2SPeter Wemm switch (err) 3450c2aa98e2SPeter Wemm { 3451c2aa98e2SPeter Wemm case EIO: /* I/O error */ 3452c2aa98e2SPeter Wemm case ENXIO: /* Device not configured */ 3453c2aa98e2SPeter Wemm case EAGAIN: /* Resource temporarily unavailable */ 3454c2aa98e2SPeter Wemm case ENOMEM: /* Cannot allocate memory */ 3455c2aa98e2SPeter Wemm case ENODEV: /* Operation not supported by device */ 3456c2aa98e2SPeter Wemm case ENFILE: /* Too many open files in system */ 3457c2aa98e2SPeter Wemm case EMFILE: /* Too many open files */ 3458c2aa98e2SPeter Wemm case ENOSPC: /* No space left on device */ 3459c2aa98e2SPeter Wemm case ETIMEDOUT: /* Connection timed out */ 3460c2aa98e2SPeter Wemm #ifdef ESTALE 3461c2aa98e2SPeter Wemm case ESTALE: /* Stale NFS file handle */ 34623299c2f1SGregory Neil Shapiro #endif /* ESTALE */ 3463c2aa98e2SPeter Wemm #ifdef ENETDOWN 3464c2aa98e2SPeter Wemm case ENETDOWN: /* Network is down */ 34653299c2f1SGregory Neil Shapiro #endif /* ENETDOWN */ 3466c2aa98e2SPeter Wemm #ifdef ENETUNREACH 3467c2aa98e2SPeter Wemm case ENETUNREACH: /* Network is unreachable */ 34683299c2f1SGregory Neil Shapiro #endif /* ENETUNREACH */ 3469c2aa98e2SPeter Wemm #ifdef ENETRESET 3470c2aa98e2SPeter Wemm case ENETRESET: /* Network dropped connection on reset */ 34713299c2f1SGregory Neil Shapiro #endif /* ENETRESET */ 3472c2aa98e2SPeter Wemm #ifdef ECONNABORTED 3473c2aa98e2SPeter Wemm case ECONNABORTED: /* Software caused connection abort */ 34743299c2f1SGregory Neil Shapiro #endif /* ECONNABORTED */ 3475c2aa98e2SPeter Wemm #ifdef ECONNRESET 3476c2aa98e2SPeter Wemm case ECONNRESET: /* Connection reset by peer */ 34773299c2f1SGregory Neil Shapiro #endif /* ECONNRESET */ 3478c2aa98e2SPeter Wemm #ifdef ENOBUFS 3479c2aa98e2SPeter Wemm case ENOBUFS: /* No buffer space available */ 34803299c2f1SGregory Neil Shapiro #endif /* ENOBUFS */ 3481c2aa98e2SPeter Wemm #ifdef ESHUTDOWN 3482c2aa98e2SPeter Wemm case ESHUTDOWN: /* Can't send after socket shutdown */ 34833299c2f1SGregory Neil Shapiro #endif /* ESHUTDOWN */ 3484c2aa98e2SPeter Wemm #ifdef ECONNREFUSED 3485c2aa98e2SPeter Wemm case ECONNREFUSED: /* Connection refused */ 34863299c2f1SGregory Neil Shapiro #endif /* ECONNREFUSED */ 3487c2aa98e2SPeter Wemm #ifdef EHOSTDOWN 3488c2aa98e2SPeter Wemm case EHOSTDOWN: /* Host is down */ 34893299c2f1SGregory Neil Shapiro #endif /* EHOSTDOWN */ 3490c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH 3491c2aa98e2SPeter Wemm case EHOSTUNREACH: /* No route to host */ 34923299c2f1SGregory Neil Shapiro #endif /* EHOSTUNREACH */ 3493c2aa98e2SPeter Wemm #ifdef EDQUOT 3494c2aa98e2SPeter Wemm case EDQUOT: /* Disc quota exceeded */ 34953299c2f1SGregory Neil Shapiro #endif /* EDQUOT */ 3496c2aa98e2SPeter Wemm #ifdef EPROCLIM 3497c2aa98e2SPeter Wemm case EPROCLIM: /* Too many processes */ 34983299c2f1SGregory Neil Shapiro #endif /* EPROCLIM */ 3499c2aa98e2SPeter Wemm #ifdef EUSERS 3500c2aa98e2SPeter Wemm case EUSERS: /* Too many users */ 35013299c2f1SGregory Neil Shapiro #endif /* EUSERS */ 3502c2aa98e2SPeter Wemm #ifdef EDEADLK 3503c2aa98e2SPeter Wemm case EDEADLK: /* Resource deadlock avoided */ 35043299c2f1SGregory Neil Shapiro #endif /* EDEADLK */ 3505c2aa98e2SPeter Wemm #ifdef EISCONN 3506c2aa98e2SPeter Wemm case EISCONN: /* Socket already connected */ 35073299c2f1SGregory Neil Shapiro #endif /* EISCONN */ 3508c2aa98e2SPeter Wemm #ifdef EINPROGRESS 3509c2aa98e2SPeter Wemm case EINPROGRESS: /* Operation now in progress */ 35103299c2f1SGregory Neil Shapiro #endif /* EINPROGRESS */ 3511c2aa98e2SPeter Wemm #ifdef EALREADY 3512c2aa98e2SPeter Wemm case EALREADY: /* Operation already in progress */ 35133299c2f1SGregory Neil Shapiro #endif /* EALREADY */ 3514c2aa98e2SPeter Wemm #ifdef EADDRINUSE 3515c2aa98e2SPeter Wemm case EADDRINUSE: /* Address already in use */ 35163299c2f1SGregory Neil Shapiro #endif /* EADDRINUSE */ 3517c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL 3518c2aa98e2SPeter Wemm case EADDRNOTAVAIL: /* Can't assign requested address */ 35193299c2f1SGregory Neil Shapiro #endif /* EADDRNOTAVAIL */ 3520c2aa98e2SPeter Wemm #ifdef ETXTBSY 3521c2aa98e2SPeter Wemm case ETXTBSY: /* (Apollo) file locked */ 35223299c2f1SGregory Neil Shapiro #endif /* ETXTBSY */ 3523c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) 3524c2aa98e2SPeter Wemm case ENOSR: /* Out of streams resources */ 35253299c2f1SGregory Neil Shapiro #endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */ 35263299c2f1SGregory Neil Shapiro #ifdef ENOLCK 35273299c2f1SGregory Neil Shapiro case ENOLCK: /* No locks available */ 35283299c2f1SGregory Neil Shapiro #endif /* ENOLCK */ 3529c2aa98e2SPeter Wemm case E_SM_OPENTIMEOUT: /* PSEUDO: open timed out */ 353012ed1c7cSGregory Neil Shapiro return true; 3531c2aa98e2SPeter Wemm } 3532c2aa98e2SPeter Wemm 3533c2aa98e2SPeter Wemm /* nope, must be permanent */ 353412ed1c7cSGregory Neil Shapiro return false; 3535c2aa98e2SPeter Wemm } 353612ed1c7cSGregory Neil Shapiro /* 3537c2aa98e2SPeter Wemm ** LOCKFILE -- lock a file using flock or (shudder) fcntl locking 3538c2aa98e2SPeter Wemm ** 3539c2aa98e2SPeter Wemm ** Parameters: 3540c2aa98e2SPeter Wemm ** fd -- the file descriptor of the file. 3541c2aa98e2SPeter Wemm ** filename -- the file name (for error messages). 3542c2aa98e2SPeter Wemm ** ext -- the filename extension. 3543c2aa98e2SPeter Wemm ** type -- type of the lock. Bits can be: 3544c2aa98e2SPeter Wemm ** LOCK_EX -- exclusive lock. 3545c2aa98e2SPeter Wemm ** LOCK_NB -- non-blocking. 3546c46d91b7SGregory Neil Shapiro ** LOCK_UN -- unlock. 3547c2aa98e2SPeter Wemm ** 3548c2aa98e2SPeter Wemm ** Returns: 354912ed1c7cSGregory Neil Shapiro ** true if the lock was acquired. 355012ed1c7cSGregory Neil Shapiro ** false otherwise. 3551c2aa98e2SPeter Wemm */ 3552c2aa98e2SPeter Wemm 3553c2aa98e2SPeter Wemm bool 3554c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type) 3555c2aa98e2SPeter Wemm int fd; 3556c2aa98e2SPeter Wemm char *filename; 3557c2aa98e2SPeter Wemm char *ext; 3558c2aa98e2SPeter Wemm int type; 3559c2aa98e2SPeter Wemm { 3560c2aa98e2SPeter Wemm int i; 3561c2aa98e2SPeter Wemm int save_errno; 3562c2aa98e2SPeter Wemm # if !HASFLOCK 3563c2aa98e2SPeter Wemm int action; 3564c2aa98e2SPeter Wemm struct flock lfd; 3565c2aa98e2SPeter Wemm 3566c2aa98e2SPeter Wemm if (ext == NULL) 3567c2aa98e2SPeter Wemm ext = ""; 3568c2aa98e2SPeter Wemm 3569951742c4SGregory Neil Shapiro memset(&lfd, '\0', sizeof(lfd)); 3570c2aa98e2SPeter Wemm if (bitset(LOCK_UN, type)) 3571c2aa98e2SPeter Wemm lfd.l_type = F_UNLCK; 3572c2aa98e2SPeter Wemm else if (bitset(LOCK_EX, type)) 3573c2aa98e2SPeter Wemm lfd.l_type = F_WRLCK; 3574c2aa98e2SPeter Wemm else 3575c2aa98e2SPeter Wemm lfd.l_type = F_RDLCK; 3576c2aa98e2SPeter Wemm 3577c2aa98e2SPeter Wemm if (bitset(LOCK_NB, type)) 3578c2aa98e2SPeter Wemm action = F_SETLK; 3579c2aa98e2SPeter Wemm else 3580c2aa98e2SPeter Wemm action = F_SETLKW; 3581c2aa98e2SPeter Wemm 3582c2aa98e2SPeter Wemm if (tTd(55, 60)) 358312ed1c7cSGregory Neil Shapiro sm_dprintf("lockfile(%s%s, action=%d, type=%d): ", 3584c2aa98e2SPeter Wemm filename, ext, action, lfd.l_type); 3585c2aa98e2SPeter Wemm 3586c2aa98e2SPeter Wemm while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR) 3587c2aa98e2SPeter Wemm continue; 3588c2aa98e2SPeter Wemm if (i >= 0) 3589c2aa98e2SPeter Wemm { 3590c2aa98e2SPeter Wemm if (tTd(55, 60)) 359112ed1c7cSGregory Neil Shapiro sm_dprintf("SUCCESS\n"); 359212ed1c7cSGregory Neil Shapiro return true; 3593c2aa98e2SPeter Wemm } 3594c2aa98e2SPeter Wemm save_errno = errno; 3595c2aa98e2SPeter Wemm 3596c2aa98e2SPeter Wemm if (tTd(55, 60)) 359712ed1c7cSGregory Neil Shapiro sm_dprintf("(%s) ", sm_errstring(save_errno)); 3598c2aa98e2SPeter Wemm 3599c2aa98e2SPeter Wemm /* 3600c2aa98e2SPeter Wemm ** On SunOS, if you are testing using -oQ/tmp/mqueue or 3601c2aa98e2SPeter Wemm ** -oA/tmp/aliases or anything like that, and /tmp is mounted 3602c2aa98e2SPeter Wemm ** as type "tmp" (that is, served from swap space), the 3603c2aa98e2SPeter Wemm ** previous fcntl will fail with "Invalid argument" errors. 3604c2aa98e2SPeter Wemm ** Since this is fairly common during testing, we will assume 3605c2aa98e2SPeter Wemm ** that this indicates that the lock is successfully grabbed. 3606c2aa98e2SPeter Wemm */ 3607c2aa98e2SPeter Wemm 3608c2aa98e2SPeter Wemm if (save_errno == EINVAL) 3609c2aa98e2SPeter Wemm { 3610c2aa98e2SPeter Wemm if (tTd(55, 60)) 361112ed1c7cSGregory Neil Shapiro sm_dprintf("SUCCESS\n"); 361212ed1c7cSGregory Neil Shapiro return true; 3613c2aa98e2SPeter Wemm } 3614c2aa98e2SPeter Wemm 36153299c2f1SGregory Neil Shapiro if (!bitset(LOCK_NB, type) || 36163299c2f1SGregory Neil Shapiro (save_errno != EACCES && save_errno != EAGAIN)) 3617c2aa98e2SPeter Wemm { 3618320f00e7SGregory Neil Shapiro int omode = fcntl(fd, F_GETFL, 0); 3619320f00e7SGregory Neil Shapiro uid_t euid = geteuid(); 3620320f00e7SGregory Neil Shapiro 3621c2aa98e2SPeter Wemm errno = save_errno; 3622da7d7b9cSGregory Neil Shapiro syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)", 3623da7d7b9cSGregory Neil Shapiro filename, ext, fd, type, omode, (long) euid); 362412ed1c7cSGregory Neil Shapiro dumpfd(fd, true, true); 3625c2aa98e2SPeter Wemm } 36263299c2f1SGregory Neil Shapiro # else /* !HASFLOCK */ 3627c2aa98e2SPeter Wemm if (ext == NULL) 3628c2aa98e2SPeter Wemm ext = ""; 3629c2aa98e2SPeter Wemm 3630c2aa98e2SPeter Wemm if (tTd(55, 60)) 363112ed1c7cSGregory Neil Shapiro sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type); 3632c2aa98e2SPeter Wemm 3633c2aa98e2SPeter Wemm while ((i = flock(fd, type)) < 0 && errno == EINTR) 3634c2aa98e2SPeter Wemm continue; 3635c2aa98e2SPeter Wemm if (i >= 0) 3636c2aa98e2SPeter Wemm { 3637c2aa98e2SPeter Wemm if (tTd(55, 60)) 363812ed1c7cSGregory Neil Shapiro sm_dprintf("SUCCESS\n"); 363912ed1c7cSGregory Neil Shapiro return true; 3640c2aa98e2SPeter Wemm } 3641c2aa98e2SPeter Wemm save_errno = errno; 3642c2aa98e2SPeter Wemm 3643c2aa98e2SPeter Wemm if (tTd(55, 60)) 364412ed1c7cSGregory Neil Shapiro sm_dprintf("(%s) ", sm_errstring(save_errno)); 3645c2aa98e2SPeter Wemm 3646c2aa98e2SPeter Wemm if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK) 3647c2aa98e2SPeter Wemm { 3648320f00e7SGregory Neil Shapiro int omode = fcntl(fd, F_GETFL, 0); 3649320f00e7SGregory Neil Shapiro uid_t euid = geteuid(); 3650320f00e7SGregory Neil Shapiro 3651c2aa98e2SPeter Wemm errno = save_errno; 3652da7d7b9cSGregory Neil Shapiro syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)", 3653da7d7b9cSGregory Neil Shapiro filename, ext, fd, type, omode, (long) euid); 365412ed1c7cSGregory Neil Shapiro dumpfd(fd, true, true); 3655c2aa98e2SPeter Wemm } 36563299c2f1SGregory Neil Shapiro # endif /* !HASFLOCK */ 3657c2aa98e2SPeter Wemm if (tTd(55, 60)) 365812ed1c7cSGregory Neil Shapiro sm_dprintf("FAIL\n"); 3659c2aa98e2SPeter Wemm errno = save_errno; 366012ed1c7cSGregory Neil Shapiro return false; 3661c2aa98e2SPeter Wemm } 366212ed1c7cSGregory Neil Shapiro /* 3663c2aa98e2SPeter Wemm ** CHOWNSAFE -- tell if chown is "safe" (executable only by root) 3664c2aa98e2SPeter Wemm ** 3665c2aa98e2SPeter Wemm ** Unfortunately, given that we can't predict other systems on which 3666c2aa98e2SPeter Wemm ** a remote mounted (NFS) filesystem will be mounted, the answer is 3667c2aa98e2SPeter Wemm ** almost always that this is unsafe. 3668c2aa98e2SPeter Wemm ** 3669c2aa98e2SPeter Wemm ** Note also that many operating systems have non-compliant 3670c2aa98e2SPeter Wemm ** implementations of the _POSIX_CHOWN_RESTRICTED variable and the 3671c2aa98e2SPeter Wemm ** fpathconf() routine. According to IEEE 1003.1-1990, if 3672c2aa98e2SPeter Wemm ** _POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then 3673c2aa98e2SPeter Wemm ** no non-root process can give away the file. However, vendors 3674c2aa98e2SPeter Wemm ** don't take NFS into account, so a comfortable value of 3675c2aa98e2SPeter Wemm ** _POSIX_CHOWN_RESTRICTED tells us nothing. 3676c2aa98e2SPeter Wemm ** 3677c2aa98e2SPeter Wemm ** Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf() 3678c2aa98e2SPeter Wemm ** even on files where chown is not restricted. Many systems get 3679c2aa98e2SPeter Wemm ** this wrong on NFS-based filesystems (that is, they say that chown 3680c2aa98e2SPeter Wemm ** is restricted [safe] on NFS filesystems where it may not be, since 3681c2aa98e2SPeter Wemm ** other systems can access the same filesystem and do file giveaway; 3682c2aa98e2SPeter Wemm ** only the NFS server knows for sure!) Hence, it is important to 3683c2aa98e2SPeter Wemm ** get the value of SAFENFSPATHCONF correct -- it should be defined 3684c2aa98e2SPeter Wemm ** _only_ after testing (see test/t_pathconf.c) a system on an unsafe 3685c2aa98e2SPeter Wemm ** NFS-based filesystem to ensure that you can get meaningful results. 3686c2aa98e2SPeter Wemm ** If in doubt, assume unsafe! 3687c2aa98e2SPeter Wemm ** 3688c2aa98e2SPeter Wemm ** You may also need to tweak IS_SAFE_CHOWN -- it should be a 3689c2aa98e2SPeter Wemm ** condition indicating whether the return from pathconf indicates 3690c2aa98e2SPeter Wemm ** that chown is safe (typically either > 0 or >= 0 -- there isn't 3691c2aa98e2SPeter Wemm ** even any agreement about whether a zero return means that a file 3692c2aa98e2SPeter Wemm ** is or is not safe). It defaults to "> 0". 3693c2aa98e2SPeter Wemm ** 3694c2aa98e2SPeter Wemm ** If the parent directory is safe (writable only by owner back 3695c2aa98e2SPeter Wemm ** to the root) then we can relax slightly and trust fpathconf 3696c2aa98e2SPeter Wemm ** in more circumstances. This is really a crock -- if this is an 3697c2aa98e2SPeter Wemm ** NFS mounted filesystem then we really know nothing about the 3698c2aa98e2SPeter Wemm ** underlying implementation. However, most systems pessimize and 3699c2aa98e2SPeter Wemm ** return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which 3700c2aa98e2SPeter Wemm ** we interpret as unsafe, as we should. Thus, this heuristic gets 3701c2aa98e2SPeter Wemm ** us into a possible problem only on systems that have a broken 3702c2aa98e2SPeter Wemm ** pathconf implementation and which are also poorly configured 3703c2aa98e2SPeter Wemm ** (have :include: files in group- or world-writable directories). 3704c2aa98e2SPeter Wemm ** 3705c2aa98e2SPeter Wemm ** Parameters: 3706c2aa98e2SPeter Wemm ** fd -- the file descriptor to check. 3707c2aa98e2SPeter Wemm ** safedir -- set if the parent directory is safe. 3708c2aa98e2SPeter Wemm ** 3709c2aa98e2SPeter Wemm ** Returns: 371012ed1c7cSGregory Neil Shapiro ** true -- if the chown(2) operation is "safe" -- that is, 3711c2aa98e2SPeter Wemm ** only root can chown the file to an arbitrary user. 371212ed1c7cSGregory Neil Shapiro ** false -- if an arbitrary user can give away a file. 3713c2aa98e2SPeter Wemm */ 3714c2aa98e2SPeter Wemm 3715c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN 3716c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN > 0 37173299c2f1SGregory Neil Shapiro #endif /* ! IS_SAFE_CHOWN */ 3718c2aa98e2SPeter Wemm 3719c2aa98e2SPeter Wemm bool 3720c2aa98e2SPeter Wemm chownsafe(fd, safedir) 3721c2aa98e2SPeter Wemm int fd; 3722c2aa98e2SPeter Wemm bool safedir; 3723c2aa98e2SPeter Wemm { 3724c2aa98e2SPeter Wemm # if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ 3725c2aa98e2SPeter Wemm (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H)) 3726c2aa98e2SPeter Wemm int rval; 3727c2aa98e2SPeter Wemm 3728c2aa98e2SPeter Wemm /* give the system administrator a chance to override */ 37293299c2f1SGregory Neil Shapiro if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail)) 373012ed1c7cSGregory Neil Shapiro return true; 3731c2aa98e2SPeter Wemm 3732c2aa98e2SPeter Wemm /* 3733c2aa98e2SPeter Wemm ** Some systems (e.g., SunOS) seem to have the call and the 3734c2aa98e2SPeter Wemm ** #define _PC_CHOWN_RESTRICTED, but don't actually implement 3735c2aa98e2SPeter Wemm ** the call. This heuristic checks for that. 3736c2aa98e2SPeter Wemm */ 3737c2aa98e2SPeter Wemm 3738c2aa98e2SPeter Wemm errno = 0; 3739c2aa98e2SPeter Wemm rval = fpathconf(fd, _PC_CHOWN_RESTRICTED); 3740c2aa98e2SPeter Wemm # if SAFENFSPATHCONF 3741c2aa98e2SPeter Wemm return errno == 0 && rval IS_SAFE_CHOWN; 37423299c2f1SGregory Neil Shapiro # else /* SAFENFSPATHCONF */ 3743c2aa98e2SPeter Wemm return safedir && errno == 0 && rval IS_SAFE_CHOWN; 37443299c2f1SGregory Neil Shapiro # endif /* SAFENFSPATHCONF */ 374512ed1c7cSGregory Neil Shapiro # else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */ 37463299c2f1SGregory Neil Shapiro return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail); 374712ed1c7cSGregory Neil Shapiro # endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */ 3748c2aa98e2SPeter Wemm } 374912ed1c7cSGregory Neil Shapiro /* 3750c2aa98e2SPeter Wemm ** RESETLIMITS -- reset system controlled resource limits 3751c2aa98e2SPeter Wemm ** 3752c2aa98e2SPeter Wemm ** This is to avoid denial-of-service attacks 3753c2aa98e2SPeter Wemm ** 3754c2aa98e2SPeter Wemm ** Parameters: 3755c2aa98e2SPeter Wemm ** none 3756c2aa98e2SPeter Wemm ** 3757c2aa98e2SPeter Wemm ** Returns: 3758c2aa98e2SPeter Wemm ** none 3759c2aa98e2SPeter Wemm */ 3760c2aa98e2SPeter Wemm 3761c2aa98e2SPeter Wemm #if HASSETRLIMIT 3762c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H 3763567a2fc9SGregory Neil Shapiro # include <sm/time.h> 37643299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NEEDS_SYS_TIME_H */ 3765c2aa98e2SPeter Wemm # include <sys/resource.h> 37663299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */ 3767c2aa98e2SPeter Wemm 3768c2aa98e2SPeter Wemm void 3769c2aa98e2SPeter Wemm resetlimits() 3770c2aa98e2SPeter Wemm { 3771c2aa98e2SPeter Wemm #if HASSETRLIMIT 3772c2aa98e2SPeter Wemm struct rlimit lim; 3773c2aa98e2SPeter Wemm 3774c2aa98e2SPeter Wemm lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; 3775c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_CPU, &lim); 3776c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_FSIZE, &lim); 3777c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE 3778c2aa98e2SPeter Wemm lim.rlim_cur = lim.rlim_max = FD_SETSIZE; 3779c2aa98e2SPeter Wemm (void) setrlimit(RLIMIT_NOFILE, &lim); 37803299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */ 37813299c2f1SGregory Neil Shapiro #else /* HASSETRLIMIT */ 3782c2aa98e2SPeter Wemm # if HASULIMIT 3783c2aa98e2SPeter Wemm (void) ulimit(2, 0x3fffff); 3784c2aa98e2SPeter Wemm (void) ulimit(4, FD_SETSIZE); 37853299c2f1SGregory Neil Shapiro # endif /* HASULIMIT */ 37863299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */ 3787c2aa98e2SPeter Wemm errno = 0; 3788c2aa98e2SPeter Wemm } 378912ed1c7cSGregory Neil Shapiro /* 3790c2aa98e2SPeter Wemm ** SETVENDOR -- process vendor code from V configuration line 3791c2aa98e2SPeter Wemm ** 3792c2aa98e2SPeter Wemm ** Parameters: 3793c2aa98e2SPeter Wemm ** vendor -- string representation of vendor. 3794c2aa98e2SPeter Wemm ** 3795c2aa98e2SPeter Wemm ** Returns: 379612ed1c7cSGregory Neil Shapiro ** true -- if ok. 379712ed1c7cSGregory Neil Shapiro ** false -- if vendor code could not be processed. 3798c2aa98e2SPeter Wemm ** 3799c2aa98e2SPeter Wemm ** Side Effects: 3800c2aa98e2SPeter Wemm ** It is reasonable to set mode flags here to tweak 3801c2aa98e2SPeter Wemm ** processing in other parts of the code if necessary. 3802c2aa98e2SPeter Wemm ** For example, if you are a vendor that uses $%y to 3803c2aa98e2SPeter Wemm ** indicate YP lookups, you could enable that here. 3804c2aa98e2SPeter Wemm */ 3805c2aa98e2SPeter Wemm 3806c2aa98e2SPeter Wemm bool 3807c2aa98e2SPeter Wemm setvendor(vendor) 3808c2aa98e2SPeter Wemm char *vendor; 3809c2aa98e2SPeter Wemm { 381012ed1c7cSGregory Neil Shapiro if (sm_strcasecmp(vendor, "Berkeley") == 0) 3811c2aa98e2SPeter Wemm { 3812c2aa98e2SPeter Wemm VendorCode = VENDOR_BERKELEY; 381312ed1c7cSGregory Neil Shapiro return true; 3814c2aa98e2SPeter Wemm } 3815c2aa98e2SPeter Wemm 3816c2aa98e2SPeter Wemm /* add vendor extensions here */ 3817c2aa98e2SPeter Wemm 3818c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS 381912ed1c7cSGregory Neil Shapiro if (sm_strcasecmp(vendor, "Sun") == 0) 3820c2aa98e2SPeter Wemm { 3821c2aa98e2SPeter Wemm VendorCode = VENDOR_SUN; 382212ed1c7cSGregory Neil Shapiro return true; 3823c2aa98e2SPeter Wemm } 38243299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */ 3825567a2fc9SGregory Neil Shapiro #ifdef DEC 3826567a2fc9SGregory Neil Shapiro if (sm_strcasecmp(vendor, "Digital") == 0) 3827567a2fc9SGregory Neil Shapiro { 3828567a2fc9SGregory Neil Shapiro VendorCode = VENDOR_DEC; 3829567a2fc9SGregory Neil Shapiro return true; 3830567a2fc9SGregory Neil Shapiro } 3831567a2fc9SGregory Neil Shapiro #endif /* DEC */ 3832c2aa98e2SPeter Wemm 383376b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE) 383412ed1c7cSGregory Neil Shapiro if (sm_strcasecmp(vendor, VENDOR_NAME) == 0) 383576b7bf71SPeter Wemm { 383676b7bf71SPeter Wemm VendorCode = VENDOR_CODE; 383712ed1c7cSGregory Neil Shapiro return true; 383876b7bf71SPeter Wemm } 38393299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */ 384076b7bf71SPeter Wemm 384112ed1c7cSGregory Neil Shapiro return false; 3842c2aa98e2SPeter Wemm } 384312ed1c7cSGregory Neil Shapiro /* 384476b7bf71SPeter Wemm ** GETVENDOR -- return vendor name based on vendor code 384576b7bf71SPeter Wemm ** 384676b7bf71SPeter Wemm ** Parameters: 384776b7bf71SPeter Wemm ** vendorcode -- numeric representation of vendor. 384876b7bf71SPeter Wemm ** 384976b7bf71SPeter Wemm ** Returns: 385076b7bf71SPeter Wemm ** string containing vendor name. 385176b7bf71SPeter Wemm */ 385276b7bf71SPeter Wemm 385376b7bf71SPeter Wemm char * 385476b7bf71SPeter Wemm getvendor(vendorcode) 385576b7bf71SPeter Wemm int vendorcode; 385676b7bf71SPeter Wemm { 385776b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE) 385876b7bf71SPeter Wemm /* 385976b7bf71SPeter Wemm ** Can't have the same switch case twice so need to 386076b7bf71SPeter Wemm ** handle VENDOR_CODE outside of switch. It might 386176b7bf71SPeter Wemm ** match one of the existing VENDOR_* codes. 386276b7bf71SPeter Wemm */ 386376b7bf71SPeter Wemm 386476b7bf71SPeter Wemm if (vendorcode == VENDOR_CODE) 386576b7bf71SPeter Wemm return VENDOR_NAME; 38663299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */ 386776b7bf71SPeter Wemm 386876b7bf71SPeter Wemm switch (vendorcode) 386976b7bf71SPeter Wemm { 387076b7bf71SPeter Wemm case VENDOR_BERKELEY: 387176b7bf71SPeter Wemm return "Berkeley"; 387276b7bf71SPeter Wemm 387376b7bf71SPeter Wemm case VENDOR_SUN: 387476b7bf71SPeter Wemm return "Sun"; 387576b7bf71SPeter Wemm 387676b7bf71SPeter Wemm case VENDOR_HP: 387776b7bf71SPeter Wemm return "HP"; 387876b7bf71SPeter Wemm 387976b7bf71SPeter Wemm case VENDOR_IBM: 388076b7bf71SPeter Wemm return "IBM"; 388176b7bf71SPeter Wemm 388276b7bf71SPeter Wemm case VENDOR_SENDMAIL: 388376b7bf71SPeter Wemm return "Sendmail"; 388476b7bf71SPeter Wemm 388576b7bf71SPeter Wemm default: 388676b7bf71SPeter Wemm return "Unknown"; 388776b7bf71SPeter Wemm } 388876b7bf71SPeter Wemm } 388912ed1c7cSGregory Neil Shapiro /* 3890c2aa98e2SPeter Wemm ** VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults 3891c2aa98e2SPeter Wemm ** 3892c2aa98e2SPeter Wemm ** Vendor_pre_defaults is called before reading the configuration 3893c2aa98e2SPeter Wemm ** file; vendor_post_defaults is called immediately after. 3894c2aa98e2SPeter Wemm ** 3895c2aa98e2SPeter Wemm ** Parameters: 3896c2aa98e2SPeter Wemm ** e -- the global environment to initialize. 3897c2aa98e2SPeter Wemm ** 3898c2aa98e2SPeter Wemm ** Returns: 3899c2aa98e2SPeter Wemm ** none. 3900c2aa98e2SPeter Wemm */ 3901c2aa98e2SPeter Wemm 3902c2aa98e2SPeter Wemm #if SHARE_V1 3903c2aa98e2SPeter Wemm int DefShareUid; /* default share uid to run as -- unused??? */ 39043299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */ 3905c2aa98e2SPeter Wemm 3906c2aa98e2SPeter Wemm void 3907c2aa98e2SPeter Wemm vendor_pre_defaults(e) 3908c2aa98e2SPeter Wemm ENVELOPE *e; 3909c2aa98e2SPeter Wemm { 3910c2aa98e2SPeter Wemm #if SHARE_V1 3911c2aa98e2SPeter Wemm /* OTHERUID is defined in shares.h, do not be alarmed */ 3912c2aa98e2SPeter Wemm DefShareUid = OTHERUID; 39133299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */ 3914c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) 3915c2aa98e2SPeter Wemm sun_pre_defaults(e); 39163299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */ 3917c2aa98e2SPeter Wemm #ifdef apollo 39183299c2f1SGregory Neil Shapiro /* 39193299c2f1SGregory Neil Shapiro ** stupid domain/os can't even open 39203299c2f1SGregory Neil Shapiro ** /etc/mail/sendmail.cf without this 39213299c2f1SGregory Neil Shapiro */ 39223299c2f1SGregory Neil Shapiro 3923567a2fc9SGregory Neil Shapiro sm_setuserenv("ISP", NULL); 3924567a2fc9SGregory Neil Shapiro sm_setuserenv("SYSTYPE", NULL); 39253299c2f1SGregory Neil Shapiro #endif /* apollo */ 3926c2aa98e2SPeter Wemm } 3927c2aa98e2SPeter Wemm 3928c2aa98e2SPeter Wemm 3929c2aa98e2SPeter Wemm void 3930c2aa98e2SPeter Wemm vendor_post_defaults(e) 3931c2aa98e2SPeter Wemm ENVELOPE *e; 3932c2aa98e2SPeter Wemm { 3933c2aa98e2SPeter Wemm #ifdef __QNX__ 3934c2aa98e2SPeter Wemm /* Makes sure the SOCK environment variable remains */ 3935951742c4SGregory Neil Shapiro sm_setuserenv("SOCK", NULL); 39363299c2f1SGregory Neil Shapiro #endif /* __QNX__ */ 3937c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) 3938c2aa98e2SPeter Wemm sun_post_defaults(e); 39393299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */ 3940c2aa98e2SPeter Wemm } 394112ed1c7cSGregory Neil Shapiro /* 3942c2aa98e2SPeter Wemm ** VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode 3943c2aa98e2SPeter Wemm */ 3944c2aa98e2SPeter Wemm 3945c2aa98e2SPeter Wemm void 3946c2aa98e2SPeter Wemm vendor_daemon_setup(e) 3947c2aa98e2SPeter Wemm ENVELOPE *e; 3948c2aa98e2SPeter Wemm { 39493299c2f1SGregory Neil Shapiro #if HASSETLOGIN 39503299c2f1SGregory Neil Shapiro (void) setlogin(RunAsUserName); 39513299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */ 3952c2aa98e2SPeter Wemm #if SECUREWARE 3953c2aa98e2SPeter Wemm if (getluid() != -1) 3954c2aa98e2SPeter Wemm { 3955c2aa98e2SPeter Wemm usrerr("Daemon cannot have LUID"); 395612ed1c7cSGregory Neil Shapiro finis(false, true, EX_USAGE); 3957c2aa98e2SPeter Wemm } 3958c2aa98e2SPeter Wemm #endif /* SECUREWARE */ 3959c2aa98e2SPeter Wemm } 396012ed1c7cSGregory Neil Shapiro /* 3961c2aa98e2SPeter Wemm ** VENDOR_SET_UID -- do setup for setting a user id 3962c2aa98e2SPeter Wemm ** 3963c2aa98e2SPeter Wemm ** This is called when we are still root. 3964c2aa98e2SPeter Wemm ** 3965c2aa98e2SPeter Wemm ** Parameters: 3966c2aa98e2SPeter Wemm ** uid -- the uid we are about to become. 3967c2aa98e2SPeter Wemm ** 3968c2aa98e2SPeter Wemm ** Returns: 3969c2aa98e2SPeter Wemm ** none. 3970c2aa98e2SPeter Wemm */ 3971c2aa98e2SPeter Wemm 3972c2aa98e2SPeter Wemm void 3973c2aa98e2SPeter Wemm vendor_set_uid(uid) 3974c2aa98e2SPeter Wemm UID_T uid; 3975c2aa98e2SPeter Wemm { 3976c2aa98e2SPeter Wemm /* 3977c2aa98e2SPeter Wemm ** We need to setup the share groups (lnodes) 39783299c2f1SGregory Neil Shapiro ** and add auditing information (luid's) 3979c2aa98e2SPeter Wemm ** before we loose our ``root''ness. 3980c2aa98e2SPeter Wemm */ 3981c2aa98e2SPeter Wemm #if SHARE_V1 3982c2aa98e2SPeter Wemm if (setupshares(uid, syserr) != 0) 3983c2aa98e2SPeter Wemm syserr("Unable to set up shares"); 39843299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */ 3985c2aa98e2SPeter Wemm #if SECUREWARE 3986c2aa98e2SPeter Wemm (void) setup_secure(uid); 39873299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */ 3988c2aa98e2SPeter Wemm } 398912ed1c7cSGregory Neil Shapiro /* 3990c2aa98e2SPeter Wemm ** VALIDATE_CONNECTION -- check connection for rationality 3991c2aa98e2SPeter Wemm ** 3992c2aa98e2SPeter Wemm ** If the connection is rejected, this routine should log an 3993c2aa98e2SPeter Wemm ** appropriate message -- but should never issue any SMTP protocol. 3994c2aa98e2SPeter Wemm ** 3995c2aa98e2SPeter Wemm ** Parameters: 3996c2aa98e2SPeter Wemm ** sap -- a pointer to a SOCKADDR naming the peer. 3997c2aa98e2SPeter Wemm ** hostname -- the name corresponding to sap. 3998c2aa98e2SPeter Wemm ** e -- the current envelope. 3999c2aa98e2SPeter Wemm ** 4000c2aa98e2SPeter Wemm ** Returns: 4001c2aa98e2SPeter Wemm ** error message from rejection. 4002c2aa98e2SPeter Wemm ** NULL if not rejected. 4003c2aa98e2SPeter Wemm */ 4004c2aa98e2SPeter Wemm 4005c2aa98e2SPeter Wemm #if TCPWRAPPERS 4006c2aa98e2SPeter Wemm # include <tcpd.h> 4007c2aa98e2SPeter Wemm 4008c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */ 4009c2aa98e2SPeter Wemm int allow_severity = LOG_INFO; 4010c2aa98e2SPeter Wemm int deny_severity = LOG_NOTICE; 40113299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */ 4012c2aa98e2SPeter Wemm 4013c2aa98e2SPeter Wemm char * 4014c2aa98e2SPeter Wemm validate_connection(sap, hostname, e) 4015c2aa98e2SPeter Wemm SOCKADDR *sap; 4016c2aa98e2SPeter Wemm char *hostname; 4017c2aa98e2SPeter Wemm ENVELOPE *e; 4018c2aa98e2SPeter Wemm { 4019c2aa98e2SPeter Wemm #if TCPWRAPPERS 4020c2aa98e2SPeter Wemm char *host; 402112ed1c7cSGregory Neil Shapiro char *addr; 402212ed1c7cSGregory Neil Shapiro extern int hosts_ctl(); 40233299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */ 4024c2aa98e2SPeter Wemm 4025c2aa98e2SPeter Wemm if (tTd(48, 3)) 402612ed1c7cSGregory Neil Shapiro sm_dprintf("validate_connection(%s, %s)\n", 4027c2aa98e2SPeter Wemm hostname, anynet_ntoa(sap)); 4028c2aa98e2SPeter Wemm 4029bfb62e91SGregory Neil Shapiro connection_rate_check(sap, e); 4030da7d7b9cSGregory Neil Shapiro if (rscheck("check_relay", hostname, anynet_ntoa(sap), e, 4031da7d7b9cSGregory Neil Shapiro RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID, NULL, NULL) != EX_OK) 4032c2aa98e2SPeter Wemm { 4033c2aa98e2SPeter Wemm static char reject[BUFSIZ*2]; 4034c2aa98e2SPeter Wemm extern char MsgBuf[]; 4035c2aa98e2SPeter Wemm 4036c2aa98e2SPeter Wemm if (tTd(48, 4)) 403712ed1c7cSGregory Neil Shapiro sm_dprintf(" ... validate_connection: BAD (rscheck)\n"); 4038c2aa98e2SPeter Wemm 40393299c2f1SGregory Neil Shapiro if (strlen(MsgBuf) >= 3) 4040951742c4SGregory Neil Shapiro (void) sm_strlcpy(reject, MsgBuf, sizeof(reject)); 4041c2aa98e2SPeter Wemm else 4042951742c4SGregory Neil Shapiro (void) sm_strlcpy(reject, "Access denied", sizeof(reject)); 4043c2aa98e2SPeter Wemm 4044c2aa98e2SPeter Wemm return reject; 4045c2aa98e2SPeter Wemm } 4046c2aa98e2SPeter Wemm 4047c2aa98e2SPeter Wemm #if TCPWRAPPERS 4048c2aa98e2SPeter Wemm if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']') 4049c2aa98e2SPeter Wemm host = "unknown"; 4050c2aa98e2SPeter Wemm else 4051c2aa98e2SPeter Wemm host = hostname; 405212ed1c7cSGregory Neil Shapiro addr = anynet_ntoa(sap); 405312ed1c7cSGregory Neil Shapiro 405412ed1c7cSGregory Neil Shapiro # if NETINET6 405512ed1c7cSGregory Neil Shapiro /* TCP/Wrappers don't want the IPv6: protocol label */ 405612ed1c7cSGregory Neil Shapiro if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0) 405712ed1c7cSGregory Neil Shapiro addr += 5; 405812ed1c7cSGregory Neil Shapiro # endif /* NETINET6 */ 405912ed1c7cSGregory Neil Shapiro 406012ed1c7cSGregory Neil Shapiro if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN)) 4061c2aa98e2SPeter Wemm { 4062c2aa98e2SPeter Wemm if (tTd(48, 4)) 406312ed1c7cSGregory Neil Shapiro sm_dprintf(" ... validate_connection: BAD (tcpwrappers)\n"); 406412ed1c7cSGregory Neil Shapiro if (LogLevel > 3) 40653299c2f1SGregory Neil Shapiro sm_syslog(LOG_NOTICE, e->e_id, 4066c2aa98e2SPeter Wemm "tcpwrappers (%s, %s) rejection", 406712ed1c7cSGregory Neil Shapiro host, addr); 4068c2aa98e2SPeter Wemm return "Access denied"; 4069c2aa98e2SPeter Wemm } 40703299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */ 4071c2aa98e2SPeter Wemm if (tTd(48, 4)) 407212ed1c7cSGregory Neil Shapiro sm_dprintf(" ... validate_connection: OK\n"); 4073c2aa98e2SPeter Wemm return NULL; 4074c2aa98e2SPeter Wemm } 4075c2aa98e2SPeter Wemm 407612ed1c7cSGregory Neil Shapiro /* 4077c2aa98e2SPeter Wemm ** STRTOL -- convert string to long integer 4078c2aa98e2SPeter Wemm ** 4079c2aa98e2SPeter Wemm ** For systems that don't have it in the C library. 4080c2aa98e2SPeter Wemm ** 4081c2aa98e2SPeter Wemm ** This is taken verbatim from the 4.4-Lite C library. 4082c2aa98e2SPeter Wemm */ 4083c2aa98e2SPeter Wemm 40843299c2f1SGregory Neil Shapiro #if NEEDSTRTOL 4085c2aa98e2SPeter Wemm 4086c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint) 4087c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; 40883299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */ 4089c2aa98e2SPeter Wemm 4090c2aa98e2SPeter Wemm /* 409112ed1c7cSGregory Neil Shapiro ** Convert a string to a long integer. 409212ed1c7cSGregory Neil Shapiro ** 409312ed1c7cSGregory Neil Shapiro ** Ignores `locale' stuff. Assumes that the upper and lower case 409412ed1c7cSGregory Neil Shapiro ** alphabets and digits are each contiguous. 4095c2aa98e2SPeter Wemm */ 4096c2aa98e2SPeter Wemm 4097c2aa98e2SPeter Wemm long 4098c2aa98e2SPeter Wemm strtol(nptr, endptr, base) 4099c2aa98e2SPeter Wemm const char *nptr; 4100c2aa98e2SPeter Wemm char **endptr; 4101c2aa98e2SPeter Wemm register int base; 4102c2aa98e2SPeter Wemm { 4103c2aa98e2SPeter Wemm register const char *s = nptr; 4104c2aa98e2SPeter Wemm register unsigned long acc; 4105c2aa98e2SPeter Wemm register int c; 4106c2aa98e2SPeter Wemm register unsigned long cutoff; 4107c2aa98e2SPeter Wemm register int neg = 0, any, cutlim; 4108c2aa98e2SPeter Wemm 4109c2aa98e2SPeter Wemm /* 411012ed1c7cSGregory Neil Shapiro ** Skip white space and pick up leading +/- sign if any. 411112ed1c7cSGregory Neil Shapiro ** If base is 0, allow 0x for hex and 0 for octal, else 411212ed1c7cSGregory Neil Shapiro ** assume decimal; if base is already 16, allow 0x. 4113c2aa98e2SPeter Wemm */ 4114c2aa98e2SPeter Wemm do { 4115c2aa98e2SPeter Wemm c = *s++; 41169bd497b8SGregory Neil Shapiro } while (isascii(c) && isspace(c)); 4117c2aa98e2SPeter Wemm if (c == '-') { 4118c2aa98e2SPeter Wemm neg = 1; 4119c2aa98e2SPeter Wemm c = *s++; 4120c2aa98e2SPeter Wemm } else if (c == '+') 4121c2aa98e2SPeter Wemm c = *s++; 4122c2aa98e2SPeter Wemm if ((base == 0 || base == 16) && 4123c2aa98e2SPeter Wemm c == '0' && (*s == 'x' || *s == 'X')) { 4124c2aa98e2SPeter Wemm c = s[1]; 4125c2aa98e2SPeter Wemm s += 2; 4126c2aa98e2SPeter Wemm base = 16; 4127c2aa98e2SPeter Wemm } 4128c2aa98e2SPeter Wemm if (base == 0) 4129c2aa98e2SPeter Wemm base = c == '0' ? 8 : 10; 4130c2aa98e2SPeter Wemm 4131c2aa98e2SPeter Wemm /* 413212ed1c7cSGregory Neil Shapiro ** Compute the cutoff value between legal numbers and illegal 413312ed1c7cSGregory Neil Shapiro ** numbers. That is the largest legal value, divided by the 413412ed1c7cSGregory Neil Shapiro ** base. An input number that is greater than this value, if 413512ed1c7cSGregory Neil Shapiro ** followed by a legal input character, is too big. One that 413612ed1c7cSGregory Neil Shapiro ** is equal to this value may be valid or not; the limit 413712ed1c7cSGregory Neil Shapiro ** between valid and invalid numbers is then based on the last 413812ed1c7cSGregory Neil Shapiro ** digit. For instance, if the range for longs is 413912ed1c7cSGregory Neil Shapiro ** [-2147483648..2147483647] and the input base is 10, 414012ed1c7cSGregory Neil Shapiro ** cutoff will be set to 214748364 and cutlim to either 414112ed1c7cSGregory Neil Shapiro ** 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 414212ed1c7cSGregory Neil Shapiro ** a value > 214748364, or equal but the next digit is > 7 (or 8), 414312ed1c7cSGregory Neil Shapiro ** the number is too big, and we will return a range error. 414412ed1c7cSGregory Neil Shapiro ** 414512ed1c7cSGregory Neil Shapiro ** Set any if any `digits' consumed; make it negative to indicate 414612ed1c7cSGregory Neil Shapiro ** overflow. 4147c2aa98e2SPeter Wemm */ 4148c2aa98e2SPeter Wemm cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX; 4149c2aa98e2SPeter Wemm cutlim = cutoff % (unsigned long) base; 4150c2aa98e2SPeter Wemm cutoff /= (unsigned long) base; 4151c2aa98e2SPeter Wemm for (acc = 0, any = 0;; c = *s++) { 41529bd497b8SGregory Neil Shapiro if (isascii(c) && isdigit(c)) 4153c2aa98e2SPeter Wemm c -= '0'; 41549bd497b8SGregory Neil Shapiro else if (isascii(c) && isalpha(c)) 4155c2aa98e2SPeter Wemm c -= isupper(c) ? 'A' - 10 : 'a' - 10; 4156c2aa98e2SPeter Wemm else 4157c2aa98e2SPeter Wemm break; 4158c2aa98e2SPeter Wemm if (c >= base) 4159c2aa98e2SPeter Wemm break; 4160c2aa98e2SPeter Wemm if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 4161c2aa98e2SPeter Wemm any = -1; 4162c2aa98e2SPeter Wemm else { 4163c2aa98e2SPeter Wemm any = 1; 4164c2aa98e2SPeter Wemm acc *= base; 4165c2aa98e2SPeter Wemm acc += c; 4166c2aa98e2SPeter Wemm } 4167c2aa98e2SPeter Wemm } 4168c2aa98e2SPeter Wemm if (any < 0) { 4169c2aa98e2SPeter Wemm acc = neg ? LONG_MIN : LONG_MAX; 4170c2aa98e2SPeter Wemm errno = ERANGE; 4171c2aa98e2SPeter Wemm } else if (neg) 4172c2aa98e2SPeter Wemm acc = -acc; 4173c2aa98e2SPeter Wemm if (endptr != 0) 4174c2aa98e2SPeter Wemm *endptr = (char *)(any ? s - 1 : nptr); 41753299c2f1SGregory Neil Shapiro return acc; 4176c2aa98e2SPeter Wemm } 4177c2aa98e2SPeter Wemm 41783299c2f1SGregory Neil Shapiro #endif /* NEEDSTRTOL */ 417912ed1c7cSGregory Neil Shapiro /* 4180c2aa98e2SPeter Wemm ** STRSTR -- find first substring in string 4181c2aa98e2SPeter Wemm ** 4182c2aa98e2SPeter Wemm ** Parameters: 4183c2aa98e2SPeter Wemm ** big -- the big (full) string. 4184c2aa98e2SPeter Wemm ** little -- the little (sub) string. 4185c2aa98e2SPeter Wemm ** 4186c2aa98e2SPeter Wemm ** Returns: 4187c2aa98e2SPeter Wemm ** A pointer to the first instance of little in big. 4188c2aa98e2SPeter Wemm ** big if little is the null string. 4189c2aa98e2SPeter Wemm ** NULL if little is not contained in big. 4190c2aa98e2SPeter Wemm */ 4191c2aa98e2SPeter Wemm 41923299c2f1SGregory Neil Shapiro #if NEEDSTRSTR 4193c2aa98e2SPeter Wemm 4194c2aa98e2SPeter Wemm char * 4195c2aa98e2SPeter Wemm strstr(big, little) 4196c2aa98e2SPeter Wemm char *big; 4197c2aa98e2SPeter Wemm char *little; 4198c2aa98e2SPeter Wemm { 4199c2aa98e2SPeter Wemm register char *p = big; 4200c2aa98e2SPeter Wemm int l; 4201c2aa98e2SPeter Wemm 4202c2aa98e2SPeter Wemm if (*little == '\0') 4203c2aa98e2SPeter Wemm return big; 4204c2aa98e2SPeter Wemm l = strlen(little); 4205c2aa98e2SPeter Wemm 4206c2aa98e2SPeter Wemm while ((p = strchr(p, *little)) != NULL) 4207c2aa98e2SPeter Wemm { 4208c2aa98e2SPeter Wemm if (strncmp(p, little, l) == 0) 4209c2aa98e2SPeter Wemm return p; 4210c2aa98e2SPeter Wemm p++; 4211c2aa98e2SPeter Wemm } 4212c2aa98e2SPeter Wemm return NULL; 4213c2aa98e2SPeter Wemm } 4214c2aa98e2SPeter Wemm 42153299c2f1SGregory Neil Shapiro #endif /* NEEDSTRSTR */ 421612ed1c7cSGregory Neil Shapiro /* 4217c2aa98e2SPeter Wemm ** SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX 4218c2aa98e2SPeter Wemm ** 42196f9c8e5bSGregory Neil Shapiro ** Some operating systems have weird problems with the gethostbyXXX 4220c2aa98e2SPeter Wemm ** routines. For example, Solaris versions at least through 2.3 4221c2aa98e2SPeter Wemm ** don't properly deliver a canonical h_name field. This tries to 4222c2aa98e2SPeter Wemm ** work around these problems. 42233299c2f1SGregory Neil Shapiro ** 42243299c2f1SGregory Neil Shapiro ** Support IPv6 as well as IPv4. 4225c2aa98e2SPeter Wemm */ 4226c2aa98e2SPeter Wemm 4227c0c4794dSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE 42283299c2f1SGregory Neil Shapiro 42293299c2f1SGregory Neil Shapiro # ifndef AI_DEFAULT 42303299c2f1SGregory Neil Shapiro # define AI_DEFAULT 0 /* dummy */ 42313299c2f1SGregory Neil Shapiro # endif /* ! AI_DEFAULT */ 42323299c2f1SGregory Neil Shapiro # ifndef AI_ADDRCONFIG 42333299c2f1SGregory Neil Shapiro # define AI_ADDRCONFIG 0 /* dummy */ 42343299c2f1SGregory Neil Shapiro # endif /* ! AI_ADDRCONFIG */ 42353299c2f1SGregory Neil Shapiro # ifndef AI_V4MAPPED 42363299c2f1SGregory Neil Shapiro # define AI_V4MAPPED 0 /* dummy */ 42373299c2f1SGregory Neil Shapiro # endif /* ! AI_V4MAPPED */ 42383299c2f1SGregory Neil Shapiro # ifndef AI_ALL 42393299c2f1SGregory Neil Shapiro # define AI_ALL 0 /* dummy */ 42403299c2f1SGregory Neil Shapiro # endif /* ! AI_ALL */ 42413299c2f1SGregory Neil Shapiro 42423299c2f1SGregory Neil Shapiro static struct hostent * 42436f9c8e5bSGregory Neil Shapiro sm_getipnodebyname(name, family, flags, err) 42446f9c8e5bSGregory Neil Shapiro const char *name; 42453299c2f1SGregory Neil Shapiro int family; 42463299c2f1SGregory Neil Shapiro int flags; 42473299c2f1SGregory Neil Shapiro int *err; 42483299c2f1SGregory Neil Shapiro { 42493299c2f1SGregory Neil Shapiro struct hostent *h; 42505dd76dd0SGregory Neil Shapiro # if HAS_GETHOSTBYNAME2 42515dd76dd0SGregory Neil Shapiro 42525dd76dd0SGregory Neil Shapiro h = gethostbyname2(name, family); 42535dd76dd0SGregory Neil Shapiro if (h == NULL) 42545dd76dd0SGregory Neil Shapiro *err = h_errno; 42555dd76dd0SGregory Neil Shapiro return h; 42565dd76dd0SGregory Neil Shapiro 42575dd76dd0SGregory Neil Shapiro # else /* HAS_GETHOSTBYNAME2 */ 42585dd76dd0SGregory Neil Shapiro bool resv6 = true; 42593299c2f1SGregory Neil Shapiro 42603299c2f1SGregory Neil Shapiro if (family == AF_INET6) 42613299c2f1SGregory Neil Shapiro { 42623299c2f1SGregory Neil Shapiro /* From RFC2133, section 6.1 */ 42633299c2f1SGregory Neil Shapiro resv6 = bitset(RES_USE_INET6, _res.options); 42643299c2f1SGregory Neil Shapiro _res.options |= RES_USE_INET6; 42653299c2f1SGregory Neil Shapiro } 4266b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(0); 42673299c2f1SGregory Neil Shapiro h = gethostbyname(name); 426812ed1c7cSGregory Neil Shapiro if (!resv6) 42693299c2f1SGregory Neil Shapiro _res.options &= ~RES_USE_INET6; 42705dd76dd0SGregory Neil Shapiro 42715dd76dd0SGregory Neil Shapiro /* the function is supposed to return only the requested family */ 42725dd76dd0SGregory Neil Shapiro if (h != NULL && h->h_addrtype != family) 42735dd76dd0SGregory Neil Shapiro { 42745dd76dd0SGregory Neil Shapiro # if NETINET6 42755dd76dd0SGregory Neil Shapiro freehostent(h); 42765dd76dd0SGregory Neil Shapiro # endif /* NETINET6 */ 42775dd76dd0SGregory Neil Shapiro h = NULL; 42785dd76dd0SGregory Neil Shapiro *err = NO_DATA; 42795dd76dd0SGregory Neil Shapiro } 42805dd76dd0SGregory Neil Shapiro else 428112ed1c7cSGregory Neil Shapiro *err = h_errno; 42823299c2f1SGregory Neil Shapiro return h; 42835dd76dd0SGregory Neil Shapiro # endif /* HAS_GETHOSTBYNAME2 */ 42843299c2f1SGregory Neil Shapiro } 42853299c2f1SGregory Neil Shapiro 42863299c2f1SGregory Neil Shapiro static struct hostent * 42876f9c8e5bSGregory Neil Shapiro sm_getipnodebyaddr(addr, len, family, err) 42886f9c8e5bSGregory Neil Shapiro const void *addr; 42896f9c8e5bSGregory Neil Shapiro size_t len; 42903299c2f1SGregory Neil Shapiro int family; 42913299c2f1SGregory Neil Shapiro int *err; 4292c2aa98e2SPeter Wemm { 4293c2aa98e2SPeter Wemm struct hostent *h; 42943299c2f1SGregory Neil Shapiro 4295b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(0); 42963299c2f1SGregory Neil Shapiro h = gethostbyaddr(addr, len, family); 42973299c2f1SGregory Neil Shapiro *err = h_errno; 42983299c2f1SGregory Neil Shapiro return h; 42993299c2f1SGregory Neil Shapiro } 4300c46d91b7SGregory Neil Shapiro 4301c46d91b7SGregory Neil Shapiro void 4302c46d91b7SGregory Neil Shapiro freehostent(h) 4303c46d91b7SGregory Neil Shapiro struct hostent *h; 4304c46d91b7SGregory Neil Shapiro { 4305c46d91b7SGregory Neil Shapiro /* 4306c46d91b7SGregory Neil Shapiro ** Stub routine -- if they don't have getipnodeby*(), 4307c46d91b7SGregory Neil Shapiro ** they probably don't have the free routine either. 4308c46d91b7SGregory Neil Shapiro */ 4309c46d91b7SGregory Neil Shapiro 4310c46d91b7SGregory Neil Shapiro return; 4311c46d91b7SGregory Neil Shapiro } 431212ed1c7cSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */ 43133299c2f1SGregory Neil Shapiro 43143299c2f1SGregory Neil Shapiro struct hostent * 43153299c2f1SGregory Neil Shapiro sm_gethostbyname(name, family) 43163299c2f1SGregory Neil Shapiro char *name; 43173299c2f1SGregory Neil Shapiro int family; 43183299c2f1SGregory Neil Shapiro { 4319b4662009SGregory Neil Shapiro int save_errno; 43203299c2f1SGregory Neil Shapiro struct hostent *h = NULL; 4321c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) 4322c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203 4323c2aa98e2SPeter Wemm static struct hostent hp; 4324c2aa98e2SPeter Wemm static char buf[1000]; 4325c2aa98e2SPeter Wemm extern struct hostent *_switch_gethostbyname_r(); 4326c2aa98e2SPeter Wemm 4327c2aa98e2SPeter Wemm if (tTd(61, 10)) 432812ed1c7cSGregory Neil Shapiro sm_dprintf("_switch_gethostbyname_r(%s)... ", name); 4329c2aa98e2SPeter Wemm h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); 4330b4662009SGregory Neil Shapiro save_errno = errno; 43313299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */ 4332c2aa98e2SPeter Wemm extern struct hostent *__switch_gethostbyname(); 4333c2aa98e2SPeter Wemm 4334c2aa98e2SPeter Wemm if (tTd(61, 10)) 433512ed1c7cSGregory Neil Shapiro sm_dprintf("__switch_gethostbyname(%s)... ", name); 4336c2aa98e2SPeter Wemm h = __switch_gethostbyname(name); 4337b4662009SGregory Neil Shapiro save_errno = errno; 43383299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */ 43393299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ 4340c2aa98e2SPeter Wemm int nmaps; 43413299c2f1SGregory Neil Shapiro # if NETINET6 4342552d4955SGregory Neil Shapiro # ifndef SM_IPNODEBYNAME_FLAGS 4343552d4955SGregory Neil Shapiro /* For IPv4-mapped addresses, use: AI_DEFAULT|AI_ALL */ 4344552d4955SGregory Neil Shapiro # define SM_IPNODEBYNAME_FLAGS AI_ADDRCONFIG 4345552d4955SGregory Neil Shapiro # endif /* SM_IPNODEBYNAME_FLAGS */ 4346552d4955SGregory Neil Shapiro 4347552d4955SGregory Neil Shapiro int flags = SM_IPNODEBYNAME_FLAGS; 43483299c2f1SGregory Neil Shapiro int err; 43493299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 4350c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 4351c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 4352c2aa98e2SPeter Wemm char hbuf[MAXNAME]; 4353c2aa98e2SPeter Wemm 4354c2aa98e2SPeter Wemm if (tTd(61, 10)) 435512ed1c7cSGregory Neil Shapiro sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family); 43563299c2f1SGregory Neil Shapiro 43573299c2f1SGregory Neil Shapiro # if NETINET6 43583299c2f1SGregory Neil Shapiro # if ADDRCONFIG_IS_BROKEN 43593299c2f1SGregory Neil Shapiro flags &= ~AI_ADDRCONFIG; 43603299c2f1SGregory Neil Shapiro # endif /* ADDRCONFIG_IS_BROKEN */ 43616f9c8e5bSGregory Neil Shapiro h = sm_getipnodebyname(name, family, flags, &err); 4362b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(err); 43633299c2f1SGregory Neil Shapiro # else /* NETINET6 */ 4364c2aa98e2SPeter Wemm h = gethostbyname(name); 43653299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 43663299c2f1SGregory Neil Shapiro 43673299c2f1SGregory Neil Shapiro save_errno = errno; 4368c2aa98e2SPeter Wemm if (h == NULL) 4369c2aa98e2SPeter Wemm { 4370c2aa98e2SPeter Wemm if (tTd(61, 10)) 437112ed1c7cSGregory Neil Shapiro sm_dprintf("failure\n"); 4372c2aa98e2SPeter Wemm 4373c2aa98e2SPeter Wemm nmaps = switch_map_find("hosts", maptype, mapreturn); 4374c2aa98e2SPeter Wemm while (--nmaps >= 0) 4375c46d91b7SGregory Neil Shapiro { 4376c2aa98e2SPeter Wemm if (strcmp(maptype[nmaps], "nis") == 0 || 4377c2aa98e2SPeter Wemm strcmp(maptype[nmaps], "files") == 0) 4378c2aa98e2SPeter Wemm break; 4379c46d91b7SGregory Neil Shapiro } 4380c46d91b7SGregory Neil Shapiro 4381c2aa98e2SPeter Wemm if (nmaps >= 0) 4382c2aa98e2SPeter Wemm { 4383c2aa98e2SPeter Wemm /* try short name */ 4384951742c4SGregory Neil Shapiro if (strlen(name) > sizeof(hbuf) - 1) 43853299c2f1SGregory Neil Shapiro { 43863299c2f1SGregory Neil Shapiro errno = save_errno; 4387c2aa98e2SPeter Wemm return NULL; 43883299c2f1SGregory Neil Shapiro } 4389951742c4SGregory Neil Shapiro (void) sm_strlcpy(hbuf, name, sizeof(hbuf)); 4390b4662009SGregory Neil Shapiro (void) shorten_hostname(hbuf); 4391c2aa98e2SPeter Wemm 4392c2aa98e2SPeter Wemm /* if it hasn't been shortened, there's no point */ 4393c2aa98e2SPeter Wemm if (strcmp(hbuf, name) != 0) 4394c2aa98e2SPeter Wemm { 4395c2aa98e2SPeter Wemm if (tTd(61, 10)) 439612ed1c7cSGregory Neil Shapiro sm_dprintf("sm_gethostbyname(%s, %d)... ", 43973299c2f1SGregory Neil Shapiro hbuf, family); 43983299c2f1SGregory Neil Shapiro 43993299c2f1SGregory Neil Shapiro # if NETINET6 44006f9c8e5bSGregory Neil Shapiro h = sm_getipnodebyname(hbuf, family, flags, &err); 4401b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(err); 44023299c2f1SGregory Neil Shapiro save_errno = errno; 44033299c2f1SGregory Neil Shapiro # else /* NETINET6 */ 4404c2aa98e2SPeter Wemm h = gethostbyname(hbuf); 44053299c2f1SGregory Neil Shapiro save_errno = errno; 44063299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 4407c2aa98e2SPeter Wemm } 4408c2aa98e2SPeter Wemm } 4409c2aa98e2SPeter Wemm } 44103299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ 44115dd76dd0SGregory Neil Shapiro 44125dd76dd0SGregory Neil Shapiro /* the function is supposed to return only the requested family */ 44135dd76dd0SGregory Neil Shapiro if (h != NULL && h->h_addrtype != family) 44145dd76dd0SGregory Neil Shapiro { 44155dd76dd0SGregory Neil Shapiro # if NETINET6 44165dd76dd0SGregory Neil Shapiro freehostent(h); 44175dd76dd0SGregory Neil Shapiro # endif /* NETINET6 */ 44185dd76dd0SGregory Neil Shapiro h = NULL; 44195dd76dd0SGregory Neil Shapiro SM_SET_H_ERRNO(NO_DATA); 44205dd76dd0SGregory Neil Shapiro } 44215dd76dd0SGregory Neil Shapiro 4422c2aa98e2SPeter Wemm if (tTd(61, 10)) 4423c2aa98e2SPeter Wemm { 4424c2aa98e2SPeter Wemm if (h == NULL) 442512ed1c7cSGregory Neil Shapiro sm_dprintf("failure\n"); 4426c2aa98e2SPeter Wemm else 44273299c2f1SGregory Neil Shapiro { 442812ed1c7cSGregory Neil Shapiro sm_dprintf("%s\n", h->h_name); 44293299c2f1SGregory Neil Shapiro if (tTd(61, 11)) 44303299c2f1SGregory Neil Shapiro { 44315dd76dd0SGregory Neil Shapiro struct in_addr ia; 44325dd76dd0SGregory Neil Shapiro size_t i; 44333299c2f1SGregory Neil Shapiro #if NETINET6 44343299c2f1SGregory Neil Shapiro struct in6_addr ia6; 44353299c2f1SGregory Neil Shapiro char buf6[INET6_ADDRSTRLEN]; 44363299c2f1SGregory Neil Shapiro #endif /* NETINET6 */ 44373299c2f1SGregory Neil Shapiro 44383299c2f1SGregory Neil Shapiro if (h->h_aliases != NULL) 44393299c2f1SGregory Neil Shapiro for (i = 0; h->h_aliases[i] != NULL; 44403299c2f1SGregory Neil Shapiro i++) 444112ed1c7cSGregory Neil Shapiro sm_dprintf("\talias: %s\n", 44423299c2f1SGregory Neil Shapiro h->h_aliases[i]); 44433299c2f1SGregory Neil Shapiro for (i = 0; h->h_addr_list[i] != NULL; i++) 44443299c2f1SGregory Neil Shapiro { 44453299c2f1SGregory Neil Shapiro char *addr; 44463299c2f1SGregory Neil Shapiro 44475dd76dd0SGregory Neil Shapiro addr = NULL; 44483299c2f1SGregory Neil Shapiro #if NETINET6 44495dd76dd0SGregory Neil Shapiro if (h->h_addrtype == AF_INET6) 44505dd76dd0SGregory Neil Shapiro { 44513299c2f1SGregory Neil Shapiro memmove(&ia6, h->h_addr_list[i], 44523299c2f1SGregory Neil Shapiro IN6ADDRSZ); 44533299c2f1SGregory Neil Shapiro addr = anynet_ntop(&ia6, 4454951742c4SGregory Neil Shapiro buf6, sizeof(buf6)); 44555dd76dd0SGregory Neil Shapiro } 44565dd76dd0SGregory Neil Shapiro else 44575dd76dd0SGregory Neil Shapiro #endif /* NETINET6 */ 44585dd76dd0SGregory Neil Shapiro /* "else" in #if code above */ 44595dd76dd0SGregory Neil Shapiro { 44603299c2f1SGregory Neil Shapiro memmove(&ia, h->h_addr_list[i], 44613299c2f1SGregory Neil Shapiro INADDRSZ); 44623299c2f1SGregory Neil Shapiro addr = (char *) inet_ntoa(ia); 44635dd76dd0SGregory Neil Shapiro } 44643299c2f1SGregory Neil Shapiro if (addr != NULL) 446512ed1c7cSGregory Neil Shapiro sm_dprintf("\taddr: %s\n", addr); 4466c2aa98e2SPeter Wemm } 44673299c2f1SGregory Neil Shapiro } 44683299c2f1SGregory Neil Shapiro } 44693299c2f1SGregory Neil Shapiro } 44703299c2f1SGregory Neil Shapiro errno = save_errno; 4471c2aa98e2SPeter Wemm return h; 4472c2aa98e2SPeter Wemm } 4473c2aa98e2SPeter Wemm 4474c2aa98e2SPeter Wemm struct hostent * 4475c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type) 4476c2aa98e2SPeter Wemm char *addr; 4477c2aa98e2SPeter Wemm int len; 4478c2aa98e2SPeter Wemm int type; 4479c2aa98e2SPeter Wemm { 44803299c2f1SGregory Neil Shapiro struct hostent *hp; 4481b4662009SGregory Neil Shapiro 4482b4662009SGregory Neil Shapiro #if NETINET6 4483b4662009SGregory Neil Shapiro if (type == AF_INET6 && 4484b4662009SGregory Neil Shapiro IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr)) 4485b4662009SGregory Neil Shapiro { 4486b4662009SGregory Neil Shapiro /* Avoid reverse lookup for IPv6 unspecified address */ 4487b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(HOST_NOT_FOUND); 4488b4662009SGregory Neil Shapiro return NULL; 4489b4662009SGregory Neil Shapiro } 4490b4662009SGregory Neil Shapiro #endif /* NETINET6 */ 4491b4662009SGregory Neil Shapiro 4492c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) 4493c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203 4494b4662009SGregory Neil Shapiro { 44953299c2f1SGregory Neil Shapiro static struct hostent he; 4496c2aa98e2SPeter Wemm static char buf[1000]; 4497c2aa98e2SPeter Wemm extern struct hostent *_switch_gethostbyaddr_r(); 4498c2aa98e2SPeter Wemm 4499b4662009SGregory Neil Shapiro hp = _switch_gethostbyaddr_r(addr, len, type, &he, 4500b4662009SGregory Neil Shapiro buf, sizeof(buf), &h_errno); 4501b4662009SGregory Neil Shapiro } 45023299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */ 4503b4662009SGregory Neil Shapiro { 4504c2aa98e2SPeter Wemm extern struct hostent *__switch_gethostbyaddr(); 4505c2aa98e2SPeter Wemm 45063299c2f1SGregory Neil Shapiro hp = __switch_gethostbyaddr(addr, len, type); 4507b4662009SGregory Neil Shapiro } 45083299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */ 45093299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */ 45103299c2f1SGregory Neil Shapiro # if NETINET6 4511b4662009SGregory Neil Shapiro { 45123299c2f1SGregory Neil Shapiro int err; 45133299c2f1SGregory Neil Shapiro 45146f9c8e5bSGregory Neil Shapiro hp = sm_getipnodebyaddr(addr, len, type, &err); 4515b4662009SGregory Neil Shapiro SM_SET_H_ERRNO(err); 4516b4662009SGregory Neil Shapiro } 45173299c2f1SGregory Neil Shapiro # else /* NETINET6 */ 45183299c2f1SGregory Neil Shapiro hp = gethostbyaddr(addr, len, type); 45193299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 45203299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */ 4521c0c4794dSGregory Neil Shapiro return hp; 4522c2aa98e2SPeter Wemm } 452312ed1c7cSGregory Neil Shapiro /* 4524c2aa98e2SPeter Wemm ** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid 4525c2aa98e2SPeter Wemm */ 4526c2aa98e2SPeter Wemm 4527c2aa98e2SPeter Wemm struct passwd * 4528c2aa98e2SPeter Wemm sm_getpwnam(user) 4529c2aa98e2SPeter Wemm char *user; 4530c2aa98e2SPeter Wemm { 4531c2aa98e2SPeter Wemm #ifdef _AIX4 4532c2aa98e2SPeter Wemm extern struct passwd *_getpwnam_shadow(const char *, const int); 4533c2aa98e2SPeter Wemm 4534c2aa98e2SPeter Wemm return _getpwnam_shadow(user, 0); 45353299c2f1SGregory Neil Shapiro #else /* _AIX4 */ 4536c2aa98e2SPeter Wemm return getpwnam(user); 45373299c2f1SGregory Neil Shapiro #endif /* _AIX4 */ 4538c2aa98e2SPeter Wemm } 4539c2aa98e2SPeter Wemm 4540c2aa98e2SPeter Wemm struct passwd * 4541c2aa98e2SPeter Wemm sm_getpwuid(uid) 4542c2aa98e2SPeter Wemm UID_T uid; 4543c2aa98e2SPeter Wemm { 4544c2aa98e2SPeter Wemm #if defined(_AIX4) && 0 4545c2aa98e2SPeter Wemm extern struct passwd *_getpwuid_shadow(const int, const int); 4546c2aa98e2SPeter Wemm 4547c2aa98e2SPeter Wemm return _getpwuid_shadow(uid,0); 45483299c2f1SGregory Neil Shapiro #else /* defined(_AIX4) && 0 */ 4549c2aa98e2SPeter Wemm return getpwuid(uid); 45503299c2f1SGregory Neil Shapiro #endif /* defined(_AIX4) && 0 */ 4551c2aa98e2SPeter Wemm } 455212ed1c7cSGregory Neil Shapiro /* 4553c2aa98e2SPeter Wemm ** SECUREWARE_SETUP_SECURE -- Convex SecureWare setup 4554c2aa98e2SPeter Wemm ** 4555c2aa98e2SPeter Wemm ** Set up the trusted computing environment for C2 level security 4556c2aa98e2SPeter Wemm ** under SecureWare. 4557c2aa98e2SPeter Wemm ** 4558c2aa98e2SPeter Wemm ** Parameters: 4559c2aa98e2SPeter Wemm ** uid -- uid of the user to initialize in the TCB 4560c2aa98e2SPeter Wemm ** 4561c2aa98e2SPeter Wemm ** Returns: 4562c2aa98e2SPeter Wemm ** none 4563c2aa98e2SPeter Wemm ** 4564c2aa98e2SPeter Wemm ** Side Effects: 4565c2aa98e2SPeter Wemm ** Initialized the user in the trusted computing base 4566c2aa98e2SPeter Wemm */ 4567c2aa98e2SPeter Wemm 4568c2aa98e2SPeter Wemm #if SECUREWARE 4569c2aa98e2SPeter Wemm 4570c2aa98e2SPeter Wemm # include <sys/security.h> 4571c2aa98e2SPeter Wemm # include <prot.h> 4572c2aa98e2SPeter Wemm 4573c2aa98e2SPeter Wemm void 4574c2aa98e2SPeter Wemm secureware_setup_secure(uid) 4575c2aa98e2SPeter Wemm UID_T uid; 4576c2aa98e2SPeter Wemm { 4577c2aa98e2SPeter Wemm int rc; 4578c2aa98e2SPeter Wemm 4579c2aa98e2SPeter Wemm if (getluid() != -1) 4580c2aa98e2SPeter Wemm return; 4581c2aa98e2SPeter Wemm 4582c2aa98e2SPeter Wemm if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN) 4583c2aa98e2SPeter Wemm { 4584c2aa98e2SPeter Wemm switch (rc) 4585c2aa98e2SPeter Wemm { 4586c2aa98e2SPeter Wemm case SSI_NO_PRPW_ENTRY: 458712ed1c7cSGregory Neil Shapiro syserr("No protected passwd entry, uid = %d", 458812ed1c7cSGregory Neil Shapiro (int) uid); 4589c2aa98e2SPeter Wemm break; 4590c2aa98e2SPeter Wemm 4591c2aa98e2SPeter Wemm case SSI_LOCKED: 459212ed1c7cSGregory Neil Shapiro syserr("Account has been disabled, uid = %d", 459312ed1c7cSGregory Neil Shapiro (int) uid); 4594c2aa98e2SPeter Wemm break; 4595c2aa98e2SPeter Wemm 4596c2aa98e2SPeter Wemm case SSI_RETIRED: 459712ed1c7cSGregory Neil Shapiro syserr("Account has been retired, uid = %d", 459812ed1c7cSGregory Neil Shapiro (int) uid); 4599c2aa98e2SPeter Wemm break; 4600c2aa98e2SPeter Wemm 4601c2aa98e2SPeter Wemm case SSI_BAD_SET_LUID: 460212ed1c7cSGregory Neil Shapiro syserr("Could not set LUID, uid = %d", (int) uid); 4603c2aa98e2SPeter Wemm break; 4604c2aa98e2SPeter Wemm 4605c2aa98e2SPeter Wemm case SSI_BAD_SET_PRIVS: 460612ed1c7cSGregory Neil Shapiro syserr("Could not set kernel privs, uid = %d", 460712ed1c7cSGregory Neil Shapiro (int) uid); 4608c2aa98e2SPeter Wemm 4609c2aa98e2SPeter Wemm default: 4610c2aa98e2SPeter Wemm syserr("Unknown return code (%d) from set_secure_info(%d)", 461112ed1c7cSGregory Neil Shapiro rc, (int) uid); 4612c2aa98e2SPeter Wemm break; 4613c2aa98e2SPeter Wemm } 461412ed1c7cSGregory Neil Shapiro finis(false, true, EX_NOPERM); 4615c2aa98e2SPeter Wemm } 4616c2aa98e2SPeter Wemm } 4617c2aa98e2SPeter Wemm #endif /* SECUREWARE */ 461812ed1c7cSGregory Neil Shapiro /* 46193299c2f1SGregory Neil Shapiro ** ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address 462076b7bf71SPeter Wemm ** 462176b7bf71SPeter Wemm ** Add hostnames to class 'w' based on the IP address read from 462276b7bf71SPeter Wemm ** the network interface. 462376b7bf71SPeter Wemm ** 462476b7bf71SPeter Wemm ** Parameters: 462576b7bf71SPeter Wemm ** sa -- a pointer to a SOCKADDR containing the address 462676b7bf71SPeter Wemm ** 462776b7bf71SPeter Wemm ** Returns: 462876b7bf71SPeter Wemm ** 0 if successful, -1 if host lookup fails. 462976b7bf71SPeter Wemm */ 463076b7bf71SPeter Wemm 46313299c2f1SGregory Neil Shapiro static int 463276b7bf71SPeter Wemm add_hostnames(sa) 463376b7bf71SPeter Wemm SOCKADDR *sa; 463476b7bf71SPeter Wemm { 463576b7bf71SPeter Wemm struct hostent *hp; 46363299c2f1SGregory Neil Shapiro char **ha; 46373299c2f1SGregory Neil Shapiro char hnb[MAXHOSTNAMELEN]; 463876b7bf71SPeter Wemm 463976b7bf71SPeter Wemm /* lookup name with IP address */ 464076b7bf71SPeter Wemm switch (sa->sa.sa_family) 464176b7bf71SPeter Wemm { 46423299c2f1SGregory Neil Shapiro #if NETINET 464376b7bf71SPeter Wemm case AF_INET: 464476b7bf71SPeter Wemm hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr, 4645c46d91b7SGregory Neil Shapiro sizeof(sa->sin.sin_addr), 4646c46d91b7SGregory Neil Shapiro sa->sa.sa_family); 464776b7bf71SPeter Wemm break; 46483299c2f1SGregory Neil Shapiro #endif /* NETINET */ 46493299c2f1SGregory Neil Shapiro 46503299c2f1SGregory Neil Shapiro #if NETINET6 46513299c2f1SGregory Neil Shapiro case AF_INET6: 46523299c2f1SGregory Neil Shapiro hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr, 4653c46d91b7SGregory Neil Shapiro sizeof(sa->sin6.sin6_addr), 4654c46d91b7SGregory Neil Shapiro sa->sa.sa_family); 46553299c2f1SGregory Neil Shapiro break; 46563299c2f1SGregory Neil Shapiro #endif /* NETINET6 */ 465776b7bf71SPeter Wemm 465876b7bf71SPeter Wemm default: 46593299c2f1SGregory Neil Shapiro /* Give warning about unsupported family */ 466076b7bf71SPeter Wemm if (LogLevel > 3) 466176b7bf71SPeter Wemm sm_syslog(LOG_WARNING, NOQID, 466276b7bf71SPeter Wemm "Unsupported address family %d: %.100s", 466376b7bf71SPeter Wemm sa->sa.sa_family, anynet_ntoa(sa)); 466476b7bf71SPeter Wemm return -1; 466576b7bf71SPeter Wemm } 466676b7bf71SPeter Wemm 466776b7bf71SPeter Wemm if (hp == NULL) 466876b7bf71SPeter Wemm { 466976b7bf71SPeter Wemm int save_errno = errno; 467076b7bf71SPeter Wemm 46713299c2f1SGregory Neil Shapiro if (LogLevel > 3 && 4672ba00ec3dSGregory Neil Shapiro #if NETINET && defined(IN_LINKLOCAL) 4673ba00ec3dSGregory Neil Shapiro !(sa->sa.sa_family == AF_INET && 4674ba00ec3dSGregory Neil Shapiro IN_LINKLOCAL(ntohl(sa->sin.sin_addr.s_addr))) && 4675ba00ec3dSGregory Neil Shapiro #endif /* NETINET && defined(IN_LINKLOCAL) */ 46763299c2f1SGregory Neil Shapiro #if NETINET6 46773299c2f1SGregory Neil Shapiro !(sa->sa.sa_family == AF_INET6 && 46783299c2f1SGregory Neil Shapiro IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) && 46793299c2f1SGregory Neil Shapiro #endif /* NETINET6 */ 468012ed1c7cSGregory Neil Shapiro true) 468176b7bf71SPeter Wemm sm_syslog(LOG_WARNING, NOQID, 468212ed1c7cSGregory Neil Shapiro "gethostbyaddr(%.100s) failed: %d", 468376b7bf71SPeter Wemm anynet_ntoa(sa), 468476b7bf71SPeter Wemm #if NAMED_BIND 468576b7bf71SPeter Wemm h_errno 46863299c2f1SGregory Neil Shapiro #else /* NAMED_BIND */ 468776b7bf71SPeter Wemm -1 46883299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */ 468976b7bf71SPeter Wemm ); 469076b7bf71SPeter Wemm errno = save_errno; 469176b7bf71SPeter Wemm return -1; 469276b7bf71SPeter Wemm } 469376b7bf71SPeter Wemm 469476b7bf71SPeter Wemm /* save its cname */ 469576b7bf71SPeter Wemm if (!wordinclass((char *) hp->h_name, 'w')) 469676b7bf71SPeter Wemm { 469776b7bf71SPeter Wemm setclass('w', (char *) hp->h_name); 469876b7bf71SPeter Wemm if (tTd(0, 4)) 469912ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s\n", hp->h_name); 47003299c2f1SGregory Neil Shapiro 4701951742c4SGregory Neil Shapiro if (sm_snprintf(hnb, sizeof(hnb), "[%s]", hp->h_name) < 4702951742c4SGregory Neil Shapiro sizeof(hnb) 47033299c2f1SGregory Neil Shapiro && !wordinclass((char *) hnb, 'w')) 47043299c2f1SGregory Neil Shapiro setclass('w', hnb); 47053299c2f1SGregory Neil Shapiro } 47063299c2f1SGregory Neil Shapiro else 47073299c2f1SGregory Neil Shapiro { 47083299c2f1SGregory Neil Shapiro if (tTd(0, 43)) 470912ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name); 471076b7bf71SPeter Wemm } 471176b7bf71SPeter Wemm 471276b7bf71SPeter Wemm /* save all it aliases name */ 47133299c2f1SGregory Neil Shapiro for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++) 471476b7bf71SPeter Wemm { 47153299c2f1SGregory Neil Shapiro if (!wordinclass(*ha, 'w')) 471676b7bf71SPeter Wemm { 47173299c2f1SGregory Neil Shapiro setclass('w', *ha); 471876b7bf71SPeter Wemm if (tTd(0, 4)) 471912ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s\n", *ha); 4720951742c4SGregory Neil Shapiro if (sm_snprintf(hnb, sizeof(hnb), 4721951742c4SGregory Neil Shapiro "[%s]", *ha) < sizeof(hnb) && 47223299c2f1SGregory Neil Shapiro !wordinclass((char *) hnb, 'w')) 47233299c2f1SGregory Neil Shapiro setclass('w', hnb); 472476b7bf71SPeter Wemm } 47253299c2f1SGregory Neil Shapiro else 47263299c2f1SGregory Neil Shapiro { 47273299c2f1SGregory Neil Shapiro if (tTd(0, 43)) 472812ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s (already in $=w)\n", 47293299c2f1SGregory Neil Shapiro *ha); 47303299c2f1SGregory Neil Shapiro } 473176b7bf71SPeter Wemm } 473212ed1c7cSGregory Neil Shapiro #if NETINET6 4733c46d91b7SGregory Neil Shapiro freehostent(hp); 473412ed1c7cSGregory Neil Shapiro #endif /* NETINET6 */ 473576b7bf71SPeter Wemm return 0; 473676b7bf71SPeter Wemm } 473712ed1c7cSGregory Neil Shapiro /* 4738c2aa98e2SPeter Wemm ** LOAD_IF_NAMES -- load interface-specific names into $=w 4739c2aa98e2SPeter Wemm ** 4740c2aa98e2SPeter Wemm ** Parameters: 4741c2aa98e2SPeter Wemm ** none. 4742c2aa98e2SPeter Wemm ** 4743c2aa98e2SPeter Wemm ** Returns: 4744c2aa98e2SPeter Wemm ** none. 4745c2aa98e2SPeter Wemm ** 4746c2aa98e2SPeter Wemm ** Side Effects: 4747c2aa98e2SPeter Wemm ** Loads $=w with the names of all the interfaces. 4748c2aa98e2SPeter Wemm */ 4749c2aa98e2SPeter Wemm 47503299c2f1SGregory Neil Shapiro #if !NETINET 47513299c2f1SGregory Neil Shapiro # define SIOCGIFCONF_IS_BROKEN 1 /* XXX */ 47523299c2f1SGregory Neil Shapiro #endif /* !NETINET */ 47533299c2f1SGregory Neil Shapiro 4754c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN 4755c2aa98e2SPeter Wemm struct rtentry; 4756c2aa98e2SPeter Wemm struct mbuf; 4757c2aa98e2SPeter Wemm # ifndef SUNOS403 4758567a2fc9SGregory Neil Shapiro # include <sm/time.h> 47593299c2f1SGregory Neil Shapiro # endif /* ! SUNOS403 */ 47603299c2f1SGregory Neil Shapiro # if (_AIX4 >= 40300) && !defined(_NET_IF_H) 4761c2aa98e2SPeter Wemm # undef __P 47623299c2f1SGregory Neil Shapiro # endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */ 4763c2aa98e2SPeter Wemm # include <net/if.h> 47643299c2f1SGregory Neil Shapiro #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */ 4765c2aa98e2SPeter Wemm 4766c2aa98e2SPeter Wemm void 4767c2aa98e2SPeter Wemm load_if_names() 4768c2aa98e2SPeter Wemm { 47693299c2f1SGregory Neil Shapiro # if NETINET6 && defined(SIOCGLIFCONF) 477012ed1c7cSGregory Neil Shapiro # ifdef __hpux 477112ed1c7cSGregory Neil Shapiro 477212ed1c7cSGregory Neil Shapiro /* 477312ed1c7cSGregory Neil Shapiro ** Unfortunately, HP has changed all of the structures, 477412ed1c7cSGregory Neil Shapiro ** making life difficult for implementors. 477512ed1c7cSGregory Neil Shapiro */ 477612ed1c7cSGregory Neil Shapiro 477712ed1c7cSGregory Neil Shapiro # define lifconf if_laddrconf 477812ed1c7cSGregory Neil Shapiro # define lifc_len iflc_len 477912ed1c7cSGregory Neil Shapiro # define lifc_buf iflc_buf 478012ed1c7cSGregory Neil Shapiro # define lifreq if_laddrreq 478112ed1c7cSGregory Neil Shapiro # define lifr_addr iflr_addr 478212ed1c7cSGregory Neil Shapiro # define lifr_name iflr_name 478312ed1c7cSGregory Neil Shapiro # define lifr_flags iflr_flags 478412ed1c7cSGregory Neil Shapiro # define ss_family sa_family 478512ed1c7cSGregory Neil Shapiro # undef SIOCGLIFNUM 478612ed1c7cSGregory Neil Shapiro # endif /* __hpux */ 478712ed1c7cSGregory Neil Shapiro 47883299c2f1SGregory Neil Shapiro int s; 47893299c2f1SGregory Neil Shapiro int i; 479012ed1c7cSGregory Neil Shapiro size_t len; 47913299c2f1SGregory Neil Shapiro int numifs; 479212ed1c7cSGregory Neil Shapiro char *buf; 479312ed1c7cSGregory Neil Shapiro struct lifconf lifc; 479412ed1c7cSGregory Neil Shapiro # ifdef SIOCGLIFNUM 479512ed1c7cSGregory Neil Shapiro struct lifnum lifn; 479612ed1c7cSGregory Neil Shapiro # endif /* SIOCGLIFNUM */ 47973299c2f1SGregory Neil Shapiro 47983299c2f1SGregory Neil Shapiro s = socket(InetMode, SOCK_DGRAM, 0); 47993299c2f1SGregory Neil Shapiro if (s == -1) 48003299c2f1SGregory Neil Shapiro return; 48013299c2f1SGregory Neil Shapiro 48023299c2f1SGregory Neil Shapiro /* get the list of known IP address from the kernel */ 480312ed1c7cSGregory Neil Shapiro # ifdef __hpux 480412ed1c7cSGregory Neil Shapiro i = ioctl(s, SIOCGIFNUM, (char *) &numifs); 480512ed1c7cSGregory Neil Shapiro # endif /* __hpux */ 48063299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFNUM 48073299c2f1SGregory Neil Shapiro lifn.lifn_family = AF_UNSPEC; 48083299c2f1SGregory Neil Shapiro lifn.lifn_flags = 0; 480912ed1c7cSGregory Neil Shapiro i = ioctl(s, SIOCGLIFNUM, (char *)&lifn); 481012ed1c7cSGregory Neil Shapiro numifs = lifn.lifn_count; 481112ed1c7cSGregory Neil Shapiro # endif /* SIOCGLIFNUM */ 481212ed1c7cSGregory Neil Shapiro 481312ed1c7cSGregory Neil Shapiro # if defined(__hpux) || defined(SIOCGLIFNUM) 481412ed1c7cSGregory Neil Shapiro if (i < 0) 48153299c2f1SGregory Neil Shapiro { 48163299c2f1SGregory Neil Shapiro /* can't get number of interfaces -- fall back */ 48173299c2f1SGregory Neil Shapiro if (tTd(0, 4)) 481812ed1c7cSGregory Neil Shapiro sm_dprintf("SIOCGLIFNUM failed: %s\n", 481912ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 48203299c2f1SGregory Neil Shapiro numifs = -1; 48213299c2f1SGregory Neil Shapiro } 482212ed1c7cSGregory Neil Shapiro else if (tTd(0, 42)) 482312ed1c7cSGregory Neil Shapiro sm_dprintf("system has %d interfaces\n", numifs); 48243299c2f1SGregory Neil Shapiro if (numifs < 0) 482512ed1c7cSGregory Neil Shapiro # endif /* defined(__hpux) || defined(SIOCGLIFNUM) */ 48263299c2f1SGregory Neil Shapiro numifs = MAXINTERFACES; 48273299c2f1SGregory Neil Shapiro 48283299c2f1SGregory Neil Shapiro if (numifs <= 0) 48293299c2f1SGregory Neil Shapiro { 4830c46d91b7SGregory Neil Shapiro (void) close(s); 48313299c2f1SGregory Neil Shapiro return; 48323299c2f1SGregory Neil Shapiro } 483312ed1c7cSGregory Neil Shapiro 483412ed1c7cSGregory Neil Shapiro len = lifc.lifc_len = numifs * sizeof(struct lifreq); 483512ed1c7cSGregory Neil Shapiro buf = lifc.lifc_buf = xalloc(lifc.lifc_len); 483612ed1c7cSGregory Neil Shapiro # ifndef __hpux 48373299c2f1SGregory Neil Shapiro lifc.lifc_family = AF_UNSPEC; 48383299c2f1SGregory Neil Shapiro lifc.lifc_flags = 0; 48397660b554SGregory Neil Shapiro # endif /* ! __hpux */ 48403299c2f1SGregory Neil Shapiro if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) 48413299c2f1SGregory Neil Shapiro { 48423299c2f1SGregory Neil Shapiro if (tTd(0, 4)) 484312ed1c7cSGregory Neil Shapiro sm_dprintf("SIOCGLIFCONF failed: %s\n", 484412ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 4845c46d91b7SGregory Neil Shapiro (void) close(s); 484612ed1c7cSGregory Neil Shapiro sm_free(buf); 48473299c2f1SGregory Neil Shapiro return; 48483299c2f1SGregory Neil Shapiro } 48493299c2f1SGregory Neil Shapiro 48503299c2f1SGregory Neil Shapiro /* scan the list of IP address */ 48513299c2f1SGregory Neil Shapiro if (tTd(0, 40)) 485212ed1c7cSGregory Neil Shapiro sm_dprintf("scanning for interface specific names, lifc_len=%ld\n", 485312ed1c7cSGregory Neil Shapiro (long) len); 48543299c2f1SGregory Neil Shapiro 485512ed1c7cSGregory Neil Shapiro for (i = 0; i < len && i >= 0; ) 48563299c2f1SGregory Neil Shapiro { 485712ed1c7cSGregory Neil Shapiro int flags; 485812ed1c7cSGregory Neil Shapiro struct lifreq *ifr = (struct lifreq *)&buf[i]; 48593299c2f1SGregory Neil Shapiro SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr; 486012ed1c7cSGregory Neil Shapiro int af = ifr->lifr_addr.ss_family; 48613299c2f1SGregory Neil Shapiro char *addr; 486212ed1c7cSGregory Neil Shapiro char *name; 48633299c2f1SGregory Neil Shapiro struct in6_addr ia6; 48643299c2f1SGregory Neil Shapiro struct in_addr ia; 48653299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS 48663299c2f1SGregory Neil Shapiro struct lifreq ifrf; 48673299c2f1SGregory Neil Shapiro # endif /* SIOCGLIFFLAGS */ 48683299c2f1SGregory Neil Shapiro char ip_addr[256]; 48693299c2f1SGregory Neil Shapiro char buf6[INET6_ADDRSTRLEN]; 48703299c2f1SGregory Neil Shapiro 48713299c2f1SGregory Neil Shapiro /* 48723299c2f1SGregory Neil Shapiro ** We must close and recreate the socket each time 48733299c2f1SGregory Neil Shapiro ** since we don't know what type of socket it is now 48743299c2f1SGregory Neil Shapiro ** (each status function may change it). 48753299c2f1SGregory Neil Shapiro */ 48763299c2f1SGregory Neil Shapiro 48773299c2f1SGregory Neil Shapiro (void) close(s); 48783299c2f1SGregory Neil Shapiro 48793299c2f1SGregory Neil Shapiro s = socket(af, SOCK_DGRAM, 0); 48803299c2f1SGregory Neil Shapiro if (s == -1) 4881c46d91b7SGregory Neil Shapiro { 488212ed1c7cSGregory Neil Shapiro sm_free(buf); /* XXX */ 48833299c2f1SGregory Neil Shapiro return; 4884c46d91b7SGregory Neil Shapiro } 48853299c2f1SGregory Neil Shapiro 48863299c2f1SGregory Neil Shapiro /* 48873299c2f1SGregory Neil Shapiro ** If we don't have a complete ifr structure, 48883299c2f1SGregory Neil Shapiro ** don't try to use it. 48893299c2f1SGregory Neil Shapiro */ 48903299c2f1SGregory Neil Shapiro 4891951742c4SGregory Neil Shapiro if ((len - i) < sizeof(*ifr)) 48923299c2f1SGregory Neil Shapiro break; 48933299c2f1SGregory Neil Shapiro 48943299c2f1SGregory Neil Shapiro # ifdef BSD4_4_SOCKADDR 4895951742c4SGregory Neil Shapiro if (sa->sa.sa_len > sizeof(ifr->lifr_addr)) 4896951742c4SGregory Neil Shapiro i += sizeof(ifr->lifr_name) + sa->sa.sa_len; 48973299c2f1SGregory Neil Shapiro else 48983299c2f1SGregory Neil Shapiro # endif /* BSD4_4_SOCKADDR */ 4899567a2fc9SGregory Neil Shapiro # ifdef DEC 4900567a2fc9SGregory Neil Shapiro /* fix for IPv6 size differences */ 4901951742c4SGregory Neil Shapiro i += sizeof(ifr->ifr_name) + 4902567a2fc9SGregory Neil Shapiro max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len); 4903567a2fc9SGregory Neil Shapiro # else /* DEC */ 4904951742c4SGregory Neil Shapiro i += sizeof(*ifr); 4905567a2fc9SGregory Neil Shapiro # endif /* DEC */ 49063299c2f1SGregory Neil Shapiro 49073299c2f1SGregory Neil Shapiro if (tTd(0, 20)) 490812ed1c7cSGregory Neil Shapiro sm_dprintf("%s\n", anynet_ntoa(sa)); 49093299c2f1SGregory Neil Shapiro 49103299c2f1SGregory Neil Shapiro if (af != AF_INET && af != AF_INET6) 49113299c2f1SGregory Neil Shapiro continue; 49123299c2f1SGregory Neil Shapiro 49133299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS 49143299c2f1SGregory Neil Shapiro memset(&ifrf, '\0', sizeof(struct lifreq)); 491512ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name, 49163299c2f1SGregory Neil Shapiro sizeof(ifrf.lifr_name)); 49173299c2f1SGregory Neil Shapiro if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0) 49183299c2f1SGregory Neil Shapiro { 49193299c2f1SGregory Neil Shapiro if (tTd(0, 4)) 492012ed1c7cSGregory Neil Shapiro sm_dprintf("SIOCGLIFFLAGS failed: %s\n", 492112ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 49223299c2f1SGregory Neil Shapiro continue; 49233299c2f1SGregory Neil Shapiro } 49243299c2f1SGregory Neil Shapiro 492512ed1c7cSGregory Neil Shapiro name = ifr->lifr_name; 492612ed1c7cSGregory Neil Shapiro flags = ifrf.lifr_flags; 492712ed1c7cSGregory Neil Shapiro 492812ed1c7cSGregory Neil Shapiro if (tTd(0, 41)) 492912ed1c7cSGregory Neil Shapiro sm_dprintf("\tflags: %lx\n", (unsigned long) flags); 493012ed1c7cSGregory Neil Shapiro 493112ed1c7cSGregory Neil Shapiro if (!bitset(IFF_UP, flags)) 49323299c2f1SGregory Neil Shapiro continue; 49333299c2f1SGregory Neil Shapiro # endif /* SIOCGLIFFLAGS */ 49343299c2f1SGregory Neil Shapiro 49353299c2f1SGregory Neil Shapiro ip_addr[0] = '\0'; 49363299c2f1SGregory Neil Shapiro 49373299c2f1SGregory Neil Shapiro /* extract IP address from the list*/ 49383299c2f1SGregory Neil Shapiro switch (af) 49393299c2f1SGregory Neil Shapiro { 49403299c2f1SGregory Neil Shapiro case AF_INET6: 49416f9c8e5bSGregory Neil Shapiro SETV6LOOPBACKADDRFOUND(*sa); 4942c46d91b7SGregory Neil Shapiro # ifdef __KAME__ 4943b4662009SGregory Neil Shapiro /* convert into proper scoped address */ 4944b4662009SGregory Neil Shapiro if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) || 4945b4662009SGregory Neil Shapiro IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) && 4946c46d91b7SGregory Neil Shapiro sa->sin6.sin6_scope_id == 0) 4947c46d91b7SGregory Neil Shapiro { 4948b4662009SGregory Neil Shapiro struct in6_addr *ia6p; 4949b4662009SGregory Neil Shapiro 4950b4662009SGregory Neil Shapiro ia6p = &sa->sin6.sin6_addr; 4951b4662009SGregory Neil Shapiro sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] | 4952b4662009SGregory Neil Shapiro ((unsigned int)ia6p->s6_addr[2] << 8)); 4953b4662009SGregory Neil Shapiro ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0; 4954c46d91b7SGregory Neil Shapiro } 4955c46d91b7SGregory Neil Shapiro # endif /* __KAME__ */ 4956b4662009SGregory Neil Shapiro ia6 = sa->sin6.sin6_addr; 4957c46d91b7SGregory Neil Shapiro if (IN6_IS_ADDR_UNSPECIFIED(&ia6)) 49583299c2f1SGregory Neil Shapiro { 4959951742c4SGregory Neil Shapiro addr = anynet_ntop(&ia6, buf6, sizeof(buf6)); 49603299c2f1SGregory Neil Shapiro message("WARNING: interface %s is UP with %s address", 496112ed1c7cSGregory Neil Shapiro name, addr == NULL ? "(NULL)" : addr); 49623299c2f1SGregory Neil Shapiro continue; 49633299c2f1SGregory Neil Shapiro } 49643299c2f1SGregory Neil Shapiro 49653299c2f1SGregory Neil Shapiro /* save IP address in text from */ 4966951742c4SGregory Neil Shapiro addr = anynet_ntop(&ia6, buf6, sizeof(buf6)); 49673299c2f1SGregory Neil Shapiro if (addr != NULL) 4968951742c4SGregory Neil Shapiro (void) sm_snprintf(ip_addr, sizeof(ip_addr), 49693299c2f1SGregory Neil Shapiro "[%.*s]", 4970951742c4SGregory Neil Shapiro (int) sizeof(ip_addr) - 3, 497112ed1c7cSGregory Neil Shapiro addr); 49723299c2f1SGregory Neil Shapiro break; 49733299c2f1SGregory Neil Shapiro 49743299c2f1SGregory Neil Shapiro case AF_INET: 49753299c2f1SGregory Neil Shapiro ia = sa->sin.sin_addr; 49763299c2f1SGregory Neil Shapiro if (ia.s_addr == INADDR_ANY || 49773299c2f1SGregory Neil Shapiro ia.s_addr == INADDR_NONE) 49783299c2f1SGregory Neil Shapiro { 49793299c2f1SGregory Neil Shapiro message("WARNING: interface %s is UP with %s address", 498012ed1c7cSGregory Neil Shapiro name, inet_ntoa(ia)); 49813299c2f1SGregory Neil Shapiro continue; 49823299c2f1SGregory Neil Shapiro } 49833299c2f1SGregory Neil Shapiro 49843299c2f1SGregory Neil Shapiro /* save IP address in text from */ 4985951742c4SGregory Neil Shapiro (void) sm_snprintf(ip_addr, sizeof(ip_addr), "[%.*s]", 4986951742c4SGregory Neil Shapiro (int) sizeof(ip_addr) - 3, inet_ntoa(ia)); 49873299c2f1SGregory Neil Shapiro break; 49883299c2f1SGregory Neil Shapiro } 49893299c2f1SGregory Neil Shapiro 49903299c2f1SGregory Neil Shapiro if (*ip_addr == '\0') 49913299c2f1SGregory Neil Shapiro continue; 49923299c2f1SGregory Neil Shapiro 49933299c2f1SGregory Neil Shapiro if (!wordinclass(ip_addr, 'w')) 49943299c2f1SGregory Neil Shapiro { 49953299c2f1SGregory Neil Shapiro setclass('w', ip_addr); 49963299c2f1SGregory Neil Shapiro if (tTd(0, 4)) 499712ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s\n", ip_addr); 49983299c2f1SGregory Neil Shapiro } 49993299c2f1SGregory Neil Shapiro 50003299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS 50013299c2f1SGregory Neil Shapiro /* skip "loopback" interface "lo" */ 500212ed1c7cSGregory Neil Shapiro if (DontProbeInterfaces == DPI_SKIPLOOPBACK && 500312ed1c7cSGregory Neil Shapiro bitset(IFF_LOOPBACK, flags)) 50043299c2f1SGregory Neil Shapiro continue; 50053299c2f1SGregory Neil Shapiro # endif /* SIOCGLIFFLAGS */ 50063299c2f1SGregory Neil Shapiro (void) add_hostnames(sa); 50073299c2f1SGregory Neil Shapiro } 500812ed1c7cSGregory Neil Shapiro sm_free(buf); /* XXX */ 5009c46d91b7SGregory Neil Shapiro (void) close(s); 50103299c2f1SGregory Neil Shapiro # else /* NETINET6 && defined(SIOCGLIFCONF) */ 5011c2aa98e2SPeter Wemm # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN 5012c2aa98e2SPeter Wemm int s; 5013c2aa98e2SPeter Wemm int i; 5014c2aa98e2SPeter Wemm struct ifconf ifc; 5015c2aa98e2SPeter Wemm int numifs; 5016c2aa98e2SPeter Wemm 5017c2aa98e2SPeter Wemm s = socket(AF_INET, SOCK_DGRAM, 0); 5018c2aa98e2SPeter Wemm if (s == -1) 5019c2aa98e2SPeter Wemm return; 5020c2aa98e2SPeter Wemm 5021c2aa98e2SPeter Wemm /* get the list of known IP address from the kernel */ 5022c2aa98e2SPeter Wemm # if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN 5023c2aa98e2SPeter Wemm if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0) 5024c2aa98e2SPeter Wemm { 5025c2aa98e2SPeter Wemm /* can't get number of interfaces -- fall back */ 5026c2aa98e2SPeter Wemm if (tTd(0, 4)) 502712ed1c7cSGregory Neil Shapiro sm_dprintf("SIOCGIFNUM failed: %s\n", 502812ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 5029c2aa98e2SPeter Wemm numifs = -1; 5030c2aa98e2SPeter Wemm } 5031c2aa98e2SPeter Wemm else if (tTd(0, 42)) 503212ed1c7cSGregory Neil Shapiro sm_dprintf("system has %d interfaces\n", numifs); 5033c2aa98e2SPeter Wemm if (numifs < 0) 50343299c2f1SGregory Neil Shapiro # endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */ 50353299c2f1SGregory Neil Shapiro numifs = MAXINTERFACES; 5036c2aa98e2SPeter Wemm 5037c2aa98e2SPeter Wemm if (numifs <= 0) 5038c2aa98e2SPeter Wemm { 50393299c2f1SGregory Neil Shapiro (void) close(s); 5040c2aa98e2SPeter Wemm return; 5041c2aa98e2SPeter Wemm } 5042c2aa98e2SPeter Wemm ifc.ifc_len = numifs * sizeof(struct ifreq); 5043c2aa98e2SPeter Wemm ifc.ifc_buf = xalloc(ifc.ifc_len); 5044c2aa98e2SPeter Wemm if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) 5045c2aa98e2SPeter Wemm { 5046c2aa98e2SPeter Wemm if (tTd(0, 4)) 504712ed1c7cSGregory Neil Shapiro sm_dprintf("SIOCGIFCONF failed: %s\n", 504812ed1c7cSGregory Neil Shapiro sm_errstring(errno)); 50493299c2f1SGregory Neil Shapiro (void) close(s); 5050c2aa98e2SPeter Wemm return; 5051c2aa98e2SPeter Wemm } 5052c2aa98e2SPeter Wemm 5053c2aa98e2SPeter Wemm /* scan the list of IP address */ 5054c2aa98e2SPeter Wemm if (tTd(0, 40)) 505512ed1c7cSGregory Neil Shapiro sm_dprintf("scanning for interface specific names, ifc_len=%d\n", 5056c2aa98e2SPeter Wemm ifc.ifc_len); 5057c2aa98e2SPeter Wemm 505812ed1c7cSGregory Neil Shapiro for (i = 0; i < ifc.ifc_len && i >= 0; ) 5059c2aa98e2SPeter Wemm { 50603299c2f1SGregory Neil Shapiro int af; 5061c2aa98e2SPeter Wemm struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i]; 506276b7bf71SPeter Wemm SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr; 50633299c2f1SGregory Neil Shapiro # if NETINET6 50643299c2f1SGregory Neil Shapiro char *addr; 50653299c2f1SGregory Neil Shapiro struct in6_addr ia6; 50663299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 5067c2aa98e2SPeter Wemm struct in_addr ia; 5068c2aa98e2SPeter Wemm # ifdef SIOCGIFFLAGS 5069c2aa98e2SPeter Wemm struct ifreq ifrf; 50703299c2f1SGregory Neil Shapiro # endif /* SIOCGIFFLAGS */ 5071c2aa98e2SPeter Wemm char ip_addr[256]; 50723299c2f1SGregory Neil Shapiro # if NETINET6 50733299c2f1SGregory Neil Shapiro char buf6[INET6_ADDRSTRLEN]; 50743299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 50753299c2f1SGregory Neil Shapiro 50763299c2f1SGregory Neil Shapiro /* 50773299c2f1SGregory Neil Shapiro ** If we don't have a complete ifr structure, 50783299c2f1SGregory Neil Shapiro ** don't try to use it. 50793299c2f1SGregory Neil Shapiro */ 50803299c2f1SGregory Neil Shapiro 5081951742c4SGregory Neil Shapiro if ((ifc.ifc_len - i) < sizeof(*ifr)) 50823299c2f1SGregory Neil Shapiro break; 5083c2aa98e2SPeter Wemm 5084c2aa98e2SPeter Wemm # ifdef BSD4_4_SOCKADDR 5085951742c4SGregory Neil Shapiro if (sa->sa.sa_len > sizeof(ifr->ifr_addr)) 5086951742c4SGregory Neil Shapiro i += sizeof(ifr->ifr_name) + sa->sa.sa_len; 5087c2aa98e2SPeter Wemm else 50883299c2f1SGregory Neil Shapiro # endif /* BSD4_4_SOCKADDR */ 5089951742c4SGregory Neil Shapiro i += sizeof(*ifr); 5090c2aa98e2SPeter Wemm 5091c2aa98e2SPeter Wemm if (tTd(0, 20)) 509212ed1c7cSGregory Neil Shapiro sm_dprintf("%s\n", anynet_ntoa(sa)); 5093c2aa98e2SPeter Wemm 50943299c2f1SGregory Neil Shapiro af = ifr->ifr_addr.sa_family; 50953299c2f1SGregory Neil Shapiro if (af != AF_INET 50963299c2f1SGregory Neil Shapiro # if NETINET6 50973299c2f1SGregory Neil Shapiro && af != AF_INET6 50983299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 50993299c2f1SGregory Neil Shapiro ) 5100c2aa98e2SPeter Wemm continue; 5101c2aa98e2SPeter Wemm 5102c2aa98e2SPeter Wemm # ifdef SIOCGIFFLAGS 51033299c2f1SGregory Neil Shapiro memset(&ifrf, '\0', sizeof(struct ifreq)); 510412ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name, 51053299c2f1SGregory Neil Shapiro sizeof(ifrf.ifr_name)); 51063299c2f1SGregory Neil Shapiro (void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf); 5107c2aa98e2SPeter Wemm if (tTd(0, 41)) 510812ed1c7cSGregory Neil Shapiro sm_dprintf("\tflags: %lx\n", 51093299c2f1SGregory Neil Shapiro (unsigned long) ifrf.ifr_flags); 5110c2aa98e2SPeter Wemm # define IFRFREF ifrf 51113299c2f1SGregory Neil Shapiro # else /* SIOCGIFFLAGS */ 5112c2aa98e2SPeter Wemm # define IFRFREF (*ifr) 51133299c2f1SGregory Neil Shapiro # endif /* SIOCGIFFLAGS */ 51143299c2f1SGregory Neil Shapiro 5115c2aa98e2SPeter Wemm if (!bitset(IFF_UP, IFRFREF.ifr_flags)) 5116c2aa98e2SPeter Wemm continue; 5117c2aa98e2SPeter Wemm 51183299c2f1SGregory Neil Shapiro ip_addr[0] = '\0'; 51193299c2f1SGregory Neil Shapiro 5120c2aa98e2SPeter Wemm /* extract IP address from the list*/ 51213299c2f1SGregory Neil Shapiro switch (af) 51223299c2f1SGregory Neil Shapiro { 51233299c2f1SGregory Neil Shapiro case AF_INET: 512476b7bf71SPeter Wemm ia = sa->sin.sin_addr; 51253299c2f1SGregory Neil Shapiro if (ia.s_addr == INADDR_ANY || 51263299c2f1SGregory Neil Shapiro ia.s_addr == INADDR_NONE) 5127c2aa98e2SPeter Wemm { 5128c2aa98e2SPeter Wemm message("WARNING: interface %s is UP with %s address", 5129c2aa98e2SPeter Wemm ifr->ifr_name, inet_ntoa(ia)); 5130c2aa98e2SPeter Wemm continue; 5131c2aa98e2SPeter Wemm } 5132c2aa98e2SPeter Wemm 5133c2aa98e2SPeter Wemm /* save IP address in text from */ 5134951742c4SGregory Neil Shapiro (void) sm_snprintf(ip_addr, sizeof(ip_addr), "[%.*s]", 5135951742c4SGregory Neil Shapiro (int) sizeof(ip_addr) - 3, 5136c2aa98e2SPeter Wemm inet_ntoa(ia)); 51373299c2f1SGregory Neil Shapiro break; 51383299c2f1SGregory Neil Shapiro 51393299c2f1SGregory Neil Shapiro # if NETINET6 51403299c2f1SGregory Neil Shapiro case AF_INET6: 51416f9c8e5bSGregory Neil Shapiro SETV6LOOPBACKADDRFOUND(*sa); 5142b4662009SGregory Neil Shapiro # ifdef __KAME__ 5143b4662009SGregory Neil Shapiro /* convert into proper scoped address */ 5144b4662009SGregory Neil Shapiro if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) || 5145b4662009SGregory Neil Shapiro IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) && 5146b4662009SGregory Neil Shapiro sa->sin6.sin6_scope_id == 0) 5147b4662009SGregory Neil Shapiro { 5148b4662009SGregory Neil Shapiro struct in6_addr *ia6p; 5149b4662009SGregory Neil Shapiro 5150b4662009SGregory Neil Shapiro ia6p = &sa->sin6.sin6_addr; 5151b4662009SGregory Neil Shapiro sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] | 5152b4662009SGregory Neil Shapiro ((unsigned int)ia6p->s6_addr[2] << 8)); 5153b4662009SGregory Neil Shapiro ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0; 5154b4662009SGregory Neil Shapiro } 5155b4662009SGregory Neil Shapiro # endif /* __KAME__ */ 51563299c2f1SGregory Neil Shapiro ia6 = sa->sin6.sin6_addr; 5157c46d91b7SGregory Neil Shapiro if (IN6_IS_ADDR_UNSPECIFIED(&ia6)) 51583299c2f1SGregory Neil Shapiro { 5159951742c4SGregory Neil Shapiro addr = anynet_ntop(&ia6, buf6, sizeof(buf6)); 51603299c2f1SGregory Neil Shapiro message("WARNING: interface %s is UP with %s address", 51613299c2f1SGregory Neil Shapiro ifr->ifr_name, 51623299c2f1SGregory Neil Shapiro addr == NULL ? "(NULL)" : addr); 51633299c2f1SGregory Neil Shapiro continue; 51643299c2f1SGregory Neil Shapiro } 51653299c2f1SGregory Neil Shapiro 51663299c2f1SGregory Neil Shapiro /* save IP address in text from */ 5167951742c4SGregory Neil Shapiro addr = anynet_ntop(&ia6, buf6, sizeof(buf6)); 51683299c2f1SGregory Neil Shapiro if (addr != NULL) 5169951742c4SGregory Neil Shapiro (void) sm_snprintf(ip_addr, sizeof(ip_addr), 51703299c2f1SGregory Neil Shapiro "[%.*s]", 5171951742c4SGregory Neil Shapiro (int) sizeof(ip_addr) - 3, 517212ed1c7cSGregory Neil Shapiro addr); 51733299c2f1SGregory Neil Shapiro break; 51743299c2f1SGregory Neil Shapiro 51753299c2f1SGregory Neil Shapiro # endif /* NETINET6 */ 51763299c2f1SGregory Neil Shapiro } 51773299c2f1SGregory Neil Shapiro 51783299c2f1SGregory Neil Shapiro if (ip_addr[0] == '\0') 51793299c2f1SGregory Neil Shapiro continue; 51803299c2f1SGregory Neil Shapiro 5181c2aa98e2SPeter Wemm if (!wordinclass(ip_addr, 'w')) 5182c2aa98e2SPeter Wemm { 5183c2aa98e2SPeter Wemm setclass('w', ip_addr); 5184c2aa98e2SPeter Wemm if (tTd(0, 4)) 518512ed1c7cSGregory Neil Shapiro sm_dprintf("\ta.k.a.: %s\n", ip_addr); 5186c2aa98e2SPeter Wemm } 5187c2aa98e2SPeter Wemm 5188c2aa98e2SPeter Wemm /* skip "loopback" interface "lo" */ 518912ed1c7cSGregory Neil Shapiro if (DontProbeInterfaces == DPI_SKIPLOOPBACK && 519012ed1c7cSGregory Neil Shapiro bitset(IFF_LOOPBACK, IFRFREF.ifr_flags)) 5191c2aa98e2SPeter Wemm continue; 5192c2aa98e2SPeter Wemm 519376b7bf71SPeter Wemm (void) add_hostnames(sa); 5194c2aa98e2SPeter Wemm } 519512ed1c7cSGregory Neil Shapiro sm_free(ifc.ifc_buf); /* XXX */ 51963299c2f1SGregory Neil Shapiro (void) close(s); 5197c2aa98e2SPeter Wemm # undef IFRFREF 51983299c2f1SGregory Neil Shapiro # endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */ 51993299c2f1SGregory Neil Shapiro # endif /* NETINET6 && defined(SIOCGLIFCONF) */ 52003299c2f1SGregory Neil Shapiro } 520112ed1c7cSGregory Neil Shapiro /* 52023299c2f1SGregory Neil Shapiro ** ISLOOPBACK -- is socket address in the loopback net? 52033299c2f1SGregory Neil Shapiro ** 52043299c2f1SGregory Neil Shapiro ** Parameters: 52053299c2f1SGregory Neil Shapiro ** sa -- socket address. 52063299c2f1SGregory Neil Shapiro ** 52073299c2f1SGregory Neil Shapiro ** Returns: 520812ed1c7cSGregory Neil Shapiro ** true -- is socket address in the loopback net? 520912ed1c7cSGregory Neil Shapiro ** false -- otherwise 52103299c2f1SGregory Neil Shapiro ** 52113299c2f1SGregory Neil Shapiro */ 52123299c2f1SGregory Neil Shapiro 52133299c2f1SGregory Neil Shapiro bool 52143299c2f1SGregory Neil Shapiro isloopback(sa) 52153299c2f1SGregory Neil Shapiro SOCKADDR sa; 52163299c2f1SGregory Neil Shapiro { 52173299c2f1SGregory Neil Shapiro #if NETINET6 52183299c2f1SGregory Neil Shapiro if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr)) 521912ed1c7cSGregory Neil Shapiro return true; 52203299c2f1SGregory Neil Shapiro #else /* NETINET6 */ 52213299c2f1SGregory Neil Shapiro /* XXX how to correctly extract IN_LOOPBACKNET part? */ 52223299c2f1SGregory Neil Shapiro if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET) 52233299c2f1SGregory Neil Shapiro >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 522412ed1c7cSGregory Neil Shapiro return true; 52253299c2f1SGregory Neil Shapiro #endif /* NETINET6 */ 522612ed1c7cSGregory Neil Shapiro return false; 5227c2aa98e2SPeter Wemm } 522812ed1c7cSGregory Neil Shapiro /* 5229c2aa98e2SPeter Wemm ** GET_NUM_PROCS_ONLINE -- return the number of processors currently online 5230c2aa98e2SPeter Wemm ** 5231c2aa98e2SPeter Wemm ** Parameters: 5232c2aa98e2SPeter Wemm ** none. 5233c2aa98e2SPeter Wemm ** 5234c2aa98e2SPeter Wemm ** Returns: 5235c2aa98e2SPeter Wemm ** The number of processors online. 5236c2aa98e2SPeter Wemm */ 5237c2aa98e2SPeter Wemm 52383299c2f1SGregory Neil Shapiro static int 5239c2aa98e2SPeter Wemm get_num_procs_online() 5240c2aa98e2SPeter Wemm { 5241c2aa98e2SPeter Wemm int nproc = 0; 5242c2aa98e2SPeter Wemm 52433299c2f1SGregory Neil Shapiro #ifdef USESYSCTL 52443299c2f1SGregory Neil Shapiro # if defined(CTL_HW) && defined(HW_NCPU) 52453299c2f1SGregory Neil Shapiro size_t sz; 52463299c2f1SGregory Neil Shapiro int mib[2]; 52473299c2f1SGregory Neil Shapiro 52483299c2f1SGregory Neil Shapiro mib[0] = CTL_HW; 52493299c2f1SGregory Neil Shapiro mib[1] = HW_NCPU; 5250951742c4SGregory Neil Shapiro sz = (size_t) sizeof(nproc); 52513299c2f1SGregory Neil Shapiro (void) sysctl(mib, 2, &nproc, &sz, NULL, 0); 525212ed1c7cSGregory Neil Shapiro # endif /* defined(CTL_HW) && defined(HW_NCPU) */ 52533299c2f1SGregory Neil Shapiro #else /* USESYSCTL */ 5254c2aa98e2SPeter Wemm # ifdef _SC_NPROCESSORS_ONLN 5255c2aa98e2SPeter Wemm nproc = (int) sysconf(_SC_NPROCESSORS_ONLN); 52563299c2f1SGregory Neil Shapiro # else /* _SC_NPROCESSORS_ONLN */ 52573299c2f1SGregory Neil Shapiro # ifdef __hpux 52583299c2f1SGregory Neil Shapiro # include <sys/pstat.h> 52593299c2f1SGregory Neil Shapiro struct pst_dynamic psd; 52603299c2f1SGregory Neil Shapiro 52613299c2f1SGregory Neil Shapiro if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1) 52623299c2f1SGregory Neil Shapiro nproc = psd.psd_proc_cnt; 52633299c2f1SGregory Neil Shapiro # endif /* __hpux */ 52643299c2f1SGregory Neil Shapiro # endif /* _SC_NPROCESSORS_ONLN */ 52653299c2f1SGregory Neil Shapiro #endif /* USESYSCTL */ 52663299c2f1SGregory Neil Shapiro 5267c2aa98e2SPeter Wemm if (nproc <= 0) 5268c2aa98e2SPeter Wemm nproc = 1; 5269c2aa98e2SPeter Wemm return nproc; 5270c2aa98e2SPeter Wemm } 527112ed1c7cSGregory Neil Shapiro /* 5272bfb62e91SGregory Neil Shapiro ** SM_CLOSEFROM -- close file descriptors 5273bfb62e91SGregory Neil Shapiro ** 5274bfb62e91SGregory Neil Shapiro ** Parameters: 5275bfb62e91SGregory Neil Shapiro ** lowest -- first fd to close 5276bfb62e91SGregory Neil Shapiro ** highest -- last fd + 1 to close 5277bfb62e91SGregory Neil Shapiro ** 5278bfb62e91SGregory Neil Shapiro ** Returns: 5279bfb62e91SGregory Neil Shapiro ** none 5280bfb62e91SGregory Neil Shapiro */ 5281bfb62e91SGregory Neil Shapiro 5282bfb62e91SGregory Neil Shapiro void 5283bfb62e91SGregory Neil Shapiro sm_closefrom(lowest, highest) 5284bfb62e91SGregory Neil Shapiro int lowest, highest; 5285bfb62e91SGregory Neil Shapiro { 5286bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM 5287bfb62e91SGregory Neil Shapiro closefrom(lowest); 5288bfb62e91SGregory Neil Shapiro #else /* HASCLOSEFROM */ 5289bfb62e91SGregory Neil Shapiro int i; 5290bfb62e91SGregory Neil Shapiro 5291bfb62e91SGregory Neil Shapiro for (i = lowest; i < highest; i++) 5292bfb62e91SGregory Neil Shapiro (void) close(i); 5293bfb62e91SGregory Neil Shapiro #endif /* HASCLOSEFROM */ 5294bfb62e91SGregory Neil Shapiro } 5295bfb62e91SGregory Neil Shapiro #if HASFDWALK 5296bfb62e91SGregory Neil Shapiro /* 5297bfb62e91SGregory Neil Shapiro ** CLOSEFD_WALK -- walk fd's arranging to close them 5298bfb62e91SGregory Neil Shapiro ** Callback for fdwalk() 5299bfb62e91SGregory Neil Shapiro ** 5300bfb62e91SGregory Neil Shapiro ** Parameters: 5301bfb62e91SGregory Neil Shapiro ** lowest -- first fd to arrange to be closed 5302bfb62e91SGregory Neil Shapiro ** fd -- fd to arrange to be closed 5303bfb62e91SGregory Neil Shapiro ** 5304bfb62e91SGregory Neil Shapiro ** Returns: 5305bfb62e91SGregory Neil Shapiro ** zero 5306bfb62e91SGregory Neil Shapiro */ 5307bfb62e91SGregory Neil Shapiro 5308bfb62e91SGregory Neil Shapiro static int 5309bfb62e91SGregory Neil Shapiro closefd_walk(lowest, fd) 5310bfb62e91SGregory Neil Shapiro void *lowest; 5311bfb62e91SGregory Neil Shapiro int fd; 5312bfb62e91SGregory Neil Shapiro { 5313bfb62e91SGregory Neil Shapiro if (fd >= *(int *)lowest) 5314bfb62e91SGregory Neil Shapiro (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 5315bfb62e91SGregory Neil Shapiro return 0; 5316bfb62e91SGregory Neil Shapiro } 5317bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */ 5318bfb62e91SGregory Neil Shapiro /* 5319bfb62e91SGregory Neil Shapiro ** SM_CLOSE_ON_EXEC -- arrange for file descriptors to be closed 5320bfb62e91SGregory Neil Shapiro ** 5321bfb62e91SGregory Neil Shapiro ** Parameters: 5322bfb62e91SGregory Neil Shapiro ** lowest -- first fd to arrange to be closed 5323bfb62e91SGregory Neil Shapiro ** highest -- last fd + 1 to arrange to be closed 5324bfb62e91SGregory Neil Shapiro ** 5325bfb62e91SGregory Neil Shapiro ** Returns: 5326bfb62e91SGregory Neil Shapiro ** none 5327bfb62e91SGregory Neil Shapiro */ 5328bfb62e91SGregory Neil Shapiro 5329bfb62e91SGregory Neil Shapiro void 53304313cc83SGregory Neil Shapiro sm_close_on_exec(lowest, highest) 53314313cc83SGregory Neil Shapiro int lowest, highest; 5332bfb62e91SGregory Neil Shapiro { 5333bfb62e91SGregory Neil Shapiro #if HASFDWALK 5334bfb62e91SGregory Neil Shapiro (void) fdwalk(closefd_walk, &lowest); 5335bfb62e91SGregory Neil Shapiro #else /* HASFDWALK */ 5336bfb62e91SGregory Neil Shapiro int i, j; 5337bfb62e91SGregory Neil Shapiro 5338bfb62e91SGregory Neil Shapiro for (i = lowest; i < highest; i++) 5339bfb62e91SGregory Neil Shapiro { 5340bfb62e91SGregory Neil Shapiro if ((j = fcntl(i, F_GETFD, 0)) != -1) 5341bfb62e91SGregory Neil Shapiro (void) fcntl(i, F_SETFD, j | FD_CLOEXEC); 5342bfb62e91SGregory Neil Shapiro } 5343bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */ 5344bfb62e91SGregory Neil Shapiro } 5345bfb62e91SGregory Neil Shapiro /* 53463299c2f1SGregory Neil Shapiro ** SEED_RANDOM -- seed the random number generator 53473299c2f1SGregory Neil Shapiro ** 53483299c2f1SGregory Neil Shapiro ** Parameters: 53493299c2f1SGregory Neil Shapiro ** none 53503299c2f1SGregory Neil Shapiro ** 53513299c2f1SGregory Neil Shapiro ** Returns: 53523299c2f1SGregory Neil Shapiro ** none 53533299c2f1SGregory Neil Shapiro */ 53543299c2f1SGregory Neil Shapiro 53553299c2f1SGregory Neil Shapiro void 53563299c2f1SGregory Neil Shapiro seed_random() 53573299c2f1SGregory Neil Shapiro { 53583299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV 53593299c2f1SGregory Neil Shapiro srandomdev(); 53603299c2f1SGregory Neil Shapiro #else /* HASSRANDOMDEV */ 53613299c2f1SGregory Neil Shapiro long seed; 53623299c2f1SGregory Neil Shapiro struct timeval t; 53633299c2f1SGregory Neil Shapiro 536412ed1c7cSGregory Neil Shapiro seed = (long) CurrentPid; 53653299c2f1SGregory Neil Shapiro if (gettimeofday(&t, NULL) >= 0) 53663299c2f1SGregory Neil Shapiro seed += t.tv_sec + t.tv_usec; 53673299c2f1SGregory Neil Shapiro 53683299c2f1SGregory Neil Shapiro # if HASRANDOM 53693299c2f1SGregory Neil Shapiro (void) srandom(seed); 53703299c2f1SGregory Neil Shapiro # else /* HASRANDOM */ 53713299c2f1SGregory Neil Shapiro (void) srand((unsigned int) seed); 53723299c2f1SGregory Neil Shapiro # endif /* HASRANDOM */ 53733299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */ 53743299c2f1SGregory Neil Shapiro } 537512ed1c7cSGregory Neil Shapiro /* 5376c2aa98e2SPeter Wemm ** SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE 5377c2aa98e2SPeter Wemm ** 5378c2aa98e2SPeter Wemm ** Parameters: 5379c2aa98e2SPeter Wemm ** level -- syslog level 5380c2aa98e2SPeter Wemm ** id -- envelope ID or NULL (NOQUEUE) 5381c2aa98e2SPeter Wemm ** fmt -- format string 5382c2aa98e2SPeter Wemm ** arg... -- arguments as implied by fmt. 5383c2aa98e2SPeter Wemm ** 5384c2aa98e2SPeter Wemm ** Returns: 5385c2aa98e2SPeter Wemm ** none 5386c2aa98e2SPeter Wemm */ 5387c2aa98e2SPeter Wemm 5388c2aa98e2SPeter Wemm /* VARARGS3 */ 5389c2aa98e2SPeter Wemm void 5390c2aa98e2SPeter Wemm #ifdef __STDC__ 5391c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...) 53923299c2f1SGregory Neil Shapiro #else /* __STDC__ */ 5393c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist) 5394c2aa98e2SPeter Wemm int level; 5395c2aa98e2SPeter Wemm const char *id; 5396c2aa98e2SPeter Wemm const char *fmt; 5397c2aa98e2SPeter Wemm va_dcl 53983299c2f1SGregory Neil Shapiro #endif /* __STDC__ */ 5399c2aa98e2SPeter Wemm { 5400567a2fc9SGregory Neil Shapiro char *buf; 5401567a2fc9SGregory Neil Shapiro size_t bufsize; 5402c2aa98e2SPeter Wemm char *begin, *end; 54033299c2f1SGregory Neil Shapiro int save_errno; 5404c2aa98e2SPeter Wemm int seq = 1; 5405c2aa98e2SPeter Wemm int idlen; 54063299c2f1SGregory Neil Shapiro char buf0[MAXLINE]; 540712ed1c7cSGregory Neil Shapiro char *newstring; 540812ed1c7cSGregory Neil Shapiro extern int SyslogPrefixLen; 540912ed1c7cSGregory Neil Shapiro SM_VA_LOCAL_DECL 5410c2aa98e2SPeter Wemm 541112ed1c7cSGregory Neil Shapiro save_errno = errno; 5412c2aa98e2SPeter Wemm if (id == NULL) 5413c2aa98e2SPeter Wemm id = "NOQUEUE"; 541412ed1c7cSGregory Neil Shapiro idlen = strlen(id) + SyslogPrefixLen; 5415c2aa98e2SPeter Wemm 54163299c2f1SGregory Neil Shapiro buf = buf0; 5417951742c4SGregory Neil Shapiro bufsize = sizeof(buf0); 54183299c2f1SGregory Neil Shapiro 54193299c2f1SGregory Neil Shapiro for (;;) 54203299c2f1SGregory Neil Shapiro { 542112ed1c7cSGregory Neil Shapiro int n; 5422c2aa98e2SPeter Wemm 542312ed1c7cSGregory Neil Shapiro /* print log message into buf */ 542412ed1c7cSGregory Neil Shapiro SM_VA_START(ap, fmt); 542512ed1c7cSGregory Neil Shapiro n = sm_vsnprintf(buf, bufsize, fmt, ap); 542612ed1c7cSGregory Neil Shapiro SM_VA_END(ap); 5427da7d7b9cSGregory Neil Shapiro SM_ASSERT(n >= 0); 542812ed1c7cSGregory Neil Shapiro if (n < bufsize) 54293299c2f1SGregory Neil Shapiro break; 54303299c2f1SGregory Neil Shapiro 5431c2aa98e2SPeter Wemm /* String too small, redo with correct size */ 543212ed1c7cSGregory Neil Shapiro bufsize = n + 1; 54333299c2f1SGregory Neil Shapiro if (buf != buf0) 543412ed1c7cSGregory Neil Shapiro { 5435c0c4794dSGregory Neil Shapiro sm_free(buf); 543612ed1c7cSGregory Neil Shapiro buf = NULL; 5437c2aa98e2SPeter Wemm } 543812ed1c7cSGregory Neil Shapiro buf = sm_malloc_x(bufsize); 543912ed1c7cSGregory Neil Shapiro } 544012ed1c7cSGregory Neil Shapiro 544112ed1c7cSGregory Neil Shapiro /* clean up buf after it has been expanded with args */ 544212ed1c7cSGregory Neil Shapiro newstring = str2prt(buf); 544312ed1c7cSGregory Neil Shapiro if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE) 5444c2aa98e2SPeter Wemm { 5445c2aa98e2SPeter Wemm #if LOG 5446c2aa98e2SPeter Wemm if (*id == '\0') 5447951742c4SGregory Neil Shapiro { 5448ba00ec3dSGregory Neil Shapiro if (tTd(89, 10)) 5449ba00ec3dSGregory Neil Shapiro { 5450ba00ec3dSGregory Neil Shapiro struct timeval tv; 5451ba00ec3dSGregory Neil Shapiro 5452ba00ec3dSGregory Neil Shapiro gettimeofday(&tv, NULL); 5453ba00ec3dSGregory Neil Shapiro sm_dprintf("%ld.%06ld %s\n", (long) tv.tv_sec, 5454ba00ec3dSGregory Neil Shapiro (long) tv.tv_usec, newstring); 5455ba00ec3dSGregory Neil Shapiro } 5456ba00ec3dSGregory Neil Shapiro else if (tTd(89, 8)) 5457951742c4SGregory Neil Shapiro sm_dprintf("%s\n", newstring); 5458951742c4SGregory Neil Shapiro else 545912ed1c7cSGregory Neil Shapiro syslog(level, "%s", newstring); 5460951742c4SGregory Neil Shapiro } 5461951742c4SGregory Neil Shapiro else 5462951742c4SGregory Neil Shapiro { 5463ba00ec3dSGregory Neil Shapiro if (tTd(89, 10)) 5464ba00ec3dSGregory Neil Shapiro { 5465ba00ec3dSGregory Neil Shapiro struct timeval tv; 5466ba00ec3dSGregory Neil Shapiro 5467ba00ec3dSGregory Neil Shapiro gettimeofday(&tv, NULL); 5468ba00ec3dSGregory Neil Shapiro sm_dprintf("%ld.%06ld %s: %s\n", (long) tv.tv_sec, 5469ba00ec3dSGregory Neil Shapiro (long) tv.tv_usec, id, newstring); 5470ba00ec3dSGregory Neil Shapiro } 5471ba00ec3dSGregory Neil Shapiro else if (tTd(89, 8)) 5472951742c4SGregory Neil Shapiro sm_dprintf("%s: %s\n", id, newstring); 5473c2aa98e2SPeter Wemm else 547412ed1c7cSGregory Neil Shapiro syslog(level, "%s: %s", id, newstring); 5475951742c4SGregory Neil Shapiro } 54763299c2f1SGregory Neil Shapiro #else /* LOG */ 5477c2aa98e2SPeter Wemm /*XXX should do something more sensible */ 5478c2aa98e2SPeter Wemm if (*id == '\0') 547912ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n", 548012ed1c7cSGregory Neil Shapiro newstring); 5481c2aa98e2SPeter Wemm else 548212ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 548312ed1c7cSGregory Neil Shapiro "%s: %s\n", id, newstring); 54843299c2f1SGregory Neil Shapiro #endif /* LOG */ 5485567a2fc9SGregory Neil Shapiro if (buf != buf0) 5486567a2fc9SGregory Neil Shapiro sm_free(buf); 54873299c2f1SGregory Neil Shapiro errno = save_errno; 5488c2aa98e2SPeter Wemm return; 5489c2aa98e2SPeter Wemm } 5490c2aa98e2SPeter Wemm 549112ed1c7cSGregory Neil Shapiro /* 549212ed1c7cSGregory Neil Shapiro ** additional length for splitting: " ..." + 3, where 3 is magic to 549312ed1c7cSGregory Neil Shapiro ** have some data for the next entry. 549412ed1c7cSGregory Neil Shapiro */ 549512ed1c7cSGregory Neil Shapiro 549612ed1c7cSGregory Neil Shapiro #define SL_SPLIT 7 549712ed1c7cSGregory Neil Shapiro 549812ed1c7cSGregory Neil Shapiro begin = newstring; 549912ed1c7cSGregory Neil Shapiro idlen += 5; /* strlen("[999]"), see below */ 5500c2aa98e2SPeter Wemm while (*begin != '\0' && 550112ed1c7cSGregory Neil Shapiro (strlen(begin) + idlen) > SYSLOG_BUFSIZE) 5502c2aa98e2SPeter Wemm { 5503c2aa98e2SPeter Wemm char save; 5504c2aa98e2SPeter Wemm 550512ed1c7cSGregory Neil Shapiro if (seq >= 999) 5506c2aa98e2SPeter Wemm { 5507c2aa98e2SPeter Wemm /* Too many messages */ 5508c2aa98e2SPeter Wemm break; 5509c2aa98e2SPeter Wemm } 551012ed1c7cSGregory Neil Shapiro end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT; 5511c2aa98e2SPeter Wemm while (end > begin) 5512c2aa98e2SPeter Wemm { 5513c2aa98e2SPeter Wemm /* Break on comma or space */ 5514c2aa98e2SPeter Wemm if (*end == ',' || *end == ' ') 5515c2aa98e2SPeter Wemm { 5516c2aa98e2SPeter Wemm end++; /* Include separator */ 5517c2aa98e2SPeter Wemm break; 5518c2aa98e2SPeter Wemm } 5519c2aa98e2SPeter Wemm end--; 5520c2aa98e2SPeter Wemm } 5521c2aa98e2SPeter Wemm /* No separator, break midstring... */ 5522c2aa98e2SPeter Wemm if (end == begin) 552312ed1c7cSGregory Neil Shapiro end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT; 5524c2aa98e2SPeter Wemm save = *end; 5525c2aa98e2SPeter Wemm *end = 0; 5526c2aa98e2SPeter Wemm #if LOG 5527951742c4SGregory Neil Shapiro if (tTd(89, 8)) 5528951742c4SGregory Neil Shapiro sm_dprintf("%s[%d]: %s ...\n", id, seq++, begin); 5529951742c4SGregory Neil Shapiro else 5530c2aa98e2SPeter Wemm syslog(level, "%s[%d]: %s ...", id, seq++, begin); 55313299c2f1SGregory Neil Shapiro #else /* LOG */ 553212ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 553312ed1c7cSGregory Neil Shapiro "%s[%d]: %s ...\n", id, seq++, begin); 55343299c2f1SGregory Neil Shapiro #endif /* LOG */ 5535c2aa98e2SPeter Wemm *end = save; 5536c2aa98e2SPeter Wemm begin = end; 5537c2aa98e2SPeter Wemm } 553812ed1c7cSGregory Neil Shapiro if (seq >= 999) 5539951742c4SGregory Neil Shapiro { 5540c2aa98e2SPeter Wemm #if LOG 5541951742c4SGregory Neil Shapiro if (tTd(89, 8)) 5542951742c4SGregory Neil Shapiro sm_dprintf("%s[%d]: log terminated, too many parts\n", 5543951742c4SGregory Neil Shapiro id, seq); 5544951742c4SGregory Neil Shapiro else 55453299c2f1SGregory Neil Shapiro syslog(level, "%s[%d]: log terminated, too many parts", 55463299c2f1SGregory Neil Shapiro id, seq); 55473299c2f1SGregory Neil Shapiro #else /* LOG */ 554812ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 554912ed1c7cSGregory Neil Shapiro "%s[%d]: log terminated, too many parts\n", id, seq); 55503299c2f1SGregory Neil Shapiro #endif /* LOG */ 5551951742c4SGregory Neil Shapiro } 5552c2aa98e2SPeter Wemm else if (*begin != '\0') 5553951742c4SGregory Neil Shapiro { 5554c2aa98e2SPeter Wemm #if LOG 5555951742c4SGregory Neil Shapiro if (tTd(89, 8)) 5556951742c4SGregory Neil Shapiro sm_dprintf("%s[%d]: %s\n", id, seq, begin); 5557951742c4SGregory Neil Shapiro else 5558c2aa98e2SPeter Wemm syslog(level, "%s[%d]: %s", id, seq, begin); 55593299c2f1SGregory Neil Shapiro #else /* LOG */ 556012ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 556112ed1c7cSGregory Neil Shapiro "%s[%d]: %s\n", id, seq, begin); 55623299c2f1SGregory Neil Shapiro #endif /* LOG */ 5563951742c4SGregory Neil Shapiro } 5564567a2fc9SGregory Neil Shapiro if (buf != buf0) 5565567a2fc9SGregory Neil Shapiro sm_free(buf); 55663299c2f1SGregory Neil Shapiro errno = save_errno; 5567c2aa98e2SPeter Wemm } 556812ed1c7cSGregory Neil Shapiro /* 5569c2aa98e2SPeter Wemm ** HARD_SYSLOG -- call syslog repeatedly until it works 5570c2aa98e2SPeter Wemm ** 5571c2aa98e2SPeter Wemm ** Needed on HP-UX, which apparently doesn't guarantee that 5572c2aa98e2SPeter Wemm ** syslog succeeds during interrupt handlers. 5573c2aa98e2SPeter Wemm */ 5574c2aa98e2SPeter Wemm 5575c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11) 5576c2aa98e2SPeter Wemm 5577c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES 100 5578c2aa98e2SPeter Wemm # undef syslog 5579c2aa98e2SPeter Wemm # ifdef V4FS 5580c2aa98e2SPeter Wemm # define XCNST const 5581c2aa98e2SPeter Wemm # define CAST (const char *) 55823299c2f1SGregory Neil Shapiro # else /* V4FS */ 5583c2aa98e2SPeter Wemm # define XCNST 5584c2aa98e2SPeter Wemm # define CAST 55853299c2f1SGregory Neil Shapiro # endif /* V4FS */ 5586c2aa98e2SPeter Wemm 5587c2aa98e2SPeter Wemm void 5588c2aa98e2SPeter Wemm # ifdef __STDC__ 5589c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...) 55903299c2f1SGregory Neil Shapiro # else /* __STDC__ */ 5591c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist) 5592c2aa98e2SPeter Wemm int pri; 5593c2aa98e2SPeter Wemm XCNST char *msg; 5594c2aa98e2SPeter Wemm va_dcl 55953299c2f1SGregory Neil Shapiro # endif /* __STDC__ */ 5596c2aa98e2SPeter Wemm { 5597c2aa98e2SPeter Wemm int i; 5598c2aa98e2SPeter Wemm char buf[SYSLOG_BUFSIZE]; 559912ed1c7cSGregory Neil Shapiro SM_VA_LOCAL_DECL 5600c2aa98e2SPeter Wemm 560112ed1c7cSGregory Neil Shapiro SM_VA_START(ap, msg); 5602951742c4SGregory Neil Shapiro (void) sm_vsnprintf(buf, sizeof(buf), msg, ap); 560312ed1c7cSGregory Neil Shapiro SM_VA_END(ap); 5604c2aa98e2SPeter Wemm 5605c2aa98e2SPeter Wemm for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; ) 5606c2aa98e2SPeter Wemm continue; 5607c2aa98e2SPeter Wemm } 5608c2aa98e2SPeter Wemm 5609c2aa98e2SPeter Wemm # undef CAST 56103299c2f1SGregory Neil Shapiro #endif /* defined(__hpux) && !defined(HPUX11) */ 56113299c2f1SGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH 561212ed1c7cSGregory Neil Shapiro /* 5613c2aa98e2SPeter Wemm ** LOCAL_HOSTNAME_LENGTH 5614c2aa98e2SPeter Wemm ** 5615c2aa98e2SPeter Wemm ** This is required to get sendmail to compile against BIND 4.9.x 5616c2aa98e2SPeter Wemm ** on Ultrix. 56173299c2f1SGregory Neil Shapiro ** 56183299c2f1SGregory Neil Shapiro ** Unfortunately, a Compaq Y2K patch kit provides it without 56193299c2f1SGregory Neil Shapiro ** bumping __RES in /usr/include/resolv.h so we can't automatically 56203299c2f1SGregory Neil Shapiro ** figure out whether it is needed. 5621c2aa98e2SPeter Wemm */ 5622c2aa98e2SPeter Wemm 5623c2aa98e2SPeter Wemm int 5624c2aa98e2SPeter Wemm local_hostname_length(hostname) 5625c2aa98e2SPeter Wemm char *hostname; 5626c2aa98e2SPeter Wemm { 562712ed1c7cSGregory Neil Shapiro size_t len_host, len_domain; 5628c2aa98e2SPeter Wemm 5629c2aa98e2SPeter Wemm if (!*_res.defdname) 5630c2aa98e2SPeter Wemm res_init(); 5631c2aa98e2SPeter Wemm len_host = strlen(hostname); 5632c2aa98e2SPeter Wemm len_domain = strlen(_res.defdname); 5633c2aa98e2SPeter Wemm if (len_host > len_domain && 563412ed1c7cSGregory Neil Shapiro (sm_strcasecmp(hostname + len_host - len_domain, 56353299c2f1SGregory Neil Shapiro _res.defdname) == 0) && 5636c2aa98e2SPeter Wemm hostname[len_host - len_domain - 1] == '.') 5637c2aa98e2SPeter Wemm return len_host - len_domain - 1; 5638c2aa98e2SPeter Wemm else 5639c2aa98e2SPeter Wemm return 0; 5640c2aa98e2SPeter Wemm } 56413299c2f1SGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */ 5642c2aa98e2SPeter Wemm 564312ed1c7cSGregory Neil Shapiro #if NEEDLINK 564412ed1c7cSGregory Neil Shapiro /* 564512ed1c7cSGregory Neil Shapiro ** LINK -- clone a file 564612ed1c7cSGregory Neil Shapiro ** 564712ed1c7cSGregory Neil Shapiro ** Some OS's lacks link() and hard links. Since sendmail is using 564812ed1c7cSGregory Neil Shapiro ** link() as an efficient way to clone files, this implementation 564912ed1c7cSGregory Neil Shapiro ** will simply do a file copy. 565012ed1c7cSGregory Neil Shapiro ** 565112ed1c7cSGregory Neil Shapiro ** NOTE: This link() replacement is not a generic replacement as it 565212ed1c7cSGregory Neil Shapiro ** does not handle all of the semantics of the real link(2). 565312ed1c7cSGregory Neil Shapiro ** 565412ed1c7cSGregory Neil Shapiro ** Parameters: 565512ed1c7cSGregory Neil Shapiro ** source -- pathname of existing file. 565612ed1c7cSGregory Neil Shapiro ** target -- pathname of link (clone) to be created. 565712ed1c7cSGregory Neil Shapiro ** 565812ed1c7cSGregory Neil Shapiro ** Returns: 565912ed1c7cSGregory Neil Shapiro ** 0 -- success. 566012ed1c7cSGregory Neil Shapiro ** -1 -- failure, see errno for details. 566112ed1c7cSGregory Neil Shapiro */ 566212ed1c7cSGregory Neil Shapiro 566312ed1c7cSGregory Neil Shapiro int 566412ed1c7cSGregory Neil Shapiro link(source, target) 566512ed1c7cSGregory Neil Shapiro const char *source; 566612ed1c7cSGregory Neil Shapiro const char *target; 566712ed1c7cSGregory Neil Shapiro { 566812ed1c7cSGregory Neil Shapiro int save_errno; 566912ed1c7cSGregory Neil Shapiro int sff; 567012ed1c7cSGregory Neil Shapiro int src = -1, dst = -1; 567112ed1c7cSGregory Neil Shapiro ssize_t readlen; 567212ed1c7cSGregory Neil Shapiro ssize_t writelen; 567312ed1c7cSGregory Neil Shapiro char buf[BUFSIZ]; 567412ed1c7cSGregory Neil Shapiro struct stat st; 567512ed1c7cSGregory Neil Shapiro 567612ed1c7cSGregory Neil Shapiro sff = SFF_REGONLY|SFF_OPENASROOT; 567712ed1c7cSGregory Neil Shapiro if (DontLockReadFiles) 567812ed1c7cSGregory Neil Shapiro sff |= SFF_NOLOCK; 567912ed1c7cSGregory Neil Shapiro 568012ed1c7cSGregory Neil Shapiro /* Open the original file */ 568112ed1c7cSGregory Neil Shapiro src = safeopen((char *)source, O_RDONLY, 0, sff); 568212ed1c7cSGregory Neil Shapiro if (src < 0) 568312ed1c7cSGregory Neil Shapiro goto fail; 568412ed1c7cSGregory Neil Shapiro 568512ed1c7cSGregory Neil Shapiro /* Obtain the size and the mode */ 568612ed1c7cSGregory Neil Shapiro if (fstat(src, &st) < 0) 568712ed1c7cSGregory Neil Shapiro goto fail; 568812ed1c7cSGregory Neil Shapiro 568912ed1c7cSGregory Neil Shapiro /* Create the duplicate copy */ 569012ed1c7cSGregory Neil Shapiro sff &= ~SFF_NOLOCK; 569112ed1c7cSGregory Neil Shapiro sff |= SFF_CREAT; 569212ed1c7cSGregory Neil Shapiro dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY, 569312ed1c7cSGregory Neil Shapiro st.st_mode, sff); 569412ed1c7cSGregory Neil Shapiro if (dst < 0) 569512ed1c7cSGregory Neil Shapiro goto fail; 569612ed1c7cSGregory Neil Shapiro 569712ed1c7cSGregory Neil Shapiro /* Copy all of the bytes one buffer at a time */ 569812ed1c7cSGregory Neil Shapiro while ((readlen = read(src, &buf, sizeof(buf))) > 0) 569912ed1c7cSGregory Neil Shapiro { 570012ed1c7cSGregory Neil Shapiro ssize_t left = readlen; 570112ed1c7cSGregory Neil Shapiro char *p = buf; 570212ed1c7cSGregory Neil Shapiro 570312ed1c7cSGregory Neil Shapiro while (left > 0 && 570412ed1c7cSGregory Neil Shapiro (writelen = write(dst, p, (size_t) left)) >= 0) 570512ed1c7cSGregory Neil Shapiro { 570612ed1c7cSGregory Neil Shapiro left -= writelen; 570712ed1c7cSGregory Neil Shapiro p += writelen; 570812ed1c7cSGregory Neil Shapiro } 5709320f00e7SGregory Neil Shapiro if (writelen < 0) 571012ed1c7cSGregory Neil Shapiro break; 571112ed1c7cSGregory Neil Shapiro } 571212ed1c7cSGregory Neil Shapiro 571312ed1c7cSGregory Neil Shapiro /* Any trouble reading? */ 571412ed1c7cSGregory Neil Shapiro if (readlen < 0 || writelen < 0) 571512ed1c7cSGregory Neil Shapiro goto fail; 571612ed1c7cSGregory Neil Shapiro 571712ed1c7cSGregory Neil Shapiro /* Close the input file */ 571812ed1c7cSGregory Neil Shapiro if (close(src) < 0) 571912ed1c7cSGregory Neil Shapiro { 572012ed1c7cSGregory Neil Shapiro src = -1; 572112ed1c7cSGregory Neil Shapiro goto fail; 572212ed1c7cSGregory Neil Shapiro } 572312ed1c7cSGregory Neil Shapiro src = -1; 572412ed1c7cSGregory Neil Shapiro 572512ed1c7cSGregory Neil Shapiro /* Close the output file */ 572612ed1c7cSGregory Neil Shapiro if (close(dst) < 0) 572712ed1c7cSGregory Neil Shapiro { 572812ed1c7cSGregory Neil Shapiro /* don't set dst = -1 here so we unlink the file */ 572912ed1c7cSGregory Neil Shapiro goto fail; 573012ed1c7cSGregory Neil Shapiro } 573112ed1c7cSGregory Neil Shapiro 573212ed1c7cSGregory Neil Shapiro /* Success */ 573312ed1c7cSGregory Neil Shapiro return 0; 573412ed1c7cSGregory Neil Shapiro 573512ed1c7cSGregory Neil Shapiro fail: 573612ed1c7cSGregory Neil Shapiro save_errno = errno; 573712ed1c7cSGregory Neil Shapiro if (src >= 0) 573812ed1c7cSGregory Neil Shapiro (void) close(src); 573912ed1c7cSGregory Neil Shapiro if (dst >= 0) 574012ed1c7cSGregory Neil Shapiro { 574112ed1c7cSGregory Neil Shapiro (void) unlink(target); 574212ed1c7cSGregory Neil Shapiro (void) close(dst); 574312ed1c7cSGregory Neil Shapiro } 574412ed1c7cSGregory Neil Shapiro errno = save_errno; 574512ed1c7cSGregory Neil Shapiro return -1; 574612ed1c7cSGregory Neil Shapiro } 574712ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */ 574812ed1c7cSGregory Neil Shapiro 574912ed1c7cSGregory Neil Shapiro /* 5750c2aa98e2SPeter Wemm ** Compile-Time options 5751c2aa98e2SPeter Wemm */ 5752c2aa98e2SPeter Wemm 5753c2aa98e2SPeter Wemm char *CompileOptions[] = 5754c2aa98e2SPeter Wemm { 5755bfb62e91SGregory Neil Shapiro #if ALLOW_255 5756bfb62e91SGregory Neil Shapiro "ALLOW_255", 5757da7d7b9cSGregory Neil Shapiro #endif 575812ed1c7cSGregory Neil Shapiro #if NAMED_BIND 575912ed1c7cSGregory Neil Shapiro # if DNSMAP 576012ed1c7cSGregory Neil Shapiro "DNSMAP", 5761da7d7b9cSGregory Neil Shapiro # endif 5762da7d7b9cSGregory Neil Shapiro #endif 5763c0c4794dSGregory Neil Shapiro #if EGD 5764c0c4794dSGregory Neil Shapiro "EGD", 5765da7d7b9cSGregory Neil Shapiro #endif 576612ed1c7cSGregory Neil Shapiro #if HESIOD 5767c2aa98e2SPeter Wemm "HESIOD", 5768da7d7b9cSGregory Neil Shapiro #endif 5769da7d7b9cSGregory Neil Shapiro #if HESIOD_ALLOW_NUMERIC_LOGIN 5770da7d7b9cSGregory Neil Shapiro "HESIOD_ALLOW_NUMERIC_LOGIN", 5771da7d7b9cSGregory Neil Shapiro #endif 5772c2aa98e2SPeter Wemm #if HES_GETMAILHOST 5773c2aa98e2SPeter Wemm "HES_GETMAILHOST", 5774da7d7b9cSGregory Neil Shapiro #endif 5775da7d7b9cSGregory Neil Shapiro #if IPV6_FULL 5776da7d7b9cSGregory Neil Shapiro /* Use uncompressed IPv6 address format (no "::") by default */ 5777da7d7b9cSGregory Neil Shapiro "IPV6_FULL", 5778da7d7b9cSGregory Neil Shapiro #endif 577912ed1c7cSGregory Neil Shapiro #if LDAPMAP 5780c2aa98e2SPeter Wemm "LDAPMAP", 5781da7d7b9cSGregory Neil Shapiro #endif 5782567a2fc9SGregory Neil Shapiro #if LDAP_REFERRALS 5783567a2fc9SGregory Neil Shapiro "LDAP_REFERRALS", 5784da7d7b9cSGregory Neil Shapiro #endif 5785c2aa98e2SPeter Wemm #if LOG 5786c2aa98e2SPeter Wemm "LOG", 5787da7d7b9cSGregory Neil Shapiro #endif 578812ed1c7cSGregory Neil Shapiro #if MAP_NSD 578912ed1c7cSGregory Neil Shapiro "MAP_NSD", 5790da7d7b9cSGregory Neil Shapiro #endif 579112ed1c7cSGregory Neil Shapiro #if MAP_REGEX 579212ed1c7cSGregory Neil Shapiro "MAP_REGEX", 5793da7d7b9cSGregory Neil Shapiro #endif 5794c2aa98e2SPeter Wemm #if MATCHGECOS 5795c2aa98e2SPeter Wemm "MATCHGECOS", 5796da7d7b9cSGregory Neil Shapiro #endif 579712ed1c7cSGregory Neil Shapiro #if MILTER 579812ed1c7cSGregory Neil Shapiro "MILTER", 5799da7d7b9cSGregory Neil Shapiro #endif 5800c2aa98e2SPeter Wemm #if MIME7TO8 5801c2aa98e2SPeter Wemm "MIME7TO8", 5802da7d7b9cSGregory Neil Shapiro #endif 58031ae5b8d4SGregory Neil Shapiro #if MIME7TO8_OLD 58041ae5b8d4SGregory Neil Shapiro "MIME7TO8_OLD", 5805da7d7b9cSGregory Neil Shapiro #endif 5806c2aa98e2SPeter Wemm #if MIME8TO7 5807c2aa98e2SPeter Wemm "MIME8TO7", 5808da7d7b9cSGregory Neil Shapiro #endif 5809c2aa98e2SPeter Wemm #if NAMED_BIND 5810c2aa98e2SPeter Wemm "NAMED_BIND", 5811da7d7b9cSGregory Neil Shapiro #endif 581212ed1c7cSGregory Neil Shapiro #if NDBM 5813c2aa98e2SPeter Wemm "NDBM", 5814da7d7b9cSGregory Neil Shapiro #endif 5815c2aa98e2SPeter Wemm #if NETINET 5816c2aa98e2SPeter Wemm "NETINET", 5817da7d7b9cSGregory Neil Shapiro #endif 58183299c2f1SGregory Neil Shapiro #if NETINET6 58193299c2f1SGregory Neil Shapiro "NETINET6", 5820da7d7b9cSGregory Neil Shapiro #endif 5821c2aa98e2SPeter Wemm #if NETINFO 5822c2aa98e2SPeter Wemm "NETINFO", 5823da7d7b9cSGregory Neil Shapiro #endif 5824c2aa98e2SPeter Wemm #if NETISO 5825c2aa98e2SPeter Wemm "NETISO", 5826da7d7b9cSGregory Neil Shapiro #endif 5827c2aa98e2SPeter Wemm #if NETNS 5828c2aa98e2SPeter Wemm "NETNS", 5829da7d7b9cSGregory Neil Shapiro #endif 5830c2aa98e2SPeter Wemm #if NETUNIX 5831c2aa98e2SPeter Wemm "NETUNIX", 5832da7d7b9cSGregory Neil Shapiro #endif 5833c2aa98e2SPeter Wemm #if NETX25 5834c2aa98e2SPeter Wemm "NETX25", 5835da7d7b9cSGregory Neil Shapiro #endif 583612ed1c7cSGregory Neil Shapiro #if NEWDB 5837c2aa98e2SPeter Wemm "NEWDB", 5838da7d7b9cSGregory Neil Shapiro #endif 583912ed1c7cSGregory Neil Shapiro #if NIS 5840c2aa98e2SPeter Wemm "NIS", 5841da7d7b9cSGregory Neil Shapiro #endif 584212ed1c7cSGregory Neil Shapiro #if NISPLUS 5843c2aa98e2SPeter Wemm "NISPLUS", 5844da7d7b9cSGregory Neil Shapiro #endif 584512ed1c7cSGregory Neil Shapiro #if NO_DH 584612ed1c7cSGregory Neil Shapiro "NO_DH", 5847da7d7b9cSGregory Neil Shapiro #endif 584812ed1c7cSGregory Neil Shapiro #if PH_MAP 58493299c2f1SGregory Neil Shapiro "PH_MAP", 5850da7d7b9cSGregory Neil Shapiro #endif 585112ed1c7cSGregory Neil Shapiro #ifdef PICKY_HELO_CHECK 585212ed1c7cSGregory Neil Shapiro "PICKY_HELO_CHECK", 5853da7d7b9cSGregory Neil Shapiro #endif 585412ed1c7cSGregory Neil Shapiro #if PIPELINING 585512ed1c7cSGregory Neil Shapiro "PIPELINING", 5856da7d7b9cSGregory Neil Shapiro #endif 58573299c2f1SGregory Neil Shapiro #if SASL 585888ad41d4SGregory Neil Shapiro # if SASL >= 20000 585988ad41d4SGregory Neil Shapiro "SASLv2", 586088ad41d4SGregory Neil Shapiro # else /* SASL >= 20000 */ 58613299c2f1SGregory Neil Shapiro "SASL", 5862da7d7b9cSGregory Neil Shapiro # endif 5863da7d7b9cSGregory Neil Shapiro #endif 5864c2aa98e2SPeter Wemm #if SCANF 5865c2aa98e2SPeter Wemm "SCANF", 5866da7d7b9cSGregory Neil Shapiro #endif 5867951742c4SGregory Neil Shapiro #if SM_LDAP_ERROR_ON_MISSING_ARGS 5868951742c4SGregory Neil Shapiro "SM_LDAP_ERROR_ON_MISSING_ARGS", 5869da7d7b9cSGregory Neil Shapiro #endif 5870c2aa98e2SPeter Wemm #if SMTPDEBUG 5871c2aa98e2SPeter Wemm "SMTPDEBUG", 5872da7d7b9cSGregory Neil Shapiro #endif 5873bfb62e91SGregory Neil Shapiro #if SOCKETMAP 5874bfb62e91SGregory Neil Shapiro "SOCKETMAP", 5875da7d7b9cSGregory Neil Shapiro #endif 58763299c2f1SGregory Neil Shapiro #if STARTTLS 58773299c2f1SGregory Neil Shapiro "STARTTLS", 5878da7d7b9cSGregory Neil Shapiro #endif 587912ed1c7cSGregory Neil Shapiro #if SUID_ROOT_FILES_OK 5880c2aa98e2SPeter Wemm "SUID_ROOT_FILES_OK", 5881da7d7b9cSGregory Neil Shapiro #endif 5882c2aa98e2SPeter Wemm #if TCPWRAPPERS 5883c2aa98e2SPeter Wemm "TCPWRAPPERS", 5884da7d7b9cSGregory Neil Shapiro #endif 588512ed1c7cSGregory Neil Shapiro #if TLS_NO_RSA 588612ed1c7cSGregory Neil Shapiro "TLS_NO_RSA", 5887da7d7b9cSGregory Neil Shapiro #endif 588812ed1c7cSGregory Neil Shapiro #if TLS_VRFY_PER_CTX 588912ed1c7cSGregory Neil Shapiro "TLS_VRFY_PER_CTX", 5890da7d7b9cSGregory Neil Shapiro #endif 5891c2aa98e2SPeter Wemm #if USERDB 5892c2aa98e2SPeter Wemm "USERDB", 5893da7d7b9cSGregory Neil Shapiro #endif 5894320f00e7SGregory Neil Shapiro #if USE_LDAP_INIT 5895320f00e7SGregory Neil Shapiro "USE_LDAP_INIT", 5896da7d7b9cSGregory Neil Shapiro #endif 5897bfb62e91SGregory Neil Shapiro #if USE_TTYPATH 5898bfb62e91SGregory Neil Shapiro "USE_TTYPATH", 5899da7d7b9cSGregory Neil Shapiro #endif 5900c2aa98e2SPeter Wemm #if XDEBUG 5901c2aa98e2SPeter Wemm "XDEBUG", 5902da7d7b9cSGregory Neil Shapiro #endif 590312ed1c7cSGregory Neil Shapiro #if XLA 5904c2aa98e2SPeter Wemm "XLA", 5905da7d7b9cSGregory Neil Shapiro #endif 5906c2aa98e2SPeter Wemm NULL 5907c2aa98e2SPeter Wemm }; 5908c2aa98e2SPeter Wemm 5909c2aa98e2SPeter Wemm 5910c2aa98e2SPeter Wemm /* 5911c2aa98e2SPeter Wemm ** OS compile options. 5912c2aa98e2SPeter Wemm */ 5913c2aa98e2SPeter Wemm 5914c2aa98e2SPeter Wemm char *OsCompileOptions[] = 5915c2aa98e2SPeter Wemm { 591612ed1c7cSGregory Neil Shapiro #if ADDRCONFIG_IS_BROKEN 591712ed1c7cSGregory Neil Shapiro "ADDRCONFIG_IS_BROKEN", 5918da7d7b9cSGregory Neil Shapiro #endif 591912ed1c7cSGregory Neil Shapiro #ifdef AUTO_NETINFO_HOSTS 592012ed1c7cSGregory Neil Shapiro "AUTO_NETINFO_HOSTS", 5921da7d7b9cSGregory Neil Shapiro #endif 592212ed1c7cSGregory Neil Shapiro #ifdef AUTO_NIS_ALIASES 592312ed1c7cSGregory Neil Shapiro "AUTO_NIS_ALIASES", 5924da7d7b9cSGregory Neil Shapiro #endif 592512ed1c7cSGregory Neil Shapiro #if BROKEN_RES_SEARCH 592612ed1c7cSGregory Neil Shapiro "BROKEN_RES_SEARCH", 5927da7d7b9cSGregory Neil Shapiro #endif 592812ed1c7cSGregory Neil Shapiro #ifdef BSD4_4_SOCKADDR 592912ed1c7cSGregory Neil Shapiro "BSD4_4_SOCKADDR", 5930da7d7b9cSGregory Neil Shapiro #endif 5931c2aa98e2SPeter Wemm #if BOGUS_O_EXCL 5932c2aa98e2SPeter Wemm "BOGUS_O_EXCL", 5933da7d7b9cSGregory Neil Shapiro #endif 593412ed1c7cSGregory Neil Shapiro #if DEC_OSF_BROKEN_GETPWENT 593512ed1c7cSGregory Neil Shapiro "DEC_OSF_BROKEN_GETPWENT", 5936da7d7b9cSGregory Neil Shapiro #endif 59373299c2f1SGregory Neil Shapiro #if FAST_PID_RECYCLE 59383299c2f1SGregory Neil Shapiro "FAST_PID_RECYCLE", 5939da7d7b9cSGregory Neil Shapiro #endif 5940bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM 5941bfb62e91SGregory Neil Shapiro "HASCLOSEFROM", 5942da7d7b9cSGregory Neil Shapiro #endif 59433299c2f1SGregory Neil Shapiro #if HASFCHOWN 59443299c2f1SGregory Neil Shapiro "HASFCHOWN", 5945da7d7b9cSGregory Neil Shapiro #endif 5946c2aa98e2SPeter Wemm #if HASFCHMOD 5947c2aa98e2SPeter Wemm "HASFCHMOD", 5948da7d7b9cSGregory Neil Shapiro #endif 5949bfb62e91SGregory Neil Shapiro #if HASFDWALK 5950bfb62e91SGregory Neil Shapiro "HASFDWALK", 5951da7d7b9cSGregory Neil Shapiro #endif 5952c2aa98e2SPeter Wemm #if HASFLOCK 5953c2aa98e2SPeter Wemm "HASFLOCK", 5954da7d7b9cSGregory Neil Shapiro #endif 5955c2aa98e2SPeter Wemm #if HASGETDTABLESIZE 5956c2aa98e2SPeter Wemm "HASGETDTABLESIZE", 5957da7d7b9cSGregory Neil Shapiro #endif 5958c2aa98e2SPeter Wemm #if HASGETUSERSHELL 5959c2aa98e2SPeter Wemm "HASGETUSERSHELL", 5960da7d7b9cSGregory Neil Shapiro #endif 5961c2aa98e2SPeter Wemm #if HASINITGROUPS 5962c2aa98e2SPeter Wemm "HASINITGROUPS", 5963da7d7b9cSGregory Neil Shapiro #endif 5964951742c4SGregory Neil Shapiro #if HASLDAPGETALIASBYNAME 5965951742c4SGregory Neil Shapiro "HASLDAPGETALIASBYNAME", 5966da7d7b9cSGregory Neil Shapiro #endif 5967c2aa98e2SPeter Wemm #if HASLSTAT 5968c2aa98e2SPeter Wemm "HASLSTAT", 5969da7d7b9cSGregory Neil Shapiro #endif 597012ed1c7cSGregory Neil Shapiro #if HASNICE 597112ed1c7cSGregory Neil Shapiro "HASNICE", 5972da7d7b9cSGregory Neil Shapiro #endif 59733299c2f1SGregory Neil Shapiro #if HASRANDOM 59743299c2f1SGregory Neil Shapiro "HASRANDOM", 5975da7d7b9cSGregory Neil Shapiro #endif 597612ed1c7cSGregory Neil Shapiro #if HASRRESVPORT 597712ed1c7cSGregory Neil Shapiro "HASRRESVPORT", 5978da7d7b9cSGregory Neil Shapiro #endif 597912ed1c7cSGregory Neil Shapiro #if HASSETEGID 598012ed1c7cSGregory Neil Shapiro "HASSETEGID", 5981da7d7b9cSGregory Neil Shapiro #endif 59823299c2f1SGregory Neil Shapiro #if HASSETLOGIN 59833299c2f1SGregory Neil Shapiro "HASSETLOGIN", 5984da7d7b9cSGregory Neil Shapiro #endif 598512ed1c7cSGregory Neil Shapiro #if HASSETREGID 598612ed1c7cSGregory Neil Shapiro "HASSETREGID", 5987da7d7b9cSGregory Neil Shapiro #endif 598812ed1c7cSGregory Neil Shapiro #if HASSETRESGID 598912ed1c7cSGregory Neil Shapiro "HASSETRESGID", 5990da7d7b9cSGregory Neil Shapiro #endif 5991c2aa98e2SPeter Wemm #if HASSETREUID 5992c2aa98e2SPeter Wemm "HASSETREUID", 5993da7d7b9cSGregory Neil Shapiro #endif 5994c2aa98e2SPeter Wemm #if HASSETRLIMIT 5995c2aa98e2SPeter Wemm "HASSETRLIMIT", 5996da7d7b9cSGregory Neil Shapiro #endif 5997c2aa98e2SPeter Wemm #if HASSETSID 5998c2aa98e2SPeter Wemm "HASSETSID", 5999da7d7b9cSGregory Neil Shapiro #endif 6000c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT 6001c2aa98e2SPeter Wemm "HASSETUSERCONTEXT", 6002da7d7b9cSGregory Neil Shapiro #endif 6003c2aa98e2SPeter Wemm #if HASSETVBUF 6004c2aa98e2SPeter Wemm "HASSETVBUF", 6005da7d7b9cSGregory Neil Shapiro #endif 6006c2aa98e2SPeter Wemm #if HAS_ST_GEN 6007c2aa98e2SPeter Wemm "HAS_ST_GEN", 6008da7d7b9cSGregory Neil Shapiro #endif 60093299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV 60103299c2f1SGregory Neil Shapiro "HASSRANDOMDEV", 6011da7d7b9cSGregory Neil Shapiro #endif 60123299c2f1SGregory Neil Shapiro #if HASURANDOMDEV 60133299c2f1SGregory Neil Shapiro "HASURANDOMDEV", 6014da7d7b9cSGregory Neil Shapiro #endif 6015c2aa98e2SPeter Wemm #if HASSTRERROR 6016c2aa98e2SPeter Wemm "HASSTRERROR", 6017da7d7b9cSGregory Neil Shapiro #endif 6018c2aa98e2SPeter Wemm #if HASULIMIT 6019c2aa98e2SPeter Wemm "HASULIMIT", 6020da7d7b9cSGregory Neil Shapiro #endif 6021c2aa98e2SPeter Wemm #if HASUNAME 6022c2aa98e2SPeter Wemm "HASUNAME", 6023da7d7b9cSGregory Neil Shapiro #endif 6024c2aa98e2SPeter Wemm #if HASUNSETENV 6025c2aa98e2SPeter Wemm "HASUNSETENV", 6026da7d7b9cSGregory Neil Shapiro #endif 6027c2aa98e2SPeter Wemm #if HASWAITPID 6028c2aa98e2SPeter Wemm "HASWAITPID", 6029da7d7b9cSGregory Neil Shapiro #endif 60306f9c8e5bSGregory Neil Shapiro #if HAVE_NANOSLEEP 60316f9c8e5bSGregory Neil Shapiro "HAVE_NANOSLEEP", 6032da7d7b9cSGregory Neil Shapiro #endif 6033c2aa98e2SPeter Wemm #if IDENTPROTO 6034c2aa98e2SPeter Wemm "IDENTPROTO", 6035da7d7b9cSGregory Neil Shapiro #endif 6036c2aa98e2SPeter Wemm #if IP_SRCROUTE 6037c2aa98e2SPeter Wemm "IP_SRCROUTE", 6038da7d7b9cSGregory Neil Shapiro #endif 6039c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL 6040c2aa98e2SPeter Wemm "LOCK_ON_OPEN", 6041da7d7b9cSGregory Neil Shapiro #endif 6042951742c4SGregory Neil Shapiro #if MILTER_NO_NAGLE 6043951742c4SGregory Neil Shapiro "MILTER_NO_NAGLE ", 6044da7d7b9cSGregory Neil Shapiro #endif 6045c2aa98e2SPeter Wemm #if NEEDFSYNC 6046c2aa98e2SPeter Wemm "NEEDFSYNC", 6047da7d7b9cSGregory Neil Shapiro #endif 604812ed1c7cSGregory Neil Shapiro #if NEEDLINK 604912ed1c7cSGregory Neil Shapiro "NEEDLINK", 6050da7d7b9cSGregory Neil Shapiro #endif 605112ed1c7cSGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH 605212ed1c7cSGregory Neil Shapiro "NEEDLOCAL_HOSTNAME_LENGTH", 6053da7d7b9cSGregory Neil Shapiro #endif 605412ed1c7cSGregory Neil Shapiro #if NEEDSGETIPNODE 605512ed1c7cSGregory Neil Shapiro "NEEDSGETIPNODE", 6056da7d7b9cSGregory Neil Shapiro #endif 605712ed1c7cSGregory Neil Shapiro #if NEEDSTRSTR 605812ed1c7cSGregory Neil Shapiro "NEEDSTRSTR", 6059da7d7b9cSGregory Neil Shapiro #endif 606012ed1c7cSGregory Neil Shapiro #if NEEDSTRTOL 606112ed1c7cSGregory Neil Shapiro "NEEDSTRTOL", 6062da7d7b9cSGregory Neil Shapiro #endif 606312ed1c7cSGregory Neil Shapiro #ifdef NO_GETSERVBYNAME 606412ed1c7cSGregory Neil Shapiro "NO_GETSERVBYNAME", 6065da7d7b9cSGregory Neil Shapiro #endif 6066c2aa98e2SPeter Wemm #if NOFTRUNCATE 6067c2aa98e2SPeter Wemm "NOFTRUNCATE", 6068da7d7b9cSGregory Neil Shapiro #endif 606912ed1c7cSGregory Neil Shapiro #if REQUIRES_DIR_FSYNC 607012ed1c7cSGregory Neil Shapiro "REQUIRES_DIR_FSYNC", 6071da7d7b9cSGregory Neil Shapiro #endif 6072c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H 6073c2aa98e2SPeter Wemm "RLIMIT_NEEDS_SYS_TIME_H", 6074da7d7b9cSGregory Neil Shapiro #endif 6075c2aa98e2SPeter Wemm #if SAFENFSPATHCONF 6076c2aa98e2SPeter Wemm "SAFENFSPATHCONF", 6077da7d7b9cSGregory Neil Shapiro #endif 6078c2aa98e2SPeter Wemm #if SECUREWARE 6079c2aa98e2SPeter Wemm "SECUREWARE", 6080da7d7b9cSGregory Neil Shapiro #endif 6081552d4955SGregory Neil Shapiro #if SFS_TYPE == SFS_4ARGS 6082552d4955SGregory Neil Shapiro "SFS_4ARGS", 6083552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_MOUNT 6084552d4955SGregory Neil Shapiro "SFS_MOUNT", 6085552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_NONE 6086552d4955SGregory Neil Shapiro "SFS_NONE", 6087552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_NT 6088552d4955SGregory Neil Shapiro "SFS_NT", 6089552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_STATFS 6090552d4955SGregory Neil Shapiro "SFS_STATFS", 6091552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_STATVFS 6092552d4955SGregory Neil Shapiro "SFS_STATVFS", 6093552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_USTAT 6094552d4955SGregory Neil Shapiro "SFS_USTAT", 6095552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_VFS 6096552d4955SGregory Neil Shapiro "SFS_VFS", 6097552d4955SGregory Neil Shapiro #endif 6098c2aa98e2SPeter Wemm #if SHARE_V1 6099c2aa98e2SPeter Wemm "SHARE_V1", 6100da7d7b9cSGregory Neil Shapiro #endif 6101c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN 6102c2aa98e2SPeter Wemm "SIOCGIFCONF_IS_BROKEN", 6103da7d7b9cSGregory Neil Shapiro #endif 6104c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN 6105c2aa98e2SPeter Wemm "SIOCGIFNUM_IS_BROKEN", 6106da7d7b9cSGregory Neil Shapiro #endif 61073299c2f1SGregory Neil Shapiro #if SNPRINTF_IS_BROKEN 61083299c2f1SGregory Neil Shapiro "SNPRINTF_IS_BROKEN", 6109da7d7b9cSGregory Neil Shapiro #endif 61103299c2f1SGregory Neil Shapiro #if SO_REUSEADDR_IS_BROKEN 61113299c2f1SGregory Neil Shapiro "SO_REUSEADDR_IS_BROKEN", 6112da7d7b9cSGregory Neil Shapiro #endif 6113c2aa98e2SPeter Wemm #if SYS5SETPGRP 6114c2aa98e2SPeter Wemm "SYS5SETPGRP", 6115da7d7b9cSGregory Neil Shapiro #endif 6116c2aa98e2SPeter Wemm #if SYSTEM5 6117c2aa98e2SPeter Wemm "SYSTEM5", 6118da7d7b9cSGregory Neil Shapiro #endif 611912ed1c7cSGregory Neil Shapiro #if USE_DOUBLE_FORK 612012ed1c7cSGregory Neil Shapiro "USE_DOUBLE_FORK", 6121da7d7b9cSGregory Neil Shapiro #endif 612212ed1c7cSGregory Neil Shapiro #if USE_ENVIRON 612312ed1c7cSGregory Neil Shapiro "USE_ENVIRON", 6124da7d7b9cSGregory Neil Shapiro #endif 6125c2aa98e2SPeter Wemm #if USE_SA_SIGACTION 6126c2aa98e2SPeter Wemm "USE_SA_SIGACTION", 6127da7d7b9cSGregory Neil Shapiro #endif 6128c2aa98e2SPeter Wemm #if USE_SIGLONGJMP 6129c2aa98e2SPeter Wemm "USE_SIGLONGJMP", 6130da7d7b9cSGregory Neil Shapiro #endif 613112ed1c7cSGregory Neil Shapiro #if USEGETCONFATTR 613212ed1c7cSGregory Neil Shapiro "USEGETCONFATTR", 6133da7d7b9cSGregory Neil Shapiro #endif 6134c2aa98e2SPeter Wemm #if USESETEUID 6135c2aa98e2SPeter Wemm "USESETEUID", 6136da7d7b9cSGregory Neil Shapiro #endif 613712ed1c7cSGregory Neil Shapiro #ifdef USESYSCTL 613812ed1c7cSGregory Neil Shapiro "USESYSCTL", 6139da7d7b9cSGregory Neil Shapiro #endif 61406f9c8e5bSGregory Neil Shapiro #if USE_OPENSSL_ENGINE 61416f9c8e5bSGregory Neil Shapiro "USE_OPENSSL_ENGINE", 6142da7d7b9cSGregory Neil Shapiro #endif 614312ed1c7cSGregory Neil Shapiro #if USING_NETSCAPE_LDAP 614412ed1c7cSGregory Neil Shapiro "USING_NETSCAPE_LDAP", 6145da7d7b9cSGregory Neil Shapiro #endif 614612ed1c7cSGregory Neil Shapiro #ifdef WAITUNION 614712ed1c7cSGregory Neil Shapiro "WAITUNION", 6148da7d7b9cSGregory Neil Shapiro #endif 614912ed1c7cSGregory Neil Shapiro NULL 615012ed1c7cSGregory Neil Shapiro }; 615112ed1c7cSGregory Neil Shapiro 615212ed1c7cSGregory Neil Shapiro /* 615312ed1c7cSGregory Neil Shapiro ** FFR compile options. 615412ed1c7cSGregory Neil Shapiro */ 615512ed1c7cSGregory Neil Shapiro 615612ed1c7cSGregory Neil Shapiro char *FFRCompileOptions[] = 615712ed1c7cSGregory Neil Shapiro { 6158da7d7b9cSGregory Neil Shapiro #if _FFR_ADD_BCC 6159da7d7b9cSGregory Neil Shapiro "_FFR_ADD_BCC", 6160da7d7b9cSGregory Neil Shapiro #endif 616141f3d2ceSGregory Neil Shapiro #if _FFR_ADDR_TYPE_MODES 616241f3d2ceSGregory Neil Shapiro /* more info in {addr_type}, requires m4 changes! */ 616341f3d2ceSGregory Neil Shapiro "_FFR_ADDR_TYPE_MODES", 6164da7d7b9cSGregory Neil Shapiro #endif 6165da7d7b9cSGregory Neil Shapiro #if _FFR_ALIAS_DETAIL 6166da7d7b9cSGregory Neil Shapiro /* try to handle +detail for aliases */ 6167da7d7b9cSGregory Neil Shapiro "_FFR_ALIAS_DETAIL", 6168da7d7b9cSGregory Neil Shapiro #endif 616912ed1c7cSGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO 617072936242SGregory Neil Shapiro /* DefaultAuthInfo can be specified by user. */ 6171bfb62e91SGregory Neil Shapiro /* DefaultAuthInfo doesn't really work in 8.13 anymore. */ 617212ed1c7cSGregory Neil Shapiro "_FFR_ALLOW_SASLINFO", 6173da7d7b9cSGregory Neil Shapiro #endif 6174e3793f76SGregory Neil Shapiro #if _FFR_BADRCPT_SHUTDOWN 6175e3793f76SGregory Neil Shapiro /* shut down connection (421) if there are too many bad RCPTs */ 6176e3793f76SGregory Neil Shapiro "_FFR_BADRCPT_SHUTDOWN", 6177da7d7b9cSGregory Neil Shapiro #endif 617812ed1c7cSGregory Neil Shapiro #if _FFR_BESTMX_BETTER_TRUNCATION 617972936242SGregory Neil Shapiro /* Better truncation of list of MX records for dns map. */ 618012ed1c7cSGregory Neil Shapiro "_FFR_BESTMX_BETTER_TRUNCATION", 6181da7d7b9cSGregory Neil Shapiro #endif 6182da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 6183da7d7b9cSGregory Neil Shapiro /* Separate, unprocessed queue for DSNs */ 6184da7d7b9cSGregory Neil Shapiro /* John Gardiner Myers of Proofpoint */ 6185da7d7b9cSGregory Neil Shapiro "_FFR_BOUNCE_QUEUE", 6186da7d7b9cSGregory Neil Shapiro #endif 618712ed1c7cSGregory Neil Shapiro #if _FFR_CATCH_BROKEN_MTAS 618872936242SGregory Neil Shapiro /* Deal with MTAs that send a reply during the DATA phase. */ 618912ed1c7cSGregory Neil Shapiro "_FFR_CATCH_BROKEN_MTAS", 6190da7d7b9cSGregory Neil Shapiro #endif 619188ad41d4SGregory Neil Shapiro #if _FFR_CHK_QUEUE 619272936242SGregory Neil Shapiro /* Stricter checks about queue directory permissions. */ 619388ad41d4SGregory Neil Shapiro "_FFR_CHK_QUEUE", 6194da7d7b9cSGregory Neil Shapiro #endif 61957660b554SGregory Neil Shapiro #if _FFR_CLIENT_SIZE 61967660b554SGregory Neil Shapiro /* Don't try to send mail if its size exceeds SIZE= of server. */ 61977660b554SGregory Neil Shapiro "_FFR_CLIENT_SIZE", 6198da7d7b9cSGregory Neil Shapiro #endif 6199bfb62e91SGregory Neil Shapiro #if _FFR_CRLPATH 6200bfb62e91SGregory Neil Shapiro /* CRLPath; needs documentation; Al Smith */ 6201bfb62e91SGregory Neil Shapiro "_FFR_CRLPATH", 6202da7d7b9cSGregory Neil Shapiro #endif 6203567a2fc9SGregory Neil Shapiro #if _FFR_DM_ONE 6204567a2fc9SGregory Neil Shapiro /* deliver first TA in background, then queue */ 6205567a2fc9SGregory Neil Shapiro "_FFR_DM_ONE", 6206da7d7b9cSGregory Neil Shapiro #endif 6207320f00e7SGregory Neil Shapiro #if _FFR_DIGUNIX_SAFECHOWN 620872936242SGregory Neil Shapiro /* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */ 6209320f00e7SGregory Neil Shapiro /* Problem noted by Anne Bennett of Concordia University */ 6210320f00e7SGregory Neil Shapiro "_FFR_DIGUNIX_SAFECHOWN", 6211da7d7b9cSGregory Neil Shapiro #endif 6212320f00e7SGregory Neil Shapiro #if _FFR_DNSMAP_ALIASABLE 621372936242SGregory Neil Shapiro /* Allow dns map type to be used for aliases. */ 6214320f00e7SGregory Neil Shapiro /* Don Lewis of TDK */ 6215320f00e7SGregory Neil Shapiro "_FFR_DNSMAP_ALIASABLE", 6216da7d7b9cSGregory Neil Shapiro #endif 621712ed1c7cSGregory Neil Shapiro #if _FFR_DONTLOCKFILESFORREAD_OPTION 621872936242SGregory Neil Shapiro /* Enable DontLockFilesForRead option. */ 621912ed1c7cSGregory Neil Shapiro "_FFR_DONTLOCKFILESFORREAD_OPTION", 6220da7d7b9cSGregory Neil Shapiro #endif 622112ed1c7cSGregory Neil Shapiro #if _FFR_DOTTED_USERNAMES 622272936242SGregory Neil Shapiro /* Allow usernames with '.' */ 622312ed1c7cSGregory Neil Shapiro "_FFR_DOTTED_USERNAMES", 6224da7d7b9cSGregory Neil Shapiro #endif 6225951742c4SGregory Neil Shapiro #if _FFR_DPO_CS 6226951742c4SGregory Neil Shapiro /* 6227951742c4SGregory Neil Shapiro ** Make DaemonPortOptions case sensitive. 6228951742c4SGregory Neil Shapiro ** For some unknown reasons the code converted every option 6229951742c4SGregory Neil Shapiro ** to uppercase (first letter only, as that's the only one that 6230951742c4SGregory Neil Shapiro ** is actually checked). This prevented all new lower case options 6231951742c4SGregory Neil Shapiro ** from working... 6232951742c4SGregory Neil Shapiro ** The documentation doesn't say anything about case (in)sensitivity, 6233951742c4SGregory Neil Shapiro ** which means it should be case sensitive by default, 6234951742c4SGregory Neil Shapiro ** but it's not a good idea to change this within a patch release, 6235951742c4SGregory Neil Shapiro ** so let's delay this to 8.15. 6236951742c4SGregory Neil Shapiro */ 6237951742c4SGregory Neil Shapiro 6238951742c4SGregory Neil Shapiro "_FFR_DPO_CS", 6239da7d7b9cSGregory Neil Shapiro #endif 624041f3d2ceSGregory Neil Shapiro #if _FFR_DPRINTF_MAP 624141f3d2ceSGregory Neil Shapiro /* dprintf map for logging */ 624241f3d2ceSGregory Neil Shapiro "_FFR_DPRINTF_MAP", 6243da7d7b9cSGregory Neil Shapiro #endif 624412ed1c7cSGregory Neil Shapiro #if _FFR_DROP_TRUSTUSER_WARNING 624572936242SGregory Neil Shapiro /* 624672936242SGregory Neil Shapiro ** Don't issue this warning: 624772936242SGregory Neil Shapiro ** "readcf: option TrustedUser may cause problems on systems 624872936242SGregory Neil Shapiro ** which do not support fchown() if UseMSP is not set. 624972936242SGregory Neil Shapiro */ 625072936242SGregory Neil Shapiro 625112ed1c7cSGregory Neil Shapiro "_FFR_DROP_TRUSTUSER_WARNING", 6252da7d7b9cSGregory Neil Shapiro #endif 6253951742c4SGregory Neil Shapiro #if _FFR_EIGHT_BIT_ADDR_OK 6254951742c4SGregory Neil Shapiro /* EightBitAddrOK: allow 8-bit e-mail addresses */ 6255951742c4SGregory Neil Shapiro "_FFR_EIGHT_BIT_ADDR_OK", 6256da7d7b9cSGregory Neil Shapiro #endif 62577660b554SGregory Neil Shapiro #if _FFR_EXTRA_MAP_CHECK 62587660b554SGregory Neil Shapiro /* perform extra checks on $( $) in R lines */ 62597660b554SGregory Neil Shapiro "_FFR_EXTRA_MAP_CHECK", 6260da7d7b9cSGregory Neil Shapiro #endif 6261951742c4SGregory Neil Shapiro #if _FFR_GETHBN_ExFILE 6262951742c4SGregory Neil Shapiro /* 6263951742c4SGregory Neil Shapiro ** According to Motonori Nakamura some gethostbyname() 6264951742c4SGregory Neil Shapiro ** implementations (TurboLinux?) may (temporarily) fail 6265da7d7b9cSGregory Neil Shapiro ** due to a lack of file descriptors. Enabling this FFR 6266951742c4SGregory Neil Shapiro ** will check errno for EMFILE and ENFILE and in case of a match 6267951742c4SGregory Neil Shapiro ** cause a temporary error instead of a permanent error. 6268951742c4SGregory Neil Shapiro ** The right solution is of course to file a bug against those 6269951742c4SGregory Neil Shapiro ** systems such that they actually set h_errno = TRY_AGAIN. 6270951742c4SGregory Neil Shapiro */ 6271951742c4SGregory Neil Shapiro 6272951742c4SGregory Neil Shapiro "_FFR_GETHBN_ExFILE", 6273da7d7b9cSGregory Neil Shapiro #endif 6274552d4955SGregory Neil Shapiro #if _FFR_FIPSMODE 6275552d4955SGregory Neil Shapiro /* FIPSMode (if supported by OpenSSL library) */ 6276552d4955SGregory Neil Shapiro "_FFR_FIPSMODE", 6277da7d7b9cSGregory Neil Shapiro #endif 627812ed1c7cSGregory Neil Shapiro #if _FFR_FIX_DASHT 627972936242SGregory Neil Shapiro /* 628072936242SGregory Neil Shapiro ** If using -t, force not sending to argv recipients, even 628172936242SGregory Neil Shapiro ** if they are mentioned in the headers. 628272936242SGregory Neil Shapiro */ 628372936242SGregory Neil Shapiro 628412ed1c7cSGregory Neil Shapiro "_FFR_FIX_DASHT", 6285da7d7b9cSGregory Neil Shapiro #endif 628612ed1c7cSGregory Neil Shapiro #if _FFR_FORWARD_SYSERR 628772936242SGregory Neil Shapiro /* Cause a "syserr" if forward file isn't "safe". */ 628812ed1c7cSGregory Neil Shapiro "_FFR_FORWARD_SYSERR", 6289da7d7b9cSGregory Neil Shapiro #endif 629012ed1c7cSGregory Neil Shapiro #if _FFR_GEN_ORCPT 629172936242SGregory Neil Shapiro /* Generate a ORCPT DSN arg if not already provided */ 629212ed1c7cSGregory Neil Shapiro "_FFR_GEN_ORCPT", 6293da7d7b9cSGregory Neil Shapiro #endif 6294320f00e7SGregory Neil Shapiro #if _FFR_HANDLE_ISO8859_GECOS 629572936242SGregory Neil Shapiro /* 629672936242SGregory Neil Shapiro ** Allow ISO 8859 characters in GECOS field: replace them 6297da7d7b9cSGregory Neil Shapiro ** with ASCII "equivalent". 629872936242SGregory Neil Shapiro */ 629972936242SGregory Neil Shapiro 6300320f00e7SGregory Neil Shapiro /* Peter Eriksson of Linkopings universitet */ 6301320f00e7SGregory Neil Shapiro "_FFR_HANDLE_ISO8859_GECOS", 6302da7d7b9cSGregory Neil Shapiro #endif 6303da7d7b9cSGregory Neil Shapiro #if _FFR_HANDLE_HDR_RW_TEMPFAIL 6304da7d7b9cSGregory Neil Shapiro /* 6305da7d7b9cSGregory Neil Shapiro ** Temporary header rewriting problems from remotename() etc 6306da7d7b9cSGregory Neil Shapiro ** are not "sticky" for mci (e.g., during queue runs). 6307da7d7b9cSGregory Neil Shapiro */ 6308da7d7b9cSGregory Neil Shapiro 6309da7d7b9cSGregory Neil Shapiro "_FFR_HANDLE_HDR_RW_TEMPFAIL", 6310da7d7b9cSGregory Neil Shapiro #endif 631112ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH 631272936242SGregory Neil Shapiro /* Use nsswitch on HP-UX */ 631312ed1c7cSGregory Neil Shapiro "_FFR_HPUX_NSSWITCH", 6314da7d7b9cSGregory Neil Shapiro #endif 63157660b554SGregory Neil Shapiro #if _FFR_IGNORE_BOGUS_ADDR 63167660b554SGregory Neil Shapiro /* Ignore addresses for which prescan() failed */ 63177660b554SGregory Neil Shapiro "_FFR_IGNORE_BOGUS_ADDR", 6318da7d7b9cSGregory Neil Shapiro #endif 631912ed1c7cSGregory Neil Shapiro #if _FFR_IGNORE_EXT_ON_HELO 632072936242SGregory Neil Shapiro /* Ignore extensions offered in response to HELO */ 632112ed1c7cSGregory Neil Shapiro "_FFR_IGNORE_EXT_ON_HELO", 6322da7d7b9cSGregory Neil Shapiro #endif 63239bd497b8SGregory Neil Shapiro #if _FFR_LINUX_MHNL 63249bd497b8SGregory Neil Shapiro /* Set MAXHOSTNAMELEN to 256 (Linux) */ 63259bd497b8SGregory Neil Shapiro "_FFR_LINUX_MHNL", 6326da7d7b9cSGregory Neil Shapiro #endif 6327e3793f76SGregory Neil Shapiro #if _FFR_LOCAL_DAEMON 6328e3793f76SGregory Neil Shapiro /* Local daemon mode (-bl) which only accepts loopback connections */ 6329e3793f76SGregory Neil Shapiro "_FFR_LOCAL_DAEMON", 6330da7d7b9cSGregory Neil Shapiro #endif 6331da7d7b9cSGregory Neil Shapiro #if _FFR_LOG_MORE1 6332da7d7b9cSGregory Neil Shapiro /* log some TLS/AUTH info in from= too */ 6333da7d7b9cSGregory Neil Shapiro "_FFR_LOG_MORE1", 6334da7d7b9cSGregory Neil Shapiro #endif 6335da7d7b9cSGregory Neil Shapiro #if _FFR_LOG_MORE2 6336da7d7b9cSGregory Neil Shapiro /* log some TLS info in to= too */ 6337da7d7b9cSGregory Neil Shapiro "_FFR_LOG_MORE2", 6338da7d7b9cSGregory Neil Shapiro #endif 6339da7d7b9cSGregory Neil Shapiro #if _FFR_LOGREPLY 6340da7d7b9cSGregory Neil Shapiro "_FFR_LOGREPLY", 6341da7d7b9cSGregory Neil Shapiro #endif 63429bd497b8SGregory Neil Shapiro #if _FFR_MAIL_MACRO 63439bd497b8SGregory Neil Shapiro "_FFR_MAIL_MACRO", 6344da7d7b9cSGregory Neil Shapiro #endif 6345bfb62e91SGregory Neil Shapiro #if _FFR_MAXDATASIZE 6346bfb62e91SGregory Neil Shapiro /* 6347bfb62e91SGregory Neil Shapiro ** It is possible that a header is larger than MILTER_CHUNK_SIZE, 6348bfb62e91SGregory Neil Shapiro ** hence this shouldn't be used as limit for milter communication. 6349bfb62e91SGregory Neil Shapiro ** see also libmilter/comm.c 6350bfb62e91SGregory Neil Shapiro ** Gurusamy Sarathy of ActiveState 6351bfb62e91SGregory Neil Shapiro */ 6352bfb62e91SGregory Neil Shapiro 6353684b2a5fSGregory Neil Shapiro "_FFR_MAXDATASIZE", 6354da7d7b9cSGregory Neil Shapiro #endif 635512ed1c7cSGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES 635672936242SGregory Neil Shapiro /* Try to limit number of .forward entries */ 635772936242SGregory Neil Shapiro /* (doesn't work) */ 635812ed1c7cSGregory Neil Shapiro /* Randall S. Winchester of the University of Maryland */ 635912ed1c7cSGregory Neil Shapiro "_FFR_MAX_FORWARD_ENTRIES", 6360da7d7b9cSGregory Neil Shapiro #endif 63617660b554SGregory Neil Shapiro #if _FFR_MAX_SLEEP_TIME 63627660b554SGregory Neil Shapiro /* Limit sleep(2) time in libsm/clock.c */ 63637660b554SGregory Neil Shapiro "_FFR_MAX_SLEEP_TIME", 6364da7d7b9cSGregory Neil Shapiro #endif 63659bd497b8SGregory Neil Shapiro #if _FFR_MDS_NEGOTIATE 63669bd497b8SGregory Neil Shapiro /* MaxDataSize negotation with libmilter */ 63679bd497b8SGregory Neil Shapiro "_FFR_MDS_NEGOTIATE", 6368da7d7b9cSGregory Neil Shapiro #endif 6369567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT 6370567a2fc9SGregory Neil Shapiro /* Check free memory */ 6371567a2fc9SGregory Neil Shapiro "_FFR_MEMSTAT", 6372da7d7b9cSGregory Neil Shapiro #endif 6373951742c4SGregory Neil Shapiro #if _FFR_MILTER_CHECK 6374951742c4SGregory Neil Shapiro "_FFR_MILTER_CHECK", 6375da7d7b9cSGregory Neil Shapiro #endif 6376da7d7b9cSGregory Neil Shapiro #if _FFR_MILTER_CONNECT_REPLYCODE 6377da7d7b9cSGregory Neil Shapiro /* milter: propagate replycode returned by connect commands */ 6378da7d7b9cSGregory Neil Shapiro /* John Gardiner Myers of Proofpoint */ 6379da7d7b9cSGregory Neil Shapiro "_FFR_MILTER_CONNECT_REPLYCODE ", 6380da7d7b9cSGregory Neil Shapiro #endif 6381951742c4SGregory Neil Shapiro #if _FFR_MILTER_CONVERT_ALL_LF_TO_CRLF 6382951742c4SGregory Neil Shapiro /* 6383951742c4SGregory Neil Shapiro ** milter_body() uses the same conversion algorithm as putbody() 6384951742c4SGregory Neil Shapiro ** to translate the "local" df format (\n) to SMTP format (\r\n). 6385951742c4SGregory Neil Shapiro ** However, putbody() and mime8to7() use different conversion 6386951742c4SGregory Neil Shapiro ** algorithms. 6387951742c4SGregory Neil Shapiro ** If the input date does not follow the SMTP standard 6388951742c4SGregory Neil Shapiro ** (e.g., if it has "naked \r"s), then the output from putbody() 6389951742c4SGregory Neil Shapiro ** and mime8to7() will most likely be different. 6390951742c4SGregory Neil Shapiro ** By turning on this FFR milter_body() will try to "imitate" 6391951742c4SGregory Neil Shapiro ** mime8to7(). 6392951742c4SGregory Neil Shapiro ** Note: there is no (simple) way to deal with both conversions 6393951742c4SGregory Neil Shapiro ** in a consistent manner. Moreover, as the "GiGo" principle applies, 6394951742c4SGregory Neil Shapiro ** it's not really worth to fix it. 6395951742c4SGregory Neil Shapiro */ 6396951742c4SGregory Neil Shapiro 6397951742c4SGregory Neil Shapiro "_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF", 6398da7d7b9cSGregory Neil Shapiro #endif 6399951742c4SGregory Neil Shapiro #if _FFR_MILTER_CHECK_REJECTIONS_TOO 6400951742c4SGregory Neil Shapiro /* 6401951742c4SGregory Neil Shapiro ** Also send RCPTs that are rejected by check_rcpt to a milter 6402951742c4SGregory Neil Shapiro ** (if requested during option negotiation). 6403951742c4SGregory Neil Shapiro */ 6404951742c4SGregory Neil Shapiro 6405951742c4SGregory Neil Shapiro "_FFR_MILTER_CHECK_REJECTIONS_TOO", 6406da7d7b9cSGregory Neil Shapiro #endif 64079bd497b8SGregory Neil Shapiro #if _FFR_MILTER_ENHSC 64089bd497b8SGregory Neil Shapiro /* extract enhanced status code from milter replies for dsn= logging */ 64099bd497b8SGregory Neil Shapiro "_FFR_MILTER_ENHSC", 6410da7d7b9cSGregory Neil Shapiro #endif 6411bfb62e91SGregory Neil Shapiro #if _FFR_MIME7TO8_OLD 6412bfb62e91SGregory Neil Shapiro /* Old mime7to8 code, the new is broken for at least one example. */ 6413bfb62e91SGregory Neil Shapiro "_FFR_MIME7TO8_OLD", 6414da7d7b9cSGregory Neil Shapiro #endif 641541f3d2ceSGregory Neil Shapiro #if _FFR_MORE_MACROS 641641f3d2ceSGregory Neil Shapiro /* allow more long macro names ("unprintable" characters). */ 641741f3d2ceSGregory Neil Shapiro "_FFR_MORE_MACROS", 6418da7d7b9cSGregory Neil Shapiro #endif 6419567a2fc9SGregory Neil Shapiro #if _FFR_MSG_ACCEPT 6420567a2fc9SGregory Neil Shapiro /* allow to override "Message accepted for delivery" */ 6421567a2fc9SGregory Neil Shapiro "_FFR_MSG_ACCEPT", 6422da7d7b9cSGregory Neil Shapiro #endif 642312ed1c7cSGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD 642472936242SGregory Neil Shapiro /* Do not issue a DELAY DSN for mailers that use the hold flag. */ 642512ed1c7cSGregory Neil Shapiro /* Steven Pitzl */ 642612ed1c7cSGregory Neil Shapiro "_FFR_NODELAYDSN_ON_HOLD", 6427da7d7b9cSGregory Neil Shapiro #endif 642812ed1c7cSGregory Neil Shapiro #if _FFR_NO_PIPE 642972936242SGregory Neil Shapiro /* Disable PIPELINING, delay client if used. */ 643012ed1c7cSGregory Neil Shapiro "_FFR_NO_PIPE", 6431da7d7b9cSGregory Neil Shapiro #endif 643241f3d2ceSGregory Neil Shapiro #if _FFR_LDAP_NETWORK_TIMEOUT 643341f3d2ceSGregory Neil Shapiro /* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */ 643441f3d2ceSGregory Neil Shapiro "_FFR_LDAP_NETWORK_TIMEOUT", 6435da7d7b9cSGregory Neil Shapiro #endif 6436188b7d28SGregory Neil Shapiro #if _FFR_LOG_NTRIES 6437188b7d28SGregory Neil Shapiro /* log ntries=, from Nik Clayton of FreeBSD */ 6438188b7d28SGregory Neil Shapiro "_FFR_LOG_NTRIES", 6439da7d7b9cSGregory Neil Shapiro #endif 6440da7d7b9cSGregory Neil Shapiro #if _FFR_PROXY 6441da7d7b9cSGregory Neil Shapiro /* "proxy" (synchronous) delivery mode */ 6442da7d7b9cSGregory Neil Shapiro "_FFR_PROXY", 6443da7d7b9cSGregory Neil Shapiro #endif 6444951742c4SGregory Neil Shapiro #if _FFR_QF_PARANOIA 6445951742c4SGregory Neil Shapiro "_FFR_QF_PARANOIA", 6446da7d7b9cSGregory Neil Shapiro #endif 6447320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_GROUP_SORTORDER 644872936242SGregory Neil Shapiro /* Allow QueueSortOrder per queue group. */ 6449320f00e7SGregory Neil Shapiro /* XXX: Still need to actually use qgrp->qg_sortorder */ 6450320f00e7SGregory Neil Shapiro "_FFR_QUEUE_GROUP_SORTORDER", 6451da7d7b9cSGregory Neil Shapiro #endif 645212ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_MACRO 645372936242SGregory Neil Shapiro /* Define {queue} macro. */ 645412ed1c7cSGregory Neil Shapiro "_FFR_QUEUE_MACRO", 6455da7d7b9cSGregory Neil Shapiro #endif 6456320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_RUN_PARANOIA 6457567a2fc9SGregory Neil Shapiro /* Additional checks when doing queue runs; interval of checks */ 6458320f00e7SGregory Neil Shapiro "_FFR_QUEUE_RUN_PARANOIA", 6459da7d7b9cSGregory Neil Shapiro #endif 646012ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_SCHED_DBG 646172936242SGregory Neil Shapiro /* Debug output for the queue scheduler. */ 646212ed1c7cSGregory Neil Shapiro "_FFR_QUEUE_SCHED_DBG", 6463da7d7b9cSGregory Neil Shapiro #endif 6464da7d7b9cSGregory Neil Shapiro #if _FFR_RCPTFLAGS 6465da7d7b9cSGregory Neil Shapiro "_FFR_RCPTFLAGS", 6466da7d7b9cSGregory Neil Shapiro #endif 64679bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY 64689bd497b8SGregory Neil Shapiro /* configurable delay for BadRcptThrottle */ 64696f9c8e5bSGregory Neil Shapiro "_FFR_RCPTTHROTDELAY", 6470da7d7b9cSGregory Neil Shapiro #endif 647112ed1c7cSGregory Neil Shapiro #if _FFR_REDIRECTEMPTY 647272936242SGregory Neil Shapiro /* 647372936242SGregory Neil Shapiro ** envelope <> can't be sent to mailing lists, only owner- 647472936242SGregory Neil Shapiro ** send spam of this type to owner- of the list 647572936242SGregory Neil Shapiro ** ---- to stop spam from going to mailing lists. 647672936242SGregory Neil Shapiro */ 647772936242SGregory Neil Shapiro 647812ed1c7cSGregory Neil Shapiro "_FFR_REDIRECTEMPTY", 6479da7d7b9cSGregory Neil Shapiro #endif 6480552d4955SGregory Neil Shapiro #if _FFR_REJECT_NUL_BYTE 6481552d4955SGregory Neil Shapiro /* reject NUL bytes in body */ 6482552d4955SGregory Neil Shapiro "_FFR_REJECT_NUL_BYTE", 6483da7d7b9cSGregory Neil Shapiro #endif 648412ed1c7cSGregory Neil Shapiro #if _FFR_RESET_MACRO_GLOBALS 648572936242SGregory Neil Shapiro /* Allow macro 'j' to be set dynamically via rulesets. */ 648612ed1c7cSGregory Neil Shapiro "_FFR_RESET_MACRO_GLOBALS", 6487da7d7b9cSGregory Neil Shapiro #endif 648812ed1c7cSGregory Neil Shapiro #if _FFR_RHS 648972936242SGregory Neil Shapiro /* Random shuffle for queue sorting. */ 649012ed1c7cSGregory Neil Shapiro "_FFR_RHS", 6491da7d7b9cSGregory Neil Shapiro #endif 649241f3d2ceSGregory Neil Shapiro #if _FFR_RUNPQG 649341f3d2ceSGregory Neil Shapiro /* 649441f3d2ceSGregory Neil Shapiro ** allow -qGqueue_group -qp to work, i.e., 649541f3d2ceSGregory Neil Shapiro ** restrict a persistent queue runner to a queue group. 649641f3d2ceSGregory Neil Shapiro */ 649741f3d2ceSGregory Neil Shapiro 649841f3d2ceSGregory Neil Shapiro "_FFR_RUNPQG", 6499da7d7b9cSGregory Neil Shapiro #endif 650041f3d2ceSGregory Neil Shapiro #if _FFR_SESSID 650141f3d2ceSGregory Neil Shapiro /* session id (for logging) */ 650241f3d2ceSGregory Neil Shapiro "_FFR_SESSID", 6503da7d7b9cSGregory Neil Shapiro #endif 650412ed1c7cSGregory Neil Shapiro #if _FFR_SHM_STATUS 650572936242SGregory Neil Shapiro /* Donated code (unused). */ 650612ed1c7cSGregory Neil Shapiro "_FFR_SHM_STATUS", 6507da7d7b9cSGregory Neil Shapiro #endif 6508567a2fc9SGregory Neil Shapiro #if _FFR_LDAP_SINGLEDN 6509567a2fc9SGregory Neil Shapiro /* 6510567a2fc9SGregory Neil Shapiro ** The LDAP database map code in Sendmail 8.12.10, when 6511567a2fc9SGregory Neil Shapiro ** given the -1 switch, would match only a single DN, 6512567a2fc9SGregory Neil Shapiro ** but was able to return multiple attributes for that 6513567a2fc9SGregory Neil Shapiro ** DN. In Sendmail 8.13 this "bug" was corrected to 6514567a2fc9SGregory Neil Shapiro ** only return if exactly one attribute matched. 6515567a2fc9SGregory Neil Shapiro ** 6516567a2fc9SGregory Neil Shapiro ** Unfortunately, our configuration uses the former 6517567a2fc9SGregory Neil Shapiro ** behaviour. Attached is a relatively simple patch 6518567a2fc9SGregory Neil Shapiro ** to 8.13.4 which adds a -2 switch (for lack of a 6519567a2fc9SGregory Neil Shapiro ** better option) which returns the single dn/multiple 6520567a2fc9SGregory Neil Shapiro ** attributes. 6521567a2fc9SGregory Neil Shapiro ** 6522567a2fc9SGregory Neil Shapiro ** Jeffrey T. Eaton, Carnegie-Mellon University 6523567a2fc9SGregory Neil Shapiro */ 6524567a2fc9SGregory Neil Shapiro 6525567a2fc9SGregory Neil Shapiro "_FFR_LDAP_SINGLEDN", 6526da7d7b9cSGregory Neil Shapiro #endif 6527bfb62e91SGregory Neil Shapiro #if _FFR_SKIP_DOMAINS 6528bfb62e91SGregory Neil Shapiro /* process every N'th domain instead of every N'th message */ 6529684b2a5fSGregory Neil Shapiro "_FFR_SKIP_DOMAINS", 6530da7d7b9cSGregory Neil Shapiro #endif 65317660b554SGregory Neil Shapiro #if _FFR_SLEEP_USE_SELECT 65327660b554SGregory Neil Shapiro /* Use select(2) in libsm/clock.c to emulate sleep(2) */ 65337660b554SGregory Neil Shapiro "_FFR_SLEEP_USE_SELECT ", 6534da7d7b9cSGregory Neil Shapiro #endif 653588ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN 653672936242SGregory Neil Shapiro /* 653772936242SGregory Neil Shapiro ** It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64 653872936242SGregory Neil Shapiro ** bit alignment, so unless each piece of argv and envp is a multiple 653972936242SGregory Neil Shapiro ** of 8 bytes (including terminating NULL), initsetproctitle() won't 654072936242SGregory Neil Shapiro ** use any of the space beyond argv[0]. Be sure to set SPT_ALIGN_SIZE 654172936242SGregory Neil Shapiro ** if you use this FFR. 654272936242SGregory Neil Shapiro */ 654372936242SGregory Neil Shapiro 654488ad41d4SGregory Neil Shapiro /* Chris Adams of HiWAAY Informations Services */ 654588ad41d4SGregory Neil Shapiro "_FFR_SPT_ALIGN", 6546da7d7b9cSGregory Neil Shapiro #endif 6547188b7d28SGregory Neil Shapiro #if _FFR_SS_PER_DAEMON 6548188b7d28SGregory Neil Shapiro /* SuperSafe per DaemonPortOptions: 'T' (better letter?) */ 6549188b7d28SGregory Neil Shapiro "_FFR_SS_PER_DAEMON", 6550da7d7b9cSGregory Neil Shapiro #endif 65519bd497b8SGregory Neil Shapiro #if _FFR_TESTS 65529bd497b8SGregory Neil Shapiro /* enable some test code */ 65539bd497b8SGregory Neil Shapiro "_FFR_TESTS", 6554da7d7b9cSGregory Neil Shapiro #endif 655512ed1c7cSGregory Neil Shapiro #if _FFR_TIMERS 655672936242SGregory Neil Shapiro /* Donated code (unused). */ 655712ed1c7cSGregory Neil Shapiro "_FFR_TIMERS", 6558da7d7b9cSGregory Neil Shapiro #endif 65595dd76dd0SGregory Neil Shapiro #if _FFR_TLS_EC 65605dd76dd0SGregory Neil Shapiro "_FFR_TLS_EC", 6561da7d7b9cSGregory Neil Shapiro #endif 6562da7d7b9cSGregory Neil Shapiro #if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE 6563da7d7b9cSGregory Neil Shapiro /* 6564da7d7b9cSGregory Neil Shapiro ** Use SSL_CTX_use_certificate_chain_file() 6565da7d7b9cSGregory Neil Shapiro ** instead of SSL_CTX_use_certificate_file() 6566da7d7b9cSGregory Neil Shapiro */ 6567da7d7b9cSGregory Neil Shapiro 6568da7d7b9cSGregory Neil Shapiro "_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE", 6569da7d7b9cSGregory Neil Shapiro #endif 6570da7d7b9cSGregory Neil Shapiro #if _FFR_TLS_SE_OPTS 6571da7d7b9cSGregory Neil Shapiro /* TLS session options */ 6572da7d7b9cSGregory Neil Shapiro "_FFR_TLS_SE_OPTS", 6573da7d7b9cSGregory Neil Shapiro #endif 657412ed1c7cSGregory Neil Shapiro #if _FFR_TRUSTED_QF 657572936242SGregory Neil Shapiro /* 657672936242SGregory Neil Shapiro ** If we don't own the file mark it as unsafe. 657772936242SGregory Neil Shapiro ** However, allow TrustedUser to own it as well 657872936242SGregory Neil Shapiro ** in case TrustedUser manipulates the queue. 657972936242SGregory Neil Shapiro */ 658072936242SGregory Neil Shapiro 658112ed1c7cSGregory Neil Shapiro "_FFR_TRUSTED_QF", 6582da7d7b9cSGregory Neil Shapiro #endif 65835dd76dd0SGregory Neil Shapiro #if _FFR_USE_GETPWNAM_ERRNO 65845dd76dd0SGregory Neil Shapiro /* 65855dd76dd0SGregory Neil Shapiro ** See libsm/mbdb.c: only enable this on OSs 65865dd76dd0SGregory Neil Shapiro ** that implement the correct (POSIX) semantics. 65874313cc83SGregory Neil Shapiro ** This will need to become an OS-specific #if enabled 65884313cc83SGregory Neil Shapiro ** in one of the headers files under include/sm/os/ . 65895dd76dd0SGregory Neil Shapiro */ 65905dd76dd0SGregory Neil Shapiro 65915dd76dd0SGregory Neil Shapiro "_FFR_USE_GETPWNAM_ERRNO", 6592da7d7b9cSGregory Neil Shapiro #endif 6593188b7d28SGregory Neil Shapiro #if _FFR_USE_SEM_LOCKING 6594188b7d28SGregory Neil Shapiro "_FFR_USE_SEM_LOCKING", 6595da7d7b9cSGregory Neil Shapiro #endif 6596320f00e7SGregory Neil Shapiro #if _FFR_USE_SETLOGIN 659772936242SGregory Neil Shapiro /* Use setlogin() */ 6598320f00e7SGregory Neil Shapiro /* Peter Philipp */ 6599320f00e7SGregory Neil Shapiro "_FFR_USE_SETLOGIN", 6600da7d7b9cSGregory Neil Shapiro #endif 6601da7d7b9cSGregory Neil Shapiro #if _FFR_XCNCT 6602da7d7b9cSGregory Neil Shapiro "_FFR_XCNCT", 6603da7d7b9cSGregory Neil Shapiro #endif 6604c2aa98e2SPeter Wemm NULL 6605c2aa98e2SPeter Wemm }; 66063299c2f1SGregory Neil Shapiro 6607