perform.c revision 73134
1327Sjkh#ifndef lint
230221Scharnierstatic const char rcsid[] =
350479Speter  "$FreeBSD: head/usr.sbin/pkg_install/info/perform.c 73134 2001-02-27 09:00:18Z sobomax $";
4327Sjkh#endif
5327Sjkh
6327Sjkh/*
7327Sjkh * FreeBSD install - a package for the installation and maintainance
8327Sjkh * of non-core utilities.
9327Sjkh *
10327Sjkh * Redistribution and use in source and binary forms, with or without
11327Sjkh * modification, are permitted provided that the following conditions
12327Sjkh * are met:
13327Sjkh * 1. Redistributions of source code must retain the above copyright
14327Sjkh *    notice, this list of conditions and the following disclaimer.
15327Sjkh * 2. Redistributions in binary form must reproduce the above copyright
16327Sjkh *    notice, this list of conditions and the following disclaimer in the
17327Sjkh *    documentation and/or other materials provided with the distribution.
18327Sjkh *
19327Sjkh * Jordan K. Hubbard
20327Sjkh * 23 Aug 1993
21327Sjkh *
22327Sjkh * This is the main body of the info module.
23327Sjkh *
24327Sjkh */
25327Sjkh
26327Sjkh#include "lib.h"
27327Sjkh#include "info.h"
28327Sjkh
2972174Ssobomax#include <sys/types.h>
3072174Ssobomax#include <err.h>
31327Sjkh#include <signal.h>
32327Sjkh
33327Sjkhstatic int pkg_do(char *);
34327Sjkh
35327Sjkhint
36327Sjkhpkg_perform(char **pkgs)
37327Sjkh{
3873134Ssobomax    char **matched;
397937Sjkh    char *tmp;
4073134Ssobomax    int err_cnt = 0;
4173134Ssobomax    int i, errcode;
42327Sjkh
43327Sjkh    signal(SIGINT, cleanup);
44327Sjkh
45327Sjkh    /* Overriding action? */
4616404Sjkh    if (CheckPkg) {
4716404Sjkh	char buf[FILENAME_MAX];
48327Sjkh
4916404Sjkh	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
5016404Sjkh	return abs(access(buf, R_OK));
5172174Ssobomax	/* Not reached */
5216404Sjkh    }
538857Srgrimes
5473134Ssobomax    if (MatchType != MATCH_EXACT) {
5573134Ssobomax	matched = matchinstalled(MatchType, pkgs, &errcode);
5673134Ssobomax	if (errcode != 0)
5773134Ssobomax	    return 1;
5873134Ssobomax	    /* Not reached */
5972174Ssobomax
6073134Ssobomax	if (matched != NULL)
6173134Ssobomax	    pkgs = matched;
6273134Ssobomax	else switch (MatchType) {
6373134Ssobomax	    case MATCH_GLOB:
6473134Ssobomax		break;
6573134Ssobomax	    case MATCH_ALL:
6673134Ssobomax		warnx("no packages installed");
6773134Ssobomax		return 0;
6873134Ssobomax		/* Not reached */
6973134Ssobomax	    case MATCH_REGEX:
7073134Ssobomax		warnx("no packages match pattern(s)");
7172174Ssobomax		return 1;
7273134Ssobomax		/* Not reached */
7373134Ssobomax	    default:
7473134Ssobomax		break;
7516404Sjkh	}
7673134Ssobomax    }
7772174Ssobomax
7873134Ssobomax    for (i = 0; pkgs[i]; i++)
7973134Ssobomax	err_cnt += pkg_do(pkgs[i]);
8072174Ssobomax
81327Sjkh    return err_cnt;
82327Sjkh}
83327Sjkh
8411780Sjkhstatic char *Home;
8511780Sjkh
86327Sjkhstatic int
87327Sjkhpkg_do(char *pkg)
88327Sjkh{
898086Sjkh    Boolean installed = FALSE, isTMP = FALSE;
90327Sjkh    char log_dir[FILENAME_MAX];
918086Sjkh    char fname[FILENAME_MAX];
92327Sjkh    Package plist;
93327Sjkh    FILE *fp;
948086Sjkh    struct stat sb;
958142Sjkh    char *cp = NULL;
968086Sjkh    int code = 0;
97327Sjkh
988086Sjkh    if (isURL(pkg)) {
9911780Sjkh	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
1008086Sjkh	    strcpy(fname, cp);
1018086Sjkh	    isTMP = TRUE;
1028086Sjkh	}
1038086Sjkh    }
1049782Sache    else if (fexists(pkg) && isfile(pkg)) {
1058086Sjkh	int len;
106327Sjkh
1078423Sjkh	if (*pkg != '/') {
1088423Sjkh	    if (!getcwd(fname, FILENAME_MAX))
1098423Sjkh		upchuck("getcwd");
1108423Sjkh	    len = strlen(fname);
1118423Sjkh	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
1128423Sjkh	}
1138423Sjkh	else
1148423Sjkh	    strcpy(fname, pkg);
1158086Sjkh	cp = fname;
1168086Sjkh    }
1178086Sjkh    else {
11811780Sjkh	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
1198086Sjkh	    strncpy(fname, cp, FILENAME_MAX);
1208086Sjkh    }
1218086Sjkh    if (cp) {
1223364Sjkh	/*
1233364Sjkh	 * Apply a crude heuristic to see how much space the package will
1243364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
1253577Sjkh	 * compress an average of 75%, but we're only unpacking the + files so
1263577Sjkh	 * be very optimistic.
1273364Sjkh	 */
1283364Sjkh	if (stat(fname, &sb) == FAIL) {
12930221Scharnier	    warnx("can't stat package file '%s'", fname);
1308086Sjkh	    code = 1;
1318086Sjkh	    goto bail;
1323364Sjkh	}
13311780Sjkh	Home = make_playpen(PlayPen, sb.st_size / 2);
134327Sjkh	if (unpack(fname, "+*")) {
13530221Scharnier	    warnx("error during unpacking, no info for '%s' available", pkg);
1368086Sjkh	    code = 1;
1378086Sjkh	    goto bail;
138327Sjkh	}
139327Sjkh    }
1408086Sjkh    /* It's not an ininstalled package, try and find it among the installed */
141327Sjkh    else {
1427937Sjkh	char *tmp;
1437937Sjkh
1447937Sjkh	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
1457937Sjkh		pkg);
146327Sjkh	if (!fexists(log_dir)) {
14730221Scharnier	    warnx("can't find package `%s' installed or in a file!", pkg);
148327Sjkh	    return 1;
149327Sjkh	}
150327Sjkh	if (chdir(log_dir) == FAIL) {
15130221Scharnier	    warnx("can't change directory to '%s'!", log_dir);
152327Sjkh	    return 1;
153327Sjkh	}
154327Sjkh	installed = TRUE;
155327Sjkh    }
156327Sjkh
157327Sjkh    /* Suck in the contents list */
158327Sjkh    plist.head = plist.tail = NULL;
159327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
160327Sjkh    if (!fp) {
16130221Scharnier	warnx("unable to open %s file", CONTENTS_FNAME);
1628086Sjkh	code = 1;
1638086Sjkh	goto bail;
164327Sjkh    }
165327Sjkh    /* If we have a prefix, add it now */
166327Sjkh    read_plist(&plist, fp);
167327Sjkh    fclose(fp);
168327Sjkh
169327Sjkh    /*
170327Sjkh     * Index is special info type that has to override all others to make
171327Sjkh     * any sense.
172327Sjkh     */
173327Sjkh    if (Flags & SHOW_INDEX) {
1748086Sjkh	char tmp[FILENAME_MAX];
175327Sjkh
1768086Sjkh	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
1778086Sjkh	show_index(tmp, COMMENT_FNAME);
178327Sjkh    }
179327Sjkh    else {
180327Sjkh	/* Start showing the package contents */
181411Sjkh	if (!Quiet)
182411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
183327Sjkh	if (Flags & SHOW_COMMENT)
184379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
18566339Smarko	if (Flags & SHOW_REQUIRE)
18666339Smarko	    show_plist("Depends on:\n", &plist, PLIST_PKGDEP);
1874996Sjkh	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
1884996Sjkh	    show_file("Required by:\n", REQUIRED_BY_FNAME);
189327Sjkh	if (Flags & SHOW_DESC)
190379Sjkh	    show_file("Description:\n", DESC_FNAME);
1914996Sjkh	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
1924996Sjkh	    show_file("Install notice:\n", DISPLAY_FNAME);
193327Sjkh	if (Flags & SHOW_PLIST)
194379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
195327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
196379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
19741866Sjkh	if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME))
19841866Sjkh	    show_file("Post-Install script:\n", POST_INSTALL_FNAME);
199327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
200379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
20141866Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME))
20241866Sjkh	    show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME);
2034996Sjkh	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
2044996Sjkh	    show_file("mtree file:\n", MTREE_FNAME);
205327Sjkh	if (Flags & SHOW_PREFIX)
206379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
207411Sjkh	if (Flags & SHOW_FILES)
208411Sjkh	    show_files("Files:\n", &plist);
20962775Ssobomax	if ((Flags & SHOW_SIZE) && installed)
21062775Ssobomax	    show_size("Package Size:\n", &plist);
21171965Sjkh	if ((Flags & SHOW_CKSUM) && installed)
21271965Sjkh	    show_cksum("Mismatched Checksums:\n", &plist);
21367454Ssobomax	if (Flags & SHOW_ORIGIN)
21467454Ssobomax	    show_origin("Origin:\n", &plist);
215411Sjkh	if (!Quiet)
216411Sjkh	    puts(InfoPrefix);
217327Sjkh    }
218327Sjkh    free_plist(&plist);
2198086Sjkh bail:
22033427Sjkh    leave_playpen();
2218086Sjkh    if (isTMP)
2228086Sjkh	unlink(fname);
2238086Sjkh    return code;
224327Sjkh}
225327Sjkh
226327Sjkhvoid
227327Sjkhcleanup(int sig)
228327Sjkh{
22933427Sjkh    static int in_cleanup = 0;
23033427Sjkh
23133427Sjkh    if (!in_cleanup) {
23233427Sjkh	in_cleanup = 1;
23372174Ssobomax	leave_playpen();
23433427Sjkh    }
23539068Sjkh    if (sig)
23639068Sjkh	exit(1);
237327Sjkh}
23849300Sjdp
239