perform.c revision 39068
1#ifndef lint
2static const char rcsid[] =
3	"$Id: perform.c,v 1.24 1998/02/16 17:16:38 jkh Exp $";
4#endif
5
6/*
7 * FreeBSD install - a package for the installation and maintainance
8 * of non-core utilities.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * Jordan K. Hubbard
20 * 23 Aug 1993
21 *
22 * This is the main body of the info module.
23 *
24 */
25
26#include "lib.h"
27#include "info.h"
28
29#include <signal.h>
30
31static int pkg_do(char *);
32
33int
34pkg_perform(char **pkgs)
35{
36    int i, err_cnt = 0;
37    char *tmp;
38
39    signal(SIGINT, cleanup);
40
41    tmp = getenv(PKG_DBDIR);
42    if (!tmp)
43	tmp = DEF_LOG_DIR;
44    /* Overriding action? */
45    if (CheckPkg) {
46	char buf[FILENAME_MAX];
47
48	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
49	return abs(access(buf, R_OK));
50    }
51    else if (AllInstalled) {
52	DIR *dirp;
53	struct dirent *dp;
54
55	if (!isdir(tmp))
56	    return 1;
57	dirp = opendir(tmp);
58	if (dirp) {
59	    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
60		if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
61		    err_cnt += pkg_do(dp->d_name);
62	    (void)closedir(dirp);
63	}
64    }
65    else
66	for (i = 0; pkgs[i]; i++)
67	    err_cnt += pkg_do(pkgs[i]);
68    return err_cnt;
69}
70
71static char *Home;
72
73static int
74pkg_do(char *pkg)
75{
76    Boolean installed = FALSE, isTMP = FALSE;
77    char log_dir[FILENAME_MAX];
78    char fname[FILENAME_MAX];
79    Package plist;
80    FILE *fp;
81    struct stat sb;
82    char *cp = NULL;
83    int code = 0;
84
85    if (isURL(pkg)) {
86	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
87	    strcpy(fname, cp);
88	    isTMP = TRUE;
89	}
90    }
91    else if (fexists(pkg) && isfile(pkg)) {
92	int len;
93
94	if (*pkg != '/') {
95	    if (!getcwd(fname, FILENAME_MAX))
96		upchuck("getcwd");
97	    len = strlen(fname);
98	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
99	}
100	else
101	    strcpy(fname, pkg);
102	cp = fname;
103    }
104    else {
105	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
106	    strncpy(fname, cp, FILENAME_MAX);
107    }
108    if (cp) {
109	/*
110	 * Apply a crude heuristic to see how much space the package will
111	 * take up once it's unpacked.  I've noticed that most packages
112	 * compress an average of 75%, but we're only unpacking the + files so
113	 * be very optimistic.
114	 */
115	if (stat(fname, &sb) == FAIL) {
116	    warnx("can't stat package file '%s'", fname);
117	    code = 1;
118	    goto bail;
119	}
120	Home = make_playpen(PlayPen, sb.st_size / 2);
121	if (unpack(fname, "+*")) {
122	    warnx("error during unpacking, no info for '%s' available", pkg);
123	    code = 1;
124	    goto bail;
125	}
126    }
127    /* It's not an ininstalled package, try and find it among the installed */
128    else {
129	char *tmp;
130
131	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
132		pkg);
133	if (!fexists(log_dir)) {
134	    warnx("can't find package `%s' installed or in a file!", pkg);
135	    return 1;
136	}
137	if (chdir(log_dir) == FAIL) {
138	    warnx("can't change directory to '%s'!", log_dir);
139	    return 1;
140	}
141	installed = TRUE;
142    }
143
144    /* Suck in the contents list */
145    plist.head = plist.tail = NULL;
146    fp = fopen(CONTENTS_FNAME, "r");
147    if (!fp) {
148	warnx("unable to open %s file", CONTENTS_FNAME);
149	code = 1;
150	goto bail;
151    }
152    /* If we have a prefix, add it now */
153    read_plist(&plist, fp);
154    fclose(fp);
155
156    /*
157     * Index is special info type that has to override all others to make
158     * any sense.
159     */
160    if (Flags & SHOW_INDEX) {
161	char tmp[FILENAME_MAX];
162
163	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
164	show_index(tmp, COMMENT_FNAME);
165    }
166    else {
167	/* Start showing the package contents */
168	if (!Quiet)
169	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
170	if (Flags & SHOW_COMMENT)
171	    show_file("Comment:\n", COMMENT_FNAME);
172	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
173	    show_file("Required by:\n", REQUIRED_BY_FNAME);
174	if (Flags & SHOW_DESC)
175	    show_file("Description:\n", DESC_FNAME);
176	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
177	    show_file("Install notice:\n", DISPLAY_FNAME);
178	if (Flags & SHOW_PLIST)
179	    show_plist("Packing list:\n", &plist, (plist_t)-1);
180	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
181	    show_file("Install script:\n", INSTALL_FNAME);
182	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
183	    show_file("De-Install script:\n", DEINSTALL_FNAME);
184	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
185	    show_file("mtree file:\n", MTREE_FNAME);
186	if (Flags & SHOW_PREFIX)
187	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
188	if (Flags & SHOW_FILES)
189	    show_files("Files:\n", &plist);
190	if (!Quiet)
191	    puts(InfoPrefix);
192    }
193    free_plist(&plist);
194 bail:
195    leave_playpen();
196    if (isTMP)
197	unlink(fname);
198    return code;
199}
200
201void
202cleanup(int sig)
203{
204    static int in_cleanup = 0;
205
206    if (!in_cleanup) {
207	in_cleanup = 1;
208    	leave_playpen();
209    }
210    if (sig)
211	exit(1);
212}
213