perform.c revision 71965
1229997Sken#ifndef lint
2229997Skenstatic const char rcsid[] =
3232604Strasz  "$FreeBSD: head/usr.sbin/pkg_install/info/perform.c 71965 2001-02-03 20:56:32Z jkh $";
4229997Sken#endif
5229997Sken
6232604Strasz/*
7232604Strasz * FreeBSD install - a package for the installation and maintainance
8232604Strasz * of non-core utilities.
9229997Sken *
10229997Sken * Redistribution and use in source and binary forms, with or without
11229997Sken * modification, are permitted provided that the following conditions
12229997Sken * are met:
13229997Sken * 1. Redistributions of source code must retain the above copyright
14229997Sken *    notice, this list of conditions and the following disclaimer.
15229997Sken * 2. Redistributions in binary form must reproduce the above copyright
16229997Sken *    notice, this list of conditions and the following disclaimer in the
17229997Sken *    documentation and/or other materials provided with the distribution.
18229997Sken *
19229997Sken * Jordan K. Hubbard
20229997Sken * 23 Aug 1993
21229997Sken *
22229997Sken * This is the main body of the info module.
23229997Sken *
24229997Sken */
25229997Sken
26229997Sken#include "lib.h"
27229997Sken#include "info.h"
28229997Sken
29229997Sken#include <fts.h>
30229997Sken#include <signal.h>
31229997Sken#include <err.h>
32229997Sken
33229997Skenstatic int fname_cmp(const FTSENT **, const FTSENT **);
34278796Smavstatic int pkg_do(char *);
35229997Sken
36229997Skenint
37229997Skenpkg_perform(char **pkgs)
38229997Sken{
39229997Sken    int i, err_cnt = 0;
40229997Sken    char *tmp;
41229997Sken
42229997Sken    signal(SIGINT, cleanup);
43229997Sken
44229997Sken    tmp = getenv(PKG_DBDIR);
45229997Sken    if (!tmp)
46229997Sken	tmp = DEF_LOG_DIR;
47229997Sken    /* Overriding action? */
48229997Sken    if (CheckPkg) {
49273979Smav	char buf[FILENAME_MAX];
50229997Sken
51229997Sken	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
52229997Sken	return abs(access(buf, R_OK));
53229997Sken    }
54229997Sken    else if (AllInstalled) {
55229997Sken	FTS *ftsp;
56249009Strasz	FTSENT *f;
57229997Sken	char *paths[2];
58229997Sken
59229997Sken	if (!isdir(tmp))
60229997Sken	    return 1;
61229997Sken	paths[0] = tmp;
62229997Sken	paths[1] = NULL;
63229997Sken	ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT,
64265492Strasz	  fname_cmp);
65229997Sken	if (ftsp != NULL) {
66229997Sken	    while ((f = fts_read(ftsp)) != NULL) {
67275878Smav		if (f->fts_info == FTS_D && f->fts_level == 1) {
68229997Sken		    err_cnt += pkg_do(f->fts_name);
69229997Sken		    fts_set(ftsp, f, FTS_SKIP);
70229997Sken		}
71229997Sken	    }
72229997Sken	    fts_close(ftsp);
73229997Sken	}
74229997Sken    }
75229997Sken    else
76229997Sken	for (i = 0; pkgs[i]; i++)
77229997Sken	    err_cnt += pkg_do(pkgs[i]);
78229997Sken    return err_cnt;
79229997Sken}
80229997Sken
81229997Skenstatic char *Home;
82229997Sken
83229997Skenstatic int
84229997Skenpkg_do(char *pkg)
85229997Sken{
86229997Sken    Boolean installed = FALSE, isTMP = FALSE;
87229997Sken    char log_dir[FILENAME_MAX];
88229997Sken    char fname[FILENAME_MAX];
89229997Sken    Package plist;
90229997Sken    FILE *fp;
91229997Sken    struct stat sb;
92229997Sken    char *cp = NULL;
93229997Sken    int code = 0;
94229997Sken
95229997Sken    if (isURL(pkg)) {
96229997Sken	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
97229997Sken	    strcpy(fname, cp);
98229997Sken	    isTMP = TRUE;
99229997Sken	}
100229997Sken    }
101229997Sken    else if (fexists(pkg) && isfile(pkg)) {
102229997Sken	int len;
103229997Sken
104229997Sken	if (*pkg != '/') {
105229997Sken	    if (!getcwd(fname, FILENAME_MAX))
106229997Sken		upchuck("getcwd");
107229997Sken	    len = strlen(fname);
108229997Sken	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
109229997Sken	}
110229997Sken	else
111229997Sken	    strcpy(fname, pkg);
112229997Sken	cp = fname;
113229997Sken    }
114276615Smav    else {
115229997Sken	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
116229997Sken	    strncpy(fname, cp, FILENAME_MAX);
117229997Sken    }
118229997Sken    if (cp) {
119229997Sken	/*
120229997Sken	 * Apply a crude heuristic to see how much space the package will
121229997Sken	 * take up once it's unpacked.  I've noticed that most packages
122229997Sken	 * compress an average of 75%, but we're only unpacking the + files so
123229997Sken	 * be very optimistic.
124276615Smav	 */
125229997Sken	if (stat(fname, &sb) == FAIL) {
126229997Sken	    warnx("can't stat package file '%s'", fname);
127229997Sken	    code = 1;
128229997Sken	    goto bail;
129229997Sken	}
130229997Sken	Home = make_playpen(PlayPen, sb.st_size / 2);
131229997Sken	if (unpack(fname, "+*")) {
132229997Sken	    warnx("error during unpacking, no info for '%s' available", pkg);
133276615Smav	    code = 1;
134273977Smav	    goto bail;
135273977Smav	}
136273977Smav    }
137273977Smav    /* It's not an ininstalled package, try and find it among the installed */
138273977Smav    else {
139273977Smav	char *tmp;
140273977Smav
141274732Smav	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
142273977Smav		pkg);
143273977Smav	if (!fexists(log_dir)) {
144273977Smav	    warnx("can't find package `%s' installed or in a file!", pkg);
145273977Smav	    return 1;
146273977Smav	}
147276615Smav	if (chdir(log_dir) == FAIL) {
148273977Smav	    warnx("can't change directory to '%s'!", log_dir);
149273977Smav	    return 1;
150273977Smav	}
151273977Smav	installed = TRUE;
152273977Smav    }
153273977Smav
154273977Smav    /* Suck in the contents list */
155273977Smav    plist.head = plist.tail = NULL;
156273977Smav    fp = fopen(CONTENTS_FNAME, "r");
157273977Smav    if (!fp) {
158273977Smav	warnx("unable to open %s file", CONTENTS_FNAME);
159273977Smav	code = 1;
160273977Smav	goto bail;
161276615Smav    }
162229997Sken    /* If we have a prefix, add it now */
163229997Sken    read_plist(&plist, fp);
164229997Sken    fclose(fp);
165229997Sken
166229997Sken    /*
167229997Sken     * Index is special info type that has to override all others to make
168229997Sken     * any sense.
169229997Sken     */
170229997Sken    if (Flags & SHOW_INDEX) {
171229997Sken	char tmp[FILENAME_MAX];
172229997Sken
173229997Sken	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
174229997Sken	show_index(tmp, COMMENT_FNAME);
175229997Sken    }
176229997Sken    else {
177229997Sken	/* Start showing the package contents */
178276615Smav	if (!Quiet)
179229997Sken	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
180229997Sken	if (Flags & SHOW_COMMENT)
181229997Sken	    show_file("Comment:\n", COMMENT_FNAME);
182229997Sken	if (Flags & SHOW_REQUIRE)
183229997Sken	    show_plist("Depends on:\n", &plist, PLIST_PKGDEP);
184229997Sken	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
185229997Sken	    show_file("Required by:\n", REQUIRED_BY_FNAME);
186229997Sken	if (Flags & SHOW_DESC)
187229997Sken	    show_file("Description:\n", DESC_FNAME);
188229997Sken	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
189229997Sken	    show_file("Install notice:\n", DISPLAY_FNAME);
190229997Sken	if (Flags & SHOW_PLIST)
191229997Sken	    show_plist("Packing list:\n", &plist, (plist_t)-1);
192229997Sken	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
193229997Sken	    show_file("Install script:\n", INSTALL_FNAME);
194276615Smav	if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME))
195229997Sken	    show_file("Post-Install script:\n", POST_INSTALL_FNAME);
196229997Sken	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
197229997Sken	    show_file("De-Install script:\n", DEINSTALL_FNAME);
198229997Sken	if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME))
199229997Sken	    show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME);
200229997Sken	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
201229997Sken	    show_file("mtree file:\n", MTREE_FNAME);
202229997Sken	if (Flags & SHOW_PREFIX)
203229997Sken	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
204229997Sken	if (Flags & SHOW_FILES)
205229997Sken	    show_files("Files:\n", &plist);
206229997Sken	if ((Flags & SHOW_SIZE) && installed)
207229997Sken	    show_size("Package Size:\n", &plist);
208229997Sken	if ((Flags & SHOW_CKSUM) && installed)
209229997Sken	    show_cksum("Mismatched Checksums:\n", &plist);
210229997Sken	if (Flags & SHOW_ORIGIN)
211276615Smav	    show_origin("Origin:\n", &plist);
212229997Sken	if (!Quiet)
213229997Sken	    puts(InfoPrefix);
214229997Sken    }
215229997Sken    free_plist(&plist);
216229997Sken bail:
217229997Sken    leave_playpen();
218229997Sken    if (isTMP)
219229997Sken	unlink(fname);
220229997Sken    return code;
221229997Sken}
222229997Sken
223229997Skenvoid
224229997Skencleanup(int sig)
225229997Sken{
226229997Sken    static int in_cleanup = 0;
227276615Smav
228229997Sken    if (!in_cleanup) {
229229997Sken	in_cleanup = 1;
230229997Sken    	leave_playpen();
231229997Sken    }
232229997Sken    if (sig)
233229997Sken	exit(1);
234229997Sken}
235229997Sken
236229997Skenstatic int
237229997Skenfname_cmp(const FTSENT **a, const FTSENT **b)
238229997Sken{
239229997Sken    return strcmp((*a)->fts_name, (*b)->fts_name);
240229997Sken}
241229997Sken