xref: /titanic_53/usr/src/cmd/sendmail/src/conf.c (revision d25d47ee62f52e470a91221e64abe838a0af786d)
17c478bd9Sstevel@tonic-gate /*
2445f2479Sjbeck  * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
37c478bd9Sstevel@tonic-gate  *	All rights reserved.
47c478bd9Sstevel@tonic-gate  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
57c478bd9Sstevel@tonic-gate  * Copyright (c) 1988, 1993
67c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
97c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
107c478bd9Sstevel@tonic-gate  * the sendmail distribution.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  */
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate /*
15*d25d47eeSjbeck  * Copyright 1999-2006 Sun Microsystems, Inc.  All rights reserved.
167c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #include <sendmail.h>
227c478bd9Sstevel@tonic-gate 
233ee0e492Sjbeck SM_RCSID("@(#)$Id: conf.c,v 8.1082 2006/03/22 22:49:33 ca Exp $")
247c478bd9Sstevel@tonic-gate SM_IDSTR(i2, "%W% (Sun) %G%")
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sendmail/pathnames.h>
277c478bd9Sstevel@tonic-gate #if NEWDB
287c478bd9Sstevel@tonic-gate # include "sm/bdb.h"
297c478bd9Sstevel@tonic-gate #endif /* NEWDB */
307c478bd9Sstevel@tonic-gate 
3149218d4fSjbeck #ifdef DEC
3249218d4fSjbeck # if NETINET6
3349218d4fSjbeck /* for the IPv6 device lookup */
3449218d4fSjbeck #  define _SOCKADDR_LEN
3549218d4fSjbeck #  include <macros.h>
3649218d4fSjbeck # endif /* NETINET6 */
3749218d4fSjbeck #endif /* DEC */
3849218d4fSjbeck 
397c478bd9Sstevel@tonic-gate # include <sys/ioctl.h>
407c478bd9Sstevel@tonic-gate # include <sys/param.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <limits.h>
437c478bd9Sstevel@tonic-gate #if NETINET || NETINET6
447c478bd9Sstevel@tonic-gate # include <arpa/inet.h>
457c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */
467c478bd9Sstevel@tonic-gate #if HASULIMIT && defined(HPUX11)
477c478bd9Sstevel@tonic-gate # include <ulimit.h>
487c478bd9Sstevel@tonic-gate #endif /* HASULIMIT && defined(HPUX11) */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate static void	setupmaps __P((void));
517c478bd9Sstevel@tonic-gate static void	setupmailers __P((void));
527c478bd9Sstevel@tonic-gate static void	setupqueues __P((void));
537c478bd9Sstevel@tonic-gate static int	get_num_procs_online __P((void));
547c478bd9Sstevel@tonic-gate static int	add_hostnames __P((SOCKADDR *));
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #if NETINET6 && NEEDSGETIPNODE
577c478bd9Sstevel@tonic-gate static struct hostent *getipnodebyname __P((char *, int, int, int *));
587c478bd9Sstevel@tonic-gate static struct hostent *getipnodebyaddr __P((char *, int, int, int *));
597c478bd9Sstevel@tonic-gate #endif /* NETINET6 && NEEDSGETIPNODE */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate **  CONF.C -- Sendmail Configuration Tables.
647c478bd9Sstevel@tonic-gate **
657c478bd9Sstevel@tonic-gate **	Defines the configuration of this installation.
667c478bd9Sstevel@tonic-gate **
677c478bd9Sstevel@tonic-gate **	Configuration Variables:
687c478bd9Sstevel@tonic-gate **		HdrInfo -- a table describing well-known header fields.
697c478bd9Sstevel@tonic-gate **			Each entry has the field name and some flags,
707c478bd9Sstevel@tonic-gate **			which are described in sendmail.h.
717c478bd9Sstevel@tonic-gate **
727c478bd9Sstevel@tonic-gate **	Notes:
737c478bd9Sstevel@tonic-gate **		I have tried to put almost all the reasonable
747c478bd9Sstevel@tonic-gate **		configuration information into the configuration
757c478bd9Sstevel@tonic-gate **		file read at runtime.  My intent is that anything
767c478bd9Sstevel@tonic-gate **		here is a function of the version of UNIX you
777c478bd9Sstevel@tonic-gate **		are running, or is really static -- for example
787c478bd9Sstevel@tonic-gate **		the headers are a superset of widely used
797c478bd9Sstevel@tonic-gate **		protocols.  If you find yourself playing with
807c478bd9Sstevel@tonic-gate **		this file too much, you may be making a mistake!
817c478bd9Sstevel@tonic-gate */
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate **  Header info table
867c478bd9Sstevel@tonic-gate **	Final (null) entry contains the flags used for any other field.
877c478bd9Sstevel@tonic-gate **
887c478bd9Sstevel@tonic-gate **	Not all of these are actually handled specially by sendmail
897c478bd9Sstevel@tonic-gate **	at this time.  They are included as placeholders, to let
907c478bd9Sstevel@tonic-gate **	you know that "someday" I intend to have sendmail do
917c478bd9Sstevel@tonic-gate **	something with them.
927c478bd9Sstevel@tonic-gate */
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate struct hdrinfo	HdrInfo[] =
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate 		/* originator fields, most to least significant */
977c478bd9Sstevel@tonic-gate 	{ "resent-sender",		H_FROM|H_RESENT,	NULL	},
987c478bd9Sstevel@tonic-gate 	{ "resent-from",		H_FROM|H_RESENT,	NULL	},
997c478bd9Sstevel@tonic-gate 	{ "resent-reply-to",		H_FROM|H_RESENT,	NULL	},
1007c478bd9Sstevel@tonic-gate 	{ "sender",			H_FROM,			NULL	},
1017c478bd9Sstevel@tonic-gate 	{ "from",			H_FROM,			NULL	},
1027c478bd9Sstevel@tonic-gate 	{ "reply-to",			H_FROM,			NULL	},
1037c478bd9Sstevel@tonic-gate 	{ "errors-to",			H_FROM|H_ERRORSTO,	NULL	},
1047c478bd9Sstevel@tonic-gate 	{ "full-name",			H_ACHECK,		NULL	},
1057c478bd9Sstevel@tonic-gate 	{ "return-receipt-to",		H_RECEIPTTO,		NULL	},
1067c478bd9Sstevel@tonic-gate 	{ "delivery-receipt-to",	H_RECEIPTTO,		NULL	},
1077c478bd9Sstevel@tonic-gate 	{ "disposition-notification-to",	H_FROM,		NULL	},
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 		/* destination fields */
1107c478bd9Sstevel@tonic-gate 	{ "to",				H_RCPT,			NULL	},
1117c478bd9Sstevel@tonic-gate 	{ "resent-to",			H_RCPT|H_RESENT,	NULL	},
1127c478bd9Sstevel@tonic-gate 	{ "cc",				H_RCPT,			NULL	},
1137c478bd9Sstevel@tonic-gate 	{ "resent-cc",			H_RCPT|H_RESENT,	NULL	},
1147c478bd9Sstevel@tonic-gate 	{ "bcc",			H_RCPT|H_BCC,		NULL	},
1157c478bd9Sstevel@tonic-gate 	{ "resent-bcc",			H_RCPT|H_BCC|H_RESENT,	NULL	},
1167c478bd9Sstevel@tonic-gate 	{ "apparently-to",		H_RCPT,			NULL	},
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 		/* message identification and control */
1197c478bd9Sstevel@tonic-gate 	{ "message-id",			0,			NULL	},
1207c478bd9Sstevel@tonic-gate 	{ "resent-message-id",		H_RESENT,		NULL	},
1217c478bd9Sstevel@tonic-gate 	{ "message",			H_EOH,			NULL	},
1227c478bd9Sstevel@tonic-gate 	{ "text",			H_EOH,			NULL	},
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 		/* date fields */
1257c478bd9Sstevel@tonic-gate 	{ "date",			0,			NULL	},
1267c478bd9Sstevel@tonic-gate 	{ "resent-date",		H_RESENT,		NULL	},
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 		/* trace fields */
1297c478bd9Sstevel@tonic-gate 	{ "received",			H_TRACE|H_FORCE,	NULL	},
1307c478bd9Sstevel@tonic-gate 	{ "x400-received",		H_TRACE|H_FORCE,	NULL	},
1317c478bd9Sstevel@tonic-gate 	{ "via",			H_TRACE|H_FORCE,	NULL	},
1327c478bd9Sstevel@tonic-gate 	{ "mail-from",			H_TRACE|H_FORCE,	NULL	},
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 		/* miscellaneous fields */
1357c478bd9Sstevel@tonic-gate 	{ "comments",			H_FORCE|H_ENCODABLE,	NULL	},
1367c478bd9Sstevel@tonic-gate 	{ "return-path",		H_FORCE|H_ACHECK|H_BINDLATE,	NULL	},
1377c478bd9Sstevel@tonic-gate 	{ "content-transfer-encoding",	H_CTE,			NULL	},
1387c478bd9Sstevel@tonic-gate 	{ "content-type",		H_CTYPE,		NULL	},
1397c478bd9Sstevel@tonic-gate 	{ "content-length",		H_ACHECK,		NULL	},
1407c478bd9Sstevel@tonic-gate 	{ "subject",			H_ENCODABLE,		NULL	},
1417c478bd9Sstevel@tonic-gate 	{ "x-authentication-warning",	H_FORCE,		NULL	},
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	{ NULL,				0,			NULL	}
1447c478bd9Sstevel@tonic-gate };
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate **  Privacy values
1507c478bd9Sstevel@tonic-gate */
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate struct prival PrivacyValues[] =
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate 	{ "public",		PRIV_PUBLIC		},
1557c478bd9Sstevel@tonic-gate 	{ "needmailhelo",	PRIV_NEEDMAILHELO	},
1567c478bd9Sstevel@tonic-gate 	{ "needexpnhelo",	PRIV_NEEDEXPNHELO	},
1577c478bd9Sstevel@tonic-gate 	{ "needvrfyhelo",	PRIV_NEEDVRFYHELO	},
1587c478bd9Sstevel@tonic-gate 	{ "noexpn",		PRIV_NOEXPN		},
1597c478bd9Sstevel@tonic-gate 	{ "novrfy",		PRIV_NOVRFY		},
1607c478bd9Sstevel@tonic-gate 	{ "restrictexpand",	PRIV_RESTRICTEXPAND	},
1617c478bd9Sstevel@tonic-gate 	{ "restrictmailq",	PRIV_RESTRICTMAILQ	},
1627c478bd9Sstevel@tonic-gate 	{ "restrictqrun",	PRIV_RESTRICTQRUN	},
1637c478bd9Sstevel@tonic-gate 	{ "noetrn",		PRIV_NOETRN		},
1647c478bd9Sstevel@tonic-gate 	{ "noverb",		PRIV_NOVERB		},
1657c478bd9Sstevel@tonic-gate 	{ "authwarnings",	PRIV_AUTHWARNINGS	},
1667c478bd9Sstevel@tonic-gate 	{ "noreceipts",		PRIV_NORECEIPTS		},
1677c478bd9Sstevel@tonic-gate 	{ "nobodyreturn",	PRIV_NOBODYRETN		},
1687c478bd9Sstevel@tonic-gate 	{ "goaway",		PRIV_GOAWAY		},
1697c478bd9Sstevel@tonic-gate #if _FFR_PRIV_NOACTUALRECIPIENT
1707c478bd9Sstevel@tonic-gate 	{ "noactualrecipient",	PRIV_NOACTUALRECIPIENT	},
1717c478bd9Sstevel@tonic-gate #endif /* _FFR_PRIV_NOACTUALRECIPIENT */
1727c478bd9Sstevel@tonic-gate 	{ NULL,			0			}
1737c478bd9Sstevel@tonic-gate };
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate **  DontBlameSendmail values
1777c478bd9Sstevel@tonic-gate */
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate struct dbsval DontBlameSendmailValues[] =
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate 	{ "safe",			DBS_SAFE			},
1827c478bd9Sstevel@tonic-gate 	{ "assumesafechown",		DBS_ASSUMESAFECHOWN		},
1837c478bd9Sstevel@tonic-gate 	{ "groupwritabledirpathsafe",	DBS_GROUPWRITABLEDIRPATHSAFE	},
1847c478bd9Sstevel@tonic-gate 	{ "groupwritableforwardfilesafe",
1857c478bd9Sstevel@tonic-gate 					DBS_GROUPWRITABLEFORWARDFILESAFE },
1867c478bd9Sstevel@tonic-gate 	{ "groupwritableincludefilesafe",
1877c478bd9Sstevel@tonic-gate 					DBS_GROUPWRITABLEINCLUDEFILESAFE },
1887c478bd9Sstevel@tonic-gate 	{ "groupwritablealiasfile",	DBS_GROUPWRITABLEALIASFILE	},
1897c478bd9Sstevel@tonic-gate 	{ "worldwritablealiasfile",	DBS_WORLDWRITABLEALIASFILE	},
1907c478bd9Sstevel@tonic-gate 	{ "forwardfileinunsafedirpath",	DBS_FORWARDFILEINUNSAFEDIRPATH	},
1917c478bd9Sstevel@tonic-gate 	{ "includefileinunsafedirpath",	DBS_INCLUDEFILEINUNSAFEDIRPATH	},
1927c478bd9Sstevel@tonic-gate 	{ "mapinunsafedirpath",		DBS_MAPINUNSAFEDIRPATH	},
1937c478bd9Sstevel@tonic-gate 	{ "linkedaliasfileinwritabledir",
1947c478bd9Sstevel@tonic-gate 					DBS_LINKEDALIASFILEINWRITABLEDIR },
1957c478bd9Sstevel@tonic-gate 	{ "linkedclassfileinwritabledir",
1967c478bd9Sstevel@tonic-gate 					DBS_LINKEDCLASSFILEINWRITABLEDIR },
1977c478bd9Sstevel@tonic-gate 	{ "linkedforwardfileinwritabledir",
1987c478bd9Sstevel@tonic-gate 					DBS_LINKEDFORWARDFILEINWRITABLEDIR },
1997c478bd9Sstevel@tonic-gate 	{ "linkedincludefileinwritabledir",
2007c478bd9Sstevel@tonic-gate 					DBS_LINKEDINCLUDEFILEINWRITABLEDIR },
2017c478bd9Sstevel@tonic-gate 	{ "linkedmapinwritabledir",	DBS_LINKEDMAPINWRITABLEDIR	},
2027c478bd9Sstevel@tonic-gate 	{ "linkedserviceswitchfileinwritabledir",
2037c478bd9Sstevel@tonic-gate 					DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR },
2047c478bd9Sstevel@tonic-gate 	{ "filedeliverytohardlink",	DBS_FILEDELIVERYTOHARDLINK	},
2057c478bd9Sstevel@tonic-gate 	{ "filedeliverytosymlink",	DBS_FILEDELIVERYTOSYMLINK	},
2067c478bd9Sstevel@tonic-gate 	{ "writemaptohardlink",		DBS_WRITEMAPTOHARDLINK		},
2077c478bd9Sstevel@tonic-gate 	{ "writemaptosymlink",		DBS_WRITEMAPTOSYMLINK		},
2087c478bd9Sstevel@tonic-gate 	{ "writestatstohardlink",	DBS_WRITESTATSTOHARDLINK	},
2097c478bd9Sstevel@tonic-gate 	{ "writestatstosymlink",	DBS_WRITESTATSTOSYMLINK		},
2107c478bd9Sstevel@tonic-gate 	{ "forwardfileingroupwritabledirpath",
2117c478bd9Sstevel@tonic-gate 					DBS_FORWARDFILEINGROUPWRITABLEDIRPATH },
2127c478bd9Sstevel@tonic-gate 	{ "includefileingroupwritabledirpath",
2137c478bd9Sstevel@tonic-gate 					DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH },
2147c478bd9Sstevel@tonic-gate 	{ "classfileinunsafedirpath",	DBS_CLASSFILEINUNSAFEDIRPATH	},
2157c478bd9Sstevel@tonic-gate 	{ "errorheaderinunsafedirpath",	DBS_ERRORHEADERINUNSAFEDIRPATH	},
2167c478bd9Sstevel@tonic-gate 	{ "helpfileinunsafedirpath",	DBS_HELPFILEINUNSAFEDIRPATH	},
2177c478bd9Sstevel@tonic-gate 	{ "forwardfileinunsafedirpathsafe",
2187c478bd9Sstevel@tonic-gate 					DBS_FORWARDFILEINUNSAFEDIRPATHSAFE },
2197c478bd9Sstevel@tonic-gate 	{ "includefileinunsafedirpathsafe",
2207c478bd9Sstevel@tonic-gate 					DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
2217c478bd9Sstevel@tonic-gate 	{ "runprograminunsafedirpath",	DBS_RUNPROGRAMINUNSAFEDIRPATH	},
2227c478bd9Sstevel@tonic-gate 	{ "runwritableprogram",		DBS_RUNWRITABLEPROGRAM		},
2237c478bd9Sstevel@tonic-gate 	{ "nonrootsafeaddr",		DBS_NONROOTSAFEADDR		},
2247c478bd9Sstevel@tonic-gate 	{ "truststickybit",		DBS_TRUSTSTICKYBIT		},
2257c478bd9Sstevel@tonic-gate 	{ "dontwarnforwardfileinunsafedirpath",
2267c478bd9Sstevel@tonic-gate 					DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH },
2277c478bd9Sstevel@tonic-gate 	{ "insufficiententropy",	DBS_INSUFFICIENTENTROPY },
2287c478bd9Sstevel@tonic-gate 	{ "groupreadablesasldbfile",	DBS_GROUPREADABLESASLDBFILE	},
2297c478bd9Sstevel@tonic-gate 	{ "groupwritablesasldbfile",	DBS_GROUPWRITABLESASLDBFILE	},
2307c478bd9Sstevel@tonic-gate 	{ "groupwritableforwardfile",	DBS_GROUPWRITABLEFORWARDFILE	},
2317c478bd9Sstevel@tonic-gate 	{ "groupwritableincludefile",	DBS_GROUPWRITABLEINCLUDEFILE	},
2327c478bd9Sstevel@tonic-gate 	{ "worldwritableforwardfile",	DBS_WORLDWRITABLEFORWARDFILE	},
2337c478bd9Sstevel@tonic-gate 	{ "worldwritableincludefile",	DBS_WORLDWRITABLEINCLUDEFILE	},
2347c478bd9Sstevel@tonic-gate 	{ "groupreadablekeyfile",	DBS_GROUPREADABLEKEYFILE	},
2357c478bd9Sstevel@tonic-gate #if _FFR_GROUPREADABLEAUTHINFOFILE
2367c478bd9Sstevel@tonic-gate 	{ "groupreadableadefaultauthinfofile",
2377c478bd9Sstevel@tonic-gate 					DBS_GROUPREADABLEAUTHINFOFILE	},
2387c478bd9Sstevel@tonic-gate #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
2397c478bd9Sstevel@tonic-gate 	{ NULL,				0				}
2407c478bd9Sstevel@tonic-gate };
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate /*
2437c478bd9Sstevel@tonic-gate **  Miscellaneous stuff.
2447c478bd9Sstevel@tonic-gate */
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
2477c478bd9Sstevel@tonic-gate /*
2487c478bd9Sstevel@tonic-gate **  SETDEFAULTS -- set default values
2497c478bd9Sstevel@tonic-gate **
2507c478bd9Sstevel@tonic-gate **	Some of these must be initialized using direct code since they
2517c478bd9Sstevel@tonic-gate **	depend on run-time values. So let's do all of them this way.
2527c478bd9Sstevel@tonic-gate **
2537c478bd9Sstevel@tonic-gate **	Parameters:
2547c478bd9Sstevel@tonic-gate **		e -- the default envelope.
2557c478bd9Sstevel@tonic-gate **
2567c478bd9Sstevel@tonic-gate **	Returns:
2577c478bd9Sstevel@tonic-gate **		none.
2587c478bd9Sstevel@tonic-gate **
2597c478bd9Sstevel@tonic-gate **	Side Effects:
2607c478bd9Sstevel@tonic-gate **		Initializes a bunch of global variables to their
2617c478bd9Sstevel@tonic-gate **		default values.
2627c478bd9Sstevel@tonic-gate */
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate #define MINUTES		* 60
2657c478bd9Sstevel@tonic-gate #define HOURS		* 60 MINUTES
2667c478bd9Sstevel@tonic-gate #define DAYS		* 24 HOURS
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate #ifndef MAXRULERECURSION
2697c478bd9Sstevel@tonic-gate # define MAXRULERECURSION	50	/* max ruleset recursion depth */
2707c478bd9Sstevel@tonic-gate #endif /* ! MAXRULERECURSION */
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate void
2737c478bd9Sstevel@tonic-gate setdefaults(e)
2747c478bd9Sstevel@tonic-gate 	register ENVELOPE *e;
2757c478bd9Sstevel@tonic-gate {
2767c478bd9Sstevel@tonic-gate 	int i;
2777c478bd9Sstevel@tonic-gate 	int numprocs;
2787c478bd9Sstevel@tonic-gate 	struct passwd *pw;
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	numprocs = get_num_procs_online();
2817c478bd9Sstevel@tonic-gate 	SpaceSub = ' ';				/* option B */
2827c478bd9Sstevel@tonic-gate 	QueueLA = 8 * numprocs;			/* option x */
2837c478bd9Sstevel@tonic-gate 	RefuseLA = 12 * numprocs;		/* option X */
2847c478bd9Sstevel@tonic-gate 	WkRecipFact = 30000L;			/* option y */
2857c478bd9Sstevel@tonic-gate 	WkClassFact = 1800L;			/* option z */
2867c478bd9Sstevel@tonic-gate 	WkTimeFact = 90000L;			/* option Z */
2877c478bd9Sstevel@tonic-gate 	QueueFactor = WkRecipFact * 20;		/* option q */
2887c478bd9Sstevel@tonic-gate 	QueueMode = QM_NORMAL;		/* what queue items to act upon */
2897c478bd9Sstevel@tonic-gate 	FileMode = (RealUid != geteuid()) ? 0644 : 0600;
2907c478bd9Sstevel@tonic-gate 						/* option F */
2917c478bd9Sstevel@tonic-gate 	QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600;
2927c478bd9Sstevel@tonic-gate 						/* option QueueFileMode */
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) ||
2957c478bd9Sstevel@tonic-gate 	    ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) ||
2967c478bd9Sstevel@tonic-gate 	    ((pw = sm_getpwnam("daemon")) != NULL && pw->pw_uid != 0))
2977c478bd9Sstevel@tonic-gate 	{
2987c478bd9Sstevel@tonic-gate 		DefUid = pw->pw_uid;		/* option u */
2997c478bd9Sstevel@tonic-gate 		DefGid = pw->pw_gid;		/* option g */
3007c478bd9Sstevel@tonic-gate 		DefUser = newstr(pw->pw_name);
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 	else
3037c478bd9Sstevel@tonic-gate 	{
3047c478bd9Sstevel@tonic-gate 		DefUid = 1;			/* option u */
3057c478bd9Sstevel@tonic-gate 		DefGid = 1;			/* option g */
3067c478bd9Sstevel@tonic-gate 		setdefuser();
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 	TrustedUid = 0;
3097c478bd9Sstevel@tonic-gate 	if (tTd(37, 4))
3107c478bd9Sstevel@tonic-gate 		sm_dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n",
3117c478bd9Sstevel@tonic-gate 			DefUser != NULL ? DefUser : "<1:1>",
3127c478bd9Sstevel@tonic-gate 			(int) DefUid, (int) DefGid);
3137c478bd9Sstevel@tonic-gate 	CheckpointInterval = 10;		/* option C */
3147c478bd9Sstevel@tonic-gate 	MaxHopCount = 25;			/* option h */
3157c478bd9Sstevel@tonic-gate 	set_delivery_mode(SM_FORK, e);		/* option d */
3167c478bd9Sstevel@tonic-gate 	e->e_errormode = EM_PRINT;		/* option e */
3177c478bd9Sstevel@tonic-gate 	e->e_qgrp = NOQGRP;
3187c478bd9Sstevel@tonic-gate 	e->e_qdir = NOQDIR;
3197c478bd9Sstevel@tonic-gate 	e->e_xfqgrp = NOQGRP;
3207c478bd9Sstevel@tonic-gate 	e->e_xfqdir = NOQDIR;
3217c478bd9Sstevel@tonic-gate 	e->e_ctime = curtime();
3227c478bd9Sstevel@tonic-gate 	SevenBitInput = false;			/* option 7 */
3237c478bd9Sstevel@tonic-gate 	MaxMciCache = 1;			/* option k */
3247c478bd9Sstevel@tonic-gate 	MciCacheTimeout = 5 MINUTES;		/* option K */
3257c478bd9Sstevel@tonic-gate 	LogLevel = 9;				/* option L */
3267c478bd9Sstevel@tonic-gate #if MILTER
3277c478bd9Sstevel@tonic-gate 	MilterLogLevel = -1;
3287c478bd9Sstevel@tonic-gate #endif /* MILTER */
3297c478bd9Sstevel@tonic-gate 	inittimeouts(NULL, false);		/* option r */
3307c478bd9Sstevel@tonic-gate 	PrivacyFlags = PRIV_PUBLIC;		/* option p */
3317c478bd9Sstevel@tonic-gate 	MeToo = true;				/* option m */
3327c478bd9Sstevel@tonic-gate 	SendMIMEErrors = true;			/* option f */
3337c478bd9Sstevel@tonic-gate 	SuperSafe = SAFE_REALLY;		/* option s */
3347c478bd9Sstevel@tonic-gate 	clrbitmap(DontBlameSendmail);		/* DontBlameSendmail option */
3357c478bd9Sstevel@tonic-gate #if MIME8TO7
3367c478bd9Sstevel@tonic-gate 	MimeMode = MM_CVTMIME|MM_PASS8BIT;	/* option 8 */
3377c478bd9Sstevel@tonic-gate #else /* MIME8TO7 */
3387c478bd9Sstevel@tonic-gate 	MimeMode = MM_PASS8BIT;
3397c478bd9Sstevel@tonic-gate #endif /* MIME8TO7 */
3407c478bd9Sstevel@tonic-gate 	for (i = 0; i < MAXTOCLASS; i++)
3417c478bd9Sstevel@tonic-gate 	{
3427c478bd9Sstevel@tonic-gate 		TimeOuts.to_q_return[i] = 5 DAYS;	/* option T */
3437c478bd9Sstevel@tonic-gate 		TimeOuts.to_q_warning[i] = 0;		/* option T */
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate 	ServiceSwitchFile = "/etc/mail/service.switch";
3467c478bd9Sstevel@tonic-gate 	ServiceCacheMaxAge = (time_t) 10;
3477c478bd9Sstevel@tonic-gate 	HostsFile = _PATH_HOSTS;
3487c478bd9Sstevel@tonic-gate 	PidFile = newstr(_PATH_SENDMAILPID);
3497c478bd9Sstevel@tonic-gate 	MustQuoteChars = "@,;:\\()[].'";
3507c478bd9Sstevel@tonic-gate 	MciInfoTimeout = 30 MINUTES;
3517c478bd9Sstevel@tonic-gate 	MaxRuleRecursion = MAXRULERECURSION;
3527c478bd9Sstevel@tonic-gate 	MaxAliasRecursion = 10;
3537c478bd9Sstevel@tonic-gate 	MaxMacroRecursion = 10;
3547c478bd9Sstevel@tonic-gate 	ColonOkInAddr = true;
3557c478bd9Sstevel@tonic-gate 	DontLockReadFiles = true;
3567c478bd9Sstevel@tonic-gate 	DontProbeInterfaces = DPI_PROBEALL;
3577c478bd9Sstevel@tonic-gate 	DoubleBounceAddr = "postmaster";
3587c478bd9Sstevel@tonic-gate 	MaxHeadersLength = MAXHDRSLEN;
3597c478bd9Sstevel@tonic-gate 	MaxMimeHeaderLength = MAXLINE;
3607c478bd9Sstevel@tonic-gate 	MaxMimeFieldLength = MaxMimeHeaderLength / 2;
3617c478bd9Sstevel@tonic-gate 	MaxForwardEntries = 0;
3627c478bd9Sstevel@tonic-gate 	FastSplit = 1;
363445f2479Sjbeck 	MaxNOOPCommands = MAXNOOPCOMMANDS;
3647c478bd9Sstevel@tonic-gate #if SASL
3657c478bd9Sstevel@tonic-gate 	AuthMechanisms = newstr(AUTH_MECHANISMS);
3667c478bd9Sstevel@tonic-gate 	AuthRealm = NULL;
3677c478bd9Sstevel@tonic-gate 	MaxSLBits = INT_MAX;
3687c478bd9Sstevel@tonic-gate #endif /* SASL */
3697c478bd9Sstevel@tonic-gate #if STARTTLS
3707c478bd9Sstevel@tonic-gate 	TLS_Srv_Opts = TLS_I_SRV;
3717c478bd9Sstevel@tonic-gate #endif /* STARTTLS */
3727c478bd9Sstevel@tonic-gate #ifdef HESIOD_INIT
3737c478bd9Sstevel@tonic-gate 	HesiodContext = NULL;
3747c478bd9Sstevel@tonic-gate #endif /* HESIOD_INIT */
3757c478bd9Sstevel@tonic-gate #if NETINET6
3767c478bd9Sstevel@tonic-gate 	/* Detect if IPv6 is available at run time */
3777c478bd9Sstevel@tonic-gate 	i = socket(AF_INET6, SOCK_STREAM, 0);
3787c478bd9Sstevel@tonic-gate 	if (i >= 0)
3797c478bd9Sstevel@tonic-gate 	{
3807c478bd9Sstevel@tonic-gate 		InetMode = AF_INET6;
3817c478bd9Sstevel@tonic-gate 		(void) close(i);
3827c478bd9Sstevel@tonic-gate 	}
3837c478bd9Sstevel@tonic-gate 	else
3847c478bd9Sstevel@tonic-gate 		InetMode = AF_INET;
3857c478bd9Sstevel@tonic-gate #else /* NETINET6 */
3867c478bd9Sstevel@tonic-gate 	InetMode = AF_INET;
3877c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
3887c478bd9Sstevel@tonic-gate 	ControlSocketName = NULL;
3897c478bd9Sstevel@tonic-gate 	memset(&ConnectOnlyTo, '\0', sizeof ConnectOnlyTo);
3907c478bd9Sstevel@tonic-gate 	DataFileBufferSize = 4096;
3917c478bd9Sstevel@tonic-gate 	XscriptFileBufferSize = 4096;
3927c478bd9Sstevel@tonic-gate 	for (i = 0; i < MAXRWSETS; i++)
3937c478bd9Sstevel@tonic-gate 		RuleSetNames[i] = NULL;
3947c478bd9Sstevel@tonic-gate #if MILTER
3957c478bd9Sstevel@tonic-gate 	InputFilters[0] = NULL;
3967c478bd9Sstevel@tonic-gate #endif /* MILTER */
3977c478bd9Sstevel@tonic-gate 	RejectLogInterval = 3 HOURS;
3987c478bd9Sstevel@tonic-gate #if REQUIRES_DIR_FSYNC
3997c478bd9Sstevel@tonic-gate 	RequiresDirfsync = true;
4007c478bd9Sstevel@tonic-gate #endif /* REQUIRES_DIR_FSYNC */
4017c478bd9Sstevel@tonic-gate 	ConnectionRateWindowSize = 60;
4027c478bd9Sstevel@tonic-gate 	setupmaps();
4037c478bd9Sstevel@tonic-gate 	setupqueues();
4047c478bd9Sstevel@tonic-gate 	setupmailers();
4057c478bd9Sstevel@tonic-gate 	setupheaders();
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate /*
4107c478bd9Sstevel@tonic-gate **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
4117c478bd9Sstevel@tonic-gate */
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate void
4147c478bd9Sstevel@tonic-gate setdefuser()
4157c478bd9Sstevel@tonic-gate {
4167c478bd9Sstevel@tonic-gate 	struct passwd *defpwent;
4177c478bd9Sstevel@tonic-gate 	static char defuserbuf[40];
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	DefUser = defuserbuf;
4207c478bd9Sstevel@tonic-gate 	defpwent = sm_getpwuid(DefUid);
4217c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(defuserbuf,
4227c478bd9Sstevel@tonic-gate 			  (defpwent == NULL || defpwent->pw_name == NULL)
4237c478bd9Sstevel@tonic-gate 			   ? "nobody" : defpwent->pw_name,
4247c478bd9Sstevel@tonic-gate 			  sizeof defuserbuf);
4257c478bd9Sstevel@tonic-gate 	if (tTd(37, 4))
4267c478bd9Sstevel@tonic-gate 		sm_dprintf("setdefuser: DefUid=%d, DefUser=%s\n",
4277c478bd9Sstevel@tonic-gate 			   (int) DefUid, DefUser);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate /*
4307c478bd9Sstevel@tonic-gate **  SETUPQUEUES -- initialize default queues
4317c478bd9Sstevel@tonic-gate **
4327c478bd9Sstevel@tonic-gate **	The mqueue QUEUE structure gets filled in after readcf() but
4337c478bd9Sstevel@tonic-gate **	we need something to point to now for the mailer setup,
4347c478bd9Sstevel@tonic-gate **	which use "mqueue" as default queue.
4357c478bd9Sstevel@tonic-gate */
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate static void
4387c478bd9Sstevel@tonic-gate setupqueues()
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate 	char buf[100];
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	MaxRunnersPerQueue = 1;
4437c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof buf);
4447c478bd9Sstevel@tonic-gate 	makequeue(buf, false);
4457c478bd9Sstevel@tonic-gate }
4467c478bd9Sstevel@tonic-gate /*
4477c478bd9Sstevel@tonic-gate **  SETUPMAILERS -- initialize default mailers
4487c478bd9Sstevel@tonic-gate */
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate static void
4517c478bd9Sstevel@tonic-gate setupmailers()
4527c478bd9Sstevel@tonic-gate {
4537c478bd9Sstevel@tonic-gate 	char buf[100];
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u",
4567c478bd9Sstevel@tonic-gate 			sizeof buf);
4577c478bd9Sstevel@tonic-gate 	makemailer(buf);
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u",
4607c478bd9Sstevel@tonic-gate 			sizeof buf);
4617c478bd9Sstevel@tonic-gate 	makemailer(buf);
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u",
4647c478bd9Sstevel@tonic-gate 			sizeof buf);
4657c478bd9Sstevel@tonic-gate 	makemailer(buf);
4667c478bd9Sstevel@tonic-gate 	initerrmailers();
4677c478bd9Sstevel@tonic-gate }
4687c478bd9Sstevel@tonic-gate /*
4697c478bd9Sstevel@tonic-gate **  SETUPMAPS -- set up map classes
4707c478bd9Sstevel@tonic-gate */
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate #define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
4737c478bd9Sstevel@tonic-gate 	{ \
4747c478bd9Sstevel@tonic-gate 		extern bool parse __P((MAP *, char *)); \
4757c478bd9Sstevel@tonic-gate 		extern bool open __P((MAP *, int)); \
4767c478bd9Sstevel@tonic-gate 		extern void close __P((MAP *)); \
4777c478bd9Sstevel@tonic-gate 		extern char *lookup __P((MAP *, char *, char **, int *)); \
4787c478bd9Sstevel@tonic-gate 		extern void store __P((MAP *, char *, char *)); \
4797c478bd9Sstevel@tonic-gate 		s = stab(name, ST_MAPCLASS, ST_ENTER); \
4807c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_cname = name; \
4817c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_ext = ext; \
4827c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_cflags = flags; \
4837c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_parse = parse; \
4847c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_open = open; \
4857c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_close = close; \
4867c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_lookup = lookup; \
4877c478bd9Sstevel@tonic-gate 		s->s_mapclass.map_store = store; \
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate static void
4917c478bd9Sstevel@tonic-gate setupmaps()
4927c478bd9Sstevel@tonic-gate {
4937c478bd9Sstevel@tonic-gate 	register STAB *s;
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate #if NEWDB
4967c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 1
4977c478bd9Sstevel@tonic-gate 	int major_v, minor_v, patch_v;
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 	(void) db_version(&major_v, &minor_v, &patch_v);
5007c478bd9Sstevel@tonic-gate 	if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR)
5017c478bd9Sstevel@tonic-gate 	{
5027c478bd9Sstevel@tonic-gate 		errno = 0;
5037c478bd9Sstevel@tonic-gate 		syserr("Berkeley DB version mismatch: compiled against %d.%d.%d, run-time linked against %d.%d.%d",
5047c478bd9Sstevel@tonic-gate 		  DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
5057c478bd9Sstevel@tonic-gate 		  major_v, minor_v, patch_v);
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 1 */
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 	MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
5107c478bd9Sstevel@tonic-gate 		map_parseargs, hash_map_open, db_map_close,
5117c478bd9Sstevel@tonic-gate 		db_map_lookup, db_map_store);
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
5147c478bd9Sstevel@tonic-gate 		map_parseargs, bt_map_open, db_map_close,
5157c478bd9Sstevel@tonic-gate 		db_map_lookup, db_map_store);
5167c478bd9Sstevel@tonic-gate #endif /* NEWDB */
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate #if NDBM
5197c478bd9Sstevel@tonic-gate 	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
5207c478bd9Sstevel@tonic-gate 		map_parseargs, ndbm_map_open, ndbm_map_close,
5217c478bd9Sstevel@tonic-gate 		ndbm_map_lookup, ndbm_map_store);
5227c478bd9Sstevel@tonic-gate #endif /* NDBM */
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate #if NIS
5257c478bd9Sstevel@tonic-gate 	MAPDEF("nis", NULL, MCF_ALIASOK,
5267c478bd9Sstevel@tonic-gate 		map_parseargs, nis_map_open, null_map_close,
5277c478bd9Sstevel@tonic-gate 		nis_map_lookup, null_map_store);
5287c478bd9Sstevel@tonic-gate #endif /* NIS */
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate #if NISPLUS
5317c478bd9Sstevel@tonic-gate 	MAPDEF("nisplus", NULL, MCF_ALIASOK,
5327c478bd9Sstevel@tonic-gate 		map_parseargs, nisplus_map_open, null_map_close,
5337c478bd9Sstevel@tonic-gate 		nisplus_map_lookup, null_map_store);
5347c478bd9Sstevel@tonic-gate #endif /* NISPLUS */
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate #if LDAPMAP
5377c478bd9Sstevel@tonic-gate 	MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST,
5387c478bd9Sstevel@tonic-gate 		ldapmap_parseargs, ldapmap_open, ldapmap_close,
5397c478bd9Sstevel@tonic-gate 		ldapmap_lookup, null_map_store);
5407c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate #if PH_MAP
5437c478bd9Sstevel@tonic-gate 	MAPDEF("ph", NULL, MCF_NOTPERSIST,
5447c478bd9Sstevel@tonic-gate 		ph_map_parseargs, ph_map_open, ph_map_close,
5457c478bd9Sstevel@tonic-gate 		ph_map_lookup, null_map_store);
5467c478bd9Sstevel@tonic-gate #endif /* PH_MAP */
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate #if MAP_NSD
5497c478bd9Sstevel@tonic-gate 	/* IRIX 6.5 nsd support */
5507c478bd9Sstevel@tonic-gate 	MAPDEF("nsd", NULL, MCF_ALIASOK,
5517c478bd9Sstevel@tonic-gate 	       map_parseargs, null_map_open, null_map_close,
5527c478bd9Sstevel@tonic-gate 	       nsd_map_lookup, null_map_store);
5537c478bd9Sstevel@tonic-gate #endif /* MAP_NSD */
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate #if HESIOD
5567c478bd9Sstevel@tonic-gate 	MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
5577c478bd9Sstevel@tonic-gate 		map_parseargs, hes_map_open, hes_map_close,
5587c478bd9Sstevel@tonic-gate 		hes_map_lookup, null_map_store);
5597c478bd9Sstevel@tonic-gate #endif /* HESIOD */
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate #if NETINFO
5627c478bd9Sstevel@tonic-gate 	MAPDEF("netinfo", NULL, MCF_ALIASOK,
5637c478bd9Sstevel@tonic-gate 		map_parseargs, ni_map_open, null_map_close,
5647c478bd9Sstevel@tonic-gate 		ni_map_lookup, null_map_store);
5657c478bd9Sstevel@tonic-gate #endif /* NETINFO */
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate #if 0
5687c478bd9Sstevel@tonic-gate 	MAPDEF("dns", NULL, 0,
5697c478bd9Sstevel@tonic-gate 		dns_map_init, null_map_open, null_map_close,
5707c478bd9Sstevel@tonic-gate 		dns_map_lookup, null_map_store);
5717c478bd9Sstevel@tonic-gate #endif /* 0 */
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate #if NAMED_BIND
5747c478bd9Sstevel@tonic-gate # if DNSMAP
5757c478bd9Sstevel@tonic-gate #  if _FFR_DNSMAP_ALIASABLE
5767c478bd9Sstevel@tonic-gate 	MAPDEF("dns", NULL, MCF_ALIASOK,
5777c478bd9Sstevel@tonic-gate 	       dns_map_parseargs, dns_map_open, null_map_close,
5787c478bd9Sstevel@tonic-gate 	       dns_map_lookup, null_map_store);
5797c478bd9Sstevel@tonic-gate #  else /* _FFR_DNSMAP_ALIASABLE */
5807c478bd9Sstevel@tonic-gate 	MAPDEF("dns", NULL, 0,
5817c478bd9Sstevel@tonic-gate 	       dns_map_parseargs, dns_map_open, null_map_close,
5827c478bd9Sstevel@tonic-gate 	       dns_map_lookup, null_map_store);
5837c478bd9Sstevel@tonic-gate #  endif /* _FFR_DNSMAP_ALIASABLE */
5847c478bd9Sstevel@tonic-gate # endif /* DNSMAP */
5857c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate #if NAMED_BIND
5887c478bd9Sstevel@tonic-gate 	/* best MX DNS lookup */
5897c478bd9Sstevel@tonic-gate 	MAPDEF("bestmx", NULL, MCF_OPTFILE,
5907c478bd9Sstevel@tonic-gate 		map_parseargs, null_map_open, null_map_close,
5917c478bd9Sstevel@tonic-gate 		bestmx_map_lookup, null_map_store);
5927c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	MAPDEF("host", NULL, 0,
5957c478bd9Sstevel@tonic-gate 		host_map_init, null_map_open, null_map_close,
5967c478bd9Sstevel@tonic-gate 		host_map_lookup, null_map_store);
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 	MAPDEF("text", NULL, MCF_ALIASOK,
5997c478bd9Sstevel@tonic-gate 		map_parseargs, text_map_open, null_map_close,
6007c478bd9Sstevel@tonic-gate 		text_map_lookup, null_map_store);
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
6037c478bd9Sstevel@tonic-gate 		map_parseargs, stab_map_open, null_map_close,
6047c478bd9Sstevel@tonic-gate 		stab_map_lookup, stab_map_store);
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
6077c478bd9Sstevel@tonic-gate 		map_parseargs, impl_map_open, impl_map_close,
6087c478bd9Sstevel@tonic-gate 		impl_map_lookup, impl_map_store);
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	/* access to system passwd file */
6117c478bd9Sstevel@tonic-gate 	MAPDEF("user", NULL, MCF_OPTFILE,
6127c478bd9Sstevel@tonic-gate 		map_parseargs, user_map_open, null_map_close,
6137c478bd9Sstevel@tonic-gate 		user_map_lookup, null_map_store);
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	/* dequote map */
6167c478bd9Sstevel@tonic-gate 	MAPDEF("dequote", NULL, 0,
6177c478bd9Sstevel@tonic-gate 		dequote_init, null_map_open, null_map_close,
6187c478bd9Sstevel@tonic-gate 		dequote_map, null_map_store);
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate #if MAP_REGEX
6217c478bd9Sstevel@tonic-gate 	MAPDEF("regex", NULL, 0,
6227c478bd9Sstevel@tonic-gate 		regex_map_init, null_map_open, null_map_close,
6237c478bd9Sstevel@tonic-gate 		regex_map_lookup, null_map_store);
6247c478bd9Sstevel@tonic-gate #endif /* MAP_REGEX */
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate #if USERDB
6277c478bd9Sstevel@tonic-gate 	/* user database */
6287c478bd9Sstevel@tonic-gate 	MAPDEF("userdb", ".db", 0,
6297c478bd9Sstevel@tonic-gate 		map_parseargs, null_map_open, null_map_close,
6307c478bd9Sstevel@tonic-gate 		udb_map_lookup, null_map_store);
6317c478bd9Sstevel@tonic-gate #endif /* USERDB */
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	/* arbitrary programs */
6347c478bd9Sstevel@tonic-gate 	MAPDEF("program", NULL, MCF_ALIASOK,
6357c478bd9Sstevel@tonic-gate 		map_parseargs, null_map_open, null_map_close,
6367c478bd9Sstevel@tonic-gate 		prog_map_lookup, null_map_store);
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 	/* sequenced maps */
6397c478bd9Sstevel@tonic-gate 	MAPDEF("sequence", NULL, MCF_ALIASOK,
6407c478bd9Sstevel@tonic-gate 		seq_map_parse, null_map_open, null_map_close,
6417c478bd9Sstevel@tonic-gate 		seq_map_lookup, seq_map_store);
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	/* switched interface to sequenced maps */
6447c478bd9Sstevel@tonic-gate 	MAPDEF("switch", NULL, MCF_ALIASOK,
6457c478bd9Sstevel@tonic-gate 		map_parseargs, switch_map_open, null_map_close,
6467c478bd9Sstevel@tonic-gate 		seq_map_lookup, seq_map_store);
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	/* null map lookup -- really for internal use only */
6497c478bd9Sstevel@tonic-gate 	MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
6507c478bd9Sstevel@tonic-gate 		map_parseargs, null_map_open, null_map_close,
6517c478bd9Sstevel@tonic-gate 		null_map_lookup, null_map_store);
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	/* syslog map -- logs information to syslog */
6547c478bd9Sstevel@tonic-gate 	MAPDEF("syslog", NULL, 0,
6557c478bd9Sstevel@tonic-gate 		syslog_map_parseargs, null_map_open, null_map_close,
6567c478bd9Sstevel@tonic-gate 		syslog_map_lookup, null_map_store);
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	/* macro storage map -- rulesets can set macros */
6597c478bd9Sstevel@tonic-gate 	MAPDEF("macro", NULL, 0,
6607c478bd9Sstevel@tonic-gate 		dequote_init, null_map_open, null_map_close,
6617c478bd9Sstevel@tonic-gate 		macro_map_lookup, null_map_store);
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	/* arithmetic map -- add/subtract/compare */
6647c478bd9Sstevel@tonic-gate 	MAPDEF("arith", NULL, 0,
6657c478bd9Sstevel@tonic-gate 		dequote_init, null_map_open, null_map_close,
6667c478bd9Sstevel@tonic-gate 		arith_map_lookup, null_map_store);
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate #if SOCKETMAP
6697c478bd9Sstevel@tonic-gate 	/* arbitrary daemons */
6707c478bd9Sstevel@tonic-gate 	MAPDEF("socket", NULL, MCF_ALIASOK,
6717c478bd9Sstevel@tonic-gate 		map_parseargs, socket_map_open, socket_map_close,
6727c478bd9Sstevel@tonic-gate 		socket_map_lookup, null_map_store);
6737c478bd9Sstevel@tonic-gate #endif /* SOCKETMAP */
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	if (tTd(38, 2))
6767c478bd9Sstevel@tonic-gate 	{
6777c478bd9Sstevel@tonic-gate 		/* bogus map -- always return tempfail */
6787c478bd9Sstevel@tonic-gate 		MAPDEF("bogus",	NULL, MCF_ALIASOK|MCF_OPTFILE,
6797c478bd9Sstevel@tonic-gate 		       map_parseargs, null_map_open, null_map_close,
6807c478bd9Sstevel@tonic-gate 		       bogus_map_lookup, null_map_store);
6817c478bd9Sstevel@tonic-gate 	}
6827c478bd9Sstevel@tonic-gate }
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate #undef MAPDEF
6857c478bd9Sstevel@tonic-gate /*
6867c478bd9Sstevel@tonic-gate **  INITHOSTMAPS -- initial host-dependent maps
6877c478bd9Sstevel@tonic-gate **
6887c478bd9Sstevel@tonic-gate **	This should act as an interface to any local service switch
6897c478bd9Sstevel@tonic-gate **	provided by the host operating system.
6907c478bd9Sstevel@tonic-gate **
6917c478bd9Sstevel@tonic-gate **	Parameters:
6927c478bd9Sstevel@tonic-gate **		none
6937c478bd9Sstevel@tonic-gate **
6947c478bd9Sstevel@tonic-gate **	Returns:
6957c478bd9Sstevel@tonic-gate **		none
6967c478bd9Sstevel@tonic-gate **
6977c478bd9Sstevel@tonic-gate **	Side Effects:
6987c478bd9Sstevel@tonic-gate **		Should define maps "host" and "users" as necessary
6997c478bd9Sstevel@tonic-gate **		for this OS.  If they are not defined, they will get
7007c478bd9Sstevel@tonic-gate **		a default value later.  It should check to make sure
7017c478bd9Sstevel@tonic-gate **		they are not defined first, since it's possible that
7027c478bd9Sstevel@tonic-gate **		the config file has provided an override.
7037c478bd9Sstevel@tonic-gate */
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate void
7067c478bd9Sstevel@tonic-gate inithostmaps()
7077c478bd9Sstevel@tonic-gate {
7087c478bd9Sstevel@tonic-gate 	register int i;
7097c478bd9Sstevel@tonic-gate 	int nmaps;
7107c478bd9Sstevel@tonic-gate 	char *maptype[MAXMAPSTACK];
7117c478bd9Sstevel@tonic-gate 	short mapreturn[MAXMAPACTIONS];
7127c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 	/*
7157c478bd9Sstevel@tonic-gate 	**  Set up default hosts maps.
7167c478bd9Sstevel@tonic-gate 	*/
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate #if 0
7197c478bd9Sstevel@tonic-gate 	nmaps = switch_map_find("hosts", maptype, mapreturn);
7207c478bd9Sstevel@tonic-gate 	for (i = 0; i < nmaps; i++)
7217c478bd9Sstevel@tonic-gate 	{
7227c478bd9Sstevel@tonic-gate 		if (strcmp(maptype[i], "files") == 0 &&
7237c478bd9Sstevel@tonic-gate 		    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
7247c478bd9Sstevel@tonic-gate 		{
7257c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts",
7267c478bd9Sstevel@tonic-gate 				sizeof buf);
7277c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7287c478bd9Sstevel@tonic-gate 		}
7297c478bd9Sstevel@tonic-gate # if NAMED_BIND
7307c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "dns") == 0 &&
7317c478bd9Sstevel@tonic-gate 			 stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
7327c478bd9Sstevel@tonic-gate 		{
7337c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "hosts.dns dns A", sizeof buf);
7347c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7357c478bd9Sstevel@tonic-gate 		}
7367c478bd9Sstevel@tonic-gate # endif /* NAMED_BIND */
7377c478bd9Sstevel@tonic-gate # if NISPLUS
7387c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nisplus") == 0 &&
7397c478bd9Sstevel@tonic-gate 			 stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
7407c478bd9Sstevel@tonic-gate 		{
7417c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir",
7427c478bd9Sstevel@tonic-gate 				sizeof buf);
7437c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7447c478bd9Sstevel@tonic-gate 		}
7457c478bd9Sstevel@tonic-gate # endif /* NISPLUS */
7467c478bd9Sstevel@tonic-gate # if NIS
7477c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nis") == 0 &&
7487c478bd9Sstevel@tonic-gate 			 stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
7497c478bd9Sstevel@tonic-gate 		{
7507c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname",
7517c478bd9Sstevel@tonic-gate 				sizeof buf);
7527c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7537c478bd9Sstevel@tonic-gate 		}
7547c478bd9Sstevel@tonic-gate # endif /* NIS */
7557c478bd9Sstevel@tonic-gate # if NETINFO
7567c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "netinfo") == 0 &&
7577c478bd9Sstevel@tonic-gate 			 stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
7587c478bd9Sstevel@tonic-gate 		{
7597c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "hosts.netinfo netinfo -v name /machines",
7607c478bd9Sstevel@tonic-gate 				sizeof buf);
7617c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7627c478bd9Sstevel@tonic-gate 		}
7637c478bd9Sstevel@tonic-gate # endif /* NETINFO */
7647c478bd9Sstevel@tonic-gate 	}
7657c478bd9Sstevel@tonic-gate #endif /* 0 */
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	/*
7687c478bd9Sstevel@tonic-gate 	**  Make sure we have a host map.
7697c478bd9Sstevel@tonic-gate 	*/
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	if (stab("host", ST_MAP, ST_FIND) == NULL)
7727c478bd9Sstevel@tonic-gate 	{
7737c478bd9Sstevel@tonic-gate 		/* user didn't initialize: set up host map */
7747c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(buf, "host host", sizeof buf);
7757c478bd9Sstevel@tonic-gate #if NAMED_BIND
7767c478bd9Sstevel@tonic-gate 		if (ConfigLevel >= 2)
7777c478bd9Sstevel@tonic-gate 			(void) sm_strlcat(buf, " -a. -D", sizeof buf);
7787c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
7797c478bd9Sstevel@tonic-gate 		(void) makemapentry(buf);
7807c478bd9Sstevel@tonic-gate 	}
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 	/*
7837c478bd9Sstevel@tonic-gate 	**  Set up default aliases maps
7847c478bd9Sstevel@tonic-gate 	*/
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate 	nmaps = switch_map_find("aliases", maptype, mapreturn);
7877c478bd9Sstevel@tonic-gate 	for (i = 0; i < nmaps; i++)
7887c478bd9Sstevel@tonic-gate 	{
7897c478bd9Sstevel@tonic-gate 		if (strcmp(maptype[i], "files") == 0 &&
7907c478bd9Sstevel@tonic-gate 		    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
7917c478bd9Sstevel@tonic-gate 		{
7927c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "aliases.files null",
7937c478bd9Sstevel@tonic-gate 					  sizeof buf);
7947c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
7957c478bd9Sstevel@tonic-gate 		}
7967c478bd9Sstevel@tonic-gate #if NISPLUS
7977c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nisplus") == 0 &&
7987c478bd9Sstevel@tonic-gate 			 stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
7997c478bd9Sstevel@tonic-gate 		{
8007c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
8017c478bd9Sstevel@tonic-gate 				sizeof buf);
8027c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8037c478bd9Sstevel@tonic-gate 		}
8047c478bd9Sstevel@tonic-gate #endif /* NISPLUS */
8057c478bd9Sstevel@tonic-gate #if NIS
8067c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nis") == 0 &&
8077c478bd9Sstevel@tonic-gate 			 stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
8087c478bd9Sstevel@tonic-gate 		{
8097c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "aliases.nis nis mail.aliases",
8107c478bd9Sstevel@tonic-gate 				sizeof buf);
8117c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8127c478bd9Sstevel@tonic-gate 		}
8137c478bd9Sstevel@tonic-gate #endif /* NIS */
8147c478bd9Sstevel@tonic-gate #if NETINFO
8157c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "netinfo") == 0 &&
8167c478bd9Sstevel@tonic-gate 			 stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
8177c478bd9Sstevel@tonic-gate 		{
8187c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
8197c478bd9Sstevel@tonic-gate 				sizeof buf);
8207c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8217c478bd9Sstevel@tonic-gate 		}
8227c478bd9Sstevel@tonic-gate #endif /* NETINFO */
8237c478bd9Sstevel@tonic-gate #if HESIOD
8247c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "hesiod") == 0 &&
8257c478bd9Sstevel@tonic-gate 			 stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
8267c478bd9Sstevel@tonic-gate 		{
8277c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases",
8287c478bd9Sstevel@tonic-gate 				sizeof buf);
8297c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8307c478bd9Sstevel@tonic-gate 		}
8317c478bd9Sstevel@tonic-gate #endif /* HESIOD */
832*d25d47eeSjbeck #if LDAPMAP && defined(SUN_EXTENSIONS) && \
833*d25d47eeSjbeck     defined(SUN_SIMPLIFIED_LDAP) && HASLDAPGETALIASBYNAME
8347c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "ldap") == 0 &&
8357c478bd9Sstevel@tonic-gate 		    stab("aliases.ldap", ST_MAP, ST_FIND) == NULL)
8367c478bd9Sstevel@tonic-gate 		{
8377c478bd9Sstevel@tonic-gate 			(void) strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup",
8387c478bd9Sstevel@tonic-gate 				sizeof buf);
8397c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8407c478bd9Sstevel@tonic-gate 		}
841*d25d47eeSjbeck #endif /* LDAPMAP && defined(SUN_EXTENSIONS) && ... */
8427c478bd9Sstevel@tonic-gate 	}
8437c478bd9Sstevel@tonic-gate 	if (stab("aliases", ST_MAP, ST_FIND) == NULL)
8447c478bd9Sstevel@tonic-gate 	{
8457c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(buf, "aliases switch aliases", sizeof buf);
8467c478bd9Sstevel@tonic-gate 		(void) makemapentry(buf);
8477c478bd9Sstevel@tonic-gate 	}
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate #if 0		/* "user" map class is a better choice */
8507c478bd9Sstevel@tonic-gate 	/*
8517c478bd9Sstevel@tonic-gate 	**  Set up default users maps.
8527c478bd9Sstevel@tonic-gate 	*/
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	nmaps = switch_map_find("passwd", maptype, mapreturn);
8557c478bd9Sstevel@tonic-gate 	for (i = 0; i < nmaps; i++)
8567c478bd9Sstevel@tonic-gate 	{
8577c478bd9Sstevel@tonic-gate 		if (strcmp(maptype[i], "files") == 0 &&
8587c478bd9Sstevel@tonic-gate 		    stab("users.files", ST_MAP, ST_FIND) == NULL)
8597c478bd9Sstevel@tonic-gate 		{
8607c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd",
8617c478bd9Sstevel@tonic-gate 				sizeof buf);
8627c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8637c478bd9Sstevel@tonic-gate 		}
8647c478bd9Sstevel@tonic-gate # if NISPLUS
8657c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nisplus") == 0 &&
8667c478bd9Sstevel@tonic-gate 		    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
8677c478bd9Sstevel@tonic-gate 		{
8687c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir",
8697c478bd9Sstevel@tonic-gate 				sizeof buf);
8707c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8717c478bd9Sstevel@tonic-gate 		}
8727c478bd9Sstevel@tonic-gate # endif /* NISPLUS */
8737c478bd9Sstevel@tonic-gate # if NIS
8747c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "nis") == 0 &&
8757c478bd9Sstevel@tonic-gate 		    stab("users.nis", ST_MAP, ST_FIND) == NULL)
8767c478bd9Sstevel@tonic-gate 		{
8777c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "users.nis nis -m passwd.byname",
8787c478bd9Sstevel@tonic-gate 				sizeof buf);
8797c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8807c478bd9Sstevel@tonic-gate 		}
8817c478bd9Sstevel@tonic-gate # endif /* NIS */
8827c478bd9Sstevel@tonic-gate # if HESIOD
8837c478bd9Sstevel@tonic-gate 		else if (strcmp(maptype[i], "hesiod") == 0 &&
8847c478bd9Sstevel@tonic-gate 			 stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
8857c478bd9Sstevel@tonic-gate 		{
8867c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(buf, "users.hesiod hesiod", sizeof buf);
8877c478bd9Sstevel@tonic-gate 			(void) makemapentry(buf);
8887c478bd9Sstevel@tonic-gate 		}
8897c478bd9Sstevel@tonic-gate # endif /* HESIOD */
8907c478bd9Sstevel@tonic-gate 	}
8917c478bd9Sstevel@tonic-gate 	if (stab("users", ST_MAP, ST_FIND) == NULL)
8927c478bd9Sstevel@tonic-gate 	{
8937c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(buf, "users switch -m passwd", sizeof buf);
8947c478bd9Sstevel@tonic-gate 		(void) makemapentry(buf);
8957c478bd9Sstevel@tonic-gate 	}
8967c478bd9Sstevel@tonic-gate #endif /* 0 */
8977c478bd9Sstevel@tonic-gate }
8987c478bd9Sstevel@tonic-gate /*
8997c478bd9Sstevel@tonic-gate **  SWITCH_MAP_FIND -- find the list of types associated with a map
9007c478bd9Sstevel@tonic-gate **
9017c478bd9Sstevel@tonic-gate **	This is the system-dependent interface to the service switch.
9027c478bd9Sstevel@tonic-gate **
9037c478bd9Sstevel@tonic-gate **	Parameters:
9047c478bd9Sstevel@tonic-gate **		service -- the name of the service of interest.
9057c478bd9Sstevel@tonic-gate **		maptype -- an out-array of strings containing the types
9067c478bd9Sstevel@tonic-gate **			of access to use for this service.  There can
9077c478bd9Sstevel@tonic-gate **			be at most MAXMAPSTACK types for a single service.
9087c478bd9Sstevel@tonic-gate **		mapreturn -- an out-array of return information bitmaps
9097c478bd9Sstevel@tonic-gate **			for the map.
9107c478bd9Sstevel@tonic-gate **
9117c478bd9Sstevel@tonic-gate **	Returns:
9127c478bd9Sstevel@tonic-gate **		The number of map types filled in, or -1 for failure.
9137c478bd9Sstevel@tonic-gate **
9147c478bd9Sstevel@tonic-gate **	Side effects:
9157c478bd9Sstevel@tonic-gate **		Preserves errno so nothing in the routine clobbers it.
9167c478bd9Sstevel@tonic-gate */
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate #if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
9197c478bd9Sstevel@tonic-gate # define _USE_SUN_NSSWITCH_
9207c478bd9Sstevel@tonic-gate #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate #if _FFR_HPUX_NSSWITCH
9237c478bd9Sstevel@tonic-gate # ifdef __hpux
9247c478bd9Sstevel@tonic-gate #  define _USE_SUN_NSSWITCH_
9257c478bd9Sstevel@tonic-gate # endif /* __hpux */
9267c478bd9Sstevel@tonic-gate #endif /* _FFR_HPUX_NSSWITCH */
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate #ifdef _USE_SUN_NSSWITCH_
9297c478bd9Sstevel@tonic-gate # include <nsswitch.h>
9307c478bd9Sstevel@tonic-gate #endif /* _USE_SUN_NSSWITCH_ */
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
9337c478bd9Sstevel@tonic-gate # define _USE_DEC_SVC_CONF_
9347c478bd9Sstevel@tonic-gate #endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate #ifdef _USE_DEC_SVC_CONF_
9377c478bd9Sstevel@tonic-gate # include <sys/svcinfo.h>
9387c478bd9Sstevel@tonic-gate #endif /* _USE_DEC_SVC_CONF_ */
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate int
9417c478bd9Sstevel@tonic-gate switch_map_find(service, maptype, mapreturn)
9427c478bd9Sstevel@tonic-gate 	char *service;
9437c478bd9Sstevel@tonic-gate 	char *maptype[MAXMAPSTACK];
9447c478bd9Sstevel@tonic-gate 	short mapreturn[MAXMAPACTIONS];
9457c478bd9Sstevel@tonic-gate {
9467c478bd9Sstevel@tonic-gate 	int svcno = 0;
9477c478bd9Sstevel@tonic-gate 	int save_errno = errno;
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate #ifdef _USE_SUN_NSSWITCH_
9507c478bd9Sstevel@tonic-gate 	struct __nsw_switchconfig *nsw_conf;
9517c478bd9Sstevel@tonic-gate 	enum __nsw_parse_err pserr;
9527c478bd9Sstevel@tonic-gate 	struct __nsw_lookup *lk;
9537c478bd9Sstevel@tonic-gate 	static struct __nsw_lookup lkp0 =
9547c478bd9Sstevel@tonic-gate 		{ "files", {1, 0, 0, 0}, NULL, NULL };
9557c478bd9Sstevel@tonic-gate 	static struct __nsw_switchconfig lkp_default =
9567c478bd9Sstevel@tonic-gate 		{ 0, "sendmail", 3, &lkp0 };
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
9597c478bd9Sstevel@tonic-gate 		mapreturn[svcno] = 0;
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
9627c478bd9Sstevel@tonic-gate 		lk = lkp_default.lookups;
9637c478bd9Sstevel@tonic-gate 	else
9647c478bd9Sstevel@tonic-gate 		lk = nsw_conf->lookups;
9657c478bd9Sstevel@tonic-gate 	svcno = 0;
9667c478bd9Sstevel@tonic-gate 	while (lk != NULL && svcno < MAXMAPSTACK)
9677c478bd9Sstevel@tonic-gate 	{
9687c478bd9Sstevel@tonic-gate 		maptype[svcno] = lk->service_name;
9697c478bd9Sstevel@tonic-gate 		if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
9707c478bd9Sstevel@tonic-gate 			mapreturn[MA_NOTFOUND] |= 1 << svcno;
9717c478bd9Sstevel@tonic-gate 		if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
9727c478bd9Sstevel@tonic-gate 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
9737c478bd9Sstevel@tonic-gate 		if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
9747c478bd9Sstevel@tonic-gate 			mapreturn[MA_TRYAGAIN] |= 1 << svcno;
9757c478bd9Sstevel@tonic-gate 		svcno++;
9767c478bd9Sstevel@tonic-gate 		lk = lk->next;
9777c478bd9Sstevel@tonic-gate 	}
9787c478bd9Sstevel@tonic-gate 	errno = save_errno;
9797c478bd9Sstevel@tonic-gate 	return svcno;
9807c478bd9Sstevel@tonic-gate #endif /* _USE_SUN_NSSWITCH_ */
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate #ifdef _USE_DEC_SVC_CONF_
9837c478bd9Sstevel@tonic-gate 	struct svcinfo *svcinfo;
9847c478bd9Sstevel@tonic-gate 	int svc;
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
9877c478bd9Sstevel@tonic-gate 		mapreturn[svcno] = 0;
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate 	svcinfo = getsvc();
9907c478bd9Sstevel@tonic-gate 	if (svcinfo == NULL)
9917c478bd9Sstevel@tonic-gate 		goto punt;
9927c478bd9Sstevel@tonic-gate 	if (strcmp(service, "hosts") == 0)
9937c478bd9Sstevel@tonic-gate 		svc = SVC_HOSTS;
9947c478bd9Sstevel@tonic-gate 	else if (strcmp(service, "aliases") == 0)
9957c478bd9Sstevel@tonic-gate 		svc = SVC_ALIASES;
9967c478bd9Sstevel@tonic-gate 	else if (strcmp(service, "passwd") == 0)
9977c478bd9Sstevel@tonic-gate 		svc = SVC_PASSWD;
9987c478bd9Sstevel@tonic-gate 	else
9997c478bd9Sstevel@tonic-gate 	{
10007c478bd9Sstevel@tonic-gate 		errno = save_errno;
10017c478bd9Sstevel@tonic-gate 		return -1;
10027c478bd9Sstevel@tonic-gate 	}
10037c478bd9Sstevel@tonic-gate 	for (svcno = 0; svcno < SVC_PATHSIZE && svcno < MAXMAPSTACK; svcno++)
10047c478bd9Sstevel@tonic-gate 	{
10057c478bd9Sstevel@tonic-gate 		switch (svcinfo->svcpath[svc][svcno])
10067c478bd9Sstevel@tonic-gate 		{
10077c478bd9Sstevel@tonic-gate 		  case SVC_LOCAL:
10087c478bd9Sstevel@tonic-gate 			maptype[svcno] = "files";
10097c478bd9Sstevel@tonic-gate 			break;
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate 		  case SVC_YP:
10127c478bd9Sstevel@tonic-gate 			maptype[svcno] = "nis";
10137c478bd9Sstevel@tonic-gate 			break;
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 		  case SVC_BIND:
10167c478bd9Sstevel@tonic-gate 			maptype[svcno] = "dns";
10177c478bd9Sstevel@tonic-gate 			break;
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate # ifdef SVC_HESIOD
10207c478bd9Sstevel@tonic-gate 		  case SVC_HESIOD:
10217c478bd9Sstevel@tonic-gate 			maptype[svcno] = "hesiod";
10227c478bd9Sstevel@tonic-gate 			break;
10237c478bd9Sstevel@tonic-gate # endif /* SVC_HESIOD */
10247c478bd9Sstevel@tonic-gate 
10257c478bd9Sstevel@tonic-gate 		  case SVC_LAST:
10267c478bd9Sstevel@tonic-gate 			errno = save_errno;
10277c478bd9Sstevel@tonic-gate 			return svcno;
10287c478bd9Sstevel@tonic-gate 		}
10297c478bd9Sstevel@tonic-gate 	}
10307c478bd9Sstevel@tonic-gate 	errno = save_errno;
10317c478bd9Sstevel@tonic-gate 	return svcno;
10327c478bd9Sstevel@tonic-gate #endif /* _USE_DEC_SVC_CONF_ */
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate #if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
10357c478bd9Sstevel@tonic-gate 	/*
10367c478bd9Sstevel@tonic-gate 	**  Fall-back mechanism.
10377c478bd9Sstevel@tonic-gate 	*/
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate 	STAB *st;
10407c478bd9Sstevel@tonic-gate 	static time_t servicecachetime;	/* time service switch was cached */
10417c478bd9Sstevel@tonic-gate 	time_t now = curtime();
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
10447c478bd9Sstevel@tonic-gate 		mapreturn[svcno] = 0;
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 	if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge)
10477c478bd9Sstevel@tonic-gate 	{
10487c478bd9Sstevel@tonic-gate 		/* (re)read service switch */
10497c478bd9Sstevel@tonic-gate 		register SM_FILE_T *fp;
10507c478bd9Sstevel@tonic-gate 		long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 		if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
10537c478bd9Sstevel@tonic-gate 			    DontBlameSendmail))
10547c478bd9Sstevel@tonic-gate 			sff |= SFF_NOWLINK;
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 		if (ConfigFileRead)
10577c478bd9Sstevel@tonic-gate 			servicecachetime = now;
10587c478bd9Sstevel@tonic-gate 		fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
10597c478bd9Sstevel@tonic-gate 		if (fp != NULL)
10607c478bd9Sstevel@tonic-gate 		{
10617c478bd9Sstevel@tonic-gate 			char buf[MAXLINE];
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 			while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf,
10647c478bd9Sstevel@tonic-gate 					   sizeof buf) != NULL)
10657c478bd9Sstevel@tonic-gate 			{
10667c478bd9Sstevel@tonic-gate 				register char *p;
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate 				p = strpbrk(buf, "#\n");
10697c478bd9Sstevel@tonic-gate 				if (p != NULL)
10707c478bd9Sstevel@tonic-gate 					*p = '\0';
10717c478bd9Sstevel@tonic-gate 				p = strpbrk(buf, " \t");
10727c478bd9Sstevel@tonic-gate 				if (p != NULL)
10737c478bd9Sstevel@tonic-gate 					*p++ = '\0';
10747c478bd9Sstevel@tonic-gate 				if (buf[0] == '\0')
10757c478bd9Sstevel@tonic-gate 					continue;
10767c478bd9Sstevel@tonic-gate 				if (p == NULL)
10777c478bd9Sstevel@tonic-gate 				{
10787c478bd9Sstevel@tonic-gate 					sm_syslog(LOG_ERR, NOQID,
10797c478bd9Sstevel@tonic-gate 						  "Bad line on %.100s: %.100s",
10807c478bd9Sstevel@tonic-gate 						  ServiceSwitchFile,
10817c478bd9Sstevel@tonic-gate 						  buf);
10827c478bd9Sstevel@tonic-gate 					continue;
10837c478bd9Sstevel@tonic-gate 				}
10847c478bd9Sstevel@tonic-gate 				while (isspace(*p))
10857c478bd9Sstevel@tonic-gate 					p++;
10867c478bd9Sstevel@tonic-gate 				if (*p == '\0')
10877c478bd9Sstevel@tonic-gate 					continue;
10887c478bd9Sstevel@tonic-gate 
10897c478bd9Sstevel@tonic-gate 				/*
10907c478bd9Sstevel@tonic-gate 				**  Find/allocate space for this service entry.
10917c478bd9Sstevel@tonic-gate 				**	Space for all of the service strings
10927c478bd9Sstevel@tonic-gate 				**	are allocated at once.  This means
10937c478bd9Sstevel@tonic-gate 				**	that we only have to free the first
10947c478bd9Sstevel@tonic-gate 				**	one to free all of them.
10957c478bd9Sstevel@tonic-gate 				*/
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate 				st = stab(buf, ST_SERVICE, ST_ENTER);
10987c478bd9Sstevel@tonic-gate 				if (st->s_service[0] != NULL)
10997c478bd9Sstevel@tonic-gate 					sm_free((void *) st->s_service[0]); /* XXX */
11007c478bd9Sstevel@tonic-gate 				p = newstr(p);
11017c478bd9Sstevel@tonic-gate 				for (svcno = 0; svcno < MAXMAPSTACK; )
11027c478bd9Sstevel@tonic-gate 				{
11037c478bd9Sstevel@tonic-gate 					if (*p == '\0')
11047c478bd9Sstevel@tonic-gate 						break;
11057c478bd9Sstevel@tonic-gate 					st->s_service[svcno++] = p;
11067c478bd9Sstevel@tonic-gate 					p = strpbrk(p, " \t");
11077c478bd9Sstevel@tonic-gate 					if (p == NULL)
11087c478bd9Sstevel@tonic-gate 						break;
11097c478bd9Sstevel@tonic-gate 					*p++ = '\0';
11107c478bd9Sstevel@tonic-gate 					while (isspace(*p))
11117c478bd9Sstevel@tonic-gate 						p++;
11127c478bd9Sstevel@tonic-gate 				}
11137c478bd9Sstevel@tonic-gate 				if (svcno < MAXMAPSTACK)
11147c478bd9Sstevel@tonic-gate 					st->s_service[svcno] = NULL;
11157c478bd9Sstevel@tonic-gate 			}
11167c478bd9Sstevel@tonic-gate 			(void) sm_io_close(fp, SM_TIME_DEFAULT);
11177c478bd9Sstevel@tonic-gate 		}
11187c478bd9Sstevel@tonic-gate 	}
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate 	/* look up entry in cache */
11217c478bd9Sstevel@tonic-gate 	st = stab(service, ST_SERVICE, ST_FIND);
11227c478bd9Sstevel@tonic-gate 	if (st != NULL && st->s_service[0] != NULL)
11237c478bd9Sstevel@tonic-gate 	{
11247c478bd9Sstevel@tonic-gate 		/* extract data */
11257c478bd9Sstevel@tonic-gate 		svcno = 0;
11267c478bd9Sstevel@tonic-gate 		while (svcno < MAXMAPSTACK)
11277c478bd9Sstevel@tonic-gate 		{
11287c478bd9Sstevel@tonic-gate 			maptype[svcno] = st->s_service[svcno];
11297c478bd9Sstevel@tonic-gate 			if (maptype[svcno++] == NULL)
11307c478bd9Sstevel@tonic-gate 				break;
11317c478bd9Sstevel@tonic-gate 		}
11327c478bd9Sstevel@tonic-gate 		errno = save_errno;
11337c478bd9Sstevel@tonic-gate 		return --svcno;
11347c478bd9Sstevel@tonic-gate 	}
11357c478bd9Sstevel@tonic-gate #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate #if !defined(_USE_SUN_NSSWITCH_)
11387c478bd9Sstevel@tonic-gate 	/* if the service file doesn't work, use an absolute fallback */
11397c478bd9Sstevel@tonic-gate # ifdef _USE_DEC_SVC_CONF_
11407c478bd9Sstevel@tonic-gate   punt:
11417c478bd9Sstevel@tonic-gate # endif /* _USE_DEC_SVC_CONF_ */
11427c478bd9Sstevel@tonic-gate 	for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
11437c478bd9Sstevel@tonic-gate 		mapreturn[svcno] = 0;
11447c478bd9Sstevel@tonic-gate 	svcno = 0;
11457c478bd9Sstevel@tonic-gate 	if (strcmp(service, "aliases") == 0)
11467c478bd9Sstevel@tonic-gate 	{
11477c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "files";
11487c478bd9Sstevel@tonic-gate # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
11497c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "netinfo";
11507c478bd9Sstevel@tonic-gate # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
11517c478bd9Sstevel@tonic-gate # ifdef AUTO_NIS_ALIASES
11527c478bd9Sstevel@tonic-gate #  if NISPLUS
11537c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "nisplus";
11547c478bd9Sstevel@tonic-gate #  endif /* NISPLUS */
11557c478bd9Sstevel@tonic-gate #  if NIS
11567c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "nis";
11577c478bd9Sstevel@tonic-gate #  endif /* NIS */
11587c478bd9Sstevel@tonic-gate # endif /* AUTO_NIS_ALIASES */
11597c478bd9Sstevel@tonic-gate 		errno = save_errno;
11607c478bd9Sstevel@tonic-gate 		return svcno;
11617c478bd9Sstevel@tonic-gate 	}
11627c478bd9Sstevel@tonic-gate 	if (strcmp(service, "hosts") == 0)
11637c478bd9Sstevel@tonic-gate 	{
11647c478bd9Sstevel@tonic-gate # if NAMED_BIND
11657c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "dns";
11667c478bd9Sstevel@tonic-gate # else /* NAMED_BIND */
11677c478bd9Sstevel@tonic-gate #  if defined(sun) && !defined(BSD)
11687c478bd9Sstevel@tonic-gate 		/* SunOS */
11697c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "nis";
11707c478bd9Sstevel@tonic-gate #  endif /* defined(sun) && !defined(BSD) */
11717c478bd9Sstevel@tonic-gate # endif /* NAMED_BIND */
11727c478bd9Sstevel@tonic-gate # if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
11737c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "netinfo";
11747c478bd9Sstevel@tonic-gate # endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */
11757c478bd9Sstevel@tonic-gate 		maptype[svcno++] = "files";
11767c478bd9Sstevel@tonic-gate 		errno = save_errno;
11777c478bd9Sstevel@tonic-gate 		return svcno;
11787c478bd9Sstevel@tonic-gate 	}
11797c478bd9Sstevel@tonic-gate 	errno = save_errno;
11807c478bd9Sstevel@tonic-gate 	return -1;
11817c478bd9Sstevel@tonic-gate #endif /* !defined(_USE_SUN_NSSWITCH_) */
11827c478bd9Sstevel@tonic-gate }
11837c478bd9Sstevel@tonic-gate /*
11847c478bd9Sstevel@tonic-gate **  USERNAME -- return the user id of the logged in user.
11857c478bd9Sstevel@tonic-gate **
11867c478bd9Sstevel@tonic-gate **	Parameters:
11877c478bd9Sstevel@tonic-gate **		none.
11887c478bd9Sstevel@tonic-gate **
11897c478bd9Sstevel@tonic-gate **	Returns:
11907c478bd9Sstevel@tonic-gate **		The login name of the logged in user.
11917c478bd9Sstevel@tonic-gate **
11927c478bd9Sstevel@tonic-gate **	Side Effects:
11937c478bd9Sstevel@tonic-gate **		none.
11947c478bd9Sstevel@tonic-gate **
11957c478bd9Sstevel@tonic-gate **	Notes:
11967c478bd9Sstevel@tonic-gate **		The return value is statically allocated.
11977c478bd9Sstevel@tonic-gate */
11987c478bd9Sstevel@tonic-gate 
11997c478bd9Sstevel@tonic-gate char *
12007c478bd9Sstevel@tonic-gate username()
12017c478bd9Sstevel@tonic-gate {
12027c478bd9Sstevel@tonic-gate 	static char *myname = NULL;
12037c478bd9Sstevel@tonic-gate 	extern char *getlogin();
12047c478bd9Sstevel@tonic-gate 	register struct passwd *pw;
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	/* cache the result */
12077c478bd9Sstevel@tonic-gate 	if (myname == NULL)
12087c478bd9Sstevel@tonic-gate 	{
12097c478bd9Sstevel@tonic-gate 		myname = getlogin();
12107c478bd9Sstevel@tonic-gate 		if (myname == NULL || myname[0] == '\0')
12117c478bd9Sstevel@tonic-gate 		{
12127c478bd9Sstevel@tonic-gate 			pw = sm_getpwuid(RealUid);
12137c478bd9Sstevel@tonic-gate 			if (pw != NULL)
12147c478bd9Sstevel@tonic-gate 				myname = pw->pw_name;
12157c478bd9Sstevel@tonic-gate 		}
12167c478bd9Sstevel@tonic-gate 		else
12177c478bd9Sstevel@tonic-gate 		{
12187c478bd9Sstevel@tonic-gate 			uid_t uid = RealUid;
12197c478bd9Sstevel@tonic-gate 
12207c478bd9Sstevel@tonic-gate 			if ((pw = sm_getpwnam(myname)) == NULL ||
12217c478bd9Sstevel@tonic-gate 			      (uid != 0 && uid != pw->pw_uid))
12227c478bd9Sstevel@tonic-gate 			{
12237c478bd9Sstevel@tonic-gate 				pw = sm_getpwuid(uid);
12247c478bd9Sstevel@tonic-gate 				if (pw != NULL)
12257c478bd9Sstevel@tonic-gate 					myname = pw->pw_name;
12267c478bd9Sstevel@tonic-gate 			}
12277c478bd9Sstevel@tonic-gate 		}
12287c478bd9Sstevel@tonic-gate 		if (myname == NULL || myname[0] == '\0')
12297c478bd9Sstevel@tonic-gate 		{
12307c478bd9Sstevel@tonic-gate 			syserr("554 5.3.0 Who are you?");
12317c478bd9Sstevel@tonic-gate 			myname = "postmaster";
12327c478bd9Sstevel@tonic-gate 		}
12337c478bd9Sstevel@tonic-gate 		else if (strpbrk(myname, ",;:/|\"\\") != NULL)
12347c478bd9Sstevel@tonic-gate 			myname = addquotes(myname, NULL);
12357c478bd9Sstevel@tonic-gate 		else
12367c478bd9Sstevel@tonic-gate 			myname = sm_pstrdup_x(myname);
12377c478bd9Sstevel@tonic-gate 	}
12387c478bd9Sstevel@tonic-gate 	return myname;
12397c478bd9Sstevel@tonic-gate }
12407c478bd9Sstevel@tonic-gate /*
12417c478bd9Sstevel@tonic-gate **  TTYPATH -- Get the path of the user's tty
12427c478bd9Sstevel@tonic-gate **
12437c478bd9Sstevel@tonic-gate **	Returns the pathname of the user's tty.  Returns NULL if
12447c478bd9Sstevel@tonic-gate **	the user is not logged in or if s/he has write permission
12457c478bd9Sstevel@tonic-gate **	denied.
12467c478bd9Sstevel@tonic-gate **
12477c478bd9Sstevel@tonic-gate **	Parameters:
12487c478bd9Sstevel@tonic-gate **		none
12497c478bd9Sstevel@tonic-gate **
12507c478bd9Sstevel@tonic-gate **	Returns:
12517c478bd9Sstevel@tonic-gate **		pathname of the user's tty.
12527c478bd9Sstevel@tonic-gate **		NULL if not logged in or write permission denied.
12537c478bd9Sstevel@tonic-gate **
12547c478bd9Sstevel@tonic-gate **	Side Effects:
12557c478bd9Sstevel@tonic-gate **		none.
12567c478bd9Sstevel@tonic-gate **
12577c478bd9Sstevel@tonic-gate **	WARNING:
12587c478bd9Sstevel@tonic-gate **		Return value is in a local buffer.
12597c478bd9Sstevel@tonic-gate **
12607c478bd9Sstevel@tonic-gate **	Called By:
12617c478bd9Sstevel@tonic-gate **		savemail
12627c478bd9Sstevel@tonic-gate */
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate char *
12657c478bd9Sstevel@tonic-gate ttypath()
12667c478bd9Sstevel@tonic-gate {
12677c478bd9Sstevel@tonic-gate 	struct stat stbuf;
12687c478bd9Sstevel@tonic-gate 	register char *pathn;
12697c478bd9Sstevel@tonic-gate 	extern char *ttyname();
12707c478bd9Sstevel@tonic-gate 	extern char *getlogin();
12717c478bd9Sstevel@tonic-gate 
12727c478bd9Sstevel@tonic-gate 	/* compute the pathname of the controlling tty */
12737c478bd9Sstevel@tonic-gate 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
12747c478bd9Sstevel@tonic-gate 	    (pathn = ttyname(0)) == NULL)
12757c478bd9Sstevel@tonic-gate 	{
12767c478bd9Sstevel@tonic-gate 		errno = 0;
12777c478bd9Sstevel@tonic-gate 		return NULL;
12787c478bd9Sstevel@tonic-gate 	}
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate 	/* see if we have write permission */
12817c478bd9Sstevel@tonic-gate 	if (stat(pathn, &stbuf) < 0 || !bitset(S_IWOTH, stbuf.st_mode))
12827c478bd9Sstevel@tonic-gate 	{
12837c478bd9Sstevel@tonic-gate 		errno = 0;
12847c478bd9Sstevel@tonic-gate 		return NULL;
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	/* see if the user is logged in */
12887c478bd9Sstevel@tonic-gate 	if (getlogin() == NULL)
12897c478bd9Sstevel@tonic-gate 		return NULL;
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate 	/* looks good */
12927c478bd9Sstevel@tonic-gate 	return pathn;
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate /*
12957c478bd9Sstevel@tonic-gate **  CHECKCOMPAT -- check for From and To person compatible.
12967c478bd9Sstevel@tonic-gate **
12977c478bd9Sstevel@tonic-gate **	This routine can be supplied on a per-installation basis
12987c478bd9Sstevel@tonic-gate **	to determine whether a person is allowed to send a message.
12997c478bd9Sstevel@tonic-gate **	This allows restriction of certain types of internet
13007c478bd9Sstevel@tonic-gate **	forwarding or registration of users.
13017c478bd9Sstevel@tonic-gate **
13027c478bd9Sstevel@tonic-gate **	If the hosts are found to be incompatible, an error
13037c478bd9Sstevel@tonic-gate **	message should be given using "usrerr" and an EX_ code
13047c478bd9Sstevel@tonic-gate **	should be returned.  You can also set to->q_status to
13057c478bd9Sstevel@tonic-gate **	a DSN-style status code.
13067c478bd9Sstevel@tonic-gate **
13077c478bd9Sstevel@tonic-gate **	EF_NO_BODY_RETN can be set in e->e_flags to suppress the
13087c478bd9Sstevel@tonic-gate **	body during the return-to-sender function; this should be done
13097c478bd9Sstevel@tonic-gate **	on huge messages.  This bit may already be set by the ESMTP
13107c478bd9Sstevel@tonic-gate **	protocol.
13117c478bd9Sstevel@tonic-gate **
13127c478bd9Sstevel@tonic-gate **	Parameters:
13137c478bd9Sstevel@tonic-gate **		to -- the person being sent to.
13147c478bd9Sstevel@tonic-gate **
13157c478bd9Sstevel@tonic-gate **	Returns:
13167c478bd9Sstevel@tonic-gate **		an exit status
13177c478bd9Sstevel@tonic-gate **
13187c478bd9Sstevel@tonic-gate **	Side Effects:
13197c478bd9Sstevel@tonic-gate **		none (unless you include the usrerr stuff)
13207c478bd9Sstevel@tonic-gate */
13217c478bd9Sstevel@tonic-gate 
13227c478bd9Sstevel@tonic-gate int
13237c478bd9Sstevel@tonic-gate checkcompat(to, e)
13247c478bd9Sstevel@tonic-gate 	register ADDRESS *to;
13257c478bd9Sstevel@tonic-gate 	register ENVELOPE *e;
13267c478bd9Sstevel@tonic-gate {
13277c478bd9Sstevel@tonic-gate 	if (tTd(49, 1))
13287c478bd9Sstevel@tonic-gate 		sm_dprintf("checkcompat(to=%s, from=%s)\n",
13297c478bd9Sstevel@tonic-gate 			to->q_paddr, e->e_from.q_paddr);
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate #ifdef EXAMPLE_CODE
13327c478bd9Sstevel@tonic-gate 	/* this code is intended as an example only */
13337c478bd9Sstevel@tonic-gate 	register STAB *s;
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 	s = stab("arpa", ST_MAILER, ST_FIND);
13367c478bd9Sstevel@tonic-gate 	if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
13377c478bd9Sstevel@tonic-gate 	    to->q_mailer == s->s_mailer)
13387c478bd9Sstevel@tonic-gate 	{
13397c478bd9Sstevel@tonic-gate 		usrerr("553 No ARPA mail through this machine: see your system administration");
13407c478bd9Sstevel@tonic-gate 		/* e->e_flags |= EF_NO_BODY_RETN; to suppress body on return */
13417c478bd9Sstevel@tonic-gate 		to->q_status = "5.7.1";
13427c478bd9Sstevel@tonic-gate 		return EX_UNAVAILABLE;
13437c478bd9Sstevel@tonic-gate 	}
13447c478bd9Sstevel@tonic-gate #endif /* EXAMPLE_CODE */
13457c478bd9Sstevel@tonic-gate 	return EX_OK;
13467c478bd9Sstevel@tonic-gate }
1347*d25d47eeSjbeck 
1348*d25d47eeSjbeck #ifdef SUN_EXTENSIONS
1349*d25d47eeSjbeck static void
1350*d25d47eeSjbeck init_md_sun()
1351*d25d47eeSjbeck {
1352*d25d47eeSjbeck 	struct stat sbuf;
1353*d25d47eeSjbeck 
1354*d25d47eeSjbeck 	/* Check for large file descriptor */
1355*d25d47eeSjbeck 	if (fstat(fileno(stdin), &sbuf) < 0)
1356*d25d47eeSjbeck 	{
1357*d25d47eeSjbeck 		if (errno == EOVERFLOW)
1358*d25d47eeSjbeck 		{
1359*d25d47eeSjbeck 			perror("stdin");
1360*d25d47eeSjbeck 			exit(EX_NOINPUT);
1361*d25d47eeSjbeck 		}
1362*d25d47eeSjbeck 	}
1363*d25d47eeSjbeck }
1364*d25d47eeSjbeck #endif /* SUN_EXTENSIONS */
1365*d25d47eeSjbeck 
13667c478bd9Sstevel@tonic-gate /*
13677c478bd9Sstevel@tonic-gate **  INIT_MD -- do machine dependent initializations
13687c478bd9Sstevel@tonic-gate **
13697c478bd9Sstevel@tonic-gate **	Systems that have global modes that should be set should do
13707c478bd9Sstevel@tonic-gate **	them here rather than in main.
13717c478bd9Sstevel@tonic-gate */
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate #ifdef _AUX_SOURCE
13747c478bd9Sstevel@tonic-gate # include <compat.h>
13757c478bd9Sstevel@tonic-gate #endif /* _AUX_SOURCE */
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate #if SHARE_V1
13787c478bd9Sstevel@tonic-gate # include <shares.h>
13797c478bd9Sstevel@tonic-gate #endif /* SHARE_V1 */
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate void
13827c478bd9Sstevel@tonic-gate init_md(argc, argv)
13837c478bd9Sstevel@tonic-gate 	int argc;
13847c478bd9Sstevel@tonic-gate 	char **argv;
13857c478bd9Sstevel@tonic-gate {
13867c478bd9Sstevel@tonic-gate #ifdef _AUX_SOURCE
13877c478bd9Sstevel@tonic-gate 	setcompat(getcompat() | COMPAT_BSDPROT);
13887c478bd9Sstevel@tonic-gate #endif /* _AUX_SOURCE */
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate #ifdef SUN_EXTENSIONS
13917c478bd9Sstevel@tonic-gate 	init_md_sun();
13927c478bd9Sstevel@tonic-gate #endif /* SUN_EXTENSIONS */
13937c478bd9Sstevel@tonic-gate 
13947c478bd9Sstevel@tonic-gate #if _CONVEX_SOURCE
13957c478bd9Sstevel@tonic-gate 	/* keep gethostby*() from stripping the local domain name */
13967c478bd9Sstevel@tonic-gate 	set_domain_trim_off();
13977c478bd9Sstevel@tonic-gate #endif /* _CONVEX_SOURCE */
13987c478bd9Sstevel@tonic-gate #ifdef __QNX__
13997c478bd9Sstevel@tonic-gate 	/*
14007c478bd9Sstevel@tonic-gate 	**  Due to QNX's network distributed nature, you can target a tcpip
14017c478bd9Sstevel@tonic-gate 	**  stack on a different node in the qnx network; this patch lets
14027c478bd9Sstevel@tonic-gate 	**  this feature work.  The __sock_locate() must be done before the
14037c478bd9Sstevel@tonic-gate 	**  environment is clear.
14047c478bd9Sstevel@tonic-gate 	*/
14057c478bd9Sstevel@tonic-gate 	__sock_locate();
14067c478bd9Sstevel@tonic-gate #endif /* __QNX__ */
14077c478bd9Sstevel@tonic-gate #if SECUREWARE || defined(_SCO_unix_)
14087c478bd9Sstevel@tonic-gate 	set_auth_parameters(argc, argv);
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate # ifdef _SCO_unix_
14117c478bd9Sstevel@tonic-gate 	/*
14127c478bd9Sstevel@tonic-gate 	**  This is required for highest security levels (the kernel
14137c478bd9Sstevel@tonic-gate 	**  won't let it call set*uid() or run setuid binaries without
14147c478bd9Sstevel@tonic-gate 	**  it).  It may be necessary on other SECUREWARE systems.
14157c478bd9Sstevel@tonic-gate 	*/
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate 	if (getluid() == -1)
14187c478bd9Sstevel@tonic-gate 		setluid(0);
14197c478bd9Sstevel@tonic-gate # endif /* _SCO_unix_ */
14207c478bd9Sstevel@tonic-gate #endif /* SECUREWARE || defined(_SCO_unix_) */
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate #ifdef VENDOR_DEFAULT
14247c478bd9Sstevel@tonic-gate 	VendorCode = VENDOR_DEFAULT;
14257c478bd9Sstevel@tonic-gate #else /* VENDOR_DEFAULT */
14267c478bd9Sstevel@tonic-gate 	VendorCode = VENDOR_BERKELEY;
14277c478bd9Sstevel@tonic-gate #endif /* VENDOR_DEFAULT */
14287c478bd9Sstevel@tonic-gate }
14297c478bd9Sstevel@tonic-gate /*
14307c478bd9Sstevel@tonic-gate **  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
14317c478bd9Sstevel@tonic-gate **
14327c478bd9Sstevel@tonic-gate **	Called once, on startup.
14337c478bd9Sstevel@tonic-gate **
14347c478bd9Sstevel@tonic-gate **	Parameters:
14357c478bd9Sstevel@tonic-gate **		e -- the global envelope.
14367c478bd9Sstevel@tonic-gate **
14377c478bd9Sstevel@tonic-gate **	Returns:
14387c478bd9Sstevel@tonic-gate **		none.
14397c478bd9Sstevel@tonic-gate **
14407c478bd9Sstevel@tonic-gate **	Side Effects:
14417c478bd9Sstevel@tonic-gate **		vendor-dependent.
14427c478bd9Sstevel@tonic-gate */
14437c478bd9Sstevel@tonic-gate 
14447c478bd9Sstevel@tonic-gate void
14457c478bd9Sstevel@tonic-gate init_vendor_macros(e)
14467c478bd9Sstevel@tonic-gate 	register ENVELOPE *e;
14477c478bd9Sstevel@tonic-gate {
14487c478bd9Sstevel@tonic-gate }
14497c478bd9Sstevel@tonic-gate /*
14507c478bd9Sstevel@tonic-gate **  GETLA -- get the current load average
14517c478bd9Sstevel@tonic-gate **
14527c478bd9Sstevel@tonic-gate **	This code stolen from la.c.
14537c478bd9Sstevel@tonic-gate **
14547c478bd9Sstevel@tonic-gate **	Parameters:
14557c478bd9Sstevel@tonic-gate **		none.
14567c478bd9Sstevel@tonic-gate **
14577c478bd9Sstevel@tonic-gate **	Returns:
14587c478bd9Sstevel@tonic-gate **		The current load average as an integer.
14597c478bd9Sstevel@tonic-gate **
14607c478bd9Sstevel@tonic-gate **	Side Effects:
14617c478bd9Sstevel@tonic-gate **		none.
14627c478bd9Sstevel@tonic-gate */
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate /* try to guess what style of load average we have */
14657c478bd9Sstevel@tonic-gate #define LA_ZERO		1	/* always return load average as zero */
14667c478bd9Sstevel@tonic-gate #define LA_INT		2	/* read kmem for avenrun; interpret as long */
14677c478bd9Sstevel@tonic-gate #define LA_FLOAT	3	/* read kmem for avenrun; interpret as float */
14687c478bd9Sstevel@tonic-gate #define LA_SUBR		4	/* call getloadavg */
14697c478bd9Sstevel@tonic-gate #define LA_MACH		5	/* MACH load averages (as on NeXT boxes) */
14707c478bd9Sstevel@tonic-gate #define LA_SHORT	6	/* read kmem for avenrun; interpret as short */
14717c478bd9Sstevel@tonic-gate #define LA_PROCSTR	7	/* read string ("1.17") from /proc/loadavg */
14727c478bd9Sstevel@tonic-gate #define LA_READKSYM	8	/* SVR4: use MIOC_READKSYM ioctl call */
14737c478bd9Sstevel@tonic-gate #define LA_DGUX		9	/* special DGUX implementation */
14747c478bd9Sstevel@tonic-gate #define LA_HPUX		10	/* special HPUX implementation */
14757c478bd9Sstevel@tonic-gate #define LA_IRIX6	11	/* special IRIX 6.2 implementation */
14767c478bd9Sstevel@tonic-gate #define LA_KSTAT	12	/* special Solaris kstat(3k) implementation */
14777c478bd9Sstevel@tonic-gate #define LA_DEVSHORT	13	/* read short from a device */
14787c478bd9Sstevel@tonic-gate #define LA_ALPHAOSF	14	/* Digital UNIX (OSF/1 on Alpha) table() call */
14797c478bd9Sstevel@tonic-gate #define LA_PSET		15	/* Solaris per-processor-set load average */
14807c478bd9Sstevel@tonic-gate #define LA_LONGLONG	17 /* read kmem for avenrun; interpret as long long */
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate /* do guesses based on general OS type */
14837c478bd9Sstevel@tonic-gate #ifndef LA_TYPE
14847c478bd9Sstevel@tonic-gate # define LA_TYPE	LA_ZERO
14857c478bd9Sstevel@tonic-gate #endif /* ! LA_TYPE */
14867c478bd9Sstevel@tonic-gate 
14877c478bd9Sstevel@tonic-gate #ifndef FSHIFT
14887c478bd9Sstevel@tonic-gate # if defined(unixpc)
14897c478bd9Sstevel@tonic-gate #  define FSHIFT	5
14907c478bd9Sstevel@tonic-gate # endif /* defined(unixpc) */
14917c478bd9Sstevel@tonic-gate 
14927c478bd9Sstevel@tonic-gate # if defined(__alpha) || defined(IRIX)
14937c478bd9Sstevel@tonic-gate #  define FSHIFT	10
14947c478bd9Sstevel@tonic-gate # endif /* defined(__alpha) || defined(IRIX) */
14957c478bd9Sstevel@tonic-gate 
14967c478bd9Sstevel@tonic-gate #endif /* ! FSHIFT */
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate #ifndef FSHIFT
14997c478bd9Sstevel@tonic-gate # define FSHIFT		8
15007c478bd9Sstevel@tonic-gate #endif /* ! FSHIFT */
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate #ifndef FSCALE
15037c478bd9Sstevel@tonic-gate # define FSCALE		(1 << FSHIFT)
15047c478bd9Sstevel@tonic-gate #endif /* ! FSCALE */
15057c478bd9Sstevel@tonic-gate 
15067c478bd9Sstevel@tonic-gate #ifndef LA_AVENRUN
15077c478bd9Sstevel@tonic-gate # ifdef SYSTEM5
15087c478bd9Sstevel@tonic-gate #  define LA_AVENRUN	"avenrun"
15097c478bd9Sstevel@tonic-gate # else /* SYSTEM5 */
15107c478bd9Sstevel@tonic-gate #  define LA_AVENRUN	"_avenrun"
15117c478bd9Sstevel@tonic-gate # endif /* SYSTEM5 */
15127c478bd9Sstevel@tonic-gate #endif /* ! LA_AVENRUN */
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate /* _PATH_KMEM should be defined in <paths.h> */
15157c478bd9Sstevel@tonic-gate #ifndef _PATH_KMEM
15167c478bd9Sstevel@tonic-gate # define _PATH_KMEM	"/dev/kmem"
15177c478bd9Sstevel@tonic-gate #endif /* ! _PATH_KMEM */
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate # include <nlist.h>
15227c478bd9Sstevel@tonic-gate 
15237c478bd9Sstevel@tonic-gate /* _PATH_UNIX should be defined in <paths.h> */
15247c478bd9Sstevel@tonic-gate # ifndef _PATH_UNIX
15257c478bd9Sstevel@tonic-gate #  if defined(SYSTEM5)
15267c478bd9Sstevel@tonic-gate #   define _PATH_UNIX	"/unix"
15277c478bd9Sstevel@tonic-gate #  else /* defined(SYSTEM5) */
15287c478bd9Sstevel@tonic-gate #   define _PATH_UNIX	"/vmunix"
15297c478bd9Sstevel@tonic-gate #  endif /* defined(SYSTEM5) */
15307c478bd9Sstevel@tonic-gate # endif /* ! _PATH_UNIX */
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate # ifdef _AUX_SOURCE
15337c478bd9Sstevel@tonic-gate struct nlist	Nl[2];
15347c478bd9Sstevel@tonic-gate # else /* _AUX_SOURCE */
15357c478bd9Sstevel@tonic-gate struct nlist	Nl[] =
15367c478bd9Sstevel@tonic-gate {
15377c478bd9Sstevel@tonic-gate 	{ LA_AVENRUN },
15387c478bd9Sstevel@tonic-gate 	{ 0 },
15397c478bd9Sstevel@tonic-gate };
15407c478bd9Sstevel@tonic-gate # endif /* _AUX_SOURCE */
15417c478bd9Sstevel@tonic-gate # define X_AVENRUN	0
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate int
15447c478bd9Sstevel@tonic-gate getla()
15457c478bd9Sstevel@tonic-gate {
15467c478bd9Sstevel@tonic-gate 	int j;
15477c478bd9Sstevel@tonic-gate 	static int kmem = -1;
15487c478bd9Sstevel@tonic-gate # if LA_TYPE == LA_INT
15497c478bd9Sstevel@tonic-gate 	long avenrun[3];
15507c478bd9Sstevel@tonic-gate # else /* LA_TYPE == LA_INT */
15517c478bd9Sstevel@tonic-gate #  if LA_TYPE == LA_SHORT
15527c478bd9Sstevel@tonic-gate 	short avenrun[3];
15537c478bd9Sstevel@tonic-gate #  else
15547c478bd9Sstevel@tonic-gate #   if LA_TYPE == LA_LONGLONG
15557c478bd9Sstevel@tonic-gate 	long long avenrun[3];
15567c478bd9Sstevel@tonic-gate #   else /* LA_TYPE == LA_LONGLONG */
15577c478bd9Sstevel@tonic-gate 	double avenrun[3];
15587c478bd9Sstevel@tonic-gate #   endif /* LA_TYPE == LA_LONGLONG */
15597c478bd9Sstevel@tonic-gate #  endif /* LA_TYPE == LA_SHORT */
15607c478bd9Sstevel@tonic-gate # endif /* LA_TYPE == LA_INT */
15617c478bd9Sstevel@tonic-gate 	extern off_t lseek();
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 	if (kmem < 0)
15647c478bd9Sstevel@tonic-gate 	{
15657c478bd9Sstevel@tonic-gate # ifdef _AUX_SOURCE
15667c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN,
15677c478bd9Sstevel@tonic-gate 			       sizeof Nl[X_AVENRUN].n_name);
15687c478bd9Sstevel@tonic-gate 		Nl[1].n_name[0] = '\0';
15697c478bd9Sstevel@tonic-gate # endif /* _AUX_SOURCE */
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate # if defined(_AIX3) || defined(_AIX4)
15727c478bd9Sstevel@tonic-gate 		if (knlist(Nl, 1, sizeof Nl[0]) < 0)
15737c478bd9Sstevel@tonic-gate # else /* defined(_AIX3) || defined(_AIX4) */
15747c478bd9Sstevel@tonic-gate 		if (nlist(_PATH_UNIX, Nl) < 0)
15757c478bd9Sstevel@tonic-gate # endif /* defined(_AIX3) || defined(_AIX4) */
15767c478bd9Sstevel@tonic-gate 		{
15777c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
15787c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
15797c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
15807c478bd9Sstevel@tonic-gate 			return -1;
15817c478bd9Sstevel@tonic-gate 		}
15827c478bd9Sstevel@tonic-gate 		if (Nl[X_AVENRUN].n_value == 0)
15837c478bd9Sstevel@tonic-gate 		{
15847c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
15857c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: nlist(%s, %s) ==> 0\n",
15867c478bd9Sstevel@tonic-gate 					_PATH_UNIX, LA_AVENRUN);
15877c478bd9Sstevel@tonic-gate 			return -1;
15887c478bd9Sstevel@tonic-gate 		}
15897c478bd9Sstevel@tonic-gate # ifdef NAMELISTMASK
15907c478bd9Sstevel@tonic-gate 		Nl[X_AVENRUN].n_value &= NAMELISTMASK;
15917c478bd9Sstevel@tonic-gate # endif /* NAMELISTMASK */
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate 		kmem = open(_PATH_KMEM, 0, 0);
15947c478bd9Sstevel@tonic-gate 		if (kmem < 0)
15957c478bd9Sstevel@tonic-gate 		{
15967c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
15977c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: open(/dev/kmem): %s\n",
15987c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
15997c478bd9Sstevel@tonic-gate 			return -1;
16007c478bd9Sstevel@tonic-gate 		}
16017c478bd9Sstevel@tonic-gate 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
16027c478bd9Sstevel@tonic-gate 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
16037c478bd9Sstevel@tonic-gate 		{
16047c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
16057c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
16067c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
16077c478bd9Sstevel@tonic-gate 			(void) close(kmem);
16087c478bd9Sstevel@tonic-gate 			kmem = -1;
16097c478bd9Sstevel@tonic-gate 			return -1;
16107c478bd9Sstevel@tonic-gate 		}
16117c478bd9Sstevel@tonic-gate 	}
16127c478bd9Sstevel@tonic-gate 	if (tTd(3, 20))
16137c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: symbol address = %#lx\n",
16147c478bd9Sstevel@tonic-gate 			(unsigned long) Nl[X_AVENRUN].n_value);
16157c478bd9Sstevel@tonic-gate 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
16167c478bd9Sstevel@tonic-gate 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
16177c478bd9Sstevel@tonic-gate 	{
16187c478bd9Sstevel@tonic-gate 		/* thank you Ian */
16197c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
16207c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: lseek or read: %s\n",
16217c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
16227c478bd9Sstevel@tonic-gate 		return -1;
16237c478bd9Sstevel@tonic-gate 	}
16247c478bd9Sstevel@tonic-gate # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
16257c478bd9Sstevel@tonic-gate 	if (tTd(3, 5))
16267c478bd9Sstevel@tonic-gate 	{
16277c478bd9Sstevel@tonic-gate #  if LA_TYPE == LA_SHORT
16287c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
16297c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
16307c478bd9Sstevel@tonic-gate 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
16317c478bd9Sstevel@tonic-gate #  else /* LA_TYPE == LA_SHORT */
16327c478bd9Sstevel@tonic-gate #   if LA_TYPE == LA_LONGLONG
16337c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %lld", avenrun[0]);
16347c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
16357c478bd9Sstevel@tonic-gate 			sm_dprintf(", %lld, %lld", avenrun[1], avenrun[2]);
16367c478bd9Sstevel@tonic-gate #   else /* LA_TYPE == LA_LONGLONG */
16377c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %ld", avenrun[0]);
16387c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
16397c478bd9Sstevel@tonic-gate 			sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]);
16407c478bd9Sstevel@tonic-gate #   endif /* LA_TYPE == LA_LONGLONG */
16417c478bd9Sstevel@tonic-gate #  endif /* LA_TYPE == LA_SHORT */
16427c478bd9Sstevel@tonic-gate 		sm_dprintf("\n");
16437c478bd9Sstevel@tonic-gate 	}
16447c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
16457c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n",
16467c478bd9Sstevel@tonic-gate 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
16477c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
16487c478bd9Sstevel@tonic-gate # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
16497c478bd9Sstevel@tonic-gate 	if (tTd(3, 5))
16507c478bd9Sstevel@tonic-gate 	{
16517c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %g", avenrun[0]);
16527c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
16537c478bd9Sstevel@tonic-gate 			sm_dprintf(", %g, %g", avenrun[1], avenrun[2]);
16547c478bd9Sstevel@tonic-gate 		sm_dprintf("\n");
16557c478bd9Sstevel@tonic-gate 	}
16567c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
16577c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
16587c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + 0.5));
16597c478bd9Sstevel@tonic-gate # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
16607c478bd9Sstevel@tonic-gate }
16617c478bd9Sstevel@tonic-gate 
16627c478bd9Sstevel@tonic-gate #endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG) */
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_READKSYM
16657c478bd9Sstevel@tonic-gate 
16667c478bd9Sstevel@tonic-gate # include <sys/ksym.h>
16677c478bd9Sstevel@tonic-gate 
16687c478bd9Sstevel@tonic-gate int
16697c478bd9Sstevel@tonic-gate getla()
16707c478bd9Sstevel@tonic-gate {
16717c478bd9Sstevel@tonic-gate 	int j;
16727c478bd9Sstevel@tonic-gate 	static int kmem = -1;
16737c478bd9Sstevel@tonic-gate 	long avenrun[3];
16747c478bd9Sstevel@tonic-gate 	struct mioc_rksym mirk;
16757c478bd9Sstevel@tonic-gate 
16767c478bd9Sstevel@tonic-gate 	if (kmem < 0)
16777c478bd9Sstevel@tonic-gate 	{
16787c478bd9Sstevel@tonic-gate 		kmem = open("/dev/kmem", 0, 0);
16797c478bd9Sstevel@tonic-gate 		if (kmem < 0)
16807c478bd9Sstevel@tonic-gate 		{
16817c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
16827c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: open(/dev/kmem): %s\n",
16837c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
16847c478bd9Sstevel@tonic-gate 			return -1;
16857c478bd9Sstevel@tonic-gate 		}
16867c478bd9Sstevel@tonic-gate 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
16877c478bd9Sstevel@tonic-gate 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
16887c478bd9Sstevel@tonic-gate 		{
16897c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
16907c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
16917c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
16927c478bd9Sstevel@tonic-gate 			(void) close(kmem);
16937c478bd9Sstevel@tonic-gate 			kmem = -1;
16947c478bd9Sstevel@tonic-gate 			return -1;
16957c478bd9Sstevel@tonic-gate 		}
16967c478bd9Sstevel@tonic-gate 	}
16977c478bd9Sstevel@tonic-gate 	mirk.mirk_symname = LA_AVENRUN;
16987c478bd9Sstevel@tonic-gate 	mirk.mirk_buf = avenrun;
16997c478bd9Sstevel@tonic-gate 	mirk.mirk_buflen = sizeof(avenrun);
17007c478bd9Sstevel@tonic-gate 	if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
17017c478bd9Sstevel@tonic-gate 	{
17027c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
17037c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
17047c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
17057c478bd9Sstevel@tonic-gate 		return -1;
17067c478bd9Sstevel@tonic-gate 	}
17077c478bd9Sstevel@tonic-gate 	if (tTd(3, 5))
17087c478bd9Sstevel@tonic-gate 	{
17097c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %d", avenrun[0]);
17107c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
17117c478bd9Sstevel@tonic-gate 			sm_dprintf(", %d, %d", avenrun[1], avenrun[2]);
17127c478bd9Sstevel@tonic-gate 		sm_dprintf("\n");
17137c478bd9Sstevel@tonic-gate 	}
17147c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
17157c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n",
17167c478bd9Sstevel@tonic-gate 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
17177c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
17187c478bd9Sstevel@tonic-gate }
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_READKSYM */
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_DGUX
17237c478bd9Sstevel@tonic-gate 
17247c478bd9Sstevel@tonic-gate # include <sys/dg_sys_info.h>
17257c478bd9Sstevel@tonic-gate 
17267c478bd9Sstevel@tonic-gate int
17277c478bd9Sstevel@tonic-gate getla()
17287c478bd9Sstevel@tonic-gate {
17297c478bd9Sstevel@tonic-gate 	struct dg_sys_info_load_info load_info;
17307c478bd9Sstevel@tonic-gate 
17317c478bd9Sstevel@tonic-gate 	dg_sys_info((long *)&load_info,
17327c478bd9Sstevel@tonic-gate 		DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
17337c478bd9Sstevel@tonic-gate 
17347c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
17357c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5));
17367c478bd9Sstevel@tonic-gate 
17377c478bd9Sstevel@tonic-gate 	return ((int) (load_info.one_minute + 0.5));
17387c478bd9Sstevel@tonic-gate }
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_DGUX */
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_HPUX
17437c478bd9Sstevel@tonic-gate 
17447c478bd9Sstevel@tonic-gate /* forward declarations to keep gcc from complaining */
17457c478bd9Sstevel@tonic-gate struct pst_dynamic;
17467c478bd9Sstevel@tonic-gate struct pst_status;
17477c478bd9Sstevel@tonic-gate struct pst_static;
17487c478bd9Sstevel@tonic-gate struct pst_vminfo;
17497c478bd9Sstevel@tonic-gate struct pst_diskinfo;
17507c478bd9Sstevel@tonic-gate struct pst_processor;
17517c478bd9Sstevel@tonic-gate struct pst_lv;
17527c478bd9Sstevel@tonic-gate struct pst_swapinfo;
17537c478bd9Sstevel@tonic-gate 
17547c478bd9Sstevel@tonic-gate # include <sys/param.h>
17557c478bd9Sstevel@tonic-gate # include <sys/pstat.h>
17567c478bd9Sstevel@tonic-gate 
17577c478bd9Sstevel@tonic-gate int
17587c478bd9Sstevel@tonic-gate getla()
17597c478bd9Sstevel@tonic-gate {
17607c478bd9Sstevel@tonic-gate 	struct pst_dynamic pstd;
17617c478bd9Sstevel@tonic-gate 
17627c478bd9Sstevel@tonic-gate 	if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
17637c478bd9Sstevel@tonic-gate 			     (size_t) 1, 0) == -1)
17647c478bd9Sstevel@tonic-gate 		return 0;
17657c478bd9Sstevel@tonic-gate 
17667c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
17677c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
17687c478bd9Sstevel@tonic-gate 
17697c478bd9Sstevel@tonic-gate 	return (int) (pstd.psd_avg_1_min + 0.5);
17707c478bd9Sstevel@tonic-gate }
17717c478bd9Sstevel@tonic-gate 
17727c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_HPUX */
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_SUBR
17757c478bd9Sstevel@tonic-gate 
17767c478bd9Sstevel@tonic-gate int
17777c478bd9Sstevel@tonic-gate getla()
17787c478bd9Sstevel@tonic-gate {
17797c478bd9Sstevel@tonic-gate 	double avenrun[3];
17807c478bd9Sstevel@tonic-gate 
17817c478bd9Sstevel@tonic-gate 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
17827c478bd9Sstevel@tonic-gate 	{
17837c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
17847c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: getloadavg failed: %s",
17857c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
17867c478bd9Sstevel@tonic-gate 		return -1;
17877c478bd9Sstevel@tonic-gate 	}
17887c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
17897c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
17907c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + 0.5));
17917c478bd9Sstevel@tonic-gate }
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_SUBR */
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_MACH
17967c478bd9Sstevel@tonic-gate 
17977c478bd9Sstevel@tonic-gate /*
17987c478bd9Sstevel@tonic-gate **  This has been tested on NEXTSTEP release 2.1/3.X.
17997c478bd9Sstevel@tonic-gate */
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate # if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
18027c478bd9Sstevel@tonic-gate #  include <mach/mach.h>
18037c478bd9Sstevel@tonic-gate # else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
18047c478bd9Sstevel@tonic-gate #  include <mach.h>
18057c478bd9Sstevel@tonic-gate # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
18067c478bd9Sstevel@tonic-gate 
18077c478bd9Sstevel@tonic-gate int
18087c478bd9Sstevel@tonic-gate getla()
18097c478bd9Sstevel@tonic-gate {
18107c478bd9Sstevel@tonic-gate 	processor_set_t default_set;
18117c478bd9Sstevel@tonic-gate 	kern_return_t error;
18127c478bd9Sstevel@tonic-gate 	unsigned int info_count;
18137c478bd9Sstevel@tonic-gate 	struct processor_set_basic_info info;
18147c478bd9Sstevel@tonic-gate 	host_t host;
18157c478bd9Sstevel@tonic-gate 
18167c478bd9Sstevel@tonic-gate 	error = processor_set_default(host_self(), &default_set);
18177c478bd9Sstevel@tonic-gate 	if (error != KERN_SUCCESS)
18187c478bd9Sstevel@tonic-gate 	{
18197c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
18207c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: processor_set_default failed: %s",
18217c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
18227c478bd9Sstevel@tonic-gate 		return -1;
18237c478bd9Sstevel@tonic-gate 	}
18247c478bd9Sstevel@tonic-gate 	info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
18257c478bd9Sstevel@tonic-gate 	if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
18267c478bd9Sstevel@tonic-gate 			       &host, (processor_set_info_t)&info,
18277c478bd9Sstevel@tonic-gate 			       &info_count) != KERN_SUCCESS)
18287c478bd9Sstevel@tonic-gate 	{
18297c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
18307c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: processor_set_info failed: %s",
18317c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
18327c478bd9Sstevel@tonic-gate 		return -1;
18337c478bd9Sstevel@tonic-gate 	}
18347c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
18357c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n",
18367c478bd9Sstevel@tonic-gate 			(int) ((info.load_average + (LOAD_SCALE / 2)) /
18377c478bd9Sstevel@tonic-gate 			       LOAD_SCALE));
18387c478bd9Sstevel@tonic-gate 	return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
18397c478bd9Sstevel@tonic-gate }
18407c478bd9Sstevel@tonic-gate 
18417c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_MACH */
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_PROCSTR
18447c478bd9Sstevel@tonic-gate # if SM_CONF_BROKEN_STRTOD
18457c478bd9Sstevel@tonic-gate 	ERROR: This OS has most likely a broken strtod() implemenentation.
18467c478bd9Sstevel@tonic-gate 	ERROR: The function is required for getla().
18477c478bd9Sstevel@tonic-gate 	ERROR: Check the compilation options _LA_PROCSTR and
18487c478bd9Sstevel@tonic-gate 	ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _).
18497c478bd9Sstevel@tonic-gate # endif /* SM_CONF_BROKEN_STRTOD */
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate /*
18527c478bd9Sstevel@tonic-gate **  Read /proc/loadavg for the load average.  This is assumed to be
18537c478bd9Sstevel@tonic-gate **  in a format like "0.15 0.12 0.06".
18547c478bd9Sstevel@tonic-gate **
18557c478bd9Sstevel@tonic-gate **	Initially intended for Linux.  This has been in the kernel
18567c478bd9Sstevel@tonic-gate **	since at least 0.99.15.
18577c478bd9Sstevel@tonic-gate */
18587c478bd9Sstevel@tonic-gate 
18597c478bd9Sstevel@tonic-gate # ifndef _PATH_LOADAVG
18607c478bd9Sstevel@tonic-gate #  define _PATH_LOADAVG	"/proc/loadavg"
18617c478bd9Sstevel@tonic-gate # endif /* ! _PATH_LOADAVG */
18627c478bd9Sstevel@tonic-gate 
18637c478bd9Sstevel@tonic-gate int
18647c478bd9Sstevel@tonic-gate getla()
18657c478bd9Sstevel@tonic-gate {
18667c478bd9Sstevel@tonic-gate 	double avenrun;
18677c478bd9Sstevel@tonic-gate 	register int result;
18687c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
18697c478bd9Sstevel@tonic-gate 
18707c478bd9Sstevel@tonic-gate 	fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY,
18717c478bd9Sstevel@tonic-gate 			NULL);
18727c478bd9Sstevel@tonic-gate 	if (fp == NULL)
18737c478bd9Sstevel@tonic-gate 	{
18747c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
18757c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: sm_io_open(%s): %s\n",
18767c478bd9Sstevel@tonic-gate 				   _PATH_LOADAVG, sm_errstring(errno));
18777c478bd9Sstevel@tonic-gate 		return -1;
18787c478bd9Sstevel@tonic-gate 	}
18797c478bd9Sstevel@tonic-gate 	result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun);
18807c478bd9Sstevel@tonic-gate 	(void) sm_io_close(fp, SM_TIME_DEFAULT);
18817c478bd9Sstevel@tonic-gate 	if (result != 1)
18827c478bd9Sstevel@tonic-gate 	{
18837c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
18847c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: sm_io_fscanf() = %d: %s\n",
18857c478bd9Sstevel@tonic-gate 				   result, sm_errstring(errno));
18867c478bd9Sstevel@tonic-gate 		return -1;
18877c478bd9Sstevel@tonic-gate 	}
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
18907c478bd9Sstevel@tonic-gate 		sm_dprintf("getla(): %.2f\n", avenrun);
18917c478bd9Sstevel@tonic-gate 
18927c478bd9Sstevel@tonic-gate 	return ((int) (avenrun + 0.5));
18937c478bd9Sstevel@tonic-gate }
18947c478bd9Sstevel@tonic-gate 
18957c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_PROCSTR */
18967c478bd9Sstevel@tonic-gate 
18977c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_IRIX6
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate # include <sys/sysmp.h>
19007c478bd9Sstevel@tonic-gate 
19017c478bd9Sstevel@tonic-gate # ifdef _UNICOSMP
19027c478bd9Sstevel@tonic-gate #  define CAST_SYSMP(x)	(x)
19037c478bd9Sstevel@tonic-gate # else /* _UNICOSMP */
19047c478bd9Sstevel@tonic-gate #  define CAST_SYSMP(x)	((x) & 0x7fffffff)
19057c478bd9Sstevel@tonic-gate # endif /* _UNICOSMP */
19067c478bd9Sstevel@tonic-gate 
19077c478bd9Sstevel@tonic-gate int
19087c478bd9Sstevel@tonic-gate getla(void)
19097c478bd9Sstevel@tonic-gate {
19107c478bd9Sstevel@tonic-gate 	int j;
19117c478bd9Sstevel@tonic-gate 	static int kmem = -1;
19127c478bd9Sstevel@tonic-gate 	int avenrun[3];
19137c478bd9Sstevel@tonic-gate 
19147c478bd9Sstevel@tonic-gate 	if (kmem < 0)
19157c478bd9Sstevel@tonic-gate 	{
19167c478bd9Sstevel@tonic-gate 		kmem = open(_PATH_KMEM, 0, 0);
19177c478bd9Sstevel@tonic-gate 		if (kmem < 0)
19187c478bd9Sstevel@tonic-gate 		{
19197c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
19207c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM,
19217c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
19227c478bd9Sstevel@tonic-gate 			return -1;
19237c478bd9Sstevel@tonic-gate 		}
19247c478bd9Sstevel@tonic-gate 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
19257c478bd9Sstevel@tonic-gate 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
19267c478bd9Sstevel@tonic-gate 		{
19277c478bd9Sstevel@tonic-gate 			if (tTd(3, 1))
19287c478bd9Sstevel@tonic-gate 				sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n",
19297c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
19307c478bd9Sstevel@tonic-gate 			(void) close(kmem);
19317c478bd9Sstevel@tonic-gate 			kmem = -1;
19327c478bd9Sstevel@tonic-gate 			return -1;
19337c478bd9Sstevel@tonic-gate 		}
19347c478bd9Sstevel@tonic-gate 	}
19357c478bd9Sstevel@tonic-gate 
19367c478bd9Sstevel@tonic-gate 	if (lseek(kmem, CAST_SYSMP(sysmp(MP_KERNADDR, MPKA_AVENRUN)), SEEK_SET)
19377c478bd9Sstevel@tonic-gate 		== -1 ||
19387c478bd9Sstevel@tonic-gate 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
19397c478bd9Sstevel@tonic-gate 	{
19407c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
19417c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: lseek or read: %s\n",
19427c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
19437c478bd9Sstevel@tonic-gate 		return -1;
19447c478bd9Sstevel@tonic-gate 	}
19457c478bd9Sstevel@tonic-gate 	if (tTd(3, 5))
19467c478bd9Sstevel@tonic-gate 	{
19477c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]);
19487c478bd9Sstevel@tonic-gate 		if (tTd(3, 15))
19497c478bd9Sstevel@tonic-gate 			sm_dprintf(", %ld, %ld",
19507c478bd9Sstevel@tonic-gate 				(long int) avenrun[1], (long int) avenrun[2]);
19517c478bd9Sstevel@tonic-gate 		sm_dprintf("\n");
19527c478bd9Sstevel@tonic-gate 	}
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
19557c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n",
19567c478bd9Sstevel@tonic-gate 			(int) (avenrun[0] + FSCALE/2) >> FSHIFT);
19577c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate }
19607c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_IRIX6 */
19617c478bd9Sstevel@tonic-gate 
19627c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_KSTAT
19637c478bd9Sstevel@tonic-gate 
19647c478bd9Sstevel@tonic-gate # include <kstat.h>
19657c478bd9Sstevel@tonic-gate 
19667c478bd9Sstevel@tonic-gate int
19677c478bd9Sstevel@tonic-gate getla()
19687c478bd9Sstevel@tonic-gate {
19697c478bd9Sstevel@tonic-gate 	static kstat_ctl_t *kc = NULL;
19707c478bd9Sstevel@tonic-gate 	static kstat_t *ksp = NULL;
19717c478bd9Sstevel@tonic-gate 	kstat_named_t *ksn;
19727c478bd9Sstevel@tonic-gate 	int la;
19737c478bd9Sstevel@tonic-gate 
19747c478bd9Sstevel@tonic-gate 	if (kc == NULL)		/* if not initialized before */
19757c478bd9Sstevel@tonic-gate 		kc = kstat_open();
19767c478bd9Sstevel@tonic-gate 	if (kc == NULL)
19777c478bd9Sstevel@tonic-gate 	{
19787c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
19797c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: kstat_open(): %s\n",
19807c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
19817c478bd9Sstevel@tonic-gate 		return -1;
19827c478bd9Sstevel@tonic-gate 	}
19837c478bd9Sstevel@tonic-gate 	if (ksp == NULL)
19847c478bd9Sstevel@tonic-gate 		ksp = kstat_lookup(kc, "unix", 0, "system_misc");
19857c478bd9Sstevel@tonic-gate 	if (ksp == NULL)
19867c478bd9Sstevel@tonic-gate 	{
19877c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
19887c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: kstat_lookup(): %s\n",
19897c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
19907c478bd9Sstevel@tonic-gate 		return -1;
19917c478bd9Sstevel@tonic-gate 	}
19927c478bd9Sstevel@tonic-gate 	if (kstat_read(kc, ksp, NULL) < 0)
19937c478bd9Sstevel@tonic-gate 	{
19947c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
19957c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: kstat_read(): %s\n",
19967c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
19977c478bd9Sstevel@tonic-gate 		return -1;
19987c478bd9Sstevel@tonic-gate 	}
19997c478bd9Sstevel@tonic-gate 	ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
20007c478bd9Sstevel@tonic-gate 	la = ((double) ksn->value.ul + FSCALE/2) / FSCALE;
20017c478bd9Sstevel@tonic-gate 	/* kstat_close(kc); /o do not close for fast access */
20027c478bd9Sstevel@tonic-gate 	return la;
20037c478bd9Sstevel@tonic-gate }
20047c478bd9Sstevel@tonic-gate 
20057c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_KSTAT */
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_DEVSHORT
20087c478bd9Sstevel@tonic-gate 
20097c478bd9Sstevel@tonic-gate /*
20107c478bd9Sstevel@tonic-gate **  Read /dev/table/avenrun for the load average.  This should contain
20117c478bd9Sstevel@tonic-gate **  three shorts for the 1, 5, and 15 minute loads.  We only read the
20127c478bd9Sstevel@tonic-gate **  first, since that's all we care about.
20137c478bd9Sstevel@tonic-gate **
20147c478bd9Sstevel@tonic-gate **	Intended for SCO OpenServer 5.
20157c478bd9Sstevel@tonic-gate */
20167c478bd9Sstevel@tonic-gate 
20177c478bd9Sstevel@tonic-gate # ifndef _PATH_AVENRUN
20187c478bd9Sstevel@tonic-gate #  define _PATH_AVENRUN	"/dev/table/avenrun"
20197c478bd9Sstevel@tonic-gate # endif /* ! _PATH_AVENRUN */
20207c478bd9Sstevel@tonic-gate 
20217c478bd9Sstevel@tonic-gate int
20227c478bd9Sstevel@tonic-gate getla()
20237c478bd9Sstevel@tonic-gate {
20247c478bd9Sstevel@tonic-gate 	static int afd = -1;
20257c478bd9Sstevel@tonic-gate 	short avenrun;
20267c478bd9Sstevel@tonic-gate 	int loadav;
20277c478bd9Sstevel@tonic-gate 	int r;
20287c478bd9Sstevel@tonic-gate 
20297c478bd9Sstevel@tonic-gate 	errno = EBADF;
20307c478bd9Sstevel@tonic-gate 
20317c478bd9Sstevel@tonic-gate 	if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
20327c478bd9Sstevel@tonic-gate 	{
20337c478bd9Sstevel@tonic-gate 		if (errno != EBADF)
20347c478bd9Sstevel@tonic-gate 			return -1;
20357c478bd9Sstevel@tonic-gate 		afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
20367c478bd9Sstevel@tonic-gate 		if (afd < 0)
20377c478bd9Sstevel@tonic-gate 		{
20387c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_ERR, NOQID,
20397c478bd9Sstevel@tonic-gate 				"can't open %s: %s",
20407c478bd9Sstevel@tonic-gate 				_PATH_AVENRUN, sm_errstring(errno));
20417c478bd9Sstevel@tonic-gate 			return -1;
20427c478bd9Sstevel@tonic-gate 		}
20437c478bd9Sstevel@tonic-gate 	}
20447c478bd9Sstevel@tonic-gate 
20457c478bd9Sstevel@tonic-gate 	r = read(afd, &avenrun, sizeof avenrun);
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 	if (tTd(3, 5))
20487c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: avenrun = %d\n", avenrun);
20497c478bd9Sstevel@tonic-gate 	loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
20507c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
20517c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", loadav);
20527c478bd9Sstevel@tonic-gate 	return loadav;
20537c478bd9Sstevel@tonic-gate }
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_DEVSHORT */
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_ALPHAOSF
20587c478bd9Sstevel@tonic-gate struct rtentry;
20597c478bd9Sstevel@tonic-gate struct mbuf;
20607c478bd9Sstevel@tonic-gate # include <sys/table.h>
20617c478bd9Sstevel@tonic-gate 
20627c478bd9Sstevel@tonic-gate int
20637c478bd9Sstevel@tonic-gate getla()
20647c478bd9Sstevel@tonic-gate {
20657c478bd9Sstevel@tonic-gate 	int ave = 0;
20667c478bd9Sstevel@tonic-gate 	struct tbl_loadavg tab;
20677c478bd9Sstevel@tonic-gate 
20687c478bd9Sstevel@tonic-gate 	if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
20697c478bd9Sstevel@tonic-gate 	{
20707c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
20717c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: table %s\n", sm_errstring(errno));
20727c478bd9Sstevel@tonic-gate 		return -1;
20737c478bd9Sstevel@tonic-gate 	}
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
20767c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: scale = %d\n", tab.tl_lscale);
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate 	if (tab.tl_lscale)
20797c478bd9Sstevel@tonic-gate 		ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) /
20807c478bd9Sstevel@tonic-gate 		       tab.tl_lscale);
20817c478bd9Sstevel@tonic-gate 	else
20827c478bd9Sstevel@tonic-gate 		ave = (int) (tab.tl_avenrun.d[2] + 0.5);
20837c478bd9Sstevel@tonic-gate 
20847c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
20857c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", ave);
20867c478bd9Sstevel@tonic-gate 
20877c478bd9Sstevel@tonic-gate 	return ave;
20887c478bd9Sstevel@tonic-gate }
20897c478bd9Sstevel@tonic-gate 
20907c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_ALPHAOSF */
20917c478bd9Sstevel@tonic-gate 
20927c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_PSET
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate int
20957c478bd9Sstevel@tonic-gate getla()
20967c478bd9Sstevel@tonic-gate {
20977c478bd9Sstevel@tonic-gate 	double avenrun[3];
20987c478bd9Sstevel@tonic-gate 
20997c478bd9Sstevel@tonic-gate 	if (pset_getloadavg(PS_MYID, avenrun,
21007c478bd9Sstevel@tonic-gate 			    sizeof(avenrun) / sizeof(avenrun[0])) < 0)
21017c478bd9Sstevel@tonic-gate 	{
21027c478bd9Sstevel@tonic-gate 		if (tTd(3, 1))
21037c478bd9Sstevel@tonic-gate 			sm_dprintf("getla: pset_getloadavg failed: %s",
21047c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
21057c478bd9Sstevel@tonic-gate 		return -1;
21067c478bd9Sstevel@tonic-gate 	}
21077c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
21087c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5));
21097c478bd9Sstevel@tonic-gate 	return ((int) (avenrun[0] + 0.5));
21107c478bd9Sstevel@tonic-gate }
21117c478bd9Sstevel@tonic-gate 
21127c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_PSET */
21137c478bd9Sstevel@tonic-gate 
21147c478bd9Sstevel@tonic-gate #if LA_TYPE == LA_ZERO
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate int
21177c478bd9Sstevel@tonic-gate getla()
21187c478bd9Sstevel@tonic-gate {
21197c478bd9Sstevel@tonic-gate 	if (tTd(3, 1))
21207c478bd9Sstevel@tonic-gate 		sm_dprintf("getla: ZERO\n");
21217c478bd9Sstevel@tonic-gate 	return 0;
21227c478bd9Sstevel@tonic-gate }
21237c478bd9Sstevel@tonic-gate 
21247c478bd9Sstevel@tonic-gate #endif /* LA_TYPE == LA_ZERO */
21257c478bd9Sstevel@tonic-gate 
21267c478bd9Sstevel@tonic-gate /*
21277c478bd9Sstevel@tonic-gate  * Copyright 1989 Massachusetts Institute of Technology
21287c478bd9Sstevel@tonic-gate  *
21297c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, distribute, and sell this software and its
21307c478bd9Sstevel@tonic-gate  * documentation for any purpose is hereby granted without fee, provided that
21317c478bd9Sstevel@tonic-gate  * the above copyright notice appear in all copies and that both that
21327c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in supporting
21337c478bd9Sstevel@tonic-gate  * documentation, and that the name of M.I.T. not be used in advertising or
21347c478bd9Sstevel@tonic-gate  * publicity pertaining to distribution of the software without specific,
21357c478bd9Sstevel@tonic-gate  * written prior permission.  M.I.T. makes no representations about the
21367c478bd9Sstevel@tonic-gate  * suitability of this software for any purpose.  It is provided "as is"
21377c478bd9Sstevel@tonic-gate  * without express or implied warranty.
21387c478bd9Sstevel@tonic-gate  *
21397c478bd9Sstevel@tonic-gate  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
21407c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
21417c478bd9Sstevel@tonic-gate  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21427c478bd9Sstevel@tonic-gate  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21437c478bd9Sstevel@tonic-gate  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21447c478bd9Sstevel@tonic-gate  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21457c478bd9Sstevel@tonic-gate  *
21467c478bd9Sstevel@tonic-gate  * Authors:  Many and varied...
21477c478bd9Sstevel@tonic-gate  */
21487c478bd9Sstevel@tonic-gate 
21497c478bd9Sstevel@tonic-gate /* Non Apollo stuff removed by Don Lewis 11/15/93 */
21507c478bd9Sstevel@tonic-gate #ifndef lint
21517c478bd9Sstevel@tonic-gate SM_UNUSED(static char  rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
21527c478bd9Sstevel@tonic-gate #endif /* ! lint */
21537c478bd9Sstevel@tonic-gate 
21547c478bd9Sstevel@tonic-gate #ifdef apollo
21557c478bd9Sstevel@tonic-gate # undef volatile
21567c478bd9Sstevel@tonic-gate # include <apollo/base.h>
21577c478bd9Sstevel@tonic-gate 
21587c478bd9Sstevel@tonic-gate /* ARGSUSED */
21597c478bd9Sstevel@tonic-gate int getloadavg( call_data )
21607c478bd9Sstevel@tonic-gate 	caddr_t call_data;	/* pointer to (double) return value */
21617c478bd9Sstevel@tonic-gate {
21627c478bd9Sstevel@tonic-gate 	double *avenrun = (double *) call_data;
21637c478bd9Sstevel@tonic-gate 	int i;
21647c478bd9Sstevel@tonic-gate 	status_$t      st;
21657c478bd9Sstevel@tonic-gate 	long loadav[3];
21667c478bd9Sstevel@tonic-gate 
21677c478bd9Sstevel@tonic-gate 	proc1_$get_loadav(loadav, &st);
21687c478bd9Sstevel@tonic-gate 	*avenrun = loadav[0] / (double) (1 << 16);
21697c478bd9Sstevel@tonic-gate 	return 0;
21707c478bd9Sstevel@tonic-gate }
21717c478bd9Sstevel@tonic-gate #endif /* apollo */
21727c478bd9Sstevel@tonic-gate /*
21737c478bd9Sstevel@tonic-gate **  SM_GETLA -- get the current load average
21747c478bd9Sstevel@tonic-gate **
21757c478bd9Sstevel@tonic-gate **	Parameters:
21767c478bd9Sstevel@tonic-gate **		none
21777c478bd9Sstevel@tonic-gate **
21787c478bd9Sstevel@tonic-gate **	Returns:
21797c478bd9Sstevel@tonic-gate **		none
21807c478bd9Sstevel@tonic-gate **
21817c478bd9Sstevel@tonic-gate **	Side Effects:
21827c478bd9Sstevel@tonic-gate **		Set CurrentLA to the current load average.
21837c478bd9Sstevel@tonic-gate **		Set {load_avg} in GlobalMacros to the current load average.
21847c478bd9Sstevel@tonic-gate */
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate void
21877c478bd9Sstevel@tonic-gate sm_getla()
21887c478bd9Sstevel@tonic-gate {
21897c478bd9Sstevel@tonic-gate 	char labuf[8];
21907c478bd9Sstevel@tonic-gate 
21917c478bd9Sstevel@tonic-gate 	CurrentLA = getla();
21927c478bd9Sstevel@tonic-gate 	(void) sm_snprintf(labuf, sizeof labuf, "%d", CurrentLA);
21937c478bd9Sstevel@tonic-gate 	macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf);
21947c478bd9Sstevel@tonic-gate }
21957c478bd9Sstevel@tonic-gate /*
21967c478bd9Sstevel@tonic-gate **  SHOULDQUEUE -- should this message be queued or sent?
21977c478bd9Sstevel@tonic-gate **
21987c478bd9Sstevel@tonic-gate **	Compares the message cost to the load average to decide.
21997c478bd9Sstevel@tonic-gate **
22007c478bd9Sstevel@tonic-gate **	Note: Do NOT change this API! It is documented in op.me
22017c478bd9Sstevel@tonic-gate **		and theoretically the user can change this function...
22027c478bd9Sstevel@tonic-gate **
22037c478bd9Sstevel@tonic-gate **	Parameters:
22047c478bd9Sstevel@tonic-gate **		pri -- the priority of the message in question.
22057c478bd9Sstevel@tonic-gate **		ct -- the message creation time (unused, but see above).
22067c478bd9Sstevel@tonic-gate **
22077c478bd9Sstevel@tonic-gate **	Returns:
22087c478bd9Sstevel@tonic-gate **		true -- if this message should be queued up for the
22097c478bd9Sstevel@tonic-gate **			time being.
22107c478bd9Sstevel@tonic-gate **		false -- if the load is low enough to send this message.
22117c478bd9Sstevel@tonic-gate **
22127c478bd9Sstevel@tonic-gate **	Side Effects:
22137c478bd9Sstevel@tonic-gate **		none.
22147c478bd9Sstevel@tonic-gate */
22157c478bd9Sstevel@tonic-gate 
22167c478bd9Sstevel@tonic-gate /* ARGSUSED1 */
22177c478bd9Sstevel@tonic-gate bool
22187c478bd9Sstevel@tonic-gate shouldqueue(pri, ct)
22197c478bd9Sstevel@tonic-gate 	long pri;
22207c478bd9Sstevel@tonic-gate 	time_t ct;
22217c478bd9Sstevel@tonic-gate {
22227c478bd9Sstevel@tonic-gate 	bool rval;
2223445f2479Sjbeck #if _FFR_MEMSTAT
2224445f2479Sjbeck 	long memfree;
2225445f2479Sjbeck #endif /* _FFR_MEMSTAT */
22267c478bd9Sstevel@tonic-gate 
22277c478bd9Sstevel@tonic-gate 	if (tTd(3, 30))
22287c478bd9Sstevel@tonic-gate 		sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
22297c478bd9Sstevel@tonic-gate 			CurrentLA, pri);
2230445f2479Sjbeck 
2231445f2479Sjbeck #if _FFR_MEMSTAT
2232445f2479Sjbeck 	if (QueueLowMem > 0 &&
2233445f2479Sjbeck 	    sm_memstat_get(MemoryResource, &memfree) >= 0 &&
2234445f2479Sjbeck 	    memfree < QueueLowMem)
2235445f2479Sjbeck 	{
2236445f2479Sjbeck 		if (tTd(3, 30))
22373ee0e492Sjbeck 			sm_dprintf("true (memfree=%ld < QueueLowMem=%ld)\n",
2238445f2479Sjbeck 				memfree, QueueLowMem);
2239445f2479Sjbeck 		return true;
2240445f2479Sjbeck 	}
2241445f2479Sjbeck #endif /* _FFR_MEMSTAT */
22427c478bd9Sstevel@tonic-gate 	if (CurrentLA < QueueLA)
22437c478bd9Sstevel@tonic-gate 	{
22447c478bd9Sstevel@tonic-gate 		if (tTd(3, 30))
22457c478bd9Sstevel@tonic-gate 			sm_dprintf("false (CurrentLA < QueueLA)\n");
22467c478bd9Sstevel@tonic-gate 		return false;
22477c478bd9Sstevel@tonic-gate 	}
22487c478bd9Sstevel@tonic-gate # if 0	/* this code is reported to cause oscillation around RefuseLA */
22497c478bd9Sstevel@tonic-gate 	if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
22507c478bd9Sstevel@tonic-gate 	{
22517c478bd9Sstevel@tonic-gate 		if (tTd(3, 30))
22527c478bd9Sstevel@tonic-gate 			sm_dprintf("TRUE (CurrentLA >= RefuseLA)\n");
22537c478bd9Sstevel@tonic-gate 		return true;
22547c478bd9Sstevel@tonic-gate 	}
22557c478bd9Sstevel@tonic-gate # endif /* 0 */
22567c478bd9Sstevel@tonic-gate 	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
22577c478bd9Sstevel@tonic-gate 	if (tTd(3, 30))
22587c478bd9Sstevel@tonic-gate 		sm_dprintf("%s (by calculation)\n", rval ? "true" : "false");
22597c478bd9Sstevel@tonic-gate 	return rval;
22607c478bd9Sstevel@tonic-gate }
22617c478bd9Sstevel@tonic-gate /*
22627c478bd9Sstevel@tonic-gate **  REFUSECONNECTIONS -- decide if connections should be refused
22637c478bd9Sstevel@tonic-gate **
22647c478bd9Sstevel@tonic-gate **	Parameters:
22657c478bd9Sstevel@tonic-gate **		name -- daemon name (for error messages only)
22667c478bd9Sstevel@tonic-gate **		e -- the current envelope.
22677c478bd9Sstevel@tonic-gate **		d -- number of daemon
22687c478bd9Sstevel@tonic-gate **		active -- was this daemon actually active?
22697c478bd9Sstevel@tonic-gate **
22707c478bd9Sstevel@tonic-gate **	Returns:
22717c478bd9Sstevel@tonic-gate **		true if incoming SMTP connections should be refused
22727c478bd9Sstevel@tonic-gate **			(for now).
22737c478bd9Sstevel@tonic-gate **		false if we should accept new work.
22747c478bd9Sstevel@tonic-gate **
22757c478bd9Sstevel@tonic-gate **	Side Effects:
22767c478bd9Sstevel@tonic-gate **		Sets process title when it is rejecting connections.
22777c478bd9Sstevel@tonic-gate */
22787c478bd9Sstevel@tonic-gate 
22797c478bd9Sstevel@tonic-gate bool
22807c478bd9Sstevel@tonic-gate refuseconnections(name, e, d, active)
22817c478bd9Sstevel@tonic-gate 	char *name;
22827c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
22837c478bd9Sstevel@tonic-gate 	int d;
22847c478bd9Sstevel@tonic-gate 	bool active;
22857c478bd9Sstevel@tonic-gate {
22867c478bd9Sstevel@tonic-gate 	static time_t lastconn[MAXDAEMONS];
22877c478bd9Sstevel@tonic-gate 	static int conncnt[MAXDAEMONS];
22887c478bd9Sstevel@tonic-gate 	static time_t firstrejtime[MAXDAEMONS];
22897c478bd9Sstevel@tonic-gate 	static time_t nextlogtime[MAXDAEMONS];
2290445f2479Sjbeck #if _FFR_MEMSTAT
2291445f2479Sjbeck 	long memfree;
2292445f2479Sjbeck #endif /* _FFR_MEMSTAT */
22937c478bd9Sstevel@tonic-gate 
22947c478bd9Sstevel@tonic-gate #if XLA
22957c478bd9Sstevel@tonic-gate 	if (!xla_smtp_ok())
22967c478bd9Sstevel@tonic-gate 		return true;
22977c478bd9Sstevel@tonic-gate #endif /* XLA */
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 	SM_ASSERT(d >= 0);
23007c478bd9Sstevel@tonic-gate 	SM_ASSERT(d < MAXDAEMONS);
23017c478bd9Sstevel@tonic-gate 	if (ConnRateThrottle > 0)
23027c478bd9Sstevel@tonic-gate 	{
23037c478bd9Sstevel@tonic-gate 		time_t now;
23047c478bd9Sstevel@tonic-gate 
23057c478bd9Sstevel@tonic-gate 		now = curtime();
23067c478bd9Sstevel@tonic-gate 		if (active)
23077c478bd9Sstevel@tonic-gate 		{
23087c478bd9Sstevel@tonic-gate 			if (now != lastconn[d])
23097c478bd9Sstevel@tonic-gate 			{
23107c478bd9Sstevel@tonic-gate 				lastconn[d] = now;
23117c478bd9Sstevel@tonic-gate 				conncnt[d] = 1;
23127c478bd9Sstevel@tonic-gate 			}
23137c478bd9Sstevel@tonic-gate 			else if (conncnt[d]++ > ConnRateThrottle)
23147c478bd9Sstevel@tonic-gate 			{
23157c478bd9Sstevel@tonic-gate #define D_MSG_CRT "deferring connections on daemon %s: %d per second"
23167c478bd9Sstevel@tonic-gate 				/* sleep to flatten out connection load */
23177c478bd9Sstevel@tonic-gate 				sm_setproctitle(true, e, D_MSG_CRT,
23187c478bd9Sstevel@tonic-gate 						name, ConnRateThrottle);
23197c478bd9Sstevel@tonic-gate 				if (LogLevel > 8)
23207c478bd9Sstevel@tonic-gate 					sm_syslog(LOG_INFO, NOQID, D_MSG_CRT,
23217c478bd9Sstevel@tonic-gate 						  name, ConnRateThrottle);
23227c478bd9Sstevel@tonic-gate 				(void) sleep(1);
23237c478bd9Sstevel@tonic-gate 			}
23247c478bd9Sstevel@tonic-gate 		}
23257c478bd9Sstevel@tonic-gate 		else if (now != lastconn[d])
23267c478bd9Sstevel@tonic-gate 			conncnt[d] = 0;
23277c478bd9Sstevel@tonic-gate 	}
23287c478bd9Sstevel@tonic-gate 
2329445f2479Sjbeck 
2330445f2479Sjbeck #if _FFR_MEMSTAT
2331445f2479Sjbeck 	if (RefuseLowMem > 0 &&
2332445f2479Sjbeck 	    sm_memstat_get(MemoryResource, &memfree) >= 0 &&
2333445f2479Sjbeck 	    memfree < RefuseLowMem)
2334445f2479Sjbeck 	{
2335445f2479Sjbeck # define R_MSG_LM "rejecting connections on daemon %s: free memory: %ld"
2336445f2479Sjbeck 		sm_setproctitle(true, e, R_MSG_LM, name, memfree);
2337445f2479Sjbeck 		if (LogLevel > 8)
2338445f2479Sjbeck 			sm_syslog(LOG_NOTICE, NOQID, R_MSG_LM, name, memfree);
2339445f2479Sjbeck 		return true;
2340445f2479Sjbeck 	}
2341445f2479Sjbeck #endif /* _FFR_MEMSTAT */
23427c478bd9Sstevel@tonic-gate 	sm_getla();
23437c478bd9Sstevel@tonic-gate 	if (RefuseLA > 0 && CurrentLA >= RefuseLA)
23447c478bd9Sstevel@tonic-gate 	{
23457c478bd9Sstevel@tonic-gate 		time_t now;
23467c478bd9Sstevel@tonic-gate 
23477c478bd9Sstevel@tonic-gate # define R_MSG_LA "rejecting connections on daemon %s: load average: %d"
23487c478bd9Sstevel@tonic-gate # define R2_MSG_LA "have been rejecting connections on daemon %s for %s"
23497c478bd9Sstevel@tonic-gate 		sm_setproctitle(true, e, R_MSG_LA, name, CurrentLA);
23507c478bd9Sstevel@tonic-gate 		if (LogLevel > 8)
23517c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_NOTICE, NOQID, R_MSG_LA, name, CurrentLA);
23527c478bd9Sstevel@tonic-gate 		now = curtime();
23537c478bd9Sstevel@tonic-gate 		if (firstrejtime[d] == 0)
23547c478bd9Sstevel@tonic-gate 		{
23557c478bd9Sstevel@tonic-gate 			firstrejtime[d] = now;
23567c478bd9Sstevel@tonic-gate 			nextlogtime[d] = now + RejectLogInterval;
23577c478bd9Sstevel@tonic-gate 		}
23587c478bd9Sstevel@tonic-gate 		else if (nextlogtime[d] < now)
23597c478bd9Sstevel@tonic-gate 		{
23607c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_ERR, NOQID, R2_MSG_LA, name,
23617c478bd9Sstevel@tonic-gate 				  pintvl(now - firstrejtime[d], true));
23627c478bd9Sstevel@tonic-gate 			nextlogtime[d] = now + RejectLogInterval;
23637c478bd9Sstevel@tonic-gate 		}
23647c478bd9Sstevel@tonic-gate 		return true;
23657c478bd9Sstevel@tonic-gate 	}
23667c478bd9Sstevel@tonic-gate 	else
23677c478bd9Sstevel@tonic-gate 		firstrejtime[d] = 0;
23687c478bd9Sstevel@tonic-gate 
23697c478bd9Sstevel@tonic-gate 	if (DelayLA > 0 && CurrentLA >= DelayLA)
23707c478bd9Sstevel@tonic-gate 	{
23717c478bd9Sstevel@tonic-gate 		time_t now;
23727c478bd9Sstevel@tonic-gate 		static time_t log_delay = (time_t) 0;
23737c478bd9Sstevel@tonic-gate 
23747c478bd9Sstevel@tonic-gate # define MIN_DELAY_LOG	90	/* wait before logging this again */
23757c478bd9Sstevel@tonic-gate # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d"
23767c478bd9Sstevel@tonic-gate 		/* sleep to flatten out connection load */
23777c478bd9Sstevel@tonic-gate 		sm_setproctitle(true, e, D_MSG_LA, name, DelayLA);
23787c478bd9Sstevel@tonic-gate 		if (LogLevel > 8 && (now = curtime()) > log_delay)
23797c478bd9Sstevel@tonic-gate 		{
23807c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_INFO, NOQID, D_MSG_LA,
23817c478bd9Sstevel@tonic-gate 				  name, CurrentLA, DelayLA);
23827c478bd9Sstevel@tonic-gate 			log_delay = now + MIN_DELAY_LOG;
23837c478bd9Sstevel@tonic-gate 		}
23847c478bd9Sstevel@tonic-gate 		(void) sleep(1);
23857c478bd9Sstevel@tonic-gate 	}
23867c478bd9Sstevel@tonic-gate 
23877c478bd9Sstevel@tonic-gate 	if (MaxChildren > 0 && CurChildren >= MaxChildren)
23887c478bd9Sstevel@tonic-gate 	{
23897c478bd9Sstevel@tonic-gate 		proc_list_probe();
23907c478bd9Sstevel@tonic-gate 		if (CurChildren >= MaxChildren)
23917c478bd9Sstevel@tonic-gate 		{
23927c478bd9Sstevel@tonic-gate #define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d"
23937c478bd9Sstevel@tonic-gate 			sm_setproctitle(true, e, R_MSG_CHILD,
23947c478bd9Sstevel@tonic-gate 					name, CurChildren, MaxChildren);
23957c478bd9Sstevel@tonic-gate 			if (LogLevel > 8)
23967c478bd9Sstevel@tonic-gate 				sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD,
23977c478bd9Sstevel@tonic-gate 					name, CurChildren, MaxChildren);
23987c478bd9Sstevel@tonic-gate 			return true;
23997c478bd9Sstevel@tonic-gate 		}
24007c478bd9Sstevel@tonic-gate 	}
24017c478bd9Sstevel@tonic-gate 	return false;
24027c478bd9Sstevel@tonic-gate }
24037c478bd9Sstevel@tonic-gate /*
24047c478bd9Sstevel@tonic-gate **  SETPROCTITLE -- set process title for ps
24057c478bd9Sstevel@tonic-gate **
24067c478bd9Sstevel@tonic-gate **	Parameters:
24077c478bd9Sstevel@tonic-gate **		fmt -- a printf style format string.
24087c478bd9Sstevel@tonic-gate **		a, b, c -- possible parameters to fmt.
24097c478bd9Sstevel@tonic-gate **
24107c478bd9Sstevel@tonic-gate **	Returns:
24117c478bd9Sstevel@tonic-gate **		none.
24127c478bd9Sstevel@tonic-gate **
24137c478bd9Sstevel@tonic-gate **	Side Effects:
24147c478bd9Sstevel@tonic-gate **		Clobbers argv of our main procedure so ps(1) will
24157c478bd9Sstevel@tonic-gate **		display the title.
24167c478bd9Sstevel@tonic-gate */
24177c478bd9Sstevel@tonic-gate 
24187c478bd9Sstevel@tonic-gate #define SPT_NONE	0	/* don't use it at all */
24197c478bd9Sstevel@tonic-gate #define SPT_REUSEARGV	1	/* cover argv with title information */
24207c478bd9Sstevel@tonic-gate #define SPT_BUILTIN	2	/* use libc builtin */
24217c478bd9Sstevel@tonic-gate #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
24227c478bd9Sstevel@tonic-gate #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
24237c478bd9Sstevel@tonic-gate #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
24247c478bd9Sstevel@tonic-gate #define SPT_SCO		6	/* write kernel u. area */
24257c478bd9Sstevel@tonic-gate #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
24267c478bd9Sstevel@tonic-gate 
24277c478bd9Sstevel@tonic-gate #ifndef SPT_TYPE
24287c478bd9Sstevel@tonic-gate # define SPT_TYPE	SPT_REUSEARGV
24297c478bd9Sstevel@tonic-gate #endif /* ! SPT_TYPE */
24307c478bd9Sstevel@tonic-gate 
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
24337c478bd9Sstevel@tonic-gate 
24347c478bd9Sstevel@tonic-gate # if SPT_TYPE == SPT_PSTAT
24357c478bd9Sstevel@tonic-gate #  include <sys/pstat.h>
24367c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE == SPT_PSTAT */
24377c478bd9Sstevel@tonic-gate # if SPT_TYPE == SPT_PSSTRINGS
24387c478bd9Sstevel@tonic-gate #  include <machine/vmparam.h>
24397c478bd9Sstevel@tonic-gate #  include <sys/exec.h>
24407c478bd9Sstevel@tonic-gate #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
24417c478bd9Sstevel@tonic-gate #   undef SPT_TYPE
24427c478bd9Sstevel@tonic-gate #   define SPT_TYPE	SPT_REUSEARGV
24437c478bd9Sstevel@tonic-gate #  else /* ! PS_STRINGS */
24447c478bd9Sstevel@tonic-gate #   ifndef NKPDE			/* FreeBSD 2.0 */
24457c478bd9Sstevel@tonic-gate #    define NKPDE 63
24467c478bd9Sstevel@tonic-gate typedef unsigned int	*pt_entry_t;
24477c478bd9Sstevel@tonic-gate #   endif /* ! NKPDE */
24487c478bd9Sstevel@tonic-gate #  endif /* ! PS_STRINGS */
24497c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE == SPT_PSSTRINGS */
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
24527c478bd9Sstevel@tonic-gate #  define SETPROC_STATIC	static
24537c478bd9Sstevel@tonic-gate # else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
24547c478bd9Sstevel@tonic-gate #  define SETPROC_STATIC
24557c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
24567c478bd9Sstevel@tonic-gate 
24577c478bd9Sstevel@tonic-gate # if SPT_TYPE == SPT_SYSMIPS
24587c478bd9Sstevel@tonic-gate #  include <sys/sysmips.h>
24597c478bd9Sstevel@tonic-gate #  include <sys/sysnews.h>
24607c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE == SPT_SYSMIPS */
24617c478bd9Sstevel@tonic-gate 
24627c478bd9Sstevel@tonic-gate # if SPT_TYPE == SPT_SCO
24637c478bd9Sstevel@tonic-gate #  include <sys/immu.h>
24647c478bd9Sstevel@tonic-gate #  include <sys/dir.h>
24657c478bd9Sstevel@tonic-gate #  include <sys/user.h>
24667c478bd9Sstevel@tonic-gate #  include <sys/fs/s5param.h>
24677c478bd9Sstevel@tonic-gate #  if PSARGSZ > MAXLINE
24687c478bd9Sstevel@tonic-gate #   define SPT_BUFSIZE	PSARGSZ
24697c478bd9Sstevel@tonic-gate #  endif /* PSARGSZ > MAXLINE */
24707c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE == SPT_SCO */
24717c478bd9Sstevel@tonic-gate 
24727c478bd9Sstevel@tonic-gate # ifndef SPT_PADCHAR
24737c478bd9Sstevel@tonic-gate #  define SPT_PADCHAR	' '
24747c478bd9Sstevel@tonic-gate # endif /* ! SPT_PADCHAR */
24757c478bd9Sstevel@tonic-gate 
24767c478bd9Sstevel@tonic-gate #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
24777c478bd9Sstevel@tonic-gate 
24787c478bd9Sstevel@tonic-gate #ifndef SPT_BUFSIZE
24797c478bd9Sstevel@tonic-gate # define SPT_BUFSIZE	MAXLINE
24807c478bd9Sstevel@tonic-gate #endif /* ! SPT_BUFSIZE */
24817c478bd9Sstevel@tonic-gate 
24827c478bd9Sstevel@tonic-gate #if _FFR_SPT_ALIGN
24837c478bd9Sstevel@tonic-gate 
24847c478bd9Sstevel@tonic-gate /*
24857c478bd9Sstevel@tonic-gate **  It looks like the Compaq Tru64 5.1A now aligns argv and envp to
24867c478bd9Sstevel@tonic-gate **  64 bit alignment, so unless each piece of argv and envp is a multiple
24877c478bd9Sstevel@tonic-gate **  of 8 bytes (including terminating NULL), initsetproctitle() won't use
24887c478bd9Sstevel@tonic-gate **  any of the space beyond argv[0].  Be sure to set SPT_ALIGN_SIZE if
24897c478bd9Sstevel@tonic-gate **  you use this FFR.
24907c478bd9Sstevel@tonic-gate */
24917c478bd9Sstevel@tonic-gate 
24927c478bd9Sstevel@tonic-gate # ifdef SPT_ALIGN_SIZE
24937c478bd9Sstevel@tonic-gate #  define SPT_ALIGN(x, align)	(((((x) + SPT_ALIGN_SIZE) >> (align)) << (align)) - 1)
24947c478bd9Sstevel@tonic-gate # else /* SPT_ALIGN_SIZE */
24957c478bd9Sstevel@tonic-gate #  define SPT_ALIGN(x, align)	(x)
24967c478bd9Sstevel@tonic-gate # endif /* SPT_ALIGN_SIZE */
24977c478bd9Sstevel@tonic-gate #else /* _FFR_SPT_ALIGN */
24987c478bd9Sstevel@tonic-gate # define SPT_ALIGN(x, align)	(x)
24997c478bd9Sstevel@tonic-gate #endif /* _FFR_SPT_ALIGN */
25007c478bd9Sstevel@tonic-gate 
25017c478bd9Sstevel@tonic-gate /*
25027c478bd9Sstevel@tonic-gate **  Pointers for setproctitle.
25037c478bd9Sstevel@tonic-gate **	This allows "ps" listings to give more useful information.
25047c478bd9Sstevel@tonic-gate */
25057c478bd9Sstevel@tonic-gate 
25067c478bd9Sstevel@tonic-gate static char	**Argv = NULL;		/* pointer to argument vector */
25077c478bd9Sstevel@tonic-gate static char	*LastArgv = NULL;	/* end of argv */
25087c478bd9Sstevel@tonic-gate #if SPT_TYPE != SPT_BUILTIN
25097c478bd9Sstevel@tonic-gate static void	setproctitle __P((const char *, ...));
25107c478bd9Sstevel@tonic-gate #endif /* SPT_TYPE != SPT_BUILTIN */
25117c478bd9Sstevel@tonic-gate 
25127c478bd9Sstevel@tonic-gate void
25137c478bd9Sstevel@tonic-gate initsetproctitle(argc, argv, envp)
25147c478bd9Sstevel@tonic-gate 	int argc;
25157c478bd9Sstevel@tonic-gate 	char **argv;
25167c478bd9Sstevel@tonic-gate 	char **envp;
25177c478bd9Sstevel@tonic-gate {
25187c478bd9Sstevel@tonic-gate 	register int i;
25197c478bd9Sstevel@tonic-gate 	int align;
25207c478bd9Sstevel@tonic-gate 	extern char **environ;
25217c478bd9Sstevel@tonic-gate 
25227c478bd9Sstevel@tonic-gate 	/*
25237c478bd9Sstevel@tonic-gate 	**  Move the environment so setproctitle can use the space at
25247c478bd9Sstevel@tonic-gate 	**  the top of memory.
25257c478bd9Sstevel@tonic-gate 	*/
25267c478bd9Sstevel@tonic-gate 
25277c478bd9Sstevel@tonic-gate 	if (envp != NULL)
25287c478bd9Sstevel@tonic-gate 	{
25297c478bd9Sstevel@tonic-gate 		for (i = 0; envp[i] != NULL; i++)
25307c478bd9Sstevel@tonic-gate 			continue;
25317c478bd9Sstevel@tonic-gate 		environ = (char **) xalloc(sizeof (char *) * (i + 1));
25327c478bd9Sstevel@tonic-gate 		for (i = 0; envp[i] != NULL; i++)
25337c478bd9Sstevel@tonic-gate 			environ[i] = newstr(envp[i]);
25347c478bd9Sstevel@tonic-gate 		environ[i] = NULL;
25357c478bd9Sstevel@tonic-gate 	}
25367c478bd9Sstevel@tonic-gate 
25377c478bd9Sstevel@tonic-gate 	/*
25387c478bd9Sstevel@tonic-gate 	**  Save start and extent of argv for setproctitle.
25397c478bd9Sstevel@tonic-gate 	*/
25407c478bd9Sstevel@tonic-gate 
25417c478bd9Sstevel@tonic-gate 	Argv = argv;
25427c478bd9Sstevel@tonic-gate 
25437c478bd9Sstevel@tonic-gate 	/*
25447c478bd9Sstevel@tonic-gate 	**  Determine how much space we can use for setproctitle.
25457c478bd9Sstevel@tonic-gate 	**  Use all contiguous argv and envp pointers starting at argv[0]
25467c478bd9Sstevel@tonic-gate 	*/
25477c478bd9Sstevel@tonic-gate 
25487c478bd9Sstevel@tonic-gate 	align = -1;
25497c478bd9Sstevel@tonic-gate # if _FFR_SPT_ALIGN
25507c478bd9Sstevel@tonic-gate #  ifdef SPT_ALIGN_SIZE
25517c478bd9Sstevel@tonic-gate 	for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1)
25527c478bd9Sstevel@tonic-gate 		align++;
25537c478bd9Sstevel@tonic-gate #  endif /* SPT_ALIGN_SIZE */
25547c478bd9Sstevel@tonic-gate # endif /* _FFR_SPT_ALIGN */
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate 	for (i = 0; i < argc; i++)
25577c478bd9Sstevel@tonic-gate 	{
25587c478bd9Sstevel@tonic-gate 		if (i == 0 || LastArgv + 1 == argv[i])
25597c478bd9Sstevel@tonic-gate 			LastArgv = argv[i] + SPT_ALIGN(strlen(argv[i]), align);
25607c478bd9Sstevel@tonic-gate 	}
25617c478bd9Sstevel@tonic-gate 	for (i = 0; LastArgv != NULL && envp != NULL && envp[i] != NULL; i++)
25627c478bd9Sstevel@tonic-gate 	{
25637c478bd9Sstevel@tonic-gate 		if (LastArgv + 1 == envp[i])
25647c478bd9Sstevel@tonic-gate 			LastArgv = envp[i] + SPT_ALIGN(strlen(envp[i]), align);
25657c478bd9Sstevel@tonic-gate 	}
25667c478bd9Sstevel@tonic-gate }
25677c478bd9Sstevel@tonic-gate 
25687c478bd9Sstevel@tonic-gate #if SPT_TYPE != SPT_BUILTIN
25697c478bd9Sstevel@tonic-gate 
25707c478bd9Sstevel@tonic-gate /*VARARGS1*/
25717c478bd9Sstevel@tonic-gate static void
25727c478bd9Sstevel@tonic-gate # ifdef __STDC__
25737c478bd9Sstevel@tonic-gate setproctitle(const char *fmt, ...)
25747c478bd9Sstevel@tonic-gate # else /* __STDC__ */
25757c478bd9Sstevel@tonic-gate setproctitle(fmt, va_alist)
25767c478bd9Sstevel@tonic-gate 	const char *fmt;
25777c478bd9Sstevel@tonic-gate 	va_dcl
25787c478bd9Sstevel@tonic-gate # endif /* __STDC__ */
25797c478bd9Sstevel@tonic-gate {
25807c478bd9Sstevel@tonic-gate # if SPT_TYPE != SPT_NONE
25817c478bd9Sstevel@tonic-gate 	register int i;
25827c478bd9Sstevel@tonic-gate 	register char *p;
25837c478bd9Sstevel@tonic-gate 	SETPROC_STATIC char buf[SPT_BUFSIZE];
25847c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
25857c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_PSTAT
25867c478bd9Sstevel@tonic-gate 	union pstun pst;
25877c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_PSTAT */
25887c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_SCO
25897c478bd9Sstevel@tonic-gate 	int j;
25907c478bd9Sstevel@tonic-gate 	off_t seek_off;
25917c478bd9Sstevel@tonic-gate 	static int kmem = -1;
25927c478bd9Sstevel@tonic-gate 	static pid_t kmempid = -1;
25937c478bd9Sstevel@tonic-gate 	struct user u;
25947c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_SCO */
25957c478bd9Sstevel@tonic-gate 
25967c478bd9Sstevel@tonic-gate 	p = buf;
25977c478bd9Sstevel@tonic-gate 
25987c478bd9Sstevel@tonic-gate 	/* print sendmail: heading for grep */
25997c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
26007c478bd9Sstevel@tonic-gate 	p += strlen(p);
26017c478bd9Sstevel@tonic-gate 
26027c478bd9Sstevel@tonic-gate 	/* print the argument string */
26037c478bd9Sstevel@tonic-gate 	SM_VA_START(ap, fmt);
26047c478bd9Sstevel@tonic-gate 	(void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
26057c478bd9Sstevel@tonic-gate 	SM_VA_END(ap);
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 	i = (int) strlen(buf);
26087c478bd9Sstevel@tonic-gate 	if (i < 0)
26097c478bd9Sstevel@tonic-gate 		return;
26107c478bd9Sstevel@tonic-gate 
26117c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_PSTAT
26127c478bd9Sstevel@tonic-gate 	pst.pst_command = buf;
26137c478bd9Sstevel@tonic-gate 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
26147c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_PSTAT */
26157c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_PSSTRINGS
26167c478bd9Sstevel@tonic-gate 	PS_STRINGS->ps_nargvstr = 1;
26177c478bd9Sstevel@tonic-gate 	PS_STRINGS->ps_argvstr = buf;
26187c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_PSSTRINGS */
26197c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_SYSMIPS
26207c478bd9Sstevel@tonic-gate 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
26217c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_SYSMIPS */
26227c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_SCO
26237c478bd9Sstevel@tonic-gate 	if (kmem < 0 || kmempid != CurrentPid)
26247c478bd9Sstevel@tonic-gate 	{
26257c478bd9Sstevel@tonic-gate 		if (kmem >= 0)
26267c478bd9Sstevel@tonic-gate 			(void) close(kmem);
26277c478bd9Sstevel@tonic-gate 		kmem = open(_PATH_KMEM, O_RDWR, 0);
26287c478bd9Sstevel@tonic-gate 		if (kmem < 0)
26297c478bd9Sstevel@tonic-gate 			return;
26307c478bd9Sstevel@tonic-gate 		if ((j = fcntl(kmem, F_GETFD, 0)) < 0 ||
26317c478bd9Sstevel@tonic-gate 		    fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0)
26327c478bd9Sstevel@tonic-gate 		{
26337c478bd9Sstevel@tonic-gate 			(void) close(kmem);
26347c478bd9Sstevel@tonic-gate 			kmem = -1;
26357c478bd9Sstevel@tonic-gate 			return;
26367c478bd9Sstevel@tonic-gate 		}
26377c478bd9Sstevel@tonic-gate 		kmempid = CurrentPid;
26387c478bd9Sstevel@tonic-gate 	}
26397c478bd9Sstevel@tonic-gate 	buf[PSARGSZ - 1] = '\0';
26407c478bd9Sstevel@tonic-gate 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
26417c478bd9Sstevel@tonic-gate 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
26427c478bd9Sstevel@tonic-gate 		(void) write(kmem, buf, PSARGSZ);
26437c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_SCO */
26447c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_REUSEARGV
26457c478bd9Sstevel@tonic-gate 	if (LastArgv == NULL)
26467c478bd9Sstevel@tonic-gate 		return;
26477c478bd9Sstevel@tonic-gate 
26487c478bd9Sstevel@tonic-gate 	if (i > LastArgv - Argv[0] - 2)
26497c478bd9Sstevel@tonic-gate 	{
26507c478bd9Sstevel@tonic-gate 		i = LastArgv - Argv[0] - 2;
26517c478bd9Sstevel@tonic-gate 		buf[i] = '\0';
26527c478bd9Sstevel@tonic-gate 	}
26537c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(Argv[0], buf, i + 1);
26547c478bd9Sstevel@tonic-gate 	p = &Argv[0][i];
26557c478bd9Sstevel@tonic-gate 	while (p < LastArgv)
26567c478bd9Sstevel@tonic-gate 		*p++ = SPT_PADCHAR;
26577c478bd9Sstevel@tonic-gate 	Argv[1] = NULL;
26587c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_REUSEARGV */
26597c478bd9Sstevel@tonic-gate #  if SPT_TYPE == SPT_CHANGEARGV
26607c478bd9Sstevel@tonic-gate 	Argv[0] = buf;
26617c478bd9Sstevel@tonic-gate 	Argv[1] = 0;
26627c478bd9Sstevel@tonic-gate #  endif /* SPT_TYPE == SPT_CHANGEARGV */
26637c478bd9Sstevel@tonic-gate # endif /* SPT_TYPE != SPT_NONE */
26647c478bd9Sstevel@tonic-gate }
26657c478bd9Sstevel@tonic-gate 
26667c478bd9Sstevel@tonic-gate #endif /* SPT_TYPE != SPT_BUILTIN */
26677c478bd9Sstevel@tonic-gate /*
26687c478bd9Sstevel@tonic-gate **  SM_SETPROCTITLE -- set process task and set process title for ps
26697c478bd9Sstevel@tonic-gate **
26707c478bd9Sstevel@tonic-gate **	Possibly set process status and call setproctitle() to
26717c478bd9Sstevel@tonic-gate **	change the ps display.
26727c478bd9Sstevel@tonic-gate **
26737c478bd9Sstevel@tonic-gate **	Parameters:
26747c478bd9Sstevel@tonic-gate **		status -- whether or not to store as process status
26757c478bd9Sstevel@tonic-gate **		e -- the current envelope.
26767c478bd9Sstevel@tonic-gate **		fmt -- a printf style format string.
26777c478bd9Sstevel@tonic-gate **		a, b, c -- possible parameters to fmt.
26787c478bd9Sstevel@tonic-gate **
26797c478bd9Sstevel@tonic-gate **	Returns:
26807c478bd9Sstevel@tonic-gate **		none.
26817c478bd9Sstevel@tonic-gate */
26827c478bd9Sstevel@tonic-gate 
26837c478bd9Sstevel@tonic-gate /*VARARGS2*/
26847c478bd9Sstevel@tonic-gate void
26857c478bd9Sstevel@tonic-gate #ifdef __STDC__
26867c478bd9Sstevel@tonic-gate sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
26877c478bd9Sstevel@tonic-gate #else /* __STDC__ */
26887c478bd9Sstevel@tonic-gate sm_setproctitle(status, e, fmt, va_alist)
26897c478bd9Sstevel@tonic-gate 	bool status;
26907c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
26917c478bd9Sstevel@tonic-gate 	const char *fmt;
26927c478bd9Sstevel@tonic-gate 	va_dcl
26937c478bd9Sstevel@tonic-gate #endif /* __STDC__ */
26947c478bd9Sstevel@tonic-gate {
26957c478bd9Sstevel@tonic-gate 	char buf[SPT_BUFSIZE];
26967c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
26977c478bd9Sstevel@tonic-gate 
26987c478bd9Sstevel@tonic-gate 	/* print the argument string */
26997c478bd9Sstevel@tonic-gate 	SM_VA_START(ap, fmt);
27007c478bd9Sstevel@tonic-gate 	(void) sm_vsnprintf(buf, sizeof buf, fmt, ap);
27017c478bd9Sstevel@tonic-gate 	SM_VA_END(ap);
27027c478bd9Sstevel@tonic-gate 
27037c478bd9Sstevel@tonic-gate 	if (status)
27047c478bd9Sstevel@tonic-gate 		proc_list_set(CurrentPid, buf);
27057c478bd9Sstevel@tonic-gate 
27067c478bd9Sstevel@tonic-gate 	if (ProcTitlePrefix != NULL)
27077c478bd9Sstevel@tonic-gate 	{
27087c478bd9Sstevel@tonic-gate 		char prefix[SPT_BUFSIZE];
27097c478bd9Sstevel@tonic-gate 
27107c478bd9Sstevel@tonic-gate 		expand(ProcTitlePrefix, prefix, sizeof prefix, e);
27117c478bd9Sstevel@tonic-gate 		setproctitle("%s: %s", prefix, buf);
27127c478bd9Sstevel@tonic-gate 	}
27137c478bd9Sstevel@tonic-gate 	else
27147c478bd9Sstevel@tonic-gate 		setproctitle("%s", buf);
27157c478bd9Sstevel@tonic-gate }
27167c478bd9Sstevel@tonic-gate /*
27177c478bd9Sstevel@tonic-gate **  WAITFOR -- wait for a particular process id.
27187c478bd9Sstevel@tonic-gate **
27197c478bd9Sstevel@tonic-gate **	Parameters:
27207c478bd9Sstevel@tonic-gate **		pid -- process id to wait for.
27217c478bd9Sstevel@tonic-gate **
27227c478bd9Sstevel@tonic-gate **	Returns:
27237c478bd9Sstevel@tonic-gate **		status of pid.
27247c478bd9Sstevel@tonic-gate **		-1 if pid never shows up.
27257c478bd9Sstevel@tonic-gate **
27267c478bd9Sstevel@tonic-gate **	Side Effects:
27277c478bd9Sstevel@tonic-gate **		none.
27287c478bd9Sstevel@tonic-gate */
27297c478bd9Sstevel@tonic-gate 
27307c478bd9Sstevel@tonic-gate int
27317c478bd9Sstevel@tonic-gate waitfor(pid)
27327c478bd9Sstevel@tonic-gate 	pid_t pid;
27337c478bd9Sstevel@tonic-gate {
27347c478bd9Sstevel@tonic-gate 	int st;
27357c478bd9Sstevel@tonic-gate 	pid_t i;
27367c478bd9Sstevel@tonic-gate 
27377c478bd9Sstevel@tonic-gate 	do
27387c478bd9Sstevel@tonic-gate 	{
27397c478bd9Sstevel@tonic-gate 		errno = 0;
27407c478bd9Sstevel@tonic-gate 		i = sm_wait(&st);
27417c478bd9Sstevel@tonic-gate 		if (i > 0)
27427c478bd9Sstevel@tonic-gate 			proc_list_drop(i, st, NULL);
27437c478bd9Sstevel@tonic-gate 	} while ((i >= 0 || errno == EINTR) && i != pid);
27447c478bd9Sstevel@tonic-gate 	if (i < 0)
27457c478bd9Sstevel@tonic-gate 		return -1;
27467c478bd9Sstevel@tonic-gate 	return st;
27477c478bd9Sstevel@tonic-gate }
27487c478bd9Sstevel@tonic-gate /*
27497c478bd9Sstevel@tonic-gate **  SM_WAIT -- wait
27507c478bd9Sstevel@tonic-gate **
27517c478bd9Sstevel@tonic-gate **	Parameters:
27527c478bd9Sstevel@tonic-gate **		status -- pointer to status (return value)
27537c478bd9Sstevel@tonic-gate **
27547c478bd9Sstevel@tonic-gate **	Returns:
27557c478bd9Sstevel@tonic-gate **		pid
27567c478bd9Sstevel@tonic-gate */
27577c478bd9Sstevel@tonic-gate 
27587c478bd9Sstevel@tonic-gate pid_t
27597c478bd9Sstevel@tonic-gate sm_wait(status)
27607c478bd9Sstevel@tonic-gate 	int *status;
27617c478bd9Sstevel@tonic-gate {
27627c478bd9Sstevel@tonic-gate # ifdef WAITUNION
27637c478bd9Sstevel@tonic-gate 	union wait st;
27647c478bd9Sstevel@tonic-gate # else /* WAITUNION */
27657c478bd9Sstevel@tonic-gate 	auto int st;
27667c478bd9Sstevel@tonic-gate # endif /* WAITUNION */
27677c478bd9Sstevel@tonic-gate 	pid_t i;
27687c478bd9Sstevel@tonic-gate # if defined(ISC_UNIX) || defined(_SCO_unix_)
27697c478bd9Sstevel@tonic-gate 	int savesig;
27707c478bd9Sstevel@tonic-gate # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
27717c478bd9Sstevel@tonic-gate 
27727c478bd9Sstevel@tonic-gate # if defined(ISC_UNIX) || defined(_SCO_unix_)
27737c478bd9Sstevel@tonic-gate 	savesig = sm_releasesignal(SIGCHLD);
27747c478bd9Sstevel@tonic-gate # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
27757c478bd9Sstevel@tonic-gate 	i = wait(&st);
27767c478bd9Sstevel@tonic-gate # if defined(ISC_UNIX) || defined(_SCO_unix_)
27777c478bd9Sstevel@tonic-gate 	if (savesig > 0)
27787c478bd9Sstevel@tonic-gate 		sm_blocksignal(SIGCHLD);
27797c478bd9Sstevel@tonic-gate # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
27807c478bd9Sstevel@tonic-gate # ifdef WAITUNION
27817c478bd9Sstevel@tonic-gate 	*status = st.w_status;
27827c478bd9Sstevel@tonic-gate # else /* WAITUNION */
27837c478bd9Sstevel@tonic-gate 	*status = st;
27847c478bd9Sstevel@tonic-gate # endif /* WAITUNION */
27857c478bd9Sstevel@tonic-gate 	return i;
27867c478bd9Sstevel@tonic-gate }
27877c478bd9Sstevel@tonic-gate /*
27887c478bd9Sstevel@tonic-gate **  REAPCHILD -- pick up the body of my child, lest it become a zombie
27897c478bd9Sstevel@tonic-gate **
27907c478bd9Sstevel@tonic-gate **	Parameters:
27917c478bd9Sstevel@tonic-gate **		sig -- the signal that got us here (unused).
27927c478bd9Sstevel@tonic-gate **
27937c478bd9Sstevel@tonic-gate **	Returns:
27947c478bd9Sstevel@tonic-gate **		none.
27957c478bd9Sstevel@tonic-gate **
27967c478bd9Sstevel@tonic-gate **	Side Effects:
27977c478bd9Sstevel@tonic-gate **		Picks up extant zombies.
27987c478bd9Sstevel@tonic-gate **		Control socket exits may restart/shutdown daemon.
27997c478bd9Sstevel@tonic-gate **
28007c478bd9Sstevel@tonic-gate **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
28017c478bd9Sstevel@tonic-gate **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
28027c478bd9Sstevel@tonic-gate **		DOING.
28037c478bd9Sstevel@tonic-gate */
28047c478bd9Sstevel@tonic-gate 
28057c478bd9Sstevel@tonic-gate /* ARGSUSED0 */
28067c478bd9Sstevel@tonic-gate SIGFUNC_DECL
28077c478bd9Sstevel@tonic-gate reapchild(sig)
28087c478bd9Sstevel@tonic-gate 	int sig;
28097c478bd9Sstevel@tonic-gate {
28107c478bd9Sstevel@tonic-gate 	int save_errno = errno;
28117c478bd9Sstevel@tonic-gate 	int st;
28127c478bd9Sstevel@tonic-gate 	pid_t pid;
28137c478bd9Sstevel@tonic-gate # if HASWAITPID
28147c478bd9Sstevel@tonic-gate 	auto int status;
28157c478bd9Sstevel@tonic-gate 	int count;
28167c478bd9Sstevel@tonic-gate 
28177c478bd9Sstevel@tonic-gate 	count = 0;
28187c478bd9Sstevel@tonic-gate 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
28197c478bd9Sstevel@tonic-gate 	{
28207c478bd9Sstevel@tonic-gate 		st = status;
28217c478bd9Sstevel@tonic-gate 		if (count++ > 1000)
28227c478bd9Sstevel@tonic-gate 			break;
28237c478bd9Sstevel@tonic-gate # else /* HASWAITPID */
28247c478bd9Sstevel@tonic-gate #  ifdef WNOHANG
28257c478bd9Sstevel@tonic-gate 	union wait status;
28267c478bd9Sstevel@tonic-gate 
28277c478bd9Sstevel@tonic-gate 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
28287c478bd9Sstevel@tonic-gate 	{
28297c478bd9Sstevel@tonic-gate 		st = status.w_status;
28307c478bd9Sstevel@tonic-gate #  else /* WNOHANG */
28317c478bd9Sstevel@tonic-gate 	auto int status;
28327c478bd9Sstevel@tonic-gate 
28337c478bd9Sstevel@tonic-gate 	/*
28347c478bd9Sstevel@tonic-gate 	**  Catch one zombie -- we will be re-invoked (we hope) if there
28357c478bd9Sstevel@tonic-gate 	**  are more.  Unreliable signals probably break this, but this
28367c478bd9Sstevel@tonic-gate 	**  is the "old system" situation -- waitpid or wait3 are to be
28377c478bd9Sstevel@tonic-gate 	**  strongly preferred.
28387c478bd9Sstevel@tonic-gate 	*/
28397c478bd9Sstevel@tonic-gate 
28407c478bd9Sstevel@tonic-gate 	if ((pid = wait(&status)) > 0)
28417c478bd9Sstevel@tonic-gate 	{
28427c478bd9Sstevel@tonic-gate 		st = status;
28437c478bd9Sstevel@tonic-gate #  endif /* WNOHANG */
28447c478bd9Sstevel@tonic-gate # endif /* HASWAITPID */
28457c478bd9Sstevel@tonic-gate 		/* Drop PID and check if it was a control socket child */
28467c478bd9Sstevel@tonic-gate 		proc_list_drop(pid, st, NULL);
28477c478bd9Sstevel@tonic-gate 	}
28487c478bd9Sstevel@tonic-gate 	FIX_SYSV_SIGNAL(sig, reapchild);
28497c478bd9Sstevel@tonic-gate 	errno = save_errno;
28507c478bd9Sstevel@tonic-gate 	return SIGFUNC_RETURN;
28517c478bd9Sstevel@tonic-gate }
28527c478bd9Sstevel@tonic-gate /*
28537c478bd9Sstevel@tonic-gate **  GETDTABLESIZE -- return number of file descriptors
28547c478bd9Sstevel@tonic-gate **
28557c478bd9Sstevel@tonic-gate **	Only on non-BSD systems
28567c478bd9Sstevel@tonic-gate **
28577c478bd9Sstevel@tonic-gate **	Parameters:
28587c478bd9Sstevel@tonic-gate **		none
28597c478bd9Sstevel@tonic-gate **
28607c478bd9Sstevel@tonic-gate **	Returns:
28617c478bd9Sstevel@tonic-gate **		size of file descriptor table
28627c478bd9Sstevel@tonic-gate **
28637c478bd9Sstevel@tonic-gate **	Side Effects:
28647c478bd9Sstevel@tonic-gate **		none
28657c478bd9Sstevel@tonic-gate */
28667c478bd9Sstevel@tonic-gate 
28677c478bd9Sstevel@tonic-gate #ifdef SOLARIS
28687c478bd9Sstevel@tonic-gate # include <sys/resource.h>
28697c478bd9Sstevel@tonic-gate #endif /* SOLARIS */
28707c478bd9Sstevel@tonic-gate 
28717c478bd9Sstevel@tonic-gate int
28727c478bd9Sstevel@tonic-gate getdtsize()
28737c478bd9Sstevel@tonic-gate {
28747c478bd9Sstevel@tonic-gate # ifdef RLIMIT_NOFILE
28757c478bd9Sstevel@tonic-gate 	struct rlimit rl;
28767c478bd9Sstevel@tonic-gate 
28777c478bd9Sstevel@tonic-gate 	if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
28787c478bd9Sstevel@tonic-gate 		return rl.rlim_cur;
28797c478bd9Sstevel@tonic-gate # endif /* RLIMIT_NOFILE */
28807c478bd9Sstevel@tonic-gate 
28817c478bd9Sstevel@tonic-gate # if HASGETDTABLESIZE
28827c478bd9Sstevel@tonic-gate 	return getdtablesize();
28837c478bd9Sstevel@tonic-gate # else /* HASGETDTABLESIZE */
28847c478bd9Sstevel@tonic-gate #  ifdef _SC_OPEN_MAX
28857c478bd9Sstevel@tonic-gate 	return sysconf(_SC_OPEN_MAX);
28867c478bd9Sstevel@tonic-gate #  else /* _SC_OPEN_MAX */
28877c478bd9Sstevel@tonic-gate 	return NOFILE;
28887c478bd9Sstevel@tonic-gate #  endif /* _SC_OPEN_MAX */
28897c478bd9Sstevel@tonic-gate # endif /* HASGETDTABLESIZE */
28907c478bd9Sstevel@tonic-gate }
28917c478bd9Sstevel@tonic-gate /*
28927c478bd9Sstevel@tonic-gate **  UNAME -- get the UUCP name of this system.
28937c478bd9Sstevel@tonic-gate */
28947c478bd9Sstevel@tonic-gate 
28957c478bd9Sstevel@tonic-gate #if !HASUNAME
28967c478bd9Sstevel@tonic-gate 
28977c478bd9Sstevel@tonic-gate int
28987c478bd9Sstevel@tonic-gate uname(name)
28997c478bd9Sstevel@tonic-gate 	struct utsname *name;
29007c478bd9Sstevel@tonic-gate {
29017c478bd9Sstevel@tonic-gate 	SM_FILE_T *file;
29027c478bd9Sstevel@tonic-gate 	char *n;
29037c478bd9Sstevel@tonic-gate 
29047c478bd9Sstevel@tonic-gate 	name->nodename[0] = '\0';
29057c478bd9Sstevel@tonic-gate 
29067c478bd9Sstevel@tonic-gate 	/* try /etc/whoami -- one line with the node name */
29077c478bd9Sstevel@tonic-gate 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami",
29087c478bd9Sstevel@tonic-gate 			       SM_IO_RDONLY, NULL)) != NULL)
29097c478bd9Sstevel@tonic-gate 	{
29107c478bd9Sstevel@tonic-gate 		(void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename,
29117c478bd9Sstevel@tonic-gate 				   NODE_LENGTH + 1);
29127c478bd9Sstevel@tonic-gate 		(void) sm_io_close(file, SM_TIME_DEFAULT);
29137c478bd9Sstevel@tonic-gate 		n = strchr(name->nodename, '\n');
29147c478bd9Sstevel@tonic-gate 		if (n != NULL)
29157c478bd9Sstevel@tonic-gate 			*n = '\0';
29167c478bd9Sstevel@tonic-gate 		if (name->nodename[0] != '\0')
29177c478bd9Sstevel@tonic-gate 			return 0;
29187c478bd9Sstevel@tonic-gate 	}
29197c478bd9Sstevel@tonic-gate 
29207c478bd9Sstevel@tonic-gate 	/* try /usr/include/whoami.h -- has a #define somewhere */
29217c478bd9Sstevel@tonic-gate 	if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT,
29227c478bd9Sstevel@tonic-gate 			       "/usr/include/whoami.h", SM_IO_RDONLY, NULL))
29237c478bd9Sstevel@tonic-gate 	    != NULL)
29247c478bd9Sstevel@tonic-gate 	{
29257c478bd9Sstevel@tonic-gate 		char buf[MAXLINE];
29267c478bd9Sstevel@tonic-gate 
29277c478bd9Sstevel@tonic-gate 		while (sm_io_fgets(file, SM_TIME_DEFAULT,
29287c478bd9Sstevel@tonic-gate 				   buf, sizeof buf) != NULL)
29297c478bd9Sstevel@tonic-gate 		{
29307c478bd9Sstevel@tonic-gate 			if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"",
29317c478bd9Sstevel@tonic-gate 					NODE_LENGTH, name->nodename) > 0)
29327c478bd9Sstevel@tonic-gate 				break;
29337c478bd9Sstevel@tonic-gate 		}
29347c478bd9Sstevel@tonic-gate 		(void) sm_io_close(file, SM_TIME_DEFAULT);
29357c478bd9Sstevel@tonic-gate 		if (name->nodename[0] != '\0')
29367c478bd9Sstevel@tonic-gate 			return 0;
29377c478bd9Sstevel@tonic-gate 	}
29387c478bd9Sstevel@tonic-gate 
29397c478bd9Sstevel@tonic-gate 	return -1;
29407c478bd9Sstevel@tonic-gate }
29417c478bd9Sstevel@tonic-gate #endif /* !HASUNAME */
29427c478bd9Sstevel@tonic-gate /*
29437c478bd9Sstevel@tonic-gate **  INITGROUPS -- initialize groups
29447c478bd9Sstevel@tonic-gate **
29457c478bd9Sstevel@tonic-gate **	Stub implementation for System V style systems
29467c478bd9Sstevel@tonic-gate */
29477c478bd9Sstevel@tonic-gate 
29487c478bd9Sstevel@tonic-gate #if !HASINITGROUPS
29497c478bd9Sstevel@tonic-gate 
29507c478bd9Sstevel@tonic-gate initgroups(name, basegid)
29517c478bd9Sstevel@tonic-gate 	char *name;
29527c478bd9Sstevel@tonic-gate 	int basegid;
29537c478bd9Sstevel@tonic-gate {
29547c478bd9Sstevel@tonic-gate 	return 0;
29557c478bd9Sstevel@tonic-gate }
29567c478bd9Sstevel@tonic-gate 
29577c478bd9Sstevel@tonic-gate #endif /* !HASINITGROUPS */
29587c478bd9Sstevel@tonic-gate /*
29597c478bd9Sstevel@tonic-gate **  SETGROUPS -- set group list
29607c478bd9Sstevel@tonic-gate **
29617c478bd9Sstevel@tonic-gate **	Stub implementation for systems that don't have group lists
29627c478bd9Sstevel@tonic-gate */
29637c478bd9Sstevel@tonic-gate 
29647c478bd9Sstevel@tonic-gate #ifndef NGROUPS_MAX
29657c478bd9Sstevel@tonic-gate 
29667c478bd9Sstevel@tonic-gate int
29677c478bd9Sstevel@tonic-gate setgroups(ngroups, grouplist)
29687c478bd9Sstevel@tonic-gate 	int ngroups;
29697c478bd9Sstevel@tonic-gate 	GIDSET_T grouplist[];
29707c478bd9Sstevel@tonic-gate {
29717c478bd9Sstevel@tonic-gate 	return 0;
29727c478bd9Sstevel@tonic-gate }
29737c478bd9Sstevel@tonic-gate 
29747c478bd9Sstevel@tonic-gate #endif /* ! NGROUPS_MAX */
29757c478bd9Sstevel@tonic-gate /*
29767c478bd9Sstevel@tonic-gate **  SETSID -- set session id (for non-POSIX systems)
29777c478bd9Sstevel@tonic-gate */
29787c478bd9Sstevel@tonic-gate 
29797c478bd9Sstevel@tonic-gate #if !HASSETSID
29807c478bd9Sstevel@tonic-gate 
29817c478bd9Sstevel@tonic-gate pid_t
29827c478bd9Sstevel@tonic-gate setsid __P ((void))
29837c478bd9Sstevel@tonic-gate {
29847c478bd9Sstevel@tonic-gate #  ifdef TIOCNOTTY
29857c478bd9Sstevel@tonic-gate 	int fd;
29867c478bd9Sstevel@tonic-gate 
29877c478bd9Sstevel@tonic-gate 	fd = open("/dev/tty", O_RDWR, 0);
29887c478bd9Sstevel@tonic-gate 	if (fd >= 0)
29897c478bd9Sstevel@tonic-gate 	{
29907c478bd9Sstevel@tonic-gate 		(void) ioctl(fd, TIOCNOTTY, (char *) 0);
29917c478bd9Sstevel@tonic-gate 		(void) close(fd);
29927c478bd9Sstevel@tonic-gate 	}
29937c478bd9Sstevel@tonic-gate #  endif /* TIOCNOTTY */
29947c478bd9Sstevel@tonic-gate #  ifdef SYS5SETPGRP
29957c478bd9Sstevel@tonic-gate 	return setpgrp();
29967c478bd9Sstevel@tonic-gate #  else /* SYS5SETPGRP */
29977c478bd9Sstevel@tonic-gate 	return setpgid(0, CurrentPid);
29987c478bd9Sstevel@tonic-gate #  endif /* SYS5SETPGRP */
29997c478bd9Sstevel@tonic-gate }
30007c478bd9Sstevel@tonic-gate 
30017c478bd9Sstevel@tonic-gate #endif /* !HASSETSID */
30027c478bd9Sstevel@tonic-gate /*
30037c478bd9Sstevel@tonic-gate **  FSYNC -- dummy fsync
30047c478bd9Sstevel@tonic-gate */
30057c478bd9Sstevel@tonic-gate 
30067c478bd9Sstevel@tonic-gate #if NEEDFSYNC
30077c478bd9Sstevel@tonic-gate 
30087c478bd9Sstevel@tonic-gate fsync(fd)
30097c478bd9Sstevel@tonic-gate 	int fd;
30107c478bd9Sstevel@tonic-gate {
30117c478bd9Sstevel@tonic-gate # ifdef O_SYNC
30127c478bd9Sstevel@tonic-gate 	return fcntl(fd, F_SETFL, O_SYNC);
30137c478bd9Sstevel@tonic-gate # else /* O_SYNC */
30147c478bd9Sstevel@tonic-gate 	/* nothing we can do */
30157c478bd9Sstevel@tonic-gate 	return 0;
30167c478bd9Sstevel@tonic-gate # endif /* O_SYNC */
30177c478bd9Sstevel@tonic-gate }
30187c478bd9Sstevel@tonic-gate 
30197c478bd9Sstevel@tonic-gate #endif /* NEEDFSYNC */
30207c478bd9Sstevel@tonic-gate /*
30217c478bd9Sstevel@tonic-gate **  DGUX_INET_ADDR -- inet_addr for DG/UX
30227c478bd9Sstevel@tonic-gate **
30237c478bd9Sstevel@tonic-gate **	Data General DG/UX version of inet_addr returns a struct in_addr
30247c478bd9Sstevel@tonic-gate **	instead of a long.  This patches things.  Only needed on versions
30257c478bd9Sstevel@tonic-gate **	prior to 5.4.3.
30267c478bd9Sstevel@tonic-gate */
30277c478bd9Sstevel@tonic-gate 
30287c478bd9Sstevel@tonic-gate #ifdef DGUX_5_4_2
30297c478bd9Sstevel@tonic-gate 
30307c478bd9Sstevel@tonic-gate # undef inet_addr
30317c478bd9Sstevel@tonic-gate 
30327c478bd9Sstevel@tonic-gate long
30337c478bd9Sstevel@tonic-gate dgux_inet_addr(host)
30347c478bd9Sstevel@tonic-gate 	char *host;
30357c478bd9Sstevel@tonic-gate {
30367c478bd9Sstevel@tonic-gate 	struct in_addr haddr;
30377c478bd9Sstevel@tonic-gate 
30387c478bd9Sstevel@tonic-gate 	haddr = inet_addr(host);
30397c478bd9Sstevel@tonic-gate 	return haddr.s_addr;
30407c478bd9Sstevel@tonic-gate }
30417c478bd9Sstevel@tonic-gate 
30427c478bd9Sstevel@tonic-gate #endif /* DGUX_5_4_2 */
30437c478bd9Sstevel@tonic-gate /*
30447c478bd9Sstevel@tonic-gate **  GETOPT -- for old systems or systems with bogus implementations
30457c478bd9Sstevel@tonic-gate */
30467c478bd9Sstevel@tonic-gate 
30477c478bd9Sstevel@tonic-gate #if !SM_CONF_GETOPT
30487c478bd9Sstevel@tonic-gate 
30497c478bd9Sstevel@tonic-gate /*
30507c478bd9Sstevel@tonic-gate  * Copyright (c) 1985 Regents of the University of California.
30517c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
30527c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
30537c478bd9Sstevel@tonic-gate  */
30547c478bd9Sstevel@tonic-gate 
30557c478bd9Sstevel@tonic-gate 
30567c478bd9Sstevel@tonic-gate /*
30577c478bd9Sstevel@tonic-gate **  this version hacked to add `atend' flag to allow state machine
30587c478bd9Sstevel@tonic-gate **  to reset if invoked by the program to scan args for a 2nd time
30597c478bd9Sstevel@tonic-gate */
30607c478bd9Sstevel@tonic-gate 
30617c478bd9Sstevel@tonic-gate # if defined(LIBC_SCCS) && !defined(lint)
30627c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)getopt.c	4.3 (Berkeley) 3/9/86";
30637c478bd9Sstevel@tonic-gate # endif /* defined(LIBC_SCCS) && !defined(lint) */
30647c478bd9Sstevel@tonic-gate 
30657c478bd9Sstevel@tonic-gate /*
30667c478bd9Sstevel@tonic-gate **  get option letter from argument vector
30677c478bd9Sstevel@tonic-gate */
30687c478bd9Sstevel@tonic-gate # ifdef _CONVEX_SOURCE
30697c478bd9Sstevel@tonic-gate extern int	optind, opterr, optopt;
30707c478bd9Sstevel@tonic-gate extern char	*optarg;
30717c478bd9Sstevel@tonic-gate # else /* _CONVEX_SOURCE */
30727c478bd9Sstevel@tonic-gate int	opterr = 1;		/* if error message should be printed */
30737c478bd9Sstevel@tonic-gate int	optind = 1;		/* index into parent argv vector */
30747c478bd9Sstevel@tonic-gate int	optopt = 0;		/* character checked for validity */
30757c478bd9Sstevel@tonic-gate char	*optarg = NULL;		/* argument associated with option */
30767c478bd9Sstevel@tonic-gate # endif /* _CONVEX_SOURCE */
30777c478bd9Sstevel@tonic-gate 
30787c478bd9Sstevel@tonic-gate # define BADCH	(int)'?'
30797c478bd9Sstevel@tonic-gate # define EMSG	""
30807c478bd9Sstevel@tonic-gate # define tell(s)	if (opterr) \
30817c478bd9Sstevel@tonic-gate 			{sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \
30827c478bd9Sstevel@tonic-gate 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \
30837c478bd9Sstevel@tonic-gate 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \
30847c478bd9Sstevel@tonic-gate 			(void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \
30857c478bd9Sstevel@tonic-gate 			return BADCH;}
30867c478bd9Sstevel@tonic-gate 
30877c478bd9Sstevel@tonic-gate int
30887c478bd9Sstevel@tonic-gate getopt(nargc,nargv,ostr)
30897c478bd9Sstevel@tonic-gate 	int		nargc;
30907c478bd9Sstevel@tonic-gate 	char *const	*nargv;
30917c478bd9Sstevel@tonic-gate 	const char	*ostr;
30927c478bd9Sstevel@tonic-gate {
30937c478bd9Sstevel@tonic-gate 	static char	*place = EMSG;	/* option letter processing */
30947c478bd9Sstevel@tonic-gate 	static char	atend = 0;
30957c478bd9Sstevel@tonic-gate 	register char	*oli = NULL;	/* option letter list index */
30967c478bd9Sstevel@tonic-gate 
30977c478bd9Sstevel@tonic-gate 	if (atend) {
30987c478bd9Sstevel@tonic-gate 		atend = 0;
30997c478bd9Sstevel@tonic-gate 		place = EMSG;
31007c478bd9Sstevel@tonic-gate 	}
31017c478bd9Sstevel@tonic-gate 	if(!*place) {			/* update scanning pointer */
31027c478bd9Sstevel@tonic-gate 		if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
31037c478bd9Sstevel@tonic-gate 			atend++;
31047c478bd9Sstevel@tonic-gate 			return -1;
31057c478bd9Sstevel@tonic-gate 		}
31067c478bd9Sstevel@tonic-gate 		if (*place == '-') {	/* found "--" */
31077c478bd9Sstevel@tonic-gate 			++optind;
31087c478bd9Sstevel@tonic-gate 			atend++;
31097c478bd9Sstevel@tonic-gate 			return -1;
31107c478bd9Sstevel@tonic-gate 		}
31117c478bd9Sstevel@tonic-gate 	}				/* option letter okay? */
31127c478bd9Sstevel@tonic-gate 	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
31137c478bd9Sstevel@tonic-gate 		if (!*place) ++optind;
31147c478bd9Sstevel@tonic-gate 		tell(": illegal option -- ");
31157c478bd9Sstevel@tonic-gate 	}
31167c478bd9Sstevel@tonic-gate 	if (oli && *++oli != ':') {		/* don't need argument */
31177c478bd9Sstevel@tonic-gate 		optarg = NULL;
31187c478bd9Sstevel@tonic-gate 		if (!*place) ++optind;
31197c478bd9Sstevel@tonic-gate 	}
31207c478bd9Sstevel@tonic-gate 	else {				/* need an argument */
31217c478bd9Sstevel@tonic-gate 		if (*place) optarg = place;	/* no white space */
31227c478bd9Sstevel@tonic-gate 		else if (nargc <= ++optind) {	/* no arg */
31237c478bd9Sstevel@tonic-gate 			place = EMSG;
31247c478bd9Sstevel@tonic-gate 			tell(": option requires an argument -- ");
31257c478bd9Sstevel@tonic-gate 		}
31267c478bd9Sstevel@tonic-gate 		else optarg = nargv[optind];	/* white space */
31277c478bd9Sstevel@tonic-gate 		place = EMSG;
31287c478bd9Sstevel@tonic-gate 		++optind;
31297c478bd9Sstevel@tonic-gate 	}
31307c478bd9Sstevel@tonic-gate 	return optopt;			/* dump back option letter */
31317c478bd9Sstevel@tonic-gate }
31327c478bd9Sstevel@tonic-gate 
31337c478bd9Sstevel@tonic-gate #endif /* !SM_CONF_GETOPT */
31347c478bd9Sstevel@tonic-gate /*
31357c478bd9Sstevel@tonic-gate **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
31367c478bd9Sstevel@tonic-gate **
31377c478bd9Sstevel@tonic-gate **	Parameters:
31387c478bd9Sstevel@tonic-gate **		user -- the name of the user we are checking.
31397c478bd9Sstevel@tonic-gate **		shell -- the user's shell from /etc/passwd
31407c478bd9Sstevel@tonic-gate **
31417c478bd9Sstevel@tonic-gate **	Returns:
31427c478bd9Sstevel@tonic-gate **		true -- if it is ok to use this for unrestricted access.
31437c478bd9Sstevel@tonic-gate **		false -- if the shell is restricted.
31447c478bd9Sstevel@tonic-gate */
31457c478bd9Sstevel@tonic-gate 
31467c478bd9Sstevel@tonic-gate #if !HASGETUSERSHELL
31477c478bd9Sstevel@tonic-gate 
31487c478bd9Sstevel@tonic-gate # ifndef _PATH_SHELLS
31497c478bd9Sstevel@tonic-gate #  define _PATH_SHELLS	"/etc/shells"
31507c478bd9Sstevel@tonic-gate # endif /* ! _PATH_SHELLS */
31517c478bd9Sstevel@tonic-gate 
31527c478bd9Sstevel@tonic-gate # if defined(_AIX3) || defined(_AIX4)
31537c478bd9Sstevel@tonic-gate #  include <userconf.h>
31547c478bd9Sstevel@tonic-gate #  if _AIX4 >= 40200
31557c478bd9Sstevel@tonic-gate #   include <userpw.h>
31567c478bd9Sstevel@tonic-gate #  endif /* _AIX4 >= 40200 */
31577c478bd9Sstevel@tonic-gate #  include <usersec.h>
31587c478bd9Sstevel@tonic-gate # endif /* defined(_AIX3) || defined(_AIX4) */
31597c478bd9Sstevel@tonic-gate 
31607c478bd9Sstevel@tonic-gate static char	*DefaultUserShells[] =
31617c478bd9Sstevel@tonic-gate {
31627c478bd9Sstevel@tonic-gate 	"/bin/sh",		/* standard shell */
31637c478bd9Sstevel@tonic-gate # ifdef MPE
31647c478bd9Sstevel@tonic-gate 	"/SYS/PUB/CI",
31657c478bd9Sstevel@tonic-gate # else /* MPE */
31667c478bd9Sstevel@tonic-gate 	"/usr/bin/sh",
31677c478bd9Sstevel@tonic-gate 	"/bin/csh",		/* C shell */
31687c478bd9Sstevel@tonic-gate 	"/usr/bin/csh",
31697c478bd9Sstevel@tonic-gate # endif /* MPE */
31707c478bd9Sstevel@tonic-gate # ifdef __hpux
31717c478bd9Sstevel@tonic-gate #  ifdef V4FS
31727c478bd9Sstevel@tonic-gate 	"/usr/bin/rsh",		/* restricted Bourne shell */
31737c478bd9Sstevel@tonic-gate 	"/usr/bin/ksh",		/* Korn shell */
31747c478bd9Sstevel@tonic-gate 	"/usr/bin/rksh",	/* restricted Korn shell */
31757c478bd9Sstevel@tonic-gate 	"/usr/bin/pam",
31767c478bd9Sstevel@tonic-gate 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
31777c478bd9Sstevel@tonic-gate 	"/usr/bin/posix/sh",
31787c478bd9Sstevel@tonic-gate #  else /* V4FS */
31797c478bd9Sstevel@tonic-gate 	"/bin/rsh",		/* restricted Bourne shell */
31807c478bd9Sstevel@tonic-gate 	"/bin/ksh",		/* Korn shell */
31817c478bd9Sstevel@tonic-gate 	"/bin/rksh",		/* restricted Korn shell */
31827c478bd9Sstevel@tonic-gate 	"/bin/pam",
31837c478bd9Sstevel@tonic-gate 	"/usr/bin/keysh",	/* key shell (extended Korn shell) */
31847c478bd9Sstevel@tonic-gate 	"/bin/posix/sh",
31857c478bd9Sstevel@tonic-gate 	"/sbin/sh",
31867c478bd9Sstevel@tonic-gate #  endif /* V4FS */
31877c478bd9Sstevel@tonic-gate # endif /* __hpux */
31887c478bd9Sstevel@tonic-gate # if defined(_AIX3) || defined(_AIX4)
31897c478bd9Sstevel@tonic-gate 	"/bin/ksh",		/* Korn shell */
31907c478bd9Sstevel@tonic-gate 	"/usr/bin/ksh",
31917c478bd9Sstevel@tonic-gate 	"/bin/tsh",		/* trusted shell */
31927c478bd9Sstevel@tonic-gate 	"/usr/bin/tsh",
31937c478bd9Sstevel@tonic-gate 	"/bin/bsh",		/* Bourne shell */
31947c478bd9Sstevel@tonic-gate 	"/usr/bin/bsh",
31957c478bd9Sstevel@tonic-gate # endif /* defined(_AIX3) || defined(_AIX4) */
31967c478bd9Sstevel@tonic-gate # if defined(__svr4__) || defined(__svr5__)
31977c478bd9Sstevel@tonic-gate 	"/bin/ksh",		/* Korn shell */
31987c478bd9Sstevel@tonic-gate 	"/usr/bin/ksh",
31997c478bd9Sstevel@tonic-gate # endif /* defined(__svr4__) || defined(__svr5__) */
32007c478bd9Sstevel@tonic-gate # ifdef sgi
32017c478bd9Sstevel@tonic-gate 	"/sbin/sh",		/* SGI's shells really live in /sbin */
32027c478bd9Sstevel@tonic-gate 	"/usr/bin/sh",
32037c478bd9Sstevel@tonic-gate 	"/sbin/bsh",		/* classic Bourne shell */
32047c478bd9Sstevel@tonic-gate 	"/bin/bsh",
32057c478bd9Sstevel@tonic-gate 	"/usr/bin/bsh",
32067c478bd9Sstevel@tonic-gate 	"/sbin/csh",		/* standard csh */
32077c478bd9Sstevel@tonic-gate 	"/bin/csh",
32087c478bd9Sstevel@tonic-gate 	"/usr/bin/csh",
32097c478bd9Sstevel@tonic-gate 	"/sbin/jsh",		/* classic Bourne shell w/ job control*/
32107c478bd9Sstevel@tonic-gate 	"/bin/jsh",
32117c478bd9Sstevel@tonic-gate 	"/usr/bin/jsh",
32127c478bd9Sstevel@tonic-gate 	"/bin/ksh",		/* Korn shell */
32137c478bd9Sstevel@tonic-gate 	"/sbin/ksh",
32147c478bd9Sstevel@tonic-gate 	"/usr/bin/ksh",
32157c478bd9Sstevel@tonic-gate 	"/sbin/tcsh",		/* Extended csh */
32167c478bd9Sstevel@tonic-gate 	"/bin/tcsh",
32177c478bd9Sstevel@tonic-gate 	"/usr/bin/tcsh",
32187c478bd9Sstevel@tonic-gate # endif /* sgi */
32197c478bd9Sstevel@tonic-gate 	NULL
32207c478bd9Sstevel@tonic-gate };
32217c478bd9Sstevel@tonic-gate 
32227c478bd9Sstevel@tonic-gate #endif /* !HASGETUSERSHELL */
32237c478bd9Sstevel@tonic-gate 
32247c478bd9Sstevel@tonic-gate #define WILDCARD_SHELL	"/SENDMAIL/ANY/SHELL/"
32257c478bd9Sstevel@tonic-gate 
32267c478bd9Sstevel@tonic-gate bool
32277c478bd9Sstevel@tonic-gate usershellok(user, shell)
32287c478bd9Sstevel@tonic-gate 	char *user;
32297c478bd9Sstevel@tonic-gate 	char *shell;
32307c478bd9Sstevel@tonic-gate {
32317c478bd9Sstevel@tonic-gate # if HASGETUSERSHELL
32327c478bd9Sstevel@tonic-gate 	register char *p;
32337c478bd9Sstevel@tonic-gate 	extern char *getusershell();
32347c478bd9Sstevel@tonic-gate 
32357c478bd9Sstevel@tonic-gate 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
32367c478bd9Sstevel@tonic-gate 	    ConfigLevel <= 1)
32377c478bd9Sstevel@tonic-gate 		return true;
32387c478bd9Sstevel@tonic-gate 
32397c478bd9Sstevel@tonic-gate 	setusershell();
32407c478bd9Sstevel@tonic-gate 	while ((p = getusershell()) != NULL)
32417c478bd9Sstevel@tonic-gate 		if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
32427c478bd9Sstevel@tonic-gate 			break;
32437c478bd9Sstevel@tonic-gate 	endusershell();
32447c478bd9Sstevel@tonic-gate 	return p != NULL;
32457c478bd9Sstevel@tonic-gate # else /* HASGETUSERSHELL */
32467c478bd9Sstevel@tonic-gate #  if USEGETCONFATTR
32477c478bd9Sstevel@tonic-gate 	auto char *v;
32487c478bd9Sstevel@tonic-gate #  endif /* USEGETCONFATTR */
32497c478bd9Sstevel@tonic-gate 	register SM_FILE_T *shellf;
32507c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
32517c478bd9Sstevel@tonic-gate 
32527c478bd9Sstevel@tonic-gate 	if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
32537c478bd9Sstevel@tonic-gate 	    ConfigLevel <= 1)
32547c478bd9Sstevel@tonic-gate 		return true;
32557c478bd9Sstevel@tonic-gate 
32567c478bd9Sstevel@tonic-gate #  if USEGETCONFATTR
32577c478bd9Sstevel@tonic-gate 	/*
32587c478bd9Sstevel@tonic-gate 	**  Naturally IBM has a "better" idea.....
32597c478bd9Sstevel@tonic-gate 	**
32607c478bd9Sstevel@tonic-gate 	**	What a crock.  This interface isn't documented, it is
32617c478bd9Sstevel@tonic-gate 	**	considered part of the security library (-ls), and it
32627c478bd9Sstevel@tonic-gate 	**	only works if you are running as root (since the list
32637c478bd9Sstevel@tonic-gate 	**	of valid shells is obviously a source of great concern).
32647c478bd9Sstevel@tonic-gate 	**	I recommend that you do NOT define USEGETCONFATTR,
32657c478bd9Sstevel@tonic-gate 	**	especially since you are going to have to set up an
32667c478bd9Sstevel@tonic-gate 	**	/etc/shells anyhow to handle the cases where getconfattr
32677c478bd9Sstevel@tonic-gate 	**	fails.
32687c478bd9Sstevel@tonic-gate 	*/
32697c478bd9Sstevel@tonic-gate 
32707c478bd9Sstevel@tonic-gate 	if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
32717c478bd9Sstevel@tonic-gate 	{
32727c478bd9Sstevel@tonic-gate 		while (*v != '\0')
32737c478bd9Sstevel@tonic-gate 		{
32747c478bd9Sstevel@tonic-gate 			if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
32757c478bd9Sstevel@tonic-gate 				return true;
32767c478bd9Sstevel@tonic-gate 			v += strlen(v) + 1;
32777c478bd9Sstevel@tonic-gate 		}
32787c478bd9Sstevel@tonic-gate 		return false;
32797c478bd9Sstevel@tonic-gate 	}
32807c478bd9Sstevel@tonic-gate #  endif /* USEGETCONFATTR */
32817c478bd9Sstevel@tonic-gate 
32827c478bd9Sstevel@tonic-gate 	shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS,
32837c478bd9Sstevel@tonic-gate 			    SM_IO_RDONLY, NULL);
32847c478bd9Sstevel@tonic-gate 	if (shellf == NULL)
32857c478bd9Sstevel@tonic-gate 	{
32867c478bd9Sstevel@tonic-gate 		/* no /etc/shells; see if it is one of the std shells */
32877c478bd9Sstevel@tonic-gate 		char **d;
32887c478bd9Sstevel@tonic-gate 
32897c478bd9Sstevel@tonic-gate 		if (errno != ENOENT && LogLevel > 3)
32907c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_ERR, NOQID,
32917c478bd9Sstevel@tonic-gate 				  "usershellok: cannot open %s: %s",
32927c478bd9Sstevel@tonic-gate 				  _PATH_SHELLS, sm_errstring(errno));
32937c478bd9Sstevel@tonic-gate 
32947c478bd9Sstevel@tonic-gate 		for (d = DefaultUserShells; *d != NULL; d++)
32957c478bd9Sstevel@tonic-gate 		{
32967c478bd9Sstevel@tonic-gate 			if (strcmp(shell, *d) == 0)
32977c478bd9Sstevel@tonic-gate 				return true;
32987c478bd9Sstevel@tonic-gate 		}
32997c478bd9Sstevel@tonic-gate 		return false;
33007c478bd9Sstevel@tonic-gate 	}
33017c478bd9Sstevel@tonic-gate 
33027c478bd9Sstevel@tonic-gate 	while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
33037c478bd9Sstevel@tonic-gate 	{
33047c478bd9Sstevel@tonic-gate 		register char *p, *q;
33057c478bd9Sstevel@tonic-gate 
33067c478bd9Sstevel@tonic-gate 		p = buf;
33077c478bd9Sstevel@tonic-gate 		while (*p != '\0' && *p != '#' && *p != '/')
33087c478bd9Sstevel@tonic-gate 			p++;
33097c478bd9Sstevel@tonic-gate 		if (*p == '#' || *p == '\0')
33107c478bd9Sstevel@tonic-gate 			continue;
33117c478bd9Sstevel@tonic-gate 		q = p;
33127c478bd9Sstevel@tonic-gate 		while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p)))
33137c478bd9Sstevel@tonic-gate 			p++;
33147c478bd9Sstevel@tonic-gate 		*p = '\0';
33157c478bd9Sstevel@tonic-gate 		if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
33167c478bd9Sstevel@tonic-gate 		{
33177c478bd9Sstevel@tonic-gate 			(void) sm_io_close(shellf, SM_TIME_DEFAULT);
33187c478bd9Sstevel@tonic-gate 			return true;
33197c478bd9Sstevel@tonic-gate 		}
33207c478bd9Sstevel@tonic-gate 	}
33217c478bd9Sstevel@tonic-gate 	(void) sm_io_close(shellf, SM_TIME_DEFAULT);
33227c478bd9Sstevel@tonic-gate 	return false;
33237c478bd9Sstevel@tonic-gate # endif /* HASGETUSERSHELL */
33247c478bd9Sstevel@tonic-gate }
33257c478bd9Sstevel@tonic-gate /*
33267c478bd9Sstevel@tonic-gate **  FREEDISKSPACE -- see how much free space is on the queue filesystem
33277c478bd9Sstevel@tonic-gate **
33287c478bd9Sstevel@tonic-gate **	Only implemented if you have statfs.
33297c478bd9Sstevel@tonic-gate **
33307c478bd9Sstevel@tonic-gate **	Parameters:
33317c478bd9Sstevel@tonic-gate **		dir -- the directory in question.
33327c478bd9Sstevel@tonic-gate **		bsize -- a variable into which the filesystem
33337c478bd9Sstevel@tonic-gate **			block size is stored.
33347c478bd9Sstevel@tonic-gate **
33357c478bd9Sstevel@tonic-gate **	Returns:
33367c478bd9Sstevel@tonic-gate **		The number of blocks free on the queue filesystem.
33377c478bd9Sstevel@tonic-gate **		-1 if the statfs call fails.
33387c478bd9Sstevel@tonic-gate **
33397c478bd9Sstevel@tonic-gate **	Side effects:
33407c478bd9Sstevel@tonic-gate **		Puts the filesystem block size into bsize.
33417c478bd9Sstevel@tonic-gate */
33427c478bd9Sstevel@tonic-gate 
33437c478bd9Sstevel@tonic-gate /* statfs types */
33447c478bd9Sstevel@tonic-gate # define SFS_NONE	0	/* no statfs implementation */
33457c478bd9Sstevel@tonic-gate # define SFS_USTAT	1	/* use ustat */
33467c478bd9Sstevel@tonic-gate # define SFS_4ARGS	2	/* use four-argument statfs call */
33477c478bd9Sstevel@tonic-gate # define SFS_VFS	3	/* use <sys/vfs.h> implementation */
33487c478bd9Sstevel@tonic-gate # define SFS_MOUNT	4	/* use <sys/mount.h> implementation */
33497c478bd9Sstevel@tonic-gate # define SFS_STATFS	5	/* use <sys/statfs.h> implementation */
33507c478bd9Sstevel@tonic-gate # define SFS_STATVFS	6	/* use <sys/statvfs.h> implementation */
33517c478bd9Sstevel@tonic-gate 
33527c478bd9Sstevel@tonic-gate # ifndef SFS_TYPE
33537c478bd9Sstevel@tonic-gate #  define SFS_TYPE	SFS_NONE
33547c478bd9Sstevel@tonic-gate # endif /* ! SFS_TYPE */
33557c478bd9Sstevel@tonic-gate 
33567c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_USTAT
33577c478bd9Sstevel@tonic-gate #  include <ustat.h>
33587c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_USTAT */
33597c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
33607c478bd9Sstevel@tonic-gate #  include <sys/statfs.h>
33617c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */
33627c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_VFS
33637c478bd9Sstevel@tonic-gate #  include <sys/vfs.h>
33647c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_VFS */
33657c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_MOUNT
33667c478bd9Sstevel@tonic-gate #  include <sys/mount.h>
33677c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_MOUNT */
33687c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_STATVFS
33697c478bd9Sstevel@tonic-gate #  include <sys/statvfs.h>
33707c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_STATVFS */
33717c478bd9Sstevel@tonic-gate 
33727c478bd9Sstevel@tonic-gate long
33737c478bd9Sstevel@tonic-gate freediskspace(dir, bsize)
33747c478bd9Sstevel@tonic-gate 	char *dir;
33757c478bd9Sstevel@tonic-gate 	long *bsize;
33767c478bd9Sstevel@tonic-gate {
33777c478bd9Sstevel@tonic-gate # if SFS_TYPE == SFS_NONE
33787c478bd9Sstevel@tonic-gate 	if (bsize != NULL)
33797c478bd9Sstevel@tonic-gate 		*bsize = 4096L;
33807c478bd9Sstevel@tonic-gate 
33817c478bd9Sstevel@tonic-gate 	/* assume free space is plentiful */
33827c478bd9Sstevel@tonic-gate 	return (long) LONG_MAX;
33837c478bd9Sstevel@tonic-gate # else /* SFS_TYPE == SFS_NONE */
33847c478bd9Sstevel@tonic-gate #  if SFS_TYPE == SFS_USTAT
33857c478bd9Sstevel@tonic-gate 	struct ustat fs;
33867c478bd9Sstevel@tonic-gate 	struct stat statbuf;
33877c478bd9Sstevel@tonic-gate #   define FSBLOCKSIZE	DEV_BSIZE
33887c478bd9Sstevel@tonic-gate #   define SFS_BAVAIL	f_tfree
33897c478bd9Sstevel@tonic-gate #  else /* SFS_TYPE == SFS_USTAT */
33907c478bd9Sstevel@tonic-gate #   if defined(ultrix)
33917c478bd9Sstevel@tonic-gate 	struct fs_data fs;
33927c478bd9Sstevel@tonic-gate #    define SFS_BAVAIL	fd_bfreen
33937c478bd9Sstevel@tonic-gate #    define FSBLOCKSIZE	1024L
33947c478bd9Sstevel@tonic-gate #   else /* defined(ultrix) */
33957c478bd9Sstevel@tonic-gate #    if SFS_TYPE == SFS_STATVFS
33967c478bd9Sstevel@tonic-gate 	struct statvfs fs;
33977c478bd9Sstevel@tonic-gate #     define FSBLOCKSIZE	fs.f_frsize
33987c478bd9Sstevel@tonic-gate #    else /* SFS_TYPE == SFS_STATVFS */
33997c478bd9Sstevel@tonic-gate 	struct statfs fs;
34007c478bd9Sstevel@tonic-gate #     define FSBLOCKSIZE	fs.f_bsize
34017c478bd9Sstevel@tonic-gate #    endif /* SFS_TYPE == SFS_STATVFS */
34027c478bd9Sstevel@tonic-gate #   endif /* defined(ultrix) */
34037c478bd9Sstevel@tonic-gate #  endif /* SFS_TYPE == SFS_USTAT */
34047c478bd9Sstevel@tonic-gate #  ifndef SFS_BAVAIL
34057c478bd9Sstevel@tonic-gate #   define SFS_BAVAIL f_bavail
34067c478bd9Sstevel@tonic-gate #  endif /* ! SFS_BAVAIL */
34077c478bd9Sstevel@tonic-gate 
34087c478bd9Sstevel@tonic-gate #  if SFS_TYPE == SFS_USTAT
34097c478bd9Sstevel@tonic-gate 	if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
34107c478bd9Sstevel@tonic-gate #  else /* SFS_TYPE == SFS_USTAT */
34117c478bd9Sstevel@tonic-gate #   if SFS_TYPE == SFS_4ARGS
34127c478bd9Sstevel@tonic-gate 	if (statfs(dir, &fs, sizeof fs, 0) == 0)
34137c478bd9Sstevel@tonic-gate #   else /* SFS_TYPE == SFS_4ARGS */
34147c478bd9Sstevel@tonic-gate #    if SFS_TYPE == SFS_STATVFS
34157c478bd9Sstevel@tonic-gate 	if (statvfs(dir, &fs) == 0)
34167c478bd9Sstevel@tonic-gate #    else /* SFS_TYPE == SFS_STATVFS */
34177c478bd9Sstevel@tonic-gate #     if defined(ultrix)
34187c478bd9Sstevel@tonic-gate 	if (statfs(dir, &fs) > 0)
34197c478bd9Sstevel@tonic-gate #     else /* defined(ultrix) */
34207c478bd9Sstevel@tonic-gate 	if (statfs(dir, &fs) == 0)
34217c478bd9Sstevel@tonic-gate #     endif /* defined(ultrix) */
34227c478bd9Sstevel@tonic-gate #    endif /* SFS_TYPE == SFS_STATVFS */
34237c478bd9Sstevel@tonic-gate #   endif /* SFS_TYPE == SFS_4ARGS */
34247c478bd9Sstevel@tonic-gate #  endif /* SFS_TYPE == SFS_USTAT */
34257c478bd9Sstevel@tonic-gate 	{
34267c478bd9Sstevel@tonic-gate 		if (bsize != NULL)
34277c478bd9Sstevel@tonic-gate 			*bsize = FSBLOCKSIZE;
34287c478bd9Sstevel@tonic-gate 		if (fs.SFS_BAVAIL <= 0)
34297c478bd9Sstevel@tonic-gate 			return 0;
34307c478bd9Sstevel@tonic-gate 		else if (fs.SFS_BAVAIL > LONG_MAX)
34317c478bd9Sstevel@tonic-gate 			return (long) LONG_MAX;
34327c478bd9Sstevel@tonic-gate 		else
34337c478bd9Sstevel@tonic-gate 			return (long) fs.SFS_BAVAIL;
34347c478bd9Sstevel@tonic-gate 	}
34357c478bd9Sstevel@tonic-gate 	return -1;
34367c478bd9Sstevel@tonic-gate # endif /* SFS_TYPE == SFS_NONE */
34377c478bd9Sstevel@tonic-gate }
34387c478bd9Sstevel@tonic-gate /*
34397c478bd9Sstevel@tonic-gate **  ENOUGHDISKSPACE -- is there enough free space on the queue file systems?
34407c478bd9Sstevel@tonic-gate **
34417c478bd9Sstevel@tonic-gate **	Parameters:
34427c478bd9Sstevel@tonic-gate **		msize -- the size to check against.  If zero, we don't yet
34437c478bd9Sstevel@tonic-gate **		know how big the message will be, so just check for
34447c478bd9Sstevel@tonic-gate **		a "reasonable" amount.
34457c478bd9Sstevel@tonic-gate **		e -- envelope, or NULL -- controls logging
34467c478bd9Sstevel@tonic-gate **
34477c478bd9Sstevel@tonic-gate **	Returns:
34487c478bd9Sstevel@tonic-gate **		true if in every queue group there is at least one
34497c478bd9Sstevel@tonic-gate **		queue directory whose file system contains enough free space.
34507c478bd9Sstevel@tonic-gate **		false otherwise.
34517c478bd9Sstevel@tonic-gate **
34527c478bd9Sstevel@tonic-gate **	Side Effects:
34537c478bd9Sstevel@tonic-gate **		If there is not enough disk space and e != NULL
34547c478bd9Sstevel@tonic-gate **		then sm_syslog is called.
34557c478bd9Sstevel@tonic-gate */
34567c478bd9Sstevel@tonic-gate 
34577c478bd9Sstevel@tonic-gate bool
34587c478bd9Sstevel@tonic-gate enoughdiskspace(msize, e)
34597c478bd9Sstevel@tonic-gate 	long msize;
34607c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
34617c478bd9Sstevel@tonic-gate {
34627c478bd9Sstevel@tonic-gate 	int i;
34637c478bd9Sstevel@tonic-gate 
34647c478bd9Sstevel@tonic-gate 	if (MinBlocksFree <= 0 && msize <= 0)
34657c478bd9Sstevel@tonic-gate 	{
34667c478bd9Sstevel@tonic-gate 		if (tTd(4, 80))
34677c478bd9Sstevel@tonic-gate 			sm_dprintf("enoughdiskspace: no threshold\n");
34687c478bd9Sstevel@tonic-gate 		return true;
34697c478bd9Sstevel@tonic-gate 	}
34707c478bd9Sstevel@tonic-gate 
34717c478bd9Sstevel@tonic-gate 	filesys_update();
34727c478bd9Sstevel@tonic-gate 	for (i = 0; i < NumQueue; ++i)
34737c478bd9Sstevel@tonic-gate 	{
34747c478bd9Sstevel@tonic-gate 		if (pickqdir(Queue[i], msize, e) < 0)
34757c478bd9Sstevel@tonic-gate 			return false;
34767c478bd9Sstevel@tonic-gate 	}
34777c478bd9Sstevel@tonic-gate 	return true;
34787c478bd9Sstevel@tonic-gate }
34797c478bd9Sstevel@tonic-gate /*
34807c478bd9Sstevel@tonic-gate **  TRANSIENTERROR -- tell if an error code indicates a transient failure
34817c478bd9Sstevel@tonic-gate **
34827c478bd9Sstevel@tonic-gate **	This looks at an errno value and tells if this is likely to
34837c478bd9Sstevel@tonic-gate **	go away if retried later.
34847c478bd9Sstevel@tonic-gate **
34857c478bd9Sstevel@tonic-gate **	Parameters:
34867c478bd9Sstevel@tonic-gate **		err -- the errno code to classify.
34877c478bd9Sstevel@tonic-gate **
34887c478bd9Sstevel@tonic-gate **	Returns:
34897c478bd9Sstevel@tonic-gate **		true if this is probably transient.
34907c478bd9Sstevel@tonic-gate **		false otherwise.
34917c478bd9Sstevel@tonic-gate */
34927c478bd9Sstevel@tonic-gate 
34937c478bd9Sstevel@tonic-gate bool
34947c478bd9Sstevel@tonic-gate transienterror(err)
34957c478bd9Sstevel@tonic-gate 	int err;
34967c478bd9Sstevel@tonic-gate {
34977c478bd9Sstevel@tonic-gate 	switch (err)
34987c478bd9Sstevel@tonic-gate 	{
34997c478bd9Sstevel@tonic-gate 	  case EIO:			/* I/O error */
35007c478bd9Sstevel@tonic-gate 	  case ENXIO:			/* Device not configured */
35017c478bd9Sstevel@tonic-gate 	  case EAGAIN:			/* Resource temporarily unavailable */
35027c478bd9Sstevel@tonic-gate 	  case ENOMEM:			/* Cannot allocate memory */
35037c478bd9Sstevel@tonic-gate 	  case ENODEV:			/* Operation not supported by device */
35047c478bd9Sstevel@tonic-gate 	  case ENFILE:			/* Too many open files in system */
35057c478bd9Sstevel@tonic-gate 	  case EMFILE:			/* Too many open files */
35067c478bd9Sstevel@tonic-gate 	  case ENOSPC:			/* No space left on device */
35077c478bd9Sstevel@tonic-gate 	  case ETIMEDOUT:		/* Connection timed out */
35087c478bd9Sstevel@tonic-gate #ifdef ESTALE
35097c478bd9Sstevel@tonic-gate 	  case ESTALE:			/* Stale NFS file handle */
35107c478bd9Sstevel@tonic-gate #endif /* ESTALE */
35117c478bd9Sstevel@tonic-gate #ifdef ENETDOWN
35127c478bd9Sstevel@tonic-gate 	  case ENETDOWN:		/* Network is down */
35137c478bd9Sstevel@tonic-gate #endif /* ENETDOWN */
35147c478bd9Sstevel@tonic-gate #ifdef ENETUNREACH
35157c478bd9Sstevel@tonic-gate 	  case ENETUNREACH:		/* Network is unreachable */
35167c478bd9Sstevel@tonic-gate #endif /* ENETUNREACH */
35177c478bd9Sstevel@tonic-gate #ifdef ENETRESET
35187c478bd9Sstevel@tonic-gate 	  case ENETRESET:		/* Network dropped connection on reset */
35197c478bd9Sstevel@tonic-gate #endif /* ENETRESET */
35207c478bd9Sstevel@tonic-gate #ifdef ECONNABORTED
35217c478bd9Sstevel@tonic-gate 	  case ECONNABORTED:		/* Software caused connection abort */
35227c478bd9Sstevel@tonic-gate #endif /* ECONNABORTED */
35237c478bd9Sstevel@tonic-gate #ifdef ECONNRESET
35247c478bd9Sstevel@tonic-gate 	  case ECONNRESET:		/* Connection reset by peer */
35257c478bd9Sstevel@tonic-gate #endif /* ECONNRESET */
35267c478bd9Sstevel@tonic-gate #ifdef ENOBUFS
35277c478bd9Sstevel@tonic-gate 	  case ENOBUFS:			/* No buffer space available */
35287c478bd9Sstevel@tonic-gate #endif /* ENOBUFS */
35297c478bd9Sstevel@tonic-gate #ifdef ESHUTDOWN
35307c478bd9Sstevel@tonic-gate 	  case ESHUTDOWN:		/* Can't send after socket shutdown */
35317c478bd9Sstevel@tonic-gate #endif /* ESHUTDOWN */
35327c478bd9Sstevel@tonic-gate #ifdef ECONNREFUSED
35337c478bd9Sstevel@tonic-gate 	  case ECONNREFUSED:		/* Connection refused */
35347c478bd9Sstevel@tonic-gate #endif /* ECONNREFUSED */
35357c478bd9Sstevel@tonic-gate #ifdef EHOSTDOWN
35367c478bd9Sstevel@tonic-gate 	  case EHOSTDOWN:		/* Host is down */
35377c478bd9Sstevel@tonic-gate #endif /* EHOSTDOWN */
35387c478bd9Sstevel@tonic-gate #ifdef EHOSTUNREACH
35397c478bd9Sstevel@tonic-gate 	  case EHOSTUNREACH:		/* No route to host */
35407c478bd9Sstevel@tonic-gate #endif /* EHOSTUNREACH */
35417c478bd9Sstevel@tonic-gate #ifdef EDQUOT
35427c478bd9Sstevel@tonic-gate 	  case EDQUOT:			/* Disc quota exceeded */
35437c478bd9Sstevel@tonic-gate #endif /* EDQUOT */
35447c478bd9Sstevel@tonic-gate #ifdef EPROCLIM
35457c478bd9Sstevel@tonic-gate 	  case EPROCLIM:		/* Too many processes */
35467c478bd9Sstevel@tonic-gate #endif /* EPROCLIM */
35477c478bd9Sstevel@tonic-gate #ifdef EUSERS
35487c478bd9Sstevel@tonic-gate 	  case EUSERS:			/* Too many users */
35497c478bd9Sstevel@tonic-gate #endif /* EUSERS */
35507c478bd9Sstevel@tonic-gate #ifdef EDEADLK
35517c478bd9Sstevel@tonic-gate 	  case EDEADLK:			/* Resource deadlock avoided */
35527c478bd9Sstevel@tonic-gate #endif /* EDEADLK */
35537c478bd9Sstevel@tonic-gate #ifdef EISCONN
35547c478bd9Sstevel@tonic-gate 	  case EISCONN:			/* Socket already connected */
35557c478bd9Sstevel@tonic-gate #endif /* EISCONN */
35567c478bd9Sstevel@tonic-gate #ifdef EINPROGRESS
35577c478bd9Sstevel@tonic-gate 	  case EINPROGRESS:		/* Operation now in progress */
35587c478bd9Sstevel@tonic-gate #endif /* EINPROGRESS */
35597c478bd9Sstevel@tonic-gate #ifdef EALREADY
35607c478bd9Sstevel@tonic-gate 	  case EALREADY:		/* Operation already in progress */
35617c478bd9Sstevel@tonic-gate #endif /* EALREADY */
35627c478bd9Sstevel@tonic-gate #ifdef EADDRINUSE
35637c478bd9Sstevel@tonic-gate 	  case EADDRINUSE:		/* Address already in use */
35647c478bd9Sstevel@tonic-gate #endif /* EADDRINUSE */
35657c478bd9Sstevel@tonic-gate #ifdef EADDRNOTAVAIL
35667c478bd9Sstevel@tonic-gate 	  case EADDRNOTAVAIL:		/* Can't assign requested address */
35677c478bd9Sstevel@tonic-gate #endif /* EADDRNOTAVAIL */
35687c478bd9Sstevel@tonic-gate #ifdef ETXTBSY
35697c478bd9Sstevel@tonic-gate 	  case ETXTBSY:			/* (Apollo) file locked */
35707c478bd9Sstevel@tonic-gate #endif /* ETXTBSY */
35717c478bd9Sstevel@tonic-gate #if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
35727c478bd9Sstevel@tonic-gate 	  case ENOSR:			/* Out of streams resources */
35737c478bd9Sstevel@tonic-gate #endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */
35747c478bd9Sstevel@tonic-gate #ifdef ENOLCK
35757c478bd9Sstevel@tonic-gate 	  case ENOLCK:			/* No locks available */
35767c478bd9Sstevel@tonic-gate #endif /* ENOLCK */
35777c478bd9Sstevel@tonic-gate 	  case E_SM_OPENTIMEOUT:	/* PSEUDO: open timed out */
35787c478bd9Sstevel@tonic-gate 		return true;
35797c478bd9Sstevel@tonic-gate 	}
35807c478bd9Sstevel@tonic-gate 
35817c478bd9Sstevel@tonic-gate 	/* nope, must be permanent */
35827c478bd9Sstevel@tonic-gate 	return false;
35837c478bd9Sstevel@tonic-gate }
35847c478bd9Sstevel@tonic-gate /*
35857c478bd9Sstevel@tonic-gate **  LOCKFILE -- lock a file using flock or (shudder) fcntl locking
35867c478bd9Sstevel@tonic-gate **
35877c478bd9Sstevel@tonic-gate **	Parameters:
35887c478bd9Sstevel@tonic-gate **		fd -- the file descriptor of the file.
35897c478bd9Sstevel@tonic-gate **		filename -- the file name (for error messages).
35907c478bd9Sstevel@tonic-gate **		ext -- the filename extension.
35917c478bd9Sstevel@tonic-gate **		type -- type of the lock.  Bits can be:
35927c478bd9Sstevel@tonic-gate **			LOCK_EX -- exclusive lock.
35937c478bd9Sstevel@tonic-gate **			LOCK_NB -- non-blocking.
35947c478bd9Sstevel@tonic-gate **			LOCK_UN -- unlock.
35957c478bd9Sstevel@tonic-gate **
35967c478bd9Sstevel@tonic-gate **	Returns:
35977c478bd9Sstevel@tonic-gate **		true if the lock was acquired.
35987c478bd9Sstevel@tonic-gate **		false otherwise.
35997c478bd9Sstevel@tonic-gate */
36007c478bd9Sstevel@tonic-gate 
36017c478bd9Sstevel@tonic-gate bool
36027c478bd9Sstevel@tonic-gate lockfile(fd, filename, ext, type)
36037c478bd9Sstevel@tonic-gate 	int fd;
36047c478bd9Sstevel@tonic-gate 	char *filename;
36057c478bd9Sstevel@tonic-gate 	char *ext;
36067c478bd9Sstevel@tonic-gate 	int type;
36077c478bd9Sstevel@tonic-gate {
36087c478bd9Sstevel@tonic-gate 	int i;
36097c478bd9Sstevel@tonic-gate 	int save_errno;
36107c478bd9Sstevel@tonic-gate # if !HASFLOCK
36117c478bd9Sstevel@tonic-gate 	int action;
36127c478bd9Sstevel@tonic-gate 	struct flock lfd;
36137c478bd9Sstevel@tonic-gate 
36147c478bd9Sstevel@tonic-gate 	if (ext == NULL)
36157c478bd9Sstevel@tonic-gate 		ext = "";
36167c478bd9Sstevel@tonic-gate 
36177c478bd9Sstevel@tonic-gate 	memset(&lfd, '\0', sizeof lfd);
36187c478bd9Sstevel@tonic-gate 	if (bitset(LOCK_UN, type))
36197c478bd9Sstevel@tonic-gate 		lfd.l_type = F_UNLCK;
36207c478bd9Sstevel@tonic-gate 	else if (bitset(LOCK_EX, type))
36217c478bd9Sstevel@tonic-gate 		lfd.l_type = F_WRLCK;
36227c478bd9Sstevel@tonic-gate 	else
36237c478bd9Sstevel@tonic-gate 		lfd.l_type = F_RDLCK;
36247c478bd9Sstevel@tonic-gate 
36257c478bd9Sstevel@tonic-gate 	if (bitset(LOCK_NB, type))
36267c478bd9Sstevel@tonic-gate 		action = F_SETLK;
36277c478bd9Sstevel@tonic-gate 	else
36287c478bd9Sstevel@tonic-gate 		action = F_SETLKW;
36297c478bd9Sstevel@tonic-gate 
36307c478bd9Sstevel@tonic-gate 	if (tTd(55, 60))
36317c478bd9Sstevel@tonic-gate 		sm_dprintf("lockfile(%s%s, action=%d, type=%d): ",
36327c478bd9Sstevel@tonic-gate 			filename, ext, action, lfd.l_type);
36337c478bd9Sstevel@tonic-gate 
36347c478bd9Sstevel@tonic-gate 	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
36357c478bd9Sstevel@tonic-gate 		continue;
36367c478bd9Sstevel@tonic-gate 	if (i >= 0)
36377c478bd9Sstevel@tonic-gate 	{
36387c478bd9Sstevel@tonic-gate 		if (tTd(55, 60))
36397c478bd9Sstevel@tonic-gate 			sm_dprintf("SUCCESS\n");
36407c478bd9Sstevel@tonic-gate 		return true;
36417c478bd9Sstevel@tonic-gate 	}
36427c478bd9Sstevel@tonic-gate 	save_errno = errno;
36437c478bd9Sstevel@tonic-gate 
36447c478bd9Sstevel@tonic-gate 	if (tTd(55, 60))
36457c478bd9Sstevel@tonic-gate 		sm_dprintf("(%s) ", sm_errstring(save_errno));
36467c478bd9Sstevel@tonic-gate 
36477c478bd9Sstevel@tonic-gate 	/*
36487c478bd9Sstevel@tonic-gate 	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
36497c478bd9Sstevel@tonic-gate 	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
36507c478bd9Sstevel@tonic-gate 	**  as type "tmp" (that is, served from swap space), the
36517c478bd9Sstevel@tonic-gate 	**  previous fcntl will fail with "Invalid argument" errors.
36527c478bd9Sstevel@tonic-gate 	**  Since this is fairly common during testing, we will assume
36537c478bd9Sstevel@tonic-gate 	**  that this indicates that the lock is successfully grabbed.
36547c478bd9Sstevel@tonic-gate 	*/
36557c478bd9Sstevel@tonic-gate 
36567c478bd9Sstevel@tonic-gate 	if (save_errno == EINVAL)
36577c478bd9Sstevel@tonic-gate 	{
36587c478bd9Sstevel@tonic-gate 		if (tTd(55, 60))
36597c478bd9Sstevel@tonic-gate 			sm_dprintf("SUCCESS\n");
36607c478bd9Sstevel@tonic-gate 		return true;
36617c478bd9Sstevel@tonic-gate 	}
36627c478bd9Sstevel@tonic-gate 
36637c478bd9Sstevel@tonic-gate 	if (!bitset(LOCK_NB, type) ||
36647c478bd9Sstevel@tonic-gate 	    (save_errno != EACCES && save_errno != EAGAIN))
36657c478bd9Sstevel@tonic-gate 	{
36667c478bd9Sstevel@tonic-gate 		int omode = fcntl(fd, F_GETFL, 0);
36677c478bd9Sstevel@tonic-gate 		uid_t euid = geteuid();
36687c478bd9Sstevel@tonic-gate 
36697c478bd9Sstevel@tonic-gate 		errno = save_errno;
36707c478bd9Sstevel@tonic-gate 		syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
36717c478bd9Sstevel@tonic-gate 		       filename, ext, fd, type, omode, euid);
36727c478bd9Sstevel@tonic-gate 		dumpfd(fd, true, true);
36737c478bd9Sstevel@tonic-gate 	}
36747c478bd9Sstevel@tonic-gate # else /* !HASFLOCK */
36757c478bd9Sstevel@tonic-gate 	if (ext == NULL)
36767c478bd9Sstevel@tonic-gate 		ext = "";
36777c478bd9Sstevel@tonic-gate 
36787c478bd9Sstevel@tonic-gate 	if (tTd(55, 60))
36797c478bd9Sstevel@tonic-gate 		sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type);
36807c478bd9Sstevel@tonic-gate 
36817c478bd9Sstevel@tonic-gate 	while ((i = flock(fd, type)) < 0 && errno == EINTR)
36827c478bd9Sstevel@tonic-gate 		continue;
36837c478bd9Sstevel@tonic-gate 	if (i >= 0)
36847c478bd9Sstevel@tonic-gate 	{
36857c478bd9Sstevel@tonic-gate 		if (tTd(55, 60))
36867c478bd9Sstevel@tonic-gate 			sm_dprintf("SUCCESS\n");
36877c478bd9Sstevel@tonic-gate 		return true;
36887c478bd9Sstevel@tonic-gate 	}
36897c478bd9Sstevel@tonic-gate 	save_errno = errno;
36907c478bd9Sstevel@tonic-gate 
36917c478bd9Sstevel@tonic-gate 	if (tTd(55, 60))
36927c478bd9Sstevel@tonic-gate 		sm_dprintf("(%s) ", sm_errstring(save_errno));
36937c478bd9Sstevel@tonic-gate 
36947c478bd9Sstevel@tonic-gate 	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
36957c478bd9Sstevel@tonic-gate 	{
36967c478bd9Sstevel@tonic-gate 		int omode = fcntl(fd, F_GETFL, 0);
36977c478bd9Sstevel@tonic-gate 		uid_t euid = geteuid();
36987c478bd9Sstevel@tonic-gate 
36997c478bd9Sstevel@tonic-gate 		errno = save_errno;
37007c478bd9Sstevel@tonic-gate 		syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
37017c478bd9Sstevel@tonic-gate 			filename, ext, fd, type, omode, euid);
37027c478bd9Sstevel@tonic-gate 		dumpfd(fd, true, true);
37037c478bd9Sstevel@tonic-gate 	}
37047c478bd9Sstevel@tonic-gate # endif /* !HASFLOCK */
37057c478bd9Sstevel@tonic-gate 	if (tTd(55, 60))
37067c478bd9Sstevel@tonic-gate 		sm_dprintf("FAIL\n");
37077c478bd9Sstevel@tonic-gate 	errno = save_errno;
37087c478bd9Sstevel@tonic-gate 	return false;
37097c478bd9Sstevel@tonic-gate }
37107c478bd9Sstevel@tonic-gate /*
37117c478bd9Sstevel@tonic-gate **  CHOWNSAFE -- tell if chown is "safe" (executable only by root)
37127c478bd9Sstevel@tonic-gate **
37137c478bd9Sstevel@tonic-gate **	Unfortunately, given that we can't predict other systems on which
37147c478bd9Sstevel@tonic-gate **	a remote mounted (NFS) filesystem will be mounted, the answer is
37157c478bd9Sstevel@tonic-gate **	almost always that this is unsafe.
37167c478bd9Sstevel@tonic-gate **
37177c478bd9Sstevel@tonic-gate **	Note also that many operating systems have non-compliant
37187c478bd9Sstevel@tonic-gate **	implementations of the _POSIX_CHOWN_RESTRICTED variable and the
37197c478bd9Sstevel@tonic-gate **	fpathconf() routine.  According to IEEE 1003.1-1990, if
37207c478bd9Sstevel@tonic-gate **	_POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
37217c478bd9Sstevel@tonic-gate **	no non-root process can give away the file.  However, vendors
37227c478bd9Sstevel@tonic-gate **	don't take NFS into account, so a comfortable value of
37237c478bd9Sstevel@tonic-gate **	_POSIX_CHOWN_RESTRICTED tells us nothing.
37247c478bd9Sstevel@tonic-gate **
37257c478bd9Sstevel@tonic-gate **	Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
37267c478bd9Sstevel@tonic-gate **	even on files where chown is not restricted.  Many systems get
37277c478bd9Sstevel@tonic-gate **	this wrong on NFS-based filesystems (that is, they say that chown
37287c478bd9Sstevel@tonic-gate **	is restricted [safe] on NFS filesystems where it may not be, since
37297c478bd9Sstevel@tonic-gate **	other systems can access the same filesystem and do file giveaway;
37307c478bd9Sstevel@tonic-gate **	only the NFS server knows for sure!)  Hence, it is important to
37317c478bd9Sstevel@tonic-gate **	get the value of SAFENFSPATHCONF correct -- it should be defined
37327c478bd9Sstevel@tonic-gate **	_only_ after testing (see test/t_pathconf.c) a system on an unsafe
37337c478bd9Sstevel@tonic-gate **	NFS-based filesystem to ensure that you can get meaningful results.
37347c478bd9Sstevel@tonic-gate **	If in doubt, assume unsafe!
37357c478bd9Sstevel@tonic-gate **
37367c478bd9Sstevel@tonic-gate **	You may also need to tweak IS_SAFE_CHOWN -- it should be a
37377c478bd9Sstevel@tonic-gate **	condition indicating whether the return from pathconf indicates
37387c478bd9Sstevel@tonic-gate **	that chown is safe (typically either > 0 or >= 0 -- there isn't
37397c478bd9Sstevel@tonic-gate **	even any agreement about whether a zero return means that a file
37407c478bd9Sstevel@tonic-gate **	is or is not safe).  It defaults to "> 0".
37417c478bd9Sstevel@tonic-gate **
37427c478bd9Sstevel@tonic-gate **	If the parent directory is safe (writable only by owner back
37437c478bd9Sstevel@tonic-gate **	to the root) then we can relax slightly and trust fpathconf
37447c478bd9Sstevel@tonic-gate **	in more circumstances.  This is really a crock -- if this is an
37457c478bd9Sstevel@tonic-gate **	NFS mounted filesystem then we really know nothing about the
37467c478bd9Sstevel@tonic-gate **	underlying implementation.  However, most systems pessimize and
37477c478bd9Sstevel@tonic-gate **	return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
37487c478bd9Sstevel@tonic-gate **	we interpret as unsafe, as we should.  Thus, this heuristic gets
37497c478bd9Sstevel@tonic-gate **	us into a possible problem only on systems that have a broken
37507c478bd9Sstevel@tonic-gate **	pathconf implementation and which are also poorly configured
37517c478bd9Sstevel@tonic-gate **	(have :include: files in group- or world-writable directories).
37527c478bd9Sstevel@tonic-gate **
37537c478bd9Sstevel@tonic-gate **	Parameters:
37547c478bd9Sstevel@tonic-gate **		fd -- the file descriptor to check.
37557c478bd9Sstevel@tonic-gate **		safedir -- set if the parent directory is safe.
37567c478bd9Sstevel@tonic-gate **
37577c478bd9Sstevel@tonic-gate **	Returns:
37587c478bd9Sstevel@tonic-gate **		true -- if the chown(2) operation is "safe" -- that is,
37597c478bd9Sstevel@tonic-gate **			only root can chown the file to an arbitrary user.
37607c478bd9Sstevel@tonic-gate **		false -- if an arbitrary user can give away a file.
37617c478bd9Sstevel@tonic-gate */
37627c478bd9Sstevel@tonic-gate 
37637c478bd9Sstevel@tonic-gate #ifndef IS_SAFE_CHOWN
37647c478bd9Sstevel@tonic-gate # define IS_SAFE_CHOWN	> 0
37657c478bd9Sstevel@tonic-gate #endif /* ! IS_SAFE_CHOWN */
37667c478bd9Sstevel@tonic-gate 
37677c478bd9Sstevel@tonic-gate bool
37687c478bd9Sstevel@tonic-gate chownsafe(fd, safedir)
37697c478bd9Sstevel@tonic-gate 	int fd;
37707c478bd9Sstevel@tonic-gate 	bool safedir;
37717c478bd9Sstevel@tonic-gate {
37727c478bd9Sstevel@tonic-gate # if (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \
37737c478bd9Sstevel@tonic-gate     (defined(_PC_CHOWN_RESTRICTED) || defined(_GNU_TYPES_H))
37747c478bd9Sstevel@tonic-gate 	int rval;
37757c478bd9Sstevel@tonic-gate 
37767c478bd9Sstevel@tonic-gate 	/* give the system administrator a chance to override */
37777c478bd9Sstevel@tonic-gate 	if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail))
37787c478bd9Sstevel@tonic-gate 		return true;
37797c478bd9Sstevel@tonic-gate 
37807c478bd9Sstevel@tonic-gate 	/*
37817c478bd9Sstevel@tonic-gate 	**  Some systems (e.g., SunOS) seem to have the call and the
37827c478bd9Sstevel@tonic-gate 	**  #define _PC_CHOWN_RESTRICTED, but don't actually implement
37837c478bd9Sstevel@tonic-gate 	**  the call.  This heuristic checks for that.
37847c478bd9Sstevel@tonic-gate 	*/
37857c478bd9Sstevel@tonic-gate 
37867c478bd9Sstevel@tonic-gate 	errno = 0;
37877c478bd9Sstevel@tonic-gate 	rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
37887c478bd9Sstevel@tonic-gate #  if SAFENFSPATHCONF
37897c478bd9Sstevel@tonic-gate 	return errno == 0 && rval IS_SAFE_CHOWN;
37907c478bd9Sstevel@tonic-gate #  else /* SAFENFSPATHCONF */
37917c478bd9Sstevel@tonic-gate 	return safedir && errno == 0 && rval IS_SAFE_CHOWN;
37927c478bd9Sstevel@tonic-gate #  endif /* SAFENFSPATHCONF */
37937c478bd9Sstevel@tonic-gate # else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
37947c478bd9Sstevel@tonic-gate 	return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
37957c478bd9Sstevel@tonic-gate # endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
37967c478bd9Sstevel@tonic-gate }
37977c478bd9Sstevel@tonic-gate /*
37987c478bd9Sstevel@tonic-gate **  RESETLIMITS -- reset system controlled resource limits
37997c478bd9Sstevel@tonic-gate **
38007c478bd9Sstevel@tonic-gate **	This is to avoid denial-of-service attacks
38017c478bd9Sstevel@tonic-gate **
38027c478bd9Sstevel@tonic-gate **	Parameters:
38037c478bd9Sstevel@tonic-gate **		none
38047c478bd9Sstevel@tonic-gate **
38057c478bd9Sstevel@tonic-gate **	Returns:
38067c478bd9Sstevel@tonic-gate **		none
38077c478bd9Sstevel@tonic-gate */
38087c478bd9Sstevel@tonic-gate 
38097c478bd9Sstevel@tonic-gate #if HASSETRLIMIT
38107c478bd9Sstevel@tonic-gate # ifdef RLIMIT_NEEDS_SYS_TIME_H
381149218d4fSjbeck #  include <sm/time.h>
38127c478bd9Sstevel@tonic-gate # endif /* RLIMIT_NEEDS_SYS_TIME_H */
38137c478bd9Sstevel@tonic-gate # include <sys/resource.h>
38147c478bd9Sstevel@tonic-gate #endif /* HASSETRLIMIT */
38157c478bd9Sstevel@tonic-gate 
38167c478bd9Sstevel@tonic-gate void
38177c478bd9Sstevel@tonic-gate resetlimits()
38187c478bd9Sstevel@tonic-gate {
38197c478bd9Sstevel@tonic-gate #if HASSETRLIMIT
38207c478bd9Sstevel@tonic-gate 	struct rlimit lim;
38217c478bd9Sstevel@tonic-gate 
38227c478bd9Sstevel@tonic-gate 	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
38237c478bd9Sstevel@tonic-gate 	(void) setrlimit(RLIMIT_CPU, &lim);
38247c478bd9Sstevel@tonic-gate 	(void) setrlimit(RLIMIT_FSIZE, &lim);
38257c478bd9Sstevel@tonic-gate # ifdef RLIMIT_NOFILE
38267c478bd9Sstevel@tonic-gate 	lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
38277c478bd9Sstevel@tonic-gate 	(void) setrlimit(RLIMIT_NOFILE, &lim);
38287c478bd9Sstevel@tonic-gate # endif /* RLIMIT_NOFILE */
38297c478bd9Sstevel@tonic-gate #else /* HASSETRLIMIT */
38307c478bd9Sstevel@tonic-gate # if HASULIMIT
38317c478bd9Sstevel@tonic-gate 	(void) ulimit(2, 0x3fffff);
38327c478bd9Sstevel@tonic-gate 	(void) ulimit(4, FD_SETSIZE);
38337c478bd9Sstevel@tonic-gate # endif /* HASULIMIT */
38347c478bd9Sstevel@tonic-gate #endif /* HASSETRLIMIT */
38357c478bd9Sstevel@tonic-gate 	errno = 0;
38367c478bd9Sstevel@tonic-gate }
38377c478bd9Sstevel@tonic-gate /*
38387c478bd9Sstevel@tonic-gate **  SETVENDOR -- process vendor code from V configuration line
38397c478bd9Sstevel@tonic-gate **
38407c478bd9Sstevel@tonic-gate **	Parameters:
38417c478bd9Sstevel@tonic-gate **		vendor -- string representation of vendor.
38427c478bd9Sstevel@tonic-gate **
38437c478bd9Sstevel@tonic-gate **	Returns:
38447c478bd9Sstevel@tonic-gate **		true -- if ok.
38457c478bd9Sstevel@tonic-gate **		false -- if vendor code could not be processed.
38467c478bd9Sstevel@tonic-gate **
38477c478bd9Sstevel@tonic-gate **	Side Effects:
38487c478bd9Sstevel@tonic-gate **		It is reasonable to set mode flags here to tweak
38497c478bd9Sstevel@tonic-gate **		processing in other parts of the code if necessary.
38507c478bd9Sstevel@tonic-gate **		For example, if you are a vendor that uses $%y to
38517c478bd9Sstevel@tonic-gate **		indicate YP lookups, you could enable that here.
38527c478bd9Sstevel@tonic-gate */
38537c478bd9Sstevel@tonic-gate 
38547c478bd9Sstevel@tonic-gate bool
38557c478bd9Sstevel@tonic-gate setvendor(vendor)
38567c478bd9Sstevel@tonic-gate 	char *vendor;
38577c478bd9Sstevel@tonic-gate {
38587c478bd9Sstevel@tonic-gate 	if (sm_strcasecmp(vendor, "Berkeley") == 0)
38597c478bd9Sstevel@tonic-gate 	{
38607c478bd9Sstevel@tonic-gate 		VendorCode = VENDOR_BERKELEY;
38617c478bd9Sstevel@tonic-gate 		return true;
38627c478bd9Sstevel@tonic-gate 	}
38637c478bd9Sstevel@tonic-gate 
38647c478bd9Sstevel@tonic-gate 	/* add vendor extensions here */
38657c478bd9Sstevel@tonic-gate 
38667c478bd9Sstevel@tonic-gate #ifdef SUN_EXTENSIONS
38677c478bd9Sstevel@tonic-gate 	if (sm_strcasecmp(vendor, "Sun") == 0)
38687c478bd9Sstevel@tonic-gate 	{
38697c478bd9Sstevel@tonic-gate 		VendorCode = VENDOR_SUN;
38707c478bd9Sstevel@tonic-gate 		return true;
38717c478bd9Sstevel@tonic-gate 	}
38727c478bd9Sstevel@tonic-gate #endif /* SUN_EXTENSIONS */
387349218d4fSjbeck #ifdef DEC
387449218d4fSjbeck 	if (sm_strcasecmp(vendor, "Digital") == 0)
387549218d4fSjbeck 	{
387649218d4fSjbeck 		VendorCode = VENDOR_DEC;
387749218d4fSjbeck 		return true;
387849218d4fSjbeck 	}
387949218d4fSjbeck #endif /* DEC */
38807c478bd9Sstevel@tonic-gate 
38817c478bd9Sstevel@tonic-gate #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
38827c478bd9Sstevel@tonic-gate 	if (sm_strcasecmp(vendor, VENDOR_NAME) == 0)
38837c478bd9Sstevel@tonic-gate 	{
38847c478bd9Sstevel@tonic-gate 		VendorCode = VENDOR_CODE;
38857c478bd9Sstevel@tonic-gate 		return true;
38867c478bd9Sstevel@tonic-gate 	}
38877c478bd9Sstevel@tonic-gate #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
38887c478bd9Sstevel@tonic-gate 
38897c478bd9Sstevel@tonic-gate 	return false;
38907c478bd9Sstevel@tonic-gate }
38917c478bd9Sstevel@tonic-gate /*
38927c478bd9Sstevel@tonic-gate **  GETVENDOR -- return vendor name based on vendor code
38937c478bd9Sstevel@tonic-gate **
38947c478bd9Sstevel@tonic-gate **	Parameters:
38957c478bd9Sstevel@tonic-gate **		vendorcode -- numeric representation of vendor.
38967c478bd9Sstevel@tonic-gate **
38977c478bd9Sstevel@tonic-gate **	Returns:
38987c478bd9Sstevel@tonic-gate **		string containing vendor name.
38997c478bd9Sstevel@tonic-gate */
39007c478bd9Sstevel@tonic-gate 
39017c478bd9Sstevel@tonic-gate char *
39027c478bd9Sstevel@tonic-gate getvendor(vendorcode)
39037c478bd9Sstevel@tonic-gate 	int vendorcode;
39047c478bd9Sstevel@tonic-gate {
39057c478bd9Sstevel@tonic-gate #if defined(VENDOR_NAME) && defined(VENDOR_CODE)
39067c478bd9Sstevel@tonic-gate 	/*
39077c478bd9Sstevel@tonic-gate 	**  Can't have the same switch case twice so need to
39087c478bd9Sstevel@tonic-gate 	**  handle VENDOR_CODE outside of switch.  It might
39097c478bd9Sstevel@tonic-gate 	**  match one of the existing VENDOR_* codes.
39107c478bd9Sstevel@tonic-gate 	*/
39117c478bd9Sstevel@tonic-gate 
39127c478bd9Sstevel@tonic-gate 	if (vendorcode == VENDOR_CODE)
39137c478bd9Sstevel@tonic-gate 		return VENDOR_NAME;
39147c478bd9Sstevel@tonic-gate #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */
39157c478bd9Sstevel@tonic-gate 
39167c478bd9Sstevel@tonic-gate 	switch (vendorcode)
39177c478bd9Sstevel@tonic-gate 	{
39187c478bd9Sstevel@tonic-gate 	  case VENDOR_BERKELEY:
39197c478bd9Sstevel@tonic-gate 		return "Berkeley";
39207c478bd9Sstevel@tonic-gate 
39217c478bd9Sstevel@tonic-gate 	  case VENDOR_SUN:
39227c478bd9Sstevel@tonic-gate 		return "Sun";
39237c478bd9Sstevel@tonic-gate 
39247c478bd9Sstevel@tonic-gate 	  case VENDOR_HP:
39257c478bd9Sstevel@tonic-gate 		return "HP";
39267c478bd9Sstevel@tonic-gate 
39277c478bd9Sstevel@tonic-gate 	  case VENDOR_IBM:
39287c478bd9Sstevel@tonic-gate 		return "IBM";
39297c478bd9Sstevel@tonic-gate 
39307c478bd9Sstevel@tonic-gate 	  case VENDOR_SENDMAIL:
39317c478bd9Sstevel@tonic-gate 		return "Sendmail";
39327c478bd9Sstevel@tonic-gate 
39337c478bd9Sstevel@tonic-gate 	  default:
39347c478bd9Sstevel@tonic-gate 		return "Unknown";
39357c478bd9Sstevel@tonic-gate 	}
39367c478bd9Sstevel@tonic-gate }
39377c478bd9Sstevel@tonic-gate /*
39387c478bd9Sstevel@tonic-gate **  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
39397c478bd9Sstevel@tonic-gate **
39407c478bd9Sstevel@tonic-gate **	Vendor_pre_defaults is called before reading the configuration
39417c478bd9Sstevel@tonic-gate **	file; vendor_post_defaults is called immediately after.
39427c478bd9Sstevel@tonic-gate **
39437c478bd9Sstevel@tonic-gate **	Parameters:
39447c478bd9Sstevel@tonic-gate **		e -- the global environment to initialize.
39457c478bd9Sstevel@tonic-gate **
39467c478bd9Sstevel@tonic-gate **	Returns:
39477c478bd9Sstevel@tonic-gate **		none.
39487c478bd9Sstevel@tonic-gate */
39497c478bd9Sstevel@tonic-gate 
39507c478bd9Sstevel@tonic-gate #if SHARE_V1
39517c478bd9Sstevel@tonic-gate int	DefShareUid;	/* default share uid to run as -- unused??? */
39527c478bd9Sstevel@tonic-gate #endif /* SHARE_V1 */
39537c478bd9Sstevel@tonic-gate 
39547c478bd9Sstevel@tonic-gate void
39557c478bd9Sstevel@tonic-gate vendor_pre_defaults(e)
39567c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
39577c478bd9Sstevel@tonic-gate {
39587c478bd9Sstevel@tonic-gate #if SHARE_V1
39597c478bd9Sstevel@tonic-gate 	/* OTHERUID is defined in shares.h, do not be alarmed */
39607c478bd9Sstevel@tonic-gate 	DefShareUid = OTHERUID;
39617c478bd9Sstevel@tonic-gate #endif /* SHARE_V1 */
39627c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
39637c478bd9Sstevel@tonic-gate 	sun_pre_defaults(e);
39647c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
39657c478bd9Sstevel@tonic-gate #ifdef apollo
39667c478bd9Sstevel@tonic-gate 	/*
39677c478bd9Sstevel@tonic-gate 	**  stupid domain/os can't even open
39687c478bd9Sstevel@tonic-gate 	**  /etc/mail/sendmail.cf without this
39697c478bd9Sstevel@tonic-gate 	*/
39707c478bd9Sstevel@tonic-gate 
3971445f2479Sjbeck 	sm_setuserenv("ISP", NULL);
3972445f2479Sjbeck 	sm_setuserenv("SYSTYPE", NULL);
39737c478bd9Sstevel@tonic-gate #endif /* apollo */
39747c478bd9Sstevel@tonic-gate }
39757c478bd9Sstevel@tonic-gate 
39767c478bd9Sstevel@tonic-gate 
39777c478bd9Sstevel@tonic-gate void
39787c478bd9Sstevel@tonic-gate vendor_post_defaults(e)
39797c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
39807c478bd9Sstevel@tonic-gate {
39817c478bd9Sstevel@tonic-gate #ifdef __QNX__
39827c478bd9Sstevel@tonic-gate 	char *p;
39837c478bd9Sstevel@tonic-gate 
39847c478bd9Sstevel@tonic-gate 	/* Makes sure the SOCK environment variable remains */
39857c478bd9Sstevel@tonic-gate 	if (p = getextenv("SOCK"))
3986445f2479Sjbeck 		sm_setuserenv("SOCK", p);
39877c478bd9Sstevel@tonic-gate #endif /* __QNX__ */
39887c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
39897c478bd9Sstevel@tonic-gate 	sun_post_defaults(e);
39907c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
39917c478bd9Sstevel@tonic-gate }
39927c478bd9Sstevel@tonic-gate /*
39937c478bd9Sstevel@tonic-gate **  VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
39947c478bd9Sstevel@tonic-gate */
39957c478bd9Sstevel@tonic-gate 
39967c478bd9Sstevel@tonic-gate void
39977c478bd9Sstevel@tonic-gate vendor_daemon_setup(e)
39987c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
39997c478bd9Sstevel@tonic-gate {
40007c478bd9Sstevel@tonic-gate #if HASSETLOGIN
40017c478bd9Sstevel@tonic-gate 	(void) setlogin(RunAsUserName);
40027c478bd9Sstevel@tonic-gate #endif /* HASSETLOGIN */
40037c478bd9Sstevel@tonic-gate #if SECUREWARE
40047c478bd9Sstevel@tonic-gate 	if (getluid() != -1)
40057c478bd9Sstevel@tonic-gate 	{
40067c478bd9Sstevel@tonic-gate 		usrerr("Daemon cannot have LUID");
40077c478bd9Sstevel@tonic-gate 		finis(false, true, EX_USAGE);
40087c478bd9Sstevel@tonic-gate 	}
40097c478bd9Sstevel@tonic-gate #endif /* SECUREWARE */
40107c478bd9Sstevel@tonic-gate }
40117c478bd9Sstevel@tonic-gate /*
40127c478bd9Sstevel@tonic-gate **  VENDOR_SET_UID -- do setup for setting a user id
40137c478bd9Sstevel@tonic-gate **
40147c478bd9Sstevel@tonic-gate **	This is called when we are still root.
40157c478bd9Sstevel@tonic-gate **
40167c478bd9Sstevel@tonic-gate **	Parameters:
40177c478bd9Sstevel@tonic-gate **		uid -- the uid we are about to become.
40187c478bd9Sstevel@tonic-gate **
40197c478bd9Sstevel@tonic-gate **	Returns:
40207c478bd9Sstevel@tonic-gate **		none.
40217c478bd9Sstevel@tonic-gate */
40227c478bd9Sstevel@tonic-gate 
40237c478bd9Sstevel@tonic-gate void
40247c478bd9Sstevel@tonic-gate vendor_set_uid(uid)
40257c478bd9Sstevel@tonic-gate 	UID_T uid;
40267c478bd9Sstevel@tonic-gate {
40277c478bd9Sstevel@tonic-gate 	/*
40287c478bd9Sstevel@tonic-gate 	**  We need to setup the share groups (lnodes)
40297c478bd9Sstevel@tonic-gate 	**  and add auditing information (luid's)
40307c478bd9Sstevel@tonic-gate 	**  before we loose our ``root''ness.
40317c478bd9Sstevel@tonic-gate 	*/
40327c478bd9Sstevel@tonic-gate #if SHARE_V1
40337c478bd9Sstevel@tonic-gate 	if (setupshares(uid, syserr) != 0)
40347c478bd9Sstevel@tonic-gate 		syserr("Unable to set up shares");
40357c478bd9Sstevel@tonic-gate #endif /* SHARE_V1 */
40367c478bd9Sstevel@tonic-gate #if SECUREWARE
40377c478bd9Sstevel@tonic-gate 	(void) setup_secure(uid);
40387c478bd9Sstevel@tonic-gate #endif /* SECUREWARE */
40397c478bd9Sstevel@tonic-gate }
40407c478bd9Sstevel@tonic-gate /*
40417c478bd9Sstevel@tonic-gate **  VALIDATE_CONNECTION -- check connection for rationality
40427c478bd9Sstevel@tonic-gate **
40437c478bd9Sstevel@tonic-gate **	If the connection is rejected, this routine should log an
40447c478bd9Sstevel@tonic-gate **	appropriate message -- but should never issue any SMTP protocol.
40457c478bd9Sstevel@tonic-gate **
40467c478bd9Sstevel@tonic-gate **	Parameters:
40477c478bd9Sstevel@tonic-gate **		sap -- a pointer to a SOCKADDR naming the peer.
40487c478bd9Sstevel@tonic-gate **		hostname -- the name corresponding to sap.
40497c478bd9Sstevel@tonic-gate **		e -- the current envelope.
40507c478bd9Sstevel@tonic-gate **
40517c478bd9Sstevel@tonic-gate **	Returns:
40527c478bd9Sstevel@tonic-gate **		error message from rejection.
40537c478bd9Sstevel@tonic-gate **		NULL if not rejected.
40547c478bd9Sstevel@tonic-gate */
40557c478bd9Sstevel@tonic-gate 
40567c478bd9Sstevel@tonic-gate #if TCPWRAPPERS
40577c478bd9Sstevel@tonic-gate # include <tcpd.h>
40587c478bd9Sstevel@tonic-gate 
40597c478bd9Sstevel@tonic-gate /* tcpwrappers does no logging, but you still have to declare these -- ugh */
40607c478bd9Sstevel@tonic-gate int	allow_severity	= LOG_INFO;
40617c478bd9Sstevel@tonic-gate int	deny_severity	= LOG_NOTICE;
40627c478bd9Sstevel@tonic-gate #endif /* TCPWRAPPERS */
40637c478bd9Sstevel@tonic-gate 
40647c478bd9Sstevel@tonic-gate char *
40657c478bd9Sstevel@tonic-gate validate_connection(sap, hostname, e)
40667c478bd9Sstevel@tonic-gate 	SOCKADDR *sap;
40677c478bd9Sstevel@tonic-gate 	char *hostname;
40687c478bd9Sstevel@tonic-gate 	ENVELOPE *e;
40697c478bd9Sstevel@tonic-gate {
40707c478bd9Sstevel@tonic-gate #if TCPWRAPPERS
40717c478bd9Sstevel@tonic-gate 	char *host;
40727c478bd9Sstevel@tonic-gate 	char *addr;
40737c478bd9Sstevel@tonic-gate 	extern int hosts_ctl();
40747c478bd9Sstevel@tonic-gate #endif /* TCPWRAPPERS */
40757c478bd9Sstevel@tonic-gate 
40767c478bd9Sstevel@tonic-gate 	if (tTd(48, 3))
40777c478bd9Sstevel@tonic-gate 		sm_dprintf("validate_connection(%s, %s)\n",
40787c478bd9Sstevel@tonic-gate 			hostname, anynet_ntoa(sap));
40797c478bd9Sstevel@tonic-gate 
40807c478bd9Sstevel@tonic-gate 	connection_rate_check(sap, e);
40817c478bd9Sstevel@tonic-gate 	if (rscheck("check_relay", hostname, anynet_ntoa(sap),
40827c478bd9Sstevel@tonic-gate 		    e, RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID) != EX_OK)
40837c478bd9Sstevel@tonic-gate 	{
40847c478bd9Sstevel@tonic-gate 		static char reject[BUFSIZ*2];
40857c478bd9Sstevel@tonic-gate 		extern char MsgBuf[];
40867c478bd9Sstevel@tonic-gate 
40877c478bd9Sstevel@tonic-gate 		if (tTd(48, 4))
40887c478bd9Sstevel@tonic-gate 			sm_dprintf("  ... validate_connection: BAD (rscheck)\n");
40897c478bd9Sstevel@tonic-gate 
40907c478bd9Sstevel@tonic-gate 		if (strlen(MsgBuf) >= 3)
40917c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(reject, MsgBuf, sizeof reject);
40927c478bd9Sstevel@tonic-gate 		else
40937c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(reject, "Access denied", sizeof reject);
40947c478bd9Sstevel@tonic-gate 
40957c478bd9Sstevel@tonic-gate 		return reject;
40967c478bd9Sstevel@tonic-gate 	}
40977c478bd9Sstevel@tonic-gate 
40987c478bd9Sstevel@tonic-gate #if TCPWRAPPERS
40997c478bd9Sstevel@tonic-gate 	if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']')
41007c478bd9Sstevel@tonic-gate 		host = "unknown";
41017c478bd9Sstevel@tonic-gate 	else
41027c478bd9Sstevel@tonic-gate 		host = hostname;
41037c478bd9Sstevel@tonic-gate 	addr = anynet_ntoa(sap);
41047c478bd9Sstevel@tonic-gate 
41057c478bd9Sstevel@tonic-gate # if NETINET6
41067c478bd9Sstevel@tonic-gate 	/* TCP/Wrappers don't want the IPv6: protocol label */
41077c478bd9Sstevel@tonic-gate 	if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0)
41087c478bd9Sstevel@tonic-gate 		addr += 5;
41097c478bd9Sstevel@tonic-gate # endif /* NETINET6 */
41107c478bd9Sstevel@tonic-gate 
41117c478bd9Sstevel@tonic-gate 	if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN))
41127c478bd9Sstevel@tonic-gate 	{
41137c478bd9Sstevel@tonic-gate 		if (tTd(48, 4))
41147c478bd9Sstevel@tonic-gate 			sm_dprintf("  ... validate_connection: BAD (tcpwrappers)\n");
41157c478bd9Sstevel@tonic-gate 		if (LogLevel > 3)
41167c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_NOTICE, e->e_id,
41177c478bd9Sstevel@tonic-gate 				  "tcpwrappers (%s, %s) rejection",
41187c478bd9Sstevel@tonic-gate 				  host, addr);
41197c478bd9Sstevel@tonic-gate 		return "Access denied";
41207c478bd9Sstevel@tonic-gate 	}
41217c478bd9Sstevel@tonic-gate #endif /* TCPWRAPPERS */
41227c478bd9Sstevel@tonic-gate 	if (tTd(48, 4))
41237c478bd9Sstevel@tonic-gate 		sm_dprintf("  ... validate_connection: OK\n");
41247c478bd9Sstevel@tonic-gate 	return NULL;
41257c478bd9Sstevel@tonic-gate }
41267c478bd9Sstevel@tonic-gate 
41277c478bd9Sstevel@tonic-gate /*
41287c478bd9Sstevel@tonic-gate **  STRTOL -- convert string to long integer
41297c478bd9Sstevel@tonic-gate **
41307c478bd9Sstevel@tonic-gate **	For systems that don't have it in the C library.
41317c478bd9Sstevel@tonic-gate **
41327c478bd9Sstevel@tonic-gate **	This is taken verbatim from the 4.4-Lite C library.
41337c478bd9Sstevel@tonic-gate */
41347c478bd9Sstevel@tonic-gate 
41357c478bd9Sstevel@tonic-gate #if NEEDSTRTOL
41367c478bd9Sstevel@tonic-gate 
41377c478bd9Sstevel@tonic-gate # if defined(LIBC_SCCS) && !defined(lint)
41387c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)strtol.c	8.1 (Berkeley) 6/4/93";
41397c478bd9Sstevel@tonic-gate # endif /* defined(LIBC_SCCS) && !defined(lint) */
41407c478bd9Sstevel@tonic-gate 
41417c478bd9Sstevel@tonic-gate /*
41427c478bd9Sstevel@tonic-gate **  Convert a string to a long integer.
41437c478bd9Sstevel@tonic-gate **
41447c478bd9Sstevel@tonic-gate **  Ignores `locale' stuff.  Assumes that the upper and lower case
41457c478bd9Sstevel@tonic-gate **  alphabets and digits are each contiguous.
41467c478bd9Sstevel@tonic-gate */
41477c478bd9Sstevel@tonic-gate 
41487c478bd9Sstevel@tonic-gate long
41497c478bd9Sstevel@tonic-gate strtol(nptr, endptr, base)
41507c478bd9Sstevel@tonic-gate 	const char *nptr;
41517c478bd9Sstevel@tonic-gate 	char **endptr;
41527c478bd9Sstevel@tonic-gate 	register int base;
41537c478bd9Sstevel@tonic-gate {
41547c478bd9Sstevel@tonic-gate 	register const char *s = nptr;
41557c478bd9Sstevel@tonic-gate 	register unsigned long acc;
41567c478bd9Sstevel@tonic-gate 	register int c;
41577c478bd9Sstevel@tonic-gate 	register unsigned long cutoff;
41587c478bd9Sstevel@tonic-gate 	register int neg = 0, any, cutlim;
41597c478bd9Sstevel@tonic-gate 
41607c478bd9Sstevel@tonic-gate 	/*
41617c478bd9Sstevel@tonic-gate 	**  Skip white space and pick up leading +/- sign if any.
41627c478bd9Sstevel@tonic-gate 	**  If base is 0, allow 0x for hex and 0 for octal, else
41637c478bd9Sstevel@tonic-gate 	**  assume decimal; if base is already 16, allow 0x.
41647c478bd9Sstevel@tonic-gate 	*/
41657c478bd9Sstevel@tonic-gate 	do {
41667c478bd9Sstevel@tonic-gate 		c = *s++;
41677c478bd9Sstevel@tonic-gate 	} while (isspace(c));
41687c478bd9Sstevel@tonic-gate 	if (c == '-') {
41697c478bd9Sstevel@tonic-gate 		neg = 1;
41707c478bd9Sstevel@tonic-gate 		c = *s++;
41717c478bd9Sstevel@tonic-gate 	} else if (c == '+')
41727c478bd9Sstevel@tonic-gate 		c = *s++;
41737c478bd9Sstevel@tonic-gate 	if ((base == 0 || base == 16) &&
41747c478bd9Sstevel@tonic-gate 	    c == '0' && (*s == 'x' || *s == 'X')) {
41757c478bd9Sstevel@tonic-gate 		c = s[1];
41767c478bd9Sstevel@tonic-gate 		s += 2;
41777c478bd9Sstevel@tonic-gate 		base = 16;
41787c478bd9Sstevel@tonic-gate 	}
41797c478bd9Sstevel@tonic-gate 	if (base == 0)
41807c478bd9Sstevel@tonic-gate 		base = c == '0' ? 8 : 10;
41817c478bd9Sstevel@tonic-gate 
41827c478bd9Sstevel@tonic-gate 	/*
41837c478bd9Sstevel@tonic-gate 	**  Compute the cutoff value between legal numbers and illegal
41847c478bd9Sstevel@tonic-gate 	**  numbers.  That is the largest legal value, divided by the
41857c478bd9Sstevel@tonic-gate 	**  base.  An input number that is greater than this value, if
41867c478bd9Sstevel@tonic-gate 	**  followed by a legal input character, is too big.  One that
41877c478bd9Sstevel@tonic-gate 	**  is equal to this value may be valid or not; the limit
41887c478bd9Sstevel@tonic-gate 	**  between valid and invalid numbers is then based on the last
41897c478bd9Sstevel@tonic-gate 	**  digit.  For instance, if the range for longs is
41907c478bd9Sstevel@tonic-gate 	**  [-2147483648..2147483647] and the input base is 10,
41917c478bd9Sstevel@tonic-gate 	**  cutoff will be set to 214748364 and cutlim to either
41927c478bd9Sstevel@tonic-gate 	**  7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
41937c478bd9Sstevel@tonic-gate 	**  a value > 214748364, or equal but the next digit is > 7 (or 8),
41947c478bd9Sstevel@tonic-gate 	**  the number is too big, and we will return a range error.
41957c478bd9Sstevel@tonic-gate 	**
41967c478bd9Sstevel@tonic-gate 	**  Set any if any `digits' consumed; make it negative to indicate
41977c478bd9Sstevel@tonic-gate 	**  overflow.
41987c478bd9Sstevel@tonic-gate 	*/
41997c478bd9Sstevel@tonic-gate 	cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
42007c478bd9Sstevel@tonic-gate 	cutlim = cutoff % (unsigned long) base;
42017c478bd9Sstevel@tonic-gate 	cutoff /= (unsigned long) base;
42027c478bd9Sstevel@tonic-gate 	for (acc = 0, any = 0;; c = *s++) {
42037c478bd9Sstevel@tonic-gate 		if (isdigit(c))
42047c478bd9Sstevel@tonic-gate 			c -= '0';
42057c478bd9Sstevel@tonic-gate 		else if (isalpha(c))
42067c478bd9Sstevel@tonic-gate 			c -= isupper(c) ? 'A' - 10 : 'a' - 10;
42077c478bd9Sstevel@tonic-gate 		else
42087c478bd9Sstevel@tonic-gate 			break;
42097c478bd9Sstevel@tonic-gate 		if (c >= base)
42107c478bd9Sstevel@tonic-gate 			break;
42117c478bd9Sstevel@tonic-gate 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
42127c478bd9Sstevel@tonic-gate 			any = -1;
42137c478bd9Sstevel@tonic-gate 		else {
42147c478bd9Sstevel@tonic-gate 			any = 1;
42157c478bd9Sstevel@tonic-gate 			acc *= base;
42167c478bd9Sstevel@tonic-gate 			acc += c;
42177c478bd9Sstevel@tonic-gate 		}
42187c478bd9Sstevel@tonic-gate 	}
42197c478bd9Sstevel@tonic-gate 	if (any < 0) {
42207c478bd9Sstevel@tonic-gate 		acc = neg ? LONG_MIN : LONG_MAX;
42217c478bd9Sstevel@tonic-gate 		errno = ERANGE;
42227c478bd9Sstevel@tonic-gate 	} else if (neg)
42237c478bd9Sstevel@tonic-gate 		acc = -acc;
42247c478bd9Sstevel@tonic-gate 	if (endptr != 0)
42257c478bd9Sstevel@tonic-gate 		*endptr = (char *)(any ? s - 1 : nptr);
42267c478bd9Sstevel@tonic-gate 	return acc;
42277c478bd9Sstevel@tonic-gate }
42287c478bd9Sstevel@tonic-gate 
42297c478bd9Sstevel@tonic-gate #endif /* NEEDSTRTOL */
42307c478bd9Sstevel@tonic-gate /*
42317c478bd9Sstevel@tonic-gate **  STRSTR -- find first substring in string
42327c478bd9Sstevel@tonic-gate **
42337c478bd9Sstevel@tonic-gate **	Parameters:
42347c478bd9Sstevel@tonic-gate **		big -- the big (full) string.
42357c478bd9Sstevel@tonic-gate **		little -- the little (sub) string.
42367c478bd9Sstevel@tonic-gate **
42377c478bd9Sstevel@tonic-gate **	Returns:
42387c478bd9Sstevel@tonic-gate **		A pointer to the first instance of little in big.
42397c478bd9Sstevel@tonic-gate **		big if little is the null string.
42407c478bd9Sstevel@tonic-gate **		NULL if little is not contained in big.
42417c478bd9Sstevel@tonic-gate */
42427c478bd9Sstevel@tonic-gate 
42437c478bd9Sstevel@tonic-gate #if NEEDSTRSTR
42447c478bd9Sstevel@tonic-gate 
42457c478bd9Sstevel@tonic-gate char *
42467c478bd9Sstevel@tonic-gate strstr(big, little)
42477c478bd9Sstevel@tonic-gate 	char *big;
42487c478bd9Sstevel@tonic-gate 	char *little;
42497c478bd9Sstevel@tonic-gate {
42507c478bd9Sstevel@tonic-gate 	register char *p = big;
42517c478bd9Sstevel@tonic-gate 	int l;
42527c478bd9Sstevel@tonic-gate 
42537c478bd9Sstevel@tonic-gate 	if (*little == '\0')
42547c478bd9Sstevel@tonic-gate 		return big;
42557c478bd9Sstevel@tonic-gate 	l = strlen(little);
42567c478bd9Sstevel@tonic-gate 
42577c478bd9Sstevel@tonic-gate 	while ((p = strchr(p, *little)) != NULL)
42587c478bd9Sstevel@tonic-gate 	{
42597c478bd9Sstevel@tonic-gate 		if (strncmp(p, little, l) == 0)
42607c478bd9Sstevel@tonic-gate 			return p;
42617c478bd9Sstevel@tonic-gate 		p++;
42627c478bd9Sstevel@tonic-gate 	}
42637c478bd9Sstevel@tonic-gate 	return NULL;
42647c478bd9Sstevel@tonic-gate }
42657c478bd9Sstevel@tonic-gate 
42667c478bd9Sstevel@tonic-gate #endif /* NEEDSTRSTR */
42677c478bd9Sstevel@tonic-gate /*
42687c478bd9Sstevel@tonic-gate **  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
42697c478bd9Sstevel@tonic-gate **
42707c478bd9Sstevel@tonic-gate **	Some operating systems have wierd problems with the gethostbyXXX
42717c478bd9Sstevel@tonic-gate **	routines.  For example, Solaris versions at least through 2.3
42727c478bd9Sstevel@tonic-gate **	don't properly deliver a canonical h_name field.  This tries to
42737c478bd9Sstevel@tonic-gate **	work around these problems.
42747c478bd9Sstevel@tonic-gate **
42757c478bd9Sstevel@tonic-gate **	Support IPv6 as well as IPv4.
42767c478bd9Sstevel@tonic-gate */
42777c478bd9Sstevel@tonic-gate 
42787c478bd9Sstevel@tonic-gate #if NETINET6 && NEEDSGETIPNODE
42797c478bd9Sstevel@tonic-gate 
42807c478bd9Sstevel@tonic-gate # ifndef AI_DEFAULT
42817c478bd9Sstevel@tonic-gate #  define AI_DEFAULT	0	/* dummy */
42827c478bd9Sstevel@tonic-gate # endif /* ! AI_DEFAULT */
42837c478bd9Sstevel@tonic-gate # ifndef AI_ADDRCONFIG
42847c478bd9Sstevel@tonic-gate #  define AI_ADDRCONFIG	0	/* dummy */
42857c478bd9Sstevel@tonic-gate # endif /* ! AI_ADDRCONFIG */
42867c478bd9Sstevel@tonic-gate # ifndef AI_V4MAPPED
42877c478bd9Sstevel@tonic-gate #  define AI_V4MAPPED	0	/* dummy */
42887c478bd9Sstevel@tonic-gate # endif /* ! AI_V4MAPPED */
42897c478bd9Sstevel@tonic-gate # ifndef AI_ALL
42907c478bd9Sstevel@tonic-gate #  define AI_ALL	0	/* dummy */
42917c478bd9Sstevel@tonic-gate # endif /* ! AI_ALL */
42927c478bd9Sstevel@tonic-gate 
42937c478bd9Sstevel@tonic-gate static struct hostent *
42947c478bd9Sstevel@tonic-gate getipnodebyname(name, family, flags, err)
42957c478bd9Sstevel@tonic-gate 	char *name;
42967c478bd9Sstevel@tonic-gate 	int family;
42977c478bd9Sstevel@tonic-gate 	int flags;
42987c478bd9Sstevel@tonic-gate 	int *err;
42997c478bd9Sstevel@tonic-gate {
43007c478bd9Sstevel@tonic-gate 	bool resv6 = true;
43017c478bd9Sstevel@tonic-gate 	struct hostent *h;
43027c478bd9Sstevel@tonic-gate 
43037c478bd9Sstevel@tonic-gate 	if (family == AF_INET6)
43047c478bd9Sstevel@tonic-gate 	{
43057c478bd9Sstevel@tonic-gate 		/* From RFC2133, section 6.1 */
43067c478bd9Sstevel@tonic-gate 		resv6 = bitset(RES_USE_INET6, _res.options);
43077c478bd9Sstevel@tonic-gate 		_res.options |= RES_USE_INET6;
43087c478bd9Sstevel@tonic-gate 	}
43097c478bd9Sstevel@tonic-gate 	SM_SET_H_ERRNO(0);
43107c478bd9Sstevel@tonic-gate 	h = gethostbyname(name);
43117c478bd9Sstevel@tonic-gate 	if (!resv6)
43127c478bd9Sstevel@tonic-gate 		_res.options &= ~RES_USE_INET6;
43137c478bd9Sstevel@tonic-gate 	*err = h_errno;
43147c478bd9Sstevel@tonic-gate 	return h;
43157c478bd9Sstevel@tonic-gate }
43167c478bd9Sstevel@tonic-gate 
43177c478bd9Sstevel@tonic-gate static struct hostent *
43187c478bd9Sstevel@tonic-gate getipnodebyaddr(addr, len, family, err)
43197c478bd9Sstevel@tonic-gate 	char *addr;
43207c478bd9Sstevel@tonic-gate 	int len;
43217c478bd9Sstevel@tonic-gate 	int family;
43227c478bd9Sstevel@tonic-gate 	int *err;
43237c478bd9Sstevel@tonic-gate {
43247c478bd9Sstevel@tonic-gate 	struct hostent *h;
43257c478bd9Sstevel@tonic-gate 
43267c478bd9Sstevel@tonic-gate 	SM_SET_H_ERRNO(0);
43277c478bd9Sstevel@tonic-gate 	h = gethostbyaddr(addr, len, family);
43287c478bd9Sstevel@tonic-gate 	*err = h_errno;
43297c478bd9Sstevel@tonic-gate 	return h;
43307c478bd9Sstevel@tonic-gate }
43317c478bd9Sstevel@tonic-gate 
43327c478bd9Sstevel@tonic-gate void
43337c478bd9Sstevel@tonic-gate freehostent(h)
43347c478bd9Sstevel@tonic-gate 	struct hostent *h;
43357c478bd9Sstevel@tonic-gate {
43367c478bd9Sstevel@tonic-gate 	/*
43377c478bd9Sstevel@tonic-gate 	**  Stub routine -- if they don't have getipnodeby*(),
43387c478bd9Sstevel@tonic-gate 	**  they probably don't have the free routine either.
43397c478bd9Sstevel@tonic-gate 	*/
43407c478bd9Sstevel@tonic-gate 
43417c478bd9Sstevel@tonic-gate 	return;
43427c478bd9Sstevel@tonic-gate }
43437c478bd9Sstevel@tonic-gate #endif /* NETINET6 && NEEDSGETIPNODE */
43447c478bd9Sstevel@tonic-gate 
43457c478bd9Sstevel@tonic-gate struct hostent *
43467c478bd9Sstevel@tonic-gate sm_gethostbyname(name, family)
43477c478bd9Sstevel@tonic-gate 	char *name;
43487c478bd9Sstevel@tonic-gate 	int family;
43497c478bd9Sstevel@tonic-gate {
43507c478bd9Sstevel@tonic-gate 	int save_errno;
43517c478bd9Sstevel@tonic-gate 	struct hostent *h = NULL;
43527c478bd9Sstevel@tonic-gate #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
43537c478bd9Sstevel@tonic-gate # if SOLARIS == 20300 || SOLARIS == 203
43547c478bd9Sstevel@tonic-gate 	static struct hostent hp;
43557c478bd9Sstevel@tonic-gate 	static char buf[1000];
43567c478bd9Sstevel@tonic-gate 	extern struct hostent *_switch_gethostbyname_r();
43577c478bd9Sstevel@tonic-gate 
43587c478bd9Sstevel@tonic-gate 	if (tTd(61, 10))
43597c478bd9Sstevel@tonic-gate 		sm_dprintf("_switch_gethostbyname_r(%s)... ", name);
43607c478bd9Sstevel@tonic-gate 	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
43617c478bd9Sstevel@tonic-gate 	save_errno = errno;
43627c478bd9Sstevel@tonic-gate # else /* SOLARIS == 20300 || SOLARIS == 203 */
43637c478bd9Sstevel@tonic-gate 	extern struct hostent *__switch_gethostbyname();
43647c478bd9Sstevel@tonic-gate 
43657c478bd9Sstevel@tonic-gate 	if (tTd(61, 10))
43667c478bd9Sstevel@tonic-gate 		sm_dprintf("__switch_gethostbyname(%s)... ", name);
43677c478bd9Sstevel@tonic-gate 	h = __switch_gethostbyname(name);
43687c478bd9Sstevel@tonic-gate 	save_errno = errno;
43697c478bd9Sstevel@tonic-gate # endif /* SOLARIS == 20300 || SOLARIS == 203 */
43707c478bd9Sstevel@tonic-gate #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
43717c478bd9Sstevel@tonic-gate 	int nmaps;
43727c478bd9Sstevel@tonic-gate # if NETINET6
43737c478bd9Sstevel@tonic-gate 	int flags = AI_DEFAULT|AI_ALL;
43747c478bd9Sstevel@tonic-gate 	int err;
43757c478bd9Sstevel@tonic-gate # endif /* NETINET6 */
43767c478bd9Sstevel@tonic-gate 	char *maptype[MAXMAPSTACK];
43777c478bd9Sstevel@tonic-gate 	short mapreturn[MAXMAPACTIONS];
43787c478bd9Sstevel@tonic-gate 	char hbuf[MAXNAME];
43797c478bd9Sstevel@tonic-gate 
43807c478bd9Sstevel@tonic-gate 	if (tTd(61, 10))
43817c478bd9Sstevel@tonic-gate 		sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family);
43827c478bd9Sstevel@tonic-gate 
43837c478bd9Sstevel@tonic-gate # if NETINET6
43847c478bd9Sstevel@tonic-gate #  if ADDRCONFIG_IS_BROKEN
43857c478bd9Sstevel@tonic-gate 	flags &= ~AI_ADDRCONFIG;
43867c478bd9Sstevel@tonic-gate #  endif /* ADDRCONFIG_IS_BROKEN */
43877c478bd9Sstevel@tonic-gate 	h = getipnodebyname(name, family, flags, &err);
43887c478bd9Sstevel@tonic-gate 	SM_SET_H_ERRNO(err);
43897c478bd9Sstevel@tonic-gate # else /* NETINET6 */
43907c478bd9Sstevel@tonic-gate 	h = gethostbyname(name);
43917c478bd9Sstevel@tonic-gate # endif /* NETINET6 */
43927c478bd9Sstevel@tonic-gate 
43937c478bd9Sstevel@tonic-gate 	save_errno = errno;
43947c478bd9Sstevel@tonic-gate 	if (h == NULL)
43957c478bd9Sstevel@tonic-gate 	{
43967c478bd9Sstevel@tonic-gate 		if (tTd(61, 10))
43977c478bd9Sstevel@tonic-gate 			sm_dprintf("failure\n");
43987c478bd9Sstevel@tonic-gate 
43997c478bd9Sstevel@tonic-gate 		nmaps = switch_map_find("hosts", maptype, mapreturn);
44007c478bd9Sstevel@tonic-gate 		while (--nmaps >= 0)
44017c478bd9Sstevel@tonic-gate 		{
44027c478bd9Sstevel@tonic-gate 			if (strcmp(maptype[nmaps], "nis") == 0 ||
44037c478bd9Sstevel@tonic-gate 			    strcmp(maptype[nmaps], "files") == 0)
44047c478bd9Sstevel@tonic-gate 				break;
44057c478bd9Sstevel@tonic-gate 		}
44067c478bd9Sstevel@tonic-gate 
44077c478bd9Sstevel@tonic-gate 		if (nmaps >= 0)
44087c478bd9Sstevel@tonic-gate 		{
44097c478bd9Sstevel@tonic-gate 			/* try short name */
44107c478bd9Sstevel@tonic-gate 			if (strlen(name) > sizeof hbuf - 1)
44117c478bd9Sstevel@tonic-gate 			{
44127c478bd9Sstevel@tonic-gate 				errno = save_errno;
44137c478bd9Sstevel@tonic-gate 				return NULL;
44147c478bd9Sstevel@tonic-gate 			}
44157c478bd9Sstevel@tonic-gate 			(void) sm_strlcpy(hbuf, name, sizeof hbuf);
44167c478bd9Sstevel@tonic-gate 			(void) shorten_hostname(hbuf);
44177c478bd9Sstevel@tonic-gate 
44187c478bd9Sstevel@tonic-gate 			/* if it hasn't been shortened, there's no point */
44197c478bd9Sstevel@tonic-gate 			if (strcmp(hbuf, name) != 0)
44207c478bd9Sstevel@tonic-gate 			{
44217c478bd9Sstevel@tonic-gate 				if (tTd(61, 10))
44227c478bd9Sstevel@tonic-gate 					sm_dprintf("sm_gethostbyname(%s, %d)... ",
44237c478bd9Sstevel@tonic-gate 					       hbuf, family);
44247c478bd9Sstevel@tonic-gate 
44257c478bd9Sstevel@tonic-gate # if NETINET6
44267c478bd9Sstevel@tonic-gate 				h = getipnodebyname(hbuf, family, flags, &err);
44277c478bd9Sstevel@tonic-gate 				SM_SET_H_ERRNO(err);
44287c478bd9Sstevel@tonic-gate 				save_errno = errno;
44297c478bd9Sstevel@tonic-gate # else /* NETINET6 */
44307c478bd9Sstevel@tonic-gate 				h = gethostbyname(hbuf);
44317c478bd9Sstevel@tonic-gate 				save_errno = errno;
44327c478bd9Sstevel@tonic-gate # endif /* NETINET6 */
44337c478bd9Sstevel@tonic-gate 			}
44347c478bd9Sstevel@tonic-gate 		}
44357c478bd9Sstevel@tonic-gate 	}
44367c478bd9Sstevel@tonic-gate #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
44377c478bd9Sstevel@tonic-gate 	if (tTd(61, 10))
44387c478bd9Sstevel@tonic-gate 	{
44397c478bd9Sstevel@tonic-gate 		if (h == NULL)
44407c478bd9Sstevel@tonic-gate 			sm_dprintf("failure\n");
44417c478bd9Sstevel@tonic-gate 		else
44427c478bd9Sstevel@tonic-gate 		{
44437c478bd9Sstevel@tonic-gate 			sm_dprintf("%s\n", h->h_name);
44447c478bd9Sstevel@tonic-gate 			if (tTd(61, 11))
44457c478bd9Sstevel@tonic-gate 			{
44467c478bd9Sstevel@tonic-gate #if NETINET6
44477c478bd9Sstevel@tonic-gate 				struct in6_addr ia6;
44487c478bd9Sstevel@tonic-gate 				char buf6[INET6_ADDRSTRLEN];
44497c478bd9Sstevel@tonic-gate #else /* NETINET6 */
44507c478bd9Sstevel@tonic-gate 				struct in_addr ia;
44517c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
44527c478bd9Sstevel@tonic-gate 				size_t i;
44537c478bd9Sstevel@tonic-gate 
44547c478bd9Sstevel@tonic-gate 				if (h->h_aliases != NULL)
44557c478bd9Sstevel@tonic-gate 					for (i = 0; h->h_aliases[i] != NULL;
44567c478bd9Sstevel@tonic-gate 					     i++)
44577c478bd9Sstevel@tonic-gate 						sm_dprintf("\talias: %s\n",
44587c478bd9Sstevel@tonic-gate 							h->h_aliases[i]);
44597c478bd9Sstevel@tonic-gate 				for (i = 0; h->h_addr_list[i] != NULL; i++)
44607c478bd9Sstevel@tonic-gate 				{
44617c478bd9Sstevel@tonic-gate 					char *addr;
44627c478bd9Sstevel@tonic-gate 
44637c478bd9Sstevel@tonic-gate #if NETINET6
44647c478bd9Sstevel@tonic-gate 					memmove(&ia6, h->h_addr_list[i],
44657c478bd9Sstevel@tonic-gate 						IN6ADDRSZ);
44667c478bd9Sstevel@tonic-gate 					addr = anynet_ntop(&ia6,
44677c478bd9Sstevel@tonic-gate 							   buf6, sizeof buf6);
44687c478bd9Sstevel@tonic-gate #else /* NETINET6 */
44697c478bd9Sstevel@tonic-gate 					memmove(&ia, h->h_addr_list[i],
44707c478bd9Sstevel@tonic-gate 						INADDRSZ);
44717c478bd9Sstevel@tonic-gate 					addr = (char *) inet_ntoa(ia);
44727c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
44737c478bd9Sstevel@tonic-gate 					if (addr != NULL)
44747c478bd9Sstevel@tonic-gate 						sm_dprintf("\taddr: %s\n", addr);
44757c478bd9Sstevel@tonic-gate 				}
44767c478bd9Sstevel@tonic-gate 			}
44777c478bd9Sstevel@tonic-gate 		}
44787c478bd9Sstevel@tonic-gate 	}
44797c478bd9Sstevel@tonic-gate 	errno = save_errno;
44807c478bd9Sstevel@tonic-gate 	return h;
44817c478bd9Sstevel@tonic-gate }
44827c478bd9Sstevel@tonic-gate 
44837c478bd9Sstevel@tonic-gate struct hostent *
44847c478bd9Sstevel@tonic-gate sm_gethostbyaddr(addr, len, type)
44857c478bd9Sstevel@tonic-gate 	char *addr;
44867c478bd9Sstevel@tonic-gate 	int len;
44877c478bd9Sstevel@tonic-gate 	int type;
44887c478bd9Sstevel@tonic-gate {
44897c478bd9Sstevel@tonic-gate 	struct hostent *hp;
44907c478bd9Sstevel@tonic-gate 
44917c478bd9Sstevel@tonic-gate #if NETINET6
44927c478bd9Sstevel@tonic-gate 	if (type == AF_INET6 &&
44937c478bd9Sstevel@tonic-gate 	    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) addr))
44947c478bd9Sstevel@tonic-gate 	{
44957c478bd9Sstevel@tonic-gate 		/* Avoid reverse lookup for IPv6 unspecified address */
44967c478bd9Sstevel@tonic-gate 		SM_SET_H_ERRNO(HOST_NOT_FOUND);
44977c478bd9Sstevel@tonic-gate 		return NULL;
44987c478bd9Sstevel@tonic-gate 	}
44997c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
45007c478bd9Sstevel@tonic-gate 
45017c478bd9Sstevel@tonic-gate #if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204)
45027c478bd9Sstevel@tonic-gate # if SOLARIS == 20300 || SOLARIS == 203
45037c478bd9Sstevel@tonic-gate 	{
45047c478bd9Sstevel@tonic-gate 		static struct hostent he;
45057c478bd9Sstevel@tonic-gate 		static char buf[1000];
45067c478bd9Sstevel@tonic-gate 		extern struct hostent *_switch_gethostbyaddr_r();
45077c478bd9Sstevel@tonic-gate 
45087c478bd9Sstevel@tonic-gate 		hp = _switch_gethostbyaddr_r(addr, len, type, &he,
45097c478bd9Sstevel@tonic-gate 					     buf, sizeof(buf), &h_errno);
45107c478bd9Sstevel@tonic-gate 	}
45117c478bd9Sstevel@tonic-gate # else /* SOLARIS == 20300 || SOLARIS == 203 */
45127c478bd9Sstevel@tonic-gate 	{
45137c478bd9Sstevel@tonic-gate 		extern struct hostent *__switch_gethostbyaddr();
45147c478bd9Sstevel@tonic-gate 
45157c478bd9Sstevel@tonic-gate 		hp = __switch_gethostbyaddr(addr, len, type);
45167c478bd9Sstevel@tonic-gate 	}
45177c478bd9Sstevel@tonic-gate # endif /* SOLARIS == 20300 || SOLARIS == 203 */
45187c478bd9Sstevel@tonic-gate #else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
45197c478bd9Sstevel@tonic-gate # if NETINET6
45207c478bd9Sstevel@tonic-gate 	{
45217c478bd9Sstevel@tonic-gate 		int err;
45227c478bd9Sstevel@tonic-gate 
45237c478bd9Sstevel@tonic-gate 		hp = getipnodebyaddr(addr, len, type, &err);
45247c478bd9Sstevel@tonic-gate 		SM_SET_H_ERRNO(err);
45257c478bd9Sstevel@tonic-gate 	}
45267c478bd9Sstevel@tonic-gate # else /* NETINET6 */
45277c478bd9Sstevel@tonic-gate 	hp = gethostbyaddr(addr, len, type);
45287c478bd9Sstevel@tonic-gate # endif /* NETINET6 */
45297c478bd9Sstevel@tonic-gate #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
45307c478bd9Sstevel@tonic-gate 	return hp;
45317c478bd9Sstevel@tonic-gate }
45327c478bd9Sstevel@tonic-gate /*
45337c478bd9Sstevel@tonic-gate **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
45347c478bd9Sstevel@tonic-gate */
45357c478bd9Sstevel@tonic-gate 
45367c478bd9Sstevel@tonic-gate struct passwd *
45377c478bd9Sstevel@tonic-gate sm_getpwnam(user)
45387c478bd9Sstevel@tonic-gate 	char *user;
45397c478bd9Sstevel@tonic-gate {
45407c478bd9Sstevel@tonic-gate #ifdef _AIX4
45417c478bd9Sstevel@tonic-gate 	extern struct passwd *_getpwnam_shadow(const char *, const int);
45427c478bd9Sstevel@tonic-gate 
45437c478bd9Sstevel@tonic-gate 	return _getpwnam_shadow(user, 0);
45447c478bd9Sstevel@tonic-gate #else /* _AIX4 */
45457c478bd9Sstevel@tonic-gate 	return getpwnam(user);
45467c478bd9Sstevel@tonic-gate #endif /* _AIX4 */
45477c478bd9Sstevel@tonic-gate }
45487c478bd9Sstevel@tonic-gate 
45497c478bd9Sstevel@tonic-gate struct passwd *
45507c478bd9Sstevel@tonic-gate sm_getpwuid(uid)
45517c478bd9Sstevel@tonic-gate 	UID_T uid;
45527c478bd9Sstevel@tonic-gate {
45537c478bd9Sstevel@tonic-gate #if defined(_AIX4) && 0
45547c478bd9Sstevel@tonic-gate 	extern struct passwd *_getpwuid_shadow(const int, const int);
45557c478bd9Sstevel@tonic-gate 
45567c478bd9Sstevel@tonic-gate 	return _getpwuid_shadow(uid,0);
45577c478bd9Sstevel@tonic-gate #else /* defined(_AIX4) && 0 */
45587c478bd9Sstevel@tonic-gate 	return getpwuid(uid);
45597c478bd9Sstevel@tonic-gate #endif /* defined(_AIX4) && 0 */
45607c478bd9Sstevel@tonic-gate }
45617c478bd9Sstevel@tonic-gate /*
45627c478bd9Sstevel@tonic-gate **  SECUREWARE_SETUP_SECURE -- Convex SecureWare setup
45637c478bd9Sstevel@tonic-gate **
45647c478bd9Sstevel@tonic-gate **	Set up the trusted computing environment for C2 level security
45657c478bd9Sstevel@tonic-gate **	under SecureWare.
45667c478bd9Sstevel@tonic-gate **
45677c478bd9Sstevel@tonic-gate **	Parameters:
45687c478bd9Sstevel@tonic-gate **		uid -- uid of the user to initialize in the TCB
45697c478bd9Sstevel@tonic-gate **
45707c478bd9Sstevel@tonic-gate **	Returns:
45717c478bd9Sstevel@tonic-gate **		none
45727c478bd9Sstevel@tonic-gate **
45737c478bd9Sstevel@tonic-gate **	Side Effects:
45747c478bd9Sstevel@tonic-gate **		Initialized the user in the trusted computing base
45757c478bd9Sstevel@tonic-gate */
45767c478bd9Sstevel@tonic-gate 
45777c478bd9Sstevel@tonic-gate #if SECUREWARE
45787c478bd9Sstevel@tonic-gate 
45797c478bd9Sstevel@tonic-gate # include <sys/security.h>
45807c478bd9Sstevel@tonic-gate # include <prot.h>
45817c478bd9Sstevel@tonic-gate 
45827c478bd9Sstevel@tonic-gate void
45837c478bd9Sstevel@tonic-gate secureware_setup_secure(uid)
45847c478bd9Sstevel@tonic-gate 	UID_T uid;
45857c478bd9Sstevel@tonic-gate {
45867c478bd9Sstevel@tonic-gate 	int rc;
45877c478bd9Sstevel@tonic-gate 
45887c478bd9Sstevel@tonic-gate 	if (getluid() != -1)
45897c478bd9Sstevel@tonic-gate 		return;
45907c478bd9Sstevel@tonic-gate 
45917c478bd9Sstevel@tonic-gate 	if ((rc = set_secure_info(uid)) != SSI_GOOD_RETURN)
45927c478bd9Sstevel@tonic-gate 	{
45937c478bd9Sstevel@tonic-gate 		switch (rc)
45947c478bd9Sstevel@tonic-gate 		{
45957c478bd9Sstevel@tonic-gate 		  case SSI_NO_PRPW_ENTRY:
45967c478bd9Sstevel@tonic-gate 			syserr("No protected passwd entry, uid = %d",
45977c478bd9Sstevel@tonic-gate 			       (int) uid);
45987c478bd9Sstevel@tonic-gate 			break;
45997c478bd9Sstevel@tonic-gate 
46007c478bd9Sstevel@tonic-gate 		  case SSI_LOCKED:
46017c478bd9Sstevel@tonic-gate 			syserr("Account has been disabled, uid = %d",
46027c478bd9Sstevel@tonic-gate 			       (int) uid);
46037c478bd9Sstevel@tonic-gate 			break;
46047c478bd9Sstevel@tonic-gate 
46057c478bd9Sstevel@tonic-gate 		  case SSI_RETIRED:
46067c478bd9Sstevel@tonic-gate 			syserr("Account has been retired, uid = %d",
46077c478bd9Sstevel@tonic-gate 			       (int) uid);
46087c478bd9Sstevel@tonic-gate 			break;
46097c478bd9Sstevel@tonic-gate 
46107c478bd9Sstevel@tonic-gate 		  case SSI_BAD_SET_LUID:
46117c478bd9Sstevel@tonic-gate 			syserr("Could not set LUID, uid = %d", (int) uid);
46127c478bd9Sstevel@tonic-gate 			break;
46137c478bd9Sstevel@tonic-gate 
46147c478bd9Sstevel@tonic-gate 		  case SSI_BAD_SET_PRIVS:
46157c478bd9Sstevel@tonic-gate 			syserr("Could not set kernel privs, uid = %d",
46167c478bd9Sstevel@tonic-gate 			       (int) uid);
46177c478bd9Sstevel@tonic-gate 
46187c478bd9Sstevel@tonic-gate 		  default:
46197c478bd9Sstevel@tonic-gate 			syserr("Unknown return code (%d) from set_secure_info(%d)",
46207c478bd9Sstevel@tonic-gate 				rc, (int) uid);
46217c478bd9Sstevel@tonic-gate 			break;
46227c478bd9Sstevel@tonic-gate 		}
46237c478bd9Sstevel@tonic-gate 		finis(false, true, EX_NOPERM);
46247c478bd9Sstevel@tonic-gate 	}
46257c478bd9Sstevel@tonic-gate }
46267c478bd9Sstevel@tonic-gate #endif /* SECUREWARE */
46277c478bd9Sstevel@tonic-gate /*
46287c478bd9Sstevel@tonic-gate **  ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address
46297c478bd9Sstevel@tonic-gate **
46307c478bd9Sstevel@tonic-gate **	Add hostnames to class 'w' based on the IP address read from
46317c478bd9Sstevel@tonic-gate **	the network interface.
46327c478bd9Sstevel@tonic-gate **
46337c478bd9Sstevel@tonic-gate **	Parameters:
46347c478bd9Sstevel@tonic-gate **		sa -- a pointer to a SOCKADDR containing the address
46357c478bd9Sstevel@tonic-gate **
46367c478bd9Sstevel@tonic-gate **	Returns:
46377c478bd9Sstevel@tonic-gate **		0 if successful, -1 if host lookup fails.
46387c478bd9Sstevel@tonic-gate */
46397c478bd9Sstevel@tonic-gate 
46407c478bd9Sstevel@tonic-gate static int
46417c478bd9Sstevel@tonic-gate add_hostnames(sa)
46427c478bd9Sstevel@tonic-gate 	SOCKADDR *sa;
46437c478bd9Sstevel@tonic-gate {
46447c478bd9Sstevel@tonic-gate 	struct hostent *hp;
46457c478bd9Sstevel@tonic-gate 	char **ha;
46467c478bd9Sstevel@tonic-gate 	char hnb[MAXHOSTNAMELEN];
46477c478bd9Sstevel@tonic-gate 
46487c478bd9Sstevel@tonic-gate 	/* lookup name with IP address */
46497c478bd9Sstevel@tonic-gate 	switch (sa->sa.sa_family)
46507c478bd9Sstevel@tonic-gate 	{
46517c478bd9Sstevel@tonic-gate #if NETINET
46527c478bd9Sstevel@tonic-gate 	  case AF_INET:
46537c478bd9Sstevel@tonic-gate 		hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr,
46547c478bd9Sstevel@tonic-gate 				      sizeof(sa->sin.sin_addr),
46557c478bd9Sstevel@tonic-gate 				      sa->sa.sa_family);
46567c478bd9Sstevel@tonic-gate 		break;
46577c478bd9Sstevel@tonic-gate #endif /* NETINET */
46587c478bd9Sstevel@tonic-gate 
46597c478bd9Sstevel@tonic-gate #if NETINET6
46607c478bd9Sstevel@tonic-gate 	  case AF_INET6:
46617c478bd9Sstevel@tonic-gate 		hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr,
46627c478bd9Sstevel@tonic-gate 				      sizeof(sa->sin6.sin6_addr),
46637c478bd9Sstevel@tonic-gate 				      sa->sa.sa_family);
46647c478bd9Sstevel@tonic-gate 		break;
46657c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
46667c478bd9Sstevel@tonic-gate 
46677c478bd9Sstevel@tonic-gate 	  default:
46687c478bd9Sstevel@tonic-gate 		/* Give warning about unsupported family */
46697c478bd9Sstevel@tonic-gate 		if (LogLevel > 3)
46707c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_WARNING, NOQID,
46717c478bd9Sstevel@tonic-gate 				  "Unsupported address family %d: %.100s",
46727c478bd9Sstevel@tonic-gate 				  sa->sa.sa_family, anynet_ntoa(sa));
46737c478bd9Sstevel@tonic-gate 		return -1;
46747c478bd9Sstevel@tonic-gate 	}
46757c478bd9Sstevel@tonic-gate 
46767c478bd9Sstevel@tonic-gate 	if (hp == NULL)
46777c478bd9Sstevel@tonic-gate 	{
46787c478bd9Sstevel@tonic-gate 		int save_errno = errno;
46797c478bd9Sstevel@tonic-gate 
46807c478bd9Sstevel@tonic-gate 		if (LogLevel > 3 &&
46817c478bd9Sstevel@tonic-gate #if NETINET6
46827c478bd9Sstevel@tonic-gate 		    !(sa->sa.sa_family == AF_INET6 &&
46837c478bd9Sstevel@tonic-gate 		      IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
46847c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
46857c478bd9Sstevel@tonic-gate 		    true)
46867c478bd9Sstevel@tonic-gate 			sm_syslog(LOG_WARNING, NOQID,
46877c478bd9Sstevel@tonic-gate 				  "gethostbyaddr(%.100s) failed: %d",
46887c478bd9Sstevel@tonic-gate 				  anynet_ntoa(sa),
46897c478bd9Sstevel@tonic-gate #if NAMED_BIND
46907c478bd9Sstevel@tonic-gate 				  h_errno
46917c478bd9Sstevel@tonic-gate #else /* NAMED_BIND */
46927c478bd9Sstevel@tonic-gate 				  -1
46937c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
46947c478bd9Sstevel@tonic-gate 				 );
46957c478bd9Sstevel@tonic-gate 		errno = save_errno;
46967c478bd9Sstevel@tonic-gate 		return -1;
46977c478bd9Sstevel@tonic-gate 	}
46987c478bd9Sstevel@tonic-gate 
46997c478bd9Sstevel@tonic-gate 	/* save its cname */
47007c478bd9Sstevel@tonic-gate 	if (!wordinclass((char *) hp->h_name, 'w'))
47017c478bd9Sstevel@tonic-gate 	{
47027c478bd9Sstevel@tonic-gate 		setclass('w', (char *) hp->h_name);
47037c478bd9Sstevel@tonic-gate 		if (tTd(0, 4))
47047c478bd9Sstevel@tonic-gate 			sm_dprintf("\ta.k.a.: %s\n", hp->h_name);
47057c478bd9Sstevel@tonic-gate 
47067c478bd9Sstevel@tonic-gate 		if (sm_snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb
47077c478bd9Sstevel@tonic-gate 		    && !wordinclass((char *) hnb, 'w'))
47087c478bd9Sstevel@tonic-gate 			setclass('w', hnb);
47097c478bd9Sstevel@tonic-gate 	}
47107c478bd9Sstevel@tonic-gate 	else
47117c478bd9Sstevel@tonic-gate 	{
47127c478bd9Sstevel@tonic-gate 		if (tTd(0, 43))
47137c478bd9Sstevel@tonic-gate 			sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name);
47147c478bd9Sstevel@tonic-gate 	}
47157c478bd9Sstevel@tonic-gate 
47167c478bd9Sstevel@tonic-gate 	/* save all it aliases name */
47177c478bd9Sstevel@tonic-gate 	for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
47187c478bd9Sstevel@tonic-gate 	{
47197c478bd9Sstevel@tonic-gate 		if (!wordinclass(*ha, 'w'))
47207c478bd9Sstevel@tonic-gate 		{
47217c478bd9Sstevel@tonic-gate 			setclass('w', *ha);
47227c478bd9Sstevel@tonic-gate 			if (tTd(0, 4))
47237c478bd9Sstevel@tonic-gate 				sm_dprintf("\ta.k.a.: %s\n", *ha);
47247c478bd9Sstevel@tonic-gate 			if (sm_snprintf(hnb, sizeof hnb,
47257c478bd9Sstevel@tonic-gate 				     "[%s]", *ha) < sizeof hnb &&
47267c478bd9Sstevel@tonic-gate 			    !wordinclass((char *) hnb, 'w'))
47277c478bd9Sstevel@tonic-gate 				setclass('w', hnb);
47287c478bd9Sstevel@tonic-gate 		}
47297c478bd9Sstevel@tonic-gate 		else
47307c478bd9Sstevel@tonic-gate 		{
47317c478bd9Sstevel@tonic-gate 			if (tTd(0, 43))
47327c478bd9Sstevel@tonic-gate 				sm_dprintf("\ta.k.a.: %s (already in $=w)\n",
47337c478bd9Sstevel@tonic-gate 					*ha);
47347c478bd9Sstevel@tonic-gate 		}
47357c478bd9Sstevel@tonic-gate 	}
47367c478bd9Sstevel@tonic-gate #if NETINET6
47377c478bd9Sstevel@tonic-gate 	freehostent(hp);
47387c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
47397c478bd9Sstevel@tonic-gate 	return 0;
47407c478bd9Sstevel@tonic-gate }
47417c478bd9Sstevel@tonic-gate /*
47427c478bd9Sstevel@tonic-gate **  LOAD_IF_NAMES -- load interface-specific names into $=w
47437c478bd9Sstevel@tonic-gate **
47447c478bd9Sstevel@tonic-gate **	Parameters:
47457c478bd9Sstevel@tonic-gate **		none.
47467c478bd9Sstevel@tonic-gate **
47477c478bd9Sstevel@tonic-gate **	Returns:
47487c478bd9Sstevel@tonic-gate **		none.
47497c478bd9Sstevel@tonic-gate **
47507c478bd9Sstevel@tonic-gate **	Side Effects:
47517c478bd9Sstevel@tonic-gate **		Loads $=w with the names of all the interfaces.
47527c478bd9Sstevel@tonic-gate */
47537c478bd9Sstevel@tonic-gate 
47547c478bd9Sstevel@tonic-gate #if !NETINET
47557c478bd9Sstevel@tonic-gate # define SIOCGIFCONF_IS_BROKEN	1 /* XXX */
47567c478bd9Sstevel@tonic-gate #endif /* !NETINET */
47577c478bd9Sstevel@tonic-gate 
47587c478bd9Sstevel@tonic-gate #if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
47597c478bd9Sstevel@tonic-gate struct rtentry;
47607c478bd9Sstevel@tonic-gate struct mbuf;
47617c478bd9Sstevel@tonic-gate # ifndef SUNOS403
476249218d4fSjbeck #  include <sm/time.h>
47637c478bd9Sstevel@tonic-gate # endif /* ! SUNOS403 */
47647c478bd9Sstevel@tonic-gate # if (_AIX4 >= 40300) && !defined(_NET_IF_H)
47657c478bd9Sstevel@tonic-gate #  undef __P
47667c478bd9Sstevel@tonic-gate # endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */
47677c478bd9Sstevel@tonic-gate # include <net/if.h>
47687c478bd9Sstevel@tonic-gate #endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
47697c478bd9Sstevel@tonic-gate 
47707c478bd9Sstevel@tonic-gate void
47717c478bd9Sstevel@tonic-gate load_if_names()
47727c478bd9Sstevel@tonic-gate {
47737c478bd9Sstevel@tonic-gate # if NETINET6 && defined(SIOCGLIFCONF)
47747c478bd9Sstevel@tonic-gate #  ifdef __hpux
47757c478bd9Sstevel@tonic-gate 
47767c478bd9Sstevel@tonic-gate     /*
47777c478bd9Sstevel@tonic-gate     **  Unfortunately, HP has changed all of the structures,
47787c478bd9Sstevel@tonic-gate     **  making life difficult for implementors.
47797c478bd9Sstevel@tonic-gate     */
47807c478bd9Sstevel@tonic-gate 
47817c478bd9Sstevel@tonic-gate #   define lifconf	if_laddrconf
47827c478bd9Sstevel@tonic-gate #   define lifc_len	iflc_len
47837c478bd9Sstevel@tonic-gate #   define lifc_buf	iflc_buf
47847c478bd9Sstevel@tonic-gate #   define lifreq	if_laddrreq
47857c478bd9Sstevel@tonic-gate #   define lifr_addr	iflr_addr
47867c478bd9Sstevel@tonic-gate #   define lifr_name	iflr_name
47877c478bd9Sstevel@tonic-gate #   define lifr_flags	iflr_flags
47887c478bd9Sstevel@tonic-gate #   define ss_family	sa_family
47897c478bd9Sstevel@tonic-gate #   undef SIOCGLIFNUM
47907c478bd9Sstevel@tonic-gate #  endif /* __hpux */
47917c478bd9Sstevel@tonic-gate 
47927c478bd9Sstevel@tonic-gate 	int s;
47937c478bd9Sstevel@tonic-gate 	int i;
47947c478bd9Sstevel@tonic-gate 	size_t len;
47957c478bd9Sstevel@tonic-gate 	int numifs;
47967c478bd9Sstevel@tonic-gate 	char *buf;
47977c478bd9Sstevel@tonic-gate 	struct lifconf lifc;
47987c478bd9Sstevel@tonic-gate #  ifdef SIOCGLIFNUM
47997c478bd9Sstevel@tonic-gate 	struct lifnum lifn;
48007c478bd9Sstevel@tonic-gate #  endif /* SIOCGLIFNUM */
48017c478bd9Sstevel@tonic-gate 
48027c478bd9Sstevel@tonic-gate 	s = socket(InetMode, SOCK_DGRAM, 0);
48037c478bd9Sstevel@tonic-gate 	if (s == -1)
48047c478bd9Sstevel@tonic-gate 		return;
48057c478bd9Sstevel@tonic-gate 
48067c478bd9Sstevel@tonic-gate 	/* get the list of known IP address from the kernel */
48077c478bd9Sstevel@tonic-gate #  ifdef __hpux
48087c478bd9Sstevel@tonic-gate 	i = ioctl(s, SIOCGIFNUM, (char *) &numifs);
48097c478bd9Sstevel@tonic-gate #  endif /* __hpux */
48107c478bd9Sstevel@tonic-gate #  ifdef SIOCGLIFNUM
48117c478bd9Sstevel@tonic-gate 	lifn.lifn_family = AF_UNSPEC;
48127c478bd9Sstevel@tonic-gate 	lifn.lifn_flags = 0;
48137c478bd9Sstevel@tonic-gate 	i = ioctl(s, SIOCGLIFNUM, (char *)&lifn);
48147c478bd9Sstevel@tonic-gate 	numifs = lifn.lifn_count;
48157c478bd9Sstevel@tonic-gate #  endif /* SIOCGLIFNUM */
48167c478bd9Sstevel@tonic-gate 
48177c478bd9Sstevel@tonic-gate #  if defined(__hpux) || defined(SIOCGLIFNUM)
48187c478bd9Sstevel@tonic-gate 	if (i < 0)
48197c478bd9Sstevel@tonic-gate 	{
48207c478bd9Sstevel@tonic-gate 		/* can't get number of interfaces -- fall back */
48217c478bd9Sstevel@tonic-gate 		if (tTd(0, 4))
48227c478bd9Sstevel@tonic-gate 			sm_dprintf("SIOCGLIFNUM failed: %s\n",
48237c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
48247c478bd9Sstevel@tonic-gate 		numifs = -1;
48257c478bd9Sstevel@tonic-gate 	}
48267c478bd9Sstevel@tonic-gate 	else if (tTd(0, 42))
48277c478bd9Sstevel@tonic-gate 		sm_dprintf("system has %d interfaces\n", numifs);
48287c478bd9Sstevel@tonic-gate 	if (numifs < 0)
48297c478bd9Sstevel@tonic-gate #  endif /* defined(__hpux) || defined(SIOCGLIFNUM) */
48307c478bd9Sstevel@tonic-gate 		numifs = MAXINTERFACES;
48317c478bd9Sstevel@tonic-gate 
48327c478bd9Sstevel@tonic-gate 	if (numifs <= 0)
48337c478bd9Sstevel@tonic-gate 	{
48347c478bd9Sstevel@tonic-gate 		(void) close(s);
48357c478bd9Sstevel@tonic-gate 		return;
48367c478bd9Sstevel@tonic-gate 	}
48377c478bd9Sstevel@tonic-gate 
48387c478bd9Sstevel@tonic-gate 	len = lifc.lifc_len = numifs * sizeof (struct lifreq);
48397c478bd9Sstevel@tonic-gate 	buf = lifc.lifc_buf = xalloc(lifc.lifc_len);
48407c478bd9Sstevel@tonic-gate #  ifndef __hpux
48417c478bd9Sstevel@tonic-gate 	lifc.lifc_family = AF_UNSPEC;
48427c478bd9Sstevel@tonic-gate 	lifc.lifc_flags = 0;
48437c478bd9Sstevel@tonic-gate #  endif /* ! __hpux */
48447c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
48457c478bd9Sstevel@tonic-gate 	{
48467c478bd9Sstevel@tonic-gate 		if (tTd(0, 4))
48477c478bd9Sstevel@tonic-gate 			sm_dprintf("SIOCGLIFCONF failed: %s\n",
48487c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
48497c478bd9Sstevel@tonic-gate 		(void) close(s);
48507c478bd9Sstevel@tonic-gate 		sm_free(buf);
48517c478bd9Sstevel@tonic-gate 		return;
48527c478bd9Sstevel@tonic-gate 	}
48537c478bd9Sstevel@tonic-gate 
48547c478bd9Sstevel@tonic-gate 	/* scan the list of IP address */
48557c478bd9Sstevel@tonic-gate 	if (tTd(0, 40))
48567c478bd9Sstevel@tonic-gate 		sm_dprintf("scanning for interface specific names, lifc_len=%ld\n",
48577c478bd9Sstevel@tonic-gate 			   (long) len);
48587c478bd9Sstevel@tonic-gate 
48597c478bd9Sstevel@tonic-gate 	for (i = 0; i < len && i >= 0; )
48607c478bd9Sstevel@tonic-gate 	{
48617c478bd9Sstevel@tonic-gate 		int flags;
48627c478bd9Sstevel@tonic-gate 		struct lifreq *ifr = (struct lifreq *)&buf[i];
48637c478bd9Sstevel@tonic-gate 		SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr;
48647c478bd9Sstevel@tonic-gate 		int af = ifr->lifr_addr.ss_family;
48657c478bd9Sstevel@tonic-gate 		char *addr;
48667c478bd9Sstevel@tonic-gate 		char *name;
48677c478bd9Sstevel@tonic-gate 		struct in6_addr ia6;
48687c478bd9Sstevel@tonic-gate 		struct in_addr ia;
48697c478bd9Sstevel@tonic-gate #  ifdef SIOCGLIFFLAGS
48707c478bd9Sstevel@tonic-gate 		struct lifreq ifrf;
48717c478bd9Sstevel@tonic-gate #  endif /* SIOCGLIFFLAGS */
48727c478bd9Sstevel@tonic-gate 		char ip_addr[256];
48737c478bd9Sstevel@tonic-gate 		char buf6[INET6_ADDRSTRLEN];
48747c478bd9Sstevel@tonic-gate 
48757c478bd9Sstevel@tonic-gate 		/*
48767c478bd9Sstevel@tonic-gate 		**  We must close and recreate the socket each time
48777c478bd9Sstevel@tonic-gate 		**  since we don't know what type of socket it is now
48787c478bd9Sstevel@tonic-gate 		**  (each status function may change it).
48797c478bd9Sstevel@tonic-gate 		*/
48807c478bd9Sstevel@tonic-gate 
48817c478bd9Sstevel@tonic-gate 		(void) close(s);
48827c478bd9Sstevel@tonic-gate 
48837c478bd9Sstevel@tonic-gate 		s = socket(af, SOCK_DGRAM, 0);
48847c478bd9Sstevel@tonic-gate 		if (s == -1)
48857c478bd9Sstevel@tonic-gate 		{
48867c478bd9Sstevel@tonic-gate 			sm_free(buf); /* XXX */
48877c478bd9Sstevel@tonic-gate 			return;
48887c478bd9Sstevel@tonic-gate 		}
48897c478bd9Sstevel@tonic-gate 
48907c478bd9Sstevel@tonic-gate 		/*
48917c478bd9Sstevel@tonic-gate 		**  If we don't have a complete ifr structure,
48927c478bd9Sstevel@tonic-gate 		**  don't try to use it.
48937c478bd9Sstevel@tonic-gate 		*/
48947c478bd9Sstevel@tonic-gate 
48957c478bd9Sstevel@tonic-gate 		if ((len - i) < sizeof *ifr)
48967c478bd9Sstevel@tonic-gate 			break;
48977c478bd9Sstevel@tonic-gate 
48987c478bd9Sstevel@tonic-gate #  ifdef BSD4_4_SOCKADDR
48997c478bd9Sstevel@tonic-gate 		if (sa->sa.sa_len > sizeof ifr->lifr_addr)
49007c478bd9Sstevel@tonic-gate 			i += sizeof ifr->lifr_name + sa->sa.sa_len;
49017c478bd9Sstevel@tonic-gate 		else
49027c478bd9Sstevel@tonic-gate #  endif /* BSD4_4_SOCKADDR */
490349218d4fSjbeck #  ifdef DEC
490449218d4fSjbeck 			/* fix for IPv6  size differences */
490549218d4fSjbeck 			i += sizeof ifr->ifr_name +
490649218d4fSjbeck 			     max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
490749218d4fSjbeck #   else /* DEC */
49087c478bd9Sstevel@tonic-gate 			i += sizeof *ifr;
490949218d4fSjbeck #   endif /* DEC */
49107c478bd9Sstevel@tonic-gate 
49117c478bd9Sstevel@tonic-gate 		if (tTd(0, 20))
49127c478bd9Sstevel@tonic-gate 			sm_dprintf("%s\n", anynet_ntoa(sa));
49137c478bd9Sstevel@tonic-gate 
49147c478bd9Sstevel@tonic-gate 		if (af != AF_INET && af != AF_INET6)
49157c478bd9Sstevel@tonic-gate 			continue;
49167c478bd9Sstevel@tonic-gate 
49177c478bd9Sstevel@tonic-gate #  ifdef SIOCGLIFFLAGS
49187c478bd9Sstevel@tonic-gate 		memset(&ifrf, '\0', sizeof(struct lifreq));
49197c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name,
49207c478bd9Sstevel@tonic-gate 				  sizeof(ifrf.lifr_name));
49217c478bd9Sstevel@tonic-gate 		if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0)
49227c478bd9Sstevel@tonic-gate 		{
49237c478bd9Sstevel@tonic-gate 			if (tTd(0, 4))
49247c478bd9Sstevel@tonic-gate 				sm_dprintf("SIOCGLIFFLAGS failed: %s\n",
49257c478bd9Sstevel@tonic-gate 					   sm_errstring(errno));
49267c478bd9Sstevel@tonic-gate 			continue;
49277c478bd9Sstevel@tonic-gate 		}
49287c478bd9Sstevel@tonic-gate 
49297c478bd9Sstevel@tonic-gate 		name = ifr->lifr_name;
49307c478bd9Sstevel@tonic-gate 		flags = ifrf.lifr_flags;
49317c478bd9Sstevel@tonic-gate 
49327c478bd9Sstevel@tonic-gate 		if (tTd(0, 41))
49337c478bd9Sstevel@tonic-gate 			sm_dprintf("\tflags: %lx\n", (unsigned long) flags);
49347c478bd9Sstevel@tonic-gate 
49357c478bd9Sstevel@tonic-gate 		if (!bitset(IFF_UP, flags))
49367c478bd9Sstevel@tonic-gate 			continue;
49377c478bd9Sstevel@tonic-gate #  endif /* SIOCGLIFFLAGS */
49387c478bd9Sstevel@tonic-gate 
49397c478bd9Sstevel@tonic-gate 		ip_addr[0] = '\0';
49407c478bd9Sstevel@tonic-gate 
49417c478bd9Sstevel@tonic-gate 		/* extract IP address from the list*/
49427c478bd9Sstevel@tonic-gate 		switch (af)
49437c478bd9Sstevel@tonic-gate 		{
49447c478bd9Sstevel@tonic-gate 		  case AF_INET6:
49457c478bd9Sstevel@tonic-gate #  ifdef __KAME__
49467c478bd9Sstevel@tonic-gate 			/* convert into proper scoped address */
49477c478bd9Sstevel@tonic-gate 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
49487c478bd9Sstevel@tonic-gate 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
49497c478bd9Sstevel@tonic-gate 			    sa->sin6.sin6_scope_id == 0)
49507c478bd9Sstevel@tonic-gate 			{
49517c478bd9Sstevel@tonic-gate 				struct in6_addr *ia6p;
49527c478bd9Sstevel@tonic-gate 
49537c478bd9Sstevel@tonic-gate 				ia6p = &sa->sin6.sin6_addr;
49547c478bd9Sstevel@tonic-gate 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
49557c478bd9Sstevel@tonic-gate 							       ((unsigned int)ia6p->s6_addr[2] << 8));
49567c478bd9Sstevel@tonic-gate 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
49577c478bd9Sstevel@tonic-gate 			}
49587c478bd9Sstevel@tonic-gate #  endif /* __KAME__ */
49597c478bd9Sstevel@tonic-gate 			ia6 = sa->sin6.sin6_addr;
49607c478bd9Sstevel@tonic-gate 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
49617c478bd9Sstevel@tonic-gate 			{
49627c478bd9Sstevel@tonic-gate 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
49637c478bd9Sstevel@tonic-gate 				message("WARNING: interface %s is UP with %s address",
49647c478bd9Sstevel@tonic-gate 					name, addr == NULL ? "(NULL)" : addr);
49657c478bd9Sstevel@tonic-gate 				continue;
49667c478bd9Sstevel@tonic-gate 			}
49677c478bd9Sstevel@tonic-gate 
49687c478bd9Sstevel@tonic-gate 			/* save IP address in text from */
49697c478bd9Sstevel@tonic-gate 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
49707c478bd9Sstevel@tonic-gate 			if (addr != NULL)
49717c478bd9Sstevel@tonic-gate 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
49727c478bd9Sstevel@tonic-gate 						   "[%.*s]",
49737c478bd9Sstevel@tonic-gate 						   (int) sizeof ip_addr - 3,
49747c478bd9Sstevel@tonic-gate 						   addr);
49757c478bd9Sstevel@tonic-gate 			break;
49767c478bd9Sstevel@tonic-gate 
49777c478bd9Sstevel@tonic-gate 		  case AF_INET:
49787c478bd9Sstevel@tonic-gate 			ia = sa->sin.sin_addr;
49797c478bd9Sstevel@tonic-gate 			if (ia.s_addr == INADDR_ANY ||
49807c478bd9Sstevel@tonic-gate 			    ia.s_addr == INADDR_NONE)
49817c478bd9Sstevel@tonic-gate 			{
49827c478bd9Sstevel@tonic-gate 				message("WARNING: interface %s is UP with %s address",
49837c478bd9Sstevel@tonic-gate 					name, inet_ntoa(ia));
49847c478bd9Sstevel@tonic-gate 				continue;
49857c478bd9Sstevel@tonic-gate 			}
49867c478bd9Sstevel@tonic-gate 
49877c478bd9Sstevel@tonic-gate 			/* save IP address in text from */
49887c478bd9Sstevel@tonic-gate 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
49897c478bd9Sstevel@tonic-gate 					(int) sizeof ip_addr - 3, inet_ntoa(ia));
49907c478bd9Sstevel@tonic-gate 			break;
49917c478bd9Sstevel@tonic-gate 		}
49927c478bd9Sstevel@tonic-gate 
49937c478bd9Sstevel@tonic-gate 		if (*ip_addr == '\0')
49947c478bd9Sstevel@tonic-gate 			continue;
49957c478bd9Sstevel@tonic-gate 
49967c478bd9Sstevel@tonic-gate 		if (!wordinclass(ip_addr, 'w'))
49977c478bd9Sstevel@tonic-gate 		{
49987c478bd9Sstevel@tonic-gate 			setclass('w', ip_addr);
49997c478bd9Sstevel@tonic-gate 			if (tTd(0, 4))
50007c478bd9Sstevel@tonic-gate 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
50017c478bd9Sstevel@tonic-gate 		}
50027c478bd9Sstevel@tonic-gate 
50037c478bd9Sstevel@tonic-gate #  ifdef SIOCGLIFFLAGS
50047c478bd9Sstevel@tonic-gate 		/* skip "loopback" interface "lo" */
50057c478bd9Sstevel@tonic-gate 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
50067c478bd9Sstevel@tonic-gate 		    bitset(IFF_LOOPBACK, flags))
50077c478bd9Sstevel@tonic-gate 			continue;
50087c478bd9Sstevel@tonic-gate #  endif /* SIOCGLIFFLAGS */
50097c478bd9Sstevel@tonic-gate 		(void) add_hostnames(sa);
50107c478bd9Sstevel@tonic-gate 	}
50117c478bd9Sstevel@tonic-gate 	sm_free(buf); /* XXX */
50127c478bd9Sstevel@tonic-gate 	(void) close(s);
50137c478bd9Sstevel@tonic-gate # else /* NETINET6 && defined(SIOCGLIFCONF) */
50147c478bd9Sstevel@tonic-gate #  if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
50157c478bd9Sstevel@tonic-gate 	int s;
50167c478bd9Sstevel@tonic-gate 	int i;
50177c478bd9Sstevel@tonic-gate 	struct ifconf ifc;
50187c478bd9Sstevel@tonic-gate 	int numifs;
50197c478bd9Sstevel@tonic-gate 
50207c478bd9Sstevel@tonic-gate 	s = socket(AF_INET, SOCK_DGRAM, 0);
50217c478bd9Sstevel@tonic-gate 	if (s == -1)
50227c478bd9Sstevel@tonic-gate 		return;
50237c478bd9Sstevel@tonic-gate 
50247c478bd9Sstevel@tonic-gate 	/* get the list of known IP address from the kernel */
50257c478bd9Sstevel@tonic-gate #   if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN
50267c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
50277c478bd9Sstevel@tonic-gate 	{
50287c478bd9Sstevel@tonic-gate 		/* can't get number of interfaces -- fall back */
50297c478bd9Sstevel@tonic-gate 		if (tTd(0, 4))
50307c478bd9Sstevel@tonic-gate 			sm_dprintf("SIOCGIFNUM failed: %s\n",
50317c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
50327c478bd9Sstevel@tonic-gate 		numifs = -1;
50337c478bd9Sstevel@tonic-gate 	}
50347c478bd9Sstevel@tonic-gate 	else if (tTd(0, 42))
50357c478bd9Sstevel@tonic-gate 		sm_dprintf("system has %d interfaces\n", numifs);
50367c478bd9Sstevel@tonic-gate 	if (numifs < 0)
50377c478bd9Sstevel@tonic-gate #   endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */
50387c478bd9Sstevel@tonic-gate 		numifs = MAXINTERFACES;
50397c478bd9Sstevel@tonic-gate 
50407c478bd9Sstevel@tonic-gate 	if (numifs <= 0)
50417c478bd9Sstevel@tonic-gate 	{
50427c478bd9Sstevel@tonic-gate 		(void) close(s);
50437c478bd9Sstevel@tonic-gate 		return;
50447c478bd9Sstevel@tonic-gate 	}
50457c478bd9Sstevel@tonic-gate 	ifc.ifc_len = numifs * sizeof (struct ifreq);
50467c478bd9Sstevel@tonic-gate 	ifc.ifc_buf = xalloc(ifc.ifc_len);
50477c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
50487c478bd9Sstevel@tonic-gate 	{
50497c478bd9Sstevel@tonic-gate 		if (tTd(0, 4))
50507c478bd9Sstevel@tonic-gate 			sm_dprintf("SIOCGIFCONF failed: %s\n",
50517c478bd9Sstevel@tonic-gate 				   sm_errstring(errno));
50527c478bd9Sstevel@tonic-gate 		(void) close(s);
50537c478bd9Sstevel@tonic-gate 		return;
50547c478bd9Sstevel@tonic-gate 	}
50557c478bd9Sstevel@tonic-gate 
50567c478bd9Sstevel@tonic-gate 	/* scan the list of IP address */
50577c478bd9Sstevel@tonic-gate 	if (tTd(0, 40))
50587c478bd9Sstevel@tonic-gate 		sm_dprintf("scanning for interface specific names, ifc_len=%d\n",
50597c478bd9Sstevel@tonic-gate 			ifc.ifc_len);
50607c478bd9Sstevel@tonic-gate 
50617c478bd9Sstevel@tonic-gate 	for (i = 0; i < ifc.ifc_len && i >= 0; )
50627c478bd9Sstevel@tonic-gate 	{
50637c478bd9Sstevel@tonic-gate 		int af;
50647c478bd9Sstevel@tonic-gate 		struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
50657c478bd9Sstevel@tonic-gate 		SOCKADDR *sa = (SOCKADDR *) &ifr->ifr_addr;
50667c478bd9Sstevel@tonic-gate #   if NETINET6
50677c478bd9Sstevel@tonic-gate 		char *addr;
50687c478bd9Sstevel@tonic-gate 		struct in6_addr ia6;
50697c478bd9Sstevel@tonic-gate #   endif /* NETINET6 */
50707c478bd9Sstevel@tonic-gate 		struct in_addr ia;
50717c478bd9Sstevel@tonic-gate #   ifdef SIOCGIFFLAGS
50727c478bd9Sstevel@tonic-gate 		struct ifreq ifrf;
50737c478bd9Sstevel@tonic-gate #   endif /* SIOCGIFFLAGS */
50747c478bd9Sstevel@tonic-gate 		char ip_addr[256];
50757c478bd9Sstevel@tonic-gate #   if NETINET6
50767c478bd9Sstevel@tonic-gate 		char buf6[INET6_ADDRSTRLEN];
50777c478bd9Sstevel@tonic-gate #   endif /* NETINET6 */
50787c478bd9Sstevel@tonic-gate 
50797c478bd9Sstevel@tonic-gate 		/*
50807c478bd9Sstevel@tonic-gate 		**  If we don't have a complete ifr structure,
50817c478bd9Sstevel@tonic-gate 		**  don't try to use it.
50827c478bd9Sstevel@tonic-gate 		*/
50837c478bd9Sstevel@tonic-gate 
50847c478bd9Sstevel@tonic-gate 		if ((ifc.ifc_len - i) < sizeof *ifr)
50857c478bd9Sstevel@tonic-gate 			break;
50867c478bd9Sstevel@tonic-gate 
50877c478bd9Sstevel@tonic-gate #   ifdef BSD4_4_SOCKADDR
50887c478bd9Sstevel@tonic-gate 		if (sa->sa.sa_len > sizeof ifr->ifr_addr)
50897c478bd9Sstevel@tonic-gate 			i += sizeof ifr->ifr_name + sa->sa.sa_len;
50907c478bd9Sstevel@tonic-gate 		else
50917c478bd9Sstevel@tonic-gate #   endif /* BSD4_4_SOCKADDR */
50927c478bd9Sstevel@tonic-gate 			i += sizeof *ifr;
50937c478bd9Sstevel@tonic-gate 
50947c478bd9Sstevel@tonic-gate 		if (tTd(0, 20))
50957c478bd9Sstevel@tonic-gate 			sm_dprintf("%s\n", anynet_ntoa(sa));
50967c478bd9Sstevel@tonic-gate 
50977c478bd9Sstevel@tonic-gate 		af = ifr->ifr_addr.sa_family;
50987c478bd9Sstevel@tonic-gate 		if (af != AF_INET
50997c478bd9Sstevel@tonic-gate #   if NETINET6
51007c478bd9Sstevel@tonic-gate 		    && af != AF_INET6
51017c478bd9Sstevel@tonic-gate #   endif /* NETINET6 */
51027c478bd9Sstevel@tonic-gate 		    )
51037c478bd9Sstevel@tonic-gate 			continue;
51047c478bd9Sstevel@tonic-gate 
51057c478bd9Sstevel@tonic-gate #   ifdef SIOCGIFFLAGS
51067c478bd9Sstevel@tonic-gate 		memset(&ifrf, '\0', sizeof(struct ifreq));
51077c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name,
51087c478bd9Sstevel@tonic-gate 			       sizeof(ifrf.ifr_name));
51097c478bd9Sstevel@tonic-gate 		(void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
51107c478bd9Sstevel@tonic-gate 		if (tTd(0, 41))
51117c478bd9Sstevel@tonic-gate 			sm_dprintf("\tflags: %lx\n",
51127c478bd9Sstevel@tonic-gate 				(unsigned long) ifrf.ifr_flags);
51137c478bd9Sstevel@tonic-gate #    define IFRFREF ifrf
51147c478bd9Sstevel@tonic-gate #   else /* SIOCGIFFLAGS */
51157c478bd9Sstevel@tonic-gate #    define IFRFREF (*ifr)
51167c478bd9Sstevel@tonic-gate #   endif /* SIOCGIFFLAGS */
51177c478bd9Sstevel@tonic-gate 
51187c478bd9Sstevel@tonic-gate 		if (!bitset(IFF_UP, IFRFREF.ifr_flags))
51197c478bd9Sstevel@tonic-gate 			continue;
51207c478bd9Sstevel@tonic-gate 
51217c478bd9Sstevel@tonic-gate 		ip_addr[0] = '\0';
51227c478bd9Sstevel@tonic-gate 
51237c478bd9Sstevel@tonic-gate 		/* extract IP address from the list*/
51247c478bd9Sstevel@tonic-gate 		switch (af)
51257c478bd9Sstevel@tonic-gate 		{
51267c478bd9Sstevel@tonic-gate 		  case AF_INET:
51277c478bd9Sstevel@tonic-gate 			ia = sa->sin.sin_addr;
51287c478bd9Sstevel@tonic-gate 			if (ia.s_addr == INADDR_ANY ||
51297c478bd9Sstevel@tonic-gate 			    ia.s_addr == INADDR_NONE)
51307c478bd9Sstevel@tonic-gate 			{
51317c478bd9Sstevel@tonic-gate 				message("WARNING: interface %s is UP with %s address",
51327c478bd9Sstevel@tonic-gate 					ifr->ifr_name, inet_ntoa(ia));
51337c478bd9Sstevel@tonic-gate 				continue;
51347c478bd9Sstevel@tonic-gate 			}
51357c478bd9Sstevel@tonic-gate 
51367c478bd9Sstevel@tonic-gate 			/* save IP address in text from */
51377c478bd9Sstevel@tonic-gate 			(void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]",
51387c478bd9Sstevel@tonic-gate 					(int) sizeof ip_addr - 3,
51397c478bd9Sstevel@tonic-gate 					inet_ntoa(ia));
51407c478bd9Sstevel@tonic-gate 			break;
51417c478bd9Sstevel@tonic-gate 
51427c478bd9Sstevel@tonic-gate #   if NETINET6
51437c478bd9Sstevel@tonic-gate 		  case AF_INET6:
51447c478bd9Sstevel@tonic-gate #    ifdef __KAME__
51457c478bd9Sstevel@tonic-gate 			/* convert into proper scoped address */
51467c478bd9Sstevel@tonic-gate 			if ((IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr) ||
51477c478bd9Sstevel@tonic-gate 			     IN6_IS_ADDR_SITELOCAL(&sa->sin6.sin6_addr)) &&
51487c478bd9Sstevel@tonic-gate 			    sa->sin6.sin6_scope_id == 0)
51497c478bd9Sstevel@tonic-gate 			{
51507c478bd9Sstevel@tonic-gate 				struct in6_addr *ia6p;
51517c478bd9Sstevel@tonic-gate 
51527c478bd9Sstevel@tonic-gate 				ia6p = &sa->sin6.sin6_addr;
51537c478bd9Sstevel@tonic-gate 				sa->sin6.sin6_scope_id = ntohs(ia6p->s6_addr[3] |
51547c478bd9Sstevel@tonic-gate 							       ((unsigned int)ia6p->s6_addr[2] << 8));
51557c478bd9Sstevel@tonic-gate 				ia6p->s6_addr[2] = ia6p->s6_addr[3] = 0;
51567c478bd9Sstevel@tonic-gate 			}
51577c478bd9Sstevel@tonic-gate #    endif /* __KAME__ */
51587c478bd9Sstevel@tonic-gate 			ia6 = sa->sin6.sin6_addr;
51597c478bd9Sstevel@tonic-gate 			if (IN6_IS_ADDR_UNSPECIFIED(&ia6))
51607c478bd9Sstevel@tonic-gate 			{
51617c478bd9Sstevel@tonic-gate 				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
51627c478bd9Sstevel@tonic-gate 				message("WARNING: interface %s is UP with %s address",
51637c478bd9Sstevel@tonic-gate 					ifr->ifr_name,
51647c478bd9Sstevel@tonic-gate 					addr == NULL ? "(NULL)" : addr);
51657c478bd9Sstevel@tonic-gate 				continue;
51667c478bd9Sstevel@tonic-gate 			}
51677c478bd9Sstevel@tonic-gate 
51687c478bd9Sstevel@tonic-gate 			/* save IP address in text from */
51697c478bd9Sstevel@tonic-gate 			addr = anynet_ntop(&ia6, buf6, sizeof buf6);
51707c478bd9Sstevel@tonic-gate 			if (addr != NULL)
51717c478bd9Sstevel@tonic-gate 				(void) sm_snprintf(ip_addr, sizeof ip_addr,
51727c478bd9Sstevel@tonic-gate 						   "[%.*s]",
51737c478bd9Sstevel@tonic-gate 						   (int) sizeof ip_addr - 3,
51747c478bd9Sstevel@tonic-gate 						   addr);
51757c478bd9Sstevel@tonic-gate 			break;
51767c478bd9Sstevel@tonic-gate 
51777c478bd9Sstevel@tonic-gate #   endif /* NETINET6 */
51787c478bd9Sstevel@tonic-gate 		}
51797c478bd9Sstevel@tonic-gate 
51807c478bd9Sstevel@tonic-gate 		if (ip_addr[0] == '\0')
51817c478bd9Sstevel@tonic-gate 			continue;
51827c478bd9Sstevel@tonic-gate 
51837c478bd9Sstevel@tonic-gate 		if (!wordinclass(ip_addr, 'w'))
51847c478bd9Sstevel@tonic-gate 		{
51857c478bd9Sstevel@tonic-gate 			setclass('w', ip_addr);
51867c478bd9Sstevel@tonic-gate 			if (tTd(0, 4))
51877c478bd9Sstevel@tonic-gate 				sm_dprintf("\ta.k.a.: %s\n", ip_addr);
51887c478bd9Sstevel@tonic-gate 		}
51897c478bd9Sstevel@tonic-gate 
51907c478bd9Sstevel@tonic-gate 		/* skip "loopback" interface "lo" */
51917c478bd9Sstevel@tonic-gate 		if (DontProbeInterfaces == DPI_SKIPLOOPBACK &&
51927c478bd9Sstevel@tonic-gate 		    bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
51937c478bd9Sstevel@tonic-gate 			continue;
51947c478bd9Sstevel@tonic-gate 
51957c478bd9Sstevel@tonic-gate 		(void) add_hostnames(sa);
51967c478bd9Sstevel@tonic-gate 	}
51977c478bd9Sstevel@tonic-gate 	sm_free(ifc.ifc_buf); /* XXX */
51987c478bd9Sstevel@tonic-gate 	(void) close(s);
51997c478bd9Sstevel@tonic-gate #   undef IFRFREF
52007c478bd9Sstevel@tonic-gate #  endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
52017c478bd9Sstevel@tonic-gate # endif /* NETINET6 && defined(SIOCGLIFCONF) */
52027c478bd9Sstevel@tonic-gate }
52037c478bd9Sstevel@tonic-gate /*
52047c478bd9Sstevel@tonic-gate **  ISLOOPBACK -- is socket address in the loopback net?
52057c478bd9Sstevel@tonic-gate **
52067c478bd9Sstevel@tonic-gate **	Parameters:
52077c478bd9Sstevel@tonic-gate **		sa -- socket address.
52087c478bd9Sstevel@tonic-gate **
52097c478bd9Sstevel@tonic-gate **	Returns:
52107c478bd9Sstevel@tonic-gate **		true -- is socket address in the loopback net?
52117c478bd9Sstevel@tonic-gate **		false -- otherwise
52127c478bd9Sstevel@tonic-gate **
52137c478bd9Sstevel@tonic-gate */
52147c478bd9Sstevel@tonic-gate 
52157c478bd9Sstevel@tonic-gate bool
52167c478bd9Sstevel@tonic-gate isloopback(sa)
52177c478bd9Sstevel@tonic-gate 	SOCKADDR sa;
52187c478bd9Sstevel@tonic-gate {
52197c478bd9Sstevel@tonic-gate #if NETINET6
52207c478bd9Sstevel@tonic-gate 	if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
52217c478bd9Sstevel@tonic-gate 		return true;
52227c478bd9Sstevel@tonic-gate #else /* NETINET6 */
52237c478bd9Sstevel@tonic-gate 	/* XXX how to correctly extract IN_LOOPBACKNET part? */
52247c478bd9Sstevel@tonic-gate 	if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET)
52257c478bd9Sstevel@tonic-gate 	     >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
52267c478bd9Sstevel@tonic-gate 		return true;
52277c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
52287c478bd9Sstevel@tonic-gate 	return false;
52297c478bd9Sstevel@tonic-gate }
52307c478bd9Sstevel@tonic-gate /*
52317c478bd9Sstevel@tonic-gate **  GET_NUM_PROCS_ONLINE -- return the number of processors currently online
52327c478bd9Sstevel@tonic-gate **
52337c478bd9Sstevel@tonic-gate **	Parameters:
52347c478bd9Sstevel@tonic-gate **		none.
52357c478bd9Sstevel@tonic-gate **
52367c478bd9Sstevel@tonic-gate **	Returns:
52377c478bd9Sstevel@tonic-gate **		The number of processors online.
52387c478bd9Sstevel@tonic-gate */
52397c478bd9Sstevel@tonic-gate 
52407c478bd9Sstevel@tonic-gate static int
52417c478bd9Sstevel@tonic-gate get_num_procs_online()
52427c478bd9Sstevel@tonic-gate {
52437c478bd9Sstevel@tonic-gate 	int nproc = 0;
52447c478bd9Sstevel@tonic-gate 
52457c478bd9Sstevel@tonic-gate #ifdef USESYSCTL
52467c478bd9Sstevel@tonic-gate # if defined(CTL_HW) && defined(HW_NCPU)
52477c478bd9Sstevel@tonic-gate 	size_t sz;
52487c478bd9Sstevel@tonic-gate 	int mib[2];
52497c478bd9Sstevel@tonic-gate 
52507c478bd9Sstevel@tonic-gate 	mib[0] = CTL_HW;
52517c478bd9Sstevel@tonic-gate 	mib[1] = HW_NCPU;
52527c478bd9Sstevel@tonic-gate 	sz = (size_t) sizeof nproc;
52537c478bd9Sstevel@tonic-gate 	(void) sysctl(mib, 2, &nproc, &sz, NULL, 0);
52547c478bd9Sstevel@tonic-gate # endif /* defined(CTL_HW) && defined(HW_NCPU) */
52557c478bd9Sstevel@tonic-gate #else /* USESYSCTL */
52567c478bd9Sstevel@tonic-gate # ifdef _SC_NPROCESSORS_ONLN
52577c478bd9Sstevel@tonic-gate 	nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
52587c478bd9Sstevel@tonic-gate # else /* _SC_NPROCESSORS_ONLN */
52597c478bd9Sstevel@tonic-gate #  ifdef __hpux
52607c478bd9Sstevel@tonic-gate #   include <sys/pstat.h>
52617c478bd9Sstevel@tonic-gate 	struct pst_dynamic psd;
52627c478bd9Sstevel@tonic-gate 
52637c478bd9Sstevel@tonic-gate 	if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1)
52647c478bd9Sstevel@tonic-gate 		nproc = psd.psd_proc_cnt;
52657c478bd9Sstevel@tonic-gate #  endif /* __hpux */
52667c478bd9Sstevel@tonic-gate # endif /* _SC_NPROCESSORS_ONLN */
52677c478bd9Sstevel@tonic-gate #endif /* USESYSCTL */
52687c478bd9Sstevel@tonic-gate 
52697c478bd9Sstevel@tonic-gate 	if (nproc <= 0)
52707c478bd9Sstevel@tonic-gate 		nproc = 1;
52717c478bd9Sstevel@tonic-gate 	return nproc;
52727c478bd9Sstevel@tonic-gate }
52737c478bd9Sstevel@tonic-gate /*
52747c478bd9Sstevel@tonic-gate **  SM_CLOSEFROM -- close file descriptors
52757c478bd9Sstevel@tonic-gate **
52767c478bd9Sstevel@tonic-gate **	Parameters:
52777c478bd9Sstevel@tonic-gate **		lowest -- first fd to close
52787c478bd9Sstevel@tonic-gate **		highest -- last fd + 1 to close
52797c478bd9Sstevel@tonic-gate **
52807c478bd9Sstevel@tonic-gate **	Returns:
52817c478bd9Sstevel@tonic-gate **		none
52827c478bd9Sstevel@tonic-gate */
52837c478bd9Sstevel@tonic-gate 
52847c478bd9Sstevel@tonic-gate void
52857c478bd9Sstevel@tonic-gate sm_closefrom(lowest, highest)
52867c478bd9Sstevel@tonic-gate 	int lowest, highest;
52877c478bd9Sstevel@tonic-gate {
52887c478bd9Sstevel@tonic-gate #if HASCLOSEFROM
52897c478bd9Sstevel@tonic-gate 	closefrom(lowest);
52907c478bd9Sstevel@tonic-gate #else /* HASCLOSEFROM */
52917c478bd9Sstevel@tonic-gate 	int i;
52927c478bd9Sstevel@tonic-gate 
52937c478bd9Sstevel@tonic-gate 	for (i = lowest; i < highest; i++)
52947c478bd9Sstevel@tonic-gate 		(void) close(i);
52957c478bd9Sstevel@tonic-gate #endif /* HASCLOSEFROM */
52967c478bd9Sstevel@tonic-gate }
52977c478bd9Sstevel@tonic-gate #if HASFDWALK
52987c478bd9Sstevel@tonic-gate /*
52997c478bd9Sstevel@tonic-gate **  CLOSEFD_WALK -- walk fd's arranging to close them
53007c478bd9Sstevel@tonic-gate **	Callback for fdwalk()
53017c478bd9Sstevel@tonic-gate **
53027c478bd9Sstevel@tonic-gate **	Parameters:
53037c478bd9Sstevel@tonic-gate **		lowest -- first fd to arrange to be closed
53047c478bd9Sstevel@tonic-gate **		fd -- fd to arrange to be closed
53057c478bd9Sstevel@tonic-gate **
53067c478bd9Sstevel@tonic-gate **	Returns:
53077c478bd9Sstevel@tonic-gate **		zero
53087c478bd9Sstevel@tonic-gate */
53097c478bd9Sstevel@tonic-gate 
53107c478bd9Sstevel@tonic-gate static int
53117c478bd9Sstevel@tonic-gate closefd_walk(lowest, fd)
53127c478bd9Sstevel@tonic-gate 	void *lowest;
53137c478bd9Sstevel@tonic-gate 	int fd;
53147c478bd9Sstevel@tonic-gate {
53157c478bd9Sstevel@tonic-gate 	if (fd >= *(int *)lowest)
53167c478bd9Sstevel@tonic-gate 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
53177c478bd9Sstevel@tonic-gate 	return 0;
53187c478bd9Sstevel@tonic-gate }
53197c478bd9Sstevel@tonic-gate #endif /* HASFDWALK */
53207c478bd9Sstevel@tonic-gate /*
53217c478bd9Sstevel@tonic-gate **  SM_CLOSE_ON_EXEC -- arrange for file descriptors to be closed
53227c478bd9Sstevel@tonic-gate **
53237c478bd9Sstevel@tonic-gate **	Parameters:
53247c478bd9Sstevel@tonic-gate **		lowest -- first fd to arrange to be closed
53257c478bd9Sstevel@tonic-gate **		highest -- last fd + 1 to arrange to be closed
53267c478bd9Sstevel@tonic-gate **
53277c478bd9Sstevel@tonic-gate **	Returns:
53287c478bd9Sstevel@tonic-gate **		none
53297c478bd9Sstevel@tonic-gate */
53307c478bd9Sstevel@tonic-gate 
53317c478bd9Sstevel@tonic-gate void
53327c478bd9Sstevel@tonic-gate sm_close_on_exec(highest, lowest)
53337c478bd9Sstevel@tonic-gate 	int highest, lowest;
53347c478bd9Sstevel@tonic-gate {
53357c478bd9Sstevel@tonic-gate #if HASFDWALK
53367c478bd9Sstevel@tonic-gate 	(void) fdwalk(closefd_walk, &lowest);
53377c478bd9Sstevel@tonic-gate #else /* HASFDWALK */
53387c478bd9Sstevel@tonic-gate 	int i, j;
53397c478bd9Sstevel@tonic-gate 
53407c478bd9Sstevel@tonic-gate 	for (i = lowest; i < highest; i++)
53417c478bd9Sstevel@tonic-gate 	{
53427c478bd9Sstevel@tonic-gate 		if ((j = fcntl(i, F_GETFD, 0)) != -1)
53437c478bd9Sstevel@tonic-gate 			(void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
53447c478bd9Sstevel@tonic-gate 	}
53457c478bd9Sstevel@tonic-gate #endif /* HASFDWALK */
53467c478bd9Sstevel@tonic-gate }
53477c478bd9Sstevel@tonic-gate /*
53487c478bd9Sstevel@tonic-gate **  SEED_RANDOM -- seed the random number generator
53497c478bd9Sstevel@tonic-gate **
53507c478bd9Sstevel@tonic-gate **	Parameters:
53517c478bd9Sstevel@tonic-gate **		none
53527c478bd9Sstevel@tonic-gate **
53537c478bd9Sstevel@tonic-gate **	Returns:
53547c478bd9Sstevel@tonic-gate **		none
53557c478bd9Sstevel@tonic-gate */
53567c478bd9Sstevel@tonic-gate 
53577c478bd9Sstevel@tonic-gate void
53587c478bd9Sstevel@tonic-gate seed_random()
53597c478bd9Sstevel@tonic-gate {
53607c478bd9Sstevel@tonic-gate #if HASSRANDOMDEV
53617c478bd9Sstevel@tonic-gate 	srandomdev();
53627c478bd9Sstevel@tonic-gate #else /* HASSRANDOMDEV */
53637c478bd9Sstevel@tonic-gate 	long seed;
53647c478bd9Sstevel@tonic-gate 	struct timeval t;
53657c478bd9Sstevel@tonic-gate 
53667c478bd9Sstevel@tonic-gate 	seed = (long) CurrentPid;
53677c478bd9Sstevel@tonic-gate 	if (gettimeofday(&t, NULL) >= 0)
53687c478bd9Sstevel@tonic-gate 		seed += t.tv_sec + t.tv_usec;
53697c478bd9Sstevel@tonic-gate 
53707c478bd9Sstevel@tonic-gate # if HASRANDOM
53717c478bd9Sstevel@tonic-gate 	(void) srandom(seed);
53727c478bd9Sstevel@tonic-gate # else /* HASRANDOM */
53737c478bd9Sstevel@tonic-gate 	(void) srand((unsigned int) seed);
53747c478bd9Sstevel@tonic-gate # endif /* HASRANDOM */
53757c478bd9Sstevel@tonic-gate #endif /* HASSRANDOMDEV */
53767c478bd9Sstevel@tonic-gate }
53777c478bd9Sstevel@tonic-gate /*
53787c478bd9Sstevel@tonic-gate **  SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
53797c478bd9Sstevel@tonic-gate **
53807c478bd9Sstevel@tonic-gate **	Parameters:
53817c478bd9Sstevel@tonic-gate **		level -- syslog level
53827c478bd9Sstevel@tonic-gate **		id -- envelope ID or NULL (NOQUEUE)
53837c478bd9Sstevel@tonic-gate **		fmt -- format string
53847c478bd9Sstevel@tonic-gate **		arg... -- arguments as implied by fmt.
53857c478bd9Sstevel@tonic-gate **
53867c478bd9Sstevel@tonic-gate **	Returns:
53877c478bd9Sstevel@tonic-gate **		none
53887c478bd9Sstevel@tonic-gate */
53897c478bd9Sstevel@tonic-gate 
53907c478bd9Sstevel@tonic-gate /* VARARGS3 */
53917c478bd9Sstevel@tonic-gate void
53927c478bd9Sstevel@tonic-gate #ifdef __STDC__
53937c478bd9Sstevel@tonic-gate sm_syslog(int level, const char *id, const char *fmt, ...)
53947c478bd9Sstevel@tonic-gate #else /* __STDC__ */
53957c478bd9Sstevel@tonic-gate sm_syslog(level, id, fmt, va_alist)
53967c478bd9Sstevel@tonic-gate 	int level;
53977c478bd9Sstevel@tonic-gate 	const char *id;
53987c478bd9Sstevel@tonic-gate 	const char *fmt;
53997c478bd9Sstevel@tonic-gate 	va_dcl
54007c478bd9Sstevel@tonic-gate #endif /* __STDC__ */
54017c478bd9Sstevel@tonic-gate {
5402445f2479Sjbeck 	char *buf;
5403445f2479Sjbeck 	size_t bufsize;
54047c478bd9Sstevel@tonic-gate 	char *begin, *end;
54057c478bd9Sstevel@tonic-gate 	int save_errno;
54067c478bd9Sstevel@tonic-gate 	int seq = 1;
54077c478bd9Sstevel@tonic-gate 	int idlen;
54087c478bd9Sstevel@tonic-gate 	char buf0[MAXLINE];
54097c478bd9Sstevel@tonic-gate 	char *newstring;
54107c478bd9Sstevel@tonic-gate 	extern int SyslogPrefixLen;
54117c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
54127c478bd9Sstevel@tonic-gate 
54137c478bd9Sstevel@tonic-gate 	save_errno = errno;
54147c478bd9Sstevel@tonic-gate 	if (id == NULL)
54157c478bd9Sstevel@tonic-gate 	{
54167c478bd9Sstevel@tonic-gate 		id = "NOQUEUE";
54177c478bd9Sstevel@tonic-gate 		idlen = strlen(id) + SyslogPrefixLen;
54187c478bd9Sstevel@tonic-gate 	}
54197c478bd9Sstevel@tonic-gate 	else if (strcmp(id, NOQID) == 0)
54207c478bd9Sstevel@tonic-gate 	{
54217c478bd9Sstevel@tonic-gate 		id = "";
54227c478bd9Sstevel@tonic-gate 		idlen = SyslogPrefixLen;
54237c478bd9Sstevel@tonic-gate 	}
54247c478bd9Sstevel@tonic-gate 	else
54257c478bd9Sstevel@tonic-gate 		idlen = strlen(id) + SyslogPrefixLen;
54267c478bd9Sstevel@tonic-gate 
54277c478bd9Sstevel@tonic-gate 	buf = buf0;
54287c478bd9Sstevel@tonic-gate 	bufsize = sizeof buf0;
54297c478bd9Sstevel@tonic-gate 
54307c478bd9Sstevel@tonic-gate 	for (;;)
54317c478bd9Sstevel@tonic-gate 	{
54327c478bd9Sstevel@tonic-gate 		int n;
54337c478bd9Sstevel@tonic-gate 
54347c478bd9Sstevel@tonic-gate 		/* print log message into buf */
54357c478bd9Sstevel@tonic-gate 		SM_VA_START(ap, fmt);
54367c478bd9Sstevel@tonic-gate 		n = sm_vsnprintf(buf, bufsize, fmt, ap);
54377c478bd9Sstevel@tonic-gate 		SM_VA_END(ap);
54387c478bd9Sstevel@tonic-gate 		SM_ASSERT(n > 0);
54397c478bd9Sstevel@tonic-gate 		if (n < bufsize)
54407c478bd9Sstevel@tonic-gate 			break;
54417c478bd9Sstevel@tonic-gate 
54427c478bd9Sstevel@tonic-gate 		/* String too small, redo with correct size */
54437c478bd9Sstevel@tonic-gate 		bufsize = n + 1;
54447c478bd9Sstevel@tonic-gate 		if (buf != buf0)
54457c478bd9Sstevel@tonic-gate 		{
54467c478bd9Sstevel@tonic-gate 			sm_free(buf);
54477c478bd9Sstevel@tonic-gate 			buf = NULL;
54487c478bd9Sstevel@tonic-gate 		}
54497c478bd9Sstevel@tonic-gate 		buf = sm_malloc_x(bufsize);
54507c478bd9Sstevel@tonic-gate 	}
54517c478bd9Sstevel@tonic-gate 
54527c478bd9Sstevel@tonic-gate 	/* clean up buf after it has been expanded with args */
54537c478bd9Sstevel@tonic-gate 	newstring = str2prt(buf);
54547c478bd9Sstevel@tonic-gate 	if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE)
54557c478bd9Sstevel@tonic-gate 	{
54567c478bd9Sstevel@tonic-gate #if LOG
54577c478bd9Sstevel@tonic-gate 		if (*id == '\0')
54587c478bd9Sstevel@tonic-gate 			syslog(level, "%s", newstring);
54597c478bd9Sstevel@tonic-gate 		else
54607c478bd9Sstevel@tonic-gate 			syslog(level, "%s: %s", id, newstring);
54617c478bd9Sstevel@tonic-gate #else /* LOG */
54627c478bd9Sstevel@tonic-gate 		/*XXX should do something more sensible */
54637c478bd9Sstevel@tonic-gate 		if (*id == '\0')
54647c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n",
54657c478bd9Sstevel@tonic-gate 					     newstring);
54667c478bd9Sstevel@tonic-gate 		else
54677c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
54687c478bd9Sstevel@tonic-gate 					     "%s: %s\n", id, newstring);
54697c478bd9Sstevel@tonic-gate #endif /* LOG */
5470445f2479Sjbeck 		if (buf != buf0)
5471445f2479Sjbeck 			sm_free(buf);
54727c478bd9Sstevel@tonic-gate 		errno = save_errno;
54737c478bd9Sstevel@tonic-gate 		return;
54747c478bd9Sstevel@tonic-gate 	}
54757c478bd9Sstevel@tonic-gate 
54767c478bd9Sstevel@tonic-gate /*
54777c478bd9Sstevel@tonic-gate **  additional length for splitting: " ..." + 3, where 3 is magic to
54787c478bd9Sstevel@tonic-gate **  have some data for the next entry.
54797c478bd9Sstevel@tonic-gate */
54807c478bd9Sstevel@tonic-gate 
54817c478bd9Sstevel@tonic-gate #define SL_SPLIT 7
54827c478bd9Sstevel@tonic-gate 
54837c478bd9Sstevel@tonic-gate 	begin = newstring;
54847c478bd9Sstevel@tonic-gate 	idlen += 5;	/* strlen("[999]"), see below */
54857c478bd9Sstevel@tonic-gate 	while (*begin != '\0' &&
54867c478bd9Sstevel@tonic-gate 	       (strlen(begin) + idlen) > SYSLOG_BUFSIZE)
54877c478bd9Sstevel@tonic-gate 	{
54887c478bd9Sstevel@tonic-gate 		char save;
54897c478bd9Sstevel@tonic-gate 
54907c478bd9Sstevel@tonic-gate 		if (seq >= 999)
54917c478bd9Sstevel@tonic-gate 		{
54927c478bd9Sstevel@tonic-gate 			/* Too many messages */
54937c478bd9Sstevel@tonic-gate 			break;
54947c478bd9Sstevel@tonic-gate 		}
54957c478bd9Sstevel@tonic-gate 		end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
54967c478bd9Sstevel@tonic-gate 		while (end > begin)
54977c478bd9Sstevel@tonic-gate 		{
54987c478bd9Sstevel@tonic-gate 			/* Break on comma or space */
54997c478bd9Sstevel@tonic-gate 			if (*end == ',' || *end == ' ')
55007c478bd9Sstevel@tonic-gate 			{
55017c478bd9Sstevel@tonic-gate 				end++;	  /* Include separator */
55027c478bd9Sstevel@tonic-gate 				break;
55037c478bd9Sstevel@tonic-gate 			}
55047c478bd9Sstevel@tonic-gate 			end--;
55057c478bd9Sstevel@tonic-gate 		}
55067c478bd9Sstevel@tonic-gate 		/* No separator, break midstring... */
55077c478bd9Sstevel@tonic-gate 		if (end == begin)
55087c478bd9Sstevel@tonic-gate 			end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT;
55097c478bd9Sstevel@tonic-gate 		save = *end;
55107c478bd9Sstevel@tonic-gate 		*end = 0;
55117c478bd9Sstevel@tonic-gate #if LOG
55127c478bd9Sstevel@tonic-gate 		syslog(level, "%s[%d]: %s ...", id, seq++, begin);
55137c478bd9Sstevel@tonic-gate #else /* LOG */
55147c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
55157c478bd9Sstevel@tonic-gate 				     "%s[%d]: %s ...\n", id, seq++, begin);
55167c478bd9Sstevel@tonic-gate #endif /* LOG */
55177c478bd9Sstevel@tonic-gate 		*end = save;
55187c478bd9Sstevel@tonic-gate 		begin = end;
55197c478bd9Sstevel@tonic-gate 	}
55207c478bd9Sstevel@tonic-gate 	if (seq >= 999)
55217c478bd9Sstevel@tonic-gate #if LOG
55227c478bd9Sstevel@tonic-gate 		syslog(level, "%s[%d]: log terminated, too many parts",
55237c478bd9Sstevel@tonic-gate 			id, seq);
55247c478bd9Sstevel@tonic-gate #else /* LOG */
55257c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
55267c478bd9Sstevel@tonic-gate 			      "%s[%d]: log terminated, too many parts\n", id, seq);
55277c478bd9Sstevel@tonic-gate #endif /* LOG */
55287c478bd9Sstevel@tonic-gate 	else if (*begin != '\0')
55297c478bd9Sstevel@tonic-gate #if LOG
55307c478bd9Sstevel@tonic-gate 		syslog(level, "%s[%d]: %s", id, seq, begin);
55317c478bd9Sstevel@tonic-gate #else /* LOG */
55327c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
55337c478bd9Sstevel@tonic-gate 				     "%s[%d]: %s\n", id, seq, begin);
55347c478bd9Sstevel@tonic-gate #endif /* LOG */
5535445f2479Sjbeck 	if (buf != buf0)
5536445f2479Sjbeck 		sm_free(buf);
55377c478bd9Sstevel@tonic-gate 	errno = save_errno;
55387c478bd9Sstevel@tonic-gate }
55397c478bd9Sstevel@tonic-gate /*
55407c478bd9Sstevel@tonic-gate **  HARD_SYSLOG -- call syslog repeatedly until it works
55417c478bd9Sstevel@tonic-gate **
55427c478bd9Sstevel@tonic-gate **	Needed on HP-UX, which apparently doesn't guarantee that
55437c478bd9Sstevel@tonic-gate **	syslog succeeds during interrupt handlers.
55447c478bd9Sstevel@tonic-gate */
55457c478bd9Sstevel@tonic-gate 
55467c478bd9Sstevel@tonic-gate #if defined(__hpux) && !defined(HPUX11)
55477c478bd9Sstevel@tonic-gate 
55487c478bd9Sstevel@tonic-gate # define MAXSYSLOGTRIES	100
55497c478bd9Sstevel@tonic-gate # undef syslog
55507c478bd9Sstevel@tonic-gate # ifdef V4FS
55517c478bd9Sstevel@tonic-gate #  define XCNST	const
55527c478bd9Sstevel@tonic-gate #  define CAST	(const char *)
55537c478bd9Sstevel@tonic-gate # else /* V4FS */
55547c478bd9Sstevel@tonic-gate #  define XCNST
55557c478bd9Sstevel@tonic-gate #  define CAST
55567c478bd9Sstevel@tonic-gate # endif /* V4FS */
55577c478bd9Sstevel@tonic-gate 
55587c478bd9Sstevel@tonic-gate void
55597c478bd9Sstevel@tonic-gate # ifdef __STDC__
55607c478bd9Sstevel@tonic-gate hard_syslog(int pri, XCNST char *msg, ...)
55617c478bd9Sstevel@tonic-gate # else /* __STDC__ */
55627c478bd9Sstevel@tonic-gate hard_syslog(pri, msg, va_alist)
55637c478bd9Sstevel@tonic-gate 	int pri;
55647c478bd9Sstevel@tonic-gate 	XCNST char *msg;
55657c478bd9Sstevel@tonic-gate 	va_dcl
55667c478bd9Sstevel@tonic-gate # endif /* __STDC__ */
55677c478bd9Sstevel@tonic-gate {
55687c478bd9Sstevel@tonic-gate 	int i;
55697c478bd9Sstevel@tonic-gate 	char buf[SYSLOG_BUFSIZE];
55707c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
55717c478bd9Sstevel@tonic-gate 
55727c478bd9Sstevel@tonic-gate 	SM_VA_START(ap, msg);
55737c478bd9Sstevel@tonic-gate 	(void) sm_vsnprintf(buf, sizeof buf, msg, ap);
55747c478bd9Sstevel@tonic-gate 	SM_VA_END(ap);
55757c478bd9Sstevel@tonic-gate 
55767c478bd9Sstevel@tonic-gate 	for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; )
55777c478bd9Sstevel@tonic-gate 		continue;
55787c478bd9Sstevel@tonic-gate }
55797c478bd9Sstevel@tonic-gate 
55807c478bd9Sstevel@tonic-gate # undef CAST
55817c478bd9Sstevel@tonic-gate #endif /* defined(__hpux) && !defined(HPUX11) */
55827c478bd9Sstevel@tonic-gate #if NEEDLOCAL_HOSTNAME_LENGTH
55837c478bd9Sstevel@tonic-gate /*
55847c478bd9Sstevel@tonic-gate **  LOCAL_HOSTNAME_LENGTH
55857c478bd9Sstevel@tonic-gate **
55867c478bd9Sstevel@tonic-gate **	This is required to get sendmail to compile against BIND 4.9.x
55877c478bd9Sstevel@tonic-gate **	on Ultrix.
55887c478bd9Sstevel@tonic-gate **
55897c478bd9Sstevel@tonic-gate **	Unfortunately, a Compaq Y2K patch kit provides it without
55907c478bd9Sstevel@tonic-gate **	bumping __RES in /usr/include/resolv.h so we can't automatically
55917c478bd9Sstevel@tonic-gate **	figure out whether it is needed.
55927c478bd9Sstevel@tonic-gate */
55937c478bd9Sstevel@tonic-gate 
55947c478bd9Sstevel@tonic-gate int
55957c478bd9Sstevel@tonic-gate local_hostname_length(hostname)
55967c478bd9Sstevel@tonic-gate 	char *hostname;
55977c478bd9Sstevel@tonic-gate {
55987c478bd9Sstevel@tonic-gate 	size_t len_host, len_domain;
55997c478bd9Sstevel@tonic-gate 
56007c478bd9Sstevel@tonic-gate 	if (!*_res.defdname)
56017c478bd9Sstevel@tonic-gate 		res_init();
56027c478bd9Sstevel@tonic-gate 	len_host = strlen(hostname);
56037c478bd9Sstevel@tonic-gate 	len_domain = strlen(_res.defdname);
56047c478bd9Sstevel@tonic-gate 	if (len_host > len_domain &&
56057c478bd9Sstevel@tonic-gate 	    (sm_strcasecmp(hostname + len_host - len_domain,
56067c478bd9Sstevel@tonic-gate 			_res.defdname) == 0) &&
56077c478bd9Sstevel@tonic-gate 	    hostname[len_host - len_domain - 1] == '.')
56087c478bd9Sstevel@tonic-gate 		return len_host - len_domain - 1;
56097c478bd9Sstevel@tonic-gate 	else
56107c478bd9Sstevel@tonic-gate 		return 0;
56117c478bd9Sstevel@tonic-gate }
56127c478bd9Sstevel@tonic-gate #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
56137c478bd9Sstevel@tonic-gate 
56147c478bd9Sstevel@tonic-gate #if NEEDLINK
56157c478bd9Sstevel@tonic-gate /*
56167c478bd9Sstevel@tonic-gate **  LINK -- clone a file
56177c478bd9Sstevel@tonic-gate **
56187c478bd9Sstevel@tonic-gate **	Some OS's lacks link() and hard links.  Since sendmail is using
56197c478bd9Sstevel@tonic-gate **	link() as an efficient way to clone files, this implementation
56207c478bd9Sstevel@tonic-gate **	will simply do a file copy.
56217c478bd9Sstevel@tonic-gate **
56227c478bd9Sstevel@tonic-gate **	NOTE: This link() replacement is not a generic replacement as it
56237c478bd9Sstevel@tonic-gate **	does not handle all of the semantics of the real link(2).
56247c478bd9Sstevel@tonic-gate **
56257c478bd9Sstevel@tonic-gate **	Parameters:
56267c478bd9Sstevel@tonic-gate **		source -- pathname of existing file.
56277c478bd9Sstevel@tonic-gate **		target -- pathname of link (clone) to be created.
56287c478bd9Sstevel@tonic-gate **
56297c478bd9Sstevel@tonic-gate **	Returns:
56307c478bd9Sstevel@tonic-gate **		0 -- success.
56317c478bd9Sstevel@tonic-gate **		-1 -- failure, see errno for details.
56327c478bd9Sstevel@tonic-gate */
56337c478bd9Sstevel@tonic-gate 
56347c478bd9Sstevel@tonic-gate int
56357c478bd9Sstevel@tonic-gate link(source, target)
56367c478bd9Sstevel@tonic-gate 	const char *source;
56377c478bd9Sstevel@tonic-gate 	const char *target;
56387c478bd9Sstevel@tonic-gate {
56397c478bd9Sstevel@tonic-gate 	int save_errno;
56407c478bd9Sstevel@tonic-gate 	int sff;
56417c478bd9Sstevel@tonic-gate 	int src = -1, dst = -1;
56427c478bd9Sstevel@tonic-gate 	ssize_t readlen;
56437c478bd9Sstevel@tonic-gate 	ssize_t writelen;
56447c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
56457c478bd9Sstevel@tonic-gate 	struct stat st;
56467c478bd9Sstevel@tonic-gate 
56477c478bd9Sstevel@tonic-gate 	sff = SFF_REGONLY|SFF_OPENASROOT;
56487c478bd9Sstevel@tonic-gate 	if (DontLockReadFiles)
56497c478bd9Sstevel@tonic-gate 		sff |= SFF_NOLOCK;
56507c478bd9Sstevel@tonic-gate 
56517c478bd9Sstevel@tonic-gate 	/* Open the original file */
56527c478bd9Sstevel@tonic-gate 	src = safeopen((char *)source, O_RDONLY, 0, sff);
56537c478bd9Sstevel@tonic-gate 	if (src < 0)
56547c478bd9Sstevel@tonic-gate 		goto fail;
56557c478bd9Sstevel@tonic-gate 
56567c478bd9Sstevel@tonic-gate 	/* Obtain the size and the mode */
56577c478bd9Sstevel@tonic-gate 	if (fstat(src, &st) < 0)
56587c478bd9Sstevel@tonic-gate 		goto fail;
56597c478bd9Sstevel@tonic-gate 
56607c478bd9Sstevel@tonic-gate 	/* Create the duplicate copy */
56617c478bd9Sstevel@tonic-gate 	sff &= ~SFF_NOLOCK;
56627c478bd9Sstevel@tonic-gate 	sff |= SFF_CREAT;
56637c478bd9Sstevel@tonic-gate 	dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY,
56647c478bd9Sstevel@tonic-gate 		       st.st_mode, sff);
56657c478bd9Sstevel@tonic-gate 	if (dst < 0)
56667c478bd9Sstevel@tonic-gate 		goto fail;
56677c478bd9Sstevel@tonic-gate 
56687c478bd9Sstevel@tonic-gate 	/* Copy all of the bytes one buffer at a time */
56697c478bd9Sstevel@tonic-gate 	while ((readlen = read(src, &buf, sizeof(buf))) > 0)
56707c478bd9Sstevel@tonic-gate 	{
56717c478bd9Sstevel@tonic-gate 		ssize_t left = readlen;
56727c478bd9Sstevel@tonic-gate 		char *p = buf;
56737c478bd9Sstevel@tonic-gate 
56747c478bd9Sstevel@tonic-gate 		while (left > 0 &&
56757c478bd9Sstevel@tonic-gate 		       (writelen = write(dst, p, (size_t) left)) >= 0)
56767c478bd9Sstevel@tonic-gate 		{
56777c478bd9Sstevel@tonic-gate 			left -= writelen;
56787c478bd9Sstevel@tonic-gate 			p += writelen;
56797c478bd9Sstevel@tonic-gate 		}
56807c478bd9Sstevel@tonic-gate 		if (writelen < 0)
56817c478bd9Sstevel@tonic-gate 			break;
56827c478bd9Sstevel@tonic-gate 	}
56837c478bd9Sstevel@tonic-gate 
56847c478bd9Sstevel@tonic-gate 	/* Any trouble reading? */
56857c478bd9Sstevel@tonic-gate 	if (readlen < 0 || writelen < 0)
56867c478bd9Sstevel@tonic-gate 		goto fail;
56877c478bd9Sstevel@tonic-gate 
56887c478bd9Sstevel@tonic-gate 	/* Close the input file */
56897c478bd9Sstevel@tonic-gate 	if (close(src) < 0)
56907c478bd9Sstevel@tonic-gate 	{
56917c478bd9Sstevel@tonic-gate 		src = -1;
56927c478bd9Sstevel@tonic-gate 		goto fail;
56937c478bd9Sstevel@tonic-gate 	}
56947c478bd9Sstevel@tonic-gate 	src = -1;
56957c478bd9Sstevel@tonic-gate 
56967c478bd9Sstevel@tonic-gate 	/* Close the output file */
56977c478bd9Sstevel@tonic-gate 	if (close(dst) < 0)
56987c478bd9Sstevel@tonic-gate 	{
56997c478bd9Sstevel@tonic-gate 		/* don't set dst = -1 here so we unlink the file */
57007c478bd9Sstevel@tonic-gate 		goto fail;
57017c478bd9Sstevel@tonic-gate 	}
57027c478bd9Sstevel@tonic-gate 
57037c478bd9Sstevel@tonic-gate 	/* Success */
57047c478bd9Sstevel@tonic-gate 	return 0;
57057c478bd9Sstevel@tonic-gate 
57067c478bd9Sstevel@tonic-gate  fail:
57077c478bd9Sstevel@tonic-gate 	save_errno = errno;
57087c478bd9Sstevel@tonic-gate 	if (src >= 0)
57097c478bd9Sstevel@tonic-gate 		(void) close(src);
57107c478bd9Sstevel@tonic-gate 	if (dst >= 0)
57117c478bd9Sstevel@tonic-gate 	{
57127c478bd9Sstevel@tonic-gate 		(void) unlink(target);
57137c478bd9Sstevel@tonic-gate 		(void) close(dst);
57147c478bd9Sstevel@tonic-gate 	}
57157c478bd9Sstevel@tonic-gate 	errno = save_errno;
57167c478bd9Sstevel@tonic-gate 	return -1;
57177c478bd9Sstevel@tonic-gate }
57187c478bd9Sstevel@tonic-gate #endif /* NEEDLINK */
57197c478bd9Sstevel@tonic-gate 
57207c478bd9Sstevel@tonic-gate /*
57217c478bd9Sstevel@tonic-gate **  Compile-Time options
57227c478bd9Sstevel@tonic-gate */
57237c478bd9Sstevel@tonic-gate 
57247c478bd9Sstevel@tonic-gate char	*CompileOptions[] =
57257c478bd9Sstevel@tonic-gate {
57267c478bd9Sstevel@tonic-gate #if ALLOW_255
57277c478bd9Sstevel@tonic-gate 	"ALLOW_255",
57287c478bd9Sstevel@tonic-gate #endif /* ALLOW_255 */
57297c478bd9Sstevel@tonic-gate #if NAMED_BIND
57307c478bd9Sstevel@tonic-gate # if DNSMAP
57317c478bd9Sstevel@tonic-gate 	"DNSMAP",
57327c478bd9Sstevel@tonic-gate # endif /* DNSMAP */
57337c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
57347c478bd9Sstevel@tonic-gate #if EGD
57357c478bd9Sstevel@tonic-gate 	"EGD",
57367c478bd9Sstevel@tonic-gate #endif /* EGD */
57377c478bd9Sstevel@tonic-gate #if HESIOD
57387c478bd9Sstevel@tonic-gate 	"HESIOD",
57397c478bd9Sstevel@tonic-gate #endif /* HESIOD */
57407c478bd9Sstevel@tonic-gate #if HES_GETMAILHOST
57417c478bd9Sstevel@tonic-gate 	"HES_GETMAILHOST",
57427c478bd9Sstevel@tonic-gate #endif /* HES_GETMAILHOST */
57437c478bd9Sstevel@tonic-gate #if LDAPMAP
57447c478bd9Sstevel@tonic-gate 	"LDAPMAP",
57457c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */
574649218d4fSjbeck #if LDAP_REFERRALS
574749218d4fSjbeck 	"LDAP_REFERRALS",
574849218d4fSjbeck #endif /* LDAP_REFERRALS */
57497c478bd9Sstevel@tonic-gate #if LOG
57507c478bd9Sstevel@tonic-gate 	"LOG",
57517c478bd9Sstevel@tonic-gate #endif /* LOG */
57527c478bd9Sstevel@tonic-gate #if MAP_NSD
57537c478bd9Sstevel@tonic-gate 	"MAP_NSD",
57547c478bd9Sstevel@tonic-gate #endif /* MAP_NSD */
57557c478bd9Sstevel@tonic-gate #if MAP_REGEX
57567c478bd9Sstevel@tonic-gate 	"MAP_REGEX",
57577c478bd9Sstevel@tonic-gate #endif /* MAP_REGEX */
57587c478bd9Sstevel@tonic-gate #if MATCHGECOS
57597c478bd9Sstevel@tonic-gate 	"MATCHGECOS",
57607c478bd9Sstevel@tonic-gate #endif /* MATCHGECOS */
57617c478bd9Sstevel@tonic-gate #if MILTER
57627c478bd9Sstevel@tonic-gate 	"MILTER",
57637c478bd9Sstevel@tonic-gate #endif /* MILTER */
57647c478bd9Sstevel@tonic-gate #if MIME7TO8
57657c478bd9Sstevel@tonic-gate 	"MIME7TO8",
57667c478bd9Sstevel@tonic-gate #endif /* MIME7TO8 */
57677c478bd9Sstevel@tonic-gate #if MIME7TO8_OLD
57687c478bd9Sstevel@tonic-gate 	"MIME7TO8_OLD",
57697c478bd9Sstevel@tonic-gate #endif /* MIME7TO8_OLD */
57707c478bd9Sstevel@tonic-gate #if MIME8TO7
57717c478bd9Sstevel@tonic-gate 	"MIME8TO7",
57727c478bd9Sstevel@tonic-gate #endif /* MIME8TO7 */
57737c478bd9Sstevel@tonic-gate #if NAMED_BIND
57747c478bd9Sstevel@tonic-gate 	"NAMED_BIND",
57757c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */
57767c478bd9Sstevel@tonic-gate #if NDBM
57777c478bd9Sstevel@tonic-gate 	"NDBM",
57787c478bd9Sstevel@tonic-gate #endif /* NDBM */
57797c478bd9Sstevel@tonic-gate #if NETINET
57807c478bd9Sstevel@tonic-gate 	"NETINET",
57817c478bd9Sstevel@tonic-gate #endif /* NETINET */
57827c478bd9Sstevel@tonic-gate #if NETINET6
57837c478bd9Sstevel@tonic-gate 	"NETINET6",
57847c478bd9Sstevel@tonic-gate #endif /* NETINET6 */
57857c478bd9Sstevel@tonic-gate #if NETINFO
57867c478bd9Sstevel@tonic-gate 	"NETINFO",
57877c478bd9Sstevel@tonic-gate #endif /* NETINFO */
57887c478bd9Sstevel@tonic-gate #if NETISO
57897c478bd9Sstevel@tonic-gate 	"NETISO",
57907c478bd9Sstevel@tonic-gate #endif /* NETISO */
57917c478bd9Sstevel@tonic-gate #if NETNS
57927c478bd9Sstevel@tonic-gate 	"NETNS",
57937c478bd9Sstevel@tonic-gate #endif /* NETNS */
57947c478bd9Sstevel@tonic-gate #if NETUNIX
57957c478bd9Sstevel@tonic-gate 	"NETUNIX",
57967c478bd9Sstevel@tonic-gate #endif /* NETUNIX */
57977c478bd9Sstevel@tonic-gate #if NETX25
57987c478bd9Sstevel@tonic-gate 	"NETX25",
57997c478bd9Sstevel@tonic-gate #endif /* NETX25 */
58007c478bd9Sstevel@tonic-gate #if NEWDB
58017c478bd9Sstevel@tonic-gate 	"NEWDB",
58027c478bd9Sstevel@tonic-gate #endif /* NEWDB */
58037c478bd9Sstevel@tonic-gate #if NIS
58047c478bd9Sstevel@tonic-gate 	"NIS",
58057c478bd9Sstevel@tonic-gate #endif /* NIS */
58067c478bd9Sstevel@tonic-gate #if NISPLUS
58077c478bd9Sstevel@tonic-gate 	"NISPLUS",
58087c478bd9Sstevel@tonic-gate #endif /* NISPLUS */
58097c478bd9Sstevel@tonic-gate #if NO_DH
58107c478bd9Sstevel@tonic-gate 	"NO_DH",
58117c478bd9Sstevel@tonic-gate #endif /* NO_DH */
58127c478bd9Sstevel@tonic-gate #if PH_MAP
58137c478bd9Sstevel@tonic-gate 	"PH_MAP",
58147c478bd9Sstevel@tonic-gate #endif /* PH_MAP */
58157c478bd9Sstevel@tonic-gate #ifdef PICKY_HELO_CHECK
58167c478bd9Sstevel@tonic-gate 	"PICKY_HELO_CHECK",
58177c478bd9Sstevel@tonic-gate #endif /* PICKY_HELO_CHECK */
58187c478bd9Sstevel@tonic-gate #if PIPELINING
58197c478bd9Sstevel@tonic-gate 	"PIPELINING",
58207c478bd9Sstevel@tonic-gate #endif /* PIPELINING */
58217c478bd9Sstevel@tonic-gate #if SASL
58227c478bd9Sstevel@tonic-gate # if SASL >= 20000
58237c478bd9Sstevel@tonic-gate 	"SASLv2",
58247c478bd9Sstevel@tonic-gate # else /* SASL >= 20000 */
58257c478bd9Sstevel@tonic-gate 	"SASL",
58267c478bd9Sstevel@tonic-gate # endif /* SASL >= 20000 */
58277c478bd9Sstevel@tonic-gate #endif /* SASL */
58287c478bd9Sstevel@tonic-gate #if SCANF
58297c478bd9Sstevel@tonic-gate 	"SCANF",
58307c478bd9Sstevel@tonic-gate #endif /* SCANF */
58317c478bd9Sstevel@tonic-gate #if SMTPDEBUG
58327c478bd9Sstevel@tonic-gate 	"SMTPDEBUG",
58337c478bd9Sstevel@tonic-gate #endif /* SMTPDEBUG */
58347c478bd9Sstevel@tonic-gate #if SOCKETMAP
58357c478bd9Sstevel@tonic-gate 	"SOCKETMAP",
58367c478bd9Sstevel@tonic-gate #endif /* SOCKETMAP */
58377c478bd9Sstevel@tonic-gate #if STARTTLS
58387c478bd9Sstevel@tonic-gate 	"STARTTLS",
58397c478bd9Sstevel@tonic-gate #endif /* STARTTLS */
58407c478bd9Sstevel@tonic-gate #if SUID_ROOT_FILES_OK
58417c478bd9Sstevel@tonic-gate 	"SUID_ROOT_FILES_OK",
58427c478bd9Sstevel@tonic-gate #endif /* SUID_ROOT_FILES_OK */
58437c478bd9Sstevel@tonic-gate #if TCPWRAPPERS
58447c478bd9Sstevel@tonic-gate 	"TCPWRAPPERS",
58457c478bd9Sstevel@tonic-gate #endif /* TCPWRAPPERS */
58467c478bd9Sstevel@tonic-gate #if TLS_NO_RSA
58477c478bd9Sstevel@tonic-gate 	"TLS_NO_RSA",
58487c478bd9Sstevel@tonic-gate #endif /* TLS_NO_RSA */
58497c478bd9Sstevel@tonic-gate #if TLS_VRFY_PER_CTX
58507c478bd9Sstevel@tonic-gate 	"TLS_VRFY_PER_CTX",
58517c478bd9Sstevel@tonic-gate #endif /* TLS_VRFY_PER_CTX */
58527c478bd9Sstevel@tonic-gate #if USERDB
58537c478bd9Sstevel@tonic-gate 	"USERDB",
58547c478bd9Sstevel@tonic-gate #endif /* USERDB */
58557c478bd9Sstevel@tonic-gate #if USE_LDAP_INIT
58567c478bd9Sstevel@tonic-gate 	"USE_LDAP_INIT",
58577c478bd9Sstevel@tonic-gate #endif /* USE_LDAP_INIT */
58587c478bd9Sstevel@tonic-gate #if USE_TTYPATH
58597c478bd9Sstevel@tonic-gate 	"USE_TTYPATH",
58607c478bd9Sstevel@tonic-gate #endif /* USE_TTYPATH */
58617c478bd9Sstevel@tonic-gate #if XDEBUG
58627c478bd9Sstevel@tonic-gate 	"XDEBUG",
58637c478bd9Sstevel@tonic-gate #endif /* XDEBUG */
58647c478bd9Sstevel@tonic-gate #if XLA
58657c478bd9Sstevel@tonic-gate 	"XLA",
58667c478bd9Sstevel@tonic-gate #endif /* XLA */
58677c478bd9Sstevel@tonic-gate 	NULL
58687c478bd9Sstevel@tonic-gate };
58697c478bd9Sstevel@tonic-gate 
58707c478bd9Sstevel@tonic-gate 
58717c478bd9Sstevel@tonic-gate /*
58727c478bd9Sstevel@tonic-gate **  OS compile options.
58737c478bd9Sstevel@tonic-gate */
58747c478bd9Sstevel@tonic-gate 
58757c478bd9Sstevel@tonic-gate char	*OsCompileOptions[] =
58767c478bd9Sstevel@tonic-gate {
58777c478bd9Sstevel@tonic-gate #if ADDRCONFIG_IS_BROKEN
58787c478bd9Sstevel@tonic-gate 	"ADDRCONFIG_IS_BROKEN",
58797c478bd9Sstevel@tonic-gate #endif /* ADDRCONFIG_IS_BROKEN */
58807c478bd9Sstevel@tonic-gate #ifdef AUTO_NETINFO_HOSTS
58817c478bd9Sstevel@tonic-gate 	"AUTO_NETINFO_HOSTS",
58827c478bd9Sstevel@tonic-gate #endif /* AUTO_NETINFO_HOSTS */
58837c478bd9Sstevel@tonic-gate #ifdef AUTO_NIS_ALIASES
58847c478bd9Sstevel@tonic-gate 	"AUTO_NIS_ALIASES",
58857c478bd9Sstevel@tonic-gate #endif /* AUTO_NIS_ALIASES */
58867c478bd9Sstevel@tonic-gate #if BROKEN_RES_SEARCH
58877c478bd9Sstevel@tonic-gate 	"BROKEN_RES_SEARCH",
58887c478bd9Sstevel@tonic-gate #endif /* BROKEN_RES_SEARCH */
58897c478bd9Sstevel@tonic-gate #ifdef BSD4_4_SOCKADDR
58907c478bd9Sstevel@tonic-gate 	"BSD4_4_SOCKADDR",
58917c478bd9Sstevel@tonic-gate #endif /* BSD4_4_SOCKADDR */
58927c478bd9Sstevel@tonic-gate #if BOGUS_O_EXCL
58937c478bd9Sstevel@tonic-gate 	"BOGUS_O_EXCL",
58947c478bd9Sstevel@tonic-gate #endif /* BOGUS_O_EXCL */
58957c478bd9Sstevel@tonic-gate #if DEC_OSF_BROKEN_GETPWENT
58967c478bd9Sstevel@tonic-gate 	"DEC_OSF_BROKEN_GETPWENT",
58977c478bd9Sstevel@tonic-gate #endif /* DEC_OSF_BROKEN_GETPWENT */
58987c478bd9Sstevel@tonic-gate #if FAST_PID_RECYCLE
58997c478bd9Sstevel@tonic-gate 	"FAST_PID_RECYCLE",
59007c478bd9Sstevel@tonic-gate #endif /* FAST_PID_RECYCLE */
59017c478bd9Sstevel@tonic-gate #if HASCLOSEFROM
59027c478bd9Sstevel@tonic-gate 	"HASCLOSEFROM",
59037c478bd9Sstevel@tonic-gate #endif /* HASCLOSEFROM */
59047c478bd9Sstevel@tonic-gate #if HASFCHOWN
59057c478bd9Sstevel@tonic-gate 	"HASFCHOWN",
59067c478bd9Sstevel@tonic-gate #endif /* HASFCHOWN */
59077c478bd9Sstevel@tonic-gate #if HASFCHMOD
59087c478bd9Sstevel@tonic-gate 	"HASFCHMOD",
59097c478bd9Sstevel@tonic-gate #endif /* HASFCHMOD */
59107c478bd9Sstevel@tonic-gate #if HASFDWALK
59117c478bd9Sstevel@tonic-gate 	"HASFDWALK",
59127c478bd9Sstevel@tonic-gate #endif /* HASFDWALK */
59137c478bd9Sstevel@tonic-gate #if HASFLOCK
59147c478bd9Sstevel@tonic-gate 	"HASFLOCK",
59157c478bd9Sstevel@tonic-gate #endif /* HASFLOCK */
59167c478bd9Sstevel@tonic-gate #if HASGETDTABLESIZE
59177c478bd9Sstevel@tonic-gate 	"HASGETDTABLESIZE",
59187c478bd9Sstevel@tonic-gate #endif /* HASGETDTABLESIZE */
59197c478bd9Sstevel@tonic-gate #if HASGETUSERSHELL
59207c478bd9Sstevel@tonic-gate 	"HASGETUSERSHELL",
59217c478bd9Sstevel@tonic-gate #endif /* HASGETUSERSHELL */
59227c478bd9Sstevel@tonic-gate #if HASINITGROUPS
59237c478bd9Sstevel@tonic-gate 	"HASINITGROUPS",
59247c478bd9Sstevel@tonic-gate #endif /* HASINITGROUPS */
59257c478bd9Sstevel@tonic-gate #if HASLDAPGETALIASBYNAME
59267c478bd9Sstevel@tonic-gate 	"HASLDAPGETALIASBYNAME",
59277c478bd9Sstevel@tonic-gate #endif /* HASLDAPGETALIASBYNAME */
59287c478bd9Sstevel@tonic-gate #if HASLSTAT
59297c478bd9Sstevel@tonic-gate 	"HASLSTAT",
59307c478bd9Sstevel@tonic-gate #endif /* HASLSTAT */
59317c478bd9Sstevel@tonic-gate #if HASNICE
59327c478bd9Sstevel@tonic-gate 	"HASNICE",
59337c478bd9Sstevel@tonic-gate #endif /* HASNICE */
59347c478bd9Sstevel@tonic-gate #if HASRANDOM
59357c478bd9Sstevel@tonic-gate 	"HASRANDOM",
59367c478bd9Sstevel@tonic-gate #endif /* HASRANDOM */
59377c478bd9Sstevel@tonic-gate #if HASRRESVPORT
59387c478bd9Sstevel@tonic-gate 	"HASRRESVPORT",
59397c478bd9Sstevel@tonic-gate #endif /* HASRRESVPORT */
59407c478bd9Sstevel@tonic-gate #if HASSETEGID
59417c478bd9Sstevel@tonic-gate 	"HASSETEGID",
59427c478bd9Sstevel@tonic-gate #endif /* HASSETEGID */
59437c478bd9Sstevel@tonic-gate #if HASSETLOGIN
59447c478bd9Sstevel@tonic-gate 	"HASSETLOGIN",
59457c478bd9Sstevel@tonic-gate #endif /* HASSETLOGIN */
59467c478bd9Sstevel@tonic-gate #if HASSETREGID
59477c478bd9Sstevel@tonic-gate 	"HASSETREGID",
59487c478bd9Sstevel@tonic-gate #endif /* HASSETREGID */
59497c478bd9Sstevel@tonic-gate #if HASSETRESGID
59507c478bd9Sstevel@tonic-gate 	"HASSETRESGID",
59517c478bd9Sstevel@tonic-gate #endif /* HASSETRESGID */
59527c478bd9Sstevel@tonic-gate #if HASSETREUID
59537c478bd9Sstevel@tonic-gate 	"HASSETREUID",
59547c478bd9Sstevel@tonic-gate #endif /* HASSETREUID */
59557c478bd9Sstevel@tonic-gate #if HASSETRLIMIT
59567c478bd9Sstevel@tonic-gate 	"HASSETRLIMIT",
59577c478bd9Sstevel@tonic-gate #endif /* HASSETRLIMIT */
59587c478bd9Sstevel@tonic-gate #if HASSETSID
59597c478bd9Sstevel@tonic-gate 	"HASSETSID",
59607c478bd9Sstevel@tonic-gate #endif /* HASSETSID */
59617c478bd9Sstevel@tonic-gate #if HASSETUSERCONTEXT
59627c478bd9Sstevel@tonic-gate 	"HASSETUSERCONTEXT",
59637c478bd9Sstevel@tonic-gate #endif /* HASSETUSERCONTEXT */
59647c478bd9Sstevel@tonic-gate #if HASSETVBUF
59657c478bd9Sstevel@tonic-gate 	"HASSETVBUF",
59667c478bd9Sstevel@tonic-gate #endif /* HASSETVBUF */
59677c478bd9Sstevel@tonic-gate #if HAS_ST_GEN
59687c478bd9Sstevel@tonic-gate 	"HAS_ST_GEN",
59697c478bd9Sstevel@tonic-gate #endif /* HAS_ST_GEN */
59707c478bd9Sstevel@tonic-gate #if HASSRANDOMDEV
59717c478bd9Sstevel@tonic-gate 	"HASSRANDOMDEV",
59727c478bd9Sstevel@tonic-gate #endif /* HASSRANDOMDEV */
59737c478bd9Sstevel@tonic-gate #if HASURANDOMDEV
59747c478bd9Sstevel@tonic-gate 	"HASURANDOMDEV",
59757c478bd9Sstevel@tonic-gate #endif /* HASURANDOMDEV */
59767c478bd9Sstevel@tonic-gate #if HASSTRERROR
59777c478bd9Sstevel@tonic-gate 	"HASSTRERROR",
59787c478bd9Sstevel@tonic-gate #endif /* HASSTRERROR */
59797c478bd9Sstevel@tonic-gate #if HASULIMIT
59807c478bd9Sstevel@tonic-gate 	"HASULIMIT",
59817c478bd9Sstevel@tonic-gate #endif /* HASULIMIT */
59827c478bd9Sstevel@tonic-gate #if HASUNAME
59837c478bd9Sstevel@tonic-gate 	"HASUNAME",
59847c478bd9Sstevel@tonic-gate #endif /* HASUNAME */
59857c478bd9Sstevel@tonic-gate #if HASUNSETENV
59867c478bd9Sstevel@tonic-gate 	"HASUNSETENV",
59877c478bd9Sstevel@tonic-gate #endif /* HASUNSETENV */
59887c478bd9Sstevel@tonic-gate #if HASWAITPID
59897c478bd9Sstevel@tonic-gate 	"HASWAITPID",
59907c478bd9Sstevel@tonic-gate #endif /* HASWAITPID */
59917c478bd9Sstevel@tonic-gate #if IDENTPROTO
59927c478bd9Sstevel@tonic-gate 	"IDENTPROTO",
59937c478bd9Sstevel@tonic-gate #endif /* IDENTPROTO */
59947c478bd9Sstevel@tonic-gate #if IP_SRCROUTE
59957c478bd9Sstevel@tonic-gate 	"IP_SRCROUTE",
59967c478bd9Sstevel@tonic-gate #endif /* IP_SRCROUTE */
59977c478bd9Sstevel@tonic-gate #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
59987c478bd9Sstevel@tonic-gate 	"LOCK_ON_OPEN",
59997c478bd9Sstevel@tonic-gate #endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
60007c478bd9Sstevel@tonic-gate #if NEEDFSYNC
60017c478bd9Sstevel@tonic-gate 	"NEEDFSYNC",
60027c478bd9Sstevel@tonic-gate #endif /* NEEDFSYNC */
60037c478bd9Sstevel@tonic-gate #if NEEDLINK
60047c478bd9Sstevel@tonic-gate 	"NEEDLINK",
60057c478bd9Sstevel@tonic-gate #endif /* NEEDLINK */
60067c478bd9Sstevel@tonic-gate #if NEEDLOCAL_HOSTNAME_LENGTH
60077c478bd9Sstevel@tonic-gate 	"NEEDLOCAL_HOSTNAME_LENGTH",
60087c478bd9Sstevel@tonic-gate #endif /* NEEDLOCAL_HOSTNAME_LENGTH */
60097c478bd9Sstevel@tonic-gate #if NEEDSGETIPNODE
60107c478bd9Sstevel@tonic-gate 	"NEEDSGETIPNODE",
60117c478bd9Sstevel@tonic-gate #endif /* NEEDSGETIPNODE */
60127c478bd9Sstevel@tonic-gate #if NEEDSTRSTR
60137c478bd9Sstevel@tonic-gate 	"NEEDSTRSTR",
60147c478bd9Sstevel@tonic-gate #endif /* NEEDSTRSTR */
60157c478bd9Sstevel@tonic-gate #if NEEDSTRTOL
60167c478bd9Sstevel@tonic-gate 	"NEEDSTRTOL",
60177c478bd9Sstevel@tonic-gate #endif /* NEEDSTRTOL */
60187c478bd9Sstevel@tonic-gate #ifdef NO_GETSERVBYNAME
60197c478bd9Sstevel@tonic-gate 	"NO_GETSERVBYNAME",
60207c478bd9Sstevel@tonic-gate #endif /* NO_GETSERVBYNAME */
60217c478bd9Sstevel@tonic-gate #if NOFTRUNCATE
60227c478bd9Sstevel@tonic-gate 	"NOFTRUNCATE",
60237c478bd9Sstevel@tonic-gate #endif /* NOFTRUNCATE */
60247c478bd9Sstevel@tonic-gate #if REQUIRES_DIR_FSYNC
60257c478bd9Sstevel@tonic-gate 	"REQUIRES_DIR_FSYNC",
60267c478bd9Sstevel@tonic-gate #endif /* REQUIRES_DIR_FSYNC */
60277c478bd9Sstevel@tonic-gate #if RLIMIT_NEEDS_SYS_TIME_H
60287c478bd9Sstevel@tonic-gate 	"RLIMIT_NEEDS_SYS_TIME_H",
60297c478bd9Sstevel@tonic-gate #endif /* RLIMIT_NEEDS_SYS_TIME_H */
60307c478bd9Sstevel@tonic-gate #if SAFENFSPATHCONF
60317c478bd9Sstevel@tonic-gate 	"SAFENFSPATHCONF",
60327c478bd9Sstevel@tonic-gate #endif /* SAFENFSPATHCONF */
60337c478bd9Sstevel@tonic-gate #if SECUREWARE
60347c478bd9Sstevel@tonic-gate 	"SECUREWARE",
60357c478bd9Sstevel@tonic-gate #endif /* SECUREWARE */
60367c478bd9Sstevel@tonic-gate #if SHARE_V1
60377c478bd9Sstevel@tonic-gate 	"SHARE_V1",
60387c478bd9Sstevel@tonic-gate #endif /* SHARE_V1 */
60397c478bd9Sstevel@tonic-gate #if SIOCGIFCONF_IS_BROKEN
60407c478bd9Sstevel@tonic-gate 	"SIOCGIFCONF_IS_BROKEN",
60417c478bd9Sstevel@tonic-gate #endif /* SIOCGIFCONF_IS_BROKEN */
60427c478bd9Sstevel@tonic-gate #if SIOCGIFNUM_IS_BROKEN
60437c478bd9Sstevel@tonic-gate 	"SIOCGIFNUM_IS_BROKEN",
60447c478bd9Sstevel@tonic-gate #endif /* SIOCGIFNUM_IS_BROKEN */
60457c478bd9Sstevel@tonic-gate #if SNPRINTF_IS_BROKEN
60467c478bd9Sstevel@tonic-gate 	"SNPRINTF_IS_BROKEN",
60477c478bd9Sstevel@tonic-gate #endif /* SNPRINTF_IS_BROKEN */
60487c478bd9Sstevel@tonic-gate #if SO_REUSEADDR_IS_BROKEN
60497c478bd9Sstevel@tonic-gate 	"SO_REUSEADDR_IS_BROKEN",
60507c478bd9Sstevel@tonic-gate #endif /* SO_REUSEADDR_IS_BROKEN */
60517c478bd9Sstevel@tonic-gate #if SYS5SETPGRP
60527c478bd9Sstevel@tonic-gate 	"SYS5SETPGRP",
60537c478bd9Sstevel@tonic-gate #endif /* SYS5SETPGRP */
60547c478bd9Sstevel@tonic-gate #if SYSTEM5
60557c478bd9Sstevel@tonic-gate 	"SYSTEM5",
60567c478bd9Sstevel@tonic-gate #endif /* SYSTEM5 */
60577c478bd9Sstevel@tonic-gate #if USE_DOUBLE_FORK
60587c478bd9Sstevel@tonic-gate 	"USE_DOUBLE_FORK",
60597c478bd9Sstevel@tonic-gate #endif /* USE_DOUBLE_FORK */
60607c478bd9Sstevel@tonic-gate #if USE_ENVIRON
60617c478bd9Sstevel@tonic-gate 	"USE_ENVIRON",
60627c478bd9Sstevel@tonic-gate #endif /* USE_ENVIRON */
60637c478bd9Sstevel@tonic-gate #if USE_SA_SIGACTION
60647c478bd9Sstevel@tonic-gate 	"USE_SA_SIGACTION",
60657c478bd9Sstevel@tonic-gate #endif /* USE_SA_SIGACTION */
60667c478bd9Sstevel@tonic-gate #if USE_SIGLONGJMP
60677c478bd9Sstevel@tonic-gate 	"USE_SIGLONGJMP",
60687c478bd9Sstevel@tonic-gate #endif /* USE_SIGLONGJMP */
60697c478bd9Sstevel@tonic-gate #if USEGETCONFATTR
60707c478bd9Sstevel@tonic-gate 	"USEGETCONFATTR",
60717c478bd9Sstevel@tonic-gate #endif /* USEGETCONFATTR */
60727c478bd9Sstevel@tonic-gate #if USESETEUID
60737c478bd9Sstevel@tonic-gate 	"USESETEUID",
60747c478bd9Sstevel@tonic-gate #endif /* USESETEUID */
60757c478bd9Sstevel@tonic-gate #ifdef USESYSCTL
60767c478bd9Sstevel@tonic-gate 	"USESYSCTL",
60777c478bd9Sstevel@tonic-gate #endif /* USESYSCTL */
60787c478bd9Sstevel@tonic-gate #if USING_NETSCAPE_LDAP
60797c478bd9Sstevel@tonic-gate 	"USING_NETSCAPE_LDAP",
60807c478bd9Sstevel@tonic-gate #endif /* USING_NETSCAPE_LDAP */
60817c478bd9Sstevel@tonic-gate #ifdef WAITUNION
60827c478bd9Sstevel@tonic-gate 	"WAITUNION",
60837c478bd9Sstevel@tonic-gate #endif /* WAITUNION */
60847c478bd9Sstevel@tonic-gate 	NULL
60857c478bd9Sstevel@tonic-gate };
60867c478bd9Sstevel@tonic-gate 
60877c478bd9Sstevel@tonic-gate /*
60887c478bd9Sstevel@tonic-gate **  FFR compile options.
60897c478bd9Sstevel@tonic-gate */
60907c478bd9Sstevel@tonic-gate 
60917c478bd9Sstevel@tonic-gate char	*FFRCompileOptions[] =
60927c478bd9Sstevel@tonic-gate {
60937c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO
60947c478bd9Sstevel@tonic-gate 	/* DefaultAuthInfo can be specified by user. */
60957c478bd9Sstevel@tonic-gate 	/* DefaultAuthInfo doesn't really work in 8.13 anymore. */
60967c478bd9Sstevel@tonic-gate 	"_FFR_ALLOW_SASLINFO",
60977c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */
60987c478bd9Sstevel@tonic-gate #if _FFR_BESTMX_BETTER_TRUNCATION
60997c478bd9Sstevel@tonic-gate 	/* Better truncation of list of MX records for dns map. */
61007c478bd9Sstevel@tonic-gate 	"_FFR_BESTMX_BETTER_TRUNCATION",
61017c478bd9Sstevel@tonic-gate #endif /* _FFR_BESTMX_BETTER_TRUNCATION */
61027c478bd9Sstevel@tonic-gate #if _FFR_BLOCK_PROXIES
61037c478bd9Sstevel@tonic-gate 	/*
61047c478bd9Sstevel@tonic-gate 	**  Try to deal with open HTTP proxies that are used to send spam
61057c478bd9Sstevel@tonic-gate 	**  by recognizing some commands from them.
61067c478bd9Sstevel@tonic-gate 	*/
61077c478bd9Sstevel@tonic-gate 
61087c478bd9Sstevel@tonic-gate 	"_FFR_BLOCK_PROXIES",
61097c478bd9Sstevel@tonic-gate #endif /* _FFR_BLOCK_PROXIES */
61107c478bd9Sstevel@tonic-gate #if _FFR_CATCH_BROKEN_MTAS
61117c478bd9Sstevel@tonic-gate 	/* Deal with MTAs that send a reply during the DATA phase. */
61127c478bd9Sstevel@tonic-gate 	"_FFR_CATCH_BROKEN_MTAS",
61137c478bd9Sstevel@tonic-gate #endif /* _FFR_CATCH_BROKEN_MTAS */
61147c478bd9Sstevel@tonic-gate #if _FFR_CHECK_EOM
61157c478bd9Sstevel@tonic-gate 	/* Enable check_eom ruleset */
61167c478bd9Sstevel@tonic-gate 	"_FFR_CHECK_EOM",
61177c478bd9Sstevel@tonic-gate #endif /* _FFR_CHECK_EOM */
61187c478bd9Sstevel@tonic-gate #if _FFR_CHK_QUEUE
61197c478bd9Sstevel@tonic-gate 	/* Stricter checks about queue directory permissions. */
61207c478bd9Sstevel@tonic-gate 	"_FFR_CHK_QUEUE",
61217c478bd9Sstevel@tonic-gate #endif /* _FFR_CHK_QUEUE */
61227c478bd9Sstevel@tonic-gate #if _FFR_CLIENT_SIZE
61237c478bd9Sstevel@tonic-gate 	/* Don't try to send mail if its size exceeds SIZE= of server. */
61247c478bd9Sstevel@tonic-gate 	"_FFR_CLIENT_SIZE",
61257c478bd9Sstevel@tonic-gate #endif /* _FFR_CLIENT_SIZE */
61267c478bd9Sstevel@tonic-gate #if _FFR_CONTROL_MSTAT
61277c478bd9Sstevel@tonic-gate 	/* Extended daemon status. */
61287c478bd9Sstevel@tonic-gate 	"_FFR_CONTROL_MSTAT",
61297c478bd9Sstevel@tonic-gate #endif /* _FFR_CONTROL_MSTAT */
61307c478bd9Sstevel@tonic-gate #if _FFR_CRLPATH
61317c478bd9Sstevel@tonic-gate 	/* CRLPath; needs documentation; Al Smith */
61327c478bd9Sstevel@tonic-gate 	"_FFR_CRLPATH",
61337c478bd9Sstevel@tonic-gate #endif /* _FFR_CRLPATH */
61347c478bd9Sstevel@tonic-gate #if _FFR_DAEMON_NETUNIX
61357c478bd9Sstevel@tonic-gate 	/* Allow local (not just TCP) socket connection to server. */
61367c478bd9Sstevel@tonic-gate 	"_FFR_DAEMON_NETUNIX",
61377c478bd9Sstevel@tonic-gate #endif /* _FFR_DAEMON_NETUNIX */
61387c478bd9Sstevel@tonic-gate #if _FFR_DEPRECATE_MAILER_FLAG_I
61397c478bd9Sstevel@tonic-gate 	/* What it says :-) */
61407c478bd9Sstevel@tonic-gate 	"_FFR_DEPRECATE_MAILER_FLAG_I",
61417c478bd9Sstevel@tonic-gate #endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
6142445f2479Sjbeck #if _FFR_DM_ONE
6143445f2479Sjbeck 	/* deliver first TA in background, then queue */
6144445f2479Sjbeck 	"_FFR_DM_ONE",
6145445f2479Sjbeck #endif /* _FFR_DM_ONE */
61467c478bd9Sstevel@tonic-gate #if _FFR_DIGUNIX_SAFECHOWN
61477c478bd9Sstevel@tonic-gate 	/* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */
61487c478bd9Sstevel@tonic-gate /* Problem noted by Anne Bennett of Concordia University */
61497c478bd9Sstevel@tonic-gate 	"_FFR_DIGUNIX_SAFECHOWN",
61507c478bd9Sstevel@tonic-gate #endif /* _FFR_DIGUNIX_SAFECHOWN */
61517c478bd9Sstevel@tonic-gate #if _FFR_DM_PER_DAEMON
61527c478bd9Sstevel@tonic-gate 	/* DeliveryMode per DaemonPortOptions: 'D' */
61537c478bd9Sstevel@tonic-gate 	"_FFR_DM_PER_DAEMON",
61547c478bd9Sstevel@tonic-gate #endif /* _FFR_DM_PER_DAEMON */
61557c478bd9Sstevel@tonic-gate #if _FFR_DNSMAP_ALIASABLE
61567c478bd9Sstevel@tonic-gate 	/* Allow dns map type to be used for aliases. */
61577c478bd9Sstevel@tonic-gate /* Don Lewis of TDK */
61587c478bd9Sstevel@tonic-gate 	"_FFR_DNSMAP_ALIASABLE",
61597c478bd9Sstevel@tonic-gate #endif /* _FFR_DNSMAP_ALIASABLE */
61607c478bd9Sstevel@tonic-gate #if _FFR_DNSMAP_BASE
61617c478bd9Sstevel@tonic-gate 	/* Specify a "base" domain for DNS lookups. */
61627c478bd9Sstevel@tonic-gate 	"_FFR_DNSMAP_BASE",
61637c478bd9Sstevel@tonic-gate #endif /* _FFR_DNSMAP_BASE */
61647c478bd9Sstevel@tonic-gate #if _FFR_DNSMAP_MULTI
61657c478bd9Sstevel@tonic-gate 	/* Allow multiple return values for DNS map. */
61667c478bd9Sstevel@tonic-gate 	"_FFR_DNSMAP_MULTI",
61677c478bd9Sstevel@tonic-gate # if _FFR_DNSMAP_MULTILIMIT
61687c478bd9Sstevel@tonic-gate 	/* Limit number of return values for DNS map. */
61697c478bd9Sstevel@tonic-gate 	"_FFR_DNSMAP_MULTILIMIT",
61707c478bd9Sstevel@tonic-gate # endif /* _FFR_DNSMAP_MULTILIMIT */
61717c478bd9Sstevel@tonic-gate #endif /* _FFR_DNSMAP_MULTI */
61727c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION
61737c478bd9Sstevel@tonic-gate 	/* Enable DontLockFilesForRead option. */
61747c478bd9Sstevel@tonic-gate 	"_FFR_DONTLOCKFILESFORREAD_OPTION",
61757c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
61767c478bd9Sstevel@tonic-gate #if _FFR_DOTTED_USERNAMES
61777c478bd9Sstevel@tonic-gate 	/* Allow usernames with '.' */
61787c478bd9Sstevel@tonic-gate 	"_FFR_DOTTED_USERNAMES",
61797c478bd9Sstevel@tonic-gate #endif /* _FFR_DOTTED_USERNAMES */
61807c478bd9Sstevel@tonic-gate #if _FFR_DROP_TRUSTUSER_WARNING
61817c478bd9Sstevel@tonic-gate 	/*
61827c478bd9Sstevel@tonic-gate 	**  Don't issue this warning:
61837c478bd9Sstevel@tonic-gate 	**  "readcf: option TrustedUser may cause problems on systems
61847c478bd9Sstevel@tonic-gate 	**  which do not support fchown() if UseMSP is not set.
61857c478bd9Sstevel@tonic-gate 	*/
61867c478bd9Sstevel@tonic-gate 
61877c478bd9Sstevel@tonic-gate 	"_FFR_DROP_TRUSTUSER_WARNING",
61887c478bd9Sstevel@tonic-gate #endif /* _FFR_DROP_TRUSTUSER_WARNING */
61897c478bd9Sstevel@tonic-gate #if _FFR_EXTRA_MAP_CHECK
61907c478bd9Sstevel@tonic-gate 	/* perform extra checks on $( $) in R lines */
61917c478bd9Sstevel@tonic-gate 	"_FFR_EXTRA_MAP_CHECK",
61927c478bd9Sstevel@tonic-gate #endif /* _FFR_EXTRA_MAP_CHECK */
61937c478bd9Sstevel@tonic-gate #if _FFR_FIX_DASHT
61947c478bd9Sstevel@tonic-gate 	/*
61957c478bd9Sstevel@tonic-gate 	**  If using -t, force not sending to argv recipients, even
61967c478bd9Sstevel@tonic-gate 	**  if they are mentioned in the headers.
61977c478bd9Sstevel@tonic-gate 	*/
61987c478bd9Sstevel@tonic-gate 
61997c478bd9Sstevel@tonic-gate 	"_FFR_FIX_DASHT",
62007c478bd9Sstevel@tonic-gate #endif /* _FFR_FIX_DASHT */
62017c478bd9Sstevel@tonic-gate #if _FFR_FORWARD_SYSERR
62027c478bd9Sstevel@tonic-gate 	/* Cause a "syserr" if forward file isn't "safe". */
62037c478bd9Sstevel@tonic-gate 	"_FFR_FORWARD_SYSERR",
62047c478bd9Sstevel@tonic-gate #endif /* _FFR_FORWARD_SYSERR */
62057c478bd9Sstevel@tonic-gate #if _FFR_GEN_ORCPT
62067c478bd9Sstevel@tonic-gate 	/* Generate a ORCPT DSN arg if not already provided */
62077c478bd9Sstevel@tonic-gate 	"_FFR_GEN_ORCPT",
62087c478bd9Sstevel@tonic-gate #endif /* _FFR_GEN_ORCPT */
620949218d4fSjbeck #if _FFR_LOG_GREET_PAUSE
621049218d4fSjbeck 	/* log time for greet_pause delay; from Nik Clayton */
621149218d4fSjbeck 	"_FFR_LOG_GREET_PAUSE",
621249218d4fSjbeck #endif /* _FFR_LOG_GREET_PAUSE */
62137c478bd9Sstevel@tonic-gate #if _FFR_GROUPREADABLEAUTHINFOFILE
62147c478bd9Sstevel@tonic-gate 	/* Allow group readable DefaultAuthInfo file. */
62157c478bd9Sstevel@tonic-gate 	"_FFR_GROUPREADABLEAUTHINFOFILE",
62167c478bd9Sstevel@tonic-gate #endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
62177c478bd9Sstevel@tonic-gate #if _FFR_HANDLE_ISO8859_GECOS
62187c478bd9Sstevel@tonic-gate 	/*
62197c478bd9Sstevel@tonic-gate 	**  Allow ISO 8859 characters in GECOS field: replace them
62207c478bd9Sstevel@tonic-gate 	**  ith ASCII "equivalent".
62217c478bd9Sstevel@tonic-gate 	*/
62227c478bd9Sstevel@tonic-gate 
62237c478bd9Sstevel@tonic-gate /* Peter Eriksson of Linkopings universitet */
62247c478bd9Sstevel@tonic-gate 	"_FFR_HANDLE_ISO8859_GECOS",
62257c478bd9Sstevel@tonic-gate #endif /* _FFR_HANDLE_ISO8859_GECOS */
62267c478bd9Sstevel@tonic-gate #if _FFR_HDR_TYPE
62277c478bd9Sstevel@tonic-gate 	/* Set 'h' in {addr_type} for headers. */
62287c478bd9Sstevel@tonic-gate 	"_FFR_HDR_TYPE",
62297c478bd9Sstevel@tonic-gate #endif /* _FFR_HDR_TYPE */
62307c478bd9Sstevel@tonic-gate #if _FFR_HELONAME
62317c478bd9Sstevel@tonic-gate 	/* option to set heloname; Nik Clayton of FreeBSD */
62327c478bd9Sstevel@tonic-gate 	"_FFR_HELONAME",
62337c478bd9Sstevel@tonic-gate #endif /* _FFR_HELONAME */
62347c478bd9Sstevel@tonic-gate #if _FFR_HPUX_NSSWITCH
62357c478bd9Sstevel@tonic-gate 	/* Use nsswitch on HP-UX */
62367c478bd9Sstevel@tonic-gate 	"_FFR_HPUX_NSSWITCH",
62377c478bd9Sstevel@tonic-gate #endif /* _FFR_HPUX_NSSWITCH */
62387c478bd9Sstevel@tonic-gate #if _FFR_IGNORE_BOGUS_ADDR
62397c478bd9Sstevel@tonic-gate 	/* Ignore addresses for which prescan() failed */
62407c478bd9Sstevel@tonic-gate 	"_FFR_IGNORE_BOGUS_ADDR",
62417c478bd9Sstevel@tonic-gate #endif /* _FFR_IGNORE_BOGUS_ADDR */
62427c478bd9Sstevel@tonic-gate #if _FFR_IGNORE_EXT_ON_HELO
62437c478bd9Sstevel@tonic-gate 	/* Ignore extensions offered in response to HELO */
62447c478bd9Sstevel@tonic-gate 	"_FFR_IGNORE_EXT_ON_HELO",
62457c478bd9Sstevel@tonic-gate #endif /* _FFR_IGNORE_EXT_ON_HELO */
62467c478bd9Sstevel@tonic-gate #if _FFR_MAXDATASIZE
62477c478bd9Sstevel@tonic-gate 	/*
62487c478bd9Sstevel@tonic-gate 	**  It is possible that a header is larger than MILTER_CHUNK_SIZE,
62497c478bd9Sstevel@tonic-gate 	**  hence this shouldn't be used as limit for milter communication.
62507c478bd9Sstevel@tonic-gate 	**  see also libmilter/comm.c
62517c478bd9Sstevel@tonic-gate 	**  Gurusamy Sarathy of ActiveState
62527c478bd9Sstevel@tonic-gate 	*/
62537c478bd9Sstevel@tonic-gate 
62547c478bd9Sstevel@tonic-gate 	"_FFR_MAXDATASIZE",
62557c478bd9Sstevel@tonic-gate #endif /* _FFR_MAXDATASIZE */
62567c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES
62577c478bd9Sstevel@tonic-gate 	/* Try to limit number of .forward entries */
62587c478bd9Sstevel@tonic-gate 	/* (doesn't work) */
62597c478bd9Sstevel@tonic-gate /* Randall S. Winchester of the University of Maryland */
62607c478bd9Sstevel@tonic-gate 	"_FFR_MAX_FORWARD_ENTRIES",
62617c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */
6262445f2479Sjbeck #if _FFR_MAXKEY
6263445f2479Sjbeck 	/* increase key size for LDAP lookups, see conf.h */
6264445f2479Sjbeck 	"_FFR_MAXKEY",
6265445f2479Sjbeck #endif /* _FFR_MAXKEY */
6266445f2479Sjbeck #if _FFR_MAXNOOPCOMMANDS
6267445f2479Sjbeck 	/* runtime option for "MaxNOOPCommands" */
6268445f2479Sjbeck 	"_FFR_MAXNOOPCOMMANDS",
6269445f2479Sjbeck #endif /* _FFR_MAXNOOPCOMMANDS */
62707c478bd9Sstevel@tonic-gate #if _FFR_MAX_SLEEP_TIME
62717c478bd9Sstevel@tonic-gate 	/* Limit sleep(2) time in libsm/clock.c */
62727c478bd9Sstevel@tonic-gate 	"_FFR_MAX_SLEEP_TIME",
62737c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_SLEEP_TIME */
6274445f2479Sjbeck #if _FFR_MEMSTAT
6275445f2479Sjbeck 	/* Check free memory */
6276445f2479Sjbeck 	"_FFR_MEMSTAT",
6277445f2479Sjbeck #endif /* _FFR_MEMSTAT */
62787c478bd9Sstevel@tonic-gate #if _FFR_MILTER_NAGLE
62797c478bd9Sstevel@tonic-gate 	/* milter: turn off Nagle ("cork" on Linux) */
62807c478bd9Sstevel@tonic-gate 	/* John Gardiner Myers of Proofpoint */
62817c478bd9Sstevel@tonic-gate 	"_FFR_MILTER_NAGLE ",
62827c478bd9Sstevel@tonic-gate #endif /* _FFR_MILTER_NAGLE */
62837c478bd9Sstevel@tonic-gate #if _FFR_MILTER_NOHDR_RESP
62847c478bd9Sstevel@tonic-gate 	/* milter: no response expected when sending headers */
62857c478bd9Sstevel@tonic-gate 	/* John Gardiner Myers of Proofpoint */
62867c478bd9Sstevel@tonic-gate 	"_FFR_MILTER_NOHDR_RESP",
62877c478bd9Sstevel@tonic-gate #endif /* _FFR_MILTER_NOHDR_RESP */
62887c478bd9Sstevel@tonic-gate #if _FFR_MIME7TO8_OLD
62897c478bd9Sstevel@tonic-gate 	/* Old mime7to8 code, the new is broken for at least one example. */
62907c478bd9Sstevel@tonic-gate 	"_FFR_MIME7TO8_OLD",
62917c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_SLEEP_TIME */
6292445f2479Sjbeck #if _FFR_MSG_ACCEPT
6293445f2479Sjbeck 	/* allow to override "Message accepted for delivery" */
6294445f2479Sjbeck 	"_FFR_MSG_ACCEPT",
6295445f2479Sjbeck #endif /* _FFR_MSG_ACCEPT */
62967c478bd9Sstevel@tonic-gate #if _FFR_NODELAYDSN_ON_HOLD
62977c478bd9Sstevel@tonic-gate 	/* Do not issue a DELAY DSN for mailers that use the hold flag. */
62987c478bd9Sstevel@tonic-gate /* Steven Pitzl */
62997c478bd9Sstevel@tonic-gate 	"_FFR_NODELAYDSN_ON_HOLD",
63007c478bd9Sstevel@tonic-gate #endif /* _FFR_NODELAYDSN_ON_HOLD */
63017c478bd9Sstevel@tonic-gate #if _FFR_NO_PIPE
63027c478bd9Sstevel@tonic-gate 	/* Disable PIPELINING, delay client if used. */
63037c478bd9Sstevel@tonic-gate 	"_FFR_NO_PIPE",
63047c478bd9Sstevel@tonic-gate #endif /* _FFR_NO_PIPE */
63057c478bd9Sstevel@tonic-gate #if _FFR_LOG_NTRIES
63067c478bd9Sstevel@tonic-gate 	/* log ntries=, from Nik Clayton of FreeBSD */
63077c478bd9Sstevel@tonic-gate 	"_FFR_LOG_NTRIES",
63087c478bd9Sstevel@tonic-gate #endif /* _FFR_LOG_NTRIES */
63097c478bd9Sstevel@tonic-gate #if _FFR_PRIV_NOACTUALRECIPIENT
63107c478bd9Sstevel@tonic-gate 	/*
63117c478bd9Sstevel@tonic-gate 	**  PrivacyOptions=noactualrecipient stops sendmail from putting
63127c478bd9Sstevel@tonic-gate 	**  X-Actual-Recipient lines in DSNs revealing the actual
63137c478bd9Sstevel@tonic-gate 	**  account that addresses map to.  Patch from Dan Harkless.
63147c478bd9Sstevel@tonic-gate 	*/
63157c478bd9Sstevel@tonic-gate 
63167c478bd9Sstevel@tonic-gate 	"_FFR_PRIV_NOACTUALRECIPIENT",
63177c478bd9Sstevel@tonic-gate #endif /* _FFR_PRIV_NOACTUALRECIPIENT */
63187c478bd9Sstevel@tonic-gate #if _FFR_QUEUEDELAY
63197c478bd9Sstevel@tonic-gate 	/* Exponential queue delay; disabled in 8.13 since it isn't used. */
63207c478bd9Sstevel@tonic-gate 	"_FFR_QUEUEDELAY",
63217c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUEDELAY */
63227c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_GROUP_SORTORDER
63237c478bd9Sstevel@tonic-gate 	/* Allow QueueSortOrder per queue group. */
63247c478bd9Sstevel@tonic-gate /* XXX: Still need to actually use qgrp->qg_sortorder */
63257c478bd9Sstevel@tonic-gate 	"_FFR_QUEUE_GROUP_SORTORDER",
63267c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_GROUP_SORTORDER */
63277c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_MACRO
63287c478bd9Sstevel@tonic-gate 	/* Define {queue} macro. */
63297c478bd9Sstevel@tonic-gate 	"_FFR_QUEUE_MACRO",
63307c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_MACRO */
63317c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_RUN_PARANOIA
6332445f2479Sjbeck 	/* Additional checks when doing queue runs; interval of checks */
63337c478bd9Sstevel@tonic-gate 	"_FFR_QUEUE_RUN_PARANOIA",
63347c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_RUN_PARANOIA */
63357c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_SCHED_DBG
63367c478bd9Sstevel@tonic-gate 	/* Debug output for the queue scheduler. */
63377c478bd9Sstevel@tonic-gate 	"_FFR_QUEUE_SCHED_DBG",
63387c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_SCHED_DBG */
63397c478bd9Sstevel@tonic-gate #if _FFR_REDIRECTEMPTY
63407c478bd9Sstevel@tonic-gate 	/*
63417c478bd9Sstevel@tonic-gate 	**  envelope <> can't be sent to mailing lists, only owner-
63427c478bd9Sstevel@tonic-gate 	**  send spam of this type to owner- of the list
63437c478bd9Sstevel@tonic-gate 	**  ----  to stop spam from going to mailing lists.
63447c478bd9Sstevel@tonic-gate 	*/
63457c478bd9Sstevel@tonic-gate 
63467c478bd9Sstevel@tonic-gate 	"_FFR_REDIRECTEMPTY",
63477c478bd9Sstevel@tonic-gate #endif /* _FFR_REDIRECTEMPTY */
63487c478bd9Sstevel@tonic-gate #if _FFR_RESET_MACRO_GLOBALS
63497c478bd9Sstevel@tonic-gate 	/* Allow macro 'j' to be set dynamically via rulesets. */
63507c478bd9Sstevel@tonic-gate 	"_FFR_RESET_MACRO_GLOBALS",
63517c478bd9Sstevel@tonic-gate #endif /* _FFR_RESET_MACRO_GLOBALS */
63527c478bd9Sstevel@tonic-gate #if _FFR_RHS
63537c478bd9Sstevel@tonic-gate 	/* Random shuffle for queue sorting. */
63547c478bd9Sstevel@tonic-gate 	"_FFR_RHS",
63557c478bd9Sstevel@tonic-gate #endif /* _FFR_RHS */
63567c478bd9Sstevel@tonic-gate #if _FFR_SELECT_SHM
63577c478bd9Sstevel@tonic-gate 	/* Auto-select of shared memory key */
63587c478bd9Sstevel@tonic-gate 	"_FFR_SELECT_SHM",
63597c478bd9Sstevel@tonic-gate #endif /* _FFR_SELECT_SHM */
63607c478bd9Sstevel@tonic-gate #if _FFR_SHM_STATUS
63617c478bd9Sstevel@tonic-gate 	/* Donated code (unused). */
63627c478bd9Sstevel@tonic-gate 	"_FFR_SHM_STATUS",
63637c478bd9Sstevel@tonic-gate #endif /* _FFR_SHM_STATUS */
636449218d4fSjbeck #if _FFR_LDAP_SINGLEDN
636549218d4fSjbeck 	/*
636649218d4fSjbeck 	**  The LDAP database map code in Sendmail 8.12.10, when
636749218d4fSjbeck 	**  given the -1 switch, would match only a single DN,
636849218d4fSjbeck 	**  but was able to return multiple attributes for that
636949218d4fSjbeck 	**  DN.  In Sendmail 8.13 this "bug" was corrected to
637049218d4fSjbeck 	**  only return if exactly one attribute matched.
637149218d4fSjbeck 	**
6372445f2479Sjbeck 	**  Unfortunately, our configuration uses the former
637349218d4fSjbeck 	**  behaviour.  Attached is a relatively simple patch
637449218d4fSjbeck 	**  to 8.13.4 which adds a -2 switch (for lack of a
637549218d4fSjbeck 	**  better option) which returns the single dn/multiple
637649218d4fSjbeck 	**  attributes.
637749218d4fSjbeck 	**
637849218d4fSjbeck 	** Jeffrey T. Eaton, Carnegie-Mellon University
637949218d4fSjbeck 	*/
638049218d4fSjbeck 
638149218d4fSjbeck 	"_FFR_LDAP_SINGLEDN",
638249218d4fSjbeck #endif /* _FFR_LDAP_SINGLEDN */
63837c478bd9Sstevel@tonic-gate #if _FFR_SKIP_DOMAINS
63847c478bd9Sstevel@tonic-gate 	/* process every N'th domain instead of every N'th message */
63857c478bd9Sstevel@tonic-gate 	"_FFR_SKIP_DOMAINS",
63867c478bd9Sstevel@tonic-gate #endif /* _FFR_SKIP_DOMAINS */
63877c478bd9Sstevel@tonic-gate #if _FFR_SLEEP_USE_SELECT
63887c478bd9Sstevel@tonic-gate 	/* Use select(2) in libsm/clock.c to emulate sleep(2) */
63897c478bd9Sstevel@tonic-gate 	"_FFR_SLEEP_USE_SELECT ",
63907c478bd9Sstevel@tonic-gate #endif /* _FFR_SLEEP_USE_SELECT */
63917c478bd9Sstevel@tonic-gate #if _FFR_SOFT_BOUNCE
63927c478bd9Sstevel@tonic-gate 	/* Turn all errors into temporary errors. */
63937c478bd9Sstevel@tonic-gate 	"_FFR_SOFT_BOUNCE",
63947c478bd9Sstevel@tonic-gate #endif /* _FFR_SOFT_BOUNCE */
63957c478bd9Sstevel@tonic-gate #if _FFR_SPT_ALIGN
63967c478bd9Sstevel@tonic-gate 	/*
63977c478bd9Sstevel@tonic-gate 	**  It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64
63987c478bd9Sstevel@tonic-gate 	**  bit alignment, so unless each piece of argv and envp is a multiple
63997c478bd9Sstevel@tonic-gate 	**  of 8 bytes (including terminating NULL), initsetproctitle() won't
64007c478bd9Sstevel@tonic-gate 	**  use any of the space beyond argv[0]. Be sure to set SPT_ALIGN_SIZE
64017c478bd9Sstevel@tonic-gate 	**  if you use this FFR.
64027c478bd9Sstevel@tonic-gate 	*/
64037c478bd9Sstevel@tonic-gate 
64047c478bd9Sstevel@tonic-gate /* Chris Adams of HiWAAY Informations Services */
64057c478bd9Sstevel@tonic-gate 	"_FFR_SPT_ALIGN",
64067c478bd9Sstevel@tonic-gate #endif /* _FFR_SPT_ALIGN */
64077c478bd9Sstevel@tonic-gate #if _FFR_SS_PER_DAEMON
64087c478bd9Sstevel@tonic-gate 	/* SuperSafe per DaemonPortOptions: 'T' (better letter?) */
64097c478bd9Sstevel@tonic-gate 	"_FFR_SS_PER_DAEMON",
64107c478bd9Sstevel@tonic-gate #endif /* _FFR_SS_PER_DAEMON */
64117c478bd9Sstevel@tonic-gate #if _FFR_TIMERS
64127c478bd9Sstevel@tonic-gate 	/* Donated code (unused). */
64137c478bd9Sstevel@tonic-gate 	"_FFR_TIMERS",
64147c478bd9Sstevel@tonic-gate #endif /* _FFR_TIMERS */
64157c478bd9Sstevel@tonic-gate #if _FFR_TLS_1
64167c478bd9Sstevel@tonic-gate 	/* More STARTTLS options, e.g., secondary certs. */
64177c478bd9Sstevel@tonic-gate 	"_FFR_TLS_1",
64187c478bd9Sstevel@tonic-gate #endif /* _FFR_TLS_1 */
64197c478bd9Sstevel@tonic-gate #if _FFR_TRUSTED_QF
64207c478bd9Sstevel@tonic-gate 	/*
64217c478bd9Sstevel@tonic-gate 	**  If we don't own the file mark it as unsafe.
64227c478bd9Sstevel@tonic-gate 	**  However, allow TrustedUser to own it as well
64237c478bd9Sstevel@tonic-gate 	**  in case TrustedUser manipulates the queue.
64247c478bd9Sstevel@tonic-gate 	*/
64257c478bd9Sstevel@tonic-gate 
64267c478bd9Sstevel@tonic-gate 	"_FFR_TRUSTED_QF",
64277c478bd9Sstevel@tonic-gate #endif /* _FFR_TRUSTED_QF */
64287c478bd9Sstevel@tonic-gate #if _FFR_USE_SEM_LOCKING
64297c478bd9Sstevel@tonic-gate 	"_FFR_USE_SEM_LOCKING",
64307c478bd9Sstevel@tonic-gate #endif /* _FFR_USE_SEM_LOCKING */
64317c478bd9Sstevel@tonic-gate #if _FFR_USE_SETLOGIN
64327c478bd9Sstevel@tonic-gate 	/* Use setlogin() */
64337c478bd9Sstevel@tonic-gate /* Peter Philipp */
64347c478bd9Sstevel@tonic-gate 	"_FFR_USE_SETLOGIN",
64357c478bd9Sstevel@tonic-gate #endif /* _FFR_USE_SETLOGIN */
64367c478bd9Sstevel@tonic-gate 	NULL
64377c478bd9Sstevel@tonic-gate };
64387c478bd9Sstevel@tonic-gate 
6439