import from branch_1_1:
[freeradius.git] / libltdl / ltdl.c
index c405c83..57c2a39 100644 (file)
@@ -1,5 +1,5 @@
 /* ltdl.c -- system independent dlopen wrapper
-   Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2004, 2005  Free Software Foundation, Inc.
    Originally by Thomas Tanner <tanner@ffii.org>
    This file is part of GNU Libtool.
 
@@ -20,8 +20,8 @@ Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307  USA
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301  USA
 
 */
 
@@ -457,7 +457,9 @@ opendir (path)
   DIR *entry;
 
   assert(path != (char *) NULL);
-  (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
+  /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
+  (void) strncpy (file_specification, path, LT_FILENAME_MAX-6);
+  file_specification[LT_FILENAME_MAX-6] = LT_EOS_CHAR;
   (void) strcat(file_specification,"\\");
   entry = LT_DLMALLOC (DIR,sizeof(DIR));
   if (entry != (DIR *) 0)
@@ -498,6 +500,7 @@ static struct dirent *readdir(entry)
   entry->firsttime = FALSE;
   (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
     LT_FILENAME_MAX-1);
+  entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR;
   entry->file_info.d_namlen = strlen(entry->file_info.d_name);
   return(&entry->file_info);
 }
@@ -622,7 +625,7 @@ argz_create_sep (str, delim, pargz, pargz_len)
   assert (pargz);
   assert (pargz_len);
 
-  /* Make a copy of STR, but replacing each occurence of
+  /* Make a copy of STR, but replacing each occurrence of
      DELIM with '\0'.  */
   argz_len = 1+ LT_STRLEN (str);
   if (argz_len)
@@ -1345,15 +1348,27 @@ sys_wll_open (loader_data, filename)
   if (!searchname)
     return 0;
 
-#if __CYGWIN__
   {
-    char wpath[MAX_PATH];
-    cygwin_conv_to_full_win32_path(searchname, wpath);
-    module = LoadLibrary(wpath);
-  }
+    /* Silence dialog from LoadLibrary on some failures.
+       No way to get the error mode, but to set it,
+       so set it twice to preserve any previous flags. */
+    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
+    SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
+
+#if defined(__CYGWIN__)
+    {
+      char wpath[MAX_PATH];
+      cygwin_conv_to_full_win32_path (searchname, wpath);
+      module = LoadLibrary (wpath);
+    }
 #else
-  module = LoadLibrary (searchname);
+    module = LoadLibrary (searchname);
 #endif
+
+    /* Restore the error mode. */
+    SetErrorMode(errormode);
+  }
+
   LT_DLFREE (searchname);
 
   /* libltdl expects this function to fail if it is unable
@@ -2346,8 +2361,6 @@ lt_dlexit ()
          LT_DLMEM_REASSIGN (loader, next);
        }
       loaders = 0;
-
-      LT_DLFREE (user_search_path);
     }
 
  done:
@@ -2540,8 +2553,8 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
 
       /* maybe it was moved to another directory */
       {
-         if (tryall_dlopen_module (handle,
-                                   (const char *) 0, dir, dlname) == 0)
+         if (dir && (tryall_dlopen_module (handle,
+                                   (const char *) 0, dir, dlname) == 0))
            return 0;
       }
     }
@@ -2868,12 +2881,6 @@ load_deplibs (handle, deplibs)
        }
     }
 
-  /* restore the old search path */
-  LT_DLFREE (user_search_path);
-  user_search_path = save_search_path;
-
-  LT_DLMUTEX_UNLOCK ();
-
   if (!depcount)
     {
       errors = 0;
@@ -2960,6 +2967,13 @@ load_deplibs (handle, deplibs)
 
  cleanup:
   LT_DLFREE (names);
+  /* restore the old search path */
+  if (user_search_path) {
+    LT_DLFREE (user_search_path);
+    user_search_path = save_search_path;
+  }
+  LT_DLMUTEX_UNLOCK ();
+
 #endif
 
   return errors;
@@ -2999,6 +3013,9 @@ trim (dest, str)
 
   LT_DLFREE (*dest);
 
+  if (!end)
+    return 1;
+
   if (len > 3 && str[0] == '\'')
     {
       tmp = LT_EMALLOC (char, end - str);
@@ -3044,7 +3061,6 @@ try_dlopen (phandle, filename)
   char *       dir             = 0;
   char *       name            = 0;
   int          errors          = 0;
-  int          free_base_name  = 0;
   lt_dlhandle  newhandle;
 
   assert (phandle);
@@ -3103,10 +3119,8 @@ try_dlopen (phandle, filename)
 
       ++base_name;
     }
-  else {
-    LT_DLMEM_REASSIGN (base_name, canonical);
-    free_base_name = 1;
-  }
+  else
+    base_name = canonical;
 
   assert (base_name && *base_name);
 
@@ -3407,7 +3421,6 @@ try_dlopen (phandle, filename)
   LT_DLFREE (dir);
   LT_DLFREE (name);
   LT_DLFREE (canonical);
-  if (free_base_name) LT_DLFREE (base_name);
 
   return errors;
 }
@@ -3483,7 +3496,10 @@ lt_dlopenext (filename)
   strcpy (tmp, filename);
   strcat (tmp, archive_ext);
   errors = try_dlopen (&handle, tmp);
-  if (errors) return 0;
+  if (handle && errors) {
+    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+    return 0;  /* leaks tmp and handle */
+  }
 
   /* If we found FILENAME, stop searching -- whether we were able to
      load the file as a module or not.  If the file exists but loading
@@ -3514,7 +3530,10 @@ lt_dlopenext (filename)
 
   strcat(tmp, shlib_ext);
   errors = try_dlopen (&handle, tmp);
-  if (errors) return 0;
+  if (handle && errors) {
+    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+    return 0;  /* leaks tmp and handle */
+  }
 
   /* As before, if the file was found but loading failed, return now
      with the current error message.  */
@@ -3542,7 +3561,14 @@ lt_argz_insert (pargz, pargz_len, before, entry)
 {
   error_t error;
 
-  if ((error = argz_insert (pargz, pargz_len, before, entry)))
+  /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
+     pargz_len, NULL, entry) failed with EINVAL.  */
+  if (before)
+    error = argz_insert (pargz, pargz_len, before, entry);
+  else
+    error = argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
+
+  if (error)
     {
       switch (error)
        {