xref: /freebsd/contrib/sendmail/src/conf.c (revision 76d46bbb0efc05fa0d2250ba8b32d4c70e3f4f16)
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