diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2017-09-19 09:39:10 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2017-09-19 09:39:10 -0700 |
commit | 3cb284a5b22f1c515a3c12ced8b6177bc0da1f1f (patch) | |
tree | 7d6879ad30e141da9ccc394d121a4384c9f04854 | |
parent | ea6bb2990424e74d9c1e5ec05589b3ea83039a0e (diff) |
-rw-r--r-- | dist-files.mk | 7 | ||||
-rw-r--r-- | files.c | 9 | ||||
-rw-r--r-- | files.h | 2 | ||||
-rw-r--r-- | kernel.c | 210 | ||||
-rw-r--r-- | misc.c | 14 | ||||
-rw-r--r-- | nvidia-installer.c | 42 | ||||
-rw-r--r-- | nvidia-installer.h | 10 | ||||
-rw-r--r-- | option_table.h | 45 | ||||
-rw-r--r-- | snarf-ftp.c | 410 | ||||
-rw-r--r-- | snarf-http.c | 509 | ||||
-rw-r--r-- | snarf-internal.h | 82 | ||||
-rw-r--r-- | snarf.c | 537 | ||||
-rw-r--r-- | snarf.h | 42 | ||||
-rw-r--r-- | update.c | 368 | ||||
-rw-r--r-- | update.h | 34 | ||||
-rw-r--r-- | version.mk | 2 |
16 files changed, 45 insertions, 2278 deletions
diff --git a/dist-files.mk b/dist-files.mk index 8c786a7..2587aeb 100644 --- a/dist-files.mk +++ b/dist-files.mk @@ -36,11 +36,7 @@ SRC += log.c SRC += misc.c SRC += nvidia-installer.c SRC += precompiled.c -SRC += snarf-ftp.c -SRC += snarf-http.c -SRC += snarf.c SRC += stream-ui.c -SRC += update.c SRC += user-interface.c SRC += sanity.c SRC += conflicting-kernel-modules.c @@ -58,9 +54,6 @@ DIST_FILES += nvidia-installer.h DIST_FILES += option_table.h DIST_FILES += precompiled.h DIST_FILES += sanity.h -DIST_FILES += snarf-internal.h -DIST_FILES += snarf.h -DIST_FILES += update.h DIST_FILES += user-interface.h DIST_FILES += conflicting-kernel-modules.h @@ -1998,10 +1998,10 @@ void process_dot_desktop_files(Options *op, Package *p) /* - * set_security_context() - set the security context of the file to 'shlib_t' + * set_security_context() - set the security context of the file to 'type' * Returns TRUE on success or if SELinux is disabled, FALSE otherwise */ -int set_security_context(Options *op, const char *filename) +int set_security_context(Options *op, const char *filename, const char *type) { char *cmd = NULL; int ret = FALSE; @@ -2010,8 +2010,7 @@ int set_security_context(Options *op, const char *filename) return TRUE; } - cmd = nvstrcat(op->utils[CHCON], " -t ", op->selinux_chcon_type, " ", - filename, NULL); + cmd = nvstrcat(op->utils[CHCON], " -t ", type, " ", filename, NULL); ret = run_command(op, cmd, NULL, FALSE, 0, TRUE); @@ -2019,7 +2018,7 @@ int set_security_context(Options *op, const char *filename) if (cmd) nvfree(cmd); return ret; -} /* set_security_context() */ +} /* @@ -59,7 +59,7 @@ char *process_template_file(Options *op, PackageEntry *pe, char **tokens, char **replacements); void process_libGL_la_files(Options *op, Package *p); void process_dot_desktop_files(Options *op, Package *p); -int set_security_context(Options *op, const char *filename); +int set_security_context(Options *op, const char *filename, const char *type); void get_default_prefixes_and_paths(Options *op); #endif /* __NVIDIA_INSTALLER_FILES_H__ */ @@ -39,7 +39,6 @@ #include "files.h" #include "misc.h" #include "precompiled.h" -#include "snarf.h" #include "crc.h" #include "conflicting-kernel-modules.h" @@ -49,8 +48,6 @@ static char *default_kernel_module_installation_path(Options *op); static char *default_kernel_source_path(Options *op); static int check_for_loaded_kernel_module(Options *op, const char *); static void check_for_warning_messages(Options *op); -static PrecompiledInfo *download_updated_kernel_interface(Options*, Package*, - const char*); static int fbdev_check(Options *op, Package *p); static int xen_check(Options *op, Package *p); @@ -733,10 +730,16 @@ static int set_loglevel(int level, int *old_level) int test_kernel_module(Options *op, Package *p) { - char *cmd = NULL, *data; + char *cmd = NULL, *data, *kernel_module_fullpath; int ret, i, old_loglevel, loglevel_set; const char *depmods[] = { "agpgart", "i2c-core", "drm" }; + /* SELinux type labels to add to kernel modules */ + static const char *selinux_kmod_types[] = { + "modules_object_t", + NULL + }; + /* * If we're building/installing for a different kernel, then we * can't test the module now. @@ -755,13 +758,28 @@ int test_kernel_module(Options *op, Package *p) } } + kernel_module_fullpath = nvstrcat(p->kernel_module_build_directory, "/", + p->kernel_module_filename, NULL); + + /* Some SELinux policies require specific file type labels for inserting + * kernel modules. Attempt to set known types until one succeeds. If all + * types fail, hopefully it's just because no type is needed. */ + for (i = 0; selinux_kmod_types[i]; i++) { + if (set_security_context(op, kernel_module_fullpath, + selinux_kmod_types[i])) { + break; + + } + } + cmd = nvstrcat(op->utils[INSMOD], " ", - p->kernel_module_build_directory, "/", - p->kernel_module_filename, + kernel_module_fullpath, " NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=0" " NVreg_DeviceFileMode=0 NVreg_ModifyDeviceFiles=0", NULL); + nvfree(kernel_module_fullpath); + loglevel_set = set_loglevel(PRINTK_LOGLEVEL_KERN_ALERT, &old_loglevel); /* only output the result of the test if in expert mode */ @@ -1065,23 +1083,6 @@ int find_precompiled_kernel_interface(Options *op, Package *p) info = scan_dir(op, p, p->precompiled_kernel_interface_directory, output_filename, proc_version_string); } - - /* - * If we didn't find a matching precompiled kernel interface, ask - * if we should try to download one. - */ - - if (!info && !op->no_network && op->precompiled_kernel_interfaces_url) { - info = download_updated_kernel_interface(op, p, - proc_version_string); - if (!info) { - ui_message(op, "No matching precompiled kernel interface was " - "found at '%s'; this means that the installer will need " - "to compile a kernel interface for your kernel.", - op->precompiled_kernel_interfaces_url); - return FALSE; - } - } /* If we found one, ask expert users if they really want to use it */ @@ -1374,169 +1375,6 @@ int rmmod_kernel_module(Options *op, const char *module_name) /* - * get_updated_kernel_interfaces() - - */ - -static PrecompiledInfo * -download_updated_kernel_interface(Options *op, Package *p, - const char *proc_version_string) -{ - int fd = -1; - int dst_fd = -1; - int length; - char *url = NULL; - char *tmpfile = NULL; - char *dstfile = NULL; - char *buf = NULL; - char *output_filename = NULL; - char *str = (void *) -1; - char *ptr, *s; - struct stat stat_buf; - PrecompiledInfo *info = NULL; - uint32 crc; - - /* initialize the tmpfile and url strings */ - - tmpfile = nvstrcat(op->tmpdir, "/nv-updates-XXXXXX", NULL); - url = nvstrcat(op->precompiled_kernel_interfaces_url, "/", INSTALLER_OS, - "-", INSTALLER_ARCH, "/", p->version, "/updates/updates.txt", - NULL); - - /* - * create a temporary file in which to write the list of available - * updates - */ - - if ((fd = mkstemp(tmpfile)) == -1) { - ui_error(op, "Unable to create temporary file (%s)", strerror(errno)); - goto done; - } - - /* download the updates list */ - - if (!snarf(op, url, fd, SNARF_FLAGS_DOWNLOAD_SILENT)) goto done; - - /* get the length of the file */ - - if (fstat(fd, &stat_buf) == -1) goto done; - - length = stat_buf.st_size; - - /* map the file into memory for easier reading */ - - str = mmap(0, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); - if (str == (void *) -1) goto done; - - /* - * loop over each line of the updates file: each line should be of - * the format: "[filename]:::[proc version string]" - */ - - ptr = str; - - while (TRUE) { - buf = get_next_line(ptr, &ptr, str, length); - if ((!buf) || (buf[0] == '\0')) goto done; - - s = strstr(buf, ":::"); - if (!s) { - ui_error(op, "Invalid updates.txt list."); - goto done; - } - - s += 3; /* skip past the ":::" separator */ - - if (strcmp(proc_version_string, s) == 0) { - - /* proc versions strings match */ - - /* - * terminate the string at the start of the ":::" - * separator so that buf is the filename - */ - - s -= 3; - *s = '\0'; - - /* build the new url and dstfile strings */ - - nvfree(url); - url = nvstrcat(op->precompiled_kernel_interfaces_url, "/", - INSTALLER_OS, "-", INSTALLER_ARCH, "/", p->version, - "/updates/", buf, NULL); - - dstfile = nvstrcat(p->precompiled_kernel_interface_directory, - "/", buf, NULL); - - /* create dstfile */ - - dst_fd = creat(dstfile, S_IRUSR | S_IWUSR); - if (dst_fd == -1) { - ui_error(op, "Unable to create file '%s' (%s).", - dstfile, strerror(errno)); - goto done; - } - - /* download the file */ - - if (!snarf(op, url, dst_fd, SNARF_FLAGS_STATUS_BAR)) goto done; - - close(dst_fd); - dst_fd = -1; - - /* XXX once we have gpg setup, should check the file here */ - - /* build the output filename string */ - - output_filename = nvstrcat(p->kernel_module_build_directory, "/", - PRECOMPILED_KERNEL_INTERFACE_FILENAME, - NULL); - - /* unpack the downloaded file */ - - info = precompiled_unpack(op, dstfile, output_filename, - proc_version_string, - p->version); - - /* compare checksums */ - - crc = compute_crc(op, output_filename); - - if (info && (info->crc != crc)) { - ui_error(op, "The embedded checksum of the downloaded file " - "'%s' (%d) does not match the computed checksum ", - "(%d); not using.", buf, info->crc, crc); - unlink(dstfile); - /* XXX free info */ - info = NULL; - } - - goto done; - } - - nvfree(buf); - } - - - done: - - if (dstfile) nvfree(dstfile); - if (buf) nvfree(buf); - if (str != (void *) -1) munmap(str, stat_buf.st_size); - if (dst_fd > 0) close(dst_fd); - if (fd > 0) close(fd); - - unlink(tmpfile); - if (tmpfile) nvfree(tmpfile); - if (url) nvfree(url); - - return info; - -} /* get_updated_kernel_interfaces() */ - - - -/* * check_cc_version() - check if the selected or default system * compiler is compatible with the one that was used to build the * currently running kernel. @@ -1446,7 +1446,7 @@ static int tls_test_internal(Options *op, int which_tls, goto done; } - if (set_security_context(op, dso_tmpfile) == FALSE) { + if (!set_security_context(op, dso_tmpfile, op->selinux_chcon_type)) { /* We are on a system with SELinux and the chcon command failed. * Assume that the system is recent enough to have the new TLS */ @@ -2222,17 +2222,13 @@ int check_selinux(Options *op) ui_warn(op, "Couldn't test chcon. Assuming shlib_t."); op->selinux_chcon_type = "shlib_t"; } else { - int i, ret; - char *cmd; + int i; /* Try each chcon command */ for (i = 0; chcon_types[i]; i++) { - cmd = nvstrcat(op->utils[CHCON], " -t ", chcon_types[i], " ", - tmpfile, NULL); - ret = run_command(op, cmd, NULL, FALSE, 0, TRUE); - nvfree(cmd); - - if (ret == 0) break; + if (set_security_context(op, tmpfile, chcon_types[i])) { + break; + } } if (!chcon_types[i]) { diff --git a/nvidia-installer.c b/nvidia-installer.c index 6fdc5b9..6f9c0ca 100644 --- a/nvidia-installer.c +++ b/nvidia-installer.c @@ -43,7 +43,6 @@ #include "backup.h" #include "files.h" #include "misc.h" -#include "update.h" #include "sanity.h" #include "option_table.h" @@ -130,7 +129,6 @@ static Options *load_default_options(void) /* statically initialized strings */ op->proc_mount_point = DEFAULT_PROC_MOUNT_POINT; - op->ftp_site = DEFAULT_FTP_SITE; op->tmpdir = get_tmpdir(op); op->distro = get_distribution(op); @@ -192,7 +190,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) switch (c) { case 'a': op->accept_license = TRUE; break; - case UPDATE_OPTION: op->update = TRUE; break; case 'e': op->expert = TRUE; break; case 'v': print_version(); exit(0); break; case 'd': op->debug = TRUE; break; @@ -203,9 +200,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) 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 = strval; break; - case 'f': op->update = op->force_update = TRUE; break; case 'h': print_help_after = TRUE; break; case 'A': print_help_after = TRUE; @@ -324,14 +318,13 @@ static void parse_commandline(int argc, char *argv[], Options *op) op->no_runlevel_check = TRUE; break; case 'N': - op->no_network = TRUE; + /* This option is no longer used; ignore it. */ + fmterr("The '--no-network' option is deprecated: " + "nvidia-installer will ignore this option."); break; case PRECOMPILED_KERNEL_INTERFACES_PATH_OPTION: op->precompiled_kernel_interfaces_path = strval; break; - case PRECOMPILED_KERNEL_INTERFACES_URL_OPTION: - op->precompiled_kernel_interfaces_url = strval; - break; case NO_ABI_NOTE_OPTION: op->no_abi_note = TRUE; break; @@ -389,21 +382,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) goto fail; } - /* - * as we go, build a list of options that we would pass on to - * a new invocation of the installer if we were to download a - * new driver and run its installer (update mode). Be sure - * not to place "--update" or "--force-update" in the update - * argument list (avoid infinite loop) - */ - - if ((c != UPDATE_OPTION) && (c != 'f')) { - - op->update_arguments = - append_update_arguments(op->update_arguments, - c, strval, __options); - } - } if (print_help_after) { @@ -519,15 +497,9 @@ int main(int argc, char *argv[]) get_default_prefixes_and_paths(op); - /* get the latest available driver version */ - - if (op->latest) { - ret = report_latest_driver_version(op); - } - /* get driver information */ - else if (op->driver_info) { + if (op->driver_info) { ret = report_driver_information(op); } @@ -543,12 +515,6 @@ int main(int argc, char *argv[]) ret = uninstall_existing_driver(op, TRUE); } - /* update */ - - else if (op->update) { - ret = update(op); - } - /* add this kernel */ else if (op->add_this_kernel) { diff --git a/nvidia-installer.h b/nvidia-installer.h index 80d8a6a..56b96a2 100644 --- a/nvidia-installer.h +++ b/nvidia-installer.h @@ -105,7 +105,6 @@ typedef uint8_t uint8; typedef struct __options { int accept_license; - int update; int expert; int uninstall; int skip_module_unload; @@ -114,8 +113,6 @@ typedef struct __options { int logging; int no_precompiled_interface; int no_ncurses_color; - int latest; - int force_update; int opengl_headers; int no_questions; int silent; @@ -125,7 +122,6 @@ typedef struct __options { int add_this_kernel; int no_runlevel_check; int no_backup; - int no_network; int kernel_module_only; int no_kernel_module; int no_abi_note; @@ -186,14 +182,10 @@ typedef struct __options { char *ui_str; char *log_file_name; - char *ftp_site; - char *tmpdir; - char *update_arguments; char *kernel_name; char *rpm_file_list; char *precompiled_kernel_interfaces_path; - char *precompiled_kernel_interfaces_url; const char *selinux_chcon_type; Distribution distro; @@ -507,8 +499,6 @@ typedef struct __package { #define DEFAULT_PROC_MOUNT_POINT "/proc" -#define DEFAULT_FTP_SITE "ftp://download.nvidia.com" - #define LICENSE_FILE "LICENSE" #define DEFAULT_LOG_FILE_NAME "/var/log/nvidia-installer.log" diff --git a/option_table.h b/option_table.h index cba4ed3..06fda69 100644 --- a/option_table.h +++ b/option_table.h @@ -98,13 +98,6 @@ static const NVGetoptOption __options[] = { "License Agreement contained in the file 'LICENSE' (in the top " "level directory of the driver package)." }, - { "update", UPDATE_OPTION, NVGETOPT_HELP_ALWAYS, NULL, - "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', NVGETOPT_HELP_ALWAYS | NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL, NULL, "Print the nvidia-installer version and exit." }, @@ -311,27 +304,11 @@ static const NVGetoptOption __options[] = { { "tmpdir", TMPDIR_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL, NULL, "Use the specified directory as a temporary directory when " - "downloading files from the NVIDIA ftp site; " + "generating transient files used by the installer; " "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', NVGETOPT_STRING_ARGUMENT, NULL, - "Use the specified FTP mirror rather than the default ' " - DEFAULT_FTP_SITE - " ' when downloading driver updates." }, - - { "latest", 'l', 0, NULL, - "Connect to the NVIDIA FTP server ' " DEFAULT_FTP_SITE " ' " - "(or use the ftp mirror " - "specified with the '--ftp-mirror' option) and query the most " - "recent " INSTALLER_OS "-" INSTALLER_ARCH " driver version number." }, - - { "force-update", 'f', 0, NULL, - "Forces an update to proceed, even if the installer " - "thinks the latest driver is already installed; this option " - "implies '--update'." }, - { "ui", USER_INTERFACE_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL, NULL, "Specify what user interface to use, if available. " @@ -410,11 +387,6 @@ static const NVGetoptOption __options[] = { "uninstalled. This option causes the installer to simply delete " "conflicting files, rather than back them up." }, - { "no-network", 'N', 0, NULL, - "This option instructs the installer to not attempt to " - "connect to the NVIDIA ftp site (for updated precompiled kernel " - "interfaces, for example)." }, - { "no-recursion", NO_RECURSION_OPTION, 0, NULL, "Normally, nvidia-installer will recursively search for " "potentially conflicting libraries under the default OpenGL " @@ -449,16 +421,6 @@ static const NVGetoptOption __options[] = { "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, - NVGETOPT_STRING_ARGUMENT, NULL, - "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 " - "precompiled kernel interfaces, but system administrators might use this " - "for distributing precompiled kernel interfaces in a local area " - "network." }, - { "no-nouveau-check", 'z', 0, NULL, "Normally, nvidia-installer aborts installation if the nouveau kernel " "driver is in use. Use this option to disable this check." }, @@ -564,6 +526,11 @@ static const NVGetoptOption __options[] = { { "advanced-options-args-only", ADVANCED_OPTIONS_ARGS_ONLY_OPTION, 0, NULL, NULL }, + /* Deprecated options: These options are no longer used, but + * nvidia-installer will allow the user to set them anyway, for + * backwards-compatibility purposes. */ + { "no-network", 'N', 0, NULL, NULL }, + { NULL, 0, 0, NULL, NULL }, }; diff --git a/snarf-ftp.c b/snarf-ftp.c deleted file mode 100644 index d2cde60..0000000 --- a/snarf-ftp.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * snarf-ftp.c - this source file contains functions for downloading - * files via the ftp protocol. Based on snarf - * (http://www.xach.com/snarf/) by Zachary Beane <xach@xach.com>, - * released under the GPL. - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include <unistd.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include <stdarg.h> - -#include <netdb.h> - -#ifdef USE_SOCKS5 -#define SOCKS -#include <socks.h> -#endif - -#include <errno.h> - -#include "snarf-internal.h" -#include "user-interface.h" -#include "misc.h" - - - -static void close_quit(int sock) -{ - if (sock) { - write(sock, "QUIT\r\n", 6); - close(sock); - } -} /* close_quit() */ - - - -static void ftp_set_defaults(UrlResource *rsrc, Url *u) -{ - if (!u->port) u->port = 21; - if (!u->username) u->username = strdup("anonymous"); - if (!u->password) u->password = strdup("snarf@"); - -} /* ftp_set_defaults() */ - - - -static void send_control(int sock, char *string, ...) -{ - va_list args; - char *line = NULL; - char *newline; - char *s = NULL; - - line = nvstrdup(string); - - va_start(args, string); - s = va_arg(args, char *); - while (s) { - newline = nvstrcat(line, s, NULL); - nvfree(line); - line = newline; - s = va_arg(args, char *); - } - va_end(args); - - write(sock, line, strlen(line)); - nvfree(line); - -} /* send_control() */ - - - -static char *get_line(UrlResource *rsrc, int control) -{ - int bytes_read = 0; - char *end; - char buf[SNARF_BUFSIZE+1]; - - while ((bytes_read = read(control, buf, SNARF_BUFSIZE)) > 0) { - - if (buf[0] == '4' || buf[0] == '5') return NULL; - - /* in case there's a partial read */ - buf[bytes_read] = '\0'; - - if (buf[bytes_read - 1] == '\n') buf[bytes_read - 1] = '\0'; - - if (buf[bytes_read - 2] == '\r') buf[bytes_read - 2] = '\0'; - - ui_expert(rsrc->op, "%s", buf); - - if (isdigit(buf[0]) && buf[3] == ' ') { - return strdup(buf); - } - - /* skip to last line of possibly multiple line input */ - - if ((end = strrchr(buf, '\n'))) { - end++; - if (isdigit(end[0]) && end[3] == ' ') - return strdup(end); - } - } - - return NULL; - -} /* get_line() */ - - - -static int check_numeric(const char *numeric, const char *buf) -{ - return ((buf[0] == numeric[0]) && - (buf[1] == numeric[1]) && - (buf[2] == numeric[2])); - -} /* check_numeric() */ - - - -static int sock_init(Options *op, struct sockaddr_in *sa, int control) -{ - socklen_t i; - int sock; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ui_error(op, "unable to open socket (%s)", strerror(errno)); - return(0); - } - - i = sizeof(*sa); - - getsockname(control, (struct sockaddr *)sa, &i); - sa->sin_port = 0 ; /* let system choose a port */ - if (bind (sock, (struct sockaddr *)sa, sizeof (*sa)) < 0) { - ui_error(op, "unable to bind socket (%s)", strerror(errno)); - return 0; - } - - return sock; - -} /* sock_init() */ - - - -static int get_passive_sock(UrlResource *rsrc, int control) -{ - unsigned char *addr; - struct sockaddr_in sa; - int sock; - int x; - char *line, *orig_line; - - send_control(control, "PASV\r\n", NULL); - - if( !((line = get_line(rsrc, control)) && - check_numeric("227", line)) ) { - nvfree(line); - return 0; - } - - orig_line = line; - - if (strlen(line) < 4) { - nvfree(line); - return 0; - } - - if (!(sock = sock_init(rsrc->op, &sa, control))) return -1; - - /* skip the numeric response */ - line += 4; - - /* then find the digits */ - - while (!(isdigit(*line))) line++; - - /* ugliness from snarf 1.x */ - - sa.sin_family = AF_INET; - addr = (unsigned char *)&sa.sin_addr; - - for(x = 0; x < 4; x++) { - addr[x] = atoi(line); - line = strchr(line,',') + 1; - } - - addr = (unsigned char *)&sa.sin_port ; - addr[0] = atoi(line); - line = strchr(line,',') + 1; - addr[1] = atoi(line); - - if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - nvfree(orig_line); - ui_error(rsrc->op, "unable to connect (%s)", strerror(errno)); - return -1; - } - - nvfree(orig_line); - return sock; - -} /* get_passive_sock() */ - - - -static int get_sock(UrlResource *rsrc, int control) -{ - struct sockaddr_in sa; - unsigned char *addr; - unsigned char *port; - char *line; - char port_string[SNARF_BUFSIZE]; - unsigned int sock; - socklen_t i; - - if (!(sock = sock_init(rsrc->op, &sa, control))) return 0; - - - if (listen(sock, 0) < 0) { - ui_error(rsrc->op, "unable to listen (%s)", strerror(errno)); - return 0; - } - - i = sizeof(sa); - - getsockname(sock, (struct sockaddr *)&sa, &i); - - addr = (unsigned char *)(&sa.sin_addr.s_addr); - port = (unsigned char *)(&sa.sin_port); - - sprintf(port_string, "PORT %d,%d,%d,%d,%d,%d\r\n", - addr[0], addr[1], addr[2], addr[3], - port[0],(unsigned char)port[1]); - - send_control(control, port_string, NULL); - - if (!((line = get_line(rsrc, control)) && check_numeric("200", line))) { - nvfree(line); - return 0; - } - nvfree(line); - - return sock; - -} /* get_sock() */ - - - -/* I'm going to go to hell for not doing proper cleanup. */ - -int ftp_transfer(UrlResource *rsrc) -{ - Url *u = NULL; - char *line = NULL; - int sock = 0; - int data_sock = 0; - int passive = 1; - int retval = 0; - - u = rsrc->url; - - /* - * first of all, if this is proxied, just pass it off to the - * http module, since that's how we support proxying. - */ - - rsrc->proxy = get_proxy("FTP_PROXY"); - - if (rsrc->proxy && (rsrc->proxy[0] != '\0')) { - return http_transfer(rsrc); - } - - ftp_set_defaults(rsrc, u); - - if (!(sock = tcp_connect(rsrc->op, u->host, u->port))) - return FALSE; - - if (!(line = get_line(rsrc, sock))) - return FALSE; - - if (!check_numeric("220", line)) { - ui_error(rsrc->op, "bad ftp server greeting: %s", line); - nvfree(line); - return FALSE; - } - - send_control(sock, "USER ", u->username, "\r\n", NULL); - - if (!(line = get_line(rsrc, sock))) return FALSE; - - /* do the password dance */ - if (!check_numeric("230", line)) { - if (!check_numeric("331", line)) { - nvfree(line); - ui_error(rsrc->op, "bad/unexpected response: %s", line); - return FALSE; - } else { - nvfree(line); - - send_control(sock, "PASS ", u->password, "\r\n", NULL); - - if (!((line = get_line(rsrc, sock)) && - check_numeric("230", line)) ) { - nvfree(line); - ui_error(rsrc->op, "login failed"); - return FALSE; - } - nvfree(line); - } - } - - /* set binmode */ - send_control(sock, "TYPE I\r\n", NULL); - - if (!(line = get_line(rsrc, sock))) return 0; - nvfree(line); - - if (u->path) { - send_control(sock, "CWD ", u->path, "\r\n", NULL); - - if (!((line = get_line(rsrc, sock)) && - check_numeric("250", line))) { - nvfree(line); - close_quit(sock); - return 0; - } - nvfree(line); - } - - /* finally, the good stuff */ - - /* get a socket for reading. try passive first. */ - - if ((data_sock = get_passive_sock(rsrc, sock)) == -1) { - return FALSE; - } - - if (!data_sock) { - if ((data_sock = get_sock(rsrc, sock)) < 1) - return 0; - else - passive = 0; - } - - if (u->file) { - send_control(sock, "SIZE ", u->file, "\r\n", NULL); - line = get_line(rsrc, sock); - if (line && check_numeric("213", line)) { - rsrc->outfile_size = atoi(line + 3); - } else { - rsrc->outfile_size = 0; - } - } - - if (u->file) - send_control(sock, "RETR ", u->file, "\r\n", NULL); - else - send_control(sock, "NLST\r\n", NULL); - - if (!((line = get_line(rsrc, sock)) && - (check_numeric("150", line) || check_numeric("125", line)))) { - nvfree(line); - close_quit(sock); - return 0; - } - - if (!passive) - data_sock = accept(data_sock, NULL, NULL); - - nvfree(line); - - retval = dump_data(rsrc, data_sock); - - line = get_line(rsrc, sock); /* 226 Transfer complete */ - nvfree(line); - send_control(sock, "QUIT\r\n", NULL); - line = get_line(rsrc, sock); /* 221 Goodbye */ - nvfree(line); - - close(sock); - close(data_sock); - return retval; - -} /* ftp_transfer() */ diff --git a/snarf-http.c b/snarf-http.c deleted file mode 100644 index 548c804..0000000 --- a/snarf-http.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * snarf-http.c - this source file contains functions for downloading - * files via HTTP. Based on snarf (http://www.xach.com/snarf/) by - * Zachary Beane <xach@xach.com>, released under the GPL. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <pwd.h> -#include <ctype.h> -#include <unistd.h> - -#include "snarf.h" -#include "snarf-internal.h" -#include "user-interface.h" -#include "misc.h" - - -/* - * NV_STRCAT() - takes a dynamically allocated string followed by a - * NULL-terminated list of arbitrary strings and concatenates the - * strings with nvstrcat(); the newly allocated string replaces the - * original one, which is freed. - */ -#define NV_STRCAT(str, args...) \ -do { \ - char *__tmp_str = (str); \ - (str) = nvstrcat(__tmp_str, ##args); \ - nvfree(__tmp_str); \ -} while (0) - - - -extern int default_opts; - -int redirect_count = 0; -#define REDIRECT_MAX 10 - -typedef struct _HttpHeader HttpHeader; -typedef struct _HttpHeaderEntry HttpHeaderEntry; -typedef struct _List List; - -struct _HttpHeader { - List *header_list; -}; - -struct _HttpHeaderEntry { - char *key; - char *value; -}; - -struct _List { - void *data; - List *next; -}; - - - -static List *list_new(void) -{ - List *new_list; - - new_list = malloc(sizeof(List)); - - new_list->data = NULL; - new_list->next = NULL; - - return new_list; - -} /* list_new() */ - - - -static void list_append(List *l, void *data) -{ - if (l->data == NULL) { - l->data = data; - return; - } - - while (l->next) { - l = l->next; - } - - l->next = list_new(); - l->next->data = data; - l->next->next = NULL; - -} /* list_append() */ - - - -/* written by lauri alanko */ -static char *base64(char *bin, int len) -{ - char *buf= (char *)malloc((len+2)/3*4+1); - int i=0, j=0; - - char BASE64_END = '='; - char base64_table[64]= "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - while( j < len - 2 ) { - buf[i++]=base64_table[bin[j]>>2]; - buf[i++]=base64_table[((bin[j]&3)<<4)|(bin[j+1]>>4)]; - buf[i++]=base64_table[((bin[j+1]&15)<<2)|(bin[j+2]>>6)]; - buf[i++]=base64_table[bin[j+2]&63]; - j+=3; - } - - switch ( len - j ) { - case 1: - buf[i++] = base64_table[bin[j]>>2]; - buf[i++] = base64_table[(bin[j]&3)<<4]; - buf[i++] = BASE64_END; - buf[i++] = BASE64_END; - break; - case 2: - buf[i++] = base64_table[bin[j] >> 2]; - buf[i++] = base64_table[((bin[j] & 3) << 4) - | (bin[j + 1] >> 4)]; - buf[i++] = base64_table[(bin[j + 1] & 15) << 2]; - buf[i++] = BASE64_END; - break; - case 0: - break; - } - buf[i]='\0'; - return buf; - -} /* base64() */ - - - -static HttpHeader *make_http_header(char *r) -{ - HttpHeader *h = NULL; - HttpHeaderEntry *he = NULL; - char *s = NULL; - char *raw_header = NULL; - char *raw_header_head = NULL; - - raw_header = strdup(r); - /* Track this to free at the end */ - raw_header_head = raw_header; - - h = malloc(sizeof(HttpHeader)); - h->header_list = list_new(); - - /* Skip the first line: "HTTP/1.X NNN Comment\r?\n" */ - s = raw_header; - while (*s != '\0' && *s != '\r' && *s != '\n') s++; - - while (*s != '\0' && isspace(*s)) s++; - - raw_header = s; - - s = strstr(raw_header, ": "); - while (s) { - /* Set ':' to '\0' to terminate the key */ - *s++ = '\0'; - he = malloc(sizeof(HttpHeaderEntry)); - he->key = strdup(raw_header); - /* Make it lowercase so we can lookup case-insensitive */ - nvstrtolower(he->key); - - /* Now get the value */ - s++; - raw_header = s; - while (*s != '\0' && *s != '\r' && *s != '\n') { - s++; - } - *s++ = '\0'; - he->value = strdup(raw_header); - list_append(h->header_list, he); - - /* Go to the next line */ - while (*s != '\0' && isspace(*s)) { - s++; - } - raw_header = s; - s = strstr(raw_header, ": "); - } - - free(raw_header_head); - return h; - -} /* make_http_header() */ - - - -static void free_http_header(HttpHeader *h) -{ - List *l; - List *l1; - HttpHeaderEntry *he; - - if (h == NULL) return; - - l = h->header_list; - while (l && l->data) { - he = l->data; - free(he->key); - free(he->value); - free(l->data); - l = l->next; - } - - l = h->header_list; - while (l) { - l1 = l->next; - free(l); - l = l1; - } - - free(h); - -} /* free_http_header() */ - - - -static char *get_header_value(char *key, HttpHeader *header) -{ - List *l = NULL; - HttpHeaderEntry *he = NULL; - - l = header->header_list; - - while (l && l->data) { - he = l->data; - if (strcmp(he->key, key) == 0) { - return strdup(he->value); - } - l = l->next; - } - - return NULL; - -} /* get_header_value() */ - - - -static char *get_raw_header(int fd) -{ - char *header = NULL; - char buf[SNARF_BUFSIZE]; /* this whole function is pathetic. please - rewrite it for me. */ - int bytes_read = 0; - int total_read = 0; - - header = strdup(""); - - buf[0] = buf[1] = buf[2] = '\0'; - - while( (bytes_read = read(fd, buf, 1)) ) { - total_read += bytes_read; - - header = nvstrcat(header, buf, NULL); - if( total_read > 1) { - if( strcmp(header + (total_read - 2), "\n\n") == 0 ) - break; - } - - if( total_read > 3 ) { - if( strcmp(header + (total_read - 4), "\r\n\r\n") - == 0 ) - break; - } - } - - return header; - -} /* get_raw_header() */ - - - -static char *get_request(UrlResource *rsrc) -{ - char *request = NULL; - char *auth = NULL; - char *tmp_auth = NULL; - Url *u; - - u = rsrc->url; - - request = nvstrcat("GET ", u->path, u->file, " HTTP/1.0\r\n", - "Host: ", u->host, "\r\n", NULL); - - if (u->username && u->password) { - tmp_auth = nvstrcat(u->username, ":", u->password, NULL); - auth = base64(tmp_auth, strlen(tmp_auth)); - nvfree(tmp_auth); - NV_STRCAT(request, "Authorization: Basic ", - auth, "\r\n", NULL); - nvfree(auth); - } - - if (rsrc->proxy_username && rsrc->proxy_password) { - tmp_auth = nvstrcat(rsrc->proxy_username, ":", - rsrc->proxy_password, NULL); - auth = base64(tmp_auth, strlen(tmp_auth)); - nvfree(tmp_auth); - NV_STRCAT(request, "Proxy-Authorization: Basic ", - auth, "\r\n", NULL); - nvfree(auth); - } - - NV_STRCAT(request, "User-Agent: ", PROGRAM_NAME, "/", - NVIDIA_INSTALLER_VERSION, NULL); - - /* This CRLF pair closes the User-Agent key-value set. */ - NV_STRCAT(request, "\r\n", NULL); - - /* If SNARF_HTTP_REFERER is set, spoof it. */ - if (getenv("SNARF_HTTP_REFERER")) { - NV_STRCAT(request, "Referer: ", - getenv("SNARF_HTTP_REFERER"), - "\r\n", NULL); - } - - NV_STRCAT(request, "\r\n", NULL); - - return request; - -} /* get_request() */ - - -int http_transfer(UrlResource *rsrc) -{ - Url *u = NULL; - Url *proxy_url = NULL; - Url *redir_u = NULL; - char *request = NULL; - char *raw_header = NULL; - char *tmp_header = NULL; - HttpHeader *header = NULL; - char *len_string = NULL; - char *new_location = NULL; - char buf[SNARF_BUFSIZE]; - int sock = 0; - ssize_t bytes_read = 0; - int retval = FALSE; - int i; - - /* make sure we haven't recursed too much */ - - if (redirect_count > REDIRECT_MAX) { - ui_error(rsrc->op, "redirection max count exceeded " - "(looping redirect?)"); - redirect_count = 0; - return FALSE; - } - - /* make sure everything's initialized to something useful */ - u = rsrc->url; - - if (! *(u->host)) { - ui_error(rsrc->op, "no host specified"); - return FALSE; - } - - /* fill in proxyness */ - if (!rsrc->proxy) { - rsrc->proxy = get_proxy("HTTP_PROXY"); - } - - if (!u->path) u->path = strdup("/"); - - if (!u->file) u->file = strdup(""); /* funny looking */ - - if (!u->port) u->port = 80; - - /* send the request to either the proxy or the remote host */ - if (rsrc->proxy) { - proxy_url = url_new(); - url_init(proxy_url, rsrc->proxy); - - if (!proxy_url->port) proxy_url->port = 80; - - if (!proxy_url->host) { - ui_error(rsrc->op, "bad proxy `%s'", rsrc->proxy); - return FALSE; - } - - if (proxy_url->username) - rsrc->proxy_username = strdup(proxy_url->username); - - if (proxy_url->password) - rsrc->proxy_password = strdup(proxy_url->password); - - /* Prompt for proxy password if not specified */ - if (proxy_url->username && !proxy_url->password) { - proxy_url->password = ui_get_input(rsrc->op, NULL, - "Password for " - "proxy %s@%s", - proxy_url->username, - proxy_url->host); - } - - if (!(sock = tcp_connect(rsrc->op, proxy_url->host, proxy_url->port))) - return FALSE; - - u->path = strdup(""); - u->file = strdup(u->full_url); - request = get_request(rsrc); - - write(sock, request, strlen(request)); - - } else /* no proxy */ { - - if (!(sock = tcp_connect(rsrc->op, u->host, u->port))) return FALSE; - - request = get_request(rsrc); - write(sock, request, strlen(request)); - } - - /* check to see if it returned an HTTP 1.x response */ - memset(buf, '\0', 5); - - bytes_read = read(sock, buf, 8); - - if (bytes_read <= 0) { - close(sock); - return FALSE; - } - - if (!(buf[0] == 'H' && buf[1] == 'T' - && buf[2] == 'T' && buf[3] == 'P')) { - write(rsrc->out_fd, buf, bytes_read); - } else { - /* skip the header */ - buf[bytes_read] = '\0'; - tmp_header = get_raw_header(sock); - raw_header = nvstrcat(buf, tmp_header, NULL); - free(tmp_header); - header = make_http_header(raw_header); - - /* if in expert mode, write the raw_header to the log */ - - ui_expert(rsrc->op, "%s", raw_header); - - /* check for redirects */ - new_location = get_header_value("location", header); - - if (raw_header[9] == '3' && new_location) { - redir_u = url_new(); - - /* make sure we still send user/password along */ - redir_u->username = nvstrdup(u->username); - redir_u->password = nvstrdup(u->password); - - url_init(redir_u, new_location); - rsrc->url = redir_u; - redirect_count++; - retval = transfer(rsrc); - goto cleanup; - } - - if (raw_header[9] == '4' || raw_header[9] == '5') { - for(i=0; raw_header[i] && raw_header[i] != '\n'; i++); - raw_header[i] = '\0'; - - if (!(rsrc->flags & SNARF_FLAGS_DOWNLOAD_SILENT)) { - ui_error(rsrc->op, "HTTP error from server: %s", raw_header); - } - - retval = FALSE; - goto cleanup; - } - - len_string = get_header_value("content-length", header); - - if (len_string) - rsrc->outfile_size = (off_t )atoi(len_string); - - if (get_header_value("content-range", header)) - rsrc->outfile_size += rsrc->outfile_offset; - } - - retval = dump_data(rsrc, sock); - - cleanup: - free_http_header(header); - close(sock); - return retval; - -} /* http_transfer() */ diff --git a/snarf-internal.h b/snarf-internal.h deleted file mode 100644 index c212b2d..0000000 --- a/snarf-internal.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * snarf-internal.h - */ - -#ifndef __NVIDIA_INSTALLER_SNARF_INTERNAL_H__ -#define __NVIDIA_INSTALLER_SNARF_INTERNAL_H__ - -#include "nvidia-installer.h" - -typedef struct _UrlResource UrlResource; -typedef struct _Url Url; - -struct _Url { - char *full_url; - int service_type; - char *username; - char *password; - char *host; - int port; - char *path; - char *file; -}; - -struct _UrlResource { - Url *url; - Options *op; - int out_fd; - uint32 flags; - char *proxy; - char *proxy_username; - char *proxy_password; - off_t outfile_size; - off_t outfile_offset; -}; - - -/* Service types */ -enum url_services { - SERVICE_HTTP = 1, - SERVICE_FTP -}; - - -#define SNARF_BUFSIZE (5*2048) - -/* snarf.c */ - -Url *url_new (void); -Url *url_init (Url *, const char *); -void url_destroy(Url *); -char *get_proxy (const char *); -int dump_data (UrlResource *, int); -int tcp_connect(Options *, char *, int); -int transfer(UrlResource *rsrc); - -/* snarf-ftp.c */ - -int ftp_transfer(UrlResource *); - -/* snarf-http.c */ - -int http_transfer(UrlResource *); - -#endif /* __NVIDIA_INSTALLER_SNARF_INTERNAL_H__ */ diff --git a/snarf.c b/snarf.c deleted file mode 100644 index 504489e..0000000 --- a/snarf.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * snarf.c - this source file contains functions for downloading - * files. Based on snarf (http://www.xach.com/snarf/) by Zachary - * Beane <xach@xach.com>, released under the GPL. - */ - -#include <stdlib.h> -#include <netdb.h> -#include <netinet/in.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <ctype.h> - -#include "nvidia-installer.h" - -#include "snarf.h" -#include "snarf-internal.h" - -#include "user-interface.h" -#include "misc.h" - - -static const char *get_url_service_type(const char *string, Url *u); -static const char *get_url_username (const char *string, Url *u); -static const char *get_url_password (const char *string, Url *u); -static const char *get_url_hostname (const char *url, Url *u); -static const char *get_url_port (const char *url, Url *u); -static const char *get_url_path (const char *url, Url *u); -static const char *get_url_file (const char *string, Url *u); - -static UrlResource *url_resource_new(void); -static void url_resource_destroy(UrlResource *rsrc); - -static const char *local_hstrerror(int n); - -/* - * snarf() - main entry point - */ - -int snarf(Options *op, const char *url, int out_fd, uint32 flags) -{ - UrlResource *rsrc = NULL; - int ret; - - if (op->no_network) { - ui_error(op, "Unable to access file '%s', because the '--no-network' " - "commandline option was specified.", url); - return FALSE; - } - - rsrc = url_resource_new(); - rsrc->url = url_new(); - rsrc->op = op; - - if (url_init(rsrc->url, url) == NULL) { - ui_error(op, "'%s' is not a valid URL.", url); - return FALSE; - } - - rsrc->out_fd = out_fd; - rsrc->flags = flags; - - ret = transfer(rsrc); - url_resource_destroy(rsrc); - - return ret; - -} /* snarf() */ - - - -Url *url_new(void) -{ - Url *new_url; - - new_url = nvalloc(sizeof(Url)); - - new_url->full_url = NULL; - new_url->service_type = 0; - new_url->username = NULL; - new_url->password = NULL; - new_url->host = NULL; - new_url->port = 0; - new_url->path = NULL; - new_url->file = NULL; - - return new_url; - -} /* url_new() */ - - - -Url *url_init(Url *u, const char *string) -{ - const char *sp = string; - - u->full_url = nvstrdup(string); - - if (!(sp = get_url_service_type(sp, u))) return NULL; - - /* - * only get username/password if they are not null, - * allows us to handle redirects properly - */ - - if (!u->username) - sp = get_url_username(sp, u); - if (!u->password) - sp = get_url_password(sp, u); - - sp = get_url_hostname(sp, u); - - if (!(u->host && *(u->host))) return NULL; - - sp = get_url_port(sp, u); - - sp = get_url_path(sp, u); - sp = get_url_file(sp, u); - - return u; - -} /* url_init() */ - - - -void url_destroy(Url *u) -{ - if (!u) return; - - nvfree(u->full_url); - nvfree(u->username); - nvfree(u->password); - nvfree(u->host); - nvfree(u->path); - nvfree(u->file); - -} /* url_destroy() */ - - - -char *get_proxy(const char *firstchoice) -{ - char *proxy; - char *help; - - if ((proxy = getenv(firstchoice))) return proxy; - - help = nvstrdup(firstchoice); - nvstrtolower(help); - proxy = getenv(help); - nvfree(help); - if (proxy) return proxy; - - if ((proxy = getenv("SNARF_PROXY"))) return proxy; - - if ((proxy = getenv("PROXY"))) return proxy; - - return NULL; - -} /* get_proxy() */ - - - -int tcp_connect(Options *op, char *remote_host, int port) -{ - struct hostent *host; - struct sockaddr_in sa; - int sock_fd; - - if ((host = (struct hostent *)gethostbyname(remote_host)) == NULL) { - ui_error(op, "Unable to connect to %s (%s)", - remote_host, local_hstrerror(h_errno)); - return FALSE; - } - - /* get the socket */ - if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ui_error(op, "Unable to create socket (%s)", strerror(errno)); - return FALSE; - } - - /* connect the socket, filling in the important stuff */ - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - memcpy(&sa.sin_addr, host->h_addr,host->h_length); - - if(connect(sock_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0){ - ui_error(op, "Unable to connect to remote host %s (%s)", - remote_host, strerror(errno)); - return FALSE; - } - - return sock_fd; - -} /* tcp_connect() */ - - - -int dump_data(UrlResource *rsrc, int sock) -{ - int bytes_read = 0; - int total_bytes_read = 0; - ssize_t written = 0; - char buf[SNARF_BUFSIZE]; - char *msg; - float percent; - - msg = nvstrcat("Downloading: ", rsrc->url->full_url, NULL); - - if (rsrc->flags & SNARF_FLAGS_STATUS_BAR) { - ui_status_begin(rsrc->op, msg, "Downloading"); - } - - while ((bytes_read = read(sock, buf, SNARF_BUFSIZE)) > 0) { - - if (rsrc->flags & SNARF_FLAGS_STATUS_BAR) { - total_bytes_read += bytes_read; - percent = (float) total_bytes_read / (float) rsrc->outfile_size; - ui_status_update(rsrc->op, percent, NULL); - } - - written = write(rsrc->out_fd, buf, bytes_read); - if (written == -1) { - ui_error(rsrc->op, "Error while writing output file (%s)", - strerror(errno)); - close(sock); - return FALSE; - } - } - - close(sock); - - if (rsrc->flags & SNARF_FLAGS_STATUS_BAR) { - ui_status_end(rsrc->op, "done."); - } - - free(msg); - - return 1; - -} /* dump_data() */ - - - -int transfer(UrlResource *rsrc) -{ - int ret = FALSE; - - switch (rsrc->url->service_type) { - case SERVICE_HTTP: - ret = http_transfer(rsrc); - break; - case SERVICE_FTP: - ret = ftp_transfer(rsrc); - break; - default: - ret = FALSE; - break; - } - - return ret; -} - - - -/*************************************************************************/ -/* static functions */ - -static const char *get_url_service_type(const char *string, Url *u) -{ - /* - * fixme: what if the string isn't at the beginning of the string? - */ - - if (strstr(string, "http://")) { - string += 7; - u->service_type = SERVICE_HTTP; - return string; - } - - if (strstr(string, "ftp://")) { - string += 6; - u->service_type = SERVICE_FTP; - return string; - } - - if (strncasecmp(string, "www", 3) == 0) { - u->service_type = SERVICE_HTTP; - u->full_url = nvstrcat("http://", u->full_url, NULL); - return string; - } - - if (strncasecmp(string, "ftp", 3) == 0) { - u->service_type = SERVICE_FTP; - u->full_url = nvstrcat("ftp://", u->full_url, NULL); - return string; - } - - /* default to browser-style serviceless http URL */ - u->full_url = nvstrcat("http://", u->full_url, NULL); - u->service_type = SERVICE_HTTP; - return string; - -} /* get_url_service_type() */ - - - -static const char *get_url_username(const char *string, Url *u) -{ - int i; - char *username; - char *at; - char *slash; - - at = strchr(string, '@'); - slash = strchr(string, '/'); - - if ((!at) || (slash && (at >= slash))) return string; - - for (i = 0; string[i] && string[i] != ':' && string[i] != '@' && - string[i] != '/'; i++); - - if (string[i] != '@' && string[i] != ':') return string; - - username = nvalloc(i); - memcpy(username, string, i + 1); - - username[i] = '\0'; - - string += i + 1; - - u->username = username; - return string; - -} /* get_url_username() */ - - - -static const char *get_url_password(const char *string, Url *u) -{ - int i; - char *password; - char *at; - char *slash; - - at = strchr(string, '@'); - slash = strchr(string, '/'); - - if ((!at) || (slash && (at >= slash))) return string; - - /* - * skipping to the end of the host portion. this is kinda messy - * for the (rare) cases where someone has a slash and/or at in - * their password. It's not perfect; but it catches easy cases. - * - * If you know of a better way to do this, be my guest. I do not - * feel a particular paternal instinct towards my ugly code. - * - * I guess that applies to this whole program. - */ - - for (i = 0 ; string[i] != '@'; i++); - - password = nvalloc(i); - - /* and finally, get the password portion */ - - memcpy(password, string, i); - password[i] = '\0'; - - string += i + 1; - - u->password = password; - - return string; - -} /* get_url_password() */ - - - -static const char *get_url_hostname(const char *url, Url *u) -{ - char *hostname; - int i; - - /* skip to end, slash, or port colon */ - for (i = 0; url[i] && url[i] != '/' && url[i] != ':'; i++); - - hostname = nvalloc(i + 1); - - memcpy(hostname, url, i); - - hostname[i] = '\0'; - - /* if there's a port */ - if(url[i] == ':') - url += i + 1; - else - url += i; - - u->host = hostname; - return url; - -} /* get_url_hostname() */ - - - -static const char *get_url_port(const char *url, Url *u) -{ - char *port_string; - int i; - - for (i = 0; isdigit(url[i]); i++); - - if (i == 0) return url; - - port_string = nvalloc(i + 1); - memcpy(port_string, url, i + 1); - - port_string[i] = '\0'; - - url += i; - - u->port = atoi(port_string); - - return url; - -} /* get_url_port() */ - - - -static const char *get_url_path(const char *url, Url *u) -{ - int i; - char *path; - - /* find where the last slash is */ - for (i = strlen(url); i > 0 && url[i] != '/'; i--); - - if (url[i] != '/') return url; - - path = nvalloc(i + 2); - memcpy(path, url, i + 1); - path[i] = '/'; - path[i + 1] = '\0'; - - url += i + 1; - u->path = path; - - return url; - -} /* get_url_path() */ - - - -static const char *get_url_file(const char *string, Url *u) -{ - char *file; - - if (!string[0]) return NULL; - - file = nvalloc(strlen(string) + 1); - - memcpy(file, string, strlen(string) + 1); - - u->file = file; - - return string; - -} /* get_url_file() */ - - - -static UrlResource *url_resource_new(void) -{ - UrlResource *new_resource; - - new_resource = nvalloc(sizeof(UrlResource)); - - new_resource->url = NULL; - new_resource->out_fd = 0; - new_resource->proxy = NULL; - new_resource->proxy_username = NULL; - new_resource->proxy_password = NULL; - new_resource->op = NULL; - new_resource->outfile_size = 0; - new_resource->outfile_offset = 0; - - return new_resource; - -} /* url_resource_new() */ - - - -static void url_resource_destroy(UrlResource *rsrc) -{ - if (!rsrc) return; - - if(rsrc->url) url_destroy(rsrc->url); - - free(rsrc); - -} /* url_resource_destroy() */ - - - -static const char *local_hstrerror(int n) -{ - switch (n) { - case HOST_NOT_FOUND: return "unknown host"; - case NO_ADDRESS: return "no IP address associated with host"; - case NO_RECOVERY: return "fatal DNS error"; - case TRY_AGAIN: return "temporary DNS error (try again later)"; - default: return "unknown error"; - } -} /* local_hstrerror() */ diff --git a/snarf.h b/snarf.h deleted file mode 100644 index f9f2fa0..0000000 --- a/snarf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * snarf.h - */ - -#ifndef __NVIDIA_INSTALLER_SNARF_H__ -#define __NVIDIA_INSTALLER_SNARF_H__ - -#include "nvidia-installer.h" - -/* - * SNARF_FLAGS_STATUS_BAR: when this flag is set, a status bar is - * displayed, showing the progress of the download. - */ -#define SNARF_FLAGS_STATUS_BAR 0x1 - -/* - * SNARF_FLAGS_DOWNLOAD_SILENT: when this flag is set, then snarf will - * not print error messages when the download fails - */ -#define SNARF_FLAGS_DOWNLOAD_SILENT 0x2 - -int snarf(Options *op, const char *url, int out_fd, uint32 flags); - -#endif /* __NVIDIA_INSTALLER_SNARF_H__ */ diff --git a/update.c b/update.c deleted file mode 100644 index a8e8700..0000000 --- a/update.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * update.c - */ - -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <sys/mman.h> -#include <string.h> -#include <errno.h> - -#include "nvidia-installer.h" -#include "misc.h" -#include "snarf.h" -#include "backup.h" -#include "user-interface.h" -#include "update.h" - - -static int get_latest_driver_version_and_filename(Options *op, - char **, char **); - - - -/* - * update() - determine if there is a more recent driver available; if - * so, download it and install it. - */ - -int update(Options *op) -{ - char *descr = NULL; - char *filename = NULL; - char *tmpfile = NULL; - char *url = NULL; - char *cmd; - char *installedVersion = NULL; - char *latestVersion = NULL; - int fd, installedRet, latestRet, localRet; - int ret = FALSE; - - installedRet = get_installed_driver_version_and_descr(op, - &installedVersion, - &descr); - - latestRet = get_latest_driver_version_and_filename(op, &latestVersion, - &filename); - if (!latestRet) { - goto done; - } - - if (installedRet && !op->force_update) { - - /* - * if the currently installed driver version is the same as - * the latest, don't update. - */ - - if (strcmp(installedVersion, latestVersion) == 0) { - ui_message(op, "The latest %s (version %s) is already " - "installed.", descr, installedVersion); - ret = TRUE; - goto done; - } - } - - /* build the temporary file and url strings */ - - tmpfile = nvstrcat(op->tmpdir, "/nv-update-XXXXXX", NULL); - url = nvstrcat(op->ftp_site, "/XFree86/", INSTALLER_OS, "-", - INSTALLER_ARCH, "/", filename, NULL); - - /* create the temporary file */ - - if ((fd = mkstemp(tmpfile)) == -1) { - ui_error(op, "Unable to create temporary file (%s)", strerror(errno)); - goto done; - } - - /* download the file */ - - if (!snarf(op, url, fd, SNARF_FLAGS_STATUS_BAR)) { - ui_error(op, "Unable to download driver %s.", url); - goto done; - } - - close(fd); - - /* XXX once we setup gpg validate the binary here */ - - /* check the binary */ - - cmd = nvstrcat("sh ", tmpfile, " --check", NULL); - localRet = run_command(op, cmd, NULL, FALSE, FALSE, TRUE); - nvfree(cmd); - - if (localRet != 0) { - ui_error(op, "The downloaded file does not pass its integrity check."); - goto done; - } - - /* - * We're ready to execute the binary; first, close down the ui so - * that the new installer can take over. - */ - - ui_close(op); - - /* execute `sh <downloaded file> <arguments>` */ - - cmd = nvstrcat("sh ", tmpfile, " ", op->update_arguments, NULL); - localRet = system(cmd); - nvfree(cmd); - - /* remove the downloaded file */ - - unlink(tmpfile); - - /* - * we've already shut down the ui, so no need to return from this - * function. - */ - - exit(localRet); - - ret = TRUE; - - done: - - nvfree(installedVersion); - nvfree(descr); - nvfree(latestVersion); - nvfree(filename); - - nvfree(tmpfile); - nvfree(url); - - return ret; - -} /* update() */ - - - -/* - * report_latest_driver_version() - - */ - -int report_latest_driver_version(Options *op) -{ - char *descr = NULL; - char *filename = NULL; - char *url = NULL; - char *installedVersion = NULL; - char *latestVersion = NULL; - int installedRet, latestRet; - - installedRet = get_installed_driver_version_and_descr(op, - &installedVersion, - &descr); - - latestRet = get_latest_driver_version_and_filename(op, &latestVersion, - &filename); - - if (!latestRet) { - nvfree(descr); - nvfree(installedVersion); - return FALSE; - } - - url = nvstrcat(op->ftp_site, "/XFree86/", INSTALLER_OS, "-", - INSTALLER_ARCH, "/", filename, NULL); - - if (installedRet) { - ui_message(op, "Currently installed version: %s; " - "latest available version: %s; latest driver " - "file: %s.", installedVersion, latestVersion, url); - } else { - ui_message(op, "Latest version: %s; latest driver file: %s.", - latestVersion, url); - } - - nvfree(descr); - nvfree(installedVersion); - nvfree(filename); - nvfree(latestVersion); - nvfree(url); - - return TRUE; - -} /* report_latest_driver_version() */ - - - -/* - * append_update_arguments() - append the specified argument to the - * update_arguments string. - */ - -char *append_update_arguments(char *s, int c, const char *arg, - const NVGetoptOption *options) -{ - char *t; - int i = 0; - - if (!s) { - s = nvstrcat(" ", NULL); - } - - do { - if (options[i].val == c) { - t = nvstrcat(s, " --", options[i].name, NULL); - nvfree(s); - s = t; - if (options[i].flags & NVGETOPT_HAS_ARGUMENT) { - t = nvstrcat(s, "=", arg, NULL); - nvfree(s); - s = t; - } - return (s); - } - } while (options[++i].name); - - return s; - -} /* append_update_arguments() */ - - - -/* - * get_latest_driver_version() - download and parse the latest.txt - * file; the format of this file is: - * - * [old format version] [path to .run file] - * [new format version] - * - * This is done for backwards compatibility -- old nvidia-installers - * will read only the first line and parse the old format version - * string; new nvidia-installers will try to find the version string - * on the second line. If we are unable to find the version string on - * the second line, then fall back to the old format string on the - * first line. - */ - -static int get_latest_driver_version_and_filename(Options *op, - char **pVersion, - char **pFileName) -{ - int fd = -1; - int length; - int ret = FALSE; - char *tmpfile = NULL; - char *url = NULL; - char *str = (void *) -1; - char *s = NULL; - char *buf = NULL; - char *buf2 = NULL; - char *ptr; - char *version = NULL; - struct stat stat_buf; - - tmpfile = nvstrcat(op->tmpdir, "/nv-latest-XXXXXX", NULL); - url = nvstrcat(op->ftp_site, "/XFree86/", INSTALLER_OS, "-", - INSTALLER_ARCH, "/latest.txt", NULL); - - /* check for no_network option */ - - if (op->no_network) { - ui_error(op, "Unable to determine most recent NVIDIA %s-%s driver " - "version: cannot access '%s', because the '--no-network' " - "commandline option was specified.", INSTALLER_OS, INSTALLER_ARCH, url); - goto done; - } - - if ((fd = mkstemp(tmpfile)) == -1) { - ui_error(op, "Unable to create temporary file (%s)", strerror(errno)); - goto done; - } - - if (!snarf(op, url, fd, SNARF_FLAGS_DOWNLOAD_SILENT)) { - ui_error(op, "Unable to determine most recent NVIDIA %s-%s driver " - "version.", INSTALLER_OS, INSTALLER_ARCH); - goto done; - } - - if (fstat(fd, &stat_buf) == -1) { - ui_error(op, "Unable to determine most recent NVIDIA %s-%s driver " - "version (%s).", INSTALLER_OS, INSTALLER_ARCH, - strerror(errno)); - goto done; - } - - length = stat_buf.st_size; - - str = mmap(0, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); - if (str == (void *) -1) { - ui_error(op, "Unable to determine most recent NVIDIA %s-%s driver " - "version (%s).", INSTALLER_OS, INSTALLER_ARCH, - strerror(errno)); - goto done; - } - - - /* - * read in the first two lines from the file; the second line may - * optionally contain a version string with the new format - */ - - buf = get_next_line(str, &ptr, str, length); - buf2 = get_next_line(ptr, NULL, str, length); - - version = extract_version_string(buf2); - if (!version) version = extract_version_string(buf); - - if (!version) { - ui_error(op, "Unable to determine latest NVIDIA driver " - "version (no version number found in %s)", url); - goto done; - } - - /* everything after the space is the filename */ - - s = strchr(buf, ' '); - if (!s) { - ui_error(op, "Unable to read filename from %s.", url); - goto done; - } - - s++; - *pFileName = nvstrdup(s); - *pVersion = strdup(version); - - ret = TRUE; - - done: - - nvfree(buf); - nvfree(buf2); - if (str != (void *) -1) munmap(str, stat_buf.st_size); - if (fd != -1) close(fd); - - unlink(tmpfile); - - nvfree(tmpfile); - nvfree(url); - nvfree(version); - - return ret; - -} /* get_latest_driver_version() */ diff --git a/update.h b/update.h deleted file mode 100644 index 351383e..0000000 --- a/update.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses>. - * - * - * update.h - */ - -#ifndef __NVIDIA_INSTALLER_UPDATE_H__ -#define __NVIDIA_INSTALLER_UPDATE_H__ - -#include "nvgetopt.h" -#include "nvidia-installer.h" - -int update(Options *); -int report_latest_driver_version(Options *); -char *append_update_arguments(char *s, int c, const char *arg, - const NVGetoptOption *options); - -#endif /* __NVIDIA_INSTALLER_UPDATE_H__ */ @@ -1 +1 @@ -NVIDIA_VERSION = 304.135 +NVIDIA_VERSION = 304.137 |