diff options
Diffstat (limited to 'hw/xfree86/loader/loadmod.c')
-rw-r--r-- | hw/xfree86/loader/loadmod.c | 1904 |
1 files changed, 960 insertions, 944 deletions
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c index deba80643..733f6feb1 100644 --- a/hw/xfree86/loader/loadmod.c +++ b/hw/xfree86/loader/loadmod.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.68 2002/07/30 18:36:18 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.73 2003/11/03 05:11:51 tsi Exp $ */ /* * @@ -22,8 +22,32 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - -/* This file is best viewed with tab stops set to 4 spaces */ +/* + * Copyright (c) 1997-2002 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ #include "os.h" /* For stat() and related stuff */ @@ -48,50 +72,51 @@ extern int check_unresolved_sema; typedef struct _pattern { - const char * pattern; - regex_t rex; + const char *pattern; + regex_t rex; } PatternRec, *PatternPtr; /* Prototypes for static functions */ -static char *FindModule (const char *, const char *, const char **, PatternPtr); -static Bool CheckVersion (const char *, XF86ModuleVersionInfo *, - const XF86ModReqInfo *); -static void UnloadModuleOrDriver (ModuleDescPtr mod); +static char *FindModule(const char *, const char *, const char **, + PatternPtr); +static Bool CheckVersion(const char *, XF86ModuleVersionInfo *, + const XF86ModReqInfo *); +static void UnloadModuleOrDriver(ModuleDescPtr mod); static char *LoaderGetCanonicalName(const char *, PatternPtr); static void RemoveChild(ModuleDescPtr); ModuleVersions LoaderVersionInfo = { - XF86_VERSION_CURRENT, - ABI_ANSIC_VERSION, - ABI_VIDEODRV_VERSION, - ABI_XINPUT_VERSION, - ABI_EXTENSION_VERSION, - ABI_FONT_VERSION + XF86_VERSION_CURRENT, + ABI_ANSIC_VERSION, + ABI_VIDEODRV_VERSION, + ABI_XINPUT_VERSION, + ABI_EXTENSION_VERSION, + ABI_FONT_VERSION }; #if 0 void -LoaderFixups (void) +LoaderFixups(void) { - /* Need to call LRS here because the frame buffers get loaded last, - * and the drivers depend on them. */ + /* Need to call LRS here because the frame buffers get loaded last, + * and the drivers depend on them. */ - LoaderResolveSymbols (); + LoaderResolveSymbols(); } #endif static void FreeStringList(char **paths) { - char **p; + char **p; - if (!paths) - return; + if (!paths) + return; - for (p = paths; *p; p++) - xfree(*p); + for (p = paths; *p; p++) + xfree(*p); - xfree(paths); + xfree(paths); } static char **defaultPathList = NULL; @@ -104,90 +129,89 @@ static char **defaultPathList = NULL; static char ** InitPathList(const char *path) { - char *fullpath = NULL; - char *elem = NULL; - char **list = NULL, **save = NULL; - int len; - int addslash; - int n = 0; - - if (!path) - return defaultPathList; - - fullpath = xstrdup(path); - if (!fullpath) - return NULL; - elem = strtok(fullpath, ","); - while (elem) { - /* Only allow fully specified paths */ + char *fullpath = NULL; + char *elem = NULL; + char **list = NULL, **save = NULL; + int len; + int addslash; + int n = 0; + + if (!path) + return defaultPathList; + + fullpath = xstrdup(path); + if (!fullpath) + return NULL; + elem = strtok(fullpath, ","); + while (elem) { + /* Only allow fully specified paths */ #ifndef __UNIXOS2__ - if (*elem == '/') + if (*elem == '/') #else - if (*elem == '/' || (strlen(elem) > 2 && isalpha(elem[0]) && - elem[1] == ':' && elem[2] == '/')) + if (*elem == '/' || (strlen(elem) > 2 && isalpha(elem[0]) && + elem[1] == ':' && elem[2] == '/')) #endif - { - len = strlen(elem); - addslash = (elem[len - 1] != '/'); - if (addslash) - len++; - save = list; - list = xrealloc(list, (n + 2) * sizeof(char *)); - if (!list) { - if (save) { - save[n] = NULL; - FreeStringList(save); - } - xfree(fullpath); - return NULL; - } - list[n] = xalloc(len + 1); - if (!list[n]) { - FreeStringList(list); - xfree(fullpath); - return NULL; - } - strcpy(list[n], elem); - if (addslash) { - list[n][len - 1] = '/'; - list[n][len] = '\0'; - } - n++; + { + len = strlen(elem); + addslash = (elem[len - 1] != '/'); + if (addslash) + len++; + save = list; + list = xrealloc(list, (n + 2) * sizeof(char *)); + if (!list) { + if (save) { + save[n] = NULL; + FreeStringList(save); } - elem = strtok(NULL, ","); + xfree(fullpath); + return NULL; + } + list[n] = xalloc(len + 1); + if (!list[n]) { + FreeStringList(list); + xfree(fullpath); + return NULL; + } + strcpy(list[n], elem); + if (addslash) { + list[n][len - 1] = '/'; + list[n][len] = '\0'; + } + n++; } - if (list) - list[n] = NULL; - return list; + elem = strtok(NULL, ","); + } + if (list) + list[n] = NULL; + return list; } static void FreePathList(char **pathlist) { - if (pathlist && pathlist != defaultPathList) - FreeStringList(pathlist); + if (pathlist && pathlist != defaultPathList) + FreeStringList(pathlist); } void LoaderSetPath(const char *path) { - if (!path) - return; + if (!path) + return; - defaultPathList = InitPathList(path); + defaultPathList = InitPathList(path); } /* Standard set of module subdirectories to search, in order of preference */ -static const char *stdSubdirs[] = -{ - "drivers/", - "input/", - "multimedia/", - "extensions/", - "fonts/", - "internal/", - "", - NULL +static const char *stdSubdirs[] = { + "drivers/", + "input/", + "multimedia/", + "extensions/", + "fonts/", + "internal/", + "", + NULL }; /* @@ -195,519 +219,529 @@ static const char *stdSubdirs[] = * These are regular expressions (suitable for use with POSIX regex(3)). */ static PatternRec stdPatterns[] = { - { "^lib(.*)\\.so$", }, - { "^lib(.*)\\.a$", }, - { "(.*)_drv\\.so$", }, - { "(.*)_drv\\.o$", }, - { "(.*)\\.so$", }, - { "(.*)\\.a$", }, - { "(.*)\\.o$", }, - { NULL, } + {"^lib(.*)\\.so$",}, + {"^lib(.*)\\.a$",}, + {"(.*)_drv\\.so$",}, + {"(.*)_drv\\.o$",}, + {"(.*)\\.so$",}, + {"(.*)\\.a$",}, + {"(.*)\\.o$",}, + {NULL,} }; static PatternPtr InitPatterns(const char **patternlist) { - char errmsg[80]; - int i, e; - PatternPtr patterns = NULL; - PatternPtr p = NULL; - static int firstTime = 1; - const char **s; - - if (firstTime) { - /* precompile stdPatterns */ - firstTime = 0; - for (p = stdPatterns; p->pattern; p++) - if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) { - regerror(e, &p->rex, errmsg, sizeof(errmsg)); - FatalError("InitPatterns: regcomp error for `%s': %s\n", - p->pattern, errmsg); - } + char errmsg[80]; + int i, e; + PatternPtr patterns = NULL; + PatternPtr p = NULL; + static int firstTime = 1; + const char **s; + + if (firstTime) { + /* precompile stdPatterns */ + firstTime = 0; + for (p = stdPatterns; p->pattern; p++) + if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) { + regerror(e, &p->rex, errmsg, sizeof(errmsg)); + FatalError("InitPatterns: regcomp error for `%s': %s\n", + p->pattern, errmsg); + } + } + + if (patternlist) { + for (i = 0, s = patternlist; *s; i++, s++) + if (*s == DEFAULT_LIST) + i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1; + patterns = xalloc((i + 1) * sizeof(PatternRec)); + if (!patterns) { + return NULL; } - - if (patternlist) { - for (i = 0, s = patternlist; *s; i++, s++) - if (*s == DEFAULT_LIST) - i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1; - patterns = xalloc((i + 1) * sizeof(PatternRec)); - if (!patterns) { - return NULL; + for (i = 0, s = patternlist; *s; i++, s++) + if (*s != DEFAULT_LIST) { + p = patterns + i; + p->pattern = *s; + if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) { + regerror(e, &p->rex, errmsg, sizeof(errmsg)); + ErrorF("InitPatterns: regcomp error for `%s': %s\n", + p->pattern, errmsg); + i--; } - for (i = 0, s = patternlist; *s; i++, s++) - if (*s != DEFAULT_LIST) { - p = patterns + i; - p->pattern = *s; - if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) { - regerror(e, &p->rex, errmsg, sizeof(errmsg)); - ErrorF("InitPatterns: regcomp error for `%s': %s\n", - p->pattern, errmsg); - i--; - } - } else { - for (p = stdPatterns; p->pattern; p++, i++) - patterns[i] = *p; - if (p != stdPatterns) - i--; - } - patterns[i].pattern = NULL; - } else - patterns = stdPatterns; - return patterns; + } else { + for (p = stdPatterns; p->pattern; p++, i++) + patterns[i] = *p; + if (p != stdPatterns) + i--; + } + patterns[i].pattern = NULL; + } else + patterns = stdPatterns; + return patterns; } static void FreePatterns(PatternPtr patterns) { - if (patterns && patterns != stdPatterns) - xfree(patterns); + if (patterns && patterns != stdPatterns) + xfree(patterns); } static const char ** InitSubdirs(const char **subdirlist) { - int i; - char **subdirs = NULL; - const char **s, **stmp = NULL; + int i; + const char **tmp_subdirlist = NULL; + char **subdirs = NULL; + const char **s, **stmp = NULL; const char *osname; const char *slash; int oslen = 0, len; Bool indefault; if (subdirlist == NULL) { - subdirlist = xalloc(2 * sizeof(char *)); - if (subdirlist == NULL) - return NULL; - subdirlist[0] = DEFAULT_LIST; - subdirlist[1] = NULL; - } - + subdirlist = tmp_subdirlist = xalloc(2 * sizeof(char *)); + if (subdirlist == NULL) + return NULL; + subdirlist[0] = DEFAULT_LIST; + subdirlist[1] = NULL; + } + LoaderGetOS(&osname, NULL, NULL, NULL); oslen = strlen(osname); { - /* Count number of entries and check for invalid paths */ - for (i = 0, s = subdirlist; *s; i++, s++) { - if (*s == DEFAULT_LIST) { - i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1; - } else { - /* - * Path validity check. Don't allow absolute paths, or - * paths containing "..". To catch absolute paths on - * platforms that use driver letters, don't allow the ':' - * character to appear at all. - */ - if (**s == '/' || **s == '\\' || strchr(*s, ':') || - strstr(*s, "..")) { - xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s); - return NULL; - } - } + /* Count number of entries and check for invalid paths */ + for (i = 0, s = subdirlist; *s; i++, s++) { + if (*s == DEFAULT_LIST) { + i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1; + } else { + /* + * Path validity check. Don't allow absolute paths, or + * paths containing "..". To catch absolute paths on + * platforms that use driver letters, don't allow the ':' + * character to appear at all. + */ + if (**s == '/' || **s == '\\' || strchr(*s, ':') || + strstr(*s, "..")) { + xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s); + if (tmp_subdirlist) + xfree(tmp_subdirlist); + return NULL; } - subdirs = xalloc((i * 2 + 1) * sizeof(char *)); - if (!subdirs) - return NULL; - i = 0; - s = subdirlist; + } + } + subdirs = xalloc((i * 2 + 1) * sizeof(char *)); + if (!subdirs) { + if (tmp_subdirlist) + xfree(tmp_subdirlist); + return NULL; + } + i = 0; + s = subdirlist; + indefault = FALSE; + while (*s) { + if (*s == DEFAULT_LIST) { + /* Divert to the default list */ + indefault = TRUE; + stmp = ++s; + s = stdSubdirs; + } + len = strlen(*s); + if (**s && (*s)[len - 1] != '/') { + slash = "/"; + len++; + } else + slash = ""; + len += oslen + 2; + if (!(subdirs[i] = xalloc(len))) { + while (--i >= 0) + xfree(subdirs[i]); + xfree(subdirs); + if (tmp_subdirlist) + xfree(tmp_subdirlist); + return NULL; + } + /* tack on the OS name */ + sprintf(subdirs[i], "%s%s%s/", *s, slash, osname); + i++; + /* path as given */ + subdirs[i] = xstrdup(*s); + i++; + s++; + if (indefault && !s) { + /* revert back to the main list */ indefault = FALSE; - while (*s) { - if (*s == DEFAULT_LIST) { - /* Divert to the default list */ - indefault = TRUE; - stmp = ++s; - s = stdSubdirs; - } - len = strlen(*s); - if (**s && (*s)[len - 1] != '/') { - slash = "/"; - len++; - } else - slash = ""; - len += oslen + 2; - if (!(subdirs[i] = xalloc(len))) - return NULL; - /* tack on the OS name */ - sprintf(subdirs[i], "%s%s%s/", *s, slash, osname); - i++; - /* path as given */ - subdirs[i] = xstrdup(*s); - i++; - s++; - if (indefault && !s) { - /* revert back to the main list */ - indefault = FALSE; - s = stmp; - } - } - subdirs[i] = NULL; + s = stmp; + } } - return (const char **)subdirs; + subdirs[i] = NULL; + } + if (tmp_subdirlist) + xfree(tmp_subdirlist); + return (const char **)subdirs; } static void FreeSubdirs(const char **subdirs) { - const char **s; + const char **s; - if (subdirs) { - for (s = subdirs; *s; s++) - xfree(*s); - xfree(subdirs); - } + if (subdirs) { + for (s = subdirs; *s; s++) + xfree(*s); + xfree(subdirs); + } } static char * -FindModule (const char *module, const char *dir, const char **subdirlist, - PatternPtr patterns) +FindModule(const char *module, const char *dir, const char **subdirlist, + PatternPtr patterns) { - char buf[PATH_MAX + 1]; - char *dirpath = NULL; - char *name = NULL; - struct stat stat_buf; - int len, dirlen; - char *fp; - DIR *d; - const char **subdirs = NULL; - PatternPtr p = NULL; - const char **s; - struct dirent *dp; - regmatch_t match[2]; - - subdirs = InitSubdirs(subdirlist); - if (!subdirs) - return NULL; + char buf[PATH_MAX + 1]; + char *dirpath = NULL; + char *name = NULL; + struct stat stat_buf; + int len, dirlen; + char *fp; + DIR *d; + const char **subdirs = NULL; + PatternPtr p = NULL; + const char **s; + struct dirent *dp; + regmatch_t match[2]; + + subdirs = InitSubdirs(subdirlist); + if (!subdirs) + return NULL; #ifndef __EMX__ - dirpath = (char *)dir; + dirpath = (char *)dir; #else - dirpath = xalloc(strlen(dir) + 10); - strcpy(dirpath, (char *) __XOS2RedirRoot (dir)); + dirpath = xalloc(strlen(dir) + 10); + strcpy(dirpath, (char *)__XOS2RedirRoot(dir)); #endif - if (strlen(dirpath) > PATH_MAX) - return NULL; - /*xf86Msg(X_INFO,"OS2DIAG: FindModule: dirpath=%s\n",dirpath);*/ - - for (s = subdirs; *s; s++) { - if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX) - continue; - strcpy(buf, dirpath); - strcat(buf, *s); - /*xf86Msg(X_INFO,"OS2DIAG: FindModule: buf=%s\n",buf);*/ - fp = buf + dirlen; - if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && - (d = opendir(buf))) { - if (buf[dirlen - 1] != '/') { - buf[dirlen++] = '/'; - fp++; - } - while ((dp = readdir(d))) { - if (dirlen + strlen(dp->d_name) + 1 > PATH_MAX) - continue; - strcpy(fp, dp->d_name); - if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode))) - continue; - for (p = patterns; p->pattern; p++) { - if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && - match[1].rm_so != -1) { - len = match[1].rm_eo - match[1].rm_so; - if (len == strlen(module) && - strncmp(module, dp->d_name + match[1].rm_so, len) == 0) { - /*xf86Msg(X_INFO,"OS2DIAG: matching %s\n",buf);*/ - name = buf; - break; - } - } - } - if (name) - break; + if (strlen(dirpath) > PATH_MAX) + return NULL; + /*xf86Msg(X_INFO,"OS2DIAG: FindModule: dirpath=%s\n",dirpath); */ + + for (s = subdirs; *s; s++) { + if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX) + continue; + strcpy(buf, dirpath); + strcat(buf, *s); + /*xf86Msg(X_INFO,"OS2DIAG: FindModule: buf=%s\n",buf); */ + fp = buf + dirlen; + if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && + (d = opendir(buf))) { + if (buf[dirlen - 1] != '/') { + buf[dirlen++] = '/'; + fp++; + } + while ((dp = readdir(d))) { + if (dirlen + strlen(dp->d_name) + 1 > PATH_MAX) + continue; + strcpy(fp, dp->d_name); + if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode))) + continue; + for (p = patterns; p->pattern; p++) { + if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && + match[1].rm_so != -1) { + len = match[1].rm_eo - match[1].rm_so; + if (len == strlen(module) && + strncmp(module, dp->d_name + match[1].rm_so, + len) == 0) { + /*xf86Msg(X_INFO,"OS2DIAG: matching %s\n",buf); */ + name = buf; + break; } - closedir(d); - if (name) - break; + } } + if (name) + break; + } + closedir(d); + if (name) + break; } - FreeSubdirs(subdirs); - if (dirpath != dir) - xfree(dirpath); - - if (name) { - return xstrdup(name); - } - return NULL; + } + FreeSubdirs(subdirs); + if (dirpath != dir) + xfree(dirpath); + + if (name) { + return xstrdup(name); + } + return NULL; } char ** LoaderListDirs(const char **subdirlist, const char **patternlist) { - char buf[PATH_MAX + 1]; - char **pathlist; - char **elem; - const char **subdirs; - const char **s; - PatternPtr patterns; - PatternPtr p; - DIR *d; - struct dirent *dp; - regmatch_t match[2]; - struct stat stat_buf; - int len, dirlen; - char *fp; - char **listing = NULL; - char **save; - int n = 0; - - if (!(pathlist = InitPathList(NULL))) - return NULL; - if (!(subdirs = InitSubdirs(subdirlist))) { - FreePathList(pathlist); - return NULL; - } - if (!(patterns = InitPatterns(patternlist))) { - FreePathList(pathlist); - FreeSubdirs(subdirs); - return NULL; - } + char buf[PATH_MAX + 1]; + char **pathlist; + char **elem; + const char **subdirs; + const char **s; + PatternPtr patterns; + PatternPtr p; + DIR *d; + struct dirent *dp; + regmatch_t match[2]; + struct stat stat_buf; + int len, dirlen; + char *fp; + char **listing = NULL; + char **save; + int n = 0; + + if (!(pathlist = InitPathList(NULL))) + return NULL; + if (!(subdirs = InitSubdirs(subdirlist))) { + FreePathList(pathlist); + return NULL; + } + if (!(patterns = InitPatterns(patternlist))) { + FreePathList(pathlist); + FreeSubdirs(subdirs); + return NULL; + } - for (elem = pathlist; *elem; elem++) { - for (s = subdirs; *s; s++) { - if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX) - continue; - strcpy(buf, *elem); - strcat(buf, *s); - fp = buf + dirlen; - if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && - (d = opendir(buf))) { - if (buf[dirlen - 1] != '/') { - buf[dirlen++] = '/'; - fp++; - } - while ((dp = readdir(d))) { - if (dirlen + strlen(dp->d_name) > PATH_MAX) - continue; - strcpy(fp, dp->d_name); - if (!(stat(buf, &stat_buf) == 0 && - S_ISREG(stat_buf.st_mode))) - continue; - for (p = patterns; p->pattern; p++) { - if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && - match[1].rm_so != -1) { - len = match[1].rm_eo - match[1].rm_so; - save = listing; - listing = xrealloc(listing, - (n + 2) * sizeof(char *)); - if (!listing) { - if (save) { - save[n] = NULL; - FreeStringList(save); - } - FreePathList(pathlist); - FreeSubdirs(subdirs); - FreePatterns(patterns); - return NULL; - } - listing[n] = xalloc(len + 1); - if (!listing[n]) { - FreeStringList(listing); - FreePathList(pathlist); - FreeSubdirs(subdirs); - FreePatterns(patterns); - return NULL; - } - strncpy(listing[n], dp->d_name + match[1].rm_so, - len); - listing[n][len] = '\0'; - n++; - break; - } - } + for (elem = pathlist; *elem; elem++) { + for (s = subdirs; *s; s++) { + if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX) + continue; + strcpy(buf, *elem); + strcat(buf, *s); + fp = buf + dirlen; + if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && + (d = opendir(buf))) { + if (buf[dirlen - 1] != '/') { + buf[dirlen++] = '/'; + fp++; + } + while ((dp = readdir(d))) { + if (dirlen + strlen(dp->d_name) > PATH_MAX) + continue; + strcpy(fp, dp->d_name); + if (!(stat(buf, &stat_buf) == 0 && + S_ISREG(stat_buf.st_mode))) + continue; + for (p = patterns; p->pattern; p++) { + if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && + match[1].rm_so != -1) { + len = match[1].rm_eo - match[1].rm_so; + save = listing; + listing = xrealloc(listing, + (n + 2) * sizeof(char *)); + if (!listing) { + if (save) { + save[n] = NULL; + FreeStringList(save); } - closedir(d); + FreePathList(pathlist); + FreeSubdirs(subdirs); + FreePatterns(patterns); + return NULL; + } + listing[n] = xalloc(len + 1); + if (!listing[n]) { + FreeStringList(listing); + FreePathList(pathlist); + FreeSubdirs(subdirs); + FreePatterns(patterns); + return NULL; + } + strncpy(listing[n], dp->d_name + match[1].rm_so, + len); + listing[n][len] = '\0'; + n++; + break; } + } } + closedir(d); + } } - if (listing) - listing[n] = NULL; - return listing; + } + if (listing) + listing[n] = NULL; + return listing; } void LoaderFreeDirList(char **list) { - FreeStringList(list); + FreeStringList(list); } - static Bool -CheckVersion (const char *module, XF86ModuleVersionInfo *data, - const XF86ModReqInfo *req) +CheckVersion(const char *module, XF86ModuleVersionInfo * data, + const XF86ModReqInfo * req) { - int vercode[4]; - char verstr[4]; - long ver = data->xf86version; - int errtype = 0; - - xf86Msg (X_INFO, "Module %s: vendor=\"%s\"\n", - data->modname ? data->modname : "UNKNOWN!", - data->vendor ? data->vendor : "UNKNOWN!"); - - if (ver > (4 << 24)) { - /* 4.0.x and earlier */ - verstr[1] = verstr[3] = 0; - verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0; - ver >>= 5; - verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0; - ver >>= 5; - vercode[2] = ver & 0x7f; - ver >>= 7; - vercode[1] = ver & 0x7f; - ver >>= 7; - vercode[0] = ver; - xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]); - if (vercode[2] != 0) - xf86ErrorF(".%d", vercode[2]); - xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2, - data->majorversion, data->minorversion, data->patchlevel); - } else { - vercode[0] = ver / 10000000; - vercode[1] = (ver / 100000) % 100; - vercode[2] = (ver / 1000) % 100; - vercode[3] = ver % 1000; - xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1], - vercode[2]); - if (vercode[3] != 0) - xf86ErrorF(".%d", vercode[3]); - xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion, - data->minorversion, data->patchlevel); - } + int vercode[4]; + char verstr[4]; + long ver = data->xf86version; + MessageType errtype; + + xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n", + data->modname ? data->modname : "UNKNOWN!", + data->vendor ? data->vendor : "UNKNOWN!"); + + if (ver > (4 << 24)) { + /* 4.0.x and earlier */ + verstr[1] = verstr[3] = 0; + verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0; + ver >>= 5; + verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0; + ver >>= 5; + vercode[2] = ver & 0x7f; + ver >>= 7; + vercode[1] = ver & 0x7f; + ver >>= 7; + vercode[0] = ver; + xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]); + if (vercode[2] != 0) + xf86ErrorF(".%d", vercode[2]); + xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2, + data->majorversion, data->minorversion, data->patchlevel); + } else { + vercode[0] = ver / 10000000; + vercode[1] = (ver / 100000) % 100; + vercode[2] = (ver / 1000) % 100; + vercode[3] = ver % 1000; + xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1], + vercode[2]); + if (vercode[3] != 0) + xf86ErrorF(".%d", vercode[3]); + xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion, + data->minorversion, data->patchlevel); + } if (data->moduleclass) - xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass); - - ver = -1; - if (data->abiclass) { - int abimaj, abimin; - int vermaj, vermin; - - if (!strcmp(data->abiclass, ABI_CLASS_ANSIC)) - ver = LoaderVersionInfo.ansicVersion; - else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV)) - ver = LoaderVersionInfo.videodrvVersion; - else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT)) - ver = LoaderVersionInfo.xinputVersion; - else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION)) - ver = LoaderVersionInfo.extensionVersion; - else if (!strcmp(data->abiclass, ABI_CLASS_FONT)) - ver = LoaderVersionInfo.fontVersion; - - abimaj = GET_ABI_MAJOR(data->abiversion); - abimin = GET_ABI_MINOR(data->abiversion); - xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n", - data->abiclass, abimaj, abimin); - if (ver != -1) { - vermaj = GET_ABI_MAJOR(ver); - vermin = GET_ABI_MINOR(ver); - if (abimaj != vermaj) { - if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) - errtype = X_WARNING; - else - errtype = X_ERROR; - xf86MsgVerb(errtype, 0, - "module ABI major version (%d) doesn't" - " match the server's version (%d)\n", - abimaj, vermaj); - if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)) - return FALSE; - } else if (abimin > vermin) { - if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) - errtype = X_WARNING; - else - errtype = X_ERROR; - xf86MsgVerb(errtype, 0, - "module ABI minor version (%d) is " - "newer than the server's version " - "(%d)\n", abimin, vermin); - if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)) - return FALSE; - } - } + xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass); + + ver = -1; + if (data->abiclass) { + int abimaj, abimin; + int vermaj, vermin; + + if (!strcmp(data->abiclass, ABI_CLASS_ANSIC)) + ver = LoaderVersionInfo.ansicVersion; + else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV)) + ver = LoaderVersionInfo.videodrvVersion; + else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT)) + ver = LoaderVersionInfo.xinputVersion; + else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION)) + ver = LoaderVersionInfo.extensionVersion; + else if (!strcmp(data->abiclass, ABI_CLASS_FONT)) + ver = LoaderVersionInfo.fontVersion; + + abimaj = GET_ABI_MAJOR(data->abiversion); + abimin = GET_ABI_MINOR(data->abiversion); + xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n", + data->abiclass, abimaj, abimin); + if (ver != -1) { + vermaj = GET_ABI_MAJOR(ver); + vermin = GET_ABI_MINOR(ver); + if (abimaj != vermaj) { + if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) + errtype = X_WARNING; + else + errtype = X_ERROR; + xf86MsgVerb(errtype, 0, + "module ABI major version (%d) doesn't" + " match the server's version (%d)\n", + abimaj, vermaj); + if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)) + return FALSE; + } else if (abimin > vermin) { + if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) + errtype = X_WARNING; + else + errtype = X_ERROR; + xf86MsgVerb(errtype, 0, + "module ABI minor version (%d) is " + "newer than the server's version " + "(%d)\n", abimin, vermin); + if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)) + return FALSE; + } } - - /* Check against requirements that the caller has specified */ - if (req) { - if (req->majorversion != MAJOR_UNSPEC) { - if (data->majorversion != req->majorversion) { - xf86MsgVerb(X_WARNING, 2, "module major version (%d) " - "doesn't match required major version (%d)\n", - data->majorversion, req->majorversion); - return FALSE; - } else if (req->minorversion != MINOR_UNSPEC) { - if (data->minorversion < req->minorversion) { - xf86MsgVerb(X_WARNING, 2, "module minor version (%d) " - "is less than the required minor version (%d)\n", - data->minorversion, req->minorversion); - return FALSE; - } else if (data->minorversion == req->minorversion && - req->patchlevel != PATCH_UNSPEC) { - if (data->patchlevel < req->patchlevel) { - xf86MsgVerb(X_WARNING, 2, "module patch level (%d) " - "is less than the required patch level (%d)\n", - data->patchlevel, req->patchlevel); - return FALSE; - } - } - } - } - if (req->moduleclass) { - if (!data->moduleclass || - strcmp(req->moduleclass, data->moduleclass)) { - xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match " - "the required class (%s)\n", - data->moduleclass ? data->moduleclass : "<NONE>", - req->moduleclass); - return FALSE; - } - } else if (req->abiclass != ABI_CLASS_NONE) { - if (!data->abiclass || strcmp(req->abiclass, data->moduleclass)) { - xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the " - "required ABI class (%s)\n", - data->abiclass ? data->abiclass : "<NONE>", - req->abiclass); - return FALSE; - } - } - if ((req->abiclass != ABI_CLASS_NONE) && - req->abiversion != ABI_VERS_UNSPEC) { - int reqmaj, reqmin, maj, min; - reqmaj = GET_ABI_MAJOR(req->abiversion); - reqmin = GET_ABI_MINOR(req->abiversion); - maj = GET_ABI_MAJOR(data->abiversion); - min = GET_ABI_MINOR(data->abiversion); - if (maj != reqmaj) { - xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't " - "match the required ABI major version (%d)\n", - maj, reqmaj); - return FALSE; - } - /* XXX Maybe this should be the other way around? */ - if (min > reqmin) { - xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) " - "is new than that available (%d)\n", - min, reqmin); - return FALSE; - } + } + + /* Check against requirements that the caller has specified */ + if (req) { + if (req->majorversion != MAJOR_UNSPEC) { + if (data->majorversion != req->majorversion) { + xf86MsgVerb(X_WARNING, 2, "module major version (%d) " + "doesn't match required major version (%d)\n", + data->majorversion, req->majorversion); + return FALSE; + } else if (req->minorversion != MINOR_UNSPEC) { + if (data->minorversion < req->minorversion) { + xf86MsgVerb(X_WARNING, 2, "module minor version (%d) " + "is less than the required minor version (%d)\n", + data->minorversion, req->minorversion); + return FALSE; + } else if (data->minorversion == req->minorversion && + req->patchlevel != PATCH_UNSPEC) { + if (data->patchlevel < req->patchlevel) { + xf86MsgVerb(X_WARNING, 2, "module patch level (%d) " + "is less than the required patch level (%d)\n", + data->patchlevel, req->patchlevel); + return FALSE; + } } + } } - -#ifdef NOTYET - if (data->checksum) - { - /* verify the checksum field */ - /* TO BE DONE */ + if (req->moduleclass) { + if (!data->moduleclass || + strcmp(req->moduleclass, data->moduleclass)) { + xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match " + "the required class (%s)\n", + data->moduleclass ? data->moduleclass : "<NONE>", + req->moduleclass); + return FALSE; + } + } else if (req->abiclass != ABI_CLASS_NONE) { + if (!data->abiclass || strcmp(req->abiclass, data->moduleclass)) { + xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the " + "required ABI class (%s)\n", + data->abiclass ? data->abiclass : "<NONE>", + req->abiclass); + return FALSE; + } } - else - { - ErrorF ("\t*** Checksum field is 0 - this module is untrusted!\n"); + if ((req->abiclass != ABI_CLASS_NONE) && + req->abiversion != ABI_VERS_UNSPEC) { + int reqmaj, reqmin, maj, min; + + reqmaj = GET_ABI_MAJOR(req->abiversion); + reqmin = GET_ABI_MINOR(req->abiversion); + maj = GET_ABI_MAJOR(data->abiversion); + min = GET_ABI_MINOR(data->abiversion); + if (maj != reqmaj) { + xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't " + "match the required ABI major version (%d)\n", + maj, reqmaj); + return FALSE; + } + /* XXX Maybe this should be the other way around? */ + if (min > reqmin) { + xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) " + "is new than that available (%d)\n", min, reqmin); + return FALSE; + } } + } +#ifdef NOTYET + if (data->checksum) { + /* verify the checksum field */ + /* TO BE DONE */ + } else { + ErrorF("\t*** Checksum field is 0 - this module is untrusted!\n"); + } #endif return TRUE; } @@ -715,69 +749,69 @@ CheckVersion (const char *module, XF86ModuleVersionInfo *data, ModuleDescPtr LoadSubModule(ModuleDescPtr parent, const char *module, const char **subdirlist, const char **patternlist, - pointer options, const XF86ModReqInfo *modreq, + pointer options, const XF86ModReqInfo * modreq, int *errmaj, int *errmin) { - ModuleDescPtr submod; + ModuleDescPtr submod; - xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module); + xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module); - /* Absolute module paths are not allowed here */ + /* Absolute module paths are not allowed here */ #ifndef __UNIXOS2__ - if (module[0] == '/') + if (module[0] == '/') #else - if (isalpha (module[0]) && module[1] == ':' && module[2] == '/') + if (isalpha(module[0]) && module[1] == ':' && module[2] == '/') #endif - { - xf86Msg(X_ERROR, - "LoadSubModule: Absolute module path not permitted: \"%s\"\n", - module); - if (errmaj) - *errmaj = LDR_BADUSAGE; - if (errmin) - *errmin = 0; - return NULL; - } - - submod = LoadModule (module, NULL, subdirlist, patternlist, options, - modreq, errmaj, errmin); - if (submod) { - parent->child = AddSibling (parent->child, submod); - submod->parent = parent; - } - return submod; + { + xf86Msg(X_ERROR, + "LoadSubModule: Absolute module path not permitted: \"%s\"\n", + module); + if (errmaj) + *errmaj = LDR_BADUSAGE; + if (errmin) + *errmin = 0; + return NULL; + } + + submod = LoadModule(module, NULL, subdirlist, patternlist, options, + modreq, errmaj, errmin); + if (submod) { + parent->child = AddSibling(parent->child, submod); + submod->parent = parent; + } + return submod; } ModuleDescPtr DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent) { - ModuleDescPtr ret; + ModuleDescPtr ret; - if (!mod) - return NULL; + if (!mod) + return NULL; - ret = NewModuleDesc(mod->name); - if (ret == NULL) - return NULL; + ret = NewModuleDesc(mod->name); + if (ret == NULL) + return NULL; - if (LoaderHandleOpen(mod->handle) == -1) - return NULL; + if (LoaderHandleOpen(mod->handle) == -1) + return NULL; - ret->filename = xstrdup(mod->filename); - ret->identifier = mod->identifier; - ret->client_id = mod->client_id; - ret->in_use = mod->in_use; - ret->handle = mod->handle; - ret->SetupProc = mod->SetupProc; - ret->TearDownProc = mod->TearDownProc; - ret->TearDownData = NULL; - ret->path = mod->path; - ret->child = DuplicateModule(mod->child, ret); - ret->sib = DuplicateModule(mod->sib, parent); - ret->parent = parent; - ret->VersionInfo = mod->VersionInfo; - - return ret; + ret->filename = xstrdup(mod->filename); + ret->identifier = mod->identifier; + ret->client_id = mod->client_id; + ret->in_use = mod->in_use; + ret->handle = mod->handle; + ret->SetupProc = mod->SetupProc; + ret->TearDownProc = mod->TearDownProc; + ret->TearDownData = NULL; + ret->path = mod->path; + ret->child = DuplicateModule(mod->child, ret); + ret->sib = DuplicateModule(mod->sib, parent); + ret->parent = parent; + ret->VersionInfo = mod->VersionInfo; + + return ret; } /* @@ -819,241 +853,227 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent) */ ModuleDescPtr -LoadModule (const char *module, const char *path, const char **subdirlist, - const char **patternlist, pointer options, - const XF86ModReqInfo * modreq, - int *errmaj, int *errmin) +LoadModule(const char *module, const char *path, const char **subdirlist, + const char **patternlist, pointer options, + const XF86ModReqInfo * modreq, int *errmaj, int *errmin) { - XF86ModuleData *initdata = NULL; - char **pathlist = NULL; - char *found = NULL; - char *name = NULL; - char **path_elem = NULL; - char *p = NULL; - ModuleDescPtr ret = NULL; - int wasLoaded = 0; - PatternPtr patterns = NULL; - int noncanonical = 0; - char *m = NULL; - - /*xf86Msg(X_INFO,"OS2DIAG: LoadModule: %s\n",module);*/ - xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module); - - patterns = InitPatterns(patternlist); - name = LoaderGetCanonicalName(module, patterns); - noncanonical = (name && strcmp(module, name) != 0); - if (noncanonical) - { - xf86ErrorFVerb(3, " (%s)\n", name); - xf86MsgVerb(X_WARNING, 1, - "LoadModule: given non-canonical module name \"%s\"\n", - module); - m = name; - } - else - { - xf86ErrorFVerb(3, "\n"); - m = (char *)module; - } - if (!name) { - if (errmaj) - *errmaj = LDR_BADUSAGE; - if (errmin) - *errmin = 0; - goto LoadModule_fail; - } - ret = NewModuleDesc (name); - if (!ret) { - if (errmaj) - *errmaj = LDR_NOMEM; - if (errmin) - *errmin = 0; - goto LoadModule_fail; - } - - pathlist = InitPathList(path); - if (!pathlist) { - /* This could be a malloc failure too */ - if (errmaj) - *errmaj = LDR_BADUSAGE; - if (errmin) - *errmin = 1; - goto LoadModule_fail; - } - - /* - * if the module name is not a full pathname, we need to - * check the elements in the path - */ + XF86ModuleData *initdata = NULL; + char **pathlist = NULL; + char *found = NULL; + char *name = NULL; + char **path_elem = NULL; + char *p = NULL; + ModuleDescPtr ret = NULL; + int wasLoaded = 0; + PatternPtr patterns = NULL; + int noncanonical = 0; + char *m = NULL; + + /*xf86Msg(X_INFO,"OS2DIAG: LoadModule: %s\n",module); */ + xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module); + + patterns = InitPatterns(patternlist); + name = LoaderGetCanonicalName(module, patterns); + noncanonical = (name && strcmp(module, name) != 0); + if (noncanonical) { + xf86ErrorFVerb(3, " (%s)\n", name); + xf86MsgVerb(X_WARNING, 1, + "LoadModule: given non-canonical module name \"%s\"\n", + module); + m = name; + } else { + xf86ErrorFVerb(3, "\n"); + m = (char *)module; + } + if (!name) { + if (errmaj) + *errmaj = LDR_BADUSAGE; + if (errmin) + *errmin = 0; + goto LoadModule_fail; + } + ret = NewModuleDesc(name); + if (!ret) { + if (errmaj) + *errmaj = LDR_NOMEM; + if (errmin) + *errmin = 0; + goto LoadModule_fail; + } + + pathlist = InitPathList(path); + if (!pathlist) { + /* This could be a malloc failure too */ + if (errmaj) + *errmaj = LDR_BADUSAGE; + if (errmin) + *errmin = 1; + goto LoadModule_fail; + } + + /* + * if the module name is not a full pathname, we need to + * check the elements in the path + */ #ifndef __UNIXOS2__ - if (module[0] == '/') - found = xstrdup(module); + if (module[0] == '/') + found = xstrdup(module); #else - /* accept a drive name here */ - if (isalpha (module[0]) && module[1] == ':' && module[2] == '/') - found = xstrdup(module); + /* accept a drive name here */ + if (isalpha(module[0]) && module[1] == ':' && module[2] == '/') + found = xstrdup(module); #endif - path_elem = pathlist; - while (!found && *path_elem != NULL) - { - found = FindModule (m, *path_elem, subdirlist, patterns); - path_elem++; - /* - * When the module name isn't the canonical name, search for the - * former if no match was found for the latter. - */ - if (!*path_elem && m == name) - { - path_elem = pathlist; - m = (char *)module; - } - } - - /* - * did we find the module? - */ - if (!found) - { - xf86Msg (X_WARNING, "Warning, couldn't open module %s\n", - module); - if (errmaj) - *errmaj = LDR_NOENT; - if (errmin) - *errmin = 0; - goto LoadModule_fail; - } - ret->handle = LoaderOpen (found, name, 0, errmaj, errmin, &wasLoaded); - if (ret->handle < 0) - goto LoadModule_fail; - - ret->filename = xstrdup(found); - + path_elem = pathlist; + while (!found && *path_elem != NULL) { + found = FindModule(m, *path_elem, subdirlist, patterns); + path_elem++; /* - * now check if the special data object <modulename>ModuleData is - * present. + * When the module name isn't the canonical name, search for the + * former if no match was found for the latter. */ - p = xalloc (strlen (name) + strlen ("ModuleData") + 1); - if (!p) { - if (errmaj) - *errmaj = LDR_NOMEM; - if (errmin) - *errmin = 0; - goto LoadModule_fail; + if (!*path_elem && m == name) { + path_elem = pathlist; + m = (char *)module; } - strcpy (p, name); - strcat (p, "ModuleData"); - initdata = LoaderSymbol (p); - if (initdata) - { - ModuleSetupProc setup; - ModuleTearDownProc teardown; - XF86ModuleVersionInfo *vers; - - vers = initdata->vers; - setup = initdata->setup; - teardown = initdata->teardown; - - if (!wasLoaded) { - if (vers) { - if (!CheckVersion (module, vers, modreq)) { - if (errmaj) - *errmaj = LDR_MISMATCH; - if (errmin) - *errmin = 0; - goto LoadModule_fail; - } - } else { - xf86Msg(X_ERROR, - "LoadModule: Module %s does not supply" - " version information\n", module); - if (errmaj) - *errmaj = LDR_INVALID; - if (errmin) - *errmin = 0; - goto LoadModule_fail; - } + } + + /* + * did we find the module? + */ + if (!found) { + xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module); + if (errmaj) + *errmaj = LDR_NOENT; + if (errmin) + *errmin = 0; + goto LoadModule_fail; + } + ret->handle = LoaderOpen(found, name, 0, errmaj, errmin, &wasLoaded); + if (ret->handle < 0) + goto LoadModule_fail; + + ret->filename = xstrdup(found); + + /* + * now check if the special data object <modulename>ModuleData is + * present. + */ + p = xalloc(strlen(name) + strlen("ModuleData") + 1); + if (!p) { + if (errmaj) + *errmaj = LDR_NOMEM; + if (errmin) + *errmin = 0; + goto LoadModule_fail; + } + strcpy(p, name); + strcat(p, "ModuleData"); + initdata = LoaderSymbol(p); + if (initdata) { + ModuleSetupProc setup; + ModuleTearDownProc teardown; + XF86ModuleVersionInfo *vers; + + vers = initdata->vers; + setup = initdata->setup; + teardown = initdata->teardown; + + if (!wasLoaded) { + if (vers) { + if (!CheckVersion(module, vers, modreq)) { + if (errmaj) + *errmaj = LDR_MISMATCH; + if (errmin) + *errmin = 0; + goto LoadModule_fail; } - if (setup) - ret->SetupProc = setup; - if (teardown) - ret->TearDownProc = teardown; - ret->path = path; - ret->VersionInfo = vers; - } - else - { - /* No initdata is OK for external modules */ - if (options == EXTERN_MODULE) - goto LoadModule_exit; - - /* no initdata, fail the load */ - xf86Msg (X_ERROR, "LoadModule: Module %s does not have a %s " - "data object.\n", module, p); + } else { + xf86Msg(X_ERROR, + "LoadModule: Module %s does not supply" + " version information\n", module); if (errmaj) - *errmaj = LDR_INVALID; + *errmaj = LDR_INVALID; if (errmin) - *errmin = 0; + *errmin = 0; goto LoadModule_fail; + } } - if (ret->SetupProc) - { - ret->TearDownData = ret->SetupProc (ret, options, errmaj, errmin); - if (!ret->TearDownData) - { - goto LoadModule_fail; - } - } - else if (options) - { - xf86Msg (X_WARNING, "Module Options present, but no SetupProc " - "available for %s\n", module); + if (setup) + ret->SetupProc = setup; + if (teardown) + ret->TearDownProc = teardown; + ret->path = path; + ret->VersionInfo = vers; + } else { + /* No initdata is OK for external modules */ + if (options == EXTERN_MODULE) + goto LoadModule_exit; + + /* no initdata, fail the load */ + xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s " + "data object.\n", module, p); + if (errmaj) + *errmaj = LDR_INVALID; + if (errmin) + *errmin = 0; + goto LoadModule_fail; + } + if (ret->SetupProc) { + ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin); + if (!ret->TearDownData) { + goto LoadModule_fail; } - goto LoadModule_exit; + } else if (options) { + xf86Msg(X_WARNING, "Module Options present, but no SetupProc " + "available for %s\n", module); + } + goto LoadModule_exit; LoadModule_fail: - UnloadModule (ret); - ret = NULL; + UnloadModule(ret); + ret = NULL; LoadModule_exit: - FreePathList(pathlist); - FreePatterns(patterns); - TestFree (found); - TestFree (name); - TestFree (p); - - /* - * If you need to do something to keep the - * instruction cache in sync with the main - * memory before jumping to that code, you may - * do it here. - */ + FreePathList(pathlist); + FreePatterns(patterns); + TestFree(found); + TestFree(name); + TestFree(p); + + /* + * If you need to do something to keep the + * instruction cache in sync with the main + * memory before jumping to that code, you may + * do it here. + */ #ifdef __alpha__ - istream_mem_barrier(); + istream_mem_barrier(); #endif - return ret; + return ret; } ModuleDescPtr -LoadDriver (const char *module, const char *path, int handle, pointer options, - int *errmaj, int *errmin) +LoadDriver(const char *module, const char *path, int handle, pointer options, + int *errmaj, int *errmin) { -return LoadModule (module, path, NULL, NULL, options, NULL, errmaj, errmin); + return LoadModule(module, path, NULL, NULL, options, NULL, errmaj, + errmin); } void -UnloadModule (ModuleDescPtr mod) +UnloadModule(ModuleDescPtr mod) { - UnloadModuleOrDriver (mod); + UnloadModuleOrDriver(mod); } void -UnloadDriver (ModuleDescPtr mod) +UnloadDriver(ModuleDescPtr mod) { - UnloadModuleOrDriver (mod); + UnloadModuleOrDriver(mod); } static void -UnloadModuleOrDriver (ModuleDescPtr mod) +UnloadModuleOrDriver(ModuleDescPtr mod) { if (mod == NULL || mod->name == NULL) return; @@ -1061,18 +1081,18 @@ UnloadModuleOrDriver (ModuleDescPtr mod) xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name); if ((mod->TearDownProc) && (mod->TearDownData)) - mod->TearDownProc (mod->TearDownData); - LoaderUnload (mod->handle); + mod->TearDownProc(mod->TearDownData); + LoaderUnload(mod->handle); if (mod->child) - UnloadModuleOrDriver (mod->child); + UnloadModuleOrDriver(mod->child); if (mod->sib) - UnloadModuleOrDriver (mod->sib); - TestFree (mod->name); - TestFree (mod->filename); - xfree (mod); + UnloadModuleOrDriver(mod->sib); + TestFree(mod->name); + TestFree(mod->filename); + xfree(mod); #ifdef __alpha__ - istream_mem_barrier(); + istream_mem_barrier(); #endif } @@ -1085,69 +1105,67 @@ UnloadSubModule(ModuleDescPtr mod) xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name); if ((mod->TearDownProc) && (mod->TearDownData)) - mod->TearDownProc (mod->TearDownData); - LoaderUnload (mod->handle); + mod->TearDownProc(mod->TearDownData); + LoaderUnload(mod->handle); RemoveChild(mod); if (mod->child) - UnloadModuleOrDriver (mod->child); + UnloadModuleOrDriver(mod->child); - TestFree (mod->name); - TestFree (mod->filename); - xfree (mod); + TestFree(mod->name); + TestFree(mod->filename); + xfree(mod); } void -FreeModuleDesc (ModuleDescPtr head) +FreeModuleDesc(ModuleDescPtr head) { - ModuleDescPtr sibs, prev; + ModuleDescPtr sibs, prev; - /* - * only free it if it's not marked as in use. In use means that it may - * be unloaded someday, and UnloadModule or UnloadDriver will free it - */ - if (head->in_use) - return; - if (head->child) - FreeModuleDesc (head->child); - sibs = head; - while (sibs) - { - prev = sibs; - sibs = sibs->sib; - TestFree (prev->name); - xfree (prev); - } + /* + * only free it if it's not marked as in use. In use means that it may + * be unloaded someday, and UnloadModule or UnloadDriver will free it + */ + if (head->in_use) + return; + if (head->child) + FreeModuleDesc(head->child); + sibs = head; + while (sibs) { + prev = sibs; + sibs = sibs->sib; + TestFree(prev->name); + xfree(prev); + } } ModuleDescPtr -NewModuleDesc (const char *name) +NewModuleDesc(const char *name) { - ModuleDescPtr mdp = xalloc (sizeof (ModuleDesc)); - - if (mdp) - { - mdp->child = NULL; - mdp->sib = NULL; - mdp->parent = NULL; - mdp->demand_next = NULL; - mdp->name = xstrdup (name); - mdp->filename = NULL; - mdp->identifier = NULL; - mdp->client_id = 0; - mdp->in_use = 0; - mdp->handle = -1; - mdp->SetupProc = NULL; - mdp->TearDownProc = NULL; - mdp->TearDownData = NULL; - } - - return (mdp); + ModuleDescPtr mdp = xalloc(sizeof(ModuleDesc)); + + if (mdp) { + mdp->child = NULL; + mdp->sib = NULL; + mdp->parent = NULL; + mdp->demand_next = NULL; + mdp->name = xstrdup(name); + mdp->filename = NULL; + mdp->identifier = NULL; + mdp->client_id = 0; + mdp->in_use = 0; + mdp->handle = -1; + mdp->SetupProc = NULL; + mdp->TearDownProc = NULL; + mdp->TearDownData = NULL; + } + + return (mdp); } ModuleDescPtr -AddSibling (ModuleDescPtr head, ModuleDescPtr new) +AddSibling(ModuleDescPtr head, ModuleDescPtr new) { new->sib = head; return (new); @@ -1155,142 +1173,140 @@ AddSibling (ModuleDescPtr head, ModuleDescPtr new) } static void -RemoveChild (ModuleDescPtr child) +RemoveChild(ModuleDescPtr child) { - ModuleDescPtr mdp; - ModuleDescPtr prevsib; - ModuleDescPtr parent; + ModuleDescPtr mdp; + ModuleDescPtr prevsib; + ModuleDescPtr parent; - if (!child->parent) - return; - - parent = child->parent; - if (parent->child == child) { - parent->child = child->sib; - return; - } + if (!child->parent) + return; - prevsib = parent->child; - mdp = prevsib->sib; - while (mdp && mdp != child) { - prevsib = mdp; - mdp = mdp->sib; - } - if (mdp == child) - prevsib->sib = child->sib; + parent = child->parent; + if (parent->child == child) { + parent->child = child->sib; return; + } + + prevsib = parent->child; + mdp = prevsib->sib; + while (mdp && mdp != child) { + prevsib = mdp; + mdp = mdp->sib; + } + if (mdp == child) + prevsib->sib = child->sib; + return; } void LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin) { - const char *msg; - - switch (errmaj) { - case LDR_NOERROR: - msg = "no error"; - break; - case LDR_NOMEM: - msg = "out of memory"; - break; - case LDR_NOENT: - msg = "module does not exist"; - break; - case LDR_NOSUBENT: - msg = "a required submodule could not be loaded"; - break; - case LDR_NOSPACE: - msg = "too many modules"; - break; - case LDR_NOMODOPEN: - msg = "open failed"; - break; - case LDR_UNKTYPE: - msg = "unknown module type"; - break; - case LDR_NOLOAD: - msg = "loader failed"; - break; - case LDR_ONCEONLY: - msg = "once-only module"; - break; - case LDR_NOPORTOPEN: - msg = "port open failed"; - break; - case LDR_NOHARDWARE: - msg = "no hardware found"; - break; - case LDR_MISMATCH: - msg = "module requirement mismatch"; - break; - case LDR_BADUSAGE: - msg = "invalid argument(s) to LoadModule()"; - break; - case LDR_INVALID: - msg = "invalid module"; - break; - case LDR_BADOS: - msg = "module doesn't support this OS"; - break; - case LDR_MODSPECIFIC: - msg = "module-specific error"; - break; - default: - msg = "uknown error"; - } - if (name) - xf86Msg(X_ERROR, "%s: Failed to load module \"%s\" (%s, %d)\n", - name, modname, msg, errmin); - else - xf86Msg(X_ERROR, "Failed to load module \"%s\" (%s, %d)\n", - modname, msg, errmin); + const char *msg; + + switch (errmaj) { + case LDR_NOERROR: + msg = "no error"; + break; + case LDR_NOMEM: + msg = "out of memory"; + break; + case LDR_NOENT: + msg = "module does not exist"; + break; + case LDR_NOSUBENT: + msg = "a required submodule could not be loaded"; + break; + case LDR_NOSPACE: + msg = "too many modules"; + break; + case LDR_NOMODOPEN: + msg = "open failed"; + break; + case LDR_UNKTYPE: + msg = "unknown module type"; + break; + case LDR_NOLOAD: + msg = "loader failed"; + break; + case LDR_ONCEONLY: + msg = "once-only module"; + break; + case LDR_NOPORTOPEN: + msg = "port open failed"; + break; + case LDR_NOHARDWARE: + msg = "no hardware found"; + break; + case LDR_MISMATCH: + msg = "module requirement mismatch"; + break; + case LDR_BADUSAGE: + msg = "invalid argument(s) to LoadModule()"; + break; + case LDR_INVALID: + msg = "invalid module"; + break; + case LDR_BADOS: + msg = "module doesn't support this OS"; + break; + case LDR_MODSPECIFIC: + msg = "module-specific error"; + break; + default: + msg = "uknown error"; + } + if (name) + xf86Msg(X_ERROR, "%s: Failed to load module \"%s\" (%s, %d)\n", + name, modname, msg, errmin); + else + xf86Msg(X_ERROR, "Failed to load module \"%s\" (%s, %d)\n", + modname, msg, errmin); } - /* Given a module path or file name, return the module's canonical name */ static char * LoaderGetCanonicalName(const char *modname, PatternPtr patterns) { - char *str; - const char *s; - int len; - PatternPtr p; - regmatch_t match[2]; - - /* Strip off any leading path */ - s = strrchr(modname, '/'); - if (s == NULL) - s = modname; - else - s++; - - /* Find the first regex that is matched */ - for (p = patterns; p->pattern; p++) - if (regexec(&p->rex, s, 2, match, 0) == 0 && - match[1].rm_so != -1) { - len = match[1].rm_eo - match[1].rm_so; - str = xalloc(len + 1); - if (!str) - return NULL; - strncpy(str, s + match[1].rm_so, len); - str[len] = '\0'; - return str; - } + char *str; + const char *s; + int len; + PatternPtr p; + regmatch_t match[2]; + + /* Strip off any leading path */ + s = strrchr(modname, '/'); + if (s == NULL) + s = modname; + else + s++; + + /* Find the first regex that is matched */ + for (p = patterns; p->pattern; p++) + if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) { + len = match[1].rm_eo - match[1].rm_so; + str = xalloc(len + 1); + if (!str) + return NULL; + strncpy(str, s + match[1].rm_so, len); + str[len] = '\0'; + return str; + } - /* If there is no match, return the whole name minus the leading path */ - return xstrdup(s); + /* If there is no match, return the whole name minus the leading path */ + return xstrdup(s); } /* * Return the module version information. */ unsigned long -LoaderGetModuleVersion (ModuleDescPtr mod) +LoaderGetModuleVersion(ModuleDescPtr mod) { if (!mod || !mod->VersionInfo) - return 0; + return 0; return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion, - mod->VersionInfo->minorversion, - mod->VersionInfo->patchlevel); + mod->VersionInfo->minorversion, + mod->VersionInfo->patchlevel); } |