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 void throw_to_top_level ();
108 extern int interrupt_state;
111 /* Global variable which controls whether or not * matches .*.
112 Non-zero means don't match .*. */
113 int noglob_dot_filenames = 1;
115 /* Global variable to return to signify an error in globbing. */
116 char *glob_error_return;
118 /* Return nonzero if PATTERN has any special globbing chars in it. */
120 glob_pattern_p (pattern)
123 register char *p = pattern;
127 while ((c = *p++) != '\0')
134 case '[': /* Only accept an open brace if there is a close */
135 open++; /* brace to match it. Bracket expressions must be */
136 continue; /* complete, according to Posix.2 */
150 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
152 dequote_pathname (pathname)
157 for (i = j = 0; pathname && pathname[i]; )
159 if (pathname[i] == '\\')
162 pathname[j++] = pathname[i++];
164 if (!pathname[i - 1])
171 /* Return a vector of names of files in directory DIR
172 whose names match glob pattern PAT.
173 The names are not in any particular order.
174 Wildcards at the beginning of PAT do not match an initial period.
176 The vector is terminated by an element that is a null pointer.
178 To free the space allocated, first free the vector's elements,
179 then free the vector.
181 Return 0 if cannot get enough memory to hold the pointer
184 Return -1 if cannot access directory DIR.
185 Look in errno for more information. */
188 glob_vector (pat, dir)
194 struct globval *next;
199 register struct dirent *dp;
200 struct globval *lastlink;
201 register struct globval *nextlink;
202 register char *nextname;
205 register char **name_vector;
206 register unsigned int i;
207 #if defined (OPENDIR_NOT_ROBUST)
210 if (stat (dir, &finfo) < 0)
211 return ((char **) &glob_error_return);
213 if (!S_ISDIR (finfo.st_mode))
214 return ((char **) &glob_error_return);
215 #endif /* OPENDIR_NOT_ROBUST */
219 return ((char **) &glob_error_return);
226 /* If PAT is empty, skip the loop, but return one (empty) filename. */
229 nextlink = (struct globval *)alloca (sizeof (struct globval));
230 nextlink->next = lastlink;
231 nextname = (char *) malloc (1);
237 nextlink->name = nextname;
244 /* Scan the directory, finding all names that match.
245 For each name that matches, allocate a struct globval
246 on the stack and store the name in it.
247 Chain those structs together; lastlink is the front of the chain. */
250 int flags; /* Flags passed to fnmatch (). */
252 /* Make globbing interruptible in the bash shell. */
265 /* If this directory entry is not to be used, try again. */
266 if (!REAL_DIR_ENTRY (dp))
269 /* If a dot must be explicity matched, check to see if they do. */
270 if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
271 (pat[0] != '\\' || pat[1] != '.'))
274 flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
276 if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
278 nextlink = (struct globval *) alloca (sizeof (struct globval));
279 nextlink->next = lastlink;
280 nextname = (char *) malloc (D_NAMLEN (dp) + 1);
281 if (nextname == NULL)
287 nextlink->name = nextname;
288 bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
296 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
297 lose |= name_vector == NULL;
300 /* Have we run out of memory? */
306 /* Here free the strings we have got. */
309 free (lastlink->name);
310 lastlink = lastlink->next;
314 throw_to_top_level ();
319 /* Copy the name pointers from the linked list into the vector. */
320 for (i = 0; i < count; ++i)
322 name_vector[i] = lastlink->name;
323 lastlink = lastlink->next;
326 name_vector[count] = NULL;
327 return (name_vector);
330 /* Return a new array which is the concatenation of each string in ARRAY
331 to DIR. This function expects you to pass in an allocated ARRAY, and
332 it takes care of free()ing that array. Thus, you might think of this
333 function as side-effecting ARRAY. */
335 glob_dir_to_array (dir, array)
338 register unsigned int i, l;
346 add_slash = dir[l - 1] != '/';
349 while (array[i] != NULL)
352 result = (char **) malloc ((i + 1) * sizeof (char *));
356 for (i = 0; array[i] != NULL; i++)
358 result[i] = (char *) malloc (l + (add_slash ? 1 : 0)
359 + strlen (array[i]) + 1);
360 if (result[i] == NULL)
363 strcpy (result[i], dir);
366 strcpy (result[i] + l + add_slash, array[i]);
368 (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
373 /* Free the input array. */
374 for (i = 0; array[i] != NULL; i++)
376 free ((char *) array);
381 /* Do globbing on PATHNAME. Return an array of pathnames that match,
382 marking the end of the array with a null-pointer as an element.
383 If no pathnames match, then the array is empty (first element is null).
384 If there isn't enough memory, then return NULL.
385 If a file system error occurs, return -1; `errno' has the error code. */
387 glob_filename (pathname)
391 unsigned int result_size;
392 char *directory_name, *filename;
393 unsigned int directory_len;
395 result = (char **) malloc (sizeof (char *));
402 /* Find the filename. */
403 filename = strrchr (pathname, '/');
404 if (filename == NULL)
412 directory_len = (filename - pathname) + 1;
413 directory_name = (char *) alloca (directory_len + 1);
415 bcopy (pathname, directory_name, directory_len);
416 directory_name[directory_len] = '\0';
420 /* If directory_name contains globbing characters, then we
421 have to expand the previous levels. Just recurse. */
422 if (glob_pattern_p (directory_name))
425 register unsigned int i;
427 if (directory_name[directory_len - 1] == '/')
428 directory_name[directory_len - 1] = '\0';
430 directories = glob_filename (directory_name);
432 if (directories == NULL)
434 else if (directories == (char **)&glob_error_return)
436 free ((char *) result);
437 return ((char **) &glob_error_return);
439 else if (*directories == NULL)
441 free ((char *) directories);
442 free ((char *) result);
443 return ((char **) &glob_error_return);
446 /* We have successfully globbed the preceding directory name.
447 For each name in DIRECTORIES, call glob_vector on it and
448 FILENAME. Concatenate the results together. */
449 for (i = 0; directories[i] != NULL; ++i)
453 /* Scan directory even on a NULL pathname. That way, `*h/'
454 returns only directories ending in `h', instead of all
455 files ending in `h' with a `/' appended. */
456 temp_results = glob_vector (filename, directories[i]);
458 /* Handle error cases. */
459 if (temp_results == NULL)
461 else if (temp_results == (char **)&glob_error_return)
462 /* This filename is probably not a directory. Ignore it. */
467 register unsigned int l;
469 array = glob_dir_to_array (directories[i], temp_results);
471 while (array[l] != NULL)
475 (char **)realloc (result, (result_size + l) * sizeof (char *));
480 for (l = 0; array[l] != NULL; ++l)
481 result[result_size++ - 1] = array[l];
483 result[result_size - 1] = NULL;
485 /* Note that the elements of ARRAY are not freed. */
486 free ((char *) array);
489 /* Free the directories. */
490 for (i = 0; directories[i]; i++)
491 free (directories[i]);
493 free ((char *) directories);
498 /* If there is only a directory name, return it. */
499 if (*filename == '\0')
501 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
504 result[0] = (char *) malloc (directory_len + 1);
505 if (result[0] == NULL)
507 bcopy (directory_name, result[0], directory_len + 1);
515 /* There are no unquoted globbing characters in DIRECTORY_NAME.
516 Dequote it before we try to open the directory since there may
517 be quoted globbing characters which should be treated verbatim. */
518 if (directory_len > 0)
519 dequote_pathname (directory_name);
521 /* We allocated a small array called RESULT, which we won't be using.
522 Free that memory now. */
525 /* Just return what glob_vector () returns appended to the
528 glob_vector (filename, (directory_len == 0 ? "." : directory_name));
530 if (temp_results == NULL || temp_results == (char **)&glob_error_return)
531 return (temp_results);
533 return (glob_dir_to_array (directory_name, temp_results));
536 /* We get to memory_error if the program has run out of memory, or
537 if this is the shell, and we have been interrupted. */
541 register unsigned int i;
542 for (i = 0; result[i] != NULL; ++i)
544 free ((char *) result);
548 throw_to_top_level ();
561 for (i = 1; i < argc; ++i)
563 char **value = glob_filename (argv[i]);
565 puts ("Out of memory.");
566 else if (value == &glob_error_return)
569 for (i = 0; value[i] != NULL; i++)