6a9679fc8365c57027d57eea4e89776752e10ef2
[platform/upstream/bash.git] / lib / glob / glob.c
1 /* File-name wildcard pattern matching for GNU.
2    Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 1, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 /* To whomever it may concern: I have never seen the code which most
19    Unix programs use to perform this function.  I wrote this from scratch
20    based on specifications for the pattern matching.  --RMS.  */
21
22 #include <config.h>
23
24 #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
25   #pragma alloca
26 #endif /* _AIX && RISC6000 && !__GNUC__ */
27
28 #if defined (SHELL)
29 #  include "bashtypes.h"
30 #else
31 #  include <sys/types.h>
32 #endif
33
34 #if defined (HAVE_UNISTD_H)
35 #  include <unistd.h>
36 #endif
37
38 #if defined (SHELL)
39 #  include "bashansi.h"
40 #else
41 #  if defined (HAVE_STDLIB_H)
42 #    include <stdlib.h>
43 #  endif
44 #  if defined (HAVE_STRING_H)
45 #    include <string.h>
46 #  else /* !HAVE_STRING_H */
47 #    include <strings.h>
48 #  endif /* !HAVE_STRING_H */
49 #endif
50
51 #if defined (HAVE_DIRENT_H)
52 #  include <dirent.h>
53 #  define D_NAMLEN(d) strlen ((d)->d_name)
54 #else /* !HAVE_DIRENT_H */
55 #  define D_NAMLEN(d) ((d)->d_namlen)
56 #  if defined (HAVE_SYS_NDIR_H)
57 #    include <sys/ndir.h>
58 #  endif
59 #  if defined (HAVE_SYS_DIR_H)
60 #    include <sys/dir.h>
61 #  endif /* HAVE_SYS_DIR_H */
62 #  if defined (HAVE_NDIR_H)
63 #    include <ndir.h>
64 #  endif
65 #  if !defined (dirent)
66 #    define dirent direct
67 #  endif
68 #endif /* !HAVE_DIRENT_H */
69
70 #if defined (_POSIX_SOURCE)
71 /* Posix does not require that the d_ino field be present, and some
72    systems do not provide it. */
73 #  define REAL_DIR_ENTRY(dp) 1
74 #else
75 #  define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
76 #endif /* _POSIX_SOURCE */
77
78 #if !defined (HAVE_BCOPY)
79 #  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
80 #endif /* !HAVE_BCOPY */
81
82 #if defined (SHELL)
83 #  include "posixstat.h"
84 #else /* !SHELL */
85 #  include <sys/stat.h>
86 #endif /* !SHELL */
87
88 #include "filecntl.h"
89 #if !defined (F_OK)
90 #  define F_OK 0
91 #endif
92
93 #if defined (SHELL)
94 #  include "memalloc.h"
95 #endif
96
97 #include "fnmatch.h"
98
99 #if !defined (HAVE_STDLIB_H) && !defined (SHELL)
100 extern char *malloc (), *realloc ();
101 extern void free ();
102 #endif /* !HAVE_STDLIB_H */
103
104 #if !defined (NULL)
105 #  if defined (__STDC__)
106 #    define NULL ((void *) 0)
107 #  else
108 #    define NULL 0x0
109 #  endif /* __STDC__ */
110 #endif /* !NULL */
111
112 #if defined (SHELL)
113 extern void throw_to_top_level ();
114 extern int test_eaccess ();
115
116 extern int interrupt_state;
117 extern int extended_glob;
118 #endif /* SHELL */
119
120 /* Global variable which controls whether or not * matches .*.
121    Non-zero means don't match .*.  */
122 int noglob_dot_filenames = 1;
123
124 /* Global variable which controls whether or not filename globbing
125    is done without regard to case. */
126 int glob_ignore_case = 0;
127
128 /* Global variable to return to signify an error in globbing. */
129 char *glob_error_return;
130
131 /* Return nonzero if PATTERN has any special globbing chars in it.  */
132 int
133 glob_pattern_p (pattern)
134      char *pattern;
135 {
136   register char *p;
137   register char c;
138   int bopen;
139
140   p = pattern;
141   bopen = 0;
142
143   while ((c = *p++) != '\0')
144     switch (c)
145       {
146       case '?':
147       case '*':
148         return (1);
149
150       case '[':         /* Only accept an open brace if there is a close */
151         bopen++;        /* brace to match it.  Bracket expressions must be */
152         continue;       /* complete, according to Posix.2 */
153       case ']':
154         if (bopen)
155           return (1);
156         continue;      
157
158       case '+':         /* extended matching operators */
159       case '@':
160       case '!':
161         if (*p == '(')  /*) */
162           return (1);
163         continue;
164
165       case '\\':
166         if (*p++ == '\0')
167           return (0);
168       }
169
170   return (0);
171 }
172
173 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
174 static void
175 dequote_pathname (pathname)
176      char *pathname;
177 {
178   register int i, j;
179
180   for (i = j = 0; pathname && pathname[i]; )
181     {
182       if (pathname[i] == '\\')
183         i++;
184
185       pathname[j++] = pathname[i++];
186
187       if (!pathname[i - 1])
188         break;
189     }
190   pathname[j] = '\0';
191 }
192
193 \f
194
195 /* Test whether NAME exists. */
196
197 #if defined (HAVE_LSTAT)
198 #  define GLOB_TESTNAME(name)  (lstat (name, &finfo))
199 #else /* !HAVE_LSTAT */
200 #  if defined (SHELL) && !defined (AFS)
201 #    define GLOB_TESTNAME(name)  (test_eaccess (nextname, F_OK))
202 #  else /* !SHELL || AFS */
203 #    define GLOB_TESTNAME(name)  (access (nextname, F_OK))
204 #  endif /* !SHELL || AFS */
205 #endif /* !HAVE_LSTAT */
206
207 /* Return 0 if DIR is a directory, -1 otherwise. */
208 static int
209 glob_testdir (dir)
210      char *dir;
211 {
212   struct stat finfo;
213
214   if (stat (dir, &finfo) < 0)
215     return (-1);
216
217   if (S_ISDIR (finfo.st_mode) == 0)
218     return (-1);
219
220   return (0);
221 }
222
223 /* Return a vector of names of files in directory DIR
224    whose names match glob pattern PAT.
225    The names are not in any particular order.
226    Wildcards at the beginning of PAT do not match an initial period.
227
228    The vector is terminated by an element that is a null pointer.
229
230    To free the space allocated, first free the vector's elements,
231    then free the vector.
232
233    Return 0 if cannot get enough memory to hold the pointer
234    and the names.
235
236    Return -1 if cannot access directory DIR.
237    Look in errno for more information.  */
238
239 char **
240 glob_vector (pat, dir)
241      char *pat;
242      char *dir;
243 {
244   struct globval
245     {
246       struct globval *next;
247       char *name;
248     };
249
250   DIR *d;
251   register struct dirent *dp;
252   struct globval *lastlink;
253   register struct globval *nextlink;
254   register char *nextname;
255   unsigned int count;
256   int lose, skip;
257   register char **name_vector;
258   register unsigned int i;
259   int flags;            /* Flags passed to fnmatch (). */
260
261   lastlink = 0;
262   count = lose = skip = 0;
263
264   /* If PAT is empty, skip the loop, but return one (empty) filename. */
265   if (pat == 0 || *pat == '\0')
266     {
267       if (glob_testdir (dir) < 0)
268         return ((char **) &glob_error_return);
269
270       nextlink = (struct globval *)alloca (sizeof (struct globval));
271       nextlink->next = (struct globval *)0;
272       nextname = (char *) malloc (1);
273       if (nextname == 0)
274         lose = 1;
275       else
276         {
277           lastlink = nextlink;
278           nextlink->name = nextname;
279           nextname[0] = '\0';
280           count = 1;
281         }
282
283       skip = 1;
284     }
285
286   /* If the filename pattern (PAT) does not contain any globbing characters,
287      we can dispense with reading the directory, and just see if there is
288      a filename `DIR/PAT'.  If there is, and we can access it, just make the
289      vector to return and bail immediately. */
290   if (skip == 0 && glob_pattern_p (pat) == 0)
291     {
292       int dirlen;
293       struct stat finfo;
294
295       if (glob_testdir (dir) < 0)
296         return ((char **) &glob_error_return);
297
298       dirlen = strlen (dir);
299       nextname = (char *)malloc (dirlen + strlen (pat) + 2);
300       if (nextname == 0)
301         lose = 1;
302       else
303         {
304           strcpy (nextname, dir);
305           nextname[dirlen++] = '/';
306           strcpy (nextname + dirlen, pat);
307
308           if (GLOB_TESTNAME (nextname) >= 0)
309             {
310               free (nextname);
311               nextlink = (struct globval *)alloca (sizeof (struct globval));
312               nextlink->next = (struct globval *)0;
313               nextname = (char *) malloc (strlen (pat) + 1);
314               if (nextname == 0)
315                 lose = 1;
316               else
317                 {
318                   lastlink = nextlink;
319                   nextlink->name = nextname;
320                   strcpy (nextname, pat);
321                   count = 1;
322                 }
323             }
324           else
325             free (nextname);
326         }
327
328       skip = 1;
329     }
330
331   if (skip == 0)
332     {
333       /* Open the directory, punting immediately if we cannot.  If opendir
334          is not robust (i.e., it opens non-directories successfully), test
335          that DIR is a directory and punt if it's not. */
336 #if defined (OPENDIR_NOT_ROBUST)
337       if (glob_testdir (dir) < 0)
338         return ((char **) &glob_error_return);
339 #endif
340
341       d = opendir (dir);
342       if (d == NULL)
343         return ((char **) &glob_error_return);
344
345       /* Compute the flags that will be passed to fnmatch().  We don't
346          need to do this every time through the loop. */
347       flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
348
349 #ifdef FNM_CASEFOLD
350       if (glob_ignore_case)
351         flags |= FNM_CASEFOLD;
352 #endif
353
354 #ifdef SHELL
355       if (extended_glob)
356         flags |= FNM_EXTMATCH;
357 #endif
358
359       /* Scan the directory, finding all names that match.
360          For each name that matches, allocate a struct globval
361          on the stack and store the name in it.
362          Chain those structs together; lastlink is the front of the chain.  */
363       while (1)
364         {
365 #if defined (SHELL)
366           /* Make globbing interruptible in the shell. */
367           if (interrupt_state)
368             {
369               lose = 1;
370               break;
371             }
372 #endif /* SHELL */
373           
374           dp = readdir (d);
375           if (dp == NULL)
376             break;
377
378           /* If this directory entry is not to be used, try again. */
379           if (REAL_DIR_ENTRY (dp) == 0)
380             continue;
381
382           /* If a dot must be explicity matched, check to see if they do. */
383           if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
384                 (pat[0] != '\\' || pat[1] != '.'))
385             continue;
386
387           if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
388             {
389               nextlink = (struct globval *) alloca (sizeof (struct globval));
390               nextlink->next = lastlink;
391               nextname = (char *) malloc (D_NAMLEN (dp) + 1);
392               if (nextname == NULL)
393                 {
394                   lose = 1;
395                   break;
396                 }
397               lastlink = nextlink;
398               nextlink->name = nextname;
399               bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
400               ++count;
401             }
402         }
403
404       (void) closedir (d);
405     }
406
407   if (lose == 0)
408     {
409       name_vector = (char **) malloc ((count + 1) * sizeof (char *));
410       lose |= name_vector == NULL;
411     }
412
413   /* Have we run out of memory?  */
414   if (lose)
415     {
416       /* Here free the strings we have got.  */
417       while (lastlink)
418         {
419           free (lastlink->name);
420           lastlink = lastlink->next;
421         }
422 #if defined (SHELL)
423       if (interrupt_state)
424         throw_to_top_level ();
425 #endif /* SHELL */
426
427       return ((char **)NULL);
428     }
429
430   /* Copy the name pointers from the linked list into the vector.  */
431   for (i = 0; i < count; ++i)
432     {
433       name_vector[i] = lastlink->name;
434       lastlink = lastlink->next;
435     }
436
437   name_vector[count] = NULL;
438   return (name_vector);
439 }
440 \f
441 /* Return a new array which is the concatenation of each string in ARRAY
442    to DIR.  This function expects you to pass in an allocated ARRAY, and
443    it takes care of free()ing that array.  Thus, you might think of this
444    function as side-effecting ARRAY. */
445 static char **
446 glob_dir_to_array (dir, array)
447      char *dir, **array;
448 {
449   register unsigned int i, l;
450   int add_slash;
451   char **result;
452
453   l = strlen (dir);
454   if (l == 0)
455     return (array);
456
457   add_slash = dir[l - 1] != '/';
458
459   i = 0;
460   while (array[i] != NULL)
461     ++i;
462
463   result = (char **) malloc ((i + 1) * sizeof (char *));
464   if (result == NULL)
465     return (NULL);
466
467   for (i = 0; array[i] != NULL; i++)
468     {
469       result[i] = (char *) malloc (l + (add_slash ? 1 : 0)
470                                    + strlen (array[i]) + 1);
471       if (result[i] == NULL)
472         return (NULL);
473 #if 1
474       strcpy (result[i], dir);
475       if (add_slash)
476         result[i][l] = '/';
477       strcpy (result[i] + l + add_slash, array[i]);
478 #else
479       (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
480 #endif
481     }
482   result[i] = NULL;
483
484   /* Free the input array.  */
485   for (i = 0; array[i] != NULL; i++)
486     free (array[i]);
487   free ((char *) array);
488
489   return (result);
490 }
491 \f
492 /* Do globbing on PATHNAME.  Return an array of pathnames that match,
493    marking the end of the array with a null-pointer as an element.
494    If no pathnames match, then the array is empty (first element is null).
495    If there isn't enough memory, then return NULL.
496    If a file system error occurs, return -1; `errno' has the error code.  */
497 char **
498 glob_filename (pathname)
499      char *pathname;
500 {
501   char **result;
502   unsigned int result_size;
503   char *directory_name, *filename;
504   unsigned int directory_len;
505
506   result = (char **) malloc (sizeof (char *));
507   result_size = 1;
508   if (result == NULL)
509     return (NULL);
510
511   result[0] = NULL;
512
513   /* Find the filename.  */
514   filename = strrchr (pathname, '/');
515   if (filename == NULL)
516     {
517       filename = pathname;
518       directory_name = "";
519       directory_len = 0;
520     }
521   else
522     {
523       directory_len = (filename - pathname) + 1;
524       directory_name = (char *) alloca (directory_len + 1);
525
526       bcopy (pathname, directory_name, directory_len);
527       directory_name[directory_len] = '\0';
528       ++filename;
529     }
530
531   /* If directory_name contains globbing characters, then we
532      have to expand the previous levels.  Just recurse. */
533   if (glob_pattern_p (directory_name))
534     {
535       char **directories;
536       register unsigned int i;
537
538       if (directory_name[directory_len - 1] == '/')
539         directory_name[directory_len - 1] = '\0';
540
541       directories = glob_filename (directory_name);
542
543       if (directories == NULL)
544         goto memory_error;
545       else if (directories == (char **)&glob_error_return)
546         {
547           free ((char *) result);
548           return ((char **) &glob_error_return);
549         }
550       else if (*directories == NULL)
551         {
552           free ((char *) directories);
553           free ((char *) result);
554           return ((char **) &glob_error_return);
555         }
556
557       /* We have successfully globbed the preceding directory name.
558          For each name in DIRECTORIES, call glob_vector on it and
559          FILENAME.  Concatenate the results together.  */
560       for (i = 0; directories[i] != NULL; ++i)
561         {
562           char **temp_results;
563
564           /* Scan directory even on a NULL pathname.  That way, `*h/'
565              returns only directories ending in `h', instead of all
566              files ending in `h' with a `/' appended. */
567           temp_results = glob_vector (filename, directories[i]);
568
569           /* Handle error cases. */
570           if (temp_results == NULL)
571             goto memory_error;
572           else if (temp_results == (char **)&glob_error_return)
573             /* This filename is probably not a directory.  Ignore it.  */
574             ;
575           else
576             {
577               char **array;
578               register unsigned int l;
579
580               array = glob_dir_to_array (directories[i], temp_results);
581               l = 0;
582               while (array[l] != NULL)
583                 ++l;
584
585               result =
586                 (char **)realloc (result, (result_size + l) * sizeof (char *));
587
588               if (result == NULL)
589                 goto memory_error;
590
591               for (l = 0; array[l] != NULL; ++l)
592                 result[result_size++ - 1] = array[l];
593
594               result[result_size - 1] = NULL;
595
596               /* Note that the elements of ARRAY are not freed.  */
597               free ((char *) array);
598             }
599         }
600       /* Free the directories.  */
601       for (i = 0; directories[i]; i++)
602         free (directories[i]);
603
604       free ((char *) directories);
605
606       return (result);
607     }
608
609   /* If there is only a directory name, return it. */
610   if (*filename == '\0')
611     {
612       result = (char **) realloc ((char *) result, 2 * sizeof (char *));
613       if (result == NULL)
614         return (NULL);
615       result[0] = (char *) malloc (directory_len + 1);
616       if (result[0] == NULL)
617         goto memory_error;
618       bcopy (directory_name, result[0], directory_len + 1);
619       result[1] = NULL;
620       return (result);
621     }
622   else
623     {
624       char **temp_results;
625
626       /* There are no unquoted globbing characters in DIRECTORY_NAME.
627          Dequote it before we try to open the directory since there may
628          be quoted globbing characters which should be treated verbatim. */
629       if (directory_len > 0)
630         dequote_pathname (directory_name);
631
632       /* We allocated a small array called RESULT, which we won't be using.
633          Free that memory now. */
634       free (result);
635
636       /* Just return what glob_vector () returns appended to the
637          directory name. */
638       temp_results =
639         glob_vector (filename, (directory_len == 0 ? "." : directory_name));
640
641       if (temp_results == NULL || temp_results == (char **)&glob_error_return)
642         return (temp_results);
643
644       return (glob_dir_to_array (directory_name, temp_results));
645     }
646
647   /* We get to memory_error if the program has run out of memory, or
648      if this is the shell, and we have been interrupted. */
649  memory_error:
650   if (result != NULL)
651     {
652       register unsigned int i;
653       for (i = 0; result[i] != NULL; ++i)
654         free (result[i]);
655       free ((char *) result);
656     }
657 #if defined (SHELL)
658   if (interrupt_state)
659     throw_to_top_level ();
660 #endif /* SHELL */
661   return (NULL);
662 }
663 \f
664 #if defined (TEST)
665
666 main (argc, argv)
667      int argc;
668      char **argv;
669 {
670   unsigned int i;
671
672   for (i = 1; i < argc; ++i)
673     {
674       char **value = glob_filename (argv[i]);
675       if (value == NULL)
676         puts ("Out of memory.");
677       else if (value == &glob_error_return)
678         perror (argv[i]);
679       else
680         for (i = 0; value[i] != NULL; i++)
681           puts (value[i]);
682     }
683
684   exit (0);
685 }
686 #endif  /* TEST.  */