package.c revision 15883
1/* 2 * The new sysinstall program. 3 * 4 * This is probably the last program in the `sysinstall' line - the next 5 * generation being essentially a complete rewrite. 6 * 7 * $Id: package.c,v 1.36 1996/05/16 11:47:42 jkh Exp $ 8 * 9 * Copyright (c) 1995 10 * Jordan Hubbard. All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer, 17 * verbatim and that no modifications are made prior to this 18 * point in the file. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 */ 36 37#include <stdio.h> 38#include <string.h> 39#include <stdlib.h> 40#include <sys/errno.h> 41#include <sys/time.h> 42#include <sys/param.h> 43#include <sys/mount.h> 44#include <sys/stat.h> 45#include "sysinstall.h" 46 47/* Like package_extract, but assumes current media device */ 48int 49package_add(char *name) 50{ 51 if (!mediaVerify()) 52 return DITEM_FAILURE; 53 return package_extract(mediaDevice, name, FALSE); 54} 55 56Boolean 57package_exists(char *name) 58{ 59 int status = vsystem("pkg_info -e %s", name); 60 61 msgDebug("package check for %s returns %s.\n", name, 62 status ? "failure" : "success"); 63 return !status; 64} 65 66/* Extract a package based on a namespec and a media device */ 67int 68package_extract(Device *dev, char *name, Boolean depended) 69{ 70 char path[511]; 71 int fd, ret; 72 73 /* If necessary, initialize the ldconfig hints */ 74 if (!file_readable("/var/run/ld.so.hints")) 75 vsystem("ldconfig /usr/lib /usr/local/lib /usr/X11R6/lib"); 76 77 /* Check to make sure it's not already there */ 78 msgNotify("Checking for existence of %s package", name); 79 if (package_exists(name)) 80 return DITEM_SUCCESS; 81 82 if (!dev->init(dev)) { 83 msgConfirm("Unable to initialize media type for package extract."); 84 return DITEM_FAILURE; 85 } 86 87 /* Be initially optimistic */ 88 ret = DITEM_SUCCESS | DITEM_RESTORE; 89 /* Make a couple of paranoid locations for temp files to live if user specified none */ 90 if (!variable_get("PKG_TMPDIR")) { 91 Mkdir("/usr/tmp", NULL); 92 Mkdir("/var/tmp", NULL); 93 /* Set it to a location with as much space as possible */ 94 variable_set2("PKG_TMPDIR", "/usr/tmp"); 95 } 96 97 sprintf(path, "packages/All/%s%s", name, strstr(name, ".tgz") ? "" : ".tgz"); 98 fd = dev->get(dev, path, TRUE); 99 if (fd >= 0) { 100 int i, tot, pfd[2]; 101 pid_t pid; 102 103 msgNotify("Adding %s%s\nfrom %s", path, depended ? " (as a dependency)" : "", dev->name); 104 pipe(pfd); 105 pid = fork(); 106 if (!pid) { 107 dup2(pfd[0], 0); close(pfd[0]); 108 dup2(DebugFD, 1); 109 close(2); 110 close(pfd[1]); 111 i = execl("/usr/sbin/pkg_add", "/usr/sbin/pkg_add", "-", 0); 112 if (isDebug()) 113 msgDebug("pkg_add returns %d status\n", i); 114 } 115 else { 116 char buf[BUFSIZ]; 117 WINDOW *w = savescr(); 118 struct timeval start, stop; 119 120 close(pfd[0]); 121 tot = 0; 122 (void)gettimeofday(&start, (struct timezone *)0); 123 124 while ((i = read(fd, buf, BUFSIZ)) > 0) { 125 int seconds; 126 127 tot += i; 128 /* Print statistics about how we're doing */ 129 (void) gettimeofday(&stop, (struct timezone *)0); 130 stop.tv_sec = stop.tv_sec - start.tv_sec; 131 stop.tv_usec = stop.tv_usec - start.tv_usec; 132 if (stop.tv_usec < 0) 133 stop.tv_sec--, stop.tv_usec += 1000000; 134 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0); 135 if (!seconds) 136 seconds = 1; 137 msgInfo("%d bytes read from package %s, %d KBytes/second", tot, name, (tot / seconds) / 1024); 138 /* Write it out */ 139 if (write(pfd[1], buf, i) != i) { 140 msgInfo("Write failure to pkg_add! Package may be corrupt."); 141 break; 142 } 143 } 144 close(pfd[1]); 145 dev->close(dev, fd); 146 msgInfo("Package %s read successfully - waiting for pkg_add", name); 147 refresh(); 148 i = waitpid(pid, &tot, 0); 149 if (i < 0 || WEXITSTATUS(tot)) { 150 msgNotify("Add of package %s aborted due to some error -\n" 151 "Please check the debug screen for more info."); 152 } 153 else 154 msgNotify("Package %s was added successfully", name); 155 sleep(1); 156 restorescr(w); 157 } 158 } 159 else { 160 msgDebug("pkg_extract: get operation returned %d\n", fd); 161 dialog_clear(); 162 if (variable_get(VAR_NO_CONFIRM)) 163 msgNotify("Unable to fetch package %s from selected media.\n" 164 "No package add will be done.", name); 165 else { 166 msgConfirm("Unable to fetch package %s from selected media.\n" 167 "No package add will be done.", name); 168 } 169 ret = DITEM_FAILURE | DITEM_RESTORE; 170 } 171 return ret; 172} 173