]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/glob/glob.c
Bash-5.0 patch 3: improvements when globbing directory names containing backslashes
[thirdparty/bash.git] / lib / glob / glob.c
1 /* glob.c -- file-name wildcard pattern matching for Bash.
2
3 Copyright (C) 1985-2017 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne-Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /* To whomever it may concern: I have never seen the code which most
22 Unix programs use to perform this function. I wrote this from scratch
23 based on specifications for the pattern matching. --RMS. */
24
25 #include <config.h>
26
27 #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
28 #pragma alloca
29 #endif /* _AIX && RISC6000 && !__GNUC__ */
30
31 #include "bashtypes.h"
32
33 #if defined (HAVE_UNISTD_H)
34 # include <unistd.h>
35 #endif
36
37 #include "bashansi.h"
38 #include "posixdir.h"
39 #include "posixstat.h"
40 #include "shmbutil.h"
41 #include "xmalloc.h"
42
43 #include "filecntl.h"
44 #if !defined (F_OK)
45 # define F_OK 0
46 #endif
47
48 #include "stdc.h"
49 #include "memalloc.h"
50
51 #include <signal.h>
52
53 #include "shell.h"
54
55 #include "glob.h"
56 #include "strmatch.h"
57
58 #if !defined (HAVE_BCOPY) && !defined (bcopy)
59 # define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
60 #endif /* !HAVE_BCOPY && !bcopy */
61
62 #if !defined (NULL)
63 # if defined (__STDC__)
64 # define NULL ((void *) 0)
65 # else
66 # define NULL 0x0
67 # endif /* __STDC__ */
68 #endif /* !NULL */
69
70 #if !defined (FREE)
71 # define FREE(x) if (x) free (x)
72 #endif
73
74 /* Don't try to alloca() more than this much memory for `struct globval'
75 in glob_vector() */
76 #ifndef ALLOCA_MAX
77 # define ALLOCA_MAX 100000
78 #endif
79
80 struct globval
81 {
82 struct globval *next;
83 char *name;
84 };
85
86 extern void throw_to_top_level __P((void));
87 extern int sh_eaccess __P((const char *, int));
88 extern char *sh_makepath __P((const char *, const char *, int));
89 extern int signal_is_pending __P((int));
90 extern void run_pending_traps __P((void));
91
92 extern int extended_glob;
93
94 /* Global variable which controls whether or not * matches .*.
95 Non-zero means don't match .*. */
96 int noglob_dot_filenames = 1;
97
98 /* Global variable which controls whether or not filename globbing
99 is done without regard to case. */
100 int glob_ignore_case = 0;
101
102 /* Global variable to return to signify an error in globbing. */
103 char *glob_error_return;
104
105 static struct globval finddirs_error_return;
106
107 /* Some forward declarations. */
108 static int skipname __P((char *, char *, int));
109 #if HANDLE_MULTIBYTE
110 static int mbskipname __P((char *, char *, int));
111 #endif
112 #if HANDLE_MULTIBYTE
113 static void udequote_pathname __P((char *));
114 static void wdequote_pathname __P((char *));
115 #else
116 # define dequote_pathname udequote_pathname
117 #endif
118 static void dequote_pathname __P((char *));
119 static int glob_testdir __P((char *, int));
120 static char **glob_dir_to_array __P((char *, char **, int));
121
122 /* Make sure these names continue to agree with what's in smatch.c */
123 extern char *glob_patscan __P((char *, char *, int));
124 extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int));
125
126 /* And this from gmisc.c/gm_loop.c */
127 extern int wextglob_pattern_p __P((wchar_t *));
128
129 extern char *glob_dirscan __P((char *, int));
130
131 /* Compile `glob_loop.c' for single-byte characters. */
132 #define GCHAR unsigned char
133 #define CHAR char
134 #define INT int
135 #define L(CS) CS
136 #define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
137 #include "glob_loop.c"
138
139 /* Compile `glob_loop.c' again for multibyte characters. */
140 #if HANDLE_MULTIBYTE
141
142 #define GCHAR wchar_t
143 #define CHAR wchar_t
144 #define INT wint_t
145 #define L(CS) L##CS
146 #define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
147 #include "glob_loop.c"
148
149 #endif /* HANDLE_MULTIBYTE */
150
151 /* And now a function that calls either the single-byte or multibyte version
152 of internal_glob_pattern_p. */
153 int
154 glob_pattern_p (pattern)
155 const char *pattern;
156 {
157 #if HANDLE_MULTIBYTE
158 size_t n;
159 wchar_t *wpattern;
160 int r;
161
162 if (MB_CUR_MAX == 1)
163 return (internal_glob_pattern_p ((unsigned char *)pattern));
164
165 /* Convert strings to wide chars, and call the multibyte version. */
166 n = xdupmbstowcs (&wpattern, NULL, pattern);
167 if (n == (size_t)-1)
168 /* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
169 return (internal_glob_pattern_p ((unsigned char *)pattern));
170
171 r = internal_glob_wpattern_p (wpattern);
172 free (wpattern);
173
174 return r;
175 #else
176 return (internal_glob_pattern_p (pattern));
177 #endif
178 }
179
180 #if EXTENDED_GLOB
181 /* Return 1 if all subpatterns in the extended globbing pattern PAT indicate
182 that the name should be skipped. XXX - doesn't handle pattern negation,
183 not sure if it should */
184 static int
185 extglob_skipname (pat, dname, flags)
186 char *pat, *dname;
187 int flags;
188 {
189 char *pp, *pe, *t, *se;
190 int n, r, negate, wild;
191
192 negate = *pat == '!';
193 wild = *pat == '*' || *pat == '?';
194 pp = pat + 2;
195 se = pp + strlen (pp) - 1; /* end of string */
196 pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */
197 /* we should check for invalid extglob pattern here */
198 if (pe == 0)
199 return 0;
200
201 /* if pe != se we have more of the pattern at the end of the extglob
202 pattern. Check the easy case first ( */
203 if (pe == se && *pe == ')' && (t = strchr (pp, '|')) == 0)
204 {
205 *pe = '\0';
206 #if defined (HANDLE_MULTIBYTE)
207 r = mbskipname (pp, dname, flags);
208 #else
209 r = skipname (pp, dname, flags); /*(*/
210 #endif
211 *pe = ')';
212 if (wild && pe[1]) /* if we can match zero instances, check further */
213 return (skipname (pe+1, dname, flags));
214 return r;
215 }
216
217 /* check every subpattern */
218 while (t = glob_patscan (pp, pe, '|'))
219 {
220 n = t[-1]; /* ( */
221 if (extglob_pattern_p (pp) && n == ')')
222 t[-1] = n; /* no-op for now */
223 else
224 t[-1] = '\0';
225 #if defined (HANDLE_MULTIBYTE)
226 r = mbskipname (pp, dname, flags);
227 #else
228 r = skipname (pp, dname, flags);
229 #endif
230 t[-1] = n;
231 if (r == 0) /* if any pattern says not skip, we don't skip */
232 return r;
233 pp = t;
234 } /*(*/
235
236 /* glob_patscan might find end of string */
237 if (pp == se)
238 return r;
239
240 /* but if it doesn't then we didn't match a leading dot */
241 if (wild && *pe) /* if we can match zero instances, check further */
242 return (skipname (pe, dname, flags));
243 return 1;
244 }
245 #endif
246
247 /* Return 1 if DNAME should be skipped according to PAT. Mostly concerned
248 with matching leading `.'. */
249 static int
250 skipname (pat, dname, flags)
251 char *pat;
252 char *dname;
253 int flags;
254 {
255 #if EXTENDED_GLOB
256 if (extglob_pattern_p (pat)) /* XXX */
257 return (extglob_skipname (pat, dname, flags));
258 #endif
259
260 /* If a leading dot need not be explicitly matched, and the pattern
261 doesn't start with a `.', don't match `.' or `..' */
262 if (noglob_dot_filenames == 0 && pat[0] != '.' &&
263 (pat[0] != '\\' || pat[1] != '.') &&
264 (dname[0] == '.' &&
265 (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
266 return 1;
267
268 /* If a dot must be explicitly matched, check to see if they do. */
269 else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
270 (pat[0] != '\\' || pat[1] != '.'))
271 return 1;
272
273 return 0;
274 }
275
276 #if HANDLE_MULTIBYTE
277
278 static int
279 wskipname (pat, dname, flags)
280 wchar_t *pat, *dname;
281 int flags;
282 {
283 /* If a leading dot need not be explicitly matched, and the
284 pattern doesn't start with a `.', don't match `.' or `..' */
285 if (noglob_dot_filenames == 0 && pat[0] != L'.' &&
286 (pat[0] != L'\\' || pat[1] != L'.') &&
287 (dname[0] == L'.' &&
288 (dname[1] == L'\0' || (dname[1] == L'.' && dname[2] == L'\0'))))
289 return 1;
290
291 /* If a leading dot must be explicitly matched, check to see if the
292 pattern and dirname both have one. */
293 else if (noglob_dot_filenames && dname[0] == L'.' &&
294 pat[0] != L'.' &&
295 (pat[0] != L'\\' || pat[1] != L'.'))
296 return 1;
297
298 return 0;
299 }
300
301 static int
302 wextglob_skipname (pat, dname, flags)
303 wchar_t *pat, *dname;
304 int flags;
305 {
306 #if EXTENDED_GLOB
307 wchar_t *pp, *pe, *t, n, *se;
308 int r, negate, wild;
309
310 negate = *pat == L'!';
311 wild = *pat == L'*' || *pat == L'?';
312 pp = pat + 2;
313 se = pp + wcslen (pp) - 1; /*(*/
314 pe = glob_patscan_wc (pp, se, 0);
315
316 if (pe == se && *pe == ')' && (t = wcschr (pp, L'|')) == 0)
317 {
318 *pe = L'\0';
319 r = wskipname (pp, dname, flags); /*(*/
320 *pe = L')';
321 if (wild && pe[1] != L'\0')
322 return (wskipname (pe+1, dname, flags));
323 return r;
324 }
325
326 /* check every subpattern */
327 while (t = glob_patscan_wc (pp, pe, '|'))
328 {
329 n = t[-1]; /* ( */
330 if (wextglob_pattern_p (pp) && n == L')')
331 t[-1] = n; /* no-op for now */
332 else
333 t[-1] = L'\0';
334 r = wskipname (pp, dname, flags);
335 t[-1] = n;
336 if (r == 0)
337 return 0;
338 pp = t;
339 }
340
341 if (pp == pe) /* glob_patscan_wc might find end of pattern */
342 return r;
343
344 /* but if it doesn't then we didn't match a leading dot */
345 if (wild && *pe != L'\0')
346 return (wskipname (pe, dname, flags));
347 return 1;
348 #else
349 return (wskipname (pat, dname, flags));
350 #endif
351 }
352
353 /* Return 1 if DNAME should be skipped according to PAT. Handles multibyte
354 characters in PAT and DNAME. Mostly concerned with matching leading `.'. */
355 static int
356 mbskipname (pat, dname, flags)
357 char *pat, *dname;
358 int flags;
359 {
360 int ret, ext;
361 wchar_t *pat_wc, *dn_wc;
362 size_t pat_n, dn_n;
363
364 if (mbsmbchar (dname) == 0 && mbsmbchar (pat) == 0)
365 return (skipname (pat, dname, flags));
366
367 ext = 0;
368 #if EXTENDED_GLOB
369 ext = extglob_pattern_p (pat);
370 #endif
371
372 pat_wc = dn_wc = (wchar_t *)NULL;
373
374 pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
375 if (pat_n != (size_t)-1)
376 dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
377
378 ret = 0;
379 if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
380 ret = ext ? wextglob_skipname (pat_wc, dn_wc, flags) : wskipname (pat_wc, dn_wc, flags);
381 else
382 ret = skipname (pat, dname, flags);
383
384 FREE (pat_wc);
385 FREE (dn_wc);
386
387 return ret;
388 }
389 #endif /* HANDLE_MULTIBYTE */
390
391 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
392 static void
393 udequote_pathname (pathname)
394 char *pathname;
395 {
396 register int i, j;
397
398 for (i = j = 0; pathname && pathname[i]; )
399 {
400 if (pathname[i] == '\\')
401 i++;
402
403 pathname[j++] = pathname[i++];
404
405 if (pathname[i - 1] == 0)
406 break;
407 }
408 if (pathname)
409 pathname[j] = '\0';
410 }
411
412 #if HANDLE_MULTIBYTE
413 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
414 static void
415 wdequote_pathname (pathname)
416 char *pathname;
417 {
418 mbstate_t ps;
419 size_t len, n;
420 wchar_t *wpathname;
421 int i, j;
422 wchar_t *orig_wpathname;
423
424 len = strlen (pathname);
425 /* Convert the strings into wide characters. */
426 n = xdupmbstowcs (&wpathname, NULL, pathname);
427 if (n == (size_t) -1)
428 {
429 /* Something wrong. Fall back to single-byte */
430 udequote_pathname (pathname);
431 return;
432 }
433 orig_wpathname = wpathname;
434
435 for (i = j = 0; wpathname && wpathname[i]; )
436 {
437 if (wpathname[i] == L'\\')
438 i++;
439
440 wpathname[j++] = wpathname[i++];
441
442 if (wpathname[i - 1] == L'\0')
443 break;
444 }
445 if (wpathname)
446 wpathname[j] = L'\0';
447
448 /* Convert the wide character string into unibyte character set. */
449 memset (&ps, '\0', sizeof(mbstate_t));
450 n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
451 pathname[len] = '\0';
452
453 /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
454 free (orig_wpathname);
455 }
456
457 static void
458 dequote_pathname (pathname)
459 char *pathname;
460 {
461 if (MB_CUR_MAX > 1)
462 wdequote_pathname (pathname);
463 else
464 udequote_pathname (pathname);
465 }
466 #endif /* HANDLE_MULTIBYTE */
467
468 /* Test whether NAME exists. */
469
470 #if defined (HAVE_LSTAT)
471 # define GLOB_TESTNAME(name) (lstat (name, &finfo))
472 #else /* !HAVE_LSTAT */
473 # if !defined (AFS)
474 # define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK))
475 # else /* AFS */
476 # define GLOB_TESTNAME(name) (access (name, F_OK))
477 # endif /* AFS */
478 #endif /* !HAVE_LSTAT */
479
480 /* Return 0 if DIR is a directory, -2 if DIR is a symlink, -1 otherwise. */
481 static int
482 glob_testdir (dir, flags)
483 char *dir;
484 int flags;
485 {
486 struct stat finfo;
487 int r;
488
489 /*itrace("glob_testdir: testing %s" flags = %d, dir, flags);*/
490 #if defined (HAVE_LSTAT)
491 r = (flags & GX_ALLDIRS) ? lstat (dir, &finfo) : stat (dir, &finfo);
492 #else
493 r = stat (dir, &finfo);
494 #endif
495 if (r < 0)
496 return (-1);
497
498 #if defined (S_ISLNK)
499 if (S_ISLNK (finfo.st_mode))
500 return (-2);
501 #endif
502
503 if (S_ISDIR (finfo.st_mode) == 0)
504 return (-1);
505
506 return (0);
507 }
508
509 /* Recursively scan SDIR for directories matching PAT (PAT is always `**').
510 FLAGS is simply passed down to the recursive call to glob_vector. Returns
511 a list of matching directory names. EP, if non-null, is set to the last
512 element of the returned list. NP, if non-null, is set to the number of
513 directories in the returned list. These two variables exist for the
514 convenience of the caller (always glob_vector). */
515 static struct globval *
516 finddirs (pat, sdir, flags, ep, np)
517 char *pat;
518 char *sdir;
519 int flags;
520 struct globval **ep;
521 int *np;
522 {
523 char **r, *n;
524 int ndirs;
525 struct globval *ret, *e, *g;
526
527 /*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/
528 e = ret = 0;
529 r = glob_vector (pat, sdir, flags);
530 if (r == 0 || r[0] == 0)
531 {
532 if (np)
533 *np = 0;
534 if (ep)
535 *ep = 0;
536 if (r && r != &glob_error_return)
537 free (r);
538 return (struct globval *)0;
539 }
540 for (ndirs = 0; r[ndirs] != 0; ndirs++)
541 {
542 g = (struct globval *) malloc (sizeof (struct globval));
543 if (g == 0)
544 {
545 while (ret) /* free list built so far */
546 {
547 g = ret->next;
548 free (ret);
549 ret = g;
550 }
551
552 free (r);
553 if (np)
554 *np = 0;
555 if (ep)
556 *ep = 0;
557 return (&finddirs_error_return);
558 }
559 if (e == 0)
560 e = g;
561
562 g->next = ret;
563 ret = g;
564
565 g->name = r[ndirs];
566 }
567
568 free (r);
569 if (ep)
570 *ep = e;
571 if (np)
572 *np = ndirs;
573
574 return ret;
575 }
576
577 /* Return a vector of names of files in directory DIR
578 whose names match glob pattern PAT.
579 The names are not in any particular order.
580 Wildcards at the beginning of PAT do not match an initial period.
581
582 The vector is terminated by an element that is a null pointer.
583
584 To free the space allocated, first free the vector's elements,
585 then free the vector.
586
587 Return 0 if cannot get enough memory to hold the pointer
588 and the names.
589
590 Return -1 if cannot access directory DIR.
591 Look in errno for more information. */
592
593 char **
594 glob_vector (pat, dir, flags)
595 char *pat;
596 char *dir;
597 int flags;
598 {
599 DIR *d;
600 register struct dirent *dp;
601 struct globval *lastlink, *e, *dirlist;
602 register struct globval *nextlink;
603 register char *nextname, *npat, *subdir;
604 unsigned int count;
605 int lose, skip, ndirs, isdir, sdlen, add_current, patlen;
606 register char **name_vector;
607 register unsigned int i;
608 int mflags; /* Flags passed to strmatch (). */
609 int pflags; /* flags passed to sh_makepath () */
610 int nalloca;
611 struct globval *firstmalloc, *tmplink;
612 char *convfn;
613
614 lastlink = 0;
615 count = lose = skip = add_current = 0;
616
617 firstmalloc = 0;
618 nalloca = 0;
619
620 name_vector = NULL;
621
622 /*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
623 /* If PAT is empty, skip the loop, but return one (empty) filename. */
624 if (pat == 0 || *pat == '\0')
625 {
626 if (glob_testdir (dir, 0) < 0)
627 return ((char **) &glob_error_return);
628
629 nextlink = (struct globval *)alloca (sizeof (struct globval));
630 if (nextlink == NULL)
631 return ((char **) NULL);
632
633 nextlink->next = (struct globval *)0;
634 nextname = (char *) malloc (1);
635 if (nextname == 0)
636 lose = 1;
637 else
638 {
639 lastlink = nextlink;
640 nextlink->name = nextname;
641 nextname[0] = '\0';
642 count = 1;
643 }
644
645 skip = 1;
646 }
647
648 patlen = (pat && *pat) ? strlen (pat) : 0;
649
650 /* If the filename pattern (PAT) does not contain any globbing characters,
651 we can dispense with reading the directory, and just see if there is
652 a filename `DIR/PAT'. If there is, and we can access it, just make the
653 vector to return and bail immediately. */
654 if (skip == 0 && glob_pattern_p (pat) == 0)
655 {
656 int dirlen;
657 struct stat finfo;
658
659 if (glob_testdir (dir, 0) < 0)
660 return ((char **) &glob_error_return);
661
662 dirlen = strlen (dir);
663 nextname = (char *)malloc (dirlen + patlen + 2);
664 npat = (char *)malloc (patlen + 1);
665 if (nextname == 0 || npat == 0)
666 {
667 FREE (nextname);
668 FREE (npat);
669 lose = 1;
670 }
671 else
672 {
673 strcpy (npat, pat);
674 dequote_pathname (npat);
675
676 strcpy (nextname, dir);
677 nextname[dirlen++] = '/';
678 strcpy (nextname + dirlen, npat);
679
680 if (GLOB_TESTNAME (nextname) >= 0)
681 {
682 free (nextname);
683 nextlink = (struct globval *)alloca (sizeof (struct globval));
684 if (nextlink)
685 {
686 nextlink->next = (struct globval *)0;
687 lastlink = nextlink;
688 nextlink->name = npat;
689 count = 1;
690 }
691 else
692 {
693 free (npat);
694 lose = 1;
695 }
696 }
697 else
698 {
699 free (nextname);
700 free (npat);
701 }
702 }
703
704 skip = 1;
705 }
706
707 if (skip == 0)
708 {
709 /* Open the directory, punting immediately if we cannot. If opendir
710 is not robust (i.e., it opens non-directories successfully), test
711 that DIR is a directory and punt if it's not. */
712 #if defined (OPENDIR_NOT_ROBUST)
713 if (glob_testdir (dir, 0) < 0)
714 return ((char **) &glob_error_return);
715 #endif
716
717 d = opendir (dir);
718 if (d == NULL)
719 return ((char **) &glob_error_return);
720
721 /* Compute the flags that will be passed to strmatch(). We don't
722 need to do this every time through the loop. */
723 mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
724
725 #ifdef FNM_CASEFOLD
726 if (glob_ignore_case)
727 mflags |= FNM_CASEFOLD;
728 #endif
729
730 if (extended_glob)
731 mflags |= FNM_EXTMATCH;
732
733 add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR));
734
735 /* Scan the directory, finding all names that match.
736 For each name that matches, allocate a struct globval
737 on the stack and store the name in it.
738 Chain those structs together; lastlink is the front of the chain. */
739 while (1)
740 {
741 /* Make globbing interruptible in the shell. */
742 if (interrupt_state || terminating_signal)
743 {
744 lose = 1;
745 break;
746 }
747 else if (signal_is_pending (SIGINT)) /* XXX - make SIGINT traps responsive */
748 {
749 lose = 1;
750 break;
751 }
752
753 dp = readdir (d);
754 if (dp == NULL)
755 break;
756
757 /* If this directory entry is not to be used, try again. */
758 if (REAL_DIR_ENTRY (dp) == 0)
759 continue;
760
761 #if 0
762 if (dp->d_name == 0 || *dp->d_name == 0)
763 continue;
764 #endif
765
766 #if HANDLE_MULTIBYTE
767 if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags))
768 continue;
769 else
770 #endif
771 if (skipname (pat, dp->d_name, flags))
772 continue;
773
774 /* If we're only interested in directories, don't bother with files */
775 if (flags & (GX_MATCHDIRS|GX_ALLDIRS))
776 {
777 pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0;
778 if (flags & GX_NULLDIR)
779 pflags |= MP_IGNDOT;
780 subdir = sh_makepath (dir, dp->d_name, pflags);
781 isdir = glob_testdir (subdir, flags);
782 if (isdir < 0 && (flags & GX_MATCHDIRS))
783 {
784 free (subdir);
785 continue;
786 }
787 }
788
789 if (flags & GX_ALLDIRS)
790 {
791 if (isdir == 0)
792 {
793 dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs);
794 if (dirlist == &finddirs_error_return)
795 {
796 free (subdir);
797 lose = 1;
798 break;
799 }
800 if (ndirs) /* add recursive directories to list */
801 {
802 if (firstmalloc == 0)
803 firstmalloc = e;
804 e->next = lastlink;
805 lastlink = dirlist;
806 count += ndirs;
807 }
808 }
809
810 /* When FLAGS includes GX_ALLDIRS, we want to skip a symlink
811 to a directory, since we will pick the directory up later. */
812 if (isdir == -2 && glob_testdir (subdir, 0) == 0)
813 {
814 free (subdir);
815 continue;
816 }
817
818 /* XXX - should we even add this if it's not a directory? */
819 nextlink = (struct globval *) malloc (sizeof (struct globval));
820 if (firstmalloc == 0)
821 firstmalloc = nextlink;
822 sdlen = strlen (subdir);
823 nextname = (char *) malloc (sdlen + 1);
824 if (nextlink == 0 || nextname == 0)
825 {
826 FREE (nextlink);
827 FREE (nextname);
828 free (subdir);
829 lose = 1;
830 break;
831 }
832 nextlink->next = lastlink;
833 lastlink = nextlink;
834 nextlink->name = nextname;
835 bcopy (subdir, nextname, sdlen + 1);
836 free (subdir);
837 ++count;
838 continue;
839 }
840 else if (flags & GX_MATCHDIRS)
841 free (subdir);
842
843 convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp));
844 if (strmatch (pat, convfn, mflags) != FNM_NOMATCH)
845 {
846 if (nalloca < ALLOCA_MAX)
847 {
848 nextlink = (struct globval *) alloca (sizeof (struct globval));
849 nalloca += sizeof (struct globval);
850 }
851 else
852 {
853 nextlink = (struct globval *) malloc (sizeof (struct globval));
854 if (firstmalloc == 0)
855 firstmalloc = nextlink;
856 }
857
858 nextname = (char *) malloc (D_NAMLEN (dp) + 1);
859 if (nextlink == 0 || nextname == 0)
860 {
861 FREE (nextlink);
862 FREE (nextname);
863 lose = 1;
864 break;
865 }
866 nextlink->next = lastlink;
867 lastlink = nextlink;
868 nextlink->name = nextname;
869 bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
870 ++count;
871 }
872 }
873
874 (void) closedir (d);
875 }
876
877 /* compat: if GX_ADDCURDIR, add the passed directory also. Add an empty
878 directory name as a placeholder if GX_NULLDIR (in which case the passed
879 directory name is "."). */
880 if (add_current)
881 {
882 sdlen = strlen (dir);
883 nextname = (char *)malloc (sdlen + 1);
884 nextlink = (struct globval *) malloc (sizeof (struct globval));
885 if (nextlink == 0 || nextname == 0)
886 {
887 FREE (nextlink);
888 FREE (nextname);
889 lose = 1;
890 }
891 else
892 {
893 nextlink->name = nextname;
894 nextlink->next = lastlink;
895 lastlink = nextlink;
896 if (flags & GX_NULLDIR)
897 nextname[0] = '\0';
898 else
899 bcopy (dir, nextname, sdlen + 1);
900 ++count;
901 }
902 }
903
904 if (lose == 0)
905 {
906 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
907 lose |= name_vector == NULL;
908 }
909
910 /* Have we run out of memory? */
911 if (lose)
912 {
913 tmplink = 0;
914
915 /* Here free the strings we have got. */
916 while (lastlink)
917 {
918 /* Since we build the list in reverse order, the first N entries
919 will be allocated with malloc, if firstmalloc is set, from
920 lastlink to firstmalloc. */
921 if (firstmalloc)
922 {
923 if (lastlink == firstmalloc)
924 firstmalloc = 0;
925 tmplink = lastlink;
926 }
927 else
928 tmplink = 0;
929 free (lastlink->name);
930 lastlink = lastlink->next;
931 FREE (tmplink);
932 }
933
934 /* Don't call QUIT; here; let higher layers deal with it. */
935
936 return ((char **)NULL);
937 }
938
939 /* Copy the name pointers from the linked list into the vector. */
940 for (tmplink = lastlink, i = 0; i < count; ++i)
941 {
942 name_vector[i] = tmplink->name;
943 tmplink = tmplink->next;
944 }
945
946 name_vector[count] = NULL;
947
948 /* If we allocated some of the struct globvals, free them now. */
949 if (firstmalloc)
950 {
951 tmplink = 0;
952 while (lastlink)
953 {
954 tmplink = lastlink;
955 if (lastlink == firstmalloc)
956 lastlink = firstmalloc = 0;
957 else
958 lastlink = lastlink->next;
959 free (tmplink);
960 }
961 }
962
963 return (name_vector);
964 }
965
966 /* Return a new array which is the concatenation of each string in ARRAY
967 to DIR. This function expects you to pass in an allocated ARRAY, and
968 it takes care of free()ing that array. Thus, you might think of this
969 function as side-effecting ARRAY. This should handle GX_MARKDIRS. */
970 static char **
971 glob_dir_to_array (dir, array, flags)
972 char *dir, **array;
973 int flags;
974 {
975 register unsigned int i, l;
976 int add_slash;
977 char **result, *new;
978 struct stat sb;
979
980 l = strlen (dir);
981 if (l == 0)
982 {
983 if (flags & GX_MARKDIRS)
984 for (i = 0; array[i]; i++)
985 {
986 if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
987 {
988 l = strlen (array[i]);
989 new = (char *)realloc (array[i], l + 2);
990 if (new == 0)
991 return NULL;
992 new[l] = '/';
993 new[l+1] = '\0';
994 array[i] = new;
995 }
996 }
997 return (array);
998 }
999
1000 add_slash = dir[l - 1] != '/';
1001
1002 i = 0;
1003 while (array[i] != NULL)
1004 ++i;
1005
1006 result = (char **) malloc ((i + 1) * sizeof (char *));
1007 if (result == NULL)
1008 return (NULL);
1009
1010 for (i = 0; array[i] != NULL; i++)
1011 {
1012 /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
1013 result[i] = (char *) malloc (l + strlen (array[i]) + 3);
1014
1015 if (result[i] == NULL)
1016 {
1017 int ind;
1018 for (ind = 0; ind < i; ind++)
1019 free (result[ind]);
1020 free (result);
1021 return (NULL);
1022 }
1023
1024 strcpy (result[i], dir);
1025 if (add_slash)
1026 result[i][l] = '/';
1027 strcpy (result[i] + l + add_slash, array[i]);
1028 if (flags & GX_MARKDIRS)
1029 {
1030 if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
1031 {
1032 size_t rlen;
1033 rlen = strlen (result[i]);
1034 result[i][rlen] = '/';
1035 result[i][rlen+1] = '\0';
1036 }
1037 }
1038 }
1039 result[i] = NULL;
1040
1041 /* Free the input array. */
1042 for (i = 0; array[i] != NULL; i++)
1043 free (array[i]);
1044 free ((char *) array);
1045
1046 return (result);
1047 }
1048
1049 /* Do globbing on PATHNAME. Return an array of pathnames that match,
1050 marking the end of the array with a null-pointer as an element.
1051 If no pathnames match, then the array is empty (first element is null).
1052 If there isn't enough memory, then return NULL.
1053 If a file system error occurs, return -1; `errno' has the error code. */
1054 char **
1055 glob_filename (pathname, flags)
1056 char *pathname;
1057 int flags;
1058 {
1059 char **result, **new_result;
1060 unsigned int result_size;
1061 char *directory_name, *filename, *dname, *fn;
1062 unsigned int directory_len;
1063 int free_dirname; /* flag */
1064 int dflags, hasglob;
1065
1066 result = (char **) malloc (sizeof (char *));
1067 result_size = 1;
1068 if (result == NULL)
1069 return (NULL);
1070
1071 result[0] = NULL;
1072
1073 directory_name = NULL;
1074
1075 /* Find the filename. */
1076 filename = strrchr (pathname, '/');
1077 #if defined (EXTENDED_GLOB)
1078 if (filename && extended_glob)
1079 {
1080 fn = glob_dirscan (pathname, '/');
1081 #if DEBUG_MATCHING
1082 if (fn != filename)
1083 fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename);
1084 #endif
1085 filename = fn;
1086 }
1087 #endif
1088
1089 if (filename == NULL)
1090 {
1091 filename = pathname;
1092 directory_name = "";
1093 directory_len = 0;
1094 free_dirname = 0;
1095 }
1096 else
1097 {
1098 directory_len = (filename - pathname) + 1;
1099 directory_name = (char *) malloc (directory_len + 1);
1100
1101 if (directory_name == 0) /* allocation failed? */
1102 {
1103 free (result);
1104 return (NULL);
1105 }
1106
1107 bcopy (pathname, directory_name, directory_len);
1108 directory_name[directory_len] = '\0';
1109 ++filename;
1110 free_dirname = 1;
1111 }
1112
1113 hasglob = 0;
1114 /* If directory_name contains globbing characters, then we
1115 have to expand the previous levels. Just recurse.
1116 If glob_pattern_p returns != [0,1] we have a pattern that has backslash
1117 quotes but no unquoted glob pattern characters. We dequote it below. */
1118 if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1)
1119 {
1120 char **directories, *d, *p;
1121 register unsigned int i;
1122 int all_starstar, last_starstar;
1123
1124 all_starstar = last_starstar = 0;
1125 d = directory_name;
1126 dflags = flags & ~GX_MARKDIRS;
1127 /* Collapse a sequence of ** patterns separated by one or more slashes
1128 to a single ** terminated by a slash or NUL */
1129 if ((flags & GX_GLOBSTAR) && d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0'))
1130 {
1131 p = d;
1132 while (d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0'))
1133 {
1134 p = d;
1135 if (d[2])
1136 {
1137 d += 3;
1138 while (*d == '/')
1139 d++;
1140 if (*d == 0)
1141 break;
1142 }
1143 }
1144 if (*d == 0)
1145 all_starstar = 1;
1146 d = p;
1147 dflags |= GX_ALLDIRS|GX_ADDCURDIR;
1148 directory_len = strlen (d);
1149 }
1150
1151 /* If there is a non [star][star]/ component in directory_name, we
1152 still need to collapse trailing sequences of [star][star]/ into
1153 a single one and note that the directory name ends with [star][star],
1154 so we can compensate if filename is [star][star] */
1155 if ((flags & GX_GLOBSTAR) && all_starstar == 0)
1156 {
1157 int dl, prev;
1158 prev = dl = directory_len;
1159 while (dl >= 4 && d[dl - 1] == '/' &&
1160 d[dl - 2] == '*' &&
1161 d[dl - 3] == '*' &&
1162 d[dl - 4] == '/')
1163 prev = dl, dl -= 3;
1164 if (dl != directory_len)
1165 last_starstar = 1;
1166 directory_len = prev;
1167 }
1168
1169 /* If the directory name ends in [star][star]/ but the filename is
1170 [star][star], just remove the final [star][star] from the directory
1171 so we don't have to scan everything twice. */
1172 if (last_starstar && directory_len > 4 &&
1173 filename[0] == '*' && filename[1] == '*' && filename[2] == 0)
1174 {
1175 directory_len -= 3;
1176 }
1177
1178 if (d[directory_len - 1] == '/')
1179 d[directory_len - 1] = '\0';
1180
1181 directories = glob_filename (d, dflags|GX_RECURSE);
1182
1183 if (free_dirname)
1184 {
1185 free (directory_name);
1186 directory_name = NULL;
1187 }
1188
1189 if (directories == NULL)
1190 goto memory_error;
1191 else if (directories == (char **)&glob_error_return)
1192 {
1193 free ((char *) result);
1194 return ((char **) &glob_error_return);
1195 }
1196 else if (*directories == NULL)
1197 {
1198 free ((char *) directories);
1199 free ((char *) result);
1200 return ((char **) &glob_error_return);
1201 }
1202
1203 /* If we have something like [star][star]/[star][star], it's no use to
1204 glob **, then do it again, and throw half the results away. */
1205 if (all_starstar && filename[0] == '*' && filename[1] == '*' && filename[2] == 0)
1206 {
1207 free ((char *) directories);
1208 free (directory_name);
1209 directory_name = NULL;
1210 directory_len = 0;
1211 goto only_filename;
1212 }
1213
1214 /* We have successfully globbed the preceding directory name.
1215 For each name in DIRECTORIES, call glob_vector on it and
1216 FILENAME. Concatenate the results together. */
1217 for (i = 0; directories[i] != NULL; ++i)
1218 {
1219 char **temp_results;
1220 int shouldbreak;
1221
1222 shouldbreak = 0;
1223 /* XXX -- we've recursively scanned any directories resulting from
1224 a `**', so turn off the flag. We turn it on again below if
1225 filename is `**' */
1226 /* Scan directory even on a NULL filename. That way, `*h/'
1227 returns only directories ending in `h', instead of all
1228 files ending in `h' with a `/' appended. */
1229 dname = directories[i];
1230 dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
1231 if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
1232 dflags |= GX_ALLDIRS|GX_ADDCURDIR;
1233 if (dname[0] == '\0' && filename[0])
1234 {
1235 dflags |= GX_NULLDIR;
1236 dname = "."; /* treat null directory name and non-null filename as current directory */
1237 }
1238 temp_results = glob_vector (filename, dname, dflags);
1239
1240 /* Handle error cases. */
1241 if (temp_results == NULL)
1242 goto memory_error;
1243 else if (temp_results == (char **)&glob_error_return)
1244 /* This filename is probably not a directory. Ignore it. */
1245 ;
1246 else
1247 {
1248 char **array;
1249 register unsigned int l;
1250
1251 /* If we're expanding **, we don't need to glue the directory
1252 name to the results; we've already done it in glob_vector */
1253 if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && (filename[2] == '\0' || filename[2] == '/'))
1254 {
1255 /* When do we remove null elements from temp_results? And
1256 how to avoid duplicate elements in the final result? */
1257 /* If (dflags & GX_NULLDIR) glob_filename potentially left a
1258 NULL placeholder in the temp results just in case
1259 glob_vector/glob_dir_to_array did something with it, but
1260 if it didn't, and we're not supposed to be passing them
1261 through for some reason ((flags & GX_NULLDIR) == 0) we
1262 need to remove all the NULL elements from the beginning
1263 of TEMP_RESULTS. */
1264 /* If we have a null directory name and ** as the filename,
1265 we have just searched for everything from the current
1266 directory on down. Break now (shouldbreak = 1) to avoid
1267 duplicate entries in the final result. */
1268 #define NULL_PLACEHOLDER(x) ((x) && *(x) && **(x) == 0)
1269 if ((dflags & GX_NULLDIR) && (flags & GX_NULLDIR) == 0 &&
1270 NULL_PLACEHOLDER (temp_results))
1271 #undef NULL_PLACEHOLDER
1272 {
1273 register int i, n;
1274 for (n = 0; temp_results[n] && *temp_results[n] == 0; n++)
1275 ;
1276 i = n;
1277 do
1278 temp_results[i - n] = temp_results[i];
1279 while (temp_results[i++] != 0);
1280 array = temp_results;
1281 shouldbreak = 1;
1282 }
1283 else
1284 array = temp_results;
1285 }
1286 else
1287 array = glob_dir_to_array (directories[i], temp_results, flags);
1288 l = 0;
1289 while (array[l] != NULL)
1290 ++l;
1291
1292 new_result = (char **)realloc (result, (result_size + l) * sizeof (char *));
1293
1294 if (new_result == NULL)
1295 {
1296 for (l = 0; array[l]; ++l)
1297 free (array[l]);
1298 free ((char *)array);
1299 goto memory_error;
1300 }
1301 result = new_result;
1302
1303 for (l = 0; array[l] != NULL; ++l)
1304 result[result_size++ - 1] = array[l];
1305
1306 result[result_size - 1] = NULL;
1307
1308 /* Note that the elements of ARRAY are not freed. */
1309 if (array != temp_results)
1310 free ((char *) array);
1311 else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
1312 free (temp_results); /* expanding ** case above */
1313
1314 if (shouldbreak)
1315 break;
1316 }
1317 }
1318 /* Free the directories. */
1319 for (i = 0; directories[i]; i++)
1320 free (directories[i]);
1321
1322 free ((char *) directories);
1323
1324 return (result);
1325 }
1326
1327 only_filename:
1328 /* If there is only a directory name, return it. */
1329 if (*filename == '\0')
1330 {
1331 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
1332 if (result == NULL)
1333 {
1334 if (free_dirname)
1335 free (directory_name);
1336 return (NULL);
1337 }
1338 /* If we have a directory name with quoted characters, and we are
1339 being called recursively to glob the directory portion of a pathname,
1340 we need to dequote the directory name before returning it so the
1341 caller can read the directory */
1342 if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0)
1343 {
1344 dequote_pathname (directory_name);
1345 directory_len = strlen (directory_name);
1346 }
1347
1348 /* We could check whether or not the dequoted directory_name is a
1349 directory and return it here, returning the original directory_name
1350 if not, but we don't do that yet. I'm not sure it matters. */
1351
1352 /* Handle GX_MARKDIRS here. */
1353 result[0] = (char *) malloc (directory_len + 1);
1354 if (result[0] == NULL)
1355 goto memory_error;
1356 bcopy (directory_name, result[0], directory_len + 1);
1357 if (free_dirname)
1358 free (directory_name);
1359 result[1] = NULL;
1360 return (result);
1361 }
1362 else
1363 {
1364 char **temp_results;
1365
1366 /* There are no unquoted globbing characters in DIRECTORY_NAME.
1367 Dequote it before we try to open the directory since there may
1368 be quoted globbing characters which should be treated verbatim. */
1369 if (directory_len > 0)
1370 dequote_pathname (directory_name);
1371
1372 /* We allocated a small array called RESULT, which we won't be using.
1373 Free that memory now. */
1374 free (result);
1375
1376 /* Just return what glob_vector () returns appended to the
1377 directory name. */
1378 /* If flags & GX_ALLDIRS, we're called recursively */
1379 dflags = flags & ~GX_MARKDIRS;
1380 if (directory_len == 0)
1381 dflags |= GX_NULLDIR;
1382 if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
1383 {
1384 dflags |= GX_ALLDIRS|GX_ADDCURDIR;
1385 #if 0
1386 /* If we want all directories (dflags & GX_ALLDIRS) and we're not
1387 being called recursively as something like `echo [star][star]/[star].o'
1388 ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from
1389 adding a null directory name to the front of the temp_results
1390 array. We turn off ADDCURDIR if not called recursively and
1391 dlen == 0 */
1392 #endif
1393 if (directory_len == 0 && (flags & GX_ALLDIRS) == 0)
1394 dflags &= ~GX_ADDCURDIR;
1395 }
1396 temp_results = glob_vector (filename,
1397 (directory_len == 0 ? "." : directory_name),
1398 dflags);
1399
1400 if (temp_results == NULL || temp_results == (char **)&glob_error_return)
1401 {
1402 if (free_dirname)
1403 free (directory_name);
1404 QUIT; /* XXX - shell */
1405 run_pending_traps ();
1406 return (temp_results);
1407 }
1408
1409 result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags);
1410
1411 if (free_dirname)
1412 free (directory_name);
1413 return (result);
1414 }
1415
1416 /* We get to memory_error if the program has run out of memory, or
1417 if this is the shell, and we have been interrupted. */
1418 memory_error:
1419 if (result != NULL)
1420 {
1421 register unsigned int i;
1422 for (i = 0; result[i] != NULL; ++i)
1423 free (result[i]);
1424 free ((char *) result);
1425 }
1426
1427 if (free_dirname && directory_name)
1428 free (directory_name);
1429
1430 QUIT;
1431 run_pending_traps ();
1432
1433 return (NULL);
1434 }
1435
1436 #if defined (TEST)
1437
1438 main (argc, argv)
1439 int argc;
1440 char **argv;
1441 {
1442 unsigned int i;
1443
1444 for (i = 1; i < argc; ++i)
1445 {
1446 char **value = glob_filename (argv[i], 0);
1447 if (value == NULL)
1448 puts ("Out of memory.");
1449 else if (value == &glob_error_return)
1450 perror (argv[i]);
1451 else
1452 for (i = 0; value[i] != NULL; i++)
1453 puts (value[i]);
1454 }
1455
1456 exit (0);
1457 }
1458 #endif /* TEST. */