xref: /freebsd/contrib/sendmail/src/conf.c (revision 12ed1c7c81a0777c53a89597f28b0ece402a6e0c)
1c2aa98e2SPeter Wemm /*
212ed1c7cSGregory Neil Shapiro  * Copyright (c) 1998-2002 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  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
1412ed1c7cSGregory Neil Shapiro #include <sendmail.h>
1512ed1c7cSGregory Neil Shapiro 
1612ed1c7cSGregory Neil Shapiro SM_RCSID("@(#)$Id: conf.c,v 8.939 2002/01/09 17:26:28 gshapiro Exp $")
17c2aa98e2SPeter Wemm 
183299c2f1SGregory Neil Shapiro /* $FreeBSD$ */
193299c2f1SGregory Neil Shapiro 
203299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
213299c2f1SGregory Neil Shapiro 
22c2aa98e2SPeter Wemm # include <sys/ioctl.h>
23c2aa98e2SPeter Wemm # include <sys/param.h>
243299c2f1SGregory Neil Shapiro 
25c2aa98e2SPeter Wemm #include <limits.h>
263299c2f1SGregory Neil Shapiro #if NETINET || NETINET6
273299c2f1SGregory Neil Shapiro # include <arpa/inet.h>
283299c2f1SGregory Neil Shapiro #endif /* NETINET || NETINET6 */
293299c2f1SGregory Neil Shapiro #if HASULIMIT && defined(HPUX11)
303299c2f1SGregory Neil Shapiro # include <ulimit.h>
313299c2f1SGregory Neil Shapiro #endif /* HASULIMIT && defined(HPUX11) */
323299c2f1SGregory Neil Shapiro 
333299c2f1SGregory Neil Shapiro 
343299c2f1SGregory Neil Shapiro static void	setupmaps __P((void));
353299c2f1SGregory Neil Shapiro static void	setupmailers __P((void));
3612ed1c7cSGregory Neil Shapiro static void	setupqueues __P((void));
373299c2f1SGregory Neil Shapiro static int	get_num_procs_online __P((void));
383299c2f1SGregory Neil Shapiro 
39c2aa98e2SPeter Wemm 
40c2aa98e2SPeter Wemm /*
41c2aa98e2SPeter Wemm **  CONF.C -- Sendmail Configuration Tables.
42c2aa98e2SPeter Wemm **
43c2aa98e2SPeter Wemm **	Defines the configuration of this installation.
44c2aa98e2SPeter Wemm **
45c2aa98e2SPeter Wemm **	Configuration Variables:
46c2aa98e2SPeter Wemm **		HdrInfo -- a table describing well-known header fields.
47c2aa98e2SPeter Wemm **			Each entry has the field name and some flags,
48c2aa98e2SPeter Wemm **			which are described in sendmail.h.
49c2aa98e2SPeter Wemm **
50c2aa98e2SPeter Wemm **	Notes:
51c2aa98e2SPeter Wemm **		I have tried to put almost all the reasonable
52c2aa98e2SPeter Wemm **		configuration information into the configuration
53c2aa98e2SPeter Wemm **		file read at runtime.  My intent is that anything
54c2aa98e2SPeter Wemm **		here is a function of the version of UNIX you
55c2aa98e2SPeter Wemm **		are running, or is really static -- for example
56c2aa98e2SPeter Wemm **		the headers are a superset of widely used
57c2aa98e2SPeter Wemm **		protocols.  If you find yourself playing with
58c2aa98e2SPeter Wemm **		this file too much, you may be making a mistake!
59c2aa98e2SPeter Wemm */
60c2aa98e2SPeter Wemm 
61c2aa98e2SPeter Wemm 
62c2aa98e2SPeter Wemm /*
63c2aa98e2SPeter Wemm **  Header info table
64c2aa98e2SPeter Wemm **	Final (null) entry contains the flags used for any other field.
65c2aa98e2SPeter Wemm **
66c2aa98e2SPeter Wemm **	Not all of these are actually handled specially by sendmail
67c2aa98e2SPeter Wemm **	at this time.  They are included as placeholders, to let
68c2aa98e2SPeter Wemm **	you know that "someday" I intend to have sendmail do
69c2aa98e2SPeter Wemm **	something with them.
70c2aa98e2SPeter Wemm */
71c2aa98e2SPeter Wemm 
72c2aa98e2SPeter Wemm struct hdrinfo	HdrInfo[] =
73c2aa98e2SPeter Wemm {
74c2aa98e2SPeter Wemm 		/* originator fields, most to least significant */
753299c2f1SGregory Neil Shapiro 	{ "resent-sender",		H_FROM|H_RESENT,	NULL	},
763299c2f1SGregory Neil Shapiro 	{ "resent-from",		H_FROM|H_RESENT,	NULL	},
773299c2f1SGregory Neil Shapiro 	{ "resent-reply-to",		H_FROM|H_RESENT,	NULL	},
783299c2f1SGregory Neil Shapiro 	{ "sender",			H_FROM,			NULL	},
793299c2f1SGregory Neil Shapiro 	{ "from",			H_FROM,			NULL	},
803299c2f1SGregory Neil Shapiro 	{ "reply-to",			H_FROM,			NULL	},
813299c2f1SGregory Neil Shapiro 	{ "errors-to",			H_FROM|H_ERRORSTO,	NULL	},
823299c2f1SGregory Neil Shapiro 	{ "full-name",			H_ACHECK,		NULL	},
833299c2f1SGregory Neil Shapiro 	{ "return-receipt-to",		H_RECEIPTTO,		NULL	},
8412ed1c7cSGregory Neil Shapiro 	{ "disposition-notification-to",	H_FROM,		NULL	},
85c2aa98e2SPeter Wemm 
86c2aa98e2SPeter Wemm 		/* destination fields */
873299c2f1SGregory Neil Shapiro 	{ "to",				H_RCPT,			NULL	},
883299c2f1SGregory Neil Shapiro 	{ "resent-to",			H_RCPT|H_RESENT,	NULL	},
893299c2f1SGregory Neil Shapiro 	{ "cc",				H_RCPT,			NULL	},
903299c2f1SGregory Neil Shapiro 	{ "resent-cc",			H_RCPT|H_RESENT,	NULL	},
913299c2f1SGregory Neil Shapiro 	{ "bcc",			H_RCPT|H_BCC,		NULL	},
923299c2f1SGregory Neil Shapiro 	{ "resent-bcc",			H_RCPT|H_BCC|H_RESENT,	NULL	},
933299c2f1SGregory Neil Shapiro 	{ "apparently-to",		H_RCPT,			NULL	},
94c2aa98e2SPeter Wemm 
95c2aa98e2SPeter Wemm 		/* message identification and control */
963299c2f1SGregory Neil Shapiro 	{ "message-id",			0,			NULL	},
973299c2f1SGregory Neil Shapiro 	{ "resent-message-id",		H_RESENT,		NULL	},
983299c2f1SGregory Neil Shapiro 	{ "message",			H_EOH,			NULL	},
993299c2f1SGregory Neil Shapiro 	{ "text",			H_EOH,			NULL	},
100c2aa98e2SPeter Wemm 
101c2aa98e2SPeter Wemm 		/* date fields */
1023299c2f1SGregory Neil Shapiro 	{ "date",			0,			NULL	},
1033299c2f1SGregory Neil Shapiro 	{ "resent-date",		H_RESENT,		NULL	},
104c2aa98e2SPeter Wemm 
105c2aa98e2SPeter Wemm 		/* trace fields */
1063299c2f1SGregory Neil Shapiro 	{ "received",			H_TRACE|H_FORCE,	NULL	},
1073299c2f1SGregory Neil Shapiro 	{ "x400-received",		H_TRACE|H_FORCE,	NULL	},
1083299c2f1SGregory Neil Shapiro 	{ "via",			H_TRACE|H_FORCE,	NULL	},
1093299c2f1SGregory Neil Shapiro 	{ "mail-from",			H_TRACE|H_FORCE,	NULL	},
110c2aa98e2SPeter Wemm 
111c2aa98e2SPeter Wemm 		/* miscellaneous fields */
1123299c2f1SGregory Neil Shapiro 	{ "comments",			H_FORCE|H_ENCODABLE,	NULL	},
1133299c2f1SGregory Neil Shapiro 	{ "return-path",		H_FORCE|H_ACHECK|H_BINDLATE,	NULL	},
1143299c2f1SGregory Neil Shapiro 	{ "content-transfer-encoding",	H_CTE,			NULL	},
1153299c2f1SGregory Neil Shapiro 	{ "content-type",		H_CTYPE,		NULL	},
1163299c2f1SGregory Neil Shapiro 	{ "content-length",		H_ACHECK,		NULL	},
1173299c2f1SGregory Neil Shapiro 	{ "subject",			H_ENCODABLE,		NULL	},
1183299c2f1SGregory Neil Shapiro 	{ "x-authentication-warning",	H_FORCE,		NULL	},
119c2aa98e2SPeter Wemm 
1203299c2f1SGregory Neil Shapiro 	{ NULL,				0,			NULL	}
121c2aa98e2SPeter Wemm };
122c2aa98e2SPeter Wemm 
123c2aa98e2SPeter Wemm 
124c2aa98e2SPeter Wemm 
125c2aa98e2SPeter Wemm /*
126c2aa98e2SPeter Wemm **  Privacy values
127c2aa98e2SPeter Wemm */
128c2aa98e2SPeter Wemm 
129c2aa98e2SPeter Wemm struct prival PrivacyValues[] =
130c2aa98e2SPeter Wemm {
131c2aa98e2SPeter Wemm 	{ "public",		PRIV_PUBLIC		},
132c2aa98e2SPeter Wemm 	{ "needmailhelo",	PRIV_NEEDMAILHELO	},
133c2aa98e2SPeter Wemm 	{ "needexpnhelo",	PRIV_NEEDEXPNHELO	},
134c2aa98e2SPeter Wemm 	{ "needvrfyhelo",	PRIV_NEEDVRFYHELO	},
135c2aa98e2SPeter Wemm 	{ "noexpn",		PRIV_NOEXPN		},
136c2aa98e2SPeter Wemm 	{ "novrfy",		PRIV_NOVRFY		},
13712ed1c7cSGregory Neil Shapiro 	{ "restrictexpand",	PRIV_RESTRICTEXPAND	},
138c2aa98e2SPeter Wemm 	{ "restrictmailq",	PRIV_RESTRICTMAILQ	},
139c2aa98e2SPeter Wemm 	{ "restrictqrun",	PRIV_RESTRICTQRUN	},
140c2aa98e2SPeter Wemm 	{ "noetrn",		PRIV_NOETRN		},
141c2aa98e2SPeter Wemm 	{ "noverb",		PRIV_NOVERB		},
142c2aa98e2SPeter Wemm 	{ "authwarnings",	PRIV_AUTHWARNINGS	},
143c2aa98e2SPeter Wemm 	{ "noreceipts",		PRIV_NORECEIPTS		},
1443299c2f1SGregory Neil Shapiro 	{ "nobodyreturn",	PRIV_NOBODYRETN		},
145c2aa98e2SPeter Wemm 	{ "goaway",		PRIV_GOAWAY		},
146c2aa98e2SPeter Wemm 	{ NULL,			0			}
147c2aa98e2SPeter Wemm };
148c2aa98e2SPeter Wemm 
149c2aa98e2SPeter Wemm /*
150c2aa98e2SPeter Wemm **  DontBlameSendmail values
151c2aa98e2SPeter Wemm */
15212ed1c7cSGregory Neil Shapiro 
153c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] =
154c2aa98e2SPeter Wemm {
155c2aa98e2SPeter Wemm 	{ "safe",			DBS_SAFE			},
156c2aa98e2SPeter Wemm 	{ "assumesafechown",		DBS_ASSUMESAFECHOWN		},
157c2aa98e2SPeter Wemm 	{ "groupwritabledirpathsafe",	DBS_GROUPWRITABLEDIRPATHSAFE	},
158c2aa98e2SPeter Wemm 	{ "groupwritableforwardfilesafe",
159c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEFORWARDFILESAFE },
160c2aa98e2SPeter Wemm 	{ "groupwritableincludefilesafe",
161c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEINCLUDEFILESAFE },
162c2aa98e2SPeter Wemm 	{ "groupwritablealiasfile",	DBS_GROUPWRITABLEALIASFILE	},
163c2aa98e2SPeter Wemm 	{ "worldwritablealiasfile",	DBS_WORLDWRITABLEALIASFILE	},
164c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpath",	DBS_FORWARDFILEINUNSAFEDIRPATH	},
165c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpath",	DBS_INCLUDEFILEINUNSAFEDIRPATH	},
166c2aa98e2SPeter Wemm 	{ "mapinunsafedirpath",		DBS_MAPINUNSAFEDIRPATH	},
167c2aa98e2SPeter Wemm 	{ "linkedaliasfileinwritabledir",
168c2aa98e2SPeter Wemm 					DBS_LINKEDALIASFILEINWRITABLEDIR },
169c2aa98e2SPeter Wemm 	{ "linkedclassfileinwritabledir",
170c2aa98e2SPeter Wemm 					DBS_LINKEDCLASSFILEINWRITABLEDIR },
171c2aa98e2SPeter Wemm 	{ "linkedforwardfileinwritabledir",
172c2aa98e2SPeter Wemm 					DBS_LINKEDFORWARDFILEINWRITABLEDIR },
173c2aa98e2SPeter Wemm 	{ "linkedincludefileinwritabledir",
174c2aa98e2SPeter Wemm 					DBS_LINKEDINCLUDEFILEINWRITABLEDIR },
175c2aa98e2SPeter Wemm 	{ "linkedmapinwritabledir",	DBS_LINKEDMAPINWRITABLEDIR	},
176c2aa98e2SPeter Wemm 	{ "linkedserviceswitchfileinwritabledir",
177c2aa98e2SPeter Wemm 					DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR },
178c2aa98e2SPeter Wemm 	{ "filedeliverytohardlink",	DBS_FILEDELIVERYTOHARDLINK	},
179c2aa98e2SPeter Wemm 	{ "filedeliverytosymlink",	DBS_FILEDELIVERYTOSYMLINK	},
180c2aa98e2SPeter Wemm 	{ "writemaptohardlink",		DBS_WRITEMAPTOHARDLINK		},
181c2aa98e2SPeter Wemm 	{ "writemaptosymlink",		DBS_WRITEMAPTOSYMLINK		},
182c2aa98e2SPeter Wemm 	{ "writestatstohardlink",	DBS_WRITESTATSTOHARDLINK	},
183c2aa98e2SPeter Wemm 	{ "writestatstosymlink",	DBS_WRITESTATSTOSYMLINK		},
184c2aa98e2SPeter Wemm 	{ "forwardfileingroupwritabledirpath",
185c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINGROUPWRITABLEDIRPATH },
186c2aa98e2SPeter Wemm 	{ "includefileingroupwritabledirpath",
187c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH },
188c2aa98e2SPeter Wemm 	{ "classfileinunsafedirpath",	DBS_CLASSFILEINUNSAFEDIRPATH	},
189c2aa98e2SPeter Wemm 	{ "errorheaderinunsafedirpath",	DBS_ERRORHEADERINUNSAFEDIRPATH	},
190c2aa98e2SPeter Wemm 	{ "helpfileinunsafedirpath",	DBS_HELPFILEINUNSAFEDIRPATH	},
191c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpathsafe",
192c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINUNSAFEDIRPATHSAFE },
193c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpathsafe",
194c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
195c2aa98e2SPeter Wemm 	{ "runprograminunsafedirpath",	DBS_RUNPROGRAMINUNSAFEDIRPATH	},
196c2aa98e2SPeter Wemm 	{ "runwritableprogram",		DBS_RUNWRITABLEPROGRAM		},
1973299c2f1SGregory Neil Shapiro 	{ "nonrootsafeaddr",		DBS_NONROOTSAFEADDR		},
1983299c2f1SGregory Neil Shapiro 	{ "truststickybit",		DBS_TRUSTSTICKYBIT		},
1993299c2f1SGregory Neil Shapiro 	{ "dontwarnforwardfileinunsafedirpath",
2003299c2f1SGregory Neil Shapiro 					DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH },
2013299c2f1SGregory Neil Shapiro 	{ "insufficiententropy",	DBS_INSUFFICIENTENTROPY },
20212ed1c7cSGregory Neil Shapiro 	{ "groupreadablesasldbfile",	DBS_GROUPREADABLESASLDBFILE	},
20312ed1c7cSGregory Neil Shapiro 	{ "groupwritablesasldbfile",	DBS_GROUPWRITABLESASLDBFILE	},
204d995d2baSGregory Neil Shapiro 	{ "groupwritableforwardfile",	DBS_GROUPWRITABLEFORWARDFILE	},
205d995d2baSGregory Neil Shapiro 	{ "groupwritableincludefile",	DBS_GROUPWRITABLEINCLUDEFILE	},
206d995d2baSGregory Neil Shapiro 	{ "worldwritableforwardfile",	DBS_WORLDWRITABLEFORWARDFILE	},
207d995d2baSGregory Neil Shapiro 	{ "worldwritableincludefile",	DBS_WORLDWRITABLEINCLUDEFILE	},
20812ed1c7cSGregory Neil Shapiro 	{ "groupreadablekeyfile",	DBS_GROUPREADABLEKEYFILE	},
20912ed1c7cSGregory Neil Shapiro #if _FFR_GROUPREADABLEAUTHINFOFILE
21012ed1c7cSGregory Neil Shapiro 	{ "groupreadableadefaultauthinfofile",
21112ed1c7cSGregory Neil Shapiro 					DBS_GROUPREADABLEAUTHINFOFILE	},
21212ed1c7cSGregory Neil Shapiro #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
213c2aa98e2SPeter Wemm 	{ NULL,				0				}
214c2aa98e2SPeter Wemm };
215c2aa98e2SPeter Wemm 
216c2aa98e2SPeter Wemm /*
217c2aa98e2SPeter Wemm **  Miscellaneous stuff.
218c2aa98e2SPeter Wemm */
219c2aa98e2SPeter Wemm 
220c2aa98e2SPeter Wemm int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
22112ed1c7cSGregory Neil Shapiro /*
222c2aa98e2SPeter Wemm **  SETDEFAULTS -- set default values
223c2aa98e2SPeter Wemm **
22412ed1c7cSGregory Neil Shapiro **	Some of these must be initialized using direct code since they
22512ed1c7cSGregory Neil Shapiro **	depend on run-time values. So let's do all of them this way.
226c2aa98e2SPeter Wemm **
227c2aa98e2SPeter Wemm **	Parameters:
228c2aa98e2SPeter Wemm **		e -- the default envelope.
229c2aa98e2SPeter Wemm **
230c2aa98e2SPeter Wemm **	Returns:
231c2aa98e2SPeter Wemm **		none.
232c2aa98e2SPeter Wemm **
233c2aa98e2SPeter Wemm **	Side Effects:
234c2aa98e2SPeter Wemm **		Initializes a bunch of global variables to their
235c2aa98e2SPeter Wemm **		default values.
236c2aa98e2SPeter Wemm */
237c2aa98e2SPeter Wemm 
238c2aa98e2SPeter Wemm #define MINUTES		* 60
239c2aa98e2SPeter Wemm #define HOURS		* 60 MINUTES
240c2aa98e2SPeter Wemm #define DAYS		* 24 HOURS
241c2aa98e2SPeter Wemm 
242c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION
243c2aa98e2SPeter Wemm # define MAXRULERECURSION	50	/* max ruleset recursion depth */
2443299c2f1SGregory Neil Shapiro #endif /* ! MAXRULERECURSION */
245c2aa98e2SPeter Wemm 
246c2aa98e2SPeter Wemm void
247c2aa98e2SPeter Wemm setdefaults(e)
248c2aa98e2SPeter Wemm 	register ENVELOPE *e;
249c2aa98e2SPeter Wemm {
250c2aa98e2SPeter Wemm 	int i;
2513299c2f1SGregory Neil Shapiro 	int numprocs;
252c2aa98e2SPeter Wemm 	struct passwd *pw;
253c2aa98e2SPeter Wemm 
2543299c2f1SGregory Neil Shapiro 	numprocs = get_num_procs_online();
255c2aa98e2SPeter Wemm 	SpaceSub = ' ';				/* option B */
2563299c2f1SGregory Neil Shapiro 	QueueLA = 8 * numprocs;			/* option x */
2573299c2f1SGregory Neil Shapiro 	RefuseLA = 12 * numprocs;		/* option X */
258c2aa98e2SPeter Wemm 	WkRecipFact = 30000L;			/* option y */
259c2aa98e2SPeter Wemm 	WkClassFact = 1800L;			/* option z */
260c2aa98e2SPeter Wemm 	WkTimeFact = 90000L;			/* option Z */
261c2aa98e2SPeter Wemm 	QueueFactor = WkRecipFact * 20;		/* option q */
26212ed1c7cSGregory Neil Shapiro #if _FFR_QUARANTINE
26312ed1c7cSGregory Neil Shapiro 	QueueMode = QM_NORMAL;		/* what queue items to act upon */
26412ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUARANTINE */
265c2aa98e2SPeter Wemm 	FileMode = (RealUid != geteuid()) ? 0644 : 0600;
266c2aa98e2SPeter Wemm 						/* option F */
2673299c2f1SGregory Neil Shapiro 	QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600;
2683299c2f1SGregory Neil Shapiro 						/* option QueueFileMode */
269c2aa98e2SPeter Wemm 
2703299c2f1SGregory Neil Shapiro 	if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) ||
2713299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) ||
2723299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0))
273c2aa98e2SPeter Wemm 	{
274c2aa98e2SPeter Wemm 		DefUid = pw->pw_uid;		/* option u */
275c2aa98e2SPeter Wemm 		DefGid = pw->pw_gid;		/* option g */
276c2aa98e2SPeter Wemm 		DefUser = newstr(pw->pw_name);
277c2aa98e2SPeter Wemm 	}
278c2aa98e2SPeter Wemm 	else
279c2aa98e2SPeter Wemm 	{
280c2aa98e2SPeter Wemm 		DefUid = 1;			/* option u */
281c2aa98e2SPeter Wemm 		DefGid = 1;			/* option g */
282c2aa98e2SPeter Wemm 		setdefuser();
283c2aa98e2SPeter Wemm 	}
28476b7bf71SPeter Wemm 	TrustedUid = 0;
285c2aa98e2SPeter Wemm 	if (tTd(37, 4))
28612ed1c7cSGregory Neil Shapiro 		sm_dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n",
287c2aa98e2SPeter Wemm 			DefUser != NULL ? DefUser : "<1:1>",
288c2aa98e2SPeter Wemm 			(int) DefUid, (int) DefGid);
289c2aa98e2SPeter Wemm 	CheckpointInterval = 10;		/* option C */
290c2aa98e2SPeter Wemm 	MaxHopCount = 25;			/* option h */
2913299c2f1SGregory Neil Shapiro 	set_delivery_mode(SM_FORK, e);		/* option d */
292c2aa98e2SPeter Wemm 	e->e_errormode = EM_PRINT;		/* option e */
29312ed1c7cSGregory Neil Shapiro 	e->e_qgrp = NOQGRP;
29412ed1c7cSGregory Neil Shapiro 	e->e_qdir = NOQDIR;
29512ed1c7cSGregory Neil Shapiro 	e->e_xfqgrp = NOQGRP;
29612ed1c7cSGregory Neil Shapiro 	e->e_xfqdir = NOQDIR;
2973299c2f1SGregory Neil Shapiro 	e->e_ctime = curtime();
29812ed1c7cSGregory Neil Shapiro 	SevenBitInput = false;			/* option 7 */
299c2aa98e2SPeter Wemm 	MaxMciCache = 1;			/* option k */
300c2aa98e2SPeter Wemm 	MciCacheTimeout = 5 MINUTES;		/* option K */
301c2aa98e2SPeter Wemm 	LogLevel = 9;				/* option L */
30212ed1c7cSGregory Neil Shapiro #if MILTER
30312ed1c7cSGregory Neil Shapiro 	MilterLogLevel = -1;
30412ed1c7cSGregory Neil Shapiro #endif /* MILTER */
30512ed1c7cSGregory Neil Shapiro 	inittimeouts(NULL, false);		/* option r */
306c2aa98e2SPeter Wemm 	PrivacyFlags = PRIV_PUBLIC;		/* option p */
30712ed1c7cSGregory Neil Shapiro 	MeToo = true;				/* option m */
30812ed1c7cSGregory Neil Shapiro 	SendMIMEErrors = true;			/* option f */
30912ed1c7cSGregory Neil Shapiro 	SuperSafe = SAFE_REALLY;		/* option s */
3103299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);		/* DontBlameSendmail option */
311c2aa98e2SPeter Wemm #if MIME8TO7
312c2aa98e2SPeter Wemm 	MimeMode = MM_CVTMIME|MM_PASS8BIT;	/* option 8 */
3133299c2f1SGregory Neil Shapiro #else /* MIME8TO7 */
314c2aa98e2SPeter Wemm 	MimeMode = MM_PASS8BIT;
3153299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
316c2aa98e2SPeter Wemm 	for (i = 0; i < MAXTOCLASS; i++)
317c2aa98e2SPeter Wemm 	{
318c2aa98e2SPeter Wemm 		TimeOuts.to_q_return[i] = 5 DAYS;	/* option T */
319c2aa98e2SPeter Wemm 		TimeOuts.to_q_warning[i] = 0;		/* option T */
320c2aa98e2SPeter Wemm 	}
3213299c2f1SGregory Neil Shapiro 	ServiceSwitchFile = "/etc/mail/service.switch";
322c2aa98e2SPeter Wemm 	ServiceCacheMaxAge = (time_t) 10;
323c2aa98e2SPeter Wemm 	HostsFile = _PATH_HOSTS;
324c2aa98e2SPeter Wemm 	PidFile = newstr(_PATH_SENDMAILPID);
325c2aa98e2SPeter Wemm 	MustQuoteChars = "@,;:\\()[].'";
326c2aa98e2SPeter Wemm 	MciInfoTimeout = 30 MINUTES;
327c2aa98e2SPeter Wemm 	MaxRuleRecursion = MAXRULERECURSION;
328c2aa98e2SPeter Wemm 	MaxAliasRecursion = 10;
329c2aa98e2SPeter Wemm 	MaxMacroRecursion = 10;
33012ed1c7cSGregory Neil Shapiro 	ColonOkInAddr = true;
33112ed1c7cSGregory Neil Shapiro 	DontLockReadFiles = true;
33212ed1c7cSGregory Neil Shapiro 	DontProbeInterfaces = DPI_PROBEALL;
333c2aa98e2SPeter Wemm 	DoubleBounceAddr = "postmaster";
334e01d6f61SPeter Wemm 	MaxHeadersLength = MAXHDRSLEN;
3353299c2f1SGregory Neil Shapiro 	MaxForwardEntries = 0;
33612ed1c7cSGregory Neil Shapiro 	FastSplit = 1;
3373299c2f1SGregory Neil Shapiro #if SASL
3383299c2f1SGregory Neil Shapiro 	AuthMechanisms = newstr(AUTH_MECHANISMS);
33912ed1c7cSGregory Neil Shapiro 	MaxSLBits = INT_MAX;
3403299c2f1SGregory Neil Shapiro #endif /* SASL */
34112ed1c7cSGregory Neil Shapiro #if STARTTLS
34212ed1c7cSGregory Neil Shapiro 	TLS_Srv_Opts = TLS_I_SRV;
34312ed1c7cSGregory Neil Shapiro #endif /* STARTTLS */
344c2aa98e2SPeter Wemm #ifdef HESIOD_INIT
345c2aa98e2SPeter Wemm 	HesiodContext = NULL;
3463299c2f1SGregory Neil Shapiro #endif /* HESIOD_INIT */
3473299c2f1SGregory Neil Shapiro #if NETINET6
3483299c2f1SGregory Neil Shapiro 	/* Detect if IPv6 is available at run time */
3493299c2f1SGregory Neil Shapiro 	i = socket(AF_INET6, SOCK_STREAM, 0);
3503299c2f1SGregory Neil Shapiro 	if (i >= 0)
3513299c2f1SGregory Neil Shapiro 	{
3523299c2f1SGregory Neil Shapiro 		InetMode = AF_INET6;
3533299c2f1SGregory Neil Shapiro 		(void) close(i);
3543299c2f1SGregory Neil Shapiro 	}
3553299c2f1SGregory Neil Shapiro 	else
3563299c2f1SGregory Neil Shapiro 		InetMode = AF_INET;
3573299c2f1SGregory Neil Shapiro #else /* NETINET6 */
3583299c2f1SGregory Neil Shapiro 	InetMode = AF_INET;
3593299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
36076b7bf71SPeter Wemm 	ControlSocketName = NULL;
3613299c2f1SGregory Neil Shapiro 	memset(&ConnectOnlyTo, '\0', sizeof ConnectOnlyTo);
3623299c2f1SGregory Neil Shapiro 	DataFileBufferSize = 4096;
3633299c2f1SGregory Neil Shapiro 	XscriptFileBufferSize = 4096;
3643299c2f1SGregory Neil Shapiro 	for (i = 0; i < MAXRWSETS; i++)
3653299c2f1SGregory Neil Shapiro 		RuleSetNames[i] = NULL;
36612ed1c7cSGregory Neil Shapiro #if MILTER
3673299c2f1SGregory Neil Shapiro 	InputFilters[0] = NULL;
36812ed1c7cSGregory Neil Shapiro #endif /* MILTER */
369c2aa98e2SPeter Wemm 	setupmaps();
37012ed1c7cSGregory Neil Shapiro 	setupqueues();
371c2aa98e2SPeter Wemm 	setupmailers();
372c2aa98e2SPeter Wemm 	setupheaders();
373c2aa98e2SPeter Wemm }
374c2aa98e2SPeter Wemm 
375c2aa98e2SPeter Wemm 
376c2aa98e2SPeter Wemm /*
377c2aa98e2SPeter Wemm **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
378c2aa98e2SPeter Wemm */
379c2aa98e2SPeter Wemm 
380c2aa98e2SPeter Wemm void
381c2aa98e2SPeter Wemm setdefuser()
382c2aa98e2SPeter Wemm {
383c2aa98e2SPeter Wemm 	struct passwd *defpwent;
384c2aa98e2SPeter Wemm 	static char defuserbuf[40];
385c2aa98e2SPeter Wemm 
386c2aa98e2SPeter Wemm 	DefUser = defuserbuf;
387c2aa98e2SPeter Wemm 	defpwent = sm_getpwuid(DefUid);
38812ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(defuserbuf,
38912ed1c7cSGregory Neil Shapiro 			  (defpwent == NULL || defpwent->pw_name == NULL)
39012ed1c7cSGregory Neil Shapiro 			   ? "nobody" : defpwent->pw_name,
39112ed1c7cSGregory Neil Shapiro 			  sizeof defuserbuf);
392c2aa98e2SPeter Wemm 	if (tTd(37, 4))
39312ed1c7cSGregory Neil Shapiro 		sm_dprintf("setdefuser: DefUid=%d, DefUser=%s\n",
394c2aa98e2SPeter Wemm 			   (int) DefUid, DefUser);
395c2aa98e2SPeter Wemm }
39612ed1c7cSGregory Neil Shapiro /*
39712ed1c7cSGregory Neil Shapiro **  SETUPQUEUES -- initialize default queues
39812ed1c7cSGregory Neil Shapiro **
39912ed1c7cSGregory Neil Shapiro **	The mqueue QUEUE structure gets filled in after readcf() but
40012ed1c7cSGregory Neil Shapiro **	we need something to point to now for the mailer setup,
40112ed1c7cSGregory Neil Shapiro **	which use "mqueue" as default queue.
40212ed1c7cSGregory Neil Shapiro */
40312ed1c7cSGregory Neil Shapiro 
40412ed1c7cSGregory Neil Shapiro static void
40512ed1c7cSGregory Neil Shapiro setupqueues()
40612ed1c7cSGregory Neil Shapiro {
40712ed1c7cSGregory Neil Shapiro 	char buf[100];
40812ed1c7cSGregory Neil Shapiro 
40912ed1c7cSGregory Neil Shapiro 	MaxRunnersPerQueue = 1;
41012ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof buf);
41112ed1c7cSGregory Neil Shapiro 	makequeue(buf, false);
41212ed1c7cSGregory Neil Shapiro }
41312ed1c7cSGregory Neil Shapiro /*
414c2aa98e2SPeter Wemm **  SETUPMAILERS -- initialize default mailers
415c2aa98e2SPeter Wemm */
416c2aa98e2SPeter Wemm 
4173299c2f1SGregory Neil Shapiro static void
418c2aa98e2SPeter Wemm setupmailers()
419c2aa98e2SPeter Wemm {
420c2aa98e2SPeter Wemm 	char buf[100];
421c2aa98e2SPeter Wemm 
42212ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u",
4233299c2f1SGregory Neil Shapiro 			sizeof buf);
424c2aa98e2SPeter Wemm 	makemailer(buf);
425c2aa98e2SPeter Wemm 
42612ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u",
4273299c2f1SGregory Neil Shapiro 			sizeof buf);
428c2aa98e2SPeter Wemm 	makemailer(buf);
429c2aa98e2SPeter Wemm 
43012ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u",
4313299c2f1SGregory Neil Shapiro 			sizeof buf);
432c2aa98e2SPeter Wemm 	makemailer(buf);
4333299c2f1SGregory Neil Shapiro 	initerrmailers();
434c2aa98e2SPeter Wemm }
43512ed1c7cSGregory Neil Shapiro /*
436c2aa98e2SPeter Wemm **  SETUPMAPS -- set up map classes
437c2aa98e2SPeter Wemm */
438c2aa98e2SPeter Wemm 
439c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
440c2aa98e2SPeter Wemm 	{ \
441c2aa98e2SPeter Wemm 		extern bool parse __P((MAP *, char *)); \
442c2aa98e2SPeter Wemm 		extern bool open __P((MAP *, int)); \
443c2aa98e2SPeter Wemm 		extern void close __P((MAP *)); \
444c2aa98e2SPeter Wemm 		extern char *lookup __P((MAP *, char *, char **, int *)); \
445c2aa98e2SPeter Wemm 		extern void store __P((MAP *, char *, char *)); \
446c2aa98e2SPeter Wemm 		s = stab(name, ST_MAPCLASS, ST_ENTER); \
447c2aa98e2SPeter Wemm 		s->s_mapclass.map_cname = name; \
448c2aa98e2SPeter Wemm 		s->s_mapclass.map_ext = ext; \
449c2aa98e2SPeter Wemm 		s->s_mapclass.map_cflags = flags; \
450c2aa98e2SPeter Wemm 		s->s_mapclass.map_parse = parse; \
451c2aa98e2SPeter Wemm 		s->s_mapclass.map_open = open; \
452c2aa98e2SPeter Wemm 		s->s_mapclass.map_close = close; \
453c2aa98e2SPeter Wemm 		s->s_mapclass.map_lookup = lookup; \
454c2aa98e2SPeter Wemm 		s->s_mapclass.map_store = store; \
455c2aa98e2SPeter Wemm 	}
456c2aa98e2SPeter Wemm 
4573299c2f1SGregory Neil Shapiro static void
458c2aa98e2SPeter Wemm setupmaps()
459c2aa98e2SPeter Wemm {
460c2aa98e2SPeter Wemm 	register STAB *s;
461c2aa98e2SPeter Wemm 
46212ed1c7cSGregory Neil Shapiro #if NEWDB
463c2aa98e2SPeter Wemm 	MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
464c2aa98e2SPeter Wemm 		map_parseargs, hash_map_open, db_map_close,
465c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
466c2aa98e2SPeter Wemm 
467c2aa98e2SPeter Wemm 	MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
468c2aa98e2SPeter Wemm 		map_parseargs, bt_map_open, db_map_close,
469c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
4703299c2f1SGregory Neil Shapiro #endif /* NEWDB */
471c2aa98e2SPeter Wemm 
47212ed1c7cSGregory Neil Shapiro #if NDBM
473c2aa98e2SPeter Wemm 	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
474c2aa98e2SPeter Wemm 		map_parseargs, ndbm_map_open, ndbm_map_close,
475c2aa98e2SPeter Wemm 		ndbm_map_lookup, ndbm_map_store);
4763299c2f1SGregory Neil Shapiro #endif /* NDBM */
477c2aa98e2SPeter Wemm 
47812ed1c7cSGregory Neil Shapiro #if NIS
479c2aa98e2SPeter Wemm 	MAPDEF("nis", NULL, MCF_ALIASOK,
480c2aa98e2SPeter Wemm 		map_parseargs, nis_map_open, null_map_close,
481c2aa98e2SPeter Wemm 		nis_map_lookup, null_map_store);
4823299c2f1SGregory Neil Shapiro #endif /* NIS */
483c2aa98e2SPeter Wemm 
48412ed1c7cSGregory Neil Shapiro #if NISPLUS
485c2aa98e2SPeter Wemm 	MAPDEF("nisplus", NULL, MCF_ALIASOK,
486c2aa98e2SPeter Wemm 		map_parseargs, nisplus_map_open, null_map_close,
487c2aa98e2SPeter Wemm 		nisplus_map_lookup, null_map_store);
4883299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
4893299c2f1SGregory Neil Shapiro 
49012ed1c7cSGregory Neil Shapiro #if LDAPMAP
49112ed1c7cSGregory Neil Shapiro 	MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST,
4923299c2f1SGregory Neil Shapiro 		ldapmap_parseargs, ldapmap_open, ldapmap_close,
4933299c2f1SGregory Neil Shapiro 		ldapmap_lookup, null_map_store);
4943299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
4953299c2f1SGregory Neil Shapiro 
49612ed1c7cSGregory Neil Shapiro #if PH_MAP
49712ed1c7cSGregory Neil Shapiro 	MAPDEF("ph", NULL, MCF_NOTPERSIST,
4983299c2f1SGregory Neil Shapiro 		ph_map_parseargs, ph_map_open, ph_map_close,
4993299c2f1SGregory Neil Shapiro 		ph_map_lookup, null_map_store);
5003299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
5013299c2f1SGregory Neil Shapiro 
5023299c2f1SGregory Neil Shapiro #if MAP_NSD
5033299c2f1SGregory Neil Shapiro 	/* IRIX 6.5 nsd support */
5043299c2f1SGregory Neil Shapiro 	MAPDEF("nsd", NULL, MCF_ALIASOK,
5053299c2f1SGregory Neil Shapiro 	       map_parseargs, null_map_open, null_map_close,
5063299c2f1SGregory Neil Shapiro 	       nsd_map_lookup, null_map_store);
5073299c2f1SGregory Neil Shapiro #endif /* MAP_NSD */
508c2aa98e2SPeter Wemm 
50912ed1c7cSGregory Neil Shapiro #if HESIOD
510c2aa98e2SPeter Wemm 	MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
51112ed1c7cSGregory Neil Shapiro 		map_parseargs, hes_map_open, hes_map_close,
512c2aa98e2SPeter Wemm 		hes_map_lookup, null_map_store);
5133299c2f1SGregory Neil Shapiro #endif /* HESIOD */
514c2aa98e2SPeter Wemm 
515c2aa98e2SPeter Wemm #if NETINFO
516c2aa98e2SPeter Wemm 	MAPDEF("netinfo", NULL, MCF_ALIASOK,
517c2aa98e2SPeter Wemm 		map_parseargs, ni_map_open, null_map_close,
518c2aa98e2SPeter Wemm 		ni_map_lookup, null_map_store);
5193299c2f1SGregory Neil Shapiro #endif /* NETINFO */
520c2aa98e2SPeter Wemm 
521c2aa98e2SPeter Wemm #if 0
522c2aa98e2SPeter Wemm 	MAPDEF("dns", NULL, 0,
523c2aa98e2SPeter Wemm 		dns_map_init, null_map_open, null_map_close,
524c2aa98e2SPeter Wemm 		dns_map_lookup, null_map_store);
5253299c2f1SGregory Neil Shapiro #endif /* 0 */
526c2aa98e2SPeter Wemm 
527c2aa98e2SPeter Wemm #if NAMED_BIND
52812ed1c7cSGregory Neil Shapiro # if DNSMAP
52912ed1c7cSGregory Neil Shapiro 	MAPDEF("dns", NULL, 0,
53012ed1c7cSGregory Neil Shapiro 	       dns_map_parseargs, dns_map_open, null_map_close,
53112ed1c7cSGregory Neil Shapiro 	       dns_map_lookup, null_map_store);
53212ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */
53312ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */
53412ed1c7cSGregory Neil Shapiro 
53512ed1c7cSGregory Neil Shapiro #if NAMED_BIND
536c2aa98e2SPeter Wemm 	/* best MX DNS lookup */
537c2aa98e2SPeter Wemm 	MAPDEF("bestmx", NULL, MCF_OPTFILE,
538c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
539c2aa98e2SPeter Wemm 		bestmx_map_lookup, null_map_store);
5403299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
541c2aa98e2SPeter Wemm 
542c2aa98e2SPeter Wemm 	MAPDEF("host", NULL, 0,
543c2aa98e2SPeter Wemm 		host_map_init, null_map_open, null_map_close,
544c2aa98e2SPeter Wemm 		host_map_lookup, null_map_store);
545c2aa98e2SPeter Wemm 
546c2aa98e2SPeter Wemm 	MAPDEF("text", NULL, MCF_ALIASOK,
547c2aa98e2SPeter Wemm 		map_parseargs, text_map_open, null_map_close,
548c2aa98e2SPeter Wemm 		text_map_lookup, null_map_store);
549c2aa98e2SPeter Wemm 
550c2aa98e2SPeter Wemm 	MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
551c2aa98e2SPeter Wemm 		map_parseargs, stab_map_open, null_map_close,
552c2aa98e2SPeter Wemm 		stab_map_lookup, stab_map_store);
553c2aa98e2SPeter Wemm 
554c2aa98e2SPeter Wemm 	MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
555c2aa98e2SPeter Wemm 		map_parseargs, impl_map_open, impl_map_close,
556c2aa98e2SPeter Wemm 		impl_map_lookup, impl_map_store);
557c2aa98e2SPeter Wemm 
558c2aa98e2SPeter Wemm 	/* access to system passwd file */
559c2aa98e2SPeter Wemm 	MAPDEF("user", NULL, MCF_OPTFILE,
560c2aa98e2SPeter Wemm 		map_parseargs, user_map_open, null_map_close,
561c2aa98e2SPeter Wemm 		user_map_lookup, null_map_store);
562c2aa98e2SPeter Wemm 
563c2aa98e2SPeter Wemm 	/* dequote map */
564c2aa98e2SPeter Wemm 	MAPDEF("dequote", NULL, 0,
565c2aa98e2SPeter Wemm 		dequote_init, null_map_open, null_map_close,
566c2aa98e2SPeter Wemm 		dequote_map, null_map_store);
567c2aa98e2SPeter Wemm 
56812ed1c7cSGregory Neil Shapiro #if MAP_REGEX
569c2aa98e2SPeter Wemm 	MAPDEF("regex", NULL, 0,
570c2aa98e2SPeter Wemm 		regex_map_init, null_map_open, null_map_close,
571c2aa98e2SPeter Wemm 		regex_map_lookup, null_map_store);
5723299c2f1SGregory Neil Shapiro #endif /* MAP_REGEX */
573c2aa98e2SPeter Wemm 
574c2aa98e2SPeter Wemm #if USERDB
575c2aa98e2SPeter Wemm 	/* user database */
576c2aa98e2SPeter Wemm 	MAPDEF("userdb", ".db", 0,
577c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
578c2aa98e2SPeter Wemm 		udb_map_lookup, null_map_store);
5793299c2f1SGregory Neil Shapiro #endif /* USERDB */
580c2aa98e2SPeter Wemm 
581c2aa98e2SPeter Wemm 	/* arbitrary programs */
582c2aa98e2SPeter Wemm 	MAPDEF("program", NULL, MCF_ALIASOK,
583c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
584c2aa98e2SPeter Wemm 		prog_map_lookup, null_map_store);
585c2aa98e2SPeter Wemm 
586c2aa98e2SPeter Wemm 	/* sequenced maps */
587c2aa98e2SPeter Wemm 	MAPDEF("sequence", NULL, MCF_ALIASOK,
588c2aa98e2SPeter Wemm 		seq_map_parse, null_map_open, null_map_close,
589c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
590c2aa98e2SPeter Wemm 
591c2aa98e2SPeter Wemm 	/* switched interface to sequenced maps */
592c2aa98e2SPeter Wemm 	MAPDEF("switch", NULL, MCF_ALIASOK,
593c2aa98e2SPeter Wemm 		map_parseargs, switch_map_open, null_map_close,
594c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
595c2aa98e2SPeter Wemm 
596c2aa98e2SPeter Wemm 	/* null map lookup -- really for internal use only */
597c2aa98e2SPeter Wemm 	MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
598c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
599c2aa98e2SPeter Wemm 		null_map_lookup, null_map_store);
600c2aa98e2SPeter Wemm 
601c2aa98e2SPeter Wemm 	/* syslog map -- logs information to syslog */
602c2aa98e2SPeter Wemm 	MAPDEF("syslog", NULL, 0,
603c2aa98e2SPeter Wemm 		syslog_map_parseargs, null_map_open, null_map_close,
604c2aa98e2SPeter Wemm 		syslog_map_lookup, null_map_store);
6053299c2f1SGregory Neil Shapiro 
6063299c2f1SGregory Neil Shapiro 	/* macro storage map -- rulesets can set macros */
6073299c2f1SGregory Neil Shapiro 	MAPDEF("macro", NULL, 0,
6083299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
6093299c2f1SGregory Neil Shapiro 		macro_map_lookup, null_map_store);
6103299c2f1SGregory Neil Shapiro 
6113299c2f1SGregory Neil Shapiro 	/* arithmetic map -- add/subtract/compare */
6123299c2f1SGregory Neil Shapiro 	MAPDEF("arith", NULL, 0,
6133299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
6143299c2f1SGregory Neil Shapiro 		arith_map_lookup, null_map_store);
6153299c2f1SGregory Neil Shapiro 
6163299c2f1SGregory Neil Shapiro 	if (tTd(38, 2))
6173299c2f1SGregory Neil Shapiro 	{
6183299c2f1SGregory Neil Shapiro 		/* bogus map -- always return tempfail */
6193299c2f1SGregory Neil Shapiro 		MAPDEF("bogus",	NULL, MCF_ALIASOK|MCF_OPTFILE,
6203299c2f1SGregory Neil Shapiro 		       map_parseargs, null_map_open, null_map_close,
6213299c2f1SGregory Neil Shapiro 		       bogus_map_lookup, null_map_store);
6223299c2f1SGregory Neil Shapiro 	}
623c2aa98e2SPeter Wemm }
624c2aa98e2SPeter Wemm 
625c2aa98e2SPeter Wemm #undef MAPDEF
62612ed1c7cSGregory Neil Shapiro /*
627c2aa98e2SPeter Wemm **  INITHOSTMAPS -- initial host-dependent maps
628c2aa98e2SPeter Wemm **
629c2aa98e2SPeter Wemm **	This should act as an interface to any local service switch
630c2aa98e2SPeter Wemm **	provided by the host operating system.
631c2aa98e2SPeter Wemm **
632c2aa98e2SPeter Wemm **	Parameters:
633c2aa98e2SPeter Wemm **		none
634c2aa98e2SPeter Wemm **
635c2aa98e2SPeter Wemm **	Returns:
636c2aa98e2SPeter Wemm **		none
637c2aa98e2SPeter Wemm **
638c2aa98e2SPeter Wemm **	Side Effects:
639c2aa98e2SPeter Wemm **		Should define maps "host" and "users" as necessary
640c2aa98e2SPeter Wemm **		for this OS.  If they are not defined, they will get
641c2aa98e2SPeter Wemm **		a default value later.  It should check to make sure
642c2aa98e2SPeter Wemm **		they are not defined first, since it's possible that
643c2aa98e2SPeter Wemm **		the config file has provided an override.
644c2aa98e2SPeter Wemm */
645c2aa98e2SPeter Wemm 
646c2aa98e2SPeter Wemm void
647c2aa98e2SPeter Wemm inithostmaps()
648c2aa98e2SPeter Wemm {
649c2aa98e2SPeter Wemm 	register int i;
650c2aa98e2SPeter Wemm 	int nmaps;
651c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
652c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
653c2aa98e2SPeter Wemm 	char buf[MAXLINE];
654c2aa98e2SPeter Wemm 
655c2aa98e2SPeter Wemm 	/*
656c2aa98e2SPeter Wemm 	**  Set up default hosts maps.
657c2aa98e2SPeter Wemm 	*/
658c2aa98e2SPeter Wemm 
659c2aa98e2SPeter Wemm #if 0
660c2aa98e2SPeter Wemm 	nmaps = switch_map_find("hosts", maptype, mapreturn);
661c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
662c2aa98e2SPeter Wemm 	{
663c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
664c2aa98e2SPeter Wemm 		    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
665c2aa98e2SPeter Wemm 		{
66612ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts",
6673299c2f1SGregory Neil Shapiro 				sizeof buf);
668c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
669c2aa98e2SPeter Wemm 		}
670c2aa98e2SPeter Wemm # if NAMED_BIND
671c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "dns") == 0 &&
672c2aa98e2SPeter Wemm 			 stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
673c2aa98e2SPeter Wemm 		{
67412ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.dns dns A", sizeof buf);
675c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
676c2aa98e2SPeter Wemm 		}
6773299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
67812ed1c7cSGregory Neil Shapiro # if NISPLUS
679c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
680c2aa98e2SPeter Wemm 			 stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
681c2aa98e2SPeter Wemm 		{
68212ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir",
6833299c2f1SGregory Neil Shapiro 				sizeof buf);
684c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
685c2aa98e2SPeter Wemm 		}
6863299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
68712ed1c7cSGregory Neil Shapiro # if NIS
688c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
689c2aa98e2SPeter Wemm 			 stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
690c2aa98e2SPeter Wemm 		{
69112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname",
6923299c2f1SGregory Neil Shapiro 				sizeof buf);
693c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
694c2aa98e2SPeter Wemm 		}
6953299c2f1SGregory Neil Shapiro # endif /* NIS */
696c2aa98e2SPeter Wemm # if NETINFO
69712ed1c7cSGregory Neil Shapiro 		else if (strcmp(maptype[i], "netinfo") == 0 &&
698c2aa98e2SPeter Wemm 			 stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
699c2aa98e2SPeter Wemm 		{
70012ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "hosts.netinfo netinfo -v name /machines",
7013299c2f1SGregory Neil Shapiro 				sizeof buf);
702c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
703c2aa98e2SPeter Wemm 		}
7043299c2f1SGregory Neil Shapiro # endif /* NETINFO */
705c2aa98e2SPeter Wemm 	}
7063299c2f1SGregory Neil Shapiro #endif /* 0 */
707c2aa98e2SPeter Wemm 
708c2aa98e2SPeter Wemm 	/*
709c2aa98e2SPeter Wemm 	**  Make sure we have a host map.
710c2aa98e2SPeter Wemm 	*/
711c2aa98e2SPeter Wemm 
712c2aa98e2SPeter Wemm 	if (stab("host", ST_MAP, ST_FIND) == NULL)
713c2aa98e2SPeter Wemm 	{
714c2aa98e2SPeter Wemm 		/* user didn't initialize: set up host map */
71512ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "host host", sizeof buf);
716c2aa98e2SPeter Wemm #if NAMED_BIND
717c2aa98e2SPeter Wemm 		if (ConfigLevel >= 2)
71812ed1c7cSGregory Neil Shapiro 			(void) sm_strlcat(buf, " -a. -D", sizeof buf);
7193299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
720c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
721c2aa98e2SPeter Wemm 	}
722c2aa98e2SPeter Wemm 
723c2aa98e2SPeter Wemm 	/*
724c2aa98e2SPeter Wemm 	**  Set up default aliases maps
725c2aa98e2SPeter Wemm 	*/
726c2aa98e2SPeter Wemm 
727c2aa98e2SPeter Wemm 	nmaps = switch_map_find("aliases", maptype, mapreturn);
728c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
729c2aa98e2SPeter Wemm 	{
730c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
731c2aa98e2SPeter Wemm 		    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
732c2aa98e2SPeter Wemm 		{
73312ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.files null",
73412ed1c7cSGregory Neil Shapiro 					  sizeof buf);
735c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
736c2aa98e2SPeter Wemm 		}
73712ed1c7cSGregory Neil Shapiro #if NISPLUS
738c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
739c2aa98e2SPeter Wemm 			 stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
740c2aa98e2SPeter Wemm 		{
74112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
7423299c2f1SGregory Neil Shapiro 				sizeof buf);
743c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
744c2aa98e2SPeter Wemm 		}
7453299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
74612ed1c7cSGregory Neil Shapiro #if NIS
747c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
748c2aa98e2SPeter Wemm 			 stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
749c2aa98e2SPeter Wemm 		{
75012ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nis nis mail.aliases",
7513299c2f1SGregory Neil Shapiro 				sizeof buf);
752c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
753c2aa98e2SPeter Wemm 		}
7543299c2f1SGregory Neil Shapiro #endif /* NIS */
7553299c2f1SGregory Neil Shapiro #if NETINFO
756c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "netinfo") == 0 &&
757c2aa98e2SPeter Wemm 			 stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
758c2aa98e2SPeter Wemm 		{
75912ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
7603299c2f1SGregory Neil Shapiro 				sizeof buf);
761c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
762c2aa98e2SPeter Wemm 		}
7633299c2f1SGregory Neil Shapiro #endif /* NETINFO */
76412ed1c7cSGregory Neil Shapiro #if HESIOD
765c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "hesiod") == 0 &&
766c2aa98e2SPeter Wemm 			 stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
767c2aa98e2SPeter Wemm 		{
76812ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases",
7693299c2f1SGregory Neil Shapiro 				sizeof buf);
770c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
771c2aa98e2SPeter Wemm 		}
7723299c2f1SGregory Neil Shapiro #endif /* HESIOD */
773c2aa98e2SPeter Wemm 	}
774c2aa98e2SPeter Wemm 	if (stab("aliases", ST_MAP, ST_FIND) == NULL)
775c2aa98e2SPeter Wemm 	{
77612ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "aliases switch aliases", sizeof buf);
777c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
778c2aa98e2SPeter Wemm 	}
779c2aa98e2SPeter Wemm 
780c2aa98e2SPeter Wemm #if 0		/* "user" map class is a better choice */
781c2aa98e2SPeter Wemm 	/*
782c2aa98e2SPeter Wemm 	**  Set up default users maps.
783c2aa98e2SPeter Wemm 	*/
784c2aa98e2SPeter Wemm 
785c2aa98e2SPeter Wemm 	nmaps = switch_map_find("passwd", maptype, mapreturn);
786c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
787c2aa98e2SPeter Wemm 	{
788c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
789c2aa98e2SPeter Wemm 		    stab("users.files", ST_MAP, ST_FIND) == NULL)
790c2aa98e2SPeter Wemm 		{
79112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd",
7923299c2f1SGregory Neil Shapiro 				sizeof buf);
793c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
794c2aa98e2SPeter Wemm 		}
79512ed1c7cSGregory Neil Shapiro # if NISPLUS
796c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
797c2aa98e2SPeter Wemm 		    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
798c2aa98e2SPeter Wemm 		{
79912ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir",
8003299c2f1SGregory Neil Shapiro 				sizeof buf);
801c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
802c2aa98e2SPeter Wemm 		}
8033299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
80412ed1c7cSGregory Neil Shapiro # if NIS
805c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
806c2aa98e2SPeter Wemm 		    stab("users.nis", ST_MAP, ST_FIND) == NULL)
807c2aa98e2SPeter Wemm 		{
80812ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.nis nis -m passwd.byname",
8093299c2f1SGregory Neil Shapiro 				sizeof buf);
810c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
811c2aa98e2SPeter Wemm 		}
8123299c2f1SGregory Neil Shapiro # endif /* NIS */
81312ed1c7cSGregory Neil Shapiro # if HESIOD
81412ed1c7cSGregory Neil Shapiro 		else if (strcmp(maptype[i], "hesiod") == 0 &&
815c2aa98e2SPeter Wemm 			 stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
816c2aa98e2SPeter Wemm 		{
81712ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "users.hesiod hesiod", sizeof buf);
818c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
819c2aa98e2SPeter Wemm 		}
8203299c2f1SGregory Neil Shapiro # endif /* HESIOD */
821c2aa98e2SPeter Wemm 	}
822c2aa98e2SPeter Wemm 	if (stab("users", ST_MAP, ST_FIND) == NULL)
823c2aa98e2SPeter Wemm 	{
82412ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(buf, "users switch -m passwd", sizeof buf);
825c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
826c2aa98e2SPeter Wemm 	}
8273299c2f1SGregory Neil Shapiro #endif /* 0 */
828c2aa98e2SPeter Wemm }
82912ed1c7cSGregory Neil Shapiro /*
830c2aa98e2SPeter Wemm **  SWITCH_MAP_FIND -- find the list of types associated with a map
831c2aa98e2SPeter Wemm **
832c2aa98e2SPeter Wemm **	This is the system-dependent interface to the service switch.
833c2aa98e2SPeter Wemm **
834c2aa98e2SPeter Wemm **	Parameters:
835c2aa98e2SPeter Wemm **		service -- the name of the service of interest.
836c2aa98e2SPeter Wemm **		maptype -- an out-array of strings containing the types
837c2aa98e2SPeter Wemm **			of access to use for this service.  There can
838c2aa98e2SPeter Wemm **			be at most MAXMAPSTACK types for a single service.
839c2aa98e2SPeter Wemm **		mapreturn -- an out-array of return information bitmaps
840c2aa98e2SPeter Wemm **			for the map.
841c2aa98e2SPeter Wemm **
842c2aa98e2SPeter Wemm **	Returns:
843c2aa98e2SPeter Wemm **		The number of map types filled in, or -1 for failure.
8443299c2f1SGregory Neil Shapiro **
8453299c2f1SGregory Neil Shapiro **	Side effects:
8463299c2f1SGregory Neil Shapiro **		Preserves errno so nothing in the routine clobbers it.
847c2aa98e2SPeter Wemm */
848c2aa98e2SPeter Wemm 
849c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
850c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_
8513299c2f1SGregory Neil Shapiro #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
852c2aa98e2SPeter Wemm 
85312ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
85412ed1c7cSGregory Neil Shapiro # ifdef __hpux
85512ed1c7cSGregory Neil Shapiro #  define _USE_SUN_NSSWITCH_
85612ed1c7cSGregory Neil Shapiro # endif /* __hpux */
85712ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */
85812ed1c7cSGregory Neil Shapiro 
859c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
860c2aa98e2SPeter Wemm # include <nsswitch.h>
8613299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
862c2aa98e2SPeter Wemm 
863c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
864c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_
8653299c2f1SGregory Neil Shapiro #endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
866c2aa98e2SPeter Wemm 
867c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
868c2aa98e2SPeter Wemm # include <sys/svcinfo.h>
8693299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
870c2aa98e2SPeter Wemm 
871c2aa98e2SPeter Wemm int
872c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn)
873c2aa98e2SPeter Wemm 	char *service;
874c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
875c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
876c2aa98e2SPeter Wemm {
877c46d91b7SGregory Neil Shapiro 	int svcno = 0;
8783299c2f1SGregory Neil Shapiro 	int save_errno = errno;
879c2aa98e2SPeter Wemm 
880c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
881c2aa98e2SPeter Wemm 	struct __nsw_switchconfig *nsw_conf;
882c2aa98e2SPeter Wemm 	enum __nsw_parse_err pserr;
883c2aa98e2SPeter Wemm 	struct __nsw_lookup *lk;
884c2aa98e2SPeter Wemm 	static struct __nsw_lookup lkp0 =
885c2aa98e2SPeter Wemm 		{ "files", {1, 0, 0, 0}, NULL, NULL };
886c2aa98e2SPeter Wemm 	static struct __nsw_switchconfig lkp_default =
887c2aa98e2SPeter Wemm 		{ 0, "sendmail", 3, &lkp0 };
888c2aa98e2SPeter Wemm 
889c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
890c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
891c2aa98e2SPeter Wemm 
892c2aa98e2SPeter Wemm 	if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
893c2aa98e2SPeter Wemm 		lk = lkp_default.lookups;
894c2aa98e2SPeter Wemm 	else
895c2aa98e2SPeter Wemm 		lk = nsw_conf->lookups;
896c2aa98e2SPeter Wemm 	svcno = 0;
897c46d91b7SGregory Neil Shapiro 	while (lk != NULL && svcno < MAXMAPSTACK)
898c2aa98e2SPeter Wemm 	{
899c2aa98e2SPeter Wemm 		maptype[svcno] = lk->service_name;
900c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
901c2aa98e2SPeter Wemm 			mapreturn[MA_NOTFOUND] |= 1 << svcno;
902c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
903c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
904c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
905c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
906c2aa98e2SPeter Wemm 		svcno++;
907c2aa98e2SPeter Wemm 		lk = lk->next;
908c2aa98e2SPeter Wemm 	}
9093299c2f1SGregory Neil Shapiro 	errno = save_errno;
910c2aa98e2SPeter Wemm 	return svcno;
9113299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
912c2aa98e2SPeter Wemm 
913c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
914c2aa98e2SPeter Wemm 	struct svcinfo *svcinfo;
915c2aa98e2SPeter Wemm 	int svc;
916c2aa98e2SPeter Wemm 
917c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
918c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
919c2aa98e2SPeter Wemm 
920c2aa98e2SPeter Wemm 	svcinfo = getsvc();
921c2aa98e2SPeter Wemm 	if (svcinfo == NULL)
922c2aa98e2SPeter Wemm 		goto punt;
923c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
924c2aa98e2SPeter Wemm 		svc = SVC_HOSTS;
925c2aa98e2SPeter Wemm 	else if (strcmp(service, "aliases") == 0)
926c2aa98e2SPeter Wemm 		svc = SVC_ALIASES;
927c2aa98e2SPeter Wemm 	else if (strcmp(service, "passwd") == 0)
928c2aa98e2SPeter Wemm 		svc = SVC_PASSWD;
929c2aa98e2SPeter Wemm 	else
9303299c2f1SGregory Neil Shapiro 	{
9313299c2f1SGregory Neil Shapiro 		errno = save_errno;
932c2aa98e2SPeter Wemm 		return -1;
9333299c2f1SGregory Neil Shapiro 	}
934c46d91b7SGregory Neil Shapiro 	for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++)
935c2aa98e2SPeter Wemm 	{
936c2aa98e2SPeter Wemm 		switch (svcinfo->svcpath[svc][svcno])
937c2aa98e2SPeter Wemm 		{
938c2aa98e2SPeter Wemm 		  case SVC_LOCAL:
939c2aa98e2SPeter Wemm 			maptype[svcno] = "files";
940c2aa98e2SPeter Wemm 			break;
941c2aa98e2SPeter Wemm 
942c2aa98e2SPeter Wemm 		  case SVC_YP:
943c2aa98e2SPeter Wemm 			maptype[svcno] = "nis";
944c2aa98e2SPeter Wemm 			break;
945c2aa98e2SPeter Wemm 
946c2aa98e2SPeter Wemm 		  case SVC_BIND:
947c2aa98e2SPeter Wemm 			maptype[svcno] = "dns";
948c2aa98e2SPeter Wemm 			break;
949c2aa98e2SPeter Wemm 
950c2aa98e2SPeter Wemm # ifdef SVC_HESIOD
951c2aa98e2SPeter Wemm 		  case SVC_HESIOD:
952c2aa98e2SPeter Wemm 			maptype[svcno] = "hesiod";
953c2aa98e2SPeter Wemm 			break;
9543299c2f1SGregory Neil Shapiro # endif /* SVC_HESIOD */
955c2aa98e2SPeter Wemm 
956c2aa98e2SPeter Wemm 		  case SVC_LAST:
9573299c2f1SGregory Neil Shapiro 			errno = save_errno;
958c2aa98e2SPeter Wemm 			return svcno;
959c2aa98e2SPeter Wemm 		}
960c2aa98e2SPeter Wemm 	}
9613299c2f1SGregory Neil Shapiro 	errno = save_errno;
962c2aa98e2SPeter Wemm 	return svcno;
9633299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
964c2aa98e2SPeter Wemm 
965c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
966c2aa98e2SPeter Wemm 	/*
967c2aa98e2SPeter Wemm 	**  Fall-back mechanism.
968c2aa98e2SPeter Wemm 	*/
969c2aa98e2SPeter Wemm 
970c2aa98e2SPeter Wemm 	STAB *st;
97112ed1c7cSGregory Neil Shapiro 	static time_t servicecachetime;	/* time service switch was cached */
972c2aa98e2SPeter Wemm 	time_t now = curtime();
973c2aa98e2SPeter Wemm 
974c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
975c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
976c2aa98e2SPeter Wemm 
97712ed1c7cSGregory Neil Shapiro 	if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge)
978c2aa98e2SPeter Wemm 	{
979c2aa98e2SPeter Wemm 		/* (re)read service switch */
98012ed1c7cSGregory Neil Shapiro 		register SM_FILE_T *fp;
9813299c2f1SGregory Neil Shapiro 		long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
982c2aa98e2SPeter Wemm 
9833299c2f1SGregory Neil Shapiro 		if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
9843299c2f1SGregory Neil Shapiro 			    DontBlameSendmail))
985c2aa98e2SPeter Wemm 			sff |= SFF_NOWLINK;
986c2aa98e2SPeter Wemm 
987c2aa98e2SPeter Wemm 		if (ConfigFileRead)
98812ed1c7cSGregory Neil Shapiro 			servicecachetime = now;
989c2aa98e2SPeter Wemm 		fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
990c2aa98e2SPeter Wemm 		if (fp != NULL)
991c2aa98e2SPeter Wemm 		{
992c2aa98e2SPeter Wemm 			char buf[MAXLINE];
993c2aa98e2SPeter Wemm 
99412ed1c7cSGregory Neil Shapiro 			while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf,
99512ed1c7cSGregory Neil Shapiro 					   sizeof buf) != NULL)
996c2aa98e2SPeter Wemm 			{
997c2aa98e2SPeter Wemm 				register char *p;
998c2aa98e2SPeter Wemm 
999c2aa98e2SPeter Wemm 				p = strpbrk(buf, "#\n");
1000c2aa98e2SPeter Wemm 				if (p != NULL)
1001c2aa98e2SPeter Wemm 					*p = '\0';
1002c2aa98e2SPeter Wemm 				p = strpbrk(buf, " \t");
1003c2aa98e2SPeter Wemm 				if (p != NULL)
1004c2aa98e2SPeter Wemm 					*p++ = '\0';
1005c2aa98e2SPeter Wemm 				if (buf[0] == '\0')
1006c2aa98e2SPeter Wemm 					continue;
100776b7bf71SPeter Wemm 				if (p == NULL)
100876b7bf71SPeter Wemm 				{
100976b7bf71SPeter Wemm 					sm_syslog(LOG_ERR, NOQID,
101076b7bf71SPeter Wemm 						  "Bad line on %.100s: %.100s",
101176b7bf71SPeter Wemm 						  ServiceSwitchFile,
101276b7bf71SPeter Wemm 						  buf);
101376b7bf71SPeter Wemm 					continue;
101476b7bf71SPeter Wemm 				}
1015c2aa98e2SPeter Wemm 				while (isspace(*p))
1016c2aa98e2SPeter Wemm 					p++;
1017c2aa98e2SPeter Wemm 				if (*p == '\0')
1018c2aa98e2SPeter Wemm 					continue;
1019c2aa98e2SPeter Wemm 
1020c2aa98e2SPeter Wemm 				/*
1021c2aa98e2SPeter Wemm 				**  Find/allocate space for this service entry.
1022c2aa98e2SPeter Wemm 				**	Space for all of the service strings
1023c2aa98e2SPeter Wemm 				**	are allocated at once.  This means
1024c2aa98e2SPeter Wemm 				**	that we only have to free the first
1025c2aa98e2SPeter Wemm 				**	one to free all of them.
1026c2aa98e2SPeter Wemm 				*/
1027c2aa98e2SPeter Wemm 
1028c2aa98e2SPeter Wemm 				st = stab(buf, ST_SERVICE, ST_ENTER);
1029c2aa98e2SPeter Wemm 				if (st->s_service[0] != NULL)
103012ed1c7cSGregory Neil Shapiro 					sm_free((void *) st->s_service[0]); /* XXX */
1031c2aa98e2SPeter Wemm 				p = newstr(p);
1032c2aa98e2SPeter Wemm 				for (svcno = 0; svcno < MAXMAPSTACK; )
1033c2aa98e2SPeter Wemm 				{
1034c2aa98e2SPeter Wemm 					if (*p == '\0')
1035c2aa98e2SPeter Wemm 						break;
1036c2aa98e2SPeter Wemm 					st->s_service[svcno++] = p;
1037c2aa98e2SPeter Wemm 					p = strpbrk(p, " \t");
1038c2aa98e2SPeter Wemm 					if (p == NULL)
1039c2aa98e2SPeter Wemm 						break;
1040c2aa98e2SPeter Wemm 					*p++ = '\0';
1041c2aa98e2SPeter Wemm 					while (isspace(*p))
1042c2aa98e2SPeter Wemm 						p++;
1043c2aa98e2SPeter Wemm 				}
1044c2aa98e2SPeter Wemm 				if (svcno < MAXMAPSTACK)
1045c2aa98e2SPeter Wemm 					st->s_service[svcno] = NULL;
1046c2aa98e2SPeter Wemm 			}
104712ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(fp, SM_TIME_DEFAULT);
1048c2aa98e2SPeter Wemm 		}
1049c2aa98e2SPeter Wemm 	}
1050c2aa98e2SPeter Wemm 
1051c2aa98e2SPeter Wemm 	/* look up entry in cache */
1052c2aa98e2SPeter Wemm 	st = stab(service, ST_SERVICE, ST_FIND);
1053c2aa98e2SPeter Wemm 	if (st != NULL && st->s_service[0] != NULL)
1054c2aa98e2SPeter Wemm 	{
1055c2aa98e2SPeter Wemm 		/* extract data */
1056c2aa98e2SPeter Wemm 		svcno = 0;
1057c2aa98e2SPeter Wemm 		while (svcno < MAXMAPSTACK)
1058c2aa98e2SPeter Wemm 		{
1059c2aa98e2SPeter Wemm 			maptype[svcno] = st->s_service[svcno];
1060c2aa98e2SPeter Wemm 			if (maptype[svcno++] == NULL)
1061c2aa98e2SPeter Wemm 				break;
1062c2aa98e2SPeter Wemm 		}
10633299c2f1SGregory Neil Shapiro 		errno = save_errno;
1064c2aa98e2SPeter Wemm 		return --svcno;
1065c2aa98e2SPeter Wemm 	}
10663299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
1067c2aa98e2SPeter Wemm 
1068c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_)
1069c2aa98e2SPeter Wemm 	/* if the service file doesn't work, use an absolute fallback */
1070c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_
1071c2aa98e2SPeter Wemm   punt:
10723299c2f1SGregory Neil Shapiro # endif /* _USE_DEC_SVC_CONF_ */
1073c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1074c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1075c2aa98e2SPeter Wemm 	svcno = 0;
1076c2aa98e2SPeter Wemm 	if (strcmp(service, "aliases") == 0)
1077c2aa98e2SPeter Wemm 	{
1078c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
10793299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
10803299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
10813299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
1082c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES
108312ed1c7cSGregory Neil Shapiro #  if NISPLUS
1084c2aa98e2SPeter Wemm 		maptype[svcno++] = "nisplus";
10853299c2f1SGregory Neil Shapiro #  endif /* NISPLUS */
108612ed1c7cSGregory Neil Shapiro #  if NIS
1087c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
10883299c2f1SGregory Neil Shapiro #  endif /* NIS */
10893299c2f1SGregory Neil Shapiro # endif /* AUTO_NIS_ALIASES */
10903299c2f1SGregory Neil Shapiro 		errno = save_errno;
1091c2aa98e2SPeter Wemm 		return svcno;
1092c2aa98e2SPeter Wemm 	}
1093c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
1094c2aa98e2SPeter Wemm 	{
1095c2aa98e2SPeter Wemm # if NAMED_BIND
1096c2aa98e2SPeter Wemm 		maptype[svcno++] = "dns";
10973299c2f1SGregory Neil Shapiro # else /* NAMED_BIND */
1098c2aa98e2SPeter Wemm #  if defined(sun) && !defined(BSD)
1099c2aa98e2SPeter Wemm 		/* SunOS */
1100c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
11013299c2f1SGregory Neil Shapiro #  endif /* defined(sun) && !defined(BSD) */
11023299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
11033299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
11043299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
11053299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */
1106c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
11073299c2f1SGregory Neil Shapiro 		errno = save_errno;
1108c2aa98e2SPeter Wemm 		return svcno;
1109c2aa98e2SPeter Wemm 	}
11103299c2f1SGregory Neil Shapiro 	errno = save_errno;
1111c2aa98e2SPeter Wemm 	return -1;
11123299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) */
1113c2aa98e2SPeter Wemm }
111412ed1c7cSGregory Neil Shapiro /*
1115c2aa98e2SPeter Wemm **  USERNAME -- return the user id of the logged in user.
1116c2aa98e2SPeter Wemm **
1117c2aa98e2SPeter Wemm **	Parameters:
1118c2aa98e2SPeter Wemm **		none.
1119c2aa98e2SPeter Wemm **
1120c2aa98e2SPeter Wemm **	Returns:
1121c2aa98e2SPeter Wemm **		The login name of the logged in user.
1122c2aa98e2SPeter Wemm **
1123c2aa98e2SPeter Wemm **	Side Effects:
1124c2aa98e2SPeter Wemm **		none.
1125c2aa98e2SPeter Wemm **
1126c2aa98e2SPeter Wemm **	Notes:
1127c2aa98e2SPeter Wemm **		The return value is statically allocated.
1128c2aa98e2SPeter Wemm */
1129c2aa98e2SPeter Wemm 
1130c2aa98e2SPeter Wemm char *
1131c2aa98e2SPeter Wemm username()
1132c2aa98e2SPeter Wemm {
1133c2aa98e2SPeter Wemm 	static char *myname = NULL;
1134c2aa98e2SPeter Wemm 	extern char *getlogin();
1135c2aa98e2SPeter Wemm 	register struct passwd *pw;
1136c2aa98e2SPeter Wemm 
1137c2aa98e2SPeter Wemm 	/* cache the result */
1138c2aa98e2SPeter Wemm 	if (myname == NULL)
1139c2aa98e2SPeter Wemm 	{
1140c2aa98e2SPeter Wemm 		myname = getlogin();
1141c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1142c2aa98e2SPeter Wemm 		{
1143c2aa98e2SPeter Wemm 			pw = sm_getpwuid(RealUid);
1144c2aa98e2SPeter Wemm 			if (pw != NULL)
114512ed1c7cSGregory Neil Shapiro 				myname = pw->pw_name;
1146c2aa98e2SPeter Wemm 		}
1147c2aa98e2SPeter Wemm 		else
1148c2aa98e2SPeter Wemm 		{
1149c2aa98e2SPeter Wemm 			uid_t uid = RealUid;
1150c2aa98e2SPeter Wemm 
1151c2aa98e2SPeter Wemm 			if ((pw = sm_getpwnam(myname)) == NULL ||
1152c2aa98e2SPeter Wemm 			      (uid != 0 && uid != pw->pw_uid))
1153c2aa98e2SPeter Wemm 			{
1154c2aa98e2SPeter Wemm 				pw = sm_getpwuid(uid);
1155c2aa98e2SPeter Wemm 				if (pw != NULL)
115612ed1c7cSGregory Neil Shapiro 					myname = pw->pw_name;
1157c2aa98e2SPeter Wemm 			}
1158c2aa98e2SPeter Wemm 		}
1159c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1160c2aa98e2SPeter Wemm 		{
11613299c2f1SGregory Neil Shapiro 			syserr("554 5.3.0 Who are you?");
1162c2aa98e2SPeter Wemm 			myname = "postmaster";
1163c2aa98e2SPeter Wemm 		}
116412ed1c7cSGregory Neil Shapiro 		else if (strpbrk(myname, ",;:/|\"\\") != NULL)
116512ed1c7cSGregory Neil Shapiro 			myname = addquotes(myname, NULL);
116612ed1c7cSGregory Neil Shapiro 		else
116712ed1c7cSGregory Neil Shapiro 			myname = sm_pstrdup_x(myname);
1168c2aa98e2SPeter Wemm 	}
11693299c2f1SGregory Neil Shapiro 	return myname;
1170c2aa98e2SPeter Wemm }
117112ed1c7cSGregory Neil Shapiro /*
1172c2aa98e2SPeter Wemm **  TTYPATH -- Get the path of the user's tty
1173c2aa98e2SPeter Wemm **
1174c2aa98e2SPeter Wemm **	Returns the pathname of the user's tty.  Returns NULL if
1175c2aa98e2SPeter Wemm **	the user is not logged in or if s/he has write permission
1176c2aa98e2SPeter Wemm **	denied.
1177c2aa98e2SPeter Wemm **
1178c2aa98e2SPeter Wemm **	Parameters:
1179c2aa98e2SPeter Wemm **		none
1180c2aa98e2SPeter Wemm **
1181c2aa98e2SPeter Wemm **	Returns:
1182c2aa98e2SPeter Wemm **		pathname of the user's tty.
1183c2aa98e2SPeter Wemm **		NULL if not logged in or write permission denied.
1184c2aa98e2SPeter Wemm **
1185c2aa98e2SPeter Wemm **	Side Effects:
1186c2aa98e2SPeter Wemm **		none.
1187c2aa98e2SPeter Wemm **
1188c2aa98e2SPeter Wemm **	WARNING:
1189c2aa98e2SPeter Wemm **		Return value is in a local buffer.
1190c2aa98e2SPeter Wemm **
1191c2aa98e2SPeter Wemm **	Called By:
1192c2aa98e2SPeter Wemm **		savemail
1193c2aa98e2SPeter Wemm */
1194c2aa98e2SPeter Wemm 
1195c2aa98e2SPeter Wemm char *
1196c2aa98e2SPeter Wemm ttypath()
1197c2aa98e2SPeter Wemm {
1198c2aa98e2SPeter Wemm 	struct stat stbuf;
1199c2aa98e2SPeter Wemm 	register char *pathn;
1200c2aa98e2SPeter Wemm 	extern char *ttyname();
1201c2aa98e2SPeter Wemm 	extern char *getlogin();
1202c2aa98e2SPeter Wemm 
1203c2aa98e2SPeter Wemm 	/* compute the pathname of the controlling tty */
1204c2aa98e2SPeter Wemm 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
1205c2aa98e2SPeter Wemm 	    (pathn = ttyname(0)) == NULL)
1206c2aa98e2SPeter Wemm 	{
1207c2aa98e2SPeter Wemm 		errno = 0;
12083299c2f1SGregory Neil Shapiro 		return NULL;
1209c2aa98e2SPeter Wemm 	}
1210c2aa98e2SPeter Wemm 
1211c2aa98e2SPeter Wemm 	/* see if we have write permission */
1212c2aa98e2SPeter Wemm 	if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode))
1213c2aa98e2SPeter Wemm 	{
1214c2aa98e2SPeter Wemm 		errno = 0;
12153299c2f1SGregory Neil Shapiro 		return NULL;
1216c2aa98e2SPeter Wemm 	}
1217c2aa98e2SPeter Wemm 
1218c2aa98e2SPeter Wemm 	/* see if the user is logged in */
1219c2aa98e2SPeter Wemm 	if (getlogin() == NULL)
12203299c2f1SGregory Neil Shapiro 		return NULL;
1221c2aa98e2SPeter Wemm 
1222c2aa98e2SPeter Wemm 	/* looks good */
12233299c2f1SGregory Neil Shapiro 	return pathn;
1224c2aa98e2SPeter Wemm }
122512ed1c7cSGregory Neil Shapiro /*
1226c2aa98e2SPeter Wemm **  CHECKCOMPAT -- check for From and To person compatible.
1227c2aa98e2SPeter Wemm **
1228c2aa98e2SPeter Wemm **	This routine can be supplied on a per-installation basis
1229c2aa98e2SPeter Wemm **	to determine whether a person is allowed to send a message.
1230c2aa98e2SPeter Wemm **	This allows restriction of certain types of internet
1231c2aa98e2SPeter Wemm **	forwarding or registration of users.
1232c2aa98e2SPeter Wemm **
1233c2aa98e2SPeter Wemm **	If the hosts are found to be incompatible, an error
1234c2aa98e2SPeter Wemm **	message should be given using "usrerr" and an EX_ code
1235c2aa98e2SPeter Wemm **	should be returned.  You can also set to->q_status to
1236c2aa98e2SPeter Wemm **	a DSN-style status code.
1237c2aa98e2SPeter Wemm **
1238c2aa98e2SPeter Wemm **	EF_NO_BODY_RETN can be set in e->e_flags to suppress the
1239c2aa98e2SPeter Wemm **	body during the return-to-sender function; this should be done
1240c2aa98e2SPeter Wemm **	on huge messages.  This bit may already be set by the ESMTP
1241c2aa98e2SPeter Wemm **	protocol.
1242c2aa98e2SPeter Wemm **
1243c2aa98e2SPeter Wemm **	Parameters:
1244c2aa98e2SPeter Wemm **		to -- the person being sent to.
1245c2aa98e2SPeter Wemm **
1246c2aa98e2SPeter Wemm **	Returns:
1247c2aa98e2SPeter Wemm **		an exit status
1248c2aa98e2SPeter Wemm **
1249c2aa98e2SPeter Wemm **	Side Effects:
1250c2aa98e2SPeter Wemm **		none (unless you include the usrerr stuff)
1251c2aa98e2SPeter Wemm */
1252c2aa98e2SPeter Wemm 
1253c2aa98e2SPeter Wemm int
1254c2aa98e2SPeter Wemm checkcompat(to, e)
1255c2aa98e2SPeter Wemm 	register ADDRESS *to;
1256c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1257c2aa98e2SPeter Wemm {
1258c2aa98e2SPeter Wemm 	if (tTd(49, 1))
125912ed1c7cSGregory Neil Shapiro 		sm_dprintf("checkcompat(to=%s, from=%s)\n",
1260c2aa98e2SPeter Wemm 			to->q_paddr, e->e_from.q_paddr);
1261c2aa98e2SPeter Wemm 
1262c2aa98e2SPeter Wemm #ifdef EXAMPLE_CODE
1263c2aa98e2SPeter Wemm 	/* this code is intended as an example only */
1264c2aa98e2SPeter Wemm 	register STAB *s;
1265c2aa98e2SPeter Wemm 
1266c2aa98e2SPeter Wemm 	s = stab("arpa", ST_MAILER, ST_FIND);
1267c2aa98e2SPeter Wemm 	if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
1268c2aa98e2SPeter Wemm 	    to->q_mailer == s->s_mailer)
1269c2aa98e2SPeter Wemm 	{
1270c2aa98e2SPeter Wemm 		usrerr("553 No ARPA mail through this machine: see your system administration");
12713299c2f1SGregory Neil Shapiro 		/* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */
1272c2aa98e2SPeter Wemm 		to->q_status = "5.7.1";
12733299c2f1SGregory Neil Shapiro 		return EX_UNAVAILABLE;
1274c2aa98e2SPeter Wemm 	}
1275c2aa98e2SPeter Wemm #endif /* EXAMPLE_CODE */
12763299c2f1SGregory Neil Shapiro 	return EX_OK;
1277c2aa98e2SPeter Wemm }
12783299c2f1SGregory Neil Shapiro /*
1279c2aa98e2SPeter Wemm **  INIT_MD -- do machine dependent initializations
1280c2aa98e2SPeter Wemm **
1281c2aa98e2SPeter Wemm **	Systems that have global modes that should be set should do
1282c2aa98e2SPeter Wemm **	them here rather than in main.
1283c2aa98e2SPeter Wemm */
1284c2aa98e2SPeter Wemm 
1285c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1286c2aa98e2SPeter Wemm # include <compat.h>
12873299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1288c2aa98e2SPeter Wemm 
1289c2aa98e2SPeter Wemm #if SHARE_V1
1290c2aa98e2SPeter Wemm # include <shares.h>
12913299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
1292c2aa98e2SPeter Wemm 
1293c2aa98e2SPeter Wemm void
1294c2aa98e2SPeter Wemm init_md(argc, argv)
1295c2aa98e2SPeter Wemm 	int argc;
1296c2aa98e2SPeter Wemm 	char **argv;
1297c2aa98e2SPeter Wemm {
1298c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1299c2aa98e2SPeter Wemm 	setcompat(getcompat() | COMPAT_BSDPROT);
13003299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1301c2aa98e2SPeter Wemm 
1302c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
1303c2aa98e2SPeter Wemm 	init_md_sun();
13043299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
1305c2aa98e2SPeter Wemm 
1306c2aa98e2SPeter Wemm #if _CONVEX_SOURCE
1307c2aa98e2SPeter Wemm 	/* keep gethostby*() from stripping the local domain name */
1308c2aa98e2SPeter Wemm 	set_domain_trim_off();
13093299c2f1SGregory Neil Shapiro #endif /* _CONVEX_SOURCE */
1310c2aa98e2SPeter Wemm #ifdef __QNX__
1311c2aa98e2SPeter Wemm 	/*
1312c2aa98e2SPeter Wemm 	**  Due to QNX's network distributed nature, you can target a tcpip
1313c2aa98e2SPeter Wemm 	**  stack on a different node in the qnx network; this patch lets
1314c2aa98e2SPeter Wemm 	**  this feature work.  The __sock_locate() must be done before the
1315c2aa98e2SPeter Wemm 	**  environment is clear.
1316c2aa98e2SPeter Wemm 	*/
1317c2aa98e2SPeter Wemm 	__sock_locate();
13183299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
1319c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_)
1320c2aa98e2SPeter Wemm 	set_auth_parameters(argc, argv);
1321c2aa98e2SPeter Wemm 
1322c2aa98e2SPeter Wemm # ifdef _SCO_unix_
1323c2aa98e2SPeter Wemm 	/*
1324c2aa98e2SPeter Wemm 	**  This is required for highest security levels (the kernel
1325c2aa98e2SPeter Wemm 	**  won't let it call set*uid() or run setuid binaries without
1326c2aa98e2SPeter Wemm 	**  it).  It may be necessary on other SECUREWARE systems.
1327c2aa98e2SPeter Wemm 	*/
1328c2aa98e2SPeter Wemm 
1329c2aa98e2SPeter Wemm 	if (getluid() == -1)
1330c2aa98e2SPeter Wemm 		setluid(0);
13313299c2f1SGregory Neil Shapiro # endif /* _SCO_unix_ */
13323299c2f1SGregory Neil Shapiro #endif /* SECUREWARE || defined(_SCO_unix_) */
13333299c2f1SGregory Neil Shapiro 
1334c2aa98e2SPeter Wemm 
1335c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT
1336c2aa98e2SPeter Wemm 	VendorCode = VENDOR_DEFAULT;
13373299c2f1SGregory Neil Shapiro #else /* VENDOR_DEFAULT */
1338c2aa98e2SPeter Wemm 	VendorCode = VENDOR_BERKELEY;
13393299c2f1SGregory Neil Shapiro #endif /* VENDOR_DEFAULT */
1340c2aa98e2SPeter Wemm }
134112ed1c7cSGregory Neil Shapiro /*
1342c2aa98e2SPeter Wemm **  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
1343c2aa98e2SPeter Wemm **
1344c2aa98e2SPeter Wemm **	Called once, on startup.
1345c2aa98e2SPeter Wemm **
1346c2aa98e2SPeter Wemm **	Parameters:
1347c2aa98e2SPeter Wemm **		e -- the global envelope.
1348c2aa98e2SPeter Wemm **
1349c2aa98e2SPeter Wemm **	Returns:
1350c2aa98e2SPeter Wemm **		none.
1351c2aa98e2SPeter Wemm **
1352c2aa98e2SPeter Wemm **	Side Effects:
1353c2aa98e2SPeter Wemm **		vendor-dependent.
1354c2aa98e2SPeter Wemm */
1355c2aa98e2SPeter Wemm 
1356c2aa98e2SPeter Wemm void
1357c2aa98e2SPeter Wemm init_vendor_macros(e)
1358c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1359c2aa98e2SPeter Wemm {
1360c2aa98e2SPeter Wemm }
136112ed1c7cSGregory Neil Shapiro /*
1362c2aa98e2SPeter Wemm **  GETLA -- get the current load average
1363c2aa98e2SPeter Wemm **
1364c2aa98e2SPeter Wemm **	This code stolen from la.c.
1365c2aa98e2SPeter Wemm **
1366c2aa98e2SPeter Wemm **	Parameters:
1367c2aa98e2SPeter Wemm **		none.
1368c2aa98e2SPeter Wemm **
1369c2aa98e2SPeter Wemm **	Returns:
1370c2aa98e2SPeter Wemm **		The current load average as an integer.
1371c2aa98e2SPeter Wemm **
1372c2aa98e2SPeter Wemm **	Side Effects:
1373c2aa98e2SPeter Wemm **		none.
1374c2aa98e2SPeter Wemm */
1375c2aa98e2SPeter Wemm 
1376c2aa98e2SPeter Wemm /* try to guess what style of load average we have */
1377c2aa98e2SPeter Wemm #define LA_ZERO		1	/* always return load average as zero */
1378c2aa98e2SPeter Wemm #define LA_INT		2	/* read kmem for avenrun; interpret as long */
1379c2aa98e2SPeter Wemm #define LA_FLOAT	3	/* read kmem for avenrun; interpret as float */
1380c2aa98e2SPeter Wemm #define LA_SUBR		4	/* call getloadavg */
1381c2aa98e2SPeter Wemm #define LA_MACH		5	/* MACH load averages (as on NeXT boxes) */
1382c2aa98e2SPeter Wemm #define LA_SHORT	6	/* read kmem for avenrun; interpret as short */
1383c2aa98e2SPeter Wemm #define LA_PROCSTR	7	/* read string ("1.17") from /proc/loadavg */
1384c2aa98e2SPeter Wemm #define LA_READKSYM	8	/* SVR4: use MIOC_READKSYM ioctl call */
1385c2aa98e2SPeter Wemm #define LA_DGUX		9	/* special DGUX implementation */
1386c2aa98e2SPeter Wemm #define LA_HPUX		10	/* special HPUX implementation */
1387c2aa98e2SPeter Wemm #define LA_IRIX6	11	/* special IRIX 6.2 implementation */
1388c2aa98e2SPeter Wemm #define LA_KSTAT	12	/* special Solaris kstat(3k) implementation */
1389c2aa98e2SPeter Wemm #define LA_DEVSHORT	13	/* read short from a device */
1390c2aa98e2SPeter Wemm #define LA_ALPHAOSF	14	/* Digital UNIX (OSF/1 on Alpha) table() call */
1391c46d91b7SGregory Neil Shapiro #define LA_PSET		15	/* Solaris per-processor-set load average */
1392c2aa98e2SPeter Wemm 
1393c2aa98e2SPeter Wemm /* do guesses based on general OS type */
1394c2aa98e2SPeter Wemm #ifndef LA_TYPE
1395c2aa98e2SPeter Wemm # define LA_TYPE	LA_ZERO
13963299c2f1SGregory Neil Shapiro #endif /* ! LA_TYPE */
1397c2aa98e2SPeter Wemm 
1398c2aa98e2SPeter Wemm #ifndef FSHIFT
1399c2aa98e2SPeter Wemm # if defined(unixpc)
1400c2aa98e2SPeter Wemm #  define FSHIFT	5
14013299c2f1SGregory Neil Shapiro # endif /* defined(unixpc) */
1402c2aa98e2SPeter Wemm 
1403c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX)
1404c2aa98e2SPeter Wemm #  define FSHIFT	10
14053299c2f1SGregory Neil Shapiro # endif /* defined(__alpha) || defined(IRIX) */
1406c2aa98e2SPeter Wemm 
14073299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1408c2aa98e2SPeter Wemm 
1409c2aa98e2SPeter Wemm #ifndef FSHIFT
1410c2aa98e2SPeter Wemm # define FSHIFT		8
14113299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1412c2aa98e2SPeter Wemm 
1413c2aa98e2SPeter Wemm #ifndef FSCALE
1414c2aa98e2SPeter Wemm # define FSCALE		(1 << FSHIFT)
14153299c2f1SGregory Neil Shapiro #endif /* ! FSCALE */
1416c2aa98e2SPeter Wemm 
1417c2aa98e2SPeter Wemm #ifndef LA_AVENRUN
1418c2aa98e2SPeter Wemm # ifdef SYSTEM5
1419c2aa98e2SPeter Wemm #  define LA_AVENRUN	"avenrun"
14203299c2f1SGregory Neil Shapiro # else /* SYSTEM5 */
1421c2aa98e2SPeter Wemm #  define LA_AVENRUN	"_avenrun"
14223299c2f1SGregory Neil Shapiro # endif /* SYSTEM5 */
14233299c2f1SGregory Neil Shapiro #endif /* ! LA_AVENRUN */
1424c2aa98e2SPeter Wemm 
1425c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */
1426c2aa98e2SPeter Wemm #ifndef _PATH_KMEM
1427c2aa98e2SPeter Wemm # define _PATH_KMEM	"/dev/kmem"
14283299c2f1SGregory Neil Shapiro #endif /* ! _PATH_KMEM */
1429c2aa98e2SPeter Wemm 
1430c2aa98e2SPeter Wemm #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
1431c2aa98e2SPeter Wemm 
1432c2aa98e2SPeter Wemm # include <nlist.h>
1433c2aa98e2SPeter Wemm 
1434c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */
1435c2aa98e2SPeter Wemm # ifndef _PATH_UNIX
1436c2aa98e2SPeter Wemm #  if defined(SYSTEM5)
1437c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/unix"
14383299c2f1SGregory Neil Shapiro #  else /* defined(SYSTEM5) */
1439c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/vmunix"
14403299c2f1SGregory Neil Shapiro #  endif /* defined(SYSTEM5) */
14413299c2f1SGregory Neil Shapiro # endif /* ! _PATH_UNIX */
1442c2aa98e2SPeter Wemm 
1443c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
1444c2aa98e2SPeter Wemm struct nlist	Nl[2];
14453299c2f1SGregory Neil Shapiro # else /* _AUX_SOURCE */
1446c2aa98e2SPeter Wemm struct nlist	Nl[] =
1447c2aa98e2SPeter Wemm {
1448c2aa98e2SPeter Wemm 	{ LA_AVENRUN },
1449c2aa98e2SPeter Wemm 	{ 0 },
1450c2aa98e2SPeter Wemm };
14513299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1452c2aa98e2SPeter Wemm # define X_AVENRUN	0
1453c2aa98e2SPeter Wemm 
145412ed1c7cSGregory Neil Shapiro int
1455c2aa98e2SPeter Wemm getla()
1456c2aa98e2SPeter Wemm {
145712ed1c7cSGregory Neil Shapiro 	int j;
1458c2aa98e2SPeter Wemm 	static int kmem = -1;
1459c2aa98e2SPeter Wemm # if LA_TYPE == LA_INT
1460c2aa98e2SPeter Wemm 	long avenrun[3];
14613299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_INT */
1462c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
1463c2aa98e2SPeter Wemm 	short avenrun[3];
14643299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
1465c2aa98e2SPeter Wemm 	double avenrun[3];
14663299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
14673299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_INT */
1468c2aa98e2SPeter Wemm 	extern int errno;
1469c2aa98e2SPeter Wemm 	extern off_t lseek();
1470c2aa98e2SPeter Wemm 
1471c2aa98e2SPeter Wemm 	if (kmem < 0)
1472c2aa98e2SPeter Wemm 	{
1473c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
147412ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN,
14753299c2f1SGregory Neil Shapiro 			       sizeof Nl[X_AVENRUN].n_name);
1476c2aa98e2SPeter Wemm 		Nl[1].n_name[0] = '\0';
14773299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1478c2aa98e2SPeter Wemm 
1479c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
1480c2aa98e2SPeter Wemm 		if (knlist(Nl, 1, sizeof Nl[0]) < 0)
14813299c2f1SGregory Neil Shapiro # else /* defined(_AIX3) || defined(_AIX4) */
1482c2aa98e2SPeter Wemm 		if (nlist(_PATH_UNIX, Nl) < 0)
14833299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
1484c2aa98e2SPeter Wemm 		{
1485c2aa98e2SPeter Wemm 			if (tTd(3, 1))
148612ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
148712ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
14883299c2f1SGregory Neil Shapiro 			return -1;
1489c2aa98e2SPeter Wemm 		}
1490c2aa98e2SPeter Wemm 		if (Nl[X_AVENRUN].n_value == 0)
1491c2aa98e2SPeter Wemm 		{
1492c2aa98e2SPeter Wemm 			if (tTd(3, 1))
149312ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s, %s) ==> 0\n",
1494c2aa98e2SPeter Wemm 					_PATH_UNIX, LA_AVENRUN);
14953299c2f1SGregory Neil Shapiro 			return -1;
1496c2aa98e2SPeter Wemm 		}
1497c2aa98e2SPeter Wemm # ifdef NAMELISTMASK
1498c2aa98e2SPeter Wemm 		Nl[X_AVENRUN].n_value &= NAMELISTMASK;
14993299c2f1SGregory Neil Shapiro # endif /* NAMELISTMASK */
1500c2aa98e2SPeter Wemm 
1501c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1502c2aa98e2SPeter Wemm 		if (kmem < 0)
1503c2aa98e2SPeter Wemm 		{
1504c2aa98e2SPeter Wemm 			if (tTd(3, 1))
150512ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
150612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15073299c2f1SGregory Neil Shapiro 			return -1;
1508c2aa98e2SPeter Wemm 		}
150912ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
151012ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
151112ed1c7cSGregory Neil Shapiro 		{
151212ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
151312ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
151412ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
151512ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
151612ed1c7cSGregory Neil Shapiro 			kmem = -1;
151712ed1c7cSGregory Neil Shapiro 			return -1;
151812ed1c7cSGregory Neil Shapiro 		}
1519c2aa98e2SPeter Wemm 	}
1520c2aa98e2SPeter Wemm 	if (tTd(3, 20))
152112ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: symbol address = %#lx\n",
152212ed1c7cSGregory Neil Shapiro 			(unsigned long) Nl[X_AVENRUN].n_value);
1523c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
1524c2aa98e2SPeter Wemm 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
1525c2aa98e2SPeter Wemm 	{
1526c2aa98e2SPeter Wemm 		/* thank you Ian */
1527c2aa98e2SPeter Wemm 		if (tTd(3, 1))
152812ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
152912ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
15303299c2f1SGregory Neil Shapiro 		return -1;
1531c2aa98e2SPeter Wemm 	}
1532c2aa98e2SPeter Wemm # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
1533c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1534c2aa98e2SPeter Wemm 	{
1535c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
153612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1537c2aa98e2SPeter Wemm 		if (tTd(3, 15))
153812ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
15393299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
154012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", avenrun[0]);
1541c2aa98e2SPeter Wemm 		if (tTd(3, 15))
154212ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]);
15433299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
154412ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1545c2aa98e2SPeter Wemm 	}
1546c2aa98e2SPeter Wemm 	if (tTd(3, 1))
154712ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
15483299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1549c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
15503299c2f1SGregory Neil Shapiro # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */
1551c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1552c2aa98e2SPeter Wemm 	{
155312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %g", avenrun[0]);
1554c2aa98e2SPeter Wemm 		if (tTd(3, 15))
155512ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %g, %g", avenrun[1], avenrun[2]);
155612ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1557c2aa98e2SPeter Wemm 	}
1558c2aa98e2SPeter Wemm 	if (tTd(3, 1))
155912ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1560c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
15613299c2f1SGregory Neil Shapiro # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */
1562c2aa98e2SPeter Wemm }
1563c2aa98e2SPeter Wemm 
15643299c2f1SGregory Neil Shapiro #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) */
1565c2aa98e2SPeter Wemm 
1566c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM
1567c2aa98e2SPeter Wemm 
1568c2aa98e2SPeter Wemm # include <sys/ksym.h>
1569c2aa98e2SPeter Wemm 
157012ed1c7cSGregory Neil Shapiro int
1571c2aa98e2SPeter Wemm getla()
1572c2aa98e2SPeter Wemm {
157312ed1c7cSGregory Neil Shapiro 	int j;
1574c2aa98e2SPeter Wemm 	static int kmem = -1;
1575c2aa98e2SPeter Wemm 	long avenrun[3];
1576c2aa98e2SPeter Wemm 	extern int errno;
1577c2aa98e2SPeter Wemm 	struct mioc_rksym mirk;
1578c2aa98e2SPeter Wemm 
1579c2aa98e2SPeter Wemm 	if (kmem < 0)
1580c2aa98e2SPeter Wemm 	{
1581c2aa98e2SPeter Wemm 		kmem = open("/dev/kmem", 0, 0);
1582c2aa98e2SPeter Wemm 		if (kmem < 0)
1583c2aa98e2SPeter Wemm 		{
1584c2aa98e2SPeter Wemm 			if (tTd(3, 1))
158512ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
158612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15873299c2f1SGregory Neil Shapiro 			return -1;
1588c2aa98e2SPeter Wemm 		}
158912ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
159012ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
159112ed1c7cSGregory Neil Shapiro 		{
159212ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
159312ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
159412ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
159512ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
159612ed1c7cSGregory Neil Shapiro 			kmem = -1;
159712ed1c7cSGregory Neil Shapiro 			return -1;
159812ed1c7cSGregory Neil Shapiro 		}
1599c2aa98e2SPeter Wemm 	}
1600c2aa98e2SPeter Wemm 	mirk.mirk_symname = LA_AVENRUN;
1601c2aa98e2SPeter Wemm 	mirk.mirk_buf = avenrun;
1602c2aa98e2SPeter Wemm 	mirk.mirk_buflen = sizeof(avenrun);
1603c2aa98e2SPeter Wemm 	if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
1604c2aa98e2SPeter Wemm 	{
1605c2aa98e2SPeter Wemm 		if (tTd(3, 1))
160612ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
160712ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1608c2aa98e2SPeter Wemm 		return -1;
1609c2aa98e2SPeter Wemm 	}
1610c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1611c2aa98e2SPeter Wemm 	{
161212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1613c2aa98e2SPeter Wemm 		if (tTd(3, 15))
161412ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
161512ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1616c2aa98e2SPeter Wemm 	}
1617c2aa98e2SPeter Wemm 	if (tTd(3, 1))
161812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
16193299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1620c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1621c2aa98e2SPeter Wemm }
1622c2aa98e2SPeter Wemm 
1623c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */
1624c2aa98e2SPeter Wemm 
1625c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX
1626c2aa98e2SPeter Wemm 
1627c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h>
1628c2aa98e2SPeter Wemm 
162912ed1c7cSGregory Neil Shapiro int
1630c2aa98e2SPeter Wemm getla()
1631c2aa98e2SPeter Wemm {
1632c2aa98e2SPeter Wemm 	struct dg_sys_info_load_info load_info;
1633c2aa98e2SPeter Wemm 
1634c2aa98e2SPeter Wemm 	dg_sys_info((long *)&load_info,
1635c2aa98e2SPeter Wemm 		DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
1636c2aa98e2SPeter Wemm 
1637c2aa98e2SPeter Wemm 	if (tTd(3, 1))
163812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5));
1639c2aa98e2SPeter Wemm 
1640c2aa98e2SPeter Wemm 	return ((int) (load_info.one_minute + 0.5));
1641c2aa98e2SPeter Wemm }
1642c2aa98e2SPeter Wemm 
1643c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */
1644c2aa98e2SPeter Wemm 
1645c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX
1646c2aa98e2SPeter Wemm 
1647c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */
1648c2aa98e2SPeter Wemm struct pst_dynamic;
1649c2aa98e2SPeter Wemm struct pst_status;
1650c2aa98e2SPeter Wemm struct pst_static;
1651c2aa98e2SPeter Wemm struct pst_vminfo;
1652c2aa98e2SPeter Wemm struct pst_diskinfo;
1653c2aa98e2SPeter Wemm struct pst_processor;
1654c2aa98e2SPeter Wemm struct pst_lv;
1655c2aa98e2SPeter Wemm struct pst_swapinfo;
1656c2aa98e2SPeter Wemm 
1657c2aa98e2SPeter Wemm # include <sys/param.h>
1658c2aa98e2SPeter Wemm # include <sys/pstat.h>
1659c2aa98e2SPeter Wemm 
166012ed1c7cSGregory Neil Shapiro int
1661c2aa98e2SPeter Wemm getla()
1662c2aa98e2SPeter Wemm {
1663c2aa98e2SPeter Wemm 	struct pst_dynamic pstd;
1664c2aa98e2SPeter Wemm 
1665c2aa98e2SPeter Wemm 	if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
1666c2aa98e2SPeter Wemm 			     (size_t) 1, 0) == -1)
1667c2aa98e2SPeter Wemm 		return 0;
1668c2aa98e2SPeter Wemm 
1669c2aa98e2SPeter Wemm 	if (tTd(3, 1))
167012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
1671c2aa98e2SPeter Wemm 
1672c2aa98e2SPeter Wemm 	return (int) (pstd.psd_avg_1_min + 0.5);
1673c2aa98e2SPeter Wemm }
1674c2aa98e2SPeter Wemm 
1675c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */
1676c2aa98e2SPeter Wemm 
1677c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR
1678c2aa98e2SPeter Wemm 
167912ed1c7cSGregory Neil Shapiro int
1680c2aa98e2SPeter Wemm getla()
1681c2aa98e2SPeter Wemm {
1682c2aa98e2SPeter Wemm 	double avenrun[3];
1683c2aa98e2SPeter Wemm 
1684c2aa98e2SPeter Wemm 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
1685c2aa98e2SPeter Wemm 	{
1686c2aa98e2SPeter Wemm 		if (tTd(3, 1))
168712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: getloadavg failed: %s",
168812ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
16893299c2f1SGregory Neil Shapiro 		return -1;
1690c2aa98e2SPeter Wemm 	}
1691c2aa98e2SPeter Wemm 	if (tTd(3, 1))
169212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1693c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1694c2aa98e2SPeter Wemm }
1695c2aa98e2SPeter Wemm 
1696c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */
1697c2aa98e2SPeter Wemm 
1698c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH
1699c2aa98e2SPeter Wemm 
1700c2aa98e2SPeter Wemm /*
1701c2aa98e2SPeter Wemm **  This has been tested on NEXTSTEP release 2.1/3.X.
1702c2aa98e2SPeter Wemm */
1703c2aa98e2SPeter Wemm 
1704c2aa98e2SPeter Wemm # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
1705c2aa98e2SPeter Wemm #  include <mach/mach.h>
17063299c2f1SGregory Neil Shapiro # else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1707c2aa98e2SPeter Wemm #  include <mach.h>
17083299c2f1SGregory Neil Shapiro # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1709c2aa98e2SPeter Wemm 
171012ed1c7cSGregory Neil Shapiro int
1711c2aa98e2SPeter Wemm getla()
1712c2aa98e2SPeter Wemm {
1713c2aa98e2SPeter Wemm 	processor_set_t default_set;
1714c2aa98e2SPeter Wemm 	kern_return_t error;
1715c2aa98e2SPeter Wemm 	unsigned int info_count;
1716c2aa98e2SPeter Wemm 	struct processor_set_basic_info info;
1717c2aa98e2SPeter Wemm 	host_t host;
1718c2aa98e2SPeter Wemm 
1719c2aa98e2SPeter Wemm 	error = processor_set_default(host_self(), &default_set);
1720c2aa98e2SPeter Wemm 	if (error != KERN_SUCCESS)
1721c2aa98e2SPeter Wemm 	{
1722c2aa98e2SPeter Wemm 		if (tTd(3, 1))
172312ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_default failed: %s",
172412ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1725c2aa98e2SPeter Wemm 		return -1;
1726c2aa98e2SPeter Wemm 	}
1727c2aa98e2SPeter Wemm 	info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
1728c2aa98e2SPeter Wemm 	if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
1729c2aa98e2SPeter Wemm 			       &host, (processor_set_info_t)&info,
1730c2aa98e2SPeter Wemm 			       &info_count) != KERN_SUCCESS)
1731c2aa98e2SPeter Wemm 	{
1732c2aa98e2SPeter Wemm 		if (tTd(3, 1))
173312ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_info failed: %s",
173412ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1735c2aa98e2SPeter Wemm 		return -1;
1736c2aa98e2SPeter Wemm 	}
1737c2aa98e2SPeter Wemm 	if (tTd(3, 1))
173812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
17393299c2f1SGregory Neil Shapiro 			(int) ((info.load_average + (LOAD_SCALE / 2)) /
17403299c2f1SGregory Neil Shapiro 			       LOAD_SCALE));
1741c2aa98e2SPeter Wemm 	return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
1742c2aa98e2SPeter Wemm }
1743c2aa98e2SPeter Wemm 
1744c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */
1745c2aa98e2SPeter Wemm 
1746c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR
174712ed1c7cSGregory Neil Shapiro # if SM_CONF_BROKEN_STRTOD
174812ed1c7cSGregory Neil Shapiro 	ERROR: This OS has most likely a broken strtod() implemenentation.
174912ed1c7cSGregory Neil Shapiro 	ERROR: The function is required for getla().
175012ed1c7cSGregory Neil Shapiro 	ERROR: Check the compilation options _LA_PROCSTR and
175112ed1c7cSGregory Neil Shapiro 	ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _).
175212ed1c7cSGregory Neil Shapiro # endif /* SM_CONF_BROKEN_STRTOD */
1753c2aa98e2SPeter Wemm 
1754c2aa98e2SPeter Wemm /*
1755c2aa98e2SPeter Wemm **  Read /proc/loadavg for the load average.  This is assumed to be
1756c2aa98e2SPeter Wemm **  in a format like "0.15 0.12 0.06".
1757c2aa98e2SPeter Wemm **
1758c2aa98e2SPeter Wemm **	Initially intended for Linux.  This has been in the kernel
1759c2aa98e2SPeter Wemm **	since at least 0.99.15.
1760c2aa98e2SPeter Wemm */
1761c2aa98e2SPeter Wemm 
1762c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG
1763c2aa98e2SPeter Wemm #  define _PATH_LOADAVG	"/proc/loadavg"
17643299c2f1SGregory Neil Shapiro # endif /* ! _PATH_LOADAVG */
1765c2aa98e2SPeter Wemm 
176612ed1c7cSGregory Neil Shapiro int
1767c2aa98e2SPeter Wemm getla()
1768c2aa98e2SPeter Wemm {
1769c2aa98e2SPeter Wemm 	double avenrun;
1770c2aa98e2SPeter Wemm 	register int result;
177112ed1c7cSGregory Neil Shapiro 	SM_FILE_T *fp;
1772c2aa98e2SPeter Wemm 
177312ed1c7cSGregory Neil Shapiro 	fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY,
177412ed1c7cSGregory Neil Shapiro 			NULL);
1775c2aa98e2SPeter Wemm 	if (fp == NULL)
1776c2aa98e2SPeter Wemm 	{
1777c2aa98e2SPeter Wemm 		if (tTd(3, 1))
177812ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_open(%s): %s\n",
177912ed1c7cSGregory Neil Shapiro 				   _PATH_LOADAVG, sm_errstring(errno));
1780c2aa98e2SPeter Wemm 		return -1;
1781c2aa98e2SPeter Wemm 	}
178212ed1c7cSGregory Neil Shapiro 	result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun);
178312ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(fp, SM_TIME_DEFAULT);
1784c2aa98e2SPeter Wemm 	if (result != 1)
1785c2aa98e2SPeter Wemm 	{
1786c2aa98e2SPeter Wemm 		if (tTd(3, 1))
178712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_fscanf() = %d: %s\n",
178812ed1c7cSGregory Neil Shapiro 				   result, sm_errstring(errno));
1789c2aa98e2SPeter Wemm 		return -1;
1790c2aa98e2SPeter Wemm 	}
1791c2aa98e2SPeter Wemm 
1792c2aa98e2SPeter Wemm 	if (tTd(3, 1))
179312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla(): %.2f\n", avenrun);
1794c2aa98e2SPeter Wemm 
1795c2aa98e2SPeter Wemm 	return ((int) (avenrun + 0.5));
1796c2aa98e2SPeter Wemm }
1797c2aa98e2SPeter Wemm 
1798c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */
1799c2aa98e2SPeter Wemm 
1800c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6
18013299c2f1SGregory Neil Shapiro 
1802c2aa98e2SPeter Wemm # include <sys/sysmp.h>
1803c2aa98e2SPeter Wemm 
180412ed1c7cSGregory Neil Shapiro int
180512ed1c7cSGregory Neil Shapiro getla(void)
1806c2aa98e2SPeter Wemm {
180712ed1c7cSGregory Neil Shapiro 	int j;
1808c2aa98e2SPeter Wemm 	static int kmem = -1;
1809c2aa98e2SPeter Wemm 	int avenrun[3];
1810c2aa98e2SPeter Wemm 
1811c2aa98e2SPeter Wemm 	if (kmem < 0)
1812c2aa98e2SPeter Wemm 	{
1813c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1814c2aa98e2SPeter Wemm 		if (kmem < 0)
1815c2aa98e2SPeter Wemm 		{
1816c2aa98e2SPeter Wemm 			if (tTd(3, 1))
181712ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM,
181812ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
1819c2aa98e2SPeter Wemm 			return -1;
1820c2aa98e2SPeter Wemm 		}
182112ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
182212ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
182312ed1c7cSGregory Neil Shapiro 		{
182412ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
182512ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
182612ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
182712ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
182812ed1c7cSGregory Neil Shapiro 			kmem = -1;
182912ed1c7cSGregory Neil Shapiro 			return -1;
183012ed1c7cSGregory Neil Shapiro 		}
1831c2aa98e2SPeter Wemm 	}
1832c2aa98e2SPeter Wemm 
1833c2aa98e2SPeter Wemm 	if (lseek(kmem, (sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff), SEEK_SET) == -1 ||
1834c2aa98e2SPeter Wemm 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
1835c2aa98e2SPeter Wemm 	{
1836c2aa98e2SPeter Wemm 		if (tTd(3, 1))
183712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
183812ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1839c2aa98e2SPeter Wemm 		return -1;
1840c2aa98e2SPeter Wemm 	}
1841c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1842c2aa98e2SPeter Wemm 	{
184312ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]);
1844c2aa98e2SPeter Wemm 		if (tTd(3, 15))
184512ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld",
1846c2aa98e2SPeter Wemm 				(long int) avenrun[1], (long int) avenrun[2]);
184712ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1848c2aa98e2SPeter Wemm 	}
1849c2aa98e2SPeter Wemm 
1850c2aa98e2SPeter Wemm 	if (tTd(3, 1))
185112ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
18523299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1853c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1854c2aa98e2SPeter Wemm 
1855c2aa98e2SPeter Wemm }
18563299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_IRIX6 */
1857c2aa98e2SPeter Wemm 
1858c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT
1859c2aa98e2SPeter Wemm 
1860c2aa98e2SPeter Wemm # include <kstat.h>
1861c2aa98e2SPeter Wemm 
186212ed1c7cSGregory Neil Shapiro int
1863c2aa98e2SPeter Wemm getla()
1864c2aa98e2SPeter Wemm {
1865c2aa98e2SPeter Wemm 	static kstat_ctl_t *kc = NULL;
1866c2aa98e2SPeter Wemm 	static kstat_t *ksp = NULL;
1867c2aa98e2SPeter Wemm 	kstat_named_t *ksn;
1868c2aa98e2SPeter Wemm 	int la;
1869c2aa98e2SPeter Wemm 
1870c2aa98e2SPeter Wemm 	if (kc == NULL)		/* if not initialized before */
1871c2aa98e2SPeter Wemm 		kc = kstat_open();
1872c2aa98e2SPeter Wemm 	if (kc == NULL)
1873c2aa98e2SPeter Wemm 	{
1874c2aa98e2SPeter Wemm 		if (tTd(3, 1))
187512ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_open(): %s\n",
187612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1877c2aa98e2SPeter Wemm 		return -1;
1878c2aa98e2SPeter Wemm 	}
1879c2aa98e2SPeter Wemm 	if (ksp == NULL)
1880c2aa98e2SPeter Wemm 		ksp = kstat_lookup(kc, "unix", 0, "system_misc");
1881c2aa98e2SPeter Wemm 	if (ksp == NULL)
1882c2aa98e2SPeter Wemm 	{
1883c2aa98e2SPeter Wemm 		if (tTd(3, 1))
188412ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_lookup(): %s\n",
188512ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1886c2aa98e2SPeter Wemm 		return -1;
1887c2aa98e2SPeter Wemm 	}
1888c2aa98e2SPeter Wemm 	if (kstat_read(kc, ksp, NULL) < 0)
1889c2aa98e2SPeter Wemm 	{
1890c2aa98e2SPeter Wemm 		if (tTd(3, 1))
189112ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_read(): %s\n",
189212ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1893c2aa98e2SPeter Wemm 		return -1;
1894c2aa98e2SPeter Wemm 	}
1895c2aa98e2SPeter Wemm 	ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
1896c2aa98e2SPeter Wemm 	la = ((double) ksn->value.ul + FSCALE/2) / FSCALE;
1897c2aa98e2SPeter Wemm 	/* kstat_close(kc); /o do not close for fast access */
1898c2aa98e2SPeter Wemm 	return la;
1899c2aa98e2SPeter Wemm }
1900c2aa98e2SPeter Wemm 
1901c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */
1902c2aa98e2SPeter Wemm 
1903c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT
1904c2aa98e2SPeter Wemm 
1905c2aa98e2SPeter Wemm /*
1906c2aa98e2SPeter Wemm **  Read /dev/table/avenrun for the load average.  This should contain
1907c2aa98e2SPeter Wemm **  three shorts for the 1, 5, and 15 minute loads.  We only read the
1908c2aa98e2SPeter Wemm **  first, since that's all we care about.
1909c2aa98e2SPeter Wemm **
1910c2aa98e2SPeter Wemm **	Intended for SCO OpenServer 5.
1911c2aa98e2SPeter Wemm */
1912c2aa98e2SPeter Wemm 
1913c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN
1914c2aa98e2SPeter Wemm #  define _PATH_AVENRUN	"/dev/table/avenrun"
19153299c2f1SGregory Neil Shapiro # endif /* ! _PATH_AVENRUN */
1916c2aa98e2SPeter Wemm 
191712ed1c7cSGregory Neil Shapiro int
1918c2aa98e2SPeter Wemm getla()
1919c2aa98e2SPeter Wemm {
1920c2aa98e2SPeter Wemm 	static int afd = -1;
1921c2aa98e2SPeter Wemm 	short avenrun;
1922c2aa98e2SPeter Wemm 	int loadav;
1923c2aa98e2SPeter Wemm 	int r;
1924c2aa98e2SPeter Wemm 
1925c2aa98e2SPeter Wemm 	errno = EBADF;
1926c2aa98e2SPeter Wemm 
1927c2aa98e2SPeter Wemm 	if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
1928c2aa98e2SPeter Wemm 	{
1929c2aa98e2SPeter Wemm 		if (errno != EBADF)
1930c2aa98e2SPeter Wemm 			return -1;
1931c2aa98e2SPeter Wemm 		afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
1932c2aa98e2SPeter Wemm 		if (afd < 0)
1933c2aa98e2SPeter Wemm 		{
1934c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
193512ed1c7cSGregory Neil Shapiro 				"can't open %s: %s",
193612ed1c7cSGregory Neil Shapiro 				_PATH_AVENRUN, sm_errstring(errno));
1937c2aa98e2SPeter Wemm 			return -1;
1938c2aa98e2SPeter Wemm 		}
1939c2aa98e2SPeter Wemm 	}
1940c2aa98e2SPeter Wemm 
1941c2aa98e2SPeter Wemm 	r = read(afd, &avenrun, sizeof avenrun);
1942c2aa98e2SPeter Wemm 
1943c2aa98e2SPeter Wemm 	if (tTd(3, 5))
194412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d\n", avenrun);
1945c2aa98e2SPeter Wemm 	loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
1946c2aa98e2SPeter Wemm 	if (tTd(3, 1))
194712ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", loadav);
1948c2aa98e2SPeter Wemm 	return loadav;
1949c2aa98e2SPeter Wemm }
1950c2aa98e2SPeter Wemm 
1951c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */
1952c2aa98e2SPeter Wemm 
1953c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF
1954c2aa98e2SPeter Wemm struct rtentry;
1955c2aa98e2SPeter Wemm struct mbuf;
1956c2aa98e2SPeter Wemm # include <sys/table.h>
1957c2aa98e2SPeter Wemm 
195812ed1c7cSGregory Neil Shapiro int
195912ed1c7cSGregory Neil Shapiro getla()
1960c2aa98e2SPeter Wemm {
1961c2aa98e2SPeter Wemm 	int ave = 0;
1962c2aa98e2SPeter Wemm 	struct tbl_loadavg tab;
1963c2aa98e2SPeter Wemm 
1964c2aa98e2SPeter Wemm 	if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
1965c2aa98e2SPeter Wemm 	{
1966c2aa98e2SPeter Wemm 		if (tTd(3, 1))
196712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: table %s\n", sm_errstring(errno));
19683299c2f1SGregory Neil Shapiro 		return -1;
1969c2aa98e2SPeter Wemm 	}
1970c2aa98e2SPeter Wemm 
1971c2aa98e2SPeter Wemm 	if (tTd(3, 1))
197212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: scale = %d\n", tab.tl_lscale);
1973c2aa98e2SPeter Wemm 
1974c2aa98e2SPeter Wemm 	if (tab.tl_lscale)
19753299c2f1SGregory Neil Shapiro 		ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) /
19763299c2f1SGregory Neil Shapiro 		       tab.tl_lscale);
1977c2aa98e2SPeter Wemm 	else
19783299c2f1SGregory Neil Shapiro 		ave = (int) (tab.tl_avenrun.d[2] + 0.5);
1979c2aa98e2SPeter Wemm 
1980c2aa98e2SPeter Wemm 	if (tTd(3, 1))
198112ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", ave);
1982c2aa98e2SPeter Wemm 
1983c2aa98e2SPeter Wemm 	return ave;
1984c2aa98e2SPeter Wemm }
1985c2aa98e2SPeter Wemm 
19863299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_ALPHAOSF */
1987c2aa98e2SPeter Wemm 
1988c46d91b7SGregory Neil Shapiro #if LA_TYPE == LA_PSET
1989c46d91b7SGregory Neil Shapiro 
199012ed1c7cSGregory Neil Shapiro int
1991c46d91b7SGregory Neil Shapiro getla()
1992c46d91b7SGregory Neil Shapiro {
1993c46d91b7SGregory Neil Shapiro 	double avenrun[3];
1994c46d91b7SGregory Neil Shapiro 
1995c46d91b7SGregory Neil Shapiro 	if (pset_getloadavg(PS_MYID, avenrun,
1996c46d91b7SGregory Neil Shapiro 			    sizeof(avenrun) / sizeof(avenrun[0])) < 0)
1997c46d91b7SGregory Neil Shapiro 	{
1998c46d91b7SGregory Neil Shapiro 		if (tTd(3, 1))
199912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: pset_getloadavg failed: %s",
200012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
2001c46d91b7SGregory Neil Shapiro 		return -1;
2002c46d91b7SGregory Neil Shapiro 	}
2003c46d91b7SGregory Neil Shapiro 	if (tTd(3, 1))
200412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
2005c46d91b7SGregory Neil Shapiro 	return ((int) (avenrun[0] + 0.5));
2006c46d91b7SGregory Neil Shapiro }
2007c46d91b7SGregory Neil Shapiro 
2008c46d91b7SGregory Neil Shapiro #endif /* LA_TYPE == LA_PSET */
2009c46d91b7SGregory Neil Shapiro 
2010c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO
2011c2aa98e2SPeter Wemm 
201212ed1c7cSGregory Neil Shapiro int
2013c2aa98e2SPeter Wemm getla()
2014c2aa98e2SPeter Wemm {
2015c2aa98e2SPeter Wemm 	if (tTd(3, 1))
201612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: ZERO\n");
20173299c2f1SGregory Neil Shapiro 	return 0;
2018c2aa98e2SPeter Wemm }
2019c2aa98e2SPeter Wemm 
2020c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */
2021c2aa98e2SPeter Wemm 
2022c2aa98e2SPeter Wemm /*
2023c2aa98e2SPeter Wemm  * Copyright 1989 Massachusetts Institute of Technology
2024c2aa98e2SPeter Wemm  *
2025c2aa98e2SPeter Wemm  * Permission to use, copy, modify, distribute, and sell this software and its
2026c2aa98e2SPeter Wemm  * documentation for any purpose is hereby granted without fee, provided that
2027c2aa98e2SPeter Wemm  * the above copyright notice appear in all copies and that both that
2028c2aa98e2SPeter Wemm  * copyright notice and this permission notice appear in supporting
2029c2aa98e2SPeter Wemm  * documentation, and that the name of M.I.T. not be used in advertising or
2030c2aa98e2SPeter Wemm  * publicity pertaining to distribution of the software without specific,
2031c2aa98e2SPeter Wemm  * written prior permission.  M.I.T. makes no representations about the
2032c2aa98e2SPeter Wemm  * suitability of this software for any purpose.  It is provided "as is"
2033c2aa98e2SPeter Wemm  * without express or implied warranty.
2034c2aa98e2SPeter Wemm  *
2035c2aa98e2SPeter Wemm  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
2036c2aa98e2SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
2037c2aa98e2SPeter Wemm  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2038c2aa98e2SPeter Wemm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2039c2aa98e2SPeter Wemm  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2040c2aa98e2SPeter Wemm  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2041c2aa98e2SPeter Wemm  *
2042c2aa98e2SPeter Wemm  * Authors:  Many and varied...
2043c2aa98e2SPeter Wemm  */
2044c2aa98e2SPeter Wemm 
2045c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */
2046c2aa98e2SPeter Wemm #ifndef lint
204712ed1c7cSGregory Neil Shapiro SM_UNUSED(static char  rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
2048c2aa98e2SPeter Wemm #endif /* ! lint */
2049c2aa98e2SPeter Wemm 
2050c2aa98e2SPeter Wemm #ifdef apollo
2051c2aa98e2SPeter Wemm # undef volatile
2052c2aa98e2SPeter Wemm # include <apollo/base.h>
2053c2aa98e2SPeter Wemm 
2054c2aa98e2SPeter Wemm /* ARGSUSED */
2055c2aa98e2SPeter Wemm int getloadavg( call_data )
2056c2aa98e2SPeter Wemm 	caddr_t call_data;	/* pointer to (double) return value */
2057c2aa98e2SPeter Wemm {
2058c2aa98e2SPeter Wemm 	double *avenrun = (double *) call_data;
2059c2aa98e2SPeter Wemm 	int i;
2060c2aa98e2SPeter Wemm 	status_$t      st;
2061c2aa98e2SPeter Wemm 	long loadav[3];
206212ed1c7cSGregory Neil Shapiro 
2063c2aa98e2SPeter Wemm 	proc1_$get_loadav(loadav, &st);
2064c2aa98e2SPeter Wemm 	*avenrun = loadav[0] / (double) (1 << 16);
20653299c2f1SGregory Neil Shapiro 	return 0;
2066c2aa98e2SPeter Wemm }
2067c2aa98e2SPeter Wemm #endif /* apollo */
206812ed1c7cSGregory Neil Shapiro /*
206912ed1c7cSGregory Neil Shapiro **  SM_GETLA -- get the current load average
20703299c2f1SGregory Neil Shapiro **
20713299c2f1SGregory Neil Shapiro **	Parameters:
207212ed1c7cSGregory Neil Shapiro **		none
20733299c2f1SGregory Neil Shapiro **
20743299c2f1SGregory Neil Shapiro **	Returns:
207512ed1c7cSGregory Neil Shapiro **		none
20763299c2f1SGregory Neil Shapiro **
20773299c2f1SGregory Neil Shapiro **	Side Effects:
207812ed1c7cSGregory Neil Shapiro **		Set CurrentLA to the current load average.
207912ed1c7cSGregory Neil Shapiro **		Set {load_avg} in GlobalMacros to the current load average.
20803299c2f1SGregory Neil Shapiro */
20813299c2f1SGregory Neil Shapiro 
208212ed1c7cSGregory Neil Shapiro void
208312ed1c7cSGregory Neil Shapiro sm_getla()
20843299c2f1SGregory Neil Shapiro {
20853299c2f1SGregory Neil Shapiro 	char labuf[8];
20863299c2f1SGregory Neil Shapiro 
208712ed1c7cSGregory Neil Shapiro 	CurrentLA = getla();
208812ed1c7cSGregory Neil Shapiro 	(void) sm_snprintf(labuf, sizeof labuf, "%d", CurrentLA);
208912ed1c7cSGregory Neil Shapiro 	macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf);
20903299c2f1SGregory Neil Shapiro }
209112ed1c7cSGregory Neil Shapiro /*
2092c2aa98e2SPeter Wemm **  SHOULDQUEUE -- should this message be queued or sent?
2093c2aa98e2SPeter Wemm **
2094c2aa98e2SPeter Wemm **	Compares the message cost to the load average to decide.
2095c2aa98e2SPeter Wemm **
209612ed1c7cSGregory Neil Shapiro **	Note: Do NOT change this API! It is documented in op.me
209712ed1c7cSGregory Neil Shapiro **		and theoretically the user can change this function...
209812ed1c7cSGregory Neil Shapiro **
2099c2aa98e2SPeter Wemm **	Parameters:
2100c2aa98e2SPeter Wemm **		pri -- the priority of the message in question.
210112ed1c7cSGregory Neil Shapiro **		ct -- the message creation time (unused, but see above).
2102c2aa98e2SPeter Wemm **
2103c2aa98e2SPeter Wemm **	Returns:
210412ed1c7cSGregory Neil Shapiro **		true -- if this message should be queued up for the
2105c2aa98e2SPeter Wemm **			time being.
210612ed1c7cSGregory Neil Shapiro **		false -- if the load is low enough to send this message.
2107c2aa98e2SPeter Wemm **
2108c2aa98e2SPeter Wemm **	Side Effects:
2109c2aa98e2SPeter Wemm **		none.
2110c2aa98e2SPeter Wemm */
2111c2aa98e2SPeter Wemm 
21123299c2f1SGregory Neil Shapiro /* ARGSUSED1 */
2113c2aa98e2SPeter Wemm bool
21143299c2f1SGregory Neil Shapiro shouldqueue(pri, ct)
2115c2aa98e2SPeter Wemm 	long pri;
21163299c2f1SGregory Neil Shapiro 	time_t ct;
2117c2aa98e2SPeter Wemm {
2118c2aa98e2SPeter Wemm 	bool rval;
2119c2aa98e2SPeter Wemm 
2120c2aa98e2SPeter Wemm 	if (tTd(3, 30))
212112ed1c7cSGregory Neil Shapiro 		sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
21223299c2f1SGregory Neil Shapiro 			CurrentLA, pri);
21233299c2f1SGregory Neil Shapiro 	if (CurrentLA < QueueLA)
2124c2aa98e2SPeter Wemm 	{
2125c2aa98e2SPeter Wemm 		if (tTd(3, 30))
212612ed1c7cSGregory Neil Shapiro 			sm_dprintf("false (CurrentLA < QueueLA)\n");
212712ed1c7cSGregory Neil Shapiro 		return false;
2128c2aa98e2SPeter Wemm 	}
2129c2aa98e2SPeter Wemm # if 0	/* this code is reported to cause oscillation around RefuseLA */
2130c2aa98e2SPeter Wemm 	if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
2131c2aa98e2SPeter Wemm 	{
2132c2aa98e2SPeter Wemm 		if (tTd(3, 30))
213312ed1c7cSGregory Neil Shapiro 			sm_dprintf("TRUE (CurrentLA >= RefuseLA)\n");
213412ed1c7cSGregory Neil Shapiro 		return true;
2135c2aa98e2SPeter Wemm 	}
21363299c2f1SGregory Neil Shapiro # endif /* 0 */
21373299c2f1SGregory Neil Shapiro 	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
2138c2aa98e2SPeter Wemm 	if (tTd(3, 30))
213912ed1c7cSGregory Neil Shapiro 		sm_dprintf("%s (by calculation)\n", rval ? "true" : "false");
2140c2aa98e2SPeter Wemm 	return rval;
2141c2aa98e2SPeter Wemm }
214212ed1c7cSGregory Neil Shapiro /*
2143c2aa98e2SPeter Wemm **  REFUSECONNECTIONS -- decide if connections should be refused
2144c2aa98e2SPeter Wemm **
2145c2aa98e2SPeter Wemm **	Parameters:
21463299c2f1SGregory Neil Shapiro **		name -- daemon name (for error messages only)
21473299c2f1SGregory Neil Shapiro **		e -- the current envelope.
21483299c2f1SGregory Neil Shapiro **		d -- number of daemon
214912ed1c7cSGregory Neil Shapiro **		active -- was this daemon actually active?
2150c2aa98e2SPeter Wemm **
2151c2aa98e2SPeter Wemm **	Returns:
215212ed1c7cSGregory Neil Shapiro **		true if incoming SMTP connections should be refused
2153c2aa98e2SPeter Wemm **			(for now).
215412ed1c7cSGregory Neil Shapiro **		false if we should accept new work.
2155c2aa98e2SPeter Wemm **
2156c2aa98e2SPeter Wemm **	Side Effects:
2157c2aa98e2SPeter Wemm **		Sets process title when it is rejecting connections.
2158c2aa98e2SPeter Wemm */
2159c2aa98e2SPeter Wemm 
2160c2aa98e2SPeter Wemm bool
216112ed1c7cSGregory Neil Shapiro refuseconnections(name, e, d, active)
21623299c2f1SGregory Neil Shapiro 	char *name;
21633299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
21643299c2f1SGregory Neil Shapiro 	int d;
216512ed1c7cSGregory Neil Shapiro 	bool active;
2166c2aa98e2SPeter Wemm {
216712ed1c7cSGregory Neil Shapiro 	static time_t lastconn[MAXDAEMONS];
216812ed1c7cSGregory Neil Shapiro 	static int conncnt[MAXDAEMONS];
216912ed1c7cSGregory Neil Shapiro 
217012ed1c7cSGregory Neil Shapiro #if XLA
2171c2aa98e2SPeter Wemm 	if (!xla_smtp_ok())
217212ed1c7cSGregory Neil Shapiro 		return true;
21733299c2f1SGregory Neil Shapiro #endif /* XLA */
2174c2aa98e2SPeter Wemm 
217512ed1c7cSGregory Neil Shapiro 	if (ConnRateThrottle > 0)
217612ed1c7cSGregory Neil Shapiro 	{
217712ed1c7cSGregory Neil Shapiro 		time_t now;
217812ed1c7cSGregory Neil Shapiro 
217912ed1c7cSGregory Neil Shapiro 		now = curtime();
218012ed1c7cSGregory Neil Shapiro 		if (active)
218112ed1c7cSGregory Neil Shapiro 		{
218212ed1c7cSGregory Neil Shapiro 			if (now != lastconn[d])
218312ed1c7cSGregory Neil Shapiro 			{
218412ed1c7cSGregory Neil Shapiro 				lastconn[d] = now;
218512ed1c7cSGregory Neil Shapiro 				conncnt[d] = 1;
218612ed1c7cSGregory Neil Shapiro 			}
218712ed1c7cSGregory Neil Shapiro 			else if (conncnt[d]++ > ConnRateThrottle)
218812ed1c7cSGregory Neil Shapiro 			{
218912ed1c7cSGregory Neil Shapiro #define D_MSG_CRT "deferring connections on daemon %s: %d per second"
219012ed1c7cSGregory Neil Shapiro 				/* sleep to flatten out connection load */
219112ed1c7cSGregory Neil Shapiro 				sm_setproctitle(true, e, D_MSG_CRT,
219212ed1c7cSGregory Neil Shapiro 						name, ConnRateThrottle);
219312ed1c7cSGregory Neil Shapiro 				if (LogLevel > 8)
219412ed1c7cSGregory Neil Shapiro 					sm_syslog(LOG_INFO, NOQID, D_MSG_CRT,
219512ed1c7cSGregory Neil Shapiro 						  name, ConnRateThrottle);
219612ed1c7cSGregory Neil Shapiro 				(void) sleep(1);
219712ed1c7cSGregory Neil Shapiro 			}
219812ed1c7cSGregory Neil Shapiro 		}
219912ed1c7cSGregory Neil Shapiro 		else if (now != lastconn[d])
220012ed1c7cSGregory Neil Shapiro 			conncnt[d] = 0;
220112ed1c7cSGregory Neil Shapiro 	}
220212ed1c7cSGregory Neil Shapiro 
220312ed1c7cSGregory Neil Shapiro 	sm_getla();
22043299c2f1SGregory Neil Shapiro 	if (RefuseLA > 0 && CurrentLA >= RefuseLA)
2205c2aa98e2SPeter Wemm 	{
220612ed1c7cSGregory Neil Shapiro # define R_MSG_LA "rejecting connections on daemon %s: load average: %d"
220712ed1c7cSGregory Neil Shapiro 		sm_setproctitle(true, e, R_MSG_LA, name, CurrentLA);
220812ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8)
220912ed1c7cSGregory Neil Shapiro 			sm_syslog(LOG_INFO, NOQID, R_MSG_LA, name, CurrentLA);
221012ed1c7cSGregory Neil Shapiro 		return true;
221112ed1c7cSGregory Neil Shapiro 	}
221212ed1c7cSGregory Neil Shapiro 
221312ed1c7cSGregory Neil Shapiro 	if (DelayLA > 0 && CurrentLA >= DelayLA)
221412ed1c7cSGregory Neil Shapiro 	{
221512ed1c7cSGregory Neil Shapiro 		time_t now;
221612ed1c7cSGregory Neil Shapiro 		static time_t log_delay = (time_t) 0;
221712ed1c7cSGregory Neil Shapiro 
221812ed1c7cSGregory Neil Shapiro # define MIN_DELAY_LOG	90	/* wait before logging this again */
221912ed1c7cSGregory Neil Shapiro # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d"
222012ed1c7cSGregory Neil Shapiro 		/* sleep to flatten out connection load */
222112ed1c7cSGregory Neil Shapiro 		sm_setproctitle(true, e, D_MSG_LA, name, DelayLA);
222212ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8 && (now = curtime()) > log_delay)
222312ed1c7cSGregory Neil Shapiro 		{
222412ed1c7cSGregory Neil Shapiro 			sm_syslog(LOG_INFO, NOQID, D_MSG_LA,
222512ed1c7cSGregory Neil Shapiro 				  name, CurrentLA, DelayLA);
222612ed1c7cSGregory Neil Shapiro 			log_delay = now + MIN_DELAY_LOG;
222712ed1c7cSGregory Neil Shapiro 		}
222812ed1c7cSGregory Neil Shapiro 		(void) sleep(1);
2229c2aa98e2SPeter Wemm 	}
2230c2aa98e2SPeter Wemm 
2231c2aa98e2SPeter Wemm 	if (MaxChildren > 0 && CurChildren >= MaxChildren)
2232c2aa98e2SPeter Wemm 	{
2233c2aa98e2SPeter Wemm 		proc_list_probe();
2234c2aa98e2SPeter Wemm 		if (CurChildren >= MaxChildren)
2235c2aa98e2SPeter Wemm 		{
223612ed1c7cSGregory Neil Shapiro #define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d"
223712ed1c7cSGregory Neil Shapiro 			sm_setproctitle(true, e, R_MSG_CHILD,
22383299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
223912ed1c7cSGregory Neil Shapiro 			if (LogLevel > 8)
224012ed1c7cSGregory Neil Shapiro 				sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD,
22413299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
224212ed1c7cSGregory Neil Shapiro 			return true;
2243c2aa98e2SPeter Wemm 		}
2244c2aa98e2SPeter Wemm 	}
224512ed1c7cSGregory Neil Shapiro 	return false;
2246c2aa98e2SPeter Wemm }
224712ed1c7cSGregory Neil Shapiro /*
2248c2aa98e2SPeter Wemm **  SETPROCTITLE -- set process title for ps
2249c2aa98e2SPeter Wemm **
2250c2aa98e2SPeter Wemm **	Parameters:
2251c2aa98e2SPeter Wemm **		fmt -- a printf style format string.
2252c2aa98e2SPeter Wemm **		a, b, c -- possible parameters to fmt.
2253c2aa98e2SPeter Wemm **
2254c2aa98e2SPeter Wemm **	Returns:
2255c2aa98e2SPeter Wemm **		none.
2256c2aa98e2SPeter Wemm **
2257c2aa98e2SPeter Wemm **	Side Effects:
2258c2aa98e2SPeter Wemm **		Clobbers argv of our main procedure so ps(1) will
2259c2aa98e2SPeter Wemm **		display the title.
2260c2aa98e2SPeter Wemm */
2261c2aa98e2SPeter Wemm 
2262c2aa98e2SPeter Wemm #define SPT_NONE	0	/* don't use it at all */
2263c2aa98e2SPeter Wemm #define SPT_REUSEARGV	1	/* cover argv with title information */
2264c2aa98e2SPeter Wemm #define SPT_BUILTIN	2	/* use libc builtin */
2265c2aa98e2SPeter Wemm #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
2266c2aa98e2SPeter Wemm #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
2267c2aa98e2SPeter Wemm #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
2268c2aa98e2SPeter Wemm #define SPT_SCO		6	/* write kernel u. area */
2269c2aa98e2SPeter Wemm #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
2270c2aa98e2SPeter Wemm 
2271c2aa98e2SPeter Wemm #ifndef SPT_TYPE
2272c2aa98e2SPeter Wemm # define SPT_TYPE	SPT_REUSEARGV
22733299c2f1SGregory Neil Shapiro #endif /* ! SPT_TYPE */
22743299c2f1SGregory Neil Shapiro 
2275c2aa98e2SPeter Wemm 
2276c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
2277c2aa98e2SPeter Wemm 
2278c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT
2279c2aa98e2SPeter Wemm #  include <sys/pstat.h>
22803299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */
2281c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS
2282c2aa98e2SPeter Wemm #  include <machine/vmparam.h>
2283c2aa98e2SPeter Wemm #  include <sys/exec.h>
2284c2aa98e2SPeter Wemm #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
2285c2aa98e2SPeter Wemm #   undef SPT_TYPE
2286c2aa98e2SPeter Wemm #   define SPT_TYPE	SPT_REUSEARGV
22873299c2f1SGregory Neil Shapiro #  else /* ! PS_STRINGS */
2288c2aa98e2SPeter Wemm #   ifndef NKPDE			/* FreeBSD 2.0 */
2289c2aa98e2SPeter Wemm #    define NKPDE 63
2290c2aa98e2SPeter Wemm typedef unsigned int	*pt_entry_t;
22913299c2f1SGregory Neil Shapiro #   endif /* ! NKPDE */
22923299c2f1SGregory Neil Shapiro #  endif /* ! PS_STRINGS */
22933299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */
2294c2aa98e2SPeter Wemm 
2295c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
2296c2aa98e2SPeter Wemm #  define SETPROC_STATIC	static
22973299c2f1SGregory Neil Shapiro # else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2298c2aa98e2SPeter Wemm #  define SETPROC_STATIC
22993299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2300c2aa98e2SPeter Wemm 
2301c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS
2302c2aa98e2SPeter Wemm #  include <sys/sysmips.h>
2303c2aa98e2SPeter Wemm #  include <sys/sysnews.h>
23043299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SYSMIPS */
2305c2aa98e2SPeter Wemm 
2306c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO
2307c2aa98e2SPeter Wemm #  include <sys/immu.h>
2308c2aa98e2SPeter Wemm #  include <sys/dir.h>
2309c2aa98e2SPeter Wemm #  include <sys/user.h>
2310c2aa98e2SPeter Wemm #  include <sys/fs/s5param.h>
2311c2aa98e2SPeter Wemm #  if PSARGSZ > MAXLINE
2312c2aa98e2SPeter Wemm #   define SPT_BUFSIZE	PSARGSZ
23133299c2f1SGregory Neil Shapiro #  endif /* PSARGSZ > MAXLINE */
23143299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */
2315c2aa98e2SPeter Wemm 
2316c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR
2317c2aa98e2SPeter Wemm #  define SPT_PADCHAR	' '
23183299c2f1SGregory Neil Shapiro # endif /* ! SPT_PADCHAR */
2319c2aa98e2SPeter Wemm 
232076b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
232176b7bf71SPeter Wemm 
2322c2aa98e2SPeter Wemm #ifndef SPT_BUFSIZE
2323c2aa98e2SPeter Wemm # define SPT_BUFSIZE	MAXLINE
23243299c2f1SGregory Neil Shapiro #endif /* ! SPT_BUFSIZE */
2325c2aa98e2SPeter Wemm 
2326c2aa98e2SPeter Wemm /*
2327c2aa98e2SPeter Wemm **  Pointers for setproctitle.
2328c2aa98e2SPeter Wemm **	This allows "ps" listings to give more useful information.
2329c2aa98e2SPeter Wemm */
2330c2aa98e2SPeter Wemm 
23313299c2f1SGregory Neil Shapiro static char	**Argv = NULL;		/* pointer to argument vector */
23323299c2f1SGregory Neil Shapiro static char	*LastArgv = NULL;	/* end of argv */
23333299c2f1SGregory Neil Shapiro #if SPT_TYPE != SPT_BUILTIN
23343299c2f1SGregory Neil Shapiro static void	setproctitle __P((const char *, ...));
23353299c2f1SGregory Neil Shapiro #endif /* SPT_TYPE != SPT_BUILTIN */
2336c2aa98e2SPeter Wemm 
2337c2aa98e2SPeter Wemm void
2338c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp)
2339c2aa98e2SPeter Wemm 	int argc;
2340c2aa98e2SPeter Wemm 	char **argv;
2341c2aa98e2SPeter Wemm 	char **envp;
2342c2aa98e2SPeter Wemm {
234312ed1c7cSGregory Neil Shapiro 	register int i;
2344c2aa98e2SPeter Wemm 	extern char **environ;
2345c2aa98e2SPeter Wemm 
2346c2aa98e2SPeter Wemm 	/*
2347c2aa98e2SPeter Wemm 	**  Move the environment so setproctitle can use the space at
2348c2aa98e2SPeter Wemm 	**  the top of memory.
2349c2aa98e2SPeter Wemm 	*/
2350c2aa98e2SPeter Wemm 
2351c2aa98e2SPeter Wemm 	for (i = 0; envp[i] != NULL; i++)
235212ed1c7cSGregory Neil Shapiro 		continue;
2353c2aa98e2SPeter Wemm 	environ = (char **) xalloc(sizeof (char *) * (i + 1));
2354c2aa98e2SPeter Wemm 	for (i = 0; envp[i] != NULL; i++)
2355c2aa98e2SPeter Wemm 		environ[i] = newstr(envp[i]);
2356c2aa98e2SPeter Wemm 	environ[i] = NULL;
2357c2aa98e2SPeter Wemm 
2358c2aa98e2SPeter Wemm 	/*
2359c2aa98e2SPeter Wemm 	**  Save start and extent of argv for setproctitle.
2360c2aa98e2SPeter Wemm 	*/
2361c2aa98e2SPeter Wemm 
2362c2aa98e2SPeter Wemm 	Argv = argv;
2363c2aa98e2SPeter Wemm 
2364c2aa98e2SPeter Wemm 	/*
2365c2aa98e2SPeter Wemm 	**  Determine how much space we can use for setproctitle.
2366c2aa98e2SPeter Wemm 	**  Use all contiguous argv and envp pointers starting at argv[0]
2367c2aa98e2SPeter Wemm 	*/
2368c2aa98e2SPeter Wemm 	for (i = 0; i < argc; i++)
2369c2aa98e2SPeter Wemm 	{
2370c2aa98e2SPeter Wemm 		if (i == 0 || LastArgv + 1 == argv[i])
2371c2aa98e2SPeter Wemm 			LastArgv = argv[i] + strlen(argv[i]);
2372c2aa98e2SPeter Wemm 	}
23733299c2f1SGregory Neil Shapiro 	for (i = 0; LastArgv != NULL && envp[i] != NULL; i++)
2374c2aa98e2SPeter Wemm 	{
2375c2aa98e2SPeter Wemm 		if (LastArgv + 1 == envp[i])
2376c2aa98e2SPeter Wemm 			LastArgv = envp[i] + strlen(envp[i]);
2377c2aa98e2SPeter Wemm 	}
2378c2aa98e2SPeter Wemm }
2379c2aa98e2SPeter Wemm 
2380c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN
2381c2aa98e2SPeter Wemm 
2382c2aa98e2SPeter Wemm /*VARARGS1*/
23833299c2f1SGregory Neil Shapiro static void
2384c2aa98e2SPeter Wemm # ifdef __STDC__
2385c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...)
23863299c2f1SGregory Neil Shapiro # else /* __STDC__ */
2387c2aa98e2SPeter Wemm setproctitle(fmt, va_alist)
2388c2aa98e2SPeter Wemm 	const char *fmt;
2389c2aa98e2SPeter Wemm 	va_dcl
23903299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
2391c2aa98e2SPeter Wemm {
2392c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE
2393c2aa98e2SPeter Wemm 	register int i;
23943299c2f1SGregory Neil Shapiro 	register char *p;
2395c2aa98e2SPeter Wemm 	SETPROC_STATIC char buf[SPT_BUFSIZE];
239612ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
2397c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2398c2aa98e2SPeter Wemm 	union pstun pst;
23993299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2400c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
240112ed1c7cSGregory Neil Shapiro 	int j;
2402c2aa98e2SPeter Wemm 	off_t seek_off;
2403c2aa98e2SPeter Wemm 	static int kmem = -1;
2404c0c4794dSGregory Neil Shapiro 	static pid_t kmempid = -1;
2405c2aa98e2SPeter Wemm 	struct user u;
24063299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2407c2aa98e2SPeter Wemm 
2408c2aa98e2SPeter Wemm 	p = buf;
2409c2aa98e2SPeter Wemm 
2410c2aa98e2SPeter Wemm 	/* print sendmail: heading for grep */
241112ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
2412c2aa98e2SPeter Wemm 	p += strlen(p);
2413c2aa98e2SPeter Wemm 
2414c2aa98e2SPeter Wemm 	/* print the argument string */
241512ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
241612ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
241712ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
2418c2aa98e2SPeter Wemm 
241912ed1c7cSGregory Neil Shapiro 	i = (int) strlen(buf);
242012ed1c7cSGregory Neil Shapiro 	if (i < 0)
242112ed1c7cSGregory Neil Shapiro 		return;
2422c2aa98e2SPeter Wemm 
2423c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2424c2aa98e2SPeter Wemm 	pst.pst_command = buf;
2425c2aa98e2SPeter Wemm 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
24263299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2427c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSSTRINGS
2428c2aa98e2SPeter Wemm 	PS_STRINGS->ps_nargvstr = 1;
2429c2aa98e2SPeter Wemm 	PS_STRINGS->ps_argvstr = buf;
24303299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSSTRINGS */
2431c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SYSMIPS
2432c2aa98e2SPeter Wemm 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
24333299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SYSMIPS */
2434c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
243512ed1c7cSGregory Neil Shapiro 	if (kmem < 0 || kmempid != CurrentPid)
2436c2aa98e2SPeter Wemm 	{
2437c2aa98e2SPeter Wemm 		if (kmem >= 0)
2438c46d91b7SGregory Neil Shapiro 			(void) close(kmem);
2439c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, O_RDWR, 0);
2440c2aa98e2SPeter Wemm 		if (kmem < 0)
2441c2aa98e2SPeter Wemm 			return;
244212ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
244312ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
244412ed1c7cSGregory Neil Shapiro 		{
244512ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
244612ed1c7cSGregory Neil Shapiro 			kmem = -1;
244712ed1c7cSGregory Neil Shapiro 			return;
244812ed1c7cSGregory Neil Shapiro 		}
244912ed1c7cSGregory Neil Shapiro 		kmempid = CurrentPid;
2450c2aa98e2SPeter Wemm 	}
2451c2aa98e2SPeter Wemm 	buf[PSARGSZ - 1] = '\0';
2452c2aa98e2SPeter Wemm 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
2453c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
2454c2aa98e2SPeter Wemm 		(void) write(kmem, buf, PSARGSZ);
24553299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2456c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_REUSEARGV
24573299c2f1SGregory Neil Shapiro 	if (LastArgv == NULL)
24583299c2f1SGregory Neil Shapiro 		return;
24593299c2f1SGregory Neil Shapiro 
2460c2aa98e2SPeter Wemm 	if (i > LastArgv - Argv[0] - 2)
2461c2aa98e2SPeter Wemm 	{
2462c2aa98e2SPeter Wemm 		i = LastArgv - Argv[0] - 2;
2463c2aa98e2SPeter Wemm 		buf[i] = '\0';
2464c2aa98e2SPeter Wemm 	}
246512ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(Argv[0], buf, i + 1);
2466c2aa98e2SPeter Wemm 	p = &Argv[0][i];
2467c2aa98e2SPeter Wemm 	while (p < LastArgv)
2468c2aa98e2SPeter Wemm 		*p++ = SPT_PADCHAR;
2469c2aa98e2SPeter Wemm 	Argv[1] = NULL;
24703299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_REUSEARGV */
2471c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_CHANGEARGV
2472c2aa98e2SPeter Wemm 	Argv[0] = buf;
2473c2aa98e2SPeter Wemm 	Argv[1] = 0;
24743299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_CHANGEARGV */
2475c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */
2476c2aa98e2SPeter Wemm }
2477c2aa98e2SPeter Wemm 
2478c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */
247912ed1c7cSGregory Neil Shapiro /*
248076b7bf71SPeter Wemm **  SM_SETPROCTITLE -- set process task and set process title for ps
248176b7bf71SPeter Wemm **
248276b7bf71SPeter Wemm **	Possibly set process status and call setproctitle() to
248376b7bf71SPeter Wemm **	change the ps display.
248476b7bf71SPeter Wemm **
248576b7bf71SPeter Wemm **	Parameters:
248676b7bf71SPeter Wemm **		status -- whether or not to store as process status
24873299c2f1SGregory Neil Shapiro **		e -- the current envelope.
248876b7bf71SPeter Wemm **		fmt -- a printf style format string.
248976b7bf71SPeter Wemm **		a, b, c -- possible parameters to fmt.
249076b7bf71SPeter Wemm **
249176b7bf71SPeter Wemm **	Returns:
249276b7bf71SPeter Wemm **		none.
249376b7bf71SPeter Wemm */
249476b7bf71SPeter Wemm 
249576b7bf71SPeter Wemm /*VARARGS2*/
249676b7bf71SPeter Wemm void
249776b7bf71SPeter Wemm #ifdef __STDC__
24983299c2f1SGregory Neil Shapiro sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
24993299c2f1SGregory Neil Shapiro #else /* __STDC__ */
25003299c2f1SGregory Neil Shapiro sm_setproctitle(status, e, fmt, va_alist)
250176b7bf71SPeter Wemm 	bool status;
25023299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
250376b7bf71SPeter Wemm 	const char *fmt;
250476b7bf71SPeter Wemm 	va_dcl
25053299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
250676b7bf71SPeter Wemm {
250776b7bf71SPeter Wemm 	char buf[SPT_BUFSIZE];
250812ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
25093299c2f1SGregory Neil Shapiro 
251076b7bf71SPeter Wemm 	/* print the argument string */
251112ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
251212ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof buf, fmt, ap);
251312ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
251476b7bf71SPeter Wemm 
251576b7bf71SPeter Wemm 	if (status)
251612ed1c7cSGregory Neil Shapiro 		proc_list_set(CurrentPid, buf);
25173299c2f1SGregory Neil Shapiro 
25183299c2f1SGregory Neil Shapiro 	if (ProcTitlePrefix != NULL)
25193299c2f1SGregory Neil Shapiro 	{
25203299c2f1SGregory Neil Shapiro 		char prefix[SPT_BUFSIZE];
25213299c2f1SGregory Neil Shapiro 
25223299c2f1SGregory Neil Shapiro 		expand(ProcTitlePrefix, prefix, sizeof prefix, e);
25233299c2f1SGregory Neil Shapiro 		setproctitle("%s: %s", prefix, buf);
25243299c2f1SGregory Neil Shapiro 	}
25253299c2f1SGregory Neil Shapiro 	else
252676b7bf71SPeter Wemm 		setproctitle("%s", buf);
252776b7bf71SPeter Wemm }
252812ed1c7cSGregory Neil Shapiro /*
2529c2aa98e2SPeter Wemm **  WAITFOR -- wait for a particular process id.
2530c2aa98e2SPeter Wemm **
2531c2aa98e2SPeter Wemm **	Parameters:
2532c2aa98e2SPeter Wemm **		pid -- process id to wait for.
2533c2aa98e2SPeter Wemm **
2534c2aa98e2SPeter Wemm **	Returns:
2535c2aa98e2SPeter Wemm **		status of pid.
2536c2aa98e2SPeter Wemm **		-1 if pid never shows up.
2537c2aa98e2SPeter Wemm **
2538c2aa98e2SPeter Wemm **	Side Effects:
2539c2aa98e2SPeter Wemm **		none.
2540c2aa98e2SPeter Wemm */
2541c2aa98e2SPeter Wemm 
2542c2aa98e2SPeter Wemm int
2543c2aa98e2SPeter Wemm waitfor(pid)
2544c2aa98e2SPeter Wemm 	pid_t pid;
2545c2aa98e2SPeter Wemm {
254612ed1c7cSGregory Neil Shapiro 	int st;
254712ed1c7cSGregory Neil Shapiro 	pid_t i;
254812ed1c7cSGregory Neil Shapiro 
254912ed1c7cSGregory Neil Shapiro 	do
255012ed1c7cSGregory Neil Shapiro 	{
255112ed1c7cSGregory Neil Shapiro 		errno = 0;
255212ed1c7cSGregory Neil Shapiro 		i = sm_wait(&st);
255312ed1c7cSGregory Neil Shapiro 		if (i > 0)
255412ed1c7cSGregory Neil Shapiro 			proc_list_drop(i, st, NULL);
255512ed1c7cSGregory Neil Shapiro 	} while ((i >= 0 || errno == EINTR) && i != pid);
255612ed1c7cSGregory Neil Shapiro 	if (i < 0)
255712ed1c7cSGregory Neil Shapiro 		return -1;
255812ed1c7cSGregory Neil Shapiro 	return st;
255912ed1c7cSGregory Neil Shapiro }
256012ed1c7cSGregory Neil Shapiro /*
256112ed1c7cSGregory Neil Shapiro **  SM_WAIT -- wait
256212ed1c7cSGregory Neil Shapiro **
256312ed1c7cSGregory Neil Shapiro **	Parameters:
256412ed1c7cSGregory Neil Shapiro **		status -- pointer to status (return value)
256512ed1c7cSGregory Neil Shapiro **
256612ed1c7cSGregory Neil Shapiro **	Returns:
256712ed1c7cSGregory Neil Shapiro **		pid
256812ed1c7cSGregory Neil Shapiro */
256912ed1c7cSGregory Neil Shapiro 
257012ed1c7cSGregory Neil Shapiro pid_t
257112ed1c7cSGregory Neil Shapiro sm_wait(status)
257212ed1c7cSGregory Neil Shapiro 	int *status;
257312ed1c7cSGregory Neil Shapiro {
2574c2aa98e2SPeter Wemm # ifdef WAITUNION
2575c2aa98e2SPeter Wemm 	union wait st;
25763299c2f1SGregory Neil Shapiro # else /* WAITUNION */
2577c2aa98e2SPeter Wemm 	auto int st;
25783299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
2579c2aa98e2SPeter Wemm 	pid_t i;
2580c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2581c2aa98e2SPeter Wemm 	int savesig;
25823299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2583c2aa98e2SPeter Wemm 
2584c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
258512ed1c7cSGregory Neil Shapiro 	savesig = sm_releasesignal(SIGCHLD);
25863299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2587c2aa98e2SPeter Wemm 	i = wait(&st);
2588c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2589c2aa98e2SPeter Wemm 	if (savesig > 0)
259012ed1c7cSGregory Neil Shapiro 		sm_blocksignal(SIGCHLD);
25913299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2592c2aa98e2SPeter Wemm # ifdef WAITUNION
259312ed1c7cSGregory Neil Shapiro 	*status = st.w_status;
25943299c2f1SGregory Neil Shapiro # else /* WAITUNION */
259512ed1c7cSGregory Neil Shapiro 	*status = st;
25963299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
259712ed1c7cSGregory Neil Shapiro 	return i;
2598c2aa98e2SPeter Wemm }
259912ed1c7cSGregory Neil Shapiro /*
2600c2aa98e2SPeter Wemm **  REAPCHILD -- pick up the body of my child, lest it become a zombie
2601c2aa98e2SPeter Wemm **
2602c2aa98e2SPeter Wemm **	Parameters:
2603c2aa98e2SPeter Wemm **		sig -- the signal that got us here (unused).
2604c2aa98e2SPeter Wemm **
2605c2aa98e2SPeter Wemm **	Returns:
2606c2aa98e2SPeter Wemm **		none.
2607c2aa98e2SPeter Wemm **
2608c2aa98e2SPeter Wemm **	Side Effects:
2609c2aa98e2SPeter Wemm **		Picks up extant zombies.
26103299c2f1SGregory Neil Shapiro **		Control socket exits may restart/shutdown daemon.
2611c0c4794dSGregory Neil Shapiro **
2612c0c4794dSGregory Neil Shapiro **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
2613c0c4794dSGregory Neil Shapiro **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
2614c0c4794dSGregory Neil Shapiro **		DOING.
2615c2aa98e2SPeter Wemm */
2616c2aa98e2SPeter Wemm 
26173299c2f1SGregory Neil Shapiro /* ARGSUSED0 */
2618c2aa98e2SPeter Wemm SIGFUNC_DECL
2619c2aa98e2SPeter Wemm reapchild(sig)
2620c2aa98e2SPeter Wemm 	int sig;
2621c2aa98e2SPeter Wemm {
262212ed1c7cSGregory Neil Shapiro 	int m = 0;
26233299c2f1SGregory Neil Shapiro 	int save_errno = errno;
26243299c2f1SGregory Neil Shapiro 	int st;
2625c2aa98e2SPeter Wemm 	pid_t pid;
26263299c2f1SGregory Neil Shapiro # if HASWAITPID
2627c2aa98e2SPeter Wemm 	auto int status;
2628c2aa98e2SPeter Wemm 	int count;
2629c2aa98e2SPeter Wemm 
2630c2aa98e2SPeter Wemm 	count = 0;
2631c2aa98e2SPeter Wemm 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2632c2aa98e2SPeter Wemm 	{
26333299c2f1SGregory Neil Shapiro 		st = status;
2634c2aa98e2SPeter Wemm 		if (count++ > 1000)
2635c2aa98e2SPeter Wemm 			break;
26363299c2f1SGregory Neil Shapiro # else /* HASWAITPID */
2637c2aa98e2SPeter Wemm #  ifdef WNOHANG
263812ed1c7cSGregory Neil Shapiro 	union wait status;
263912ed1c7cSGregory Neil Shapiro 
2640c2aa98e2SPeter Wemm 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
26413299c2f1SGregory Neil Shapiro 	{
26423299c2f1SGregory Neil Shapiro 		st = status.w_status;
2643c2aa98e2SPeter Wemm #  else /* WNOHANG */
264412ed1c7cSGregory Neil Shapiro 	auto int status;
264512ed1c7cSGregory Neil Shapiro 
2646c2aa98e2SPeter Wemm 	/*
2647c2aa98e2SPeter Wemm 	**  Catch one zombie -- we will be re-invoked (we hope) if there
2648c2aa98e2SPeter Wemm 	**  are more.  Unreliable signals probably break this, but this
2649c2aa98e2SPeter Wemm 	**  is the "old system" situation -- waitpid or wait3 are to be
2650c2aa98e2SPeter Wemm 	**  strongly preferred.
2651c2aa98e2SPeter Wemm 	*/
2652c2aa98e2SPeter Wemm 
2653c2aa98e2SPeter Wemm 	if ((pid = wait(&status)) > 0)
26543299c2f1SGregory Neil Shapiro 	{
26553299c2f1SGregory Neil Shapiro 		st = status;
2656c2aa98e2SPeter Wemm #  endif /* WNOHANG */
26573299c2f1SGregory Neil Shapiro # endif /* HASWAITPID */
26583299c2f1SGregory Neil Shapiro 		/* Drop PID and check if it was a control socket child */
265912ed1c7cSGregory Neil Shapiro 		proc_list_drop(pid, st, NULL);
266012ed1c7cSGregory Neil Shapiro 		CurRunners -= m; /* Update */
26613299c2f1SGregory Neil Shapiro 	}
2662c0c4794dSGregory Neil Shapiro 	FIX_SYSV_SIGNAL(sig, reapchild);
26633299c2f1SGregory Neil Shapiro 	errno = save_errno;
2664c2aa98e2SPeter Wemm 	return SIGFUNC_RETURN;
2665c2aa98e2SPeter Wemm }
2666c2aa98e2SPeter Wemm /*
2667c2aa98e2SPeter Wemm **  GETDTABLESIZE -- return number of file descriptors
2668c2aa98e2SPeter Wemm **
2669c2aa98e2SPeter Wemm **	Only on non-BSD systems
2670c2aa98e2SPeter Wemm **
2671c2aa98e2SPeter Wemm **	Parameters:
2672c2aa98e2SPeter Wemm **		none
2673c2aa98e2SPeter Wemm **
2674c2aa98e2SPeter Wemm **	Returns:
2675c2aa98e2SPeter Wemm **		size of file descriptor table
2676c2aa98e2SPeter Wemm **
2677c2aa98e2SPeter Wemm **	Side Effects:
2678c2aa98e2SPeter Wemm **		none
2679c2aa98e2SPeter Wemm */
2680c2aa98e2SPeter Wemm 
2681c2aa98e2SPeter Wemm #ifdef SOLARIS
2682c2aa98e2SPeter Wemm # include <sys/resource.h>
26833299c2f1SGregory Neil Shapiro #endif /* SOLARIS */
2684c2aa98e2SPeter Wemm 
2685c2aa98e2SPeter Wemm int
2686c2aa98e2SPeter Wemm getdtsize()
2687c2aa98e2SPeter Wemm {
2688c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
2689c2aa98e2SPeter Wemm 	struct rlimit rl;
2690c2aa98e2SPeter Wemm 
2691c2aa98e2SPeter Wemm 	if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2692c2aa98e2SPeter Wemm 		return rl.rlim_cur;
26933299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
2694c2aa98e2SPeter Wemm 
26953299c2f1SGregory Neil Shapiro # if HASGETDTABLESIZE
2696c2aa98e2SPeter Wemm 	return getdtablesize();
26973299c2f1SGregory Neil Shapiro # else /* HASGETDTABLESIZE */
2698c2aa98e2SPeter Wemm #  ifdef _SC_OPEN_MAX
2699c2aa98e2SPeter Wemm 	return sysconf(_SC_OPEN_MAX);
27003299c2f1SGregory Neil Shapiro #  else /* _SC_OPEN_MAX */
2701c2aa98e2SPeter Wemm 	return NOFILE;
27023299c2f1SGregory Neil Shapiro #  endif /* _SC_OPEN_MAX */
27033299c2f1SGregory Neil Shapiro # endif /* HASGETDTABLESIZE */
2704c2aa98e2SPeter Wemm }
270512ed1c7cSGregory Neil Shapiro /*
2706c2aa98e2SPeter Wemm **  UNAME -- get the UUCP name of this system.
2707c2aa98e2SPeter Wemm */
2708c2aa98e2SPeter Wemm 
27093299c2f1SGregory Neil Shapiro #if !HASUNAME
2710c2aa98e2SPeter Wemm 
2711c2aa98e2SPeter Wemm int
2712c2aa98e2SPeter Wemm uname(name)
2713c2aa98e2SPeter Wemm 	struct utsname *name;
2714c2aa98e2SPeter Wemm {
271512ed1c7cSGregory Neil Shapiro 	SM_FILE_T *file;
2716c2aa98e2SPeter Wemm 	char *n;
2717c2aa98e2SPeter Wemm 
2718c2aa98e2SPeter Wemm 	name->nodename[0] = '\0';
2719c2aa98e2SPeter Wemm 
2720c2aa98e2SPeter Wemm 	/* try /etc/whoami -- one line with the node name */
272112ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami",
272212ed1c7cSGregory Neil Shapiro 			       SM_IO_RDONLY, NULL)) != NULL)
2723c2aa98e2SPeter Wemm 	{
272412ed1c7cSGregory Neil Shapiro 		(void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename,
272512ed1c7cSGregory Neil Shapiro 				   NODE_LENGTH + 1);
272612ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2727c2aa98e2SPeter Wemm 		n = strchr(name->nodename, '\n');
2728c2aa98e2SPeter Wemm 		if (n != NULL)
2729c2aa98e2SPeter Wemm 			*n = '\0';
2730c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
27313299c2f1SGregory Neil Shapiro 			return 0;
2732c2aa98e2SPeter Wemm 	}
2733c2aa98e2SPeter Wemm 
2734c2aa98e2SPeter Wemm 	/* try /usr/include/whoami.h -- has a #define somewhere */
273512ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT,
273612ed1c7cSGregory Neil Shapiro 			       "/usr/include/whoami.h", SM_IO_RDONLY, NULL))
273712ed1c7cSGregory Neil Shapiro 	    != NULL)
2738c2aa98e2SPeter Wemm 	{
2739c2aa98e2SPeter Wemm 		char buf[MAXLINE];
2740c2aa98e2SPeter Wemm 
274112ed1c7cSGregory Neil Shapiro 		while (sm_io_fgets(file, SM_TIME_DEFAULT, buf, MAXLINE) != NULL)
27423299c2f1SGregory Neil Shapiro 		{
274312ed1c7cSGregory Neil Shapiro 			if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"",
2744c2aa98e2SPeter Wemm 					NODE_LENGTH, name->nodename) > 0)
2745c2aa98e2SPeter Wemm 				break;
27463299c2f1SGregory Neil Shapiro 		}
274712ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2748c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
27493299c2f1SGregory Neil Shapiro 			return 0;
2750c2aa98e2SPeter Wemm 	}
2751c2aa98e2SPeter Wemm 
27523299c2f1SGregory Neil Shapiro #  if 0
2753c2aa98e2SPeter Wemm 	/*
2754c2aa98e2SPeter Wemm 	**  Popen is known to have security holes.
2755c2aa98e2SPeter Wemm 	*/
2756c2aa98e2SPeter Wemm 
2757c2aa98e2SPeter Wemm 	/* try uuname -l to return local name */
2758c2aa98e2SPeter Wemm 	if ((file = popen("uuname -l", "r")) != NULL)
2759c2aa98e2SPeter Wemm 	{
276012ed1c7cSGregory Neil Shapiro 		(void) sm_io_fgets(file, SM_TIME_DEFAULT, name,
276112ed1c7cSGregory Neil Shapiro 				   NODE_LENGTH + 1);
2762c2aa98e2SPeter Wemm 		(void) pclose(file);
2763c2aa98e2SPeter Wemm 		n = strchr(name, '\n');
2764c2aa98e2SPeter Wemm 		if (n != NULL)
2765c2aa98e2SPeter Wemm 			*n = '\0';
2766c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
27673299c2f1SGregory Neil Shapiro 			return 0;
2768c2aa98e2SPeter Wemm 	}
27693299c2f1SGregory Neil Shapiro #  endif /* 0 */
2770c2aa98e2SPeter Wemm 
27713299c2f1SGregory Neil Shapiro 	return -1;
2772c2aa98e2SPeter Wemm }
27733299c2f1SGregory Neil Shapiro #endif /* !HASUNAME */
277412ed1c7cSGregory Neil Shapiro /*
2775c2aa98e2SPeter Wemm **  INITGROUPS -- initialize groups
2776c2aa98e2SPeter Wemm **
2777c2aa98e2SPeter Wemm **	Stub implementation for System V style systems
2778c2aa98e2SPeter Wemm */
2779c2aa98e2SPeter Wemm 
27803299c2f1SGregory Neil Shapiro #if !HASINITGROUPS
2781c2aa98e2SPeter Wemm 
2782c2aa98e2SPeter Wemm initgroups(name, basegid)
2783c2aa98e2SPeter Wemm 	char *name;
2784c2aa98e2SPeter Wemm 	int basegid;
2785c2aa98e2SPeter Wemm {
2786c2aa98e2SPeter Wemm 	return 0;
2787c2aa98e2SPeter Wemm }
2788c2aa98e2SPeter Wemm 
27893299c2f1SGregory Neil Shapiro #endif /* !HASINITGROUPS */
279012ed1c7cSGregory Neil Shapiro /*
2791c2aa98e2SPeter Wemm **  SETGROUPS -- set group list
2792c2aa98e2SPeter Wemm **
2793c2aa98e2SPeter Wemm **	Stub implementation for systems that don't have group lists
2794c2aa98e2SPeter Wemm */
2795c2aa98e2SPeter Wemm 
2796c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX
2797c2aa98e2SPeter Wemm 
2798c2aa98e2SPeter Wemm int
2799c2aa98e2SPeter Wemm setgroups(ngroups, grouplist)
2800c2aa98e2SPeter Wemm 	int ngroups;
2801c2aa98e2SPeter Wemm 	GIDSET_T grouplist[];
2802c2aa98e2SPeter Wemm {
2803c2aa98e2SPeter Wemm 	return 0;
2804c2aa98e2SPeter Wemm }
2805c2aa98e2SPeter Wemm 
28063299c2f1SGregory Neil Shapiro #endif /* ! NGROUPS_MAX */
280712ed1c7cSGregory Neil Shapiro /*
2808c2aa98e2SPeter Wemm **  SETSID -- set session id (for non-POSIX systems)
2809c2aa98e2SPeter Wemm */
2810c2aa98e2SPeter Wemm 
28113299c2f1SGregory Neil Shapiro #if !HASSETSID
2812c2aa98e2SPeter Wemm 
2813c2aa98e2SPeter Wemm pid_t
2814c2aa98e2SPeter Wemm setsid __P ((void))
2815c2aa98e2SPeter Wemm {
2816c2aa98e2SPeter Wemm #  ifdef TIOCNOTTY
2817c2aa98e2SPeter Wemm 	int fd;
2818c2aa98e2SPeter Wemm 
2819c2aa98e2SPeter Wemm 	fd = open("/dev/tty", O_RDWR, 0);
2820c2aa98e2SPeter Wemm 	if (fd >= 0)
2821c2aa98e2SPeter Wemm 	{
2822d995d2baSGregory Neil Shapiro 		(void) ioctl(fd, TIOCNOTTY, (char *) 0);
2823c2aa98e2SPeter Wemm 		(void) close(fd);
2824c2aa98e2SPeter Wemm 	}
2825c2aa98e2SPeter Wemm #  endif /* TIOCNOTTY */
2826c2aa98e2SPeter Wemm #  ifdef SYS5SETPGRP
2827c2aa98e2SPeter Wemm 	return setpgrp();
28283299c2f1SGregory Neil Shapiro #  else /* SYS5SETPGRP */
282912ed1c7cSGregory Neil Shapiro 	return setpgid(0, CurrentPid);
28303299c2f1SGregory Neil Shapiro #  endif /* SYS5SETPGRP */
2831c2aa98e2SPeter Wemm }
2832c2aa98e2SPeter Wemm 
28333299c2f1SGregory Neil Shapiro #endif /* !HASSETSID */
283412ed1c7cSGregory Neil Shapiro /*
2835c2aa98e2SPeter Wemm **  FSYNC -- dummy fsync
2836c2aa98e2SPeter Wemm */
2837c2aa98e2SPeter Wemm 
28383299c2f1SGregory Neil Shapiro #if NEEDFSYNC
2839c2aa98e2SPeter Wemm 
2840c2aa98e2SPeter Wemm fsync(fd)
2841c2aa98e2SPeter Wemm 	int fd;
2842c2aa98e2SPeter Wemm {
2843c2aa98e2SPeter Wemm # ifdef O_SYNC
2844c2aa98e2SPeter Wemm 	return fcntl(fd, F_SETFL, O_SYNC);
28453299c2f1SGregory Neil Shapiro # else /* O_SYNC */
2846c2aa98e2SPeter Wemm 	/* nothing we can do */
2847c2aa98e2SPeter Wemm 	return 0;
28483299c2f1SGregory Neil Shapiro # endif /* O_SYNC */
2849c2aa98e2SPeter Wemm }
2850c2aa98e2SPeter Wemm 
28513299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
285212ed1c7cSGregory Neil Shapiro /*
2853c2aa98e2SPeter Wemm **  DGUX_INET_ADDR -- inet_addr for DG/UX
2854c2aa98e2SPeter Wemm **
2855c2aa98e2SPeter Wemm **	Data General DG/UX version of inet_addr returns a struct in_addr
2856c2aa98e2SPeter Wemm **	instead of a long.  This patches things.  Only needed on versions
2857c2aa98e2SPeter Wemm **	prior to 5.4.3.
2858c2aa98e2SPeter Wemm */
2859c2aa98e2SPeter Wemm 
2860c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2
2861c2aa98e2SPeter Wemm 
2862c2aa98e2SPeter Wemm # undef inet_addr
2863c2aa98e2SPeter Wemm 
2864c2aa98e2SPeter Wemm long
2865c2aa98e2SPeter Wemm dgux_inet_addr(host)
2866c2aa98e2SPeter Wemm 	char *host;
2867c2aa98e2SPeter Wemm {
2868c2aa98e2SPeter Wemm 	struct in_addr haddr;
2869c2aa98e2SPeter Wemm 
2870c2aa98e2SPeter Wemm 	haddr = inet_addr(host);
2871c2aa98e2SPeter Wemm 	return haddr.s_addr;
2872c2aa98e2SPeter Wemm }
2873c2aa98e2SPeter Wemm 
28743299c2f1SGregory Neil Shapiro #endif /* DGUX_5_4_2 */
287512ed1c7cSGregory Neil Shapiro /*
2876c2aa98e2SPeter Wemm **  GETOPT -- for old systems or systems with bogus implementations
2877c2aa98e2SPeter Wemm */
2878c2aa98e2SPeter Wemm 
287912ed1c7cSGregory Neil Shapiro #if !SM_CONF_GETOPT
2880c2aa98e2SPeter Wemm 
2881c2aa98e2SPeter Wemm /*
2882c2aa98e2SPeter Wemm  * Copyright (c) 1985 Regents of the University of California.
2883c2aa98e2SPeter Wemm  * All rights reserved.  The Berkeley software License Agreement
2884c2aa98e2SPeter Wemm  * specifies the terms and conditions for redistribution.
2885c2aa98e2SPeter Wemm  */
2886c2aa98e2SPeter Wemm 
2887c2aa98e2SPeter Wemm 
2888c2aa98e2SPeter Wemm /*
2889c2aa98e2SPeter Wemm **  this version hacked to add `atend' flag to allow state machine
2890c2aa98e2SPeter Wemm **  to reset if invoked by the program to scan args for a 2nd time
2891c2aa98e2SPeter Wemm */
2892c2aa98e2SPeter Wemm 
2893c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
2894c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c	4.3 (Berkeley) 3/9/86";
28953299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
2896c2aa98e2SPeter Wemm 
2897c2aa98e2SPeter Wemm /*
289812ed1c7cSGregory Neil Shapiro **  get option letter from argument vector
2899c2aa98e2SPeter Wemm */
2900c2aa98e2SPeter Wemm # ifdef _CONVEX_SOURCE
2901c2aa98e2SPeter Wemm extern int	optind, opterr, optopt;
2902c2aa98e2SPeter Wemm extern char	*optarg;
29033299c2f1SGregory Neil Shapiro # else /* _CONVEX_SOURCE */
2904c2aa98e2SPeter Wemm int	opterr = 1;		/* if error message should be printed */
2905c2aa98e2SPeter Wemm int	optind = 1;		/* index into parent argv vector */
2906c2aa98e2SPeter Wemm int	optopt = 0;		/* character checked for validity */
2907c2aa98e2SPeter Wemm char	*optarg = NULL;		/* argument associated with option */
29083299c2f1SGregory Neil Shapiro # endif /* _CONVEX_SOURCE */
2909c2aa98e2SPeter Wemm 
2910c2aa98e2SPeter Wemm # define BADCH	(int)'?'
2911c2aa98e2SPeter Wemm # define EMSG	""
291212ed1c7cSGregory Neil Shapiro # define tell(s)	if (opterr) \
291312ed1c7cSGregory Neil Shapiro 			{sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \
291412ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \
291512ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \
291612ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \
291712ed1c7cSGregory Neil Shapiro 			return BADCH;}
2918c2aa98e2SPeter Wemm 
2919c2aa98e2SPeter Wemm int
2920c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr)
2921c2aa98e2SPeter Wemm 	int		nargc;
2922c2aa98e2SPeter Wemm 	char *const	*nargv;
2923c2aa98e2SPeter Wemm 	const char	*ostr;
2924c2aa98e2SPeter Wemm {
2925c2aa98e2SPeter Wemm 	static char	*place = EMSG;	/* option letter processing */
2926c2aa98e2SPeter Wemm 	static char	atend = 0;
2927c2aa98e2SPeter Wemm 	register char	*oli = NULL;	/* option letter list index */
2928c2aa98e2SPeter Wemm 
2929c2aa98e2SPeter Wemm 	if (atend) {
2930c2aa98e2SPeter Wemm 		atend = 0;
2931c2aa98e2SPeter Wemm 		place = EMSG;
2932c2aa98e2SPeter Wemm 	}
2933c2aa98e2SPeter Wemm 	if(!*place) {			/* update scanning pointer */
2934c2aa98e2SPeter Wemm 		if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
2935c2aa98e2SPeter Wemm 			atend++;
2936c2aa98e2SPeter Wemm 			return -1;
2937c2aa98e2SPeter Wemm 		}
2938c2aa98e2SPeter Wemm 		if (*place == '-') {	/* found "--" */
2939c2aa98e2SPeter Wemm 			++optind;
2940c2aa98e2SPeter Wemm 			atend++;
2941c2aa98e2SPeter Wemm 			return -1;
2942c2aa98e2SPeter Wemm 		}
2943c2aa98e2SPeter Wemm 	}				/* option letter okay? */
2944c2aa98e2SPeter Wemm 	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
2945c2aa98e2SPeter Wemm 		if (!*place) ++optind;
2946c2aa98e2SPeter Wemm 		tell(": illegal option -- ");
2947c2aa98e2SPeter Wemm 	}
2948c2aa98e2SPeter Wemm 	if (oli && *++oli != ':') {		/* don't need argument */
2949c2aa98e2SPeter Wemm 		optarg = NULL;
2950c2aa98e2SPeter Wemm 		if (!*place) ++optind;
2951c2aa98e2SPeter Wemm 	}
2952c2aa98e2SPeter Wemm 	else {				/* need an argument */
2953c2aa98e2SPeter Wemm 		if (*place) optarg = place;	/* no white space */
2954c2aa98e2SPeter Wemm 		else if (nargc <= ++optind) {	/* no arg */
2955c2aa98e2SPeter Wemm 			place = EMSG;
2956c2aa98e2SPeter Wemm 			tell(": option requires an argument -- ");
2957c2aa98e2SPeter Wemm 		}
2958c2aa98e2SPeter Wemm 		else optarg = nargv[optind];	/* white space */
2959c2aa98e2SPeter Wemm 		place = EMSG;
2960c2aa98e2SPeter Wemm 		++optind;
2961c2aa98e2SPeter Wemm 	}
296212ed1c7cSGregory Neil Shapiro 	return optopt;			/* dump back option letter */
2963c2aa98e2SPeter Wemm }
2964c2aa98e2SPeter Wemm 
296512ed1c7cSGregory Neil Shapiro #endif /* !SM_CONF_GETOPT */
296612ed1c7cSGregory Neil Shapiro /*
2967c2aa98e2SPeter Wemm **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
2968c2aa98e2SPeter Wemm **
2969c2aa98e2SPeter Wemm **	Parameters:
2970c2aa98e2SPeter Wemm **		user -- the name of the user we are checking.
2971c2aa98e2SPeter Wemm **		shell -- the user's shell from /etc/passwd
2972c2aa98e2SPeter Wemm **
2973c2aa98e2SPeter Wemm **	Returns:
297412ed1c7cSGregory Neil Shapiro **		true -- if it is ok to use this for unrestricted access.
297512ed1c7cSGregory Neil Shapiro **		false -- if the shell is restricted.
2976c2aa98e2SPeter Wemm */
2977c2aa98e2SPeter Wemm 
2978c2aa98e2SPeter Wemm #if !HASGETUSERSHELL
2979c2aa98e2SPeter Wemm 
2980c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS
2981c2aa98e2SPeter Wemm #  define _PATH_SHELLS	"/etc/shells"
29823299c2f1SGregory Neil Shapiro # endif /* ! _PATH_SHELLS */
2983c2aa98e2SPeter Wemm 
2984c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
2985c2aa98e2SPeter Wemm #  include <userconf.h>
2986c2aa98e2SPeter Wemm #  if _AIX4 >= 40200
2987c2aa98e2SPeter Wemm #   include <userpw.h>
29883299c2f1SGregory Neil Shapiro #  endif /* _AIX4 >= 40200 */
2989c2aa98e2SPeter Wemm #  include <usersec.h>
29903299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
2991c2aa98e2SPeter Wemm 
29923299c2f1SGregory Neil Shapiro static char	*DefaultUserShells[] =
2993c2aa98e2SPeter Wemm {
2994c2aa98e2SPeter Wemm 	"/bin/sh",		/* standard shell */
299512ed1c7cSGregory Neil Shapiro # ifdef MPE
299612ed1c7cSGregory Neil Shapiro 	"/SYS/PUB/CI",
299712ed1c7cSGregory Neil Shapiro # else /* MPE */
2998c2aa98e2SPeter Wemm 	"/usr/bin/sh",
2999c2aa98e2SPeter Wemm 	"/bin/csh",		/* C shell */
3000c2aa98e2SPeter Wemm 	"/usr/bin/csh",
300112ed1c7cSGregory Neil Shapiro # endif /* MPE */
3002c2aa98e2SPeter Wemm # ifdef __hpux
3003c2aa98e2SPeter Wemm #  ifdef V4FS
3004c2aa98e2SPeter Wemm 	"/usr/bin/rsh",		/* restricted Bourne shell */
3005c2aa98e2SPeter Wemm 	"/usr/bin/ksh",		/* Korn shell */
3006c2aa98e2SPeter Wemm 	"/usr/bin/rksh",	/* restricted Korn shell */
3007c2aa98e2SPeter Wemm 	"/usr/bin/pam",
3008c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3009c2aa98e2SPeter Wemm 	"/usr/bin/posix/sh",
30103299c2f1SGregory Neil Shapiro #  else /* V4FS */
3011c2aa98e2SPeter Wemm 	"/bin/rsh",		/* restricted Bourne shell */
3012c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3013c2aa98e2SPeter Wemm 	"/bin/rksh",		/* restricted Korn shell */
3014c2aa98e2SPeter Wemm 	"/bin/pam",
3015c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3016c2aa98e2SPeter Wemm 	"/bin/posix/sh",
30173299c2f1SGregory Neil Shapiro #  endif /* V4FS */
30183299c2f1SGregory Neil Shapiro # endif /* __hpux */
3019c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3020c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3021c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3022c2aa98e2SPeter Wemm 	"/bin/tsh",		/* trusted shell */
3023c2aa98e2SPeter Wemm 	"/usr/bin/tsh",
3024c2aa98e2SPeter Wemm 	"/bin/bsh",		/* Bourne shell */
3025c2aa98e2SPeter Wemm 	"/usr/bin/bsh",
30263299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
302776b7bf71SPeter Wemm # if defined(__svr4__) || defined(__svr5__)
3028c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3029c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
30303299c2f1SGregory Neil Shapiro # endif /* defined(__svr4__) || defined(__svr5__) */
3031c2aa98e2SPeter Wemm # ifdef sgi
3032c2aa98e2SPeter Wemm 	"/sbin/sh",		/* SGI's shells really live in /sbin */
3033c2aa98e2SPeter Wemm 	"/sbin/csh",
3034c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3035c2aa98e2SPeter Wemm 	"/sbin/ksh",
3036c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3037c2aa98e2SPeter Wemm 	"/bin/tcsh",		/* Extended csh */
3038c2aa98e2SPeter Wemm 	"/usr/bin/tcsh",
30393299c2f1SGregory Neil Shapiro # endif /* sgi */
3040c2aa98e2SPeter Wemm 	NULL
3041c2aa98e2SPeter Wemm };
3042c2aa98e2SPeter Wemm 
30433299c2f1SGregory Neil Shapiro #endif /* !HASGETUSERSHELL */
3044c2aa98e2SPeter Wemm 
3045c2aa98e2SPeter Wemm #define WILDCARD_SHELL	"/SENDMAIL/ANY/SHELL/"
3046c2aa98e2SPeter Wemm 
3047c2aa98e2SPeter Wemm bool
3048c2aa98e2SPeter Wemm usershellok(user, shell)
3049c2aa98e2SPeter Wemm 	char *user;
3050c2aa98e2SPeter Wemm 	char *shell;
3051c2aa98e2SPeter Wemm {
3052c2aa98e2SPeter Wemm # if HASGETUSERSHELL
3053c2aa98e2SPeter Wemm 	register char *p;
3054c2aa98e2SPeter Wemm 	extern char *getusershell();
3055c2aa98e2SPeter Wemm 
3056c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3057c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
305812ed1c7cSGregory Neil Shapiro 		return true;
3059c2aa98e2SPeter Wemm 
3060c2aa98e2SPeter Wemm 	setusershell();
3061c2aa98e2SPeter Wemm 	while ((p = getusershell()) != NULL)
3062c2aa98e2SPeter Wemm 		if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
3063c2aa98e2SPeter Wemm 			break;
3064c2aa98e2SPeter Wemm 	endusershell();
3065c2aa98e2SPeter Wemm 	return p != NULL;
30663299c2f1SGregory Neil Shapiro # else /* HASGETUSERSHELL */
3067c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3068c2aa98e2SPeter Wemm 	auto char *v;
30693299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
307012ed1c7cSGregory Neil Shapiro 	register SM_FILE_T *shellf;
3071c2aa98e2SPeter Wemm 	char buf[MAXLINE];
3072c2aa98e2SPeter Wemm 
3073c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3074c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
307512ed1c7cSGregory Neil Shapiro 		return true;
3076c2aa98e2SPeter Wemm 
3077c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3078c2aa98e2SPeter Wemm 	/*
3079c2aa98e2SPeter Wemm 	**  Naturally IBM has a "better" idea.....
3080c2aa98e2SPeter Wemm 	**
3081c2aa98e2SPeter Wemm 	**	What a crock.  This interface isn't documented, it is
3082c2aa98e2SPeter Wemm 	**	considered part of the security library (-ls), and it
3083c2aa98e2SPeter Wemm 	**	only works if you are running as root (since the list
3084c2aa98e2SPeter Wemm 	**	of valid shells is obviously a source of great concern).
3085c2aa98e2SPeter Wemm 	**	I recommend that you do NOT define USEGETCONFATTR,
3086c2aa98e2SPeter Wemm 	**	especially since you are going to have to set up an
3087c2aa98e2SPeter Wemm 	**	/etc/shells anyhow to handle the cases where getconfattr
3088c2aa98e2SPeter Wemm 	**	fails.
3089c2aa98e2SPeter Wemm 	*/
3090c2aa98e2SPeter Wemm 
3091c2aa98e2SPeter Wemm 	if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
3092c2aa98e2SPeter Wemm 	{
3093c2aa98e2SPeter Wemm 		while (*v != '\0')
3094c2aa98e2SPeter Wemm 		{
3095c2aa98e2SPeter Wemm 			if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
309612ed1c7cSGregory Neil Shapiro 				return true;
3097c2aa98e2SPeter Wemm 			v += strlen(v) + 1;
3098c2aa98e2SPeter Wemm 		}
309912ed1c7cSGregory Neil Shapiro 		return false;
3100c2aa98e2SPeter Wemm 	}
31013299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
3102c2aa98e2SPeter Wemm 
310312ed1c7cSGregory Neil Shapiro 	shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS,
310412ed1c7cSGregory Neil Shapiro 			    SM_IO_RDONLY, NULL);
3105c2aa98e2SPeter Wemm 	if (shellf == NULL)
3106c2aa98e2SPeter Wemm 	{
3107c2aa98e2SPeter Wemm 		/* no /etc/shells; see if it is one of the std shells */
3108c2aa98e2SPeter Wemm 		char **d;
3109c2aa98e2SPeter Wemm 
3110c2aa98e2SPeter Wemm 		if (errno != ENOENT && LogLevel > 3)
3111c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
3112c2aa98e2SPeter Wemm 				  "usershellok: cannot open %s: %s",
311312ed1c7cSGregory Neil Shapiro 				  _PATH_SHELLS, sm_errstring(errno));
3114c2aa98e2SPeter Wemm 
3115c2aa98e2SPeter Wemm 		for (d = DefaultUserShells; *d != NULL; d++)
3116c2aa98e2SPeter Wemm 		{
3117c2aa98e2SPeter Wemm 			if (strcmp(shell, *d) == 0)
311812ed1c7cSGregory Neil Shapiro 				return true;
3119c2aa98e2SPeter Wemm 		}
312012ed1c7cSGregory Neil Shapiro 		return false;
3121c2aa98e2SPeter Wemm 	}
3122c2aa98e2SPeter Wemm 
312312ed1c7cSGregory Neil Shapiro 	while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
3124c2aa98e2SPeter Wemm 	{
3125c2aa98e2SPeter Wemm 		register char *p, *q;
3126c2aa98e2SPeter Wemm 
3127c2aa98e2SPeter Wemm 		p = buf;
3128c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && *p != '/')
3129c2aa98e2SPeter Wemm 			p++;
3130c2aa98e2SPeter Wemm 		if (*p == '#' || *p == '\0')
3131c2aa98e2SPeter Wemm 			continue;
3132c2aa98e2SPeter Wemm 		q = p;
3133c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p)))
3134c2aa98e2SPeter Wemm 			p++;
3135c2aa98e2SPeter Wemm 		*p = '\0';
3136c2aa98e2SPeter Wemm 		if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
3137c2aa98e2SPeter Wemm 		{
313812ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(shellf, SM_TIME_DEFAULT);
313912ed1c7cSGregory Neil Shapiro 			return true;
3140c2aa98e2SPeter Wemm 		}
3141c2aa98e2SPeter Wemm 	}
314212ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(shellf, SM_TIME_DEFAULT);
314312ed1c7cSGregory Neil Shapiro 	return false;
31443299c2f1SGregory Neil Shapiro # endif /* HASGETUSERSHELL */
3145c2aa98e2SPeter Wemm }
314612ed1c7cSGregory Neil Shapiro /*
3147c2aa98e2SPeter Wemm **  FREEDISKSPACE -- see how much free space is on the queue filesystem
3148c2aa98e2SPeter Wemm **
3149c2aa98e2SPeter Wemm **	Only implemented if you have statfs.
3150c2aa98e2SPeter Wemm **
3151c2aa98e2SPeter Wemm **	Parameters:
3152c2aa98e2SPeter Wemm **		dir -- the directory in question.
3153c2aa98e2SPeter Wemm **		bsize -- a variable into which the filesystem
3154c2aa98e2SPeter Wemm **			block size is stored.
3155c2aa98e2SPeter Wemm **
3156c2aa98e2SPeter Wemm **	Returns:
31573299c2f1SGregory Neil Shapiro **		The number of blocks free on the queue filesystem.
3158c2aa98e2SPeter Wemm **		-1 if the statfs call fails.
3159c2aa98e2SPeter Wemm **
3160c2aa98e2SPeter Wemm **	Side effects:
3161c2aa98e2SPeter Wemm **		Puts the filesystem block size into bsize.
3162c2aa98e2SPeter Wemm */
3163c2aa98e2SPeter Wemm 
3164c2aa98e2SPeter Wemm /* statfs types */
3165c2aa98e2SPeter Wemm # define SFS_NONE	0	/* no statfs implementation */
3166c2aa98e2SPeter Wemm # define SFS_USTAT	1	/* use ustat */
3167c2aa98e2SPeter Wemm # define SFS_4ARGS	2	/* use four-argument statfs call */
3168c2aa98e2SPeter Wemm # define SFS_VFS	3	/* use <sys/vfs.h> implementation */
3169c2aa98e2SPeter Wemm # define SFS_MOUNT	4	/* use <sys/mount.h> implementation */
3170c2aa98e2SPeter Wemm # define SFS_STATFS	5	/* use <sys/statfs.h> implementation */
3171c2aa98e2SPeter Wemm # define SFS_STATVFS	6	/* use <sys/statvfs.h> implementation */
3172c2aa98e2SPeter Wemm 
3173c2aa98e2SPeter Wemm # ifndef SFS_TYPE
3174c2aa98e2SPeter Wemm #  define SFS_TYPE	SFS_NONE
31753299c2f1SGregory Neil Shapiro # endif /* ! SFS_TYPE */
3176c2aa98e2SPeter Wemm 
3177c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT
3178c2aa98e2SPeter Wemm #  include <ustat.h>
31793299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */
3180c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
3181c2aa98e2SPeter Wemm #  include <sys/statfs.h>
31823299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */
3183c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_VFS
3184c2aa98e2SPeter Wemm #  include <sys/vfs.h>
31853299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_VFS */
3186c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_MOUNT
3187c2aa98e2SPeter Wemm #  include <sys/mount.h>
31883299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_MOUNT */
3189c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_STATVFS
3190c2aa98e2SPeter Wemm #  include <sys/statvfs.h>
31913299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_STATVFS */
3192c2aa98e2SPeter Wemm 
3193c2aa98e2SPeter Wemm long
3194c2aa98e2SPeter Wemm freediskspace(dir, bsize)
3195c2aa98e2SPeter Wemm 	char *dir;
3196c2aa98e2SPeter Wemm 	long *bsize;
3197c2aa98e2SPeter Wemm {
319812ed1c7cSGregory Neil Shapiro # if SFS_TYPE == SFS_NONE
319912ed1c7cSGregory Neil Shapiro 	if (bsize != NULL)
320012ed1c7cSGregory Neil Shapiro 		*bsize = 4096L;
320112ed1c7cSGregory Neil Shapiro 
320212ed1c7cSGregory Neil Shapiro 	/* assume free space is plentiful */
320312ed1c7cSGregory Neil Shapiro 	return (long) LONG_MAX;
320412ed1c7cSGregory Neil Shapiro # else /* SFS_TYPE == SFS_NONE */
3205c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3206c2aa98e2SPeter Wemm 	struct ustat fs;
3207c2aa98e2SPeter Wemm 	struct stat statbuf;
3208c2aa98e2SPeter Wemm #   define FSBLOCKSIZE	DEV_BSIZE
3209c2aa98e2SPeter Wemm #   define SFS_BAVAIL	f_tfree
32103299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3211c2aa98e2SPeter Wemm #   if defined(ultrix)
3212c2aa98e2SPeter Wemm 	struct fs_data fs;
3213c2aa98e2SPeter Wemm #    define SFS_BAVAIL	fd_bfreen
3214c2aa98e2SPeter Wemm #    define FSBLOCKSIZE	1024L
32153299c2f1SGregory Neil Shapiro #   else /* defined(ultrix) */
3216c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3217c2aa98e2SPeter Wemm 	struct statvfs fs;
3218c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_frsize
32193299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3220c2aa98e2SPeter Wemm 	struct statfs fs;
3221c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_bsize
32223299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
32233299c2f1SGregory Neil Shapiro #   endif /* defined(ultrix) */
32243299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3225c2aa98e2SPeter Wemm #  ifndef SFS_BAVAIL
3226c2aa98e2SPeter Wemm #   define SFS_BAVAIL f_bavail
32273299c2f1SGregory Neil Shapiro #  endif /* ! SFS_BAVAIL */
3228c2aa98e2SPeter Wemm 
3229c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3230c2aa98e2SPeter Wemm 	if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
32313299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3232c2aa98e2SPeter Wemm #   if SFS_TYPE == SFS_4ARGS
3233c2aa98e2SPeter Wemm 	if (statfs(dir, &fs, sizeof fs, 0) == 0)
32343299c2f1SGregory Neil Shapiro #   else /* SFS_TYPE == SFS_4ARGS */
3235c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3236c2aa98e2SPeter Wemm 	if (statvfs(dir, &fs) == 0)
32373299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3238c2aa98e2SPeter Wemm #     if defined(ultrix)
3239c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) > 0)
32403299c2f1SGregory Neil Shapiro #     else /* defined(ultrix) */
3241c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) == 0)
32423299c2f1SGregory Neil Shapiro #     endif /* defined(ultrix) */
32433299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
32443299c2f1SGregory Neil Shapiro #   endif /* SFS_TYPE == SFS_4ARGS */
32453299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3246c2aa98e2SPeter Wemm 	{
3247c2aa98e2SPeter Wemm 		if (bsize != NULL)
3248c2aa98e2SPeter Wemm 			*bsize = FSBLOCKSIZE;
3249c2aa98e2SPeter Wemm 		if (fs.SFS_BAVAIL <= 0)
3250c2aa98e2SPeter Wemm 			return 0;
3251c2aa98e2SPeter Wemm 		else if (fs.SFS_BAVAIL > LONG_MAX)
32523299c2f1SGregory Neil Shapiro 			return (long) LONG_MAX;
3253c2aa98e2SPeter Wemm 		else
3254c2aa98e2SPeter Wemm 			return (long) fs.SFS_BAVAIL;
3255c2aa98e2SPeter Wemm 	}
32563299c2f1SGregory Neil Shapiro 	return -1;
325712ed1c7cSGregory Neil Shapiro # endif /* SFS_TYPE == SFS_NONE */
3258c2aa98e2SPeter Wemm }
325912ed1c7cSGregory Neil Shapiro /*
326012ed1c7cSGregory Neil Shapiro **  ENOUGHDISKSPACE -- is there enough free space on the queue file systems?
3261c2aa98e2SPeter Wemm **
3262c2aa98e2SPeter Wemm **	Parameters:
3263c2aa98e2SPeter Wemm **		msize -- the size to check against.  If zero, we don't yet
3264c2aa98e2SPeter Wemm **		know how big the message will be, so just check for
3265c2aa98e2SPeter Wemm **		a "reasonable" amount.
326612ed1c7cSGregory Neil Shapiro **		e -- envelope, or NULL -- controls logging
3267c2aa98e2SPeter Wemm **
3268c2aa98e2SPeter Wemm **	Returns:
326912ed1c7cSGregory Neil Shapiro **		true if in every queue group there is at least one
327012ed1c7cSGregory Neil Shapiro **		queue directory whose file system contains enough free space.
327112ed1c7cSGregory Neil Shapiro **		false otherwise.
327212ed1c7cSGregory Neil Shapiro **
327312ed1c7cSGregory Neil Shapiro **	Side Effects:
327412ed1c7cSGregory Neil Shapiro **		If there is not enough disk space and e != NULL
327512ed1c7cSGregory Neil Shapiro **		then sm_syslog is called.
3276c2aa98e2SPeter Wemm */
3277c2aa98e2SPeter Wemm 
3278c2aa98e2SPeter Wemm bool
327912ed1c7cSGregory Neil Shapiro enoughdiskspace(msize, e)
3280c2aa98e2SPeter Wemm 	long msize;
328112ed1c7cSGregory Neil Shapiro 	ENVELOPE *e;
3282c2aa98e2SPeter Wemm {
328312ed1c7cSGregory Neil Shapiro 	int i;
3284c2aa98e2SPeter Wemm 
3285c2aa98e2SPeter Wemm 	if (MinBlocksFree <= 0 && msize <= 0)
3286c2aa98e2SPeter Wemm 	{
3287c2aa98e2SPeter Wemm 		if (tTd(4, 80))
328812ed1c7cSGregory Neil Shapiro 			sm_dprintf("enoughdiskspace: no threshold\n");
328912ed1c7cSGregory Neil Shapiro 		return true;
3290c2aa98e2SPeter Wemm 	}
3291c2aa98e2SPeter Wemm 
329212ed1c7cSGregory Neil Shapiro 	filesys_update();
329312ed1c7cSGregory Neil Shapiro 	for (i = 0; i < NumQueue; ++i)
3294c2aa98e2SPeter Wemm 	{
329512ed1c7cSGregory Neil Shapiro 		if (pickqdir(Queue[i], msize, e) < 0)
329612ed1c7cSGregory Neil Shapiro 			return false;
3297c2aa98e2SPeter Wemm 	}
329812ed1c7cSGregory Neil Shapiro 	return true;
3299c2aa98e2SPeter Wemm }
330012ed1c7cSGregory Neil Shapiro /*
3301c2aa98e2SPeter Wemm **  TRANSIENTERROR -- tell if an error code indicates a transient failure
3302c2aa98e2SPeter Wemm **
3303c2aa98e2SPeter Wemm **	This looks at an errno value and tells if this is likely to
3304c2aa98e2SPeter Wemm **	go away if retried later.
3305c2aa98e2SPeter Wemm **
3306c2aa98e2SPeter Wemm **	Parameters:
3307c2aa98e2SPeter Wemm **		err -- the errno code to classify.
3308c2aa98e2SPeter Wemm **
3309c2aa98e2SPeter Wemm **	Returns:
331012ed1c7cSGregory Neil Shapiro **		true if this is probably transient.
331112ed1c7cSGregory Neil Shapiro **		false otherwise.
3312c2aa98e2SPeter Wemm */
3313c2aa98e2SPeter Wemm 
3314c2aa98e2SPeter Wemm bool
3315c2aa98e2SPeter Wemm transienterror(err)
3316c2aa98e2SPeter Wemm 	int err;
3317c2aa98e2SPeter Wemm {
3318c2aa98e2SPeter Wemm 	switch (err)
3319c2aa98e2SPeter Wemm 	{
3320c2aa98e2SPeter Wemm 	  case EIO:			/* I/O error */
3321c2aa98e2SPeter Wemm 	  case ENXIO:			/* Device not configured */
3322c2aa98e2SPeter Wemm 	  case EAGAIN:			/* Resource temporarily unavailable */
3323c2aa98e2SPeter Wemm 	  case ENOMEM:			/* Cannot allocate memory */
3324c2aa98e2SPeter Wemm 	  case ENODEV:			/* Operation not supported by device */
3325c2aa98e2SPeter Wemm 	  case ENFILE:			/* Too many open files in system */
3326c2aa98e2SPeter Wemm 	  case EMFILE:			/* Too many open files */
3327c2aa98e2SPeter Wemm 	  case ENOSPC:			/* No space left on device */
3328c2aa98e2SPeter Wemm 	  case ETIMEDOUT:		/* Connection timed out */
3329c2aa98e2SPeter Wemm #ifdef ESTALE
3330c2aa98e2SPeter Wemm 	  case ESTALE:			/* Stale NFS file handle */
33313299c2f1SGregory Neil Shapiro #endif /* ESTALE */
3332c2aa98e2SPeter Wemm #ifdef ENETDOWN
3333c2aa98e2SPeter Wemm 	  case ENETDOWN:		/* Network is down */
33343299c2f1SGregory Neil Shapiro #endif /* ENETDOWN */
3335c2aa98e2SPeter Wemm #ifdef ENETUNREACH
3336c2aa98e2SPeter Wemm 	  case ENETUNREACH:		/* Network is unreachable */
33373299c2f1SGregory Neil Shapiro #endif /* ENETUNREACH */
3338c2aa98e2SPeter Wemm #ifdef ENETRESET
3339c2aa98e2SPeter Wemm 	  case ENETRESET:		/* Network dropped connection on reset */
33403299c2f1SGregory Neil Shapiro #endif /* ENETRESET */
3341c2aa98e2SPeter Wemm #ifdef ECONNABORTED
3342c2aa98e2SPeter Wemm 	  case ECONNABORTED:		/* Software caused connection abort */
33433299c2f1SGregory Neil Shapiro #endif /* ECONNABORTED */
3344c2aa98e2SPeter Wemm #ifdef ECONNRESET
3345c2aa98e2SPeter Wemm 	  case ECONNRESET:		/* Connection reset by peer */
33463299c2f1SGregory Neil Shapiro #endif /* ECONNRESET */
3347c2aa98e2SPeter Wemm #ifdef ENOBUFS
3348c2aa98e2SPeter Wemm 	  case ENOBUFS:			/* No buffer space available */
33493299c2f1SGregory Neil Shapiro #endif /* ENOBUFS */
3350c2aa98e2SPeter Wemm #ifdef ESHUTDOWN
3351c2aa98e2SPeter Wemm 	  case ESHUTDOWN:		/* Can't send after socket shutdown */
33523299c2f1SGregory Neil Shapiro #endif /* ESHUTDOWN */
3353c2aa98e2SPeter Wemm #ifdef ECONNREFUSED
3354c2aa98e2SPeter Wemm 	  case ECONNREFUSED:		/* Connection refused */
33553299c2f1SGregory Neil Shapiro #endif /* ECONNREFUSED */
3356c2aa98e2SPeter Wemm #ifdef EHOSTDOWN
3357c2aa98e2SPeter Wemm 	  case EHOSTDOWN:		/* Host is down */
33583299c2f1SGregory Neil Shapiro #endif /* EHOSTDOWN */
3359c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH
3360c2aa98e2SPeter Wemm 	  case EHOSTUNREACH:		/* No route to host */
33613299c2f1SGregory Neil Shapiro #endif /* EHOSTUNREACH */
3362c2aa98e2SPeter Wemm #ifdef EDQUOT
3363c2aa98e2SPeter Wemm 	  case EDQUOT:			/* Disc quota exceeded */
33643299c2f1SGregory Neil Shapiro #endif /* EDQUOT */
3365c2aa98e2SPeter Wemm #ifdef EPROCLIM
3366c2aa98e2SPeter Wemm 	  case EPROCLIM:		/* Too many processes */
33673299c2f1SGregory Neil Shapiro #endif /* EPROCLIM */
3368c2aa98e2SPeter Wemm #ifdef EUSERS
3369c2aa98e2SPeter Wemm 	  case EUSERS:			/* Too many users */
33703299c2f1SGregory Neil Shapiro #endif /* EUSERS */
3371c2aa98e2SPeter Wemm #ifdef EDEADLK
3372c2aa98e2SPeter Wemm 	  case EDEADLK:			/* Resource deadlock avoided */
33733299c2f1SGregory Neil Shapiro #endif /* EDEADLK */
3374c2aa98e2SPeter Wemm #ifdef EISCONN
3375c2aa98e2SPeter Wemm 	  case EISCONN:			/* Socket already connected */
33763299c2f1SGregory Neil Shapiro #endif /* EISCONN */
3377c2aa98e2SPeter Wemm #ifdef EINPROGRESS
3378c2aa98e2SPeter Wemm 	  case EINPROGRESS:		/* Operation now in progress */
33793299c2f1SGregory Neil Shapiro #endif /* EINPROGRESS */
3380c2aa98e2SPeter Wemm #ifdef EALREADY
3381c2aa98e2SPeter Wemm 	  case EALREADY:		/* Operation already in progress */
33823299c2f1SGregory Neil Shapiro #endif /* EALREADY */
3383c2aa98e2SPeter Wemm #ifdef EADDRINUSE
3384c2aa98e2SPeter Wemm 	  case EADDRINUSE:		/* Address already in use */
33853299c2f1SGregory Neil Shapiro #endif /* EADDRINUSE */
3386c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL
3387c2aa98e2SPeter Wemm 	  case EADDRNOTAVAIL:		/* Can't assign requested address */
33883299c2f1SGregory Neil Shapiro #endif /* EADDRNOTAVAIL */
3389c2aa98e2SPeter Wemm #ifdef ETXTBSY
3390c2aa98e2SPeter Wemm 	  case ETXTBSY:			/* (Apollo) file locked */
33913299c2f1SGregory Neil Shapiro #endif /* ETXTBSY */
3392c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
3393c2aa98e2SPeter Wemm 	  case ENOSR:			/* Out of streams resources */
33943299c2f1SGregory Neil Shapiro #endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */
33953299c2f1SGregory Neil Shapiro #ifdef ENOLCK
33963299c2f1SGregory Neil Shapiro 	  case ENOLCK:			/* No locks available */
33973299c2f1SGregory Neil Shapiro #endif /* ENOLCK */
3398c2aa98e2SPeter Wemm 	  case E_SM_OPENTIMEOUT:	/* PSEUDO: open timed out */
339912ed1c7cSGregory Neil Shapiro 		return true;
3400c2aa98e2SPeter Wemm 	}
3401c2aa98e2SPeter Wemm 
3402c2aa98e2SPeter Wemm 	/* nope, must be permanent */
340312ed1c7cSGregory Neil Shapiro 	return false;
3404c2aa98e2SPeter Wemm }
340512ed1c7cSGregory Neil Shapiro /*
3406c2aa98e2SPeter Wemm **  LOCKFILE -- lock a file using flock or (shudder) fcntl locking
3407c2aa98e2SPeter Wemm **
3408c2aa98e2SPeter Wemm **	Parameters:
3409c2aa98e2SPeter Wemm **		fd -- the file descriptor of the file.
3410c2aa98e2SPeter Wemm **		filename -- the file name (for error messages).
3411c2aa98e2SPeter Wemm **		ext -- the filename extension.
3412c2aa98e2SPeter Wemm **		type -- type of the lock.  Bits can be:
3413c2aa98e2SPeter Wemm **			LOCK_EX -- exclusive lock.
3414c2aa98e2SPeter Wemm **			LOCK_NB -- non-blocking.
3415c46d91b7SGregory Neil Shapiro **			LOCK_UN -- unlock.
3416c2aa98e2SPeter Wemm **
3417c2aa98e2SPeter Wemm **	Returns:
341812ed1c7cSGregory Neil Shapiro **		true if the lock was acquired.
341912ed1c7cSGregory Neil Shapiro **		false otherwise.
3420c2aa98e2SPeter Wemm */
3421c2aa98e2SPeter Wemm 
3422c2aa98e2SPeter Wemm bool
3423c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type)
3424c2aa98e2SPeter Wemm 	int fd;
3425c2aa98e2SPeter Wemm 	char *filename;
3426c2aa98e2SPeter Wemm 	char *ext;
3427c2aa98e2SPeter Wemm 	int type;
3428c2aa98e2SPeter Wemm {
3429c2aa98e2SPeter Wemm 	int i;
3430c2aa98e2SPeter Wemm 	int save_errno;
3431c2aa98e2SPeter Wemm # if !HASFLOCK
3432c2aa98e2SPeter Wemm 	int action;
3433c2aa98e2SPeter Wemm 	struct flock lfd;
3434c2aa98e2SPeter Wemm 
3435c2aa98e2SPeter Wemm 	if (ext == NULL)
3436c2aa98e2SPeter Wemm 		ext = "";
3437c2aa98e2SPeter Wemm 
34383299c2f1SGregory Neil Shapiro 	memset(&lfd, '\0', sizeof lfd);
3439c2aa98e2SPeter Wemm 	if (bitset(LOCK_UN, type))
3440c2aa98e2SPeter Wemm 		lfd.l_type = F_UNLCK;
3441c2aa98e2SPeter Wemm 	else if (bitset(LOCK_EX, type))
3442c2aa98e2SPeter Wemm 		lfd.l_type = F_WRLCK;
3443c2aa98e2SPeter Wemm 	else
3444c2aa98e2SPeter Wemm 		lfd.l_type = F_RDLCK;
3445c2aa98e2SPeter Wemm 
3446c2aa98e2SPeter Wemm 	if (bitset(LOCK_NB, type))
3447c2aa98e2SPeter Wemm 		action = F_SETLK;
3448c2aa98e2SPeter Wemm 	else
3449c2aa98e2SPeter Wemm 		action = F_SETLKW;
3450c2aa98e2SPeter Wemm 
3451c2aa98e2SPeter Wemm 	if (tTd(55, 60))
345212ed1c7cSGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, action=%d, type=%d): ",
3453c2aa98e2SPeter Wemm 			filename, ext, action, lfd.l_type);
3454c2aa98e2SPeter Wemm 
3455c2aa98e2SPeter Wemm 	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
3456c2aa98e2SPeter Wemm 		continue;
3457c2aa98e2SPeter Wemm 	if (i >= 0)
3458c2aa98e2SPeter Wemm 	{
3459c2aa98e2SPeter Wemm 		if (tTd(55, 60))
346012ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
346112ed1c7cSGregory Neil Shapiro 		return true;
3462c2aa98e2SPeter Wemm 	}
3463c2aa98e2SPeter Wemm 	save_errno = errno;
3464c2aa98e2SPeter Wemm 
3465c2aa98e2SPeter Wemm 	if (tTd(55, 60))
346612ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3467c2aa98e2SPeter Wemm 
3468c2aa98e2SPeter Wemm 	/*
3469c2aa98e2SPeter Wemm 	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
3470c2aa98e2SPeter Wemm 	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
3471c2aa98e2SPeter Wemm 	**  as type "tmp" (that is, served from swap space), the
3472c2aa98e2SPeter Wemm 	**  previous fcntl will fail with "Invalid argument" errors.
3473c2aa98e2SPeter Wemm 	**  Since this is fairly common during testing, we will assume
3474c2aa98e2SPeter Wemm 	**  that this indicates that the lock is successfully grabbed.
3475c2aa98e2SPeter Wemm 	*/
3476c2aa98e2SPeter Wemm 
3477c2aa98e2SPeter Wemm 	if (save_errno == EINVAL)
3478c2aa98e2SPeter Wemm 	{
3479c2aa98e2SPeter Wemm 		if (tTd(55, 60))
348012ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
348112ed1c7cSGregory Neil Shapiro 		return true;
3482c2aa98e2SPeter Wemm 	}
3483c2aa98e2SPeter Wemm 
34843299c2f1SGregory Neil Shapiro 	if (!bitset(LOCK_NB, type) ||
34853299c2f1SGregory Neil Shapiro 	    (save_errno != EACCES && save_errno != EAGAIN))
3486c2aa98e2SPeter Wemm 	{
3487c2aa98e2SPeter Wemm 		int omode = -1;
3488c2aa98e2SPeter Wemm #  ifdef F_GETFL
3489c2aa98e2SPeter Wemm 		(void) fcntl(fd, F_GETFL, &omode);
3490c2aa98e2SPeter Wemm 		errno = save_errno;
34913299c2f1SGregory Neil Shapiro #  endif /* F_GETFL */
3492c2aa98e2SPeter Wemm 		syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3493c2aa98e2SPeter Wemm 			filename, ext, fd, type, omode, geteuid());
349412ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3495c2aa98e2SPeter Wemm 	}
34963299c2f1SGregory Neil Shapiro # else /* !HASFLOCK */
3497c2aa98e2SPeter Wemm 	if (ext == NULL)
3498c2aa98e2SPeter Wemm 		ext = "";
3499c2aa98e2SPeter Wemm 
3500c2aa98e2SPeter Wemm 	if (tTd(55, 60))
350112ed1c7cSGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type);
3502c2aa98e2SPeter Wemm 
3503c2aa98e2SPeter Wemm 	while ((i = flock(fd, type)) < 0 && errno == EINTR)
3504c2aa98e2SPeter Wemm 		continue;
3505c2aa98e2SPeter Wemm 	if (i >= 0)
3506c2aa98e2SPeter Wemm 	{
3507c2aa98e2SPeter Wemm 		if (tTd(55, 60))
350812ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
350912ed1c7cSGregory Neil Shapiro 		return true;
3510c2aa98e2SPeter Wemm 	}
3511c2aa98e2SPeter Wemm 	save_errno = errno;
3512c2aa98e2SPeter Wemm 
3513c2aa98e2SPeter Wemm 	if (tTd(55, 60))
351412ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3515c2aa98e2SPeter Wemm 
3516c2aa98e2SPeter Wemm 	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
3517c2aa98e2SPeter Wemm 	{
3518c2aa98e2SPeter Wemm 		int omode = -1;
3519c2aa98e2SPeter Wemm #  ifdef F_GETFL
3520c2aa98e2SPeter Wemm 		(void) fcntl(fd, F_GETFL, &omode);
3521c2aa98e2SPeter Wemm 		errno = save_errno;
35223299c2f1SGregory Neil Shapiro #  endif /* F_GETFL */
3523c2aa98e2SPeter Wemm 		syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3524c2aa98e2SPeter Wemm 			filename, ext, fd, type, omode, geteuid());
352512ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3526c2aa98e2SPeter Wemm 	}
35273299c2f1SGregory Neil Shapiro # endif /* !HASFLOCK */
3528c2aa98e2SPeter Wemm 	if (tTd(55, 60))
352912ed1c7cSGregory Neil Shapiro 		sm_dprintf("FAIL\n");
3530c2aa98e2SPeter Wemm 	errno = save_errno;
353112ed1c7cSGregory Neil Shapiro 	return false;
3532c2aa98e2SPeter Wemm }
353312ed1c7cSGregory Neil Shapiro /*
3534c2aa98e2SPeter Wemm **  CHOWNSAFE -- tell if chown is "safe" (executable only by root)
3535c2aa98e2SPeter Wemm **
3536c2aa98e2SPeter Wemm **	Unfortunately, given that we can't predict other systems on which
3537c2aa98e2SPeter Wemm **	a remote mounted (NFS) filesystem will be mounted, the answer is
3538c2aa98e2SPeter Wemm **	almost always that this is unsafe.
3539c2aa98e2SPeter Wemm **
3540c2aa98e2SPeter Wemm **	Note also that many operating systems have non-compliant
3541c2aa98e2SPeter Wemm **	implementations of the _POSIX_CHOWN_RESTRICTED variable and the
3542c2aa98e2SPeter Wemm **	fpathconf() routine.  According to IEEE 1003.1-1990, if
3543c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
3544c2aa98e2SPeter Wemm **	no non-root process can give away the file.  However, vendors
3545c2aa98e2SPeter Wemm **	don't take NFS into account, so a comfortable value of
3546c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED tells us nothing.
3547c2aa98e2SPeter Wemm **
3548c2aa98e2SPeter Wemm **	Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
3549c2aa98e2SPeter Wemm **	even on files where chown is not restricted.  Many systems get
3550c2aa98e2SPeter Wemm **	this wrong on NFS-based filesystems (that is, they say that chown
3551c2aa98e2SPeter Wemm **	is restricted [safe] on NFS filesystems where it may not be, since
3552c2aa98e2SPeter Wemm **	other systems can access the same filesystem and do file giveaway;
3553c2aa98e2SPeter Wemm **	only the NFS server knows for sure!)  Hence, it is important to
3554c2aa98e2SPeter Wemm **	get the value of SAFENFSPATHCONF correct -- it should be defined
3555c2aa98e2SPeter Wemm **	_only_ after testing (see test/t_pathconf.c) a system on an unsafe
3556c2aa98e2SPeter Wemm **	NFS-based filesystem to ensure that you can get meaningful results.
3557c2aa98e2SPeter Wemm **	If in doubt, assume unsafe!
3558c2aa98e2SPeter Wemm **
3559c2aa98e2SPeter Wemm **	You may also need to tweak IS_SAFE_CHOWN -- it should be a
3560c2aa98e2SPeter Wemm **	condition indicating whether the return from pathconf indicates
3561c2aa98e2SPeter Wemm **	that chown is safe (typically either > 0 or >= 0 -- there isn't
3562c2aa98e2SPeter Wemm **	even any agreement about whether a zero return means that a file
3563c2aa98e2SPeter Wemm **	is or is not safe).  It defaults to "> 0".
3564c2aa98e2SPeter Wemm **
3565c2aa98e2SPeter Wemm **	If the parent directory is safe (writable only by owner back
3566c2aa98e2SPeter Wemm **	to the root) then we can relax slightly and trust fpathconf
3567c2aa98e2SPeter Wemm **	in more circumstances.  This is really a crock -- if this is an
3568c2aa98e2SPeter Wemm **	NFS mounted filesystem then we really know nothing about the
3569c2aa98e2SPeter Wemm **	underlying implementation.  However, most systems pessimize and
3570c2aa98e2SPeter Wemm **	return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
3571c2aa98e2SPeter Wemm **	we interpret as unsafe, as we should.  Thus, this heuristic gets
3572c2aa98e2SPeter Wemm **	us into a possible problem only on systems that have a broken
3573c2aa98e2SPeter Wemm **	pathconf implementation and which are also poorly configured
3574c2aa98e2SPeter Wemm **	(have :include: files in group- or world-writable directories).
3575c2aa98e2SPeter Wemm **
3576c2aa98e2SPeter Wemm **	Parameters:
3577c2aa98e2SPeter Wemm **		fd -- the file descriptor to check.
3578c2aa98e2SPeter Wemm **		safedir -- set if the parent directory is safe.
3579c2aa98e2SPeter Wemm **
3580c2aa98e2SPeter Wemm **	Returns:
358112ed1c7cSGregory Neil Shapiro **		true -- if the chown(2) operation is "safe" -- that is,
3582c2aa98e2SPeter Wemm **			only root can chown the file to an arbitrary user.
358312ed1c7cSGregory Neil Shapiro **		false -- if an arbitrary user can give away a file.
3584c2aa98e2SPeter Wemm */
3585c2aa98e2SPeter Wemm 
3586c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN
3587c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN	> 0
35883299c2f1SGregory Neil Shapiro #endif /* ! IS_SAFE_CHOWN */
3589c2aa98e2SPeter Wemm 
3590c2aa98e2SPeter Wemm bool
3591c2aa98e2SPeter Wemm chownsafe(fd, safedir)
3592c2aa98e2SPeter Wemm 	int fd;
3593c2aa98e2SPeter Wemm 	bool safedir;
3594c2aa98e2SPeter Wemm {
3595c2aa98e2SPeter Wemm # if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \
3596c2aa98e2SPeter Wemm     (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H))
3597c2aa98e2SPeter Wemm 	int rval;
3598c2aa98e2SPeter Wemm 
3599c2aa98e2SPeter Wemm 	/* give the system administrator a chance to override */
36003299c2f1SGregory Neil Shapiro 	if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail))
360112ed1c7cSGregory Neil Shapiro 		return true;
3602c2aa98e2SPeter Wemm 
3603c2aa98e2SPeter Wemm 	/*
3604c2aa98e2SPeter Wemm 	**  Some systems (e.g., SunOS) seem to have the call and the
3605c2aa98e2SPeter Wemm 	**  #define _PC_CHOWN_RESTRICTED, but don't actually implement
3606c2aa98e2SPeter Wemm 	**  the call.  This heuristic checks for that.
3607c2aa98e2SPeter Wemm 	*/
3608c2aa98e2SPeter Wemm 
3609c2aa98e2SPeter Wemm 	errno = 0;
3610c2aa98e2SPeter Wemm 	rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
3611c2aa98e2SPeter Wemm #  if SAFENFSPATHCONF
3612c2aa98e2SPeter Wemm 	return errno == 0 && rval IS_SAFE_CHOWN;
36133299c2f1SGregory Neil Shapiro #  else /* SAFENFSPATHCONF */
3614c2aa98e2SPeter Wemm 	return safedir && errno == 0 && rval IS_SAFE_CHOWN;
36153299c2f1SGregory Neil Shapiro #  endif /* SAFENFSPATHCONF */
361612ed1c7cSGregory Neil Shapiro # else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
36173299c2f1SGregory Neil Shapiro 	return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
361812ed1c7cSGregory Neil Shapiro # endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
3619c2aa98e2SPeter Wemm }
362012ed1c7cSGregory Neil Shapiro /*
3621c2aa98e2SPeter Wemm **  RESETLIMITS -- reset system controlled resource limits
3622c2aa98e2SPeter Wemm **
3623c2aa98e2SPeter Wemm **	This is to avoid denial-of-service attacks
3624c2aa98e2SPeter Wemm **
3625c2aa98e2SPeter Wemm **	Parameters:
3626c2aa98e2SPeter Wemm **		none
3627c2aa98e2SPeter Wemm **
3628c2aa98e2SPeter Wemm **	Returns:
3629c2aa98e2SPeter Wemm **		none
3630c2aa98e2SPeter Wemm */
3631c2aa98e2SPeter Wemm 
3632c2aa98e2SPeter Wemm #if HASSETRLIMIT
3633c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H
3634c2aa98e2SPeter Wemm #  include <sys/time.h>
36353299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NEEDS_SYS_TIME_H */
3636c2aa98e2SPeter Wemm # include <sys/resource.h>
36373299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3638c2aa98e2SPeter Wemm #ifndef FD_SETSIZE
3639c2aa98e2SPeter Wemm # define FD_SETSIZE	256
36403299c2f1SGregory Neil Shapiro #endif /* ! FD_SETSIZE */
3641c2aa98e2SPeter Wemm 
3642c2aa98e2SPeter Wemm void
3643c2aa98e2SPeter Wemm resetlimits()
3644c2aa98e2SPeter Wemm {
3645c2aa98e2SPeter Wemm #if HASSETRLIMIT
3646c2aa98e2SPeter Wemm 	struct rlimit lim;
3647c2aa98e2SPeter Wemm 
3648c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
3649c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_CPU, &lim);
3650c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_FSIZE, &lim);
3651c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
3652c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
3653c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_NOFILE, &lim);
36543299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
36553299c2f1SGregory Neil Shapiro #else /* HASSETRLIMIT */
3656c2aa98e2SPeter Wemm # if HASULIMIT
3657c2aa98e2SPeter Wemm 	(void) ulimit(2, 0x3fffff);
3658c2aa98e2SPeter Wemm 	(void) ulimit(4, FD_SETSIZE);
36593299c2f1SGregory Neil Shapiro # endif /* HASULIMIT */
36603299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3661c2aa98e2SPeter Wemm 	errno = 0;
3662c2aa98e2SPeter Wemm }
366312ed1c7cSGregory Neil Shapiro /*
3664c2aa98e2SPeter Wemm **  SETVENDOR -- process vendor code from V configuration line
3665c2aa98e2SPeter Wemm **
3666c2aa98e2SPeter Wemm **	Parameters:
3667c2aa98e2SPeter Wemm **		vendor -- string representation of vendor.
3668c2aa98e2SPeter Wemm **
3669c2aa98e2SPeter Wemm **	Returns:
367012ed1c7cSGregory Neil Shapiro **		true -- if ok.
367112ed1c7cSGregory Neil Shapiro **		false -- if vendor code could not be processed.
3672c2aa98e2SPeter Wemm **
3673c2aa98e2SPeter Wemm **	Side Effects:
3674c2aa98e2SPeter Wemm **		It is reasonable to set mode flags here to tweak
3675c2aa98e2SPeter Wemm **		processing in other parts of the code if necessary.
3676c2aa98e2SPeter Wemm **		For example, if you are a vendor that uses $%y to
3677c2aa98e2SPeter Wemm **		indicate YP lookups, you could enable that here.
3678c2aa98e2SPeter Wemm */
3679c2aa98e2SPeter Wemm 
3680c2aa98e2SPeter Wemm bool
3681c2aa98e2SPeter Wemm setvendor(vendor)
3682c2aa98e2SPeter Wemm 	char *vendor;
3683c2aa98e2SPeter Wemm {
368412ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, "Berkeley") == 0)
3685c2aa98e2SPeter Wemm 	{
3686c2aa98e2SPeter Wemm 		VendorCode = VENDOR_BERKELEY;
368712ed1c7cSGregory Neil Shapiro 		return true;
3688c2aa98e2SPeter Wemm 	}
3689c2aa98e2SPeter Wemm 
3690c2aa98e2SPeter Wemm 	/* add vendor extensions here */
3691c2aa98e2SPeter Wemm 
3692c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
369312ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, "Sun") == 0)
3694c2aa98e2SPeter Wemm 	{
3695c2aa98e2SPeter Wemm 		VendorCode = VENDOR_SUN;
369612ed1c7cSGregory Neil Shapiro 		return true;
3697c2aa98e2SPeter Wemm 	}
36983299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
3699c2aa98e2SPeter Wemm 
370076b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
370112ed1c7cSGregory Neil Shapiro 	if (sm_strcasecmp(vendor, VENDOR_NAME) == 0)
370276b7bf71SPeter Wemm 	{
370376b7bf71SPeter Wemm 		VendorCode = VENDOR_CODE;
370412ed1c7cSGregory Neil Shapiro 		return true;
370576b7bf71SPeter Wemm 	}
37063299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
370776b7bf71SPeter Wemm 
370812ed1c7cSGregory Neil Shapiro 	return false;
3709c2aa98e2SPeter Wemm }
371012ed1c7cSGregory Neil Shapiro /*
371176b7bf71SPeter Wemm **  GETVENDOR -- return vendor name based on vendor code
371276b7bf71SPeter Wemm **
371376b7bf71SPeter Wemm **	Parameters:
371476b7bf71SPeter Wemm **		vendorcode -- numeric representation of vendor.
371576b7bf71SPeter Wemm **
371676b7bf71SPeter Wemm **	Returns:
371776b7bf71SPeter Wemm **		string containing vendor name.
371876b7bf71SPeter Wemm */
371976b7bf71SPeter Wemm 
372076b7bf71SPeter Wemm char *
372176b7bf71SPeter Wemm getvendor(vendorcode)
372276b7bf71SPeter Wemm 	int vendorcode;
372376b7bf71SPeter Wemm {
372476b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
372576b7bf71SPeter Wemm 	/*
372676b7bf71SPeter Wemm 	**  Can't have the same switch case twice so need to
372776b7bf71SPeter Wemm 	**  handle VENDOR_CODE outside of switch.  It might
372876b7bf71SPeter Wemm 	**  match one of the existing VENDOR_* codes.
372976b7bf71SPeter Wemm 	*/
373076b7bf71SPeter Wemm 
373176b7bf71SPeter Wemm 	if (vendorcode == VENDOR_CODE)
373276b7bf71SPeter Wemm 		return VENDOR_NAME;
37333299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
373476b7bf71SPeter Wemm 
373576b7bf71SPeter Wemm 	switch (vendorcode)
373676b7bf71SPeter Wemm 	{
373776b7bf71SPeter Wemm 	  case VENDOR_BERKELEY:
373876b7bf71SPeter Wemm 		return "Berkeley";
373976b7bf71SPeter Wemm 
374076b7bf71SPeter Wemm 	  case VENDOR_SUN:
374176b7bf71SPeter Wemm 		return "Sun";
374276b7bf71SPeter Wemm 
374376b7bf71SPeter Wemm 	  case VENDOR_HP:
374476b7bf71SPeter Wemm 		return "HP";
374576b7bf71SPeter Wemm 
374676b7bf71SPeter Wemm 	  case VENDOR_IBM:
374776b7bf71SPeter Wemm 		return "IBM";
374876b7bf71SPeter Wemm 
374976b7bf71SPeter Wemm 	  case VENDOR_SENDMAIL:
375076b7bf71SPeter Wemm 		return "Sendmail";
375176b7bf71SPeter Wemm 
375276b7bf71SPeter Wemm 	  default:
375376b7bf71SPeter Wemm 		return "Unknown";
375476b7bf71SPeter Wemm 	}
375576b7bf71SPeter Wemm }
375612ed1c7cSGregory Neil Shapiro /*
3757c2aa98e2SPeter Wemm **  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
3758c2aa98e2SPeter Wemm **
3759c2aa98e2SPeter Wemm **	Vendor_pre_defaults is called before reading the configuration
3760c2aa98e2SPeter Wemm **	file; vendor_post_defaults is called immediately after.
3761c2aa98e2SPeter Wemm **
3762c2aa98e2SPeter Wemm **	Parameters:
3763c2aa98e2SPeter Wemm **		e -- the global environment to initialize.
3764c2aa98e2SPeter Wemm **
3765c2aa98e2SPeter Wemm **	Returns:
3766c2aa98e2SPeter Wemm **		none.
3767c2aa98e2SPeter Wemm */
3768c2aa98e2SPeter Wemm 
3769c2aa98e2SPeter Wemm #if SHARE_V1
3770c2aa98e2SPeter Wemm int	DefShareUid;	/* default share uid to run as -- unused??? */
37713299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3772c2aa98e2SPeter Wemm 
3773c2aa98e2SPeter Wemm void
3774c2aa98e2SPeter Wemm vendor_pre_defaults(e)
3775c2aa98e2SPeter Wemm 	ENVELOPE *e;
3776c2aa98e2SPeter Wemm {
3777c2aa98e2SPeter Wemm #if SHARE_V1
3778c2aa98e2SPeter Wemm 	/* OTHERUID is defined in shares.h, do not be alarmed */
3779c2aa98e2SPeter Wemm 	DefShareUid = OTHERUID;
37803299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3781c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3782c2aa98e2SPeter Wemm 	sun_pre_defaults(e);
37833299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
3784c2aa98e2SPeter Wemm #ifdef apollo
37853299c2f1SGregory Neil Shapiro 	/*
37863299c2f1SGregory Neil Shapiro 	**  stupid domain/os can't even open
37873299c2f1SGregory Neil Shapiro 	**  /etc/mail/sendmail.cf without this
37883299c2f1SGregory Neil Shapiro 	*/
37893299c2f1SGregory Neil Shapiro 
3790c2aa98e2SPeter Wemm 	setuserenv("ISP", NULL);
3791c2aa98e2SPeter Wemm 	setuserenv("SYSTYPE", NULL);
37923299c2f1SGregory Neil Shapiro #endif /* apollo */
3793c2aa98e2SPeter Wemm }
3794c2aa98e2SPeter Wemm 
3795c2aa98e2SPeter Wemm 
3796c2aa98e2SPeter Wemm void
3797c2aa98e2SPeter Wemm vendor_post_defaults(e)
3798c2aa98e2SPeter Wemm 	ENVELOPE *e;
3799c2aa98e2SPeter Wemm {
3800c2aa98e2SPeter Wemm #ifdef __QNX__
3801c2aa98e2SPeter Wemm 	char *p;
3802c2aa98e2SPeter Wemm 
3803c2aa98e2SPeter Wemm 	/* Makes sure the SOCK environment variable remains */
3804c2aa98e2SPeter Wemm 	if (p = getextenv("SOCK"))
3805c2aa98e2SPeter Wemm 		setuserenv("SOCK", p);
38063299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
3807c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3808c2aa98e2SPeter Wemm 	sun_post_defaults(e);
38093299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
3810c2aa98e2SPeter Wemm }
381112ed1c7cSGregory Neil Shapiro /*
3812c2aa98e2SPeter Wemm **  VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
3813c2aa98e2SPeter Wemm */
3814c2aa98e2SPeter Wemm 
3815c2aa98e2SPeter Wemm void
3816c2aa98e2SPeter Wemm vendor_daemon_setup(e)
3817c2aa98e2SPeter Wemm 	ENVELOPE *e;
3818c2aa98e2SPeter Wemm {
38193299c2f1SGregory Neil Shapiro #if HASSETLOGIN
38203299c2f1SGregory Neil Shapiro 	(void) setlogin(RunAsUserName);
38213299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
3822c2aa98e2SPeter Wemm #if SECUREWARE
3823c2aa98e2SPeter Wemm 	if (getluid() != -1)
3824c2aa98e2SPeter Wemm 	{
3825c2aa98e2SPeter Wemm 		usrerr("Daemon cannot have LUID");
382612ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_USAGE);
3827c2aa98e2SPeter Wemm 	}
3828c2aa98e2SPeter Wemm #endif /* SECUREWARE */
3829c2aa98e2SPeter Wemm }
383012ed1c7cSGregory Neil Shapiro /*
3831c2aa98e2SPeter Wemm **  VENDOR_SET_UID -- do setup for setting a user id
3832c2aa98e2SPeter Wemm **
3833c2aa98e2SPeter Wemm **	This is called when we are still root.
3834c2aa98e2SPeter Wemm **
3835c2aa98e2SPeter Wemm **	Parameters:
3836c2aa98e2SPeter Wemm **		uid -- the uid we are about to become.
3837c2aa98e2SPeter Wemm **
3838c2aa98e2SPeter Wemm **	Returns:
3839c2aa98e2SPeter Wemm **		none.
3840c2aa98e2SPeter Wemm */
3841c2aa98e2SPeter Wemm 
3842c2aa98e2SPeter Wemm void
3843c2aa98e2SPeter Wemm vendor_set_uid(uid)
3844c2aa98e2SPeter Wemm 	UID_T uid;
3845c2aa98e2SPeter Wemm {
3846c2aa98e2SPeter Wemm 	/*
3847c2aa98e2SPeter Wemm 	**  We need to setup the share groups (lnodes)
38483299c2f1SGregory Neil Shapiro 	**  and add auditing information (luid's)
3849c2aa98e2SPeter Wemm 	**  before we loose our ``root''ness.
3850c2aa98e2SPeter Wemm 	*/
3851c2aa98e2SPeter Wemm #if SHARE_V1
3852c2aa98e2SPeter Wemm 	if (setupshares(uid, syserr) != 0)
3853c2aa98e2SPeter Wemm 		syserr("Unable to set up shares");
38543299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
3855c2aa98e2SPeter Wemm #if SECUREWARE
3856c2aa98e2SPeter Wemm 	(void) setup_secure(uid);
38573299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
3858c2aa98e2SPeter Wemm }
385912ed1c7cSGregory Neil Shapiro /*
3860c2aa98e2SPeter Wemm **  VALIDATE_CONNECTION -- check connection for rationality
3861c2aa98e2SPeter Wemm **
3862c2aa98e2SPeter Wemm **	If the connection is rejected, this routine should log an
3863c2aa98e2SPeter Wemm **	appropriate message -- but should never issue any SMTP protocol.
3864c2aa98e2SPeter Wemm **
3865c2aa98e2SPeter Wemm **	Parameters:
3866c2aa98e2SPeter Wemm **		sap -- a pointer to a SOCKADDR naming the peer.
3867c2aa98e2SPeter Wemm **		hostname -- the name corresponding to sap.
3868c2aa98e2SPeter Wemm **		e -- the current envelope.
3869c2aa98e2SPeter Wemm **
3870c2aa98e2SPeter Wemm **	Returns:
3871c2aa98e2SPeter Wemm **		error message from rejection.
3872c2aa98e2SPeter Wemm **		NULL if not rejected.
3873c2aa98e2SPeter Wemm */
3874c2aa98e2SPeter Wemm 
3875c2aa98e2SPeter Wemm #if TCPWRAPPERS
3876c2aa98e2SPeter Wemm # include <tcpd.h>
3877c2aa98e2SPeter Wemm 
3878c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */
3879c2aa98e2SPeter Wemm int	allow_severity	= LOG_INFO;
3880c2aa98e2SPeter Wemm int	deny_severity	= LOG_NOTICE;
38813299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
3882c2aa98e2SPeter Wemm 
3883c2aa98e2SPeter Wemm char *
3884c2aa98e2SPeter Wemm validate_connection(sap, hostname, e)
3885c2aa98e2SPeter Wemm 	SOCKADDR *sap;
3886c2aa98e2SPeter Wemm 	char *hostname;
3887c2aa98e2SPeter Wemm 	ENVELOPE *e;
3888c2aa98e2SPeter Wemm {
3889c2aa98e2SPeter Wemm #if TCPWRAPPERS
3890c2aa98e2SPeter Wemm 	char *host;
389112ed1c7cSGregory Neil Shapiro 	char *addr;
389212ed1c7cSGregory Neil Shapiro 	extern int hosts_ctl();
38933299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
3894c2aa98e2SPeter Wemm 
3895c2aa98e2SPeter Wemm 	if (tTd(48, 3))
389612ed1c7cSGregory Neil Shapiro 		sm_dprintf("validate_connection(%s, %s)\n",
3897c2aa98e2SPeter Wemm 			hostname, anynet_ntoa(sap));
3898c2aa98e2SPeter Wemm 
38993299c2f1SGregory Neil Shapiro 	if (rscheck("check_relay", hostname, anynet_ntoa(sap),
390012ed1c7cSGregory Neil Shapiro 		    e, true, true, 3, NULL, NOQID) != EX_OK)
3901c2aa98e2SPeter Wemm 	{
3902c2aa98e2SPeter Wemm 		static char reject[BUFSIZ*2];
3903c2aa98e2SPeter Wemm 		extern char MsgBuf[];
3904c2aa98e2SPeter Wemm 
3905c2aa98e2SPeter Wemm 		if (tTd(48, 4))
390612ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (rscheck)\n");
3907c2aa98e2SPeter Wemm 
39083299c2f1SGregory Neil Shapiro 		if (strlen(MsgBuf) >= 3)
390912ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(reject, MsgBuf, sizeof reject);
3910c2aa98e2SPeter Wemm 		else
391112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(reject, "Access denied", sizeof reject);
3912c2aa98e2SPeter Wemm 
3913c2aa98e2SPeter Wemm 		return reject;
3914c2aa98e2SPeter Wemm 	}
3915c2aa98e2SPeter Wemm 
3916c2aa98e2SPeter Wemm #if TCPWRAPPERS
3917c2aa98e2SPeter Wemm 	if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']')
3918c2aa98e2SPeter Wemm 		host = "unknown";
3919c2aa98e2SPeter Wemm 	else
3920c2aa98e2SPeter Wemm 		host = hostname;
392112ed1c7cSGregory Neil Shapiro 	addr = anynet_ntoa(sap);
392212ed1c7cSGregory Neil Shapiro 
392312ed1c7cSGregory Neil Shapiro # if NETINET6
392412ed1c7cSGregory Neil Shapiro 	/* TCP/Wrappers don't want the IPv6: protocol label */
392512ed1c7cSGregory Neil Shapiro 	if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0)
392612ed1c7cSGregory Neil Shapiro 		addr += 5;
392712ed1c7cSGregory Neil Shapiro # endif /* NETINET6 */
392812ed1c7cSGregory Neil Shapiro 
392912ed1c7cSGregory Neil Shapiro 	if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN))
3930c2aa98e2SPeter Wemm 	{
3931c2aa98e2SPeter Wemm 		if (tTd(48, 4))
393212ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (tcpwrappers)\n");
393312ed1c7cSGregory Neil Shapiro 		if (LogLevel > 3)
39343299c2f1SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, e->e_id,
3935c2aa98e2SPeter Wemm 				  "tcpwrappers (%s, %s) rejection",
393612ed1c7cSGregory Neil Shapiro 				  host, addr);
3937c2aa98e2SPeter Wemm 		return "Access denied";
3938c2aa98e2SPeter Wemm 	}
39393299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
3940c2aa98e2SPeter Wemm 	if (tTd(48, 4))
394112ed1c7cSGregory Neil Shapiro 		sm_dprintf("  ... validate_connection: OK\n");
3942c2aa98e2SPeter Wemm 	return NULL;
3943c2aa98e2SPeter Wemm }
3944c2aa98e2SPeter Wemm 
394512ed1c7cSGregory Neil Shapiro /*
3946c2aa98e2SPeter Wemm **  STRTOL -- convert string to long integer
3947c2aa98e2SPeter Wemm **
3948c2aa98e2SPeter Wemm **	For systems that don't have it in the C library.
3949c2aa98e2SPeter Wemm **
3950c2aa98e2SPeter Wemm **	This is taken verbatim from the 4.4-Lite C library.
3951c2aa98e2SPeter Wemm */
3952c2aa98e2SPeter Wemm 
39533299c2f1SGregory Neil Shapiro #if NEEDSTRTOL
3954c2aa98e2SPeter Wemm 
3955c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
3956c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c	8.1 (Berkeley) 6/4/93";
39573299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
3958c2aa98e2SPeter Wemm 
3959c2aa98e2SPeter Wemm /*
396012ed1c7cSGregory Neil Shapiro **  Convert a string to a long integer.
396112ed1c7cSGregory Neil Shapiro **
396212ed1c7cSGregory Neil Shapiro **  Ignores `locale' stuff.  Assumes that the upper and lower case
396312ed1c7cSGregory Neil Shapiro **  alphabets and digits are each contiguous.
3964c2aa98e2SPeter Wemm */
3965c2aa98e2SPeter Wemm 
3966c2aa98e2SPeter Wemm long
3967c2aa98e2SPeter Wemm strtol(nptr, endptr, base)
3968c2aa98e2SPeter Wemm 	const char *nptr;
3969c2aa98e2SPeter Wemm 	char **endptr;
3970c2aa98e2SPeter Wemm 	register int base;
3971c2aa98e2SPeter Wemm {
3972c2aa98e2SPeter Wemm 	register const char *s = nptr;
3973c2aa98e2SPeter Wemm 	register unsigned long acc;
3974c2aa98e2SPeter Wemm 	register int c;
3975c2aa98e2SPeter Wemm 	register unsigned long cutoff;
3976c2aa98e2SPeter Wemm 	register int neg = 0, any, cutlim;
3977c2aa98e2SPeter Wemm 
3978c2aa98e2SPeter Wemm 	/*
397912ed1c7cSGregory Neil Shapiro 	**  Skip white space and pick up leading +/- sign if any.
398012ed1c7cSGregory Neil Shapiro 	**  If base is 0, allow 0x for hex and 0 for octal, else
398112ed1c7cSGregory Neil Shapiro 	**  assume decimal; if base is already 16, allow 0x.
3982c2aa98e2SPeter Wemm 	*/
3983c2aa98e2SPeter Wemm 	do {
3984c2aa98e2SPeter Wemm 		c = *s++;
3985c2aa98e2SPeter Wemm 	} while (isspace(c));
3986c2aa98e2SPeter Wemm 	if (c == '-') {
3987c2aa98e2SPeter Wemm 		neg = 1;
3988c2aa98e2SPeter Wemm 		c = *s++;
3989c2aa98e2SPeter Wemm 	} else if (c == '+')
3990c2aa98e2SPeter Wemm 		c = *s++;
3991c2aa98e2SPeter Wemm 	if ((base == 0 || base == 16) &&
3992c2aa98e2SPeter Wemm 	    c == '0' && (*s == 'x' || *s == 'X')) {
3993c2aa98e2SPeter Wemm 		c = s[1];
3994c2aa98e2SPeter Wemm 		s += 2;
3995c2aa98e2SPeter Wemm 		base = 16;
3996c2aa98e2SPeter Wemm 	}
3997c2aa98e2SPeter Wemm 	if (base == 0)
3998c2aa98e2SPeter Wemm 		base = c == '0' ? 8 : 10;
3999c2aa98e2SPeter Wemm 
4000c2aa98e2SPeter Wemm 	/*
400112ed1c7cSGregory Neil Shapiro 	**  Compute the cutoff value between legal numbers and illegal
400212ed1c7cSGregory Neil Shapiro 	**  numbers.  That is the largest legal value, divided by the
400312ed1c7cSGregory Neil Shapiro 	**  base.  An input number that is greater than this value, if
400412ed1c7cSGregory Neil Shapiro 	**  followed by a legal input character, is too big.  One that
400512ed1c7cSGregory Neil Shapiro 	**  is equal to this value may be valid or not; the limit
400612ed1c7cSGregory Neil Shapiro 	**  between valid and invalid numbers is then based on the last
400712ed1c7cSGregory Neil Shapiro 	**  digit.  For instance, if the range for longs is
400812ed1c7cSGregory Neil Shapiro 	**  [-2147483648..2147483647] and the input base is 10,
400912ed1c7cSGregory Neil Shapiro 	**  cutoff will be set to 214748364 and cutlim to either
401012ed1c7cSGregory Neil Shapiro 	**  7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
401112ed1c7cSGregory Neil Shapiro 	**  a value > 214748364, or equal but the next digit is > 7 (or 8),
401212ed1c7cSGregory Neil Shapiro 	**  the number is too big, and we will return a range error.
401312ed1c7cSGregory Neil Shapiro 	**
401412ed1c7cSGregory Neil Shapiro 	**  Set any if any `digits' consumed; make it negative to indicate
401512ed1c7cSGregory Neil Shapiro 	**  overflow.
4016c2aa98e2SPeter Wemm 	*/
4017c2aa98e2SPeter Wemm 	cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
4018c2aa98e2SPeter Wemm 	cutlim = cutoff % (unsigned long) base;
4019c2aa98e2SPeter Wemm 	cutoff /= (unsigned long) base;
4020c2aa98e2SPeter Wemm 	for (acc = 0, any = 0;; c = *s++) {
4021c2aa98e2SPeter Wemm 		if (isdigit(c))
4022c2aa98e2SPeter Wemm 			c -= '0';
4023c2aa98e2SPeter Wemm 		else if (isalpha(c))
4024c2aa98e2SPeter Wemm 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4025c2aa98e2SPeter Wemm 		else
4026c2aa98e2SPeter Wemm 			break;
4027c2aa98e2SPeter Wemm 		if (c >= base)
4028c2aa98e2SPeter Wemm 			break;
4029c2aa98e2SPeter Wemm 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
4030c2aa98e2SPeter Wemm 			any = -1;
4031c2aa98e2SPeter Wemm 		else {
4032c2aa98e2SPeter Wemm 			any = 1;
4033c2aa98e2SPeter Wemm 			acc *= base;
4034c2aa98e2SPeter Wemm 			acc += c;
4035c2aa98e2SPeter Wemm 		}
4036c2aa98e2SPeter Wemm 	}
4037c2aa98e2SPeter Wemm 	if (any < 0) {
4038c2aa98e2SPeter Wemm 		acc = neg ? LONG_MIN : LONG_MAX;
4039c2aa98e2SPeter Wemm 		errno = ERANGE;
4040c2aa98e2SPeter Wemm 	} else if (neg)
4041c2aa98e2SPeter Wemm 		acc = -acc;
4042c2aa98e2SPeter Wemm 	if (endptr != 0)
4043c2aa98e2SPeter Wemm 		*endptr = (char *)(any ? s - 1 : nptr);
40443299c2f1SGregory Neil Shapiro 	return acc;
4045c2aa98e2SPeter Wemm }
4046c2aa98e2SPeter Wemm 
40473299c2f1SGregory Neil Shapiro #endif /* NEEDSTRTOL */
404812ed1c7cSGregory Neil Shapiro /*
4049c2aa98e2SPeter Wemm **  STRSTR -- find first substring in string
4050c2aa98e2SPeter Wemm **
4051c2aa98e2SPeter Wemm **	Parameters:
4052c2aa98e2SPeter Wemm **		big -- the big (full) string.
4053c2aa98e2SPeter Wemm **		little -- the little (sub) string.
4054c2aa98e2SPeter Wemm **
4055c2aa98e2SPeter Wemm **	Returns:
4056c2aa98e2SPeter Wemm **		A pointer to the first instance of little in big.
4057c2aa98e2SPeter Wemm **		big if little is the null string.
4058c2aa98e2SPeter Wemm **		NULL if little is not contained in big.
4059c2aa98e2SPeter Wemm */
4060c2aa98e2SPeter Wemm 
40613299c2f1SGregory Neil Shapiro #if NEEDSTRSTR
4062c2aa98e2SPeter Wemm 
4063c2aa98e2SPeter Wemm char *
4064c2aa98e2SPeter Wemm strstr(big, little)
4065c2aa98e2SPeter Wemm 	char *big;
4066c2aa98e2SPeter Wemm 	char *little;
4067c2aa98e2SPeter Wemm {
4068c2aa98e2SPeter Wemm 	register char *p = big;
4069c2aa98e2SPeter Wemm 	int l;
4070c2aa98e2SPeter Wemm 
4071c2aa98e2SPeter Wemm 	if (*little == '\0')
4072c2aa98e2SPeter Wemm 		return big;
4073c2aa98e2SPeter Wemm 	l = strlen(little);
4074c2aa98e2SPeter Wemm 
4075c2aa98e2SPeter Wemm 	while ((p = strchr(p, *little)) != NULL)
4076c2aa98e2SPeter Wemm 	{
4077c2aa98e2SPeter Wemm 		if (strncmp(p, little, l) == 0)
4078c2aa98e2SPeter Wemm 			return p;
4079c2aa98e2SPeter Wemm 		p++;
4080c2aa98e2SPeter Wemm 	}
4081c2aa98e2SPeter Wemm 	return NULL;
4082c2aa98e2SPeter Wemm }
4083c2aa98e2SPeter Wemm 
40843299c2f1SGregory Neil Shapiro #endif /* NEEDSTRSTR */
408512ed1c7cSGregory Neil Shapiro /*
4086c2aa98e2SPeter Wemm **  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
4087c2aa98e2SPeter Wemm **
4088c2aa98e2SPeter Wemm **	Some operating systems have wierd problems with the gethostbyXXX
4089c2aa98e2SPeter Wemm **	routines.  For example, Solaris versions at least through 2.3
4090c2aa98e2SPeter Wemm **	don't properly deliver a canonical h_name field.  This tries to
4091c2aa98e2SPeter Wemm **	work around these problems.
40923299c2f1SGregory Neil Shapiro **
40933299c2f1SGregory Neil Shapiro **	Support IPv6 as well as IPv4.
4094c2aa98e2SPeter Wemm */
4095c2aa98e2SPeter Wemm 
4096c0c4794dSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
40973299c2f1SGregory Neil Shapiro 
40983299c2f1SGregory Neil Shapiro # ifndef AI_DEFAULT
40993299c2f1SGregory Neil Shapiro #  define AI_DEFAULT	0	/* dummy */
41003299c2f1SGregory Neil Shapiro # endif /* ! AI_DEFAULT */
41013299c2f1SGregory Neil Shapiro # ifndef AI_ADDRCONFIG
41023299c2f1SGregory Neil Shapiro #  define AI_ADDRCONFIG	0	/* dummy */
41033299c2f1SGregory Neil Shapiro # endif /* ! AI_ADDRCONFIG */
41043299c2f1SGregory Neil Shapiro # ifndef AI_V4MAPPED
41053299c2f1SGregory Neil Shapiro #  define AI_V4MAPPED	0	/* dummy */
41063299c2f1SGregory Neil Shapiro # endif /* ! AI_V4MAPPED */
41073299c2f1SGregory Neil Shapiro # ifndef AI_ALL
41083299c2f1SGregory Neil Shapiro #  define AI_ALL	0	/* dummy */
41093299c2f1SGregory Neil Shapiro # endif /* ! AI_ALL */
41103299c2f1SGregory Neil Shapiro 
41113299c2f1SGregory Neil Shapiro static struct hostent *
41123299c2f1SGregory Neil Shapiro getipnodebyname(name, family, flags, err)
4113c2aa98e2SPeter Wemm 	char *name;
41143299c2f1SGregory Neil Shapiro 	int family;
41153299c2f1SGregory Neil Shapiro 	int flags;
41163299c2f1SGregory Neil Shapiro 	int *err;
41173299c2f1SGregory Neil Shapiro {
411812ed1c7cSGregory Neil Shapiro 	bool resv6 = true;
41193299c2f1SGregory Neil Shapiro 	struct hostent *h;
41203299c2f1SGregory Neil Shapiro 
41213299c2f1SGregory Neil Shapiro 	if (family == AF_INET6)
41223299c2f1SGregory Neil Shapiro 	{
41233299c2f1SGregory Neil Shapiro 		/* From RFC2133, section 6.1 */
41243299c2f1SGregory Neil Shapiro 		resv6 = bitset(RES_USE_INET6, _res.options);
41253299c2f1SGregory Neil Shapiro 		_res.options |= RES_USE_INET6;
41263299c2f1SGregory Neil Shapiro 	}
4127b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
41283299c2f1SGregory Neil Shapiro 	h = gethostbyname(name);
412912ed1c7cSGregory Neil Shapiro 	if (!resv6)
41303299c2f1SGregory Neil Shapiro 		_res.options &= ~RES_USE_INET6;
413112ed1c7cSGregory Neil Shapiro 	*err = h_errno;
41323299c2f1SGregory Neil Shapiro 	return h;
41333299c2f1SGregory Neil Shapiro }
41343299c2f1SGregory Neil Shapiro 
41353299c2f1SGregory Neil Shapiro static struct hostent *
41363299c2f1SGregory Neil Shapiro getipnodebyaddr(addr, len, family, err)
41373299c2f1SGregory Neil Shapiro 	char *addr;
41383299c2f1SGregory Neil Shapiro 	int len;
41393299c2f1SGregory Neil Shapiro 	int family;
41403299c2f1SGregory Neil Shapiro 	int *err;
4141c2aa98e2SPeter Wemm {
4142c2aa98e2SPeter Wemm 	struct hostent *h;
41433299c2f1SGregory Neil Shapiro 
4144b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
41453299c2f1SGregory Neil Shapiro 	h = gethostbyaddr(addr, len, family);
41463299c2f1SGregory Neil Shapiro 	*err = h_errno;
41473299c2f1SGregory Neil Shapiro 	return h;
41483299c2f1SGregory Neil Shapiro }
4149c46d91b7SGregory Neil Shapiro 
4150c46d91b7SGregory Neil Shapiro void
4151c46d91b7SGregory Neil Shapiro freehostent(h)
4152c46d91b7SGregory Neil Shapiro 	struct hostent *h;
4153c46d91b7SGregory Neil Shapiro {
4154c46d91b7SGregory Neil Shapiro 	/*
4155c46d91b7SGregory Neil Shapiro 	**  Stub routine -- if they don't have getipnodeby*(),
4156c46d91b7SGregory Neil Shapiro 	**  they probably don't have the free routine either.
4157c46d91b7SGregory Neil Shapiro 	*/
4158c46d91b7SGregory Neil Shapiro 
4159c46d91b7SGregory Neil Shapiro 	return;
4160c46d91b7SGregory Neil Shapiro }
416112ed1c7cSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */
41623299c2f1SGregory Neil Shapiro 
41633299c2f1SGregory Neil Shapiro struct hostent *
41643299c2f1SGregory Neil Shapiro sm_gethostbyname(name, family)
41653299c2f1SGregory Neil Shapiro 	char *name;
41663299c2f1SGregory Neil Shapiro 	int family;
41673299c2f1SGregory Neil Shapiro {
4168b4662009SGregory Neil Shapiro 	int save_errno;
41693299c2f1SGregory Neil Shapiro 	struct hostent *h = NULL;
4170c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
4171c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4172c2aa98e2SPeter Wemm 	static struct hostent hp;
4173c2aa98e2SPeter Wemm 	static char buf[1000];
4174c2aa98e2SPeter Wemm 	extern struct hostent *_switch_gethostbyname_r();
4175c2aa98e2SPeter Wemm 
4176c2aa98e2SPeter Wemm 	if (tTd(61, 10))
417712ed1c7cSGregory Neil Shapiro 		sm_dprintf("_switch_gethostbyname_r(%s)... ", name);
4178c2aa98e2SPeter Wemm 	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
4179b4662009SGregory Neil Shapiro 	save_errno = errno;
41803299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4181c2aa98e2SPeter Wemm 	extern struct hostent *__switch_gethostbyname();
4182c2aa98e2SPeter Wemm 
4183c2aa98e2SPeter Wemm 	if (tTd(61, 10))
418412ed1c7cSGregory Neil Shapiro 		sm_dprintf("__switch_gethostbyname(%s)... ", name);
4185c2aa98e2SPeter Wemm 	h = __switch_gethostbyname(name);
4186b4662009SGregory Neil Shapiro 	save_errno = errno;
41873299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
41883299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4189c2aa98e2SPeter Wemm 	int nmaps;
41903299c2f1SGregory Neil Shapiro # if NETINET6
41913299c2f1SGregory Neil Shapiro 	int flags = AI_DEFAULT|AI_ALL;
41923299c2f1SGregory Neil Shapiro 	int err;
41933299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4194c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
4195c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
4196c2aa98e2SPeter Wemm 	char hbuf[MAXNAME];
4197c2aa98e2SPeter Wemm 
4198c2aa98e2SPeter Wemm 	if (tTd(61, 10))
419912ed1c7cSGregory Neil Shapiro 		sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family);
42003299c2f1SGregory Neil Shapiro 
42013299c2f1SGregory Neil Shapiro # if NETINET6
42023299c2f1SGregory Neil Shapiro #  if ADDRCONFIG_IS_BROKEN
42033299c2f1SGregory Neil Shapiro 	flags &= ~AI_ADDRCONFIG;
42043299c2f1SGregory Neil Shapiro #  endif /* ADDRCONFIG_IS_BROKEN */
42053299c2f1SGregory Neil Shapiro 	h = getipnodebyname(name, family, flags, &err);
4206b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(err);
42073299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4208c2aa98e2SPeter Wemm 	h = gethostbyname(name);
42093299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
42103299c2f1SGregory Neil Shapiro 
42113299c2f1SGregory Neil Shapiro 	save_errno = errno;
4212c2aa98e2SPeter Wemm 	if (h == NULL)
4213c2aa98e2SPeter Wemm 	{
4214c2aa98e2SPeter Wemm 		if (tTd(61, 10))
421512ed1c7cSGregory Neil Shapiro 			sm_dprintf("failure\n");
4216c2aa98e2SPeter Wemm 
4217c2aa98e2SPeter Wemm 		nmaps = switch_map_find("hosts", maptype, mapreturn);
4218c2aa98e2SPeter Wemm 		while (--nmaps >= 0)
4219c46d91b7SGregory Neil Shapiro 		{
4220c2aa98e2SPeter Wemm 			if (strcmp(maptype[nmaps], "nis") == 0 ||
4221c2aa98e2SPeter Wemm 			    strcmp(maptype[nmaps], "files") == 0)
4222c2aa98e2SPeter Wemm 				break;
4223c46d91b7SGregory Neil Shapiro 		}
4224c46d91b7SGregory Neil Shapiro 
4225c2aa98e2SPeter Wemm 		if (nmaps >= 0)
4226c2aa98e2SPeter Wemm 		{
4227c2aa98e2SPeter Wemm 			/* try short name */
422812ed1c7cSGregory Neil Shapiro 			if (strlen(name) > sizeof hbuf - 1)
42293299c2f1SGregory Neil Shapiro 			{
42303299c2f1SGregory Neil Shapiro 				errno = save_errno;
4231c2aa98e2SPeter Wemm 				return NULL;
42323299c2f1SGregory Neil Shapiro 			}
423312ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(hbuf, name, sizeof hbuf);
4234b4662009SGregory Neil Shapiro 			(void) shorten_hostname(hbuf);
4235c2aa98e2SPeter Wemm 
4236c2aa98e2SPeter Wemm 			/* if it hasn't been shortened, there's no point */
4237c2aa98e2SPeter Wemm 			if (strcmp(hbuf, name) != 0)
4238c2aa98e2SPeter Wemm 			{
4239c2aa98e2SPeter Wemm 				if (tTd(61, 10))
424012ed1c7cSGregory Neil Shapiro 					sm_dprintf("sm_gethostbyname(%s, %d)... ",
42413299c2f1SGregory Neil Shapiro 					       hbuf, family);
42423299c2f1SGregory Neil Shapiro 
42433299c2f1SGregory Neil Shapiro # if NETINET6
42446dbce3c3SGregory Neil Shapiro 				h = getipnodebyname(hbuf, family, flags, &err);
4245b4662009SGregory Neil Shapiro 				SM_SET_H_ERRNO(err);
42463299c2f1SGregory Neil Shapiro 				save_errno = errno;
42473299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4248c2aa98e2SPeter Wemm 				h = gethostbyname(hbuf);
42493299c2f1SGregory Neil Shapiro 				save_errno = errno;
42503299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4251c2aa98e2SPeter Wemm 			}
4252c2aa98e2SPeter Wemm 		}
4253c2aa98e2SPeter Wemm 	}
42543299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4255c2aa98e2SPeter Wemm 	if (tTd(61, 10))
4256c2aa98e2SPeter Wemm 	{
4257c2aa98e2SPeter Wemm 		if (h == NULL)
425812ed1c7cSGregory Neil Shapiro 			sm_dprintf("failure\n");
4259c2aa98e2SPeter Wemm 		else
42603299c2f1SGregory Neil Shapiro 		{
426112ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", h->h_name);
42623299c2f1SGregory Neil Shapiro 			if (tTd(61, 11))
42633299c2f1SGregory Neil Shapiro 			{
42643299c2f1SGregory Neil Shapiro #if NETINET6
42653299c2f1SGregory Neil Shapiro 				struct in6_addr ia6;
42663299c2f1SGregory Neil Shapiro 				char buf6[INET6_ADDRSTRLEN];
42673299c2f1SGregory Neil Shapiro #else /* NETINET6 */
42683299c2f1SGregory Neil Shapiro 				struct in_addr ia;
42693299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
427012ed1c7cSGregory Neil Shapiro 				size_t i;
42713299c2f1SGregory Neil Shapiro 
42723299c2f1SGregory Neil Shapiro 				if (h->h_aliases != NULL)
42733299c2f1SGregory Neil Shapiro 					for (i = 0; h->h_aliases[i] != NULL;
42743299c2f1SGregory Neil Shapiro 					     i++)
427512ed1c7cSGregory Neil Shapiro 						sm_dprintf("\talias: %s\n",
42763299c2f1SGregory Neil Shapiro 							h->h_aliases[i]);
42773299c2f1SGregory Neil Shapiro 				for (i = 0; h->h_addr_list[i] != NULL; i++)
42783299c2f1SGregory Neil Shapiro 				{
42793299c2f1SGregory Neil Shapiro 					char *addr;
42803299c2f1SGregory Neil Shapiro 
42813299c2f1SGregory Neil Shapiro #if NETINET6
42823299c2f1SGregory Neil Shapiro 					memmove(&ia6, h->h_addr_list[i],
42833299c2f1SGregory Neil Shapiro 						IN6ADDRSZ);
42843299c2f1SGregory Neil Shapiro 					addr = anynet_ntop(&ia6,
42853299c2f1SGregory Neil Shapiro 							   buf6, sizeof buf6);
42863299c2f1SGregory Neil Shapiro #else /* NETINET6 */
42873299c2f1SGregory Neil Shapiro 					memmove(&ia, h->h_addr_list[i],
42883299c2f1SGregory Neil Shapiro 						INADDRSZ);
42893299c2f1SGregory Neil Shapiro 					addr = (char *) inet_ntoa(ia);
42903299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
42913299c2f1SGregory Neil Shapiro 					if (addr != NULL)
429212ed1c7cSGregory Neil Shapiro 						sm_dprintf("\taddr: %s\n", addr);
4293c2aa98e2SPeter Wemm 				}
42943299c2f1SGregory Neil Shapiro 			}
42953299c2f1SGregory Neil Shapiro 		}
42963299c2f1SGregory Neil Shapiro 	}
42973299c2f1SGregory Neil Shapiro 	errno = save_errno;
4298c2aa98e2SPeter Wemm 	return h;
4299c2aa98e2SPeter Wemm }
4300c2aa98e2SPeter Wemm 
4301c2aa98e2SPeter Wemm struct hostent *
4302c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type)
4303c2aa98e2SPeter Wemm 	char *addr;
4304c2aa98e2SPeter Wemm 	int len;
4305c2aa98e2SPeter Wemm 	int type;
4306c2aa98e2SPeter Wemm {
43073299c2f1SGregory Neil Shapiro 	struct hostent *hp;
4308b4662009SGregory Neil Shapiro 
4309b4662009SGregory Neil Shapiro #if NETINET6
4310b4662009SGregory Neil Shapiro 	if (type == AF_INET6 &&
4311b4662009SGregory Neil Shapiro 	    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr))
4312b4662009SGregory Neil Shapiro 	{
4313b4662009SGregory Neil Shapiro 		/* Avoid reverse lookup for IPv6 unspecified address */
4314b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(HOST_NOT_FOUND);
4315b4662009SGregory Neil Shapiro 		return NULL;
4316b4662009SGregory Neil Shapiro 	}
4317b4662009SGregory Neil Shapiro #endif /* NETINET6 */
4318b4662009SGregory Neil Shapiro 
4319c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204)
4320c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4321b4662009SGregory Neil Shapiro 	{
43223299c2f1SGregory Neil Shapiro 		static struct hostent he;
4323c2aa98e2SPeter Wemm 		static char buf[1000];
4324c2aa98e2SPeter Wemm 		extern struct hostent *_switch_gethostbyaddr_r();
4325c2aa98e2SPeter Wemm 
4326b4662009SGregory Neil Shapiro 		hp = _switch_gethostbyaddr_r(addr, len, type, &he,
4327b4662009SGregory Neil Shapiro 					     buf, sizeof(buf), &h_errno);
4328b4662009SGregory Neil Shapiro 	}
43293299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4330b4662009SGregory Neil Shapiro 	{
4331c2aa98e2SPeter Wemm 		extern struct hostent *__switch_gethostbyaddr();
4332c2aa98e2SPeter Wemm 
43333299c2f1SGregory Neil Shapiro 		hp = __switch_gethostbyaddr(addr, len, type);
4334b4662009SGregory Neil Shapiro 	}
43353299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
43363299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
43373299c2f1SGregory Neil Shapiro # if NETINET6
4338b4662009SGregory Neil Shapiro 	{
43393299c2f1SGregory Neil Shapiro 		int err;
43403299c2f1SGregory Neil Shapiro 
43413299c2f1SGregory Neil Shapiro 		hp = getipnodebyaddr(addr, len, type, &err);
4342b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(err);
4343b4662009SGregory Neil Shapiro 	}
43443299c2f1SGregory Neil Shapiro # else /* NETINET6 */
43453299c2f1SGregory Neil Shapiro 	hp = gethostbyaddr(addr, len, type);
43463299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
43473299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
4348c0c4794dSGregory Neil Shapiro 	return hp;
4349c2aa98e2SPeter Wemm }
435012ed1c7cSGregory Neil Shapiro /*
4351c2aa98e2SPeter Wemm **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
4352c2aa98e2SPeter Wemm */
4353c2aa98e2SPeter Wemm 
4354c2aa98e2SPeter Wemm struct passwd *
4355c2aa98e2SPeter Wemm sm_getpwnam(user)
4356c2aa98e2SPeter Wemm 	char *user;
4357c2aa98e2SPeter Wemm {
4358c2aa98e2SPeter Wemm #ifdef _AIX4
4359c2aa98e2SPeter Wemm 	extern struct passwd *_getpwnam_shadow(const char *, const int);
4360c2aa98e2SPeter Wemm 
4361c2aa98e2SPeter Wemm 	return _getpwnam_shadow(user, 0);
43623299c2f1SGregory Neil Shapiro #else /* _AIX4 */
4363c2aa98e2SPeter Wemm 	return getpwnam(user);
43643299c2f1SGregory Neil Shapiro #endif /* _AIX4 */
4365c2aa98e2SPeter Wemm }
4366c2aa98e2SPeter Wemm 
4367c2aa98e2SPeter Wemm struct passwd *
4368c2aa98e2SPeter Wemm sm_getpwuid(uid)
4369c2aa98e2SPeter Wemm 	UID_T uid;
4370c2aa98e2SPeter Wemm {
4371c2aa98e2SPeter Wemm #if defined(_AIX4) && 0
4372c2aa98e2SPeter Wemm 	extern struct passwd *_getpwuid_shadow(const int, const int);
4373c2aa98e2SPeter Wemm 
4374c2aa98e2SPeter Wemm 	return _getpwuid_shadow(uid,0);
43753299c2f1SGregory Neil Shapiro #else /* defined(_AIX4) && 0 */
4376c2aa98e2SPeter Wemm 	return getpwuid(uid);
43773299c2f1SGregory Neil Shapiro #endif /* defined(_AIX4) && 0 */
4378c2aa98e2SPeter Wemm }
437912ed1c7cSGregory Neil Shapiro /*
4380c2aa98e2SPeter Wemm **  SECUREWARE_SETUP_SECURE -- Convex SecureWare setup
4381c2aa98e2SPeter Wemm **
4382c2aa98e2SPeter Wemm **	Set up the trusted computing environment for C2 level security
4383c2aa98e2SPeter Wemm **	under SecureWare.
4384c2aa98e2SPeter Wemm **
4385c2aa98e2SPeter Wemm **	Parameters:
4386c2aa98e2SPeter Wemm **		uid -- uid of the user to initialize in the TCB
4387c2aa98e2SPeter Wemm **
4388c2aa98e2SPeter Wemm **	Returns:
4389c2aa98e2SPeter Wemm **		none
4390c2aa98e2SPeter Wemm **
4391c2aa98e2SPeter Wemm **	Side Effects:
4392c2aa98e2SPeter Wemm **		Initialized the user in the trusted computing base
4393c2aa98e2SPeter Wemm */
4394c2aa98e2SPeter Wemm 
4395c2aa98e2SPeter Wemm #if SECUREWARE
4396c2aa98e2SPeter Wemm 
4397c2aa98e2SPeter Wemm # include <sys/security.h>
4398c2aa98e2SPeter Wemm # include <prot.h>
4399c2aa98e2SPeter Wemm 
4400c2aa98e2SPeter Wemm void
4401c2aa98e2SPeter Wemm secureware_setup_secure(uid)
4402c2aa98e2SPeter Wemm 	UID_T uid;
4403c2aa98e2SPeter Wemm {
4404c2aa98e2SPeter Wemm 	int rc;
4405c2aa98e2SPeter Wemm 
4406c2aa98e2SPeter Wemm 	if (getluid() != -1)
4407c2aa98e2SPeter Wemm 		return;
4408c2aa98e2SPeter Wemm 
4409c2aa98e2SPeter Wemm 	if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN)
4410c2aa98e2SPeter Wemm 	{
4411c2aa98e2SPeter Wemm 		switch (rc)
4412c2aa98e2SPeter Wemm 		{
4413c2aa98e2SPeter Wemm 		  case SSI_NO_PRPW_ENTRY:
441412ed1c7cSGregory Neil Shapiro 			syserr("No protected passwd entry, uid = %d",
441512ed1c7cSGregory Neil Shapiro 			       (int) uid);
4416c2aa98e2SPeter Wemm 			break;
4417c2aa98e2SPeter Wemm 
4418c2aa98e2SPeter Wemm 		  case SSI_LOCKED:
441912ed1c7cSGregory Neil Shapiro 			syserr("Account has been disabled, uid = %d",
442012ed1c7cSGregory Neil Shapiro 			       (int) uid);
4421c2aa98e2SPeter Wemm 			break;
4422c2aa98e2SPeter Wemm 
4423c2aa98e2SPeter Wemm 		  case SSI_RETIRED:
442412ed1c7cSGregory Neil Shapiro 			syserr("Account has been retired, uid = %d",
442512ed1c7cSGregory Neil Shapiro 			       (int) uid);
4426c2aa98e2SPeter Wemm 			break;
4427c2aa98e2SPeter Wemm 
4428c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_LUID:
442912ed1c7cSGregory Neil Shapiro 			syserr("Could not set LUID, uid = %d", (int) uid);
4430c2aa98e2SPeter Wemm 			break;
4431c2aa98e2SPeter Wemm 
4432c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_PRIVS:
443312ed1c7cSGregory Neil Shapiro 			syserr("Could not set kernel privs, uid = %d",
443412ed1c7cSGregory Neil Shapiro 			       (int) uid);
4435c2aa98e2SPeter Wemm 
4436c2aa98e2SPeter Wemm 		  default:
4437c2aa98e2SPeter Wemm 			syserr("Unknown return code (%d) from set_secure_info(%d)",
443812ed1c7cSGregory Neil Shapiro 				rc, (int) uid);
4439c2aa98e2SPeter Wemm 			break;
4440c2aa98e2SPeter Wemm 		}
444112ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_NOPERM);
4442c2aa98e2SPeter Wemm 	}
4443c2aa98e2SPeter Wemm }
4444c2aa98e2SPeter Wemm #endif /* SECUREWARE */
444512ed1c7cSGregory Neil Shapiro /*
44463299c2f1SGregory Neil Shapiro **  ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address
444776b7bf71SPeter Wemm **
444876b7bf71SPeter Wemm **	Add hostnames to class 'w' based on the IP address read from
444976b7bf71SPeter Wemm **	the network interface.
445076b7bf71SPeter Wemm **
445176b7bf71SPeter Wemm **	Parameters:
445276b7bf71SPeter Wemm **		sa -- a pointer to a SOCKADDR containing the address
445376b7bf71SPeter Wemm **
445476b7bf71SPeter Wemm **	Returns:
445576b7bf71SPeter Wemm **		0 if successful, -1 if host lookup fails.
445676b7bf71SPeter Wemm */
445776b7bf71SPeter Wemm 
44583299c2f1SGregory Neil Shapiro static int
445976b7bf71SPeter Wemm add_hostnames(sa)
446076b7bf71SPeter Wemm 	SOCKADDR *sa;
446176b7bf71SPeter Wemm {
446276b7bf71SPeter Wemm 	struct hostent *hp;
44633299c2f1SGregory Neil Shapiro 	char **ha;
44643299c2f1SGregory Neil Shapiro 	char hnb[MAXHOSTNAMELEN];
446576b7bf71SPeter Wemm 
446676b7bf71SPeter Wemm 	/* lookup name with IP address */
446776b7bf71SPeter Wemm 	switch (sa->sa.sa_family)
446876b7bf71SPeter Wemm 	{
44693299c2f1SGregory Neil Shapiro #if NETINET
447076b7bf71SPeter Wemm 	  case AF_INET:
447176b7bf71SPeter Wemm 		hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr,
4472c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin.sin_addr),
4473c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
447476b7bf71SPeter Wemm 		break;
44753299c2f1SGregory Neil Shapiro #endif /* NETINET */
44763299c2f1SGregory Neil Shapiro 
44773299c2f1SGregory Neil Shapiro #if NETINET6
44783299c2f1SGregory Neil Shapiro 	  case AF_INET6:
44793299c2f1SGregory Neil Shapiro 		hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr,
4480c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin6.sin6_addr),
4481c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
44823299c2f1SGregory Neil Shapiro 		break;
44833299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
448476b7bf71SPeter Wemm 
448576b7bf71SPeter Wemm 	  default:
44863299c2f1SGregory Neil Shapiro 		/* Give warning about unsupported family */
448776b7bf71SPeter Wemm 		if (LogLevel > 3)
448876b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
448976b7bf71SPeter Wemm 				  "Unsupported address family %d: %.100s",
449076b7bf71SPeter Wemm 				  sa->sa.sa_family, anynet_ntoa(sa));
449176b7bf71SPeter Wemm 		return -1;
449276b7bf71SPeter Wemm 	}
449376b7bf71SPeter Wemm 
449476b7bf71SPeter Wemm 	if (hp == NULL)
449576b7bf71SPeter Wemm 	{
449676b7bf71SPeter Wemm 		int save_errno = errno;
449776b7bf71SPeter Wemm 
44983299c2f1SGregory Neil Shapiro 		if (LogLevel > 3 &&
44993299c2f1SGregory Neil Shapiro #if NETINET6
45003299c2f1SGregory Neil Shapiro 		    !(sa->sa.sa_family == AF_INET6 &&
45013299c2f1SGregory Neil Shapiro 		      IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
45023299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
450312ed1c7cSGregory Neil Shapiro 		    true)
450476b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
450512ed1c7cSGregory Neil Shapiro 				  "gethostbyaddr(%.100s) failed: %d",
450676b7bf71SPeter Wemm 				  anynet_ntoa(sa),
450776b7bf71SPeter Wemm #if NAMED_BIND
450876b7bf71SPeter Wemm 				  h_errno
45093299c2f1SGregory Neil Shapiro #else /* NAMED_BIND */
451076b7bf71SPeter Wemm 				  -1
45113299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
451276b7bf71SPeter Wemm 				 );
451376b7bf71SPeter Wemm 		errno = save_errno;
451476b7bf71SPeter Wemm 		return -1;
451576b7bf71SPeter Wemm 	}
451676b7bf71SPeter Wemm 
451776b7bf71SPeter Wemm 	/* save its cname */
451876b7bf71SPeter Wemm 	if (!wordinclass((char *) hp->h_name, 'w'))
451976b7bf71SPeter Wemm 	{
452076b7bf71SPeter Wemm 		setclass('w', (char *) hp->h_name);
452176b7bf71SPeter Wemm 		if (tTd(0, 4))
452212ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s\n", hp->h_name);
45233299c2f1SGregory Neil Shapiro 
452412ed1c7cSGregory Neil Shapiro 		if (sm_snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb
45253299c2f1SGregory Neil Shapiro 		    && !wordinclass((char *) hnb, 'w'))
45263299c2f1SGregory Neil Shapiro 			setclass('w', hnb);
45273299c2f1SGregory Neil Shapiro 	}
45283299c2f1SGregory Neil Shapiro 	else
45293299c2f1SGregory Neil Shapiro 	{
45303299c2f1SGregory Neil Shapiro 		if (tTd(0, 43))
453112ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name);
453276b7bf71SPeter Wemm 	}
453376b7bf71SPeter Wemm 
453476b7bf71SPeter Wemm 	/* save all it aliases name */
45353299c2f1SGregory Neil Shapiro 	for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
453676b7bf71SPeter Wemm 	{
45373299c2f1SGregory Neil Shapiro 		if (!wordinclass(*ha, 'w'))
453876b7bf71SPeter Wemm 		{
45393299c2f1SGregory Neil Shapiro 			setclass('w', *ha);
454076b7bf71SPeter Wemm 			if (tTd(0, 4))
454112ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", *ha);
454212ed1c7cSGregory Neil Shapiro 			if (sm_snprintf(hnb, sizeof hnb,
45433299c2f1SGregory Neil Shapiro 				     "[%s]", *ha) < sizeof hnb &&
45443299c2f1SGregory Neil Shapiro 			    !wordinclass((char *) hnb, 'w'))
45453299c2f1SGregory Neil Shapiro 				setclass('w', hnb);
454676b7bf71SPeter Wemm 		}
45473299c2f1SGregory Neil Shapiro 		else
45483299c2f1SGregory Neil Shapiro 		{
45493299c2f1SGregory Neil Shapiro 			if (tTd(0, 43))
455012ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s (already in $=w)\n",
45513299c2f1SGregory Neil Shapiro 					*ha);
45523299c2f1SGregory Neil Shapiro 		}
455376b7bf71SPeter Wemm 	}
455412ed1c7cSGregory Neil Shapiro #if NETINET6
4555c46d91b7SGregory Neil Shapiro 	freehostent(hp);
455612ed1c7cSGregory Neil Shapiro #endif /* NETINET6 */
455776b7bf71SPeter Wemm 	return 0;
455876b7bf71SPeter Wemm }
455912ed1c7cSGregory Neil Shapiro /*
4560c2aa98e2SPeter Wemm **  LOAD_IF_NAMES -- load interface-specific names into $=w
4561c2aa98e2SPeter Wemm **
4562c2aa98e2SPeter Wemm **	Parameters:
4563c2aa98e2SPeter Wemm **		none.
4564c2aa98e2SPeter Wemm **
4565c2aa98e2SPeter Wemm **	Returns:
4566c2aa98e2SPeter Wemm **		none.
4567c2aa98e2SPeter Wemm **
4568c2aa98e2SPeter Wemm **	Side Effects:
4569c2aa98e2SPeter Wemm **		Loads $=w with the names of all the interfaces.
4570c2aa98e2SPeter Wemm */
4571c2aa98e2SPeter Wemm 
45723299c2f1SGregory Neil Shapiro #if !NETINET
45733299c2f1SGregory Neil Shapiro # define SIOCGIFCONF_IS_BROKEN	1 /* XXX */
45743299c2f1SGregory Neil Shapiro #endif /* !NETINET */
45753299c2f1SGregory Neil Shapiro 
4576c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4577c2aa98e2SPeter Wemm struct rtentry;
4578c2aa98e2SPeter Wemm struct mbuf;
4579c2aa98e2SPeter Wemm # ifndef SUNOS403
4580c2aa98e2SPeter Wemm #  include <sys/time.h>
45813299c2f1SGregory Neil Shapiro # endif /* ! SUNOS403 */
45823299c2f1SGregory Neil Shapiro # if (_AIX4 >= 40300) && !defined(_NET_IF_H)
4583c2aa98e2SPeter Wemm #  undef __P
45843299c2f1SGregory Neil Shapiro # endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */
4585c2aa98e2SPeter Wemm # include <net/if.h>
45863299c2f1SGregory Neil Shapiro #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
4587c2aa98e2SPeter Wemm 
4588c2aa98e2SPeter Wemm void
4589c2aa98e2SPeter Wemm load_if_names()
4590c2aa98e2SPeter Wemm {
45913299c2f1SGregory Neil Shapiro # if NETINET6 && defined(SIOCGLIFCONF)
459212ed1c7cSGregory Neil Shapiro #  ifdef __hpux
459312ed1c7cSGregory Neil Shapiro 
459412ed1c7cSGregory Neil Shapiro     /*
459512ed1c7cSGregory Neil Shapiro     **  Unfortunately, HP has changed all of the structures,
459612ed1c7cSGregory Neil Shapiro     **  making life difficult for implementors.
459712ed1c7cSGregory Neil Shapiro     */
459812ed1c7cSGregory Neil Shapiro 
459912ed1c7cSGregory Neil Shapiro #   define lifconf	if_laddrconf
460012ed1c7cSGregory Neil Shapiro #   define lifc_len	iflc_len
460112ed1c7cSGregory Neil Shapiro #   define lifc_buf	iflc_buf
460212ed1c7cSGregory Neil Shapiro #   define lifreq	if_laddrreq
460312ed1c7cSGregory Neil Shapiro #   define lifr_addr	iflr_addr
460412ed1c7cSGregory Neil Shapiro #   define lifr_name	iflr_name
460512ed1c7cSGregory Neil Shapiro #   define lifr_flags	iflr_flags
460612ed1c7cSGregory Neil Shapiro #   define ss_family	sa_family
460712ed1c7cSGregory Neil Shapiro #   undef SIOCGLIFNUM
460812ed1c7cSGregory Neil Shapiro #  endif /* __hpux */
460912ed1c7cSGregory Neil Shapiro 
46103299c2f1SGregory Neil Shapiro 	int s;
46113299c2f1SGregory Neil Shapiro 	int i;
461212ed1c7cSGregory Neil Shapiro 	size_t len;
46133299c2f1SGregory Neil Shapiro 	int numifs;
461412ed1c7cSGregory Neil Shapiro 	char *buf;
461512ed1c7cSGregory Neil Shapiro 	struct lifconf lifc;
461612ed1c7cSGregory Neil Shapiro #  ifdef SIOCGLIFNUM
461712ed1c7cSGregory Neil Shapiro 	struct lifnum lifn;
461812ed1c7cSGregory Neil Shapiro #  endif /* SIOCGLIFNUM */
46193299c2f1SGregory Neil Shapiro 
46203299c2f1SGregory Neil Shapiro 	s = socket(InetMode, SOCK_DGRAM, 0);
46213299c2f1SGregory Neil Shapiro 	if (s == -1)
46223299c2f1SGregory Neil Shapiro 		return;
46233299c2f1SGregory Neil Shapiro 
46243299c2f1SGregory Neil Shapiro 	/* get the list of known IP address from the kernel */
462512ed1c7cSGregory Neil Shapiro #  ifdef __hpux
462612ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGIFNUM, (char *) &numifs);
462712ed1c7cSGregory Neil Shapiro #  endif /* __hpux */
46283299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFNUM
46293299c2f1SGregory Neil Shapiro 	lifn.lifn_family = AF_UNSPEC;
46303299c2f1SGregory Neil Shapiro 	lifn.lifn_flags = 0;
463112ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGLIFNUM, (char *)&lifn);
463212ed1c7cSGregory Neil Shapiro 	numifs = lifn.lifn_count;
463312ed1c7cSGregory Neil Shapiro #  endif /* SIOCGLIFNUM */
463412ed1c7cSGregory Neil Shapiro 
463512ed1c7cSGregory Neil Shapiro #  if defined(__hpux) || defined(SIOCGLIFNUM)
463612ed1c7cSGregory Neil Shapiro 	if (i < 0)
46373299c2f1SGregory Neil Shapiro 	{
46383299c2f1SGregory Neil Shapiro 		/* can't get number of interfaces -- fall back */
46393299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
464012ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFNUM failed: %s\n",
464112ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
46423299c2f1SGregory Neil Shapiro 		numifs = -1;
46433299c2f1SGregory Neil Shapiro 	}
464412ed1c7cSGregory Neil Shapiro 	else if (tTd(0, 42))
464512ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
46463299c2f1SGregory Neil Shapiro 	if (numifs < 0)
464712ed1c7cSGregory Neil Shapiro #  endif /* defined(__hpux) || defined(SIOCGLIFNUM) */
46483299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
46493299c2f1SGregory Neil Shapiro 
46503299c2f1SGregory Neil Shapiro 	if (numifs <= 0)
46513299c2f1SGregory Neil Shapiro 	{
4652c46d91b7SGregory Neil Shapiro 		(void) close(s);
46533299c2f1SGregory Neil Shapiro 		return;
46543299c2f1SGregory Neil Shapiro 	}
465512ed1c7cSGregory Neil Shapiro 
465612ed1c7cSGregory Neil Shapiro 	len = lifc.lifc_len = numifs * sizeof (struct lifreq);
465712ed1c7cSGregory Neil Shapiro 	buf = lifc.lifc_buf = xalloc(lifc.lifc_len);
465812ed1c7cSGregory Neil Shapiro #  ifndef __hpux
46593299c2f1SGregory Neil Shapiro 	lifc.lifc_family = AF_UNSPEC;
46603299c2f1SGregory Neil Shapiro 	lifc.lifc_flags = 0;
466112ed1c7cSGregory Neil Shapiro #  endif /* __hpux */
46623299c2f1SGregory Neil Shapiro 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
46633299c2f1SGregory Neil Shapiro 	{
46643299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
466512ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFCONF failed: %s\n",
466612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
4667c46d91b7SGregory Neil Shapiro 		(void) close(s);
466812ed1c7cSGregory Neil Shapiro 		sm_free(buf);
46693299c2f1SGregory Neil Shapiro 		return;
46703299c2f1SGregory Neil Shapiro 	}
46713299c2f1SGregory Neil Shapiro 
46723299c2f1SGregory Neil Shapiro 	/* scan the list of IP address */
46733299c2f1SGregory Neil Shapiro 	if (tTd(0, 40))
467412ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, lifc_len=%ld\n",
467512ed1c7cSGregory Neil Shapiro 			   (long) len);
46763299c2f1SGregory Neil Shapiro 
467712ed1c7cSGregory Neil Shapiro 	for (i = 0; i < len && i >= 0; )
46783299c2f1SGregory Neil Shapiro 	{
467912ed1c7cSGregory Neil Shapiro 		int flags;
468012ed1c7cSGregory Neil Shapiro 		struct lifreq *ifr = (struct lifreq *)&buf[i];
46813299c2f1SGregory Neil Shapiro 		SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr;
468212ed1c7cSGregory Neil Shapiro 		int af = ifr->lifr_addr.ss_family;
46833299c2f1SGregory Neil Shapiro 		char *addr;
468412ed1c7cSGregory Neil Shapiro 		char *name;
46853299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
46863299c2f1SGregory Neil Shapiro 		struct in_addr ia;
46873299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
46883299c2f1SGregory Neil Shapiro 		struct lifreq ifrf;
46893299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
46903299c2f1SGregory Neil Shapiro 		char ip_addr[256];
46913299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
46923299c2f1SGregory Neil Shapiro 
46933299c2f1SGregory Neil Shapiro 		/*
46943299c2f1SGregory Neil Shapiro 		**  We must close and recreate the socket each time
46953299c2f1SGregory Neil Shapiro 		**  since we don't know what type of socket it is now
46963299c2f1SGregory Neil Shapiro 		**  (each status function may change it).
46973299c2f1SGregory Neil Shapiro 		*/
46983299c2f1SGregory Neil Shapiro 
46993299c2f1SGregory Neil Shapiro 		(void) close(s);
47003299c2f1SGregory Neil Shapiro 
47013299c2f1SGregory Neil Shapiro 		s = socket(af, SOCK_DGRAM, 0);
47023299c2f1SGregory Neil Shapiro 		if (s == -1)
4703c46d91b7SGregory Neil Shapiro 		{
470412ed1c7cSGregory Neil Shapiro 			sm_free(buf); /* XXX */
47053299c2f1SGregory Neil Shapiro 			return;
4706c46d91b7SGregory Neil Shapiro 		}
47073299c2f1SGregory Neil Shapiro 
47083299c2f1SGregory Neil Shapiro 		/*
47093299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
47103299c2f1SGregory Neil Shapiro 		**  don't try to use it.
47113299c2f1SGregory Neil Shapiro 		*/
47123299c2f1SGregory Neil Shapiro 
471312ed1c7cSGregory Neil Shapiro 		if ((len - i) < sizeof *ifr)
47143299c2f1SGregory Neil Shapiro 			break;
47153299c2f1SGregory Neil Shapiro 
47163299c2f1SGregory Neil Shapiro #  ifdef BSD4_4_SOCKADDR
47173299c2f1SGregory Neil Shapiro 		if (sa->sa.sa_len > sizeof ifr->lifr_addr)
47183299c2f1SGregory Neil Shapiro 			i += sizeof ifr->lifr_name + sa->sa.sa_len;
47193299c2f1SGregory Neil Shapiro 		else
47203299c2f1SGregory Neil Shapiro #  endif /* BSD4_4_SOCKADDR */
47213299c2f1SGregory Neil Shapiro 			i += sizeof *ifr;
47223299c2f1SGregory Neil Shapiro 
47233299c2f1SGregory Neil Shapiro 		if (tTd(0, 20))
472412ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
47253299c2f1SGregory Neil Shapiro 
47263299c2f1SGregory Neil Shapiro 		if (af != AF_INET && af != AF_INET6)
47273299c2f1SGregory Neil Shapiro 			continue;
47283299c2f1SGregory Neil Shapiro 
47293299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
47303299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct lifreq));
473112ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name,
47323299c2f1SGregory Neil Shapiro 				  sizeof(ifrf.lifr_name));
47333299c2f1SGregory Neil Shapiro 		if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0)
47343299c2f1SGregory Neil Shapiro 		{
47353299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
473612ed1c7cSGregory Neil Shapiro 				sm_dprintf("SIOCGLIFFLAGS failed: %s\n",
473712ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
47383299c2f1SGregory Neil Shapiro 			continue;
47393299c2f1SGregory Neil Shapiro 		}
47403299c2f1SGregory Neil Shapiro 
474112ed1c7cSGregory Neil Shapiro 		name = ifr->lifr_name;
474212ed1c7cSGregory Neil Shapiro 		flags = ifrf.lifr_flags;
474312ed1c7cSGregory Neil Shapiro 
474412ed1c7cSGregory Neil Shapiro 		if (tTd(0, 41))
474512ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n", (unsigned long) flags);
474612ed1c7cSGregory Neil Shapiro 
474712ed1c7cSGregory Neil Shapiro 		if (!bitset(IFF_UP, flags))
47483299c2f1SGregory Neil Shapiro 			continue;
47493299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
47503299c2f1SGregory Neil Shapiro 
47513299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
47523299c2f1SGregory Neil Shapiro 
47533299c2f1SGregory Neil Shapiro 		/* extract IP address from the list*/
47543299c2f1SGregory Neil Shapiro 		switch (af)
47553299c2f1SGregory Neil Shapiro 		{
47563299c2f1SGregory Neil Shapiro 		  case AF_INET6:
4757c46d91b7SGregory Neil Shapiro #  ifdef __KAME__
4758b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
4759b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
4760b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
4761c46d91b7SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
4762c46d91b7SGregory Neil Shapiro 			{
4763b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
4764b4662009SGregory Neil Shapiro 
4765b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
4766b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
4767b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
4768b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
4769c46d91b7SGregory Neil Shapiro 			}
4770c46d91b7SGregory Neil Shapiro #  endif /* __KAME__ */
4771b4662009SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
4772c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
47733299c2f1SGregory Neil Shapiro 			{
47743299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
47753299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
477612ed1c7cSGregory Neil Shapiro 					name, addr == NULL ? "(NULL)" : addr);
47773299c2f1SGregory Neil Shapiro 				continue;
47783299c2f1SGregory Neil Shapiro 			}
47793299c2f1SGregory Neil Shapiro 
47803299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
47813299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
47823299c2f1SGregory Neil Shapiro 			if (addr != NULL)
478312ed1c7cSGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
47843299c2f1SGregory Neil Shapiro 						   "[%.*s]",
478512ed1c7cSGregory Neil Shapiro 						   (int) sizeof ip_addr - 3,
478612ed1c7cSGregory Neil Shapiro 						   addr);
47873299c2f1SGregory Neil Shapiro 			break;
47883299c2f1SGregory Neil Shapiro 
47893299c2f1SGregory Neil Shapiro 		  case AF_INET:
47903299c2f1SGregory Neil Shapiro 			ia = sa->sin.sin_addr;
47913299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
47923299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
47933299c2f1SGregory Neil Shapiro 			{
47943299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
479512ed1c7cSGregory Neil Shapiro 					name, inet_ntoa(ia));
47963299c2f1SGregory Neil Shapiro 				continue;
47973299c2f1SGregory Neil Shapiro 			}
47983299c2f1SGregory Neil Shapiro 
47993299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
480012ed1c7cSGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
4801d995d2baSGregory Neil Shapiro 					(int) sizeof ip_addr - 3, inet_ntoa(ia));
48023299c2f1SGregory Neil Shapiro 			break;
48033299c2f1SGregory Neil Shapiro 		}
48043299c2f1SGregory Neil Shapiro 
48053299c2f1SGregory Neil Shapiro 		if (*ip_addr == '\0')
48063299c2f1SGregory Neil Shapiro 			continue;
48073299c2f1SGregory Neil Shapiro 
48083299c2f1SGregory Neil Shapiro 		if (!wordinclass(ip_addr, 'w'))
48093299c2f1SGregory Neil Shapiro 		{
48103299c2f1SGregory Neil Shapiro 			setclass('w', ip_addr);
48113299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
481212ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
48133299c2f1SGregory Neil Shapiro 		}
48143299c2f1SGregory Neil Shapiro 
48153299c2f1SGregory Neil Shapiro #  ifdef SIOCGLIFFLAGS
48163299c2f1SGregory Neil Shapiro 		/* skip "loopback" interface "lo" */
481712ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
481812ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, flags))
48193299c2f1SGregory Neil Shapiro 			continue;
48203299c2f1SGregory Neil Shapiro #  endif /* SIOCGLIFFLAGS */
48213299c2f1SGregory Neil Shapiro 		(void) add_hostnames(sa);
48223299c2f1SGregory Neil Shapiro 	}
482312ed1c7cSGregory Neil Shapiro 	sm_free(buf); /* XXX */
4824c46d91b7SGregory Neil Shapiro 	(void) close(s);
48253299c2f1SGregory Neil Shapiro # else /* NETINET6 && defined(SIOCGLIFCONF) */
4826c2aa98e2SPeter Wemm #  if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4827c2aa98e2SPeter Wemm 	int s;
4828c2aa98e2SPeter Wemm 	int i;
4829c2aa98e2SPeter Wemm 	struct ifconf ifc;
4830c2aa98e2SPeter Wemm 	int numifs;
4831c2aa98e2SPeter Wemm 
4832c2aa98e2SPeter Wemm 	s = socket(AF_INET, SOCK_DGRAM, 0);
4833c2aa98e2SPeter Wemm 	if (s == -1)
4834c2aa98e2SPeter Wemm 		return;
4835c2aa98e2SPeter Wemm 
4836c2aa98e2SPeter Wemm 	/* get the list of known IP address from the kernel */
4837c2aa98e2SPeter Wemm #   if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN
4838c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
4839c2aa98e2SPeter Wemm 	{
4840c2aa98e2SPeter Wemm 		/* can't get number of interfaces -- fall back */
4841c2aa98e2SPeter Wemm 		if (tTd(0, 4))
484212ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFNUM failed: %s\n",
484312ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
4844c2aa98e2SPeter Wemm 		numifs = -1;
4845c2aa98e2SPeter Wemm 	}
4846c2aa98e2SPeter Wemm 	else if (tTd(0, 42))
484712ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
4848c2aa98e2SPeter Wemm 	if (numifs < 0)
48493299c2f1SGregory Neil Shapiro #   endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */
48503299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
4851c2aa98e2SPeter Wemm 
4852c2aa98e2SPeter Wemm 	if (numifs <= 0)
4853c2aa98e2SPeter Wemm 	{
48543299c2f1SGregory Neil Shapiro 		(void) close(s);
4855c2aa98e2SPeter Wemm 		return;
4856c2aa98e2SPeter Wemm 	}
4857c2aa98e2SPeter Wemm 	ifc.ifc_len = numifs * sizeof (struct ifreq);
4858c2aa98e2SPeter Wemm 	ifc.ifc_buf = xalloc(ifc.ifc_len);
4859c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
4860c2aa98e2SPeter Wemm 	{
4861c2aa98e2SPeter Wemm 		if (tTd(0, 4))
486212ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFCONF failed: %s\n",
486312ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
48643299c2f1SGregory Neil Shapiro 		(void) close(s);
4865c2aa98e2SPeter Wemm 		return;
4866c2aa98e2SPeter Wemm 	}
4867c2aa98e2SPeter Wemm 
4868c2aa98e2SPeter Wemm 	/* scan the list of IP address */
4869c2aa98e2SPeter Wemm 	if (tTd(0, 40))
487012ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, ifc_len=%d\n",
4871c2aa98e2SPeter Wemm 			ifc.ifc_len);
4872c2aa98e2SPeter Wemm 
487312ed1c7cSGregory Neil Shapiro 	for (i = 0; i < ifc.ifc_len && i >= 0; )
4874c2aa98e2SPeter Wemm 	{
48753299c2f1SGregory Neil Shapiro 		int af;
4876c2aa98e2SPeter Wemm 		struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
487776b7bf71SPeter Wemm 		SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr;
48783299c2f1SGregory Neil Shapiro #   if NETINET6
48793299c2f1SGregory Neil Shapiro 		char *addr;
48803299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
48813299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
4882c2aa98e2SPeter Wemm 		struct in_addr ia;
4883c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
4884c2aa98e2SPeter Wemm 		struct ifreq ifrf;
48853299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
4886c2aa98e2SPeter Wemm 		char ip_addr[256];
48873299c2f1SGregory Neil Shapiro #   if NETINET6
48883299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
48893299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
48903299c2f1SGregory Neil Shapiro 
48913299c2f1SGregory Neil Shapiro 		/*
48923299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
48933299c2f1SGregory Neil Shapiro 		**  don't try to use it.
48943299c2f1SGregory Neil Shapiro 		*/
48953299c2f1SGregory Neil Shapiro 
48963299c2f1SGregory Neil Shapiro 		if ((ifc.ifc_len - i) < sizeof *ifr)
48973299c2f1SGregory Neil Shapiro 			break;
4898c2aa98e2SPeter Wemm 
4899c2aa98e2SPeter Wemm #   ifdef BSD4_4_SOCKADDR
490076b7bf71SPeter Wemm 		if (sa->sa.sa_len > sizeof ifr->ifr_addr)
490176b7bf71SPeter Wemm 			i += sizeof ifr->ifr_name + sa->sa.sa_len;
4902c2aa98e2SPeter Wemm 		else
49033299c2f1SGregory Neil Shapiro #   endif /* BSD4_4_SOCKADDR */
4904c2aa98e2SPeter Wemm 			i += sizeof *ifr;
4905c2aa98e2SPeter Wemm 
4906c2aa98e2SPeter Wemm 		if (tTd(0, 20))
490712ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
4908c2aa98e2SPeter Wemm 
49093299c2f1SGregory Neil Shapiro 		af = ifr->ifr_addr.sa_family;
49103299c2f1SGregory Neil Shapiro 		if (af != AF_INET
49113299c2f1SGregory Neil Shapiro #   if NETINET6
49123299c2f1SGregory Neil Shapiro 		    && af != AF_INET6
49133299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
49143299c2f1SGregory Neil Shapiro 		    )
4915c2aa98e2SPeter Wemm 			continue;
4916c2aa98e2SPeter Wemm 
4917c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
49183299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct ifreq));
491912ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name,
49203299c2f1SGregory Neil Shapiro 			       sizeof(ifrf.ifr_name));
49213299c2f1SGregory Neil Shapiro 		(void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
4922c2aa98e2SPeter Wemm 		if (tTd(0, 41))
492312ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n",
49243299c2f1SGregory Neil Shapiro 				(unsigned long) ifrf.ifr_flags);
4925c2aa98e2SPeter Wemm #    define IFRFREF ifrf
49263299c2f1SGregory Neil Shapiro #   else /* SIOCGIFFLAGS */
4927c2aa98e2SPeter Wemm #    define IFRFREF (*ifr)
49283299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
49293299c2f1SGregory Neil Shapiro 
4930c2aa98e2SPeter Wemm 		if (!bitset(IFF_UP, IFRFREF.ifr_flags))
4931c2aa98e2SPeter Wemm 			continue;
4932c2aa98e2SPeter Wemm 
49333299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
49343299c2f1SGregory Neil Shapiro 
4935c2aa98e2SPeter Wemm 		/* extract IP address from the list*/
49363299c2f1SGregory Neil Shapiro 		switch (af)
49373299c2f1SGregory Neil Shapiro 		{
49383299c2f1SGregory Neil Shapiro 		  case AF_INET:
493976b7bf71SPeter Wemm 			ia = sa->sin.sin_addr;
49403299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
49413299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
4942c2aa98e2SPeter Wemm 			{
4943c2aa98e2SPeter Wemm 				message("WARNING: interface %s is UP with %s address",
4944c2aa98e2SPeter Wemm 					ifr->ifr_name, inet_ntoa(ia));
4945c2aa98e2SPeter Wemm 				continue;
4946c2aa98e2SPeter Wemm 			}
4947c2aa98e2SPeter Wemm 
4948c2aa98e2SPeter Wemm 			/* save IP address in text from */
494912ed1c7cSGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
49501ec86adfSBruce Evans 					(int) sizeof ip_addr - 3,
4951c2aa98e2SPeter Wemm 					inet_ntoa(ia));
49523299c2f1SGregory Neil Shapiro 			break;
49533299c2f1SGregory Neil Shapiro 
49543299c2f1SGregory Neil Shapiro #   if NETINET6
49553299c2f1SGregory Neil Shapiro 		  case AF_INET6:
4956b4662009SGregory Neil Shapiro #    ifdef __KAME__
4957b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
4958b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
4959b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
4960b4662009SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
4961b4662009SGregory Neil Shapiro 			{
4962b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
4963b4662009SGregory Neil Shapiro 
4964b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
4965b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
4966b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
4967b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
4968b4662009SGregory Neil Shapiro 			}
4969b4662009SGregory Neil Shapiro #    endif /* __KAME__ */
49703299c2f1SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
4971c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
49723299c2f1SGregory Neil Shapiro 			{
49733299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
49743299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
49753299c2f1SGregory Neil Shapiro 					ifr->ifr_name,
49763299c2f1SGregory Neil Shapiro 					addr == NULL ? "(NULL)" : addr);
49773299c2f1SGregory Neil Shapiro 				continue;
49783299c2f1SGregory Neil Shapiro 			}
49793299c2f1SGregory Neil Shapiro 
49803299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
49813299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
49823299c2f1SGregory Neil Shapiro 			if (addr != NULL)
498312ed1c7cSGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
49843299c2f1SGregory Neil Shapiro 						   "[%.*s]",
498512ed1c7cSGregory Neil Shapiro 						   (int) sizeof ip_addr - 3,
498612ed1c7cSGregory Neil Shapiro 						   addr);
49873299c2f1SGregory Neil Shapiro 			break;
49883299c2f1SGregory Neil Shapiro 
49893299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
49903299c2f1SGregory Neil Shapiro 		}
49913299c2f1SGregory Neil Shapiro 
49923299c2f1SGregory Neil Shapiro 		if (ip_addr[0] == '\0')
49933299c2f1SGregory Neil Shapiro 			continue;
49943299c2f1SGregory Neil Shapiro 
4995c2aa98e2SPeter Wemm 		if (!wordinclass(ip_addr, 'w'))
4996c2aa98e2SPeter Wemm 		{
4997c2aa98e2SPeter Wemm 			setclass('w', ip_addr);
4998c2aa98e2SPeter Wemm 			if (tTd(0, 4))
499912ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
5000c2aa98e2SPeter Wemm 		}
5001c2aa98e2SPeter Wemm 
5002c2aa98e2SPeter Wemm 		/* skip "loopback" interface "lo" */
500312ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
500412ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
5005c2aa98e2SPeter Wemm 			continue;
5006c2aa98e2SPeter Wemm 
500776b7bf71SPeter Wemm 		(void) add_hostnames(sa);
5008c2aa98e2SPeter Wemm 	}
500912ed1c7cSGregory Neil Shapiro 	sm_free(ifc.ifc_buf); /* XXX */
50103299c2f1SGregory Neil Shapiro 	(void) close(s);
5011c2aa98e2SPeter Wemm #   undef IFRFREF
50123299c2f1SGregory Neil Shapiro #  endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
50133299c2f1SGregory Neil Shapiro # endif /* NETINET6 && defined(SIOCGLIFCONF) */
50143299c2f1SGregory Neil Shapiro }
501512ed1c7cSGregory Neil Shapiro /*
50163299c2f1SGregory Neil Shapiro **  ISLOOPBACK -- is socket address in the loopback net?
50173299c2f1SGregory Neil Shapiro **
50183299c2f1SGregory Neil Shapiro **	Parameters:
50193299c2f1SGregory Neil Shapiro **		sa -- socket address.
50203299c2f1SGregory Neil Shapiro **
50213299c2f1SGregory Neil Shapiro **	Returns:
502212ed1c7cSGregory Neil Shapiro **		true -- is socket address in the loopback net?
502312ed1c7cSGregory Neil Shapiro **		false -- otherwise
50243299c2f1SGregory Neil Shapiro **
50253299c2f1SGregory Neil Shapiro */
50263299c2f1SGregory Neil Shapiro 
50273299c2f1SGregory Neil Shapiro bool
50283299c2f1SGregory Neil Shapiro isloopback(sa)
50293299c2f1SGregory Neil Shapiro 	SOCKADDR sa;
50303299c2f1SGregory Neil Shapiro {
50313299c2f1SGregory Neil Shapiro #if NETINET6
50323299c2f1SGregory Neil Shapiro 	if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
503312ed1c7cSGregory Neil Shapiro 		return true;
50343299c2f1SGregory Neil Shapiro #else /* NETINET6 */
50353299c2f1SGregory Neil Shapiro 	/* XXX how to correctly extract IN_LOOPBACKNET part? */
50363299c2f1SGregory Neil Shapiro 	if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET)
50373299c2f1SGregory Neil Shapiro 	     >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
503812ed1c7cSGregory Neil Shapiro 		return true;
50393299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
504012ed1c7cSGregory Neil Shapiro 	return false;
5041c2aa98e2SPeter Wemm }
504212ed1c7cSGregory Neil Shapiro /*
5043c2aa98e2SPeter Wemm **  GET_NUM_PROCS_ONLINE -- return the number of processors currently online
5044c2aa98e2SPeter Wemm **
5045c2aa98e2SPeter Wemm **	Parameters:
5046c2aa98e2SPeter Wemm **		none.
5047c2aa98e2SPeter Wemm **
5048c2aa98e2SPeter Wemm **	Returns:
5049c2aa98e2SPeter Wemm **		The number of processors online.
5050c2aa98e2SPeter Wemm */
5051c2aa98e2SPeter Wemm 
50523299c2f1SGregory Neil Shapiro static int
5053c2aa98e2SPeter Wemm get_num_procs_online()
5054c2aa98e2SPeter Wemm {
5055c2aa98e2SPeter Wemm 	int nproc = 0;
5056c2aa98e2SPeter Wemm 
50573299c2f1SGregory Neil Shapiro #ifdef USESYSCTL
50583299c2f1SGregory Neil Shapiro # if defined(CTL_HW) && defined(HW_NCPU)
50593299c2f1SGregory Neil Shapiro 	size_t sz;
50603299c2f1SGregory Neil Shapiro 	int mib[2];
50613299c2f1SGregory Neil Shapiro 
50623299c2f1SGregory Neil Shapiro 	mib[0] = CTL_HW;
50633299c2f1SGregory Neil Shapiro 	mib[1] = HW_NCPU;
50643299c2f1SGregory Neil Shapiro 	sz = (size_t) sizeof nproc;
50653299c2f1SGregory Neil Shapiro 	(void) sysctl(mib, 2, &nproc, &sz, NULL, 0);
506612ed1c7cSGregory Neil Shapiro # endif /* defined(CTL_HW) && defined(HW_NCPU) */
50673299c2f1SGregory Neil Shapiro #else /* USESYSCTL */
5068c2aa98e2SPeter Wemm # ifdef _SC_NPROCESSORS_ONLN
5069c2aa98e2SPeter Wemm 	nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
50703299c2f1SGregory Neil Shapiro # else /* _SC_NPROCESSORS_ONLN */
50713299c2f1SGregory Neil Shapiro #  ifdef __hpux
50723299c2f1SGregory Neil Shapiro #   include <sys/pstat.h>
50733299c2f1SGregory Neil Shapiro 	struct pst_dynamic psd;
50743299c2f1SGregory Neil Shapiro 
50753299c2f1SGregory Neil Shapiro 	if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1)
50763299c2f1SGregory Neil Shapiro 		nproc = psd.psd_proc_cnt;
50773299c2f1SGregory Neil Shapiro #  endif /* __hpux */
50783299c2f1SGregory Neil Shapiro # endif /* _SC_NPROCESSORS_ONLN */
50793299c2f1SGregory Neil Shapiro #endif /* USESYSCTL */
50803299c2f1SGregory Neil Shapiro 
5081c2aa98e2SPeter Wemm 	if (nproc <= 0)
5082c2aa98e2SPeter Wemm 		nproc = 1;
5083c2aa98e2SPeter Wemm 	return nproc;
5084c2aa98e2SPeter Wemm }
508512ed1c7cSGregory Neil Shapiro /*
50863299c2f1SGregory Neil Shapiro **  SEED_RANDOM -- seed the random number generator
50873299c2f1SGregory Neil Shapiro **
50883299c2f1SGregory Neil Shapiro **	Parameters:
50893299c2f1SGregory Neil Shapiro **		none
50903299c2f1SGregory Neil Shapiro **
50913299c2f1SGregory Neil Shapiro **	Returns:
50923299c2f1SGregory Neil Shapiro **		none
50933299c2f1SGregory Neil Shapiro */
50943299c2f1SGregory Neil Shapiro 
50953299c2f1SGregory Neil Shapiro void
50963299c2f1SGregory Neil Shapiro seed_random()
50973299c2f1SGregory Neil Shapiro {
50983299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
50993299c2f1SGregory Neil Shapiro 	srandomdev();
51003299c2f1SGregory Neil Shapiro #else /* HASSRANDOMDEV */
51013299c2f1SGregory Neil Shapiro 	long seed;
51023299c2f1SGregory Neil Shapiro 	struct timeval t;
51033299c2f1SGregory Neil Shapiro 
510412ed1c7cSGregory Neil Shapiro 	seed = (long) CurrentPid;
51053299c2f1SGregory Neil Shapiro 	if (gettimeofday(&t, NULL) >= 0)
51063299c2f1SGregory Neil Shapiro 		seed += t.tv_sec + t.tv_usec;
51073299c2f1SGregory Neil Shapiro 
51083299c2f1SGregory Neil Shapiro # if HASRANDOM
51093299c2f1SGregory Neil Shapiro 	(void) srandom(seed);
51103299c2f1SGregory Neil Shapiro # else /* HASRANDOM */
51113299c2f1SGregory Neil Shapiro 	(void) srand((unsigned int) seed);
51123299c2f1SGregory Neil Shapiro # endif /* HASRANDOM */
51133299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
51143299c2f1SGregory Neil Shapiro }
511512ed1c7cSGregory Neil Shapiro /*
5116c2aa98e2SPeter Wemm **  SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
5117c2aa98e2SPeter Wemm **
5118c2aa98e2SPeter Wemm **	Parameters:
5119c2aa98e2SPeter Wemm **		level -- syslog level
5120c2aa98e2SPeter Wemm **		id -- envelope ID or NULL (NOQUEUE)
5121c2aa98e2SPeter Wemm **		fmt -- format string
5122c2aa98e2SPeter Wemm **		arg... -- arguments as implied by fmt.
5123c2aa98e2SPeter Wemm **
5124c2aa98e2SPeter Wemm **	Returns:
5125c2aa98e2SPeter Wemm **		none
5126c2aa98e2SPeter Wemm */
5127c2aa98e2SPeter Wemm 
5128c2aa98e2SPeter Wemm /* VARARGS3 */
5129c2aa98e2SPeter Wemm void
5130c2aa98e2SPeter Wemm #ifdef __STDC__
5131c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...)
51323299c2f1SGregory Neil Shapiro #else /* __STDC__ */
5133c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist)
5134c2aa98e2SPeter Wemm 	int level;
5135c2aa98e2SPeter Wemm 	const char *id;
5136c2aa98e2SPeter Wemm 	const char *fmt;
5137c2aa98e2SPeter Wemm 	va_dcl
51383299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
5139c2aa98e2SPeter Wemm {
5140c2aa98e2SPeter Wemm 	static char *buf = NULL;
51413299c2f1SGregory Neil Shapiro 	static size_t bufsize;
5142c2aa98e2SPeter Wemm 	char *begin, *end;
51433299c2f1SGregory Neil Shapiro 	int save_errno;
5144c2aa98e2SPeter Wemm 	int seq = 1;
5145c2aa98e2SPeter Wemm 	int idlen;
51463299c2f1SGregory Neil Shapiro 	char buf0[MAXLINE];
514712ed1c7cSGregory Neil Shapiro 	char *newstring;
514812ed1c7cSGregory Neil Shapiro 	extern int SyslogPrefixLen;
514912ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5150c2aa98e2SPeter Wemm 
515112ed1c7cSGregory Neil Shapiro 	save_errno = errno;
5152c2aa98e2SPeter Wemm 	if (id == NULL)
515312ed1c7cSGregory Neil Shapiro 	{
5154c2aa98e2SPeter Wemm 		id = "NOQUEUE";
515512ed1c7cSGregory Neil Shapiro 		idlen = strlen(id) + SyslogPrefixLen;
515612ed1c7cSGregory Neil Shapiro 	}
5157c2aa98e2SPeter Wemm 	else if (strcmp(id, NOQID) == 0)
515812ed1c7cSGregory Neil Shapiro 	{
5159c2aa98e2SPeter Wemm 		id = "";
516012ed1c7cSGregory Neil Shapiro 		idlen = SyslogPrefixLen;
516112ed1c7cSGregory Neil Shapiro 	}
516212ed1c7cSGregory Neil Shapiro 	else
516312ed1c7cSGregory Neil Shapiro 		idlen = strlen(id) + SyslogPrefixLen;
5164c2aa98e2SPeter Wemm 
51653299c2f1SGregory Neil Shapiro 	if (buf == NULL)
51663299c2f1SGregory Neil Shapiro 	{
51673299c2f1SGregory Neil Shapiro 		buf = buf0;
51683299c2f1SGregory Neil Shapiro 		bufsize = sizeof buf0;
51693299c2f1SGregory Neil Shapiro 	}
51703299c2f1SGregory Neil Shapiro 
51713299c2f1SGregory Neil Shapiro 	for (;;)
51723299c2f1SGregory Neil Shapiro 	{
517312ed1c7cSGregory Neil Shapiro 		int n;
5174c2aa98e2SPeter Wemm 
517512ed1c7cSGregory Neil Shapiro 		/* print log message into buf */
517612ed1c7cSGregory Neil Shapiro 		SM_VA_START(ap, fmt);
517712ed1c7cSGregory Neil Shapiro 		n = sm_vsnprintf(buf, bufsize, fmt, ap);
517812ed1c7cSGregory Neil Shapiro 		SM_VA_END(ap);
517912ed1c7cSGregory Neil Shapiro 		SM_ASSERT(n > 0);
518012ed1c7cSGregory Neil Shapiro 		if (n < bufsize)
51813299c2f1SGregory Neil Shapiro 			break;
51823299c2f1SGregory Neil Shapiro 
5183c2aa98e2SPeter Wemm 		/* String too small, redo with correct size */
518412ed1c7cSGregory Neil Shapiro 		bufsize = n + 1;
51853299c2f1SGregory Neil Shapiro 		if (buf != buf0)
518612ed1c7cSGregory Neil Shapiro 		{
5187c0c4794dSGregory Neil Shapiro 			sm_free(buf);
518812ed1c7cSGregory Neil Shapiro 			buf = NULL;
5189c2aa98e2SPeter Wemm 		}
519012ed1c7cSGregory Neil Shapiro 		buf = sm_malloc_x(bufsize);
519112ed1c7cSGregory Neil Shapiro 	}
519212ed1c7cSGregory Neil Shapiro 
519312ed1c7cSGregory Neil Shapiro 	/* clean up buf after it has been expanded with args */
519412ed1c7cSGregory Neil Shapiro 	newstring = str2prt(buf);
519512ed1c7cSGregory Neil Shapiro 	if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE)
5196c2aa98e2SPeter Wemm 	{
5197c2aa98e2SPeter Wemm #if LOG
5198c2aa98e2SPeter Wemm 		if (*id == '\0')
519912ed1c7cSGregory Neil Shapiro 			syslog(level, "%s", newstring);
5200c2aa98e2SPeter Wemm 		else
520112ed1c7cSGregory Neil Shapiro 			syslog(level, "%s: %s", id, newstring);
52023299c2f1SGregory Neil Shapiro #else /* LOG */
5203c2aa98e2SPeter Wemm 		/*XXX should do something more sensible */
5204c2aa98e2SPeter Wemm 		if (*id == '\0')
520512ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n",
520612ed1c7cSGregory Neil Shapiro 					     newstring);
5207c2aa98e2SPeter Wemm 		else
520812ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
520912ed1c7cSGregory Neil Shapiro 					     "%s: %s\n", id, newstring);
52103299c2f1SGregory Neil Shapiro #endif /* LOG */
52113299c2f1SGregory Neil Shapiro 		if (buf == buf0)
52123299c2f1SGregory Neil Shapiro 			buf = NULL;
52133299c2f1SGregory Neil Shapiro 		errno = save_errno;
5214c2aa98e2SPeter Wemm 		return;
5215c2aa98e2SPeter Wemm 	}
5216c2aa98e2SPeter Wemm 
521712ed1c7cSGregory Neil Shapiro /*
521812ed1c7cSGregory Neil Shapiro **  additional length for splitting: " ..." + 3, where 3 is magic to
521912ed1c7cSGregory Neil Shapiro **  have some data for the next entry.
522012ed1c7cSGregory Neil Shapiro */
522112ed1c7cSGregory Neil Shapiro 
522212ed1c7cSGregory Neil Shapiro #define SL_SPLIT 7
522312ed1c7cSGregory Neil Shapiro 
522412ed1c7cSGregory Neil Shapiro 	begin = newstring;
522512ed1c7cSGregory Neil Shapiro 	idlen += 5;	/* strlen("[999]"), see below */
5226c2aa98e2SPeter Wemm 	while (*begin != '\0' &&
522712ed1c7cSGregory Neil Shapiro 	       (strlen(begin) + idlen) > SYSLOG_BUFSIZE)
5228c2aa98e2SPeter Wemm 	{
5229c2aa98e2SPeter Wemm 		char save;
5230c2aa98e2SPeter Wemm 
523112ed1c7cSGregory Neil Shapiro 		if (seq >= 999)
5232c2aa98e2SPeter Wemm 		{
5233c2aa98e2SPeter Wemm 			/* Too many messages */
5234c2aa98e2SPeter Wemm 			break;
5235c2aa98e2SPeter Wemm 		}
523612ed1c7cSGregory Neil Shapiro 		end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5237c2aa98e2SPeter Wemm 		while (end > begin)
5238c2aa98e2SPeter Wemm 		{
5239c2aa98e2SPeter Wemm 			/* Break on comma or space */
5240c2aa98e2SPeter Wemm 			if (*end == ',' || *end == ' ')
5241c2aa98e2SPeter Wemm 			{
5242c2aa98e2SPeter Wemm 				end++;	  /* Include separator */
5243c2aa98e2SPeter Wemm 				break;
5244c2aa98e2SPeter Wemm 			}
5245c2aa98e2SPeter Wemm 			end--;
5246c2aa98e2SPeter Wemm 		}
5247c2aa98e2SPeter Wemm 		/* No separator, break midstring... */
5248c2aa98e2SPeter Wemm 		if (end == begin)
524912ed1c7cSGregory Neil Shapiro 			end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5250c2aa98e2SPeter Wemm 		save = *end;
5251c2aa98e2SPeter Wemm 		*end = 0;
5252c2aa98e2SPeter Wemm #if LOG
5253c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s ...", id, seq++, begin);
52543299c2f1SGregory Neil Shapiro #else /* LOG */
525512ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
525612ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s ...\n", id, seq++, begin);
52573299c2f1SGregory Neil Shapiro #endif /* LOG */
5258c2aa98e2SPeter Wemm 		*end = save;
5259c2aa98e2SPeter Wemm 		begin = end;
5260c2aa98e2SPeter Wemm 	}
526112ed1c7cSGregory Neil Shapiro 	if (seq >= 999)
5262c2aa98e2SPeter Wemm #if LOG
52633299c2f1SGregory Neil Shapiro 		syslog(level, "%s[%d]: log terminated, too many parts",
52643299c2f1SGregory Neil Shapiro 			id, seq);
52653299c2f1SGregory Neil Shapiro #else /* LOG */
526612ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
526712ed1c7cSGregory Neil Shapiro 			      "%s[%d]: log terminated, too many parts\n", id, seq);
52683299c2f1SGregory Neil Shapiro #endif /* LOG */
5269c2aa98e2SPeter Wemm 	else if (*begin != '\0')
5270c2aa98e2SPeter Wemm #if LOG
5271c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s", id, seq, begin);
52723299c2f1SGregory Neil Shapiro #else /* LOG */
527312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
527412ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s\n", id, seq, begin);
52753299c2f1SGregory Neil Shapiro #endif /* LOG */
52763299c2f1SGregory Neil Shapiro 	if (buf == buf0)
52773299c2f1SGregory Neil Shapiro 		buf = NULL;
52783299c2f1SGregory Neil Shapiro 	errno = save_errno;
5279c2aa98e2SPeter Wemm }
528012ed1c7cSGregory Neil Shapiro /*
5281c2aa98e2SPeter Wemm **  HARD_SYSLOG -- call syslog repeatedly until it works
5282c2aa98e2SPeter Wemm **
5283c2aa98e2SPeter Wemm **	Needed on HP-UX, which apparently doesn't guarantee that
5284c2aa98e2SPeter Wemm **	syslog succeeds during interrupt handlers.
5285c2aa98e2SPeter Wemm */
5286c2aa98e2SPeter Wemm 
5287c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11)
5288c2aa98e2SPeter Wemm 
5289c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES	100
5290c2aa98e2SPeter Wemm # undef syslog
5291c2aa98e2SPeter Wemm # ifdef V4FS
5292c2aa98e2SPeter Wemm #  define XCNST	const
5293c2aa98e2SPeter Wemm #  define CAST	(const char *)
52943299c2f1SGregory Neil Shapiro # else /* V4FS */
5295c2aa98e2SPeter Wemm #  define XCNST
5296c2aa98e2SPeter Wemm #  define CAST
52973299c2f1SGregory Neil Shapiro # endif /* V4FS */
5298c2aa98e2SPeter Wemm 
5299c2aa98e2SPeter Wemm void
5300c2aa98e2SPeter Wemm # ifdef __STDC__
5301c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...)
53023299c2f1SGregory Neil Shapiro # else /* __STDC__ */
5303c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist)
5304c2aa98e2SPeter Wemm 	int pri;
5305c2aa98e2SPeter Wemm 	XCNST char *msg;
5306c2aa98e2SPeter Wemm 	va_dcl
53073299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
5308c2aa98e2SPeter Wemm {
5309c2aa98e2SPeter Wemm 	int i;
5310c2aa98e2SPeter Wemm 	char buf[SYSLOG_BUFSIZE];
531112ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5312c2aa98e2SPeter Wemm 
531312ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, msg);
531412ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof buf, msg, ap);
531512ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
5316c2aa98e2SPeter Wemm 
5317c2aa98e2SPeter Wemm 	for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; )
5318c2aa98e2SPeter Wemm 		continue;
5319c2aa98e2SPeter Wemm }
5320c2aa98e2SPeter Wemm 
5321c2aa98e2SPeter Wemm # undef CAST
53223299c2f1SGregory Neil Shapiro #endif /* defined(__hpux) && !defined(HPUX11) */
53233299c2f1SGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
532412ed1c7cSGregory Neil Shapiro /*
5325c2aa98e2SPeter Wemm **  LOCAL_HOSTNAME_LENGTH
5326c2aa98e2SPeter Wemm **
5327c2aa98e2SPeter Wemm **	This is required to get sendmail to compile against BIND 4.9.x
5328c2aa98e2SPeter Wemm **	on Ultrix.
53293299c2f1SGregory Neil Shapiro **
53303299c2f1SGregory Neil Shapiro **	Unfortunately, a Compaq Y2K patch kit provides it without
53313299c2f1SGregory Neil Shapiro **	bumping __RES in /usr/include/resolv.h so we can't automatically
53323299c2f1SGregory Neil Shapiro **	figure out whether it is needed.
5333c2aa98e2SPeter Wemm */
5334c2aa98e2SPeter Wemm 
5335c2aa98e2SPeter Wemm int
5336c2aa98e2SPeter Wemm local_hostname_length(hostname)
5337c2aa98e2SPeter Wemm 	char *hostname;
5338c2aa98e2SPeter Wemm {
533912ed1c7cSGregory Neil Shapiro 	size_t len_host, len_domain;
5340c2aa98e2SPeter Wemm 
5341c2aa98e2SPeter Wemm 	if (!*_res.defdname)
5342c2aa98e2SPeter Wemm 		res_init();
5343c2aa98e2SPeter Wemm 	len_host = strlen(hostname);
5344c2aa98e2SPeter Wemm 	len_domain = strlen(_res.defdname);
5345c2aa98e2SPeter Wemm 	if (len_host > len_domain &&
534612ed1c7cSGregory Neil Shapiro 	    (sm_strcasecmp(hostname + len_host - len_domain,
53473299c2f1SGregory Neil Shapiro 			_res.defdname) == 0) &&
5348c2aa98e2SPeter Wemm 	    hostname[len_host - len_domain - 1] == '.')
5349c2aa98e2SPeter Wemm 		return len_host - len_domain - 1;
5350c2aa98e2SPeter Wemm 	else
5351c2aa98e2SPeter Wemm 		return 0;
5352c2aa98e2SPeter Wemm }
53533299c2f1SGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
5354c2aa98e2SPeter Wemm 
535512ed1c7cSGregory Neil Shapiro #if NEEDLINK
535612ed1c7cSGregory Neil Shapiro /*
535712ed1c7cSGregory Neil Shapiro **  LINK -- clone a file
535812ed1c7cSGregory Neil Shapiro **
535912ed1c7cSGregory Neil Shapiro **	Some OS's lacks link() and hard links.  Since sendmail is using
536012ed1c7cSGregory Neil Shapiro **	link() as an efficient way to clone files, this implementation
536112ed1c7cSGregory Neil Shapiro **	will simply do a file copy.
536212ed1c7cSGregory Neil Shapiro **
536312ed1c7cSGregory Neil Shapiro **	NOTE: This link() replacement is not a generic replacement as it
536412ed1c7cSGregory Neil Shapiro **	does not handle all of the semantics of the real link(2).
536512ed1c7cSGregory Neil Shapiro **
536612ed1c7cSGregory Neil Shapiro **	Parameters:
536712ed1c7cSGregory Neil Shapiro **		source -- pathname of existing file.
536812ed1c7cSGregory Neil Shapiro **		target -- pathname of link (clone) to be created.
536912ed1c7cSGregory Neil Shapiro **
537012ed1c7cSGregory Neil Shapiro **	Returns:
537112ed1c7cSGregory Neil Shapiro **		0 -- success.
537212ed1c7cSGregory Neil Shapiro **		-1 -- failure, see errno for details.
537312ed1c7cSGregory Neil Shapiro */
537412ed1c7cSGregory Neil Shapiro 
537512ed1c7cSGregory Neil Shapiro int
537612ed1c7cSGregory Neil Shapiro link(source, target)
537712ed1c7cSGregory Neil Shapiro 	const char *source;
537812ed1c7cSGregory Neil Shapiro 	const char *target;
537912ed1c7cSGregory Neil Shapiro {
538012ed1c7cSGregory Neil Shapiro 	int save_errno;
538112ed1c7cSGregory Neil Shapiro 	int sff;
538212ed1c7cSGregory Neil Shapiro 	int src = -1, dst = -1;
538312ed1c7cSGregory Neil Shapiro 	ssize_t readlen;
538412ed1c7cSGregory Neil Shapiro 	ssize_t writelen;
538512ed1c7cSGregory Neil Shapiro 	char buf[BUFSIZ];
538612ed1c7cSGregory Neil Shapiro 	struct stat st;
538712ed1c7cSGregory Neil Shapiro 
538812ed1c7cSGregory Neil Shapiro 	sff = SFF_REGONLY|SFF_OPENASROOT;
538912ed1c7cSGregory Neil Shapiro 	if (DontLockReadFiles)
539012ed1c7cSGregory Neil Shapiro 		sff |= SFF_NOLOCK;
539112ed1c7cSGregory Neil Shapiro 
539212ed1c7cSGregory Neil Shapiro 	/* Open the original file */
539312ed1c7cSGregory Neil Shapiro 	src = safeopen((char *)source, O_RDONLY, 0, sff);
539412ed1c7cSGregory Neil Shapiro 	if (src < 0)
539512ed1c7cSGregory Neil Shapiro 		goto fail;
539612ed1c7cSGregory Neil Shapiro 
539712ed1c7cSGregory Neil Shapiro 	/* Obtain the size and the mode */
539812ed1c7cSGregory Neil Shapiro 	if (fstat(src, &st) < 0)
539912ed1c7cSGregory Neil Shapiro 		goto fail;
540012ed1c7cSGregory Neil Shapiro 
540112ed1c7cSGregory Neil Shapiro 	/* Create the duplicate copy */
540212ed1c7cSGregory Neil Shapiro 	sff &= ~SFF_NOLOCK;
540312ed1c7cSGregory Neil Shapiro 	sff |= SFF_CREAT;
540412ed1c7cSGregory Neil Shapiro 	dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY,
540512ed1c7cSGregory Neil Shapiro 		       st.st_mode, sff);
540612ed1c7cSGregory Neil Shapiro 	if (dst < 0)
540712ed1c7cSGregory Neil Shapiro 		goto fail;
540812ed1c7cSGregory Neil Shapiro 
540912ed1c7cSGregory Neil Shapiro 	/* Copy all of the bytes one buffer at a time */
541012ed1c7cSGregory Neil Shapiro 	while ((readlen = read(src, &buf, sizeof(buf))) > 0)
541112ed1c7cSGregory Neil Shapiro 	{
541212ed1c7cSGregory Neil Shapiro 		ssize_t left = readlen;
541312ed1c7cSGregory Neil Shapiro 		char *p = buf;
541412ed1c7cSGregory Neil Shapiro 
541512ed1c7cSGregory Neil Shapiro 		while (left > 0 &&
541612ed1c7cSGregory Neil Shapiro 		       (writelen = write(dst, p, (size_t) left)) >= 0)
541712ed1c7cSGregory Neil Shapiro 		{
541812ed1c7cSGregory Neil Shapiro 			left -= writelen;
541912ed1c7cSGregory Neil Shapiro 			p += writelen;
542012ed1c7cSGregory Neil Shapiro 		}
542112ed1c7cSGregory Neil Shapiro 		if (writeln < 0)
542212ed1c7cSGregory Neil Shapiro 			break;
542312ed1c7cSGregory Neil Shapiro 	}
542412ed1c7cSGregory Neil Shapiro 
542512ed1c7cSGregory Neil Shapiro 	/* Any trouble reading? */
542612ed1c7cSGregory Neil Shapiro 	if (readlen < 0 || writelen < 0)
542712ed1c7cSGregory Neil Shapiro 		goto fail;
542812ed1c7cSGregory Neil Shapiro 
542912ed1c7cSGregory Neil Shapiro 	/* Close the input file */
543012ed1c7cSGregory Neil Shapiro 	if (close(src) < 0)
543112ed1c7cSGregory Neil Shapiro 	{
543212ed1c7cSGregory Neil Shapiro 		src = -1;
543312ed1c7cSGregory Neil Shapiro 		goto fail;
543412ed1c7cSGregory Neil Shapiro 	}
543512ed1c7cSGregory Neil Shapiro 	src = -1;
543612ed1c7cSGregory Neil Shapiro 
543712ed1c7cSGregory Neil Shapiro 	/* Close the output file */
543812ed1c7cSGregory Neil Shapiro 	if (close(dst) < 0)
543912ed1c7cSGregory Neil Shapiro 	{
544012ed1c7cSGregory Neil Shapiro 		/* don't set dst = -1 here so we unlink the file */
544112ed1c7cSGregory Neil Shapiro 		goto fail;
544212ed1c7cSGregory Neil Shapiro 	}
544312ed1c7cSGregory Neil Shapiro 
544412ed1c7cSGregory Neil Shapiro 	/* Success */
544512ed1c7cSGregory Neil Shapiro 	return 0;
544612ed1c7cSGregory Neil Shapiro 
544712ed1c7cSGregory Neil Shapiro  fail:
544812ed1c7cSGregory Neil Shapiro 	save_errno = errno;
544912ed1c7cSGregory Neil Shapiro 	if (src >= 0)
545012ed1c7cSGregory Neil Shapiro 		(void) close(src);
545112ed1c7cSGregory Neil Shapiro 	if (dst >= 0)
545212ed1c7cSGregory Neil Shapiro 	{
545312ed1c7cSGregory Neil Shapiro 		(void) unlink(target);
545412ed1c7cSGregory Neil Shapiro 		(void) close(dst);
545512ed1c7cSGregory Neil Shapiro 	}
545612ed1c7cSGregory Neil Shapiro 	errno = save_errno;
545712ed1c7cSGregory Neil Shapiro 	return -1;
545812ed1c7cSGregory Neil Shapiro }
545912ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */
546012ed1c7cSGregory Neil Shapiro 
546112ed1c7cSGregory Neil Shapiro /*
5462c2aa98e2SPeter Wemm **  Compile-Time options
5463c2aa98e2SPeter Wemm */
5464c2aa98e2SPeter Wemm 
5465c2aa98e2SPeter Wemm char	*CompileOptions[] =
5466c2aa98e2SPeter Wemm {
546712ed1c7cSGregory Neil Shapiro #if NAMED_BIND
546812ed1c7cSGregory Neil Shapiro # if DNSMAP
546912ed1c7cSGregory Neil Shapiro 	"DNSMAP",
547012ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */
547112ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */
5472c0c4794dSGregory Neil Shapiro #if EGD
5473c0c4794dSGregory Neil Shapiro 	"EGD",
5474c0c4794dSGregory Neil Shapiro #endif /* EGD */
547512ed1c7cSGregory Neil Shapiro #if HESIOD
5476c2aa98e2SPeter Wemm 	"HESIOD",
54773299c2f1SGregory Neil Shapiro #endif /* HESIOD */
5478c2aa98e2SPeter Wemm #if HES_GETMAILHOST
5479c2aa98e2SPeter Wemm 	"HES_GETMAILHOST",
54803299c2f1SGregory Neil Shapiro #endif /* HES_GETMAILHOST */
548112ed1c7cSGregory Neil Shapiro #if LDAPMAP
5482c2aa98e2SPeter Wemm 	"LDAPMAP",
54833299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
5484c2aa98e2SPeter Wemm #if LOG
5485c2aa98e2SPeter Wemm 	"LOG",
54863299c2f1SGregory Neil Shapiro #endif /* LOG */
548712ed1c7cSGregory Neil Shapiro #if MAP_NSD
548812ed1c7cSGregory Neil Shapiro 	"MAP_NSD",
548912ed1c7cSGregory Neil Shapiro #endif /* MAP_NSD */
549012ed1c7cSGregory Neil Shapiro #if MAP_REGEX
549112ed1c7cSGregory Neil Shapiro 	"MAP_REGEX",
549212ed1c7cSGregory Neil Shapiro #endif /* MAP_REGEX */
5493c2aa98e2SPeter Wemm #if MATCHGECOS
5494c2aa98e2SPeter Wemm 	"MATCHGECOS",
54953299c2f1SGregory Neil Shapiro #endif /* MATCHGECOS */
549612ed1c7cSGregory Neil Shapiro #if MILTER
549712ed1c7cSGregory Neil Shapiro 	"MILTER",
549812ed1c7cSGregory Neil Shapiro #endif /* MILTER */
5499c2aa98e2SPeter Wemm #if MIME7TO8
5500c2aa98e2SPeter Wemm 	"MIME7TO8",
55013299c2f1SGregory Neil Shapiro #endif /* MIME7TO8 */
5502c2aa98e2SPeter Wemm #if MIME8TO7
5503c2aa98e2SPeter Wemm 	"MIME8TO7",
55043299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
5505c2aa98e2SPeter Wemm #if NAMED_BIND
5506c2aa98e2SPeter Wemm 	"NAMED_BIND",
55073299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
550812ed1c7cSGregory Neil Shapiro #if NDBM
5509c2aa98e2SPeter Wemm 	"NDBM",
55103299c2f1SGregory Neil Shapiro #endif /* NDBM */
5511c2aa98e2SPeter Wemm #if NETINET
5512c2aa98e2SPeter Wemm 	"NETINET",
55133299c2f1SGregory Neil Shapiro #endif /* NETINET */
55143299c2f1SGregory Neil Shapiro #if NETINET6
55153299c2f1SGregory Neil Shapiro 	"NETINET6",
55163299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
5517c2aa98e2SPeter Wemm #if NETINFO
5518c2aa98e2SPeter Wemm 	"NETINFO",
55193299c2f1SGregory Neil Shapiro #endif /* NETINFO */
5520c2aa98e2SPeter Wemm #if NETISO
5521c2aa98e2SPeter Wemm 	"NETISO",
55223299c2f1SGregory Neil Shapiro #endif /* NETISO */
5523c2aa98e2SPeter Wemm #if NETNS
5524c2aa98e2SPeter Wemm 	"NETNS",
55253299c2f1SGregory Neil Shapiro #endif /* NETNS */
5526c2aa98e2SPeter Wemm #if NETUNIX
5527c2aa98e2SPeter Wemm 	"NETUNIX",
55283299c2f1SGregory Neil Shapiro #endif /* NETUNIX */
5529c2aa98e2SPeter Wemm #if NETX25
5530c2aa98e2SPeter Wemm 	"NETX25",
55313299c2f1SGregory Neil Shapiro #endif /* NETX25 */
553212ed1c7cSGregory Neil Shapiro #if NEWDB
5533c2aa98e2SPeter Wemm 	"NEWDB",
55343299c2f1SGregory Neil Shapiro #endif /* NEWDB */
553512ed1c7cSGregory Neil Shapiro #if NIS
5536c2aa98e2SPeter Wemm 	"NIS",
55373299c2f1SGregory Neil Shapiro #endif /* NIS */
553812ed1c7cSGregory Neil Shapiro #if NISPLUS
5539c2aa98e2SPeter Wemm 	"NISPLUS",
55403299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
554112ed1c7cSGregory Neil Shapiro #if NO_DH
554212ed1c7cSGregory Neil Shapiro 	"NO_DH",
554312ed1c7cSGregory Neil Shapiro #endif /* NO_DH */
554412ed1c7cSGregory Neil Shapiro #if PH_MAP
55453299c2f1SGregory Neil Shapiro 	"PH_MAP",
55463299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
554712ed1c7cSGregory Neil Shapiro #ifdef PICKY_HELO_CHECK
554812ed1c7cSGregory Neil Shapiro 	"PICKY_HELO_CHECK",
554912ed1c7cSGregory Neil Shapiro #endif /* PICKY_HELO_CHECK */
555012ed1c7cSGregory Neil Shapiro #if PIPELINING
555112ed1c7cSGregory Neil Shapiro 	"PIPELINING",
555212ed1c7cSGregory Neil Shapiro #endif /* PIPELINING */
55533299c2f1SGregory Neil Shapiro #if SASL
55543299c2f1SGregory Neil Shapiro 	"SASL",
55553299c2f1SGregory Neil Shapiro #endif /* SASL */
5556c2aa98e2SPeter Wemm #if SCANF
5557c2aa98e2SPeter Wemm 	"SCANF",
55583299c2f1SGregory Neil Shapiro #endif /* SCANF */
5559c2aa98e2SPeter Wemm #if SMTPDEBUG
5560c2aa98e2SPeter Wemm 	"SMTPDEBUG",
55613299c2f1SGregory Neil Shapiro #endif /* SMTPDEBUG */
55623299c2f1SGregory Neil Shapiro #if STARTTLS
55633299c2f1SGregory Neil Shapiro 	"STARTTLS",
55643299c2f1SGregory Neil Shapiro #endif /* STARTTLS */
556512ed1c7cSGregory Neil Shapiro #if SUID_ROOT_FILES_OK
5566c2aa98e2SPeter Wemm 	"SUID_ROOT_FILES_OK",
55673299c2f1SGregory Neil Shapiro #endif /* SUID_ROOT_FILES_OK */
5568c2aa98e2SPeter Wemm #if TCPWRAPPERS
5569c2aa98e2SPeter Wemm 	"TCPWRAPPERS",
55703299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
557112ed1c7cSGregory Neil Shapiro #if TLS_NO_RSA
557212ed1c7cSGregory Neil Shapiro 	"TLS_NO_RSA",
557312ed1c7cSGregory Neil Shapiro #endif /* TLS_NO_RSA */
557412ed1c7cSGregory Neil Shapiro #if TLS_VRFY_PER_CTX
557512ed1c7cSGregory Neil Shapiro 	"TLS_VRFY_PER_CTX",
557612ed1c7cSGregory Neil Shapiro #endif /* TLS_VRFY_PER_CTX */
5577c2aa98e2SPeter Wemm #if USERDB
5578c2aa98e2SPeter Wemm 	"USERDB",
55793299c2f1SGregory Neil Shapiro #endif /* USERDB */
5580c2aa98e2SPeter Wemm #if XDEBUG
5581c2aa98e2SPeter Wemm 	"XDEBUG",
55823299c2f1SGregory Neil Shapiro #endif /* XDEBUG */
558312ed1c7cSGregory Neil Shapiro #if XLA
5584c2aa98e2SPeter Wemm 	"XLA",
55853299c2f1SGregory Neil Shapiro #endif /* XLA */
5586c2aa98e2SPeter Wemm 	NULL
5587c2aa98e2SPeter Wemm };
5588c2aa98e2SPeter Wemm 
5589c2aa98e2SPeter Wemm 
5590c2aa98e2SPeter Wemm /*
5591c2aa98e2SPeter Wemm **  OS compile options.
5592c2aa98e2SPeter Wemm */
5593c2aa98e2SPeter Wemm 
5594c2aa98e2SPeter Wemm char	*OsCompileOptions[] =
5595c2aa98e2SPeter Wemm {
559612ed1c7cSGregory Neil Shapiro #if ADDRCONFIG_IS_BROKEN
559712ed1c7cSGregory Neil Shapiro 	"ADDRCONFIG_IS_BROKEN",
559812ed1c7cSGregory Neil Shapiro #endif /* ADDRCONFIG_IS_BROKEN */
559912ed1c7cSGregory Neil Shapiro #ifdef AUTO_NETINFO_HOSTS
560012ed1c7cSGregory Neil Shapiro 	"AUTO_NETINFO_HOSTS",
560112ed1c7cSGregory Neil Shapiro #endif /* AUTO_NETINFO_HOSTS */
560212ed1c7cSGregory Neil Shapiro #ifdef AUTO_NIS_ALIASES
560312ed1c7cSGregory Neil Shapiro 	"AUTO_NIS_ALIASES",
560412ed1c7cSGregory Neil Shapiro #endif /* AUTO_NIS_ALIASES */
560512ed1c7cSGregory Neil Shapiro #if BROKEN_RES_SEARCH
560612ed1c7cSGregory Neil Shapiro 	"BROKEN_RES_SEARCH",
560712ed1c7cSGregory Neil Shapiro #endif /* BROKEN_RES_SEARCH */
560812ed1c7cSGregory Neil Shapiro #ifdef BSD4_4_SOCKADDR
560912ed1c7cSGregory Neil Shapiro 	"BSD4_4_SOCKADDR",
561012ed1c7cSGregory Neil Shapiro #endif /* BSD4_4_SOCKADDR */
5611c2aa98e2SPeter Wemm #if BOGUS_O_EXCL
5612c2aa98e2SPeter Wemm 	"BOGUS_O_EXCL",
56133299c2f1SGregory Neil Shapiro #endif /* BOGUS_O_EXCL */
561412ed1c7cSGregory Neil Shapiro #if DEC_OSF_BROKEN_GETPWENT
561512ed1c7cSGregory Neil Shapiro 	"DEC_OSF_BROKEN_GETPWENT",
561612ed1c7cSGregory Neil Shapiro #endif /* DEC_OSF_BROKEN_GETPWENT */
56173299c2f1SGregory Neil Shapiro #if FAST_PID_RECYCLE
56183299c2f1SGregory Neil Shapiro 	"FAST_PID_RECYCLE",
56193299c2f1SGregory Neil Shapiro #endif /* FAST_PID_RECYCLE */
56203299c2f1SGregory Neil Shapiro #if HASFCHOWN
56213299c2f1SGregory Neil Shapiro 	"HASFCHOWN",
56223299c2f1SGregory Neil Shapiro #endif /* HASFCHOWN */
5623c2aa98e2SPeter Wemm #if HASFCHMOD
5624c2aa98e2SPeter Wemm 	"HASFCHMOD",
56253299c2f1SGregory Neil Shapiro #endif /* HASFCHMOD */
5626c2aa98e2SPeter Wemm #if HASFLOCK
5627c2aa98e2SPeter Wemm 	"HASFLOCK",
56283299c2f1SGregory Neil Shapiro #endif /* HASFLOCK */
5629c2aa98e2SPeter Wemm #if HASGETDTABLESIZE
5630c2aa98e2SPeter Wemm 	"HASGETDTABLESIZE",
56313299c2f1SGregory Neil Shapiro #endif /* HASGETDTABLESIZE */
5632c2aa98e2SPeter Wemm #if HASGETUSERSHELL
5633c2aa98e2SPeter Wemm 	"HASGETUSERSHELL",
56343299c2f1SGregory Neil Shapiro #endif /* HASGETUSERSHELL */
5635c2aa98e2SPeter Wemm #if HASINITGROUPS
5636c2aa98e2SPeter Wemm 	"HASINITGROUPS",
56373299c2f1SGregory Neil Shapiro #endif /* HASINITGROUPS */
5638c2aa98e2SPeter Wemm #if HASLSTAT
5639c2aa98e2SPeter Wemm 	"HASLSTAT",
56403299c2f1SGregory Neil Shapiro #endif /* HASLSTAT */
564112ed1c7cSGregory Neil Shapiro #if HASNICE
564212ed1c7cSGregory Neil Shapiro 	"HASNICE",
564312ed1c7cSGregory Neil Shapiro #endif /* HASNICE */
56443299c2f1SGregory Neil Shapiro #if HASRANDOM
56453299c2f1SGregory Neil Shapiro 	"HASRANDOM",
56463299c2f1SGregory Neil Shapiro #endif /* HASRANDOM */
564712ed1c7cSGregory Neil Shapiro #if HASRRESVPORT
564812ed1c7cSGregory Neil Shapiro 	"HASRRESVPORT",
564912ed1c7cSGregory Neil Shapiro #endif /* HASRRESVPORT */
565012ed1c7cSGregory Neil Shapiro #if HASSETEGID
565112ed1c7cSGregory Neil Shapiro 	"HASSETEGID",
565212ed1c7cSGregory Neil Shapiro #endif /* HASSETEGID */
56533299c2f1SGregory Neil Shapiro #if HASSETLOGIN
56543299c2f1SGregory Neil Shapiro 	"HASSETLOGIN",
56553299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
565612ed1c7cSGregory Neil Shapiro #if HASSETREGID
565712ed1c7cSGregory Neil Shapiro 	"HASSETREGID",
565812ed1c7cSGregory Neil Shapiro #endif /* HASSETREGID */
565912ed1c7cSGregory Neil Shapiro #if HASSETRESGID
566012ed1c7cSGregory Neil Shapiro 	"HASSETRESGID",
566112ed1c7cSGregory Neil Shapiro #endif /* HASSETRESGID */
5662c2aa98e2SPeter Wemm #if HASSETREUID
5663c2aa98e2SPeter Wemm 	"HASSETREUID",
56643299c2f1SGregory Neil Shapiro #endif /* HASSETREUID */
5665c2aa98e2SPeter Wemm #if HASSETRLIMIT
5666c2aa98e2SPeter Wemm 	"HASSETRLIMIT",
56673299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
5668c2aa98e2SPeter Wemm #if HASSETSID
5669c2aa98e2SPeter Wemm 	"HASSETSID",
56703299c2f1SGregory Neil Shapiro #endif /* HASSETSID */
5671c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT
5672c2aa98e2SPeter Wemm 	"HASSETUSERCONTEXT",
56733299c2f1SGregory Neil Shapiro #endif /* HASSETUSERCONTEXT */
5674c2aa98e2SPeter Wemm #if HASSETVBUF
5675c2aa98e2SPeter Wemm 	"HASSETVBUF",
56763299c2f1SGregory Neil Shapiro #endif /* HASSETVBUF */
5677c2aa98e2SPeter Wemm #if HAS_ST_GEN
5678c2aa98e2SPeter Wemm 	"HAS_ST_GEN",
56793299c2f1SGregory Neil Shapiro #endif /* HAS_ST_GEN */
56803299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
56813299c2f1SGregory Neil Shapiro 	"HASSRANDOMDEV",
56823299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
56833299c2f1SGregory Neil Shapiro #if HASURANDOMDEV
56843299c2f1SGregory Neil Shapiro 	"HASURANDOMDEV",
56853299c2f1SGregory Neil Shapiro #endif /* HASURANDOMDEV */
5686c2aa98e2SPeter Wemm #if HASSTRERROR
5687c2aa98e2SPeter Wemm 	"HASSTRERROR",
56883299c2f1SGregory Neil Shapiro #endif /* HASSTRERROR */
5689c2aa98e2SPeter Wemm #if HASULIMIT
5690c2aa98e2SPeter Wemm 	"HASULIMIT",
56913299c2f1SGregory Neil Shapiro #endif /* HASULIMIT */
5692c2aa98e2SPeter Wemm #if HASUNAME
5693c2aa98e2SPeter Wemm 	"HASUNAME",
56943299c2f1SGregory Neil Shapiro #endif /* HASUNAME */
5695c2aa98e2SPeter Wemm #if HASUNSETENV
5696c2aa98e2SPeter Wemm 	"HASUNSETENV",
56973299c2f1SGregory Neil Shapiro #endif /* HASUNSETENV */
5698c2aa98e2SPeter Wemm #if HASWAITPID
5699c2aa98e2SPeter Wemm 	"HASWAITPID",
57003299c2f1SGregory Neil Shapiro #endif /* HASWAITPID */
5701c2aa98e2SPeter Wemm #if IDENTPROTO
5702c2aa98e2SPeter Wemm 	"IDENTPROTO",
57033299c2f1SGregory Neil Shapiro #endif /* IDENTPROTO */
5704c2aa98e2SPeter Wemm #if IP_SRCROUTE
5705c2aa98e2SPeter Wemm 	"IP_SRCROUTE",
57063299c2f1SGregory Neil Shapiro #endif /* IP_SRCROUTE */
5707c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
5708c2aa98e2SPeter Wemm 	"LOCK_ON_OPEN",
57093299c2f1SGregory Neil Shapiro #endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
5710c2aa98e2SPeter Wemm #if NEEDFSYNC
5711c2aa98e2SPeter Wemm 	"NEEDFSYNC",
57123299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
571312ed1c7cSGregory Neil Shapiro #if NEEDLINK
571412ed1c7cSGregory Neil Shapiro 	"NEEDLINK",
571512ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */
571612ed1c7cSGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
571712ed1c7cSGregory Neil Shapiro 	"NEEDLOCAL_HOSTNAME_LENGTH",
571812ed1c7cSGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
571912ed1c7cSGregory Neil Shapiro #if NEEDSGETIPNODE
572012ed1c7cSGregory Neil Shapiro 	"NEEDSGETIPNODE",
572112ed1c7cSGregory Neil Shapiro #endif /* NEEDSGETIPNODE */
572212ed1c7cSGregory Neil Shapiro #if NEEDSTRSTR
572312ed1c7cSGregory Neil Shapiro 	"NEEDSTRSTR",
572412ed1c7cSGregory Neil Shapiro #endif /* NEEDSTRSTR */
572512ed1c7cSGregory Neil Shapiro #if NEEDSTRTOL
572612ed1c7cSGregory Neil Shapiro 	"NEEDSTRTOL",
572712ed1c7cSGregory Neil Shapiro #endif /* NEEDSTRTOL */
572812ed1c7cSGregory Neil Shapiro #ifdef NO_GETSERVBYNAME
572912ed1c7cSGregory Neil Shapiro 	"NO_GETSERVBYNAME",
573012ed1c7cSGregory Neil Shapiro #endif /* NO_GETSERVBYNAME */
5731c2aa98e2SPeter Wemm #if NOFTRUNCATE
5732c2aa98e2SPeter Wemm 	"NOFTRUNCATE",
57333299c2f1SGregory Neil Shapiro #endif /* NOFTRUNCATE */
573412ed1c7cSGregory Neil Shapiro #if REQUIRES_DIR_FSYNC
573512ed1c7cSGregory Neil Shapiro 	"REQUIRES_DIR_FSYNC",
573612ed1c7cSGregory Neil Shapiro #endif /* REQUIRES_DIR_FSYNC */
5737c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H
5738c2aa98e2SPeter Wemm 	"RLIMIT_NEEDS_SYS_TIME_H",
57393299c2f1SGregory Neil Shapiro #endif /* RLIMIT_NEEDS_SYS_TIME_H */
5740c2aa98e2SPeter Wemm #if SAFENFSPATHCONF
5741c2aa98e2SPeter Wemm 	"SAFENFSPATHCONF",
57423299c2f1SGregory Neil Shapiro #endif /* SAFENFSPATHCONF */
5743c2aa98e2SPeter Wemm #if SECUREWARE
5744c2aa98e2SPeter Wemm 	"SECUREWARE",
57453299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
5746c2aa98e2SPeter Wemm #if SHARE_V1
5747c2aa98e2SPeter Wemm 	"SHARE_V1",
57483299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
5749c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN
5750c2aa98e2SPeter Wemm 	"SIOCGIFCONF_IS_BROKEN",
57513299c2f1SGregory Neil Shapiro #endif /* SIOCGIFCONF_IS_BROKEN */
5752c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN
5753c2aa98e2SPeter Wemm 	"SIOCGIFNUM_IS_BROKEN",
57543299c2f1SGregory Neil Shapiro #endif /* SIOCGIFNUM_IS_BROKEN */
57553299c2f1SGregory Neil Shapiro #if SNPRINTF_IS_BROKEN
57563299c2f1SGregory Neil Shapiro 	"SNPRINTF_IS_BROKEN",
57573299c2f1SGregory Neil Shapiro #endif /* SNPRINTF_IS_BROKEN */
57583299c2f1SGregory Neil Shapiro #if SO_REUSEADDR_IS_BROKEN
57593299c2f1SGregory Neil Shapiro 	"SO_REUSEADDR_IS_BROKEN",
57603299c2f1SGregory Neil Shapiro #endif /* SO_REUSEADDR_IS_BROKEN */
5761c2aa98e2SPeter Wemm #if SYS5SETPGRP
5762c2aa98e2SPeter Wemm 	"SYS5SETPGRP",
57633299c2f1SGregory Neil Shapiro #endif /* SYS5SETPGRP */
5764c2aa98e2SPeter Wemm #if SYSTEM5
5765c2aa98e2SPeter Wemm 	"SYSTEM5",
57663299c2f1SGregory Neil Shapiro #endif /* SYSTEM5 */
576712ed1c7cSGregory Neil Shapiro #if USE_DOUBLE_FORK
576812ed1c7cSGregory Neil Shapiro 	"USE_DOUBLE_FORK",
576912ed1c7cSGregory Neil Shapiro #endif /* USE_DOUBLE_FORK */
577012ed1c7cSGregory Neil Shapiro #if USE_ENVIRON
577112ed1c7cSGregory Neil Shapiro 	"USE_ENVIRON",
577212ed1c7cSGregory Neil Shapiro #endif /* USE_ENVIRON */
5773c2aa98e2SPeter Wemm #if USE_SA_SIGACTION
5774c2aa98e2SPeter Wemm 	"USE_SA_SIGACTION",
57753299c2f1SGregory Neil Shapiro #endif /* USE_SA_SIGACTION */
5776c2aa98e2SPeter Wemm #if USE_SIGLONGJMP
5777c2aa98e2SPeter Wemm 	"USE_SIGLONGJMP",
57783299c2f1SGregory Neil Shapiro #endif /* USE_SIGLONGJMP */
577912ed1c7cSGregory Neil Shapiro #if USEGETCONFATTR
578012ed1c7cSGregory Neil Shapiro 	"USEGETCONFATTR",
578112ed1c7cSGregory Neil Shapiro #endif /* USEGETCONFATTR */
5782c2aa98e2SPeter Wemm #if USESETEUID
5783c2aa98e2SPeter Wemm 	"USESETEUID",
57843299c2f1SGregory Neil Shapiro #endif /* USESETEUID */
578512ed1c7cSGregory Neil Shapiro #ifdef USESYSCTL
578612ed1c7cSGregory Neil Shapiro 	"USESYSCTL",
578712ed1c7cSGregory Neil Shapiro #endif /* USESYSCTL */
578812ed1c7cSGregory Neil Shapiro #if USING_NETSCAPE_LDAP
578912ed1c7cSGregory Neil Shapiro 	"USING_NETSCAPE_LDAP",
579012ed1c7cSGregory Neil Shapiro #endif /* USING_NETSCAPE_LDAP */
579112ed1c7cSGregory Neil Shapiro #ifdef WAITUNION
579212ed1c7cSGregory Neil Shapiro 	"WAITUNION",
579312ed1c7cSGregory Neil Shapiro #endif /* WAITUNION */
579412ed1c7cSGregory Neil Shapiro 	NULL
579512ed1c7cSGregory Neil Shapiro };
579612ed1c7cSGregory Neil Shapiro 
579712ed1c7cSGregory Neil Shapiro /*
579812ed1c7cSGregory Neil Shapiro **  FFR compile options.
579912ed1c7cSGregory Neil Shapiro */
580012ed1c7cSGregory Neil Shapiro 
580112ed1c7cSGregory Neil Shapiro char	*FFRCompileOptions[] =
580212ed1c7cSGregory Neil Shapiro {
580312ed1c7cSGregory Neil Shapiro #if _FFR_ADAPTIVE_EOL
580412ed1c7cSGregory Neil Shapiro 	"_FFR_ADAPTIVE_EOL",
580512ed1c7cSGregory Neil Shapiro #endif /* _FFR_ADAPTIVE_EOL */
580612ed1c7cSGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO
580712ed1c7cSGregory Neil Shapiro 	"_FFR_ALLOW_SASLINFO",
580812ed1c7cSGregory Neil Shapiro #endif /* _FFR_ALLOW_SASLINFO */
580912ed1c7cSGregory Neil Shapiro #if _FFR_BESTMX_BETTER_TRUNCATION
581012ed1c7cSGregory Neil Shapiro 	"_FFR_BESTMX_BETTER_TRUNCATION",
581112ed1c7cSGregory Neil Shapiro #endif /* _FFR_BESTMX_BETTER_TRUNCATION */
581212ed1c7cSGregory Neil Shapiro #if _FFR_CACHE_LPC
581312ed1c7cSGregory Neil Shapiro /* Christophe Wolfhugel of France Telecom Oleane */
581412ed1c7cSGregory Neil Shapiro 	"_FFR_CACHE_LPC",
581512ed1c7cSGregory Neil Shapiro #endif /* _FFR_CACHE_LPC */
581612ed1c7cSGregory Neil Shapiro #if _FFR_CATCH_BROKEN_MTAS
581712ed1c7cSGregory Neil Shapiro 	"_FFR_CATCH_BROKEN_MTAS",
581812ed1c7cSGregory Neil Shapiro #endif /* _FFR_CATCH_BROKEN_MTAS */
581912ed1c7cSGregory Neil Shapiro #if _FFR_CHECK_EOM
582012ed1c7cSGregory Neil Shapiro 	"_FFR_CHECK_EOM",
582112ed1c7cSGregory Neil Shapiro #endif /* _FFR_CHECK_EOM */
582212ed1c7cSGregory Neil Shapiro #if _FFR_CONTROL_MSTAT
582312ed1c7cSGregory Neil Shapiro 	"_FFR_CONTROL_MSTAT",
582412ed1c7cSGregory Neil Shapiro #endif /* _FFR_CONTROL_MSTAT */
582512ed1c7cSGregory Neil Shapiro #if _FFR_DAEMON_NETUNIX
582612ed1c7cSGregory Neil Shapiro 	"_FFR_DAEMON_NETUNIX",
582712ed1c7cSGregory Neil Shapiro #endif /* _FFR_DAEMON_NETUNIX */
582812ed1c7cSGregory Neil Shapiro #if _FFR_DEPRECATE_MAILER_FLAG_I
582912ed1c7cSGregory Neil Shapiro 	"_FFR_DEPRECATE_MAILER_FLAG_I",
583012ed1c7cSGregory Neil Shapiro #endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
583112ed1c7cSGregory Neil Shapiro #if _FFR_DNSMAP_BASE
583212ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_BASE",
583312ed1c7cSGregory Neil Shapiro #endif /* _FFR_DNSMAP_BASE */
583412ed1c7cSGregory Neil Shapiro #if _FFR_DNSMAP_MULTI
583512ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_MULTI",
583612ed1c7cSGregory Neil Shapiro # if _FFR_DNSMAP_MULTILIMIT
583712ed1c7cSGregory Neil Shapiro 	"_FFR_DNSMAP_MULTILIMIT",
583812ed1c7cSGregory Neil Shapiro # endif /* _FFR_DNSMAP_MULTILIMIT */
583912ed1c7cSGregory Neil Shapiro #endif /* _FFR_DNSMAP_MULTI */
584012ed1c7cSGregory Neil Shapiro #if _FFR_DONTLOCKFILESFORREAD_OPTION
584112ed1c7cSGregory Neil Shapiro 	"_FFR_DONTLOCKFILESFORREAD_OPTION",
584212ed1c7cSGregory Neil Shapiro #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
584312ed1c7cSGregory Neil Shapiro #if _FFR_DOTTED_USERNAMES
584412ed1c7cSGregory Neil Shapiro 	"_FFR_DOTTED_USERNAMES",
584512ed1c7cSGregory Neil Shapiro #endif /* _FFR_DOTTED_USERNAMES */
584612ed1c7cSGregory Neil Shapiro #if _FFR_DROP_TRUSTUSER_WARNING
584712ed1c7cSGregory Neil Shapiro 	"_FFR_DROP_TRUSTUSER_WARNING",
584812ed1c7cSGregory Neil Shapiro #endif /* _FFR_DROP_TRUSTUSER_WARNING */
584912ed1c7cSGregory Neil Shapiro #if _FFR_FIX_DASHT
585012ed1c7cSGregory Neil Shapiro 	"_FFR_FIX_DASHT",
585112ed1c7cSGregory Neil Shapiro #endif /* _FFR_FIX_DASHT */
585212ed1c7cSGregory Neil Shapiro #if _FFR_FORWARD_SYSERR
585312ed1c7cSGregory Neil Shapiro 	"_FFR_FORWARD_SYSERR",
585412ed1c7cSGregory Neil Shapiro #endif /* _FFR_FORWARD_SYSERR */
585512ed1c7cSGregory Neil Shapiro #if _FFR_GEN_ORCPT
585612ed1c7cSGregory Neil Shapiro 	"_FFR_GEN_ORCPT",
585712ed1c7cSGregory Neil Shapiro #endif /* _FFR_GEN_ORCPT */
585812ed1c7cSGregory Neil Shapiro #if _FFR_GROUPREADABLEAUTHINFOFILE
585912ed1c7cSGregory Neil Shapiro 	"_FFR_GROUPREADABLEAUTHINFOFILE",
586012ed1c7cSGregory Neil Shapiro #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
586112ed1c7cSGregory Neil Shapiro #if _FFR_HDR_TYPE
586212ed1c7cSGregory Neil Shapiro 	"_FFR_HDR_TYPE",
586312ed1c7cSGregory Neil Shapiro #endif /* _FFR_HDR_TYPE */
586412ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
586512ed1c7cSGregory Neil Shapiro 	"_FFR_HPUX_NSSWITCH",
586612ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */
586712ed1c7cSGregory Neil Shapiro #if _FFR_IGNORE_EXT_ON_HELO
586812ed1c7cSGregory Neil Shapiro 	"_FFR_IGNORE_EXT_ON_HELO",
586912ed1c7cSGregory Neil Shapiro #endif /* _FFR_IGNORE_EXT_ON_HELO */
587012ed1c7cSGregory Neil Shapiro #if _FFR_LDAP_RECURSION
587112ed1c7cSGregory Neil Shapiro 	"_FFR_LDAP_RECURSION",
587212ed1c7cSGregory Neil Shapiro #endif /* _FFR_LDAP_RECURSION */
587312ed1c7cSGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES
587412ed1c7cSGregory Neil Shapiro /* Randall S. Winchester of the University of Maryland */
587512ed1c7cSGregory Neil Shapiro 	"_FFR_MAX_FORWARD_ENTRIES",
587612ed1c7cSGregory Neil Shapiro #endif /* _FFR_MAX_FORWARD_ENTRIES */
587712ed1c7cSGregory Neil Shapiro #if MILTER
587812ed1c7cSGregory Neil Shapiro # if  _FFR_MILTER_PERDAEMON
587912ed1c7cSGregory Neil Shapiro 	"_FFR_MILTER_PERDAEMON",
588012ed1c7cSGregory Neil Shapiro # endif /* _FFR_MILTER_PERDAEMON */
588112ed1c7cSGregory Neil Shapiro #endif /* MILTER */
588212ed1c7cSGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD
588312ed1c7cSGregory Neil Shapiro /* Steven Pitzl */
588412ed1c7cSGregory Neil Shapiro 	"_FFR_NODELAYDSN_ON_HOLD",
588512ed1c7cSGregory Neil Shapiro #endif /* _FFR_NODELAYDSN_ON_HOLD */
588612ed1c7cSGregory Neil Shapiro #if _FFR_NO_PIPE
588712ed1c7cSGregory Neil Shapiro 	"_FFR_NO_PIPE",
588812ed1c7cSGregory Neil Shapiro #endif /* _FFR_NO_PIPE */
588912ed1c7cSGregory Neil Shapiro #if _FFR_QUARANTINE
589012ed1c7cSGregory Neil Shapiro 	"_FFR_QUARANTINE",
589112ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUARANTINE */
589212ed1c7cSGregory Neil Shapiro #if _FFR_QUEUEDELAY
589312ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUEDELAY",
589412ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUEDELAY */
589512ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_MACRO
589612ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_MACRO",
589712ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUE_MACRO */
589812ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_SCHED_DBG
589912ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_SCHED_DBG",
590012ed1c7cSGregory Neil Shapiro #endif /* _FFR_QUEUE_SCHED_DBG */
590112ed1c7cSGregory Neil Shapiro #if _FFR_REDIRECTEMPTY
590212ed1c7cSGregory Neil Shapiro 	"_FFR_REDIRECTEMPTY",
590312ed1c7cSGregory Neil Shapiro #endif /* _FFR_REDIRECTEMPTY */
590412ed1c7cSGregory Neil Shapiro #if _FFR_RESET_MACRO_GLOBALS
590512ed1c7cSGregory Neil Shapiro 	"_FFR_RESET_MACRO_GLOBALS",
590612ed1c7cSGregory Neil Shapiro #endif /* _FFR_RESET_MACRO_GLOBALS */
590712ed1c7cSGregory Neil Shapiro #if _FFR_RHS
590812ed1c7cSGregory Neil Shapiro 	"_FFR_RHS",
590912ed1c7cSGregory Neil Shapiro #endif /* _FFR_RHS */
591012ed1c7cSGregory Neil Shapiro #if _FFR_SHM_STATUS
591112ed1c7cSGregory Neil Shapiro 	"_FFR_SHM_STATUS",
591212ed1c7cSGregory Neil Shapiro #endif /* _FFR_SHM_STATUS */
591312ed1c7cSGregory Neil Shapiro #if _FFR_SMTP_SSL
591412ed1c7cSGregory Neil Shapiro 	"_FFR_SMTP_SSL",
591512ed1c7cSGregory Neil Shapiro #endif /* _FFR_SMTP_SSL */
591612ed1c7cSGregory Neil Shapiro #if _FFR_SOFT_BOUNCE
591712ed1c7cSGregory Neil Shapiro 	"_FFR_SOFT_BOUNCE",
591812ed1c7cSGregory Neil Shapiro #endif /* _FFR_SOFT_BOUNCE */
591912ed1c7cSGregory Neil Shapiro #if _FFR_TIMERS
592012ed1c7cSGregory Neil Shapiro 	"_FFR_TIMERS",
592112ed1c7cSGregory Neil Shapiro #endif /* _FFR_TIMERS */
592212ed1c7cSGregory Neil Shapiro #if _FFR_TLS_1
592312ed1c7cSGregory Neil Shapiro 	"_FFR_TLS_1",
592412ed1c7cSGregory Neil Shapiro #endif /* _FFR_TLS_1 */
592512ed1c7cSGregory Neil Shapiro #if _FFR_TRUSTED_QF
592612ed1c7cSGregory Neil Shapiro 	"_FFR_TRUSTED_QF",
592712ed1c7cSGregory Neil Shapiro #endif /* _FFR_TRUSTED_QF */
5928c2aa98e2SPeter Wemm 	NULL
5929c2aa98e2SPeter Wemm };
59303299c2f1SGregory Neil Shapiro 
5931