summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/roken
diff options
context:
space:
mode:
authorHeimdal Import User <samba-bugs@samba.org>2005-07-11 01:16:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:33 -0500
commit954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9 (patch)
treefc11a048c8a582e2ca66415ff04dacf74f9abf22 /source4/heimdal/lib/roken
parent7ead5ab06cea9f33e954a4579163262f97ea06ff (diff)
downloadsamba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.tar.gz
samba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.tar.bz2
samba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.zip
r8302: import mini HEIMDAL into the tree
(This used to be commit 118be28a7aef233799956615a99d1a2a74dac175)
Diffstat (limited to 'source4/heimdal/lib/roken')
-rw-r--r--source4/heimdal/lib/roken/base64.c136
-rw-r--r--source4/heimdal/lib/roken/base64.h53
-rw-r--r--source4/heimdal/lib/roken/bswap.c61
-rw-r--r--source4/heimdal/lib/roken/emalloc.c56
-rw-r--r--source4/heimdal/lib/roken/get_window_size.c102
-rw-r--r--source4/heimdal/lib/roken/getarg.c595
-rw-r--r--source4/heimdal/lib/roken/getarg.h102
-rw-r--r--source4/heimdal/lib/roken/getifaddrs.c1186
-rw-r--r--source4/heimdal/lib/roken/getprogname.c51
-rw-r--r--source4/heimdal/lib/roken/h_errno.c41
-rw-r--r--source4/heimdal/lib/roken/issuid.c59
-rw-r--r--source4/heimdal/lib/roken/net_read.c74
-rw-r--r--source4/heimdal/lib/roken/net_write.c72
-rw-r--r--source4/heimdal/lib/roken/parse_time.c78
-rw-r--r--source4/heimdal/lib/roken/parse_time.h59
-rw-r--r--source4/heimdal/lib/roken/parse_units.c330
-rw-r--r--source4/heimdal/lib/roken/parse_units.h79
-rw-r--r--source4/heimdal/lib/roken/print_version.c78
-rw-r--r--source4/heimdal/lib/roken/resolve.c690
-rw-r--r--source4/heimdal/lib/roken/resolve.h298
-rw-r--r--source4/heimdal/lib/roken/roken-common.h399
-rw-r--r--source4/heimdal/lib/roken/roken.h688
-rw-r--r--source4/heimdal/lib/roken/roken_gethostby.c274
-rw-r--r--source4/heimdal/lib/roken/setprogname.c61
-rw-r--r--source4/heimdal/lib/roken/signal.c80
-rw-r--r--source4/heimdal/lib/roken/strlwr.c53
-rw-r--r--source4/heimdal/lib/roken/strpool.c111
-rw-r--r--source4/heimdal/lib/roken/strsep_copy.c69
-rw-r--r--source4/heimdal/lib/roken/strupr.c53
-rw-r--r--source4/heimdal/lib/roken/vis.c330
-rw-r--r--source4/heimdal/lib/roken/vis.hin98
31 files changed, 6416 insertions, 0 deletions
diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c
new file mode 100644
index 0000000000..78dbe9c526
--- /dev/null
+++ b/source4/heimdal/lib/roken/base64.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: base64.c,v 1.6 2005/04/12 11:28:34 lha Exp $");
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "base64.h"
+
+static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int
+pos(char c)
+{
+ const char *p;
+ for (p = base64_chars; *p; p++)
+ if (*p == c)
+ return p - base64_chars;
+ return -1;
+}
+
+int ROKEN_LIB_FUNCTION
+base64_encode(const void *data, int size, char **str)
+{
+ char *s, *p;
+ int i;
+ int c;
+ const unsigned char *q;
+
+ p = s = (char *) malloc(size * 4 / 3 + 4);
+ if (p == NULL)
+ return -1;
+ q = (const unsigned char *) data;
+ i = 0;
+ for (i = 0; i < size;) {
+ c = q[i++];
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ p[0] = base64_chars[(c & 0x00fc0000) >> 18];
+ p[1] = base64_chars[(c & 0x0003f000) >> 12];
+ p[2] = base64_chars[(c & 0x00000fc0) >> 6];
+ p[3] = base64_chars[(c & 0x0000003f) >> 0];
+ if (i > size)
+ p[3] = '=';
+ if (i > size + 1)
+ p[2] = '=';
+ p += 4;
+ }
+ *p = 0;
+ *str = s;
+ return strlen(s);
+}
+
+#define DECODE_ERROR 0xffffffff
+
+static unsigned int
+token_decode(const char *token)
+{
+ int i;
+ unsigned int val = 0;
+ int marker = 0;
+ if (strlen(token) < 4)
+ return DECODE_ERROR;
+ for (i = 0; i < 4; i++) {
+ val *= 64;
+ if (token[i] == '=')
+ marker++;
+ else if (marker > 0)
+ return DECODE_ERROR;
+ else
+ val += pos(token[i]);
+ }
+ if (marker > 2)
+ return DECODE_ERROR;
+ return (marker << 24) | val;
+}
+
+int ROKEN_LIB_FUNCTION
+base64_decode(const char *str, void *data)
+{
+ const char *p;
+ unsigned char *q;
+
+ q = data;
+ for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
+ unsigned int val = token_decode(p);
+ unsigned int marker = (val >> 24) & 0xff;
+ if (val == DECODE_ERROR)
+ return -1;
+ *q++ = (val >> 16) & 0xff;
+ if (marker < 2)
+ *q++ = (val >> 8) & 0xff;
+ if (marker < 1)
+ *q++ = val & 0xff;
+ }
+ return q - (unsigned char *) data;
+}
diff --git a/source4/heimdal/lib/roken/base64.h b/source4/heimdal/lib/roken/base64.h
new file mode 100644
index 0000000000..95992f9c21
--- /dev/null
+++ b/source4/heimdal/lib/roken/base64.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: base64.h,v 1.4 2005/06/30 07:13:33 lha Exp $ */
+
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+int ROKEN_LIB_FUNCTION
+base64_encode(const void *, int, char **);
+
+int ROKEN_LIB_FUNCTION
+base64_decode(const char *, void *);
+
+#endif
diff --git a/source4/heimdal/lib/roken/bswap.c b/source4/heimdal/lib/roken/bswap.c
new file mode 100644
index 0000000000..48b587d2db
--- /dev/null
+++ b/source4/heimdal/lib/roken/bswap.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+RCSID("$Id: bswap.c,v 1.4 2005/04/12 11:28:35 lha Exp $");
+
+#ifndef HAVE_BSWAP32
+
+unsigned int ROKEN_LIB_FUNCTION
+bswap32 (unsigned int val)
+{
+ return (val & 0xff) << 24 |
+ (val & 0xff00) << 8 |
+ (val & 0xff0000) >> 8 |
+ (val & 0xff000000) >> 24;
+}
+#endif
+
+#ifndef HAVE_BSWAP16
+
+unsigned short ROKEN_LIB_FUNCTION
+bswap16 (unsigned short val)
+{
+ return (val & 0xff) << 8 |
+ (val & 0xff00) >> 8;
+}
+#endif
diff --git a/source4/heimdal/lib/roken/emalloc.c b/source4/heimdal/lib/roken/emalloc.c
new file mode 100644
index 0000000000..91af6b5184
--- /dev/null
+++ b/source4/heimdal/lib/roken/emalloc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: emalloc.c,v 1.6 2005/04/12 11:28:37 lha Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like malloc but never fails.
+ */
+
+void * ROKEN_LIB_FUNCTION
+emalloc (size_t sz)
+{
+ void *tmp = malloc (sz);
+
+ if (tmp == NULL && sz != 0)
+ errx (1, "malloc %lu failed", (unsigned long)sz);
+ return tmp;
+}
diff --git a/source4/heimdal/lib/roken/get_window_size.c b/source4/heimdal/lib/roken/get_window_size.c
new file mode 100644
index 0000000000..6743e15af9
--- /dev/null
+++ b/source4/heimdal/lib/roken/get_window_size.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: get_window_size.c,v 1.10 2005/04/12 11:28:42 lha Exp $");
+#endif
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if 0 /* Where were those needed? /confused */
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+
+#ifdef HAVE_SYS_TTY_H
+#include <sys/tty.h>
+#endif
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#include <roken.h>
+
+int ROKEN_LIB_FUNCTION
+get_window_size(int fd, struct winsize *wp)
+{
+ int ret = -1;
+
+ memset(wp, 0, sizeof(*wp));
+
+#if defined(TIOCGWINSZ)
+ ret = ioctl(fd, TIOCGWINSZ, wp);
+#elif defined(TIOCGSIZE)
+ {
+ struct ttysize ts;
+
+ ret = ioctl(fd, TIOCGSIZE, &ts);
+ if(ret == 0) {
+ wp->ws_row = ts.ts_lines;
+ wp->ws_col = ts.ts_cols;
+ }
+ }
+#elif defined(HAVE__SCRSIZE)
+ {
+ int dst[2];
+
+ _scrsize(dst);
+ wp->ws_row = dst[1];
+ wp->ws_col = dst[0];
+ ret = 0;
+ }
+#endif
+ if (ret != 0) {
+ char *s;
+ if((s = getenv("COLUMNS")))
+ wp->ws_col = atoi(s);
+ if((s = getenv("LINES")))
+ wp->ws_row = atoi(s);
+ if(wp->ws_col > 0 && wp->ws_row > 0)
+ ret = 0;
+ }
+ return ret;
+}
diff --git a/source4/heimdal/lib/roken/getarg.c b/source4/heimdal/lib/roken/getarg.c
new file mode 100644
index 0000000000..e4e0556adf
--- /dev/null
+++ b/source4/heimdal/lib/roken/getarg.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getarg.c,v 1.48 2005/04/12 11:28:43 lha Exp $");
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <roken.h>
+#include "getarg.h"
+
+#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+static size_t
+print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg)
+{
+ const char *s;
+
+ *string = '\0';
+
+ if (ISFLAG(*arg) || (!longp && arg->type == arg_counter))
+ return 0;
+
+ if(mdoc){
+ if(longp)
+ strlcat(string, "= Ns", len);
+ strlcat(string, " Ar ", len);
+ } else {
+ if (longp)
+ strlcat (string, "=", len);
+ else
+ strlcat (string, " ", len);
+ }
+
+ if (arg->arg_help)
+ s = arg->arg_help;
+ else if (arg->type == arg_integer || arg->type == arg_counter)
+ s = "integer";
+ else if (arg->type == arg_string)
+ s = "string";
+ else if (arg->type == arg_strings)
+ s = "strings";
+ else if (arg->type == arg_double)
+ s = "float";
+ else
+ s = "<undefined>";
+
+ strlcat(string, s, len);
+ return 1 + strlen(s);
+}
+
+static void
+mandoc_template(struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string)
+{
+ int i;
+ char timestr[64], cmd[64];
+ char buf[128];
+ const char *p;
+ time_t t;
+
+ printf(".\\\" Things to fix:\n");
+ printf(".\\\" * correct section, and operating system\n");
+ printf(".\\\" * remove Op from mandatory flags\n");
+ printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
+ printf(".\\\"\n");
+ t = time(NULL);
+ strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t));
+ printf(".Dd %s\n", timestr);
+ p = strrchr(progname, '/');
+ if(p) p++; else p = progname;
+ strlcpy(cmd, p, sizeof(cmd));
+ strupr(cmd);
+
+ printf(".Dt %s SECTION\n", cmd);
+ printf(".Os OPERATING_SYSTEM\n");
+ printf(".Sh NAME\n");
+ printf(".Nm %s\n", p);
+ printf(".Nd\n");
+ printf("in search of a description\n");
+ printf(".Sh SYNOPSIS\n");
+ printf(".Nm\n");
+ for(i = 0; i < num_args; i++){
+ /* we seem to hit a limit on number of arguments if doing
+ short and long flags with arguments -- split on two lines */
+ if(ISFLAG(args[i]) ||
+ args[i].short_name == 0 || args[i].long_name == NULL) {
+ printf(".Op ");
+
+ if(args[i].short_name) {
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf("Fl %c%s", args[i].short_name, buf);
+ if(args[i].long_name)
+ printf(" | ");
+ }
+ if(args[i].long_name) {
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf("Fl -%s%s%s",
+ args[i].type == arg_negative_flag ? "no-" : "",
+ args[i].long_name, buf);
+ }
+ printf("\n");
+ } else {
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf);
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf(".Fl -%s%s\n.Xc\n.Oc\n", args[i].long_name, buf);
+ }
+ /*
+ if(args[i].type == arg_strings)
+ fprintf (stderr, "...");
+ */
+ }
+ if (extra_string && *extra_string)
+ printf (".Ar %s\n", extra_string);
+ printf(".Sh DESCRIPTION\n");
+ printf("Supported options:\n");
+ printf(".Bl -tag -width Ds\n");
+ for(i = 0; i < num_args; i++){
+ printf(".It Xo\n");
+ if(args[i].short_name){
+ printf(".Fl %c", args[i].short_name);
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf("%s", buf);
+ if(args[i].long_name)
+ printf(" ,");
+ printf("\n");
+ }
+ if(args[i].long_name){
+ printf(".Fl -%s%s",
+ args[i].type == arg_negative_flag ? "no-" : "",
+ args[i].long_name);
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf("%s\n", buf);
+ }
+ printf(".Xc\n");
+ if(args[i].help)
+ printf("%s\n", args[i].help);
+ /*
+ if(args[i].type == arg_strings)
+ fprintf (stderr, "...");
+ */
+ }
+ printf(".El\n");
+ printf(".\\\".Sh ENVIRONMENT\n");
+ printf(".\\\".Sh FILES\n");
+ printf(".\\\".Sh EXAMPLES\n");
+ printf(".\\\".Sh DIAGNOSTICS\n");
+ printf(".\\\".Sh SEE ALSO\n");
+ printf(".\\\".Sh STANDARDS\n");
+ printf(".\\\".Sh HISTORY\n");
+ printf(".\\\".Sh AUTHORS\n");
+ printf(".\\\".Sh BUGS\n");
+}
+
+static int
+check_column(FILE *f, int col, int len, int columns)
+{
+ if(col + len > columns) {
+ fprintf(f, "\n");
+ col = fprintf(f, " ");
+ }
+ return col;
+}
+
+void ROKEN_LIB_FUNCTION
+arg_printusage (struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string)
+{
+ int i;
+ size_t max_len = 0;
+ char buf[128];
+ int col = 0, columns;
+ struct winsize ws;
+
+ if (progname == NULL)
+ progname = getprogname();
+
+ if(getenv("GETARGMANDOC")){
+ mandoc_template(args, num_args, progname, extra_string);
+ return;
+ }
+ if(get_window_size(2, &ws) == 0)
+ columns = ws.ws_col;
+ else
+ columns = 80;
+ col = 0;
+ col += fprintf (stderr, "Usage: %s", progname);
+ buf[0] = '\0';
+ for (i = 0; i < num_args; ++i) {
+ if(args[i].short_name && ISFLAG(args[i])) {
+ char s[2];
+ if(buf[0] == '\0')
+ strlcpy(buf, "[-", sizeof(buf));
+ s[0] = args[i].short_name;
+ s[1] = '\0';
+ strlcat(buf, s, sizeof(buf));
+ }
+ }
+ if(buf[0] != '\0') {
+ strlcat(buf, "]", sizeof(buf));
+ col = check_column(stderr, col, strlen(buf) + 1, columns);
+ col += fprintf(stderr, " %s", buf);
+ }
+
+ for (i = 0; i < num_args; ++i) {
+ size_t len = 0;
+
+ if (args[i].long_name) {
+ buf[0] = '\0';
+ strlcat(buf, "[--", sizeof(buf));
+ len += 2;
+ if(args[i].type == arg_negative_flag) {
+ strlcat(buf, "no-", sizeof(buf));
+ len += 3;
+ }
+ strlcat(buf, args[i].long_name, sizeof(buf));
+ len += strlen(args[i].long_name);
+ len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ 0, 1, &args[i]);
+ strlcat(buf, "]", sizeof(buf));
+ if(args[i].type == arg_strings)
+ strlcat(buf, "...", sizeof(buf));
+ col = check_column(stderr, col, strlen(buf) + 1, columns);
+ col += fprintf(stderr, " %s", buf);
+ }
+ if (args[i].short_name && !ISFLAG(args[i])) {
+ snprintf(buf, sizeof(buf), "[-%c", args[i].short_name);
+ len += 2;
+ len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ 0, 0, &args[i]);
+ strlcat(buf, "]", sizeof(buf));
+ if(args[i].type == arg_strings)
+ strlcat(buf, "...", sizeof(buf));
+ col = check_column(stderr, col, strlen(buf) + 1, columns);
+ col += fprintf(stderr, " %s", buf);
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+ max_len = max(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+ fprintf (stderr, " %s\n", extra_string);
+ } else
+ fprintf (stderr, "\n");
+ for (i = 0; i < num_args; ++i) {
+ if (args[i].help) {
+ size_t count = 0;
+
+ if (args[i].short_name) {
+ count += fprintf (stderr, "-%c", args[i].short_name);
+ print_arg (buf, sizeof(buf), 0, 0, &args[i]);
+ count += fprintf(stderr, "%s", buf);
+ }
+ if (args[i].short_name && args[i].long_name)
+ count += fprintf (stderr, ", ");
+ if (args[i].long_name) {
+ count += fprintf (stderr, "--");
+ if (args[i].type == arg_negative_flag)
+ count += fprintf (stderr, "no-");
+ count += fprintf (stderr, "%s", args[i].long_name);
+ print_arg (buf, sizeof(buf), 0, 1, &args[i]);
+ count += fprintf(stderr, "%s", buf);
+ }
+ while(count++ <= max_len)
+ putc (' ', stderr);
+ fprintf (stderr, "%s\n", args[i].help);
+ }
+ }
+}
+
+static int
+add_string(getarg_strings *s, char *value)
+{
+ char **strings;
+
+ strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings));
+ if (strings == NULL) {
+ free(s->strings);
+ s->strings = NULL;
+ s->num_strings = 0;
+ return ENOMEM;
+ }
+ s->strings = strings;
+ s->strings[s->num_strings] = value;
+ s->num_strings++;
+ return 0;
+}
+
+static int
+arg_match_long(struct getargs *args, size_t num_args,
+ char *argv, int argc, char **rargv, int *goptind)
+{
+ int i;
+ char *goptarg = NULL;
+ int negate = 0;
+ int partial_match = 0;
+ struct getargs *partial = NULL;
+ struct getargs *current = NULL;
+ int argv_len;
+ char *p;
+ int p_len;
+
+ argv_len = strlen(argv);
+ p = strchr (argv, '=');
+ if (p != NULL)
+ argv_len = p - argv;
+
+ for (i = 0; i < num_args; ++i) {
+ if(args[i].long_name) {
+ int len = strlen(args[i].long_name);
+ p = argv;
+ p_len = argv_len;
+ negate = 0;
+
+ for (;;) {
+ if (strncmp (args[i].long_name, p, p_len) == 0) {
+ if(p_len == len)
+ current = &args[i];
+ else {
+ ++partial_match;
+ partial = &args[i];
+ }
+ goptarg = p + p_len;
+ } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) {
+ negate = !negate;
+ p += 3;
+ p_len -= 3;
+ continue;
+ }
+ break;
+ }
+ if (current)
+ break;
+ }
+ }
+ if (current == NULL) {
+ if (partial_match == 1)
+ current = partial;
+ else
+ return ARG_ERR_NO_MATCH;
+ }
+
+ if(*goptarg == '\0'
+ && !ISFLAG(*current)
+ && current->type != arg_collect
+ && current->type != arg_counter)
+ return ARG_ERR_NO_MATCH;
+ switch(current->type){
+ case arg_integer:
+ {
+ int tmp;
+ if(sscanf(goptarg + 1, "%d", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(int*)current->value = tmp;
+ return 0;
+ }
+ case arg_string:
+ {
+ *(char**)current->value = goptarg + 1;
+ return 0;
+ }
+ case arg_strings:
+ {
+ return add_string((getarg_strings*)current->value, goptarg + 1);
+ }
+ case arg_flag:
+ case arg_negative_flag:
+ {
+ int *flag = current->value;
+ if(*goptarg == '\0' ||
+ strcmp(goptarg + 1, "yes") == 0 ||
+ strcmp(goptarg + 1, "true") == 0){
+ *flag = !negate;
+ return 0;
+ } else if (*goptarg && strcmp(goptarg + 1, "maybe") == 0) {
+#ifdef HAVE_RANDOM
+ *flag = random() & 1;
+#else
+ *flag = rand() & 1;
+#endif
+ } else {
+ *flag = negate;
+ return 0;
+ }
+ return ARG_ERR_BAD_ARG;
+ }
+ case arg_counter :
+ {
+ int val;
+
+ if (*goptarg == '\0')
+ val = 1;
+ else if(sscanf(goptarg + 1, "%d", &val) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(int *)current->value += val;
+ return 0;
+ }
+ case arg_double:
+ {
+ double tmp;
+ if(sscanf(goptarg + 1, "%lf", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(double*)current->value = tmp;
+ return 0;
+ }
+ case arg_collect:{
+ struct getarg_collect_info *c = current->value;
+ int o = argv - rargv[*goptind];
+ return (*c->func)(FALSE, argc, rargv, goptind, &o, c->data);
+ }
+
+ default:
+ abort ();
+ }
+}
+
+static int
+arg_match_short (struct getargs *args, size_t num_args,
+ char *argv, int argc, char **rargv, int *goptind)
+{
+ int j, k;
+
+ for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) {
+ for(k = 0; k < num_args; k++) {
+ char *goptarg;
+
+ if(args[k].short_name == 0)
+ continue;
+ if(argv[j] == args[k].short_name) {
+ if(args[k].type == arg_flag) {
+ *(int*)args[k].value = 1;
+ break;
+ }
+ if(args[k].type == arg_negative_flag) {
+ *(int*)args[k].value = 0;
+ break;
+ }
+ if(args[k].type == arg_counter) {
+ ++*(int *)args[k].value;
+ break;
+ }
+ if(args[k].type == arg_collect) {
+ struct getarg_collect_info *c = args[k].value;
+
+ if((*c->func)(TRUE, argc, rargv, goptind, &j, c->data))
+ return ARG_ERR_BAD_ARG;
+ break;
+ }
+
+ if(argv[j + 1])
+ goptarg = &argv[j + 1];
+ else {
+ ++*goptind;
+ goptarg = rargv[*goptind];
+ }
+ if(goptarg == NULL) {
+ --*goptind;
+ return ARG_ERR_NO_ARG;
+ }
+ if(args[k].type == arg_integer) {
+ int tmp;
+ if(sscanf(goptarg, "%d", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(int*)args[k].value = tmp;
+ return 0;
+ } else if(args[k].type == arg_string) {
+ *(char**)args[k].value = goptarg;
+ return 0;
+ } else if(args[k].type == arg_strings) {
+ return add_string((getarg_strings*)args[k].value, goptarg);
+ } else if(args[k].type == arg_double) {
+ double tmp;
+ if(sscanf(goptarg, "%lf", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(double*)args[k].value = tmp;
+ return 0;
+ }
+ return ARG_ERR_BAD_ARG;
+ }
+ }
+ if (k == num_args)
+ return ARG_ERR_NO_MATCH;
+ }
+ return 0;
+}
+
+int ROKEN_LIB_FUNCTION
+getarg(struct getargs *args, size_t num_args,
+ int argc, char **argv, int *goptind)
+{
+ int i;
+ int ret = 0;
+
+#if defined(HAVE_SRANDOMDEV)
+ srandomdev();
+#elif defined(HAVE_RANDOM)
+ srandom(time(NULL));
+#else
+ srand (time(NULL));
+#endif
+ (*goptind)++;
+ for(i = *goptind; i < argc; i++) {
+ if(argv[i][0] != '-')
+ break;
+ if(argv[i][1] == '-'){
+ if(argv[i][2] == 0){
+ i++;
+ break;
+ }
+ ret = arg_match_long (args, num_args, argv[i] + 2,
+ argc, argv, &i);
+ } else {
+ ret = arg_match_short (args, num_args, argv[i],
+ argc, argv, &i);
+ }
+ if(ret)
+ break;
+ }
+ *goptind = i;
+ return ret;
+}
+
+void ROKEN_LIB_FUNCTION
+free_getarg_strings (getarg_strings *s)
+{
+ free (s->strings);
+}
+
+#if TEST
+int foo_flag = 2;
+int flag1 = 0;
+int flag2 = 0;
+int bar_int;
+char *baz_string;
+
+struct getargs args[] = {
+ { NULL, '1', arg_flag, &flag1, "one", NULL },
+ { NULL, '2', arg_flag, &flag2, "two", NULL },
+ { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL },
+ { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"},
+ { "baz", 'x', arg_string, &baz_string, "baz", "name" },
+};
+
+int main(int argc, char **argv)
+{
+ int goptind = 0;
+ while(getarg(args, 5, argc, argv, &goptind))
+ printf("Bad arg: %s\n", argv[goptind]);
+ printf("flag1 = %d\n", flag1);
+ printf("flag2 = %d\n", flag2);
+ printf("foo_flag = %d\n", foo_flag);
+ printf("bar_int = %d\n", bar_int);
+ printf("baz_flag = %s\n", baz_string);
+ arg_printusage (args, 5, argv[0], "nothing here");
+}
+#endif
diff --git a/source4/heimdal/lib/roken/getarg.h b/source4/heimdal/lib/roken/getarg.h
new file mode 100644
index 0000000000..bffa04486f
--- /dev/null
+++ b/source4/heimdal/lib/roken/getarg.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: getarg.h,v 1.14 2005/04/13 05:52:27 lha Exp $ */
+
+#ifndef __GETARG_H__
+#define __GETARG_H__
+
+#include <stddef.h>
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+struct getargs{
+ const char *long_name;
+ char short_name;
+ enum { arg_integer,
+ arg_string,
+ arg_flag,
+ arg_negative_flag,
+ arg_strings,
+ arg_double,
+ arg_collect,
+ arg_counter
+ } type;
+ void *value;
+ const char *help;
+ const char *arg_help;
+};
+
+enum {
+ ARG_ERR_NO_MATCH = 1,
+ ARG_ERR_BAD_ARG,
+ ARG_ERR_NO_ARG
+};
+
+typedef struct getarg_strings {
+ int num_strings;
+ char **strings;
+} getarg_strings;
+
+typedef int (*getarg_collect_func)(int short_opt,
+ int argc,
+ char **argv,
+ int *goptind,
+ int *goptarg,
+ void *data);
+
+typedef struct getarg_collect_info {
+ getarg_collect_func func;
+ void *data;
+} getarg_collect_info;
+
+int ROKEN_LIB_FUNCTION
+getarg(struct getargs *args, size_t num_args,
+ int argc, char **argv, int *goptind);
+
+void ROKEN_LIB_FUNCTION
+arg_printusage (struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string);
+
+void ROKEN_LIB_FUNCTION
+free_getarg_strings (getarg_strings *);
+
+#endif /* __GETARG_H__ */
diff --git a/source4/heimdal/lib/roken/getifaddrs.c b/source4/heimdal/lib/roken/getifaddrs.c
new file mode 100644
index 0000000000..3c97e89810
--- /dev/null
+++ b/source4/heimdal/lib/roken/getifaddrs.c
@@ -0,0 +1,1186 @@
+/*
+ * Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getifaddrs.c,v 1.11 2005/04/30 15:45:47 lha Exp $");
+#endif
+#include "roken.h"
+
+#ifdef __osf__
+/* hate */
+struct rtentry;
+struct mbuf;
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif /* HAVE_SYS_SOCKIO_H */
+
+#ifdef HAVE_NETINET_IN6_VAR_H
+#include <netinet/in6_var.h>
+#endif /* HAVE_NETINET_IN6_VAR_H */
+
+#include <ifaddrs.h>
+
+#ifdef AF_NETLINK
+
+/*
+ * The linux - AF_NETLINK version of getifaddrs - from Usagi.
+ * Linux does not return v6 addresses from SIOCGIFCONF.
+ */
+
+/* $USAGI: ifaddrs.c,v 1.18 2002/03/06 01:50:46 yoshfuji Exp $ */
+
+/**************************************************************************
+ * ifaddrs.c
+ * Copyright (C)2000 Hideaki YOSHIFUJI, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <time.h>
+#include <malloc.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h> /* the L2 protocols */
+#include <sys/uio.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+
+#define __set_errno(e) (errno = (e))
+#define __close(fd) (close(fd))
+#undef ifa_broadaddr
+#define ifa_broadaddr ifa_dstaddr
+#define IFA_NETMASK
+
+/* ====================================================================== */
+struct nlmsg_list{
+ struct nlmsg_list *nlm_next;
+ struct nlmsghdr *nlh;
+ int size;
+ time_t seq;
+};
+
+struct rtmaddr_ifamap {
+ void *address;
+ void *local;
+#ifdef IFA_NETMASK
+ void *netmask;
+#endif
+ void *broadcast;
+#ifdef HAVE_IFADDRS_IFA_ANYCAST
+ void *anycast;
+#endif
+ int address_len;
+ int local_len;
+#ifdef IFA_NETMASK
+ int netmask_len;
+#endif
+ int broadcast_len;
+#ifdef HAVE_IFADDRS_IFA_ANYCAST
+ int anycast_len;
+#endif
+};
+
+/* ====================================================================== */
+static size_t
+ifa_sa_len(sa_family_t family, int len)
+{
+ size_t size;
+ switch(family){
+ case AF_INET:
+ size = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ size = sizeof(struct sockaddr_in6);
+ break;
+ case AF_PACKET:
+ size = (size_t)(((struct sockaddr_ll *)NULL)->sll_addr) + len;
+ if (size < sizeof(struct sockaddr_ll))
+ size = sizeof(struct sockaddr_ll);
+ break;
+ default:
+ size = (size_t)(((struct sockaddr *)NULL)->sa_data) + len;
+ if (size < sizeof(struct sockaddr))
+ size = sizeof(struct sockaddr);
+ break;
+ }
+ return size;
+}
+
+static void
+ifa_make_sockaddr(sa_family_t family,
+ struct sockaddr *sa,
+ void *p, size_t len,
+ uint32_t scope, uint32_t scopeid)
+{
+ if (sa == NULL) return;
+ switch(family){
+ case AF_INET:
+ memcpy(&((struct sockaddr_in*)sa)->sin_addr, (char *)p, len);
+ break;
+ case AF_INET6:
+ memcpy(&((struct sockaddr_in6*)sa)->sin6_addr, (char *)p, len);
+ if (IN6_IS_ADDR_LINKLOCAL(p) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(p)){
+ ((struct sockaddr_in6*)sa)->sin6_scope_id = scopeid;
+ }
+ break;
+ case AF_PACKET:
+ memcpy(((struct sockaddr_ll*)sa)->sll_addr, (char *)p, len);
+ ((struct sockaddr_ll*)sa)->sll_halen = len;
+ break;
+ default:
+ memcpy(sa->sa_data, p, len); /*XXX*/
+ break;
+ }
+ sa->sa_family = family;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sa->sa_len = ifa_sa_len(family, len);
+#endif
+}
+
+#ifndef IFA_NETMASK
+static struct sockaddr *
+ifa_make_sockaddr_mask(sa_family_t family,
+ struct sockaddr *sa,
+ uint32_t prefixlen)
+{
+ int i;
+ char *p = NULL, c;
+ uint32_t max_prefixlen = 0;
+
+ if (sa == NULL) return NULL;
+ switch(family){
+ case AF_INET:
+ memset(&((struct sockaddr_in*)sa)->sin_addr, 0, sizeof(((struct sockaddr_in*)sa)->sin_addr));
+ p = (char *)&((struct sockaddr_in*)sa)->sin_addr;
+ max_prefixlen = 32;
+ break;
+ case AF_INET6:
+ memset(&((struct sockaddr_in6*)sa)->sin6_addr, 0, sizeof(((struct sockaddr_in6*)sa)->sin6_addr));
+ p = (char *)&((struct sockaddr_in6*)sa)->sin6_addr;
+#if 0 /* XXX: fill scope-id? */
+ if (IN6_IS_ADDR_LINKLOCAL(p) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(p)){
+ ((struct sockaddr_in6*)sa)->sin6_scope_id = scopeid;
+ }
+#endif
+ max_prefixlen = 128;
+ break;
+ default:
+ return NULL;
+ }
+ sa->sa_family = family;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sa->sa_len = ifa_sa_len(family, len);
+#endif
+ if (p){
+ if (prefixlen > max_prefixlen)
+ prefixlen = max_prefixlen;
+ for (i=0; i<(prefixlen / 8); i++)
+ *p++ = 0xff;
+ c = 0xff;
+ c <<= (8 - (prefixlen % 8));
+ *p = c;
+ }
+ return sa;
+}
+#endif
+
+/* ====================================================================== */
+static int
+nl_sendreq(int sd, int request, int flags, int *seq)
+{
+ char reqbuf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+ NLMSG_ALIGN(sizeof(struct rtgenmsg))];
+ struct sockaddr_nl nladdr;
+ struct nlmsghdr *req_hdr;
+ struct rtgenmsg *req_msg;
+ time_t t = time(NULL);
+
+ if (seq) *seq = t;
+ memset(&reqbuf, 0, sizeof(reqbuf));
+ req_hdr = (struct nlmsghdr *)reqbuf;
+ req_msg = (struct rtgenmsg *)NLMSG_DATA(req_hdr);
+ req_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*req_msg));
+ req_hdr->nlmsg_type = request;
+ req_hdr->nlmsg_flags = flags | NLM_F_REQUEST;
+ req_hdr->nlmsg_pid = 0;
+ req_hdr->nlmsg_seq = t;
+ req_msg->rtgen_family = AF_UNSPEC;
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ return (sendto(sd, (void *)req_hdr, req_hdr->nlmsg_len, 0,
+ (struct sockaddr *)&nladdr, sizeof(nladdr)));
+}
+
+static int
+nl_recvmsg(int sd, int request, int seq,
+ void *buf, size_t buflen,
+ int *flags)
+{
+ struct msghdr msg;
+ struct iovec iov = { buf, buflen };
+ struct sockaddr_nl nladdr;
+ int read_len;
+
+ for (;;){
+ msg.msg_name = (void *)&nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ read_len = recvmsg(sd, &msg, 0);
+ if ((read_len < 0 && errno == EINTR) || (msg.msg_flags & MSG_TRUNC))
+ continue;
+ if (flags) *flags = msg.msg_flags;
+ break;
+ }
+ return read_len;
+}
+
+static int
+nl_getmsg(int sd, int request, int seq,
+ struct nlmsghdr **nlhp,
+ int *done)
+{
+ struct nlmsghdr *nh;
+ size_t bufsize = 65536, lastbufsize = 0;
+ void *buff = NULL;
+ int result = 0, read_size;
+ int msg_flags;
+ pid_t pid = getpid();
+ for (;;){
+ void *newbuff = realloc(buff, bufsize);
+ if (newbuff == NULL || bufsize < lastbufsize) {
+ result = -1;
+ break;
+ }
+ buff = newbuff;
+ result = read_size = nl_recvmsg(sd, request, seq, buff, bufsize, &msg_flags);
+ if (read_size < 0 || (msg_flags & MSG_TRUNC)){
+ lastbufsize = bufsize;
+ bufsize *= 2;
+ continue;
+ }
+ if (read_size == 0) break;
+ nh = (struct nlmsghdr *)buff;
+ for (nh = (struct nlmsghdr *)buff;
+ NLMSG_OK(nh, read_size);
+ nh = (struct nlmsghdr *)NLMSG_NEXT(nh, read_size)){
+ if (nh->nlmsg_pid != pid ||
+ nh->nlmsg_seq != seq)
+ continue;
+ if (nh->nlmsg_type == NLMSG_DONE){
+ (*done)++;
+ break; /* ok */
+ }
+ if (nh->nlmsg_type == NLMSG_ERROR){
+ struct nlmsgerr *nlerr = (struct nlmsgerr *)NLMSG_DATA(nh);
+ result = -1;
+ if (nh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
+ __set_errno(EIO);
+ else
+ __set_errno(-nlerr->error);
+ break;
+ }
+ }
+ break;
+ }
+ if (result < 0)
+ if (buff){
+ int saved_errno = errno;
+ free(buff);
+ __set_errno(saved_errno);
+ }
+ *nlhp = (struct nlmsghdr *)buff;
+ return result;
+}
+
+static int
+nl_getlist(int sd, int seq,
+ int request,
+ struct nlmsg_list **nlm_list,
+ struct nlmsg_list **nlm_end)
+{
+ struct nlmsghdr *nlh = NULL;
+ int status;
+ int done = 0;
+
+ status = nl_sendreq(sd, request, NLM_F_ROOT|NLM_F_MATCH, &seq);
+ if (status < 0)
+ return status;
+ if (seq == 0)
+ seq = (int)time(NULL);
+ while(!done){
+ status = nl_getmsg(sd, request, seq, &nlh, &done);
+ if (status < 0)
+ return status;
+ if (nlh){
+ struct nlmsg_list *nlm_next = (struct nlmsg_list *)malloc(sizeof(struct nlmsg_list));
+ if (nlm_next == NULL){
+ int saved_errno = errno;
+ free(nlh);
+ __set_errno(saved_errno);
+ status = -1;
+ } else {
+ nlm_next->nlm_next = NULL;
+ nlm_next->nlh = (struct nlmsghdr *)nlh;
+ nlm_next->size = status;
+ nlm_next->seq = seq;
+ if (*nlm_list == NULL){
+ *nlm_list = nlm_next;
+ *nlm_end = nlm_next;
+ } else {
+ (*nlm_end)->nlm_next = nlm_next;
+ *nlm_end = nlm_next;
+ }
+ }
+ }
+ }
+ return status >= 0 ? seq : status;
+}
+
+/* ---------------------------------------------------------------------- */
+static void
+free_nlmsglist(struct nlmsg_list *nlm0)
+{
+ struct nlmsg_list *nlm;
+ int saved_errno;
+ if (!nlm0)
+ return;
+ saved_errno = errno;
+ for (nlm=nlm0; nlm; nlm=nlm->nlm_next){
+ if (nlm->nlh)
+ free(nlm->nlh);
+ }
+ free(nlm0);
+ __set_errno(saved_errno);
+}
+
+static void
+free_data(void *data, void *ifdata)
+{
+ int saved_errno = errno;
+ if (data != NULL) free(data);
+ if (ifdata != NULL) free(ifdata);
+ __set_errno(saved_errno);
+}
+
+/* ---------------------------------------------------------------------- */
+static void
+nl_close(int sd)
+{
+ int saved_errno = errno;
+ if (sd >= 0) __close(sd);
+ __set_errno(saved_errno);
+}
+
+/* ---------------------------------------------------------------------- */
+static int
+nl_open(void)
+{
+ struct sockaddr_nl nladdr;
+ int sd;
+
+ sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (sd < 0) return -1;
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ if (bind(sd, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0){
+ nl_close(sd);
+ return -1;
+ }
+ return sd;
+}
+
+/* ====================================================================== */
+int ROKEN_LIB_FUNCTION
+getifaddrs(struct ifaddrs **ifap)
+{
+ int sd;
+ struct nlmsg_list *nlmsg_list, *nlmsg_end, *nlm;
+ /* - - - - - - - - - - - - - - - */
+ int icnt;
+ size_t dlen, xlen, nlen;
+ uint32_t max_ifindex = 0;
+
+ pid_t pid = getpid();
+ int seq;
+ int result;
+ int build ; /* 0 or 1 */
+
+/* ---------------------------------- */
+ /* initialize */
+ icnt = dlen = xlen = nlen = 0;
+ nlmsg_list = nlmsg_end = NULL;
+
+ if (ifap)
+ *ifap = NULL;
+
+/* ---------------------------------- */
+ /* open socket and bind */
+ sd = nl_open();
+ if (sd < 0)
+ return -1;
+
+/* ---------------------------------- */
+ /* gather info */
+ if ((seq = nl_getlist(sd, 0, RTM_GETLINK,
+ &nlmsg_list, &nlmsg_end)) < 0){
+ free_nlmsglist(nlmsg_list);
+ nl_close(sd);
+ return -1;
+ }
+ if ((seq = nl_getlist(sd, seq+1, RTM_GETADDR,
+ &nlmsg_list, &nlmsg_end)) < 0){
+ free_nlmsglist(nlmsg_list);
+ nl_close(sd);
+ return -1;
+ }
+
+/* ---------------------------------- */
+ /* Estimate size of result buffer and fill it */
+ for (build=0; build<=1; build++){
+ struct ifaddrs *ifl = NULL, *ifa = NULL;
+ struct nlmsghdr *nlh, *nlh0;
+ char *data = NULL, *xdata = NULL;
+ void *ifdata = NULL;
+ char *ifname = NULL, **iflist = NULL;
+ uint16_t *ifflist = NULL;
+ struct rtmaddr_ifamap ifamap;
+
+ if (build){
+ data = calloc(1,
+ NLMSG_ALIGN(sizeof(struct ifaddrs[icnt]))
+ + dlen + xlen + nlen);
+ ifa = (struct ifaddrs *)data;
+ ifdata = calloc(1,
+ NLMSG_ALIGN(sizeof(char *[max_ifindex+1]))
+ + NLMSG_ALIGN(sizeof(uint16_t [max_ifindex+1])));
+ if (ifap != NULL)
+ *ifap = (ifdata != NULL) ? ifa : NULL;
+ else{
+ free_data(data, ifdata);
+ result = 0;
+ break;
+ }
+ if (data == NULL || ifdata == NULL){
+ free_data(data, ifdata);
+ result = -1;
+ break;
+ }
+ ifl = NULL;
+ data += NLMSG_ALIGN(sizeof(struct ifaddrs)) * icnt;
+ xdata = data + dlen;
+ ifname = xdata + xlen;
+ iflist = ifdata;
+ ifflist = (uint16_t *)(((char *)iflist) + NLMSG_ALIGN(sizeof(char *[max_ifindex+1])));
+ }
+
+ for (nlm=nlmsg_list; nlm; nlm=nlm->nlm_next){
+ int nlmlen = nlm->size;
+ if (!(nlh0 = nlm->nlh))
+ continue;
+ for (nlh = nlh0;
+ NLMSG_OK(nlh, nlmlen);
+ nlh=NLMSG_NEXT(nlh,nlmlen)){
+ struct ifinfomsg *ifim = NULL;
+ struct ifaddrmsg *ifam = NULL;
+ struct rtattr *rta;
+
+ size_t nlm_struct_size = 0;
+ sa_family_t nlm_family = 0;
+ uint32_t nlm_scope = 0, nlm_index = 0;
+ size_t sockaddr_size = 0;
+ uint32_t nlm_prefixlen = 0;
+ size_t rtasize;
+
+ memset(&ifamap, 0, sizeof(ifamap));
+
+ /* check if the message is what we want */
+ if (nlh->nlmsg_pid != pid ||
+ nlh->nlmsg_seq != nlm->seq)
+ continue;
+ if (nlh->nlmsg_type == NLMSG_DONE){
+ break; /* ok */
+ }
+ switch (nlh->nlmsg_type){
+ case RTM_NEWLINK:
+ ifim = (struct ifinfomsg *)NLMSG_DATA(nlh);
+ nlm_struct_size = sizeof(*ifim);
+ nlm_family = ifim->ifi_family;
+ nlm_scope = 0;
+ nlm_index = ifim->ifi_index;
+ nlm_prefixlen = 0;
+ if (build)
+ ifflist[nlm_index] = ifa->ifa_flags = ifim->ifi_flags;
+ break;
+ case RTM_NEWADDR:
+ ifam = (struct ifaddrmsg *)NLMSG_DATA(nlh);
+ nlm_struct_size = sizeof(*ifam);
+ nlm_family = ifam->ifa_family;
+ nlm_scope = ifam->ifa_scope;
+ nlm_index = ifam->ifa_index;
+ nlm_prefixlen = ifam->ifa_prefixlen;
+ if (build)
+ ifa->ifa_flags = ifflist[nlm_index];
+ break;
+ default:
+ continue;
+ }
+
+ if (!build){
+ if (max_ifindex < nlm_index)
+ max_ifindex = nlm_index;
+ } else {
+ if (ifl != NULL)
+ ifl->ifa_next = ifa;
+ }
+
+ rtasize = NLMSG_PAYLOAD(nlh, nlmlen) - NLMSG_ALIGN(nlm_struct_size);
+ for (rta = (struct rtattr *)(((char *)NLMSG_DATA(nlh)) + NLMSG_ALIGN(nlm_struct_size));
+ RTA_OK(rta, rtasize);
+ rta = RTA_NEXT(rta, rtasize)){
+ struct sockaddr **sap = NULL;
+ void *rtadata = RTA_DATA(rta);
+ size_t rtapayload = RTA_PAYLOAD(rta);
+ socklen_t sa_len;
+
+ switch(nlh->nlmsg_type){
+ case RTM_NEWLINK:
+ switch(rta->rta_type){
+ case IFLA_ADDRESS:
+ case IFLA_BROADCAST:
+ if (build){
+ sap = (rta->rta_type == IFLA_ADDRESS) ? &ifa->ifa_addr : &ifa->ifa_broadaddr;
+ *sap = (struct sockaddr *)data;
+ }
+ sa_len = ifa_sa_len(AF_PACKET, rtapayload);
+ if (rta->rta_type == IFLA_ADDRESS)
+ sockaddr_size = NLMSG_ALIGN(sa_len);
+ if (!build){
+ dlen += NLMSG_ALIGN(sa_len);
+ } else {
+ memset(*sap, 0, sa_len);
+ ifa_make_sockaddr(AF_PACKET, *sap, rtadata,rtapayload, 0,0);
+ ((struct sockaddr_ll *)*sap)->sll_ifindex = nlm_index;
+ ((struct sockaddr_ll *)*sap)->sll_hatype = ifim->ifi_type;
+ data += NLMSG_ALIGN(sa_len);
+ }
+ break;
+ case IFLA_IFNAME:/* Name of Interface */
+ if (!build)
+ nlen += NLMSG_ALIGN(rtapayload + 1);
+ else{
+ ifa->ifa_name = ifname;
+ if (iflist[nlm_index] == NULL)
+ iflist[nlm_index] = ifa->ifa_name;
+ strncpy(ifa->ifa_name, rtadata, rtapayload);
+ ifa->ifa_name[rtapayload] = '\0';
+ ifname += NLMSG_ALIGN(rtapayload + 1);
+ }
+ break;
+ case IFLA_STATS:/* Statistics of Interface */
+ if (!build)
+ xlen += NLMSG_ALIGN(rtapayload);
+ else{
+ ifa->ifa_data = xdata;
+ memcpy(ifa->ifa_data, rtadata, rtapayload);
+ xdata += NLMSG_ALIGN(rtapayload);
+ }
+ break;
+ case IFLA_UNSPEC:
+ break;
+ case IFLA_MTU:
+ break;
+ case IFLA_LINK:
+ break;
+ case IFLA_QDISC:
+ break;
+ default:
+ break;
+ }
+ break;
+ case RTM_NEWADDR:
+ if (nlm_family == AF_PACKET) break;
+ switch(rta->rta_type){
+ case IFA_ADDRESS:
+ ifamap.address = rtadata;
+ ifamap.address_len = rtapayload;
+ break;
+ case IFA_LOCAL:
+ ifamap.local = rtadata;
+ ifamap.local_len = rtapayload;
+ break;
+ case IFA_BROADCAST:
+ ifamap.broadcast = rtadata;
+ ifamap.broadcast_len = rtapayload;
+ break;
+#ifdef HAVE_IFADDRS_IFA_ANYCAST
+ case IFA_ANYCAST:
+ ifamap.anycast = rtadata;
+ ifamap.anycast_len = rtapayload;
+ break;
+#endif
+ case IFA_LABEL:
+ if (!build)
+ nlen += NLMSG_ALIGN(rtapayload + 1);
+ else{
+ ifa->ifa_name = ifname;
+ if (iflist[nlm_index] == NULL)
+ iflist[nlm_index] = ifname;
+ strncpy(ifa->ifa_name, rtadata, rtapayload);
+ ifa->ifa_name[rtapayload] = '\0';
+ ifname += NLMSG_ALIGN(rtapayload + 1);
+ }
+ break;
+ case IFA_UNSPEC:
+ break;
+ case IFA_CACHEINFO:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (nlh->nlmsg_type == RTM_NEWADDR &&
+ nlm_family != AF_PACKET) {
+ if (!ifamap.local) {
+ ifamap.local = ifamap.address;
+ ifamap.local_len = ifamap.address_len;
+ }
+ if (!ifamap.address) {
+ ifamap.address = ifamap.local;
+ ifamap.address_len = ifamap.local_len;
+ }
+ if (ifamap.address_len != ifamap.local_len ||
+ (ifamap.address != NULL &&
+ memcmp(ifamap.address, ifamap.local, ifamap.address_len))) {
+ /* p2p; address is peer and local is ours */
+ ifamap.broadcast = ifamap.address;
+ ifamap.broadcast_len = ifamap.address_len;
+ ifamap.address = ifamap.local;
+ ifamap.address_len = ifamap.local_len;
+ }
+ if (ifamap.address) {
+#ifndef IFA_NETMASK
+ sockaddr_size = NLMSG_ALIGN(ifa_sa_len(nlm_family,ifamap.address_len));
+#endif
+ if (!build)
+ dlen += NLMSG_ALIGN(ifa_sa_len(nlm_family,ifamap.address_len));
+ else {
+ ifa->ifa_addr = (struct sockaddr *)data;
+ ifa_make_sockaddr(nlm_family, ifa->ifa_addr, ifamap.address, ifamap.address_len,
+ nlm_scope, nlm_index);
+ data += NLMSG_ALIGN(ifa_sa_len(nlm_family, ifamap.address_len));
+ }
+ }
+#ifdef IFA_NETMASK
+ if (ifamap.netmask) {
+ if (!build)
+ dlen += NLMSG_ALIGN(ifa_sa_len(nlm_family,ifamap.netmask_len));
+ else {
+ ifa->ifa_netmask = (struct sockaddr *)data;
+ ifa_make_sockaddr(nlm_family, ifa->ifa_netmask, ifamap.netmask, ifamap.netmask_len,
+ nlm_scope, nlm_index);
+ data += NLMSG_ALIGN(ifa_sa_len(nlm_family, ifamap.netmask_len));
+ }
+ }
+#endif
+ if (ifamap.broadcast) {
+ if (!build)
+ dlen += NLMSG_ALIGN(ifa_sa_len(nlm_family,ifamap.broadcast_len));
+ else {
+ ifa->ifa_broadaddr = (struct sockaddr *)data;
+ ifa_make_sockaddr(nlm_family, ifa->ifa_broadaddr, ifamap.broadcast, ifamap.broadcast_len,
+ nlm_scope, nlm_index);
+ data += NLMSG_ALIGN(ifa_sa_len(nlm_family, ifamap.broadcast_len));
+ }
+ }
+#ifdef HAVE_IFADDRS_IFA_ANYCAST
+ if (ifamap.anycast) {
+ if (!build)
+ dlen += NLMSG_ALIGN(ifa_sa_len(nlm_family,ifamap.anycast_len));
+ else {
+ ifa->ifa_anycast = (struct sockaddr *)data;
+ ifa_make_sockaddr(nlm_family, ifa->ifa_anyaddr, ifamap.anycast, ifamap.anycast_len,
+ nlm_scope, nlm_index);
+ data += NLMSG_ALIGN(ifa_sa_len(nlm_family, ifamap.anycast_len));
+ }
+ }
+#endif
+ }
+ if (!build){
+#ifndef IFA_NETMASK
+ dlen += sockaddr_size;
+#endif
+ icnt++;
+ } else {
+ if (ifa->ifa_name == NULL)
+ ifa->ifa_name = iflist[nlm_index];
+#ifndef IFA_NETMASK
+ if (ifa->ifa_addr &&
+ ifa->ifa_addr->sa_family != AF_UNSPEC &&
+ ifa->ifa_addr->sa_family != AF_PACKET){
+ ifa->ifa_netmask = (struct sockaddr *)data;
+ ifa_make_sockaddr_mask(ifa->ifa_addr->sa_family, ifa->ifa_netmask, nlm_prefixlen);
+ }
+ data += sockaddr_size;
+#endif
+ ifl = ifa++;
+ }
+ }
+ }
+ if (!build){
+ if (icnt == 0 && (dlen + nlen + xlen == 0)){
+ if (ifap != NULL)
+ *ifap = NULL;
+ break; /* cannot found any addresses */
+ }
+ }
+ else
+ free_data(NULL, ifdata);
+ }
+
+/* ---------------------------------- */
+ /* Finalize */
+ free_nlmsglist(nlmsg_list);
+ nl_close(sd);
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+void ROKEN_LIB_FUNCTION
+freeifaddrs(struct ifaddrs *ifa)
+{
+ free(ifa);
+}
+
+
+#else /* !AF_NETLINK */
+
+/*
+ * The generic SIOCGIFCONF version.
+ */
+
+static int
+getifaddrs2(struct ifaddrs **ifap,
+ int af, int siocgifconf, int siocgifflags,
+ size_t ifreq_sz)
+{
+ int ret;
+ int fd;
+ size_t buf_size;
+ char *buf;
+ struct ifconf ifconf;
+ char *p;
+ size_t sz;
+ struct sockaddr sa_zero;
+ struct ifreq *ifr;
+ struct ifaddrs *start = NULL, **end = &start;
+
+ buf = NULL;
+
+ memset (&sa_zero, 0, sizeof(sa_zero));
+ fd = socket(af, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return -1;
+
+ buf_size = 8192;
+ for (;;) {
+ buf = calloc(1, buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ ifconf.ifc_len = buf_size;
+ ifconf.ifc_buf = buf;
+
+ /*
+ * Solaris returns EINVAL when the buffer is too small.
+ */
+ if (ioctl (fd, siocgifconf, &ifconf) < 0 && errno != EINVAL) {
+ ret = errno;
+ goto error_out;
+ }
+ /*
+ * Can the difference between a full and a overfull buf
+ * be determined?
+ */
+
+ if (ifconf.ifc_len < buf_size)
+ break;
+ free (buf);
+ buf_size *= 2;
+ }
+
+ for (p = ifconf.ifc_buf;
+ p < ifconf.ifc_buf + ifconf.ifc_len;
+ p += sz) {
+ struct ifreq ifreq;
+ struct sockaddr *sa;
+ size_t salen;
+
+ ifr = (struct ifreq *)p;
+ sa = &ifr->ifr_addr;
+
+ sz = ifreq_sz;
+ salen = sizeof(struct sockaddr);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ salen = sa->sa_len;
+ sz = max(sz, sizeof(ifr->ifr_name) + sa->sa_len);
+#endif
+#ifdef SA_LEN
+ salen = SA_LEN(sa);
+ sz = max(sz, sizeof(ifr->ifr_name) + SA_LEN(sa));
+#endif
+ memset (&ifreq, 0, sizeof(ifreq));
+ memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
+
+ if (ioctl(fd, siocgifflags, &ifreq) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+
+ *end = malloc(sizeof(**end));
+ if (*end == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+
+ (*end)->ifa_next = NULL;
+ (*end)->ifa_name = strdup(ifr->ifr_name);
+ (*end)->ifa_flags = ifreq.ifr_flags;
+ (*end)->ifa_addr = malloc(salen);
+ memcpy((*end)->ifa_addr, sa, salen);
+ (*end)->ifa_netmask = NULL;
+
+#if 0
+ /* fix these when we actually need them */
+ if(ifreq.ifr_flags & IFF_BROADCAST) {
+ (*end)->ifa_broadaddr = malloc(sizeof(ifr->ifr_broadaddr));
+ memcpy((*end)->ifa_broadaddr, &ifr->ifr_broadaddr,
+ sizeof(ifr->ifr_broadaddr));
+ } else if(ifreq.ifr_flags & IFF_POINTOPOINT) {
+ (*end)->ifa_dstaddr = malloc(sizeof(ifr->ifr_dstaddr));
+ memcpy((*end)->ifa_dstaddr, &ifr->ifr_dstaddr,
+ sizeof(ifr->ifr_dstaddr));
+ } else
+ (*end)->ifa_dstaddr = NULL;
+#else
+ (*end)->ifa_dstaddr = NULL;
+#endif
+
+ (*end)->ifa_data = NULL;
+
+ end = &(*end)->ifa_next;
+
+ }
+ *ifap = start;
+ close(fd);
+ free(buf);
+ return 0;
+ error_out:
+ freeifaddrs(start);
+ close(fd);
+ free(buf);
+ errno = ret;
+ return -1;
+}
+
+#if defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS)
+static int
+getlifaddrs2(struct ifaddrs **ifap,
+ int af, int siocgifconf, int siocgifflags,
+ size_t ifreq_sz)
+{
+ int ret;
+ int fd;
+ size_t buf_size;
+ char *buf;
+ struct lifconf ifconf;
+ char *p;
+ size_t sz;
+ struct sockaddr sa_zero;
+ struct lifreq *ifr;
+ struct ifaddrs *start = NULL, **end = &start;
+
+ buf = NULL;
+
+ memset (&sa_zero, 0, sizeof(sa_zero));
+ fd = socket(af, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return -1;
+
+ buf_size = 8192;
+ for (;;) {
+ buf = calloc(1, buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ ifconf.lifc_family = AF_UNSPEC;
+ ifconf.lifc_flags = 0;
+ ifconf.lifc_len = buf_size;
+ ifconf.lifc_buf = buf;
+
+ /*
+ * Solaris returns EINVAL when the buffer is too small.
+ */
+ if (ioctl (fd, siocgifconf, &ifconf) < 0 && errno != EINVAL) {
+ ret = errno;
+ goto error_out;
+ }
+ /*
+ * Can the difference between a full and a overfull buf
+ * be determined?
+ */
+
+ if (ifconf.lifc_len < buf_size)
+ break;
+ free (buf);
+ buf_size *= 2;
+ }
+
+ for (p = ifconf.lifc_buf;
+ p < ifconf.lifc_buf + ifconf.lifc_len;
+ p += sz) {
+ struct lifreq ifreq;
+ struct sockaddr_storage *sa;
+ size_t salen;
+
+ ifr = (struct lifreq *)p;
+ sa = &ifr->lifr_addr;
+
+ sz = ifreq_sz;
+ salen = sizeof(struct sockaddr_storage);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ salen = sa->sa_len;
+ sz = max(sz, sizeof(ifr->ifr_name) + sa->sa_len);
+#endif
+#ifdef SA_LEN
+ salen = SA_LEN(sa);
+ sz = max(sz, sizeof(ifr->ifr_name) + SA_LEN(sa));
+#endif
+ memset (&ifreq, 0, sizeof(ifreq));
+ memcpy (ifreq.lifr_name, ifr->lifr_name, sizeof(ifr->lifr_name));
+
+ if (ioctl(fd, siocgifflags, &ifreq) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+
+ *end = malloc(sizeof(**end));
+
+ (*end)->ifa_next = NULL;
+ (*end)->ifa_name = strdup(ifr->lifr_name);
+ (*end)->ifa_flags = ifreq.lifr_flags;
+ (*end)->ifa_addr = malloc(salen);
+ memcpy((*end)->ifa_addr, sa, salen);
+ (*end)->ifa_netmask = NULL;
+
+#if 0
+ /* fix these when we actually need them */
+ if(ifreq.ifr_flags & IFF_BROADCAST) {
+ (*end)->ifa_broadaddr = malloc(sizeof(ifr->ifr_broadaddr));
+ memcpy((*end)->ifa_broadaddr, &ifr->ifr_broadaddr,
+ sizeof(ifr->ifr_broadaddr));
+ } else if(ifreq.ifr_flags & IFF_POINTOPOINT) {
+ (*end)->ifa_dstaddr = malloc(sizeof(ifr->ifr_dstaddr));
+ memcpy((*end)->ifa_dstaddr, &ifr->ifr_dstaddr,
+ sizeof(ifr->ifr_dstaddr));
+ } else
+ (*end)->ifa_dstaddr = NULL;
+#else
+ (*end)->ifa_dstaddr = NULL;
+#endif
+
+ (*end)->ifa_data = NULL;
+
+ end = &(*end)->ifa_next;
+
+ }
+ *ifap = start;
+ close(fd);
+ free(buf);
+ return 0;
+ error_out:
+ freeifaddrs(start);
+ close(fd);
+ free(buf);
+ errno = ret;
+ return -1;
+}
+#endif /* defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS) */
+
+int ROKEN_LIB_FUNCTION
+getifaddrs(struct ifaddrs **ifap)
+{
+ int ret = -1;
+ errno = ENXIO;
+#if defined(AF_INET6) && defined(SIOCGIF6CONF) && defined(SIOCGIF6FLAGS)
+ if (ret)
+ ret = getifaddrs2 (ifap, AF_INET6, SIOCGIF6CONF, SIOCGIF6FLAGS,
+ sizeof(struct in6_ifreq));
+#endif
+#if defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS)
+ if (ret)
+ ret = getlifaddrs2 (ifap, AF_INET6, SIOCGLIFCONF, SIOCGLIFFLAGS,
+ sizeof(struct lifreq));
+#endif
+#if defined(HAVE_IPV6) && defined(SIOCGIFCONF)
+ if (ret)
+ ret = getifaddrs2 (ifap, AF_INET6, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+#endif
+#if defined(AF_INET) && defined(SIOCGIFCONF) && defined(SIOCGIFFLAGS)
+ if (ret)
+ ret = getifaddrs2 (ifap, AF_INET, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+#endif
+ return ret;
+}
+
+void ROKEN_LIB_FUNCTION
+freeifaddrs(struct ifaddrs *ifp)
+{
+ struct ifaddrs *p, *q;
+
+ for(p = ifp; p; ) {
+ free(p->ifa_name);
+ if(p->ifa_addr)
+ free(p->ifa_addr);
+ if(p->ifa_dstaddr)
+ free(p->ifa_dstaddr);
+ if(p->ifa_netmask)
+ free(p->ifa_netmask);
+ if(p->ifa_data)
+ free(p->ifa_data);
+ q = p;
+ p = p->ifa_next;
+ free(q);
+ }
+}
+
+#endif /* !AF_NETLINK */
+
+#ifdef TEST
+
+void
+print_addr(const char *s, struct sockaddr *sa)
+{
+ int i;
+ printf(" %s=%d/", s, sa->sa_family);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ for(i = 0; i < sa->sa_len - ((long)sa->sa_data - (long)&sa->sa_family); i++)
+ printf("%02x", ((unsigned char*)sa->sa_data)[i]);
+#else
+ for(i = 0; i < sizeof(sa->sa_data); i++)
+ printf("%02x", ((unsigned char*)sa->sa_data)[i]);
+#endif
+ printf("\n");
+}
+
+void
+print_ifaddrs(struct ifaddrs *x)
+{
+ struct ifaddrs *p;
+
+ for(p = x; p; p = p->ifa_next) {
+ printf("%s\n", p->ifa_name);
+ printf(" flags=%x\n", p->ifa_flags);
+ if(p->ifa_addr)
+ print_addr("addr", p->ifa_addr);
+ if(p->ifa_dstaddr)
+ print_addr("dstaddr", p->ifa_dstaddr);
+ if(p->ifa_netmask)
+ print_addr("netmask", p->ifa_netmask);
+ printf(" %p\n", p->ifa_data);
+ }
+}
+
+int
+main()
+{
+ struct ifaddrs *a = NULL, *b;
+ getifaddrs2(&a, AF_INET, SIOCGIFCONF, SIOCGIFFLAGS, sizeof(struct ifreq));
+ print_ifaddrs(a);
+ printf("---\n");
+ getifaddrs(&b);
+ print_ifaddrs(b);
+ return 0;
+}
+#endif
diff --git a/source4/heimdal/lib/roken/getprogname.c b/source4/heimdal/lib/roken/getprogname.c
new file mode 100644
index 0000000000..f8f1e9d4a2
--- /dev/null
+++ b/source4/heimdal/lib/roken/getprogname.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getprogname.c,v 1.3 2005/04/12 11:28:48 lha Exp $");
+#endif
+
+#include "roken.h"
+
+#ifndef HAVE___PROGNAME
+const char *__progname;
+#endif
+
+#ifndef HAVE_GETPROGNAME
+const char * ROKEN_LIB_FUNCTION
+getprogname(void)
+{
+ return __progname;
+}
+#endif /* HAVE_GETPROGNAME */
diff --git a/source4/heimdal/lib/roken/h_errno.c b/source4/heimdal/lib/roken/h_errno.c
new file mode 100644
index 0000000000..c2d4452c32
--- /dev/null
+++ b/source4/heimdal/lib/roken/h_errno.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: h_errno.c,v 1.1 2001/08/08 03:47:23 assar Exp $");
+#endif
+
+#ifndef HAVE_H_ERRNO
+int h_errno = -17; /* Some magic number */
+#endif
diff --git a/source4/heimdal/lib/roken/issuid.c b/source4/heimdal/lib/roken/issuid.c
new file mode 100644
index 0000000000..7ccf615451
--- /dev/null
+++ b/source4/heimdal/lib/roken/issuid.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: issuid.c,v 1.6 2005/05/13 07:42:03 lha Exp $");
+#endif
+
+#include "roken.h"
+
+int ROKEN_LIB_FUNCTION
+issuid(void)
+{
+#if defined(HAVE_ISSETUGID)
+ return issetugid();
+#else /* !HAVE_ISSETUGID */
+
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+ if(getuid() != geteuid())
+ return 1;
+#endif
+#if defined(HAVE_GETGID) && defined(HAVE_GETEGID)
+ if(getgid() != getegid())
+ return 2;
+#endif
+
+ return 0;
+#endif /* HAVE_ISSETUGID */
+}
diff --git a/source4/heimdal/lib/roken/net_read.c b/source4/heimdal/lib/roken/net_read.c
new file mode 100644
index 0000000000..f8d4dd1424
--- /dev/null
+++ b/source4/heimdal/lib/roken/net_read.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: net_read.c,v 1.4 2005/04/12 11:28:57 lha Exp $");
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <roken.h>
+
+/*
+ * Like read but never return partial data.
+ */
+
+ssize_t ROKEN_LIB_FUNCTION
+net_read (int fd, void *buf, size_t nbytes)
+{
+ char *cbuf = (char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+#ifdef WIN32
+ count = recv (fd, cbuf, rem, 0);
+#else
+ count = read (fd, cbuf, rem);
+#endif
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ } else if (count == 0) {
+ return count;
+ }
+ cbuf += count;
+ rem -= count;
+ }
+ return nbytes;
+}
diff --git a/source4/heimdal/lib/roken/net_write.c b/source4/heimdal/lib/roken/net_write.c
new file mode 100644
index 0000000000..83d14f4af9
--- /dev/null
+++ b/source4/heimdal/lib/roken/net_write.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: net_write.c,v 1.5 2005/04/12 11:28:58 lha Exp $");
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <roken.h>
+
+/*
+ * Like write but never return partial data.
+ */
+
+ssize_t ROKEN_LIB_FUNCTION
+net_write (int fd, const void *buf, size_t nbytes)
+{
+ const char *cbuf = (const char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+#ifdef WIN32
+ count = send (fd, cbuf, rem, 0);
+#else
+ count = write (fd, cbuf, rem);
+#endif
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ }
+ cbuf += count;
+ rem -= count;
+ }
+ return nbytes;
+}
diff --git a/source4/heimdal/lib/roken/parse_time.c b/source4/heimdal/lib/roken/parse_time.c
new file mode 100644
index 0000000000..551bee313f
--- /dev/null
+++ b/source4/heimdal/lib/roken/parse_time.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_time.c,v 1.7 2005/04/12 11:28:58 lha Exp $");
+#endif
+
+#include <parse_units.h>
+#include "parse_time.h"
+
+static struct units time_units[] = {
+ {"year", 365 * 24 * 60 * 60},
+ {"month", 30 * 24 * 60 * 60},
+ {"week", 7 * 24 * 60 * 60},
+ {"day", 24 * 60 * 60},
+ {"hour", 60 * 60},
+ {"h", 60 * 60},
+ {"minute", 60},
+ {"m", 60},
+ {"second", 1},
+ {"s", 1},
+ {NULL, 0},
+};
+
+int ROKEN_LIB_FUNCTION
+parse_time (const char *s, const char *def_unit)
+{
+ return parse_units (s, time_units, def_unit);
+}
+
+size_t ROKEN_LIB_FUNCTION
+unparse_time (int t, char *s, size_t len)
+{
+ return unparse_units (t, time_units, s, len);
+}
+
+size_t ROKEN_LIB_FUNCTION
+unparse_time_approx (int t, char *s, size_t len)
+{
+ return unparse_units_approx (t, time_units, s, len);
+}
+
+void ROKEN_LIB_FUNCTION
+print_time_table (FILE *f)
+{
+ print_units_table (time_units, f);
+}
diff --git a/source4/heimdal/lib/roken/parse_time.h b/source4/heimdal/lib/roken/parse_time.h
new file mode 100644
index 0000000000..5c9de87675
--- /dev/null
+++ b/source4/heimdal/lib/roken/parse_time.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: parse_time.h,v 1.5 2005/04/12 11:28:59 lha Exp $ */
+
+#ifndef __PARSE_TIME_H__
+#define __PARSE_TIME_H__
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+int
+parse_time (const char *s, const char *def_unit);
+
+size_t
+unparse_time (int t, char *s, size_t len);
+
+size_t
+unparse_time_approx (int t, char *s, size_t len);
+
+void
+print_time_table (FILE *f);
+
+#endif /* __PARSE_TIME_H__ */
diff --git a/source4/heimdal/lib/roken/parse_units.c b/source4/heimdal/lib/roken/parse_units.c
new file mode 100644
index 0000000000..5b01937aee
--- /dev/null
+++ b/source4/heimdal/lib/roken/parse_units.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_units.c,v 1.18 2005/04/12 11:28:59 lha Exp $");
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <roken.h>
+#include "parse_units.h"
+
+/*
+ * Parse string in `s' according to `units' and return value.
+ * def_unit defines the default unit.
+ */
+
+static int
+parse_something (const char *s, const struct units *units,
+ const char *def_unit,
+ int (*func)(int res, int val, unsigned mult),
+ int init,
+ int accept_no_val_p)
+{
+ const char *p;
+ int res = init;
+ unsigned def_mult = 1;
+
+ if (def_unit != NULL) {
+ const struct units *u;
+
+ for (u = units; u->name; ++u) {
+ if (strcasecmp (u->name, def_unit) == 0) {
+ def_mult = u->mult;
+ break;
+ }
+ }
+ if (u->name == NULL)
+ return -1;
+ }
+
+ p = s;
+ while (*p) {
+ double val;
+ char *next;
+ const struct units *u, *partial_unit;
+ size_t u_len;
+ unsigned partial;
+ int no_val_p = 0;
+
+ while(isspace((unsigned char)*p) || *p == ',')
+ ++p;
+
+ val = strtod (p, &next); /* strtol(p, &next, 0); */
+ if (p == next) {
+ val = 0;
+ if(!accept_no_val_p)
+ return -1;
+ no_val_p = 1;
+ }
+ p = next;
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p == '\0') {
+ res = (*func)(res, val, def_mult);
+ if (res < 0)
+ return res;
+ break;
+ } else if (*p == '+') {
+ ++p;
+ val = 1;
+ } else if (*p == '-') {
+ ++p;
+ val = -1;
+ }
+ if (no_val_p && val == 0)
+ val = 1;
+ u_len = strcspn (p, ", \t");
+ partial = 0;
+ partial_unit = NULL;
+ if (u_len > 1 && p[u_len - 1] == 's')
+ --u_len;
+ for (u = units; u->name; ++u) {
+ if (strncasecmp (p, u->name, u_len) == 0) {
+ if (u_len == strlen (u->name)) {
+ p += u_len;
+ res = (*func)(res, val, u->mult);
+ if (res < 0)
+ return res;
+ break;
+ } else {
+ ++partial;
+ partial_unit = u;
+ }
+ }
+ }
+ if (u->name == NULL) {
+ if (partial == 1) {
+ p += u_len;
+ res = (*func)(res, val, partial_unit->mult);
+ if (res < 0)
+ return res;
+ } else {
+ return -1;
+ }
+ }
+ if (*p == 's')
+ ++p;
+ }
+ return res;
+}
+
+/*
+ * The string consists of a sequence of `n unit'
+ */
+
+static int
+acc_units(int res, int val, unsigned mult)
+{
+ return res + val * mult;
+}
+
+int ROKEN_LIB_FUNCTION
+parse_units (const char *s, const struct units *units,
+ const char *def_unit)
+{
+ return parse_something (s, units, def_unit, acc_units, 0, 0);
+}
+
+/*
+ * The string consists of a sequence of `[+-]flag'. `orig' consists
+ * the original set of flags, those are then modified and returned as
+ * the function value.
+ */
+
+static int
+acc_flags(int res, int val, unsigned mult)
+{
+ if(val == 1)
+ return res | mult;
+ else if(val == -1)
+ return res & ~mult;
+ else if (val == 0)
+ return mult;
+ else
+ return -1;
+}
+
+int ROKEN_LIB_FUNCTION
+parse_flags (const char *s, const struct units *units,
+ int orig)
+{
+ return parse_something (s, units, NULL, acc_flags, orig, 1);
+}
+
+/*
+ * Return a string representation according to `units' of `num' in `s'
+ * with maximum length `len'. The actual length is the function value.
+ */
+
+static int
+unparse_something (int num, const struct units *units, char *s, size_t len,
+ int (*print) (char *, size_t, int, const char *, int),
+ int (*update) (int, unsigned),
+ const char *zero_string)
+{
+ const struct units *u;
+ int ret = 0, tmp;
+
+ if (num == 0)
+ return snprintf (s, len, "%s", zero_string);
+
+ for (u = units; num > 0 && u->name; ++u) {
+ int divisor;
+
+ divisor = num / u->mult;
+ if (divisor) {
+ num = (*update) (num, u->mult);
+ tmp = (*print) (s, len, divisor, u->name, num);
+ if (tmp < 0)
+ return tmp;
+ if (tmp > len) {
+ len = 0;
+ s = NULL;
+ } else {
+ len -= tmp;
+ s += tmp;
+ }
+ ret += tmp;
+ }
+ }
+ return ret;
+}
+
+static int
+print_unit (char *s, size_t len, int divisor, const char *name, int rem)
+{
+ return snprintf (s, len, "%u %s%s%s",
+ divisor, name,
+ divisor == 1 ? "" : "s",
+ rem > 0 ? " " : "");
+}
+
+static int
+update_unit (int in, unsigned mult)
+{
+ return in % mult;
+}
+
+static int
+update_unit_approx (int in, unsigned mult)
+{
+ if (in / mult > 0)
+ return 0;
+ else
+ return update_unit (in, mult);
+}
+
+int ROKEN_LIB_FUNCTION
+unparse_units (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_unit,
+ update_unit,
+ "0");
+}
+
+int ROKEN_LIB_FUNCTION
+unparse_units_approx (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_unit,
+ update_unit_approx,
+ "0");
+}
+
+void ROKEN_LIB_FUNCTION
+print_units_table (const struct units *units, FILE *f)
+{
+ const struct units *u, *u2;
+ unsigned max_sz = 0;
+
+ for (u = units; u->name; ++u) {
+ max_sz = max(max_sz, strlen(u->name));
+ }
+
+ for (u = units; u->name;) {
+ char buf[1024];
+ const struct units *next;
+
+ for (next = u + 1; next->name && next->mult == u->mult; ++next)
+ ;
+
+ if (next->name) {
+ for (u2 = next;
+ u2->name && u->mult % u2->mult != 0;
+ ++u2)
+ ;
+ if (u2->name == NULL)
+ --u2;
+ unparse_units (u->mult, u2, buf, sizeof(buf));
+ fprintf (f, "1 %*s = %s\n", max_sz, u->name, buf);
+ } else {
+ fprintf (f, "1 %s\n", u->name);
+ }
+ u = next;
+ }
+}
+
+static int
+print_flag (char *s, size_t len, int divisor, const char *name, int rem)
+{
+ return snprintf (s, len, "%s%s", name, rem > 0 ? ", " : "");
+}
+
+static int
+update_flag (int in, unsigned mult)
+{
+ return in - mult;
+}
+
+int ROKEN_LIB_FUNCTION
+unparse_flags (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_flag,
+ update_flag,
+ "");
+}
+
+void ROKEN_LIB_FUNCTION
+print_flags_table (const struct units *units, FILE *f)
+{
+ const struct units *u;
+
+ for(u = units; u->name; ++u)
+ fprintf(f, "%s%s", u->name, (u+1)->name ? ", " : "\n");
+}
diff --git a/source4/heimdal/lib/roken/parse_units.h b/source4/heimdal/lib/roken/parse_units.h
new file mode 100644
index 0000000000..9d019266ac
--- /dev/null
+++ b/source4/heimdal/lib/roken/parse_units.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: parse_units.h,v 1.9 2005/04/12 11:28:59 lha Exp $ */
+
+#ifndef __PARSE_UNITS_H__
+#define __PARSE_UNITS_H__
+
+#include <stdio.h>
+#include <stddef.h>
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+struct units {
+ const char *name;
+ unsigned mult;
+};
+
+int ROKEN_LIB_FUNCTION
+parse_units (const char *s, const struct units *units,
+ const char *def_unit);
+
+void ROKEN_LIB_FUNCTION
+print_units_table (const struct units *units, FILE *f);
+
+int ROKEN_LIB_FUNCTION
+parse_flags (const char *s, const struct units *units,
+ int orig);
+
+int ROKEN_LIB_FUNCTION
+unparse_units (int num, const struct units *units, char *s, size_t len);
+
+int ROKEN_LIB_FUNCTION
+unparse_units_approx (int num, const struct units *units, char *s,
+ size_t len);
+
+int ROKEN_LIB_FUNCTION
+unparse_flags (int num, const struct units *units, char *s, size_t len);
+
+void ROKEN_LIB_FUNCTION
+print_flags_table (const struct units *units, FILE *f);
+
+#endif /* __PARSE_UNITS_H__ */
diff --git a/source4/heimdal/lib/roken/print_version.c b/source4/heimdal/lib/roken/print_version.c
new file mode 100644
index 0000000000..9d678056b5
--- /dev/null
+++ b/source4/heimdal/lib/roken/print_version.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: print_version.c,v 1.9 2005/04/12 11:29:00 lha Exp $");
+#endif
+#include "roken.h"
+
+#include "print_version.h"
+
+void ROKEN_LIB_FUNCTION
+print_version(const char *progname)
+{
+ const char *arg[] = VERSIONLIST;
+ const int num_args = sizeof(arg) / sizeof(arg[0]);
+ char *msg;
+ size_t len = 0;
+ int i;
+
+ if(progname == NULL)
+ progname = getprogname();
+
+ if(num_args == 0)
+ msg = "no version information";
+ else {
+ for(i = 0; i < num_args; i++) {
+ if(i > 0)
+ len += 2;
+ len += strlen(arg[i]);
+ }
+ msg = malloc(len + 1);
+ if(msg == NULL) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ return;
+ }
+ msg[0] = '\0';
+ for(i = 0; i < num_args; i++) {
+ if(i > 0)
+ strcat(msg, ", ");
+ strcat(msg, arg[i]);
+ }
+ }
+ fprintf(stderr, "%s (%s)\n", progname, msg);
+ fprintf(stderr, "Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan\n");
+ if(num_args != 0)
+ free(msg);
+}
diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c
new file mode 100644
index 0000000000..46a1e4de71
--- /dev/null
+++ b/source4/heimdal/lib/roken/resolve.c
@@ -0,0 +1,690 @@
+/*
+ * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+#include "resolve.h"
+
+#include <assert.h>
+
+RCSID("$Id: resolve.c,v 1.51 2005/06/16 16:46:16 lha Exp $");
+
+#ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */
+#undef HAVE_RES_NSEARCH
+#endif
+
+#define DECL(X) {#X, rk_ns_t_##X}
+
+static struct stot{
+ const char *name;
+ int type;
+}stot[] = {
+ DECL(a),
+ DECL(aaaa),
+ DECL(ns),
+ DECL(cname),
+ DECL(soa),
+ DECL(ptr),
+ DECL(mx),
+ DECL(txt),
+ DECL(afsdb),
+ DECL(sig),
+ DECL(key),
+ DECL(srv),
+ DECL(naptr),
+ DECL(sshfp),
+ DECL(ds),
+ {NULL, 0}
+};
+
+int _resolve_debug = 0;
+
+int ROKEN_LIB_FUNCTION
+dns_string_to_type(const char *name)
+{
+ struct stot *p = stot;
+ for(p = stot; p->name; p++)
+ if(strcasecmp(name, p->name) == 0)
+ return p->type;
+ return -1;
+}
+
+const char * ROKEN_LIB_FUNCTION
+dns_type_to_string(int type)
+{
+ struct stot *p = stot;
+ for(p = stot; p->name; p++)
+ if(type == p->type)
+ return p->name;
+ return NULL;
+}
+
+#if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
+
+void ROKEN_LIB_FUNCTION
+dns_free_data(struct dns_reply *r)
+{
+ struct resource_record *rr;
+ if(r->q.domain)
+ free(r->q.domain);
+ for(rr = r->head; rr;){
+ struct resource_record *tmp = rr;
+ if(rr->domain)
+ free(rr->domain);
+ if(rr->u.data)
+ free(rr->u.data);
+ rr = rr->next;
+ free(tmp);
+ }
+ free (r);
+}
+
+static int
+parse_record(const unsigned char *data, const unsigned char *end_data,
+ const unsigned char **pp, struct resource_record **rr)
+{
+ int type, class, ttl, size;
+ int status;
+ char host[MAXDNAME];
+ const unsigned char *p = *pp;
+ status = dn_expand(data, end_data, p, host, sizeof(host));
+ if(status < 0)
+ return -1;
+ if (p + status + 10 > end_data)
+ return -1;
+ p += status;
+ type = (p[0] << 8) | p[1];
+ p += 2;
+ class = (p[0] << 8) | p[1];
+ p += 2;
+ ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p += 4;
+ size = (p[0] << 8) | p[1];
+ p += 2;
+
+ if (p + size > end_data)
+ return -1;
+
+ *rr = calloc(1, sizeof(**rr));
+ if(*rr == NULL)
+ return -1;
+ (*rr)->domain = strdup(host);
+ if((*rr)->domain == NULL) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->type = type;
+ (*rr)->class = class;
+ (*rr)->ttl = ttl;
+ (*rr)->size = size;
+ switch(type){
+ case rk_ns_t_ns:
+ case rk_ns_t_cname:
+ case rk_ns_t_ptr:
+ status = dn_expand(data, end_data, p, host, sizeof(host));
+ if(status < 0) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->u.txt = strdup(host);
+ if((*rr)->u.txt == NULL) {
+ free(*rr);
+ return -1;
+ }
+ break;
+ case rk_ns_t_mx:
+ case rk_ns_t_afsdb:{
+ size_t hostlen;
+
+ status = dn_expand(data, end_data, p + 2, host, sizeof(host));
+ if(status < 0){
+ free(*rr);
+ return -1;
+ }
+ if (status + 2 > size) {
+ free(*rr);
+ return -1;
+ }
+
+ hostlen = strlen(host);
+ (*rr)->u.mx = (struct mx_record*)malloc(sizeof(struct mx_record) +
+ hostlen);
+ if((*rr)->u.mx == NULL) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->u.mx->preference = (p[0] << 8) | p[1];
+ strlcpy((*rr)->u.mx->domain, host, hostlen + 1);
+ break;
+ }
+ case rk_ns_t_srv:{
+ size_t hostlen;
+ status = dn_expand(data, end_data, p + 6, host, sizeof(host));
+ if(status < 0){
+ free(*rr);
+ return -1;
+ }
+ if (status + 6 > size) {
+ free(*rr);
+ return -1;
+ }
+
+ hostlen = strlen(host);
+ (*rr)->u.srv =
+ (struct srv_record*)malloc(sizeof(struct srv_record) +
+ hostlen);
+ if((*rr)->u.srv == NULL) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->u.srv->priority = (p[0] << 8) | p[1];
+ (*rr)->u.srv->weight = (p[2] << 8) | p[3];
+ (*rr)->u.srv->port = (p[4] << 8) | p[5];
+ strlcpy((*rr)->u.srv->target, host, hostlen + 1);
+ break;
+ }
+ case rk_ns_t_txt:{
+ if(size == 0 || size < *p + 1) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->u.txt = (char*)malloc(*p + 1);
+ if((*rr)->u.txt == NULL) {
+ free(*rr);
+ return -1;
+ }
+ strncpy((*rr)->u.txt, (const char*)(p + 1), *p);
+ (*rr)->u.txt[*p] = '\0';
+ break;
+ }
+ case rk_ns_t_key : {
+ size_t key_len;
+
+ if (size < 4) {
+ free(*rr);
+ return -1;
+ }
+
+ key_len = size - 4;
+ (*rr)->u.key = malloc (sizeof(*(*rr)->u.key) + key_len - 1);
+ if ((*rr)->u.key == NULL) {
+ free(*rr);
+ return -1;
+ }
+
+ (*rr)->u.key->flags = (p[0] << 8) | p[1];
+ (*rr)->u.key->protocol = p[2];
+ (*rr)->u.key->algorithm = p[3];
+ (*rr)->u.key->key_len = key_len;
+ memcpy ((*rr)->u.key->key_data, p + 4, key_len);
+ break;
+ }
+ case rk_ns_t_sig : {
+ size_t sig_len, hostlen;
+
+ if(size <= 18) {
+ free(*rr);
+ return -1;
+ }
+ status = dn_expand (data, end_data, p + 18, host, sizeof(host));
+ if (status < 0) {
+ free(*rr);
+ return -1;
+ }
+ if (status + 18 > size) {
+ free(*rr);
+ return -1;
+ }
+
+ /* the signer name is placed after the sig_data, to make it
+ easy to free this struture; the size calculation below
+ includes the zero-termination if the structure itself.
+ don't you just love C?
+ */
+ sig_len = size - 18 - status;
+ hostlen = strlen(host);
+ (*rr)->u.sig = malloc(sizeof(*(*rr)->u.sig)
+ + hostlen + sig_len);
+ if ((*rr)->u.sig == NULL) {
+ free(*rr);
+ return -1;
+ }
+ (*rr)->u.sig->type = (p[0] << 8) | p[1];
+ (*rr)->u.sig->algorithm = p[2];
+ (*rr)->u.sig->labels = p[3];
+ (*rr)->u.sig->orig_ttl = (p[4] << 24) | (p[5] << 16)
+ | (p[6] << 8) | p[7];
+ (*rr)->u.sig->sig_expiration = (p[8] << 24) | (p[9] << 16)
+ | (p[10] << 8) | p[11];
+ (*rr)->u.sig->sig_inception = (p[12] << 24) | (p[13] << 16)
+ | (p[14] << 8) | p[15];
+ (*rr)->u.sig->key_tag = (p[16] << 8) | p[17];
+ (*rr)->u.sig->sig_len = sig_len;
+ memcpy ((*rr)->u.sig->sig_data, p + 18 + status, sig_len);
+ (*rr)->u.sig->signer = &(*rr)->u.sig->sig_data[sig_len];
+ strlcpy((*rr)->u.sig->signer, host, hostlen + 1);
+ break;
+ }
+
+ case rk_ns_t_cert : {
+ size_t cert_len;
+
+ if (size < 5) {
+ free(*rr);
+ return -1;
+ }
+
+ cert_len = size - 5;
+ (*rr)->u.cert = malloc (sizeof(*(*rr)->u.cert) + cert_len - 1);
+ if ((*rr)->u.cert == NULL) {
+ free(*rr);
+ return -1;
+ }
+
+ (*rr)->u.cert->type = (p[0] << 8) | p[1];
+ (*rr)->u.cert->tag = (p[2] << 8) | p[3];
+ (*rr)->u.cert->algorithm = p[4];
+ (*rr)->u.cert->cert_len = cert_len;
+ memcpy ((*rr)->u.cert->cert_data, p + 5, cert_len);
+ break;
+ }
+ case rk_ns_t_sshfp : {
+ size_t sshfp_len;
+
+ if (size < 2) {
+ free(*rr);
+ return -1;
+ }
+
+ sshfp_len = size - 2;
+
+ (*rr)->u.sshfp = malloc (sizeof(*(*rr)->u.sshfp) + sshfp_len - 1);
+ if ((*rr)->u.sshfp == NULL) {
+ free(*rr);
+ return -1;
+ }
+
+ (*rr)->u.sshfp->algorithm = p[0];
+ (*rr)->u.sshfp->type = p[1];
+ (*rr)->u.sshfp->sshfp_len = sshfp_len;
+ memcpy ((*rr)->u.sshfp->sshfp_data, p + 2, sshfp_len);
+ break;
+ }
+ case rk_ns_t_ds: {
+ size_t digest_len;
+
+ if (size < 4) {
+ free(*rr);
+ return -1;
+ }
+
+ digest_len = size - 4;
+
+ (*rr)->u.ds = malloc (sizeof(*(*rr)->u.ds) + digest_len - 1);
+ if ((*rr)->u.ds == NULL) {
+ free(*rr);
+ return -1;
+ }
+
+ (*rr)->u.ds->key_tag = (p[0] << 8) | p[1];
+ (*rr)->u.ds->algorithm = p[2];
+ (*rr)->u.ds->digest_type = p[3];
+ (*rr)->u.ds->digest_len = digest_len;
+ memcpy ((*rr)->u.ds->digest_data, p + 4, digest_len);
+ break;
+ }
+ default:
+ (*rr)->u.data = (unsigned char*)malloc(size);
+ if(size != 0 && (*rr)->u.data == NULL) {
+ free(*rr);
+ return -1;
+ }
+ memcpy((*rr)->u.data, p, size);
+ }
+ *pp = p + size;
+ return 0;
+}
+
+#ifndef TEST_RESOLVE
+static
+#endif
+struct dns_reply*
+parse_reply(const unsigned char *data, size_t len)
+{
+ const unsigned char *p;
+ int status;
+ int i;
+ char host[MAXDNAME];
+ const unsigned char *end_data = data + len;
+ struct dns_reply *r;
+ struct resource_record **rr;
+
+ r = calloc(1, sizeof(*r));
+ if (r == NULL)
+ return NULL;
+
+ p = data;
+
+ r->h.id = (p[0] << 8) | p[1];
+ r->h.flags = 0;
+ if (p[2] & 0x01)
+ r->h.flags |= rk_DNS_HEADER_RESPONSE_FLAG;
+ r->h.opcode = (p[2] >> 1) & 0xf;
+ if (p[2] & 0x20)
+ r->h.flags |= rk_DNS_HEADER_AUTHORITIVE_ANSWER;
+ if (p[2] & 0x40)
+ r->h.flags |= rk_DNS_HEADER_TRUNCATED_MESSAGE;
+ if (p[2] & 0x80)
+ r->h.flags |= rk_DNS_HEADER_RECURSION_DESIRED;
+ if (p[3] & 0x01)
+ r->h.flags |= rk_DNS_HEADER_RECURSION_AVAILABLE;
+ if (p[3] & 0x04)
+ r->h.flags |= rk_DNS_HEADER_AUTHORITIVE_ANSWER;
+ if (p[3] & 0x08)
+ r->h.flags |= rk_DNS_HEADER_CHECKING_DISABLED;
+ r->h.response_code = (p[3] >> 4) & 0xf;
+ r->h.qdcount = (p[4] << 8) | p[5];
+ r->h.ancount = (p[6] << 8) | p[7];
+ r->h.nscount = (p[8] << 8) | p[9];
+ r->h.arcount = (p[10] << 8) | p[11];
+
+ p += 12;
+
+ if(r->h.qdcount != 1) {
+ free(r);
+ return NULL;
+ }
+ status = dn_expand(data, end_data, p, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ r->q.domain = strdup(host);
+ if(r->q.domain == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ if (p + status + 4 > end_data) {
+ dns_free_data(r);
+ return NULL;
+ }
+ p += status;
+ r->q.type = (p[0] << 8 | p[1]);
+ p += 2;
+ r->q.class = (p[0] << 8 | p[1]);
+ p += 2;
+
+ rr = &r->head;
+ for(i = 0; i < r->h.ancount; i++) {
+ if(parse_record(data, end_data, &p, rr) != 0) {
+ dns_free_data(r);
+ return NULL;
+ }
+ rr = &(*rr)->next;
+ }
+ for(i = 0; i < r->h.nscount; i++) {
+ if(parse_record(data, end_data, &p, rr) != 0) {
+ dns_free_data(r);
+ return NULL;
+ }
+ rr = &(*rr)->next;
+ }
+ for(i = 0; i < r->h.arcount; i++) {
+ if(parse_record(data, end_data, &p, rr) != 0) {
+ dns_free_data(r);
+ return NULL;
+ }
+ rr = &(*rr)->next;
+ }
+ *rr = NULL;
+ return r;
+}
+
+static struct dns_reply *
+dns_lookup_int(const char *domain, int rr_class, int rr_type)
+{
+ struct dns_reply *r;
+ unsigned char *reply = NULL;
+ int size;
+ int len;
+#ifdef HAVE_RES_NSEARCH
+ struct __res_state state;
+ memset(&state, 0, sizeof(state));
+ if(res_ninit(&state))
+ return NULL; /* is this the best we can do? */
+#elif defined(HAVE__RES)
+ u_long old_options = 0;
+#endif
+
+ size = 0;
+ len = 1000;
+ do {
+ if (reply) {
+ free(reply);
+ reply = NULL;
+ }
+ if (size <= len)
+ size = len;
+ if (_resolve_debug) {
+#ifdef HAVE_RES_NSEARCH
+ state.options |= RES_DEBUG;
+#elif defined(HAVE__RES)
+ old_options = _res.options;
+ _res.options |= RES_DEBUG;
+#endif
+ fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain,
+ rr_class, dns_type_to_string(rr_type), size);
+ }
+ reply = malloc(size);
+ if (reply == NULL) {
+#ifdef HAVE_RES_NSEARCH
+ res_nclose(&state);
+#endif
+ return NULL;
+ }
+#ifdef HAVE_RES_NSEARCH
+ len = res_nsearch(&state, domain, rr_class, rr_type, reply, size);
+#else
+ len = res_search(domain, rr_class, rr_type, reply, size);
+#endif
+ if (_resolve_debug) {
+#if defined(HAVE__RES) && !defined(HAVE_RES_NSEARCH)
+ _res.options = old_options;
+#endif
+ fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
+ domain, rr_class, dns_type_to_string(rr_type), len);
+ }
+ if (len < 0) {
+#ifdef HAVE_RES_NSEARCH
+ res_nclose(&state);
+#endif
+ free(reply);
+ return NULL;
+ }
+ } while (size < len && len < rk_DNS_MAX_PACKET_SIZE);
+#ifdef HAVE_RES_NSEARCH
+ res_nclose(&state);
+#endif
+
+ len = min(len, size);
+ r = parse_reply(reply, len);
+ free(reply);
+ return r;
+}
+
+struct dns_reply * ROKEN_LIB_FUNCTION
+dns_lookup(const char *domain, const char *type_name)
+{
+ int type;
+
+ type = dns_string_to_type(type_name);
+ if(type == -1) {
+ if(_resolve_debug)
+ fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
+ type_name);
+ return NULL;
+ }
+ return dns_lookup_int(domain, C_IN, type);
+}
+
+static int
+compare_srv(const void *a, const void *b)
+{
+ const struct resource_record *const* aa = a, *const* bb = b;
+
+ if((*aa)->u.srv->priority == (*bb)->u.srv->priority)
+ return ((*aa)->u.srv->weight - (*bb)->u.srv->weight);
+ return ((*aa)->u.srv->priority - (*bb)->u.srv->priority);
+}
+
+#ifndef HAVE_RANDOM
+#define random() rand()
+#endif
+
+/* try to rearrange the srv-records by the algorithm in RFC2782 */
+void ROKEN_LIB_FUNCTION
+dns_srv_order(struct dns_reply *r)
+{
+ struct resource_record **srvs, **ss, **headp;
+ struct resource_record *rr;
+ int num_srv = 0;
+
+#if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
+ int state[256 / sizeof(int)];
+ char *oldstate;
+#endif
+
+ for(rr = r->head; rr; rr = rr->next)
+ if(rr->type == rk_ns_t_srv)
+ num_srv++;
+
+ if(num_srv == 0)
+ return;
+
+ srvs = malloc(num_srv * sizeof(*srvs));
+ if(srvs == NULL)
+ return; /* XXX not much to do here */
+
+ /* unlink all srv-records from the linked list and put them in
+ a vector */
+ for(ss = srvs, headp = &r->head; *headp; )
+ if((*headp)->type == rk_ns_t_srv) {
+ *ss = *headp;
+ *headp = (*headp)->next;
+ (*ss)->next = NULL;
+ ss++;
+ } else
+ headp = &(*headp)->next;
+
+ /* sort them by priority and weight */
+ qsort(srvs, num_srv, sizeof(*srvs), compare_srv);
+
+#if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
+ oldstate = initstate(time(NULL), (char*)state, sizeof(state));
+#endif
+
+ headp = &r->head;
+
+ for(ss = srvs; ss < srvs + num_srv; ) {
+ int sum, rnd, count;
+ struct resource_record **ee, **tt;
+ /* find the last record with the same priority and count the
+ sum of all weights */
+ for(sum = 0, tt = ss; tt < srvs + num_srv; tt++) {
+ if(*tt == NULL)
+ continue;
+ if((*tt)->u.srv->priority != (*ss)->u.srv->priority)
+ break;
+ sum += (*tt)->u.srv->weight;
+ }
+ ee = tt;
+ /* ss is now the first record of this priority and ee is the
+ first of the next */
+ while(ss < ee) {
+ rnd = random() % (sum + 1);
+ for(count = 0, tt = ss; ; tt++) {
+ if(*tt == NULL)
+ continue;
+ count += (*tt)->u.srv->weight;
+ if(count >= rnd)
+ break;
+ }
+
+ assert(tt < ee);
+
+ /* insert the selected record at the tail (of the head) of
+ the list */
+ (*tt)->next = *headp;
+ *headp = *tt;
+ headp = &(*tt)->next;
+ sum -= (*tt)->u.srv->weight;
+ *tt = NULL;
+ while(ss < ee && *ss == NULL)
+ ss++;
+ }
+ }
+
+#if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
+ setstate(oldstate);
+#endif
+ free(srvs);
+ return;
+}
+
+#else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
+
+struct dns_reply * ROKEN_LIB_FUNCTION
+dns_lookup(const char *domain, const char *type_name)
+{
+ return NULL;
+}
+
+void ROKEN_LIB_FUNCTION
+dns_free_data(struct dns_reply *r)
+{
+}
+
+void ROKEN_LIB_FUNCTION
+dns_srv_order(struct dns_reply *r)
+{
+}
+
+#endif
diff --git a/source4/heimdal/lib/roken/resolve.h b/source4/heimdal/lib/roken/resolve.h
new file mode 100644
index 0000000000..2106c11ebd
--- /dev/null
+++ b/source4/heimdal/lib/roken/resolve.h
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: resolve.h,v 1.24 2005/04/12 11:29:02 lha Exp $ */
+
+#ifndef __RESOLVE_H__
+#define __RESOLVE_H__
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+typedef enum {
+ rk_ns_t_invalid = 0, /* Cookie. */
+ rk_ns_t_a = 1, /* Host address. */
+ rk_ns_t_ns = 2, /* Authoritative server. */
+ rk_ns_t_md = 3, /* Mail destination. */
+ rk_ns_t_mf = 4, /* Mail forwarder. */
+ rk_ns_t_cname = 5, /* Canonical name. */
+ rk_ns_t_soa = 6, /* Start of authority zone. */
+ rk_ns_t_mb = 7, /* Mailbox domain name. */
+ rk_ns_t_mg = 8, /* Mail group member. */
+ rk_ns_t_mr = 9, /* Mail rename name. */
+ rk_ns_t_null = 10, /* Null resource record. */
+ rk_ns_t_wks = 11, /* Well known service. */
+ rk_ns_t_ptr = 12, /* Domain name pointer. */
+ rk_ns_t_hinfo = 13, /* Host information. */
+ rk_ns_t_minfo = 14, /* Mailbox information. */
+ rk_ns_t_mx = 15, /* Mail routing information. */
+ rk_ns_t_txt = 16, /* Text strings. */
+ rk_ns_t_rp = 17, /* Responsible person. */
+ rk_ns_t_afsdb = 18, /* AFS cell database. */
+ rk_ns_t_x25 = 19, /* X_25 calling address. */
+ rk_ns_t_isdn = 20, /* ISDN calling address. */
+ rk_ns_t_rt = 21, /* Router. */
+ rk_ns_t_nsap = 22, /* NSAP address. */
+ rk_ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
+ rk_ns_t_sig = 24, /* Security signature. */
+ rk_ns_t_key = 25, /* Security key. */
+ rk_ns_t_px = 26, /* X.400 mail mapping. */
+ rk_ns_t_gpos = 27, /* Geographical position (withdrawn). */
+ rk_ns_t_aaaa = 28, /* Ip6 Address. */
+ rk_ns_t_loc = 29, /* Location Information. */
+ rk_ns_t_nxt = 30, /* Next domain (security). */
+ rk_ns_t_eid = 31, /* Endpoint identifier. */
+ rk_ns_t_nimloc = 32, /* Nimrod Locator. */
+ rk_ns_t_srv = 33, /* Server Selection. */
+ rk_ns_t_atma = 34, /* ATM Address */
+ rk_ns_t_naptr = 35, /* Naming Authority PoinTeR */
+ rk_ns_t_kx = 36, /* Key Exchange */
+ rk_ns_t_cert = 37, /* Certification record */
+ rk_ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
+ rk_ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
+ rk_ns_t_sink = 40, /* Kitchen sink (experimentatl) */
+ rk_ns_t_opt = 41, /* EDNS0 option (meta-RR) */
+ rk_ns_t_apl = 42, /* Address prefix list (RFC 3123) */
+ rk_ns_t_ds = 43, /* Delegation Signer (RFC 3658) */
+ rk_ns_t_sshfp = 44, /* SSH fingerprint */
+ rk_ns_t_tkey = 249, /* Transaction key */
+ rk_ns_t_tsig = 250, /* Transaction signature. */
+ rk_ns_t_ixfr = 251, /* Incremental zone transfer. */
+ rk_ns_t_axfr = 252, /* Transfer zone of authority. */
+ rk_ns_t_mailb = 253, /* Transfer mailbox records. */
+ rk_ns_t_maila = 254, /* Transfer mail agent records. */
+ rk_ns_t_any = 255, /* Wildcard match. */
+ rk_ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
+ rk_ns_t_max = 65536
+} rk_ns_type;
+
+/* We use these, but they are not always present in <arpa/nameser.h> */
+
+#ifndef C_IN
+#define C_IN 1
+#endif
+
+#ifndef T_A
+#define T_A 1
+#endif
+#ifndef T_NS
+#define T_NS 2
+#endif
+#ifndef T_CNAME
+#define T_CNAME 5
+#endif
+#ifndef T_SOA
+#define T_SOA 5
+#endif
+#ifndef T_PTR
+#define T_PTR 12
+#endif
+#ifndef T_MX
+#define T_MX 15
+#endif
+#ifndef T_TXT
+#define T_TXT 16
+#endif
+#ifndef T_AFSDB
+#define T_AFSDB 18
+#endif
+#ifndef T_SIG
+#define T_SIG 24
+#endif
+#ifndef T_KEY
+#define T_KEY 25
+#endif
+#ifndef T_AAAA
+#define T_AAAA 28
+#endif
+#ifndef T_SRV
+#define T_SRV 33
+#endif
+#ifndef T_NAPTR
+#define T_NAPTR 35
+#endif
+#ifndef T_CERT
+#define T_CERT 37
+#endif
+#ifndef T_SSHFP
+#define T_SSHFP 44
+#endif
+
+#ifndef MAXDNAME
+#define MAXDNAME 1025
+#endif
+
+#define dns_query rk_dns_query
+#define mx_record rk_mx_record
+#define srv_record rk_srv_record
+#define key_record rk_key_record
+#define sig_record rk_sig_record
+#define cert_record rk_cert_record
+#define sshfp_record rk_sshfp_record
+#define resource_record rk_resource_record
+#define dns_reply rk_dns_reply
+
+#define dns_lookup rk_dns_lookup
+#define dns_free_data rk_dns_free_data
+#define dns_string_to_type rk_dns_string_to_type
+#define dns_type_to_string rk_dns_type_to_string
+#define dns_srv_order rk_dns_srv_order
+
+struct dns_query{
+ char *domain;
+ unsigned type;
+ unsigned class;
+};
+
+struct mx_record{
+ unsigned preference;
+ char domain[1];
+};
+
+struct srv_record{
+ unsigned priority;
+ unsigned weight;
+ unsigned port;
+ char target[1];
+};
+
+struct key_record {
+ unsigned flags;
+ unsigned protocol;
+ unsigned algorithm;
+ size_t key_len;
+ u_char key_data[1];
+};
+
+struct sig_record {
+ unsigned type;
+ unsigned algorithm;
+ unsigned labels;
+ unsigned orig_ttl;
+ unsigned sig_expiration;
+ unsigned sig_inception;
+ unsigned key_tag;
+ char *signer;
+ unsigned sig_len;
+ char sig_data[1]; /* also includes signer */
+};
+
+struct cert_record {
+ unsigned type;
+ unsigned tag;
+ unsigned algorithm;
+ size_t cert_len;
+ u_char cert_data[1];
+};
+
+struct sshfp_record {
+ unsigned algorithm;
+ unsigned type;
+ size_t sshfp_len;
+ u_char sshfp_data[1];
+};
+
+struct ds_record {
+ unsigned key_tag;
+ unsigned algorithm;
+ unsigned digest_type;
+ unsigned digest_len;
+ u_char digest_data[1];
+};
+
+struct resource_record{
+ char *domain;
+ unsigned type;
+ unsigned class;
+ unsigned ttl;
+ unsigned size;
+ union {
+ void *data;
+ struct mx_record *mx;
+ struct mx_record *afsdb; /* mx and afsdb are identical */
+ struct srv_record *srv;
+ struct in_addr *a;
+ char *txt;
+ struct key_record *key;
+ struct cert_record *cert;
+ struct sig_record *sig;
+ struct sshfp_record *sshfp;
+ struct ds_record *ds;
+ }u;
+ struct resource_record *next;
+};
+
+#define rk_DNS_MAX_PACKET_SIZE 0xffff
+
+struct dns_header {
+ unsigned id;
+ unsigned flags;
+#define rk_DNS_HEADER_RESPONSE_FLAG 1
+#define rk_DNS_HEADER_AUTHORITIVE_ANSWER 2
+#define rk_DNS_HEADER_TRUNCATED_MESSAGE 4
+#define rk_DNS_HEADER_RECURSION_DESIRED 8
+#define rk_DNS_HEADER_RECURSION_AVAILABLE 16
+#define rk_DNS_HEADER_AUTHENTIC_DATA 32
+#define rk_DNS_HEADER_CHECKING_DISABLED 64
+ unsigned opcode;
+ unsigned response_code;
+ unsigned qdcount;
+ unsigned ancount;
+ unsigned nscount;
+ unsigned arcount;
+};
+
+struct dns_reply{
+ struct dns_header h;
+ struct dns_query q;
+ struct resource_record *head;
+};
+
+
+struct dns_reply* ROKEN_LIB_FUNCTION
+ dns_lookup(const char *, const char *);
+void ROKEN_LIB_FUNCTION
+ dns_free_data(struct dns_reply *);
+int ROKEN_LIB_FUNCTION
+ dns_string_to_type(const char *name);
+const char *ROKEN_LIB_FUNCTION
+ dns_type_to_string(int type);
+void ROKEN_LIB_FUNCTION
+ dns_srv_order(struct dns_reply*);
+
+#endif /* __RESOLVE_H__ */
diff --git a/source4/heimdal/lib/roken/roken-common.h b/source4/heimdal/lib/roken/roken-common.h
new file mode 100644
index 0000000000..d85d55f433
--- /dev/null
+++ b/source4/heimdal/lib/roken/roken-common.h
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 1995 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: roken-common.h,v 1.61 2005/07/07 05:03:30 lha Exp $ */
+
+#ifndef __ROKEN_COMMON_H__
+#define __ROKEN_COMMON_H__
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+#ifdef __cplusplus
+#define ROKEN_CPP_START extern "C" {
+#define ROKEN_CPP_END }
+#else
+#define ROKEN_CPP_START
+#define ROKEN_CPP_END
+#endif
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001
+#endif
+
+#ifndef SOMAXCONN
+#define SOMAXCONN 5
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef LOG_DAEMON
+#define openlog(id,option,facility) openlog((id),(option))
+#define LOG_DAEMON 0
+#endif
+#ifndef LOG_ODELAY
+#define LOG_ODELAY 0
+#endif
+#ifndef LOG_NDELAY
+#define LOG_NDELAY 0x08
+#endif
+#ifndef LOG_CONS
+#define LOG_CONS 0
+#endif
+#ifndef LOG_AUTH
+#define LOG_AUTH 0
+#endif
+#ifndef LOG_AUTHPRIV
+#define LOG_AUTHPRIV LOG_AUTH
+#endif
+
+#ifndef F_OK
+#define F_OK 0
+#endif
+
+#ifndef O_ACCMODE
+#define O_ACCMODE 003
+#endif
+
+#ifndef _PATH_DEV
+#define _PATH_DEV "/dev/"
+#endif
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+#ifndef _PATH_HEQUIV
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#endif
+
+#ifndef _PATH_VARRUN
+#define _PATH_VARRUN "/var/run/"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN (1024+4)
+#endif
+
+#ifndef SIG_ERR
+#define SIG_ERR ((RETSIGTYPE (*)(int))-1)
+#endif
+
+/*
+ * error code for getipnodeby{name,addr}
+ */
+
+#ifndef HOST_NOT_FOUND
+#define HOST_NOT_FOUND 1
+#endif
+
+#ifndef TRY_AGAIN
+#define TRY_AGAIN 2
+#endif
+
+#ifndef NO_RECOVERY
+#define NO_RECOVERY 3
+#endif
+
+#ifndef NO_DATA
+#define NO_DATA 4
+#endif
+
+#ifndef NO_ADDRESS
+#define NO_ADDRESS NO_DATA
+#endif
+
+/*
+ * error code for getaddrinfo
+ */
+
+#ifndef EAI_NOERROR
+#define EAI_NOERROR 0 /* no error */
+#endif
+
+#ifndef EAI_NONAME
+
+#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with nodename */
+#define EAI_NONAME 8 /* nodename nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+
+#endif /* EAI_NONAME */
+
+/* flags for getaddrinfo() */
+
+#ifndef AI_PASSIVE
+#define AI_PASSIVE 0x01
+#define AI_CANONNAME 0x02
+#endif /* AI_PASSIVE */
+
+#ifndef AI_NUMERICHOST
+#define AI_NUMERICHOST 0x04
+#endif
+
+/* flags for getnameinfo() */
+
+#ifndef NI_DGRAM
+#define NI_DGRAM 0x01
+#define NI_NAMEREQD 0x02
+#define NI_NOFQDN 0x04
+#define NI_NUMERICHOST 0x08
+#define NI_NUMERICSERV 0x10
+#endif
+
+/*
+ * constants for getnameinfo
+ */
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+#endif
+
+/*
+ * constants for inet_ntop
+ */
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/*
+ * for shutdown(2)
+ */
+
+#ifndef SHUT_RD
+#define SHUT_RD 0
+#endif
+
+#ifndef SHUT_WR
+#define SHUT_WR 1
+#endif
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+#define rk_UNCONST(x) ((void *)(unsigned long)(const void *)(x))
+
+ROKEN_CPP_START
+
+#ifndef IRIX4 /* fix for compiler bug */
+#ifdef RETSIGTYPE
+typedef RETSIGTYPE (*SigAction)(int);
+SigAction signal(int iSig, SigAction pAction); /* BSD compatible */
+#endif
+#endif
+
+int ROKEN_LIB_FUNCTION
+simple_execve(const char*, char*const[], char*const[]);
+
+int ROKEN_LIB_FUNCTION
+simple_execve_timed(const char *, char *const[],
+ char *const [], time_t (*)(void *),
+ void *, time_t);
+int ROKEN_LIB_FUNCTION
+simple_execvp(const char*, char *const[]);
+
+int ROKEN_LIB_FUNCTION
+simple_execvp_timed(const char *, char *const[],
+ time_t (*)(void *), void *, time_t);
+int ROKEN_LIB_FUNCTION
+simple_execlp(const char*, ...);
+
+int ROKEN_LIB_FUNCTION
+simple_execle(const char*, ...);
+
+int ROKEN_LIB_FUNCTION
+simple_execl(const char *file, ...);
+
+int ROKEN_LIB_FUNCTION
+wait_for_process(pid_t);
+
+int ROKEN_LIB_FUNCTION
+wait_for_process_timed(pid_t, time_t (*)(void *),
+ void *, time_t);
+int ROKEN_LIB_FUNCTION
+pipe_execv(FILE**, FILE**, FILE**, const char*, ...);
+
+void ROKEN_LIB_FUNCTION
+print_version(const char *);
+
+ssize_t ROKEN_LIB_FUNCTION
+eread (int fd, void *buf, size_t nbytes);
+
+ssize_t ROKEN_LIB_FUNCTION
+ewrite (int fd, const void *buf, size_t nbytes);
+
+struct hostent;
+
+const char * ROKEN_LIB_FUNCTION
+hostent_find_fqdn (const struct hostent *he);
+
+void ROKEN_LIB_FUNCTION
+esetenv(const char *var, const char *val, int rewrite);
+
+void ROKEN_LIB_FUNCTION
+socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port);
+
+size_t ROKEN_LIB_FUNCTION
+socket_addr_size (const struct sockaddr *sa);
+
+void ROKEN_LIB_FUNCTION
+socket_set_any (struct sockaddr *sa, int af);
+
+size_t ROKEN_LIB_FUNCTION
+socket_sockaddr_size (const struct sockaddr *sa);
+
+void * ROKEN_LIB_FUNCTION
+socket_get_address (struct sockaddr *sa);
+
+int ROKEN_LIB_FUNCTION
+socket_get_port (const struct sockaddr *sa);
+
+void ROKEN_LIB_FUNCTION
+socket_set_port (struct sockaddr *sa, int port);
+
+void ROKEN_LIB_FUNCTION
+socket_set_portrange (int sock, int restr, int af);
+
+void ROKEN_LIB_FUNCTION
+socket_set_debug (int sock);
+
+void ROKEN_LIB_FUNCTION
+socket_set_tos (int sock, int tos);
+
+void ROKEN_LIB_FUNCTION
+socket_set_reuseaddr (int sock, int val);
+
+char ** ROKEN_LIB_FUNCTION
+vstrcollect(va_list *ap);
+
+char ** ROKEN_LIB_FUNCTION
+strcollect(char *first, ...);
+
+void ROKEN_LIB_FUNCTION
+timevalfix(struct timeval *t1);
+
+void ROKEN_LIB_FUNCTION
+timevaladd(struct timeval *t1, const struct timeval *t2);
+
+void ROKEN_LIB_FUNCTION
+timevalsub(struct timeval *t1, const struct timeval *t2);
+
+char *ROKEN_LIB_FUNCTION
+pid_file_write (const char *progname);
+
+void ROKEN_LIB_FUNCTION
+pid_file_delete (char **);
+
+int ROKEN_LIB_FUNCTION
+read_environment(const char *file, char ***env);
+
+void ROKEN_LIB_FUNCTION
+warnerr(int doerrno, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 2, 0)));
+
+void * ROKEN_LIB_FUNCTION
+rk_realloc(void *, size_t);
+
+struct rk_strpool;
+
+char * ROKEN_LIB_FUNCTION
+rk_strpoolcollect(struct rk_strpool *);
+
+struct rk_strpool * ROKEN_LIB_FUNCTION
+rk_strpoolprintf(struct rk_strpool *, const char *, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+void ROKEN_LIB_FUNCTION
+rk_strpoolfree(struct rk_strpool *);
+
+
+ROKEN_CPP_END
+
+#endif /* __ROKEN_COMMON_H__ */
diff --git a/source4/heimdal/lib/roken/roken.h b/source4/heimdal/lib/roken/roken.h
new file mode 100644
index 0000000000..545f43c6a7
--- /dev/null
+++ b/source4/heimdal/lib/roken/roken.h
@@ -0,0 +1,688 @@
+/* -*- C -*- */
+/*
+ * Copyright (c) 1995-2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: roken.h.in,v 1.175 2005/07/07 19:16:17 lha Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
+
+#ifdef _AIX
+struct ether_addr;
+struct sockaddr_dl;
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <err.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifndef HAVE_SSIZE_T
+typedef int ssize_t;
+#endif
+
+#include <roken-common.h>
+
+ROKEN_CPP_START
+
+#if !defined(HAVE_SETSID) && defined(HAVE__SETSID)
+#define setsid _setsid
+#endif
+
+#ifndef HAVE_PUTENV
+int ROKEN_LIB_FUNCTION putenv(const char *string);
+#endif
+
+#if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
+int ROKEN_LIB_FUNCTION setenv(const char *var, const char *val, int rewrite);
+#endif
+
+#if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
+void ROKEN_LIB_FUNCTION unsetenv(const char *name);
+#endif
+
+#if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
+char * ROKEN_LIB_FUNCTION getusershell(void);
+void ROKEN_LIB_FUNCTION endusershell(void);
+#endif
+
+#if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION snprintf (char *str, size_t sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION
+ vsnprintf (char *str, size_t sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION
+ asprintf (char **ret, const char *format, ...)
+ __attribute__ ((format (printf, 2, 3)));
+#endif
+
+#if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION
+ vasprintf (char **ret, const char *format, va_list ap)
+ __attribute__((format (printf, 2, 0)));
+#endif
+
+#if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION
+ asnprintf (char **ret, size_t max_sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
+int ROKEN_LIB_FUNCTION
+ vasnprintf (char **ret, size_t max_sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#ifndef HAVE_STRDUP
+char * ROKEN_LIB_FUNCTION strdup(const char *old);
+#endif
+
+#if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO)
+char * ROKEN_LIB_FUNCTION strndup(const char *old, size_t sz);
+#endif
+
+#ifndef HAVE_STRLWR
+char * ROKEN_LIB_FUNCTION strlwr(char *);
+#endif
+
+#ifndef HAVE_STRNLEN
+size_t ROKEN_LIB_FUNCTION strnlen(const char*, size_t);
+#endif
+
+#if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO)
+char * ROKEN_LIB_FUNCTION strsep(char**, const char*);
+#endif
+
+#if !defined(HAVE_STRSEP_COPY) || defined(NEED_STRSEP_COPY_PROTO)
+ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t);
+#endif
+
+#ifndef HAVE_STRCASECMP
+int ROKEN_LIB_FUNCTION strcasecmp(const char *s1, const char *s2);
+#endif
+
+#ifdef NEED_FCLOSE_PROTO
+int ROKEN_LIB_FUNCTION fclose(FILE *);
+#endif
+
+#ifdef NEED_STRTOK_R_PROTO
+char * ROKEN_LIB_FUNCTION strtok_r(char *s1, const char *s2, char **lasts);
+#endif
+
+#ifndef HAVE_STRUPR
+char * ROKEN_LIB_FUNCTION strupr(char *);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t ROKEN_LIB_FUNCTION strlcpy (char *dst, const char *src, size_t dst_sz);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t ROKEN_LIB_FUNCTION strlcat (char *dst, const char *src, size_t dst_sz);
+#endif
+
+#ifndef HAVE_GETDTABLESIZE
+int ROKEN_LIB_FUNCTION getdtablesize(void);
+#endif
+
+#if !defined(HAVE_STRERROR) && !defined(strerror)
+char * ROKEN_LIB_FUNCTION strerror(int eno);
+#endif
+
+#if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
+/* This causes a fatal error under Psoriasis */
+#if !(defined(SunOS) && (SunOS >= 50))
+const char * ROKEN_LIB_FUNCTION hstrerror(int herr);
+#endif
+#endif
+
+#if !HAVE_DECL_H_ERRNO
+extern int h_errno;
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
+int ROKEN_LIB_FUNCTION inet_aton(const char *cp, struct in_addr *adr);
+#endif
+
+#ifndef HAVE_INET_NTOP
+const char * ROKEN_LIB_FUNCTION
+inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
+#ifndef HAVE_INET_PTON
+int ROKEN_LIB_FUNCTION
+inet_pton(int af, const char *src, void *dst);
+#endif
+
+#if !defined(HAVE_GETCWD)
+char* ROKEN_LIB_FUNCTION getcwd(char *path, size_t size);
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+struct passwd * ROKEN_LIB_FUNCTION k_getpwnam (const char *user);
+struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t uid);
+#endif
+
+const char * ROKEN_LIB_FUNCTION get_default_username (void);
+
+#ifndef HAVE_SETEUID
+int ROKEN_LIB_FUNCTION seteuid(uid_t euid);
+#endif
+
+#ifndef HAVE_SETEGID
+int ROKEN_LIB_FUNCTION setegid(gid_t egid);
+#endif
+
+#ifndef HAVE_LSTAT
+int ROKEN_LIB_FUNCTION lstat(const char *path, struct stat *buf);
+#endif
+
+#if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
+int ROKEN_LIB_FUNCTION mkstemp(char *);
+#endif
+
+#ifndef HAVE_CGETENT
+int ROKEN_LIB_FUNCTION cgetent(char **buf, char **db_array, const char *name);
+int ROKEN_LIB_FUNCTION cgetstr(char *buf, const char *cap, char **str);
+#endif
+
+#ifndef HAVE_INITGROUPS
+int ROKEN_LIB_FUNCTION initgroups(const char *name, gid_t basegid);
+#endif
+
+#ifndef HAVE_FCHOWN
+int ROKEN_LIB_FUNCTION fchown(int fd, uid_t owner, gid_t group);
+#endif
+
+#if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO)
+int ROKEN_LIB_FUNCTION daemon(int nochdir, int noclose);
+#endif
+
+#ifndef HAVE_INNETGR
+int ROKEN_LIB_FUNCTION innetgr(const char *netgroup, const char *machine,
+ const char *user, const char *domain);
+#endif
+
+#ifndef HAVE_CHOWN
+int ROKEN_LIB_FUNCTION chown(const char *path, uid_t owner, gid_t group);
+#endif
+
+#ifndef HAVE_RCMD
+int ROKEN_LIB_FUNCTION
+ rcmd(char **ahost, unsigned short inport, const char *locuser,
+ const char *remuser, const char *cmd, int *fd2p);
+#endif
+
+#if !defined(HAVE_INNETGR) || defined(NEED_INNETGR_PROTO)
+int ROKEN_LIB_FUNCTION innetgr(const char*, const char*,
+ const char*, const char*);
+#endif
+
+#ifndef HAVE_IRUSEROK
+int ROKEN_LIB_FUNCTION iruserok(unsigned raddr, int superuser,
+ const char *ruser, const char *luser);
+#endif
+
+#if !defined(HAVE_GETHOSTNAME) || defined(NEED_GETHOSTNAME_PROTO)
+int ROKEN_LIB_FUNCTION gethostname(char *name, int namelen);
+#endif
+
+#ifndef HAVE_WRITEV
+ssize_t ROKEN_LIB_FUNCTION
+writev(int d, const struct iovec *iov, int iovcnt);
+#endif
+
+#ifndef HAVE_READV
+ssize_t ROKEN_LIB_FUNCTION
+readv(int d, const struct iovec *iov, int iovcnt);
+#endif
+
+#ifndef HAVE_MKSTEMP
+int ROKEN_LIB_FUNCTION
+mkstemp(char *template);
+#endif
+
+#ifndef HAVE_PIDFILE
+void ROKEN_LIB_FUNCTION pidfile (const char*);
+#endif
+
+#ifndef HAVE_BSWAP32
+unsigned int ROKEN_LIB_FUNCTION bswap32(unsigned int);
+#endif
+
+#ifndef HAVE_BSWAP16
+unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
+#endif
+
+#ifndef HAVE_FLOCK
+#ifndef LOCK_SH
+#define LOCK_SH 1 /* Shared lock */
+#endif
+#ifndef LOCK_EX
+#define LOCK_EX 2 /* Exclusive lock */
+#endif
+#ifndef LOCK_NB
+#define LOCK_NB 4 /* Don't block when locking */
+#endif
+#ifndef LOCK_UN
+#define LOCK_UN 8 /* Unlock */
+#endif
+
+int flock(int fd, int operation);
+#endif /* HAVE_FLOCK */
+
+time_t ROKEN_LIB_FUNCTION tm2time (struct tm tm, int local);
+
+int ROKEN_LIB_FUNCTION unix_verify_user(char *user, char *password);
+
+int ROKEN_LIB_FUNCTION roken_concat (char *s, size_t len, ...);
+
+size_t ROKEN_LIB_FUNCTION roken_mconcat (char **s, size_t max_len, ...);
+
+int ROKEN_LIB_FUNCTION roken_vconcat (char *s, size_t len, va_list args);
+
+size_t ROKEN_LIB_FUNCTION
+ roken_vmconcat (char **s, size_t max_len, va_list args);
+
+ssize_t ROKEN_LIB_FUNCTION net_write (int fd, const void *buf, size_t nbytes);
+
+ssize_t ROKEN_LIB_FUNCTION net_read (int fd, void *buf, size_t nbytes);
+
+int ROKEN_LIB_FUNCTION issuid(void);
+
+#ifndef HAVE_STRUCT_WINSIZE
+struct winsize {
+ unsigned short ws_row, ws_col;
+ unsigned short ws_xpixel, ws_ypixel;
+};
+#endif
+
+int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *);
+
+#ifndef HAVE_VSYSLOG
+void ROKEN_LIB_FUNCTION vsyslog(int pri, const char *fmt, va_list ap);
+#endif
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+#endif
+#if !HAVE_DECL_OPTIND
+extern int optind;
+#endif
+#if !HAVE_DECL_OPTERR
+extern int opterr;
+#endif
+
+#if !HAVE_DECL_ENVIRON
+extern char **environ;
+#endif
+
+#ifndef HAVE_GETIPNODEBYNAME
+struct hostent * ROKEN_LIB_FUNCTION
+getipnodebyname (const char *name, int af, int flags, int *error_num);
+#endif
+
+#ifndef HAVE_GETIPNODEBYADDR
+struct hostent * ROKEN_LIB_FUNCTION
+getipnodebyaddr (const void *src, size_t len, int af, int *error_num);
+#endif
+
+#ifndef HAVE_FREEHOSTENT
+void ROKEN_LIB_FUNCTION
+freehostent (struct hostent *h);
+#endif
+
+#ifndef HAVE_COPYHOSTENT
+struct hostent * ROKEN_LIB_FUNCTION
+copyhostent (const struct hostent *h);
+#endif
+
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+
+#ifndef HAVE_SA_FAMILY_T
+typedef unsigned short sa_family_t;
+#endif
+
+#ifdef HAVE_IPV6
+#define _SS_MAXSIZE sizeof(struct sockaddr_in6)
+#else
+#define _SS_MAXSIZE sizeof(struct sockaddr_in)
+#endif
+
+#define _SS_ALIGNSIZE sizeof(unsigned long)
+
+#if HAVE_STRUCT_SOCKADDR_SA_LEN
+
+typedef unsigned char roken_sa_family_t;
+
+#define _SS_PAD1SIZE ((2 * _SS_ALIGNSIZE - sizeof (roken_sa_family_t) - sizeof(unsigned char)) % _SS_ALIGNSIZE)
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + sizeof(unsigned char) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+ unsigned char ss_len;
+ roken_sa_family_t ss_family;
+ char __ss_pad1[_SS_PAD1SIZE];
+ unsigned long __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
+};
+
+#else /* !HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+typedef unsigned short roken_sa_family_t;
+
+#define _SS_PAD1SIZE ((2 * _SS_ALIGNSIZE - sizeof (roken_sa_family_t)) % _SS_ALIGNSIZE)
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+ roken_sa_family_t ss_family;
+ char __ss_pad1[_SS_PAD1SIZE];
+ unsigned long __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
+};
+
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfo *ai_next;
+};
+#endif
+
+#ifndef HAVE_GETADDRINFO
+int ROKEN_LIB_FUNCTION
+getaddrinfo(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res);
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+int ROKEN_LIB_FUNCTION
+getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags);
+#endif
+
+#ifndef HAVE_FREEADDRINFO
+void ROKEN_LIB_FUNCTION
+freeaddrinfo(struct addrinfo *ai);
+#endif
+
+#ifndef HAVE_GAI_STRERROR
+char * ROKEN_LIB_FUNCTION
+gai_strerror(int ecode);
+#endif
+
+int ROKEN_LIB_FUNCTION
+getnameinfo_verified(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags);
+
+int ROKEN_LIB_FUNCTION
+roken_getaddrinfo_hostspec(const char *, int, struct addrinfo **);
+int ROKEN_LIB_FUNCTION
+roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **);
+
+#ifndef HAVE_STRFTIME
+size_t ROKEN_LIB_FUNCTION
+strftime (char *buf, size_t maxsize, const char *format,
+ const struct tm *tm);
+#endif
+
+#ifndef HAVE_STRPTIME
+char * ROKEN_LIB_FUNCTION
+strptime (const char *buf, const char *format, struct tm *timeptr);
+#endif
+
+#ifndef HAVE_EMALLOC
+void * ROKEN_LIB_FUNCTION emalloc (size_t);
+#endif
+#ifndef HAVE_ECALLOC
+void * ROKEN_LIB_FUNCTION ecalloc(size_t num, size_t sz);
+#endif
+#ifndef HAVE_EREALLOC
+void * ROKEN_LIB_FUNCTION erealloc (void *, size_t);
+#endif
+#ifndef HAVE_ESTRDUP
+char * ROKEN_LIB_FUNCTION estrdup (const char *);
+#endif
+
+/*
+ * kludges and such
+ */
+
+#if 1
+int ROKEN_LIB_FUNCTION
+roken_gethostby_setup(const char*, const char*);
+struct hostent* ROKEN_LIB_FUNCTION
+roken_gethostbyname(const char*);
+struct hostent* ROKEN_LIB_FUNCTION
+roken_gethostbyaddr(const void*, size_t, int);
+#else
+#ifdef GETHOSTBYNAME_PROTO_COMPATIBLE
+#define roken_gethostbyname(x) gethostbyname(x)
+#else
+#define roken_gethostbyname(x) gethostbyname((char *)x)
+#endif
+
+#ifdef GETHOSTBYADDR_PROTO_COMPATIBLE
+#define roken_gethostbyaddr(a, l, t) gethostbyaddr(a, l, t)
+#else
+#define roken_gethostbyaddr(a, l, t) gethostbyaddr((char *)a, l, t)
+#endif
+#endif
+
+#ifdef GETSERVBYNAME_PROTO_COMPATIBLE
+#define roken_getservbyname(x,y) getservbyname(x,y)
+#else
+#define roken_getservbyname(x,y) getservbyname((char *)x, (char *)y)
+#endif
+
+#ifdef OPENLOG_PROTO_COMPATIBLE
+#define roken_openlog(a,b,c) openlog(a,b,c)
+#else
+#define roken_openlog(a,b,c) openlog((char *)a,b,c)
+#endif
+
+#ifdef GETSOCKNAME_PROTO_COMPATIBLE
+#define roken_getsockname(a,b,c) getsockname(a,b,c)
+#else
+#define roken_getsockname(a,b,c) getsockname(a, b, (void*)c)
+#endif
+
+#ifndef HAVE_SETPROGNAME
+void ROKEN_LIB_FUNCTION setprogname(const char *argv0);
+#endif
+
+#ifndef HAVE_GETPROGNAME
+const char * ROKEN_LIB_FUNCTION getprogname(void);
+#endif
+
+#if !defined(HAVE_SETPROGNAME) && !defined(HAVE_GETPROGNAME) && !HAVE_DECL___PROGNAME
+extern const char *__progname;
+#endif
+
+void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo*);
+void ROKEN_LIB_FUNCTION mini_inetd (int port);
+
+#ifndef HAVE_LOCALTIME_R
+struct tm * ROKEN_LIB_FUNCTION
+localtime_r(const time_t *timer, struct tm *result);
+#endif
+
+#if !defined(HAVE_STRSVIS) || defined(NEED_STRSVIS_PROTO)
+int ROKEN_LIB_FUNCTION
+strsvis(char *dst, const char *src, int flag, const char *extra);
+#endif
+
+#if !defined(HAVE_STRUNVIS) || defined(NEED_STRUNVIS_PROTO)
+int ROKEN_LIB_FUNCTION
+strunvis(char *dst, const char *src);
+#endif
+
+#if !defined(HAVE_STRVIS) || defined(NEED_STRVIS_PROTO)
+int ROKEN_LIB_FUNCTION
+strvis(char *dst, const char *src, int flag);
+#endif
+
+#if !defined(HAVE_STRVISX) || defined(NEED_STRVISX_PROTO)
+int ROKEN_LIB_FUNCTION
+strvisx(char *dst, const char *src, size_t len, int flag);
+#endif
+
+#if !defined(HAVE_SVIS) || defined(NEED_SVIS_PROTO)
+char * ROKEN_LIB_FUNCTION
+svis(char *dst, int c, int flag, int nextc, const char *extra);
+#endif
+
+#if !defined(HAVE_UNVIS) || defined(NEED_UNVIS_PROTO)
+int ROKEN_LIB_FUNCTION
+unvis(char *cp, int c, int *astate, int flag);
+#endif
+
+#if !defined(HAVE_VIS) || defined(NEED_VIS_PROTO)
+char * ROKEN_LIB_FUNCTION
+vis(char *dst, int c, int flag, int nextc);
+#endif
+
+#if !defined(HAVE_CLOSEFROM)
+int ROKEN_LIB_FUNCTION
+closefrom(int);
+#endif
+
+ROKEN_CPP_END
diff --git a/source4/heimdal/lib/roken/roken_gethostby.c b/source4/heimdal/lib/roken/roken_gethostby.c
new file mode 100644
index 0000000000..2df3f83e36
--- /dev/null
+++ b/source4/heimdal/lib/roken/roken_gethostby.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: roken_gethostby.c,v 1.7 2005/04/12 11:29:03 lha Exp $");
+#endif
+
+#include <roken.h>
+
+#undef roken_gethostbyname
+#undef roken_gethostbyaddr
+
+static struct sockaddr_in dns_addr;
+static char *dns_req;
+
+static int
+make_address(const char *address, struct in_addr *ip)
+{
+ if(inet_aton(address, ip) == 0){
+ /* try to resolve as hostname, it might work if the address we
+ are trying to lookup is local, for instance a web proxy */
+ struct hostent *he = gethostbyname(address);
+ if(he) {
+ unsigned char *p = (unsigned char*)he->h_addr;
+ ip->s_addr = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+setup_int(const char *proxy_host, short proxy_port,
+ const char *dns_host, short dns_port,
+ const char *dns_path)
+{
+ memset(&dns_addr, 0, sizeof(dns_addr));
+ if(dns_req)
+ free(dns_req);
+ if(proxy_host) {
+ if(make_address(proxy_host, &dns_addr.sin_addr) != 0)
+ return -1;
+ dns_addr.sin_port = htons(proxy_port);
+ asprintf(&dns_req, "http://%s:%d%s", dns_host, dns_port, dns_path);
+ } else {
+ if(make_address(dns_host, &dns_addr.sin_addr) != 0)
+ return -1;
+ dns_addr.sin_port = htons(dns_port);
+ asprintf(&dns_req, "%s", dns_path);
+ }
+ dns_addr.sin_family = AF_INET;
+ return 0;
+}
+
+static void
+split_spec(const char *spec, char **host, int *port, char **path, int def_port)
+{
+ char *p;
+ *host = strdup(spec);
+ p = strchr(*host, ':');
+ if(p) {
+ *p++ = '\0';
+ if(sscanf(p, "%d", port) != 1)
+ *port = def_port;
+ } else
+ *port = def_port;
+ p = strchr(p ? p : *host, '/');
+ if(p) {
+ if(path)
+ *path = strdup(p);
+ *p = '\0';
+ }else
+ if(path)
+ *path = NULL;
+}
+
+
+int ROKEN_LIB_FUNCTION
+roken_gethostby_setup(const char *proxy_spec, const char *dns_spec)
+{
+ char *proxy_host = NULL;
+ int proxy_port;
+ char *dns_host, *dns_path;
+ int dns_port;
+
+ int ret = -1;
+
+ split_spec(dns_spec, &dns_host, &dns_port, &dns_path, 80);
+ if(dns_path == NULL)
+ goto out;
+ if(proxy_spec)
+ split_spec(proxy_spec, &proxy_host, &proxy_port, NULL, 80);
+ ret = setup_int(proxy_host, proxy_port, dns_host, dns_port, dns_path);
+out:
+ free(proxy_host);
+ free(dns_host);
+ free(dns_path);
+ return ret;
+}
+
+
+/* Try to lookup a name or an ip-address using http as transport
+ mechanism. See the end of this file for an example program. */
+static struct hostent*
+roken_gethostby(const char *hostname)
+{
+ int s;
+ struct sockaddr_in addr;
+ char *request;
+ char buf[1024];
+ int offset = 0;
+ int n;
+ char *p, *foo;
+
+ if(dns_addr.sin_family == 0)
+ return NULL; /* no configured host */
+ addr = dns_addr;
+ asprintf(&request, "GET %s?%s HTTP/1.0\r\n\r\n", dns_req, hostname);
+ if(request == NULL)
+ return NULL;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if(s < 0) {
+ free(request);
+ return NULL;
+ }
+ if(connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ close(s);
+ free(request);
+ return NULL;
+ }
+ if(write(s, request, strlen(request)) != strlen(request)) {
+ close(s);
+ free(request);
+ return NULL;
+ }
+ free(request);
+ while(1) {
+ n = read(s, buf + offset, sizeof(buf) - offset);
+ if(n <= 0)
+ break;
+ offset += n;
+ }
+ buf[offset] = '\0';
+ close(s);
+ p = strstr(buf, "\r\n\r\n"); /* find end of header */
+ if(p) p += 4;
+ else return NULL;
+ foo = NULL;
+ p = strtok_r(p, " \t\r\n", &foo);
+ if(p == NULL)
+ return NULL;
+ {
+ /* make a hostent to return */
+#define MAX_ADDRS 16
+ static struct hostent he;
+ static char addrs[4 * MAX_ADDRS];
+ static char *addr_list[MAX_ADDRS];
+ int num_addrs = 0;
+
+ he.h_name = p;
+ he.h_aliases = NULL;
+ he.h_addrtype = AF_INET;
+ he.h_length = 4;
+
+ while((p = strtok_r(NULL, " \t\r\n", &foo)) && num_addrs < MAX_ADDRS) {
+ struct in_addr ip;
+ inet_aton(p, &ip);
+ ip.s_addr = ntohl(ip.s_addr);
+ addr_list[num_addrs] = &addrs[num_addrs * 4];
+ addrs[num_addrs * 4 + 0] = (ip.s_addr >> 24) & 0xff;
+ addrs[num_addrs * 4 + 1] = (ip.s_addr >> 16) & 0xff;
+ addrs[num_addrs * 4 + 2] = (ip.s_addr >> 8) & 0xff;
+ addrs[num_addrs * 4 + 3] = (ip.s_addr >> 0) & 0xff;
+ addr_list[++num_addrs] = NULL;
+ }
+ he.h_addr_list = addr_list;
+ return &he;
+ }
+}
+
+struct hostent*
+roken_gethostbyname(const char *hostname)
+{
+ struct hostent *he;
+ he = gethostbyname(hostname);
+ if(he)
+ return he;
+ return roken_gethostby(hostname);
+}
+
+struct hostent* ROKEN_LIB_FUNCTION
+roken_gethostbyaddr(const void *addr, size_t len, int type)
+{
+ struct in_addr a;
+ const char *p;
+ struct hostent *he;
+ he = gethostbyaddr(addr, len, type);
+ if(he)
+ return he;
+ if(type != AF_INET || len != 4)
+ return NULL;
+ p = addr;
+ a.s_addr = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ return roken_gethostby(inet_ntoa(a));
+}
+
+#if 0
+
+/* this program can be used as a cgi `script' to lookup names and
+ ip-addresses */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/param.h>
+
+int
+main(int argc, char **argv)
+{
+ char *query = getenv("QUERY_STRING");
+ char host[MAXHOSTNAMELEN];
+ int i;
+ struct hostent *he;
+
+ printf("Content-type: text/plain\n\n");
+ if(query == NULL)
+ exit(0);
+ he = gethostbyname(query);
+ strncpy(host, he->h_name, sizeof(host));
+ host[sizeof(host) - 1] = '\0';
+ he = gethostbyaddr(he->h_addr, he->h_length, AF_INET);
+ printf("%s\n", he->h_name);
+ for(i = 0; he->h_addr_list[i]; i++) {
+ struct in_addr ip;
+ unsigned char *p = (unsigned char*)he->h_addr_list[i];
+ ip.s_addr = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ printf("%s\n", inet_ntoa(ip));
+ }
+ exit(0);
+}
+
+#endif
diff --git a/source4/heimdal/lib/roken/setprogname.c b/source4/heimdal/lib/roken/setprogname.c
new file mode 100644
index 0000000000..9c4210da9b
--- /dev/null
+++ b/source4/heimdal/lib/roken/setprogname.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995-2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: setprogname.c,v 1.3 2005/04/12 11:29:05 lha Exp $");
+#endif
+
+#include "roken.h"
+
+#ifndef HAVE___PROGNAME
+extern const char *__progname;
+#endif
+
+#ifndef HAVE_SETPROGNAME
+void ROKEN_LIB_FUNCTION
+setprogname(const char *argv0)
+{
+#ifndef HAVE___PROGNAME
+ char *p;
+ if(argv0 == NULL)
+ return;
+ p = strrchr(argv0, '/');
+ if(p == NULL)
+ p = (char *)argv0;
+ else
+ p++;
+ __progname = p;
+#endif
+}
+#endif /* HAVE_SETPROGNAME */
diff --git a/source4/heimdal/lib/roken/signal.c b/source4/heimdal/lib/roken/signal.c
new file mode 100644
index 0000000000..d92742d9fb
--- /dev/null
+++ b/source4/heimdal/lib/roken/signal.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: signal.c,v 1.13 2005/04/12 11:29:05 lha Exp $");
+#endif
+
+#include <signal.h>
+#include "roken.h"
+
+/*
+ * We would like to always use this signal but there is a link error
+ * on NEXTSTEP
+ */
+#if !defined(NeXT) && !defined(__APPLE__)
+/*
+ * Bugs:
+ *
+ * Do we need any extra hacks for SIGCLD and/or SIGCHLD?
+ */
+
+SigAction ROKEN_LIB_FUNCTION
+signal(int iSig, SigAction pAction)
+{
+ struct sigaction saNew, saOld;
+
+ saNew.sa_handler = pAction;
+ sigemptyset(&saNew.sa_mask);
+ saNew.sa_flags = 0;
+
+ if (iSig == SIGALRM)
+ {
+#ifdef SA_INTERRUPT
+ saNew.sa_flags |= SA_INTERRUPT;
+#endif
+ }
+ else
+ {
+#ifdef SA_RESTART
+ saNew.sa_flags |= SA_RESTART;
+#endif
+ }
+
+ if (sigaction(iSig, &saNew, &saOld) < 0)
+ return(SIG_ERR);
+
+ return(saOld.sa_handler);
+}
+#endif
diff --git a/source4/heimdal/lib/roken/strlwr.c b/source4/heimdal/lib/roken/strlwr.c
new file mode 100644
index 0000000000..c0ef46dc35
--- /dev/null
+++ b/source4/heimdal/lib/roken/strlwr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strlwr.c,v 1.6 2005/04/12 11:29:09 lha Exp $");
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#ifndef HAVE_STRLWR
+char * ROKEN_LIB_FUNCTION
+strlwr(char *str)
+{
+ char *s;
+
+ for(s = str; *s; s++)
+ *s = tolower((unsigned char)*s);
+ return str;
+}
+#endif
diff --git a/source4/heimdal/lib/roken/strpool.c b/source4/heimdal/lib/roken/strpool.c
new file mode 100644
index 0000000000..8ee95654cb
--- /dev/null
+++ b/source4/heimdal/lib/roken/strpool.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strpool.c,v 1.1 2005/06/28 22:46:57 lha Exp $");
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <roken.h>
+
+struct rk_strpool {
+ char *str;
+ size_t len;
+};
+
+/*
+ *
+ */
+
+void ROKEN_LIB_FUNCTION
+rk_strpoolfree(struct rk_strpool *p)
+{
+ if (p->str) {
+ free(p->str);
+ p->str = NULL;
+ }
+ free(p);
+}
+
+/*
+ *
+ */
+
+struct rk_strpool * ROKEN_LIB_FUNCTION
+rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...)
+{
+ va_list ap;
+ char *str, *str2;
+ int len;
+
+ if (p == NULL) {
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ p->str = NULL;
+ p->len = 0;
+ }
+ va_start(ap, fmt);
+ len = vasprintf(&str, fmt, ap);
+ va_end(ap);
+ if (str == NULL) {
+ printf("vasprintf");
+ rk_strpoolfree(p);
+ return NULL;
+ }
+ str2 = realloc(p->str, len + p->len + 1);
+ if (str2 == NULL) {
+ printf("realloc");
+ rk_strpoolfree(p);
+ return NULL;
+ }
+ p->str = str2;
+ memcpy(p->str + p->len, str, len + 1);
+ p->len += len;
+ return p;
+}
+
+/*
+ *
+ */
+
+char * ROKEN_LIB_FUNCTION
+rk_strpoolcollect(struct rk_strpool *p)
+{
+ char *str = p->str;
+ p->str = NULL;
+ free(p);
+ return str;
+}
diff --git a/source4/heimdal/lib/roken/strsep_copy.c b/source4/heimdal/lib/roken/strsep_copy.c
new file mode 100644
index 0000000000..5149838547
--- /dev/null
+++ b/source4/heimdal/lib/roken/strsep_copy.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000, 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strsep_copy.c,v 1.5 2005/04/12 11:29:11 lha Exp $");
+#endif
+
+#include <string.h>
+
+#include "roken.h"
+
+#ifndef HAVE_STRSEP_COPY
+
+/* strsep, but with const stringp, so return string in buf */
+
+ssize_t ROKEN_LIB_FUNCTION
+strsep_copy(const char **stringp, const char *delim, char *buf, size_t len)
+{
+ const char *save = *stringp;
+ size_t l;
+ if(save == NULL)
+ return -1;
+ *stringp = *stringp + strcspn(*stringp, delim);
+ l = min(len, *stringp - save);
+ if(len > 0) {
+ memcpy(buf, save, l);
+ buf[l] = '\0';
+ }
+
+ l = *stringp - save;
+ if(**stringp == '\0')
+ *stringp = NULL;
+ else
+ (*stringp)++;
+ return l;
+}
+
+#endif
diff --git a/source4/heimdal/lib/roken/strupr.c b/source4/heimdal/lib/roken/strupr.c
new file mode 100644
index 0000000000..4763a1a111
--- /dev/null
+++ b/source4/heimdal/lib/roken/strupr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strupr.c,v 1.6 2005/04/12 11:29:11 lha Exp $");
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#ifndef HAVE_STRUPR
+char * ROKEN_LIB_FUNCTION
+strupr(char *str)
+{
+ char *s;
+
+ for(s = str; *s; s++)
+ *s = toupper((unsigned char)*s);
+ return str;
+}
+#endif
diff --git a/source4/heimdal/lib/roken/vis.c b/source4/heimdal/lib/roken/vis.c
new file mode 100644
index 0000000000..a4bde71e9b
--- /dev/null
+++ b/source4/heimdal/lib/roken/vis.c
@@ -0,0 +1,330 @@
+/* $NetBSD: vis.c,v 1.4 2003/08/07 09:15:32 agc Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#if 1
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: vis.c,v 1.9 2005/04/12 11:29:15 lha Exp $");
+#endif
+#include <roken.h>
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(X)
+#endif
+#else
+#include <sys/cdefs.h>
+#if !defined(lint)
+__RCSID("$NetBSD: vis.c,v 1.4 2003/08/07 09:15:32 agc Exp $");
+#endif /* not lint */
+#endif
+
+#if 0
+#include "namespace.h"
+#endif
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <vis.h>
+
+#if 0
+#ifdef __weak_alias
+__weak_alias(strsvis,_strsvis)
+__weak_alias(strsvisx,_strsvisx)
+__weak_alias(strvis,_strvis)
+__weak_alias(strvisx,_strvisx)
+__weak_alias(svis,_svis)
+__weak_alias(vis,_vis)
+#endif
+#endif
+
+#undef BELL
+#if defined(__STDC__)
+#define BELL '\a'
+#else
+#define BELL '\007'
+#endif
+
+#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
+#define issafe(c) (c == '\b' || c == BELL || c == '\r')
+
+#define MAXEXTRAS 5
+
+
+#define MAKEEXTRALIST(flag, extra) \
+do { \
+ char *pextra = extra; \
+ if (flag & VIS_SP) *pextra++ = ' '; \
+ if (flag & VIS_TAB) *pextra++ = '\t'; \
+ if (flag & VIS_NL) *pextra++ = '\n'; \
+ if ((flag & VIS_NOSLASH) == 0) *pextra++ = '\\'; \
+ *pextra = '\0'; \
+} while (/*CONSTCOND*/0)
+
+/*
+ * This is SVIS, the central macro of vis.
+ * dst: Pointer to the destination buffer
+ * c: Character to encode
+ * flag: Flag word
+ * nextc: The character following 'c'
+ * extra: Pointer to the list of extra characters to be
+ * backslash-protected.
+ */
+#define SVIS(dst, c, flag, nextc, extra) \
+do { \
+ int isextra, isc; \
+ isextra = strchr(extra, c) != NULL; \
+ if (!isextra && \
+ isascii((unsigned char)c) && \
+ (isgraph((unsigned char)c) || iswhite(c) || \
+ ((flag & VIS_SAFE) && issafe(c)))) { \
+ *dst++ = c; \
+ break; \
+ } \
+ isc = 0; \
+ if (flag & VIS_CSTYLE) { \
+ switch (c) { \
+ case '\n': \
+ isc = 1; *dst++ = '\\'; *dst++ = 'n'; \
+ break; \
+ case '\r': \
+ isc = 1; *dst++ = '\\'; *dst++ = 'r'; \
+ break; \
+ case '\b': \
+ isc = 1; *dst++ = '\\'; *dst++ = 'b'; \
+ break; \
+ case BELL: \
+ isc = 1; *dst++ = '\\'; *dst++ = 'a'; \
+ break; \
+ case '\v': \
+ isc = 1; *dst++ = '\\'; *dst++ = 'v'; \
+ break; \
+ case '\t': \
+ isc = 1; *dst++ = '\\'; *dst++ = 't'; \
+ break; \
+ case '\f': \
+ isc = 1; *dst++ = '\\'; *dst++ = 'f'; \
+ break; \
+ case ' ': \
+ isc = 1; *dst++ = '\\'; *dst++ = 's'; \
+ break; \
+ case '\0': \
+ isc = 1; *dst++ = '\\'; *dst++ = '0'; \
+ if (isoctal(nextc)) { \
+ *dst++ = '0'; \
+ *dst++ = '0'; \
+ } \
+ } \
+ } \
+ if (isc) break; \
+ if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
+ *dst++ = '\\'; \
+ *dst++ = (u_char)(((unsigned)(u_char)c >> 6) & 03) + '0'; \
+ *dst++ = (u_char)(((unsigned)(u_char)c >> 3) & 07) + '0'; \
+ *dst++ = (c & 07) + '0'; \
+ } else { \
+ if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
+ if (c & 0200) { \
+ c &= 0177; *dst++ = 'M'; \
+ } \
+ if (iscntrl((unsigned char)c)) { \
+ *dst++ = '^'; \
+ if (c == 0177) \
+ *dst++ = '?'; \
+ else \
+ *dst++ = c + '@'; \
+ } else { \
+ *dst++ = '-'; *dst++ = c; \
+ } \
+ } \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * svis - visually encode characters, also encoding the characters
+ * pointed to by `extra'
+ */
+#ifndef HAVE_SVIS
+char * ROKEN_LIB_FUNCTION
+svis(char *dst, int c, int flag, int nextc, const char *extra)
+{
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(extra != NULL);
+
+ SVIS(dst, c, flag, nextc, extra);
+ *dst = '\0';
+ return(dst);
+}
+#endif
+
+
+/*
+ * strsvis, strsvisx - visually encode characters from src into dst
+ *
+ * Extra is a pointer to a \0-terminated list of characters to
+ * be encoded, too. These functions are useful e. g. to
+ * encode strings in such a way so that they are not interpreted
+ * by a shell.
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strsvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+#ifndef HAVE_STRSVIS
+int ROKEN_LIB_FUNCTION
+strsvis(char *dst, const char *src, int flag, const char *extra)
+{
+ char c;
+ char *start;
+
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(extra != NULL);
+
+ for (start = dst; (c = *src++) != '\0'; /* empty */)
+ SVIS(dst, c, flag, *src, extra);
+ *dst = '\0';
+ return (dst - start);
+}
+#endif
+
+
+#ifndef HAVE_STRVISX
+int ROKEN_LIB_FUNCTION
+strsvisx(char *dst, const char *src, size_t len, int flag, const char *extra)
+{
+ char c;
+ char *start;
+
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(extra != NULL);
+
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ SVIS(dst, c, flag, len ? *src : '\0', extra);
+ }
+ *dst = '\0';
+ return (dst - start);
+}
+#endif
+
+
+/*
+ * vis - visually encode characters
+ */
+#ifndef HAVE_VIS
+char * ROKEN_LIB_FUNCTION
+vis(char *dst, int c, int flag, int nextc)
+{
+ char extra[MAXEXTRAS];
+
+ _DIAGASSERT(dst != NULL);
+
+ MAKEEXTRALIST(flag, extra);
+ SVIS(dst, c, flag, nextc, extra);
+ *dst = '\0';
+ return (dst);
+}
+#endif
+
+
+/*
+ * strvis, strvisx - visually encode characters from src into dst
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+#ifndef HAVE_STRVIS
+int ROKEN_LIB_FUNCTION
+strvis(char *dst, const char *src, int flag)
+{
+ char extra[MAXEXTRAS];
+
+ MAKEEXTRALIST(flag, extra);
+ return (strsvis(dst, src, flag, extra));
+}
+#endif
+
+
+#ifndef HAVE_STRVISX
+int ROKEN_LIB_FUNCTION
+strvisx(char *dst, const char *src, size_t len, int flag)
+{
+ char extra[MAXEXTRAS];
+
+ MAKEEXTRALIST(flag, extra);
+ return (strsvisx(dst, src, len, flag, extra));
+}
+#endif
diff --git a/source4/heimdal/lib/roken/vis.hin b/source4/heimdal/lib/roken/vis.hin
new file mode 100644
index 0000000000..5b45c94362
--- /dev/null
+++ b/source4/heimdal/lib/roken/vis.hin
@@ -0,0 +1,98 @@
+/* $NetBSD: vis.h,v 1.11 1999/11/25 16:55:50 wennmach Exp $ */
+/* $Id: vis.hin,v 1.3 2005/04/12 11:29:15 lha Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)vis.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _VIS_H_
+#define _VIS_H_
+
+#ifndef ROKEN_LIB_FUNCTION
+#ifdef _WIN32
+#define ROKEN_LIB_FUNCTION _stdcall
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+/*
+ * to select alternate encoding format
+ */
+#define VIS_OCTAL 0x01 /* use octal \ddd format */
+#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
+
+/*
+ * to alter set of characters encoded (default is to encode all
+ * non-graphic except space, tab, and newline).
+ */
+#define VIS_SP 0x04 /* also encode space */
+#define VIS_TAB 0x08 /* also encode tab */
+#define VIS_NL 0x10 /* also encode newline */
+#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
+#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
+
+/*
+ * other
+ */
+#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
+
+/*
+ * unvis return codes
+ */
+#define UNVIS_VALID 1 /* character valid */
+#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
+#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
+#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
+#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
+
+/*
+ * unvis flags
+ */
+#define UNVIS_END 1 /* no more characters */
+
+char ROKEN_LIB_FUNCTION
+ *vis (char *, int, int, int);
+char ROKEN_LIB_FUNCTION
+ *svis (char *, int, int, int, const char *);
+int ROKEN_LIB_FUNCTION
+ strvis (char *, const char *, int);
+int ROKEN_LIB_FUNCTION
+ strsvis (char *, const char *, int, const char *);
+int ROKEN_LIB_FUNCTION
+ strvisx (char *, const char *, size_t, int);
+int ROKEN_LIB_FUNCTION
+ strsvisx (char *, const char *, size_t, int, const char *);
+int ROKEN_LIB_FUNCTION
+ strunvis (char *, const char *);
+int ROKEN_LIB_FUNCTION
+ unvis (char *, int, int *, int);
+
+#endif /* !_VIS_H_ */