summaryrefslogtreecommitdiff
path: root/openbsd-compat
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat')
-rw-r--r--openbsd-compat/Makefile.in4
-rw-r--r--openbsd-compat/base64.c5
-rw-r--r--openbsd-compat/bindresvport.c2
-rw-r--r--openbsd-compat/bsd-cray.c613
-rw-r--r--openbsd-compat/bsd-cray.h17
-rw-r--r--openbsd-compat/bsd-getpeereid.c56
-rw-r--r--openbsd-compat/bsd-getpeereid.h14
-rw-r--r--openbsd-compat/bsd-misc.c6
-rw-r--r--openbsd-compat/dirname.c8
-rw-r--r--openbsd-compat/getcwd.c2
-rw-r--r--openbsd-compat/getopt.c2
-rw-r--r--openbsd-compat/glob.c45
-rw-r--r--openbsd-compat/glob.h18
-rw-r--r--openbsd-compat/inet_ntoa.c6
-rw-r--r--openbsd-compat/inet_ntop.c51
-rw-r--r--openbsd-compat/mktemp.c6
-rw-r--r--openbsd-compat/openbsd-compat.h3
-rw-r--r--openbsd-compat/port-aix.c45
-rw-r--r--openbsd-compat/port-aix.h30
-rw-r--r--openbsd-compat/readpassphrase.c35
-rw-r--r--openbsd-compat/readpassphrase.h5
-rw-r--r--openbsd-compat/realpath.c6
-rw-r--r--openbsd-compat/rresvport.c2
-rw-r--r--openbsd-compat/setenv.c2
-rw-r--r--openbsd-compat/sigact.c2
-rw-r--r--openbsd-compat/strlcat.c2
-rw-r--r--openbsd-compat/strlcpy.c2
-rw-r--r--openbsd-compat/strsep.c2
-rw-r--r--openbsd-compat/sys-queue.h584
-rw-r--r--openbsd-compat/sys-tree.h675
-rw-r--r--openbsd-compat/xmmap.c67
-rw-r--r--openbsd-compat/xmmap.h23
32 files changed, 2170 insertions, 170 deletions
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 3e09cfefe..5229e7e20 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.21 2002/02/19 20:27:57 mouring Exp $ 1# $Id: Makefile.in,v 1.23 2002/09/12 00:33:02 djm Exp $
2 2
3sysconfdir=@sysconfdir@ 3sysconfdir=@sysconfdir@
4piddir=@piddir@ 4piddir=@piddir@
@@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@
18 18
19OPENBSD=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 19OPENBSD=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
20 20
21COMPAT=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 21COMPAT=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
22 22
23PORTS=port-irix.o port-aix.o 23PORTS=port-irix.o port-aix.o
24 24
diff --git a/openbsd-compat/base64.c b/openbsd-compat/base64.c
index d12b993b7..005170b80 100644
--- a/openbsd-compat/base64.c
+++ b/openbsd-compat/base64.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */ 1/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 by Internet Software Consortium. 4 * Copyright (c) 1996 by Internet Software Consortium.
@@ -42,7 +42,7 @@
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include "config.h" 45#include "includes.h"
46 46
47#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) 47#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)
48 48
@@ -60,6 +60,7 @@
60 60
61#include "base64.h" 61#include "base64.h"
62 62
63/* XXX abort illegal in library */
63#define Assert(Cond) if (!(Cond)) abort() 64#define Assert(Cond) if (!(Cond)) abort()
64 65
65static const char Base64[] = 66static const char Base64[] =
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c
index 332bcb016..620f980ed 100644
--- a/openbsd-compat/bindresvport.c
+++ b/openbsd-compat/bindresvport.c
@@ -29,7 +29,7 @@
29 * Mountain View, California 94043 29 * Mountain View, California 94043
30 */ 30 */
31 31
32#include "config.h" 32#include "includes.h"
33 33
34#ifndef HAVE_BINDRESVPORT_SA 34#ifndef HAVE_BINDRESVPORT_SA
35 35
diff --git a/openbsd-compat/bsd-cray.c b/openbsd-compat/bsd-cray.c
index 9bab75b41..edb3112b3 100644
--- a/openbsd-compat/bsd-cray.c
+++ b/openbsd-compat/bsd-cray.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: bsd-cray.c,v 1.6 2002/05/15 16:39:51 mouring Exp $ 2 * $Id: bsd-cray.c,v 1.8 2002/09/26 00:38:51 tim Exp $
3 * 3 *
4 * bsd-cray.c 4 * bsd-cray.c
5 * 5 *
@@ -34,8 +34,8 @@
34 * on UNICOS systems. 34 * on UNICOS systems.
35 * 35 *
36 */ 36 */
37#ifdef _UNICOS
37 38
38#ifdef _CRAY
39#include <udb.h> 39#include <udb.h>
40#include <tmpdir.h> 40#include <tmpdir.h>
41#include <unistd.h> 41#include <unistd.h>
@@ -45,19 +45,33 @@
45#include <signal.h> 45#include <signal.h>
46#include <sys/priv.h> 46#include <sys/priv.h>
47#include <sys/secparm.h> 47#include <sys/secparm.h>
48#include <sys/tfm.h>
48#include <sys/usrv.h> 49#include <sys/usrv.h>
49#include <sys/sysv.h> 50#include <sys/sysv.h>
50#include <sys/sectab.h> 51#include <sys/sectab.h>
52#include <sys/secstat.h>
51#include <sys/stat.h> 53#include <sys/stat.h>
54#include <sys/session.h>
52#include <stdlib.h> 55#include <stdlib.h>
53#include <pwd.h> 56#include <pwd.h>
54#include <fcntl.h> 57#include <fcntl.h>
55#include <errno.h> 58#include <errno.h>
56 59#include <ia.h>
60#include <urm.h>
61#include "ssh.h"
62#include "log.h"
63#include "servconf.h"
57#include "bsd-cray.h" 64#include "bsd-cray.h"
58 65
66#define MAXACID 80
67
68extern ServerOptions options;
69
59char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ 70char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */
60 71
72struct sysv sysv; /* system security structure */
73struct usrv usrv; /* user security structure */
74
61/* 75/*
62 * Functions. 76 * Functions.
63 */ 77 */
@@ -65,68 +79,538 @@ void cray_retain_utmp(struct utmp *, int);
65void cray_delete_tmpdir(char *, int, uid_t); 79void cray_delete_tmpdir(char *, int, uid_t);
66void cray_init_job(struct passwd *); 80void cray_init_job(struct passwd *);
67void cray_set_tmpdir(struct utmp *); 81void cray_set_tmpdir(struct utmp *);
82void cray_login_failure(char *, int);
83int cray_setup(uid_t, char *, const char *);
84int cray_access_denied(char *);
85
86void
87cray_login_failure(char *username, int errcode)
88{
89 struct udb *ueptr; /* UDB pointer for username */
90 ia_failure_t fsent; /* ia_failure structure */
91 ia_failure_ret_t fret; /* ia_failure return stuff */
92 struct jtab jtab; /* job table structure */
93 int jid = 0; /* job id */
94
95 if ((jid = getjtab(&jtab)) < 0) {
96 debug("cray_login_failure(): getjtab error");
97 }
98 getsysudb();
99 if ((ueptr = getudbnam(username)) == UDB_NULL) {
100 debug("cray_login_failure(): getudbname() returned NULL");
101 }
102 endudb();
103 fsent.revision = 0;
104 fsent.uname = username;
105 fsent.host = (char *)get_canonical_hostname(options.verify_reverse_mapping);
106 fsent.ttyn = "sshd";
107 fsent.caller = IA_SSHD;
108 fsent.flags = IA_INTERACTIVE;
109 fsent.ueptr = ueptr;
110 fsent.jid = jid;
111 fsent.errcode = errcode;
112 fsent.pwdp = NULL;
113 fsent.exitcode = 0; /* dont exit in ia_failure() */
114
115 fret.revision = 0;
116 fret.normal = 0;
68 117
118 /*
119 * Call ia_failure because of an login failure.
120 */
121 ia_failure(&fsent,&fret);
122}
69 123
70/* 124/*
71 * Orignal written by: 125 * Cray access denied
72 * Wayne Schroeder 126 */
73 * San Diego Supercomputer Center 127int
74 * schroeder@sdsc.edu 128cray_access_denied(char *username)
75*/
76void
77cray_setup(uid_t uid, char *username)
78{ 129{
79 struct udb *p; 130 struct udb *ueptr; /* UDB pointer for username */
131 int errcode; /* IA errorcode */
132
133 errcode = 0;
134 getsysudb();
135 if ((ueptr = getudbnam(username)) == UDB_NULL) {
136 debug("cray_login_failure(): getudbname() returned NULL");
137 }
138 endudb();
139 if (ueptr && ueptr->ue_disabled)
140 errcode = IA_DISABLED;
141 if (errcode)
142 cray_login_failure(username, errcode);
143 return (errcode);
144}
145
146int
147cray_setup (uid_t uid, char *username, const char *command)
148{
149 extern struct udb *getudb();
80 extern char *setlimits(); 150 extern char *setlimits();
81 int i, j;
82 int accts[MAXVIDS];
83 int naccts;
84 int err;
85 char *sr;
86 int pid;
87 struct jtab jbuf;
88 int jid;
89 151
90 if ((jid = getjtab(&jbuf)) < 0) 152 int err; /* error return */
91 fatal("getjtab: no jid"); 153 time_t system_time; /* current system clock */
92 154 time_t expiration_time; /* password expiration time */
93 err = setudb(); /* open and rewind the Cray User DataBase */ 155 int maxattempts; /* maximum no. of failed login attempts */
94 if (err != 0) 156 int SecureSys; /* unicos security flag */
95 fatal("UDB open failure"); 157 int minslevel = 0; /* system minimum security level */
96 naccts = 0; 158 int i, j;
97 p = getudbnam(username); 159 int valid_acct = -1; /* flag for reading valid acct */
98 if (p == NULL) 160 char acct_name[MAXACID] = { "" }; /* used to read acct name */
99 fatal("No UDB entry for %.100s", username); 161 struct jtab jtab; /* Job table struct */
100 if (uid != p->ue_uid) 162 struct udb ue; /* udb entry for logging-in user */
101 fatal("UDB entry %.100s uid(%d) does not match uid %d", 163 struct udb *up; /* pointer to UDB entry */
102 username, (int) p->ue_uid, (int) uid); 164 struct secstat secinfo; /* file security attributes */
103 for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { 165 struct servprov init_info; /* used for sesscntl() call */
104 accts[naccts] = p->ue_acids[j]; 166 int jid; /* job ID */
105 naccts++; 167 int pid; /* process ID */
168 char *sr; /* status return from setlimits() */
169 char *ttyn = NULL; /* ttyname or command name*/
170 char hostname[MAXHOSTNAMELEN];
171 passwd_t pwdacm,
172 pwddialup,
173 pwdudb,
174 pwdwal,
175 pwddce; /* passwd stuff for ia_user */
176 ia_user_ret_t uret; /* stuff returned from ia_user */
177 ia_user_t usent; /* ia_user main structure */
178 int ia_rcode; /* ia_user return code */
179 ia_failure_t fsent; /* ia_failure structure */
180 ia_failure_ret_t fret; /* ia_failure return stuff */
181 ia_success_t ssent; /* ia_success structure */
182 ia_success_ret_t sret; /* ia_success return stuff */
183 int ia_mlsrcode; /* ia_mlsuser return code */
184 int secstatrc; /* [f]secstat return code */
185
186 if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) {
187 getsysv(&sysv, sizeof(struct sysv));
188 minslevel = sysv.sy_minlvl;
189 if (getusrv(&usrv) < 0) {
190 debug("getusrv() failed, errno = %d",errno);
191 exit(1);
192 }
106 } 193 }
107 endudb(); /* close the udb */ 194 hostname[0] = '\0';
108 195 strncpy(hostname,
109 if (naccts != 0) { 196 (char *)get_canonical_hostname(options.verify_reverse_mapping),
110 /* Perhaps someday we'll prompt users who have multiple accounts 197 MAXHOSTNAMELEN);
111 to let them pick one (like CRI's login does), but for now just set 198 /*
112 the account to the first entry. */ 199 * Fetch user's UDB entry.
113 if (acctid(0, accts[0]) < 0) 200 */
114 fatal("System call acctid failed, accts[0]=%d", accts[0]); 201 getsysudb();
202 if ((up = getudbnam(username)) == UDB_NULL) {
203 debug("cannot fetch user's UDB entry");
204 exit(1);
205 }
206
207 /*
208 * Prevent any possible fudging so perform a data
209 * safety check and compare the supplied uid against
210 * the udb's uid.
211 */
212 if (up->ue_uid != uid) {
213 debug("IA uid missmatch");
214 exit(1);
215 }
216 endudb();
217
218 if ((jid = getjtab (&jtab)) < 0) {
219 debug("getjtab");
220 return -1;
221 }
222 pid = getpid();
223 ttyn = ttyname(0);
224 if (SecureSys) {
225 if (ttyn) {
226 secstatrc = secstat(ttyn, &secinfo);
227 } else {
228 secstatrc = fsecstat(1, &secinfo);
229 }
230 if (secstatrc == 0) {
231 debug("[f]secstat() successful");
232 } else {
233 debug("[f]secstat() error, rc = %d", secstatrc);
234 exit(1);
235 }
236 }
237 if ((ttyn == NULL) && ((char *)command != NULL))
238 ttyn = (char *)command;
239 /*
240 * Initialize all structures to call ia_user
241 */
242 usent.revision = 0;
243 usent.uname = username;
244 usent.host = hostname;
245 usent.ttyn = ttyn;
246 usent.caller = IA_SSHD;
247 usent.pswdlist = &pwdacm;
248 usent.ueptr = &ue;
249 usent.flags = IA_INTERACTIVE | IA_FFLAG;
250 pwdacm.atype = IA_SECURID;
251 pwdacm.pwdp = NULL;
252 pwdacm.next = &pwdudb;
253
254 pwdudb.atype = IA_UDB;
255 pwdudb.pwdp = NULL;
256 pwdudb.next = &pwddce;
257
258 pwddce.atype = IA_DCE;
259 pwddce.pwdp = NULL;
260 pwddce.next = &pwddialup;
261
262 pwddialup.atype = IA_DIALUP;
263 pwddialup.pwdp = NULL;
264 /* pwddialup.next = &pwdwal; */
265 pwddialup.next = NULL;
266
267 pwdwal.atype = IA_WAL;
268 pwdwal.pwdp = NULL;
269 pwdwal.next = NULL;
270
271 uret.revision = 0;
272 uret.pswd = NULL;
273 uret.normal = 0;
274
275 ia_rcode = ia_user(&usent, &uret);
276
277 switch (ia_rcode) {
278 /*
279 * These are acceptable return codes from ia_user()
280 */
281 case IA_UDBWEEK: /* Password Expires in 1 week */
282 expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage;
283 printf ("WARNING - your current password will expire %s\n",
284 ctime((const time_t *)&expiration_time));
285 break;
286 case IA_UDBEXPIRED:
287 if (ttyname(0) != NULL) {
288 /* Force a password change */
289 printf("Your password has expired; Choose a new one.\n");
290 execl("/bin/passwd", "passwd", username, 0);
291 exit(9);
292 }
293
294 break;
295 case IA_NORMAL: /* Normal Return Code */
296 break;
297 case IA_BACKDOOR:
298 strcpy(ue.ue_name, "root");
299 strcpy(ue.ue_passwd, "");
300 strcpy(ue.ue_dir, "/");
301 strcpy(ue.ue_shell, "/bin/sh");
302 strcpy(ue.ue_age, "");
303 strcpy(ue.ue_comment, "");
304 strcpy(ue.ue_loghost, "");
305 strcpy(ue.ue_logline, "");
306 ue.ue_uid=-1;
307 ue.ue_nice[UDBRC_INTER]=0;
308 for (i=0;i<MAXVIDS;i++)
309 ue.ue_gids[i]=0;
310 ue.ue_logfails=0;
311 ue.ue_minlvl=minslevel;
312 ue.ue_maxlvl=minslevel;
313 ue.ue_deflvl=minslevel;
314 ue.ue_defcomps=0;
315 ue.ue_comparts=0;
316 ue.ue_permits=0;
317 ue.ue_trap=0;
318 ue.ue_disabled=0;
319 ue.ue_logtime=0;
320 break;
321 case IA_CONSOLE: /* Superuser not from Console */
322 case IA_TRUSTED: /* Trusted user */
323 if (options.permit_root_login > PERMIT_NO)
324 break; /* Accept root login */
325 default:
326 /*
327 * These are failed return codes from ia_user()
328 */
329 switch (ia_rcode)
330 {
331 case IA_BADAUTH:
332 printf ("Bad authorization, access denied.\n");
333 break;
334 case IA_DIALUPERR:
335 break;
336 case IA_DISABLED:
337 printf ("Your login has been disabled. Contact the system ");
338 printf ("administrator for assistance.\n");
339 break;
340 case IA_GETSYSV:
341 printf ("getsysv() failed - errno = %d\n", errno);
342 break;
343 case IA_LOCALHOST:
344 break;
345 case IA_MAXLOGS:
346 printf ("Maximum number of failed login attempts exceeded.\n");
347 printf ("Access denied.\n");
348 break;
349 case IA_NOPASS:
350 break;
351 case IA_PUBLIC:
352 break;
353 case IA_SECURIDERR:
354 break;
355 case IA_CONSOLE:
356 break;
357 case IA_TRUSTED:
358 break;
359 case IA_UDBERR:
360 break;
361 case IA_UDBPWDNULL:
362 /*
363 * NULL password not allowed on MLS systems
364 */
365 if (SecureSys) {
366 printf("NULL Password not allowed on MLS systems.\n");
367 }
368 break;
369 case IA_UNKNOWN:
370 break;
371 case IA_UNKNOWNYP:
372 break;
373 case IA_WALERR:
374 break;
375 default:
376 /* nothing special */
377 ;
378 } /* 2. switch (ia_rcode) */
379 /*
380 * Authentication failed.
381 */
382 printf("sshd: Login incorrect, (0%o)\n",
383 ia_rcode-IA_ERRORCODE);
384
385 /*
386 * Initialize structure for ia_failure
387 * which will exit.
388 */
389 fsent.revision = 0;
390 fsent.uname = username;
391 fsent.host = hostname;
392 fsent.ttyn = ttyn;
393 fsent.caller = IA_SSHD;
394 fsent.flags = IA_INTERACTIVE;
395 fsent.ueptr = &ue;
396 fsent.jid = jid;
397 fsent.errcode = ia_rcode;
398 fsent.pwdp = uret.pswd;
399 fsent.exitcode = 1;
400
401 fret.revision = 0;
402 fret.normal = 0;
403
404 /*
405 * Call ia_failure because of an IA failure.
406 * There is no return because ia_failure exits.
407 */
408
409 ia_failure(&fsent,&fret);
410
411 exit(1);
412 } /* 1. switch (ia_rcode) */
413 ia_mlsrcode = IA_NORMAL;
414 if (SecureSys) {
415 debug("calling ia_mlsuser()");
416 ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0);
417 }
418 if (ia_mlsrcode != IA_NORMAL) {
419 printf("sshd: Login incorrect, (0%o)\n",
420 ia_mlsrcode-IA_ERRORCODE);
421 /*
422 * Initialize structure for ia_failure
423 * which will exit.
424 */
425 fsent.revision = 0;
426 fsent.uname = username;
427 fsent.host = hostname;
428 fsent.ttyn = ttyn;
429 fsent.caller = IA_SSHD;
430 fsent.flags = IA_INTERACTIVE;
431 fsent.ueptr = &ue;
432 fsent.jid = jid;
433 fsent.errcode = ia_mlsrcode;
434 fsent.pwdp = uret.pswd;
435 fsent.exitcode = 1;
436 fret.revision = 0;
437 fret.normal = 0;
438
439 /*
440 * Call ia_failure because of an IA failure.
441 * There is no return because ia_failure exits.
442 */
443 ia_failure(&fsent,&fret);
444 exit(1);
115 } 445 }
116 446
117 /* Now set limits, including CPU time for the (interactive) job and process, 447 /* Provide login status information */
118 and set up permissions (for chown etc), etc. This is via an internal CRI 448 if (options.print_lastlog && ue.ue_logtime != 0) {
119 routine, setlimits, used by CRI's login. */ 449 printf("Last successful login was : %.*s ",
450 19, (char *)ctime(&ue.ue_logtime));
451
452 if (*ue.ue_loghost != '\0')
453 printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost);
454
455 else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline);
456
457 if ( SecureSys && (ue.ue_logfails != 0))
458 printf(" followed by %d failed attempts\n", ue.ue_logfails);
459 }
460
461
462 /*
463 * Call ia_success to process successful I/A.
464 */
465 ssent.revision = 0;
466 ssent.uname = username;
467 ssent.host = hostname;
468 ssent.ttyn = ttyn;
469 ssent.caller = IA_SSHD;
470 ssent.flags = IA_INTERACTIVE;
471 ssent.ueptr = &ue;
472 ssent.jid = jid;
473 ssent.errcode = ia_rcode;
474 ssent.us = NULL;
475 ssent.time = 1; /* Set ue_logtime */
476
477 sret.revision = 0;
478 sret.normal = 0;
479
480 ia_success(&ssent,&sret);
481
482 /*
483 * Query for account, iff > 1 valid acid & askacid permbit
484 */
485 if (((ue.ue_permbits & PERMBITS_ACCTID) ||
486 (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) &&
487 ue.ue_permbits & PERMBITS_ASKACID) {
488 if (ttyname(0) != NULL) {
489 debug("cray_setup: ttyname true case, %.100s", ttyname);
490 while (valid_acct == -1) {
491 printf("Account (? for available accounts)"
492 " [%s]: ", acid2nam(ue.ue_acids[0]));
493 gets(acct_name);
494 switch (acct_name[0]) {
495 case EOF:
496 exit(0);
497 break;
498 case '\0':
499 valid_acct = ue.ue_acids[0];
500 strcpy(acct_name, acid2nam(valid_acct));
501 break;
502 case '?':
503 /* Print the list 3 wide */
504 for (i = 0, j = 0; i < MAXVIDS; i++) {
505 if (ue.ue_acids[i] == -1) {
506 printf("\n");
507 break;
508 }
509 if (++j == 4) {
510 j = 1;
511 printf("\n");
512 }
513 printf(" %s",
514 acid2nam(ue.ue_acids[i]));
515 }
516 if (ue.ue_permbits & PERMBITS_ACCTID)
517 printf("\"acctid\" permbit also allows"
518 " you to select any valid "
519 "account name.\n");
520 printf("\n");
521 break;
522 default:
523 if ((valid_acct = nam2acid(acct_name)) == -1) printf("Account id not found for"
524 " account name \"%s\"\n\n",
525 acct_name);
526 break;
527 }
528 /*
529 * If an account was given, search the user's
530 * acids array to verify they can use this account.
531 */
532 if ((valid_acct != -1) &&
533 !(ue.ue_permbits & PERMBITS_ACCTID)) {
534 for (i = 0; i < MAXVIDS; i++) {
535 if (ue.ue_acids[i] == -1)
536 break;
537 if (valid_acct == ue.ue_acids[i])
538 break;
539 }
540 if (i == MAXVIDS ||
541 ue.ue_acids[i] == -1) {
542 fprintf(stderr, "Cannot set"
543 " account name to "
544 "\"%s\", permission "
545 "denied\n\n", acct_name);
546 valid_acct = -1;
547 }
548 }
549 }
550 } else {
551 /*
552 * The client isn't connected to a terminal and can't
553 * respond to an acid prompt. Use default acid.
554 */
555 debug("cray_setup: ttyname false case, %.100s", ttyname);
556 valid_acct = ue.ue_acids[0];
557 }
558 } else {
559 /*
560 * The user doesn't have the askacid permbit set or
561 * only has one valid account to use.
562 */
563 valid_acct = ue.ue_acids[0];
564 }
565 if (acctid(0, valid_acct) < 0) {
566 printf ("Bad account id: %d\n", valid_acct);
567 exit(1);
568 }
569
570/* set up shares and quotas */
571/* Now set shares, quotas, limits, including CPU time for the (interactive)
572 * job and process, and set up permissions (for chown etc), etc.
573 */
574 if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) {
575 printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct);
576 exit(1);
577 }
120 578
121 pid = getpid();
122 sr = setlimits(username, C_PROC, pid, UDBRC_INTER); 579 sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
123 if (sr != NULL) 580 if (sr != NULL) {
124 fatal("%.200s", sr); 581 debug("%.200s", sr);
125 582 exit(1);
583 }
126 sr = setlimits(username, C_JOB, jid, UDBRC_INTER); 584 sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
127 if (sr != NULL) 585 if (sr != NULL) {
128 fatal("%.200s", sr); 586 debug("%.200s", sr);
587 exit(1);
588 }
589 /*
590 * Place the service provider information into
591 * the session table (Unicos) or job table (Unicos/mk).
592 * There exist double defines for the job/session table in
593 * unicos/mk (jtab.h) so no need for a compile time switch.
594 */
595 bzero((char *)&init_info, sizeof(struct servprov));
596 init_info.s_sessinit.si_id = URM_SPT_LOGIN;
597 init_info.s_sessinit.si_pid = getpid();
598 init_info.s_sessinit.si_sid = jid;
599 init_info.s_routing.seqno = 0;
600 init_info.s_routing.iadrs = 0;
601 sesscntl(0, S_SETSERVPO, (int)&init_info);
129 602
603 /*
604 * Set user and controlling tty security attributes.
605 */
606 if (SecureSys) {
607 if (setusrv(&usrv) == -1) {
608 debug("setusrv() failed, errno = %d",errno);
609 exit(1);
610 }
611 }
612
613 return(0);
130} 614}
131 615
132/* 616/*
@@ -143,7 +627,6 @@ drop_cray_privs()
143 int result; 627 int result;
144 extern int priv_set_proc(); 628 extern int priv_set_proc();
145 extern priv_proc_t* priv_init_proc(); 629 extern priv_proc_t* priv_init_proc();
146 struct usrv usrv;
147 630
148 /* 631 /*
149 * If ether of theses two flags are not set 632 * If ether of theses two flags are not set
@@ -154,9 +637,23 @@ drop_cray_privs()
154 if (!sysconf(_SC_CRAY_POSIX_PRIV)) 637 if (!sysconf(_SC_CRAY_POSIX_PRIV))
155 fatal("Not POSIX_PRIV."); 638 fatal("Not POSIX_PRIV.");
156 639
157 debug("Dropping privileges."); 640 debug("Setting MLS labels.");;
641
642 if (sysconf(_SC_CRAY_SECURE_MAC)) {
643 usrv.sv_minlvl = SYSLOW;
644 usrv.sv_actlvl = SYSHIGH;
645 usrv.sv_maxlvl = SYSHIGH;
646 } else {
647 usrv.sv_minlvl = sysv.sy_minlvl;
648 usrv.sv_actlvl = sysv.sy_minlvl;
649 usrv.sv_maxlvl = sysv.sy_maxlvl;
650 }
651 usrv.sv_actcmp = 0;
652 usrv.sv_valcmp = sysv.sy_valcmp;
653
654 usrv.sv_intcat = TFM_SYSTEM;
655 usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE);
158 656
159 memset(&usrv, 0, sizeof(usrv));
160 if (setusrv(&usrv) < 0) 657 if (setusrv(&usrv) < 0)
161 fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, 658 fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
162 strerror(errno)); 659 strerror(errno));
@@ -189,7 +686,6 @@ cray_retain_utmp(struct utmp *ut, int pid)
189 while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { 686 while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
190 if (pid == utmp.ut_pid) { 687 if (pid == utmp.ut_pid) {
191 ut->ut_jid = utmp.ut_jid; 688 ut->ut_jid = utmp.ut_jid;
192 /* XXX: MIN_SIZEOF here? can this go in loginrec? */
193 strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); 689 strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
194 strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); 690 strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
195 strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); 691 strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
@@ -198,7 +694,8 @@ cray_retain_utmp(struct utmp *ut, int pid)
198 } 694 }
199 close(fd); 695 close(fd);
200 } 696 }
201 /* XXX: error message? */ 697 else
698 fatal("Unable to open utmp file");
202} 699}
203 700
204/* 701/*
@@ -245,7 +742,7 @@ cray_job_termination_handler(int sig)
245 char *login = NULL; 742 char *login = NULL;
246 struct jtab jtab; 743 struct jtab jtab;
247 744
248 debug("Received SIG JOB."); 745 debug("received signal %d",sig);
249 746
250 if ((jid = waitjob(&jtab)) == -1 || 747 if ((jid = waitjob(&jtab)) == -1 ||
251 (login = uid2nam(jtab.j_uid)) == NULL) 748 (login = uid2nam(jtab.j_uid)) == NULL)
diff --git a/openbsd-compat/bsd-cray.h b/openbsd-compat/bsd-cray.h
index 9067a389a..8868b4364 100644
--- a/openbsd-compat/bsd-cray.h
+++ b/openbsd-compat/bsd-cray.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: bsd-cray.h,v 1.3 2002/05/15 16:39:52 mouring Exp $ 2 * $Id: bsd-cray.h,v 1.5 2002/09/26 00:38:51 tim Exp $
3 * 3 *
4 * bsd-cray.h 4 * bsd-cray.h
5 * 5 *
@@ -37,11 +37,18 @@
37#ifndef _BSD_CRAY_H 37#ifndef _BSD_CRAY_H
38#define _BSD_CRAY_H 38#define _BSD_CRAY_H
39 39
40#ifdef _CRAY 40#ifdef _UNICOS
41void cray_init_job(struct passwd *); /* init cray job */ 41void cray_init_job(struct passwd *); /* init cray job */
42void cray_job_termination_handler(int); /* process end of job signal */ 42void cray_job_termination_handler(int); /* process end of job signal */
43void cray_setup(uid_t, char *); /* set cray limits */ 43void cray_login_failure(char *username, int errcode);
44int cray_access_denied(char *username);
44extern char cray_tmpdir[]; /* cray tmpdir */ 45extern char cray_tmpdir[]; /* cray tmpdir */
46#ifndef IA_SSHD
47#define IA_SSHD IA_LOGIN
48#endif
49#ifndef MAXHOSTNAMELEN
50#define MAXHOSTNAMELEN 64
51#endif
45#endif 52#endif
46 53
47#endif /* _BSD_CRAY_H */ 54#endif /* _BSD_CRAY_H */
diff --git a/openbsd-compat/bsd-getpeereid.c b/openbsd-compat/bsd-getpeereid.c
new file mode 100644
index 000000000..c7876823d
--- /dev/null
+++ b/openbsd-compat/bsd-getpeereid.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2002 Damien Miller. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26
27RCSID("$Id: bsd-getpeereid.c,v 1.1 2002/09/12 00:33:02 djm Exp $");
28
29#if !defined(HAVE_GETPEEREID)
30
31#if defined(SO_PEERCRED)
32int
33getpeereid(int s, uid_t *euid, gid_t *gid)
34{
35 struct ucred cred;
36 size_t len = sizeof(cred);
37
38 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
39 return (-1);
40 *euid = cred.uid;
41 *gid = cred.gid;
42
43 return (0);
44}
45#else
46int
47getpeereid(int s, uid_t *euid, gid_t *gid)
48{
49 *euid = geteuid();
50 *gid = getgid();
51
52 return (0);
53}
54#endif /* defined(SO_PEERCRED) */
55
56#endif /* !defined(HAVE_GETPEEREID) */
diff --git a/openbsd-compat/bsd-getpeereid.h b/openbsd-compat/bsd-getpeereid.h
new file mode 100644
index 000000000..2e9f077f9
--- /dev/null
+++ b/openbsd-compat/bsd-getpeereid.h
@@ -0,0 +1,14 @@
1/* $Id: bsd-getpeereid.h,v 1.1 2002/09/12 00:33:02 djm Exp $ */
2
3#ifndef _BSD_GETPEEREID_H
4#define _BSD_GETPEEREID_H
5
6#include "config.h"
7
8#include <sys/types.h> /* For uid_t, gid_t */
9
10#ifndef HAVE_GETPEEREID
11int getpeereid(int , uid_t *, gid_t *);
12#endif /* HAVE_GETPEEREID */
13
14#endif /* _BSD_GETPEEREID_H */
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c
index fa48afea9..1c1e43a52 100644
--- a/openbsd-compat/bsd-misc.c
+++ b/openbsd-compat/bsd-misc.c
@@ -24,7 +24,7 @@
24 24
25#include "includes.h" 25#include "includes.h"
26 26
27RCSID("$Id: bsd-misc.c,v 1.8 2002/06/13 21:34:58 mouring Exp $"); 27RCSID("$Id: bsd-misc.c,v 1.10 2002/07/08 21:09:41 mouring Exp $");
28 28
29char *get_progname(char *argv0) 29char *get_progname(char *argv0)
30{ 30{
@@ -93,8 +93,8 @@ int utimes(char *filename, struct timeval *tvp)
93{ 93{
94 struct utimbuf ub; 94 struct utimbuf ub;
95 95
96 ub.actime = tvp->tv_sec; 96 ub.actime = tvp[0].tv_sec;
97 ub.modtime = tvp->tv_usec; 97 ub.modtime = tvp[1].tv_sec;
98 98
99 return(utime(filename, &ub)); 99 return(utime(filename, &ub));
100} 100}
diff --git a/openbsd-compat/dirname.c b/openbsd-compat/dirname.c
index 391b2dd81..35c7d8ec7 100644
--- a/openbsd-compat/dirname.c
+++ b/openbsd-compat/dirname.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $ */ 1/* $OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -31,7 +31,7 @@
31#ifndef HAVE_DIRNAME 31#ifndef HAVE_DIRNAME
32 32
33#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
34static char rcsid[] = "$OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $"; 34static char rcsid[] = "$OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
35#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
36 36
37#include <errno.h> 37#include <errno.h>
@@ -47,7 +47,7 @@ dirname(path)
47 47
48 /* Empty or NULL string gets treated as "." */ 48 /* Empty or NULL string gets treated as "." */
49 if (path == NULL || *path == '\0') { 49 if (path == NULL || *path == '\0') {
50 (void)strcpy(bname, "."); 50 (void)strlcpy(bname, ".", sizeof bname);
51 return(bname); 51 return(bname);
52 } 52 }
53 53
@@ -62,7 +62,7 @@ dirname(path)
62 62
63 /* Either the dir is "/" or there are no slashes */ 63 /* Either the dir is "/" or there are no slashes */
64 if (endp == path) { 64 if (endp == path) {
65 (void)strcpy(bname, *endp == '/' ? "/" : "."); 65 (void)strlcpy(bname, *endp == '/' ? "/" : ".", sizeof bname);
66 return(bname); 66 return(bname);
67 } else { 67 } else {
68 do { 68 do {
diff --git a/openbsd-compat/getcwd.c b/openbsd-compat/getcwd.c
index de3baccbb..6fd8543a5 100644
--- a/openbsd-compat/getcwd.c
+++ b/openbsd-compat/getcwd.c
@@ -24,7 +24,7 @@
24 * SUCH DAMAGE. 24 * SUCH DAMAGE.
25 */ 25 */
26 26
27#include "config.h" 27#include "includes.h"
28 28
29#if !defined(HAVE_GETCWD) 29#if !defined(HAVE_GETCWD)
30 30
diff --git a/openbsd-compat/getopt.c b/openbsd-compat/getopt.c
index f4fbc9bac..4a5cfe5f0 100644
--- a/openbsd-compat/getopt.c
+++ b/openbsd-compat/getopt.c
@@ -31,7 +31,7 @@
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include "config.h" 34#include "includes.h"
35#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) 35#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c
index 365d4334f..e928a2272 100644
--- a/openbsd-compat/glob.c
+++ b/openbsd-compat/glob.c
@@ -56,7 +56,7 @@ get_arg_max(void)
56#if 0 56#if 0
57static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; 57static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
58#else 58#else
59static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $"; 59static char rcsid[] = "$OpenBSD: glob.c,v 1.20 2002/06/14 21:34:58 todd Exp $";
60#endif 60#endif
61#endif /* LIBC_SCCS and not lint */ 61#endif /* LIBC_SCCS and not lint */
62 62
@@ -97,6 +97,7 @@ static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $
97#define RBRACKET ']' 97#define RBRACKET ']'
98#define SEP '/' 98#define SEP '/'
99#define STAR '*' 99#define STAR '*'
100#undef TILDE /* Some platforms may already define it */
100#define TILDE '~' 101#define TILDE '~'
101#define UNDERSCORE '_' 102#define UNDERSCORE '_'
102#define LBRACE '{' 103#define LBRACE '{'
@@ -136,32 +137,32 @@ typedef char Char;
136#define ismeta(c) (((c)&M_QUOTE) != 0) 137#define ismeta(c) (((c)&M_QUOTE) != 0)
137 138
138 139
139static int compare __P((const void *, const void *)); 140static int compare(const void *, const void *);
140static int g_Ctoc __P((const Char *, char *, u_int)); 141static int g_Ctoc(const Char *, char *, u_int);
141static int g_lstat __P((Char *, struct stat *, glob_t *)); 142static int g_lstat(Char *, struct stat *, glob_t *);
142static DIR *g_opendir __P((Char *, glob_t *)); 143static DIR *g_opendir(Char *, glob_t *);
143static Char *g_strchr __P((Char *, int)); 144static Char *g_strchr(Char *, int);
144static int g_stat __P((Char *, struct stat *, glob_t *)); 145static int g_stat(Char *, struct stat *, glob_t *);
145static int glob0 __P((const Char *, glob_t *)); 146static int glob0(const Char *, glob_t *);
146static int glob1 __P((Char *, Char *, glob_t *, size_t *)); 147static int glob1(Char *, Char *, glob_t *, size_t *);
147static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *, 148static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
148 glob_t *, size_t *)); 149 glob_t *, size_t *);
149static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *, 150static int glob3(Char *, Char *, Char *, Char *, Char *, Char *,
150 Char *, Char *, glob_t *, size_t *)); 151 Char *, Char *, glob_t *, size_t *);
151static int globextend __P((const Char *, glob_t *, size_t *)); 152static int globextend(const Char *, glob_t *, size_t *);
152static const Char * 153static const Char *
153 globtilde __P((const Char *, Char *, size_t, glob_t *)); 154 globtilde(const Char *, Char *, size_t, glob_t *);
154static int globexp1 __P((const Char *, glob_t *)); 155static int globexp1(const Char *, glob_t *);
155static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); 156static int globexp2(const Char *, const Char *, glob_t *, int *);
156static int match __P((Char *, Char *, Char *)); 157static int match(Char *, Char *, Char *);
157#ifdef DEBUG 158#ifdef DEBUG
158static void qprintf __P((const char *, Char *)); 159static void qprintf(const char *, Char *);
159#endif 160#endif
160 161
161int 162int
162glob(pattern, flags, errfunc, pglob) 163glob(pattern, flags, errfunc, pglob)
163 const char *pattern; 164 const char *pattern;
164 int flags, (*errfunc) __P((const char *, int)); 165 int flags, (*errfunc)(const char *, int);
165 glob_t *pglob; 166 glob_t *pglob;
166{ 167{
167 const u_char *patnext; 168 const u_char *patnext;
@@ -676,7 +677,7 @@ glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last,
676 677
677 678
678/* 679/*
679 * Extend the gl_pathv member of a glob_t structure to accomodate a new item, 680 * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
680 * add the new item, and update gl_pathc. 681 * add the new item, and update gl_pathc.
681 * 682 *
682 * This assumes the BSD realloc, which only copies the block when its size 683 * This assumes the BSD realloc, which only copies the block when its size
@@ -821,7 +822,7 @@ g_opendir(str, pglob)
821 char buf[MAXPATHLEN]; 822 char buf[MAXPATHLEN];
822 823
823 if (!*str) 824 if (!*str)
824 strcpy(buf, "."); 825 strlcpy(buf, ".", sizeof buf);
825 else { 826 else {
826 if (g_Ctoc(str, buf, sizeof(buf))) 827 if (g_Ctoc(str, buf, sizeof(buf)))
827 return(NULL); 828 return(NULL);
diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h
index b4c8f7aaa..6421f7049 100644
--- a/openbsd-compat/glob.h
+++ b/openbsd-compat/glob.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: glob.h,v 1.5 2001/03/18 17:18:58 deraadt Exp $ */ 1/* $OpenBSD: glob.h,v 1.7 2002/02/17 19:42:21 millert Exp $ */
2/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ 2/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
3 3
4/* 4/*
@@ -53,18 +53,18 @@ typedef struct {
53 int gl_flags; /* Copy of flags parameter to glob. */ 53 int gl_flags; /* Copy of flags parameter to glob. */
54 char **gl_pathv; /* List of paths matching pattern. */ 54 char **gl_pathv; /* List of paths matching pattern. */
55 /* Copy of errfunc parameter to glob. */ 55 /* Copy of errfunc parameter to glob. */
56 int (*gl_errfunc) __P((const char *, int)); 56 int (*gl_errfunc)(const char *, int);
57 57
58 /* 58 /*
59 * Alternate filesystem access methods for glob; replacement 59 * Alternate filesystem access methods for glob; replacement
60 * versions of closedir(3), readdir(3), opendir(3), stat(2) 60 * versions of closedir(3), readdir(3), opendir(3), stat(2)
61 * and lstat(2). 61 * and lstat(2).
62 */ 62 */
63 void (*gl_closedir) __P((void *)); 63 void (*gl_closedir)(void *);
64 struct dirent *(*gl_readdir) __P((void *)); 64 struct dirent *(*gl_readdir)(void *);
65 void *(*gl_opendir) __P((const char *)); 65 void *(*gl_opendir)(const char *);
66 int (*gl_lstat) __P((const char *, struct stat *)); 66 int (*gl_lstat)(const char *, struct stat *);
67 int (*gl_stat) __P((const char *, struct stat *)); 67 int (*gl_stat)(const char *, struct stat *);
68} glob_t; 68} glob_t;
69 69
70/* Flags */ 70/* Flags */
@@ -91,8 +91,8 @@ typedef struct {
91#define GLOB_NOSYS (-4) /* Function not supported. */ 91#define GLOB_NOSYS (-4) /* Function not supported. */
92#define GLOB_ABEND GLOB_ABORTED 92#define GLOB_ABEND GLOB_ABORTED
93 93
94int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); 94int glob(const char *, int, int (*)(const char *, int), glob_t *);
95void globfree __P((glob_t *)); 95void globfree(glob_t *);
96 96
97#endif /* !_GLOB_H_ */ 97#endif /* !_GLOB_H_ */
98 98
diff --git a/openbsd-compat/inet_ntoa.c b/openbsd-compat/inet_ntoa.c
index 8a8b3c846..ac5f56708 100644
--- a/openbsd-compat/inet_ntoa.c
+++ b/openbsd-compat/inet_ntoa.c
@@ -31,12 +31,12 @@
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include "config.h" 34#include "includes.h"
35 35
36#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) 36#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
37 37
38#if defined(LIBC_SCCS) && !defined(lint) 38#if defined(LIBC_SCCS) && !defined(lint)
39static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $"; 39static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Exp $";
40#endif /* LIBC_SCCS and not lint */ 40#endif /* LIBC_SCCS and not lint */
41 41
42/* 42/*
@@ -57,7 +57,7 @@ char *inet_ntoa(struct in_addr in)
57 p = (char *)&in; 57 p = (char *)&in;
58#define UC(b) (((int)b)&0xff) 58#define UC(b) (((int)b)&0xff)
59 (void)snprintf(b, sizeof(b), 59 (void)snprintf(b, sizeof(b),
60 "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 60 "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
61 return (b); 61 return (b);
62} 62}
63 63
diff --git a/openbsd-compat/inet_ntop.c b/openbsd-compat/inet_ntop.c
index 2b8d31f8d..3bea519af 100644
--- a/openbsd-compat/inet_ntop.c
+++ b/openbsd-compat/inet_ntop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $ */ 1/* $OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $ */
2 2
3/* Copyright (c) 1996 by Internet Software Consortium. 3/* Copyright (c) 1996 by Internet Software Consortium.
4 * 4 *
@@ -16,7 +16,7 @@
16 * SOFTWARE. 16 * SOFTWARE.
17 */ 17 */
18 18
19#include "config.h" 19#include "includes.h"
20 20
21#ifndef HAVE_INET_NTOP 21#ifndef HAVE_INET_NTOP
22 22
@@ -24,7 +24,7 @@
24#if 0 24#if 0
25static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; 25static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
26#else 26#else
27static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $"; 27static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $";
28#endif 28#endif
29#endif /* LIBC_SCCS and not lint */ 29#endif /* LIBC_SCCS and not lint */
30 30
@@ -54,8 +54,8 @@ static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Ex
54 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. 54 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
55 */ 55 */
56 56
57static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); 57static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
58static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); 58static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
59 59
60/* char * 60/* char *
61 * inet_ntop(af, src, dst, size) 61 * inet_ntop(af, src, dst, size)
@@ -103,13 +103,14 @@ inet_ntop4(src, dst, size)
103{ 103{
104 static const char fmt[] = "%u.%u.%u.%u"; 104 static const char fmt[] = "%u.%u.%u.%u";
105 char tmp[sizeof "255.255.255.255"]; 105 char tmp[sizeof "255.255.255.255"];
106 int l;
106 107
107 if (snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], 108 l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
108 src[3]) > size) { 109 if (l <= 0 || l >= size) {
109 errno = ENOSPC; 110 errno = ENOSPC;
110 return (NULL); 111 return (NULL);
111 } 112 }
112 strcpy(dst, tmp); 113 strlcpy(dst, tmp, size);
113 return (dst); 114 return (dst);
114} 115}
115 116
@@ -132,10 +133,12 @@ inet_ntop6(src, dst, size)
132 * Keep this in mind if you think this function should have been coded 133 * Keep this in mind if you think this function should have been coded
133 * to use pointer overlays. All the world's not a VAX. 134 * to use pointer overlays. All the world's not a VAX.
134 */ 135 */
135 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 136 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
137 char *tp, *ep;
136 struct { int base, len; } best, cur; 138 struct { int base, len; } best, cur;
137 u_int words[IN6ADDRSZ / INT16SZ]; 139 u_int words[IN6ADDRSZ / INT16SZ];
138 int i; 140 int i;
141 int advance;
139 142
140 /* 143 /*
141 * Preprocess: 144 * Preprocess:
@@ -172,31 +175,45 @@ inet_ntop6(src, dst, size)
172 * Format the result. 175 * Format the result.
173 */ 176 */
174 tp = tmp; 177 tp = tmp;
175 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { 178 ep = tmp + sizeof(tmp);
179 for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
176 /* Are we inside the best run of 0x00's? */ 180 /* Are we inside the best run of 0x00's? */
177 if (best.base != -1 && i >= best.base && 181 if (best.base != -1 && i >= best.base &&
178 i < (best.base + best.len)) { 182 i < (best.base + best.len)) {
179 if (i == best.base) 183 if (i == best.base) {
184 if (tp + 1 >= ep)
185 return (NULL);
180 *tp++ = ':'; 186 *tp++ = ':';
187 }
181 continue; 188 continue;
182 } 189 }
183 /* Are we following an initial run of 0x00s or any real hex? */ 190 /* Are we following an initial run of 0x00s or any real hex? */
184 if (i != 0) 191 if (i != 0) {
192 if (tp + 1 >= ep)
193 return (NULL);
185 *tp++ = ':'; 194 *tp++ = ':';
195 }
186 /* Is this address an encapsulated IPv4? */ 196 /* Is this address an encapsulated IPv4? */
187 if (i == 6 && best.base == 0 && 197 if (i == 6 && best.base == 0 &&
188 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 198 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
189 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) 199 if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
190 return (NULL); 200 return (NULL);
191 tp += strlen(tp); 201 tp += strlen(tp);
192 break; 202 break;
193 } 203 }
194 snprintf(tp, sizeof(tmp - (tp - tmp)), "%x", words[i]); 204 advance = snprintf(tp, ep - tp, "%x", words[i]);
195 tp += strlen(tp); 205 if (advance <= 0 || advance >= ep - tp)
206 return (NULL);
207 tp += advance;
196 } 208 }
197 /* Was it a trailing run of 0x00's? */ 209 /* Was it a trailing run of 0x00's? */
198 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) 210 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
211 if (tp + 1 >= ep)
212 return (NULL);
199 *tp++ = ':'; 213 *tp++ = ':';
214 }
215 if (tp + 1 >= ep)
216 return (NULL);
200 *tp++ = '\0'; 217 *tp++ = '\0';
201 218
202 /* 219 /*
@@ -206,7 +223,7 @@ inet_ntop6(src, dst, size)
206 errno = ENOSPC; 223 errno = ENOSPC;
207 return (NULL); 224 return (NULL);
208 } 225 }
209 strcpy(dst, tmp); 226 strlcpy(dst, tmp, size);
210 return (dst); 227 return (dst);
211} 228}
212 229
diff --git a/openbsd-compat/mktemp.c b/openbsd-compat/mktemp.c
index d69dc5c24..d256ee448 100644
--- a/openbsd-compat/mktemp.c
+++ b/openbsd-compat/mktemp.c
@@ -39,7 +39,7 @@
39#ifndef HAVE_MKDTEMP 39#ifndef HAVE_MKDTEMP
40 40
41#if defined(LIBC_SCCS) && !defined(lint) 41#if defined(LIBC_SCCS) && !defined(lint)
42static char rcsid[] = "$OpenBSD: mktemp.c,v 1.14 2002/01/02 20:18:32 deraadt Exp $"; 42static char rcsid[] = "$OpenBSD: mktemp.c,v 1.16 2002/05/27 18:20:45 millert Exp $";
43#endif /* LIBC_SCCS and not lint */ 43#endif /* LIBC_SCCS and not lint */
44 44
45#ifdef HAVE_CYGWIN 45#ifdef HAVE_CYGWIN
@@ -102,11 +102,11 @@ _gettemp(path, doopen, domkdir, slen)
102 return (0); 102 return (0);
103 } 103 }
104 pid = getpid(); 104 pid = getpid();
105 while (*trv == 'X' && pid != 0) { 105 while (trv >= path && *trv == 'X' && pid != 0) {
106 *trv-- = (pid % 10) + '0'; 106 *trv-- = (pid % 10) + '0';
107 pid /= 10; 107 pid /= 10;
108 } 108 }
109 while (*trv == 'X') { 109 while (trv >= path && *trv == 'X') {
110 char c; 110 char c;
111 111
112 pid = (arc4random() & 0xffff) % (26+26); 112 pid = (arc4random() & 0xffff) % (26+26);
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 11918443d..ae18afd34 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openbsd-compat.h,v 1.16 2002/02/19 20:27:57 mouring Exp $ */ 1/* $Id: openbsd-compat.h,v 1.17 2002/09/12 00:33:02 djm Exp $ */
2 2
3#ifndef _OPENBSD_H 3#ifndef _OPENBSD_H
4#define _OPENBSD_H 4#define _OPENBSD_H
@@ -29,6 +29,7 @@
29 29
30/* Home grown routines */ 30/* Home grown routines */
31#include "bsd-arc4random.h" 31#include "bsd-arc4random.h"
32#include "bsd-getpeereid.h"
32#include "bsd-misc.h" 33#include "bsd-misc.h"
33#include "bsd-snprintf.h" 34#include "bsd-snprintf.h"
34#include "bsd-waitpid.h" 35#include "bsd-waitpid.h"
diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c
index ca0a88e69..4c96a3171 100644
--- a/openbsd-compat/port-aix.c
+++ b/openbsd-compat/port-aix.c
@@ -1,3 +1,28 @@
1/*
2 *
3 * Copyright (c) 2001 Gert Doering. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
1#include "includes.h" 26#include "includes.h"
2 27
3#ifdef _AIX 28#ifdef _AIX
@@ -6,21 +31,21 @@
6#include <../xmalloc.h> 31#include <../xmalloc.h>
7 32
8/* 33/*
9 * AIX has a "usrinfo" area where logname and 34 * AIX has a "usrinfo" area where logname and other stuff is stored -
10 * other stuff is stored - a few applications 35 * a few applications actually use this and die if it's not set
11 * actually use this and die if it's not set 36 *
37 * NOTE: TTY= should be set, but since no one uses it and it's hard to
38 * acquire due to privsep code. We will just drop support.
12 */ 39 */
13void 40void
14aix_usrinfo(struct passwd *pw, char *tty, int ttyfd) 41aix_usrinfo(struct passwd *pw)
15{ 42{
16 u_int i; 43 u_int i;
17 char *cp=NULL; 44 char *cp;
18 45
19 if (ttyfd == -1) 46 cp = xmalloc(16 + 2 * strlen(pw->pw_name));
20 tty[0] = '\0'; 47 i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0,
21 cp = xmalloc(22 + strlen(tty) + 2 * strlen(pw->pw_name)); 48 pw->pw_name, 0);
22 i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c", pw->pw_name, 0,
23 pw->pw_name, 0, tty, 0, 0);
24 if (usrinfo(SETUINFO, cp, i) == -1) 49 if (usrinfo(SETUINFO, cp, i) == -1)
25 fatal("Couldn't set usrinfo: %s", strerror(errno)); 50 fatal("Couldn't set usrinfo: %s", strerror(errno));
26 debug3("AIX/UsrInfo: set len %d", i); 51 debug3("AIX/UsrInfo: set len %d", i);
diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h
index e4d14f4ae..79570a206 100644
--- a/openbsd-compat/port-aix.h
+++ b/openbsd-compat/port-aix.h
@@ -1,5 +1,29 @@
1#ifdef _AIX 1/*
2 2 *
3void aix_usrinfo(struct passwd *pw, char *tty, int ttyfd); 3 * Copyright (c) 2001 Gert Doering. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
4 26
27#ifdef _AIX
28void aix_usrinfo(struct passwd *pw);
5#endif /* _AIX */ 29#endif /* _AIX */
diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c
index 8c2f5f841..4e549b62b 100644
--- a/openbsd-compat/readpassphrase.c
+++ b/openbsd-compat/readpassphrase.c
@@ -1,7 +1,7 @@
1/* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ */ 1/* $OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; 31static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include "includes.h" 34#include "includes.h"
@@ -60,8 +60,8 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
60 int input, output, save_errno; 60 int input, output, save_errno;
61 char ch, *p, *end; 61 char ch, *p, *end;
62 struct termios term, oterm; 62 struct termios term, oterm;
63 struct sigaction sa, saveint, savehup, savequit, saveterm; 63 struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
64 struct sigaction savetstp, savettin, savettou; 64 struct sigaction savetstp, savettin, savettou, savepipe;
65 65
66 /* I suppose we could alloc on demand in this case (XXX). */ 66 /* I suppose we could alloc on demand in this case (XXX). */
67 if (bufsiz == 0) { 67 if (bufsiz == 0) {
@@ -70,11 +70,13 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
70 } 70 }
71 71
72restart: 72restart:
73 signo = 0;
73 /* 74 /*
74 * Read and write to /dev/tty if available. If not, read from 75 * Read and write to /dev/tty if available. If not, read from
75 * stdin and write to stderr unless a tty is required. 76 * stdin and write to stderr unless a tty is required.
76 */ 77 */
77 if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { 78 if ((flags & RPP_STDIN) ||
79 (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
78 if (flags & RPP_REQUIRE_TTY) { 80 if (flags & RPP_REQUIRE_TTY) {
79 errno = ENOTTY; 81 errno = ENOTTY;
80 return(NULL); 82 return(NULL);
@@ -86,13 +88,15 @@ restart:
86 /* 88 /*
87 * Catch signals that would otherwise cause the user to end 89 * Catch signals that would otherwise cause the user to end
88 * up with echo turned off in the shell. Don't worry about 90 * up with echo turned off in the shell. Don't worry about
89 * things like SIGALRM and SIGPIPE for now. 91 * things like SIGXCPU and SIGVTALRM for now.
90 */ 92 */
91 sigemptyset(&sa.sa_mask); 93 sigemptyset(&sa.sa_mask);
92 sa.sa_flags = 0; /* don't restart system calls */ 94 sa.sa_flags = 0; /* don't restart system calls */
93 sa.sa_handler = handler; 95 sa.sa_handler = handler;
94 (void)sigaction(SIGINT, &sa, &saveint); 96 (void)sigaction(SIGALRM, &sa, &savealrm);
95 (void)sigaction(SIGHUP, &sa, &savehup); 97 (void)sigaction(SIGHUP, &sa, &savehup);
98 (void)sigaction(SIGINT, &sa, &saveint);
99 (void)sigaction(SIGPIPE, &sa, &savepipe);
96 (void)sigaction(SIGQUIT, &sa, &savequit); 100 (void)sigaction(SIGQUIT, &sa, &savequit);
97 (void)sigaction(SIGTERM, &sa, &saveterm); 101 (void)sigaction(SIGTERM, &sa, &saveterm);
98 (void)sigaction(SIGTSTP, &sa, &savetstp); 102 (void)sigaction(SIGTSTP, &sa, &savetstp);
@@ -100,7 +104,7 @@ restart:
100 (void)sigaction(SIGTTOU, &sa, &savettou); 104 (void)sigaction(SIGTTOU, &sa, &savettou);
101 105
102 /* Turn off echo if possible. */ 106 /* Turn off echo if possible. */
103 if (tcgetattr(input, &oterm) == 0) { 107 if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
104 memcpy(&term, &oterm, sizeof(term)); 108 memcpy(&term, &oterm, sizeof(term));
105 if (!(flags & RPP_ECHO_ON)) 109 if (!(flags & RPP_ECHO_ON))
106 term.c_lflag &= ~(ECHO | ECHONL); 110 term.c_lflag &= ~(ECHO | ECHONL);
@@ -111,10 +115,13 @@ restart:
111 (void)tcsetattr(input, _T_FLUSH, &term); 115 (void)tcsetattr(input, _T_FLUSH, &term);
112 } else { 116 } else {
113 memset(&term, 0, sizeof(term)); 117 memset(&term, 0, sizeof(term));
118 term.c_lflag |= ECHO;
114 memset(&oterm, 0, sizeof(oterm)); 119 memset(&oterm, 0, sizeof(oterm));
120 oterm.c_lflag |= ECHO;
115 } 121 }
116 122
117 (void)write(output, prompt, strlen(prompt)); 123 if (!(flags & RPP_STDIN))
124 (void)write(output, prompt, strlen(prompt));
118 end = buf + bufsiz - 1; 125 end = buf + bufsiz - 1;
119 for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { 126 for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
120 if (p < end) { 127 if (p < end) {
@@ -137,13 +144,14 @@ restart:
137 /* Restore old terminal settings and signals. */ 144 /* Restore old terminal settings and signals. */
138 if (memcmp(&term, &oterm, sizeof(term)) != 0) 145 if (memcmp(&term, &oterm, sizeof(term)) != 0)
139 (void)tcsetattr(input, _T_FLUSH, &oterm); 146 (void)tcsetattr(input, _T_FLUSH, &oterm);
140 (void)sigaction(SIGINT, &saveint, NULL); 147 (void)sigaction(SIGALRM, &savealrm, NULL);
141 (void)sigaction(SIGHUP, &savehup, NULL); 148 (void)sigaction(SIGHUP, &savehup, NULL);
149 (void)sigaction(SIGINT, &saveint, NULL);
142 (void)sigaction(SIGQUIT, &savequit, NULL); 150 (void)sigaction(SIGQUIT, &savequit, NULL);
151 (void)sigaction(SIGPIPE, &savepipe, NULL);
143 (void)sigaction(SIGTERM, &saveterm, NULL); 152 (void)sigaction(SIGTERM, &saveterm, NULL);
144 (void)sigaction(SIGTSTP, &savetstp, NULL); 153 (void)sigaction(SIGTSTP, &savetstp, NULL);
145 (void)sigaction(SIGTTIN, &savettin, NULL); 154 (void)sigaction(SIGTTIN, &savettin, NULL);
146 (void)sigaction(SIGTTOU, &savettou, NULL);
147 if (input != STDIN_FILENO) 155 if (input != STDIN_FILENO)
148 (void)close(input); 156 (void)close(input);
149 157
@@ -152,12 +160,11 @@ restart:
152 * now that we have restored the signal handlers. 160 * now that we have restored the signal handlers.
153 */ 161 */
154 if (signo) { 162 if (signo) {
155 kill(getpid(), signo); 163 kill(getpid(), signo);
156 switch (signo) { 164 switch (signo) {
157 case SIGTSTP: 165 case SIGTSTP:
158 case SIGTTIN: 166 case SIGTTIN:
159 case SIGTTOU: 167 case SIGTTOU:
160 signo = 0;
161 goto restart; 168 goto restart;
162 } 169 }
163 } 170 }
diff --git a/openbsd-compat/readpassphrase.h b/openbsd-compat/readpassphrase.h
index 9077b6e08..92908a489 100644
--- a/openbsd-compat/readpassphrase.h
+++ b/openbsd-compat/readpassphrase.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ */ 1/* $OpenBSD: readpassphrase.h,v 1.3 2002/06/28 12:32:22 millert Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -40,8 +40,9 @@
40#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ 40#define RPP_FORCELOWER 0x04 /* Force input to lower case. */
41#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ 41#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */
42#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ 42#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
43#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */
43 44
44char *readpassphrase(const char *, char *, size_t, int); 45char * readpassphrase(const char *, char *, size_t, int);
45 46
46#endif /* HAVE_READPASSPHRASE */ 47#endif /* HAVE_READPASSPHRASE */
47 48
diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c
index b4a05db95..b9035ca22 100644
--- a/openbsd-compat/realpath.c
+++ b/openbsd-compat/realpath.c
@@ -32,7 +32,7 @@
32#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) 32#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: realpath.c,v 1.6 2002/01/12 16:24:35 millert Exp $"; 35static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
37 37
38#include <sys/param.h> 38#include <sys/param.h>
@@ -69,7 +69,7 @@ realpath(const char *path, char *resolved)
69 /* Save the starting point. */ 69 /* Save the starting point. */
70 getcwd(start,MAXPATHLEN); 70 getcwd(start,MAXPATHLEN);
71 if ((fd = open(".", O_RDONLY)) < 0) { 71 if ((fd = open(".", O_RDONLY)) < 0) {
72 (void)strcpy(resolved, "."); 72 (void)strlcpy(resolved, ".", MAXPATHLEN);
73 return (NULL); 73 return (NULL);
74 } 74 }
75 close(fd); 75 close(fd);
@@ -129,7 +129,7 @@ loop:
129 * Save the last component name and get the full pathname of 129 * Save the last component name and get the full pathname of
130 * the current directory. 130 * the current directory.
131 */ 131 */
132 (void)strcpy(wbuf, p); 132 (void)strlcpy(wbuf, p, sizeof wbuf);
133 if (getcwd(resolved, MAXPATHLEN) == 0) 133 if (getcwd(resolved, MAXPATHLEN) == 0)
134 goto err1; 134 goto err1;
135 135
diff --git a/openbsd-compat/rresvport.c b/openbsd-compat/rresvport.c
index 44eac2036..9f058961d 100644
--- a/openbsd-compat/rresvport.c
+++ b/openbsd-compat/rresvport.c
@@ -33,7 +33,7 @@
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 */ 34 */
35 35
36#include "config.h" 36#include "includes.h"
37 37
38#ifndef HAVE_RRESVPORT_AF 38#ifndef HAVE_RRESVPORT_AF
39 39
diff --git a/openbsd-compat/setenv.c b/openbsd-compat/setenv.c
index 6c2d5cd31..1dff15c73 100644
--- a/openbsd-compat/setenv.c
+++ b/openbsd-compat/setenv.c
@@ -31,7 +31,7 @@
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include "config.h" 34#include "includes.h"
35#ifndef HAVE_SETENV 35#ifndef HAVE_SETENV
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/openbsd-compat/sigact.c b/openbsd-compat/sigact.c
index 806eb02b6..35fbab0eb 100644
--- a/openbsd-compat/sigact.c
+++ b/openbsd-compat/sigact.c
@@ -33,7 +33,7 @@
33 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
34 ****************************************************************************/ 34 ****************************************************************************/
35 35
36#include "config.h" 36#include "includes.h"
37#include <signal.h> 37#include <signal.h>
38#include "sigact.h" 38#include "sigact.h"
39 39
diff --git a/openbsd-compat/strlcat.c b/openbsd-compat/strlcat.c
index 6ff65c19b..3a9b5d1a7 100644
--- a/openbsd-compat/strlcat.c
+++ b/openbsd-compat/strlcat.c
@@ -27,7 +27,7 @@
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include "config.h" 30#include "includes.h"
31#ifndef HAVE_STRLCAT 31#ifndef HAVE_STRLCAT
32 32
33#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/openbsd-compat/strlcpy.c b/openbsd-compat/strlcpy.c
index b5e5a552e..2f87eca44 100644
--- a/openbsd-compat/strlcpy.c
+++ b/openbsd-compat/strlcpy.c
@@ -27,7 +27,7 @@
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include "config.h" 30#include "includes.h"
31#ifndef HAVE_STRLCPY 31#ifndef HAVE_STRLCPY
32 32
33#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/openbsd-compat/strsep.c b/openbsd-compat/strsep.c
index c03649cff..d0afc44ae 100644
--- a/openbsd-compat/strsep.c
+++ b/openbsd-compat/strsep.c
@@ -33,7 +33,7 @@
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 */ 34 */
35 35
36#include "config.h" 36#include "includes.h"
37 37
38#if !defined(HAVE_STRSEP) 38#if !defined(HAVE_STRSEP)
39 39
diff --git a/openbsd-compat/sys-queue.h b/openbsd-compat/sys-queue.h
new file mode 100644
index 000000000..176fe3174
--- /dev/null
+++ b/openbsd-compat/sys-queue.h
@@ -0,0 +1,584 @@
1/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */
2/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4/*
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)queue.h 8.5 (Berkeley) 8/20/94
37 */
38
39#ifndef _FAKE_QUEUE_H_
40#define _FAKE_QUEUE_H_
41
42/*
43 * Ignore all <sys/queue.h> since older platforms have broken/incomplete
44 * <sys/queue.h> that are too hard to work around.
45 */
46#undef SLIST_HEAD
47#undef SLIST_HEAD_INITIALIZER
48#undef SLIST_ENTRY
49#undef SLIST_FIRST
50#undef SLIST_END
51#undef SLIST_EMPTY
52#undef SLIST_NEXT
53#undef SLIST_FOREACH
54#undef SLIST_INIT
55#undef SLIST_INSERT_AFTER
56#undef SLIST_INSERT_HEAD
57#undef SLIST_REMOVE_HEAD
58#undef SLIST_REMOVE
59#undef LIST_HEAD
60#undef LIST_HEAD_INITIALIZER
61#undef LIST_ENTRY
62#undef LIST_FIRST
63#undef LIST_END
64#undef LIST_EMPTY
65#undef LIST_NEXT
66#undef LIST_FOREACH
67#undef LIST_INIT
68#undef LIST_INSERT_AFTER
69#undef LIST_INSERT_BEFORE
70#undef LIST_INSERT_HEAD
71#undef LIST_REMOVE
72#undef LIST_REPLACE
73#undef SIMPLEQ_HEAD
74#undef SIMPLEQ_HEAD_INITIALIZER
75#undef SIMPLEQ_ENTRY
76#undef SIMPLEQ_FIRST
77#undef SIMPLEQ_END
78#undef SIMPLEQ_EMPTY
79#undef SIMPLEQ_NEXT
80#undef SIMPLEQ_FOREACH
81#undef SIMPLEQ_INIT
82#undef SIMPLEQ_INSERT_HEAD
83#undef SIMPLEQ_INSERT_TAIL
84#undef SIMPLEQ_INSERT_AFTER
85#undef SIMPLEQ_REMOVE_HEAD
86#undef TAILQ_HEAD
87#undef TAILQ_HEAD_INITIALIZER
88#undef TAILQ_ENTRY
89#undef TAILQ_FIRST
90#undef TAILQ_END
91#undef TAILQ_NEXT
92#undef TAILQ_LAST
93#undef TAILQ_PREV
94#undef TAILQ_EMPTY
95#undef TAILQ_FOREACH
96#undef TAILQ_FOREACH_REVERSE
97#undef TAILQ_INIT
98#undef TAILQ_INSERT_HEAD
99#undef TAILQ_INSERT_TAIL
100#undef TAILQ_INSERT_AFTER
101#undef TAILQ_INSERT_BEFORE
102#undef TAILQ_REMOVE
103#undef TAILQ_REPLACE
104#undef CIRCLEQ_HEAD
105#undef CIRCLEQ_HEAD_INITIALIZER
106#undef CIRCLEQ_ENTRY
107#undef CIRCLEQ_FIRST
108#undef CIRCLEQ_LAST
109#undef CIRCLEQ_END
110#undef CIRCLEQ_NEXT
111#undef CIRCLEQ_PREV
112#undef CIRCLEQ_EMPTY
113#undef CIRCLEQ_FOREACH
114#undef CIRCLEQ_FOREACH_REVERSE
115#undef CIRCLEQ_INIT
116#undef CIRCLEQ_INSERT_AFTER
117#undef CIRCLEQ_INSERT_BEFORE
118#undef CIRCLEQ_INSERT_HEAD
119#undef CIRCLEQ_INSERT_TAIL
120#undef CIRCLEQ_REMOVE
121#undef CIRCLEQ_REPLACE
122
123/*
124 * This file defines five types of data structures: singly-linked lists,
125 * lists, simple queues, tail queues, and circular queues.
126 *
127 *
128 * A singly-linked list is headed by a single forward pointer. The elements
129 * are singly linked for minimum space and pointer manipulation overhead at
130 * the expense of O(n) removal for arbitrary elements. New elements can be
131 * added to the list after an existing element or at the head of the list.
132 * Elements being removed from the head of the list should use the explicit
133 * macro for this purpose for optimum efficiency. A singly-linked list may
134 * only be traversed in the forward direction. Singly-linked lists are ideal
135 * for applications with large datasets and few or no removals or for
136 * implementing a LIFO queue.
137 *
138 * A list is headed by a single forward pointer (or an array of forward
139 * pointers for a hash table header). The elements are doubly linked
140 * so that an arbitrary element can be removed without a need to
141 * traverse the list. New elements can be added to the list before
142 * or after an existing element or at the head of the list. A list
143 * may only be traversed in the forward direction.
144 *
145 * A simple queue is headed by a pair of pointers, one the head of the
146 * list and the other to the tail of the list. The elements are singly
147 * linked to save space, so elements can only be removed from the
148 * head of the list. New elements can be added to the list before or after
149 * an existing element, at the head of the list, or at the end of the
150 * list. A simple queue may only be traversed in the forward direction.
151 *
152 * A tail queue is headed by a pair of pointers, one to the head of the
153 * list and the other to the tail of the list. The elements are doubly
154 * linked so that an arbitrary element can be removed without a need to
155 * traverse the list. New elements can be added to the list before or
156 * after an existing element, at the head of the list, or at the end of
157 * the list. A tail queue may be traversed in either direction.
158 *
159 * A circle queue is headed by a pair of pointers, one to the head of the
160 * list and the other to the tail of the list. The elements are doubly
161 * linked so that an arbitrary element can be removed without a need to
162 * traverse the list. New elements can be added to the list before or after
163 * an existing element, at the head of the list, or at the end of the list.
164 * A circle queue may be traversed in either direction, but has a more
165 * complex end of list detection.
166 *
167 * For details on the use of these macros, see the queue(3) manual page.
168 */
169
170/*
171 * Singly-linked List definitions.
172 */
173#define SLIST_HEAD(name, type) \
174struct name { \
175 struct type *slh_first; /* first element */ \
176}
177
178#define SLIST_HEAD_INITIALIZER(head) \
179 { NULL }
180
181#define SLIST_ENTRY(type) \
182struct { \
183 struct type *sle_next; /* next element */ \
184}
185
186/*
187 * Singly-linked List access methods.
188 */
189#define SLIST_FIRST(head) ((head)->slh_first)
190#define SLIST_END(head) NULL
191#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
192#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
193
194#define SLIST_FOREACH(var, head, field) \
195 for((var) = SLIST_FIRST(head); \
196 (var) != SLIST_END(head); \
197 (var) = SLIST_NEXT(var, field))
198
199/*
200 * Singly-linked List functions.
201 */
202#define SLIST_INIT(head) { \
203 SLIST_FIRST(head) = SLIST_END(head); \
204}
205
206#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
207 (elm)->field.sle_next = (slistelm)->field.sle_next; \
208 (slistelm)->field.sle_next = (elm); \
209} while (0)
210
211#define SLIST_INSERT_HEAD(head, elm, field) do { \
212 (elm)->field.sle_next = (head)->slh_first; \
213 (head)->slh_first = (elm); \
214} while (0)
215
216#define SLIST_REMOVE_HEAD(head, field) do { \
217 (head)->slh_first = (head)->slh_first->field.sle_next; \
218} while (0)
219
220#define SLIST_REMOVE(head, elm, type, field) do { \
221 if ((head)->slh_first == (elm)) { \
222 SLIST_REMOVE_HEAD((head), field); \
223 } \
224 else { \
225 struct type *curelm = (head)->slh_first; \
226 while( curelm->field.sle_next != (elm) ) \
227 curelm = curelm->field.sle_next; \
228 curelm->field.sle_next = \
229 curelm->field.sle_next->field.sle_next; \
230 } \
231} while (0)
232
233/*
234 * List definitions.
235 */
236#define LIST_HEAD(name, type) \
237struct name { \
238 struct type *lh_first; /* first element */ \
239}
240
241#define LIST_HEAD_INITIALIZER(head) \
242 { NULL }
243
244#define LIST_ENTRY(type) \
245struct { \
246 struct type *le_next; /* next element */ \
247 struct type **le_prev; /* address of previous next element */ \
248}
249
250/*
251 * List access methods
252 */
253#define LIST_FIRST(head) ((head)->lh_first)
254#define LIST_END(head) NULL
255#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
256#define LIST_NEXT(elm, field) ((elm)->field.le_next)
257
258#define LIST_FOREACH(var, head, field) \
259 for((var) = LIST_FIRST(head); \
260 (var)!= LIST_END(head); \
261 (var) = LIST_NEXT(var, field))
262
263/*
264 * List functions.
265 */
266#define LIST_INIT(head) do { \
267 LIST_FIRST(head) = LIST_END(head); \
268} while (0)
269
270#define LIST_INSERT_AFTER(listelm, elm, field) do { \
271 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
272 (listelm)->field.le_next->field.le_prev = \
273 &(elm)->field.le_next; \
274 (listelm)->field.le_next = (elm); \
275 (elm)->field.le_prev = &(listelm)->field.le_next; \
276} while (0)
277
278#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
279 (elm)->field.le_prev = (listelm)->field.le_prev; \
280 (elm)->field.le_next = (listelm); \
281 *(listelm)->field.le_prev = (elm); \
282 (listelm)->field.le_prev = &(elm)->field.le_next; \
283} while (0)
284
285#define LIST_INSERT_HEAD(head, elm, field) do { \
286 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
287 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
288 (head)->lh_first = (elm); \
289 (elm)->field.le_prev = &(head)->lh_first; \
290} while (0)
291
292#define LIST_REMOVE(elm, field) do { \
293 if ((elm)->field.le_next != NULL) \
294 (elm)->field.le_next->field.le_prev = \
295 (elm)->field.le_prev; \
296 *(elm)->field.le_prev = (elm)->field.le_next; \
297} while (0)
298
299#define LIST_REPLACE(elm, elm2, field) do { \
300 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
301 (elm2)->field.le_next->field.le_prev = \
302 &(elm2)->field.le_next; \
303 (elm2)->field.le_prev = (elm)->field.le_prev; \
304 *(elm2)->field.le_prev = (elm2); \
305} while (0)
306
307/*
308 * Simple queue definitions.
309 */
310#define SIMPLEQ_HEAD(name, type) \
311struct name { \
312 struct type *sqh_first; /* first element */ \
313 struct type **sqh_last; /* addr of last next element */ \
314}
315
316#define SIMPLEQ_HEAD_INITIALIZER(head) \
317 { NULL, &(head).sqh_first }
318
319#define SIMPLEQ_ENTRY(type) \
320struct { \
321 struct type *sqe_next; /* next element */ \
322}
323
324/*
325 * Simple queue access methods.
326 */
327#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
328#define SIMPLEQ_END(head) NULL
329#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
330#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
331
332#define SIMPLEQ_FOREACH(var, head, field) \
333 for((var) = SIMPLEQ_FIRST(head); \
334 (var) != SIMPLEQ_END(head); \
335 (var) = SIMPLEQ_NEXT(var, field))
336
337/*
338 * Simple queue functions.
339 */
340#define SIMPLEQ_INIT(head) do { \
341 (head)->sqh_first = NULL; \
342 (head)->sqh_last = &(head)->sqh_first; \
343} while (0)
344
345#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
346 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
347 (head)->sqh_last = &(elm)->field.sqe_next; \
348 (head)->sqh_first = (elm); \
349} while (0)
350
351#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
352 (elm)->field.sqe_next = NULL; \
353 *(head)->sqh_last = (elm); \
354 (head)->sqh_last = &(elm)->field.sqe_next; \
355} while (0)
356
357#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
358 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
359 (head)->sqh_last = &(elm)->field.sqe_next; \
360 (listelm)->field.sqe_next = (elm); \
361} while (0)
362
363#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
364 if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
365 (head)->sqh_last = &(head)->sqh_first; \
366} while (0)
367
368/*
369 * Tail queue definitions.
370 */
371#define TAILQ_HEAD(name, type) \
372struct name { \
373 struct type *tqh_first; /* first element */ \
374 struct type **tqh_last; /* addr of last next element */ \
375}
376
377#define TAILQ_HEAD_INITIALIZER(head) \
378 { NULL, &(head).tqh_first }
379
380#define TAILQ_ENTRY(type) \
381struct { \
382 struct type *tqe_next; /* next element */ \
383 struct type **tqe_prev; /* address of previous next element */ \
384}
385
386/*
387 * tail queue access methods
388 */
389#define TAILQ_FIRST(head) ((head)->tqh_first)
390#define TAILQ_END(head) NULL
391#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
392#define TAILQ_LAST(head, headname) \
393 (*(((struct headname *)((head)->tqh_last))->tqh_last))
394/* XXX */
395#define TAILQ_PREV(elm, headname, field) \
396 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
397#define TAILQ_EMPTY(head) \
398 (TAILQ_FIRST(head) == TAILQ_END(head))
399
400#define TAILQ_FOREACH(var, head, field) \
401 for((var) = TAILQ_FIRST(head); \
402 (var) != TAILQ_END(head); \
403 (var) = TAILQ_NEXT(var, field))
404
405#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
406 for((var) = TAILQ_LAST(head, headname); \
407 (var) != TAILQ_END(head); \
408 (var) = TAILQ_PREV(var, headname, field))
409
410/*
411 * Tail queue functions.
412 */
413#define TAILQ_INIT(head) do { \
414 (head)->tqh_first = NULL; \
415 (head)->tqh_last = &(head)->tqh_first; \
416} while (0)
417
418#define TAILQ_INSERT_HEAD(head, elm, field) do { \
419 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
420 (head)->tqh_first->field.tqe_prev = \
421 &(elm)->field.tqe_next; \
422 else \
423 (head)->tqh_last = &(elm)->field.tqe_next; \
424 (head)->tqh_first = (elm); \
425 (elm)->field.tqe_prev = &(head)->tqh_first; \
426} while (0)
427
428#define TAILQ_INSERT_TAIL(head, elm, field) do { \
429 (elm)->field.tqe_next = NULL; \
430 (elm)->field.tqe_prev = (head)->tqh_last; \
431 *(head)->tqh_last = (elm); \
432 (head)->tqh_last = &(elm)->field.tqe_next; \
433} while (0)
434
435#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
436 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
437 (elm)->field.tqe_next->field.tqe_prev = \
438 &(elm)->field.tqe_next; \
439 else \
440 (head)->tqh_last = &(elm)->field.tqe_next; \
441 (listelm)->field.tqe_next = (elm); \
442 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
443} while (0)
444
445#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
446 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
447 (elm)->field.tqe_next = (listelm); \
448 *(listelm)->field.tqe_prev = (elm); \
449 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
450} while (0)
451
452#define TAILQ_REMOVE(head, elm, field) do { \
453 if (((elm)->field.tqe_next) != NULL) \
454 (elm)->field.tqe_next->field.tqe_prev = \
455 (elm)->field.tqe_prev; \
456 else \
457 (head)->tqh_last = (elm)->field.tqe_prev; \
458 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
459} while (0)
460
461#define TAILQ_REPLACE(head, elm, elm2, field) do { \
462 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
463 (elm2)->field.tqe_next->field.tqe_prev = \
464 &(elm2)->field.tqe_next; \
465 else \
466 (head)->tqh_last = &(elm2)->field.tqe_next; \
467 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
468 *(elm2)->field.tqe_prev = (elm2); \
469} while (0)
470
471/*
472 * Circular queue definitions.
473 */
474#define CIRCLEQ_HEAD(name, type) \
475struct name { \
476 struct type *cqh_first; /* first element */ \
477 struct type *cqh_last; /* last element */ \
478}
479
480#define CIRCLEQ_HEAD_INITIALIZER(head) \
481 { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
482
483#define CIRCLEQ_ENTRY(type) \
484struct { \
485 struct type *cqe_next; /* next element */ \
486 struct type *cqe_prev; /* previous element */ \
487}
488
489/*
490 * Circular queue access methods
491 */
492#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
493#define CIRCLEQ_LAST(head) ((head)->cqh_last)
494#define CIRCLEQ_END(head) ((void *)(head))
495#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
496#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
497#define CIRCLEQ_EMPTY(head) \
498 (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
499
500#define CIRCLEQ_FOREACH(var, head, field) \
501 for((var) = CIRCLEQ_FIRST(head); \
502 (var) != CIRCLEQ_END(head); \
503 (var) = CIRCLEQ_NEXT(var, field))
504
505#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
506 for((var) = CIRCLEQ_LAST(head); \
507 (var) != CIRCLEQ_END(head); \
508 (var) = CIRCLEQ_PREV(var, field))
509
510/*
511 * Circular queue functions.
512 */
513#define CIRCLEQ_INIT(head) do { \
514 (head)->cqh_first = CIRCLEQ_END(head); \
515 (head)->cqh_last = CIRCLEQ_END(head); \
516} while (0)
517
518#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
519 (elm)->field.cqe_next = (listelm)->field.cqe_next; \
520 (elm)->field.cqe_prev = (listelm); \
521 if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
522 (head)->cqh_last = (elm); \
523 else \
524 (listelm)->field.cqe_next->field.cqe_prev = (elm); \
525 (listelm)->field.cqe_next = (elm); \
526} while (0)
527
528#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
529 (elm)->field.cqe_next = (listelm); \
530 (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
531 if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
532 (head)->cqh_first = (elm); \
533 else \
534 (listelm)->field.cqe_prev->field.cqe_next = (elm); \
535 (listelm)->field.cqe_prev = (elm); \
536} while (0)
537
538#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
539 (elm)->field.cqe_next = (head)->cqh_first; \
540 (elm)->field.cqe_prev = CIRCLEQ_END(head); \
541 if ((head)->cqh_last == CIRCLEQ_END(head)) \
542 (head)->cqh_last = (elm); \
543 else \
544 (head)->cqh_first->field.cqe_prev = (elm); \
545 (head)->cqh_first = (elm); \
546} while (0)
547
548#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
549 (elm)->field.cqe_next = CIRCLEQ_END(head); \
550 (elm)->field.cqe_prev = (head)->cqh_last; \
551 if ((head)->cqh_first == CIRCLEQ_END(head)) \
552 (head)->cqh_first = (elm); \
553 else \
554 (head)->cqh_last->field.cqe_next = (elm); \
555 (head)->cqh_last = (elm); \
556} while (0)
557
558#define CIRCLEQ_REMOVE(head, elm, field) do { \
559 if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
560 (head)->cqh_last = (elm)->field.cqe_prev; \
561 else \
562 (elm)->field.cqe_next->field.cqe_prev = \
563 (elm)->field.cqe_prev; \
564 if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
565 (head)->cqh_first = (elm)->field.cqe_next; \
566 else \
567 (elm)->field.cqe_prev->field.cqe_next = \
568 (elm)->field.cqe_next; \
569} while (0)
570
571#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
572 if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
573 CIRCLEQ_END(head)) \
574 (head).cqh_last = (elm2); \
575 else \
576 (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
577 if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
578 CIRCLEQ_END(head)) \
579 (head).cqh_first = (elm2); \
580 else \
581 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
582} while (0)
583
584#endif /* !_FAKE_QUEUE_H_ */
diff --git a/openbsd-compat/sys-tree.h b/openbsd-compat/sys-tree.h
new file mode 100644
index 000000000..0a58710c9
--- /dev/null
+++ b/openbsd-compat/sys-tree.h
@@ -0,0 +1,675 @@
1/* $OpenBSD: tree.h,v 1.6 2002/06/11 22:09:52 provos Exp $ */
2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef _SYS_TREE_H_
28#define _SYS_TREE_H_
29
30/*
31 * This file defines data structures for different types of trees:
32 * splay trees and red-black trees.
33 *
34 * A splay tree is a self-organizing data structure. Every operation
35 * on the tree causes a splay to happen. The splay moves the requested
36 * node to the root of the tree and partly rebalances it.
37 *
38 * This has the benefit that request locality causes faster lookups as
39 * the requested nodes move to the top of the tree. On the other hand,
40 * every lookup causes memory writes.
41 *
42 * The Balance Theorem bounds the total access time for m operations
43 * and n inserts on an initially empty tree as O((m + n)lg n). The
44 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
45 *
46 * A red-black tree is a binary search tree with the node color as an
47 * extra attribute. It fulfills a set of conditions:
48 * - every search path from the root to a leaf consists of the
49 * same number of black nodes,
50 * - each red node (except for the root) has a black parent,
51 * - each leaf node is black.
52 *
53 * Every operation on a red-black tree is bounded as O(lg n).
54 * The maximum height of a red-black tree is 2lg (n+1).
55 */
56
57#define SPLAY_HEAD(name, type) \
58struct name { \
59 struct type *sph_root; /* root of the tree */ \
60}
61
62#define SPLAY_INITIALIZER(root) \
63 { NULL }
64
65#define SPLAY_INIT(root) do { \
66 (root)->sph_root = NULL; \
67} while (0)
68
69#define SPLAY_ENTRY(type) \
70struct { \
71 struct type *spe_left; /* left element */ \
72 struct type *spe_right; /* right element */ \
73}
74
75#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
76#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
77#define SPLAY_ROOT(head) (head)->sph_root
78#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
79
80/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
81#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
82 SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
83 SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
84 (head)->sph_root = tmp; \
85} while (0)
86
87#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
88 SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
89 SPLAY_LEFT(tmp, field) = (head)->sph_root; \
90 (head)->sph_root = tmp; \
91} while (0)
92
93#define SPLAY_LINKLEFT(head, tmp, field) do { \
94 SPLAY_LEFT(tmp, field) = (head)->sph_root; \
95 tmp = (head)->sph_root; \
96 (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
97} while (0)
98
99#define SPLAY_LINKRIGHT(head, tmp, field) do { \
100 SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
101 tmp = (head)->sph_root; \
102 (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
103} while (0)
104
105#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
106 SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
107 SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
108 SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
109 SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
110} while (0)
111
112/* Generates prototypes and inline functions */
113
114#define SPLAY_PROTOTYPE(name, type, field, cmp) \
115void name##_SPLAY(struct name *, struct type *); \
116void name##_SPLAY_MINMAX(struct name *, int); \
117struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
118struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
119 \
120/* Finds the node with the same key as elm */ \
121static __inline struct type * \
122name##_SPLAY_FIND(struct name *head, struct type *elm) \
123{ \
124 if (SPLAY_EMPTY(head)) \
125 return(NULL); \
126 name##_SPLAY(head, elm); \
127 if ((cmp)(elm, (head)->sph_root) == 0) \
128 return (head->sph_root); \
129 return (NULL); \
130} \
131 \
132static __inline struct type * \
133name##_SPLAY_NEXT(struct name *head, struct type *elm) \
134{ \
135 name##_SPLAY(head, elm); \
136 if (SPLAY_RIGHT(elm, field) != NULL) { \
137 elm = SPLAY_RIGHT(elm, field); \
138 while (SPLAY_LEFT(elm, field) != NULL) { \
139 elm = SPLAY_LEFT(elm, field); \
140 } \
141 } else \
142 elm = NULL; \
143 return (elm); \
144} \
145 \
146static __inline struct type * \
147name##_SPLAY_MIN_MAX(struct name *head, int val) \
148{ \
149 name##_SPLAY_MINMAX(head, val); \
150 return (SPLAY_ROOT(head)); \
151}
152
153/* Main splay operation.
154 * Moves node close to the key of elm to top
155 */
156#define SPLAY_GENERATE(name, type, field, cmp) \
157struct type * \
158name##_SPLAY_INSERT(struct name *head, struct type *elm) \
159{ \
160 if (SPLAY_EMPTY(head)) { \
161 SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
162 } else { \
163 int __comp; \
164 name##_SPLAY(head, elm); \
165 __comp = (cmp)(elm, (head)->sph_root); \
166 if(__comp < 0) { \
167 SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
168 SPLAY_RIGHT(elm, field) = (head)->sph_root; \
169 SPLAY_LEFT((head)->sph_root, field) = NULL; \
170 } else if (__comp > 0) { \
171 SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
172 SPLAY_LEFT(elm, field) = (head)->sph_root; \
173 SPLAY_RIGHT((head)->sph_root, field) = NULL; \
174 } else \
175 return ((head)->sph_root); \
176 } \
177 (head)->sph_root = (elm); \
178 return (NULL); \
179} \
180 \
181struct type * \
182name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
183{ \
184 struct type *__tmp; \
185 if (SPLAY_EMPTY(head)) \
186 return (NULL); \
187 name##_SPLAY(head, elm); \
188 if ((cmp)(elm, (head)->sph_root) == 0) { \
189 if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
190 (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
191 } else { \
192 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
193 (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
194 name##_SPLAY(head, elm); \
195 SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
196 } \
197 return (elm); \
198 } \
199 return (NULL); \
200} \
201 \
202void \
203name##_SPLAY(struct name *head, struct type *elm) \
204{ \
205 struct type __node, *__left, *__right, *__tmp; \
206 int __comp; \
207\
208 SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
209 __left = __right = &__node; \
210\
211 while ((__comp = (cmp)(elm, (head)->sph_root))) { \
212 if (__comp < 0) { \
213 __tmp = SPLAY_LEFT((head)->sph_root, field); \
214 if (__tmp == NULL) \
215 break; \
216 if ((cmp)(elm, __tmp) < 0){ \
217 SPLAY_ROTATE_RIGHT(head, __tmp, field); \
218 if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
219 break; \
220 } \
221 SPLAY_LINKLEFT(head, __right, field); \
222 } else if (__comp > 0) { \
223 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
224 if (__tmp == NULL) \
225 break; \
226 if ((cmp)(elm, __tmp) > 0){ \
227 SPLAY_ROTATE_LEFT(head, __tmp, field); \
228 if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
229 break; \
230 } \
231 SPLAY_LINKRIGHT(head, __left, field); \
232 } \
233 } \
234 SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
235} \
236 \
237/* Splay with either the minimum or the maximum element \
238 * Used to find minimum or maximum element in tree. \
239 */ \
240void name##_SPLAY_MINMAX(struct name *head, int __comp) \
241{ \
242 struct type __node, *__left, *__right, *__tmp; \
243\
244 SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
245 __left = __right = &__node; \
246\
247 while (1) { \
248 if (__comp < 0) { \
249 __tmp = SPLAY_LEFT((head)->sph_root, field); \
250 if (__tmp == NULL) \
251 break; \
252 if (__comp < 0){ \
253 SPLAY_ROTATE_RIGHT(head, __tmp, field); \
254 if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
255 break; \
256 } \
257 SPLAY_LINKLEFT(head, __right, field); \
258 } else if (__comp > 0) { \
259 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
260 if (__tmp == NULL) \
261 break; \
262 if (__comp > 0) { \
263 SPLAY_ROTATE_LEFT(head, __tmp, field); \
264 if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
265 break; \
266 } \
267 SPLAY_LINKRIGHT(head, __left, field); \
268 } \
269 } \
270 SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
271}
272
273#define SPLAY_NEGINF -1
274#define SPLAY_INF 1
275
276#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
277#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
278#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
279#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
280#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
281 : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
282#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
283 : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
284
285#define SPLAY_FOREACH(x, name, head) \
286 for ((x) = SPLAY_MIN(name, head); \
287 (x) != NULL; \
288 (x) = SPLAY_NEXT(name, head, x))
289
290/* Macros that define a red-back tree */
291#define RB_HEAD(name, type) \
292struct name { \
293 struct type *rbh_root; /* root of the tree */ \
294}
295
296#define RB_INITIALIZER(root) \
297 { NULL }
298
299#define RB_INIT(root) do { \
300 (root)->rbh_root = NULL; \
301} while (0)
302
303#define RB_BLACK 0
304#define RB_RED 1
305#define RB_ENTRY(type) \
306struct { \
307 struct type *rbe_left; /* left element */ \
308 struct type *rbe_right; /* right element */ \
309 struct type *rbe_parent; /* parent element */ \
310 int rbe_color; /* node color */ \
311}
312
313#define RB_LEFT(elm, field) (elm)->field.rbe_left
314#define RB_RIGHT(elm, field) (elm)->field.rbe_right
315#define RB_PARENT(elm, field) (elm)->field.rbe_parent
316#define RB_COLOR(elm, field) (elm)->field.rbe_color
317#define RB_ROOT(head) (head)->rbh_root
318#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
319
320#define RB_SET(elm, parent, field) do { \
321 RB_PARENT(elm, field) = parent; \
322 RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
323 RB_COLOR(elm, field) = RB_RED; \
324} while (0)
325
326#define RB_SET_BLACKRED(black, red, field) do { \
327 RB_COLOR(black, field) = RB_BLACK; \
328 RB_COLOR(red, field) = RB_RED; \
329} while (0)
330
331#ifndef RB_AUGMENT
332#define RB_AUGMENT(x)
333#endif
334
335#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
336 (tmp) = RB_RIGHT(elm, field); \
337 if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
338 RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
339 } \
340 RB_AUGMENT(elm); \
341 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
342 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
343 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
344 else \
345 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
346 RB_AUGMENT(RB_PARENT(elm, field)); \
347 } else \
348 (head)->rbh_root = (tmp); \
349 RB_LEFT(tmp, field) = (elm); \
350 RB_PARENT(elm, field) = (tmp); \
351 RB_AUGMENT(tmp); \
352} while (0)
353
354#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
355 (tmp) = RB_LEFT(elm, field); \
356 if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
357 RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
358 } \
359 RB_AUGMENT(elm); \
360 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
361 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
362 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
363 else \
364 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
365 RB_AUGMENT(RB_PARENT(elm, field)); \
366 } else \
367 (head)->rbh_root = (tmp); \
368 RB_RIGHT(tmp, field) = (elm); \
369 RB_PARENT(elm, field) = (tmp); \
370 RB_AUGMENT(tmp); \
371} while (0)
372
373/* Generates prototypes and inline functions */
374#define RB_PROTOTYPE(name, type, field, cmp) \
375void name##_RB_INSERT_COLOR(struct name *, struct type *); \
376void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
377struct type *name##_RB_REMOVE(struct name *, struct type *); \
378struct type *name##_RB_INSERT(struct name *, struct type *); \
379struct type *name##_RB_FIND(struct name *, struct type *); \
380struct type *name##_RB_NEXT(struct name *, struct type *); \
381struct type *name##_RB_MINMAX(struct name *, int); \
382 \
383
384/* Main rb operation.
385 * Moves node close to the key of elm to top
386 */
387#define RB_GENERATE(name, type, field, cmp) \
388void \
389name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
390{ \
391 struct type *parent, *gparent, *tmp; \
392 while ((parent = RB_PARENT(elm, field)) && \
393 RB_COLOR(parent, field) == RB_RED) { \
394 gparent = RB_PARENT(parent, field); \
395 if (parent == RB_LEFT(gparent, field)) { \
396 tmp = RB_RIGHT(gparent, field); \
397 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
398 RB_COLOR(tmp, field) = RB_BLACK; \
399 RB_SET_BLACKRED(parent, gparent, field);\
400 elm = gparent; \
401 continue; \
402 } \
403 if (RB_RIGHT(parent, field) == elm) { \
404 RB_ROTATE_LEFT(head, parent, tmp, field);\
405 tmp = parent; \
406 parent = elm; \
407 elm = tmp; \
408 } \
409 RB_SET_BLACKRED(parent, gparent, field); \
410 RB_ROTATE_RIGHT(head, gparent, tmp, field); \
411 } else { \
412 tmp = RB_LEFT(gparent, field); \
413 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
414 RB_COLOR(tmp, field) = RB_BLACK; \
415 RB_SET_BLACKRED(parent, gparent, field);\
416 elm = gparent; \
417 continue; \
418 } \
419 if (RB_LEFT(parent, field) == elm) { \
420 RB_ROTATE_RIGHT(head, parent, tmp, field);\
421 tmp = parent; \
422 parent = elm; \
423 elm = tmp; \
424 } \
425 RB_SET_BLACKRED(parent, gparent, field); \
426 RB_ROTATE_LEFT(head, gparent, tmp, field); \
427 } \
428 } \
429 RB_COLOR(head->rbh_root, field) = RB_BLACK; \
430} \
431 \
432void \
433name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
434{ \
435 struct type *tmp; \
436 while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
437 elm != RB_ROOT(head)) { \
438 if (RB_LEFT(parent, field) == elm) { \
439 tmp = RB_RIGHT(parent, field); \
440 if (RB_COLOR(tmp, field) == RB_RED) { \
441 RB_SET_BLACKRED(tmp, parent, field); \
442 RB_ROTATE_LEFT(head, parent, tmp, field);\
443 tmp = RB_RIGHT(parent, field); \
444 } \
445 if ((RB_LEFT(tmp, field) == NULL || \
446 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
447 (RB_RIGHT(tmp, field) == NULL || \
448 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
449 RB_COLOR(tmp, field) = RB_RED; \
450 elm = parent; \
451 parent = RB_PARENT(elm, field); \
452 } else { \
453 if (RB_RIGHT(tmp, field) == NULL || \
454 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
455 struct type *oleft; \
456 if ((oleft = RB_LEFT(tmp, field)))\
457 RB_COLOR(oleft, field) = RB_BLACK;\
458 RB_COLOR(tmp, field) = RB_RED; \
459 RB_ROTATE_RIGHT(head, tmp, oleft, field);\
460 tmp = RB_RIGHT(parent, field); \
461 } \
462 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
463 RB_COLOR(parent, field) = RB_BLACK; \
464 if (RB_RIGHT(tmp, field)) \
465 RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
466 RB_ROTATE_LEFT(head, parent, tmp, field);\
467 elm = RB_ROOT(head); \
468 break; \
469 } \
470 } else { \
471 tmp = RB_LEFT(parent, field); \
472 if (RB_COLOR(tmp, field) == RB_RED) { \
473 RB_SET_BLACKRED(tmp, parent, field); \
474 RB_ROTATE_RIGHT(head, parent, tmp, field);\
475 tmp = RB_LEFT(parent, field); \
476 } \
477 if ((RB_LEFT(tmp, field) == NULL || \
478 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
479 (RB_RIGHT(tmp, field) == NULL || \
480 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
481 RB_COLOR(tmp, field) = RB_RED; \
482 elm = parent; \
483 parent = RB_PARENT(elm, field); \
484 } else { \
485 if (RB_LEFT(tmp, field) == NULL || \
486 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
487 struct type *oright; \
488 if ((oright = RB_RIGHT(tmp, field)))\
489 RB_COLOR(oright, field) = RB_BLACK;\
490 RB_COLOR(tmp, field) = RB_RED; \
491 RB_ROTATE_LEFT(head, tmp, oright, field);\
492 tmp = RB_LEFT(parent, field); \
493 } \
494 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
495 RB_COLOR(parent, field) = RB_BLACK; \
496 if (RB_LEFT(tmp, field)) \
497 RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
498 RB_ROTATE_RIGHT(head, parent, tmp, field);\
499 elm = RB_ROOT(head); \
500 break; \
501 } \
502 } \
503 } \
504 if (elm) \
505 RB_COLOR(elm, field) = RB_BLACK; \
506} \
507 \
508struct type * \
509name##_RB_REMOVE(struct name *head, struct type *elm) \
510{ \
511 struct type *child, *parent, *old = elm; \
512 int color; \
513 if (RB_LEFT(elm, field) == NULL) \
514 child = RB_RIGHT(elm, field); \
515 else if (RB_RIGHT(elm, field) == NULL) \
516 child = RB_LEFT(elm, field); \
517 else { \
518 struct type *left; \
519 elm = RB_RIGHT(elm, field); \
520 while ((left = RB_LEFT(elm, field))) \
521 elm = left; \
522 child = RB_RIGHT(elm, field); \
523 parent = RB_PARENT(elm, field); \
524 color = RB_COLOR(elm, field); \
525 if (child) \
526 RB_PARENT(child, field) = parent; \
527 if (parent) { \
528 if (RB_LEFT(parent, field) == elm) \
529 RB_LEFT(parent, field) = child; \
530 else \
531 RB_RIGHT(parent, field) = child; \
532 RB_AUGMENT(parent); \
533 } else \
534 RB_ROOT(head) = child; \
535 if (RB_PARENT(elm, field) == old) \
536 parent = elm; \
537 (elm)->field = (old)->field; \
538 if (RB_PARENT(old, field)) { \
539 if (RB_LEFT(RB_PARENT(old, field), field) == old)\
540 RB_LEFT(RB_PARENT(old, field), field) = elm;\
541 else \
542 RB_RIGHT(RB_PARENT(old, field), field) = elm;\
543 RB_AUGMENT(RB_PARENT(old, field)); \
544 } else \
545 RB_ROOT(head) = elm; \
546 RB_PARENT(RB_LEFT(old, field), field) = elm; \
547 if (RB_RIGHT(old, field)) \
548 RB_PARENT(RB_RIGHT(old, field), field) = elm; \
549 if (parent) { \
550 left = parent; \
551 do { \
552 RB_AUGMENT(left); \
553 } while ((left = RB_PARENT(left, field))); \
554 } \
555 goto color; \
556 } \
557 parent = RB_PARENT(elm, field); \
558 color = RB_COLOR(elm, field); \
559 if (child) \
560 RB_PARENT(child, field) = parent; \
561 if (parent) { \
562 if (RB_LEFT(parent, field) == elm) \
563 RB_LEFT(parent, field) = child; \
564 else \
565 RB_RIGHT(parent, field) = child; \
566 RB_AUGMENT(parent); \
567 } else \
568 RB_ROOT(head) = child; \
569color: \
570 if (color == RB_BLACK) \
571 name##_RB_REMOVE_COLOR(head, parent, child); \
572 return (old); \
573} \
574 \
575/* Inserts a node into the RB tree */ \
576struct type * \
577name##_RB_INSERT(struct name *head, struct type *elm) \
578{ \
579 struct type *tmp; \
580 struct type *parent = NULL; \
581 int comp = 0; \
582 tmp = RB_ROOT(head); \
583 while (tmp) { \
584 parent = tmp; \
585 comp = (cmp)(elm, parent); \
586 if (comp < 0) \
587 tmp = RB_LEFT(tmp, field); \
588 else if (comp > 0) \
589 tmp = RB_RIGHT(tmp, field); \
590 else \
591 return (tmp); \
592 } \
593 RB_SET(elm, parent, field); \
594 if (parent != NULL) { \
595 if (comp < 0) \
596 RB_LEFT(parent, field) = elm; \
597 else \
598 RB_RIGHT(parent, field) = elm; \
599 RB_AUGMENT(parent); \
600 } else \
601 RB_ROOT(head) = elm; \
602 name##_RB_INSERT_COLOR(head, elm); \
603 return (NULL); \
604} \
605 \
606/* Finds the node with the same key as elm */ \
607struct type * \
608name##_RB_FIND(struct name *head, struct type *elm) \
609{ \
610 struct type *tmp = RB_ROOT(head); \
611 int comp; \
612 while (tmp) { \
613 comp = cmp(elm, tmp); \
614 if (comp < 0) \
615 tmp = RB_LEFT(tmp, field); \
616 else if (comp > 0) \
617 tmp = RB_RIGHT(tmp, field); \
618 else \
619 return (tmp); \
620 } \
621 return (NULL); \
622} \
623 \
624struct type * \
625name##_RB_NEXT(struct name *head, struct type *elm) \
626{ \
627 if (RB_RIGHT(elm, field)) { \
628 elm = RB_RIGHT(elm, field); \
629 while (RB_LEFT(elm, field)) \
630 elm = RB_LEFT(elm, field); \
631 } else { \
632 if (RB_PARENT(elm, field) && \
633 (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
634 elm = RB_PARENT(elm, field); \
635 else { \
636 while (RB_PARENT(elm, field) && \
637 (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
638 elm = RB_PARENT(elm, field); \
639 elm = RB_PARENT(elm, field); \
640 } \
641 } \
642 return (elm); \
643} \
644 \
645struct type * \
646name##_RB_MINMAX(struct name *head, int val) \
647{ \
648 struct type *tmp = RB_ROOT(head); \
649 struct type *parent = NULL; \
650 while (tmp) { \
651 parent = tmp; \
652 if (val < 0) \
653 tmp = RB_LEFT(tmp, field); \
654 else \
655 tmp = RB_RIGHT(tmp, field); \
656 } \
657 return (parent); \
658}
659
660#define RB_NEGINF -1
661#define RB_INF 1
662
663#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
664#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
665#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
666#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y)
667#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
668#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
669
670#define RB_FOREACH(x, name, head) \
671 for ((x) = RB_MIN(name, head); \
672 (x) != NULL; \
673 (x) = name##_RB_NEXT(head, x))
674
675#endif /* _SYS_TREE_H_ */
diff --git a/openbsd-compat/xmmap.c b/openbsd-compat/xmmap.c
new file mode 100644
index 000000000..8f1d2022c
--- /dev/null
+++ b/openbsd-compat/xmmap.c
@@ -0,0 +1,67 @@
1/*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions
4 * are met:
5 * 1. Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
17 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
18 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 */
22
23#include "includes.h"
24
25#ifdef HAVE_SYS_MMAN_H
26#include <sys/mman.h>
27#endif
28
29#include "log.h"
30
31void *xmmap(size_t size)
32{
33 void *address;
34
35#ifdef HAVE_MMAP
36# ifdef MAP_ANON
37 address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
38 -1, 0);
39# else
40 address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
41 open("/dev/zero", O_RDWR), 0);
42# endif
43
44#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX"
45 if (address == MAP_FAILED) {
46 char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE;
47 int tmpfd;
48
49 tmpfd = mkstemp(tmpname);
50 if (tmpfd == -1)
51 fatal("mkstemp(\"%s\"): %s",
52 MM_SWAP_TEMPLATE, strerror(errno));
53 unlink(tmpname);
54 ftruncate(tmpfd, size);
55 address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
56 tmpfd, 0);
57 close(tmpfd);
58 }
59
60 return (address);
61#else
62 fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
63 __func__);
64#endif /* HAVE_MMAP */
65
66}
67
diff --git a/openbsd-compat/xmmap.h b/openbsd-compat/xmmap.h
new file mode 100644
index 000000000..c0fa04aca
--- /dev/null
+++ b/openbsd-compat/xmmap.h
@@ -0,0 +1,23 @@
1/*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions
4 * are met:
5 * 1. Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
17 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
18 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 */
22
23void *xmmap(size_t size);