xref: /freebsd/contrib/sendmail/src/conf.c (revision d39bd2c1388b520fcba9abed1932acacead60fba)
1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2013 Proofpoint, Inc. and its suppliers.
33299c2f1SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
1412ed1c7cSGregory Neil Shapiro #include <sendmail.h>
1512ed1c7cSGregory Neil Shapiro 
16da7d7b9cSGregory Neil Shapiro SM_RCSID("@(#)$Id: conf.c,v 8.1192 2014-01-27 18:23:21 ca Exp $")
17c2aa98e2SPeter Wemm 
18951742c4SGregory Neil Shapiro #include <sm/sendmail.h>
193299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
207660b554SGregory Neil Shapiro #if NEWDB
217660b554SGregory Neil Shapiro # include "sm/bdb.h"
225b0945b5SGregory Neil Shapiro #endif
233299c2f1SGregory Neil Shapiro 
24951742c4SGregory Neil Shapiro #include <daemon.h>
25951742c4SGregory Neil Shapiro #include "map.h"
265b0945b5SGregory Neil Shapiro #include <ratectrl.h>
27951742c4SGregory Neil Shapiro 
282fb4f839SGregory Neil Shapiro #if defined(DEC) && NETINET6
29567a2fc9SGregory Neil Shapiro /* for the IPv6 device lookup */
30567a2fc9SGregory Neil Shapiro # define _SOCKADDR_LEN
31567a2fc9SGregory Neil Shapiro # include <macros.h>
322fb4f839SGregory Neil Shapiro #endif
33567a2fc9SGregory Neil Shapiro 
34c2aa98e2SPeter Wemm #include <sys/ioctl.h>
35c2aa98e2SPeter Wemm #include <sys/param.h>
363299c2f1SGregory Neil Shapiro 
37c2aa98e2SPeter Wemm #include <limits.h>
383299c2f1SGregory Neil Shapiro #if NETINET || NETINET6
393299c2f1SGregory Neil Shapiro # include <arpa/inet.h>
405b0945b5SGregory Neil Shapiro #endif
413299c2f1SGregory Neil Shapiro #if HASULIMIT && defined(HPUX11)
423299c2f1SGregory Neil Shapiro # include <ulimit.h>
435b0945b5SGregory Neil Shapiro #endif
445b0945b5SGregory Neil Shapiro #if STARTTLS
455b0945b5SGregory Neil Shapiro # include "tls.h"
465b0945b5SGregory Neil Shapiro #endif
473299c2f1SGregory Neil Shapiro 
483299c2f1SGregory Neil Shapiro static void	setupmaps __P((void));
493299c2f1SGregory Neil Shapiro static void	setupmailers __P((void));
5012ed1c7cSGregory Neil Shapiro static void	setupqueues __P((void));
513299c2f1SGregory Neil Shapiro static int	get_num_procs_online __P((void));
52684b2a5fSGregory Neil Shapiro static int	add_hostnames __P((SOCKADDR *));
53684b2a5fSGregory Neil Shapiro 
54684b2a5fSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
556f9c8e5bSGregory Neil Shapiro static struct hostent *sm_getipnodebyname __P((const char *, int, int, int *));
566f9c8e5bSGregory Neil Shapiro static struct hostent *sm_getipnodebyaddr __P((const void *, size_t, int, int *));
576f9c8e5bSGregory Neil Shapiro #else /* NETINET6 && NEEDSGETIPNODE */
586f9c8e5bSGregory Neil Shapiro #define sm_getipnodebyname getipnodebyname
596f9c8e5bSGregory Neil Shapiro #define sm_getipnodebyaddr getipnodebyaddr
60684b2a5fSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */
613299c2f1SGregory Neil Shapiro 
62c2aa98e2SPeter Wemm 
63c2aa98e2SPeter Wemm /*
64c2aa98e2SPeter Wemm **  CONF.C -- Sendmail Configuration Tables.
65c2aa98e2SPeter Wemm **
66c2aa98e2SPeter Wemm **	Defines the configuration of this installation.
67c2aa98e2SPeter Wemm **
68c2aa98e2SPeter Wemm **	Configuration Variables:
69c2aa98e2SPeter Wemm **		HdrInfo -- a table describing well-known header fields.
70c2aa98e2SPeter Wemm **			Each entry has the field name and some flags,
71c2aa98e2SPeter Wemm **			which are described in sendmail.h.
72c2aa98e2SPeter Wemm **
73c2aa98e2SPeter Wemm **	Notes:
74c2aa98e2SPeter Wemm **		I have tried to put almost all the reasonable
75c2aa98e2SPeter Wemm **		configuration information into the configuration
76c2aa98e2SPeter Wemm **		file read at runtime.  My intent is that anything
77c2aa98e2SPeter Wemm **		here is a function of the version of UNIX you
78c2aa98e2SPeter Wemm **		are running, or is really static -- for example
79c2aa98e2SPeter Wemm **		the headers are a superset of widely used
80c2aa98e2SPeter Wemm **		protocols.  If you find yourself playing with
81c2aa98e2SPeter Wemm **		this file too much, you may be making a mistake!
82c2aa98e2SPeter Wemm */
83c2aa98e2SPeter Wemm 
84c2aa98e2SPeter Wemm /*
85c2aa98e2SPeter Wemm **  Header info table
86c2aa98e2SPeter Wemm **	Final (null) entry contains the flags used for any other field.
87c2aa98e2SPeter Wemm **
88c2aa98e2SPeter Wemm **	Not all of these are actually handled specially by sendmail
89c2aa98e2SPeter Wemm **	at this time.  They are included as placeholders, to let
90c2aa98e2SPeter Wemm **	you know that "someday" I intend to have sendmail do
91c2aa98e2SPeter Wemm **	something with them.
92c2aa98e2SPeter Wemm */
93c2aa98e2SPeter Wemm 
942fb4f839SGregory Neil Shapiro #if _FFR_MTA_MODE
952fb4f839SGregory Neil Shapiro # define Xflags	H_ASIS
962fb4f839SGregory Neil Shapiro #else
972fb4f839SGregory Neil Shapiro # define Xflags 0
982fb4f839SGregory Neil Shapiro #endif
992fb4f839SGregory Neil Shapiro 
100c2aa98e2SPeter Wemm struct hdrinfo	HdrInfo[] =
101c2aa98e2SPeter Wemm {
102c2aa98e2SPeter Wemm 		/* originator fields, most to least significant */
1033299c2f1SGregory Neil Shapiro 	{ "resent-sender",		H_FROM|H_RESENT,	NULL	},
1043299c2f1SGregory Neil Shapiro 	{ "resent-from",		H_FROM|H_RESENT,	NULL	},
1053299c2f1SGregory Neil Shapiro 	{ "resent-reply-to",		H_FROM|H_RESENT,	NULL	},
1063299c2f1SGregory Neil Shapiro 	{ "sender",			H_FROM,			NULL	},
1072fb4f839SGregory Neil Shapiro 	{ "from",			H_FROM | Xflags,	NULL	},
1082fb4f839SGregory Neil Shapiro 	{ "reply-to",			H_FROM | Xflags,	NULL	},
1093299c2f1SGregory Neil Shapiro 	{ "errors-to",			H_FROM|H_ERRORSTO,	NULL	},
1103299c2f1SGregory Neil Shapiro 	{ "full-name",			H_ACHECK,		NULL	},
1113299c2f1SGregory Neil Shapiro 	{ "return-receipt-to",		H_RECEIPTTO,		NULL	},
112bfb62e91SGregory Neil Shapiro 	{ "delivery-receipt-to",	H_RECEIPTTO,		NULL	},
11312ed1c7cSGregory Neil Shapiro 	{ "disposition-notification-to",	H_FROM,		NULL	},
114c2aa98e2SPeter Wemm 
115c2aa98e2SPeter Wemm 		/* destination fields */
1162fb4f839SGregory Neil Shapiro 	{ "to",				H_RCPT | Xflags,	NULL	},
1173299c2f1SGregory Neil Shapiro 	{ "resent-to",			H_RCPT|H_RESENT,	NULL	},
1183299c2f1SGregory Neil Shapiro 	{ "cc",				H_RCPT,			NULL	},
1193299c2f1SGregory Neil Shapiro 	{ "resent-cc",			H_RCPT|H_RESENT,	NULL	},
1203299c2f1SGregory Neil Shapiro 	{ "bcc",			H_RCPT|H_BCC,		NULL	},
1213299c2f1SGregory Neil Shapiro 	{ "resent-bcc",			H_RCPT|H_BCC|H_RESENT,	NULL	},
1223299c2f1SGregory Neil Shapiro 	{ "apparently-to",		H_RCPT,			NULL	},
123c2aa98e2SPeter Wemm 
124c2aa98e2SPeter Wemm 		/* message identification and control */
1253299c2f1SGregory Neil Shapiro 	{ "message-id",			0,			NULL	},
1263299c2f1SGregory Neil Shapiro 	{ "resent-message-id",		H_RESENT,		NULL	},
1275b0945b5SGregory Neil Shapiro #if !NO_EOH_FIELDS
1283299c2f1SGregory Neil Shapiro 	{ "message",			H_EOH,			NULL	},
1293299c2f1SGregory Neil Shapiro 	{ "text",			H_EOH,			NULL	},
1305b0945b5SGregory Neil Shapiro #endif
131c2aa98e2SPeter Wemm 
132c2aa98e2SPeter Wemm 		/* date fields */
1333299c2f1SGregory Neil Shapiro 	{ "date",			0,			NULL	},
1343299c2f1SGregory Neil Shapiro 	{ "resent-date",		H_RESENT,		NULL	},
135c2aa98e2SPeter Wemm 
136c2aa98e2SPeter Wemm 		/* trace fields */
1373299c2f1SGregory Neil Shapiro 	{ "received",			H_TRACE|H_FORCE,	NULL	},
1383299c2f1SGregory Neil Shapiro 	{ "x400-received",		H_TRACE|H_FORCE,	NULL	},
1393299c2f1SGregory Neil Shapiro 	{ "via",			H_TRACE|H_FORCE,	NULL	},
1403299c2f1SGregory Neil Shapiro 	{ "mail-from",			H_TRACE|H_FORCE,	NULL	},
141c2aa98e2SPeter Wemm 
142c2aa98e2SPeter Wemm 		/* miscellaneous fields */
1433299c2f1SGregory Neil Shapiro 	{ "comments",			H_FORCE|H_ENCODABLE,	NULL	},
1443299c2f1SGregory Neil Shapiro 	{ "return-path",		H_FORCE|H_ACHECK|H_BINDLATE,	NULL	},
1453299c2f1SGregory Neil Shapiro 	{ "content-transfer-encoding",	H_CTE,			NULL	},
1463299c2f1SGregory Neil Shapiro 	{ "content-type",		H_CTYPE,		NULL	},
1473299c2f1SGregory Neil Shapiro 	{ "content-length",		H_ACHECK,		NULL	},
1483299c2f1SGregory Neil Shapiro 	{ "subject",			H_ENCODABLE,		NULL	},
1493299c2f1SGregory Neil Shapiro 	{ "x-authentication-warning",	H_FORCE,		NULL	},
150c2aa98e2SPeter Wemm 
1513299c2f1SGregory Neil Shapiro 	{ NULL,				0,			NULL	}
152c2aa98e2SPeter Wemm };
153c2aa98e2SPeter Wemm 
154c2aa98e2SPeter Wemm /*
155c2aa98e2SPeter Wemm **  Privacy values
156c2aa98e2SPeter Wemm */
157c2aa98e2SPeter Wemm 
158c2aa98e2SPeter Wemm struct prival PrivacyValues[] =
159c2aa98e2SPeter Wemm {
160c2aa98e2SPeter Wemm 	{ "public",		PRIV_PUBLIC		},
161c2aa98e2SPeter Wemm 	{ "needmailhelo",	PRIV_NEEDMAILHELO	},
162c2aa98e2SPeter Wemm 	{ "needexpnhelo",	PRIV_NEEDEXPNHELO	},
163c2aa98e2SPeter Wemm 	{ "needvrfyhelo",	PRIV_NEEDVRFYHELO	},
164c2aa98e2SPeter Wemm 	{ "noexpn",		PRIV_NOEXPN		},
165c2aa98e2SPeter Wemm 	{ "novrfy",		PRIV_NOVRFY		},
166*d39bd2c1SGregory Neil Shapiro 	{ "authwarnings",	PRIV_AUTHWARNINGS	},
167*d39bd2c1SGregory Neil Shapiro 	{ "noverb",		PRIV_NOVERB		},
168c2aa98e2SPeter Wemm 	{ "restrictmailq",	PRIV_RESTRICTMAILQ	},
169c2aa98e2SPeter Wemm 	{ "restrictqrun",	PRIV_RESTRICTQRUN	},
170*d39bd2c1SGregory Neil Shapiro 	{ "restrictexpand",	PRIV_RESTRICTEXPAND	},
171c2aa98e2SPeter Wemm 	{ "noetrn",		PRIV_NOETRN		},
1723299c2f1SGregory Neil Shapiro 	{ "nobodyreturn",	PRIV_NOBODYRETN		},
173*d39bd2c1SGregory Neil Shapiro 	{ "noreceipts",		PRIV_NORECEIPTS		},
174c2aa98e2SPeter Wemm 	{ "goaway",		PRIV_GOAWAY		},
175684b2a5fSGregory Neil Shapiro 	{ "noactualrecipient",	PRIV_NOACTUALRECIPIENT	},
1762fb4f839SGregory Neil Shapiro #if _FFR_NOREFLECT
1772fb4f839SGregory Neil Shapiro 	{ "noreflection",	PRIV_NOREFLECTION	},
1782fb4f839SGregory Neil Shapiro #endif
179c2aa98e2SPeter Wemm 	{ NULL,			0			}
180c2aa98e2SPeter Wemm };
181c2aa98e2SPeter Wemm 
182c2aa98e2SPeter Wemm /*
183c2aa98e2SPeter Wemm **  DontBlameSendmail values
184c2aa98e2SPeter Wemm */
18512ed1c7cSGregory Neil Shapiro 
186c2aa98e2SPeter Wemm struct dbsval DontBlameSendmailValues[] =
187c2aa98e2SPeter Wemm {
188c2aa98e2SPeter Wemm 	{ "safe",			DBS_SAFE			},
189c2aa98e2SPeter Wemm 	{ "assumesafechown",		DBS_ASSUMESAFECHOWN		},
190c2aa98e2SPeter Wemm 	{ "groupwritabledirpathsafe",	DBS_GROUPWRITABLEDIRPATHSAFE	},
191c2aa98e2SPeter Wemm 	{ "groupwritableforwardfilesafe",
192c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEFORWARDFILESAFE },
193c2aa98e2SPeter Wemm 	{ "groupwritableincludefilesafe",
194c2aa98e2SPeter Wemm 					DBS_GROUPWRITABLEINCLUDEFILESAFE },
195c2aa98e2SPeter Wemm 	{ "groupwritablealiasfile",	DBS_GROUPWRITABLEALIASFILE	},
196c2aa98e2SPeter Wemm 	{ "worldwritablealiasfile",	DBS_WORLDWRITABLEALIASFILE	},
197c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpath",	DBS_FORWARDFILEINUNSAFEDIRPATH	},
198c2aa98e2SPeter Wemm 	{ "mapinunsafedirpath",		DBS_MAPINUNSAFEDIRPATH	},
199c2aa98e2SPeter Wemm 	{ "linkedaliasfileinwritabledir",
200c2aa98e2SPeter Wemm 					DBS_LINKEDALIASFILEINWRITABLEDIR },
201c2aa98e2SPeter Wemm 	{ "linkedclassfileinwritabledir",
202c2aa98e2SPeter Wemm 					DBS_LINKEDCLASSFILEINWRITABLEDIR },
203c2aa98e2SPeter Wemm 	{ "linkedforwardfileinwritabledir",
204c2aa98e2SPeter Wemm 					DBS_LINKEDFORWARDFILEINWRITABLEDIR },
205c2aa98e2SPeter Wemm 	{ "linkedincludefileinwritabledir",
206c2aa98e2SPeter Wemm 					DBS_LINKEDINCLUDEFILEINWRITABLEDIR },
207c2aa98e2SPeter Wemm 	{ "linkedmapinwritabledir",	DBS_LINKEDMAPINWRITABLEDIR	},
208c2aa98e2SPeter Wemm 	{ "linkedserviceswitchfileinwritabledir",
209c2aa98e2SPeter Wemm 					DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR },
210c2aa98e2SPeter Wemm 	{ "filedeliverytohardlink",	DBS_FILEDELIVERYTOHARDLINK	},
211c2aa98e2SPeter Wemm 	{ "filedeliverytosymlink",	DBS_FILEDELIVERYTOSYMLINK	},
212c2aa98e2SPeter Wemm 	{ "writemaptohardlink",		DBS_WRITEMAPTOHARDLINK		},
213c2aa98e2SPeter Wemm 	{ "writemaptosymlink",		DBS_WRITEMAPTOSYMLINK		},
214c2aa98e2SPeter Wemm 	{ "writestatstohardlink",	DBS_WRITESTATSTOHARDLINK	},
215c2aa98e2SPeter Wemm 	{ "writestatstosymlink",	DBS_WRITESTATSTOSYMLINK		},
216c2aa98e2SPeter Wemm 	{ "forwardfileingroupwritabledirpath",
217c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINGROUPWRITABLEDIRPATH },
218c2aa98e2SPeter Wemm 	{ "includefileingroupwritabledirpath",
219c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH },
220c2aa98e2SPeter Wemm 	{ "classfileinunsafedirpath",	DBS_CLASSFILEINUNSAFEDIRPATH	},
221c2aa98e2SPeter Wemm 	{ "errorheaderinunsafedirpath",	DBS_ERRORHEADERINUNSAFEDIRPATH	},
222c2aa98e2SPeter Wemm 	{ "helpfileinunsafedirpath",	DBS_HELPFILEINUNSAFEDIRPATH	},
223c2aa98e2SPeter Wemm 	{ "forwardfileinunsafedirpathsafe",
224c2aa98e2SPeter Wemm 					DBS_FORWARDFILEINUNSAFEDIRPATHSAFE },
225c2aa98e2SPeter Wemm 	{ "includefileinunsafedirpathsafe",
226c2aa98e2SPeter Wemm 					DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
227c2aa98e2SPeter Wemm 	{ "runprograminunsafedirpath",	DBS_RUNPROGRAMINUNSAFEDIRPATH	},
228c2aa98e2SPeter Wemm 	{ "runwritableprogram",		DBS_RUNWRITABLEPROGRAM		},
229*d39bd2c1SGregory Neil Shapiro 	{ "includefileinunsafedirpath",	DBS_INCLUDEFILEINUNSAFEDIRPATH	},
2303299c2f1SGregory Neil Shapiro 	{ "nonrootsafeaddr",		DBS_NONROOTSAFEADDR		},
2313299c2f1SGregory Neil Shapiro 	{ "truststickybit",		DBS_TRUSTSTICKYBIT		},
2323299c2f1SGregory Neil Shapiro 	{ "dontwarnforwardfileinunsafedirpath",
2333299c2f1SGregory Neil Shapiro 					DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH },
2343299c2f1SGregory Neil Shapiro 	{ "insufficiententropy",	DBS_INSUFFICIENTENTROPY },
23512ed1c7cSGregory Neil Shapiro 	{ "groupreadablesasldbfile",	DBS_GROUPREADABLESASLDBFILE	},
23612ed1c7cSGregory Neil Shapiro 	{ "groupwritablesasldbfile",	DBS_GROUPWRITABLESASLDBFILE	},
237d995d2baSGregory Neil Shapiro 	{ "groupwritableforwardfile",	DBS_GROUPWRITABLEFORWARDFILE	},
238d995d2baSGregory Neil Shapiro 	{ "groupwritableincludefile",	DBS_GROUPWRITABLEINCLUDEFILE	},
239d995d2baSGregory Neil Shapiro 	{ "worldwritableforwardfile",	DBS_WORLDWRITABLEFORWARDFILE	},
240d995d2baSGregory Neil Shapiro 	{ "worldwritableincludefile",	DBS_WORLDWRITABLEINCLUDEFILE	},
24112ed1c7cSGregory Neil Shapiro 	{ "groupreadablekeyfile",	DBS_GROUPREADABLEKEYFILE	},
242da7d7b9cSGregory Neil Shapiro 	{ "groupreadabledefaultauthinfofile",
24312ed1c7cSGregory Neil Shapiro 					DBS_GROUPREADABLEAUTHINFOFILE	},
244*d39bd2c1SGregory Neil Shapiro 	{ "certowner",			DBS_CERTOWNER			},
245c2aa98e2SPeter Wemm 	{ NULL,				0				}
246c2aa98e2SPeter Wemm };
247c2aa98e2SPeter Wemm 
248c2aa98e2SPeter Wemm /*
249c2aa98e2SPeter Wemm **  Miscellaneous stuff.
250c2aa98e2SPeter Wemm */
251c2aa98e2SPeter Wemm 
252c2aa98e2SPeter Wemm int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
25312ed1c7cSGregory Neil Shapiro /*
254c2aa98e2SPeter Wemm **  SETDEFAULTS -- set default values
255c2aa98e2SPeter Wemm **
25612ed1c7cSGregory Neil Shapiro **	Some of these must be initialized using direct code since they
25712ed1c7cSGregory Neil Shapiro **	depend on run-time values. So let's do all of them this way.
258c2aa98e2SPeter Wemm **
259c2aa98e2SPeter Wemm **	Parameters:
260c2aa98e2SPeter Wemm **		e -- the default envelope.
261c2aa98e2SPeter Wemm **
262c2aa98e2SPeter Wemm **	Returns:
263c2aa98e2SPeter Wemm **		none.
264c2aa98e2SPeter Wemm **
265c2aa98e2SPeter Wemm **	Side Effects:
266c2aa98e2SPeter Wemm **		Initializes a bunch of global variables to their
267c2aa98e2SPeter Wemm **		default values.
268c2aa98e2SPeter Wemm */
269c2aa98e2SPeter Wemm 
270c2aa98e2SPeter Wemm #define MINUTES		* 60
271c2aa98e2SPeter Wemm #define HOURS		* 60 MINUTES
272c2aa98e2SPeter Wemm #define DAYS		* 24 HOURS
273c2aa98e2SPeter Wemm 
274c2aa98e2SPeter Wemm #ifndef MAXRULERECURSION
275c2aa98e2SPeter Wemm # define MAXRULERECURSION	50	/* max ruleset recursion depth */
2765b0945b5SGregory Neil Shapiro #endif
277c2aa98e2SPeter Wemm 
278c2aa98e2SPeter Wemm void
setdefaults(e)279c2aa98e2SPeter Wemm setdefaults(e)
280c2aa98e2SPeter Wemm 	register ENVELOPE *e;
281c2aa98e2SPeter Wemm {
282c2aa98e2SPeter Wemm 	int i;
2833299c2f1SGregory Neil Shapiro 	int numprocs;
284c2aa98e2SPeter Wemm 	struct passwd *pw;
285c2aa98e2SPeter Wemm 
2863299c2f1SGregory Neil Shapiro 	numprocs = get_num_procs_online();
287c2aa98e2SPeter Wemm 	SpaceSub = ' ';				/* option B */
2883299c2f1SGregory Neil Shapiro 	QueueLA = 8 * numprocs;			/* option x */
2893299c2f1SGregory Neil Shapiro 	RefuseLA = 12 * numprocs;		/* option X */
290c2aa98e2SPeter Wemm 	WkRecipFact = 30000L;			/* option y */
291c2aa98e2SPeter Wemm 	WkClassFact = 1800L;			/* option z */
292c2aa98e2SPeter Wemm 	WkTimeFact = 90000L;			/* option Z */
293c2aa98e2SPeter Wemm 	QueueFactor = WkRecipFact * 20;		/* option q */
29412ed1c7cSGregory Neil Shapiro 	QueueMode = QM_NORMAL;		/* what queue items to act upon */
295c2aa98e2SPeter Wemm 	FileMode = (RealUid != geteuid()) ? 0644 : 0600;
296c2aa98e2SPeter Wemm 						/* option F */
2973299c2f1SGregory Neil Shapiro 	QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600;
2983299c2f1SGregory Neil Shapiro 						/* option QueueFileMode */
299c2aa98e2SPeter Wemm 
3003299c2f1SGregory Neil Shapiro 	if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) ||
3013299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) ||
3023299c2f1SGregory Neil Shapiro 	    ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0))
303c2aa98e2SPeter Wemm 	{
304c2aa98e2SPeter Wemm 		DefUid = pw->pw_uid;		/* option u */
305c2aa98e2SPeter Wemm 		DefGid = pw->pw_gid;		/* option g */
306c2aa98e2SPeter Wemm 		DefUser = newstr(pw->pw_name);
307c2aa98e2SPeter Wemm 	}
308c2aa98e2SPeter Wemm 	else
309c2aa98e2SPeter Wemm 	{
310c2aa98e2SPeter Wemm 		DefUid = 1;			/* option u */
311c2aa98e2SPeter Wemm 		DefGid = 1;			/* option g */
312c2aa98e2SPeter Wemm 		setdefuser();
313c2aa98e2SPeter Wemm 	}
31476b7bf71SPeter Wemm 	TrustedUid = 0;
315c2aa98e2SPeter Wemm 	if (tTd(37, 4))
316da7d7b9cSGregory Neil Shapiro 		sm_dprintf("setdefaults: DefUser=%s, DefUid=%ld, DefGid=%ld\n",
317c2aa98e2SPeter Wemm 			DefUser != NULL ? DefUser : "<1:1>",
318da7d7b9cSGregory Neil Shapiro 			(long) DefUid, (long) DefGid);
319c2aa98e2SPeter Wemm 	CheckpointInterval = 10;		/* option C */
320c2aa98e2SPeter Wemm 	MaxHopCount = 25;			/* option h */
3213299c2f1SGregory Neil Shapiro 	set_delivery_mode(SM_FORK, e);		/* option d */
322c2aa98e2SPeter Wemm 	e->e_errormode = EM_PRINT;		/* option e */
32312ed1c7cSGregory Neil Shapiro 	e->e_qgrp = NOQGRP;
32412ed1c7cSGregory Neil Shapiro 	e->e_qdir = NOQDIR;
32512ed1c7cSGregory Neil Shapiro 	e->e_xfqgrp = NOQGRP;
32612ed1c7cSGregory Neil Shapiro 	e->e_xfqdir = NOQDIR;
3273299c2f1SGregory Neil Shapiro 	e->e_ctime = curtime();
3282fb4f839SGregory Neil Shapiro #if USE_EAI
3295b0945b5SGregory Neil Shapiro 	e->e_smtputf8 = false;
3305b0945b5SGregory Neil Shapiro #endif
33112ed1c7cSGregory Neil Shapiro 	SevenBitInput = false;			/* option 7 */
332c2aa98e2SPeter Wemm 	MaxMciCache = 1;			/* option k */
333c2aa98e2SPeter Wemm 	MciCacheTimeout = 5 MINUTES;		/* option K */
334c2aa98e2SPeter Wemm 	LogLevel = 9;				/* option L */
33512ed1c7cSGregory Neil Shapiro #if MILTER
33612ed1c7cSGregory Neil Shapiro 	MilterLogLevel = -1;
3375b0945b5SGregory Neil Shapiro #endif
33812ed1c7cSGregory Neil Shapiro 	inittimeouts(NULL, false);		/* option r */
339c2aa98e2SPeter Wemm 	PrivacyFlags = PRIV_PUBLIC;		/* option p */
34012ed1c7cSGregory Neil Shapiro 	MeToo = true;				/* option m */
34112ed1c7cSGregory Neil Shapiro 	SendMIMEErrors = true;			/* option f */
34212ed1c7cSGregory Neil Shapiro 	SuperSafe = SAFE_REALLY;		/* option s */
3433299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);		/* DontBlameSendmail option */
344c2aa98e2SPeter Wemm #if MIME8TO7
345c2aa98e2SPeter Wemm 	MimeMode = MM_CVTMIME|MM_PASS8BIT;	/* option 8 */
3465b0945b5SGregory Neil Shapiro #else
347c2aa98e2SPeter Wemm 	MimeMode = MM_PASS8BIT;
3485b0945b5SGregory Neil Shapiro #endif
349c2aa98e2SPeter Wemm 	for (i = 0; i < MAXTOCLASS; i++)
350c2aa98e2SPeter Wemm 	{
351c2aa98e2SPeter Wemm 		TimeOuts.to_q_return[i] = 5 DAYS;	/* option T */
352c2aa98e2SPeter Wemm 		TimeOuts.to_q_warning[i] = 0;		/* option T */
353c2aa98e2SPeter Wemm 	}
3543299c2f1SGregory Neil Shapiro 	ServiceSwitchFile = "/etc/mail/service.switch";
355c2aa98e2SPeter Wemm 	ServiceCacheMaxAge = (time_t) 10;
356c2aa98e2SPeter Wemm 	HostsFile = _PATH_HOSTS;
357c2aa98e2SPeter Wemm 	PidFile = newstr(_PATH_SENDMAILPID);
358c2aa98e2SPeter Wemm 	MustQuoteChars = "@,;:\\()[].'";
359c2aa98e2SPeter Wemm 	MciInfoTimeout = 30 MINUTES;
360c2aa98e2SPeter Wemm 	MaxRuleRecursion = MAXRULERECURSION;
361c2aa98e2SPeter Wemm 	MaxAliasRecursion = 10;
362c2aa98e2SPeter Wemm 	MaxMacroRecursion = 10;
36312ed1c7cSGregory Neil Shapiro 	ColonOkInAddr = true;
36412ed1c7cSGregory Neil Shapiro 	DontLockReadFiles = true;
36512ed1c7cSGregory Neil Shapiro 	DontProbeInterfaces = DPI_PROBEALL;
366c2aa98e2SPeter Wemm 	DoubleBounceAddr = "postmaster";
367e01d6f61SPeter Wemm 	MaxHeadersLength = MAXHDRSLEN;
36872936242SGregory Neil Shapiro 	MaxMimeHeaderLength = MAXLINE;
36972936242SGregory Neil Shapiro 	MaxMimeFieldLength = MaxMimeHeaderLength / 2;
3703299c2f1SGregory Neil Shapiro 	MaxForwardEntries = 0;
37112ed1c7cSGregory Neil Shapiro 	FastSplit = 1;
372567a2fc9SGregory Neil Shapiro 	MaxNOOPCommands = MAXNOOPCOMMANDS;
3733299c2f1SGregory Neil Shapiro #if SASL
3743299c2f1SGregory Neil Shapiro 	AuthMechanisms = newstr(AUTH_MECHANISMS);
375bfb62e91SGregory Neil Shapiro 	AuthRealm = NULL;
37612ed1c7cSGregory Neil Shapiro 	MaxSLBits = INT_MAX;
3775b0945b5SGregory Neil Shapiro #endif
37812ed1c7cSGregory Neil Shapiro #if STARTTLS
37912ed1c7cSGregory Neil Shapiro 	TLS_Srv_Opts = TLS_I_SRV;
380da7d7b9cSGregory Neil Shapiro 	if (NULL == EVP_digest)
381da7d7b9cSGregory Neil Shapiro 		EVP_digest = EVP_md5();
3825b0945b5SGregory Neil Shapiro # if _FFR_TLSFB2CLEAR
3835b0945b5SGregory Neil Shapiro 	TLSFallbacktoClear = true;
3845b0945b5SGregory Neil Shapiro # endif
38576d46bbbSHiroki Sato 	Srv_SSL_Options = SSL_OP_ALL;
38676d46bbbSHiroki Sato 	Clt_SSL_Options = SSL_OP_ALL
38776d46bbbSHiroki Sato # ifdef SSL_OP_NO_SSLv2
38876d46bbbSHiroki Sato 		| SSL_OP_NO_SSLv2
38976d46bbbSHiroki Sato # endif
39076d46bbbSHiroki Sato # ifdef SSL_OP_NO_TICKET
39176d46bbbSHiroki Sato 		| SSL_OP_NO_TICKET
39276d46bbbSHiroki Sato # endif
39376d46bbbSHiroki Sato 		;
39476d46bbbSHiroki Sato # ifdef SSL_OP_TLSEXT_PADDING
39576d46bbbSHiroki Sato 	/* SSL_OP_TLSEXT_PADDING breaks compatibility with some sites */
39676d46bbbSHiroki Sato 	Srv_SSL_Options &= ~SSL_OP_TLSEXT_PADDING;
39776d46bbbSHiroki Sato 	Clt_SSL_Options &= ~SSL_OP_TLSEXT_PADDING;
39876d46bbbSHiroki Sato # endif /* SSL_OP_TLSEXT_PADDING */
39912ed1c7cSGregory Neil Shapiro #endif /* STARTTLS */
400c2aa98e2SPeter Wemm #ifdef HESIOD_INIT
401c2aa98e2SPeter Wemm 	HesiodContext = NULL;
4025b0945b5SGregory Neil Shapiro #endif
4033299c2f1SGregory Neil Shapiro #if NETINET6
4043299c2f1SGregory Neil Shapiro 	/* Detect if IPv6 is available at run time */
4053299c2f1SGregory Neil Shapiro 	i = socket(AF_INET6, SOCK_STREAM, 0);
4063299c2f1SGregory Neil Shapiro 	if (i >= 0)
4073299c2f1SGregory Neil Shapiro 	{
4083299c2f1SGregory Neil Shapiro 		InetMode = AF_INET6;
4093299c2f1SGregory Neil Shapiro 		(void) close(i);
4103299c2f1SGregory Neil Shapiro 	}
4113299c2f1SGregory Neil Shapiro 	else
4123299c2f1SGregory Neil Shapiro 		InetMode = AF_INET;
413da7d7b9cSGregory Neil Shapiro # if !IPV6_FULL
414da7d7b9cSGregory Neil Shapiro 	UseCompressedIPv6Addresses = true;
415da7d7b9cSGregory Neil Shapiro # endif
4163299c2f1SGregory Neil Shapiro #else /* NETINET6 */
4173299c2f1SGregory Neil Shapiro 	InetMode = AF_INET;
4183299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
41976b7bf71SPeter Wemm 	ControlSocketName = NULL;
420951742c4SGregory Neil Shapiro 	memset(&ConnectOnlyTo, '\0', sizeof(ConnectOnlyTo));
4213299c2f1SGregory Neil Shapiro 	DataFileBufferSize = 4096;
4223299c2f1SGregory Neil Shapiro 	XscriptFileBufferSize = 4096;
4233299c2f1SGregory Neil Shapiro 	for (i = 0; i < MAXRWSETS; i++)
4243299c2f1SGregory Neil Shapiro 		RuleSetNames[i] = NULL;
42512ed1c7cSGregory Neil Shapiro #if MILTER
4263299c2f1SGregory Neil Shapiro 	InputFilters[0] = NULL;
4275b0945b5SGregory Neil Shapiro #endif
4282ef40764SGregory Neil Shapiro 	RejectLogInterval = 3 HOURS;
429bfb62e91SGregory Neil Shapiro #if REQUIRES_DIR_FSYNC
4302ef40764SGregory Neil Shapiro 	RequiresDirfsync = true;
4315b0945b5SGregory Neil Shapiro #endif
4329bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY
4339bd497b8SGregory Neil Shapiro 	BadRcptThrottleDelay = 1;
4345b0945b5SGregory Neil Shapiro #endif
435bfb62e91SGregory Neil Shapiro 	ConnectionRateWindowSize = 60;
436da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE
437da7d7b9cSGregory Neil Shapiro 	BounceQueue = NOQGRP;
4385b0945b5SGregory Neil Shapiro #endif
439c2aa98e2SPeter Wemm 	setupmaps();
44012ed1c7cSGregory Neil Shapiro 	setupqueues();
441c2aa98e2SPeter Wemm 	setupmailers();
442c2aa98e2SPeter Wemm 	setupheaders();
443c2aa98e2SPeter Wemm }
444c2aa98e2SPeter Wemm 
445c2aa98e2SPeter Wemm /*
446c2aa98e2SPeter Wemm **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
447c2aa98e2SPeter Wemm */
448c2aa98e2SPeter Wemm 
449c2aa98e2SPeter Wemm void
setdefuser()450c2aa98e2SPeter Wemm setdefuser()
451c2aa98e2SPeter Wemm {
452c2aa98e2SPeter Wemm 	struct passwd *defpwent;
453c2aa98e2SPeter Wemm 	static char defuserbuf[40];
454c2aa98e2SPeter Wemm 
455c2aa98e2SPeter Wemm 	DefUser = defuserbuf;
456c2aa98e2SPeter Wemm 	defpwent = sm_getpwuid(DefUid);
45712ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(defuserbuf,
45812ed1c7cSGregory Neil Shapiro 			  (defpwent == NULL || defpwent->pw_name == NULL)
45912ed1c7cSGregory Neil Shapiro 			   ? "nobody" : defpwent->pw_name,
460951742c4SGregory Neil Shapiro 			  sizeof(defuserbuf));
461c2aa98e2SPeter Wemm 	if (tTd(37, 4))
462da7d7b9cSGregory Neil Shapiro 		sm_dprintf("setdefuser: DefUid=%ld, DefUser=%s\n",
463da7d7b9cSGregory Neil Shapiro 			   (long) DefUid, DefUser);
464c2aa98e2SPeter Wemm }
46512ed1c7cSGregory Neil Shapiro /*
46612ed1c7cSGregory Neil Shapiro **  SETUPQUEUES -- initialize default queues
46712ed1c7cSGregory Neil Shapiro **
46812ed1c7cSGregory Neil Shapiro **	The mqueue QUEUE structure gets filled in after readcf() but
46912ed1c7cSGregory Neil Shapiro **	we need something to point to now for the mailer setup,
47012ed1c7cSGregory Neil Shapiro **	which use "mqueue" as default queue.
47112ed1c7cSGregory Neil Shapiro */
47212ed1c7cSGregory Neil Shapiro 
47312ed1c7cSGregory Neil Shapiro static void
setupqueues()47412ed1c7cSGregory Neil Shapiro setupqueues()
47512ed1c7cSGregory Neil Shapiro {
47612ed1c7cSGregory Neil Shapiro 	char buf[100];
47712ed1c7cSGregory Neil Shapiro 
47812ed1c7cSGregory Neil Shapiro 	MaxRunnersPerQueue = 1;
479951742c4SGregory Neil Shapiro 	(void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof(buf));
48012ed1c7cSGregory Neil Shapiro 	makequeue(buf, false);
48112ed1c7cSGregory Neil Shapiro }
48212ed1c7cSGregory Neil Shapiro /*
483c2aa98e2SPeter Wemm **  SETUPMAILERS -- initialize default mailers
484c2aa98e2SPeter Wemm */
485c2aa98e2SPeter Wemm 
4863299c2f1SGregory Neil Shapiro static void
setupmailers()487c2aa98e2SPeter Wemm setupmailers()
488c2aa98e2SPeter Wemm {
489c2aa98e2SPeter Wemm 	char buf[100];
490c2aa98e2SPeter Wemm 
49112ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u",
492951742c4SGregory Neil Shapiro 			sizeof(buf));
493c2aa98e2SPeter Wemm 	makemailer(buf);
494c2aa98e2SPeter Wemm 
49512ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u",
496951742c4SGregory Neil Shapiro 			sizeof(buf));
497c2aa98e2SPeter Wemm 	makemailer(buf);
498c2aa98e2SPeter Wemm 
49912ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u",
500951742c4SGregory Neil Shapiro 			sizeof(buf));
501c2aa98e2SPeter Wemm 	makemailer(buf);
5023299c2f1SGregory Neil Shapiro 	initerrmailers();
503c2aa98e2SPeter Wemm }
50412ed1c7cSGregory Neil Shapiro /*
505c2aa98e2SPeter Wemm **  SETUPMAPS -- set up map classes
506c2aa98e2SPeter Wemm */
507c2aa98e2SPeter Wemm 
508c2aa98e2SPeter Wemm #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
509c2aa98e2SPeter Wemm 	{ \
510c2aa98e2SPeter Wemm 		extern bool parse __P((MAP *, char *)); \
511c2aa98e2SPeter Wemm 		extern bool open __P((MAP *, int)); \
512c2aa98e2SPeter Wemm 		extern void close __P((MAP *)); \
513c2aa98e2SPeter Wemm 		extern char *lookup __P((MAP *, char *, char **, int *)); \
514c2aa98e2SPeter Wemm 		extern void store __P((MAP *, char *, char *)); \
515c2aa98e2SPeter Wemm 		s = stab(name, ST_MAPCLASS, ST_ENTER); \
516c2aa98e2SPeter Wemm 		s->s_mapclass.map_cname = name; \
517c2aa98e2SPeter Wemm 		s->s_mapclass.map_ext = ext; \
518c2aa98e2SPeter Wemm 		s->s_mapclass.map_cflags = flags; \
519c2aa98e2SPeter Wemm 		s->s_mapclass.map_parse = parse; \
520c2aa98e2SPeter Wemm 		s->s_mapclass.map_open = open; \
521c2aa98e2SPeter Wemm 		s->s_mapclass.map_close = close; \
522c2aa98e2SPeter Wemm 		s->s_mapclass.map_lookup = lookup; \
523c2aa98e2SPeter Wemm 		s->s_mapclass.map_store = store; \
524c2aa98e2SPeter Wemm 	}
525c2aa98e2SPeter Wemm 
5263299c2f1SGregory Neil Shapiro static void
setupmaps()527c2aa98e2SPeter Wemm setupmaps()
528c2aa98e2SPeter Wemm {
529c2aa98e2SPeter Wemm 	register STAB *s;
530c2aa98e2SPeter Wemm 
53112ed1c7cSGregory Neil Shapiro #if NEWDB
5327660b554SGregory Neil Shapiro # if DB_VERSION_MAJOR > 1
5337660b554SGregory Neil Shapiro 	int major_v, minor_v, patch_v;
5347660b554SGregory Neil Shapiro 
5357660b554SGregory Neil Shapiro 	(void) db_version(&major_v, &minor_v, &patch_v);
5367660b554SGregory Neil Shapiro 	if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR)
5377660b554SGregory Neil Shapiro 	{
5387660b554SGregory Neil Shapiro 		errno = 0;
5397660b554SGregory Neil Shapiro 		syserr("Berkeley DB version mismatch: compiled against %d.%d.%d, run-time linked against %d.%d.%d",
5407660b554SGregory Neil Shapiro 		  DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
5417660b554SGregory Neil Shapiro 		  major_v, minor_v, patch_v);
5427660b554SGregory Neil Shapiro 	}
5437660b554SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR > 1 */
5447660b554SGregory Neil Shapiro 
545c2aa98e2SPeter Wemm 	MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
546c2aa98e2SPeter Wemm 		map_parseargs, hash_map_open, db_map_close,
547c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
548c2aa98e2SPeter Wemm 
549c2aa98e2SPeter Wemm 	MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
550c2aa98e2SPeter Wemm 		map_parseargs, bt_map_open, db_map_close,
551c2aa98e2SPeter Wemm 		db_map_lookup, db_map_store);
5523299c2f1SGregory Neil Shapiro #endif /* NEWDB */
553c2aa98e2SPeter Wemm 
55412ed1c7cSGregory Neil Shapiro #if NDBM
555c2aa98e2SPeter Wemm 	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
556c2aa98e2SPeter Wemm 		map_parseargs, ndbm_map_open, ndbm_map_close,
557c2aa98e2SPeter Wemm 		ndbm_map_lookup, ndbm_map_store);
5585b0945b5SGregory Neil Shapiro #endif
5595b0945b5SGregory Neil Shapiro 
5605b0945b5SGregory Neil Shapiro #if CDB
5615b0945b5SGregory Neil Shapiro 	MAPDEF("cdb", CDBEXT, MCF_ALIASOK|MCF_REBUILDABLE,
5625b0945b5SGregory Neil Shapiro 		map_parseargs, cdb_map_open, cdb_map_close,
5635b0945b5SGregory Neil Shapiro 		cdb_map_lookup, cdb_map_store);
5645b0945b5SGregory Neil Shapiro #endif
565c2aa98e2SPeter Wemm 
56612ed1c7cSGregory Neil Shapiro #if NIS
567c2aa98e2SPeter Wemm 	MAPDEF("nis", NULL, MCF_ALIASOK,
568c2aa98e2SPeter Wemm 		map_parseargs, nis_map_open, null_map_close,
569c2aa98e2SPeter Wemm 		nis_map_lookup, null_map_store);
5705b0945b5SGregory Neil Shapiro #endif
571c2aa98e2SPeter Wemm 
57212ed1c7cSGregory Neil Shapiro #if NISPLUS
573c2aa98e2SPeter Wemm 	MAPDEF("nisplus", NULL, MCF_ALIASOK,
574c2aa98e2SPeter Wemm 		map_parseargs, nisplus_map_open, null_map_close,
575c2aa98e2SPeter Wemm 		nisplus_map_lookup, null_map_store);
5765b0945b5SGregory Neil Shapiro #endif
5773299c2f1SGregory Neil Shapiro 
57812ed1c7cSGregory Neil Shapiro #if LDAPMAP
57912ed1c7cSGregory Neil Shapiro 	MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST,
5803299c2f1SGregory Neil Shapiro 		ldapmap_parseargs, ldapmap_open, ldapmap_close,
5813299c2f1SGregory Neil Shapiro 		ldapmap_lookup, null_map_store);
5825b0945b5SGregory Neil Shapiro #endif
5833299c2f1SGregory Neil Shapiro 
58412ed1c7cSGregory Neil Shapiro #if PH_MAP
58512ed1c7cSGregory Neil Shapiro 	MAPDEF("ph", NULL, MCF_NOTPERSIST,
5863299c2f1SGregory Neil Shapiro 		ph_map_parseargs, ph_map_open, ph_map_close,
5873299c2f1SGregory Neil Shapiro 		ph_map_lookup, null_map_store);
5885b0945b5SGregory Neil Shapiro #endif
5893299c2f1SGregory Neil Shapiro 
5903299c2f1SGregory Neil Shapiro #if MAP_NSD
5913299c2f1SGregory Neil Shapiro 	/* IRIX 6.5 nsd support */
5923299c2f1SGregory Neil Shapiro 	MAPDEF("nsd", NULL, MCF_ALIASOK,
5933299c2f1SGregory Neil Shapiro 	       map_parseargs, null_map_open, null_map_close,
5943299c2f1SGregory Neil Shapiro 	       nsd_map_lookup, null_map_store);
5955b0945b5SGregory Neil Shapiro #endif
596c2aa98e2SPeter Wemm 
59712ed1c7cSGregory Neil Shapiro #if HESIOD
5985b0945b5SGregory Neil Shapiro 	MAPDEF("hesiod", NULL, MCF_ALIASOK,
59912ed1c7cSGregory Neil Shapiro 		map_parseargs, hes_map_open, hes_map_close,
600c2aa98e2SPeter Wemm 		hes_map_lookup, null_map_store);
6015b0945b5SGregory Neil Shapiro #endif
602c2aa98e2SPeter Wemm 
603c2aa98e2SPeter Wemm #if NETINFO
604c2aa98e2SPeter Wemm 	MAPDEF("netinfo", NULL, MCF_ALIASOK,
605c2aa98e2SPeter Wemm 		map_parseargs, ni_map_open, null_map_close,
606c2aa98e2SPeter Wemm 		ni_map_lookup, null_map_store);
6075b0945b5SGregory Neil Shapiro #endif
608c2aa98e2SPeter Wemm 
609c2aa98e2SPeter Wemm #if 0
610c2aa98e2SPeter Wemm 	MAPDEF("dns", NULL, 0,
611c2aa98e2SPeter Wemm 		dns_map_init, null_map_open, null_map_close,
612c2aa98e2SPeter Wemm 		dns_map_lookup, null_map_store);
6133299c2f1SGregory Neil Shapiro #endif /* 0 */
614c2aa98e2SPeter Wemm 
615c2aa98e2SPeter Wemm #if NAMED_BIND
61612ed1c7cSGregory Neil Shapiro # if DNSMAP
617320f00e7SGregory Neil Shapiro #  if _FFR_DNSMAP_ALIASABLE
618320f00e7SGregory Neil Shapiro 	MAPDEF("dns", NULL, MCF_ALIASOK,
619320f00e7SGregory Neil Shapiro 	       dns_map_parseargs, dns_map_open, null_map_close,
620320f00e7SGregory Neil Shapiro 	       dns_map_lookup, null_map_store);
621320f00e7SGregory Neil Shapiro #  else /* _FFR_DNSMAP_ALIASABLE */
62212ed1c7cSGregory Neil Shapiro 	MAPDEF("dns", NULL, 0,
62312ed1c7cSGregory Neil Shapiro 	       dns_map_parseargs, dns_map_open, null_map_close,
62412ed1c7cSGregory Neil Shapiro 	       dns_map_lookup, null_map_store);
625320f00e7SGregory Neil Shapiro #  endif /* _FFR_DNSMAP_ALIASABLE */
62612ed1c7cSGregory Neil Shapiro # endif /* DNSMAP */
62712ed1c7cSGregory Neil Shapiro #endif /* NAMED_BIND */
62812ed1c7cSGregory Neil Shapiro 
62912ed1c7cSGregory Neil Shapiro #if NAMED_BIND
630c2aa98e2SPeter Wemm 	/* best MX DNS lookup */
631c2aa98e2SPeter Wemm 	MAPDEF("bestmx", NULL, MCF_OPTFILE,
632c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
633c2aa98e2SPeter Wemm 		bestmx_map_lookup, null_map_store);
6345b0945b5SGregory Neil Shapiro #endif
635c2aa98e2SPeter Wemm 
636c2aa98e2SPeter Wemm 	MAPDEF("host", NULL, 0,
637c2aa98e2SPeter Wemm 		host_map_init, null_map_open, null_map_close,
638c2aa98e2SPeter Wemm 		host_map_lookup, null_map_store);
639c2aa98e2SPeter Wemm 
640c2aa98e2SPeter Wemm 	MAPDEF("text", NULL, MCF_ALIASOK,
641c2aa98e2SPeter Wemm 		map_parseargs, text_map_open, null_map_close,
642c2aa98e2SPeter Wemm 		text_map_lookup, null_map_store);
643c2aa98e2SPeter Wemm 
6445b0945b5SGregory Neil Shapiro 	MAPDEF("stab", NULL, MCF_ALIASOK,
645c2aa98e2SPeter Wemm 		map_parseargs, stab_map_open, null_map_close,
646c2aa98e2SPeter Wemm 		stab_map_lookup, stab_map_store);
647c2aa98e2SPeter Wemm 
6485b0945b5SGregory Neil Shapiro 	MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_REBUILDABLE,
649c2aa98e2SPeter Wemm 		map_parseargs, impl_map_open, impl_map_close,
650c2aa98e2SPeter Wemm 		impl_map_lookup, impl_map_store);
651c2aa98e2SPeter Wemm 
652c2aa98e2SPeter Wemm 	/* access to system passwd file */
653c2aa98e2SPeter Wemm 	MAPDEF("user", NULL, MCF_OPTFILE,
654c2aa98e2SPeter Wemm 		map_parseargs, user_map_open, null_map_close,
655c2aa98e2SPeter Wemm 		user_map_lookup, null_map_store);
656c2aa98e2SPeter Wemm 
657c2aa98e2SPeter Wemm 	/* dequote map */
658c2aa98e2SPeter Wemm 	MAPDEF("dequote", NULL, 0,
659c2aa98e2SPeter Wemm 		dequote_init, null_map_open, null_map_close,
660c2aa98e2SPeter Wemm 		dequote_map, null_map_store);
661c2aa98e2SPeter Wemm 
66212ed1c7cSGregory Neil Shapiro #if MAP_REGEX
663c2aa98e2SPeter Wemm 	MAPDEF("regex", NULL, 0,
664c2aa98e2SPeter Wemm 		regex_map_init, null_map_open, null_map_close,
665c2aa98e2SPeter Wemm 		regex_map_lookup, null_map_store);
6665b0945b5SGregory Neil Shapiro #endif
667c2aa98e2SPeter Wemm 
668c2aa98e2SPeter Wemm #if USERDB
669c2aa98e2SPeter Wemm 	/* user database */
670c2aa98e2SPeter Wemm 	MAPDEF("userdb", ".db", 0,
671c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
672c2aa98e2SPeter Wemm 		udb_map_lookup, null_map_store);
6735b0945b5SGregory Neil Shapiro #endif
674c2aa98e2SPeter Wemm 
675c2aa98e2SPeter Wemm 	/* arbitrary programs */
676c2aa98e2SPeter Wemm 	MAPDEF("program", NULL, MCF_ALIASOK,
677c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
678c2aa98e2SPeter Wemm 		prog_map_lookup, null_map_store);
679c2aa98e2SPeter Wemm 
680c2aa98e2SPeter Wemm 	/* sequenced maps */
681c2aa98e2SPeter Wemm 	MAPDEF("sequence", NULL, MCF_ALIASOK,
682c2aa98e2SPeter Wemm 		seq_map_parse, null_map_open, null_map_close,
683c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
684c2aa98e2SPeter Wemm 
685c2aa98e2SPeter Wemm 	/* switched interface to sequenced maps */
686c2aa98e2SPeter Wemm 	MAPDEF("switch", NULL, MCF_ALIASOK,
687c2aa98e2SPeter Wemm 		map_parseargs, switch_map_open, null_map_close,
688c2aa98e2SPeter Wemm 		seq_map_lookup, seq_map_store);
689c2aa98e2SPeter Wemm 
690c2aa98e2SPeter Wemm 	/* null map lookup -- really for internal use only */
691c2aa98e2SPeter Wemm 	MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
692c2aa98e2SPeter Wemm 		map_parseargs, null_map_open, null_map_close,
693c2aa98e2SPeter Wemm 		null_map_lookup, null_map_store);
694c2aa98e2SPeter Wemm 
695c2aa98e2SPeter Wemm 	/* syslog map -- logs information to syslog */
696c2aa98e2SPeter Wemm 	MAPDEF("syslog", NULL, 0,
697c2aa98e2SPeter Wemm 		syslog_map_parseargs, null_map_open, null_map_close,
698c2aa98e2SPeter Wemm 		syslog_map_lookup, null_map_store);
6993299c2f1SGregory Neil Shapiro 
7003299c2f1SGregory Neil Shapiro 	/* macro storage map -- rulesets can set macros */
7013299c2f1SGregory Neil Shapiro 	MAPDEF("macro", NULL, 0,
7023299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
7033299c2f1SGregory Neil Shapiro 		macro_map_lookup, null_map_store);
7043299c2f1SGregory Neil Shapiro 
7053299c2f1SGregory Neil Shapiro 	/* arithmetic map -- add/subtract/compare */
7063299c2f1SGregory Neil Shapiro 	MAPDEF("arith", NULL, 0,
7073299c2f1SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
7083299c2f1SGregory Neil Shapiro 		arith_map_lookup, null_map_store);
7093299c2f1SGregory Neil Shapiro 
7105dd76dd0SGregory Neil Shapiro 	/* "arpa" map -- IP -> arpa */
7115dd76dd0SGregory Neil Shapiro 	MAPDEF("arpa", NULL, 0,
7125dd76dd0SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
7135dd76dd0SGregory Neil Shapiro 		arpa_map_lookup, null_map_store);
7145dd76dd0SGregory Neil Shapiro 
715bfb62e91SGregory Neil Shapiro #if SOCKETMAP
716bfb62e91SGregory Neil Shapiro 	/* arbitrary daemons */
717bfb62e91SGregory Neil Shapiro 	MAPDEF("socket", NULL, MCF_ALIASOK,
718bfb62e91SGregory Neil Shapiro 		map_parseargs, socket_map_open, socket_map_close,
719bfb62e91SGregory Neil Shapiro 		socket_map_lookup, null_map_store);
7205b0945b5SGregory Neil Shapiro #endif
721bfb62e91SGregory Neil Shapiro 
722951742c4SGregory Neil Shapiro #if _FFR_DPRINTF_MAP
723951742c4SGregory Neil Shapiro 	/* dprintf map -- logs information to syslog */
724951742c4SGregory Neil Shapiro 	MAPDEF("dprintf", NULL, 0,
725951742c4SGregory Neil Shapiro 		dprintf_map_parseargs, null_map_open, null_map_close,
726951742c4SGregory Neil Shapiro 		dprintf_map_lookup, null_map_store);
7275b0945b5SGregory Neil Shapiro #endif
7285b0945b5SGregory Neil Shapiro 
7295b0945b5SGregory Neil Shapiro #if _FFR_SETDEBUG_MAP
7305b0945b5SGregory Neil Shapiro 	/* setdebug map -- set debug levels */
7315b0945b5SGregory Neil Shapiro 	MAPDEF("setdebug", NULL, 0,
7325b0945b5SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
7335b0945b5SGregory Neil Shapiro 		setdebug_map_lookup, null_map_store);
7345b0945b5SGregory Neil Shapiro #endif
7355b0945b5SGregory Neil Shapiro 
7365b0945b5SGregory Neil Shapiro #if _FFR_SETOPT_MAP
7375b0945b5SGregory Neil Shapiro 	/* setopt map -- set option */
7385b0945b5SGregory Neil Shapiro 	MAPDEF("setopt", NULL, 0,
7395b0945b5SGregory Neil Shapiro 		dequote_init, null_map_open, null_map_close,
7405b0945b5SGregory Neil Shapiro 		setopt_map_lookup, null_map_store);
7415b0945b5SGregory Neil Shapiro #endif
742951742c4SGregory Neil Shapiro 
7433299c2f1SGregory Neil Shapiro 	if (tTd(38, 2))
7443299c2f1SGregory Neil Shapiro 	{
7453299c2f1SGregory Neil Shapiro 		/* bogus map -- always return tempfail */
7463299c2f1SGregory Neil Shapiro 		MAPDEF("bogus",	NULL, MCF_ALIASOK|MCF_OPTFILE,
7473299c2f1SGregory Neil Shapiro 		       map_parseargs, null_map_open, null_map_close,
7483299c2f1SGregory Neil Shapiro 		       bogus_map_lookup, null_map_store);
7493299c2f1SGregory Neil Shapiro 	}
750c2aa98e2SPeter Wemm }
751c2aa98e2SPeter Wemm 
752c2aa98e2SPeter Wemm #undef MAPDEF
75312ed1c7cSGregory Neil Shapiro /*
754c2aa98e2SPeter Wemm **  INITHOSTMAPS -- initial host-dependent maps
755c2aa98e2SPeter Wemm **
756c2aa98e2SPeter Wemm **	This should act as an interface to any local service switch
757c2aa98e2SPeter Wemm **	provided by the host operating system.
758c2aa98e2SPeter Wemm **
759c2aa98e2SPeter Wemm **	Parameters:
760c2aa98e2SPeter Wemm **		none
761c2aa98e2SPeter Wemm **
762c2aa98e2SPeter Wemm **	Returns:
763c2aa98e2SPeter Wemm **		none
764c2aa98e2SPeter Wemm **
765c2aa98e2SPeter Wemm **	Side Effects:
766c2aa98e2SPeter Wemm **		Should define maps "host" and "users" as necessary
767c2aa98e2SPeter Wemm **		for this OS.  If they are not defined, they will get
768c2aa98e2SPeter Wemm **		a default value later.  It should check to make sure
769c2aa98e2SPeter Wemm **		they are not defined first, since it's possible that
770c2aa98e2SPeter Wemm **		the config file has provided an override.
771c2aa98e2SPeter Wemm */
772c2aa98e2SPeter Wemm 
773c2aa98e2SPeter Wemm void
inithostmaps()774c2aa98e2SPeter Wemm inithostmaps()
775c2aa98e2SPeter Wemm {
776c2aa98e2SPeter Wemm 	register int i;
777c2aa98e2SPeter Wemm 	int nmaps;
778c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
779c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
780c2aa98e2SPeter Wemm 	char buf[MAXLINE];
781c2aa98e2SPeter Wemm 
782c2aa98e2SPeter Wemm 	/*
783c2aa98e2SPeter Wemm 	**  Make sure we have a host map.
784c2aa98e2SPeter Wemm 	*/
785c2aa98e2SPeter Wemm 
786c2aa98e2SPeter Wemm 	if (stab("host", ST_MAP, ST_FIND) == NULL)
787c2aa98e2SPeter Wemm 	{
788c2aa98e2SPeter Wemm 		/* user didn't initialize: set up host map */
789951742c4SGregory Neil Shapiro 		(void) sm_strlcpy(buf, "host host", sizeof(buf));
790c2aa98e2SPeter Wemm #if NAMED_BIND
791c2aa98e2SPeter Wemm 		if (ConfigLevel >= 2)
792951742c4SGregory Neil Shapiro 			(void) sm_strlcat(buf, " -a. -D", sizeof(buf));
7935b0945b5SGregory Neil Shapiro #endif
794c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
795c2aa98e2SPeter Wemm 	}
796c2aa98e2SPeter Wemm 
797c2aa98e2SPeter Wemm 	/*
798c2aa98e2SPeter Wemm 	**  Set up default aliases maps
799c2aa98e2SPeter Wemm 	*/
800c2aa98e2SPeter Wemm 
801c2aa98e2SPeter Wemm 	nmaps = switch_map_find("aliases", maptype, mapreturn);
802c2aa98e2SPeter Wemm 	for (i = 0; i < nmaps; i++)
803c2aa98e2SPeter Wemm 	{
804c2aa98e2SPeter Wemm 		if (strcmp(maptype[i], "files") == 0 &&
805c2aa98e2SPeter Wemm 		    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
806c2aa98e2SPeter Wemm 		{
80712ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.files null",
808951742c4SGregory Neil Shapiro 					  sizeof(buf));
809c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
810c2aa98e2SPeter Wemm 		}
8115b0945b5SGregory Neil Shapiro #if CDB
8125b0945b5SGregory Neil Shapiro 		else if (strcmp(maptype[i], "cdb") == 0 &&
8135b0945b5SGregory Neil Shapiro 			 stab("aliases.cdb", ST_MAP, ST_FIND) == NULL)
8145b0945b5SGregory Neil Shapiro 		{
8155b0945b5SGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.cdb null", sizeof(buf));
8165b0945b5SGregory Neil Shapiro 			(void) makemapentry(buf);
8175b0945b5SGregory Neil Shapiro 		}
8185b0945b5SGregory Neil Shapiro #endif /* CDB */
81912ed1c7cSGregory Neil Shapiro #if NISPLUS
820c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nisplus") == 0 &&
821c2aa98e2SPeter Wemm 			 stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
822c2aa98e2SPeter Wemm 		{
82312ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
824951742c4SGregory Neil Shapiro 				sizeof(buf));
825c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
826c2aa98e2SPeter Wemm 		}
8273299c2f1SGregory Neil Shapiro #endif /* NISPLUS */
82812ed1c7cSGregory Neil Shapiro #if NIS
829c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "nis") == 0 &&
830c2aa98e2SPeter Wemm 			 stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
831c2aa98e2SPeter Wemm 		{
83212ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.nis nis mail.aliases",
833951742c4SGregory Neil Shapiro 				sizeof(buf));
834c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
835c2aa98e2SPeter Wemm 		}
8363299c2f1SGregory Neil Shapiro #endif /* NIS */
8373299c2f1SGregory Neil Shapiro #if NETINFO
838c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "netinfo") == 0 &&
839c2aa98e2SPeter Wemm 			 stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
840c2aa98e2SPeter Wemm 		{
84112ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
842951742c4SGregory Neil Shapiro 				sizeof(buf));
843c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
844c2aa98e2SPeter Wemm 		}
8453299c2f1SGregory Neil Shapiro #endif /* NETINFO */
84612ed1c7cSGregory Neil Shapiro #if HESIOD
847c2aa98e2SPeter Wemm 		else if (strcmp(maptype[i], "hesiod") == 0 &&
848c2aa98e2SPeter Wemm 			 stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
849c2aa98e2SPeter Wemm 		{
85012ed1c7cSGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases",
851951742c4SGregory Neil Shapiro 				sizeof(buf));
852c2aa98e2SPeter Wemm 			(void) makemapentry(buf);
853c2aa98e2SPeter Wemm 		}
8543299c2f1SGregory Neil Shapiro #endif /* HESIOD */
855951742c4SGregory Neil Shapiro #if LDAPMAP && defined(SUN_EXTENSIONS) && \
856951742c4SGregory Neil Shapiro     defined(SUN_SIMPLIFIED_LDAP) && HASLDAPGETALIASBYNAME
857951742c4SGregory Neil Shapiro 		else if (strcmp(maptype[i], "ldap") == 0 &&
858951742c4SGregory Neil Shapiro 		    stab("aliases.ldap", ST_MAP, ST_FIND) == NULL)
859951742c4SGregory Neil Shapiro 		{
8609bd497b8SGregory Neil Shapiro 			(void) sm_strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup",
861951742c4SGregory Neil Shapiro 				sizeof buf);
862951742c4SGregory Neil Shapiro 			(void) makemapentry(buf);
863951742c4SGregory Neil Shapiro 		}
864951742c4SGregory Neil Shapiro #endif /* LDAPMAP && defined(SUN_EXTENSIONS) && ... */
865c2aa98e2SPeter Wemm 	}
866c2aa98e2SPeter Wemm 	if (stab("aliases", ST_MAP, ST_FIND) == NULL)
867c2aa98e2SPeter Wemm 	{
868951742c4SGregory Neil Shapiro 		(void) sm_strlcpy(buf, "aliases switch aliases", sizeof(buf));
869c2aa98e2SPeter Wemm 		(void) makemapentry(buf);
870c2aa98e2SPeter Wemm 	}
871951742c4SGregory Neil Shapiro }
872c2aa98e2SPeter Wemm 
87312ed1c7cSGregory Neil Shapiro /*
874c2aa98e2SPeter Wemm **  SWITCH_MAP_FIND -- find the list of types associated with a map
875c2aa98e2SPeter Wemm **
876c2aa98e2SPeter Wemm **	This is the system-dependent interface to the service switch.
877c2aa98e2SPeter Wemm **
878c2aa98e2SPeter Wemm **	Parameters:
879c2aa98e2SPeter Wemm **		service -- the name of the service of interest.
880c2aa98e2SPeter Wemm **		maptype -- an out-array of strings containing the types
881c2aa98e2SPeter Wemm **			of access to use for this service.  There can
882c2aa98e2SPeter Wemm **			be at most MAXMAPSTACK types for a single service.
883c2aa98e2SPeter Wemm **		mapreturn -- an out-array of return information bitmaps
884c2aa98e2SPeter Wemm **			for the map.
885c2aa98e2SPeter Wemm **
886c2aa98e2SPeter Wemm **	Returns:
887c2aa98e2SPeter Wemm **		The number of map types filled in, or -1 for failure.
8883299c2f1SGregory Neil Shapiro **
8893299c2f1SGregory Neil Shapiro **	Side effects:
8903299c2f1SGregory Neil Shapiro **		Preserves errno so nothing in the routine clobbers it.
891c2aa98e2SPeter Wemm */
892c2aa98e2SPeter Wemm 
893c2aa98e2SPeter Wemm #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
894c2aa98e2SPeter Wemm # define _USE_SUN_NSSWITCH_
8955b0945b5SGregory Neil Shapiro #endif
896c2aa98e2SPeter Wemm 
89712ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
89812ed1c7cSGregory Neil Shapiro # ifdef __hpux
89912ed1c7cSGregory Neil Shapiro #  define _USE_SUN_NSSWITCH_
9005b0945b5SGregory Neil Shapiro # endif
90112ed1c7cSGregory Neil Shapiro #endif /* _FFR_HPUX_NSSWITCH */
90212ed1c7cSGregory Neil Shapiro 
903c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
904c2aa98e2SPeter Wemm # include <nsswitch.h>
9055b0945b5SGregory Neil Shapiro #endif
906c2aa98e2SPeter Wemm 
907c2aa98e2SPeter Wemm #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
908c2aa98e2SPeter Wemm # define _USE_DEC_SVC_CONF_
9095b0945b5SGregory Neil Shapiro #endif
910c2aa98e2SPeter Wemm 
911c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
912c2aa98e2SPeter Wemm # include <sys/svcinfo.h>
9135b0945b5SGregory Neil Shapiro #endif
914c2aa98e2SPeter Wemm 
915c2aa98e2SPeter Wemm int
switch_map_find(service,maptype,mapreturn)916c2aa98e2SPeter Wemm switch_map_find(service, maptype, mapreturn)
917c2aa98e2SPeter Wemm 	char *service;
918c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
919c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
920c2aa98e2SPeter Wemm {
921c46d91b7SGregory Neil Shapiro 	int svcno = 0;
9223299c2f1SGregory Neil Shapiro 	int save_errno = errno;
923c2aa98e2SPeter Wemm 
924c2aa98e2SPeter Wemm #ifdef _USE_SUN_NSSWITCH_
925c2aa98e2SPeter Wemm 	struct __nsw_switchconfig *nsw_conf;
926c2aa98e2SPeter Wemm 	enum __nsw_parse_err pserr;
927c2aa98e2SPeter Wemm 	struct __nsw_lookup *lk;
928c2aa98e2SPeter Wemm 	static struct __nsw_lookup lkp0 =
929c2aa98e2SPeter Wemm 		{ "files", {1, 0, 0, 0}, NULL, NULL };
930c2aa98e2SPeter Wemm 	static struct __nsw_switchconfig lkp_default =
931c2aa98e2SPeter Wemm 		{ 0, "sendmail", 3, &lkp0 };
932c2aa98e2SPeter Wemm 
933c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
934c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
935c2aa98e2SPeter Wemm 
936c2aa98e2SPeter Wemm 	if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
937c2aa98e2SPeter Wemm 		lk = lkp_default.lookups;
938c2aa98e2SPeter Wemm 	else
939c2aa98e2SPeter Wemm 		lk = nsw_conf->lookups;
940c2aa98e2SPeter Wemm 	svcno = 0;
941c46d91b7SGregory Neil Shapiro 	while (lk != NULL && svcno < MAXMAPSTACK)
942c2aa98e2SPeter Wemm 	{
943c2aa98e2SPeter Wemm 		maptype[svcno] = lk->service_name;
944c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
945c2aa98e2SPeter Wemm 			mapreturn[MA_NOTFOUND] |= 1 << svcno;
946c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
947c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
948c2aa98e2SPeter Wemm 		if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
949c2aa98e2SPeter Wemm 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
950c2aa98e2SPeter Wemm 		svcno++;
951c2aa98e2SPeter Wemm 		lk = lk->next;
952c2aa98e2SPeter Wemm 	}
9533299c2f1SGregory Neil Shapiro 	errno = save_errno;
954c2aa98e2SPeter Wemm 	return svcno;
9553299c2f1SGregory Neil Shapiro #endif /* _USE_SUN_NSSWITCH_ */
956c2aa98e2SPeter Wemm 
957c2aa98e2SPeter Wemm #ifdef _USE_DEC_SVC_CONF_
958c2aa98e2SPeter Wemm 	struct svcinfo *svcinfo;
959c2aa98e2SPeter Wemm 	int svc;
960c2aa98e2SPeter Wemm 
961c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
962c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
963c2aa98e2SPeter Wemm 
964c2aa98e2SPeter Wemm 	svcinfo = getsvc();
965c2aa98e2SPeter Wemm 	if (svcinfo == NULL)
966c2aa98e2SPeter Wemm 		goto punt;
967c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
968c2aa98e2SPeter Wemm 		svc = SVC_HOSTS;
969c2aa98e2SPeter Wemm 	else if (strcmp(service, "aliases") == 0)
970c2aa98e2SPeter Wemm 		svc = SVC_ALIASES;
971c2aa98e2SPeter Wemm 	else if (strcmp(service, "passwd") == 0)
972c2aa98e2SPeter Wemm 		svc = SVC_PASSWD;
973c2aa98e2SPeter Wemm 	else
9743299c2f1SGregory Neil Shapiro 	{
9753299c2f1SGregory Neil Shapiro 		errno = save_errno;
976c2aa98e2SPeter Wemm 		return -1;
9773299c2f1SGregory Neil Shapiro 	}
978c46d91b7SGregory Neil Shapiro 	for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++)
979c2aa98e2SPeter Wemm 	{
980c2aa98e2SPeter Wemm 		switch (svcinfo->svcpath[svc][svcno])
981c2aa98e2SPeter Wemm 		{
982c2aa98e2SPeter Wemm 		  case SVC_LOCAL:
983c2aa98e2SPeter Wemm 			maptype[svcno] = "files";
984c2aa98e2SPeter Wemm 			break;
985c2aa98e2SPeter Wemm 
986c2aa98e2SPeter Wemm 		  case SVC_YP:
987c2aa98e2SPeter Wemm 			maptype[svcno] = "nis";
988c2aa98e2SPeter Wemm 			break;
989c2aa98e2SPeter Wemm 
990c2aa98e2SPeter Wemm 		  case SVC_BIND:
991c2aa98e2SPeter Wemm 			maptype[svcno] = "dns";
992c2aa98e2SPeter Wemm 			break;
993c2aa98e2SPeter Wemm 
994c2aa98e2SPeter Wemm # ifdef SVC_HESIOD
995c2aa98e2SPeter Wemm 		  case SVC_HESIOD:
996c2aa98e2SPeter Wemm 			maptype[svcno] = "hesiod";
997c2aa98e2SPeter Wemm 			break;
9985b0945b5SGregory Neil Shapiro # endif
999c2aa98e2SPeter Wemm 
1000c2aa98e2SPeter Wemm 		  case SVC_LAST:
10013299c2f1SGregory Neil Shapiro 			errno = save_errno;
1002c2aa98e2SPeter Wemm 			return svcno;
1003c2aa98e2SPeter Wemm 		}
1004c2aa98e2SPeter Wemm 	}
10053299c2f1SGregory Neil Shapiro 	errno = save_errno;
1006c2aa98e2SPeter Wemm 	return svcno;
10073299c2f1SGregory Neil Shapiro #endif /* _USE_DEC_SVC_CONF_ */
1008c2aa98e2SPeter Wemm 
1009c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
1010c2aa98e2SPeter Wemm 	/*
1011c2aa98e2SPeter Wemm 	**  Fall-back mechanism.
1012c2aa98e2SPeter Wemm 	*/
1013c2aa98e2SPeter Wemm 
1014c2aa98e2SPeter Wemm 	STAB *st;
101512ed1c7cSGregory Neil Shapiro 	static time_t servicecachetime;	/* time service switch was cached */
1016c2aa98e2SPeter Wemm 	time_t now = curtime();
1017c2aa98e2SPeter Wemm 
1018c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1019c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1020c2aa98e2SPeter Wemm 
102112ed1c7cSGregory Neil Shapiro 	if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge)
1022c2aa98e2SPeter Wemm 	{
1023c2aa98e2SPeter Wemm 		/* (re)read service switch */
102412ed1c7cSGregory Neil Shapiro 		register SM_FILE_T *fp;
10253299c2f1SGregory Neil Shapiro 		long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
1026c2aa98e2SPeter Wemm 
10273299c2f1SGregory Neil Shapiro 		if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
10283299c2f1SGregory Neil Shapiro 			    DontBlameSendmail))
1029c2aa98e2SPeter Wemm 			sff |= SFF_NOWLINK;
1030c2aa98e2SPeter Wemm 
1031c2aa98e2SPeter Wemm 		if (ConfigFileRead)
103212ed1c7cSGregory Neil Shapiro 			servicecachetime = now;
1033c2aa98e2SPeter Wemm 		fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
1034c2aa98e2SPeter Wemm 		if (fp != NULL)
1035c2aa98e2SPeter Wemm 		{
1036c2aa98e2SPeter Wemm 			char buf[MAXLINE];
1037c2aa98e2SPeter Wemm 
103812ed1c7cSGregory Neil Shapiro 			while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf,
1039552d4955SGregory Neil Shapiro 					   sizeof(buf)) >= 0)
1040c2aa98e2SPeter Wemm 			{
1041c2aa98e2SPeter Wemm 				register char *p;
1042c2aa98e2SPeter Wemm 
1043c2aa98e2SPeter Wemm 				p = strpbrk(buf, "#\n");
1044c2aa98e2SPeter Wemm 				if (p != NULL)
1045c2aa98e2SPeter Wemm 					*p = '\0';
10469bd497b8SGregory Neil Shapiro # ifndef SM_NSSWITCH_DELIMS
10479bd497b8SGregory Neil Shapiro #  define SM_NSSWITCH_DELIMS	" \t"
10485b0945b5SGregory Neil Shapiro # endif
10499bd497b8SGregory Neil Shapiro 				p = strpbrk(buf, SM_NSSWITCH_DELIMS);
1050c2aa98e2SPeter Wemm 				if (p != NULL)
1051c2aa98e2SPeter Wemm 					*p++ = '\0';
1052c2aa98e2SPeter Wemm 				if (buf[0] == '\0')
1053c2aa98e2SPeter Wemm 					continue;
105476b7bf71SPeter Wemm 				if (p == NULL)
105576b7bf71SPeter Wemm 				{
105676b7bf71SPeter Wemm 					sm_syslog(LOG_ERR, NOQID,
105776b7bf71SPeter Wemm 						  "Bad line on %.100s: %.100s",
105876b7bf71SPeter Wemm 						  ServiceSwitchFile,
105976b7bf71SPeter Wemm 						  buf);
106076b7bf71SPeter Wemm 					continue;
106176b7bf71SPeter Wemm 				}
10625b0945b5SGregory Neil Shapiro 				while (SM_ISSPACE(*p))
1063c2aa98e2SPeter Wemm 					p++;
1064c2aa98e2SPeter Wemm 				if (*p == '\0')
1065c2aa98e2SPeter Wemm 					continue;
1066c2aa98e2SPeter Wemm 
1067c2aa98e2SPeter Wemm 				/*
1068c2aa98e2SPeter Wemm 				**  Find/allocate space for this service entry.
1069c2aa98e2SPeter Wemm 				**	Space for all of the service strings
1070c2aa98e2SPeter Wemm 				**	are allocated at once.  This means
1071c2aa98e2SPeter Wemm 				**	that we only have to free the first
1072c2aa98e2SPeter Wemm 				**	one to free all of them.
1073c2aa98e2SPeter Wemm 				*/
1074c2aa98e2SPeter Wemm 
1075c2aa98e2SPeter Wemm 				st = stab(buf, ST_SERVICE, ST_ENTER);
1076c2aa98e2SPeter Wemm 				if (st->s_service[0] != NULL)
107712ed1c7cSGregory Neil Shapiro 					sm_free((void *) st->s_service[0]); /* XXX */
1078c2aa98e2SPeter Wemm 				p = newstr(p);
1079c2aa98e2SPeter Wemm 				for (svcno = 0; svcno < MAXMAPSTACK; )
1080c2aa98e2SPeter Wemm 				{
1081c2aa98e2SPeter Wemm 					if (*p == '\0')
1082c2aa98e2SPeter Wemm 						break;
1083c2aa98e2SPeter Wemm 					st->s_service[svcno++] = p;
1084c2aa98e2SPeter Wemm 					p = strpbrk(p, " \t");
1085c2aa98e2SPeter Wemm 					if (p == NULL)
1086c2aa98e2SPeter Wemm 						break;
1087c2aa98e2SPeter Wemm 					*p++ = '\0';
10885b0945b5SGregory Neil Shapiro 					while (SM_ISSPACE(*p))
1089c2aa98e2SPeter Wemm 						p++;
1090c2aa98e2SPeter Wemm 				}
1091c2aa98e2SPeter Wemm 				if (svcno < MAXMAPSTACK)
1092c2aa98e2SPeter Wemm 					st->s_service[svcno] = NULL;
1093c2aa98e2SPeter Wemm 			}
109412ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(fp, SM_TIME_DEFAULT);
1095c2aa98e2SPeter Wemm 		}
1096c2aa98e2SPeter Wemm 	}
1097c2aa98e2SPeter Wemm 
1098c2aa98e2SPeter Wemm 	/* look up entry in cache */
1099c2aa98e2SPeter Wemm 	st = stab(service, ST_SERVICE, ST_FIND);
1100c2aa98e2SPeter Wemm 	if (st != NULL && st->s_service[0] != NULL)
1101c2aa98e2SPeter Wemm 	{
1102c2aa98e2SPeter Wemm 		/* extract data */
1103c2aa98e2SPeter Wemm 		svcno = 0;
1104c2aa98e2SPeter Wemm 		while (svcno < MAXMAPSTACK)
1105c2aa98e2SPeter Wemm 		{
1106c2aa98e2SPeter Wemm 			maptype[svcno] = st->s_service[svcno];
1107c2aa98e2SPeter Wemm 			if (maptype[svcno++] == NULL)
1108c2aa98e2SPeter Wemm 				break;
1109c2aa98e2SPeter Wemm 		}
11103299c2f1SGregory Neil Shapiro 		errno = save_errno;
1111c2aa98e2SPeter Wemm 		return --svcno;
1112c2aa98e2SPeter Wemm 	}
11133299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
1114c2aa98e2SPeter Wemm 
1115c2aa98e2SPeter Wemm #if !defined(_USE_SUN_NSSWITCH_)
1116c2aa98e2SPeter Wemm 	/* if the service file doesn't work, use an absolute fallback */
1117c2aa98e2SPeter Wemm # ifdef _USE_DEC_SVC_CONF_
1118c2aa98e2SPeter Wemm   punt:
11195b0945b5SGregory Neil Shapiro # endif
1120c2aa98e2SPeter Wemm 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
1121c2aa98e2SPeter Wemm 		mapreturn[svcno] = 0;
1122c2aa98e2SPeter Wemm 	svcno = 0;
1123c2aa98e2SPeter Wemm 	if (strcmp(service, "aliases") == 0)
1124c2aa98e2SPeter Wemm 	{
11255b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1126c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
11275b0945b5SGregory Neil Shapiro # if CDB
11285b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
11295b0945b5SGregory Neil Shapiro 		maptype[svcno++] = "cdb";
11305b0945b5SGregory Neil Shapiro # endif
11313299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
11325b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
11333299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
11345b0945b5SGregory Neil Shapiro # endif
1135c2aa98e2SPeter Wemm # ifdef AUTO_NIS_ALIASES
113612ed1c7cSGregory Neil Shapiro #  if NISPLUS
11375b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1138c2aa98e2SPeter Wemm 		maptype[svcno++] = "nisplus";
11395b0945b5SGregory Neil Shapiro #  endif
114012ed1c7cSGregory Neil Shapiro #  if NIS
11415b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1142c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
11435b0945b5SGregory Neil Shapiro #  endif
11443299c2f1SGregory Neil Shapiro # endif /* AUTO_NIS_ALIASES */
11453299c2f1SGregory Neil Shapiro 		errno = save_errno;
1146c2aa98e2SPeter Wemm 		return svcno;
1147c2aa98e2SPeter Wemm 	}
1148c2aa98e2SPeter Wemm 	if (strcmp(service, "hosts") == 0)
1149c2aa98e2SPeter Wemm 	{
1150c2aa98e2SPeter Wemm # if NAMED_BIND
11515b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1152c2aa98e2SPeter Wemm 		maptype[svcno++] = "dns";
11533299c2f1SGregory Neil Shapiro # else /* NAMED_BIND */
1154c2aa98e2SPeter Wemm #  if defined(sun) && !defined(BSD)
1155c2aa98e2SPeter Wemm 		/* SunOS */
11565b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1157c2aa98e2SPeter Wemm 		maptype[svcno++] = "nis";
11583299c2f1SGregory Neil Shapiro #  endif /* defined(sun) && !defined(BSD) */
11593299c2f1SGregory Neil Shapiro # endif /* NAMED_BIND */
11603299c2f1SGregory Neil Shapiro # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
11615b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
11623299c2f1SGregory Neil Shapiro 		maptype[svcno++] = "netinfo";
11635b0945b5SGregory Neil Shapiro # endif
11645b0945b5SGregory Neil Shapiro 		SM_ASSERT(svcno < MAXMAPSTACK);
1165c2aa98e2SPeter Wemm 		maptype[svcno++] = "files";
11663299c2f1SGregory Neil Shapiro 		errno = save_errno;
1167c2aa98e2SPeter Wemm 		return svcno;
1168c2aa98e2SPeter Wemm 	}
11693299c2f1SGregory Neil Shapiro 	errno = save_errno;
1170c2aa98e2SPeter Wemm 	return -1;
11713299c2f1SGregory Neil Shapiro #endif /* !defined(_USE_SUN_NSSWITCH_) */
1172c2aa98e2SPeter Wemm }
117312ed1c7cSGregory Neil Shapiro /*
1174c2aa98e2SPeter Wemm **  USERNAME -- return the user id of the logged in user.
1175c2aa98e2SPeter Wemm **
1176c2aa98e2SPeter Wemm **	Parameters:
1177c2aa98e2SPeter Wemm **		none.
1178c2aa98e2SPeter Wemm **
1179c2aa98e2SPeter Wemm **	Returns:
1180c2aa98e2SPeter Wemm **		The login name of the logged in user.
1181c2aa98e2SPeter Wemm **
1182c2aa98e2SPeter Wemm **	Side Effects:
1183c2aa98e2SPeter Wemm **		none.
1184c2aa98e2SPeter Wemm **
1185c2aa98e2SPeter Wemm **	Notes:
1186c2aa98e2SPeter Wemm **		The return value is statically allocated.
1187c2aa98e2SPeter Wemm */
1188c2aa98e2SPeter Wemm 
1189c2aa98e2SPeter Wemm char *
username()1190c2aa98e2SPeter Wemm username()
1191c2aa98e2SPeter Wemm {
1192c2aa98e2SPeter Wemm 	static char *myname = NULL;
11932fb4f839SGregory Neil Shapiro 	extern char *getlogin __P((void));
1194c2aa98e2SPeter Wemm 	register struct passwd *pw;
1195c2aa98e2SPeter Wemm 
1196c2aa98e2SPeter Wemm 	/* cache the result */
1197c2aa98e2SPeter Wemm 	if (myname == NULL)
1198c2aa98e2SPeter Wemm 	{
1199c2aa98e2SPeter Wemm 		myname = getlogin();
12002fb4f839SGregory Neil Shapiro 		if (SM_IS_EMPTY(myname))
1201c2aa98e2SPeter Wemm 		{
1202c2aa98e2SPeter Wemm 			pw = sm_getpwuid(RealUid);
1203c2aa98e2SPeter Wemm 			if (pw != NULL)
120412ed1c7cSGregory Neil Shapiro 				myname = pw->pw_name;
1205c2aa98e2SPeter Wemm 		}
1206c2aa98e2SPeter Wemm 		else
1207c2aa98e2SPeter Wemm 		{
1208c2aa98e2SPeter Wemm 			uid_t uid = RealUid;
1209c2aa98e2SPeter Wemm 
1210c2aa98e2SPeter Wemm 			if ((pw = sm_getpwnam(myname)) == NULL ||
1211c2aa98e2SPeter Wemm 			      (uid != 0 && uid != pw->pw_uid))
1212c2aa98e2SPeter Wemm 			{
1213c2aa98e2SPeter Wemm 				pw = sm_getpwuid(uid);
1214c2aa98e2SPeter Wemm 				if (pw != NULL)
121512ed1c7cSGregory Neil Shapiro 					myname = pw->pw_name;
1216c2aa98e2SPeter Wemm 			}
1217c2aa98e2SPeter Wemm 		}
12182fb4f839SGregory Neil Shapiro 		if (SM_IS_EMPTY(myname))
1219c2aa98e2SPeter Wemm 		{
12203299c2f1SGregory Neil Shapiro 			syserr("554 5.3.0 Who are you?");
1221c2aa98e2SPeter Wemm 			myname = "postmaster";
1222c2aa98e2SPeter Wemm 		}
122312ed1c7cSGregory Neil Shapiro 		else if (strpbrk(myname, ",;:/|\"\\") != NULL)
122412ed1c7cSGregory Neil Shapiro 			myname = addquotes(myname, NULL);
122512ed1c7cSGregory Neil Shapiro 		else
122612ed1c7cSGregory Neil Shapiro 			myname = sm_pstrdup_x(myname);
1227c2aa98e2SPeter Wemm 	}
12283299c2f1SGregory Neil Shapiro 	return myname;
1229c2aa98e2SPeter Wemm }
123012ed1c7cSGregory Neil Shapiro /*
1231c2aa98e2SPeter Wemm **  TTYPATH -- Get the path of the user's tty
1232c2aa98e2SPeter Wemm **
1233c2aa98e2SPeter Wemm **	Returns the pathname of the user's tty.  Returns NULL if
1234c2aa98e2SPeter Wemm **	the user is not logged in or if s/he has write permission
1235c2aa98e2SPeter Wemm **	denied.
1236c2aa98e2SPeter Wemm **
1237c2aa98e2SPeter Wemm **	Parameters:
1238c2aa98e2SPeter Wemm **		none
1239c2aa98e2SPeter Wemm **
1240c2aa98e2SPeter Wemm **	Returns:
1241c2aa98e2SPeter Wemm **		pathname of the user's tty.
1242c2aa98e2SPeter Wemm **		NULL if not logged in or write permission denied.
1243c2aa98e2SPeter Wemm **
1244c2aa98e2SPeter Wemm **	Side Effects:
1245c2aa98e2SPeter Wemm **		none.
1246c2aa98e2SPeter Wemm **
1247c2aa98e2SPeter Wemm **	WARNING:
1248c2aa98e2SPeter Wemm **		Return value is in a local buffer.
1249c2aa98e2SPeter Wemm **
1250c2aa98e2SPeter Wemm **	Called By:
1251c2aa98e2SPeter Wemm **		savemail
1252c2aa98e2SPeter Wemm */
1253c2aa98e2SPeter Wemm 
1254c2aa98e2SPeter Wemm char *
ttypath()1255c2aa98e2SPeter Wemm ttypath()
1256c2aa98e2SPeter Wemm {
1257c2aa98e2SPeter Wemm 	struct stat stbuf;
1258c2aa98e2SPeter Wemm 	register char *pathn;
12592fb4f839SGregory Neil Shapiro 	extern char *ttyname __P((int));
12602fb4f839SGregory Neil Shapiro 	extern char *getlogin __P((void));
1261c2aa98e2SPeter Wemm 
1262c2aa98e2SPeter Wemm 	/* compute the pathname of the controlling tty */
1263c2aa98e2SPeter Wemm 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
1264c2aa98e2SPeter Wemm 	    (pathn = ttyname(0)) == NULL)
1265c2aa98e2SPeter Wemm 	{
1266c2aa98e2SPeter Wemm 		errno = 0;
12673299c2f1SGregory Neil Shapiro 		return NULL;
1268c2aa98e2SPeter Wemm 	}
1269c2aa98e2SPeter Wemm 
1270c2aa98e2SPeter Wemm 	/* see if we have write permission */
1271c2aa98e2SPeter Wemm 	if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode))
1272c2aa98e2SPeter Wemm 	{
1273c2aa98e2SPeter Wemm 		errno = 0;
12743299c2f1SGregory Neil Shapiro 		return NULL;
1275c2aa98e2SPeter Wemm 	}
1276c2aa98e2SPeter Wemm 
1277c2aa98e2SPeter Wemm 	/* see if the user is logged in */
1278c2aa98e2SPeter Wemm 	if (getlogin() == NULL)
12793299c2f1SGregory Neil Shapiro 		return NULL;
1280c2aa98e2SPeter Wemm 
1281c2aa98e2SPeter Wemm 	/* looks good */
12823299c2f1SGregory Neil Shapiro 	return pathn;
1283c2aa98e2SPeter Wemm }
128412ed1c7cSGregory Neil Shapiro /*
1285c2aa98e2SPeter Wemm **  CHECKCOMPAT -- check for From and To person compatible.
1286c2aa98e2SPeter Wemm **
1287c2aa98e2SPeter Wemm **	This routine can be supplied on a per-installation basis
1288c2aa98e2SPeter Wemm **	to determine whether a person is allowed to send a message.
1289c2aa98e2SPeter Wemm **	This allows restriction of certain types of internet
1290c2aa98e2SPeter Wemm **	forwarding or registration of users.
1291c2aa98e2SPeter Wemm **
1292c2aa98e2SPeter Wemm **	If the hosts are found to be incompatible, an error
1293c2aa98e2SPeter Wemm **	message should be given using "usrerr" and an EX_ code
1294c2aa98e2SPeter Wemm **	should be returned.  You can also set to->q_status to
1295c2aa98e2SPeter Wemm **	a DSN-style status code.
1296c2aa98e2SPeter Wemm **
1297c2aa98e2SPeter Wemm **	EF_NO_BODY_RETN can be set in e->e_flags to suppress the
1298c2aa98e2SPeter Wemm **	body during the return-to-sender function; this should be done
1299c2aa98e2SPeter Wemm **	on huge messages.  This bit may already be set by the ESMTP
1300c2aa98e2SPeter Wemm **	protocol.
1301c2aa98e2SPeter Wemm **
1302c2aa98e2SPeter Wemm **	Parameters:
1303c2aa98e2SPeter Wemm **		to -- the person being sent to.
1304c2aa98e2SPeter Wemm **
1305c2aa98e2SPeter Wemm **	Returns:
1306c2aa98e2SPeter Wemm **		an exit status
1307c2aa98e2SPeter Wemm **
1308c2aa98e2SPeter Wemm **	Side Effects:
1309c2aa98e2SPeter Wemm **		none (unless you include the usrerr stuff)
1310c2aa98e2SPeter Wemm */
1311c2aa98e2SPeter Wemm 
1312c2aa98e2SPeter Wemm int
checkcompat(to,e)1313c2aa98e2SPeter Wemm checkcompat(to, e)
1314c2aa98e2SPeter Wemm 	register ADDRESS *to;
1315c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1316c2aa98e2SPeter Wemm {
1317c2aa98e2SPeter Wemm 	if (tTd(49, 1))
131812ed1c7cSGregory Neil Shapiro 		sm_dprintf("checkcompat(to=%s, from=%s)\n",
1319c2aa98e2SPeter Wemm 			to->q_paddr, e->e_from.q_paddr);
1320c2aa98e2SPeter Wemm 
1321c2aa98e2SPeter Wemm #ifdef EXAMPLE_CODE
1322c2aa98e2SPeter Wemm 	/* this code is intended as an example only */
1323c2aa98e2SPeter Wemm 	register STAB *s;
1324c2aa98e2SPeter Wemm 
1325c2aa98e2SPeter Wemm 	s = stab("arpa", ST_MAILER, ST_FIND);
1326c2aa98e2SPeter Wemm 	if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
1327c2aa98e2SPeter Wemm 	    to->q_mailer == s->s_mailer)
1328c2aa98e2SPeter Wemm 	{
1329c2aa98e2SPeter Wemm 		usrerr("553 No ARPA mail through this machine: see your system administration");
13303299c2f1SGregory Neil Shapiro 		/* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */
1331c2aa98e2SPeter Wemm 		to->q_status = "5.7.1";
13323299c2f1SGregory Neil Shapiro 		return EX_UNAVAILABLE;
1333c2aa98e2SPeter Wemm 	}
1334c2aa98e2SPeter Wemm #endif /* EXAMPLE_CODE */
13353299c2f1SGregory Neil Shapiro 	return EX_OK;
1336c2aa98e2SPeter Wemm }
1337951742c4SGregory Neil Shapiro 
1338951742c4SGregory Neil Shapiro #ifdef SUN_EXTENSIONS
1339951742c4SGregory Neil Shapiro static void
init_md_sun()1340951742c4SGregory Neil Shapiro init_md_sun()
1341951742c4SGregory Neil Shapiro {
1342951742c4SGregory Neil Shapiro 	struct stat sbuf;
1343951742c4SGregory Neil Shapiro 
1344951742c4SGregory Neil Shapiro 	/* Check for large file descriptor */
1345951742c4SGregory Neil Shapiro 	if (fstat(fileno(stdin), &sbuf) < 0)
1346951742c4SGregory Neil Shapiro 	{
1347951742c4SGregory Neil Shapiro 		if (errno == EOVERFLOW)
1348951742c4SGregory Neil Shapiro 		{
1349951742c4SGregory Neil Shapiro 			perror("stdin");
1350951742c4SGregory Neil Shapiro 			exit(EX_NOINPUT);
1351951742c4SGregory Neil Shapiro 		}
1352951742c4SGregory Neil Shapiro 	}
1353951742c4SGregory Neil Shapiro }
1354951742c4SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
1355951742c4SGregory Neil Shapiro 
13563299c2f1SGregory Neil Shapiro /*
1357c2aa98e2SPeter Wemm **  INIT_MD -- do machine dependent initializations
1358c2aa98e2SPeter Wemm **
1359c2aa98e2SPeter Wemm **	Systems that have global modes that should be set should do
1360c2aa98e2SPeter Wemm **	them here rather than in main.
1361c2aa98e2SPeter Wemm */
1362c2aa98e2SPeter Wemm 
1363c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1364c2aa98e2SPeter Wemm # include <compat.h>
13655b0945b5SGregory Neil Shapiro #endif
1366c2aa98e2SPeter Wemm 
1367c2aa98e2SPeter Wemm #if SHARE_V1
1368c2aa98e2SPeter Wemm # include <shares.h>
13695b0945b5SGregory Neil Shapiro #endif
1370c2aa98e2SPeter Wemm 
1371c2aa98e2SPeter Wemm void
init_md(argc,argv)1372c2aa98e2SPeter Wemm init_md(argc, argv)
1373c2aa98e2SPeter Wemm 	int argc;
1374c2aa98e2SPeter Wemm 	char **argv;
1375c2aa98e2SPeter Wemm {
1376c2aa98e2SPeter Wemm #ifdef _AUX_SOURCE
1377c2aa98e2SPeter Wemm 	setcompat(getcompat() | COMPAT_BSDPROT);
13785b0945b5SGregory Neil Shapiro #endif
1379c2aa98e2SPeter Wemm 
1380c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
1381c2aa98e2SPeter Wemm 	init_md_sun();
13825b0945b5SGregory Neil Shapiro #endif
1383c2aa98e2SPeter Wemm 
1384c2aa98e2SPeter Wemm #if _CONVEX_SOURCE
1385c2aa98e2SPeter Wemm 	/* keep gethostby*() from stripping the local domain name */
1386c2aa98e2SPeter Wemm 	set_domain_trim_off();
13875b0945b5SGregory Neil Shapiro #endif
1388951742c4SGregory Neil Shapiro #if defined(__QNX__) && !defined(__QNXNTO__)
1389c2aa98e2SPeter Wemm 	/*
1390c2aa98e2SPeter Wemm 	**  Due to QNX's network distributed nature, you can target a tcpip
1391c2aa98e2SPeter Wemm 	**  stack on a different node in the qnx network; this patch lets
1392c2aa98e2SPeter Wemm 	**  this feature work.  The __sock_locate() must be done before the
1393c2aa98e2SPeter Wemm 	**  environment is clear.
1394c2aa98e2SPeter Wemm 	*/
1395c2aa98e2SPeter Wemm 	__sock_locate();
13963299c2f1SGregory Neil Shapiro #endif /* __QNX__ */
1397c2aa98e2SPeter Wemm #if SECUREWARE || defined(_SCO_unix_)
1398c2aa98e2SPeter Wemm 	set_auth_parameters(argc, argv);
1399c2aa98e2SPeter Wemm 
1400c2aa98e2SPeter Wemm # ifdef _SCO_unix_
1401c2aa98e2SPeter Wemm 	/*
1402c2aa98e2SPeter Wemm 	**  This is required for highest security levels (the kernel
1403c2aa98e2SPeter Wemm 	**  won't let it call set*uid() or run setuid binaries without
1404c2aa98e2SPeter Wemm 	**  it).  It may be necessary on other SECUREWARE systems.
1405c2aa98e2SPeter Wemm 	*/
1406c2aa98e2SPeter Wemm 
1407c2aa98e2SPeter Wemm 	if (getluid() == -1)
1408c2aa98e2SPeter Wemm 		setluid(0);
14093299c2f1SGregory Neil Shapiro # endif /* _SCO_unix_ */
14103299c2f1SGregory Neil Shapiro #endif /* SECUREWARE || defined(_SCO_unix_) */
14113299c2f1SGregory Neil Shapiro 
1412c2aa98e2SPeter Wemm #ifdef VENDOR_DEFAULT
1413c2aa98e2SPeter Wemm 	VendorCode = VENDOR_DEFAULT;
14145b0945b5SGregory Neil Shapiro #else
1415c2aa98e2SPeter Wemm 	VendorCode = VENDOR_BERKELEY;
14165b0945b5SGregory Neil Shapiro #endif
1417c2aa98e2SPeter Wemm }
141812ed1c7cSGregory Neil Shapiro /*
1419c2aa98e2SPeter Wemm **  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
1420c2aa98e2SPeter Wemm **
1421c2aa98e2SPeter Wemm **	Called once, on startup.
1422c2aa98e2SPeter Wemm **
1423c2aa98e2SPeter Wemm **	Parameters:
1424c2aa98e2SPeter Wemm **		e -- the global envelope.
1425c2aa98e2SPeter Wemm **
1426c2aa98e2SPeter Wemm **	Returns:
1427c2aa98e2SPeter Wemm **		none.
1428c2aa98e2SPeter Wemm **
1429c2aa98e2SPeter Wemm **	Side Effects:
1430c2aa98e2SPeter Wemm **		vendor-dependent.
1431c2aa98e2SPeter Wemm */
1432c2aa98e2SPeter Wemm 
1433c2aa98e2SPeter Wemm void
init_vendor_macros(e)1434c2aa98e2SPeter Wemm init_vendor_macros(e)
1435c2aa98e2SPeter Wemm 	register ENVELOPE *e;
1436c2aa98e2SPeter Wemm {
1437c2aa98e2SPeter Wemm }
143812ed1c7cSGregory Neil Shapiro /*
1439c2aa98e2SPeter Wemm **  GETLA -- get the current load average
1440c2aa98e2SPeter Wemm **
1441c2aa98e2SPeter Wemm **	This code stolen from la.c.
1442c2aa98e2SPeter Wemm **
1443c2aa98e2SPeter Wemm **	Parameters:
1444c2aa98e2SPeter Wemm **		none.
1445c2aa98e2SPeter Wemm **
1446c2aa98e2SPeter Wemm **	Returns:
1447c2aa98e2SPeter Wemm **		The current load average as an integer.
1448c2aa98e2SPeter Wemm **
1449c2aa98e2SPeter Wemm **	Side Effects:
1450c2aa98e2SPeter Wemm **		none.
1451c2aa98e2SPeter Wemm */
1452c2aa98e2SPeter Wemm 
1453c2aa98e2SPeter Wemm /* try to guess what style of load average we have */
1454c2aa98e2SPeter Wemm #define LA_ZERO		1	/* always return load average as zero */
1455c2aa98e2SPeter Wemm #define LA_INT		2	/* read kmem for avenrun; interpret as long */
1456c2aa98e2SPeter Wemm #define LA_FLOAT	3	/* read kmem for avenrun; interpret as float */
1457c2aa98e2SPeter Wemm #define LA_SUBR		4	/* call getloadavg */
1458c2aa98e2SPeter Wemm #define LA_MACH		5	/* MACH load averages (as on NeXT boxes) */
1459c2aa98e2SPeter Wemm #define LA_SHORT	6	/* read kmem for avenrun; interpret as short */
1460c2aa98e2SPeter Wemm #define LA_PROCSTR	7	/* read string ("1.17") from /proc/loadavg */
1461c2aa98e2SPeter Wemm #define LA_READKSYM	8	/* SVR4: use MIOC_READKSYM ioctl call */
1462c2aa98e2SPeter Wemm #define LA_DGUX		9	/* special DGUX implementation */
1463c2aa98e2SPeter Wemm #define LA_HPUX		10	/* special HPUX implementation */
1464c2aa98e2SPeter Wemm #define LA_IRIX6	11	/* special IRIX 6.2 implementation */
1465c2aa98e2SPeter Wemm #define LA_KSTAT	12	/* special Solaris kstat(3k) implementation */
1466c2aa98e2SPeter Wemm #define LA_DEVSHORT	13	/* read short from a device */
1467c2aa98e2SPeter Wemm #define LA_ALPHAOSF	14	/* Digital UNIX (OSF/1 on Alpha) table() call */
1468c46d91b7SGregory Neil Shapiro #define LA_PSET		15	/* Solaris per-processor-set load average */
1469188b7d28SGregory Neil Shapiro #define LA_LONGLONG	17 /* read kmem for avenrun; interpret as long long */
1470c2aa98e2SPeter Wemm 
1471c2aa98e2SPeter Wemm /* do guesses based on general OS type */
1472c2aa98e2SPeter Wemm #ifndef LA_TYPE
1473c2aa98e2SPeter Wemm # define LA_TYPE	LA_ZERO
14745b0945b5SGregory Neil Shapiro #endif
1475c2aa98e2SPeter Wemm 
1476c2aa98e2SPeter Wemm #ifndef FSHIFT
1477c2aa98e2SPeter Wemm # if defined(unixpc)
1478c2aa98e2SPeter Wemm #  define FSHIFT	5
14795b0945b5SGregory Neil Shapiro # endif
1480c2aa98e2SPeter Wemm 
1481c2aa98e2SPeter Wemm # if defined(__alpha) || defined(IRIX)
1482c2aa98e2SPeter Wemm #  define FSHIFT	10
14835b0945b5SGregory Neil Shapiro # endif
1484c2aa98e2SPeter Wemm 
14853299c2f1SGregory Neil Shapiro #endif /* ! FSHIFT */
1486c2aa98e2SPeter Wemm 
1487c2aa98e2SPeter Wemm #ifndef FSHIFT
1488c2aa98e2SPeter Wemm # define FSHIFT		8
14895b0945b5SGregory Neil Shapiro #endif
1490c2aa98e2SPeter Wemm 
1491c2aa98e2SPeter Wemm #ifndef FSCALE
1492c2aa98e2SPeter Wemm # define FSCALE		(1 << FSHIFT)
14935b0945b5SGregory Neil Shapiro #endif
1494c2aa98e2SPeter Wemm 
1495c2aa98e2SPeter Wemm #ifndef LA_AVENRUN
1496c2aa98e2SPeter Wemm # ifdef SYSTEM5
1497c2aa98e2SPeter Wemm #  define LA_AVENRUN	"avenrun"
14985b0945b5SGregory Neil Shapiro # else
1499c2aa98e2SPeter Wemm #  define LA_AVENRUN	"_avenrun"
15005b0945b5SGregory Neil Shapiro # endif
15013299c2f1SGregory Neil Shapiro #endif /* ! LA_AVENRUN */
1502c2aa98e2SPeter Wemm 
1503c2aa98e2SPeter Wemm /* _PATH_KMEM should be defined in <paths.h> */
1504c2aa98e2SPeter Wemm #ifndef _PATH_KMEM
1505c2aa98e2SPeter Wemm # define _PATH_KMEM	"/dev/kmem"
15065b0945b5SGregory Neil Shapiro #endif
1507c2aa98e2SPeter Wemm 
1508188b7d28SGregory Neil Shapiro #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
1509c2aa98e2SPeter Wemm 
1510c2aa98e2SPeter Wemm # include <nlist.h>
1511c2aa98e2SPeter Wemm 
1512c2aa98e2SPeter Wemm /* _PATH_UNIX should be defined in <paths.h> */
1513c2aa98e2SPeter Wemm # ifndef _PATH_UNIX
1514c2aa98e2SPeter Wemm #  if defined(SYSTEM5)
1515c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/unix"
15165b0945b5SGregory Neil Shapiro #  else
1517c2aa98e2SPeter Wemm #   define _PATH_UNIX	"/vmunix"
15185b0945b5SGregory Neil Shapiro #  endif
15193299c2f1SGregory Neil Shapiro # endif /* ! _PATH_UNIX */
1520c2aa98e2SPeter Wemm 
1521c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
1522c2aa98e2SPeter Wemm struct nlist	Nl[2];
15233299c2f1SGregory Neil Shapiro # else /* _AUX_SOURCE */
1524c2aa98e2SPeter Wemm struct nlist	Nl[] =
1525c2aa98e2SPeter Wemm {
1526c2aa98e2SPeter Wemm 	{ LA_AVENRUN },
1527c2aa98e2SPeter Wemm 	{ 0 },
1528c2aa98e2SPeter Wemm };
15293299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1530c2aa98e2SPeter Wemm # define X_AVENRUN	0
1531c2aa98e2SPeter Wemm 
153212ed1c7cSGregory Neil Shapiro int
getla()1533c2aa98e2SPeter Wemm getla()
1534c2aa98e2SPeter Wemm {
153512ed1c7cSGregory Neil Shapiro 	int j;
1536c2aa98e2SPeter Wemm 	static int kmem = -1;
1537c2aa98e2SPeter Wemm # if LA_TYPE == LA_INT
1538c2aa98e2SPeter Wemm 	long avenrun[3];
15393299c2f1SGregory Neil Shapiro # else /* LA_TYPE == LA_INT */
1540c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
1541c2aa98e2SPeter Wemm 	short avenrun[3];
1542188b7d28SGregory Neil Shapiro #  else
1543188b7d28SGregory Neil Shapiro #   if LA_TYPE == LA_LONGLONG
1544188b7d28SGregory Neil Shapiro 	long long avenrun[3];
15455b0945b5SGregory Neil Shapiro #   else
1546c2aa98e2SPeter Wemm 	double avenrun[3];
15475b0945b5SGregory Neil Shapiro #   endif
15483299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
15493299c2f1SGregory Neil Shapiro # endif /* LA_TYPE == LA_INT */
15502fb4f839SGregory Neil Shapiro 	extern off_t lseek __P((int, off_t, int));
1551c2aa98e2SPeter Wemm 
1552c2aa98e2SPeter Wemm 	if (kmem < 0)
1553c2aa98e2SPeter Wemm 	{
1554c2aa98e2SPeter Wemm # ifdef _AUX_SOURCE
155512ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN,
1556951742c4SGregory Neil Shapiro 			       sizeof(Nl[X_AVENRUN].n_name));
1557c2aa98e2SPeter Wemm 		Nl[1].n_name[0] = '\0';
15583299c2f1SGregory Neil Shapiro # endif /* _AUX_SOURCE */
1559c2aa98e2SPeter Wemm 
1560c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
1561951742c4SGregory Neil Shapiro 		if (knlist(Nl, 1, sizeof(Nl[0])) < 0)
15625b0945b5SGregory Neil Shapiro # else
1563c2aa98e2SPeter Wemm 		if (nlist(_PATH_UNIX, Nl) < 0)
15645b0945b5SGregory Neil Shapiro # endif
1565c2aa98e2SPeter Wemm 		{
1566c2aa98e2SPeter Wemm 			if (tTd(3, 1))
156712ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
156812ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15693299c2f1SGregory Neil Shapiro 			return -1;
1570c2aa98e2SPeter Wemm 		}
1571c2aa98e2SPeter Wemm 		if (Nl[X_AVENRUN].n_value == 0)
1572c2aa98e2SPeter Wemm 		{
1573c2aa98e2SPeter Wemm 			if (tTd(3, 1))
157412ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: nlist(%s, %s) ==> 0\n",
1575c2aa98e2SPeter Wemm 					_PATH_UNIX, LA_AVENRUN);
15763299c2f1SGregory Neil Shapiro 			return -1;
1577c2aa98e2SPeter Wemm 		}
1578c2aa98e2SPeter Wemm # ifdef NAMELISTMASK
1579c2aa98e2SPeter Wemm 		Nl[X_AVENRUN].n_value &= NAMELISTMASK;
15805b0945b5SGregory Neil Shapiro # endif
1581c2aa98e2SPeter Wemm 
1582c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1583c2aa98e2SPeter Wemm 		if (kmem < 0)
1584c2aa98e2SPeter Wemm 		{
1585c2aa98e2SPeter Wemm 			if (tTd(3, 1))
158612ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
158712ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
15883299c2f1SGregory Neil Shapiro 			return -1;
1589c2aa98e2SPeter Wemm 		}
159012ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
159112ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
159212ed1c7cSGregory Neil Shapiro 		{
159312ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
159412ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
159512ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
159612ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
159712ed1c7cSGregory Neil Shapiro 			kmem = -1;
159812ed1c7cSGregory Neil Shapiro 			return -1;
159912ed1c7cSGregory Neil Shapiro 		}
1600c2aa98e2SPeter Wemm 	}
1601c2aa98e2SPeter Wemm 	if (tTd(3, 20))
160212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: symbol address = %#lx\n",
160312ed1c7cSGregory Neil Shapiro 			(unsigned long) Nl[X_AVENRUN].n_value);
1604c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
1605e3793f76SGregory Neil Shapiro 	    read(kmem, (char *) avenrun, sizeof(avenrun)) != sizeof(avenrun))
1606c2aa98e2SPeter Wemm 	{
1607c2aa98e2SPeter Wemm 		/* thank you Ian */
1608c2aa98e2SPeter Wemm 		if (tTd(3, 1))
160912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
161012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
16113299c2f1SGregory Neil Shapiro 		return -1;
1612c2aa98e2SPeter Wemm 	}
1613188b7d28SGregory Neil Shapiro # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
1614c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1615c2aa98e2SPeter Wemm 	{
1616c2aa98e2SPeter Wemm #  if LA_TYPE == LA_SHORT
161712ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1618c2aa98e2SPeter Wemm 		if (tTd(3, 15))
161912ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
16203299c2f1SGregory Neil Shapiro #  else /* LA_TYPE == LA_SHORT */
1621188b7d28SGregory Neil Shapiro #   if LA_TYPE == LA_LONGLONG
1622188b7d28SGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %lld", avenrun[0]);
1623188b7d28SGregory Neil Shapiro 		if (tTd(3, 15))
1624188b7d28SGregory Neil Shapiro 			sm_dprintf(", %lld, %lld", avenrun[1], avenrun[2]);
1625188b7d28SGregory Neil Shapiro #   else /* LA_TYPE == LA_LONGLONG */
162612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", avenrun[0]);
1627c2aa98e2SPeter Wemm 		if (tTd(3, 15))
162812ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]);
1629188b7d28SGregory Neil Shapiro #   endif /* LA_TYPE == LA_LONGLONG */
16303299c2f1SGregory Neil Shapiro #  endif /* LA_TYPE == LA_SHORT */
163112ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1632c2aa98e2SPeter Wemm 	}
1633c2aa98e2SPeter Wemm 	if (tTd(3, 1))
163412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
16353299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1636c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1637188b7d28SGregory Neil Shapiro # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1638c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1639c2aa98e2SPeter Wemm 	{
164012ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %g", avenrun[0]);
1641c2aa98e2SPeter Wemm 		if (tTd(3, 15))
164212ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %g, %g", avenrun[1], avenrun[2]);
164312ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1644c2aa98e2SPeter Wemm 	}
1645c2aa98e2SPeter Wemm 	if (tTd(3, 1))
164612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1647c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1648188b7d28SGregory Neil Shapiro # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1649c2aa98e2SPeter Wemm }
1650c2aa98e2SPeter Wemm 
1651188b7d28SGregory Neil Shapiro #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
1652c2aa98e2SPeter Wemm 
1653c2aa98e2SPeter Wemm #if LA_TYPE == LA_READKSYM
1654c2aa98e2SPeter Wemm 
1655c2aa98e2SPeter Wemm # include <sys/ksym.h>
1656c2aa98e2SPeter Wemm 
165712ed1c7cSGregory Neil Shapiro int
getla()1658c2aa98e2SPeter Wemm getla()
1659c2aa98e2SPeter Wemm {
166012ed1c7cSGregory Neil Shapiro 	int j;
1661c2aa98e2SPeter Wemm 	static int kmem = -1;
1662c2aa98e2SPeter Wemm 	long avenrun[3];
1663c2aa98e2SPeter Wemm 	struct mioc_rksym mirk;
1664c2aa98e2SPeter Wemm 
1665c2aa98e2SPeter Wemm 	if (kmem < 0)
1666c2aa98e2SPeter Wemm 	{
1667c2aa98e2SPeter Wemm 		kmem = open("/dev/kmem", 0, 0);
1668c2aa98e2SPeter Wemm 		if (kmem < 0)
1669c2aa98e2SPeter Wemm 		{
1670c2aa98e2SPeter Wemm 			if (tTd(3, 1))
167112ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(/dev/kmem): %s\n",
167212ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
16733299c2f1SGregory Neil Shapiro 			return -1;
1674c2aa98e2SPeter Wemm 		}
167512ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
167612ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
167712ed1c7cSGregory Neil Shapiro 		{
167812ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
167912ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
168012ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
168112ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
168212ed1c7cSGregory Neil Shapiro 			kmem = -1;
168312ed1c7cSGregory Neil Shapiro 			return -1;
168412ed1c7cSGregory Neil Shapiro 		}
1685c2aa98e2SPeter Wemm 	}
1686c2aa98e2SPeter Wemm 	mirk.mirk_symname = LA_AVENRUN;
1687c2aa98e2SPeter Wemm 	mirk.mirk_buf = avenrun;
1688c2aa98e2SPeter Wemm 	mirk.mirk_buflen = sizeof(avenrun);
1689c2aa98e2SPeter Wemm 	if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
1690c2aa98e2SPeter Wemm 	{
1691c2aa98e2SPeter Wemm 		if (tTd(3, 1))
169212ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
169312ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1694c2aa98e2SPeter Wemm 		return -1;
1695c2aa98e2SPeter Wemm 	}
1696c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1697c2aa98e2SPeter Wemm 	{
169812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
1699c2aa98e2SPeter Wemm 		if (tTd(3, 15))
170012ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
170112ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1702c2aa98e2SPeter Wemm 	}
1703c2aa98e2SPeter Wemm 	if (tTd(3, 1))
170412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
17053299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1706c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1707c2aa98e2SPeter Wemm }
1708c2aa98e2SPeter Wemm 
1709c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_READKSYM */
1710c2aa98e2SPeter Wemm 
1711c2aa98e2SPeter Wemm #if LA_TYPE == LA_DGUX
1712c2aa98e2SPeter Wemm 
1713c2aa98e2SPeter Wemm # include <sys/dg_sys_info.h>
1714c2aa98e2SPeter Wemm 
171512ed1c7cSGregory Neil Shapiro int
getla()1716c2aa98e2SPeter Wemm getla()
1717c2aa98e2SPeter Wemm {
1718c2aa98e2SPeter Wemm 	struct dg_sys_info_load_info load_info;
1719c2aa98e2SPeter Wemm 
1720c2aa98e2SPeter Wemm 	dg_sys_info((long *)&load_info,
1721c2aa98e2SPeter Wemm 		DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
1722c2aa98e2SPeter Wemm 
1723c2aa98e2SPeter Wemm 	if (tTd(3, 1))
172412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5));
1725c2aa98e2SPeter Wemm 
1726c2aa98e2SPeter Wemm 	return ((int) (load_info.one_minute + 0.5));
1727c2aa98e2SPeter Wemm }
1728c2aa98e2SPeter Wemm 
1729c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DGUX */
1730c2aa98e2SPeter Wemm 
1731c2aa98e2SPeter Wemm #if LA_TYPE == LA_HPUX
1732c2aa98e2SPeter Wemm 
1733c2aa98e2SPeter Wemm /* forward declarations to keep gcc from complaining */
1734c2aa98e2SPeter Wemm struct pst_dynamic;
1735c2aa98e2SPeter Wemm struct pst_status;
1736c2aa98e2SPeter Wemm struct pst_static;
1737c2aa98e2SPeter Wemm struct pst_vminfo;
1738c2aa98e2SPeter Wemm struct pst_diskinfo;
1739c2aa98e2SPeter Wemm struct pst_processor;
1740c2aa98e2SPeter Wemm struct pst_lv;
1741c2aa98e2SPeter Wemm struct pst_swapinfo;
1742c2aa98e2SPeter Wemm 
1743c2aa98e2SPeter Wemm # include <sys/param.h>
1744c2aa98e2SPeter Wemm # include <sys/pstat.h>
1745c2aa98e2SPeter Wemm 
174612ed1c7cSGregory Neil Shapiro int
getla()1747c2aa98e2SPeter Wemm getla()
1748c2aa98e2SPeter Wemm {
1749c2aa98e2SPeter Wemm 	struct pst_dynamic pstd;
1750c2aa98e2SPeter Wemm 
1751c2aa98e2SPeter Wemm 	if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
1752c2aa98e2SPeter Wemm 			     (size_t) 1, 0) == -1)
1753c2aa98e2SPeter Wemm 		return 0;
1754c2aa98e2SPeter Wemm 
1755c2aa98e2SPeter Wemm 	if (tTd(3, 1))
175612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
1757c2aa98e2SPeter Wemm 
1758c2aa98e2SPeter Wemm 	return (int) (pstd.psd_avg_1_min + 0.5);
1759c2aa98e2SPeter Wemm }
1760c2aa98e2SPeter Wemm 
1761c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_HPUX */
1762c2aa98e2SPeter Wemm 
1763c2aa98e2SPeter Wemm #if LA_TYPE == LA_SUBR
1764c2aa98e2SPeter Wemm 
176512ed1c7cSGregory Neil Shapiro int
getla()1766c2aa98e2SPeter Wemm getla()
1767c2aa98e2SPeter Wemm {
1768c2aa98e2SPeter Wemm 	double avenrun[3];
1769c2aa98e2SPeter Wemm 
1770c2aa98e2SPeter Wemm 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
1771c2aa98e2SPeter Wemm 	{
1772c2aa98e2SPeter Wemm 		if (tTd(3, 1))
177312ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: getloadavg failed: %s",
177412ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
17753299c2f1SGregory Neil Shapiro 		return -1;
1776c2aa98e2SPeter Wemm 	}
1777c2aa98e2SPeter Wemm 	if (tTd(3, 1))
177812ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
1779c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + 0.5));
1780c2aa98e2SPeter Wemm }
1781c2aa98e2SPeter Wemm 
1782c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_SUBR */
1783c2aa98e2SPeter Wemm 
1784c2aa98e2SPeter Wemm #if LA_TYPE == LA_MACH
1785c2aa98e2SPeter Wemm 
1786c2aa98e2SPeter Wemm /*
1787c2aa98e2SPeter Wemm **  This has been tested on NEXTSTEP release 2.1/3.X.
1788c2aa98e2SPeter Wemm */
1789c2aa98e2SPeter Wemm 
1790c2aa98e2SPeter Wemm # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
1791c2aa98e2SPeter Wemm #  include <mach/mach.h>
17925b0945b5SGregory Neil Shapiro # else
1793c2aa98e2SPeter Wemm #  include <mach.h>
17945b0945b5SGregory Neil Shapiro # endif
1795c2aa98e2SPeter Wemm 
179612ed1c7cSGregory Neil Shapiro int
getla()1797c2aa98e2SPeter Wemm getla()
1798c2aa98e2SPeter Wemm {
1799c2aa98e2SPeter Wemm 	processor_set_t default_set;
1800c2aa98e2SPeter Wemm 	kern_return_t error;
1801c2aa98e2SPeter Wemm 	unsigned int info_count;
1802c2aa98e2SPeter Wemm 	struct processor_set_basic_info info;
1803c2aa98e2SPeter Wemm 	host_t host;
1804c2aa98e2SPeter Wemm 
1805c2aa98e2SPeter Wemm 	error = processor_set_default(host_self(), &default_set);
1806c2aa98e2SPeter Wemm 	if (error != KERN_SUCCESS)
1807c2aa98e2SPeter Wemm 	{
1808c2aa98e2SPeter Wemm 		if (tTd(3, 1))
180912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_default failed: %s",
181012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1811c2aa98e2SPeter Wemm 		return -1;
1812c2aa98e2SPeter Wemm 	}
1813c2aa98e2SPeter Wemm 	info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
1814c2aa98e2SPeter Wemm 	if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
1815c2aa98e2SPeter Wemm 			       &host, (processor_set_info_t)&info,
1816c2aa98e2SPeter Wemm 			       &info_count) != KERN_SUCCESS)
1817c2aa98e2SPeter Wemm 	{
1818c2aa98e2SPeter Wemm 		if (tTd(3, 1))
181912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: processor_set_info failed: %s",
182012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1821c2aa98e2SPeter Wemm 		return -1;
1822c2aa98e2SPeter Wemm 	}
1823c2aa98e2SPeter Wemm 	if (tTd(3, 1))
182412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
18253299c2f1SGregory Neil Shapiro 			(int) ((info.load_average + (LOAD_SCALE / 2)) /
18263299c2f1SGregory Neil Shapiro 			       LOAD_SCALE));
1827c2aa98e2SPeter Wemm 	return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
1828c2aa98e2SPeter Wemm }
1829c2aa98e2SPeter Wemm 
1830c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_MACH */
1831c2aa98e2SPeter Wemm 
1832c2aa98e2SPeter Wemm #if LA_TYPE == LA_PROCSTR
183312ed1c7cSGregory Neil Shapiro # if SM_CONF_BROKEN_STRTOD
183412ed1c7cSGregory Neil Shapiro 	ERROR: This OS has most likely a broken strtod() implemenentation.
183512ed1c7cSGregory Neil Shapiro 	ERROR: The function is required for getla().
183612ed1c7cSGregory Neil Shapiro 	ERROR: Check the compilation options _LA_PROCSTR and
_SM_CONF_BROKEN_STRTOD(without the leading _)183712ed1c7cSGregory Neil Shapiro 	ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _).
183812ed1c7cSGregory Neil Shapiro # endif /* SM_CONF_BROKEN_STRTOD */
1839c2aa98e2SPeter Wemm 
1840c2aa98e2SPeter Wemm /*
1841c2aa98e2SPeter Wemm **  Read /proc/loadavg for the load average.  This is assumed to be
1842c2aa98e2SPeter Wemm **  in a format like "0.15 0.12 0.06".
1843c2aa98e2SPeter Wemm **
1844c2aa98e2SPeter Wemm **	Initially intended for Linux.  This has been in the kernel
1845c2aa98e2SPeter Wemm **	since at least 0.99.15.
1846c2aa98e2SPeter Wemm */
1847c2aa98e2SPeter Wemm 
1848c2aa98e2SPeter Wemm # ifndef _PATH_LOADAVG
1849c2aa98e2SPeter Wemm #  define _PATH_LOADAVG	"/proc/loadavg"
18505b0945b5SGregory Neil Shapiro # endif
1851c2aa98e2SPeter Wemm 
185212ed1c7cSGregory Neil Shapiro int
1853c2aa98e2SPeter Wemm getla()
1854c2aa98e2SPeter Wemm {
1855c2aa98e2SPeter Wemm 	double avenrun;
1856c2aa98e2SPeter Wemm 	register int result;
185712ed1c7cSGregory Neil Shapiro 	SM_FILE_T *fp;
1858c2aa98e2SPeter Wemm 
185912ed1c7cSGregory Neil Shapiro 	fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY,
186012ed1c7cSGregory Neil Shapiro 			NULL);
1861c2aa98e2SPeter Wemm 	if (fp == NULL)
1862c2aa98e2SPeter Wemm 	{
1863c2aa98e2SPeter Wemm 		if (tTd(3, 1))
186412ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_open(%s): %s\n",
186512ed1c7cSGregory Neil Shapiro 				   _PATH_LOADAVG, sm_errstring(errno));
1866c2aa98e2SPeter Wemm 		return -1;
1867c2aa98e2SPeter Wemm 	}
186812ed1c7cSGregory Neil Shapiro 	result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun);
186912ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(fp, SM_TIME_DEFAULT);
1870c2aa98e2SPeter Wemm 	if (result != 1)
1871c2aa98e2SPeter Wemm 	{
1872c2aa98e2SPeter Wemm 		if (tTd(3, 1))
187312ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: sm_io_fscanf() = %d: %s\n",
187412ed1c7cSGregory Neil Shapiro 				   result, sm_errstring(errno));
1875c2aa98e2SPeter Wemm 		return -1;
1876c2aa98e2SPeter Wemm 	}
1877c2aa98e2SPeter Wemm 
1878c2aa98e2SPeter Wemm 	if (tTd(3, 1))
187912ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla(): %.2f\n", avenrun);
1880c2aa98e2SPeter Wemm 
1881c2aa98e2SPeter Wemm 	return ((int) (avenrun + 0.5));
1882c2aa98e2SPeter Wemm }
1883c2aa98e2SPeter Wemm 
1884c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_PROCSTR */
1885c2aa98e2SPeter Wemm 
1886c2aa98e2SPeter Wemm #if LA_TYPE == LA_IRIX6
18873299c2f1SGregory Neil Shapiro 
1888c2aa98e2SPeter Wemm # include <sys/sysmp.h>
1889c2aa98e2SPeter Wemm 
1890bfb62e91SGregory Neil Shapiro # ifdef _UNICOSMP
1891bfb62e91SGregory Neil Shapiro #  define CAST_SYSMP(x)	(x)
18925b0945b5SGregory Neil Shapiro # else
1893bfb62e91SGregory Neil Shapiro #  define CAST_SYSMP(x)	((x) & 0x7fffffff)
18945b0945b5SGregory Neil Shapiro # endif
1895bfb62e91SGregory Neil Shapiro 
189612ed1c7cSGregory Neil Shapiro int
getla(void)189712ed1c7cSGregory Neil Shapiro getla(void)
1898c2aa98e2SPeter Wemm {
189912ed1c7cSGregory Neil Shapiro 	int j;
1900c2aa98e2SPeter Wemm 	static int kmem = -1;
1901c2aa98e2SPeter Wemm 	int avenrun[3];
1902c2aa98e2SPeter Wemm 
1903c2aa98e2SPeter Wemm 	if (kmem < 0)
1904c2aa98e2SPeter Wemm 	{
1905c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, 0, 0);
1906c2aa98e2SPeter Wemm 		if (kmem < 0)
1907c2aa98e2SPeter Wemm 		{
1908c2aa98e2SPeter Wemm 			if (tTd(3, 1))
190912ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM,
191012ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
1911c2aa98e2SPeter Wemm 			return -1;
1912c2aa98e2SPeter Wemm 		}
191312ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
191412ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
191512ed1c7cSGregory Neil Shapiro 		{
191612ed1c7cSGregory Neil Shapiro 			if (tTd(3, 1))
191712ed1c7cSGregory Neil Shapiro 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
191812ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
191912ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
192012ed1c7cSGregory Neil Shapiro 			kmem = -1;
192112ed1c7cSGregory Neil Shapiro 			return -1;
192212ed1c7cSGregory Neil Shapiro 		}
1923c2aa98e2SPeter Wemm 	}
1924c2aa98e2SPeter Wemm 
1925bfb62e91SGregory Neil Shapiro 	if (lseek(kmem, CAST_SYSMP(sysmp(MP_KERNADDR, MPKA_AVENRUN)), SEEK_SET)
1926bfb62e91SGregory Neil Shapiro 		== -1 ||
1927e3793f76SGregory Neil Shapiro 	    read(kmem, (char *) avenrun, sizeof(avenrun)) != sizeof(avenrun))
1928c2aa98e2SPeter Wemm 	{
1929c2aa98e2SPeter Wemm 		if (tTd(3, 1))
193012ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: lseek or read: %s\n",
193112ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1932c2aa98e2SPeter Wemm 		return -1;
1933c2aa98e2SPeter Wemm 	}
1934c2aa98e2SPeter Wemm 	if (tTd(3, 5))
1935c2aa98e2SPeter Wemm 	{
193612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]);
1937c2aa98e2SPeter Wemm 		if (tTd(3, 15))
193812ed1c7cSGregory Neil Shapiro 			sm_dprintf(", %ld, %ld",
1939c2aa98e2SPeter Wemm 				(long int) avenrun[1], (long int) avenrun[2]);
194012ed1c7cSGregory Neil Shapiro 		sm_dprintf("\n");
1941c2aa98e2SPeter Wemm 	}
1942c2aa98e2SPeter Wemm 
1943c2aa98e2SPeter Wemm 	if (tTd(3, 1))
194412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n",
19453299c2f1SGregory Neil Shapiro 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1946c2aa98e2SPeter Wemm 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
1947c2aa98e2SPeter Wemm 
1948c2aa98e2SPeter Wemm }
19493299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_IRIX6 */
1950c2aa98e2SPeter Wemm 
1951c2aa98e2SPeter Wemm #if LA_TYPE == LA_KSTAT
1952c2aa98e2SPeter Wemm 
1953c2aa98e2SPeter Wemm # include <kstat.h>
1954c2aa98e2SPeter Wemm 
195512ed1c7cSGregory Neil Shapiro int
getla()1956c2aa98e2SPeter Wemm getla()
1957c2aa98e2SPeter Wemm {
1958c2aa98e2SPeter Wemm 	static kstat_ctl_t *kc = NULL;
1959c2aa98e2SPeter Wemm 	static kstat_t *ksp = NULL;
1960c2aa98e2SPeter Wemm 	kstat_named_t *ksn;
1961c2aa98e2SPeter Wemm 	int la;
1962c2aa98e2SPeter Wemm 
1963c2aa98e2SPeter Wemm 	if (kc == NULL)		/* if not initialized before */
1964c2aa98e2SPeter Wemm 		kc = kstat_open();
1965c2aa98e2SPeter Wemm 	if (kc == NULL)
1966c2aa98e2SPeter Wemm 	{
1967c2aa98e2SPeter Wemm 		if (tTd(3, 1))
196812ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_open(): %s\n",
196912ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1970c2aa98e2SPeter Wemm 		return -1;
1971c2aa98e2SPeter Wemm 	}
1972c2aa98e2SPeter Wemm 	if (ksp == NULL)
1973c2aa98e2SPeter Wemm 		ksp = kstat_lookup(kc, "unix", 0, "system_misc");
1974c2aa98e2SPeter Wemm 	if (ksp == NULL)
1975c2aa98e2SPeter Wemm 	{
1976c2aa98e2SPeter Wemm 		if (tTd(3, 1))
197712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_lookup(): %s\n",
197812ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1979c2aa98e2SPeter Wemm 		return -1;
1980c2aa98e2SPeter Wemm 	}
1981c2aa98e2SPeter Wemm 	if (kstat_read(kc, ksp, NULL) < 0)
1982c2aa98e2SPeter Wemm 	{
1983c2aa98e2SPeter Wemm 		if (tTd(3, 1))
198412ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: kstat_read(): %s\n",
198512ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
1986c2aa98e2SPeter Wemm 		return -1;
1987c2aa98e2SPeter Wemm 	}
1988c2aa98e2SPeter Wemm 	ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
1989c2aa98e2SPeter Wemm 	la = ((double) ksn->value.ul + FSCALE/2) / FSCALE;
1990c2aa98e2SPeter Wemm 	/* kstat_close(kc); /o do not close for fast access */
1991c2aa98e2SPeter Wemm 	return la;
1992c2aa98e2SPeter Wemm }
1993c2aa98e2SPeter Wemm 
1994c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_KSTAT */
1995c2aa98e2SPeter Wemm 
1996c2aa98e2SPeter Wemm #if LA_TYPE == LA_DEVSHORT
1997c2aa98e2SPeter Wemm 
1998c2aa98e2SPeter Wemm /*
1999c2aa98e2SPeter Wemm **  Read /dev/table/avenrun for the load average.  This should contain
2000c2aa98e2SPeter Wemm **  three shorts for the 1, 5, and 15 minute loads.  We only read the
2001c2aa98e2SPeter Wemm **  first, since that's all we care about.
2002c2aa98e2SPeter Wemm **
2003c2aa98e2SPeter Wemm **	Intended for SCO OpenServer 5.
2004c2aa98e2SPeter Wemm */
2005c2aa98e2SPeter Wemm 
2006c2aa98e2SPeter Wemm # ifndef _PATH_AVENRUN
2007c2aa98e2SPeter Wemm #  define _PATH_AVENRUN	"/dev/table/avenrun"
20085b0945b5SGregory Neil Shapiro # endif
2009c2aa98e2SPeter Wemm 
201012ed1c7cSGregory Neil Shapiro int
getla()2011c2aa98e2SPeter Wemm getla()
2012c2aa98e2SPeter Wemm {
2013c2aa98e2SPeter Wemm 	static int afd = -1;
2014c2aa98e2SPeter Wemm 	short avenrun;
2015c2aa98e2SPeter Wemm 	int loadav;
2016c2aa98e2SPeter Wemm 	int r;
2017c2aa98e2SPeter Wemm 
2018c2aa98e2SPeter Wemm 	errno = EBADF;
2019c2aa98e2SPeter Wemm 
2020c2aa98e2SPeter Wemm 	if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
2021c2aa98e2SPeter Wemm 	{
2022c2aa98e2SPeter Wemm 		if (errno != EBADF)
2023c2aa98e2SPeter Wemm 			return -1;
2024c2aa98e2SPeter Wemm 		afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
2025c2aa98e2SPeter Wemm 		if (afd < 0)
2026c2aa98e2SPeter Wemm 		{
2027c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
202812ed1c7cSGregory Neil Shapiro 				"can't open %s: %s",
202912ed1c7cSGregory Neil Shapiro 				_PATH_AVENRUN, sm_errstring(errno));
2030c2aa98e2SPeter Wemm 			return -1;
2031c2aa98e2SPeter Wemm 		}
2032c2aa98e2SPeter Wemm 	}
2033c2aa98e2SPeter Wemm 
2034951742c4SGregory Neil Shapiro 	r = read(afd, &avenrun, sizeof(avenrun));
2035e3793f76SGregory Neil Shapiro 	if (r != sizeof(avenrun))
2036e3793f76SGregory Neil Shapiro 	{
2037e3793f76SGregory Neil Shapiro 		sm_syslog(LOG_ERR, NOQID,
2038e3793f76SGregory Neil Shapiro 			"can't read %s: %s", _PATH_AVENRUN,
2039e3793f76SGregory Neil Shapiro 			r == -1 ? sm_errstring(errno) : "short read");
2040e3793f76SGregory Neil Shapiro 		return -1;
2041e3793f76SGregory Neil Shapiro 	}
2042c2aa98e2SPeter Wemm 
2043c2aa98e2SPeter Wemm 	if (tTd(3, 5))
204412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: avenrun = %d\n", avenrun);
2045c2aa98e2SPeter Wemm 	loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
2046c2aa98e2SPeter Wemm 	if (tTd(3, 1))
204712ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", loadav);
2048c2aa98e2SPeter Wemm 	return loadav;
2049c2aa98e2SPeter Wemm }
2050c2aa98e2SPeter Wemm 
2051c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_DEVSHORT */
2052c2aa98e2SPeter Wemm 
2053c2aa98e2SPeter Wemm #if LA_TYPE == LA_ALPHAOSF
2054c2aa98e2SPeter Wemm struct rtentry;
2055c2aa98e2SPeter Wemm struct mbuf;
2056c2aa98e2SPeter Wemm # include <sys/table.h>
2057c2aa98e2SPeter Wemm 
205812ed1c7cSGregory Neil Shapiro int
getla()205912ed1c7cSGregory Neil Shapiro getla()
2060c2aa98e2SPeter Wemm {
2061c2aa98e2SPeter Wemm 	int ave = 0;
2062c2aa98e2SPeter Wemm 	struct tbl_loadavg tab;
2063c2aa98e2SPeter Wemm 
2064c2aa98e2SPeter Wemm 	if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
2065c2aa98e2SPeter Wemm 	{
2066c2aa98e2SPeter Wemm 		if (tTd(3, 1))
206712ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: table %s\n", sm_errstring(errno));
20683299c2f1SGregory Neil Shapiro 		return -1;
2069c2aa98e2SPeter Wemm 	}
2070c2aa98e2SPeter Wemm 
2071c2aa98e2SPeter Wemm 	if (tTd(3, 1))
207212ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: scale = %d\n", tab.tl_lscale);
2073c2aa98e2SPeter Wemm 
2074c2aa98e2SPeter Wemm 	if (tab.tl_lscale)
20753299c2f1SGregory Neil Shapiro 		ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) /
20763299c2f1SGregory Neil Shapiro 		       tab.tl_lscale);
2077c2aa98e2SPeter Wemm 	else
20783299c2f1SGregory Neil Shapiro 		ave = (int) (tab.tl_avenrun.d[2] + 0.5);
2079c2aa98e2SPeter Wemm 
2080c2aa98e2SPeter Wemm 	if (tTd(3, 1))
208112ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", ave);
2082c2aa98e2SPeter Wemm 
2083c2aa98e2SPeter Wemm 	return ave;
2084c2aa98e2SPeter Wemm }
2085c2aa98e2SPeter Wemm 
20863299c2f1SGregory Neil Shapiro #endif /* LA_TYPE == LA_ALPHAOSF */
2087c2aa98e2SPeter Wemm 
2088c46d91b7SGregory Neil Shapiro #if LA_TYPE == LA_PSET
2089c46d91b7SGregory Neil Shapiro 
209012ed1c7cSGregory Neil Shapiro int
getla()2091c46d91b7SGregory Neil Shapiro getla()
2092c46d91b7SGregory Neil Shapiro {
2093c46d91b7SGregory Neil Shapiro 	double avenrun[3];
2094c46d91b7SGregory Neil Shapiro 
2095c46d91b7SGregory Neil Shapiro 	if (pset_getloadavg(PS_MYID, avenrun,
2096c46d91b7SGregory Neil Shapiro 			    sizeof(avenrun) / sizeof(avenrun[0])) < 0)
2097c46d91b7SGregory Neil Shapiro 	{
2098c46d91b7SGregory Neil Shapiro 		if (tTd(3, 1))
209912ed1c7cSGregory Neil Shapiro 			sm_dprintf("getla: pset_getloadavg failed: %s",
210012ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
2101c46d91b7SGregory Neil Shapiro 		return -1;
2102c46d91b7SGregory Neil Shapiro 	}
2103c46d91b7SGregory Neil Shapiro 	if (tTd(3, 1))
210412ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
2105c46d91b7SGregory Neil Shapiro 	return ((int) (avenrun[0] + 0.5));
2106c46d91b7SGregory Neil Shapiro }
2107c46d91b7SGregory Neil Shapiro 
2108c46d91b7SGregory Neil Shapiro #endif /* LA_TYPE == LA_PSET */
2109c46d91b7SGregory Neil Shapiro 
2110c2aa98e2SPeter Wemm #if LA_TYPE == LA_ZERO
2111c2aa98e2SPeter Wemm 
211212ed1c7cSGregory Neil Shapiro int
getla()2113c2aa98e2SPeter Wemm getla()
2114c2aa98e2SPeter Wemm {
2115c2aa98e2SPeter Wemm 	if (tTd(3, 1))
211612ed1c7cSGregory Neil Shapiro 		sm_dprintf("getla: ZERO\n");
21173299c2f1SGregory Neil Shapiro 	return 0;
2118c2aa98e2SPeter Wemm }
2119c2aa98e2SPeter Wemm 
2120c2aa98e2SPeter Wemm #endif /* LA_TYPE == LA_ZERO */
2121c2aa98e2SPeter Wemm 
2122c2aa98e2SPeter Wemm /*
2123c2aa98e2SPeter Wemm  * Copyright 1989 Massachusetts Institute of Technology
2124c2aa98e2SPeter Wemm  *
2125c2aa98e2SPeter Wemm  * Permission to use, copy, modify, distribute, and sell this software and its
2126c2aa98e2SPeter Wemm  * documentation for any purpose is hereby granted without fee, provided that
2127c2aa98e2SPeter Wemm  * the above copyright notice appear in all copies and that both that
2128c2aa98e2SPeter Wemm  * copyright notice and this permission notice appear in supporting
2129c2aa98e2SPeter Wemm  * documentation, and that the name of M.I.T. not be used in advertising or
2130c2aa98e2SPeter Wemm  * publicity pertaining to distribution of the software without specific,
2131c2aa98e2SPeter Wemm  * written prior permission.  M.I.T. makes no representations about the
2132c2aa98e2SPeter Wemm  * suitability of this software for any purpose.  It is provided "as is"
2133c2aa98e2SPeter Wemm  * without express or implied warranty.
2134c2aa98e2SPeter Wemm  *
2135c2aa98e2SPeter Wemm  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
2136c2aa98e2SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
2137c2aa98e2SPeter Wemm  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2138c2aa98e2SPeter Wemm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2139c2aa98e2SPeter Wemm  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2140c2aa98e2SPeter Wemm  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2141c2aa98e2SPeter Wemm  *
2142c2aa98e2SPeter Wemm  * Authors:  Many and varied...
2143c2aa98e2SPeter Wemm  */
2144c2aa98e2SPeter Wemm 
2145c2aa98e2SPeter Wemm /* Non Apollo stuff removed by Don Lewis 11/15/93 */
2146c2aa98e2SPeter Wemm #ifndef lint
214712ed1c7cSGregory Neil Shapiro SM_UNUSED(static char  rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
21485b0945b5SGregory Neil Shapiro #endif
2149c2aa98e2SPeter Wemm 
2150c2aa98e2SPeter Wemm #ifdef apollo
2151c2aa98e2SPeter Wemm # undef volatile
2152c2aa98e2SPeter Wemm # include <apollo/base.h>
2153c2aa98e2SPeter Wemm 
2154c2aa98e2SPeter Wemm /* ARGSUSED */
getloadavg(call_data)2155c2aa98e2SPeter Wemm int getloadavg( call_data )
2156c2aa98e2SPeter Wemm 	caddr_t call_data;	/* pointer to (double) return value */
2157c2aa98e2SPeter Wemm {
2158c2aa98e2SPeter Wemm 	double *avenrun = (double *) call_data;
2159c2aa98e2SPeter Wemm 	int i;
2160c2aa98e2SPeter Wemm 	status_$t      st;
2161c2aa98e2SPeter Wemm 	long loadav[3];
216212ed1c7cSGregory Neil Shapiro 
2163c2aa98e2SPeter Wemm 	proc1_$get_loadav(loadav, &st);
2164c2aa98e2SPeter Wemm 	*avenrun = loadav[0] / (double) (1 << 16);
21653299c2f1SGregory Neil Shapiro 	return 0;
2166c2aa98e2SPeter Wemm }
2167c2aa98e2SPeter Wemm #endif /* apollo */
216812ed1c7cSGregory Neil Shapiro /*
216912ed1c7cSGregory Neil Shapiro **  SM_GETLA -- get the current load average
21703299c2f1SGregory Neil Shapiro **
21713299c2f1SGregory Neil Shapiro **	Parameters:
217212ed1c7cSGregory Neil Shapiro **		none
21733299c2f1SGregory Neil Shapiro **
21743299c2f1SGregory Neil Shapiro **	Returns:
217512ed1c7cSGregory Neil Shapiro **		none
21763299c2f1SGregory Neil Shapiro **
21773299c2f1SGregory Neil Shapiro **	Side Effects:
217812ed1c7cSGregory Neil Shapiro **		Set CurrentLA to the current load average.
217912ed1c7cSGregory Neil Shapiro **		Set {load_avg} in GlobalMacros to the current load average.
21803299c2f1SGregory Neil Shapiro */
21813299c2f1SGregory Neil Shapiro 
218212ed1c7cSGregory Neil Shapiro void
sm_getla()218312ed1c7cSGregory Neil Shapiro sm_getla()
21843299c2f1SGregory Neil Shapiro {
21853299c2f1SGregory Neil Shapiro 	char labuf[8];
21863299c2f1SGregory Neil Shapiro 
218712ed1c7cSGregory Neil Shapiro 	CurrentLA = getla();
2188951742c4SGregory Neil Shapiro 	(void) sm_snprintf(labuf, sizeof(labuf), "%d", CurrentLA);
218912ed1c7cSGregory Neil Shapiro 	macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf);
21903299c2f1SGregory Neil Shapiro }
219112ed1c7cSGregory Neil Shapiro /*
2192c2aa98e2SPeter Wemm **  SHOULDQUEUE -- should this message be queued or sent?
2193c2aa98e2SPeter Wemm **
2194c2aa98e2SPeter Wemm **	Compares the message cost to the load average to decide.
2195c2aa98e2SPeter Wemm **
219612ed1c7cSGregory Neil Shapiro **	Note: Do NOT change this API! It is documented in op.me
219712ed1c7cSGregory Neil Shapiro **		and theoretically the user can change this function...
219812ed1c7cSGregory Neil Shapiro **
2199c2aa98e2SPeter Wemm **	Parameters:
2200c2aa98e2SPeter Wemm **		pri -- the priority of the message in question.
220112ed1c7cSGregory Neil Shapiro **		ct -- the message creation time (unused, but see above).
2202c2aa98e2SPeter Wemm **
2203c2aa98e2SPeter Wemm **	Returns:
220412ed1c7cSGregory Neil Shapiro **		true -- if this message should be queued up for the
2205c2aa98e2SPeter Wemm **			time being.
220612ed1c7cSGregory Neil Shapiro **		false -- if the load is low enough to send this message.
2207c2aa98e2SPeter Wemm **
2208c2aa98e2SPeter Wemm **	Side Effects:
2209c2aa98e2SPeter Wemm **		none.
2210c2aa98e2SPeter Wemm */
2211c2aa98e2SPeter Wemm 
22123299c2f1SGregory Neil Shapiro /* ARGSUSED1 */
2213c2aa98e2SPeter Wemm bool
shouldqueue(pri,ct)22143299c2f1SGregory Neil Shapiro shouldqueue(pri, ct)
2215c2aa98e2SPeter Wemm 	long pri;
22163299c2f1SGregory Neil Shapiro 	time_t ct;
2217c2aa98e2SPeter Wemm {
2218c2aa98e2SPeter Wemm 	bool rval;
2219567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT
2220567a2fc9SGregory Neil Shapiro 	long memfree;
22215b0945b5SGregory Neil Shapiro #endif
2222c2aa98e2SPeter Wemm 
2223c2aa98e2SPeter Wemm 	if (tTd(3, 30))
222412ed1c7cSGregory Neil Shapiro 		sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
22253299c2f1SGregory Neil Shapiro 			CurrentLA, pri);
2226567a2fc9SGregory Neil Shapiro 
2227567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT
2228567a2fc9SGregory Neil Shapiro 	if (QueueLowMem > 0 &&
2229567a2fc9SGregory Neil Shapiro 	    sm_memstat_get(MemoryResource, &memfree) >= 0 &&
2230567a2fc9SGregory Neil Shapiro 	    memfree < QueueLowMem)
2231567a2fc9SGregory Neil Shapiro 	{
2232567a2fc9SGregory Neil Shapiro 		if (tTd(3, 30))
2233355d91e3SGregory Neil Shapiro 			sm_dprintf("true (memfree=%ld < QueueLowMem=%ld)\n",
2234567a2fc9SGregory Neil Shapiro 				memfree, QueueLowMem);
2235567a2fc9SGregory Neil Shapiro 		return true;
2236567a2fc9SGregory Neil Shapiro 	}
2237567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */
22383299c2f1SGregory Neil Shapiro 	if (CurrentLA < QueueLA)
2239c2aa98e2SPeter Wemm 	{
2240c2aa98e2SPeter Wemm 		if (tTd(3, 30))
224112ed1c7cSGregory Neil Shapiro 			sm_dprintf("false (CurrentLA < QueueLA)\n");
224212ed1c7cSGregory Neil Shapiro 		return false;
2243c2aa98e2SPeter Wemm 	}
22443299c2f1SGregory Neil Shapiro 	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
2245c2aa98e2SPeter Wemm 	if (tTd(3, 30))
224612ed1c7cSGregory Neil Shapiro 		sm_dprintf("%s (by calculation)\n", rval ? "true" : "false");
2247c2aa98e2SPeter Wemm 	return rval;
2248c2aa98e2SPeter Wemm }
2249951742c4SGregory Neil Shapiro 
225012ed1c7cSGregory Neil Shapiro /*
2251c2aa98e2SPeter Wemm **  REFUSECONNECTIONS -- decide if connections should be refused
2252c2aa98e2SPeter Wemm **
2253c2aa98e2SPeter Wemm **	Parameters:
22543299c2f1SGregory Neil Shapiro **		e -- the current envelope.
2255951742c4SGregory Neil Shapiro **		dn -- number of daemon.
225612ed1c7cSGregory Neil Shapiro **		active -- was this daemon actually active?
2257c2aa98e2SPeter Wemm **
2258c2aa98e2SPeter Wemm **	Returns:
225912ed1c7cSGregory Neil Shapiro **		true if incoming SMTP connections should be refused
2260c2aa98e2SPeter Wemm **			(for now).
226112ed1c7cSGregory Neil Shapiro **		false if we should accept new work.
2262c2aa98e2SPeter Wemm **
2263c2aa98e2SPeter Wemm **	Side Effects:
2264c2aa98e2SPeter Wemm **		Sets process title when it is rejecting connections.
2265c2aa98e2SPeter Wemm */
2266c2aa98e2SPeter Wemm 
2267c2aa98e2SPeter Wemm bool
refuseconnections(e,dn,active)2268951742c4SGregory Neil Shapiro refuseconnections(e, dn, active)
22693299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
2270951742c4SGregory Neil Shapiro 	int dn;
227112ed1c7cSGregory Neil Shapiro 	bool active;
2272c2aa98e2SPeter Wemm {
227312ed1c7cSGregory Neil Shapiro 	static time_t lastconn[MAXDAEMONS];
227412ed1c7cSGregory Neil Shapiro 	static int conncnt[MAXDAEMONS];
22752ef40764SGregory Neil Shapiro 	static time_t firstrejtime[MAXDAEMONS];
22762ef40764SGregory Neil Shapiro 	static time_t nextlogtime[MAXDAEMONS];
2277951742c4SGregory Neil Shapiro 	int limit;
2278567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT
2279567a2fc9SGregory Neil Shapiro 	long memfree;
22805b0945b5SGregory Neil Shapiro #endif
228112ed1c7cSGregory Neil Shapiro 
228212ed1c7cSGregory Neil Shapiro #if XLA
2283c2aa98e2SPeter Wemm 	if (!xla_smtp_ok())
228412ed1c7cSGregory Neil Shapiro 		return true;
22855b0945b5SGregory Neil Shapiro #endif
2286c2aa98e2SPeter Wemm 
2287951742c4SGregory Neil Shapiro 	SM_ASSERT(dn >= 0);
2288951742c4SGregory Neil Shapiro 	SM_ASSERT(dn < MAXDAEMONS);
228912ed1c7cSGregory Neil Shapiro 	if (ConnRateThrottle > 0)
229012ed1c7cSGregory Neil Shapiro 	{
229112ed1c7cSGregory Neil Shapiro 		time_t now;
229212ed1c7cSGregory Neil Shapiro 
229312ed1c7cSGregory Neil Shapiro 		now = curtime();
229412ed1c7cSGregory Neil Shapiro 		if (active)
229512ed1c7cSGregory Neil Shapiro 		{
2296951742c4SGregory Neil Shapiro 			if (now != lastconn[dn])
229712ed1c7cSGregory Neil Shapiro 			{
2298951742c4SGregory Neil Shapiro 				lastconn[dn] = now;
2299951742c4SGregory Neil Shapiro 				conncnt[dn] = 1;
230012ed1c7cSGregory Neil Shapiro 			}
2301951742c4SGregory Neil Shapiro 			else if (conncnt[dn]++ > ConnRateThrottle)
230212ed1c7cSGregory Neil Shapiro 			{
230312ed1c7cSGregory Neil Shapiro #define D_MSG_CRT "deferring connections on daemon %s: %d per second"
230412ed1c7cSGregory Neil Shapiro 				/* sleep to flatten out connection load */
230512ed1c7cSGregory Neil Shapiro 				sm_setproctitle(true, e, D_MSG_CRT,
2306951742c4SGregory Neil Shapiro 						Daemons[dn].d_name,
2307951742c4SGregory Neil Shapiro 						ConnRateThrottle);
230812ed1c7cSGregory Neil Shapiro 				if (LogLevel > 8)
230912ed1c7cSGregory Neil Shapiro 					sm_syslog(LOG_INFO, NOQID, D_MSG_CRT,
2310951742c4SGregory Neil Shapiro 						  Daemons[dn].d_name,
2311951742c4SGregory Neil Shapiro 						  ConnRateThrottle);
231212ed1c7cSGregory Neil Shapiro 				(void) sleep(1);
231312ed1c7cSGregory Neil Shapiro 			}
231412ed1c7cSGregory Neil Shapiro 		}
2315951742c4SGregory Neil Shapiro 		else if (now != lastconn[dn])
2316951742c4SGregory Neil Shapiro 			conncnt[dn] = 0;
231712ed1c7cSGregory Neil Shapiro 	}
231812ed1c7cSGregory Neil Shapiro 
2319567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT
2320567a2fc9SGregory Neil Shapiro 	if (RefuseLowMem > 0 &&
2321567a2fc9SGregory Neil Shapiro 	    sm_memstat_get(MemoryResource, &memfree) >= 0 &&
2322567a2fc9SGregory Neil Shapiro 	    memfree < RefuseLowMem)
2323567a2fc9SGregory Neil Shapiro 	{
2324567a2fc9SGregory Neil Shapiro # define R_MSG_LM "rejecting connections on daemon %s: free memory: %ld"
2325951742c4SGregory Neil Shapiro 		sm_setproctitle(true, e, R_MSG_LM, Daemons[dn].d_name, memfree);
2326567a2fc9SGregory Neil Shapiro 		if (LogLevel > 8)
2327951742c4SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, NOQID, R_MSG_LM,
2328951742c4SGregory Neil Shapiro 				Daemons[dn].d_name, memfree);
2329567a2fc9SGregory Neil Shapiro 		return true;
2330567a2fc9SGregory Neil Shapiro 	}
2331567a2fc9SGregory Neil Shapiro #endif /* _FFR_MEMSTAT */
233212ed1c7cSGregory Neil Shapiro 	sm_getla();
2333951742c4SGregory Neil Shapiro 	limit = (Daemons[dn].d_refuseLA != DPO_NOTSET) ?
2334951742c4SGregory Neil Shapiro 		Daemons[dn].d_refuseLA : RefuseLA;
2335951742c4SGregory Neil Shapiro 	if (limit > 0 && CurrentLA >= limit)
2336c2aa98e2SPeter Wemm 	{
23372ef40764SGregory Neil Shapiro 		time_t now;
23382ef40764SGregory Neil Shapiro 
233912ed1c7cSGregory Neil Shapiro # define R_MSG_LA "rejecting connections on daemon %s: load average: %d"
2340bfb62e91SGregory Neil Shapiro # define R2_MSG_LA "have been rejecting connections on daemon %s for %s"
2341951742c4SGregory Neil Shapiro 		sm_setproctitle(true, e, R_MSG_LA, Daemons[dn].d_name,
2342951742c4SGregory Neil Shapiro 				CurrentLA);
234312ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8)
2344951742c4SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, NOQID, R_MSG_LA,
2345951742c4SGregory Neil Shapiro 				Daemons[dn].d_name, CurrentLA);
23462ef40764SGregory Neil Shapiro 		now = curtime();
2347951742c4SGregory Neil Shapiro 		if (firstrejtime[dn] == 0)
23482ef40764SGregory Neil Shapiro 		{
2349951742c4SGregory Neil Shapiro 			firstrejtime[dn] = now;
2350951742c4SGregory Neil Shapiro 			nextlogtime[dn] = now + RejectLogInterval;
23512ef40764SGregory Neil Shapiro 		}
2352951742c4SGregory Neil Shapiro 		else if (nextlogtime[dn] < now)
23532ef40764SGregory Neil Shapiro 		{
2354951742c4SGregory Neil Shapiro 			sm_syslog(LOG_ERR, NOQID, R2_MSG_LA, Daemons[dn].d_name,
2355951742c4SGregory Neil Shapiro 				  pintvl(now - firstrejtime[dn], true));
2356951742c4SGregory Neil Shapiro 			nextlogtime[dn] = now + RejectLogInterval;
23572ef40764SGregory Neil Shapiro 		}
235812ed1c7cSGregory Neil Shapiro 		return true;
235912ed1c7cSGregory Neil Shapiro 	}
23602ef40764SGregory Neil Shapiro 	else
2361951742c4SGregory Neil Shapiro 		firstrejtime[dn] = 0;
236212ed1c7cSGregory Neil Shapiro 
2363951742c4SGregory Neil Shapiro 	limit = (Daemons[dn].d_delayLA != DPO_NOTSET) ?
2364951742c4SGregory Neil Shapiro 		Daemons[dn].d_delayLA : DelayLA;
2365951742c4SGregory Neil Shapiro 	if (limit > 0 && CurrentLA >= limit)
236612ed1c7cSGregory Neil Shapiro 	{
236712ed1c7cSGregory Neil Shapiro 		time_t now;
236812ed1c7cSGregory Neil Shapiro 		static time_t log_delay = (time_t) 0;
236912ed1c7cSGregory Neil Shapiro 
237012ed1c7cSGregory Neil Shapiro # define MIN_DELAY_LOG	90	/* wait before logging this again */
237112ed1c7cSGregory Neil Shapiro # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d"
237212ed1c7cSGregory Neil Shapiro 		/* sleep to flatten out connection load */
23739bd497b8SGregory Neil Shapiro 		sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name,
23749bd497b8SGregory Neil Shapiro 				CurrentLA, limit);
237512ed1c7cSGregory Neil Shapiro 		if (LogLevel > 8 && (now = curtime()) > log_delay)
237612ed1c7cSGregory Neil Shapiro 		{
237712ed1c7cSGregory Neil Shapiro 			sm_syslog(LOG_INFO, NOQID, D_MSG_LA,
2378951742c4SGregory Neil Shapiro 				  Daemons[dn].d_name, CurrentLA, limit);
237912ed1c7cSGregory Neil Shapiro 			log_delay = now + MIN_DELAY_LOG;
238012ed1c7cSGregory Neil Shapiro 		}
238112ed1c7cSGregory Neil Shapiro 		(void) sleep(1);
2382c2aa98e2SPeter Wemm 	}
2383c2aa98e2SPeter Wemm 
2384951742c4SGregory Neil Shapiro 	limit = (Daemons[dn].d_maxchildren != DPO_NOTSET) ?
2385951742c4SGregory Neil Shapiro 		Daemons[dn].d_maxchildren : MaxChildren;
2386951742c4SGregory Neil Shapiro 	if (limit > 0 && CurChildren >= limit)
2387c2aa98e2SPeter Wemm 	{
2388c2aa98e2SPeter Wemm 		proc_list_probe();
2389951742c4SGregory Neil Shapiro 		if (CurChildren >= limit)
2390c2aa98e2SPeter Wemm 		{
239112ed1c7cSGregory Neil Shapiro #define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d"
239212ed1c7cSGregory Neil Shapiro 			sm_setproctitle(true, e, R_MSG_CHILD,
2393951742c4SGregory Neil Shapiro 					Daemons[dn].d_name, CurChildren,
2394951742c4SGregory Neil Shapiro 					limit);
239512ed1c7cSGregory Neil Shapiro 			if (LogLevel > 8)
239612ed1c7cSGregory Neil Shapiro 				sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD,
2397951742c4SGregory Neil Shapiro 					Daemons[dn].d_name, CurChildren,
2398951742c4SGregory Neil Shapiro 					limit);
239912ed1c7cSGregory Neil Shapiro 			return true;
2400c2aa98e2SPeter Wemm 		}
2401c2aa98e2SPeter Wemm 	}
240212ed1c7cSGregory Neil Shapiro 	return false;
2403c2aa98e2SPeter Wemm }
2404951742c4SGregory Neil Shapiro 
240512ed1c7cSGregory Neil Shapiro /*
2406c2aa98e2SPeter Wemm **  SETPROCTITLE -- set process title for ps
2407c2aa98e2SPeter Wemm **
2408c2aa98e2SPeter Wemm **	Parameters:
2409c2aa98e2SPeter Wemm **		fmt -- a printf style format string.
2410c2aa98e2SPeter Wemm **		a, b, c -- possible parameters to fmt.
2411c2aa98e2SPeter Wemm **
2412c2aa98e2SPeter Wemm **	Returns:
2413c2aa98e2SPeter Wemm **		none.
2414c2aa98e2SPeter Wemm **
2415c2aa98e2SPeter Wemm **	Side Effects:
2416c2aa98e2SPeter Wemm **		Clobbers argv of our main procedure so ps(1) will
2417c2aa98e2SPeter Wemm **		display the title.
2418c2aa98e2SPeter Wemm */
2419c2aa98e2SPeter Wemm 
2420c2aa98e2SPeter Wemm #define SPT_NONE	0	/* don't use it at all */
2421c2aa98e2SPeter Wemm #define SPT_REUSEARGV	1	/* cover argv with title information */
2422c2aa98e2SPeter Wemm #define SPT_BUILTIN	2	/* use libc builtin */
2423c2aa98e2SPeter Wemm #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
2424c2aa98e2SPeter Wemm #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
2425c2aa98e2SPeter Wemm #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
2426c2aa98e2SPeter Wemm #define SPT_SCO		6	/* write kernel u. area */
2427c2aa98e2SPeter Wemm #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
2428c2aa98e2SPeter Wemm 
2429c2aa98e2SPeter Wemm #ifndef SPT_TYPE
2430c2aa98e2SPeter Wemm # define SPT_TYPE	SPT_REUSEARGV
24315b0945b5SGregory Neil Shapiro #endif
24323299c2f1SGregory Neil Shapiro 
2433c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
2434c2aa98e2SPeter Wemm 
2435c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSTAT
2436c2aa98e2SPeter Wemm #  include <sys/pstat.h>
24375b0945b5SGregory Neil Shapiro # endif
2438c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS
2439c2aa98e2SPeter Wemm #  include <machine/vmparam.h>
2440c2aa98e2SPeter Wemm #  include <sys/exec.h>
2441c2aa98e2SPeter Wemm #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
2442c2aa98e2SPeter Wemm #   undef SPT_TYPE
2443c2aa98e2SPeter Wemm #   define SPT_TYPE	SPT_REUSEARGV
24443299c2f1SGregory Neil Shapiro #  else /* ! PS_STRINGS */
2445c2aa98e2SPeter Wemm #   ifndef NKPDE			/* FreeBSD 2.0 */
2446c2aa98e2SPeter Wemm #    define NKPDE 63
2447c2aa98e2SPeter Wemm typedef unsigned int	*pt_entry_t;
24483299c2f1SGregory Neil Shapiro #   endif /* ! NKPDE */
24493299c2f1SGregory Neil Shapiro #  endif /* ! PS_STRINGS */
24503299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_PSSTRINGS */
2451c2aa98e2SPeter Wemm 
2452c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
2453c2aa98e2SPeter Wemm #  define SETPROC_STATIC	static
24545b0945b5SGregory Neil Shapiro # else
2455c2aa98e2SPeter Wemm #  define SETPROC_STATIC
24565b0945b5SGregory Neil Shapiro # endif
2457c2aa98e2SPeter Wemm 
2458c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SYSMIPS
2459c2aa98e2SPeter Wemm #  include <sys/sysmips.h>
2460c2aa98e2SPeter Wemm #  include <sys/sysnews.h>
24615b0945b5SGregory Neil Shapiro # endif
2462c2aa98e2SPeter Wemm 
2463c2aa98e2SPeter Wemm # if SPT_TYPE == SPT_SCO
2464c2aa98e2SPeter Wemm #  include <sys/immu.h>
2465c2aa98e2SPeter Wemm #  include <sys/dir.h>
2466c2aa98e2SPeter Wemm #  include <sys/user.h>
2467c2aa98e2SPeter Wemm #  include <sys/fs/s5param.h>
2468c2aa98e2SPeter Wemm #  if PSARGSZ > MAXLINE
2469c2aa98e2SPeter Wemm #   define SPT_BUFSIZE	PSARGSZ
24705b0945b5SGregory Neil Shapiro #  endif
24713299c2f1SGregory Neil Shapiro # endif /* SPT_TYPE == SPT_SCO */
2472c2aa98e2SPeter Wemm 
2473c2aa98e2SPeter Wemm # ifndef SPT_PADCHAR
2474c2aa98e2SPeter Wemm #  define SPT_PADCHAR	' '
24755b0945b5SGregory Neil Shapiro # endif
2476c2aa98e2SPeter Wemm 
247776b7bf71SPeter Wemm #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
247876b7bf71SPeter Wemm 
2479c2aa98e2SPeter Wemm #ifndef SPT_BUFSIZE
2480c2aa98e2SPeter Wemm # define SPT_BUFSIZE	MAXLINE
24815b0945b5SGregory Neil Shapiro #endif
2482c2aa98e2SPeter Wemm 
248388ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN
248488ad41d4SGregory Neil Shapiro 
248588ad41d4SGregory Neil Shapiro /*
248688ad41d4SGregory Neil Shapiro **  It looks like the Compaq Tru64 5.1A now aligns argv and envp to
248788ad41d4SGregory Neil Shapiro **  64 bit alignment, so unless each piece of argv and envp is a multiple
248888ad41d4SGregory Neil Shapiro **  of 8 bytes (including terminating NULL), initsetproctitle() won't use
248988ad41d4SGregory Neil Shapiro **  any of the space beyond argv[0].  Be sure to set SPT_ALIGN_SIZE if
249088ad41d4SGregory Neil Shapiro **  you use this FFR.
249188ad41d4SGregory Neil Shapiro */
249288ad41d4SGregory Neil Shapiro 
249388ad41d4SGregory Neil Shapiro # ifdef SPT_ALIGN_SIZE
2494f848909fSGregory Neil Shapiro #  define SPT_ALIGN(x, align)	(((((x) + SPT_ALIGN_SIZE) >> (align)) << (align)) - 1)
24955b0945b5SGregory Neil Shapiro # else
249688ad41d4SGregory Neil Shapiro #  define SPT_ALIGN(x, align)	(x)
24975b0945b5SGregory Neil Shapiro # endif
249888ad41d4SGregory Neil Shapiro #else /* _FFR_SPT_ALIGN */
249988ad41d4SGregory Neil Shapiro # define SPT_ALIGN(x, align)	(x)
250088ad41d4SGregory Neil Shapiro #endif /* _FFR_SPT_ALIGN */
250188ad41d4SGregory Neil Shapiro 
2502c2aa98e2SPeter Wemm /*
2503c2aa98e2SPeter Wemm **  Pointers for setproctitle.
2504c2aa98e2SPeter Wemm **	This allows "ps" listings to give more useful information.
2505c2aa98e2SPeter Wemm */
2506c2aa98e2SPeter Wemm 
25073299c2f1SGregory Neil Shapiro static char	**Argv = NULL;		/* pointer to argument vector */
25083299c2f1SGregory Neil Shapiro static char	*LastArgv = NULL;	/* end of argv */
25093299c2f1SGregory Neil Shapiro #if SPT_TYPE != SPT_BUILTIN
25103299c2f1SGregory Neil Shapiro static void	setproctitle __P((const char *, ...));
25115b0945b5SGregory Neil Shapiro #endif
2512c2aa98e2SPeter Wemm 
2513c2aa98e2SPeter Wemm void
initsetproctitle(argc,argv,envp)2514c2aa98e2SPeter Wemm initsetproctitle(argc, argv, envp)
2515c2aa98e2SPeter Wemm 	int argc;
2516c2aa98e2SPeter Wemm 	char **argv;
2517c2aa98e2SPeter Wemm 	char **envp;
2518c2aa98e2SPeter Wemm {
251912ed1c7cSGregory Neil Shapiro 	register int i;
25205b0945b5SGregory Neil Shapiro #if _FFR_SPT_ALIGN
252188ad41d4SGregory Neil Shapiro 	int align;
25225b0945b5SGregory Neil Shapiro #endif
2523c2aa98e2SPeter Wemm 	extern char **environ;
2524c2aa98e2SPeter Wemm 
2525c2aa98e2SPeter Wemm 	/*
2526c2aa98e2SPeter Wemm 	**  Move the environment so setproctitle can use the space at
2527c2aa98e2SPeter Wemm 	**  the top of memory.
2528c2aa98e2SPeter Wemm 	*/
2529c2aa98e2SPeter Wemm 
25309d8fddc1SGregory Neil Shapiro 	if (envp != NULL)
25319d8fddc1SGregory Neil Shapiro 	{
2532c2aa98e2SPeter Wemm 		for (i = 0; envp[i] != NULL; i++)
253312ed1c7cSGregory Neil Shapiro 			continue;
2534c2aa98e2SPeter Wemm 		environ = (char **) xalloc(sizeof(char *) * (i + 1));
2535c2aa98e2SPeter Wemm 		for (i = 0; envp[i] != NULL; i++)
2536c2aa98e2SPeter Wemm 			environ[i] = newstr(envp[i]);
2537c2aa98e2SPeter Wemm 		environ[i] = NULL;
25389d8fddc1SGregory Neil Shapiro 	}
2539c2aa98e2SPeter Wemm 
2540c2aa98e2SPeter Wemm 	/*
2541c2aa98e2SPeter Wemm 	**  Save start and extent of argv for setproctitle.
2542c2aa98e2SPeter Wemm 	*/
2543c2aa98e2SPeter Wemm 
2544c2aa98e2SPeter Wemm 	Argv = argv;
2545c2aa98e2SPeter Wemm 
2546c2aa98e2SPeter Wemm 	/*
2547c2aa98e2SPeter Wemm 	**  Determine how much space we can use for setproctitle.
2548c2aa98e2SPeter Wemm 	**  Use all contiguous argv and envp pointers starting at argv[0]
2549c2aa98e2SPeter Wemm 	*/
255088ad41d4SGregory Neil Shapiro 
255188ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN
25525b0945b5SGregory Neil Shapiro 	align = -1;
255388ad41d4SGregory Neil Shapiro # ifdef SPT_ALIGN_SIZE
255488ad41d4SGregory Neil Shapiro 	for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1)
255588ad41d4SGregory Neil Shapiro 		align++;
25565b0945b5SGregory Neil Shapiro # endif
255788ad41d4SGregory Neil Shapiro #endif /* _FFR_SPT_ALIGN */
255888ad41d4SGregory Neil Shapiro 
2559c2aa98e2SPeter Wemm 	for (i = 0; i < argc; i++)
2560c2aa98e2SPeter Wemm 	{
2561c2aa98e2SPeter Wemm 		if (i == 0 || LastArgv + 1 == argv[i])
256288ad41d4SGregory Neil Shapiro 			LastArgv = argv[i] + SPT_ALIGN(strlen(argv[i]), align);
2563c2aa98e2SPeter Wemm 	}
25649d8fddc1SGregory Neil Shapiro 	for (i = 0; LastArgv != NULL && envp != NULL && envp[i] != NULL; i++)
2565c2aa98e2SPeter Wemm 	{
2566c2aa98e2SPeter Wemm 		if (LastArgv + 1 == envp[i])
256788ad41d4SGregory Neil Shapiro 			LastArgv = envp[i] + SPT_ALIGN(strlen(envp[i]), align);
2568c2aa98e2SPeter Wemm 	}
2569c2aa98e2SPeter Wemm }
2570c2aa98e2SPeter Wemm 
2571c2aa98e2SPeter Wemm #if SPT_TYPE != SPT_BUILTIN
2572c2aa98e2SPeter Wemm 
2573c2aa98e2SPeter Wemm /*VARARGS1*/
25743299c2f1SGregory Neil Shapiro static void
2575c2aa98e2SPeter Wemm # ifdef __STDC__
setproctitle(const char * fmt,...)2576c2aa98e2SPeter Wemm setproctitle(const char *fmt, ...)
25773299c2f1SGregory Neil Shapiro # else /* __STDC__ */
2578c2aa98e2SPeter Wemm setproctitle(fmt, va_alist)
2579c2aa98e2SPeter Wemm 	const char *fmt;
2580c2aa98e2SPeter Wemm 	va_dcl
25813299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
2582c2aa98e2SPeter Wemm {
2583c2aa98e2SPeter Wemm # if SPT_TYPE != SPT_NONE
2584c2aa98e2SPeter Wemm 	register int i;
25853299c2f1SGregory Neil Shapiro 	register char *p;
2586c2aa98e2SPeter Wemm 	SETPROC_STATIC char buf[SPT_BUFSIZE];
258712ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
2588c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2589c2aa98e2SPeter Wemm 	union pstun pst;
25905b0945b5SGregory Neil Shapiro #  endif
2591c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
259212ed1c7cSGregory Neil Shapiro 	int j;
2593c2aa98e2SPeter Wemm 	off_t seek_off;
2594c2aa98e2SPeter Wemm 	static int kmem = -1;
2595c0c4794dSGregory Neil Shapiro 	static pid_t kmempid = -1;
2596c2aa98e2SPeter Wemm 	struct user u;
25973299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2598c2aa98e2SPeter Wemm 
2599c2aa98e2SPeter Wemm 	p = buf;
2600c2aa98e2SPeter Wemm 
2601c2aa98e2SPeter Wemm 	/* print sendmail: heading for grep */
260212ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
2603c2aa98e2SPeter Wemm 	p += strlen(p);
2604c2aa98e2SPeter Wemm 
2605c2aa98e2SPeter Wemm 	/* print the argument string */
260612ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
260712ed1c7cSGregory Neil Shapiro 	(void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
260812ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
2609c2aa98e2SPeter Wemm 
261012ed1c7cSGregory Neil Shapiro 	i = (int) strlen(buf);
261112ed1c7cSGregory Neil Shapiro 	if (i < 0)
261212ed1c7cSGregory Neil Shapiro 		return;
2613c2aa98e2SPeter Wemm 
2614c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSTAT
2615c2aa98e2SPeter Wemm 	pst.pst_command = buf;
2616c2aa98e2SPeter Wemm 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
26175b0945b5SGregory Neil Shapiro #  endif
2618c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_PSSTRINGS
2619c2aa98e2SPeter Wemm 	PS_STRINGS->ps_nargvstr = 1;
2620c2aa98e2SPeter Wemm 	PS_STRINGS->ps_argvstr = buf;
26215b0945b5SGregory Neil Shapiro #  endif
2622c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SYSMIPS
2623c2aa98e2SPeter Wemm 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
26245b0945b5SGregory Neil Shapiro #  endif
2625c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_SCO
262612ed1c7cSGregory Neil Shapiro 	if (kmem < 0 || kmempid != CurrentPid)
2627c2aa98e2SPeter Wemm 	{
2628c2aa98e2SPeter Wemm 		if (kmem >= 0)
2629c46d91b7SGregory Neil Shapiro 			(void) close(kmem);
2630c2aa98e2SPeter Wemm 		kmem = open(_PATH_KMEM, O_RDWR, 0);
2631c2aa98e2SPeter Wemm 		if (kmem < 0)
2632c2aa98e2SPeter Wemm 			return;
263312ed1c7cSGregory Neil Shapiro 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
263412ed1c7cSGregory Neil Shapiro 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
263512ed1c7cSGregory Neil Shapiro 		{
263612ed1c7cSGregory Neil Shapiro 			(void) close(kmem);
263712ed1c7cSGregory Neil Shapiro 			kmem = -1;
263812ed1c7cSGregory Neil Shapiro 			return;
263912ed1c7cSGregory Neil Shapiro 		}
264012ed1c7cSGregory Neil Shapiro 		kmempid = CurrentPid;
2641c2aa98e2SPeter Wemm 	}
2642c2aa98e2SPeter Wemm 	buf[PSARGSZ - 1] = '\0';
2643c2aa98e2SPeter Wemm 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
2644c2aa98e2SPeter Wemm 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
2645c2aa98e2SPeter Wemm 		(void) write(kmem, buf, PSARGSZ);
26463299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_SCO */
2647c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_REUSEARGV
26483299c2f1SGregory Neil Shapiro 	if (LastArgv == NULL)
26493299c2f1SGregory Neil Shapiro 		return;
26503299c2f1SGregory Neil Shapiro 
2651c2aa98e2SPeter Wemm 	if (i > LastArgv - Argv[0] - 2)
2652c2aa98e2SPeter Wemm 	{
2653c2aa98e2SPeter Wemm 		i = LastArgv - Argv[0] - 2;
2654c2aa98e2SPeter Wemm 		buf[i] = '\0';
2655c2aa98e2SPeter Wemm 	}
265612ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(Argv[0], buf, i + 1);
2657c2aa98e2SPeter Wemm 	p = &Argv[0][i];
2658c2aa98e2SPeter Wemm 	while (p < LastArgv)
2659c2aa98e2SPeter Wemm 		*p++ = SPT_PADCHAR;
2660c2aa98e2SPeter Wemm 	Argv[1] = NULL;
26613299c2f1SGregory Neil Shapiro #  endif /* SPT_TYPE == SPT_REUSEARGV */
2662c2aa98e2SPeter Wemm #  if SPT_TYPE == SPT_CHANGEARGV
2663c2aa98e2SPeter Wemm 	Argv[0] = buf;
26645b0945b5SGregory Neil Shapiro 	Argv[1] = NULL;
26655b0945b5SGregory Neil Shapiro #  endif
2666c2aa98e2SPeter Wemm # endif /* SPT_TYPE != SPT_NONE */
2667c2aa98e2SPeter Wemm }
2668c2aa98e2SPeter Wemm #endif /* SPT_TYPE != SPT_BUILTIN */
26695b0945b5SGregory Neil Shapiro 
267012ed1c7cSGregory Neil Shapiro /*
267176b7bf71SPeter Wemm **  SM_SETPROCTITLE -- set process task and set process title for ps
267276b7bf71SPeter Wemm **
267376b7bf71SPeter Wemm **	Possibly set process status and call setproctitle() to
267476b7bf71SPeter Wemm **	change the ps display.
267576b7bf71SPeter Wemm **
267676b7bf71SPeter Wemm **	Parameters:
267776b7bf71SPeter Wemm **		status -- whether or not to store as process status
26783299c2f1SGregory Neil Shapiro **		e -- the current envelope.
267976b7bf71SPeter Wemm **		fmt -- a printf style format string.
268076b7bf71SPeter Wemm **		a, b, c -- possible parameters to fmt.
268176b7bf71SPeter Wemm **
268276b7bf71SPeter Wemm **	Returns:
268376b7bf71SPeter Wemm **		none.
268476b7bf71SPeter Wemm */
268576b7bf71SPeter Wemm 
26866f9c8e5bSGregory Neil Shapiro /*VARARGS3*/
268776b7bf71SPeter Wemm void
268876b7bf71SPeter Wemm #ifdef __STDC__
sm_setproctitle(bool status,ENVELOPE * e,const char * fmt,...)26893299c2f1SGregory Neil Shapiro sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
26903299c2f1SGregory Neil Shapiro #else /* __STDC__ */
26913299c2f1SGregory Neil Shapiro sm_setproctitle(status, e, fmt, va_alist)
269276b7bf71SPeter Wemm 	bool status;
26933299c2f1SGregory Neil Shapiro 	ENVELOPE *e;
269476b7bf71SPeter Wemm 	const char *fmt;
269576b7bf71SPeter Wemm 	va_dcl
26963299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
269776b7bf71SPeter Wemm {
269876b7bf71SPeter Wemm 	char buf[SPT_BUFSIZE];
269912ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
27003299c2f1SGregory Neil Shapiro 
270176b7bf71SPeter Wemm 	/* print the argument string */
270212ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, fmt);
2703951742c4SGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof(buf), fmt, ap);
270412ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
270576b7bf71SPeter Wemm 
270676b7bf71SPeter Wemm 	if (status)
270712ed1c7cSGregory Neil Shapiro 		proc_list_set(CurrentPid, buf);
27083299c2f1SGregory Neil Shapiro 
27093299c2f1SGregory Neil Shapiro 	if (ProcTitlePrefix != NULL)
27103299c2f1SGregory Neil Shapiro 	{
27113299c2f1SGregory Neil Shapiro 		char prefix[SPT_BUFSIZE];
27123299c2f1SGregory Neil Shapiro 
2713951742c4SGregory Neil Shapiro 		expand(ProcTitlePrefix, prefix, sizeof(prefix), e);
27143299c2f1SGregory Neil Shapiro 		setproctitle("%s: %s", prefix, buf);
27153299c2f1SGregory Neil Shapiro 	}
27163299c2f1SGregory Neil Shapiro 	else
271776b7bf71SPeter Wemm 		setproctitle("%s", buf);
271876b7bf71SPeter Wemm }
271912ed1c7cSGregory Neil Shapiro /*
2720c2aa98e2SPeter Wemm **  WAITFOR -- wait for a particular process id.
2721c2aa98e2SPeter Wemm **
2722c2aa98e2SPeter Wemm **	Parameters:
2723c2aa98e2SPeter Wemm **		pid -- process id to wait for.
2724c2aa98e2SPeter Wemm **
2725c2aa98e2SPeter Wemm **	Returns:
2726c2aa98e2SPeter Wemm **		status of pid.
2727c2aa98e2SPeter Wemm **		-1 if pid never shows up.
2728c2aa98e2SPeter Wemm **
2729c2aa98e2SPeter Wemm **	Side Effects:
2730c2aa98e2SPeter Wemm **		none.
2731c2aa98e2SPeter Wemm */
2732c2aa98e2SPeter Wemm 
2733c2aa98e2SPeter Wemm int
waitfor(pid)2734c2aa98e2SPeter Wemm waitfor(pid)
2735c2aa98e2SPeter Wemm 	pid_t pid;
2736c2aa98e2SPeter Wemm {
273712ed1c7cSGregory Neil Shapiro 	int st;
273812ed1c7cSGregory Neil Shapiro 	pid_t i;
273912ed1c7cSGregory Neil Shapiro 
274012ed1c7cSGregory Neil Shapiro 	do
274112ed1c7cSGregory Neil Shapiro 	{
274212ed1c7cSGregory Neil Shapiro 		errno = 0;
274312ed1c7cSGregory Neil Shapiro 		i = sm_wait(&st);
274412ed1c7cSGregory Neil Shapiro 		if (i > 0)
274512ed1c7cSGregory Neil Shapiro 			proc_list_drop(i, st, NULL);
274612ed1c7cSGregory Neil Shapiro 	} while ((i >= 0 || errno == EINTR) && i != pid);
274712ed1c7cSGregory Neil Shapiro 	if (i < 0)
274812ed1c7cSGregory Neil Shapiro 		return -1;
274912ed1c7cSGregory Neil Shapiro 	return st;
275012ed1c7cSGregory Neil Shapiro }
275112ed1c7cSGregory Neil Shapiro /*
275212ed1c7cSGregory Neil Shapiro **  SM_WAIT -- wait
275312ed1c7cSGregory Neil Shapiro **
275412ed1c7cSGregory Neil Shapiro **	Parameters:
275512ed1c7cSGregory Neil Shapiro **		status -- pointer to status (return value)
275612ed1c7cSGregory Neil Shapiro **
275712ed1c7cSGregory Neil Shapiro **	Returns:
275812ed1c7cSGregory Neil Shapiro **		pid
275912ed1c7cSGregory Neil Shapiro */
276012ed1c7cSGregory Neil Shapiro 
276112ed1c7cSGregory Neil Shapiro pid_t
sm_wait(status)276212ed1c7cSGregory Neil Shapiro sm_wait(status)
276312ed1c7cSGregory Neil Shapiro 	int *status;
276412ed1c7cSGregory Neil Shapiro {
2765c2aa98e2SPeter Wemm #ifdef WAITUNION
2766c2aa98e2SPeter Wemm 	union wait st;
27675b0945b5SGregory Neil Shapiro #else
2768c2aa98e2SPeter Wemm 	auto int st;
27695b0945b5SGregory Neil Shapiro #endif
2770c2aa98e2SPeter Wemm 	pid_t i;
2771c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_)
2772c2aa98e2SPeter Wemm 	int savesig;
27735b0945b5SGregory Neil Shapiro #endif
2774c2aa98e2SPeter Wemm 
2775c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_)
277612ed1c7cSGregory Neil Shapiro 	savesig = sm_releasesignal(SIGCHLD);
27775b0945b5SGregory Neil Shapiro #endif
2778c2aa98e2SPeter Wemm 	i = wait(&st);
2779c2aa98e2SPeter Wemm #if defined(ISC_UNIX) || defined(_SCO_unix_)
2780c2aa98e2SPeter Wemm 	if (savesig > 0)
278112ed1c7cSGregory Neil Shapiro 		sm_blocksignal(SIGCHLD);
27825b0945b5SGregory Neil Shapiro #endif
2783c2aa98e2SPeter Wemm #ifdef WAITUNION
278412ed1c7cSGregory Neil Shapiro 	*status = st.w_status;
27855b0945b5SGregory Neil Shapiro #else
278612ed1c7cSGregory Neil Shapiro 	*status = st;
27875b0945b5SGregory Neil Shapiro #endif
278812ed1c7cSGregory Neil Shapiro 	return i;
2789c2aa98e2SPeter Wemm }
279012ed1c7cSGregory Neil Shapiro /*
2791c2aa98e2SPeter Wemm **  REAPCHILD -- pick up the body of my child, lest it become a zombie
2792c2aa98e2SPeter Wemm **
2793c2aa98e2SPeter Wemm **	Parameters:
2794c2aa98e2SPeter Wemm **		sig -- the signal that got us here (unused).
2795c2aa98e2SPeter Wemm **
2796c2aa98e2SPeter Wemm **	Returns:
2797c2aa98e2SPeter Wemm **		none.
2798c2aa98e2SPeter Wemm **
2799c2aa98e2SPeter Wemm **	Side Effects:
2800c2aa98e2SPeter Wemm **		Picks up extant zombies.
28013299c2f1SGregory Neil Shapiro **		Control socket exits may restart/shutdown daemon.
2802c0c4794dSGregory Neil Shapiro **
2803c0c4794dSGregory Neil Shapiro **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
2804c0c4794dSGregory Neil Shapiro **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
2805c0c4794dSGregory Neil Shapiro **		DOING.
2806c2aa98e2SPeter Wemm */
2807c2aa98e2SPeter Wemm 
28083299c2f1SGregory Neil Shapiro /* ARGSUSED0 */
2809c2aa98e2SPeter Wemm SIGFUNC_DECL
reapchild(sig)2810c2aa98e2SPeter Wemm reapchild(sig)
2811c2aa98e2SPeter Wemm 	int sig;
2812c2aa98e2SPeter Wemm {
28133299c2f1SGregory Neil Shapiro 	int save_errno = errno;
28143299c2f1SGregory Neil Shapiro 	int st;
2815c2aa98e2SPeter Wemm 	pid_t pid;
28163299c2f1SGregory Neil Shapiro #if HASWAITPID
2817c2aa98e2SPeter Wemm 	auto int status;
2818c2aa98e2SPeter Wemm 	int count;
2819c2aa98e2SPeter Wemm 
2820c2aa98e2SPeter Wemm 	count = 0;
2821c2aa98e2SPeter Wemm 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2822c2aa98e2SPeter Wemm 	{
28233299c2f1SGregory Neil Shapiro 		st = status;
2824c2aa98e2SPeter Wemm 		if (count++ > 1000)
2825c2aa98e2SPeter Wemm 			break;
28263299c2f1SGregory Neil Shapiro #else /* HASWAITPID */
2827c2aa98e2SPeter Wemm # ifdef WNOHANG
282812ed1c7cSGregory Neil Shapiro 	union wait status;
282912ed1c7cSGregory Neil Shapiro 
2830c2aa98e2SPeter Wemm 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
28313299c2f1SGregory Neil Shapiro 	{
28323299c2f1SGregory Neil Shapiro 		st = status.w_status;
2833c2aa98e2SPeter Wemm # else /* WNOHANG */
283412ed1c7cSGregory Neil Shapiro 	auto int status;
283512ed1c7cSGregory Neil Shapiro 
2836c2aa98e2SPeter Wemm 	/*
2837c2aa98e2SPeter Wemm 	**  Catch one zombie -- we will be re-invoked (we hope) if there
2838c2aa98e2SPeter Wemm 	**  are more.  Unreliable signals probably break this, but this
2839c2aa98e2SPeter Wemm 	**  is the "old system" situation -- waitpid or wait3 are to be
2840c2aa98e2SPeter Wemm 	**  strongly preferred.
2841c2aa98e2SPeter Wemm 	*/
2842c2aa98e2SPeter Wemm 
2843c2aa98e2SPeter Wemm 	if ((pid = wait(&status)) > 0)
28443299c2f1SGregory Neil Shapiro 	{
28453299c2f1SGregory Neil Shapiro 		st = status;
2846c2aa98e2SPeter Wemm # endif /* WNOHANG */
28473299c2f1SGregory Neil Shapiro #endif /* HASWAITPID */
28483299c2f1SGregory Neil Shapiro 		/* Drop PID and check if it was a control socket child */
284912ed1c7cSGregory Neil Shapiro 		proc_list_drop(pid, st, NULL);
28503299c2f1SGregory Neil Shapiro 	}
2851c0c4794dSGregory Neil Shapiro 	FIX_SYSV_SIGNAL(sig, reapchild);
28523299c2f1SGregory Neil Shapiro 	errno = save_errno;
2853c2aa98e2SPeter Wemm 	return SIGFUNC_RETURN;
2854c2aa98e2SPeter Wemm }
2855c2aa98e2SPeter Wemm /*
2856da7d7b9cSGregory Neil Shapiro **  GETDTSIZE -- return number of file descriptors
2857c2aa98e2SPeter Wemm **
2858c2aa98e2SPeter Wemm **	Only on non-BSD systems
2859c2aa98e2SPeter Wemm **
2860c2aa98e2SPeter Wemm **	Parameters:
2861c2aa98e2SPeter Wemm **		none
2862c2aa98e2SPeter Wemm **
2863c2aa98e2SPeter Wemm **	Returns:
2864c2aa98e2SPeter Wemm **		size of file descriptor table
2865c2aa98e2SPeter Wemm **
2866c2aa98e2SPeter Wemm **	Side Effects:
2867c2aa98e2SPeter Wemm **		none
2868c2aa98e2SPeter Wemm */
2869c2aa98e2SPeter Wemm 
2870c2aa98e2SPeter Wemm #ifdef SOLARIS
2871c2aa98e2SPeter Wemm # include <sys/resource.h>
28725b0945b5SGregory Neil Shapiro #endif
2873c2aa98e2SPeter Wemm 
2874c2aa98e2SPeter Wemm int
getdtsize()2875c2aa98e2SPeter Wemm getdtsize()
2876c2aa98e2SPeter Wemm {
2877c2aa98e2SPeter Wemm #ifdef RLIMIT_NOFILE
2878c2aa98e2SPeter Wemm 	struct rlimit rl;
2879c2aa98e2SPeter Wemm 
2880c2aa98e2SPeter Wemm 	if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2881c2aa98e2SPeter Wemm 		return rl.rlim_cur;
28823299c2f1SGregory Neil Shapiro #endif /* RLIMIT_NOFILE */
2883c2aa98e2SPeter Wemm 
28843299c2f1SGregory Neil Shapiro #if HASGETDTABLESIZE
2885c2aa98e2SPeter Wemm 	return getdtablesize();
28863299c2f1SGregory Neil Shapiro #else /* HASGETDTABLESIZE */
2887c2aa98e2SPeter Wemm # ifdef _SC_OPEN_MAX
2888c2aa98e2SPeter Wemm 	return sysconf(_SC_OPEN_MAX);
28895b0945b5SGregory Neil Shapiro # else
2890c2aa98e2SPeter Wemm 	return NOFILE;
28915b0945b5SGregory Neil Shapiro # endif
28923299c2f1SGregory Neil Shapiro #endif /* HASGETDTABLESIZE */
2893c2aa98e2SPeter Wemm }
289412ed1c7cSGregory Neil Shapiro /*
2895c2aa98e2SPeter Wemm **  UNAME -- get the UUCP name of this system.
2896c2aa98e2SPeter Wemm */
2897c2aa98e2SPeter Wemm 
28983299c2f1SGregory Neil Shapiro #if !HASUNAME
2899c2aa98e2SPeter Wemm 
2900c2aa98e2SPeter Wemm int
uname(name)2901c2aa98e2SPeter Wemm uname(name)
2902c2aa98e2SPeter Wemm 	struct utsname *name;
2903c2aa98e2SPeter Wemm {
290412ed1c7cSGregory Neil Shapiro 	SM_FILE_T *file;
2905c2aa98e2SPeter Wemm 	char *n;
2906c2aa98e2SPeter Wemm 
2907c2aa98e2SPeter Wemm 	name->nodename[0] = '\0';
2908c2aa98e2SPeter Wemm 
2909c2aa98e2SPeter Wemm 	/* try /etc/whoami -- one line with the node name */
291012ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami",
291112ed1c7cSGregory Neil Shapiro 			       SM_IO_RDONLY, NULL)) != NULL)
2912c2aa98e2SPeter Wemm 	{
291312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename,
291412ed1c7cSGregory Neil Shapiro 				   NODE_LENGTH + 1);
291512ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2916c2aa98e2SPeter Wemm 		n = strchr(name->nodename, '\n');
2917c2aa98e2SPeter Wemm 		if (n != NULL)
2918c2aa98e2SPeter Wemm 			*n = '\0';
2919c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
29203299c2f1SGregory Neil Shapiro 			return 0;
2921c2aa98e2SPeter Wemm 	}
2922c2aa98e2SPeter Wemm 
2923c2aa98e2SPeter Wemm 	/* try /usr/include/whoami.h -- has a #define somewhere */
292412ed1c7cSGregory Neil Shapiro 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT,
292512ed1c7cSGregory Neil Shapiro 			       "/usr/include/whoami.h", SM_IO_RDONLY, NULL))
292612ed1c7cSGregory Neil Shapiro 	    != NULL)
2927c2aa98e2SPeter Wemm 	{
2928c2aa98e2SPeter Wemm 		char buf[MAXLINE];
2929c2aa98e2SPeter Wemm 
293088ad41d4SGregory Neil Shapiro 		while (sm_io_fgets(file, SM_TIME_DEFAULT,
2931552d4955SGregory Neil Shapiro 				   buf, sizeof(buf)) >= 0)
29323299c2f1SGregory Neil Shapiro 		{
293312ed1c7cSGregory Neil Shapiro 			if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"",
2934c2aa98e2SPeter Wemm 					NODE_LENGTH, name->nodename) > 0)
2935c2aa98e2SPeter Wemm 				break;
29363299c2f1SGregory Neil Shapiro 		}
293712ed1c7cSGregory Neil Shapiro 		(void) sm_io_close(file, SM_TIME_DEFAULT);
2938c2aa98e2SPeter Wemm 		if (name->nodename[0] != '\0')
29393299c2f1SGregory Neil Shapiro 			return 0;
2940c2aa98e2SPeter Wemm 	}
2941c2aa98e2SPeter Wemm 
29423299c2f1SGregory Neil Shapiro 	return -1;
2943c2aa98e2SPeter Wemm }
29443299c2f1SGregory Neil Shapiro #endif /* !HASUNAME */
294512ed1c7cSGregory Neil Shapiro /*
2946c2aa98e2SPeter Wemm **  INITGROUPS -- initialize groups
2947c2aa98e2SPeter Wemm **
2948c2aa98e2SPeter Wemm **	Stub implementation for System V style systems
2949c2aa98e2SPeter Wemm */
2950c2aa98e2SPeter Wemm 
29513299c2f1SGregory Neil Shapiro #if !HASINITGROUPS
29522fb4f839SGregory Neil Shapiro int
initgroups(name,basegid)2953c2aa98e2SPeter Wemm initgroups(name, basegid)
2954c2aa98e2SPeter Wemm 	char *name;
2955c2aa98e2SPeter Wemm 	int basegid;
2956c2aa98e2SPeter Wemm {
2957c2aa98e2SPeter Wemm 	return 0;
2958c2aa98e2SPeter Wemm }
29593299c2f1SGregory Neil Shapiro #endif /* !HASINITGROUPS */
29605b0945b5SGregory Neil Shapiro 
296112ed1c7cSGregory Neil Shapiro /*
2962c2aa98e2SPeter Wemm **  SETGROUPS -- set group list
2963c2aa98e2SPeter Wemm **
2964c2aa98e2SPeter Wemm **	Stub implementation for systems that don't have group lists
2965c2aa98e2SPeter Wemm */
2966c2aa98e2SPeter Wemm 
2967c2aa98e2SPeter Wemm #ifndef NGROUPS_MAX
2968c2aa98e2SPeter Wemm int
setgroups(ngroups,grouplist)2969c2aa98e2SPeter Wemm setgroups(ngroups, grouplist)
2970c2aa98e2SPeter Wemm 	int ngroups;
2971c2aa98e2SPeter Wemm 	GIDSET_T grouplist[];
2972c2aa98e2SPeter Wemm {
2973c2aa98e2SPeter Wemm 	return 0;
2974c2aa98e2SPeter Wemm }
29753299c2f1SGregory Neil Shapiro #endif /* ! NGROUPS_MAX */
29765b0945b5SGregory Neil Shapiro 
297712ed1c7cSGregory Neil Shapiro /*
2978c2aa98e2SPeter Wemm **  SETSID -- set session id (for non-POSIX systems)
2979c2aa98e2SPeter Wemm */
2980c2aa98e2SPeter Wemm 
29813299c2f1SGregory Neil Shapiro #if !HASSETSID
2982c2aa98e2SPeter Wemm 
2983c2aa98e2SPeter Wemm pid_t
setsid(void)2984c2aa98e2SPeter Wemm setsid __P ((void))
2985c2aa98e2SPeter Wemm {
2986c2aa98e2SPeter Wemm # ifdef TIOCNOTTY
2987c2aa98e2SPeter Wemm 	int fd;
2988c2aa98e2SPeter Wemm 
2989c2aa98e2SPeter Wemm 	fd = open("/dev/tty", O_RDWR, 0);
2990c2aa98e2SPeter Wemm 	if (fd >= 0)
2991c2aa98e2SPeter Wemm 	{
2992d995d2baSGregory Neil Shapiro 		(void) ioctl(fd, TIOCNOTTY, (char *) 0);
2993c2aa98e2SPeter Wemm 		(void) close(fd);
2994c2aa98e2SPeter Wemm 	}
2995c2aa98e2SPeter Wemm # endif /* TIOCNOTTY */
2996c2aa98e2SPeter Wemm # ifdef SYS5SETPGRP
2997c2aa98e2SPeter Wemm 	return setpgrp();
29985b0945b5SGregory Neil Shapiro # else
299912ed1c7cSGregory Neil Shapiro 	return setpgid(0, CurrentPid);
30005b0945b5SGregory Neil Shapiro # endif
3001c2aa98e2SPeter Wemm }
3002c2aa98e2SPeter Wemm 
30033299c2f1SGregory Neil Shapiro #endif /* !HASSETSID */
300412ed1c7cSGregory Neil Shapiro /*
3005c2aa98e2SPeter Wemm **  FSYNC -- dummy fsync
3006c2aa98e2SPeter Wemm */
3007c2aa98e2SPeter Wemm 
30083299c2f1SGregory Neil Shapiro #if NEEDFSYNC
30092fb4f839SGregory Neil Shapiro int
fsync(fd)3010c2aa98e2SPeter Wemm fsync(fd)
3011c2aa98e2SPeter Wemm 	int fd;
3012c2aa98e2SPeter Wemm {
3013c2aa98e2SPeter Wemm # ifdef O_SYNC
3014c2aa98e2SPeter Wemm 	return fcntl(fd, F_SETFL, O_SYNC);
30155b0945b5SGregory Neil Shapiro # else
3016c2aa98e2SPeter Wemm 	/* nothing we can do */
3017c2aa98e2SPeter Wemm 	return 0;
30185b0945b5SGregory Neil Shapiro # endif
3019c2aa98e2SPeter Wemm }
30203299c2f1SGregory Neil Shapiro #endif /* NEEDFSYNC */
30215b0945b5SGregory Neil Shapiro 
302212ed1c7cSGregory Neil Shapiro /*
3023c2aa98e2SPeter Wemm **  DGUX_INET_ADDR -- inet_addr for DG/UX
3024c2aa98e2SPeter Wemm **
3025c2aa98e2SPeter Wemm **	Data General DG/UX version of inet_addr returns a struct in_addr
3026c2aa98e2SPeter Wemm **	instead of a long.  This patches things.  Only needed on versions
3027c2aa98e2SPeter Wemm **	prior to 5.4.3.
3028c2aa98e2SPeter Wemm */
3029c2aa98e2SPeter Wemm 
3030c2aa98e2SPeter Wemm #ifdef DGUX_5_4_2
3031c2aa98e2SPeter Wemm 
3032c2aa98e2SPeter Wemm # undef inet_addr
3033c2aa98e2SPeter Wemm 
3034c2aa98e2SPeter Wemm long
dgux_inet_addr(host)3035c2aa98e2SPeter Wemm dgux_inet_addr(host)
3036c2aa98e2SPeter Wemm 	char *host;
3037c2aa98e2SPeter Wemm {
3038c2aa98e2SPeter Wemm 	struct in_addr haddr;
3039c2aa98e2SPeter Wemm 
3040c2aa98e2SPeter Wemm 	haddr = inet_addr(host);
3041c2aa98e2SPeter Wemm 	return haddr.s_addr;
3042c2aa98e2SPeter Wemm }
3043c2aa98e2SPeter Wemm 
30443299c2f1SGregory Neil Shapiro #endif /* DGUX_5_4_2 */
304512ed1c7cSGregory Neil Shapiro /*
3046c2aa98e2SPeter Wemm **  GETOPT -- for old systems or systems with bogus implementations
3047c2aa98e2SPeter Wemm */
3048c2aa98e2SPeter Wemm 
304912ed1c7cSGregory Neil Shapiro #if !SM_CONF_GETOPT
3050c2aa98e2SPeter Wemm 
3051c2aa98e2SPeter Wemm /*
3052c2aa98e2SPeter Wemm  * Copyright (c) 1985 Regents of the University of California.
3053c2aa98e2SPeter Wemm  * All rights reserved.  The Berkeley software License Agreement
3054c2aa98e2SPeter Wemm  * specifies the terms and conditions for redistribution.
3055c2aa98e2SPeter Wemm  */
3056c2aa98e2SPeter Wemm 
3057c2aa98e2SPeter Wemm /*
3058c2aa98e2SPeter Wemm **  this version hacked to add `atend' flag to allow state machine
3059c2aa98e2SPeter Wemm **  to reset if invoked by the program to scan args for a 2nd time
3060c2aa98e2SPeter Wemm */
3061c2aa98e2SPeter Wemm 
3062c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
3063c2aa98e2SPeter Wemm static char sccsid[] = "@(#)getopt.c	4.3 (Berkeley) 3/9/86";
30645b0945b5SGregory Neil Shapiro # endif
3065c2aa98e2SPeter Wemm 
3066c2aa98e2SPeter Wemm /*
306712ed1c7cSGregory Neil Shapiro **  get option letter from argument vector
3068c2aa98e2SPeter Wemm */
3069c2aa98e2SPeter Wemm # ifdef _CONVEX_SOURCE
3070c2aa98e2SPeter Wemm extern int	optind, opterr, optopt;
3071c2aa98e2SPeter Wemm extern char	*optarg;
30723299c2f1SGregory Neil Shapiro # else /* _CONVEX_SOURCE */
3073c2aa98e2SPeter Wemm int	opterr = 1;		/* if error message should be printed */
3074c2aa98e2SPeter Wemm int	optind = 1;		/* index into parent argv vector */
3075c2aa98e2SPeter Wemm int	optopt = 0;		/* character checked for validity */
3076c2aa98e2SPeter Wemm char	*optarg = NULL;		/* argument associated with option */
30773299c2f1SGregory Neil Shapiro # endif /* _CONVEX_SOURCE */
3078c2aa98e2SPeter Wemm 
3079c2aa98e2SPeter Wemm # define BADCH	(int)'?'
3080c2aa98e2SPeter Wemm # define EMSG	""
308112ed1c7cSGregory Neil Shapiro # define tell(s)	if (opterr) \
308212ed1c7cSGregory Neil Shapiro 			{sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \
308312ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \
308412ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \
308512ed1c7cSGregory Neil Shapiro 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \
308612ed1c7cSGregory Neil Shapiro 			return BADCH;}
3087c2aa98e2SPeter Wemm 
3088c2aa98e2SPeter Wemm int
getopt(nargc,nargv,ostr)3089c2aa98e2SPeter Wemm getopt(nargc,nargv,ostr)
3090c2aa98e2SPeter Wemm 	int		nargc;
3091c2aa98e2SPeter Wemm 	char *const	*nargv;
3092c2aa98e2SPeter Wemm 	const char	*ostr;
3093c2aa98e2SPeter Wemm {
3094c2aa98e2SPeter Wemm 	static char	*place = EMSG;	/* option letter processing */
3095c2aa98e2SPeter Wemm 	static char	atend = 0;
3096c2aa98e2SPeter Wemm 	register char	*oli = NULL;	/* option letter list index */
3097c2aa98e2SPeter Wemm 
3098c2aa98e2SPeter Wemm 	if (atend) {
3099c2aa98e2SPeter Wemm 		atend = 0;
3100c2aa98e2SPeter Wemm 		place = EMSG;
3101c2aa98e2SPeter Wemm 	}
3102c2aa98e2SPeter Wemm 	if(!*place) {			/* update scanning pointer */
3103c2aa98e2SPeter Wemm 		if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
3104c2aa98e2SPeter Wemm 			atend++;
3105c2aa98e2SPeter Wemm 			return -1;
3106c2aa98e2SPeter Wemm 		}
3107c2aa98e2SPeter Wemm 		if (*place == '-') {	/* found "--" */
3108c2aa98e2SPeter Wemm 			++optind;
3109c2aa98e2SPeter Wemm 			atend++;
3110c2aa98e2SPeter Wemm 			return -1;
3111c2aa98e2SPeter Wemm 		}
3112c2aa98e2SPeter Wemm 	}				/* option letter okay? */
3113c2aa98e2SPeter Wemm 	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
3114c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3115c2aa98e2SPeter Wemm 		tell(": illegal option -- ");
3116c2aa98e2SPeter Wemm 	}
3117c2aa98e2SPeter Wemm 	if (oli && *++oli != ':') {		/* don't need argument */
3118c2aa98e2SPeter Wemm 		optarg = NULL;
3119c2aa98e2SPeter Wemm 		if (!*place) ++optind;
3120c2aa98e2SPeter Wemm 	}
3121c2aa98e2SPeter Wemm 	else {				/* need an argument */
3122c2aa98e2SPeter Wemm 		if (*place) optarg = place;	/* no white space */
3123c2aa98e2SPeter Wemm 		else if (nargc <= ++optind) {	/* no arg */
3124c2aa98e2SPeter Wemm 			place = EMSG;
3125c2aa98e2SPeter Wemm 			tell(": option requires an argument -- ");
3126c2aa98e2SPeter Wemm 		}
3127c2aa98e2SPeter Wemm 		else optarg = nargv[optind];	/* white space */
3128c2aa98e2SPeter Wemm 		place = EMSG;
3129c2aa98e2SPeter Wemm 		++optind;
3130c2aa98e2SPeter Wemm 	}
313112ed1c7cSGregory Neil Shapiro 	return optopt;			/* dump back option letter */
3132c2aa98e2SPeter Wemm }
3133c2aa98e2SPeter Wemm 
313412ed1c7cSGregory Neil Shapiro #endif /* !SM_CONF_GETOPT */
313512ed1c7cSGregory Neil Shapiro /*
3136c2aa98e2SPeter Wemm **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
3137c2aa98e2SPeter Wemm **
3138c2aa98e2SPeter Wemm **	Parameters:
3139c2aa98e2SPeter Wemm **		user -- the name of the user we are checking.
3140c2aa98e2SPeter Wemm **		shell -- the user's shell from /etc/passwd
3141c2aa98e2SPeter Wemm **
3142c2aa98e2SPeter Wemm **	Returns:
314312ed1c7cSGregory Neil Shapiro **		true -- if it is ok to use this for unrestricted access.
314412ed1c7cSGregory Neil Shapiro **		false -- if the shell is restricted.
3145c2aa98e2SPeter Wemm */
3146c2aa98e2SPeter Wemm 
3147c2aa98e2SPeter Wemm #if !HASGETUSERSHELL
3148c2aa98e2SPeter Wemm 
3149c2aa98e2SPeter Wemm # ifndef _PATH_SHELLS
3150c2aa98e2SPeter Wemm #  define _PATH_SHELLS	"/etc/shells"
31515b0945b5SGregory Neil Shapiro # endif
3152c2aa98e2SPeter Wemm 
3153c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3154c2aa98e2SPeter Wemm #  include <userconf.h>
3155c2aa98e2SPeter Wemm #  if _AIX4 >= 40200
3156c2aa98e2SPeter Wemm #   include <userpw.h>
31575b0945b5SGregory Neil Shapiro #  endif
3158c2aa98e2SPeter Wemm #  include <usersec.h>
31593299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
3160c2aa98e2SPeter Wemm 
31613299c2f1SGregory Neil Shapiro static char	*DefaultUserShells[] =
3162c2aa98e2SPeter Wemm {
3163c2aa98e2SPeter Wemm 	"/bin/sh",		/* standard shell */
316412ed1c7cSGregory Neil Shapiro # ifdef MPE
316512ed1c7cSGregory Neil Shapiro 	"/SYS/PUB/CI",
316612ed1c7cSGregory Neil Shapiro # else /* MPE */
3167c2aa98e2SPeter Wemm 	"/usr/bin/sh",
3168c2aa98e2SPeter Wemm 	"/bin/csh",		/* C shell */
3169c2aa98e2SPeter Wemm 	"/usr/bin/csh",
317012ed1c7cSGregory Neil Shapiro # endif /* MPE */
3171c2aa98e2SPeter Wemm # ifdef __hpux
3172c2aa98e2SPeter Wemm #  ifdef V4FS
3173c2aa98e2SPeter Wemm 	"/usr/bin/rsh",		/* restricted Bourne shell */
3174c2aa98e2SPeter Wemm 	"/usr/bin/ksh",		/* Korn shell */
3175c2aa98e2SPeter Wemm 	"/usr/bin/rksh",	/* restricted Korn shell */
3176c2aa98e2SPeter Wemm 	"/usr/bin/pam",
3177c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3178c2aa98e2SPeter Wemm 	"/usr/bin/posix/sh",
31793299c2f1SGregory Neil Shapiro #  else /* V4FS */
3180c2aa98e2SPeter Wemm 	"/bin/rsh",		/* restricted Bourne shell */
3181c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3182c2aa98e2SPeter Wemm 	"/bin/rksh",		/* restricted Korn shell */
3183c2aa98e2SPeter Wemm 	"/bin/pam",
3184c2aa98e2SPeter Wemm 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
3185c2aa98e2SPeter Wemm 	"/bin/posix/sh",
318672936242SGregory Neil Shapiro 	"/sbin/sh",
31873299c2f1SGregory Neil Shapiro #  endif /* V4FS */
31883299c2f1SGregory Neil Shapiro # endif /* __hpux */
3189c2aa98e2SPeter Wemm # if defined(_AIX3) || defined(_AIX4)
3190c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3191c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
3192c2aa98e2SPeter Wemm 	"/bin/tsh",		/* trusted shell */
3193c2aa98e2SPeter Wemm 	"/usr/bin/tsh",
3194c2aa98e2SPeter Wemm 	"/bin/bsh",		/* Bourne shell */
3195c2aa98e2SPeter Wemm 	"/usr/bin/bsh",
31963299c2f1SGregory Neil Shapiro # endif /* defined(_AIX3) || defined(_AIX4) */
319776b7bf71SPeter Wemm # if defined(__svr4__) || defined(__svr5__)
3198c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3199c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
32003299c2f1SGregory Neil Shapiro # endif /* defined(__svr4__) || defined(__svr5__) */
3201c2aa98e2SPeter Wemm # ifdef sgi
3202c2aa98e2SPeter Wemm 	"/sbin/sh",		/* SGI's shells really live in /sbin */
32039d8fddc1SGregory Neil Shapiro 	"/usr/bin/sh",
32042ef40764SGregory Neil Shapiro 	"/sbin/bsh",		/* classic Bourne shell */
32059d8fddc1SGregory Neil Shapiro 	"/bin/bsh",
32069d8fddc1SGregory Neil Shapiro 	"/usr/bin/bsh",
32079d8fddc1SGregory Neil Shapiro 	"/sbin/csh",		/* standard csh */
32089d8fddc1SGregory Neil Shapiro 	"/bin/csh",
32099d8fddc1SGregory Neil Shapiro 	"/usr/bin/csh",
32102ef40764SGregory Neil Shapiro 	"/sbin/jsh",		/* classic Bourne shell w/ job control*/
32119d8fddc1SGregory Neil Shapiro 	"/bin/jsh",
32129d8fddc1SGregory Neil Shapiro 	"/usr/bin/jsh",
3213c2aa98e2SPeter Wemm 	"/bin/ksh",		/* Korn shell */
3214c2aa98e2SPeter Wemm 	"/sbin/ksh",
3215c2aa98e2SPeter Wemm 	"/usr/bin/ksh",
32169d8fddc1SGregory Neil Shapiro 	"/sbin/tcsh",		/* Extended csh */
32179d8fddc1SGregory Neil Shapiro 	"/bin/tcsh",
3218c2aa98e2SPeter Wemm 	"/usr/bin/tcsh",
32193299c2f1SGregory Neil Shapiro # endif /* sgi */
3220c2aa98e2SPeter Wemm 	NULL
3221c2aa98e2SPeter Wemm };
3222c2aa98e2SPeter Wemm 
32233299c2f1SGregory Neil Shapiro #endif /* !HASGETUSERSHELL */
3224c2aa98e2SPeter Wemm 
3225c2aa98e2SPeter Wemm #define WILDCARD_SHELL	"/SENDMAIL/ANY/SHELL/"
3226c2aa98e2SPeter Wemm 
3227c2aa98e2SPeter Wemm bool
usershellok(user,shell)3228c2aa98e2SPeter Wemm usershellok(user, shell)
3229c2aa98e2SPeter Wemm 	char *user;
3230c2aa98e2SPeter Wemm 	char *shell;
3231c2aa98e2SPeter Wemm {
3232c2aa98e2SPeter Wemm #if HASGETUSERSHELL
3233c2aa98e2SPeter Wemm 	register char *p;
32342fb4f839SGregory Neil Shapiro 	extern char *getusershell __P((void));
3235c2aa98e2SPeter Wemm 
3236c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3237c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
323812ed1c7cSGregory Neil Shapiro 		return true;
3239c2aa98e2SPeter Wemm 
3240c2aa98e2SPeter Wemm 	setusershell();
3241c2aa98e2SPeter Wemm 	while ((p = getusershell()) != NULL)
3242c2aa98e2SPeter Wemm 		if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
3243c2aa98e2SPeter Wemm 			break;
3244c2aa98e2SPeter Wemm 	endusershell();
3245c2aa98e2SPeter Wemm 	return p != NULL;
32463299c2f1SGregory Neil Shapiro #else /* HASGETUSERSHELL */
3247c2aa98e2SPeter Wemm # if USEGETCONFATTR
3248c2aa98e2SPeter Wemm 	auto char *v;
32495b0945b5SGregory Neil Shapiro # endif
325012ed1c7cSGregory Neil Shapiro 	register SM_FILE_T *shellf;
3251c2aa98e2SPeter Wemm 	char buf[MAXLINE];
3252c2aa98e2SPeter Wemm 
3253c2aa98e2SPeter Wemm 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
3254c2aa98e2SPeter Wemm 	    ConfigLevel <= 1)
325512ed1c7cSGregory Neil Shapiro 		return true;
3256c2aa98e2SPeter Wemm 
3257c2aa98e2SPeter Wemm # if USEGETCONFATTR
3258c2aa98e2SPeter Wemm 	/*
3259c2aa98e2SPeter Wemm 	**  Naturally IBM has a "better" idea.....
3260c2aa98e2SPeter Wemm 	**
3261c2aa98e2SPeter Wemm 	**	What a crock.  This interface isn't documented, it is
3262c2aa98e2SPeter Wemm 	**	considered part of the security library (-ls), and it
3263c2aa98e2SPeter Wemm 	**	only works if you are running as root (since the list
3264c2aa98e2SPeter Wemm 	**	of valid shells is obviously a source of great concern).
3265c2aa98e2SPeter Wemm 	**	I recommend that you do NOT define USEGETCONFATTR,
3266c2aa98e2SPeter Wemm 	**	especially since you are going to have to set up an
3267c2aa98e2SPeter Wemm 	**	/etc/shells anyhow to handle the cases where getconfattr
3268c2aa98e2SPeter Wemm 	**	fails.
3269c2aa98e2SPeter Wemm 	*/
3270c2aa98e2SPeter Wemm 
3271c2aa98e2SPeter Wemm 	if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
3272c2aa98e2SPeter Wemm 	{
3273c2aa98e2SPeter Wemm 		while (*v != '\0')
3274c2aa98e2SPeter Wemm 		{
3275c2aa98e2SPeter Wemm 			if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
327612ed1c7cSGregory Neil Shapiro 				return true;
3277c2aa98e2SPeter Wemm 			v += strlen(v) + 1;
3278c2aa98e2SPeter Wemm 		}
327912ed1c7cSGregory Neil Shapiro 		return false;
3280c2aa98e2SPeter Wemm 	}
32813299c2f1SGregory Neil Shapiro # endif /* USEGETCONFATTR */
3282c2aa98e2SPeter Wemm 
328312ed1c7cSGregory Neil Shapiro 	shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS,
328412ed1c7cSGregory Neil Shapiro 			    SM_IO_RDONLY, NULL);
3285c2aa98e2SPeter Wemm 	if (shellf == NULL)
3286c2aa98e2SPeter Wemm 	{
3287c2aa98e2SPeter Wemm 		/* no /etc/shells; see if it is one of the std shells */
3288c2aa98e2SPeter Wemm 		char **d;
3289c2aa98e2SPeter Wemm 
3290c2aa98e2SPeter Wemm 		if (errno != ENOENT && LogLevel > 3)
3291c2aa98e2SPeter Wemm 			sm_syslog(LOG_ERR, NOQID,
3292c2aa98e2SPeter Wemm 				  "usershellok: cannot open %s: %s",
329312ed1c7cSGregory Neil Shapiro 				  _PATH_SHELLS, sm_errstring(errno));
3294c2aa98e2SPeter Wemm 
3295c2aa98e2SPeter Wemm 		for (d = DefaultUserShells; *d != NULL; d++)
3296c2aa98e2SPeter Wemm 		{
3297c2aa98e2SPeter Wemm 			if (strcmp(shell, *d) == 0)
329812ed1c7cSGregory Neil Shapiro 				return true;
3299c2aa98e2SPeter Wemm 		}
330012ed1c7cSGregory Neil Shapiro 		return false;
3301c2aa98e2SPeter Wemm 	}
3302c2aa98e2SPeter Wemm 
3303552d4955SGregory Neil Shapiro 	while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
3304c2aa98e2SPeter Wemm 	{
3305c2aa98e2SPeter Wemm 		register char *p, *q;
3306c2aa98e2SPeter Wemm 
3307c2aa98e2SPeter Wemm 		p = buf;
3308c2aa98e2SPeter Wemm 		while (*p != '\0' && *p != '#' && *p != '/')
3309c2aa98e2SPeter Wemm 			p++;
3310c2aa98e2SPeter Wemm 		if (*p == '#' || *p == '\0')
3311c2aa98e2SPeter Wemm 			continue;
3312c2aa98e2SPeter Wemm 		q = p;
33135b0945b5SGregory Neil Shapiro 		while (*p != '\0' && *p != '#' && !(SM_ISSPACE(*p)))
3314c2aa98e2SPeter Wemm 			p++;
3315c2aa98e2SPeter Wemm 		*p = '\0';
3316c2aa98e2SPeter Wemm 		if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
3317c2aa98e2SPeter Wemm 		{
331812ed1c7cSGregory Neil Shapiro 			(void) sm_io_close(shellf, SM_TIME_DEFAULT);
331912ed1c7cSGregory Neil Shapiro 			return true;
3320c2aa98e2SPeter Wemm 		}
3321c2aa98e2SPeter Wemm 	}
332212ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(shellf, SM_TIME_DEFAULT);
332312ed1c7cSGregory Neil Shapiro 	return false;
33243299c2f1SGregory Neil Shapiro #endif /* HASGETUSERSHELL */
3325c2aa98e2SPeter Wemm }
332612ed1c7cSGregory Neil Shapiro /*
3327c2aa98e2SPeter Wemm **  FREEDISKSPACE -- see how much free space is on the queue filesystem
3328c2aa98e2SPeter Wemm **
3329c2aa98e2SPeter Wemm **	Only implemented if you have statfs.
3330c2aa98e2SPeter Wemm **
3331c2aa98e2SPeter Wemm **	Parameters:
3332c2aa98e2SPeter Wemm **		dir -- the directory in question.
3333c2aa98e2SPeter Wemm **		bsize -- a variable into which the filesystem
3334c2aa98e2SPeter Wemm **			block size is stored.
3335c2aa98e2SPeter Wemm **
3336c2aa98e2SPeter Wemm **	Returns:
33373299c2f1SGregory Neil Shapiro **		The number of blocks free on the queue filesystem.
3338c2aa98e2SPeter Wemm **		-1 if the statfs call fails.
3339c2aa98e2SPeter Wemm **
3340c2aa98e2SPeter Wemm **	Side effects:
3341c2aa98e2SPeter Wemm **		Puts the filesystem block size into bsize.
3342c2aa98e2SPeter Wemm */
3343c2aa98e2SPeter Wemm 
3344c2aa98e2SPeter Wemm /* statfs types */
3345c2aa98e2SPeter Wemm #define SFS_NONE	0	/* no statfs implementation */
3346c2aa98e2SPeter Wemm #define SFS_USTAT	1	/* use ustat */
3347c2aa98e2SPeter Wemm #define SFS_4ARGS	2	/* use four-argument statfs call */
3348c2aa98e2SPeter Wemm #define SFS_VFS	3	/* use <sys/vfs.h> implementation */
3349c2aa98e2SPeter Wemm #define SFS_MOUNT	4	/* use <sys/mount.h> implementation */
3350c2aa98e2SPeter Wemm #define SFS_STATFS	5	/* use <sys/statfs.h> implementation */
3351c2aa98e2SPeter Wemm #define SFS_STATVFS	6	/* use <sys/statvfs.h> implementation */
3352c2aa98e2SPeter Wemm 
3353c2aa98e2SPeter Wemm #ifndef SFS_TYPE
3354c2aa98e2SPeter Wemm # define SFS_TYPE	SFS_NONE
33555b0945b5SGregory Neil Shapiro #endif
3356c2aa98e2SPeter Wemm 
3357c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_USTAT
3358c2aa98e2SPeter Wemm # include <ustat.h>
33595b0945b5SGregory Neil Shapiro #endif
3360c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
3361c2aa98e2SPeter Wemm # include <sys/statfs.h>
33625b0945b5SGregory Neil Shapiro #endif
3363c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_VFS
3364c2aa98e2SPeter Wemm # include <sys/vfs.h>
33655b0945b5SGregory Neil Shapiro #endif
3366c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_MOUNT
3367c2aa98e2SPeter Wemm # include <sys/mount.h>
33685b0945b5SGregory Neil Shapiro #endif
3369c2aa98e2SPeter Wemm #if SFS_TYPE == SFS_STATVFS
3370c2aa98e2SPeter Wemm # include <sys/statvfs.h>
33715b0945b5SGregory Neil Shapiro #endif
3372c2aa98e2SPeter Wemm 
3373c2aa98e2SPeter Wemm long
freediskspace(dir,bsize)3374c2aa98e2SPeter Wemm freediskspace(dir, bsize)
3375951742c4SGregory Neil Shapiro 	const char *dir;
3376c2aa98e2SPeter Wemm 	long *bsize;
3377c2aa98e2SPeter Wemm {
337812ed1c7cSGregory Neil Shapiro #if SFS_TYPE == SFS_NONE
337912ed1c7cSGregory Neil Shapiro 	if (bsize != NULL)
338012ed1c7cSGregory Neil Shapiro 		*bsize = 4096L;
338112ed1c7cSGregory Neil Shapiro 
338212ed1c7cSGregory Neil Shapiro 	/* assume free space is plentiful */
338312ed1c7cSGregory Neil Shapiro 	return (long) LONG_MAX;
338412ed1c7cSGregory Neil Shapiro #else /* SFS_TYPE == SFS_NONE */
3385c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT
3386c2aa98e2SPeter Wemm 	struct ustat fs;
3387c2aa98e2SPeter Wemm 	struct stat statbuf;
3388c2aa98e2SPeter Wemm #  define FSBLOCKSIZE	DEV_BSIZE
3389c2aa98e2SPeter Wemm #  define SFS_BAVAIL	f_tfree
33903299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_USTAT */
3391c2aa98e2SPeter Wemm #  if defined(ultrix)
3392c2aa98e2SPeter Wemm 	struct fs_data fs;
3393c2aa98e2SPeter Wemm #   define SFS_BAVAIL	fd_bfreen
3394c2aa98e2SPeter Wemm #   define FSBLOCKSIZE	1024L
33953299c2f1SGregory Neil Shapiro #  else /* defined(ultrix) */
3396c2aa98e2SPeter Wemm #   if SFS_TYPE == SFS_STATVFS
3397c2aa98e2SPeter Wemm 	struct statvfs fs;
3398c2aa98e2SPeter Wemm #    define FSBLOCKSIZE	fs.f_frsize
33993299c2f1SGregory Neil Shapiro #   else /* SFS_TYPE == SFS_STATVFS */
3400c2aa98e2SPeter Wemm 	struct statfs fs;
3401c2aa98e2SPeter Wemm #    define FSBLOCKSIZE	fs.f_bsize
34023299c2f1SGregory Neil Shapiro #   endif /* SFS_TYPE == SFS_STATVFS */
34033299c2f1SGregory Neil Shapiro #  endif /* defined(ultrix) */
34043299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */
3405c2aa98e2SPeter Wemm # ifndef SFS_BAVAIL
3406c2aa98e2SPeter Wemm #  define SFS_BAVAIL f_bavail
34075b0945b5SGregory Neil Shapiro # endif
3408c2aa98e2SPeter Wemm 
3409c2aa98e2SPeter Wemm # if SFS_TYPE == SFS_USTAT
3410c2aa98e2SPeter Wemm 	if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
34113299c2f1SGregory Neil Shapiro # else /* SFS_TYPE == SFS_USTAT */
3412c2aa98e2SPeter Wemm #  if SFS_TYPE == SFS_4ARGS
3413951742c4SGregory Neil Shapiro 	if (statfs(dir, &fs, sizeof(fs), 0) == 0)
34143299c2f1SGregory Neil Shapiro #  else /* SFS_TYPE == SFS_4ARGS */
3415c2aa98e2SPeter Wemm #   if SFS_TYPE == SFS_STATVFS
3416c2aa98e2SPeter Wemm 	if (statvfs(dir, &fs) == 0)
34173299c2f1SGregory Neil Shapiro #   else /* SFS_TYPE == SFS_STATVFS */
3418c2aa98e2SPeter Wemm #    if defined(ultrix)
3419c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) > 0)
34203299c2f1SGregory Neil Shapiro #    else /* defined(ultrix) */
3421c2aa98e2SPeter Wemm 	if (statfs(dir, &fs) == 0)
34223299c2f1SGregory Neil Shapiro #    endif /* defined(ultrix) */
34233299c2f1SGregory Neil Shapiro #   endif /* SFS_TYPE == SFS_STATVFS */
34243299c2f1SGregory Neil Shapiro #  endif /* SFS_TYPE == SFS_4ARGS */
34253299c2f1SGregory Neil Shapiro # endif /* SFS_TYPE == SFS_USTAT */
3426c2aa98e2SPeter Wemm 	{
3427c2aa98e2SPeter Wemm 		if (bsize != NULL)
3428c2aa98e2SPeter Wemm 			*bsize = FSBLOCKSIZE;
3429c2aa98e2SPeter Wemm 		if (fs.SFS_BAVAIL <= 0)
3430c2aa98e2SPeter Wemm 			return 0;
3431c2aa98e2SPeter Wemm 		else if (fs.SFS_BAVAIL > LONG_MAX)
34323299c2f1SGregory Neil Shapiro 			return (long) LONG_MAX;
3433c2aa98e2SPeter Wemm 		else
3434c2aa98e2SPeter Wemm 			return (long) fs.SFS_BAVAIL;
3435c2aa98e2SPeter Wemm 	}
34363299c2f1SGregory Neil Shapiro 	return -1;
343712ed1c7cSGregory Neil Shapiro #endif /* SFS_TYPE == SFS_NONE */
3438c2aa98e2SPeter Wemm }
343912ed1c7cSGregory Neil Shapiro /*
344012ed1c7cSGregory Neil Shapiro **  ENOUGHDISKSPACE -- is there enough free space on the queue file systems?
3441c2aa98e2SPeter Wemm **
3442c2aa98e2SPeter Wemm **	Parameters:
3443c2aa98e2SPeter Wemm **		msize -- the size to check against.  If zero, we don't yet
3444c2aa98e2SPeter Wemm **		know how big the message will be, so just check for
3445c2aa98e2SPeter Wemm **		a "reasonable" amount.
344612ed1c7cSGregory Neil Shapiro **		e -- envelope, or NULL -- controls logging
3447c2aa98e2SPeter Wemm **
3448c2aa98e2SPeter Wemm **	Returns:
344912ed1c7cSGregory Neil Shapiro **		true if in every queue group there is at least one
345012ed1c7cSGregory Neil Shapiro **		queue directory whose file system contains enough free space.
345112ed1c7cSGregory Neil Shapiro **		false otherwise.
345212ed1c7cSGregory Neil Shapiro **
345312ed1c7cSGregory Neil Shapiro **	Side Effects:
345412ed1c7cSGregory Neil Shapiro **		If there is not enough disk space and e != NULL
345512ed1c7cSGregory Neil Shapiro **		then sm_syslog is called.
3456c2aa98e2SPeter Wemm */
3457c2aa98e2SPeter Wemm 
3458c2aa98e2SPeter Wemm bool
enoughdiskspace(msize,e)345912ed1c7cSGregory Neil Shapiro enoughdiskspace(msize, e)
3460c2aa98e2SPeter Wemm 	long msize;
346112ed1c7cSGregory Neil Shapiro 	ENVELOPE *e;
3462c2aa98e2SPeter Wemm {
346312ed1c7cSGregory Neil Shapiro 	int i;
3464c2aa98e2SPeter Wemm 
34659bd497b8SGregory Neil Shapiro #if _FFR_TESTS
34669bd497b8SGregory Neil Shapiro 	if (tTd(4, 101))
34679bd497b8SGregory Neil Shapiro 		return false;
34685b0945b5SGregory Neil Shapiro #endif
3469c2aa98e2SPeter Wemm 	if (MinBlocksFree <= 0 && msize <= 0)
3470c2aa98e2SPeter Wemm 	{
3471c2aa98e2SPeter Wemm 		if (tTd(4, 80))
347212ed1c7cSGregory Neil Shapiro 			sm_dprintf("enoughdiskspace: no threshold\n");
347312ed1c7cSGregory Neil Shapiro 		return true;
3474c2aa98e2SPeter Wemm 	}
3475c2aa98e2SPeter Wemm 
347612ed1c7cSGregory Neil Shapiro 	filesys_update();
347712ed1c7cSGregory Neil Shapiro 	for (i = 0; i < NumQueue; ++i)
3478c2aa98e2SPeter Wemm 	{
347912ed1c7cSGregory Neil Shapiro 		if (pickqdir(Queue[i], msize, e) < 0)
348012ed1c7cSGregory Neil Shapiro 			return false;
3481c2aa98e2SPeter Wemm 	}
348212ed1c7cSGregory Neil Shapiro 	return true;
3483c2aa98e2SPeter Wemm }
348412ed1c7cSGregory Neil Shapiro /*
3485c2aa98e2SPeter Wemm **  TRANSIENTERROR -- tell if an error code indicates a transient failure
3486c2aa98e2SPeter Wemm **
3487c2aa98e2SPeter Wemm **	This looks at an errno value and tells if this is likely to
3488c2aa98e2SPeter Wemm **	go away if retried later.
3489c2aa98e2SPeter Wemm **
3490c2aa98e2SPeter Wemm **	Parameters:
3491c2aa98e2SPeter Wemm **		err -- the errno code to classify.
3492c2aa98e2SPeter Wemm **
3493c2aa98e2SPeter Wemm **	Returns:
349412ed1c7cSGregory Neil Shapiro **		true if this is probably transient.
349512ed1c7cSGregory Neil Shapiro **		false otherwise.
3496c2aa98e2SPeter Wemm */
3497c2aa98e2SPeter Wemm 
3498c2aa98e2SPeter Wemm bool
transienterror(err)3499c2aa98e2SPeter Wemm transienterror(err)
3500c2aa98e2SPeter Wemm 	int err;
3501c2aa98e2SPeter Wemm {
3502c2aa98e2SPeter Wemm 	switch (err)
3503c2aa98e2SPeter Wemm 	{
3504c2aa98e2SPeter Wemm 	  case EIO:			/* I/O error */
3505c2aa98e2SPeter Wemm 	  case ENXIO:			/* Device not configured */
3506c2aa98e2SPeter Wemm 	  case EAGAIN:			/* Resource temporarily unavailable */
3507c2aa98e2SPeter Wemm 	  case ENOMEM:			/* Cannot allocate memory */
3508c2aa98e2SPeter Wemm 	  case ENODEV:			/* Operation not supported by device */
3509c2aa98e2SPeter Wemm 	  case ENFILE:			/* Too many open files in system */
3510c2aa98e2SPeter Wemm 	  case EMFILE:			/* Too many open files */
3511c2aa98e2SPeter Wemm 	  case ENOSPC:			/* No space left on device */
3512c2aa98e2SPeter Wemm 	  case ETIMEDOUT:		/* Connection timed out */
3513c2aa98e2SPeter Wemm #ifdef ESTALE
3514c2aa98e2SPeter Wemm 	  case ESTALE:			/* Stale NFS file handle */
35155b0945b5SGregory Neil Shapiro #endif
3516c2aa98e2SPeter Wemm #ifdef ENETDOWN
3517c2aa98e2SPeter Wemm 	  case ENETDOWN:		/* Network is down */
35185b0945b5SGregory Neil Shapiro #endif
3519c2aa98e2SPeter Wemm #ifdef ENETUNREACH
3520c2aa98e2SPeter Wemm 	  case ENETUNREACH:		/* Network is unreachable */
35215b0945b5SGregory Neil Shapiro #endif
3522c2aa98e2SPeter Wemm #ifdef ENETRESET
3523c2aa98e2SPeter Wemm 	  case ENETRESET:		/* Network dropped connection on reset */
35245b0945b5SGregory Neil Shapiro #endif
3525c2aa98e2SPeter Wemm #ifdef ECONNABORTED
3526c2aa98e2SPeter Wemm 	  case ECONNABORTED:		/* Software caused connection abort */
35275b0945b5SGregory Neil Shapiro #endif
3528c2aa98e2SPeter Wemm #ifdef ECONNRESET
3529c2aa98e2SPeter Wemm 	  case ECONNRESET:		/* Connection reset by peer */
35305b0945b5SGregory Neil Shapiro #endif
3531c2aa98e2SPeter Wemm #ifdef ENOBUFS
3532c2aa98e2SPeter Wemm 	  case ENOBUFS:			/* No buffer space available */
35335b0945b5SGregory Neil Shapiro #endif
3534c2aa98e2SPeter Wemm #ifdef ESHUTDOWN
3535c2aa98e2SPeter Wemm 	  case ESHUTDOWN:		/* Can't send after socket shutdown */
35365b0945b5SGregory Neil Shapiro #endif
3537c2aa98e2SPeter Wemm #ifdef ECONNREFUSED
3538c2aa98e2SPeter Wemm 	  case ECONNREFUSED:		/* Connection refused */
35395b0945b5SGregory Neil Shapiro #endif
3540c2aa98e2SPeter Wemm #ifdef EHOSTDOWN
3541c2aa98e2SPeter Wemm 	  case EHOSTDOWN:		/* Host is down */
35425b0945b5SGregory Neil Shapiro #endif
3543c2aa98e2SPeter Wemm #ifdef EHOSTUNREACH
3544c2aa98e2SPeter Wemm 	  case EHOSTUNREACH:		/* No route to host */
35455b0945b5SGregory Neil Shapiro #endif
3546c2aa98e2SPeter Wemm #ifdef EDQUOT
3547c2aa98e2SPeter Wemm 	  case EDQUOT:			/* Disc quota exceeded */
35485b0945b5SGregory Neil Shapiro #endif
3549c2aa98e2SPeter Wemm #ifdef EPROCLIM
3550c2aa98e2SPeter Wemm 	  case EPROCLIM:		/* Too many processes */
35515b0945b5SGregory Neil Shapiro #endif
3552c2aa98e2SPeter Wemm #ifdef EUSERS
3553c2aa98e2SPeter Wemm 	  case EUSERS:			/* Too many users */
35545b0945b5SGregory Neil Shapiro #endif
3555c2aa98e2SPeter Wemm #ifdef EDEADLK
3556c2aa98e2SPeter Wemm 	  case EDEADLK:			/* Resource deadlock avoided */
35575b0945b5SGregory Neil Shapiro #endif
3558c2aa98e2SPeter Wemm #ifdef EISCONN
3559c2aa98e2SPeter Wemm 	  case EISCONN:			/* Socket already connected */
35605b0945b5SGregory Neil Shapiro #endif
3561c2aa98e2SPeter Wemm #ifdef EINPROGRESS
3562c2aa98e2SPeter Wemm 	  case EINPROGRESS:		/* Operation now in progress */
35635b0945b5SGregory Neil Shapiro #endif
3564c2aa98e2SPeter Wemm #ifdef EALREADY
3565c2aa98e2SPeter Wemm 	  case EALREADY:		/* Operation already in progress */
35665b0945b5SGregory Neil Shapiro #endif
3567c2aa98e2SPeter Wemm #ifdef EADDRINUSE
3568c2aa98e2SPeter Wemm 	  case EADDRINUSE:		/* Address already in use */
35695b0945b5SGregory Neil Shapiro #endif
3570c2aa98e2SPeter Wemm #ifdef EADDRNOTAVAIL
3571c2aa98e2SPeter Wemm 	  case EADDRNOTAVAIL:		/* Can't assign requested address */
35725b0945b5SGregory Neil Shapiro #endif
3573c2aa98e2SPeter Wemm #ifdef ETXTBSY
3574c2aa98e2SPeter Wemm 	  case ETXTBSY:			/* (Apollo) file locked */
35755b0945b5SGregory Neil Shapiro #endif
3576c2aa98e2SPeter Wemm #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
3577c2aa98e2SPeter Wemm 	  case ENOSR:			/* Out of streams resources */
35785b0945b5SGregory Neil Shapiro #endif
35793299c2f1SGregory Neil Shapiro #ifdef ENOLCK
35803299c2f1SGregory Neil Shapiro 	  case ENOLCK:			/* No locks available */
35815b0945b5SGregory Neil Shapiro #endif
3582c2aa98e2SPeter Wemm 	  case E_SM_OPENTIMEOUT:	/* PSEUDO: open timed out */
358312ed1c7cSGregory Neil Shapiro 		return true;
3584c2aa98e2SPeter Wemm 	}
3585c2aa98e2SPeter Wemm 
3586c2aa98e2SPeter Wemm 	/* nope, must be permanent */
358712ed1c7cSGregory Neil Shapiro 	return false;
3588c2aa98e2SPeter Wemm }
358912ed1c7cSGregory Neil Shapiro /*
3590c2aa98e2SPeter Wemm **  LOCKFILE -- lock a file using flock or (shudder) fcntl locking
3591c2aa98e2SPeter Wemm **
3592c2aa98e2SPeter Wemm **	Parameters:
3593c2aa98e2SPeter Wemm **		fd -- the file descriptor of the file.
3594c2aa98e2SPeter Wemm **		filename -- the file name (for error messages).
3595c2aa98e2SPeter Wemm **		ext -- the filename extension.
3596c2aa98e2SPeter Wemm **		type -- type of the lock.  Bits can be:
3597c2aa98e2SPeter Wemm **			LOCK_EX -- exclusive lock.
3598c2aa98e2SPeter Wemm **			LOCK_NB -- non-blocking.
3599c46d91b7SGregory Neil Shapiro **			LOCK_UN -- unlock.
3600c2aa98e2SPeter Wemm **
3601c2aa98e2SPeter Wemm **	Returns:
360212ed1c7cSGregory Neil Shapiro **		true if the lock was acquired.
360312ed1c7cSGregory Neil Shapiro **		false otherwise.
3604c2aa98e2SPeter Wemm */
3605c2aa98e2SPeter Wemm 
3606c2aa98e2SPeter Wemm bool
lockfile(fd,filename,ext,type)3607c2aa98e2SPeter Wemm lockfile(fd, filename, ext, type)
3608c2aa98e2SPeter Wemm 	int fd;
3609c2aa98e2SPeter Wemm 	char *filename;
3610c2aa98e2SPeter Wemm 	char *ext;
3611c2aa98e2SPeter Wemm 	int type;
3612c2aa98e2SPeter Wemm {
3613c2aa98e2SPeter Wemm 	int i;
3614c2aa98e2SPeter Wemm 	int save_errno;
3615c2aa98e2SPeter Wemm #if !HASFLOCK
3616c2aa98e2SPeter Wemm 	int action;
3617c2aa98e2SPeter Wemm 	struct flock lfd;
3618c2aa98e2SPeter Wemm 
3619c2aa98e2SPeter Wemm 	if (ext == NULL)
3620c2aa98e2SPeter Wemm 		ext = "";
3621c2aa98e2SPeter Wemm 
36222fb4f839SGregory Neil Shapiro 	(void) memset(&lfd, '\0', sizeof(lfd));
3623c2aa98e2SPeter Wemm 	if (bitset(LOCK_UN, type))
3624c2aa98e2SPeter Wemm 		lfd.l_type = F_UNLCK;
3625c2aa98e2SPeter Wemm 	else if (bitset(LOCK_EX, type))
3626c2aa98e2SPeter Wemm 		lfd.l_type = F_WRLCK;
3627c2aa98e2SPeter Wemm 	else
3628c2aa98e2SPeter Wemm 		lfd.l_type = F_RDLCK;
3629c2aa98e2SPeter Wemm 
3630c2aa98e2SPeter Wemm 	if (bitset(LOCK_NB, type))
3631c2aa98e2SPeter Wemm 		action = F_SETLK;
3632c2aa98e2SPeter Wemm 	else
3633c2aa98e2SPeter Wemm 		action = F_SETLKW;
3634c2aa98e2SPeter Wemm 
3635c2aa98e2SPeter Wemm 	if (tTd(55, 60))
3636*d39bd2c1SGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, fd=%d, action=%s, type=%s): ",
3637*d39bd2c1SGregory Neil Shapiro 			filename, ext, fd,
3638*d39bd2c1SGregory Neil Shapiro 			bitset(LOCK_NB, type) ? "nb" : "block",
3639*d39bd2c1SGregory Neil Shapiro 			bitset(LOCK_UN, type) ? "unlock" :
3640*d39bd2c1SGregory Neil Shapiro 				(bitset(LOCK_EX, type) ? "wr" : "rd"));
3641c2aa98e2SPeter Wemm 	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
3642c2aa98e2SPeter Wemm 		continue;
3643c2aa98e2SPeter Wemm 	if (i >= 0)
3644c2aa98e2SPeter Wemm 	{
3645c2aa98e2SPeter Wemm 		if (tTd(55, 60))
364612ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
364712ed1c7cSGregory Neil Shapiro 		return true;
3648c2aa98e2SPeter Wemm 	}
3649c2aa98e2SPeter Wemm 	save_errno = errno;
3650c2aa98e2SPeter Wemm 
3651c2aa98e2SPeter Wemm 	if (tTd(55, 60))
365212ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3653c2aa98e2SPeter Wemm 
3654c2aa98e2SPeter Wemm 	/*
3655c2aa98e2SPeter Wemm 	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
3656c2aa98e2SPeter Wemm 	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
3657c2aa98e2SPeter Wemm 	**  as type "tmp" (that is, served from swap space), the
3658c2aa98e2SPeter Wemm 	**  previous fcntl will fail with "Invalid argument" errors.
3659c2aa98e2SPeter Wemm 	**  Since this is fairly common during testing, we will assume
3660c2aa98e2SPeter Wemm 	**  that this indicates that the lock is successfully grabbed.
3661c2aa98e2SPeter Wemm 	*/
3662c2aa98e2SPeter Wemm 
3663c2aa98e2SPeter Wemm 	if (save_errno == EINVAL)
3664c2aa98e2SPeter Wemm 	{
3665c2aa98e2SPeter Wemm 		if (tTd(55, 60))
366612ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
366712ed1c7cSGregory Neil Shapiro 		return true;
3668c2aa98e2SPeter Wemm 	}
3669c2aa98e2SPeter Wemm 
36703299c2f1SGregory Neil Shapiro 	if (!bitset(LOCK_NB, type) ||
36713299c2f1SGregory Neil Shapiro 	    (save_errno != EACCES && save_errno != EAGAIN))
3672c2aa98e2SPeter Wemm 	{
3673320f00e7SGregory Neil Shapiro 		int omode = fcntl(fd, F_GETFL, 0);
3674320f00e7SGregory Neil Shapiro 		uid_t euid = geteuid();
3675320f00e7SGregory Neil Shapiro 
3676c2aa98e2SPeter Wemm 		errno = save_errno;
3677da7d7b9cSGregory Neil Shapiro 		syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)",
3678da7d7b9cSGregory Neil Shapiro 		       filename, ext, fd, type, omode, (long) euid);
367912ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3680c2aa98e2SPeter Wemm 	}
36813299c2f1SGregory Neil Shapiro #else /* !HASFLOCK */
3682c2aa98e2SPeter Wemm 	if (ext == NULL)
3683c2aa98e2SPeter Wemm 		ext = "";
3684c2aa98e2SPeter Wemm 
3685c2aa98e2SPeter Wemm 	if (tTd(55, 60))
3686*d39bd2c1SGregory Neil Shapiro 		sm_dprintf("lockfile(%s%s, fd=%d, type=%s): ", filename, ext,
3687*d39bd2c1SGregory Neil Shapiro 			fd, bitset(LOCK_UN, type) ? "unlock" :
3688*d39bd2c1SGregory Neil Shapiro 				(bitset(LOCK_EX, type) ? "wr" : "rd"));
3689c2aa98e2SPeter Wemm 
3690c2aa98e2SPeter Wemm 	while ((i = flock(fd, type)) < 0 && errno == EINTR)
3691c2aa98e2SPeter Wemm 		continue;
3692c2aa98e2SPeter Wemm 	if (i >= 0)
3693c2aa98e2SPeter Wemm 	{
3694c2aa98e2SPeter Wemm 		if (tTd(55, 60))
369512ed1c7cSGregory Neil Shapiro 			sm_dprintf("SUCCESS\n");
369612ed1c7cSGregory Neil Shapiro 		return true;
3697c2aa98e2SPeter Wemm 	}
3698c2aa98e2SPeter Wemm 	save_errno = errno;
3699c2aa98e2SPeter Wemm 
3700c2aa98e2SPeter Wemm 	if (tTd(55, 60))
370112ed1c7cSGregory Neil Shapiro 		sm_dprintf("(%s) ", sm_errstring(save_errno));
3702c2aa98e2SPeter Wemm 
3703c2aa98e2SPeter Wemm 	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
3704c2aa98e2SPeter Wemm 	{
3705320f00e7SGregory Neil Shapiro 		int omode = fcntl(fd, F_GETFL, 0);
3706320f00e7SGregory Neil Shapiro 		uid_t euid = geteuid();
3707320f00e7SGregory Neil Shapiro 
3708c2aa98e2SPeter Wemm 		errno = save_errno;
3709da7d7b9cSGregory Neil Shapiro 		syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)",
3710da7d7b9cSGregory Neil Shapiro 			filename, ext, fd, type, omode, (long) euid);
371112ed1c7cSGregory Neil Shapiro 		dumpfd(fd, true, true);
3712c2aa98e2SPeter Wemm 	}
37133299c2f1SGregory Neil Shapiro #endif /* !HASFLOCK */
3714c2aa98e2SPeter Wemm 	if (tTd(55, 60))
371512ed1c7cSGregory Neil Shapiro 		sm_dprintf("FAIL\n");
3716c2aa98e2SPeter Wemm 	errno = save_errno;
371712ed1c7cSGregory Neil Shapiro 	return false;
3718c2aa98e2SPeter Wemm }
371912ed1c7cSGregory Neil Shapiro /*
3720c2aa98e2SPeter Wemm **  CHOWNSAFE -- tell if chown is "safe" (executable only by root)
3721c2aa98e2SPeter Wemm **
3722c2aa98e2SPeter Wemm **	Unfortunately, given that we can't predict other systems on which
3723c2aa98e2SPeter Wemm **	a remote mounted (NFS) filesystem will be mounted, the answer is
3724c2aa98e2SPeter Wemm **	almost always that this is unsafe.
3725c2aa98e2SPeter Wemm **
3726c2aa98e2SPeter Wemm **	Note also that many operating systems have non-compliant
3727c2aa98e2SPeter Wemm **	implementations of the _POSIX_CHOWN_RESTRICTED variable and the
3728c2aa98e2SPeter Wemm **	fpathconf() routine.  According to IEEE 1003.1-1990, if
3729c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
3730c2aa98e2SPeter Wemm **	no non-root process can give away the file.  However, vendors
3731c2aa98e2SPeter Wemm **	don't take NFS into account, so a comfortable value of
3732c2aa98e2SPeter Wemm **	_POSIX_CHOWN_RESTRICTED tells us nothing.
3733c2aa98e2SPeter Wemm **
3734c2aa98e2SPeter Wemm **	Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
3735c2aa98e2SPeter Wemm **	even on files where chown is not restricted.  Many systems get
3736c2aa98e2SPeter Wemm **	this wrong on NFS-based filesystems (that is, they say that chown
3737c2aa98e2SPeter Wemm **	is restricted [safe] on NFS filesystems where it may not be, since
3738c2aa98e2SPeter Wemm **	other systems can access the same filesystem and do file giveaway;
3739c2aa98e2SPeter Wemm **	only the NFS server knows for sure!)  Hence, it is important to
3740c2aa98e2SPeter Wemm **	get the value of SAFENFSPATHCONF correct -- it should be defined
3741c2aa98e2SPeter Wemm **	_only_ after testing (see test/t_pathconf.c) a system on an unsafe
3742c2aa98e2SPeter Wemm **	NFS-based filesystem to ensure that you can get meaningful results.
3743c2aa98e2SPeter Wemm **	If in doubt, assume unsafe!
3744c2aa98e2SPeter Wemm **
3745c2aa98e2SPeter Wemm **	You may also need to tweak IS_SAFE_CHOWN -- it should be a
3746c2aa98e2SPeter Wemm **	condition indicating whether the return from pathconf indicates
3747c2aa98e2SPeter Wemm **	that chown is safe (typically either > 0 or >= 0 -- there isn't
3748c2aa98e2SPeter Wemm **	even any agreement about whether a zero return means that a file
3749c2aa98e2SPeter Wemm **	is or is not safe).  It defaults to "> 0".
3750c2aa98e2SPeter Wemm **
3751c2aa98e2SPeter Wemm **	If the parent directory is safe (writable only by owner back
3752c2aa98e2SPeter Wemm **	to the root) then we can relax slightly and trust fpathconf
3753c2aa98e2SPeter Wemm **	in more circumstances.  This is really a crock -- if this is an
3754c2aa98e2SPeter Wemm **	NFS mounted filesystem then we really know nothing about the
3755c2aa98e2SPeter Wemm **	underlying implementation.  However, most systems pessimize and
3756c2aa98e2SPeter Wemm **	return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
3757c2aa98e2SPeter Wemm **	we interpret as unsafe, as we should.  Thus, this heuristic gets
3758c2aa98e2SPeter Wemm **	us into a possible problem only on systems that have a broken
3759c2aa98e2SPeter Wemm **	pathconf implementation and which are also poorly configured
3760c2aa98e2SPeter Wemm **	(have :include: files in group- or world-writable directories).
3761c2aa98e2SPeter Wemm **
3762c2aa98e2SPeter Wemm **	Parameters:
3763c2aa98e2SPeter Wemm **		fd -- the file descriptor to check.
3764c2aa98e2SPeter Wemm **		safedir -- set if the parent directory is safe.
3765c2aa98e2SPeter Wemm **
3766c2aa98e2SPeter Wemm **	Returns:
376712ed1c7cSGregory Neil Shapiro **		true -- if the chown(2) operation is "safe" -- that is,
3768c2aa98e2SPeter Wemm **			only root can chown the file to an arbitrary user.
376912ed1c7cSGregory Neil Shapiro **		false -- if an arbitrary user can give away a file.
3770c2aa98e2SPeter Wemm */
3771c2aa98e2SPeter Wemm 
3772c2aa98e2SPeter Wemm #ifndef IS_SAFE_CHOWN
3773c2aa98e2SPeter Wemm # define IS_SAFE_CHOWN	> 0
37745b0945b5SGregory Neil Shapiro #endif
3775c2aa98e2SPeter Wemm 
3776c2aa98e2SPeter Wemm bool
chownsafe(fd,safedir)3777c2aa98e2SPeter Wemm chownsafe(fd, safedir)
3778c2aa98e2SPeter Wemm 	int fd;
3779c2aa98e2SPeter Wemm 	bool safedir;
3780c2aa98e2SPeter Wemm {
3781c2aa98e2SPeter Wemm #if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \
3782c2aa98e2SPeter Wemm     (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H))
3783c2aa98e2SPeter Wemm 	int rval;
3784c2aa98e2SPeter Wemm 
3785c2aa98e2SPeter Wemm 	/* give the system administrator a chance to override */
37863299c2f1SGregory Neil Shapiro 	if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail))
378712ed1c7cSGregory Neil Shapiro 		return true;
3788c2aa98e2SPeter Wemm 
3789c2aa98e2SPeter Wemm 	/*
3790c2aa98e2SPeter Wemm 	**  Some systems (e.g., SunOS) seem to have the call and the
3791c2aa98e2SPeter Wemm 	**  #define _PC_CHOWN_RESTRICTED, but don't actually implement
3792c2aa98e2SPeter Wemm 	**  the call.  This heuristic checks for that.
3793c2aa98e2SPeter Wemm 	*/
3794c2aa98e2SPeter Wemm 
3795c2aa98e2SPeter Wemm 	errno = 0;
3796c2aa98e2SPeter Wemm 	rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
3797c2aa98e2SPeter Wemm # if SAFENFSPATHCONF
3798c2aa98e2SPeter Wemm 	return errno == 0 && rval IS_SAFE_CHOWN;
37995b0945b5SGregory Neil Shapiro # else
3800c2aa98e2SPeter Wemm 	return safedir && errno == 0 && rval IS_SAFE_CHOWN;
38015b0945b5SGregory Neil Shapiro # endif
380212ed1c7cSGregory Neil Shapiro #else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
38033299c2f1SGregory Neil Shapiro 	return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
380412ed1c7cSGregory Neil Shapiro #endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
3805c2aa98e2SPeter Wemm }
380612ed1c7cSGregory Neil Shapiro /*
3807c2aa98e2SPeter Wemm **  RESETLIMITS -- reset system controlled resource limits
3808c2aa98e2SPeter Wemm **
3809c2aa98e2SPeter Wemm **	This is to avoid denial-of-service attacks
3810c2aa98e2SPeter Wemm **
3811c2aa98e2SPeter Wemm **	Parameters:
3812c2aa98e2SPeter Wemm **		none
3813c2aa98e2SPeter Wemm **
3814c2aa98e2SPeter Wemm **	Returns:
3815c2aa98e2SPeter Wemm **		none
3816c2aa98e2SPeter Wemm */
3817c2aa98e2SPeter Wemm 
3818c2aa98e2SPeter Wemm #if HASSETRLIMIT
3819c2aa98e2SPeter Wemm # ifdef RLIMIT_NEEDS_SYS_TIME_H
3820567a2fc9SGregory Neil Shapiro #  include <sm/time.h>
38215b0945b5SGregory Neil Shapiro # endif
3822c2aa98e2SPeter Wemm # include <sys/resource.h>
38233299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3824c2aa98e2SPeter Wemm 
3825c2aa98e2SPeter Wemm void
resetlimits()3826c2aa98e2SPeter Wemm resetlimits()
3827c2aa98e2SPeter Wemm {
3828c2aa98e2SPeter Wemm #if HASSETRLIMIT
3829c2aa98e2SPeter Wemm 	struct rlimit lim;
3830c2aa98e2SPeter Wemm 
3831c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
3832c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_CPU, &lim);
3833c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_FSIZE, &lim);
3834c2aa98e2SPeter Wemm # ifdef RLIMIT_NOFILE
3835c2aa98e2SPeter Wemm 	lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
3836c2aa98e2SPeter Wemm 	(void) setrlimit(RLIMIT_NOFILE, &lim);
38375b0945b5SGregory Neil Shapiro # endif
38383299c2f1SGregory Neil Shapiro #else /* HASSETRLIMIT */
3839c2aa98e2SPeter Wemm # if HASULIMIT
3840c2aa98e2SPeter Wemm 	(void) ulimit(2, 0x3fffff);
3841c2aa98e2SPeter Wemm 	(void) ulimit(4, FD_SETSIZE);
38425b0945b5SGregory Neil Shapiro # endif
38433299c2f1SGregory Neil Shapiro #endif /* HASSETRLIMIT */
3844c2aa98e2SPeter Wemm 	errno = 0;
3845c2aa98e2SPeter Wemm }
384612ed1c7cSGregory Neil Shapiro /*
3847c2aa98e2SPeter Wemm **  SETVENDOR -- process vendor code from V configuration line
3848c2aa98e2SPeter Wemm **
3849c2aa98e2SPeter Wemm **	Parameters:
3850c2aa98e2SPeter Wemm **		vendor -- string representation of vendor.
3851c2aa98e2SPeter Wemm **
3852c2aa98e2SPeter Wemm **	Returns:
385312ed1c7cSGregory Neil Shapiro **		true -- if ok.
385412ed1c7cSGregory Neil Shapiro **		false -- if vendor code could not be processed.
3855c2aa98e2SPeter Wemm **
3856c2aa98e2SPeter Wemm **	Side Effects:
3857c2aa98e2SPeter Wemm **		It is reasonable to set mode flags here to tweak
3858c2aa98e2SPeter Wemm **		processing in other parts of the code if necessary.
3859c2aa98e2SPeter Wemm **		For example, if you are a vendor that uses $%y to
3860c2aa98e2SPeter Wemm **		indicate YP lookups, you could enable that here.
3861c2aa98e2SPeter Wemm */
3862c2aa98e2SPeter Wemm 
3863c2aa98e2SPeter Wemm bool
setvendor(vendor)3864c2aa98e2SPeter Wemm setvendor(vendor)
3865c2aa98e2SPeter Wemm 	char *vendor;
3866c2aa98e2SPeter Wemm {
38672fb4f839SGregory Neil Shapiro 	if (SM_STRCASEEQ(vendor, "Berkeley"))
3868c2aa98e2SPeter Wemm 	{
3869c2aa98e2SPeter Wemm 		VendorCode = VENDOR_BERKELEY;
387012ed1c7cSGregory Neil Shapiro 		return true;
3871c2aa98e2SPeter Wemm 	}
3872c2aa98e2SPeter Wemm 
3873c2aa98e2SPeter Wemm 	/* add vendor extensions here */
3874c2aa98e2SPeter Wemm 
3875c2aa98e2SPeter Wemm #ifdef SUN_EXTENSIONS
38762fb4f839SGregory Neil Shapiro 	if (SM_STRCASEEQ(vendor, "Sun"))
3877c2aa98e2SPeter Wemm 	{
3878c2aa98e2SPeter Wemm 		VendorCode = VENDOR_SUN;
387912ed1c7cSGregory Neil Shapiro 		return true;
3880c2aa98e2SPeter Wemm 	}
38813299c2f1SGregory Neil Shapiro #endif /* SUN_EXTENSIONS */
3882567a2fc9SGregory Neil Shapiro #ifdef DEC
38832fb4f839SGregory Neil Shapiro 	if (SM_STRCASEEQ(vendor, "Digital"))
3884567a2fc9SGregory Neil Shapiro 	{
3885567a2fc9SGregory Neil Shapiro 		VendorCode = VENDOR_DEC;
3886567a2fc9SGregory Neil Shapiro 		return true;
3887567a2fc9SGregory Neil Shapiro 	}
3888567a2fc9SGregory Neil Shapiro #endif /* DEC */
3889c2aa98e2SPeter Wemm 
389076b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
38912fb4f839SGregory Neil Shapiro 	if (SM_STRCASEEQ(vendor, VENDOR_NAME))
389276b7bf71SPeter Wemm 	{
389376b7bf71SPeter Wemm 		VendorCode = VENDOR_CODE;
389412ed1c7cSGregory Neil Shapiro 		return true;
389576b7bf71SPeter Wemm 	}
38963299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
389776b7bf71SPeter Wemm 
389812ed1c7cSGregory Neil Shapiro 	return false;
3899c2aa98e2SPeter Wemm }
390012ed1c7cSGregory Neil Shapiro /*
390176b7bf71SPeter Wemm **  GETVENDOR -- return vendor name based on vendor code
390276b7bf71SPeter Wemm **
390376b7bf71SPeter Wemm **	Parameters:
390476b7bf71SPeter Wemm **		vendorcode -- numeric representation of vendor.
390576b7bf71SPeter Wemm **
390676b7bf71SPeter Wemm **	Returns:
390776b7bf71SPeter Wemm **		string containing vendor name.
390876b7bf71SPeter Wemm */
390976b7bf71SPeter Wemm 
391076b7bf71SPeter Wemm char *
getvendor(vendorcode)391176b7bf71SPeter Wemm getvendor(vendorcode)
391276b7bf71SPeter Wemm 	int vendorcode;
391376b7bf71SPeter Wemm {
391476b7bf71SPeter Wemm #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
391576b7bf71SPeter Wemm 	/*
391676b7bf71SPeter Wemm 	**  Can't have the same switch case twice so need to
391776b7bf71SPeter Wemm 	**  handle VENDOR_CODE outside of switch.  It might
391876b7bf71SPeter Wemm 	**  match one of the existing VENDOR_* codes.
391976b7bf71SPeter Wemm 	*/
392076b7bf71SPeter Wemm 
392176b7bf71SPeter Wemm 	if (vendorcode == VENDOR_CODE)
392276b7bf71SPeter Wemm 		return VENDOR_NAME;
39233299c2f1SGregory Neil Shapiro #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
392476b7bf71SPeter Wemm 
392576b7bf71SPeter Wemm 	switch (vendorcode)
392676b7bf71SPeter Wemm 	{
392776b7bf71SPeter Wemm 	  case VENDOR_BERKELEY:
392876b7bf71SPeter Wemm 		return "Berkeley";
392976b7bf71SPeter Wemm 
393076b7bf71SPeter Wemm 	  case VENDOR_SUN:
393176b7bf71SPeter Wemm 		return "Sun";
393276b7bf71SPeter Wemm 
393376b7bf71SPeter Wemm 	  case VENDOR_HP:
393476b7bf71SPeter Wemm 		return "HP";
393576b7bf71SPeter Wemm 
393676b7bf71SPeter Wemm 	  case VENDOR_IBM:
393776b7bf71SPeter Wemm 		return "IBM";
393876b7bf71SPeter Wemm 
393976b7bf71SPeter Wemm 	  case VENDOR_SENDMAIL:
394076b7bf71SPeter Wemm 		return "Sendmail";
394176b7bf71SPeter Wemm 
394276b7bf71SPeter Wemm 	  default:
394376b7bf71SPeter Wemm 		return "Unknown";
394476b7bf71SPeter Wemm 	}
394576b7bf71SPeter Wemm }
394612ed1c7cSGregory Neil Shapiro /*
3947c2aa98e2SPeter Wemm **  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
3948c2aa98e2SPeter Wemm **
3949c2aa98e2SPeter Wemm **	Vendor_pre_defaults is called before reading the configuration
3950c2aa98e2SPeter Wemm **	file; vendor_post_defaults is called immediately after.
3951c2aa98e2SPeter Wemm **
3952c2aa98e2SPeter Wemm **	Parameters:
3953c2aa98e2SPeter Wemm **		e -- the global environment to initialize.
3954c2aa98e2SPeter Wemm **
3955c2aa98e2SPeter Wemm **	Returns:
3956c2aa98e2SPeter Wemm **		none.
3957c2aa98e2SPeter Wemm */
3958c2aa98e2SPeter Wemm 
3959c2aa98e2SPeter Wemm #if SHARE_V1
3960c2aa98e2SPeter Wemm int	DefShareUid;	/* default share uid to run as -- unused??? */
39615b0945b5SGregory Neil Shapiro #endif
3962c2aa98e2SPeter Wemm 
3963c2aa98e2SPeter Wemm void
vendor_pre_defaults(e)3964c2aa98e2SPeter Wemm vendor_pre_defaults(e)
3965c2aa98e2SPeter Wemm 	ENVELOPE *e;
3966c2aa98e2SPeter Wemm {
3967c2aa98e2SPeter Wemm #if SHARE_V1
3968c2aa98e2SPeter Wemm 	/* OTHERUID is defined in shares.h, do not be alarmed */
3969c2aa98e2SPeter Wemm 	DefShareUid = OTHERUID;
39705b0945b5SGregory Neil Shapiro #endif
3971c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3972c2aa98e2SPeter Wemm 	sun_pre_defaults(e);
39735b0945b5SGregory Neil Shapiro #endif
3974c2aa98e2SPeter Wemm #ifdef apollo
39753299c2f1SGregory Neil Shapiro 	/*
39763299c2f1SGregory Neil Shapiro 	**  stupid domain/os can't even open
39773299c2f1SGregory Neil Shapiro 	**  /etc/mail/sendmail.cf without this
39783299c2f1SGregory Neil Shapiro 	*/
39793299c2f1SGregory Neil Shapiro 
3980567a2fc9SGregory Neil Shapiro 	sm_setuserenv("ISP", NULL);
3981567a2fc9SGregory Neil Shapiro 	sm_setuserenv("SYSTYPE", NULL);
39823299c2f1SGregory Neil Shapiro #endif /* apollo */
3983c2aa98e2SPeter Wemm }
3984c2aa98e2SPeter Wemm 
3985c2aa98e2SPeter Wemm void
vendor_post_defaults(e)3986c2aa98e2SPeter Wemm vendor_post_defaults(e)
3987c2aa98e2SPeter Wemm 	ENVELOPE *e;
3988c2aa98e2SPeter Wemm {
3989c2aa98e2SPeter Wemm #ifdef __QNX__
3990c2aa98e2SPeter Wemm 	/* Makes sure the SOCK environment variable remains */
3991951742c4SGregory Neil Shapiro 	sm_setuserenv("SOCK", NULL);
39925b0945b5SGregory Neil Shapiro #endif
3993c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
3994c2aa98e2SPeter Wemm 	sun_post_defaults(e);
39955b0945b5SGregory Neil Shapiro #endif
3996c2aa98e2SPeter Wemm }
399712ed1c7cSGregory Neil Shapiro /*
3998c2aa98e2SPeter Wemm **  VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
3999c2aa98e2SPeter Wemm */
4000c2aa98e2SPeter Wemm 
4001c2aa98e2SPeter Wemm void
vendor_daemon_setup(e)4002c2aa98e2SPeter Wemm vendor_daemon_setup(e)
4003c2aa98e2SPeter Wemm 	ENVELOPE *e;
4004c2aa98e2SPeter Wemm {
40053299c2f1SGregory Neil Shapiro #if HASSETLOGIN
40063299c2f1SGregory Neil Shapiro 	(void) setlogin(RunAsUserName);
40075b0945b5SGregory Neil Shapiro #endif
4008c2aa98e2SPeter Wemm #if SECUREWARE
4009c2aa98e2SPeter Wemm 	if (getluid() != -1)
4010c2aa98e2SPeter Wemm 	{
4011c2aa98e2SPeter Wemm 		usrerr("Daemon cannot have LUID");
401212ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_USAGE);
4013c2aa98e2SPeter Wemm 	}
4014c2aa98e2SPeter Wemm #endif /* SECUREWARE */
4015c2aa98e2SPeter Wemm }
401612ed1c7cSGregory Neil Shapiro /*
4017c2aa98e2SPeter Wemm **  VENDOR_SET_UID -- do setup for setting a user id
4018c2aa98e2SPeter Wemm **
4019c2aa98e2SPeter Wemm **	This is called when we are still root.
4020c2aa98e2SPeter Wemm **
4021c2aa98e2SPeter Wemm **	Parameters:
4022c2aa98e2SPeter Wemm **		uid -- the uid we are about to become.
4023c2aa98e2SPeter Wemm **
4024c2aa98e2SPeter Wemm **	Returns:
4025c2aa98e2SPeter Wemm **		none.
4026c2aa98e2SPeter Wemm */
4027c2aa98e2SPeter Wemm 
4028c2aa98e2SPeter Wemm void
vendor_set_uid(uid)4029c2aa98e2SPeter Wemm vendor_set_uid(uid)
4030c2aa98e2SPeter Wemm 	UID_T uid;
4031c2aa98e2SPeter Wemm {
4032c2aa98e2SPeter Wemm 	/*
4033c2aa98e2SPeter Wemm 	**  We need to setup the share groups (lnodes)
40343299c2f1SGregory Neil Shapiro 	**  and add auditing information (luid's)
4035c2aa98e2SPeter Wemm 	**  before we loose our ``root''ness.
4036c2aa98e2SPeter Wemm 	*/
4037c2aa98e2SPeter Wemm #if SHARE_V1
4038c2aa98e2SPeter Wemm 	if (setupshares(uid, syserr) != 0)
4039c2aa98e2SPeter Wemm 		syserr("Unable to set up shares");
40405b0945b5SGregory Neil Shapiro #endif
4041c2aa98e2SPeter Wemm #if SECUREWARE
4042c2aa98e2SPeter Wemm 	(void) setup_secure(uid);
40435b0945b5SGregory Neil Shapiro #endif
4044c2aa98e2SPeter Wemm }
404512ed1c7cSGregory Neil Shapiro /*
4046c2aa98e2SPeter Wemm **  VALIDATE_CONNECTION -- check connection for rationality
4047c2aa98e2SPeter Wemm **
4048c2aa98e2SPeter Wemm **	If the connection is rejected, this routine should log an
4049c2aa98e2SPeter Wemm **	appropriate message -- but should never issue any SMTP protocol.
4050c2aa98e2SPeter Wemm **
4051c2aa98e2SPeter Wemm **	Parameters:
4052c2aa98e2SPeter Wemm **		sap -- a pointer to a SOCKADDR naming the peer.
4053c2aa98e2SPeter Wemm **		hostname -- the name corresponding to sap.
4054c2aa98e2SPeter Wemm **		e -- the current envelope.
4055c2aa98e2SPeter Wemm **
4056c2aa98e2SPeter Wemm **	Returns:
4057c2aa98e2SPeter Wemm **		error message from rejection.
4058c2aa98e2SPeter Wemm **		NULL if not rejected.
4059c2aa98e2SPeter Wemm */
4060c2aa98e2SPeter Wemm 
4061c2aa98e2SPeter Wemm #if TCPWRAPPERS
4062c2aa98e2SPeter Wemm # include <tcpd.h>
4063c2aa98e2SPeter Wemm 
4064c2aa98e2SPeter Wemm /* tcpwrappers does no logging, but you still have to declare these -- ugh */
4065c2aa98e2SPeter Wemm int	allow_severity	= LOG_INFO;
4066c2aa98e2SPeter Wemm int	deny_severity	= LOG_NOTICE;
40673299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
4068c2aa98e2SPeter Wemm 
4069c2aa98e2SPeter Wemm char *
validate_connection(sap,hostname,e)4070c2aa98e2SPeter Wemm validate_connection(sap, hostname, e)
4071c2aa98e2SPeter Wemm 	SOCKADDR *sap;
4072c2aa98e2SPeter Wemm 	char *hostname;
4073c2aa98e2SPeter Wemm 	ENVELOPE *e;
4074c2aa98e2SPeter Wemm {
4075c2aa98e2SPeter Wemm #if TCPWRAPPERS
4076c2aa98e2SPeter Wemm 	char *host;
407712ed1c7cSGregory Neil Shapiro 	char *addr;
407812ed1c7cSGregory Neil Shapiro 	extern int hosts_ctl();
40793299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
4080c2aa98e2SPeter Wemm 
4081c2aa98e2SPeter Wemm 	if (tTd(48, 3))
408212ed1c7cSGregory Neil Shapiro 		sm_dprintf("validate_connection(%s, %s)\n",
4083c2aa98e2SPeter Wemm 			hostname, anynet_ntoa(sap));
4084c2aa98e2SPeter Wemm 
4085bfb62e91SGregory Neil Shapiro 	connection_rate_check(sap, e);
4086da7d7b9cSGregory Neil Shapiro 	if (rscheck("check_relay", hostname, anynet_ntoa(sap), e,
4087da7d7b9cSGregory Neil Shapiro 		    RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID, NULL, NULL) != EX_OK)
4088c2aa98e2SPeter Wemm 	{
4089c2aa98e2SPeter Wemm 		static char reject[BUFSIZ*2];
4090c2aa98e2SPeter Wemm 		extern char MsgBuf[];
4091c2aa98e2SPeter Wemm 
4092c2aa98e2SPeter Wemm 		if (tTd(48, 4))
409312ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (rscheck)\n");
4094c2aa98e2SPeter Wemm 
40953299c2f1SGregory Neil Shapiro 		if (strlen(MsgBuf) >= 3)
4096951742c4SGregory Neil Shapiro 			(void) sm_strlcpy(reject, MsgBuf, sizeof(reject));
4097c2aa98e2SPeter Wemm 		else
4098951742c4SGregory Neil Shapiro 			(void) sm_strlcpy(reject, "Access denied", sizeof(reject));
4099c2aa98e2SPeter Wemm 
4100c2aa98e2SPeter Wemm 		return reject;
4101c2aa98e2SPeter Wemm 	}
4102c2aa98e2SPeter Wemm 
4103c2aa98e2SPeter Wemm #if TCPWRAPPERS
4104c2aa98e2SPeter Wemm 	if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']')
4105c2aa98e2SPeter Wemm 		host = "unknown";
4106c2aa98e2SPeter Wemm 	else
4107c2aa98e2SPeter Wemm 		host = hostname;
410812ed1c7cSGregory Neil Shapiro 	addr = anynet_ntoa(sap);
410912ed1c7cSGregory Neil Shapiro 
411012ed1c7cSGregory Neil Shapiro # if NETINET6
411112ed1c7cSGregory Neil Shapiro 	/* TCP/Wrappers don't want the IPv6: protocol label */
411212ed1c7cSGregory Neil Shapiro 	if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0)
411312ed1c7cSGregory Neil Shapiro 		addr += 5;
411412ed1c7cSGregory Neil Shapiro # endif /* NETINET6 */
411512ed1c7cSGregory Neil Shapiro 
411612ed1c7cSGregory Neil Shapiro 	if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN))
4117c2aa98e2SPeter Wemm 	{
4118c2aa98e2SPeter Wemm 		if (tTd(48, 4))
411912ed1c7cSGregory Neil Shapiro 			sm_dprintf("  ... validate_connection: BAD (tcpwrappers)\n");
412012ed1c7cSGregory Neil Shapiro 		if (LogLevel > 3)
41213299c2f1SGregory Neil Shapiro 			sm_syslog(LOG_NOTICE, e->e_id,
4122c2aa98e2SPeter Wemm 				  "tcpwrappers (%s, %s) rejection",
412312ed1c7cSGregory Neil Shapiro 				  host, addr);
4124c2aa98e2SPeter Wemm 		return "Access denied";
4125c2aa98e2SPeter Wemm 	}
41263299c2f1SGregory Neil Shapiro #endif /* TCPWRAPPERS */
4127c2aa98e2SPeter Wemm 	if (tTd(48, 4))
412812ed1c7cSGregory Neil Shapiro 		sm_dprintf("  ... validate_connection: OK\n");
4129c2aa98e2SPeter Wemm 	return NULL;
4130c2aa98e2SPeter Wemm }
4131c2aa98e2SPeter Wemm 
413212ed1c7cSGregory Neil Shapiro /*
4133c2aa98e2SPeter Wemm **  STRTOL -- convert string to long integer
4134c2aa98e2SPeter Wemm **
4135c2aa98e2SPeter Wemm **	For systems that don't have it in the C library.
4136c2aa98e2SPeter Wemm **
4137c2aa98e2SPeter Wemm **	This is taken verbatim from the 4.4-Lite C library.
4138c2aa98e2SPeter Wemm */
4139c2aa98e2SPeter Wemm 
41403299c2f1SGregory Neil Shapiro #if NEEDSTRTOL
4141c2aa98e2SPeter Wemm 
4142c2aa98e2SPeter Wemm # if defined(LIBC_SCCS) && !defined(lint)
4143c2aa98e2SPeter Wemm static char sccsid[] = "@(#)strtol.c	8.1 (Berkeley) 6/4/93";
41445b0945b5SGregory Neil Shapiro # endif
4145c2aa98e2SPeter Wemm 
4146c2aa98e2SPeter Wemm /*
414712ed1c7cSGregory Neil Shapiro **  Convert a string to a long integer.
414812ed1c7cSGregory Neil Shapiro **
414912ed1c7cSGregory Neil Shapiro **  Ignores `locale' stuff.  Assumes that the upper and lower case
415012ed1c7cSGregory Neil Shapiro **  alphabets and digits are each contiguous.
4151c2aa98e2SPeter Wemm */
4152c2aa98e2SPeter Wemm 
4153c2aa98e2SPeter Wemm long
strtol(nptr,endptr,base)4154c2aa98e2SPeter Wemm strtol(nptr, endptr, base)
4155c2aa98e2SPeter Wemm 	const char *nptr;
4156c2aa98e2SPeter Wemm 	char **endptr;
4157c2aa98e2SPeter Wemm 	register int base;
4158c2aa98e2SPeter Wemm {
4159c2aa98e2SPeter Wemm 	register const char *s = nptr;
4160c2aa98e2SPeter Wemm 	register unsigned long acc;
4161c2aa98e2SPeter Wemm 	register int c;
4162c2aa98e2SPeter Wemm 	register unsigned long cutoff;
4163c2aa98e2SPeter Wemm 	register int neg = 0, any, cutlim;
4164c2aa98e2SPeter Wemm 
4165c2aa98e2SPeter Wemm 	/*
416612ed1c7cSGregory Neil Shapiro 	**  Skip white space and pick up leading +/- sign if any.
416712ed1c7cSGregory Neil Shapiro 	**  If base is 0, allow 0x for hex and 0 for octal, else
416812ed1c7cSGregory Neil Shapiro 	**  assume decimal; if base is already 16, allow 0x.
4169c2aa98e2SPeter Wemm 	*/
4170c2aa98e2SPeter Wemm 	do {
4171c2aa98e2SPeter Wemm 		c = *s++;
41725b0945b5SGregory Neil Shapiro 	} while (SM_ISSPACE(c));
4173c2aa98e2SPeter Wemm 	if (c == '-') {
4174c2aa98e2SPeter Wemm 		neg = 1;
4175c2aa98e2SPeter Wemm 		c = *s++;
4176c2aa98e2SPeter Wemm 	} else if (c == '+')
4177c2aa98e2SPeter Wemm 		c = *s++;
4178c2aa98e2SPeter Wemm 	if ((base == 0 || base == 16) &&
4179c2aa98e2SPeter Wemm 	    c == '0' && (*s == 'x' || *s == 'X')) {
4180c2aa98e2SPeter Wemm 		c = s[1];
4181c2aa98e2SPeter Wemm 		s += 2;
4182c2aa98e2SPeter Wemm 		base = 16;
4183c2aa98e2SPeter Wemm 	}
4184c2aa98e2SPeter Wemm 	if (base == 0)
4185c2aa98e2SPeter Wemm 		base = c == '0' ? 8 : 10;
4186c2aa98e2SPeter Wemm 
4187c2aa98e2SPeter Wemm 	/*
418812ed1c7cSGregory Neil Shapiro 	**  Compute the cutoff value between legal numbers and illegal
418912ed1c7cSGregory Neil Shapiro 	**  numbers.  That is the largest legal value, divided by the
419012ed1c7cSGregory Neil Shapiro 	**  base.  An input number that is greater than this value, if
419112ed1c7cSGregory Neil Shapiro 	**  followed by a legal input character, is too big.  One that
419212ed1c7cSGregory Neil Shapiro 	**  is equal to this value may be valid or not; the limit
419312ed1c7cSGregory Neil Shapiro 	**  between valid and invalid numbers is then based on the last
419412ed1c7cSGregory Neil Shapiro 	**  digit.  For instance, if the range for longs is
419512ed1c7cSGregory Neil Shapiro 	**  [-2147483648..2147483647] and the input base is 10,
419612ed1c7cSGregory Neil Shapiro 	**  cutoff will be set to 214748364 and cutlim to either
419712ed1c7cSGregory Neil Shapiro 	**  7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
419812ed1c7cSGregory Neil Shapiro 	**  a value > 214748364, or equal but the next digit is > 7 (or 8),
419912ed1c7cSGregory Neil Shapiro 	**  the number is too big, and we will return a range error.
420012ed1c7cSGregory Neil Shapiro 	**
420112ed1c7cSGregory Neil Shapiro 	**  Set any if any `digits' consumed; make it negative to indicate
420212ed1c7cSGregory Neil Shapiro 	**  overflow.
4203c2aa98e2SPeter Wemm 	*/
4204c2aa98e2SPeter Wemm 	cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
4205c2aa98e2SPeter Wemm 	cutlim = cutoff % (unsigned long) base;
4206c2aa98e2SPeter Wemm 	cutoff /= (unsigned long) base;
4207c2aa98e2SPeter Wemm 	for (acc = 0, any = 0;; c = *s++) {
42089bd497b8SGregory Neil Shapiro 		if (isascii(c) && isdigit(c))
4209c2aa98e2SPeter Wemm 			c -= '0';
42109bd497b8SGregory Neil Shapiro 		else if (isascii(c) && isalpha(c))
4211c2aa98e2SPeter Wemm 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4212c2aa98e2SPeter Wemm 		else
4213c2aa98e2SPeter Wemm 			break;
4214c2aa98e2SPeter Wemm 		if (c >= base)
4215c2aa98e2SPeter Wemm 			break;
4216c2aa98e2SPeter Wemm 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
4217c2aa98e2SPeter Wemm 			any = -1;
4218c2aa98e2SPeter Wemm 		else {
4219c2aa98e2SPeter Wemm 			any = 1;
4220c2aa98e2SPeter Wemm 			acc *= base;
4221c2aa98e2SPeter Wemm 			acc += c;
4222c2aa98e2SPeter Wemm 		}
4223c2aa98e2SPeter Wemm 	}
4224c2aa98e2SPeter Wemm 	if (any < 0) {
4225c2aa98e2SPeter Wemm 		acc = neg ? LONG_MIN : LONG_MAX;
4226c2aa98e2SPeter Wemm 		errno = ERANGE;
4227c2aa98e2SPeter Wemm 	} else if (neg)
4228c2aa98e2SPeter Wemm 		acc = -acc;
42295b0945b5SGregory Neil Shapiro 	if (endptr != NULL)
4230c2aa98e2SPeter Wemm 		*endptr = (char *)(any ? s - 1 : nptr);
42313299c2f1SGregory Neil Shapiro 	return acc;
4232c2aa98e2SPeter Wemm }
4233c2aa98e2SPeter Wemm 
42343299c2f1SGregory Neil Shapiro #endif /* NEEDSTRTOL */
423512ed1c7cSGregory Neil Shapiro /*
4236c2aa98e2SPeter Wemm **  STRSTR -- find first substring in string
4237c2aa98e2SPeter Wemm **
4238c2aa98e2SPeter Wemm **	Parameters:
4239c2aa98e2SPeter Wemm **		big -- the big (full) string.
4240c2aa98e2SPeter Wemm **		little -- the little (sub) string.
4241c2aa98e2SPeter Wemm **
4242c2aa98e2SPeter Wemm **	Returns:
4243c2aa98e2SPeter Wemm **		A pointer to the first instance of little in big.
4244c2aa98e2SPeter Wemm **		big if little is the null string.
4245c2aa98e2SPeter Wemm **		NULL if little is not contained in big.
4246c2aa98e2SPeter Wemm */
4247c2aa98e2SPeter Wemm 
42483299c2f1SGregory Neil Shapiro #if NEEDSTRSTR
4249c2aa98e2SPeter Wemm 
4250c2aa98e2SPeter Wemm char *
strstr(big,little)4251c2aa98e2SPeter Wemm strstr(big, little)
4252c2aa98e2SPeter Wemm 	char *big;
4253c2aa98e2SPeter Wemm 	char *little;
4254c2aa98e2SPeter Wemm {
4255c2aa98e2SPeter Wemm 	register char *p = big;
4256c2aa98e2SPeter Wemm 	int l;
4257c2aa98e2SPeter Wemm 
4258c2aa98e2SPeter Wemm 	if (*little == '\0')
4259c2aa98e2SPeter Wemm 		return big;
4260c2aa98e2SPeter Wemm 	l = strlen(little);
4261c2aa98e2SPeter Wemm 
4262c2aa98e2SPeter Wemm 	while ((p = strchr(p, *little)) != NULL)
4263c2aa98e2SPeter Wemm 	{
4264c2aa98e2SPeter Wemm 		if (strncmp(p, little, l) == 0)
4265c2aa98e2SPeter Wemm 			return p;
4266c2aa98e2SPeter Wemm 		p++;
4267c2aa98e2SPeter Wemm 	}
4268c2aa98e2SPeter Wemm 	return NULL;
4269c2aa98e2SPeter Wemm }
4270c2aa98e2SPeter Wemm 
42713299c2f1SGregory Neil Shapiro #endif /* NEEDSTRSTR */
427212ed1c7cSGregory Neil Shapiro /*
4273c2aa98e2SPeter Wemm **  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
4274c2aa98e2SPeter Wemm **
42756f9c8e5bSGregory Neil Shapiro **	Some operating systems have weird problems with the gethostbyXXX
4276c2aa98e2SPeter Wemm **	routines.  For example, Solaris versions at least through 2.3
4277c2aa98e2SPeter Wemm **	don't properly deliver a canonical h_name field.  This tries to
4278c2aa98e2SPeter Wemm **	work around these problems.
42793299c2f1SGregory Neil Shapiro **
42803299c2f1SGregory Neil Shapiro **	Support IPv6 as well as IPv4.
4281c2aa98e2SPeter Wemm */
4282c2aa98e2SPeter Wemm 
4283c0c4794dSGregory Neil Shapiro #if NETINET6 && NEEDSGETIPNODE
42843299c2f1SGregory Neil Shapiro 
42853299c2f1SGregory Neil Shapiro # ifndef AI_DEFAULT
42863299c2f1SGregory Neil Shapiro #  define AI_DEFAULT	0	/* dummy */
42875b0945b5SGregory Neil Shapiro # endif
42883299c2f1SGregory Neil Shapiro # ifndef AI_ADDRCONFIG
42893299c2f1SGregory Neil Shapiro #  define AI_ADDRCONFIG	0	/* dummy */
42905b0945b5SGregory Neil Shapiro # endif
42913299c2f1SGregory Neil Shapiro # ifndef AI_V4MAPPED
42923299c2f1SGregory Neil Shapiro #  define AI_V4MAPPED	0	/* dummy */
42935b0945b5SGregory Neil Shapiro # endif
42943299c2f1SGregory Neil Shapiro # ifndef AI_ALL
42953299c2f1SGregory Neil Shapiro #  define AI_ALL	0	/* dummy */
42965b0945b5SGregory Neil Shapiro # endif
42973299c2f1SGregory Neil Shapiro 
42983299c2f1SGregory Neil Shapiro static struct hostent *
sm_getipnodebyname(name,family,flags,err)42996f9c8e5bSGregory Neil Shapiro sm_getipnodebyname(name, family, flags, err)
43006f9c8e5bSGregory Neil Shapiro 	const char *name;
43013299c2f1SGregory Neil Shapiro 	int family;
43023299c2f1SGregory Neil Shapiro 	int flags;
43033299c2f1SGregory Neil Shapiro 	int *err;
43043299c2f1SGregory Neil Shapiro {
43053299c2f1SGregory Neil Shapiro 	struct hostent *h;
43065dd76dd0SGregory Neil Shapiro # if HAS_GETHOSTBYNAME2
43075dd76dd0SGregory Neil Shapiro 
43085dd76dd0SGregory Neil Shapiro 	h = gethostbyname2(name, family);
43095dd76dd0SGregory Neil Shapiro 	if (h == NULL)
43105dd76dd0SGregory Neil Shapiro 		*err = h_errno;
43115dd76dd0SGregory Neil Shapiro 	return h;
43125dd76dd0SGregory Neil Shapiro 
43135dd76dd0SGregory Neil Shapiro # else /* HAS_GETHOSTBYNAME2 */
43145b0945b5SGregory Neil Shapiro #  ifdef RES_USE_INET6
43155dd76dd0SGregory Neil Shapiro 	bool resv6 = true;
43163299c2f1SGregory Neil Shapiro 
43173299c2f1SGregory Neil Shapiro 	if (family == AF_INET6)
43183299c2f1SGregory Neil Shapiro 	{
43193299c2f1SGregory Neil Shapiro 		/* From RFC2133, section 6.1 */
43203299c2f1SGregory Neil Shapiro 		resv6 = bitset(RES_USE_INET6, _res.options);
43213299c2f1SGregory Neil Shapiro 		_res.options |= RES_USE_INET6;
43223299c2f1SGregory Neil Shapiro 	}
43235b0945b5SGregory Neil Shapiro #  endif /* RES_USE_INET6 */
4324b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
43253299c2f1SGregory Neil Shapiro 	h = gethostbyname(name);
43265b0945b5SGregory Neil Shapiro #  ifdef RES_USE_INET6
432712ed1c7cSGregory Neil Shapiro 	if (!resv6)
43283299c2f1SGregory Neil Shapiro 		_res.options &= ~RES_USE_INET6;
43295b0945b5SGregory Neil Shapiro #  endif
43305dd76dd0SGregory Neil Shapiro 
43315dd76dd0SGregory Neil Shapiro 	/* the function is supposed to return only the requested family */
43325dd76dd0SGregory Neil Shapiro 	if (h != NULL && h->h_addrtype != family)
43335dd76dd0SGregory Neil Shapiro 	{
43345dd76dd0SGregory Neil Shapiro #  if NETINET6
43355dd76dd0SGregory Neil Shapiro 		freehostent(h);
43365b0945b5SGregory Neil Shapiro #  endif
43375dd76dd0SGregory Neil Shapiro 		h = NULL;
43385dd76dd0SGregory Neil Shapiro 		*err = NO_DATA;
43395dd76dd0SGregory Neil Shapiro 	}
43405dd76dd0SGregory Neil Shapiro 	else
434112ed1c7cSGregory Neil Shapiro 		*err = h_errno;
43423299c2f1SGregory Neil Shapiro 	return h;
43435dd76dd0SGregory Neil Shapiro # endif /* HAS_GETHOSTBYNAME2 */
43443299c2f1SGregory Neil Shapiro }
43453299c2f1SGregory Neil Shapiro 
43463299c2f1SGregory Neil Shapiro static struct hostent *
sm_getipnodebyaddr(addr,len,family,err)43476f9c8e5bSGregory Neil Shapiro sm_getipnodebyaddr(addr, len, family, err)
43486f9c8e5bSGregory Neil Shapiro 	const void *addr;
43496f9c8e5bSGregory Neil Shapiro 	size_t len;
43503299c2f1SGregory Neil Shapiro 	int family;
43513299c2f1SGregory Neil Shapiro 	int *err;
4352c2aa98e2SPeter Wemm {
4353c2aa98e2SPeter Wemm 	struct hostent *h;
43543299c2f1SGregory Neil Shapiro 
4355b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(0);
43563299c2f1SGregory Neil Shapiro 	h = gethostbyaddr(addr, len, family);
43573299c2f1SGregory Neil Shapiro 	*err = h_errno;
43583299c2f1SGregory Neil Shapiro 	return h;
43593299c2f1SGregory Neil Shapiro }
4360c46d91b7SGregory Neil Shapiro 
4361c46d91b7SGregory Neil Shapiro void
freehostent(h)4362c46d91b7SGregory Neil Shapiro freehostent(h)
4363c46d91b7SGregory Neil Shapiro 	struct hostent *h;
4364c46d91b7SGregory Neil Shapiro {
4365c46d91b7SGregory Neil Shapiro 	/*
4366c46d91b7SGregory Neil Shapiro 	**  Stub routine -- if they don't have getipnodeby*(),
4367c46d91b7SGregory Neil Shapiro 	**  they probably don't have the free routine either.
4368c46d91b7SGregory Neil Shapiro 	*/
4369c46d91b7SGregory Neil Shapiro 
4370c46d91b7SGregory Neil Shapiro 	return;
4371c46d91b7SGregory Neil Shapiro }
437212ed1c7cSGregory Neil Shapiro #endif /* NETINET6 && NEEDSGETIPNODE */
43733299c2f1SGregory Neil Shapiro 
43743299c2f1SGregory Neil Shapiro struct hostent *
sm_gethostbyname(name,family)43753299c2f1SGregory Neil Shapiro sm_gethostbyname(name, family)
43763299c2f1SGregory Neil Shapiro 	char *name;
43773299c2f1SGregory Neil Shapiro 	int family;
43783299c2f1SGregory Neil Shapiro {
4379b4662009SGregory Neil Shapiro 	int save_errno;
43803299c2f1SGregory Neil Shapiro 	struct hostent *h = NULL;
4381c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
4382c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4383c2aa98e2SPeter Wemm 	static struct hostent hp;
4384c2aa98e2SPeter Wemm 	static char buf[1000];
4385c2aa98e2SPeter Wemm 	extern struct hostent *_switch_gethostbyname_r();
4386c2aa98e2SPeter Wemm 
4387c2aa98e2SPeter Wemm 	if (tTd(61, 10))
438812ed1c7cSGregory Neil Shapiro 		sm_dprintf("_switch_gethostbyname_r(%s)... ", name);
4389c2aa98e2SPeter Wemm 	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
4390b4662009SGregory Neil Shapiro 	save_errno = errno;
43913299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4392c2aa98e2SPeter Wemm 	extern struct hostent *__switch_gethostbyname();
4393c2aa98e2SPeter Wemm 
4394c2aa98e2SPeter Wemm 	if (tTd(61, 10))
439512ed1c7cSGregory Neil Shapiro 		sm_dprintf("__switch_gethostbyname(%s)... ", name);
4396c2aa98e2SPeter Wemm 	h = __switch_gethostbyname(name);
4397b4662009SGregory Neil Shapiro 	save_errno = errno;
43983299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
43993299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
4400c2aa98e2SPeter Wemm 	int nmaps;
44013299c2f1SGregory Neil Shapiro # if NETINET6
4402552d4955SGregory Neil Shapiro #  ifndef SM_IPNODEBYNAME_FLAGS
4403552d4955SGregory Neil Shapiro     /* For IPv4-mapped addresses, use: AI_DEFAULT|AI_ALL */
4404552d4955SGregory Neil Shapiro #   define SM_IPNODEBYNAME_FLAGS	AI_ADDRCONFIG
44055b0945b5SGregory Neil Shapiro #  endif
4406552d4955SGregory Neil Shapiro 
4407552d4955SGregory Neil Shapiro 	int flags = SM_IPNODEBYNAME_FLAGS;
44083299c2f1SGregory Neil Shapiro 	int err;
44093299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4410c2aa98e2SPeter Wemm 	char *maptype[MAXMAPSTACK];
4411c2aa98e2SPeter Wemm 	short mapreturn[MAXMAPACTIONS];
44122fb4f839SGregory Neil Shapiro 	char hbuf[MAXNAME_I];
44132fb4f839SGregory Neil Shapiro # if _FFR_8BITENVADDR
44142fb4f839SGregory Neil Shapiro 	(void) dequote_internal_chars(name, hbuf, sizeof(hbuf));
44152fb4f839SGregory Neil Shapiro 	name = hbuf;
44162fb4f839SGregory Neil Shapiro # endif
4417c2aa98e2SPeter Wemm 	if (tTd(61, 10))
441812ed1c7cSGregory Neil Shapiro 		sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family);
44193299c2f1SGregory Neil Shapiro 
44203299c2f1SGregory Neil Shapiro # if NETINET6
44213299c2f1SGregory Neil Shapiro #  if ADDRCONFIG_IS_BROKEN
44223299c2f1SGregory Neil Shapiro 	flags &= ~AI_ADDRCONFIG;
44235b0945b5SGregory Neil Shapiro #  endif
44246f9c8e5bSGregory Neil Shapiro 	h = sm_getipnodebyname(name, family, flags, &err);
4425b4662009SGregory Neil Shapiro 	SM_SET_H_ERRNO(err);
44263299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4427c2aa98e2SPeter Wemm 	h = gethostbyname(name);
44283299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
44293299c2f1SGregory Neil Shapiro 
44303299c2f1SGregory Neil Shapiro 	save_errno = errno;
4431c2aa98e2SPeter Wemm 	if (h == NULL)
4432c2aa98e2SPeter Wemm 	{
4433c2aa98e2SPeter Wemm 		if (tTd(61, 10))
44342fb4f839SGregory Neil Shapiro 			sm_dprintf("failure: errno=%d, h_errno=%d\n",
44352fb4f839SGregory Neil Shapiro 				errno, h_errno);
4436c2aa98e2SPeter Wemm 
4437c2aa98e2SPeter Wemm 		nmaps = switch_map_find("hosts", maptype, mapreturn);
4438c2aa98e2SPeter Wemm 		while (--nmaps >= 0)
4439c46d91b7SGregory Neil Shapiro 		{
4440c2aa98e2SPeter Wemm 			if (strcmp(maptype[nmaps], "nis") == 0 ||
4441c2aa98e2SPeter Wemm 			    strcmp(maptype[nmaps], "files") == 0)
4442c2aa98e2SPeter Wemm 				break;
4443c46d91b7SGregory Neil Shapiro 		}
4444c46d91b7SGregory Neil Shapiro 
4445c2aa98e2SPeter Wemm 		if (nmaps >= 0)
4446c2aa98e2SPeter Wemm 		{
4447c2aa98e2SPeter Wemm 			/* try short name */
4448951742c4SGregory Neil Shapiro 			if (strlen(name) > sizeof(hbuf) - 1)
44493299c2f1SGregory Neil Shapiro 			{
44503299c2f1SGregory Neil Shapiro 				errno = save_errno;
4451c2aa98e2SPeter Wemm 				return NULL;
44523299c2f1SGregory Neil Shapiro 			}
4453951742c4SGregory Neil Shapiro 			(void) sm_strlcpy(hbuf, name, sizeof(hbuf));
4454b4662009SGregory Neil Shapiro 			(void) shorten_hostname(hbuf);
4455c2aa98e2SPeter Wemm 
4456c2aa98e2SPeter Wemm 			/* if it hasn't been shortened, there's no point */
4457c2aa98e2SPeter Wemm 			if (strcmp(hbuf, name) != 0)
4458c2aa98e2SPeter Wemm 			{
4459c2aa98e2SPeter Wemm 				if (tTd(61, 10))
446012ed1c7cSGregory Neil Shapiro 					sm_dprintf("sm_gethostbyname(%s, %d)... ",
44613299c2f1SGregory Neil Shapiro 					       hbuf, family);
44623299c2f1SGregory Neil Shapiro 
44633299c2f1SGregory Neil Shapiro # if NETINET6
44646f9c8e5bSGregory Neil Shapiro 				h = sm_getipnodebyname(hbuf, family, flags, &err);
4465b4662009SGregory Neil Shapiro 				SM_SET_H_ERRNO(err);
44663299c2f1SGregory Neil Shapiro 				save_errno = errno;
44673299c2f1SGregory Neil Shapiro # else /* NETINET6 */
4468c2aa98e2SPeter Wemm 				h = gethostbyname(hbuf);
44693299c2f1SGregory Neil Shapiro 				save_errno = errno;
44703299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
4471c2aa98e2SPeter Wemm 			}
4472c2aa98e2SPeter Wemm 		}
4473c2aa98e2SPeter Wemm 	}
44743299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
44755dd76dd0SGregory Neil Shapiro 
44765dd76dd0SGregory Neil Shapiro 	/* the function is supposed to return only the requested family */
44775dd76dd0SGregory Neil Shapiro 	if (h != NULL && h->h_addrtype != family)
44785dd76dd0SGregory Neil Shapiro 	{
44795dd76dd0SGregory Neil Shapiro #if NETINET6
44805dd76dd0SGregory Neil Shapiro 		freehostent(h);
44815b0945b5SGregory Neil Shapiro #endif
44825dd76dd0SGregory Neil Shapiro 		h = NULL;
44835dd76dd0SGregory Neil Shapiro 		SM_SET_H_ERRNO(NO_DATA);
44845dd76dd0SGregory Neil Shapiro 	}
44855dd76dd0SGregory Neil Shapiro 
4486c2aa98e2SPeter Wemm 	if (tTd(61, 10))
4487c2aa98e2SPeter Wemm 	{
4488c2aa98e2SPeter Wemm 		if (h == NULL)
44892fb4f839SGregory Neil Shapiro 			sm_dprintf("failure: errno=%d, h_errno=%d\n",
44902fb4f839SGregory Neil Shapiro 				errno, h_errno);
4491c2aa98e2SPeter Wemm 		else
44923299c2f1SGregory Neil Shapiro 		{
449312ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", h->h_name);
44943299c2f1SGregory Neil Shapiro 			if (tTd(61, 11))
44953299c2f1SGregory Neil Shapiro 			{
44965dd76dd0SGregory Neil Shapiro 				struct in_addr ia;
44975dd76dd0SGregory Neil Shapiro 				size_t i;
44983299c2f1SGregory Neil Shapiro #if NETINET6
44993299c2f1SGregory Neil Shapiro 				struct in6_addr ia6;
45003299c2f1SGregory Neil Shapiro 				char buf6[INET6_ADDRSTRLEN];
45015b0945b5SGregory Neil Shapiro #endif
45023299c2f1SGregory Neil Shapiro 
45033299c2f1SGregory Neil Shapiro 				if (h->h_aliases != NULL)
45043299c2f1SGregory Neil Shapiro 					for (i = 0; h->h_aliases[i] != NULL;
45053299c2f1SGregory Neil Shapiro 					     i++)
450612ed1c7cSGregory Neil Shapiro 						sm_dprintf("\talias: %s\n",
45073299c2f1SGregory Neil Shapiro 							h->h_aliases[i]);
45083299c2f1SGregory Neil Shapiro 				for (i = 0; h->h_addr_list[i] != NULL; i++)
45093299c2f1SGregory Neil Shapiro 				{
45103299c2f1SGregory Neil Shapiro 					char *addr;
45113299c2f1SGregory Neil Shapiro 
45125dd76dd0SGregory Neil Shapiro 					addr = NULL;
45133299c2f1SGregory Neil Shapiro #if NETINET6
45145dd76dd0SGregory Neil Shapiro 					if (h->h_addrtype == AF_INET6)
45155dd76dd0SGregory Neil Shapiro 					{
45163299c2f1SGregory Neil Shapiro 						memmove(&ia6, h->h_addr_list[i],
45173299c2f1SGregory Neil Shapiro 							IN6ADDRSZ);
45183299c2f1SGregory Neil Shapiro 						addr = anynet_ntop(&ia6,
4519951742c4SGregory Neil Shapiro 							buf6, sizeof(buf6));
45205dd76dd0SGregory Neil Shapiro 					}
45215dd76dd0SGregory Neil Shapiro 					else
45225dd76dd0SGregory Neil Shapiro #endif /* NETINET6 */
45235dd76dd0SGregory Neil Shapiro 					/* "else" in #if code above */
45245dd76dd0SGregory Neil Shapiro 					{
45253299c2f1SGregory Neil Shapiro 						memmove(&ia, h->h_addr_list[i],
45263299c2f1SGregory Neil Shapiro 							INADDRSZ);
45273299c2f1SGregory Neil Shapiro 						addr = (char *) inet_ntoa(ia);
45285dd76dd0SGregory Neil Shapiro 					}
45293299c2f1SGregory Neil Shapiro 					if (addr != NULL)
453012ed1c7cSGregory Neil Shapiro 						sm_dprintf("\taddr: %s\n", addr);
4531c2aa98e2SPeter Wemm 				}
45323299c2f1SGregory Neil Shapiro 			}
45333299c2f1SGregory Neil Shapiro 		}
45343299c2f1SGregory Neil Shapiro 	}
45353299c2f1SGregory Neil Shapiro 	errno = save_errno;
4536c2aa98e2SPeter Wemm 	return h;
4537c2aa98e2SPeter Wemm }
4538c2aa98e2SPeter Wemm 
4539c2aa98e2SPeter Wemm struct hostent *
sm_gethostbyaddr(addr,len,type)4540c2aa98e2SPeter Wemm sm_gethostbyaddr(addr, len, type)
4541c2aa98e2SPeter Wemm 	char *addr;
4542c2aa98e2SPeter Wemm 	int len;
4543c2aa98e2SPeter Wemm 	int type;
4544c2aa98e2SPeter Wemm {
45453299c2f1SGregory Neil Shapiro 	struct hostent *hp;
4546b4662009SGregory Neil Shapiro 
4547b4662009SGregory Neil Shapiro #if NETINET6
4548b4662009SGregory Neil Shapiro 	if (type == AF_INET6 &&
4549b4662009SGregory Neil Shapiro 	    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr))
4550b4662009SGregory Neil Shapiro 	{
4551b4662009SGregory Neil Shapiro 		/* Avoid reverse lookup for IPv6 unspecified address */
4552b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(HOST_NOT_FOUND);
4553b4662009SGregory Neil Shapiro 		return NULL;
4554b4662009SGregory Neil Shapiro 	}
4555b4662009SGregory Neil Shapiro #endif /* NETINET6 */
4556b4662009SGregory Neil Shapiro 
4557c2aa98e2SPeter Wemm #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204)
4558c2aa98e2SPeter Wemm # if SOLARIS == 20300 || SOLARIS == 203
4559b4662009SGregory Neil Shapiro 	{
45603299c2f1SGregory Neil Shapiro 		static struct hostent he;
4561c2aa98e2SPeter Wemm 		static char buf[1000];
4562c2aa98e2SPeter Wemm 		extern struct hostent *_switch_gethostbyaddr_r();
4563c2aa98e2SPeter Wemm 
4564b4662009SGregory Neil Shapiro 		hp = _switch_gethostbyaddr_r(addr, len, type, &he,
4565b4662009SGregory Neil Shapiro 					     buf, sizeof(buf), &h_errno);
4566b4662009SGregory Neil Shapiro 	}
45673299c2f1SGregory Neil Shapiro # else /* SOLARIS == 20300 || SOLARIS == 203 */
4568b4662009SGregory Neil Shapiro 	{
4569c2aa98e2SPeter Wemm 		extern struct hostent *__switch_gethostbyaddr();
4570c2aa98e2SPeter Wemm 
45713299c2f1SGregory Neil Shapiro 		hp = __switch_gethostbyaddr(addr, len, type);
4572b4662009SGregory Neil Shapiro 	}
45733299c2f1SGregory Neil Shapiro # endif /* SOLARIS == 20300 || SOLARIS == 203 */
45743299c2f1SGregory Neil Shapiro #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
45753299c2f1SGregory Neil Shapiro # if NETINET6
4576b4662009SGregory Neil Shapiro 	{
45773299c2f1SGregory Neil Shapiro 		int err;
45783299c2f1SGregory Neil Shapiro 
45796f9c8e5bSGregory Neil Shapiro 		hp = sm_getipnodebyaddr(addr, len, type, &err);
4580b4662009SGregory Neil Shapiro 		SM_SET_H_ERRNO(err);
4581b4662009SGregory Neil Shapiro 	}
45823299c2f1SGregory Neil Shapiro # else /* NETINET6 */
45833299c2f1SGregory Neil Shapiro 	hp = gethostbyaddr(addr, len, type);
45843299c2f1SGregory Neil Shapiro # endif /* NETINET6 */
45853299c2f1SGregory Neil Shapiro #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
4586c0c4794dSGregory Neil Shapiro 	return hp;
4587c2aa98e2SPeter Wemm }
458812ed1c7cSGregory Neil Shapiro /*
4589c2aa98e2SPeter Wemm **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
4590c2aa98e2SPeter Wemm */
4591c2aa98e2SPeter Wemm 
4592c2aa98e2SPeter Wemm struct passwd *
sm_getpwnam(user)4593c2aa98e2SPeter Wemm sm_getpwnam(user)
4594c2aa98e2SPeter Wemm 	char *user;
4595c2aa98e2SPeter Wemm {
4596c2aa98e2SPeter Wemm #ifdef _AIX4
4597c2aa98e2SPeter Wemm 	extern struct passwd *_getpwnam_shadow(const char *, const int);
4598c2aa98e2SPeter Wemm 
4599c2aa98e2SPeter Wemm 	return _getpwnam_shadow(user, 0);
46003299c2f1SGregory Neil Shapiro #else /* _AIX4 */
4601c2aa98e2SPeter Wemm 	return getpwnam(user);
46023299c2f1SGregory Neil Shapiro #endif /* _AIX4 */
4603c2aa98e2SPeter Wemm }
4604c2aa98e2SPeter Wemm 
4605c2aa98e2SPeter Wemm struct passwd *
sm_getpwuid(uid)4606c2aa98e2SPeter Wemm sm_getpwuid(uid)
4607c2aa98e2SPeter Wemm 	UID_T uid;
4608c2aa98e2SPeter Wemm {
4609c2aa98e2SPeter Wemm #if defined(_AIX4) && 0
4610c2aa98e2SPeter Wemm 	extern struct passwd *_getpwuid_shadow(const int, const int);
4611c2aa98e2SPeter Wemm 
4612c2aa98e2SPeter Wemm 	return _getpwuid_shadow(uid,0);
46133299c2f1SGregory Neil Shapiro #else /* defined(_AIX4) && 0 */
4614c2aa98e2SPeter Wemm 	return getpwuid(uid);
46153299c2f1SGregory Neil Shapiro #endif /* defined(_AIX4) && 0 */
4616c2aa98e2SPeter Wemm }
461712ed1c7cSGregory Neil Shapiro /*
4618c2aa98e2SPeter Wemm **  SECUREWARE_SETUP_SECURE -- Convex SecureWare setup
4619c2aa98e2SPeter Wemm **
4620c2aa98e2SPeter Wemm **	Set up the trusted computing environment for C2 level security
4621c2aa98e2SPeter Wemm **	under SecureWare.
4622c2aa98e2SPeter Wemm **
4623c2aa98e2SPeter Wemm **	Parameters:
4624c2aa98e2SPeter Wemm **		uid -- uid of the user to initialize in the TCB
4625c2aa98e2SPeter Wemm **
4626c2aa98e2SPeter Wemm **	Returns:
4627c2aa98e2SPeter Wemm **		none
4628c2aa98e2SPeter Wemm **
4629c2aa98e2SPeter Wemm **	Side Effects:
4630c2aa98e2SPeter Wemm **		Initialized the user in the trusted computing base
4631c2aa98e2SPeter Wemm */
4632c2aa98e2SPeter Wemm 
4633c2aa98e2SPeter Wemm #if SECUREWARE
4634c2aa98e2SPeter Wemm 
4635c2aa98e2SPeter Wemm # include <sys/security.h>
4636c2aa98e2SPeter Wemm # include <prot.h>
4637c2aa98e2SPeter Wemm 
4638c2aa98e2SPeter Wemm void
secureware_setup_secure(uid)4639c2aa98e2SPeter Wemm secureware_setup_secure(uid)
4640c2aa98e2SPeter Wemm 	UID_T uid;
4641c2aa98e2SPeter Wemm {
4642c2aa98e2SPeter Wemm 	int rc;
4643c2aa98e2SPeter Wemm 
4644c2aa98e2SPeter Wemm 	if (getluid() != -1)
4645c2aa98e2SPeter Wemm 		return;
4646c2aa98e2SPeter Wemm 
4647c2aa98e2SPeter Wemm 	if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN)
4648c2aa98e2SPeter Wemm 	{
4649c2aa98e2SPeter Wemm 		switch (rc)
4650c2aa98e2SPeter Wemm 		{
4651c2aa98e2SPeter Wemm 		  case SSI_NO_PRPW_ENTRY:
465212ed1c7cSGregory Neil Shapiro 			syserr("No protected passwd entry, uid = %d",
465312ed1c7cSGregory Neil Shapiro 			       (int) uid);
4654c2aa98e2SPeter Wemm 			break;
4655c2aa98e2SPeter Wemm 
4656c2aa98e2SPeter Wemm 		  case SSI_LOCKED:
465712ed1c7cSGregory Neil Shapiro 			syserr("Account has been disabled, uid = %d",
465812ed1c7cSGregory Neil Shapiro 			       (int) uid);
4659c2aa98e2SPeter Wemm 			break;
4660c2aa98e2SPeter Wemm 
4661c2aa98e2SPeter Wemm 		  case SSI_RETIRED:
466212ed1c7cSGregory Neil Shapiro 			syserr("Account has been retired, uid = %d",
466312ed1c7cSGregory Neil Shapiro 			       (int) uid);
4664c2aa98e2SPeter Wemm 			break;
4665c2aa98e2SPeter Wemm 
4666c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_LUID:
466712ed1c7cSGregory Neil Shapiro 			syserr("Could not set LUID, uid = %d", (int) uid);
4668c2aa98e2SPeter Wemm 			break;
4669c2aa98e2SPeter Wemm 
4670c2aa98e2SPeter Wemm 		  case SSI_BAD_SET_PRIVS:
467112ed1c7cSGregory Neil Shapiro 			syserr("Could not set kernel privs, uid = %d",
467212ed1c7cSGregory Neil Shapiro 			       (int) uid);
4673c2aa98e2SPeter Wemm 
4674c2aa98e2SPeter Wemm 		  default:
4675c2aa98e2SPeter Wemm 			syserr("Unknown return code (%d) from set_secure_info(%d)",
467612ed1c7cSGregory Neil Shapiro 				rc, (int) uid);
4677c2aa98e2SPeter Wemm 			break;
4678c2aa98e2SPeter Wemm 		}
467912ed1c7cSGregory Neil Shapiro 		finis(false, true, EX_NOPERM);
4680c2aa98e2SPeter Wemm 	}
4681c2aa98e2SPeter Wemm }
4682c2aa98e2SPeter Wemm #endif /* SECUREWARE */
468312ed1c7cSGregory Neil Shapiro /*
46843299c2f1SGregory Neil Shapiro **  ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address
468576b7bf71SPeter Wemm **
468676b7bf71SPeter Wemm **	Add hostnames to class 'w' based on the IP address read from
468776b7bf71SPeter Wemm **	the network interface.
468876b7bf71SPeter Wemm **
468976b7bf71SPeter Wemm **	Parameters:
469076b7bf71SPeter Wemm **		sa -- a pointer to a SOCKADDR containing the address
469176b7bf71SPeter Wemm **
469276b7bf71SPeter Wemm **	Returns:
469376b7bf71SPeter Wemm **		0 if successful, -1 if host lookup fails.
469476b7bf71SPeter Wemm */
469576b7bf71SPeter Wemm 
46963299c2f1SGregory Neil Shapiro static int
add_hostnames(sa)469776b7bf71SPeter Wemm add_hostnames(sa)
469876b7bf71SPeter Wemm 	SOCKADDR *sa;
469976b7bf71SPeter Wemm {
470076b7bf71SPeter Wemm 	struct hostent *hp;
47013299c2f1SGregory Neil Shapiro 	char **ha;
47023299c2f1SGregory Neil Shapiro 	char hnb[MAXHOSTNAMELEN];
470376b7bf71SPeter Wemm 
470476b7bf71SPeter Wemm 	/* look up name with IP address */
470576b7bf71SPeter Wemm 	switch (sa->sa.sa_family)
470676b7bf71SPeter Wemm 	{
47073299c2f1SGregory Neil Shapiro #if NETINET
470876b7bf71SPeter Wemm 	  case AF_INET:
470976b7bf71SPeter Wemm 		hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr,
4710c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin.sin_addr),
4711c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
471276b7bf71SPeter Wemm 		break;
47133299c2f1SGregory Neil Shapiro #endif /* NETINET */
47143299c2f1SGregory Neil Shapiro 
47153299c2f1SGregory Neil Shapiro #if NETINET6
47163299c2f1SGregory Neil Shapiro 	  case AF_INET6:
47173299c2f1SGregory Neil Shapiro 		hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr,
4718c46d91b7SGregory Neil Shapiro 				      sizeof(sa->sin6.sin6_addr),
4719c46d91b7SGregory Neil Shapiro 				      sa->sa.sa_family);
47203299c2f1SGregory Neil Shapiro 		break;
47213299c2f1SGregory Neil Shapiro #endif /* NETINET6 */
472276b7bf71SPeter Wemm 
472376b7bf71SPeter Wemm 	  default:
47243299c2f1SGregory Neil Shapiro 		/* Give warning about unsupported family */
472576b7bf71SPeter Wemm 		if (LogLevel > 3)
472676b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
472776b7bf71SPeter Wemm 				  "Unsupported address family %d: %.100s",
472876b7bf71SPeter Wemm 				  sa->sa.sa_family, anynet_ntoa(sa));
472976b7bf71SPeter Wemm 		return -1;
473076b7bf71SPeter Wemm 	}
473176b7bf71SPeter Wemm 
473276b7bf71SPeter Wemm 	if (hp == NULL)
473376b7bf71SPeter Wemm 	{
473476b7bf71SPeter Wemm 		int save_errno = errno;
473576b7bf71SPeter Wemm 
47363299c2f1SGregory Neil Shapiro 		if (LogLevel > 3 &&
4737ba00ec3dSGregory Neil Shapiro #if NETINET && defined(IN_LINKLOCAL)
4738ba00ec3dSGregory Neil Shapiro 		    !(sa->sa.sa_family == AF_INET &&
4739ba00ec3dSGregory Neil Shapiro 		      IN_LINKLOCAL(ntohl(sa->sin.sin_addr.s_addr))) &&
47405b0945b5SGregory Neil Shapiro #endif
47413299c2f1SGregory Neil Shapiro #if NETINET6
47423299c2f1SGregory Neil Shapiro 		    !(sa->sa.sa_family == AF_INET6 &&
47433299c2f1SGregory Neil Shapiro 		      IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
47445b0945b5SGregory Neil Shapiro #endif
474512ed1c7cSGregory Neil Shapiro 		    true)
474676b7bf71SPeter Wemm 			sm_syslog(LOG_WARNING, NOQID,
474712ed1c7cSGregory Neil Shapiro 				  "gethostbyaddr(%.100s) failed: %d",
474876b7bf71SPeter Wemm 				  anynet_ntoa(sa),
474976b7bf71SPeter Wemm #if NAMED_BIND
475076b7bf71SPeter Wemm 				  h_errno
47515b0945b5SGregory Neil Shapiro #else
475276b7bf71SPeter Wemm 				  -1
47535b0945b5SGregory Neil Shapiro #endif
475476b7bf71SPeter Wemm 				 );
475576b7bf71SPeter Wemm 		errno = save_errno;
475676b7bf71SPeter Wemm 		return -1;
475776b7bf71SPeter Wemm 	}
475876b7bf71SPeter Wemm 
475976b7bf71SPeter Wemm 	/* save its cname */
476076b7bf71SPeter Wemm 	if (!wordinclass((char *) hp->h_name, 'w'))
476176b7bf71SPeter Wemm 	{
476276b7bf71SPeter Wemm 		setclass('w', (char *) hp->h_name);
476376b7bf71SPeter Wemm 		if (tTd(0, 4))
476412ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s\n", hp->h_name);
47653299c2f1SGregory Neil Shapiro 
4766951742c4SGregory Neil Shapiro 		if (sm_snprintf(hnb, sizeof(hnb), "[%s]", hp->h_name) <
4767951742c4SGregory Neil Shapiro 								sizeof(hnb)
47683299c2f1SGregory Neil Shapiro 		    && !wordinclass((char *) hnb, 'w'))
47693299c2f1SGregory Neil Shapiro 			setclass('w', hnb);
47703299c2f1SGregory Neil Shapiro 	}
47713299c2f1SGregory Neil Shapiro 	else
47723299c2f1SGregory Neil Shapiro 	{
47733299c2f1SGregory Neil Shapiro 		if (tTd(0, 43))
477412ed1c7cSGregory Neil Shapiro 			sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name);
477576b7bf71SPeter Wemm 	}
477676b7bf71SPeter Wemm 
477776b7bf71SPeter Wemm 	/* save all it aliases name */
47783299c2f1SGregory Neil Shapiro 	for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
477976b7bf71SPeter Wemm 	{
47803299c2f1SGregory Neil Shapiro 		if (!wordinclass(*ha, 'w'))
478176b7bf71SPeter Wemm 		{
47823299c2f1SGregory Neil Shapiro 			setclass('w', *ha);
478376b7bf71SPeter Wemm 			if (tTd(0, 4))
478412ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", *ha);
4785951742c4SGregory Neil Shapiro 			if (sm_snprintf(hnb, sizeof(hnb),
4786951742c4SGregory Neil Shapiro 				     "[%s]", *ha) < sizeof(hnb) &&
47873299c2f1SGregory Neil Shapiro 			    !wordinclass((char *) hnb, 'w'))
47883299c2f1SGregory Neil Shapiro 				setclass('w', hnb);
478976b7bf71SPeter Wemm 		}
47903299c2f1SGregory Neil Shapiro 		else
47913299c2f1SGregory Neil Shapiro 		{
47923299c2f1SGregory Neil Shapiro 			if (tTd(0, 43))
479312ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s (already in $=w)\n",
47943299c2f1SGregory Neil Shapiro 					*ha);
47953299c2f1SGregory Neil Shapiro 		}
479676b7bf71SPeter Wemm 	}
479712ed1c7cSGregory Neil Shapiro #if NETINET6
4798c46d91b7SGregory Neil Shapiro 	freehostent(hp);
47995b0945b5SGregory Neil Shapiro #endif
480076b7bf71SPeter Wemm 	return 0;
480176b7bf71SPeter Wemm }
480212ed1c7cSGregory Neil Shapiro /*
4803c2aa98e2SPeter Wemm **  LOAD_IF_NAMES -- load interface-specific names into $=w
4804c2aa98e2SPeter Wemm **
4805c2aa98e2SPeter Wemm **	Parameters:
4806c2aa98e2SPeter Wemm **		none.
4807c2aa98e2SPeter Wemm **
4808c2aa98e2SPeter Wemm **	Returns:
4809c2aa98e2SPeter Wemm **		none.
4810c2aa98e2SPeter Wemm **
4811c2aa98e2SPeter Wemm **	Side Effects:
4812c2aa98e2SPeter Wemm **		Loads $=w with the names of all the interfaces.
4813c2aa98e2SPeter Wemm */
4814c2aa98e2SPeter Wemm 
48153299c2f1SGregory Neil Shapiro #if !NETINET
48163299c2f1SGregory Neil Shapiro # define SIOCGIFCONF_IS_BROKEN	1 /* XXX */
48175b0945b5SGregory Neil Shapiro #endif
48183299c2f1SGregory Neil Shapiro 
4819c2aa98e2SPeter Wemm #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
4820c2aa98e2SPeter Wemm struct rtentry;
4821c2aa98e2SPeter Wemm struct mbuf;
4822c2aa98e2SPeter Wemm # ifndef SUNOS403
4823567a2fc9SGregory Neil Shapiro #  include <sm/time.h>
48245b0945b5SGregory Neil Shapiro # endif
48253299c2f1SGregory Neil Shapiro # if (_AIX4 >= 40300) && !defined(_NET_IF_H)
4826c2aa98e2SPeter Wemm #  undef __P
48275b0945b5SGregory Neil Shapiro # endif
4828c2aa98e2SPeter Wemm # include <net/if.h>
48293299c2f1SGregory Neil Shapiro #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
4830c2aa98e2SPeter Wemm 
4831c2aa98e2SPeter Wemm void
load_if_names()4832c2aa98e2SPeter Wemm load_if_names()
4833c2aa98e2SPeter Wemm {
48343299c2f1SGregory Neil Shapiro #if NETINET6 && defined(SIOCGLIFCONF)
483512ed1c7cSGregory Neil Shapiro # ifdef __hpux
483612ed1c7cSGregory Neil Shapiro 
483712ed1c7cSGregory Neil Shapiro     /*
483812ed1c7cSGregory Neil Shapiro     **  Unfortunately, HP has changed all of the structures,
483912ed1c7cSGregory Neil Shapiro     **  making life difficult for implementors.
484012ed1c7cSGregory Neil Shapiro     */
484112ed1c7cSGregory Neil Shapiro 
484212ed1c7cSGregory Neil Shapiro #  define lifconf	if_laddrconf
484312ed1c7cSGregory Neil Shapiro #  define lifc_len	iflc_len
484412ed1c7cSGregory Neil Shapiro #  define lifc_buf	iflc_buf
484512ed1c7cSGregory Neil Shapiro #  define lifreq	if_laddrreq
484612ed1c7cSGregory Neil Shapiro #  define lifr_addr	iflr_addr
484712ed1c7cSGregory Neil Shapiro #  define lifr_name	iflr_name
484812ed1c7cSGregory Neil Shapiro #  define lifr_flags	iflr_flags
484912ed1c7cSGregory Neil Shapiro #  define ss_family	sa_family
485012ed1c7cSGregory Neil Shapiro #  undef SIOCGLIFNUM
485112ed1c7cSGregory Neil Shapiro # endif /* __hpux */
485212ed1c7cSGregory Neil Shapiro 
48533299c2f1SGregory Neil Shapiro 	int s;
48543299c2f1SGregory Neil Shapiro 	int i;
485512ed1c7cSGregory Neil Shapiro 	size_t len;
48563299c2f1SGregory Neil Shapiro 	int numifs;
485712ed1c7cSGregory Neil Shapiro 	char *buf;
485812ed1c7cSGregory Neil Shapiro 	struct lifconf lifc;
485912ed1c7cSGregory Neil Shapiro # ifdef SIOCGLIFNUM
486012ed1c7cSGregory Neil Shapiro 	struct lifnum lifn;
48615b0945b5SGregory Neil Shapiro # endif
48623299c2f1SGregory Neil Shapiro 
48633299c2f1SGregory Neil Shapiro 	s = socket(InetMode, SOCK_DGRAM, 0);
48643299c2f1SGregory Neil Shapiro 	if (s == -1)
48653299c2f1SGregory Neil Shapiro 		return;
48663299c2f1SGregory Neil Shapiro 
48673299c2f1SGregory Neil Shapiro 	/* get the list of known IP address from the kernel */
486812ed1c7cSGregory Neil Shapiro # ifdef __hpux
486912ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGIFNUM, (char *) &numifs);
48705b0945b5SGregory Neil Shapiro # endif
48713299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFNUM
48723299c2f1SGregory Neil Shapiro 	lifn.lifn_family = AF_UNSPEC;
48733299c2f1SGregory Neil Shapiro 	lifn.lifn_flags = 0;
487412ed1c7cSGregory Neil Shapiro 	i = ioctl(s, SIOCGLIFNUM, (char *)&lifn);
487512ed1c7cSGregory Neil Shapiro 	numifs = lifn.lifn_count;
487612ed1c7cSGregory Neil Shapiro # endif /* SIOCGLIFNUM */
487712ed1c7cSGregory Neil Shapiro 
487812ed1c7cSGregory Neil Shapiro # if defined(__hpux) || defined(SIOCGLIFNUM)
487912ed1c7cSGregory Neil Shapiro 	if (i < 0)
48803299c2f1SGregory Neil Shapiro 	{
48813299c2f1SGregory Neil Shapiro 		/* can't get number of interfaces -- fall back */
48823299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
488312ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFNUM failed: %s\n",
488412ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
48853299c2f1SGregory Neil Shapiro 		numifs = -1;
48863299c2f1SGregory Neil Shapiro 	}
488712ed1c7cSGregory Neil Shapiro 	else if (tTd(0, 42))
488812ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
48893299c2f1SGregory Neil Shapiro 	if (numifs < 0)
489012ed1c7cSGregory Neil Shapiro # endif /* defined(__hpux) || defined(SIOCGLIFNUM) */
48913299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
48923299c2f1SGregory Neil Shapiro 
48933299c2f1SGregory Neil Shapiro 	if (numifs <= 0)
48943299c2f1SGregory Neil Shapiro 	{
4895c46d91b7SGregory Neil Shapiro 		(void) close(s);
48963299c2f1SGregory Neil Shapiro 		return;
48973299c2f1SGregory Neil Shapiro 	}
489812ed1c7cSGregory Neil Shapiro 
489912ed1c7cSGregory Neil Shapiro 	len = lifc.lifc_len = numifs * sizeof(struct lifreq);
490012ed1c7cSGregory Neil Shapiro 	buf = lifc.lifc_buf = xalloc(lifc.lifc_len);
490112ed1c7cSGregory Neil Shapiro # ifndef __hpux
49023299c2f1SGregory Neil Shapiro 	lifc.lifc_family = AF_UNSPEC;
49033299c2f1SGregory Neil Shapiro 	lifc.lifc_flags = 0;
49045b0945b5SGregory Neil Shapiro # endif
49053299c2f1SGregory Neil Shapiro 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
49063299c2f1SGregory Neil Shapiro 	{
49073299c2f1SGregory Neil Shapiro 		if (tTd(0, 4))
490812ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGLIFCONF failed: %s\n",
490912ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
4910c46d91b7SGregory Neil Shapiro 		(void) close(s);
491112ed1c7cSGregory Neil Shapiro 		sm_free(buf);
49123299c2f1SGregory Neil Shapiro 		return;
49133299c2f1SGregory Neil Shapiro 	}
49143299c2f1SGregory Neil Shapiro 
49153299c2f1SGregory Neil Shapiro 	/* scan the list of IP address */
49163299c2f1SGregory Neil Shapiro 	if (tTd(0, 40))
491712ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, lifc_len=%ld\n",
491812ed1c7cSGregory Neil Shapiro 			   (long) len);
49193299c2f1SGregory Neil Shapiro 
492012ed1c7cSGregory Neil Shapiro 	for (i = 0; i < len && i >= 0; )
49213299c2f1SGregory Neil Shapiro 	{
492212ed1c7cSGregory Neil Shapiro 		int flags;
492312ed1c7cSGregory Neil Shapiro 		struct lifreq *ifr = (struct lifreq *)&buf[i];
49243299c2f1SGregory Neil Shapiro 		SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr;
492512ed1c7cSGregory Neil Shapiro 		int af = ifr->lifr_addr.ss_family;
49263299c2f1SGregory Neil Shapiro 		char *addr;
492712ed1c7cSGregory Neil Shapiro 		char *name;
49283299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
49293299c2f1SGregory Neil Shapiro 		struct in_addr ia;
49303299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS
49313299c2f1SGregory Neil Shapiro 		struct lifreq ifrf;
49325b0945b5SGregory Neil Shapiro # endif
49333299c2f1SGregory Neil Shapiro 		char ip_addr[256];
49343299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
49353299c2f1SGregory Neil Shapiro 
49363299c2f1SGregory Neil Shapiro 		/*
49373299c2f1SGregory Neil Shapiro 		**  We must close and recreate the socket each time
49383299c2f1SGregory Neil Shapiro 		**  since we don't know what type of socket it is now
49393299c2f1SGregory Neil Shapiro 		**  (each status function may change it).
49403299c2f1SGregory Neil Shapiro 		*/
49413299c2f1SGregory Neil Shapiro 
49423299c2f1SGregory Neil Shapiro 		(void) close(s);
49433299c2f1SGregory Neil Shapiro 
49443299c2f1SGregory Neil Shapiro 		s = socket(af, SOCK_DGRAM, 0);
49453299c2f1SGregory Neil Shapiro 		if (s == -1)
4946c46d91b7SGregory Neil Shapiro 		{
494712ed1c7cSGregory Neil Shapiro 			sm_free(buf); /* XXX */
49483299c2f1SGregory Neil Shapiro 			return;
4949c46d91b7SGregory Neil Shapiro 		}
49503299c2f1SGregory Neil Shapiro 
49513299c2f1SGregory Neil Shapiro 		/*
49523299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
49533299c2f1SGregory Neil Shapiro 		**  don't try to use it.
49543299c2f1SGregory Neil Shapiro 		*/
49553299c2f1SGregory Neil Shapiro 
4956951742c4SGregory Neil Shapiro 		if ((len - i) < sizeof(*ifr))
49573299c2f1SGregory Neil Shapiro 			break;
49583299c2f1SGregory Neil Shapiro 
49593299c2f1SGregory Neil Shapiro # ifdef BSD4_4_SOCKADDR
4960951742c4SGregory Neil Shapiro 		if (sa->sa.sa_len > sizeof(ifr->lifr_addr))
4961951742c4SGregory Neil Shapiro 			i += sizeof(ifr->lifr_name) + sa->sa.sa_len;
49623299c2f1SGregory Neil Shapiro 		else
49633299c2f1SGregory Neil Shapiro # endif /* BSD4_4_SOCKADDR */
49642fb4f839SGregory Neil Shapiro 		/* "else" in #if code above */
49652fb4f839SGregory Neil Shapiro 		{
4966567a2fc9SGregory Neil Shapiro # ifdef DEC
4967567a2fc9SGregory Neil Shapiro 			/* fix for IPv6  size differences */
4968951742c4SGregory Neil Shapiro 			i += sizeof(ifr->ifr_name) +
4969567a2fc9SGregory Neil Shapiro 			     max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
4970567a2fc9SGregory Neil Shapiro # else /* DEC */
4971951742c4SGregory Neil Shapiro 			i += sizeof(*ifr);
4972567a2fc9SGregory Neil Shapiro # endif /* DEC */
49732fb4f839SGregory Neil Shapiro 		}
49743299c2f1SGregory Neil Shapiro 
49753299c2f1SGregory Neil Shapiro 		if (tTd(0, 20))
497612ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
49773299c2f1SGregory Neil Shapiro 
49783299c2f1SGregory Neil Shapiro 		if (af != AF_INET && af != AF_INET6)
49793299c2f1SGregory Neil Shapiro 			continue;
49803299c2f1SGregory Neil Shapiro 
49813299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS
49823299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct lifreq));
498312ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name,
49843299c2f1SGregory Neil Shapiro 				  sizeof(ifrf.lifr_name));
49853299c2f1SGregory Neil Shapiro 		if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0)
49863299c2f1SGregory Neil Shapiro 		{
49873299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
498812ed1c7cSGregory Neil Shapiro 				sm_dprintf("SIOCGLIFFLAGS failed: %s\n",
498912ed1c7cSGregory Neil Shapiro 					   sm_errstring(errno));
49903299c2f1SGregory Neil Shapiro 			continue;
49913299c2f1SGregory Neil Shapiro 		}
49923299c2f1SGregory Neil Shapiro 
499312ed1c7cSGregory Neil Shapiro 		name = ifr->lifr_name;
499412ed1c7cSGregory Neil Shapiro 		flags = ifrf.lifr_flags;
499512ed1c7cSGregory Neil Shapiro 
499612ed1c7cSGregory Neil Shapiro 		if (tTd(0, 41))
499712ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n", (unsigned long) flags);
499812ed1c7cSGregory Neil Shapiro 
499912ed1c7cSGregory Neil Shapiro 		if (!bitset(IFF_UP, flags))
50003299c2f1SGregory Neil Shapiro 			continue;
50013299c2f1SGregory Neil Shapiro # endif /* SIOCGLIFFLAGS */
50023299c2f1SGregory Neil Shapiro 
50033299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
50043299c2f1SGregory Neil Shapiro 
50053299c2f1SGregory Neil Shapiro 		/* extract IP address from the list*/
50063299c2f1SGregory Neil Shapiro 		switch (af)
50073299c2f1SGregory Neil Shapiro 		{
50083299c2f1SGregory Neil Shapiro 		  case AF_INET6:
50096f9c8e5bSGregory Neil Shapiro 			SETV6LOOPBACKADDRFOUND(*sa);
5010c46d91b7SGregory Neil Shapiro # ifdef __KAME__
5011b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
5012b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
5013b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
5014c46d91b7SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
5015c46d91b7SGregory Neil Shapiro 			{
5016b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
5017b4662009SGregory Neil Shapiro 
5018b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
5019b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
5020b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
5021b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
5022c46d91b7SGregory Neil Shapiro 			}
5023c46d91b7SGregory Neil Shapiro # endif /* __KAME__ */
5024b4662009SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
5025c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
50263299c2f1SGregory Neil Shapiro 			{
5027951742c4SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
50283299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
502912ed1c7cSGregory Neil Shapiro 					name, addr == NULL ? "(NULL)" : addr);
50303299c2f1SGregory Neil Shapiro 				continue;
50313299c2f1SGregory Neil Shapiro 			}
50323299c2f1SGregory Neil Shapiro 
50333299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
5034951742c4SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
50353299c2f1SGregory Neil Shapiro 			if (addr != NULL)
5036951742c4SGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof(ip_addr),
50373299c2f1SGregory Neil Shapiro 						   "[%.*s]",
5038951742c4SGregory Neil Shapiro 						   (int) sizeof(ip_addr) - 3,
503912ed1c7cSGregory Neil Shapiro 						   addr);
50403299c2f1SGregory Neil Shapiro 			break;
50413299c2f1SGregory Neil Shapiro 
50423299c2f1SGregory Neil Shapiro 		  case AF_INET:
50433299c2f1SGregory Neil Shapiro 			ia = sa->sin.sin_addr;
50443299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
50453299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
50463299c2f1SGregory Neil Shapiro 			{
50473299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
504812ed1c7cSGregory Neil Shapiro 					name, inet_ntoa(ia));
50493299c2f1SGregory Neil Shapiro 				continue;
50503299c2f1SGregory Neil Shapiro 			}
50513299c2f1SGregory Neil Shapiro 
50523299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
5053951742c4SGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof(ip_addr), "[%.*s]",
5054951742c4SGregory Neil Shapiro 					(int) sizeof(ip_addr) - 3, inet_ntoa(ia));
50553299c2f1SGregory Neil Shapiro 			break;
50563299c2f1SGregory Neil Shapiro 		}
50573299c2f1SGregory Neil Shapiro 
50583299c2f1SGregory Neil Shapiro 		if (*ip_addr == '\0')
50593299c2f1SGregory Neil Shapiro 			continue;
50603299c2f1SGregory Neil Shapiro 
50613299c2f1SGregory Neil Shapiro 		if (!wordinclass(ip_addr, 'w'))
50623299c2f1SGregory Neil Shapiro 		{
50633299c2f1SGregory Neil Shapiro 			setclass('w', ip_addr);
50643299c2f1SGregory Neil Shapiro 			if (tTd(0, 4))
506512ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
50663299c2f1SGregory Neil Shapiro 		}
50673299c2f1SGregory Neil Shapiro 
50683299c2f1SGregory Neil Shapiro # ifdef SIOCGLIFFLAGS
50693299c2f1SGregory Neil Shapiro 		/* skip "loopback" interface "lo" */
507012ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
507112ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, flags))
50723299c2f1SGregory Neil Shapiro 			continue;
50733299c2f1SGregory Neil Shapiro # endif /* SIOCGLIFFLAGS */
50743299c2f1SGregory Neil Shapiro 		(void) add_hostnames(sa);
50753299c2f1SGregory Neil Shapiro 	}
507612ed1c7cSGregory Neil Shapiro 	sm_free(buf); /* XXX */
5077c46d91b7SGregory Neil Shapiro 	(void) close(s);
50783299c2f1SGregory Neil Shapiro #else /* NETINET6 && defined(SIOCGLIFCONF) */
5079c2aa98e2SPeter Wemm # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
5080c2aa98e2SPeter Wemm 	int s;
5081c2aa98e2SPeter Wemm 	int i;
5082c2aa98e2SPeter Wemm 	struct ifconf ifc;
5083c2aa98e2SPeter Wemm 	int numifs;
5084c2aa98e2SPeter Wemm 
5085c2aa98e2SPeter Wemm 	s = socket(AF_INET, SOCK_DGRAM, 0);
5086c2aa98e2SPeter Wemm 	if (s == -1)
5087c2aa98e2SPeter Wemm 		return;
5088c2aa98e2SPeter Wemm 
5089c2aa98e2SPeter Wemm 	/* get the list of known IP address from the kernel */
5090c2aa98e2SPeter Wemm #  if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN
5091c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
5092c2aa98e2SPeter Wemm 	{
5093c2aa98e2SPeter Wemm 		/* can't get number of interfaces -- fall back */
5094c2aa98e2SPeter Wemm 		if (tTd(0, 4))
509512ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFNUM failed: %s\n",
509612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
5097c2aa98e2SPeter Wemm 		numifs = -1;
5098c2aa98e2SPeter Wemm 	}
5099c2aa98e2SPeter Wemm 	else if (tTd(0, 42))
510012ed1c7cSGregory Neil Shapiro 		sm_dprintf("system has %d interfaces\n", numifs);
5101c2aa98e2SPeter Wemm 	if (numifs < 0)
51023299c2f1SGregory Neil Shapiro #  endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */
51033299c2f1SGregory Neil Shapiro 		numifs = MAXINTERFACES;
5104c2aa98e2SPeter Wemm 
5105c2aa98e2SPeter Wemm 	if (numifs <= 0)
5106c2aa98e2SPeter Wemm 	{
51073299c2f1SGregory Neil Shapiro 		(void) close(s);
5108c2aa98e2SPeter Wemm 		return;
5109c2aa98e2SPeter Wemm 	}
5110c2aa98e2SPeter Wemm 	ifc.ifc_len = numifs * sizeof(struct ifreq);
5111c2aa98e2SPeter Wemm 	ifc.ifc_buf = xalloc(ifc.ifc_len);
5112c2aa98e2SPeter Wemm 	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
5113c2aa98e2SPeter Wemm 	{
5114c2aa98e2SPeter Wemm 		if (tTd(0, 4))
511512ed1c7cSGregory Neil Shapiro 			sm_dprintf("SIOCGIFCONF failed: %s\n",
511612ed1c7cSGregory Neil Shapiro 				   sm_errstring(errno));
51173299c2f1SGregory Neil Shapiro 		(void) close(s);
5118c2aa98e2SPeter Wemm 		return;
5119c2aa98e2SPeter Wemm 	}
5120c2aa98e2SPeter Wemm 
5121c2aa98e2SPeter Wemm 	/* scan the list of IP address */
5122c2aa98e2SPeter Wemm 	if (tTd(0, 40))
512312ed1c7cSGregory Neil Shapiro 		sm_dprintf("scanning for interface specific names, ifc_len=%d\n",
5124c2aa98e2SPeter Wemm 			ifc.ifc_len);
5125c2aa98e2SPeter Wemm 
512612ed1c7cSGregory Neil Shapiro 	for (i = 0; i < ifc.ifc_len && i >= 0; )
5127c2aa98e2SPeter Wemm 	{
51283299c2f1SGregory Neil Shapiro 		int af;
51292fb4f839SGregory Neil Shapiro #  if HAVE_IFC_BUF_VOID
51302fb4f839SGregory Neil Shapiro 		struct ifreq *ifr = (struct ifreq *) &((char *)ifc.ifc_buf)[i];
51312fb4f839SGregory Neil Shapiro #  else
5132c2aa98e2SPeter Wemm 		struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
51332fb4f839SGregory Neil Shapiro #  endif
513476b7bf71SPeter Wemm 		SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr;
51353299c2f1SGregory Neil Shapiro #  if NETINET6
51363299c2f1SGregory Neil Shapiro 		char *addr;
51373299c2f1SGregory Neil Shapiro 		struct in6_addr ia6;
51385b0945b5SGregory Neil Shapiro #  endif
5139c2aa98e2SPeter Wemm 		struct in_addr ia;
5140c2aa98e2SPeter Wemm #  ifdef SIOCGIFFLAGS
5141c2aa98e2SPeter Wemm 		struct ifreq ifrf;
51425b0945b5SGregory Neil Shapiro #  endif
5143c2aa98e2SPeter Wemm 		char ip_addr[256];
51443299c2f1SGregory Neil Shapiro #  if NETINET6
51453299c2f1SGregory Neil Shapiro 		char buf6[INET6_ADDRSTRLEN];
51465b0945b5SGregory Neil Shapiro #  endif
51473299c2f1SGregory Neil Shapiro 
51483299c2f1SGregory Neil Shapiro 		/*
51493299c2f1SGregory Neil Shapiro 		**  If we don't have a complete ifr structure,
51503299c2f1SGregory Neil Shapiro 		**  don't try to use it.
51513299c2f1SGregory Neil Shapiro 		*/
51523299c2f1SGregory Neil Shapiro 
5153951742c4SGregory Neil Shapiro 		if ((ifc.ifc_len - i) < sizeof(*ifr))
51543299c2f1SGregory Neil Shapiro 			break;
5155c2aa98e2SPeter Wemm 
5156c2aa98e2SPeter Wemm #  ifdef BSD4_4_SOCKADDR
5157951742c4SGregory Neil Shapiro 		if (sa->sa.sa_len > sizeof(ifr->ifr_addr))
5158951742c4SGregory Neil Shapiro 			i += sizeof(ifr->ifr_name) + sa->sa.sa_len;
5159c2aa98e2SPeter Wemm 		else
51603299c2f1SGregory Neil Shapiro #  endif /* BSD4_4_SOCKADDR */
51612fb4f839SGregory Neil Shapiro 		/* "else" in #if code above */
51622fb4f839SGregory Neil Shapiro 		{
5163951742c4SGregory Neil Shapiro 			i += sizeof(*ifr);
51642fb4f839SGregory Neil Shapiro 		}
5165c2aa98e2SPeter Wemm 
5166c2aa98e2SPeter Wemm 		if (tTd(0, 20))
516712ed1c7cSGregory Neil Shapiro 			sm_dprintf("%s\n", anynet_ntoa(sa));
5168c2aa98e2SPeter Wemm 
51693299c2f1SGregory Neil Shapiro 		af = ifr->ifr_addr.sa_family;
51703299c2f1SGregory Neil Shapiro 		if (af != AF_INET
51713299c2f1SGregory Neil Shapiro #  if NETINET6
51723299c2f1SGregory Neil Shapiro 		    && af != AF_INET6
51735b0945b5SGregory Neil Shapiro #  endif
51743299c2f1SGregory Neil Shapiro 		    )
5175c2aa98e2SPeter Wemm 			continue;
5176c2aa98e2SPeter Wemm 
5177c2aa98e2SPeter Wemm #  ifdef SIOCGIFFLAGS
51783299c2f1SGregory Neil Shapiro 		memset(&ifrf, '\0', sizeof(struct ifreq));
517912ed1c7cSGregory Neil Shapiro 		(void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name,
51803299c2f1SGregory Neil Shapiro 			       sizeof(ifrf.ifr_name));
51813299c2f1SGregory Neil Shapiro 		(void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
5182c2aa98e2SPeter Wemm 		if (tTd(0, 41))
518312ed1c7cSGregory Neil Shapiro 			sm_dprintf("\tflags: %lx\n",
51843299c2f1SGregory Neil Shapiro 				(unsigned long) ifrf.ifr_flags);
5185c2aa98e2SPeter Wemm #   define IFRFREF ifrf
51863299c2f1SGregory Neil Shapiro #  else /* SIOCGIFFLAGS */
5187c2aa98e2SPeter Wemm #   define IFRFREF (*ifr)
51883299c2f1SGregory Neil Shapiro #  endif /* SIOCGIFFLAGS */
51893299c2f1SGregory Neil Shapiro 
5190c2aa98e2SPeter Wemm 		if (!bitset(IFF_UP, IFRFREF.ifr_flags))
5191c2aa98e2SPeter Wemm 			continue;
5192c2aa98e2SPeter Wemm 
51933299c2f1SGregory Neil Shapiro 		ip_addr[0] = '\0';
51943299c2f1SGregory Neil Shapiro 
5195c2aa98e2SPeter Wemm 		/* extract IP address from the list*/
51963299c2f1SGregory Neil Shapiro 		switch (af)
51973299c2f1SGregory Neil Shapiro 		{
51983299c2f1SGregory Neil Shapiro 		  case AF_INET:
519976b7bf71SPeter Wemm 			ia = sa->sin.sin_addr;
52003299c2f1SGregory Neil Shapiro 			if (ia.s_addr == INADDR_ANY ||
52013299c2f1SGregory Neil Shapiro 			    ia.s_addr == INADDR_NONE)
5202c2aa98e2SPeter Wemm 			{
5203c2aa98e2SPeter Wemm 				message("WARNING: interface %s is UP with %s address",
5204c2aa98e2SPeter Wemm 					ifr->ifr_name, inet_ntoa(ia));
5205c2aa98e2SPeter Wemm 				continue;
5206c2aa98e2SPeter Wemm 			}
5207c2aa98e2SPeter Wemm 
5208c2aa98e2SPeter Wemm 			/* save IP address in text from */
5209951742c4SGregory Neil Shapiro 			(void) sm_snprintf(ip_addr, sizeof(ip_addr), "[%.*s]",
5210951742c4SGregory Neil Shapiro 					(int) sizeof(ip_addr) - 3,
5211c2aa98e2SPeter Wemm 					inet_ntoa(ia));
52123299c2f1SGregory Neil Shapiro 			break;
52133299c2f1SGregory Neil Shapiro 
52143299c2f1SGregory Neil Shapiro #  if NETINET6
52153299c2f1SGregory Neil Shapiro 		  case AF_INET6:
52166f9c8e5bSGregory Neil Shapiro 			SETV6LOOPBACKADDRFOUND(*sa);
5217b4662009SGregory Neil Shapiro #   ifdef __KAME__
5218b4662009SGregory Neil Shapiro 			/* convert into proper scoped address */
5219b4662009SGregory Neil Shapiro 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
5220b4662009SGregory Neil Shapiro 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
5221b4662009SGregory Neil Shapiro 			    sa->sin6.sin6_scope_id == 0)
5222b4662009SGregory Neil Shapiro 			{
5223b4662009SGregory Neil Shapiro 				struct in6_addr *ia6p;
5224b4662009SGregory Neil Shapiro 
5225b4662009SGregory Neil Shapiro 				ia6p = &sa->sin6.sin6_addr;
5226b4662009SGregory Neil Shapiro 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
5227b4662009SGregory Neil Shapiro 							       ((unsigned int)ia6p->s6_addr[2] << 8));
5228b4662009SGregory Neil Shapiro 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
5229b4662009SGregory Neil Shapiro 			}
5230b4662009SGregory Neil Shapiro #   endif /* __KAME__ */
52313299c2f1SGregory Neil Shapiro 			ia6 = sa->sin6.sin6_addr;
5232c46d91b7SGregory Neil Shapiro 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
52333299c2f1SGregory Neil Shapiro 			{
5234951742c4SGregory Neil Shapiro 				addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
52353299c2f1SGregory Neil Shapiro 				message("WARNING: interface %s is UP with %s address",
52363299c2f1SGregory Neil Shapiro 					ifr->ifr_name,
52373299c2f1SGregory Neil Shapiro 					addr == NULL ? "(NULL)" : addr);
52383299c2f1SGregory Neil Shapiro 				continue;
52393299c2f1SGregory Neil Shapiro 			}
52403299c2f1SGregory Neil Shapiro 
52413299c2f1SGregory Neil Shapiro 			/* save IP address in text from */
5242951742c4SGregory Neil Shapiro 			addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
52433299c2f1SGregory Neil Shapiro 			if (addr != NULL)
5244951742c4SGregory Neil Shapiro 				(void) sm_snprintf(ip_addr, sizeof(ip_addr),
52453299c2f1SGregory Neil Shapiro 						   "[%.*s]",
5246951742c4SGregory Neil Shapiro 						   (int) sizeof(ip_addr) - 3,
524712ed1c7cSGregory Neil Shapiro 						   addr);
52483299c2f1SGregory Neil Shapiro 			break;
52493299c2f1SGregory Neil Shapiro 
52503299c2f1SGregory Neil Shapiro #  endif /* NETINET6 */
52513299c2f1SGregory Neil Shapiro 		}
52523299c2f1SGregory Neil Shapiro 
52533299c2f1SGregory Neil Shapiro 		if (ip_addr[0] == '\0')
52543299c2f1SGregory Neil Shapiro 			continue;
52553299c2f1SGregory Neil Shapiro 
5256c2aa98e2SPeter Wemm 		if (!wordinclass(ip_addr, 'w'))
5257c2aa98e2SPeter Wemm 		{
5258c2aa98e2SPeter Wemm 			setclass('w', ip_addr);
5259c2aa98e2SPeter Wemm 			if (tTd(0, 4))
526012ed1c7cSGregory Neil Shapiro 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
5261c2aa98e2SPeter Wemm 		}
5262c2aa98e2SPeter Wemm 
5263c2aa98e2SPeter Wemm 		/* skip "loopback" interface "lo" */
526412ed1c7cSGregory Neil Shapiro 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
526512ed1c7cSGregory Neil Shapiro 		    bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
5266c2aa98e2SPeter Wemm 			continue;
5267c2aa98e2SPeter Wemm 
526876b7bf71SPeter Wemm 		(void) add_hostnames(sa);
5269c2aa98e2SPeter Wemm 	}
527012ed1c7cSGregory Neil Shapiro 	sm_free(ifc.ifc_buf); /* XXX */
52713299c2f1SGregory Neil Shapiro 	(void) close(s);
5272c2aa98e2SPeter Wemm #  undef IFRFREF
52733299c2f1SGregory Neil Shapiro # endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
52743299c2f1SGregory Neil Shapiro #endif /* NETINET6 && defined(SIOCGLIFCONF) */
52753299c2f1SGregory Neil Shapiro }
527612ed1c7cSGregory Neil Shapiro /*
52773299c2f1SGregory Neil Shapiro **  ISLOOPBACK -- is socket address in the loopback net?
52783299c2f1SGregory Neil Shapiro **
52793299c2f1SGregory Neil Shapiro **	Parameters:
52803299c2f1SGregory Neil Shapiro **		sa -- socket address.
52813299c2f1SGregory Neil Shapiro **
52823299c2f1SGregory Neil Shapiro **	Returns:
528312ed1c7cSGregory Neil Shapiro **		true -- is socket address in the loopback net?
528412ed1c7cSGregory Neil Shapiro **		false -- otherwise
52853299c2f1SGregory Neil Shapiro **
52863299c2f1SGregory Neil Shapiro */
52873299c2f1SGregory Neil Shapiro 
52883299c2f1SGregory Neil Shapiro bool
isloopback(sa)52893299c2f1SGregory Neil Shapiro isloopback(sa)
52903299c2f1SGregory Neil Shapiro 	SOCKADDR sa;
52913299c2f1SGregory Neil Shapiro {
52923299c2f1SGregory Neil Shapiro 	/* XXX how to correctly extract IN_LOOPBACKNET part? */
5293*d39bd2c1SGregory Neil Shapiro #ifdef IN_LOOPBACK
5294*d39bd2c1SGregory Neil Shapiro # define SM_IS_IPV4_LOOP(a) IN_LOOPBACK(ntohl(a))
5295*d39bd2c1SGregory Neil Shapiro #else /* IN_LOOPBACK */
52965b0945b5SGregory Neil Shapiro # define SM_IS_IPV4_LOOP(a) (((ntohl(a) & IN_CLASSA_NET) \
52973299c2f1SGregory Neil Shapiro 	     >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
5298*d39bd2c1SGregory Neil Shapiro # endif /* IN_LOOPBACK */
52995b0945b5SGregory Neil Shapiro #if NETINET6
53005b0945b5SGregory Neil Shapiro 	if (sa.sa.sa_family == AF_INET6 &&
53015b0945b5SGregory Neil Shapiro 	    IN6_IS_ADDR_V4MAPPED(&sa.sin6.sin6_addr) &&
53025b0945b5SGregory Neil Shapiro 	    SM_IS_IPV4_LOOP(((uint32_t *) (&sa.sin6.sin6_addr))[3]))
530312ed1c7cSGregory Neil Shapiro 		return true;
53045b0945b5SGregory Neil Shapiro 	if (sa.sa.sa_family == AF_INET6 &&
53055b0945b5SGregory Neil Shapiro 	    IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
53065b0945b5SGregory Neil Shapiro 		return true;
53075b0945b5SGregory Neil Shapiro #endif
53085b0945b5SGregory Neil Shapiro #if NETINET
53095b0945b5SGregory Neil Shapiro 	if (sa.sa.sa_family == AF_INET &&
53105b0945b5SGregory Neil Shapiro 	    SM_IS_IPV4_LOOP(sa.sin.sin_addr.s_addr))
53115b0945b5SGregory Neil Shapiro 		return true;
53125b0945b5SGregory Neil Shapiro #endif
531312ed1c7cSGregory Neil Shapiro 	return false;
5314c2aa98e2SPeter Wemm }
53155b0945b5SGregory Neil Shapiro 
531612ed1c7cSGregory Neil Shapiro /*
5317c2aa98e2SPeter Wemm **  GET_NUM_PROCS_ONLINE -- return the number of processors currently online
5318c2aa98e2SPeter Wemm **
5319c2aa98e2SPeter Wemm **	Parameters:
5320c2aa98e2SPeter Wemm **		none.
5321c2aa98e2SPeter Wemm **
5322c2aa98e2SPeter Wemm **	Returns:
5323c2aa98e2SPeter Wemm **		The number of processors online.
5324c2aa98e2SPeter Wemm */
5325c2aa98e2SPeter Wemm 
53263299c2f1SGregory Neil Shapiro static int
get_num_procs_online()5327c2aa98e2SPeter Wemm get_num_procs_online()
5328c2aa98e2SPeter Wemm {
5329c2aa98e2SPeter Wemm 	int nproc = 0;
5330c2aa98e2SPeter Wemm 
53313299c2f1SGregory Neil Shapiro #ifdef USESYSCTL
53323299c2f1SGregory Neil Shapiro # if defined(CTL_HW) && defined(HW_NCPU)
53333299c2f1SGregory Neil Shapiro 	size_t sz;
53343299c2f1SGregory Neil Shapiro 	int mib[2];
53353299c2f1SGregory Neil Shapiro 
53363299c2f1SGregory Neil Shapiro 	mib[0] = CTL_HW;
53373299c2f1SGregory Neil Shapiro 	mib[1] = HW_NCPU;
5338951742c4SGregory Neil Shapiro 	sz = (size_t) sizeof(nproc);
53393299c2f1SGregory Neil Shapiro 	(void) sysctl(mib, 2, &nproc, &sz, NULL, 0);
534012ed1c7cSGregory Neil Shapiro # endif /* defined(CTL_HW) && defined(HW_NCPU) */
53413299c2f1SGregory Neil Shapiro #else /* USESYSCTL */
5342c2aa98e2SPeter Wemm # ifdef _SC_NPROCESSORS_ONLN
5343c2aa98e2SPeter Wemm 	nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
53443299c2f1SGregory Neil Shapiro # else /* _SC_NPROCESSORS_ONLN */
53453299c2f1SGregory Neil Shapiro #  ifdef __hpux
53463299c2f1SGregory Neil Shapiro #   include <sys/pstat.h>
53473299c2f1SGregory Neil Shapiro 	struct pst_dynamic psd;
53483299c2f1SGregory Neil Shapiro 
53493299c2f1SGregory Neil Shapiro 	if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1)
53503299c2f1SGregory Neil Shapiro 		nproc = psd.psd_proc_cnt;
53513299c2f1SGregory Neil Shapiro #  endif /* __hpux */
53523299c2f1SGregory Neil Shapiro # endif /* _SC_NPROCESSORS_ONLN */
53533299c2f1SGregory Neil Shapiro #endif /* USESYSCTL */
53543299c2f1SGregory Neil Shapiro 
5355c2aa98e2SPeter Wemm 	if (nproc <= 0)
5356c2aa98e2SPeter Wemm 		nproc = 1;
5357c2aa98e2SPeter Wemm 	return nproc;
5358c2aa98e2SPeter Wemm }
535912ed1c7cSGregory Neil Shapiro /*
5360bfb62e91SGregory Neil Shapiro **  SM_CLOSEFROM -- close file descriptors
5361bfb62e91SGregory Neil Shapiro **
5362bfb62e91SGregory Neil Shapiro **	Parameters:
5363bfb62e91SGregory Neil Shapiro **		lowest -- first fd to close
5364bfb62e91SGregory Neil Shapiro **		highest -- last fd + 1 to close
5365bfb62e91SGregory Neil Shapiro **
5366bfb62e91SGregory Neil Shapiro **	Returns:
5367bfb62e91SGregory Neil Shapiro **		none
5368bfb62e91SGregory Neil Shapiro */
5369bfb62e91SGregory Neil Shapiro 
5370bfb62e91SGregory Neil Shapiro void
sm_closefrom(lowest,highest)5371bfb62e91SGregory Neil Shapiro sm_closefrom(lowest, highest)
5372bfb62e91SGregory Neil Shapiro 	int lowest, highest;
5373bfb62e91SGregory Neil Shapiro {
5374bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM
5375bfb62e91SGregory Neil Shapiro 	closefrom(lowest);
5376bfb62e91SGregory Neil Shapiro #else /* HASCLOSEFROM */
5377bfb62e91SGregory Neil Shapiro 	int i;
5378bfb62e91SGregory Neil Shapiro 
5379bfb62e91SGregory Neil Shapiro 	for (i = lowest; i < highest; i++)
5380bfb62e91SGregory Neil Shapiro 		(void) close(i);
5381bfb62e91SGregory Neil Shapiro #endif /* HASCLOSEFROM */
5382bfb62e91SGregory Neil Shapiro }
5383bfb62e91SGregory Neil Shapiro #if HASFDWALK
5384bfb62e91SGregory Neil Shapiro /*
5385bfb62e91SGregory Neil Shapiro **  CLOSEFD_WALK -- walk fd's arranging to close them
5386bfb62e91SGregory Neil Shapiro **	Callback for fdwalk()
5387bfb62e91SGregory Neil Shapiro **
5388bfb62e91SGregory Neil Shapiro **	Parameters:
5389bfb62e91SGregory Neil Shapiro **		lowest -- first fd to arrange to be closed
5390bfb62e91SGregory Neil Shapiro **		fd -- fd to arrange to be closed
5391bfb62e91SGregory Neil Shapiro **
5392bfb62e91SGregory Neil Shapiro **	Returns:
5393bfb62e91SGregory Neil Shapiro **		zero
5394bfb62e91SGregory Neil Shapiro */
5395bfb62e91SGregory Neil Shapiro 
5396bfb62e91SGregory Neil Shapiro static int
closefd_walk(lowest,fd)5397bfb62e91SGregory Neil Shapiro closefd_walk(lowest, fd)
5398bfb62e91SGregory Neil Shapiro 	void *lowest;
5399bfb62e91SGregory Neil Shapiro 	int fd;
5400bfb62e91SGregory Neil Shapiro {
5401bfb62e91SGregory Neil Shapiro 	if (fd >= *(int *)lowest)
5402bfb62e91SGregory Neil Shapiro 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
5403bfb62e91SGregory Neil Shapiro 	return 0;
5404bfb62e91SGregory Neil Shapiro }
5405bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */
5406bfb62e91SGregory Neil Shapiro /*
5407bfb62e91SGregory Neil Shapiro **  SM_CLOSE_ON_EXEC -- arrange for file descriptors to be closed
5408bfb62e91SGregory Neil Shapiro **
5409bfb62e91SGregory Neil Shapiro **	Parameters:
5410bfb62e91SGregory Neil Shapiro **		lowest -- first fd to arrange to be closed
5411bfb62e91SGregory Neil Shapiro **		highest -- last fd + 1 to arrange to be closed
5412bfb62e91SGregory Neil Shapiro **
5413bfb62e91SGregory Neil Shapiro **	Returns:
5414bfb62e91SGregory Neil Shapiro **		none
5415bfb62e91SGregory Neil Shapiro */
5416bfb62e91SGregory Neil Shapiro 
5417bfb62e91SGregory Neil Shapiro void
sm_close_on_exec(lowest,highest)54184313cc83SGregory Neil Shapiro sm_close_on_exec(lowest, highest)
54194313cc83SGregory Neil Shapiro 	int lowest, highest;
5420bfb62e91SGregory Neil Shapiro {
5421bfb62e91SGregory Neil Shapiro #if HASFDWALK
5422bfb62e91SGregory Neil Shapiro 	(void) fdwalk(closefd_walk, &lowest);
5423bfb62e91SGregory Neil Shapiro #else /* HASFDWALK */
5424bfb62e91SGregory Neil Shapiro 	int i, j;
5425bfb62e91SGregory Neil Shapiro 
5426bfb62e91SGregory Neil Shapiro 	for (i = lowest; i < highest; i++)
5427bfb62e91SGregory Neil Shapiro 	{
5428bfb62e91SGregory Neil Shapiro 		if ((j = fcntl(i, F_GETFD, 0)) != -1)
5429bfb62e91SGregory Neil Shapiro 			(void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
5430bfb62e91SGregory Neil Shapiro 	}
5431bfb62e91SGregory Neil Shapiro #endif /* HASFDWALK */
5432bfb62e91SGregory Neil Shapiro }
5433bfb62e91SGregory Neil Shapiro /*
54343299c2f1SGregory Neil Shapiro **  SEED_RANDOM -- seed the random number generator
54353299c2f1SGregory Neil Shapiro **
54363299c2f1SGregory Neil Shapiro **	Parameters:
54373299c2f1SGregory Neil Shapiro **		none
54383299c2f1SGregory Neil Shapiro **
54393299c2f1SGregory Neil Shapiro **	Returns:
54403299c2f1SGregory Neil Shapiro **		none
54413299c2f1SGregory Neil Shapiro */
54423299c2f1SGregory Neil Shapiro 
54433299c2f1SGregory Neil Shapiro void
seed_random()54443299c2f1SGregory Neil Shapiro seed_random()
54453299c2f1SGregory Neil Shapiro {
54463299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
54473299c2f1SGregory Neil Shapiro 	srandomdev();
54483299c2f1SGregory Neil Shapiro #else /* HASSRANDOMDEV */
54493299c2f1SGregory Neil Shapiro 	long seed;
54503299c2f1SGregory Neil Shapiro 	struct timeval t;
54513299c2f1SGregory Neil Shapiro 
545212ed1c7cSGregory Neil Shapiro 	seed = (long) CurrentPid;
54533299c2f1SGregory Neil Shapiro 	if (gettimeofday(&t, NULL) >= 0)
54543299c2f1SGregory Neil Shapiro 		seed += t.tv_sec + t.tv_usec;
54553299c2f1SGregory Neil Shapiro 
54563299c2f1SGregory Neil Shapiro # if HASRANDOM
54573299c2f1SGregory Neil Shapiro 	(void) srandom(seed);
54585b0945b5SGregory Neil Shapiro # else
54593299c2f1SGregory Neil Shapiro 	(void) srand((unsigned int) seed);
54605b0945b5SGregory Neil Shapiro # endif
54613299c2f1SGregory Neil Shapiro #endif /* HASSRANDOMDEV */
54623299c2f1SGregory Neil Shapiro }
546312ed1c7cSGregory Neil Shapiro /*
5464c2aa98e2SPeter Wemm **  SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
5465c2aa98e2SPeter Wemm **
5466c2aa98e2SPeter Wemm **	Parameters:
5467c2aa98e2SPeter Wemm **		level -- syslog level
5468c2aa98e2SPeter Wemm **		id -- envelope ID or NULL (NOQUEUE)
5469c2aa98e2SPeter Wemm **		fmt -- format string
5470c2aa98e2SPeter Wemm **		arg... -- arguments as implied by fmt.
5471c2aa98e2SPeter Wemm **
5472c2aa98e2SPeter Wemm **	Returns:
5473c2aa98e2SPeter Wemm **		none
5474c2aa98e2SPeter Wemm */
5475c2aa98e2SPeter Wemm 
5476c2aa98e2SPeter Wemm /* VARARGS3 */
5477c2aa98e2SPeter Wemm void
5478c2aa98e2SPeter Wemm #ifdef __STDC__
sm_syslog(int level,const char * id,const char * fmt,...)5479c2aa98e2SPeter Wemm sm_syslog(int level, const char *id, const char *fmt, ...)
54803299c2f1SGregory Neil Shapiro #else /* __STDC__ */
5481c2aa98e2SPeter Wemm sm_syslog(level, id, fmt, va_alist)
5482c2aa98e2SPeter Wemm 	int level;
5483c2aa98e2SPeter Wemm 	const char *id;
5484c2aa98e2SPeter Wemm 	const char *fmt;
5485c2aa98e2SPeter Wemm 	va_dcl
54863299c2f1SGregory Neil Shapiro #endif /* __STDC__ */
5487c2aa98e2SPeter Wemm {
5488567a2fc9SGregory Neil Shapiro 	char *buf;
5489567a2fc9SGregory Neil Shapiro 	size_t bufsize;
5490c2aa98e2SPeter Wemm 	char *begin, *end;
54913299c2f1SGregory Neil Shapiro 	int save_errno;
5492c2aa98e2SPeter Wemm 	int seq = 1;
5493c2aa98e2SPeter Wemm 	int idlen;
54943299c2f1SGregory Neil Shapiro 	char buf0[MAXLINE];
549512ed1c7cSGregory Neil Shapiro 	char *newstring;
549612ed1c7cSGregory Neil Shapiro 	extern int SyslogPrefixLen;
549712ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5498c2aa98e2SPeter Wemm 
549912ed1c7cSGregory Neil Shapiro 	save_errno = errno;
5500c2aa98e2SPeter Wemm 	if (id == NULL)
5501c2aa98e2SPeter Wemm 		id = "NOQUEUE";
550212ed1c7cSGregory Neil Shapiro 	idlen = strlen(id) + SyslogPrefixLen;
5503c2aa98e2SPeter Wemm 
55043299c2f1SGregory Neil Shapiro 	buf = buf0;
5505951742c4SGregory Neil Shapiro 	bufsize = sizeof(buf0);
55063299c2f1SGregory Neil Shapiro 
55073299c2f1SGregory Neil Shapiro 	for (;;)
55083299c2f1SGregory Neil Shapiro 	{
550912ed1c7cSGregory Neil Shapiro 		int n;
5510c2aa98e2SPeter Wemm 
551112ed1c7cSGregory Neil Shapiro 		/* print log message into buf */
551212ed1c7cSGregory Neil Shapiro 		SM_VA_START(ap, fmt);
551312ed1c7cSGregory Neil Shapiro 		n = sm_vsnprintf(buf, bufsize, fmt, ap);
551412ed1c7cSGregory Neil Shapiro 		SM_VA_END(ap);
5515da7d7b9cSGregory Neil Shapiro 		SM_ASSERT(n >= 0);
551612ed1c7cSGregory Neil Shapiro 		if (n < bufsize)
55173299c2f1SGregory Neil Shapiro 			break;
55183299c2f1SGregory Neil Shapiro 
5519c2aa98e2SPeter Wemm 		/* String too small, redo with correct size */
552012ed1c7cSGregory Neil Shapiro 		bufsize = n + 1;
55213299c2f1SGregory Neil Shapiro 		if (buf != buf0)
552212ed1c7cSGregory Neil Shapiro 		{
5523c0c4794dSGregory Neil Shapiro 			sm_free(buf);
552412ed1c7cSGregory Neil Shapiro 			buf = NULL;
5525c2aa98e2SPeter Wemm 		}
552612ed1c7cSGregory Neil Shapiro 		buf = sm_malloc_x(bufsize);
552712ed1c7cSGregory Neil Shapiro 	}
552812ed1c7cSGregory Neil Shapiro 
552912ed1c7cSGregory Neil Shapiro 	/* clean up buf after it has been expanded with args */
55302fb4f839SGregory Neil Shapiro #if _FFR_LOGASIS >= 5
5531*d39bd2c1SGregory Neil Shapiro 	/* for testing! maybe make it an -d option (hence runtime)? */
55322fb4f839SGregory Neil Shapiro 	newstring = buf;
55332fb4f839SGregory Neil Shapiro #else
553412ed1c7cSGregory Neil Shapiro 	newstring = str2prt(buf);
55352fb4f839SGregory Neil Shapiro #endif
553612ed1c7cSGregory Neil Shapiro 	if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE)
5537c2aa98e2SPeter Wemm 	{
5538c2aa98e2SPeter Wemm #if LOG
5539c2aa98e2SPeter Wemm 		if (*id == '\0')
5540951742c4SGregory Neil Shapiro 		{
5541ba00ec3dSGregory Neil Shapiro 			if (tTd(89, 10))
5542ba00ec3dSGregory Neil Shapiro 			{
5543ba00ec3dSGregory Neil Shapiro 				struct timeval tv;
5544ba00ec3dSGregory Neil Shapiro 
5545ba00ec3dSGregory Neil Shapiro 				gettimeofday(&tv, NULL);
5546ba00ec3dSGregory Neil Shapiro 				sm_dprintf("%ld.%06ld %s\n", (long) tv.tv_sec,
5547ba00ec3dSGregory Neil Shapiro 					(long) tv.tv_usec, newstring);
5548ba00ec3dSGregory Neil Shapiro 			}
5549ba00ec3dSGregory Neil Shapiro 			else if (tTd(89, 8))
5550951742c4SGregory Neil Shapiro 				sm_dprintf("%s\n", newstring);
5551951742c4SGregory Neil Shapiro 			else
555212ed1c7cSGregory Neil Shapiro 				syslog(level, "%s", newstring);
5553951742c4SGregory Neil Shapiro 		}
5554951742c4SGregory Neil Shapiro 		else
5555951742c4SGregory Neil Shapiro 		{
5556ba00ec3dSGregory Neil Shapiro 			if (tTd(89, 10))
5557ba00ec3dSGregory Neil Shapiro 			{
5558ba00ec3dSGregory Neil Shapiro 				struct timeval tv;
5559ba00ec3dSGregory Neil Shapiro 
5560ba00ec3dSGregory Neil Shapiro 				gettimeofday(&tv, NULL);
5561ba00ec3dSGregory Neil Shapiro 				sm_dprintf("%ld.%06ld %s: %s\n", (long) tv.tv_sec,
5562ba00ec3dSGregory Neil Shapiro 					(long) tv.tv_usec, id, newstring);
5563ba00ec3dSGregory Neil Shapiro 			}
5564ba00ec3dSGregory Neil Shapiro 			else if (tTd(89, 8))
5565951742c4SGregory Neil Shapiro 				sm_dprintf("%s: %s\n", id, newstring);
5566c2aa98e2SPeter Wemm 			else
556712ed1c7cSGregory Neil Shapiro 				syslog(level, "%s: %s", id, newstring);
5568951742c4SGregory Neil Shapiro 		}
55693299c2f1SGregory Neil Shapiro #else /* LOG */
5570c2aa98e2SPeter Wemm 		/*XXX should do something more sensible */
5571c2aa98e2SPeter Wemm 		if (*id == '\0')
557212ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n",
557312ed1c7cSGregory Neil Shapiro 					     newstring);
5574c2aa98e2SPeter Wemm 		else
557512ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
557612ed1c7cSGregory Neil Shapiro 					     "%s: %s\n", id, newstring);
55773299c2f1SGregory Neil Shapiro #endif /* LOG */
5578567a2fc9SGregory Neil Shapiro 		if (buf != buf0)
5579567a2fc9SGregory Neil Shapiro 			sm_free(buf);
55803299c2f1SGregory Neil Shapiro 		errno = save_errno;
5581c2aa98e2SPeter Wemm 		return;
5582c2aa98e2SPeter Wemm 	}
5583c2aa98e2SPeter Wemm 
558412ed1c7cSGregory Neil Shapiro /*
558512ed1c7cSGregory Neil Shapiro **  additional length for splitting: " ..." + 3, where 3 is magic to
558612ed1c7cSGregory Neil Shapiro **  have some data for the next entry.
558712ed1c7cSGregory Neil Shapiro */
558812ed1c7cSGregory Neil Shapiro 
558912ed1c7cSGregory Neil Shapiro #define SL_SPLIT 7
559012ed1c7cSGregory Neil Shapiro 
559112ed1c7cSGregory Neil Shapiro 	begin = newstring;
559212ed1c7cSGregory Neil Shapiro 	idlen += 5;	/* strlen("[999]"), see below */
5593c2aa98e2SPeter Wemm 	while (*begin != '\0' &&
559412ed1c7cSGregory Neil Shapiro 	       (strlen(begin) + idlen) > SYSLOG_BUFSIZE)
5595c2aa98e2SPeter Wemm 	{
5596c2aa98e2SPeter Wemm 		char save;
5597c2aa98e2SPeter Wemm 
559812ed1c7cSGregory Neil Shapiro 		if (seq >= 999)
5599c2aa98e2SPeter Wemm 		{
5600c2aa98e2SPeter Wemm 			/* Too many messages */
5601c2aa98e2SPeter Wemm 			break;
5602c2aa98e2SPeter Wemm 		}
560312ed1c7cSGregory Neil Shapiro 		end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5604c2aa98e2SPeter Wemm 		while (end > begin)
5605c2aa98e2SPeter Wemm 		{
5606c2aa98e2SPeter Wemm 			/* Break on comma or space */
5607c2aa98e2SPeter Wemm 			if (*end == ',' || *end == ' ')
5608c2aa98e2SPeter Wemm 			{
5609c2aa98e2SPeter Wemm 				end++;	  /* Include separator */
5610c2aa98e2SPeter Wemm 				break;
5611c2aa98e2SPeter Wemm 			}
5612c2aa98e2SPeter Wemm 			end--;
5613c2aa98e2SPeter Wemm 		}
5614c2aa98e2SPeter Wemm 		/* No separator, break midstring... */
5615c2aa98e2SPeter Wemm 		if (end == begin)
561612ed1c7cSGregory Neil Shapiro 			end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
5617c2aa98e2SPeter Wemm 		save = *end;
5618c2aa98e2SPeter Wemm 		*end = 0;
5619c2aa98e2SPeter Wemm #if LOG
5620951742c4SGregory Neil Shapiro 		if (tTd(89, 8))
5621951742c4SGregory Neil Shapiro 			sm_dprintf("%s[%d]: %s ...\n", id, seq++, begin);
5622951742c4SGregory Neil Shapiro 		else
5623c2aa98e2SPeter Wemm 			syslog(level, "%s[%d]: %s ...", id, seq++, begin);
56243299c2f1SGregory Neil Shapiro #else /* LOG */
562512ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
562612ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s ...\n", id, seq++, begin);
56273299c2f1SGregory Neil Shapiro #endif /* LOG */
5628c2aa98e2SPeter Wemm 		*end = save;
5629c2aa98e2SPeter Wemm 		begin = end;
5630c2aa98e2SPeter Wemm 	}
563112ed1c7cSGregory Neil Shapiro 	if (seq >= 999)
5632951742c4SGregory Neil Shapiro 	{
5633c2aa98e2SPeter Wemm #if LOG
5634951742c4SGregory Neil Shapiro 		if (tTd(89, 8))
5635951742c4SGregory Neil Shapiro 			sm_dprintf("%s[%d]: log terminated, too many parts\n",
5636951742c4SGregory Neil Shapiro 				id, seq);
5637951742c4SGregory Neil Shapiro 		else
56383299c2f1SGregory Neil Shapiro 			syslog(level, "%s[%d]: log terminated, too many parts",
56393299c2f1SGregory Neil Shapiro 				id, seq);
56403299c2f1SGregory Neil Shapiro #else /* LOG */
564112ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
564212ed1c7cSGregory Neil Shapiro 			      "%s[%d]: log terminated, too many parts\n", id, seq);
56433299c2f1SGregory Neil Shapiro #endif /* LOG */
5644951742c4SGregory Neil Shapiro 	}
5645c2aa98e2SPeter Wemm 	else if (*begin != '\0')
5646951742c4SGregory Neil Shapiro 	{
5647c2aa98e2SPeter Wemm #if LOG
5648951742c4SGregory Neil Shapiro 		if (tTd(89, 8))
5649951742c4SGregory Neil Shapiro 			sm_dprintf("%s[%d]: %s\n", id, seq, begin);
5650951742c4SGregory Neil Shapiro 		else
5651c2aa98e2SPeter Wemm 			syslog(level, "%s[%d]: %s", id, seq, begin);
56523299c2f1SGregory Neil Shapiro #else /* LOG */
565312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
565412ed1c7cSGregory Neil Shapiro 				     "%s[%d]: %s\n", id, seq, begin);
56553299c2f1SGregory Neil Shapiro #endif /* LOG */
5656951742c4SGregory Neil Shapiro 	}
5657567a2fc9SGregory Neil Shapiro 	if (buf != buf0)
5658567a2fc9SGregory Neil Shapiro 		sm_free(buf);
56593299c2f1SGregory Neil Shapiro 	errno = save_errno;
5660c2aa98e2SPeter Wemm }
566112ed1c7cSGregory Neil Shapiro /*
5662c2aa98e2SPeter Wemm **  HARD_SYSLOG -- call syslog repeatedly until it works
5663c2aa98e2SPeter Wemm **
5664c2aa98e2SPeter Wemm **	Needed on HP-UX, which apparently doesn't guarantee that
5665c2aa98e2SPeter Wemm **	syslog succeeds during interrupt handlers.
5666c2aa98e2SPeter Wemm */
5667c2aa98e2SPeter Wemm 
5668c2aa98e2SPeter Wemm #if defined(__hpux) && !defined(HPUX11)
5669c2aa98e2SPeter Wemm 
5670c2aa98e2SPeter Wemm # define MAXSYSLOGTRIES	100
5671c2aa98e2SPeter Wemm # undef syslog
5672c2aa98e2SPeter Wemm # ifdef V4FS
5673c2aa98e2SPeter Wemm #  define XCNST	const
5674c2aa98e2SPeter Wemm #  define CAST	(const char *)
56755b0945b5SGregory Neil Shapiro # else
5676c2aa98e2SPeter Wemm #  define XCNST
5677c2aa98e2SPeter Wemm #  define CAST
56785b0945b5SGregory Neil Shapiro # endif
5679c2aa98e2SPeter Wemm 
5680c2aa98e2SPeter Wemm void
5681c2aa98e2SPeter Wemm # ifdef __STDC__
hard_syslog(int pri,XCNST char * msg,...)5682c2aa98e2SPeter Wemm hard_syslog(int pri, XCNST char *msg, ...)
56833299c2f1SGregory Neil Shapiro # else /* __STDC__ */
5684c2aa98e2SPeter Wemm hard_syslog(pri, msg, va_alist)
5685c2aa98e2SPeter Wemm 	int pri;
5686c2aa98e2SPeter Wemm 	XCNST char *msg;
5687c2aa98e2SPeter Wemm 	va_dcl
56883299c2f1SGregory Neil Shapiro # endif /* __STDC__ */
5689c2aa98e2SPeter Wemm {
5690c2aa98e2SPeter Wemm 	int i;
5691c2aa98e2SPeter Wemm 	char buf[SYSLOG_BUFSIZE];
569212ed1c7cSGregory Neil Shapiro 	SM_VA_LOCAL_DECL
5693c2aa98e2SPeter Wemm 
569412ed1c7cSGregory Neil Shapiro 	SM_VA_START(ap, msg);
5695951742c4SGregory Neil Shapiro 	(void) sm_vsnprintf(buf, sizeof(buf), msg, ap);
569612ed1c7cSGregory Neil Shapiro 	SM_VA_END(ap);
5697c2aa98e2SPeter Wemm 
5698c2aa98e2SPeter Wemm 	for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; )
5699c2aa98e2SPeter Wemm 		continue;
5700c2aa98e2SPeter Wemm }
5701c2aa98e2SPeter Wemm 
5702c2aa98e2SPeter Wemm # undef CAST
57033299c2f1SGregory Neil Shapiro #endif /* defined(__hpux) && !defined(HPUX11) */
57043299c2f1SGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
570512ed1c7cSGregory Neil Shapiro /*
5706c2aa98e2SPeter Wemm **  LOCAL_HOSTNAME_LENGTH
5707c2aa98e2SPeter Wemm **
5708c2aa98e2SPeter Wemm **	This is required to get sendmail to compile against BIND 4.9.x
5709c2aa98e2SPeter Wemm **	on Ultrix.
57103299c2f1SGregory Neil Shapiro **
57113299c2f1SGregory Neil Shapiro **	Unfortunately, a Compaq Y2K patch kit provides it without
57123299c2f1SGregory Neil Shapiro **	bumping __RES in /usr/include/resolv.h so we can't automatically
57133299c2f1SGregory Neil Shapiro **	figure out whether it is needed.
5714c2aa98e2SPeter Wemm */
5715c2aa98e2SPeter Wemm 
5716c2aa98e2SPeter Wemm int
local_hostname_length(hostname)5717c2aa98e2SPeter Wemm local_hostname_length(hostname)
5718c2aa98e2SPeter Wemm 	char *hostname;
5719c2aa98e2SPeter Wemm {
572012ed1c7cSGregory Neil Shapiro 	size_t len_host, len_domain;
5721c2aa98e2SPeter Wemm 
5722c2aa98e2SPeter Wemm 	if (!*_res.defdname)
5723c2aa98e2SPeter Wemm 		res_init();
5724c2aa98e2SPeter Wemm 	len_host = strlen(hostname);
5725c2aa98e2SPeter Wemm 	len_domain = strlen(_res.defdname);
5726c2aa98e2SPeter Wemm 	if (len_host > len_domain &&
57272fb4f839SGregory Neil Shapiro 	    (SM_STRCASEEQ(hostname + len_host - len_domain, _res.defdname)) &&
5728c2aa98e2SPeter Wemm 	    hostname[len_host - len_domain - 1] == '.')
5729c2aa98e2SPeter Wemm 		return len_host - len_domain - 1;
5730c2aa98e2SPeter Wemm 	else
5731c2aa98e2SPeter Wemm 		return 0;
5732c2aa98e2SPeter Wemm }
57333299c2f1SGregory Neil Shapiro #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
5734c2aa98e2SPeter Wemm 
573512ed1c7cSGregory Neil Shapiro #if NEEDLINK
573612ed1c7cSGregory Neil Shapiro /*
573712ed1c7cSGregory Neil Shapiro **  LINK -- clone a file
573812ed1c7cSGregory Neil Shapiro **
573912ed1c7cSGregory Neil Shapiro **	Some OS's lacks link() and hard links.  Since sendmail is using
574012ed1c7cSGregory Neil Shapiro **	link() as an efficient way to clone files, this implementation
574112ed1c7cSGregory Neil Shapiro **	will simply do a file copy.
574212ed1c7cSGregory Neil Shapiro **
574312ed1c7cSGregory Neil Shapiro **	NOTE: This link() replacement is not a generic replacement as it
574412ed1c7cSGregory Neil Shapiro **	does not handle all of the semantics of the real link(2).
574512ed1c7cSGregory Neil Shapiro **
574612ed1c7cSGregory Neil Shapiro **	Parameters:
574712ed1c7cSGregory Neil Shapiro **		source -- pathname of existing file.
574812ed1c7cSGregory Neil Shapiro **		target -- pathname of link (clone) to be created.
574912ed1c7cSGregory Neil Shapiro **
575012ed1c7cSGregory Neil Shapiro **	Returns:
575112ed1c7cSGregory Neil Shapiro **		0 -- success.
575212ed1c7cSGregory Neil Shapiro **		-1 -- failure, see errno for details.
575312ed1c7cSGregory Neil Shapiro */
575412ed1c7cSGregory Neil Shapiro 
575512ed1c7cSGregory Neil Shapiro int
link(source,target)575612ed1c7cSGregory Neil Shapiro link(source, target)
575712ed1c7cSGregory Neil Shapiro 	const char *source;
575812ed1c7cSGregory Neil Shapiro 	const char *target;
575912ed1c7cSGregory Neil Shapiro {
576012ed1c7cSGregory Neil Shapiro 	int save_errno;
576112ed1c7cSGregory Neil Shapiro 	int sff;
576212ed1c7cSGregory Neil Shapiro 	int src = -1, dst = -1;
576312ed1c7cSGregory Neil Shapiro 	ssize_t readlen;
576412ed1c7cSGregory Neil Shapiro 	ssize_t writelen;
576512ed1c7cSGregory Neil Shapiro 	char buf[BUFSIZ];
576612ed1c7cSGregory Neil Shapiro 	struct stat st;
576712ed1c7cSGregory Neil Shapiro 
576812ed1c7cSGregory Neil Shapiro 	sff = SFF_REGONLY|SFF_OPENASROOT;
576912ed1c7cSGregory Neil Shapiro 	if (DontLockReadFiles)
577012ed1c7cSGregory Neil Shapiro 		sff |= SFF_NOLOCK;
577112ed1c7cSGregory Neil Shapiro 
577212ed1c7cSGregory Neil Shapiro 	/* Open the original file */
577312ed1c7cSGregory Neil Shapiro 	src = safeopen((char *)source, O_RDONLY, 0, sff);
577412ed1c7cSGregory Neil Shapiro 	if (src < 0)
577512ed1c7cSGregory Neil Shapiro 		goto fail;
577612ed1c7cSGregory Neil Shapiro 
577712ed1c7cSGregory Neil Shapiro 	/* Obtain the size and the mode */
577812ed1c7cSGregory Neil Shapiro 	if (fstat(src, &st) < 0)
577912ed1c7cSGregory Neil Shapiro 		goto fail;
578012ed1c7cSGregory Neil Shapiro 
578112ed1c7cSGregory Neil Shapiro 	/* Create the duplicate copy */
578212ed1c7cSGregory Neil Shapiro 	sff &= ~SFF_NOLOCK;
578312ed1c7cSGregory Neil Shapiro 	sff |= SFF_CREAT;
578412ed1c7cSGregory Neil Shapiro 	dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY,
578512ed1c7cSGregory Neil Shapiro 		       st.st_mode, sff);
578612ed1c7cSGregory Neil Shapiro 	if (dst < 0)
578712ed1c7cSGregory Neil Shapiro 		goto fail;
578812ed1c7cSGregory Neil Shapiro 
578912ed1c7cSGregory Neil Shapiro 	/* Copy all of the bytes one buffer at a time */
579012ed1c7cSGregory Neil Shapiro 	while ((readlen = read(src, &buf, sizeof(buf))) > 0)
579112ed1c7cSGregory Neil Shapiro 	{
579212ed1c7cSGregory Neil Shapiro 		ssize_t left = readlen;
579312ed1c7cSGregory Neil Shapiro 		char *p = buf;
579412ed1c7cSGregory Neil Shapiro 
579512ed1c7cSGregory Neil Shapiro 		while (left > 0 &&
579612ed1c7cSGregory Neil Shapiro 		       (writelen = write(dst, p, (size_t) left)) >= 0)
579712ed1c7cSGregory Neil Shapiro 		{
579812ed1c7cSGregory Neil Shapiro 			left -= writelen;
579912ed1c7cSGregory Neil Shapiro 			p += writelen;
580012ed1c7cSGregory Neil Shapiro 		}
5801320f00e7SGregory Neil Shapiro 		if (writelen < 0)
580212ed1c7cSGregory Neil Shapiro 			break;
580312ed1c7cSGregory Neil Shapiro 	}
580412ed1c7cSGregory Neil Shapiro 
580512ed1c7cSGregory Neil Shapiro 	/* Any trouble reading? */
580612ed1c7cSGregory Neil Shapiro 	if (readlen < 0 || writelen < 0)
580712ed1c7cSGregory Neil Shapiro 		goto fail;
580812ed1c7cSGregory Neil Shapiro 
580912ed1c7cSGregory Neil Shapiro 	/* Close the input file */
581012ed1c7cSGregory Neil Shapiro 	if (close(src) < 0)
581112ed1c7cSGregory Neil Shapiro 	{
581212ed1c7cSGregory Neil Shapiro 		src = -1;
581312ed1c7cSGregory Neil Shapiro 		goto fail;
581412ed1c7cSGregory Neil Shapiro 	}
581512ed1c7cSGregory Neil Shapiro 	src = -1;
581612ed1c7cSGregory Neil Shapiro 
581712ed1c7cSGregory Neil Shapiro 	/* Close the output file */
581812ed1c7cSGregory Neil Shapiro 	if (close(dst) < 0)
581912ed1c7cSGregory Neil Shapiro 	{
582012ed1c7cSGregory Neil Shapiro 		/* don't set dst = -1 here so we unlink the file */
582112ed1c7cSGregory Neil Shapiro 		goto fail;
582212ed1c7cSGregory Neil Shapiro 	}
582312ed1c7cSGregory Neil Shapiro 
582412ed1c7cSGregory Neil Shapiro 	/* Success */
582512ed1c7cSGregory Neil Shapiro 	return 0;
582612ed1c7cSGregory Neil Shapiro 
582712ed1c7cSGregory Neil Shapiro  fail:
582812ed1c7cSGregory Neil Shapiro 	save_errno = errno;
582912ed1c7cSGregory Neil Shapiro 	if (src >= 0)
583012ed1c7cSGregory Neil Shapiro 		(void) close(src);
583112ed1c7cSGregory Neil Shapiro 	if (dst >= 0)
583212ed1c7cSGregory Neil Shapiro 	{
583312ed1c7cSGregory Neil Shapiro 		(void) unlink(target);
583412ed1c7cSGregory Neil Shapiro 		(void) close(dst);
583512ed1c7cSGregory Neil Shapiro 	}
583612ed1c7cSGregory Neil Shapiro 	errno = save_errno;
583712ed1c7cSGregory Neil Shapiro 	return -1;
583812ed1c7cSGregory Neil Shapiro }
583912ed1c7cSGregory Neil Shapiro #endif /* NEEDLINK */
584012ed1c7cSGregory Neil Shapiro 
584112ed1c7cSGregory Neil Shapiro /*
5842c2aa98e2SPeter Wemm **  Compile-Time options
5843c2aa98e2SPeter Wemm */
5844c2aa98e2SPeter Wemm 
58455b0945b5SGregory Neil Shapiro #define SM_STR(x) #x
58465b0945b5SGregory Neil Shapiro #define SM_XSTR(x) SM_STR(x)
58475b0945b5SGregory Neil Shapiro 
5848c2aa98e2SPeter Wemm char	*CompileOptions[] =
5849c2aa98e2SPeter Wemm {
5850bfb62e91SGregory Neil Shapiro #if ALLOW_255
58512fb4f839SGregory Neil Shapiro 	/* if not enabled (and EightBitAddrOK not set): convert 0xff to 0x7f */
5852bfb62e91SGregory Neil Shapiro 	"ALLOW_255",
5853da7d7b9cSGregory Neil Shapiro #endif
58545b0945b5SGregory Neil Shapiro #if DANE
58555b0945b5SGregory Neil Shapiro 	"DANE",
58565b0945b5SGregory Neil Shapiro #endif
5857*d39bd2c1SGregory Neil Shapiro #if HAVE_SSL_CTX_dane_enable
5858*d39bd2c1SGregory Neil Shapiro 	"HAVE_SSL_CTX_dane_enable",
5859*d39bd2c1SGregory Neil Shapiro #endif
5860*d39bd2c1SGregory Neil Shapiro #if MAX_TLSA_RR
5861*d39bd2c1SGregory Neil Shapiro 	"MAX_TLSA_RR=" SM_XSTR(MAX_TLSA_RR),
5862*d39bd2c1SGregory Neil Shapiro #endif
586312ed1c7cSGregory Neil Shapiro #if NAMED_BIND
586412ed1c7cSGregory Neil Shapiro # if DNSMAP
586512ed1c7cSGregory Neil Shapiro 	"DNSMAP",
5866da7d7b9cSGregory Neil Shapiro # endif
5867da7d7b9cSGregory Neil Shapiro #endif
5868c0c4794dSGregory Neil Shapiro #if EGD
5869c0c4794dSGregory Neil Shapiro 	"EGD",
5870da7d7b9cSGregory Neil Shapiro #endif
587112ed1c7cSGregory Neil Shapiro #if HESIOD
5872c2aa98e2SPeter Wemm 	"HESIOD",
5873da7d7b9cSGregory Neil Shapiro #endif
5874da7d7b9cSGregory Neil Shapiro #if HESIOD_ALLOW_NUMERIC_LOGIN
5875da7d7b9cSGregory Neil Shapiro 	"HESIOD_ALLOW_NUMERIC_LOGIN",
5876da7d7b9cSGregory Neil Shapiro #endif
5877c2aa98e2SPeter Wemm #if HES_GETMAILHOST
5878c2aa98e2SPeter Wemm 	"HES_GETMAILHOST",
5879da7d7b9cSGregory Neil Shapiro #endif
5880da7d7b9cSGregory Neil Shapiro #if IPV6_FULL
5881da7d7b9cSGregory Neil Shapiro 	/* Use uncompressed IPv6 address format (no "::") by default */
5882da7d7b9cSGregory Neil Shapiro 	"IPV6_FULL",
5883da7d7b9cSGregory Neil Shapiro #endif
588412ed1c7cSGregory Neil Shapiro #if LDAPMAP
5885c2aa98e2SPeter Wemm 	"LDAPMAP",
5886da7d7b9cSGregory Neil Shapiro #endif
58875b0945b5SGregory Neil Shapiro #if LDAP_NETWORK_TIMEOUT
58885b0945b5SGregory Neil Shapiro 	/* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */
58895b0945b5SGregory Neil Shapiro 	"LDAP_NETWORK_TIMEOUT",
58905b0945b5SGregory Neil Shapiro #endif
5891567a2fc9SGregory Neil Shapiro #if LDAP_REFERRALS
5892567a2fc9SGregory Neil Shapiro 	"LDAP_REFERRALS",
5893da7d7b9cSGregory Neil Shapiro #endif
5894c2aa98e2SPeter Wemm #if LOG
5895c2aa98e2SPeter Wemm 	"LOG",
5896da7d7b9cSGregory Neil Shapiro #endif
589712ed1c7cSGregory Neil Shapiro #if MAP_NSD
589812ed1c7cSGregory Neil Shapiro 	"MAP_NSD",
5899da7d7b9cSGregory Neil Shapiro #endif
590012ed1c7cSGregory Neil Shapiro #if MAP_REGEX
590112ed1c7cSGregory Neil Shapiro 	"MAP_REGEX",
5902da7d7b9cSGregory Neil Shapiro #endif
5903c2aa98e2SPeter Wemm #if MATCHGECOS
5904c2aa98e2SPeter Wemm 	"MATCHGECOS",
5905da7d7b9cSGregory Neil Shapiro #endif
59065b0945b5SGregory Neil Shapiro #if MAXDAEMONS != 10
59075b0945b5SGregory Neil Shapiro 	"MAXDAEMONS=" SM_XSTR(MAXDAEMONS),
59085b0945b5SGregory Neil Shapiro #endif
59095b0945b5SGregory Neil Shapiro #if defined(MSGIDLOGLEN)
59105b0945b5SGregory Neil Shapiro 	"MSGIDLOGLEN=" SM_XSTR(MSGIDLOGLEN),
59115b0945b5SGregory Neil Shapiro #endif
591212ed1c7cSGregory Neil Shapiro #if MILTER
591312ed1c7cSGregory Neil Shapiro 	"MILTER",
5914da7d7b9cSGregory Neil Shapiro #endif
5915c2aa98e2SPeter Wemm #if MIME7TO8
5916c2aa98e2SPeter Wemm 	"MIME7TO8",
5917da7d7b9cSGregory Neil Shapiro #endif
59181ae5b8d4SGregory Neil Shapiro #if MIME7TO8_OLD
59191ae5b8d4SGregory Neil Shapiro 	"MIME7TO8_OLD",
5920da7d7b9cSGregory Neil Shapiro #endif
5921c2aa98e2SPeter Wemm #if MIME8TO7
5922c2aa98e2SPeter Wemm 	"MIME8TO7",
5923da7d7b9cSGregory Neil Shapiro #endif
5924c2aa98e2SPeter Wemm #if NAMED_BIND
5925c2aa98e2SPeter Wemm 	"NAMED_BIND",
5926*d39bd2c1SGregory Neil Shapiro #else
5927*d39bd2c1SGregory Neil Shapiro # if DANE
5928*d39bd2c1SGregory Neil Shapiro #  error "DANE requires NAMED_BIND"
5929*d39bd2c1SGregory Neil Shapiro # endif
5930da7d7b9cSGregory Neil Shapiro #endif
593112ed1c7cSGregory Neil Shapiro #if NDBM
5932c2aa98e2SPeter Wemm 	"NDBM",
5933da7d7b9cSGregory Neil Shapiro #endif
5934c2aa98e2SPeter Wemm #if NETINET
5935c2aa98e2SPeter Wemm 	"NETINET",
5936da7d7b9cSGregory Neil Shapiro #endif
59373299c2f1SGregory Neil Shapiro #if NETINET6
59383299c2f1SGregory Neil Shapiro 	"NETINET6",
5939da7d7b9cSGregory Neil Shapiro #endif
5940c2aa98e2SPeter Wemm #if NETINFO
5941c2aa98e2SPeter Wemm 	"NETINFO",
5942da7d7b9cSGregory Neil Shapiro #endif
5943c2aa98e2SPeter Wemm #if NETISO
5944c2aa98e2SPeter Wemm 	"NETISO",
5945da7d7b9cSGregory Neil Shapiro #endif
5946c2aa98e2SPeter Wemm #if NETNS
5947c2aa98e2SPeter Wemm 	"NETNS",
5948da7d7b9cSGregory Neil Shapiro #endif
5949c2aa98e2SPeter Wemm #if NETUNIX
5950c2aa98e2SPeter Wemm 	"NETUNIX",
5951da7d7b9cSGregory Neil Shapiro #endif
5952c2aa98e2SPeter Wemm #if NETX25
5953c2aa98e2SPeter Wemm 	"NETX25",
5954da7d7b9cSGregory Neil Shapiro #endif
59555b0945b5SGregory Neil Shapiro #if NO_EOH_FIELDS
59565b0945b5SGregory Neil Shapiro 	"NO_EOH_FIELDS",
59575b0945b5SGregory Neil Shapiro #endif
595812ed1c7cSGregory Neil Shapiro #if NEWDB
59595b0945b5SGregory Neil Shapiro # if defined(DB_VERSION_MAJOR) && defined(DB_VERSION_MINOR)
5960*d39bd2c1SGregory Neil Shapiro #  if DB_VERSION_MAJOR >= 5 && !defined(SOLARIS) && !HASFLOCK && !ACCEPT_BROKEN_BDB_LOCKING
5961*d39bd2c1SGregory Neil Shapiro 
5962*d39bd2c1SGregory Neil Shapiro /*
5963*d39bd2c1SGregory Neil Shapiro **  NOTE: disabling this check by setting ACCEPT_BROKEN_BDB_LOCKING
5964*d39bd2c1SGregory Neil Shapiro **	means you are taking full responsibility for any problems
5965*d39bd2c1SGregory Neil Shapiro **	which may arise!
5966*d39bd2c1SGregory Neil Shapiro **
5967*d39bd2c1SGregory Neil Shapiro **	Map locking will not work, and making a change to a map
5968*d39bd2c1SGregory Neil Shapiro **	while sendmail is using it can break mail handling.
5969*d39bd2c1SGregory Neil Shapiro **	At least you must stop all sendmail processes when using
5970*d39bd2c1SGregory Neil Shapiro **	makemap or newaliases - but there might be other things
5971*d39bd2c1SGregory Neil Shapiro **	which could break.
5972*d39bd2c1SGregory Neil Shapiro **
5973*d39bd2c1SGregory Neil Shapiro **	You have been warned - use at your own risk!
5974*d39bd2c1SGregory Neil Shapiro */
5975*d39bd2c1SGregory Neil Shapiro 
5976*d39bd2c1SGregory Neil Shapiro #    error "Berkeley DB file locking needs flock() for version 5.x (and greater?)"
59772fb4f839SGregory Neil Shapiro #  endif
59785b0945b5SGregory Neil Shapiro 	"NEWDB=" SM_XSTR(DB_VERSION_MAJOR) "." SM_XSTR(DB_VERSION_MINOR),
59795b0945b5SGregory Neil Shapiro # else
5980c2aa98e2SPeter Wemm 	"NEWDB",
5981da7d7b9cSGregory Neil Shapiro # endif
59825b0945b5SGregory Neil Shapiro #endif
59835b0945b5SGregory Neil Shapiro #if CDB
59845b0945b5SGregory Neil Shapiro 	"CDB=" SM_XSTR(CDB),
59855b0945b5SGregory Neil Shapiro #endif
598612ed1c7cSGregory Neil Shapiro #if NIS
5987c2aa98e2SPeter Wemm 	"NIS",
5988da7d7b9cSGregory Neil Shapiro #endif
598912ed1c7cSGregory Neil Shapiro #if NISPLUS
5990c2aa98e2SPeter Wemm 	"NISPLUS",
5991da7d7b9cSGregory Neil Shapiro #endif
599212ed1c7cSGregory Neil Shapiro #if NO_DH
599312ed1c7cSGregory Neil Shapiro 	"NO_DH",
5994da7d7b9cSGregory Neil Shapiro #endif
599512ed1c7cSGregory Neil Shapiro #if PH_MAP
59963299c2f1SGregory Neil Shapiro 	"PH_MAP",
5997da7d7b9cSGregory Neil Shapiro #endif
599812ed1c7cSGregory Neil Shapiro #ifdef PICKY_HELO_CHECK
599912ed1c7cSGregory Neil Shapiro 	"PICKY_HELO_CHECK",
6000da7d7b9cSGregory Neil Shapiro #endif
600112ed1c7cSGregory Neil Shapiro #if PIPELINING
600212ed1c7cSGregory Neil Shapiro 	"PIPELINING",
6003da7d7b9cSGregory Neil Shapiro #endif
60043299c2f1SGregory Neil Shapiro #if SASL
600588ad41d4SGregory Neil Shapiro # if SASL >= 20000
600688ad41d4SGregory Neil Shapiro 	"SASLv2",
60075b0945b5SGregory Neil Shapiro # else
60083299c2f1SGregory Neil Shapiro 	"SASL",
6009da7d7b9cSGregory Neil Shapiro # endif
6010da7d7b9cSGregory Neil Shapiro #endif
6011c2aa98e2SPeter Wemm #if SCANF
6012c2aa98e2SPeter Wemm 	"SCANF",
6013da7d7b9cSGregory Neil Shapiro #endif
6014951742c4SGregory Neil Shapiro #if SM_LDAP_ERROR_ON_MISSING_ARGS
6015951742c4SGregory Neil Shapiro 	"SM_LDAP_ERROR_ON_MISSING_ARGS",
6016da7d7b9cSGregory Neil Shapiro #endif
6017c2aa98e2SPeter Wemm #if SMTPDEBUG
6018c2aa98e2SPeter Wemm 	"SMTPDEBUG",
6019da7d7b9cSGregory Neil Shapiro #endif
6020bfb62e91SGregory Neil Shapiro #if SOCKETMAP
6021bfb62e91SGregory Neil Shapiro 	"SOCKETMAP",
6022da7d7b9cSGregory Neil Shapiro #endif
60233299c2f1SGregory Neil Shapiro #if STARTTLS
60243299c2f1SGregory Neil Shapiro 	"STARTTLS",
6025da7d7b9cSGregory Neil Shapiro #endif
602612ed1c7cSGregory Neil Shapiro #if SUID_ROOT_FILES_OK
6027c2aa98e2SPeter Wemm 	"SUID_ROOT_FILES_OK",
6028da7d7b9cSGregory Neil Shapiro #endif
60295b0945b5SGregory Neil Shapiro #if SYSLOG_BUFSIZE > 1024
60305b0945b5SGregory Neil Shapiro 	"SYSLOG_BUFSIZE=" SM_XSTR(SYSLOG_BUFSIZE),
60315b0945b5SGregory Neil Shapiro #endif
6032c2aa98e2SPeter Wemm #if TCPWRAPPERS
6033c2aa98e2SPeter Wemm 	"TCPWRAPPERS",
6034da7d7b9cSGregory Neil Shapiro #endif
603512ed1c7cSGregory Neil Shapiro #if TLS_NO_RSA
603612ed1c7cSGregory Neil Shapiro 	"TLS_NO_RSA",
6037da7d7b9cSGregory Neil Shapiro #endif
60385b0945b5SGregory Neil Shapiro #if TLS_EC
6039*d39bd2c1SGregory Neil Shapiro # if NO_DH
6040*d39bd2c1SGregory Neil Shapiro #  error "NO_DH disables TLS_EC"
6041*d39bd2c1SGregory Neil Shapiro # else
60425b0945b5SGregory Neil Shapiro 	/* elliptic curves */
60435b0945b5SGregory Neil Shapiro 	"TLS_EC",
60445b0945b5SGregory Neil Shapiro # endif
6045*d39bd2c1SGregory Neil Shapiro #endif
604612ed1c7cSGregory Neil Shapiro #if TLS_VRFY_PER_CTX
604712ed1c7cSGregory Neil Shapiro 	"TLS_VRFY_PER_CTX",
6048da7d7b9cSGregory Neil Shapiro #endif
6049c2aa98e2SPeter Wemm #if USERDB
6050c2aa98e2SPeter Wemm 	"USERDB",
6051da7d7b9cSGregory Neil Shapiro #endif
60522fb4f839SGregory Neil Shapiro #if USE_EAI
60532fb4f839SGregory Neil Shapiro 
60542fb4f839SGregory Neil Shapiro 	/*
60552fb4f839SGregory Neil Shapiro 	**  Initial/Partial/Experimental EAI (SMTPUTF8) support.
60562fb4f839SGregory Neil Shapiro 	**  Requires ICU include files and library depending on the OS.
60572fb4f839SGregory Neil Shapiro 	**  Initial patch from Arnt Gulbrandsen.
60582fb4f839SGregory Neil Shapiro 	*/
60592fb4f839SGregory Neil Shapiro 
60602fb4f839SGregory Neil Shapiro # if !ALLOW_255
6061*d39bd2c1SGregory Neil Shapiro #  error "USE_EAI requires ALLOW_255"
60622fb4f839SGregory Neil Shapiro # endif
60632fb4f839SGregory Neil Shapiro # if _FFR_EIGHT_BIT_ADDR_OK
6064*d39bd2c1SGregory Neil Shapiro #  error "Cannot enable both USE_EAI and _FFR_EIGHT_BIT_ADDR_OK"
60652fb4f839SGregory Neil Shapiro # endif
60662fb4f839SGregory Neil Shapiro 	"USE_EAI",
60672fb4f839SGregory Neil Shapiro #endif
6068320f00e7SGregory Neil Shapiro #if USE_LDAP_INIT
6069320f00e7SGregory Neil Shapiro 	"USE_LDAP_INIT",
6070da7d7b9cSGregory Neil Shapiro #endif
6071bfb62e91SGregory Neil Shapiro #if USE_TTYPATH
6072bfb62e91SGregory Neil Shapiro 	"USE_TTYPATH",
6073da7d7b9cSGregory Neil Shapiro #endif
6074c2aa98e2SPeter Wemm #if XDEBUG
6075c2aa98e2SPeter Wemm 	"XDEBUG",
6076da7d7b9cSGregory Neil Shapiro #endif
607712ed1c7cSGregory Neil Shapiro #if XLA
6078c2aa98e2SPeter Wemm 	"XLA",
6079da7d7b9cSGregory Neil Shapiro #endif
6080c2aa98e2SPeter Wemm 	NULL
6081c2aa98e2SPeter Wemm };
6082c2aa98e2SPeter Wemm 
6083c2aa98e2SPeter Wemm /*
6084c2aa98e2SPeter Wemm **  OS compile options.
6085c2aa98e2SPeter Wemm */
6086c2aa98e2SPeter Wemm 
6087c2aa98e2SPeter Wemm char	*OsCompileOptions[] =
6088c2aa98e2SPeter Wemm {
608912ed1c7cSGregory Neil Shapiro #if ADDRCONFIG_IS_BROKEN
609012ed1c7cSGregory Neil Shapiro 	"ADDRCONFIG_IS_BROKEN",
6091da7d7b9cSGregory Neil Shapiro #endif
609212ed1c7cSGregory Neil Shapiro #ifdef AUTO_NETINFO_HOSTS
609312ed1c7cSGregory Neil Shapiro 	"AUTO_NETINFO_HOSTS",
6094da7d7b9cSGregory Neil Shapiro #endif
609512ed1c7cSGregory Neil Shapiro #ifdef AUTO_NIS_ALIASES
609612ed1c7cSGregory Neil Shapiro 	"AUTO_NIS_ALIASES",
6097da7d7b9cSGregory Neil Shapiro #endif
609812ed1c7cSGregory Neil Shapiro #if BROKEN_RES_SEARCH
609912ed1c7cSGregory Neil Shapiro 	"BROKEN_RES_SEARCH",
6100da7d7b9cSGregory Neil Shapiro #endif
610112ed1c7cSGregory Neil Shapiro #ifdef BSD4_4_SOCKADDR
610212ed1c7cSGregory Neil Shapiro 	"BSD4_4_SOCKADDR",
6103da7d7b9cSGregory Neil Shapiro #endif
6104c2aa98e2SPeter Wemm #if BOGUS_O_EXCL
6105c2aa98e2SPeter Wemm 	"BOGUS_O_EXCL",
6106da7d7b9cSGregory Neil Shapiro #endif
610712ed1c7cSGregory Neil Shapiro #if DEC_OSF_BROKEN_GETPWENT
610812ed1c7cSGregory Neil Shapiro 	"DEC_OSF_BROKEN_GETPWENT",
6109da7d7b9cSGregory Neil Shapiro #endif
61105b0945b5SGregory Neil Shapiro #if DNSSEC_TEST
61115b0945b5SGregory Neil Shapiro 	"DNSSEC_TEST",
61125b0945b5SGregory Neil Shapiro #endif
61133299c2f1SGregory Neil Shapiro #if FAST_PID_RECYCLE
61143299c2f1SGregory Neil Shapiro 	"FAST_PID_RECYCLE",
6115da7d7b9cSGregory Neil Shapiro #endif
6116bfb62e91SGregory Neil Shapiro #if HASCLOSEFROM
6117bfb62e91SGregory Neil Shapiro 	"HASCLOSEFROM",
6118da7d7b9cSGregory Neil Shapiro #endif
61193299c2f1SGregory Neil Shapiro #if HASFCHOWN
61203299c2f1SGregory Neil Shapiro 	"HASFCHOWN",
6121da7d7b9cSGregory Neil Shapiro #endif
6122c2aa98e2SPeter Wemm #if HASFCHMOD
6123c2aa98e2SPeter Wemm 	"HASFCHMOD",
6124da7d7b9cSGregory Neil Shapiro #endif
6125bfb62e91SGregory Neil Shapiro #if HASFDWALK
6126bfb62e91SGregory Neil Shapiro 	"HASFDWALK",
6127da7d7b9cSGregory Neil Shapiro #endif
6128c2aa98e2SPeter Wemm #if HASFLOCK
6129c2aa98e2SPeter Wemm 	"HASFLOCK",
6130da7d7b9cSGregory Neil Shapiro #endif
6131c2aa98e2SPeter Wemm #if HASGETDTABLESIZE
6132c2aa98e2SPeter Wemm 	"HASGETDTABLESIZE",
6133da7d7b9cSGregory Neil Shapiro #endif
61345b0945b5SGregory Neil Shapiro #if HAS_GETHOSTBYNAME2
61355b0945b5SGregory Neil Shapiro 	"HAS_GETHOSTBYNAME2",
61365b0945b5SGregory Neil Shapiro #endif
6137c2aa98e2SPeter Wemm #if HASGETUSERSHELL
6138c2aa98e2SPeter Wemm 	"HASGETUSERSHELL",
6139da7d7b9cSGregory Neil Shapiro #endif
6140c2aa98e2SPeter Wemm #if HASINITGROUPS
6141c2aa98e2SPeter Wemm 	"HASINITGROUPS",
6142da7d7b9cSGregory Neil Shapiro #endif
6143951742c4SGregory Neil Shapiro #if HASLDAPGETALIASBYNAME
6144951742c4SGregory Neil Shapiro 	"HASLDAPGETALIASBYNAME",
6145da7d7b9cSGregory Neil Shapiro #endif
6146c2aa98e2SPeter Wemm #if HASLSTAT
6147c2aa98e2SPeter Wemm 	"HASLSTAT",
6148da7d7b9cSGregory Neil Shapiro #endif
614912ed1c7cSGregory Neil Shapiro #if HASNICE
615012ed1c7cSGregory Neil Shapiro 	"HASNICE",
6151da7d7b9cSGregory Neil Shapiro #endif
61523299c2f1SGregory Neil Shapiro #if HASRANDOM
61533299c2f1SGregory Neil Shapiro 	"HASRANDOM",
6154da7d7b9cSGregory Neil Shapiro #endif
615512ed1c7cSGregory Neil Shapiro #if HASRRESVPORT
615612ed1c7cSGregory Neil Shapiro 	"HASRRESVPORT",
6157da7d7b9cSGregory Neil Shapiro #endif
615812ed1c7cSGregory Neil Shapiro #if HASSETEGID
615912ed1c7cSGregory Neil Shapiro 	"HASSETEGID",
6160da7d7b9cSGregory Neil Shapiro #endif
61613299c2f1SGregory Neil Shapiro #if HASSETLOGIN
61623299c2f1SGregory Neil Shapiro 	"HASSETLOGIN",
6163da7d7b9cSGregory Neil Shapiro #endif
616412ed1c7cSGregory Neil Shapiro #if HASSETREGID
616512ed1c7cSGregory Neil Shapiro 	"HASSETREGID",
6166da7d7b9cSGregory Neil Shapiro #endif
616712ed1c7cSGregory Neil Shapiro #if HASSETRESGID
616812ed1c7cSGregory Neil Shapiro 	"HASSETRESGID",
6169da7d7b9cSGregory Neil Shapiro #endif
6170c2aa98e2SPeter Wemm #if HASSETREUID
6171c2aa98e2SPeter Wemm 	"HASSETREUID",
6172da7d7b9cSGregory Neil Shapiro #endif
6173c2aa98e2SPeter Wemm #if HASSETRLIMIT
6174c2aa98e2SPeter Wemm 	"HASSETRLIMIT",
6175da7d7b9cSGregory Neil Shapiro #endif
6176c2aa98e2SPeter Wemm #if HASSETSID
6177c2aa98e2SPeter Wemm 	"HASSETSID",
6178da7d7b9cSGregory Neil Shapiro #endif
6179c2aa98e2SPeter Wemm #if HASSETUSERCONTEXT
6180c2aa98e2SPeter Wemm 	"HASSETUSERCONTEXT",
6181da7d7b9cSGregory Neil Shapiro #endif
6182c2aa98e2SPeter Wemm #if HASSETVBUF
6183c2aa98e2SPeter Wemm 	"HASSETVBUF",
6184da7d7b9cSGregory Neil Shapiro #endif
6185c2aa98e2SPeter Wemm #if HAS_ST_GEN
6186c2aa98e2SPeter Wemm 	"HAS_ST_GEN",
6187da7d7b9cSGregory Neil Shapiro #endif
61883299c2f1SGregory Neil Shapiro #if HASSRANDOMDEV
61893299c2f1SGregory Neil Shapiro 	"HASSRANDOMDEV",
6190da7d7b9cSGregory Neil Shapiro #endif
61913299c2f1SGregory Neil Shapiro #if HASURANDOMDEV
61923299c2f1SGregory Neil Shapiro 	"HASURANDOMDEV",
6193da7d7b9cSGregory Neil Shapiro #endif
6194c2aa98e2SPeter Wemm #if HASSTRERROR
6195c2aa98e2SPeter Wemm 	"HASSTRERROR",
6196da7d7b9cSGregory Neil Shapiro #endif
6197c2aa98e2SPeter Wemm #if HASULIMIT
6198c2aa98e2SPeter Wemm 	"HASULIMIT",
6199da7d7b9cSGregory Neil Shapiro #endif
6200c2aa98e2SPeter Wemm #if HASUNAME
6201c2aa98e2SPeter Wemm 	"HASUNAME",
6202da7d7b9cSGregory Neil Shapiro #endif
6203c2aa98e2SPeter Wemm #if HASUNSETENV
6204c2aa98e2SPeter Wemm 	"HASUNSETENV",
6205da7d7b9cSGregory Neil Shapiro #endif
6206c2aa98e2SPeter Wemm #if HASWAITPID
6207c2aa98e2SPeter Wemm 	"HASWAITPID",
6208da7d7b9cSGregory Neil Shapiro #endif
62096f9c8e5bSGregory Neil Shapiro #if HAVE_NANOSLEEP
62106f9c8e5bSGregory Neil Shapiro 	"HAVE_NANOSLEEP",
6211da7d7b9cSGregory Neil Shapiro #endif
6212c2aa98e2SPeter Wemm #if IDENTPROTO
6213c2aa98e2SPeter Wemm 	"IDENTPROTO",
6214da7d7b9cSGregory Neil Shapiro #endif
6215c2aa98e2SPeter Wemm #if IP_SRCROUTE
6216c2aa98e2SPeter Wemm 	"IP_SRCROUTE",
6217da7d7b9cSGregory Neil Shapiro #endif
6218c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
6219c2aa98e2SPeter Wemm 	"LOCK_ON_OPEN",
6220da7d7b9cSGregory Neil Shapiro #endif
6221951742c4SGregory Neil Shapiro #if MILTER_NO_NAGLE
6222951742c4SGregory Neil Shapiro 	"MILTER_NO_NAGLE ",
6223da7d7b9cSGregory Neil Shapiro #endif
6224c2aa98e2SPeter Wemm #if NEEDFSYNC
6225c2aa98e2SPeter Wemm 	"NEEDFSYNC",
6226da7d7b9cSGregory Neil Shapiro #endif
622712ed1c7cSGregory Neil Shapiro #if NEEDLINK
622812ed1c7cSGregory Neil Shapiro 	"NEEDLINK",
6229da7d7b9cSGregory Neil Shapiro #endif
623012ed1c7cSGregory Neil Shapiro #if NEEDLOCAL_HOSTNAME_LENGTH
623112ed1c7cSGregory Neil Shapiro 	"NEEDLOCAL_HOSTNAME_LENGTH",
6232da7d7b9cSGregory Neil Shapiro #endif
623312ed1c7cSGregory Neil Shapiro #if NEEDSGETIPNODE
623412ed1c7cSGregory Neil Shapiro 	"NEEDSGETIPNODE",
6235da7d7b9cSGregory Neil Shapiro #endif
623612ed1c7cSGregory Neil Shapiro #if NEEDSTRSTR
623712ed1c7cSGregory Neil Shapiro 	"NEEDSTRSTR",
6238da7d7b9cSGregory Neil Shapiro #endif
623912ed1c7cSGregory Neil Shapiro #if NEEDSTRTOL
624012ed1c7cSGregory Neil Shapiro 	"NEEDSTRTOL",
6241da7d7b9cSGregory Neil Shapiro #endif
624212ed1c7cSGregory Neil Shapiro #ifdef NO_GETSERVBYNAME
624312ed1c7cSGregory Neil Shapiro 	"NO_GETSERVBYNAME",
6244da7d7b9cSGregory Neil Shapiro #endif
6245c2aa98e2SPeter Wemm #if NOFTRUNCATE
6246c2aa98e2SPeter Wemm 	"NOFTRUNCATE",
6247da7d7b9cSGregory Neil Shapiro #endif
624812ed1c7cSGregory Neil Shapiro #if REQUIRES_DIR_FSYNC
624912ed1c7cSGregory Neil Shapiro 	"REQUIRES_DIR_FSYNC",
6250da7d7b9cSGregory Neil Shapiro #endif
6251c2aa98e2SPeter Wemm #if RLIMIT_NEEDS_SYS_TIME_H
6252c2aa98e2SPeter Wemm 	"RLIMIT_NEEDS_SYS_TIME_H",
6253da7d7b9cSGregory Neil Shapiro #endif
6254c2aa98e2SPeter Wemm #if SAFENFSPATHCONF
6255c2aa98e2SPeter Wemm 	"SAFENFSPATHCONF",
6256da7d7b9cSGregory Neil Shapiro #endif
6257c2aa98e2SPeter Wemm #if SECUREWARE
6258c2aa98e2SPeter Wemm 	"SECUREWARE",
6259da7d7b9cSGregory Neil Shapiro #endif
6260552d4955SGregory Neil Shapiro #if SFS_TYPE == SFS_4ARGS
6261552d4955SGregory Neil Shapiro 	"SFS_4ARGS",
6262552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_MOUNT
6263552d4955SGregory Neil Shapiro 	"SFS_MOUNT",
6264552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_NONE
6265552d4955SGregory Neil Shapiro 	"SFS_NONE",
6266552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_NT
6267552d4955SGregory Neil Shapiro 	"SFS_NT",
6268552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_STATFS
6269552d4955SGregory Neil Shapiro 	"SFS_STATFS",
6270552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_STATVFS
6271552d4955SGregory Neil Shapiro 	"SFS_STATVFS",
6272552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_USTAT
6273552d4955SGregory Neil Shapiro 	"SFS_USTAT",
6274552d4955SGregory Neil Shapiro #elif SFS_TYPE == SFS_VFS
6275552d4955SGregory Neil Shapiro 	"SFS_VFS",
6276552d4955SGregory Neil Shapiro #endif
6277c2aa98e2SPeter Wemm #if SHARE_V1
6278c2aa98e2SPeter Wemm 	"SHARE_V1",
6279da7d7b9cSGregory Neil Shapiro #endif
6280c2aa98e2SPeter Wemm #if SIOCGIFCONF_IS_BROKEN
6281c2aa98e2SPeter Wemm 	"SIOCGIFCONF_IS_BROKEN",
6282da7d7b9cSGregory Neil Shapiro #endif
6283c2aa98e2SPeter Wemm #if SIOCGIFNUM_IS_BROKEN
6284c2aa98e2SPeter Wemm 	"SIOCGIFNUM_IS_BROKEN",
6285da7d7b9cSGregory Neil Shapiro #endif
62863299c2f1SGregory Neil Shapiro #if SNPRINTF_IS_BROKEN
62873299c2f1SGregory Neil Shapiro 	"SNPRINTF_IS_BROKEN",
6288da7d7b9cSGregory Neil Shapiro #endif
62893299c2f1SGregory Neil Shapiro #if SO_REUSEADDR_IS_BROKEN
62903299c2f1SGregory Neil Shapiro 	"SO_REUSEADDR_IS_BROKEN",
6291da7d7b9cSGregory Neil Shapiro #endif
6292c2aa98e2SPeter Wemm #if SYS5SETPGRP
6293c2aa98e2SPeter Wemm 	"SYS5SETPGRP",
6294da7d7b9cSGregory Neil Shapiro #endif
6295c2aa98e2SPeter Wemm #if SYSTEM5
6296c2aa98e2SPeter Wemm 	"SYSTEM5",
6297da7d7b9cSGregory Neil Shapiro #endif
629812ed1c7cSGregory Neil Shapiro #if USE_DOUBLE_FORK
629912ed1c7cSGregory Neil Shapiro 	"USE_DOUBLE_FORK",
6300da7d7b9cSGregory Neil Shapiro #endif
630112ed1c7cSGregory Neil Shapiro #if USE_ENVIRON
630212ed1c7cSGregory Neil Shapiro 	"USE_ENVIRON",
6303da7d7b9cSGregory Neil Shapiro #endif
6304c2aa98e2SPeter Wemm #if USE_SA_SIGACTION
6305c2aa98e2SPeter Wemm 	"USE_SA_SIGACTION",
6306da7d7b9cSGregory Neil Shapiro #endif
6307c2aa98e2SPeter Wemm #if USE_SIGLONGJMP
6308c2aa98e2SPeter Wemm 	"USE_SIGLONGJMP",
6309da7d7b9cSGregory Neil Shapiro #endif
631012ed1c7cSGregory Neil Shapiro #if USEGETCONFATTR
631112ed1c7cSGregory Neil Shapiro 	"USEGETCONFATTR",
6312da7d7b9cSGregory Neil Shapiro #endif
6313c2aa98e2SPeter Wemm #if USESETEUID
6314c2aa98e2SPeter Wemm 	"USESETEUID",
6315da7d7b9cSGregory Neil Shapiro #endif
631612ed1c7cSGregory Neil Shapiro #ifdef USESYSCTL
631712ed1c7cSGregory Neil Shapiro 	"USESYSCTL",
6318da7d7b9cSGregory Neil Shapiro #endif
63196f9c8e5bSGregory Neil Shapiro #if USE_OPENSSL_ENGINE
63205b0945b5SGregory Neil Shapiro 	/*
63215b0945b5SGregory Neil Shapiro 	**  0: OpenSSL ENGINE?
63225b0945b5SGregory Neil Shapiro 	**  1: Support Sun OpenSSL patch for SPARC T4 pkcs11
63235b0945b5SGregory Neil Shapiro 	**  2: none
63245b0945b5SGregory Neil Shapiro 	*/
63255b0945b5SGregory Neil Shapiro # if USE_OPENSSL_ENGINE != 1
63265b0945b5SGregory Neil Shapiro 	"USE_OPENSSL_ENGINE=" SM_XSTR(USE_OPENSSL_ENGINE),
63275b0945b5SGregory Neil Shapiro # else
63286f9c8e5bSGregory Neil Shapiro 	"USE_OPENSSL_ENGINE",
6329da7d7b9cSGregory Neil Shapiro # endif
63305b0945b5SGregory Neil Shapiro #endif
633112ed1c7cSGregory Neil Shapiro #if USING_NETSCAPE_LDAP
633212ed1c7cSGregory Neil Shapiro 	"USING_NETSCAPE_LDAP",
6333da7d7b9cSGregory Neil Shapiro #endif
633412ed1c7cSGregory Neil Shapiro #ifdef WAITUNION
633512ed1c7cSGregory Neil Shapiro 	"WAITUNION",
6336da7d7b9cSGregory Neil Shapiro #endif
633712ed1c7cSGregory Neil Shapiro 	NULL
633812ed1c7cSGregory Neil Shapiro };
633912ed1c7cSGregory Neil Shapiro 
634012ed1c7cSGregory Neil Shapiro /*
634112ed1c7cSGregory Neil Shapiro **  FFR compile options.
634212ed1c7cSGregory Neil Shapiro */
634312ed1c7cSGregory Neil Shapiro 
634412ed1c7cSGregory Neil Shapiro char	*FFRCompileOptions[] =
634512ed1c7cSGregory Neil Shapiro {
6346da7d7b9cSGregory Neil Shapiro #if _FFR_ADD_BCC
63475b0945b5SGregory Neil Shapiro 	/* see cf/feature/bcc.m4 */
6348da7d7b9cSGregory Neil Shapiro 	"_FFR_ADD_BCC",
6349da7d7b9cSGregory Neil Shapiro #endif
635041f3d2ceSGregory Neil Shapiro #if _FFR_ADDR_TYPE_MODES
635141f3d2ceSGregory Neil Shapiro 	/* more info in {addr_type}, requires m4 changes! */
635241f3d2ceSGregory Neil Shapiro 	"_FFR_ADDR_TYPE_MODES",
6353da7d7b9cSGregory Neil Shapiro #endif
6354da7d7b9cSGregory Neil Shapiro #if _FFR_ALIAS_DETAIL
6355da7d7b9cSGregory Neil Shapiro 	/* try to handle +detail for aliases */
6356da7d7b9cSGregory Neil Shapiro 	"_FFR_ALIAS_DETAIL",
6357da7d7b9cSGregory Neil Shapiro #endif
635812ed1c7cSGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO
635972936242SGregory Neil Shapiro 	/* DefaultAuthInfo can be specified by user. */
6360*d39bd2c1SGregory Neil Shapiro 	/* DefaultAuthInfo doesn't really work in 8.13ff anymore. */
636112ed1c7cSGregory Neil Shapiro 	"_FFR_ALLOW_SASLINFO",
6362da7d7b9cSGregory Neil Shapiro #endif
6363e3793f76SGregory Neil Shapiro #if _FFR_BADRCPT_SHUTDOWN
6364e3793f76SGregory Neil Shapiro 	/* shut down connection (421) if there are too many bad RCPTs */
6365e3793f76SGregory Neil Shapiro 	"_FFR_BADRCPT_SHUTDOWN",
6366da7d7b9cSGregory Neil Shapiro #endif
636712ed1c7cSGregory Neil Shapiro #if _FFR_BESTMX_BETTER_TRUNCATION
636872936242SGregory Neil Shapiro 	/* Better truncation of list of MX records for dns map. */
636912ed1c7cSGregory Neil Shapiro 	"_FFR_BESTMX_BETTER_TRUNCATION",
6370da7d7b9cSGregory Neil Shapiro #endif
63715b0945b5SGregory Neil Shapiro #if _FFR_BLANKENV_MACV
63725b0945b5SGregory Neil Shapiro 	/* also look up macros in BlankEnvelope */
63735b0945b5SGregory Neil Shapiro 	"_FFR_BLANKENV_MACV",
63745b0945b5SGregory Neil Shapiro #endif
6375da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE
6376da7d7b9cSGregory Neil Shapiro 	/* Separate, unprocessed queue for DSNs */
6377da7d7b9cSGregory Neil Shapiro 	/* John Gardiner Myers of Proofpoint */
6378da7d7b9cSGregory Neil Shapiro 	"_FFR_BOUNCE_QUEUE",
6379da7d7b9cSGregory Neil Shapiro #endif
638012ed1c7cSGregory Neil Shapiro #if _FFR_CATCH_BROKEN_MTAS
638172936242SGregory Neil Shapiro 	/* Deal with MTAs that send a reply during the DATA phase. */
638212ed1c7cSGregory Neil Shapiro 	"_FFR_CATCH_BROKEN_MTAS",
6383da7d7b9cSGregory Neil Shapiro #endif
638488ad41d4SGregory Neil Shapiro #if _FFR_CHK_QUEUE
638572936242SGregory Neil Shapiro 	/* Stricter checks about queue directory permissions. */
638688ad41d4SGregory Neil Shapiro 	"_FFR_CHK_QUEUE",
6387da7d7b9cSGregory Neil Shapiro #endif
6388*d39bd2c1SGregory Neil Shapiro #if _FFR_CLASS_RM_ENTRY
6389*d39bd2c1SGregory Neil Shapiro 	/* WIP: remove entries from a class: C-{name}entry */
6390*d39bd2c1SGregory Neil Shapiro 	"_FFR_CLASS_RM_ENTRY",
6391*d39bd2c1SGregory Neil Shapiro #endif
63925b0945b5SGregory Neil Shapiro #if _FFR_CLIENTCA
63935b0945b5SGregory Neil Shapiro 	/*
63945b0945b5SGregory Neil Shapiro 	**  Allow to set client specific CA values.
63955b0945b5SGregory Neil Shapiro 	**  CACertFile: see doc/op.*:
63965b0945b5SGregory Neil Shapiro 	**  "The DNs of these certificates are sent to the client
63975b0945b5SGregory Neil Shapiro 	**  during the TLS handshake (as part of the CertificateRequest)
63985b0945b5SGregory Neil Shapiro 	**  as the list of acceptable CAs.
63995b0945b5SGregory Neil Shapiro 	**  However, do not list too many root CAs in that file,
64005b0945b5SGregory Neil Shapiro 	**  otherwise the TLS handshake may fail;"
64015b0945b5SGregory Neil Shapiro 	**  In TLSv1.3 the certs in CACertFile are also sent by
64025b0945b5SGregory Neil Shapiro 	**  the client to the server and there is seemingly a
64035b0945b5SGregory Neil Shapiro 	**  16KB limit (just in OpenSSL?).
64045b0945b5SGregory Neil Shapiro 	**  Having a separate CACertFile for the client
64055b0945b5SGregory Neil Shapiro 	**  helps to avoid this problem.
64065b0945b5SGregory Neil Shapiro 	*/
64075b0945b5SGregory Neil Shapiro 
64085b0945b5SGregory Neil Shapiro 	"_FFR_CLIENTCA",
64095b0945b5SGregory Neil Shapiro #endif
64107660b554SGregory Neil Shapiro #if _FFR_CLIENT_SIZE
64117660b554SGregory Neil Shapiro 	/* Don't try to send mail if its size exceeds SIZE= of server. */
64127660b554SGregory Neil Shapiro 	"_FFR_CLIENT_SIZE",
6413da7d7b9cSGregory Neil Shapiro #endif
6414320f00e7SGregory Neil Shapiro #if _FFR_DIGUNIX_SAFECHOWN
641572936242SGregory Neil Shapiro 	/* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */
6416320f00e7SGregory Neil Shapiro /* Problem noted by Anne Bennett of Concordia University */
6417320f00e7SGregory Neil Shapiro 	"_FFR_DIGUNIX_SAFECHOWN",
6418da7d7b9cSGregory Neil Shapiro #endif
64192fb4f839SGregory Neil Shapiro #if _FFR_DM_ONE
64202fb4f839SGregory Neil Shapiro 	/* deliver first TA in background, then queue */
64212fb4f839SGregory Neil Shapiro 	"_FFR_DM_ONE",
64222fb4f839SGregory Neil Shapiro #endif
64232fb4f839SGregory Neil Shapiro #if _FFR_DMTRIGGER
64242fb4f839SGregory Neil Shapiro 	/*
64252fb4f839SGregory Neil Shapiro 	**  WIP: DeliveryMode=Trigger: queue message and notify
64262fb4f839SGregory Neil Shapiro 	**  some kind of queue manager about it.
64272fb4f839SGregory Neil Shapiro 	*/
64282fb4f839SGregory Neil Shapiro 
64292fb4f839SGregory Neil Shapiro 	"_FFR_DMTRIGGER",
64302fb4f839SGregory Neil Shapiro #endif
6431320f00e7SGregory Neil Shapiro #if _FFR_DNSMAP_ALIASABLE
643272936242SGregory Neil Shapiro 	/* Allow dns map type to be used for aliases. */
6433320f00e7SGregory Neil Shapiro /* Don Lewis of TDK */
6434320f00e7SGregory Neil Shapiro 	"_FFR_DNSMAP_ALIASABLE",
6435da7d7b9cSGregory Neil Shapiro #endif
643612ed1c7cSGregory Neil Shapiro #if _FFR_DONTLOCKFILESFORREAD_OPTION
643772936242SGregory Neil Shapiro 	/* Enable DontLockFilesForRead option. */
643812ed1c7cSGregory Neil Shapiro 	"_FFR_DONTLOCKFILESFORREAD_OPTION",
6439da7d7b9cSGregory Neil Shapiro #endif
644012ed1c7cSGregory Neil Shapiro #if _FFR_DOTTED_USERNAMES
644172936242SGregory Neil Shapiro 	/* Allow usernames with '.' */
644212ed1c7cSGregory Neil Shapiro 	"_FFR_DOTTED_USERNAMES",
6443da7d7b9cSGregory Neil Shapiro #endif
6444951742c4SGregory Neil Shapiro #if _FFR_DPO_CS
6445951742c4SGregory Neil Shapiro 	/*
6446951742c4SGregory Neil Shapiro 	**  Make DaemonPortOptions case sensitive.
6447951742c4SGregory Neil Shapiro 	**  For some unknown reasons the code converted every option
6448951742c4SGregory Neil Shapiro 	**  to uppercase (first letter only, as that's the only one that
6449951742c4SGregory Neil Shapiro 	**  is actually checked). This prevented all new lower case options
6450951742c4SGregory Neil Shapiro 	**  from working...
6451951742c4SGregory Neil Shapiro 	**  The documentation doesn't say anything about case (in)sensitivity,
6452951742c4SGregory Neil Shapiro 	**  which means it should be case sensitive by default,
6453951742c4SGregory Neil Shapiro 	**  but it's not a good idea to change this within a patch release,
6454951742c4SGregory Neil Shapiro 	**  so let's delay this to 8.15.
6455951742c4SGregory Neil Shapiro 	*/
6456951742c4SGregory Neil Shapiro 
6457951742c4SGregory Neil Shapiro 	"_FFR_DPO_CS",
6458da7d7b9cSGregory Neil Shapiro #endif
645941f3d2ceSGregory Neil Shapiro #if _FFR_DPRINTF_MAP
646041f3d2ceSGregory Neil Shapiro 	/* dprintf map for logging */
646141f3d2ceSGregory Neil Shapiro 	"_FFR_DPRINTF_MAP",
6462da7d7b9cSGregory Neil Shapiro #endif
646312ed1c7cSGregory Neil Shapiro #if _FFR_DROP_TRUSTUSER_WARNING
646472936242SGregory Neil Shapiro 	/*
646572936242SGregory Neil Shapiro 	**  Don't issue this warning:
646672936242SGregory Neil Shapiro 	**  "readcf: option TrustedUser may cause problems on systems
646772936242SGregory Neil Shapiro 	**  which do not support fchown() if UseMSP is not set.
646872936242SGregory Neil Shapiro 	*/
646972936242SGregory Neil Shapiro 
647012ed1c7cSGregory Neil Shapiro 	"_FFR_DROP_TRUSTUSER_WARNING",
6471da7d7b9cSGregory Neil Shapiro #endif
6472*d39bd2c1SGregory Neil Shapiro #if _FFR_DYN_CLASS
6473*d39bd2c1SGregory Neil Shapiro 	/* dynamic classes based on maps */
6474*d39bd2c1SGregory Neil Shapiro 	"_FFR_DYN_CLASS",
6475*d39bd2c1SGregory Neil Shapiro #endif
6476951742c4SGregory Neil Shapiro #if _FFR_EIGHT_BIT_ADDR_OK
6477*d39bd2c1SGregory Neil Shapiro 	/*
6478*d39bd2c1SGregory Neil Shapiro 	**  EightBitAddrOK: allow all 8-bit e-mail addresses.
6479*d39bd2c1SGregory Neil Shapiro 	**  By default only ((ch & 0340) == 0200) is blocked
6480*d39bd2c1SGregory Neil Shapiro 	**  because that range is used for "META" chars.
6481*d39bd2c1SGregory Neil Shapiro 	*/
6482*d39bd2c1SGregory Neil Shapiro 
6483951742c4SGregory Neil Shapiro 	"_FFR_EIGHT_BIT_ADDR_OK",
6484da7d7b9cSGregory Neil Shapiro #endif
64855b0945b5SGregory Neil Shapiro #if _FFR_EXPAND_HELONAME
64865b0945b5SGregory Neil Shapiro 	/* perform macro expansion for heloname */
64875b0945b5SGregory Neil Shapiro 	"_FFR_EXPAND_HELONAME",
64885b0945b5SGregory Neil Shapiro #endif
64897660b554SGregory Neil Shapiro #if _FFR_EXTRA_MAP_CHECK
64907660b554SGregory Neil Shapiro 	/* perform extra checks on $( $) in R lines */
64917660b554SGregory Neil Shapiro 	"_FFR_EXTRA_MAP_CHECK",
6492da7d7b9cSGregory Neil Shapiro #endif
6493951742c4SGregory Neil Shapiro #if _FFR_GETHBN_ExFILE
6494951742c4SGregory Neil Shapiro 	/*
6495951742c4SGregory Neil Shapiro 	**  According to Motonori Nakamura some gethostbyname()
6496951742c4SGregory Neil Shapiro 	**  implementations (TurboLinux?) may (temporarily) fail
6497da7d7b9cSGregory Neil Shapiro 	**  due to a lack of file descriptors. Enabling this FFR
6498951742c4SGregory Neil Shapiro 	**  will check errno for EMFILE and ENFILE and in case of a match
6499951742c4SGregory Neil Shapiro 	**  cause a temporary error instead of a permanent error.
6500951742c4SGregory Neil Shapiro 	**  The right solution is of course to file a bug against those
6501951742c4SGregory Neil Shapiro 	**  systems such that they actually set h_errno = TRY_AGAIN.
6502951742c4SGregory Neil Shapiro 	*/
6503951742c4SGregory Neil Shapiro 
6504951742c4SGregory Neil Shapiro 	"_FFR_GETHBN_ExFILE",
6505da7d7b9cSGregory Neil Shapiro #endif
6506552d4955SGregory Neil Shapiro #if _FFR_FIPSMODE
6507552d4955SGregory Neil Shapiro 	/* FIPSMode (if supported by OpenSSL library) */
6508552d4955SGregory Neil Shapiro 	"_FFR_FIPSMODE",
6509da7d7b9cSGregory Neil Shapiro #endif
651012ed1c7cSGregory Neil Shapiro #if _FFR_FIX_DASHT
651172936242SGregory Neil Shapiro 	/*
651272936242SGregory Neil Shapiro 	**  If using -t, force not sending to argv recipients, even
651372936242SGregory Neil Shapiro 	**  if they are mentioned in the headers.
651472936242SGregory Neil Shapiro 	*/
651572936242SGregory Neil Shapiro 
651612ed1c7cSGregory Neil Shapiro 	"_FFR_FIX_DASHT",
6517da7d7b9cSGregory Neil Shapiro #endif
651812ed1c7cSGregory Neil Shapiro #if _FFR_FORWARD_SYSERR
651972936242SGregory Neil Shapiro 	/* Cause a "syserr" if forward file isn't "safe". */
652012ed1c7cSGregory Neil Shapiro 	"_FFR_FORWARD_SYSERR",
6521da7d7b9cSGregory Neil Shapiro #endif
652212ed1c7cSGregory Neil Shapiro #if _FFR_GEN_ORCPT
652372936242SGregory Neil Shapiro 	/* Generate a ORCPT DSN arg if not already provided */
652412ed1c7cSGregory Neil Shapiro 	"_FFR_GEN_ORCPT",
6525da7d7b9cSGregory Neil Shapiro #endif
6526320f00e7SGregory Neil Shapiro #if _FFR_HANDLE_ISO8859_GECOS
652772936242SGregory Neil Shapiro 	/*
652872936242SGregory Neil Shapiro 	**  Allow ISO 8859 characters in GECOS field: replace them
6529da7d7b9cSGregory Neil Shapiro 	**  with ASCII "equivalent".
653072936242SGregory Neil Shapiro 	*/
653172936242SGregory Neil Shapiro 
6532320f00e7SGregory Neil Shapiro /* Peter Eriksson of Linkopings universitet */
6533320f00e7SGregory Neil Shapiro 	"_FFR_HANDLE_ISO8859_GECOS",
6534da7d7b9cSGregory Neil Shapiro #endif
6535da7d7b9cSGregory Neil Shapiro #if _FFR_HANDLE_HDR_RW_TEMPFAIL
6536da7d7b9cSGregory Neil Shapiro 	/*
6537da7d7b9cSGregory Neil Shapiro 	**  Temporary header rewriting problems from remotename() etc
6538da7d7b9cSGregory Neil Shapiro 	**  are not "sticky" for mci (e.g., during queue runs).
6539da7d7b9cSGregory Neil Shapiro 	*/
6540da7d7b9cSGregory Neil Shapiro 
6541da7d7b9cSGregory Neil Shapiro 	"_FFR_HANDLE_HDR_RW_TEMPFAIL",
6542da7d7b9cSGregory Neil Shapiro #endif
654312ed1c7cSGregory Neil Shapiro #if _FFR_HPUX_NSSWITCH
654472936242SGregory Neil Shapiro 	/* Use nsswitch on HP-UX */
654512ed1c7cSGregory Neil Shapiro 	"_FFR_HPUX_NSSWITCH",
6546da7d7b9cSGregory Neil Shapiro #endif
65477660b554SGregory Neil Shapiro #if _FFR_IGNORE_BOGUS_ADDR
65487660b554SGregory Neil Shapiro 	/* Ignore addresses for which prescan() failed */
65497660b554SGregory Neil Shapiro 	"_FFR_IGNORE_BOGUS_ADDR",
6550da7d7b9cSGregory Neil Shapiro #endif
655112ed1c7cSGregory Neil Shapiro #if _FFR_IGNORE_EXT_ON_HELO
655272936242SGregory Neil Shapiro 	/* Ignore extensions offered in response to HELO */
655312ed1c7cSGregory Neil Shapiro 	"_FFR_IGNORE_EXT_ON_HELO",
6554da7d7b9cSGregory Neil Shapiro #endif
65555b0945b5SGregory Neil Shapiro #if _FFR_KEEPBCC
65565b0945b5SGregory Neil Shapiro 	/* Keep Bcc header */
65575b0945b5SGregory Neil Shapiro 	"_FFR_KEEPBCC",
6558da7d7b9cSGregory Neil Shapiro #endif
6559e3793f76SGregory Neil Shapiro #if _FFR_LOCAL_DAEMON
6560e3793f76SGregory Neil Shapiro 	/* Local daemon mode (-bl) which only accepts loopback connections */
6561e3793f76SGregory Neil Shapiro 	"_FFR_LOCAL_DAEMON",
6562da7d7b9cSGregory Neil Shapiro #endif
6563*d39bd2c1SGregory Neil Shapiro #if _FFR_LOG_FAILOVER
6564*d39bd2c1SGregory Neil Shapiro 	/* WIP: log reason why trying another host */
6565*d39bd2c1SGregory Neil Shapiro 	"_FFR_LOG_FAILOVER",
6566*d39bd2c1SGregory Neil Shapiro #endif
6567da7d7b9cSGregory Neil Shapiro #if _FFR_LOG_MORE1
6568da7d7b9cSGregory Neil Shapiro 	/* log some TLS/AUTH info in from= too */
65695b0945b5SGregory Neil Shapiro 	"_FFR_LOG_MORE1=" SM_XSTR(_FFR_LOG_MORE1),
6570da7d7b9cSGregory Neil Shapiro #endif
6571da7d7b9cSGregory Neil Shapiro #if _FFR_LOG_MORE2
6572da7d7b9cSGregory Neil Shapiro 	/* log some TLS info in to= too */
65735b0945b5SGregory Neil Shapiro 	"_FFR_LOG_MORE2=" SM_XSTR(_FFR_LOG_MORE2),
6574da7d7b9cSGregory Neil Shapiro #endif
6575*d39bd2c1SGregory Neil Shapiro #if _FFR_LOG_STAGE
6576*d39bd2c1SGregory Neil Shapiro 	/* log protocol stage for delivery problems */
6577*d39bd2c1SGregory Neil Shapiro 	"_FFR_LOG_STAGE",
6578*d39bd2c1SGregory Neil Shapiro #endif
65799bd497b8SGregory Neil Shapiro #if _FFR_MAIL_MACRO
65805b0945b5SGregory Neil Shapiro 	/* make the "real" sender address available in {mail_from} */
65819bd497b8SGregory Neil Shapiro 	"_FFR_MAIL_MACRO",
6582da7d7b9cSGregory Neil Shapiro #endif
6583*d39bd2c1SGregory Neil Shapiro #if _FFR_MAP_CHK_FILE
6584*d39bd2c1SGregory Neil Shapiro 	/* check whether the underlying map file was changed */
6585*d39bd2c1SGregory Neil Shapiro 	"_FFR_MAP_CHK_FILE=" SM_XSTR(_FFR_MAP_CHK_FILE),
6586*d39bd2c1SGregory Neil Shapiro #endif
6587bfb62e91SGregory Neil Shapiro #if _FFR_MAXDATASIZE
6588bfb62e91SGregory Neil Shapiro 	/*
6589bfb62e91SGregory Neil Shapiro 	**  It is possible that a header is larger than MILTER_CHUNK_SIZE,
6590bfb62e91SGregory Neil Shapiro 	**  hence this shouldn't be used as limit for milter communication.
6591bfb62e91SGregory Neil Shapiro 	**  see also libmilter/comm.c
6592bfb62e91SGregory Neil Shapiro 	**  Gurusamy Sarathy of ActiveState
6593bfb62e91SGregory Neil Shapiro 	*/
6594bfb62e91SGregory Neil Shapiro 
6595684b2a5fSGregory Neil Shapiro 	"_FFR_MAXDATASIZE",
6596da7d7b9cSGregory Neil Shapiro #endif
659712ed1c7cSGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES
659872936242SGregory Neil Shapiro 	/* Try to limit number of .forward entries */
659972936242SGregory Neil Shapiro 	/* (doesn't work) */
660012ed1c7cSGregory Neil Shapiro /* Randall S. Winchester of the University of Maryland */
660112ed1c7cSGregory Neil Shapiro 	"_FFR_MAX_FORWARD_ENTRIES",
6602da7d7b9cSGregory Neil Shapiro #endif
66037660b554SGregory Neil Shapiro #if _FFR_MAX_SLEEP_TIME
66047660b554SGregory Neil Shapiro 	/* Limit sleep(2) time in libsm/clock.c */
66057660b554SGregory Neil Shapiro 	"_FFR_MAX_SLEEP_TIME",
6606da7d7b9cSGregory Neil Shapiro #endif
66079bd497b8SGregory Neil Shapiro #if _FFR_MDS_NEGOTIATE
66085b0945b5SGregory Neil Shapiro 	/* MaxDataSize negotiation with libmilter */
66099bd497b8SGregory Neil Shapiro 	"_FFR_MDS_NEGOTIATE",
6610da7d7b9cSGregory Neil Shapiro #endif
6611567a2fc9SGregory Neil Shapiro #if _FFR_MEMSTAT
6612567a2fc9SGregory Neil Shapiro 	/* Check free memory */
6613567a2fc9SGregory Neil Shapiro 	"_FFR_MEMSTAT",
6614da7d7b9cSGregory Neil Shapiro #endif
6615951742c4SGregory Neil Shapiro #if _FFR_MILTER_CHECK
6616*d39bd2c1SGregory Neil Shapiro 	/* for (lib)milter testing */
6617951742c4SGregory Neil Shapiro 	"_FFR_MILTER_CHECK",
6618da7d7b9cSGregory Neil Shapiro #endif
6619da7d7b9cSGregory Neil Shapiro #if _FFR_MILTER_CONNECT_REPLYCODE
6620da7d7b9cSGregory Neil Shapiro 	/* milter: propagate replycode returned by connect commands */
6621da7d7b9cSGregory Neil Shapiro 	/* John Gardiner Myers of Proofpoint */
6622da7d7b9cSGregory Neil Shapiro 	"_FFR_MILTER_CONNECT_REPLYCODE",
6623da7d7b9cSGregory Neil Shapiro #endif
6624951742c4SGregory Neil Shapiro #if _FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
6625951742c4SGregory Neil Shapiro 	/*
6626951742c4SGregory Neil Shapiro 	**  milter_body() uses the same conversion algorithm as putbody()
6627951742c4SGregory Neil Shapiro 	**  to translate the "local" df format (\n) to SMTP format (\r\n).
6628951742c4SGregory Neil Shapiro 	**  However, putbody() and mime8to7() use different conversion
6629951742c4SGregory Neil Shapiro 	**  algorithms.
6630951742c4SGregory Neil Shapiro 	**  If the input date does not follow the SMTP standard
6631951742c4SGregory Neil Shapiro 	**  (e.g., if it has "naked \r"s), then the output from putbody()
6632951742c4SGregory Neil Shapiro 	**  and mime8to7() will most likely be different.
6633951742c4SGregory Neil Shapiro 	**  By turning on this FFR milter_body() will try to "imitate"
6634951742c4SGregory Neil Shapiro 	**  mime8to7().
6635951742c4SGregory Neil Shapiro 	**  Note: there is no (simple) way to deal with both conversions
6636951742c4SGregory Neil Shapiro 	**  in a consistent manner. Moreover, as the "GiGo" principle applies,
6637951742c4SGregory Neil Shapiro 	**  it's not really worth to fix it.
6638951742c4SGregory Neil Shapiro 	*/
6639951742c4SGregory Neil Shapiro 
6640951742c4SGregory Neil Shapiro 	"_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF",
6641da7d7b9cSGregory Neil Shapiro #endif
6642951742c4SGregory Neil Shapiro #if _FFR_MILTER_CHECK_REJECTIONS_TOO
6643951742c4SGregory Neil Shapiro 	/*
6644951742c4SGregory Neil Shapiro 	**  Also send RCPTs that are rejected by check_rcpt to a milter
6645951742c4SGregory Neil Shapiro 	**  (if requested during option negotiation).
6646951742c4SGregory Neil Shapiro 	*/
6647951742c4SGregory Neil Shapiro 
6648951742c4SGregory Neil Shapiro 	"_FFR_MILTER_CHECK_REJECTIONS_TOO",
6649da7d7b9cSGregory Neil Shapiro #endif
66509bd497b8SGregory Neil Shapiro #if _FFR_MILTER_ENHSC
66519bd497b8SGregory Neil Shapiro 	/* extract enhanced status code from milter replies for dsn= logging */
66529bd497b8SGregory Neil Shapiro 	"_FFR_MILTER_ENHSC",
6653da7d7b9cSGregory Neil Shapiro #endif
6654bfb62e91SGregory Neil Shapiro #if _FFR_MIME7TO8_OLD
6655bfb62e91SGregory Neil Shapiro 	/* Old mime7to8 code, the new is broken for at least one example. */
6656bfb62e91SGregory Neil Shapiro 	"_FFR_MIME7TO8_OLD",
6657da7d7b9cSGregory Neil Shapiro #endif
665841f3d2ceSGregory Neil Shapiro #if _FFR_MORE_MACROS
665941f3d2ceSGregory Neil Shapiro 	/* allow more long macro names ("unprintable" characters). */
666041f3d2ceSGregory Neil Shapiro 	"_FFR_MORE_MACROS",
6661da7d7b9cSGregory Neil Shapiro #endif
6662567a2fc9SGregory Neil Shapiro #if _FFR_MSG_ACCEPT
6663567a2fc9SGregory Neil Shapiro 	/* allow to override "Message accepted for delivery" */
6664567a2fc9SGregory Neil Shapiro 	"_FFR_MSG_ACCEPT",
6665da7d7b9cSGregory Neil Shapiro #endif
66662fb4f839SGregory Neil Shapiro #if _FFR_MTA_MODE
66672fb4f839SGregory Neil Shapiro 	/* do not modify headers -- does NOT (yet) work */
66682fb4f839SGregory Neil Shapiro 	"_FFR_MTA_MODE",
66692fb4f839SGregory Neil Shapiro #endif
66702fb4f839SGregory Neil Shapiro #if _FFR_MTA_STS
66712fb4f839SGregory Neil Shapiro # if !MAP_REGEX
6672*d39bd2c1SGregory Neil Shapiro #  error "_FFR_MTA_STS requires MAP_REGEX"
66732fb4f839SGregory Neil Shapiro # endif
66742fb4f839SGregory Neil Shapiro # if !STARTTLS
6675*d39bd2c1SGregory Neil Shapiro #  error "_FFR_MTA_STS requires STARTTLS"
66762fb4f839SGregory Neil Shapiro # endif
66772fb4f839SGregory Neil Shapiro # if !_FFR_TLS_ALTNAMES
6678*d39bd2c1SGregory Neil Shapiro #  error "_FFR_MTA_STS requires _FFR_TLS_ALTNAMES"
66792fb4f839SGregory Neil Shapiro # endif
66802fb4f839SGregory Neil Shapiro 	/* MTA STS support */
66812fb4f839SGregory Neil Shapiro 	"_FFR_MTA_STS",
66822fb4f839SGregory Neil Shapiro #endif /* _FFR_MTA_STS */
668312ed1c7cSGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD
668472936242SGregory Neil Shapiro 	/* Do not issue a DELAY DSN for mailers that use the hold flag. */
668512ed1c7cSGregory Neil Shapiro /* Steven Pitzl */
668612ed1c7cSGregory Neil Shapiro 	"_FFR_NODELAYDSN_ON_HOLD",
6687da7d7b9cSGregory Neil Shapiro #endif
668812ed1c7cSGregory Neil Shapiro #if _FFR_NO_PIPE
668972936242SGregory Neil Shapiro 	/* Disable PIPELINING, delay client if used. */
669012ed1c7cSGregory Neil Shapiro 	"_FFR_NO_PIPE",
6691da7d7b9cSGregory Neil Shapiro #endif
66925b0945b5SGregory Neil Shapiro #if _FFR_LDAP_SINGLEDN
66935b0945b5SGregory Neil Shapiro 	/*
66945b0945b5SGregory Neil Shapiro 	**  The LDAP database map code in Sendmail 8.12.10, when
66955b0945b5SGregory Neil Shapiro 	**  given the -1 switch, would match only a single DN,
66965b0945b5SGregory Neil Shapiro 	**  but was able to return multiple attributes for that
66975b0945b5SGregory Neil Shapiro 	**  DN.  In Sendmail 8.13 this "bug" was corrected to
66985b0945b5SGregory Neil Shapiro 	**  only return if exactly one attribute matched.
66995b0945b5SGregory Neil Shapiro 	**
67005b0945b5SGregory Neil Shapiro 	**  Unfortunately, our configuration uses the former
67015b0945b5SGregory Neil Shapiro 	**  behaviour.  Attached is a relatively simple patch
67025b0945b5SGregory Neil Shapiro 	**  to 8.13.4 which adds a -2 switch (for lack of a
67035b0945b5SGregory Neil Shapiro 	**  better option) which returns the single dn/multiple
67045b0945b5SGregory Neil Shapiro 	**  attributes.
67055b0945b5SGregory Neil Shapiro 	**
67065b0945b5SGregory Neil Shapiro 	**  Jeffrey T. Eaton, Carnegie-Mellon University
67075b0945b5SGregory Neil Shapiro 	*/
67085b0945b5SGregory Neil Shapiro 
67095b0945b5SGregory Neil Shapiro 	"_FFR_LDAP_SINGLEDN",
6710da7d7b9cSGregory Neil Shapiro #endif
6711188b7d28SGregory Neil Shapiro #if _FFR_LOG_NTRIES
6712188b7d28SGregory Neil Shapiro 	/* log ntries=, from Nik Clayton of FreeBSD */
6713188b7d28SGregory Neil Shapiro 	"_FFR_LOG_NTRIES",
6714da7d7b9cSGregory Neil Shapiro #endif
67155b0945b5SGregory Neil Shapiro #if _FFR_OCC
67165b0945b5SGregory Neil Shapiro # if SM_CONF_SHM
67175b0945b5SGregory Neil Shapiro 	/* outgoing connection control (not yet working) */
67185b0945b5SGregory Neil Shapiro 	"_FFR_OCC",
67195b0945b5SGregory Neil Shapiro # else
6720*d39bd2c1SGregory Neil Shapiro #  error "_FFR_OCC requires SM_CONF_SHM"
67215b0945b5SGregory Neil Shapiro # endif
67225b0945b5SGregory Neil Shapiro #endif
6723da7d7b9cSGregory Neil Shapiro #if _FFR_PROXY
6724da7d7b9cSGregory Neil Shapiro 	/* "proxy" (synchronous) delivery mode */
6725da7d7b9cSGregory Neil Shapiro 	"_FFR_PROXY",
6726da7d7b9cSGregory Neil Shapiro #endif
6727951742c4SGregory Neil Shapiro #if _FFR_QF_PARANOIA
67285b0945b5SGregory Neil Shapiro 	/* Check to make sure key fields were read from qf */
6729951742c4SGregory Neil Shapiro 	"_FFR_QF_PARANOIA",
6730da7d7b9cSGregory Neil Shapiro #endif
6731320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_GROUP_SORTORDER
673272936242SGregory Neil Shapiro 	/* Allow QueueSortOrder per queue group. */
6733320f00e7SGregory Neil Shapiro /* XXX: Still need to actually use qgrp->qg_sortorder */
6734320f00e7SGregory Neil Shapiro 	"_FFR_QUEUE_GROUP_SORTORDER",
6735da7d7b9cSGregory Neil Shapiro #endif
673612ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_MACRO
673772936242SGregory Neil Shapiro 	/* Define {queue} macro. */
673812ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_MACRO",
6739da7d7b9cSGregory Neil Shapiro #endif
6740320f00e7SGregory Neil Shapiro #if _FFR_QUEUE_RUN_PARANOIA
6741567a2fc9SGregory Neil Shapiro 	/* Additional checks when doing queue runs; interval of checks */
6742320f00e7SGregory Neil Shapiro 	"_FFR_QUEUE_RUN_PARANOIA",
6743da7d7b9cSGregory Neil Shapiro #endif
674412ed1c7cSGregory Neil Shapiro #if _FFR_QUEUE_SCHED_DBG
674572936242SGregory Neil Shapiro 	/* Debug output for the queue scheduler. */
674612ed1c7cSGregory Neil Shapiro 	"_FFR_QUEUE_SCHED_DBG",
6747da7d7b9cSGregory Neil Shapiro #endif
6748da7d7b9cSGregory Neil Shapiro #if _FFR_RCPTFLAGS
67495b0945b5SGregory Neil Shapiro 	/* dynamic mailer modifications via {rcpt_flags}*/
6750da7d7b9cSGregory Neil Shapiro 	"_FFR_RCPTFLAGS",
6751da7d7b9cSGregory Neil Shapiro #endif
67529bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY
67539bd497b8SGregory Neil Shapiro 	/* configurable delay for BadRcptThrottle */
67546f9c8e5bSGregory Neil Shapiro 	"_FFR_RCPTTHROTDELAY",
6755da7d7b9cSGregory Neil Shapiro #endif
675612ed1c7cSGregory Neil Shapiro #if _FFR_REDIRECTEMPTY
675772936242SGregory Neil Shapiro 	/*
675872936242SGregory Neil Shapiro 	**  envelope <> can't be sent to mailing lists, only owner-
675972936242SGregory Neil Shapiro 	**  send spam of this type to owner- of the list
676072936242SGregory Neil Shapiro 	**  ----  to stop spam from going to mailing lists.
676172936242SGregory Neil Shapiro 	*/
676272936242SGregory Neil Shapiro 
676312ed1c7cSGregory Neil Shapiro 	"_FFR_REDIRECTEMPTY",
6764da7d7b9cSGregory Neil Shapiro #endif
6765552d4955SGregory Neil Shapiro #if _FFR_REJECT_NUL_BYTE
6766552d4955SGregory Neil Shapiro 	/* reject NUL bytes in body */
6767552d4955SGregory Neil Shapiro 	"_FFR_REJECT_NUL_BYTE",
6768da7d7b9cSGregory Neil Shapiro #endif
67692fb4f839SGregory Neil Shapiro #if _FFR_REPLY_MULTILINE
67702fb4f839SGregory Neil Shapiro 	/* try to gather multi-line replies for reply= logging */
67712fb4f839SGregory Neil Shapiro 	"_FFR_REPLY_MULTILINE=" SM_XSTR(_FFR_REPLY_MULTILINE),
67722fb4f839SGregory Neil Shapiro #endif
677312ed1c7cSGregory Neil Shapiro #if _FFR_RESET_MACRO_GLOBALS
677472936242SGregory Neil Shapiro 	/* Allow macro 'j' to be set dynamically via rulesets. */
677512ed1c7cSGregory Neil Shapiro 	"_FFR_RESET_MACRO_GLOBALS",
6776da7d7b9cSGregory Neil Shapiro #endif
677712ed1c7cSGregory Neil Shapiro #if _FFR_RHS
677872936242SGregory Neil Shapiro 	/* Random shuffle for queue sorting. */
677912ed1c7cSGregory Neil Shapiro 	"_FFR_RHS",
6780da7d7b9cSGregory Neil Shapiro #endif
678141f3d2ceSGregory Neil Shapiro #if _FFR_RUNPQG
678241f3d2ceSGregory Neil Shapiro 	/*
678341f3d2ceSGregory Neil Shapiro 	**  allow -qGqueue_group -qp to work, i.e.,
678441f3d2ceSGregory Neil Shapiro 	**  restrict a persistent queue runner to a queue group.
678541f3d2ceSGregory Neil Shapiro 	*/
678641f3d2ceSGregory Neil Shapiro 
678741f3d2ceSGregory Neil Shapiro 	"_FFR_RUNPQG",
6788da7d7b9cSGregory Neil Shapiro #endif
678941f3d2ceSGregory Neil Shapiro #if _FFR_SESSID
67905b0945b5SGregory Neil Shapiro 	/* session id (for logging): WIP, no logging yet!  */
679141f3d2ceSGregory Neil Shapiro 	"_FFR_SESSID",
6792da7d7b9cSGregory Neil Shapiro #endif
67935b0945b5SGregory Neil Shapiro #if _FFR_SETANYOPT
6794*d39bd2c1SGregory Neil Shapiro 	/*
6795*d39bd2c1SGregory Neil Shapiro 	**  if _FFR_SETOPT_MAP is used: allow to set any option
6796*d39bd2c1SGregory Neil Shapiro 	**  (which probably does not work as expected for many options).
6797*d39bd2c1SGregory Neil Shapiro 	*/
6798*d39bd2c1SGregory Neil Shapiro 
67995b0945b5SGregory Neil Shapiro 	"_FFR_SETANYOPT",
68005b0945b5SGregory Neil Shapiro #endif
68015b0945b5SGregory Neil Shapiro #if _FFR_SETDEBUG_MAP
6802*d39bd2c1SGregory Neil Shapiro 	/* enable setdebug map to set debug levels from rules */
68035b0945b5SGregory Neil Shapiro 	"_FFR_SETDEBUG_MAP",
68045b0945b5SGregory Neil Shapiro #endif
68055b0945b5SGregory Neil Shapiro #if _FFR_SETOPT_MAP
6806*d39bd2c1SGregory Neil Shapiro 	/* enable setopt map to set options from rules */
68075b0945b5SGregory Neil Shapiro 	"_FFR_SETOPT_MAP",
68085b0945b5SGregory Neil Shapiro #endif
680912ed1c7cSGregory Neil Shapiro #if _FFR_SHM_STATUS
681072936242SGregory Neil Shapiro 	/* Donated code (unused). */
681112ed1c7cSGregory Neil Shapiro 	"_FFR_SHM_STATUS",
6812da7d7b9cSGregory Neil Shapiro #endif
6813bfb62e91SGregory Neil Shapiro #if _FFR_SKIP_DOMAINS
6814bfb62e91SGregory Neil Shapiro 	/* process every N'th domain instead of every N'th message */
6815684b2a5fSGregory Neil Shapiro 	"_FFR_SKIP_DOMAINS",
6816da7d7b9cSGregory Neil Shapiro #endif
68177660b554SGregory Neil Shapiro #if _FFR_SLEEP_USE_SELECT
68187660b554SGregory Neil Shapiro 	/* Use select(2) in libsm/clock.c to emulate sleep(2) */
68197660b554SGregory Neil Shapiro 	"_FFR_SLEEP_USE_SELECT",
6820da7d7b9cSGregory Neil Shapiro #endif
68215b0945b5SGregory Neil Shapiro #if _FFR_SM_LDAP_DBG
6822*d39bd2c1SGregory Neil Shapiro # if defined(LBER_OPT_LOG_PRINT_FN)
68235b0945b5SGregory Neil Shapiro 	/* LDAP debugging */
68245b0945b5SGregory Neil Shapiro 	"_FFR_SM_LDAP_DBG",
68255b0945b5SGregory Neil Shapiro # else
6826*d39bd2c1SGregory Neil Shapiro #  error "_FFR_SM_LDAP_DBG requires LBER_OPT_LOG_PRINT_FN"
68275b0945b5SGregory Neil Shapiro # endif
68285b0945b5SGregory Neil Shapiro #endif
682988ad41d4SGregory Neil Shapiro #if _FFR_SPT_ALIGN
683072936242SGregory Neil Shapiro 	/*
683172936242SGregory Neil Shapiro 	**  It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64
683272936242SGregory Neil Shapiro 	**  bit alignment, so unless each piece of argv and envp is a multiple
683372936242SGregory Neil Shapiro 	**  of 8 bytes (including terminating NULL), initsetproctitle() won't
683472936242SGregory Neil Shapiro 	**  use any of the space beyond argv[0]. Be sure to set SPT_ALIGN_SIZE
683572936242SGregory Neil Shapiro 	**  if you use this FFR.
683672936242SGregory Neil Shapiro 	*/
683772936242SGregory Neil Shapiro 
683888ad41d4SGregory Neil Shapiro /* Chris Adams of HiWAAY Informations Services */
683988ad41d4SGregory Neil Shapiro 	"_FFR_SPT_ALIGN",
6840da7d7b9cSGregory Neil Shapiro #endif
6841188b7d28SGregory Neil Shapiro #if _FFR_SS_PER_DAEMON
6842188b7d28SGregory Neil Shapiro 	/* SuperSafe per DaemonPortOptions: 'T' (better letter?) */
6843188b7d28SGregory Neil Shapiro 	"_FFR_SS_PER_DAEMON",
6844da7d7b9cSGregory Neil Shapiro #endif
68459bd497b8SGregory Neil Shapiro #if _FFR_TESTS
68469bd497b8SGregory Neil Shapiro 	/* enable some test code */
68479bd497b8SGregory Neil Shapiro 	"_FFR_TESTS",
6848da7d7b9cSGregory Neil Shapiro #endif
684912ed1c7cSGregory Neil Shapiro #if _FFR_TIMERS
685072936242SGregory Neil Shapiro 	/* Donated code (unused). */
685112ed1c7cSGregory Neil Shapiro 	"_FFR_TIMERS",
6852da7d7b9cSGregory Neil Shapiro #endif
68535b0945b5SGregory Neil Shapiro #if _FFR_TLS_ALTNAMES
68545b0945b5SGregory Neil Shapiro 	/* store subjectAltNames in class {cert_altnames} */
68555b0945b5SGregory Neil Shapiro 	"_FFR_TLS_ALTNAMES",
68565b0945b5SGregory Neil Shapiro #endif
68575b0945b5SGregory Neil Shapiro #if _FFR_TLSFB2CLEAR
68585b0945b5SGregory Neil Shapiro 	/* set default for TLSFallbacktoClear to true */
68595b0945b5SGregory Neil Shapiro 	"_FFR_TLSFB2CLEAR",
6860da7d7b9cSGregory Neil Shapiro #endif
6861da7d7b9cSGregory Neil Shapiro #if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
6862da7d7b9cSGregory Neil Shapiro 	/*
6863da7d7b9cSGregory Neil Shapiro 	**  Use SSL_CTX_use_certificate_chain_file()
6864da7d7b9cSGregory Neil Shapiro 	**  instead of SSL_CTX_use_certificate_file()
6865da7d7b9cSGregory Neil Shapiro 	*/
6866da7d7b9cSGregory Neil Shapiro 
6867da7d7b9cSGregory Neil Shapiro 	"_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE",
6868da7d7b9cSGregory Neil Shapiro #endif
686912ed1c7cSGregory Neil Shapiro #if _FFR_TRUSTED_QF
687072936242SGregory Neil Shapiro 	/*
687172936242SGregory Neil Shapiro 	**  If we don't own the file mark it as unsafe.
687272936242SGregory Neil Shapiro 	**  However, allow TrustedUser to own it as well
687372936242SGregory Neil Shapiro 	**  in case TrustedUser manipulates the queue.
687472936242SGregory Neil Shapiro 	*/
687572936242SGregory Neil Shapiro 
687612ed1c7cSGregory Neil Shapiro 	"_FFR_TRUSTED_QF",
6877da7d7b9cSGregory Neil Shapiro #endif
68785dd76dd0SGregory Neil Shapiro #if _FFR_USE_GETPWNAM_ERRNO
68795dd76dd0SGregory Neil Shapiro 	/*
68805dd76dd0SGregory Neil Shapiro 	**  See libsm/mbdb.c: only enable this on OSs
68815dd76dd0SGregory Neil Shapiro 	**  that implement the correct (POSIX) semantics.
68824313cc83SGregory Neil Shapiro 	**  This will need to become an OS-specific #if enabled
68834313cc83SGregory Neil Shapiro 	**  in one of the headers files under include/sm/os/ .
68845dd76dd0SGregory Neil Shapiro 	*/
68855dd76dd0SGregory Neil Shapiro 
68865dd76dd0SGregory Neil Shapiro 	"_FFR_USE_GETPWNAM_ERRNO",
6887da7d7b9cSGregory Neil Shapiro #endif
68885b0945b5SGregory Neil Shapiro #if _FFR_VRFY_TRUSTED_FIRST
68895b0945b5SGregory Neil Shapiro 	/*
68905b0945b5SGregory Neil Shapiro 	**  Sets X509_V_FLAG_TRUSTED_FIRST if -d88;.101 is used.
68915b0945b5SGregory Neil Shapiro 	**  X509_VERIFY_PARAM_set_flags(3)
68925b0945b5SGregory Neil Shapiro 	**  When X509_V_FLAG_TRUSTED_FIRST is set, construction of the
68935b0945b5SGregory Neil Shapiro 	**  certificate chain in X509_verify_cert(3) will search the trust
68945b0945b5SGregory Neil Shapiro 	**  store for issuer certificates before searching the provided
68955b0945b5SGregory Neil Shapiro 	**  untrusted certificates. Local issuer certificates are often more
68965b0945b5SGregory Neil Shapiro 	**  likely to satisfy local security requirements and lead to a locally
68975b0945b5SGregory Neil Shapiro 	**  trusted root. This is especially important when some certificates
68985b0945b5SGregory Neil Shapiro 	**  in the trust store have explicit trust settings (see "TRUST
68995b0945b5SGregory Neil Shapiro 	**  SETTINGS" in x509(1)).
69005b0945b5SGregory Neil Shapiro 	**  As of OpenSSL 1.1.0 this option is on by default.
69015b0945b5SGregory Neil Shapiro 	*/
69025b0945b5SGregory Neil Shapiro 
69035b0945b5SGregory Neil Shapiro # if defined(X509_V_FLAG_TRUSTED_FIRST)
69045b0945b5SGregory Neil Shapiro 	"_FFR_VRFY_TRUSTED_FIRST",
69055b0945b5SGregory Neil Shapiro # else
6906*d39bd2c1SGregory Neil Shapiro #  error "_FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
69075b0945b5SGregory Neil Shapiro # endif
69085b0945b5SGregory Neil Shapiro #endif
69095b0945b5SGregory Neil Shapiro 
6910188b7d28SGregory Neil Shapiro #if _FFR_USE_SEM_LOCKING
69115b0945b5SGregory Neil Shapiro 	/* Use semaphore locking */
6912188b7d28SGregory Neil Shapiro 	"_FFR_USE_SEM_LOCKING",
6913da7d7b9cSGregory Neil Shapiro #endif
6914320f00e7SGregory Neil Shapiro #if _FFR_USE_SETLOGIN
691572936242SGregory Neil Shapiro 	/* Use setlogin() */
6916320f00e7SGregory Neil Shapiro /* Peter Philipp */
6917320f00e7SGregory Neil Shapiro 	"_FFR_USE_SETLOGIN",
6918da7d7b9cSGregory Neil Shapiro #endif
6919da7d7b9cSGregory Neil Shapiro #if _FFR_XCNCT
69205b0945b5SGregory Neil Shapiro 	/* X-Connect support */
6921da7d7b9cSGregory Neil Shapiro 	"_FFR_XCNCT",
6922da7d7b9cSGregory Neil Shapiro #endif
6923*d39bd2c1SGregory Neil Shapiro #if _FFR_HAPROXY
6924*d39bd2c1SGregory Neil Shapiro 	/* HAproxy support */
6925*d39bd2c1SGregory Neil Shapiro 	"_FFR_HAPROXY",
6926*d39bd2c1SGregory Neil Shapiro #endif
69272fb4f839SGregory Neil Shapiro #if _FFR_LOGASIS
6928*d39bd2c1SGregory Neil Shapiro 	/* only convert char <= 31 to something printable for logging etc */
69292fb4f839SGregory Neil Shapiro 	"_FFR_LOGASIS=" SM_XSTR(_FFR_LOGASIS),
69302fb4f839SGregory Neil Shapiro #endif
6931*d39bd2c1SGregory Neil Shapiro #if _FFR_NAMESERVER
6932*d39bd2c1SGregory Neil Shapiro 	/* Allow to override nameserver set by OS */
6933*d39bd2c1SGregory Neil Shapiro 	"_FFR_NAMESERVER",
6934*d39bd2c1SGregory Neil Shapiro #endif
69352fb4f839SGregory Neil Shapiro #if _FFR_NOREFLECT
6936*d39bd2c1SGregory Neil Shapiro 	/* Do not include input from a client in a reply of the server */
69372fb4f839SGregory Neil Shapiro 	"_FFR_NOREFLECT",
69382fb4f839SGregory Neil Shapiro #endif
69392fb4f839SGregory Neil Shapiro #if _FFR_AUTH_PASSING
69402fb4f839SGregory Neil Shapiro 	/* Set the default AUTH= if the sender didn't */
69412fb4f839SGregory Neil Shapiro 	"_FFR_AUTH_PASSING",
69422fb4f839SGregory Neil Shapiro #endif
69432fb4f839SGregory Neil Shapiro #if _FFR_HOST_SORT_REVERSE
69442fb4f839SGregory Neil Shapiro 	/* Reverse sort for host for recipient sorting pre-envelope-split */
69452fb4f839SGregory Neil Shapiro 	"_FFR_HOST_SORT_REVERSE",
69462fb4f839SGregory Neil Shapiro #endif
69472fb4f839SGregory Neil Shapiro #if _FFR_MSP_PARANOIA
69485b0945b5SGregory Neil Shapiro 	/*
6949*d39bd2c1SGregory Neil Shapiro 	**  Forbid queue groups, multiple queues, and
6950*d39bd2c1SGregory Neil Shapiro 	**  dangerous queue permissions when operating as an MSP
69515b0945b5SGregory Neil Shapiro 	*/
69525b0945b5SGregory Neil Shapiro 
69532fb4f839SGregory Neil Shapiro 	"_FFR_MSP_PARANOIA",
69545b0945b5SGregory Neil Shapiro #endif
69552fb4f839SGregory Neil Shapiro #if _FFR_ANY_FREE_FS
69562fb4f839SGregory Neil Shapiro 	/*
69572fb4f839SGregory Neil Shapiro 	**  Check whether there is at least one fs with enough space
69582fb4f839SGregory Neil Shapiro 	**  (may not work, needs review)
69592fb4f839SGregory Neil Shapiro 	*/
69602fb4f839SGregory Neil Shapiro 
69612fb4f839SGregory Neil Shapiro 	"_FFR_ANY_FREE_FS",
69625b0945b5SGregory Neil Shapiro #endif
69632fb4f839SGregory Neil Shapiro #if _FFR_MIME_CR_OK
69642fb4f839SGregory Neil Shapiro 	/*
69652fb4f839SGregory Neil Shapiro 	**  Strip trailing CR in MIME boundaries
69662fb4f839SGregory Neil Shapiro 	**  (may not work, needs review)
69672fb4f839SGregory Neil Shapiro 	*/
69682fb4f839SGregory Neil Shapiro 
69692fb4f839SGregory Neil Shapiro 	"_FFR_MIME_CR_OK",
69705b0945b5SGregory Neil Shapiro #endif
6971*d39bd2c1SGregory Neil Shapiro #if _FFR_M_ONLY_IPV4
6972*d39bd2c1SGregory Neil Shapiro 	/* mailer flag 4: use only IPv4 for delivery attempts */
6973*d39bd2c1SGregory Neil Shapiro 	"_FFR_M_ONLY_IPV4",
6974*d39bd2c1SGregory Neil Shapiro #endif
6975*d39bd2c1SGregory Neil Shapiro #if _FFR_SMTPS_CLIENT
6976*d39bd2c1SGregory Neil Shapiro 	/* SMTP over TLS client (defaults to port 465/tcp outbound) */
6977*d39bd2c1SGregory Neil Shapiro 	"_FFR_SMTPS_CLIENT",
6978*d39bd2c1SGregory Neil Shapiro #endif
6979c2aa98e2SPeter Wemm 	NULL
6980c2aa98e2SPeter Wemm };
6981