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