+\f/*
+** STRTOL -- convert string to long integer
+**
+** For systems that don't have it in the C library.
+**
+** This is taken verbatim from the 4.4-Lite C library.
+*/
+
+#ifdef NEEDSTRTOL
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+
+#endif
+\f/*
+** SOLARIS_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+**
+** Solaris versions prior through 2.3 don't properly deliver a
+** canonical h_name field. This tries to work around it.
+*/
+
+#ifdef SOLARIS
+
+struct hostent *
+solaris_gethostbyname(name)
+ const char *name;
+{
+# ifdef SOLARIS_2_3
+ static struct hostent hp;
+ static char buf[1000];
+ extern struct hostent *_switch_gethostbyname_r();
+
+ return _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
+# else
+ extern struct hostent *__switch_gethostbyname();
+
+ return __switch_gethostbyname(name);
+# endif
+}
+
+struct hostent *
+solaris_gethostbyaddr(addr, len, type)
+ const char *addr;
+ int len;
+ int type;
+{
+# ifdef SOLARIS_2_3
+ static struct hostent hp;
+ static char buf[1000];
+ extern struct hostent *_switch_gethostbyaddr_r();
+
+ return _switch_gethostbyaddr_r(addr, len, type, &hp, buf, sizeof(buf), &h_errno);
+# else
+ extern struct hostent *__switch_gethostbyaddr();
+
+ return __switch_gethostbyaddr(addr, len, type);
+# endif
+}
+
+#endif
+\f/*
+** NI_PROPVAL -- netinfo property value lookup routine
+**
+** Parameters:
+** directory -- the Netinfo directory name.
+** propname -- the Netinfo property name.
+**
+** Returns:
+** NULL -- if:
+** 1. the directory is not found
+** 2. the property name is not found
+** 3. the property contains multiple values
+** 4. some error occured
+** else -- the location of the config file.
+**
+** Notes:
+** Caller should free the return value of ni_proval
+*/
+
+#ifdef NETINFO
+
+# include <netinfo/ni.h>
+
+# define LOCAL_NETINFO_DOMAIN "."
+# define PARENT_NETINFO_DOMAIN ".."
+# define MAX_NI_LEVELS 256
+
+char *
+ni_propval(directory, propname)
+ char *directory;
+ char *propname;
+{
+ char *propval = NULL;
+ int i;
+ void *ni = NULL;
+ void *lastni = NULL;
+ ni_status nis;
+ ni_id nid;
+ ni_namelist ninl;
+
+ /*
+ ** If the passed directory and property name are found
+ ** in one of netinfo domains we need to search (starting
+ ** from the local domain moving all the way back to the
+ ** root domain) set propval to the property's value
+ ** and return it.
+ */
+
+ for (i = 0; i < MAX_NI_LEVELS; ++i)
+ {
+ if (i == 0)
+ {
+ nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
+ }
+ else
+ {
+ if (lastni != NULL)
+ ni_free(lastni);
+ lastni = ni;
+ nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
+ }
+
+ /*
+ ** Don't bother if we didn't get a handle on a
+ ** proper domain. This is not necessarily an error.
+ ** We would get a positive ni_status if, for instance
+ ** we never found the directory or property and tried
+ ** to open the parent of the root domain!
+ */
+
+ if (nis != 0)
+ break;
+
+ /*
+ ** Find the path to the server information.
+ */
+
+ if (ni_pathsearch(ni, &nid, directory) != 0)
+ continue;
+
+ /*
+ ** Find "host" information.
+ */
+
+ if (ni_lookupprop(ni, &nid, propname, &ninl) != 0)
+ continue;
+
+ /*
+ ** If there's only one name in
+ ** the list, assume we've got
+ ** what we want.
+ */
+
+ if (ninl.ni_namelist_len == 1)
+ {
+ propval = ni_name_dup(ninl.ni_namelist_val[0]);
+ break;
+ }
+ }
+
+ /*
+ ** Clean up.
+ */
+
+ if (ni != NULL)
+ ni_free(ni);
+ if (lastni != NULL && ni != lastni)
+ ni_free(lastni);
+
+ return propval;
+}
+
+#endif /* NETINFO */
+\f/*
+** HARD_SYSLOG -- call syslog repeatedly until it works
+**
+** Needed on HP-UX, which apparently doesn't guarantee that
+** syslog succeeds during interrupt handlers.
+*/
+
+#ifdef __hpux
+
+# define MAXSYSLOGTRIES 100
+# undef syslog
+
+# ifdef __STDC__
+hard_syslog(int pri, char *msg, ...)
+# else
+hard_syslog(pri, msg, va_alist)
+ int pri;
+ char *msg;
+ va_dcl
+# endif
+{
+ int i;
+ char buf[SYSLOG_BUFSIZE * 2];
+ VA_LOCAL_DECL;
+
+ VA_START(msg);
+ vsprintf(buf, msg, ap);
+ VA_END;
+
+ for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, "%s", buf) < 0; )
+ continue;
+}
+
+#endif