diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:20:37 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:20:37 -0800 |
commit | a99e5e558fc9e279eeee2b76187766ac1dde19cf (patch) | |
tree | 2b51e4e723ea77efb29c50a65af708c64fe77381 /files.c | |
parent | 919fc87075a0b604d316b7d91fca592eba64829e (diff) |
1.0-81741.0-8174
Diffstat (limited to 'files.c')
-rw-r--r-- | files.c | 540 |
1 files changed, 426 insertions, 114 deletions
@@ -47,6 +47,10 @@ #include "misc.h" #include "precompiled.h" + +static int get_x_module_path(Options *op); + + /* * remove_directory() - recursively delete a direcotry (`rm -rf`) */ @@ -478,11 +482,66 @@ void select_tls_class(Options *op, Package *p) int set_destinations(Options *op, Package *p) { - char *prefix, *path, *name; + char *prefix, *path, *name, *s; + char *xdg_data_dir; int i; + s = NULL; for (i = 0; i < p->num_entries; i++) { +#if defined(NV_X86_64) + if (p->entries[i].flags & FILE_TYPE_HAVE_PATH) { + if ((op->distro == DEBIAN || op->distro == UBUNTU) && + (s = strstr(p->entries[i].path, "lib64"))) { + /* + * XXX Debian GNU/Linux for Linux/x86-64 doesn't follow + * the "lib64" convention used by other distributors. + * The 64-bit libraries are installed in ../lib. Ubuntu + * Linux inherited this layout. + */ + + /* + * The default 64-bit destination path is ../lib64. + * Get the length of the string following "lib64", then + * move this remainder over the "64". + */ + int j, len = strlen(s+5); + for (j = 0; j <= len; j++) s[j+3] = s[j+5]; + + } else if (((op->distro == UBUNTU) || + (op->distro == GENTOO)) && + (p->entries[i].flags & FILE_CLASS_COMPAT32) && + (s = strstr(p->entries[i].path, "lib"))) { + /* + * XXX Ubuntu for Linux/x86-64 doesn't follow the "lib" + * convention used by other distributors; the 32-bit + * libraries are installed in ../lib32, instead. Patch + * up the destination path accordingly. + * + * Sadly, the same thing is also true for Gentoo Linux. + */ + + /* + * The default 32-bit destination path is ../lib. + * If this entry's path ends with "lib", go ahead and + * replace it with ../lib32, else replace the "lib" + * in the path with "lib32". + */ + if (*(s+3) == '\0') { + path = p->entries[i].path; + p->entries[i].path = nvstrcat(path, "32", NULL); + free(path); + } else if ((s+4) != NULL) { + *(s+3) = '\0'; + path = p->entries[i].path; + p->entries[i].path = nvstrcat(path, "32/", s+4, NULL); + free(path); + } else + p->entries[i].dst = NULL; + } + } +#endif /* NV_X86_64 */ + switch (p->entries[i].flags & FILE_TYPE_MASK) { case FILE_TYPE_KERNEL_MODULE_CMD: @@ -499,18 +558,32 @@ int set_destinations(Options *op, Package *p) path = p->entries[i].path; break; - case FILE_TYPE_XFREE86_LIB: - case FILE_TYPE_XFREE86_SYMLINK: + case FILE_TYPE_XLIB_SHARED_LIB: + case FILE_TYPE_XLIB_STATIC_LIB: + case FILE_TYPE_XLIB_SYMLINK: prefix = op->xfree86_prefix; path = p->entries[i].path; break; + case FILE_TYPE_XMODULE_SHARED_LIB: + case FILE_TYPE_XMODULE_STATIC_LIB: + case FILE_TYPE_XMODULE_SYMLINK: + prefix = op->x_module_path; + path = p->entries[i].path; + break; + case FILE_TYPE_TLS_LIB: case FILE_TYPE_TLS_SYMLINK: prefix = op->opengl_prefix; path = p->entries[i].path; break; + case FILE_TYPE_UTILITY_LIB: + case FILE_TYPE_UTILITY_SYMLINK: + prefix = op->utility_prefix; + path = p->entries[i].path; + break; + case FILE_TYPE_LIBGL_LA: prefix = op->opengl_prefix; path = p->entries[i].path; @@ -543,6 +616,24 @@ int set_destinations(Options *op, Package *p) path = UTILITY_BINARY_DST_PATH; break; + case FILE_TYPE_DOT_DESKTOP: + /* + * If XDG_DATA_DIRS is set, then derive the installation path + * from the first entry; complies with: + * http://www.freedesktop.org/Standards/basedir-spec + */ + xdg_data_dir = getenv("XDG_DATA_DIRS"); + if (xdg_data_dir) xdg_data_dir = nvstrdup(strtok(xdg_data_dir, ":")); + + if (xdg_data_dir != NULL) { + prefix = xdg_data_dir; + path = nvstrdup("applications"); + } else { + prefix = op->opengl_prefix; + path = DOT_DESKTOP_DST_PATH; + } + break; + case FILE_TYPE_KERNEL_MODULE: /* @@ -665,6 +756,29 @@ int get_prefixes (Options *op) remove_trailing_slashes(op->xfree86_prefix); ui_expert(op, "X installation prefix is: '%s'", op->xfree86_prefix); + + /* + * assign the X module path; this must be done after + * op->xfree86_prefix is assigned + */ + + if (!get_x_module_path(op)) { + return FALSE; + } + + if (op->expert) { + ret = ui_get_input(op, op->x_module_path, + "X module installation path (only under " + "rare circumstances should this be changed " + "from the default)"); + if (ret && ret[0]) { + op->x_module_path = ret; + if (!confirm_path(op, op->x_module_path)) return FALSE; + } + } + + remove_trailing_slashes(op->x_module_path); + ui_expert(op, "X module installation path is: '%s'", op->x_module_path); if (op->expert) { ret = ui_get_input(op, op->opengl_prefix, @@ -1409,6 +1523,149 @@ static char *nv_strreplace(char *src, char *orig, char *replace) /* + * process_template_file() - copy the specified template file to + * a temporary file, replacing specified tokens with specified + * replacement strings. Return the temporary file's path to the + * caller or NULL, if an error occurs. + */ + +char *process_template_file(Options *op, PackageEntry *pe, + char **tokens, char **replacements) +{ + int failed, src_fd, dst_fd, len; + struct stat stat_buf; + char *src, *dst, *tmp, *tmp0, *tmpfile = NULL; + char *token, *replacement; + + failed = FALSE; + src_fd = dst_fd = -1; + tmp = tmp0 = src = dst = tmpfile = NULL; + len = 0; + + /* open the file */ + + if ((src_fd = open(pe->file, O_RDONLY)) == -1) { + ui_error(op, "Unable to open '%s' for copying (%s)", + pe->file, strerror(errno)); + return NULL; + } + + /* get the size of the file */ + + if (fstat(src_fd, &stat_buf) == -1) { + ui_error(op, "Unable to determine size of '%s' (%s)", + pe->file, strerror(errno)); + failed = TRUE; goto done; + } + + /* mmap the file */ + + if ((src = mmap(0, stat_buf.st_size, PROT_READ, + MAP_FILE|MAP_SHARED, src_fd, 0)) == MAP_FAILED) { + ui_error (op, "Unable to map source file '%s' for " + "copying (%s)", pe->file, strerror(errno)); + src = NULL; + failed = TRUE; goto done; + } + + if (!src) { + ui_log(op, "%s is empty; skipping.", pe->file); + failed = TRUE; goto done; + } + + token = *tokens; + replacement = *replacements; + tmp = src; + + while (token != NULL && replacement != NULL) { + /* + * Replace any occurances of 'token' with 'replacement' in + * the source string and free the source unless it points + * to the source file mapping, in which case the unmap has + * to be deferred. + */ + tmp0 = nv_strreplace(tmp, token, replacement); + if (tmp != src) nvfree(tmp); + tmp = tmp0; + token = *(++tokens); + replacement = *(++replacements); + } + + /* create a temporary file to store the processed template file */ + + tmpfile = nvstrcat(op->tmpdir, "/template-XXXXXX", NULL); + if ((dst_fd = mkstemp(tmpfile)) == -1) { + ui_error(op, "Unable to create temporary file (%s)", + strerror(errno)); + failed = TRUE; goto done; + } + + /* set the size of the new file */ + + len = strlen(tmp); + + if (lseek(dst_fd, len - 1, SEEK_SET) == -1) { + ui_error(op, "Unable to set file size for '%s' (%s)", + tmpfile, strerror(errno)); + failed = TRUE; goto done; + } + if (write(dst_fd, "", 1) != 1) { + ui_error(op, "Unable to write file size for '%s' (%s)", + tmpfile, strerror(errno)); + failed = TRUE; goto done; + } + + /* mmap the new file */ + + if ((dst = mmap(0, len, PROT_READ | PROT_WRITE, + MAP_FILE|MAP_SHARED, dst_fd, 0)) == MAP_FAILED) { + ui_error(op, "Unable to map destination file '%s' for " + "copying (%s)", tmpfile, strerror(errno)); + dst = NULL; + failed = TRUE; goto done; + } + + /* write the processed data out to the temporary file */ + + memcpy(dst, tmp, len); + +done: + + if (src) { + if (munmap(src, stat_buf.st_size) == -1) { + ui_error(op, "Unable to unmap source file '%s' after " + "copying (%s)", pe->file, + strerror(errno)); + } + } + + if (dst) { + if (munmap(dst, len) == -1) { + ui_error (op, "Unable to unmap destination file '%s' " + "after copying (%s)", tmpfile, strerror(errno)); + } + } + + if (src_fd != -1) close(src_fd); + if (dst_fd != -1) { + close(dst_fd); + /* in case an error occurred, delete the temporary file */ + if (failed) unlink(tmpfile); + } + + if (failed) { + nvfree(tmpfile); tmpfile = NULL; + } + + nvfree(tmp); + + return tmpfile; + +} /* process_template_files() */ + + + +/* * process_libGL_la_files() - for any libGL.la files in the package, * copy them to a temporary file, replacing __GENERATED_BY__ and * __LIBGL_PATH__ as appropriate. Then, add the new file to the @@ -1417,145 +1674,200 @@ static char *nv_strreplace(char *src, char *orig, char *replace) void process_libGL_la_files(Options *op, Package *p) { - int i, n, src_fd, dst_fd, len; - struct stat stat_buf; - char *src, *dst, *tmp, *tmp0, *tmp1, *tmpfile; + int i, n; + char *tmpfile; + + char *tokens[3] = { "__LIBGL_PATH__", "__GENERATED_BY__", NULL }; + char *replacements[3] = { NULL, NULL, NULL }; int package_num_entries = p->num_entries; + replacements[1] = nvstrcat(PROGRAM_NAME, ": ", + NVIDIA_INSTALLER_VERSION, NULL); + for (i = 0; i < package_num_entries; i++) { if ((p->entries[i].flags & FILE_TYPE_LIBGL_LA)) { - src_fd = dst_fd = -1; - tmp0 = tmp1 = src = dst = tmpfile = NULL; - len = 0; - - /* open the file */ - - if ((src_fd = open(p->entries[i].file, O_RDONLY)) == -1) { - ui_error(op, "Unable to open '%s' for copying (%s)", - p->entries[i].file, strerror(errno)); - goto done; - } + replacements[0] = nvstrcat(op->opengl_prefix, + "/", p->entries[i].path, NULL); + + /* invalidate the template file */ - /* get the size of the file */ + p->entries[i].flags &= ~FILE_TYPE_MASK; + p->entries[i].dst = NULL; - if (fstat(src_fd, &stat_buf) == -1) { - ui_error(op, "Unable to determine size of '%s' (%s)", - p->entries[i].file, strerror(errno)); - goto done; + tmpfile = process_template_file(op, &p->entries[i], tokens, + replacements); + + if (tmpfile != NULL) { + /* add this new file to the package */ + + n = p->num_entries; + + p->entries = + (PackageEntry *) nvrealloc(p->entries, + (n + 1) * sizeof(PackageEntry)); + p->entries[n].file = tmpfile; + p->entries[n].path = p->entries[i].path; + p->entries[n].target = NULL; + p->entries[n].flags = ((p->entries[i].flags & FILE_CLASS_MASK) + | FILE_TYPE_LIBGL_LA); + p->entries[n].mode = p->entries[i].mode; + + p->entries[n].name = nvstrdup(p->entries[i].name); + + p->num_entries++; } - /* mmap the file */ + nvfree(replacements[0]); + } + } - if ((src = mmap(0, stat_buf.st_size, PROT_READ, - MAP_FILE|MAP_SHARED, src_fd, 0)) == (void *) -1) { - ui_error (op, "Unable to map source file '%s' for " - "copying (%s)", p->entries[i].file, strerror(errno)); - src = NULL; - goto done; - } + nvfree(replacements[1]); - if (!src) { - ui_log(op, "%s is empty; skipping.", p->entries[i].file); - goto done; - } +} /* process_libGL_la_files() */ - /* replace __LIBGL_PATH__ */ - tmp = nvstrcat(op->opengl_prefix, "/", p->entries[i].path, NULL); - tmp0 = nv_strreplace(src, "__LIBGL_PATH__", tmp); - nvfree(tmp); - /* replace __GENERATED_BY__ */ +/* + * process_dot_desktop_files() - for any .desktop files in the + * package, copy them to a temporary file, replacing __UTILS_PATH__ + * and __LIBGL_PATH__ as appropriate. Then, add the new file to + * the package list. + */ - tmp = nvstrcat(PROGRAM_NAME, ": ", NVIDIA_INSTALLER_VERSION, NULL); - tmp1 = nv_strreplace(tmp0, "__GENERATED_BY__", tmp); - nvfree(tmp); +void process_dot_desktop_files(Options *op, Package *p) +{ + int i, n; + char *tmpfile; - /* create a temporary file to store the processed libGL.la file */ - - tmpfile = nvstrcat(op->tmpdir, "/libGL.la-XXXXXX", NULL); - if ((dst_fd = mkstemp(tmpfile)) == -1) { - ui_error(op, "Unable to create temporary file (%s)", - strerror(errno)); - goto done; - } + char *tokens[3] = { "__UTILS_PATH__", "__DOCS_PATH__", NULL }; + char *replacements[3] = { NULL, NULL, NULL }; - /* set the size of the new file */ + int package_num_entries = p->num_entries; - len = strlen(tmp1); - - if (lseek(dst_fd, len - 1, SEEK_SET) == -1) { - ui_error(op, "Unable to set file size for '%s' (%s)", - tmpfile, strerror(errno)); - goto done; - } - if (write(dst_fd, "", 1) != 1) { - ui_error(op, "Unable to write file size for '%s' (%s)", - tmpfile, strerror(errno)); - goto done; - } + for (i = 0; i < package_num_entries; i++) { + if ((p->entries[i].flags & FILE_TYPE_DOT_DESKTOP)) { + + replacements[0] = nvstrcat(op->utility_prefix, + "/", UTILITY_BINARY_DST_PATH, NULL); + replacements[1] = nvstrcat(op->opengl_prefix, + "/", DOCUMENTATION_DST_PATH, NULL); - /* mmap the new file */ + /* invalidate the template file */ + + p->entries[i].flags &= ~FILE_TYPE_MASK; + p->entries[i].dst = NULL; - if ((dst = mmap(0, len, PROT_READ | PROT_WRITE, - MAP_FILE|MAP_SHARED, dst_fd, 0)) == (void *) -1) { - ui_error(op, "Unable to map destination file '%s' for " - "copying (%s)", tmpfile, strerror(errno)); - dst = NULL; - goto done; + tmpfile = process_template_file(op, &p->entries[i], tokens, + replacements); + if (tmpfile != NULL) { + /* add this new file to the package */ + + n = p->num_entries; + + p->entries = + (PackageEntry *) nvrealloc(p->entries, + (n + 1) * sizeof(PackageEntry)); + p->entries[n].file = tmpfile; + p->entries[n].path = p->entries[i].path; + p->entries[n].target = NULL; + p->entries[n].flags = ((p->entries[i].flags & FILE_CLASS_MASK) + | FILE_TYPE_DOT_DESKTOP); + p->entries[n].mode = p->entries[i].mode; + + p->entries[n].name = nvstrdup(p->entries[i].name); + + p->num_entries++; } - /* write the data out to the new file */ + nvfree(replacements[0]); + nvfree(replacements[1]); + } + } +} /* process_dot_desktop_files() */ - memcpy(dst, tmp1, len); - /* invalidate the template file */ +/* + * set_security_context() - set the security context of the file to 'shlib_t' + * Returns TRUE on success or if SELinux is disabled, FALSE otherwise + */ +int set_security_context(Options *op, const char *filename) +{ + char *cmd = NULL; + int ret = FALSE; + + if (op->selinux_enabled == FALSE) { + return TRUE; + } + + cmd = nvstrcat(op->utils[CHCON], " -t shlib_t ", filename, + NULL); + + ret = run_command(op, cmd, NULL, FALSE, 0, TRUE); + + ret = ((ret == 0) ? TRUE : FALSE); + if (cmd) nvfree(cmd); + + return ret; +} /* set_security_context() */ - p->entries[i].flags &= ~FILE_TYPE_MASK; - p->entries[i].dst = NULL; - /* add this new file to the package */ - - n = p->num_entries; - - p->entries = - (PackageEntry *) nvrealloc(p->entries, - (n + 1) * sizeof(PackageEntry)); - p->entries[n].file = tmpfile; - p->entries[n].path = p->entries[i].path; - p->entries[n].target = NULL; - p->entries[n].flags = ((p->entries[i].flags & FILE_CLASS_MASK) | - FILE_TYPE_LIBGL_LA); - p->entries[n].mode = p->entries[i].mode; - - p->entries[n].name = nvstrdup(p->entries[i].name); - - p->num_entries++; - done: +/* + * get_x_module_path() - assign op->x_module_path if it is not already + * set + */ - if (src) { - if (munmap(src, stat_buf.st_size) == -1) { - ui_error(op, "Unable to unmap source file '%s' after " - "copying (%s)", p->entries[i].file, - strerror(errno)); - } - } - - if (dst) { - if (munmap(dst, len) == -1) { - ui_error (op, "Unable to unmap destination file '%s' " - "after copying (%s)", tmpfile, strerror(errno)); - } - } +static int get_x_module_path(Options *op) +{ + char *dir = NULL; + char *lib; + int ret; - if (src_fd != -1) close(src_fd); - if (dst_fd != -1) close(dst_fd); - - if (tmp0) nvfree(tmp0); - if (tmp1) nvfree(tmp1); - } + /* + * if the path was already specified (ie: by a commandline + * option), then we are done + */ + + if (op->x_module_path) { + return TRUE; } -} /* process_libGL_la_files() */ + + /* ask pkg-config */ + + ret = run_command(op, "pkg-config --variable=moduledir xorg-server", + &dir, FALSE, 0, TRUE); + + if ((ret == 0) && directory_exists(op, dir)) { + op->x_module_path = dir; + return TRUE; + } + + nvfree(dir); + + /* build the X module path from the xfree86_prefix */ + + /* + * XXX kludge to determine the correct 'lib' vs 'lib64' path; + * normally, on 64-bit distributions, the X modules get installed + * in "<xprefix>/lib64/modules". However, on Debian, Ubuntu, or + * any 32-bit distribution, we use "<xprefix>/lib/modules" + */ + +#if defined(NV_X86_64) + if ((op->distro == DEBIAN || op->distro == UBUNTU)) { + lib = "lib"; + } else { + lib = "lib64"; + } +#else + lib = "lib"; +#endif + + op->x_module_path = nvstrcat(op->xfree86_prefix, + "/", lib, "/modules", NULL); + + return TRUE; + +} /* get_x_module_path() */ |