xref: /freebsd/contrib/sendmail/src/conf.c (revision 188b7d28c9b437f7af143c2b61df401529416949)
1c2aa98e2SPeter Wemm /*
2188b7d28SGregory Neil Shapiro  * Copyright (c) 1998-2005 Sendmail, 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  *
127660b554SGregory Neil Shapiro  * $FreeBSD$
13c2aa98e2SPeter Wemm  */
14c2aa98e2SPeter Wemm 
1512ed1c7cSGregory Neil Shapiro #include <sendmail.h>
1612ed1c7cSGregory Neil Shapiro 
17188b7d28SGregory Neil Shapiro SM_RCSID("@(#)$Id: conf.c,v 8.1061 2005/03/07 17:18:44 ca Exp $")
18c2aa98e2SPeter Wemm 
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 
24c2aa98e2SPeter Wemm # include <sys/ioctl.h>
25c2aa98e2SPeter Wemm # include <sys/param.h>
263299c2f1SGregory Neil Shapiro 
27c2aa98e2SPeter Wemm #include <limits.h>
283299c2f1SGregory Neil Shapiro #if NETINET || NETINET6
293299c2f1SGregory Neil Shapiro # include <arpa/inet.h>
303299c2f1SGregory Neil Shapiro #endif /* NETINET || NETINET6 */
313299c2f1SGregory Neil Shapiro #if HASULIMIT && defined(HPUX11)
323299c2f1SGregory Neil Shapiro # include <ulimit.h>
333299c2f1SGregory Neil Shapiro #endif /* HASULIMIT && defined(HPUX11) */
343299c2f1SGregory Neil Shapiro 
353299c2f1SGregory Neil Shapiro static void	setupmaps __P((void));
363299c2f1SGregory Neil Shapiro static void	setupmailers __P((void));
3712ed1c7cSGregory Neil Shapiro static void	setupqueues __P((void));
383299c2f1SGregory Neil Shapiro static int	get_num_procs_online __P((void));
39684b2a5fSGregory Neil Shapiro static int	add_hostnames __P((SOCKADDR *));
40684b2a5fSGregory Neil Shapiro 
41684b2a5fSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
42684b2a5fSGregory Neil Shapiro static struct hostent *getipnodebyname __P((char *, int, int, int *));
43684b2a5fSGregory Neil Shapiro static struct hostent *getipnodebyaddr __P((char *, int, int, int *));
44684b2a5fSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */
453299c2f1SGregory Neil Shapiro 
46c2aa98e2SPeter Wemm 
47c2aa98e2SPeter Wemm /*
48c2aa98e2SPeter Wemm **  CONF.C -- Sendmail Configuration Tables.
49c2aa98e2SPeter Wemm **
50c2aa98e2SPeter Wemm **	Defines the configuration of this installation.
51c2aa98e2SPeter Wemm **
52c2aa98e2SPeter Wemm **	Configuration Variables:
53c2aa98e2SPeter Wemm **		HdrInfo -- a table describing well-known header fields.
54c2aa98e2SPeter Wemm **			Each entry has the field name and some flags,
55c2aa98e2SPeter Wemm **			which are described in sendmail.h.
56c2aa98e2SPeter Wemm **
57c2aa98e2SPeter Wemm **	Notes:
58c2aa98e2SPeter Wemm **		I have tried to put almost all the reasonable
59c2aa98e2SPeter Wemm **		configuration information into the configuration
60c2aa98e2SPeter Wemm **		file read at runtime.  My intent is that anything
61c2aa98e2SPeter Wemm **		here is a function of the version of UNIX you
62c2aa98e2SPeter Wemm **		are running, or is really static -- for example
63c2aa98e2SPeter Wemm **		the headers are a superset of widely used
64c2aa98e2SPeter Wemm **		protocols.  If you find yourself playing with
65c2aa98e2SPeter Wemm **		this file too much, you may be making a mistake!
66c2aa98e2SPeter Wemm */
67c2aa98e2SPeter Wemm 
68c2aa98e2SPeter Wemm 
69c2aa98e2SPeter Wemm /*
70c2aa98e2SPeter Wemm **  Header info table
71c2aa98e2SPeter Wemm **	Final (null) entry contains the flags used for any other field.
72c2aa98e2SPeter Wemm **
73c2aa98e2SPeter Wemm **	Not all of these are actually handled specially by sendmail
74c2aa98e2SPeter Wemm **	at this time.  They are included as placeholders, to let
75c2aa98e2SPeter Wemm **	you know that "someday" I intend to have sendmail do
76c2aa98e2SPeter Wemm **	something with them.
77c2aa98e2SPeter Wemm */
78c2aa98e2SPeter Wemm 
79c2aa98e2SPeter Wemm struct hdrinfo	HdrInfo[] =
80c2aa98e2SPeter Wemm {
81c2aa98e2SPeter Wemm 		/* originator fields, most to least significant */
823299c2f1SGregory Neil Shapiro 	{ "resent-sender",		H_FROM|H_RESENT,	NULL	},
833299c2f1SGregory Neil Shapiro 	{ "resent-from",		H_FROM|H_RESENT,	NULL	},
843299c2f1SGregory Neil Shapiro 	{ "resent-reply-to",		H_FROM|H_RESENT,	NULL	},
853299c2f1SGregory Neil Shapiro 	{ "sender",			H_FROM,			NULL	},
863299c2f1SGregory Neil Shapiro 	{ "from",			H_FROM,			NULL	},
873299c2f1SGregory Neil Shapiro 	{ "reply-to",			H_FROM,			NULL	},
883299c2f1SGregory Neil Shapiro 	{ "errors-to",			H_FROM|H_ERRORSTO,	NULL	},
893299c2f1SGregory Neil Shapiro 	{ "full-name",			H_ACHECK,		NULL	},
903299c2f1SGregory Neil Shapiro 	{ "return-receipt-to",		H_RECEIPTTO,		NULL	},
91bfb62e91SGregory Neil Shapiro 	{ "delivery-receipt-to",	H_RECEIPTTO,		NULL	},
9212ed1c7cSGregory Neil Shapiro 	{ "disposition-notification-to",	H_FROM,		NULL	},
93c2aa98e2SPeter Wemm 
94c2aa98e2SPeter Wemm 		/* destination fields */
953299c2f1SGregory Neil Shapiro 	{ "to",				H_RCPT,			NULL	},
963299c2f1SGregory Neil Shapiro 	{ "resent-to",			H_RCPT|H_RESENT,	NULL	},
973299c2f1SGregory Neil Shapiro 	{ "cc",				H_RCPT,			NULL	},
983299c2f1SGregory Neil Shapiro 	{ "resent-cc",			H_RCPT|H_RESENT,	NULL	},
993299c2f1SGregory Neil Shapiro 	{ "bcc",			H_RCPT|H_BCC,		NULL	},
1003299c2f1SGregory Neil Shapiro 	{ "resent-bcc",			H_RCPT|H_BCC|H_RESENT,	NULL	},
1013299c2f1SGregory Neil Shapiro 	{ "apparently-to",		H_RCPT,			NULL	},
102c2aa98e2SPeter Wemm 
103c2aa98e2SPeter Wemm 		/* message identification and control */
1043299c2f1SGregory Neil Shapiro 	{ "message-id",			0,			NULL	},
1053299c2f1SGregory Neil Shapiro 	{ "resent-message-id",		H_RESENT,		NULL	},
1063299c2f1SGregory Neil Shapiro 	{ "message",			H_EOH,			NULL	},
1073299c2f1SGregory Neil Shapiro 	{ "text",			H_EOH,			NULL	},
108c2aa98e2SPeter Wemm 
109c2aa98e2SPeter Wemm 		/* date fields */
1103299c2f1SGregory Neil Shapiro 	{ "date",			0,			NULL	},
1113299c2f1SGregory Neil Shapiro 	{ "resent-date",		H_RESENT,		NULL	},
112c2aa98e2SPeter Wemm 
113c2aa98e2SPeter Wemm 		/* trace fields */
1143299c2f1SGregory Neil Shapiro 	{ "received",			H_TRACE|H_FORCE,	NULL	},
1153299c2f1SGregory Neil Shapiro 	{ "x400-received",		H_TRACE|H_FORCE,	NULL	},
1163299c2f1SGregory Neil Shapiro 	{ "via",			H_TRACE|H_FORCE,	NULL	},
1173299c2f1SGregory Neil Shapiro 	{ "mail-from",			H_TRACE|H_FORCE,	NULL	},
118c2aa98e2SPeter Wemm 
119c2aa98e2SPeter Wemm 		/* miscellaneous fields */
1203299c2f1SGregory Neil Shapiro 	{ "comments",			H_FORCE|H_ENCODABLE,	NULL	},
1213299c2f1SGregory Neil Shapiro 	{ "return-path",		H_FORCE|H_ACHECK|H_BINDLATE,	NULL	},
1223299c2f1SGregory Neil Shapiro 	{ "content-transfer-encoding",	H_CTE,			NULL	},
1233299c2f1SGregory Neil Shapiro 	{ "content-type",		H_CTYPE,		NULL	},
1243299c2f1SGregory Neil Shapiro 	{ "content-length",		H_ACHECK,		NULL	},
1253299c2f1SGregory Neil Shapiro 	{ "subject",			H_ENCODABLE,		NULL	},
1263299c2f1SGregory Neil Shapiro 	{ "x-authentication-warning",	H_FORCE,		NULL	},
127c2aa98e2SPeter Wemm 
1283299c2f1SGregory Neil Shapiro 	{ NULL,				0,			NULL	}
129c2aa98e2SPeter Wemm };
130c2aa98e2SPeter Wemm 
131c2aa98e2SPeter Wemm 
132c2aa98e2SPeter Wemm 
133c2aa98e2SPeter Wemm /*
134c2aa98e2SPeter Wemm **  Privacy values
135c2aa98e2SPeter Wemm */
136c2aa98e2SPeter Wemm 
137c2aa98e2SPeter Wemm struct prival PrivacyValues[] =
138c2aa98e2SPeter Wemm {
139c2aa98e2SPeter Wemm 	{ "public",		PRIV_PUBLIC		},
140c2aa98e2SPeter Wemm 	{ "needmailhelo",	PRIV_NEEDMAILHELO	},
141c2aa98e2SPeter Wemm 	{ "needexpnhelo",	PRIV_NEEDEXPNHELO	},
142c2aa98e2SPeter Wemm 	{ "needvrfyhelo",	PRIV_NEEDVRFYHELO	},
143c2aa98e2SPeter Wemm 	{ "noexpn",		PRIV_NOEXPN		},
144c2aa98e2SPeter Wemm 	{ "novrfy",		PRIV_NOVRFY		},
14512ed1c7cSGregory Neil Shapiro 	{ "restrictexpand",	PRIV_RESTRICTEXPAND	},
146c2aa98e2SPeter Wemm 	{ "restrictmailq",	PRIV_RESTRICTMAILQ	},
147c2aa98e2SPeter Wemm 	{ "restrictqrun",	PRIV_RESTRICTQRUN	},
148c2aa98e2SPeter Wemm 	{ "noetrn",		PRIV_NOETRN		},
149c2aa98e2SPeter Wemm 	{ "noverb",		PRIV_NOVERB		},
150c2aa98e2SPeter Wemm 	{ "authwarnings",	PRIV_AUTHWARNINGS	},
151c2aa98e2SPeter Wemm 	{ "noreceipts",		PRIV_NORECEIPTS		},
1523299c2f1SGregory Neil Shapiro 	{ "nobodyreturn",	PRIV_NOBODYRETN		},
153c2aa98e2SPeter Wemm 	{ "goaway",		PRIV_GOAWAY		},
154684b2a5fSGregory Neil Shapiro #if _FFR_PRIV_NOACTUALRECIPIENT
155684b2a5fSGregory Neil Shapiro 	{ "noactualrecipient",	PRIV_NOACTUALRECIPIENT	},
156684b2a5fSGregory Neil Shapiro #endif /* _FFR_PRIV_NOACTUALRECIPIENT */
157c2aa98e2SPeter Wemm 	{ NULL,			0			}
158c2aa98e2SPeter Wemm };
159c2aa98e2SPeter Wemm 
160c2aa98e2SPeter Wemm /*
161c2aa98e2SPeter Wemm **  DontBlameSendmail values
162c2aa98e2SPeter Wemm */
16312ed1c7cSGregory Neil Shapiro 
164c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] =
165c2aa98e2SPeter Wemm {
166c2aa98e2SPeter Wemm 	{ "safe",			DBS_SAFE			},
167c2aa98e2SPeter Wemm 	{ "assumesafechown",		DBS_ASSUMESAFECHOWN		},
168c2aa98e2SPeter Wemm 	{ "groupwritabledirpathsafe",	DBS_GROUPWRITABLEDIRPATHSAFE	},
169c2aa98e2SPeter Wemm 	{ "groupwritableforwardfilesafe",
170c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEFORWARDFILESAFE },
171c2aa98e2SPeter Wemm 	{ "groupwritableincludefilesafe",
172c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEINCLUDEFILESAFE },
173c2aa98e2SPeter Wemm 	{ "groupwritablealiasfile",	DBS_GROUPWRITABLEALIASFILE	},
174c2aa98e2SPeter Wemm 	{ "worldwritablealiasfile",	DBS_WORLDWRITABLEALIASFILE	},
175c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpath",	DBS_FORWARDFILEINUNSAFEDIRPATH	},
176c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpath",	DBS_INCLUDEFILEINUNSAFEDIRPATH	},
177c2aa98e2SPeter Wemm 	{ "mapinunsafedirpath",		DBS_MAPINUNSAFEDIRPATH	},
178c2aa98e2SPeter Wemm 	{ "linkedaliasfileinwritabledir",
179c2aa98e2SPeter Wemm 					DBS_LINKEDALIASFILEINWRITABLEDIR },
180c2aa98e2SPeter Wemm 	{ "linkedclassfileinwritabledir",
181c2aa98e2SPeter Wemm 					DBS_LINKEDCLASSFILEINWRITABLEDIR },
182c2aa98e2SPeter Wemm 	{ "linkedforwardfileinwritabledir",
183c2aa98e2SPeter Wemm 					DBS_LINKEDFORWARDFILEINWRITABLEDIR },
184c2aa98e2SPeter Wemm 	{ "linkedincludefileinwritabledir",
185c2aa98e2SPeter Wemm 					DBS_LINKEDINCLUDEFILEINWRITABLEDIR },
186c2aa98e2SPeter Wemm 	{ "linkedmapinwritabledir",	DBS_LINKEDMAPINWRITABLEDIR	},
187c2aa98e2SPeter Wemm 	{ "linkedserviceswitchfileinwritabledir",
188c2aa98e2SPeter Wemm 					DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR },
189c2aa98e2SPeter Wemm 	{ "filedeliverytohardlink",	DBS_FILEDELIVERYTOHARDLINK	},
190c2aa98e2SPeter Wemm 	{ "filedeliverytosymlink",	DBS_FILEDELIVERYTOSYMLINK	},
191c2aa98e2SPeter Wemm 	{ "writemaptohardlink",		DBS_WRITEMAPTOHARDLINK		},
192c2aa98e2SPeter Wemm 	{ "writemaptosymlink",		DBS_WRITEMAPTOSYMLINK		},
193c2aa98e2SPeter Wemm 	{ "writestatstohardlink",	DBS_WRITESTATSTOHARDLINK	},
194c2aa98e2SPeter Wemm 	{ "writestatstosymlink",	DBS_WRITESTATSTOSYMLINK		},
195c2aa98e2SPeter Wemm 	{ "forwardfileingroupwritabledirpath",
196c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINGROUPWRITABLEDIRPATH },
197c2aa98e2SPeter Wemm 	{ "includefileingroupwritabledirpath",
198c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH },
199c2aa98e2SPeter Wemm 	{ "classfileinunsafedirpath",	DBS_CLASSFILEINUNSAFEDIRPATH	},
200c2aa98e2SPeter Wemm 	{ "errorheaderinunsafedirpath",	DBS_ERRORHEADERINUNSAFEDIRPATH	},
201c2aa98e2SPeter Wemm 	{ "helpfileinunsafedirpath",	DBS_HELPFILEINUNSAFEDIRPATH	},
202c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpathsafe",
203c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINUNSAFEDIRPATHSAFE },
204c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpathsafe",
205c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
206c2aa98e2SPeter Wemm 	{ "runprograminunsafedirpath",	DBS_RUNPROGRAMINUNSAFEDIRPATH	},
207c2aa98e2SPeter Wemm 	{ "runwritableprogram",		DBS_RUNWRITABLEPROGRAM		},
2083299c2f1SGregory Neil Shapiro 	{ "nonrootsafeaddr",		DBS_NONROOTSAFEADDR		},
2093299c2f1SGregory Neil Shapiro 	{ "truststickybit",		DBS_TRUSTSTICKYBIT		},
2103299c2f1SGregory Neil Shapiro 	{ "dontwarnforwardfileinunsafedirpath",
2113299c2f1SGregory Neil Shapiro 					DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH },
2123299c2f1SGregory Neil Shapiro 	{ "insufficiententropy",	DBS_INSUFFICIENTENTROPY },
21312ed1c7cSGregory Neil Shapiro 	{ "groupreadablesasldbfile",	DBS_GROUPREADABLESASLDBFILE	},
21412ed1c7cSGregory Neil Shapiro 	{ "groupwritablesasldbfile",	DBS_GROUPWRITABLESASLDBFILE	},
215d995d2baSGregory Neil Shapiro 	{ "groupwritableforwardfile",	DBS_GROUPWRITABLEFORWARDFILE	},
216d995d2baSGregory Neil Shapiro 	{ "groupwritableincludefile",	DBS_GROUPWRITABLEINCLUDEFILE	},
217d995d2baSGregory Neil Shapiro 	{ "worldwritableforwardfile",	DBS_WORLDWRITABLEFORWARDFILE	},
218d995d2baSGregory Neil Shapiro 	{ "worldwritableincludefile",	DBS_WORLDWRITABLEINCLUDEFILE	},
21912ed1c7cSGregory Neil Shapiro 	{ "groupreadablekeyfile",	DBS_GROUPREADABLEKEYFILE	},
22012ed1c7cSGregory Neil Shapiro #if _FFR_GROUPREADABLEAUTHINFOFILE
22112ed1c7cSGregory Neil Shapiro 	{ "groupreadableadefaultauthinfofile",
22212ed1c7cSGregory Neil Shapiro 					DBS_GROUPREADABLEAUTHINFOFILE	},
22312ed1c7cSGregory Neil Shapiro #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
224c2aa98e2SPeter Wemm 	{ NULL,				0				}
225c2aa98e2SPeter Wemm };
226c2aa98e2SPeter Wemm 
227c2aa98e2SPeter Wemm /*
228c2aa98e2SPeter Wemm **  Miscellaneous stuff.
229c2aa98e2SPeter Wemm */
230c2aa98e2SPeter Wemm 
231c2aa98e2SPeter Wemm int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
23212ed1c7cSGregory Neil Shapiro /*
233c2aa98e2SPeter Wemm **  SETDEFAULTS -- set default values
234c2aa98e2SPeter Wemm **
23512ed1c7cSGregory Neil Shapiro **	Some of these must be initialized using direct code since they
23612ed1c7cSGregory Neil Shapiro **	depend on run-time values. So let's do all of them this way.
237c2aa98e2SPeter Wemm **
238c2aa98e2SPeter Wemm **	Parameters:
239c2aa98e2SPeter Wemm **		e -- the default envelope.
240c2aa98e2SPeter Wemm **
241c2aa98e2SPeter Wemm **	Returns:
242c2aa98e2SPeter Wemm **		none.
243c2aa98e2SPeter Wemm **
244c2aa98e2SPeter Wemm **	Side Effects:
245c2aa98e2SPeter Wemm **		Initializes a bunch of global variables to their
246c2aa98e2SPeter Wemm **		default values.
247c2aa98e2SPeter Wemm */
248c2aa98e2SPeter Wemm 
249c2aa98e2SPeter Wemm #define MINUTES		* 60
250c2aa98e2SPeter Wemm #define HOURS		* 60 MINUTES
251c2aa98e2SPeter Wemm #define DAYS		* 24 HOURS
252c2aa98e2SPeter Wemm 
253c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION
254c2aa98e2SPeter Wemm # define MAXRULERECURSION	50	/* max ruleset recursion depth */
2553299c2f1SGregory Neil Shapiro #endif /* ! MAXRULERECURSION */
256c2aa98e2SPeter Wemm 
257c2aa98e2SPeter Wemm void
258c2aa98e2SPeter Wemm setdefaults(e)
259c2aa98e2SPeter Wemm 	register ENVELOPE *e;
260c2aa98e2SPeter Wemm {
261c2aa98e2SPeter Wemm 	int i;
2623299c2f1SGregory Neil Shapiro 	int numprocs;
263c2aa98e2SPeter Wemm 	struct passwd *pw;
264c2aa98e2SPeter Wemm 
2653299c2f1SGregory Neil Shapiro 	numprocs = get_num_procs_online();
266c2aa98e2SPeter Wemm 	SpaceSub = ' ';				/* option B */
2673299c2f1SGregory Neil Shapiro 	QueueLA = 8 * numprocs;			/* option x */
2683299c2f1SGregory Neil Shapiro 	RefuseLA = 12 * numprocs;		/* option X */
269c2aa98e2SPeter Wemm 	WkRecipFact = 30000L;			/* option y */
270c2aa98e2SPeter Wemm 	WkClassFact = 1800L;			/* option z */
271c2aa98e2SPeter Wemm 	WkTimeFact = 90000L;			/* option Z */
272c2aa98e2SPeter Wemm 	QueueFactor = WkRecipFact * 20;		/* option q */
27312ed1c7cSGregory Neil Shapiro 	QueueMode = QM_NORMAL;		/* what queue items to act upon */
274c2aa98e2SPeter Wemm 	FileMode = (RealUid != geteuid()) ? 0644 : 0600;
275c2aa98e2SPeter Wemm 						/* option F */
2763299c2f1SGregory Neil Shapiro 	QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600;
2773299c2f1SGregory Neil Shapiro 						/* option QueueFileMode */
278c2aa98e2SPeter Wemm 
2793299c2f1SGregory Neil Shapiro 	if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) ||
2803299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) ||
2813299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0))
282c2aa98e2SPeter Wemm 	{
283c2aa98e2SPeter Wemm 		DefUid = pw->pw_uid;		/* option u */
284c2aa98e2SPeter Wemm 		DefGid = pw->pw_gid;		/* option g */
285c2aa98e2SPeter Wemm 		DefUser = newstr(pw->pw_name);
286c2aa98e2SPeter Wemm 	}
287c2aa98e2SPeter Wemm 	else
288c2aa98e2SPeter Wemm 	{
289c2aa98e2SPeter Wemm 		DefUid = 1;			/* option u */
290c2aa98e2SPeter Wemm 		DefGid = 1;			/* option g */
291c2aa98e2SPeter Wemm 		setdefuser();
292c2aa98e2SPeter Wemm 	}
29376b7bf71SPeter Wemm 	TrustedUid = 0;
294c2aa98e2SPeter Wemm 	if (tTd(37, 4))
29512ed1c7cSGregory Neil Shapiro 		sm_dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n",
296c2aa98e2SPeter Wemm 			DefUser != NULL ? DefUser : "<1:1>",
297c2aa98e2SPeter Wemm 			(int) DefUid, (int) DefGid);
298c2aa98e2SPeter Wemm 	CheckpointInterval = 10;		/* option C */
299c2aa98e2SPeter Wemm 	MaxHopCount = 25;			/* option h */
3003299c2f1SGregory Neil Shapiro 	set_delivery_mode(SM_FORK, e);		/* option d */
301c2aa98e2SPeter Wemm 	e->e_errormode = EM_PRINT;		/* option e */
30212ed1c7cSGregory Neil Shapiro 	e->e_qgrp = NOQGRP;
30312ed1c7cSGregory Neil Shapiro 	e->e_qdir = NOQDIR;
30412ed1c7cSGregory Neil Shapiro 	e->e_xfqgrp = NOQGRP;
30512ed1c7cSGregory Neil Shapiro 	e->e_xfqdir = NOQDIR;
3063299c2f1SGregory Neil Shapiro 	e->e_ctime = curtime();
30712ed1c7cSGregory Neil Shapiro 	SevenBitInput = false;			/* option 7 */
308c2aa98e2SPeter Wemm 	MaxMciCache = 1;			/* option k */
309c2aa98e2SPeter Wemm 	MciCacheTimeout = 5 MINUTES;		/* option K */
310c2aa98e2SPeter Wemm 	LogLevel = 9;				/* option L */
31112ed1c7cSGregory Neil Shapiro #if MILTER
31212ed1c7cSGregory Neil Shapiro 	MilterLogLevel = -1;
31312ed1c7cSGregory Neil Shapiro #endif /* MILTER */
31412ed1c7cSGregory Neil Shapiro 	inittimeouts(NULL, false);		/* option r */
315c2aa98e2SPeter Wemm 	PrivacyFlags = PRIV_PUBLIC;		/* option p */
31612ed1c7cSGregory Neil Shapiro 	MeToo = true;				/* option m */
31712ed1c7cSGregory Neil Shapiro 	SendMIMEErrors = true;			/* option f */
31812ed1c7cSGregory Neil Shapiro 	SuperSafe = SAFE_REALLY;		/* option s */
3193299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);		/* DontBlameSendmail option */
320c2aa98e2SPeter Wemm #if MIME8TO7
321c2aa98e2SPeter Wemm 	MimeMode = MM_CVTMIME|MM_PASS8BIT;	/* option 8 */
3223299c2f1SGregory Neil Shapiro #else /* MIME8TO7 */
323c2aa98e2SPeter Wemm 	MimeMode = MM_PASS8BIT;
3243299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
325c2aa98e2SPeter Wemm 	for (i = 0; i < MAXTOCLASS; i++)
326c2aa98e2SPeter Wemm 	{
327c2aa98e2SPeter Wemm 		TimeOuts.to_q_return[i] = 5 DAYS;	/* option T */
328c2aa98e2SPeter Wemm 		TimeOuts.to_q_warning[i] = 0;		/* option T */
329c2aa98e2SPeter Wemm 	}
3303299c2f1SGregory Neil Shapiro 	ServiceSwitchFile = "/etc/mail/service.switch";
331c2aa98e2SPeter Wemm 	ServiceCacheMaxAge = (time_t) 10;
332c2aa98e2SPeter Wemm 	HostsFile = _PATH_HOSTS;
333c2aa98e2SPeter Wemm 	PidFile = newstr(_PATH_SENDMAILPID);
334c2aa98e2SPeter Wemm 	MustQuoteChars = "@,;:\\()[].'";
335c2aa98e2SPeter Wemm 	MciInfoTimeout = 30 MINUTES;
336c2aa98e2SPeter Wemm 	MaxRuleRecursion = MAXRULERECURSION;
337c2aa98e2SPeter Wemm 	MaxAliasRecursion = 10;
338c2aa98e2SPeter Wemm 	MaxMacroRecursion = 10;
33912ed1c7cSGregory Neil Shapiro 	ColonOkInAddr = true;
34012ed1c7cSGregory Neil Shapiro 	DontLockReadFiles = true;
34112ed1c7cSGregory Neil Shapiro 	DontProbeInterfaces = DPI_PROBEALL;
342c2aa98e2SPeter Wemm 	DoubleBounceAddr = "postmaster";
343e01d6f61SPeter Wemm 	MaxHeadersLength = MAXHDRSLEN;
34472936242SGregory Neil Shapiro 	MaxMimeHeaderLength = MAXLINE;
34572936242SGregory Neil Shapiro 	MaxMimeFieldLength = MaxMimeHeaderLength / 2;
3463299c2f1SGregory Neil Shapiro 	MaxForwardEntries = 0;
34712ed1c7cSGregory Neil Shapiro 	FastSplit = 1;
3483299c2f1SGregory Neil Shapiro #if SASL
3493299c2f1SGregory Neil Shapiro 	AuthMechanisms = newstr(AUTH_MECHANISMS);
350bfb62e91SGregory Neil Shapiro 	AuthRealm = NULL;
35112ed1c7cSGregory Neil Shapiro 	MaxSLBits = INT_MAX;
3523299c2f1SGregory Neil Shapiro #endif /* SASL */
35312ed1c7cSGregory Neil Shapiro #if STARTTLS
35412ed1c7cSGregory Neil Shapiro 	TLS_Srv_Opts = TLS_I_SRV;
35512ed1c7cSGregory Neil Shapiro #endif /* STARTTLS */
356c2aa98e2SPeter Wemm #ifdef HESIOD_INIT
357c2aa98e2SPeter Wemm 	HesiodContext = NULL;
3583299c2f1SGregory Neil Shapiro #endif /* HESIOD_INIT */
3593299c2f1SGregory Neil Shapiro #if NETINET6
3603299c2f1SGregory Neil Shapiro 	/* Detect if IPv6 is available at run time */
3613299c2f1SGregory Neil Shapiro 	i = socket(AF_INET6, SOCK_STREAM, 0);
3623299c2f1SGregory Neil Shapiro 	if (i >= 0)
3633299c2f1SGregory Neil Shapiro 	{
3643299c2f1SGregory Neil Shapiro 		InetMode = AF_INET6;
3653299c2f1SGregory Neil Shapiro 		(void) close(i);
3663299c2f1SGregory Neil Shapiro 	}
3673299c2f1SGregory Neil Shapiro 	else
3683299c2f1SGregory Neil Shapiro 		InetMode = AF_INET;
3693299c2f1SGregory Neil Shapiro #else /* NETINET6 */
3703299c2f1SGregory Neil Shapiro 	InetMode = AF_INET;
3713299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
37276b7bf71SPeter Wemm 	ControlSocketName = NULL;
3733299c2f1SGregory Neil Shapiro 	memset(&ConnectOnlyTo, '\0', sizeof ConnectOnlyTo);
3743299c2f1SGregory Neil Shapiro 	DataFileBufferSize = 4096;
3753299c2f1SGregory Neil Shapiro 	XscriptFileBufferSize = 4096;
3763299c2f1SGregory Neil Shapiro 	for (i = 0; i < MAXRWSETS; i++)
3773299c2f1SGregory Neil Shapiro 		RuleSetNames[i] = NULL;
37812ed1c7cSGregory Neil Shapiro #if MILTER
3793299c2f1SGregory Neil Shapiro 	InputFilters[0] = NULL;
38012ed1c7cSGregory Neil Shapiro #endif /* MILTER */
3812ef40764SGregory Neil Shapiro 	RejectLogInterval = 3 HOURS;
382bfb62e91SGregory Neil Shapiro #if REQUIRES_DIR_FSYNC
3832ef40764SGregory Neil Shapiro 	RequiresDirfsync = true;
384bfb62e91SGregory Neil Shapiro #endif /* REQUIRES_DIR_FSYNC */
385bfb62e91SGregory Neil Shapiro 	ConnectionRateWindowSize = 60;
386c2aa98e2SPeter Wemm 	setupmaps();
38712ed1c7cSGregory Neil Shapiro 	setupqueues();
388c2aa98e2SPeter Wemm 	setupmailers();
389c2aa98e2SPeter Wemm 	setupheaders();
390c2aa98e2SPeter Wemm }
391c2aa98e2SPeter Wemm 
392c2aa98e2SPeter Wemm 
393c2aa98e2SPeter Wemm /*
394c2aa98e2SPeter Wemm **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
395c2aa98e2SPeter Wemm */
396c2aa98e2SPeter Wemm 
397c2aa98e2SPeter Wemm void
398c2aa98e2SPeter Wemm setdefuser()
399c2aa98e2SPeter Wemm {
400c2aa98e2SPeter Wemm 	struct passwd *defpwent;
401c2aa98e2SPeter Wemm 	static char defuserbuf[40];
402c2aa98e2SPeter Wemm 
403c2aa98e2SPeter Wemm 	DefUser = defuserbuf;
404c2aa98e2SPeter Wemm 	defpwent = sm_getpwuid(DefUid);
40512ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(defuserbuf,
40612ed1c7cSGregory Neil Shapiro 			  (defpwent == NULL || defpwent->pw_name == NULL)
40712ed1c7cSGregory Neil Shapiro 			   ? "nobody" : defpwent->pw_name,
40812ed1c7cSGregory Neil Shapiro 			  sizeof defuserbuf);
409c2aa98e2SPeter Wemm 	if (tTd(37, 4))
41012ed1c7cSGregory Neil Shapiro 		sm_dprintf("setdefuser: DefUid=%d, DefUser=%s\n",
411c2aa98e2SPeter Wemm 			   (int) DefUid, DefUser);
412c2aa98e2SPeter Wemm }
41312ed1c7cSGregory Neil Shapiro /*
41412ed1c7cSGregory Neil Shapiro **  SETUPQUEUES -- initialize default queues
41512ed1c7cSGregory Neil Shapiro **
41612ed1c7cSGregory Neil Shapiro **	The mqueue QUEUE structure gets filled in after readcf() but
41712ed1c7cSGregory Neil Shapiro **	we need something to point to now for the mailer setup,
41812ed1c7cSGregory Neil Shapiro **	which use "mqueue" as default queue.
41912ed1c7cSGregory Neil Shapiro */
42012ed1c7cSGregory Neil Shapiro 
42112ed1c7cSGregory Neil Shapiro static void
42212ed1c7cSGregory Neil Shapiro setupqueues()
42312ed1c7cSGregory Neil Shapiro {
42412ed1c7cSGregory Neil Shapiro 	char buf[100];
42512ed1c7cSGregory Neil Shapiro 
42612ed1c7cSGregory Neil Shapiro 	MaxRunnersPerQueue = 1;
42712ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof buf);
42812ed1c7cSGregory Neil Shapiro 	makequeue(buf, false);
42912ed1c7cSGregory Neil Shapiro }
43012ed1c7cSGregory Neil Shapiro /*
431c2aa98e2SPeter Wemm **  SETUPMAILERS -- initialize default mailers
432c2aa98e2SPeter Wemm */
433c2aa98e2SPeter Wemm 
4343299c2f1SGregory Neil Shapiro static void
435c2aa98e2SPeter Wemm setupmailers()
436c2aa98e2SPeter Wemm {
437c2aa98e2SPeter Wemm 	char buf[100];
438c2aa98e2SPeter Wemm 
43912ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u",
4403299c2f1SGregory Neil Shapiro 			sizeof buf);
441c2aa98e2SPeter Wemm 	makemailer(buf);
442c2aa98e2SPeter Wemm 
44312ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u",
4443299c2f1SGregory Neil Shapiro 			sizeof buf);
445c2aa98e2SPeter Wemm 	makemailer(buf);
446c2aa98e2SPeter Wemm 
44712ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u",
4483299c2f1SGregory Neil Shapiro 			sizeof buf);
449c2aa98e2SPeter Wemm 	makemailer(buf);
4503299c2f1SGregory Neil Shapiro 	initerrmailers();
451c2aa98e2SPeter Wemm }
45212ed1c7cSGregory Neil Shapiro /*
453c2aa98e2SPeter Wemm **  SETUPMAPS -- set up map classes
454c2aa98e2SPeter Wemm */
455c2aa98e2SPeter Wemm 
456c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
457c2aa98e2SPeter Wemm 	{ \
458c2aa98e2SPeter Wemm 		extern bool parse __P((MAP *, char *)); \
459c2aa98e2SPeter Wemm 		extern bool open __P((MAP *, int)); \
460c2aa98e2SPeter Wemm 		extern void close __P((MAP *)); \
461c2aa98e2SPeter Wemm 		extern char *lookup __P((MAP *, char *, char **, int *)); \
462c2aa98e2SPeter Wemm 		extern void store __P((MAP *, char *, char *)); \
463c2aa98e2SPeter Wemm 		s = stab(name, ST_MAPCLASS, ST_ENTER); \
464c2aa98e2SPeter Wemm 		s->s_mapclass.map_cname = name; \
465c2aa98e2SPeter Wemm 		s->s_mapclass.map_ext = ext; \
466c2aa98e2SPeter Wemm 		s->s_mapclass.map_cflags = flags; \
467c2aa98e2SPeter Wemm 		s->s_mapclass.map_parse = parse; \
468c2aa98e2SPeter Wemm 		s->s_mapclass.map_open = open; \
469c2aa98e2SPeter Wemm 		s->s_mapclass.map_close = close; \
470c2aa98e2SPeter Wemm 		s->s_mapclass.map_lookup = lookup; \
471c2aa98e2SPeter Wemm 		s->s_mapclass.map_store = store; \
472c2aa98e2SPeter Wemm 	}
473c2aa98e2SPeter Wemm 
4743299c2f1SGregory Neil Shapiro static void
475c2aa98e2SPeter Wemm setupmaps()
476c2aa98e2SPeter Wemm {
477c2aa98e2SPeter Wemm 	register STAB *s;
478c2aa98e2SPeter Wemm 
47912ed1c7cSGregory Neil Shapiro #if NEWDB
4807660b554SGregory Neil Shapiro # if DB_VERSION_MAJOR > 1
4817660b554SGregory Neil Shapiro 	int major_v, minor_v, patch_v;
4827660b554SGregory Neil Shapiro 
4837660b554SGregory Neil Shapiro 	(void) db_version(&major_v, &minor_v, &patch_v);
4847660b554SGregory Neil Shapiro 	if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR)
4857660b554SGregory Neil Shapiro 	{
4867660b554SGregory Neil Shapiro 		errno = 0;
4877660b554SGregory Neil Shapiro 		syserr("Berkeley DB version mismatch: compiled against %d.%d.%d, run-time linked against %d.%d.%d",
4887660b554SGregory Neil Shapiro 		  DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
4897660b554SGregory Neil Shapiro 		  major_v, minor_v, patch_v);
4907660b554SGregory Neil Shapiro 	}
4917660b554SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR > 1 */
4927660b554SGregory Neil Shapiro 
493c2aa98e2SPeter Wemm 	MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
494c2aa98e2SPeter Wemm 		map_parseargs, hash_map_open, db_map_close,
495c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
496c2aa98e2SPeter Wemm 
497c2aa98e2SPeter Wemm 	MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
498c2aa98e2SPeter Wemm 		map_parseargs, bt_map_open, db_map_close,
499c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
5003299c2f1SGregory Neil Shapiro #endif /* NEWDB */
501c2aa98e2SPeter Wemm 
50212ed1c7cSGregory Neil Shapiro #if NDBM
503c2aa98e2SPeter Wemm 	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
504c2aa98e2SPeter Wemm 		map_parseargs, ndbm_map_open, ndbm_map_close,
505c2aa98e2SPeter Wemm 		ndbm_map_lookup, ndbm_map_store);
5063299c2f1SGregory Neil Shapiro #endif /* NDBM */
507c2aa98e2SPeter Wemm 
50812ed1c7cSGregory Neil Shapiro #if NIS
509c2aa98e2SPeter Wemm 	MAPDEF("nis", NULL, MCF_ALIASOK,
510c2aa98e2SPeter Wemm 		map_parseargs, nis_map_open, null_map_close,
511c2aa98e2SPeter Wemm 		nis_map_lookup, null_map_store);
5123299c2f1SGregory Neil Shapiro #endif /* NIS */
513c2aa98e2SPeter Wemm 
51412ed1c7cSGregory Neil Shapiro #if NISPLUS
515c2aa98e2SPeter Wemm 	MAPDEF("nisplus", NULL, MCF_ALIASOK,
516c2aa98e2SPeter Wemm 		map_parseargs, nisplus_map_open, null_map_close,
517c2aa98e2SPeter Wemm 		nisplus_map_lookup, null_map_store);
5183299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
5193299c2f1SGregory Neil Shapiro 
52012ed1c7cSGregory Neil Shapiro #if LDAPMAP
52112ed1c7cSGregory Neil Shapiro 	MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST,
5223299c2f1SGregory Neil Shapiro 		ldapmap_parseargs, ldapmap_open, ldapmap_close,
5233299c2f1SGregory Neil Shapiro 		ldapmap_lookup, null_map_store);
5243299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
5253299c2f1SGregory Neil Shapiro 
52612ed1c7cSGregory Neil Shapiro #if PH_MAP
52712ed1c7cSGregory Neil Shapiro 	MAPDEF("ph", NULL, MCF_NOTPERSIST,
5283299c2f1SGregory Neil Shapiro 		ph_map_parseargs, ph_map_open, ph_map_close,
5293299c2f1SGregory Neil Shapiro 		ph_map_lookup, null_map_store);
5303299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
5313299c2f1SGregory Neil Shapiro 
5323299c2f1SGregory Neil Shapiro #if MAP_NSD
5333299c2f1SGregory Neil Shapiro 	/* IRIX 6.5 nsd support */
5343299c2f1SGregory Neil Shapiro 	MAPDEF("nsd", NULL, MCF_ALIASOK,
5353299c2f1SGregory Neil Shapiro 	       map_parseargs, null_map_open, null_map_close,
5363299c2f1SGregory Neil Shapiro 	       nsd_map_lookup, null_map_store);
5373299c2f1SGregory Neil Shapiro #endif /* MAP_NSD */
538c2aa98e2SPeter Wemm 
53912ed1c7cSGregory Neil Shapiro #if HESIOD
540c2aa98e2SPeter Wemm 	MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
54112ed1c7cSGregory Neil Shapiro 		map_parseargs, hes_map_open, hes_map_close,
542c2aa98e2SPeter Wemm 		hes_map_lookup, null_map_store);
5433299c2f1SGregory Neil Shapiro #endif /* HESIOD */
544c2aa98e2SPeter Wemm 
545c2aa98e2SPeter Wemm #if NETINFO
546c2aa98e2SPeter Wemm 	MAPDEF("netinfo", NULL, MCF_ALIASOK,
547c2aa98e2SPeter Wemm 		map_parseargs, ni_map_open, null_map_close,
548c2aa98e2SPeter Wemm 		ni_map_lookup, null_map_store);
5493299c2f1SGregory Neil Shapiro #endif /* NETINFO */
550c2aa98e2SPeter Wemm 
551c2aa98e2SPeter Wemm #if 0
552c2aa98e2SPeter Wemm 	MAPDEF("dns", NULL, 0,
553c2aa98e2SPeter Wemm 		dns_map_init, null_map_open, null_map_close,
554c2aa98e2SPeter Wemm 		dns_map_lookup, null_map_store);
5553299c2f1SGregory Neil Shapiro #endif /* 0 */
556c2aa98e2SPeter Wemm 
557c2aa98e2SPeter Wemm #if NAMED_BIND
55812ed1c7cSGregory Neil Shapiro # if DNSMAP
559320f00e7SGregory Neil Shapiro #  if _FFR_DNSMAP_ALIASABLE
560320f00e7SGregory Neil Shapiro 	MAPDEF("dns", NULL, MCF_ALIASOK,
561320f00e7SGregory Neil Shapiro 	       dns_map_parseargs, dns_map_open, null_map_close,
562320f00e7SGregory Neil Shapiro 	       dns_map_lookup, null_map_store);
563320f00e7SGregory Neil Shapiro #  else /* _FFR_DNSMAP_ALIASABLE */
56412ed1c7cSGregory Neil Shapiro 	MAPDEF("dns", NULL, 0,
56512ed1c7cSGregory Neil Shapiro 	       dns_map_parseargs, dns_map_open, null_map_close,
56612ed1c7cSGregory Neil Shapiro 	       dns_map_lookup, null_map_store);
567320f00e7SGregory Neil Shapiro #  endif /* _FFR_DNSMAP_ALIASABLE */
56812ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */
56912ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */
57012ed1c7cSGregory Neil Shapiro 
57112ed1c7cSGregory Neil Shapiro #if NAMED_BIND
572c2aa98e2SPeter Wemm 	/* best MX DNS lookup */
573c2aa98e2SPeter Wemm 	MAPDEF("bestmx", NULL, MCF_OPTFILE,
574c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
575c2aa98e2SPeter Wemm 		bestmx_map_lookup, null_map_store);
5763299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
577c2aa98e2SPeter Wemm 
578c2aa98e2SPeter Wemm 	MAPDEF("host", NULL, 0,
579c2aa98e2SPeter Wemm 		host_map_init, null_map_open, null_map_close,
580c2aa98e2SPeter Wemm 		host_map_lookup, null_map_store);
581c2aa98e2SPeter Wemm 
582c2aa98e2SPeter Wemm 	MAPDEF("text", NULL, MCF_ALIASOK,
583c2aa98e2SPeter Wemm 		map_parseargs, text_map_open, null_map_close,
584c2aa98e2SPeter Wemm 		text_map_lookup, null_map_store);
585c2aa98e2SPeter Wemm 
586c2aa98e2SPeter Wemm 	MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
587c2aa98e2SPeter Wemm 		map_parseargs, stab_map_open, null_map_close,
588c2aa98e2SPeter Wemm 		stab_map_lookup, stab_map_store);
589c2aa98e2SPeter Wemm 
590c2aa98e2SPeter Wemm 	MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
591c2aa98e2SPeter Wemm 		map_parseargs, impl_map_open, impl_map_close,
592c2aa98e2SPeter Wemm 		impl_map_lookup, impl_map_store);
593c2aa98e2SPeter Wemm 
594c2aa98e2SPeter Wemm 	/* access to system passwd file */
595c2aa98e2SPeter Wemm 	MAPDEF("user", NULL, MCF_OPTFILE,
596c2aa98e2SPeter Wemm 		map_parseargs, user_map_open, null_map_close,
597c2aa98e2SPeter Wemm 		user_map_lookup, null_map_store);
598c2aa98e2SPeter Wemm 
599c2aa98e2SPeter Wemm 	/* dequote map */
600c2aa98e2SPeter Wemm 	MAPDEF("dequote", NULL, 0,
601c2aa98e2SPeter Wemm 		dequote_init, null_map_open, null_map_close,
602c2aa98e2SPeter Wemm 		dequote_map, null_map_store);
603c2aa98e2SPeter Wemm 
60412ed1c7cSGregory Neil Shapiro #if MAP_REGEX
605c2aa98e2SPeter Wemm 	MAPDEF("regex", NULL, 0,
606c2aa98e2SPeter Wemm 		regex_map_init, null_map_open, null_map_close,
607c2aa98e2SPeter Wemm 		regex_map_lookup, null_map_store);
6083299c2f1SGregory Neil Shapiro #endif /* MAP_REGEX */
609c2aa98e2SPeter Wemm 
610c2aa98e2SPeter Wemm #if USERDB
611c2aa98e2SPeter Wemm 	/* user database */
612c2aa98e2SPeter Wemm 	MAPDEF("userdb", ".db", 0,
613c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
614c2aa98e2SPeter Wemm 		udb_map_lookup, null_map_store);
6153299c2f1SGregory Neil Shapiro #endif /* USERDB */
616c2aa98e2SPeter Wemm 
617c2aa98e2SPeter Wemm 	/* arbitrary programs */
618c2aa98e2SPeter Wemm 	MAPDEF("program", NULL, MCF_ALIASOK,
619c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
620c2aa98e2SPeter Wemm 		prog_map_lookup, null_map_store);
621c2aa98e2SPeter Wemm 
622c2aa98e2SPeter Wemm 	/* sequenced maps */
623c2aa98e2SPeter Wemm 	MAPDEF("sequence", NULL, MCF_ALIASOK,
624c2aa98e2SPeter Wemm 		seq_map_parse, null_map_open, null_map_close,
625c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
626c2aa98e2SPeter Wemm 
627c2aa98e2SPeter Wemm 	/* switched interface to sequenced maps */
628c2aa98e2SPeter Wemm 	MAPDEF("switch", NULL, MCF_ALIASOK,
629c2aa98e2SPeter Wemm 		map_parseargs, switch_map_open, null_map_close,
630c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
631c2aa98e2SPeter Wemm 
632c2aa98e2SPeter Wemm 	/* null map lookup -- really for internal use only */
633c2aa98e2SPeter Wemm 	MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
634c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
635c2aa98e2SPeter Wemm 		null_map_lookup, null_map_store);
636c2aa98e2SPeter Wemm 
637c2aa98e2SPeter Wemm 	/* syslog map -- logs information to syslog */
638c2aa98e2SPeter Wemm 	MAPDEF("syslog", NULL, 0,
639c2aa98e2SPeter Wemm 		syslog_map_parseargs, null_map_open, null_map_close,
640c2aa98e2SPeter Wemm 		syslog_map_lookup, null_map_store);
6413299c2f1SGregory Neil Shapiro 
6423299c2f1SGregory Neil Shapiro 	/* macro storage map -- rulesets can set macros */
6433299c2f1SGregory Neil Shapiro 	MAPDEF("macro", NULL, 0,
6443299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
6453299c2f1SGregory Neil Shapiro 		macro_map_lookup, null_map_store);
6463299c2f1SGregory Neil Shapiro 
6473299c2f1SGregory Neil Shapiro 	/* arithmetic map -- add/subtract/compare */
6483299c2f1SGregory Neil Shapiro 	MAPDEF("arith", NULL, 0,
6493299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
6503299c2f1SGregory Neil Shapiro 		arith_map_lookup, null_map_store);
6513299c2f1SGregory Neil Shapiro 
652bfb62e91SGregory Neil Shapiro #if SOCKETMAP
653bfb62e91SGregory Neil Shapiro 	/* arbitrary daemons */
654bfb62e91SGregory Neil Shapiro 	MAPDEF("socket", NULL, MCF_ALIASOK,
655bfb62e91SGregory Neil Shapiro 		map_parseargs, socket_map_open, socket_map_close,
656bfb62e91SGregory Neil Shapiro 		socket_map_lookup, null_map_store);
657bfb62e91SGregory Neil Shapiro #endif /* SOCKETMAP */
658bfb62e91SGregory Neil Shapiro 
6593299c2f1SGregory Neil Shapiro 	if (tTd(38, 2))
6603299c2f1SGregory Neil Shapiro 	{
6613299c2f1SGregory Neil Shapiro 		/* bogus map -- always return tempfail */
6623299c2f1SGregory Neil Shapiro 		MAPDEF("bogus",	NULL, MCF_ALIASOK|MCF_OPTFILE,
6633299c2f1SGregory Neil Shapiro 		       map_parseargs, null_map_open, null_map_close,
6643299c2f1SGregory Neil Shapiro 		       bogus_map_lookup, null_map_store);
6653299c2f1SGregory Neil Shapiro 	}
666c2aa98e2SPeter Wemm }
667c2aa98e2SPeter Wemm 
668c2aa98e2SPeter Wemm #undef MAPDEF
66912ed1c7cSGregory Neil Shapiro /*
670c2aa98e2SPeter Wemm **  INITHOSTMAPS -- initial host-dependent maps
671c2aa98e2SPeter Wemm **
672c2aa98e2SPeter Wemm **	This should act as an interface to any local service switch
673c2aa98e2SPeter Wemm **	provided by the host operating system.
674c2aa98e2SPeter Wemm **
675c2aa98e2SPeter Wemm **	Parameters:
676c2aa98e2SPeter Wemm **		none
677c2aa98e2SPeter Wemm **
678c2aa98e2SPeter Wemm **	Returns:
679c2aa98e2SPeter Wemm **		none
680c2aa98e2SPeter Wemm **
681c2aa98e2SPeter Wemm **	Side Effects:
682c2aa98e2SPeter Wemm **		Should define maps "host" and "users" as necessary
683c2aa98e2SPeter Wemm **		for this OS.  If they are not defined, they will get
684c2aa98e2SPeter Wemm **		a default value later.  It should check to make sure
685c2aa98e2SPeter Wemm **		they are not defined first, since it's possible that
686c2aa98e2SPeter Wemm **		the config file has provided an override.
687c2aa98e2SPeter Wemm */
688c2aa98e2SPeter Wemm 
689c2aa98e2SPeter Wemm void
690c2aa98e2SPeter Wemm inithostmaps()
691c2aa98e2SPeter Wemm {
692c2aa98e2SPeter Wemm 	register int i;
693c2aa98e2SPeter Wemm 	int nmaps;
694c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
695c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
696c2aa98e2SPeter Wemm 	char buf[MAXLINE];
697c2aa98e2SPeter Wemm 
698c2aa98e2SPeter Wemm 	/*
699c2aa98e2SPeter Wemm 	**  Set up default hosts maps.
700c2aa98e2SPeter Wemm 	*/
701c2aa98e2SPeter Wemm 
702c2aa98e2SPeter Wemm #if 0
703c2aa98e2SPeter Wemm 	nmaps = switch_map_find("hosts", maptype, mapreturn);
704c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
705c2aa98e2SPeter Wemm 	{
706c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
707c2aa98e2SPeter Wemm 		    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
708c2aa98e2SPeter Wemm 		{
70912ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts",
7103299c2f1SGregory Neil Shapiro 				sizeof buf);
711c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
712c2aa98e2SPeter Wemm 		}
713c2aa98e2SPeter Wemm # if NAMED_BIND
714c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "dns") == 0 &&
715c2aa98e2SPeter Wemm 			 stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
716c2aa98e2SPeter Wemm 		{
71712ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.dns dns A", sizeof buf);
718c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
719c2aa98e2SPeter Wemm 		}
7203299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
72112ed1c7cSGregory Neil Shapiro # if NISPLUS
722c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
723c2aa98e2SPeter Wemm 			 stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
724c2aa98e2SPeter Wemm 		{
72512ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir",
7263299c2f1SGregory Neil Shapiro 				sizeof buf);
727c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
728c2aa98e2SPeter Wemm 		}
7293299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
73012ed1c7cSGregory Neil Shapiro # if NIS
731c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
732c2aa98e2SPeter Wemm 			 stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
733c2aa98e2SPeter Wemm 		{
73412ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname",
7353299c2f1SGregory Neil Shapiro 				sizeof buf);
736c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
737c2aa98e2SPeter Wemm 		}
7383299c2f1SGregory Neil Shapiro # endif /* NIS */
739c2aa98e2SPeter Wemm # if NETINFO
74012ed1c7cSGregory Neil Shapiro 		else if (strcmp(maptype[i], "netinfo") == 0 &&
741c2aa98e2SPeter Wemm 			 stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
742c2aa98e2SPeter Wemm 		{
74312ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.netinfo netinfo -v name /machines",
7443299c2f1SGregory Neil Shapiro 				sizeof buf);
745c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
746c2aa98e2SPeter Wemm 		}
7473299c2f1SGregory Neil Shapiro # endif /* NETINFO */
748c2aa98e2SPeter Wemm 	}
7493299c2f1SGregory Neil Shapiro #endif /* 0 */
750c2aa98e2SPeter Wemm 
751c2aa98e2SPeter Wemm 	/*
752c2aa98e2SPeter Wemm 	**  Make sure we have a host map.
753c2aa98e2SPeter Wemm 	*/
754c2aa98e2SPeter Wemm 
755c2aa98e2SPeter Wemm 	if (stab("host", ST_MAP, ST_FIND) == NULL)
756c2aa98e2SPeter Wemm 	{
757c2aa98e2SPeter Wemm 		/* user didn't initialize: set up host map */
75812ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "host host", sizeof buf);
759c2aa98e2SPeter Wemm #if NAMED_BIND
760c2aa98e2SPeter Wemm 		if (ConfigLevel >= 2)
76112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcat(buf, " -a. -D", sizeof buf);
7623299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
763c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
764c2aa98e2SPeter Wemm 	}
765c2aa98e2SPeter Wemm 
766c2aa98e2SPeter Wemm 	/*
767c2aa98e2SPeter Wemm 	**  Set up default aliases maps
768c2aa98e2SPeter Wemm 	*/
769c2aa98e2SPeter Wemm 
770c2aa98e2SPeter Wemm 	nmaps = switch_map_find("aliases", maptype, mapreturn);
771c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
772c2aa98e2SPeter Wemm 	{
773c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
774c2aa98e2SPeter Wemm 		    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
775c2aa98e2SPeter Wemm 		{
77612ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.files null",
77712ed1c7cSGregory Neil Shapiro 					  sizeof buf);
778c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
779c2aa98e2SPeter Wemm 		}
78012ed1c7cSGregory Neil Shapiro #if NISPLUS
781c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
782c2aa98e2SPeter Wemm 			 stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
783c2aa98e2SPeter Wemm 		{
78412ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
7853299c2f1SGregory Neil Shapiro 				sizeof buf);
786c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
787c2aa98e2SPeter Wemm 		}
7883299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
78912ed1c7cSGregory Neil Shapiro #if NIS
790c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
791c2aa98e2SPeter Wemm 			 stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
792c2aa98e2SPeter Wemm 		{
79312ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nis nis mail.aliases",
7943299c2f1SGregory Neil Shapiro 				sizeof buf);
795c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
796c2aa98e2SPeter Wemm 		}
7973299c2f1SGregory Neil Shapiro #endif /* NIS */
7983299c2f1SGregory Neil Shapiro #if NETINFO
799c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "netinfo") == 0 &&
800c2aa98e2SPeter Wemm 			 stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
801c2aa98e2SPeter Wemm 		{
80212ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
8033299c2f1SGregory Neil Shapiro 				sizeof buf);
804c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
805c2aa98e2SPeter Wemm 		}
8063299c2f1SGregory Neil Shapiro #endif /* NETINFO */
80712ed1c7cSGregory Neil Shapiro #if HESIOD
808c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "hesiod") == 0 &&
809c2aa98e2SPeter Wemm 			 stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
810c2aa98e2SPeter Wemm 		{
81112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases",
8123299c2f1SGregory Neil Shapiro 				sizeof buf);
813c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
814c2aa98e2SPeter Wemm 		}
8153299c2f1SGregory Neil Shapiro #endif /* HESIOD */
816c2aa98e2SPeter Wemm 	}
817c2aa98e2SPeter Wemm 	if (stab("aliases", ST_MAP, ST_FIND) == NULL)
818c2aa98e2SPeter Wemm 	{
81912ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "aliases switch aliases", sizeof buf);
820c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
821c2aa98e2SPeter Wemm 	}
822c2aa98e2SPeter Wemm 
823c2aa98e2SPeter Wemm #if 0		/* "user" map class is a better choice */
824c2aa98e2SPeter Wemm 	/*
825c2aa98e2SPeter Wemm 	**  Set up default users maps.
826c2aa98e2SPeter Wemm 	*/
827c2aa98e2SPeter Wemm 
828c2aa98e2SPeter Wemm 	nmaps = switch_map_find("passwd", maptype, mapreturn);
829c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
830c2aa98e2SPeter Wemm 	{
831c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
832c2aa98e2SPeter Wemm 		    stab("users.files", ST_MAP, ST_FIND) == NULL)
833c2aa98e2SPeter Wemm 		{
83412ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd",
8353299c2f1SGregory Neil Shapiro 				sizeof buf);
836c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
837c2aa98e2SPeter Wemm 		}
83812ed1c7cSGregory Neil Shapiro # if NISPLUS
839c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
840c2aa98e2SPeter Wemm 		    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
841c2aa98e2SPeter Wemm 		{
84212ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir",
8433299c2f1SGregory Neil Shapiro 				sizeof buf);
844c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
845c2aa98e2SPeter Wemm 		}
8463299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
84712ed1c7cSGregory Neil Shapiro # if NIS
848c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
849c2aa98e2SPeter Wemm 		    stab("users.nis", ST_MAP, ST_FIND) == NULL)
850c2aa98e2SPeter Wemm 		{
85112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.nis nis -m passwd.byname",
8523299c2f1SGregory Neil Shapiro 				sizeof buf);
853c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
854c2aa98e2SPeter Wemm 		}
8553299c2f1SGregory Neil Shapiro # endif /* NIS */
85612ed1c7cSGregory Neil Shapiro # if HESIOD
85712ed1c7cSGregory Neil Shapiro 		else if (strcmp(maptype[i], "hesiod") == 0 &&
858c2aa98e2SPeter Wemm 			 stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
859c2aa98e2SPeter Wemm 		{
86012ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.hesiod hesiod", sizeof buf);
861c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
862c2aa98e2SPeter Wemm 		}
8633299c2f1SGregory Neil Shapiro # endif /* HESIOD */
864c2aa98e2SPeter Wemm 	}
865c2aa98e2SPeter Wemm 	if (stab("users", ST_MAP, ST_FIND) == NULL)
866c2aa98e2SPeter Wemm 	{
86712ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "users switch -m passwd", sizeof buf);
868c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
869c2aa98e2SPeter Wemm 	}
8703299c2f1SGregory Neil Shapiro #endif /* 0 */
871c2aa98e2SPeter Wemm }
87212ed1c7cSGregory Neil Shapiro /*
873c2aa98e2SPeter Wemm **  SWITCH_MAP_FIND -- find the list of types associated with a map
874c2aa98e2SPeter Wemm **
875c2aa98e2SPeter Wemm **	This is the system-dependent interface to the service switch.
876c2aa98e2SPeter Wemm **
877c2aa98e2SPeter Wemm **	Parameters:
878c2aa98e2SPeter Wemm **		service -- the name of the service of interest.
879c2aa98e2SPeter Wemm **		maptype -- an out-array of strings containing the types
880c2aa98e2SPeter Wemm **			of access to use for this service.  There can
881c2aa98e2SPeter Wemm **			be at most MAXMAPSTACK types for a single service.
882c2aa98e2SPeter Wemm **		mapreturn -- an out-array of return information bitmaps
883c2aa98e2SPeter Wemm **			for the map.
884c2aa98e2SPeter Wemm **
885c2aa98e2SPeter Wemm **	Returns:
886c2aa98e2SPeter Wemm **		The number of map types filled in, or -1 for failure.
8873299c2f1SGregory Neil Shapiro **
8883299c2f1SGregory Neil Shapiro **	Side effects:
8893299c2f1SGregory Neil Shapiro **		Preserves errno so nothing in the routine clobbers it.
890c2aa98e2SPeter Wemm */
891c2aa98e2SPeter Wemm 
892c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
893c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_
8943299c2f1SGregory Neil Shapiro #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
895c2aa98e2SPeter Wemm 
89612ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
89712ed1c7cSGregory Neil Shapiro # ifdef __hpux
89812ed1c7cSGregory Neil Shapiro #  define _USE_SUN_NSSWITCH_
89912ed1c7cSGregory Neil Shapiro # endif /* __hpux */
90012ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */
90112ed1c7cSGregory Neil Shapiro 
902c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
903c2aa98e2SPeter Wemm # include <nsswitch.h>
9043299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
905c2aa98e2SPeter Wemm 
906c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
907c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_
9083299c2f1SGregory Neil Shapiro #endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
909c2aa98e2SPeter Wemm 
910c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
911c2aa98e2SPeter Wemm # include <sys/svcinfo.h>
9123299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
913c2aa98e2SPeter Wemm 
914c2aa98e2SPeter Wemm int
915c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn)
916c2aa98e2SPeter Wemm 	char *service;
917c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
918c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
919c2aa98e2SPeter Wemm {
920c46d91b7SGregory Neil Shapiro 	int svcno = 0;
9213299c2f1SGregory Neil Shapiro 	int save_errno = errno;
922c2aa98e2SPeter Wemm 
923c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
924c2aa98e2SPeter Wemm 	struct __nsw_switchconfig *nsw_conf;
925c2aa98e2SPeter Wemm 	enum __nsw_parse_err pserr;
926c2aa98e2SPeter Wemm 	struct __nsw_lookup *lk;
927c2aa98e2SPeter Wemm 	static struct __nsw_lookup lkp0 =
928c2aa98e2SPeter Wemm 		{ "files", {1, 0, 0, 0}, NULL, NULL };
929c2aa98e2SPeter Wemm 	static struct __nsw_switchconfig lkp_default =
930c2aa98e2SPeter Wemm 		{ 0, "sendmail", 3, &lkp0 };
931c2aa98e2SPeter Wemm 
932c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
933c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
934c2aa98e2SPeter Wemm 
935c2aa98e2SPeter Wemm 	if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
936c2aa98e2SPeter Wemm 		lk = lkp_default.lookups;
937c2aa98e2SPeter Wemm 	else
938c2aa98e2SPeter Wemm 		lk = nsw_conf->lookups;
939c2aa98e2SPeter Wemm 	svcno = 0;
940c46d91b7SGregory Neil Shapiro 	while (lk != NULL && svcno < MAXMAPSTACK)
941c2aa98e2SPeter Wemm 	{
942c2aa98e2SPeter Wemm 		maptype[svcno] = lk->service_name;
943c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
944c2aa98e2SPeter Wemm 			mapreturn[MA_NOTFOUND] |= 1 << svcno;
945c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
946c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
947c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
948c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
949c2aa98e2SPeter Wemm 		svcno++;
950c2aa98e2SPeter Wemm 		lk = lk->next;
951c2aa98e2SPeter Wemm 	}
9523299c2f1SGregory Neil Shapiro 	errno = save_errno;
953c2aa98e2SPeter Wemm 	return svcno;
9543299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
955c2aa98e2SPeter Wemm 
956c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
957c2aa98e2SPeter Wemm 	struct svcinfo *svcinfo;
958c2aa98e2SPeter Wemm 	int svc;
959c2aa98e2SPeter Wemm 
960c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
961c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
962c2aa98e2SPeter Wemm 
963c2aa98e2SPeter Wemm 	svcinfo = getsvc();
964c2aa98e2SPeter Wemm 	if (svcinfo == NULL)
965c2aa98e2SPeter Wemm 		goto punt;
966c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
967c2aa98e2SPeter Wemm 		svc = SVC_HOSTS;
968c2aa98e2SPeter Wemm 	else if (strcmp(service, "aliases") == 0)
969c2aa98e2SPeter Wemm 		svc = SVC_ALIASES;
970c2aa98e2SPeter Wemm 	else if (strcmp(service, "passwd") == 0)
971c2aa98e2SPeter Wemm 		svc = SVC_PASSWD;
972c2aa98e2SPeter Wemm 	else
9733299c2f1SGregory Neil Shapiro 	{
9743299c2f1SGregory Neil Shapiro 		errno = save_errno;
975c2aa98e2SPeter Wemm 		return -1;
9763299c2f1SGregory Neil Shapiro 	}
977c46d91b7SGregory Neil Shapiro 	for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++)
978c2aa98e2SPeter Wemm 	{
979c2aa98e2SPeter Wemm 		switch (svcinfo->svcpath[svc][svcno])
980c2aa98e2SPeter Wemm 		{
981c2aa98e2SPeter Wemm 		  case SVC_LOCAL:
982c2aa98e2SPeter Wemm 			maptype[svcno] = "files";
983c2aa98e2SPeter Wemm 			break;
984c2aa98e2SPeter Wemm 
985c2aa98e2SPeter Wemm 		  case SVC_YP:
986c2aa98e2SPeter Wemm 			maptype[svcno] = "nis";
987c2aa98e2SPeter Wemm 			break;
988c2aa98e2SPeter Wemm 
989c2aa98e2SPeter Wemm 		  case SVC_BIND:
990c2aa98e2SPeter Wemm 			maptype[svcno] = "dns";
991c2aa98e2SPeter Wemm 			break;
992c2aa98e2SPeter Wemm 
993c2aa98e2SPeter Wemm # ifdef SVC_HESIOD
994c2aa98e2SPeter Wemm 		  case SVC_HESIOD:
995c2aa98e2SPeter Wemm 			maptype[svcno] = "hesiod";
996c2aa98e2SPeter Wemm 			break;
9973299c2f1SGregory Neil Shapiro # endif /* SVC_HESIOD */
998c2aa98e2SPeter Wemm 
999c2aa98e2SPeter Wemm 		  case SVC_LAST:
10003299c2f1SGregory Neil Shapiro 			errno = save_errno;
1001c2aa98e2SPeter Wemm 			return svcno;
1002c2aa98e2SPeter Wemm 		}
1003c2aa98e2SPeter Wemm 	}
10043299c2f1SGregory Neil Shapiro 	errno = save_errno;
1005c2aa98e2SPeter Wemm 	return svcno;
10063299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
1007c2aa98e2SPeter Wemm 
1008c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
1009c2aa98e2SPeter Wemm 	/*
1010c2aa98e2SPeter Wemm 	**  Fall-back mechanism.
1011c2aa98e2SPeter Wemm 	*/
1012c2aa98e2SPeter Wemm 
1013c2aa98e2SPeter Wemm 	STAB *st;
101412ed1c7cSGregory Neil Shapiro 	static time_t servicecachetime;	/* time service switch was cached */
1015c2aa98e2SPeter Wemm 	time_t now = curtime();
1016c2aa98e2SPeter Wemm 
1017c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1018c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1019c2aa98e2SPeter Wemm 
102012ed1c7cSGregory Neil Shapiro 	if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge)
1021c2aa98e2SPeter Wemm 	{
1022c2aa98e2SPeter Wemm 		/* (re)read service switch */
102312ed1c7cSGregory Neil Shapiro 		register SM_FILE_T *fp;
10243299c2f1SGregory Neil Shapiro 		long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
1025c2aa98e2SPeter Wemm 
10263299c2f1SGregory Neil Shapiro 		if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
10273299c2f1SGregory Neil Shapiro 			    DontBlameSendmail))
1028c2aa98e2SPeter Wemm 			sff |= SFF_NOWLINK;
1029c2aa98e2SPeter Wemm 
1030c2aa98e2SPeter Wemm 		if (ConfigFileRead)
103112ed1c7cSGregory Neil Shapiro 			servicecachetime = now;
1032c2aa98e2SPeter Wemm 		fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
1033c2aa98e2SPeter Wemm 		if (fp != NULL)
1034c2aa98e2SPeter Wemm 		{
1035c2aa98e2SPeter Wemm 			char buf[MAXLINE];
1036c2aa98e2SPeter Wemm 
103712ed1c7cSGregory Neil Shapiro 			while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf,
103812ed1c7cSGregory Neil Shapiro 					   sizeof buf) != NULL)
1039c2aa98e2SPeter Wemm 			{
1040c2aa98e2SPeter Wemm 				register char *p;
1041c2aa98e2SPeter Wemm 
1042c2aa98e2SPeter Wemm 				p = strpbrk(buf, "#\n");
1043c2aa98e2SPeter Wemm 				if (p != NULL)
1044c2aa98e2SPeter Wemm 					*p = '\0';
1045c2aa98e2SPeter Wemm 				p = strpbrk(buf, " \t");
1046c2aa98e2SPeter Wemm 				if (p != NULL)
1047c2aa98e2SPeter Wemm 					*p++ = '\0';
1048c2aa98e2SPeter Wemm 				if (buf[0] == '\0')
1049c2aa98e2SPeter Wemm 					continue;
105076b7bf71SPeter Wemm 				if (p == NULL)
105176b7bf71SPeter Wemm 				{
105276b7bf71SPeter Wemm 					sm_syslog(LOG_ERR, NOQID,
105376b7bf71SPeter Wemm 						  "Bad line on %.100s: %.100s",
105476b7bf71SPeter Wemm 						  ServiceSwitchFile,
105576b7bf71SPeter Wemm 						  buf);
105676b7bf71SPeter Wemm 					continue;
105776b7bf71SPeter Wemm 				}
1058c2aa98e2SPeter Wemm 				while (isspace(*p))
1059c2aa98e2SPeter Wemm 					p++;
1060c2aa98e2SPeter Wemm 				if (*p == '\0')
1061c2aa98e2SPeter Wemm 					continue;
1062c2aa98e2SPeter Wemm 
1063c2aa98e2SPeter Wemm 				/*
1064c2aa98e2SPeter Wemm 				**  Find/allocate space for this service entry.
1065c2aa98e2SPeter Wemm 				**	Space for all of the service strings
1066c2aa98e2SPeter Wemm 				**	are allocated at once.  This means
1067c2aa98e2SPeter Wemm 				**	that we only have to free the first
1068c2aa98e2SPeter Wemm 				**	one to free all of them.
1069c2aa98e2SPeter Wemm 				*/
1070c2aa98e2SPeter Wemm 
1071c2aa98e2SPeter Wemm 				st = stab(buf, ST_SERVICE, ST_ENTER);
1072c2aa98e2SPeter Wemm 				if (st->s_service[0] != NULL)
107312ed1c7cSGregory Neil Shapiro 					sm_free((void *) st->s_service[0]); /* XXX */
1074c2aa98e2SPeter Wemm 				p = newstr(p);
1075c2aa98e2SPeter Wemm 				for (svcno = 0; svcno < MAXMAPSTACK; )
1076c2aa98e2SPeter Wemm 				{
1077c2aa98e2SPeter Wemm 					if (*p == '\0')
1078c2aa98e2SPeter Wemm 						break;
1079c2aa98e2SPeter Wemm 					st->s_service[svcno++] = p;
1080c2aa98e2SPeter Wemm 					p = strpbrk(p, " \t");
1081c2aa98e2SPeter Wemm 					if (p == NULL)
1082c2aa98e2SPeter Wemm 						break;
1083c2aa98e2SPeter Wemm 					*p++ = '\0';
1084c2aa98e2SPeter Wemm 					while (isspace(*p))
1085c2aa98e2SPeter Wemm 						p++;
1086c2aa98e2SPeter Wemm 				}
1087c2aa98e2SPeter Wemm 				if (svcno < MAXMAPSTACK)
1088c2aa98e2SPeter Wemm 					st->s_service[svcno] = NULL;
1089c2aa98e2SPeter Wemm 			}
109012ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(fp, SM_TIME_DEFAULT);
1091c2aa98e2SPeter Wemm 		}
1092c2aa98e2SPeter Wemm 	}
1093c2aa98e2SPeter Wemm 
1094c2aa98e2SPeter Wemm 	/* look up entry in cache */
1095c2aa98e2SPeter Wemm 	st = stab(service, ST_SERVICE, ST_FIND);
1096c2aa98e2SPeter Wemm 	if (st != NULL && st->s_service[0] != NULL)
1097c2aa98e2SPeter Wemm 	{
1098c2aa98e2SPeter Wemm 		/* extract data */
1099c2aa98e2SPeter Wemm 		svcno = 0;
1100c2aa98e2SPeter Wemm 		while (svcno < MAXMAPSTACK)
1101c2aa98e2SPeter Wemm 		{
1102c2aa98e2SPeter Wemm 			maptype[svcno] = st->s_service[svcno];
1103c2aa98e2SPeter Wemm 			if (maptype[svcno++] == NULL)
1104c2aa98e2SPeter Wemm 				break;
1105c2aa98e2SPeter Wemm 		}
11063299c2f1SGregory Neil Shapiro 		errno = save_errno;
1107c2aa98e2SPeter Wemm 		return --svcno;
1108c2aa98e2SPeter Wemm 	}
11093299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
1110c2aa98e2SPeter Wemm 
1111c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_)
1112c2aa98e2SPeter Wemm 	/* if the service file doesn't work, use an absolute fallback */
1113c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_
1114c2aa98e2SPeter Wemm   punt:
11153299c2f1SGregory Neil Shapiro # endif /* _USE_DEC_SVC_CONF_ */
1116c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1117c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1118c2aa98e2SPeter Wemm 	svcno = 0;
1119c2aa98e2SPeter Wemm 	if (strcmp(service, "aliases") == 0)
1120c2aa98e2SPeter Wemm 	{
1121c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
11223299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
11233299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
11243299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
1125c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES
112612ed1c7cSGregory Neil Shapiro #  if NISPLUS
1127c2aa98e2SPeter Wemm 		maptype[svcno++] = "nisplus";
11283299c2f1SGregory Neil Shapiro #  endif /* NISPLUS */
112912ed1c7cSGregory Neil Shapiro #  if NIS
1130c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
11313299c2f1SGregory Neil Shapiro #  endif /* NIS */
11323299c2f1SGregory Neil Shapiro # endif /* AUTO_NIS_ALIASES */
11333299c2f1SGregory Neil Shapiro 		errno = save_errno;
1134c2aa98e2SPeter Wemm 		return svcno;
1135c2aa98e2SPeter Wemm 	}
1136c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
1137c2aa98e2SPeter Wemm 	{
1138c2aa98e2SPeter Wemm # if NAMED_BIND
1139c2aa98e2SPeter Wemm 		maptype[svcno++] = "dns";
11403299c2f1SGregory Neil Shapiro # else /* NAMED_BIND */
1141c2aa98e2SPeter Wemm #  if defined(sun) && !defined(BSD)
1142c2aa98e2SPeter Wemm 		/* SunOS */
1143c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
11443299c2f1SGregory Neil Shapiro #  endif /* defined(sun) && !defined(BSD) */
11453299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
11463299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
11473299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
11483299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */
1149c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
11503299c2f1SGregory Neil Shapiro 		errno = save_errno;
1151c2aa98e2SPeter Wemm 		return svcno;
1152c2aa98e2SPeter Wemm 	}
11533299c2f1SGregory Neil Shapiro 	errno = save_errno;
1154c2aa98e2SPeter Wemm 	return -1;
11553299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) */
1156c2aa98e2SPeter Wemm }
115712ed1c7cSGregory Neil Shapiro /*
1158c2aa98e2SPeter Wemm **  USERNAME -- return the user id of the logged in user.
1159c2aa98e2SPeter Wemm **
1160c2aa98e2SPeter Wemm **	Parameters:
1161c2aa98e2SPeter Wemm **		none.
1162c2aa98e2SPeter Wemm **
1163c2aa98e2SPeter Wemm **	Returns:
1164c2aa98e2SPeter Wemm **		The login name of the logged in user.
1165c2aa98e2SPeter Wemm **
1166c2aa98e2SPeter Wemm **	Side Effects:
1167c2aa98e2SPeter Wemm **		none.
1168c2aa98e2SPeter Wemm **
1169c2aa98e2SPeter Wemm **	Notes:
1170c2aa98e2SPeter Wemm **		The return value is statically allocated.
1171c2aa98e2SPeter Wemm */
1172c2aa98e2SPeter Wemm 
1173c2aa98e2SPeter Wemm char *
1174c2aa98e2SPeter Wemm username()
1175c2aa98e2SPeter Wemm {
1176c2aa98e2SPeter Wemm 	static char *myname = NULL;
1177c2aa98e2SPeter Wemm 	extern char *getlogin();
1178c2aa98e2SPeter Wemm 	register struct passwd *pw;
1179c2aa98e2SPeter Wemm 
1180c2aa98e2SPeter Wemm 	/* cache the result */
1181c2aa98e2SPeter Wemm 	if (myname == NULL)
1182c2aa98e2SPeter Wemm 	{
1183c2aa98e2SPeter Wemm 		myname = getlogin();
1184c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1185c2aa98e2SPeter Wemm 		{
1186c2aa98e2SPeter Wemm 			pw = sm_getpwuid(RealUid);
1187c2aa98e2SPeter Wemm 			if (pw != NULL)
118812ed1c7cSGregory Neil Shapiro 				myname = pw->pw_name;
1189c2aa98e2SPeter Wemm 		}
1190c2aa98e2SPeter Wemm 		else
1191c2aa98e2SPeter Wemm 		{
1192c2aa98e2SPeter Wemm 			uid_t uid = RealUid;
1193c2aa98e2SPeter Wemm 
1194c2aa98e2SPeter Wemm 			if ((pw = sm_getpwnam(myname)) == NULL ||
1195c2aa98e2SPeter Wemm 			      (uid != 0 && uid != pw->pw_uid))
1196c2aa98e2SPeter Wemm 			{
1197c2aa98e2SPeter Wemm 				pw = sm_getpwuid(uid);
1198c2aa98e2SPeter Wemm 				if (pw != NULL)
119912ed1c7cSGregory Neil Shapiro 					myname = pw->pw_name;
1200c2aa98e2SPeter Wemm 			}
1201c2aa98e2SPeter Wemm 		}
1202c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1203c2aa98e2SPeter Wemm 		{
12043299c2f1SGregory Neil Shapiro 			syserr("554 5.3.0 Who are you?");
1205c2aa98e2SPeter Wemm 			myname = "postmaster";
1206c2aa98e2SPeter Wemm 		}
120712ed1c7cSGregory Neil Shapiro 		else if (strpbrk(myname, ",;:/|\"\\") != NULL)
120812ed1c7cSGregory Neil Shapiro 			myname = addquotes(myname, NULL);
120912ed1c7cSGregory Neil Shapiro 		else
121012ed1c7cSGregory Neil Shapiro 			myname = sm_pstrdup_x(myname);
1211c2aa98e2SPeter Wemm 	}
12123299c2f1SGregory Neil Shapiro 	return myname;
1213c2aa98e2SPeter Wemm }
121412ed1c7cSGregory Neil Shapiro /*
1215c2aa98e2SPeter Wemm **  TTYPATH -- Get the path of the user's tty
1216c2aa98e2SPeter Wemm **
1217c2aa98e2SPeter Wemm **	Returns the pathname of the user's tty.  Returns NULL if
1218c2aa98e2SPeter Wemm **	the user is not logged in or if s/he has write permission
1219c2aa98e2SPeter Wemm **	denied.
1220c2aa98e2SPeter Wemm **
1221c2aa98e2SPeter Wemm **	Parameters:
1222c2aa98e2SPeter Wemm **		none
1223c2aa98e2SPeter Wemm **
1224c2aa98e2SPeter Wemm **	Returns:
1225c2aa98e2SPeter Wemm **		pathname of the user's tty.
1226c2aa98e2SPeter Wemm **		NULL if not logged in or write permission denied.
1227c2aa98e2SPeter Wemm **
1228c2aa98e2SPeter Wemm **	Side Effects:
1229c2aa98e2SPeter Wemm **		none.
1230c2aa98e2SPeter Wemm **
1231c2aa98e2SPeter Wemm **	WARNING:
1232c2aa98e2SPeter Wemm **		Return value is in a local buffer.
1233c2aa98e2SPeter Wemm **
1234c2aa98e2SPeter Wemm **	Called By:
1235c2aa98e2SPeter Wemm **		savemail
1236c2aa98e2SPeter Wemm */
1237c2aa98e2SPeter Wemm 
1238c2aa98e2SPeter Wemm char *
1239c2aa98e2SPeter Wemm ttypath()
1240c2aa98e2SPeter Wemm {
1241c2aa98e2SPeter Wemm 	struct stat stbuf;
1242c2aa98e2SPeter Wemm 	register char *pathn;
1243c2aa98e2SPeter Wemm 	extern char *ttyname();
1244c2aa98e2SPeter Wemm 	extern char *getlogin();
1245c2aa98e2SPeter Wemm 
1246c2aa98e2SPeter Wemm 	/* compute the pathname of the controlling tty */
1247c2aa98e2SPeter Wemm 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
1248c2aa98e2SPeter Wemm 	    (pathn = ttyname(0)) == NULL)
1249c2aa98e2SPeter Wemm 	{
1250c2aa98e2SPeter Wemm 		errno = 0;
12513299c2f1SGregory Neil Shapiro 		return NULL;
1252c2aa98e2SPeter Wemm 	}
1253c2aa98e2SPeter Wemm 
1254c2aa98e2SPeter Wemm 	/* see if we have write permission */
1255c2aa98e2SPeter Wemm 	if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode))
1256c2aa98e2SPeter Wemm 	{
1257c2aa98e2SPeter Wemm 		errno = 0;
12583299c2f1SGregory Neil Shapiro 		return NULL;
1259c2aa98e2SPeter Wemm 	}
1260c2aa98e2SPeter Wemm 
1261c2aa98e2SPeter Wemm 	/* see if the user is logged in */
1262c2aa98e2SPeter Wemm 	if (getlogin() == NULL)
12633299c2f1SGregory Neil Shapiro 		return NULL;
1264c2aa98e2SPeter Wemm 
1265c2aa98e2SPeter Wemm 	/* looks good */
12663299c2f1SGregory Neil Shapiro 	return pathn;
1267c2aa98e2SPeter Wemm }
126812ed1c7cSGregory Neil Shapiro /*
1269c2aa98e2SPeter Wemm **  CHECKCOMPAT -- check for From and To person compatible.
1270c2aa98e2SPeter Wemm **
1271c2aa98e2SPeter Wemm **	This routine can be supplied on a per-installation basis
1272c2aa98e2SPeter Wemm **	to determine whether a person is allowed to send a message.
1273c2aa98e2SPeter Wemm **	This allows restriction of certain types of internet
1274c2aa98e2SPeter Wemm **	forwarding or registration of users.
1275c2aa98e2SPeter Wemm **
1276c2aa98e2SPeter Wemm **	If the hosts are found to be incompatible, an error
1277c2aa98e2SPeter Wemm **	message should be given using "usrerr" and an EX_ code
1278c2aa98e2SPeter Wemm **	should be returned.  You can also set to->q_status to
1279c2aa98e2SPeter Wemm **	a DSN-style status code.
1280c2aa98e2SPeter Wemm **
1281c2aa98e2SPeter Wemm **	EF_NO_BODY_RETN can be set in e->e_flags to suppress the
1282c2aa98e2SPeter Wemm **	body during the return-to-sender function; this should be done
1283c2aa98e2SPeter Wemm **	on huge messages.  This bit may already be set by the ESMTP
1284c2aa98e2SPeter Wemm **	protocol.
1285c2aa98e2SPeter Wemm **
1286c2aa98e2SPeter Wemm **	Parameters:
1287c2aa98e2SPeter Wemm **		to -- the person being sent to.
1288c2aa98e2SPeter Wemm **
1289c2aa98e2SPeter Wemm **	Returns:
1290c2aa98e2SPeter Wemm **		an exit status
1291c2aa98e2SPeter Wemm **
1292c2aa98e2SPeter Wemm **	Side Effects:
1293c2aa98e2SPeter Wemm **		none (unless you include the usrerr stuff)
1294c2aa98e2SPeter Wemm */
1295c2aa98e2SPeter Wemm 
1296c2aa98e2SPeter Wemm int
1297c2aa98e2SPeter Wemm checkcompat(to, e)
1298c2aa98e2SPeter Wemm 	register ADDRESS *to;
1299c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1300c2aa98e2SPeter Wemm {
1301c2aa98e2SPeter Wemm 	if (tTd(49, 1))
130212ed1c7cSGregory Neil Shapiro 		sm_dprintf("checkcompat(to=%s, from=%s)\n",
1303c2aa98e2SPeter Wemm 			to->q_paddr, e->e_from.q_paddr);
1304c2aa98e2SPeter Wemm 
1305c2aa98e2SPeter Wemm #ifdef EXAMPLE_CODE
1306c2aa98e2SPeter Wemm 	/* this code is intended as an example only */
1307c2aa98e2SPeter Wemm 	register STAB *s;
1308c2aa98e2SPeter Wemm 
1309c2aa98e2SPeter Wemm 	s = stab("arpa", ST_MAILER, ST_FIND);
1310c2aa98e2SPeter Wemm 	if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
1311c2aa98e2SPeter Wemm 	    to->q_mailer == s->s_mailer)
1312c2aa98e2SPeter Wemm 	{
1313c2aa98e2SPeter Wemm 		usrerr("553 No ARPA mail through this machine: see your system administration");
13143299c2f1SGregory Neil Shapiro 		/* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */
1315c2aa98e2SPeter Wemm 		to->q_status = "5.7.1";
13163299c2f1SGregory Neil Shapiro 		return EX_UNAVAILABLE;
1317c2aa98e2SPeter Wemm 	}
1318c2aa98e2SPeter Wemm #endif /* EXAMPLE_CODE */
13193299c2f1SGregory Neil Shapiro 	return EX_OK;
1320c2aa98e2SPeter Wemm }
13213299c2f1SGregory Neil Shapiro /*
1322c2aa98e2SPeter Wemm **  INIT_MD -- do machine dependent initializations
1323c2aa98e2SPeter Wemm **
1324c2aa98e2SPeter Wemm **	Systems that have global modes that should be set should do
1325c2aa98e2SPeter Wemm **	them here rather than in main.
1326c2aa98e2SPeter Wemm */
1327c2aa98e2SPeter Wemm 
1328c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1329c2aa98e2SPeter Wemm # include <compat.h>
13303299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1331c2aa98e2SPeter Wemm 
1332c2aa98e2SPeter Wemm #if SHARE_V1
1333c2aa98e2SPeter Wemm # include <shares.h>
13343299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
1335c2aa98e2SPeter Wemm 
1336c2aa98e2SPeter Wemm void
1337c2aa98e2SPeter Wemm init_md(argc, argv)
1338c2aa98e2SPeter Wemm 	int argc;
1339c2aa98e2SPeter Wemm 	char **argv;
1340c2aa98e2SPeter Wemm {
1341c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1342c2aa98e2SPeter Wemm 	setcompat(getcompat() | COMPAT_BSDPROT);
13433299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1344c2aa98e2SPeter Wemm 
1345c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
1346c2aa98e2SPeter Wemm 	init_md_sun();
13473299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
1348c2aa98e2SPeter Wemm 
1349c2aa98e2SPeter Wemm #if _CONVEX_SOURCE
1350c2aa98e2SPeter Wemm 	/* keep gethostby*() from stripping the local domain name */
1351c2aa98e2SPeter Wemm 	set_domain_trim_off();
13523299c2f1SGregory Neil Shapiro #endif /* _CONVEX_SOURCE */
1353c2aa98e2SPeter Wemm #ifdef __QNX__
1354c2aa98e2SPeter Wemm 	/*
1355c2aa98e2SPeter Wemm 	**  Due to QNX's network distributed nature, you can target a tcpip
1356c2aa98e2SPeter Wemm 	**  stack on a different node in the qnx network; this patch lets
1357c2aa98e2SPeter Wemm 	**  this feature work.  The __sock_locate() must be done before the
1358c2aa98e2SPeter Wemm 	**  environment is clear.
1359c2aa98e2SPeter Wemm 	*/
1360c2aa98e2SPeter Wemm 	__sock_locate();
13613299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
1362c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_)
1363c2aa98e2SPeter Wemm 	set_auth_parameters(argc, argv);
1364c2aa98e2SPeter Wemm 
1365c2aa98e2SPeter Wemm # ifdef _SCO_unix_
1366c2aa98e2SPeter Wemm 	/*
1367c2aa98e2SPeter Wemm 	**  This is required for highest security levels (the kernel
1368c2aa98e2SPeter Wemm 	**  won't let it call set*uid() or run setuid binaries without
1369c2aa98e2SPeter Wemm 	**  it).  It may be necessary on other SECUREWARE systems.
1370c2aa98e2SPeter Wemm 	*/
1371c2aa98e2SPeter Wemm 
1372c2aa98e2SPeter Wemm 	if (getluid() == -1)
1373c2aa98e2SPeter Wemm 		setluid(0);
13743299c2f1SGregory Neil Shapiro # endif /* _SCO_unix_ */
13753299c2f1SGregory Neil Shapiro #endif /* SECUREWARE || defined(_SCO_unix_) */
13763299c2f1SGregory Neil Shapiro 
1377c2aa98e2SPeter Wemm 
1378c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT
1379c2aa98e2SPeter Wemm 	VendorCode = VENDOR_DEFAULT;
13803299c2f1SGregory Neil Shapiro #else /* VENDOR_DEFAULT */
1381c2aa98e2SPeter Wemm 	VendorCode = VENDOR_BERKELEY;
13823299c2f1SGregory Neil Shapiro #endif /* VENDOR_DEFAULT */
1383c2aa98e2SPeter Wemm }
138412ed1c7cSGregory Neil Shapiro /*
1385c2aa98e2SPeter Wemm **  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
1386c2aa98e2SPeter Wemm **
1387c2aa98e2SPeter Wemm **	Called once, on startup.
1388c2aa98e2SPeter Wemm **
1389c2aa98e2SPeter Wemm **	Parameters:
1390c2aa98e2SPeter Wemm **		e -- the global envelope.
1391c2aa98e2SPeter Wemm **
1392c2aa98e2SPeter Wemm **	Returns:
1393c2aa98e2SPeter Wemm **		none.
1394c2aa98e2SPeter Wemm **
1395c2aa98e2SPeter Wemm **	Side Effects:
1396c2aa98e2SPeter Wemm **		vendor-dependent.
1397c2aa98e2SPeter Wemm */
1398c2aa98e2SPeter Wemm 
1399c2aa98e2SPeter Wemm void
1400c2aa98e2SPeter Wemm init_vendor_macros(e)
1401c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1402c2aa98e2SPeter Wemm {
1403c2aa98e2SPeter Wemm }
140412ed1c7cSGregory Neil Shapiro /*
1405c2aa98e2SPeter Wemm **  GETLA -- get the current load average
1406c2aa98e2SPeter Wemm **
1407c2aa98e2SPeter Wemm **	This code stolen from la.c.
1408c2aa98e2SPeter Wemm **
1409c2aa98e2SPeter Wemm **	Parameters:
1410c2aa98e2SPeter Wemm **		none.
1411c2aa98e2SPeter Wemm **
1412c2aa98e2SPeter Wemm **	Returns:
1413c2aa98e2SPeter Wemm **		The current load average as an integer.
1414c2aa98e2SPeter Wemm **
1415c2aa98e2SPeter Wemm **	Side Effects:
1416c2aa98e2SPeter Wemm **		none.
1417c2aa98e2SPeter Wemm */
1418c2aa98e2SPeter Wemm 
1419c2aa98e2SPeter Wemm /* try to guess what style of load average we have */
1420c2aa98e2SPeter Wemm #define LA_ZERO		1	/* always return load average as zero */
1421c2aa98e2SPeter Wemm #define LA_INT		2	/* read kmem for avenrun; interpret as long */
1422c2aa98e2SPeter Wemm #define LA_FLOAT	3	/* read kmem for avenrun; interpret as float */
1423c2aa98e2SPeter Wemm #define LA_SUBR		4	/* call getloadavg */
1424c2aa98e2SPeter Wemm #define LA_MACH		5	/* MACH load averages (as on NeXT boxes) */
1425c2aa98e2SPeter Wemm #define LA_SHORT	6	/* read kmem for avenrun; interpret as short */
1426c2aa98e2SPeter Wemm #define LA_PROCSTR	7	/* read string ("1.17") from /proc/loadavg */
1427c2aa98e2SPeter Wemm #define LA_READKSYM	8	/* SVR4: use MIOC_READKSYM ioctl call */
1428c2aa98e2SPeter Wemm #define LA_DGUX		9	/* special DGUX implementation */
1429c2aa98e2SPeter Wemm #define LA_HPUX		10	/* special HPUX implementation */
1430c2aa98e2SPeter Wemm #define LA_IRIX6	11	/* special IRIX 6.2 implementation */
1431c2aa98e2SPeter Wemm #define LA_KSTAT	12	/* special Solaris kstat(3k) implementation */
1432c2aa98e2SPeter Wemm #define LA_DEVSHORT	13	/* read short from a device */
1433c2aa98e2SPeter Wemm #define LA_ALPHAOSF	14	/* Digital UNIX (OSF/1 on Alpha) table() call */
1434c46d91b7SGregory Neil Shapiro #define LA_PSET		15	/* Solaris per-processor-set load average */
1435188b7d28SGregory Neil Shapiro #define LA_LONGLONG	17 /* read kmem for avenrun; interpret as long long */
1436c2aa98e2SPeter Wemm 
1437c2aa98e2SPeter Wemm /* do guesses based on general OS type */
1438c2aa98e2SPeter Wemm #ifndef LA_TYPE
1439c2aa98e2SPeter Wemm # define LA_TYPE	LA_ZERO
14403299c2f1SGregory Neil Shapiro #endif /* ! LA_TYPE */
1441c2aa98e2SPeter Wemm 
1442c2aa98e2SPeter Wemm #ifndef FSHIFT
1443c2aa98e2SPeter Wemm # if defined(unixpc)
1444c2aa98e2SPeter Wemm #  define FSHIFT	5
14453299c2f1SGregory Neil Shapiro # endif /* defined(unixpc) */
1446c2aa98e2SPeter Wemm 
1447c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX)
1448c2aa98e2SPeter Wemm #  define FSHIFT	10
14493299c2f1SGregory Neil Shapiro # endif /* defined(__alpha) || defined(IRIX) */
1450c2aa98e2SPeter Wemm 
14513299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1452c2aa98e2SPeter Wemm 
1453c2aa98e2SPeter Wemm #ifndef FSHIFT
1454c2aa98e2SPeter Wemm # define FSHIFT		8
14553299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1456c2aa98e2SPeter Wemm 
1457c2aa98e2SPeter Wemm #ifndef FSCALE
1458c2aa98e2SPeter Wemm # define FSCALE		(1 << FSHIFT)
14593299c2f1SGregory Neil Shapiro #endif /* ! FSCALE */
1460c2aa98e2SPeter Wemm 
1461c2aa98e2SPeter Wemm #ifndef LA_AVENRUN
1462c2aa98e2SPeter Wemm # ifdef SYSTEM5
1463c2aa98e2SPeter Wemm #  define LA_AVENRUN	"avenrun"
14643299c2f1SGregory Neil Shapiro # else /* SYSTEM5 */
1465c2aa98e2SPeter Wemm #  define LA_AVENRUN	"_avenrun"
14663299c2f1SGregory Neil Shapiro # endif /* SYSTEM5 */
14673299c2f1SGregory Neil Shapiro #endif /* ! LA_AVENRUN */
1468c2aa98e2SPeter Wemm 
1469c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */
1470c2aa98e2SPeter Wemm #ifndef _PATH_KMEM
1471c2aa98e2SPeter Wemm # define _PATH_KMEM	"/dev/kmem"
14723299c2f1SGregory Neil Shapiro #endif /* ! _PATH_KMEM */
1473c2aa98e2SPeter Wemm 
1474188b7d28SGregory Neil Shapiro #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
1475c2aa98e2SPeter Wemm 
1476c2aa98e2SPeter Wemm # include <nlist.h>
1477c2aa98e2SPeter Wemm 
1478c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */
1479c2aa98e2SPeter Wemm # ifndef _PATH_UNIX
1480c2aa98e2SPeter Wemm #  if defined(SYSTEM5)
1481c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/unix"
14823299c2f1SGregory Neil Shapiro #  else /* defined(SYSTEM5) */
1483c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/vmunix"
14843299c2f1SGregory Neil Shapiro #  endif /* defined(SYSTEM5) */
14853299c2f1SGregory Neil Shapiro # endif /* ! _PATH_UNIX */
1486c2aa98e2SPeter Wemm 
1487c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
1488c2aa98e2SPeter Wemm struct nlist	Nl[2];
14893299c2f1SGregory Neil Shapiro # else /* _AUX_SOURCE */
1490c2aa98e2SPeter Wemm struct nlist	Nl[] =
1491c2aa98e2SPeter Wemm {
1492c2aa98e2SPeter Wemm 	{ LA_AVENRUN },
1493c2aa98e2SPeter Wemm 	{ 0 },
1494c2aa98e2SPeter Wemm };
14953299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1496c2aa98e2SPeter Wemm # define X_AVENRUN	0
1497c2aa98e2SPeter Wemm 
149812ed1c7cSGregory Neil Shapiro int
1499c2aa98e2SPeter Wemm getla()
1500c2aa98e2SPeter Wemm {
150112ed1c7cSGregory Neil Shapiro 	int j;
1502c2aa98e2SPeter Wemm 	static int kmem = -1;
1503c2aa98e2SPeter Wemm # if LA_TYPE == LA_INT
1504c2aa98e2SPeter Wemm 	long avenrun[3];
15053299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_INT */
1506c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
1507c2aa98e2SPeter Wemm 	short avenrun[3];
1508188b7d28SGregory Neil Shapiro #  else
1509188b7d28SGregory Neil Shapiro #   if LA_TYPE == LA_LONGLONG
1510188b7d28SGregory Neil Shapiro 	long long avenrun[3];
1511188b7d28SGregory Neil Shapiro #   else /* LA_TYPE == LA_LONGLONG */
1512c2aa98e2SPeter Wemm 	double avenrun[3];
1513188b7d28SGregory Neil Shapiro #   endif /* LA_TYPE == LA_LONGLONG */
15143299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
15153299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_INT */
1516c2aa98e2SPeter Wemm 	extern off_t lseek();
1517c2aa98e2SPeter Wemm 
1518c2aa98e2SPeter Wemm 	if (kmem < 0)
1519c2aa98e2SPeter Wemm 	{
1520c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
152112ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN,
15223299c2f1SGregory Neil Shapiro 			       sizeof Nl[X_AVENRUN].n_name);
1523c2aa98e2SPeter Wemm 		Nl[1].n_name[0] = '\0';
15243299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1525c2aa98e2SPeter Wemm 
1526c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
1527c2aa98e2SPeter Wemm 		if (knlist(Nl, 1, sizeof Nl[0]) < 0)
15283299c2f1SGregory Neil Shapiro # else /* defined(_AIX3) || defined(_AIX4) */
1529c2aa98e2SPeter Wemm 		if (nlist(_PATH_UNIX, Nl) < 0)
15303299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
1531c2aa98e2SPeter Wemm 		{
1532c2aa98e2SPeter Wemm 			if (tTd(3, 1))
153312ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
153412ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15353299c2f1SGregory Neil Shapiro 			return -1;
1536c2aa98e2SPeter Wemm 		}
1537c2aa98e2SPeter Wemm 		if (Nl[X_AVENRUN].n_value == 0)
1538c2aa98e2SPeter Wemm 		{
1539c2aa98e2SPeter Wemm 			if (tTd(3, 1))
154012ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s, %s) ==> 0\n",
1541c2aa98e2SPeter Wemm 					_PATH_UNIX, LA_AVENRUN);
15423299c2f1SGregory Neil Shapiro 			return -1;
1543c2aa98e2SPeter Wemm 		}
1544c2aa98e2SPeter Wemm # ifdef NAMELISTMASK
1545c2aa98e2SPeter Wemm 		Nl[X_AVENRUN].n_value &= NAMELISTMASK;
15463299c2f1SGregory Neil Shapiro # endif /* NAMELISTMASK */
1547c2aa98e2SPeter Wemm 
1548c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1549c2aa98e2SPeter Wemm 		if (kmem < 0)
1550c2aa98e2SPeter Wemm 		{
1551c2aa98e2SPeter Wemm 			if (tTd(3, 1))
155212ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
155312ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15543299c2f1SGregory Neil Shapiro 			return -1;
1555c2aa98e2SPeter Wemm 		}
155612ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
155712ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
155812ed1c7cSGregory Neil Shapiro 		{
155912ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
156012ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
156112ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
156212ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
156312ed1c7cSGregory Neil Shapiro 			kmem = -1;
156412ed1c7cSGregory Neil Shapiro 			return -1;
156512ed1c7cSGregory Neil Shapiro 		}
1566c2aa98e2SPeter Wemm 	}
1567c2aa98e2SPeter Wemm 	if (tTd(3, 20))
156812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: symbol address = %#lx\n",
156912ed1c7cSGregory Neil Shapiro 			(unsigned long) Nl[X_AVENRUN].n_value);
1570c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
1571c2aa98e2SPeter Wemm 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
1572c2aa98e2SPeter Wemm 	{
1573c2aa98e2SPeter Wemm 		/* thank you Ian */
1574c2aa98e2SPeter Wemm 		if (tTd(3, 1))
157512ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
157612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
15773299c2f1SGregory Neil Shapiro 		return -1;
1578c2aa98e2SPeter Wemm 	}
1579188b7d28SGregory Neil Shapiro # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
1580c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1581c2aa98e2SPeter Wemm 	{
1582c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
158312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1584c2aa98e2SPeter Wemm 		if (tTd(3, 15))
158512ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
15863299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
1587188b7d28SGregory Neil Shapiro #   if LA_TYPE == LA_LONGLONG
1588188b7d28SGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %lld", avenrun[0]);
1589188b7d28SGregory Neil Shapiro 		if (tTd(3, 15))
1590188b7d28SGregory Neil Shapiro 			sm_dprintf(", %lld, %lld", avenrun[1], avenrun[2]);
1591188b7d28SGregory Neil Shapiro #   else /* LA_TYPE == LA_LONGLONG */
159212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", avenrun[0]);
1593c2aa98e2SPeter Wemm 		if (tTd(3, 15))
159412ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]);
1595188b7d28SGregory Neil Shapiro #   endif /* LA_TYPE == LA_LONGLONG */
15963299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
159712ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1598c2aa98e2SPeter Wemm 	}
1599c2aa98e2SPeter Wemm 	if (tTd(3, 1))
160012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
16013299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1602c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1603188b7d28SGregory Neil Shapiro # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1604c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1605c2aa98e2SPeter Wemm 	{
160612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %g", avenrun[0]);
1607c2aa98e2SPeter Wemm 		if (tTd(3, 15))
160812ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %g, %g", avenrun[1], avenrun[2]);
160912ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1610c2aa98e2SPeter Wemm 	}
1611c2aa98e2SPeter Wemm 	if (tTd(3, 1))
161212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1613c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1614188b7d28SGregory Neil Shapiro # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1615c2aa98e2SPeter Wemm }
1616c2aa98e2SPeter Wemm 
1617188b7d28SGregory Neil Shapiro #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1618c2aa98e2SPeter Wemm 
1619c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM
1620c2aa98e2SPeter Wemm 
1621c2aa98e2SPeter Wemm # include <sys/ksym.h>
1622c2aa98e2SPeter Wemm 
162312ed1c7cSGregory Neil Shapiro int
1624c2aa98e2SPeter Wemm getla()
1625c2aa98e2SPeter Wemm {
162612ed1c7cSGregory Neil Shapiro 	int j;
1627c2aa98e2SPeter Wemm 	static int kmem = -1;
1628c2aa98e2SPeter Wemm 	long avenrun[3];
1629c2aa98e2SPeter Wemm 	struct mioc_rksym mirk;
1630c2aa98e2SPeter Wemm 
1631c2aa98e2SPeter Wemm 	if (kmem < 0)
1632c2aa98e2SPeter Wemm 	{
1633c2aa98e2SPeter Wemm 		kmem = open("/dev/kmem", 0, 0);
1634c2aa98e2SPeter Wemm 		if (kmem < 0)
1635c2aa98e2SPeter Wemm 		{
1636c2aa98e2SPeter Wemm 			if (tTd(3, 1))
163712ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
163812ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
16393299c2f1SGregory Neil Shapiro 			return -1;
1640c2aa98e2SPeter Wemm 		}
164112ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
164212ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
164312ed1c7cSGregory Neil Shapiro 		{
164412ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
164512ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
164612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
164712ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
164812ed1c7cSGregory Neil Shapiro 			kmem = -1;
164912ed1c7cSGregory Neil Shapiro 			return -1;
165012ed1c7cSGregory Neil Shapiro 		}
1651c2aa98e2SPeter Wemm 	}
1652c2aa98e2SPeter Wemm 	mirk.mirk_symname = LA_AVENRUN;
1653c2aa98e2SPeter Wemm 	mirk.mirk_buf = avenrun;
1654c2aa98e2SPeter Wemm 	mirk.mirk_buflen = sizeof(avenrun);
1655c2aa98e2SPeter Wemm 	if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
1656c2aa98e2SPeter Wemm 	{
1657c2aa98e2SPeter Wemm 		if (tTd(3, 1))
165812ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
165912ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1660c2aa98e2SPeter Wemm 		return -1;
1661c2aa98e2SPeter Wemm 	}
1662c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1663c2aa98e2SPeter Wemm 	{
166412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1665c2aa98e2SPeter Wemm 		if (tTd(3, 15))
166612ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
166712ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1668c2aa98e2SPeter Wemm 	}
1669c2aa98e2SPeter Wemm 	if (tTd(3, 1))
167012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
16713299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1672c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1673c2aa98e2SPeter Wemm }
1674c2aa98e2SPeter Wemm 
1675c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */
1676c2aa98e2SPeter Wemm 
1677c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX
1678c2aa98e2SPeter Wemm 
1679c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h>
1680c2aa98e2SPeter Wemm 
168112ed1c7cSGregory Neil Shapiro int
1682c2aa98e2SPeter Wemm getla()
1683c2aa98e2SPeter Wemm {
1684c2aa98e2SPeter Wemm 	struct dg_sys_info_load_info load_info;
1685c2aa98e2SPeter Wemm 
1686c2aa98e2SPeter Wemm 	dg_sys_info((long *)&load_info,
1687c2aa98e2SPeter Wemm 		DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
1688c2aa98e2SPeter Wemm 
1689c2aa98e2SPeter Wemm 	if (tTd(3, 1))
169012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5));
1691c2aa98e2SPeter Wemm 
1692c2aa98e2SPeter Wemm 	return ((int) (load_info.one_minute + 0.5));
1693c2aa98e2SPeter Wemm }
1694c2aa98e2SPeter Wemm 
1695c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */
1696c2aa98e2SPeter Wemm 
1697c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX
1698c2aa98e2SPeter Wemm 
1699c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */
1700c2aa98e2SPeter Wemm struct pst_dynamic;
1701c2aa98e2SPeter Wemm struct pst_status;
1702c2aa98e2SPeter Wemm struct pst_static;
1703c2aa98e2SPeter Wemm struct pst_vminfo;
1704c2aa98e2SPeter Wemm struct pst_diskinfo;
1705c2aa98e2SPeter Wemm struct pst_processor;
1706c2aa98e2SPeter Wemm struct pst_lv;
1707c2aa98e2SPeter Wemm struct pst_swapinfo;
1708c2aa98e2SPeter Wemm 
1709c2aa98e2SPeter Wemm # include <sys/param.h>
1710c2aa98e2SPeter Wemm # include <sys/pstat.h>
1711c2aa98e2SPeter Wemm 
171212ed1c7cSGregory Neil Shapiro int
1713c2aa98e2SPeter Wemm getla()
1714c2aa98e2SPeter Wemm {
1715c2aa98e2SPeter Wemm 	struct pst_dynamic pstd;
1716c2aa98e2SPeter Wemm 
1717c2aa98e2SPeter Wemm 	if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
1718c2aa98e2SPeter Wemm 			     (size_t) 1, 0) == -1)
1719c2aa98e2SPeter Wemm 		return 0;
1720c2aa98e2SPeter Wemm 
1721c2aa98e2SPeter Wemm 	if (tTd(3, 1))
172212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
1723c2aa98e2SPeter Wemm 
1724c2aa98e2SPeter Wemm 	return (int) (pstd.psd_avg_1_min + 0.5);
1725c2aa98e2SPeter Wemm }
1726c2aa98e2SPeter Wemm 
1727c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */
1728c2aa98e2SPeter Wemm 
1729c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR
1730c2aa98e2SPeter Wemm 
173112ed1c7cSGregory Neil Shapiro int
1732c2aa98e2SPeter Wemm getla()
1733c2aa98e2SPeter Wemm {
1734c2aa98e2SPeter Wemm 	double avenrun[3];
1735c2aa98e2SPeter Wemm 
1736c2aa98e2SPeter Wemm 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
1737c2aa98e2SPeter Wemm 	{
1738c2aa98e2SPeter Wemm 		if (tTd(3, 1))
173912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: getloadavg failed: %s",
174012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
17413299c2f1SGregory Neil Shapiro 		return -1;
1742c2aa98e2SPeter Wemm 	}
1743c2aa98e2SPeter Wemm 	if (tTd(3, 1))
174412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1745c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1746c2aa98e2SPeter Wemm }
1747c2aa98e2SPeter Wemm 
1748c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */
1749c2aa98e2SPeter Wemm 
1750c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH
1751c2aa98e2SPeter Wemm 
1752c2aa98e2SPeter Wemm /*
1753c2aa98e2SPeter Wemm **  This has been tested on NEXTSTEP release 2.1/3.X.
1754c2aa98e2SPeter Wemm */
1755c2aa98e2SPeter Wemm 
1756c2aa98e2SPeter Wemm # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
1757c2aa98e2SPeter Wemm #  include <mach/mach.h>
17583299c2f1SGregory Neil Shapiro # else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1759c2aa98e2SPeter Wemm #  include <mach.h>
17603299c2f1SGregory Neil Shapiro # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1761c2aa98e2SPeter Wemm 
176212ed1c7cSGregory Neil Shapiro int
1763c2aa98e2SPeter Wemm getla()
1764c2aa98e2SPeter Wemm {
1765c2aa98e2SPeter Wemm 	processor_set_t default_set;
1766c2aa98e2SPeter Wemm 	kern_return_t error;
1767c2aa98e2SPeter Wemm 	unsigned int info_count;
1768c2aa98e2SPeter Wemm 	struct processor_set_basic_info info;
1769c2aa98e2SPeter Wemm 	host_t host;
1770c2aa98e2SPeter Wemm 
1771c2aa98e2SPeter Wemm 	error = processor_set_default(host_self(), &default_set);
1772c2aa98e2SPeter Wemm 	if (error != KERN_SUCCESS)
1773c2aa98e2SPeter Wemm 	{
1774c2aa98e2SPeter Wemm 		if (tTd(3, 1))
177512ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_default failed: %s",
177612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1777c2aa98e2SPeter Wemm 		return -1;
1778c2aa98e2SPeter Wemm 	}
1779c2aa98e2SPeter Wemm 	info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
1780c2aa98e2SPeter Wemm 	if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
1781c2aa98e2SPeter Wemm 			       &host, (processor_set_info_t)&info,
1782c2aa98e2SPeter Wemm 			       &info_count) != KERN_SUCCESS)
1783c2aa98e2SPeter Wemm 	{
1784c2aa98e2SPeter Wemm 		if (tTd(3, 1))
178512ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_info failed: %s",
178612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1787c2aa98e2SPeter Wemm 		return -1;
1788c2aa98e2SPeter Wemm 	}
1789c2aa98e2SPeter Wemm 	if (tTd(3, 1))
179012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
17913299c2f1SGregory Neil Shapiro 			(int) ((info.load_average + (LOAD_SCALE / 2)) /
17923299c2f1SGregory Neil Shapiro 			       LOAD_SCALE));
1793c2aa98e2SPeter Wemm 	return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
1794c2aa98e2SPeter Wemm }
1795c2aa98e2SPeter Wemm 
1796c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */
1797c2aa98e2SPeter Wemm 
1798c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR
179912ed1c7cSGregory Neil Shapiro # if SM_CONF_BROKEN_STRTOD
180012ed1c7cSGregory Neil Shapiro 	ERROR: This OS has most likely a broken strtod() implemenentation.
180112ed1c7cSGregory Neil Shapiro 	ERROR: The function is required for getla().
180212ed1c7cSGregory Neil Shapiro 	ERROR: Check the compilation options _LA_PROCSTR and
180312ed1c7cSGregory Neil Shapiro 	ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _).
180412ed1c7cSGregory Neil Shapiro # endif /* SM_CONF_BROKEN_STRTOD */
1805c2aa98e2SPeter Wemm 
1806c2aa98e2SPeter Wemm /*
1807c2aa98e2SPeter Wemm **  Read /proc/loadavg for the load average.  This is assumed to be
1808c2aa98e2SPeter Wemm **  in a format like "0.15 0.12 0.06".
1809c2aa98e2SPeter Wemm **
1810c2aa98e2SPeter Wemm **	Initially intended for Linux.  This has been in the kernel
1811c2aa98e2SPeter Wemm **	since at least 0.99.15.
1812c2aa98e2SPeter Wemm */
1813c2aa98e2SPeter Wemm 
1814c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG
1815c2aa98e2SPeter Wemm #  define _PATH_LOADAVG	"/proc/loadavg"
18163299c2f1SGregory Neil Shapiro # endif /* ! _PATH_LOADAVG */
1817c2aa98e2SPeter Wemm 
181812ed1c7cSGregory Neil Shapiro int
1819c2aa98e2SPeter Wemm getla()
1820c2aa98e2SPeter Wemm {
1821c2aa98e2SPeter Wemm 	double avenrun;
1822c2aa98e2SPeter Wemm 	register int result;
182312ed1c7cSGregory Neil Shapiro 	SM_FILE_T *fp;
1824c2aa98e2SPeter Wemm 
182512ed1c7cSGregory Neil Shapiro 	fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY,
182612ed1c7cSGregory Neil Shapiro 			NULL);
1827c2aa98e2SPeter Wemm 	if (fp == NULL)
1828c2aa98e2SPeter Wemm 	{
1829c2aa98e2SPeter Wemm 		if (tTd(3, 1))
183012ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_open(%s): %s\n",
183112ed1c7cSGregory Neil Shapiro 				   _PATH_LOADAVG, sm_errstring(errno));
1832c2aa98e2SPeter Wemm 		return -1;
1833c2aa98e2SPeter Wemm 	}
183412ed1c7cSGregory Neil Shapiro 	result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun);
183512ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(fp, SM_TIME_DEFAULT);
1836c2aa98e2SPeter Wemm 	if (result != 1)
1837c2aa98e2SPeter Wemm 	{
1838c2aa98e2SPeter Wemm 		if (tTd(3, 1))
183912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_fscanf() = %d: %s\n",
184012ed1c7cSGregory Neil Shapiro 				   result, sm_errstring(errno));
1841c2aa98e2SPeter Wemm 		return -1;
1842c2aa98e2SPeter Wemm 	}
1843c2aa98e2SPeter Wemm 
1844c2aa98e2SPeter Wemm 	if (tTd(3, 1))
184512ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla(): %.2f\n", avenrun);
1846c2aa98e2SPeter Wemm 
1847c2aa98e2SPeter Wemm 	return ((int) (avenrun + 0.5));
1848c2aa98e2SPeter Wemm }
1849c2aa98e2SPeter Wemm 
1850c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */
1851c2aa98e2SPeter Wemm 
1852c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6
18533299c2f1SGregory Neil Shapiro 
1854c2aa98e2SPeter Wemm # include <sys/sysmp.h>
1855c2aa98e2SPeter Wemm 
1856bfb62e91SGregory Neil Shapiro # ifdef _UNICOSMP
1857bfb62e91SGregory Neil Shapiro #  define CAST_SYSMP(x)	(x)
1858bfb62e91SGregory Neil Shapiro # else /* _UNICOSMP */
1859bfb62e91SGregory Neil Shapiro #  define CAST_SYSMP(x)	((x) & 0x7fffffff)
1860bfb62e91SGregory Neil Shapiro # endif /* _UNICOSMP */
1861bfb62e91SGregory Neil Shapiro 
186212ed1c7cSGregory Neil Shapiro int
186312ed1c7cSGregory Neil Shapiro getla(void)
1864c2aa98e2SPeter Wemm {
186512ed1c7cSGregory Neil Shapiro 	int j;
1866c2aa98e2SPeter Wemm 	static int kmem = -1;
1867c2aa98e2SPeter Wemm 	int avenrun[3];
1868c2aa98e2SPeter Wemm 
1869c2aa98e2SPeter Wemm 	if (kmem < 0)
1870c2aa98e2SPeter Wemm 	{
1871c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1872c2aa98e2SPeter Wemm 		if (kmem < 0)
1873c2aa98e2SPeter Wemm 		{
1874c2aa98e2SPeter Wemm 			if (tTd(3, 1))
187512ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM,
187612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
1877c2aa98e2SPeter Wemm 			return -1;
1878c2aa98e2SPeter Wemm 		}
187912ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
188012ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
188112ed1c7cSGregory Neil Shapiro 		{
188212ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
188312ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
188412ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
188512ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
188612ed1c7cSGregory Neil Shapiro 			kmem = -1;
188712ed1c7cSGregory Neil Shapiro 			return -1;
188812ed1c7cSGregory Neil Shapiro 		}
1889c2aa98e2SPeter Wemm 	}
1890c2aa98e2SPeter Wemm 
1891bfb62e91SGregory Neil Shapiro 	if (lseek(kmem, CAST_SYSMP(sysmp(MP_KERNADDR, MPKA_AVENRUN)), SEEK_SET)
1892bfb62e91SGregory Neil Shapiro 		== -1 ||
1893c2aa98e2SPeter Wemm 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
1894c2aa98e2SPeter Wemm 	{
1895c2aa98e2SPeter Wemm 		if (tTd(3, 1))
189612ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
189712ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1898c2aa98e2SPeter Wemm 		return -1;
1899c2aa98e2SPeter Wemm 	}
1900c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1901c2aa98e2SPeter Wemm 	{
190212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]);
1903c2aa98e2SPeter Wemm 		if (tTd(3, 15))
190412ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld",
1905c2aa98e2SPeter Wemm 				(long int) avenrun[1], (long int) avenrun[2]);
190612ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1907c2aa98e2SPeter Wemm 	}
1908c2aa98e2SPeter Wemm 
1909c2aa98e2SPeter Wemm 	if (tTd(3, 1))
191012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
19113299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1912c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1913c2aa98e2SPeter Wemm 
1914c2aa98e2SPeter Wemm }
19153299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_IRIX6 */
1916c2aa98e2SPeter Wemm 
1917c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT
1918c2aa98e2SPeter Wemm 
1919c2aa98e2SPeter Wemm # include <kstat.h>
1920c2aa98e2SPeter Wemm 
192112ed1c7cSGregory Neil Shapiro int
1922c2aa98e2SPeter Wemm getla()
1923c2aa98e2SPeter Wemm {
1924c2aa98e2SPeter Wemm 	static kstat_ctl_t *kc = NULL;
1925c2aa98e2SPeter Wemm 	static kstat_t *ksp = NULL;
1926c2aa98e2SPeter Wemm 	kstat_named_t *ksn;
1927c2aa98e2SPeter Wemm 	int la;
1928c2aa98e2SPeter Wemm 
1929c2aa98e2SPeter Wemm 	if (kc == NULL)		/* if not initialized before */
1930c2aa98e2SPeter Wemm 		kc = kstat_open();
1931c2aa98e2SPeter Wemm 	if (kc == NULL)
1932c2aa98e2SPeter Wemm 	{
1933c2aa98e2SPeter Wemm 		if (tTd(3, 1))
193412ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_open(): %s\n",
193512ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1936c2aa98e2SPeter Wemm 		return -1;
1937c2aa98e2SPeter Wemm 	}
1938c2aa98e2SPeter Wemm 	if (ksp == NULL)
1939c2aa98e2SPeter Wemm 		ksp = kstat_lookup(kc, "unix", 0, "system_misc");
1940c2aa98e2SPeter Wemm 	if (ksp == NULL)
1941c2aa98e2SPeter Wemm 	{
1942c2aa98e2SPeter Wemm 		if (tTd(3, 1))
194312ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_lookup(): %s\n",
194412ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1945c2aa98e2SPeter Wemm 		return -1;
1946c2aa98e2SPeter Wemm 	}
1947c2aa98e2SPeter Wemm 	if (kstat_read(kc, ksp, NULL) < 0)
1948c2aa98e2SPeter Wemm 	{
1949c2aa98e2SPeter Wemm 		if (tTd(3, 1))
195012ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_read(): %s\n",
195112ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1952c2aa98e2SPeter Wemm 		return -1;
1953c2aa98e2SPeter Wemm 	}
1954c2aa98e2SPeter Wemm 	ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
1955c2aa98e2SPeter Wemm 	la = ((double) ksn->value.ul + FSCALE/2) / FSCALE;
1956c2aa98e2SPeter Wemm 	/* kstat_close(kc); /o do not close for fast access */
1957c2aa98e2SPeter Wemm 	return la;
1958c2aa98e2SPeter Wemm }
1959c2aa98e2SPeter Wemm 
1960c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */
1961c2aa98e2SPeter Wemm 
1962c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT
1963c2aa98e2SPeter Wemm 
1964c2aa98e2SPeter Wemm /*
1965c2aa98e2SPeter Wemm **  Read /dev/table/avenrun for the load average.  This should contain
1966c2aa98e2SPeter Wemm **  three shorts for the 1, 5, and 15 minute loads.  We only read the
1967c2aa98e2SPeter Wemm **  first, since that's all we care about.
1968c2aa98e2SPeter Wemm **
1969c2aa98e2SPeter Wemm **	Intended for SCO OpenServer 5.
1970c2aa98e2SPeter Wemm */
1971c2aa98e2SPeter Wemm 
1972c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN
1973c2aa98e2SPeter Wemm #  define _PATH_AVENRUN	"/dev/table/avenrun"
19743299c2f1SGregory Neil Shapiro # endif /* ! _PATH_AVENRUN */
1975c2aa98e2SPeter Wemm 
197612ed1c7cSGregory Neil Shapiro int
1977c2aa98e2SPeter Wemm getla()
1978c2aa98e2SPeter Wemm {
1979c2aa98e2SPeter Wemm 	static int afd = -1;
1980c2aa98e2SPeter Wemm 	short avenrun;
1981c2aa98e2SPeter Wemm 	int loadav;
1982c2aa98e2SPeter Wemm 	int r;
1983c2aa98e2SPeter Wemm 
1984c2aa98e2SPeter Wemm 	errno = EBADF;
1985c2aa98e2SPeter Wemm 
1986c2aa98e2SPeter Wemm 	if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
1987c2aa98e2SPeter Wemm 	{
1988c2aa98e2SPeter Wemm 		if (errno != EBADF)
1989c2aa98e2SPeter Wemm 			return -1;
1990c2aa98e2SPeter Wemm 		afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
1991c2aa98e2SPeter Wemm 		if (afd < 0)
1992c2aa98e2SPeter Wemm 		{
1993c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
199412ed1c7cSGregory Neil Shapiro 				"can't open %s: %s",
199512ed1c7cSGregory Neil Shapiro 				_PATH_AVENRUN, sm_errstring(errno));
1996c2aa98e2SPeter Wemm 			return -1;
1997c2aa98e2SPeter Wemm 		}
1998c2aa98e2SPeter Wemm 	}
1999c2aa98e2SPeter Wemm 
2000c2aa98e2SPeter Wemm 	r = read(afd, &avenrun, sizeof avenrun);
2001c2aa98e2SPeter Wemm 
2002c2aa98e2SPeter Wemm 	if (tTd(3, 5))
200312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d\n", avenrun);
2004c2aa98e2SPeter Wemm 	loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
2005c2aa98e2SPeter Wemm 	if (tTd(3, 1))
200612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", loadav);
2007c2aa98e2SPeter Wemm 	return loadav;
2008c2aa98e2SPeter Wemm }
2009c2aa98e2SPeter Wemm 
2010c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */
2011c2aa98e2SPeter Wemm 
2012c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF
2013c2aa98e2SPeter Wemm struct rtentry;
2014c2aa98e2SPeter Wemm struct mbuf;
2015c2aa98e2SPeter Wemm # include <sys/table.h>
2016c2aa98e2SPeter Wemm 
201712ed1c7cSGregory Neil Shapiro int
201812ed1c7cSGregory Neil Shapiro getla()
2019c2aa98e2SPeter Wemm {
2020c2aa98e2SPeter Wemm 	int ave = 0;
2021c2aa98e2SPeter Wemm 	struct tbl_loadavg tab;
2022c2aa98e2SPeter Wemm 
2023c2aa98e2SPeter Wemm 	if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
2024c2aa98e2SPeter Wemm 	{
2025c2aa98e2SPeter Wemm 		if (tTd(3, 1))
202612ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: table %s\n", sm_errstring(errno));
20273299c2f1SGregory Neil Shapiro 		return -1;
2028c2aa98e2SPeter Wemm 	}
2029c2aa98e2SPeter Wemm 
2030c2aa98e2SPeter Wemm 	if (tTd(3, 1))
203112ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: scale = %d\n", tab.tl_lscale);
2032c2aa98e2SPeter Wemm 
2033c2aa98e2SPeter Wemm 	if (tab.tl_lscale)
20343299c2f1SGregory Neil Shapiro 		ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) /
20353299c2f1SGregory Neil Shapiro 		       tab.tl_lscale);
2036c2aa98e2SPeter Wemm 	else
20373299c2f1SGregory Neil Shapiro 		ave = (int) (tab.tl_avenrun.d[2] + 0.5);
2038c2aa98e2SPeter Wemm 
2039c2aa98e2SPeter Wemm 	if (tTd(3, 1))
204012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", ave);
2041c2aa98e2SPeter Wemm 
2042c2aa98e2SPeter Wemm 	return ave;
2043c2aa98e2SPeter Wemm }
2044c2aa98e2SPeter Wemm 
20453299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_ALPHAOSF */
2046c2aa98e2SPeter Wemm 
2047c46d91b7SGregory Neil Shapiro #if LA_TYPE == LA_PSET
2048c46d91b7SGregory Neil Shapiro 
204912ed1c7cSGregory Neil Shapiro int
2050c46d91b7SGregory Neil Shapiro getla()
2051c46d91b7SGregory Neil Shapiro {
2052c46d91b7SGregory Neil Shapiro 	double avenrun[3];
2053c46d91b7SGregory Neil Shapiro 
2054c46d91b7SGregory Neil Shapiro 	if (pset_getloadavg(PS_MYID, avenrun,
2055c46d91b7SGregory Neil Shapiro 			    sizeof(avenrun) / sizeof(avenrun[0])) < 0)
2056c46d91b7SGregory Neil Shapiro 	{
2057c46d91b7SGregory Neil Shapiro 		if (tTd(3, 1))
205812ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: pset_getloadavg failed: %s",
205912ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
2060c46d91b7SGregory Neil Shapiro 		return -1;
2061c46d91b7SGregory Neil Shapiro 	}
2062c46d91b7SGregory Neil Shapiro 	if (tTd(3, 1))
206312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
2064c46d91b7SGregory Neil Shapiro 	return ((int) (avenrun[0] + 0.5));
2065c46d91b7SGregory Neil Shapiro }
2066c46d91b7SGregory Neil Shapiro 
2067c46d91b7SGregory Neil Shapiro #endif /* LA_TYPE == LA_PSET */
2068c46d91b7SGregory Neil Shapiro 
2069c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO
2070c2aa98e2SPeter Wemm 
207112ed1c7cSGregory Neil Shapiro int
2072c2aa98e2SPeter Wemm getla()
2073c2aa98e2SPeter Wemm {
2074c2aa98e2SPeter Wemm 	if (tTd(3, 1))
207512ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: ZERO\n");
20763299c2f1SGregory Neil Shapiro 	return 0;
2077c2aa98e2SPeter Wemm }
2078c2aa98e2SPeter Wemm 
2079c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */
2080c2aa98e2SPeter Wemm 
2081c2aa98e2SPeter Wemm /*
2082c2aa98e2SPeter Wemm  * Copyright 1989 Massachusetts Institute of Technology
2083c2aa98e2SPeter Wemm  *
2084c2aa98e2SPeter Wemm  * Permission to use, copy, modify, distribute, and sell this software and its
2085c2aa98e2SPeter Wemm  * documentation for any purpose is hereby granted without fee, provided that
2086c2aa98e2SPeter Wemm  * the above copyright notice appear in all copies and that both that
2087c2aa98e2SPeter Wemm  * copyright notice and this permission notice appear in supporting
2088c2aa98e2SPeter Wemm  * documentation, and that the name of M.I.T. not be used in advertising or
2089c2aa98e2SPeter Wemm  * publicity pertaining to distribution of the software without specific,
2090c2aa98e2SPeter Wemm  * written prior permission.  M.I.T. makes no representations about the
2091c2aa98e2SPeter Wemm  * suitability of this software for any purpose.  It is provided "as is"
2092c2aa98e2SPeter Wemm  * without express or implied warranty.
2093c2aa98e2SPeter Wemm  *
2094c2aa98e2SPeter Wemm  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
2095c2aa98e2SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
2096c2aa98e2SPeter Wemm  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2097c2aa98e2SPeter Wemm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2098c2aa98e2SPeter Wemm  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2099c2aa98e2SPeter Wemm  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2100c2aa98e2SPeter Wemm  *
2101c2aa98e2SPeter Wemm  * Authors:  Many and varied...
2102c2aa98e2SPeter Wemm  */
2103c2aa98e2SPeter Wemm 
2104c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */
2105c2aa98e2SPeter Wemm #ifndef lint
210612ed1c7cSGregory Neil Shapiro SM_UNUSED(static char  rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
2107c2aa98e2SPeter Wemm #endif /* ! lint */
2108c2aa98e2SPeter Wemm 
2109c2aa98e2SPeter Wemm #ifdef apollo
2110c2aa98e2SPeter Wemm # undef volatile
2111c2aa98e2SPeter Wemm # include <apollo/base.h>
2112c2aa98e2SPeter Wemm 
2113c2aa98e2SPeter Wemm /* ARGSUSED */
2114c2aa98e2SPeter Wemm int getloadavg( call_data )
2115c2aa98e2SPeter Wemm 	caddr_t call_data;	/* pointer to (double) return value */
2116c2aa98e2SPeter Wemm {
2117c2aa98e2SPeter Wemm 	double *avenrun = (double *) call_data;
2118c2aa98e2SPeter Wemm 	int i;
2119c2aa98e2SPeter Wemm 	status_$t      st;
2120c2aa98e2SPeter Wemm 	long loadav[3];
212112ed1c7cSGregory Neil Shapiro 
2122c2aa98e2SPeter Wemm 	proc1_$get_loadav(loadav, &st);
2123c2aa98e2SPeter Wemm 	*avenrun = loadav[0] / (double) (1 << 16);
21243299c2f1SGregory Neil Shapiro 	return 0;
2125c2aa98e2SPeter Wemm }
2126c2aa98e2SPeter Wemm #endif /* apollo */
212712ed1c7cSGregory Neil Shapiro /*
212812ed1c7cSGregory Neil Shapiro **  SM_GETLA -- get the current load average
21293299c2f1SGregory Neil Shapiro **
21303299c2f1SGregory Neil Shapiro **	Parameters:
213112ed1c7cSGregory Neil Shapiro **		none
21323299c2f1SGregory Neil Shapiro **
21333299c2f1SGregory Neil Shapiro **	Returns:
213412ed1c7cSGregory Neil Shapiro **		none
21353299c2f1SGregory Neil Shapiro **
21363299c2f1SGregory Neil Shapiro **	Side Effects:
213712ed1c7cSGregory Neil Shapiro **		Set CurrentLA to the current load average.
213812ed1c7cSGregory Neil Shapiro **		Set {load_avg} in GlobalMacros to the current load average.
21393299c2f1SGregory Neil Shapiro */
21403299c2f1SGregory Neil Shapiro 
214112ed1c7cSGregory Neil Shapiro void
214212ed1c7cSGregory Neil Shapiro sm_getla()
21433299c2f1SGregory Neil Shapiro {
21443299c2f1SGregory Neil Shapiro 	char labuf[8];
21453299c2f1SGregory Neil Shapiro 
214612ed1c7cSGregory Neil Shapiro 	CurrentLA = getla();
214712ed1c7cSGregory Neil Shapiro 	(void) sm_snprintf(labuf, sizeof labuf, "%d", CurrentLA);
214812ed1c7cSGregory Neil Shapiro 	macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf);
21493299c2f1SGregory Neil Shapiro }
215012ed1c7cSGregory Neil Shapiro /*
2151c2aa98e2SPeter Wemm **  SHOULDQUEUE -- should this message be queued or sent?
2152c2aa98e2SPeter Wemm **
2153c2aa98e2SPeter Wemm **	Compares the message cost to the load average to decide.
2154c2aa98e2SPeter Wemm **
215512ed1c7cSGregory Neil Shapiro **	Note: Do NOT change this API! It is documented in op.me
215612ed1c7cSGregory Neil Shapiro **		and theoretically the user can change this function...
215712ed1c7cSGregory Neil Shapiro **
2158c2aa98e2SPeter Wemm **	Parameters:
2159c2aa98e2SPeter Wemm **		pri -- the priority of the message in question.
216012ed1c7cSGregory Neil Shapiro **		ct -- the message creation time (unused, but see above).
2161c2aa98e2SPeter Wemm **
2162c2aa98e2SPeter Wemm **	Returns:
216312ed1c7cSGregory Neil Shapiro **		true -- if this message should be queued up for the
2164c2aa98e2SPeter Wemm **			time being.
216512ed1c7cSGregory Neil Shapiro **		false -- if the load is low enough to send this message.
2166c2aa98e2SPeter Wemm **
2167c2aa98e2SPeter Wemm **	Side Effects:
2168c2aa98e2SPeter Wemm **		none.
2169c2aa98e2SPeter Wemm */
2170c2aa98e2SPeter Wemm 
21713299c2f1SGregory Neil Shapiro /* ARGSUSED1 */
2172c2aa98e2SPeter Wemm bool
21733299c2f1SGregory Neil Shapiro shouldqueue(pri, ct)
2174c2aa98e2SPeter Wemm 	long pri;
21753299c2f1SGregory Neil Shapiro 	time_t ct;
2176c2aa98e2SPeter Wemm {
2177c2aa98e2SPeter Wemm 	bool rval;
2178c2aa98e2SPeter Wemm 
2179c2aa98e2SPeter Wemm 	if (tTd(3, 30))
218012ed1c7cSGregory Neil Shapiro 		sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
21813299c2f1SGregory Neil Shapiro 			CurrentLA, pri);
21823299c2f1SGregory Neil Shapiro 	if (CurrentLA < QueueLA)
2183c2aa98e2SPeter Wemm 	{
2184c2aa98e2SPeter Wemm 		if (tTd(3, 30))
218512ed1c7cSGregory Neil Shapiro 			sm_dprintf("false (CurrentLA < QueueLA)\n");
218612ed1c7cSGregory Neil Shapiro 		return false;
2187c2aa98e2SPeter Wemm 	}
2188c2aa98e2SPeter Wemm # if 0	/* this code is reported to cause oscillation around RefuseLA */
2189c2aa98e2SPeter Wemm 	if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
2190c2aa98e2SPeter Wemm 	{
2191c2aa98e2SPeter Wemm 		if (tTd(3, 30))
219212ed1c7cSGregory Neil Shapiro 			sm_dprintf("TRUE (CurrentLA >= RefuseLA)\n");
219312ed1c7cSGregory Neil Shapiro 		return true;
2194c2aa98e2SPeter Wemm 	}
21953299c2f1SGregory Neil Shapiro # endif /* 0 */
21963299c2f1SGregory Neil Shapiro 	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
2197c2aa98e2SPeter Wemm 	if (tTd(3, 30))
219812ed1c7cSGregory Neil Shapiro 		sm_dprintf("%s (by calculation)\n", rval ? "true" : "false");
2199c2aa98e2SPeter Wemm 	return rval;
2200c2aa98e2SPeter Wemm }
220112ed1c7cSGregory Neil Shapiro /*
2202c2aa98e2SPeter Wemm **  REFUSECONNECTIONS -- decide if connections should be refused
2203c2aa98e2SPeter Wemm **
2204c2aa98e2SPeter Wemm **	Parameters:
22053299c2f1SGregory Neil Shapiro **		name -- daemon name (for error messages only)
22063299c2f1SGregory Neil Shapiro **		e -- the current envelope.
22073299c2f1SGregory Neil Shapiro **		d -- number of daemon
220812ed1c7cSGregory Neil Shapiro **		active -- was this daemon actually active?
2209c2aa98e2SPeter Wemm **
2210c2aa98e2SPeter Wemm **	Returns:
221112ed1c7cSGregory Neil Shapiro **		true if incoming SMTP connections should be refused
2212c2aa98e2SPeter Wemm **			(for now).
221312ed1c7cSGregory Neil Shapiro **		false if we should accept new work.
2214c2aa98e2SPeter Wemm **
2215c2aa98e2SPeter Wemm **	Side Effects:
2216c2aa98e2SPeter Wemm **		Sets process title when it is rejecting connections.
2217c2aa98e2SPeter Wemm */
2218c2aa98e2SPeter Wemm 
2219c2aa98e2SPeter Wemm bool
222012ed1c7cSGregory Neil Shapiro refuseconnections(name, e, d, active)
22213299c2f1SGregory Neil Shapiro 	char *name;
22223299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
22233299c2f1SGregory Neil Shapiro 	int d;
222412ed1c7cSGregory Neil Shapiro 	bool active;
2225c2aa98e2SPeter Wemm {
222612ed1c7cSGregory Neil Shapiro 	static time_t lastconn[MAXDAEMONS];
222712ed1c7cSGregory Neil Shapiro 	static int conncnt[MAXDAEMONS];
22282ef40764SGregory Neil Shapiro 	static time_t firstrejtime[MAXDAEMONS];
22292ef40764SGregory Neil Shapiro 	static time_t nextlogtime[MAXDAEMONS];
223012ed1c7cSGregory Neil Shapiro 
223112ed1c7cSGregory Neil Shapiro #if XLA
2232c2aa98e2SPeter Wemm 	if (!xla_smtp_ok())
223312ed1c7cSGregory Neil Shapiro 		return true;
22343299c2f1SGregory Neil Shapiro #endif /* XLA */
2235c2aa98e2SPeter Wemm 
2236bfb62e91SGregory Neil Shapiro 	SM_ASSERT(d >= 0);
2237bfb62e91SGregory Neil Shapiro 	SM_ASSERT(d < MAXDAEMONS);
223812ed1c7cSGregory Neil Shapiro 	if (ConnRateThrottle > 0)
223912ed1c7cSGregory Neil Shapiro 	{
224012ed1c7cSGregory Neil Shapiro 		time_t now;
224112ed1c7cSGregory Neil Shapiro 
224212ed1c7cSGregory Neil Shapiro 		now = curtime();
224312ed1c7cSGregory Neil Shapiro 		if (active)
224412ed1c7cSGregory Neil Shapiro 		{
224512ed1c7cSGregory Neil Shapiro 			if (now != lastconn[d])
224612ed1c7cSGregory Neil Shapiro 			{
224712ed1c7cSGregory Neil Shapiro 				lastconn[d] = now;
224812ed1c7cSGregory Neil Shapiro 				conncnt[d] = 1;
224912ed1c7cSGregory Neil Shapiro 			}
225012ed1c7cSGregory Neil Shapiro 			else if (conncnt[d]++ > ConnRateThrottle)
225112ed1c7cSGregory Neil Shapiro 			{
225212ed1c7cSGregory Neil Shapiro #define D_MSG_CRT "deferring connections on daemon %s: %d per second"
225312ed1c7cSGregory Neil Shapiro 				/* sleep to flatten out connection load */
225412ed1c7cSGregory Neil Shapiro 				sm_setproctitle(true, e, D_MSG_CRT,
225512ed1c7cSGregory Neil Shapiro 						name, ConnRateThrottle);
225612ed1c7cSGregory Neil Shapiro 				if (LogLevel > 8)
225712ed1c7cSGregory Neil Shapiro 					sm_syslog(LOG_INFO, NOQID, D_MSG_CRT,
225812ed1c7cSGregory Neil Shapiro 						  name, ConnRateThrottle);
225912ed1c7cSGregory Neil Shapiro 				(void) sleep(1);
226012ed1c7cSGregory Neil Shapiro 			}
226112ed1c7cSGregory Neil Shapiro 		}
226212ed1c7cSGregory Neil Shapiro 		else if (now != lastconn[d])
226312ed1c7cSGregory Neil Shapiro 			conncnt[d] = 0;
226412ed1c7cSGregory Neil Shapiro 	}
226512ed1c7cSGregory Neil Shapiro 
226612ed1c7cSGregory Neil Shapiro 	sm_getla();
22673299c2f1SGregory Neil Shapiro 	if (RefuseLA > 0 && CurrentLA >= RefuseLA)
2268c2aa98e2SPeter Wemm 	{
22692ef40764SGregory Neil Shapiro 		time_t now;
22702ef40764SGregory Neil Shapiro 
227112ed1c7cSGregory Neil Shapiro # define R_MSG_LA "rejecting connections on daemon %s: load average: %d"
2272bfb62e91SGregory Neil Shapiro # define R2_MSG_LA "have been rejecting connections on daemon %s for %s"
227312ed1c7cSGregory Neil Shapiro 		sm_setproctitle(true, e, R_MSG_LA, name, CurrentLA);
227412ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8)
22752ef40764SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, NOQID, R_MSG_LA, name, CurrentLA);
22762ef40764SGregory Neil Shapiro 		now = curtime();
22772ef40764SGregory Neil Shapiro 		if (firstrejtime[d] == 0)
22782ef40764SGregory Neil Shapiro 		{
22792ef40764SGregory Neil Shapiro 			firstrejtime[d] = now;
22802ef40764SGregory Neil Shapiro 			nextlogtime[d] = now + RejectLogInterval;
22812ef40764SGregory Neil Shapiro 		}
22822ef40764SGregory Neil Shapiro 		else if (nextlogtime[d] < now)
22832ef40764SGregory Neil Shapiro 		{
22842ef40764SGregory Neil Shapiro 			sm_syslog(LOG_ERR, NOQID, R2_MSG_LA, name,
22852ef40764SGregory Neil Shapiro 				  pintvl(now - firstrejtime[d], true));
22862ef40764SGregory Neil Shapiro 			nextlogtime[d] = now + RejectLogInterval;
22872ef40764SGregory Neil Shapiro 		}
228812ed1c7cSGregory Neil Shapiro 		return true;
228912ed1c7cSGregory Neil Shapiro 	}
22902ef40764SGregory Neil Shapiro 	else
22912ef40764SGregory Neil Shapiro 		firstrejtime[d] = 0;
229212ed1c7cSGregory Neil Shapiro 
229312ed1c7cSGregory Neil Shapiro 	if (DelayLA > 0 && CurrentLA >= DelayLA)
229412ed1c7cSGregory Neil Shapiro 	{
229512ed1c7cSGregory Neil Shapiro 		time_t now;
229612ed1c7cSGregory Neil Shapiro 		static time_t log_delay = (time_t) 0;
229712ed1c7cSGregory Neil Shapiro 
229812ed1c7cSGregory Neil Shapiro # define MIN_DELAY_LOG	90	/* wait before logging this again */
229912ed1c7cSGregory Neil Shapiro # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d"
230012ed1c7cSGregory Neil Shapiro 		/* sleep to flatten out connection load */
230112ed1c7cSGregory Neil Shapiro 		sm_setproctitle(true, e, D_MSG_LA, name, DelayLA);
230212ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8 && (now = curtime()) > log_delay)
230312ed1c7cSGregory Neil Shapiro 		{
230412ed1c7cSGregory Neil Shapiro 			sm_syslog(LOG_INFO, NOQID, D_MSG_LA,
230512ed1c7cSGregory Neil Shapiro 				  name, CurrentLA, DelayLA);
230612ed1c7cSGregory Neil Shapiro 			log_delay = now + MIN_DELAY_LOG;
230712ed1c7cSGregory Neil Shapiro 		}
230812ed1c7cSGregory Neil Shapiro 		(void) sleep(1);
2309c2aa98e2SPeter Wemm 	}
2310c2aa98e2SPeter Wemm 
2311c2aa98e2SPeter Wemm 	if (MaxChildren > 0 && CurChildren >= MaxChildren)
2312c2aa98e2SPeter Wemm 	{
2313c2aa98e2SPeter Wemm 		proc_list_probe();
2314c2aa98e2SPeter Wemm 		if (CurChildren >= MaxChildren)
2315c2aa98e2SPeter Wemm 		{
231612ed1c7cSGregory Neil Shapiro #define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d"
231712ed1c7cSGregory Neil Shapiro 			sm_setproctitle(true, e, R_MSG_CHILD,
23183299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
231912ed1c7cSGregory Neil Shapiro 			if (LogLevel > 8)
232012ed1c7cSGregory Neil Shapiro 				sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD,
23213299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
232212ed1c7cSGregory Neil Shapiro 			return true;
2323c2aa98e2SPeter Wemm 		}
2324c2aa98e2SPeter Wemm 	}
232512ed1c7cSGregory Neil Shapiro 	return false;
2326c2aa98e2SPeter Wemm }
232712ed1c7cSGregory Neil Shapiro /*
2328c2aa98e2SPeter Wemm **  SETPROCTITLE -- set process title for ps
2329c2aa98e2SPeter Wemm **
2330c2aa98e2SPeter Wemm **	Parameters:
2331c2aa98e2SPeter Wemm **		fmt -- a printf style format string.
2332c2aa98e2SPeter Wemm **		a, b, c -- possible parameters to fmt.
2333c2aa98e2SPeter Wemm **
2334c2aa98e2SPeter Wemm **	Returns:
2335c2aa98e2SPeter Wemm **		none.
2336c2aa98e2SPeter Wemm **
2337c2aa98e2SPeter Wemm **	Side Effects:
2338c2aa98e2SPeter Wemm **		Clobbers argv of our main procedure so ps(1) will
2339c2aa98e2SPeter Wemm **		display the title.
2340c2aa98e2SPeter Wemm */
2341c2aa98e2SPeter Wemm 
2342c2aa98e2SPeter Wemm #define SPT_NONE	0	/* don't use it at all */
2343c2aa98e2SPeter Wemm #define SPT_REUSEARGV	1	/* cover argv with title information */
2344c2aa98e2SPeter Wemm #define SPT_BUILTIN	2	/* use libc builtin */
2345c2aa98e2SPeter Wemm #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
2346c2aa98e2SPeter Wemm #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
2347c2aa98e2SPeter Wemm #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
2348c2aa98e2SPeter Wemm #define SPT_SCO		6	/* write kernel u. area */
2349c2aa98e2SPeter Wemm #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
2350c2aa98e2SPeter Wemm 
2351c2aa98e2SPeter Wemm #ifndef SPT_TYPE
2352c2aa98e2SPeter Wemm # define SPT_TYPE	SPT_REUSEARGV
23533299c2f1SGregory Neil Shapiro #endif /* ! SPT_TYPE */
23543299c2f1SGregory Neil Shapiro 
2355c2aa98e2SPeter Wemm 
2356c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
2357c2aa98e2SPeter Wemm 
2358c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT
2359c2aa98e2SPeter Wemm #  include <sys/pstat.h>
23603299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */
2361c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS
2362c2aa98e2SPeter Wemm #  include <machine/vmparam.h>
2363c2aa98e2SPeter Wemm #  include <sys/exec.h>
2364c2aa98e2SPeter Wemm #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
2365c2aa98e2SPeter Wemm #   undef SPT_TYPE
2366c2aa98e2SPeter Wemm #   define SPT_TYPE	SPT_REUSEARGV
23673299c2f1SGregory Neil Shapiro #  else /* ! PS_STRINGS */
2368c2aa98e2SPeter Wemm #   ifndef NKPDE			/* FreeBSD 2.0 */
2369c2aa98e2SPeter Wemm #    define NKPDE 63
2370c2aa98e2SPeter Wemm typedef unsigned int	*pt_entry_t;
23713299c2f1SGregory Neil Shapiro #   endif /* ! NKPDE */
23723299c2f1SGregory Neil Shapiro #  endif /* ! PS_STRINGS */
23733299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */
2374c2aa98e2SPeter Wemm 
2375c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
2376c2aa98e2SPeter Wemm #  define SETPROC_STATIC	static
23773299c2f1SGregory Neil Shapiro # else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2378c2aa98e2SPeter Wemm #  define SETPROC_STATIC
23793299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2380c2aa98e2SPeter Wemm 
2381c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS
2382c2aa98e2SPeter Wemm #  include <sys/sysmips.h>
2383c2aa98e2SPeter Wemm #  include <sys/sysnews.h>
23843299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SYSMIPS */
2385c2aa98e2SPeter Wemm 
2386c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO
2387c2aa98e2SPeter Wemm #  include <sys/immu.h>
2388c2aa98e2SPeter Wemm #  include <sys/dir.h>
2389c2aa98e2SPeter Wemm #  include <sys/user.h>
2390c2aa98e2SPeter Wemm #  include <sys/fs/s5param.h>
2391c2aa98e2SPeter Wemm #  if PSARGSZ > MAXLINE
2392c2aa98e2SPeter Wemm #   define SPT_BUFSIZE	PSARGSZ
23933299c2f1SGregory Neil Shapiro #  endif /* PSARGSZ > MAXLINE */
23943299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */
2395c2aa98e2SPeter Wemm 
2396c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR
2397c2aa98e2SPeter Wemm #  define SPT_PADCHAR	' '
23983299c2f1SGregory Neil Shapiro # endif /* ! SPT_PADCHAR */
2399c2aa98e2SPeter Wemm 
240076b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
240176b7bf71SPeter Wemm 
2402c2aa98e2SPeter Wemm #ifndef SPT_BUFSIZE
2403c2aa98e2SPeter Wemm # define SPT_BUFSIZE	MAXLINE
24043299c2f1SGregory Neil Shapiro #endif /* ! SPT_BUFSIZE */
2405c2aa98e2SPeter Wemm 
240688ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN
240788ad41d4SGregory Neil Shapiro 
240888ad41d4SGregory Neil Shapiro /*
240988ad41d4SGregory Neil Shapiro **  It looks like the Compaq Tru64 5.1A now aligns argv and envp to
241088ad41d4SGregory Neil Shapiro **  64 bit alignment, so unless each piece of argv and envp is a multiple
241188ad41d4SGregory Neil Shapiro **  of 8 bytes (including terminating NULL), initsetproctitle() won't use
241288ad41d4SGregory Neil Shapiro **  any of the space beyond argv[0].  Be sure to set SPT_ALIGN_SIZE if
241388ad41d4SGregory Neil Shapiro **  you use this FFR.
241488ad41d4SGregory Neil Shapiro */
241588ad41d4SGregory Neil Shapiro 
241688ad41d4SGregory Neil Shapiro # ifdef SPT_ALIGN_SIZE
2417f848909fSGregory Neil Shapiro #  define SPT_ALIGN(x, align)	(((((x) + SPT_ALIGN_SIZE) >> (align)) << (align)) - 1)
241888ad41d4SGregory Neil Shapiro # else /* SPT_ALIGN_SIZE */
241988ad41d4SGregory Neil Shapiro #  define SPT_ALIGN(x, align)	(x)
242088ad41d4SGregory Neil Shapiro # endif /* SPT_ALIGN_SIZE */
242188ad41d4SGregory Neil Shapiro #else /* _FFR_SPT_ALIGN */
242288ad41d4SGregory Neil Shapiro # define SPT_ALIGN(x, align)	(x)
242388ad41d4SGregory Neil Shapiro #endif /* _FFR_SPT_ALIGN */
242488ad41d4SGregory Neil Shapiro 
2425c2aa98e2SPeter Wemm /*
2426c2aa98e2SPeter Wemm **  Pointers for setproctitle.
2427c2aa98e2SPeter Wemm **	This allows "ps" listings to give more useful information.
2428c2aa98e2SPeter Wemm */
2429c2aa98e2SPeter Wemm 
24303299c2f1SGregory Neil Shapiro static char	**Argv = NULL;		/* pointer to argument vector */
24313299c2f1SGregory Neil Shapiro static char	*LastArgv = NULL;	/* end of argv */
24323299c2f1SGregory Neil Shapiro #if SPT_TYPE != SPT_BUILTIN
24333299c2f1SGregory Neil Shapiro static void	setproctitle __P((const char *, ...));
24343299c2f1SGregory Neil Shapiro #endif /* SPT_TYPE != SPT_BUILTIN */
2435c2aa98e2SPeter Wemm 
2436c2aa98e2SPeter Wemm void
2437c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp)
2438c2aa98e2SPeter Wemm 	int argc;
2439c2aa98e2SPeter Wemm 	char **argv;
2440c2aa98e2SPeter Wemm 	char **envp;
2441c2aa98e2SPeter Wemm {
244212ed1c7cSGregory Neil Shapiro 	register int i;
244388ad41d4SGregory Neil Shapiro 	int align;
2444c2aa98e2SPeter Wemm 	extern char **environ;
2445c2aa98e2SPeter Wemm 
2446c2aa98e2SPeter Wemm 	/*
2447c2aa98e2SPeter Wemm 	**  Move the environment so setproctitle can use the space at
2448c2aa98e2SPeter Wemm 	**  the top of memory.
2449c2aa98e2SPeter Wemm 	*/
2450c2aa98e2SPeter Wemm 
24519d8fddc1SGregory Neil Shapiro 	if (envp != NULL)
24529d8fddc1SGregory Neil Shapiro 	{
2453c2aa98e2SPeter Wemm 		for (i = 0; envp[i] != NULL; i++)
245412ed1c7cSGregory Neil Shapiro 			continue;
2455c2aa98e2SPeter Wemm 		environ = (char **) xalloc(sizeof (char *) * (i + 1));
2456c2aa98e2SPeter Wemm 		for (i = 0; envp[i] != NULL; i++)
2457c2aa98e2SPeter Wemm 			environ[i] = newstr(envp[i]);
2458c2aa98e2SPeter Wemm 		environ[i] = NULL;
24599d8fddc1SGregory Neil Shapiro 	}
2460c2aa98e2SPeter Wemm 
2461c2aa98e2SPeter Wemm 	/*
2462c2aa98e2SPeter Wemm 	**  Save start and extent of argv for setproctitle.
2463c2aa98e2SPeter Wemm 	*/
2464c2aa98e2SPeter Wemm 
2465c2aa98e2SPeter Wemm 	Argv = argv;
2466c2aa98e2SPeter Wemm 
2467c2aa98e2SPeter Wemm 	/*
2468c2aa98e2SPeter Wemm 	**  Determine how much space we can use for setproctitle.
2469c2aa98e2SPeter Wemm 	**  Use all contiguous argv and envp pointers starting at argv[0]
2470c2aa98e2SPeter Wemm 	*/
247188ad41d4SGregory Neil Shapiro 
247288ad41d4SGregory Neil Shapiro 	align = -1;
247388ad41d4SGregory Neil Shapiro # if _FFR_SPT_ALIGN
247488ad41d4SGregory Neil Shapiro #  ifdef SPT_ALIGN_SIZE
247588ad41d4SGregory Neil Shapiro 	for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1)
247688ad41d4SGregory Neil Shapiro 		align++;
247788ad41d4SGregory Neil Shapiro #  endif /* SPT_ALIGN_SIZE */
247888ad41d4SGregory Neil Shapiro # endif /* _FFR_SPT_ALIGN */
247988ad41d4SGregory Neil Shapiro 
2480c2aa98e2SPeter Wemm 	for (i = 0; i < argc; i++)
2481c2aa98e2SPeter Wemm 	{
2482c2aa98e2SPeter Wemm 		if (i == 0 || LastArgv + 1 == argv[i])
248388ad41d4SGregory Neil Shapiro 			LastArgv = argv[i] + SPT_ALIGN(strlen(argv[i]), align);
2484c2aa98e2SPeter Wemm 	}
24859d8fddc1SGregory Neil Shapiro 	for (i = 0; LastArgv != NULL && envp != NULL && envp[i] != NULL; i++)
2486c2aa98e2SPeter Wemm 	{
2487c2aa98e2SPeter Wemm 		if (LastArgv + 1 == envp[i])
248888ad41d4SGregory Neil Shapiro 			LastArgv = envp[i] + SPT_ALIGN(strlen(envp[i]), align);
2489c2aa98e2SPeter Wemm 	}
2490c2aa98e2SPeter Wemm }
2491c2aa98e2SPeter Wemm 
2492c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN
2493c2aa98e2SPeter Wemm 
2494c2aa98e2SPeter Wemm /*VARARGS1*/
24953299c2f1SGregory Neil Shapiro static void
2496c2aa98e2SPeter Wemm # ifdef __STDC__
2497c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...)
24983299c2f1SGregory Neil Shapiro # else /* __STDC__ */
2499c2aa98e2SPeter Wemm setproctitle(fmt, va_alist)
2500c2aa98e2SPeter Wemm 	const char *fmt;
2501c2aa98e2SPeter Wemm 	va_dcl
25023299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
2503c2aa98e2SPeter Wemm {
2504c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE
2505c2aa98e2SPeter Wemm 	register int i;
25063299c2f1SGregory Neil Shapiro 	register char *p;
2507c2aa98e2SPeter Wemm 	SETPROC_STATIC char buf[SPT_BUFSIZE];
250812ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
2509c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2510c2aa98e2SPeter Wemm 	union pstun pst;
25113299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2512c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
251312ed1c7cSGregory Neil Shapiro 	int j;
2514c2aa98e2SPeter Wemm 	off_t seek_off;
2515c2aa98e2SPeter Wemm 	static int kmem = -1;
2516c0c4794dSGregory Neil Shapiro 	static pid_t kmempid = -1;
2517c2aa98e2SPeter Wemm 	struct user u;
25183299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2519c2aa98e2SPeter Wemm 
2520c2aa98e2SPeter Wemm 	p = buf;
2521c2aa98e2SPeter Wemm 
2522c2aa98e2SPeter Wemm 	/* print sendmail: heading for grep */
252312ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
2524c2aa98e2SPeter Wemm 	p += strlen(p);
2525c2aa98e2SPeter Wemm 
2526c2aa98e2SPeter Wemm 	/* print the argument string */
252712ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
252812ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
252912ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
2530c2aa98e2SPeter Wemm 
253112ed1c7cSGregory Neil Shapiro 	i = (int) strlen(buf);
253212ed1c7cSGregory Neil Shapiro 	if (i < 0)
253312ed1c7cSGregory Neil Shapiro 		return;
2534c2aa98e2SPeter Wemm 
2535c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2536c2aa98e2SPeter Wemm 	pst.pst_command = buf;
2537c2aa98e2SPeter Wemm 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
25383299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2539c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSSTRINGS
2540c2aa98e2SPeter Wemm 	PS_STRINGS->ps_nargvstr = 1;
2541c2aa98e2SPeter Wemm 	PS_STRINGS->ps_argvstr = buf;
25423299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSSTRINGS */
2543c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SYSMIPS
2544c2aa98e2SPeter Wemm 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
25453299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SYSMIPS */
2546c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
254712ed1c7cSGregory Neil Shapiro 	if (kmem < 0 || kmempid != CurrentPid)
2548c2aa98e2SPeter Wemm 	{
2549c2aa98e2SPeter Wemm 		if (kmem >= 0)
2550c46d91b7SGregory Neil Shapiro 			(void) close(kmem);
2551c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, O_RDWR, 0);
2552c2aa98e2SPeter Wemm 		if (kmem < 0)
2553c2aa98e2SPeter Wemm 			return;
255412ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
255512ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
255612ed1c7cSGregory Neil Shapiro 		{
255712ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
255812ed1c7cSGregory Neil Shapiro 			kmem = -1;
255912ed1c7cSGregory Neil Shapiro 			return;
256012ed1c7cSGregory Neil Shapiro 		}
256112ed1c7cSGregory Neil Shapiro 		kmempid = CurrentPid;
2562c2aa98e2SPeter Wemm 	}
2563c2aa98e2SPeter Wemm 	buf[PSARGSZ - 1] = '\0';
2564c2aa98e2SPeter Wemm 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
2565c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
2566c2aa98e2SPeter Wemm 		(void) write(kmem, buf, PSARGSZ);
25673299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2568c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_REUSEARGV
25693299c2f1SGregory Neil Shapiro 	if (LastArgv == NULL)
25703299c2f1SGregory Neil Shapiro 		return;
25713299c2f1SGregory Neil Shapiro 
2572c2aa98e2SPeter Wemm 	if (i > LastArgv - Argv[0] - 2)
2573c2aa98e2SPeter Wemm 	{
2574c2aa98e2SPeter Wemm 		i = LastArgv - Argv[0] - 2;
2575c2aa98e2SPeter Wemm 		buf[i] = '\0';
2576c2aa98e2SPeter Wemm 	}
257712ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(Argv[0], buf, i + 1);
2578c2aa98e2SPeter Wemm 	p = &Argv[0][i];
2579c2aa98e2SPeter Wemm 	while (p < LastArgv)
2580c2aa98e2SPeter Wemm 		*p++ = SPT_PADCHAR;
2581c2aa98e2SPeter Wemm 	Argv[1] = NULL;
25823299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_REUSEARGV */
2583c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_CHANGEARGV
2584c2aa98e2SPeter Wemm 	Argv[0] = buf;
2585c2aa98e2SPeter Wemm 	Argv[1] = 0;
25863299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_CHANGEARGV */
2587c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */
2588c2aa98e2SPeter Wemm }
2589c2aa98e2SPeter Wemm 
2590c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */
259112ed1c7cSGregory Neil Shapiro /*
259276b7bf71SPeter Wemm **  SM_SETPROCTITLE -- set process task and set process title for ps
259376b7bf71SPeter Wemm **
259476b7bf71SPeter Wemm **	Possibly set process status and call setproctitle() to
259576b7bf71SPeter Wemm **	change the ps display.
259676b7bf71SPeter Wemm **
259776b7bf71SPeter Wemm **	Parameters:
259876b7bf71SPeter Wemm **		status -- whether or not to store as process status
25993299c2f1SGregory Neil Shapiro **		e -- the current envelope.
260076b7bf71SPeter Wemm **		fmt -- a printf style format string.
260176b7bf71SPeter Wemm **		a, b, c -- possible parameters to fmt.
260276b7bf71SPeter Wemm **
260376b7bf71SPeter Wemm **	Returns:
260476b7bf71SPeter Wemm **		none.
260576b7bf71SPeter Wemm */
260676b7bf71SPeter Wemm 
260776b7bf71SPeter Wemm /*VARARGS2*/
260876b7bf71SPeter Wemm void
260976b7bf71SPeter Wemm #ifdef __STDC__
26103299c2f1SGregory Neil Shapiro sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
26113299c2f1SGregory Neil Shapiro #else /* __STDC__ */
26123299c2f1SGregory Neil Shapiro sm_setproctitle(status, e, fmt, va_alist)
261376b7bf71SPeter Wemm 	bool status;
26143299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
261576b7bf71SPeter Wemm 	const char *fmt;
261676b7bf71SPeter Wemm 	va_dcl
26173299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
261876b7bf71SPeter Wemm {
261976b7bf71SPeter Wemm 	char buf[SPT_BUFSIZE];
262012ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
26213299c2f1SGregory Neil Shapiro 
262276b7bf71SPeter Wemm 	/* print the argument string */
262312ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
262412ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof buf, fmt, ap);
262512ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
262676b7bf71SPeter Wemm 
262776b7bf71SPeter Wemm 	if (status)
262812ed1c7cSGregory Neil Shapiro 		proc_list_set(CurrentPid, buf);
26293299c2f1SGregory Neil Shapiro 
26303299c2f1SGregory Neil Shapiro 	if (ProcTitlePrefix != NULL)
26313299c2f1SGregory Neil Shapiro 	{
26323299c2f1SGregory Neil Shapiro 		char prefix[SPT_BUFSIZE];
26333299c2f1SGregory Neil Shapiro 
26343299c2f1SGregory Neil Shapiro 		expand(ProcTitlePrefix, prefix, sizeof prefix, e);
26353299c2f1SGregory Neil Shapiro 		setproctitle("%s: %s", prefix, buf);
26363299c2f1SGregory Neil Shapiro 	}
26373299c2f1SGregory Neil Shapiro 	else
263876b7bf71SPeter Wemm 		setproctitle("%s", buf);
263976b7bf71SPeter Wemm }
264012ed1c7cSGregory Neil Shapiro /*
2641c2aa98e2SPeter Wemm **  WAITFOR -- wait for a particular process id.
2642c2aa98e2SPeter Wemm **
2643c2aa98e2SPeter Wemm **	Parameters:
2644c2aa98e2SPeter Wemm **		pid -- process id to wait for.
2645c2aa98e2SPeter Wemm **
2646c2aa98e2SPeter Wemm **	Returns:
2647c2aa98e2SPeter Wemm **		status of pid.
2648c2aa98e2SPeter Wemm **		-1 if pid never shows up.
2649c2aa98e2SPeter Wemm **
2650c2aa98e2SPeter Wemm **	Side Effects:
2651c2aa98e2SPeter Wemm **		none.
2652c2aa98e2SPeter Wemm */
2653c2aa98e2SPeter Wemm 
2654c2aa98e2SPeter Wemm int
2655c2aa98e2SPeter Wemm waitfor(pid)
2656c2aa98e2SPeter Wemm 	pid_t pid;
2657c2aa98e2SPeter Wemm {
265812ed1c7cSGregory Neil Shapiro 	int st;
265912ed1c7cSGregory Neil Shapiro 	pid_t i;
266012ed1c7cSGregory Neil Shapiro 
266112ed1c7cSGregory Neil Shapiro 	do
266212ed1c7cSGregory Neil Shapiro 	{
266312ed1c7cSGregory Neil Shapiro 		errno = 0;
266412ed1c7cSGregory Neil Shapiro 		i = sm_wait(&st);
266512ed1c7cSGregory Neil Shapiro 		if (i > 0)
266612ed1c7cSGregory Neil Shapiro 			proc_list_drop(i, st, NULL);
266712ed1c7cSGregory Neil Shapiro 	} while ((i >= 0 || errno == EINTR) && i != pid);
266812ed1c7cSGregory Neil Shapiro 	if (i < 0)
266912ed1c7cSGregory Neil Shapiro 		return -1;
267012ed1c7cSGregory Neil Shapiro 	return st;
267112ed1c7cSGregory Neil Shapiro }
267212ed1c7cSGregory Neil Shapiro /*
267312ed1c7cSGregory Neil Shapiro **  SM_WAIT -- wait
267412ed1c7cSGregory Neil Shapiro **
267512ed1c7cSGregory Neil Shapiro **	Parameters:
267612ed1c7cSGregory Neil Shapiro **		status -- pointer to status (return value)
267712ed1c7cSGregory Neil Shapiro **
267812ed1c7cSGregory Neil Shapiro **	Returns:
267912ed1c7cSGregory Neil Shapiro **		pid
268012ed1c7cSGregory Neil Shapiro */
268112ed1c7cSGregory Neil Shapiro 
268212ed1c7cSGregory Neil Shapiro pid_t
268312ed1c7cSGregory Neil Shapiro sm_wait(status)
268412ed1c7cSGregory Neil Shapiro 	int *status;
268512ed1c7cSGregory Neil Shapiro {
2686c2aa98e2SPeter Wemm # ifdef WAITUNION
2687c2aa98e2SPeter Wemm 	union wait st;
26883299c2f1SGregory Neil Shapiro # else /* WAITUNION */
2689c2aa98e2SPeter Wemm 	auto int st;
26903299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
2691c2aa98e2SPeter Wemm 	pid_t i;
2692c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2693c2aa98e2SPeter Wemm 	int savesig;
26943299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2695c2aa98e2SPeter Wemm 
2696c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
269712ed1c7cSGregory Neil Shapiro 	savesig = sm_releasesignal(SIGCHLD);
26983299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2699c2aa98e2SPeter Wemm 	i = wait(&st);
2700c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2701c2aa98e2SPeter Wemm 	if (savesig > 0)
270212ed1c7cSGregory Neil Shapiro 		sm_blocksignal(SIGCHLD);
27033299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2704c2aa98e2SPeter Wemm # ifdef WAITUNION
270512ed1c7cSGregory Neil Shapiro 	*status = st.w_status;
27063299c2f1SGregory Neil Shapiro # else /* WAITUNION */
270712ed1c7cSGregory Neil Shapiro 	*status = st;
27083299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
270912ed1c7cSGregory Neil Shapiro 	return i;
2710c2aa98e2SPeter Wemm }
271112ed1c7cSGregory Neil Shapiro /*
2712c2aa98e2SPeter Wemm **  REAPCHILD -- pick up the body of my child, lest it become a zombie
2713c2aa98e2SPeter Wemm **
2714c2aa98e2SPeter Wemm **	Parameters:
2715c2aa98e2SPeter Wemm **		sig -- the signal that got us here (unused).
2716c2aa98e2SPeter Wemm **
2717c2aa98e2SPeter Wemm **	Returns:
2718c2aa98e2SPeter Wemm **		none.
2719c2aa98e2SPeter Wemm **
2720c2aa98e2SPeter Wemm **	Side Effects:
2721c2aa98e2SPeter Wemm **		Picks up extant zombies.
27223299c2f1SGregory Neil Shapiro **		Control socket exits may restart/shutdown daemon.
2723c0c4794dSGregory Neil Shapiro **
2724c0c4794dSGregory Neil Shapiro **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
2725c0c4794dSGregory Neil Shapiro **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
2726c0c4794dSGregory Neil Shapiro **		DOING.
2727c2aa98e2SPeter Wemm */
2728c2aa98e2SPeter Wemm 
27293299c2f1SGregory Neil Shapiro /* ARGSUSED0 */
2730c2aa98e2SPeter Wemm SIGFUNC_DECL
2731c2aa98e2SPeter Wemm reapchild(sig)
2732c2aa98e2SPeter Wemm 	int sig;
2733c2aa98e2SPeter Wemm {
27343299c2f1SGregory Neil Shapiro 	int save_errno = errno;
27353299c2f1SGregory Neil Shapiro 	int st;
2736c2aa98e2SPeter Wemm 	pid_t pid;
27373299c2f1SGregory Neil Shapiro # if HASWAITPID
2738c2aa98e2SPeter Wemm 	auto int status;
2739c2aa98e2SPeter Wemm 	int count;
2740c2aa98e2SPeter Wemm 
2741c2aa98e2SPeter Wemm 	count = 0;
2742c2aa98e2SPeter Wemm 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2743c2aa98e2SPeter Wemm 	{
27443299c2f1SGregory Neil Shapiro 		st = status;
2745c2aa98e2SPeter Wemm 		if (count++ > 1000)
2746c2aa98e2SPeter Wemm 			break;
27473299c2f1SGregory Neil Shapiro # else /* HASWAITPID */
2748c2aa98e2SPeter Wemm #  ifdef WNOHANG
274912ed1c7cSGregory Neil Shapiro 	union wait status;
275012ed1c7cSGregory Neil Shapiro 
2751c2aa98e2SPeter Wemm 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
27523299c2f1SGregory Neil Shapiro 	{
27533299c2f1SGregory Neil Shapiro 		st = status.w_status;
2754c2aa98e2SPeter Wemm #  else /* WNOHANG */
275512ed1c7cSGregory Neil Shapiro 	auto int status;
275612ed1c7cSGregory Neil Shapiro 
2757c2aa98e2SPeter Wemm 	/*
2758c2aa98e2SPeter Wemm 	**  Catch one zombie -- we will be re-invoked (we hope) if there
2759c2aa98e2SPeter Wemm 	**  are more.  Unreliable signals probably break this, but this
2760c2aa98e2SPeter Wemm 	**  is the "old system" situation -- waitpid or wait3 are to be
2761c2aa98e2SPeter Wemm 	**  strongly preferred.
2762c2aa98e2SPeter Wemm 	*/
2763c2aa98e2SPeter Wemm 
2764c2aa98e2SPeter Wemm 	if ((pid = wait(&status)) > 0)
27653299c2f1SGregory Neil Shapiro 	{
27663299c2f1SGregory Neil Shapiro 		st = status;
2767c2aa98e2SPeter Wemm #  endif /* WNOHANG */
27683299c2f1SGregory Neil Shapiro # endif /* HASWAITPID */
27693299c2f1SGregory Neil Shapiro 		/* Drop PID and check if it was a control socket child */
277012ed1c7cSGregory Neil Shapiro 		proc_list_drop(pid, st, NULL);
27713299c2f1SGregory Neil Shapiro 	}
2772c0c4794dSGregory Neil Shapiro 	FIX_SYSV_SIGNAL(sig, reapchild);
27733299c2f1SGregory Neil Shapiro 	errno = save_errno;
2774c2aa98e2SPeter Wemm 	return SIGFUNC_RETURN;
2775c2aa98e2SPeter Wemm }
2776c2aa98e2SPeter Wemm /*
2777c2aa98e2SPeter Wemm **  GETDTABLESIZE -- return number of file descriptors
2778c2aa98e2SPeter Wemm **
2779c2aa98e2SPeter Wemm **	Only on non-BSD systems
2780c2aa98e2SPeter Wemm **
2781c2aa98e2SPeter Wemm **	Parameters:
2782c2aa98e2SPeter Wemm **		none
2783c2aa98e2SPeter Wemm **
2784c2aa98e2SPeter Wemm **	Returns:
2785c2aa98e2SPeter Wemm **		size of file descriptor table
2786c2aa98e2SPeter Wemm **
2787c2aa98e2SPeter Wemm **	Side Effects:
2788c2aa98e2SPeter Wemm **		none
2789c2aa98e2SPeter Wemm */
2790c2aa98e2SPeter Wemm 
2791c2aa98e2SPeter Wemm #ifdef SOLARIS
2792c2aa98e2SPeter Wemm # include <sys/resource.h>
27933299c2f1SGregory Neil Shapiro #endif /* SOLARIS */
2794c2aa98e2SPeter Wemm 
2795c2aa98e2SPeter Wemm int
2796c2aa98e2SPeter Wemm getdtsize()
2797c2aa98e2SPeter Wemm {
2798c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
2799c2aa98e2SPeter Wemm 	struct rlimit rl;
2800c2aa98e2SPeter Wemm 
2801c2aa98e2SPeter Wemm 	if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2802c2aa98e2SPeter Wemm 		return rl.rlim_cur;
28033299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
2804c2aa98e2SPeter Wemm 
28053299c2f1SGregory Neil Shapiro # if HASGETDTABLESIZE
2806c2aa98e2SPeter Wemm 	return getdtablesize();
28073299c2f1SGregory Neil Shapiro # else /* HASGETDTABLESIZE */
2808c2aa98e2SPeter Wemm #  ifdef _SC_OPEN_MAX
2809c2aa98e2SPeter Wemm 	return sysconf(_SC_OPEN_MAX);
28103299c2f1SGregory Neil Shapiro #  else /* _SC_OPEN_MAX */
2811c2aa98e2SPeter Wemm 	return NOFILE;
28123299c2f1SGregory Neil Shapiro #  endif /* _SC_OPEN_MAX */
28133299c2f1SGregory Neil Shapiro # endif /* HASGETDTABLESIZE */
2814c2aa98e2SPeter Wemm }
281512ed1c7cSGregory Neil Shapiro /*
2816c2aa98e2SPeter Wemm **  UNAME -- get the UUCP name of this system.
2817c2aa98e2SPeter Wemm */
2818c2aa98e2SPeter Wemm 
28193299c2f1SGregory Neil Shapiro #if !HASUNAME
2820c2aa98e2SPeter Wemm 
2821c2aa98e2SPeter Wemm int
2822c2aa98e2SPeter Wemm uname(name)
2823c2aa98e2SPeter Wemm 	struct utsname *name;
2824c2aa98e2SPeter Wemm {
282512ed1c7cSGregory Neil Shapiro 	SM_FILE_T *file;
2826c2aa98e2SPeter Wemm 	char *n;
2827c2aa98e2SPeter Wemm 
2828c2aa98e2SPeter Wemm 	name->nodename[0] = '\0';
2829c2aa98e2SPeter Wemm 
2830c2aa98e2SPeter Wemm 	/* try /etc/whoami -- one line with the node name */
283112ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami",
283212ed1c7cSGregory Neil Shapiro 			       SM_IO_RDONLY, NULL)) != NULL)
2833c2aa98e2SPeter Wemm 	{
283412ed1c7cSGregory Neil Shapiro 		(void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename,
283512ed1c7cSGregory Neil Shapiro 				   NODE_LENGTH + 1);
283612ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2837c2aa98e2SPeter Wemm 		n = strchr(name->nodename, '\n');
2838c2aa98e2SPeter Wemm 		if (n != NULL)
2839c2aa98e2SPeter Wemm 			*n = '\0';
2840c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
28413299c2f1SGregory Neil Shapiro 			return 0;
2842c2aa98e2SPeter Wemm 	}
2843c2aa98e2SPeter Wemm 
2844c2aa98e2SPeter Wemm 	/* try /usr/include/whoami.h -- has a #define somewhere */
284512ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT,
284612ed1c7cSGregory Neil Shapiro 			       "/usr/include/whoami.h", SM_IO_RDONLY, NULL))
284712ed1c7cSGregory Neil Shapiro 	    != NULL)
2848c2aa98e2SPeter Wemm 	{
2849c2aa98e2SPeter Wemm 		char buf[MAXLINE];
2850c2aa98e2SPeter Wemm 
285188ad41d4SGregory Neil Shapiro 		while (sm_io_fgets(file, SM_TIME_DEFAULT,
285288ad41d4SGregory Neil Shapiro 				   buf, sizeof buf) != NULL)
28533299c2f1SGregory Neil Shapiro 		{
285412ed1c7cSGregory Neil Shapiro 			if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"",
2855c2aa98e2SPeter Wemm 					NODE_LENGTH, name->nodename) > 0)
2856c2aa98e2SPeter Wemm 				break;
28573299c2f1SGregory Neil Shapiro 		}
285812ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2859c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
28603299c2f1SGregory Neil Shapiro 			return 0;
2861c2aa98e2SPeter Wemm 	}
2862c2aa98e2SPeter Wemm 
28633299c2f1SGregory Neil Shapiro 	return -1;
2864c2aa98e2SPeter Wemm }
28653299c2f1SGregory Neil Shapiro #endif /* !HASUNAME */
286612ed1c7cSGregory Neil Shapiro /*
2867c2aa98e2SPeter Wemm **  INITGROUPS -- initialize groups
2868c2aa98e2SPeter Wemm **
2869c2aa98e2SPeter Wemm **	Stub implementation for System V style systems
2870c2aa98e2SPeter Wemm */
2871c2aa98e2SPeter Wemm 
28723299c2f1SGregory Neil Shapiro #if !HASINITGROUPS
2873c2aa98e2SPeter Wemm 
2874c2aa98e2SPeter Wemm initgroups(name, basegid)
2875c2aa98e2SPeter Wemm 	char *name;
2876c2aa98e2SPeter Wemm 	int basegid;
2877c2aa98e2SPeter Wemm {
2878c2aa98e2SPeter Wemm 	return 0;
2879c2aa98e2SPeter Wemm }
2880c2aa98e2SPeter Wemm 
28813299c2f1SGregory Neil Shapiro #endif /* !HASINITGROUPS */
288212ed1c7cSGregory Neil Shapiro /*
2883c2aa98e2SPeter Wemm **  SETGROUPS -- set group list
2884c2aa98e2SPeter Wemm **
2885c2aa98e2SPeter Wemm **	Stub implementation for systems that don't have group lists
2886c2aa98e2SPeter Wemm */
2887c2aa98e2SPeter Wemm 
2888c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX
2889c2aa98e2SPeter Wemm 
2890c2aa98e2SPeter Wemm int
2891c2aa98e2SPeter Wemm setgroups(ngroups, grouplist)
2892c2aa98e2SPeter Wemm 	int ngroups;
2893c2aa98e2SPeter Wemm 	GIDSET_T grouplist[];
2894c2aa98e2SPeter Wemm {
2895c2aa98e2SPeter Wemm 	return 0;
2896c2aa98e2SPeter Wemm }
2897c2aa98e2SPeter Wemm 
28983299c2f1SGregory Neil Shapiro #endif /* ! NGROUPS_MAX */
289912ed1c7cSGregory Neil Shapiro /*
2900c2aa98e2SPeter Wemm **  SETSID -- set session id (for non-POSIX systems)
2901c2aa98e2SPeter Wemm */
2902c2aa98e2SPeter Wemm 
29033299c2f1SGregory Neil Shapiro #if !HASSETSID
2904c2aa98e2SPeter Wemm 
2905c2aa98e2SPeter Wemm pid_t
2906c2aa98e2SPeter Wemm setsid __P ((void))
2907c2aa98e2SPeter Wemm {
2908c2aa98e2SPeter Wemm #  ifdef TIOCNOTTY
2909c2aa98e2SPeter Wemm 	int fd;
2910c2aa98e2SPeter Wemm 
2911c2aa98e2SPeter Wemm 	fd = open("/dev/tty", O_RDWR, 0);
2912c2aa98e2SPeter Wemm 	if (fd >= 0)
2913c2aa98e2SPeter Wemm 	{
2914d995d2baSGregory Neil Shapiro 		(void) ioctl(fd, TIOCNOTTY, (char *) 0);
2915c2aa98e2SPeter Wemm 		(void) close(fd);
2916c2aa98e2SPeter Wemm 	}
2917c2aa98e2SPeter Wemm #  endif /* TIOCNOTTY */
2918c2aa98e2SPeter Wemm #  ifdef SYS5SETPGRP
2919c2aa98e2SPeter Wemm 	return setpgrp();
29203299c2f1SGregory Neil Shapiro #  else /* SYS5SETPGRP */
292112ed1c7cSGregory Neil Shapiro 	return setpgid(0, CurrentPid);
29223299c2f1SGregory Neil Shapiro #  endif /* SYS5SETPGRP */
2923c2aa98e2SPeter Wemm }
2924c2aa98e2SPeter Wemm 
29253299c2f1SGregory Neil Shapiro #endif /* !HASSETSID */
292612ed1c7cSGregory Neil Shapiro /*
2927c2aa98e2SPeter Wemm **  FSYNC -- dummy fsync
2928c2aa98e2SPeter Wemm */
2929c2aa98e2SPeter Wemm 
29303299c2f1SGregory Neil Shapiro #if NEEDFSYNC
2931c2aa98e2SPeter Wemm 
2932c2aa98e2SPeter Wemm fsync(fd)
2933c2aa98e2SPeter Wemm 	int fd;
2934c2aa98e2SPeter Wemm {
2935c2aa98e2SPeter Wemm # ifdef O_SYNC
2936c2aa98e2SPeter Wemm 	return fcntl(fd, F_SETFL, O_SYNC);
29373299c2f1SGregory Neil Shapiro # else /* O_SYNC */
2938c2aa98e2SPeter Wemm 	/* nothing we can do */
2939c2aa98e2SPeter Wemm 	return 0;
29403299c2f1SGregory Neil Shapiro # endif /* O_SYNC */
2941c2aa98e2SPeter Wemm }
2942c2aa98e2SPeter Wemm 
29433299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
294412ed1c7cSGregory Neil Shapiro /*
2945c2aa98e2SPeter Wemm **  DGUX_INET_ADDR -- inet_addr for DG/UX
2946c2aa98e2SPeter Wemm **
2947c2aa98e2SPeter Wemm **	Data General DG/UX version of inet_addr returns a struct in_addr
2948c2aa98e2SPeter Wemm **	instead of a long.  This patches things.  Only needed on versions
2949c2aa98e2SPeter Wemm **	prior to 5.4.3.
2950c2aa98e2SPeter Wemm */
2951c2aa98e2SPeter Wemm 
2952c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2
2953c2aa98e2SPeter Wemm 
2954c2aa98e2SPeter Wemm # undef inet_addr
2955c2aa98e2SPeter Wemm 
2956c2aa98e2SPeter Wemm long
2957c2aa98e2SPeter Wemm dgux_inet_addr(host)
2958c2aa98e2SPeter Wemm 	char *host;
2959c2aa98e2SPeter Wemm {
2960c2aa98e2SPeter Wemm 	struct in_addr haddr;
2961c2aa98e2SPeter Wemm 
2962c2aa98e2SPeter Wemm 	haddr = inet_addr(host);
2963c2aa98e2SPeter Wemm 	return haddr.s_addr;
2964c2aa98e2SPeter Wemm }
2965c2aa98e2SPeter Wemm 
29663299c2f1SGregory Neil Shapiro #endif /* DGUX_5_4_2 */
296712ed1c7cSGregory Neil Shapiro /*
2968c2aa98e2SPeter Wemm **  GETOPT -- for old systems or systems with bogus implementations
2969c2aa98e2SPeter Wemm */
2970c2aa98e2SPeter Wemm 
297112ed1c7cSGregory Neil Shapiro #if !SM_CONF_GETOPT
2972c2aa98e2SPeter Wemm 
2973c2aa98e2SPeter Wemm /*
2974c2aa98e2SPeter Wemm  * Copyright (c) 1985 Regents of the University of California.
2975c2aa98e2SPeter Wemm  * All rights reserved.  The Berkeley software License Agreement
2976c2aa98e2SPeter Wemm  * specifies the terms and conditions for redistribution.
2977c2aa98e2SPeter Wemm  */
2978c2aa98e2SPeter Wemm 
2979c2aa98e2SPeter Wemm 
2980c2aa98e2SPeter Wemm /*
2981c2aa98e2SPeter Wemm **  this version hacked to add `atend' flag to allow state machine
2982c2aa98e2SPeter Wemm **  to reset if invoked by the program to scan args for a 2nd time
2983c2aa98e2SPeter Wemm */
2984c2aa98e2SPeter Wemm 
2985c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
2986c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c	4.3 (Berkeley) 3/9/86";
29873299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
2988c2aa98e2SPeter Wemm 
2989c2aa98e2SPeter Wemm /*
299012ed1c7cSGregory Neil Shapiro **  get option letter from argument vector
2991c2aa98e2SPeter Wemm */
2992c2aa98e2SPeter Wemm # ifdef _CONVEX_SOURCE
2993c2aa98e2SPeter Wemm extern int	optind, opterr, optopt;
2994c2aa98e2SPeter Wemm extern char	*optarg;
29953299c2f1SGregory Neil Shapiro # else /* _CONVEX_SOURCE */
2996c2aa98e2SPeter Wemm int	opterr = 1;		/* if error message should be printed */
2997c2aa98e2SPeter Wemm int	optind = 1;		/* index into parent argv vector */
2998c2aa98e2SPeter Wemm int	optopt = 0;		/* character checked for validity */
2999c2aa98e2SPeter Wemm char	*optarg = NULL;		/* argument associated with option */
30003299c2f1SGregory Neil Shapiro # endif /* _CONVEX_SOURCE */
3001c2aa98e2SPeter Wemm 
3002c2aa98e2SPeter Wemm # define BADCH	(int)'?'
3003c2aa98e2SPeter Wemm # define EMSG	""
300412ed1c7cSGregory Neil Shapiro # define tell(s)	if (opterr) \
300512ed1c7cSGregory Neil Shapiro 			{sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \
300612ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \
300712ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \
300812ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \
300912ed1c7cSGregory Neil Shapiro 			return BADCH;}
3010c2aa98e2SPeter Wemm 
3011c2aa98e2SPeter Wemm int
3012c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr)
3013c2aa98e2SPeter Wemm 	int		nargc;
3014c2aa98e2SPeter Wemm 	char *const	*nargv;
3015c2aa98e2SPeter Wemm 	const char	*ostr;
3016c2aa98e2SPeter Wemm {
3017c2aa98e2SPeter Wemm 	static char	*place = EMSG;	/* option letter processing */
3018c2aa98e2SPeter Wemm 	static char	atend = 0;
3019c2aa98e2SPeter Wemm 	register char	*oli = NULL;	/* option letter list index */
3020c2aa98e2SPeter Wemm 
3021c2aa98e2SPeter Wemm 	if (atend) {
3022c2aa98e2SPeter Wemm 		atend = 0;
3023c2aa98e2SPeter Wemm 		place = EMSG;
3024c2aa98e2SPeter Wemm 	}
3025c2aa98e2SPeter Wemm 	if(!*place) {			/* update scanning pointer */
3026c2aa98e2SPeter Wemm 		if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
3027c2aa98e2SPeter Wemm 			atend++;
3028c2aa98e2SPeter Wemm 			return -1;
3029c2aa98e2SPeter Wemm 		}
3030c2aa98e2SPeter Wemm 		if (*place == '-') {	/* found "--" */
3031c2aa98e2SPeter Wemm 			++optind;
3032c2aa98e2SPeter Wemm 			atend++;
3033c2aa98e2SPeter Wemm 			return -1;
3034c2aa98e2SPeter Wemm 		}
3035c2aa98e2SPeter Wemm 	}				/* option letter okay? */
3036c2aa98e2SPeter Wemm 	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
3037c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3038c2aa98e2SPeter Wemm 		tell(": illegal option -- ");
3039c2aa98e2SPeter Wemm 	}
3040c2aa98e2SPeter Wemm 	if (oli && *++oli != ':') {		/* don't need argument */
3041c2aa98e2SPeter Wemm 		optarg = NULL;
3042c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3043c2aa98e2SPeter Wemm 	}
3044c2aa98e2SPeter Wemm 	else {				/* need an argument */
3045c2aa98e2SPeter Wemm 		if (*place) optarg = place;	/* no white space */
3046c2aa98e2SPeter Wemm 		else if (nargc <= ++optind) {	/* no arg */
3047c2aa98e2SPeter Wemm 			place = EMSG;
3048c2aa98e2SPeter Wemm 			tell(": option requires an argument -- ");
3049c2aa98e2SPeter Wemm 		}
3050c2aa98e2SPeter Wemm 		else optarg = nargv[optind];	/* white space */
3051c2aa98e2SPeter Wemm 		place = EMSG;
3052c2aa98e2SPeter Wemm 		++optind;
3053c2aa98e2SPeter Wemm 	}
305412ed1c7cSGregory Neil Shapiro 	return optopt;			/* dump back option letter */
3055c2aa98e2SPeter Wemm }
3056c2aa98e2SPeter Wemm 
305712ed1c7cSGregory Neil Shapiro #endif /* !SM_CONF_GETOPT */
305812ed1c7cSGregory Neil Shapiro /*
3059c2aa98e2SPeter Wemm **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
3060c2aa98e2SPeter Wemm **
3061c2aa98e2SPeter Wemm **	Parameters:
3062c2aa98e2SPeter Wemm **		user -- the name of the user we are checking.
3063c2aa98e2SPeter Wemm **		shell -- the user's shell from /etc/passwd
3064c2aa98e2SPeter Wemm **
3065c2aa98e2SPeter Wemm **	Returns:
306612ed1c7cSGregory Neil Shapiro **		true -- if it is ok to use this for unrestricted access.
306712ed1c7cSGregory Neil Shapiro **		false -- if the shell is restricted.
3068c2aa98e2SPeter Wemm */
3069c2aa98e2SPeter Wemm 
3070c2aa98e2SPeter Wemm #if !HASGETUSERSHELL
3071c2aa98e2SPeter Wemm 
3072c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS
3073c2aa98e2SPeter Wemm #  define _PATH_SHELLS	"/etc/shells"
30743299c2f1SGregory Neil Shapiro # endif /* ! _PATH_SHELLS */
3075c2aa98e2SPeter Wemm 
3076c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3077c2aa98e2SPeter Wemm #  include <userconf.h>
3078c2aa98e2SPeter Wemm #  if _AIX4 >= 40200
3079c2aa98e2SPeter Wemm #   include <userpw.h>
30803299c2f1SGregory Neil Shapiro #  endif /* _AIX4 >= 40200 */
3081c2aa98e2SPeter Wemm #  include <usersec.h>
30823299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
3083c2aa98e2SPeter Wemm 
30843299c2f1SGregory Neil Shapiro static char	*DefaultUserShells[] =
3085c2aa98e2SPeter Wemm {
3086c2aa98e2SPeter Wemm 	"/bin/sh",		/* standard shell */
308712ed1c7cSGregory Neil Shapiro # ifdef MPE
308812ed1c7cSGregory Neil Shapiro 	"/SYS/PUB/CI",
308912ed1c7cSGregory Neil Shapiro # else /* MPE */
3090c2aa98e2SPeter Wemm 	"/usr/bin/sh",
3091c2aa98e2SPeter Wemm 	"/bin/csh",		/* C shell */
3092c2aa98e2SPeter Wemm 	"/usr/bin/csh",
309312ed1c7cSGregory Neil Shapiro # endif /* MPE */
3094c2aa98e2SPeter Wemm # ifdef __hpux
3095c2aa98e2SPeter Wemm #  ifdef V4FS
3096c2aa98e2SPeter Wemm 	"/usr/bin/rsh",		/* restricted Bourne shell */
3097c2aa98e2SPeter Wemm 	"/usr/bin/ksh",		/* Korn shell */
3098c2aa98e2SPeter Wemm 	"/usr/bin/rksh",	/* restricted Korn shell */
3099c2aa98e2SPeter Wemm 	"/usr/bin/pam",
3100c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3101c2aa98e2SPeter Wemm 	"/usr/bin/posix/sh",
31023299c2f1SGregory Neil Shapiro #  else /* V4FS */
3103c2aa98e2SPeter Wemm 	"/bin/rsh",		/* restricted Bourne shell */
3104c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3105c2aa98e2SPeter Wemm 	"/bin/rksh",		/* restricted Korn shell */
3106c2aa98e2SPeter Wemm 	"/bin/pam",
3107c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3108c2aa98e2SPeter Wemm 	"/bin/posix/sh",
310972936242SGregory Neil Shapiro 	"/sbin/sh",
31103299c2f1SGregory Neil Shapiro #  endif /* V4FS */
31113299c2f1SGregory Neil Shapiro # endif /* __hpux */
3112c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3113c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3114c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3115c2aa98e2SPeter Wemm 	"/bin/tsh",		/* trusted shell */
3116c2aa98e2SPeter Wemm 	"/usr/bin/tsh",
3117c2aa98e2SPeter Wemm 	"/bin/bsh",		/* Bourne shell */
3118c2aa98e2SPeter Wemm 	"/usr/bin/bsh",
31193299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
312076b7bf71SPeter Wemm # if defined(__svr4__) || defined(__svr5__)
3121c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3122c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
31233299c2f1SGregory Neil Shapiro # endif /* defined(__svr4__) || defined(__svr5__) */
3124c2aa98e2SPeter Wemm # ifdef sgi
3125c2aa98e2SPeter Wemm 	"/sbin/sh",		/* SGI's shells really live in /sbin */
31269d8fddc1SGregory Neil Shapiro 	"/usr/bin/sh",
31272ef40764SGregory Neil Shapiro 	"/sbin/bsh",		/* classic Bourne shell */
31289d8fddc1SGregory Neil Shapiro 	"/bin/bsh",
31299d8fddc1SGregory Neil Shapiro 	"/usr/bin/bsh",
31309d8fddc1SGregory Neil Shapiro 	"/sbin/csh",		/* standard csh */
31319d8fddc1SGregory Neil Shapiro 	"/bin/csh",
31329d8fddc1SGregory Neil Shapiro 	"/usr/bin/csh",
31332ef40764SGregory Neil Shapiro 	"/sbin/jsh",		/* classic Bourne shell w/ job control*/
31349d8fddc1SGregory Neil Shapiro 	"/bin/jsh",
31359d8fddc1SGregory Neil Shapiro 	"/usr/bin/jsh",
3136c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3137c2aa98e2SPeter Wemm 	"/sbin/ksh",
3138c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
31399d8fddc1SGregory Neil Shapiro 	"/sbin/tcsh",		/* Extended csh */
31409d8fddc1SGregory Neil Shapiro 	"/bin/tcsh",
3141c2aa98e2SPeter Wemm 	"/usr/bin/tcsh",
31423299c2f1SGregory Neil Shapiro # endif /* sgi */
3143c2aa98e2SPeter Wemm 	NULL
3144c2aa98e2SPeter Wemm };
3145c2aa98e2SPeter Wemm 
31463299c2f1SGregory Neil Shapiro #endif /* !HASGETUSERSHELL */
3147c2aa98e2SPeter Wemm 
3148c2aa98e2SPeter Wemm #define WILDCARD_SHELL	"/SENDMAIL/ANY/SHELL/"
3149c2aa98e2SPeter Wemm 
3150c2aa98e2SPeter Wemm bool
3151c2aa98e2SPeter Wemm usershellok(user, shell)
3152c2aa98e2SPeter Wemm 	char *user;
3153c2aa98e2SPeter Wemm 	char *shell;
3154c2aa98e2SPeter Wemm {
3155c2aa98e2SPeter Wemm # if HASGETUSERSHELL
3156c2aa98e2SPeter Wemm 	register char *p;
3157c2aa98e2SPeter Wemm 	extern char *getusershell();
3158c2aa98e2SPeter Wemm 
3159c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3160c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
316112ed1c7cSGregory Neil Shapiro 		return true;
3162c2aa98e2SPeter Wemm 
3163c2aa98e2SPeter Wemm 	setusershell();
3164c2aa98e2SPeter Wemm 	while ((p = getusershell()) != NULL)
3165c2aa98e2SPeter Wemm 		if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
3166c2aa98e2SPeter Wemm 			break;
3167c2aa98e2SPeter Wemm 	endusershell();
3168c2aa98e2SPeter Wemm 	return p != NULL;
31693299c2f1SGregory Neil Shapiro # else /* HASGETUSERSHELL */
3170c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3171c2aa98e2SPeter Wemm 	auto char *v;
31723299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
317312ed1c7cSGregory Neil Shapiro 	register SM_FILE_T *shellf;
3174c2aa98e2SPeter Wemm 	char buf[MAXLINE];
3175c2aa98e2SPeter Wemm 
3176c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3177c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
317812ed1c7cSGregory Neil Shapiro 		return true;
3179c2aa98e2SPeter Wemm 
3180c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3181c2aa98e2SPeter Wemm 	/*
3182c2aa98e2SPeter Wemm 	**  Naturally IBM has a "better" idea.....
3183c2aa98e2SPeter Wemm 	**
3184c2aa98e2SPeter Wemm 	**	What a crock.  This interface isn't documented, it is
3185c2aa98e2SPeter Wemm 	**	considered part of the security library (-ls), and it
3186c2aa98e2SPeter Wemm 	**	only works if you are running as root (since the list
3187c2aa98e2SPeter Wemm 	**	of valid shells is obviously a source of great concern).
3188c2aa98e2SPeter Wemm 	**	I recommend that you do NOT define USEGETCONFATTR,
3189c2aa98e2SPeter Wemm 	**	especially since you are going to have to set up an
3190c2aa98e2SPeter Wemm 	**	/etc/shells anyhow to handle the cases where getconfattr
3191c2aa98e2SPeter Wemm 	**	fails.
3192c2aa98e2SPeter Wemm 	*/
3193c2aa98e2SPeter Wemm 
3194c2aa98e2SPeter Wemm 	if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
3195c2aa98e2SPeter Wemm 	{
3196c2aa98e2SPeter Wemm 		while (*v != '\0')
3197c2aa98e2SPeter Wemm 		{
3198c2aa98e2SPeter Wemm 			if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
319912ed1c7cSGregory Neil Shapiro 				return true;
3200c2aa98e2SPeter Wemm 			v += strlen(v) + 1;
3201c2aa98e2SPeter Wemm 		}
320212ed1c7cSGregory Neil Shapiro 		return false;
3203c2aa98e2SPeter Wemm 	}
32043299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
3205c2aa98e2SPeter Wemm 
320612ed1c7cSGregory Neil Shapiro 	shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS,
320712ed1c7cSGregory Neil Shapiro 			    SM_IO_RDONLY, NULL);
3208c2aa98e2SPeter Wemm 	if (shellf == NULL)
3209c2aa98e2SPeter Wemm 	{
3210c2aa98e2SPeter Wemm 		/* no /etc/shells; see if it is one of the std shells */
3211c2aa98e2SPeter Wemm 		char **d;
3212c2aa98e2SPeter Wemm 
3213c2aa98e2SPeter Wemm 		if (errno != ENOENT && LogLevel > 3)
3214c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
3215c2aa98e2SPeter Wemm 				  "usershellok: cannot open %s: %s",
321612ed1c7cSGregory Neil Shapiro 				  _PATH_SHELLS, sm_errstring(errno));
3217c2aa98e2SPeter Wemm 
3218c2aa98e2SPeter Wemm 		for (d = DefaultUserShells; *d != NULL; d++)
3219c2aa98e2SPeter Wemm 		{
3220c2aa98e2SPeter Wemm 			if (strcmp(shell, *d) == 0)
322112ed1c7cSGregory Neil Shapiro 				return true;
3222c2aa98e2SPeter Wemm 		}
322312ed1c7cSGregory Neil Shapiro 		return false;
3224c2aa98e2SPeter Wemm 	}
3225c2aa98e2SPeter Wemm 
322612ed1c7cSGregory Neil Shapiro 	while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
3227c2aa98e2SPeter Wemm 	{
3228c2aa98e2SPeter Wemm 		register char *p, *q;
3229c2aa98e2SPeter Wemm 
3230c2aa98e2SPeter Wemm 		p = buf;
3231c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && *p != '/')
3232c2aa98e2SPeter Wemm 			p++;
3233c2aa98e2SPeter Wemm 		if (*p == '#' || *p == '\0')
3234c2aa98e2SPeter Wemm 			continue;
3235c2aa98e2SPeter Wemm 		q = p;
3236c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p)))
3237c2aa98e2SPeter Wemm 			p++;
3238c2aa98e2SPeter Wemm 		*p = '\0';
3239c2aa98e2SPeter Wemm 		if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
3240c2aa98e2SPeter Wemm 		{
324112ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(shellf, SM_TIME_DEFAULT);
324212ed1c7cSGregory Neil Shapiro 			return true;
3243c2aa98e2SPeter Wemm 		}
3244c2aa98e2SPeter Wemm 	}
324512ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(shellf, SM_TIME_DEFAULT);
324612ed1c7cSGregory Neil Shapiro 	return false;
32473299c2f1SGregory Neil Shapiro # endif /* HASGETUSERSHELL */
3248c2aa98e2SPeter Wemm }
324912ed1c7cSGregory Neil Shapiro /*
3250c2aa98e2SPeter Wemm **  FREEDISKSPACE -- see how much free space is on the queue filesystem
3251c2aa98e2SPeter Wemm **
3252c2aa98e2SPeter Wemm **	Only implemented if you have statfs.
3253c2aa98e2SPeter Wemm **
3254c2aa98e2SPeter Wemm **	Parameters:
3255c2aa98e2SPeter Wemm **		dir -- the directory in question.
3256c2aa98e2SPeter Wemm **		bsize -- a variable into which the filesystem
3257c2aa98e2SPeter Wemm **			block size is stored.
3258c2aa98e2SPeter Wemm **
3259c2aa98e2SPeter Wemm **	Returns:
32603299c2f1SGregory Neil Shapiro **		The number of blocks free on the queue filesystem.
3261c2aa98e2SPeter Wemm **		-1 if the statfs call fails.
3262c2aa98e2SPeter Wemm **
3263c2aa98e2SPeter Wemm **	Side effects:
3264c2aa98e2SPeter Wemm **		Puts the filesystem block size into bsize.
3265c2aa98e2SPeter Wemm */
3266c2aa98e2SPeter Wemm 
3267c2aa98e2SPeter Wemm /* statfs types */
3268c2aa98e2SPeter Wemm # define SFS_NONE	0	/* no statfs implementation */
3269c2aa98e2SPeter Wemm # define SFS_USTAT	1	/* use ustat */
3270c2aa98e2SPeter Wemm # define SFS_4ARGS	2	/* use four-argument statfs call */
3271c2aa98e2SPeter Wemm # define SFS_VFS	3	/* use <sys/vfs.h> implementation */
3272c2aa98e2SPeter Wemm # define SFS_MOUNT	4	/* use <sys/mount.h> implementation */
3273c2aa98e2SPeter Wemm # define SFS_STATFS	5	/* use <sys/statfs.h> implementation */
3274c2aa98e2SPeter Wemm # define SFS_STATVFS	6	/* use <sys/statvfs.h> implementation */
3275c2aa98e2SPeter Wemm 
3276c2aa98e2SPeter Wemm # ifndef SFS_TYPE
3277c2aa98e2SPeter Wemm #  define SFS_TYPE	SFS_NONE
32783299c2f1SGregory Neil Shapiro # endif /* ! SFS_TYPE */
3279c2aa98e2SPeter Wemm 
3280c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT
3281c2aa98e2SPeter Wemm #  include <ustat.h>
32823299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */
3283c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
3284c2aa98e2SPeter Wemm #  include <sys/statfs.h>
32853299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */
3286c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_VFS
3287c2aa98e2SPeter Wemm #  include <sys/vfs.h>
32883299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_VFS */
3289c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_MOUNT
3290c2aa98e2SPeter Wemm #  include <sys/mount.h>
32913299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_MOUNT */
3292c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS
3293c2aa98e2SPeter Wemm #  include <sys/statvfs.h>
32943299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_STATVFS */
3295c2aa98e2SPeter Wemm 
3296c2aa98e2SPeter Wemm long
3297c2aa98e2SPeter Wemm freediskspace(dir, bsize)
3298c2aa98e2SPeter Wemm 	char *dir;
3299c2aa98e2SPeter Wemm 	long *bsize;
3300c2aa98e2SPeter Wemm {
330112ed1c7cSGregory Neil Shapiro # if SFS_TYPE == SFS_NONE
330212ed1c7cSGregory Neil Shapiro 	if (bsize != NULL)
330312ed1c7cSGregory Neil Shapiro 		*bsize = 4096L;
330412ed1c7cSGregory Neil Shapiro 
330512ed1c7cSGregory Neil Shapiro 	/* assume free space is plentiful */
330612ed1c7cSGregory Neil Shapiro 	return (long) LONG_MAX;
330712ed1c7cSGregory Neil Shapiro # else /* SFS_TYPE == SFS_NONE */
3308c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3309c2aa98e2SPeter Wemm 	struct ustat fs;
3310c2aa98e2SPeter Wemm 	struct stat statbuf;
3311c2aa98e2SPeter Wemm #   define FSBLOCKSIZE	DEV_BSIZE
3312c2aa98e2SPeter Wemm #   define SFS_BAVAIL	f_tfree
33133299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3314c2aa98e2SPeter Wemm #   if defined(ultrix)
3315c2aa98e2SPeter Wemm 	struct fs_data fs;
3316c2aa98e2SPeter Wemm #    define SFS_BAVAIL	fd_bfreen
3317c2aa98e2SPeter Wemm #    define FSBLOCKSIZE	1024L
33183299c2f1SGregory Neil Shapiro #   else /* defined(ultrix) */
3319c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3320c2aa98e2SPeter Wemm 	struct statvfs fs;
3321c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_frsize
33223299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3323c2aa98e2SPeter Wemm 	struct statfs fs;
3324c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_bsize
33253299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
33263299c2f1SGregory Neil Shapiro #   endif /* defined(ultrix) */
33273299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3328c2aa98e2SPeter Wemm #  ifndef SFS_BAVAIL
3329c2aa98e2SPeter Wemm #   define SFS_BAVAIL f_bavail
33303299c2f1SGregory Neil Shapiro #  endif /* ! SFS_BAVAIL */
3331c2aa98e2SPeter Wemm 
3332c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3333c2aa98e2SPeter Wemm 	if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
33343299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3335c2aa98e2SPeter Wemm #   if SFS_TYPE == SFS_4ARGS
3336c2aa98e2SPeter Wemm 	if (statfs(dir, &fs, sizeof fs, 0) == 0)
33373299c2f1SGregory Neil Shapiro #   else /* SFS_TYPE == SFS_4ARGS */
3338c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3339c2aa98e2SPeter Wemm 	if (statvfs(dir, &fs) == 0)
33403299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3341c2aa98e2SPeter Wemm #     if defined(ultrix)
3342c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) > 0)
33433299c2f1SGregory Neil Shapiro #     else /* defined(ultrix) */
3344c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) == 0)
33453299c2f1SGregory Neil Shapiro #     endif /* defined(ultrix) */
33463299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
33473299c2f1SGregory Neil Shapiro #   endif /* SFS_TYPE == SFS_4ARGS */
33483299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3349c2aa98e2SPeter Wemm 	{
3350c2aa98e2SPeter Wemm 		if (bsize != NULL)
3351c2aa98e2SPeter Wemm 			*bsize = FSBLOCKSIZE;
3352c2aa98e2SPeter Wemm 		if (fs.SFS_BAVAIL <= 0)
3353c2aa98e2SPeter Wemm 			return 0;
3354c2aa98e2SPeter Wemm 		else if (fs.SFS_BAVAIL > LONG_MAX)
33553299c2f1SGregory Neil Shapiro 			return (long) LONG_MAX;
3356c2aa98e2SPeter Wemm 		else
3357c2aa98e2SPeter Wemm 			return (long) fs.SFS_BAVAIL;
3358c2aa98e2SPeter Wemm 	}
33593299c2f1SGregory Neil Shapiro 	return -1;
336012ed1c7cSGregory Neil Shapiro # endif /* SFS_TYPE == SFS_NONE */
3361c2aa98e2SPeter Wemm }
336212ed1c7cSGregory Neil Shapiro /*
336312ed1c7cSGregory Neil Shapiro **  ENOUGHDISKSPACE -- is there enough free space on the queue file systems?
3364c2aa98e2SPeter Wemm **
3365c2aa98e2SPeter Wemm **	Parameters:
3366c2aa98e2SPeter Wemm **		msize -- the size to check against.  If zero, we don't yet
3367c2aa98e2SPeter Wemm **		know how big the message will be, so just check for
3368c2aa98e2SPeter Wemm **		a "reasonable" amount.
336912ed1c7cSGregory Neil Shapiro **		e -- envelope, or NULL -- controls logging
3370c2aa98e2SPeter Wemm **
3371c2aa98e2SPeter Wemm **	Returns:
337212ed1c7cSGregory Neil Shapiro **		true if in every queue group there is at least one
337312ed1c7cSGregory Neil Shapiro **		queue directory whose file system contains enough free space.
337412ed1c7cSGregory Neil Shapiro **		false otherwise.
337512ed1c7cSGregory Neil Shapiro **
337612ed1c7cSGregory Neil Shapiro **	Side Effects:
337712ed1c7cSGregory Neil Shapiro **		If there is not enough disk space and e != NULL
337812ed1c7cSGregory Neil Shapiro **		then sm_syslog is called.
3379c2aa98e2SPeter Wemm */
3380c2aa98e2SPeter Wemm 
3381c2aa98e2SPeter Wemm bool
338212ed1c7cSGregory Neil Shapiro enoughdiskspace(msize, e)
3383c2aa98e2SPeter Wemm 	long msize;
338412ed1c7cSGregory Neil Shapiro 	ENVELOPE *e;
3385c2aa98e2SPeter Wemm {
338612ed1c7cSGregory Neil Shapiro 	int i;
3387c2aa98e2SPeter Wemm 
3388c2aa98e2SPeter Wemm 	if (MinBlocksFree <= 0 && msize <= 0)
3389c2aa98e2SPeter Wemm 	{
3390c2aa98e2SPeter Wemm 		if (tTd(4, 80))
339112ed1c7cSGregory Neil Shapiro 			sm_dprintf("enoughdiskspace: no threshold\n");
339212ed1c7cSGregory Neil Shapiro 		return true;
3393c2aa98e2SPeter Wemm 	}
3394c2aa98e2SPeter Wemm 
339512ed1c7cSGregory Neil Shapiro 	filesys_update();
339612ed1c7cSGregory Neil Shapiro 	for (i = 0; i < NumQueue; ++i)
3397c2aa98e2SPeter Wemm 	{
339812ed1c7cSGregory Neil Shapiro 		if (pickqdir(Queue[i], msize, e) < 0)
339912ed1c7cSGregory Neil Shapiro 			return false;
3400c2aa98e2SPeter Wemm 	}
340112ed1c7cSGregory Neil Shapiro 	return true;
3402c2aa98e2SPeter Wemm }
340312ed1c7cSGregory Neil Shapiro /*
3404c2aa98e2SPeter Wemm **  TRANSIENTERROR -- tell if an error code indicates a transient failure
3405c2aa98e2SPeter Wemm **
3406c2aa98e2SPeter Wemm **	This looks at an errno value and tells if this is likely to
3407c2aa98e2SPeter Wemm **	go away if retried later.
3408c2aa98e2SPeter Wemm **
3409c2aa98e2SPeter Wemm **	Parameters:
3410c2aa98e2SPeter Wemm **		err -- the errno code to classify.
3411c2aa98e2SPeter Wemm **
3412c2aa98e2SPeter Wemm **	Returns:
341312ed1c7cSGregory Neil Shapiro **		true if this is probably transient.
341412ed1c7cSGregory Neil Shapiro **		false otherwise.
3415c2aa98e2SPeter Wemm */
3416c2aa98e2SPeter Wemm 
3417c2aa98e2SPeter Wemm bool
3418c2aa98e2SPeter Wemm transienterror(err)
3419c2aa98e2SPeter Wemm 	int err;
3420c2aa98e2SPeter Wemm {
3421c2aa98e2SPeter Wemm 	switch (err)
3422c2aa98e2SPeter Wemm 	{
3423c2aa98e2SPeter Wemm 	  case EIO:			/* I/O error */
3424c2aa98e2SPeter Wemm 	  case ENXIO:			/* Device not configured */
3425c2aa98e2SPeter Wemm 	  case EAGAIN:			/* Resource temporarily unavailable */
3426c2aa98e2SPeter Wemm 	  case ENOMEM:			/* Cannot allocate memory */
3427c2aa98e2SPeter Wemm 	  case ENODEV:			/* Operation not supported by device */
3428c2aa98e2SPeter Wemm 	  case ENFILE:			/* Too many open files in system */
3429c2aa98e2SPeter Wemm 	  case EMFILE:			/* Too many open files */
3430c2aa98e2SPeter Wemm 	  case ENOSPC:			/* No space left on device */
3431c2aa98e2SPeter Wemm 	  case ETIMEDOUT:		/* Connection timed out */
3432c2aa98e2SPeter Wemm #ifdef ESTALE
3433c2aa98e2SPeter Wemm 	  case ESTALE:			/* Stale NFS file handle */
34343299c2f1SGregory Neil Shapiro #endif /* ESTALE */
3435c2aa98e2SPeter Wemm #ifdef ENETDOWN
3436c2aa98e2SPeter Wemm 	  case ENETDOWN:		/* Network is down */
34373299c2f1SGregory Neil Shapiro #endif /* ENETDOWN */
3438c2aa98e2SPeter Wemm #ifdef ENETUNREACH
3439c2aa98e2SPeter Wemm 	  case ENETUNREACH:		/* Network is unreachable */
34403299c2f1SGregory Neil Shapiro #endif /* ENETUNREACH */
3441c2aa98e2SPeter Wemm #ifdef ENETRESET
3442c2aa98e2SPeter Wemm 	  case ENETRESET:		/* Network dropped connection on reset */
34433299c2f1SGregory Neil Shapiro #endif /* ENETRESET */
3444c2aa98e2SPeter Wemm #ifdef ECONNABORTED
3445c2aa98e2SPeter Wemm 	  case ECONNABORTED:		/* Software caused connection abort */
34463299c2f1SGregory Neil Shapiro #endif /* ECONNABORTED */
3447c2aa98e2SPeter Wemm #ifdef ECONNRESET
3448c2aa98e2SPeter Wemm 	  case ECONNRESET:		/* Connection reset by peer */
34493299c2f1SGregory Neil Shapiro #endif /* ECONNRESET */
3450c2aa98e2SPeter Wemm #ifdef ENOBUFS
3451c2aa98e2SPeter Wemm 	  case ENOBUFS:			/* No buffer space available */
34523299c2f1SGregory Neil Shapiro #endif /* ENOBUFS */
3453c2aa98e2SPeter Wemm #ifdef ESHUTDOWN
3454c2aa98e2SPeter Wemm 	  case ESHUTDOWN:		/* Can't send after socket shutdown */
34553299c2f1SGregory Neil Shapiro #endif /* ESHUTDOWN */
3456c2aa98e2SPeter Wemm #ifdef ECONNREFUSED
3457c2aa98e2SPeter Wemm 	  case ECONNREFUSED:		/* Connection refused */
34583299c2f1SGregory Neil Shapiro #endif /* ECONNREFUSED */
3459c2aa98e2SPeter Wemm #ifdef EHOSTDOWN
3460c2aa98e2SPeter Wemm 	  case EHOSTDOWN:		/* Host is down */
34613299c2f1SGregory Neil Shapiro #endif /* EHOSTDOWN */
3462c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH
3463c2aa98e2SPeter Wemm 	  case EHOSTUNREACH:		/* No route to host */
34643299c2f1SGregory Neil Shapiro #endif /* EHOSTUNREACH */
3465c2aa98e2SPeter Wemm #ifdef EDQUOT
3466c2aa98e2SPeter Wemm 	  case EDQUOT:			/* Disc quota exceeded */
34673299c2f1SGregory Neil Shapiro #endif /* EDQUOT */
3468c2aa98e2SPeter Wemm #ifdef EPROCLIM
3469c2aa98e2SPeter Wemm 	  case EPROCLIM:		/* Too many processes */
34703299c2f1SGregory Neil Shapiro #endif /* EPROCLIM */
3471c2aa98e2SPeter Wemm #ifdef EUSERS
3472c2aa98e2SPeter Wemm 	  case EUSERS:			/* Too many users */
34733299c2f1SGregory Neil Shapiro #endif /* EUSERS */
3474c2aa98e2SPeter Wemm #ifdef EDEADLK
3475c2aa98e2SPeter Wemm 	  case EDEADLK:			/* Resource deadlock avoided */
34763299c2f1SGregory Neil Shapiro #endif /* EDEADLK */
3477c2aa98e2SPeter Wemm #ifdef EISCONN
3478c2aa98e2SPeter Wemm 	  case EISCONN:			/* Socket already connected */
34793299c2f1SGregory Neil Shapiro #endif /* EISCONN */
3480c2aa98e2SPeter Wemm #ifdef EINPROGRESS
3481c2aa98e2SPeter Wemm 	  case EINPROGRESS:		/* Operation now in progress */
34823299c2f1SGregory Neil Shapiro #endif /* EINPROGRESS */
3483c2aa98e2SPeter Wemm #ifdef EALREADY
3484c2aa98e2SPeter Wemm 	  case EALREADY:		/* Operation already in progress */
34853299c2f1SGregory Neil Shapiro #endif /* EALREADY */
3486c2aa98e2SPeter Wemm #ifdef EADDRINUSE
3487c2aa98e2SPeter Wemm 	  case EADDRINUSE:		/* Address already in use */
34883299c2f1SGregory Neil Shapiro #endif /* EADDRINUSE */
3489c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL
3490c2aa98e2SPeter Wemm 	  case EADDRNOTAVAIL:		/* Can't assign requested address */
34913299c2f1SGregory Neil Shapiro #endif /* EADDRNOTAVAIL */
3492c2aa98e2SPeter Wemm #ifdef ETXTBSY
3493c2aa98e2SPeter Wemm 	  case ETXTBSY:			/* (Apollo) file locked */
34943299c2f1SGregory Neil Shapiro #endif /* ETXTBSY */
3495c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
3496c2aa98e2SPeter Wemm 	  case ENOSR:			/* Out of streams resources */
34973299c2f1SGregory Neil Shapiro #endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */
34983299c2f1SGregory Neil Shapiro #ifdef ENOLCK
34993299c2f1SGregory Neil Shapiro 	  case ENOLCK:			/* No locks available */
35003299c2f1SGregory Neil Shapiro #endif /* ENOLCK */
3501c2aa98e2SPeter Wemm 	  case E_SM_OPENTIMEOUT:	/* PSEUDO: open timed out */
350212ed1c7cSGregory Neil Shapiro 		return true;
3503c2aa98e2SPeter Wemm 	}
3504c2aa98e2SPeter Wemm 
3505c2aa98e2SPeter Wemm 	/* nope, must be permanent */
350612ed1c7cSGregory Neil Shapiro 	return false;
3507c2aa98e2SPeter Wemm }
350812ed1c7cSGregory Neil Shapiro /*
3509c2aa98e2SPeter Wemm **  LOCKFILE -- lock a file using flock or (shudder) fcntl locking
3510c2aa98e2SPeter Wemm **
3511c2aa98e2SPeter Wemm **	Parameters:
3512c2aa98e2SPeter Wemm **		fd -- the file descriptor of the file.
3513c2aa98e2SPeter Wemm **		filename -- the file name (for error messages).
3514c2aa98e2SPeter Wemm **		ext -- the filename extension.
3515c2aa98e2SPeter Wemm **		type -- type of the lock.  Bits can be:
3516c2aa98e2SPeter Wemm **			LOCK_EX -- exclusive lock.
3517c2aa98e2SPeter Wemm **			LOCK_NB -- non-blocking.
3518c46d91b7SGregory Neil Shapiro **			LOCK_UN -- unlock.
3519c2aa98e2SPeter Wemm **
3520c2aa98e2SPeter Wemm **	Returns:
352112ed1c7cSGregory Neil Shapiro **		true if the lock was acquired.
352212ed1c7cSGregory Neil Shapiro **		false otherwise.
3523c2aa98e2SPeter Wemm */
3524c2aa98e2SPeter Wemm 
3525c2aa98e2SPeter Wemm bool
3526c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type)
3527c2aa98e2SPeter Wemm 	int fd;
3528c2aa98e2SPeter Wemm 	char *filename;
3529c2aa98e2SPeter Wemm 	char *ext;
3530c2aa98e2SPeter Wemm 	int type;
3531c2aa98e2SPeter Wemm {
3532c2aa98e2SPeter Wemm 	int i;
3533c2aa98e2SPeter Wemm 	int save_errno;
3534c2aa98e2SPeter Wemm # if !HASFLOCK
3535c2aa98e2SPeter Wemm 	int action;
3536c2aa98e2SPeter Wemm 	struct flock lfd;
3537c2aa98e2SPeter Wemm 
3538c2aa98e2SPeter Wemm 	if (ext == NULL)
3539c2aa98e2SPeter Wemm 		ext = "";
3540c2aa98e2SPeter Wemm 
35413299c2f1SGregory Neil Shapiro 	memset(&lfd, '\0', sizeof lfd);
3542c2aa98e2SPeter Wemm 	if (bitset(LOCK_UN, type))
3543c2aa98e2SPeter Wemm 		lfd.l_type = F_UNLCK;
3544c2aa98e2SPeter Wemm 	else if (bitset(LOCK_EX, type))
3545c2aa98e2SPeter Wemm 		lfd.l_type = F_WRLCK;
3546c2aa98e2SPeter Wemm 	else
3547c2aa98e2SPeter Wemm 		lfd.l_type = F_RDLCK;
3548c2aa98e2SPeter Wemm 
3549c2aa98e2SPeter Wemm 	if (bitset(LOCK_NB, type))
3550c2aa98e2SPeter Wemm 		action = F_SETLK;
3551c2aa98e2SPeter Wemm 	else
3552c2aa98e2SPeter Wemm 		action = F_SETLKW;
3553c2aa98e2SPeter Wemm 
3554c2aa98e2SPeter Wemm 	if (tTd(55, 60))
355512ed1c7cSGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, action=%d, type=%d): ",
3556c2aa98e2SPeter Wemm 			filename, ext, action, lfd.l_type);
3557c2aa98e2SPeter Wemm 
3558c2aa98e2SPeter Wemm 	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
3559c2aa98e2SPeter Wemm 		continue;
3560c2aa98e2SPeter Wemm 	if (i >= 0)
3561c2aa98e2SPeter Wemm 	{
3562c2aa98e2SPeter Wemm 		if (tTd(55, 60))
356312ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
356412ed1c7cSGregory Neil Shapiro 		return true;
3565c2aa98e2SPeter Wemm 	}
3566c2aa98e2SPeter Wemm 	save_errno = errno;
3567c2aa98e2SPeter Wemm 
3568c2aa98e2SPeter Wemm 	if (tTd(55, 60))
356912ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3570c2aa98e2SPeter Wemm 
3571c2aa98e2SPeter Wemm 	/*
3572c2aa98e2SPeter Wemm 	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
3573c2aa98e2SPeter Wemm 	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
3574c2aa98e2SPeter Wemm 	**  as type "tmp" (that is, served from swap space), the
3575c2aa98e2SPeter Wemm 	**  previous fcntl will fail with "Invalid argument" errors.
3576c2aa98e2SPeter Wemm 	**  Since this is fairly common during testing, we will assume
3577c2aa98e2SPeter Wemm 	**  that this indicates that the lock is successfully grabbed.
3578c2aa98e2SPeter Wemm 	*/
3579c2aa98e2SPeter Wemm 
3580c2aa98e2SPeter Wemm 	if (save_errno == EINVAL)
3581c2aa98e2SPeter Wemm 	{
3582c2aa98e2SPeter Wemm 		if (tTd(55, 60))
358312ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
358412ed1c7cSGregory Neil Shapiro 		return true;
3585c2aa98e2SPeter Wemm 	}
3586c2aa98e2SPeter Wemm 
35873299c2f1SGregory Neil Shapiro 	if (!bitset(LOCK_NB, type) ||
35883299c2f1SGregory Neil Shapiro 	    (save_errno != EACCES && save_errno != EAGAIN))
3589c2aa98e2SPeter Wemm 	{
3590320f00e7SGregory Neil Shapiro 		int omode = fcntl(fd, F_GETFL, 0);
3591320f00e7SGregory Neil Shapiro 		uid_t euid = geteuid();
3592320f00e7SGregory Neil Shapiro 
3593c2aa98e2SPeter Wemm 		errno = save_errno;
3594c2aa98e2SPeter Wemm 		syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3595320f00e7SGregory Neil Shapiro 		       filename, ext, fd, type, omode, euid);
359612ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3597c2aa98e2SPeter Wemm 	}
35983299c2f1SGregory Neil Shapiro # else /* !HASFLOCK */
3599c2aa98e2SPeter Wemm 	if (ext == NULL)
3600c2aa98e2SPeter Wemm 		ext = "";
3601c2aa98e2SPeter Wemm 
3602c2aa98e2SPeter Wemm 	if (tTd(55, 60))
360312ed1c7cSGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type);
3604c2aa98e2SPeter Wemm 
3605c2aa98e2SPeter Wemm 	while ((i = flock(fd, type)) < 0 && errno == EINTR)
3606c2aa98e2SPeter Wemm 		continue;
3607c2aa98e2SPeter Wemm 	if (i >= 0)
3608c2aa98e2SPeter Wemm 	{
3609c2aa98e2SPeter Wemm 		if (tTd(55, 60))
361012ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
361112ed1c7cSGregory Neil Shapiro 		return true;
3612c2aa98e2SPeter Wemm 	}
3613c2aa98e2SPeter Wemm 	save_errno = errno;
3614c2aa98e2SPeter Wemm 
3615c2aa98e2SPeter Wemm 	if (tTd(55, 60))
361612ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3617c2aa98e2SPeter Wemm 
3618c2aa98e2SPeter Wemm 	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
3619c2aa98e2SPeter Wemm 	{
3620320f00e7SGregory Neil Shapiro 		int omode = fcntl(fd, F_GETFL, 0);
3621320f00e7SGregory Neil Shapiro 		uid_t euid = geteuid();
3622320f00e7SGregory Neil Shapiro 
3623c2aa98e2SPeter Wemm 		errno = save_errno;
3624c2aa98e2SPeter Wemm 		syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3625320f00e7SGregory Neil Shapiro 			filename, ext, fd, type, omode, euid);
362612ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3627c2aa98e2SPeter Wemm 	}
36283299c2f1SGregory Neil Shapiro # endif /* !HASFLOCK */
3629c2aa98e2SPeter Wemm 	if (tTd(55, 60))
363012ed1c7cSGregory Neil Shapiro 		sm_dprintf("FAIL\n");
3631c2aa98e2SPeter Wemm 	errno = save_errno;
363212ed1c7cSGregory Neil Shapiro 	return false;
3633c2aa98e2SPeter Wemm }
363412ed1c7cSGregory Neil Shapiro /*
3635c2aa98e2SPeter Wemm **  CHOWNSAFE -- tell if chown is "safe" (executable only by root)
3636c2aa98e2SPeter Wemm **
3637c2aa98e2SPeter Wemm **	Unfortunately, given that we can't predict other systems on which
3638c2aa98e2SPeter Wemm **	a remote mounted (NFS) filesystem will be mounted, the answer is
3639c2aa98e2SPeter Wemm **	almost always that this is unsafe.
3640c2aa98e2SPeter Wemm **
3641c2aa98e2SPeter Wemm **	Note also that many operating systems have non-compliant
3642c2aa98e2SPeter Wemm **	implementations of the _POSIX_CHOWN_RESTRICTED variable and the
3643c2aa98e2SPeter Wemm **	fpathconf() routine.  According to IEEE 1003.1-1990, if
3644c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
3645c2aa98e2SPeter Wemm **	no non-root process can give away the file.  However, vendors
3646c2aa98e2SPeter Wemm **	don't take NFS into account, so a comfortable value of
3647c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED tells us nothing.
3648c2aa98e2SPeter Wemm **
3649c2aa98e2SPeter Wemm **	Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
3650c2aa98e2SPeter Wemm **	even on files where chown is not restricted.  Many systems get
3651c2aa98e2SPeter Wemm **	this wrong on NFS-based filesystems (that is, they say that chown
3652c2aa98e2SPeter Wemm **	is restricted [safe] on NFS filesystems where it may not be, since
3653c2aa98e2SPeter Wemm **	other systems can access the same filesystem and do file giveaway;
3654c2aa98e2SPeter Wemm **	only the NFS server knows for sure!)  Hence, it is important to
3655c2aa98e2SPeter Wemm **	get the value of SAFENFSPATHCONF correct -- it should be defined
3656c2aa98e2SPeter Wemm **	_only_ after testing (see test/t_pathconf.c) a system on an unsafe
3657c2aa98e2SPeter Wemm **	NFS-based filesystem to ensure that you can get meaningful results.
3658c2aa98e2SPeter Wemm **	If in doubt, assume unsafe!
3659c2aa98e2SPeter Wemm **
3660c2aa98e2SPeter Wemm **	You may also need to tweak IS_SAFE_CHOWN -- it should be a
3661c2aa98e2SPeter Wemm **	condition indicating whether the return from pathconf indicates
3662c2aa98e2SPeter Wemm **	that chown is safe (typically either > 0 or >= 0 -- there isn't
3663c2aa98e2SPeter Wemm **	even any agreement about whether a zero return means that a file
3664c2aa98e2SPeter Wemm **	is or is not safe).  It defaults to "> 0".
3665c2aa98e2SPeter Wemm **
3666c2aa98e2SPeter Wemm **	If the parent directory is safe (writable only by owner back
3667c2aa98e2SPeter Wemm **	to the root) then we can relax slightly and trust fpathconf
3668c2aa98e2SPeter Wemm **	in more circumstances.  This is really a crock -- if this is an
3669c2aa98e2SPeter Wemm **	NFS mounted filesystem then we really know nothing about the
3670c2aa98e2SPeter Wemm **	underlying implementation.  However, most systems pessimize and
3671c2aa98e2SPeter Wemm **	return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
3672c2aa98e2SPeter Wemm **	we interpret as unsafe, as we should.  Thus, this heuristic gets
3673c2aa98e2SPeter Wemm **	us into a possible problem only on systems that have a broken
3674c2aa98e2SPeter Wemm **	pathconf implementation and which are also poorly configured
3675c2aa98e2SPeter Wemm **	(have :include: files in group- or world-writable directories).
3676c2aa98e2SPeter Wemm **
3677c2aa98e2SPeter Wemm **	Parameters:
3678c2aa98e2SPeter Wemm **		fd -- the file descriptor to check.
3679c2aa98e2SPeter Wemm **		safedir -- set if the parent directory is safe.
3680c2aa98e2SPeter Wemm **
3681c2aa98e2SPeter Wemm **	Returns:
368212ed1c7cSGregory Neil Shapiro **		true -- if the chown(2) operation is "safe" -- that is,
3683c2aa98e2SPeter Wemm **			only root can chown the file to an arbitrary user.
368412ed1c7cSGregory Neil Shapiro **		false -- if an arbitrary user can give away a file.
3685c2aa98e2SPeter Wemm */
3686c2aa98e2SPeter Wemm 
3687c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN
3688c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN	> 0
36893299c2f1SGregory Neil Shapiro #endif /* ! IS_SAFE_CHOWN */
3690c2aa98e2SPeter Wemm 
3691c2aa98e2SPeter Wemm bool
3692c2aa98e2SPeter Wemm chownsafe(fd, safedir)
3693c2aa98e2SPeter Wemm 	int fd;
3694c2aa98e2SPeter Wemm 	bool safedir;
3695c2aa98e2SPeter Wemm {
3696c2aa98e2SPeter Wemm # if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \
3697c2aa98e2SPeter Wemm     (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H))
3698c2aa98e2SPeter Wemm 	int rval;
3699c2aa98e2SPeter Wemm 
3700c2aa98e2SPeter Wemm 	/* give the system administrator a chance to override */
37013299c2f1SGregory Neil Shapiro 	if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail))
370212ed1c7cSGregory Neil Shapiro 		return true;
3703c2aa98e2SPeter Wemm 
3704c2aa98e2SPeter Wemm 	/*
3705c2aa98e2SPeter Wemm 	**  Some systems (e.g., SunOS) seem to have the call and the
3706c2aa98e2SPeter Wemm 	**  #define _PC_CHOWN_RESTRICTED, but don't actually implement
3707c2aa98e2SPeter Wemm 	**  the call.  This heuristic checks for that.
3708c2aa98e2SPeter Wemm 	*/
3709c2aa98e2SPeter Wemm 
3710c2aa98e2SPeter Wemm 	errno = 0;
3711c2aa98e2SPeter Wemm 	rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
3712c2aa98e2SPeter Wemm #  if SAFENFSPATHCONF
3713c2aa98e2SPeter Wemm 	return errno == 0 && rval IS_SAFE_CHOWN;
37143299c2f1SGregory Neil Shapiro #  else /* SAFENFSPATHCONF */
3715c2aa98e2SPeter Wemm 	return safedir && errno == 0 && rval IS_SAFE_CHOWN;
37163299c2f1SGregory Neil Shapiro #  endif /* SAFENFSPATHCONF */
371712ed1c7cSGregory Neil Shapiro # else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
37183299c2f1SGregory Neil Shapiro 	return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
371912ed1c7cSGregory Neil Shapiro # endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
3720c2aa98e2SPeter Wemm }
372112ed1c7cSGregory Neil Shapiro /*
3722c2aa98e2SPeter Wemm **  RESETLIMITS -- reset system controlled resource limits
3723c2aa98e2SPeter Wemm **
3724c2aa98e2SPeter Wemm **	This is to avoid denial-of-service attacks
3725c2aa98e2SPeter Wemm **
3726c2aa98e2SPeter Wemm **	Parameters:
3727c2aa98e2SPeter Wemm **		none
3728c2aa98e2SPeter Wemm **
3729c2aa98e2SPeter Wemm **	Returns:
3730c2aa98e2SPeter Wemm **		none
3731c2aa98e2SPeter Wemm */
3732c2aa98e2SPeter Wemm 
3733c2aa98e2SPeter Wemm #if HASSETRLIMIT
3734c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H
3735c2aa98e2SPeter Wemm #  include <sys/time.h>
37363299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NEEDS_SYS_TIME_H */
3737c2aa98e2SPeter Wemm # include <sys/resource.h>
37383299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3739c2aa98e2SPeter Wemm 
3740c2aa98e2SPeter Wemm void
3741c2aa98e2SPeter Wemm resetlimits()
3742c2aa98e2SPeter Wemm {
3743c2aa98e2SPeter Wemm #if HASSETRLIMIT
3744c2aa98e2SPeter Wemm 	struct rlimit lim;
3745c2aa98e2SPeter Wemm 
3746c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
3747c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_CPU, &lim);
3748c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_FSIZE, &lim);
3749c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
3750c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
3751c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_NOFILE, &lim);
37523299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
37533299c2f1SGregory Neil Shapiro #else /* HASSETRLIMIT */
3754c2aa98e2SPeter Wemm # if HASULIMIT
3755c2aa98e2SPeter Wemm 	(void) ulimit(2, 0x3fffff);
3756c2aa98e2SPeter Wemm 	(void) ulimit(4, FD_SETSIZE);
37573299c2f1SGregory Neil Shapiro # endif /* HASULIMIT */
37583299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3759c2aa98e2SPeter Wemm 	errno = 0;
3760c2aa98e2SPeter Wemm }
376112ed1c7cSGregory Neil Shapiro /*
3762c2aa98e2SPeter Wemm **  SETVENDOR -- process vendor code from V configuration line
3763c2aa98e2SPeter Wemm **
3764c2aa98e2SPeter Wemm **	Parameters:
3765c2aa98e2SPeter Wemm **		vendor -- string representation of vendor.
3766c2aa98e2SPeter Wemm **
3767c2aa98e2SPeter Wemm **	Returns:
376812ed1c7cSGregory Neil Shapiro **		true -- if ok.
376912ed1c7cSGregory Neil Shapiro **		false -- if vendor code could not be processed.
3770c2aa98e2SPeter Wemm **
3771c2aa98e2SPeter Wemm **	Side Effects:
3772c2aa98e2SPeter Wemm **		It is reasonable to set mode flags here to tweak
3773c2aa98e2SPeter Wemm **		processing in other parts of the code if necessary.
3774c2aa98e2SPeter Wemm **		For example, if you are a vendor that uses $%y to
3775c2aa98e2SPeter Wemm **		indicate YP lookups, you could enable that here.
3776c2aa98e2SPeter Wemm */
3777c2aa98e2SPeter Wemm 
3778c2aa98e2SPeter Wemm bool
3779c2aa98e2SPeter Wemm setvendor(vendor)
3780c2aa98e2SPeter Wemm 	char *vendor;
3781c2aa98e2SPeter Wemm {
378212ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, "Berkeley") == 0)
3783c2aa98e2SPeter Wemm 	{
3784c2aa98e2SPeter Wemm 		VendorCode = VENDOR_BERKELEY;
378512ed1c7cSGregory Neil Shapiro 		return true;
3786c2aa98e2SPeter Wemm 	}
3787c2aa98e2SPeter Wemm 
3788c2aa98e2SPeter Wemm 	/* add vendor extensions here */
3789c2aa98e2SPeter Wemm 
3790c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
379112ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, "Sun") == 0)
3792c2aa98e2SPeter Wemm 	{
3793c2aa98e2SPeter Wemm 		VendorCode = VENDOR_SUN;
379412ed1c7cSGregory Neil Shapiro 		return true;
3795c2aa98e2SPeter Wemm 	}
37963299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
3797c2aa98e2SPeter Wemm 
379876b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
379912ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, VENDOR_NAME) == 0)
380076b7bf71SPeter Wemm 	{
380176b7bf71SPeter Wemm 		VendorCode = VENDOR_CODE;
380212ed1c7cSGregory Neil Shapiro 		return true;
380376b7bf71SPeter Wemm 	}
38043299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
380576b7bf71SPeter Wemm 
380612ed1c7cSGregory Neil Shapiro 	return false;
3807c2aa98e2SPeter Wemm }
380812ed1c7cSGregory Neil Shapiro /*
380976b7bf71SPeter Wemm **  GETVENDOR -- return vendor name based on vendor code
381076b7bf71SPeter Wemm **
381176b7bf71SPeter Wemm **	Parameters:
381276b7bf71SPeter Wemm **		vendorcode -- numeric representation of vendor.
381376b7bf71SPeter Wemm **
381476b7bf71SPeter Wemm **	Returns:
381576b7bf71SPeter Wemm **		string containing vendor name.
381676b7bf71SPeter Wemm */
381776b7bf71SPeter Wemm 
381876b7bf71SPeter Wemm char *
381976b7bf71SPeter Wemm getvendor(vendorcode)
382076b7bf71SPeter Wemm 	int vendorcode;
382176b7bf71SPeter Wemm {
382276b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
382376b7bf71SPeter Wemm 	/*
382476b7bf71SPeter Wemm 	**  Can't have the same switch case twice so need to
382576b7bf71SPeter Wemm 	**  handle VENDOR_CODE outside of switch.  It might
382676b7bf71SPeter Wemm 	**  match one of the existing VENDOR_* codes.
382776b7bf71SPeter Wemm 	*/
382876b7bf71SPeter Wemm 
382976b7bf71SPeter Wemm 	if (vendorcode == VENDOR_CODE)
383076b7bf71SPeter Wemm 		return VENDOR_NAME;
38313299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
383276b7bf71SPeter Wemm 
383376b7bf71SPeter Wemm 	switch (vendorcode)
383476b7bf71SPeter Wemm 	{
383576b7bf71SPeter Wemm 	  case VENDOR_BERKELEY:
383676b7bf71SPeter Wemm 		return "Berkeley";
383776b7bf71SPeter Wemm 
383876b7bf71SPeter Wemm 	  case VENDOR_SUN:
383976b7bf71SPeter Wemm 		return "Sun";
384076b7bf71SPeter Wemm 
384176b7bf71SPeter Wemm 	  case VENDOR_HP:
384276b7bf71SPeter Wemm 		return "HP";
384376b7bf71SPeter Wemm 
384476b7bf71SPeter Wemm 	  case VENDOR_IBM:
384576b7bf71SPeter Wemm 		return "IBM";
384676b7bf71SPeter Wemm 
384776b7bf71SPeter Wemm 	  case VENDOR_SENDMAIL:
384876b7bf71SPeter Wemm 		return "Sendmail";
384976b7bf71SPeter Wemm 
385076b7bf71SPeter Wemm 	  default:
385176b7bf71SPeter Wemm 		return "Unknown";
385276b7bf71SPeter Wemm 	}
385376b7bf71SPeter Wemm }
385412ed1c7cSGregory Neil Shapiro /*
3855c2aa98e2SPeter Wemm **  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
3856c2aa98e2SPeter Wemm **
3857c2aa98e2SPeter Wemm **	Vendor_pre_defaults is called before reading the configuration
3858c2aa98e2SPeter Wemm **	file; vendor_post_defaults is called immediately after.
3859c2aa98e2SPeter Wemm **
3860c2aa98e2SPeter Wemm **	Parameters:
3861c2aa98e2SPeter Wemm **		e -- the global environment to initialize.
3862c2aa98e2SPeter Wemm **
3863c2aa98e2SPeter Wemm **	Returns:
3864c2aa98e2SPeter Wemm **		none.
3865c2aa98e2SPeter Wemm */
3866c2aa98e2SPeter Wemm 
3867c2aa98e2SPeter Wemm #if SHARE_V1
3868c2aa98e2SPeter Wemm int	DefShareUid;	/* default share uid to run as -- unused??? */
38693299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3870c2aa98e2SPeter Wemm 
3871c2aa98e2SPeter Wemm void
3872c2aa98e2SPeter Wemm vendor_pre_defaults(e)
3873c2aa98e2SPeter Wemm 	ENVELOPE *e;
3874c2aa98e2SPeter Wemm {
3875c2aa98e2SPeter Wemm #if SHARE_V1
3876c2aa98e2SPeter Wemm 	/* OTHERUID is defined in shares.h, do not be alarmed */
3877c2aa98e2SPeter Wemm 	DefShareUid = OTHERUID;
38783299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3879c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3880c2aa98e2SPeter Wemm 	sun_pre_defaults(e);
38813299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
3882c2aa98e2SPeter Wemm #ifdef apollo
38833299c2f1SGregory Neil Shapiro 	/*
38843299c2f1SGregory Neil Shapiro 	**  stupid domain/os can't even open
38853299c2f1SGregory Neil Shapiro 	**  /etc/mail/sendmail.cf without this
38863299c2f1SGregory Neil Shapiro 	*/
38873299c2f1SGregory Neil Shapiro 
3888c2aa98e2SPeter Wemm 	setuserenv("ISP", NULL);
3889c2aa98e2SPeter Wemm 	setuserenv("SYSTYPE", NULL);
38903299c2f1SGregory Neil Shapiro #endif /* apollo */
3891c2aa98e2SPeter Wemm }
3892c2aa98e2SPeter Wemm 
3893c2aa98e2SPeter Wemm 
3894c2aa98e2SPeter Wemm void
3895c2aa98e2SPeter Wemm vendor_post_defaults(e)
3896c2aa98e2SPeter Wemm 	ENVELOPE *e;
3897c2aa98e2SPeter Wemm {
3898c2aa98e2SPeter Wemm #ifdef __QNX__
3899c2aa98e2SPeter Wemm 	char *p;
3900c2aa98e2SPeter Wemm 
3901c2aa98e2SPeter Wemm 	/* Makes sure the SOCK environment variable remains */
3902c2aa98e2SPeter Wemm 	if (p = getextenv("SOCK"))
3903c2aa98e2SPeter Wemm 		setuserenv("SOCK", p);
39043299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
3905c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3906c2aa98e2SPeter Wemm 	sun_post_defaults(e);
39073299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
3908c2aa98e2SPeter Wemm }
390912ed1c7cSGregory Neil Shapiro /*
3910c2aa98e2SPeter Wemm **  VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
3911c2aa98e2SPeter Wemm */
3912c2aa98e2SPeter Wemm 
3913c2aa98e2SPeter Wemm void
3914c2aa98e2SPeter Wemm vendor_daemon_setup(e)
3915c2aa98e2SPeter Wemm 	ENVELOPE *e;
3916c2aa98e2SPeter Wemm {
39173299c2f1SGregory Neil Shapiro #if HASSETLOGIN
39183299c2f1SGregory Neil Shapiro 	(void) setlogin(RunAsUserName);
39193299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
3920c2aa98e2SPeter Wemm #if SECUREWARE
3921c2aa98e2SPeter Wemm 	if (getluid() != -1)
3922c2aa98e2SPeter Wemm 	{
3923c2aa98e2SPeter Wemm 		usrerr("Daemon cannot have LUID");
392412ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_USAGE);
3925c2aa98e2SPeter Wemm 	}
3926c2aa98e2SPeter Wemm #endif /* SECUREWARE */
3927c2aa98e2SPeter Wemm }
392812ed1c7cSGregory Neil Shapiro /*
3929c2aa98e2SPeter Wemm **  VENDOR_SET_UID -- do setup for setting a user id
3930c2aa98e2SPeter Wemm **
3931c2aa98e2SPeter Wemm **	This is called when we are still root.
3932c2aa98e2SPeter Wemm **
3933c2aa98e2SPeter Wemm **	Parameters:
3934c2aa98e2SPeter Wemm **		uid -- the uid we are about to become.
3935c2aa98e2SPeter Wemm **
3936c2aa98e2SPeter Wemm **	Returns:
3937c2aa98e2SPeter Wemm **		none.
3938c2aa98e2SPeter Wemm */
3939c2aa98e2SPeter Wemm 
3940c2aa98e2SPeter Wemm void
3941c2aa98e2SPeter Wemm vendor_set_uid(uid)
3942c2aa98e2SPeter Wemm 	UID_T uid;
3943c2aa98e2SPeter Wemm {
3944c2aa98e2SPeter Wemm 	/*
3945c2aa98e2SPeter Wemm 	**  We need to setup the share groups (lnodes)
39463299c2f1SGregory Neil Shapiro 	**  and add auditing information (luid's)
3947c2aa98e2SPeter Wemm 	**  before we loose our ``root''ness.
3948c2aa98e2SPeter Wemm 	*/
3949c2aa98e2SPeter Wemm #if SHARE_V1
3950c2aa98e2SPeter Wemm 	if (setupshares(uid, syserr) != 0)
3951c2aa98e2SPeter Wemm 		syserr("Unable to set up shares");
39523299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3953c2aa98e2SPeter Wemm #if SECUREWARE
3954c2aa98e2SPeter Wemm 	(void) setup_secure(uid);
39553299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
3956c2aa98e2SPeter Wemm }
395712ed1c7cSGregory Neil Shapiro /*
3958c2aa98e2SPeter Wemm **  VALIDATE_CONNECTION -- check connection for rationality
3959c2aa98e2SPeter Wemm **
3960c2aa98e2SPeter Wemm **	If the connection is rejected, this routine should log an
3961c2aa98e2SPeter Wemm **	appropriate message -- but should never issue any SMTP protocol.
3962c2aa98e2SPeter Wemm **
3963c2aa98e2SPeter Wemm **	Parameters:
3964c2aa98e2SPeter Wemm **		sap -- a pointer to a SOCKADDR naming the peer.
3965c2aa98e2SPeter Wemm **		hostname -- the name corresponding to sap.
3966c2aa98e2SPeter Wemm **		e -- the current envelope.
3967c2aa98e2SPeter Wemm **
3968c2aa98e2SPeter Wemm **	Returns:
3969c2aa98e2SPeter Wemm **		error message from rejection.
3970c2aa98e2SPeter Wemm **		NULL if not rejected.
3971c2aa98e2SPeter Wemm */
3972c2aa98e2SPeter Wemm 
3973c2aa98e2SPeter Wemm #if TCPWRAPPERS
3974c2aa98e2SPeter Wemm # include <tcpd.h>
3975c2aa98e2SPeter Wemm 
3976c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */
3977c2aa98e2SPeter Wemm int	allow_severity	= LOG_INFO;
3978c2aa98e2SPeter Wemm int	deny_severity	= LOG_NOTICE;
39793299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
3980c2aa98e2SPeter Wemm 
3981c2aa98e2SPeter Wemm char *
3982c2aa98e2SPeter Wemm validate_connection(sap, hostname, e)
3983c2aa98e2SPeter Wemm 	SOCKADDR *sap;
3984c2aa98e2SPeter Wemm 	char *hostname;
3985c2aa98e2SPeter Wemm 	ENVELOPE *e;
3986c2aa98e2SPeter Wemm {
3987c2aa98e2SPeter Wemm #if TCPWRAPPERS
3988c2aa98e2SPeter Wemm 	char *host;
398912ed1c7cSGregory Neil Shapiro 	char *addr;
399012ed1c7cSGregory Neil Shapiro 	extern int hosts_ctl();
39913299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
3992c2aa98e2SPeter Wemm 
3993c2aa98e2SPeter Wemm 	if (tTd(48, 3))
399412ed1c7cSGregory Neil Shapiro 		sm_dprintf("validate_connection(%s, %s)\n",
3995c2aa98e2SPeter Wemm 			hostname, anynet_ntoa(sap));
3996c2aa98e2SPeter Wemm 
3997bfb62e91SGregory Neil Shapiro 	connection_rate_check(sap, e);
39983299c2f1SGregory Neil Shapiro 	if (rscheck("check_relay", hostname, anynet_ntoa(sap),
39999d8fddc1SGregory Neil Shapiro 		    e, RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID) != EX_OK)
4000c2aa98e2SPeter Wemm 	{
4001c2aa98e2SPeter Wemm 		static char reject[BUFSIZ*2];
4002c2aa98e2SPeter Wemm 		extern char MsgBuf[];
4003c2aa98e2SPeter Wemm 
4004c2aa98e2SPeter Wemm 		if (tTd(48, 4))
400512ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (rscheck)\n");
4006c2aa98e2SPeter Wemm 
40073299c2f1SGregory Neil Shapiro 		if (strlen(MsgBuf) >= 3)
400812ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(reject, MsgBuf, sizeof reject);
4009c2aa98e2SPeter Wemm 		else
401012ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(reject, "Access denied", sizeof reject);
4011c2aa98e2SPeter Wemm 
4012c2aa98e2SPeter Wemm 		return reject;
4013c2aa98e2SPeter Wemm 	}
4014c2aa98e2SPeter Wemm 
4015c2aa98e2SPeter Wemm #if TCPWRAPPERS
4016c2aa98e2SPeter Wemm 	if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']')
4017c2aa98e2SPeter Wemm 		host = "unknown";
4018c2aa98e2SPeter Wemm 	else
4019c2aa98e2SPeter Wemm 		host = hostname;
402012ed1c7cSGregory Neil Shapiro 	addr = anynet_ntoa(sap);
402112ed1c7cSGregory Neil Shapiro 
402212ed1c7cSGregory Neil Shapiro # if NETINET6
402312ed1c7cSGregory Neil Shapiro 	/* TCP/Wrappers don't want the IPv6: protocol label */
402412ed1c7cSGregory Neil Shapiro 	if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0)
402512ed1c7cSGregory Neil Shapiro 		addr += 5;
402612ed1c7cSGregory Neil Shapiro # endif /* NETINET6 */
402712ed1c7cSGregory Neil Shapiro 
402812ed1c7cSGregory Neil Shapiro 	if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN))
4029c2aa98e2SPeter Wemm 	{
4030c2aa98e2SPeter Wemm 		if (tTd(48, 4))
403112ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (tcpwrappers)\n");
403212ed1c7cSGregory Neil Shapiro 		if (LogLevel > 3)
40333299c2f1SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, e->e_id,
4034c2aa98e2SPeter Wemm 				  "tcpwrappers (%s, %s) rejection",
403512ed1c7cSGregory Neil Shapiro 				  host, addr);
4036c2aa98e2SPeter Wemm 		return "Access denied";
4037c2aa98e2SPeter Wemm 	}
40383299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
4039c2aa98e2SPeter Wemm 	if (tTd(48, 4))
404012ed1c7cSGregory Neil Shapiro 		sm_dprintf("  ... validate_connection: OK\n");
4041c2aa98e2SPeter Wemm 	return NULL;
4042c2aa98e2SPeter Wemm }
4043c2aa98e2SPeter Wemm 
404412ed1c7cSGregory Neil Shapiro /*
4045c2aa98e2SPeter Wemm **  STRTOL -- convert string to long integer
4046c2aa98e2SPeter Wemm **
4047c2aa98e2SPeter Wemm **	For systems that don't have it in the C library.
4048c2aa98e2SPeter Wemm **
4049c2aa98e2SPeter Wemm **	This is taken verbatim from the 4.4-Lite C library.
4050c2aa98e2SPeter Wemm */
4051c2aa98e2SPeter Wemm 
40523299c2f1SGregory Neil Shapiro #if NEEDSTRTOL
4053c2aa98e2SPeter Wemm 
4054c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
4055c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c	8.1 (Berkeley) 6/4/93";
40563299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
4057c2aa98e2SPeter Wemm 
4058c2aa98e2SPeter Wemm /*
405912ed1c7cSGregory Neil Shapiro **  Convert a string to a long integer.
406012ed1c7cSGregory Neil Shapiro **
406112ed1c7cSGregory Neil Shapiro **  Ignores `locale' stuff.  Assumes that the upper and lower case
406212ed1c7cSGregory Neil Shapiro **  alphabets and digits are each contiguous.
4063c2aa98e2SPeter Wemm */
4064c2aa98e2SPeter Wemm 
4065c2aa98e2SPeter Wemm long
4066c2aa98e2SPeter Wemm strtol(nptr, endptr, base)
4067c2aa98e2SPeter Wemm 	const char *nptr;
4068c2aa98e2SPeter Wemm 	char **endptr;
4069c2aa98e2SPeter Wemm 	register int base;
4070c2aa98e2SPeter Wemm {
4071c2aa98e2SPeter Wemm 	register const char *s = nptr;
4072c2aa98e2SPeter Wemm 	register unsigned long acc;
4073c2aa98e2SPeter Wemm 	register int c;
4074c2aa98e2SPeter Wemm 	register unsigned long cutoff;
4075c2aa98e2SPeter Wemm 	register int neg = 0, any, cutlim;
4076c2aa98e2SPeter Wemm 
4077c2aa98e2SPeter Wemm 	/*
407812ed1c7cSGregory Neil Shapiro 	**  Skip white space and pick up leading +/- sign if any.
407912ed1c7cSGregory Neil Shapiro 	**  If base is 0, allow 0x for hex and 0 for octal, else
408012ed1c7cSGregory Neil Shapiro 	**  assume decimal; if base is already 16, allow 0x.
4081c2aa98e2SPeter Wemm 	*/
4082c2aa98e2SPeter Wemm 	do {
4083c2aa98e2SPeter Wemm 		c = *s++;
4084c2aa98e2SPeter Wemm 	} while (isspace(c));
4085c2aa98e2SPeter Wemm 	if (c == '-') {
4086c2aa98e2SPeter Wemm 		neg = 1;
4087c2aa98e2SPeter Wemm 		c = *s++;
4088c2aa98e2SPeter Wemm 	} else if (c == '+')
4089c2aa98e2SPeter Wemm 		c = *s++;
4090c2aa98e2SPeter Wemm 	if ((base == 0 || base == 16) &&
4091c2aa98e2SPeter Wemm 	    c == '0' && (*s == 'x' || *s == 'X')) {
4092c2aa98e2SPeter Wemm 		c = s[1];
4093c2aa98e2SPeter Wemm 		s += 2;
4094c2aa98e2SPeter Wemm 		base = 16;
4095c2aa98e2SPeter Wemm 	}
4096c2aa98e2SPeter Wemm 	if (base == 0)
4097c2aa98e2SPeter Wemm 		base = c == '0' ? 8 : 10;
4098c2aa98e2SPeter Wemm 
4099c2aa98e2SPeter Wemm 	/*
410012ed1c7cSGregory Neil Shapiro 	**  Compute the cutoff value between legal numbers and illegal
410112ed1c7cSGregory Neil Shapiro 	**  numbers.  That is the largest legal value, divided by the
410212ed1c7cSGregory Neil Shapiro 	**  base.  An input number that is greater than this value, if
410312ed1c7cSGregory Neil Shapiro 	**  followed by a legal input character, is too big.  One that
410412ed1c7cSGregory Neil Shapiro 	**  is equal to this value may be valid or not; the limit
410512ed1c7cSGregory Neil Shapiro 	**  between valid and invalid numbers is then based on the last
410612ed1c7cSGregory Neil Shapiro 	**  digit.  For instance, if the range for longs is
410712ed1c7cSGregory Neil Shapiro 	**  [-2147483648..2147483647] and the input base is 10,
410812ed1c7cSGregory Neil Shapiro 	**  cutoff will be set to 214748364 and cutlim to either
410912ed1c7cSGregory Neil Shapiro 	**  7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
411012ed1c7cSGregory Neil Shapiro 	**  a value > 214748364, or equal but the next digit is > 7 (or 8),
411112ed1c7cSGregory Neil Shapiro 	**  the number is too big, and we will return a range error.
411212ed1c7cSGregory Neil Shapiro 	**
411312ed1c7cSGregory Neil Shapiro 	**  Set any if any `digits' consumed; make it negative to indicate
411412ed1c7cSGregory Neil Shapiro 	**  overflow.
4115c2aa98e2SPeter Wemm 	*/
4116c2aa98e2SPeter Wemm 	cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
4117c2aa98e2SPeter Wemm 	cutlim = cutoff % (unsigned long) base;
4118c2aa98e2SPeter Wemm 	cutoff /= (unsigned long) base;
4119c2aa98e2SPeter Wemm 	for (acc = 0, any = 0;; c = *s++) {
4120c2aa98e2SPeter Wemm 		if (isdigit(c))
4121c2aa98e2SPeter Wemm 			c -= '0';
4122c2aa98e2SPeter Wemm 		else if (isalpha(c))
4123c2aa98e2SPeter Wemm 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4124c2aa98e2SPeter Wemm 		else
4125c2aa98e2SPeter Wemm 			break;
4126c2aa98e2SPeter Wemm 		if (c >= base)
4127c2aa98e2SPeter Wemm 			break;
4128c2aa98e2SPeter Wemm 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
4129c2aa98e2SPeter Wemm 			any = -1;
4130c2aa98e2SPeter Wemm 		else {
4131c2aa98e2SPeter Wemm 			any = 1;
4132c2aa98e2SPeter Wemm 			acc *= base;
4133c2aa98e2SPeter Wemm 			acc += c;
4134c2aa98e2SPeter Wemm 		}
4135c2aa98e2SPeter Wemm 	}
4136c2aa98e2SPeter Wemm 	if (any < 0) {
4137c2aa98e2SPeter Wemm 		acc = neg ? LONG_MIN : LONG_MAX;
4138c2aa98e2SPeter Wemm 		errno = ERANGE;
4139c2aa98e2SPeter Wemm 	} else if (neg)
4140c2aa98e2SPeter Wemm 		acc = -acc;
4141c2aa98e2SPeter Wemm 	if (endptr != 0)
4142c2aa98e2SPeter Wemm 		*endptr = (char *)(any ? s - 1 : nptr);
41433299c2f1SGregory Neil Shapiro 	return acc;
4144c2aa98e2SPeter Wemm }
4145c2aa98e2SPeter Wemm 
41463299c2f1SGregory Neil Shapiro #endif /* NEEDSTRTOL */
414712ed1c7cSGregory Neil Shapiro /*
4148c2aa98e2SPeter Wemm **  STRSTR -- find first substring in string
4149c2aa98e2SPeter Wemm **
4150c2aa98e2SPeter Wemm **	Parameters:
4151c2aa98e2SPeter Wemm **		big -- the big (full) string.
4152c2aa98e2SPeter Wemm **		little -- the little (sub) string.
4153c2aa98e2SPeter Wemm **
4154c2aa98e2SPeter Wemm **	Returns:
4155c2aa98e2SPeter Wemm **		A pointer to the first instance of little in big.
4156c2aa98e2SPeter Wemm **		big if little is the null string.
4157c2aa98e2SPeter Wemm **		NULL if little is not contained in big.
4158c2aa98e2SPeter Wemm */
4159c2aa98e2SPeter Wemm 
41603299c2f1SGregory Neil Shapiro #if NEEDSTRSTR
4161c2aa98e2SPeter Wemm 
4162c2aa98e2SPeter Wemm char *
4163c2aa98e2SPeter Wemm strstr(big, little)
4164c2aa98e2SPeter Wemm 	char *big;
4165c2aa98e2SPeter Wemm 	char *little;
4166c2aa98e2SPeter Wemm {
4167c2aa98e2SPeter Wemm 	register char *p = big;
4168c2aa98e2SPeter Wemm 	int l;
4169c2aa98e2SPeter Wemm 
4170c2aa98e2SPeter Wemm 	if (*little == '\0')
4171c2aa98e2SPeter Wemm 		return big;
4172c2aa98e2SPeter Wemm 	l = strlen(little);
4173c2aa98e2SPeter Wemm 
4174c2aa98e2SPeter Wemm 	while ((p = strchr(p, *little)) != NULL)
4175c2aa98e2SPeter Wemm 	{
4176c2aa98e2SPeter Wemm 		if (strncmp(p, little, l) == 0)
4177c2aa98e2SPeter Wemm 			return p;
4178c2aa98e2SPeter Wemm 		p++;
4179c2aa98e2SPeter Wemm 	}
4180c2aa98e2SPeter Wemm 	return NULL;
4181c2aa98e2SPeter Wemm }
4182c2aa98e2SPeter Wemm 
41833299c2f1SGregory Neil Shapiro #endif /* NEEDSTRSTR */
418412ed1c7cSGregory Neil Shapiro /*
4185c2aa98e2SPeter Wemm **  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
4186c2aa98e2SPeter Wemm **
4187c2aa98e2SPeter Wemm **	Some operating systems have wierd problems with the gethostbyXXX
4188c2aa98e2SPeter Wemm **	routines.  For example, Solaris versions at least through 2.3
4189c2aa98e2SPeter Wemm **	don't properly deliver a canonical h_name field.  This tries to
4190c2aa98e2SPeter Wemm **	work around these problems.
41913299c2f1SGregory Neil Shapiro **
41923299c2f1SGregory Neil Shapiro **	Support IPv6 as well as IPv4.
4193c2aa98e2SPeter Wemm */
4194c2aa98e2SPeter Wemm 
4195c0c4794dSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
41963299c2f1SGregory Neil Shapiro 
41973299c2f1SGregory Neil Shapiro # ifndef AI_DEFAULT
41983299c2f1SGregory Neil Shapiro #  define AI_DEFAULT	0	/* dummy */
41993299c2f1SGregory Neil Shapiro # endif /* ! AI_DEFAULT */
42003299c2f1SGregory Neil Shapiro # ifndef AI_ADDRCONFIG
42013299c2f1SGregory Neil Shapiro #  define AI_ADDRCONFIG	0	/* dummy */
42023299c2f1SGregory Neil Shapiro # endif /* ! AI_ADDRCONFIG */
42033299c2f1SGregory Neil Shapiro # ifndef AI_V4MAPPED
42043299c2f1SGregory Neil Shapiro #  define AI_V4MAPPED	0	/* dummy */
42053299c2f1SGregory Neil Shapiro # endif /* ! AI_V4MAPPED */
42063299c2f1SGregory Neil Shapiro # ifndef AI_ALL
42073299c2f1SGregory Neil Shapiro #  define AI_ALL	0	/* dummy */
42083299c2f1SGregory Neil Shapiro # endif /* ! AI_ALL */
42093299c2f1SGregory Neil Shapiro 
42103299c2f1SGregory Neil Shapiro static struct hostent *
42113299c2f1SGregory Neil Shapiro getipnodebyname(name, family, flags, err)
4212c2aa98e2SPeter Wemm 	char *name;
42133299c2f1SGregory Neil Shapiro 	int family;
42143299c2f1SGregory Neil Shapiro 	int flags;
42153299c2f1SGregory Neil Shapiro 	int *err;
42163299c2f1SGregory Neil Shapiro {
421712ed1c7cSGregory Neil Shapiro 	bool resv6 = true;
42183299c2f1SGregory Neil Shapiro 	struct hostent *h;
42193299c2f1SGregory Neil Shapiro 
42203299c2f1SGregory Neil Shapiro 	if (family == AF_INET6)
42213299c2f1SGregory Neil Shapiro 	{
42223299c2f1SGregory Neil Shapiro 		/* From RFC2133, section 6.1 */
42233299c2f1SGregory Neil Shapiro 		resv6 = bitset(RES_USE_INET6, _res.options);
42243299c2f1SGregory Neil Shapiro 		_res.options |= RES_USE_INET6;
42253299c2f1SGregory Neil Shapiro 	}
4226b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
42273299c2f1SGregory Neil Shapiro 	h = gethostbyname(name);
422812ed1c7cSGregory Neil Shapiro 	if (!resv6)
42293299c2f1SGregory Neil Shapiro 		_res.options &= ~RES_USE_INET6;
423012ed1c7cSGregory Neil Shapiro 	*err = h_errno;
42313299c2f1SGregory Neil Shapiro 	return h;
42323299c2f1SGregory Neil Shapiro }
42333299c2f1SGregory Neil Shapiro 
42343299c2f1SGregory Neil Shapiro static struct hostent *
42353299c2f1SGregory Neil Shapiro getipnodebyaddr(addr, len, family, err)
42363299c2f1SGregory Neil Shapiro 	char *addr;
42373299c2f1SGregory Neil Shapiro 	int len;
42383299c2f1SGregory Neil Shapiro 	int family;
42393299c2f1SGregory Neil Shapiro 	int *err;
4240c2aa98e2SPeter Wemm {
4241c2aa98e2SPeter Wemm 	struct hostent *h;
42423299c2f1SGregory Neil Shapiro 
4243b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
42443299c2f1SGregory Neil Shapiro 	h = gethostbyaddr(addr, len, family);
42453299c2f1SGregory Neil Shapiro 	*err = h_errno;
42463299c2f1SGregory Neil Shapiro 	return h;
42473299c2f1SGregory Neil Shapiro }
4248c46d91b7SGregory Neil Shapiro 
4249c46d91b7SGregory Neil Shapiro void
4250c46d91b7SGregory Neil Shapiro freehostent(h)
4251c46d91b7SGregory Neil Shapiro 	struct hostent *h;
4252c46d91b7SGregory Neil Shapiro {
4253c46d91b7SGregory Neil Shapiro 	/*
4254c46d91b7SGregory Neil Shapiro 	**  Stub routine -- if they don't have getipnodeby*(),
4255c46d91b7SGregory Neil Shapiro 	**  they probably don't have the free routine either.
4256c46d91b7SGregory Neil Shapiro 	*/
4257c46d91b7SGregory Neil Shapiro 
4258c46d91b7SGregory Neil Shapiro 	return;
4259c46d91b7SGregory Neil Shapiro }
426012ed1c7cSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */
42613299c2f1SGregory Neil Shapiro 
42623299c2f1SGregory Neil Shapiro struct hostent *
42633299c2f1SGregory Neil Shapiro sm_gethostbyname(name, family)
42643299c2f1SGregory Neil Shapiro 	char *name;
42653299c2f1SGregory Neil Shapiro 	int family;
42663299c2f1SGregory Neil Shapiro {
4267b4662009SGregory Neil Shapiro 	int save_errno;
42683299c2f1SGregory Neil Shapiro 	struct hostent *h = NULL;
4269c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
4270c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4271c2aa98e2SPeter Wemm 	static struct hostent hp;
4272c2aa98e2SPeter Wemm 	static char buf[1000];
4273c2aa98e2SPeter Wemm 	extern struct hostent *_switch_gethostbyname_r();
4274c2aa98e2SPeter Wemm 
4275c2aa98e2SPeter Wemm 	if (tTd(61, 10))
427612ed1c7cSGregory Neil Shapiro 		sm_dprintf("_switch_gethostbyname_r(%s)... ", name);
4277c2aa98e2SPeter Wemm 	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
4278b4662009SGregory Neil Shapiro 	save_errno = errno;
42793299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4280c2aa98e2SPeter Wemm 	extern struct hostent *__switch_gethostbyname();
4281c2aa98e2SPeter Wemm 
4282c2aa98e2SPeter Wemm 	if (tTd(61, 10))
428312ed1c7cSGregory Neil Shapiro 		sm_dprintf("__switch_gethostbyname(%s)... ", name);
4284c2aa98e2SPeter Wemm 	h = __switch_gethostbyname(name);
4285b4662009SGregory Neil Shapiro 	save_errno = errno;
42863299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
42873299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4288c2aa98e2SPeter Wemm 	int nmaps;
42893299c2f1SGregory Neil Shapiro # if NETINET6
42903299c2f1SGregory Neil Shapiro 	int flags = AI_DEFAULT|AI_ALL;
42913299c2f1SGregory Neil Shapiro 	int err;
42923299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4293c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
4294c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
4295c2aa98e2SPeter Wemm 	char hbuf[MAXNAME];
4296c2aa98e2SPeter Wemm 
4297c2aa98e2SPeter Wemm 	if (tTd(61, 10))
429812ed1c7cSGregory Neil Shapiro 		sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family);
42993299c2f1SGregory Neil Shapiro 
43003299c2f1SGregory Neil Shapiro # if NETINET6
43013299c2f1SGregory Neil Shapiro #  if ADDRCONFIG_IS_BROKEN
43023299c2f1SGregory Neil Shapiro 	flags &= ~AI_ADDRCONFIG;
43033299c2f1SGregory Neil Shapiro #  endif /* ADDRCONFIG_IS_BROKEN */
43043299c2f1SGregory Neil Shapiro 	h = getipnodebyname(name, family, flags, &err);
4305b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(err);
43063299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4307c2aa98e2SPeter Wemm 	h = gethostbyname(name);
43083299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
43093299c2f1SGregory Neil Shapiro 
43103299c2f1SGregory Neil Shapiro 	save_errno = errno;
4311c2aa98e2SPeter Wemm 	if (h == NULL)
4312c2aa98e2SPeter Wemm 	{
4313c2aa98e2SPeter Wemm 		if (tTd(61, 10))
431412ed1c7cSGregory Neil Shapiro 			sm_dprintf("failure\n");
4315c2aa98e2SPeter Wemm 
4316c2aa98e2SPeter Wemm 		nmaps = switch_map_find("hosts", maptype, mapreturn);
4317c2aa98e2SPeter Wemm 		while (--nmaps >= 0)
4318c46d91b7SGregory Neil Shapiro 		{
4319c2aa98e2SPeter Wemm 			if (strcmp(maptype[nmaps], "nis") == 0 ||
4320c2aa98e2SPeter Wemm 			    strcmp(maptype[nmaps], "files") == 0)
4321c2aa98e2SPeter Wemm 				break;
4322c46d91b7SGregory Neil Shapiro 		}
4323c46d91b7SGregory Neil Shapiro 
4324c2aa98e2SPeter Wemm 		if (nmaps >= 0)
4325c2aa98e2SPeter Wemm 		{
4326c2aa98e2SPeter Wemm 			/* try short name */
432712ed1c7cSGregory Neil Shapiro 			if (strlen(name) > sizeof hbuf - 1)
43283299c2f1SGregory Neil Shapiro 			{
43293299c2f1SGregory Neil Shapiro 				errno = save_errno;
4330c2aa98e2SPeter Wemm 				return NULL;
43313299c2f1SGregory Neil Shapiro 			}
433212ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(hbuf, name, sizeof hbuf);
4333b4662009SGregory Neil Shapiro 			(void) shorten_hostname(hbuf);
4334c2aa98e2SPeter Wemm 
4335c2aa98e2SPeter Wemm 			/* if it hasn't been shortened, there's no point */
4336c2aa98e2SPeter Wemm 			if (strcmp(hbuf, name) != 0)
4337c2aa98e2SPeter Wemm 			{
4338c2aa98e2SPeter Wemm 				if (tTd(61, 10))
433912ed1c7cSGregory Neil Shapiro 					sm_dprintf("sm_gethostbyname(%s, %d)... ",
43403299c2f1SGregory Neil Shapiro 					       hbuf, family);
43413299c2f1SGregory Neil Shapiro 
43423299c2f1SGregory Neil Shapiro # if NETINET6
43436dbce3c3SGregory Neil Shapiro 				h = getipnodebyname(hbuf, family, flags, &err);
4344b4662009SGregory Neil Shapiro 				SM_SET_H_ERRNO(err);
43453299c2f1SGregory Neil Shapiro 				save_errno = errno;
43463299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4347c2aa98e2SPeter Wemm 				h = gethostbyname(hbuf);
43483299c2f1SGregory Neil Shapiro 				save_errno = errno;
43493299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4350c2aa98e2SPeter Wemm 			}
4351c2aa98e2SPeter Wemm 		}
4352c2aa98e2SPeter Wemm 	}
43533299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4354c2aa98e2SPeter Wemm 	if (tTd(61, 10))
4355c2aa98e2SPeter Wemm 	{
4356c2aa98e2SPeter Wemm 		if (h == NULL)
435712ed1c7cSGregory Neil Shapiro 			sm_dprintf("failure\n");
4358c2aa98e2SPeter Wemm 		else
43593299c2f1SGregory Neil Shapiro 		{
436012ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", h->h_name);
43613299c2f1SGregory Neil Shapiro 			if (tTd(61, 11))
43623299c2f1SGregory Neil Shapiro 			{
43633299c2f1SGregory Neil Shapiro #if NETINET6
43643299c2f1SGregory Neil Shapiro 				struct in6_addr ia6;
43653299c2f1SGregory Neil Shapiro 				char buf6[INET6_ADDRSTRLEN];
43663299c2f1SGregory Neil Shapiro #else /* NETINET6 */
43673299c2f1SGregory Neil Shapiro 				struct in_addr ia;
43683299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
436912ed1c7cSGregory Neil Shapiro 				size_t i;
43703299c2f1SGregory Neil Shapiro 
43713299c2f1SGregory Neil Shapiro 				if (h->h_aliases != NULL)
43723299c2f1SGregory Neil Shapiro 					for (i = 0; h->h_aliases[i] != NULL;
43733299c2f1SGregory Neil Shapiro 					     i++)
437412ed1c7cSGregory Neil Shapiro 						sm_dprintf("\talias: %s\n",
43753299c2f1SGregory Neil Shapiro 							h->h_aliases[i]);
43763299c2f1SGregory Neil Shapiro 				for (i = 0; h->h_addr_list[i] != NULL; i++)
43773299c2f1SGregory Neil Shapiro 				{
43783299c2f1SGregory Neil Shapiro 					char *addr;
43793299c2f1SGregory Neil Shapiro 
43803299c2f1SGregory Neil Shapiro #if NETINET6
43813299c2f1SGregory Neil Shapiro 					memmove(&ia6, h->h_addr_list[i],
43823299c2f1SGregory Neil Shapiro 						IN6ADDRSZ);
43833299c2f1SGregory Neil Shapiro 					addr = anynet_ntop(&ia6,
43843299c2f1SGregory Neil Shapiro 							   buf6, sizeof buf6);
43853299c2f1SGregory Neil Shapiro #else /* NETINET6 */
43863299c2f1SGregory Neil Shapiro 					memmove(&ia, h->h_addr_list[i],
43873299c2f1SGregory Neil Shapiro 						INADDRSZ);
43883299c2f1SGregory Neil Shapiro 					addr = (char *) inet_ntoa(ia);
43893299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
43903299c2f1SGregory Neil Shapiro 					if (addr != NULL)
439112ed1c7cSGregory Neil Shapiro 						sm_dprintf("\taddr: %s\n", addr);
4392c2aa98e2SPeter Wemm 				}
43933299c2f1SGregory Neil Shapiro 			}
43943299c2f1SGregory Neil Shapiro 		}
43953299c2f1SGregory Neil Shapiro 	}
43963299c2f1SGregory Neil Shapiro 	errno = save_errno;
4397c2aa98e2SPeter Wemm 	return h;
4398c2aa98e2SPeter Wemm }
4399c2aa98e2SPeter Wemm 
4400c2aa98e2SPeter Wemm struct hostent *
4401c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type)
4402c2aa98e2SPeter Wemm 	char *addr;
4403c2aa98e2SPeter Wemm 	int len;
4404c2aa98e2SPeter Wemm 	int type;
4405c2aa98e2SPeter Wemm {
44063299c2f1SGregory Neil Shapiro 	struct hostent *hp;
4407b4662009SGregory Neil Shapiro 
4408b4662009SGregory Neil Shapiro #if NETINET6
4409b4662009SGregory Neil Shapiro 	if (type == AF_INET6 &&
4410b4662009SGregory Neil Shapiro 	    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr))
4411b4662009SGregory Neil Shapiro 	{
4412b4662009SGregory Neil Shapiro 		/* Avoid reverse lookup for IPv6 unspecified address */
4413b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(HOST_NOT_FOUND);
4414b4662009SGregory Neil Shapiro 		return NULL;
4415b4662009SGregory Neil Shapiro 	}
4416b4662009SGregory Neil Shapiro #endif /* NETINET6 */
4417b4662009SGregory Neil Shapiro 
4418c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204)
4419c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4420b4662009SGregory Neil Shapiro 	{
44213299c2f1SGregory Neil Shapiro 		static struct hostent he;
4422c2aa98e2SPeter Wemm 		static char buf[1000];
4423c2aa98e2SPeter Wemm 		extern struct hostent *_switch_gethostbyaddr_r();
4424c2aa98e2SPeter Wemm 
4425b4662009SGregory Neil Shapiro 		hp = _switch_gethostbyaddr_r(addr, len, type, &he,
4426b4662009SGregory Neil Shapiro 					     buf, sizeof(buf), &h_errno);
4427b4662009SGregory Neil Shapiro 	}
44283299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4429b4662009SGregory Neil Shapiro 	{
4430c2aa98e2SPeter Wemm 		extern struct hostent *__switch_gethostbyaddr();
4431c2aa98e2SPeter Wemm 
44323299c2f1SGregory Neil Shapiro 		hp = __switch_gethostbyaddr(addr, len, type);
4433b4662009SGregory Neil Shapiro 	}
44343299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
44353299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
44363299c2f1SGregory Neil Shapiro # if NETINET6
4437b4662009SGregory Neil Shapiro 	{
44383299c2f1SGregory Neil Shapiro 		int err;
44393299c2f1SGregory Neil Shapiro 
44403299c2f1SGregory Neil Shapiro 		hp = getipnodebyaddr(addr, len, type, &err);
4441b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(err);
4442b4662009SGregory Neil Shapiro 	}
44433299c2f1SGregory Neil Shapiro # else /* NETINET6 */
44443299c2f1SGregory Neil Shapiro 	hp = gethostbyaddr(addr, len, type);
44453299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
44463299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
4447c0c4794dSGregory Neil Shapiro 	return hp;
4448c2aa98e2SPeter Wemm }
444912ed1c7cSGregory Neil Shapiro /*
4450c2aa98e2SPeter Wemm **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
4451c2aa98e2SPeter Wemm */
4452c2aa98e2SPeter Wemm 
4453c2aa98e2SPeter Wemm struct passwd *
4454c2aa98e2SPeter Wemm sm_getpwnam(user)
4455c2aa98e2SPeter Wemm 	char *user;
4456c2aa98e2SPeter Wemm {
4457c2aa98e2SPeter Wemm #ifdef _AIX4
4458c2aa98e2SPeter Wemm 	extern struct passwd *_getpwnam_shadow(const char *, const int);
4459c2aa98e2SPeter Wemm 
4460c2aa98e2SPeter Wemm 	return _getpwnam_shadow(user, 0);
44613299c2f1SGregory Neil Shapiro #else /* _AIX4 */
4462c2aa98e2SPeter Wemm 	return getpwnam(user);
44633299c2f1SGregory Neil Shapiro #endif /* _AIX4 */
4464c2aa98e2SPeter Wemm }
4465c2aa98e2SPeter Wemm 
4466c2aa98e2SPeter Wemm struct passwd *
4467c2aa98e2SPeter Wemm sm_getpwuid(uid)
4468c2aa98e2SPeter Wemm 	UID_T uid;
4469c2aa98e2SPeter Wemm {
4470c2aa98e2SPeter Wemm #if defined(_AIX4) && 0
4471c2aa98e2SPeter Wemm 	extern struct passwd *_getpwuid_shadow(const int, const int);
4472c2aa98e2SPeter Wemm 
4473c2aa98e2SPeter Wemm 	return _getpwuid_shadow(uid,0);
44743299c2f1SGregory Neil Shapiro #else /* defined(_AIX4) && 0 */
4475c2aa98e2SPeter Wemm 	return getpwuid(uid);
44763299c2f1SGregory Neil Shapiro #endif /* defined(_AIX4) && 0 */
4477c2aa98e2SPeter Wemm }
447812ed1c7cSGregory Neil Shapiro /*
4479c2aa98e2SPeter Wemm **  SECUREWARE_SETUP_SECURE -- Convex SecureWare setup
4480c2aa98e2SPeter Wemm **
4481c2aa98e2SPeter Wemm **	Set up the trusted computing environment for C2 level security
4482c2aa98e2SPeter Wemm **	under SecureWare.
4483c2aa98e2SPeter Wemm **
4484c2aa98e2SPeter Wemm **	Parameters:
4485c2aa98e2SPeter Wemm **		uid -- uid of the user to initialize in the TCB
4486c2aa98e2SPeter Wemm **
4487c2aa98e2SPeter Wemm **	Returns:
4488c2aa98e2SPeter Wemm **		none
4489c2aa98e2SPeter Wemm **
4490c2aa98e2SPeter Wemm **	Side Effects:
4491c2aa98e2SPeter Wemm **		Initialized the user in the trusted computing base
4492c2aa98e2SPeter Wemm */
4493c2aa98e2SPeter Wemm 
4494c2aa98e2SPeter Wemm #if SECUREWARE
4495c2aa98e2SPeter Wemm 
4496c2aa98e2SPeter Wemm # include <sys/security.h>
4497c2aa98e2SPeter Wemm # include <prot.h>
4498c2aa98e2SPeter Wemm 
4499c2aa98e2SPeter Wemm void
4500c2aa98e2SPeter Wemm secureware_setup_secure(uid)
4501c2aa98e2SPeter Wemm 	UID_T uid;
4502c2aa98e2SPeter Wemm {
4503c2aa98e2SPeter Wemm 	int rc;
4504c2aa98e2SPeter Wemm 
4505c2aa98e2SPeter Wemm 	if (getluid() != -1)
4506c2aa98e2SPeter Wemm 		return;
4507c2aa98e2SPeter Wemm 
4508c2aa98e2SPeter Wemm 	if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN)
4509c2aa98e2SPeter Wemm 	{
4510c2aa98e2SPeter Wemm 		switch (rc)
4511c2aa98e2SPeter Wemm 		{
4512c2aa98e2SPeter Wemm 		  case SSI_NO_PRPW_ENTRY:
451312ed1c7cSGregory Neil Shapiro 			syserr("No protected passwd entry, uid = %d",
451412ed1c7cSGregory Neil Shapiro 			       (int) uid);
4515c2aa98e2SPeter Wemm 			break;
4516c2aa98e2SPeter Wemm 
4517c2aa98e2SPeter Wemm 		  case SSI_LOCKED:
451812ed1c7cSGregory Neil Shapiro 			syserr("Account has been disabled, uid = %d",
451912ed1c7cSGregory Neil Shapiro 			       (int) uid);
4520c2aa98e2SPeter Wemm 			break;
4521c2aa98e2SPeter Wemm 
4522c2aa98e2SPeter Wemm 		  case SSI_RETIRED:
452312ed1c7cSGregory Neil Shapiro 			syserr("Account has been retired, uid = %d",
452412ed1c7cSGregory Neil Shapiro 			       (int) uid);
4525c2aa98e2SPeter Wemm 			break;
4526c2aa98e2SPeter Wemm 
4527c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_LUID:
452812ed1c7cSGregory Neil Shapiro 			syserr("Could not set LUID, uid = %d", (int) uid);
4529c2aa98e2SPeter Wemm 			break;
4530c2aa98e2SPeter Wemm 
4531c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_PRIVS:
453212ed1c7cSGregory Neil Shapiro 			syserr("Could not set kernel privs, uid = %d",
453312ed1c7cSGregory Neil Shapiro 			       (int) uid);
4534c2aa98e2SPeter Wemm 
4535c2aa98e2SPeter Wemm 		  default:
4536c2aa98e2SPeter Wemm 			syserr("Unknown return code (%d) from set_secure_info(%d)",
453712ed1c7cSGregory Neil Shapiro 				rc, (int) uid);
4538c2aa98e2SPeter Wemm 			break;
4539c2aa98e2SPeter Wemm 		}
454012ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_NOPERM);
4541c2aa98e2SPeter Wemm 	}
4542c2aa98e2SPeter Wemm }
4543c2aa98e2SPeter Wemm #endif /* SECUREWARE */
454412ed1c7cSGregory Neil Shapiro /*
45453299c2f1SGregory Neil Shapiro **  ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address
454676b7bf71SPeter Wemm **
454776b7bf71SPeter Wemm **	Add hostnames to class 'w' based on the IP address read from
454876b7bf71SPeter Wemm **	the network interface.
454976b7bf71SPeter Wemm **
455076b7bf71SPeter Wemm **	Parameters:
455176b7bf71SPeter Wemm **		sa -- a pointer to a SOCKADDR containing the address
455276b7bf71SPeter Wemm **
455376b7bf71SPeter Wemm **	Returns:
455476b7bf71SPeter Wemm **		0 if successful, -1 if host lookup fails.
455576b7bf71SPeter Wemm */
455676b7bf71SPeter Wemm 
45573299c2f1SGregory Neil Shapiro static int
455876b7bf71SPeter Wemm add_hostnames(sa)
455976b7bf71SPeter Wemm 	SOCKADDR *sa;
456076b7bf71SPeter Wemm {
456176b7bf71SPeter Wemm 	struct hostent *hp;
45623299c2f1SGregory Neil Shapiro 	char **ha;
45633299c2f1SGregory Neil Shapiro 	char hnb[MAXHOSTNAMELEN];
456476b7bf71SPeter Wemm 
456576b7bf71SPeter Wemm 	/* lookup name with IP address */
456676b7bf71SPeter Wemm 	switch (sa->sa.sa_family)
456776b7bf71SPeter Wemm 	{
45683299c2f1SGregory Neil Shapiro #if NETINET
456976b7bf71SPeter Wemm 	  case AF_INET:
457076b7bf71SPeter Wemm 		hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr,
4571c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin.sin_addr),
4572c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
457376b7bf71SPeter Wemm 		break;
45743299c2f1SGregory Neil Shapiro #endif /* NETINET */
45753299c2f1SGregory Neil Shapiro 
45763299c2f1SGregory Neil Shapiro #if NETINET6
45773299c2f1SGregory Neil Shapiro 	  case AF_INET6:
45783299c2f1SGregory Neil Shapiro 		hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr,
4579c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin6.sin6_addr),
4580c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
45813299c2f1SGregory Neil Shapiro 		break;
45823299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
458376b7bf71SPeter Wemm 
458476b7bf71SPeter Wemm 	  default:
45853299c2f1SGregory Neil Shapiro 		/* Give warning about unsupported family */
458676b7bf71SPeter Wemm 		if (LogLevel > 3)
458776b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
458876b7bf71SPeter Wemm 				  "Unsupported address family %d: %.100s",
458976b7bf71SPeter Wemm 				  sa->sa.sa_family, anynet_ntoa(sa));
459076b7bf71SPeter Wemm 		return -1;
459176b7bf71SPeter Wemm 	}
459276b7bf71SPeter Wemm 
459376b7bf71SPeter Wemm 	if (hp == NULL)
459476b7bf71SPeter Wemm 	{
459576b7bf71SPeter Wemm 		int save_errno = errno;
459676b7bf71SPeter Wemm 
45973299c2f1SGregory Neil Shapiro 		if (LogLevel > 3 &&
45983299c2f1SGregory Neil Shapiro #if NETINET6
45993299c2f1SGregory Neil Shapiro 		    !(sa->sa.sa_family == AF_INET6 &&
46003299c2f1SGregory Neil Shapiro 		      IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
46013299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
460212ed1c7cSGregory Neil Shapiro 		    true)
460376b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
460412ed1c7cSGregory Neil Shapiro 				  "gethostbyaddr(%.100s) failed: %d",
460576b7bf71SPeter Wemm 				  anynet_ntoa(sa),
460676b7bf71SPeter Wemm #if NAMED_BIND
460776b7bf71SPeter Wemm 				  h_errno
46083299c2f1SGregory Neil Shapiro #else /* NAMED_BIND */
460976b7bf71SPeter Wemm 				  -1
46103299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
461176b7bf71SPeter Wemm 				 );
461276b7bf71SPeter Wemm 		errno = save_errno;
461376b7bf71SPeter Wemm 		return -1;
461476b7bf71SPeter Wemm 	}
461576b7bf71SPeter Wemm 
461676b7bf71SPeter Wemm 	/* save its cname */
461776b7bf71SPeter Wemm 	if (!wordinclass((char *) hp->h_name, 'w'))
461876b7bf71SPeter Wemm 	{
461976b7bf71SPeter Wemm 		setclass('w', (char *) hp->h_name);
462076b7bf71SPeter Wemm 		if (tTd(0, 4))
462112ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s\n", hp->h_name);
46223299c2f1SGregory Neil Shapiro 
462312ed1c7cSGregory Neil Shapiro 		if (sm_snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb
46243299c2f1SGregory Neil Shapiro 		    && !wordinclass((char *) hnb, 'w'))
46253299c2f1SGregory Neil Shapiro 			setclass('w', hnb);
46263299c2f1SGregory Neil Shapiro 	}
46273299c2f1SGregory Neil Shapiro 	else
46283299c2f1SGregory Neil Shapiro 	{
46293299c2f1SGregory Neil Shapiro 		if (tTd(0, 43))
463012ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name);
463176b7bf71SPeter Wemm 	}
463276b7bf71SPeter Wemm 
463376b7bf71SPeter Wemm 	/* save all it aliases name */
46343299c2f1SGregory Neil Shapiro 	for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
463576b7bf71SPeter Wemm 	{
46363299c2f1SGregory Neil Shapiro 		if (!wordinclass(*ha, 'w'))
463776b7bf71SPeter Wemm 		{
46383299c2f1SGregory Neil Shapiro 			setclass('w', *ha);
463976b7bf71SPeter Wemm 			if (tTd(0, 4))
464012ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", *ha);
464112ed1c7cSGregory Neil Shapiro 			if (sm_snprintf(hnb, sizeof hnb,
46423299c2f1SGregory Neil Shapiro 				     "[%s]", *ha) < sizeof hnb &&
46433299c2f1SGregory Neil Shapiro 			    !wordinclass((char *) hnb, 'w'))
46443299c2f1SGregory Neil Shapiro 				setclass('w', hnb);
464576b7bf71SPeter Wemm 		}
46463299c2f1SGregory Neil Shapiro 		else
46473299c2f1SGregory Neil Shapiro 		{
46483299c2f1SGregory Neil Shapiro 			if (tTd(0, 43))
464912ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s (already in $=w)\n",
46503299c2f1SGregory Neil Shapiro 					*ha);
46513299c2f1SGregory Neil Shapiro 		}
465276b7bf71SPeter Wemm 	}
465312ed1c7cSGregory Neil Shapiro #if NETINET6
4654c46d91b7SGregory Neil Shapiro 	freehostent(hp);
465512ed1c7cSGregory Neil Shapiro #endif /* NETINET6 */
465676b7bf71SPeter Wemm 	return 0;
465776b7bf71SPeter Wemm }
465812ed1c7cSGregory Neil Shapiro /*
4659c2aa98e2SPeter Wemm **  LOAD_IF_NAMES -- load interface-specific names into $=w
4660c2aa98e2SPeter Wemm **
4661c2aa98e2SPeter Wemm **	Parameters:
4662c2aa98e2SPeter Wemm **		none.
4663c2aa98e2SPeter Wemm **
4664c2aa98e2SPeter Wemm **	Returns:
4665c2aa98e2SPeter Wemm **		none.
4666c2aa98e2SPeter Wemm **
4667c2aa98e2SPeter Wemm **	Side Effects:
4668c2aa98e2SPeter Wemm **		Loads $=w with the names of all the interfaces.
4669c2aa98e2SPeter Wemm */
4670c2aa98e2SPeter Wemm 
46713299c2f1SGregory Neil Shapiro #if !NETINET
46723299c2f1SGregory Neil Shapiro # define SIOCGIFCONF_IS_BROKEN	1 /* XXX */
46733299c2f1SGregory Neil Shapiro #endif /* !NETINET */
46743299c2f1SGregory Neil Shapiro 
4675c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4676c2aa98e2SPeter Wemm struct rtentry;
4677c2aa98e2SPeter Wemm struct mbuf;
4678c2aa98e2SPeter Wemm # ifndef SUNOS403
4679c2aa98e2SPeter Wemm #  include <sys/time.h>
46803299c2f1SGregory Neil Shapiro # endif /* ! SUNOS403 */
46813299c2f1SGregory Neil Shapiro # if (_AIX4 >= 40300) && !defined(_NET_IF_H)
4682c2aa98e2SPeter Wemm #  undef __P
46833299c2f1SGregory Neil Shapiro # endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */
4684c2aa98e2SPeter Wemm # include <net/if.h>
46853299c2f1SGregory Neil Shapiro #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
4686c2aa98e2SPeter Wemm 
4687c2aa98e2SPeter Wemm void
4688c2aa98e2SPeter Wemm load_if_names()
4689c2aa98e2SPeter Wemm {
46903299c2f1SGregory Neil Shapiro # if NETINET6 && defined(SIOCGLIFCONF)
469112ed1c7cSGregory Neil Shapiro #  ifdef __hpux
469212ed1c7cSGregory Neil Shapiro 
469312ed1c7cSGregory Neil Shapiro     /*
469412ed1c7cSGregory Neil Shapiro     **  Unfortunately, HP has changed all of the structures,
469512ed1c7cSGregory Neil Shapiro     **  making life difficult for implementors.
469612ed1c7cSGregory Neil Shapiro     */
469712ed1c7cSGregory Neil Shapiro 
469812ed1c7cSGregory Neil Shapiro #   define lifconf	if_laddrconf
469912ed1c7cSGregory Neil Shapiro #   define lifc_len	iflc_len
470012ed1c7cSGregory Neil Shapiro #   define lifc_buf	iflc_buf
470112ed1c7cSGregory Neil Shapiro #   define lifreq	if_laddrreq
470212ed1c7cSGregory Neil Shapiro #   define lifr_addr	iflr_addr
470312ed1c7cSGregory Neil Shapiro #   define lifr_name	iflr_name
470412ed1c7cSGregory Neil Shapiro #   define lifr_flags	iflr_flags
470512ed1c7cSGregory Neil Shapiro #   define ss_family	sa_family
470612ed1c7cSGregory Neil Shapiro #   undef SIOCGLIFNUM
470712ed1c7cSGregory Neil Shapiro #  endif /* __hpux */
470812ed1c7cSGregory Neil Shapiro 
47093299c2f1SGregory Neil Shapiro 	int s;
47103299c2f1SGregory Neil Shapiro 	int i;
471112ed1c7cSGregory Neil Shapiro 	size_t len;
47123299c2f1SGregory Neil Shapiro 	int numifs;
471312ed1c7cSGregory Neil Shapiro 	char *buf;
471412ed1c7cSGregory Neil Shapiro 	struct lifconf lifc;
471512ed1c7cSGregory Neil Shapiro #  ifdef SIOCGLIFNUM
471612ed1c7cSGregory Neil Shapiro 	struct lifnum lifn;
471712ed1c7cSGregory Neil Shapiro #  endif /* SIOCGLIFNUM */
47183299c2f1SGregory Neil Shapiro 
47193299c2f1SGregory Neil Shapiro 	s = socket(InetMode, SOCK_DGRAM, 0);
47203299c2f1SGregory Neil Shapiro 	if (s == -1)
47213299c2f1SGregory Neil Shapiro 		return;
47223299c2f1SGregory Neil Shapiro 
47233299c2f1SGregory Neil Shapiro 	/* get the list of known IP address from the kernel */
472412ed1c7cSGregory Neil Shapiro #  ifdef __hpux
472512ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGIFNUM, (char *) &numifs);
472612ed1c7cSGregory Neil Shapiro #  endif /* __hpux */
47273299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFNUM
47283299c2f1SGregory Neil Shapiro 	lifn.lifn_family = AF_UNSPEC;
47293299c2f1SGregory Neil Shapiro 	lifn.lifn_flags = 0;
473012ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGLIFNUM, (char *)&lifn);
473112ed1c7cSGregory Neil Shapiro 	numifs = lifn.lifn_count;
473212ed1c7cSGregory Neil Shapiro #  endif /* SIOCGLIFNUM */
473312ed1c7cSGregory Neil Shapiro 
473412ed1c7cSGregory Neil Shapiro #  if defined(__hpux) || defined(SIOCGLIFNUM)
473512ed1c7cSGregory Neil Shapiro 	if (i < 0)
47363299c2f1SGregory Neil Shapiro 	{
47373299c2f1SGregory Neil Shapiro 		/* can't get number of interfaces -- fall back */
47383299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
473912ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFNUM failed: %s\n",
474012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
47413299c2f1SGregory Neil Shapiro 		numifs = -1;
47423299c2f1SGregory Neil Shapiro 	}
474312ed1c7cSGregory Neil Shapiro 	else if (tTd(0, 42))
474412ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
47453299c2f1SGregory Neil Shapiro 	if (numifs < 0)
474612ed1c7cSGregory Neil Shapiro #  endif /* defined(__hpux) || defined(SIOCGLIFNUM) */
47473299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
47483299c2f1SGregory Neil Shapiro 
47493299c2f1SGregory Neil Shapiro 	if (numifs <= 0)
47503299c2f1SGregory Neil Shapiro 	{
4751c46d91b7SGregory Neil Shapiro 		(void) close(s);
47523299c2f1SGregory Neil Shapiro 		return;
47533299c2f1SGregory Neil Shapiro 	}
475412ed1c7cSGregory Neil Shapiro 
475512ed1c7cSGregory Neil Shapiro 	len = lifc.lifc_len = numifs * sizeof (struct lifreq);
475612ed1c7cSGregory Neil Shapiro 	buf = lifc.lifc_buf = xalloc(lifc.lifc_len);
475712ed1c7cSGregory Neil Shapiro #  ifndef __hpux
47583299c2f1SGregory Neil Shapiro 	lifc.lifc_family = AF_UNSPEC;
47593299c2f1SGregory Neil Shapiro 	lifc.lifc_flags = 0;
47607660b554SGregory Neil Shapiro #  endif /* ! __hpux */
47613299c2f1SGregory Neil Shapiro 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
47623299c2f1SGregory Neil Shapiro 	{
47633299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
476412ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFCONF failed: %s\n",
476512ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
4766c46d91b7SGregory Neil Shapiro 		(void) close(s);
476712ed1c7cSGregory Neil Shapiro 		sm_free(buf);
47683299c2f1SGregory Neil Shapiro 		return;
47693299c2f1SGregory Neil Shapiro 	}
47703299c2f1SGregory Neil Shapiro 
47713299c2f1SGregory Neil Shapiro 	/* scan the list of IP address */
47723299c2f1SGregory Neil Shapiro 	if (tTd(0, 40))
477312ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, lifc_len=%ld\n",
477412ed1c7cSGregory Neil Shapiro 			   (long) len);
47753299c2f1SGregory Neil Shapiro 
477612ed1c7cSGregory Neil Shapiro 	for (i = 0; i < len && i >= 0; )
47773299c2f1SGregory Neil Shapiro 	{
477812ed1c7cSGregory Neil Shapiro 		int flags;
477912ed1c7cSGregory Neil Shapiro 		struct lifreq *ifr = (struct lifreq *)&buf[i];
47803299c2f1SGregory Neil Shapiro 		SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr;
478112ed1c7cSGregory Neil Shapiro 		int af = ifr->lifr_addr.ss_family;
47823299c2f1SGregory Neil Shapiro 		char *addr;
478312ed1c7cSGregory Neil Shapiro 		char *name;
47843299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
47853299c2f1SGregory Neil Shapiro 		struct in_addr ia;
47863299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
47873299c2f1SGregory Neil Shapiro 		struct lifreq ifrf;
47883299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
47893299c2f1SGregory Neil Shapiro 		char ip_addr[256];
47903299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
47913299c2f1SGregory Neil Shapiro 
47923299c2f1SGregory Neil Shapiro 		/*
47933299c2f1SGregory Neil Shapiro 		**  We must close and recreate the socket each time
47943299c2f1SGregory Neil Shapiro 		**  since we don't know what type of socket it is now
47953299c2f1SGregory Neil Shapiro 		**  (each status function may change it).
47963299c2f1SGregory Neil Shapiro 		*/
47973299c2f1SGregory Neil Shapiro 
47983299c2f1SGregory Neil Shapiro 		(void) close(s);
47993299c2f1SGregory Neil Shapiro 
48003299c2f1SGregory Neil Shapiro 		s = socket(af, SOCK_DGRAM, 0);
48013299c2f1SGregory Neil Shapiro 		if (s == -1)
4802c46d91b7SGregory Neil Shapiro 		{
480312ed1c7cSGregory Neil Shapiro 			sm_free(buf); /* XXX */
48043299c2f1SGregory Neil Shapiro 			return;
4805c46d91b7SGregory Neil Shapiro 		}
48063299c2f1SGregory Neil Shapiro 
48073299c2f1SGregory Neil Shapiro 		/*
48083299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
48093299c2f1SGregory Neil Shapiro 		**  don't try to use it.
48103299c2f1SGregory Neil Shapiro 		*/
48113299c2f1SGregory Neil Shapiro 
481212ed1c7cSGregory Neil Shapiro 		if ((len - i) < sizeof *ifr)
48133299c2f1SGregory Neil Shapiro 			break;
48143299c2f1SGregory Neil Shapiro 
48153299c2f1SGregory Neil Shapiro #  ifdef BSD4_4_SOCKADDR
48163299c2f1SGregory Neil Shapiro 		if (sa->sa.sa_len > sizeof ifr->lifr_addr)
48173299c2f1SGregory Neil Shapiro 			i += sizeof ifr->lifr_name + sa->sa.sa_len;
48183299c2f1SGregory Neil Shapiro 		else
48193299c2f1SGregory Neil Shapiro #  endif /* BSD4_4_SOCKADDR */
48203299c2f1SGregory Neil Shapiro 			i += sizeof *ifr;
48213299c2f1SGregory Neil Shapiro 
48223299c2f1SGregory Neil Shapiro 		if (tTd(0, 20))
482312ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
48243299c2f1SGregory Neil Shapiro 
48253299c2f1SGregory Neil Shapiro 		if (af != AF_INET && af != AF_INET6)
48263299c2f1SGregory Neil Shapiro 			continue;
48273299c2f1SGregory Neil Shapiro 
48283299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
48293299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct lifreq));
483012ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name,
48313299c2f1SGregory Neil Shapiro 				  sizeof(ifrf.lifr_name));
48323299c2f1SGregory Neil Shapiro 		if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0)
48333299c2f1SGregory Neil Shapiro 		{
48343299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
483512ed1c7cSGregory Neil Shapiro 				sm_dprintf("SIOCGLIFFLAGS failed: %s\n",
483612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
48373299c2f1SGregory Neil Shapiro 			continue;
48383299c2f1SGregory Neil Shapiro 		}
48393299c2f1SGregory Neil Shapiro 
484012ed1c7cSGregory Neil Shapiro 		name = ifr->lifr_name;
484112ed1c7cSGregory Neil Shapiro 		flags = ifrf.lifr_flags;
484212ed1c7cSGregory Neil Shapiro 
484312ed1c7cSGregory Neil Shapiro 		if (tTd(0, 41))
484412ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n", (unsigned long) flags);
484512ed1c7cSGregory Neil Shapiro 
484612ed1c7cSGregory Neil Shapiro 		if (!bitset(IFF_UP, flags))
48473299c2f1SGregory Neil Shapiro 			continue;
48483299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
48493299c2f1SGregory Neil Shapiro 
48503299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
48513299c2f1SGregory Neil Shapiro 
48523299c2f1SGregory Neil Shapiro 		/* extract IP address from the list*/
48533299c2f1SGregory Neil Shapiro 		switch (af)
48543299c2f1SGregory Neil Shapiro 		{
48553299c2f1SGregory Neil Shapiro 		  case AF_INET6:
4856c46d91b7SGregory Neil Shapiro #  ifdef __KAME__
4857b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
4858b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
4859b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
4860c46d91b7SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
4861c46d91b7SGregory Neil Shapiro 			{
4862b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
4863b4662009SGregory Neil Shapiro 
4864b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
4865b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
4866b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
4867b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
4868c46d91b7SGregory Neil Shapiro 			}
4869c46d91b7SGregory Neil Shapiro #  endif /* __KAME__ */
4870b4662009SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
4871c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
48723299c2f1SGregory Neil Shapiro 			{
48733299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
48743299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
487512ed1c7cSGregory Neil Shapiro 					name, addr == NULL ? "(NULL)" : addr);
48763299c2f1SGregory Neil Shapiro 				continue;
48773299c2f1SGregory Neil Shapiro 			}
48783299c2f1SGregory Neil Shapiro 
48793299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
48803299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
48813299c2f1SGregory Neil Shapiro 			if (addr != NULL)
488212ed1c7cSGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
48833299c2f1SGregory Neil Shapiro 						   "[%.*s]",
488412ed1c7cSGregory Neil Shapiro 						   (int) sizeof ip_addr - 3,
488512ed1c7cSGregory Neil Shapiro 						   addr);
48863299c2f1SGregory Neil Shapiro 			break;
48873299c2f1SGregory Neil Shapiro 
48883299c2f1SGregory Neil Shapiro 		  case AF_INET:
48893299c2f1SGregory Neil Shapiro 			ia = sa->sin.sin_addr;
48903299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
48913299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
48923299c2f1SGregory Neil Shapiro 			{
48933299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
489412ed1c7cSGregory Neil Shapiro 					name, inet_ntoa(ia));
48953299c2f1SGregory Neil Shapiro 				continue;
48963299c2f1SGregory Neil Shapiro 			}
48973299c2f1SGregory Neil Shapiro 
48983299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
489912ed1c7cSGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
4900d995d2baSGregory Neil Shapiro 					(int) sizeof ip_addr - 3, inet_ntoa(ia));
49013299c2f1SGregory Neil Shapiro 			break;
49023299c2f1SGregory Neil Shapiro 		}
49033299c2f1SGregory Neil Shapiro 
49043299c2f1SGregory Neil Shapiro 		if (*ip_addr == '\0')
49053299c2f1SGregory Neil Shapiro 			continue;
49063299c2f1SGregory Neil Shapiro 
49073299c2f1SGregory Neil Shapiro 		if (!wordinclass(ip_addr, 'w'))
49083299c2f1SGregory Neil Shapiro 		{
49093299c2f1SGregory Neil Shapiro 			setclass('w', ip_addr);
49103299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
491112ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
49123299c2f1SGregory Neil Shapiro 		}
49133299c2f1SGregory Neil Shapiro 
49143299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
49153299c2f1SGregory Neil Shapiro 		/* skip "loopback" interface "lo" */
491612ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
491712ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, flags))
49183299c2f1SGregory Neil Shapiro 			continue;
49193299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
49203299c2f1SGregory Neil Shapiro 		(void) add_hostnames(sa);
49213299c2f1SGregory Neil Shapiro 	}
492212ed1c7cSGregory Neil Shapiro 	sm_free(buf); /* XXX */
4923c46d91b7SGregory Neil Shapiro 	(void) close(s);
49243299c2f1SGregory Neil Shapiro # else /* NETINET6 && defined(SIOCGLIFCONF) */
4925c2aa98e2SPeter Wemm #  if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4926c2aa98e2SPeter Wemm 	int s;
4927c2aa98e2SPeter Wemm 	int i;
4928c2aa98e2SPeter Wemm 	struct ifconf ifc;
4929c2aa98e2SPeter Wemm 	int numifs;
4930c2aa98e2SPeter Wemm 
4931c2aa98e2SPeter Wemm 	s = socket(AF_INET, SOCK_DGRAM, 0);
4932c2aa98e2SPeter Wemm 	if (s == -1)
4933c2aa98e2SPeter Wemm 		return;
4934c2aa98e2SPeter Wemm 
4935c2aa98e2SPeter Wemm 	/* get the list of known IP address from the kernel */
4936c2aa98e2SPeter Wemm #   if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN
4937c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
4938c2aa98e2SPeter Wemm 	{
4939c2aa98e2SPeter Wemm 		/* can't get number of interfaces -- fall back */
4940c2aa98e2SPeter Wemm 		if (tTd(0, 4))
494112ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFNUM failed: %s\n",
494212ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
4943c2aa98e2SPeter Wemm 		numifs = -1;
4944c2aa98e2SPeter Wemm 	}
4945c2aa98e2SPeter Wemm 	else if (tTd(0, 42))
494612ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
4947c2aa98e2SPeter Wemm 	if (numifs < 0)
49483299c2f1SGregory Neil Shapiro #   endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */
49493299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
4950c2aa98e2SPeter Wemm 
4951c2aa98e2SPeter Wemm 	if (numifs <= 0)
4952c2aa98e2SPeter Wemm 	{
49533299c2f1SGregory Neil Shapiro 		(void) close(s);
4954c2aa98e2SPeter Wemm 		return;
4955c2aa98e2SPeter Wemm 	}
4956c2aa98e2SPeter Wemm 	ifc.ifc_len = numifs * sizeof (struct ifreq);
4957c2aa98e2SPeter Wemm 	ifc.ifc_buf = xalloc(ifc.ifc_len);
4958c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
4959c2aa98e2SPeter Wemm 	{
4960c2aa98e2SPeter Wemm 		if (tTd(0, 4))
496112ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFCONF failed: %s\n",
496212ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
49633299c2f1SGregory Neil Shapiro 		(void) close(s);
4964c2aa98e2SPeter Wemm 		return;
4965c2aa98e2SPeter Wemm 	}
4966c2aa98e2SPeter Wemm 
4967c2aa98e2SPeter Wemm 	/* scan the list of IP address */
4968c2aa98e2SPeter Wemm 	if (tTd(0, 40))
496912ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, ifc_len=%d\n",
4970c2aa98e2SPeter Wemm 			ifc.ifc_len);
4971c2aa98e2SPeter Wemm 
497212ed1c7cSGregory Neil Shapiro 	for (i = 0; i < ifc.ifc_len && i >= 0; )
4973c2aa98e2SPeter Wemm 	{
49743299c2f1SGregory Neil Shapiro 		int af;
4975c2aa98e2SPeter Wemm 		struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
497676b7bf71SPeter Wemm 		SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr;
49773299c2f1SGregory Neil Shapiro #   if NETINET6
49783299c2f1SGregory Neil Shapiro 		char *addr;
49793299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
49803299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
4981c2aa98e2SPeter Wemm 		struct in_addr ia;
4982c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
4983c2aa98e2SPeter Wemm 		struct ifreq ifrf;
49843299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
4985c2aa98e2SPeter Wemm 		char ip_addr[256];
49863299c2f1SGregory Neil Shapiro #   if NETINET6
49873299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
49883299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
49893299c2f1SGregory Neil Shapiro 
49903299c2f1SGregory Neil Shapiro 		/*
49913299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
49923299c2f1SGregory Neil Shapiro 		**  don't try to use it.
49933299c2f1SGregory Neil Shapiro 		*/
49943299c2f1SGregory Neil Shapiro 
49953299c2f1SGregory Neil Shapiro 		if ((ifc.ifc_len - i) < sizeof *ifr)
49963299c2f1SGregory Neil Shapiro 			break;
4997c2aa98e2SPeter Wemm 
4998c2aa98e2SPeter Wemm #   ifdef BSD4_4_SOCKADDR
499976b7bf71SPeter Wemm 		if (sa->sa.sa_len > sizeof ifr->ifr_addr)
500076b7bf71SPeter Wemm 			i += sizeof ifr->ifr_name + sa->sa.sa_len;
5001c2aa98e2SPeter Wemm 		else
50023299c2f1SGregory Neil Shapiro #   endif /* BSD4_4_SOCKADDR */
5003c2aa98e2SPeter Wemm 			i += sizeof *ifr;
5004c2aa98e2SPeter Wemm 
5005c2aa98e2SPeter Wemm 		if (tTd(0, 20))
500612ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
5007c2aa98e2SPeter Wemm 
50083299c2f1SGregory Neil Shapiro 		af = ifr->ifr_addr.sa_family;
50093299c2f1SGregory Neil Shapiro 		if (af != AF_INET
50103299c2f1SGregory Neil Shapiro #   if NETINET6
50113299c2f1SGregory Neil Shapiro 		    && af != AF_INET6
50123299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
50133299c2f1SGregory Neil Shapiro 		    )
5014c2aa98e2SPeter Wemm 			continue;
5015c2aa98e2SPeter Wemm 
5016c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
50173299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct ifreq));
501812ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name,
50193299c2f1SGregory Neil Shapiro 			       sizeof(ifrf.ifr_name));
50203299c2f1SGregory Neil Shapiro 		(void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
5021c2aa98e2SPeter Wemm 		if (tTd(0, 41))
502212ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n",
50233299c2f1SGregory Neil Shapiro 				(unsigned long) ifrf.ifr_flags);
5024c2aa98e2SPeter Wemm #    define IFRFREF ifrf
50253299c2f1SGregory Neil Shapiro #   else /* SIOCGIFFLAGS */
5026c2aa98e2SPeter Wemm #    define IFRFREF (*ifr)
50273299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
50283299c2f1SGregory Neil Shapiro 
5029c2aa98e2SPeter Wemm 		if (!bitset(IFF_UP, IFRFREF.ifr_flags))
5030c2aa98e2SPeter Wemm 			continue;
5031c2aa98e2SPeter Wemm 
50323299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
50333299c2f1SGregory Neil Shapiro 
5034c2aa98e2SPeter Wemm 		/* extract IP address from the list*/
50353299c2f1SGregory Neil Shapiro 		switch (af)
50363299c2f1SGregory Neil Shapiro 		{
50373299c2f1SGregory Neil Shapiro 		  case AF_INET:
503876b7bf71SPeter Wemm 			ia = sa->sin.sin_addr;
50393299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
50403299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
5041c2aa98e2SPeter Wemm 			{
5042c2aa98e2SPeter Wemm 				message("WARNING: interface %s is UP with %s address",
5043c2aa98e2SPeter Wemm 					ifr->ifr_name, inet_ntoa(ia));
5044c2aa98e2SPeter Wemm 				continue;
5045c2aa98e2SPeter Wemm 			}
5046c2aa98e2SPeter Wemm 
5047c2aa98e2SPeter Wemm 			/* save IP address in text from */
504812ed1c7cSGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
50491ec86adfSBruce Evans 					(int) sizeof ip_addr - 3,
5050c2aa98e2SPeter Wemm 					inet_ntoa(ia));
50513299c2f1SGregory Neil Shapiro 			break;
50523299c2f1SGregory Neil Shapiro 
50533299c2f1SGregory Neil Shapiro #   if NETINET6
50543299c2f1SGregory Neil Shapiro 		  case AF_INET6:
5055b4662009SGregory Neil Shapiro #    ifdef __KAME__
5056b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
5057b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
5058b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
5059b4662009SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
5060b4662009SGregory Neil Shapiro 			{
5061b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
5062b4662009SGregory Neil Shapiro 
5063b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
5064b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
5065b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
5066b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
5067b4662009SGregory Neil Shapiro 			}
5068b4662009SGregory Neil Shapiro #    endif /* __KAME__ */
50693299c2f1SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
5070c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
50713299c2f1SGregory Neil Shapiro 			{
50723299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
50733299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
50743299c2f1SGregory Neil Shapiro 					ifr->ifr_name,
50753299c2f1SGregory Neil Shapiro 					addr == NULL ? "(NULL)" : addr);
50763299c2f1SGregory Neil Shapiro 				continue;
50773299c2f1SGregory Neil Shapiro 			}
50783299c2f1SGregory Neil Shapiro 
50793299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
50803299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
50813299c2f1SGregory Neil Shapiro 			if (addr != NULL)
508212ed1c7cSGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
50833299c2f1SGregory Neil Shapiro 						   "[%.*s]",
508412ed1c7cSGregory Neil Shapiro 						   (int) sizeof ip_addr - 3,
508512ed1c7cSGregory Neil Shapiro 						   addr);
50863299c2f1SGregory Neil Shapiro 			break;
50873299c2f1SGregory Neil Shapiro 
50883299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
50893299c2f1SGregory Neil Shapiro 		}
50903299c2f1SGregory Neil Shapiro 
50913299c2f1SGregory Neil Shapiro 		if (ip_addr[0] == '\0')
50923299c2f1SGregory Neil Shapiro 			continue;
50933299c2f1SGregory Neil Shapiro 
5094c2aa98e2SPeter Wemm 		if (!wordinclass(ip_addr, 'w'))
5095c2aa98e2SPeter Wemm 		{
5096c2aa98e2SPeter Wemm 			setclass('w', ip_addr);
5097c2aa98e2SPeter Wemm 			if (tTd(0, 4))
509812ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
5099c2aa98e2SPeter Wemm 		}
5100c2aa98e2SPeter Wemm 
5101c2aa98e2SPeter Wemm 		/* skip "loopback" interface "lo" */
510212ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
510312ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
5104c2aa98e2SPeter Wemm 			continue;
5105c2aa98e2SPeter Wemm 
510676b7bf71SPeter Wemm 		(void) add_hostnames(sa);
5107c2aa98e2SPeter Wemm 	}
510812ed1c7cSGregory Neil Shapiro 	sm_free(ifc.ifc_buf); /* XXX */
51093299c2f1SGregory Neil Shapiro 	(void) close(s);
5110c2aa98e2SPeter Wemm #   undef IFRFREF
51113299c2f1SGregory Neil Shapiro #  endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
51123299c2f1SGregory Neil Shapiro # endif /* NETINET6 && defined(SIOCGLIFCONF) */
51133299c2f1SGregory Neil Shapiro }
511412ed1c7cSGregory Neil Shapiro /*
51153299c2f1SGregory Neil Shapiro **  ISLOOPBACK -- is socket address in the loopback net?
51163299c2f1SGregory Neil Shapiro **
51173299c2f1SGregory Neil Shapiro **	Parameters:
51183299c2f1SGregory Neil Shapiro **		sa -- socket address.
51193299c2f1SGregory Neil Shapiro **
51203299c2f1SGregory Neil Shapiro **	Returns:
512112ed1c7cSGregory Neil Shapiro **		true -- is socket address in the loopback net?
512212ed1c7cSGregory Neil Shapiro **		false -- otherwise
51233299c2f1SGregory Neil Shapiro **
51243299c2f1SGregory Neil Shapiro */
51253299c2f1SGregory Neil Shapiro 
51263299c2f1SGregory Neil Shapiro bool
51273299c2f1SGregory Neil Shapiro isloopback(sa)
51283299c2f1SGregory Neil Shapiro 	SOCKADDR sa;
51293299c2f1SGregory Neil Shapiro {
51303299c2f1SGregory Neil Shapiro #if NETINET6
51313299c2f1SGregory Neil Shapiro 	if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
513212ed1c7cSGregory Neil Shapiro 		return true;
51333299c2f1SGregory Neil Shapiro #else /* NETINET6 */
51343299c2f1SGregory Neil Shapiro 	/* XXX how to correctly extract IN_LOOPBACKNET part? */
51353299c2f1SGregory Neil Shapiro 	if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET)
51363299c2f1SGregory Neil Shapiro 	     >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
513712ed1c7cSGregory Neil Shapiro 		return true;
51383299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
513912ed1c7cSGregory Neil Shapiro 	return false;
5140c2aa98e2SPeter Wemm }
514112ed1c7cSGregory Neil Shapiro /*
5142c2aa98e2SPeter Wemm **  GET_NUM_PROCS_ONLINE -- return the number of processors currently online
5143c2aa98e2SPeter Wemm **
5144c2aa98e2SPeter Wemm **	Parameters:
5145c2aa98e2SPeter Wemm **		none.
5146c2aa98e2SPeter Wemm **
5147c2aa98e2SPeter Wemm **	Returns:
5148c2aa98e2SPeter Wemm **		The number of processors online.
5149c2aa98e2SPeter Wemm */
5150c2aa98e2SPeter Wemm 
51513299c2f1SGregory Neil Shapiro static int
5152c2aa98e2SPeter Wemm get_num_procs_online()
5153c2aa98e2SPeter Wemm {
5154c2aa98e2SPeter Wemm 	int nproc = 0;
5155c2aa98e2SPeter Wemm 
51563299c2f1SGregory Neil Shapiro #ifdef USESYSCTL
51573299c2f1SGregory Neil Shapiro # if defined(CTL_HW) && defined(HW_NCPU)
51583299c2f1SGregory Neil Shapiro 	size_t sz;
51593299c2f1SGregory Neil Shapiro 	int mib[2];
51603299c2f1SGregory Neil Shapiro 
51613299c2f1SGregory Neil Shapiro 	mib[0] = CTL_HW;
51623299c2f1SGregory Neil Shapiro 	mib[1] = HW_NCPU;
51633299c2f1SGregory Neil Shapiro 	sz = (size_t) sizeof nproc;
51643299c2f1SGregory Neil Shapiro 	(void) sysctl(mib, 2, &nproc, &sz, NULL, 0);
516512ed1c7cSGregory Neil Shapiro # endif /* defined(CTL_HW) && defined(HW_NCPU) */
51663299c2f1SGregory Neil Shapiro #else /* USESYSCTL */
5167c2aa98e2SPeter Wemm # ifdef _SC_NPROCESSORS_ONLN
5168c2aa98e2SPeter Wemm 	nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
51693299c2f1SGregory Neil Shapiro # else /* _SC_NPROCESSORS_ONLN */
51703299c2f1SGregory Neil Shapiro #  ifdef __hpux
51713299c2f1SGregory Neil Shapiro #   include <sys/pstat.h>
51723299c2f1SGregory Neil Shapiro 	struct pst_dynamic psd;
51733299c2f1SGregory Neil Shapiro 
51743299c2f1SGregory Neil Shapiro 	if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1)
51753299c2f1SGregory Neil Shapiro 		nproc = psd.psd_proc_cnt;
51763299c2f1SGregory Neil Shapiro #  endif /* __hpux */
51773299c2f1SGregory Neil Shapiro # endif /* _SC_NPROCESSORS_ONLN */
51783299c2f1SGregory Neil Shapiro #endif /* USESYSCTL */
51793299c2f1SGregory Neil Shapiro 
5180c2aa98e2SPeter Wemm 	if (nproc <= 0)
5181c2aa98e2SPeter Wemm 		nproc = 1;
5182c2aa98e2SPeter Wemm 	return nproc;
5183c2aa98e2SPeter Wemm }
518412ed1c7cSGregory Neil Shapiro /*
5185bfb62e91SGregory Neil Shapiro **  SM_CLOSEFROM -- close file descriptors
5186bfb62e91SGregory Neil Shapiro **
5187bfb62e91SGregory Neil Shapiro **	Parameters:
5188bfb62e91SGregory Neil Shapiro **		lowest -- first fd to close
5189bfb62e91SGregory Neil Shapiro **		highest -- last fd + 1 to close
5190bfb62e91SGregory Neil Shapiro **
5191bfb62e91SGregory Neil Shapiro **	Returns:
5192bfb62e91SGregory Neil Shapiro **		none
5193bfb62e91SGregory Neil Shapiro */
5194bfb62e91SGregory Neil Shapiro 
5195bfb62e91SGregory Neil Shapiro void
5196bfb62e91SGregory Neil Shapiro sm_closefrom(lowest, highest)
5197bfb62e91SGregory Neil Shapiro 	int lowest, highest;
5198bfb62e91SGregory Neil Shapiro {
5199bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM
5200bfb62e91SGregory Neil Shapiro 	closefrom(lowest);
5201bfb62e91SGregory Neil Shapiro #else /* HASCLOSEFROM */
5202bfb62e91SGregory Neil Shapiro 	int i;
5203bfb62e91SGregory Neil Shapiro 
5204bfb62e91SGregory Neil Shapiro 	for (i = lowest; i < highest; i++)
5205bfb62e91SGregory Neil Shapiro 		(void) close(i);
5206bfb62e91SGregory Neil Shapiro #endif /* HASCLOSEFROM */
5207bfb62e91SGregory Neil Shapiro }
5208bfb62e91SGregory Neil Shapiro #if HASFDWALK
5209bfb62e91SGregory Neil Shapiro /*
5210bfb62e91SGregory Neil Shapiro **  CLOSEFD_WALK -- walk fd's arranging to close them
5211bfb62e91SGregory Neil Shapiro **	Callback for fdwalk()
5212bfb62e91SGregory Neil Shapiro **
5213bfb62e91SGregory Neil Shapiro **	Parameters:
5214bfb62e91SGregory Neil Shapiro **		lowest -- first fd to arrange to be closed
5215bfb62e91SGregory Neil Shapiro **		fd -- fd to arrange to be closed
5216bfb62e91SGregory Neil Shapiro **
5217bfb62e91SGregory Neil Shapiro **	Returns:
5218bfb62e91SGregory Neil Shapiro **		zero
5219bfb62e91SGregory Neil Shapiro */
5220bfb62e91SGregory Neil Shapiro 
5221bfb62e91SGregory Neil Shapiro static int
5222bfb62e91SGregory Neil Shapiro closefd_walk(lowest, fd)
5223bfb62e91SGregory Neil Shapiro 	void *lowest;
5224bfb62e91SGregory Neil Shapiro 	int fd;
5225bfb62e91SGregory Neil Shapiro {
5226bfb62e91SGregory Neil Shapiro 	if (fd >= *(int *)lowest)
5227bfb62e91SGregory Neil Shapiro 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
5228bfb62e91SGregory Neil Shapiro 	return 0;
5229bfb62e91SGregory Neil Shapiro }
5230bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */
5231bfb62e91SGregory Neil Shapiro /*
5232bfb62e91SGregory Neil Shapiro **  SM_CLOSE_ON_EXEC -- arrange for file descriptors to be closed
5233bfb62e91SGregory Neil Shapiro **
5234bfb62e91SGregory Neil Shapiro **	Parameters:
5235bfb62e91SGregory Neil Shapiro **		lowest -- first fd to arrange to be closed
5236bfb62e91SGregory Neil Shapiro **		highest -- last fd + 1 to arrange to be closed
5237bfb62e91SGregory Neil Shapiro **
5238bfb62e91SGregory Neil Shapiro **	Returns:
5239bfb62e91SGregory Neil Shapiro **		none
5240bfb62e91SGregory Neil Shapiro */
5241bfb62e91SGregory Neil Shapiro 
5242bfb62e91SGregory Neil Shapiro void
5243bfb62e91SGregory Neil Shapiro sm_close_on_exec(highest, lowest)
5244bfb62e91SGregory Neil Shapiro 	int highest, lowest;
5245bfb62e91SGregory Neil Shapiro {
5246bfb62e91SGregory Neil Shapiro #if HASFDWALK
5247bfb62e91SGregory Neil Shapiro 	(void) fdwalk(closefd_walk, &lowest);
5248bfb62e91SGregory Neil Shapiro #else /* HASFDWALK */
5249bfb62e91SGregory Neil Shapiro 	int i, j;
5250bfb62e91SGregory Neil Shapiro 
5251bfb62e91SGregory Neil Shapiro 	for (i = lowest; i < highest; i++)
5252bfb62e91SGregory Neil Shapiro 	{
5253bfb62e91SGregory Neil Shapiro 		if ((j = fcntl(i, F_GETFD, 0)) != -1)
5254bfb62e91SGregory Neil Shapiro 			(void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
5255bfb62e91SGregory Neil Shapiro 	}
5256bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */
5257bfb62e91SGregory Neil Shapiro }
5258bfb62e91SGregory Neil Shapiro /*
52593299c2f1SGregory Neil Shapiro **  SEED_RANDOM -- seed the random number generator
52603299c2f1SGregory Neil Shapiro **
52613299c2f1SGregory Neil Shapiro **	Parameters:
52623299c2f1SGregory Neil Shapiro **		none
52633299c2f1SGregory Neil Shapiro **
52643299c2f1SGregory Neil Shapiro **	Returns:
52653299c2f1SGregory Neil Shapiro **		none
52663299c2f1SGregory Neil Shapiro */
52673299c2f1SGregory Neil Shapiro 
52683299c2f1SGregory Neil Shapiro void
52693299c2f1SGregory Neil Shapiro seed_random()
52703299c2f1SGregory Neil Shapiro {
52713299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
52723299c2f1SGregory Neil Shapiro 	srandomdev();
52733299c2f1SGregory Neil Shapiro #else /* HASSRANDOMDEV */
52743299c2f1SGregory Neil Shapiro 	long seed;
52753299c2f1SGregory Neil Shapiro 	struct timeval t;
52763299c2f1SGregory Neil Shapiro 
527712ed1c7cSGregory Neil Shapiro 	seed = (long) CurrentPid;
52783299c2f1SGregory Neil Shapiro 	if (gettimeofday(&t, NULL) >= 0)
52793299c2f1SGregory Neil Shapiro 		seed += t.tv_sec + t.tv_usec;
52803299c2f1SGregory Neil Shapiro 
52813299c2f1SGregory Neil Shapiro # if HASRANDOM
52823299c2f1SGregory Neil Shapiro 	(void) srandom(seed);
52833299c2f1SGregory Neil Shapiro # else /* HASRANDOM */
52843299c2f1SGregory Neil Shapiro 	(void) srand((unsigned int) seed);
52853299c2f1SGregory Neil Shapiro # endif /* HASRANDOM */
52863299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
52873299c2f1SGregory Neil Shapiro }
528812ed1c7cSGregory Neil Shapiro /*
5289c2aa98e2SPeter Wemm **  SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
5290c2aa98e2SPeter Wemm **
5291c2aa98e2SPeter Wemm **	Parameters:
5292c2aa98e2SPeter Wemm **		level -- syslog level
5293c2aa98e2SPeter Wemm **		id -- envelope ID or NULL (NOQUEUE)
5294c2aa98e2SPeter Wemm **		fmt -- format string
5295c2aa98e2SPeter Wemm **		arg... -- arguments as implied by fmt.
5296c2aa98e2SPeter Wemm **
5297c2aa98e2SPeter Wemm **	Returns:
5298c2aa98e2SPeter Wemm **		none
5299c2aa98e2SPeter Wemm */
5300c2aa98e2SPeter Wemm 
5301c2aa98e2SPeter Wemm /* VARARGS3 */
5302c2aa98e2SPeter Wemm void
5303c2aa98e2SPeter Wemm #ifdef __STDC__
5304c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...)
53053299c2f1SGregory Neil Shapiro #else /* __STDC__ */
5306c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist)
5307c2aa98e2SPeter Wemm 	int level;
5308c2aa98e2SPeter Wemm 	const char *id;
5309c2aa98e2SPeter Wemm 	const char *fmt;
5310c2aa98e2SPeter Wemm 	va_dcl
53113299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
5312c2aa98e2SPeter Wemm {
5313c2aa98e2SPeter Wemm 	static char *buf = NULL;
53143299c2f1SGregory Neil Shapiro 	static size_t bufsize;
5315c2aa98e2SPeter Wemm 	char *begin, *end;
53163299c2f1SGregory Neil Shapiro 	int save_errno;
5317c2aa98e2SPeter Wemm 	int seq = 1;
5318c2aa98e2SPeter Wemm 	int idlen;
53193299c2f1SGregory Neil Shapiro 	char buf0[MAXLINE];
532012ed1c7cSGregory Neil Shapiro 	char *newstring;
532112ed1c7cSGregory Neil Shapiro 	extern int SyslogPrefixLen;
532212ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5323c2aa98e2SPeter Wemm 
532412ed1c7cSGregory Neil Shapiro 	save_errno = errno;
5325c2aa98e2SPeter Wemm 	if (id == NULL)
532612ed1c7cSGregory Neil Shapiro 	{
5327c2aa98e2SPeter Wemm 		id = "NOQUEUE";
532812ed1c7cSGregory Neil Shapiro 		idlen = strlen(id) + SyslogPrefixLen;
532912ed1c7cSGregory Neil Shapiro 	}
5330c2aa98e2SPeter Wemm 	else if (strcmp(id, NOQID) == 0)
533112ed1c7cSGregory Neil Shapiro 	{
5332c2aa98e2SPeter Wemm 		id = "";
533312ed1c7cSGregory Neil Shapiro 		idlen = SyslogPrefixLen;
533412ed1c7cSGregory Neil Shapiro 	}
533512ed1c7cSGregory Neil Shapiro 	else
533612ed1c7cSGregory Neil Shapiro 		idlen = strlen(id) + SyslogPrefixLen;
5337c2aa98e2SPeter Wemm 
53383299c2f1SGregory Neil Shapiro 	if (buf == NULL)
53393299c2f1SGregory Neil Shapiro 	{
53403299c2f1SGregory Neil Shapiro 		buf = buf0;
53413299c2f1SGregory Neil Shapiro 		bufsize = sizeof buf0;
53423299c2f1SGregory Neil Shapiro 	}
53433299c2f1SGregory Neil Shapiro 
53443299c2f1SGregory Neil Shapiro 	for (;;)
53453299c2f1SGregory Neil Shapiro 	{
534612ed1c7cSGregory Neil Shapiro 		int n;
5347c2aa98e2SPeter Wemm 
534812ed1c7cSGregory Neil Shapiro 		/* print log message into buf */
534912ed1c7cSGregory Neil Shapiro 		SM_VA_START(ap, fmt);
535012ed1c7cSGregory Neil Shapiro 		n = sm_vsnprintf(buf, bufsize, fmt, ap);
535112ed1c7cSGregory Neil Shapiro 		SM_VA_END(ap);
535212ed1c7cSGregory Neil Shapiro 		SM_ASSERT(n > 0);
535312ed1c7cSGregory Neil Shapiro 		if (n < bufsize)
53543299c2f1SGregory Neil Shapiro 			break;
53553299c2f1SGregory Neil Shapiro 
5356c2aa98e2SPeter Wemm 		/* String too small, redo with correct size */
535712ed1c7cSGregory Neil Shapiro 		bufsize = n + 1;
53583299c2f1SGregory Neil Shapiro 		if (buf != buf0)
535912ed1c7cSGregory Neil Shapiro 		{
5360c0c4794dSGregory Neil Shapiro 			sm_free(buf);
536112ed1c7cSGregory Neil Shapiro 			buf = NULL;
5362c2aa98e2SPeter Wemm 		}
536312ed1c7cSGregory Neil Shapiro 		buf = sm_malloc_x(bufsize);
536412ed1c7cSGregory Neil Shapiro 	}
536512ed1c7cSGregory Neil Shapiro 
536612ed1c7cSGregory Neil Shapiro 	/* clean up buf after it has been expanded with args */
536712ed1c7cSGregory Neil Shapiro 	newstring = str2prt(buf);
536812ed1c7cSGregory Neil Shapiro 	if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE)
5369c2aa98e2SPeter Wemm 	{
5370c2aa98e2SPeter Wemm #if LOG
5371c2aa98e2SPeter Wemm 		if (*id == '\0')
537212ed1c7cSGregory Neil Shapiro 			syslog(level, "%s", newstring);
5373c2aa98e2SPeter Wemm 		else
537412ed1c7cSGregory Neil Shapiro 			syslog(level, "%s: %s", id, newstring);
53753299c2f1SGregory Neil Shapiro #else /* LOG */
5376c2aa98e2SPeter Wemm 		/*XXX should do something more sensible */
5377c2aa98e2SPeter Wemm 		if (*id == '\0')
537812ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n",
537912ed1c7cSGregory Neil Shapiro 					     newstring);
5380c2aa98e2SPeter Wemm 		else
538112ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
538212ed1c7cSGregory Neil Shapiro 					     "%s: %s\n", id, newstring);
53833299c2f1SGregory Neil Shapiro #endif /* LOG */
53843299c2f1SGregory Neil Shapiro 		if (buf == buf0)
53853299c2f1SGregory Neil Shapiro 			buf = NULL;
53863299c2f1SGregory Neil Shapiro 		errno = save_errno;
5387c2aa98e2SPeter Wemm 		return;
5388c2aa98e2SPeter Wemm 	}
5389c2aa98e2SPeter Wemm 
539012ed1c7cSGregory Neil Shapiro /*
539112ed1c7cSGregory Neil Shapiro **  additional length for splitting: " ..." + 3, where 3 is magic to
539212ed1c7cSGregory Neil Shapiro **  have some data for the next entry.
539312ed1c7cSGregory Neil Shapiro */
539412ed1c7cSGregory Neil Shapiro 
539512ed1c7cSGregory Neil Shapiro #define SL_SPLIT 7
539612ed1c7cSGregory Neil Shapiro 
539712ed1c7cSGregory Neil Shapiro 	begin = newstring;
539812ed1c7cSGregory Neil Shapiro 	idlen += 5;	/* strlen("[999]"), see below */
5399c2aa98e2SPeter Wemm 	while (*begin != '\0' &&
540012ed1c7cSGregory Neil Shapiro 	       (strlen(begin) + idlen) > SYSLOG_BUFSIZE)
5401c2aa98e2SPeter Wemm 	{
5402c2aa98e2SPeter Wemm 		char save;
5403c2aa98e2SPeter Wemm 
540412ed1c7cSGregory Neil Shapiro 		if (seq >= 999)
5405c2aa98e2SPeter Wemm 		{
5406c2aa98e2SPeter Wemm 			/* Too many messages */
5407c2aa98e2SPeter Wemm 			break;
5408c2aa98e2SPeter Wemm 		}
540912ed1c7cSGregory Neil Shapiro 		end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5410c2aa98e2SPeter Wemm 		while (end > begin)
5411c2aa98e2SPeter Wemm 		{
5412c2aa98e2SPeter Wemm 			/* Break on comma or space */
5413c2aa98e2SPeter Wemm 			if (*end == ',' || *end == ' ')
5414c2aa98e2SPeter Wemm 			{
5415c2aa98e2SPeter Wemm 				end++;	  /* Include separator */
5416c2aa98e2SPeter Wemm 				break;
5417c2aa98e2SPeter Wemm 			}
5418c2aa98e2SPeter Wemm 			end--;
5419c2aa98e2SPeter Wemm 		}
5420c2aa98e2SPeter Wemm 		/* No separator, break midstring... */
5421c2aa98e2SPeter Wemm 		if (end == begin)
542212ed1c7cSGregory Neil Shapiro 			end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5423c2aa98e2SPeter Wemm 		save = *end;
5424c2aa98e2SPeter Wemm 		*end = 0;
5425c2aa98e2SPeter Wemm #if LOG
5426c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s ...", id, seq++, begin);
54273299c2f1SGregory Neil Shapiro #else /* LOG */
542812ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
542912ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s ...\n", id, seq++, begin);
54303299c2f1SGregory Neil Shapiro #endif /* LOG */
5431c2aa98e2SPeter Wemm 		*end = save;
5432c2aa98e2SPeter Wemm 		begin = end;
5433c2aa98e2SPeter Wemm 	}
543412ed1c7cSGregory Neil Shapiro 	if (seq >= 999)
5435c2aa98e2SPeter Wemm #if LOG
54363299c2f1SGregory Neil Shapiro 		syslog(level, "%s[%d]: log terminated, too many parts",
54373299c2f1SGregory Neil Shapiro 			id, seq);
54383299c2f1SGregory Neil Shapiro #else /* LOG */
543912ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
544012ed1c7cSGregory Neil Shapiro 			      "%s[%d]: log terminated, too many parts\n", id, seq);
54413299c2f1SGregory Neil Shapiro #endif /* LOG */
5442c2aa98e2SPeter Wemm 	else if (*begin != '\0')
5443c2aa98e2SPeter Wemm #if LOG
5444c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s", id, seq, begin);
54453299c2f1SGregory Neil Shapiro #else /* LOG */
544612ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
544712ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s\n", id, seq, begin);
54483299c2f1SGregory Neil Shapiro #endif /* LOG */
54493299c2f1SGregory Neil Shapiro 	if (buf == buf0)
54503299c2f1SGregory Neil Shapiro 		buf = NULL;
54513299c2f1SGregory Neil Shapiro 	errno = save_errno;
5452c2aa98e2SPeter Wemm }
545312ed1c7cSGregory Neil Shapiro /*
5454c2aa98e2SPeter Wemm **  HARD_SYSLOG -- call syslog repeatedly until it works
5455c2aa98e2SPeter Wemm **
5456c2aa98e2SPeter Wemm **	Needed on HP-UX, which apparently doesn't guarantee that
5457c2aa98e2SPeter Wemm **	syslog succeeds during interrupt handlers.
5458c2aa98e2SPeter Wemm */
5459c2aa98e2SPeter Wemm 
5460c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11)
5461c2aa98e2SPeter Wemm 
5462c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES	100
5463c2aa98e2SPeter Wemm # undef syslog
5464c2aa98e2SPeter Wemm # ifdef V4FS
5465c2aa98e2SPeter Wemm #  define XCNST	const
5466c2aa98e2SPeter Wemm #  define CAST	(const char *)
54673299c2f1SGregory Neil Shapiro # else /* V4FS */
5468c2aa98e2SPeter Wemm #  define XCNST
5469c2aa98e2SPeter Wemm #  define CAST
54703299c2f1SGregory Neil Shapiro # endif /* V4FS */
5471c2aa98e2SPeter Wemm 
5472c2aa98e2SPeter Wemm void
5473c2aa98e2SPeter Wemm # ifdef __STDC__
5474c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...)
54753299c2f1SGregory Neil Shapiro # else /* __STDC__ */
5476c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist)
5477c2aa98e2SPeter Wemm 	int pri;
5478c2aa98e2SPeter Wemm 	XCNST char *msg;
5479c2aa98e2SPeter Wemm 	va_dcl
54803299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
5481c2aa98e2SPeter Wemm {
5482c2aa98e2SPeter Wemm 	int i;
5483c2aa98e2SPeter Wemm 	char buf[SYSLOG_BUFSIZE];
548412ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5485c2aa98e2SPeter Wemm 
548612ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, msg);
548712ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof buf, msg, ap);
548812ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
5489c2aa98e2SPeter Wemm 
5490c2aa98e2SPeter Wemm 	for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; )
5491c2aa98e2SPeter Wemm 		continue;
5492c2aa98e2SPeter Wemm }
5493c2aa98e2SPeter Wemm 
5494c2aa98e2SPeter Wemm # undef CAST
54953299c2f1SGregory Neil Shapiro #endif /* defined(__hpux) && !defined(HPUX11) */
54963299c2f1SGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
549712ed1c7cSGregory Neil Shapiro /*
5498c2aa98e2SPeter Wemm **  LOCAL_HOSTNAME_LENGTH
5499c2aa98e2SPeter Wemm **
5500c2aa98e2SPeter Wemm **	This is required to get sendmail to compile against BIND 4.9.x
5501c2aa98e2SPeter Wemm **	on Ultrix.
55023299c2f1SGregory Neil Shapiro **
55033299c2f1SGregory Neil Shapiro **	Unfortunately, a Compaq Y2K patch kit provides it without
55043299c2f1SGregory Neil Shapiro **	bumping __RES in /usr/include/resolv.h so we can't automatically
55053299c2f1SGregory Neil Shapiro **	figure out whether it is needed.
5506c2aa98e2SPeter Wemm */
5507c2aa98e2SPeter Wemm 
5508c2aa98e2SPeter Wemm int
5509c2aa98e2SPeter Wemm local_hostname_length(hostname)
5510c2aa98e2SPeter Wemm 	char *hostname;
5511c2aa98e2SPeter Wemm {
551212ed1c7cSGregory Neil Shapiro 	size_t len_host, len_domain;
5513c2aa98e2SPeter Wemm 
5514c2aa98e2SPeter Wemm 	if (!*_res.defdname)
5515c2aa98e2SPeter Wemm 		res_init();
5516c2aa98e2SPeter Wemm 	len_host = strlen(hostname);
5517c2aa98e2SPeter Wemm 	len_domain = strlen(_res.defdname);
5518c2aa98e2SPeter Wemm 	if (len_host > len_domain &&
551912ed1c7cSGregory Neil Shapiro 	    (sm_strcasecmp(hostname + len_host - len_domain,
55203299c2f1SGregory Neil Shapiro 			_res.defdname) == 0) &&
5521c2aa98e2SPeter Wemm 	    hostname[len_host - len_domain - 1] == '.')
5522c2aa98e2SPeter Wemm 		return len_host - len_domain - 1;
5523c2aa98e2SPeter Wemm 	else
5524c2aa98e2SPeter Wemm 		return 0;
5525c2aa98e2SPeter Wemm }
55263299c2f1SGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
5527c2aa98e2SPeter Wemm 
552812ed1c7cSGregory Neil Shapiro #if NEEDLINK
552912ed1c7cSGregory Neil Shapiro /*
553012ed1c7cSGregory Neil Shapiro **  LINK -- clone a file
553112ed1c7cSGregory Neil Shapiro **
553212ed1c7cSGregory Neil Shapiro **	Some OS's lacks link() and hard links.  Since sendmail is using
553312ed1c7cSGregory Neil Shapiro **	link() as an efficient way to clone files, this implementation
553412ed1c7cSGregory Neil Shapiro **	will simply do a file copy.
553512ed1c7cSGregory Neil Shapiro **
553612ed1c7cSGregory Neil Shapiro **	NOTE: This link() replacement is not a generic replacement as it
553712ed1c7cSGregory Neil Shapiro **	does not handle all of the semantics of the real link(2).
553812ed1c7cSGregory Neil Shapiro **
553912ed1c7cSGregory Neil Shapiro **	Parameters:
554012ed1c7cSGregory Neil Shapiro **		source -- pathname of existing file.
554112ed1c7cSGregory Neil Shapiro **		target -- pathname of link (clone) to be created.
554212ed1c7cSGregory Neil Shapiro **
554312ed1c7cSGregory Neil Shapiro **	Returns:
554412ed1c7cSGregory Neil Shapiro **		0 -- success.
554512ed1c7cSGregory Neil Shapiro **		-1 -- failure, see errno for details.
554612ed1c7cSGregory Neil Shapiro */
554712ed1c7cSGregory Neil Shapiro 
554812ed1c7cSGregory Neil Shapiro int
554912ed1c7cSGregory Neil Shapiro link(source, target)
555012ed1c7cSGregory Neil Shapiro 	const char *source;
555112ed1c7cSGregory Neil Shapiro 	const char *target;
555212ed1c7cSGregory Neil Shapiro {
555312ed1c7cSGregory Neil Shapiro 	int save_errno;
555412ed1c7cSGregory Neil Shapiro 	int sff;
555512ed1c7cSGregory Neil Shapiro 	int src = -1, dst = -1;
555612ed1c7cSGregory Neil Shapiro 	ssize_t readlen;
555712ed1c7cSGregory Neil Shapiro 	ssize_t writelen;
555812ed1c7cSGregory Neil Shapiro 	char buf[BUFSIZ];
555912ed1c7cSGregory Neil Shapiro 	struct stat st;
556012ed1c7cSGregory Neil Shapiro 
556112ed1c7cSGregory Neil Shapiro 	sff = SFF_REGONLY|SFF_OPENASROOT;
556212ed1c7cSGregory Neil Shapiro 	if (DontLockReadFiles)
556312ed1c7cSGregory Neil Shapiro 		sff |= SFF_NOLOCK;
556412ed1c7cSGregory Neil Shapiro 
556512ed1c7cSGregory Neil Shapiro 	/* Open the original file */
556612ed1c7cSGregory Neil Shapiro 	src = safeopen((char *)source, O_RDONLY, 0, sff);
556712ed1c7cSGregory Neil Shapiro 	if (src < 0)
556812ed1c7cSGregory Neil Shapiro 		goto fail;
556912ed1c7cSGregory Neil Shapiro 
557012ed1c7cSGregory Neil Shapiro 	/* Obtain the size and the mode */
557112ed1c7cSGregory Neil Shapiro 	if (fstat(src, &st) < 0)
557212ed1c7cSGregory Neil Shapiro 		goto fail;
557312ed1c7cSGregory Neil Shapiro 
557412ed1c7cSGregory Neil Shapiro 	/* Create the duplicate copy */
557512ed1c7cSGregory Neil Shapiro 	sff &= ~SFF_NOLOCK;
557612ed1c7cSGregory Neil Shapiro 	sff |= SFF_CREAT;
557712ed1c7cSGregory Neil Shapiro 	dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY,
557812ed1c7cSGregory Neil Shapiro 		       st.st_mode, sff);
557912ed1c7cSGregory Neil Shapiro 	if (dst < 0)
558012ed1c7cSGregory Neil Shapiro 		goto fail;
558112ed1c7cSGregory Neil Shapiro 
558212ed1c7cSGregory Neil Shapiro 	/* Copy all of the bytes one buffer at a time */
558312ed1c7cSGregory Neil Shapiro 	while ((readlen = read(src, &buf, sizeof(buf))) > 0)
558412ed1c7cSGregory Neil Shapiro 	{
558512ed1c7cSGregory Neil Shapiro 		ssize_t left = readlen;
558612ed1c7cSGregory Neil Shapiro 		char *p = buf;
558712ed1c7cSGregory Neil Shapiro 
558812ed1c7cSGregory Neil Shapiro 		while (left > 0 &&
558912ed1c7cSGregory Neil Shapiro 		       (writelen = write(dst, p, (size_t) left)) >= 0)
559012ed1c7cSGregory Neil Shapiro 		{
559112ed1c7cSGregory Neil Shapiro 			left -= writelen;
559212ed1c7cSGregory Neil Shapiro 			p += writelen;
559312ed1c7cSGregory Neil Shapiro 		}
5594320f00e7SGregory Neil Shapiro 		if (writelen < 0)
559512ed1c7cSGregory Neil Shapiro 			break;
559612ed1c7cSGregory Neil Shapiro 	}
559712ed1c7cSGregory Neil Shapiro 
559812ed1c7cSGregory Neil Shapiro 	/* Any trouble reading? */
559912ed1c7cSGregory Neil Shapiro 	if (readlen < 0 || writelen < 0)
560012ed1c7cSGregory Neil Shapiro 		goto fail;
560112ed1c7cSGregory Neil Shapiro 
560212ed1c7cSGregory Neil Shapiro 	/* Close the input file */
560312ed1c7cSGregory Neil Shapiro 	if (close(src) < 0)
560412ed1c7cSGregory Neil Shapiro 	{
560512ed1c7cSGregory Neil Shapiro 		src = -1;
560612ed1c7cSGregory Neil Shapiro 		goto fail;
560712ed1c7cSGregory Neil Shapiro 	}
560812ed1c7cSGregory Neil Shapiro 	src = -1;
560912ed1c7cSGregory Neil Shapiro 
561012ed1c7cSGregory Neil Shapiro 	/* Close the output file */
561112ed1c7cSGregory Neil Shapiro 	if (close(dst) < 0)
561212ed1c7cSGregory Neil Shapiro 	{
561312ed1c7cSGregory Neil Shapiro 		/* don't set dst = -1 here so we unlink the file */
561412ed1c7cSGregory Neil Shapiro 		goto fail;
561512ed1c7cSGregory Neil Shapiro 	}
561612ed1c7cSGregory Neil Shapiro 
561712ed1c7cSGregory Neil Shapiro 	/* Success */
561812ed1c7cSGregory Neil Shapiro 	return 0;
561912ed1c7cSGregory Neil Shapiro 
562012ed1c7cSGregory Neil Shapiro  fail:
562112ed1c7cSGregory Neil Shapiro 	save_errno = errno;
562212ed1c7cSGregory Neil Shapiro 	if (src >= 0)
562312ed1c7cSGregory Neil Shapiro 		(void) close(src);
562412ed1c7cSGregory Neil Shapiro 	if (dst >= 0)
562512ed1c7cSGregory Neil Shapiro 	{
562612ed1c7cSGregory Neil Shapiro 		(void) unlink(target);
562712ed1c7cSGregory Neil Shapiro 		(void) close(dst);
562812ed1c7cSGregory Neil Shapiro 	}
562912ed1c7cSGregory Neil Shapiro 	errno = save_errno;
563012ed1c7cSGregory Neil Shapiro 	return -1;
563112ed1c7cSGregory Neil Shapiro }
563212ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */
563312ed1c7cSGregory Neil Shapiro 
563412ed1c7cSGregory Neil Shapiro /*
5635c2aa98e2SPeter Wemm **  Compile-Time options
5636c2aa98e2SPeter Wemm */
5637c2aa98e2SPeter Wemm 
5638c2aa98e2SPeter Wemm char	*CompileOptions[] =
5639c2aa98e2SPeter Wemm {
5640bfb62e91SGregory Neil Shapiro #if ALLOW_255
5641bfb62e91SGregory Neil Shapiro 	"ALLOW_255",
5642bfb62e91SGregory Neil Shapiro #endif /* ALLOW_255 */
564312ed1c7cSGregory Neil Shapiro #if NAMED_BIND
564412ed1c7cSGregory Neil Shapiro # if DNSMAP
564512ed1c7cSGregory Neil Shapiro 	"DNSMAP",
564612ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */
564712ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */
5648c0c4794dSGregory Neil Shapiro #if EGD
5649c0c4794dSGregory Neil Shapiro 	"EGD",
5650c0c4794dSGregory Neil Shapiro #endif /* EGD */
565112ed1c7cSGregory Neil Shapiro #if HESIOD
5652c2aa98e2SPeter Wemm 	"HESIOD",
56533299c2f1SGregory Neil Shapiro #endif /* HESIOD */
5654c2aa98e2SPeter Wemm #if HES_GETMAILHOST
5655c2aa98e2SPeter Wemm 	"HES_GETMAILHOST",
56563299c2f1SGregory Neil Shapiro #endif /* HES_GETMAILHOST */
565712ed1c7cSGregory Neil Shapiro #if LDAPMAP
5658c2aa98e2SPeter Wemm 	"LDAPMAP",
56593299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
5660c2aa98e2SPeter Wemm #if LOG
5661c2aa98e2SPeter Wemm 	"LOG",
56623299c2f1SGregory Neil Shapiro #endif /* LOG */
566312ed1c7cSGregory Neil Shapiro #if MAP_NSD
566412ed1c7cSGregory Neil Shapiro 	"MAP_NSD",
566512ed1c7cSGregory Neil Shapiro #endif /* MAP_NSD */
566612ed1c7cSGregory Neil Shapiro #if MAP_REGEX
566712ed1c7cSGregory Neil Shapiro 	"MAP_REGEX",
566812ed1c7cSGregory Neil Shapiro #endif /* MAP_REGEX */
5669c2aa98e2SPeter Wemm #if MATCHGECOS
5670c2aa98e2SPeter Wemm 	"MATCHGECOS",
56713299c2f1SGregory Neil Shapiro #endif /* MATCHGECOS */
567212ed1c7cSGregory Neil Shapiro #if MILTER
567312ed1c7cSGregory Neil Shapiro 	"MILTER",
567412ed1c7cSGregory Neil Shapiro #endif /* MILTER */
5675c2aa98e2SPeter Wemm #if MIME7TO8
5676c2aa98e2SPeter Wemm 	"MIME7TO8",
56773299c2f1SGregory Neil Shapiro #endif /* MIME7TO8 */
56781ae5b8d4SGregory Neil Shapiro #if MIME7TO8_OLD
56791ae5b8d4SGregory Neil Shapiro 	"MIME7TO8_OLD",
56801ae5b8d4SGregory Neil Shapiro #endif /* MIME7TO8_OLD */
5681c2aa98e2SPeter Wemm #if MIME8TO7
5682c2aa98e2SPeter Wemm 	"MIME8TO7",
56833299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
5684c2aa98e2SPeter Wemm #if NAMED_BIND
5685c2aa98e2SPeter Wemm 	"NAMED_BIND",
56863299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
568712ed1c7cSGregory Neil Shapiro #if NDBM
5688c2aa98e2SPeter Wemm 	"NDBM",
56893299c2f1SGregory Neil Shapiro #endif /* NDBM */
5690c2aa98e2SPeter Wemm #if NETINET
5691c2aa98e2SPeter Wemm 	"NETINET",
56923299c2f1SGregory Neil Shapiro #endif /* NETINET */
56933299c2f1SGregory Neil Shapiro #if NETINET6
56943299c2f1SGregory Neil Shapiro 	"NETINET6",
56953299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
5696c2aa98e2SPeter Wemm #if NETINFO
5697c2aa98e2SPeter Wemm 	"NETINFO",
56983299c2f1SGregory Neil Shapiro #endif /* NETINFO */
5699c2aa98e2SPeter Wemm #if NETISO
5700c2aa98e2SPeter Wemm 	"NETISO",
57013299c2f1SGregory Neil Shapiro #endif /* NETISO */
5702c2aa98e2SPeter Wemm #if NETNS
5703c2aa98e2SPeter Wemm 	"NETNS",
57043299c2f1SGregory Neil Shapiro #endif /* NETNS */
5705c2aa98e2SPeter Wemm #if NETUNIX
5706c2aa98e2SPeter Wemm 	"NETUNIX",
57073299c2f1SGregory Neil Shapiro #endif /* NETUNIX */
5708c2aa98e2SPeter Wemm #if NETX25
5709c2aa98e2SPeter Wemm 	"NETX25",
57103299c2f1SGregory Neil Shapiro #endif /* NETX25 */
571112ed1c7cSGregory Neil Shapiro #if NEWDB
5712c2aa98e2SPeter Wemm 	"NEWDB",
57133299c2f1SGregory Neil Shapiro #endif /* NEWDB */
571412ed1c7cSGregory Neil Shapiro #if NIS
5715c2aa98e2SPeter Wemm 	"NIS",
57163299c2f1SGregory Neil Shapiro #endif /* NIS */
571712ed1c7cSGregory Neil Shapiro #if NISPLUS
5718c2aa98e2SPeter Wemm 	"NISPLUS",
57193299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
572012ed1c7cSGregory Neil Shapiro #if NO_DH
572112ed1c7cSGregory Neil Shapiro 	"NO_DH",
572212ed1c7cSGregory Neil Shapiro #endif /* NO_DH */
572312ed1c7cSGregory Neil Shapiro #if PH_MAP
57243299c2f1SGregory Neil Shapiro 	"PH_MAP",
57253299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
572612ed1c7cSGregory Neil Shapiro #ifdef PICKY_HELO_CHECK
572712ed1c7cSGregory Neil Shapiro 	"PICKY_HELO_CHECK",
572812ed1c7cSGregory Neil Shapiro #endif /* PICKY_HELO_CHECK */
572912ed1c7cSGregory Neil Shapiro #if PIPELINING
573012ed1c7cSGregory Neil Shapiro 	"PIPELINING",
573112ed1c7cSGregory Neil Shapiro #endif /* PIPELINING */
57323299c2f1SGregory Neil Shapiro #if SASL
573388ad41d4SGregory Neil Shapiro # if SASL >= 20000
573488ad41d4SGregory Neil Shapiro 	"SASLv2",
573588ad41d4SGregory Neil Shapiro # else /* SASL >= 20000 */
57363299c2f1SGregory Neil Shapiro 	"SASL",
573788ad41d4SGregory Neil Shapiro # endif /* SASL >= 20000 */
57383299c2f1SGregory Neil Shapiro #endif /* SASL */
5739c2aa98e2SPeter Wemm #if SCANF
5740c2aa98e2SPeter Wemm 	"SCANF",
57413299c2f1SGregory Neil Shapiro #endif /* SCANF */
5742c2aa98e2SPeter Wemm #if SMTPDEBUG
5743c2aa98e2SPeter Wemm 	"SMTPDEBUG",
57443299c2f1SGregory Neil Shapiro #endif /* SMTPDEBUG */
5745bfb62e91SGregory Neil Shapiro #if SOCKETMAP
5746bfb62e91SGregory Neil Shapiro 	"SOCKETMAP",
5747bfb62e91SGregory Neil Shapiro #endif /* SOCKETMAP */
57483299c2f1SGregory Neil Shapiro #if STARTTLS
57493299c2f1SGregory Neil Shapiro 	"STARTTLS",
57503299c2f1SGregory Neil Shapiro #endif /* STARTTLS */
575112ed1c7cSGregory Neil Shapiro #if SUID_ROOT_FILES_OK
5752c2aa98e2SPeter Wemm 	"SUID_ROOT_FILES_OK",
57533299c2f1SGregory Neil Shapiro #endif /* SUID_ROOT_FILES_OK */
5754c2aa98e2SPeter Wemm #if TCPWRAPPERS
5755c2aa98e2SPeter Wemm 	"TCPWRAPPERS",
57563299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
575712ed1c7cSGregory Neil Shapiro #if TLS_NO_RSA
575812ed1c7cSGregory Neil Shapiro 	"TLS_NO_RSA",
575912ed1c7cSGregory Neil Shapiro #endif /* TLS_NO_RSA */
576012ed1c7cSGregory Neil Shapiro #if TLS_VRFY_PER_CTX
576112ed1c7cSGregory Neil Shapiro 	"TLS_VRFY_PER_CTX",
576212ed1c7cSGregory Neil Shapiro #endif /* TLS_VRFY_PER_CTX */
5763c2aa98e2SPeter Wemm #if USERDB
5764c2aa98e2SPeter Wemm 	"USERDB",
57653299c2f1SGregory Neil Shapiro #endif /* USERDB */
5766320f00e7SGregory Neil Shapiro #if USE_LDAP_INIT
5767320f00e7SGregory Neil Shapiro 	"USE_LDAP_INIT",
5768320f00e7SGregory Neil Shapiro #endif /* USE_LDAP_INIT */
5769bfb62e91SGregory Neil Shapiro #if USE_TTYPATH
5770bfb62e91SGregory Neil Shapiro 	"USE_TTYPATH",
5771bfb62e91SGregory Neil Shapiro #endif /* USE_TTYPATH */
5772c2aa98e2SPeter Wemm #if XDEBUG
5773c2aa98e2SPeter Wemm 	"XDEBUG",
57743299c2f1SGregory Neil Shapiro #endif /* XDEBUG */
577512ed1c7cSGregory Neil Shapiro #if XLA
5776c2aa98e2SPeter Wemm 	"XLA",
57773299c2f1SGregory Neil Shapiro #endif /* XLA */
5778c2aa98e2SPeter Wemm 	NULL
5779c2aa98e2SPeter Wemm };
5780c2aa98e2SPeter Wemm 
5781c2aa98e2SPeter Wemm 
5782c2aa98e2SPeter Wemm /*
5783c2aa98e2SPeter Wemm **  OS compile options.
5784c2aa98e2SPeter Wemm */
5785c2aa98e2SPeter Wemm 
5786c2aa98e2SPeter Wemm char	*OsCompileOptions[] =
5787c2aa98e2SPeter Wemm {
578812ed1c7cSGregory Neil Shapiro #if ADDRCONFIG_IS_BROKEN
578912ed1c7cSGregory Neil Shapiro 	"ADDRCONFIG_IS_BROKEN",
579012ed1c7cSGregory Neil Shapiro #endif /* ADDRCONFIG_IS_BROKEN */
579112ed1c7cSGregory Neil Shapiro #ifdef AUTO_NETINFO_HOSTS
579212ed1c7cSGregory Neil Shapiro 	"AUTO_NETINFO_HOSTS",
579312ed1c7cSGregory Neil Shapiro #endif /* AUTO_NETINFO_HOSTS */
579412ed1c7cSGregory Neil Shapiro #ifdef AUTO_NIS_ALIASES
579512ed1c7cSGregory Neil Shapiro 	"AUTO_NIS_ALIASES",
579612ed1c7cSGregory Neil Shapiro #endif /* AUTO_NIS_ALIASES */
579712ed1c7cSGregory Neil Shapiro #if BROKEN_RES_SEARCH
579812ed1c7cSGregory Neil Shapiro 	"BROKEN_RES_SEARCH",
579912ed1c7cSGregory Neil Shapiro #endif /* BROKEN_RES_SEARCH */
580012ed1c7cSGregory Neil Shapiro #ifdef BSD4_4_SOCKADDR
580112ed1c7cSGregory Neil Shapiro 	"BSD4_4_SOCKADDR",
580212ed1c7cSGregory Neil Shapiro #endif /* BSD4_4_SOCKADDR */
5803c2aa98e2SPeter Wemm #if BOGUS_O_EXCL
5804c2aa98e2SPeter Wemm 	"BOGUS_O_EXCL",
58053299c2f1SGregory Neil Shapiro #endif /* BOGUS_O_EXCL */
580612ed1c7cSGregory Neil Shapiro #if DEC_OSF_BROKEN_GETPWENT
580712ed1c7cSGregory Neil Shapiro 	"DEC_OSF_BROKEN_GETPWENT",
580812ed1c7cSGregory Neil Shapiro #endif /* DEC_OSF_BROKEN_GETPWENT */
58093299c2f1SGregory Neil Shapiro #if FAST_PID_RECYCLE
58103299c2f1SGregory Neil Shapiro 	"FAST_PID_RECYCLE",
58113299c2f1SGregory Neil Shapiro #endif /* FAST_PID_RECYCLE */
5812bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM
5813bfb62e91SGregory Neil Shapiro 	"HASCLOSEFROM",
5814bfb62e91SGregory Neil Shapiro #endif /* HASCLOSEFROM */
58153299c2f1SGregory Neil Shapiro #if HASFCHOWN
58163299c2f1SGregory Neil Shapiro 	"HASFCHOWN",
58173299c2f1SGregory Neil Shapiro #endif /* HASFCHOWN */
5818c2aa98e2SPeter Wemm #if HASFCHMOD
5819c2aa98e2SPeter Wemm 	"HASFCHMOD",
58203299c2f1SGregory Neil Shapiro #endif /* HASFCHMOD */
5821bfb62e91SGregory Neil Shapiro #if HASFDWALK
5822bfb62e91SGregory Neil Shapiro 	"HASFDWALK",
5823bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */
5824c2aa98e2SPeter Wemm #if HASFLOCK
5825c2aa98e2SPeter Wemm 	"HASFLOCK",
58263299c2f1SGregory Neil Shapiro #endif /* HASFLOCK */
5827c2aa98e2SPeter Wemm #if HASGETDTABLESIZE
5828c2aa98e2SPeter Wemm 	"HASGETDTABLESIZE",
58293299c2f1SGregory Neil Shapiro #endif /* HASGETDTABLESIZE */
5830c2aa98e2SPeter Wemm #if HASGETUSERSHELL
5831c2aa98e2SPeter Wemm 	"HASGETUSERSHELL",
58323299c2f1SGregory Neil Shapiro #endif /* HASGETUSERSHELL */
5833c2aa98e2SPeter Wemm #if HASINITGROUPS
5834c2aa98e2SPeter Wemm 	"HASINITGROUPS",
58353299c2f1SGregory Neil Shapiro #endif /* HASINITGROUPS */
5836c2aa98e2SPeter Wemm #if HASLSTAT
5837c2aa98e2SPeter Wemm 	"HASLSTAT",
58383299c2f1SGregory Neil Shapiro #endif /* HASLSTAT */
583912ed1c7cSGregory Neil Shapiro #if HASNICE
584012ed1c7cSGregory Neil Shapiro 	"HASNICE",
584112ed1c7cSGregory Neil Shapiro #endif /* HASNICE */
58423299c2f1SGregory Neil Shapiro #if HASRANDOM
58433299c2f1SGregory Neil Shapiro 	"HASRANDOM",
58443299c2f1SGregory Neil Shapiro #endif /* HASRANDOM */
584512ed1c7cSGregory Neil Shapiro #if HASRRESVPORT
584612ed1c7cSGregory Neil Shapiro 	"HASRRESVPORT",
584712ed1c7cSGregory Neil Shapiro #endif /* HASRRESVPORT */
584812ed1c7cSGregory Neil Shapiro #if HASSETEGID
584912ed1c7cSGregory Neil Shapiro 	"HASSETEGID",
585012ed1c7cSGregory Neil Shapiro #endif /* HASSETEGID */
58513299c2f1SGregory Neil Shapiro #if HASSETLOGIN
58523299c2f1SGregory Neil Shapiro 	"HASSETLOGIN",
58533299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
585412ed1c7cSGregory Neil Shapiro #if HASSETREGID
585512ed1c7cSGregory Neil Shapiro 	"HASSETREGID",
585612ed1c7cSGregory Neil Shapiro #endif /* HASSETREGID */
585712ed1c7cSGregory Neil Shapiro #if HASSETRESGID
585812ed1c7cSGregory Neil Shapiro 	"HASSETRESGID",
585912ed1c7cSGregory Neil Shapiro #endif /* HASSETRESGID */
5860c2aa98e2SPeter Wemm #if HASSETREUID
5861c2aa98e2SPeter Wemm 	"HASSETREUID",
58623299c2f1SGregory Neil Shapiro #endif /* HASSETREUID */
5863c2aa98e2SPeter Wemm #if HASSETRLIMIT
5864c2aa98e2SPeter Wemm 	"HASSETRLIMIT",
58653299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
5866c2aa98e2SPeter Wemm #if HASSETSID
5867c2aa98e2SPeter Wemm 	"HASSETSID",
58683299c2f1SGregory Neil Shapiro #endif /* HASSETSID */
5869c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT
5870c2aa98e2SPeter Wemm 	"HASSETUSERCONTEXT",
58713299c2f1SGregory Neil Shapiro #endif /* HASSETUSERCONTEXT */
5872c2aa98e2SPeter Wemm #if HASSETVBUF
5873c2aa98e2SPeter Wemm 	"HASSETVBUF",
58743299c2f1SGregory Neil Shapiro #endif /* HASSETVBUF */
5875c2aa98e2SPeter Wemm #if HAS_ST_GEN
5876c2aa98e2SPeter Wemm 	"HAS_ST_GEN",
58773299c2f1SGregory Neil Shapiro #endif /* HAS_ST_GEN */
58783299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
58793299c2f1SGregory Neil Shapiro 	"HASSRANDOMDEV",
58803299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
58813299c2f1SGregory Neil Shapiro #if HASURANDOMDEV
58823299c2f1SGregory Neil Shapiro 	"HASURANDOMDEV",
58833299c2f1SGregory Neil Shapiro #endif /* HASURANDOMDEV */
5884c2aa98e2SPeter Wemm #if HASSTRERROR
5885c2aa98e2SPeter Wemm 	"HASSTRERROR",
58863299c2f1SGregory Neil Shapiro #endif /* HASSTRERROR */
5887c2aa98e2SPeter Wemm #if HASULIMIT
5888c2aa98e2SPeter Wemm 	"HASULIMIT",
58893299c2f1SGregory Neil Shapiro #endif /* HASULIMIT */
5890c2aa98e2SPeter Wemm #if HASUNAME
5891c2aa98e2SPeter Wemm 	"HASUNAME",
58923299c2f1SGregory Neil Shapiro #endif /* HASUNAME */
5893c2aa98e2SPeter Wemm #if HASUNSETENV
5894c2aa98e2SPeter Wemm 	"HASUNSETENV",
58953299c2f1SGregory Neil Shapiro #endif /* HASUNSETENV */
5896c2aa98e2SPeter Wemm #if HASWAITPID
5897c2aa98e2SPeter Wemm 	"HASWAITPID",
58983299c2f1SGregory Neil Shapiro #endif /* HASWAITPID */
5899c2aa98e2SPeter Wemm #if IDENTPROTO
5900c2aa98e2SPeter Wemm 	"IDENTPROTO",
59013299c2f1SGregory Neil Shapiro #endif /* IDENTPROTO */
5902c2aa98e2SPeter Wemm #if IP_SRCROUTE
5903c2aa98e2SPeter Wemm 	"IP_SRCROUTE",
59043299c2f1SGregory Neil Shapiro #endif /* IP_SRCROUTE */
5905c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
5906c2aa98e2SPeter Wemm 	"LOCK_ON_OPEN",
59073299c2f1SGregory Neil Shapiro #endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
5908c2aa98e2SPeter Wemm #if NEEDFSYNC
5909c2aa98e2SPeter Wemm 	"NEEDFSYNC",
59103299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
591112ed1c7cSGregory Neil Shapiro #if NEEDLINK
591212ed1c7cSGregory Neil Shapiro 	"NEEDLINK",
591312ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */
591412ed1c7cSGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
591512ed1c7cSGregory Neil Shapiro 	"NEEDLOCAL_HOSTNAME_LENGTH",
591612ed1c7cSGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
591712ed1c7cSGregory Neil Shapiro #if NEEDSGETIPNODE
591812ed1c7cSGregory Neil Shapiro 	"NEEDSGETIPNODE",
591912ed1c7cSGregory Neil Shapiro #endif /* NEEDSGETIPNODE */
592012ed1c7cSGregory Neil Shapiro #if NEEDSTRSTR
592112ed1c7cSGregory Neil Shapiro 	"NEEDSTRSTR",
592212ed1c7cSGregory Neil Shapiro #endif /* NEEDSTRSTR */
592312ed1c7cSGregory Neil Shapiro #if NEEDSTRTOL
592412ed1c7cSGregory Neil Shapiro 	"NEEDSTRTOL",
592512ed1c7cSGregory Neil Shapiro #endif /* NEEDSTRTOL */
592612ed1c7cSGregory Neil Shapiro #ifdef NO_GETSERVBYNAME
592712ed1c7cSGregory Neil Shapiro 	"NO_GETSERVBYNAME",
592812ed1c7cSGregory Neil Shapiro #endif /* NO_GETSERVBYNAME */
5929c2aa98e2SPeter Wemm #if NOFTRUNCATE
5930c2aa98e2SPeter Wemm 	"NOFTRUNCATE",
59313299c2f1SGregory Neil Shapiro #endif /* NOFTRUNCATE */
593212ed1c7cSGregory Neil Shapiro #if REQUIRES_DIR_FSYNC
593312ed1c7cSGregory Neil Shapiro 	"REQUIRES_DIR_FSYNC",
593412ed1c7cSGregory Neil Shapiro #endif /* REQUIRES_DIR_FSYNC */
5935c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H
5936c2aa98e2SPeter Wemm 	"RLIMIT_NEEDS_SYS_TIME_H",
59373299c2f1SGregory Neil Shapiro #endif /* RLIMIT_NEEDS_SYS_TIME_H */
5938c2aa98e2SPeter Wemm #if SAFENFSPATHCONF
5939c2aa98e2SPeter Wemm 	"SAFENFSPATHCONF",
59403299c2f1SGregory Neil Shapiro #endif /* SAFENFSPATHCONF */
5941c2aa98e2SPeter Wemm #if SECUREWARE
5942c2aa98e2SPeter Wemm 	"SECUREWARE",
59433299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
5944c2aa98e2SPeter Wemm #if SHARE_V1
5945c2aa98e2SPeter Wemm 	"SHARE_V1",
59463299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
5947c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN
5948c2aa98e2SPeter Wemm 	"SIOCGIFCONF_IS_BROKEN",
59493299c2f1SGregory Neil Shapiro #endif /* SIOCGIFCONF_IS_BROKEN */
5950c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN
5951c2aa98e2SPeter Wemm 	"SIOCGIFNUM_IS_BROKEN",
59523299c2f1SGregory Neil Shapiro #endif /* SIOCGIFNUM_IS_BROKEN */
59533299c2f1SGregory Neil Shapiro #if SNPRINTF_IS_BROKEN
59543299c2f1SGregory Neil Shapiro 	"SNPRINTF_IS_BROKEN",
59553299c2f1SGregory Neil Shapiro #endif /* SNPRINTF_IS_BROKEN */
59563299c2f1SGregory Neil Shapiro #if SO_REUSEADDR_IS_BROKEN
59573299c2f1SGregory Neil Shapiro 	"SO_REUSEADDR_IS_BROKEN",
59583299c2f1SGregory Neil Shapiro #endif /* SO_REUSEADDR_IS_BROKEN */
5959c2aa98e2SPeter Wemm #if SYS5SETPGRP
5960c2aa98e2SPeter Wemm 	"SYS5SETPGRP",
59613299c2f1SGregory Neil Shapiro #endif /* SYS5SETPGRP */
5962c2aa98e2SPeter Wemm #if SYSTEM5
5963c2aa98e2SPeter Wemm 	"SYSTEM5",
59643299c2f1SGregory Neil Shapiro #endif /* SYSTEM5 */
596512ed1c7cSGregory Neil Shapiro #if USE_DOUBLE_FORK
596612ed1c7cSGregory Neil Shapiro 	"USE_DOUBLE_FORK",
596712ed1c7cSGregory Neil Shapiro #endif /* USE_DOUBLE_FORK */
596812ed1c7cSGregory Neil Shapiro #if USE_ENVIRON
596912ed1c7cSGregory Neil Shapiro 	"USE_ENVIRON",
597012ed1c7cSGregory Neil Shapiro #endif /* USE_ENVIRON */
5971c2aa98e2SPeter Wemm #if USE_SA_SIGACTION
5972c2aa98e2SPeter Wemm 	"USE_SA_SIGACTION",
59733299c2f1SGregory Neil Shapiro #endif /* USE_SA_SIGACTION */
5974c2aa98e2SPeter Wemm #if USE_SIGLONGJMP
5975c2aa98e2SPeter Wemm 	"USE_SIGLONGJMP",
59763299c2f1SGregory Neil Shapiro #endif /* USE_SIGLONGJMP */
597712ed1c7cSGregory Neil Shapiro #if USEGETCONFATTR
597812ed1c7cSGregory Neil Shapiro 	"USEGETCONFATTR",
597912ed1c7cSGregory Neil Shapiro #endif /* USEGETCONFATTR */
5980c2aa98e2SPeter Wemm #if USESETEUID
5981c2aa98e2SPeter Wemm 	"USESETEUID",
59823299c2f1SGregory Neil Shapiro #endif /* USESETEUID */
598312ed1c7cSGregory Neil Shapiro #ifdef USESYSCTL
598412ed1c7cSGregory Neil Shapiro 	"USESYSCTL",
598512ed1c7cSGregory Neil Shapiro #endif /* USESYSCTL */
598612ed1c7cSGregory Neil Shapiro #if USING_NETSCAPE_LDAP
598712ed1c7cSGregory Neil Shapiro 	"USING_NETSCAPE_LDAP",
598812ed1c7cSGregory Neil Shapiro #endif /* USING_NETSCAPE_LDAP */
598912ed1c7cSGregory Neil Shapiro #ifdef WAITUNION
599012ed1c7cSGregory Neil Shapiro 	"WAITUNION",
599112ed1c7cSGregory Neil Shapiro #endif /* WAITUNION */
599212ed1c7cSGregory Neil Shapiro 	NULL
599312ed1c7cSGregory Neil Shapiro };
599412ed1c7cSGregory Neil Shapiro 
599512ed1c7cSGregory Neil Shapiro /*
599612ed1c7cSGregory Neil Shapiro **  FFR compile options.
599712ed1c7cSGregory Neil Shapiro */
599812ed1c7cSGregory Neil Shapiro 
599912ed1c7cSGregory Neil Shapiro char	*FFRCompileOptions[] =
600012ed1c7cSGregory Neil Shapiro {
600112ed1c7cSGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO
600272936242SGregory Neil Shapiro 	/* DefaultAuthInfo can be specified by user. */
6003bfb62e91SGregory Neil Shapiro 	/* DefaultAuthInfo doesn't really work in 8.13 anymore. */
600412ed1c7cSGregory Neil Shapiro 	"_FFR_ALLOW_SASLINFO",
600512ed1c7cSGregory Neil Shapiro #endif /* _FFR_ALLOW_SASLINFO */
600612ed1c7cSGregory Neil Shapiro #if _FFR_BESTMX_BETTER_TRUNCATION
600772936242SGregory Neil Shapiro 	/* Better truncation of list of MX records for dns map. */
600812ed1c7cSGregory Neil Shapiro 	"_FFR_BESTMX_BETTER_TRUNCATION",
600912ed1c7cSGregory Neil Shapiro #endif /* _FFR_BESTMX_BETTER_TRUNCATION */
601072936242SGregory Neil Shapiro #if _FFR_BLOCK_PROXIES
601172936242SGregory Neil Shapiro 	/*
601272936242SGregory Neil Shapiro 	**  Try to deal with open HTTP proxies that are used to send spam
601372936242SGregory Neil Shapiro 	**  by recognizing some commands from them.
601472936242SGregory Neil Shapiro 	*/
601572936242SGregory Neil Shapiro 
601672936242SGregory Neil Shapiro 	"_FFR_BLOCK_PROXIES",
601772936242SGregory Neil Shapiro #endif /* _FFR_BLOCK_PROXIES */
601812ed1c7cSGregory Neil Shapiro #if _FFR_CATCH_BROKEN_MTAS
601972936242SGregory Neil Shapiro 	/* Deal with MTAs that send a reply during the DATA phase. */
602012ed1c7cSGregory Neil Shapiro 	"_FFR_CATCH_BROKEN_MTAS",
602112ed1c7cSGregory Neil Shapiro #endif /* _FFR_CATCH_BROKEN_MTAS */
602212ed1c7cSGregory Neil Shapiro #if _FFR_CHECK_EOM
602372936242SGregory Neil Shapiro 	/* Enable check_eom ruleset */
602412ed1c7cSGregory Neil Shapiro 	"_FFR_CHECK_EOM",
602512ed1c7cSGregory Neil Shapiro #endif /* _FFR_CHECK_EOM */
602688ad41d4SGregory Neil Shapiro #if _FFR_CHK_QUEUE
602772936242SGregory Neil Shapiro 	/* Stricter checks about queue directory permissions. */
602888ad41d4SGregory Neil Shapiro 	"_FFR_CHK_QUEUE",
602988ad41d4SGregory Neil Shapiro #endif /* _FFR_CHK_QUEUE */
60307660b554SGregory Neil Shapiro #if _FFR_CLIENT_SIZE
60317660b554SGregory Neil Shapiro 	/* Don't try to send mail if its size exceeds SIZE= of server. */
60327660b554SGregory Neil Shapiro 	"_FFR_CLIENT_SIZE",
60337660b554SGregory Neil Shapiro #endif /* _FFR_CLIENT_SIZE */
603412ed1c7cSGregory Neil Shapiro #if _FFR_CONTROL_MSTAT
603572936242SGregory Neil Shapiro 	/* Extended daemon status. */
603612ed1c7cSGregory Neil Shapiro 	"_FFR_CONTROL_MSTAT",
603712ed1c7cSGregory Neil Shapiro #endif /* _FFR_CONTROL_MSTAT */
6038bfb62e91SGregory Neil Shapiro #if _FFR_CRLPATH
6039bfb62e91SGregory Neil Shapiro 	/* CRLPath; needs documentation; Al Smith */
6040bfb62e91SGregory Neil Shapiro 	"_FFR_CRLPATH",
6041bfb62e91SGregory Neil Shapiro #endif /* _FFR_CRLPATH */
604212ed1c7cSGregory Neil Shapiro #if _FFR_DAEMON_NETUNIX
604372936242SGregory Neil Shapiro 	/* Allow local (not just TCP) socket connection to server. */
604412ed1c7cSGregory Neil Shapiro 	"_FFR_DAEMON_NETUNIX",
604512ed1c7cSGregory Neil Shapiro #endif /* _FFR_DAEMON_NETUNIX */
604612ed1c7cSGregory Neil Shapiro #if _FFR_DEPRECATE_MAILER_FLAG_I
604772936242SGregory Neil Shapiro 	/* What it says :-) */
604812ed1c7cSGregory Neil Shapiro 	"_FFR_DEPRECATE_MAILER_FLAG_I",
604912ed1c7cSGregory Neil Shapiro #endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
6050320f00e7SGregory Neil Shapiro #if _FFR_DIGUNIX_SAFECHOWN
605172936242SGregory Neil Shapiro 	/* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */
6052320f00e7SGregory Neil Shapiro /* Problem noted by Anne Bennett of Concordia University */
6053320f00e7SGregory Neil Shapiro 	"_FFR_DIGUNIX_SAFECHOWN",
6054320f00e7SGregory Neil Shapiro #endif /* _FFR_DIGUNIX_SAFECHOWN */
6055188b7d28SGregory Neil Shapiro #if _FFR_DM_PER_DAEMON
6056188b7d28SGregory Neil Shapiro 	/* DeliveryMode per DaemonPortOptions: 'D' */
6057188b7d28SGregory Neil Shapiro 	"_FFR_DM_PER_DAEMON",
6058188b7d28SGregory Neil Shapiro #endif /* _FFR_DM_PER_DAEMON */
6059320f00e7SGregory Neil Shapiro #if _FFR_DNSMAP_ALIASABLE
606072936242SGregory Neil Shapiro 	/* Allow dns map type to be used for aliases. */
6061320f00e7SGregory Neil Shapiro /* Don Lewis of TDK */
6062320f00e7SGregory Neil Shapiro 	"_FFR_DNSMAP_ALIASABLE",
6063320f00e7SGregory Neil Shapiro #endif /* _FFR_DNSMAP_ALIASABLE */
606412ed1c7cSGregory Neil Shapiro #if _FFR_DNSMAP_BASE
606572936242SGregory Neil Shapiro 	/* Specify a "base" domain for DNS lookups. */
606612ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_BASE",
606712ed1c7cSGregory Neil Shapiro #endif /* _FFR_DNSMAP_BASE */
606812ed1c7cSGregory Neil Shapiro #if _FFR_DNSMAP_MULTI
606972936242SGregory Neil Shapiro 	/* Allow multiple return values for DNS map. */
607012ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_MULTI",
607112ed1c7cSGregory Neil Shapiro # if _FFR_DNSMAP_MULTILIMIT
607272936242SGregory Neil Shapiro 	/* Limit number of return values for DNS map. */
607312ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_MULTILIMIT",
607412ed1c7cSGregory Neil Shapiro # endif /* _FFR_DNSMAP_MULTILIMIT */
607512ed1c7cSGregory Neil Shapiro #endif /* _FFR_DNSMAP_MULTI */
607612ed1c7cSGregory Neil Shapiro #if _FFR_DONTLOCKFILESFORREAD_OPTION
607772936242SGregory Neil Shapiro 	/* Enable DontLockFilesForRead option. */
607812ed1c7cSGregory Neil Shapiro 	"_FFR_DONTLOCKFILESFORREAD_OPTION",
607912ed1c7cSGregory Neil Shapiro #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
608012ed1c7cSGregory Neil Shapiro #if _FFR_DOTTED_USERNAMES
608172936242SGregory Neil Shapiro 	/* Allow usernames with '.' */
608212ed1c7cSGregory Neil Shapiro 	"_FFR_DOTTED_USERNAMES",
608312ed1c7cSGregory Neil Shapiro #endif /* _FFR_DOTTED_USERNAMES */
608412ed1c7cSGregory Neil Shapiro #if _FFR_DROP_TRUSTUSER_WARNING
608572936242SGregory Neil Shapiro 	/*
608672936242SGregory Neil Shapiro 	**  Don't issue this warning:
608772936242SGregory Neil Shapiro 	**  "readcf: option TrustedUser may cause problems on systems
608872936242SGregory Neil Shapiro 	**  which do not support fchown() if UseMSP is not set.
608972936242SGregory Neil Shapiro 	*/
609072936242SGregory Neil Shapiro 
609112ed1c7cSGregory Neil Shapiro 	"_FFR_DROP_TRUSTUSER_WARNING",
609212ed1c7cSGregory Neil Shapiro #endif /* _FFR_DROP_TRUSTUSER_WARNING */
60937660b554SGregory Neil Shapiro #if _FFR_EXTRA_MAP_CHECK
60947660b554SGregory Neil Shapiro 	/* perform extra checks on $( $) in R lines */
60957660b554SGregory Neil Shapiro 	"_FFR_EXTRA_MAP_CHECK",
60967660b554SGregory Neil Shapiro #endif /* _FFR_EXTRA_MAP_CHECK */
609712ed1c7cSGregory Neil Shapiro #if _FFR_FIX_DASHT
609872936242SGregory Neil Shapiro 	/*
609972936242SGregory Neil Shapiro 	**  If using -t, force not sending to argv recipients, even
610072936242SGregory Neil Shapiro 	**  if they are mentioned in the headers.
610172936242SGregory Neil Shapiro 	*/
610272936242SGregory Neil Shapiro 
610312ed1c7cSGregory Neil Shapiro 	"_FFR_FIX_DASHT",
610412ed1c7cSGregory Neil Shapiro #endif /* _FFR_FIX_DASHT */
610512ed1c7cSGregory Neil Shapiro #if _FFR_FORWARD_SYSERR
610672936242SGregory Neil Shapiro 	/* Cause a "syserr" if forward file isn't "safe". */
610712ed1c7cSGregory Neil Shapiro 	"_FFR_FORWARD_SYSERR",
610812ed1c7cSGregory Neil Shapiro #endif /* _FFR_FORWARD_SYSERR */
610912ed1c7cSGregory Neil Shapiro #if _FFR_GEN_ORCPT
611072936242SGregory Neil Shapiro 	/* Generate a ORCPT DSN arg if not already provided */
611112ed1c7cSGregory Neil Shapiro 	"_FFR_GEN_ORCPT",
611212ed1c7cSGregory Neil Shapiro #endif /* _FFR_GEN_ORCPT */
611312ed1c7cSGregory Neil Shapiro #if _FFR_GROUPREADABLEAUTHINFOFILE
611472936242SGregory Neil Shapiro 	/* Allow group readable DefaultAuthInfo file. */
611512ed1c7cSGregory Neil Shapiro 	"_FFR_GROUPREADABLEAUTHINFOFILE",
611612ed1c7cSGregory Neil Shapiro #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
6117320f00e7SGregory Neil Shapiro #if _FFR_HANDLE_ISO8859_GECOS
611872936242SGregory Neil Shapiro 	/*
611972936242SGregory Neil Shapiro 	**  Allow ISO 8859 characters in GECOS field: replace them
612072936242SGregory Neil Shapiro 	**  ith ASCII "equivalent".
612172936242SGregory Neil Shapiro 	*/
612272936242SGregory Neil Shapiro 
6123320f00e7SGregory Neil Shapiro /* Peter Eriksson of Linkopings universitet */
6124320f00e7SGregory Neil Shapiro 	"_FFR_HANDLE_ISO8859_GECOS",
6125320f00e7SGregory Neil Shapiro #endif /* _FFR_HANDLE_ISO8859_GECOS */
612612ed1c7cSGregory Neil Shapiro #if _FFR_HDR_TYPE
612772936242SGregory Neil Shapiro 	/* Set 'h' in {addr_type} for headers. */
612812ed1c7cSGregory Neil Shapiro 	"_FFR_HDR_TYPE",
612912ed1c7cSGregory Neil Shapiro #endif /* _FFR_HDR_TYPE */
6130bfb62e91SGregory Neil Shapiro #if _FFR_HELONAME
6131bfb62e91SGregory Neil Shapiro 	/* option to set heloname; Nik Clayton of FreeBSD */
6132bfb62e91SGregory Neil Shapiro 	"_FFR_HELONAME",
6133bfb62e91SGregory Neil Shapiro #endif /* _FFR_HELONAME */
613412ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
613572936242SGregory Neil Shapiro 	/* Use nsswitch on HP-UX */
613612ed1c7cSGregory Neil Shapiro 	"_FFR_HPUX_NSSWITCH",
613712ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */
61387660b554SGregory Neil Shapiro #if _FFR_IGNORE_BOGUS_ADDR
61397660b554SGregory Neil Shapiro 	/* Ignore addresses for which prescan() failed */
61407660b554SGregory Neil Shapiro 	"_FFR_IGNORE_BOGUS_ADDR",
61417660b554SGregory Neil Shapiro #endif /* _FFR_IGNORE_BOGUS_ADDR */
614212ed1c7cSGregory Neil Shapiro #if _FFR_IGNORE_EXT_ON_HELO
614372936242SGregory Neil Shapiro 	/* Ignore extensions offered in response to HELO */
614412ed1c7cSGregory Neil Shapiro 	"_FFR_IGNORE_EXT_ON_HELO",
614512ed1c7cSGregory Neil Shapiro #endif /* _FFR_IGNORE_EXT_ON_HELO */
6146bfb62e91SGregory Neil Shapiro #if _FFR_MAXDATASIZE
6147bfb62e91SGregory Neil Shapiro 	/*
6148bfb62e91SGregory Neil Shapiro 	**  It is possible that a header is larger than MILTER_CHUNK_SIZE,
6149bfb62e91SGregory Neil Shapiro 	**  hence this shouldn't be used as limit for milter communication.
6150bfb62e91SGregory Neil Shapiro 	**  see also libmilter/comm.c
6151bfb62e91SGregory Neil Shapiro 	**  Gurusamy Sarathy of ActiveState
6152bfb62e91SGregory Neil Shapiro 	*/
6153bfb62e91SGregory Neil Shapiro 
6154684b2a5fSGregory Neil Shapiro 	"_FFR_MAXDATASIZE",
6155bfb62e91SGregory Neil Shapiro #endif /* _FFR_MAXDATASIZE */
615612ed1c7cSGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES
615772936242SGregory Neil Shapiro 	/* Try to limit number of .forward entries */
615872936242SGregory Neil Shapiro 	/* (doesn't work) */
615912ed1c7cSGregory Neil Shapiro /* Randall S. Winchester of the University of Maryland */
616012ed1c7cSGregory Neil Shapiro 	"_FFR_MAX_FORWARD_ENTRIES",
616112ed1c7cSGregory Neil Shapiro #endif /* _FFR_MAX_FORWARD_ENTRIES */
61627660b554SGregory Neil Shapiro #if _FFR_MAX_SLEEP_TIME
61637660b554SGregory Neil Shapiro 	/* Limit sleep(2) time in libsm/clock.c */
61647660b554SGregory Neil Shapiro 	"_FFR_MAX_SLEEP_TIME",
61657660b554SGregory Neil Shapiro #endif /* _FFR_MAX_SLEEP_TIME */
6166bfb62e91SGregory Neil Shapiro #if _FFR_MILTER_NAGLE
6167bfb62e91SGregory Neil Shapiro 	/* milter: turn off Nagle ("cork" on Linux) */
6168bfb62e91SGregory Neil Shapiro 	/* John Gardiner Myers of Proofpoint */
6169bfb62e91SGregory Neil Shapiro 	"_FFR_MILTER_NAGLE ",
6170bfb62e91SGregory Neil Shapiro #endif /* _FFR_MILTER_NAGLE */
6171bfb62e91SGregory Neil Shapiro #if _FFR_MILTER_NOHDR_RESP
6172bfb62e91SGregory Neil Shapiro 	/* milter: no response expected when sending headers */
6173bfb62e91SGregory Neil Shapiro 	/* John Gardiner Myers of Proofpoint */
6174bfb62e91SGregory Neil Shapiro 	"_FFR_MILTER_NOHDR_RESP",
6175bfb62e91SGregory Neil Shapiro #endif /* _FFR_MILTER_NOHDR_RESP */
6176bfb62e91SGregory Neil Shapiro #if _FFR_MIME7TO8_OLD
6177bfb62e91SGregory Neil Shapiro 	/* Old mime7to8 code, the new is broken for at least one example. */
6178bfb62e91SGregory Neil Shapiro 	"_FFR_MIME7TO8_OLD",
6179bfb62e91SGregory Neil Shapiro #endif /* _FFR_MAX_SLEEP_TIME */
618012ed1c7cSGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD
618172936242SGregory Neil Shapiro 	/* Do not issue a DELAY DSN for mailers that use the hold flag. */
618212ed1c7cSGregory Neil Shapiro /* Steven Pitzl */
618312ed1c7cSGregory Neil Shapiro 	"_FFR_NODELAYDSN_ON_HOLD",
618412ed1c7cSGregory Neil Shapiro #endif /* _FFR_NODELAYDSN_ON_HOLD */
618512ed1c7cSGregory Neil Shapiro #if _FFR_NO_PIPE
618672936242SGregory Neil Shapiro 	/* Disable PIPELINING, delay client if used. */
618712ed1c7cSGregory Neil Shapiro 	"_FFR_NO_PIPE",
618812ed1c7cSGregory Neil Shapiro #endif /* _FFR_NO_PIPE */
6189188b7d28SGregory Neil Shapiro #if _FFR_LOG_NTRIES
6190188b7d28SGregory Neil Shapiro 	/* log ntries=, from Nik Clayton of FreeBSD */
6191188b7d28SGregory Neil Shapiro 	"_FFR_LOG_NTRIES",
6192188b7d28SGregory Neil Shapiro #endif /* _FFR_LOG_NTRIES */
6193684b2a5fSGregory Neil Shapiro #if _FFR_PRIV_NOACTUALRECIPIENT
6194684b2a5fSGregory Neil Shapiro 	/*
6195684b2a5fSGregory Neil Shapiro 	** PrivacyOptions=noactualrecipient stops sendmail from putting
6196684b2a5fSGregory Neil Shapiro 	** X-Actual-Recipient lines in DSNs revealing the actual
6197684b2a5fSGregory Neil Shapiro 	** account that addresses map to.  Patch from Dan Harkless.
6198684b2a5fSGregory Neil Shapiro 	*/
6199684b2a5fSGregory Neil Shapiro 
6200188b7d28SGregory Neil Shapiro 	"_FFR_PRIV_NOACTUALRECIPIENT",
6201684b2a5fSGregory Neil Shapiro #endif /* _FFR_PRIV_NOACTUALRECIPIENT */
620212ed1c7cSGregory Neil Shapiro #if _FFR_QUEUEDELAY
620372936242SGregory Neil Shapiro 	/* Exponential queue delay; disabled in 8.13 since it isn't used. */
620412ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUEDELAY",
620512ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUEDELAY */
6206320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_GROUP_SORTORDER
620772936242SGregory Neil Shapiro 	/* Allow QueueSortOrder per queue group. */
6208320f00e7SGregory Neil Shapiro /* XXX: Still need to actually use qgrp->qg_sortorder */
6209320f00e7SGregory Neil Shapiro 	"_FFR_QUEUE_GROUP_SORTORDER",
6210320f00e7SGregory Neil Shapiro #endif /* _FFR_QUEUE_GROUP_SORTORDER */
621112ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_MACRO
621272936242SGregory Neil Shapiro 	/* Define {queue} macro. */
621312ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_MACRO",
621412ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUE_MACRO */
6215320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_RUN_PARANOIA
621672936242SGregory Neil Shapiro 	/* Additional checks when doing queue runs. */
6217320f00e7SGregory Neil Shapiro 	"_FFR_QUEUE_RUN_PARANOIA",
6218320f00e7SGregory Neil Shapiro #endif /* _FFR_QUEUE_RUN_PARANOIA */
621912ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_SCHED_DBG
622072936242SGregory Neil Shapiro 	/* Debug output for the queue scheduler. */
622112ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_SCHED_DBG",
622212ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUE_SCHED_DBG */
622312ed1c7cSGregory Neil Shapiro #if _FFR_REDIRECTEMPTY
622472936242SGregory Neil Shapiro 	/*
622572936242SGregory Neil Shapiro 	**  envelope <> can't be sent to mailing lists, only owner-
622672936242SGregory Neil Shapiro 	**  send spam of this type to owner- of the list
622772936242SGregory Neil Shapiro 	**  ----  to stop spam from going to mailing lists.
622872936242SGregory Neil Shapiro 	*/
622972936242SGregory Neil Shapiro 
623012ed1c7cSGregory Neil Shapiro 	"_FFR_REDIRECTEMPTY",
623112ed1c7cSGregory Neil Shapiro #endif /* _FFR_REDIRECTEMPTY */
623212ed1c7cSGregory Neil Shapiro #if _FFR_RESET_MACRO_GLOBALS
623372936242SGregory Neil Shapiro 	/* Allow macro 'j' to be set dynamically via rulesets. */
623412ed1c7cSGregory Neil Shapiro 	"_FFR_RESET_MACRO_GLOBALS",
623512ed1c7cSGregory Neil Shapiro #endif /* _FFR_RESET_MACRO_GLOBALS */
623612ed1c7cSGregory Neil Shapiro #if _FFR_RHS
623772936242SGregory Neil Shapiro 	/* Random shuffle for queue sorting. */
623812ed1c7cSGregory Neil Shapiro 	"_FFR_RHS",
623912ed1c7cSGregory Neil Shapiro #endif /* _FFR_RHS */
6240320f00e7SGregory Neil Shapiro #if _FFR_SELECT_SHM
624172936242SGregory Neil Shapiro 	/* Auto-select of shared memory key */
6242320f00e7SGregory Neil Shapiro 	"_FFR_SELECT_SHM",
6243320f00e7SGregory Neil Shapiro #endif /* _FFR_SELECT_SHM */
624412ed1c7cSGregory Neil Shapiro #if _FFR_SHM_STATUS
624572936242SGregory Neil Shapiro 	/* Donated code (unused). */
624612ed1c7cSGregory Neil Shapiro 	"_FFR_SHM_STATUS",
624712ed1c7cSGregory Neil Shapiro #endif /* _FFR_SHM_STATUS */
6248bfb62e91SGregory Neil Shapiro #if _FFR_SKIP_DOMAINS
6249bfb62e91SGregory Neil Shapiro 	/* process every N'th domain instead of every N'th message */
6250684b2a5fSGregory Neil Shapiro 	"_FFR_SKIP_DOMAINS",
6251bfb62e91SGregory Neil Shapiro #endif /* _FFR_SKIP_DOMAINS */
62527660b554SGregory Neil Shapiro #if _FFR_SLEEP_USE_SELECT
62537660b554SGregory Neil Shapiro 	/* Use select(2) in libsm/clock.c to emulate sleep(2) */
62547660b554SGregory Neil Shapiro 	"_FFR_SLEEP_USE_SELECT ",
62557660b554SGregory Neil Shapiro #endif /* _FFR_SLEEP_USE_SELECT */
625612ed1c7cSGregory Neil Shapiro #if _FFR_SOFT_BOUNCE
625772936242SGregory Neil Shapiro 	/* Turn all errors into temporary errors. */
625812ed1c7cSGregory Neil Shapiro 	"_FFR_SOFT_BOUNCE",
625912ed1c7cSGregory Neil Shapiro #endif /* _FFR_SOFT_BOUNCE */
626088ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN
626172936242SGregory Neil Shapiro 	/*
626272936242SGregory Neil Shapiro 	**  It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64
626372936242SGregory Neil Shapiro 	**  bit alignment, so unless each piece of argv and envp is a multiple
626472936242SGregory Neil Shapiro 	**  of 8 bytes (including terminating NULL), initsetproctitle() won't
626572936242SGregory Neil Shapiro 	**  use any of the space beyond argv[0]. Be sure to set SPT_ALIGN_SIZE
626672936242SGregory Neil Shapiro 	**  if you use this FFR.
626772936242SGregory Neil Shapiro 	*/
626872936242SGregory Neil Shapiro 
626988ad41d4SGregory Neil Shapiro /* Chris Adams of HiWAAY Informations Services */
627088ad41d4SGregory Neil Shapiro 	"_FFR_SPT_ALIGN",
627188ad41d4SGregory Neil Shapiro #endif /* _FFR_SPT_ALIGN */
6272188b7d28SGregory Neil Shapiro #if _FFR_SS_PER_DAEMON
6273188b7d28SGregory Neil Shapiro 	/* SuperSafe per DaemonPortOptions: 'T' (better letter?) */
6274188b7d28SGregory Neil Shapiro 	"_FFR_SS_PER_DAEMON",
6275188b7d28SGregory Neil Shapiro #endif /* _FFR_SS_PER_DAEMON */
627612ed1c7cSGregory Neil Shapiro #if _FFR_TIMERS
627772936242SGregory Neil Shapiro 	/* Donated code (unused). */
627812ed1c7cSGregory Neil Shapiro 	"_FFR_TIMERS",
627912ed1c7cSGregory Neil Shapiro #endif /* _FFR_TIMERS */
628012ed1c7cSGregory Neil Shapiro #if _FFR_TLS_1
628172936242SGregory Neil Shapiro 	/* More STARTTLS options, e.g., secondary certs. */
628212ed1c7cSGregory Neil Shapiro 	"_FFR_TLS_1",
628312ed1c7cSGregory Neil Shapiro #endif /* _FFR_TLS_1 */
628412ed1c7cSGregory Neil Shapiro #if _FFR_TRUSTED_QF
628572936242SGregory Neil Shapiro 	/*
628672936242SGregory Neil Shapiro 	**  If we don't own the file mark it as unsafe.
628772936242SGregory Neil Shapiro 	**  However, allow TrustedUser to own it as well
628872936242SGregory Neil Shapiro 	**  in case TrustedUser manipulates the queue.
628972936242SGregory Neil Shapiro 	*/
629072936242SGregory Neil Shapiro 
629112ed1c7cSGregory Neil Shapiro 	"_FFR_TRUSTED_QF",
629212ed1c7cSGregory Neil Shapiro #endif /* _FFR_TRUSTED_QF */
6293188b7d28SGregory Neil Shapiro #if _FFR_USE_SEM_LOCKING
6294188b7d28SGregory Neil Shapiro 	"_FFR_USE_SEM_LOCKING",
6295188b7d28SGregory Neil Shapiro #endif /* _FFR_USE_SEM_LOCKING */
6296320f00e7SGregory Neil Shapiro #if _FFR_USE_SETLOGIN
629772936242SGregory Neil Shapiro 	/* Use setlogin() */
6298320f00e7SGregory Neil Shapiro /* Peter Philipp */
6299320f00e7SGregory Neil Shapiro 	"_FFR_USE_SETLOGIN",
6300320f00e7SGregory Neil Shapiro #endif /* _FFR_USE_SETLOGIN */
6301c2aa98e2SPeter Wemm 	NULL
6302c2aa98e2SPeter Wemm };
63033299c2f1SGregory Neil Shapiro 
6304