perform.c revision 11780
1327Sjkh#ifndef lint
211780Sjkhstatic const char *rcsid = "$Id: perform.c,v 1.17 1995/07/30 01:44:38 ache Exp $";
3327Sjkh#endif
4327Sjkh
5327Sjkh/*
6327Sjkh * FreeBSD install - a package for the installation and maintainance
7327Sjkh * of non-core utilities.
8327Sjkh *
9327Sjkh * Redistribution and use in source and binary forms, with or without
10327Sjkh * modification, are permitted provided that the following conditions
11327Sjkh * are met:
12327Sjkh * 1. Redistributions of source code must retain the above copyright
13327Sjkh *    notice, this list of conditions and the following disclaimer.
14327Sjkh * 2. Redistributions in binary form must reproduce the above copyright
15327Sjkh *    notice, this list of conditions and the following disclaimer in the
16327Sjkh *    documentation and/or other materials provided with the distribution.
17327Sjkh *
18327Sjkh * Jordan K. Hubbard
19327Sjkh * 23 Aug 1993
20327Sjkh *
21327Sjkh * This is the main body of the info module.
22327Sjkh *
23327Sjkh */
24327Sjkh
25327Sjkh#include "lib.h"
26327Sjkh#include "info.h"
27327Sjkh
28327Sjkh#include <signal.h>
29327Sjkh
30327Sjkhstatic int pkg_do(char *);
31327Sjkh
32327Sjkhint
33327Sjkhpkg_perform(char **pkgs)
34327Sjkh{
35327Sjkh    int i, err_cnt = 0;
367937Sjkh    char *tmp;
37327Sjkh
38327Sjkh    signal(SIGINT, cleanup);
39327Sjkh
407937Sjkh    tmp = getenv(PKG_DBDIR);
417937Sjkh    if (!tmp)
427937Sjkh	tmp = DEF_LOG_DIR;
43327Sjkh    /* Overriding action? */
44392Sjkh    if (AllInstalled || CheckPkg) {
457937Sjkh	if (isdir(tmp)) {
46327Sjkh	    DIR *dirp;
47327Sjkh	    struct dirent *dp;
48327Sjkh
497937Sjkh	    dirp = opendir(tmp);
50327Sjkh	    if (dirp) {
51327Sjkh		for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
52392Sjkh		    if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
53392Sjkh			if (CheckPkg) {
54392Sjkh			    if (!strcmp(dp->d_name, CheckPkg))
55392Sjkh				return 0;
56392Sjkh			}
578857Srgrimes			else
58392Sjkh			    err_cnt += pkg_do(dp->d_name);
59392Sjkh		    }
60327Sjkh		}
61327Sjkh		(void)closedir(dirp);
62392Sjkh		if (CheckPkg)
63392Sjkh		    return 1;
64327Sjkh	    }
65327Sjkh	    else
66327Sjkh		++err_cnt;
674996Sjkh	} else if (CheckPkg)
684996Sjkh	    return 1;			/* no dir -> not installed! */
698857Srgrimes
70327Sjkh    }
71327Sjkh    for (i = 0; pkgs[i]; i++)
72327Sjkh	err_cnt += pkg_do(pkgs[i]);
73327Sjkh    return err_cnt;
74327Sjkh}
75327Sjkh
7611780Sjkhstatic char *Home;
7711780Sjkh
78327Sjkhstatic int
79327Sjkhpkg_do(char *pkg)
80327Sjkh{
818086Sjkh    Boolean installed = FALSE, isTMP = FALSE;
82327Sjkh    char log_dir[FILENAME_MAX];
838086Sjkh    char fname[FILENAME_MAX];
84327Sjkh    Package plist;
85327Sjkh    FILE *fp;
868086Sjkh    struct stat sb;
878142Sjkh    char *cp = NULL;
888086Sjkh    int code = 0;
89327Sjkh
908086Sjkh    if (isURL(pkg)) {
9111780Sjkh	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
928086Sjkh	    strcpy(fname, cp);
938086Sjkh	    isTMP = TRUE;
948086Sjkh	}
958086Sjkh    }
969782Sache    else if (fexists(pkg) && isfile(pkg)) {
978086Sjkh	int len;
98327Sjkh
998423Sjkh	if (*pkg != '/') {
1008423Sjkh	    if (!getcwd(fname, FILENAME_MAX))
1018423Sjkh		upchuck("getcwd");
1028423Sjkh	    len = strlen(fname);
1038423Sjkh	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
1048423Sjkh	}
1058423Sjkh	else
1068423Sjkh	    strcpy(fname, pkg);
1078086Sjkh	cp = fname;
1088086Sjkh    }
1098086Sjkh    else {
11011780Sjkh	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
1118086Sjkh	    strncpy(fname, cp, FILENAME_MAX);
1128086Sjkh    }
1138086Sjkh    if (cp) {
1143364Sjkh	/*
1153364Sjkh	 * Apply a crude heuristic to see how much space the package will
1163364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
1173577Sjkh	 * compress an average of 75%, but we're only unpacking the + files so
1183577Sjkh	 * be very optimistic.
1193364Sjkh	 */
1203364Sjkh	if (stat(fname, &sb) == FAIL) {
1213364Sjkh	    whinge("Can't stat package file '%s'.", fname);
1228086Sjkh	    code = 1;
1238086Sjkh	    goto bail;
1243364Sjkh	}
12511780Sjkh	Home = make_playpen(PlayPen, sb.st_size / 2);
126327Sjkh	if (unpack(fname, "+*")) {
127327Sjkh	    whinge("Error during unpacking, no info for '%s' available.", pkg);
1288086Sjkh	    code = 1;
1298086Sjkh	    goto bail;
130327Sjkh	}
131327Sjkh    }
1328086Sjkh    /* It's not an ininstalled package, try and find it among the installed */
133327Sjkh    else {
1347937Sjkh	char *tmp;
1357937Sjkh
1367937Sjkh	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
1377937Sjkh		pkg);
138327Sjkh	if (!fexists(log_dir)) {
1398086Sjkh	    whinge("Can't find package `%s' installed or in a file!", pkg);
140327Sjkh	    return 1;
141327Sjkh	}
142327Sjkh	if (chdir(log_dir) == FAIL) {
143327Sjkh	    whinge("Can't change directory to '%s'!", log_dir);
144327Sjkh	    return 1;
145327Sjkh	}
146327Sjkh	installed = TRUE;
147327Sjkh    }
148327Sjkh
149327Sjkh    /* Suck in the contents list */
150327Sjkh    plist.head = plist.tail = NULL;
151327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
152327Sjkh    if (!fp) {
153327Sjkh	whinge("Unable to open %s file.", CONTENTS_FNAME);
1548086Sjkh	code = 1;
1558086Sjkh	goto bail;
156327Sjkh    }
157327Sjkh    /* If we have a prefix, add it now */
158327Sjkh    read_plist(&plist, fp);
159327Sjkh    fclose(fp);
160327Sjkh
161327Sjkh    /*
162327Sjkh     * Index is special info type that has to override all others to make
163327Sjkh     * any sense.
164327Sjkh     */
165327Sjkh    if (Flags & SHOW_INDEX) {
1668086Sjkh	char tmp[FILENAME_MAX];
167327Sjkh
1688086Sjkh	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
1698086Sjkh	show_index(tmp, COMMENT_FNAME);
170327Sjkh    }
171327Sjkh    else {
172327Sjkh	/* Start showing the package contents */
173411Sjkh	if (!Quiet)
174411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
175327Sjkh	if (Flags & SHOW_COMMENT)
176379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
1774996Sjkh	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
1784996Sjkh	    show_file("Required by:\n", REQUIRED_BY_FNAME);
179327Sjkh	if (Flags & SHOW_DESC)
180379Sjkh	    show_file("Description:\n", DESC_FNAME);
1814996Sjkh	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
1824996Sjkh	    show_file("Install notice:\n", DISPLAY_FNAME);
183327Sjkh	if (Flags & SHOW_PLIST)
184379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
185327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
186379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
187327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
188379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
1894996Sjkh	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
1904996Sjkh	    show_file("mtree file:\n", MTREE_FNAME);
191327Sjkh	if (Flags & SHOW_PREFIX)
192379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
193411Sjkh	if (Flags & SHOW_FILES)
194411Sjkh	    show_files("Files:\n", &plist);
195411Sjkh	if (!Quiet)
196411Sjkh	    puts(InfoPrefix);
197327Sjkh    }
198327Sjkh    free_plist(&plist);
1998086Sjkh bail:
20011780Sjkh    leave_playpen(Home);
2018086Sjkh    if (isTMP)
2028086Sjkh	unlink(fname);
2038086Sjkh    return code;
204327Sjkh}
205327Sjkh
206327Sjkhvoid
207327Sjkhcleanup(int sig)
208327Sjkh{
20911780Sjkh    leave_playpen(Home);
210327Sjkh}
211