diff options
-rw-r--r-- | DRIVER_VERSION | 2 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | command-list.c | 81 | ||||
-rw-r--r-- | command-list.h | 4 | ||||
-rw-r--r-- | gen-manpage-opts.c | 12 | ||||
-rw-r--r-- | misc.c | 15 | ||||
-rw-r--r-- | ncurses-ui.c | 8 | ||||
-rw-r--r-- | nvgetopt.c | 231 | ||||
-rw-r--r-- | nvgetopt.h | 69 | ||||
-rw-r--r-- | nvidia-installer.c | 230 | ||||
-rw-r--r-- | option_table.h | 115 | ||||
-rw-r--r-- | stream-ui.c | 6 | ||||
-rw-r--r-- | update.c | 14 | ||||
-rw-r--r-- | update.h | 6 |
14 files changed, 571 insertions, 223 deletions
diff --git a/DRIVER_VERSION b/DRIVER_VERSION index 43bedd5..1eedd74 100644 --- a/DRIVER_VERSION +++ b/DRIVER_VERSION @@ -1 +1 @@ -173.14.25 +173.14.27 @@ -145,6 +145,7 @@ SRC = backup.c \ kernel.c \ log.c \ misc.c \ + nvgetopt.c \ nvidia-installer.c \ precompiled.c \ snarf-ftp.c \ diff --git a/command-list.c b/command-list.c index 2609d07..fa17276 100644 --- a/command-list.c +++ b/command-list.c @@ -224,26 +224,33 @@ CommandList *build_command_list(Options *op, Package *p) * may be on a filesystem that doesn't support selinux attributes, * such as NFS. * - * See bug 530083 - "nvidia-installer: ERROR: Failed to execute - * execstack: Operation not supported". + * Since execstack also changes the file on disk, we need to run it + * after the file is installed but before we compute and log its CRC in + * the backup log. To achieve that, we tell INTALL_CMD to run execstack + * as a post-install step. + * + * See bugs 530083 and 611327 */ - if (p->entries[i].flags & installable_files) { - add_command(c, INSTALL_CMD, - p->entries[i].file, - p->entries[i].dst, - p->entries[i].mode); - } - if (op->selinux_enabled && (op->utils[EXECSTACK] != NULL) && ((p->entries[i].flags & FILE_TYPE_SHARED_LIB) || (p->entries[i].flags & FILE_TYPE_XMODULE_SHARED_LIB))) { tmp = nvstrcat(op->utils[EXECSTACK], " -c ", p->entries[i].dst, NULL); - add_command(c, RUN_CMD, tmp); - nvfree(tmp); + } else { + tmp = NULL; } + if (p->entries[i].flags & installable_files) { + add_command(c, INSTALL_CMD, + p->entries[i].file, + p->entries[i].dst, + tmp, + p->entries[i].mode); + } + + nvfree(tmp); + /* * delete the temporary libGL.la and .desktop files generated * based on templates earlier. @@ -391,6 +398,7 @@ void free_command_list(Options *op, CommandList *cl) c = &cl->cmds[i]; if (c->s0) free(c->s0); if (c->s1) free(c->s1); + if (c->s2) free(c->s2); } if (cl->cmds) free(cl->cmds); @@ -399,7 +407,30 @@ void free_command_list(Options *op, CommandList *cl) } /* free_command_list() */ +/* + * execute_run_command() - execute a RUN_CMD from the command list. + */ + +static inline int execute_run_command(Options *op, float percent, const char *cmd) +{ + int ret; + char *data; + ui_expert(op, "Executing: %s", cmd); + ui_status_update(op, percent, "Executing: `%s` " + "(this may take a moment...)", cmd); + ret = run_command(op, cmd, &data, TRUE, 0, TRUE); + if (ret != 0) { + ui_error(op, "Failed to execute `%s`: %s", cmd, data); + ret = continue_after_error(op, "Failed to execute `%s`", cmd); + if (!ret) { + nvfree(data); + return FALSE; + } + } + if (data) free(data); + return TRUE; +} /* execute_run_command() */ /* * execute_command_list() - execute the commands in the command list. @@ -411,7 +442,6 @@ int execute_command_list(Options *op, CommandList *c, const char *title, const char *msg) { int i, ret; - char *data; float percent; ui_status_begin(op, title, msg); @@ -434,27 +464,23 @@ int execute_command_list(Options *op, CommandList *c, c->cmds[i].s1); if (!ret) return FALSE; } else { + /* + * perform post-install step before logging the backup + */ + if (c->cmds[i].s2 && + !execute_run_command(op, percent, c->cmds[i].s2)) { + return FALSE; + } + log_install_file(op, c->cmds[i].s1); append_to_rpm_file_list(op, &c->cmds[i]); } break; case RUN_CMD: - ui_expert(op, "Executing: %s", c->cmds[i].s0); - ui_status_update(op, percent, "Executing: `%s` " - "(this may take a moment...)", c->cmds[i].s0); - ret = run_command(op, c->cmds[i].s0, &data, TRUE, 0, TRUE); - if (ret != 0) { - ui_error(op, "Failed to execute `%s`: %s", - c->cmds[i].s0, data); - ret = continue_after_error(op, "Failed to execute `%s`", - c->cmds[i].s0); - if (!ret) { - nvfree(data); - return FALSE; - } + if (!execute_run_command(op, percent, c->cmds[i].s0)) { + return FALSE; } - if (data) free(data); break; case SYMLINK_CMD: @@ -973,6 +999,7 @@ static void add_command(CommandList *c, int cmd, ...) c->cmds[n].cmd = cmd; c->cmds[n].s0 = NULL; c->cmds[n].s1 = NULL; + c->cmds[n].s2 = NULL; c->cmds[n].mode = 0x0; va_start(ap, cmd); @@ -983,6 +1010,8 @@ static void add_command(CommandList *c, int cmd, ...) c->cmds[n].s0 = nvstrdup(s); s = va_arg(ap, char *); c->cmds[n].s1 = nvstrdup(s); + s = va_arg(ap, char *); + c->cmds[n].s2 = nvstrdup(s); c->cmds[n].mode = va_arg(ap, mode_t); break; case BACKUP_CMD: diff --git a/command-list.h b/command-list.h index 5e70a1e..196f4d3 100644 --- a/command-list.h +++ b/command-list.h @@ -37,6 +37,7 @@ typedef struct { int cmd; char *s0; char *s1; + char *s2; mode_t mode; } Command; @@ -61,7 +62,8 @@ typedef struct { * commands: * * INSTALL - install the file named is s0, giving it the name in s1; - * assign s1 the permissions specified by mode + * assign s1 the permissions specified by mode; execute the string in s2 as a + * post-install step * * BACKUP - move the file named in s0, storing it in the backup * directory and recording the data as appropriate. diff --git a/gen-manpage-opts.c b/gen-manpage-opts.c index 440502e..c821a31 100644 --- a/gen-manpage-opts.c +++ b/gen-manpage-opts.c @@ -8,7 +8,7 @@ #include "nvidia-installer.h" #include "option_table.h" -static void print_option(const NVOption *o) +static void print_option(const NVGetoptOption *o) { char scratch[64], *s; int j, len; @@ -18,7 +18,7 @@ static void print_option(const NVOption *o) printf(".TP\n.BI "); /* Print the name of the option */ /* XXX We should backslashify the '-' characters in o->name. */ - if (o->flags & NVOPT_IS_BOOLEAN) { + if (o->flags & NVGETOPT_IS_BOOLEAN) { /* "\-\-name, \-\-no\-name */ printf("\"\\-\\-%s, \\-\\-no\\-%s", o->name, o->name); } else if (isalnum(o->val)) { @@ -29,7 +29,7 @@ static void print_option(const NVOption *o) printf("\"\\-\\-%s", o->name); } - if (o->flags & NVOPT_HAS_ARGUMENT) { + if (o->flags & NVGETOPT_HAS_ARGUMENT) { len = strlen(o->name); for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); scratch[len] = '\0'; @@ -87,7 +87,7 @@ static void print_option(const NVOption *o) int main(int argc, char* argv[]) { int i; - const NVOption *o; + const NVGetoptOption *o; /* Print the "simple" options, i.e. the ones you get by running * nvidia-installer --help. @@ -96,7 +96,7 @@ int main(int argc, char* argv[]) for (i = 0; __options[i].name; i++) { o = &__options[i]; - if (!(o->flags & OPTION_HELP_ALWAYS)) + if (!(o->flags & NVGETOPT_HELP_ALWAYS)) continue; if (!o->description) @@ -110,7 +110,7 @@ int main(int argc, char* argv[]) for (i = 0; __options[i].name; i++) { o = &__options[i]; - if (o->flags & OPTION_HELP_ALWAYS) + if (o->flags & NVGETOPT_HELP_ALWAYS) continue; if (!o->description) @@ -1876,9 +1876,18 @@ static int rtld_test_internal(Options *op, Package *p, cmd = nvstrcat(op->utils[LDD], " ", tmpfile, " > ", tmpfile1, NULL); if (run_command(op, cmd, NULL, FALSE, 0, TRUE)) { - ui_warn(op, "Unable to perform the runtime configuration " - "check for library '%s' ('%s'); assuming successful " - "installation.", name, p->entries[i].dst); + /* running ldd on a 32-bit SO will fail without a 32-bit loader */ + if (compat_32_libs) { + ui_warn(op, "Unable to perform the runtime configuration " + "check for 32-bit library '%s' ('%s'); this is " + "typically caused by the lack of a 32-bit " + "compatibility environment. Assuming successful " + "installation.", name, p->entries[i].dst); + } else { + ui_warn(op, "Unable to perform the runtime configuration " + "check for library '%s' ('%s'); assuming successful " + "installation.", name, p->entries[i].dst); + } goto done; } diff --git a/ncurses-ui.c b/ncurses-ui.c index 847ad8f..bb1fa32 100644 --- a/ncurses-ui.c +++ b/ncurses-ui.c @@ -1992,10 +1992,18 @@ static TextRows *nv_ncurses_create_command_list_textrows(DataStruct *d, case INSTALL_CMD: perms = nv_ncurses_mode_to_permission_string(c->mode); len = strlen(c->s0) + strlen(c->s1) + strlen(perms) + 64; + if (c->s2) { + len += strlen(c->s2) + 64; + } str = (char *) malloc(len + 1); snprintf(str, len, "Install the file '%s' as '%s' with " "permissions '%s'", c->s0, c->s1, perms); free(perms); + if (c->s2) { + len = strlen(c->s2) + 64; + snprintf(str + strlen(str), len, + " then execute the command `%s`", c->s2); + } break; case RUN_CMD: diff --git a/nvgetopt.c b/nvgetopt.c new file mode 100644 index 0000000..efce012 --- /dev/null +++ b/nvgetopt.c @@ -0,0 +1,231 @@ +/* + * nvidia-installer: A tool for installing NVIDIA software packages on + * Unix and Linux systems. + * + * Copyright (C) 2010 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA + * + * + * nvgetopt.c - portable getopt_long() replacement; removes the need + * for the stupid optstring argument. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "nvgetopt.h" + + +/* + * nvgetopt() - see the glibc getopt_long(3) manpage for usage + * description. Options can be prepended with "--" or "-". + * + * A global variable stores the current index into the argv array, so + * subsequent calls to nvgetopt() will advance through argv[]. + * + * On success, the matching NVGetoptOption.val is returned. + * + * On failure, an error is printed to stderr, and 0 is returned. + * + * When there are no more options to parse, -1 is returned. + */ + +int nvgetopt(int argc, char *argv[], const NVGetoptOption *options, + char **strval) +{ + char *c, *a, *arg, *name = NULL, *argument=NULL; + int i, found = NVGETOPT_FALSE, ret = 0; + const NVGetoptOption *o = NULL; + static int argv_index = 0; + + argv_index++; + + /* if no more options, return -1 */ + + if (argv_index >= argc) return -1; + + /* get the argument in question */ + + arg = strdup(argv[argv_index]); + + /* look for "--" or "-" */ + + if ((arg[0] == '-') && (arg[1] == '-')) { + name = arg + 2; + } else if (arg[0] == '-') { + name = arg + 1; + } else { + fprintf(stderr, "%s: invalid option: \"%s\"\n", argv[0], arg); + goto done; + } + + /* + * if there is an "=" in the string, then assign argument and zero + * out the equal sign so that name will match what is in the + * option table. + */ + + c = name; + while (*c) { + if (*c == '=') { argument = c + 1; *c = '\0'; break; } + c++; + } + + /* + * if the string is terminated after one character, interpret it + * as a short option. Otherwise, interpret it as a long option. + */ + + if (name[1] == '\0') { /* short option */ + for (i = 0; options[i].name; i++) { + if (options[i].val == name[0]) { + o = &options[i]; + break; + } + } + } else { /* long option */ + for (i = 0; options[i].name; i++) { + if (strcmp(options[i].name, name) == 0) { + o = &options[i]; + break; + } + } + } + + /* + * if we didn't find a match, maybe this is multiple short options + * stored together; is each character a short option? + */ + + if (!o) { + for (c = name; *c; c++) { + found = NVGETOPT_FALSE; + for (i = 0; options[i].name; i++) { + if (options[i].val == *c) { + found = NVGETOPT_TRUE; + break; + } + } + if (!found) break; + } + + if (found) { + + /* + * all characters individually are short options, so + * interpret them that way + */ + + for (i = 0; options[i].name; i++) { + if (options[i].val == name[0]) { + + /* + * don't allow options with arguments to be + * processed in this way + */ + + if (options[i].flags & NVGETOPT_HAS_ARGUMENT) break; + + /* + * remove the first short option from + * argv[argv_index] + */ + + a = argv[argv_index]; + if (a[0] == '-') a++; + if (a[0] == '-') a++; + if (a[0] == '+') a++; + + while(a[0]) { a[0] = a[1]; a++; } + + /* + * decrement argv_index so that we process this + * entry again + */ + + argv_index--; + + o = &options[i]; + break; + } + } + } + } + + /* if we didn't find an option, return */ + + if (!o) { + fprintf(stderr, "%s: unrecognized option: \"%s\"\n", argv[0], arg); + goto done; + } + + /* + * if the option takes an argument string, then we either + * need to use what was after the "=" in this argv[] entry, + * or we need to pull the next entry off of argv[] + */ + + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + if (argument) { + if (!argument[0]) { + fprintf(stderr, "%s: option \"%s\" requires an " + "argument.\n", argv[0], arg); + goto done; + } + } else { + argv_index++; + if (argv_index >= argc) { + fprintf(stderr, "%s: option \"%s\" requires an " + "argument.\n", argv[0], arg); + goto done; + } + argument = argv[argv_index]; + } + + /* argument is now a valid string: parse it */ + + if ((o->flags & NVGETOPT_STRING_ARGUMENT) && (strval)) { + *strval = strdup(argument); + } else { + fprintf(stderr, "%s: error while assigning argument for " + "option \"%s\".\n", argv[0], arg); + goto done; + } + + } else { + + /* if we have an argument when we shouldn't; complain */ + + if (argument) { + fprintf(stderr, "%s: option \"%s\" does not take an argument, but " + "was given an argument of \"%s\".\n", + argv[0], arg, argument); + goto done; + } + } + + ret = o->val; + +done: + + free(arg); + return ret; + +} /* nvgetopt() */ diff --git a/nvgetopt.h b/nvgetopt.h new file mode 100644 index 0000000..d7c5f1b --- /dev/null +++ b/nvgetopt.h @@ -0,0 +1,69 @@ +/* + * nvidia-installer: A tool for installing/un-installing the + * NVIDIA Linux graphics driver. + * + * Copyright (C) 2004-2010 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA + * + * + * nvgetopt.h + */ + +#ifndef __NVGETOPT_H__ +#define __NVGETOPT_H__ + +#define NVGETOPT_FALSE 0 +#define NVGETOPT_TRUE 1 + +/* + * indicates that the option is a boolean value; the presence of the + * option will be interpretted as a TRUE value; if the option is + * prepended with '--no-', the option will be interpretted as a FALSE + * value. On success, nvgetopt will return the parsed boolean value + * through 'boolval'. + */ + +#define NVGETOPT_IS_BOOLEAN 0x1 + + +/* + * indicates that the option takes an argument to be interpretted as a + * string; on success, nvgetopt will return the parsed string argument + * through 'strval'. + */ + +#define NVGETOPT_STRING_ARGUMENT 0x2 + + +#define NVGETOPT_HAS_ARGUMENT (NVGETOPT_STRING_ARGUMENT) + +#define NVGETOPT_HELP_ALWAYS 0x20 + +typedef struct { + const char *name; + int val; + unsigned int flags; + char *description; /* not used by nvgetopt() */ +} NVGetoptOption; + + +int nvgetopt(int argc, char *argv[], const NVGetoptOption *options, + char **strval); + +#endif /* __NVGETOPT_H__ */ diff --git a/nvidia-installer.c b/nvidia-installer.c index 4e91c16..3f8ead9 100644 --- a/nvidia-installer.c +++ b/nvidia-installer.c @@ -2,18 +2,18 @@ * nvidia-installer: A tool for installing NVIDIA software packages on * Unix and Linux systems. * - * Copyright (C) 2003-2009 NVIDIA Corporation + * Copyright (C) 2003-2010 NVIDIA Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the: * @@ -133,7 +133,7 @@ static void print_help_args_only(int args_only, int advanced) { int i, j, len; char *msg, *tmp, scratch[64]; - const NVOption *o; + const NVGetoptOption *o; /* * the args_only parameter is used by makeself.sh to get our * argument list and description; in this case we don't want to @@ -151,12 +151,12 @@ static void print_help_args_only(int args_only, int advanced) * not set, then skip this option */ - if (!advanced && !(o->flags & OPTION_HELP_ALWAYS)) continue; + if (!advanced && !(o->flags & NVGETOPT_HELP_ALWAYS)) continue; /* Skip options with no help text */ if (!o->description) continue; - if (o->flags & NVOPT_IS_BOOLEAN) { + if (o->flags & NVGETOPT_IS_BOOLEAN) { msg = nvstrcat("--", o->name, "/--no-", o->name, NULL); } else if (isalnum(o->val)) { sprintf(scratch, "%c", o->val); @@ -164,7 +164,7 @@ static void print_help_args_only(int args_only, int advanced) } else { msg = nvstrcat("--", o->name, NULL); } - if (o->flags & NVOPT_HAS_ARGUMENT) { + if (o->flags & NVGETOPT_HAS_ARGUMENT) { len = strlen(o->name); for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); scratch[len] = '\0'; @@ -185,58 +185,21 @@ static void print_help_args_only(int args_only, int advanced) /* - * parse_commandline() - malloc an Options structure, initialize it, - * and fill in any pertinent data from the commandline arguments; it - * is intended that this function do only minimal sanity checking -- - * just enough error trapping to ensure correct syntax of the - * commandline options. Validation of the actual data specified - * through the options is left for the functions that use this data. + * load_default_options - Allocate an Options structure + * and initialize it with default values. * - * XXX Would it be better to do more validation now? - * - * XXX this implementation uses getopt_long(), which isn't portable to - * non-glibc based systems... */ -Options *parse_commandline(int argc, char *argv[]) +static Options *load_default_options(void) { Options *op; - int c, option_index = 0; - char *program_name; - - const int num_opts = sizeof(__options) / sizeof(__options[0]) - 1; - /* Allocate space for the long options. */ - struct option *long_options = nvalloc(num_opts * sizeof(struct option)); - /* Allocate space for the short options: leave enough room for a letter and - * ':' for each option, plus the '\0'. */ - char *short_options = nvalloc(num_opts * 2 + 1); - char *pShort = short_options; - - /* Generate the table for getopt_long and the string for the short options. */ - for (c = 0; c < num_opts; c++) { - struct option* op = &long_options[c]; - const NVOption* o = &__options[c]; - - op->name = o->name; - op->has_arg = - (o->flags & NVOPT_HAS_ARGUMENT) ? - required_argument : no_argument; - op->flag = NULL; - op->val = o->val; - - if (isalnum(o->val)) { - *pShort++ = o->val; - - if (o->flags & NVOPT_HAS_ARGUMENT) - *pShort++ = ':'; - } - } - *pShort = '\0'; op = (Options *) nvalloc(sizeof(Options)); - + if (!op) { + return NULL; + } + /* statically initialized strings */ - op->proc_mount_point = DEFAULT_PROC_MOUNT_POINT; op->log_file_name = DEFAULT_LOG_FILE_NAME; op->ftp_site = DEFAULT_FTP_SITE; @@ -252,10 +215,30 @@ Options *parse_commandline(int argc, char *argv[]) op->sigwinch_workaround = TRUE; op->run_distro_scripts = TRUE; + return op; + +} /* load_default_options() */ + + + +/* + * parse_commandline() - Populate the Options structure with + * appropriate values, based on the arguments passed at the commandline. + * It is intended that this function does only minimal sanity checking -- + * just enough error trapping to ensure correct syntax of the + * commandline options. Validation of the actual data specified + * through the options is left for the functions that use this data. + */ + +static void parse_commandline(int argc, char *argv[], Options *op) +{ + int c, boolval; + char *strval = NULL, *program_name = NULL; + while (1) { - - c = getopt_long(argc, argv, short_options, - long_options, &option_index); + + c = nvgetopt(argc, argv, __options, &strval); + if (c == -1) break; @@ -274,7 +257,7 @@ Options *parse_commandline(int argc, char *argv[]) case 'n': op->no_precompiled_interface = TRUE; break; case 'c': op->no_ncurses_color = TRUE; break; case 'l': op->latest = TRUE; break; - case 'm': op->ftp_site = optarg; break; + case 'm': op->ftp_site = strval; break; case 'f': op->update = op->force_update = TRUE; break; case 'h': print_help(FALSE); exit(0); break; case 'A': print_help(TRUE); exit(0); break; @@ -291,86 +274,81 @@ Options *parse_commandline(int argc, char *argv[]) break; case 'k': - op->kernel_name = optarg; + op->kernel_name = strval; op->no_precompiled_interface = TRUE; op->ignore_cc_version_check = TRUE; break; case XFREE86_PREFIX_OPTION: case X_PREFIX_OPTION: - op->x_prefix = optarg; break; + op->x_prefix = strval; break; case X_LIBRARY_PATH_OPTION: - op->x_library_path = optarg; break; + op->x_library_path = strval; break; case X_MODULE_PATH_OPTION: - op->x_module_path = optarg; break; + op->x_module_path = strval; break; case OPENGL_PREFIX_OPTION: - op->opengl_prefix = optarg; break; + op->opengl_prefix = strval; break; case OPENGL_LIBDIR_OPTION: - op->opengl_libdir = optarg; break; + op->opengl_libdir = strval; break; #if defined(NV_X86_64) case COMPAT32_CHROOT_OPTION: - op->compat32_chroot = optarg; break; + op->compat32_chroot = strval; break; case COMPAT32_PREFIX_OPTION: - op->compat32_prefix = optarg; break; + op->compat32_prefix = strval; break; case COMPAT32_LIBDIR_OPTION: - op->compat32_libdir = optarg; break; + op->compat32_libdir = strval; break; #endif case DOCUMENTATION_PREFIX_OPTION: - op->documentation_prefix = optarg; break; + op->documentation_prefix = strval; break; case INSTALLER_PREFIX_OPTION: - op->installer_prefix = optarg; break; + op->installer_prefix = strval; break; case UTILITY_PREFIX_OPTION: - op->utility_prefix = optarg; break; + op->utility_prefix = strval; break; case UTILITY_LIBDIR_OPTION: - op->utility_libdir = optarg; break; + op->utility_libdir = strval; break; case KERNEL_SOURCE_PATH_OPTION: - op->kernel_source_path = optarg; break; + op->kernel_source_path = strval; break; case KERNEL_OUTPUT_PATH_OPTION: - op->kernel_output_path = optarg; break; + op->kernel_output_path = strval; break; case KERNEL_INCLUDE_PATH_OPTION: - op->kernel_include_path = optarg; break; + op->kernel_include_path = strval; break; case KERNEL_INSTALL_PATH_OPTION: - op->kernel_module_installation_path = optarg; break; + op->kernel_module_installation_path = strval; break; case UNINSTALL_OPTION: op->uninstall = TRUE; break; case PROC_MOUNT_POINT_OPTION: - op->proc_mount_point = optarg; break; + op->proc_mount_point = strval; break; case USER_INTERFACE_OPTION: - op->ui_str = optarg; break; + op->ui_str = strval; break; case LOG_FILE_NAME_OPTION: - op->log_file_name = optarg; break; + op->log_file_name = strval; break; case HELP_ARGS_ONLY_OPTION: print_help_args_only(TRUE, FALSE); exit(0); break; case TMPDIR_OPTION: - op->tmpdir = optarg; break; + op->tmpdir = strval; break; case NO_OPENGL_HEADERS_OPTION: op->opengl_headers = FALSE; break; case FORCE_TLS_OPTION: - if (strcasecmp(optarg, "new") == 0) + if (strcasecmp(strval, "new") == 0) op->which_tls = FORCE_NEW_TLS; - else if (strcasecmp(optarg, "classic") == 0) + else if (strcasecmp(strval, "classic") == 0) op->which_tls = FORCE_CLASSIC_TLS; else { - fmterr(""); - fmterr("Invalid parameter for '--force-tls'; please " - "run `%s --help` for usage information.", argv[0]); - fmterr(""); - exit(1); + fmterr("\n"); + fmterr("Invalid parameter for '--force-tls'"); + goto fail; } break; #if defined(NV_X86_64) case FORCE_TLS_COMPAT32_OPTION: - if (strcasecmp(optarg, "new") == 0) + if (strcasecmp(strval, "new") == 0) op->which_tls_compat32 = FORCE_NEW_TLS; - else if (strcasecmp(optarg, "classic") == 0) + else if (strcasecmp(strval, "classic") == 0) op->which_tls_compat32 = FORCE_CLASSIC_TLS; else { - fmterr(""); - fmterr("Invalid parameter for '--force-tls-compat32'; " - "please run `%s --help` for usage information.", - argv[0]); - fmterr(""); - exit(1); + fmterr("\n"); + fmterr("Invalid parameter for '--force-tls-compat32'"); + goto fail; } break; #endif @@ -384,7 +362,7 @@ Options *parse_commandline(int argc, char *argv[]) print_help_args_only(TRUE, TRUE); exit(0); break; case RPM_FILE_LIST_OPTION: - op->rpm_file_list = optarg; + op->rpm_file_list = strval; break; case NO_RUNLEVEL_CHECK_OPTION: op->no_runlevel_check = TRUE; @@ -393,10 +371,10 @@ Options *parse_commandline(int argc, char *argv[]) op->no_network = TRUE; break; case PRECOMPILED_KERNEL_INTERFACES_PATH_OPTION: - op->precompiled_kernel_interfaces_path = optarg; + op->precompiled_kernel_interfaces_path = strval; break; case PRECOMPILED_KERNEL_INTERFACES_URL_OPTION: - op->precompiled_kernel_interfaces_url = optarg; + op->precompiled_kernel_interfaces_url = strval; break; case NO_ABI_NOTE_OPTION: op->no_abi_note = TRUE; @@ -408,21 +386,18 @@ Options *parse_commandline(int argc, char *argv[]) op->no_recursion = TRUE; break; case FORCE_SELINUX_OPTION: - if (strcasecmp(optarg, "yes") == 0) + if (strcasecmp(strval, "yes") == 0) op->selinux_option = SELINUX_FORCE_YES; - else if (strcasecmp(optarg, "no") == 0) + else if (strcasecmp(strval, "no") == 0) op->selinux_option = SELINUX_FORCE_NO; - else if (strcasecmp(optarg, "default")) { - fmterr(""); - fmterr("Invalid parameter for '--force-selinux'; " - "please run `%s --help` for usage information.", - argv[0]); - fmterr(""); - exit(1); + else if (strcasecmp(strval, "default")) { + fmterr("\n"); + fmterr("Invalid parameter for '--force-selinux'"); + goto fail; } break; case SELINUX_CHCON_TYPE_OPTION: - op->selinux_chcon_type = optarg; break; + op->selinux_chcon_type = strval; break; case NO_SIGWINCH_WORKAROUND_OPTION: op->sigwinch_workaround = FALSE; break; @@ -441,11 +416,7 @@ Options *parse_commandline(int argc, char *argv[]) break; default: - fmterr(""); - fmterr("Invalid commandline, please run `%s --help` " - "for usage information.", argv[0]); - fmterr(""); - exit(1); + goto fail; } /* @@ -460,25 +431,11 @@ Options *parse_commandline(int argc, char *argv[]) op->update_arguments = append_update_arguments(op->update_arguments, - c, optarg, - long_options); + c, strval, __options); } - } - nvfree((void*)long_options); - nvfree((void*)short_options); - - if (optind < argc) { - fmterr(""); - fmterr("Unrecognized arguments:"); - while (optind < argc) - fmterrp(" ", argv[optind++]); - fmterr("Invalid commandline, please run `%s --help` for " - "usage information.", argv[0]); - fmterr(""); - exit(1); } - + /* * if the installer prefix was not specified, default it to the * utility prefix; this is done so that the installer prefix is @@ -498,9 +455,16 @@ Options *parse_commandline(int argc, char *argv[]) if (strcmp(basename(program_name), "nvidia-uninstall") == 0) op->uninstall = TRUE; free(program_name); - - return (op); + return; + + fail: + fmterr("\n"); + fmterr("Invalid commandline, please run `%s --help` " + "for usage information.", argv[0]); + fmterr("\n"); + nvfree((void*)op); + exit(1); } /* parse_commandline() */ @@ -516,10 +480,18 @@ int main(int argc, char *argv[]) /* Ensure created files get the permissions we expect */ umask(022); + + /* Load defaults */ + + op = load_default_options(); + if (!op) { + fprintf(stderr, "\nOut of memory error.\n\n"); + return 1; + } /* parse the commandline options */ - op = parse_commandline(argc, argv); + parse_commandline(argc, argv, op); /* init the log file */ @@ -607,6 +579,8 @@ int main(int argc, char *argv[]) ui_close(op); + nvfree((void*)op); + return (ret ? 0 : 1); } /* main() */ diff --git a/option_table.h b/option_table.h index 8463e49..7ad2e99 100644 --- a/option_table.h +++ b/option_table.h @@ -1,14 +1,34 @@ -#define NVOPT_HAS_ARGUMENT 0x1 -#define NVOPT_IS_BOOLEAN 0x2 - -#define OPTION_HELP_ALWAYS 0x8000 - -typedef struct { - const char *name; - int val; - unsigned int flags; - char *description; /* not used by nvgetopt() */ -} NVOption; +/* + * nvidia-installer: A tool for installing/un-installing the + * NVIDIA Linux graphics driver. + * + * Copyright (C) 2004-2010 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + *? + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + *? + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA + * + * + * option_table.h + */ + +#ifndef __OPT_TABLE_H__ +#define __OPT_TABLE_H__ + +#include "nvgetopt.h" enum { XFREE86_PREFIX_OPTION = 1, @@ -57,31 +77,31 @@ enum { NO_DISTRO_SCRIPTS_OPTION }; -static const NVOption __options[] = { +static const NVGetoptOption __options[] = { /* These options are printed by "nvidia-installer --help" */ - { "accept-license", 'a', OPTION_HELP_ALWAYS, + { "accept-license", 'a', NVGETOPT_HELP_ALWAYS, "Bypass the display and prompting for acceptance of the " "NVIDIA Software License Agreement. By passing this option to " "nvidia-installer, you indicate that you have read and accept the " "License Agreement contained in the file 'LICENSE' (in the top " "level directory of the driver package)." }, - { "update", UPDATE_OPTION, OPTION_HELP_ALWAYS, + { "update", UPDATE_OPTION, NVGETOPT_HELP_ALWAYS, "Connect to the NVIDIA FTP server ' " DEFAULT_FTP_SITE " ' and determine the " "latest available driver version. If there is a more recent " "driver available, automatically download and install it. Any " "other options given on the commandline will be passed on to the " "downloaded driver package when installing it." }, - { "version", 'v', OPTION_HELP_ALWAYS, + { "version", 'v', NVGETOPT_HELP_ALWAYS, "Print the nvidia-installer version and exit." }, - { "help", 'h', OPTION_HELP_ALWAYS, + { "help", 'h', NVGETOPT_HELP_ALWAYS, "Print usage information for the common commandline options " "and exit." }, - { "advanced-options", 'A', OPTION_HELP_ALWAYS, + { "advanced-options", 'A', NVGETOPT_HELP_ALWAYS, "Print usage information for the common commandline options " "as well as the advanced options, and then exit." }, @@ -118,17 +138,17 @@ static const NVOption __options[] = { "printed, except for error messages to stderr. This option " "implies '--ui=none --no-questions --accept-license'." }, - { "x-prefix", X_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "x-prefix", X_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the X components of the " "NVIDIA driver will be installed; the default is '" DEFAULT_X_PREFIX "' unless nvidia-installer detects that X.Org >= 7.0 is installed, " "in which case the default is '" XORG7_DEFAULT_X_PREFIX "'. Only " "under rare circumstances should this option be used." }, - { "xfree86-prefix", XFREE86_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "xfree86-prefix", XFREE86_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "This is a deprecated synonym for --x-prefix." }, - { "x-module-path", X_MODULE_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "x-module-path", X_MODULE_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The path under which the NVIDIA X server modules will be installed. " "If this option is not specified, nvidia-installer uses the following " "search order and selects the first valid directory it finds: 1) " @@ -138,7 +158,7 @@ static const NVOption __options[] = { "than X.Org 7.0) or '" XORG7_DEFAULT_X_MODULEDIR "' (for X.Org 7.0 or " "later)." }, - { "x-library-path", X_LIBRARY_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "x-library-path", X_LIBRARY_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The path under which the NVIDIA X libraries will be installed. " "If this option is not specified, nvidia-installer uses the following " "search order and selects the first valid directory it finds: 1) " @@ -148,14 +168,14 @@ static const NVOption __options[] = { DEFAULT_64BIT_LIBDIR "' or '" DEFAULT_LIBDIR "' on 64bit systems, " "depending on the installed Linux distribution." }, - { "opengl-prefix", OPENGL_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "opengl-prefix", OPENGL_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the OpenGL components of the " "NVIDIA driver will be installed; the default is: '" DEFAULT_OPENGL_PREFIX "'. Only under rare circumstances should this option be used. " "The Linux OpenGL ABI (http://oss.sgi.com/projects/ogl-sample/ABI/) " "mandates this default value." }, - { "opengl-libdir", OPENGL_LIBDIR_OPTION, NVOPT_HAS_ARGUMENT, + { "opengl-libdir", OPENGL_LIBDIR_OPTION, NVGETOPT_STRING_ARGUMENT, "The path relative to the OpenGL library installation prefix under " "which the NVIDIA OpenGL components will be installed. The " "default is '" DEFAULT_LIBDIR "' on 32bit systems, and '" @@ -164,7 +184,7 @@ static const NVOption __options[] = { "circumstances should this option be used." }, #if defined(NV_X86_64) - { "compat32-chroot", COMPAT32_CHROOT_OPTION, NVOPT_HAS_ARGUMENT, + { "compat32-chroot", COMPAT32_CHROOT_OPTION, NVGETOPT_STRING_ARGUMENT, "The top-level prefix (chroot) relative to which the 32bit " "compatibility OpenGL libraries will be installed on Linux/x86-64 " "systems; this option is unset by default, the 32bit OpenGL " @@ -172,13 +192,13 @@ static const NVOption __options[] = { "path alone determine the target location. Only under very rare " "circumstances should this option be used." }, - { "compat32-prefix", COMPAT32_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "compat32-prefix", COMPAT32_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the 32bit compatibility OpenGL components " "of the NVIDIA driver will be installed; the default is: '" DEFAULT_OPENGL_PREFIX "'. Only under rare circumstances should " "this option be used." }, - { "compat32-libdir", COMPAT32_LIBDIR_OPTION, NVOPT_HAS_ARGUMENT, + { "compat32-libdir", COMPAT32_LIBDIR_OPTION, NVGETOPT_STRING_ARGUMENT, "The path relative to the 32bit compatibility prefix under which the " "32bit compatibility OpenGL components of the NVIDIA driver will " "be installed. The default is '" DEFAULT_LIBDIR "' or '" @@ -187,36 +207,36 @@ static const NVOption __options[] = { "option be used." }, #endif /* NV_X86_64 */ - { "installer-prefix", INSTALLER_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "installer-prefix", INSTALLER_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the installer binary will be " "installed; the default is: '" DEFAULT_UTILITY_PREFIX "'. Note: please " "use the '--utility-prefix' option instead." }, - { "utility-prefix", UTILITY_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "utility-prefix", UTILITY_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the NVIDIA utilities (nvidia-installer, " "nvidia-settings, nvidia-xconfig, nvidia-bug-report.sh) and the NVIDIA " "utility libraries will be installed; the default is: '" DEFAULT_UTILITY_PREFIX "'." }, - { "utility-libdir", UTILITY_LIBDIR_OPTION, NVOPT_HAS_ARGUMENT, + { "utility-libdir", UTILITY_LIBDIR_OPTION, NVGETOPT_STRING_ARGUMENT, "The path relative to the utility installation prefix under which the " "NVIDIA utility libraries will be installed. The default is '" DEFAULT_LIBDIR "' on 32bit systems, and '" DEFAULT_64BIT_LIBDIR "' or '" DEFAULT_LIBDIR "' on 64bit " "systems, depending on the " "installed Linux distribution." }, - { "documentation-prefix", DOCUMENTATION_PREFIX_OPTION, NVOPT_HAS_ARGUMENT, + { "documentation-prefix", DOCUMENTATION_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, "The prefix under which the documentation files for the NVIDIA " "driver will be installed. The default is: '" DEFAULT_DOCUMENTATION_PREFIX "'." }, - { "kernel-include-path", KERNEL_INCLUDE_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "kernel-include-path", KERNEL_INCLUDE_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The directory containing the kernel include files that " "should be used when compiling the NVIDIA kernel module. " "This option is deprecated; please use '--kernel-source-path' " "instead." }, - { "kernel-source-path", KERNEL_SOURCE_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "kernel-source-path", KERNEL_SOURCE_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The directory containing the kernel source files that " "should be used when compiling the NVIDIA kernel module. " "When not specified, the installer will use " @@ -224,20 +244,20 @@ static const NVOption __options[] = { "directory exists. Otherwise, it will use " "'/usr/src/linux'." }, - { "kernel-output-path", KERNEL_OUTPUT_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "kernel-output-path", KERNEL_OUTPUT_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The directory containing any KBUILD output files if " "either one of the 'KBUILD_OUTPUT' or 'O' parameters were " "passed to KBUILD when building the kernel image/modules. " "When not specified, the installer will assume that no " "separate output directory was used." }, - { "kernel-install-path", KERNEL_INSTALL_PATH_OPTION, NVOPT_HAS_ARGUMENT, + { "kernel-install-path", KERNEL_INSTALL_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "The directory in which the NVIDIA kernel module should be " "installed. The default value is either '/lib/modules/`uname " "-r`/kernel/drivers/video' (if '/lib/modules/`uname -r`/kernel' " "exists) or '/lib/modules/`uname -r`/video'." }, - { "proc-mount-point", PROC_MOUNT_POINT_OPTION, NVOPT_HAS_ARGUMENT, + { "proc-mount-point", PROC_MOUNT_POINT_OPTION, NVGETOPT_STRING_ARGUMENT, "The mount point for the proc file system; if not " "specified, then this value defaults to '" DEFAULT_PROC_MOUNT_POINT "' (which is normally " @@ -247,18 +267,18 @@ static const NVOption __options[] = { "the currently running kernel. This option should only be needed " "in very rare circumstances." }, - { "log-file-name", LOG_FILE_NAME_OPTION, NVOPT_HAS_ARGUMENT, + { "log-file-name", LOG_FILE_NAME_OPTION, NVGETOPT_STRING_ARGUMENT, "File name of the installation log file (the default is: " "'" DEFAULT_LOG_FILE_NAME "')." }, - { "tmpdir", TMPDIR_OPTION, NVOPT_HAS_ARGUMENT, + { "tmpdir", TMPDIR_OPTION, NVGETOPT_STRING_ARGUMENT, "Use the specified directory as a temporary directory when " "downloading files from the NVIDIA ftp site; " "if not given, then the following list will be searched, and " "the first one that exists will be used: $TMPDIR, /tmp, ., " "$HOME." }, - { "ftp-mirror", 'm', NVOPT_HAS_ARGUMENT, + { "ftp-mirror", 'm', NVGETOPT_STRING_ARGUMENT, "Use the specified FTP mirror rather than the default ' " DEFAULT_FTP_SITE " ' when downloading driver updates." }, @@ -274,7 +294,7 @@ static const NVOption __options[] = { "thinks the latest driver is already installed; this option " "implies '--update'." }, - { "ui", USER_INTERFACE_OPTION, NVOPT_HAS_ARGUMENT, + { "ui", USER_INTERFACE_OPTION, NVGETOPT_STRING_ARGUMENT, "Specify what user interface to use, if available. " "Valid values for [UI] are 'ncurses' (the default) or 'none'. " "If the ncurses interface fails to initialize, or 'none' " @@ -289,7 +309,7 @@ static const NVOption __options[] = { "header files. This option disables installation of the NVIDIA " "OpenGL header files." }, - { "force-tls", FORCE_TLS_OPTION, NVOPT_HAS_ARGUMENT, + { "force-tls", FORCE_TLS_OPTION, NVGETOPT_STRING_ARGUMENT, "NVIDIA's OpenGL libraries are compiled with one of two " "different thread local storage (TLS) mechanisms: 'classic tls' " "which is used on systems with glibc 2.2 or older, and 'new tls' " @@ -300,13 +320,13 @@ static const NVOption __options[] = { "for [FORCE-TLS] are 'new' and 'classic'." }, #if defined(NV_X86_64) - { "force-tls-compat32", FORCE_TLS_COMPAT32_OPTION, NVOPT_HAS_ARGUMENT, + { "force-tls-compat32", FORCE_TLS_COMPAT32_OPTION, NVGETOPT_STRING_ARGUMENT, "This option forces the installer to install a specific " "32bit compatibility OpenGL TLS library; further details " "can be found in the description of the '--force-tls' option." }, #endif /* NV_X86_64 */ - { "kernel-name", 'k', NVOPT_HAS_ARGUMENT, + { "kernel-name", 'k', NVGETOPT_STRING_ARGUMENT, "Build and install the NVIDIA kernel module for the " "non-running kernel specified by [KERNEL-NAME] ([KERNEL-NAME] " "should be the output of `uname -r` when the target kernel is " @@ -379,12 +399,12 @@ static const NVOption __options[] = { "this option be used." }, { "precompiled-kernel-interfaces-path", - PRECOMPILED_KERNEL_INTERFACES_PATH_OPTION, NVOPT_HAS_ARGUMENT, + PRECOMPILED_KERNEL_INTERFACES_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "Before searching for a precompiled kernel interface in the " ".run file, search in the specified directory." }, { "precompiled-kernel-interfaces-url", - PRECOMPILED_KERNEL_INTERFACES_URL_OPTION, NVOPT_HAS_ARGUMENT, + PRECOMPILED_KERNEL_INTERFACES_URL_OPTION, NVGETOPT_STRING_ARGUMENT, "If no precompiled kernel interfaces are found within the driver package " "or provided on the file system by the Linux distribution, check the " "specified URL for updates. NVIDIA does not intend to provide updated " @@ -402,7 +422,7 @@ static const NVOption __options[] = { "'yes'. This is useful with the '--no-questions' or '--silent' " "options, which assume the default values for all questions." }, - { "force-selinux", FORCE_SELINUX_OPTION, NVOPT_HAS_ARGUMENT, + { "force-selinux", FORCE_SELINUX_OPTION, NVGETOPT_STRING_ARGUMENT, "Linux installations using SELinux (Security-Enhanced Linux) " "require that the security type of all shared libraries be set " "to 'shlib_t' or 'textrel_shlib_t', depending on the distribution. " @@ -417,7 +437,7 @@ static const NVOption __options[] = { "'no' (prevent setting of the security type), and 'default' " "(let nvidia-installer decide when to set the security type)." }, - { "selinux-chcon-type", SELINUX_CHCON_TYPE_OPTION, NVOPT_HAS_ARGUMENT, + { "selinux-chcon-type", SELINUX_CHCON_TYPE_OPTION, NVGETOPT_STRING_ARGUMENT, "When SELinux support is enabled, nvidia-installer will try to determine " "which chcon argument to use by first trying 'textrel_shlib_t', then " "'texrel_shlib_t', then 'shlib_t'. Use this option to override this " @@ -450,9 +470,10 @@ static const NVOption __options[] = { { "debug", 'd', 0, NULL }, { "help-args-only", HELP_ARGS_ONLY_OPTION, 0, NULL }, { "add-this-kernel", ADD_THIS_KERNEL_OPTION, 0, NULL }, - { "rpm-file-list", RPM_FILE_LIST_OPTION, NVOPT_HAS_ARGUMENT, NULL }, + { "rpm-file-list", RPM_FILE_LIST_OPTION, NVGETOPT_STRING_ARGUMENT, NULL }, { "no-rpms", NO_RPMS_OPTION, 0, NULL}, { "advanced-options-args-only", ADVANCED_OPTIONS_ARGS_ONLY_OPTION, 0, NULL }, { NULL, 0, 0, NULL }, }; +#endif /* __OPT_TABLE_H__ */ diff --git a/stream-ui.c b/stream-ui.c index 6e7806c..1df9d23 100644 --- a/stream-ui.c +++ b/stream-ui.c @@ -331,6 +331,9 @@ int stream_approve_command_list(Options *op, CommandList *cl, fmtoutp(prefix, "install the file '%s' as '%s' with " "permissions '%s'", c->s0, c->s1, perms); free(perms); + if (c->s2) { + fmtoutp(prefix, "execute the command `%s`", c->s2); + } break; case RUN_CMD: @@ -353,7 +356,8 @@ int stream_approve_command_list(Options *op, CommandList *cl, default: fmterrp("ERROR: ", "Error in CommandList! (cmd: %d; s0: '%s';" - "s1: '%s'; mode: %04o)", c->cmd, c->s0, c->s1, c->mode); + "s1: '%s'; s2: '%s'; mode: %04o)", + c->cmd, c->s0, c->s1, c->s2, c->mode); fmterr("Aborting installation."); return FALSE; break; @@ -221,26 +221,28 @@ int report_latest_driver_version(Options *op) */ char *append_update_arguments(char *s, int c, const char *arg, - struct option l[]) + const NVGetoptOption *options) { char *t; int i = 0; - if (!s) s = nvstrcat(" ", NULL); + if (!s) { + s = nvstrcat(" ", NULL); + } do { - if (l[i].val == c) { - t = nvstrcat(s, " --", l[i].name, NULL); + if (options[i].val == c) { + t = nvstrcat(s, " --", options[i].name, NULL); nvfree(s); s = t; - if (l[i].has_arg) { + if (options[i].flags & NVGETOPT_HAS_ARGUMENT) { t = nvstrcat(s, "=", arg, NULL); nvfree(s); s = t; } return (s); } - } while (l[++i].name); + } while (options[++i].name); return s; @@ -27,14 +27,12 @@ #ifndef __NVIDIA_INSTALLER_UPDATE_H__ #define __NVIDIA_INSTALLER_UPDATE_H__ +#include "nvgetopt.h" #include "nvidia-installer.h" -#define _GNU_SOURCE /* XXX not portable */ -#include <getopt.h> - int update(Options *); int report_latest_driver_version(Options *); char *append_update_arguments(char *s, int c, const char *arg, - struct option l[]); + const NVGetoptOption *options); #endif /* __NVIDIA_INSTALLER_UPDATE_H__ */ |