rpm  5.4.15
glob.c
Go to the documentation of this file.
1 /*@-bounds@*/
2 /*@-branchstate@*/
3 /*@-compdef@*/
4 /*@-immediatetrans@*/
5 /*@-internalglobs@*/
6 /*@-loopswitchbreak@*/
7 /*@-modnomods@*/
8 /*@-mods@*/
9 /*@-moduncon@*/
10 /*@-modunconnomods@*/
11 /*@-noeffectuncon@*/
12 /*@-nullpass@*/
13 /*@-onlytrans@*/
14 /*@-protoparammatch@*/
15 /*@-retalias@*/
16 /*@-retvalint@*/
17 /*@-shadow@*/
18 /*@-sizeoftype@*/
19 /*@-temptrans@*/
20 /*@-type@*/
21 /*@-unqualifiedtrans@*/
22 /*@-unrecog@*/
23 
24 /* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
25 
26  This library is free software; you can redistribute it and/or
27  modify it under the terms of the GNU Library General Public License as
28  published by the Free Software Foundation; either version 2 of the
29  License, or (at your option) any later version.
30 
31  This library is distributed in the hope that it will be useful,
32  but WITHOUT ANY WARRANTY; without even the implied warranty of
33  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34  Library General Public License for more details.
35 
36  You should have received a copy of the GNU Library General Public
37  License along with this library; see the file COPYING.LIB. If not,
38  write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
39  Boston, MA 02111-1307, USA. */
40 
41 /* AIX requires this to be the first thing in the file. */
42 #if defined _AIX && !defined __GNUC__
43  #pragma alloca
44 #endif
45 
46 /*@access DIR@*/
47 
48 # include "system.h"
49 
50 /* Needed for offsetof() */
51 # include <stddef.h>
52 
53 # include <assert.h>
54 
55 #undef __alloca
56 #define __alloca alloca
57 #define __stat stat
58 #define NAMLEN(_d) NLENGTH(_d)
59 
60 /* If the system has the `struct dirent64' type we use it internally. */
61 # if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
62 # define CONVERT_D_NAMLEN(d64, d32)
63 # else
64 # define CONVERT_D_NAMLEN(d64, d32) \
65  (d64)->d_namlen = (d32)->d_namlen;
66 # endif
67 
68 # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
69 # define CONVERT_D_INO(d64, d32)
70 # else
71 # define CONVERT_D_INO(d64, d32) \
72  (d64)->d_ino = (d32)->d_ino;
73 # endif
74 
75 # ifdef _DIRENT_HAVE_D_TYPE
76 # define CONVERT_D_TYPE(d64, d32) \
77  (d64)->d_type = (d32)->d_type;
78 # else
79 # define CONVERT_D_TYPE(d64, d32)
80 # endif
81 
82 # define CONVERT_DIRENT_DIRENT64(d64, d32) \
83  memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
84  CONVERT_D_NAMLEN (d64, d32) \
85  CONVERT_D_INO (d64, d32) \
86  CONVERT_D_TYPE (d64, d32)
87 
88 #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
89 /* Posix does not require that the d_ino field be present, and some
90  systems do not provide it. */
91 # define REAL_DIR_ENTRY(dp) 1
92 #else
93 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
94 #endif /* POSIX */
95 
96 #include <errno.h>
97 #ifndef __set_errno
98 # define __set_errno(val) errno = (val)
99 #endif
100 
101 #if !defined(NAME_MAX) /* XXX OpenIndiana needs this. */
102 #define NAME_MAX 255
103 #endif
104 
105 /* Outcomment the following line for production quality code. */
106 /* #define NDEBUG 1 */
107 
108 #define GLOB_INTERFACE_VERSION 1
109 
110 /*@null@*/
111 static inline const char *next_brace_sub __P ((const char *begin))
112  /*@*/;
113 static int glob_in_dir __P ((const char *pattern, const char *directory,
114  int flags,
115  int (*errfunc) (const char *, int),
116  glob_t *pglob))
117  /*@globals fileSystem @*/
118  /*@modifies fileSystem @*/;
119 static int prefix_array __P ((const char *prefix, char **array, size_t n))
120  /*@*/;
121 static int collated_compare __P ((const __ptr_t, const __ptr_t))
122  /*@*/;
123 
124 
125 /* Find the end of the sub-pattern in a brace expression. We define
126  this as an inline function if the compiler permits. */
127 static inline const char *
128 next_brace_sub (const char *begin)
129 {
130  unsigned int depth = 0;
131  const char *cp = begin;
132 
133  while (1)
134  {
135  if (depth == 0)
136  {
137  if (*cp != ',' && *cp != '}' && *cp != '\0')
138  {
139  if (*cp == '{')
140  ++depth;
141  ++cp;
142  continue;
143  }
144  }
145  else
146  {
147  while (*cp != '\0' && (*cp != '}' || depth > 0))
148  {
149  if (*cp == '}')
150  --depth;
151  ++cp;
152  }
153  if (*cp == '\0')
154  /* An incorrectly terminated brace expression. */
155  return NULL;
156 
157  continue;
158  }
159  break;
160  }
161 
162  return cp;
163 }
164 
165 static int __glob_pattern_p (const char *pattern, int quote);
166 
167 /* Do glob searching for PATTERN, placing results in PGLOB.
168  The bits defined above may be set in FLAGS.
169  If a directory cannot be opened or read and ERRFUNC is not nil,
170  it is called with the pathname that caused the error, and the
171  `errno' value from the failing call; if it returns non-zero
172  `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
173  If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
174  Otherwise, `glob' returns zero. */
175 int
176 glob (const char *pattern, int flags,
177  int (*errfunc) __P ((const char *, int)), glob_t *pglob)
178 {
179  const char *filename;
180  const char *dirname;
181  size_t dirlen;
182  int status;
183  int oldcount;
184 
185  if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
186  {
187  __set_errno (EINVAL);
188  return -1;
189  }
190 
191  if (flags & GLOB_BRACE)
192  {
193  const char *begin = strchr (pattern, '{');
194  if (begin != NULL)
195  {
196  /* Allocate working buffer large enough for our work. Note that
197  we have at least an opening and closing brace. */
198  int firstc;
199  char *alt_start;
200  const char *p;
201  const char *next;
202  const char *rest;
203  size_t rest_len;
204 #ifdef __GNUC__
205  char onealt[strlen (pattern) - 1];
206 #else
207  char *onealt = (char *) xmalloc (strlen (pattern) - 1);
208  if (onealt == NULL)
209  {
210  if (!(flags & GLOB_APPEND))
211  globfree (pglob);
212  return GLOB_NOSPACE;
213  }
214 #endif
215 
216  /* We know the prefix for all sub-patterns. */
217 #ifdef HAVE_MEMPCPY
218  alt_start = (char *) mempcpy (onealt, pattern, begin - pattern);
219 #else
220  memcpy (onealt, pattern, begin - pattern);
221  alt_start = &onealt[begin - pattern];
222 #endif
223 
224  /* Find the first sub-pattern and at the same time find the
225  rest after the closing brace. */
226  next = next_brace_sub (begin + 1);
227  if (next == NULL)
228  {
229  /* It is an illegal expression. */
230 #ifndef __GNUC__
231  free (onealt);
232 #endif
233  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
234  }
235 
236  /* Now find the end of the whole brace expression. */
237  rest = next;
238  while (*rest != '}')
239  {
240  rest = next_brace_sub (rest + 1);
241  if (rest == NULL)
242  {
243  /* It is an illegal expression. */
244 #ifndef __GNUC__
245  free (onealt);
246 #endif
247  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
248  }
249  }
250  /* Please note that we now can be sure the brace expression
251  is well-formed. */
252  rest_len = strlen (++rest) + 1;
253 
254  /* We have a brace expression. BEGIN points to the opening {,
255  NEXT points past the terminator of the first element, and END
256  points past the final }. We will accumulate result names from
257  recursive runs for each brace alternative in the buffer using
258  GLOB_APPEND. */
259 
260  if (!(flags & GLOB_APPEND))
261  {
262  /* This call is to set a new vector, so clear out the
263  vector so we can append to it. */
264  pglob->gl_pathc = 0;
265  pglob->gl_pathv = NULL;
266  }
267  firstc = pglob->gl_pathc;
268 
269  p = begin + 1;
270  while (1)
271  {
272  int result;
273 
274  /* Construct the new glob expression. */
275 #ifdef HAVE_MEMPCPY
276  mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
277 #else
278  memcpy (alt_start, p, next - p);
279  memcpy (&alt_start[next - p], rest, rest_len);
280 #endif
281 
282  result = glob (onealt,
283  ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
284  | GLOB_APPEND), errfunc, pglob);
285 
286  /* If we got an error, return it. */
287  if (result && result != GLOB_NOMATCH)
288  {
289 #ifndef __GNUC__
290  free (onealt);
291 #endif
292  if (!(flags & GLOB_APPEND))
293  globfree (pglob);
294  return result;
295  }
296 
297  if (*next == '}')
298  /* We saw the last entry. */
299  break;
300 
301  p = next + 1;
302  next = next_brace_sub (p);
303  assert (next != NULL);
304  }
305 
306 #ifndef __GNUC__
307  free (onealt);
308 #endif
309 
310  if ((int)pglob->gl_pathc != firstc)
311  /* We found some entries. */
312  return 0;
313  else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
314  return GLOB_NOMATCH;
315  }
316  }
317 
318  /* Find the filename. */
319  filename = strrchr (pattern, '/');
320 #if defined __MSDOS__ || defined WINDOWS32
321  /* The case of "d:pattern". Since `:' is not allowed in
322  file names, we can safely assume that wherever it
323  happens in pattern, it signals the filename part. This
324  is so we could some day support patterns like "[a-z]:foo". */
325  if (filename == NULL)
326  filename = strchr (pattern, ':');
327 #endif /* __MSDOS__ || WINDOWS32 */
328  if (filename == NULL)
329  {
330  /* This can mean two things: a simple name or "~name". The latter
331  case is nothing but a notation for a directory. */
332  if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
333  {
334  dirname = pattern;
335  dirlen = strlen (pattern);
336 
337  /* Set FILENAME to NULL as a special flag. This is ugly but
338  other solutions would require much more code. We test for
339  this special case below. */
340  filename = NULL;
341  }
342  else
343  {
344  filename = pattern;
345 #ifdef _AMIGA
346  dirname = "";
347 #else
348  dirname = ".";
349 #endif
350  dirlen = 0;
351  }
352  }
353  else if (filename == pattern)
354  {
355  /* "/pattern". */
356  dirname = "/";
357  dirlen = 1;
358  ++filename;
359  }
360  else
361  {
362  char *newp;
363  dirlen = filename - pattern;
364 #if defined __MSDOS__ || defined WINDOWS32
365  if (*filename == ':'
366  || (filename > pattern + 1 && filename[-1] == ':'))
367  {
368  char *drive_spec;
369 
370  ++dirlen;
371  drive_spec = (char *) __alloca (dirlen + 1);
372 #ifdef HAVE_MEMPCPY
373  *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
374 #else
375  memcpy (drive_spec, pattern, dirlen);
376  drive_spec[dirlen] = '\0';
377 #endif
378  /* For now, disallow wildcards in the drive spec, to
379  prevent infinite recursion in glob. */
380  if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
381  return GLOB_NOMATCH;
382  /* If this is "d:pattern", we need to copy `:' to DIRNAME
383  as well. If it's "d:/pattern", don't remove the slash
384  from "d:/", since "d:" and "d:/" are not the same.*/
385  }
386 #endif
387  newp = (char *) __alloca (dirlen + 1);
388 #ifdef HAVE_MEMPCPY
389  *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
390 #else
391  memcpy (newp, pattern, dirlen);
392  newp[dirlen] = '\0';
393 #endif
394  dirname = newp;
395  ++filename;
396 
397  if (filename[0] == '\0'
398 #if defined __MSDOS__ || defined WINDOWS32
399  && dirname[dirlen - 1] != ':'
400  && (dirlen < 3 || dirname[dirlen - 2] != ':'
401  || dirname[dirlen - 1] != '/')
402 #endif
403  && dirlen > 1)
404  /* "pattern/". Expand "pattern", appending slashes. */
405  {
406  int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
407  if (val == 0)
408  pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
409  | (flags & GLOB_MARK));
410  return val;
411  }
412  }
413 
414  if (!(flags & GLOB_APPEND))
415  {
416  pglob->gl_pathc = 0;
417  pglob->gl_pathv = NULL;
418  }
419 
420  oldcount = pglob->gl_pathc;
421 
422 #ifndef VMS
423  if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
424  {
425  if (dirname[1] == '\0' || dirname[1] == '/')
426  {
427  /* Look up home directory. */
428  const char *home_dir = getenv ("HOME");
429 # ifdef _AMIGA
430  if (home_dir == NULL || home_dir[0] == '\0')
431  home_dir = "SYS:";
432 # else
433 # ifdef WINDOWS32
434  if (home_dir == NULL || home_dir[0] == '\0')
435  home_dir = "c:/users/default"; /* poor default */
436 # else
437  if (home_dir == NULL || home_dir[0] == '\0')
438  {
439  int success;
440  char *name;
441 # if defined HAVE_GETLOGIN_R || defined _LIBC
442  size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
443 
444  if (buflen == 0)
445  /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
446  a moderate value. */
447  buflen = 20;
448  name = (char *) __alloca (buflen);
449 
450  success = getlogin_r (name, buflen) >= 0;
451 # else
452  success = (name = getlogin ()) != NULL;
453 # endif
454  if (success)
455  {
456  struct passwd *p;
457 # if defined HAVE_GETPWNAM_R || defined _LIBC
458  size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
459  char *pwtmpbuf;
460  struct passwd pwbuf;
461  int save = errno;
462 
463  if (pwbuflen == -1)
464  /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
465  Try a moderate value. */
466  pwbuflen = 1024;
467  pwtmpbuf = (char *) __alloca (pwbuflen);
468 
469  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
470  != 0)
471  {
472  if (errno != ERANGE)
473  {
474  p = NULL;
475  break;
476  }
477  pwbuflen *= 2;
478  pwtmpbuf = (char *) __alloca (pwbuflen);
479  __set_errno (save);
480  }
481 # else
482  p = getpwnam (name);
483 # endif
484  if (p != NULL)
485  home_dir = p->pw_dir;
486  }
487  }
488  if (home_dir == NULL || home_dir[0] == '\0')
489  {
490  if (flags & GLOB_TILDE_CHECK)
491  return GLOB_NOMATCH;
492  else
493  home_dir = "~"; /* No luck. */
494  }
495 # endif /* WINDOWS32 */
496 # endif
497  /* Now construct the full directory. */
498  if (dirname[1] == '\0')
499  dirname = home_dir;
500  else
501  {
502  char *newp;
503  size_t home_len = strlen (home_dir);
504  newp = (char *) __alloca (home_len + dirlen);
505 # ifdef HAVE_MEMPCPY
506  mempcpy (mempcpy (newp, home_dir, home_len),
507  &dirname[1], dirlen);
508 # else
509  memcpy (newp, home_dir, home_len);
510  memcpy (&newp[home_len], &dirname[1], dirlen);
511 # endif
512  dirname = newp;
513  }
514  }
515 # if !defined _AMIGA && !defined WINDOWS32
516  else
517  {
518  char * end_name = (char *) strchr (dirname, '/');
519  const char *user_name;
520  const char *home_dir;
521 
522  if (end_name == NULL)
523  user_name = dirname + 1;
524  else
525  {
526  char *newp;
527  newp = (char *) __alloca (end_name - dirname);
528 # ifdef HAVE_MEMPCPY
529  *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
530  = '\0';
531 # else
532  memcpy (newp, dirname + 1, end_name - dirname);
533  newp[end_name - dirname - 1] = '\0';
534 # endif
535  user_name = newp;
536  }
537 
538  /* Look up specific user's home directory. */
539  {
540  struct passwd *p;
541 # if defined HAVE_GETPWNAM_R || defined _LIBC
542  size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
543  char *pwtmpbuf;
544  struct passwd pwbuf;
545  int save = errno;
546 
547  if (buflen == -1)
548  /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
549  moderate value. */
550  buflen = 1024;
551  pwtmpbuf = (char *) __alloca (buflen);
552 
553  while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
554  {
555  if (errno != ERANGE)
556  {
557  p = NULL;
558  break;
559  }
560  buflen *= 2;
561  pwtmpbuf = __alloca (buflen);
562  __set_errno (save);
563  }
564 # else
565  p = getpwnam (user_name);
566 # endif
567  if (p != NULL)
568  home_dir = p->pw_dir;
569  else
570  home_dir = NULL;
571  }
572  /* If we found a home directory use this. */
573  if (home_dir != NULL)
574  {
575  char *newp;
576  size_t home_len = strlen (home_dir);
577  size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
578  newp = (char *) __alloca (home_len + rest_len + 1);
579 # ifdef HAVE_MEMPCPY
580  *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
581  end_name, rest_len)) = '\0';
582 # else
583  memcpy (newp, home_dir, home_len);
584  memcpy (&newp[home_len], end_name, rest_len);
585  newp[home_len + rest_len] = '\0';
586 # endif
587  dirname = newp;
588  }
589  else
590  if (flags & GLOB_TILDE_CHECK)
591  /* We have to regard it as an error if we cannot find the
592  home directory. */
593  return GLOB_NOMATCH;
594  }
595 # endif /* Not Amiga && not WINDOWS32. */
596  }
597 #endif /* Not VMS. */
598 
599  /* Now test whether we looked for "~" or "~NAME". In this case we
600  can give the answer now. */
601  if (filename == NULL)
602  {
603  struct stat st;
604 
605  /* Return the directory if we don't check for error or if it exists. */
606  if ((flags & GLOB_NOCHECK)
607  || (((flags & GLOB_ALTDIRFUNC)
608  ? (*pglob->gl_stat) (dirname, &st)
609  : __stat (dirname, &st)) == 0
610  && S_ISDIR (st.st_mode)))
611  {
612  pglob->gl_pathv
613  = (char **) xrealloc (pglob->gl_pathv,
614  (pglob->gl_pathc +
615  ((flags & GLOB_DOOFFS) ?
616  pglob->gl_offs : 0) +
617  1 + 1) *
618  sizeof (char *));
619  if (pglob->gl_pathv == NULL)
620  return GLOB_NOSPACE;
621 
622  if (flags & GLOB_DOOFFS)
623  while (pglob->gl_pathc < pglob->gl_offs)
624  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
625 
626 #if defined HAVE_STRDUP || defined _LIBC
627  pglob->gl_pathv[pglob->gl_pathc] = xstrdup (dirname);
628 #else
629  {
630  size_t len = strlen (dirname) + 1;
631  char *dircopy = xmalloc (len);
632  if (dircopy != NULL)
633  pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
634  len);
635  }
636 #endif
637  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
638  {
639  free (pglob->gl_pathv);
640  return GLOB_NOSPACE;
641  }
642  pglob->gl_pathv[++pglob->gl_pathc] = NULL;
643  pglob->gl_flags = flags;
644 
645  return 0;
646  }
647 
648  /* Not found. */
649  return GLOB_NOMATCH;
650  }
651 
652  if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
653  {
654  /* The directory name contains metacharacters, so we
655  have to glob for the directory, and then glob for
656  the pattern in each directory found. */
657  glob_t dirs;
658  register int i;
659 
660  if ((flags & GLOB_ALTDIRFUNC) != 0)
661  {
662  /* Use the alternative access functions also in the recursive
663  call. */
664  dirs.gl_opendir = pglob->gl_opendir;
665  dirs.gl_readdir = pglob->gl_readdir;
666  dirs.gl_closedir = pglob->gl_closedir;
667  dirs.gl_stat = pglob->gl_stat;
668  dirs.gl_lstat = pglob->gl_lstat;
669  }
670 
671  status = glob (dirname,
672  ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
673  | GLOB_ALTDIRFUNC))
675  errfunc, &dirs);
676  if (status != 0)
677  return status;
678 
679  /* We have successfully globbed the preceding directory name.
680  For each name we found, call glob_in_dir on it and FILENAME,
681  appending the results to PGLOB. */
682  for (i = 0; i < (int)dirs.gl_pathc; ++i)
683  {
684  int old_pathc;
685 
686 #ifdef SHELL
687  {
688  /* Make globbing interruptible in the bash shell. */
689  extern int interrupt_state;
690 
691  if (interrupt_state)
692  {
693  globfree (&dirs);
694  globfree (&files);
695  return GLOB_ABORTED;
696  }
697  }
698 #endif /* SHELL. */
699 
700  old_pathc = pglob->gl_pathc;
701  status = glob_in_dir (filename, dirs.gl_pathv[i],
702  ((flags | GLOB_APPEND)
703  & ~(GLOB_NOCHECK | GLOB_ERR)),
704  errfunc, pglob);
705  if (status == GLOB_NOMATCH)
706  /* No matches in this directory. Try the next. */
707  continue;
708 
709  if (status != 0)
710  {
711  globfree (&dirs);
712  globfree (pglob);
713  return status;
714  }
715 
716  /* Stick the directory on the front of each name. */
717  if (prefix_array (dirs.gl_pathv[i],
718  &pglob->gl_pathv[old_pathc],
719  pglob->gl_pathc - old_pathc))
720  {
721  globfree (&dirs);
722  globfree (pglob);
723  return GLOB_NOSPACE;
724  }
725  }
726 
727  flags |= GLOB_MAGCHAR;
728 
729  /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
730  But if we have not found any matching entry and thie GLOB_NOCHECK
731  flag was set we must return the list consisting of the disrectory
732  names followed by the filename. */
733  if ((int)pglob->gl_pathc == oldcount)
734  {
735  /* No matches. */
736  if (flags & GLOB_NOCHECK)
737  {
738  size_t filename_len = strlen (filename) + 1;
739  char **new_pathv;
740  struct stat st;
741 
742  /* This is an pessimistic guess about the size. */
743  pglob->gl_pathv
744  = (char **) xrealloc (pglob->gl_pathv,
745  (pglob->gl_pathc +
746  ((flags & GLOB_DOOFFS) ?
747  pglob->gl_offs : 0) +
748  dirs.gl_pathc + 1) *
749  sizeof (char *));
750  if (pglob->gl_pathv == NULL)
751  {
752  globfree (&dirs);
753  return GLOB_NOSPACE;
754  }
755 
756  if (flags & GLOB_DOOFFS)
757  while (pglob->gl_pathc < pglob->gl_offs)
758  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
759 
760  for (i = 0; i < (int)dirs.gl_pathc; ++i)
761  {
762  const char *dir = dirs.gl_pathv[i];
763  size_t dir_len = strlen (dir);
764 
765  /* First check whether this really is a directory. */
766  if (((flags & GLOB_ALTDIRFUNC)
767  ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
768  || !S_ISDIR (st.st_mode))
769  /* No directory, ignore this entry. */
770  continue;
771 
772  pglob->gl_pathv[pglob->gl_pathc] = (char *) xmalloc (dir_len + 1
773  + filename_len);
774  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
775  {
776  globfree (&dirs);
777  globfree (pglob);
778  return GLOB_NOSPACE;
779  }
780 
781 #ifdef HAVE_MEMPCPY
782  mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
783  dir, dir_len),
784  "/", 1),
785  filename, filename_len);
786 #else
787  memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
788  pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
789  memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
790  filename, filename_len);
791 #endif
792  ++pglob->gl_pathc;
793  }
794 
795  pglob->gl_pathv[pglob->gl_pathc] = NULL;
796  pglob->gl_flags = flags;
797 
798  /* Now we know how large the gl_pathv vector must be. */
799  new_pathv = (char **) xrealloc (pglob->gl_pathv,
800  ((pglob->gl_pathc + 1)
801  * sizeof (char *)));
802  if (new_pathv != NULL)
803  pglob->gl_pathv = new_pathv;
804  }
805  else
806  return GLOB_NOMATCH;
807  }
808 
809  globfree (&dirs);
810  }
811  else
812  {
813  status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
814  if (status != 0)
815  return status;
816 
817  if (dirlen > 0)
818  {
819  /* Stick the directory on the front of each name. */
820  int ignore = oldcount;
821 
822  if ((flags & GLOB_DOOFFS) && ignore < (int)pglob->gl_offs)
823  ignore = pglob->gl_offs;
824 
825  if (prefix_array (dirname,
826  &pglob->gl_pathv[ignore],
827  pglob->gl_pathc - ignore))
828  {
829  globfree (pglob);
830  return GLOB_NOSPACE;
831  }
832  }
833  }
834 
835  if (flags & GLOB_MARK)
836  {
837  /* Append slashes to directory names. */
838  int i;
839  struct stat st;
840  for (i = oldcount; i < (int)pglob->gl_pathc; ++i)
841  if (((flags & GLOB_ALTDIRFUNC)
842  ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
843  : __stat (pglob->gl_pathv[i], &st)) == 0
844  && S_ISDIR (st.st_mode))
845  {
846  size_t len = strlen (pglob->gl_pathv[i]) + 2;
847  char *my = (char *) xrealloc (pglob->gl_pathv[i], len);
848  if (my == NULL)
849  {
850  globfree (pglob);
851  return GLOB_NOSPACE;
852  }
853  strcpy (&my[len - 2], "/");
854  pglob->gl_pathv[i] = my;
855  }
856  }
857 
858  if (!(flags & GLOB_NOSORT))
859  {
860  /* Sort the vector. */
861  int non_sort = oldcount;
862 
863  if ((flags & GLOB_DOOFFS) && (int)pglob->gl_offs > oldcount)
864  non_sort = pglob->gl_offs;
865 
866  qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
867  pglob->gl_pathc - non_sort,
868  sizeof (char *), collated_compare);
869  }
870 
871  return 0;
872 }
873 
874 
875 /* Free storage allocated in PGLOB by a previous `glob' call. */
876 void
877 globfree (glob_t *pglob)
878 {
879  if (pglob->gl_pathv != NULL)
880  {
881  register int i;
882  for (i = 0; i < (int)pglob->gl_pathc; ++i)
883  if (pglob->gl_pathv[i] != NULL)
884  free ((__ptr_t) pglob->gl_pathv[i]);
885  free ((__ptr_t) pglob->gl_pathv);
886  }
887 }
888 
889 
890 /* Do a collated comparison of A and B. */
891 static int
893 {
894  const char *const s1 = *(const char *const * const) a;
895  const char *const s2 = *(const char *const * const) b;
896 
897  if (s1 == s2)
898  return 0;
899  if (s1 == NULL)
900  return 1;
901  if (s2 == NULL)
902  return -1;
903  return strcoll (s1, s2);
904 }
905 
906 
907 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
908  elements in place. Return nonzero if out of memory, zero if successful.
909  A slash is inserted between DIRNAME and each elt of ARRAY,
910  unless DIRNAME is just "/". Each old element of ARRAY is freed. */
911 static int
912 prefix_array (const char *dirname, char **array, size_t n)
913 {
914  register size_t i;
915  size_t dirlen = strlen (dirname);
916 #if defined __MSDOS__ || defined WINDOWS32
917  int sep_char = '/';
918 # define DIRSEP_CHAR sep_char
919 #else
920 # define DIRSEP_CHAR '/'
921 #endif
922 
923  if (dirlen == 1 && dirname[0] == '/')
924  /* DIRNAME is just "/", so normal prepending would get us "//foo".
925  We want "/foo" instead, so don't prepend any chars from DIRNAME. */
926  dirlen = 0;
927 #if defined __MSDOS__ || defined WINDOWS32
928  else if (dirlen > 1)
929  {
930  if (dirname[dirlen - 1] == '/')
931  /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
932  --dirlen;
933  else if (dirname[dirlen - 1] == ':')
934  {
935  /* DIRNAME is "d:". Use `:' instead of `/'. */
936  --dirlen;
937  sep_char = ':';
938  }
939  }
940 #endif
941 
942  for (i = 0; i < n; ++i)
943  {
944  size_t eltlen = strlen (array[i]) + 1;
945  char *my = (char *) xmalloc (dirlen + 1 + eltlen);
946  if (my == NULL)
947  {
948  while (i > 0)
949  free ((__ptr_t) array[--i]);
950  return 1;
951  }
952 
953 #ifdef HAVE_MEMPCPY
954  {
955  char *endp = (char *) mempcpy (my, dirname, dirlen);
956  *endp++ = DIRSEP_CHAR;
957  mempcpy (endp, array[i], eltlen);
958  }
959 #else
960  memcpy (my, dirname, dirlen);
961  my[dirlen] = DIRSEP_CHAR;
962  memcpy (&my[dirlen + 1], array[i], eltlen);
963 #endif
964  free ((__ptr_t) array[i]);
965  array[i] = my;
966  }
967 
968  return 0;
969 }
970 
971 
972 /* We must not compile this function twice. */
973 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
974 /* Return nonzero if PATTERN contains any metacharacters.
975  Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
976 static int
977 __glob_pattern_p (const char *pattern, int quote)
978 {
979  register const char *p;
980  int open = 0;
981 
982  for (p = pattern; *p != '\0'; ++p)
983  switch (*p)
984  {
985  case '?':
986  case '*':
987  return 1;
988 
989  case '\\':
990  if (quote && p[1] != '\0')
991  ++p;
992  break;
993 
994  case '[':
995  open = 1;
996  break;
997 
998  case ']':
999  if (open)
1000  return 1;
1001  break;
1002  }
1003 
1004  return 0;
1005 }
1006 # ifdef _LIBC
1007 weak_alias (__glob_pattern_p, glob_pattern_p)
1008 # endif
1009 #endif
1010 
1011 
1012 /* Like `glob', but PATTERN is a final pathname component,
1013  and matches are searched for in DIRECTORY.
1014  The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1015  The GLOB_APPEND flag is assumed to be set (always appends). */
1016 static int
1017 glob_in_dir (const char *pattern, const char *directory, int flags,
1018  int (*errfunc) __P ((const char *, int)), glob_t *pglob)
1019 {
1020  __ptr_t stream = NULL;
1021 
1022  struct globlink
1023  {
1024  struct globlink *next;
1025  char *name;
1026  };
1027  struct globlink *names = NULL;
1028  size_t nfound;
1029  int meta;
1030  int save;
1031 
1032  meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1033  if (meta == 0)
1034  {
1035  if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
1036  /* We need not do any tests. The PATTERN contains no meta
1037  characters and we must not return an error therefore the
1038  result will always contain exactly one name. */
1039  flags |= GLOB_NOCHECK;
1040  else
1041  {
1042  /* Since we use the normal file functions we can also use stat()
1043  to verify the file is there. */
1044  struct stat st;
1045  size_t patlen = strlen (pattern);
1046  size_t dirlen = strlen (directory);
1047  char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
1048 
1049 # ifdef HAVE_MEMPCPY
1050  mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1051  "/", 1),
1052  pattern, patlen + 1);
1053 # else
1054  memcpy (fullname, directory, dirlen);
1055  fullname[dirlen] = '/';
1056  memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
1057 # endif
1058  if (((flags & GLOB_ALTDIRFUNC)
1059  ? (*pglob->gl_stat) (fullname, &st)
1060  : __stat (fullname, &st)) == 0)
1061  /* We found this file to be existing. Now tell the rest
1062  of the function to copy this name into the result. */
1063  flags |= GLOB_NOCHECK;
1064  }
1065 
1066  nfound = 0;
1067  }
1068  else
1069  {
1070  if (pattern[0] == '\0')
1071  {
1072  /* This is a special case for matching directories like in
1073  "*a/". */
1074  names = (struct globlink *) __alloca (sizeof (struct globlink));
1075  names->name = (char *) xmalloc (1);
1076  if (names->name == NULL)
1077  goto memory_error;
1078  names->name[0] = '\0';
1079  names->next = NULL;
1080  nfound = 1;
1081  meta = 0;
1082  }
1083  else
1084  {
1085  stream = ((flags & GLOB_ALTDIRFUNC)
1086  ? (*pglob->gl_opendir) (directory)
1087  : (__ptr_t) opendir (directory));
1088  if (stream == NULL)
1089  {
1090  if (errno != ENOTDIR
1091  && ((errfunc != NULL && (*errfunc) (directory, errno))
1092  || (flags & GLOB_ERR)))
1093  return GLOB_ABORTED;
1094  nfound = 0;
1095  meta = 0;
1096  }
1097  else
1098  {
1099  int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1100  | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1101 #if defined _AMIGA || defined VMS
1102  | FNM_CASEFOLD
1103 #endif
1104  );
1105  nfound = 0;
1106  flags |= GLOB_MAGCHAR;
1107 
1108  while (1)
1109  {
1110  const char *name;
1111  size_t len;
1112 #ifdef _LARGEFILE64_SOURCE
1113  struct dirent64 *d;
1114  union
1115  {
1116  struct dirent64 d64;
1117  char room [offsetof (struct dirent64, d_name[0])
1118  + NAME_MAX + 1];
1119  }
1120  d64buf;
1121 
1122  if ((flags & GLOB_ALTDIRFUNC))
1123  {
1124  struct dirent *d32 = (*pglob->gl_readdir) (stream);
1125  if (d32 != NULL)
1126  {
1127  CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
1128  d = &d64buf.d64;
1129  }
1130  else
1131  d = NULL;
1132  }
1133  else
1134  d = readdir64 ((DIR *)stream);
1135 #else
1136  struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1137  ? (*pglob->gl_readdir) (stream)
1138  : readdir ((DIR *) stream));
1139 #endif
1140  if (d == NULL)
1141  break;
1142  if (! REAL_DIR_ENTRY (d))
1143  continue;
1144 
1145 #ifdef HAVE_D_TYPE
1146  /* If we shall match only directories use the information
1147  provided by the dirent call if possible. */
1148  if ((flags & GLOB_ONLYDIR)
1149  && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
1150  continue;
1151 #endif
1152 
1153  name = d->d_name;
1154 
1155  if (fnmatch (pattern, name, fnm_flags) == 0)
1156  {
1157  struct globlink *my = (struct globlink *)
1158  __alloca (sizeof (struct globlink));
1159  len = NAMLEN (d);
1160  my->name = (char *) xmalloc (len + 1);
1161  if (my->name == NULL)
1162  goto memory_error;
1163 #ifdef HAVE_MEMPCPY
1164  *((char *) mempcpy ((__ptr_t) my->name, name, len))
1165  = '\0';
1166 #else
1167  memcpy ((__ptr_t) my->name, name, len);
1168  my->name[len] = '\0';
1169 #endif
1170  my->next = names;
1171  names = my;
1172  ++nfound;
1173  }
1174  }
1175  }
1176  }
1177  }
1178 
1179  if (nfound == 0 && (flags & GLOB_NOCHECK))
1180  {
1181  size_t len = strlen (pattern);
1182  nfound = 1;
1183  names = (struct globlink *) __alloca (sizeof (struct globlink));
1184  names->next = NULL;
1185  names->name = (char *) xmalloc (len + 1);
1186  if (names->name == NULL)
1187  goto memory_error;
1188 #ifdef HAVE_MEMPCPY
1189  *((char *) mempcpy (names->name, pattern, len)) = '\0';
1190 #else
1191  memcpy (names->name, pattern, len);
1192  names->name[len] = '\0';
1193 #endif
1194  }
1195 
1196  if (nfound != 0)
1197  {
1198  pglob->gl_pathv
1199  = (char **) xrealloc (pglob->gl_pathv,
1200  (pglob->gl_pathc +
1201  ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1202  nfound + 1) *
1203  sizeof (char *));
1204  if (pglob->gl_pathv == NULL)
1205  goto memory_error;
1206 
1207  if (flags & GLOB_DOOFFS)
1208  while (pglob->gl_pathc < pglob->gl_offs)
1209  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
1210 
1211  for (; names != NULL; names = names->next)
1212  pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1213  pglob->gl_pathv[pglob->gl_pathc] = NULL;
1214 
1215  pglob->gl_flags = flags;
1216  }
1217 
1218  save = errno;
1219  if (stream != NULL)
1220  {
1221  if (flags & GLOB_ALTDIRFUNC)
1222  (*pglob->gl_closedir) (stream);
1223  else
1224  closedir ((DIR *) stream);
1225  }
1226  __set_errno (save);
1227 
1228  return nfound == 0 ? GLOB_NOMATCH : 0;
1229 
1230  memory_error:
1231  {
1232  save = errno;
1233  if (flags & GLOB_ALTDIRFUNC)
1234  (*pglob->gl_closedir) (stream);
1235  else
1236  closedir ((DIR *) stream);
1237  __set_errno (save);
1238  }
1239  while (names != NULL)
1240  {
1241  if (names->name != NULL)
1242  free ((__ptr_t) names->name);
1243  names = names->next;
1244  }
1245  return GLOB_NOSPACE;
1246 }
1247 /*@=unrecog@*/
1248 /*@=unqualifiedtrans@*/
1249 /*@=type@*/
1250 /*@=temptrans@*/
1251 /*@=sizeoftype@*/
1252 /*@=shadow@*/
1253 /*@=retvalint@*/
1254 /*@=retalias@*/
1255 /*@=protoparammatch@*/
1256 /*@=onlytrans@*/
1257 /*@=nullpass@*/
1258 /*@=noeffectuncon@*/
1259 /*@=modunconnomods@*/
1260 /*@=moduncon@*/
1261 /*@=mods@*/
1262 /*@=modnomods@*/
1263 /*@=loopswitchbreak@*/
1264 /*@=internalglobs@*/
1265 /*@=immediatetrans@*/
1266 /*@=compdef@*/
1267 /*@=branchstate@*/
1268 /*@=bounds@*/
const bson * b
Definition: bson.h:280
const char const double d
Definition: bson.h:800
const char const char size_t len
Definition: bson.h:823
char * getenv(const char *name)
#define GLOB_ALTDIRFUNC
Definition: glob.h:85
static int glob_in_dir(const char *pattern, const char *directory, int flags, int(*errfunc) __P((const char *, int)), glob_t *pglob)
Definition: glob.c:1017
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
#define GLOB_APPEND
Definition: glob.h:78
__size_t gl_pathc
Definition: glob.h:119
int(* gl_stat)()
Definition: glob.h:134
#define GLOB_TILDE_CHECK
Definition: glob.h:90
#define __alloca
Definition: glob.c:56
#define __set_errno(val)
Definition: glob.c:98
void globfree(glob_t *pglob)
Definition: glob.c:877
char *(* gl_opendir)()
Definition: glob.h:130
int errno
#define GLOB_BRACE
Definition: glob.h:86
char ** gl_pathv
Definition: glob.h:120
#define GLOB_MARK
Definition: glob.h:74
#define DT_UNKNOWN
Definition: rpmdir.h:12
Definition: glob.h:117
#define CONVERT_DIRENT_DIRENT64(d64, d32)
Definition: glob.c:82
int(* gl_lstat)()
Definition: glob.h:132
#define NAME_MAX
Definition: glob.c:102
#define __GLOB_FLAGS
Definition: glob.h:92
#define GLOB_DOOFFS
Definition: glob.h:76
#define GLOB_PERIOD
Definition: glob.h:80
#define DT_DIR
Definition: rpmdir.h:15
static int collated_compare(const __ptr_t a, const __ptr_t b)
Definition: glob.c:892
static const char * next_brace_sub(const char *begin)
Definition: glob.c:128
#define FNM_NOESCAPE
Definition: fnmatch.h:42
int gl_flags
Definition: glob.h:122
#define NAMLEN(_d)
Definition: glob.c:58
#define GLOB_NOMATCH
Definition: glob.h:105
#define __stat
Definition: glob.c:57
static int prefix_array(const char *dirname, char **array, size_t n)
Definition: glob.c:912
#define GLOB_NOSORT
Definition: glob.h:75
#define GLOB_NOESCAPE
Definition: glob.h:79
#define DIRSEP_CHAR
void(* gl_closedir)()
Definition: glob.h:126
#define dirent
Definition: system.h:245
#define FNM_PERIOD
Definition: fnmatch.h:43
#define GLOB_NOCHECK
Definition: glob.h:77
#define GLOB_NOMAGIC
Definition: glob.h:87
int depth
Definition: bson.h:258
struct dirent *(* gl_readdir)()
Definition: glob.h:128
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
#define GLOB_MAGCHAR
Definition: glob.h:84
#define GLOB_ERR
Definition: glob.h:73
#define GLOB_TILDE
Definition: glob.h:88
#define __ptr_t
Definition: glob.h:49
static int __glob_pattern_p(const char *pattern, int quote)
Definition: glob.c:977
const char const int i
Definition: bson.h:778
#define GLOB_ABORTED
Definition: glob.h:104
#define GLOB_ONLYDIR
Definition: glob.h:89
static const char * prefix[]
Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options.
Definition: rpmgrep.c:183
#define REAL_DIR_ENTRY(dp)
Definition: glob.c:93
__size_t gl_offs
Definition: glob.h:121
int glob(const char *pattern, int flags, int(*errfunc) __P((const char *, int)), glob_t *pglob)
Definition: glob.c:176
static const char *next_brace_sub __P((const char *begin))
static const char * name
const char const char * pattern
Definition: bson.h:971
#define xmalloc
Definition: system.h:32
#define FNM_CASEFOLD
Definition: fnmatch.h:48
int fnmatch(char *pattern, const char *string, int flags) const
Definition: fnmatch.c:279
#define xrealloc
Definition: system.h:35
#define GLOB_NOSPACE
Definition: glob.h:103