summaryrefslogtreecommitdiff
path: root/openbsd-compat
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-01-31 21:52:01 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-01-31 21:52:01 +0000
commit3c06f6a0b234822c7b2d6c63ef1aaf554af7167b (patch)
tree86e5fe626cb9cbade752baf2440badfa19976200 /openbsd-compat
parentbf75776d415126a415ac92fb767c70dc67feba4f (diff)
- (bal) Reorder. Move all bsd-*, fake-*, next-*, and cygwin* stuff to
openbsd-compat/. And resolve all ./configure and Makefile.in issues assocated. Logic: * All OpenBSD functions should have the same filename as in the OpenBSD tree * All 'home brew' functions have bsd-* infront of them. * All 'not really implemented' functions have fake-* infront of them.
Diffstat (limited to 'openbsd-compat')
-rw-r--r--openbsd-compat/Makefile.in33
-rw-r--r--openbsd-compat/base64.c316
-rw-r--r--openbsd-compat/base64.h16
-rw-r--r--openbsd-compat/bindresvport.c123
-rw-r--r--openbsd-compat/bindresvport.h10
-rw-r--r--openbsd-compat/bsd-arc4random.c71
-rw-r--r--openbsd-compat/bsd-arc4random.h35
-rw-r--r--openbsd-compat/bsd-cygwin_util.c105
-rw-r--r--openbsd-compat/bsd-cygwin_util.h28
-rw-r--r--openbsd-compat/bsd-misc.c94
-rw-r--r--openbsd-compat/bsd-misc.h70
-rw-r--r--openbsd-compat/bsd-nextstep.c100
-rw-r--r--openbsd-compat/bsd-nextstep.h52
-rw-r--r--openbsd-compat/bsd-snprintf.c818
-rw-r--r--openbsd-compat/bsd-snprintf.h17
-rw-r--r--openbsd-compat/bsd-waitpid.c48
-rw-r--r--openbsd-compat/bsd-waitpid.h47
-rw-r--r--openbsd-compat/daemon.c81
-rw-r--r--openbsd-compat/daemon.h9
-rw-r--r--openbsd-compat/fake-gai-errnos.h12
-rw-r--r--openbsd-compat/fake-getaddrinfo.c119
-rw-r--r--openbsd-compat/fake-getaddrinfo.h45
-rw-r--r--openbsd-compat/fake-getnameinfo.c53
-rw-r--r--openbsd-compat/fake-getnameinfo.h18
-rw-r--r--openbsd-compat/fake-regex.h106
-rw-r--r--openbsd-compat/fake-socket.h45
-rw-r--r--openbsd-compat/getcwd.c237
-rw-r--r--openbsd-compat/getcwd.h10
-rw-r--r--openbsd-compat/getgrouplist.c103
-rw-r--r--openbsd-compat/getgrouplist.h14
-rw-r--r--openbsd-compat/inet_aton.c193
-rw-r--r--openbsd-compat/inet_aton.h10
-rw-r--r--openbsd-compat/inet_ntoa.c64
-rw-r--r--openbsd-compat/inet_ntoa.h10
-rw-r--r--openbsd-compat/mktemp.c183
-rw-r--r--openbsd-compat/mktemp.h11
-rw-r--r--openbsd-compat/openbsd-compat.h37
-rw-r--r--openbsd-compat/queue.h490
-rw-r--r--openbsd-compat/realpath.c170
-rw-r--r--openbsd-compat/realpath.h11
-rw-r--r--openbsd-compat/rresvport.c106
-rw-r--r--openbsd-compat/rresvport.h10
-rw-r--r--openbsd-compat/setenv.c161
-rw-r--r--openbsd-compat/setenv.h12
-rw-r--r--openbsd-compat/setproctitle.c102
-rw-r--r--openbsd-compat/setproctitle.h10
-rw-r--r--openbsd-compat/sigaction.c102
-rw-r--r--openbsd-compat/sigaction.h88
-rw-r--r--openbsd-compat/strlcat.c76
-rw-r--r--openbsd-compat/strlcat.h10
-rw-r--r--openbsd-compat/strlcpy.c73
-rw-r--r--openbsd-compat/strlcpy.h10
-rw-r--r--openbsd-compat/strmode.c158
-rw-r--r--openbsd-compat/strmode.h5
-rw-r--r--openbsd-compat/strsep.c89
-rw-r--r--openbsd-compat/strsep.h10
-rw-r--r--openbsd-compat/strtok.c92
-rw-r--r--openbsd-compat/strtok.h10
-rw-r--r--openbsd-compat/vis.c137
-rw-r--r--openbsd-compat/vis.h32
60 files changed, 5307 insertions, 0 deletions
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
new file mode 100644
index 000000000..1c745fb8c
--- /dev/null
+++ b/openbsd-compat/Makefile.in
@@ -0,0 +1,33 @@
1sysconfdir=@sysconfdir@
2piddir=@piddir@
3srcdir=@srcdir@
4top_srcdir=@top_srcdir@
5
6CC=@CC@
7LD=@LD@
8CFLAGS=@CFLAGS@
9CPPFLAGS=@CPPFLAGS@ -I. -I.. -I$(srcdir) @DEFS@
10LIBS=@LIBS@
11AR=@AR@
12RANLIB=@RANLIB@
13INSTALL=@INSTALL@
14LDFLAGS=-L. @LDFLAGS@
15
16OPENBSD=base64.o bindresvport.o daemon.o getcwd.o getgrouplist.o inet_aton.o inet_ntoa.o mktemp.o realpath.o rresvport.o setenv.o setproctitle.o sigaction.o strlcat.o strlcpy.o strmode.o strsep.o strtok.o vis.o
17
18COMPAT=bsd-arc4random.o bsd-cygwin_util.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o
19
20
21all: libopenbsd-compat.a
22
23$(BSDCOMPAT): ../config.h
24
25libopenbsd-compat.a: $(COMPAT) $(OPENBSD)
26 $(AR) rv $@ $(COMPAT) $(OPENBSD)
27 $(RANLIB) $@
28
29clean:
30 rm -f *.o *.a core
31
32distclean: clean
33 rm -f Makefile *~
diff --git a/openbsd-compat/base64.c b/openbsd-compat/base64.c
new file mode 100644
index 000000000..d12b993b7
--- /dev/null
+++ b/openbsd-compat/base64.c
@@ -0,0 +1,316 @@
1/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include "config.h"
46
47#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)
48
49#include <sys/types.h>
50#include <sys/param.h>
51#include <sys/socket.h>
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <ctype.h>
56#include <stdio.h>
57
58#include <stdlib.h>
59#include <string.h>
60
61#include "base64.h"
62
63#define Assert(Cond) if (!(Cond)) abort()
64
65static const char Base64[] =
66 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
67static const char Pad64 = '=';
68
69/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
70 The following encoding technique is taken from RFC 1521 by Borenstein
71 and Freed. It is reproduced here in a slightly edited form for
72 convenience.
73
74 A 65-character subset of US-ASCII is used, enabling 6 bits to be
75 represented per printable character. (The extra 65th character, "=",
76 is used to signify a special processing function.)
77
78 The encoding process represents 24-bit groups of input bits as output
79 strings of 4 encoded characters. Proceeding from left to right, a
80 24-bit input group is formed by concatenating 3 8-bit input groups.
81 These 24 bits are then treated as 4 concatenated 6-bit groups, each
82 of which is translated into a single digit in the base64 alphabet.
83
84 Each 6-bit group is used as an index into an array of 64 printable
85 characters. The character referenced by the index is placed in the
86 output string.
87
88 Table 1: The Base64 Alphabet
89
90 Value Encoding Value Encoding Value Encoding Value Encoding
91 0 A 17 R 34 i 51 z
92 1 B 18 S 35 j 52 0
93 2 C 19 T 36 k 53 1
94 3 D 20 U 37 l 54 2
95 4 E 21 V 38 m 55 3
96 5 F 22 W 39 n 56 4
97 6 G 23 X 40 o 57 5
98 7 H 24 Y 41 p 58 6
99 8 I 25 Z 42 q 59 7
100 9 J 26 a 43 r 60 8
101 10 K 27 b 44 s 61 9
102 11 L 28 c 45 t 62 +
103 12 M 29 d 46 u 63 /
104 13 N 30 e 47 v
105 14 O 31 f 48 w (pad) =
106 15 P 32 g 49 x
107 16 Q 33 h 50 y
108
109 Special processing is performed if fewer than 24 bits are available
110 at the end of the data being encoded. A full encoding quantum is
111 always completed at the end of a quantity. When fewer than 24 input
112 bits are available in an input group, zero bits are added (on the
113 right) to form an integral number of 6-bit groups. Padding at the
114 end of the data is performed using the '=' character.
115
116 Since all base64 input is an integral number of octets, only the
117 -------------------------------------------------
118 following cases can arise:
119
120 (1) the final quantum of encoding input is an integral
121 multiple of 24 bits; here, the final unit of encoded
122 output will be an integral multiple of 4 characters
123 with no "=" padding,
124 (2) the final quantum of encoding input is exactly 8 bits;
125 here, the final unit of encoded output will be two
126 characters followed by two "=" padding characters, or
127 (3) the final quantum of encoding input is exactly 16 bits;
128 here, the final unit of encoded output will be three
129 characters followed by one "=" padding character.
130 */
131
132int
133b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
134{
135 size_t datalength = 0;
136 u_char input[3];
137 u_char output[4];
138 int i;
139
140 while (2 < srclength) {
141 input[0] = *src++;
142 input[1] = *src++;
143 input[2] = *src++;
144 srclength -= 3;
145
146 output[0] = input[0] >> 2;
147 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
148 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
149 output[3] = input[2] & 0x3f;
150 Assert(output[0] < 64);
151 Assert(output[1] < 64);
152 Assert(output[2] < 64);
153 Assert(output[3] < 64);
154
155 if (datalength + 4 > targsize)
156 return (-1);
157 target[datalength++] = Base64[output[0]];
158 target[datalength++] = Base64[output[1]];
159 target[datalength++] = Base64[output[2]];
160 target[datalength++] = Base64[output[3]];
161 }
162
163 /* Now we worry about padding. */
164 if (0 != srclength) {
165 /* Get what's left. */
166 input[0] = input[1] = input[2] = '\0';
167 for (i = 0; i < srclength; i++)
168 input[i] = *src++;
169
170 output[0] = input[0] >> 2;
171 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
172 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
173 Assert(output[0] < 64);
174 Assert(output[1] < 64);
175 Assert(output[2] < 64);
176
177 if (datalength + 4 > targsize)
178 return (-1);
179 target[datalength++] = Base64[output[0]];
180 target[datalength++] = Base64[output[1]];
181 if (srclength == 1)
182 target[datalength++] = Pad64;
183 else
184 target[datalength++] = Base64[output[2]];
185 target[datalength++] = Pad64;
186 }
187 if (datalength >= targsize)
188 return (-1);
189 target[datalength] = '\0'; /* Returned value doesn't count \0. */
190 return (datalength);
191}
192
193/* skips all whitespace anywhere.
194 converts characters, four at a time, starting at (or after)
195 src from base - 64 numbers into three 8 bit bytes in the target area.
196 it returns the number of data bytes stored at the target, or -1 on error.
197 */
198
199int
200b64_pton(char const *src, u_char *target, size_t targsize)
201{
202 int tarindex, state, ch;
203 char *pos;
204
205 state = 0;
206 tarindex = 0;
207
208 while ((ch = *src++) != '\0') {
209 if (isspace(ch)) /* Skip whitespace anywhere. */
210 continue;
211
212 if (ch == Pad64)
213 break;
214
215 pos = strchr(Base64, ch);
216 if (pos == 0) /* A non-base64 character. */
217 return (-1);
218
219 switch (state) {
220 case 0:
221 if (target) {
222 if (tarindex >= targsize)
223 return (-1);
224 target[tarindex] = (pos - Base64) << 2;
225 }
226 state = 1;
227 break;
228 case 1:
229 if (target) {
230 if (tarindex + 1 >= targsize)
231 return (-1);
232 target[tarindex] |= (pos - Base64) >> 4;
233 target[tarindex+1] = ((pos - Base64) & 0x0f)
234 << 4 ;
235 }
236 tarindex++;
237 state = 2;
238 break;
239 case 2:
240 if (target) {
241 if (tarindex + 1 >= targsize)
242 return (-1);
243 target[tarindex] |= (pos - Base64) >> 2;
244 target[tarindex+1] = ((pos - Base64) & 0x03)
245 << 6;
246 }
247 tarindex++;
248 state = 3;
249 break;
250 case 3:
251 if (target) {
252 if (tarindex >= targsize)
253 return (-1);
254 target[tarindex] |= (pos - Base64);
255 }
256 tarindex++;
257 state = 0;
258 break;
259 }
260 }
261
262 /*
263 * We are done decoding Base-64 chars. Let's see if we ended
264 * on a byte boundary, and/or with erroneous trailing characters.
265 */
266
267 if (ch == Pad64) { /* We got a pad char. */
268 ch = *src++; /* Skip it, get next. */
269 switch (state) {
270 case 0: /* Invalid = in first position */
271 case 1: /* Invalid = in second position */
272 return (-1);
273
274 case 2: /* Valid, means one byte of info */
275 /* Skip any number of spaces. */
276 for (; ch != '\0'; ch = *src++)
277 if (!isspace(ch))
278 break;
279 /* Make sure there is another trailing = sign. */
280 if (ch != Pad64)
281 return (-1);
282 ch = *src++; /* Skip the = */
283 /* Fall through to "single trailing =" case. */
284 /* FALLTHROUGH */
285
286 case 3: /* Valid, means two bytes of info */
287 /*
288 * We know this char is an =. Is there anything but
289 * whitespace after it?
290 */
291 for (; ch != '\0'; ch = *src++)
292 if (!isspace(ch))
293 return (-1);
294
295 /*
296 * Now make sure for cases 2 and 3 that the "extra"
297 * bits that slopped past the last full byte were
298 * zeros. If we don't check them, they become a
299 * subliminal channel.
300 */
301 if (target && target[tarindex] != 0)
302 return (-1);
303 }
304 } else {
305 /*
306 * We ended by seeing the end of the string. Make sure we
307 * have no partial bytes lying around.
308 */
309 if (state != 0)
310 return (-1);
311 }
312
313 return (tarindex);
314}
315
316#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */
diff --git a/openbsd-compat/base64.h b/openbsd-compat/base64.h
new file mode 100644
index 000000000..c1d69dd6c
--- /dev/null
+++ b/openbsd-compat/base64.h
@@ -0,0 +1,16 @@
1#ifndef _BSD_BASE64_H
2#define _BSD_BASE64_H
3
4#include "config.h"
5
6#ifndef HAVE___B64_NTOP
7# ifndef HAVE_B64_NTOP
8int b64_ntop(u_char const *src, size_t srclength, char *target,
9 size_t targsize);
10int b64_pton(char const *src, u_char *target, size_t targsize);
11# endif /* !HAVE_B64_NTOP */
12# define __b64_ntop b64_ntop
13# define __b64_pton b64_pton
14#endif /* HAVE___B64_NTOP */
15
16#endif /* _BSD_BINRESVPORT_H */
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c
new file mode 100644
index 000000000..332bcb016
--- /dev/null
+++ b/openbsd-compat/bindresvport.c
@@ -0,0 +1,123 @@
1/* This file has be modified from the original OpenBSD source */
2
3/*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
10 *
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 *
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
18 *
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
22 *
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
26 *
27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue
29 * Mountain View, California 94043
30 */
31
32#include "config.h"
33
34#ifndef HAVE_BINDRESVPORT_SA
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40/*
41 * Copyright (c) 1987 by Sun Microsystems, Inc.
42 *
43 * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
44 */
45
46#include "includes.h"
47
48#define STARTPORT 600
49#define ENDPORT (IPPORT_RESERVED - 1)
50#define NPORTS (ENDPORT - STARTPORT + 1)
51
52/*
53 * Bind a socket to a privileged IP port
54 */
55int
56bindresvport_sa(sd, sa)
57 int sd;
58 struct sockaddr *sa;
59{
60 int error, af;
61 struct sockaddr_storage myaddr;
62 struct sockaddr_in *sin;
63 struct sockaddr_in6 *sin6;
64 u_int16_t *portp;
65 u_int16_t port;
66 socklen_t salen;
67 int i;
68
69 if (sa == NULL) {
70 memset(&myaddr, 0, sizeof(myaddr));
71 sa = (struct sockaddr *)&myaddr;
72
73 if (getsockname(sd, sa, &salen) == -1)
74 return -1; /* errno is correctly set */
75
76 af = sa->sa_family;
77 memset(&myaddr, 0, salen);
78 } else
79 af = sa->sa_family;
80
81 if (af == AF_INET) {
82 sin = (struct sockaddr_in *)sa;
83 salen = sizeof(struct sockaddr_in);
84 portp = &sin->sin_port;
85 } else if (af == AF_INET6) {
86 sin6 = (struct sockaddr_in6 *)sa;
87 salen = sizeof(struct sockaddr_in6);
88 portp = &sin6->sin6_port;
89 } else {
90 errno = EPFNOSUPPORT;
91 return (-1);
92 }
93 sa->sa_family = af;
94
95 port = ntohs(*portp);
96 if (port == 0)
97 port = (arc4random() % NPORTS) + STARTPORT;
98
99 /* Avoid warning */
100 error = -1;
101
102 for(i = 0; i < NPORTS; i++) {
103 *portp = htons(port);
104
105 error = bind(sd, sa, salen);
106
107 /* Terminate on success */
108 if (error == 0)
109 break;
110
111 /* Terminate on errors, except "address already in use" */
112 if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL)))
113 break;
114
115 port++;
116 if (port > ENDPORT)
117 port = STARTPORT;
118 }
119
120 return (error);
121}
122
123#endif /* HAVE_BINDRESVPORT_SA */
diff --git a/openbsd-compat/bindresvport.h b/openbsd-compat/bindresvport.h
new file mode 100644
index 000000000..6dbf8a2cb
--- /dev/null
+++ b/openbsd-compat/bindresvport.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_BINDRESVPORT_H
2#define _BSD_BINDRESVPORT_H
3
4#include "config.h"
5
6#ifndef HAVE_BINDRESVPORT_SA
7int bindresvport_sa(int sd, struct sockaddr *sa);
8#endif /* !HAVE_BINDRESVPORT_SA */
9
10#endif /* _BSD_BINDRESVPORT_H */
diff --git a/openbsd-compat/bsd-arc4random.c b/openbsd-compat/bsd-arc4random.c
new file mode 100644
index 000000000..c45459f59
--- /dev/null
+++ b/openbsd-compat/bsd-arc4random.c
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 1999-2000 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#ifndef HAVE_ARC4RANDOM
28
29#include <openssl/rand.h>
30#include <openssl/rc4.h>
31
32/* Size of key to use */
33#define SEED_SIZE 20
34
35/* Number of bytes to reseed after */
36#define REKEY_BYTES (1 << 24)
37
38static int rc4_ready = 0;
39static RC4_KEY rc4;
40
41unsigned int arc4random(void)
42{
43 unsigned int r = 0;
44
45 if (rc4_ready <= 0)
46 arc4random_stir();
47
48 RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
49
50 rc4_ready -= sizeof(r);
51
52 return(r);
53}
54
55void arc4random_stir(void)
56{
57 unsigned char rand_buf[SEED_SIZE];
58
59 memset(&rc4, 0, sizeof(rc4));
60
61 seed_rng();
62
63 RAND_bytes(rand_buf, sizeof(rand_buf));
64
65 RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
66
67 memset(rand_buf, 0, sizeof(rand_buf));
68
69 rc4_ready = REKEY_BYTES;
70}
71#endif /* !HAVE_ARC4RANDOM */
diff --git a/openbsd-compat/bsd-arc4random.h b/openbsd-compat/bsd-arc4random.h
new file mode 100644
index 000000000..9819b848c
--- /dev/null
+++ b/openbsd-compat/bsd-arc4random.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 1999-2000 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#ifndef _BSD_ARC4RANDOM_H
26#define _BSD_ARC4RANDOM_H
27
28#include "config.h"
29
30#ifndef HAVE_ARC4RANDOM
31unsigned int arc4random(void);
32void arc4random_stir(void);
33#endif /* !HAVE_ARC4RANDOM */
34
35#endif /* _BSD_ARC4RANDOM_H */
diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c
new file mode 100644
index 000000000..b540ebe1a
--- /dev/null
+++ b/openbsd-compat/bsd-cygwin_util.c
@@ -0,0 +1,105 @@
1/*
2 *
3 * cygwin_util.c
4 *
5 * Author: Corinna Vinschen <vinschen@cygnus.com>
6 *
7 * Copyright (c) 2000 Corinna Vinschen <vinschen@cygnus.com>, Duisburg, Germany
8 * All rights reserved
9 *
10 * Created: Sat Sep 02 12:17:00 2000 cv
11 *
12 * This file contains functions for forcing opened file descriptors to
13 * binary mode on Windows systems.
14 */
15
16#include "config.h"
17
18#ifdef HAVE_CYGWIN
19
20#include <fcntl.h>
21#include <io.h>
22#include <stdlib.h>
23#include <sys/vfs.h>
24#include <windows.h>
25#define is_winnt (GetVersion() < 0x80000000)
26
27int binary_open(const char *filename, int flags, mode_t mode)
28{
29 return open(filename, flags | O_BINARY, mode);
30}
31
32int binary_pipe(int fd[2])
33{
34 int ret = pipe(fd);
35
36 if (!ret) {
37 setmode (fd[0], O_BINARY);
38 setmode (fd[1], O_BINARY);
39 }
40 return ret;
41}
42
43int check_nt_auth(int pwd_authenticated, uid_t uid)
44{
45 /*
46 * The only authentication which is able to change the user
47 * context on NT systems is the password authentication. So
48 * we deny all requsts for changing the user context if another
49 * authentication method is used.
50 * This may change in future when a special openssh
51 * subauthentication package is available.
52 */
53 if (is_winnt && !pwd_authenticated && geteuid() != uid)
54 return 0;
55
56 return 1;
57}
58
59int check_ntsec(const char *filename)
60{
61 char *cygwin;
62 int allow_ntea = 0;
63 int allow_ntsec = 0;
64 struct statfs fsstat;
65
66 /* Windows 95/98/ME don't support file system security at all. */
67 if (!is_winnt)
68 return 0;
69
70 /* Evaluate current CYGWIN settings. */
71 if ((cygwin = getenv("CYGWIN")) != NULL) {
72 if (strstr(cygwin, "ntea") && !strstr(cygwin, "nontea"))
73 allow_ntea = 1;
74 if (strstr(cygwin, "ntsec") && !strstr(cygwin, "nontsec"))
75 allow_ntsec = 1;
76 }
77
78 /*
79 * `ntea' is an emulation of POSIX attributes. It doesn't support
80 * real file level security as ntsec on NTFS file systems does
81 * but it supports FAT filesystems. `ntea' is minimum requirement
82 * for security checks.
83 */
84 if (allow_ntea)
85 return 1;
86
87 /*
88 * Retrieve file system flags. In Cygwin, file system flags are
89 * copied to f_type which has no meaning in Win32 itself.
90 */
91 if (statfs(filename, &fsstat))
92 return 1;
93
94 /*
95 * Only file systems supporting ACLs are able to set permissions.
96 * `ntsec' is the setting in Cygwin which switches using of NTFS
97 * ACLs to support POSIX permissions on files.
98 */
99 if (fsstat.f_type & FS_PERSISTENT_ACLS)
100 return allow_ntsec;
101
102 return 0;
103}
104
105#endif /* HAVE_CYGWIN */
diff --git a/openbsd-compat/bsd-cygwin_util.h b/openbsd-compat/bsd-cygwin_util.h
new file mode 100644
index 000000000..bf90d0293
--- /dev/null
+++ b/openbsd-compat/bsd-cygwin_util.h
@@ -0,0 +1,28 @@
1/*
2 *
3 * cygwin_util.c
4 *
5 * Author: Corinna Vinschen <vinschen@cygnus.com>
6 *
7 * Copyright (c) 2000 Corinna Vinschen <vinschen@cygnus.com>, Duisburg, Germany
8 * All rights reserved
9 *
10 * Created: Sat Sep 02 12:17:00 2000 cv
11 *
12 * This file contains functions for forcing opened file descriptors to
13 * binary mode on Windows systems.
14 */
15
16#include "config.h"
17
18#ifdef HAVE_CYGWIN
19
20int binary_open(const char *filename, int flags, ...);
21int binary_pipe(int fd[2]);
22int check_nt_auth(int pwd_authenticated, uid_t uid);
23int check_ntsec(const char *filename);
24
25#define open binary_open
26#define pipe binary_pipe
27
28#endif /* HAVE_CYGWIN */
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c
new file mode 100644
index 000000000..2e59019bc
--- /dev/null
+++ b/openbsd-compat/bsd-misc.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 1999-2000 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#include "xmalloc.h"
27#include "ssh.h"
28
29char *get_progname(char *argv0)
30{
31#ifdef HAVE___PROGNAME
32 extern char *__progname;
33
34 return __progname;
35#else
36 char *p;
37
38 if (argv0 == NULL)
39 return "unknown"; /* XXX */
40 p = strrchr(argv0, '/');
41 if (p == NULL)
42 p = argv0;
43 else
44 p++;
45 return p;
46#endif
47}
48
49#ifndef HAVE_SETLOGIN
50int setlogin(const char *name)
51{
52 return(0);
53}
54#endif /* !HAVE_SETLOGIN */
55
56#ifndef HAVE_INNETGR
57int innetgr(const char *netgroup, const char *host,
58 const char *user, const char *domain)
59{
60 return(0);
61}
62#endif /* HAVE_INNETGR */
63
64#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
65int seteuid(uid_t euid)
66{
67 return(setreuid(-1,euid));
68}
69#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
70
71#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR)
72const char *strerror(int e)
73{
74 extern int sys_nerr;
75 extern char *sys_errlist[];
76
77 if ((e >= 0) || (e < sys_nerr))
78 return("unlisted error");
79 else
80 return(sys_errlist[e]);
81}
82#endif
83
84#ifndef HAVE_UTIMES
85int utimes(char *filename, struct timeval *tvp)
86{
87 struct utimbuf ub;
88
89 ub.actime = tvp->tv_sec;
90 ub.modtime = tvp->tv_usec;
91
92 return(utime(filename, &ub));
93}
94#endif
diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
new file mode 100644
index 000000000..e02c66783
--- /dev/null
+++ b/openbsd-compat/bsd-misc.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 1999-2000 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#ifndef _BSD_MISC_H
26#define _BSD_MISC_H
27
28#include "config.h"
29
30char *get_progname(char *argv0);
31
32#ifndef HAVE_SETSID
33#define setsid() setpgrp(0, getpid())
34#endif /* !HAVE_SETSID */
35
36#ifndef HAVE_SETENV
37int setenv(const char *name, const char *value, int overwrite);
38#endif /* !HAVE_SETENV */
39
40#ifndef HAVE_SETLOGIN
41int setlogin(const char *name);
42#endif /* !HAVE_SETLOGIN */
43
44#ifndef HAVE_INNETGR
45int innetgr(const char *netgroup, const char *host,
46 const char *user, const char *domain);
47#endif /* HAVE_INNETGR */
48
49#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
50int seteuid(uid_t euid);
51#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
52
53#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR)
54const char *strerror(int e);
55#endif
56
57
58#ifndef HAVE_UTIMES
59#ifndef HAVE_STRUCT_TIMEVAL
60struct timeval {
61 long tv_sec;
62 long tv_usec;
63}
64#endif /* HAVE_STRUCT_TIMEVAL */
65
66int utimes(char *filename, struct timeval *tvp);
67#endif /* HAVE_UTIMES */
68
69
70#endif /* _BSD_MISC_H */
diff --git a/openbsd-compat/bsd-nextstep.c b/openbsd-compat/bsd-nextstep.c
new file mode 100644
index 000000000..43ec0acd9
--- /dev/null
+++ b/openbsd-compat/bsd-nextstep.c
@@ -0,0 +1,100 @@
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_NEXT
26#include <errno.h>
27#include <sys/wait.h>
28#include "next-posix.h"
29
30pid_t
31posix_wait(int *status)
32{
33 union wait statusp;
34 pid_t wait_pid;
35
36 #undef wait /* Use NeXT's wait() function */
37 wait_pid = wait(&statusp);
38 status = (int *) statusp.w_status;
39
40 return wait_pid;
41}
42
43int
44tcgetattr(int fd, struct termios *t)
45{
46 return (ioctl(fd, TIOCGETA, t));
47}
48
49int
50tcsetattr(int fd, int opt, const struct termios *t)
51{
52 struct termios localterm;
53
54 if (opt & TCSASOFT) {
55 localterm = *t;
56 localterm.c_cflag |= CIGNORE;
57 t = &localterm;
58 }
59 switch (opt & ~TCSASOFT) {
60 case TCSANOW:
61 return (ioctl(fd, TIOCSETA, t));
62 case TCSADRAIN:
63 return (ioctl(fd, TIOCSETAW, t));
64 case TCSAFLUSH:
65 return (ioctl(fd, TIOCSETAF, t));
66 default:
67 errno = EINVAL;
68 return (-1);
69 }
70}
71
72int tcsetpgrp(int fd, pid_t pgrp)
73{
74 return (ioctl(fd, TIOCSPGRP, &pgrp));
75}
76
77speed_t cfgetospeed(const struct termios *t)
78{
79 return (t->c_ospeed);
80}
81
82speed_t cfgetispeed(const struct termios *t)
83{
84 return (t->c_ispeed);
85}
86
87int
88cfsetospeed(struct termios *t,int speed)
89{
90 t->c_ospeed = speed;
91 return (0);
92}
93
94int
95cfsetispeed(struct termios *t, int speed)
96{
97 t->c_ispeed = speed;
98 return (0);
99}
100#endif /* HAVE_NEXT */
diff --git a/openbsd-compat/bsd-nextstep.h b/openbsd-compat/bsd-nextstep.h
new file mode 100644
index 000000000..3e16dacb9
--- /dev/null
+++ b/openbsd-compat/bsd-nextstep.h
@@ -0,0 +1,52 @@
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
24#ifndef _NEXT_POSIX_H
25#define _NEXT_POSIX_H
26
27#ifdef HAVE_NEXT
28#include <sys/dir.h>
29
30/* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */
31#define dirent direct
32
33/* Swap out NeXT's BSD wait() for a more POSIX complient one */
34pid_t posix_wait(int *status);
35#define wait(a) posix_wait(a)
36
37/* #ifdef wrapped functions that need defining for clean compiling */
38pid_t getppid(void);
39void vhangup(void);
40int innetgr(const char *netgroup, const char *host, const char *user,
41 const char *domain);
42
43/* TERMCAP */
44int tcgetattr(int fd, struct termios *t);
45int tcsetattr(int fd, int opt, const struct termios *t);
46int tcsetpgrp(int fd, pid_t pgrp);
47speed_t cfgetospeed(const struct termios *t);
48speed_t cfgetispeed(const struct termios *t);
49int cfsetospeed(struct termios *t, int speed);
50int cfsetispeed(struct termios *t, int speed);
51#endif /* HAVE_NEXT */
52#endif /* _NEXT_POSIX_H */
diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c
new file mode 100644
index 000000000..59fefbf25
--- /dev/null
+++ b/openbsd-compat/bsd-snprintf.c
@@ -0,0 +1,818 @@
1/**************************************************************
2 * Original:
3 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
4 * A bombproof version of doprnt (dopr) included.
5 * Sigh. This sort of thing is always nasty do deal with. Note that
6 * the version here does not include floating point...
7 *
8 * snprintf() is used instead of sprintf() as it does limit checks
9 * for string length. This covers a nasty loophole.
10 *
11 * The other functions are there to prevent NULL pointers from
12 * causing nast effects.
13 *
14 * More Recently:
15 * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
16 * This was ugly. It is still ugly. I opted out of floating point
17 * numbers, but the formatter understands just about everything
18 * from the normal C string format, at least as far as I can tell from
19 * the Solaris 2.5 printf(3S) man page.
20 *
21 * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
22 * Ok, added some minimal floating point support, which means this
23 * probably requires libm on most operating systems. Don't yet
24 * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
25 * was pretty badly broken, it just wasn't being exercised in ways
26 * which showed it, so that's been fixed. Also, formated the code
27 * to mutt conventions, and removed dead code left over from the
28 * original. Also, there is now a builtin-test, just compile with:
29 * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
30 * and run snprintf for results.
31 *
32 * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
33 * The PGP code was using unsigned hexadecimal formats.
34 * Unfortunately, unsigned formats simply didn't work.
35 *
36 * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
37 * The original code assumed that both snprintf() and vsnprintf() were
38 * missing. Some systems only have snprintf() but not vsnprintf(), so
39 * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
40 *
41 * Ben Lindstrom <mouring@pconline.com> 09/27/00 for OpenSSH
42 * Welcome to the world of %lld and %qd support. With other
43 * long long support. This is needed for sftp-server to work
44 * right.
45 **************************************************************/
46
47#include "config.h"
48
49#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
50
51#include <string.h>
52# include <ctype.h>
53#include <sys/types.h>
54
55/* Define this as a fall through, HAVE_STDARG_H is probably already set */
56
57#define HAVE_VARARGS_H
58
59/* varargs declarations: */
60
61#if defined(HAVE_STDARG_H)
62# include <stdarg.h>
63# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
64# define VA_LOCAL_DECL va_list ap
65# define VA_START(f) va_start(ap, f)
66# define VA_SHIFT(v,t) ; /* no-op for ANSI */
67# define VA_END va_end(ap)
68#else
69# if defined(HAVE_VARARGS_H)
70# include <varargs.h>
71# undef HAVE_STDARGS
72# define VA_LOCAL_DECL va_list ap
73# define VA_START(f) va_start(ap) /* f is ignored! */
74# define VA_SHIFT(v,t) v = va_arg(ap,t)
75# define VA_END va_end(ap)
76# else
77/*XX ** NO VARARGS ** XX*/
78# endif
79#endif
80
81/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
82/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
83
84static void dopr (char *buffer, size_t maxlen, const char *format,
85 va_list args);
86static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
87 char *value, int flags, int min, int max);
88static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
89 long value, int base, int min, int max, int flags);
90static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
91 long double fvalue, int min, int max, int flags);
92static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
93
94/*
95 * dopr(): poor man's version of doprintf
96 */
97
98/* format read states */
99#define DP_S_DEFAULT 0
100#define DP_S_FLAGS 1
101#define DP_S_MIN 2
102#define DP_S_DOT 3
103#define DP_S_MAX 4
104#define DP_S_MOD 5
105#define DP_S_CONV 6
106#define DP_S_DONE 7
107
108/* format flags - Bits */
109#define DP_F_MINUS (1 << 0)
110#define DP_F_PLUS (1 << 1)
111#define DP_F_SPACE (1 << 2)
112#define DP_F_NUM (1 << 3)
113#define DP_F_ZERO (1 << 4)
114#define DP_F_UP (1 << 5)
115#define DP_F_UNSIGNED (1 << 6)
116
117/* Conversion Flags */
118#define DP_C_SHORT 1
119#define DP_C_LONG 2
120#define DP_C_LDOUBLE 3
121#define DP_C_LONG_LONG 4
122
123#define char_to_int(p) (p - '0')
124#ifndef MAX
125# define MAX(p,q) ((p >= q) ? p : q)
126#endif
127
128static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
129{
130 char ch;
131 long value;
132 long double fvalue;
133 char *strvalue;
134 int min;
135 int max;
136 int state;
137 int flags;
138 int cflags;
139 size_t currlen;
140
141 state = DP_S_DEFAULT;
142 currlen = flags = cflags = min = 0;
143 max = -1;
144 ch = *format++;
145
146 while (state != DP_S_DONE)
147 {
148 if ((ch == '\0') || (currlen >= maxlen))
149 state = DP_S_DONE;
150
151 switch(state)
152 {
153 case DP_S_DEFAULT:
154 if (ch == '%')
155 state = DP_S_FLAGS;
156 else
157 dopr_outch (buffer, &currlen, maxlen, ch);
158 ch = *format++;
159 break;
160 case DP_S_FLAGS:
161 switch (ch)
162 {
163 case '-':
164 flags |= DP_F_MINUS;
165 ch = *format++;
166 break;
167 case '+':
168 flags |= DP_F_PLUS;
169 ch = *format++;
170 break;
171 case ' ':
172 flags |= DP_F_SPACE;
173 ch = *format++;
174 break;
175 case '#':
176 flags |= DP_F_NUM;
177 ch = *format++;
178 break;
179 case '0':
180 flags |= DP_F_ZERO;
181 ch = *format++;
182 break;
183 default:
184 state = DP_S_MIN;
185 break;
186 }
187 break;
188 case DP_S_MIN:
189 if (isdigit((unsigned char)ch))
190 {
191 min = 10*min + char_to_int (ch);
192 ch = *format++;
193 }
194 else if (ch == '*')
195 {
196 min = va_arg (args, int);
197 ch = *format++;
198 state = DP_S_DOT;
199 }
200 else
201 state = DP_S_DOT;
202 break;
203 case DP_S_DOT:
204 if (ch == '.')
205 {
206 state = DP_S_MAX;
207 ch = *format++;
208 }
209 else
210 state = DP_S_MOD;
211 break;
212 case DP_S_MAX:
213 if (isdigit((unsigned char)ch))
214 {
215 if (max < 0)
216 max = 0;
217 max = 10*max + char_to_int (ch);
218 ch = *format++;
219 }
220 else if (ch == '*')
221 {
222 max = va_arg (args, int);
223 ch = *format++;
224 state = DP_S_MOD;
225 }
226 else
227 state = DP_S_MOD;
228 break;
229 case DP_S_MOD:
230 switch (ch)
231 {
232 case 'h':
233 cflags = DP_C_SHORT;
234 ch = *format++;
235 break;
236 case 'l':
237 cflags = DP_C_LONG;
238 ch = *format++;
239 if (ch == 'l') {
240 cflags = DP_C_LONG_LONG;
241 ch = *format++;
242 }
243 break;
244 case 'q':
245 cflags = DP_C_LONG_LONG;
246 ch = *format++;
247 break;
248 case 'L':
249 cflags = DP_C_LDOUBLE;
250 ch = *format++;
251 break;
252 default:
253 break;
254 }
255 state = DP_S_CONV;
256 break;
257 case DP_S_CONV:
258 switch (ch)
259 {
260 case 'd':
261 case 'i':
262 if (cflags == DP_C_SHORT)
263 value = va_arg (args, int);
264 else if (cflags == DP_C_LONG)
265 value = va_arg (args, long int);
266 else if (cflags == DP_C_LONG_LONG)
267 value = va_arg (args, long long);
268 else
269 value = va_arg (args, int);
270 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
271 break;
272 case 'o':
273 flags |= DP_F_UNSIGNED;
274 if (cflags == DP_C_SHORT)
275 value = va_arg (args, unsigned int);
276 else if (cflags == DP_C_LONG)
277 value = va_arg (args, unsigned long int);
278 else if (cflags == DP_C_LONG_LONG)
279 value = va_arg (args, unsigned long long);
280 else
281 value = va_arg (args, unsigned int);
282 fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
283 break;
284 case 'u':
285 flags |= DP_F_UNSIGNED;
286 if (cflags == DP_C_SHORT)
287 value = va_arg (args, unsigned int);
288 else if (cflags == DP_C_LONG)
289 value = va_arg (args, unsigned long int);
290 else if (cflags == DP_C_LONG_LONG)
291 value = va_arg (args, unsigned long long);
292 else
293 value = va_arg (args, unsigned int);
294 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
295 break;
296 case 'X':
297 flags |= DP_F_UP;
298 case 'x':
299 flags |= DP_F_UNSIGNED;
300 if (cflags == DP_C_SHORT)
301 value = va_arg (args, unsigned int);
302 else if (cflags == DP_C_LONG)
303 value = va_arg (args, unsigned long int);
304 else if (cflags == DP_C_LONG_LONG)
305 value = va_arg (args, unsigned long long);
306 else
307 value = va_arg (args, unsigned int);
308 fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
309 break;
310 case 'f':
311 if (cflags == DP_C_LDOUBLE)
312 fvalue = va_arg (args, long double);
313 else
314 fvalue = va_arg (args, double);
315 /* um, floating point? */
316 fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
317 break;
318 case 'E':
319 flags |= DP_F_UP;
320 case 'e':
321 if (cflags == DP_C_LDOUBLE)
322 fvalue = va_arg (args, long double);
323 else
324 fvalue = va_arg (args, double);
325 break;
326 case 'G':
327 flags |= DP_F_UP;
328 case 'g':
329 if (cflags == DP_C_LDOUBLE)
330 fvalue = va_arg (args, long double);
331 else
332 fvalue = va_arg (args, double);
333 break;
334 case 'c':
335 dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
336 break;
337 case 's':
338 strvalue = va_arg (args, char *);
339 if (max < 0)
340 max = maxlen; /* ie, no max */
341 fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
342 break;
343 case 'p':
344 strvalue = va_arg (args, void *);
345 fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
346 break;
347 case 'n':
348 if (cflags == DP_C_SHORT)
349 {
350 short int *num;
351 num = va_arg (args, short int *);
352 *num = currlen;
353 }
354 else if (cflags == DP_C_LONG)
355 {
356 long int *num;
357 num = va_arg (args, long int *);
358 *num = currlen;
359 }
360 else if (cflags == DP_C_LONG_LONG)
361 {
362 long long *num;
363 num = va_arg (args, long long *);
364 *num = currlen;
365 }
366 else
367 {
368 int *num;
369 num = va_arg (args, int *);
370 *num = currlen;
371 }
372 break;
373 case '%':
374 dopr_outch (buffer, &currlen, maxlen, ch);
375 break;
376 case 'w':
377 /* not supported yet, treat as next char */
378 ch = *format++;
379 break;
380 default:
381 /* Unknown, skip */
382 break;
383 }
384 ch = *format++;
385 state = DP_S_DEFAULT;
386 flags = cflags = min = 0;
387 max = -1;
388 break;
389 case DP_S_DONE:
390 break;
391 default:
392 /* hmm? */
393 break; /* some picky compilers need this */
394 }
395 }
396 if (currlen < maxlen - 1)
397 buffer[currlen] = '\0';
398 else
399 buffer[maxlen - 1] = '\0';
400}
401
402static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
403 char *value, int flags, int min, int max)
404{
405 int padlen, strln; /* amount to pad */
406 int cnt = 0;
407
408 if (value == 0)
409 {
410 value = "<NULL>";
411 }
412
413 for (strln = 0; value[strln]; ++strln); /* strlen */
414 padlen = min - strln;
415 if (padlen < 0)
416 padlen = 0;
417 if (flags & DP_F_MINUS)
418 padlen = -padlen; /* Left Justify */
419
420 while ((padlen > 0) && (cnt < max))
421 {
422 dopr_outch (buffer, currlen, maxlen, ' ');
423 --padlen;
424 ++cnt;
425 }
426 while (*value && (cnt < max))
427 {
428 dopr_outch (buffer, currlen, maxlen, *value++);
429 ++cnt;
430 }
431 while ((padlen < 0) && (cnt < max))
432 {
433 dopr_outch (buffer, currlen, maxlen, ' ');
434 ++padlen;
435 ++cnt;
436 }
437}
438
439/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
440
441static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
442 long value, int base, int min, int max, int flags)
443{
444 int signvalue = 0;
445 unsigned long uvalue;
446 char convert[20];
447 int place = 0;
448 int spadlen = 0; /* amount to space pad */
449 int zpadlen = 0; /* amount to zero pad */
450 int caps = 0;
451
452 if (max < 0)
453 max = 0;
454
455 uvalue = value;
456
457 if(!(flags & DP_F_UNSIGNED))
458 {
459 if( value < 0 ) {
460 signvalue = '-';
461 uvalue = -value;
462 }
463 else
464 if (flags & DP_F_PLUS) /* Do a sign (+/i) */
465 signvalue = '+';
466 else
467 if (flags & DP_F_SPACE)
468 signvalue = ' ';
469 }
470
471 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
472
473 do {
474 convert[place++] =
475 (caps? "0123456789ABCDEF":"0123456789abcdef")
476 [uvalue % (unsigned)base ];
477 uvalue = (uvalue / (unsigned)base );
478 } while(uvalue && (place < 20));
479 if (place == 20) place--;
480 convert[place] = 0;
481
482 zpadlen = max - place;
483 spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
484 if (zpadlen < 0) zpadlen = 0;
485 if (spadlen < 0) spadlen = 0;
486 if (flags & DP_F_ZERO)
487 {
488 zpadlen = MAX(zpadlen, spadlen);
489 spadlen = 0;
490 }
491 if (flags & DP_F_MINUS)
492 spadlen = -spadlen; /* Left Justifty */
493
494#ifdef DEBUG_SNPRINTF
495 dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
496 zpadlen, spadlen, min, max, place));
497#endif
498
499 /* Spaces */
500 while (spadlen > 0)
501 {
502 dopr_outch (buffer, currlen, maxlen, ' ');
503 --spadlen;
504 }
505
506 /* Sign */
507 if (signvalue)
508 dopr_outch (buffer, currlen, maxlen, signvalue);
509
510 /* Zeros */
511 if (zpadlen > 0)
512 {
513 while (zpadlen > 0)
514 {
515 dopr_outch (buffer, currlen, maxlen, '0');
516 --zpadlen;
517 }
518 }
519
520 /* Digits */
521 while (place > 0)
522 dopr_outch (buffer, currlen, maxlen, convert[--place]);
523
524 /* Left Justified spaces */
525 while (spadlen < 0) {
526 dopr_outch (buffer, currlen, maxlen, ' ');
527 ++spadlen;
528 }
529}
530
531static long double abs_val (long double value)
532{
533 long double result = value;
534
535 if (value < 0)
536 result = -value;
537
538 return result;
539}
540
541static long double pow10 (int exp)
542{
543 long double result = 1;
544
545 while (exp)
546 {
547 result *= 10;
548 exp--;
549 }
550
551 return result;
552}
553
554static long round (long double value)
555{
556 long intpart;
557
558 intpart = value;
559 value = value - intpart;
560 if (value >= 0.5)
561 intpart++;
562
563 return intpart;
564}
565
566static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
567 long double fvalue, int min, int max, int flags)
568{
569 int signvalue = 0;
570 long double ufvalue;
571 char iconvert[20];
572 char fconvert[20];
573 int iplace = 0;
574 int fplace = 0;
575 int padlen = 0; /* amount to pad */
576 int zpadlen = 0;
577 int caps = 0;
578 long intpart;
579 long fracpart;
580
581 /*
582 * AIX manpage says the default is 0, but Solaris says the default
583 * is 6, and sprintf on AIX defaults to 6
584 */
585 if (max < 0)
586 max = 6;
587
588 ufvalue = abs_val (fvalue);
589
590 if (fvalue < 0)
591 signvalue = '-';
592 else
593 if (flags & DP_F_PLUS) /* Do a sign (+/i) */
594 signvalue = '+';
595 else
596 if (flags & DP_F_SPACE)
597 signvalue = ' ';
598
599#if 0
600 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
601#endif
602
603 intpart = ufvalue;
604
605 /*
606 * Sorry, we only support 9 digits past the decimal because of our
607 * conversion method
608 */
609 if (max > 9)
610 max = 9;
611
612 /* We "cheat" by converting the fractional part to integer by
613 * multiplying by a factor of 10
614 */
615 fracpart = round ((pow10 (max)) * (ufvalue - intpart));
616
617 if (fracpart >= pow10 (max))
618 {
619 intpart++;
620 fracpart -= pow10 (max);
621 }
622
623#ifdef DEBUG_SNPRINTF
624 dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
625#endif
626
627 /* Convert integer part */
628 do {
629 iconvert[iplace++] =
630 (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
631 intpart = (intpart / 10);
632 } while(intpart && (iplace < 20));
633 if (iplace == 20) iplace--;
634 iconvert[iplace] = 0;
635
636 /* Convert fractional part */
637 do {
638 fconvert[fplace++] =
639 (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
640 fracpart = (fracpart / 10);
641 } while(fracpart && (fplace < 20));
642 if (fplace == 20) fplace--;
643 fconvert[fplace] = 0;
644
645 /* -1 for decimal point, another -1 if we are printing a sign */
646 padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
647 zpadlen = max - fplace;
648 if (zpadlen < 0)
649 zpadlen = 0;
650 if (padlen < 0)
651 padlen = 0;
652 if (flags & DP_F_MINUS)
653 padlen = -padlen; /* Left Justifty */
654
655 if ((flags & DP_F_ZERO) && (padlen > 0))
656 {
657 if (signvalue)
658 {
659 dopr_outch (buffer, currlen, maxlen, signvalue);
660 --padlen;
661 signvalue = 0;
662 }
663 while (padlen > 0)
664 {
665 dopr_outch (buffer, currlen, maxlen, '0');
666 --padlen;
667 }
668 }
669 while (padlen > 0)
670 {
671 dopr_outch (buffer, currlen, maxlen, ' ');
672 --padlen;
673 }
674 if (signvalue)
675 dopr_outch (buffer, currlen, maxlen, signvalue);
676
677 while (iplace > 0)
678 dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
679
680 /*
681 * Decimal point. This should probably use locale to find the correct
682 * char to print out.
683 */
684 dopr_outch (buffer, currlen, maxlen, '.');
685
686 while (fplace > 0)
687 dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
688
689 while (zpadlen > 0)
690 {
691 dopr_outch (buffer, currlen, maxlen, '0');
692 --zpadlen;
693 }
694
695 while (padlen < 0)
696 {
697 dopr_outch (buffer, currlen, maxlen, ' ');
698 ++padlen;
699 }
700}
701
702static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
703{
704 if (*currlen < maxlen)
705 buffer[(*currlen)++] = c;
706}
707#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
708
709#ifndef HAVE_VSNPRINTF
710int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
711{
712 str[0] = 0;
713 dopr(str, count, fmt, args);
714 return(strlen(str));
715}
716#endif /* !HAVE_VSNPRINTF */
717
718#ifndef HAVE_SNPRINTF
719/* VARARGS3 */
720#ifdef HAVE_STDARGS
721int snprintf (char *str,size_t count,const char *fmt,...)
722#else
723int snprintf (va_alist) va_dcl
724#endif
725{
726#ifndef HAVE_STDARGS
727 char *str;
728 size_t count;
729 char *fmt;
730#endif
731 VA_LOCAL_DECL;
732
733 VA_START (fmt);
734 VA_SHIFT (str, char *);
735 VA_SHIFT (count, size_t );
736 VA_SHIFT (fmt, char *);
737 (void) vsnprintf(str, count, fmt, ap);
738 VA_END;
739 return(strlen(str));
740}
741
742#ifdef TEST_SNPRINTF
743#ifndef LONG_STRING
744#define LONG_STRING 1024
745#endif
746int main (void)
747{
748 char buf1[LONG_STRING];
749 char buf2[LONG_STRING];
750 char *fp_fmt[] = {
751 "%-1.5f",
752 "%1.5f",
753 "%123.9f",
754 "%10.5f",
755 "% 10.5f",
756 "%+22.9f",
757 "%+4.9f",
758 "%01.3f",
759 "%4f",
760 "%3.1f",
761 "%3.2f",
762 NULL
763 };
764 double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
765 0.9996, 1.996, 4.136, 0};
766 char *int_fmt[] = {
767 "%-1.5d",
768 "%1.5d",
769 "%123.9d",
770 "%5.5d",
771 "%10.5d",
772 "% 10.5d",
773 "%+22.33d",
774 "%01.3d",
775 "%4d",
776 "%lld",
777 "%qd",
778 NULL
779 };
780 long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 };
781 int x, y;
782 int fail = 0;
783 int num = 0;
784
785 printf ("Testing snprintf format codes against system sprintf...\n");
786
787 for (x = 0; fp_fmt[x] != NULL ; x++)
788 for (y = 0; fp_nums[y] != 0 ; y++)
789 {
790 snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
791 sprintf (buf2, fp_fmt[x], fp_nums[y]);
792 if (strcmp (buf1, buf2))
793 {
794 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
795 fp_fmt[x], buf1, buf2);
796 fail++;
797 }
798 num++;
799 }
800
801 for (x = 0; int_fmt[x] != NULL ; x++)
802 for (y = 0; int_nums[y] != 0 ; y++)
803 {
804 snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
805 sprintf (buf2, int_fmt[x], int_nums[y]);
806 if (strcmp (buf1, buf2))
807 {
808 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
809 int_fmt[x], buf1, buf2);
810 fail++;
811 }
812 num++;
813 }
814 printf ("%d tests failed out of %d.\n", fail, num);
815}
816#endif /* SNPRINTF_TEST */
817
818#endif /* !HAVE_SNPRINTF */
diff --git a/openbsd-compat/bsd-snprintf.h b/openbsd-compat/bsd-snprintf.h
new file mode 100644
index 000000000..ed7a21c97
--- /dev/null
+++ b/openbsd-compat/bsd-snprintf.h
@@ -0,0 +1,17 @@
1#ifndef _BSD_SNPRINTF_H
2#define _BSD_SNPRINTF_H
3
4#include "config.h"
5
6#include <sys/types.h> /* For size_t */
7
8#ifndef HAVE_SNPRINTF
9int snprintf(char *str, size_t count, const char *fmt, ...);
10#endif /* !HAVE_SNPRINTF */
11
12#ifndef HAVE_VSNPRINTF
13int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
14#endif /* !HAVE_SNPRINTF */
15
16
17#endif /* _BSD_SNPRINTF_H */
diff --git a/openbsd-compat/bsd-waitpid.c b/openbsd-compat/bsd-waitpid.c
new file mode 100644
index 000000000..0bf4c7cd8
--- /dev/null
+++ b/openbsd-compat/bsd-waitpid.c
@@ -0,0 +1,48 @@
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#ifndef HAVE_WAITPID
26#include <errno.h>
27#include <sys/wait.h>
28#include "bsd-waitpid.h"
29
30pid_t
31waitpid(int pid, int *stat_loc, int options)
32{
33 union wait statusp;
34 pid_t wait_pid;
35
36 if (pid <= 0) {
37 if (pid != -1) {
38 errno = EINVAL;
39 return -1;
40 }
41 pid = 0; /* wait4() wants pid=0 for indiscriminate wait. */
42 }
43 wait_pid = wait4(pid, &statusp, options, NULL);
44 stat_loc = (int *)statusp.w_status;
45 return wait_pid;
46}
47
48#endif /* !HAVE_WAITPID */
diff --git a/openbsd-compat/bsd-waitpid.h b/openbsd-compat/bsd-waitpid.h
new file mode 100644
index 000000000..25c6e9c86
--- /dev/null
+++ b/openbsd-compat/bsd-waitpid.h
@@ -0,0 +1,47 @@
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
24#ifndef _BSD_WAITPID_H
25#define _BSD_WAITPID_H
26
27#ifndef HAVE_WAITPID
28/* Clean out any potental issues */
29#undef WIFEXITED
30#undef WIFSTOPPED
31#undef WIFSIGNALED
32
33/* Define required functions to mimic a POSIX look and feel */
34#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */
35#define WIFEXITED(w) (!((_W_INT(w)) & 0377))
36#define WIFSTOPPED(w) ((_W_INT(w)) & 0100)
37#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w))
38#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1)
39#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1)
40#define WCOREFLAG 0x80
41#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG)
42
43/* Prototype */
44pid_t waitpid(int pid, int *stat_loc, int options);
45
46#endif /* !HAVE_WAITPID */
47#endif /* _BSD_WAITPID_H */
diff --git a/openbsd-compat/daemon.c b/openbsd-compat/daemon.c
new file mode 100644
index 000000000..f704a9048
--- /dev/null
+++ b/openbsd-compat/daemon.c
@@ -0,0 +1,81 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "includes.h"
35
36#ifndef HAVE_DAEMON
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char rcsid[] = "$OpenBSD: daemon.c,v 1.2 1996/08/19 08:22:13 tholo Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42int
43daemon(nochdir, noclose)
44 int nochdir, noclose;
45{
46 int fd;
47
48 switch (fork()) {
49 case -1:
50 return (-1);
51 case 0:
52 break;
53 default:
54#ifdef HAVE_CYGWIN
55 /*
56 * This sleep avoids a race condition which kills the
57 * child process if parent is started by a NT/W2K service.
58 */
59 sleep(1);
60#endif
61 _exit(0);
62 }
63
64 if (setsid() == -1)
65 return (-1);
66
67 if (!nochdir)
68 (void)chdir("/");
69
70 if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
71 (void)dup2(fd, STDIN_FILENO);
72 (void)dup2(fd, STDOUT_FILENO);
73 (void)dup2(fd, STDERR_FILENO);
74 if (fd > 2)
75 (void)close (fd);
76 }
77 return (0);
78}
79
80#endif /* !HAVE_DAEMON */
81
diff --git a/openbsd-compat/daemon.h b/openbsd-compat/daemon.h
new file mode 100644
index 000000000..cd91ea07b
--- /dev/null
+++ b/openbsd-compat/daemon.h
@@ -0,0 +1,9 @@
1#ifndef _BSD_DAEMON_H
2#define _BSD_DAEMON_H
3
4#include "config.h"
5#ifndef HAVE_DAEMON
6int daemon(int nochdir, int noclose);
7#endif /* !HAVE_DAEMON */
8
9#endif /* _BSD_DAEMON_H */
diff --git a/openbsd-compat/fake-gai-errnos.h b/openbsd-compat/fake-gai-errnos.h
new file mode 100644
index 000000000..27f6089e9
--- /dev/null
+++ b/openbsd-compat/fake-gai-errnos.h
@@ -0,0 +1,12 @@
1/*
2 * fake library for ssh
3 *
4 * This file is included in getaddrinfo.c and getnameinfo.c.
5 * See getaddrinfo.c and getnameinfo.c.
6 */
7
8/* for old netdb.h */
9#ifndef EAI_NODATA
10#define EAI_NODATA 1
11#define EAI_MEMORY 2
12#endif
diff --git a/openbsd-compat/fake-getaddrinfo.c b/openbsd-compat/fake-getaddrinfo.c
new file mode 100644
index 000000000..73c122ed1
--- /dev/null
+++ b/openbsd-compat/fake-getaddrinfo.c
@@ -0,0 +1,119 @@
1/*
2 * fake library for ssh
3 *
4 * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
5 * These funtions are defined in rfc2133.
6 *
7 * But these functions are not implemented correctly. The minimum subset
8 * is implemented for ssh use only. For exapmle, this routine assumes
9 * that ai_family is AF_INET. Don't use it for another purpose.
10 */
11
12#include "includes.h"
13#include "ssh.h"
14
15#ifndef HAVE_GAI_STRERROR
16char *gai_strerror(int ecode)
17{
18 switch (ecode) {
19 case EAI_NODATA:
20 return "no address associated with hostname.";
21 case EAI_MEMORY:
22 return "memory allocation failure.";
23 default:
24 return "unknown error.";
25 }
26}
27#endif /* !HAVE_GAI_STRERROR */
28
29#ifndef HAVE_FREEADDRINFO
30void freeaddrinfo(struct addrinfo *ai)
31{
32 struct addrinfo *next;
33
34 do {
35 next = ai->ai_next;
36 free(ai);
37 } while (NULL != (ai = next));
38}
39#endif /* !HAVE_FREEADDRINFO */
40
41#ifndef HAVE_GETADDRINFO
42static struct addrinfo *malloc_ai(int port, u_long addr)
43{
44 struct addrinfo *ai;
45
46 ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
47 if (ai == NULL)
48 return(NULL);
49
50 memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
51
52 ai->ai_addr = (struct sockaddr *)(ai + 1);
53 /* XXX -- ssh doesn't use sa_len */
54 ai->ai_addrlen = sizeof(struct sockaddr_in);
55 ai->ai_addr->sa_family = ai->ai_family = AF_INET;
56
57 ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
58 ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
59
60 return(ai);
61}
62
63int getaddrinfo(const char *hostname, const char *servname,
64 const struct addrinfo *hints, struct addrinfo **res)
65{
66 struct addrinfo *cur, *prev = NULL;
67 struct hostent *hp;
68 struct in_addr in;
69 int i, port;
70
71 if (servname)
72 port = htons(atoi(servname));
73 else
74 port = 0;
75
76 if (hints && hints->ai_flags & AI_PASSIVE) {
77 if (NULL != (*res = malloc_ai(port, htonl(0x00000000))))
78 return 0;
79 else
80 return EAI_MEMORY;
81 }
82
83 if (!hostname) {
84 if (NULL != (*res = malloc_ai(port, htonl(0x7f000001))))
85 return 0;
86 else
87 return EAI_MEMORY;
88 }
89
90 if (inet_aton(hostname, &in)) {
91 if (NULL != (*res = malloc_ai(port, in.s_addr)))
92 return 0;
93 else
94 return EAI_MEMORY;
95 }
96
97 hp = gethostbyname(hostname);
98 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
99 for (i = 0; hp->h_addr_list[i]; i++) {
100 cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
101 if (cur == NULL) {
102 if (*res)
103 freeaddrinfo(*res);
104 return EAI_MEMORY;
105 }
106
107 if (prev)
108 prev->ai_next = cur;
109 else
110 *res = cur;
111
112 prev = cur;
113 }
114 return 0;
115 }
116
117 return EAI_NODATA;
118}
119#endif /* !HAVE_GETADDRINFO */
diff --git a/openbsd-compat/fake-getaddrinfo.h b/openbsd-compat/fake-getaddrinfo.h
new file mode 100644
index 000000000..7da87142d
--- /dev/null
+++ b/openbsd-compat/fake-getaddrinfo.h
@@ -0,0 +1,45 @@
1#ifndef _FAKE_GETADDRINFO_H
2#define _FAKE_GETADDRINFO_H
3
4#include "config.h"
5
6#include "fake-gai-errnos.h"
7
8#ifndef AI_PASSIVE
9# define AI_PASSIVE 1
10# define AI_CANONNAME 2
11#endif
12
13#ifndef NI_NUMERICHOST
14# define NI_NUMERICHOST 2
15# define NI_NAMEREQD 4
16# define NI_NUMERICSERV 8
17#endif
18
19#ifndef HAVE_STRUCT_ADDRINFO
20struct addrinfo {
21 int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
22 int ai_family; /* PF_xxx */
23 int ai_socktype; /* SOCK_xxx */
24 int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
25 size_t ai_addrlen; /* length of ai_addr */
26 char *ai_canonname; /* canonical name for hostname */
27 struct sockaddr *ai_addr; /* binary address */
28 struct addrinfo *ai_next; /* next structure in linked list */
29};
30#endif /* !HAVE_STRUCT_ADDRINFO */
31
32#ifndef HAVE_GETADDRINFO
33int getaddrinfo(const char *hostname, const char *servname,
34 const struct addrinfo *hints, struct addrinfo **res);
35#endif /* !HAVE_GETADDRINFO */
36
37#ifndef HAVE_GAI_STRERROR
38char *gai_strerror(int ecode);
39#endif /* !HAVE_GAI_STRERROR */
40
41#ifndef HAVE_FREEADDRINFO
42void freeaddrinfo(struct addrinfo *ai);
43#endif /* !HAVE_FREEADDRINFO */
44
45#endif /* _FAKE_GETADDRINFO_H */
diff --git a/openbsd-compat/fake-getnameinfo.c b/openbsd-compat/fake-getnameinfo.c
new file mode 100644
index 000000000..203621f0d
--- /dev/null
+++ b/openbsd-compat/fake-getnameinfo.c
@@ -0,0 +1,53 @@
1/*
2 * fake library for ssh
3 *
4 * This file includes getnameinfo().
5 * These funtions are defined in rfc2133.
6 *
7 * But these functions are not implemented correctly. The minimum subset
8 * is implemented for ssh use only. For exapmle, this routine assumes
9 * that ai_family is AF_INET. Don't use it for another purpose.
10 */
11
12#include "includes.h"
13#include "ssh.h"
14
15#ifndef HAVE_GETNAMEINFO
16int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
17 size_t hostlen, char *serv, size_t servlen, int flags)
18{
19 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
20 struct hostent *hp;
21 char tmpserv[16];
22
23 if (serv) {
24 snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
25 if (strlen(tmpserv) >= servlen)
26 return EAI_MEMORY;
27 else
28 strcpy(serv, tmpserv);
29 }
30
31 if (host) {
32 if (flags & NI_NUMERICHOST) {
33 if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
34 return EAI_MEMORY;
35
36 strcpy(host, inet_ntoa(sin->sin_addr));
37 return 0;
38 } else {
39 hp = gethostbyaddr((char *)&sin->sin_addr,
40 sizeof(struct in_addr), AF_INET);
41 if (hp == NULL)
42 return EAI_NODATA;
43
44 if (strlen(hp->h_name) >= hostlen)
45 return EAI_MEMORY;
46
47 strcpy(host, hp->h_name);
48 return 0;
49 }
50 }
51 return 0;
52}
53#endif /* !HAVE_GETNAMEINFO */
diff --git a/openbsd-compat/fake-getnameinfo.h b/openbsd-compat/fake-getnameinfo.h
new file mode 100644
index 000000000..0d25f4270
--- /dev/null
+++ b/openbsd-compat/fake-getnameinfo.h
@@ -0,0 +1,18 @@
1#ifndef _FAKE_GETNAMEINFO_H
2#define _FAKE_GETNAMEINFO_H
3
4#include "config.h"
5
6#ifndef HAVE_GETNAMEINFO
7int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
8 size_t hostlen, char *serv, size_t servlen, int flags);
9#endif /* !HAVE_GETNAMEINFO */
10
11#ifndef NI_MAXSERV
12# define NI_MAXSERV 32
13#endif /* !NI_MAXSERV */
14#ifndef NI_MAXHOST
15# define NI_MAXHOST 1025
16#endif /* !NI_MAXHOST */
17
18#endif /* _FAKE_GETNAMEINFO_H */
diff --git a/openbsd-compat/fake-regex.h b/openbsd-compat/fake-regex.h
new file mode 100644
index 000000000..8f7f6eddd
--- /dev/null
+++ b/openbsd-compat/fake-regex.h
@@ -0,0 +1,106 @@
1/* $OpenBSD: regex.h,v 1.3 1997/09/21 10:45:48 niklas Exp $ */
2/* $NetBSD: regex.h,v 1.4.6.1 1996/06/10 18:57:07 explorer Exp $ */
3
4/*-
5 * Copyright (c) 1992 Henry Spencer.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Henry Spencer of the University of Toronto.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)regex.h 8.1 (Berkeley) 6/2/93
41 */
42
43#ifndef _REGEX_H_
44#define _REGEX_H_
45
46#include <sys/types.h>
47
48/* types */
49typedef off_t regoff_t;
50
51typedef struct {
52 int re_magic;
53 size_t re_nsub; /* number of parenthesized subexpressions */
54 const char *re_endp; /* end pointer for REG_PEND */
55 struct re_guts *re_g; /* none of your business :-) */
56} regex_t;
57
58typedef struct {
59 regoff_t rm_so; /* start of match */
60 regoff_t rm_eo; /* end of match */
61} regmatch_t;
62
63/* regcomp() flags */
64#define REG_BASIC 0000
65#define REG_EXTENDED 0001
66#define REG_ICASE 0002
67#define REG_NOSUB 0004
68#define REG_NEWLINE 0010
69#define REG_NOSPEC 0020
70#define REG_PEND 0040
71#define REG_DUMP 0200
72
73/* regerror() flags */
74#define REG_NOMATCH 1
75#define REG_BADPAT 2
76#define REG_ECOLLATE 3
77#define REG_ECTYPE 4
78#define REG_EESCAPE 5
79#define REG_ESUBREG 6
80#define REG_EBRACK 7
81#define REG_EPAREN 8
82#define REG_EBRACE 9
83#define REG_BADBR 10
84#define REG_ERANGE 11
85#define REG_ESPACE 12
86#define REG_BADRPT 13
87#define REG_EMPTY 14
88#define REG_ASSERT 15
89#define REG_INVARG 16
90#define REG_ATOI 255 /* convert name to number (!) */
91#define REG_ITOA 0400 /* convert number to name (!) */
92
93/* regexec() flags */
94#define REG_NOTBOL 00001
95#define REG_NOTEOL 00002
96#define REG_STARTEND 00004
97#define REG_TRACE 00400 /* tracing of execution */
98#define REG_LARGE 01000 /* force large representation */
99#define REG_BACKR 02000 /* force use of backref code */
100
101int regcomp(regex_t*, const char*, int);
102size_t regerror(int, const regex_t*, char*, size_t);
103int regexec(const regex_t*, const char*, size_t, regmatch_t[], int);
104void regfree(regex_t*);
105
106#endif /* !_REGEX_H_ */
diff --git a/openbsd-compat/fake-socket.h b/openbsd-compat/fake-socket.h
new file mode 100644
index 000000000..b51caa030
--- /dev/null
+++ b/openbsd-compat/fake-socket.h
@@ -0,0 +1,45 @@
1#ifndef _FAKE_SOCKET_H
2#define _FAKE_SOCKET_H
3
4#include "config.h"
5#include "sys/types.h"
6
7#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
8# define _SS_MAXSIZE 128 /* Implementation specific max size */
9# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr))
10
11struct sockaddr_storage {
12 struct sockaddr ss_sa;
13 char __ss_pad2[_SS_PADSIZE];
14};
15# define ss_family ss_sa.sa_family
16#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
17
18#ifndef IN6_IS_ADDR_LOOPBACK
19# define IN6_IS_ADDR_LOOPBACK(a) \
20 (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
21 ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
22#endif /* !IN6_IS_ADDR_LOOPBACK */
23
24#ifndef HAVE_STRUCT_IN6_ADDR
25struct in6_addr {
26 u_int8_t s6_addr[16];
27};
28#endif /* !HAVE_STRUCT_IN6_ADDR */
29
30#ifndef HAVE_STRUCT_SOCKADDR_IN6
31struct sockaddr_in6 {
32 unsigned short sin6_family;
33 u_int16_t sin6_port;
34 u_int32_t sin6_flowinfo;
35 struct in6_addr sin6_addr;
36};
37#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
38
39#ifndef AF_INET6
40/* Define it to something that should never appear */
41#define AF_INET6 AF_MAX
42#endif
43
44#endif /* !_FAKE_SOCKET_H */
45
diff --git a/openbsd-compat/getcwd.c b/openbsd-compat/getcwd.c
new file mode 100644
index 000000000..273a0487c
--- /dev/null
+++ b/openbsd-compat/getcwd.c
@@ -0,0 +1,237 @@
1/*
2 * Copyright (c) 1989, 1991, 1993
3 * The Regents of the University of California. 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#if !defined(HAVE_GETCWD)
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char rcsid[] = "$OpenBSD: getcwd.c,v 1.6 2000/07/19 15:25:13 deraadt Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <sys/param.h>
36#include <sys/stat.h>
37#include <errno.h>
38#include <dirent.h>
39#include <sys/dir.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include "includes.h"
44
45#define ISDOT(dp) \
46 (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
47 (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
48
49char *
50getcwd(char *pt,size_t size)
51{
52 register struct dirent *dp;
53 register DIR *dir = NULL;
54 register dev_t dev;
55 register ino_t ino;
56 register int first;
57 register char *bpt, *bup;
58 struct stat s;
59 dev_t root_dev;
60 ino_t root_ino;
61 size_t ptsize, upsize;
62 int save_errno;
63 char *ept, *eup, *up;
64
65 /*
66 * If no buffer specified by the user, allocate one as necessary.
67 * If a buffer is specified, the size has to be non-zero. The path
68 * is built from the end of the buffer backwards.
69 */
70 if (pt) {
71 ptsize = 0;
72 if (!size) {
73 errno = EINVAL;
74 return (NULL);
75 }
76 ept = pt + size;
77 } else {
78 if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
79 return (NULL);
80 ept = pt + ptsize;
81 }
82 bpt = ept - 1;
83 *bpt = '\0';
84
85 /*
86 * Allocate bytes (1024 - malloc space) for the string of "../"'s.
87 * Should always be enough (it's 340 levels). If it's not, allocate
88 * as necessary. Special * case the first stat, it's ".", not "..".
89 */
90 if ((up = malloc(upsize = 1024 - 4)) == NULL)
91 goto err;
92 eup = up + MAXPATHLEN;
93 bup = up;
94 up[0] = '.';
95 up[1] = '\0';
96
97 /* Save root values, so know when to stop. */
98 if (stat("/", &s))
99 goto err;
100 root_dev = s.st_dev;
101 root_ino = s.st_ino;
102
103 errno = 0; /* XXX readdir has no error return. */
104
105 for (first = 1;; first = 0) {
106 /* Stat the current level. */
107 if (lstat(up, &s))
108 goto err;
109
110 /* Save current node values. */
111 ino = s.st_ino;
112 dev = s.st_dev;
113
114 /* Check for reaching root. */
115 if (root_dev == dev && root_ino == ino) {
116 *--bpt = '/';
117 /*
118 * It's unclear that it's a requirement to copy the
119 * path to the beginning of the buffer, but it's always
120 * been that way and stuff would probably break.
121 */
122 memmove(bpt, pt, ept - bpt);
123 free(up);
124 return (pt);
125 }
126
127 /*
128 * Build pointer to the parent directory, allocating memory
129 * as necessary. Max length is 3 for "../", the largest
130 * possible component name, plus a trailing NULL.
131 */
132 if (bup + 3 + MAXNAMLEN + 1 >= eup) {
133 char *nup;
134
135 if ((nup = realloc(up, upsize *= 2)) == NULL)
136 goto err;
137 up = nup;
138 bup = up;
139 eup = up + upsize;
140 }
141 *bup++ = '.';
142 *bup++ = '.';
143 *bup = '\0';
144
145 /* Open and stat parent directory.
146 * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s)
147 */
148 if (!(dir = opendir(up)) || lstat(up,&s))
149 goto err;
150
151 /* Add trailing slash for next directory. */
152 *bup++ = '/';
153
154 /*
155 * If it's a mount point, have to stat each element because
156 * the inode number in the directory is for the entry in the
157 * parent directory, not the inode number of the mounted file.
158 */
159 save_errno = 0;
160 if (s.st_dev == dev) {
161 for (;;) {
162 if (!(dp = readdir(dir)))
163 goto notfound;
164 if (dp->d_fileno == ino)
165 break;
166 }
167 } else
168 for (;;) {
169 if (!(dp = readdir(dir)))
170 goto notfound;
171 if (ISDOT(dp))
172 continue;
173 memmove(dp->d_name, bup, dp->d_namlen + 1);
174
175 /* Save the first error for later. */
176 if (lstat(up, &s)) {
177 if (!save_errno)
178 save_errno = errno;
179 errno = 0;
180 continue;
181 }
182 if (s.st_dev == dev && s.st_ino == ino)
183 break;
184 }
185
186 /*
187 * Check for length of the current name, preceding slash,
188 * leading slash.
189 */
190 if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) {
191 size_t len, off;
192 char *npt;
193
194 if (!ptsize) {
195 errno = ERANGE;
196 goto err;
197 }
198 off = bpt - pt;
199 len = ept - bpt;
200 if ((npt = realloc(pt, ptsize *= 2)) == NULL)
201 goto err;
202 pt = npt;
203 bpt = pt + off;
204 ept = pt + ptsize;
205 memmove(bpt, ept - len, len);
206 bpt = ept - len;
207 }
208 if (!first)
209 *--bpt = '/';
210 bpt -= dp->d_namlen;
211 memmove(dp->d_name, bpt, dp->d_namlen);
212 (void)closedir(dir);
213
214 /* Truncate any file name. */
215 *bup = '\0';
216 }
217
218notfound:
219 /*
220 * If readdir set errno, use it, not any saved error; otherwise,
221 * didn't find the current directory in its parent directory, set
222 * errno to ENOENT.
223 */
224 if (!errno)
225 errno = save_errno ? save_errno : ENOENT;
226 /* FALLTHROUGH */
227err:
228 if (ptsize)
229 free(pt);
230 if (up)
231 free(up);
232 if (dir)
233 (void)closedir(dir);
234 return (NULL);
235}
236
237#endif /* !defined(HAVE_GETCWD) */
diff --git a/openbsd-compat/getcwd.h b/openbsd-compat/getcwd.h
new file mode 100644
index 000000000..bee738657
--- /dev/null
+++ b/openbsd-compat/getcwd.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_GETCWD_H
2#define _BSD_GETCWD_H
3#include "config.h"
4
5#if !defined(HAVE_GETCWD)
6
7char *getcwd(char *pt, size_t size);
8
9#endif /* !defined(HAVE_GETCWD) */
10#endif /* _BSD_GETCWD_H */
diff --git a/openbsd-compat/getgrouplist.c b/openbsd-compat/getgrouplist.c
new file mode 100644
index 000000000..f7a27c339
--- /dev/null
+++ b/openbsd-compat/getgrouplist.c
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "includes.h"
35
36#ifndef HAVE_GETGROUPLIST
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.7 1997/08/19 19:13:27 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42/*
43 * get credential
44 */
45#include <sys/types.h>
46#include <string.h>
47#include <grp.h>
48
49int
50getgrouplist(uname, agroup, groups, grpcnt)
51 const char *uname;
52 gid_t agroup;
53 register gid_t *groups;
54 int *grpcnt;
55{
56 register struct group *grp;
57 register int i, ngroups;
58 int ret, maxgroups;
59 int bail;
60
61 ret = 0;
62 ngroups = 0;
63 maxgroups = *grpcnt;
64
65 /*
66 * install primary group
67 */
68 if (ngroups >= maxgroups) {
69 *grpcnt = ngroups;
70 return (-1);
71 }
72 groups[ngroups++] = agroup;
73
74 /*
75 * Scan the group file to find additional groups.
76 */
77 setgrent();
78 while ((grp = getgrent())) {
79 if (grp->gr_gid == agroup)
80 continue;
81 for (bail = 0, i = 0; bail == 0 && i < ngroups; i++)
82 if (groups[i] == grp->gr_gid)
83 bail = 1;
84 if (bail)
85 continue;
86 for (i = 0; grp->gr_mem[i]; i++) {
87 if (!strcmp(grp->gr_mem[i], uname)) {
88 if (ngroups >= maxgroups) {
89 ret = -1;
90 goto out;
91 }
92 groups[ngroups++] = grp->gr_gid;
93 break;
94 }
95 }
96 }
97out:
98 endgrent();
99 *grpcnt = ngroups;
100 return (ret);
101}
102
103#endif /* HAVE_GETGROUPLIST */
diff --git a/openbsd-compat/getgrouplist.h b/openbsd-compat/getgrouplist.h
new file mode 100644
index 000000000..ef9e60116
--- /dev/null
+++ b/openbsd-compat/getgrouplist.h
@@ -0,0 +1,14 @@
1#ifndef _BSD_GETGROUPLIST_H
2#define _BSD_GETGROUPLIST_H
3
4#include "config.h"
5
6#ifndef HAVE_GETGROUPLIST
7
8#include <grp.h>
9
10int getgrouplist(const char *, gid_t, gid_t *, int *);
11
12#endif
13
14#endif
diff --git a/openbsd-compat/inet_aton.c b/openbsd-compat/inet_aton.c
new file mode 100644
index 000000000..18e31e7f6
--- /dev/null
+++ b/openbsd-compat/inet_aton.c
@@ -0,0 +1,193 @@
1/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */
2
3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
6 * Copyright (c) 1983, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#include "config.h"
59
60#if !defined(HAVE_INET_ATON)
61
62#if defined(LIBC_SCCS) && !defined(lint)
63#if 0
64static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
65static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
66#else
67static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $";
68#endif
69#endif /* LIBC_SCCS and not lint */
70
71#include <sys/types.h>
72#include <sys/param.h>
73#include <netinet/in.h>
74#include <arpa/inet.h>
75#include <ctype.h>
76
77#if 0
78/*
79 * Ascii internet address interpretation routine.
80 * The value returned is in network order.
81 */
82in_addr_t
83inet_addr(cp)
84 register const char *cp;
85{
86 struct in_addr val;
87
88 if (inet_aton(cp, &val))
89 return (val.s_addr);
90 return (INADDR_NONE);
91}
92#endif
93
94/*
95 * Check whether "cp" is a valid ascii representation
96 * of an Internet address and convert to a binary address.
97 * Returns 1 if the address is valid, 0 if not.
98 * This replaces inet_addr, the return value from which
99 * cannot distinguish between failure and a local broadcast address.
100 */
101int
102inet_aton(const char *cp, struct in_addr *addr)
103{
104 register u_int32_t val;
105 register int base, n;
106 register char c;
107 unsigned int parts[4];
108 register unsigned int *pp = parts;
109
110 c = *cp;
111 for (;;) {
112 /*
113 * Collect number up to ``.''.
114 * Values are specified as for C:
115 * 0x=hex, 0=octal, isdigit=decimal.
116 */
117 if (!isdigit(c))
118 return (0);
119 val = 0; base = 10;
120 if (c == '0') {
121 c = *++cp;
122 if (c == 'x' || c == 'X')
123 base = 16, c = *++cp;
124 else
125 base = 8;
126 }
127 for (;;) {
128 if (isascii(c) && isdigit(c)) {
129 val = (val * base) + (c - '0');
130 c = *++cp;
131 } else if (base == 16 && isascii(c) && isxdigit(c)) {
132 val = (val << 4) |
133 (c + 10 - (islower(c) ? 'a' : 'A'));
134 c = *++cp;
135 } else
136 break;
137 }
138 if (c == '.') {
139 /*
140 * Internet format:
141 * a.b.c.d
142 * a.b.c (with c treated as 16 bits)
143 * a.b (with b treated as 24 bits)
144 */
145 if (pp >= parts + 3)
146 return (0);
147 *pp++ = val;
148 c = *++cp;
149 } else
150 break;
151 }
152 /*
153 * Check for trailing characters.
154 */
155 if (c != '\0' && (!isascii(c) || !isspace(c)))
156 return (0);
157 /*
158 * Concoct the address according to
159 * the number of parts specified.
160 */
161 n = pp - parts + 1;
162 switch (n) {
163
164 case 0:
165 return (0); /* initial nondigit */
166
167 case 1: /* a -- 32 bits */
168 break;
169
170 case 2: /* a.b -- 8.24 bits */
171 if ((val > 0xffffff) || (parts[0] > 0xff))
172 return (0);
173 val |= parts[0] << 24;
174 break;
175
176 case 3: /* a.b.c -- 8.8.16 bits */
177 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
178 return (0);
179 val |= (parts[0] << 24) | (parts[1] << 16);
180 break;
181
182 case 4: /* a.b.c.d -- 8.8.8.8 bits */
183 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
184 return (0);
185 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
186 break;
187 }
188 if (addr)
189 addr->s_addr = htonl(val);
190 return (1);
191}
192
193#endif /* !defined(HAVE_INET_ATON) */
diff --git a/openbsd-compat/inet_aton.h b/openbsd-compat/inet_aton.h
new file mode 100644
index 000000000..ec3c225c9
--- /dev/null
+++ b/openbsd-compat/inet_aton.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_INET_ATON_H
2#define _BSD_INET_ATON_H
3
4#include "config.h"
5
6#ifndef HAVE_INET_ATON
7int inet_aton(const char *cp, struct in_addr *addr);
8#endif /* HAVE_INET_ATON */
9
10#endif /* _BSD_INET_ATON_H */
diff --git a/openbsd-compat/inet_ntoa.c b/openbsd-compat/inet_ntoa.c
new file mode 100644
index 000000000..fe5539be0
--- /dev/null
+++ b/openbsd-compat/inet_ntoa.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42/*
43 * Convert network-format internet address
44 * to base 256 d.d.d.d representation.
45 */
46#include <sys/types.h>
47#include <netinet/in.h>
48#include <arpa/inet.h>
49#include <stdio.h>
50#include "bsd-inet_ntoa.h"
51
52char *inet_ntoa(struct in_addr in)
53{
54 static char b[18];
55 register char *p;
56
57 p = (char *)&in;
58#define UC(b) (((int)b)&0xff)
59 (void)snprintf(b, sizeof(b),
60 "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
61 return (b);
62}
63
64#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */
diff --git a/openbsd-compat/inet_ntoa.h b/openbsd-compat/inet_ntoa.h
new file mode 100644
index 000000000..e3d48e4af
--- /dev/null
+++ b/openbsd-compat/inet_ntoa.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_INET_NTOA_H
2#define _BSD_INET_NTOA_H
3
4#include "config.h"
5
6#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
7char *inet_ntoa(struct in_addr in);
8#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */
9
10#endif /* _BSD_INET_NTOA_H */
diff --git a/openbsd-compat/mktemp.c b/openbsd-compat/mktemp.c
new file mode 100644
index 000000000..9ed1bc80f
--- /dev/null
+++ b/openbsd-compat/mktemp.c
@@ -0,0 +1,183 @@
1/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */
2/* Changes: Removed mktemp */
3
4/*
5 * Copyright (c) 1987, 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
37#include "includes.h"
38
39#ifndef HAVE_MKDTEMP
40
41#if defined(LIBC_SCCS) && !defined(lint)
42static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $";
43#endif /* LIBC_SCCS and not lint */
44
45#ifdef HAVE_CYGWIN
46#define open binary_open
47extern int binary_open();
48#endif
49
50static int _gettemp(char *, int *, int, int);
51
52int
53mkstemps(path, slen)
54 char *path;
55 int slen;
56{
57 int fd;
58
59 return (_gettemp(path, &fd, 0, slen) ? fd : -1);
60}
61
62int
63mkstemp(path)
64 char *path;
65{
66 int fd;
67
68 return (_gettemp(path, &fd, 0, 0) ? fd : -1);
69}
70
71char *
72mkdtemp(path)
73 char *path;
74{
75 return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL);
76}
77
78static int
79_gettemp(path, doopen, domkdir, slen)
80 char *path;
81 register int *doopen;
82 int domkdir;
83 int slen;
84{
85 register char *start, *trv, *suffp;
86 struct stat sbuf;
87 int pid, rval;
88
89 if (doopen && domkdir) {
90 errno = EINVAL;
91 return(0);
92 }
93
94 for (trv = path; *trv; ++trv)
95 ;
96 trv -= slen;
97 suffp = trv;
98 --trv;
99 if (trv < path) {
100 errno = EINVAL;
101 return (0);
102 }
103 pid = getpid();
104 while (*trv == 'X' && pid != 0) {
105 *trv-- = (pid % 10) + '0';
106 pid /= 10;
107 }
108 while (*trv == 'X') {
109 char c;
110
111 pid = (arc4random() & 0xffff) % (26+26);
112 if (pid < 26)
113 c = pid + 'A';
114 else
115 c = (pid - 26) + 'a';
116 *trv-- = c;
117 }
118 start = trv + 1;
119
120 /*
121 * check the target directory; if you have six X's and it
122 * doesn't exist this runs for a *very* long time.
123 */
124 if (doopen || domkdir) {
125 for (;; --trv) {
126 if (trv <= path)
127 break;
128 if (*trv == '/') {
129 *trv = '\0';
130 rval = stat(path, &sbuf);
131 *trv = '/';
132 if (rval != 0)
133 return(0);
134 if (!S_ISDIR(sbuf.st_mode)) {
135 errno = ENOTDIR;
136 return(0);
137 }
138 break;
139 }
140 }
141 }
142
143 for (;;) {
144 if (doopen) {
145 if ((*doopen =
146 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
147 return(1);
148 if (errno != EEXIST)
149 return(0);
150 } else if (domkdir) {
151 if (mkdir(path, 0700) == 0)
152 return(1);
153 if (errno != EEXIST)
154 return(0);
155 } else if (lstat(path, &sbuf))
156 return(errno == ENOENT ? 1 : 0);
157
158 /* tricky little algorithm for backward compatibility */
159 for (trv = start;;) {
160 if (!*trv)
161 return (0);
162 if (*trv == 'Z') {
163 if (trv == suffp)
164 return (0);
165 *trv++ = 'a';
166 } else {
167 if (isdigit(*trv))
168 *trv = 'a';
169 else if (*trv == 'z') /* inc from z to A */
170 *trv = 'A';
171 else {
172 if (trv == suffp)
173 return (0);
174 ++*trv;
175 }
176 break;
177 }
178 }
179 }
180 /*NOTREACHED*/
181}
182
183#endif /* !HAVE_MKDTEMP */
diff --git a/openbsd-compat/mktemp.h b/openbsd-compat/mktemp.h
new file mode 100644
index 000000000..faddc916e
--- /dev/null
+++ b/openbsd-compat/mktemp.h
@@ -0,0 +1,11 @@
1#ifndef _BSD_MKTEMP_H
2#define _BSD_MKTEMP_H
3
4#include "config.h"
5#ifndef HAVE_MKDTEMP
6int mkstemps(char *path, int slen);
7int mkstemp(char *path);
8char *mkdtemp(char *path);
9#endif /* !HAVE_MKDTEMP */
10
11#endif /* _BSD_MKTEMP_H */
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
new file mode 100644
index 000000000..4758a9c59
--- /dev/null
+++ b/openbsd-compat/openbsd-compat.h
@@ -0,0 +1,37 @@
1#ifndef _OPENBSD_H
2#define _OPENBSD_H
3
4#include "config.h"
5
6/* OpenBSD function replacements */
7#include "bindresvport.h"
8#include "getcwd.h"
9#include "realpath.h"
10#include "rresvport.h"
11#include "strlcpy.h"
12#include "strlcat.h"
13#include "strmode.h"
14#include "mktemp.h"
15#include "daemon.h"
16#include "base64.h"
17#include "sigaction.h"
18#include "inet_aton.h"
19#include "inet_ntoa.h"
20#include "strsep.h"
21#include "strtok.h"
22#include "vis.h"
23#include "setproctitle.h"
24#include "getgrouplist.h"
25
26/* Home grown routines */
27#include "bsd-arc4random.h"
28#include "bsd-misc.h"
29#include "bsd-snprintf.h"
30#include "bsd-waitpid.h"
31
32/* rfc2553 socket API replacements */
33#include "fake-getaddrinfo.h"
34#include "fake-getnameinfo.h"
35#include "fake-socket.h"
36
37#endif /* _OPENBSD_H */
diff --git a/openbsd-compat/queue.h b/openbsd-compat/queue.h
new file mode 100644
index 000000000..269af413c
--- /dev/null
+++ b/openbsd-compat/queue.h
@@ -0,0 +1,490 @@
1/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art 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 _SYS_QUEUE_H_
40#define _SYS_QUEUE_H_
41
42/*
43 * This file defines five types of data structures: singly-linked lists,
44 * lists, simple queues, tail queues, and circular queues.
45 *
46 *
47 * A singly-linked list is headed by a single forward pointer. The elements
48 * are singly linked for minimum space and pointer manipulation overhead at
49 * the expense of O(n) removal for arbitrary elements. New elements can be
50 * added to the list after an existing element or at the head of the list.
51 * Elements being removed from the head of the list should use the explicit
52 * macro for this purpose for optimum efficiency. A singly-linked list may
53 * only be traversed in the forward direction. Singly-linked lists are ideal
54 * for applications with large datasets and few or no removals or for
55 * implementing a LIFO queue.
56 *
57 * A list is headed by a single forward pointer (or an array of forward
58 * pointers for a hash table header). The elements are doubly linked
59 * so that an arbitrary element can be removed without a need to
60 * traverse the list. New elements can be added to the list before
61 * or after an existing element or at the head of the list. A list
62 * may only be traversed in the forward direction.
63 *
64 * A simple queue is headed by a pair of pointers, one the head of the
65 * list and the other to the tail of the list. The elements are singly
66 * linked to save space, so elements can only be removed from the
67 * head of the list. New elements can be added to the list before or after
68 * an existing element, at the head of the list, or at the end of the
69 * list. A simple queue may only be traversed in the forward direction.
70 *
71 * A tail queue is headed by a pair of pointers, one to the head of the
72 * list and the other to the tail of the list. The elements are doubly
73 * linked so that an arbitrary element can be removed without a need to
74 * traverse the list. New elements can be added to the list before or
75 * after an existing element, at the head of the list, or at the end of
76 * the list. A tail queue may be traversed in either direction.
77 *
78 * A circle queue is headed by a pair of pointers, one to the head of the
79 * list and the other to the tail of the list. The elements are doubly
80 * linked so that an arbitrary element can be removed without a need to
81 * traverse the list. New elements can be added to the list before or after
82 * an existing element, at the head of the list, or at the end of the list.
83 * A circle queue may be traversed in either direction, but has a more
84 * complex end of list detection.
85 *
86 * For details on the use of these macros, see the queue(3) manual page.
87 */
88
89/*
90 * Singly-linked List definitions.
91 */
92#define SLIST_HEAD(name, type) \
93struct name { \
94 struct type *slh_first; /* first element */ \
95}
96
97#define SLIST_HEAD_INITIALIZER(head) \
98 { NULL }
99
100#define SLIST_ENTRY(type) \
101struct { \
102 struct type *sle_next; /* next element */ \
103}
104
105/*
106 * Singly-linked List access methods.
107 */
108#define SLIST_FIRST(head) ((head)->slh_first)
109#define SLIST_END(head) NULL
110#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
111#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
112
113#define SLIST_FOREACH(var, head, field) \
114 for((var) = SLIST_FIRST(head); \
115 (var) != SLIST_END(head); \
116 (var) = SLIST_NEXT(var, field))
117
118/*
119 * Singly-linked List functions.
120 */
121#define SLIST_INIT(head) { \
122 SLIST_FIRST(head) = SLIST_END(head); \
123}
124
125#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
126 (elm)->field.sle_next = (slistelm)->field.sle_next; \
127 (slistelm)->field.sle_next = (elm); \
128} while (0)
129
130#define SLIST_INSERT_HEAD(head, elm, field) do { \
131 (elm)->field.sle_next = (head)->slh_first; \
132 (head)->slh_first = (elm); \
133} while (0)
134
135#define SLIST_REMOVE_HEAD(head, field) do { \
136 (head)->slh_first = (head)->slh_first->field.sle_next; \
137} while (0)
138
139/*
140 * List definitions.
141 */
142#define LIST_HEAD(name, type) \
143struct name { \
144 struct type *lh_first; /* first element */ \
145}
146
147#define LIST_HEAD_INITIALIZER(head) \
148 { NULL }
149
150#define LIST_ENTRY(type) \
151struct { \
152 struct type *le_next; /* next element */ \
153 struct type **le_prev; /* address of previous next element */ \
154}
155
156/*
157 * List access methods
158 */
159#define LIST_FIRST(head) ((head)->lh_first)
160#define LIST_END(head) NULL
161#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
162#define LIST_NEXT(elm, field) ((elm)->field.le_next)
163
164#define LIST_FOREACH(var, head, field) \
165 for((var) = LIST_FIRST(head); \
166 (var)!= LIST_END(head); \
167 (var) = LIST_NEXT(var, field))
168
169/*
170 * List functions.
171 */
172#define LIST_INIT(head) do { \
173 LIST_FIRST(head) = LIST_END(head); \
174} while (0)
175
176#define LIST_INSERT_AFTER(listelm, elm, field) do { \
177 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
178 (listelm)->field.le_next->field.le_prev = \
179 &(elm)->field.le_next; \
180 (listelm)->field.le_next = (elm); \
181 (elm)->field.le_prev = &(listelm)->field.le_next; \
182} while (0)
183
184#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
185 (elm)->field.le_prev = (listelm)->field.le_prev; \
186 (elm)->field.le_next = (listelm); \
187 *(listelm)->field.le_prev = (elm); \
188 (listelm)->field.le_prev = &(elm)->field.le_next; \
189} while (0)
190
191#define LIST_INSERT_HEAD(head, elm, field) do { \
192 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
193 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
194 (head)->lh_first = (elm); \
195 (elm)->field.le_prev = &(head)->lh_first; \
196} while (0)
197
198#define LIST_REMOVE(elm, field) do { \
199 if ((elm)->field.le_next != NULL) \
200 (elm)->field.le_next->field.le_prev = \
201 (elm)->field.le_prev; \
202 *(elm)->field.le_prev = (elm)->field.le_next; \
203} while (0)
204
205#define LIST_REPLACE(elm, elm2, field) do { \
206 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
207 (elm2)->field.le_next->field.le_prev = \
208 &(elm2)->field.le_next; \
209 (elm2)->field.le_prev = (elm)->field.le_prev; \
210 *(elm2)->field.le_prev = (elm2); \
211} while (0)
212
213/*
214 * Simple queue definitions.
215 */
216#define SIMPLEQ_HEAD(name, type) \
217struct name { \
218 struct type *sqh_first; /* first element */ \
219 struct type **sqh_last; /* addr of last next element */ \
220}
221
222#define SIMPLEQ_HEAD_INITIALIZER(head) \
223 { NULL, &(head).sqh_first }
224
225#define SIMPLEQ_ENTRY(type) \
226struct { \
227 struct type *sqe_next; /* next element */ \
228}
229
230/*
231 * Simple queue access methods.
232 */
233#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
234#define SIMPLEQ_END(head) NULL
235#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
236#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
237
238#define SIMPLEQ_FOREACH(var, head, field) \
239 for((var) = SIMPLEQ_FIRST(head); \
240 (var) != SIMPLEQ_END(head); \
241 (var) = SIMPLEQ_NEXT(var, field))
242
243/*
244 * Simple queue functions.
245 */
246#define SIMPLEQ_INIT(head) do { \
247 (head)->sqh_first = NULL; \
248 (head)->sqh_last = &(head)->sqh_first; \
249} while (0)
250
251#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
252 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
253 (head)->sqh_last = &(elm)->field.sqe_next; \
254 (head)->sqh_first = (elm); \
255} while (0)
256
257#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
258 (elm)->field.sqe_next = NULL; \
259 *(head)->sqh_last = (elm); \
260 (head)->sqh_last = &(elm)->field.sqe_next; \
261} while (0)
262
263#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
264 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
265 (head)->sqh_last = &(elm)->field.sqe_next; \
266 (listelm)->field.sqe_next = (elm); \
267} while (0)
268
269#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
270 if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
271 (head)->sqh_last = &(head)->sqh_first; \
272} while (0)
273
274/*
275 * Tail queue definitions.
276 */
277#define TAILQ_HEAD(name, type) \
278struct name { \
279 struct type *tqh_first; /* first element */ \
280 struct type **tqh_last; /* addr of last next element */ \
281}
282
283#define TAILQ_HEAD_INITIALIZER(head) \
284 { NULL, &(head).tqh_first }
285
286#define TAILQ_ENTRY(type) \
287struct { \
288 struct type *tqe_next; /* next element */ \
289 struct type **tqe_prev; /* address of previous next element */ \
290}
291
292/*
293 * tail queue access methods
294 */
295#define TAILQ_FIRST(head) ((head)->tqh_first)
296#define TAILQ_END(head) NULL
297#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
298#define TAILQ_LAST(head, headname) \
299 (*(((struct headname *)((head)->tqh_last))->tqh_last))
300/* XXX */
301#define TAILQ_PREV(elm, headname, field) \
302 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
303#define TAILQ_EMPTY(head) \
304 (TAILQ_FIRST(head) == TAILQ_END(head))
305
306#define TAILQ_FOREACH(var, head, field) \
307 for((var) = TAILQ_FIRST(head); \
308 (var) != TAILQ_END(head); \
309 (var) = TAILQ_NEXT(var, field))
310
311#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
312 for((var) = TAILQ_LAST(head, headname); \
313 (var) != TAILQ_END(head); \
314 (var) = TAILQ_PREV(var, headname, field))
315
316/*
317 * Tail queue functions.
318 */
319#define TAILQ_INIT(head) do { \
320 (head)->tqh_first = NULL; \
321 (head)->tqh_last = &(head)->tqh_first; \
322} while (0)
323
324#define TAILQ_INSERT_HEAD(head, elm, field) do { \
325 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
326 (head)->tqh_first->field.tqe_prev = \
327 &(elm)->field.tqe_next; \
328 else \
329 (head)->tqh_last = &(elm)->field.tqe_next; \
330 (head)->tqh_first = (elm); \
331 (elm)->field.tqe_prev = &(head)->tqh_first; \
332} while (0)
333
334#define TAILQ_INSERT_TAIL(head, elm, field) do { \
335 (elm)->field.tqe_next = NULL; \
336 (elm)->field.tqe_prev = (head)->tqh_last; \
337 *(head)->tqh_last = (elm); \
338 (head)->tqh_last = &(elm)->field.tqe_next; \
339} while (0)
340
341#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
342 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
343 (elm)->field.tqe_next->field.tqe_prev = \
344 &(elm)->field.tqe_next; \
345 else \
346 (head)->tqh_last = &(elm)->field.tqe_next; \
347 (listelm)->field.tqe_next = (elm); \
348 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
349} while (0)
350
351#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
352 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
353 (elm)->field.tqe_next = (listelm); \
354 *(listelm)->field.tqe_prev = (elm); \
355 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
356} while (0)
357
358#define TAILQ_REMOVE(head, elm, field) do { \
359 if (((elm)->field.tqe_next) != NULL) \
360 (elm)->field.tqe_next->field.tqe_prev = \
361 (elm)->field.tqe_prev; \
362 else \
363 (head)->tqh_last = (elm)->field.tqe_prev; \
364 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
365} while (0)
366
367#define TAILQ_REPLACE(head, elm, elm2, field) do { \
368 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
369 (elm2)->field.tqe_next->field.tqe_prev = \
370 &(elm2)->field.tqe_next; \
371 else \
372 (head)->tqh_last = &(elm2)->field.tqe_next; \
373 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
374 *(elm2)->field.tqe_prev = (elm2); \
375} while (0)
376
377/*
378 * Circular queue definitions.
379 */
380#define CIRCLEQ_HEAD(name, type) \
381struct name { \
382 struct type *cqh_first; /* first element */ \
383 struct type *cqh_last; /* last element */ \
384}
385
386#define CIRCLEQ_HEAD_INITIALIZER(head) \
387 { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
388
389#define CIRCLEQ_ENTRY(type) \
390struct { \
391 struct type *cqe_next; /* next element */ \
392 struct type *cqe_prev; /* previous element */ \
393}
394
395/*
396 * Circular queue access methods
397 */
398#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
399#define CIRCLEQ_LAST(head) ((head)->cqh_last)
400#define CIRCLEQ_END(head) ((void *)(head))
401#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
402#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
403#define CIRCLEQ_EMPTY(head) \
404 (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
405
406#define CIRCLEQ_FOREACH(var, head, field) \
407 for((var) = CIRCLEQ_FIRST(head); \
408 (var) != CIRCLEQ_END(head); \
409 (var) = CIRCLEQ_NEXT(var, field))
410
411#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
412 for((var) = CIRCLEQ_LAST(head); \
413 (var) != CIRCLEQ_END(head); \
414 (var) = CIRCLEQ_PREV(var, field))
415
416/*
417 * Circular queue functions.
418 */
419#define CIRCLEQ_INIT(head) do { \
420 (head)->cqh_first = CIRCLEQ_END(head); \
421 (head)->cqh_last = CIRCLEQ_END(head); \
422} while (0)
423
424#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
425 (elm)->field.cqe_next = (listelm)->field.cqe_next; \
426 (elm)->field.cqe_prev = (listelm); \
427 if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
428 (head)->cqh_last = (elm); \
429 else \
430 (listelm)->field.cqe_next->field.cqe_prev = (elm); \
431 (listelm)->field.cqe_next = (elm); \
432} while (0)
433
434#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
435 (elm)->field.cqe_next = (listelm); \
436 (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
437 if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
438 (head)->cqh_first = (elm); \
439 else \
440 (listelm)->field.cqe_prev->field.cqe_next = (elm); \
441 (listelm)->field.cqe_prev = (elm); \
442} while (0)
443
444#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
445 (elm)->field.cqe_next = (head)->cqh_first; \
446 (elm)->field.cqe_prev = CIRCLEQ_END(head); \
447 if ((head)->cqh_last == CIRCLEQ_END(head)) \
448 (head)->cqh_last = (elm); \
449 else \
450 (head)->cqh_first->field.cqe_prev = (elm); \
451 (head)->cqh_first = (elm); \
452} while (0)
453
454#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
455 (elm)->field.cqe_next = CIRCLEQ_END(head); \
456 (elm)->field.cqe_prev = (head)->cqh_last; \
457 if ((head)->cqh_first == CIRCLEQ_END(head)) \
458 (head)->cqh_first = (elm); \
459 else \
460 (head)->cqh_last->field.cqe_next = (elm); \
461 (head)->cqh_last = (elm); \
462} while (0)
463
464#define CIRCLEQ_REMOVE(head, elm, field) do { \
465 if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
466 (head)->cqh_last = (elm)->field.cqe_prev; \
467 else \
468 (elm)->field.cqe_next->field.cqe_prev = \
469 (elm)->field.cqe_prev; \
470 if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
471 (head)->cqh_first = (elm)->field.cqe_next; \
472 else \
473 (elm)->field.cqe_prev->field.cqe_next = \
474 (elm)->field.cqe_next; \
475} while (0)
476
477#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
478 if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
479 CIRCLEQ_END(head)) \
480 (head).cqh_last = (elm2); \
481 else \
482 (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
483 if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
484 CIRCLEQ_END(head)) \
485 (head).cqh_first = (elm2); \
486 else \
487 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
488} while (0)
489
490#endif /* !_SYS_QUEUE_H_ */
diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c
new file mode 100644
index 000000000..baf17f1a4
--- /dev/null
+++ b/openbsd-compat/realpath.c
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
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 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "includes.h"
31
32#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: realpath..c,v 1.4 1998/05/18 09:55:19 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <sys/stat.h>
40
41#include <errno.h>
42#include <fcntl.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47/*
48 * S_ISLNK compatibility
49 */
50#ifndef S_ISLNK
51#define S_ISLNK(m) ((m & 0170000) == 0120000)
52#endif
53
54/*
55 * MAXSYMLINKS
56 */
57#ifndef MAXSYMLINKS
58#define MAXSYMLINKS 5
59#endif
60
61/*
62 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
63 *
64 * Find the real name of path, by removing all ".", ".." and symlink
65 * components. Returns (resolved) on success, or (NULL) on failure,
66 * in which case the path which caused trouble is left in (resolved).
67 */
68char *
69realpath(const char *path, char *resolved)
70{
71 struct stat sb;
72 int fd, n, rootd, serrno = 0;
73 char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN];
74 int symlinks = 0;
75
76 /* Save the starting point. */
77 getcwd(start,MAXPATHLEN);
78 if ((fd = open(".", O_RDONLY)) < 0) {
79 (void)strcpy(resolved, ".");
80 return (NULL);
81 }
82 close(fd);
83
84 /*
85 * Find the dirname and basename from the path to be resolved.
86 * Change directory to the dirname component.
87 * lstat the basename part.
88 * if it is a symlink, read in the value and loop.
89 * if it is a directory, then change to that directory.
90 * get the current directory name and append the basename.
91 */
92 (void)strncpy(resolved, path, MAXPATHLEN - 1);
93 resolved[MAXPATHLEN - 1] = '\0';
94loop:
95 q = strrchr(resolved, '/');
96 if (q != NULL) {
97 p = q + 1;
98 if (q == resolved)
99 q = "/";
100 else {
101 do {
102 --q;
103 } while (q > resolved && *q == '/');
104 q[1] = '\0';
105 q = resolved;
106 }
107 if (chdir(q) < 0)
108 goto err1;
109 } else
110 p = resolved;
111
112 /* Deal with the last component. */
113 if (lstat(p, &sb) == 0) {
114 if (S_ISLNK(sb.st_mode)) {
115 if (++symlinks > MAXSYMLINKS) {
116 serrno = ELOOP;
117 goto err1;
118 }
119 n = readlink(p, resolved, MAXPATHLEN-1);
120 if (n < 0)
121 goto err1;
122 resolved[n] = '\0';
123 goto loop;
124 }
125 if (S_ISDIR(sb.st_mode)) {
126 if (chdir(p) < 0)
127 goto err1;
128 p = "";
129 }
130 }
131
132 /*
133 * Save the last component name and get the full pathname of
134 * the current directory.
135 */
136 (void)strcpy(wbuf, p);
137 if (getcwd(resolved, MAXPATHLEN) == 0)
138 goto err1;
139
140 /*
141 * Join the two strings together, ensuring that the right thing
142 * happens if the last component is empty, or the dirname is root.
143 */
144 if (resolved[0] == '/' && resolved[1] == '\0')
145 rootd = 1;
146 else
147 rootd = 0;
148
149 if (*wbuf) {
150 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
151 serrno = ENAMETOOLONG;
152 goto err1;
153 }
154 if (rootd == 0)
155 (void)strcat(resolved, "/");
156 (void)strcat(resolved, wbuf);
157 }
158
159 /* Go back to where we came from. */
160 if (chdir(start) < 0) {
161 serrno = errno;
162 goto err2;
163 }
164 return (resolved);
165
166err1: chdir(start);
167err2: errno = serrno;
168 return (NULL);
169}
170#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
diff --git a/openbsd-compat/realpath.h b/openbsd-compat/realpath.h
new file mode 100644
index 000000000..dc3579dd3
--- /dev/null
+++ b/openbsd-compat/realpath.h
@@ -0,0 +1,11 @@
1#ifndef _BSD_REALPATH_H
2#define _BSD_REALPATH_H
3
4#include "config.h"
5
6#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
7
8char *realpath(const char *path, char *resolved);
9
10#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
11#endif /* _BSD_REALPATH_H */
diff --git a/openbsd-compat/rresvport.c b/openbsd-compat/rresvport.c
new file mode 100644
index 000000000..44eac2036
--- /dev/null
+++ b/openbsd-compat/rresvport.c
@@ -0,0 +1,106 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. 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 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * This product includes software developed by Theo de Raadt.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "config.h"
37
38#ifndef HAVE_RRESVPORT_AF
39
40#if defined(LIBC_SCCS) && !defined(lint)
41static char *rcsid = "$OpenBSD: rresvport.c,v 1.5 2000/01/26 03:43:20 deraadt Exp $";
42#endif /* LIBC_SCCS and not lint */
43
44#include "includes.h"
45
46#if 0
47int
48rresvport(alport)
49 int *alport;
50{
51 return rresvport_af(alport, AF_INET);
52}
53#endif
54
55int
56rresvport_af(int *alport, sa_family_t af)
57{
58 struct sockaddr_storage ss;
59 struct sockaddr *sa;
60 u_int16_t *portp;
61 int s;
62 socklen_t salen;
63
64 memset(&ss, '\0', sizeof ss);
65 sa = (struct sockaddr *)&ss;
66
67 switch (af) {
68 case AF_INET:
69 salen = sizeof(struct sockaddr_in);
70 portp = &((struct sockaddr_in *)sa)->sin_port;
71 break;
72 case AF_INET6:
73 salen = sizeof(struct sockaddr_in6);
74 portp = &((struct sockaddr_in6 *)sa)->sin6_port;
75 break;
76 default:
77 errno = EPFNOSUPPORT;
78 return (-1);
79 }
80 sa->sa_family = af;
81
82 s = socket(af, SOCK_STREAM, 0);
83 if (s < 0)
84 return (-1);
85
86 *portp = htons(*alport);
87 if (*alport < IPPORT_RESERVED - 1) {
88 if (bind(s, sa, salen) >= 0)
89 return (s);
90 if (errno != EADDRINUSE) {
91 (void)close(s);
92 return (-1);
93 }
94 }
95
96 *portp = 0;
97 sa->sa_family = af;
98 if (bindresvport_sa(s, sa) == -1) {
99 (void)close(s);
100 return (-1);
101 }
102 *alport = ntohs(*portp);
103 return (s);
104}
105
106#endif /* HAVE_RRESVPORT_AF */
diff --git a/openbsd-compat/rresvport.h b/openbsd-compat/rresvport.h
new file mode 100644
index 000000000..d139895e8
--- /dev/null
+++ b/openbsd-compat/rresvport.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_RRESVPORT_H
2#define _BSD_RRESVPORT_H
3
4#include "config.h"
5
6#ifndef HAVE_RRESVPORT_AF
7int rresvport_af(int *alport, sa_family_t af);
8#endif /* !HAVE_RRESVPORT_AF */
9
10#endif /* _BSD_RRESVPORT_H */
diff --git a/openbsd-compat/setenv.c b/openbsd-compat/setenv.c
new file mode 100644
index 000000000..d69f88258
--- /dev/null
+++ b/openbsd-compat/setenv.c
@@ -0,0 +1,161 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35#ifndef HAVE_SETENV
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h>
42#include <string.h>
43
44/*
45 * __findenv --
46 * Returns pointer to value associated with name, if any, else NULL.
47 * Sets offset to be the offset of the name/value combination in the
48 * environmental array, for use by setenv(3) and unsetenv(3).
49 * Explicitly removes '=' in argument name.
50 *
51 * This routine *should* be a static; don't use it.
52 */
53char *
54__findenv(name, offset)
55 register const char *name;
56 int *offset;
57{
58 extern char **environ;
59 register int len, i;
60 register const char *np;
61 register char **p, *cp;
62
63 if (name == NULL || environ == NULL)
64 return (NULL);
65 for (np = name; *np && *np != '='; ++np)
66 ;
67 len = np - name;
68 for (p = environ; (cp = *p) != NULL; ++p) {
69 for (np = name, i = len; i && *cp; i--)
70 if (*cp++ != *np++)
71 break;
72 if (i == 0 && *cp++ == '=') {
73 *offset = p - environ;
74 return (cp);
75 }
76 }
77 return (NULL);
78}
79
80/*
81 * setenv --
82 * Set the value of the environmental variable "name" to be
83 * "value". If rewrite is set, replace any current value.
84 */
85int
86setenv(name, value, rewrite)
87 register const char *name;
88 register const char *value;
89 int rewrite;
90{
91 extern char **environ;
92 static int alloced; /* if allocated space before */
93 register char *C;
94 int l_value, offset;
95 char *__findenv();
96
97 if (*value == '=') /* no `=' in value */
98 ++value;
99 l_value = strlen(value);
100 if ((C = __findenv(name, &offset))) { /* find if already exists */
101 if (!rewrite)
102 return (0);
103 if (strlen(C) >= l_value) { /* old larger; copy over */
104 while ((*C++ = *value++));
105 return (0);
106 }
107 } else { /* create new slot */
108 register int cnt;
109 register char **P;
110
111 for (P = environ, cnt = 0; *P; ++P, ++cnt);
112 if (alloced) { /* just increase size */
113 P = (char **)realloc((void *)environ,
114 (size_t)(sizeof(char *) * (cnt + 2)));
115 if (!P)
116 return (-1);
117 environ = P;
118 }
119 else { /* get new space */
120 alloced = 1; /* copy old entries into it */
121 P = (char **)malloc((size_t)(sizeof(char *) *
122 (cnt + 2)));
123 if (!P)
124 return (-1);
125 memmove(environ, P, cnt * sizeof(char *));
126 environ = P;
127 }
128 environ[cnt + 1] = NULL;
129 offset = cnt;
130 }
131 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
132 if (!(environ[offset] = /* name + `=' + value */
133 malloc((size_t)((int)(C - name) + l_value + 2))))
134 return (-1);
135 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
136 ;
137 for (*C++ = '='; (*C++ = *value++); )
138 ;
139 return (0);
140}
141
142/*
143 * unsetenv(name) --
144 * Delete environmental variable "name".
145 */
146void
147unsetenv(name)
148 const char *name;
149{
150 extern char **environ;
151 register char **P;
152 int offset;
153 char *__findenv();
154
155 while (__findenv(name, &offset)) /* if set multiple times */
156 for (P = &environ[offset];; ++P)
157 if (!(*P = *(P + 1)))
158 break;
159}
160
161#endif /* HAVE_SETENV */
diff --git a/openbsd-compat/setenv.h b/openbsd-compat/setenv.h
new file mode 100644
index 000000000..62ebc201f
--- /dev/null
+++ b/openbsd-compat/setenv.h
@@ -0,0 +1,12 @@
1#ifndef _BSD_SETENV_H
2#define _BSD_SETENV_H
3
4#include "config.h"
5
6#ifndef HAVE_SETENV
7
8int setenv(register const char *name, register const char *value, int rewrite);
9
10#endif /* !HAVE_SETENV */
11
12#endif /* _BSD_SETENV_H */
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c
new file mode 100644
index 000000000..38eca9ad7
--- /dev/null
+++ b/openbsd-compat/setproctitle.c
@@ -0,0 +1,102 @@
1/*
2 * Modified for OpenSSH by Kevin Steves
3 * October 2000
4 */
5
6/*
7 * Copyright (c) 1994, 1995 Christopher G. Demetriou
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Christopher G. Demetriou
21 * for the NetBSD Project.
22 * 4. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.7 1999/02/25 22:10:12 art Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include "includes.h"
42
43#ifndef HAVE_SETPROCTITLE
44
45#define SPT_NONE 0
46#define SPT_PSTAT 1
47
48#ifndef SPT_TYPE
49#define SPT_TYPE SPT_NONE
50#endif
51
52#if SPT_TYPE == SPT_PSTAT
53#include <sys/param.h>
54#include <sys/pstat.h>
55#endif /* SPT_TYPE == SPT_PSTAT */
56
57#define MAX_PROCTITLE 2048
58
59extern char *__progname;
60
61/*
62 * Set Process Title (SPT) defines. Modeled after sendmail's
63 * SPT type definition strategy.
64 *
65 * SPT_TYPE:
66 *
67 * SPT_NONE: Don't set the process title. Default.
68 * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific.
69 */
70
71void
72setproctitle(const char *fmt, ...)
73{
74#if SPT_TYPE != SPT_NONE
75 va_list ap;
76
77 char buf[MAX_PROCTITLE];
78 size_t used;
79
80#if SPT_TYPE == SPT_PSTAT
81 union pstun pst;
82#endif /* SPT_TYPE == SPT_PSTAT */
83
84 va_start(ap, fmt);
85 if (fmt != NULL) {
86 used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname);
87 if (used >= MAX_PROCTITLE)
88 used = MAX_PROCTITLE - 1;
89 (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap);
90 } else
91 (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname);
92 va_end(ap);
93 used = strlen(buf);
94
95#if SPT_TYPE == SPT_PSTAT
96 pst.pst_command = buf;
97 pstat(PSTAT_SETCMD, pst, used, 0, 0);
98#endif /* SPT_TYPE == SPT_PSTAT */
99
100#endif /* SPT_TYPE != SPT_NONE */
101}
102#endif /* HAVE_SETPROCTITLE */
diff --git a/openbsd-compat/setproctitle.h b/openbsd-compat/setproctitle.h
new file mode 100644
index 000000000..000689fac
--- /dev/null
+++ b/openbsd-compat/setproctitle.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_SETPROCTITLE_H
2#define _BSD_SETPROCTITLE_H
3
4#include "config.h"
5
6#ifndef HAVE_SETPROCTITLE
7void setproctitle(const char *fmt, ...);
8#endif
9
10#endif /* _BSD_SETPROCTITLE_H */
diff --git a/openbsd-compat/sigaction.c b/openbsd-compat/sigaction.c
new file mode 100644
index 000000000..47d853fe4
--- /dev/null
+++ b/openbsd-compat/sigaction.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */
2
3/****************************************************************************
4 * Copyright (c) 1998 Free Software Foundation, Inc. *
5 * *
6 * Permission is hereby granted, free of charge, to any person obtaining a *
7 * copy of this software and associated documentation files (the *
8 * "Software"), to deal in the Software without restriction, including *
9 * without limitation the rights to use, copy, modify, merge, publish, *
10 * distribute, distribute with modifications, sublicense, and/or sell *
11 * copies of the Software, and to permit persons to whom the Software is *
12 * furnished to do so, subject to the following conditions: *
13 * *
14 * The above copyright notice and this permission notice shall be included *
15 * in all copies or substantial portions of the Software. *
16 * *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * *
25 * Except as contained in this notice, the name(s) of the above copyright *
26 * holders shall not be used in advertising or otherwise to promote the *
27 * sale, use or other dealings in this Software without prior written *
28 * authorization. *
29 ****************************************************************************/
30
31/****************************************************************************
32 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
33 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
34 ****************************************************************************/
35
36#include <signal.h>
37#include "config.h"
38#include "sigaction.h"
39
40/* This file provides sigaction() emulation using sigvec() */
41/* Use only if this is non POSIX system */
42
43#if !HAVE_SIGACTION && HAVE_SIGVEC
44
45int
46sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact)
47{
48 return sigvec(sig, &(sigact->sv), &(osigact->sv));
49}
50
51int
52sigemptyset (sigset_t * mask)
53{
54 *mask = 0;
55 return 0;
56}
57
58int
59sigprocmask (int mode, sigset_t * mask, sigset_t * omask)
60{
61 sigset_t current = sigsetmask(0);
62
63 if (omask) *omask = current;
64
65 if (mode==SIG_BLOCK)
66 current |= *mask;
67 else if (mode==SIG_UNBLOCK)
68 current &= ~*mask;
69 else if (mode==SIG_SETMASK)
70 current = *mask;
71
72 sigsetmask(current);
73 return 0;
74}
75
76int
77sigsuspend (sigset_t * mask)
78{
79 return sigpause(*mask);
80}
81
82int
83sigdelset (sigset_t * mask, int sig)
84{
85 *mask &= ~sigmask(sig);
86 return 0;
87}
88
89int
90sigaddset (sigset_t * mask, int sig)
91{
92 *mask |= sigmask(sig);
93 return 0;
94}
95
96int
97sigismember (sigset_t * mask, int sig)
98{
99 return (*mask & sigmask(sig)) != 0;
100}
101
102#endif
diff --git a/openbsd-compat/sigaction.h b/openbsd-compat/sigaction.h
new file mode 100644
index 000000000..b37c1f84a
--- /dev/null
+++ b/openbsd-compat/sigaction.h
@@ -0,0 +1,88 @@
1/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */
2
3/****************************************************************************
4 * Copyright (c) 1998 Free Software Foundation, Inc. *
5 * *
6 * Permission is hereby granted, free of charge, to any person obtaining a *
7 * copy of this software and associated documentation files (the *
8 * "Software"), to deal in the Software without restriction, including *
9 * without limitation the rights to use, copy, modify, merge, publish, *
10 * distribute, distribute with modifications, sublicense, and/or sell *
11 * copies of the Software, and to permit persons to whom the Software is *
12 * furnished to do so, subject to the following conditions: *
13 * *
14 * The above copyright notice and this permission notice shall be included *
15 * in all copies or substantial portions of the Software. *
16 * *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * *
25 * Except as contained in this notice, the name(s) of the above copyright *
26 * holders shall not be used in advertising or otherwise to promote the *
27 * sale, use or other dealings in this Software without prior written *
28 * authorization. *
29 ****************************************************************************/
30
31/****************************************************************************
32 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
33 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
34 ****************************************************************************/
35
36/*
37 * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $
38 *
39 * This file exists to handle non-POSIX systems which don't have <unistd.h>,
40 * and usually no sigaction() nor <termios.h>
41 */
42
43#ifndef _SIGACTION_H
44#define _SIGACTION_H
45
46#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
47
48#undef SIG_BLOCK
49#define SIG_BLOCK 00
50
51#undef SIG_UNBLOCK
52#define SIG_UNBLOCK 01
53
54#undef SIG_SETMASK
55#define SIG_SETMASK 02
56
57/*
58 * <bsd/signal.h> is in the Linux 1.2.8 + gcc 2.7.0 configuration,
59 * and is useful for testing this header file.
60 */
61#if HAVE_BSD_SIGNAL_H
62# include <bsd/signal.h>
63#endif
64
65struct sigaction
66{
67 struct sigvec sv;
68};
69
70typedef unsigned long sigset_t;
71
72#undef sa_mask
73#define sa_mask sv.sv_mask
74#undef sa_handler
75#define sa_handler sv.sv_handler
76#undef sa_flags
77#define sa_flags sv.sv_flags
78
79int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact);
80int sigprocmask (int how, sigset_t *mask, sigset_t *omask);
81int sigemptyset (sigset_t *mask);
82int sigsuspend (sigset_t *mask);
83int sigdelset (sigset_t *mask, int sig);
84int sigaddset (sigset_t *mask, int sig);
85
86#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */
87
88#endif /* !defined(_SIGACTION_H) */
diff --git a/openbsd-compat/strlcat.c b/openbsd-compat/strlcat.c
new file mode 100644
index 000000000..10ad9e71a
--- /dev/null
+++ b/openbsd-compat/strlcat.c
@@ -0,0 +1,76 @@
1/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#ifndef HAVE_STRLCAT
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/types.h>
38#include <string.h>
39
40/*
41 * Appends src to string dst of size siz (unlike strncat, siz is the
42 * full size of dst, not space left). At most siz-1 characters
43 * will be copied. Always NUL terminates (unless siz == 0).
44 * Returns strlen(src); if retval >= siz, truncation occurred.
45 */
46size_t strlcat(dst, src, siz)
47 char *dst;
48 const char *src;
49 size_t siz;
50{
51 register char *d = dst;
52 register const char *s = src;
53 register size_t n = siz;
54 size_t dlen;
55
56 /* Find the end of dst and adjust bytes left but don't go past end */
57 while (*d != '\0' && n-- != 0)
58 d++;
59 dlen = d - dst;
60 n = siz - dlen;
61
62 if (n == 0)
63 return(dlen + strlen(s));
64 while (*s != '\0') {
65 if (n != 1) {
66 *d++ = *s;
67 n--;
68 }
69 s++;
70 }
71 *d = '\0';
72
73 return(dlen + (s - src)); /* count does not include NUL */
74}
75
76#endif /* !HAVE_STRLCAT */
diff --git a/openbsd-compat/strlcat.h b/openbsd-compat/strlcat.h
new file mode 100644
index 000000000..562dc7045
--- /dev/null
+++ b/openbsd-compat/strlcat.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_STRLCAT_H
2#define _BSD_STRLCAT_H
3
4#include "config.h"
5#ifndef HAVE_STRLCAT
6#include <sys/types.h>
7size_t strlcat(char *dst, const char *src, size_t siz);
8#endif /* !HAVE_STRLCAT */
9
10#endif /* _BSD_STRLCAT_H */
diff --git a/openbsd-compat/strlcpy.c b/openbsd-compat/strlcpy.c
new file mode 100644
index 000000000..276c25c37
--- /dev/null
+++ b/openbsd-compat/strlcpy.c
@@ -0,0 +1,73 @@
1/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#ifndef HAVE_STRLCPY
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/types.h>
38#include <string.h>
39
40/*
41 * Copy src to string dst of size siz. At most siz-1 characters
42 * will be copied. Always NUL terminates (unless siz == 0).
43 * Returns strlen(src); if retval >= siz, truncation occurred.
44 */
45size_t strlcpy(dst, src, siz)
46 char *dst;
47 const char *src;
48 size_t siz;
49{
50 register char *d = dst;
51 register const char *s = src;
52 register size_t n = siz;
53
54 /* Copy as many bytes as will fit */
55 if (n != 0 && --n != 0) {
56 do {
57 if ((*d++ = *s++) == 0)
58 break;
59 } while (--n != 0);
60 }
61
62 /* Not enough room in dst, add NUL and traverse rest of src */
63 if (n == 0) {
64 if (siz != 0)
65 *d = '\0'; /* NUL-terminate dst */
66 while (*s++)
67 ;
68 }
69
70 return(s - src - 1); /* count does not include NUL */
71}
72
73#endif /* !HAVE_STRLCPY */
diff --git a/openbsd-compat/strlcpy.h b/openbsd-compat/strlcpy.h
new file mode 100644
index 000000000..dafa44af8
--- /dev/null
+++ b/openbsd-compat/strlcpy.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_STRLCPY_H
2#define _BSD_STRLCPY_H
3
4#include "config.h"
5#ifndef HAVE_STRLCPY
6#include <sys/types.h>
7size_t strlcpy(char *dst, const char *src, size_t siz);
8#endif /* !HAVE_STRLCPY */
9
10#endif /* _BSD_STRLCPY_H */
diff --git a/openbsd-compat/strmode.c b/openbsd-compat/strmode.c
new file mode 100644
index 000000000..67e0e4d33
--- /dev/null
+++ b/openbsd-compat/strmode.c
@@ -0,0 +1,158 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "includes.h"
35#ifndef HAVE_STRMODE
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <string.h>
44
45void
46strmode(mode, p)
47 register mode_t mode;
48 register char *p;
49{
50 /* print type */
51 switch (mode & S_IFMT) {
52 case S_IFDIR: /* directory */
53 *p++ = 'd';
54 break;
55 case S_IFCHR: /* character special */
56 *p++ = 'c';
57 break;
58 case S_IFBLK: /* block special */
59 *p++ = 'b';
60 break;
61 case S_IFREG: /* regular */
62 *p++ = '-';
63 break;
64 case S_IFLNK: /* symbolic link */
65 *p++ = 'l';
66 break;
67#ifdef S_IFSOCK
68 case S_IFSOCK: /* socket */
69 *p++ = 's';
70 break;
71#endif
72#ifdef S_IFIFO
73 case S_IFIFO: /* fifo */
74 *p++ = 'p';
75 break;
76#endif
77#ifdef S_IFWHT
78 case S_IFWHT: /* whiteout */
79 *p++ = 'w';
80 break;
81#endif
82 default: /* unknown */
83 *p++ = '?';
84 break;
85 }
86 /* usr */
87 if (mode & S_IRUSR)
88 *p++ = 'r';
89 else
90 *p++ = '-';
91 if (mode & S_IWUSR)
92 *p++ = 'w';
93 else
94 *p++ = '-';
95 switch (mode & (S_IXUSR | S_ISUID)) {
96 case 0:
97 *p++ = '-';
98 break;
99 case S_IXUSR:
100 *p++ = 'x';
101 break;
102 case S_ISUID:
103 *p++ = 'S';
104 break;
105 case S_IXUSR | S_ISUID:
106 *p++ = 's';
107 break;
108 }
109 /* group */
110 if (mode & S_IRGRP)
111 *p++ = 'r';
112 else
113 *p++ = '-';
114 if (mode & S_IWGRP)
115 *p++ = 'w';
116 else
117 *p++ = '-';
118 switch (mode & (S_IXGRP | S_ISGID)) {
119 case 0:
120 *p++ = '-';
121 break;
122 case S_IXGRP:
123 *p++ = 'x';
124 break;
125 case S_ISGID:
126 *p++ = 'S';
127 break;
128 case S_IXGRP | S_ISGID:
129 *p++ = 's';
130 break;
131 }
132 /* other */
133 if (mode & S_IROTH)
134 *p++ = 'r';
135 else
136 *p++ = '-';
137 if (mode & S_IWOTH)
138 *p++ = 'w';
139 else
140 *p++ = '-';
141 switch (mode & (S_IXOTH | S_ISVTX)) {
142 case 0:
143 *p++ = '-';
144 break;
145 case S_IXOTH:
146 *p++ = 'x';
147 break;
148 case S_ISVTX:
149 *p++ = 'T';
150 break;
151 case S_IXOTH | S_ISVTX:
152 *p++ = 't';
153 break;
154 }
155 *p++ = ' '; /* will be a '+' if ACL's implemented */
156 *p = '\0';
157}
158#endif
diff --git a/openbsd-compat/strmode.h b/openbsd-compat/strmode.h
new file mode 100644
index 000000000..773d6bdcd
--- /dev/null
+++ b/openbsd-compat/strmode.h
@@ -0,0 +1,5 @@
1#ifndef HAVE_STRMODE
2
3void strmode( register mode_t mode, register char *p);
4
5#endif
diff --git a/openbsd-compat/strsep.c b/openbsd-compat/strsep.c
new file mode 100644
index 000000000..c03649cff
--- /dev/null
+++ b/openbsd-compat/strsep.c
@@ -0,0 +1,89 @@
1/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "config.h"
37
38#if !defined(HAVE_STRSEP)
39
40#include <string.h>
41#include <stdio.h>
42
43#if defined(LIBC_SCCS) && !defined(lint)
44#if 0
45static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
46#else
47static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $";
48#endif
49#endif /* LIBC_SCCS and not lint */
50
51/*
52 * Get next token from string *stringp, where tokens are possibly-empty
53 * strings separated by characters from delim.
54 *
55 * Writes NULs into the string at *stringp to end tokens.
56 * delim need not remain constant from call to call.
57 * On return, *stringp points past the last NUL written (if there might
58 * be further tokens), or is NULL (if there are definitely no more tokens).
59 *
60 * If *stringp is NULL, strsep returns NULL.
61 */
62char *
63strsep(char **stringp, const char *delim)
64{
65 register char *s;
66 register const char *spanp;
67 register int c, sc;
68 char *tok;
69
70 if ((s = *stringp) == NULL)
71 return (NULL);
72 for (tok = s;;) {
73 c = *s++;
74 spanp = delim;
75 do {
76 if ((sc = *spanp++) == c) {
77 if (c == 0)
78 s = NULL;
79 else
80 s[-1] = 0;
81 *stringp = s;
82 return (tok);
83 }
84 } while (sc != 0);
85 }
86 /* NOTREACHED */
87}
88
89#endif /* !defined(HAVE_STRSEP) */
diff --git a/openbsd-compat/strsep.h b/openbsd-compat/strsep.h
new file mode 100644
index 000000000..d5ba6e0f1
--- /dev/null
+++ b/openbsd-compat/strsep.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_STRSEP_H
2#define _BSD_STRSEP_H
3
4#include "config.h"
5
6#ifndef HAVE_STRSEP
7char *strsep(char **stringp, const char *delim);
8#endif /* HAVE_STRSEP */
9
10#endif /* _BSD_STRSEP_H */
diff --git a/openbsd-compat/strtok.c b/openbsd-compat/strtok.c
new file mode 100644
index 000000000..d197734cb
--- /dev/null
+++ b/openbsd-compat/strtok.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#ifndef HAVE_STRTOK_R
37
38#include "bsd-strtok.h"
39
40#if defined(LIBC_SCCS) && !defined(lint)
41static char *rcsid = "$OpenBSD: strtok.c,v 1.3 1999/11/09 11:19:46 art Exp $";
42#endif /* LIBC_SCCS and not lint */
43
44#include <string.h>
45
46char *strtok_r(char *s, const char *delim, char **last)
47{
48 register char *spanp;
49 register int c, sc;
50 char *tok;
51
52 if (s == NULL && (s = *last) == NULL)
53 return (NULL);
54
55 /*
56 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
57 */
58cont:
59 c = *s++;
60 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
61 if (c == sc)
62 goto cont;
63 }
64
65 if (c == 0) { /* no non-delimiter characters */
66 *last = NULL;
67 return (NULL);
68 }
69 tok = s - 1;
70
71 /*
72 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
73 * Note that delim must have one NUL; we stop if we see that, too.
74 */
75 for (;;) {
76 c = *s++;
77 spanp = (char *)delim;
78 do {
79 if ((sc = *spanp++) == c) {
80 if (c == 0)
81 s = NULL;
82 else
83 s[-1] = 0;
84 *last = s;
85 return (tok);
86 }
87 } while (sc != 0);
88 }
89 /* NOTREACHED */
90}
91
92#endif /* !HAVE_STRTOK_R */
diff --git a/openbsd-compat/strtok.h b/openbsd-compat/strtok.h
new file mode 100644
index 000000000..5a3a56959
--- /dev/null
+++ b/openbsd-compat/strtok.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_STRTOK_H
2#define _BSD_STRTOK_H
3
4#include "config.h"
5
6#ifndef HAVE_STRTOK_R
7char *strtok_r(char *s, const char *delim, char **last);
8#endif /* HAVE_STRTOK_R */
9
10#endif /* _BSD_STRTOK_H */
diff --git a/openbsd-compat/vis.c b/openbsd-compat/vis.c
new file mode 100644
index 000000000..94283a077
--- /dev/null
+++ b/openbsd-compat/vis.c
@@ -0,0 +1,137 @@
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. 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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: vis.c,v 1.5 2000/07/19 15:25:13 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef HAVE_VIS
39
40#include "includes.h"
41
42#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
43
44/*
45 * vis - visually encode characters
46 */
47char *vis(char *dst, int c, int flag, int nextc)
48{
49 if (((u_int)c <= UCHAR_MAX && isascii((u_char)c) &&
50 isgraph((u_char)c)) ||
51 ((flag & VIS_SP) == 0 && c == ' ') ||
52 ((flag & VIS_TAB) == 0 && c == '\t') ||
53 ((flag & VIS_NL) == 0 && c == '\n') ||
54 ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
55 *dst++ = c;
56 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
57 *dst++ = '\\';
58 *dst = '\0';
59 return (dst);
60 }
61
62 if (flag & VIS_CSTYLE) {
63 switch(c) {
64 case '\n':
65 *dst++ = '\\';
66 *dst++ = 'n';
67 goto done;
68 case '\r':
69 *dst++ = '\\';
70 *dst++ = 'r';
71 goto done;
72 case '\b':
73 *dst++ = '\\';
74 *dst++ = 'b';
75 goto done;
76#ifdef __STDC__
77 case '\a':
78#else
79 case '\007':
80#endif
81 *dst++ = '\\';
82 *dst++ = 'a';
83 goto done;
84 case '\v':
85 *dst++ = '\\';
86 *dst++ = 'v';
87 goto done;
88 case '\t':
89 *dst++ = '\\';
90 *dst++ = 't';
91 goto done;
92 case '\f':
93 *dst++ = '\\';
94 *dst++ = 'f';
95 goto done;
96 case ' ':
97 *dst++ = '\\';
98 *dst++ = 's';
99 goto done;
100 case '\0':
101 *dst++ = '\\';
102 *dst++ = '0';
103 if (isoctal(nextc)) {
104 *dst++ = '0';
105 *dst++ = '0';
106 }
107 goto done;
108 }
109 }
110 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
111 *dst++ = '\\';
112 *dst++ = ((u_char)c >> 6 & 07) + '0';
113 *dst++ = ((u_char)c >> 3 & 07) + '0';
114 *dst++ = ((u_char)c & 07) + '0';
115 goto done;
116 }
117 if ((flag & VIS_NOSLASH) == 0)
118 *dst++ = '\\';
119 if (c & 0200) {
120 c &= 0177;
121 *dst++ = 'M';
122 }
123 if (iscntrl(c)) {
124 *dst++ = '^';
125 if (c == 0177)
126 *dst++ = '?';
127 else
128 *dst++ = c + '@';
129 } else {
130 *dst++ = '-';
131 *dst++ = c;
132 }
133done:
134 *dst = '\0';
135 return (dst);
136}
137#endif /* HAVE_VIS */
diff --git a/openbsd-compat/vis.h b/openbsd-compat/vis.h
new file mode 100644
index 000000000..52e867b94
--- /dev/null
+++ b/openbsd-compat/vis.h
@@ -0,0 +1,32 @@
1#ifndef _BSD_VIS_H
2#define _BSD_VIS_H
3
4#include "config.h"
5
6#ifndef HAVE_VIS
7
8/*
9 * to select alternate encoding format
10 */
11#define VIS_OCTAL 0x01 /* use octal \ddd format */
12#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */
13
14/*
15 * to alter set of characters encoded (default is to encode all
16 * non-graphic except space, tab, and newline).
17 */
18#define VIS_SP 0x04 /* also encode space */
19#define VIS_TAB 0x08 /* also encode tab */
20#define VIS_NL 0x10 /* also encode newline */
21#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
22#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
23
24/*
25 * other
26 */
27#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
28
29char *vis (char *, int, int, int);
30#endif /* HAVE_VIS */
31
32#endif /* _BSD_VIS_H */