diff options
Diffstat (limited to 'openbsd-compat')
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 | ||
3 | sysconfdir=@sysconfdir@ | 3 | sysconfdir=@sysconfdir@ |
4 | piddir=@piddir@ | 4 | piddir=@piddir@ |
@@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ | |||
18 | 18 | ||
19 | OPENBSD=base64.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o | 19 | OPENBSD=base64.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o |
20 | 20 | ||
21 | COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o | 21 | COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o xmmap.o |
22 | 22 | ||
23 | PORTS=port-irix.o port-aix.o | 23 | PORTS=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 | ||
65 | static const char Base64[] = | 66 | static 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 | |||
68 | extern ServerOptions options; | ||
69 | |||
59 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ | 70 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ |
60 | 71 | ||
72 | struct sysv sysv; /* system security structure */ | ||
73 | struct 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); | |||
65 | void cray_delete_tmpdir(char *, int, uid_t); | 79 | void cray_delete_tmpdir(char *, int, uid_t); |
66 | void cray_init_job(struct passwd *); | 80 | void cray_init_job(struct passwd *); |
67 | void cray_set_tmpdir(struct utmp *); | 81 | void cray_set_tmpdir(struct utmp *); |
82 | void cray_login_failure(char *, int); | ||
83 | int cray_setup(uid_t, char *, const char *); | ||
84 | int cray_access_denied(char *); | ||
85 | |||
86 | void | ||
87 | cray_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 | 127 | int |
74 | * schroeder@sdsc.edu | 128 | cray_access_denied(char *username) |
75 | */ | ||
76 | void | ||
77 | cray_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 | |||
146 | int | ||
147 | cray_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 |
41 | void cray_init_job(struct passwd *); /* init cray job */ | 41 | void cray_init_job(struct passwd *); /* init cray job */ |
42 | void cray_job_termination_handler(int); /* process end of job signal */ | 42 | void cray_job_termination_handler(int); /* process end of job signal */ |
43 | void cray_setup(uid_t, char *); /* set cray limits */ | 43 | void cray_login_failure(char *username, int errcode); |
44 | int cray_access_denied(char *username); | ||
44 | extern char cray_tmpdir[]; /* cray tmpdir */ | 45 | extern 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 | |||
27 | RCSID("$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) | ||
32 | int | ||
33 | getpeereid(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 | ||
46 | int | ||
47 | getpeereid(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 | ||
11 | int 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 | ||
27 | RCSID("$Id: bsd-misc.c,v 1.8 2002/06/13 21:34:58 mouring Exp $"); | 27 | RCSID("$Id: bsd-misc.c,v 1.10 2002/07/08 21:09:41 mouring Exp $"); |
28 | 28 | ||
29 | char *get_progname(char *argv0) | 29 | char *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) |
34 | static char rcsid[] = "$OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $"; | 34 | static 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 |
57 | static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; | 57 | static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; |
58 | #else | 58 | #else |
59 | static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $"; | 59 | static 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 | ||
139 | static int compare __P((const void *, const void *)); | 140 | static int compare(const void *, const void *); |
140 | static int g_Ctoc __P((const Char *, char *, u_int)); | 141 | static int g_Ctoc(const Char *, char *, u_int); |
141 | static int g_lstat __P((Char *, struct stat *, glob_t *)); | 142 | static int g_lstat(Char *, struct stat *, glob_t *); |
142 | static DIR *g_opendir __P((Char *, glob_t *)); | 143 | static DIR *g_opendir(Char *, glob_t *); |
143 | static Char *g_strchr __P((Char *, int)); | 144 | static Char *g_strchr(Char *, int); |
144 | static int g_stat __P((Char *, struct stat *, glob_t *)); | 145 | static int g_stat(Char *, struct stat *, glob_t *); |
145 | static int glob0 __P((const Char *, glob_t *)); | 146 | static int glob0(const Char *, glob_t *); |
146 | static int glob1 __P((Char *, Char *, glob_t *, size_t *)); | 147 | static int glob1(Char *, Char *, glob_t *, size_t *); |
147 | static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *, | 148 | static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, |
148 | glob_t *, size_t *)); | 149 | glob_t *, size_t *); |
149 | static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *, | 150 | static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, |
150 | Char *, Char *, glob_t *, size_t *)); | 151 | Char *, Char *, glob_t *, size_t *); |
151 | static int globextend __P((const Char *, glob_t *, size_t *)); | 152 | static int globextend(const Char *, glob_t *, size_t *); |
152 | static const Char * | 153 | static const Char * |
153 | globtilde __P((const Char *, Char *, size_t, glob_t *)); | 154 | globtilde(const Char *, Char *, size_t, glob_t *); |
154 | static int globexp1 __P((const Char *, glob_t *)); | 155 | static int globexp1(const Char *, glob_t *); |
155 | static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); | 156 | static int globexp2(const Char *, const Char *, glob_t *, int *); |
156 | static int match __P((Char *, Char *, Char *)); | 157 | static int match(Char *, Char *, Char *); |
157 | #ifdef DEBUG | 158 | #ifdef DEBUG |
158 | static void qprintf __P((const char *, Char *)); | 159 | static void qprintf(const char *, Char *); |
159 | #endif | 160 | #endif |
160 | 161 | ||
161 | int | 162 | int |
162 | glob(pattern, flags, errfunc, pglob) | 163 | glob(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 | ||
94 | int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); | 94 | int glob(const char *, int, int (*)(const char *, int), glob_t *); |
95 | void globfree __P((glob_t *)); | 95 | void 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) |
39 | static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $"; | 39 | static 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 *)∈ | 57 | p = (char *)∈ |
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 |
25 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; | 25 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; |
26 | #else | 26 | #else |
27 | static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $"; | 27 | static 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 | ||
57 | static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); | 57 | static const char *inet_ntop4(const u_char *src, char *dst, size_t size); |
58 | static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); | 58 | static 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) |
42 | static char rcsid[] = "$OpenBSD: mktemp.c,v 1.14 2002/01/02 20:18:32 deraadt Exp $"; | 42 | static 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 | */ |
13 | void | 40 | void |
14 | aix_usrinfo(struct passwd *pw, char *tty, int ttyfd) | 41 | aix_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 | * | |
3 | void 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 | ||
28 | void 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) |
31 | static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; | 31 | static 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 | ||
72 | restart: | 72 | restart: |
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 | ||
44 | char *readpassphrase(const char *, char *, size_t, int); | 45 | char * 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) |
35 | static char *rcsid = "$OpenBSD: realpath.c,v 1.6 2002/01/12 16:24:35 millert Exp $"; | 35 | static 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) \ | ||
174 | struct name { \ | ||
175 | struct type *slh_first; /* first element */ \ | ||
176 | } | ||
177 | |||
178 | #define SLIST_HEAD_INITIALIZER(head) \ | ||
179 | { NULL } | ||
180 | |||
181 | #define SLIST_ENTRY(type) \ | ||
182 | struct { \ | ||
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) \ | ||
237 | struct name { \ | ||
238 | struct type *lh_first; /* first element */ \ | ||
239 | } | ||
240 | |||
241 | #define LIST_HEAD_INITIALIZER(head) \ | ||
242 | { NULL } | ||
243 | |||
244 | #define LIST_ENTRY(type) \ | ||
245 | struct { \ | ||
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) \ | ||
311 | struct 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) \ | ||
320 | struct { \ | ||
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) \ | ||
372 | struct 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) \ | ||
381 | struct { \ | ||
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) \ | ||
475 | struct 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) \ | ||
484 | struct { \ | ||
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) \ | ||
58 | struct 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) \ | ||
70 | struct { \ | ||
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) \ | ||
115 | void name##_SPLAY(struct name *, struct type *); \ | ||
116 | void name##_SPLAY_MINMAX(struct name *, int); \ | ||
117 | struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ | ||
118 | struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ | ||
119 | \ | ||
120 | /* Finds the node with the same key as elm */ \ | ||
121 | static __inline struct type * \ | ||
122 | name##_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 | \ | ||
132 | static __inline struct type * \ | ||
133 | name##_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 | \ | ||
146 | static __inline struct type * \ | ||
147 | name##_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) \ | ||
157 | struct type * \ | ||
158 | name##_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 | \ | ||
181 | struct type * \ | ||
182 | name##_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 | \ | ||
202 | void \ | ||
203 | name##_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 | */ \ | ||
240 | void 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) \ | ||
292 | struct 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) \ | ||
306 | struct { \ | ||
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) \ | ||
375 | void name##_RB_INSERT_COLOR(struct name *, struct type *); \ | ||
376 | void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ | ||
377 | struct type *name##_RB_REMOVE(struct name *, struct type *); \ | ||
378 | struct type *name##_RB_INSERT(struct name *, struct type *); \ | ||
379 | struct type *name##_RB_FIND(struct name *, struct type *); \ | ||
380 | struct type *name##_RB_NEXT(struct name *, struct type *); \ | ||
381 | struct 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) \ | ||
388 | void \ | ||
389 | name##_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 | \ | ||
432 | void \ | ||
433 | name##_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 | \ | ||
508 | struct type * \ | ||
509 | name##_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; \ | ||
569 | color: \ | ||
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 */ \ | ||
576 | struct type * \ | ||
577 | name##_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 */ \ | ||
607 | struct type * \ | ||
608 | name##_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 | \ | ||
624 | struct type * \ | ||
625 | name##_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 | \ | ||
645 | struct type * \ | ||
646 | name##_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 | |||
31 | void *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 | |||
23 | void *xmmap(size_t size); | ||