]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - lib/glob/glob.c
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / lib / glob / glob.c
index 6a9679fc8365c57027d57eea4e89776752e10ef2..69d0e54e942b18bf1cf09eaccc07f57eedbbae18 100644 (file)
@@ -3,7 +3,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 1, or (at your option)
+   the Free Software Foundation; either version 2, or (at your option)
    any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -13,7 +13,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.  */
 
 /* To whomever it may concern: I have never seen the code which most
    Unix programs use to perform this function.  I wrote this from scratch
@@ -67,7 +67,7 @@
 #  endif
 #endif /* !HAVE_DIRENT_H */
 
-#if defined (_POSIX_SOURCE)
+#if defined (_POSIX_SOURCE) && !defined (STRUCT_DIRENT_HAS_D_INO)
 /* Posix does not require that the d_ino field be present, and some
    systems do not provide it. */
 #  define REAL_DIR_ENTRY(dp) 1
@@ -75,9 +75,9 @@
 #  define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
 #endif /* _POSIX_SOURCE */
 
-#if !defined (HAVE_BCOPY)
+#if !defined (HAVE_BCOPY) && !defined (bcopy)
 #  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
-#endif /* !HAVE_BCOPY */
+#endif /* !HAVE_BCOPY && !bcopy */
 
 #if defined (SHELL)
 #  include "posixstat.h"
@@ -251,7 +251,7 @@ glob_vector (pat, dir)
   register struct dirent *dp;
   struct globval *lastlink;
   register struct globval *nextlink;
-  register char *nextname;
+  register char *nextname, *npat;
   unsigned int count;
   int lose, skip;
   register char **name_vector;
@@ -297,32 +297,32 @@ glob_vector (pat, dir)
 
       dirlen = strlen (dir);
       nextname = (char *)malloc (dirlen + strlen (pat) + 2);
-      if (nextname == 0)
+      npat = (char *)malloc (strlen (pat) + 1);
+      if (nextname == 0 || npat == 0)
        lose = 1;
       else
        {
+         strcpy (npat, pat);
+         dequote_pathname (npat);
+
          strcpy (nextname, dir);
          nextname[dirlen++] = '/';
-         strcpy (nextname + dirlen, pat);
+         strcpy (nextname + dirlen, npat);
 
          if (GLOB_TESTNAME (nextname) >= 0)
            {
              free (nextname);
              nextlink = (struct globval *)alloca (sizeof (struct globval));
              nextlink->next = (struct globval *)0;
-             nextname = (char *) malloc (strlen (pat) + 1);
-             if (nextname == 0)
-               lose = 1;
-             else
-               {
-                 lastlink = nextlink;
-                 nextlink->name = nextname;
-                 strcpy (nextname, pat);
-                 count = 1;
-               }
+             lastlink = nextlink;
+             nextlink->name = npat;
+             count = 1;
            }
          else
-           free (nextname);
+           {
+             free (nextname);
+             free (npat);
+           }
        }
 
       skip = 1;
@@ -343,7 +343,7 @@ glob_vector (pat, dir)
        return ((char **) &glob_error_return);
 
       /* Compute the flags that will be passed to fnmatch().  We don't
-         need to do this every time through the loop. */
+        need to do this every time through the loop. */
       flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
 
 #ifdef FNM_CASEFOLD
@@ -379,6 +379,16 @@ glob_vector (pat, dir)
          if (REAL_DIR_ENTRY (dp) == 0)
            continue;
 
+         /* If a leading dot need not be explicitly matched, and the pattern
+            doesn't start with a `.', don't match `.' or `..' */
+#define dname dp->d_name
+         if (noglob_dot_filenames == 0 && pat[0] != '.' &&
+               (pat[0] != '\\' || pat[1] != '.') &&
+               (dname[0] == '.' &&
+                 (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
+#undef dname
+           continue;
+
          /* If a dot must be explicity matched, check to see if they do. */
          if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
                (pat[0] != '\\' || pat[1] != '.'))
@@ -470,14 +480,11 @@ glob_dir_to_array (dir, array)
                                   + strlen (array[i]) + 1);
       if (result[i] == NULL)
        return (NULL);
-#if 1
+
       strcpy (result[i], dir);
       if (add_slash)
-        result[i][l] = '/';
+       result[i][l] = '/';
       strcpy (result[i] + l + add_slash, array[i]);
-#else
-      (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
-#endif
     }
   result[i] = NULL;