rem: assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL);
add: assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
context: static	int	unload_deplibs	      LT_PARAMS((lt_dlhandle handle));static	int	lt_argz_insert	      LT_PARAMS((char **pargz,						 size_t *pargz_len,						 char *before,						 const char *entry));static	int	lt_argz_insertinorder LT_PARAMS((char **pargz,						 size_t *pargz_len,						 const char *entry));static	int	lt_argz_insertdir     LT_PARAMS((char **pargz,						 size_t *pargz_len,						 const char *dirnam,						 struct dirent *dp));static	int	lt_dlpath_insertdir   LT_PARAMS((char **ppath,						 char *before,						 const char *dir));static	int	list_files_by_dir     LT_PARAMS((const char *dirnam,						 char **pargz,						 size_t *pargz_len));static	int	file_not_found	      LT_PARAMS((void));static	char	       *user_search_path= NULL;static	lt_dlloader    *loaders		= NULL;static	lt_dlhandle	handles 	= NULL;static	int		initialized 	= 0;/* Initialize libltdl. */intlt_dlinit (){  int	      errors   = 0;  LT_DLMUTEX_LOCK ();  /* Initialize only at first call. */  if (++initialized == 1)    {      handles = NULL;      user_search_path = NULL; /* empty search path */#if HAVE_LIBDL && !defined(__CYGWIN__)      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");#endif#if HAVE_SHL_LOAD      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");#endif#ifdef __WINDOWS__      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");#endif#ifdef __BEOS__      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");#endif#if HAVE_DLD      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");#endif      errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");      if (presym_init (presym.dlloader_data))	{	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));	  ++errors;	}      else if (errors != 0)	{	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));	  ++errors;	}    }  LT_DLMUTEX_UNLOCK ();  return errors;}intlt_dlpreload (preloaded)     const lt_dlsymlist *preloaded;{  int errors = 0;  if (preloaded)    {      errors = presym_add_symlist (preloaded);    }  else    {      presym_free_symlists();      LT_DLMUTEX_LOCK ();      if (default_preloaded_symbols)	{	  errors = lt_dlpreload (default_preloaded_symbols);	}      LT_DLMUTEX_UNLOCK ();    }  return errors;}intlt_dlpreload_default (preloaded)     const lt_dlsymlist *preloaded;{  LT_DLMUTEX_LOCK ();  default_preloaded_symbols = preloaded;  LT_DLMUTEX_UNLOCK ();  return 0;}intlt_dlexit (){  /* shut down libltdl */  lt_dlloader *loader;  int	       errors   = 0;  LT_DLMUTEX_LOCK ();  loader = loaders;  if (!initialized)    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));      ++errors;      goto done;    }  /* shut down only at last call. */  if (--initialized == 0)    {      int	level;      while (handles && LT_DLIS_RESIDENT (handles))	{	  handles = handles->next;	}      /* close all modules */      for (level = 1; handles; ++level)	{	  lt_dlhandle cur = handles;	  int saw_nonresident = 0;	  while (cur)	    {	      lt_dlhandle tmp = cur;	      cur = cur->next;	      if (!LT_DLIS_RESIDENT (tmp))		saw_nonresident = 1;	      if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)		{		  if (lt_dlclose (tmp))		    {		      ++errors;		    }		}	    }	  /* done if only resident modules are left */	  if (!saw_nonresident)	    break;	}      /* close all loaders */      while (loader)	{	  lt_dlloader *next = loader->next;	  lt_user_data data = loader->dlloader_data;	  if (loader->dlloader_exit && loader->dlloader_exit (data))	    {	      ++errors;	    }	  LT_DLMEM_REASSIGN (loader, next);	}      loaders = NULL;    } done:  LT_DLMUTEX_UNLOCK ();  return errors;}static inttryall_dlopen (handle, filename)     lt_dlhandle *handle;     const char *filename;{  lt_dlhandle	 cur;  lt_dlloader   *loader;  const char	*saved_error;  int		 errors		= 0;  LT_DLMUTEX_GETERROR (saved_error);  LT_DLMUTEX_LOCK ();  cur	 = handles;  loader = loaders;  /* check whether the module was already opened */  while (cur)    {      /* try to dlopen the program itself? */      if (!cur->info.filename && !filename)	{	  break;	}      if (cur->info.filename && filename	  && strcmp (cur->info.filename, filename) == 0)	{	  break;	}      cur = cur->next;    }  if (cur)    {      ++cur->info.ref_count;      *handle = cur;      goto done;    }  cur = *handle;  if (filename)    {      cur->info.filename = lt_estrdup (filename);      if (!cur->info.filename)	{	  ++errors;	  goto done;	}    }  else    {      cur->info.filename = NULL;    }  while (loader)    {      lt_user_data data = loader->dlloader_data;      cur->module = loader->module_open (data, filename);      if (cur->module != NULL)	{	  break;	}      loader = loader->next;    }  if (!loader)    {      LT_DLFREE (cur->info.filename);      ++errors;      goto done;    }  cur->loader	= loader;  LT_DLMUTEX_SETERROR (saved_error); done:  LT_DLMUTEX_UNLOCK ();  return errors;}static inttryall_dlopen_module (handle, prefix, dirname, dlname)     lt_dlhandle *handle;     const char *prefix;     const char *dirname;     const char *dlname;{  int      error	= 0;  char     *filename	= NULL;  size_t   filename_len	= 0;  size_t   dirname_len	= LT_STRLEN (dirname);  assert (handle);  assert (dirname);  assert (dlname);#ifdef LT_DIRSEP_CHAR  /* Only canonicalized names (i.e. with DIRSEP chars already converted)     should make it into this function:  */  assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL);#endif  if (dirname[dirname_len -1] == '/')    --dirname_len;  filename_len = dirname_len + 1 + LT_STRLEN (dlname);  /* Allocate memory, and combine DIRNAME and MODULENAME into it.     The PREFIX (if any) is handled below.  */  filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);  if (!filename)    return 1;  sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);  /* Now that we have combined DIRNAME and MODULENAME, if there is     also a PREFIX to contend with, simply recurse with the arguments     shuffled.  Otherwise, attempt to open FILENAME as a module.  */  if (prefix)    {      error += tryall_dlopen_module (handle,				     (const char *) 0, prefix, filename);    }  else if (tryall_dlopen (handle, filename) != 0)    {      ++error;    }  LT_DLFREE (filename);  return error;}static intfind_module (handle, dir, libdir, dlname, old_name, installed)     lt_dlhandle *handle;     const char *dir;     const char *libdir;     const char *dlname;     const char *old_name;     int installed;{  /* Try to open the old library first; if it was dlpreopened,     we want the preopened version of it, even if a dlopenable     module is available.  */  if (old_name && tryall_dlopen (handle, old_name) == 0)    {      return 0;    }  /* Try to open the dynamic library.  */  if (dlname)    {      /* try to open the installed module */      if (installed && libdir)	{	  if (tryall_dlopen_module (handle,				    (const char *) 0, libdir, dlname) == 0)	    return 0;	}      /* try to open the not-installed module */      if (!installed)	{	  if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)	    return 0;	}      /* maybe it was moved to another directory */      {	  if (tryall_dlopen_module (handle,				    (const char *) 0, dir, dlname) == 0)	    return 0;      }    }  return 1;}static intcanonicalize_path (path, pcanonical)     const char *path;     char **pcanonical;{  char *canonical = NULL;  assert (path && *path);  assert (pcanonical);  canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));  if (!canonical)    return 1;  {    size_t dest = 0;    size_t src;    for (src = 0; path[src] != LT_EOS_CHAR; ++src)      {	/* Path separators are not copied to the beginning or end of	   the destination, or if another separator would follow	   immediately.  */	if (path[src] == LT_PATHSEP_CHAR)	  {	    if ((dest == 0)		|| (path[1+ src] == LT_PATHSEP_CHAR)		|| (path[1+ src] == LT_EOS_CHAR))	      continue;	  }	/* Anything other than a directory separator is copied verbatim.  */	if ((path[src] != '/')#ifdef LT_DIRSEP_CHAR	    && (path[src] != LT_DIRSEP_CHAR)#endif	    )	  {	    canonical[dest++] = path[src];	  }	/* Directory separators are converted and copied only if they are	   not at the end of a path -- i.e. before a path separator or	   NULL terminator.  */	else if ((path[1+ src] != LT_PATHSEP_CHAR)		 && (path[1+ src] != LT_EOS_CHAR)#ifdef LT_DIRSEP_CHAR		 && (path[1+ src] != LT_DIRSEP_CHAR)#endif		 && (path[1+ src] != '/'))	  {	    canonical[dest++] = '/';	  }      }    /* Add an end-of-string marker at the end.  */    canonical[dest] = LT_EOS_CHAR;  }  /* Assign new value.  */  *pcanonical = canonical;  return 0;}static intargzize_path (path, pargz, pargz_len)     const char *path;     char **pargz;     size_t *pargz_len;{  error_t error;  assert (path);  assert (pargz);  assert (pargz_len);  if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))    {      switch (error)	{	case ENOMEM:	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));	  break;	default:	  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));	  break;	}      return 1;    }  return 0;}/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element   of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns   non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,   it is appended to each SEARCH_PATH element before FUNC is called.  */static intforeach_dirinpath (search_path, base_name, func, data1, data2)     const char *search_path;     const char *base_name;     foreach_callback_func *func;     lt_ptr data1;     lt_ptr data2;{  int	 result		= 0;  int	 filenamesize	= 0;  size_t lenbase	= LT_STRLEN (base_name);  size_t argz_len	= 0;  char *argz		= NULL;  char *filename	= NULL;  char *canonical	= NULL;  LT_DLMUTEX_LOCK ();  if (!search_path || !*search_path)    {      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));      goto cleanup;    }  if (canonicalize_path (search_path, &canonical) != 0)    goto cleanup;  if (argzize_path (canonical, &argz, &argz_len) != 0)    goto cleanup;  {    char *dir_name = NULL;    while ((dir_name = argz_next (argz, argz_len, dir_name)))      {	size_t lendir = LT_STRLEN (dir_name);	if (lendir +1 +lenbase >= filenamesize)	{	  LT_DLFREE (filename);	  filenamesize	= lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */	  filename	= LT_EMALLOC (char, filenamesize);	  if (!filename)	    goto cleanup;	}	assert (filenamesize > lendir);	strcpy (filename, dir_name);	if (base_name && *base_name)	  {	    if (filename[lendir -1] != '/')	      filename[lendir++] = '/';	    strcpy (filename +lendir, base_name);	  }	if ((result = (*func) (filename, data1, data2)))	  {	    break;	  }      }  } cleanup:  LT_DLFREE (argz);  LT_DLFREE (canonical);  LT_DLFREE (filename);  LT_DLMUTEX_UNLOCK ();  return result;}/* If FILEPATH can be opened, store the name of the directory component   in DATA1, and the opened FILE* structure address in DATA2.  Otherwise   DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */static intfind_file_callback (filename, data1, data2)     char *filename;     lt_ptr data1;     lt_ptr data2;{  char	     **pdir	= (char **) data1;  FILE	     **pfile	= (FILE **) data2;  int	     is_done	= 0;  assert (filename && *filename);  assert (pdir);  assert (pfile);  if ((*pfile = fopen (filename, LT_READTEXT_MODE)))    {      char *dirend = strrchr (filename, '/');      if (dirend > filename)	*dirend   = LT_EOS_CHAR;      LT_DLFREE (*pdir);      *pdir   = lt_estrdup (filename);      is_done = (*pdir == NULL) ? -1 : 1;    }  return is_done;}static FILE *find_file (search_path, base_name, pdir)     const char *search_path;     const char *base_name;     char **pdir;{  FILE *file = NULL;  foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);  return file;}static intfind_handle_callback (filename, data, ignored)     char *filename;     lt_ptr data;     lt_ptr ignored;{  lt_dlhandle  *handle		= (lt_dlhandle *) data;  int		notfound	= access (filename, R_OK);  /* Bail out if file cannot be read...  */  if (notfound)    return 0;  /* Try to dlopen the file, but do not continue searching in any     case.  */  if (tryall_dlopen (handle, filename) != 0)    *handle = NULL;  return 1;}/* If HANDLE was found return it, otherwise return 0.  If HANDLE was   found but could not be opened, *HANDLE will be set to 0.  */static lt_dlhandle *find_handle (search_path, base_name, handle)     const char *search_path;     const char *base_name;     lt_dlhandle *handle;{  if (!search_path)    return 0;  if (!foreach_dirinpath (search_path, base_name, find_handle_callback,			  handle, 0))    return 0;  return handle;}static intload_deplibs (handle, deplibs)     lt_dlhandle handle;     char *deplibs;{#if LTDL_DLOPEN_DEPLIBS  char	*p, *save_search_path = NULL;  int   depcount = 0;  int	i;  char	**names = NULL;#endif  int	errors = 0;  handle->depcount = 0;#if LTDL_DLOPEN_DEPLIBS  if (!deplibs)    {      return errors;    }  ++errors;  LT_DLMUTEX_LOCK ();  if (user_search_path)    {      save_search_path = lt_estrdup (user_search_path);      if (!save_search_path)	goto cleanup;    }  /* extract search paths and count deplibs */  p = deplibs;  while (*p)    {      if (!isspace ((int) *p))	{	  char *end = p+1;	  while (*end && !isspace((int) *end))	    {	      ++end;	    }	  if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)	    {	      char save = *end;	      *end = '\0'; /* set a temporary string terminator */	      if (lt_dladdsearchdir(p+2))		{		  goto cleanup;		}	      *end = save;	    }	  else	    {	      ++depcount;	    }	  p = end;	}      else	{	  ++p;	}    }  /* restore the old search path */  LT_DLFREE (user_search_path);  user_search_path = save_search_path;  LT_DLMUTEX_UNLOCK ();  if (!depcount)    {      errors = 0;      goto cleanup;    }  names = LT_EMALLOC (char *, depcount * sizeof (char*));  if (!names)    goto cleanup;  /* now only extract the actual deplibs */  depcount = 0;  p = deplibs;  while (*p)    {      if (isspace ((int) *p))	{	  ++p;	}      else	{	  char *end = p+1;	  while (*end && !isspace ((int) *end))	    {	      ++end;	    }	  if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)	    {	      char *name;	      char save = *end;	      *end = '\0'; /* set a temporary string terminator */	      if (strncmp(p, "-l", 2) == 0)		{		  size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);		  name = LT_EMALLOC (char, 1+ name_len);		  if (name)		    sprintf (name, "lib%s", p+2);		}	      else		name = lt_estrdup(p);	      if (!name)		goto cleanup_names;	      names[depcount++] = name;	      *end = save;	    }	  p = end;	}    }  /* load the deplibs (in reverse order)     At this stage, don't worry if the deplibs do not load correctly,     they may already be statically linked into the loading application     for instance.  There will be a more enlightening error message     later on if the loaded module cannot resolve all of its symbols.  */  if (depcount)    {      int	j = 0;      handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);      if (!handle->deplibs)	goto cleanup;      for (i = 0; i < depcount; ++i)	{	  handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);	  if (handle->deplibs[j])	    {	      ++j;	    }	}      handle->depcount	= j;	/* Number of successfully loaded deplibs */      errors		= 0;    } cleanup_names:  for (i = 0; i < depcount; ++i)    {      LT_DLFREE (names[i]);    } cleanup:  LT_DLFREE (names);#endif  return errors;}static intunload_deplibs (handle)     lt_dlhandle handle;{  int i;  int errors = 0;  if (handle->depcount)    {      for (i = 0; i < handle->depcount; ++i)	{	  if (!LT_DLIS_RESIDENT (handle->deplibs[i]))	    {	      errors += lt_dlclose (handle->deplibs[i]);	    }	}    }  return errors;}