package.c revision 15242
133965Sjdp/*
277298Sobrien * The new sysinstall program.
333965Sjdp *
433965Sjdp * This is probably the last program in the `sysinstall' line - the next
533965Sjdp * generation being essentially a complete rewrite.
633965Sjdp *
733965Sjdp * $Id: package.c,v 1.30 1996/03/21 09:30:14 jkh Exp $
833965Sjdp *
933965Sjdp * Copyright (c) 1995
1033965Sjdp *	Jordan Hubbard.  All rights reserved.
1133965Sjdp *
1233965Sjdp * Redistribution and use in source and binary forms, with or without
1333965Sjdp * modification, are permitted provided that the following conditions
1433965Sjdp * are met:
1533965Sjdp * 1. Redistributions of source code must retain the above copyright
1633965Sjdp *    notice, this list of conditions and the following disclaimer,
1733965Sjdp *    verbatim and that no modifications are made prior to this
1833965Sjdp *    point in the file.
1933965Sjdp * 2. Redistributions in binary form must reproduce the above copyright
2033965Sjdp *    notice, this list of conditions and the following disclaimer in the
2133965Sjdp *    documentation and/or other materials provided with the distribution.
2233965Sjdp *
2333965Sjdp * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
2433965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2533965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2633965Sjdp * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
2733965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2833965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2933965Sjdp * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
3077298Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3177298Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3277298Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3377298Sobrien * SUCH DAMAGE.
3477298Sobrien *
3533965Sjdp */
3633965Sjdp
3733965Sjdp#include <stdio.h>
3833965Sjdp#include <string.h>
3933965Sjdp#include <stdlib.h>
4033965Sjdp#include <sys/errno.h>
4133965Sjdp#include <sys/param.h>
4233965Sjdp#include <sys/mount.h>
4333965Sjdp#include <sys/stat.h>
4433965Sjdp#include "sysinstall.h"
4533965Sjdp
4633965Sjdp/* Like package_extract, but assumes current media device */
4733965Sjdpint
4833965Sjdppackage_add(char *name)
4933965Sjdp{
5033965Sjdp    if (!mediaVerify())
5133965Sjdp	return DITEM_FAILURE;
5233965Sjdp    return package_extract(mediaDevice, name, FALSE);
5333965Sjdp}
5477298Sobrien
5577298Sobrien/* Extract a package based on a namespec and a media device */
5677298Sobrienint
5777298Sobrienpackage_extract(Device *dev, char *name, Boolean depended)
5877298Sobrien{
5977298Sobrien    char path[511];
6077298Sobrien    int fd, ret;
6177298Sobrien
6233965Sjdp    /* If necessary, initialize the ldconfig hints */
6333965Sjdp    if (!file_readable("/var/run/ld.so.hints"))
6433965Sjdp	vsystem("ldconfig /usr/lib /usr/local/lib /usr/X11R6/lib");
6533965Sjdp
6633965Sjdp    msgNotify("Checking for existence of %s package", name);
6733965Sjdp    /* Check to make sure it's not already there */
6833965Sjdp    if (!vsystem("pkg_info -e %s", name)) {
6933965Sjdp	msgDebug("package %s marked as already installed - return SUCCESS.\n", name);
7033965Sjdp	return DITEM_SUCCESS;
7133965Sjdp    }
7233965Sjdp
7333965Sjdp    if (!dev->init(dev)) {
7433965Sjdp	dialog_clear();
7533965Sjdp	msgConfirm("Unable to initialize media type for package extract.");
7633965Sjdp	return DITEM_FAILURE;
7733965Sjdp    }
7833965Sjdp
7933965Sjdp    /* Be initially optimistic */
8033965Sjdp    ret = DITEM_SUCCESS;
8133965Sjdp    /* Make a couple of paranoid locations for temp files to live if user specified none */
8233965Sjdp    if (!variable_get("PKG_TMPDIR")) {
8333965Sjdp	Mkdir("/usr/tmp", NULL);
8433965Sjdp	Mkdir("/var/tmp", NULL);
8533965Sjdp	/* Set it to a location with as much space as possible */
8633965Sjdp	variable_set2("PKG_TMPDIR", "/usr/tmp");
8733965Sjdp    }
8833965Sjdp
8933965Sjdp    sprintf(path, "packages/All/%s%s", name, strstr(name, ".tgz") ? "" : ".tgz");
9033965Sjdp    fd = dev->get(dev, path, TRUE);
9133965Sjdp    if (fd >= 0) {
9233965Sjdp	int i, tot, pfd[2];
9333965Sjdp	pid_t pid;
9433965Sjdp
9533965Sjdp	dialog_clear();
9633965Sjdp	msgNotify("Adding %s%s\nfrom %s", path, depended ? " (as a dependency)" : "", dev->name);
9733965Sjdp	pipe(pfd);
9833965Sjdp	pid = fork();
9933965Sjdp	if (!pid) {
10033965Sjdp	    dup2(pfd[0], 0); close(pfd[0]);
10133965Sjdp	    dup2(DebugFD, 1);
10233965Sjdp	    dup2(DebugFD, 2);
10333965Sjdp	    close(pfd[1]);
10433965Sjdp	    i = execl("/usr/sbin/pkg_add", "/usr/sbin/pkg_add", "-", 0);
10533965Sjdp	    if (isDebug())
10633965Sjdp		msgDebug("pkg_add returns %d status\n", i);
10733965Sjdp	}
10833965Sjdp	else {
10933965Sjdp	    char buf[BUFSIZ];
11033965Sjdp
11133965Sjdp	    tot = 0;
11233965Sjdp	    while ((i = read(fd, buf, BUFSIZ)) > 0) {
11333965Sjdp		char line[80];
11433965Sjdp		int x, len;
11533965Sjdp
11633965Sjdp		write(pfd[1], buf, i);
11733965Sjdp		tot += i;
11833965Sjdp		sprintf(line, "%d bytes read from package %s", tot, name);
11933965Sjdp		len = strlen(line);
12033965Sjdp		for (x = len; x < 79; x++)
12133965Sjdp		    line[x] = ' ';
12233965Sjdp		line[79] = '\0';
12333965Sjdp		mvprintw(0, 0, line);
12433965Sjdp		clrtoeol();
12533965Sjdp		refresh();
12633965Sjdp	    }
12733965Sjdp	    close(fd);
12833965Sjdp	    close(pfd[1]);
12933965Sjdp	    mvprintw(0, 0, "Package %s read successfully - waiting for pkg_add", name);
13033965Sjdp	    refresh();
13133965Sjdp	    i = waitpid(pid, &tot, 0);
13233965Sjdp	    if (i < 0 || WEXITSTATUS(tot)) {
13333965Sjdp		msgNotify("Add of package %s aborted due to some error -\n"
13477298Sobrien			  "Please check the debug screen for more info.");
13533965Sjdp	    }
13633965Sjdp	    else
13733965Sjdp		msgNotify("Package %s was added successfully", name);
13833965Sjdp	}
13933965Sjdp    }
14033965Sjdp    else {
14133965Sjdp	msgDebug("pkg_extract: get operation returned %d\n", fd);
14233965Sjdp	if (variable_get(VAR_NO_CONFIRM))
14333965Sjdp	    msgNotify("Unable to fetch package %s from selected media.\n"
14433965Sjdp		      "No package add will be done.", name);
14533965Sjdp	else {
14633965Sjdp	    dialog_clear();
14733965Sjdp	    msgConfirm("Unable to fetch package %s from selected media.\n"
14833965Sjdp		       "No package add will be done.", name);
14933965Sjdp	}
15033965Sjdp	ret = DITEM_FAILURE;
15133965Sjdp    }
15233965Sjdp    return ret;
15333965Sjdp}
15433965Sjdp