# endif
#endif
-#ifndef LTDL_SEARCHPATH_MAX
-#define LTDL_SEARCHPATH_MAX 4096
-#endif
-
#undef LTDL_READTEXT_MODE
/* fopen() mode flags for reading a text file */
#ifdef _WIN32
#undef LTDL_SYMBOL_LENGTH
/* This is the maximum symbol size that won't require malloc/free */
-#define LTDL_SYMBOL_LENGTH 256
+#define LTDL_SYMBOL_LENGTH 128
#undef LTDL_SYMBOL_OVERHEAD
/* This accounts for the _LTX_ separator and the string terminator */
#undef LTDL_TYPE_TOP
#define LTDL_TYPE_TOP &presym
-static char usr_search_path[LTDL_SEARCHPATH_MAX];
+static char *usr_search_path;
+static int usr_search_path_size = 0;
static lt_dlhandle handles = 0;
static int initialized = 0;
return 0;
}
handles = 0;
- usr_search_path[0] = '\0'; /* empty search path */
+ if (usr_search_path)
+ free(usr_search_path);
+ usr_search_path = 0; /* empty search path */
while (*type) {
if ((*type)->mod_init())
return errors;
}
-static int /* not all compilers support void */
-trim (dest, s)
- char *dest;
- const char *s;
-{
- char *i = strrchr(s, '\'');
- int len = strlen(s);
-
- if (len > 3 && s[0] == '\'') {
- strncpy(dest, &s[1], (i - s) - 1);
- dest[len-3] = '\0';
- } else
- *dest = '\0';
- return 0;
-}
-
static int
tryall_dlopen (handle, filename)
lt_dlhandle *handle;
const char *dlname;
const char *old_name;
{
- char filename[LTDL_FILENAME_MAX];
-
/* search for 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)
+ if (old_name && tryall_dlopen(handle, old_name) == 0)
return 0;
/* search a module */
- if (*dlname) {
- /* hmm, maybe it was moved to another directory */
- if (strlen(dir)+1+strlen(dlname) < LTDL_FILENAME_MAX) {
- strcpy(filename, dir);
- strcat(filename, "/");
- strcat(filename, dlname);
- if (tryall_dlopen(handle, filename) == 0)
- return 0;
+ if (dlname) {
+ char *filename = malloc(strlen(dir)+1+strlen(dlname)+1);
+
+ if (!filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ strcpy(filename, dir);
+ strcat(filename, "/");
+ strcat(filename, dlname);
+ if (tryall_dlopen(handle, filename) == 0) {
+ free(filename);
+ return 0;
}
+ free(filename);
}
last_error = file_not_found_error;
return 1;
}
+#undef LTDL_CHECK_SIZE
+#define LTDL_CHECK_SIZE(buf_, size_, need_, ret) do { \
+ char **pbuf = &buf_; int *psize = &size_, need = need_; \
+ if (need > *psize) { \
+ if (*pbuf) \
+ free(*pbuf); \
+ *pbuf = malloc(need); \
+ if (!*pbuf) { \
+ last_error = memory_error; \
+ return ret; \
+ } \
+ } \
+} while(0)
+
static int
find_library (handle, basename, search_path)
lt_dlhandle *handle;
const char *basename;
const char *search_path;
{
- char filename[LTDL_FILENAME_MAX];
+ char *filename = 0;
+ int size = 0;
const char *cur, *next;
+ int baselen;
if (!search_path || !strlen(search_path)) {
last_error = file_not_found_error;
return 1;
}
cur = search_path;
+ baselen = strlen(basename);
while (cur) {
+ int lendir;
next = strchr(cur, ':');
- if (next) {
- if (next - cur + 1 >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- return 1;
- }
- strncpy(filename, cur, next - cur);
- filename[next - cur] = '\0';
+ if (next)
+ lendir = next-cur;
+ else
+ lendir = strlen(cur);
+ if (lendir == 0)
+ continue;
+ LTDL_CHECK_SIZE(filename, size, \
+ lendir + 1 + baselen + 1, 1);
+ strncpy(filename, cur, lendir);
+ if (next)
cur = next+1;
- } else {
- if (strlen(cur)+1 >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- return 1;
- }
- strcpy(filename, cur);
+ else
cur = 0;
- }
- if (!*filename)
- continue;
- strcat(filename, "/");
- if (strlen(filename)+strlen(basename) < LTDL_FILENAME_MAX) {
- strcat(filename, basename);
- if (tryall_dlopen(handle, filename) == 0)
- return 0;
+ filename[lendir] = '/';
+ strncpy(filename+lendir+1, basename, baselen+1);
+ if (tryall_dlopen(handle, filename) == 0) {
+ free(filename);
+ return 0;
}
}
+ free(filename);
last_error = file_not_found_error;
return 1;
}
static FILE *
-find_file (basename, search_path)
+find_file (basename, search_path, pdir)
const char *basename;
const char *search_path;
+ const char **pdir;
{
- char filename[LTDL_FILENAME_MAX];
+ char *filename = 0;
+ int size = 0;
const char *cur, *next;
FILE *file;
-
+ int baselen;
+ int overhead;
+
if (!search_path || !strlen(search_path)) {
last_error = file_not_found_error;
return 0;
}
cur = search_path;
+ baselen = strlen(basename);
+ overhead = strlen(LTDL_OBJDIR)+1;
+ if (baselen > overhead)
+ overhead = baselen;
while (cur) {
+ int lendir;
next = strchr(cur, ':');
- if (next) {
- if (next - cur + 1 >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- return 0;
- }
- strncpy(filename, cur, next - cur);
- filename[next - cur] = '\0';
+ if (next)
+ lendir = next-cur;
+ else
+ lendir = strlen(cur);
+ if (lendir == 0)
+ continue;
+ LTDL_CHECK_SIZE(filename, size, \
+ lendir + 1 + overhead + 1, 0);
+ strncpy(filename, cur, lendir);
+ if (next)
cur = next+1;
- } else {
- if (strlen(cur)+1 >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- return 0;
- }
- strcpy(filename, cur);
+ else
cur = 0;
- }
- if (!*filename)
- continue;
- strcat(filename, "/");
- if (strlen(filename)+strlen(basename) < LTDL_FILENAME_MAX) {
- strcat(filename, basename);
- file = fopen(filename, LTDL_READTEXT_MODE);
- if (file)
- return file;
+ filename[lendir] = '/';
+ strncpy(filename+lendir+1, basename, baselen+1);
+ file = fopen(filename, LTDL_READTEXT_MODE);
+ if (file) {
+ filename[lendir+1] = '\0';
+ *pdir = filename;
+ return file;
}
}
+ free(filename);
last_error = file_not_found_error;
return 0;
}
return 0;
}
+#undef LTDL_TRIM
+#define LTDL_TRIM(dest_, s_) do { \
+ char **dest = &(dest_); \
+ char *s = (s_); \
+ int len = strlen(s); \
+ \
+ if (*dest) \
+ free(*dest); \
+ *dest = 0; \
+ \
+ if (len > 3 && s[0] == '\'' \
+ && s[len-1] == '\n' && s[len-2] == '\'') { \
+ *dest = malloc(len-2); \
+ if (!*dest) \
+ goto trim_raise_memory_error; \
+ strncpy(*dest, &s[1], len - 3); \
+ (*dest)[len-3] = '\0'; \
+ } \
+} while(0)
+
lt_dlhandle
lt_dlopen (filename)
const char *filename;
{
- lt_dlhandle handle;
- char dir[LTDL_FILENAME_MAX];
- const char *basename, *ext, *search_path;
-#ifdef LTDL_SHLIBPATH_VAR
- const char *sys_search_path;
-#endif
+ lt_dlhandle handle = 0;
+ char *dir = 0;
+ const char *basename, *ext;
const char *saved_error = last_error;
basename = strrchr(filename, '/');
- if (basename)
+ if (basename) {
basename++;
- else
+ dir = malloc(basename - filename + strlen(LTDL_OBJDIR) + 1);
+ if (!dir) {
+ last_error = memory_error;
+ return 0;
+ }
+ strncpy(dir, filename, basename-filename);
+ dir[basename-filename] = '\0';
+ } else
basename = filename;
- if (basename - filename >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- return 0;
- }
- strncpy(dir, filename, basename - filename);
- dir[basename - filename] = '\0';
- search_path = getenv("LTDL_LIBRARY_PATH"); /* get the search path */
-#ifdef LTDL_SHLIBPATH_VAR
- sys_search_path = getenv(LTDL_SHLIBPATH_VAR);
-#endif
+
/* check whether we open a libtool module (.la extension) */
ext = strrchr(basename, '.');
if (ext && strcmp(ext, ".la") == 0) {
- char dlname[LTDL_FILENAME_MAX], old_name[LTDL_FILENAME_MAX];
- char libdir[LTDL_FILENAME_MAX], deplibs[LTDL_FILENAME_MAX];
+ char *dlname = 0, *old_name = 0;
+ char *libdir = 0, *deplibs = 0;
char tmp[LTDL_FILENAME_MAX];
char *name;
FILE *file;
of libtool */
int installed=1;
- dlname[0] = old_name[0] = libdir[0] = deplibs[0] = '\0';
-
/* extract the module name from the file name */
- if (strlen(basename) >= LTDL_FILENAME_MAX) {
+ if (strlen(basename) >= sizeof(tmp)) {
last_error = buffer_overflow_error;
return 0;
}
return 0;
}
file = fopen(filename, LTDL_READTEXT_MODE);
- if (!file && !*dir) {
+ if (!file && !dir) {
/* try other directories */
- file = find_file(basename, usr_search_path);
+ file = find_file(basename, usr_search_path, &dir);
if (!file)
- file = find_file(basename, search_path);
+ file = find_file(basename,
+ getenv("LTDL_LIBRARY_PATH"),
+ &dir);
#ifdef LTDL_SHLIBPATH_VAR
if (!file)
- file = find_file(basename, sys_search_path);
+ file = find_file(basename,
+ getenv(LTDL_SHLIBPATH_VAR),
+ &dir);
#endif
}
if (!file) {
+ clean_up_name:
free(name);
- return 0;
+ goto clean_up_dir;
}
while (!feof(file)) {
- if (!fgets(tmp, LTDL_FILENAME_MAX, file))
+ if (!fgets(tmp, sizeof(tmp), file))
break;
+ if (tmp[0] == '\n' || tmp[0] == '#')
+ ;
+ else
if (strncmp(tmp, "dlname=", 7) == 0)
- trim(dlname, &tmp[7]);
+ LTDL_TRIM(dlname, &tmp[7]);
else
if (strncmp(tmp, "old_library=", 12) == 0)
- trim(old_name, &tmp[12]);
+ LTDL_TRIM(old_name, &tmp[12]);
else
if (strncmp(tmp, "libdir=", 7) == 0)
- trim(libdir, &tmp[7]);
+ LTDL_TRIM(libdir, &tmp[7]);
else
if (strncmp(tmp, "dl_dependency_libs=", 20) == 0)
- trim(deplibs, &tmp[20]);
+ LTDL_TRIM(deplibs, &tmp[20]);
else
if (strcmp(tmp, "installed=yes\n") == 0)
installed = 1;
else
if (strcmp(tmp, "installed=no\n") == 0)
installed = 0;
+ else
+ if (0) {
+ trim_raise_memory_error:
+ fclose(file);
+ goto handle_raise_memory_error;
+ }
}
fclose(file);
handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
if (!handle) {
+ handle_raise_memory_error:
last_error = memory_error;
- free(name);
- return 0;
+ goto clean_up_vars;
}
- if (load_deplibs(handle, deplibs)) {
+ if (deplibs && load_deplibs(handle, deplibs)) {
+ clean_up_handle:
free(handle);
- free(name);
- return 0;
+ handle = 0;
+ goto clean_up_vars;
}
if (installed) {
if (find_module(&handle, libdir, dlname, old_name)) {
+ clean_up_deplibs:
unload_deplibs(handle);
- free(handle);
- free(name);
- return 0;
+ goto clean_up_handle;
}
} else {
- if (strlen(dir) + strlen(LTDL_OBJDIR)
- >= LTDL_FILENAME_MAX) {
- last_error = buffer_overflow_error;
- unload_deplibs(handle);
- free(handle);
- free(name);
- return 0;
- }
- strcat(dir, LTDL_OBJDIR);
- if (find_module(&handle, dir, dlname, old_name)) {
- unload_deplibs(handle);
- free(handle);
- free(name);
- return 0;
- }
+ /* We dir is non-NULL, it has enough space for
+ LTDL_OBJDIR: it was reserved in the
+ beginning of the function or within
+ find_file */
+ if (dir)
+ strcat(dir, LTDL_OBJDIR);
+ if (find_module(&handle,
+ dir ? dir : LTDL_OBJDIR,
+ dlname, old_name))
+ goto clean_up_deplibs;
}
handle->name = name;
+ clean_up_vars:
+ if (dlname)
+ free(dlname);
+ if (old_name)
+ free(old_name);
+ if (libdir)
+ free(libdir);
+ if (deplibs)
+ free(deplibs);
+ if (!handle)
+ goto clean_up_name;
} else {
/* not a libtool module */
handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
if (!handle) {
last_error = memory_error;
- return 0;
+ goto clean_up_dir;
}
if (tryall_dlopen(&handle, filename)
- && (*dir
+ && (dir
|| (find_library(&handle, basename, usr_search_path)
- && find_library(&handle, basename, search_path)
+ && find_library(&handle, basename,
+ getenv("LTDL_LIBRARY_PATH"))
#ifdef LTDL_SHLIBPATH_VAR
- && find_library(&handle, basename, sys_search_path)
+ && find_library(&handle, basename,
+ getenv(LTDL_SHLIBPATH_VAR))
#endif
))) {
free(handle);
- return 0;
+ handle = 0;
+ goto clean_up_dir;
}
handle->name = 0;
}
handle->next = handles;
handles = handle;
last_error = saved_error;
+ clean_up_dir:
+ if (dir)
+ free(dir);
return handle;
}
const char *search_dir;
{
if (!search_dir) {
- usr_search_path[0] = '\0'; /* reset the search path */
+ if (usr_search_path)
+ free(usr_search_path);
+ usr_search_path = 0; /* reset the search path */
return 0;
}
if (!strlen(search_dir))
return 0;
- if (strlen(usr_search_path) + strlen(search_dir) + 1
- >= LTDL_SEARCHPATH_MAX) {
- last_error = buffer_overflow_error;
- return 1;
- }
- if (usr_search_path[0] != '\0')
+ if (!usr_search_path) {
+ usr_search_path_size = strlen(search_dir)+1;
+ usr_search_path = malloc(usr_search_path_size);
+ if (!usr_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ strcpy(usr_search_path, search_dir);
+ } else {
+ int new_size = usr_search_path_size + strlen(search_dir) + 1;
+ char *new_search_path = realloc(usr_search_path, new_size);
+ if (!new_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ usr_search_path = new_search_path;
+ usr_search_path_size = new_size;
strcat(usr_search_path, ":");
- strcat(usr_search_path, search_dir);
+ strcat(usr_search_path, search_dir);
+ }
return 0;
}
lt_dlsetsearchpath (search_path)
const char *search_path;
{
- if (!search_path) {
- usr_search_path[0] = '\0'; /* reset the search path */
+ if (usr_search_path)
+ free(usr_search_path);
+ usr_search_path = 0; /* reset the search path */
+ if (!search_path || !strlen(search_path)) {
return 0;
}
- if (!strlen(search_path))
- return 0;
- if (strlen(search_path) >= LTDL_SEARCHPATH_MAX) {
- last_error = buffer_overflow_error;
+ usr_search_path = strdup(search_path);
+ if (usr_search_path)
+ usr_search_path_size = strlen(usr_search_path)+1;
+ else
return 1;
- }
- strcpy(usr_search_path, search_path);
return 0;
}