OpenCoverage

glob.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/openbsd-compat/glob.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */-
2/*-
3 * Copyright (c) 1989, 1993-
4 * The Regents of the University of California. All rights reserved.-
5 *-
6 * This code is derived from software contributed to Berkeley by-
7 * Guido van Rossum.-
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. 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/* OPENBSD ORIGINAL: lib/libc/gen/glob.c */-
35-
36/*-
37 * glob(3) -- a superset of the one defined in POSIX 1003.2.-
38 *-
39 * The [!...] convention to negate a range is supported (SysV, Posix, ksh).-
40 *-
41 * Optional extra services, controlled by flags not defined by POSIX:-
42 *-
43 * GLOB_QUOTE:-
44 * Escaping convention: \ inhibits any special meaning the following-
45 * character might have (except \ at end of string is retained).-
46 * GLOB_MAGCHAR:-
47 * Set in gl_flags if pattern contained a globbing character.-
48 * GLOB_NOMAGIC:-
49 * Same as GLOB_NOCHECK, but it will only append pattern if it did-
50 * not contain any magic characters. [Used in csh style globbing]-
51 * GLOB_ALTDIRFUNC:-
52 * Use alternately specified directory access functions.-
53 * GLOB_TILDE:-
54 * expand ~user/foo to the /home/dir/of/user/foo-
55 * GLOB_BRACE:-
56 * expand {1,2}{a,b} to 1a 1b 2a 2b-
57 * gl_matchc:-
58 * Number of matches in the current invocation of glob.-
59 */-
60-
61#include "includes.h"-
62#include "glob.h"-
63-
64#include <sys/types.h>-
65#include <sys/stat.h>-
66-
67#include <dirent.h>-
68#include <ctype.h>-
69#include <errno.h>-
70#include <limits.h>-
71#include <pwd.h>-
72#include <stdlib.h>-
73#include <string.h>-
74#include <unistd.h>-
75-
76#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \-
77 !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \-
78 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \-
79 defined(BROKEN_GLOB)-
80-
81#include "charclass.h"-
82-
83#define DOLLAR '$'-
84#define DOT '.'-
85#define EOS '\0'-
86#define LBRACKET '['-
87#define NOT '!'-
88#define QUESTION '?'-
89#define QUOTE '\\'-
90#define RANGE '-'-
91#define RBRACKET ']'-
92#define SEP '/'-
93#define STAR '*'-
94#define TILDE '~'-
95#define UNDERSCORE '_'-
96#define LBRACE '{'-
97#define RBRACE '}'-
98#define SLASH '/'-
99#define COMMA ','-
100-
101#ifndef DEBUG-
102-
103#define M_QUOTE 0x8000-
104#define M_PROTECT 0x4000-
105#define M_MASK 0xffff-
106#define M_ASCII 0x00ff-
107-
108typedef u_short Char;-
109-
110#else-
111-
112#define M_QUOTE 0x80-
113#define M_PROTECT 0x40-
114#define M_MASK 0xff-
115#define M_ASCII 0x7f-
116-
117typedef char Char;-
118-
119#endif-
120-
121-
122#define CHAR(c) ((Char)((c)&M_ASCII))-
123#define META(c) ((Char)((c)|M_QUOTE))-
124#define M_ALL META('*')-
125#define M_END META(']')-
126#define M_NOT META('!')-
127#define M_ONE META('?')-
128#define M_RNG META('-')-
129#define M_SET META('[')-
130#define M_CLASS META(':')-
131#define ismeta(c) (((c)&M_QUOTE) != 0)-
132-
133#define GLOB_LIMIT_MALLOC 65536-
134#define GLOB_LIMIT_STAT 128-
135#define GLOB_LIMIT_READDIR 16384-
136-
137/* Limit of recursion during matching attempts. */-
138#define GLOB_LIMIT_RECUR 64-
139-
140struct glob_lim {-
141 size_t glim_malloc;-
142 size_t glim_stat;-
143 size_t glim_readdir;-
144};-
145-
146struct glob_path_stat {-
147 char *gps_path;-
148 struct stat *gps_stat;-
149};-
150-
151static int compare(const void *, const void *);-
152static int compare_gps(const void *, const void *);-
153static int g_Ctoc(const Char *, char *, u_int);-
154static int g_lstat(Char *, struct stat *, glob_t *);-
155static DIR *g_opendir(Char *, glob_t *);-
156static Char *g_strchr(const Char *, int);-
157static int g_strncmp(const Char *, const char *, size_t);-
158static int g_stat(Char *, struct stat *, glob_t *);-
159static int glob0(const Char *, glob_t *, struct glob_lim *);-
160static int glob1(Char *, Char *, glob_t *, struct glob_lim *);-
161static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,-
162 glob_t *, struct glob_lim *);-
163static int glob3(Char *, Char *, Char *, Char *, Char *,-
164 Char *, Char *, glob_t *, struct glob_lim *);-
165static int globextend(const Char *, glob_t *, struct glob_lim *,-
166 struct stat *);-
167static const Char *-
168 globtilde(const Char *, Char *, size_t, glob_t *);-
169static int globexp1(const Char *, glob_t *, struct glob_lim *);-
170static int globexp2(const Char *, const Char *, glob_t *,-
171 struct glob_lim *);-
172static int match(Char *, Char *, Char *, int);-
173#ifdef DEBUG-
174static void qprintf(const char *, Char *);-
175#endif-
176-
177int-
178glob(const char *pattern, int flags, int (*errfunc)(const char *, int),-
179 glob_t *pglob)-
180{-
181 const u_char *patnext;-
182 int c;-
183 Char *bufnext, *bufend, patbuf[MAXPATHLEN];-
184 struct glob_lim limit = { 0, 0, 0 };-
185-
186 if (strnlen(pattern, PATH_MAX) == PATH_MAX)
strnlen(patter...4096 ) == 4096Description
TRUEnever evaluated
FALSEnever evaluated
0
187 return(GLOB_NOMATCH);
never executed: return((-3));
0
188-
189 patnext = (u_char *) pattern;-
190 if (!(flags & GLOB_APPEND)) {
!(flags & 0x0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
191 pglob->gl_pathc = 0;-
192 pglob->gl_pathv = NULL;-
193 pglob->gl_statv = NULL;-
194 if (!(flags & GLOB_DOOFFS))
!(flags & 0x0002)Description
TRUEnever evaluated
FALSEnever evaluated
0
195 pglob->gl_offs = 0;
never executed: pglob->gl_offs = 0;
0
196 }
never executed: end of block
0
197 pglob->gl_flags = flags & ~GLOB_MAGCHAR;-
198 pglob->gl_errfunc = errfunc;-
199 pglob->gl_matchc = 0;-
200-
201 if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
pglob->gl_offs < 0Description
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_pathc < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
202 pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX ||
pglob->gl_offs >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_pathc >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
203 pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1)
pglob->gl_path...b->gl_offs - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
204 return GLOB_NOSPACE;
never executed: return (-1);
0
205-
206 bufnext = patbuf;-
207 bufend = bufnext + MAXPATHLEN - 1;-
208 if (flags & GLOB_NOESCAPE)
flags & 0x1000Description
TRUEnever evaluated
FALSEnever evaluated
0
209 while (bufnext < bufend && (c = *patnext++) != EOS)
bufnext < bufendDescription
TRUEnever evaluated
FALSEnever evaluated
(c = *patnext++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
210 *bufnext++ = c;
never executed: *bufnext++ = c;
0
211 else {-
212 /* Protect the quoted characters. */-
213 while (bufnext < bufend && (c = *patnext++) != EOS)
bufnext < bufendDescription
TRUEnever evaluated
FALSEnever evaluated
(c = *patnext++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
214 if (c == QUOTE) {
c == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
215 if ((c = *patnext++) == EOS) {
(c = *patnext++) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
216 c = QUOTE;-
217 --patnext;-
218 }
never executed: end of block
0
219 *bufnext++ = c | M_PROTECT;-
220 } else
never executed: end of block
0
221 *bufnext++ = c;
never executed: *bufnext++ = c;
0
222 }
never executed: end of block
0
223 *bufnext = EOS;-
224-
225 if (flags & GLOB_BRACE)
flags & 0x0080Description
TRUEnever evaluated
FALSEnever evaluated
0
226 return globexp1(patbuf, pglob, &limit);
never executed: return globexp1(patbuf, pglob, &limit);
0
227 else-
228 return glob0(patbuf, pglob, &limit);
never executed: return glob0(patbuf, pglob, &limit);
0
229}-
230-
231/*-
232 * Expand recursively a glob {} pattern. When there is no more expansion-
233 * invoke the standard globbing routine to glob the rest of the magic-
234 * characters-
235 */-
236static int-
237globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)-
238{-
239 const Char* ptr = pattern;-
240-
241 /* Protect a single {}, for find(1), like csh */-
242 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
pattern[0] == '{'Description
TRUEnever evaluated
FALSEnever evaluated
pattern[1] == '}'Description
TRUEnever evaluated
FALSEnever evaluated
pattern[2] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
243 return glob0(pattern, pglob, limitp);
never executed: return glob0(pattern, pglob, limitp);
0
244-
245 if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
(ptr = (const ...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
246 return globexp2(ptr, pattern, pglob, limitp);
never executed: return globexp2(ptr, pattern, pglob, limitp);
0
247-
248 return glob0(pattern, pglob, limitp);
never executed: return glob0(pattern, pglob, limitp);
0
249}-
250-
251-
252/*-
253 * Recursive brace globbing helper. Tries to expand a single brace.-
254 * If it succeeds then it invokes globexp1 with the new pattern.-
255 * If it fails then it tries to glob the rest of the pattern and returns.-
256 */-
257static int-
258globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,-
259 struct glob_lim *limitp)-
260{-
261 int i, rv;-
262 Char *lm, *ls;-
263 const Char *pe, *pm, *pl;-
264 Char patbuf[MAXPATHLEN];-
265-
266 /* copy part up to the brace */-
267 for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
pm != ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 ;
never executed: ;
0
269 *lm = EOS;-
270 ls = lm;-
271-
272 /* Find the balanced brace */-
273 for (i = 0, pe = ++ptr; *pe; pe++)
*peDescription
TRUEnever evaluated
FALSEnever evaluated
0
274 if (*pe == LBRACKET) {
*pe == '['Description
TRUEnever evaluated
FALSEnever evaluated
0
275 /* Ignore everything between [] */-
276 for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
*pe != ']'Description
TRUEnever evaluated
FALSEnever evaluated
*pe != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
277 ;
never executed: ;
0
278 if (*pe == EOS) {
*pe == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
279 /*-
280 * We could not find a matching RBRACKET.-
281 * Ignore and just look for RBRACE-
282 */-
283 pe = pm;-
284 }
never executed: end of block
0
285 } else if (*pe == LBRACE)
never executed: end of block
*pe == '{'Description
TRUEnever evaluated
FALSEnever evaluated
0
286 i++;
never executed: i++;
0
287 else if (*pe == RBRACE) {
*pe == '}'Description
TRUEnever evaluated
FALSEnever evaluated
0
288 if (i == 0)
i == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
289 break;
never executed: break;
0
290 i--;-
291 }
never executed: end of block
0
292-
293 /* Non matching braces; just glob the pattern */-
294 if (i != 0 || *pe == EOS)
i != 0Description
TRUEnever evaluated
FALSEnever evaluated
*pe == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
295 return glob0(patbuf, pglob, limitp);
never executed: return glob0(patbuf, pglob, limitp);
0
296-
297 for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
pm <= peDescription
TRUEnever evaluated
FALSEnever evaluated
0
298 switch (*pm) {-
299 case LBRACKET:
never executed: case '[':
0
300 /* Ignore everything between [] */-
301 for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
*pm != ']'Description
TRUEnever evaluated
FALSEnever evaluated
*pm != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
302 ;
never executed: ;
0
303 if (*pm == EOS) {
*pm == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
304 /*-
305 * We could not find a matching RBRACKET.-
306 * Ignore and just look for RBRACE-
307 */-
308 pm = pl;-
309 }
never executed: end of block
0
310 break;
never executed: break;
0
311-
312 case LBRACE:
never executed: case '{':
0
313 i++;-
314 break;
never executed: break;
0
315-
316 case RBRACE:
never executed: case '}':
0
317 if (i) {
iDescription
TRUEnever evaluated
FALSEnever evaluated
0
318 i--;-
319 break;
never executed: break;
0
320 }-
321 /* FALLTHROUGH */-
322 case COMMA:
code before this statement never executed: case ',':
never executed: case ',':
0
323 if (i && *pm == COMMA)
iDescription
TRUEnever evaluated
FALSEnever evaluated
*pm == ','Description
TRUEnever evaluated
FALSEnever evaluated
0
324 break;
never executed: break;
0
325 else {-
326 /* Append the current string */-
327 for (lm = ls; (pl < pm); *lm++ = *pl++)
(pl < pm)Description
TRUEnever evaluated
FALSEnever evaluated
0
328 ;
never executed: ;
0
329-
330 /*-
331 * Append the rest of the pattern after the-
332 * closing brace-
333 */-
334 for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
(*lm++ = *pl++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
335 ;
never executed: ;
0
336-
337 /* Expand the current pattern */-
338#ifdef DEBUG-
339 qprintf("globexp2:", patbuf);-
340#endif-
341 rv = globexp1(patbuf, pglob, limitp);-
342 if (rv && rv != GLOB_NOMATCH)
rvDescription
TRUEnever evaluated
FALSEnever evaluated
rv != (-3)Description
TRUEnever evaluated
FALSEnever evaluated
0
343 return rv;
never executed: return rv;
0
344-
345 /* move after the comma, to the next string */-
346 pl = pm + 1;-
347 }
never executed: end of block
0
348 break;
never executed: break;
0
349-
350 default:
never executed: default:
0
351 break;
never executed: break;
0
352 }-
353 }-
354 return 0;
never executed: return 0;
0
355}-
356-
357-
358-
359/*-
360 * expand tilde from the passwd file.-
361 */-
362static const Char *-
363globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)-
364{-
365 struct passwd *pwd;-
366 char *h;-
367 const Char *p;-
368 Char *b, *eb;-
369-
370 if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
*pattern != '~'Description
TRUEnever evaluated
FALSEnever evaluated
!(pglob->gl_flags & 0x0800)Description
TRUEnever evaluated
FALSEnever evaluated
0
371 return pattern;
never executed: return pattern;
0
372-
373 /* Copy up to the end of the string or / */-
374 eb = &patbuf[patbuf_len - 1];-
375 for (p = pattern + 1, h = (char *) patbuf;-
376 h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
h < (char *)ebDescription
TRUEnever evaluated
FALSEnever evaluated
*pDescription
TRUEnever evaluated
FALSEnever evaluated
*p != '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
377 ;
never executed: ;
0
378-
379 *h = EOS;-
380-
381#if 0-
382 if (h == (char *)eb)-
383 return what;-
384#endif-
385-
386 if (((char *) patbuf)[0] == EOS) {
((char *) patbuf)[0] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
387 /*-
388 * handle a plain ~ or ~/ by expanding $HOME-
389 * first and then trying the password file-
390 */-
391#if 0-
392 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {-
393#endif-
394 if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) {
(getuid() != geteuid())Description
TRUEnever evaluated
FALSEnever evaluated
(h = getenv("H...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
395 if ((pwd = getpwuid(getuid())) == NULL)
(pwd = getpwui...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
396 return pattern;
never executed: return pattern;
0
397 else-
398 h = pwd->pw_dir;
never executed: h = pwd->pw_dir;
0
399 }-
400 } else {
never executed: end of block
0
401 /*-
402 * Expand a ~user-
403 */-
404 if ((pwd = getpwnam((char*) patbuf)) == NULL)
(pwd = getpwna...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
405 return pattern;
never executed: return pattern;
0
406 else-
407 h = pwd->pw_dir;
never executed: h = pwd->pw_dir;
0
408 }-
409-
410 /* Copy the home directory */-
411 for (b = patbuf; b < eb && *h; *b++ = *h++)
b < ebDescription
TRUEnever evaluated
FALSEnever evaluated
*hDescription
TRUEnever evaluated
FALSEnever evaluated
0
412 ;
never executed: ;
0
413-
414 /* Append the rest of the pattern */-
415 while (b < eb && (*b++ = *p++) != EOS)
b < ebDescription
TRUEnever evaluated
FALSEnever evaluated
(*b++ = *p++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
416 ;
never executed: ;
0
417 *b = EOS;-
418-
419 return patbuf;
never executed: return patbuf;
0
420}-
421-
422static int-
423g_strncmp(const Char *s1, const char *s2, size_t n)-
424{-
425 int rv = 0;-
426-
427 while (n--) {
n--Description
TRUEnever evaluated
FALSEnever evaluated
0
428 rv = *(Char *)s1 - *(const unsigned char *)s2++;-
429 if (rv)
rvDescription
TRUEnever evaluated
FALSEnever evaluated
0
430 break;
never executed: break;
0
431 if (*s1++ == '\0')
*s1++ == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
432 break;
never executed: break;
0
433 }
never executed: end of block
0
434 return rv;
never executed: return rv;
0
435}-
436-
437static int-
438g_charclass(const Char **patternp, Char **bufnextp)-
439{-
440 const Char *pattern = *patternp + 1;-
441 Char *bufnext = *bufnextp;-
442 const Char *colon;-
443 struct cclass *cc;-
444 size_t len;-
445-
446 if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
(colon = g_str...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
colon[1] != ']'Description
TRUEnever evaluated
FALSEnever evaluated
0
447 return 1; /* not a character class */
never executed: return 1;
0
448-
449 len = (size_t)(colon - pattern);-
450 for (cc = cclasses; cc->name != NULL; cc++) {
cc->name != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
451 if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
!g_strncmp(pat...cc->name, len)Description
TRUEnever evaluated
FALSEnever evaluated
cc->name[len] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
452 break;
never executed: break;
0
453 }
never executed: end of block
0
454 if (cc->name == NULL)
cc->name == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
455 return -1; /* invalid character class */
never executed: return -1;
0
456 *bufnext++ = M_CLASS;-
457 *bufnext++ = (Char)(cc - &cclasses[0]);-
458 *bufnextp = bufnext;-
459 *patternp += len + 3;-
460-
461 return 0;
never executed: return 0;
0
462}-
463-
464/*-
465 * The main glob() routine: compiles the pattern (optionally processing-
466 * quotes), calls glob1() to do the real pattern matching, and finally-
467 * sorts the list (unless unsorted operation is requested). Returns 0-
468 * if things went well, nonzero if errors occurred. It is not an error-
469 * to find no matches.-
470 */-
471static int-
472glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)-
473{-
474 const Char *qpatnext;-
475 int c, err, oldpathc;-
476 Char *bufnext, patbuf[MAXPATHLEN];-
477-
478 qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);-
479 oldpathc = pglob->gl_pathc;-
480 bufnext = patbuf;-
481-
482 /* We don't need to check for buffer overflow any more. */-
483 while ((c = *qpatnext++) != EOS) {
(c = *qpatnext++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
484 switch (c) {-
485 case LBRACKET:
never executed: case '[':
0
486 c = *qpatnext;-
487 if (c == NOT)
c == '!'Description
TRUEnever evaluated
FALSEnever evaluated
0
488 ++qpatnext;
never executed: ++qpatnext;
0
489 if (*qpatnext == EOS ||
*qpatnext == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
490 g_strchr(qpatnext+1, RBRACKET) == NULL) {
g_strchr(qpatn...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
491 *bufnext++ = LBRACKET;-
492 if (c == NOT)
c == '!'Description
TRUEnever evaluated
FALSEnever evaluated
0
493 --qpatnext;
never executed: --qpatnext;
0
494 break;
never executed: break;
0
495 }-
496 *bufnext++ = M_SET;-
497 if (c == NOT)
c == '!'Description
TRUEnever evaluated
FALSEnever evaluated
0
498 *bufnext++ = M_NOT;
never executed: *bufnext++ = ((Char)(('!')|0x8000));
0
499 c = *qpatnext++;-
500 do {-
501 if (c == LBRACKET && *qpatnext == ':') {
c == '['Description
TRUEnever evaluated
FALSEnever evaluated
*qpatnext == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
502 do {-
503 err = g_charclass(&qpatnext,-
504 &bufnext);-
505 if (err)
errDescription
TRUEnever evaluated
FALSEnever evaluated
0
506 break;
never executed: break;
0
507 c = *qpatnext++;-
508 } while (c == LBRACKET && *qpatnext == ':');
never executed: end of block
c == '['Description
TRUEnever evaluated
FALSEnever evaluated
*qpatnext == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
509 if (err == -1 &&
err == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
510 !(pglob->gl_flags & GLOB_NOCHECK))
!(pglob->gl_flags & 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
511 return GLOB_NOMATCH;
never executed: return (-3);
0
512 if (c == RBRACKET)
c == ']'Description
TRUEnever evaluated
FALSEnever evaluated
0
513 break;
never executed: break;
0
514 }
never executed: end of block
0
515 *bufnext++ = CHAR(c);-
516 if (*qpatnext == RANGE &&
*qpatnext == '-'Description
TRUEnever evaluated
FALSEnever evaluated
0
517 (c = qpatnext[1]) != RBRACKET) {
(c = qpatnext[1]) != ']'Description
TRUEnever evaluated
FALSEnever evaluated
0
518 *bufnext++ = M_RNG;-
519 *bufnext++ = CHAR(c);-
520 qpatnext += 2;-
521 }
never executed: end of block
0
522 } while ((c = *qpatnext++) != RBRACKET);
never executed: end of block
(c = *qpatnext++) != ']'Description
TRUEnever evaluated
FALSEnever evaluated
0
523 pglob->gl_flags |= GLOB_MAGCHAR;-
524 *bufnext++ = M_END;-
525 break;
never executed: break;
0
526 case QUESTION:
never executed: case '?':
0
527 pglob->gl_flags |= GLOB_MAGCHAR;-
528 *bufnext++ = M_ONE;-
529 break;
never executed: break;
0
530 case STAR:
never executed: case '*':
0
531 pglob->gl_flags |= GLOB_MAGCHAR;-
532 /* collapse adjacent stars to one,-
533 * to avoid exponential behavior-
534 */-
535 if (bufnext == patbuf || bufnext[-1] != M_ALL)
bufnext == patbufDescription
TRUEnever evaluated
FALSEnever evaluated
bufnext[-1] !=...('*')|0x8000))Description
TRUEnever evaluated
FALSEnever evaluated
0
536 *bufnext++ = M_ALL;
never executed: *bufnext++ = ((Char)(('*')|0x8000));
0
537 break;
never executed: break;
0
538 default:
never executed: default:
0
539 *bufnext++ = CHAR(c);-
540 break;
never executed: break;
0
541 }-
542 }-
543 *bufnext = EOS;-
544#ifdef DEBUG-
545 qprintf("glob0:", patbuf);-
546#endif-
547-
548 if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
(err = glob1(p... limitp)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
549 return(err);
never executed: return(err);
0
550-
551 /*-
552 * If there was no match we are going to append the pattern-
553 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified-
554 * and the pattern did not contain any magic characters-
555 * GLOB_NOMAGIC is there just for compatibility with csh.-
556 */-
557 if (pglob->gl_pathc == oldpathc) {
pglob->gl_pathc == oldpathcDescription
TRUEnever evaluated
FALSEnever evaluated
0
558 if ((pglob->gl_flags & GLOB_NOCHECK) ||
(pglob->gl_flags & 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
559 ((pglob->gl_flags & GLOB_NOMAGIC) &&
(pglob->gl_flags & 0x0200)Description
TRUEnever evaluated
FALSEnever evaluated
0
560 !(pglob->gl_flags & GLOB_MAGCHAR)))
!(pglob->gl_flags & 0x0100)Description
TRUEnever evaluated
FALSEnever evaluated
0
561 return(globextend(pattern, pglob, limitp, NULL));
never executed: return(globextend(pattern, pglob, limitp, ((void *)0) ));
0
562 else-
563 return(GLOB_NOMATCH);
never executed: return((-3));
0
564 }-
565 if (!(pglob->gl_flags & GLOB_NOSORT)) {
!(pglob->gl_flags & 0x0020)Description
TRUEnever evaluated
FALSEnever evaluated
0
566 if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
(pglob->gl_flags & 0x4000)Description
TRUEnever evaluated
FALSEnever evaluated
0
567 /* Keep the paths and stat info synced during sort */-
568 struct glob_path_stat *path_stat;-
569 int i;-
570 int n = pglob->gl_pathc - oldpathc;-
571 int o = pglob->gl_offs + oldpathc;-
572-
573 if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL)
(path_stat = c...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
574 return GLOB_NOSPACE;
never executed: return (-1);
0
575 for (i = 0; i < n; i++) {
i < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
576 path_stat[i].gps_path = pglob->gl_pathv[o + i];-
577 path_stat[i].gps_stat = pglob->gl_statv[o + i];-
578 }
never executed: end of block
0
579 qsort(path_stat, n, sizeof(*path_stat), compare_gps);-
580 for (i = 0; i < n; i++) {
i < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
581 pglob->gl_pathv[o + i] = path_stat[i].gps_path;-
582 pglob->gl_statv[o + i] = path_stat[i].gps_stat;-
583 }
never executed: end of block
0
584 free(path_stat);-
585 } else {
never executed: end of block
0
586 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,-
587 pglob->gl_pathc - oldpathc, sizeof(char *),-
588 compare);-
589 }
never executed: end of block
0
590 }-
591 return(0);
never executed: return(0);
0
592}-
593-
594static int-
595compare(const void *p, const void *q)-
596{-
597 return(strcmp(*(char **)p, *(char **)q));
never executed: return( __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( *(char **)p ) && __builtin_constant_p ( *(char **)q ) && (__s1_len = __builtin_strlen ( *(char **)p ), __s2_len = __builtin_strlen ( *(char **)q ), (!((size_t)(const void *)(( *(c...ned char *) (const char *) ( *(char **)q ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( *(char **)q ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( *(char **)p , *(char **)q )))); }) );
never executed: __result = (((const unsigned char *) (const char *) ( *(char **)p ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( *(char **)q ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
598}-
599-
600static int-
601compare_gps(const void *_p, const void *_q)-
602{-
603 const struct glob_path_stat *p = (const struct glob_path_stat *)_p;-
604 const struct glob_path_stat *q = (const struct glob_path_stat *)_q;-
605-
606 return(strcmp(p->gps_path, q->gps_path));
never executed: return( __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( p->gps_path ) && __builtin_constant_p ( q->gps_path ) && (__s1_len = __builtin_strlen ( p->gps_path ), __s2_len = __builtin_strlen ( q->gps_path ), (!((size_t)(const void *)(( p->...ned char *) (const char *) ( q->gps_path ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( q->gps_path ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( p->gps_path , q->gps_path )))); }) );
never executed: __result = (((const unsigned char *) (const char *) ( p->gps_path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( q->gps_path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
607}-
608-
609static int-
610glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)-
611{-
612 Char pathbuf[MAXPATHLEN];-
613-
614 /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */-
615 if (*pattern == EOS)
*pattern == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
616 return(0);
never executed: return(0);
0
617 return(glob2(pathbuf, pathbuf+MAXPATHLEN-1,
never executed: return(glob2(pathbuf, pathbuf+ 4096 -1, pathbuf, pathbuf+ 4096 -1, pattern, pattern_last, pglob, limitp));
0
618 pathbuf, pathbuf+MAXPATHLEN-1,
never executed: return(glob2(pathbuf, pathbuf+ 4096 -1, pathbuf, pathbuf+ 4096 -1, pattern, pattern_last, pglob, limitp));
0
619 pattern, pattern_last, pglob, limitp));
never executed: return(glob2(pathbuf, pathbuf+ 4096 -1, pathbuf, pathbuf+ 4096 -1, pattern, pattern_last, pglob, limitp));
0
620}-
621-
622/*-
623 * The functions glob2 and glob3 are mutually recursive; there is one level-
624 * of recursion for each segment in the pattern that contains one or more-
625 * meta characters.-
626 */-
627static int-
628glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,-
629 Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)-
630{-
631 struct stat sb;-
632 Char *p, *q;-
633 int anymeta;-
634-
635 /*-
636 * Loop over pattern segments until end of pattern or until-
637 * segment with meta character found.-
638 */-
639 for (anymeta = 0;;) {-
640 if (*pattern == EOS) { /* End of pattern? */
*pattern == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
641 *pathend = EOS;-
642 if (g_lstat(pathbuf, &sb, pglob))
g_lstat(pathbuf, &sb, pglob)Description
TRUEnever evaluated
FALSEnever evaluated
0
643 return(0);
never executed: return(0);
0
644-
645 if ((pglob->gl_flags & GLOB_LIMIT) &&
(pglob->gl_flags & 0x2000)Description
TRUEnever evaluated
FALSEnever evaluated
0
646 limitp->glim_stat++ >= GLOB_LIMIT_STAT) {
limitp->glim_stat++ >= 128Description
TRUEnever evaluated
FALSEnever evaluated
0
647 errno = 0;-
648 *pathend++ = SEP;-
649 *pathend = EOS;-
650 return(GLOB_NOSPACE);
never executed: return((-1));
0
651 }-
652-
653 if (((pglob->gl_flags & GLOB_MARK) &&
(pglob->gl_flags & 0x0008)Description
TRUEnever evaluated
FALSEnever evaluated
0
654 pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
pathend[-1] != '/'Description
TRUEnever evaluated
FALSEnever evaluated
(((( sb.st_mod... == (0040000))Description
TRUEnever evaluated
FALSEnever evaluated
0
655 (S_ISLNK(sb.st_mode) &&
(((( sb.st_mod... == (0120000))Description
TRUEnever evaluated
FALSEnever evaluated
0
656 (g_stat(pathbuf, &sb, pglob) == 0) &&
(g_stat(pathbu..., pglob) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
657 S_ISDIR(sb.st_mode)))) {
(((( sb.st_mod... == (0040000))Description
TRUEnever evaluated
FALSEnever evaluated
0
658 if (pathend+1 > pathend_last)
pathend+1 > pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
659 return (1);
never executed: return (1);
0
660 *pathend++ = SEP;-
661 *pathend = EOS;-
662 }
never executed: end of block
0
663 ++pglob->gl_matchc;-
664 return(globextend(pathbuf, pglob, limitp, &sb));
never executed: return(globextend(pathbuf, pglob, limitp, &sb));
0
665 }-
666-
667 /* Find end of next segment, copy tentatively to pathend. */-
668 q = pathend;-
669 p = pattern;-
670 while (*p != EOS && *p != SEP) {
*p != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
*p != '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
671 if (ismeta(*p))
(((*p)&0x8000) != 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
672 anymeta = 1;
never executed: anymeta = 1;
0
673 if (q+1 > pathend_last)
q+1 > pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
674 return (1);
never executed: return (1);
0
675 *q++ = *p++;-
676 }
never executed: end of block
0
677-
678 if (!anymeta) { /* No expansion, do next segment. */
!anymetaDescription
TRUEnever evaluated
FALSEnever evaluated
0
679 pathend = q;-
680 pattern = p;-
681 while (*pattern == SEP) {
*pattern == '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
682 if (pathend+1 > pathend_last)
pathend+1 > pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
683 return (1);
never executed: return (1);
0
684 *pathend++ = *pattern++;-
685 }
never executed: end of block
0
686 } else
never executed: end of block
0
687 /* Need expansion, recurse. */-
688 return(glob3(pathbuf, pathbuf_last, pathend,
never executed: return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp));
0
689 pathend_last, pattern, p, pattern_last,
never executed: return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp));
0
690 pglob, limitp));
never executed: return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp));
0
691 }-
692 /* NOTREACHED */-
693}
never executed: end of block
0
694-
695static int-
696glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,-
697 Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,-
698 struct glob_lim *limitp)-
699{-
700 struct dirent *dp;-
701 DIR *dirp;-
702 int err;-
703 char buf[MAXPATHLEN];-
704-
705 /*-
706 * The readdirfunc declaration can't be prototyped, because it is-
707 * assigned, below, to two functions which are prototyped in glob.h-
708 * and dirent.h as taking pointers to differently typed opaque-
709 * structures.-
710 */-
711 struct dirent *(*readdirfunc)(void *);-
712-
713 if (pathend > pathend_last)
pathend > pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
714 return (1);
never executed: return (1);
0
715 *pathend = EOS;-
716 errno = 0;-
717-
718 if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
(dirp = g_open...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
719 /* TODO: don't call for ENOENT or ENOTDIR? */-
720 if (pglob->gl_errfunc) {
pglob->gl_errfuncDescription
TRUEnever evaluated
FALSEnever evaluated
0
721 if (g_Ctoc(pathbuf, buf, sizeof(buf)))
g_Ctoc(pathbuf..., sizeof(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
722 return(GLOB_ABORTED);
never executed: return((-2));
0
723 if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_errf...location ()) )Description
TRUEnever evaluated
FALSEnever evaluated
0
724 pglob->gl_flags & GLOB_ERR)
pglob->gl_flags & 0x0004Description
TRUEnever evaluated
FALSEnever evaluated
0
725 return(GLOB_ABORTED);
never executed: return((-2));
0
726 }
never executed: end of block
0
727 return(0);
never executed: return(0);
0
728 }-
729-
730 err = 0;-
731-
732 /* Search directory for matching names. */-
733 if (pglob->gl_flags & GLOB_ALTDIRFUNC)
pglob->gl_flags & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
734 readdirfunc = pglob->gl_readdir;
never executed: readdirfunc = pglob->gl_readdir;
0
735 else-
736 readdirfunc = (struct dirent *(*)(void *))readdir;
never executed: readdirfunc = (struct dirent *(*)(void *))readdir;
0
737 while ((dp = (*readdirfunc)(dirp))) {
(dp = (*readdirfunc)(dirp))Description
TRUEnever evaluated
FALSEnever evaluated
0
738 u_char *sc;-
739 Char *dc;-
740-
741 if ((pglob->gl_flags & GLOB_LIMIT) &&
(pglob->gl_flags & 0x2000)Description
TRUEnever evaluated
FALSEnever evaluated
0
742 limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) {
limitp->glim_r...dir++ >= 16384Description
TRUEnever evaluated
FALSEnever evaluated
0
743 errno = 0;-
744 *pathend++ = SEP;-
745 *pathend = EOS;-
746 err = GLOB_NOSPACE;-
747 break;
never executed: break;
0
748 }-
749-
750 /* Initial DOT must be matched literally. */-
751 if (dp->d_name[0] == DOT && *pattern != DOT)
dp->d_name[0] == '.'Description
TRUEnever evaluated
FALSEnever evaluated
*pattern != '.'Description
TRUEnever evaluated
FALSEnever evaluated
0
752 continue;
never executed: continue;
0
753 dc = pathend;-
754 sc = (u_char *) dp->d_name;-
755 while (dc < pathend_last && (*dc++ = *sc++) != EOS)
dc < pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
(*dc++ = *sc++) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
756 ;
never executed: ;
0
757 if (dc >= pathend_last) {
dc >= pathend_lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
758 *dc = EOS;-
759 err = 1;-
760 break;
never executed: break;
0
761 }-
762-
763 if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) {
!match(pathend...stpattern, 64)Description
TRUEnever evaluated
FALSEnever evaluated
0
764 *pathend = EOS;-
765 continue;
never executed: continue;
0
766 }-
767 err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,-
768 restpattern, restpattern_last, pglob, limitp);-
769 if (err)
errDescription
TRUEnever evaluated
FALSEnever evaluated
0
770 break;
never executed: break;
0
771 }
never executed: end of block
0
772-
773 if (pglob->gl_flags & GLOB_ALTDIRFUNC)
pglob->gl_flags & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
774 (*pglob->gl_closedir)(dirp);
never executed: (*pglob->gl_closedir)(dirp);
0
775 else-
776 closedir(dirp);
never executed: closedir(dirp);
0
777 return(err);
never executed: return(err);
0
778}-
779-
780-
781/*-
782 * Extend the gl_pathv member of a glob_t structure to accommodate a new item,-
783 * add the new item, and update gl_pathc.-
784 *-
785 * This assumes the BSD realloc, which only copies the block when its size-
786 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic-
787 * behavior.-
788 *-
789 * Return 0 if new item added, error code if memory couldn't be allocated.-
790 *-
791 * Invariant of the glob_t structure:-
792 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and-
793 * gl_pathv points to (gl_offs + gl_pathc + 1) items.-
794 */-
795static int-
796globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,-
797 struct stat *sb)-
798{-
799 char **pathv;-
800 ssize_t i;-
801 size_t newn, len;-
802 char *copy = NULL;-
803 const Char *p;-
804 struct stat **statv;-
805-
806 newn = 2 + pglob->gl_pathc + pglob->gl_offs;-
807 if (pglob->gl_offs >= INT_MAX ||
pglob->gl_offs >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
808 pglob->gl_pathc >= INT_MAX ||
pglob->gl_pathc >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
809 newn >= INT_MAX ||
newn >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
810 SIZE_MAX / sizeof(*pathv) <= newn ||
(1844674407370...pathv) <= newnDescription
TRUEnever evaluated
FALSEnever evaluated
0
811 SIZE_MAX / sizeof(*statv) <= newn) {
(1844674407370...statv) <= newnDescription
TRUEnever evaluated
FALSEnever evaluated
0
812 nospace:-
813 for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
i < (ssize_t)(newn - 2)Description
TRUEnever evaluated
FALSEnever evaluated
0
814 if (pglob->gl_pathv && pglob->gl_pathv[i])
pglob->gl_pathvDescription
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
815 free(pglob->gl_pathv[i]);
never executed: free(pglob->gl_pathv[i]);
0
816 if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
(pglob->gl_fla...& 0x4000) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
817 pglob->gl_pathv && pglob->gl_pathv[i])
pglob->gl_pathvDescription
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
818 free(pglob->gl_statv[i]);
never executed: free(pglob->gl_statv[i]);
0
819 }
never executed: end of block
0
820 if (pglob->gl_pathv) {
pglob->gl_pathvDescription
TRUEnever evaluated
FALSEnever evaluated
0
821 free(pglob->gl_pathv);-
822 pglob->gl_pathv = NULL;-
823 }
never executed: end of block
0
824 if (pglob->gl_statv) {
pglob->gl_statvDescription
TRUEnever evaluated
FALSEnever evaluated
0
825 free(pglob->gl_statv);-
826 pglob->gl_statv = NULL;-
827 }
never executed: end of block
0
828 return(GLOB_NOSPACE);
never executed: return((-1));
0
829 }-
830-
831 pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv));-
832 if (pathv == NULL)
pathv == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
833 goto nospace;
never executed: goto nospace;
0
834 if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
pglob->gl_pathv == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_offs > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
835 /* first time around -- clear initial gl_offs items */-
836 pathv += pglob->gl_offs;-
837 for (i = pglob->gl_offs; --i >= 0; )
--i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
838 *--pathv = NULL;
never executed: *--pathv = ((void *)0) ;
0
839 }
never executed: end of block
0
840 pglob->gl_pathv = pathv;-
841-
842 if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) {
(pglob->gl_fla...& 0x4000) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
843 statv = realloc(pglob->gl_statv, newn * sizeof(*statv));-
844 if (statv == NULL)
statv == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
845 goto nospace;
never executed: goto nospace;
0
846 if (pglob->gl_statv == NULL && pglob->gl_offs > 0) {
pglob->gl_statv == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
pglob->gl_offs > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
847 /* first time around -- clear initial gl_offs items */-
848 statv += pglob->gl_offs;-
849 for (i = pglob->gl_offs; --i >= 0; )
--i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
850 *--statv = NULL;
never executed: *--statv = ((void *)0) ;
0
851 }
never executed: end of block
0
852 pglob->gl_statv = statv;-
853 if (sb == NULL)
sb == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
854 statv[pglob->gl_offs + pglob->gl_pathc] = NULL;
never executed: statv[pglob->gl_offs + pglob->gl_pathc] = ((void *)0) ;
0
855 else {-
856 limitp->glim_malloc += sizeof(**statv);-
857 if ((pglob->gl_flags & GLOB_LIMIT) &&
(pglob->gl_flags & 0x2000)Description
TRUEnever evaluated
FALSEnever evaluated
0
858 limitp->glim_malloc >= GLOB_LIMIT_MALLOC) {
limitp->glim_malloc >= 65536Description
TRUEnever evaluated
FALSEnever evaluated
0
859 errno = 0;-
860 return(GLOB_NOSPACE);
never executed: return((-1));
0
861 }-
862 if ((statv[pglob->gl_offs + pglob->gl_pathc] =
(statv[pglob->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
863 malloc(sizeof(**statv))) == NULL)
(statv[pglob->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
864 goto copy_error;
never executed: goto copy_error;
0
865 memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb,-
866 sizeof(*sb));-
867 }
never executed: end of block
0
868 statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL;-
869 }
never executed: end of block
0
870-
871 for (p = path; *p++;)
*p++Description
TRUEnever evaluated
FALSEnever evaluated
0
872 ;
never executed: ;
0
873 len = (size_t)(p - path);-
874 limitp->glim_malloc += len;-
875 if ((copy = malloc(len)) != NULL) {
(copy = malloc...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
876 if (g_Ctoc(path, copy, len)) {
g_Ctoc(path, copy, len)Description
TRUEnever evaluated
FALSEnever evaluated
0
877 free(copy);-
878 return(GLOB_NOSPACE);
never executed: return((-1));
0
879 }-
880 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;-
881 }
never executed: end of block
0
882 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;-
883-
884 if ((pglob->gl_flags & GLOB_LIMIT) &&
(pglob->gl_flags & 0x2000)Description
TRUEnever evaluated
FALSEnever evaluated
0
885 (newn * sizeof(*pathv)) + limitp->glim_malloc >
(newn * sizeof...malloc > 65536Description
TRUEnever evaluated
FALSEnever evaluated
0
886 GLOB_LIMIT_MALLOC) {
(newn * sizeof...malloc > 65536Description
TRUEnever evaluated
FALSEnever evaluated
0
887 errno = 0;-
888 return(GLOB_NOSPACE);
never executed: return((-1));
0
889 }-
890 copy_error:
code before this statement never executed: copy_error:
0
891 return(copy == NULL ? GLOB_NOSPACE : 0);
never executed: return(copy == ((void *)0) ? (-1) : 0);
copy == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
892}-
893-
894-
895/*-
896 * pattern matching function for filenames. Each occurrence of the *-
897 * pattern causes a recursion level.-
898 */-
899static int-
900match(Char *name, Char *pat, Char *patend, int recur)-
901{-
902 int ok, negate_range;-
903 Char c, k;-
904-
905 if (recur-- == 0)
recur-- == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
906 return(GLOB_NOSPACE);
never executed: return((-1));
0
907-
908 while (pat < patend) {
pat < patendDescription
TRUEnever evaluated
FALSEnever evaluated
0
909 c = *pat++;-
910 switch (c & M_MASK) {-
911 case M_ALL:
never executed: case ((Char)(('*')|0x8000)):
0
912 while (pat < patend && (*pat & M_MASK) == M_ALL)
pat < patendDescription
TRUEnever evaluated
FALSEnever evaluated
(*pat & 0xffff...('*')|0x8000))Description
TRUEnever evaluated
FALSEnever evaluated
0
913 pat++; /* eat consecutive '*' */
never executed: pat++;
0
914 if (pat == patend)
pat == patendDescription
TRUEnever evaluated
FALSEnever evaluated
0
915 return(1);
never executed: return(1);
0
916 do {-
917 if (match(name, pat, patend, recur))
match(name, pa...patend, recur)Description
TRUEnever evaluated
FALSEnever evaluated
0
918 return(1);
never executed: return(1);
0
919 } while (*name++ != EOS);
never executed: end of block
*name++ != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
920 return(0);
never executed: return(0);
0
921 case M_ONE:
never executed: case ((Char)(('?')|0x8000)):
0
922 if (*name++ == EOS)
*name++ == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
923 return(0);
never executed: return(0);
0
924 break;
never executed: break;
0
925 case M_SET:
never executed: case ((Char)(('[')|0x8000)):
0
926 ok = 0;-
927 if ((k = *name++) == EOS)
(k = *name++) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
928 return(0);
never executed: return(0);
0
929 if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
(negate_range ...00)))) != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
930 ++pat;
never executed: ++pat;
0
931 while (((c = *pat++) & M_MASK) != M_END) {
((c = *pat++) ...(']')|0x8000))Description
TRUEnever evaluated
FALSEnever evaluated
0
932 if ((c & M_MASK) == M_CLASS) {
(c & 0xffff) =...(':')|0x8000))Description
TRUEnever evaluated
FALSEnever evaluated
0
933 Char idx = *pat & M_MASK;-
934 if (idx < NCCLASSES &&
idx < (sizeof(...asses[0]) - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
935 cclasses[idx].isctype(k))
cclasses[idx].isctype(k)Description
TRUEnever evaluated
FALSEnever evaluated
0
936 ok = 1;
never executed: ok = 1;
0
937 ++pat;-
938 }
never executed: end of block
0
939 if ((*pat & M_MASK) == M_RNG) {
(*pat & 0xffff...('-')|0x8000))Description
TRUEnever evaluated
FALSEnever evaluated
0
940 if (c <= k && k <= pat[1])
c <= kDescription
TRUEnever evaluated
FALSEnever evaluated
k <= pat[1]Description
TRUEnever evaluated
FALSEnever evaluated
0
941 ok = 1;
never executed: ok = 1;
0
942 pat += 2;-
943 } else if (c == k)
never executed: end of block
c == kDescription
TRUEnever evaluated
FALSEnever evaluated
0
944 ok = 1;
never executed: ok = 1;
0
945 }
never executed: end of block
0
946 if (ok == negate_range)
ok == negate_rangeDescription
TRUEnever evaluated
FALSEnever evaluated
0
947 return(0);
never executed: return(0);
0
948 break;
never executed: break;
0
949 default:
never executed: default:
0
950 if (*name++ != c)
*name++ != cDescription
TRUEnever evaluated
FALSEnever evaluated
0
951 return(0);
never executed: return(0);
0
952 break;
never executed: break;
0
953 }-
954 }-
955 return(*name == EOS);
never executed: return(*name == '\0');
0
956}-
957-
958/* Free allocated data belonging to a glob_t structure. */-
959void-
960globfree(glob_t *pglob)-
961{-
962 int i;-
963 char **pp;-
964-
965 if (pglob->gl_pathv != NULL) {
pglob->gl_pathv != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
966 pp = pglob->gl_pathv + pglob->gl_offs;-
967 for (i = pglob->gl_pathc; i--; ++pp)
i--Description
TRUEnever evaluated
FALSEnever evaluated
0
968 if (*pp)
*ppDescription
TRUEnever evaluated
FALSEnever evaluated
0
969 free(*pp);
never executed: free(*pp);
0
970 free(pglob->gl_pathv);-
971 pglob->gl_pathv = NULL;-
972 }
never executed: end of block
0
973 if (pglob->gl_statv != NULL) {
pglob->gl_statv != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
974 for (i = 0; i < pglob->gl_pathc; i++) {
i < pglob->gl_pathcDescription
TRUEnever evaluated
FALSEnever evaluated
0
975 if (pglob->gl_statv[i] != NULL)
pglob->gl_stat...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
976 free(pglob->gl_statv[i]);
never executed: free(pglob->gl_statv[i]);
0
977 }
never executed: end of block
0
978 free(pglob->gl_statv);-
979 pglob->gl_statv = NULL;-
980 }
never executed: end of block
0
981}
never executed: end of block
0
982-
983static DIR *-
984g_opendir(Char *str, glob_t *pglob)-
985{-
986 char buf[MAXPATHLEN];-
987-
988 if (!*str)
!*strDescription
TRUEnever evaluated
FALSEnever evaluated
0
989 strlcpy(buf, ".", sizeof buf);
never executed: strlcpy(buf, ".", sizeof buf);
0
990 else {-
991 if (g_Ctoc(str, buf, sizeof(buf)))
g_Ctoc(str, buf, sizeof(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
992 return(NULL);
never executed: return( ((void *)0) );
0
993 }
never executed: end of block
0
994-
995 if (pglob->gl_flags & GLOB_ALTDIRFUNC)
pglob->gl_flags & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
996 return((*pglob->gl_opendir)(buf));
never executed: return((*pglob->gl_opendir)(buf));
0
997-
998 return(opendir(buf));
never executed: return(opendir(buf));
0
999}-
1000-
1001static int-
1002g_lstat(Char *fn, struct stat *sb, glob_t *pglob)-
1003{-
1004 char buf[MAXPATHLEN];-
1005-
1006 if (g_Ctoc(fn, buf, sizeof(buf)))
g_Ctoc(fn, buf, sizeof(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
1007 return(-1);
never executed: return(-1);
0
1008 if (pglob->gl_flags & GLOB_ALTDIRFUNC)
pglob->gl_flags & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
1009 return((*pglob->gl_lstat)(buf, sb));
never executed: return((*pglob->gl_lstat)(buf, sb));
0
1010 return(lstat(buf, sb));
never executed: return(lstat(buf, sb));
0
1011}-
1012-
1013static int-
1014g_stat(Char *fn, struct stat *sb, glob_t *pglob)-
1015{-
1016 char buf[MAXPATHLEN];-
1017-
1018 if (g_Ctoc(fn, buf, sizeof(buf)))
g_Ctoc(fn, buf, sizeof(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
1019 return(-1);
never executed: return(-1);
0
1020 if (pglob->gl_flags & GLOB_ALTDIRFUNC)
pglob->gl_flags & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
1021 return((*pglob->gl_stat)(buf, sb));
never executed: return((*pglob->gl_stat)(buf, sb));
0
1022 return(stat(buf, sb));
never executed: return(stat(buf, sb));
0
1023}-
1024-
1025static Char *-
1026g_strchr(const Char *str, int ch)-
1027{-
1028 do {-
1029 if (*str == ch)
*str == chDescription
TRUEnever evaluated
FALSEnever evaluated
0
1030 return ((Char *)str);
never executed: return ((Char *)str);
0
1031 } while (*str++);
never executed: end of block
*str++Description
TRUEnever evaluated
FALSEnever evaluated
0
1032 return (NULL);
never executed: return ( ((void *)0) );
0
1033}-
1034-
1035static int-
1036g_Ctoc(const Char *str, char *buf, u_int len)-
1037{-
1038-
1039 while (len--) {
len--Description
TRUEnever evaluated
FALSEnever evaluated
0
1040 if ((*buf++ = *str++) == EOS)
(*buf++ = *str++) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1041 return (0);
never executed: return (0);
0
1042 }
never executed: end of block
0
1043 return (1);
never executed: return (1);
0
1044}-
1045-
1046#ifdef DEBUG-
1047static void-
1048qprintf(const char *str, Char *s)-
1049{-
1050 Char *p;-
1051-
1052 (void)printf("%s:\n", str);-
1053 for (p = s; *p; p++)-
1054 (void)printf("%c", CHAR(*p));-
1055 (void)printf("\n");-
1056 for (p = s; *p; p++)-
1057 (void)printf("%c", *p & M_PROTECT ? '"' : ' ');-
1058 (void)printf("\n");-
1059 for (p = s; *p; p++)-
1060 (void)printf("%c", ismeta(*p) ? '_' : ' ');-
1061 (void)printf("\n");-
1062}-
1063#endif-
1064-
1065#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) ||-
1066 !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2