perform.c revision 41866
1327Sjkh#ifndef lint
230221Scharnierstatic const char rcsid[] =
341866Sjkh	"$Id: perform.c,v 1.25 1998/09/11 07:26:58 jkh Exp $";
4327Sjkh#endif
5327Sjkh
6327Sjkh/*
7327Sjkh * FreeBSD install - a package for the installation and maintainance
8327Sjkh * of non-core utilities.
9327Sjkh *
10327Sjkh * Redistribution and use in source and binary forms, with or without
11327Sjkh * modification, are permitted provided that the following conditions
12327Sjkh * are met:
13327Sjkh * 1. Redistributions of source code must retain the above copyright
14327Sjkh *    notice, this list of conditions and the following disclaimer.
15327Sjkh * 2. Redistributions in binary form must reproduce the above copyright
16327Sjkh *    notice, this list of conditions and the following disclaimer in the
17327Sjkh *    documentation and/or other materials provided with the distribution.
18327Sjkh *
19327Sjkh * Jordan K. Hubbard
20327Sjkh * 23 Aug 1993
21327Sjkh *
22327Sjkh * This is the main body of the info module.
23327Sjkh *
24327Sjkh */
25327Sjkh
26327Sjkh#include "lib.h"
27327Sjkh#include "info.h"
28327Sjkh
29327Sjkh#include <signal.h>
30327Sjkh
31327Sjkhstatic int pkg_do(char *);
32327Sjkh
33327Sjkhint
34327Sjkhpkg_perform(char **pkgs)
35327Sjkh{
36327Sjkh    int i, err_cnt = 0;
377937Sjkh    char *tmp;
38327Sjkh
39327Sjkh    signal(SIGINT, cleanup);
40327Sjkh
417937Sjkh    tmp = getenv(PKG_DBDIR);
427937Sjkh    if (!tmp)
437937Sjkh	tmp = DEF_LOG_DIR;
44327Sjkh    /* Overriding action? */
4516404Sjkh    if (CheckPkg) {
4616404Sjkh	char buf[FILENAME_MAX];
47327Sjkh
4816404Sjkh	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
4916404Sjkh	return abs(access(buf, R_OK));
5016404Sjkh    }
5116404Sjkh    else if (AllInstalled) {
5216404Sjkh	DIR *dirp;
5316404Sjkh	struct dirent *dp;
548857Srgrimes
5516404Sjkh	if (!isdir(tmp))
5616404Sjkh	    return 1;
5716404Sjkh	dirp = opendir(tmp);
5816404Sjkh	if (dirp) {
5916404Sjkh	    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
6016404Sjkh		if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
6116404Sjkh		    err_cnt += pkg_do(dp->d_name);
6216404Sjkh	    (void)closedir(dirp);
6316404Sjkh	}
64327Sjkh    }
6516404Sjkh    else
6616404Sjkh	for (i = 0; pkgs[i]; i++)
6716404Sjkh	    err_cnt += pkg_do(pkgs[i]);
68327Sjkh    return err_cnt;
69327Sjkh}
70327Sjkh
7111780Sjkhstatic char *Home;
7211780Sjkh
73327Sjkhstatic int
74327Sjkhpkg_do(char *pkg)
75327Sjkh{
768086Sjkh    Boolean installed = FALSE, isTMP = FALSE;
77327Sjkh    char log_dir[FILENAME_MAX];
788086Sjkh    char fname[FILENAME_MAX];
79327Sjkh    Package plist;
80327Sjkh    FILE *fp;
818086Sjkh    struct stat sb;
828142Sjkh    char *cp = NULL;
838086Sjkh    int code = 0;
84327Sjkh
858086Sjkh    if (isURL(pkg)) {
8611780Sjkh	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
878086Sjkh	    strcpy(fname, cp);
888086Sjkh	    isTMP = TRUE;
898086Sjkh	}
908086Sjkh    }
919782Sache    else if (fexists(pkg) && isfile(pkg)) {
928086Sjkh	int len;
93327Sjkh
948423Sjkh	if (*pkg != '/') {
958423Sjkh	    if (!getcwd(fname, FILENAME_MAX))
968423Sjkh		upchuck("getcwd");
978423Sjkh	    len = strlen(fname);
988423Sjkh	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
998423Sjkh	}
1008423Sjkh	else
1018423Sjkh	    strcpy(fname, pkg);
1028086Sjkh	cp = fname;
1038086Sjkh    }
1048086Sjkh    else {
10511780Sjkh	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
1068086Sjkh	    strncpy(fname, cp, FILENAME_MAX);
1078086Sjkh    }
1088086Sjkh    if (cp) {
1093364Sjkh	/*
1103364Sjkh	 * Apply a crude heuristic to see how much space the package will
1113364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
1123577Sjkh	 * compress an average of 75%, but we're only unpacking the + files so
1133577Sjkh	 * be very optimistic.
1143364Sjkh	 */
1153364Sjkh	if (stat(fname, &sb) == FAIL) {
11630221Scharnier	    warnx("can't stat package file '%s'", fname);
1178086Sjkh	    code = 1;
1188086Sjkh	    goto bail;
1193364Sjkh	}
12011780Sjkh	Home = make_playpen(PlayPen, sb.st_size / 2);
121327Sjkh	if (unpack(fname, "+*")) {
12230221Scharnier	    warnx("error during unpacking, no info for '%s' available", pkg);
1238086Sjkh	    code = 1;
1248086Sjkh	    goto bail;
125327Sjkh	}
126327Sjkh    }
1278086Sjkh    /* It's not an ininstalled package, try and find it among the installed */
128327Sjkh    else {
1297937Sjkh	char *tmp;
1307937Sjkh
1317937Sjkh	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
1327937Sjkh		pkg);
133327Sjkh	if (!fexists(log_dir)) {
13430221Scharnier	    warnx("can't find package `%s' installed or in a file!", pkg);
135327Sjkh	    return 1;
136327Sjkh	}
137327Sjkh	if (chdir(log_dir) == FAIL) {
13830221Scharnier	    warnx("can't change directory to '%s'!", log_dir);
139327Sjkh	    return 1;
140327Sjkh	}
141327Sjkh	installed = TRUE;
142327Sjkh    }
143327Sjkh
144327Sjkh    /* Suck in the contents list */
145327Sjkh    plist.head = plist.tail = NULL;
146327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
147327Sjkh    if (!fp) {
14830221Scharnier	warnx("unable to open %s file", CONTENTS_FNAME);
1498086Sjkh	code = 1;
1508086Sjkh	goto bail;
151327Sjkh    }
152327Sjkh    /* If we have a prefix, add it now */
153327Sjkh    read_plist(&plist, fp);
154327Sjkh    fclose(fp);
155327Sjkh
156327Sjkh    /*
157327Sjkh     * Index is special info type that has to override all others to make
158327Sjkh     * any sense.
159327Sjkh     */
160327Sjkh    if (Flags & SHOW_INDEX) {
1618086Sjkh	char tmp[FILENAME_MAX];
162327Sjkh
1638086Sjkh	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
1648086Sjkh	show_index(tmp, COMMENT_FNAME);
165327Sjkh    }
166327Sjkh    else {
167327Sjkh	/* Start showing the package contents */
168411Sjkh	if (!Quiet)
169411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
170327Sjkh	if (Flags & SHOW_COMMENT)
171379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
1724996Sjkh	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
1734996Sjkh	    show_file("Required by:\n", REQUIRED_BY_FNAME);
174327Sjkh	if (Flags & SHOW_DESC)
175379Sjkh	    show_file("Description:\n", DESC_FNAME);
1764996Sjkh	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
1774996Sjkh	    show_file("Install notice:\n", DISPLAY_FNAME);
178327Sjkh	if (Flags & SHOW_PLIST)
179379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
180327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
181379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
18241866Sjkh	if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME))
18341866Sjkh	    show_file("Post-Install script:\n", POST_INSTALL_FNAME);
184327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
185379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
18641866Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME))
18741866Sjkh	    show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME);
1884996Sjkh	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
1894996Sjkh	    show_file("mtree file:\n", MTREE_FNAME);
190327Sjkh	if (Flags & SHOW_PREFIX)
191379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
192411Sjkh	if (Flags & SHOW_FILES)
193411Sjkh	    show_files("Files:\n", &plist);
194411Sjkh	if (!Quiet)
195411Sjkh	    puts(InfoPrefix);
196327Sjkh    }
197327Sjkh    free_plist(&plist);
1988086Sjkh bail:
19933427Sjkh    leave_playpen();
2008086Sjkh    if (isTMP)
2018086Sjkh	unlink(fname);
2028086Sjkh    return code;
203327Sjkh}
204327Sjkh
205327Sjkhvoid
206327Sjkhcleanup(int sig)
207327Sjkh{
20833427Sjkh    static int in_cleanup = 0;
20933427Sjkh
21033427Sjkh    if (!in_cleanup) {
21133427Sjkh	in_cleanup = 1;
21233427Sjkh    	leave_playpen();
21333427Sjkh    }
21439068Sjkh    if (sig)
21539068Sjkh	exit(1);
216327Sjkh}
217