xref: /freebsd/contrib/sendmail/src/conf.c (revision c0c4794d8403bee6c8659347a54fd9d51d1c04f9)
1c2aa98e2SPeter Wemm /*
2b4662009SGregory Neil Shapiro  * Copyright (c) 1998-2001 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 
14c2aa98e2SPeter Wemm #ifndef lint
15c0c4794dSGregory Neil Shapiro static char id[] = "@(#)$Id: conf.c,v 8.646.2.2.2.86 2001/05/17 18:18:40 ca Exp $";
163299c2f1SGregory Neil Shapiro #endif /* ! lint */
17c2aa98e2SPeter Wemm 
183299c2f1SGregory Neil Shapiro /* $FreeBSD$ */
193299c2f1SGregory Neil Shapiro 
203299c2f1SGregory Neil Shapiro #include <sendmail.h>
213299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
223299c2f1SGregory Neil Shapiro 
23c2aa98e2SPeter Wemm # include <sys/ioctl.h>
24c2aa98e2SPeter Wemm # include <sys/param.h>
253299c2f1SGregory Neil Shapiro 
26c2aa98e2SPeter Wemm #include <limits.h>
273299c2f1SGregory Neil Shapiro #if NETINET || NETINET6
283299c2f1SGregory Neil Shapiro # include <arpa/inet.h>
293299c2f1SGregory Neil Shapiro #endif /* NETINET || NETINET6 */
303299c2f1SGregory Neil Shapiro #if HASULIMIT && defined(HPUX11)
313299c2f1SGregory Neil Shapiro # include <ulimit.h>
323299c2f1SGregory Neil Shapiro #endif /* HASULIMIT && defined(HPUX11) */
333299c2f1SGregory Neil Shapiro 
343299c2f1SGregory Neil Shapiro 
353299c2f1SGregory Neil Shapiro static void	setupmaps __P((void));
363299c2f1SGregory Neil Shapiro static void	setupmailers __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	},
84c2aa98e2SPeter Wemm 
85c2aa98e2SPeter Wemm 		/* destination fields */
863299c2f1SGregory Neil Shapiro 	{ "to",				H_RCPT,			NULL	},
873299c2f1SGregory Neil Shapiro 	{ "resent-to",			H_RCPT|H_RESENT,	NULL	},
883299c2f1SGregory Neil Shapiro 	{ "cc",				H_RCPT,			NULL	},
893299c2f1SGregory Neil Shapiro 	{ "resent-cc",			H_RCPT|H_RESENT,	NULL	},
903299c2f1SGregory Neil Shapiro 	{ "bcc",			H_RCPT|H_BCC,		NULL	},
913299c2f1SGregory Neil Shapiro 	{ "resent-bcc",			H_RCPT|H_BCC|H_RESENT,	NULL	},
923299c2f1SGregory Neil Shapiro 	{ "apparently-to",		H_RCPT,			NULL	},
93c2aa98e2SPeter Wemm 
94c2aa98e2SPeter Wemm 		/* message identification and control */
953299c2f1SGregory Neil Shapiro 	{ "message-id",			0,			NULL	},
963299c2f1SGregory Neil Shapiro 	{ "resent-message-id",		H_RESENT,		NULL	},
973299c2f1SGregory Neil Shapiro 	{ "message",			H_EOH,			NULL	},
983299c2f1SGregory Neil Shapiro 	{ "text",			H_EOH,			NULL	},
99c2aa98e2SPeter Wemm 
100c2aa98e2SPeter Wemm 		/* date fields */
1013299c2f1SGregory Neil Shapiro 	{ "date",			0,			NULL	},
1023299c2f1SGregory Neil Shapiro 	{ "resent-date",		H_RESENT,		NULL	},
103c2aa98e2SPeter Wemm 
104c2aa98e2SPeter Wemm 		/* trace fields */
1053299c2f1SGregory Neil Shapiro 	{ "received",			H_TRACE|H_FORCE,	NULL	},
1063299c2f1SGregory Neil Shapiro 	{ "x400-received",		H_TRACE|H_FORCE,	NULL	},
1073299c2f1SGregory Neil Shapiro 	{ "via",			H_TRACE|H_FORCE,	NULL	},
1083299c2f1SGregory Neil Shapiro 	{ "mail-from",			H_TRACE|H_FORCE,	NULL	},
109c2aa98e2SPeter Wemm 
110c2aa98e2SPeter Wemm 		/* miscellaneous fields */
1113299c2f1SGregory Neil Shapiro 	{ "comments",			H_FORCE|H_ENCODABLE,	NULL	},
1123299c2f1SGregory Neil Shapiro 	{ "return-path",		H_FORCE|H_ACHECK|H_BINDLATE,	NULL	},
1133299c2f1SGregory Neil Shapiro 	{ "content-transfer-encoding",	H_CTE,			NULL	},
1143299c2f1SGregory Neil Shapiro 	{ "content-type",		H_CTYPE,		NULL	},
1153299c2f1SGregory Neil Shapiro 	{ "content-length",		H_ACHECK,		NULL	},
1163299c2f1SGregory Neil Shapiro 	{ "subject",			H_ENCODABLE,		NULL	},
1173299c2f1SGregory Neil Shapiro 	{ "x-authentication-warning",	H_FORCE,		NULL	},
118c2aa98e2SPeter Wemm 
1193299c2f1SGregory Neil Shapiro 	{ NULL,				0,			NULL	}
120c2aa98e2SPeter Wemm };
121c2aa98e2SPeter Wemm 
122c2aa98e2SPeter Wemm 
123c2aa98e2SPeter Wemm 
124c2aa98e2SPeter Wemm /*
125c2aa98e2SPeter Wemm **  Privacy values
126c2aa98e2SPeter Wemm */
127c2aa98e2SPeter Wemm 
128c2aa98e2SPeter Wemm struct prival PrivacyValues[] =
129c2aa98e2SPeter Wemm {
130c2aa98e2SPeter Wemm 	{ "public",		PRIV_PUBLIC		},
131c2aa98e2SPeter Wemm 	{ "needmailhelo",	PRIV_NEEDMAILHELO	},
132c2aa98e2SPeter Wemm 	{ "needexpnhelo",	PRIV_NEEDEXPNHELO	},
133c2aa98e2SPeter Wemm 	{ "needvrfyhelo",	PRIV_NEEDVRFYHELO	},
134c2aa98e2SPeter Wemm 	{ "noexpn",		PRIV_NOEXPN		},
135c2aa98e2SPeter Wemm 	{ "novrfy",		PRIV_NOVRFY		},
136c2aa98e2SPeter Wemm 	{ "restrictmailq",	PRIV_RESTRICTMAILQ	},
137c2aa98e2SPeter Wemm 	{ "restrictqrun",	PRIV_RESTRICTQRUN	},
138c2aa98e2SPeter Wemm 	{ "noetrn",		PRIV_NOETRN		},
139c2aa98e2SPeter Wemm 	{ "noverb",		PRIV_NOVERB		},
140c2aa98e2SPeter Wemm 	{ "authwarnings",	PRIV_AUTHWARNINGS	},
141c2aa98e2SPeter Wemm 	{ "noreceipts",		PRIV_NORECEIPTS		},
1423299c2f1SGregory Neil Shapiro 	{ "nobodyreturn",	PRIV_NOBODYRETN		},
143c2aa98e2SPeter Wemm 	{ "goaway",		PRIV_GOAWAY		},
144c2aa98e2SPeter Wemm 	{ NULL,			0			}
145c2aa98e2SPeter Wemm };
146c2aa98e2SPeter Wemm 
147c2aa98e2SPeter Wemm /*
148c2aa98e2SPeter Wemm **  DontBlameSendmail values
149c2aa98e2SPeter Wemm */
150c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] =
151c2aa98e2SPeter Wemm {
152c2aa98e2SPeter Wemm 	{ "safe",			DBS_SAFE			},
153c2aa98e2SPeter Wemm 	{ "assumesafechown",		DBS_ASSUMESAFECHOWN		},
154c2aa98e2SPeter Wemm 	{ "groupwritabledirpathsafe",	DBS_GROUPWRITABLEDIRPATHSAFE	},
155c2aa98e2SPeter Wemm 	{ "groupwritableforwardfilesafe",
156c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEFORWARDFILESAFE },
157c2aa98e2SPeter Wemm 	{ "groupwritableincludefilesafe",
158c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEINCLUDEFILESAFE },
159c2aa98e2SPeter Wemm 	{ "groupwritablealiasfile",	DBS_GROUPWRITABLEALIASFILE	},
160c2aa98e2SPeter Wemm 	{ "worldwritablealiasfile",	DBS_WORLDWRITABLEALIASFILE	},
161c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpath",	DBS_FORWARDFILEINUNSAFEDIRPATH	},
162c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpath",	DBS_INCLUDEFILEINUNSAFEDIRPATH	},
163c2aa98e2SPeter Wemm 	{ "mapinunsafedirpath",		DBS_MAPINUNSAFEDIRPATH	},
164c2aa98e2SPeter Wemm 	{ "linkedaliasfileinwritabledir",
165c2aa98e2SPeter Wemm 					DBS_LINKEDALIASFILEINWRITABLEDIR },
166c2aa98e2SPeter Wemm 	{ "linkedclassfileinwritabledir",
167c2aa98e2SPeter Wemm 					DBS_LINKEDCLASSFILEINWRITABLEDIR },
168c2aa98e2SPeter Wemm 	{ "linkedforwardfileinwritabledir",
169c2aa98e2SPeter Wemm 					DBS_LINKEDFORWARDFILEINWRITABLEDIR },
170c2aa98e2SPeter Wemm 	{ "linkedincludefileinwritabledir",
171c2aa98e2SPeter Wemm 					DBS_LINKEDINCLUDEFILEINWRITABLEDIR },
172c2aa98e2SPeter Wemm 	{ "linkedmapinwritabledir",	DBS_LINKEDMAPINWRITABLEDIR	},
173c2aa98e2SPeter Wemm 	{ "linkedserviceswitchfileinwritabledir",
174c2aa98e2SPeter Wemm 					DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR },
175c2aa98e2SPeter Wemm 	{ "filedeliverytohardlink",	DBS_FILEDELIVERYTOHARDLINK	},
176c2aa98e2SPeter Wemm 	{ "filedeliverytosymlink",	DBS_FILEDELIVERYTOSYMLINK	},
177c2aa98e2SPeter Wemm 	{ "writemaptohardlink",		DBS_WRITEMAPTOHARDLINK		},
178c2aa98e2SPeter Wemm 	{ "writemaptosymlink",		DBS_WRITEMAPTOSYMLINK		},
179c2aa98e2SPeter Wemm 	{ "writestatstohardlink",	DBS_WRITESTATSTOHARDLINK	},
180c2aa98e2SPeter Wemm 	{ "writestatstosymlink",	DBS_WRITESTATSTOSYMLINK		},
181c2aa98e2SPeter Wemm 	{ "forwardfileingroupwritabledirpath",
182c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINGROUPWRITABLEDIRPATH },
183c2aa98e2SPeter Wemm 	{ "includefileingroupwritabledirpath",
184c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH },
185c2aa98e2SPeter Wemm 	{ "classfileinunsafedirpath",	DBS_CLASSFILEINUNSAFEDIRPATH	},
186c2aa98e2SPeter Wemm 	{ "errorheaderinunsafedirpath",	DBS_ERRORHEADERINUNSAFEDIRPATH	},
187c2aa98e2SPeter Wemm 	{ "helpfileinunsafedirpath",	DBS_HELPFILEINUNSAFEDIRPATH	},
188c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpathsafe",
189c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINUNSAFEDIRPATHSAFE },
190c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpathsafe",
191c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
192c2aa98e2SPeter Wemm 	{ "runprograminunsafedirpath",	DBS_RUNPROGRAMINUNSAFEDIRPATH	},
193c2aa98e2SPeter Wemm 	{ "runwritableprogram",		DBS_RUNWRITABLEPROGRAM		},
1943299c2f1SGregory Neil Shapiro 	{ "nonrootsafeaddr",		DBS_NONROOTSAFEADDR		},
1953299c2f1SGregory Neil Shapiro 	{ "truststickybit",		DBS_TRUSTSTICKYBIT		},
1963299c2f1SGregory Neil Shapiro 	{ "dontwarnforwardfileinunsafedirpath",
1973299c2f1SGregory Neil Shapiro 					DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH },
1983299c2f1SGregory Neil Shapiro 	{ "insufficiententropy",	DBS_INSUFFICIENTENTROPY },
1993299c2f1SGregory Neil Shapiro #if _FFR_UNSAFE_SASL
2003299c2f1SGregory Neil Shapiro 	{ "groupreadablesaslfile",	DBS_GROUPREADABLESASLFILE	},
2013299c2f1SGregory Neil Shapiro #endif /* _FFR_UNSAFE_SASL */
202d995d2baSGregory Neil Shapiro #if _FFR_UNSAFE_WRITABLE_INCLUDE
203d995d2baSGregory Neil Shapiro 	{ "groupwritableforwardfile",	DBS_GROUPWRITABLEFORWARDFILE	},
204d995d2baSGregory Neil Shapiro 	{ "groupwritableincludefile",	DBS_GROUPWRITABLEINCLUDEFILE	},
205d995d2baSGregory Neil Shapiro 	{ "worldwritableforwardfile",	DBS_WORLDWRITABLEFORWARDFILE	},
206d995d2baSGregory Neil Shapiro 	{ "worldwritableincludefile",	DBS_WORLDWRITABLEINCLUDEFILE	},
207d995d2baSGregory Neil Shapiro #endif /* _FFR_UNSAFE_WRITABLE_INCLUDE */
208c2aa98e2SPeter Wemm 	{ NULL,				0				}
209c2aa98e2SPeter Wemm };
210c2aa98e2SPeter Wemm 
211c2aa98e2SPeter Wemm 
212c2aa98e2SPeter Wemm /*
213c2aa98e2SPeter Wemm **  Miscellaneous stuff.
214c2aa98e2SPeter Wemm */
215c2aa98e2SPeter Wemm 
216c2aa98e2SPeter Wemm int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
217c2aa98e2SPeter Wemm /*
218c2aa98e2SPeter Wemm **  SETDEFAULTS -- set default values
219c2aa98e2SPeter Wemm **
220c2aa98e2SPeter Wemm **	Because of the way freezing is done, these must be initialized
221c2aa98e2SPeter Wemm **	using direct code.
222c2aa98e2SPeter Wemm **
223c2aa98e2SPeter Wemm **	Parameters:
224c2aa98e2SPeter Wemm **		e -- the default envelope.
225c2aa98e2SPeter Wemm **
226c2aa98e2SPeter Wemm **	Returns:
227c2aa98e2SPeter Wemm **		none.
228c2aa98e2SPeter Wemm **
229c2aa98e2SPeter Wemm **	Side Effects:
230c2aa98e2SPeter Wemm **		Initializes a bunch of global variables to their
231c2aa98e2SPeter Wemm **		default values.
232c2aa98e2SPeter Wemm */
233c2aa98e2SPeter Wemm 
234c2aa98e2SPeter Wemm #define MINUTES		* 60
235c2aa98e2SPeter Wemm #define HOURS		* 60 MINUTES
236c2aa98e2SPeter Wemm #define DAYS		* 24 HOURS
237c2aa98e2SPeter Wemm 
238c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION
239c2aa98e2SPeter Wemm # define MAXRULERECURSION	50	/* max ruleset recursion depth */
2403299c2f1SGregory Neil Shapiro #endif /* ! MAXRULERECURSION */
241c2aa98e2SPeter Wemm 
242c2aa98e2SPeter Wemm void
243c2aa98e2SPeter Wemm setdefaults(e)
244c2aa98e2SPeter Wemm 	register ENVELOPE *e;
245c2aa98e2SPeter Wemm {
246c2aa98e2SPeter Wemm 	int i;
2473299c2f1SGregory Neil Shapiro 	int numprocs;
248c2aa98e2SPeter Wemm 	struct passwd *pw;
249c2aa98e2SPeter Wemm 
2503299c2f1SGregory Neil Shapiro 	numprocs = get_num_procs_online();
251c2aa98e2SPeter Wemm 	SpaceSub = ' ';				/* option B */
2523299c2f1SGregory Neil Shapiro 	QueueLA = 8 * numprocs;			/* option x */
2533299c2f1SGregory Neil Shapiro 	RefuseLA = 12 * numprocs;		/* option X */
254c2aa98e2SPeter Wemm 	WkRecipFact = 30000L;			/* option y */
255c2aa98e2SPeter Wemm 	WkClassFact = 1800L;			/* option z */
256c2aa98e2SPeter Wemm 	WkTimeFact = 90000L;			/* option Z */
257c2aa98e2SPeter Wemm 	QueueFactor = WkRecipFact * 20;		/* option q */
258c2aa98e2SPeter Wemm 	FileMode = (RealUid != geteuid()) ? 0644 : 0600;
259c2aa98e2SPeter Wemm 						/* option F */
2603299c2f1SGregory Neil Shapiro #if _FFR_QUEUE_FILE_MODE
2613299c2f1SGregory Neil Shapiro 	QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600;
2623299c2f1SGregory Neil Shapiro 						/* option QueueFileMode */
2633299c2f1SGregory Neil Shapiro #endif /* _FFR_QUEUE_FILE_MODE */
264c2aa98e2SPeter Wemm 
2653299c2f1SGregory Neil Shapiro 	if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) ||
2663299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) ||
2673299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0))
268c2aa98e2SPeter Wemm 	{
269c2aa98e2SPeter Wemm 		DefUid = pw->pw_uid;		/* option u */
270c2aa98e2SPeter Wemm 		DefGid = pw->pw_gid;		/* option g */
271c2aa98e2SPeter Wemm 		DefUser = newstr(pw->pw_name);
272c2aa98e2SPeter Wemm 	}
273c2aa98e2SPeter Wemm 	else
274c2aa98e2SPeter Wemm 	{
275c2aa98e2SPeter Wemm 		DefUid = 1;			/* option u */
276c2aa98e2SPeter Wemm 		DefGid = 1;			/* option g */
277c2aa98e2SPeter Wemm 		setdefuser();
278c2aa98e2SPeter Wemm 	}
27976b7bf71SPeter Wemm 	TrustedUid = 0;
280c2aa98e2SPeter Wemm 	if (tTd(37, 4))
2813299c2f1SGregory Neil Shapiro 		dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n",
282c2aa98e2SPeter Wemm 			DefUser != NULL ? DefUser : "<1:1>",
283c2aa98e2SPeter Wemm 			(int) DefUid, (int) DefGid);
284c2aa98e2SPeter Wemm 	CheckpointInterval = 10;		/* option C */
285c2aa98e2SPeter Wemm 	MaxHopCount = 25;			/* option h */
2863299c2f1SGregory Neil Shapiro 	set_delivery_mode(SM_FORK, e);		/* option d */
287c2aa98e2SPeter Wemm 	e->e_errormode = EM_PRINT;		/* option e */
2883299c2f1SGregory Neil Shapiro 	e->e_queuedir = NOQDIR;
2893299c2f1SGregory Neil Shapiro 	e->e_ctime = curtime();
290c2aa98e2SPeter Wemm 	SevenBitInput = FALSE;			/* option 7 */
291c2aa98e2SPeter Wemm 	MaxMciCache = 1;			/* option k */
292c2aa98e2SPeter Wemm 	MciCacheTimeout = 5 MINUTES;		/* option K */
293c2aa98e2SPeter Wemm 	LogLevel = 9;				/* option L */
2943299c2f1SGregory Neil Shapiro 	inittimeouts(NULL, FALSE);		/* option r */
295c2aa98e2SPeter Wemm 	PrivacyFlags = PRIV_PUBLIC;		/* option p */
2963299c2f1SGregory Neil Shapiro 	MeToo = TRUE;				/* option m */
2973299c2f1SGregory Neil Shapiro 	SendMIMEErrors = TRUE;			/* option f */
2983299c2f1SGregory Neil Shapiro 	SuperSafe = TRUE;			/* option s */
2993299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);		/* DontBlameSendmail option */
300c2aa98e2SPeter Wemm #if MIME8TO7
301c2aa98e2SPeter Wemm 	MimeMode = MM_CVTMIME|MM_PASS8BIT;	/* option 8 */
3023299c2f1SGregory Neil Shapiro #else /* MIME8TO7 */
303c2aa98e2SPeter Wemm 	MimeMode = MM_PASS8BIT;
3043299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
305c2aa98e2SPeter Wemm 	for (i = 0; i < MAXTOCLASS; i++)
306c2aa98e2SPeter Wemm 	{
307c2aa98e2SPeter Wemm 		TimeOuts.to_q_return[i] = 5 DAYS;	/* option T */
308c2aa98e2SPeter Wemm 		TimeOuts.to_q_warning[i] = 0;		/* option T */
309c2aa98e2SPeter Wemm 	}
3103299c2f1SGregory Neil Shapiro 	ServiceSwitchFile = "/etc/mail/service.switch";
311c2aa98e2SPeter Wemm 	ServiceCacheMaxAge = (time_t) 10;
312c2aa98e2SPeter Wemm 	HostsFile = _PATH_HOSTS;
313c2aa98e2SPeter Wemm 	PidFile = newstr(_PATH_SENDMAILPID);
314c2aa98e2SPeter Wemm 	MustQuoteChars = "@,;:\\()[].'";
315c2aa98e2SPeter Wemm 	MciInfoTimeout = 30 MINUTES;
316c2aa98e2SPeter Wemm 	MaxRuleRecursion = MAXRULERECURSION;
317c2aa98e2SPeter Wemm 	MaxAliasRecursion = 10;
318c2aa98e2SPeter Wemm 	MaxMacroRecursion = 10;
319c2aa98e2SPeter Wemm 	ColonOkInAddr = TRUE;
320c2aa98e2SPeter Wemm 	DontLockReadFiles = TRUE;
321c2aa98e2SPeter Wemm 	DoubleBounceAddr = "postmaster";
322e01d6f61SPeter Wemm 	MaxHeadersLength = MAXHDRSLEN;
3233299c2f1SGregory Neil Shapiro 	MaxForwardEntries = 0;
3243299c2f1SGregory Neil Shapiro #if SASL
3253299c2f1SGregory Neil Shapiro 	AuthMechanisms = newstr(AUTH_MECHANISMS);
3263299c2f1SGregory Neil Shapiro #endif /* SASL */
327c2aa98e2SPeter Wemm #ifdef HESIOD_INIT
328c2aa98e2SPeter Wemm 	HesiodContext = NULL;
3293299c2f1SGregory Neil Shapiro #endif /* HESIOD_INIT */
3303299c2f1SGregory Neil Shapiro #if NETINET6
3313299c2f1SGregory Neil Shapiro 	/* Detect if IPv6 is available at run time */
3323299c2f1SGregory Neil Shapiro 	i = socket(AF_INET6, SOCK_STREAM, 0);
3333299c2f1SGregory Neil Shapiro 	if (i >= 0)
3343299c2f1SGregory Neil Shapiro 	{
3353299c2f1SGregory Neil Shapiro 		InetMode = AF_INET6;
3363299c2f1SGregory Neil Shapiro 		(void) close(i);
3373299c2f1SGregory Neil Shapiro 	}
3383299c2f1SGregory Neil Shapiro 	else
3393299c2f1SGregory Neil Shapiro 		InetMode = AF_INET;
3403299c2f1SGregory Neil Shapiro #else /* NETINET6 */
3413299c2f1SGregory Neil Shapiro 	InetMode = AF_INET;
3423299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
34376b7bf71SPeter Wemm 	ControlSocketName = NULL;
3443299c2f1SGregory Neil Shapiro 	memset(&ConnectOnlyTo, '\0', sizeof ConnectOnlyTo);
3453299c2f1SGregory Neil Shapiro 	DataFileBufferSize = 4096;
3463299c2f1SGregory Neil Shapiro 	XscriptFileBufferSize = 4096;
3473299c2f1SGregory Neil Shapiro 	for (i = 0; i < MAXRWSETS; i++)
3483299c2f1SGregory Neil Shapiro 		RuleSetNames[i] = NULL;
3493299c2f1SGregory Neil Shapiro #if _FFR_MILTER
3503299c2f1SGregory Neil Shapiro 	InputFilters[0] = NULL;
3513299c2f1SGregory Neil Shapiro #endif /* _FFR_MILTER */
352c2aa98e2SPeter Wemm 	setupmaps();
353c2aa98e2SPeter Wemm 	setupmailers();
354c2aa98e2SPeter Wemm 	setupheaders();
355c2aa98e2SPeter Wemm }
356c2aa98e2SPeter Wemm 
357c2aa98e2SPeter Wemm 
358c2aa98e2SPeter Wemm /*
359c2aa98e2SPeter Wemm **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
360c2aa98e2SPeter Wemm */
361c2aa98e2SPeter Wemm 
362c2aa98e2SPeter Wemm void
363c2aa98e2SPeter Wemm setdefuser()
364c2aa98e2SPeter Wemm {
365c2aa98e2SPeter Wemm 	struct passwd *defpwent;
366c2aa98e2SPeter Wemm 	static char defuserbuf[40];
367c2aa98e2SPeter Wemm 
368c2aa98e2SPeter Wemm 	DefUser = defuserbuf;
369c2aa98e2SPeter Wemm 	defpwent = sm_getpwuid(DefUid);
370c2aa98e2SPeter Wemm 	snprintf(defuserbuf, sizeof defuserbuf, "%s",
371c2aa98e2SPeter Wemm 		defpwent == NULL ? "nobody" : defpwent->pw_name);
372c2aa98e2SPeter Wemm 	if (tTd(37, 4))
3733299c2f1SGregory Neil Shapiro 		dprintf("setdefuser: DefUid=%d, DefUser=%s\n",
374c2aa98e2SPeter Wemm 		       (int) DefUid, DefUser);
375c2aa98e2SPeter Wemm }
376c2aa98e2SPeter Wemm /*
377c2aa98e2SPeter Wemm **  SETUPMAILERS -- initialize default mailers
378c2aa98e2SPeter Wemm */
379c2aa98e2SPeter Wemm 
3803299c2f1SGregory Neil Shapiro static void
381c2aa98e2SPeter Wemm setupmailers()
382c2aa98e2SPeter Wemm {
383c2aa98e2SPeter Wemm 	char buf[100];
384c2aa98e2SPeter Wemm 
385c46d91b7SGregory Neil Shapiro 	(void) strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u",
3863299c2f1SGregory Neil Shapiro 		sizeof buf);
387c2aa98e2SPeter Wemm 	makemailer(buf);
388c2aa98e2SPeter Wemm 
3893299c2f1SGregory Neil Shapiro 	(void) strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u",
3903299c2f1SGregory Neil Shapiro 		sizeof buf);
391c2aa98e2SPeter Wemm 	makemailer(buf);
392c2aa98e2SPeter Wemm 
3933299c2f1SGregory Neil Shapiro 	(void) strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u",
3943299c2f1SGregory Neil Shapiro 		sizeof buf);
395c2aa98e2SPeter Wemm 	makemailer(buf);
3963299c2f1SGregory Neil Shapiro 	initerrmailers();
397c2aa98e2SPeter Wemm }
398c2aa98e2SPeter Wemm /*
399c2aa98e2SPeter Wemm **  SETUPMAPS -- set up map classes
400c2aa98e2SPeter Wemm */
401c2aa98e2SPeter Wemm 
402c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
403c2aa98e2SPeter Wemm 	{ \
404c2aa98e2SPeter Wemm 		extern bool parse __P((MAP *, char *)); \
405c2aa98e2SPeter Wemm 		extern bool open __P((MAP *, int)); \
406c2aa98e2SPeter Wemm 		extern void close __P((MAP *)); \
407c2aa98e2SPeter Wemm 		extern char *lookup __P((MAP *, char *, char **, int *)); \
408c2aa98e2SPeter Wemm 		extern void store __P((MAP *, char *, char *)); \
409c2aa98e2SPeter Wemm 		s = stab(name, ST_MAPCLASS, ST_ENTER); \
410c2aa98e2SPeter Wemm 		s->s_mapclass.map_cname = name; \
411c2aa98e2SPeter Wemm 		s->s_mapclass.map_ext = ext; \
412c2aa98e2SPeter Wemm 		s->s_mapclass.map_cflags = flags; \
413c2aa98e2SPeter Wemm 		s->s_mapclass.map_parse = parse; \
414c2aa98e2SPeter Wemm 		s->s_mapclass.map_open = open; \
415c2aa98e2SPeter Wemm 		s->s_mapclass.map_close = close; \
416c2aa98e2SPeter Wemm 		s->s_mapclass.map_lookup = lookup; \
417c2aa98e2SPeter Wemm 		s->s_mapclass.map_store = store; \
418c2aa98e2SPeter Wemm 	}
419c2aa98e2SPeter Wemm 
4203299c2f1SGregory Neil Shapiro static void
421c2aa98e2SPeter Wemm setupmaps()
422c2aa98e2SPeter Wemm {
423c2aa98e2SPeter Wemm 	register STAB *s;
424c2aa98e2SPeter Wemm 
425c2aa98e2SPeter Wemm #ifdef NEWDB
426c2aa98e2SPeter Wemm 	MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
427c2aa98e2SPeter Wemm 		map_parseargs, hash_map_open, db_map_close,
428c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
429c2aa98e2SPeter Wemm 
430c2aa98e2SPeter Wemm 	MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
431c2aa98e2SPeter Wemm 		map_parseargs, bt_map_open, db_map_close,
432c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
4333299c2f1SGregory Neil Shapiro #endif /* NEWDB */
434c2aa98e2SPeter Wemm 
435c2aa98e2SPeter Wemm #ifdef NDBM
436c2aa98e2SPeter Wemm 	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
437c2aa98e2SPeter Wemm 		map_parseargs, ndbm_map_open, ndbm_map_close,
438c2aa98e2SPeter Wemm 		ndbm_map_lookup, ndbm_map_store);
4393299c2f1SGregory Neil Shapiro #endif /* NDBM */
440c2aa98e2SPeter Wemm 
441c2aa98e2SPeter Wemm #ifdef NIS
442c2aa98e2SPeter Wemm 	MAPDEF("nis", NULL, MCF_ALIASOK,
443c2aa98e2SPeter Wemm 		map_parseargs, nis_map_open, null_map_close,
444c2aa98e2SPeter Wemm 		nis_map_lookup, null_map_store);
4453299c2f1SGregory Neil Shapiro #endif /* NIS */
446c2aa98e2SPeter Wemm 
447c2aa98e2SPeter Wemm #ifdef NISPLUS
448c2aa98e2SPeter Wemm 	MAPDEF("nisplus", NULL, MCF_ALIASOK,
449c2aa98e2SPeter Wemm 		map_parseargs, nisplus_map_open, null_map_close,
450c2aa98e2SPeter Wemm 		nisplus_map_lookup, null_map_store);
4513299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
4523299c2f1SGregory Neil Shapiro 
453c2aa98e2SPeter Wemm #ifdef LDAPMAP
4543299c2f1SGregory Neil Shapiro 	MAPDEF("ldap", NULL, MCF_ALIASOK,
4553299c2f1SGregory Neil Shapiro 		ldapmap_parseargs, ldapmap_open, ldapmap_close,
4563299c2f1SGregory Neil Shapiro 		ldapmap_lookup, null_map_store);
4573299c2f1SGregory Neil Shapiro 
4583299c2f1SGregory Neil Shapiro 	/* Deprecated */
4593299c2f1SGregory Neil Shapiro 	MAPDEF("ldapx", NULL, MCF_ALIASOK,
4603299c2f1SGregory Neil Shapiro 		ldapx_map_parseargs, ldapmap_open, ldapmap_close,
4613299c2f1SGregory Neil Shapiro 		ldapmap_lookup, null_map_store);
4623299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
4633299c2f1SGregory Neil Shapiro 
4643299c2f1SGregory Neil Shapiro #ifdef PH_MAP
4653299c2f1SGregory Neil Shapiro 	MAPDEF("ph", NULL, 0,
4663299c2f1SGregory Neil Shapiro 		ph_map_parseargs, ph_map_open, ph_map_close,
4673299c2f1SGregory Neil Shapiro 		ph_map_lookup, null_map_store);
4683299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
4693299c2f1SGregory Neil Shapiro 
4703299c2f1SGregory Neil Shapiro #if MAP_NSD
4713299c2f1SGregory Neil Shapiro 	/* IRIX 6.5 nsd support */
4723299c2f1SGregory Neil Shapiro 	MAPDEF("nsd", NULL, MCF_ALIASOK,
4733299c2f1SGregory Neil Shapiro 	       map_parseargs, null_map_open, null_map_close,
4743299c2f1SGregory Neil Shapiro 	       nsd_map_lookup, null_map_store);
4753299c2f1SGregory Neil Shapiro #endif /* MAP_NSD */
476c2aa98e2SPeter Wemm 
477c2aa98e2SPeter Wemm #ifdef HESIOD
478c2aa98e2SPeter Wemm 	MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
479c2aa98e2SPeter Wemm 		map_parseargs, hes_map_open, null_map_close,
480c2aa98e2SPeter Wemm 		hes_map_lookup, null_map_store);
4813299c2f1SGregory Neil Shapiro #endif /* HESIOD */
482c2aa98e2SPeter Wemm 
483c2aa98e2SPeter Wemm #if NETINFO
484c2aa98e2SPeter Wemm 	MAPDEF("netinfo", NULL, MCF_ALIASOK,
485c2aa98e2SPeter Wemm 		map_parseargs, ni_map_open, null_map_close,
486c2aa98e2SPeter Wemm 		ni_map_lookup, null_map_store);
4873299c2f1SGregory Neil Shapiro #endif /* NETINFO */
488c2aa98e2SPeter Wemm 
489c2aa98e2SPeter Wemm #if 0
490c2aa98e2SPeter Wemm 	MAPDEF("dns", NULL, 0,
491c2aa98e2SPeter Wemm 		dns_map_init, null_map_open, null_map_close,
492c2aa98e2SPeter Wemm 		dns_map_lookup, null_map_store);
4933299c2f1SGregory Neil Shapiro #endif /* 0 */
494c2aa98e2SPeter Wemm 
495c2aa98e2SPeter Wemm #if NAMED_BIND
496c2aa98e2SPeter Wemm 	/* best MX DNS lookup */
497c2aa98e2SPeter Wemm 	MAPDEF("bestmx", NULL, MCF_OPTFILE,
498c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
499c2aa98e2SPeter Wemm 		bestmx_map_lookup, null_map_store);
5003299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
501c2aa98e2SPeter Wemm 
502c2aa98e2SPeter Wemm 	MAPDEF("host", NULL, 0,
503c2aa98e2SPeter Wemm 		host_map_init, null_map_open, null_map_close,
504c2aa98e2SPeter Wemm 		host_map_lookup, null_map_store);
505c2aa98e2SPeter Wemm 
506c2aa98e2SPeter Wemm 	MAPDEF("text", NULL, MCF_ALIASOK,
507c2aa98e2SPeter Wemm 		map_parseargs, text_map_open, null_map_close,
508c2aa98e2SPeter Wemm 		text_map_lookup, null_map_store);
509c2aa98e2SPeter Wemm 
510c2aa98e2SPeter Wemm 	MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
511c2aa98e2SPeter Wemm 		map_parseargs, stab_map_open, null_map_close,
512c2aa98e2SPeter Wemm 		stab_map_lookup, stab_map_store);
513c2aa98e2SPeter Wemm 
514c2aa98e2SPeter Wemm 	MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
515c2aa98e2SPeter Wemm 		map_parseargs, impl_map_open, impl_map_close,
516c2aa98e2SPeter Wemm 		impl_map_lookup, impl_map_store);
517c2aa98e2SPeter Wemm 
518c2aa98e2SPeter Wemm 	/* access to system passwd file */
519c2aa98e2SPeter Wemm 	MAPDEF("user", NULL, MCF_OPTFILE,
520c2aa98e2SPeter Wemm 		map_parseargs, user_map_open, null_map_close,
521c2aa98e2SPeter Wemm 		user_map_lookup, null_map_store);
522c2aa98e2SPeter Wemm 
523c2aa98e2SPeter Wemm 	/* dequote map */
524c2aa98e2SPeter Wemm 	MAPDEF("dequote", NULL, 0,
525c2aa98e2SPeter Wemm 		dequote_init, null_map_open, null_map_close,
526c2aa98e2SPeter Wemm 		dequote_map, null_map_store);
527c2aa98e2SPeter Wemm 
528c2aa98e2SPeter Wemm #ifdef MAP_REGEX
529c2aa98e2SPeter Wemm 	MAPDEF("regex", NULL, 0,
530c2aa98e2SPeter Wemm 		regex_map_init, null_map_open, null_map_close,
531c2aa98e2SPeter Wemm 		regex_map_lookup, null_map_store);
5323299c2f1SGregory Neil Shapiro #endif /* MAP_REGEX */
533c2aa98e2SPeter Wemm 
534c2aa98e2SPeter Wemm #if USERDB
535c2aa98e2SPeter Wemm 	/* user database */
536c2aa98e2SPeter Wemm 	MAPDEF("userdb", ".db", 0,
537c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
538c2aa98e2SPeter Wemm 		udb_map_lookup, null_map_store);
5393299c2f1SGregory Neil Shapiro #endif /* USERDB */
540c2aa98e2SPeter Wemm 
541c2aa98e2SPeter Wemm 	/* arbitrary programs */
542c2aa98e2SPeter Wemm 	MAPDEF("program", NULL, MCF_ALIASOK,
543c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
544c2aa98e2SPeter Wemm 		prog_map_lookup, null_map_store);
545c2aa98e2SPeter Wemm 
546c2aa98e2SPeter Wemm 	/* sequenced maps */
547c2aa98e2SPeter Wemm 	MAPDEF("sequence", NULL, MCF_ALIASOK,
548c2aa98e2SPeter Wemm 		seq_map_parse, null_map_open, null_map_close,
549c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
550c2aa98e2SPeter Wemm 
551c2aa98e2SPeter Wemm 	/* switched interface to sequenced maps */
552c2aa98e2SPeter Wemm 	MAPDEF("switch", NULL, MCF_ALIASOK,
553c2aa98e2SPeter Wemm 		map_parseargs, switch_map_open, null_map_close,
554c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
555c2aa98e2SPeter Wemm 
556c2aa98e2SPeter Wemm 	/* null map lookup -- really for internal use only */
557c2aa98e2SPeter Wemm 	MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
558c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
559c2aa98e2SPeter Wemm 		null_map_lookup, null_map_store);
560c2aa98e2SPeter Wemm 
561c2aa98e2SPeter Wemm 	/* syslog map -- logs information to syslog */
562c2aa98e2SPeter Wemm 	MAPDEF("syslog", NULL, 0,
563c2aa98e2SPeter Wemm 		syslog_map_parseargs, null_map_open, null_map_close,
564c2aa98e2SPeter Wemm 		syslog_map_lookup, null_map_store);
5653299c2f1SGregory Neil Shapiro 
5663299c2f1SGregory Neil Shapiro 	/* macro storage map -- rulesets can set macros */
5673299c2f1SGregory Neil Shapiro 	MAPDEF("macro", NULL, 0,
5683299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
5693299c2f1SGregory Neil Shapiro 		macro_map_lookup, null_map_store);
5703299c2f1SGregory Neil Shapiro 
5713299c2f1SGregory Neil Shapiro 	/* arithmetic map -- add/subtract/compare */
5723299c2f1SGregory Neil Shapiro 	MAPDEF("arith", NULL, 0,
5733299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
5743299c2f1SGregory Neil Shapiro 		arith_map_lookup, null_map_store);
5753299c2f1SGregory Neil Shapiro 
5763299c2f1SGregory Neil Shapiro 	if (tTd(38, 2))
5773299c2f1SGregory Neil Shapiro 	{
5783299c2f1SGregory Neil Shapiro 		/* bogus map -- always return tempfail */
5793299c2f1SGregory Neil Shapiro 		MAPDEF("bogus",	NULL, MCF_ALIASOK|MCF_OPTFILE,
5803299c2f1SGregory Neil Shapiro 		       map_parseargs, null_map_open, null_map_close,
5813299c2f1SGregory Neil Shapiro 		       bogus_map_lookup, null_map_store);
5823299c2f1SGregory Neil Shapiro 	}
583c2aa98e2SPeter Wemm }
584c2aa98e2SPeter Wemm 
585c2aa98e2SPeter Wemm #undef MAPDEF
586c2aa98e2SPeter Wemm /*
587c2aa98e2SPeter Wemm **  INITHOSTMAPS -- initial host-dependent maps
588c2aa98e2SPeter Wemm **
589c2aa98e2SPeter Wemm **	This should act as an interface to any local service switch
590c2aa98e2SPeter Wemm **	provided by the host operating system.
591c2aa98e2SPeter Wemm **
592c2aa98e2SPeter Wemm **	Parameters:
593c2aa98e2SPeter Wemm **		none
594c2aa98e2SPeter Wemm **
595c2aa98e2SPeter Wemm **	Returns:
596c2aa98e2SPeter Wemm **		none
597c2aa98e2SPeter Wemm **
598c2aa98e2SPeter Wemm **	Side Effects:
599c2aa98e2SPeter Wemm **		Should define maps "host" and "users" as necessary
600c2aa98e2SPeter Wemm **		for this OS.  If they are not defined, they will get
601c2aa98e2SPeter Wemm **		a default value later.  It should check to make sure
602c2aa98e2SPeter Wemm **		they are not defined first, since it's possible that
603c2aa98e2SPeter Wemm **		the config file has provided an override.
604c2aa98e2SPeter Wemm */
605c2aa98e2SPeter Wemm 
606c2aa98e2SPeter Wemm void
607c2aa98e2SPeter Wemm inithostmaps()
608c2aa98e2SPeter Wemm {
609c2aa98e2SPeter Wemm 	register int i;
610c2aa98e2SPeter Wemm 	int nmaps;
611c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
612c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
613c2aa98e2SPeter Wemm 	char buf[MAXLINE];
614c2aa98e2SPeter Wemm 
615c2aa98e2SPeter Wemm 	/*
616c2aa98e2SPeter Wemm 	**  Set up default hosts maps.
617c2aa98e2SPeter Wemm 	*/
618c2aa98e2SPeter Wemm 
619c2aa98e2SPeter Wemm #if 0
620c2aa98e2SPeter Wemm 	nmaps = switch_map_find("hosts", maptype, mapreturn);
621c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
622c2aa98e2SPeter Wemm 	{
623c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
624c2aa98e2SPeter Wemm 		    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
625c2aa98e2SPeter Wemm 		{
6263299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts",
6273299c2f1SGregory Neil Shapiro 				sizeof buf);
628c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
629c2aa98e2SPeter Wemm 		}
630c2aa98e2SPeter Wemm # if NAMED_BIND
631c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "dns") == 0 &&
632c2aa98e2SPeter Wemm 		    stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
633c2aa98e2SPeter Wemm 		{
6343299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "hosts.dns dns A", sizeof buf);
635c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
636c2aa98e2SPeter Wemm 		}
6373299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
638c2aa98e2SPeter Wemm # ifdef NISPLUS
639c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
640c2aa98e2SPeter Wemm 		    stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
641c2aa98e2SPeter Wemm 		{
6423299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir",
6433299c2f1SGregory Neil Shapiro 				sizeof buf);
644c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
645c2aa98e2SPeter Wemm 		}
6463299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
647c2aa98e2SPeter Wemm # ifdef NIS
648c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
649c2aa98e2SPeter Wemm 		    stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
650c2aa98e2SPeter Wemm 		{
6513299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname",
6523299c2f1SGregory Neil Shapiro 				sizeof buf);
653c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
654c2aa98e2SPeter Wemm 		}
6553299c2f1SGregory Neil Shapiro # endif /* NIS */
656c2aa98e2SPeter Wemm # if NETINFO
657c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "netinfo") == 0) &&
658c2aa98e2SPeter Wemm 		    stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
659c2aa98e2SPeter Wemm 		{
6603299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "hosts.netinfo netinfo -v name /machines",
6613299c2f1SGregory Neil Shapiro 				sizeof buf);
662c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
663c2aa98e2SPeter Wemm 		}
6643299c2f1SGregory Neil Shapiro # endif /* NETINFO */
665c2aa98e2SPeter Wemm 	}
6663299c2f1SGregory Neil Shapiro #endif /* 0 */
667c2aa98e2SPeter Wemm 
668c2aa98e2SPeter Wemm 	/*
669c2aa98e2SPeter Wemm 	**  Make sure we have a host map.
670c2aa98e2SPeter Wemm 	*/
671c2aa98e2SPeter Wemm 
672c2aa98e2SPeter Wemm 	if (stab("host", ST_MAP, ST_FIND) == NULL)
673c2aa98e2SPeter Wemm 	{
674c2aa98e2SPeter Wemm 		/* user didn't initialize: set up host map */
6753299c2f1SGregory Neil Shapiro 		(void) strlcpy(buf, "host host", sizeof buf);
676c2aa98e2SPeter Wemm #if NAMED_BIND
677c2aa98e2SPeter Wemm 		if (ConfigLevel >= 2)
6783299c2f1SGregory Neil Shapiro 			(void) strlcat(buf, " -a. -D", sizeof buf);
6793299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
680c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
681c2aa98e2SPeter Wemm 	}
682c2aa98e2SPeter Wemm 
683c2aa98e2SPeter Wemm 	/*
684c2aa98e2SPeter Wemm 	**  Set up default aliases maps
685c2aa98e2SPeter Wemm 	*/
686c2aa98e2SPeter Wemm 
687c2aa98e2SPeter Wemm 	nmaps = switch_map_find("aliases", maptype, mapreturn);
688c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
689c2aa98e2SPeter Wemm 	{
690c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
691c2aa98e2SPeter Wemm 		    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
692c2aa98e2SPeter Wemm 		{
6933299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "aliases.files null", sizeof buf);
694c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
695c2aa98e2SPeter Wemm 		}
696c2aa98e2SPeter Wemm #ifdef NISPLUS
697c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
698c2aa98e2SPeter Wemm 		    stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
699c2aa98e2SPeter Wemm 		{
7003299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
7013299c2f1SGregory Neil Shapiro 				sizeof buf);
702c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
703c2aa98e2SPeter Wemm 		}
7043299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
705c2aa98e2SPeter Wemm #ifdef NIS
706c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
707c2aa98e2SPeter Wemm 		    stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
708c2aa98e2SPeter Wemm 		{
7093299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "aliases.nis nis mail.aliases",
7103299c2f1SGregory Neil Shapiro 				sizeof buf);
711c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
712c2aa98e2SPeter Wemm 		}
7133299c2f1SGregory Neil Shapiro #endif /* NIS */
7143299c2f1SGregory Neil Shapiro #if NETINFO
715c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "netinfo") == 0 &&
716c2aa98e2SPeter Wemm 		    stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
717c2aa98e2SPeter Wemm 		{
7183299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
7193299c2f1SGregory Neil Shapiro 				sizeof buf);
720c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
721c2aa98e2SPeter Wemm 		}
7223299c2f1SGregory Neil Shapiro #endif /* NETINFO */
723c2aa98e2SPeter Wemm #ifdef HESIOD
724c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "hesiod") == 0 &&
725c2aa98e2SPeter Wemm 		    stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
726c2aa98e2SPeter Wemm 		{
7273299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "aliases.hesiod hesiod aliases",
7283299c2f1SGregory Neil Shapiro 				sizeof buf);
729c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
730c2aa98e2SPeter Wemm 		}
7313299c2f1SGregory Neil Shapiro #endif /* HESIOD */
732c2aa98e2SPeter Wemm 	}
733c2aa98e2SPeter Wemm 	if (stab("aliases", ST_MAP, ST_FIND) == NULL)
734c2aa98e2SPeter Wemm 	{
7353299c2f1SGregory Neil Shapiro 		(void) strlcpy(buf, "aliases switch aliases", sizeof buf);
736c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
737c2aa98e2SPeter Wemm 	}
738c2aa98e2SPeter Wemm 
739c2aa98e2SPeter Wemm #if 0		/* "user" map class is a better choice */
740c2aa98e2SPeter Wemm 	/*
741c2aa98e2SPeter Wemm 	**  Set up default users maps.
742c2aa98e2SPeter Wemm 	*/
743c2aa98e2SPeter Wemm 
744c2aa98e2SPeter Wemm 	nmaps = switch_map_find("passwd", maptype, mapreturn);
745c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
746c2aa98e2SPeter Wemm 	{
747c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
748c2aa98e2SPeter Wemm 		    stab("users.files", ST_MAP, ST_FIND) == NULL)
749c2aa98e2SPeter Wemm 		{
7503299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd",
7513299c2f1SGregory Neil Shapiro 				sizeof buf);
752c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
753c2aa98e2SPeter Wemm 		}
754c2aa98e2SPeter Wemm # ifdef NISPLUS
755c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
756c2aa98e2SPeter Wemm 		    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
757c2aa98e2SPeter Wemm 		{
7583299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir",
7593299c2f1SGregory Neil Shapiro 				sizeof buf);
760c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
761c2aa98e2SPeter Wemm 		}
7623299c2f1SGregory Neil Shapiro # endif /* NISPLUS */
763c2aa98e2SPeter Wemm # ifdef NIS
764c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
765c2aa98e2SPeter Wemm 		    stab("users.nis", ST_MAP, ST_FIND) == NULL)
766c2aa98e2SPeter Wemm 		{
7673299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "users.nis nis -m passwd.byname",
7683299c2f1SGregory Neil Shapiro 				sizeof buf);
769c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
770c2aa98e2SPeter Wemm 		}
7713299c2f1SGregory Neil Shapiro # endif /* NIS */
772c2aa98e2SPeter Wemm # ifdef HESIOD
773c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "hesiod") == 0) &&
774c2aa98e2SPeter Wemm 		    stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
775c2aa98e2SPeter Wemm 		{
7763299c2f1SGregory Neil Shapiro 			(void) strlcpy(buf, "users.hesiod hesiod", sizeof buf);
777c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
778c2aa98e2SPeter Wemm 		}
7793299c2f1SGregory Neil Shapiro # endif /* HESIOD */
780c2aa98e2SPeter Wemm 	}
781c2aa98e2SPeter Wemm 	if (stab("users", ST_MAP, ST_FIND) == NULL)
782c2aa98e2SPeter Wemm 	{
7833299c2f1SGregory Neil Shapiro 		(void) strlcpy(buf, "users switch -m passwd", sizeof buf);
784c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
785c2aa98e2SPeter Wemm 	}
7863299c2f1SGregory Neil Shapiro #endif /* 0 */
787c2aa98e2SPeter Wemm }
788c2aa98e2SPeter Wemm /*
789c2aa98e2SPeter Wemm **  SWITCH_MAP_FIND -- find the list of types associated with a map
790c2aa98e2SPeter Wemm **
791c2aa98e2SPeter Wemm **	This is the system-dependent interface to the service switch.
792c2aa98e2SPeter Wemm **
793c2aa98e2SPeter Wemm **	Parameters:
794c2aa98e2SPeter Wemm **		service -- the name of the service of interest.
795c2aa98e2SPeter Wemm **		maptype -- an out-array of strings containing the types
796c2aa98e2SPeter Wemm **			of access to use for this service.  There can
797c2aa98e2SPeter Wemm **			be at most MAXMAPSTACK types for a single service.
798c2aa98e2SPeter Wemm **		mapreturn -- an out-array of return information bitmaps
799c2aa98e2SPeter Wemm **			for the map.
800c2aa98e2SPeter Wemm **
801c2aa98e2SPeter Wemm **	Returns:
802c2aa98e2SPeter Wemm **		The number of map types filled in, or -1 for failure.
8033299c2f1SGregory Neil Shapiro **
8043299c2f1SGregory Neil Shapiro **	Side effects:
8053299c2f1SGregory Neil Shapiro **		Preserves errno so nothing in the routine clobbers it.
806c2aa98e2SPeter Wemm */
807c2aa98e2SPeter Wemm 
808c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
809c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_
8103299c2f1SGregory Neil Shapiro #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
811c2aa98e2SPeter Wemm 
812c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
813c2aa98e2SPeter Wemm # include <nsswitch.h>
8143299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
815c2aa98e2SPeter Wemm 
816c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
817c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_
8183299c2f1SGregory Neil Shapiro #endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
819c2aa98e2SPeter Wemm 
820c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
821c2aa98e2SPeter Wemm # include <sys/svcinfo.h>
8223299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
823c2aa98e2SPeter Wemm 
824c2aa98e2SPeter Wemm int
825c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn)
826c2aa98e2SPeter Wemm 	char *service;
827c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
828c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
829c2aa98e2SPeter Wemm {
830c46d91b7SGregory Neil Shapiro 	int svcno = 0;
8313299c2f1SGregory Neil Shapiro 	int save_errno = errno;
832c2aa98e2SPeter Wemm 
833c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
834c2aa98e2SPeter Wemm 	struct __nsw_switchconfig *nsw_conf;
835c2aa98e2SPeter Wemm 	enum __nsw_parse_err pserr;
836c2aa98e2SPeter Wemm 	struct __nsw_lookup *lk;
837c2aa98e2SPeter Wemm 	static struct __nsw_lookup lkp0 =
838c2aa98e2SPeter Wemm 		{ "files", {1, 0, 0, 0}, NULL, NULL };
839c2aa98e2SPeter Wemm 	static struct __nsw_switchconfig lkp_default =
840c2aa98e2SPeter Wemm 		{ 0, "sendmail", 3, &lkp0 };
841c2aa98e2SPeter Wemm 
842c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
843c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
844c2aa98e2SPeter Wemm 
845c2aa98e2SPeter Wemm 	if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
846c2aa98e2SPeter Wemm 		lk = lkp_default.lookups;
847c2aa98e2SPeter Wemm 	else
848c2aa98e2SPeter Wemm 		lk = nsw_conf->lookups;
849c2aa98e2SPeter Wemm 	svcno = 0;
850c46d91b7SGregory Neil Shapiro 	while (lk != NULL && svcno < MAXMAPSTACK)
851c2aa98e2SPeter Wemm 	{
852c2aa98e2SPeter Wemm 		maptype[svcno] = lk->service_name;
853c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
854c2aa98e2SPeter Wemm 			mapreturn[MA_NOTFOUND] |= 1 << svcno;
855c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
856c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
857c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
858c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
859c2aa98e2SPeter Wemm 		svcno++;
860c2aa98e2SPeter Wemm 		lk = lk->next;
861c2aa98e2SPeter Wemm 	}
8623299c2f1SGregory Neil Shapiro 	errno = save_errno;
863c2aa98e2SPeter Wemm 	return svcno;
8643299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
865c2aa98e2SPeter Wemm 
866c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
867c2aa98e2SPeter Wemm 	struct svcinfo *svcinfo;
868c2aa98e2SPeter Wemm 	int svc;
869c2aa98e2SPeter Wemm 
870c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
871c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
872c2aa98e2SPeter Wemm 
873c2aa98e2SPeter Wemm 	svcinfo = getsvc();
874c2aa98e2SPeter Wemm 	if (svcinfo == NULL)
875c2aa98e2SPeter Wemm 		goto punt;
876c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
877c2aa98e2SPeter Wemm 		svc = SVC_HOSTS;
878c2aa98e2SPeter Wemm 	else if (strcmp(service, "aliases") == 0)
879c2aa98e2SPeter Wemm 		svc = SVC_ALIASES;
880c2aa98e2SPeter Wemm 	else if (strcmp(service, "passwd") == 0)
881c2aa98e2SPeter Wemm 		svc = SVC_PASSWD;
882c2aa98e2SPeter Wemm 	else
8833299c2f1SGregory Neil Shapiro 	{
8843299c2f1SGregory Neil Shapiro 		errno = save_errno;
885c2aa98e2SPeter Wemm 		return -1;
8863299c2f1SGregory Neil Shapiro 	}
887c46d91b7SGregory Neil Shapiro 	for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++)
888c2aa98e2SPeter Wemm 	{
889c2aa98e2SPeter Wemm 		switch (svcinfo->svcpath[svc][svcno])
890c2aa98e2SPeter Wemm 		{
891c2aa98e2SPeter Wemm 		  case SVC_LOCAL:
892c2aa98e2SPeter Wemm 			maptype[svcno] = "files";
893c2aa98e2SPeter Wemm 			break;
894c2aa98e2SPeter Wemm 
895c2aa98e2SPeter Wemm 		  case SVC_YP:
896c2aa98e2SPeter Wemm 			maptype[svcno] = "nis";
897c2aa98e2SPeter Wemm 			break;
898c2aa98e2SPeter Wemm 
899c2aa98e2SPeter Wemm 		  case SVC_BIND:
900c2aa98e2SPeter Wemm 			maptype[svcno] = "dns";
901c2aa98e2SPeter Wemm 			break;
902c2aa98e2SPeter Wemm 
903c2aa98e2SPeter Wemm # ifdef SVC_HESIOD
904c2aa98e2SPeter Wemm 		  case SVC_HESIOD:
905c2aa98e2SPeter Wemm 			maptype[svcno] = "hesiod";
906c2aa98e2SPeter Wemm 			break;
9073299c2f1SGregory Neil Shapiro # endif /* SVC_HESIOD */
908c2aa98e2SPeter Wemm 
909c2aa98e2SPeter Wemm 		  case SVC_LAST:
9103299c2f1SGregory Neil Shapiro 			errno = save_errno;
911c2aa98e2SPeter Wemm 			return svcno;
912c2aa98e2SPeter Wemm 		}
913c2aa98e2SPeter Wemm 	}
9143299c2f1SGregory Neil Shapiro 	errno = save_errno;
915c2aa98e2SPeter Wemm 	return svcno;
9163299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
917c2aa98e2SPeter Wemm 
918c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
919c2aa98e2SPeter Wemm 	/*
920c2aa98e2SPeter Wemm 	**  Fall-back mechanism.
921c2aa98e2SPeter Wemm 	*/
922c2aa98e2SPeter Wemm 
923c2aa98e2SPeter Wemm 	STAB *st;
924c2aa98e2SPeter Wemm 	time_t now = curtime();
925c2aa98e2SPeter Wemm 
926c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
927c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
928c2aa98e2SPeter Wemm 
929c2aa98e2SPeter Wemm 	if ((now - ServiceCacheTime) > (time_t) ServiceCacheMaxAge)
930c2aa98e2SPeter Wemm 	{
931c2aa98e2SPeter Wemm 		/* (re)read service switch */
932c2aa98e2SPeter Wemm 		register FILE *fp;
9333299c2f1SGregory Neil Shapiro 		long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
934c2aa98e2SPeter Wemm 
9353299c2f1SGregory Neil Shapiro 		if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
9363299c2f1SGregory Neil Shapiro 			    DontBlameSendmail))
937c2aa98e2SPeter Wemm 			sff |= SFF_NOWLINK;
938c2aa98e2SPeter Wemm 
939c2aa98e2SPeter Wemm 		if (ConfigFileRead)
940c2aa98e2SPeter Wemm 			ServiceCacheTime = now;
941c2aa98e2SPeter Wemm 		fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
942c2aa98e2SPeter Wemm 		if (fp != NULL)
943c2aa98e2SPeter Wemm 		{
944c2aa98e2SPeter Wemm 			char buf[MAXLINE];
945c2aa98e2SPeter Wemm 
946c2aa98e2SPeter Wemm 			while (fgets(buf, sizeof buf, fp) != NULL)
947c2aa98e2SPeter Wemm 			{
948c2aa98e2SPeter Wemm 				register char *p;
949c2aa98e2SPeter Wemm 
950c2aa98e2SPeter Wemm 				p = strpbrk(buf, "#\n");
951c2aa98e2SPeter Wemm 				if (p != NULL)
952c2aa98e2SPeter Wemm 					*p = '\0';
953c2aa98e2SPeter Wemm 				p = strpbrk(buf, " \t");
954c2aa98e2SPeter Wemm 				if (p != NULL)
955c2aa98e2SPeter Wemm 					*p++ = '\0';
956c2aa98e2SPeter Wemm 				if (buf[0] == '\0')
957c2aa98e2SPeter Wemm 					continue;
95876b7bf71SPeter Wemm 				if (p == NULL)
95976b7bf71SPeter Wemm 				{
96076b7bf71SPeter Wemm 					sm_syslog(LOG_ERR, NOQID,
96176b7bf71SPeter Wemm 						  "Bad line on %.100s: %.100s",
96276b7bf71SPeter Wemm 						  ServiceSwitchFile,
96376b7bf71SPeter Wemm 						  buf);
96476b7bf71SPeter Wemm 					continue;
96576b7bf71SPeter Wemm 				}
966c2aa98e2SPeter Wemm 				while (isspace(*p))
967c2aa98e2SPeter Wemm 					p++;
968c2aa98e2SPeter Wemm 				if (*p == '\0')
969c2aa98e2SPeter Wemm 					continue;
970c2aa98e2SPeter Wemm 
971c2aa98e2SPeter Wemm 				/*
972c2aa98e2SPeter Wemm 				**  Find/allocate space for this service entry.
973c2aa98e2SPeter Wemm 				**	Space for all of the service strings
974c2aa98e2SPeter Wemm 				**	are allocated at once.  This means
975c2aa98e2SPeter Wemm 				**	that we only have to free the first
976c2aa98e2SPeter Wemm 				**	one to free all of them.
977c2aa98e2SPeter Wemm 				*/
978c2aa98e2SPeter Wemm 
979c2aa98e2SPeter Wemm 				st = stab(buf, ST_SERVICE, ST_ENTER);
980c2aa98e2SPeter Wemm 				if (st->s_service[0] != NULL)
981c0c4794dSGregory Neil Shapiro 					sm_free((void *) st->s_service[0]);
982c2aa98e2SPeter Wemm 				p = newstr(p);
983c2aa98e2SPeter Wemm 				for (svcno = 0; svcno < MAXMAPSTACK; )
984c2aa98e2SPeter Wemm 				{
985c2aa98e2SPeter Wemm 					if (*p == '\0')
986c2aa98e2SPeter Wemm 						break;
987c2aa98e2SPeter Wemm 					st->s_service[svcno++] = p;
988c2aa98e2SPeter Wemm 					p = strpbrk(p, " \t");
989c2aa98e2SPeter Wemm 					if (p == NULL)
990c2aa98e2SPeter Wemm 						break;
991c2aa98e2SPeter Wemm 					*p++ = '\0';
992c2aa98e2SPeter Wemm 					while (isspace(*p))
993c2aa98e2SPeter Wemm 						p++;
994c2aa98e2SPeter Wemm 				}
995c2aa98e2SPeter Wemm 				if (svcno < MAXMAPSTACK)
996c2aa98e2SPeter Wemm 					st->s_service[svcno] = NULL;
997c2aa98e2SPeter Wemm 			}
9983299c2f1SGregory Neil Shapiro 			(void) fclose(fp);
999c2aa98e2SPeter Wemm 		}
1000c2aa98e2SPeter Wemm 	}
1001c2aa98e2SPeter Wemm 
1002c2aa98e2SPeter Wemm 	/* look up entry in cache */
1003c2aa98e2SPeter Wemm 	st = stab(service, ST_SERVICE, ST_FIND);
1004c2aa98e2SPeter Wemm 	if (st != NULL && st->s_service[0] != NULL)
1005c2aa98e2SPeter Wemm 	{
1006c2aa98e2SPeter Wemm 		/* extract data */
1007c2aa98e2SPeter Wemm 		svcno = 0;
1008c2aa98e2SPeter Wemm 		while (svcno < MAXMAPSTACK)
1009c2aa98e2SPeter Wemm 		{
1010c2aa98e2SPeter Wemm 			maptype[svcno] = st->s_service[svcno];
1011c2aa98e2SPeter Wemm 			if (maptype[svcno++] == NULL)
1012c2aa98e2SPeter Wemm 				break;
1013c2aa98e2SPeter Wemm 		}
10143299c2f1SGregory Neil Shapiro 		errno = save_errno;
1015c2aa98e2SPeter Wemm 		return --svcno;
1016c2aa98e2SPeter Wemm 	}
10173299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
1018c2aa98e2SPeter Wemm 
1019c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_)
1020c2aa98e2SPeter Wemm 	/* if the service file doesn't work, use an absolute fallback */
1021c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_
1022c2aa98e2SPeter Wemm   punt:
10233299c2f1SGregory Neil Shapiro # endif /* _USE_DEC_SVC_CONF_ */
1024c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1025c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1026c2aa98e2SPeter Wemm 	svcno = 0;
1027c2aa98e2SPeter Wemm 	if (strcmp(service, "aliases") == 0)
1028c2aa98e2SPeter Wemm 	{
1029c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
10303299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
10313299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
10323299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
1033c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES
1034c2aa98e2SPeter Wemm #  ifdef NISPLUS
1035c2aa98e2SPeter Wemm 		maptype[svcno++] = "nisplus";
10363299c2f1SGregory Neil Shapiro #  endif /* NISPLUS */
1037c2aa98e2SPeter Wemm #  ifdef NIS
1038c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
10393299c2f1SGregory Neil Shapiro #  endif /* NIS */
10403299c2f1SGregory Neil Shapiro # endif /* AUTO_NIS_ALIASES */
10413299c2f1SGregory Neil Shapiro 		errno = save_errno;
1042c2aa98e2SPeter Wemm 		return svcno;
1043c2aa98e2SPeter Wemm 	}
1044c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
1045c2aa98e2SPeter Wemm 	{
1046c2aa98e2SPeter Wemm # if NAMED_BIND
1047c2aa98e2SPeter Wemm 		maptype[svcno++] = "dns";
10483299c2f1SGregory Neil Shapiro # else /* NAMED_BIND */
1049c2aa98e2SPeter Wemm #  if defined(sun) && !defined(BSD)
1050c2aa98e2SPeter Wemm 		/* SunOS */
1051c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
10523299c2f1SGregory Neil Shapiro #  endif /* defined(sun) && !defined(BSD) */
10533299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
10543299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
10553299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
10563299c2f1SGregory Neil Shapiro # endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */
1057c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
10583299c2f1SGregory Neil Shapiro 		errno = save_errno;
1059c2aa98e2SPeter Wemm 		return svcno;
1060c2aa98e2SPeter Wemm 	}
10613299c2f1SGregory Neil Shapiro 	errno = save_errno;
1062c2aa98e2SPeter Wemm 	return -1;
10633299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) */
1064c2aa98e2SPeter Wemm }
1065c2aa98e2SPeter Wemm /*
1066c2aa98e2SPeter Wemm **  USERNAME -- return the user id of the logged in user.
1067c2aa98e2SPeter Wemm **
1068c2aa98e2SPeter Wemm **	Parameters:
1069c2aa98e2SPeter Wemm **		none.
1070c2aa98e2SPeter Wemm **
1071c2aa98e2SPeter Wemm **	Returns:
1072c2aa98e2SPeter Wemm **		The login name of the logged in user.
1073c2aa98e2SPeter Wemm **
1074c2aa98e2SPeter Wemm **	Side Effects:
1075c2aa98e2SPeter Wemm **		none.
1076c2aa98e2SPeter Wemm **
1077c2aa98e2SPeter Wemm **	Notes:
1078c2aa98e2SPeter Wemm **		The return value is statically allocated.
1079c2aa98e2SPeter Wemm */
1080c2aa98e2SPeter Wemm 
1081c2aa98e2SPeter Wemm char *
1082c2aa98e2SPeter Wemm username()
1083c2aa98e2SPeter Wemm {
1084c2aa98e2SPeter Wemm 	static char *myname = NULL;
1085c2aa98e2SPeter Wemm 	extern char *getlogin();
1086c2aa98e2SPeter Wemm 	register struct passwd *pw;
1087c2aa98e2SPeter Wemm 
1088c2aa98e2SPeter Wemm 	/* cache the result */
1089c2aa98e2SPeter Wemm 	if (myname == NULL)
1090c2aa98e2SPeter Wemm 	{
1091c2aa98e2SPeter Wemm 		myname = getlogin();
1092c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1093c2aa98e2SPeter Wemm 		{
1094c2aa98e2SPeter Wemm 			pw = sm_getpwuid(RealUid);
1095c2aa98e2SPeter Wemm 			if (pw != NULL)
1096c2aa98e2SPeter Wemm 				myname = newstr(pw->pw_name);
1097c2aa98e2SPeter Wemm 		}
1098c2aa98e2SPeter Wemm 		else
1099c2aa98e2SPeter Wemm 		{
1100c2aa98e2SPeter Wemm 			uid_t uid = RealUid;
1101c2aa98e2SPeter Wemm 
1102c2aa98e2SPeter Wemm 			myname = newstr(myname);
1103c2aa98e2SPeter Wemm 			if ((pw = sm_getpwnam(myname)) == NULL ||
1104c2aa98e2SPeter Wemm 			      (uid != 0 && uid != pw->pw_uid))
1105c2aa98e2SPeter Wemm 			{
1106c2aa98e2SPeter Wemm 				pw = sm_getpwuid(uid);
1107c2aa98e2SPeter Wemm 				if (pw != NULL)
1108c2aa98e2SPeter Wemm 					myname = newstr(pw->pw_name);
1109c2aa98e2SPeter Wemm 			}
1110c2aa98e2SPeter Wemm 		}
1111c2aa98e2SPeter Wemm 		if (myname == NULL || myname[0] == '\0')
1112c2aa98e2SPeter Wemm 		{
11133299c2f1SGregory Neil Shapiro 			syserr("554 5.3.0 Who are you?");
1114c2aa98e2SPeter Wemm 			myname = "postmaster";
1115c2aa98e2SPeter Wemm 		}
1116c2aa98e2SPeter Wemm 	}
1117c2aa98e2SPeter Wemm 
11183299c2f1SGregory Neil Shapiro 	return myname;
1119c2aa98e2SPeter Wemm }
1120c2aa98e2SPeter Wemm /*
1121c2aa98e2SPeter Wemm **  TTYPATH -- Get the path of the user's tty
1122c2aa98e2SPeter Wemm **
1123c2aa98e2SPeter Wemm **	Returns the pathname of the user's tty.  Returns NULL if
1124c2aa98e2SPeter Wemm **	the user is not logged in or if s/he has write permission
1125c2aa98e2SPeter Wemm **	denied.
1126c2aa98e2SPeter Wemm **
1127c2aa98e2SPeter Wemm **	Parameters:
1128c2aa98e2SPeter Wemm **		none
1129c2aa98e2SPeter Wemm **
1130c2aa98e2SPeter Wemm **	Returns:
1131c2aa98e2SPeter Wemm **		pathname of the user's tty.
1132c2aa98e2SPeter Wemm **		NULL if not logged in or write permission denied.
1133c2aa98e2SPeter Wemm **
1134c2aa98e2SPeter Wemm **	Side Effects:
1135c2aa98e2SPeter Wemm **		none.
1136c2aa98e2SPeter Wemm **
1137c2aa98e2SPeter Wemm **	WARNING:
1138c2aa98e2SPeter Wemm **		Return value is in a local buffer.
1139c2aa98e2SPeter Wemm **
1140c2aa98e2SPeter Wemm **	Called By:
1141c2aa98e2SPeter Wemm **		savemail
1142c2aa98e2SPeter Wemm */
1143c2aa98e2SPeter Wemm 
1144c2aa98e2SPeter Wemm char *
1145c2aa98e2SPeter Wemm ttypath()
1146c2aa98e2SPeter Wemm {
1147c2aa98e2SPeter Wemm 	struct stat stbuf;
1148c2aa98e2SPeter Wemm 	register char *pathn;
1149c2aa98e2SPeter Wemm 	extern char *ttyname();
1150c2aa98e2SPeter Wemm 	extern char *getlogin();
1151c2aa98e2SPeter Wemm 
1152c2aa98e2SPeter Wemm 	/* compute the pathname of the controlling tty */
1153c2aa98e2SPeter Wemm 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
1154c2aa98e2SPeter Wemm 	    (pathn = ttyname(0)) == NULL)
1155c2aa98e2SPeter Wemm 	{
1156c2aa98e2SPeter Wemm 		errno = 0;
11573299c2f1SGregory Neil Shapiro 		return NULL;
1158c2aa98e2SPeter Wemm 	}
1159c2aa98e2SPeter Wemm 
1160c2aa98e2SPeter Wemm 	/* see if we have write permission */
1161c2aa98e2SPeter Wemm 	if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode))
1162c2aa98e2SPeter Wemm 	{
1163c2aa98e2SPeter Wemm 		errno = 0;
11643299c2f1SGregory Neil Shapiro 		return NULL;
1165c2aa98e2SPeter Wemm 	}
1166c2aa98e2SPeter Wemm 
1167c2aa98e2SPeter Wemm 	/* see if the user is logged in */
1168c2aa98e2SPeter Wemm 	if (getlogin() == NULL)
11693299c2f1SGregory Neil Shapiro 		return NULL;
1170c2aa98e2SPeter Wemm 
1171c2aa98e2SPeter Wemm 	/* looks good */
11723299c2f1SGregory Neil Shapiro 	return pathn;
1173c2aa98e2SPeter Wemm }
1174c2aa98e2SPeter Wemm /*
1175c2aa98e2SPeter Wemm **  CHECKCOMPAT -- check for From and To person compatible.
1176c2aa98e2SPeter Wemm **
1177c2aa98e2SPeter Wemm **	This routine can be supplied on a per-installation basis
1178c2aa98e2SPeter Wemm **	to determine whether a person is allowed to send a message.
1179c2aa98e2SPeter Wemm **	This allows restriction of certain types of internet
1180c2aa98e2SPeter Wemm **	forwarding or registration of users.
1181c2aa98e2SPeter Wemm **
1182c2aa98e2SPeter Wemm **	If the hosts are found to be incompatible, an error
1183c2aa98e2SPeter Wemm **	message should be given using "usrerr" and an EX_ code
1184c2aa98e2SPeter Wemm **	should be returned.  You can also set to->q_status to
1185c2aa98e2SPeter Wemm **	a DSN-style status code.
1186c2aa98e2SPeter Wemm **
1187c2aa98e2SPeter Wemm **	EF_NO_BODY_RETN can be set in e->e_flags to suppress the
1188c2aa98e2SPeter Wemm **	body during the return-to-sender function; this should be done
1189c2aa98e2SPeter Wemm **	on huge messages.  This bit may already be set by the ESMTP
1190c2aa98e2SPeter Wemm **	protocol.
1191c2aa98e2SPeter Wemm **
1192c2aa98e2SPeter Wemm **	Parameters:
1193c2aa98e2SPeter Wemm **		to -- the person being sent to.
1194c2aa98e2SPeter Wemm **
1195c2aa98e2SPeter Wemm **	Returns:
1196c2aa98e2SPeter Wemm **		an exit status
1197c2aa98e2SPeter Wemm **
1198c2aa98e2SPeter Wemm **	Side Effects:
1199c2aa98e2SPeter Wemm **		none (unless you include the usrerr stuff)
1200c2aa98e2SPeter Wemm */
1201c2aa98e2SPeter Wemm 
1202c2aa98e2SPeter Wemm int
1203c2aa98e2SPeter Wemm checkcompat(to, e)
1204c2aa98e2SPeter Wemm 	register ADDRESS *to;
1205c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1206c2aa98e2SPeter Wemm {
1207c2aa98e2SPeter Wemm 	if (tTd(49, 1))
12083299c2f1SGregory Neil Shapiro 		dprintf("checkcompat(to=%s, from=%s)\n",
1209c2aa98e2SPeter Wemm 			to->q_paddr, e->e_from.q_paddr);
1210c2aa98e2SPeter Wemm 
1211c2aa98e2SPeter Wemm #ifdef EXAMPLE_CODE
1212c2aa98e2SPeter Wemm 	/* this code is intended as an example only */
1213c2aa98e2SPeter Wemm 	register STAB *s;
1214c2aa98e2SPeter Wemm 
1215c2aa98e2SPeter Wemm 	s = stab("arpa", ST_MAILER, ST_FIND);
1216c2aa98e2SPeter Wemm 	if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
1217c2aa98e2SPeter Wemm 	    to->q_mailer == s->s_mailer)
1218c2aa98e2SPeter Wemm 	{
1219c2aa98e2SPeter Wemm 		usrerr("553 No ARPA mail through this machine: see your system administration");
12203299c2f1SGregory Neil Shapiro 		/* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */
1221c2aa98e2SPeter Wemm 		to->q_status = "5.7.1";
12223299c2f1SGregory Neil Shapiro 		return EX_UNAVAILABLE;
1223c2aa98e2SPeter Wemm 	}
1224c2aa98e2SPeter Wemm #endif /* EXAMPLE_CODE */
12253299c2f1SGregory Neil Shapiro 	return EX_OK;
1226c2aa98e2SPeter Wemm }
1227c2aa98e2SPeter Wemm /*
1228c2aa98e2SPeter Wemm **  SETSIGNAL -- set a signal handler
1229c2aa98e2SPeter Wemm **
1230c2aa98e2SPeter Wemm **	This is essentially old BSD "signal(3)".
1231c0c4794dSGregory Neil Shapiro **
1232c0c4794dSGregory Neil Shapiro **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
1233c0c4794dSGregory Neil Shapiro **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
1234c0c4794dSGregory Neil Shapiro **		DOING.
1235c2aa98e2SPeter Wemm */
1236c2aa98e2SPeter Wemm 
1237c2aa98e2SPeter Wemm sigfunc_t
1238c2aa98e2SPeter Wemm setsignal(sig, handler)
1239c2aa98e2SPeter Wemm 	int sig;
1240c2aa98e2SPeter Wemm 	sigfunc_t handler;
1241c2aa98e2SPeter Wemm {
1242c0c4794dSGregory Neil Shapiro # if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3))
1243c0c4794dSGregory Neil Shapiro 	struct sigaction n, o;
1244c0c4794dSGregory Neil Shapiro # endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */
1245c0c4794dSGregory Neil Shapiro 
12463299c2f1SGregory Neil Shapiro 	/*
12473299c2f1SGregory Neil Shapiro 	**  First, try for modern signal calls
12483299c2f1SGregory Neil Shapiro 	**  and restartable syscalls
12493299c2f1SGregory Neil Shapiro 	*/
12503299c2f1SGregory Neil Shapiro 
12513299c2f1SGregory Neil Shapiro # ifdef SA_RESTART
12523299c2f1SGregory Neil Shapiro 	memset(&n, '\0', sizeof n);
1253c2aa98e2SPeter Wemm #  if USE_SA_SIGACTION
1254c2aa98e2SPeter Wemm 	n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler;
1255c2aa98e2SPeter Wemm 	n.sa_flags = SA_RESTART|SA_SIGINFO;
12563299c2f1SGregory Neil Shapiro #  else /* USE_SA_SIGACTION */
1257c2aa98e2SPeter Wemm 	n.sa_handler = handler;
1258c2aa98e2SPeter Wemm 	n.sa_flags = SA_RESTART;
12593299c2f1SGregory Neil Shapiro #  endif /* USE_SA_SIGACTION */
1260c2aa98e2SPeter Wemm 	if (sigaction(sig, &n, &o) < 0)
1261c2aa98e2SPeter Wemm 		return SIG_ERR;
1262c2aa98e2SPeter Wemm 	return o.sa_handler;
12633299c2f1SGregory Neil Shapiro # else /* SA_RESTART */
12643299c2f1SGregory Neil Shapiro 
12653299c2f1SGregory Neil Shapiro 	/*
12663299c2f1SGregory Neil Shapiro 	**  Else check for SYS5SIGNALS or
12673299c2f1SGregory Neil Shapiro 	**  BSD4_3 signals
12683299c2f1SGregory Neil Shapiro 	*/
12693299c2f1SGregory Neil Shapiro 
12703299c2f1SGregory Neil Shapiro #  if defined(SYS5SIGNALS) || defined(BSD4_3)
12713299c2f1SGregory Neil Shapiro #   ifdef BSD4_3
12723299c2f1SGregory Neil Shapiro 	return signal(sig, handler);
12733299c2f1SGregory Neil Shapiro #   else /* BSD4_3 */
12743299c2f1SGregory Neil Shapiro 	return sigset(sig, handler);
12753299c2f1SGregory Neil Shapiro #   endif /* BSD4_3 */
12763299c2f1SGregory Neil Shapiro #  else /* defined(SYS5SIGNALS) || defined(BSD4_3) */
12773299c2f1SGregory Neil Shapiro 
12783299c2f1SGregory Neil Shapiro 	/*
12793299c2f1SGregory Neil Shapiro 	**  Finally, if nothing else is available,
12803299c2f1SGregory Neil Shapiro 	**  go for a default
12813299c2f1SGregory Neil Shapiro 	*/
12823299c2f1SGregory Neil Shapiro 
12833299c2f1SGregory Neil Shapiro 	memset(&n, '\0', sizeof n);
12843299c2f1SGregory Neil Shapiro 	n.sa_handler = handler;
12853299c2f1SGregory Neil Shapiro 	if (sigaction(sig, &n, &o) < 0)
12863299c2f1SGregory Neil Shapiro 		return SIG_ERR;
12873299c2f1SGregory Neil Shapiro 	return o.sa_handler;
12883299c2f1SGregory Neil Shapiro #  endif /* defined(SYS5SIGNALS) || defined(BSD4_3) */
12893299c2f1SGregory Neil Shapiro # endif /* SA_RESTART */
1290c2aa98e2SPeter Wemm }
1291c2aa98e2SPeter Wemm /*
1292c0c4794dSGregory Neil Shapiro **  ALLSIGNALS -- act on all signals
1293c0c4794dSGregory Neil Shapiro **
1294c0c4794dSGregory Neil Shapiro **	Parameters:
1295c0c4794dSGregory Neil Shapiro **		block -- whether to block or release all signals.
1296c0c4794dSGregory Neil Shapiro **
1297c0c4794dSGregory Neil Shapiro **	Returns:
1298c0c4794dSGregory Neil Shapiro **		none.
1299c0c4794dSGregory Neil Shapiro */
1300c0c4794dSGregory Neil Shapiro 
1301c0c4794dSGregory Neil Shapiro void
1302c0c4794dSGregory Neil Shapiro allsignals(block)
1303c0c4794dSGregory Neil Shapiro 	bool block;
1304c0c4794dSGregory Neil Shapiro {
1305c0c4794dSGregory Neil Shapiro # ifdef BSD4_3
1306c0c4794dSGregory Neil Shapiro #  ifndef sigmask
1307c0c4794dSGregory Neil Shapiro #   define sigmask(s)	(1 << ((s) - 1))
1308c0c4794dSGregory Neil Shapiro #  endif /* ! sigmask */
1309c0c4794dSGregory Neil Shapiro 	if (block)
1310c0c4794dSGregory Neil Shapiro 	{
1311c0c4794dSGregory Neil Shapiro 		int mask = 0;
1312c0c4794dSGregory Neil Shapiro 
1313c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGALRM);
1314c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGCHLD);
1315c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGHUP);
1316c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGINT);
1317c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGTERM);
1318c0c4794dSGregory Neil Shapiro 		mask |= sigmask(SIGUSR1);
1319c0c4794dSGregory Neil Shapiro 
1320c0c4794dSGregory Neil Shapiro 		(void) sigblock(mask);
1321c0c4794dSGregory Neil Shapiro 	}
1322c0c4794dSGregory Neil Shapiro 	else
1323c0c4794dSGregory Neil Shapiro 		sigsetmask(0);
1324c0c4794dSGregory Neil Shapiro # else /* BSD4_3 */
1325c0c4794dSGregory Neil Shapiro #  ifdef ALTOS_SYSTEM_V
1326c0c4794dSGregory Neil Shapiro 	if (block)
1327c0c4794dSGregory Neil Shapiro 	{
1328c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGALRM, SIG_HOLD);
1329c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGCHLD, SIG_HOLD);
1330c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGHUP, SIG_HOLD);
1331c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGINT, SIG_HOLD);
1332c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGTERM, SIG_HOLD);
1333c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGUSR1, SIG_HOLD);
1334c0c4794dSGregory Neil Shapiro 	}
1335c0c4794dSGregory Neil Shapiro 	else
1336c0c4794dSGregory Neil Shapiro 	{
1337c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGALRM, SIG_DFL);
1338c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGCHLD, SIG_DFL);
1339c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGHUP, SIG_DFL);
1340c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGINT, SIG_DFL);
1341c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGTERM, SIG_DFL);
1342c0c4794dSGregory Neil Shapiro 		(void) sigset(SIGUSR1, SIG_DFL);
1343c0c4794dSGregory Neil Shapiro 	}
1344c0c4794dSGregory Neil Shapiro #  else /* ALTOS_SYSTEM_V */
1345c0c4794dSGregory Neil Shapiro 	sigset_t sset;
1346c0c4794dSGregory Neil Shapiro 
1347c0c4794dSGregory Neil Shapiro 	(void) sigemptyset(&sset);
1348c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGALRM);
1349c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGCHLD);
1350c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGHUP);
1351c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGINT);
1352c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGTERM);
1353c0c4794dSGregory Neil Shapiro 	(void) sigaddset(&sset, SIGUSR1);
1354c0c4794dSGregory Neil Shapiro 	(void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
1355c0c4794dSGregory Neil Shapiro #  endif /* ALTOS_SYSTEM_V */
1356c0c4794dSGregory Neil Shapiro # endif /* BSD4_3 */
1357c0c4794dSGregory Neil Shapiro }
1358c0c4794dSGregory Neil Shapiro /*
1359c2aa98e2SPeter Wemm **  BLOCKSIGNAL -- hold a signal to prevent delivery
1360c2aa98e2SPeter Wemm **
1361c2aa98e2SPeter Wemm **	Parameters:
1362c2aa98e2SPeter Wemm **		sig -- the signal to block.
1363c2aa98e2SPeter Wemm **
1364c2aa98e2SPeter Wemm **	Returns:
1365c2aa98e2SPeter Wemm **		1 signal was previously blocked
1366c2aa98e2SPeter Wemm **		0 signal was not previously blocked
1367c2aa98e2SPeter Wemm **		-1 on failure.
1368c2aa98e2SPeter Wemm */
1369c2aa98e2SPeter Wemm 
1370c2aa98e2SPeter Wemm int
1371c2aa98e2SPeter Wemm blocksignal(sig)
1372c2aa98e2SPeter Wemm 	int sig;
1373c2aa98e2SPeter Wemm {
1374c2aa98e2SPeter Wemm # ifdef BSD4_3
1375c2aa98e2SPeter Wemm #  ifndef sigmask
1376c2aa98e2SPeter Wemm #   define sigmask(s)	(1 << ((s) - 1))
13773299c2f1SGregory Neil Shapiro #  endif /* ! sigmask */
1378c2aa98e2SPeter Wemm 	return (sigblock(sigmask(sig)) & sigmask(sig)) != 0;
13793299c2f1SGregory Neil Shapiro # else /* BSD4_3 */
1380c2aa98e2SPeter Wemm #  ifdef ALTOS_SYSTEM_V
1381c2aa98e2SPeter Wemm 	sigfunc_t handler;
1382c2aa98e2SPeter Wemm 
1383c2aa98e2SPeter Wemm 	handler = sigset(sig, SIG_HOLD);
1384c2aa98e2SPeter Wemm 	if (handler == SIG_ERR)
1385c2aa98e2SPeter Wemm 		return -1;
1386c2aa98e2SPeter Wemm 	else
1387c2aa98e2SPeter Wemm 		return handler == SIG_HOLD;
13883299c2f1SGregory Neil Shapiro #  else /* ALTOS_SYSTEM_V */
1389c2aa98e2SPeter Wemm 	sigset_t sset, oset;
1390c2aa98e2SPeter Wemm 
13913299c2f1SGregory Neil Shapiro 	(void) sigemptyset(&sset);
13923299c2f1SGregory Neil Shapiro 	(void) sigaddset(&sset, sig);
1393c2aa98e2SPeter Wemm 	if (sigprocmask(SIG_BLOCK, &sset, &oset) < 0)
1394c2aa98e2SPeter Wemm 		return -1;
1395c2aa98e2SPeter Wemm 	else
1396c2aa98e2SPeter Wemm 		return sigismember(&oset, sig);
13973299c2f1SGregory Neil Shapiro #  endif /* ALTOS_SYSTEM_V */
13983299c2f1SGregory Neil Shapiro # endif /* BSD4_3 */
1399c2aa98e2SPeter Wemm }
1400c2aa98e2SPeter Wemm /*
1401c2aa98e2SPeter Wemm **  RELEASESIGNAL -- release a held signal
1402c2aa98e2SPeter Wemm **
1403c2aa98e2SPeter Wemm **	Parameters:
1404c2aa98e2SPeter Wemm **		sig -- the signal to release.
1405c2aa98e2SPeter Wemm **
1406c2aa98e2SPeter Wemm **	Returns:
1407c2aa98e2SPeter Wemm **		1 signal was previously blocked
1408c2aa98e2SPeter Wemm **		0 signal was not previously blocked
1409c2aa98e2SPeter Wemm **		-1 on failure.
1410c2aa98e2SPeter Wemm */
1411c2aa98e2SPeter Wemm 
1412c2aa98e2SPeter Wemm int
1413c2aa98e2SPeter Wemm releasesignal(sig)
1414c2aa98e2SPeter Wemm 	int sig;
1415c2aa98e2SPeter Wemm {
1416c2aa98e2SPeter Wemm # ifdef BSD4_3
1417c2aa98e2SPeter Wemm 	return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0;
14183299c2f1SGregory Neil Shapiro # else /* BSD4_3 */
1419c2aa98e2SPeter Wemm #  ifdef ALTOS_SYSTEM_V
1420c2aa98e2SPeter Wemm 	sigfunc_t handler;
1421c2aa98e2SPeter Wemm 
1422c2aa98e2SPeter Wemm 	handler = sigset(sig, SIG_HOLD);
1423c2aa98e2SPeter Wemm 	if (sigrelse(sig) < 0)
1424c2aa98e2SPeter Wemm 		return -1;
1425c2aa98e2SPeter Wemm 	else
1426c2aa98e2SPeter Wemm 		return handler == SIG_HOLD;
14273299c2f1SGregory Neil Shapiro #  else /* ALTOS_SYSTEM_V */
1428c2aa98e2SPeter Wemm 	sigset_t sset, oset;
1429c2aa98e2SPeter Wemm 
14303299c2f1SGregory Neil Shapiro 	(void) sigemptyset(&sset);
14313299c2f1SGregory Neil Shapiro 	(void) sigaddset(&sset, sig);
1432c2aa98e2SPeter Wemm 	if (sigprocmask(SIG_UNBLOCK, &sset, &oset) < 0)
1433c2aa98e2SPeter Wemm 		return -1;
1434c2aa98e2SPeter Wemm 	else
1435c2aa98e2SPeter Wemm 		return sigismember(&oset, sig);
14363299c2f1SGregory Neil Shapiro #  endif /* ALTOS_SYSTEM_V */
14373299c2f1SGregory Neil Shapiro # endif /* BSD4_3 */
1438c2aa98e2SPeter Wemm }
1439c2aa98e2SPeter Wemm /*
1440c2aa98e2SPeter Wemm **  HOLDSIGS -- arrange to hold all signals
1441c2aa98e2SPeter Wemm **
1442c2aa98e2SPeter Wemm **	Parameters:
1443c2aa98e2SPeter Wemm **		none.
1444c2aa98e2SPeter Wemm **
1445c2aa98e2SPeter Wemm **	Returns:
1446c2aa98e2SPeter Wemm **		none.
1447c2aa98e2SPeter Wemm **
1448c2aa98e2SPeter Wemm **	Side Effects:
1449c2aa98e2SPeter Wemm **		Arranges that signals are held.
1450c2aa98e2SPeter Wemm */
1451c2aa98e2SPeter Wemm 
1452c2aa98e2SPeter Wemm void
1453c2aa98e2SPeter Wemm holdsigs()
1454c2aa98e2SPeter Wemm {
1455c2aa98e2SPeter Wemm }
1456c2aa98e2SPeter Wemm /*
1457c2aa98e2SPeter Wemm **  RLSESIGS -- arrange to release all signals
1458c2aa98e2SPeter Wemm **
1459c2aa98e2SPeter Wemm **	This undoes the effect of holdsigs.
1460c2aa98e2SPeter Wemm **
1461c2aa98e2SPeter Wemm **	Parameters:
1462c2aa98e2SPeter Wemm **		none.
1463c2aa98e2SPeter Wemm **
1464c2aa98e2SPeter Wemm **	Returns:
1465c2aa98e2SPeter Wemm **		none.
1466c2aa98e2SPeter Wemm **
1467c2aa98e2SPeter Wemm **	Side Effects:
1468c2aa98e2SPeter Wemm **		Arranges that signals are released.
1469c2aa98e2SPeter Wemm */
1470c2aa98e2SPeter Wemm 
1471c2aa98e2SPeter Wemm void
1472c2aa98e2SPeter Wemm rlsesigs()
1473c2aa98e2SPeter Wemm {
1474c2aa98e2SPeter Wemm }
1475c2aa98e2SPeter Wemm /*
1476c2aa98e2SPeter Wemm **  INIT_MD -- do machine dependent initializations
1477c2aa98e2SPeter Wemm **
1478c2aa98e2SPeter Wemm **	Systems that have global modes that should be set should do
1479c2aa98e2SPeter Wemm **	them here rather than in main.
1480c2aa98e2SPeter Wemm */
1481c2aa98e2SPeter Wemm 
1482c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1483c2aa98e2SPeter Wemm # include <compat.h>
14843299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1485c2aa98e2SPeter Wemm 
1486c2aa98e2SPeter Wemm #if SHARE_V1
1487c2aa98e2SPeter Wemm # include <shares.h>
14883299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
1489c2aa98e2SPeter Wemm 
1490c2aa98e2SPeter Wemm void
1491c2aa98e2SPeter Wemm init_md(argc, argv)
1492c2aa98e2SPeter Wemm 	int argc;
1493c2aa98e2SPeter Wemm 	char **argv;
1494c2aa98e2SPeter Wemm {
1495c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1496c2aa98e2SPeter Wemm 	setcompat(getcompat() | COMPAT_BSDPROT);
14973299c2f1SGregory Neil Shapiro #endif /* _AUX_SOURCE */
1498c2aa98e2SPeter Wemm 
1499c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
1500c2aa98e2SPeter Wemm 	init_md_sun();
15013299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
1502c2aa98e2SPeter Wemm 
1503c2aa98e2SPeter Wemm #if _CONVEX_SOURCE
1504c2aa98e2SPeter Wemm 	/* keep gethostby*() from stripping the local domain name */
1505c2aa98e2SPeter Wemm 	set_domain_trim_off();
15063299c2f1SGregory Neil Shapiro #endif /* _CONVEX_SOURCE */
1507c2aa98e2SPeter Wemm #ifdef __QNX__
1508c2aa98e2SPeter Wemm 	/*
1509c2aa98e2SPeter Wemm 	**  Due to QNX's network distributed nature, you can target a tcpip
1510c2aa98e2SPeter Wemm 	**  stack on a different node in the qnx network; this patch lets
1511c2aa98e2SPeter Wemm 	**  this feature work.  The __sock_locate() must be done before the
1512c2aa98e2SPeter Wemm 	**  environment is clear.
1513c2aa98e2SPeter Wemm 	*/
1514c2aa98e2SPeter Wemm 	__sock_locate();
15153299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
1516c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_)
1517c2aa98e2SPeter Wemm 	set_auth_parameters(argc, argv);
1518c2aa98e2SPeter Wemm 
1519c2aa98e2SPeter Wemm # ifdef _SCO_unix_
1520c2aa98e2SPeter Wemm 	/*
1521c2aa98e2SPeter Wemm 	**  This is required for highest security levels (the kernel
1522c2aa98e2SPeter Wemm 	**  won't let it call set*uid() or run setuid binaries without
1523c2aa98e2SPeter Wemm 	**  it).  It may be necessary on other SECUREWARE systems.
1524c2aa98e2SPeter Wemm 	*/
1525c2aa98e2SPeter Wemm 
1526c2aa98e2SPeter Wemm 	if (getluid() == -1)
1527c2aa98e2SPeter Wemm 		setluid(0);
15283299c2f1SGregory Neil Shapiro # endif /* _SCO_unix_ */
15293299c2f1SGregory Neil Shapiro #endif /* SECUREWARE || defined(_SCO_unix_) */
15303299c2f1SGregory Neil Shapiro 
1531c2aa98e2SPeter Wemm 
1532c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT
1533c2aa98e2SPeter Wemm 	VendorCode = VENDOR_DEFAULT;
15343299c2f1SGregory Neil Shapiro #else /* VENDOR_DEFAULT */
1535c2aa98e2SPeter Wemm 	VendorCode = VENDOR_BERKELEY;
15363299c2f1SGregory Neil Shapiro #endif /* VENDOR_DEFAULT */
1537c2aa98e2SPeter Wemm }
1538c2aa98e2SPeter Wemm /*
1539c2aa98e2SPeter Wemm **  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
1540c2aa98e2SPeter Wemm **
1541c2aa98e2SPeter Wemm **	Called once, on startup.
1542c2aa98e2SPeter Wemm **
1543c2aa98e2SPeter Wemm **	Parameters:
1544c2aa98e2SPeter Wemm **		e -- the global envelope.
1545c2aa98e2SPeter Wemm **
1546c2aa98e2SPeter Wemm **	Returns:
1547c2aa98e2SPeter Wemm **		none.
1548c2aa98e2SPeter Wemm **
1549c2aa98e2SPeter Wemm **	Side Effects:
1550c2aa98e2SPeter Wemm **		vendor-dependent.
1551c2aa98e2SPeter Wemm */
1552c2aa98e2SPeter Wemm 
1553c2aa98e2SPeter Wemm void
1554c2aa98e2SPeter Wemm init_vendor_macros(e)
1555c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1556c2aa98e2SPeter Wemm {
1557c2aa98e2SPeter Wemm }
1558c2aa98e2SPeter Wemm /*
1559c2aa98e2SPeter Wemm **  GETLA -- get the current load average
1560c2aa98e2SPeter Wemm **
1561c2aa98e2SPeter Wemm **	This code stolen from la.c.
1562c2aa98e2SPeter Wemm **
1563c2aa98e2SPeter Wemm **	Parameters:
1564c2aa98e2SPeter Wemm **		none.
1565c2aa98e2SPeter Wemm **
1566c2aa98e2SPeter Wemm **	Returns:
1567c2aa98e2SPeter Wemm **		The current load average as an integer.
1568c2aa98e2SPeter Wemm **
1569c2aa98e2SPeter Wemm **	Side Effects:
1570c2aa98e2SPeter Wemm **		none.
1571c2aa98e2SPeter Wemm */
1572c2aa98e2SPeter Wemm 
1573c2aa98e2SPeter Wemm /* try to guess what style of load average we have */
1574c2aa98e2SPeter Wemm #define LA_ZERO		1	/* always return load average as zero */
1575c2aa98e2SPeter Wemm #define LA_INT		2	/* read kmem for avenrun; interpret as long */
1576c2aa98e2SPeter Wemm #define LA_FLOAT	3	/* read kmem for avenrun; interpret as float */
1577c2aa98e2SPeter Wemm #define LA_SUBR		4	/* call getloadavg */
1578c2aa98e2SPeter Wemm #define LA_MACH		5	/* MACH load averages (as on NeXT boxes) */
1579c2aa98e2SPeter Wemm #define LA_SHORT	6	/* read kmem for avenrun; interpret as short */
1580c2aa98e2SPeter Wemm #define LA_PROCSTR	7	/* read string ("1.17") from /proc/loadavg */
1581c2aa98e2SPeter Wemm #define LA_READKSYM	8	/* SVR4: use MIOC_READKSYM ioctl call */
1582c2aa98e2SPeter Wemm #define LA_DGUX		9	/* special DGUX implementation */
1583c2aa98e2SPeter Wemm #define LA_HPUX		10	/* special HPUX implementation */
1584c2aa98e2SPeter Wemm #define LA_IRIX6	11	/* special IRIX 6.2 implementation */
1585c2aa98e2SPeter Wemm #define LA_KSTAT	12	/* special Solaris kstat(3k) implementation */
1586c2aa98e2SPeter Wemm #define LA_DEVSHORT	13	/* read short from a device */
1587c2aa98e2SPeter Wemm #define LA_ALPHAOSF	14	/* Digital UNIX (OSF/1 on Alpha) table() call */
1588c46d91b7SGregory Neil Shapiro #define LA_PSET		15	/* Solaris per-processor-set load average */
1589c2aa98e2SPeter Wemm 
1590c2aa98e2SPeter Wemm /* do guesses based on general OS type */
1591c2aa98e2SPeter Wemm #ifndef LA_TYPE
1592c2aa98e2SPeter Wemm # define LA_TYPE	LA_ZERO
15933299c2f1SGregory Neil Shapiro #endif /* ! LA_TYPE */
1594c2aa98e2SPeter Wemm 
1595c2aa98e2SPeter Wemm #ifndef FSHIFT
1596c2aa98e2SPeter Wemm # if defined(unixpc)
1597c2aa98e2SPeter Wemm #  define FSHIFT	5
15983299c2f1SGregory Neil Shapiro # endif /* defined(unixpc) */
1599c2aa98e2SPeter Wemm 
1600c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX)
1601c2aa98e2SPeter Wemm #  define FSHIFT	10
16023299c2f1SGregory Neil Shapiro # endif /* defined(__alpha) || defined(IRIX) */
1603c2aa98e2SPeter Wemm 
16043299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1605c2aa98e2SPeter Wemm 
1606c2aa98e2SPeter Wemm #ifndef FSHIFT
1607c2aa98e2SPeter Wemm # define FSHIFT		8
16083299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1609c2aa98e2SPeter Wemm 
1610c2aa98e2SPeter Wemm #ifndef FSCALE
1611c2aa98e2SPeter Wemm # define FSCALE		(1 << FSHIFT)
16123299c2f1SGregory Neil Shapiro #endif /* ! FSCALE */
1613c2aa98e2SPeter Wemm 
1614c2aa98e2SPeter Wemm #ifndef LA_AVENRUN
1615c2aa98e2SPeter Wemm # ifdef SYSTEM5
1616c2aa98e2SPeter Wemm #  define LA_AVENRUN	"avenrun"
16173299c2f1SGregory Neil Shapiro # else /* SYSTEM5 */
1618c2aa98e2SPeter Wemm #  define LA_AVENRUN	"_avenrun"
16193299c2f1SGregory Neil Shapiro # endif /* SYSTEM5 */
16203299c2f1SGregory Neil Shapiro #endif /* ! LA_AVENRUN */
1621c2aa98e2SPeter Wemm 
1622c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */
1623c2aa98e2SPeter Wemm #ifndef _PATH_KMEM
1624c2aa98e2SPeter Wemm # define _PATH_KMEM	"/dev/kmem"
16253299c2f1SGregory Neil Shapiro #endif /* ! _PATH_KMEM */
1626c2aa98e2SPeter Wemm 
1627c2aa98e2SPeter Wemm #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
1628c2aa98e2SPeter Wemm 
1629c2aa98e2SPeter Wemm # include <nlist.h>
1630c2aa98e2SPeter Wemm 
1631c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */
1632c2aa98e2SPeter Wemm # ifndef _PATH_UNIX
1633c2aa98e2SPeter Wemm #  if defined(SYSTEM5)
1634c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/unix"
16353299c2f1SGregory Neil Shapiro #  else /* defined(SYSTEM5) */
1636c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/vmunix"
16373299c2f1SGregory Neil Shapiro #  endif /* defined(SYSTEM5) */
16383299c2f1SGregory Neil Shapiro # endif /* ! _PATH_UNIX */
1639c2aa98e2SPeter Wemm 
1640c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
1641c2aa98e2SPeter Wemm struct nlist	Nl[2];
16423299c2f1SGregory Neil Shapiro # else /* _AUX_SOURCE */
1643c2aa98e2SPeter Wemm struct nlist	Nl[] =
1644c2aa98e2SPeter Wemm {
1645c2aa98e2SPeter Wemm 	{ LA_AVENRUN },
1646c2aa98e2SPeter Wemm 	{ 0 },
1647c2aa98e2SPeter Wemm };
16483299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1649c2aa98e2SPeter Wemm # define X_AVENRUN	0
1650c2aa98e2SPeter Wemm 
16513299c2f1SGregory Neil Shapiro static int
1652c2aa98e2SPeter Wemm getla()
1653c2aa98e2SPeter Wemm {
1654c2aa98e2SPeter Wemm 	static int kmem = -1;
1655c2aa98e2SPeter Wemm # if LA_TYPE == LA_INT
1656c2aa98e2SPeter Wemm 	long avenrun[3];
16573299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_INT */
1658c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
1659c2aa98e2SPeter Wemm 	short avenrun[3];
16603299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
1661c2aa98e2SPeter Wemm 	double avenrun[3];
16623299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
16633299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_INT */
1664c2aa98e2SPeter Wemm 	extern int errno;
1665c2aa98e2SPeter Wemm 	extern off_t lseek();
1666c2aa98e2SPeter Wemm 
1667c2aa98e2SPeter Wemm 	if (kmem < 0)
1668c2aa98e2SPeter Wemm 	{
1669c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
16703299c2f1SGregory Neil Shapiro 		(void) strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN,
16713299c2f1SGregory Neil Shapiro 			       sizeof Nl[X_AVENRUN].n_name);
1672c2aa98e2SPeter Wemm 		Nl[1].n_name[0] = '\0';
16733299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1674c2aa98e2SPeter Wemm 
1675c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
1676c2aa98e2SPeter Wemm 		if (knlist(Nl, 1, sizeof Nl[0]) < 0)
16773299c2f1SGregory Neil Shapiro # else /* defined(_AIX3) || defined(_AIX4) */
1678c2aa98e2SPeter Wemm 		if (nlist(_PATH_UNIX, Nl) < 0)
16793299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
1680c2aa98e2SPeter Wemm 		{
1681c2aa98e2SPeter Wemm 			if (tTd(3, 1))
16823299c2f1SGregory Neil Shapiro 				dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
1683c2aa98e2SPeter Wemm 					errstring(errno));
16843299c2f1SGregory Neil Shapiro 			return -1;
1685c2aa98e2SPeter Wemm 		}
1686c2aa98e2SPeter Wemm 		if (Nl[X_AVENRUN].n_value == 0)
1687c2aa98e2SPeter Wemm 		{
1688c2aa98e2SPeter Wemm 			if (tTd(3, 1))
16893299c2f1SGregory Neil Shapiro 				dprintf("getla: nlist(%s, %s) ==> 0\n",
1690c2aa98e2SPeter Wemm 					_PATH_UNIX, LA_AVENRUN);
16913299c2f1SGregory Neil Shapiro 			return -1;
1692c2aa98e2SPeter Wemm 		}
1693c2aa98e2SPeter Wemm # ifdef NAMELISTMASK
1694c2aa98e2SPeter Wemm 		Nl[X_AVENRUN].n_value &= NAMELISTMASK;
16953299c2f1SGregory Neil Shapiro # endif /* NAMELISTMASK */
1696c2aa98e2SPeter Wemm 
1697c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1698c2aa98e2SPeter Wemm 		if (kmem < 0)
1699c2aa98e2SPeter Wemm 		{
1700c2aa98e2SPeter Wemm 			if (tTd(3, 1))
17013299c2f1SGregory Neil Shapiro 				dprintf("getla: open(/dev/kmem): %s\n",
1702c2aa98e2SPeter Wemm 					errstring(errno));
17033299c2f1SGregory Neil Shapiro 			return -1;
1704c2aa98e2SPeter Wemm 		}
17053299c2f1SGregory Neil Shapiro 		(void) fcntl(kmem, F_SETFD, FD_CLOEXEC);
1706c2aa98e2SPeter Wemm 	}
1707c2aa98e2SPeter Wemm 	if (tTd(3, 20))
17083299c2f1SGregory Neil Shapiro 		dprintf("getla: symbol address = %#lx\n",
1709c2aa98e2SPeter Wemm 			(u_long) Nl[X_AVENRUN].n_value);
1710c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
1711c2aa98e2SPeter Wemm 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
1712c2aa98e2SPeter Wemm 	{
1713c2aa98e2SPeter Wemm 		/* thank you Ian */
1714c2aa98e2SPeter Wemm 		if (tTd(3, 1))
17153299c2f1SGregory Neil Shapiro 			dprintf("getla: lseek or read: %s\n",
17163299c2f1SGregory Neil Shapiro 				errstring(errno));
17173299c2f1SGregory Neil Shapiro 		return -1;
1718c2aa98e2SPeter Wemm 	}
1719c2aa98e2SPeter Wemm # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
1720c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1721c2aa98e2SPeter Wemm 	{
1722c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
17233299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %d", avenrun[0]);
1724c2aa98e2SPeter Wemm 		if (tTd(3, 15))
17253299c2f1SGregory Neil Shapiro 			dprintf(", %d, %d", avenrun[1], avenrun[2]);
17263299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
17273299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %ld", avenrun[0]);
1728c2aa98e2SPeter Wemm 		if (tTd(3, 15))
17293299c2f1SGregory Neil Shapiro 			dprintf(", %ld, %ld", avenrun[1], avenrun[2]);
17303299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
17313299c2f1SGregory Neil Shapiro 		dprintf("\n");
1732c2aa98e2SPeter Wemm 	}
1733c2aa98e2SPeter Wemm 	if (tTd(3, 1))
17343299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n",
17353299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1736c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
17373299c2f1SGregory Neil Shapiro # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */
1738c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1739c2aa98e2SPeter Wemm 	{
17403299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %g", avenrun[0]);
1741c2aa98e2SPeter Wemm 		if (tTd(3, 15))
17423299c2f1SGregory Neil Shapiro 			dprintf(", %g, %g", avenrun[1], avenrun[2]);
17433299c2f1SGregory Neil Shapiro 		dprintf("\n");
1744c2aa98e2SPeter Wemm 	}
1745c2aa98e2SPeter Wemm 	if (tTd(3, 1))
17463299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1747c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
17483299c2f1SGregory Neil Shapiro # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */
1749c2aa98e2SPeter Wemm }
1750c2aa98e2SPeter Wemm 
17513299c2f1SGregory Neil Shapiro #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) */
1752c2aa98e2SPeter Wemm 
1753c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM
1754c2aa98e2SPeter Wemm 
1755c2aa98e2SPeter Wemm # include <sys/ksym.h>
1756c2aa98e2SPeter Wemm 
17573299c2f1SGregory Neil Shapiro static int
1758c2aa98e2SPeter Wemm getla()
1759c2aa98e2SPeter Wemm {
1760c2aa98e2SPeter Wemm 	static int kmem = -1;
1761c2aa98e2SPeter Wemm 	long avenrun[3];
1762c2aa98e2SPeter Wemm 	extern int errno;
1763c2aa98e2SPeter Wemm 	struct mioc_rksym mirk;
1764c2aa98e2SPeter Wemm 
1765c2aa98e2SPeter Wemm 	if (kmem < 0)
1766c2aa98e2SPeter Wemm 	{
1767c2aa98e2SPeter Wemm 		kmem = open("/dev/kmem", 0, 0);
1768c2aa98e2SPeter Wemm 		if (kmem < 0)
1769c2aa98e2SPeter Wemm 		{
1770c2aa98e2SPeter Wemm 			if (tTd(3, 1))
17713299c2f1SGregory Neil Shapiro 				dprintf("getla: open(/dev/kmem): %s\n",
1772c2aa98e2SPeter Wemm 					errstring(errno));
17733299c2f1SGregory Neil Shapiro 			return -1;
1774c2aa98e2SPeter Wemm 		}
17753299c2f1SGregory Neil Shapiro 		(void) fcntl(kmem, F_SETFD, FD_CLOEXEC);
1776c2aa98e2SPeter Wemm 	}
1777c2aa98e2SPeter Wemm 	mirk.mirk_symname = LA_AVENRUN;
1778c2aa98e2SPeter Wemm 	mirk.mirk_buf = avenrun;
1779c2aa98e2SPeter Wemm 	mirk.mirk_buflen = sizeof(avenrun);
1780c2aa98e2SPeter Wemm 	if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
1781c2aa98e2SPeter Wemm 	{
1782c2aa98e2SPeter Wemm 		if (tTd(3, 1))
17833299c2f1SGregory Neil Shapiro 			dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
1784c2aa98e2SPeter Wemm 				errstring(errno));
1785c2aa98e2SPeter Wemm 		return -1;
1786c2aa98e2SPeter Wemm 	}
1787c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1788c2aa98e2SPeter Wemm 	{
17893299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %d", avenrun[0]);
1790c2aa98e2SPeter Wemm 		if (tTd(3, 15))
17913299c2f1SGregory Neil Shapiro 			dprintf(", %d, %d", avenrun[1], avenrun[2]);
17923299c2f1SGregory Neil Shapiro 		dprintf("\n");
1793c2aa98e2SPeter Wemm 	}
1794c2aa98e2SPeter Wemm 	if (tTd(3, 1))
17953299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n",
17963299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1797c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1798c2aa98e2SPeter Wemm }
1799c2aa98e2SPeter Wemm 
1800c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */
1801c2aa98e2SPeter Wemm 
1802c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX
1803c2aa98e2SPeter Wemm 
1804c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h>
1805c2aa98e2SPeter Wemm 
18063299c2f1SGregory Neil Shapiro static int
1807c2aa98e2SPeter Wemm getla()
1808c2aa98e2SPeter Wemm {
1809c2aa98e2SPeter Wemm 	struct dg_sys_info_load_info load_info;
1810c2aa98e2SPeter Wemm 
1811c2aa98e2SPeter Wemm 	dg_sys_info((long *)&load_info,
1812c2aa98e2SPeter Wemm 		DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
1813c2aa98e2SPeter Wemm 
1814c2aa98e2SPeter Wemm 	if (tTd(3, 1))
18153299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5));
1816c2aa98e2SPeter Wemm 
1817c2aa98e2SPeter Wemm 	return ((int) (load_info.one_minute + 0.5));
1818c2aa98e2SPeter Wemm }
1819c2aa98e2SPeter Wemm 
1820c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */
1821c2aa98e2SPeter Wemm 
1822c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX
1823c2aa98e2SPeter Wemm 
1824c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */
1825c2aa98e2SPeter Wemm struct pst_dynamic;
1826c2aa98e2SPeter Wemm struct pst_status;
1827c2aa98e2SPeter Wemm struct pst_static;
1828c2aa98e2SPeter Wemm struct pst_vminfo;
1829c2aa98e2SPeter Wemm struct pst_diskinfo;
1830c2aa98e2SPeter Wemm struct pst_processor;
1831c2aa98e2SPeter Wemm struct pst_lv;
1832c2aa98e2SPeter Wemm struct pst_swapinfo;
1833c2aa98e2SPeter Wemm 
1834c2aa98e2SPeter Wemm # include <sys/param.h>
1835c2aa98e2SPeter Wemm # include <sys/pstat.h>
1836c2aa98e2SPeter Wemm 
18373299c2f1SGregory Neil Shapiro static int
1838c2aa98e2SPeter Wemm getla()
1839c2aa98e2SPeter Wemm {
1840c2aa98e2SPeter Wemm 	struct pst_dynamic pstd;
1841c2aa98e2SPeter Wemm 
1842c2aa98e2SPeter Wemm 	if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
1843c2aa98e2SPeter Wemm 			     (size_t) 1, 0) == -1)
1844c2aa98e2SPeter Wemm 		return 0;
1845c2aa98e2SPeter Wemm 
1846c2aa98e2SPeter Wemm 	if (tTd(3, 1))
18473299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
1848c2aa98e2SPeter Wemm 
1849c2aa98e2SPeter Wemm 	return (int) (pstd.psd_avg_1_min + 0.5);
1850c2aa98e2SPeter Wemm }
1851c2aa98e2SPeter Wemm 
1852c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */
1853c2aa98e2SPeter Wemm 
1854c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR
1855c2aa98e2SPeter Wemm 
18563299c2f1SGregory Neil Shapiro static int
1857c2aa98e2SPeter Wemm getla()
1858c2aa98e2SPeter Wemm {
1859c2aa98e2SPeter Wemm 	double avenrun[3];
1860c2aa98e2SPeter Wemm 
1861c2aa98e2SPeter Wemm 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
1862c2aa98e2SPeter Wemm 	{
1863c2aa98e2SPeter Wemm 		if (tTd(3, 1))
18643299c2f1SGregory Neil Shapiro 			dprintf("getla: getloadavg failed: %s",
18653299c2f1SGregory Neil Shapiro 				errstring(errno));
18663299c2f1SGregory Neil Shapiro 		return -1;
1867c2aa98e2SPeter Wemm 	}
1868c2aa98e2SPeter Wemm 	if (tTd(3, 1))
18693299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1870c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1871c2aa98e2SPeter Wemm }
1872c2aa98e2SPeter Wemm 
1873c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */
1874c2aa98e2SPeter Wemm 
1875c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH
1876c2aa98e2SPeter Wemm 
1877c2aa98e2SPeter Wemm /*
1878c2aa98e2SPeter Wemm **  This has been tested on NEXTSTEP release 2.1/3.X.
1879c2aa98e2SPeter Wemm */
1880c2aa98e2SPeter Wemm 
1881c2aa98e2SPeter Wemm # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
1882c2aa98e2SPeter Wemm #  include <mach/mach.h>
18833299c2f1SGregory Neil Shapiro # else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1884c2aa98e2SPeter Wemm #  include <mach.h>
18853299c2f1SGregory Neil Shapiro # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
1886c2aa98e2SPeter Wemm 
18873299c2f1SGregory Neil Shapiro static int
1888c2aa98e2SPeter Wemm getla()
1889c2aa98e2SPeter Wemm {
1890c2aa98e2SPeter Wemm 	processor_set_t default_set;
1891c2aa98e2SPeter Wemm 	kern_return_t error;
1892c2aa98e2SPeter Wemm 	unsigned int info_count;
1893c2aa98e2SPeter Wemm 	struct processor_set_basic_info info;
1894c2aa98e2SPeter Wemm 	host_t host;
1895c2aa98e2SPeter Wemm 
1896c2aa98e2SPeter Wemm 	error = processor_set_default(host_self(), &default_set);
1897c2aa98e2SPeter Wemm 	if (error != KERN_SUCCESS)
1898c2aa98e2SPeter Wemm 	{
1899c2aa98e2SPeter Wemm 		if (tTd(3, 1))
19003299c2f1SGregory Neil Shapiro 			dprintf("getla: processor_set_default failed: %s",
19013299c2f1SGregory Neil Shapiro 				errstring(errno));
1902c2aa98e2SPeter Wemm 		return -1;
1903c2aa98e2SPeter Wemm 	}
1904c2aa98e2SPeter Wemm 	info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
1905c2aa98e2SPeter Wemm 	if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
1906c2aa98e2SPeter Wemm 			       &host, (processor_set_info_t)&info,
1907c2aa98e2SPeter Wemm 			       &info_count) != KERN_SUCCESS)
1908c2aa98e2SPeter Wemm 	{
1909c2aa98e2SPeter Wemm 		if (tTd(3, 1))
19103299c2f1SGregory Neil Shapiro 			dprintf("getla: processor_set_info failed: %s",
19113299c2f1SGregory Neil Shapiro 				errstring(errno));
1912c2aa98e2SPeter Wemm 		return -1;
1913c2aa98e2SPeter Wemm 	}
1914c2aa98e2SPeter Wemm 	if (tTd(3, 1))
19153299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n",
19163299c2f1SGregory Neil Shapiro 			(int) ((info.load_average + (LOAD_SCALE / 2)) /
19173299c2f1SGregory Neil Shapiro 			       LOAD_SCALE));
1918c2aa98e2SPeter Wemm 	return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
1919c2aa98e2SPeter Wemm }
1920c2aa98e2SPeter Wemm 
1921c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */
1922c2aa98e2SPeter Wemm 
1923c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR
1924c2aa98e2SPeter Wemm 
1925c2aa98e2SPeter Wemm /*
1926c2aa98e2SPeter Wemm **  Read /proc/loadavg for the load average.  This is assumed to be
1927c2aa98e2SPeter Wemm **  in a format like "0.15 0.12 0.06".
1928c2aa98e2SPeter Wemm **
1929c2aa98e2SPeter Wemm **	Initially intended for Linux.  This has been in the kernel
1930c2aa98e2SPeter Wemm **	since at least 0.99.15.
1931c2aa98e2SPeter Wemm */
1932c2aa98e2SPeter Wemm 
1933c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG
1934c2aa98e2SPeter Wemm #  define _PATH_LOADAVG	"/proc/loadavg"
19353299c2f1SGregory Neil Shapiro # endif /* ! _PATH_LOADAVG */
1936c2aa98e2SPeter Wemm 
19373299c2f1SGregory Neil Shapiro static int
1938c2aa98e2SPeter Wemm getla()
1939c2aa98e2SPeter Wemm {
1940c2aa98e2SPeter Wemm 	double avenrun;
1941c2aa98e2SPeter Wemm 	register int result;
1942c2aa98e2SPeter Wemm 	FILE *fp;
1943c2aa98e2SPeter Wemm 
1944c2aa98e2SPeter Wemm 	fp = fopen(_PATH_LOADAVG, "r");
1945c2aa98e2SPeter Wemm 	if (fp == NULL)
1946c2aa98e2SPeter Wemm 	{
1947c2aa98e2SPeter Wemm 		if (tTd(3, 1))
19483299c2f1SGregory Neil Shapiro 			dprintf("getla: fopen(%s): %s\n",
1949c2aa98e2SPeter Wemm 				_PATH_LOADAVG, errstring(errno));
1950c2aa98e2SPeter Wemm 		return -1;
1951c2aa98e2SPeter Wemm 	}
1952c2aa98e2SPeter Wemm 	result = fscanf(fp, "%lf", &avenrun);
19533299c2f1SGregory Neil Shapiro 	(void) fclose(fp);
1954c2aa98e2SPeter Wemm 	if (result != 1)
1955c2aa98e2SPeter Wemm 	{
1956c2aa98e2SPeter Wemm 		if (tTd(3, 1))
19573299c2f1SGregory Neil Shapiro 			dprintf("getla: fscanf() = %d: %s\n",
1958c2aa98e2SPeter Wemm 				result, errstring(errno));
1959c2aa98e2SPeter Wemm 		return -1;
1960c2aa98e2SPeter Wemm 	}
1961c2aa98e2SPeter Wemm 
1962c2aa98e2SPeter Wemm 	if (tTd(3, 1))
19633299c2f1SGregory Neil Shapiro 		dprintf("getla(): %.2f\n", avenrun);
1964c2aa98e2SPeter Wemm 
1965c2aa98e2SPeter Wemm 	return ((int) (avenrun + 0.5));
1966c2aa98e2SPeter Wemm }
1967c2aa98e2SPeter Wemm 
1968c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */
1969c2aa98e2SPeter Wemm 
1970c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6
19713299c2f1SGregory Neil Shapiro 
1972c2aa98e2SPeter Wemm # include <sys/sysmp.h>
1973c2aa98e2SPeter Wemm 
1974c2aa98e2SPeter Wemm int getla(void)
1975c2aa98e2SPeter Wemm {
1976c2aa98e2SPeter Wemm 	static int kmem = -1;
1977c2aa98e2SPeter Wemm 	int avenrun[3];
1978c2aa98e2SPeter Wemm 
1979c2aa98e2SPeter Wemm 	if (kmem < 0)
1980c2aa98e2SPeter Wemm 	{
1981c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1982c2aa98e2SPeter Wemm 		if (kmem < 0)
1983c2aa98e2SPeter Wemm 		{
1984c2aa98e2SPeter Wemm 			if (tTd(3, 1))
19853299c2f1SGregory Neil Shapiro 				dprintf("getla: open(%s): %s\n", _PATH_KMEM,
1986c2aa98e2SPeter Wemm 					errstring(errno));
1987c2aa98e2SPeter Wemm 			return -1;
1988c2aa98e2SPeter Wemm 		}
19893299c2f1SGregory Neil Shapiro 		(void) fcntl(kmem, F_SETFD, FD_CLOEXEC);
1990c2aa98e2SPeter Wemm 	}
1991c2aa98e2SPeter Wemm 
1992c2aa98e2SPeter Wemm 	if (lseek(kmem, (sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff), SEEK_SET) == -1 ||
1993c2aa98e2SPeter Wemm 	    read(kmem, (char *)avenrun, sizeof(avenrun)) < sizeof(avenrun))
1994c2aa98e2SPeter Wemm 	{
1995c2aa98e2SPeter Wemm 		if (tTd(3, 1))
19963299c2f1SGregory Neil Shapiro 			dprintf("getla: lseek or read: %s\n",
1997c2aa98e2SPeter Wemm 				errstring(errno));
1998c2aa98e2SPeter Wemm 		return -1;
1999c2aa98e2SPeter Wemm 	}
2000c2aa98e2SPeter Wemm 	if (tTd(3, 5))
2001c2aa98e2SPeter Wemm 	{
20023299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %ld", (long int) avenrun[0]);
2003c2aa98e2SPeter Wemm 		if (tTd(3, 15))
20043299c2f1SGregory Neil Shapiro 			dprintf(", %ld, %ld",
2005c2aa98e2SPeter Wemm 				(long int) avenrun[1], (long int) avenrun[2]);
20063299c2f1SGregory Neil Shapiro 		dprintf("\n");
2007c2aa98e2SPeter Wemm 	}
2008c2aa98e2SPeter Wemm 
2009c2aa98e2SPeter Wemm 	if (tTd(3, 1))
20103299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n",
20113299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
2012c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
2013c2aa98e2SPeter Wemm 
2014c2aa98e2SPeter Wemm }
20153299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_IRIX6 */
2016c2aa98e2SPeter Wemm 
2017c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT
2018c2aa98e2SPeter Wemm 
2019c2aa98e2SPeter Wemm # include <kstat.h>
2020c2aa98e2SPeter Wemm 
20213299c2f1SGregory Neil Shapiro static int
2022c2aa98e2SPeter Wemm getla()
2023c2aa98e2SPeter Wemm {
2024c2aa98e2SPeter Wemm 	static kstat_ctl_t *kc = NULL;
2025c2aa98e2SPeter Wemm 	static kstat_t *ksp = NULL;
2026c2aa98e2SPeter Wemm 	kstat_named_t *ksn;
2027c2aa98e2SPeter Wemm 	int la;
2028c2aa98e2SPeter Wemm 
2029c2aa98e2SPeter Wemm 	if (kc == NULL)		/* if not initialized before */
2030c2aa98e2SPeter Wemm 		kc = kstat_open();
2031c2aa98e2SPeter Wemm 	if (kc == NULL)
2032c2aa98e2SPeter Wemm 	{
2033c2aa98e2SPeter Wemm 		if (tTd(3, 1))
20343299c2f1SGregory Neil Shapiro 			dprintf("getla: kstat_open(): %s\n",
2035c2aa98e2SPeter Wemm 				errstring(errno));
2036c2aa98e2SPeter Wemm 		return -1;
2037c2aa98e2SPeter Wemm 	}
2038c2aa98e2SPeter Wemm 	if (ksp == NULL)
2039c2aa98e2SPeter Wemm 		ksp = kstat_lookup(kc, "unix", 0, "system_misc");
2040c2aa98e2SPeter Wemm 	if (ksp == NULL)
2041c2aa98e2SPeter Wemm 	{
2042c2aa98e2SPeter Wemm 		if (tTd(3, 1))
20433299c2f1SGregory Neil Shapiro 			dprintf("getla: kstat_lookup(): %s\n",
2044c2aa98e2SPeter Wemm 				errstring(errno));
2045c2aa98e2SPeter Wemm 		return -1;
2046c2aa98e2SPeter Wemm 	}
2047c2aa98e2SPeter Wemm 	if (kstat_read(kc, ksp, NULL) < 0)
2048c2aa98e2SPeter Wemm 	{
2049c2aa98e2SPeter Wemm 		if (tTd(3, 1))
20503299c2f1SGregory Neil Shapiro 			dprintf("getla: kstat_read(): %s\n",
2051c2aa98e2SPeter Wemm 				errstring(errno));
2052c2aa98e2SPeter Wemm 		return -1;
2053c2aa98e2SPeter Wemm 	}
2054c2aa98e2SPeter Wemm 	ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
2055c2aa98e2SPeter Wemm 	la = ((double)ksn->value.ul + FSCALE/2) / FSCALE;
2056c2aa98e2SPeter Wemm 	/* kstat_close(kc); /o do not close for fast access */
2057c2aa98e2SPeter Wemm 	return la;
2058c2aa98e2SPeter Wemm }
2059c2aa98e2SPeter Wemm 
2060c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */
2061c2aa98e2SPeter Wemm 
2062c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT
2063c2aa98e2SPeter Wemm 
2064c2aa98e2SPeter Wemm /*
2065c2aa98e2SPeter Wemm **  Read /dev/table/avenrun for the load average.  This should contain
2066c2aa98e2SPeter Wemm **  three shorts for the 1, 5, and 15 minute loads.  We only read the
2067c2aa98e2SPeter Wemm **  first, since that's all we care about.
2068c2aa98e2SPeter Wemm **
2069c2aa98e2SPeter Wemm **	Intended for SCO OpenServer 5.
2070c2aa98e2SPeter Wemm */
2071c2aa98e2SPeter Wemm 
2072c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN
2073c2aa98e2SPeter Wemm #  define _PATH_AVENRUN	"/dev/table/avenrun"
20743299c2f1SGregory Neil Shapiro # endif /* ! _PATH_AVENRUN */
2075c2aa98e2SPeter Wemm 
20763299c2f1SGregory Neil Shapiro static int
2077c2aa98e2SPeter Wemm getla()
2078c2aa98e2SPeter Wemm {
2079c2aa98e2SPeter Wemm 	static int afd = -1;
2080c2aa98e2SPeter Wemm 	short avenrun;
2081c2aa98e2SPeter Wemm 	int loadav;
2082c2aa98e2SPeter Wemm 	int r;
2083c2aa98e2SPeter Wemm 
2084c2aa98e2SPeter Wemm 	errno = EBADF;
2085c2aa98e2SPeter Wemm 
2086c2aa98e2SPeter Wemm 	if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
2087c2aa98e2SPeter Wemm 	{
2088c2aa98e2SPeter Wemm 		if (errno != EBADF)
2089c2aa98e2SPeter Wemm 			return -1;
2090c2aa98e2SPeter Wemm 		afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
2091c2aa98e2SPeter Wemm 		if (afd < 0)
2092c2aa98e2SPeter Wemm 		{
2093c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
2094c2aa98e2SPeter Wemm 				"can't open %s: %m",
2095c2aa98e2SPeter Wemm 				_PATH_AVENRUN);
2096c2aa98e2SPeter Wemm 			return -1;
2097c2aa98e2SPeter Wemm 		}
2098c2aa98e2SPeter Wemm 	}
2099c2aa98e2SPeter Wemm 
2100c2aa98e2SPeter Wemm 	r = read(afd, &avenrun, sizeof avenrun);
2101c2aa98e2SPeter Wemm 
2102c2aa98e2SPeter Wemm 	if (tTd(3, 5))
21033299c2f1SGregory Neil Shapiro 		dprintf("getla: avenrun = %d\n", avenrun);
2104c2aa98e2SPeter Wemm 	loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
2105c2aa98e2SPeter Wemm 	if (tTd(3, 1))
21063299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", loadav);
2107c2aa98e2SPeter Wemm 	return loadav;
2108c2aa98e2SPeter Wemm }
2109c2aa98e2SPeter Wemm 
2110c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */
2111c2aa98e2SPeter Wemm 
2112c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF
2113c2aa98e2SPeter Wemm struct rtentry;
2114c2aa98e2SPeter Wemm struct mbuf;
2115c2aa98e2SPeter Wemm # include <sys/table.h>
2116c2aa98e2SPeter Wemm 
2117c2aa98e2SPeter Wemm int getla()
2118c2aa98e2SPeter Wemm {
2119c2aa98e2SPeter Wemm 	int ave = 0;
2120c2aa98e2SPeter Wemm 	struct tbl_loadavg tab;
2121c2aa98e2SPeter Wemm 
2122c2aa98e2SPeter Wemm 	if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
2123c2aa98e2SPeter Wemm 	{
2124c2aa98e2SPeter Wemm 		if (tTd(3, 1))
21253299c2f1SGregory Neil Shapiro 			dprintf("getla: table %s\n", errstring(errno));
21263299c2f1SGregory Neil Shapiro 		return -1;
2127c2aa98e2SPeter Wemm 	}
2128c2aa98e2SPeter Wemm 
2129c2aa98e2SPeter Wemm 	if (tTd(3, 1))
21303299c2f1SGregory Neil Shapiro 		dprintf("getla: scale = %d\n", tab.tl_lscale);
2131c2aa98e2SPeter Wemm 
2132c2aa98e2SPeter Wemm 	if (tab.tl_lscale)
21333299c2f1SGregory Neil Shapiro 		ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) /
21343299c2f1SGregory Neil Shapiro 		       tab.tl_lscale);
2135c2aa98e2SPeter Wemm 	else
21363299c2f1SGregory Neil Shapiro 		ave = (int) (tab.tl_avenrun.d[2] + 0.5);
2137c2aa98e2SPeter Wemm 
2138c2aa98e2SPeter Wemm 	if (tTd(3, 1))
21393299c2f1SGregory Neil Shapiro 		dprintf("getla: %d\n", ave);
2140c2aa98e2SPeter Wemm 
2141c2aa98e2SPeter Wemm 	return ave;
2142c2aa98e2SPeter Wemm }
2143c2aa98e2SPeter Wemm 
21443299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_ALPHAOSF */
2145c2aa98e2SPeter Wemm 
2146c46d91b7SGregory Neil Shapiro #if LA_TYPE == LA_PSET
2147c46d91b7SGregory Neil Shapiro 
2148c46d91b7SGregory Neil Shapiro static int
2149c46d91b7SGregory Neil Shapiro getla()
2150c46d91b7SGregory Neil Shapiro {
2151c46d91b7SGregory Neil Shapiro 	double avenrun[3];
2152c46d91b7SGregory Neil Shapiro 
2153c46d91b7SGregory Neil Shapiro 	if (pset_getloadavg(PS_MYID, avenrun,
2154c46d91b7SGregory Neil Shapiro 			    sizeof(avenrun) / sizeof(avenrun[0])) < 0)
2155c46d91b7SGregory Neil Shapiro 	{
2156c46d91b7SGregory Neil Shapiro 		if (tTd(3, 1))
2157c46d91b7SGregory Neil Shapiro 			dprintf("getla: pset_getloadavg failed: %s",
2158c46d91b7SGregory Neil Shapiro 				errstring(errno));
2159c46d91b7SGregory Neil Shapiro 		return -1;
2160c46d91b7SGregory Neil Shapiro 	}
2161c46d91b7SGregory Neil Shapiro 	if (tTd(3, 1))
2162c46d91b7SGregory Neil Shapiro 		dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
2163c46d91b7SGregory Neil Shapiro 	return ((int) (avenrun[0] + 0.5));
2164c46d91b7SGregory Neil Shapiro }
2165c46d91b7SGregory Neil Shapiro 
2166c46d91b7SGregory Neil Shapiro #endif /* LA_TYPE == LA_PSET */
2167c46d91b7SGregory Neil Shapiro 
2168c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO
2169c2aa98e2SPeter Wemm 
21703299c2f1SGregory Neil Shapiro static int
2171c2aa98e2SPeter Wemm getla()
2172c2aa98e2SPeter Wemm {
2173c2aa98e2SPeter Wemm 	if (tTd(3, 1))
21743299c2f1SGregory Neil Shapiro 		dprintf("getla: ZERO\n");
21753299c2f1SGregory Neil Shapiro 	return 0;
2176c2aa98e2SPeter Wemm }
2177c2aa98e2SPeter Wemm 
2178c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */
2179c2aa98e2SPeter Wemm 
2180c2aa98e2SPeter Wemm /*
2181c2aa98e2SPeter Wemm  * Copyright 1989 Massachusetts Institute of Technology
2182c2aa98e2SPeter Wemm  *
2183c2aa98e2SPeter Wemm  * Permission to use, copy, modify, distribute, and sell this software and its
2184c2aa98e2SPeter Wemm  * documentation for any purpose is hereby granted without fee, provided that
2185c2aa98e2SPeter Wemm  * the above copyright notice appear in all copies and that both that
2186c2aa98e2SPeter Wemm  * copyright notice and this permission notice appear in supporting
2187c2aa98e2SPeter Wemm  * documentation, and that the name of M.I.T. not be used in advertising or
2188c2aa98e2SPeter Wemm  * publicity pertaining to distribution of the software without specific,
2189c2aa98e2SPeter Wemm  * written prior permission.  M.I.T. makes no representations about the
2190c2aa98e2SPeter Wemm  * suitability of this software for any purpose.  It is provided "as is"
2191c2aa98e2SPeter Wemm  * without express or implied warranty.
2192c2aa98e2SPeter Wemm  *
2193c2aa98e2SPeter Wemm  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
2194c2aa98e2SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
2195c2aa98e2SPeter Wemm  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2196c2aa98e2SPeter Wemm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2197c2aa98e2SPeter Wemm  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2198c2aa98e2SPeter Wemm  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2199c2aa98e2SPeter Wemm  *
2200c2aa98e2SPeter Wemm  * Authors:  Many and varied...
2201c2aa98e2SPeter Wemm  */
2202c2aa98e2SPeter Wemm 
2203c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */
2204c2aa98e2SPeter Wemm #ifndef lint
22053299c2f1SGregory Neil Shapiro static char  rcsid[] = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
2206c2aa98e2SPeter Wemm #endif /* ! lint */
2207c2aa98e2SPeter Wemm 
2208c2aa98e2SPeter Wemm #ifdef apollo
2209c2aa98e2SPeter Wemm # undef volatile
2210c2aa98e2SPeter Wemm # include <apollo/base.h>
2211c2aa98e2SPeter Wemm 
2212c2aa98e2SPeter Wemm /* ARGSUSED */
2213c2aa98e2SPeter Wemm int getloadavg( call_data )
2214c2aa98e2SPeter Wemm      caddr_t	call_data;	/* pointer to (double) return value */
2215c2aa98e2SPeter Wemm {
2216c2aa98e2SPeter Wemm      double *avenrun = (double *) call_data;
2217c2aa98e2SPeter Wemm      int i;
2218c2aa98e2SPeter Wemm      status_$t      st;
2219c2aa98e2SPeter Wemm      long loadav[3];
2220c2aa98e2SPeter Wemm      proc1_$get_loadav(loadav, &st);
2221c2aa98e2SPeter Wemm      *avenrun = loadav[0] / (double) (1 << 16);
22223299c2f1SGregory Neil Shapiro      return 0;
2223c2aa98e2SPeter Wemm }
2224c2aa98e2SPeter Wemm #endif /* apollo */
2225c2aa98e2SPeter Wemm /*
22263299c2f1SGregory Neil Shapiro **  SM_GETLA -- get the current load average and set macro
22273299c2f1SGregory Neil Shapiro **
22283299c2f1SGregory Neil Shapiro **	Parameters:
22293299c2f1SGregory Neil Shapiro **		e -- the envelope for the load average macro.
22303299c2f1SGregory Neil Shapiro **
22313299c2f1SGregory Neil Shapiro **	Returns:
22323299c2f1SGregory Neil Shapiro **		The current load average as an integer.
22333299c2f1SGregory Neil Shapiro **
22343299c2f1SGregory Neil Shapiro **	Side Effects:
22353299c2f1SGregory Neil Shapiro **		Sets the load average macro ({load_avg}) if
22363299c2f1SGregory Neil Shapiro **		envelope e is not NULL.
22373299c2f1SGregory Neil Shapiro */
22383299c2f1SGregory Neil Shapiro 
22393299c2f1SGregory Neil Shapiro int
22403299c2f1SGregory Neil Shapiro sm_getla(e)
22413299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
22423299c2f1SGregory Neil Shapiro {
22433299c2f1SGregory Neil Shapiro 	register int la;
22443299c2f1SGregory Neil Shapiro 
22453299c2f1SGregory Neil Shapiro 	la = getla();
22463299c2f1SGregory Neil Shapiro 	if (e != NULL)
22473299c2f1SGregory Neil Shapiro 	{
22483299c2f1SGregory Neil Shapiro 		char labuf[8];
22493299c2f1SGregory Neil Shapiro 
2250d995d2baSGregory Neil Shapiro 		snprintf(labuf, sizeof labuf, "%d", la);
22513299c2f1SGregory Neil Shapiro 		define(macid("{load_avg}", NULL), newstr(labuf), e);
22523299c2f1SGregory Neil Shapiro 	}
22533299c2f1SGregory Neil Shapiro 	return la;
22543299c2f1SGregory Neil Shapiro }
22553299c2f1SGregory Neil Shapiro 
22563299c2f1SGregory Neil Shapiro /*
2257c2aa98e2SPeter Wemm **  SHOULDQUEUE -- should this message be queued or sent?
2258c2aa98e2SPeter Wemm **
2259c2aa98e2SPeter Wemm **	Compares the message cost to the load average to decide.
2260c2aa98e2SPeter Wemm **
2261c2aa98e2SPeter Wemm **	Parameters:
2262c2aa98e2SPeter Wemm **		pri -- the priority of the message in question.
22633299c2f1SGregory Neil Shapiro **		ct -- the message creation time.
2264c2aa98e2SPeter Wemm **
2265c2aa98e2SPeter Wemm **	Returns:
2266c2aa98e2SPeter Wemm **		TRUE -- if this message should be queued up for the
2267c2aa98e2SPeter Wemm **			time being.
2268c2aa98e2SPeter Wemm **		FALSE -- if the load is low enough to send this message.
2269c2aa98e2SPeter Wemm **
2270c2aa98e2SPeter Wemm **	Side Effects:
2271c2aa98e2SPeter Wemm **		none.
2272c2aa98e2SPeter Wemm */
2273c2aa98e2SPeter Wemm 
22743299c2f1SGregory Neil Shapiro /* ARGSUSED1 */
2275c2aa98e2SPeter Wemm bool
22763299c2f1SGregory Neil Shapiro shouldqueue(pri, ct)
2277c2aa98e2SPeter Wemm 	long pri;
22783299c2f1SGregory Neil Shapiro 	time_t ct;
2279c2aa98e2SPeter Wemm {
2280c2aa98e2SPeter Wemm 	bool rval;
2281c2aa98e2SPeter Wemm 
2282c2aa98e2SPeter Wemm 	if (tTd(3, 30))
22833299c2f1SGregory Neil Shapiro 		dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
22843299c2f1SGregory Neil Shapiro 			CurrentLA, pri);
22853299c2f1SGregory Neil Shapiro 	if (CurrentLA < QueueLA)
2286c2aa98e2SPeter Wemm 	{
2287c2aa98e2SPeter Wemm 		if (tTd(3, 30))
22883299c2f1SGregory Neil Shapiro 			dprintf("FALSE (CurrentLA < QueueLA)\n");
22893299c2f1SGregory Neil Shapiro 		return FALSE;
2290c2aa98e2SPeter Wemm 	}
2291c2aa98e2SPeter Wemm #if 0	/* this code is reported to cause oscillation around RefuseLA */
2292c2aa98e2SPeter Wemm 	if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
2293c2aa98e2SPeter Wemm 	{
2294c2aa98e2SPeter Wemm 		if (tTd(3, 30))
22953299c2f1SGregory Neil Shapiro 			dprintf("TRUE (CurrentLA >= RefuseLA)\n");
22963299c2f1SGregory Neil Shapiro 		return TRUE;
2297c2aa98e2SPeter Wemm 	}
22983299c2f1SGregory Neil Shapiro #endif /* 0 */
22993299c2f1SGregory Neil Shapiro 	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
2300c2aa98e2SPeter Wemm 	if (tTd(3, 30))
23013299c2f1SGregory Neil Shapiro 		dprintf("%s (by calculation)\n", rval ? "TRUE" : "FALSE");
2302c2aa98e2SPeter Wemm 	return rval;
2303c2aa98e2SPeter Wemm }
2304c2aa98e2SPeter Wemm /*
2305c2aa98e2SPeter Wemm **  REFUSECONNECTIONS -- decide if connections should be refused
2306c2aa98e2SPeter Wemm **
2307c2aa98e2SPeter Wemm **	Parameters:
23083299c2f1SGregory Neil Shapiro **		name -- daemon name (for error messages only)
23093299c2f1SGregory Neil Shapiro **		e -- the current envelope.
23103299c2f1SGregory Neil Shapiro **		d -- number of daemon
2311c2aa98e2SPeter Wemm **
2312c2aa98e2SPeter Wemm **	Returns:
2313c2aa98e2SPeter Wemm **		TRUE if incoming SMTP connections should be refused
2314c2aa98e2SPeter Wemm **			(for now).
2315c2aa98e2SPeter Wemm **		FALSE if we should accept new work.
2316c2aa98e2SPeter Wemm **
2317c2aa98e2SPeter Wemm **	Side Effects:
2318c2aa98e2SPeter Wemm **		Sets process title when it is rejecting connections.
2319c2aa98e2SPeter Wemm */
2320c2aa98e2SPeter Wemm 
2321c2aa98e2SPeter Wemm bool
23223299c2f1SGregory Neil Shapiro refuseconnections(name, e, d)
23233299c2f1SGregory Neil Shapiro 	char *name;
23243299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
23253299c2f1SGregory Neil Shapiro 	int d;
2326c2aa98e2SPeter Wemm {
2327c2aa98e2SPeter Wemm #ifdef XLA
2328c2aa98e2SPeter Wemm 	if (!xla_smtp_ok())
2329c2aa98e2SPeter Wemm 		return TRUE;
23303299c2f1SGregory Neil Shapiro #endif /* XLA */
2331c2aa98e2SPeter Wemm 
2332c46d91b7SGregory Neil Shapiro 	CurrentLA = sm_getla(NULL);
23333299c2f1SGregory Neil Shapiro 	if (RefuseLA > 0 && CurrentLA >= RefuseLA)
2334c2aa98e2SPeter Wemm 	{
23353299c2f1SGregory Neil Shapiro 		sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: load average: %d",
23363299c2f1SGregory Neil Shapiro 				name, CurrentLA);
23373299c2f1SGregory Neil Shapiro 		if (LogLevel >= 9)
2338c2aa98e2SPeter Wemm 			sm_syslog(LOG_INFO, NOQID,
23393299c2f1SGregory Neil Shapiro 				"rejecting connections on daemon %s: load average: %d",
23403299c2f1SGregory Neil Shapiro 				name, CurrentLA);
2341c2aa98e2SPeter Wemm 		return TRUE;
2342c2aa98e2SPeter Wemm 	}
2343c2aa98e2SPeter Wemm 
2344c2aa98e2SPeter Wemm 	if (MaxChildren > 0 && CurChildren >= MaxChildren)
2345c2aa98e2SPeter Wemm 	{
2346c2aa98e2SPeter Wemm 		proc_list_probe();
2347c2aa98e2SPeter Wemm 		if (CurChildren >= MaxChildren)
2348c2aa98e2SPeter Wemm 		{
23493299c2f1SGregory Neil Shapiro 			sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: %d children, max %d",
23503299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
23513299c2f1SGregory Neil Shapiro 			if (LogLevel >= 9)
2352c2aa98e2SPeter Wemm 				sm_syslog(LOG_INFO, NOQID,
23533299c2f1SGregory Neil Shapiro 					"rejecting connections on daemon %s: %d children, max %d",
23543299c2f1SGregory Neil Shapiro 					name, CurChildren, MaxChildren);
2355c2aa98e2SPeter Wemm 			return TRUE;
2356c2aa98e2SPeter Wemm 		}
2357c2aa98e2SPeter Wemm 	}
2358c2aa98e2SPeter Wemm 
2359c2aa98e2SPeter Wemm 	return FALSE;
2360c2aa98e2SPeter Wemm }
2361c2aa98e2SPeter Wemm /*
2362c2aa98e2SPeter Wemm **  SETPROCTITLE -- set process title for ps
2363c2aa98e2SPeter Wemm **
2364c2aa98e2SPeter Wemm **	Parameters:
2365c2aa98e2SPeter Wemm **		fmt -- a printf style format string.
2366c2aa98e2SPeter Wemm **		a, b, c -- possible parameters to fmt.
2367c2aa98e2SPeter Wemm **
2368c2aa98e2SPeter Wemm **	Returns:
2369c2aa98e2SPeter Wemm **		none.
2370c2aa98e2SPeter Wemm **
2371c2aa98e2SPeter Wemm **	Side Effects:
2372c2aa98e2SPeter Wemm **		Clobbers argv of our main procedure so ps(1) will
2373c2aa98e2SPeter Wemm **		display the title.
2374c2aa98e2SPeter Wemm */
2375c2aa98e2SPeter Wemm 
2376c2aa98e2SPeter Wemm #define SPT_NONE	0	/* don't use it at all */
2377c2aa98e2SPeter Wemm #define SPT_REUSEARGV	1	/* cover argv with title information */
2378c2aa98e2SPeter Wemm #define SPT_BUILTIN	2	/* use libc builtin */
2379c2aa98e2SPeter Wemm #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
2380c2aa98e2SPeter Wemm #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
2381c2aa98e2SPeter Wemm #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
2382c2aa98e2SPeter Wemm #define SPT_SCO		6	/* write kernel u. area */
2383c2aa98e2SPeter Wemm #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
2384c2aa98e2SPeter Wemm 
2385c2aa98e2SPeter Wemm #ifndef SPT_TYPE
2386c2aa98e2SPeter Wemm # define SPT_TYPE	SPT_REUSEARGV
23873299c2f1SGregory Neil Shapiro #endif /* ! SPT_TYPE */
23883299c2f1SGregory Neil Shapiro 
2389c2aa98e2SPeter Wemm 
2390c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
2391c2aa98e2SPeter Wemm 
2392c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT
2393c2aa98e2SPeter Wemm #  include <sys/pstat.h>
23943299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSTAT */
2395c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS
2396c2aa98e2SPeter Wemm #  include <machine/vmparam.h>
2397c2aa98e2SPeter Wemm #  include <sys/exec.h>
2398c2aa98e2SPeter Wemm #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
2399c2aa98e2SPeter Wemm #   undef SPT_TYPE
2400c2aa98e2SPeter Wemm #   define SPT_TYPE	SPT_REUSEARGV
24013299c2f1SGregory Neil Shapiro #  else /* ! PS_STRINGS */
2402c2aa98e2SPeter Wemm #   ifndef NKPDE			/* FreeBSD 2.0 */
2403c2aa98e2SPeter Wemm #    define NKPDE 63
2404c2aa98e2SPeter Wemm typedef unsigned int	*pt_entry_t;
24053299c2f1SGregory Neil Shapiro #   endif /* ! NKPDE */
24063299c2f1SGregory Neil Shapiro #  endif /* ! PS_STRINGS */
24073299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */
2408c2aa98e2SPeter Wemm 
2409c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
2410c2aa98e2SPeter Wemm #  define SETPROC_STATIC	static
24113299c2f1SGregory Neil Shapiro # else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2412c2aa98e2SPeter Wemm #  define SETPROC_STATIC
24133299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
2414c2aa98e2SPeter Wemm 
2415c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS
2416c2aa98e2SPeter Wemm #  include <sys/sysmips.h>
2417c2aa98e2SPeter Wemm #  include <sys/sysnews.h>
24183299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SYSMIPS */
2419c2aa98e2SPeter Wemm 
2420c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO
2421c2aa98e2SPeter Wemm #  include <sys/immu.h>
2422c2aa98e2SPeter Wemm #  include <sys/dir.h>
2423c2aa98e2SPeter Wemm #  include <sys/user.h>
2424c2aa98e2SPeter Wemm #  include <sys/fs/s5param.h>
2425c2aa98e2SPeter Wemm #  if PSARGSZ > MAXLINE
2426c2aa98e2SPeter Wemm #   define SPT_BUFSIZE	PSARGSZ
24273299c2f1SGregory Neil Shapiro #  endif /* PSARGSZ > MAXLINE */
24283299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */
2429c2aa98e2SPeter Wemm 
2430c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR
2431c2aa98e2SPeter Wemm #  define SPT_PADCHAR	' '
24323299c2f1SGregory Neil Shapiro # endif /* ! SPT_PADCHAR */
2433c2aa98e2SPeter Wemm 
243476b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
243576b7bf71SPeter Wemm 
2436c2aa98e2SPeter Wemm #ifndef SPT_BUFSIZE
2437c2aa98e2SPeter Wemm # define SPT_BUFSIZE	MAXLINE
24383299c2f1SGregory Neil Shapiro #endif /* ! SPT_BUFSIZE */
2439c2aa98e2SPeter Wemm 
2440c2aa98e2SPeter Wemm /*
2441c2aa98e2SPeter Wemm **  Pointers for setproctitle.
2442c2aa98e2SPeter Wemm **	This allows "ps" listings to give more useful information.
2443c2aa98e2SPeter Wemm */
2444c2aa98e2SPeter Wemm 
24453299c2f1SGregory Neil Shapiro static char	**Argv = NULL;		/* pointer to argument vector */
24463299c2f1SGregory Neil Shapiro static char	*LastArgv = NULL;	/* end of argv */
24473299c2f1SGregory Neil Shapiro #if SPT_TYPE != SPT_BUILTIN
24483299c2f1SGregory Neil Shapiro static void	setproctitle __P((const char *, ...));
24493299c2f1SGregory Neil Shapiro #endif /* SPT_TYPE != SPT_BUILTIN */
2450c2aa98e2SPeter Wemm 
2451c2aa98e2SPeter Wemm void
2452c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp)
2453c2aa98e2SPeter Wemm 	int argc;
2454c2aa98e2SPeter Wemm 	char **argv;
2455c2aa98e2SPeter Wemm 	char **envp;
2456c2aa98e2SPeter Wemm {
2457c2aa98e2SPeter Wemm 	register int i, envpsize = 0;
2458c2aa98e2SPeter Wemm 	extern char **environ;
2459c2aa98e2SPeter Wemm 
2460c2aa98e2SPeter Wemm 	/*
2461c2aa98e2SPeter Wemm 	**  Move the environment so setproctitle can use the space at
2462c2aa98e2SPeter Wemm 	**  the top of memory.
2463c2aa98e2SPeter Wemm 	*/
2464c2aa98e2SPeter Wemm 
2465c2aa98e2SPeter Wemm 	for (i = 0; envp[i] != NULL; i++)
2466c2aa98e2SPeter Wemm 		envpsize += strlen(envp[i]) + 1;
2467c2aa98e2SPeter Wemm 	environ = (char **) xalloc(sizeof (char *) * (i + 1));
2468c2aa98e2SPeter Wemm 	for (i = 0; envp[i] != NULL; i++)
2469c2aa98e2SPeter Wemm 		environ[i] = newstr(envp[i]);
2470c2aa98e2SPeter Wemm 	environ[i] = NULL;
2471c2aa98e2SPeter Wemm 
2472c2aa98e2SPeter Wemm 	/*
2473c2aa98e2SPeter Wemm 	**  Save start and extent of argv for setproctitle.
2474c2aa98e2SPeter Wemm 	*/
2475c2aa98e2SPeter Wemm 
2476c2aa98e2SPeter Wemm 	Argv = argv;
2477c2aa98e2SPeter Wemm 
2478c2aa98e2SPeter Wemm 	/*
2479c2aa98e2SPeter Wemm 	**  Determine how much space we can use for setproctitle.
2480c2aa98e2SPeter Wemm 	**  Use all contiguous argv and envp pointers starting at argv[0]
2481c2aa98e2SPeter Wemm 	*/
2482c2aa98e2SPeter Wemm 	for (i = 0; i < argc; i++)
2483c2aa98e2SPeter Wemm 	{
2484c2aa98e2SPeter Wemm 		if (i == 0 || LastArgv + 1 == argv[i])
2485c2aa98e2SPeter Wemm 			LastArgv = argv[i] + strlen(argv[i]);
2486c2aa98e2SPeter Wemm 	}
24873299c2f1SGregory Neil Shapiro 	for (i = 0; LastArgv != NULL && envp[i] != NULL; i++)
2488c2aa98e2SPeter Wemm 	{
2489c2aa98e2SPeter Wemm 		if (LastArgv + 1 == envp[i])
2490c2aa98e2SPeter Wemm 			LastArgv = envp[i] + strlen(envp[i]);
2491c2aa98e2SPeter Wemm 	}
2492c2aa98e2SPeter Wemm }
2493c2aa98e2SPeter Wemm 
2494c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN
2495c2aa98e2SPeter Wemm 
2496c2aa98e2SPeter Wemm /*VARARGS1*/
24973299c2f1SGregory Neil Shapiro static void
2498c2aa98e2SPeter Wemm # ifdef __STDC__
2499c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...)
25003299c2f1SGregory Neil Shapiro # else /* __STDC__ */
2501c2aa98e2SPeter Wemm setproctitle(fmt, va_alist)
2502c2aa98e2SPeter Wemm 	const char *fmt;
2503c2aa98e2SPeter Wemm 	va_dcl
25043299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
2505c2aa98e2SPeter Wemm {
2506c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE
2507c2aa98e2SPeter Wemm 	register int i;
25083299c2f1SGregory Neil Shapiro 	register char *p;
2509c2aa98e2SPeter Wemm 	SETPROC_STATIC char buf[SPT_BUFSIZE];
2510c2aa98e2SPeter Wemm 	VA_LOCAL_DECL
2511c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2512c2aa98e2SPeter Wemm 	union pstun pst;
25133299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2514c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
2515c2aa98e2SPeter Wemm 	off_t seek_off;
2516c2aa98e2SPeter Wemm 	static int kmem = -1;
2517c0c4794dSGregory Neil Shapiro 	static pid_t kmempid = -1;
2518c2aa98e2SPeter Wemm 	struct user u;
25193299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2520c2aa98e2SPeter Wemm 
2521c2aa98e2SPeter Wemm 	p = buf;
2522c2aa98e2SPeter Wemm 
2523c2aa98e2SPeter Wemm 	/* print sendmail: heading for grep */
25243299c2f1SGregory Neil Shapiro 	(void) strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
2525c2aa98e2SPeter Wemm 	p += strlen(p);
2526c2aa98e2SPeter Wemm 
2527c2aa98e2SPeter Wemm 	/* print the argument string */
2528c2aa98e2SPeter Wemm 	VA_START(fmt);
2529c2aa98e2SPeter Wemm 	(void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
2530c2aa98e2SPeter Wemm 	VA_END;
2531c2aa98e2SPeter Wemm 
2532c2aa98e2SPeter Wemm 	i = strlen(buf);
2533c2aa98e2SPeter Wemm 
2534c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2535c2aa98e2SPeter Wemm 	pst.pst_command = buf;
2536c2aa98e2SPeter Wemm 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
25373299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSTAT */
2538c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSSTRINGS
2539c2aa98e2SPeter Wemm 	PS_STRINGS->ps_nargvstr = 1;
2540c2aa98e2SPeter Wemm 	PS_STRINGS->ps_argvstr = buf;
25413299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_PSSTRINGS */
2542c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SYSMIPS
2543c2aa98e2SPeter Wemm 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
25443299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SYSMIPS */
2545c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
2546c2aa98e2SPeter Wemm 	if (kmem < 0 || kmempid != getpid())
2547c2aa98e2SPeter Wemm 	{
2548c2aa98e2SPeter Wemm 		if (kmem >= 0)
2549c46d91b7SGregory Neil Shapiro 			(void) close(kmem);
2550c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, O_RDWR, 0);
2551c2aa98e2SPeter Wemm 		if (kmem < 0)
2552c2aa98e2SPeter Wemm 			return;
25533299c2f1SGregory Neil Shapiro 		(void) fcntl(kmem, F_SETFD, FD_CLOEXEC);
2554c2aa98e2SPeter Wemm 		kmempid = getpid();
2555c2aa98e2SPeter Wemm 	}
2556c2aa98e2SPeter Wemm 	buf[PSARGSZ - 1] = '\0';
2557c2aa98e2SPeter Wemm 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
2558c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
2559c2aa98e2SPeter Wemm 		(void) write(kmem, buf, PSARGSZ);
25603299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2561c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_REUSEARGV
25623299c2f1SGregory Neil Shapiro 	if (LastArgv == NULL)
25633299c2f1SGregory Neil Shapiro 		return;
25643299c2f1SGregory Neil Shapiro 
2565c2aa98e2SPeter Wemm 	if (i > LastArgv - Argv[0] - 2)
2566c2aa98e2SPeter Wemm 	{
2567c2aa98e2SPeter Wemm 		i = LastArgv - Argv[0] - 2;
2568c2aa98e2SPeter Wemm 		buf[i] = '\0';
2569c2aa98e2SPeter Wemm 	}
25703299c2f1SGregory Neil Shapiro 	(void) strlcpy(Argv[0], buf, i + 1);
2571c2aa98e2SPeter Wemm 	p = &Argv[0][i];
2572c2aa98e2SPeter Wemm 	while (p < LastArgv)
2573c2aa98e2SPeter Wemm 		*p++ = SPT_PADCHAR;
2574c2aa98e2SPeter Wemm 	Argv[1] = NULL;
25753299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_REUSEARGV */
2576c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_CHANGEARGV
2577c2aa98e2SPeter Wemm 	Argv[0] = buf;
2578c2aa98e2SPeter Wemm 	Argv[1] = 0;
25793299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_CHANGEARGV */
2580c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */
2581c2aa98e2SPeter Wemm }
2582c2aa98e2SPeter Wemm 
2583c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */
2584c2aa98e2SPeter Wemm /*
258576b7bf71SPeter Wemm **  SM_SETPROCTITLE -- set process task and set process title for ps
258676b7bf71SPeter Wemm **
258776b7bf71SPeter Wemm **	Possibly set process status and call setproctitle() to
258876b7bf71SPeter Wemm **	change the ps display.
258976b7bf71SPeter Wemm **
259076b7bf71SPeter Wemm **	Parameters:
259176b7bf71SPeter Wemm **		status -- whether or not to store as process status
25923299c2f1SGregory Neil Shapiro **		e -- the current envelope.
259376b7bf71SPeter Wemm **		fmt -- a printf style format string.
259476b7bf71SPeter Wemm **		a, b, c -- possible parameters to fmt.
259576b7bf71SPeter Wemm **
259676b7bf71SPeter Wemm **	Returns:
259776b7bf71SPeter Wemm **		none.
259876b7bf71SPeter Wemm */
259976b7bf71SPeter Wemm 
260076b7bf71SPeter Wemm /*VARARGS2*/
260176b7bf71SPeter Wemm void
260276b7bf71SPeter Wemm #ifdef __STDC__
26033299c2f1SGregory Neil Shapiro sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
26043299c2f1SGregory Neil Shapiro #else /* __STDC__ */
26053299c2f1SGregory Neil Shapiro sm_setproctitle(status, e, fmt, va_alist)
260676b7bf71SPeter Wemm 	bool status;
26073299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
260876b7bf71SPeter Wemm 	const char *fmt;
260976b7bf71SPeter Wemm 	va_dcl
26103299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
261176b7bf71SPeter Wemm {
261276b7bf71SPeter Wemm 	char buf[SPT_BUFSIZE];
261376b7bf71SPeter Wemm 	VA_LOCAL_DECL
26143299c2f1SGregory Neil Shapiro 
261576b7bf71SPeter Wemm 	/* print the argument string */
261676b7bf71SPeter Wemm 	VA_START(fmt);
26173299c2f1SGregory Neil Shapiro 	(void) vsnprintf(buf, sizeof buf, fmt, ap);
261876b7bf71SPeter Wemm 	VA_END;
261976b7bf71SPeter Wemm 
262076b7bf71SPeter Wemm 	if (status)
262176b7bf71SPeter Wemm 		proc_list_set(getpid(), buf);
26223299c2f1SGregory Neil Shapiro 
26233299c2f1SGregory Neil Shapiro 	if (ProcTitlePrefix != NULL)
26243299c2f1SGregory Neil Shapiro 	{
26253299c2f1SGregory Neil Shapiro 		char prefix[SPT_BUFSIZE];
26263299c2f1SGregory Neil Shapiro 
26273299c2f1SGregory Neil Shapiro 		expand(ProcTitlePrefix, prefix, sizeof prefix, e);
26283299c2f1SGregory Neil Shapiro 		setproctitle("%s: %s", prefix, buf);
26293299c2f1SGregory Neil Shapiro 	}
26303299c2f1SGregory Neil Shapiro 	else
263176b7bf71SPeter Wemm 		setproctitle("%s", buf);
263276b7bf71SPeter Wemm }
263376b7bf71SPeter Wemm /*
2634c2aa98e2SPeter Wemm **  WAITFOR -- wait for a particular process id.
2635c2aa98e2SPeter Wemm **
2636c2aa98e2SPeter Wemm **	Parameters:
2637c2aa98e2SPeter Wemm **		pid -- process id to wait for.
2638c2aa98e2SPeter Wemm **
2639c2aa98e2SPeter Wemm **	Returns:
2640c2aa98e2SPeter Wemm **		status of pid.
2641c2aa98e2SPeter Wemm **		-1 if pid never shows up.
2642c2aa98e2SPeter Wemm **
2643c2aa98e2SPeter Wemm **	Side Effects:
2644c2aa98e2SPeter Wemm **		none.
2645c2aa98e2SPeter Wemm */
2646c2aa98e2SPeter Wemm 
2647c2aa98e2SPeter Wemm int
2648c2aa98e2SPeter Wemm waitfor(pid)
2649c2aa98e2SPeter Wemm 	pid_t pid;
2650c2aa98e2SPeter Wemm {
2651c2aa98e2SPeter Wemm # ifdef WAITUNION
2652c2aa98e2SPeter Wemm 	union wait st;
26533299c2f1SGregory Neil Shapiro # else /* WAITUNION */
2654c2aa98e2SPeter Wemm 	auto int st;
26553299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
2656c2aa98e2SPeter Wemm 	pid_t i;
2657c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2658c2aa98e2SPeter Wemm 	int savesig;
26593299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2660c2aa98e2SPeter Wemm 
2661c2aa98e2SPeter Wemm 	do
2662c2aa98e2SPeter Wemm 	{
2663c2aa98e2SPeter Wemm 		errno = 0;
2664c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2665c2aa98e2SPeter Wemm 		savesig = releasesignal(SIGCHLD);
26663299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2667c2aa98e2SPeter Wemm 		i = wait(&st);
2668c2aa98e2SPeter Wemm # if defined(ISC_UNIX) || defined(_SCO_unix_)
2669c2aa98e2SPeter Wemm 		if (savesig > 0)
2670c2aa98e2SPeter Wemm 			blocksignal(SIGCHLD);
26713299c2f1SGregory Neil Shapiro # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
2672c2aa98e2SPeter Wemm 		if (i > 0)
26733299c2f1SGregory Neil Shapiro 			(void) proc_list_drop(i);
2674c2aa98e2SPeter Wemm 	} while ((i >= 0 || errno == EINTR) && i != pid);
2675c2aa98e2SPeter Wemm 	if (i < 0)
2676c2aa98e2SPeter Wemm 		return -1;
2677c2aa98e2SPeter Wemm # ifdef WAITUNION
2678c2aa98e2SPeter Wemm 	return st.w_status;
26793299c2f1SGregory Neil Shapiro # else /* WAITUNION */
2680c2aa98e2SPeter Wemm 	return st;
26813299c2f1SGregory Neil Shapiro # endif /* WAITUNION */
2682c2aa98e2SPeter Wemm }
2683c2aa98e2SPeter Wemm /*
2684c2aa98e2SPeter Wemm **  REAPCHILD -- pick up the body of my child, lest it become a zombie
2685c2aa98e2SPeter Wemm **
2686c2aa98e2SPeter Wemm **	Parameters:
2687c2aa98e2SPeter Wemm **		sig -- the signal that got us here (unused).
2688c2aa98e2SPeter Wemm **
2689c2aa98e2SPeter Wemm **	Returns:
2690c2aa98e2SPeter Wemm **		none.
2691c2aa98e2SPeter Wemm **
2692c2aa98e2SPeter Wemm **	Side Effects:
2693c2aa98e2SPeter Wemm **		Picks up extant zombies.
26943299c2f1SGregory Neil Shapiro **		Control socket exits may restart/shutdown daemon.
2695c0c4794dSGregory Neil Shapiro **
2696c0c4794dSGregory Neil Shapiro **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
2697c0c4794dSGregory Neil Shapiro **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
2698c0c4794dSGregory Neil Shapiro **		DOING.
2699c2aa98e2SPeter Wemm */
2700c2aa98e2SPeter Wemm 
27013299c2f1SGregory Neil Shapiro /* ARGSUSED0 */
2702c2aa98e2SPeter Wemm SIGFUNC_DECL
2703c2aa98e2SPeter Wemm reapchild(sig)
2704c2aa98e2SPeter Wemm 	int sig;
2705c2aa98e2SPeter Wemm {
27063299c2f1SGregory Neil Shapiro 	int save_errno = errno;
27073299c2f1SGregory Neil Shapiro 	int st;
2708c2aa98e2SPeter Wemm 	pid_t pid;
27093299c2f1SGregory Neil Shapiro # if HASWAITPID
2710c2aa98e2SPeter Wemm 	auto int status;
2711c2aa98e2SPeter Wemm 	int count;
2712c0c4794dSGregory Neil Shapiro # else /* HASWAITPID */
2713c0c4794dSGregory Neil Shapiro #  ifdef WNOHANG
2714c0c4794dSGregory Neil Shapiro 	union wait status;
2715c0c4794dSGregory Neil Shapiro #  else /* WNOHANG */
2716c0c4794dSGregory Neil Shapiro 	auto int status;
2717c0c4794dSGregory Neil Shapiro #  endif /* WNOHANG */
2718c0c4794dSGregory Neil Shapiro # endif /* HASWAITPID */
2719c2aa98e2SPeter Wemm 
2720c0c4794dSGregory Neil Shapiro # if HASWAITPID
2721c2aa98e2SPeter Wemm 	count = 0;
2722c2aa98e2SPeter Wemm 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2723c2aa98e2SPeter Wemm 	{
27243299c2f1SGregory Neil Shapiro 		st = status;
2725c2aa98e2SPeter Wemm 		if (count++ > 1000)
2726c2aa98e2SPeter Wemm 			break;
27273299c2f1SGregory Neil Shapiro # else /* HASWAITPID */
2728c2aa98e2SPeter Wemm #  ifdef WNOHANG
2729c2aa98e2SPeter Wemm 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
27303299c2f1SGregory Neil Shapiro 	{
27313299c2f1SGregory Neil Shapiro 		st = status.w_status;
2732c2aa98e2SPeter Wemm #  else /* WNOHANG */
2733c2aa98e2SPeter Wemm 	/*
2734c2aa98e2SPeter Wemm 	**  Catch one zombie -- we will be re-invoked (we hope) if there
2735c2aa98e2SPeter Wemm 	**  are more.  Unreliable signals probably break this, but this
2736c2aa98e2SPeter Wemm 	**  is the "old system" situation -- waitpid or wait3 are to be
2737c2aa98e2SPeter Wemm 	**  strongly preferred.
2738c2aa98e2SPeter Wemm 	*/
2739c2aa98e2SPeter Wemm 
2740c2aa98e2SPeter Wemm 	if ((pid = wait(&status)) > 0)
27413299c2f1SGregory Neil Shapiro 	{
27423299c2f1SGregory Neil Shapiro 		st = status;
2743c2aa98e2SPeter Wemm #  endif /* WNOHANG */
27443299c2f1SGregory Neil Shapiro # endif /* HASWAITPID */
27453299c2f1SGregory Neil Shapiro 		/* Drop PID and check if it was a control socket child */
27463299c2f1SGregory Neil Shapiro 		if (proc_list_drop(pid) == PROC_CONTROL &&
27473299c2f1SGregory Neil Shapiro 		    WIFEXITED(st))
27483299c2f1SGregory Neil Shapiro 		{
27493299c2f1SGregory Neil Shapiro 			/* if so, see if we need to restart or shutdown */
27503299c2f1SGregory Neil Shapiro 			if (WEXITSTATUS(st) == EX_RESTART)
27513299c2f1SGregory Neil Shapiro 			{
2752c0c4794dSGregory Neil Shapiro 				RestartRequest = "control socket";
27533299c2f1SGregory Neil Shapiro 			}
27543299c2f1SGregory Neil Shapiro 			else if (WEXITSTATUS(st) == EX_SHUTDOWN)
27553299c2f1SGregory Neil Shapiro 			{
27563299c2f1SGregory Neil Shapiro 				/* emulate a SIGTERM shutdown */
2757c0c4794dSGregory Neil Shapiro 				ShutdownRequest = "control socket";
27583299c2f1SGregory Neil Shapiro 				/* NOTREACHED */
27593299c2f1SGregory Neil Shapiro 			}
27603299c2f1SGregory Neil Shapiro 		}
27613299c2f1SGregory Neil Shapiro 	}
2762c0c4794dSGregory Neil Shapiro 	FIX_SYSV_SIGNAL(sig, reapchild);
27633299c2f1SGregory Neil Shapiro 	errno = save_errno;
2764c2aa98e2SPeter Wemm 	return SIGFUNC_RETURN;
2765c2aa98e2SPeter Wemm }
2766c2aa98e2SPeter Wemm /*
2767c2aa98e2SPeter Wemm **  PUTENV -- emulation of putenv() in terms of setenv()
2768c2aa98e2SPeter Wemm **
2769c2aa98e2SPeter Wemm **	Not needed on Posix-compliant systems.
2770c2aa98e2SPeter Wemm **	This doesn't have full Posix semantics, but it's good enough
2771c2aa98e2SPeter Wemm **		for sendmail.
2772c2aa98e2SPeter Wemm **
2773c2aa98e2SPeter Wemm **	Parameter:
2774c2aa98e2SPeter Wemm **		env -- the environment to put.
2775c2aa98e2SPeter Wemm **
2776c2aa98e2SPeter Wemm **	Returns:
2777c2aa98e2SPeter Wemm **		none.
2778c2aa98e2SPeter Wemm */
2779c2aa98e2SPeter Wemm 
27803299c2f1SGregory Neil Shapiro #if NEEDPUTENV
2781c2aa98e2SPeter Wemm 
2782c2aa98e2SPeter Wemm # if NEEDPUTENV == 2		/* no setenv(3) call available */
2783c2aa98e2SPeter Wemm 
2784c2aa98e2SPeter Wemm int
2785c2aa98e2SPeter Wemm putenv(str)
2786c2aa98e2SPeter Wemm 	char *str;
2787c2aa98e2SPeter Wemm {
2788c2aa98e2SPeter Wemm 	char **current;
2789c2aa98e2SPeter Wemm 	int matchlen, envlen = 0;
2790c2aa98e2SPeter Wemm 	char *tmp;
2791c2aa98e2SPeter Wemm 	char **newenv;
27923299c2f1SGregory Neil Shapiro 	static bool first = TRUE;
2793c2aa98e2SPeter Wemm 	extern char **environ;
2794c2aa98e2SPeter Wemm 
2795c2aa98e2SPeter Wemm 	/*
2796c2aa98e2SPeter Wemm 	 * find out how much of str to match when searching
2797c2aa98e2SPeter Wemm 	 * for a string to replace.
2798c2aa98e2SPeter Wemm 	 */
2799c2aa98e2SPeter Wemm 	if ((tmp = strchr(str, '=')) == NULL || tmp == str)
2800c2aa98e2SPeter Wemm 		matchlen = strlen(str);
2801c2aa98e2SPeter Wemm 	else
2802c2aa98e2SPeter Wemm 		matchlen = (int) (tmp - str);
2803c2aa98e2SPeter Wemm 	++matchlen;
2804c2aa98e2SPeter Wemm 
2805c2aa98e2SPeter Wemm 	/*
2806c2aa98e2SPeter Wemm 	 * Search for an existing string in the environment and find the
2807c2aa98e2SPeter Wemm 	 * length of environ.  If found, replace and exit.
2808c2aa98e2SPeter Wemm 	 */
28093299c2f1SGregory Neil Shapiro 	for (current = environ; *current; current++)
28103299c2f1SGregory Neil Shapiro 	{
2811c2aa98e2SPeter Wemm 		++envlen;
2812c2aa98e2SPeter Wemm 
28133299c2f1SGregory Neil Shapiro 		if (strncmp(str, *current, matchlen) == 0)
28143299c2f1SGregory Neil Shapiro 		{
2815c2aa98e2SPeter Wemm 			/* found it, now insert the new version */
2816c2aa98e2SPeter Wemm 			*current = (char *)str;
28173299c2f1SGregory Neil Shapiro 			return 0;
2818c2aa98e2SPeter Wemm 		}
2819c2aa98e2SPeter Wemm 	}
2820c2aa98e2SPeter Wemm 
2821c2aa98e2SPeter Wemm 	/*
2822c2aa98e2SPeter Wemm 	 * There wasn't already a slot so add space for a new slot.
2823c2aa98e2SPeter Wemm 	 * If this is our first time through, use malloc(), else realloc().
2824c2aa98e2SPeter Wemm 	 */
28253299c2f1SGregory Neil Shapiro 	if (first)
28263299c2f1SGregory Neil Shapiro 	{
2827c0c4794dSGregory Neil Shapiro 		newenv = (char **) xalloc(sizeof(char *) * (envlen + 2));
28283299c2f1SGregory Neil Shapiro 		first = FALSE;
2829c2aa98e2SPeter Wemm 		(void) memcpy(newenv, environ, sizeof(char *) * envlen);
28303299c2f1SGregory Neil Shapiro 	}
28313299c2f1SGregory Neil Shapiro 	else
28323299c2f1SGregory Neil Shapiro 	{
2833c0c4794dSGregory Neil Shapiro 		newenv = (char **) xrealloc((char *)environ,
2834c0c4794dSGregory Neil Shapiro 					    sizeof(char *) * (envlen + 2));
2835c2aa98e2SPeter Wemm 	}
2836c2aa98e2SPeter Wemm 
2837c2aa98e2SPeter Wemm 	/* actually add in the new entry */
2838c2aa98e2SPeter Wemm 	environ = newenv;
2839c2aa98e2SPeter Wemm 	environ[envlen] = (char *)str;
2840c2aa98e2SPeter Wemm 	environ[envlen + 1] = NULL;
2841c2aa98e2SPeter Wemm 
28423299c2f1SGregory Neil Shapiro 	return 0;
2843c2aa98e2SPeter Wemm }
2844c2aa98e2SPeter Wemm 
28453299c2f1SGregory Neil Shapiro # else /* NEEDPUTENV == 2 */
2846c2aa98e2SPeter Wemm 
2847c2aa98e2SPeter Wemm int
2848c2aa98e2SPeter Wemm putenv(env)
2849c2aa98e2SPeter Wemm 	char *env;
2850c2aa98e2SPeter Wemm {
2851c2aa98e2SPeter Wemm 	char *p;
2852c2aa98e2SPeter Wemm 	int l;
2853c2aa98e2SPeter Wemm 	char nbuf[100];
2854c2aa98e2SPeter Wemm 
2855c2aa98e2SPeter Wemm 	p = strchr(env, '=');
2856c2aa98e2SPeter Wemm 	if (p == NULL)
2857c2aa98e2SPeter Wemm 		return 0;
2858c2aa98e2SPeter Wemm 	l = p - env;
2859c2aa98e2SPeter Wemm 	if (l > sizeof nbuf - 1)
2860c2aa98e2SPeter Wemm 		l = sizeof nbuf - 1;
28613299c2f1SGregory Neil Shapiro 	memmove(nbuf, env, l);
2862c2aa98e2SPeter Wemm 	nbuf[l] = '\0';
2863c2aa98e2SPeter Wemm 	return setenv(nbuf, ++p, 1);
2864c2aa98e2SPeter Wemm }
2865c2aa98e2SPeter Wemm 
28663299c2f1SGregory Neil Shapiro # endif /* NEEDPUTENV == 2 */
28673299c2f1SGregory Neil Shapiro #endif /* NEEDPUTENV */
2868c2aa98e2SPeter Wemm /*
2869c2aa98e2SPeter Wemm **  UNSETENV -- remove a variable from the environment
2870c2aa98e2SPeter Wemm **
2871c2aa98e2SPeter Wemm **	Not needed on newer systems.
2872c2aa98e2SPeter Wemm **
2873c2aa98e2SPeter Wemm **	Parameters:
2874c2aa98e2SPeter Wemm **		name -- the string name of the environment variable to be
2875c2aa98e2SPeter Wemm **			deleted from the current environment.
2876c2aa98e2SPeter Wemm **
2877c2aa98e2SPeter Wemm **	Returns:
2878c2aa98e2SPeter Wemm **		none.
2879c2aa98e2SPeter Wemm **
2880c2aa98e2SPeter Wemm **	Globals:
2881c2aa98e2SPeter Wemm **		environ -- a pointer to the current environment.
2882c2aa98e2SPeter Wemm **
2883c2aa98e2SPeter Wemm **	Side Effects:
2884c2aa98e2SPeter Wemm **		Modifies environ.
2885c2aa98e2SPeter Wemm */
2886c2aa98e2SPeter Wemm 
28873299c2f1SGregory Neil Shapiro #if !HASUNSETENV
2888c2aa98e2SPeter Wemm 
2889c2aa98e2SPeter Wemm void
2890c2aa98e2SPeter Wemm unsetenv(name)
2891c2aa98e2SPeter Wemm 	char *name;
2892c2aa98e2SPeter Wemm {
2893c2aa98e2SPeter Wemm 	extern char **environ;
2894c2aa98e2SPeter Wemm 	register char **pp;
2895c2aa98e2SPeter Wemm 	int len = strlen(name);
2896c2aa98e2SPeter Wemm 
2897c2aa98e2SPeter Wemm 	for (pp = environ; *pp != NULL; pp++)
2898c2aa98e2SPeter Wemm 	{
2899c2aa98e2SPeter Wemm 		if (strncmp(name, *pp, len) == 0 &&
2900c2aa98e2SPeter Wemm 		    ((*pp)[len] == '=' || (*pp)[len] == '\0'))
2901c2aa98e2SPeter Wemm 			break;
2902c2aa98e2SPeter Wemm 	}
2903c2aa98e2SPeter Wemm 
2904c2aa98e2SPeter Wemm 	for (; *pp != NULL; pp++)
2905c2aa98e2SPeter Wemm 		*pp = pp[1];
2906c2aa98e2SPeter Wemm }
2907c2aa98e2SPeter Wemm 
29083299c2f1SGregory Neil Shapiro #endif /* !HASUNSETENV */
2909c2aa98e2SPeter Wemm /*
2910c2aa98e2SPeter Wemm **  GETDTABLESIZE -- return number of file descriptors
2911c2aa98e2SPeter Wemm **
2912c2aa98e2SPeter Wemm **	Only on non-BSD systems
2913c2aa98e2SPeter Wemm **
2914c2aa98e2SPeter Wemm **	Parameters:
2915c2aa98e2SPeter Wemm **		none
2916c2aa98e2SPeter Wemm **
2917c2aa98e2SPeter Wemm **	Returns:
2918c2aa98e2SPeter Wemm **		size of file descriptor table
2919c2aa98e2SPeter Wemm **
2920c2aa98e2SPeter Wemm **	Side Effects:
2921c2aa98e2SPeter Wemm **		none
2922c2aa98e2SPeter Wemm */
2923c2aa98e2SPeter Wemm 
2924c2aa98e2SPeter Wemm #ifdef SOLARIS
2925c2aa98e2SPeter Wemm # include <sys/resource.h>
29263299c2f1SGregory Neil Shapiro #endif /* SOLARIS */
2927c2aa98e2SPeter Wemm 
2928c2aa98e2SPeter Wemm int
2929c2aa98e2SPeter Wemm getdtsize()
2930c2aa98e2SPeter Wemm {
2931c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
2932c2aa98e2SPeter Wemm 	struct rlimit rl;
2933c2aa98e2SPeter Wemm 
2934c2aa98e2SPeter Wemm 	if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2935c2aa98e2SPeter Wemm 		return rl.rlim_cur;
29363299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
2937c2aa98e2SPeter Wemm 
29383299c2f1SGregory Neil Shapiro # if HASGETDTABLESIZE
2939c2aa98e2SPeter Wemm 	return getdtablesize();
29403299c2f1SGregory Neil Shapiro # else /* HASGETDTABLESIZE */
2941c2aa98e2SPeter Wemm #  ifdef _SC_OPEN_MAX
2942c2aa98e2SPeter Wemm 	return sysconf(_SC_OPEN_MAX);
29433299c2f1SGregory Neil Shapiro #  else /* _SC_OPEN_MAX */
2944c2aa98e2SPeter Wemm 	return NOFILE;
29453299c2f1SGregory Neil Shapiro #  endif /* _SC_OPEN_MAX */
29463299c2f1SGregory Neil Shapiro # endif /* HASGETDTABLESIZE */
2947c2aa98e2SPeter Wemm }
2948c2aa98e2SPeter Wemm /*
2949c2aa98e2SPeter Wemm **  UNAME -- get the UUCP name of this system.
2950c2aa98e2SPeter Wemm */
2951c2aa98e2SPeter Wemm 
29523299c2f1SGregory Neil Shapiro #if !HASUNAME
2953c2aa98e2SPeter Wemm 
2954c2aa98e2SPeter Wemm int
2955c2aa98e2SPeter Wemm uname(name)
2956c2aa98e2SPeter Wemm 	struct utsname *name;
2957c2aa98e2SPeter Wemm {
2958c2aa98e2SPeter Wemm 	FILE *file;
2959c2aa98e2SPeter Wemm 	char *n;
2960c2aa98e2SPeter Wemm 
2961c2aa98e2SPeter Wemm 	name->nodename[0] = '\0';
2962c2aa98e2SPeter Wemm 
2963c2aa98e2SPeter Wemm 	/* try /etc/whoami -- one line with the node name */
2964c2aa98e2SPeter Wemm 	if ((file = fopen("/etc/whoami", "r")) != NULL)
2965c2aa98e2SPeter Wemm 	{
2966c2aa98e2SPeter Wemm 		(void) fgets(name->nodename, NODE_LENGTH + 1, file);
2967c2aa98e2SPeter Wemm 		(void) fclose(file);
2968c2aa98e2SPeter Wemm 		n = strchr(name->nodename, '\n');
2969c2aa98e2SPeter Wemm 		if (n != NULL)
2970c2aa98e2SPeter Wemm 			*n = '\0';
2971c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
29723299c2f1SGregory Neil Shapiro 			return 0;
2973c2aa98e2SPeter Wemm 	}
2974c2aa98e2SPeter Wemm 
2975c2aa98e2SPeter Wemm 	/* try /usr/include/whoami.h -- has a #define somewhere */
2976c2aa98e2SPeter Wemm 	if ((file = fopen("/usr/include/whoami.h", "r")) != NULL)
2977c2aa98e2SPeter Wemm 	{
2978c2aa98e2SPeter Wemm 		char buf[MAXLINE];
2979c2aa98e2SPeter Wemm 
2980c2aa98e2SPeter Wemm 		while (fgets(buf, MAXLINE, file) != NULL)
29813299c2f1SGregory Neil Shapiro 		{
2982c2aa98e2SPeter Wemm 			if (sscanf(buf, "#define sysname \"%*[^\"]\"",
2983c2aa98e2SPeter Wemm 					NODE_LENGTH, name->nodename) > 0)
2984c2aa98e2SPeter Wemm 				break;
29853299c2f1SGregory Neil Shapiro 		}
2986c2aa98e2SPeter Wemm 		(void) fclose(file);
2987c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
29883299c2f1SGregory Neil Shapiro 			return 0;
2989c2aa98e2SPeter Wemm 	}
2990c2aa98e2SPeter Wemm 
29913299c2f1SGregory Neil Shapiro #  if 0
2992c2aa98e2SPeter Wemm 	/*
2993c2aa98e2SPeter Wemm 	**  Popen is known to have security holes.
2994c2aa98e2SPeter Wemm 	*/
2995c2aa98e2SPeter Wemm 
2996c2aa98e2SPeter Wemm 	/* try uuname -l to return local name */
2997c2aa98e2SPeter Wemm 	if ((file = popen("uuname -l", "r")) != NULL)
2998c2aa98e2SPeter Wemm 	{
2999c2aa98e2SPeter Wemm 		(void) fgets(name, NODE_LENGTH + 1, file);
3000c2aa98e2SPeter Wemm 		(void) pclose(file);
3001c2aa98e2SPeter Wemm 		n = strchr(name, '\n');
3002c2aa98e2SPeter Wemm 		if (n != NULL)
3003c2aa98e2SPeter Wemm 			*n = '\0';
3004c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
30053299c2f1SGregory Neil Shapiro 			return 0;
3006c2aa98e2SPeter Wemm 	}
30073299c2f1SGregory Neil Shapiro #  endif /* 0 */
3008c2aa98e2SPeter Wemm 
30093299c2f1SGregory Neil Shapiro 	return -1;
3010c2aa98e2SPeter Wemm }
30113299c2f1SGregory Neil Shapiro #endif /* !HASUNAME */
3012c2aa98e2SPeter Wemm /*
3013c2aa98e2SPeter Wemm **  INITGROUPS -- initialize groups
3014c2aa98e2SPeter Wemm **
3015c2aa98e2SPeter Wemm **	Stub implementation for System V style systems
3016c2aa98e2SPeter Wemm */
3017c2aa98e2SPeter Wemm 
30183299c2f1SGregory Neil Shapiro #if !HASINITGROUPS
3019c2aa98e2SPeter Wemm 
3020c2aa98e2SPeter Wemm initgroups(name, basegid)
3021c2aa98e2SPeter Wemm 	char *name;
3022c2aa98e2SPeter Wemm 	int basegid;
3023c2aa98e2SPeter Wemm {
3024c2aa98e2SPeter Wemm 	return 0;
3025c2aa98e2SPeter Wemm }
3026c2aa98e2SPeter Wemm 
30273299c2f1SGregory Neil Shapiro #endif /* !HASINITGROUPS */
3028c2aa98e2SPeter Wemm /*
3029c2aa98e2SPeter Wemm **  SETGROUPS -- set group list
3030c2aa98e2SPeter Wemm **
3031c2aa98e2SPeter Wemm **	Stub implementation for systems that don't have group lists
3032c2aa98e2SPeter Wemm */
3033c2aa98e2SPeter Wemm 
3034c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX
3035c2aa98e2SPeter Wemm 
3036c2aa98e2SPeter Wemm int
3037c2aa98e2SPeter Wemm setgroups(ngroups, grouplist)
3038c2aa98e2SPeter Wemm 	int ngroups;
3039c2aa98e2SPeter Wemm 	GIDSET_T grouplist[];
3040c2aa98e2SPeter Wemm {
3041c2aa98e2SPeter Wemm 	return 0;
3042c2aa98e2SPeter Wemm }
3043c2aa98e2SPeter Wemm 
30443299c2f1SGregory Neil Shapiro #endif /* ! NGROUPS_MAX */
3045c2aa98e2SPeter Wemm /*
3046c2aa98e2SPeter Wemm **  SETSID -- set session id (for non-POSIX systems)
3047c2aa98e2SPeter Wemm */
3048c2aa98e2SPeter Wemm 
30493299c2f1SGregory Neil Shapiro #if !HASSETSID
3050c2aa98e2SPeter Wemm 
3051c2aa98e2SPeter Wemm pid_t
3052c2aa98e2SPeter Wemm setsid __P ((void))
3053c2aa98e2SPeter Wemm {
3054c2aa98e2SPeter Wemm #  ifdef TIOCNOTTY
3055c2aa98e2SPeter Wemm 	int fd;
3056c2aa98e2SPeter Wemm 
3057c2aa98e2SPeter Wemm 	fd = open("/dev/tty", O_RDWR, 0);
3058c2aa98e2SPeter Wemm 	if (fd >= 0)
3059c2aa98e2SPeter Wemm 	{
3060d995d2baSGregory Neil Shapiro 		(void) ioctl(fd, TIOCNOTTY, (char *) 0);
3061c2aa98e2SPeter Wemm 		(void) close(fd);
3062c2aa98e2SPeter Wemm 	}
3063c2aa98e2SPeter Wemm #  endif /* TIOCNOTTY */
3064c2aa98e2SPeter Wemm #  ifdef SYS5SETPGRP
3065c2aa98e2SPeter Wemm 	return setpgrp();
30663299c2f1SGregory Neil Shapiro #  else /* SYS5SETPGRP */
3067c2aa98e2SPeter Wemm 	return setpgid(0, getpid());
30683299c2f1SGregory Neil Shapiro #  endif /* SYS5SETPGRP */
3069c2aa98e2SPeter Wemm }
3070c2aa98e2SPeter Wemm 
30713299c2f1SGregory Neil Shapiro #endif /* !HASSETSID */
3072c2aa98e2SPeter Wemm /*
3073c2aa98e2SPeter Wemm **  FSYNC -- dummy fsync
3074c2aa98e2SPeter Wemm */
3075c2aa98e2SPeter Wemm 
30763299c2f1SGregory Neil Shapiro #if NEEDFSYNC
3077c2aa98e2SPeter Wemm 
3078c2aa98e2SPeter Wemm fsync(fd)
3079c2aa98e2SPeter Wemm 	int fd;
3080c2aa98e2SPeter Wemm {
3081c2aa98e2SPeter Wemm # ifdef O_SYNC
3082c2aa98e2SPeter Wemm 	return fcntl(fd, F_SETFL, O_SYNC);
30833299c2f1SGregory Neil Shapiro # else /* O_SYNC */
3084c2aa98e2SPeter Wemm 	/* nothing we can do */
3085c2aa98e2SPeter Wemm 	return 0;
30863299c2f1SGregory Neil Shapiro # endif /* O_SYNC */
3087c2aa98e2SPeter Wemm }
3088c2aa98e2SPeter Wemm 
30893299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
3090c2aa98e2SPeter Wemm /*
3091c2aa98e2SPeter Wemm **  DGUX_INET_ADDR -- inet_addr for DG/UX
3092c2aa98e2SPeter Wemm **
3093c2aa98e2SPeter Wemm **	Data General DG/UX version of inet_addr returns a struct in_addr
3094c2aa98e2SPeter Wemm **	instead of a long.  This patches things.  Only needed on versions
3095c2aa98e2SPeter Wemm **	prior to 5.4.3.
3096c2aa98e2SPeter Wemm */
3097c2aa98e2SPeter Wemm 
3098c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2
3099c2aa98e2SPeter Wemm 
3100c2aa98e2SPeter Wemm # undef inet_addr
3101c2aa98e2SPeter Wemm 
3102c2aa98e2SPeter Wemm long
3103c2aa98e2SPeter Wemm dgux_inet_addr(host)
3104c2aa98e2SPeter Wemm 	char *host;
3105c2aa98e2SPeter Wemm {
3106c2aa98e2SPeter Wemm 	struct in_addr haddr;
3107c2aa98e2SPeter Wemm 
3108c2aa98e2SPeter Wemm 	haddr = inet_addr(host);
3109c2aa98e2SPeter Wemm 	return haddr.s_addr;
3110c2aa98e2SPeter Wemm }
3111c2aa98e2SPeter Wemm 
31123299c2f1SGregory Neil Shapiro #endif /* DGUX_5_4_2 */
3113c2aa98e2SPeter Wemm /*
3114c2aa98e2SPeter Wemm **  GETOPT -- for old systems or systems with bogus implementations
3115c2aa98e2SPeter Wemm */
3116c2aa98e2SPeter Wemm 
31173299c2f1SGregory Neil Shapiro #if NEEDGETOPT
3118c2aa98e2SPeter Wemm 
3119c2aa98e2SPeter Wemm /*
3120c2aa98e2SPeter Wemm  * Copyright (c) 1985 Regents of the University of California.
3121c2aa98e2SPeter Wemm  * All rights reserved.  The Berkeley software License Agreement
3122c2aa98e2SPeter Wemm  * specifies the terms and conditions for redistribution.
3123c2aa98e2SPeter Wemm  */
3124c2aa98e2SPeter Wemm 
3125c2aa98e2SPeter Wemm 
3126c2aa98e2SPeter Wemm /*
3127c2aa98e2SPeter Wemm **  this version hacked to add `atend' flag to allow state machine
3128c2aa98e2SPeter Wemm **  to reset if invoked by the program to scan args for a 2nd time
3129c2aa98e2SPeter Wemm */
3130c2aa98e2SPeter Wemm 
3131c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
3132c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c	4.3 (Berkeley) 3/9/86";
31333299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
3134c2aa98e2SPeter Wemm 
3135c2aa98e2SPeter Wemm /*
3136c2aa98e2SPeter Wemm  * get option letter from argument vector
3137c2aa98e2SPeter Wemm  */
3138c2aa98e2SPeter Wemm # ifdef _CONVEX_SOURCE
3139c2aa98e2SPeter Wemm extern int	optind, opterr, optopt;
3140c2aa98e2SPeter Wemm extern char	*optarg;
31413299c2f1SGregory Neil Shapiro # else /* _CONVEX_SOURCE */
3142c2aa98e2SPeter Wemm int	opterr = 1;		/* if error message should be printed */
3143c2aa98e2SPeter Wemm int	optind = 1;		/* index into parent argv vector */
3144c2aa98e2SPeter Wemm int	optopt = 0;		/* character checked for validity */
3145c2aa98e2SPeter Wemm char	*optarg = NULL;		/* argument associated with option */
31463299c2f1SGregory Neil Shapiro # endif /* _CONVEX_SOURCE */
3147c2aa98e2SPeter Wemm 
3148c2aa98e2SPeter Wemm # define BADCH	(int)'?'
3149c2aa98e2SPeter Wemm # define EMSG	""
3150c2aa98e2SPeter Wemm # define tell(s)	if (opterr) {fputs(*nargv,stderr);fputs(s,stderr); \
3151c2aa98e2SPeter Wemm 			fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);}
3152c2aa98e2SPeter Wemm 
3153c2aa98e2SPeter Wemm int
3154c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr)
3155c2aa98e2SPeter Wemm 	int		nargc;
3156c2aa98e2SPeter Wemm 	char *const	*nargv;
3157c2aa98e2SPeter Wemm 	const char	*ostr;
3158c2aa98e2SPeter Wemm {
3159c2aa98e2SPeter Wemm 	static char	*place = EMSG;	/* option letter processing */
3160c2aa98e2SPeter Wemm 	static char	atend = 0;
3161c2aa98e2SPeter Wemm 	register char	*oli = NULL;	/* option letter list index */
3162c2aa98e2SPeter Wemm 
3163c2aa98e2SPeter Wemm 	if (atend) {
3164c2aa98e2SPeter Wemm 		atend = 0;
3165c2aa98e2SPeter Wemm 		place = EMSG;
3166c2aa98e2SPeter Wemm 	}
3167c2aa98e2SPeter Wemm 	if(!*place) {			/* update scanning pointer */
3168c2aa98e2SPeter Wemm 		if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
3169c2aa98e2SPeter Wemm 			atend++;
3170c2aa98e2SPeter Wemm 			return -1;
3171c2aa98e2SPeter Wemm 		}
3172c2aa98e2SPeter Wemm 		if (*place == '-') {	/* found "--" */
3173c2aa98e2SPeter Wemm 			++optind;
3174c2aa98e2SPeter Wemm 			atend++;
3175c2aa98e2SPeter Wemm 			return -1;
3176c2aa98e2SPeter Wemm 		}
3177c2aa98e2SPeter Wemm 	}				/* option letter okay? */
3178c2aa98e2SPeter Wemm 	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
3179c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3180c2aa98e2SPeter Wemm 		tell(": illegal option -- ");
3181c2aa98e2SPeter Wemm 	}
3182c2aa98e2SPeter Wemm 	if (oli && *++oli != ':') {		/* don't need argument */
3183c2aa98e2SPeter Wemm 		optarg = NULL;
3184c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3185c2aa98e2SPeter Wemm 	}
3186c2aa98e2SPeter Wemm 	else {				/* need an argument */
3187c2aa98e2SPeter Wemm 		if (*place) optarg = place;	/* no white space */
3188c2aa98e2SPeter Wemm 		else if (nargc <= ++optind) {	/* no arg */
3189c2aa98e2SPeter Wemm 			place = EMSG;
3190c2aa98e2SPeter Wemm 			tell(": option requires an argument -- ");
3191c2aa98e2SPeter Wemm 		}
3192c2aa98e2SPeter Wemm 		else optarg = nargv[optind];	/* white space */
3193c2aa98e2SPeter Wemm 		place = EMSG;
3194c2aa98e2SPeter Wemm 		++optind;
3195c2aa98e2SPeter Wemm 	}
3196c2aa98e2SPeter Wemm 	return(optopt);			/* dump back option letter */
3197c2aa98e2SPeter Wemm }
3198c2aa98e2SPeter Wemm 
31993299c2f1SGregory Neil Shapiro #endif /* NEEDGETOPT */
3200c2aa98e2SPeter Wemm /*
3201c2aa98e2SPeter Wemm **  VFPRINTF, VSPRINTF -- for old 4.3 BSD systems missing a real version
3202c2aa98e2SPeter Wemm */
3203c2aa98e2SPeter Wemm 
32043299c2f1SGregory Neil Shapiro #if NEEDVPRINTF
3205c2aa98e2SPeter Wemm 
3206c2aa98e2SPeter Wemm # define MAXARG	16
3207c2aa98e2SPeter Wemm 
3208c2aa98e2SPeter Wemm vfprintf(fp, fmt, ap)
3209c2aa98e2SPeter Wemm 	FILE *fp;
3210c2aa98e2SPeter Wemm 	char *fmt;
3211c2aa98e2SPeter Wemm 	char **ap;
3212c2aa98e2SPeter Wemm {
3213c2aa98e2SPeter Wemm 	char *bp[MAXARG];
3214c2aa98e2SPeter Wemm 	int i = 0;
3215c2aa98e2SPeter Wemm 
3216c2aa98e2SPeter Wemm 	while (*ap && i < MAXARG)
3217c2aa98e2SPeter Wemm 		bp[i++] = *ap++;
3218c2aa98e2SPeter Wemm 	fprintf(fp, fmt, bp[0], bp[1], bp[2], bp[3],
3219c2aa98e2SPeter Wemm 			 bp[4], bp[5], bp[6], bp[7],
3220c2aa98e2SPeter Wemm 			 bp[8], bp[9], bp[10], bp[11],
3221c2aa98e2SPeter Wemm 			 bp[12], bp[13], bp[14], bp[15]);
3222c2aa98e2SPeter Wemm }
3223c2aa98e2SPeter Wemm 
3224c2aa98e2SPeter Wemm vsprintf(s, fmt, ap)
3225c2aa98e2SPeter Wemm 	char *s;
3226c2aa98e2SPeter Wemm 	char *fmt;
3227c2aa98e2SPeter Wemm 	char **ap;
3228c2aa98e2SPeter Wemm {
3229c2aa98e2SPeter Wemm 	char *bp[MAXARG];
3230c2aa98e2SPeter Wemm 	int i = 0;
3231c2aa98e2SPeter Wemm 
3232c2aa98e2SPeter Wemm 	while (*ap && i < MAXARG)
3233c2aa98e2SPeter Wemm 		bp[i++] = *ap++;
3234c2aa98e2SPeter Wemm 	sprintf(s, fmt, bp[0], bp[1], bp[2], bp[3],
3235c2aa98e2SPeter Wemm 			bp[4], bp[5], bp[6], bp[7],
3236c2aa98e2SPeter Wemm 			bp[8], bp[9], bp[10], bp[11],
3237c2aa98e2SPeter Wemm 			bp[12], bp[13], bp[14], bp[15]);
3238c2aa98e2SPeter Wemm }
3239c2aa98e2SPeter Wemm 
32403299c2f1SGregory Neil Shapiro #endif /* NEEDVPRINTF */
3241c2aa98e2SPeter Wemm /*
3242c2aa98e2SPeter Wemm **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
3243c2aa98e2SPeter Wemm **
3244c2aa98e2SPeter Wemm **	Parameters:
3245c2aa98e2SPeter Wemm **		user -- the name of the user we are checking.
3246c2aa98e2SPeter Wemm **		shell -- the user's shell from /etc/passwd
3247c2aa98e2SPeter Wemm **
3248c2aa98e2SPeter Wemm **	Returns:
3249c2aa98e2SPeter Wemm **		TRUE -- if it is ok to use this for unrestricted access.
3250c2aa98e2SPeter Wemm **		FALSE -- if the shell is restricted.
3251c2aa98e2SPeter Wemm */
3252c2aa98e2SPeter Wemm 
3253c2aa98e2SPeter Wemm #if !HASGETUSERSHELL
3254c2aa98e2SPeter Wemm 
3255c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS
3256c2aa98e2SPeter Wemm #  define _PATH_SHELLS	"/etc/shells"
32573299c2f1SGregory Neil Shapiro # endif /* ! _PATH_SHELLS */
3258c2aa98e2SPeter Wemm 
3259c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3260c2aa98e2SPeter Wemm #  include <userconf.h>
3261c2aa98e2SPeter Wemm #  if _AIX4 >= 40200
3262c2aa98e2SPeter Wemm #   include <userpw.h>
32633299c2f1SGregory Neil Shapiro #  endif /* _AIX4 >= 40200 */
3264c2aa98e2SPeter Wemm #  include <usersec.h>
32653299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
3266c2aa98e2SPeter Wemm 
32673299c2f1SGregory Neil Shapiro static char	*DefaultUserShells[] =
3268c2aa98e2SPeter Wemm {
3269c2aa98e2SPeter Wemm 	"/bin/sh",		/* standard shell */
3270c2aa98e2SPeter Wemm 	"/usr/bin/sh",
3271c2aa98e2SPeter Wemm 	"/bin/csh",		/* C shell */
3272c2aa98e2SPeter Wemm 	"/usr/bin/csh",
3273c2aa98e2SPeter Wemm # ifdef __hpux
3274c2aa98e2SPeter Wemm #  ifdef V4FS
3275c2aa98e2SPeter Wemm 	"/usr/bin/rsh",		/* restricted Bourne shell */
3276c2aa98e2SPeter Wemm 	"/usr/bin/ksh",		/* Korn shell */
3277c2aa98e2SPeter Wemm 	"/usr/bin/rksh",	/* restricted Korn shell */
3278c2aa98e2SPeter Wemm 	"/usr/bin/pam",
3279c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3280c2aa98e2SPeter Wemm 	"/usr/bin/posix/sh",
32813299c2f1SGregory Neil Shapiro #  else /* V4FS */
3282c2aa98e2SPeter Wemm 	"/bin/rsh",		/* restricted Bourne shell */
3283c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3284c2aa98e2SPeter Wemm 	"/bin/rksh",		/* restricted Korn shell */
3285c2aa98e2SPeter Wemm 	"/bin/pam",
3286c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3287c2aa98e2SPeter Wemm 	"/bin/posix/sh",
32883299c2f1SGregory Neil Shapiro #  endif /* V4FS */
32893299c2f1SGregory Neil Shapiro # endif /* __hpux */
3290c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3291c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3292c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3293c2aa98e2SPeter Wemm 	"/bin/tsh",		/* trusted shell */
3294c2aa98e2SPeter Wemm 	"/usr/bin/tsh",
3295c2aa98e2SPeter Wemm 	"/bin/bsh",		/* Bourne shell */
3296c2aa98e2SPeter Wemm 	"/usr/bin/bsh",
32973299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
329876b7bf71SPeter Wemm # if defined(__svr4__) || defined(__svr5__)
3299c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3300c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
33013299c2f1SGregory Neil Shapiro # endif /* defined(__svr4__) || defined(__svr5__) */
3302c2aa98e2SPeter Wemm # ifdef sgi
3303c2aa98e2SPeter Wemm 	"/sbin/sh",		/* SGI's shells really live in /sbin */
3304c2aa98e2SPeter Wemm 	"/sbin/csh",
3305c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3306c2aa98e2SPeter Wemm 	"/sbin/ksh",
3307c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3308c2aa98e2SPeter Wemm 	"/bin/tcsh",		/* Extended csh */
3309c2aa98e2SPeter Wemm 	"/usr/bin/tcsh",
33103299c2f1SGregory Neil Shapiro # endif /* sgi */
3311c2aa98e2SPeter Wemm 	NULL
3312c2aa98e2SPeter Wemm };
3313c2aa98e2SPeter Wemm 
33143299c2f1SGregory Neil Shapiro #endif /* !HASGETUSERSHELL */
3315c2aa98e2SPeter Wemm 
3316c2aa98e2SPeter Wemm #define WILDCARD_SHELL	"/SENDMAIL/ANY/SHELL/"
3317c2aa98e2SPeter Wemm 
3318c2aa98e2SPeter Wemm bool
3319c2aa98e2SPeter Wemm usershellok(user, shell)
3320c2aa98e2SPeter Wemm 	char *user;
3321c2aa98e2SPeter Wemm 	char *shell;
3322c2aa98e2SPeter Wemm {
3323c2aa98e2SPeter Wemm # if HASGETUSERSHELL
3324c2aa98e2SPeter Wemm 	register char *p;
3325c2aa98e2SPeter Wemm 	extern char *getusershell();
3326c2aa98e2SPeter Wemm 
3327c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3328c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
3329c2aa98e2SPeter Wemm 		return TRUE;
3330c2aa98e2SPeter Wemm 
3331c2aa98e2SPeter Wemm 	setusershell();
3332c2aa98e2SPeter Wemm 	while ((p = getusershell()) != NULL)
3333c2aa98e2SPeter Wemm 		if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
3334c2aa98e2SPeter Wemm 			break;
3335c2aa98e2SPeter Wemm 	endusershell();
3336c2aa98e2SPeter Wemm 	return p != NULL;
33373299c2f1SGregory Neil Shapiro # else /* HASGETUSERSHELL */
3338c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3339c2aa98e2SPeter Wemm 	auto char *v;
33403299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
3341c2aa98e2SPeter Wemm 	register FILE *shellf;
3342c2aa98e2SPeter Wemm 	char buf[MAXLINE];
3343c2aa98e2SPeter Wemm 
3344c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3345c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
3346c2aa98e2SPeter Wemm 		return TRUE;
3347c2aa98e2SPeter Wemm 
3348c2aa98e2SPeter Wemm #  if USEGETCONFATTR
3349c2aa98e2SPeter Wemm 	/*
3350c2aa98e2SPeter Wemm 	**  Naturally IBM has a "better" idea.....
3351c2aa98e2SPeter Wemm 	**
3352c2aa98e2SPeter Wemm 	**	What a crock.  This interface isn't documented, it is
3353c2aa98e2SPeter Wemm 	**	considered part of the security library (-ls), and it
3354c2aa98e2SPeter Wemm 	**	only works if you are running as root (since the list
3355c2aa98e2SPeter Wemm 	**	of valid shells is obviously a source of great concern).
3356c2aa98e2SPeter Wemm 	**	I recommend that you do NOT define USEGETCONFATTR,
3357c2aa98e2SPeter Wemm 	**	especially since you are going to have to set up an
3358c2aa98e2SPeter Wemm 	**	/etc/shells anyhow to handle the cases where getconfattr
3359c2aa98e2SPeter Wemm 	**	fails.
3360c2aa98e2SPeter Wemm 	*/
3361c2aa98e2SPeter Wemm 
3362c2aa98e2SPeter Wemm 	if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
3363c2aa98e2SPeter Wemm 	{
3364c2aa98e2SPeter Wemm 		while (*v != '\0')
3365c2aa98e2SPeter Wemm 		{
3366c2aa98e2SPeter Wemm 			if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
3367c2aa98e2SPeter Wemm 				return TRUE;
3368c2aa98e2SPeter Wemm 			v += strlen(v) + 1;
3369c2aa98e2SPeter Wemm 		}
3370c2aa98e2SPeter Wemm 		return FALSE;
3371c2aa98e2SPeter Wemm 	}
33723299c2f1SGregory Neil Shapiro #  endif /* USEGETCONFATTR */
3373c2aa98e2SPeter Wemm 
3374c2aa98e2SPeter Wemm 	shellf = fopen(_PATH_SHELLS, "r");
3375c2aa98e2SPeter Wemm 	if (shellf == NULL)
3376c2aa98e2SPeter Wemm 	{
3377c2aa98e2SPeter Wemm 		/* no /etc/shells; see if it is one of the std shells */
3378c2aa98e2SPeter Wemm 		char **d;
3379c2aa98e2SPeter Wemm 
3380c2aa98e2SPeter Wemm 		if (errno != ENOENT && LogLevel > 3)
3381c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
3382c2aa98e2SPeter Wemm 				  "usershellok: cannot open %s: %s",
3383c2aa98e2SPeter Wemm 				  _PATH_SHELLS, errstring(errno));
3384c2aa98e2SPeter Wemm 
3385c2aa98e2SPeter Wemm 		for (d = DefaultUserShells; *d != NULL; d++)
3386c2aa98e2SPeter Wemm 		{
3387c2aa98e2SPeter Wemm 			if (strcmp(shell, *d) == 0)
3388c2aa98e2SPeter Wemm 				return TRUE;
3389c2aa98e2SPeter Wemm 		}
3390c2aa98e2SPeter Wemm 		return FALSE;
3391c2aa98e2SPeter Wemm 	}
3392c2aa98e2SPeter Wemm 
3393c2aa98e2SPeter Wemm 	while (fgets(buf, sizeof buf, shellf) != NULL)
3394c2aa98e2SPeter Wemm 	{
3395c2aa98e2SPeter Wemm 		register char *p, *q;
3396c2aa98e2SPeter Wemm 
3397c2aa98e2SPeter Wemm 		p = buf;
3398c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && *p != '/')
3399c2aa98e2SPeter Wemm 			p++;
3400c2aa98e2SPeter Wemm 		if (*p == '#' || *p == '\0')
3401c2aa98e2SPeter Wemm 			continue;
3402c2aa98e2SPeter Wemm 		q = p;
3403c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p)))
3404c2aa98e2SPeter Wemm 			p++;
3405c2aa98e2SPeter Wemm 		*p = '\0';
3406c2aa98e2SPeter Wemm 		if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
3407c2aa98e2SPeter Wemm 		{
34083299c2f1SGregory Neil Shapiro 			(void) fclose(shellf);
3409c2aa98e2SPeter Wemm 			return TRUE;
3410c2aa98e2SPeter Wemm 		}
3411c2aa98e2SPeter Wemm 	}
34123299c2f1SGregory Neil Shapiro 	(void) fclose(shellf);
3413c2aa98e2SPeter Wemm 	return FALSE;
34143299c2f1SGregory Neil Shapiro # endif /* HASGETUSERSHELL */
3415c2aa98e2SPeter Wemm }
3416c2aa98e2SPeter Wemm /*
3417c2aa98e2SPeter Wemm **  FREEDISKSPACE -- see how much free space is on the queue filesystem
3418c2aa98e2SPeter Wemm **
3419c2aa98e2SPeter Wemm **	Only implemented if you have statfs.
3420c2aa98e2SPeter Wemm **
3421c2aa98e2SPeter Wemm **	Parameters:
3422c2aa98e2SPeter Wemm **		dir -- the directory in question.
3423c2aa98e2SPeter Wemm **		bsize -- a variable into which the filesystem
3424c2aa98e2SPeter Wemm **			block size is stored.
3425c2aa98e2SPeter Wemm **
3426c2aa98e2SPeter Wemm **	Returns:
34273299c2f1SGregory Neil Shapiro **		The number of blocks free on the queue filesystem.
3428c2aa98e2SPeter Wemm **		-1 if the statfs call fails.
3429c2aa98e2SPeter Wemm **
3430c2aa98e2SPeter Wemm **	Side effects:
3431c2aa98e2SPeter Wemm **		Puts the filesystem block size into bsize.
3432c2aa98e2SPeter Wemm */
3433c2aa98e2SPeter Wemm 
3434c2aa98e2SPeter Wemm /* statfs types */
3435c2aa98e2SPeter Wemm #define SFS_NONE	0	/* no statfs implementation */
3436c2aa98e2SPeter Wemm #define SFS_USTAT	1	/* use ustat */
3437c2aa98e2SPeter Wemm #define SFS_4ARGS	2	/* use four-argument statfs call */
3438c2aa98e2SPeter Wemm #define SFS_VFS		3	/* use <sys/vfs.h> implementation */
3439c2aa98e2SPeter Wemm #define SFS_MOUNT	4	/* use <sys/mount.h> implementation */
3440c2aa98e2SPeter Wemm #define SFS_STATFS	5	/* use <sys/statfs.h> implementation */
3441c2aa98e2SPeter Wemm #define SFS_STATVFS	6	/* use <sys/statvfs.h> implementation */
3442c2aa98e2SPeter Wemm 
3443c2aa98e2SPeter Wemm #ifndef SFS_TYPE
3444c2aa98e2SPeter Wemm # define SFS_TYPE	SFS_NONE
34453299c2f1SGregory Neil Shapiro #endif /* ! SFS_TYPE */
3446c2aa98e2SPeter Wemm 
3447c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_USTAT
3448c2aa98e2SPeter Wemm # include <ustat.h>
34493299c2f1SGregory Neil Shapiro #endif /* SFS_TYPE == SFS_USTAT */
3450c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
3451c2aa98e2SPeter Wemm # include <sys/statfs.h>
34523299c2f1SGregory Neil Shapiro #endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */
3453c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_VFS
3454c2aa98e2SPeter Wemm # include <sys/vfs.h>
34553299c2f1SGregory Neil Shapiro #endif /* SFS_TYPE == SFS_VFS */
3456c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_MOUNT
3457c2aa98e2SPeter Wemm # include <sys/mount.h>
34583299c2f1SGregory Neil Shapiro #endif /* SFS_TYPE == SFS_MOUNT */
3459c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_STATVFS
3460c2aa98e2SPeter Wemm # include <sys/statvfs.h>
34613299c2f1SGregory Neil Shapiro #endif /* SFS_TYPE == SFS_STATVFS */
3462c2aa98e2SPeter Wemm 
3463c2aa98e2SPeter Wemm long
3464c2aa98e2SPeter Wemm freediskspace(dir, bsize)
3465c2aa98e2SPeter Wemm 	char *dir;
3466c2aa98e2SPeter Wemm 	long *bsize;
3467c2aa98e2SPeter Wemm {
3468c2aa98e2SPeter Wemm # if SFS_TYPE != SFS_NONE
3469c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3470c2aa98e2SPeter Wemm 	struct ustat fs;
3471c2aa98e2SPeter Wemm 	struct stat statbuf;
3472c2aa98e2SPeter Wemm #   define FSBLOCKSIZE	DEV_BSIZE
3473c2aa98e2SPeter Wemm #   define SFS_BAVAIL	f_tfree
34743299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3475c2aa98e2SPeter Wemm #   if defined(ultrix)
3476c2aa98e2SPeter Wemm 	struct fs_data fs;
3477c2aa98e2SPeter Wemm #    define SFS_BAVAIL	fd_bfreen
3478c2aa98e2SPeter Wemm #    define FSBLOCKSIZE	1024L
34793299c2f1SGregory Neil Shapiro #   else /* defined(ultrix) */
3480c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3481c2aa98e2SPeter Wemm 	struct statvfs fs;
3482c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_frsize
34833299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3484c2aa98e2SPeter Wemm 	struct statfs fs;
3485c2aa98e2SPeter Wemm #     define FSBLOCKSIZE	fs.f_bsize
34863299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
34873299c2f1SGregory Neil Shapiro #   endif /* defined(ultrix) */
34883299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3489c2aa98e2SPeter Wemm #  ifndef SFS_BAVAIL
3490c2aa98e2SPeter Wemm #   define SFS_BAVAIL f_bavail
34913299c2f1SGregory Neil Shapiro #  endif /* ! SFS_BAVAIL */
3492c2aa98e2SPeter Wemm 
3493c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_USTAT
3494c2aa98e2SPeter Wemm 	if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
34953299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_USTAT */
3496c2aa98e2SPeter Wemm #   if SFS_TYPE == SFS_4ARGS
3497c2aa98e2SPeter Wemm 	if (statfs(dir, &fs, sizeof fs, 0) == 0)
34983299c2f1SGregory Neil Shapiro #   else /* SFS_TYPE == SFS_4ARGS */
3499c2aa98e2SPeter Wemm #    if SFS_TYPE == SFS_STATVFS
3500c2aa98e2SPeter Wemm 	if (statvfs(dir, &fs) == 0)
35013299c2f1SGregory Neil Shapiro #    else /* SFS_TYPE == SFS_STATVFS */
3502c2aa98e2SPeter Wemm #     if defined(ultrix)
3503c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) > 0)
35043299c2f1SGregory Neil Shapiro #     else /* defined(ultrix) */
3505c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) == 0)
35063299c2f1SGregory Neil Shapiro #     endif /* defined(ultrix) */
35073299c2f1SGregory Neil Shapiro #    endif /* SFS_TYPE == SFS_STATVFS */
35083299c2f1SGregory Neil Shapiro #   endif /* SFS_TYPE == SFS_4ARGS */
35093299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_USTAT */
3510c2aa98e2SPeter Wemm 	{
3511c2aa98e2SPeter Wemm 		if (bsize != NULL)
3512c2aa98e2SPeter Wemm 			*bsize = FSBLOCKSIZE;
3513c2aa98e2SPeter Wemm 		if (fs.SFS_BAVAIL <= 0)
3514c2aa98e2SPeter Wemm 			return 0;
3515c2aa98e2SPeter Wemm 		else if (fs.SFS_BAVAIL > LONG_MAX)
35163299c2f1SGregory Neil Shapiro 			return (long) LONG_MAX;
3517c2aa98e2SPeter Wemm 		else
3518c2aa98e2SPeter Wemm 			return (long) fs.SFS_BAVAIL;
3519c2aa98e2SPeter Wemm 	}
35203299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE != SFS_NONE */
35213299c2f1SGregory Neil Shapiro 	return -1;
3522c2aa98e2SPeter Wemm }
3523c2aa98e2SPeter Wemm /*
3524c2aa98e2SPeter Wemm **  ENOUGHDISKSPACE -- is there enough free space on the queue fs?
3525c2aa98e2SPeter Wemm **
3526c2aa98e2SPeter Wemm **	Only implemented if you have statfs.
3527c2aa98e2SPeter Wemm **
3528c2aa98e2SPeter Wemm **	Parameters:
3529c2aa98e2SPeter Wemm **		msize -- the size to check against.  If zero, we don't yet
3530c2aa98e2SPeter Wemm **		know how big the message will be, so just check for
3531c2aa98e2SPeter Wemm **		a "reasonable" amount.
35323299c2f1SGregory Neil Shapiro **		log -- log message?
3533c2aa98e2SPeter Wemm **
3534c2aa98e2SPeter Wemm **	Returns:
3535c2aa98e2SPeter Wemm **		TRUE if there is enough space.
3536c2aa98e2SPeter Wemm **		FALSE otherwise.
3537c2aa98e2SPeter Wemm */
3538c2aa98e2SPeter Wemm 
3539c2aa98e2SPeter Wemm bool
35403299c2f1SGregory Neil Shapiro enoughdiskspace(msize, log)
3541c2aa98e2SPeter Wemm 	long msize;
35423299c2f1SGregory Neil Shapiro 	bool log;
3543c2aa98e2SPeter Wemm {
35443299c2f1SGregory Neil Shapiro 	long bfree;
35453299c2f1SGregory Neil Shapiro 	long bsize;
3546c2aa98e2SPeter Wemm 
3547c2aa98e2SPeter Wemm 	if (MinBlocksFree <= 0 && msize <= 0)
3548c2aa98e2SPeter Wemm 	{
3549c2aa98e2SPeter Wemm 		if (tTd(4, 80))
35503299c2f1SGregory Neil Shapiro 			dprintf("enoughdiskspace: no threshold\n");
3551c2aa98e2SPeter Wemm 		return TRUE;
3552c2aa98e2SPeter Wemm 	}
3553c2aa98e2SPeter Wemm 
35543299c2f1SGregory Neil Shapiro 	bfree = freediskspace(QueueDir, &bsize);
35553299c2f1SGregory Neil Shapiro 	if (bfree >= 0)
3556c2aa98e2SPeter Wemm 	{
3557c2aa98e2SPeter Wemm 		if (tTd(4, 80))
35583299c2f1SGregory Neil Shapiro 			dprintf("enoughdiskspace: bavail=%ld, need=%ld\n",
3559c2aa98e2SPeter Wemm 				bfree, msize);
3560c2aa98e2SPeter Wemm 
3561c2aa98e2SPeter Wemm 		/* convert msize to block count */
3562c2aa98e2SPeter Wemm 		msize = msize / bsize + 1;
3563c2aa98e2SPeter Wemm 		if (MinBlocksFree >= 0)
3564c2aa98e2SPeter Wemm 			msize += MinBlocksFree;
3565c2aa98e2SPeter Wemm 
3566c2aa98e2SPeter Wemm 		if (bfree < msize)
3567c2aa98e2SPeter Wemm 		{
35683299c2f1SGregory Neil Shapiro 			if (log && LogLevel > 0)
3569c2aa98e2SPeter Wemm 				sm_syslog(LOG_ALERT, CurEnv->e_id,
3570c2aa98e2SPeter Wemm 					"low on space (have %ld, %s needs %ld in %s)",
3571c2aa98e2SPeter Wemm 					bfree,
3572c2aa98e2SPeter Wemm 					CurHostName == NULL ? "SMTP-DAEMON" : CurHostName,
3573c2aa98e2SPeter Wemm 					msize, QueueDir);
3574c2aa98e2SPeter Wemm 			return FALSE;
3575c2aa98e2SPeter Wemm 		}
3576c2aa98e2SPeter Wemm 	}
3577c2aa98e2SPeter Wemm 	else if (tTd(4, 80))
35783299c2f1SGregory Neil Shapiro 		dprintf("enoughdiskspace failure: min=%ld, need=%ld: %s\n",
3579c2aa98e2SPeter Wemm 			MinBlocksFree, msize, errstring(errno));
3580c2aa98e2SPeter Wemm 	return TRUE;
3581c2aa98e2SPeter Wemm }
3582c2aa98e2SPeter Wemm /*
3583c2aa98e2SPeter Wemm **  TRANSIENTERROR -- tell if an error code indicates a transient failure
3584c2aa98e2SPeter Wemm **
3585c2aa98e2SPeter Wemm **	This looks at an errno value and tells if this is likely to
3586c2aa98e2SPeter Wemm **	go away if retried later.
3587c2aa98e2SPeter Wemm **
3588c2aa98e2SPeter Wemm **	Parameters:
3589c2aa98e2SPeter Wemm **		err -- the errno code to classify.
3590c2aa98e2SPeter Wemm **
3591c2aa98e2SPeter Wemm **	Returns:
3592c2aa98e2SPeter Wemm **		TRUE if this is probably transient.
3593c2aa98e2SPeter Wemm **		FALSE otherwise.
3594c2aa98e2SPeter Wemm */
3595c2aa98e2SPeter Wemm 
3596c2aa98e2SPeter Wemm bool
3597c2aa98e2SPeter Wemm transienterror(err)
3598c2aa98e2SPeter Wemm 	int err;
3599c2aa98e2SPeter Wemm {
3600c2aa98e2SPeter Wemm 	switch (err)
3601c2aa98e2SPeter Wemm 	{
3602c2aa98e2SPeter Wemm 	  case EIO:			/* I/O error */
3603c2aa98e2SPeter Wemm 	  case ENXIO:			/* Device not configured */
3604c2aa98e2SPeter Wemm 	  case EAGAIN:			/* Resource temporarily unavailable */
3605c2aa98e2SPeter Wemm 	  case ENOMEM:			/* Cannot allocate memory */
3606c2aa98e2SPeter Wemm 	  case ENODEV:			/* Operation not supported by device */
3607c2aa98e2SPeter Wemm 	  case ENFILE:			/* Too many open files in system */
3608c2aa98e2SPeter Wemm 	  case EMFILE:			/* Too many open files */
3609c2aa98e2SPeter Wemm 	  case ENOSPC:			/* No space left on device */
3610c2aa98e2SPeter Wemm #ifdef ETIMEDOUT
3611c2aa98e2SPeter Wemm 	  case ETIMEDOUT:		/* Connection timed out */
36123299c2f1SGregory Neil Shapiro #endif /* ETIMEDOUT */
3613c2aa98e2SPeter Wemm #ifdef ESTALE
3614c2aa98e2SPeter Wemm 	  case ESTALE:			/* Stale NFS file handle */
36153299c2f1SGregory Neil Shapiro #endif /* ESTALE */
3616c2aa98e2SPeter Wemm #ifdef ENETDOWN
3617c2aa98e2SPeter Wemm 	  case ENETDOWN:		/* Network is down */
36183299c2f1SGregory Neil Shapiro #endif /* ENETDOWN */
3619c2aa98e2SPeter Wemm #ifdef ENETUNREACH
3620c2aa98e2SPeter Wemm 	  case ENETUNREACH:		/* Network is unreachable */
36213299c2f1SGregory Neil Shapiro #endif /* ENETUNREACH */
3622c2aa98e2SPeter Wemm #ifdef ENETRESET
3623c2aa98e2SPeter Wemm 	  case ENETRESET:		/* Network dropped connection on reset */
36243299c2f1SGregory Neil Shapiro #endif /* ENETRESET */
3625c2aa98e2SPeter Wemm #ifdef ECONNABORTED
3626c2aa98e2SPeter Wemm 	  case ECONNABORTED:		/* Software caused connection abort */
36273299c2f1SGregory Neil Shapiro #endif /* ECONNABORTED */
3628c2aa98e2SPeter Wemm #ifdef ECONNRESET
3629c2aa98e2SPeter Wemm 	  case ECONNRESET:		/* Connection reset by peer */
36303299c2f1SGregory Neil Shapiro #endif /* ECONNRESET */
3631c2aa98e2SPeter Wemm #ifdef ENOBUFS
3632c2aa98e2SPeter Wemm 	  case ENOBUFS:			/* No buffer space available */
36333299c2f1SGregory Neil Shapiro #endif /* ENOBUFS */
3634c2aa98e2SPeter Wemm #ifdef ESHUTDOWN
3635c2aa98e2SPeter Wemm 	  case ESHUTDOWN:		/* Can't send after socket shutdown */
36363299c2f1SGregory Neil Shapiro #endif /* ESHUTDOWN */
3637c2aa98e2SPeter Wemm #ifdef ECONNREFUSED
3638c2aa98e2SPeter Wemm 	  case ECONNREFUSED:		/* Connection refused */
36393299c2f1SGregory Neil Shapiro #endif /* ECONNREFUSED */
3640c2aa98e2SPeter Wemm #ifdef EHOSTDOWN
3641c2aa98e2SPeter Wemm 	  case EHOSTDOWN:		/* Host is down */
36423299c2f1SGregory Neil Shapiro #endif /* EHOSTDOWN */
3643c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH
3644c2aa98e2SPeter Wemm 	  case EHOSTUNREACH:		/* No route to host */
36453299c2f1SGregory Neil Shapiro #endif /* EHOSTUNREACH */
3646c2aa98e2SPeter Wemm #ifdef EDQUOT
3647c2aa98e2SPeter Wemm 	  case EDQUOT:			/* Disc quota exceeded */
36483299c2f1SGregory Neil Shapiro #endif /* EDQUOT */
3649c2aa98e2SPeter Wemm #ifdef EPROCLIM
3650c2aa98e2SPeter Wemm 	  case EPROCLIM:		/* Too many processes */
36513299c2f1SGregory Neil Shapiro #endif /* EPROCLIM */
3652c2aa98e2SPeter Wemm #ifdef EUSERS
3653c2aa98e2SPeter Wemm 	  case EUSERS:			/* Too many users */
36543299c2f1SGregory Neil Shapiro #endif /* EUSERS */
3655c2aa98e2SPeter Wemm #ifdef EDEADLK
3656c2aa98e2SPeter Wemm 	  case EDEADLK:			/* Resource deadlock avoided */
36573299c2f1SGregory Neil Shapiro #endif /* EDEADLK */
3658c2aa98e2SPeter Wemm #ifdef EISCONN
3659c2aa98e2SPeter Wemm 	  case EISCONN:			/* Socket already connected */
36603299c2f1SGregory Neil Shapiro #endif /* EISCONN */
3661c2aa98e2SPeter Wemm #ifdef EINPROGRESS
3662c2aa98e2SPeter Wemm 	  case EINPROGRESS:		/* Operation now in progress */
36633299c2f1SGregory Neil Shapiro #endif /* EINPROGRESS */
3664c2aa98e2SPeter Wemm #ifdef EALREADY
3665c2aa98e2SPeter Wemm 	  case EALREADY:		/* Operation already in progress */
36663299c2f1SGregory Neil Shapiro #endif /* EALREADY */
3667c2aa98e2SPeter Wemm #ifdef EADDRINUSE
3668c2aa98e2SPeter Wemm 	  case EADDRINUSE:		/* Address already in use */
36693299c2f1SGregory Neil Shapiro #endif /* EADDRINUSE */
3670c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL
3671c2aa98e2SPeter Wemm 	  case EADDRNOTAVAIL:		/* Can't assign requested address */
36723299c2f1SGregory Neil Shapiro #endif /* EADDRNOTAVAIL */
3673c2aa98e2SPeter Wemm #ifdef ETXTBSY
3674c2aa98e2SPeter Wemm 	  case ETXTBSY:			/* (Apollo) file locked */
36753299c2f1SGregory Neil Shapiro #endif /* ETXTBSY */
3676c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
3677c2aa98e2SPeter Wemm 	  case ENOSR:			/* Out of streams resources */
36783299c2f1SGregory Neil Shapiro #endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */
36793299c2f1SGregory Neil Shapiro #ifdef ENOLCK
36803299c2f1SGregory Neil Shapiro 	  case ENOLCK:			/* No locks available */
36813299c2f1SGregory Neil Shapiro #endif /* ENOLCK */
3682c2aa98e2SPeter Wemm 	  case E_SM_OPENTIMEOUT:	/* PSEUDO: open timed out */
3683c2aa98e2SPeter Wemm 		return TRUE;
3684c2aa98e2SPeter Wemm 	}
3685c2aa98e2SPeter Wemm 
3686c2aa98e2SPeter Wemm 	/* nope, must be permanent */
3687c2aa98e2SPeter Wemm 	return FALSE;
3688c2aa98e2SPeter Wemm }
3689c2aa98e2SPeter Wemm /*
3690c2aa98e2SPeter Wemm **  LOCKFILE -- lock a file using flock or (shudder) fcntl locking
3691c2aa98e2SPeter Wemm **
3692c2aa98e2SPeter Wemm **	Parameters:
3693c2aa98e2SPeter Wemm **		fd -- the file descriptor of the file.
3694c2aa98e2SPeter Wemm **		filename -- the file name (for error messages).
3695c2aa98e2SPeter Wemm **		ext -- the filename extension.
3696c2aa98e2SPeter Wemm **		type -- type of the lock.  Bits can be:
3697c2aa98e2SPeter Wemm **			LOCK_EX -- exclusive lock.
3698c2aa98e2SPeter Wemm **			LOCK_NB -- non-blocking.
3699c46d91b7SGregory Neil Shapiro **			LOCK_UN -- unlock.
3700c2aa98e2SPeter Wemm **
3701c2aa98e2SPeter Wemm **	Returns:
3702c2aa98e2SPeter Wemm **		TRUE if the lock was acquired.
3703c2aa98e2SPeter Wemm **		FALSE otherwise.
3704c2aa98e2SPeter Wemm */
3705c2aa98e2SPeter Wemm 
3706c2aa98e2SPeter Wemm bool
3707c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type)
3708c2aa98e2SPeter Wemm 	int fd;
3709c2aa98e2SPeter Wemm 	char *filename;
3710c2aa98e2SPeter Wemm 	char *ext;
3711c2aa98e2SPeter Wemm 	int type;
3712c2aa98e2SPeter Wemm {
3713c2aa98e2SPeter Wemm 	int i;
3714c2aa98e2SPeter Wemm 	int save_errno;
3715c2aa98e2SPeter Wemm # if !HASFLOCK
3716c2aa98e2SPeter Wemm 	int action;
3717c2aa98e2SPeter Wemm 	struct flock lfd;
3718c2aa98e2SPeter Wemm 
3719c2aa98e2SPeter Wemm 	if (ext == NULL)
3720c2aa98e2SPeter Wemm 		ext = "";
3721c2aa98e2SPeter Wemm 
37223299c2f1SGregory Neil Shapiro 	memset(&lfd, '\0', sizeof lfd);
3723c2aa98e2SPeter Wemm 	if (bitset(LOCK_UN, type))
3724c2aa98e2SPeter Wemm 		lfd.l_type = F_UNLCK;
3725c2aa98e2SPeter Wemm 	else if (bitset(LOCK_EX, type))
3726c2aa98e2SPeter Wemm 		lfd.l_type = F_WRLCK;
3727c2aa98e2SPeter Wemm 	else
3728c2aa98e2SPeter Wemm 		lfd.l_type = F_RDLCK;
3729c2aa98e2SPeter Wemm 
3730c2aa98e2SPeter Wemm 	if (bitset(LOCK_NB, type))
3731c2aa98e2SPeter Wemm 		action = F_SETLK;
3732c2aa98e2SPeter Wemm 	else
3733c2aa98e2SPeter Wemm 		action = F_SETLKW;
3734c2aa98e2SPeter Wemm 
3735c2aa98e2SPeter Wemm 	if (tTd(55, 60))
37363299c2f1SGregory Neil Shapiro 		dprintf("lockfile(%s%s, action=%d, type=%d): ",
3737c2aa98e2SPeter Wemm 			filename, ext, action, lfd.l_type);
3738c2aa98e2SPeter Wemm 
3739c2aa98e2SPeter Wemm 	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
3740c2aa98e2SPeter Wemm 		continue;
3741c2aa98e2SPeter Wemm 	if (i >= 0)
3742c2aa98e2SPeter Wemm 	{
3743c2aa98e2SPeter Wemm 		if (tTd(55, 60))
37443299c2f1SGregory Neil Shapiro 			dprintf("SUCCESS\n");
3745c2aa98e2SPeter Wemm 		return TRUE;
3746c2aa98e2SPeter Wemm 	}
3747c2aa98e2SPeter Wemm 	save_errno = errno;
3748c2aa98e2SPeter Wemm 
3749c2aa98e2SPeter Wemm 	if (tTd(55, 60))
37503299c2f1SGregory Neil Shapiro 		dprintf("(%s) ", errstring(save_errno));
3751c2aa98e2SPeter Wemm 
3752c2aa98e2SPeter Wemm 	/*
3753c2aa98e2SPeter Wemm 	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
3754c2aa98e2SPeter Wemm 	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
3755c2aa98e2SPeter Wemm 	**  as type "tmp" (that is, served from swap space), the
3756c2aa98e2SPeter Wemm 	**  previous fcntl will fail with "Invalid argument" errors.
3757c2aa98e2SPeter Wemm 	**  Since this is fairly common during testing, we will assume
3758c2aa98e2SPeter Wemm 	**  that this indicates that the lock is successfully grabbed.
3759c2aa98e2SPeter Wemm 	*/
3760c2aa98e2SPeter Wemm 
3761c2aa98e2SPeter Wemm 	if (save_errno == EINVAL)
3762c2aa98e2SPeter Wemm 	{
3763c2aa98e2SPeter Wemm 		if (tTd(55, 60))
37643299c2f1SGregory Neil Shapiro 			dprintf("SUCCESS\n");
3765c2aa98e2SPeter Wemm 		return TRUE;
3766c2aa98e2SPeter Wemm 	}
3767c2aa98e2SPeter Wemm 
37683299c2f1SGregory Neil Shapiro 	if (!bitset(LOCK_NB, type) ||
37693299c2f1SGregory Neil Shapiro 	    (save_errno != EACCES && save_errno != EAGAIN))
3770c2aa98e2SPeter Wemm 	{
3771c2aa98e2SPeter Wemm 		int omode = -1;
3772c2aa98e2SPeter Wemm #  ifdef F_GETFL
3773c2aa98e2SPeter Wemm 		(void) fcntl(fd, F_GETFL, &omode);
3774c2aa98e2SPeter Wemm 		errno = save_errno;
37753299c2f1SGregory Neil Shapiro #  endif /* F_GETFL */
3776c2aa98e2SPeter Wemm 		syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3777c2aa98e2SPeter Wemm 			filename, ext, fd, type, omode, geteuid());
3778c2aa98e2SPeter Wemm 		dumpfd(fd, TRUE, TRUE);
3779c2aa98e2SPeter Wemm 	}
37803299c2f1SGregory Neil Shapiro # else /* !HASFLOCK */
3781c2aa98e2SPeter Wemm 	if (ext == NULL)
3782c2aa98e2SPeter Wemm 		ext = "";
3783c2aa98e2SPeter Wemm 
3784c2aa98e2SPeter Wemm 	if (tTd(55, 60))
37853299c2f1SGregory Neil Shapiro 		dprintf("lockfile(%s%s, type=%o): ", filename, ext, type);
3786c2aa98e2SPeter Wemm 
3787c2aa98e2SPeter Wemm 	while ((i = flock(fd, type)) < 0 && errno == EINTR)
3788c2aa98e2SPeter Wemm 		continue;
3789c2aa98e2SPeter Wemm 	if (i >= 0)
3790c2aa98e2SPeter Wemm 	{
3791c2aa98e2SPeter Wemm 		if (tTd(55, 60))
37923299c2f1SGregory Neil Shapiro 			dprintf("SUCCESS\n");
3793c2aa98e2SPeter Wemm 		return TRUE;
3794c2aa98e2SPeter Wemm 	}
3795c2aa98e2SPeter Wemm 	save_errno = errno;
3796c2aa98e2SPeter Wemm 
3797c2aa98e2SPeter Wemm 	if (tTd(55, 60))
37983299c2f1SGregory Neil Shapiro 		dprintf("(%s) ", errstring(save_errno));
3799c2aa98e2SPeter Wemm 
3800c2aa98e2SPeter Wemm 	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
3801c2aa98e2SPeter Wemm 	{
3802c2aa98e2SPeter Wemm 		int omode = -1;
3803c2aa98e2SPeter Wemm #  ifdef F_GETFL
3804c2aa98e2SPeter Wemm 		(void) fcntl(fd, F_GETFL, &omode);
3805c2aa98e2SPeter Wemm 		errno = save_errno;
38063299c2f1SGregory Neil Shapiro #  endif /* F_GETFL */
3807c2aa98e2SPeter Wemm 		syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
3808c2aa98e2SPeter Wemm 			filename, ext, fd, type, omode, geteuid());
3809c2aa98e2SPeter Wemm 		dumpfd(fd, TRUE, TRUE);
3810c2aa98e2SPeter Wemm 	}
38113299c2f1SGregory Neil Shapiro # endif /* !HASFLOCK */
3812c2aa98e2SPeter Wemm 	if (tTd(55, 60))
38133299c2f1SGregory Neil Shapiro 		dprintf("FAIL\n");
3814c2aa98e2SPeter Wemm 	errno = save_errno;
3815c2aa98e2SPeter Wemm 	return FALSE;
3816c2aa98e2SPeter Wemm }
3817c2aa98e2SPeter Wemm /*
3818c2aa98e2SPeter Wemm **  CHOWNSAFE -- tell if chown is "safe" (executable only by root)
3819c2aa98e2SPeter Wemm **
3820c2aa98e2SPeter Wemm **	Unfortunately, given that we can't predict other systems on which
3821c2aa98e2SPeter Wemm **	a remote mounted (NFS) filesystem will be mounted, the answer is
3822c2aa98e2SPeter Wemm **	almost always that this is unsafe.
3823c2aa98e2SPeter Wemm **
3824c2aa98e2SPeter Wemm **	Note also that many operating systems have non-compliant
3825c2aa98e2SPeter Wemm **	implementations of the _POSIX_CHOWN_RESTRICTED variable and the
3826c2aa98e2SPeter Wemm **	fpathconf() routine.  According to IEEE 1003.1-1990, if
3827c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
3828c2aa98e2SPeter Wemm **	no non-root process can give away the file.  However, vendors
3829c2aa98e2SPeter Wemm **	don't take NFS into account, so a comfortable value of
3830c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED tells us nothing.
3831c2aa98e2SPeter Wemm **
3832c2aa98e2SPeter Wemm **	Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
3833c2aa98e2SPeter Wemm **	even on files where chown is not restricted.  Many systems get
3834c2aa98e2SPeter Wemm **	this wrong on NFS-based filesystems (that is, they say that chown
3835c2aa98e2SPeter Wemm **	is restricted [safe] on NFS filesystems where it may not be, since
3836c2aa98e2SPeter Wemm **	other systems can access the same filesystem and do file giveaway;
3837c2aa98e2SPeter Wemm **	only the NFS server knows for sure!)  Hence, it is important to
3838c2aa98e2SPeter Wemm **	get the value of SAFENFSPATHCONF correct -- it should be defined
3839c2aa98e2SPeter Wemm **	_only_ after testing (see test/t_pathconf.c) a system on an unsafe
3840c2aa98e2SPeter Wemm **	NFS-based filesystem to ensure that you can get meaningful results.
3841c2aa98e2SPeter Wemm **	If in doubt, assume unsafe!
3842c2aa98e2SPeter Wemm **
3843c2aa98e2SPeter Wemm **	You may also need to tweak IS_SAFE_CHOWN -- it should be a
3844c2aa98e2SPeter Wemm **	condition indicating whether the return from pathconf indicates
3845c2aa98e2SPeter Wemm **	that chown is safe (typically either > 0 or >= 0 -- there isn't
3846c2aa98e2SPeter Wemm **	even any agreement about whether a zero return means that a file
3847c2aa98e2SPeter Wemm **	is or is not safe).  It defaults to "> 0".
3848c2aa98e2SPeter Wemm **
3849c2aa98e2SPeter Wemm **	If the parent directory is safe (writable only by owner back
3850c2aa98e2SPeter Wemm **	to the root) then we can relax slightly and trust fpathconf
3851c2aa98e2SPeter Wemm **	in more circumstances.  This is really a crock -- if this is an
3852c2aa98e2SPeter Wemm **	NFS mounted filesystem then we really know nothing about the
3853c2aa98e2SPeter Wemm **	underlying implementation.  However, most systems pessimize and
3854c2aa98e2SPeter Wemm **	return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
3855c2aa98e2SPeter Wemm **	we interpret as unsafe, as we should.  Thus, this heuristic gets
3856c2aa98e2SPeter Wemm **	us into a possible problem only on systems that have a broken
3857c2aa98e2SPeter Wemm **	pathconf implementation and which are also poorly configured
3858c2aa98e2SPeter Wemm **	(have :include: files in group- or world-writable directories).
3859c2aa98e2SPeter Wemm **
3860c2aa98e2SPeter Wemm **	Parameters:
3861c2aa98e2SPeter Wemm **		fd -- the file descriptor to check.
3862c2aa98e2SPeter Wemm **		safedir -- set if the parent directory is safe.
3863c2aa98e2SPeter Wemm **
3864c2aa98e2SPeter Wemm **	Returns:
3865c2aa98e2SPeter Wemm **		TRUE -- if the chown(2) operation is "safe" -- that is,
3866c2aa98e2SPeter Wemm **			only root can chown the file to an arbitrary user.
3867c2aa98e2SPeter Wemm **		FALSE -- if an arbitrary user can give away a file.
3868c2aa98e2SPeter Wemm */
3869c2aa98e2SPeter Wemm 
3870c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN
3871c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN	> 0
38723299c2f1SGregory Neil Shapiro #endif /* ! IS_SAFE_CHOWN */
3873c2aa98e2SPeter Wemm 
3874c2aa98e2SPeter Wemm bool
3875c2aa98e2SPeter Wemm chownsafe(fd, safedir)
3876c2aa98e2SPeter Wemm 	int fd;
3877c2aa98e2SPeter Wemm 	bool safedir;
3878c2aa98e2SPeter Wemm {
3879c2aa98e2SPeter Wemm # if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \
3880c2aa98e2SPeter Wemm     (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H))
3881c2aa98e2SPeter Wemm 	int rval;
3882c2aa98e2SPeter Wemm 
3883c2aa98e2SPeter Wemm 	/* give the system administrator a chance to override */
38843299c2f1SGregory Neil Shapiro 	if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail))
3885c2aa98e2SPeter Wemm 		return TRUE;
3886c2aa98e2SPeter Wemm 
3887c2aa98e2SPeter Wemm 	/*
3888c2aa98e2SPeter Wemm 	**  Some systems (e.g., SunOS) seem to have the call and the
3889c2aa98e2SPeter Wemm 	**  #define _PC_CHOWN_RESTRICTED, but don't actually implement
3890c2aa98e2SPeter Wemm 	**  the call.  This heuristic checks for that.
3891c2aa98e2SPeter Wemm 	*/
3892c2aa98e2SPeter Wemm 
3893c2aa98e2SPeter Wemm 	errno = 0;
3894c2aa98e2SPeter Wemm 	rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
3895c2aa98e2SPeter Wemm #  if SAFENFSPATHCONF
3896c2aa98e2SPeter Wemm 	return errno == 0 && rval IS_SAFE_CHOWN;
38973299c2f1SGregory Neil Shapiro #  else /* SAFENFSPATHCONF */
3898c2aa98e2SPeter Wemm 	return safedir && errno == 0 && rval IS_SAFE_CHOWN;
38993299c2f1SGregory Neil Shapiro #  endif /* SAFENFSPATHCONF */
39003299c2f1SGregory Neil Shapiro # else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ */
39013299c2f1SGregory Neil Shapiro 	return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
39023299c2f1SGregory Neil Shapiro # endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ */
3903c2aa98e2SPeter Wemm }
3904c2aa98e2SPeter Wemm /*
3905c2aa98e2SPeter Wemm **  RESETLIMITS -- reset system controlled resource limits
3906c2aa98e2SPeter Wemm **
3907c2aa98e2SPeter Wemm **	This is to avoid denial-of-service attacks
3908c2aa98e2SPeter Wemm **
3909c2aa98e2SPeter Wemm **	Parameters:
3910c2aa98e2SPeter Wemm **		none
3911c2aa98e2SPeter Wemm **
3912c2aa98e2SPeter Wemm **	Returns:
3913c2aa98e2SPeter Wemm **		none
3914c2aa98e2SPeter Wemm */
3915c2aa98e2SPeter Wemm 
3916c2aa98e2SPeter Wemm #if HASSETRLIMIT
3917c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H
3918c2aa98e2SPeter Wemm #  include <sys/time.h>
39193299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NEEDS_SYS_TIME_H */
3920c2aa98e2SPeter Wemm # include <sys/resource.h>
39213299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3922c2aa98e2SPeter Wemm #ifndef FD_SETSIZE
3923c2aa98e2SPeter Wemm # define FD_SETSIZE	256
39243299c2f1SGregory Neil Shapiro #endif /* ! FD_SETSIZE */
3925c2aa98e2SPeter Wemm 
3926c2aa98e2SPeter Wemm void
3927c2aa98e2SPeter Wemm resetlimits()
3928c2aa98e2SPeter Wemm {
3929c2aa98e2SPeter Wemm #if HASSETRLIMIT
3930c2aa98e2SPeter Wemm 	struct rlimit lim;
3931c2aa98e2SPeter Wemm 
3932c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
3933c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_CPU, &lim);
3934c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_FSIZE, &lim);
3935c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
3936c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
3937c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_NOFILE, &lim);
39383299c2f1SGregory Neil Shapiro # endif /* RLIMIT_NOFILE */
39393299c2f1SGregory Neil Shapiro #else /* HASSETRLIMIT */
3940c2aa98e2SPeter Wemm # if HASULIMIT
3941c2aa98e2SPeter Wemm 	(void) ulimit(2, 0x3fffff);
3942c2aa98e2SPeter Wemm 	(void) ulimit(4, FD_SETSIZE);
39433299c2f1SGregory Neil Shapiro # endif /* HASULIMIT */
39443299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3945c2aa98e2SPeter Wemm 	errno = 0;
3946c2aa98e2SPeter Wemm }
3947c2aa98e2SPeter Wemm /*
3948c2aa98e2SPeter Wemm **  GETCFNAME -- return the name of the .cf file.
3949c2aa98e2SPeter Wemm **
3950c2aa98e2SPeter Wemm **	Some systems (e.g., NeXT) determine this dynamically.
3951c2aa98e2SPeter Wemm */
3952c2aa98e2SPeter Wemm 
3953c2aa98e2SPeter Wemm char *
3954c2aa98e2SPeter Wemm getcfname()
3955c2aa98e2SPeter Wemm {
3956c2aa98e2SPeter Wemm 
3957c2aa98e2SPeter Wemm 	if (ConfFile != NULL)
3958c2aa98e2SPeter Wemm 		return ConfFile;
3959c2aa98e2SPeter Wemm #if NETINFO
3960c2aa98e2SPeter Wemm 	{
3961c2aa98e2SPeter Wemm 		char *cflocation;
3962c2aa98e2SPeter Wemm 
3963c2aa98e2SPeter Wemm 		cflocation = ni_propval("/locations", NULL, "sendmail",
3964c2aa98e2SPeter Wemm 					"sendmail.cf", '\0');
3965c2aa98e2SPeter Wemm 		if (cflocation != NULL)
3966c2aa98e2SPeter Wemm 			return cflocation;
3967c2aa98e2SPeter Wemm 	}
39683299c2f1SGregory Neil Shapiro #endif /* NETINFO */
3969c2aa98e2SPeter Wemm 
3970c2aa98e2SPeter Wemm 	return _PATH_SENDMAILCF;
3971c2aa98e2SPeter Wemm }
3972c2aa98e2SPeter Wemm /*
3973c2aa98e2SPeter Wemm **  SETVENDOR -- process vendor code from V configuration line
3974c2aa98e2SPeter Wemm **
3975c2aa98e2SPeter Wemm **	Parameters:
3976c2aa98e2SPeter Wemm **		vendor -- string representation of vendor.
3977c2aa98e2SPeter Wemm **
3978c2aa98e2SPeter Wemm **	Returns:
3979c2aa98e2SPeter Wemm **		TRUE -- if ok.
3980c2aa98e2SPeter Wemm **		FALSE -- if vendor code could not be processed.
3981c2aa98e2SPeter Wemm **
3982c2aa98e2SPeter Wemm **	Side Effects:
3983c2aa98e2SPeter Wemm **		It is reasonable to set mode flags here to tweak
3984c2aa98e2SPeter Wemm **		processing in other parts of the code if necessary.
3985c2aa98e2SPeter Wemm **		For example, if you are a vendor that uses $%y to
3986c2aa98e2SPeter Wemm **		indicate YP lookups, you could enable that here.
3987c2aa98e2SPeter Wemm */
3988c2aa98e2SPeter Wemm 
3989c2aa98e2SPeter Wemm bool
3990c2aa98e2SPeter Wemm setvendor(vendor)
3991c2aa98e2SPeter Wemm 	char *vendor;
3992c2aa98e2SPeter Wemm {
3993c2aa98e2SPeter Wemm 	if (strcasecmp(vendor, "Berkeley") == 0)
3994c2aa98e2SPeter Wemm 	{
3995c2aa98e2SPeter Wemm 		VendorCode = VENDOR_BERKELEY;
3996c2aa98e2SPeter Wemm 		return TRUE;
3997c2aa98e2SPeter Wemm 	}
3998c2aa98e2SPeter Wemm 
3999c2aa98e2SPeter Wemm 	/* add vendor extensions here */
4000c2aa98e2SPeter Wemm 
4001c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
4002c2aa98e2SPeter Wemm 	if (strcasecmp(vendor, "Sun") == 0)
4003c2aa98e2SPeter Wemm 	{
4004c2aa98e2SPeter Wemm 		VendorCode = VENDOR_SUN;
4005c2aa98e2SPeter Wemm 		return TRUE;
4006c2aa98e2SPeter Wemm 	}
40073299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
4008c2aa98e2SPeter Wemm 
400976b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
401076b7bf71SPeter Wemm 	if (strcasecmp(vendor, VENDOR_NAME) == 0)
401176b7bf71SPeter Wemm 	{
401276b7bf71SPeter Wemm 		VendorCode = VENDOR_CODE;
401376b7bf71SPeter Wemm 		return TRUE;
401476b7bf71SPeter Wemm 	}
40153299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
401676b7bf71SPeter Wemm 
4017c2aa98e2SPeter Wemm 	return FALSE;
4018c2aa98e2SPeter Wemm }
4019c2aa98e2SPeter Wemm /*
402076b7bf71SPeter Wemm **  GETVENDOR -- return vendor name based on vendor code
402176b7bf71SPeter Wemm **
402276b7bf71SPeter Wemm **	Parameters:
402376b7bf71SPeter Wemm **		vendorcode -- numeric representation of vendor.
402476b7bf71SPeter Wemm **
402576b7bf71SPeter Wemm **	Returns:
402676b7bf71SPeter Wemm **		string containing vendor name.
402776b7bf71SPeter Wemm */
402876b7bf71SPeter Wemm 
402976b7bf71SPeter Wemm char *
403076b7bf71SPeter Wemm getvendor(vendorcode)
403176b7bf71SPeter Wemm 	int vendorcode;
403276b7bf71SPeter Wemm {
403376b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
403476b7bf71SPeter Wemm 	/*
403576b7bf71SPeter Wemm 	**  Can't have the same switch case twice so need to
403676b7bf71SPeter Wemm 	**  handle VENDOR_CODE outside of switch.  It might
403776b7bf71SPeter Wemm 	**  match one of the existing VENDOR_* codes.
403876b7bf71SPeter Wemm 	*/
403976b7bf71SPeter Wemm 
404076b7bf71SPeter Wemm 	if (vendorcode == VENDOR_CODE)
404176b7bf71SPeter Wemm 		return VENDOR_NAME;
40423299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
404376b7bf71SPeter Wemm 
404476b7bf71SPeter Wemm 	switch (vendorcode)
404576b7bf71SPeter Wemm 	{
404676b7bf71SPeter Wemm 		case VENDOR_BERKELEY:
404776b7bf71SPeter Wemm 			return "Berkeley";
404876b7bf71SPeter Wemm 
404976b7bf71SPeter Wemm 		case VENDOR_SUN:
405076b7bf71SPeter Wemm 			return "Sun";
405176b7bf71SPeter Wemm 
405276b7bf71SPeter Wemm 		case VENDOR_HP:
405376b7bf71SPeter Wemm 			return "HP";
405476b7bf71SPeter Wemm 
405576b7bf71SPeter Wemm 		case VENDOR_IBM:
405676b7bf71SPeter Wemm 			return "IBM";
405776b7bf71SPeter Wemm 
405876b7bf71SPeter Wemm 		case VENDOR_SENDMAIL:
405976b7bf71SPeter Wemm 			return "Sendmail";
406076b7bf71SPeter Wemm 
406176b7bf71SPeter Wemm 		default:
406276b7bf71SPeter Wemm 			return "Unknown";
406376b7bf71SPeter Wemm 	}
406476b7bf71SPeter Wemm }
406576b7bf71SPeter Wemm /*
4066c2aa98e2SPeter Wemm **  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
4067c2aa98e2SPeter Wemm **
4068c2aa98e2SPeter Wemm **	Vendor_pre_defaults is called before reading the configuration
4069c2aa98e2SPeter Wemm **	file; vendor_post_defaults is called immediately after.
4070c2aa98e2SPeter Wemm **
4071c2aa98e2SPeter Wemm **	Parameters:
4072c2aa98e2SPeter Wemm **		e -- the global environment to initialize.
4073c2aa98e2SPeter Wemm **
4074c2aa98e2SPeter Wemm **	Returns:
4075c2aa98e2SPeter Wemm **		none.
4076c2aa98e2SPeter Wemm */
4077c2aa98e2SPeter Wemm 
4078c2aa98e2SPeter Wemm #if SHARE_V1
4079c2aa98e2SPeter Wemm int	DefShareUid;	/* default share uid to run as -- unused??? */
40803299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
4081c2aa98e2SPeter Wemm 
4082c2aa98e2SPeter Wemm void
4083c2aa98e2SPeter Wemm vendor_pre_defaults(e)
4084c2aa98e2SPeter Wemm 	ENVELOPE *e;
4085c2aa98e2SPeter Wemm {
4086c2aa98e2SPeter Wemm #if SHARE_V1
4087c2aa98e2SPeter Wemm 	/* OTHERUID is defined in shares.h, do not be alarmed */
4088c2aa98e2SPeter Wemm 	DefShareUid = OTHERUID;
40893299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
4090c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
4091c2aa98e2SPeter Wemm 	sun_pre_defaults(e);
40923299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
4093c2aa98e2SPeter Wemm #ifdef apollo
40943299c2f1SGregory Neil Shapiro 	/*
40953299c2f1SGregory Neil Shapiro 	**  stupid domain/os can't even open
40963299c2f1SGregory Neil Shapiro 	**  /etc/mail/sendmail.cf without this
40973299c2f1SGregory Neil Shapiro 	*/
40983299c2f1SGregory Neil Shapiro 
4099c2aa98e2SPeter Wemm 	setuserenv("ISP", NULL);
4100c2aa98e2SPeter Wemm 	setuserenv("SYSTYPE", NULL);
41013299c2f1SGregory Neil Shapiro #endif /* apollo */
4102c2aa98e2SPeter Wemm }
4103c2aa98e2SPeter Wemm 
4104c2aa98e2SPeter Wemm 
4105c2aa98e2SPeter Wemm void
4106c2aa98e2SPeter Wemm vendor_post_defaults(e)
4107c2aa98e2SPeter Wemm 	ENVELOPE *e;
4108c2aa98e2SPeter Wemm {
4109c2aa98e2SPeter Wemm #ifdef __QNX__
4110c2aa98e2SPeter Wemm 	char *p;
4111c2aa98e2SPeter Wemm 
4112c2aa98e2SPeter Wemm 	/* Makes sure the SOCK environment variable remains */
4113c2aa98e2SPeter Wemm 	if (p = getextenv("SOCK"))
4114c2aa98e2SPeter Wemm 		setuserenv("SOCK", p);
41153299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
4116c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
4117c2aa98e2SPeter Wemm 	sun_post_defaults(e);
41183299c2f1SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
4119c2aa98e2SPeter Wemm }
4120c2aa98e2SPeter Wemm /*
4121c2aa98e2SPeter Wemm **  VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
4122c2aa98e2SPeter Wemm */
4123c2aa98e2SPeter Wemm 
4124c2aa98e2SPeter Wemm void
4125c2aa98e2SPeter Wemm vendor_daemon_setup(e)
4126c2aa98e2SPeter Wemm 	ENVELOPE *e;
4127c2aa98e2SPeter Wemm {
41283299c2f1SGregory Neil Shapiro #if HASSETLOGIN
41293299c2f1SGregory Neil Shapiro 	(void) setlogin(RunAsUserName);
41303299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
4131c2aa98e2SPeter Wemm #if SECUREWARE
4132c2aa98e2SPeter Wemm 	if (getluid() != -1)
4133c2aa98e2SPeter Wemm 	{
4134c2aa98e2SPeter Wemm 		usrerr("Daemon cannot have LUID");
413576b7bf71SPeter Wemm 		finis(FALSE, EX_USAGE);
4136c2aa98e2SPeter Wemm 	}
4137c2aa98e2SPeter Wemm #endif /* SECUREWARE */
4138c2aa98e2SPeter Wemm }
4139c2aa98e2SPeter Wemm /*
4140c2aa98e2SPeter Wemm **  VENDOR_SET_UID -- do setup for setting a user id
4141c2aa98e2SPeter Wemm **
4142c2aa98e2SPeter Wemm **	This is called when we are still root.
4143c2aa98e2SPeter Wemm **
4144c2aa98e2SPeter Wemm **	Parameters:
4145c2aa98e2SPeter Wemm **		uid -- the uid we are about to become.
4146c2aa98e2SPeter Wemm **
4147c2aa98e2SPeter Wemm **	Returns:
4148c2aa98e2SPeter Wemm **		none.
4149c2aa98e2SPeter Wemm */
4150c2aa98e2SPeter Wemm 
4151c2aa98e2SPeter Wemm void
4152c2aa98e2SPeter Wemm vendor_set_uid(uid)
4153c2aa98e2SPeter Wemm 	UID_T uid;
4154c2aa98e2SPeter Wemm {
4155c2aa98e2SPeter Wemm 	/*
4156c2aa98e2SPeter Wemm 	**  We need to setup the share groups (lnodes)
41573299c2f1SGregory Neil Shapiro 	**  and add auditing information (luid's)
4158c2aa98e2SPeter Wemm 	**  before we loose our ``root''ness.
4159c2aa98e2SPeter Wemm 	*/
4160c2aa98e2SPeter Wemm #if SHARE_V1
4161c2aa98e2SPeter Wemm 	if (setupshares(uid, syserr) != 0)
4162c2aa98e2SPeter Wemm 		syserr("Unable to set up shares");
41633299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
4164c2aa98e2SPeter Wemm #if SECUREWARE
4165c2aa98e2SPeter Wemm 	(void) setup_secure(uid);
41663299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
4167c2aa98e2SPeter Wemm }
4168c2aa98e2SPeter Wemm /*
4169c2aa98e2SPeter Wemm **  VALIDATE_CONNECTION -- check connection for rationality
4170c2aa98e2SPeter Wemm **
4171c2aa98e2SPeter Wemm **	If the connection is rejected, this routine should log an
4172c2aa98e2SPeter Wemm **	appropriate message -- but should never issue any SMTP protocol.
4173c2aa98e2SPeter Wemm **
4174c2aa98e2SPeter Wemm **	Parameters:
4175c2aa98e2SPeter Wemm **		sap -- a pointer to a SOCKADDR naming the peer.
4176c2aa98e2SPeter Wemm **		hostname -- the name corresponding to sap.
4177c2aa98e2SPeter Wemm **		e -- the current envelope.
4178c2aa98e2SPeter Wemm **
4179c2aa98e2SPeter Wemm **	Returns:
4180c2aa98e2SPeter Wemm **		error message from rejection.
4181c2aa98e2SPeter Wemm **		NULL if not rejected.
4182c2aa98e2SPeter Wemm */
4183c2aa98e2SPeter Wemm 
4184c2aa98e2SPeter Wemm #if TCPWRAPPERS
4185c2aa98e2SPeter Wemm # include <tcpd.h>
4186c2aa98e2SPeter Wemm 
4187c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */
4188c2aa98e2SPeter Wemm int	allow_severity	= LOG_INFO;
4189c2aa98e2SPeter Wemm int	deny_severity	= LOG_NOTICE;
41903299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
4191c2aa98e2SPeter Wemm 
4192c2aa98e2SPeter Wemm #if DAEMON
4193c2aa98e2SPeter Wemm char *
4194c2aa98e2SPeter Wemm validate_connection(sap, hostname, e)
4195c2aa98e2SPeter Wemm 	SOCKADDR *sap;
4196c2aa98e2SPeter Wemm 	char *hostname;
4197c2aa98e2SPeter Wemm 	ENVELOPE *e;
4198c2aa98e2SPeter Wemm {
4199c2aa98e2SPeter Wemm # if TCPWRAPPERS
4200c2aa98e2SPeter Wemm 	char *host;
42013299c2f1SGregory Neil Shapiro # endif /* TCPWRAPPERS */
4202c2aa98e2SPeter Wemm 
4203c2aa98e2SPeter Wemm 	if (tTd(48, 3))
42043299c2f1SGregory Neil Shapiro 		dprintf("validate_connection(%s, %s)\n",
4205c2aa98e2SPeter Wemm 			hostname, anynet_ntoa(sap));
4206c2aa98e2SPeter Wemm 
42073299c2f1SGregory Neil Shapiro 	if (rscheck("check_relay", hostname, anynet_ntoa(sap),
4208c46d91b7SGregory Neil Shapiro 		    e, TRUE, TRUE, 4, NULL) != EX_OK)
4209c2aa98e2SPeter Wemm 	{
4210c2aa98e2SPeter Wemm 		static char reject[BUFSIZ*2];
4211c2aa98e2SPeter Wemm 		extern char MsgBuf[];
4212c2aa98e2SPeter Wemm 
4213c2aa98e2SPeter Wemm 		if (tTd(48, 4))
42143299c2f1SGregory Neil Shapiro 			dprintf("  ... validate_connection: BAD (rscheck)\n");
4215c2aa98e2SPeter Wemm 
42163299c2f1SGregory Neil Shapiro 		if (strlen(MsgBuf) >= 3)
42173299c2f1SGregory Neil Shapiro 			(void) strlcpy(reject, MsgBuf, sizeof reject);
4218c2aa98e2SPeter Wemm 		else
42193299c2f1SGregory Neil Shapiro 			(void) strlcpy(reject, "Access denied", sizeof reject);
4220c2aa98e2SPeter Wemm 
4221c2aa98e2SPeter Wemm 		return reject;
4222c2aa98e2SPeter Wemm 	}
4223c2aa98e2SPeter Wemm 
4224c2aa98e2SPeter Wemm # if TCPWRAPPERS
4225c2aa98e2SPeter Wemm 	if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']')
4226c2aa98e2SPeter Wemm 		host = "unknown";
4227c2aa98e2SPeter Wemm 	else
4228c2aa98e2SPeter Wemm 		host = hostname;
4229c2aa98e2SPeter Wemm 	if (!hosts_ctl("sendmail", host, anynet_ntoa(sap), STRING_UNKNOWN))
4230c2aa98e2SPeter Wemm 	{
4231c2aa98e2SPeter Wemm 		if (tTd(48, 4))
42323299c2f1SGregory Neil Shapiro 			dprintf("  ... validate_connection: BAD (tcpwrappers)\n");
4233c2aa98e2SPeter Wemm 		if (LogLevel >= 4)
42343299c2f1SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, e->e_id,
4235c2aa98e2SPeter Wemm 				"tcpwrappers (%s, %s) rejection",
4236c2aa98e2SPeter Wemm 				host, anynet_ntoa(sap));
4237c2aa98e2SPeter Wemm 		return "Access denied";
4238c2aa98e2SPeter Wemm 	}
42393299c2f1SGregory Neil Shapiro # endif /* TCPWRAPPERS */
4240c2aa98e2SPeter Wemm 	if (tTd(48, 4))
42413299c2f1SGregory Neil Shapiro 		dprintf("  ... validate_connection: OK\n");
4242c2aa98e2SPeter Wemm 	return NULL;
4243c2aa98e2SPeter Wemm }
4244c2aa98e2SPeter Wemm 
42453299c2f1SGregory Neil Shapiro #endif /* DAEMON */
4246c2aa98e2SPeter Wemm /*
4247c2aa98e2SPeter Wemm **  STRTOL -- convert string to long integer
4248c2aa98e2SPeter Wemm **
4249c2aa98e2SPeter Wemm **	For systems that don't have it in the C library.
4250c2aa98e2SPeter Wemm **
4251c2aa98e2SPeter Wemm **	This is taken verbatim from the 4.4-Lite C library.
4252c2aa98e2SPeter Wemm */
4253c2aa98e2SPeter Wemm 
42543299c2f1SGregory Neil Shapiro #if NEEDSTRTOL
4255c2aa98e2SPeter Wemm 
4256c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
4257c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c	8.1 (Berkeley) 6/4/93";
42583299c2f1SGregory Neil Shapiro # endif /* defined(LIBC_SCCS) && !defined(lint) */
4259c2aa98e2SPeter Wemm 
4260c2aa98e2SPeter Wemm /*
4261c2aa98e2SPeter Wemm  * Convert a string to a long integer.
4262c2aa98e2SPeter Wemm  *
4263c2aa98e2SPeter Wemm  * Ignores `locale' stuff.  Assumes that the upper and lower case
4264c2aa98e2SPeter Wemm  * alphabets and digits are each contiguous.
4265c2aa98e2SPeter Wemm  */
4266c2aa98e2SPeter Wemm 
4267c2aa98e2SPeter Wemm long
4268c2aa98e2SPeter Wemm strtol(nptr, endptr, base)
4269c2aa98e2SPeter Wemm 	const char *nptr;
4270c2aa98e2SPeter Wemm 	char **endptr;
4271c2aa98e2SPeter Wemm 	register int base;
4272c2aa98e2SPeter Wemm {
4273c2aa98e2SPeter Wemm 	register const char *s = nptr;
4274c2aa98e2SPeter Wemm 	register unsigned long acc;
4275c2aa98e2SPeter Wemm 	register int c;
4276c2aa98e2SPeter Wemm 	register unsigned long cutoff;
4277c2aa98e2SPeter Wemm 	register int neg = 0, any, cutlim;
4278c2aa98e2SPeter Wemm 
4279c2aa98e2SPeter Wemm 	/*
4280c2aa98e2SPeter Wemm 	 * Skip white space and pick up leading +/- sign if any.
4281c2aa98e2SPeter Wemm 	 * If base is 0, allow 0x for hex and 0 for octal, else
4282c2aa98e2SPeter Wemm 	 * assume decimal; if base is already 16, allow 0x.
4283c2aa98e2SPeter Wemm 	 */
4284c2aa98e2SPeter Wemm 	do {
4285c2aa98e2SPeter Wemm 		c = *s++;
4286c2aa98e2SPeter Wemm 	} while (isspace(c));
4287c2aa98e2SPeter Wemm 	if (c == '-') {
4288c2aa98e2SPeter Wemm 		neg = 1;
4289c2aa98e2SPeter Wemm 		c = *s++;
4290c2aa98e2SPeter Wemm 	} else if (c == '+')
4291c2aa98e2SPeter Wemm 		c = *s++;
4292c2aa98e2SPeter Wemm 	if ((base == 0 || base == 16) &&
4293c2aa98e2SPeter Wemm 	    c == '0' && (*s == 'x' || *s == 'X')) {
4294c2aa98e2SPeter Wemm 		c = s[1];
4295c2aa98e2SPeter Wemm 		s += 2;
4296c2aa98e2SPeter Wemm 		base = 16;
4297c2aa98e2SPeter Wemm 	}
4298c2aa98e2SPeter Wemm 	if (base == 0)
4299c2aa98e2SPeter Wemm 		base = c == '0' ? 8 : 10;
4300c2aa98e2SPeter Wemm 
4301c2aa98e2SPeter Wemm 	/*
4302c2aa98e2SPeter Wemm 	 * Compute the cutoff value between legal numbers and illegal
4303c2aa98e2SPeter Wemm 	 * numbers.  That is the largest legal value, divided by the
4304c2aa98e2SPeter Wemm 	 * base.  An input number that is greater than this value, if
4305c2aa98e2SPeter Wemm 	 * followed by a legal input character, is too big.  One that
4306c2aa98e2SPeter Wemm 	 * is equal to this value may be valid or not; the limit
4307c2aa98e2SPeter Wemm 	 * between valid and invalid numbers is then based on the last
4308c2aa98e2SPeter Wemm 	 * digit.  For instance, if the range for longs is
4309c2aa98e2SPeter Wemm 	 * [-2147483648..2147483647] and the input base is 10,
4310c2aa98e2SPeter Wemm 	 * cutoff will be set to 214748364 and cutlim to either
4311c2aa98e2SPeter Wemm 	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
4312c2aa98e2SPeter Wemm 	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
4313c2aa98e2SPeter Wemm 	 * the number is too big, and we will return a range error.
4314c2aa98e2SPeter Wemm 	 *
4315c2aa98e2SPeter Wemm 	 * Set any if any `digits' consumed; make it negative to indicate
4316c2aa98e2SPeter Wemm 	 * overflow.
4317c2aa98e2SPeter Wemm 	 */
4318c2aa98e2SPeter Wemm 	cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
4319c2aa98e2SPeter Wemm 	cutlim = cutoff % (unsigned long)base;
4320c2aa98e2SPeter Wemm 	cutoff /= (unsigned long)base;
4321c2aa98e2SPeter Wemm 	for (acc = 0, any = 0;; c = *s++) {
4322c2aa98e2SPeter Wemm 		if (isdigit(c))
4323c2aa98e2SPeter Wemm 			c -= '0';
4324c2aa98e2SPeter Wemm 		else if (isalpha(c))
4325c2aa98e2SPeter Wemm 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4326c2aa98e2SPeter Wemm 		else
4327c2aa98e2SPeter Wemm 			break;
4328c2aa98e2SPeter Wemm 		if (c >= base)
4329c2aa98e2SPeter Wemm 			break;
4330c2aa98e2SPeter Wemm 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
4331c2aa98e2SPeter Wemm 			any = -1;
4332c2aa98e2SPeter Wemm 		else {
4333c2aa98e2SPeter Wemm 			any = 1;
4334c2aa98e2SPeter Wemm 			acc *= base;
4335c2aa98e2SPeter Wemm 			acc += c;
4336c2aa98e2SPeter Wemm 		}
4337c2aa98e2SPeter Wemm 	}
4338c2aa98e2SPeter Wemm 	if (any < 0) {
4339c2aa98e2SPeter Wemm 		acc = neg ? LONG_MIN : LONG_MAX;
4340c2aa98e2SPeter Wemm 		errno = ERANGE;
4341c2aa98e2SPeter Wemm 	} else if (neg)
4342c2aa98e2SPeter Wemm 		acc = -acc;
4343c2aa98e2SPeter Wemm 	if (endptr != 0)
4344c2aa98e2SPeter Wemm 		*endptr = (char *)(any ? s - 1 : nptr);
43453299c2f1SGregory Neil Shapiro 	return acc;
4346c2aa98e2SPeter Wemm }
4347c2aa98e2SPeter Wemm 
43483299c2f1SGregory Neil Shapiro #endif /* NEEDSTRTOL */
4349c2aa98e2SPeter Wemm /*
4350c2aa98e2SPeter Wemm **  STRSTR -- find first substring in string
4351c2aa98e2SPeter Wemm **
4352c2aa98e2SPeter Wemm **	Parameters:
4353c2aa98e2SPeter Wemm **		big -- the big (full) string.
4354c2aa98e2SPeter Wemm **		little -- the little (sub) string.
4355c2aa98e2SPeter Wemm **
4356c2aa98e2SPeter Wemm **	Returns:
4357c2aa98e2SPeter Wemm **		A pointer to the first instance of little in big.
4358c2aa98e2SPeter Wemm **		big if little is the null string.
4359c2aa98e2SPeter Wemm **		NULL if little is not contained in big.
4360c2aa98e2SPeter Wemm */
4361c2aa98e2SPeter Wemm 
43623299c2f1SGregory Neil Shapiro #if NEEDSTRSTR
4363c2aa98e2SPeter Wemm 
4364c2aa98e2SPeter Wemm char *
4365c2aa98e2SPeter Wemm strstr(big, little)
4366c2aa98e2SPeter Wemm 	char *big;
4367c2aa98e2SPeter Wemm 	char *little;
4368c2aa98e2SPeter Wemm {
4369c2aa98e2SPeter Wemm 	register char *p = big;
4370c2aa98e2SPeter Wemm 	int l;
4371c2aa98e2SPeter Wemm 
4372c2aa98e2SPeter Wemm 	if (*little == '\0')
4373c2aa98e2SPeter Wemm 		return big;
4374c2aa98e2SPeter Wemm 	l = strlen(little);
4375c2aa98e2SPeter Wemm 
4376c2aa98e2SPeter Wemm 	while ((p = strchr(p, *little)) != NULL)
4377c2aa98e2SPeter Wemm 	{
4378c2aa98e2SPeter Wemm 		if (strncmp(p, little, l) == 0)
4379c2aa98e2SPeter Wemm 			return p;
4380c2aa98e2SPeter Wemm 		p++;
4381c2aa98e2SPeter Wemm 	}
4382c2aa98e2SPeter Wemm 	return NULL;
4383c2aa98e2SPeter Wemm }
4384c2aa98e2SPeter Wemm 
43853299c2f1SGregory Neil Shapiro #endif /* NEEDSTRSTR */
4386c2aa98e2SPeter Wemm /*
4387c2aa98e2SPeter Wemm **  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
4388c2aa98e2SPeter Wemm **
4389c2aa98e2SPeter Wemm **	Some operating systems have wierd problems with the gethostbyXXX
4390c2aa98e2SPeter Wemm **	routines.  For example, Solaris versions at least through 2.3
4391c2aa98e2SPeter Wemm **	don't properly deliver a canonical h_name field.  This tries to
4392c2aa98e2SPeter Wemm **	work around these problems.
43933299c2f1SGregory Neil Shapiro **
43943299c2f1SGregory Neil Shapiro **	Support IPv6 as well as IPv4.
4395c2aa98e2SPeter Wemm */
4396c2aa98e2SPeter Wemm 
4397c0c4794dSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
43983299c2f1SGregory Neil Shapiro 
43993299c2f1SGregory Neil Shapiro # ifndef AI_DEFAULT
44003299c2f1SGregory Neil Shapiro #  define AI_DEFAULT	0	/* dummy */
44013299c2f1SGregory Neil Shapiro # endif /* ! AI_DEFAULT */
44023299c2f1SGregory Neil Shapiro # ifndef AI_ADDRCONFIG
44033299c2f1SGregory Neil Shapiro #  define AI_ADDRCONFIG	0	/* dummy */
44043299c2f1SGregory Neil Shapiro # endif /* ! AI_ADDRCONFIG */
44053299c2f1SGregory Neil Shapiro # ifndef AI_V4MAPPED
44063299c2f1SGregory Neil Shapiro #  define AI_V4MAPPED	0	/* dummy */
44073299c2f1SGregory Neil Shapiro # endif /* ! AI_V4MAPPED */
44083299c2f1SGregory Neil Shapiro # ifndef AI_ALL
44093299c2f1SGregory Neil Shapiro #  define AI_ALL	0	/* dummy */
44103299c2f1SGregory Neil Shapiro # endif /* ! AI_ALL */
44113299c2f1SGregory Neil Shapiro 
44123299c2f1SGregory Neil Shapiro static struct hostent *
44133299c2f1SGregory Neil Shapiro getipnodebyname(name, family, flags, err)
4414c2aa98e2SPeter Wemm 	char *name;
44153299c2f1SGregory Neil Shapiro 	int family;
44163299c2f1SGregory Neil Shapiro 	int flags;
44173299c2f1SGregory Neil Shapiro 	int *err;
44183299c2f1SGregory Neil Shapiro {
44193299c2f1SGregory Neil Shapiro 	bool resv6 = TRUE;
44203299c2f1SGregory Neil Shapiro 	struct hostent *h;
44213299c2f1SGregory Neil Shapiro 
44223299c2f1SGregory Neil Shapiro 	if (family == AF_INET6)
44233299c2f1SGregory Neil Shapiro 	{
44243299c2f1SGregory Neil Shapiro 		/* From RFC2133, section 6.1 */
44253299c2f1SGregory Neil Shapiro 		resv6 = bitset(RES_USE_INET6, _res.options);
44263299c2f1SGregory Neil Shapiro 		_res.options |= RES_USE_INET6;
44273299c2f1SGregory Neil Shapiro 	}
4428b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
44293299c2f1SGregory Neil Shapiro 	h = gethostbyname(name);
44303299c2f1SGregory Neil Shapiro 	*err = h_errno;
44313299c2f1SGregory Neil Shapiro 	if (family == AF_INET6 && !resv6)
44323299c2f1SGregory Neil Shapiro 		_res.options &= ~RES_USE_INET6;
44333299c2f1SGregory Neil Shapiro 	return h;
44343299c2f1SGregory Neil Shapiro }
44353299c2f1SGregory Neil Shapiro 
44363299c2f1SGregory Neil Shapiro static struct hostent *
44373299c2f1SGregory Neil Shapiro getipnodebyaddr(addr, len, family, err)
44383299c2f1SGregory Neil Shapiro 	char *addr;
44393299c2f1SGregory Neil Shapiro 	int len;
44403299c2f1SGregory Neil Shapiro 	int family;
44413299c2f1SGregory Neil Shapiro 	int *err;
4442c2aa98e2SPeter Wemm {
4443c2aa98e2SPeter Wemm 	struct hostent *h;
44443299c2f1SGregory Neil Shapiro 
4445b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
44463299c2f1SGregory Neil Shapiro 	h = gethostbyaddr(addr, len, family);
44473299c2f1SGregory Neil Shapiro 	*err = h_errno;
44483299c2f1SGregory Neil Shapiro 	return h;
44493299c2f1SGregory Neil Shapiro }
4450c46d91b7SGregory Neil Shapiro 
4451c46d91b7SGregory Neil Shapiro # if _FFR_FREEHOSTENT
4452c46d91b7SGregory Neil Shapiro void
4453c46d91b7SGregory Neil Shapiro freehostent(h)
4454c46d91b7SGregory Neil Shapiro 	struct hostent *h;
4455c46d91b7SGregory Neil Shapiro {
4456c46d91b7SGregory Neil Shapiro 	/*
4457c46d91b7SGregory Neil Shapiro 	**  Stub routine -- if they don't have getipnodeby*(),
4458c46d91b7SGregory Neil Shapiro 	**  they probably don't have the free routine either.
4459c46d91b7SGregory Neil Shapiro 	*/
4460c46d91b7SGregory Neil Shapiro 
4461c46d91b7SGregory Neil Shapiro 	return;
4462c46d91b7SGregory Neil Shapiro }
4463c46d91b7SGregory Neil Shapiro # endif /* _FFR_FREEHOSTENT */
4464c0c4794dSGregory Neil Shapiro #endif /* NEEDSGETIPNODE && NETINET6 */
44653299c2f1SGregory Neil Shapiro 
44663299c2f1SGregory Neil Shapiro struct hostent *
44673299c2f1SGregory Neil Shapiro sm_gethostbyname(name, family)
44683299c2f1SGregory Neil Shapiro 	char *name;
44693299c2f1SGregory Neil Shapiro 	int family;
44703299c2f1SGregory Neil Shapiro {
4471b4662009SGregory Neil Shapiro 	int save_errno;
44723299c2f1SGregory Neil Shapiro 	struct hostent *h = NULL;
4473c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
4474c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4475c2aa98e2SPeter Wemm 	static struct hostent hp;
4476c2aa98e2SPeter Wemm 	static char buf[1000];
4477c2aa98e2SPeter Wemm 	extern struct hostent *_switch_gethostbyname_r();
4478c2aa98e2SPeter Wemm 
4479c2aa98e2SPeter Wemm 	if (tTd(61, 10))
44803299c2f1SGregory Neil Shapiro 		dprintf("_switch_gethostbyname_r(%s)... ", name);
4481c2aa98e2SPeter Wemm 	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
4482b4662009SGregory Neil Shapiro 	save_errno = errno;
44833299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4484c2aa98e2SPeter Wemm 	extern struct hostent *__switch_gethostbyname();
4485c2aa98e2SPeter Wemm 
4486c2aa98e2SPeter Wemm 	if (tTd(61, 10))
44873299c2f1SGregory Neil Shapiro 		dprintf("__switch_gethostbyname(%s)... ", name);
4488c2aa98e2SPeter Wemm 	h = __switch_gethostbyname(name);
4489b4662009SGregory Neil Shapiro 	save_errno = errno;
44903299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
44913299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4492c2aa98e2SPeter Wemm 	int nmaps;
44933299c2f1SGregory Neil Shapiro # if NETINET6
44943299c2f1SGregory Neil Shapiro 	int flags = AI_DEFAULT|AI_ALL;
44953299c2f1SGregory Neil Shapiro 	int err;
44963299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4497c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
4498c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
4499c2aa98e2SPeter Wemm 	char hbuf[MAXNAME];
4500c2aa98e2SPeter Wemm 
4501c2aa98e2SPeter Wemm 	if (tTd(61, 10))
45023299c2f1SGregory Neil Shapiro 		dprintf("sm_gethostbyname(%s, %d)... ", name, family);
45033299c2f1SGregory Neil Shapiro 
45043299c2f1SGregory Neil Shapiro # if NETINET6
45053299c2f1SGregory Neil Shapiro #  if ADDRCONFIG_IS_BROKEN
45063299c2f1SGregory Neil Shapiro 	flags &= ~AI_ADDRCONFIG;
45073299c2f1SGregory Neil Shapiro #  endif /* ADDRCONFIG_IS_BROKEN */
45083299c2f1SGregory Neil Shapiro 	h = getipnodebyname(name, family, flags, &err);
4509b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(err);
45103299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4511c2aa98e2SPeter Wemm 	h = gethostbyname(name);
45123299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
45133299c2f1SGregory Neil Shapiro 
45143299c2f1SGregory Neil Shapiro 	save_errno = errno;
4515c2aa98e2SPeter Wemm 	if (h == NULL)
4516c2aa98e2SPeter Wemm 	{
4517c2aa98e2SPeter Wemm 		if (tTd(61, 10))
45183299c2f1SGregory Neil Shapiro 			dprintf("failure\n");
4519c2aa98e2SPeter Wemm 
4520c2aa98e2SPeter Wemm 		nmaps = switch_map_find("hosts", maptype, mapreturn);
4521c2aa98e2SPeter Wemm 		while (--nmaps >= 0)
4522c46d91b7SGregory Neil Shapiro 		{
4523c2aa98e2SPeter Wemm 			if (strcmp(maptype[nmaps], "nis") == 0 ||
4524c2aa98e2SPeter Wemm 			    strcmp(maptype[nmaps], "files") == 0)
4525c2aa98e2SPeter Wemm 				break;
4526c46d91b7SGregory Neil Shapiro 		}
4527c46d91b7SGregory Neil Shapiro 
4528c2aa98e2SPeter Wemm 		if (nmaps >= 0)
4529c2aa98e2SPeter Wemm 		{
4530c2aa98e2SPeter Wemm 			/* try short name */
4531c2aa98e2SPeter Wemm 			if (strlen(name) > (SIZE_T) sizeof hbuf - 1)
45323299c2f1SGregory Neil Shapiro 			{
45333299c2f1SGregory Neil Shapiro 				errno = save_errno;
4534c2aa98e2SPeter Wemm 				return NULL;
45353299c2f1SGregory Neil Shapiro 			}
45363299c2f1SGregory Neil Shapiro 			(void) strlcpy(hbuf, name, sizeof hbuf);
4537b4662009SGregory Neil Shapiro 			(void) shorten_hostname(hbuf);
4538c2aa98e2SPeter Wemm 
4539c2aa98e2SPeter Wemm 			/* if it hasn't been shortened, there's no point */
4540c2aa98e2SPeter Wemm 			if (strcmp(hbuf, name) != 0)
4541c2aa98e2SPeter Wemm 			{
4542c2aa98e2SPeter Wemm 				if (tTd(61, 10))
45433299c2f1SGregory Neil Shapiro 					dprintf("sm_gethostbyname(%s, %d)... ",
45443299c2f1SGregory Neil Shapiro 					       hbuf, family);
45453299c2f1SGregory Neil Shapiro 
45463299c2f1SGregory Neil Shapiro # if NETINET6
45473299c2f1SGregory Neil Shapiro 				h = getipnodebyname(hbuf, family,
45483299c2f1SGregory Neil Shapiro 						    AI_V4MAPPED|AI_ALL,
45493299c2f1SGregory Neil Shapiro 						    &err);
4550b4662009SGregory Neil Shapiro 				SM_SET_H_ERRNO(err);
45513299c2f1SGregory Neil Shapiro 				save_errno = errno;
45523299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4553c2aa98e2SPeter Wemm 				h = gethostbyname(hbuf);
45543299c2f1SGregory Neil Shapiro 				save_errno = errno;
45553299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4556c2aa98e2SPeter Wemm 			}
4557c2aa98e2SPeter Wemm 		}
4558c2aa98e2SPeter Wemm 	}
45593299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4560c2aa98e2SPeter Wemm 	if (tTd(61, 10))
4561c2aa98e2SPeter Wemm 	{
4562c2aa98e2SPeter Wemm 		if (h == NULL)
45633299c2f1SGregory Neil Shapiro 			dprintf("failure\n");
4564c2aa98e2SPeter Wemm 		else
45653299c2f1SGregory Neil Shapiro 		{
45663299c2f1SGregory Neil Shapiro 			dprintf("%s\n", h->h_name);
45673299c2f1SGregory Neil Shapiro 			if (tTd(61, 11))
45683299c2f1SGregory Neil Shapiro 			{
45693299c2f1SGregory Neil Shapiro #if NETINET6
45703299c2f1SGregory Neil Shapiro 				struct in6_addr ia6;
45713299c2f1SGregory Neil Shapiro 				char buf6[INET6_ADDRSTRLEN];
45723299c2f1SGregory Neil Shapiro #else /* NETINET6 */
45733299c2f1SGregory Neil Shapiro 				struct in_addr ia;
45743299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
45753299c2f1SGregory Neil Shapiro 				int i;
45763299c2f1SGregory Neil Shapiro 
45773299c2f1SGregory Neil Shapiro 				if (h->h_aliases != NULL)
45783299c2f1SGregory Neil Shapiro 					for (i = 0; h->h_aliases[i] != NULL;
45793299c2f1SGregory Neil Shapiro 					     i++)
45803299c2f1SGregory Neil Shapiro 						dprintf("\talias: %s\n",
45813299c2f1SGregory Neil Shapiro 							h->h_aliases[i]);
45823299c2f1SGregory Neil Shapiro 				for (i = 0; h->h_addr_list[i] != NULL; i++)
45833299c2f1SGregory Neil Shapiro 				{
45843299c2f1SGregory Neil Shapiro 					char *addr;
45853299c2f1SGregory Neil Shapiro 
45863299c2f1SGregory Neil Shapiro #if NETINET6
45873299c2f1SGregory Neil Shapiro 					memmove(&ia6, h->h_addr_list[i],
45883299c2f1SGregory Neil Shapiro 						IN6ADDRSZ);
45893299c2f1SGregory Neil Shapiro 					addr = anynet_ntop(&ia6,
45903299c2f1SGregory Neil Shapiro 							   buf6, sizeof buf6);
45913299c2f1SGregory Neil Shapiro #else /* NETINET6 */
45923299c2f1SGregory Neil Shapiro 					memmove(&ia, h->h_addr_list[i],
45933299c2f1SGregory Neil Shapiro 						INADDRSZ);
45943299c2f1SGregory Neil Shapiro 					addr = (char *) inet_ntoa(ia);
45953299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
45963299c2f1SGregory Neil Shapiro 					if (addr != NULL)
45973299c2f1SGregory Neil Shapiro 						dprintf("\taddr: %s\n", addr);
4598c2aa98e2SPeter Wemm 				}
45993299c2f1SGregory Neil Shapiro 			}
46003299c2f1SGregory Neil Shapiro 		}
46013299c2f1SGregory Neil Shapiro 	}
46023299c2f1SGregory Neil Shapiro 	errno = save_errno;
4603c2aa98e2SPeter Wemm 	return h;
4604c2aa98e2SPeter Wemm }
4605c2aa98e2SPeter Wemm 
4606c2aa98e2SPeter Wemm struct hostent *
4607c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type)
4608c2aa98e2SPeter Wemm 	char *addr;
4609c2aa98e2SPeter Wemm 	int len;
4610c2aa98e2SPeter Wemm 	int type;
4611c2aa98e2SPeter Wemm {
46123299c2f1SGregory Neil Shapiro 	struct hostent *hp;
4613b4662009SGregory Neil Shapiro 
4614b4662009SGregory Neil Shapiro #if NETINET6
4615b4662009SGregory Neil Shapiro 	if (type == AF_INET6 &&
4616b4662009SGregory Neil Shapiro 	    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr))
4617b4662009SGregory Neil Shapiro 	{
4618b4662009SGregory Neil Shapiro 		/* Avoid reverse lookup for IPv6 unspecified address */
4619b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(HOST_NOT_FOUND);
4620b4662009SGregory Neil Shapiro 		return NULL;
4621b4662009SGregory Neil Shapiro 	}
4622b4662009SGregory Neil Shapiro #endif /* NETINET6 */
4623b4662009SGregory Neil Shapiro 
4624c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204)
4625c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4626b4662009SGregory Neil Shapiro 	{
46273299c2f1SGregory Neil Shapiro 		static struct hostent he;
4628c2aa98e2SPeter Wemm 		static char buf[1000];
4629c2aa98e2SPeter Wemm 		extern struct hostent *_switch_gethostbyaddr_r();
4630c2aa98e2SPeter Wemm 
4631b4662009SGregory Neil Shapiro 		hp = _switch_gethostbyaddr_r(addr, len, type, &he,
4632b4662009SGregory Neil Shapiro 					     buf, sizeof(buf), &h_errno);
4633b4662009SGregory Neil Shapiro 	}
46343299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4635b4662009SGregory Neil Shapiro 	{
4636c2aa98e2SPeter Wemm 		extern struct hostent *__switch_gethostbyaddr();
4637c2aa98e2SPeter Wemm 
46383299c2f1SGregory Neil Shapiro 		hp = __switch_gethostbyaddr(addr, len, type);
4639b4662009SGregory Neil Shapiro 	}
46403299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
46413299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
46423299c2f1SGregory Neil Shapiro # if NETINET6
4643b4662009SGregory Neil Shapiro 	{
46443299c2f1SGregory Neil Shapiro 		int err;
46453299c2f1SGregory Neil Shapiro 
46463299c2f1SGregory Neil Shapiro 		hp = getipnodebyaddr(addr, len, type, &err);
4647b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(err);
4648b4662009SGregory Neil Shapiro 	}
46493299c2f1SGregory Neil Shapiro # else /* NETINET6 */
46503299c2f1SGregory Neil Shapiro 	hp = gethostbyaddr(addr, len, type);
46513299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
46523299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
4653c0c4794dSGregory Neil Shapiro 	return hp;
4654c2aa98e2SPeter Wemm }
4655c2aa98e2SPeter Wemm /*
4656c2aa98e2SPeter Wemm **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
4657c2aa98e2SPeter Wemm */
4658c2aa98e2SPeter Wemm 
46593299c2f1SGregory Neil Shapiro 
4660c2aa98e2SPeter Wemm struct passwd *
4661c2aa98e2SPeter Wemm sm_getpwnam(user)
4662c2aa98e2SPeter Wemm 	char *user;
4663c2aa98e2SPeter Wemm {
4664c2aa98e2SPeter Wemm # ifdef _AIX4
4665c2aa98e2SPeter Wemm 	extern struct passwd *_getpwnam_shadow(const char *, const int);
4666c2aa98e2SPeter Wemm 
4667c2aa98e2SPeter Wemm 	return _getpwnam_shadow(user, 0);
46683299c2f1SGregory Neil Shapiro # else /* _AIX4 */
4669c2aa98e2SPeter Wemm 	return getpwnam(user);
46703299c2f1SGregory Neil Shapiro # endif /* _AIX4 */
4671c2aa98e2SPeter Wemm }
4672c2aa98e2SPeter Wemm 
4673c2aa98e2SPeter Wemm struct passwd *
4674c2aa98e2SPeter Wemm sm_getpwuid(uid)
4675c2aa98e2SPeter Wemm 	UID_T uid;
4676c2aa98e2SPeter Wemm {
4677c2aa98e2SPeter Wemm # if defined(_AIX4) && 0
4678c2aa98e2SPeter Wemm 	extern struct passwd *_getpwuid_shadow(const int, const int);
4679c2aa98e2SPeter Wemm 
4680c2aa98e2SPeter Wemm 	return _getpwuid_shadow(uid,0);
46813299c2f1SGregory Neil Shapiro # else /* defined(_AIX4) && 0 */
4682c2aa98e2SPeter Wemm 	return getpwuid(uid);
46833299c2f1SGregory Neil Shapiro # endif /* defined(_AIX4) && 0 */
4684c2aa98e2SPeter Wemm }
4685c2aa98e2SPeter Wemm /*
4686c2aa98e2SPeter Wemm **  SECUREWARE_SETUP_SECURE -- Convex SecureWare setup
4687c2aa98e2SPeter Wemm **
4688c2aa98e2SPeter Wemm **	Set up the trusted computing environment for C2 level security
4689c2aa98e2SPeter Wemm **	under SecureWare.
4690c2aa98e2SPeter Wemm **
4691c2aa98e2SPeter Wemm **	Parameters:
4692c2aa98e2SPeter Wemm **		uid -- uid of the user to initialize in the TCB
4693c2aa98e2SPeter Wemm **
4694c2aa98e2SPeter Wemm **	Returns:
4695c2aa98e2SPeter Wemm **		none
4696c2aa98e2SPeter Wemm **
4697c2aa98e2SPeter Wemm **	Side Effects:
4698c2aa98e2SPeter Wemm **		Initialized the user in the trusted computing base
4699c2aa98e2SPeter Wemm */
4700c2aa98e2SPeter Wemm 
4701c2aa98e2SPeter Wemm #if SECUREWARE
4702c2aa98e2SPeter Wemm 
4703c2aa98e2SPeter Wemm # include <sys/security.h>
4704c2aa98e2SPeter Wemm # include <prot.h>
4705c2aa98e2SPeter Wemm 
4706c2aa98e2SPeter Wemm void
4707c2aa98e2SPeter Wemm secureware_setup_secure(uid)
4708c2aa98e2SPeter Wemm 	UID_T uid;
4709c2aa98e2SPeter Wemm {
4710c2aa98e2SPeter Wemm 	int rc;
4711c2aa98e2SPeter Wemm 
4712c2aa98e2SPeter Wemm 	if (getluid() != -1)
4713c2aa98e2SPeter Wemm 		return;
4714c2aa98e2SPeter Wemm 
4715c2aa98e2SPeter Wemm 	if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN)
4716c2aa98e2SPeter Wemm 	{
4717c2aa98e2SPeter Wemm 		switch (rc)
4718c2aa98e2SPeter Wemm 		{
4719c2aa98e2SPeter Wemm 		  case SSI_NO_PRPW_ENTRY:
4720c2aa98e2SPeter Wemm 			syserr("No protected passwd entry, uid = %d", uid);
4721c2aa98e2SPeter Wemm 			break;
4722c2aa98e2SPeter Wemm 
4723c2aa98e2SPeter Wemm 		  case SSI_LOCKED:
4724c2aa98e2SPeter Wemm 			syserr("Account has been disabled, uid = %d", uid);
4725c2aa98e2SPeter Wemm 			break;
4726c2aa98e2SPeter Wemm 
4727c2aa98e2SPeter Wemm 		  case SSI_RETIRED:
4728c2aa98e2SPeter Wemm 			syserr("Account has been retired, uid = %d", uid);
4729c2aa98e2SPeter Wemm 			break;
4730c2aa98e2SPeter Wemm 
4731c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_LUID:
4732c2aa98e2SPeter Wemm 			syserr("Could not set LUID, uid = %d", uid);
4733c2aa98e2SPeter Wemm 			break;
4734c2aa98e2SPeter Wemm 
4735c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_PRIVS:
4736c2aa98e2SPeter Wemm 			syserr("Could not set kernel privs, uid = %d", uid);
4737c2aa98e2SPeter Wemm 
4738c2aa98e2SPeter Wemm 		  default:
4739c2aa98e2SPeter Wemm 			syserr("Unknown return code (%d) from set_secure_info(%d)",
4740c2aa98e2SPeter Wemm 				rc, uid);
4741c2aa98e2SPeter Wemm 			break;
4742c2aa98e2SPeter Wemm 		}
474376b7bf71SPeter Wemm 		finis(FALSE, EX_NOPERM);
4744c2aa98e2SPeter Wemm 	}
4745c2aa98e2SPeter Wemm }
4746c2aa98e2SPeter Wemm #endif /* SECUREWARE */
4747c2aa98e2SPeter Wemm /*
47483299c2f1SGregory Neil Shapiro **  ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address
474976b7bf71SPeter Wemm **
475076b7bf71SPeter Wemm **	Add hostnames to class 'w' based on the IP address read from
475176b7bf71SPeter Wemm **	the network interface.
475276b7bf71SPeter Wemm **
475376b7bf71SPeter Wemm **	Parameters:
475476b7bf71SPeter Wemm **		sa -- a pointer to a SOCKADDR containing the address
475576b7bf71SPeter Wemm **
475676b7bf71SPeter Wemm **	Returns:
475776b7bf71SPeter Wemm **		0 if successful, -1 if host lookup fails.
475876b7bf71SPeter Wemm */
475976b7bf71SPeter Wemm 
47603299c2f1SGregory Neil Shapiro static int
476176b7bf71SPeter Wemm add_hostnames(sa)
476276b7bf71SPeter Wemm 	SOCKADDR *sa;
476376b7bf71SPeter Wemm {
476476b7bf71SPeter Wemm 	struct hostent *hp;
47653299c2f1SGregory Neil Shapiro 	char **ha;
47663299c2f1SGregory Neil Shapiro 	char hnb[MAXHOSTNAMELEN];
476776b7bf71SPeter Wemm 
476876b7bf71SPeter Wemm 	/* lookup name with IP address */
476976b7bf71SPeter Wemm 	switch (sa->sa.sa_family)
477076b7bf71SPeter Wemm 	{
47713299c2f1SGregory Neil Shapiro #if NETINET
477276b7bf71SPeter Wemm 		case AF_INET:
477376b7bf71SPeter Wemm 			hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr,
4774c46d91b7SGregory Neil Shapiro 					      sizeof(sa->sin.sin_addr),
4775c46d91b7SGregory Neil Shapiro 					      sa->sa.sa_family);
477676b7bf71SPeter Wemm 			break;
47773299c2f1SGregory Neil Shapiro #endif /* NETINET */
47783299c2f1SGregory Neil Shapiro 
47793299c2f1SGregory Neil Shapiro #if NETINET6
47803299c2f1SGregory Neil Shapiro 		case AF_INET6:
47813299c2f1SGregory Neil Shapiro 			hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr,
4782c46d91b7SGregory Neil Shapiro 					      sizeof(sa->sin6.sin6_addr),
4783c46d91b7SGregory Neil Shapiro 					      sa->sa.sa_family);
47843299c2f1SGregory Neil Shapiro 			break;
47853299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
478676b7bf71SPeter Wemm 
478776b7bf71SPeter Wemm 		default:
47883299c2f1SGregory Neil Shapiro 			/* Give warning about unsupported family */
478976b7bf71SPeter Wemm 			if (LogLevel > 3)
479076b7bf71SPeter Wemm 				sm_syslog(LOG_WARNING, NOQID,
479176b7bf71SPeter Wemm 					  "Unsupported address family %d: %.100s",
479276b7bf71SPeter Wemm 					  sa->sa.sa_family, anynet_ntoa(sa));
479376b7bf71SPeter Wemm 			return -1;
479476b7bf71SPeter Wemm 	}
479576b7bf71SPeter Wemm 
479676b7bf71SPeter Wemm 	if (hp == NULL)
479776b7bf71SPeter Wemm 	{
479876b7bf71SPeter Wemm 		int save_errno = errno;
479976b7bf71SPeter Wemm 
48003299c2f1SGregory Neil Shapiro 		if (LogLevel > 3 &&
48013299c2f1SGregory Neil Shapiro #if NETINET6
48023299c2f1SGregory Neil Shapiro 		    !(sa->sa.sa_family == AF_INET6 &&
48033299c2f1SGregory Neil Shapiro 		      IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
48043299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
48053299c2f1SGregory Neil Shapiro 		    TRUE)
480676b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
480776b7bf71SPeter Wemm 				"gethostbyaddr(%.100s) failed: %d\n",
480876b7bf71SPeter Wemm 				anynet_ntoa(sa),
480976b7bf71SPeter Wemm #if NAMED_BIND
481076b7bf71SPeter Wemm 				h_errno
48113299c2f1SGregory Neil Shapiro #else /* NAMED_BIND */
481276b7bf71SPeter Wemm 				-1
48133299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
481476b7bf71SPeter Wemm 				);
481576b7bf71SPeter Wemm 		errno = save_errno;
481676b7bf71SPeter Wemm 		return -1;
481776b7bf71SPeter Wemm 	}
481876b7bf71SPeter Wemm 
481976b7bf71SPeter Wemm 	/* save its cname */
482076b7bf71SPeter Wemm 	if (!wordinclass((char *) hp->h_name, 'w'))
482176b7bf71SPeter Wemm 	{
482276b7bf71SPeter Wemm 		setclass('w', (char *) hp->h_name);
482376b7bf71SPeter Wemm 		if (tTd(0, 4))
48243299c2f1SGregory Neil Shapiro 			dprintf("\ta.k.a.: %s\n", hp->h_name);
48253299c2f1SGregory Neil Shapiro 
48263299c2f1SGregory Neil Shapiro 		if (snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb
48273299c2f1SGregory Neil Shapiro 		    && !wordinclass((char *) hnb, 'w'))
48283299c2f1SGregory Neil Shapiro 			setclass('w', hnb);
48293299c2f1SGregory Neil Shapiro 	}
48303299c2f1SGregory Neil Shapiro 	else
48313299c2f1SGregory Neil Shapiro 	{
48323299c2f1SGregory Neil Shapiro 		if (tTd(0, 43))
48333299c2f1SGregory Neil Shapiro 			dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name);
483476b7bf71SPeter Wemm 	}
483576b7bf71SPeter Wemm 
483676b7bf71SPeter Wemm 	/* save all it aliases name */
48373299c2f1SGregory Neil Shapiro 	for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
483876b7bf71SPeter Wemm 	{
48393299c2f1SGregory Neil Shapiro 		if (!wordinclass(*ha, 'w'))
484076b7bf71SPeter Wemm 		{
48413299c2f1SGregory Neil Shapiro 			setclass('w', *ha);
484276b7bf71SPeter Wemm 			if (tTd(0, 4))
48433299c2f1SGregory Neil Shapiro 				dprintf("\ta.k.a.: %s\n", *ha);
48443299c2f1SGregory Neil Shapiro 			if (snprintf(hnb, sizeof hnb,
48453299c2f1SGregory Neil Shapiro 				     "[%s]", *ha) < sizeof hnb &&
48463299c2f1SGregory Neil Shapiro 			    !wordinclass((char *) hnb, 'w'))
48473299c2f1SGregory Neil Shapiro 				setclass('w', hnb);
484876b7bf71SPeter Wemm 		}
48493299c2f1SGregory Neil Shapiro 		else
48503299c2f1SGregory Neil Shapiro 		{
48513299c2f1SGregory Neil Shapiro 			if (tTd(0, 43))
48523299c2f1SGregory Neil Shapiro 				dprintf("\ta.k.a.: %s (already in $=w)\n",
48533299c2f1SGregory Neil Shapiro 					*ha);
48543299c2f1SGregory Neil Shapiro 		}
485576b7bf71SPeter Wemm 	}
4856c46d91b7SGregory Neil Shapiro #if _FFR_FREEHOSTENT && NETINET6
4857c46d91b7SGregory Neil Shapiro 	freehostent(hp);
4858c46d91b7SGregory Neil Shapiro #endif /* _FFR_FREEHOSTENT && NETINET6 */
485976b7bf71SPeter Wemm 	return 0;
486076b7bf71SPeter Wemm }
486176b7bf71SPeter Wemm /*
4862c2aa98e2SPeter Wemm **  LOAD_IF_NAMES -- load interface-specific names into $=w
4863c2aa98e2SPeter Wemm **
4864c2aa98e2SPeter Wemm **	Parameters:
4865c2aa98e2SPeter Wemm **		none.
4866c2aa98e2SPeter Wemm **
4867c2aa98e2SPeter Wemm **	Returns:
4868c2aa98e2SPeter Wemm **		none.
4869c2aa98e2SPeter Wemm **
4870c2aa98e2SPeter Wemm **	Side Effects:
4871c2aa98e2SPeter Wemm **		Loads $=w with the names of all the interfaces.
4872c2aa98e2SPeter Wemm */
4873c2aa98e2SPeter Wemm 
48743299c2f1SGregory Neil Shapiro #if !NETINET
48753299c2f1SGregory Neil Shapiro # define SIOCGIFCONF_IS_BROKEN	1 /* XXX */
48763299c2f1SGregory Neil Shapiro #endif /* !NETINET */
48773299c2f1SGregory Neil Shapiro 
4878c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4879c2aa98e2SPeter Wemm struct rtentry;
4880c2aa98e2SPeter Wemm struct mbuf;
4881c2aa98e2SPeter Wemm # ifndef SUNOS403
4882c2aa98e2SPeter Wemm #  include <sys/time.h>
48833299c2f1SGregory Neil Shapiro # endif /* ! SUNOS403 */
48843299c2f1SGregory Neil Shapiro # if (_AIX4 >= 40300) && !defined(_NET_IF_H)
4885c2aa98e2SPeter Wemm #  undef __P
48863299c2f1SGregory Neil Shapiro # endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */
4887c2aa98e2SPeter Wemm # include <net/if.h>
48883299c2f1SGregory Neil Shapiro #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
4889c2aa98e2SPeter Wemm 
4890c2aa98e2SPeter Wemm void
4891c2aa98e2SPeter Wemm load_if_names()
4892c2aa98e2SPeter Wemm {
48933299c2f1SGregory Neil Shapiro #if NETINET6 && defined(SIOCGLIFCONF)
48943299c2f1SGregory Neil Shapiro 	int s;
48953299c2f1SGregory Neil Shapiro 	int i;
48963299c2f1SGregory Neil Shapiro 	struct lifconf lifc;
48973299c2f1SGregory Neil Shapiro 	struct lifnum lifn;
48983299c2f1SGregory Neil Shapiro 	int numifs;
48993299c2f1SGregory Neil Shapiro 
49003299c2f1SGregory Neil Shapiro 	s = socket(InetMode, SOCK_DGRAM, 0);
49013299c2f1SGregory Neil Shapiro 	if (s == -1)
49023299c2f1SGregory Neil Shapiro 		return;
49033299c2f1SGregory Neil Shapiro 
49043299c2f1SGregory Neil Shapiro 	/* get the list of known IP address from the kernel */
49053299c2f1SGregory Neil Shapiro #   ifdef SIOCGLIFNUM
49063299c2f1SGregory Neil Shapiro 	lifn.lifn_family = AF_UNSPEC;
49073299c2f1SGregory Neil Shapiro 	lifn.lifn_flags = 0;
49083299c2f1SGregory Neil Shapiro 	if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0)
49093299c2f1SGregory Neil Shapiro 	{
49103299c2f1SGregory Neil Shapiro 		/* can't get number of interfaces -- fall back */
49113299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
49123299c2f1SGregory Neil Shapiro 			dprintf("SIOCGLIFNUM failed: %s\n", errstring(errno));
49133299c2f1SGregory Neil Shapiro 		numifs = -1;
49143299c2f1SGregory Neil Shapiro 	}
49153299c2f1SGregory Neil Shapiro 	else
49163299c2f1SGregory Neil Shapiro 	{
49173299c2f1SGregory Neil Shapiro 		numifs = lifn.lifn_count;
49183299c2f1SGregory Neil Shapiro 		if (tTd(0, 42))
49193299c2f1SGregory Neil Shapiro 			dprintf("system has %d interfaces\n", numifs);
49203299c2f1SGregory Neil Shapiro 	}
49213299c2f1SGregory Neil Shapiro 	if (numifs < 0)
49223299c2f1SGregory Neil Shapiro #   endif /* SIOCGLIFNUM */
49233299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
49243299c2f1SGregory Neil Shapiro 
49253299c2f1SGregory Neil Shapiro 	if (numifs <= 0)
49263299c2f1SGregory Neil Shapiro 	{
4927c46d91b7SGregory Neil Shapiro 		(void) close(s);
49283299c2f1SGregory Neil Shapiro 		return;
49293299c2f1SGregory Neil Shapiro 	}
49303299c2f1SGregory Neil Shapiro 	lifc.lifc_len = numifs * sizeof (struct lifreq);
49313299c2f1SGregory Neil Shapiro 	lifc.lifc_buf = xalloc(lifc.lifc_len);
49323299c2f1SGregory Neil Shapiro 	lifc.lifc_family = AF_UNSPEC;
49333299c2f1SGregory Neil Shapiro 	lifc.lifc_flags = 0;
49343299c2f1SGregory Neil Shapiro 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
49353299c2f1SGregory Neil Shapiro 	{
49363299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
49373299c2f1SGregory Neil Shapiro 			dprintf("SIOCGLIFCONF failed: %s\n", errstring(errno));
4938c46d91b7SGregory Neil Shapiro 		(void) close(s);
4939c0c4794dSGregory Neil Shapiro 		sm_free(lifc.lifc_buf);
49403299c2f1SGregory Neil Shapiro 		return;
49413299c2f1SGregory Neil Shapiro 	}
49423299c2f1SGregory Neil Shapiro 
49433299c2f1SGregory Neil Shapiro 	/* scan the list of IP address */
49443299c2f1SGregory Neil Shapiro 	if (tTd(0, 40))
49453299c2f1SGregory Neil Shapiro 		dprintf("scanning for interface specific names, lifc_len=%d\n",
49463299c2f1SGregory Neil Shapiro 			lifc.lifc_len);
49473299c2f1SGregory Neil Shapiro 
49483299c2f1SGregory Neil Shapiro 	for (i = 0; i < lifc.lifc_len; )
49493299c2f1SGregory Neil Shapiro 	{
49503299c2f1SGregory Neil Shapiro 		struct lifreq *ifr = (struct lifreq *)&lifc.lifc_buf[i];
49513299c2f1SGregory Neil Shapiro 		SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr;
49523299c2f1SGregory Neil Shapiro 		char *addr;
49533299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
49543299c2f1SGregory Neil Shapiro 		struct in_addr ia;
49553299c2f1SGregory Neil Shapiro #   ifdef SIOCGLIFFLAGS
49563299c2f1SGregory Neil Shapiro 		struct lifreq ifrf;
49573299c2f1SGregory Neil Shapiro #   endif /* SIOCGLIFFLAGS */
49583299c2f1SGregory Neil Shapiro 		char ip_addr[256];
49593299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
49603299c2f1SGregory Neil Shapiro 		int af = ifr->lifr_addr.ss_family;
49613299c2f1SGregory Neil Shapiro 
49623299c2f1SGregory Neil Shapiro 		/*
49633299c2f1SGregory Neil Shapiro 		**  We must close and recreate the socket each time
49643299c2f1SGregory Neil Shapiro 		**  since we don't know what type of socket it is now
49653299c2f1SGregory Neil Shapiro 		**  (each status function may change it).
49663299c2f1SGregory Neil Shapiro 		*/
49673299c2f1SGregory Neil Shapiro 
49683299c2f1SGregory Neil Shapiro 		(void) close(s);
49693299c2f1SGregory Neil Shapiro 
49703299c2f1SGregory Neil Shapiro 		s = socket(af, SOCK_DGRAM, 0);
49713299c2f1SGregory Neil Shapiro 		if (s == -1)
4972c46d91b7SGregory Neil Shapiro 		{
4973c0c4794dSGregory Neil Shapiro 			sm_free(lifc.lifc_buf);
49743299c2f1SGregory Neil Shapiro 			return;
4975c46d91b7SGregory Neil Shapiro 		}
49763299c2f1SGregory Neil Shapiro 
49773299c2f1SGregory Neil Shapiro 		/*
49783299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
49793299c2f1SGregory Neil Shapiro 		**  don't try to use it.
49803299c2f1SGregory Neil Shapiro 		*/
49813299c2f1SGregory Neil Shapiro 
49823299c2f1SGregory Neil Shapiro 		if ((lifc.lifc_len - i) < sizeof *ifr)
49833299c2f1SGregory Neil Shapiro 			break;
49843299c2f1SGregory Neil Shapiro 
49853299c2f1SGregory Neil Shapiro #   ifdef BSD4_4_SOCKADDR
49863299c2f1SGregory Neil Shapiro 		if (sa->sa.sa_len > sizeof ifr->lifr_addr)
49873299c2f1SGregory Neil Shapiro 			i += sizeof ifr->lifr_name + sa->sa.sa_len;
49883299c2f1SGregory Neil Shapiro 		else
49893299c2f1SGregory Neil Shapiro #   endif /* BSD4_4_SOCKADDR */
49903299c2f1SGregory Neil Shapiro 			i += sizeof *ifr;
49913299c2f1SGregory Neil Shapiro 
49923299c2f1SGregory Neil Shapiro 		if (tTd(0, 20))
49933299c2f1SGregory Neil Shapiro 			dprintf("%s\n", anynet_ntoa(sa));
49943299c2f1SGregory Neil Shapiro 
49953299c2f1SGregory Neil Shapiro 		if (af != AF_INET && af != AF_INET6)
49963299c2f1SGregory Neil Shapiro 			continue;
49973299c2f1SGregory Neil Shapiro 
49983299c2f1SGregory Neil Shapiro #   ifdef SIOCGLIFFLAGS
49993299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct lifreq));
50003299c2f1SGregory Neil Shapiro 		(void) strlcpy(ifrf.lifr_name, ifr->lifr_name,
50013299c2f1SGregory Neil Shapiro 			       sizeof(ifrf.lifr_name));
50023299c2f1SGregory Neil Shapiro 		if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0)
50033299c2f1SGregory Neil Shapiro 		{
50043299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
50053299c2f1SGregory Neil Shapiro 				dprintf("SIOCGLIFFLAGS failed: %s\n",
50063299c2f1SGregory Neil Shapiro 					errstring(errno));
50073299c2f1SGregory Neil Shapiro 			continue;
50083299c2f1SGregory Neil Shapiro 		}
50093299c2f1SGregory Neil Shapiro 		else if (tTd(0, 41))
50103299c2f1SGregory Neil Shapiro 			dprintf("\tflags: %lx\n",
50113299c2f1SGregory Neil Shapiro 				(unsigned long)ifrf.lifr_flags);
50123299c2f1SGregory Neil Shapiro 
50133299c2f1SGregory Neil Shapiro 		if (!bitset(IFF_UP, ifrf.lifr_flags))
50143299c2f1SGregory Neil Shapiro 			continue;
50153299c2f1SGregory Neil Shapiro #   endif /* SIOCGLIFFLAGS */
50163299c2f1SGregory Neil Shapiro 
50173299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
50183299c2f1SGregory Neil Shapiro 
50193299c2f1SGregory Neil Shapiro 		/* extract IP address from the list*/
50203299c2f1SGregory Neil Shapiro 		switch (af)
50213299c2f1SGregory Neil Shapiro 		{
50223299c2f1SGregory Neil Shapiro 		  case AF_INET6:
5023c46d91b7SGregory Neil Shapiro #  ifdef __KAME__
5024b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
5025b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
5026b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
5027c46d91b7SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
5028c46d91b7SGregory Neil Shapiro 			{
5029b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
5030b4662009SGregory Neil Shapiro 
5031b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
5032b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
5033b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
5034b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
5035c46d91b7SGregory Neil Shapiro 			}
5036c46d91b7SGregory Neil Shapiro #  endif /* __KAME__ */
5037b4662009SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
5038c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
50393299c2f1SGregory Neil Shapiro 			{
50403299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
50413299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
50423299c2f1SGregory Neil Shapiro 					ifr->lifr_name,
50433299c2f1SGregory Neil Shapiro 					addr == NULL ? "(NULL)" : addr);
50443299c2f1SGregory Neil Shapiro 				continue;
50453299c2f1SGregory Neil Shapiro 			}
50463299c2f1SGregory Neil Shapiro 
50473299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
50483299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
50493299c2f1SGregory Neil Shapiro 			if (addr != NULL)
50503299c2f1SGregory Neil Shapiro 				(void) snprintf(ip_addr, sizeof ip_addr,
50513299c2f1SGregory Neil Shapiro 						"[%.*s]",
5052d995d2baSGregory Neil Shapiro 						(int) sizeof ip_addr - 3, addr);
50533299c2f1SGregory Neil Shapiro 			break;
50543299c2f1SGregory Neil Shapiro 
50553299c2f1SGregory Neil Shapiro 		  case AF_INET:
50563299c2f1SGregory Neil Shapiro 			ia = sa->sin.sin_addr;
50573299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
50583299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
50593299c2f1SGregory Neil Shapiro 			{
50603299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
50613299c2f1SGregory Neil Shapiro 					ifr->lifr_name, inet_ntoa(ia));
50623299c2f1SGregory Neil Shapiro 				continue;
50633299c2f1SGregory Neil Shapiro 			}
50643299c2f1SGregory Neil Shapiro 
50653299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
50663299c2f1SGregory Neil Shapiro 			(void) snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
5067d995d2baSGregory Neil Shapiro 					(int) sizeof ip_addr - 3, inet_ntoa(ia));
50683299c2f1SGregory Neil Shapiro 			break;
50693299c2f1SGregory Neil Shapiro 		}
50703299c2f1SGregory Neil Shapiro 
50713299c2f1SGregory Neil Shapiro 		if (*ip_addr == '\0')
50723299c2f1SGregory Neil Shapiro 			continue;
50733299c2f1SGregory Neil Shapiro 
50743299c2f1SGregory Neil Shapiro 		if (!wordinclass(ip_addr, 'w'))
50753299c2f1SGregory Neil Shapiro 		{
50763299c2f1SGregory Neil Shapiro 			setclass('w', ip_addr);
50773299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
50783299c2f1SGregory Neil Shapiro 				dprintf("\ta.k.a.: %s\n", ip_addr);
50793299c2f1SGregory Neil Shapiro 		}
50803299c2f1SGregory Neil Shapiro 
50813299c2f1SGregory Neil Shapiro #   ifdef SIOCGLIFFLAGS
50823299c2f1SGregory Neil Shapiro 		/* skip "loopback" interface "lo" */
50833299c2f1SGregory Neil Shapiro 		if (bitset(IFF_LOOPBACK, ifrf.lifr_flags))
50843299c2f1SGregory Neil Shapiro 			continue;
50853299c2f1SGregory Neil Shapiro #   endif /* SIOCGLIFFLAGS */
50863299c2f1SGregory Neil Shapiro 		(void) add_hostnames(sa);
50873299c2f1SGregory Neil Shapiro 	}
5088c0c4794dSGregory Neil Shapiro 	sm_free(lifc.lifc_buf);
5089c46d91b7SGregory Neil Shapiro 	(void) close(s);
50903299c2f1SGregory Neil Shapiro #else /* NETINET6 && defined(SIOCGLIFCONF) */
5091c2aa98e2SPeter Wemm # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
5092c2aa98e2SPeter Wemm 	int s;
5093c2aa98e2SPeter Wemm 	int i;
5094c2aa98e2SPeter Wemm 	struct ifconf ifc;
5095c2aa98e2SPeter Wemm 	int numifs;
5096c2aa98e2SPeter Wemm 
5097c2aa98e2SPeter Wemm 	s = socket(AF_INET, SOCK_DGRAM, 0);
5098c2aa98e2SPeter Wemm 	if (s == -1)
5099c2aa98e2SPeter Wemm 		return;
5100c2aa98e2SPeter Wemm 
5101c2aa98e2SPeter Wemm 	/* get the list of known IP address from the kernel */
5102c2aa98e2SPeter Wemm #  if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN
5103c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
5104c2aa98e2SPeter Wemm 	{
5105c2aa98e2SPeter Wemm 		/* can't get number of interfaces -- fall back */
5106c2aa98e2SPeter Wemm 		if (tTd(0, 4))
51073299c2f1SGregory Neil Shapiro 			dprintf("SIOCGIFNUM failed: %s\n", errstring(errno));
5108c2aa98e2SPeter Wemm 		numifs = -1;
5109c2aa98e2SPeter Wemm 	}
5110c2aa98e2SPeter Wemm 	else if (tTd(0, 42))
51113299c2f1SGregory Neil Shapiro 		dprintf("system has %d interfaces\n", numifs);
5112c2aa98e2SPeter Wemm 	if (numifs < 0)
51133299c2f1SGregory Neil Shapiro #  endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */
51143299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
5115c2aa98e2SPeter Wemm 
5116c2aa98e2SPeter Wemm 	if (numifs <= 0)
5117c2aa98e2SPeter Wemm 	{
51183299c2f1SGregory Neil Shapiro 		(void) close(s);
5119c2aa98e2SPeter Wemm 		return;
5120c2aa98e2SPeter Wemm 	}
5121c2aa98e2SPeter Wemm 	ifc.ifc_len = numifs * sizeof (struct ifreq);
5122c2aa98e2SPeter Wemm 	ifc.ifc_buf = xalloc(ifc.ifc_len);
5123c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
5124c2aa98e2SPeter Wemm 	{
5125c2aa98e2SPeter Wemm 		if (tTd(0, 4))
51263299c2f1SGregory Neil Shapiro 			dprintf("SIOCGIFCONF failed: %s\n", errstring(errno));
51273299c2f1SGregory Neil Shapiro 		(void) close(s);
5128c0c4794dSGregory Neil Shapiro 		sm_free(ifc.ifc_buf);
5129c2aa98e2SPeter Wemm 		return;
5130c2aa98e2SPeter Wemm 	}
5131c2aa98e2SPeter Wemm 
5132c2aa98e2SPeter Wemm 	/* scan the list of IP address */
5133c2aa98e2SPeter Wemm 	if (tTd(0, 40))
51343299c2f1SGregory Neil Shapiro 		dprintf("scanning for interface specific names, ifc_len=%d\n",
5135c2aa98e2SPeter Wemm 			ifc.ifc_len);
5136c2aa98e2SPeter Wemm 
5137c2aa98e2SPeter Wemm 	for (i = 0; i < ifc.ifc_len; )
5138c2aa98e2SPeter Wemm 	{
51393299c2f1SGregory Neil Shapiro 		int af;
5140c2aa98e2SPeter Wemm 		struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
514176b7bf71SPeter Wemm 		SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr;
51423299c2f1SGregory Neil Shapiro #   if NETINET6
51433299c2f1SGregory Neil Shapiro 		char *addr;
51443299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
51453299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
5146c2aa98e2SPeter Wemm 		struct in_addr ia;
5147c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
5148c2aa98e2SPeter Wemm 		struct ifreq ifrf;
51493299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
5150c2aa98e2SPeter Wemm 		char ip_addr[256];
51513299c2f1SGregory Neil Shapiro #   if NETINET6
51523299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
51533299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
51543299c2f1SGregory Neil Shapiro 
51553299c2f1SGregory Neil Shapiro 		/*
51563299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
51573299c2f1SGregory Neil Shapiro 		**  don't try to use it.
51583299c2f1SGregory Neil Shapiro 		*/
51593299c2f1SGregory Neil Shapiro 
51603299c2f1SGregory Neil Shapiro 		if ((ifc.ifc_len - i) < sizeof *ifr)
51613299c2f1SGregory Neil Shapiro 			break;
5162c2aa98e2SPeter Wemm 
5163c2aa98e2SPeter Wemm #   ifdef BSD4_4_SOCKADDR
516476b7bf71SPeter Wemm 		if (sa->sa.sa_len > sizeof ifr->ifr_addr)
516576b7bf71SPeter Wemm 			i += sizeof ifr->ifr_name + sa->sa.sa_len;
5166c2aa98e2SPeter Wemm 		else
51673299c2f1SGregory Neil Shapiro #   endif /* BSD4_4_SOCKADDR */
5168c2aa98e2SPeter Wemm 			i += sizeof *ifr;
5169c2aa98e2SPeter Wemm 
5170c2aa98e2SPeter Wemm 		if (tTd(0, 20))
51713299c2f1SGregory Neil Shapiro 			dprintf("%s\n", anynet_ntoa(sa));
5172c2aa98e2SPeter Wemm 
51733299c2f1SGregory Neil Shapiro 		af = ifr->ifr_addr.sa_family;
51743299c2f1SGregory Neil Shapiro 		if (af != AF_INET
51753299c2f1SGregory Neil Shapiro #   if NETINET6
51763299c2f1SGregory Neil Shapiro 		    && af != AF_INET6
51773299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
51783299c2f1SGregory Neil Shapiro 		    )
5179c2aa98e2SPeter Wemm 			continue;
5180c2aa98e2SPeter Wemm 
5181c2aa98e2SPeter Wemm #   ifdef SIOCGIFFLAGS
51823299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct ifreq));
51833299c2f1SGregory Neil Shapiro 		(void) strlcpy(ifrf.ifr_name, ifr->ifr_name,
51843299c2f1SGregory Neil Shapiro 			       sizeof(ifrf.ifr_name));
51853299c2f1SGregory Neil Shapiro 		(void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
5186c2aa98e2SPeter Wemm 		if (tTd(0, 41))
51873299c2f1SGregory Neil Shapiro 			dprintf("\tflags: %lx\n",
51883299c2f1SGregory Neil Shapiro 				(unsigned long) ifrf.ifr_flags);
5189c2aa98e2SPeter Wemm #    define IFRFREF ifrf
51903299c2f1SGregory Neil Shapiro #   else /* SIOCGIFFLAGS */
5191c2aa98e2SPeter Wemm #    define IFRFREF (*ifr)
51923299c2f1SGregory Neil Shapiro #   endif /* SIOCGIFFLAGS */
51933299c2f1SGregory Neil Shapiro 
5194c2aa98e2SPeter Wemm 		if (!bitset(IFF_UP, IFRFREF.ifr_flags))
5195c2aa98e2SPeter Wemm 			continue;
5196c2aa98e2SPeter Wemm 
51973299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
51983299c2f1SGregory Neil Shapiro 
5199c2aa98e2SPeter Wemm 		/* extract IP address from the list*/
52003299c2f1SGregory Neil Shapiro 		switch (af)
52013299c2f1SGregory Neil Shapiro 		{
52023299c2f1SGregory Neil Shapiro 		  case AF_INET:
520376b7bf71SPeter Wemm 			ia = sa->sin.sin_addr;
52043299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
52053299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
5206c2aa98e2SPeter Wemm 			{
5207c2aa98e2SPeter Wemm 				message("WARNING: interface %s is UP with %s address",
5208c2aa98e2SPeter Wemm 					ifr->ifr_name, inet_ntoa(ia));
5209c2aa98e2SPeter Wemm 				continue;
5210c2aa98e2SPeter Wemm 			}
5211c2aa98e2SPeter Wemm 
5212c2aa98e2SPeter Wemm 			/* save IP address in text from */
5213c2aa98e2SPeter Wemm 			(void) snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
52141ec86adfSBruce Evans 					(int) sizeof ip_addr - 3,
5215c2aa98e2SPeter Wemm 					inet_ntoa(ia));
52163299c2f1SGregory Neil Shapiro 			break;
52173299c2f1SGregory Neil Shapiro 
52183299c2f1SGregory Neil Shapiro #   if NETINET6
52193299c2f1SGregory Neil Shapiro 		  case AF_INET6:
5220b4662009SGregory Neil Shapiro #    ifdef __KAME__
5221b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
5222b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
5223b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
5224b4662009SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
5225b4662009SGregory Neil Shapiro 			{
5226b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
5227b4662009SGregory Neil Shapiro 
5228b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
5229b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
5230b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
5231b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
5232b4662009SGregory Neil Shapiro 			}
5233b4662009SGregory Neil Shapiro #    endif /* __KAME__ */
52343299c2f1SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
5235c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
52363299c2f1SGregory Neil Shapiro 			{
52373299c2f1SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
52383299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
52393299c2f1SGregory Neil Shapiro 					ifr->ifr_name,
52403299c2f1SGregory Neil Shapiro 					addr == NULL ? "(NULL)" : addr);
52413299c2f1SGregory Neil Shapiro 				continue;
52423299c2f1SGregory Neil Shapiro 			}
52433299c2f1SGregory Neil Shapiro 
52443299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
52453299c2f1SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
52463299c2f1SGregory Neil Shapiro 			if (addr != NULL)
52473299c2f1SGregory Neil Shapiro 				(void) snprintf(ip_addr, sizeof ip_addr,
52483299c2f1SGregory Neil Shapiro 						"[%.*s]",
52493299c2f1SGregory Neil Shapiro 						(int) sizeof ip_addr - 3, addr);
52503299c2f1SGregory Neil Shapiro 			break;
52513299c2f1SGregory Neil Shapiro 
52523299c2f1SGregory Neil Shapiro #   endif /* NETINET6 */
52533299c2f1SGregory Neil Shapiro 		}
52543299c2f1SGregory Neil Shapiro 
52553299c2f1SGregory Neil Shapiro 		if (ip_addr[0] == '\0')
52563299c2f1SGregory Neil Shapiro 			continue;
52573299c2f1SGregory Neil Shapiro 
5258c2aa98e2SPeter Wemm 		if (!wordinclass(ip_addr, 'w'))
5259c2aa98e2SPeter Wemm 		{
5260c2aa98e2SPeter Wemm 			setclass('w', ip_addr);
5261c2aa98e2SPeter Wemm 			if (tTd(0, 4))
52623299c2f1SGregory Neil Shapiro 				dprintf("\ta.k.a.: %s\n", ip_addr);
5263c2aa98e2SPeter Wemm 		}
5264c2aa98e2SPeter Wemm 
5265c2aa98e2SPeter Wemm 		/* skip "loopback" interface "lo" */
5266c2aa98e2SPeter Wemm 		if (bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
5267c2aa98e2SPeter Wemm 			continue;
5268c2aa98e2SPeter Wemm 
526976b7bf71SPeter Wemm 		(void) add_hostnames(sa);
5270c2aa98e2SPeter Wemm 	}
5271c0c4794dSGregory Neil Shapiro 	sm_free(ifc.ifc_buf);
52723299c2f1SGregory Neil Shapiro 	(void) close(s);
5273c2aa98e2SPeter Wemm #  undef IFRFREF
52743299c2f1SGregory Neil Shapiro # endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
52753299c2f1SGregory Neil Shapiro #endif /* NETINET6 && defined(SIOCGLIFCONF) */
52763299c2f1SGregory Neil Shapiro }
52773299c2f1SGregory Neil Shapiro /*
52783299c2f1SGregory Neil Shapiro **  ISLOOPBACK -- is socket address in the loopback net?
52793299c2f1SGregory Neil Shapiro **
52803299c2f1SGregory Neil Shapiro **	Parameters:
52813299c2f1SGregory Neil Shapiro **		sa -- socket address.
52823299c2f1SGregory Neil Shapiro **
52833299c2f1SGregory Neil Shapiro **	Returns:
52843299c2f1SGregory Neil Shapiro **		TRUE -- is socket address in the loopback net?
52853299c2f1SGregory Neil Shapiro **		FALSE -- otherwise
52863299c2f1SGregory Neil Shapiro **
52873299c2f1SGregory Neil Shapiro */
52883299c2f1SGregory Neil Shapiro 
52893299c2f1SGregory Neil Shapiro bool
52903299c2f1SGregory Neil Shapiro isloopback(sa)
52913299c2f1SGregory Neil Shapiro 	SOCKADDR sa;
52923299c2f1SGregory Neil Shapiro {
52933299c2f1SGregory Neil Shapiro #if NETINET6
52943299c2f1SGregory Neil Shapiro 	if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
52953299c2f1SGregory Neil Shapiro 		return TRUE;
52963299c2f1SGregory Neil Shapiro #else /* NETINET6 */
52973299c2f1SGregory Neil Shapiro 	/* XXX how to correctly extract IN_LOOPBACKNET part? */
52983299c2f1SGregory Neil Shapiro 	if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET)
52993299c2f1SGregory Neil Shapiro 	     >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
53003299c2f1SGregory Neil Shapiro 		return TRUE;
53013299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
53023299c2f1SGregory Neil Shapiro 	return FALSE;
5303c2aa98e2SPeter Wemm }
5304c2aa98e2SPeter Wemm /*
5305c2aa98e2SPeter Wemm **  GET_NUM_PROCS_ONLINE -- return the number of processors currently online
5306c2aa98e2SPeter Wemm **
5307c2aa98e2SPeter Wemm **	Parameters:
5308c2aa98e2SPeter Wemm **		none.
5309c2aa98e2SPeter Wemm **
5310c2aa98e2SPeter Wemm **	Returns:
5311c2aa98e2SPeter Wemm **		The number of processors online.
5312c2aa98e2SPeter Wemm */
5313c2aa98e2SPeter Wemm 
53143299c2f1SGregory Neil Shapiro static int
5315c2aa98e2SPeter Wemm get_num_procs_online()
5316c2aa98e2SPeter Wemm {
5317c2aa98e2SPeter Wemm 	int nproc = 0;
5318c2aa98e2SPeter Wemm 
53193299c2f1SGregory Neil Shapiro #ifdef USESYSCTL
53203299c2f1SGregory Neil Shapiro # if defined(CTL_HW) && defined(HW_NCPU)
53213299c2f1SGregory Neil Shapiro 	size_t sz;
53223299c2f1SGregory Neil Shapiro 	int mib[2];
53233299c2f1SGregory Neil Shapiro 
53243299c2f1SGregory Neil Shapiro 	mib[0] = CTL_HW;
53253299c2f1SGregory Neil Shapiro 	mib[1] = HW_NCPU;
53263299c2f1SGregory Neil Shapiro 	sz = (size_t) sizeof nproc;
53273299c2f1SGregory Neil Shapiro 	(void) sysctl(mib, 2, &nproc, &sz, NULL, 0);
53283299c2f1SGregory Neil Shapiro # endif /* defined(CTL_HW) && defined(HW_NCPUS) */
53293299c2f1SGregory Neil Shapiro #else /* USESYSCTL */
5330c2aa98e2SPeter Wemm # ifdef _SC_NPROCESSORS_ONLN
5331c2aa98e2SPeter Wemm 	nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
53323299c2f1SGregory Neil Shapiro # else /* _SC_NPROCESSORS_ONLN */
53333299c2f1SGregory Neil Shapiro #  ifdef __hpux
53343299c2f1SGregory Neil Shapiro #   include <sys/pstat.h>
53353299c2f1SGregory Neil Shapiro 	struct pst_dynamic psd;
53363299c2f1SGregory Neil Shapiro 
53373299c2f1SGregory Neil Shapiro 	if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1)
53383299c2f1SGregory Neil Shapiro 		nproc = psd.psd_proc_cnt;
53393299c2f1SGregory Neil Shapiro #  endif /* __hpux */
53403299c2f1SGregory Neil Shapiro # endif /* _SC_NPROCESSORS_ONLN */
53413299c2f1SGregory Neil Shapiro #endif /* USESYSCTL */
53423299c2f1SGregory Neil Shapiro 
5343c2aa98e2SPeter Wemm 	if (nproc <= 0)
5344c2aa98e2SPeter Wemm 		nproc = 1;
5345c2aa98e2SPeter Wemm 	return nproc;
5346c2aa98e2SPeter Wemm }
5347c2aa98e2SPeter Wemm /*
53483299c2f1SGregory Neil Shapiro **  SEED_RANDOM -- seed the random number generator
53493299c2f1SGregory Neil Shapiro **
53503299c2f1SGregory Neil Shapiro **	Parameters:
53513299c2f1SGregory Neil Shapiro **		none
53523299c2f1SGregory Neil Shapiro **
53533299c2f1SGregory Neil Shapiro **	Returns:
53543299c2f1SGregory Neil Shapiro **		none
53553299c2f1SGregory Neil Shapiro */
53563299c2f1SGregory Neil Shapiro 
53573299c2f1SGregory Neil Shapiro void
53583299c2f1SGregory Neil Shapiro seed_random()
53593299c2f1SGregory Neil Shapiro {
53603299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
53613299c2f1SGregory Neil Shapiro 	srandomdev();
53623299c2f1SGregory Neil Shapiro #else /* HASSRANDOMDEV */
53633299c2f1SGregory Neil Shapiro 	long seed;
53643299c2f1SGregory Neil Shapiro 	struct timeval t;
53653299c2f1SGregory Neil Shapiro 
53663299c2f1SGregory Neil Shapiro 	seed = (long) getpid();
53673299c2f1SGregory Neil Shapiro 	if (gettimeofday(&t, NULL) >= 0)
53683299c2f1SGregory Neil Shapiro 		seed += t.tv_sec + t.tv_usec;
53693299c2f1SGregory Neil Shapiro 
53703299c2f1SGregory Neil Shapiro # if HASRANDOM
53713299c2f1SGregory Neil Shapiro 	(void) srandom(seed);
53723299c2f1SGregory Neil Shapiro # else /* HASRANDOM */
53733299c2f1SGregory Neil Shapiro 	(void) srand((unsigned int) seed);
53743299c2f1SGregory Neil Shapiro # endif /* HASRANDOM */
53753299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
53763299c2f1SGregory Neil Shapiro }
53773299c2f1SGregory Neil Shapiro /*
5378c2aa98e2SPeter Wemm **  SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
5379c2aa98e2SPeter Wemm **
5380c2aa98e2SPeter Wemm **	Parameters:
5381c2aa98e2SPeter Wemm **		level -- syslog level
5382c2aa98e2SPeter Wemm **		id -- envelope ID or NULL (NOQUEUE)
5383c2aa98e2SPeter Wemm **		fmt -- format string
5384c2aa98e2SPeter Wemm **		arg... -- arguments as implied by fmt.
5385c2aa98e2SPeter Wemm **
5386c2aa98e2SPeter Wemm **	Returns:
5387c2aa98e2SPeter Wemm **		none
5388c2aa98e2SPeter Wemm */
5389c2aa98e2SPeter Wemm 
5390c2aa98e2SPeter Wemm /* VARARGS3 */
5391c2aa98e2SPeter Wemm void
5392c2aa98e2SPeter Wemm #ifdef __STDC__
5393c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...)
53943299c2f1SGregory Neil Shapiro #else /* __STDC__ */
5395c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist)
5396c2aa98e2SPeter Wemm 	int level;
5397c2aa98e2SPeter Wemm 	const char *id;
5398c2aa98e2SPeter Wemm 	const char *fmt;
5399c2aa98e2SPeter Wemm 	va_dcl
54003299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
5401c2aa98e2SPeter Wemm {
5402c2aa98e2SPeter Wemm 	static char *buf = NULL;
54033299c2f1SGregory Neil Shapiro 	static size_t bufsize;
5404c2aa98e2SPeter Wemm 	char *begin, *end;
54053299c2f1SGregory Neil Shapiro 	int save_errno;
5406c2aa98e2SPeter Wemm 	int seq = 1;
5407c2aa98e2SPeter Wemm 	int idlen;
54083299c2f1SGregory Neil Shapiro 	char buf0[MAXLINE];
5409c2aa98e2SPeter Wemm 	extern int SnprfOverflow;
5410c2aa98e2SPeter Wemm 	extern int SyslogErrno;
5411c2aa98e2SPeter Wemm 	extern char *DoprEnd;
5412c2aa98e2SPeter Wemm 	VA_LOCAL_DECL
5413c2aa98e2SPeter Wemm 
54143299c2f1SGregory Neil Shapiro 	save_errno = SyslogErrno = errno;
5415c2aa98e2SPeter Wemm 	if (id == NULL)
5416c2aa98e2SPeter Wemm 		id = "NOQUEUE";
5417c2aa98e2SPeter Wemm 	else if (strcmp(id, NOQID) == 0)
5418c2aa98e2SPeter Wemm 		id = "";
54193299c2f1SGregory Neil Shapiro 	idlen = strlen(id);
5420c2aa98e2SPeter Wemm 
54213299c2f1SGregory Neil Shapiro 	if (buf == NULL)
54223299c2f1SGregory Neil Shapiro 	{
54233299c2f1SGregory Neil Shapiro 		buf = buf0;
54243299c2f1SGregory Neil Shapiro 		bufsize = sizeof buf0;
54253299c2f1SGregory Neil Shapiro 	}
54263299c2f1SGregory Neil Shapiro 
54273299c2f1SGregory Neil Shapiro 	for (;;)
54283299c2f1SGregory Neil Shapiro 	{
5429c2aa98e2SPeter Wemm 		/* do a virtual vsnprintf into buf */
5430c2aa98e2SPeter Wemm 		VA_START(fmt);
5431c2aa98e2SPeter Wemm 		buf[0] = 0;
5432c2aa98e2SPeter Wemm 		DoprEnd = buf + bufsize - 1;
5433c2aa98e2SPeter Wemm 		SnprfOverflow = 0;
5434c2aa98e2SPeter Wemm 		sm_dopr(buf, fmt, ap);
5435c2aa98e2SPeter Wemm 		*DoprEnd = '\0';
5436c2aa98e2SPeter Wemm 		VA_END;
5437c2aa98e2SPeter Wemm 		/* end of virtual vsnprintf */
5438c2aa98e2SPeter Wemm 
54393299c2f1SGregory Neil Shapiro 		if (SnprfOverflow == 0)
54403299c2f1SGregory Neil Shapiro 			break;
54413299c2f1SGregory Neil Shapiro 
5442c2aa98e2SPeter Wemm 		/* String too small, redo with correct size */
5443c2aa98e2SPeter Wemm 		bufsize += SnprfOverflow + 1;
54443299c2f1SGregory Neil Shapiro 		if (buf != buf0)
5445c0c4794dSGregory Neil Shapiro 			sm_free(buf);
54463299c2f1SGregory Neil Shapiro 		buf = xalloc(bufsize * sizeof (char));
5447c2aa98e2SPeter Wemm 	}
5448c2aa98e2SPeter Wemm 	if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE)
5449c2aa98e2SPeter Wemm 	{
5450c2aa98e2SPeter Wemm #if LOG
5451c2aa98e2SPeter Wemm 		if (*id == '\0')
5452c2aa98e2SPeter Wemm 			syslog(level, "%s", buf);
5453c2aa98e2SPeter Wemm 		else
5454c2aa98e2SPeter Wemm 			syslog(level, "%s: %s", id, buf);
54553299c2f1SGregory Neil Shapiro #else /* LOG */
5456c2aa98e2SPeter Wemm 		/*XXX should do something more sensible */
5457c2aa98e2SPeter Wemm 		if (*id == '\0')
5458c2aa98e2SPeter Wemm 			fprintf(stderr, "%s\n", buf);
5459c2aa98e2SPeter Wemm 		else
5460c2aa98e2SPeter Wemm 			fprintf(stderr, "%s: %s\n", id, buf);
54613299c2f1SGregory Neil Shapiro #endif /* LOG */
54623299c2f1SGregory Neil Shapiro 		if (buf == buf0)
54633299c2f1SGregory Neil Shapiro 			buf = NULL;
54643299c2f1SGregory Neil Shapiro 		errno = save_errno;
5465c2aa98e2SPeter Wemm 		return;
5466c2aa98e2SPeter Wemm 	}
5467c2aa98e2SPeter Wemm 
5468c2aa98e2SPeter Wemm 	begin = buf;
5469c2aa98e2SPeter Wemm 	while (*begin != '\0' &&
5470c2aa98e2SPeter Wemm 	       (strlen(begin) + idlen + 5) > SYSLOG_BUFSIZE)
5471c2aa98e2SPeter Wemm 	{
5472c2aa98e2SPeter Wemm 		char save;
5473c2aa98e2SPeter Wemm 
5474c2aa98e2SPeter Wemm 		if (seq == 999)
5475c2aa98e2SPeter Wemm 		{
5476c2aa98e2SPeter Wemm 			/* Too many messages */
5477c2aa98e2SPeter Wemm 			break;
5478c2aa98e2SPeter Wemm 		}
5479c2aa98e2SPeter Wemm 		end = begin + SYSLOG_BUFSIZE - idlen - 12;
5480c2aa98e2SPeter Wemm 		while (end > begin)
5481c2aa98e2SPeter Wemm 		{
5482c2aa98e2SPeter Wemm 			/* Break on comma or space */
5483c2aa98e2SPeter Wemm 			if (*end == ',' || *end == ' ')
5484c2aa98e2SPeter Wemm 			{
5485c2aa98e2SPeter Wemm 				end++;	  /* Include separator */
5486c2aa98e2SPeter Wemm 				break;
5487c2aa98e2SPeter Wemm 			}
5488c2aa98e2SPeter Wemm 			end--;
5489c2aa98e2SPeter Wemm 		}
5490c2aa98e2SPeter Wemm 		/* No separator, break midstring... */
5491c2aa98e2SPeter Wemm 		if (end == begin)
5492c2aa98e2SPeter Wemm 			end = begin + SYSLOG_BUFSIZE - idlen - 12;
5493c2aa98e2SPeter Wemm 		save = *end;
5494c2aa98e2SPeter Wemm 		*end = 0;
5495c2aa98e2SPeter Wemm #if LOG
5496c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s ...", id, seq++, begin);
54973299c2f1SGregory Neil Shapiro #else /* LOG */
5498c2aa98e2SPeter Wemm 		fprintf(stderr, "%s[%d]: %s ...\n", id, seq++, begin);
54993299c2f1SGregory Neil Shapiro #endif /* LOG */
5500c2aa98e2SPeter Wemm 		*end = save;
5501c2aa98e2SPeter Wemm 		begin = end;
5502c2aa98e2SPeter Wemm 	}
5503c2aa98e2SPeter Wemm 	if (seq == 999)
5504c2aa98e2SPeter Wemm #if LOG
55053299c2f1SGregory Neil Shapiro 		syslog(level, "%s[%d]: log terminated, too many parts",
55063299c2f1SGregory Neil Shapiro 			id, seq);
55073299c2f1SGregory Neil Shapiro #else /* LOG */
55083299c2f1SGregory Neil Shapiro 		fprintf(stderr, "%s[%d]: log terminated, too many parts\n",
55093299c2f1SGregory Neil Shapiro 			id, seq);
55103299c2f1SGregory Neil Shapiro #endif /* LOG */
5511c2aa98e2SPeter Wemm 	else if (*begin != '\0')
5512c2aa98e2SPeter Wemm #if LOG
5513c2aa98e2SPeter Wemm 		syslog(level, "%s[%d]: %s", id, seq, begin);
55143299c2f1SGregory Neil Shapiro #else /* LOG */
5515c2aa98e2SPeter Wemm 		fprintf(stderr, "%s[%d]: %s\n", id, seq, begin);
55163299c2f1SGregory Neil Shapiro #endif /* LOG */
55173299c2f1SGregory Neil Shapiro 	if (buf == buf0)
55183299c2f1SGregory Neil Shapiro 		buf = NULL;
55193299c2f1SGregory Neil Shapiro 	errno = save_errno;
5520c2aa98e2SPeter Wemm }
5521c2aa98e2SPeter Wemm /*
5522c2aa98e2SPeter Wemm **  HARD_SYSLOG -- call syslog repeatedly until it works
5523c2aa98e2SPeter Wemm **
5524c2aa98e2SPeter Wemm **	Needed on HP-UX, which apparently doesn't guarantee that
5525c2aa98e2SPeter Wemm **	syslog succeeds during interrupt handlers.
5526c2aa98e2SPeter Wemm */
5527c2aa98e2SPeter Wemm 
5528c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11)
5529c2aa98e2SPeter Wemm 
5530c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES	100
5531c2aa98e2SPeter Wemm # undef syslog
5532c2aa98e2SPeter Wemm # ifdef V4FS
5533c2aa98e2SPeter Wemm #  define XCNST	const
5534c2aa98e2SPeter Wemm #  define CAST	(const char *)
55353299c2f1SGregory Neil Shapiro # else /* V4FS */
5536c2aa98e2SPeter Wemm #  define XCNST
5537c2aa98e2SPeter Wemm #  define CAST
55383299c2f1SGregory Neil Shapiro # endif /* V4FS */
5539c2aa98e2SPeter Wemm 
5540c2aa98e2SPeter Wemm void
5541c2aa98e2SPeter Wemm # ifdef __STDC__
5542c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...)
55433299c2f1SGregory Neil Shapiro # else /* __STDC__ */
5544c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist)
5545c2aa98e2SPeter Wemm 	int pri;
5546c2aa98e2SPeter Wemm 	XCNST char *msg;
5547c2aa98e2SPeter Wemm 	va_dcl
55483299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
5549c2aa98e2SPeter Wemm {
5550c2aa98e2SPeter Wemm 	int i;
5551c2aa98e2SPeter Wemm 	char buf[SYSLOG_BUFSIZE];
5552c2aa98e2SPeter Wemm 	VA_LOCAL_DECL;
5553c2aa98e2SPeter Wemm 
5554c2aa98e2SPeter Wemm 	VA_START(msg);
5555c2aa98e2SPeter Wemm 	vsnprintf(buf, sizeof buf, msg, ap);
5556c2aa98e2SPeter Wemm 	VA_END;
5557c2aa98e2SPeter Wemm 
5558c2aa98e2SPeter Wemm 	for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; )
5559c2aa98e2SPeter Wemm 		continue;
5560c2aa98e2SPeter Wemm }
5561c2aa98e2SPeter Wemm 
5562c2aa98e2SPeter Wemm # undef CAST
55633299c2f1SGregory Neil Shapiro #endif /* defined(__hpux) && !defined(HPUX11) */
55643299c2f1SGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
5565c2aa98e2SPeter Wemm /*
5566c2aa98e2SPeter Wemm **  LOCAL_HOSTNAME_LENGTH
5567c2aa98e2SPeter Wemm **
5568c2aa98e2SPeter Wemm **	This is required to get sendmail to compile against BIND 4.9.x
5569c2aa98e2SPeter Wemm **	on Ultrix.
55703299c2f1SGregory Neil Shapiro **
55713299c2f1SGregory Neil Shapiro **	Unfortunately, a Compaq Y2K patch kit provides it without
55723299c2f1SGregory Neil Shapiro **	bumping __RES in /usr/include/resolv.h so we can't automatically
55733299c2f1SGregory Neil Shapiro **	figure out whether it is needed.
5574c2aa98e2SPeter Wemm */
5575c2aa98e2SPeter Wemm 
5576c2aa98e2SPeter Wemm int
5577c2aa98e2SPeter Wemm local_hostname_length(hostname)
5578c2aa98e2SPeter Wemm 	char *hostname;
5579c2aa98e2SPeter Wemm {
5580c2aa98e2SPeter Wemm 	int len_host, len_domain;
5581c2aa98e2SPeter Wemm 
5582c2aa98e2SPeter Wemm 	if (!*_res.defdname)
5583c2aa98e2SPeter Wemm 		res_init();
5584c2aa98e2SPeter Wemm 	len_host = strlen(hostname);
5585c2aa98e2SPeter Wemm 	len_domain = strlen(_res.defdname);
5586c2aa98e2SPeter Wemm 	if (len_host > len_domain &&
55873299c2f1SGregory Neil Shapiro 	    (strcasecmp(hostname + len_host - len_domain,
55883299c2f1SGregory Neil Shapiro 			_res.defdname) == 0) &&
5589c2aa98e2SPeter Wemm 	    hostname[len_host - len_domain - 1] == '.')
5590c2aa98e2SPeter Wemm 		return len_host - len_domain - 1;
5591c2aa98e2SPeter Wemm 	else
5592c2aa98e2SPeter Wemm 		return 0;
5593c2aa98e2SPeter Wemm }
55943299c2f1SGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
5595c2aa98e2SPeter Wemm 
5596c2aa98e2SPeter Wemm /*
5597c2aa98e2SPeter Wemm **  Compile-Time options
5598c2aa98e2SPeter Wemm */
5599c2aa98e2SPeter Wemm 
5600c2aa98e2SPeter Wemm char	*CompileOptions[] =
5601c2aa98e2SPeter Wemm {
5602c0c4794dSGregory Neil Shapiro #if EGD
5603c0c4794dSGregory Neil Shapiro 	"EGD",
5604c0c4794dSGregory Neil Shapiro #endif /* EGD */
5605c2aa98e2SPeter Wemm #ifdef HESIOD
5606c2aa98e2SPeter Wemm 	"HESIOD",
56073299c2f1SGregory Neil Shapiro #endif /* HESIOD */
5608c2aa98e2SPeter Wemm #if HES_GETMAILHOST
5609c2aa98e2SPeter Wemm 	"HES_GETMAILHOST",
56103299c2f1SGregory Neil Shapiro #endif /* HES_GETMAILHOST */
5611c2aa98e2SPeter Wemm #ifdef LDAPMAP
5612c2aa98e2SPeter Wemm 	"LDAPMAP",
56133299c2f1SGregory Neil Shapiro #endif /* LDAPMAP */
56143299c2f1SGregory Neil Shapiro #ifdef MAP_NSD
56153299c2f1SGregory Neil Shapiro 	"MAP_NSD",
56163299c2f1SGregory Neil Shapiro #endif /* MAP_NSD */
5617c2aa98e2SPeter Wemm #ifdef MAP_REGEX
5618c2aa98e2SPeter Wemm 	"MAP_REGEX",
56193299c2f1SGregory Neil Shapiro #endif /* MAP_REGEX */
5620c2aa98e2SPeter Wemm #if LOG
5621c2aa98e2SPeter Wemm 	"LOG",
56223299c2f1SGregory Neil Shapiro #endif /* LOG */
5623c2aa98e2SPeter Wemm #if MATCHGECOS
5624c2aa98e2SPeter Wemm 	"MATCHGECOS",
56253299c2f1SGregory Neil Shapiro #endif /* MATCHGECOS */
5626c2aa98e2SPeter Wemm #if MIME7TO8
5627c2aa98e2SPeter Wemm 	"MIME7TO8",
56283299c2f1SGregory Neil Shapiro #endif /* MIME7TO8 */
5629c2aa98e2SPeter Wemm #if MIME8TO7
5630c2aa98e2SPeter Wemm 	"MIME8TO7",
56313299c2f1SGregory Neil Shapiro #endif /* MIME8TO7 */
5632c2aa98e2SPeter Wemm #if NAMED_BIND
5633c2aa98e2SPeter Wemm 	"NAMED_BIND",
56343299c2f1SGregory Neil Shapiro #endif /* NAMED_BIND */
5635c2aa98e2SPeter Wemm #ifdef NDBM
5636c2aa98e2SPeter Wemm 	"NDBM",
56373299c2f1SGregory Neil Shapiro #endif /* NDBM */
5638c2aa98e2SPeter Wemm #if NETINET
5639c2aa98e2SPeter Wemm 	"NETINET",
56403299c2f1SGregory Neil Shapiro #endif /* NETINET */
56413299c2f1SGregory Neil Shapiro #if NETINET6
56423299c2f1SGregory Neil Shapiro 	"NETINET6",
56433299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
5644c2aa98e2SPeter Wemm #if NETINFO
5645c2aa98e2SPeter Wemm 	"NETINFO",
56463299c2f1SGregory Neil Shapiro #endif /* NETINFO */
5647c2aa98e2SPeter Wemm #if NETISO
5648c2aa98e2SPeter Wemm 	"NETISO",
56493299c2f1SGregory Neil Shapiro #endif /* NETISO */
5650c2aa98e2SPeter Wemm #if NETNS
5651c2aa98e2SPeter Wemm 	"NETNS",
56523299c2f1SGregory Neil Shapiro #endif /* NETNS */
5653c2aa98e2SPeter Wemm #if NETUNIX
5654c2aa98e2SPeter Wemm 	"NETUNIX",
56553299c2f1SGregory Neil Shapiro #endif /* NETUNIX */
5656c2aa98e2SPeter Wemm #if NETX25
5657c2aa98e2SPeter Wemm 	"NETX25",
56583299c2f1SGregory Neil Shapiro #endif /* NETX25 */
5659c2aa98e2SPeter Wemm #ifdef NEWDB
5660c2aa98e2SPeter Wemm 	"NEWDB",
56613299c2f1SGregory Neil Shapiro #endif /* NEWDB */
5662c2aa98e2SPeter Wemm #ifdef NIS
5663c2aa98e2SPeter Wemm 	"NIS",
56643299c2f1SGregory Neil Shapiro #endif /* NIS */
5665c2aa98e2SPeter Wemm #ifdef NISPLUS
5666c2aa98e2SPeter Wemm 	"NISPLUS",
56673299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
56683299c2f1SGregory Neil Shapiro #ifdef PH_MAP
56693299c2f1SGregory Neil Shapiro 	"PH_MAP",
56703299c2f1SGregory Neil Shapiro #endif /* PH_MAP */
5671c2aa98e2SPeter Wemm #if QUEUE
5672c2aa98e2SPeter Wemm 	"QUEUE",
56733299c2f1SGregory Neil Shapiro #endif /* QUEUE */
56743299c2f1SGregory Neil Shapiro #if SASL
56753299c2f1SGregory Neil Shapiro 	"SASL",
56763299c2f1SGregory Neil Shapiro #endif /* SASL */
5677c2aa98e2SPeter Wemm #if SCANF
5678c2aa98e2SPeter Wemm 	"SCANF",
56793299c2f1SGregory Neil Shapiro #endif /* SCANF */
56803299c2f1SGregory Neil Shapiro #if SFIO
56813299c2f1SGregory Neil Shapiro 	"SFIO",
56823299c2f1SGregory Neil Shapiro #endif /* SFIO */
5683c2aa98e2SPeter Wemm #if SMTP
5684c2aa98e2SPeter Wemm 	"SMTP",
56853299c2f1SGregory Neil Shapiro #endif /* SMTP */
5686c2aa98e2SPeter Wemm #if SMTPDEBUG
5687c2aa98e2SPeter Wemm 	"SMTPDEBUG",
56883299c2f1SGregory Neil Shapiro #endif /* SMTPDEBUG */
56893299c2f1SGregory Neil Shapiro #if STARTTLS
56903299c2f1SGregory Neil Shapiro 	"STARTTLS",
56913299c2f1SGregory Neil Shapiro #endif /* STARTTLS */
5692c2aa98e2SPeter Wemm #ifdef SUID_ROOT_FILES_OK
5693c2aa98e2SPeter Wemm 	"SUID_ROOT_FILES_OK",
56943299c2f1SGregory Neil Shapiro #endif /* SUID_ROOT_FILES_OK */
5695c2aa98e2SPeter Wemm #if TCPWRAPPERS
5696c2aa98e2SPeter Wemm 	"TCPWRAPPERS",
56973299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
5698c2aa98e2SPeter Wemm #if USERDB
5699c2aa98e2SPeter Wemm 	"USERDB",
57003299c2f1SGregory Neil Shapiro #endif /* USERDB */
5701c2aa98e2SPeter Wemm #if XDEBUG
5702c2aa98e2SPeter Wemm 	"XDEBUG",
57033299c2f1SGregory Neil Shapiro #endif /* XDEBUG */
5704c2aa98e2SPeter Wemm #ifdef XLA
5705c2aa98e2SPeter Wemm 	"XLA",
57063299c2f1SGregory Neil Shapiro #endif /* XLA */
5707c2aa98e2SPeter Wemm 	NULL
5708c2aa98e2SPeter Wemm };
5709c2aa98e2SPeter Wemm 
5710c2aa98e2SPeter Wemm 
5711c2aa98e2SPeter Wemm /*
5712c2aa98e2SPeter Wemm **  OS compile options.
5713c2aa98e2SPeter Wemm */
5714c2aa98e2SPeter Wemm 
5715c2aa98e2SPeter Wemm char	*OsCompileOptions[] =
5716c2aa98e2SPeter Wemm {
5717c2aa98e2SPeter Wemm #if BOGUS_O_EXCL
5718c2aa98e2SPeter Wemm 	"BOGUS_O_EXCL",
57193299c2f1SGregory Neil Shapiro #endif /* BOGUS_O_EXCL */
57203299c2f1SGregory Neil Shapiro #if FAST_PID_RECYCLE
57213299c2f1SGregory Neil Shapiro 	"FAST_PID_RECYCLE",
57223299c2f1SGregory Neil Shapiro #endif /* FAST_PID_RECYCLE */
57233299c2f1SGregory Neil Shapiro #if HASFCHOWN
57243299c2f1SGregory Neil Shapiro 	"HASFCHOWN",
57253299c2f1SGregory Neil Shapiro #endif /* HASFCHOWN */
5726c2aa98e2SPeter Wemm #if HASFCHMOD
5727c2aa98e2SPeter Wemm 	"HASFCHMOD",
57283299c2f1SGregory Neil Shapiro #endif /* HASFCHMOD */
5729c2aa98e2SPeter Wemm #if HASFLOCK
5730c2aa98e2SPeter Wemm 	"HASFLOCK",
57313299c2f1SGregory Neil Shapiro #endif /* HASFLOCK */
5732c2aa98e2SPeter Wemm #if HASGETDTABLESIZE
5733c2aa98e2SPeter Wemm 	"HASGETDTABLESIZE",
57343299c2f1SGregory Neil Shapiro #endif /* HASGETDTABLESIZE */
5735c2aa98e2SPeter Wemm #if HASGETUSERSHELL
5736c2aa98e2SPeter Wemm 	"HASGETUSERSHELL",
57373299c2f1SGregory Neil Shapiro #endif /* HASGETUSERSHELL */
5738c2aa98e2SPeter Wemm #if HASINITGROUPS
5739c2aa98e2SPeter Wemm 	"HASINITGROUPS",
57403299c2f1SGregory Neil Shapiro #endif /* HASINITGROUPS */
5741c2aa98e2SPeter Wemm #if HASLSTAT
5742c2aa98e2SPeter Wemm 	"HASLSTAT",
57433299c2f1SGregory Neil Shapiro #endif /* HASLSTAT */
57443299c2f1SGregory Neil Shapiro #if HASRANDOM
57453299c2f1SGregory Neil Shapiro 	"HASRANDOM",
57463299c2f1SGregory Neil Shapiro #endif /* HASRANDOM */
57473299c2f1SGregory Neil Shapiro #if HASSETLOGIN
57483299c2f1SGregory Neil Shapiro 	"HASSETLOGIN",
57493299c2f1SGregory Neil Shapiro #endif /* HASSETLOGIN */
5750c2aa98e2SPeter Wemm #if HASSETREUID
5751c2aa98e2SPeter Wemm 	"HASSETREUID",
57523299c2f1SGregory Neil Shapiro #endif /* HASSETREUID */
5753c2aa98e2SPeter Wemm #if HASSETRLIMIT
5754c2aa98e2SPeter Wemm 	"HASSETRLIMIT",
57553299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
5756c2aa98e2SPeter Wemm #if HASSETSID
5757c2aa98e2SPeter Wemm 	"HASSETSID",
57583299c2f1SGregory Neil Shapiro #endif /* HASSETSID */
5759c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT
5760c2aa98e2SPeter Wemm 	"HASSETUSERCONTEXT",
57613299c2f1SGregory Neil Shapiro #endif /* HASSETUSERCONTEXT */
5762c2aa98e2SPeter Wemm #if HASSETVBUF
5763c2aa98e2SPeter Wemm 	"HASSETVBUF",
57643299c2f1SGregory Neil Shapiro #endif /* HASSETVBUF */
5765c2aa98e2SPeter Wemm #if HASSNPRINTF
5766c2aa98e2SPeter Wemm 	"HASSNPRINTF",
57673299c2f1SGregory Neil Shapiro #endif /* HASSNPRINTF */
5768c2aa98e2SPeter Wemm #if HAS_ST_GEN
5769c2aa98e2SPeter Wemm 	"HAS_ST_GEN",
57703299c2f1SGregory Neil Shapiro #endif /* HAS_ST_GEN */
57713299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
57723299c2f1SGregory Neil Shapiro 	"HASSRANDOMDEV",
57733299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
57743299c2f1SGregory Neil Shapiro #if HASURANDOMDEV
57753299c2f1SGregory Neil Shapiro 	"HASURANDOMDEV",
57763299c2f1SGregory Neil Shapiro #endif /* HASURANDOMDEV */
5777c2aa98e2SPeter Wemm #if HASSTRERROR
5778c2aa98e2SPeter Wemm 	"HASSTRERROR",
57793299c2f1SGregory Neil Shapiro #endif /* HASSTRERROR */
5780c2aa98e2SPeter Wemm #if HASULIMIT
5781c2aa98e2SPeter Wemm 	"HASULIMIT",
57823299c2f1SGregory Neil Shapiro #endif /* HASULIMIT */
5783c2aa98e2SPeter Wemm #if HASUNAME
5784c2aa98e2SPeter Wemm 	"HASUNAME",
57853299c2f1SGregory Neil Shapiro #endif /* HASUNAME */
5786c2aa98e2SPeter Wemm #if HASUNSETENV
5787c2aa98e2SPeter Wemm 	"HASUNSETENV",
57883299c2f1SGregory Neil Shapiro #endif /* HASUNSETENV */
5789c2aa98e2SPeter Wemm #if HASWAITPID
5790c2aa98e2SPeter Wemm 	"HASWAITPID",
57913299c2f1SGregory Neil Shapiro #endif /* HASWAITPID */
5792c2aa98e2SPeter Wemm #if IDENTPROTO
5793c2aa98e2SPeter Wemm 	"IDENTPROTO",
57943299c2f1SGregory Neil Shapiro #endif /* IDENTPROTO */
5795c2aa98e2SPeter Wemm #if IP_SRCROUTE
5796c2aa98e2SPeter Wemm 	"IP_SRCROUTE",
57973299c2f1SGregory Neil Shapiro #endif /* IP_SRCROUTE */
5798c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
5799c2aa98e2SPeter Wemm 	"LOCK_ON_OPEN",
58003299c2f1SGregory Neil Shapiro #endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
5801c2aa98e2SPeter Wemm #if NEEDFSYNC
5802c2aa98e2SPeter Wemm 	"NEEDFSYNC",
58033299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
5804c2aa98e2SPeter Wemm #if NOFTRUNCATE
5805c2aa98e2SPeter Wemm 	"NOFTRUNCATE",
58063299c2f1SGregory Neil Shapiro #endif /* NOFTRUNCATE */
5807c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H
5808c2aa98e2SPeter Wemm 	"RLIMIT_NEEDS_SYS_TIME_H",
58093299c2f1SGregory Neil Shapiro #endif /* RLIMIT_NEEDS_SYS_TIME_H */
5810c2aa98e2SPeter Wemm #if SAFENFSPATHCONF
5811c2aa98e2SPeter Wemm 	"SAFENFSPATHCONF",
58123299c2f1SGregory Neil Shapiro #endif /* SAFENFSPATHCONF */
5813c2aa98e2SPeter Wemm #if SECUREWARE
5814c2aa98e2SPeter Wemm 	"SECUREWARE",
58153299c2f1SGregory Neil Shapiro #endif /* SECUREWARE */
5816c2aa98e2SPeter Wemm #if SHARE_V1
5817c2aa98e2SPeter Wemm 	"SHARE_V1",
58183299c2f1SGregory Neil Shapiro #endif /* SHARE_V1 */
5819c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN
5820c2aa98e2SPeter Wemm 	"SIOCGIFCONF_IS_BROKEN",
58213299c2f1SGregory Neil Shapiro #endif /* SIOCGIFCONF_IS_BROKEN */
5822c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN
5823c2aa98e2SPeter Wemm 	"SIOCGIFNUM_IS_BROKEN",
58243299c2f1SGregory Neil Shapiro #endif /* SIOCGIFNUM_IS_BROKEN */
58253299c2f1SGregory Neil Shapiro #if SNPRINTF_IS_BROKEN
58263299c2f1SGregory Neil Shapiro 	"SNPRINTF_IS_BROKEN",
58273299c2f1SGregory Neil Shapiro #endif /* SNPRINTF_IS_BROKEN */
58283299c2f1SGregory Neil Shapiro #if SO_REUSEADDR_IS_BROKEN
58293299c2f1SGregory Neil Shapiro 	"SO_REUSEADDR_IS_BROKEN",
58303299c2f1SGregory Neil Shapiro #endif /* SO_REUSEADDR_IS_BROKEN */
5831c2aa98e2SPeter Wemm #if SYS5SETPGRP
5832c2aa98e2SPeter Wemm 	"SYS5SETPGRP",
58333299c2f1SGregory Neil Shapiro #endif /* SYS5SETPGRP */
5834c2aa98e2SPeter Wemm #if SYSTEM5
5835c2aa98e2SPeter Wemm 	"SYSTEM5",
58363299c2f1SGregory Neil Shapiro #endif /* SYSTEM5 */
5837c2aa98e2SPeter Wemm #if USE_SA_SIGACTION
5838c2aa98e2SPeter Wemm 	"USE_SA_SIGACTION",
58393299c2f1SGregory Neil Shapiro #endif /* USE_SA_SIGACTION */
5840c2aa98e2SPeter Wemm #if USE_SIGLONGJMP
5841c2aa98e2SPeter Wemm 	"USE_SIGLONGJMP",
58423299c2f1SGregory Neil Shapiro #endif /* USE_SIGLONGJMP */
5843c2aa98e2SPeter Wemm #if USESETEUID
5844c2aa98e2SPeter Wemm 	"USESETEUID",
58453299c2f1SGregory Neil Shapiro #endif /* USESETEUID */
5846c2aa98e2SPeter Wemm 	NULL
5847c2aa98e2SPeter Wemm };
58483299c2f1SGregory Neil Shapiro 
5849