perform.c revision 8423
1#ifndef lint
2static const char *rcsid = "$Id: perform.c,v 1.14 1995/04/28 18:24: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 (AllInstalled || CheckPkg) {
45	if (isdir(tmp)) {
46	    DIR *dirp;
47	    struct dirent *dp;
48
49	    dirp = opendir(tmp);
50	    if (dirp) {
51		for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
52		    if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
53			if (CheckPkg) {
54			    if (!strcmp(dp->d_name, CheckPkg))
55				return 0;
56			}
57			else
58			    err_cnt += pkg_do(dp->d_name);
59		    }
60		}
61		(void)closedir(dirp);
62		if (CheckPkg)
63		    return 1;
64	    }
65	    else
66		++err_cnt;
67	} else if (CheckPkg)
68	    return 1;			/* no dir -> not installed! */
69
70    }
71    for (i = 0; pkgs[i]; i++)
72	err_cnt += pkg_do(pkgs[i]);
73    return err_cnt;
74}
75
76static int
77pkg_do(char *pkg)
78{
79    Boolean installed = FALSE, isTMP = FALSE;
80    char log_dir[FILENAME_MAX];
81    char fname[FILENAME_MAX];
82    Package plist;
83    FILE *fp;
84    struct stat sb;
85    char *cp = NULL;
86    int code = 0;
87
88    if (isURL(pkg)) {
89	if ((cp = fileGetURL(pkg)) != NULL) {
90	    strcpy(fname, cp);
91	    isTMP = TRUE;
92	}
93    }
94    else if (fexists(pkg)) {
95	int len;
96
97	if (*pkg != '/') {
98	    if (!getcwd(fname, FILENAME_MAX))
99		upchuck("getcwd");
100	    len = strlen(fname);
101	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
102	}
103	else
104	    strcpy(fname, pkg);
105	cp = fname;
106    }
107    else {
108	if ((cp = fileFindByPath(pkg)) != NULL)
109	    strncpy(fname, cp, FILENAME_MAX);
110    }
111    if (cp) {
112	/*
113	 * Apply a crude heuristic to see how much space the package will
114	 * take up once it's unpacked.  I've noticed that most packages
115	 * compress an average of 75%, but we're only unpacking the + files so
116	 * be very optimistic.
117	 */
118	if (stat(fname, &sb) == FAIL) {
119	    whinge("Can't stat package file '%s'.", fname);
120	    code = 1;
121	    goto bail;
122	}
123	(void)make_playpen(PlayPen, sb.st_size / 2);
124	if (unpack(fname, "+*")) {
125	    whinge("Error during unpacking, no info for '%s' available.", pkg);
126	    code = 1;
127	    goto bail;
128	}
129    }
130    /* It's not an ininstalled package, try and find it among the installed */
131    else {
132	char *tmp;
133
134	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
135		pkg);
136	if (!fexists(log_dir)) {
137	    whinge("Can't find package `%s' installed or in a file!", pkg);
138	    return 1;
139	}
140	if (chdir(log_dir) == FAIL) {
141	    whinge("Can't change directory to '%s'!", log_dir);
142	    return 1;
143	}
144	installed = TRUE;
145    }
146
147    /* Suck in the contents list */
148    plist.head = plist.tail = NULL;
149    fp = fopen(CONTENTS_FNAME, "r");
150    if (!fp) {
151	whinge("Unable to open %s file.", CONTENTS_FNAME);
152	code = 1;
153	goto bail;
154    }
155    /* If we have a prefix, add it now */
156    read_plist(&plist, fp);
157    fclose(fp);
158
159    /*
160     * Index is special info type that has to override all others to make
161     * any sense.
162     */
163    if (Flags & SHOW_INDEX) {
164	char tmp[FILENAME_MAX];
165
166	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
167	show_index(tmp, COMMENT_FNAME);
168    }
169    else {
170	/* Start showing the package contents */
171	if (!Quiet)
172	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
173	if (Flags & SHOW_COMMENT)
174	    show_file("Comment:\n", COMMENT_FNAME);
175	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
176	    show_file("Required by:\n", REQUIRED_BY_FNAME);
177	if (Flags & SHOW_DESC)
178	    show_file("Description:\n", DESC_FNAME);
179	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
180	    show_file("Install notice:\n", DISPLAY_FNAME);
181	if (Flags & SHOW_PLIST)
182	    show_plist("Packing list:\n", &plist, (plist_t)-1);
183	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
184	    show_file("Install script:\n", INSTALL_FNAME);
185	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
186	    show_file("De-Install script:\n", DEINSTALL_FNAME);
187	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
188	    show_file("mtree file:\n", MTREE_FNAME);
189	if (Flags & SHOW_PREFIX)
190	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
191	if (Flags & SHOW_FILES)
192	    show_files("Files:\n", &plist);
193	if (!Quiet)
194	    puts(InfoPrefix);
195    }
196    free_plist(&plist);
197 bail:
198    leave_playpen();
199    if (isTMP)
200	unlink(fname);
201    return code;
202}
203
204void
205cleanup(int sig)
206{
207    leave_playpen();
208}
209