summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/openbsd-compat
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-10-29 09:43:00 +0000
committerdes <des@FreeBSD.org>2002-10-29 09:43:00 +0000
commit099d1a58f7bc088a9f71af6d32542ca3949468a3 (patch)
tree49cef8938d7beb10016662d15546fa090865073d /crypto/openssh/openbsd-compat
parent1ba793a7c09e24d920de3983a3223770cb37ebff (diff)
downloadFreeBSD-src-099d1a58f7bc088a9f71af6d32542ca3949468a3.zip
FreeBSD-src-099d1a58f7bc088a9f71af6d32542ca3949468a3.tar.gz
Vendor import of OpenSSH-portable 3.5p1.
Diffstat (limited to 'crypto/openssh/openbsd-compat')
-rw-r--r--crypto/openssh/openbsd-compat/Makefile.in4
-rw-r--r--crypto/openssh/openbsd-compat/base64.c5
-rw-r--r--crypto/openssh/openbsd-compat/bindresvport.c2
-rw-r--r--crypto/openssh/openbsd-compat/bsd-cray.c613
-rw-r--r--crypto/openssh/openbsd-compat/bsd-cray.h17
-rw-r--r--crypto/openssh/openbsd-compat/bsd-getpeereid.c56
-rw-r--r--crypto/openssh/openbsd-compat/bsd-getpeereid.h14
-rw-r--r--crypto/openssh/openbsd-compat/bsd-misc.c6
-rw-r--r--crypto/openssh/openbsd-compat/dirname.c8
-rw-r--r--crypto/openssh/openbsd-compat/getcwd.c2
-rw-r--r--crypto/openssh/openbsd-compat/getopt.c2
-rw-r--r--crypto/openssh/openbsd-compat/glob.c45
-rw-r--r--crypto/openssh/openbsd-compat/glob.h18
-rw-r--r--crypto/openssh/openbsd-compat/inet_ntoa.c6
-rw-r--r--crypto/openssh/openbsd-compat/inet_ntop.c51
-rw-r--r--crypto/openssh/openbsd-compat/mktemp.c6
-rw-r--r--crypto/openssh/openbsd-compat/openbsd-compat.h3
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.c45
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.h30
-rw-r--r--crypto/openssh/openbsd-compat/readpassphrase.c35
-rw-r--r--crypto/openssh/openbsd-compat/readpassphrase.h5
-rw-r--r--crypto/openssh/openbsd-compat/realpath.c6
-rw-r--r--crypto/openssh/openbsd-compat/rresvport.c2
-rw-r--r--crypto/openssh/openbsd-compat/setenv.c2
-rw-r--r--crypto/openssh/openbsd-compat/sigact.c2
-rw-r--r--crypto/openssh/openbsd-compat/strlcat.c2
-rw-r--r--crypto/openssh/openbsd-compat/strlcpy.c2
-rw-r--r--crypto/openssh/openbsd-compat/strsep.c2
-rw-r--r--crypto/openssh/openbsd-compat/sys-queue.h584
-rw-r--r--crypto/openssh/openbsd-compat/sys-tree.h675
-rw-r--r--crypto/openssh/openbsd-compat/xmmap.c67
-rw-r--r--crypto/openssh/openbsd-compat/xmmap.h23
32 files changed, 2170 insertions, 170 deletions
diff --git a/crypto/openssh/openbsd-compat/Makefile.in b/crypto/openssh/openbsd-compat/Makefile.in
index 3e09cfe..5229e7e 100644
--- a/crypto/openssh/openbsd-compat/Makefile.in
+++ b/crypto/openssh/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.21 2002/02/19 20:27:57 mouring Exp $
+# $Id: Makefile.in,v 1.23 2002/09/12 00:33:02 djm Exp $
sysconfdir=@sysconfdir@
piddir=@piddir@
@@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@
OPENBSD=base64.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o
-COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o
+COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o xmmap.o
PORTS=port-irix.o port-aix.o
diff --git a/crypto/openssh/openbsd-compat/base64.c b/crypto/openssh/openbsd-compat/base64.c
index d12b993..005170b 100644
--- a/crypto/openssh/openbsd-compat/base64.c
+++ b/crypto/openssh/openbsd-compat/base64.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */
+/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */
/*
* Copyright (c) 1996 by Internet Software Consortium.
@@ -42,7 +42,7 @@
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-#include "config.h"
+#include "includes.h"
#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)
@@ -60,6 +60,7 @@
#include "base64.h"
+/* XXX abort illegal in library */
#define Assert(Cond) if (!(Cond)) abort()
static const char Base64[] =
diff --git a/crypto/openssh/openbsd-compat/bindresvport.c b/crypto/openssh/openbsd-compat/bindresvport.c
index 332bcb0..620f980 100644
--- a/crypto/openssh/openbsd-compat/bindresvport.c
+++ b/crypto/openssh/openbsd-compat/bindresvport.c
@@ -29,7 +29,7 @@
* Mountain View, California 94043
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_BINDRESVPORT_SA
diff --git a/crypto/openssh/openbsd-compat/bsd-cray.c b/crypto/openssh/openbsd-compat/bsd-cray.c
index 9bab75b..edb3112 100644
--- a/crypto/openssh/openbsd-compat/bsd-cray.c
+++ b/crypto/openssh/openbsd-compat/bsd-cray.c
@@ -1,5 +1,5 @@
/*
- * $Id: bsd-cray.c,v 1.6 2002/05/15 16:39:51 mouring Exp $
+ * $Id: bsd-cray.c,v 1.8 2002/09/26 00:38:51 tim Exp $
*
* bsd-cray.c
*
@@ -34,8 +34,8 @@
* on UNICOS systems.
*
*/
+#ifdef _UNICOS
-#ifdef _CRAY
#include <udb.h>
#include <tmpdir.h>
#include <unistd.h>
@@ -45,19 +45,33 @@
#include <signal.h>
#include <sys/priv.h>
#include <sys/secparm.h>
+#include <sys/tfm.h>
#include <sys/usrv.h>
#include <sys/sysv.h>
#include <sys/sectab.h>
+#include <sys/secstat.h>
#include <sys/stat.h>
+#include <sys/session.h>
#include <stdlib.h>
#include <pwd.h>
#include <fcntl.h>
#include <errno.h>
-
+#include <ia.h>
+#include <urm.h>
+#include "ssh.h"
+#include "log.h"
+#include "servconf.h"
#include "bsd-cray.h"
+#define MAXACID 80
+
+extern ServerOptions options;
+
char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */
+struct sysv sysv; /* system security structure */
+struct usrv usrv; /* user security structure */
+
/*
* Functions.
*/
@@ -65,68 +79,538 @@ void cray_retain_utmp(struct utmp *, int);
void cray_delete_tmpdir(char *, int, uid_t);
void cray_init_job(struct passwd *);
void cray_set_tmpdir(struct utmp *);
+void cray_login_failure(char *, int);
+int cray_setup(uid_t, char *, const char *);
+int cray_access_denied(char *);
+
+void
+cray_login_failure(char *username, int errcode)
+{
+ struct udb *ueptr; /* UDB pointer for username */
+ ia_failure_t fsent; /* ia_failure structure */
+ ia_failure_ret_t fret; /* ia_failure return stuff */
+ struct jtab jtab; /* job table structure */
+ int jid = 0; /* job id */
+
+ if ((jid = getjtab(&jtab)) < 0) {
+ debug("cray_login_failure(): getjtab error");
+ }
+ getsysudb();
+ if ((ueptr = getudbnam(username)) == UDB_NULL) {
+ debug("cray_login_failure(): getudbname() returned NULL");
+ }
+ endudb();
+ fsent.revision = 0;
+ fsent.uname = username;
+ fsent.host = (char *)get_canonical_hostname(options.verify_reverse_mapping);
+ fsent.ttyn = "sshd";
+ fsent.caller = IA_SSHD;
+ fsent.flags = IA_INTERACTIVE;
+ fsent.ueptr = ueptr;
+ fsent.jid = jid;
+ fsent.errcode = errcode;
+ fsent.pwdp = NULL;
+ fsent.exitcode = 0; /* dont exit in ia_failure() */
+
+ fret.revision = 0;
+ fret.normal = 0;
+ /*
+ * Call ia_failure because of an login failure.
+ */
+ ia_failure(&fsent,&fret);
+}
/*
- * Orignal written by:
- * Wayne Schroeder
- * San Diego Supercomputer Center
- * schroeder@sdsc.edu
-*/
-void
-cray_setup(uid_t uid, char *username)
+ * Cray access denied
+ */
+int
+cray_access_denied(char *username)
{
- struct udb *p;
+ struct udb *ueptr; /* UDB pointer for username */
+ int errcode; /* IA errorcode */
+
+ errcode = 0;
+ getsysudb();
+ if ((ueptr = getudbnam(username)) == UDB_NULL) {
+ debug("cray_login_failure(): getudbname() returned NULL");
+ }
+ endudb();
+ if (ueptr && ueptr->ue_disabled)
+ errcode = IA_DISABLED;
+ if (errcode)
+ cray_login_failure(username, errcode);
+ return (errcode);
+}
+
+int
+cray_setup (uid_t uid, char *username, const char *command)
+{
+ extern struct udb *getudb();
extern char *setlimits();
- int i, j;
- int accts[MAXVIDS];
- int naccts;
- int err;
- char *sr;
- int pid;
- struct jtab jbuf;
- int jid;
- if ((jid = getjtab(&jbuf)) < 0)
- fatal("getjtab: no jid");
-
- err = setudb(); /* open and rewind the Cray User DataBase */
- if (err != 0)
- fatal("UDB open failure");
- naccts = 0;
- p = getudbnam(username);
- if (p == NULL)
- fatal("No UDB entry for %.100s", username);
- if (uid != p->ue_uid)
- fatal("UDB entry %.100s uid(%d) does not match uid %d",
- username, (int) p->ue_uid, (int) uid);
- for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) {
- accts[naccts] = p->ue_acids[j];
- naccts++;
+ int err; /* error return */
+ time_t system_time; /* current system clock */
+ time_t expiration_time; /* password expiration time */
+ int maxattempts; /* maximum no. of failed login attempts */
+ int SecureSys; /* unicos security flag */
+ int minslevel = 0; /* system minimum security level */
+ int i, j;
+ int valid_acct = -1; /* flag for reading valid acct */
+ char acct_name[MAXACID] = { "" }; /* used to read acct name */
+ struct jtab jtab; /* Job table struct */
+ struct udb ue; /* udb entry for logging-in user */
+ struct udb *up; /* pointer to UDB entry */
+ struct secstat secinfo; /* file security attributes */
+ struct servprov init_info; /* used for sesscntl() call */
+ int jid; /* job ID */
+ int pid; /* process ID */
+ char *sr; /* status return from setlimits() */
+ char *ttyn = NULL; /* ttyname or command name*/
+ char hostname[MAXHOSTNAMELEN];
+ passwd_t pwdacm,
+ pwddialup,
+ pwdudb,
+ pwdwal,
+ pwddce; /* passwd stuff for ia_user */
+ ia_user_ret_t uret; /* stuff returned from ia_user */
+ ia_user_t usent; /* ia_user main structure */
+ int ia_rcode; /* ia_user return code */
+ ia_failure_t fsent; /* ia_failure structure */
+ ia_failure_ret_t fret; /* ia_failure return stuff */
+ ia_success_t ssent; /* ia_success structure */
+ ia_success_ret_t sret; /* ia_success return stuff */
+ int ia_mlsrcode; /* ia_mlsuser return code */
+ int secstatrc; /* [f]secstat return code */
+
+ if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) {
+ getsysv(&sysv, sizeof(struct sysv));
+ minslevel = sysv.sy_minlvl;
+ if (getusrv(&usrv) < 0) {
+ debug("getusrv() failed, errno = %d",errno);
+ exit(1);
+ }
}
- endudb(); /* close the udb */
-
- if (naccts != 0) {
- /* Perhaps someday we'll prompt users who have multiple accounts
- to let them pick one (like CRI's login does), but for now just set
- the account to the first entry. */
- if (acctid(0, accts[0]) < 0)
- fatal("System call acctid failed, accts[0]=%d", accts[0]);
+ hostname[0] = '\0';
+ strncpy(hostname,
+ (char *)get_canonical_hostname(options.verify_reverse_mapping),
+ MAXHOSTNAMELEN);
+ /*
+ * Fetch user's UDB entry.
+ */
+ getsysudb();
+ if ((up = getudbnam(username)) == UDB_NULL) {
+ debug("cannot fetch user's UDB entry");
+ exit(1);
+ }
+
+ /*
+ * Prevent any possible fudging so perform a data
+ * safety check and compare the supplied uid against
+ * the udb's uid.
+ */
+ if (up->ue_uid != uid) {
+ debug("IA uid missmatch");
+ exit(1);
+ }
+ endudb();
+
+ if ((jid = getjtab (&jtab)) < 0) {
+ debug("getjtab");
+ return -1;
+ }
+ pid = getpid();
+ ttyn = ttyname(0);
+ if (SecureSys) {
+ if (ttyn) {
+ secstatrc = secstat(ttyn, &secinfo);
+ } else {
+ secstatrc = fsecstat(1, &secinfo);
+ }
+ if (secstatrc == 0) {
+ debug("[f]secstat() successful");
+ } else {
+ debug("[f]secstat() error, rc = %d", secstatrc);
+ exit(1);
+ }
+ }
+ if ((ttyn == NULL) && ((char *)command != NULL))
+ ttyn = (char *)command;
+ /*
+ * Initialize all structures to call ia_user
+ */
+ usent.revision = 0;
+ usent.uname = username;
+ usent.host = hostname;
+ usent.ttyn = ttyn;
+ usent.caller = IA_SSHD;
+ usent.pswdlist = &pwdacm;
+ usent.ueptr = &ue;
+ usent.flags = IA_INTERACTIVE | IA_FFLAG;
+ pwdacm.atype = IA_SECURID;
+ pwdacm.pwdp = NULL;
+ pwdacm.next = &pwdudb;
+
+ pwdudb.atype = IA_UDB;
+ pwdudb.pwdp = NULL;
+ pwdudb.next = &pwddce;
+
+ pwddce.atype = IA_DCE;
+ pwddce.pwdp = NULL;
+ pwddce.next = &pwddialup;
+
+ pwddialup.atype = IA_DIALUP;
+ pwddialup.pwdp = NULL;
+ /* pwddialup.next = &pwdwal; */
+ pwddialup.next = NULL;
+
+ pwdwal.atype = IA_WAL;
+ pwdwal.pwdp = NULL;
+ pwdwal.next = NULL;
+
+ uret.revision = 0;
+ uret.pswd = NULL;
+ uret.normal = 0;
+
+ ia_rcode = ia_user(&usent, &uret);
+
+ switch (ia_rcode) {
+ /*
+ * These are acceptable return codes from ia_user()
+ */
+ case IA_UDBWEEK: /* Password Expires in 1 week */
+ expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage;
+ printf ("WARNING - your current password will expire %s\n",
+ ctime((const time_t *)&expiration_time));
+ break;
+ case IA_UDBEXPIRED:
+ if (ttyname(0) != NULL) {
+ /* Force a password change */
+ printf("Your password has expired; Choose a new one.\n");
+ execl("/bin/passwd", "passwd", username, 0);
+ exit(9);
+ }
+
+ break;
+ case IA_NORMAL: /* Normal Return Code */
+ break;
+ case IA_BACKDOOR:
+ strcpy(ue.ue_name, "root");
+ strcpy(ue.ue_passwd, "");
+ strcpy(ue.ue_dir, "/");
+ strcpy(ue.ue_shell, "/bin/sh");
+ strcpy(ue.ue_age, "");
+ strcpy(ue.ue_comment, "");
+ strcpy(ue.ue_loghost, "");
+ strcpy(ue.ue_logline, "");
+ ue.ue_uid=-1;
+ ue.ue_nice[UDBRC_INTER]=0;
+ for (i=0;i<MAXVIDS;i++)
+ ue.ue_gids[i]=0;
+ ue.ue_logfails=0;
+ ue.ue_minlvl=minslevel;
+ ue.ue_maxlvl=minslevel;
+ ue.ue_deflvl=minslevel;
+ ue.ue_defcomps=0;
+ ue.ue_comparts=0;
+ ue.ue_permits=0;
+ ue.ue_trap=0;
+ ue.ue_disabled=0;
+ ue.ue_logtime=0;
+ break;
+ case IA_CONSOLE: /* Superuser not from Console */
+ case IA_TRUSTED: /* Trusted user */
+ if (options.permit_root_login > PERMIT_NO)
+ break; /* Accept root login */
+ default:
+ /*
+ * These are failed return codes from ia_user()
+ */
+ switch (ia_rcode)
+ {
+ case IA_BADAUTH:
+ printf ("Bad authorization, access denied.\n");
+ break;
+ case IA_DIALUPERR:
+ break;
+ case IA_DISABLED:
+ printf ("Your login has been disabled. Contact the system ");
+ printf ("administrator for assistance.\n");
+ break;
+ case IA_GETSYSV:
+ printf ("getsysv() failed - errno = %d\n", errno);
+ break;
+ case IA_LOCALHOST:
+ break;
+ case IA_MAXLOGS:
+ printf ("Maximum number of failed login attempts exceeded.\n");
+ printf ("Access denied.\n");
+ break;
+ case IA_NOPASS:
+ break;
+ case IA_PUBLIC:
+ break;
+ case IA_SECURIDERR:
+ break;
+ case IA_CONSOLE:
+ break;
+ case IA_TRUSTED:
+ break;
+ case IA_UDBERR:
+ break;
+ case IA_UDBPWDNULL:
+ /*
+ * NULL password not allowed on MLS systems
+ */
+ if (SecureSys) {
+ printf("NULL Password not allowed on MLS systems.\n");
+ }
+ break;
+ case IA_UNKNOWN:
+ break;
+ case IA_UNKNOWNYP:
+ break;
+ case IA_WALERR:
+ break;
+ default:
+ /* nothing special */
+ ;
+ } /* 2. switch (ia_rcode) */
+ /*
+ * Authentication failed.
+ */
+ printf("sshd: Login incorrect, (0%o)\n",
+ ia_rcode-IA_ERRORCODE);
+
+ /*
+ * Initialize structure for ia_failure
+ * which will exit.
+ */
+ fsent.revision = 0;
+ fsent.uname = username;
+ fsent.host = hostname;
+ fsent.ttyn = ttyn;
+ fsent.caller = IA_SSHD;
+ fsent.flags = IA_INTERACTIVE;
+ fsent.ueptr = &ue;
+ fsent.jid = jid;
+ fsent.errcode = ia_rcode;
+ fsent.pwdp = uret.pswd;
+ fsent.exitcode = 1;
+
+ fret.revision = 0;
+ fret.normal = 0;
+
+ /*
+ * Call ia_failure because of an IA failure.
+ * There is no return because ia_failure exits.
+ */
+
+ ia_failure(&fsent,&fret);
+
+ exit(1);
+ } /* 1. switch (ia_rcode) */
+ ia_mlsrcode = IA_NORMAL;
+ if (SecureSys) {
+ debug("calling ia_mlsuser()");
+ ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0);
+ }
+ if (ia_mlsrcode != IA_NORMAL) {
+ printf("sshd: Login incorrect, (0%o)\n",
+ ia_mlsrcode-IA_ERRORCODE);
+ /*
+ * Initialize structure for ia_failure
+ * which will exit.
+ */
+ fsent.revision = 0;
+ fsent.uname = username;
+ fsent.host = hostname;
+ fsent.ttyn = ttyn;
+ fsent.caller = IA_SSHD;
+ fsent.flags = IA_INTERACTIVE;
+ fsent.ueptr = &ue;
+ fsent.jid = jid;
+ fsent.errcode = ia_mlsrcode;
+ fsent.pwdp = uret.pswd;
+ fsent.exitcode = 1;
+ fret.revision = 0;
+ fret.normal = 0;
+
+ /*
+ * Call ia_failure because of an IA failure.
+ * There is no return because ia_failure exits.
+ */
+ ia_failure(&fsent,&fret);
+ exit(1);
}
- /* Now set limits, including CPU time for the (interactive) job and process,
- and set up permissions (for chown etc), etc. This is via an internal CRI
- routine, setlimits, used by CRI's login. */
+ /* Provide login status information */
+ if (options.print_lastlog && ue.ue_logtime != 0) {
+ printf("Last successful login was : %.*s ",
+ 19, (char *)ctime(&ue.ue_logtime));
+
+ if (*ue.ue_loghost != '\0')
+ printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost);
+
+ else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline);
+
+ if ( SecureSys && (ue.ue_logfails != 0))
+ printf(" followed by %d failed attempts\n", ue.ue_logfails);
+ }
+
+
+ /*
+ * Call ia_success to process successful I/A.
+ */
+ ssent.revision = 0;
+ ssent.uname = username;
+ ssent.host = hostname;
+ ssent.ttyn = ttyn;
+ ssent.caller = IA_SSHD;
+ ssent.flags = IA_INTERACTIVE;
+ ssent.ueptr = &ue;
+ ssent.jid = jid;
+ ssent.errcode = ia_rcode;
+ ssent.us = NULL;
+ ssent.time = 1; /* Set ue_logtime */
+
+ sret.revision = 0;
+ sret.normal = 0;
+
+ ia_success(&ssent,&sret);
+
+ /*
+ * Query for account, iff > 1 valid acid & askacid permbit
+ */
+ if (((ue.ue_permbits & PERMBITS_ACCTID) ||
+ (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) &&
+ ue.ue_permbits & PERMBITS_ASKACID) {
+ if (ttyname(0) != NULL) {
+ debug("cray_setup: ttyname true case, %.100s", ttyname);
+ while (valid_acct == -1) {
+ printf("Account (? for available accounts)"
+ " [%s]: ", acid2nam(ue.ue_acids[0]));
+ gets(acct_name);
+ switch (acct_name[0]) {
+ case EOF:
+ exit(0);
+ break;
+ case '\0':
+ valid_acct = ue.ue_acids[0];
+ strcpy(acct_name, acid2nam(valid_acct));
+ break;
+ case '?':
+ /* Print the list 3 wide */
+ for (i = 0, j = 0; i < MAXVIDS; i++) {
+ if (ue.ue_acids[i] == -1) {
+ printf("\n");
+ break;
+ }
+ if (++j == 4) {
+ j = 1;
+ printf("\n");
+ }
+ printf(" %s",
+ acid2nam(ue.ue_acids[i]));
+ }
+ if (ue.ue_permbits & PERMBITS_ACCTID)
+ printf("\"acctid\" permbit also allows"
+ " you to select any valid "
+ "account name.\n");
+ printf("\n");
+ break;
+ default:
+ if ((valid_acct = nam2acid(acct_name)) == -1) printf("Account id not found for"
+ " account name \"%s\"\n\n",
+ acct_name);
+ break;
+ }
+ /*
+ * If an account was given, search the user's
+ * acids array to verify they can use this account.
+ */
+ if ((valid_acct != -1) &&
+ !(ue.ue_permbits & PERMBITS_ACCTID)) {
+ for (i = 0; i < MAXVIDS; i++) {
+ if (ue.ue_acids[i] == -1)
+ break;
+ if (valid_acct == ue.ue_acids[i])
+ break;
+ }
+ if (i == MAXVIDS ||
+ ue.ue_acids[i] == -1) {
+ fprintf(stderr, "Cannot set"
+ " account name to "
+ "\"%s\", permission "
+ "denied\n\n", acct_name);
+ valid_acct = -1;
+ }
+ }
+ }
+ } else {
+ /*
+ * The client isn't connected to a terminal and can't
+ * respond to an acid prompt. Use default acid.
+ */
+ debug("cray_setup: ttyname false case, %.100s", ttyname);
+ valid_acct = ue.ue_acids[0];
+ }
+ } else {
+ /*
+ * The user doesn't have the askacid permbit set or
+ * only has one valid account to use.
+ */
+ valid_acct = ue.ue_acids[0];
+ }
+ if (acctid(0, valid_acct) < 0) {
+ printf ("Bad account id: %d\n", valid_acct);
+ exit(1);
+ }
+
+/* set up shares and quotas */
+/* Now set shares, quotas, limits, including CPU time for the (interactive)
+ * job and process, and set up permissions (for chown etc), etc.
+ */
+ if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) {
+ printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct);
+ exit(1);
+ }
- pid = getpid();
sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
- if (sr != NULL)
- fatal("%.200s", sr);
-
+ if (sr != NULL) {
+ debug("%.200s", sr);
+ exit(1);
+ }
sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
- if (sr != NULL)
- fatal("%.200s", sr);
+ if (sr != NULL) {
+ debug("%.200s", sr);
+ exit(1);
+ }
+ /*
+ * Place the service provider information into
+ * the session table (Unicos) or job table (Unicos/mk).
+ * There exist double defines for the job/session table in
+ * unicos/mk (jtab.h) so no need for a compile time switch.
+ */
+ bzero((char *)&init_info, sizeof(struct servprov));
+ init_info.s_sessinit.si_id = URM_SPT_LOGIN;
+ init_info.s_sessinit.si_pid = getpid();
+ init_info.s_sessinit.si_sid = jid;
+ init_info.s_routing.seqno = 0;
+ init_info.s_routing.iadrs = 0;
+ sesscntl(0, S_SETSERVPO, (int)&init_info);
+ /*
+ * Set user and controlling tty security attributes.
+ */
+ if (SecureSys) {
+ if (setusrv(&usrv) == -1) {
+ debug("setusrv() failed, errno = %d",errno);
+ exit(1);
+ }
+ }
+
+ return(0);
}
/*
@@ -143,7 +627,6 @@ drop_cray_privs()
int result;
extern int priv_set_proc();
extern priv_proc_t* priv_init_proc();
- struct usrv usrv;
/*
* If ether of theses two flags are not set
@@ -154,9 +637,23 @@ drop_cray_privs()
if (!sysconf(_SC_CRAY_POSIX_PRIV))
fatal("Not POSIX_PRIV.");
- debug("Dropping privileges.");
+ debug("Setting MLS labels.");;
+
+ if (sysconf(_SC_CRAY_SECURE_MAC)) {
+ usrv.sv_minlvl = SYSLOW;
+ usrv.sv_actlvl = SYSHIGH;
+ usrv.sv_maxlvl = SYSHIGH;
+ } else {
+ usrv.sv_minlvl = sysv.sy_minlvl;
+ usrv.sv_actlvl = sysv.sy_minlvl;
+ usrv.sv_maxlvl = sysv.sy_maxlvl;
+ }
+ usrv.sv_actcmp = 0;
+ usrv.sv_valcmp = sysv.sy_valcmp;
+
+ usrv.sv_intcat = TFM_SYSTEM;
+ usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE);
- memset(&usrv, 0, sizeof(usrv));
if (setusrv(&usrv) < 0)
fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
strerror(errno));
@@ -189,7 +686,6 @@ cray_retain_utmp(struct utmp *ut, int pid)
while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
if (pid == utmp.ut_pid) {
ut->ut_jid = utmp.ut_jid;
- /* XXX: MIN_SIZEOF here? can this go in loginrec? */
strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
@@ -198,7 +694,8 @@ cray_retain_utmp(struct utmp *ut, int pid)
}
close(fd);
}
- /* XXX: error message? */
+ else
+ fatal("Unable to open utmp file");
}
/*
@@ -245,7 +742,7 @@ cray_job_termination_handler(int sig)
char *login = NULL;
struct jtab jtab;
- debug("Received SIG JOB.");
+ debug("received signal %d",sig);
if ((jid = waitjob(&jtab)) == -1 ||
(login = uid2nam(jtab.j_uid)) == NULL)
diff --git a/crypto/openssh/openbsd-compat/bsd-cray.h b/crypto/openssh/openbsd-compat/bsd-cray.h
index 9067a38..8868b43 100644
--- a/crypto/openssh/openbsd-compat/bsd-cray.h
+++ b/crypto/openssh/openbsd-compat/bsd-cray.h
@@ -1,5 +1,5 @@
/*
- * $Id: bsd-cray.h,v 1.3 2002/05/15 16:39:52 mouring Exp $
+ * $Id: bsd-cray.h,v 1.5 2002/09/26 00:38:51 tim Exp $
*
* bsd-cray.h
*
@@ -37,11 +37,18 @@
#ifndef _BSD_CRAY_H
#define _BSD_CRAY_H
-#ifdef _CRAY
-void cray_init_job(struct passwd *); /* init cray job */
-void cray_job_termination_handler(int); /* process end of job signal */
-void cray_setup(uid_t, char *); /* set cray limits */
+#ifdef _UNICOS
+void cray_init_job(struct passwd *); /* init cray job */
+void cray_job_termination_handler(int); /* process end of job signal */
+void cray_login_failure(char *username, int errcode);
+int cray_access_denied(char *username);
extern char cray_tmpdir[]; /* cray tmpdir */
+#ifndef IA_SSHD
+#define IA_SSHD IA_LOGIN
+#endif
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
#endif
#endif /* _BSD_CRAY_H */
diff --git a/crypto/openssh/openbsd-compat/bsd-getpeereid.c b/crypto/openssh/openbsd-compat/bsd-getpeereid.c
new file mode 100644
index 0000000..c787682
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/bsd-getpeereid.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002 Damien Miller. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "includes.h"
+
+RCSID("$Id: bsd-getpeereid.c,v 1.1 2002/09/12 00:33:02 djm Exp $");
+
+#if !defined(HAVE_GETPEEREID)
+
+#if defined(SO_PEERCRED)
+int
+getpeereid(int s, uid_t *euid, gid_t *gid)
+{
+ struct ucred cred;
+ size_t len = sizeof(cred);
+
+ if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
+ return (-1);
+ *euid = cred.uid;
+ *gid = cred.gid;
+
+ return (0);
+}
+#else
+int
+getpeereid(int s, uid_t *euid, gid_t *gid)
+{
+ *euid = geteuid();
+ *gid = getgid();
+
+ return (0);
+}
+#endif /* defined(SO_PEERCRED) */
+
+#endif /* !defined(HAVE_GETPEEREID) */
diff --git a/crypto/openssh/openbsd-compat/bsd-getpeereid.h b/crypto/openssh/openbsd-compat/bsd-getpeereid.h
new file mode 100644
index 0000000..2e9f077
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/bsd-getpeereid.h
@@ -0,0 +1,14 @@
+/* $Id: bsd-getpeereid.h,v 1.1 2002/09/12 00:33:02 djm Exp $ */
+
+#ifndef _BSD_GETPEEREID_H
+#define _BSD_GETPEEREID_H
+
+#include "config.h"
+
+#include <sys/types.h> /* For uid_t, gid_t */
+
+#ifndef HAVE_GETPEEREID
+int getpeereid(int , uid_t *, gid_t *);
+#endif /* HAVE_GETPEEREID */
+
+#endif /* _BSD_GETPEEREID_H */
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c
index fa48afe..1c1e43a 100644
--- a/crypto/openssh/openbsd-compat/bsd-misc.c
+++ b/crypto/openssh/openbsd-compat/bsd-misc.c
@@ -24,7 +24,7 @@
#include "includes.h"
-RCSID("$Id: bsd-misc.c,v 1.8 2002/06/13 21:34:58 mouring Exp $");
+RCSID("$Id: bsd-misc.c,v 1.10 2002/07/08 21:09:41 mouring Exp $");
char *get_progname(char *argv0)
{
@@ -93,8 +93,8 @@ int utimes(char *filename, struct timeval *tvp)
{
struct utimbuf ub;
- ub.actime = tvp->tv_sec;
- ub.modtime = tvp->tv_usec;
+ ub.actime = tvp[0].tv_sec;
+ ub.modtime = tvp[1].tv_sec;
return(utime(filename, &ub));
}
diff --git a/crypto/openssh/openbsd-compat/dirname.c b/crypto/openssh/openbsd-compat/dirname.c
index 391b2dd..35c7d8e 100644
--- a/crypto/openssh/openbsd-compat/dirname.c
+++ b/crypto/openssh/openbsd-compat/dirname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $ */
+/* $OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $ */
/*
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -31,7 +31,7 @@
#ifndef HAVE_DIRNAME
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $";
+static char rcsid[] = "$OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
#endif /* LIBC_SCCS and not lint */
#include <errno.h>
@@ -47,7 +47,7 @@ dirname(path)
/* Empty or NULL string gets treated as "." */
if (path == NULL || *path == '\0') {
- (void)strcpy(bname, ".");
+ (void)strlcpy(bname, ".", sizeof bname);
return(bname);
}
@@ -62,7 +62,7 @@ dirname(path)
/* Either the dir is "/" or there are no slashes */
if (endp == path) {
- (void)strcpy(bname, *endp == '/' ? "/" : ".");
+ (void)strlcpy(bname, *endp == '/' ? "/" : ".", sizeof bname);
return(bname);
} else {
do {
diff --git a/crypto/openssh/openbsd-compat/getcwd.c b/crypto/openssh/openbsd-compat/getcwd.c
index de3bacc..6fd8543 100644
--- a/crypto/openssh/openbsd-compat/getcwd.c
+++ b/crypto/openssh/openbsd-compat/getcwd.c
@@ -24,7 +24,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#if !defined(HAVE_GETCWD)
diff --git a/crypto/openssh/openbsd-compat/getopt.c b/crypto/openssh/openbsd-compat/getopt.c
index f4fbc9b..4a5cfe5 100644
--- a/crypto/openssh/openbsd-compat/getopt.c
+++ b/crypto/openssh/openbsd-compat/getopt.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c
index 365d433..e928a22 100644
--- a/crypto/openssh/openbsd-compat/glob.c
+++ b/crypto/openssh/openbsd-compat/glob.c
@@ -56,7 +56,7 @@ get_arg_max(void)
#if 0
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#else
-static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: glob.c,v 1.20 2002/06/14 21:34:58 todd Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -97,6 +97,7 @@ static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $
#define RBRACKET ']'
#define SEP '/'
#define STAR '*'
+#undef TILDE /* Some platforms may already define it */
#define TILDE '~'
#define UNDERSCORE '_'
#define LBRACE '{'
@@ -136,32 +137,32 @@ typedef char Char;
#define ismeta(c) (((c)&M_QUOTE) != 0)
-static int compare __P((const void *, const void *));
-static int g_Ctoc __P((const Char *, char *, u_int));
-static int g_lstat __P((Char *, struct stat *, glob_t *));
-static DIR *g_opendir __P((Char *, glob_t *));
-static Char *g_strchr __P((Char *, int));
-static int g_stat __P((Char *, struct stat *, glob_t *));
-static int glob0 __P((const Char *, glob_t *));
-static int glob1 __P((Char *, Char *, glob_t *, size_t *));
-static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *,
- glob_t *, size_t *));
-static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *,
- Char *, Char *, glob_t *, size_t *));
-static int globextend __P((const Char *, glob_t *, size_t *));
+static int compare(const void *, const void *);
+static int g_Ctoc(const Char *, char *, u_int);
+static int g_lstat(Char *, struct stat *, glob_t *);
+static DIR *g_opendir(Char *, glob_t *);
+static Char *g_strchr(Char *, int);
+static int g_stat(Char *, struct stat *, glob_t *);
+static int glob0(const Char *, glob_t *);
+static int glob1(Char *, Char *, glob_t *, size_t *);
+static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
+ glob_t *, size_t *);
+static int glob3(Char *, Char *, Char *, Char *, Char *, Char *,
+ Char *, Char *, glob_t *, size_t *);
+static int globextend(const Char *, glob_t *, size_t *);
static const Char *
- globtilde __P((const Char *, Char *, size_t, glob_t *));
-static int globexp1 __P((const Char *, glob_t *));
-static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
-static int match __P((Char *, Char *, Char *));
+ globtilde(const Char *, Char *, size_t, glob_t *);
+static int globexp1(const Char *, glob_t *);
+static int globexp2(const Char *, const Char *, glob_t *, int *);
+static int match(Char *, Char *, Char *);
#ifdef DEBUG
-static void qprintf __P((const char *, Char *));
+static void qprintf(const char *, Char *);
#endif
int
glob(pattern, flags, errfunc, pglob)
const char *pattern;
- int flags, (*errfunc) __P((const char *, int));
+ int flags, (*errfunc)(const char *, int);
glob_t *pglob;
{
const u_char *patnext;
@@ -676,7 +677,7 @@ glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last,
/*
- * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
@@ -821,7 +822,7 @@ g_opendir(str, pglob)
char buf[MAXPATHLEN];
if (!*str)
- strcpy(buf, ".");
+ strlcpy(buf, ".", sizeof buf);
else {
if (g_Ctoc(str, buf, sizeof(buf)))
return(NULL);
diff --git a/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h
index b4c8f7a..6421f70 100644
--- a/crypto/openssh/openbsd-compat/glob.h
+++ b/crypto/openssh/openbsd-compat/glob.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: glob.h,v 1.5 2001/03/18 17:18:58 deraadt Exp $ */
+/* $OpenBSD: glob.h,v 1.7 2002/02/17 19:42:21 millert Exp $ */
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
/*
@@ -53,18 +53,18 @@ typedef struct {
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
- int (*gl_errfunc) __P((const char *, int));
+ int (*gl_errfunc)(const char *, int);
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
- void (*gl_closedir) __P((void *));
- struct dirent *(*gl_readdir) __P((void *));
- void *(*gl_opendir) __P((const char *));
- int (*gl_lstat) __P((const char *, struct stat *));
- int (*gl_stat) __P((const char *, struct stat *));
+ void (*gl_closedir)(void *);
+ struct dirent *(*gl_readdir)(void *);
+ void *(*gl_opendir)(const char *);
+ int (*gl_lstat)(const char *, struct stat *);
+ int (*gl_stat)(const char *, struct stat *);
} glob_t;
/* Flags */
@@ -91,8 +91,8 @@ typedef struct {
#define GLOB_NOSYS (-4) /* Function not supported. */
#define GLOB_ABEND GLOB_ABORTED
-int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
-void globfree __P((glob_t *));
+int glob(const char *, int, int (*)(const char *, int), glob_t *);
+void globfree(glob_t *);
#endif /* !_GLOB_H_ */
diff --git a/crypto/openssh/openbsd-compat/inet_ntoa.c b/crypto/openssh/openbsd-compat/inet_ntoa.c
index 8a8b3c8..ac5f567 100644
--- a/crypto/openssh/openbsd-compat/inet_ntoa.c
+++ b/crypto/openssh/openbsd-compat/inet_ntoa.c
@@ -31,12 +31,12 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $";
+static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -57,7 +57,7 @@ char *inet_ntoa(struct in_addr in)
p = (char *)&in;
#define UC(b) (((int)b)&0xff)
(void)snprintf(b, sizeof(b),
- "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
+ "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
return (b);
}
diff --git a/crypto/openssh/openbsd-compat/inet_ntop.c b/crypto/openssh/openbsd-compat/inet_ntop.c
index 2b8d31f..3bea519 100644
--- a/crypto/openssh/openbsd-compat/inet_ntop.c
+++ b/crypto/openssh/openbsd-compat/inet_ntop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $ */
+/* $OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $ */
/* Copyright (c) 1996 by Internet Software Consortium.
*
@@ -16,7 +16,7 @@
* SOFTWARE.
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_INET_NTOP
@@ -24,7 +24,7 @@
#if 0
static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $";
+static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -54,8 +54,8 @@ static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Ex
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
-static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
-static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
/* char *
* inet_ntop(af, src, dst, size)
@@ -103,13 +103,14 @@ inet_ntop4(src, dst, size)
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
+ int l;
- if (snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2],
- src[3]) > size) {
+ l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
+ if (l <= 0 || l >= size) {
errno = ENOSPC;
return (NULL);
}
- strcpy(dst, tmp);
+ strlcpy(dst, tmp, size);
return (dst);
}
@@ -132,10 +133,12 @@ inet_ntop6(src, dst, size)
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
- char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ char *tp, *ep;
struct { int base, len; } best, cur;
u_int words[IN6ADDRSZ / INT16SZ];
int i;
+ int advance;
/*
* Preprocess:
@@ -172,31 +175,45 @@ inet_ntop6(src, dst, size)
* Format the result.
*/
tp = tmp;
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ ep = tmp + sizeof(tmp);
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
- if (i == best.base)
+ if (i == best.base) {
+ if (tp + 1 >= ep)
+ return (NULL);
*tp++ = ':';
+ }
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
- if (i != 0)
+ if (i != 0) {
+ if (tp + 1 >= ep)
+ return (NULL);
*tp++ = ':';
+ }
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
- if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+ if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
return (NULL);
tp += strlen(tp);
break;
}
- snprintf(tp, sizeof(tmp - (tp - tmp)), "%x", words[i]);
- tp += strlen(tp);
+ advance = snprintf(tp, ep - tp, "%x", words[i]);
+ if (advance <= 0 || advance >= ep - tp)
+ return (NULL);
+ tp += advance;
}
/* Was it a trailing run of 0x00's? */
- if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
+ if (tp + 1 >= ep)
+ return (NULL);
*tp++ = ':';
+ }
+ if (tp + 1 >= ep)
+ return (NULL);
*tp++ = '\0';
/*
@@ -206,7 +223,7 @@ inet_ntop6(src, dst, size)
errno = ENOSPC;
return (NULL);
}
- strcpy(dst, tmp);
+ strlcpy(dst, tmp, size);
return (dst);
}
diff --git a/crypto/openssh/openbsd-compat/mktemp.c b/crypto/openssh/openbsd-compat/mktemp.c
index d69dc5c..d256ee4 100644
--- a/crypto/openssh/openbsd-compat/mktemp.c
+++ b/crypto/openssh/openbsd-compat/mktemp.c
@@ -39,7 +39,7 @@
#ifndef HAVE_MKDTEMP
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: mktemp.c,v 1.14 2002/01/02 20:18:32 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: mktemp.c,v 1.16 2002/05/27 18:20:45 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#ifdef HAVE_CYGWIN
@@ -102,11 +102,11 @@ _gettemp(path, doopen, domkdir, slen)
return (0);
}
pid = getpid();
- while (*trv == 'X' && pid != 0) {
+ while (trv >= path && *trv == 'X' && pid != 0) {
*trv-- = (pid % 10) + '0';
pid /= 10;
}
- while (*trv == 'X') {
+ while (trv >= path && *trv == 'X') {
char c;
pid = (arc4random() & 0xffff) % (26+26);
diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
index 1191844..ae18afd 100644
--- a/crypto/openssh/openbsd-compat/openbsd-compat.h
+++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
-/* $Id: openbsd-compat.h,v 1.16 2002/02/19 20:27:57 mouring Exp $ */
+/* $Id: openbsd-compat.h,v 1.17 2002/09/12 00:33:02 djm Exp $ */
#ifndef _OPENBSD_H
#define _OPENBSD_H
@@ -29,6 +29,7 @@
/* Home grown routines */
#include "bsd-arc4random.h"
+#include "bsd-getpeereid.h"
#include "bsd-misc.h"
#include "bsd-snprintf.h"
#include "bsd-waitpid.h"
diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c
index ca0a88e..4c96a31 100644
--- a/crypto/openssh/openbsd-compat/port-aix.c
+++ b/crypto/openssh/openbsd-compat/port-aix.c
@@ -1,3 +1,28 @@
+/*
+ *
+ * Copyright (c) 2001 Gert Doering. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "includes.h"
#ifdef _AIX
@@ -6,21 +31,21 @@
#include <../xmalloc.h>
/*
- * AIX has a "usrinfo" area where logname and
- * other stuff is stored - a few applications
- * actually use this and die if it's not set
+ * AIX has a "usrinfo" area where logname and other stuff is stored -
+ * a few applications actually use this and die if it's not set
+ *
+ * NOTE: TTY= should be set, but since no one uses it and it's hard to
+ * acquire due to privsep code. We will just drop support.
*/
void
-aix_usrinfo(struct passwd *pw, char *tty, int ttyfd)
+aix_usrinfo(struct passwd *pw)
{
u_int i;
- char *cp=NULL;
+ char *cp;
- if (ttyfd == -1)
- tty[0] = '\0';
- cp = xmalloc(22 + strlen(tty) + 2 * strlen(pw->pw_name));
- i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c", pw->pw_name, 0,
- pw->pw_name, 0, tty, 0, 0);
+ cp = xmalloc(16 + 2 * strlen(pw->pw_name));
+ i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0,
+ pw->pw_name, 0);
if (usrinfo(SETUINFO, cp, i) == -1)
fatal("Couldn't set usrinfo: %s", strerror(errno));
debug3("AIX/UsrInfo: set len %d", i);
diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h
index e4d14f4..79570a2 100644
--- a/crypto/openssh/openbsd-compat/port-aix.h
+++ b/crypto/openssh/openbsd-compat/port-aix.h
@@ -1,5 +1,29 @@
-#ifdef _AIX
-
-void aix_usrinfo(struct passwd *pw, char *tty, int ttyfd);
+/*
+ *
+ * Copyright (c) 2001 Gert Doering. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _AIX
+void aix_usrinfo(struct passwd *pw);
#endif /* _AIX */
diff --git a/crypto/openssh/openbsd-compat/readpassphrase.c b/crypto/openssh/openbsd-compat/readpassphrase.c
index 8c2f5f8..4e549b6 100644
--- a/crypto/openssh/openbsd-compat/readpassphrase.c
+++ b/crypto/openssh/openbsd-compat/readpassphrase.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ */
+/* $OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $ */
/*
- * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $";
+static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include "includes.h"
@@ -60,8 +60,8 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
int input, output, save_errno;
char ch, *p, *end;
struct termios term, oterm;
- struct sigaction sa, saveint, savehup, savequit, saveterm;
- struct sigaction savetstp, savettin, savettou;
+ struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
+ struct sigaction savetstp, savettin, savettou, savepipe;
/* I suppose we could alloc on demand in this case (XXX). */
if (bufsiz == 0) {
@@ -70,11 +70,13 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
}
restart:
+ signo = 0;
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
*/
- if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) {
+ if ((flags & RPP_STDIN) ||
+ (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
if (flags & RPP_REQUIRE_TTY) {
errno = ENOTTY;
return(NULL);
@@ -86,13 +88,15 @@ restart:
/*
* Catch signals that would otherwise cause the user to end
* up with echo turned off in the shell. Don't worry about
- * things like SIGALRM and SIGPIPE for now.
+ * things like SIGXCPU and SIGVTALRM for now.
*/
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0; /* don't restart system calls */
sa.sa_handler = handler;
- (void)sigaction(SIGINT, &sa, &saveint);
+ (void)sigaction(SIGALRM, &sa, &savealrm);
(void)sigaction(SIGHUP, &sa, &savehup);
+ (void)sigaction(SIGINT, &sa, &saveint);
+ (void)sigaction(SIGPIPE, &sa, &savepipe);
(void)sigaction(SIGQUIT, &sa, &savequit);
(void)sigaction(SIGTERM, &sa, &saveterm);
(void)sigaction(SIGTSTP, &sa, &savetstp);
@@ -100,7 +104,7 @@ restart:
(void)sigaction(SIGTTOU, &sa, &savettou);
/* Turn off echo if possible. */
- if (tcgetattr(input, &oterm) == 0) {
+ if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
memcpy(&term, &oterm, sizeof(term));
if (!(flags & RPP_ECHO_ON))
term.c_lflag &= ~(ECHO | ECHONL);
@@ -111,10 +115,13 @@ restart:
(void)tcsetattr(input, _T_FLUSH, &term);
} else {
memset(&term, 0, sizeof(term));
+ term.c_lflag |= ECHO;
memset(&oterm, 0, sizeof(oterm));
+ oterm.c_lflag |= ECHO;
}
- (void)write(output, prompt, strlen(prompt));
+ if (!(flags & RPP_STDIN))
+ (void)write(output, prompt, strlen(prompt));
end = buf + bufsiz - 1;
for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
if (p < end) {
@@ -137,13 +144,14 @@ restart:
/* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0)
(void)tcsetattr(input, _T_FLUSH, &oterm);
- (void)sigaction(SIGINT, &saveint, NULL);
+ (void)sigaction(SIGALRM, &savealrm, NULL);
(void)sigaction(SIGHUP, &savehup, NULL);
+ (void)sigaction(SIGINT, &saveint, NULL);
(void)sigaction(SIGQUIT, &savequit, NULL);
+ (void)sigaction(SIGPIPE, &savepipe, NULL);
(void)sigaction(SIGTERM, &saveterm, NULL);
(void)sigaction(SIGTSTP, &savetstp, NULL);
(void)sigaction(SIGTTIN, &savettin, NULL);
- (void)sigaction(SIGTTOU, &savettou, NULL);
if (input != STDIN_FILENO)
(void)close(input);
@@ -152,12 +160,11 @@ restart:
* now that we have restored the signal handlers.
*/
if (signo) {
- kill(getpid(), signo);
+ kill(getpid(), signo);
switch (signo) {
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
- signo = 0;
goto restart;
}
}
diff --git a/crypto/openssh/openbsd-compat/readpassphrase.h b/crypto/openssh/openbsd-compat/readpassphrase.h
index 9077b6e..92908a4 100644
--- a/crypto/openssh/openbsd-compat/readpassphrase.h
+++ b/crypto/openssh/openbsd-compat/readpassphrase.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ */
+/* $OpenBSD: readpassphrase.h,v 1.3 2002/06/28 12:32:22 millert Exp $ */
/*
* Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -40,8 +40,9 @@
#define RPP_FORCELOWER 0x04 /* Force input to lower case. */
#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */
#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
+#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */
-char *readpassphrase(const char *, char *, size_t, int);
+char * readpassphrase(const char *, char *, size_t, int);
#endif /* HAVE_READPASSPHRASE */
diff --git a/crypto/openssh/openbsd-compat/realpath.c b/crypto/openssh/openbsd-compat/realpath.c
index b4a05db..b9035ca 100644
--- a/crypto/openssh/openbsd-compat/realpath.c
+++ b/crypto/openssh/openbsd-compat/realpath.c
@@ -32,7 +32,7 @@
#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: realpath.c,v 1.6 2002/01/12 16:24:35 millert Exp $";
+static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -69,7 +69,7 @@ realpath(const char *path, char *resolved)
/* Save the starting point. */
getcwd(start,MAXPATHLEN);
if ((fd = open(".", O_RDONLY)) < 0) {
- (void)strcpy(resolved, ".");
+ (void)strlcpy(resolved, ".", MAXPATHLEN);
return (NULL);
}
close(fd);
@@ -129,7 +129,7 @@ loop:
* Save the last component name and get the full pathname of
* the current directory.
*/
- (void)strcpy(wbuf, p);
+ (void)strlcpy(wbuf, p, sizeof wbuf);
if (getcwd(resolved, MAXPATHLEN) == 0)
goto err1;
diff --git a/crypto/openssh/openbsd-compat/rresvport.c b/crypto/openssh/openbsd-compat/rresvport.c
index 44eac20..9f05896 100644
--- a/crypto/openssh/openbsd-compat/rresvport.c
+++ b/crypto/openssh/openbsd-compat/rresvport.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_RRESVPORT_AF
diff --git a/crypto/openssh/openbsd-compat/setenv.c b/crypto/openssh/openbsd-compat/setenv.c
index 6c2d5cd..1dff15c 100644
--- a/crypto/openssh/openbsd-compat/setenv.c
+++ b/crypto/openssh/openbsd-compat/setenv.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_SETENV
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/crypto/openssh/openbsd-compat/sigact.c b/crypto/openssh/openbsd-compat/sigact.c
index 806eb02..35fbab0 100644
--- a/crypto/openssh/openbsd-compat/sigact.c
+++ b/crypto/openssh/openbsd-compat/sigact.c
@@ -33,7 +33,7 @@
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
****************************************************************************/
-#include "config.h"
+#include "includes.h"
#include <signal.h>
#include "sigact.h"
diff --git a/crypto/openssh/openbsd-compat/strlcat.c b/crypto/openssh/openbsd-compat/strlcat.c
index 6ff65c1..3a9b5d1 100644
--- a/crypto/openssh/openbsd-compat/strlcat.c
+++ b/crypto/openssh/openbsd-compat/strlcat.c
@@ -27,7 +27,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_STRLCAT
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/crypto/openssh/openbsd-compat/strlcpy.c b/crypto/openssh/openbsd-compat/strlcpy.c
index b5e5a55..2f87eca 100644
--- a/crypto/openssh/openbsd-compat/strlcpy.c
+++ b/crypto/openssh/openbsd-compat/strlcpy.c
@@ -27,7 +27,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#ifndef HAVE_STRLCPY
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/crypto/openssh/openbsd-compat/strsep.c b/crypto/openssh/openbsd-compat/strsep.c
index c03649c..d0afc44 100644
--- a/crypto/openssh/openbsd-compat/strsep.c
+++ b/crypto/openssh/openbsd-compat/strsep.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include "includes.h"
#if !defined(HAVE_STRSEP)
diff --git a/crypto/openssh/openbsd-compat/sys-queue.h b/crypto/openssh/openbsd-compat/sys-queue.h
new file mode 100644
index 0000000..176fe31
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/sys-queue.h
@@ -0,0 +1,584 @@
+/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */
+/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 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. 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.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _FAKE_QUEUE_H_
+#define _FAKE_QUEUE_H_
+
+/*
+ * Ignore all <sys/queue.h> since older platforms have broken/incomplete
+ * <sys/queue.h> that are too hard to work around.
+ */
+#undef SLIST_HEAD
+#undef SLIST_HEAD_INITIALIZER
+#undef SLIST_ENTRY
+#undef SLIST_FIRST
+#undef SLIST_END
+#undef SLIST_EMPTY
+#undef SLIST_NEXT
+#undef SLIST_FOREACH
+#undef SLIST_INIT
+#undef SLIST_INSERT_AFTER
+#undef SLIST_INSERT_HEAD
+#undef SLIST_REMOVE_HEAD
+#undef SLIST_REMOVE
+#undef LIST_HEAD
+#undef LIST_HEAD_INITIALIZER
+#undef LIST_ENTRY
+#undef LIST_FIRST
+#undef LIST_END
+#undef LIST_EMPTY
+#undef LIST_NEXT
+#undef LIST_FOREACH
+#undef LIST_INIT
+#undef LIST_INSERT_AFTER
+#undef LIST_INSERT_BEFORE
+#undef LIST_INSERT_HEAD
+#undef LIST_REMOVE
+#undef LIST_REPLACE
+#undef SIMPLEQ_HEAD
+#undef SIMPLEQ_HEAD_INITIALIZER
+#undef SIMPLEQ_ENTRY
+#undef SIMPLEQ_FIRST
+#undef SIMPLEQ_END
+#undef SIMPLEQ_EMPTY
+#undef SIMPLEQ_NEXT
+#undef SIMPLEQ_FOREACH
+#undef SIMPLEQ_INIT
+#undef SIMPLEQ_INSERT_HEAD
+#undef SIMPLEQ_INSERT_TAIL
+#undef SIMPLEQ_INSERT_AFTER
+#undef SIMPLEQ_REMOVE_HEAD
+#undef TAILQ_HEAD
+#undef TAILQ_HEAD_INITIALIZER
+#undef TAILQ_ENTRY
+#undef TAILQ_FIRST
+#undef TAILQ_END
+#undef TAILQ_NEXT
+#undef TAILQ_LAST
+#undef TAILQ_PREV
+#undef TAILQ_EMPTY
+#undef TAILQ_FOREACH
+#undef TAILQ_FOREACH_REVERSE
+#undef TAILQ_INIT
+#undef TAILQ_INSERT_HEAD
+#undef TAILQ_INSERT_TAIL
+#undef TAILQ_INSERT_AFTER
+#undef TAILQ_INSERT_BEFORE
+#undef TAILQ_REMOVE
+#undef TAILQ_REPLACE
+#undef CIRCLEQ_HEAD
+#undef CIRCLEQ_HEAD_INITIALIZER
+#undef CIRCLEQ_ENTRY
+#undef CIRCLEQ_FIRST
+#undef CIRCLEQ_LAST
+#undef CIRCLEQ_END
+#undef CIRCLEQ_NEXT
+#undef CIRCLEQ_PREV
+#undef CIRCLEQ_EMPTY
+#undef CIRCLEQ_FOREACH
+#undef CIRCLEQ_FOREACH_REVERSE
+#undef CIRCLEQ_INIT
+#undef CIRCLEQ_INSERT_AFTER
+#undef CIRCLEQ_INSERT_BEFORE
+#undef CIRCLEQ_INSERT_HEAD
+#undef CIRCLEQ_INSERT_TAIL
+#undef CIRCLEQ_REMOVE
+#undef CIRCLEQ_REPLACE
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_END(head) NULL
+#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = SLIST_FIRST(head); \
+ (var) != SLIST_END(head); \
+ (var) = SLIST_NEXT(var, field))
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) { \
+ SLIST_FIRST(head) = SLIST_END(head); \
+}
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while( curelm->field.sle_next != (elm) ) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List access methods
+ */
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_END(head) NULL
+#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_FOREACH(var, head, field) \
+ for((var) = LIST_FIRST(head); \
+ (var)!= LIST_END(head); \
+ (var) = LIST_NEXT(var, field))
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do { \
+ LIST_FIRST(head) = LIST_END(head); \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+#define LIST_REPLACE(elm, elm2, field) do { \
+ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
+ (elm2)->field.le_next->field.le_prev = \
+ &(elm2)->field.le_next; \
+ (elm2)->field.le_prev = (elm)->field.le_prev; \
+ *(elm2)->field.le_prev = (elm2); \
+} while (0)
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_END(head) NULL
+#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for((var) = SIMPLEQ_FIRST(head); \
+ (var) != SIMPLEQ_END(head); \
+ (var) = SIMPLEQ_NEXT(var, field))
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
+ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+
+/*
+ * tail queue access methods
+ */
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_END(head) NULL
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+/* XXX */
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define TAILQ_EMPTY(head) \
+ (TAILQ_FIRST(head) == TAILQ_END(head))
+
+#define TAILQ_FOREACH(var, head, field) \
+ for((var) = TAILQ_FIRST(head); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_NEXT(var, field))
+
+#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
+ for((var) = TAILQ_LAST(head, headname); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_PREV(var, headname, field))
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
+ (elm2)->field.tqe_next->field.tqe_prev = \
+ &(elm2)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm2)->field.tqe_next; \
+ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
+ *(elm2)->field.tqe_prev = (elm2); \
+} while (0)
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue access methods
+ */
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_END(head) ((void *)(head))
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+#define CIRCLEQ_EMPTY(head) \
+ (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = CIRCLEQ_FIRST(head); \
+ (var) != CIRCLEQ_END(head); \
+ (var) = CIRCLEQ_NEXT(var, field))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for((var) = CIRCLEQ_LAST(head); \
+ (var) != CIRCLEQ_END(head); \
+ (var) = CIRCLEQ_PREV(var, field))
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = CIRCLEQ_END(head); \
+ (head)->cqh_last = CIRCLEQ_END(head); \
+} while (0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = CIRCLEQ_END(head); \
+ if ((head)->cqh_last == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = CIRCLEQ_END(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (0)
+
+#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
+ CIRCLEQ_END(head)) \
+ (head).cqh_last = (elm2); \
+ else \
+ (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
+ if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
+ CIRCLEQ_END(head)) \
+ (head).cqh_first = (elm2); \
+ else \
+ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
+} while (0)
+
+#endif /* !_FAKE_QUEUE_H_ */
diff --git a/crypto/openssh/openbsd-compat/sys-tree.h b/crypto/openssh/openbsd-compat/sys-tree.h
new file mode 100644
index 0000000..0a58710
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/sys-tree.h
@@ -0,0 +1,675 @@
+/* $OpenBSD: tree.h,v 1.6 2002/06/11 22:09:52 provos Exp $ */
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#ifndef _SYS_TREE_H_
+#define _SYS_TREE_H_
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure. Every operation
+ * on the tree causes a splay to happen. The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree. On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n). The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute. It fulfills a set of conditions:
+ * - every search path from the root to a leaf consists of the
+ * same number of black nodes,
+ * - each red node (except for the root) has a black parent,
+ * - each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type) \
+struct name { \
+ struct type *sph_root; /* root of the tree */ \
+}
+
+#define SPLAY_INITIALIZER(root) \
+ { NULL }
+
+#define SPLAY_INIT(root) do { \
+ (root)->sph_root = NULL; \
+} while (0)
+
+#define SPLAY_ENTRY(type) \
+struct { \
+ struct type *spe_left; /* left element */ \
+ struct type *spe_right; /* right element */ \
+}
+
+#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
+#define SPLAY_ROOT(head) (head)->sph_root
+#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do { \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+} while (0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do { \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+} while (0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
+ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
+} while (0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp) \
+void name##_SPLAY(struct name *, struct type *); \
+void name##_SPLAY_MINMAX(struct name *, int); \
+struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
+ \
+/* Finds the node with the same key as elm */ \
+static __inline struct type * \
+name##_SPLAY_FIND(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) \
+ return(NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) \
+ return (head->sph_root); \
+ return (NULL); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_NEXT(struct name *head, struct type *elm) \
+{ \
+ name##_SPLAY(head, elm); \
+ if (SPLAY_RIGHT(elm, field) != NULL) { \
+ elm = SPLAY_RIGHT(elm, field); \
+ while (SPLAY_LEFT(elm, field) != NULL) { \
+ elm = SPLAY_LEFT(elm, field); \
+ } \
+ } else \
+ elm = NULL; \
+ return (elm); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_MIN_MAX(struct name *head, int val) \
+{ \
+ name##_SPLAY_MINMAX(head, val); \
+ return (SPLAY_ROOT(head)); \
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp) \
+struct type * \
+name##_SPLAY_INSERT(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) { \
+ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
+ } else { \
+ int __comp; \
+ name##_SPLAY(head, elm); \
+ __comp = (cmp)(elm, (head)->sph_root); \
+ if(__comp < 0) { \
+ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
+ SPLAY_RIGHT(elm, field) = (head)->sph_root; \
+ SPLAY_LEFT((head)->sph_root, field) = NULL; \
+ } else if (__comp > 0) { \
+ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
+ SPLAY_LEFT(elm, field) = (head)->sph_root; \
+ SPLAY_RIGHT((head)->sph_root, field) = NULL; \
+ } else \
+ return ((head)->sph_root); \
+ } \
+ (head)->sph_root = (elm); \
+ return (NULL); \
+} \
+ \
+struct type * \
+name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *__tmp; \
+ if (SPLAY_EMPTY(head)) \
+ return (NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) { \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
+ } else { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
+ name##_SPLAY(head, elm); \
+ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
+ } \
+ return (elm); \
+ } \
+ return (NULL); \
+} \
+ \
+void \
+name##_SPLAY(struct name *head, struct type *elm) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+ int __comp; \
+\
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+ __left = __right = &__node; \
+\
+ while ((__comp = (cmp)(elm, (head)->sph_root))) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) > 0){ \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+} \
+ \
+/* Splay with either the minimum or the maximum element \
+ * Used to find minimum or maximum element in tree. \
+ */ \
+void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+\
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+ __left = __right = &__node; \
+\
+ while (1) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp > 0) { \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+}
+
+#define SPLAY_NEGINF -1
+#define SPLAY_INF 1
+
+#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head) \
+ for ((x) = SPLAY_MIN(name, head); \
+ (x) != NULL; \
+ (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-back tree */
+#define RB_HEAD(name, type) \
+struct name { \
+ struct type *rbh_root; /* root of the tree */ \
+}
+
+#define RB_INITIALIZER(root) \
+ { NULL }
+
+#define RB_INIT(root) do { \
+ (root)->rbh_root = NULL; \
+} while (0)
+
+#define RB_BLACK 0
+#define RB_RED 1
+#define RB_ENTRY(type) \
+struct { \
+ struct type *rbe_left; /* left element */ \
+ struct type *rbe_right; /* right element */ \
+ struct type *rbe_parent; /* parent element */ \
+ int rbe_color; /* node color */ \
+}
+
+#define RB_LEFT(elm, field) (elm)->field.rbe_left
+#define RB_RIGHT(elm, field) (elm)->field.rbe_right
+#define RB_PARENT(elm, field) (elm)->field.rbe_parent
+#define RB_COLOR(elm, field) (elm)->field.rbe_color
+#define RB_ROOT(head) (head)->rbh_root
+#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do { \
+ RB_PARENT(elm, field) = parent; \
+ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
+ RB_COLOR(elm, field) = RB_RED; \
+} while (0)
+
+#define RB_SET_BLACKRED(black, red, field) do { \
+ RB_COLOR(black, field) = RB_BLACK; \
+ RB_COLOR(red, field) = RB_RED; \
+} while (0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
+ (tmp) = RB_RIGHT(elm, field); \
+ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
+ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ RB_AUGMENT(RB_PARENT(elm, field)); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_LEFT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+} while (0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
+ (tmp) = RB_LEFT(elm, field); \
+ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
+ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ RB_AUGMENT(RB_PARENT(elm, field)); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_RIGHT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+} while (0)
+
+/* Generates prototypes and inline functions */
+#define RB_PROTOTYPE(name, type, field, cmp) \
+void name##_RB_INSERT_COLOR(struct name *, struct type *); \
+void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+struct type *name##_RB_REMOVE(struct name *, struct type *); \
+struct type *name##_RB_INSERT(struct name *, struct type *); \
+struct type *name##_RB_FIND(struct name *, struct type *); \
+struct type *name##_RB_NEXT(struct name *, struct type *); \
+struct type *name##_RB_MINMAX(struct name *, int); \
+ \
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define RB_GENERATE(name, type, field, cmp) \
+void \
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
+{ \
+ struct type *parent, *gparent, *tmp; \
+ while ((parent = RB_PARENT(elm, field)) && \
+ RB_COLOR(parent, field) == RB_RED) { \
+ gparent = RB_PARENT(parent, field); \
+ if (parent == RB_LEFT(gparent, field)) { \
+ tmp = RB_RIGHT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field);\
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_RIGHT(parent, field) == elm) { \
+ RB_ROTATE_LEFT(head, parent, tmp, field);\
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_RIGHT(head, gparent, tmp, field); \
+ } else { \
+ tmp = RB_LEFT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field);\
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_LEFT(parent, field) == elm) { \
+ RB_ROTATE_RIGHT(head, parent, tmp, field);\
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_LEFT(head, gparent, tmp, field); \
+ } \
+ } \
+ RB_COLOR(head->rbh_root, field) = RB_BLACK; \
+} \
+ \
+void \
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
+{ \
+ struct type *tmp; \
+ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
+ elm != RB_ROOT(head)) { \
+ if (RB_LEFT(parent, field) == elm) { \
+ tmp = RB_RIGHT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_LEFT(head, parent, tmp, field);\
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
+ struct type *oleft; \
+ if ((oleft = RB_LEFT(tmp, field)))\
+ RB_COLOR(oleft, field) = RB_BLACK;\
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_RIGHT(head, tmp, oleft, field);\
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_RIGHT(tmp, field)) \
+ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
+ RB_ROTATE_LEFT(head, parent, tmp, field);\
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } else { \
+ tmp = RB_LEFT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_RIGHT(head, parent, tmp, field);\
+ tmp = RB_LEFT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
+ struct type *oright; \
+ if ((oright = RB_RIGHT(tmp, field)))\
+ RB_COLOR(oright, field) = RB_BLACK;\
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_LEFT(head, tmp, oright, field);\
+ tmp = RB_LEFT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_LEFT(tmp, field)) \
+ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
+ RB_ROTATE_RIGHT(head, parent, tmp, field);\
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } \
+ } \
+ if (elm) \
+ RB_COLOR(elm, field) = RB_BLACK; \
+} \
+ \
+struct type * \
+name##_RB_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *child, *parent, *old = elm; \
+ int color; \
+ if (RB_LEFT(elm, field) == NULL) \
+ child = RB_RIGHT(elm, field); \
+ else if (RB_RIGHT(elm, field) == NULL) \
+ child = RB_LEFT(elm, field); \
+ else { \
+ struct type *left; \
+ elm = RB_RIGHT(elm, field); \
+ while ((left = RB_LEFT(elm, field))) \
+ elm = left; \
+ child = RB_RIGHT(elm, field); \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+ if (RB_PARENT(elm, field) == old) \
+ parent = elm; \
+ (elm)->field = (old)->field; \
+ if (RB_PARENT(old, field)) { \
+ if (RB_LEFT(RB_PARENT(old, field), field) == old)\
+ RB_LEFT(RB_PARENT(old, field), field) = elm;\
+ else \
+ RB_RIGHT(RB_PARENT(old, field), field) = elm;\
+ RB_AUGMENT(RB_PARENT(old, field)); \
+ } else \
+ RB_ROOT(head) = elm; \
+ RB_PARENT(RB_LEFT(old, field), field) = elm; \
+ if (RB_RIGHT(old, field)) \
+ RB_PARENT(RB_RIGHT(old, field), field) = elm; \
+ if (parent) { \
+ left = parent; \
+ do { \
+ RB_AUGMENT(left); \
+ } while ((left = RB_PARENT(left, field))); \
+ } \
+ goto color; \
+ } \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+color: \
+ if (color == RB_BLACK) \
+ name##_RB_REMOVE_COLOR(head, parent, child); \
+ return (old); \
+} \
+ \
+/* Inserts a node into the RB tree */ \
+struct type * \
+name##_RB_INSERT(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp; \
+ struct type *parent = NULL; \
+ int comp = 0; \
+ tmp = RB_ROOT(head); \
+ while (tmp) { \
+ parent = tmp; \
+ comp = (cmp)(elm, parent); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ RB_SET(elm, parent, field); \
+ if (parent != NULL) { \
+ if (comp < 0) \
+ RB_LEFT(parent, field) = elm; \
+ else \
+ RB_RIGHT(parent, field) = elm; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = elm; \
+ name##_RB_INSERT_COLOR(head, elm); \
+ return (NULL); \
+} \
+ \
+/* Finds the node with the same key as elm */ \
+struct type * \
+name##_RB_FIND(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ int comp; \
+ while (tmp) { \
+ comp = cmp(elm, tmp); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ return (NULL); \
+} \
+ \
+struct type * \
+name##_RB_NEXT(struct name *head, struct type *elm) \
+{ \
+ if (RB_RIGHT(elm, field)) { \
+ elm = RB_RIGHT(elm, field); \
+ while (RB_LEFT(elm, field)) \
+ elm = RB_LEFT(elm, field); \
+ } else { \
+ if (RB_PARENT(elm, field) && \
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ else { \
+ while (RB_PARENT(elm, field) && \
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
+ elm = RB_PARENT(elm, field); \
+ elm = RB_PARENT(elm, field); \
+ } \
+ } \
+ return (elm); \
+} \
+ \
+struct type * \
+name##_RB_MINMAX(struct name *head, int val) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ struct type *parent = NULL; \
+ while (tmp) { \
+ parent = tmp; \
+ if (val < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else \
+ tmp = RB_RIGHT(tmp, field); \
+ } \
+ return (parent); \
+}
+
+#define RB_NEGINF -1
+#define RB_INF 1
+
+#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
+#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y)
+#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head) \
+ for ((x) = RB_MIN(name, head); \
+ (x) != NULL; \
+ (x) = name##_RB_NEXT(head, x))
+
+#endif /* _SYS_TREE_H_ */
diff --git a/crypto/openssh/openbsd-compat/xmmap.c b/crypto/openssh/openbsd-compat/xmmap.c
new file mode 100644
index 0000000..8f1d202
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/xmmap.c
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "includes.h"
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include "log.h"
+
+void *xmmap(size_t size)
+{
+ void *address;
+
+#ifdef HAVE_MMAP
+# ifdef MAP_ANON
+ address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
+ -1, 0);
+# else
+ address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
+ open("/dev/zero", O_RDWR), 0);
+# endif
+
+#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX"
+ if (address == MAP_FAILED) {
+ char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE;
+ int tmpfd;
+
+ tmpfd = mkstemp(tmpname);
+ if (tmpfd == -1)
+ fatal("mkstemp(\"%s\"): %s",
+ MM_SWAP_TEMPLATE, strerror(errno));
+ unlink(tmpname);
+ ftruncate(tmpfd, size);
+ address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
+ tmpfd, 0);
+ close(tmpfd);
+ }
+
+ return (address);
+#else
+ fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
+ __func__);
+#endif /* HAVE_MMAP */
+
+}
+
diff --git a/crypto/openssh/openbsd-compat/xmmap.h b/crypto/openssh/openbsd-compat/xmmap.h
new file mode 100644
index 0000000..c0fa04a
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/xmmap.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+void *xmmap(size_t size);
OpenPOWER on IntegriCloud