1 /* File-name wildcard pattern matching for GNU.
2 Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
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)
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.
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. */
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. */
24 #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
26 #endif /* _AIX && RISC6000 && !__GNUC__ */
28 #if defined (HAVE_UNISTD_H)
32 #if defined (HAVE_STDLIB_H)
36 # include "ansi_stdlib.h"
40 #include <sys/types.h>
42 #if defined (HAVE_DIRENT_H)
44 # define D_NAMLEN(d) strlen ((d)->d_name)
45 #else /* !HAVE_DIRENT_H */
46 # define D_NAMLEN(d) ((d)->d_namlen)
47 # if defined (HAVE_SYS_NDIR_H)
48 # include <sys/ndir.h>
50 # if defined (HAVE_SYS_DIR_H)
52 # endif /* HAVE_SYS_DIR_H */
53 # if defined (HAVE_NDIR_H)
56 # if !defined (dirent)
57 # define dirent direct
59 #endif /* !HAVE_DIRENT_H */
61 #if defined (_POSIX_SOURCE)
62 /* Posix does not require that the d_ino field be present, and some
63 systems do not provide it. */
64 # define REAL_DIR_ENTRY(dp) 1
66 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
67 #endif /* _POSIX_SOURCE */
69 #if defined (HAVE_STRING_H)
71 #else /* !HAVE_STRING_H */
73 #endif /* !HAVE_STRING_H */
75 #if !defined (HAVE_BCOPY)
76 # define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
77 #endif /* !HAVE_BCOPY */
79 /* If the opendir () on your system lets you open non-directory files,
80 then we consider that not robust. */
81 #if defined (OPENDIR_NOT_ROBUST)
83 # include "posixstat.h"
85 # include <sys/stat.h>
87 #endif /* OPENDIR_NOT_ROBUST */
92 #if !defined (HAVE_STDLIB_H) && !defined (SHELL)
93 extern char *malloc (), *realloc ();
95 #endif /* !HAVE_STDLIB_H */
98 # if defined (__STDC__)
99 # define NULL ((void *) 0)
102 # endif /* __STDC__ */
106 extern int interrupt_state;
109 /* Global variable which controls whether or not * matches .*.
110 Non-zero means don't match .*. */
111 int noglob_dot_filenames = 1;
113 /* Global variable to return to signify an error in globbing. */
114 char *glob_error_return;
116 /* Return nonzero if PATTERN has any special globbing chars in it. */
118 glob_pattern_p (pattern)
121 register char *p = pattern;
125 while ((c = *p++) != '\0')
132 case '[': /* Only accept an open brace if there is a close */
133 open++; /* brace to match it. Bracket expressions must be */
134 continue; /* complete, according to Posix.2 */
148 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
150 dequote_pathname (pathname)
155 for (i = j = 0; pathname && pathname[i]; )
157 if (pathname[i] == '\\')
160 pathname[j++] = pathname[i++];
162 if (!pathname[i - 1])
169 /* Return a vector of names of files in directory DIR
170 whose names match glob pattern PAT.
171 The names are not in any particular order.
172 Wildcards at the beginning of PAT do not match an initial period.
174 The vector is terminated by an element that is a null pointer.
176 To free the space allocated, first free the vector's elements,
177 then free the vector.
179 Return 0 if cannot get enough memory to hold the pointer
182 Return -1 if cannot access directory DIR.
183 Look in errno for more information. */
186 glob_vector (pat, dir)
192 struct globval *next;
197 register struct dirent *dp;
198 struct globval *lastlink;
199 register struct globval *nextlink;
200 register char *nextname;
203 register char **name_vector;
204 register unsigned int i;
205 #if defined (OPENDIR_NOT_ROBUST)
208 if (stat (dir, &finfo) < 0)
209 return ((char **) &glob_error_return);
211 if (!S_ISDIR (finfo.st_mode))
212 return ((char **) &glob_error_return);
213 #endif /* OPENDIR_NOT_ROBUST */
217 return ((char **) &glob_error_return);
224 /* If PAT is empty, skip the loop, but return one (empty) filename. */
227 nextlink = (struct globval *)alloca (sizeof (struct globval));
228 nextlink->next = lastlink;
229 nextname = (char *) malloc (1);
235 nextlink->name = nextname;
242 /* Scan the directory, finding all names that match.
243 For each name that matches, allocate a struct globval
244 on the stack and store the name in it.
245 Chain those structs together; lastlink is the front of the chain. */
248 int flags; /* Flags passed to fnmatch (). */
250 /* Make globbing interruptible in the bash shell. */
263 /* If this directory entry is not to be used, try again. */
264 if (!REAL_DIR_ENTRY (dp))
267 /* If a dot must be explicity matched, check to see if they do. */
268 if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.')
271 flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
273 if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
275 nextlink = (struct globval *) alloca (sizeof (struct globval));
276 nextlink->next = lastlink;
277 nextname = (char *) malloc (D_NAMLEN (dp) + 1);
278 if (nextname == NULL)
284 nextlink->name = nextname;
285 bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
293 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
294 lose |= name_vector == NULL;
297 /* Have we run out of memory? */
301 /* Here free the strings we have got. */
304 free (lastlink->name);
305 lastlink = lastlink->next;
309 throw_to_top_level ();
314 /* Copy the name pointers from the linked list into the vector. */
315 for (i = 0; i < count; ++i)
317 name_vector[i] = lastlink->name;
318 lastlink = lastlink->next;
321 name_vector[count] = NULL;
322 return (name_vector);
325 /* Return a new array which is the concatenation of each string in ARRAY
326 to DIR. This function expects you to pass in an allocated ARRAY, and
327 it takes care of free()ing that array. Thus, you might think of this
328 function as side-effecting ARRAY. */
330 glob_dir_to_array (dir, array)
333 register unsigned int i, l;
341 add_slash = dir[l - 1] != '/';
344 while (array[i] != NULL)
347 result = (char **) malloc ((i + 1) * sizeof (char *));
351 for (i = 0; array[i] != NULL; i++)
353 result[i] = (char *) malloc (l + (add_slash ? 1 : 0)
354 + strlen (array[i]) + 1);
355 if (result[i] == NULL)
358 strcpy (result[i], dir);
361 strcpy (result[i] + l + add_slash, array[i]);
363 (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
368 /* Free the input array. */
369 for (i = 0; array[i] != NULL; i++)
371 free ((char *) array);
376 /* Do globbing on PATHNAME. Return an array of pathnames that match,
377 marking the end of the array with a null-pointer as an element.
378 If no pathnames match, then the array is empty (first element is null).
379 If there isn't enough memory, then return NULL.
380 If a file system error occurs, return -1; `errno' has the error code. */
382 glob_filename (pathname)
386 unsigned int result_size;
387 char *directory_name, *filename;
388 unsigned int directory_len;
390 result = (char **) malloc (sizeof (char *));
397 /* Find the filename. */
398 filename = strrchr (pathname, '/');
399 if (filename == NULL)
407 directory_len = (filename - pathname) + 1;
408 directory_name = (char *) alloca (directory_len + 1);
410 bcopy (pathname, directory_name, directory_len);
411 directory_name[directory_len] = '\0';
415 /* If directory_name contains globbing characters, then we
416 have to expand the previous levels. Just recurse. */
417 if (glob_pattern_p (directory_name))
420 register unsigned int i;
422 if (directory_name[directory_len - 1] == '/')
423 directory_name[directory_len - 1] = '\0';
425 directories = glob_filename (directory_name);
427 if (directories == NULL)
429 else if (directories == (char **)&glob_error_return)
431 free ((char *) result);
432 return ((char **) &glob_error_return);
434 else if (*directories == NULL)
436 free ((char *) directories);
437 free ((char *) result);
438 return ((char **) &glob_error_return);
441 /* We have successfully globbed the preceding directory name.
442 For each name in DIRECTORIES, call glob_vector on it and
443 FILENAME. Concatenate the results together. */
444 for (i = 0; directories[i] != NULL; ++i)
448 /* Scan directory even on a NULL pathname. That way, `*h/'
449 returns only directories ending in `h', instead of all
450 files ending in `h' with a `/' appended. */
451 temp_results = glob_vector (filename, directories[i]);
453 /* Handle error cases. */
454 if (temp_results == NULL)
456 else if (temp_results == (char **)&glob_error_return)
457 /* This filename is probably not a directory. Ignore it. */
462 register unsigned int l;
464 array = glob_dir_to_array (directories[i], temp_results);
466 while (array[l] != NULL)
470 (char **)realloc (result, (result_size + l) * sizeof (char *));
475 for (l = 0; array[l] != NULL; ++l)
476 result[result_size++ - 1] = array[l];
478 result[result_size - 1] = NULL;
480 /* Note that the elements of ARRAY are not freed. */
481 free ((char *) array);
484 /* Free the directories. */
485 for (i = 0; directories[i]; i++)
486 free (directories[i]);
488 free ((char *) directories);
493 /* If there is only a directory name, return it. */
494 if (*filename == '\0')
496 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
499 result[0] = (char *) malloc (directory_len + 1);
500 if (result[0] == NULL)
502 bcopy (directory_name, result[0], directory_len + 1);
510 /* There are no unquoted globbing characters in DIRECTORY_NAME.
511 Dequote it before we try to open the directory since there may
512 be quoted globbing characters which should be treated verbatim. */
513 if (directory_len > 0)
514 dequote_pathname (directory_name);
516 /* We allocated a small array called RESULT, which we won't be using.
517 Free that memory now. */
520 /* Just return what glob_vector () returns appended to the
523 glob_vector (filename, (directory_len == 0 ? "." : directory_name));
525 if (temp_results == NULL || temp_results == (char **)&glob_error_return)
526 return (temp_results);
528 return (glob_dir_to_array (directory_name, temp_results));
531 /* We get to memory_error if the program has run out of memory, or
532 if this is the shell, and we have been interrupted. */
536 register unsigned int i;
537 for (i = 0; result[i] != NULL; ++i)
539 free ((char *) result);
543 throw_to_top_level ();
556 for (i = 1; i < argc; ++i)
558 char **value = glob_filename (argv[i]);
560 puts ("Out of memory.");
561 else if (value == &glob_error_return)
564 for (i = 0; value[i] != NULL; i++)