diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | acconfig.h | 5 | ||||
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | includes.h | 9 | ||||
-rw-r--r-- | openbsd-compat/Makefile.in | 4 | ||||
-rw-r--r-- | openbsd-compat/glob.c | 859 | ||||
-rw-r--r-- | openbsd-compat/glob.h | 98 | ||||
-rw-r--r-- | openbsd-compat/openbsd-compat.h | 3 | ||||
-rw-r--r-- | sftp-glob.c | 2 | ||||
-rw-r--r-- | sftp-int.c | 2 | ||||
-rw-r--r-- | ssh.h | 2 |
12 files changed, 1001 insertions, 19 deletions
@@ -6,7 +6,11 @@ | |||
6 | - djm@cvs.openbsd.org 2001/03/13 22:42:54 | 6 | - djm@cvs.openbsd.org 2001/03/13 22:42:54 |
7 | [sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp-int.c] | 7 | [sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp-int.c] |
8 | sftp client filename globbing for get, put, ch{mod,grp,own}. ok markus@ | 8 | sftp client filename globbing for get, put, ch{mod,grp,own}. ok markus@ |
9 | - Fix strerror() in bsd-misc.c | 9 | - (bal) Fix strerror() in bsd-misc.c |
10 | - (djm) Add replacement glob() from OpenBSD libc if the system glob is | ||
11 | missing or lacks the GLOB_ALTDIRFUNC extension | ||
12 | - (djm) Remove -I$(srcdir)/openbsd-compat from CFLAGS, refer to headers | ||
13 | relatively. Avoids conflict between glob.h and /usr/include/glob.h | ||
10 | 14 | ||
11 | 20010313 | 15 | 20010313 |
12 | - OpenBSD CVS Sync | 16 | - OpenBSD CVS Sync |
@@ -4541,4 +4545,4 @@ | |||
4541 | - Wrote replacements for strlcpy and mkdtemp | 4545 | - Wrote replacements for strlcpy and mkdtemp |
4542 | - Released 1.0pre1 | 4546 | - Released 1.0pre1 |
4543 | 4547 | ||
4544 | $Id: ChangeLog,v 1.954 2001/03/13 23:38:20 mouring Exp $ | 4548 | $Id: ChangeLog,v 1.955 2001/03/14 00:39:45 djm Exp $ |
diff --git a/Makefile.in b/Makefile.in index b25ca00cd..2fd16be44 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.160 2001/03/13 23:27:09 djm Exp $ | 1 | # $Id: Makefile.in,v 1.161 2001/03/14 00:39:46 djm Exp $ |
2 | 2 | ||
3 | prefix=@prefix@ | 3 | prefix=@prefix@ |
4 | exec_prefix=@exec_prefix@ | 4 | exec_prefix=@exec_prefix@ |
@@ -26,7 +26,7 @@ PATHS= -DETCDIR=\"$(sysconfdir)\" \ | |||
26 | CC=@CC@ | 26 | CC=@CC@ |
27 | LD=@LD@ | 27 | LD=@LD@ |
28 | CFLAGS=@CFLAGS@ | 28 | CFLAGS=@CFLAGS@ |
29 | CPPFLAGS=-I. -I$(srcdir) -I$(srcdir)/openbsd-compat @CPPFLAGS@ $(PATHS) @DEFS@ | 29 | CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ |
30 | LIBS=@LIBS@ | 30 | LIBS=@LIBS@ |
31 | AR=@AR@ | 31 | AR=@AR@ |
32 | RANLIB=@RANLIB@ | 32 | RANLIB=@RANLIB@ |
diff --git a/acconfig.h b/acconfig.h index db53d1696..65584fc3f 100644 --- a/acconfig.h +++ b/acconfig.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: acconfig.h,v 1.106 2001/03/03 13:29:21 djm Exp $ */ | 1 | /* $Id: acconfig.h,v 1.107 2001/03/14 00:39:46 djm Exp $ */ |
2 | 2 | ||
3 | #ifndef _CONFIG_H | 3 | #ifndef _CONFIG_H |
4 | #define _CONFIG_H | 4 | #define _CONFIG_H |
@@ -302,6 +302,9 @@ | |||
302 | /* Needed for SCO and NeXT */ | 302 | /* Needed for SCO and NeXT */ |
303 | #undef BROKEN_SAVED_UIDS | 303 | #undef BROKEN_SAVED_UIDS |
304 | 304 | ||
305 | /* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ | ||
306 | #undef GLOB_HAS_ALTDIRFUNC | ||
307 | |||
305 | @BOTTOM@ | 308 | @BOTTOM@ |
306 | 309 | ||
307 | /* ******************* Shouldn't need to edit below this line ************** */ | 310 | /* ******************* Shouldn't need to edit below this line ************** */ |
diff --git a/configure.in b/configure.in index d31bf1a72..d3a902a86 100644 --- a/configure.in +++ b/configure.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.in,v 1.264 2001/03/12 01:32:12 tim Exp $ | 1 | # $Id: configure.in,v 1.265 2001/03/14 00:39:46 djm Exp $ |
2 | 2 | ||
3 | AC_INIT(ssh.c) | 3 | AC_INIT(ssh.c) |
4 | 4 | ||
@@ -368,7 +368,25 @@ AC_CHECK_FUNC(utimes, | |||
368 | AC_FUNC_STRFTIME | 368 | AC_FUNC_STRFTIME |
369 | 369 | ||
370 | # Checks for header files. | 370 | # Checks for header files. |
371 | AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h) | 371 | AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h) |
372 | |||
373 | # Check for ALTDIRFUNC glob() extension | ||
374 | AC_MSG_CHECKING(for GLOB_ALTDIRFUNC support) | ||
375 | AC_EGREP_CPP(FOUNDIT, | ||
376 | [ | ||
377 | #include <glob.h> | ||
378 | #ifdef GLOB_ALTDIRFUNC | ||
379 | FOUNDIT | ||
380 | #endif | ||
381 | ], | ||
382 | [ | ||
383 | AC_DEFINE(GLOB_HAS_ALTDIRFUNC) | ||
384 | AC_MSG_RESULT(yes) | ||
385 | ], | ||
386 | [ | ||
387 | AC_MSG_RESULT(no) | ||
388 | ] | ||
389 | ) | ||
372 | 390 | ||
373 | # Check whether user wants Kerberos support | 391 | # Check whether user wants Kerberos support |
374 | KRB4_MSG="no" | 392 | KRB4_MSG="no" |
@@ -491,7 +509,7 @@ AC_ARG_WITH(tcp-wrappers, | |||
491 | ) | 509 | ) |
492 | 510 | ||
493 | dnl Checks for library functions. | 511 | dnl Checks for library functions. |
494 | AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_sa clock fchown fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getgrouplist getnameinfo getrlimit getrusage getttyent inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setdtablesize setenv seteuid setlogin setproctitle setreuid setrlimit setsid sigaction sigvec snprintf strerror strlcat strlcpy strmode strsep strtok_r sysconf tcgetpgrp utimes vsnprintf vhangup vis waitpid _getpty __b64_ntop) | 512 | AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_sa clock fchown fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getgrouplist getnameinfo getrlimit getrusage getttyent glob inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setdtablesize setenv seteuid setlogin setproctitle setreuid setrlimit setsid sigaction sigvec snprintf strerror strlcat strlcpy strmode strsep strtok_r sysconf tcgetpgrp utimes vsnprintf vhangup vis waitpid _getpty __b64_ntop) |
495 | dnl Checks for time functions | 513 | dnl Checks for time functions |
496 | AC_CHECK_FUNCS(gettimeofday time) | 514 | AC_CHECK_FUNCS(gettimeofday time) |
497 | dnl Checks for libutil functions | 515 | dnl Checks for libutil functions |
diff --git a/includes.h b/includes.h index a4ebbd3d3..3f834ba86 100644 --- a/includes.h +++ b/includes.h | |||
@@ -21,7 +21,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } | |||
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | 23 | ||
24 | #include "bsd-nextstep.h" | 24 | #include "openbsd-compat/bsd-nextstep.h" |
25 | 25 | ||
26 | #include <sys/types.h> | 26 | #include <sys/types.h> |
27 | #include <sys/socket.h> | 27 | #include <sys/socket.h> |
@@ -54,6 +54,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } | |||
54 | #ifdef HAVE_BSTRING_H | 54 | #ifdef HAVE_BSTRING_H |
55 | # include <bstring.h> | 55 | # include <bstring.h> |
56 | #endif | 56 | #endif |
57 | #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) | ||
58 | # include <glob.h> | ||
59 | #endif | ||
57 | #ifdef HAVE_NETGROUP_H | 60 | #ifdef HAVE_NETGROUP_H |
58 | # include <netgroup.h> | 61 | # include <netgroup.h> |
59 | #endif | 62 | #endif |
@@ -95,8 +98,8 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } | |||
95 | # include <vis.h> | 98 | # include <vis.h> |
96 | #endif | 99 | #endif |
97 | #include "version.h" | 100 | #include "version.h" |
98 | #include "openbsd-compat.h" | 101 | #include "openbsd-compat/openbsd-compat.h" |
99 | #include "bsd-cygwin_util.h" | 102 | #include "openbsd-compat/bsd-cygwin_util.h" |
100 | #include "entropy.h" | 103 | #include "entropy.h" |
101 | 104 | ||
102 | #endif /* INCLUDES_H */ | 105 | #endif /* INCLUDES_H */ |
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 40d59db72..17128ad50 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.7 2001/03/12 05:16:19 mouring Exp $ | 1 | # $Id: Makefile.in,v 1.8 2001/03/14 00:39:46 djm Exp $ |
2 | 2 | ||
3 | sysconfdir=@sysconfdir@ | 3 | sysconfdir=@sysconfdir@ |
4 | piddir=@piddir@ | 4 | piddir=@piddir@ |
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@ | |||
16 | INSTALL=@INSTALL@ | 16 | INSTALL=@INSTALL@ |
17 | LDFLAGS=-L. @LDFLAGS@ | 17 | LDFLAGS=-L. @LDFLAGS@ |
18 | 18 | ||
19 | OPENBSD=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 sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtok.o vis.o | 19 | OPENBSD=base64.o bindresvport.o daemon.o getcwd.o glob.o getgrouplist.o inet_aton.o inet_ntoa.o mktemp.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtok.o vis.o |
20 | 20 | ||
21 | COMPAT=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 | 21 | COMPAT=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 |
22 | 22 | ||
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c new file mode 100644 index 000000000..2e2551866 --- /dev/null +++ b/openbsd-compat/glob.c | |||
@@ -0,0 +1,859 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1989, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * This code is derived from software contributed to Berkeley by | ||
6 | * Guido van Rossum. | ||
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 | #include <ctype.h> | ||
39 | |||
40 | #if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) | ||
41 | |||
42 | #if defined(LIBC_SCCS) && !defined(lint) | ||
43 | #if 0 | ||
44 | static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; | ||
45 | #else | ||
46 | static char rcsid[] = "$OpenBSD: glob.c,v 1.8 1998/08/14 21:39:30 deraadt Exp $"; | ||
47 | #endif | ||
48 | #endif /* LIBC_SCCS and not lint */ | ||
49 | |||
50 | /* | ||
51 | * glob(3) -- a superset of the one defined in POSIX 1003.2. | ||
52 | * | ||
53 | * The [!...] convention to negate a range is supported (SysV, Posix, ksh). | ||
54 | * | ||
55 | * Optional extra services, controlled by flags not defined by POSIX: | ||
56 | * | ||
57 | * GLOB_QUOTE: | ||
58 | * Escaping convention: \ inhibits any special meaning the following | ||
59 | * character might have (except \ at end of string is retained). | ||
60 | * GLOB_MAGCHAR: | ||
61 | * Set in gl_flags if pattern contained a globbing character. | ||
62 | * GLOB_NOMAGIC: | ||
63 | * Same as GLOB_NOCHECK, but it will only append pattern if it did | ||
64 | * not contain any magic characters. [Used in csh style globbing] | ||
65 | * GLOB_ALTDIRFUNC: | ||
66 | * Use alternately specified directory access functions. | ||
67 | * GLOB_TILDE: | ||
68 | * expand ~user/foo to the /home/dir/of/user/foo | ||
69 | * GLOB_BRACE: | ||
70 | * expand {1,2}{a,b} to 1a 1b 2a 2b | ||
71 | * gl_matchc: | ||
72 | * Number of matches in the current invocation of glob. | ||
73 | */ | ||
74 | |||
75 | |||
76 | #define DOLLAR '$' | ||
77 | #define DOT '.' | ||
78 | #define EOS '\0' | ||
79 | #define LBRACKET '[' | ||
80 | #define NOT '!' | ||
81 | #define QUESTION '?' | ||
82 | #define QUOTE '\\' | ||
83 | #define RANGE '-' | ||
84 | #define RBRACKET ']' | ||
85 | #define SEP '/' | ||
86 | #define STAR '*' | ||
87 | #define TILDE '~' | ||
88 | #define UNDERSCORE '_' | ||
89 | #define LBRACE '{' | ||
90 | #define RBRACE '}' | ||
91 | #define SLASH '/' | ||
92 | #define COMMA ',' | ||
93 | |||
94 | #ifndef DEBUG | ||
95 | |||
96 | #define M_QUOTE 0x8000 | ||
97 | #define M_PROTECT 0x4000 | ||
98 | #define M_MASK 0xffff | ||
99 | #define M_ASCII 0x00ff | ||
100 | |||
101 | typedef u_short Char; | ||
102 | |||
103 | #else | ||
104 | |||
105 | #define M_QUOTE 0x80 | ||
106 | #define M_PROTECT 0x40 | ||
107 | #define M_MASK 0xff | ||
108 | #define M_ASCII 0x7f | ||
109 | |||
110 | typedef char Char; | ||
111 | |||
112 | #endif | ||
113 | |||
114 | |||
115 | #define CHAR(c) ((Char)((c)&M_ASCII)) | ||
116 | #define META(c) ((Char)((c)|M_QUOTE)) | ||
117 | #define M_ALL META('*') | ||
118 | #define M_END META(']') | ||
119 | #define M_NOT META('!') | ||
120 | #define M_ONE META('?') | ||
121 | #define M_RNG META('-') | ||
122 | #define M_SET META('[') | ||
123 | #define ismeta(c) (((c)&M_QUOTE) != 0) | ||
124 | |||
125 | |||
126 | static int compare __P((const void *, const void *)); | ||
127 | static void g_Ctoc __P((const Char *, char *)); | ||
128 | static int g_lstat __P((Char *, struct stat *, glob_t *)); | ||
129 | static DIR *g_opendir __P((Char *, glob_t *)); | ||
130 | static Char *g_strchr __P((Char *, int)); | ||
131 | #ifdef notdef | ||
132 | static Char *g_strcat __P((Char *, const Char *)); | ||
133 | #endif | ||
134 | static int g_stat __P((Char *, struct stat *, glob_t *)); | ||
135 | static int glob0 __P((const Char *, glob_t *)); | ||
136 | static int glob1 __P((Char *, glob_t *)); | ||
137 | static int glob2 __P((Char *, Char *, Char *, glob_t *)); | ||
138 | static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); | ||
139 | static int globextend __P((const Char *, glob_t *)); | ||
140 | static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *)); | ||
141 | static int globexp1 __P((const Char *, glob_t *)); | ||
142 | static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); | ||
143 | static int match __P((Char *, Char *, Char *)); | ||
144 | #ifdef DEBUG | ||
145 | static void qprintf __P((const char *, Char *)); | ||
146 | #endif | ||
147 | |||
148 | int | ||
149 | glob(pattern, flags, errfunc, pglob) | ||
150 | const char *pattern; | ||
151 | int flags, (*errfunc) __P((const char *, int)); | ||
152 | glob_t *pglob; | ||
153 | { | ||
154 | const u_char *patnext; | ||
155 | int c; | ||
156 | Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; | ||
157 | |||
158 | patnext = (u_char *) pattern; | ||
159 | if (!(flags & GLOB_APPEND)) { | ||
160 | pglob->gl_pathc = 0; | ||
161 | pglob->gl_pathv = NULL; | ||
162 | if (!(flags & GLOB_DOOFFS)) | ||
163 | pglob->gl_offs = 0; | ||
164 | } | ||
165 | pglob->gl_flags = flags & ~GLOB_MAGCHAR; | ||
166 | pglob->gl_errfunc = errfunc; | ||
167 | pglob->gl_matchc = 0; | ||
168 | |||
169 | bufnext = patbuf; | ||
170 | bufend = bufnext + MAXPATHLEN; | ||
171 | if (flags & GLOB_NOESCAPE) | ||
172 | while (bufnext < bufend && (c = *patnext++) != EOS) | ||
173 | *bufnext++ = c; | ||
174 | else { | ||
175 | /* Protect the quoted characters. */ | ||
176 | while (bufnext < bufend && (c = *patnext++) != EOS) | ||
177 | if (c == QUOTE) { | ||
178 | if ((c = *patnext++) == EOS) { | ||
179 | c = QUOTE; | ||
180 | --patnext; | ||
181 | } | ||
182 | *bufnext++ = c | M_PROTECT; | ||
183 | } | ||
184 | else | ||
185 | *bufnext++ = c; | ||
186 | } | ||
187 | *bufnext = EOS; | ||
188 | |||
189 | if (flags & GLOB_BRACE) | ||
190 | return globexp1(patbuf, pglob); | ||
191 | else | ||
192 | return glob0(patbuf, pglob); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Expand recursively a glob {} pattern. When there is no more expansion | ||
197 | * invoke the standard globbing routine to glob the rest of the magic | ||
198 | * characters | ||
199 | */ | ||
200 | static int globexp1(pattern, pglob) | ||
201 | const Char *pattern; | ||
202 | glob_t *pglob; | ||
203 | { | ||
204 | const Char* ptr = pattern; | ||
205 | int rv; | ||
206 | |||
207 | /* Protect a single {}, for find(1), like csh */ | ||
208 | if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) | ||
209 | return glob0(pattern, pglob); | ||
210 | |||
211 | while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) | ||
212 | if (!globexp2(ptr, pattern, pglob, &rv)) | ||
213 | return rv; | ||
214 | |||
215 | return glob0(pattern, pglob); | ||
216 | } | ||
217 | |||
218 | |||
219 | /* | ||
220 | * Recursive brace globbing helper. Tries to expand a single brace. | ||
221 | * If it succeeds then it invokes globexp1 with the new pattern. | ||
222 | * If it fails then it tries to glob the rest of the pattern and returns. | ||
223 | */ | ||
224 | static int globexp2(ptr, pattern, pglob, rv) | ||
225 | const Char *ptr, *pattern; | ||
226 | glob_t *pglob; | ||
227 | int *rv; | ||
228 | { | ||
229 | int i; | ||
230 | Char *lm, *ls; | ||
231 | const Char *pe, *pm, *pl; | ||
232 | Char patbuf[MAXPATHLEN + 1]; | ||
233 | |||
234 | /* copy part up to the brace */ | ||
235 | for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) | ||
236 | continue; | ||
237 | ls = lm; | ||
238 | |||
239 | /* Find the balanced brace */ | ||
240 | for (i = 0, pe = ++ptr; *pe; pe++) | ||
241 | if (*pe == LBRACKET) { | ||
242 | /* Ignore everything between [] */ | ||
243 | for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) | ||
244 | continue; | ||
245 | if (*pe == EOS) { | ||
246 | /* | ||
247 | * We could not find a matching RBRACKET. | ||
248 | * Ignore and just look for RBRACE | ||
249 | */ | ||
250 | pe = pm; | ||
251 | } | ||
252 | } | ||
253 | else if (*pe == LBRACE) | ||
254 | i++; | ||
255 | else if (*pe == RBRACE) { | ||
256 | if (i == 0) | ||
257 | break; | ||
258 | i--; | ||
259 | } | ||
260 | |||
261 | /* Non matching braces; just glob the pattern */ | ||
262 | if (i != 0 || *pe == EOS) { | ||
263 | *rv = glob0(patbuf, pglob); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | for (i = 0, pl = pm = ptr; pm <= pe; pm++) | ||
268 | switch (*pm) { | ||
269 | case LBRACKET: | ||
270 | /* Ignore everything between [] */ | ||
271 | for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) | ||
272 | continue; | ||
273 | if (*pm == EOS) { | ||
274 | /* | ||
275 | * We could not find a matching RBRACKET. | ||
276 | * Ignore and just look for RBRACE | ||
277 | */ | ||
278 | pm = pl; | ||
279 | } | ||
280 | break; | ||
281 | |||
282 | case LBRACE: | ||
283 | i++; | ||
284 | break; | ||
285 | |||
286 | case RBRACE: | ||
287 | if (i) { | ||
288 | i--; | ||
289 | break; | ||
290 | } | ||
291 | /* FALLTHROUGH */ | ||
292 | case COMMA: | ||
293 | if (i && *pm == COMMA) | ||
294 | break; | ||
295 | else { | ||
296 | /* Append the current string */ | ||
297 | for (lm = ls; (pl < pm); *lm++ = *pl++) | ||
298 | continue; | ||
299 | /* | ||
300 | * Append the rest of the pattern after the | ||
301 | * closing brace | ||
302 | */ | ||
303 | for (pl = pe + 1; (*lm++ = *pl++) != EOS;) | ||
304 | continue; | ||
305 | |||
306 | /* Expand the current pattern */ | ||
307 | #ifdef DEBUG | ||
308 | qprintf("globexp2:", patbuf); | ||
309 | #endif | ||
310 | *rv = globexp1(patbuf, pglob); | ||
311 | |||
312 | /* move after the comma, to the next string */ | ||
313 | pl = pm + 1; | ||
314 | } | ||
315 | break; | ||
316 | |||
317 | default: | ||
318 | break; | ||
319 | } | ||
320 | *rv = 0; | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | |||
325 | |||
326 | /* | ||
327 | * expand tilde from the passwd file. | ||
328 | */ | ||
329 | static const Char * | ||
330 | globtilde(pattern, patbuf, patbuf_len, pglob) | ||
331 | const Char *pattern; | ||
332 | Char *patbuf; | ||
333 | size_t patbuf_len; | ||
334 | glob_t *pglob; | ||
335 | { | ||
336 | struct passwd *pwd; | ||
337 | char *h; | ||
338 | const Char *p; | ||
339 | Char *b, *eb; | ||
340 | |||
341 | if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) | ||
342 | return pattern; | ||
343 | |||
344 | /* Copy up to the end of the string or / */ | ||
345 | eb = &patbuf[patbuf_len - 1]; | ||
346 | for (p = pattern + 1, h = (char *) patbuf; | ||
347 | h < (char *)eb && *p && *p != SLASH; *h++ = *p++) | ||
348 | continue; | ||
349 | |||
350 | *h = EOS; | ||
351 | |||
352 | if (((char *) patbuf)[0] == EOS) { | ||
353 | /* | ||
354 | * handle a plain ~ or ~/ by expanding $HOME | ||
355 | * first and then trying the password file | ||
356 | */ | ||
357 | #if 0 | ||
358 | if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { | ||
359 | #endif | ||
360 | if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { | ||
361 | if ((pwd = getpwuid(getuid())) == NULL) | ||
362 | return pattern; | ||
363 | else | ||
364 | h = pwd->pw_dir; | ||
365 | } | ||
366 | } | ||
367 | else { | ||
368 | /* | ||
369 | * Expand a ~user | ||
370 | */ | ||
371 | if ((pwd = getpwnam((char*) patbuf)) == NULL) | ||
372 | return pattern; | ||
373 | else | ||
374 | h = pwd->pw_dir; | ||
375 | } | ||
376 | |||
377 | /* Copy the home directory */ | ||
378 | for (b = patbuf; b < eb && *h; *b++ = *h++) | ||
379 | continue; | ||
380 | |||
381 | /* Append the rest of the pattern */ | ||
382 | while (b < eb && (*b++ = *p++) != EOS) | ||
383 | continue; | ||
384 | *b = EOS; | ||
385 | |||
386 | return patbuf; | ||
387 | } | ||
388 | |||
389 | |||
390 | /* | ||
391 | * The main glob() routine: compiles the pattern (optionally processing | ||
392 | * quotes), calls glob1() to do the real pattern matching, and finally | ||
393 | * sorts the list (unless unsorted operation is requested). Returns 0 | ||
394 | * if things went well, nonzero if errors occurred. It is not an error | ||
395 | * to find no matches. | ||
396 | */ | ||
397 | static int | ||
398 | glob0(pattern, pglob) | ||
399 | const Char *pattern; | ||
400 | glob_t *pglob; | ||
401 | { | ||
402 | const Char *qpatnext; | ||
403 | int c, err, oldpathc; | ||
404 | Char *bufnext, patbuf[MAXPATHLEN+1]; | ||
405 | |||
406 | qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char), | ||
407 | pglob); | ||
408 | oldpathc = pglob->gl_pathc; | ||
409 | bufnext = patbuf; | ||
410 | |||
411 | /* We don't need to check for buffer overflow any more. */ | ||
412 | while ((c = *qpatnext++) != EOS) { | ||
413 | switch (c) { | ||
414 | case LBRACKET: | ||
415 | c = *qpatnext; | ||
416 | if (c == NOT) | ||
417 | ++qpatnext; | ||
418 | if (*qpatnext == EOS || | ||
419 | g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { | ||
420 | *bufnext++ = LBRACKET; | ||
421 | if (c == NOT) | ||
422 | --qpatnext; | ||
423 | break; | ||
424 | } | ||
425 | *bufnext++ = M_SET; | ||
426 | if (c == NOT) | ||
427 | *bufnext++ = M_NOT; | ||
428 | c = *qpatnext++; | ||
429 | do { | ||
430 | *bufnext++ = CHAR(c); | ||
431 | if (*qpatnext == RANGE && | ||
432 | (c = qpatnext[1]) != RBRACKET) { | ||
433 | *bufnext++ = M_RNG; | ||
434 | *bufnext++ = CHAR(c); | ||
435 | qpatnext += 2; | ||
436 | } | ||
437 | } while ((c = *qpatnext++) != RBRACKET); | ||
438 | pglob->gl_flags |= GLOB_MAGCHAR; | ||
439 | *bufnext++ = M_END; | ||
440 | break; | ||
441 | case QUESTION: | ||
442 | pglob->gl_flags |= GLOB_MAGCHAR; | ||
443 | *bufnext++ = M_ONE; | ||
444 | break; | ||
445 | case STAR: | ||
446 | pglob->gl_flags |= GLOB_MAGCHAR; | ||
447 | /* collapse adjacent stars to one, | ||
448 | * to avoid exponential behavior | ||
449 | */ | ||
450 | if (bufnext == patbuf || bufnext[-1] != M_ALL) | ||
451 | *bufnext++ = M_ALL; | ||
452 | break; | ||
453 | default: | ||
454 | *bufnext++ = CHAR(c); | ||
455 | break; | ||
456 | } | ||
457 | } | ||
458 | *bufnext = EOS; | ||
459 | #ifdef DEBUG | ||
460 | qprintf("glob0:", patbuf); | ||
461 | #endif | ||
462 | |||
463 | if ((err = glob1(patbuf, pglob)) != 0) | ||
464 | return(err); | ||
465 | |||
466 | /* | ||
467 | * If there was no match we are going to append the pattern | ||
468 | * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified | ||
469 | * and the pattern did not contain any magic characters | ||
470 | * GLOB_NOMAGIC is there just for compatibility with csh. | ||
471 | */ | ||
472 | if (pglob->gl_pathc == oldpathc) { | ||
473 | if ((pglob->gl_flags & GLOB_NOCHECK) || | ||
474 | ((pglob->gl_flags & GLOB_NOMAGIC) && | ||
475 | !(pglob->gl_flags & GLOB_MAGCHAR))) | ||
476 | return(globextend(pattern, pglob)); | ||
477 | else | ||
478 | return(GLOB_NOMATCH); | ||
479 | } | ||
480 | if (!(pglob->gl_flags & GLOB_NOSORT)) | ||
481 | qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, | ||
482 | pglob->gl_pathc - oldpathc, sizeof(char *), compare); | ||
483 | return(0); | ||
484 | } | ||
485 | |||
486 | static int | ||
487 | compare(p, q) | ||
488 | const void *p, *q; | ||
489 | { | ||
490 | return(strcmp(*(char **)p, *(char **)q)); | ||
491 | } | ||
492 | |||
493 | static int | ||
494 | glob1(pattern, pglob) | ||
495 | Char *pattern; | ||
496 | glob_t *pglob; | ||
497 | { | ||
498 | Char pathbuf[MAXPATHLEN+1]; | ||
499 | |||
500 | /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ | ||
501 | if (*pattern == EOS) | ||
502 | return(0); | ||
503 | return(glob2(pathbuf, pathbuf, pattern, pglob)); | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * The functions glob2 and glob3 are mutually recursive; there is one level | ||
508 | * of recursion for each segment in the pattern that contains one or more | ||
509 | * meta characters. | ||
510 | */ | ||
511 | static int | ||
512 | glob2(pathbuf, pathend, pattern, pglob) | ||
513 | Char *pathbuf, *pathend, *pattern; | ||
514 | glob_t *pglob; | ||
515 | { | ||
516 | struct stat sb; | ||
517 | Char *p, *q; | ||
518 | int anymeta; | ||
519 | |||
520 | /* | ||
521 | * Loop over pattern segments until end of pattern or until | ||
522 | * segment with meta character found. | ||
523 | */ | ||
524 | for (anymeta = 0;;) { | ||
525 | if (*pattern == EOS) { /* End of pattern? */ | ||
526 | *pathend = EOS; | ||
527 | if (g_lstat(pathbuf, &sb, pglob)) | ||
528 | return(0); | ||
529 | |||
530 | if (((pglob->gl_flags & GLOB_MARK) && | ||
531 | pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) | ||
532 | || (S_ISLNK(sb.st_mode) && | ||
533 | (g_stat(pathbuf, &sb, pglob) == 0) && | ||
534 | S_ISDIR(sb.st_mode)))) { | ||
535 | *pathend++ = SEP; | ||
536 | *pathend = EOS; | ||
537 | } | ||
538 | ++pglob->gl_matchc; | ||
539 | return(globextend(pathbuf, pglob)); | ||
540 | } | ||
541 | |||
542 | /* Find end of next segment, copy tentatively to pathend. */ | ||
543 | q = pathend; | ||
544 | p = pattern; | ||
545 | while (*p != EOS && *p != SEP) { | ||
546 | if (ismeta(*p)) | ||
547 | anymeta = 1; | ||
548 | *q++ = *p++; | ||
549 | } | ||
550 | |||
551 | if (!anymeta) { /* No expansion, do next segment. */ | ||
552 | pathend = q; | ||
553 | pattern = p; | ||
554 | while (*pattern == SEP) | ||
555 | *pathend++ = *pattern++; | ||
556 | } else /* Need expansion, recurse. */ | ||
557 | return(glob3(pathbuf, pathend, pattern, p, pglob)); | ||
558 | } | ||
559 | /* NOTREACHED */ | ||
560 | } | ||
561 | |||
562 | static int | ||
563 | glob3(pathbuf, pathend, pattern, restpattern, pglob) | ||
564 | Char *pathbuf, *pathend, *pattern, *restpattern; | ||
565 | glob_t *pglob; | ||
566 | { | ||
567 | register struct dirent *dp; | ||
568 | DIR *dirp; | ||
569 | int err; | ||
570 | char buf[MAXPATHLEN]; | ||
571 | |||
572 | /* | ||
573 | * The readdirfunc declaration can't be prototyped, because it is | ||
574 | * assigned, below, to two functions which are prototyped in glob.h | ||
575 | * and dirent.h as taking pointers to differently typed opaque | ||
576 | * structures. | ||
577 | */ | ||
578 | struct dirent *(*readdirfunc)(); | ||
579 | |||
580 | *pathend = EOS; | ||
581 | errno = 0; | ||
582 | |||
583 | if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { | ||
584 | /* TODO: don't call for ENOENT or ENOTDIR? */ | ||
585 | if (pglob->gl_errfunc) { | ||
586 | g_Ctoc(pathbuf, buf); | ||
587 | if (pglob->gl_errfunc(buf, errno) || | ||
588 | pglob->gl_flags & GLOB_ERR) | ||
589 | return (GLOB_ABORTED); | ||
590 | } | ||
591 | return(0); | ||
592 | } | ||
593 | |||
594 | err = 0; | ||
595 | |||
596 | /* Search directory for matching names. */ | ||
597 | if (pglob->gl_flags & GLOB_ALTDIRFUNC) | ||
598 | readdirfunc = pglob->gl_readdir; | ||
599 | else | ||
600 | readdirfunc = readdir; | ||
601 | while ((dp = (*readdirfunc)(dirp))) { | ||
602 | register u_char *sc; | ||
603 | register Char *dc; | ||
604 | |||
605 | /* Initial DOT must be matched literally. */ | ||
606 | if (dp->d_name[0] == DOT && *pattern != DOT) | ||
607 | continue; | ||
608 | for (sc = (u_char *) dp->d_name, dc = pathend; | ||
609 | (*dc++ = *sc++) != EOS;) | ||
610 | continue; | ||
611 | if (!match(pathend, pattern, restpattern)) { | ||
612 | *pathend = EOS; | ||
613 | continue; | ||
614 | } | ||
615 | err = glob2(pathbuf, --dc, restpattern, pglob); | ||
616 | if (err) | ||
617 | break; | ||
618 | } | ||
619 | |||
620 | if (pglob->gl_flags & GLOB_ALTDIRFUNC) | ||
621 | (*pglob->gl_closedir)(dirp); | ||
622 | else | ||
623 | closedir(dirp); | ||
624 | return(err); | ||
625 | } | ||
626 | |||
627 | |||
628 | /* | ||
629 | * Extend the gl_pathv member of a glob_t structure to accomodate a new item, | ||
630 | * add the new item, and update gl_pathc. | ||
631 | * | ||
632 | * This assumes the BSD realloc, which only copies the block when its size | ||
633 | * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic | ||
634 | * behavior. | ||
635 | * | ||
636 | * Return 0 if new item added, error code if memory couldn't be allocated. | ||
637 | * | ||
638 | * Invariant of the glob_t structure: | ||
639 | * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and | ||
640 | * gl_pathv points to (gl_offs + gl_pathc + 1) items. | ||
641 | */ | ||
642 | static int | ||
643 | globextend(path, pglob) | ||
644 | const Char *path; | ||
645 | glob_t *pglob; | ||
646 | { | ||
647 | register char **pathv; | ||
648 | register int i; | ||
649 | u_int newsize; | ||
650 | char *copy; | ||
651 | const Char *p; | ||
652 | |||
653 | newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); | ||
654 | pathv = pglob->gl_pathv ? | ||
655 | realloc((char *)pglob->gl_pathv, newsize) : | ||
656 | malloc(newsize); | ||
657 | if (pathv == NULL) { | ||
658 | if (pglob->gl_pathv) | ||
659 | free(pglob->gl_pathv); | ||
660 | return(GLOB_NOSPACE); | ||
661 | } | ||
662 | |||
663 | if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { | ||
664 | /* first time around -- clear initial gl_offs items */ | ||
665 | pathv += pglob->gl_offs; | ||
666 | for (i = pglob->gl_offs; --i >= 0; ) | ||
667 | *--pathv = NULL; | ||
668 | } | ||
669 | pglob->gl_pathv = pathv; | ||
670 | |||
671 | for (p = path; *p++;) | ||
672 | continue; | ||
673 | if ((copy = malloc(p - path)) != NULL) { | ||
674 | g_Ctoc(path, copy); | ||
675 | pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; | ||
676 | } | ||
677 | pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; | ||
678 | return(copy == NULL ? GLOB_NOSPACE : 0); | ||
679 | } | ||
680 | |||
681 | |||
682 | /* | ||
683 | * pattern matching function for filenames. Each occurrence of the * | ||
684 | * pattern causes a recursion level. | ||
685 | */ | ||
686 | static int | ||
687 | match(name, pat, patend) | ||
688 | register Char *name, *pat, *patend; | ||
689 | { | ||
690 | int ok, negate_range; | ||
691 | Char c, k; | ||
692 | |||
693 | while (pat < patend) { | ||
694 | c = *pat++; | ||
695 | switch (c & M_MASK) { | ||
696 | case M_ALL: | ||
697 | if (pat == patend) | ||
698 | return(1); | ||
699 | do | ||
700 | if (match(name, pat, patend)) | ||
701 | return(1); | ||
702 | while (*name++ != EOS); | ||
703 | return(0); | ||
704 | case M_ONE: | ||
705 | if (*name++ == EOS) | ||
706 | return(0); | ||
707 | break; | ||
708 | case M_SET: | ||
709 | ok = 0; | ||
710 | if ((k = *name++) == EOS) | ||
711 | return(0); | ||
712 | if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) | ||
713 | ++pat; | ||
714 | while (((c = *pat++) & M_MASK) != M_END) | ||
715 | if ((*pat & M_MASK) == M_RNG) { | ||
716 | if (c <= k && k <= pat[1]) | ||
717 | ok = 1; | ||
718 | pat += 2; | ||
719 | } else if (c == k) | ||
720 | ok = 1; | ||
721 | if (ok == negate_range) | ||
722 | return(0); | ||
723 | break; | ||
724 | default: | ||
725 | if (*name++ != c) | ||
726 | return(0); | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | return(*name == EOS); | ||
731 | } | ||
732 | |||
733 | /* Free allocated data belonging to a glob_t structure. */ | ||
734 | void | ||
735 | globfree(pglob) | ||
736 | glob_t *pglob; | ||
737 | { | ||
738 | register int i; | ||
739 | register char **pp; | ||
740 | |||
741 | if (pglob->gl_pathv != NULL) { | ||
742 | pp = pglob->gl_pathv + pglob->gl_offs; | ||
743 | for (i = pglob->gl_pathc; i--; ++pp) | ||
744 | if (*pp) | ||
745 | free(*pp); | ||
746 | free(pglob->gl_pathv); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | static DIR * | ||
751 | g_opendir(str, pglob) | ||
752 | register Char *str; | ||
753 | glob_t *pglob; | ||
754 | { | ||
755 | char buf[MAXPATHLEN]; | ||
756 | |||
757 | if (!*str) | ||
758 | strcpy(buf, "."); | ||
759 | else | ||
760 | g_Ctoc(str, buf); | ||
761 | |||
762 | if (pglob->gl_flags & GLOB_ALTDIRFUNC) | ||
763 | return((*pglob->gl_opendir)(buf)); | ||
764 | |||
765 | return(opendir(buf)); | ||
766 | } | ||
767 | |||
768 | static int | ||
769 | g_lstat(fn, sb, pglob) | ||
770 | register Char *fn; | ||
771 | struct stat *sb; | ||
772 | glob_t *pglob; | ||
773 | { | ||
774 | char buf[MAXPATHLEN]; | ||
775 | |||
776 | g_Ctoc(fn, buf); | ||
777 | if (pglob->gl_flags & GLOB_ALTDIRFUNC) | ||
778 | return((*pglob->gl_lstat)(buf, sb)); | ||
779 | return(lstat(buf, sb)); | ||
780 | } | ||
781 | |||
782 | static int | ||
783 | g_stat(fn, sb, pglob) | ||
784 | register Char *fn; | ||
785 | struct stat *sb; | ||
786 | glob_t *pglob; | ||
787 | { | ||
788 | char buf[MAXPATHLEN]; | ||
789 | |||
790 | g_Ctoc(fn, buf); | ||
791 | if (pglob->gl_flags & GLOB_ALTDIRFUNC) | ||
792 | return((*pglob->gl_stat)(buf, sb)); | ||
793 | return(stat(buf, sb)); | ||
794 | } | ||
795 | |||
796 | static Char * | ||
797 | g_strchr(str, ch) | ||
798 | Char *str; | ||
799 | int ch; | ||
800 | { | ||
801 | do { | ||
802 | if (*str == ch) | ||
803 | return (str); | ||
804 | } while (*str++); | ||
805 | return (NULL); | ||
806 | } | ||
807 | |||
808 | #ifdef notdef | ||
809 | static Char * | ||
810 | g_strcat(dst, src) | ||
811 | Char *dst; | ||
812 | const Char* src; | ||
813 | { | ||
814 | Char *sdst = dst; | ||
815 | |||
816 | while (*dst++) | ||
817 | continue; | ||
818 | --dst; | ||
819 | while((*dst++ = *src++) != EOS) | ||
820 | continue; | ||
821 | |||
822 | return (sdst); | ||
823 | } | ||
824 | #endif | ||
825 | |||
826 | static void | ||
827 | g_Ctoc(str, buf) | ||
828 | register const Char *str; | ||
829 | char *buf; | ||
830 | { | ||
831 | register char *dc; | ||
832 | |||
833 | for (dc = buf; (*dc++ = *str++) != EOS;) | ||
834 | continue; | ||
835 | } | ||
836 | |||
837 | #ifdef DEBUG | ||
838 | static void | ||
839 | qprintf(str, s) | ||
840 | const char *str; | ||
841 | register Char *s; | ||
842 | { | ||
843 | register Char *p; | ||
844 | |||
845 | (void)printf("%s:\n", str); | ||
846 | for (p = s; *p; p++) | ||
847 | (void)printf("%c", CHAR(*p)); | ||
848 | (void)printf("\n"); | ||
849 | for (p = s; *p; p++) | ||
850 | (void)printf("%c", *p & M_PROTECT ? '"' : ' '); | ||
851 | (void)printf("\n"); | ||
852 | for (p = s; *p; p++) | ||
853 | (void)printf("%c", ismeta(*p) ? '_' : ' '); | ||
854 | (void)printf("\n"); | ||
855 | } | ||
856 | #endif | ||
857 | |||
858 | #endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) */ | ||
859 | |||
diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h new file mode 100644 index 000000000..392c63b67 --- /dev/null +++ b/openbsd-compat/glob.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* $OpenBSD: glob.h,v 1.4 1998/01/31 17:06:26 millert Exp $ */ | ||
2 | /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 1989, 1993 | ||
6 | * The Regents of the University of California. All rights reserved. | ||
7 | * | ||
8 | * This code is derived from software contributed to Berkeley by | ||
9 | * Guido van Rossum. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * 3. All advertising materials mentioning features or use of this software | ||
20 | * must display the following acknowledgement: | ||
21 | * This product includes software developed by the University of | ||
22 | * California, Berkeley and its contributors. | ||
23 | * 4. Neither the name of the University nor the names of its contributors | ||
24 | * may be used to endorse or promote products derived from this software | ||
25 | * without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
37 | * SUCH DAMAGE. | ||
38 | * | ||
39 | * @(#)glob.h 8.1 (Berkeley) 6/2/93 | ||
40 | */ | ||
41 | |||
42 | #if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) | ||
43 | |||
44 | #ifndef _GLOB_H_ | ||
45 | #define _GLOB_H_ | ||
46 | |||
47 | struct stat; | ||
48 | typedef struct { | ||
49 | int gl_pathc; /* Count of total paths so far. */ | ||
50 | int gl_matchc; /* Count of paths matching pattern. */ | ||
51 | int gl_offs; /* Reserved at beginning of gl_pathv. */ | ||
52 | int gl_flags; /* Copy of flags parameter to glob. */ | ||
53 | char **gl_pathv; /* List of paths matching pattern. */ | ||
54 | /* Copy of errfunc parameter to glob. */ | ||
55 | int (*gl_errfunc) __P((const char *, int)); | ||
56 | |||
57 | /* | ||
58 | * Alternate filesystem access methods for glob; replacement | ||
59 | * versions of closedir(3), readdir(3), opendir(3), stat(2) | ||
60 | * and lstat(2). | ||
61 | */ | ||
62 | void (*gl_closedir) __P((void *)); | ||
63 | struct dirent *(*gl_readdir) __P((void *)); | ||
64 | void *(*gl_opendir) __P((const char *)); | ||
65 | int (*gl_lstat) __P((const char *, struct stat *)); | ||
66 | int (*gl_stat) __P((const char *, struct stat *)); | ||
67 | } glob_t; | ||
68 | |||
69 | /* Flags */ | ||
70 | #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ | ||
71 | #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ | ||
72 | #define GLOB_ERR 0x0004 /* Return on error. */ | ||
73 | #define GLOB_MARK 0x0008 /* Append / to matching directories. */ | ||
74 | #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ | ||
75 | #define GLOB_NOSORT 0x0020 /* Don't sort. */ | ||
76 | |||
77 | #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ | ||
78 | #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ | ||
79 | #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ | ||
80 | #define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ | ||
81 | #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ | ||
82 | #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ | ||
83 | #define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ | ||
84 | |||
85 | /* Error values returned by glob(3) */ | ||
86 | #define GLOB_NOSPACE (-1) /* Malloc call failed. */ | ||
87 | #define GLOB_ABORTED (-2) /* Unignored error. */ | ||
88 | #define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ | ||
89 | #define GLOB_NOSYS (-4) /* Function not supported. */ | ||
90 | #define GLOB_ABEND GLOB_ABORTED | ||
91 | |||
92 | int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); | ||
93 | void globfree __P((glob_t *)); | ||
94 | |||
95 | #endif /* !_GLOB_H_ */ | ||
96 | |||
97 | #endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) */ | ||
98 | |||
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index a377b144d..972f2678d 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: openbsd-compat.h,v 1.3 2001/02/24 00:24:20 mouring Exp $ */ | 1 | /* $Id: openbsd-compat.h,v 1.4 2001/03/14 00:39:46 djm Exp $ */ |
2 | 2 | ||
3 | #ifndef _OPENBSD_H | 3 | #ifndef _OPENBSD_H |
4 | #define _OPENBSD_H | 4 | #define _OPENBSD_H |
@@ -24,6 +24,7 @@ | |||
24 | #include "vis.h" | 24 | #include "vis.h" |
25 | #include "setproctitle.h" | 25 | #include "setproctitle.h" |
26 | #include "getgrouplist.h" | 26 | #include "getgrouplist.h" |
27 | #include "glob.h" | ||
27 | 28 | ||
28 | /* Home grown routines */ | 29 | /* Home grown routines */ |
29 | #include "bsd-arc4random.h" | 30 | #include "bsd-arc4random.h" |
diff --git a/sftp-glob.c b/sftp-glob.c index 17f46a151..aec6d2734 100644 --- a/sftp-glob.c +++ b/sftp-glob.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: sftp-glob.c,v 1.1 2001/03/13 22:42:54 djm Exp $"); | 26 | RCSID("$OpenBSD: sftp-glob.c,v 1.1 2001/03/13 22:42:54 djm Exp $"); |
27 | 27 | ||
28 | #include <glob.h> | ||
29 | |||
30 | #include "ssh.h" | 28 | #include "ssh.h" |
31 | #include "buffer.h" | 29 | #include "buffer.h" |
32 | #include "bufaux.h" | 30 | #include "bufaux.h" |
diff --git a/sftp-int.c b/sftp-int.c index d350e398d..d1c505262 100644 --- a/sftp-int.c +++ b/sftp-int.c | |||
@@ -28,8 +28,6 @@ | |||
28 | #include "includes.h" | 28 | #include "includes.h" |
29 | RCSID("$OpenBSD: sftp-int.c,v 1.27 2001/03/13 22:42:54 djm Exp $"); | 29 | RCSID("$OpenBSD: sftp-int.c,v 1.27 2001/03/13 22:42:54 djm Exp $"); |
30 | 30 | ||
31 | #include <glob.h> | ||
32 | |||
33 | #include "buffer.h" | 31 | #include "buffer.h" |
34 | #include "xmalloc.h" | 32 | #include "xmalloc.h" |
35 | #include "log.h" | 33 | #include "log.h" |
@@ -20,7 +20,7 @@ | |||
20 | #include <stdarg.h> /* For va_list */ | 20 | #include <stdarg.h> /* For va_list */ |
21 | #include <syslog.h> /* For LOG_AUTH and friends */ | 21 | #include <syslog.h> /* For LOG_AUTH and friends */ |
22 | #include <sys/socket.h> /* For struct sockaddr_storage */ | 22 | #include <sys/socket.h> /* For struct sockaddr_storage */ |
23 | #include "fake-socket.h" /* For struct sockaddr_storage */ | 23 | #include "openbsd-compat/fake-socket.h" /* For struct sockaddr_storage */ |
24 | #ifdef HAVE_SYS_SELECT_H | 24 | #ifdef HAVE_SYS_SELECT_H |
25 | # include <sys/select.h> | 25 | # include <sys/select.h> |
26 | #endif | 26 | #endif |