perform.c revision 49300
1327Sjkh#ifndef lint
230221Scharnierstatic const char rcsid[] =
349300Sjdp	"$Id: perform.c,v 1.26 1998/12/16 13:59:31 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
2949300Sjdp#include <fts.h>
30327Sjkh#include <signal.h>
31327Sjkh
3249300Sjdpstatic int fname_cmp(const FTSENT **, const FTSENT **);
33327Sjkhstatic int pkg_do(char *);
34327Sjkh
35327Sjkhint
36327Sjkhpkg_perform(char **pkgs)
37327Sjkh{
38327Sjkh    int i, err_cnt = 0;
397937Sjkh    char *tmp;
40327Sjkh
41327Sjkh    signal(SIGINT, cleanup);
42327Sjkh
437937Sjkh    tmp = getenv(PKG_DBDIR);
447937Sjkh    if (!tmp)
457937Sjkh	tmp = DEF_LOG_DIR;
46327Sjkh    /* Overriding action? */
4716404Sjkh    if (CheckPkg) {
4816404Sjkh	char buf[FILENAME_MAX];
49327Sjkh
5016404Sjkh	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
5116404Sjkh	return abs(access(buf, R_OK));
5216404Sjkh    }
5316404Sjkh    else if (AllInstalled) {
5449300Sjdp	FTS *ftsp;
5549300Sjdp	FTSENT *f;
5649300Sjdp	char *paths[2];
578857Srgrimes
5816404Sjkh	if (!isdir(tmp))
5916404Sjkh	    return 1;
6049300Sjdp	paths[0] = tmp;
6149300Sjdp	paths[1] = NULL;
6249300Sjdp	ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT,
6349300Sjdp	  fname_cmp);
6449300Sjdp	if (ftsp != NULL) {
6549300Sjdp	    while ((f = fts_read(ftsp)) != NULL) {
6649300Sjdp		if (f->fts_info == FTS_D && f->fts_level == 1) {
6749300Sjdp		    err_cnt += pkg_do(f->fts_name);
6849300Sjdp		    fts_set(ftsp, f, FTS_SKIP);
6949300Sjdp		}
7049300Sjdp	    }
7149300Sjdp	    fts_close(ftsp);
7216404Sjkh	}
73327Sjkh    }
7416404Sjkh    else
7516404Sjkh	for (i = 0; pkgs[i]; i++)
7616404Sjkh	    err_cnt += pkg_do(pkgs[i]);
77327Sjkh    return err_cnt;
78327Sjkh}
79327Sjkh
8011780Sjkhstatic char *Home;
8111780Sjkh
82327Sjkhstatic int
83327Sjkhpkg_do(char *pkg)
84327Sjkh{
858086Sjkh    Boolean installed = FALSE, isTMP = FALSE;
86327Sjkh    char log_dir[FILENAME_MAX];
878086Sjkh    char fname[FILENAME_MAX];
88327Sjkh    Package plist;
89327Sjkh    FILE *fp;
908086Sjkh    struct stat sb;
918142Sjkh    char *cp = NULL;
928086Sjkh    int code = 0;
93327Sjkh
948086Sjkh    if (isURL(pkg)) {
9511780Sjkh	if ((cp = fileGetURL(NULL, pkg)) != NULL) {
968086Sjkh	    strcpy(fname, cp);
978086Sjkh	    isTMP = TRUE;
988086Sjkh	}
998086Sjkh    }
1009782Sache    else if (fexists(pkg) && isfile(pkg)) {
1018086Sjkh	int len;
102327Sjkh
1038423Sjkh	if (*pkg != '/') {
1048423Sjkh	    if (!getcwd(fname, FILENAME_MAX))
1058423Sjkh		upchuck("getcwd");
1068423Sjkh	    len = strlen(fname);
1078423Sjkh	    snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg);
1088423Sjkh	}
1098423Sjkh	else
1108423Sjkh	    strcpy(fname, pkg);
1118086Sjkh	cp = fname;
1128086Sjkh    }
1138086Sjkh    else {
11411780Sjkh	if ((cp = fileFindByPath(NULL, pkg)) != NULL)
1158086Sjkh	    strncpy(fname, cp, FILENAME_MAX);
1168086Sjkh    }
1178086Sjkh    if (cp) {
1183364Sjkh	/*
1193364Sjkh	 * Apply a crude heuristic to see how much space the package will
1203364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
1213577Sjkh	 * compress an average of 75%, but we're only unpacking the + files so
1223577Sjkh	 * be very optimistic.
1233364Sjkh	 */
1243364Sjkh	if (stat(fname, &sb) == FAIL) {
12530221Scharnier	    warnx("can't stat package file '%s'", fname);
1268086Sjkh	    code = 1;
1278086Sjkh	    goto bail;
1283364Sjkh	}
12911780Sjkh	Home = make_playpen(PlayPen, sb.st_size / 2);
130327Sjkh	if (unpack(fname, "+*")) {
13130221Scharnier	    warnx("error during unpacking, no info for '%s' available", pkg);
1328086Sjkh	    code = 1;
1338086Sjkh	    goto bail;
134327Sjkh	}
135327Sjkh    }
1368086Sjkh    /* It's not an ininstalled package, try and find it among the installed */
137327Sjkh    else {
1387937Sjkh	char *tmp;
1397937Sjkh
1407937Sjkh	sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
1417937Sjkh		pkg);
142327Sjkh	if (!fexists(log_dir)) {
14330221Scharnier	    warnx("can't find package `%s' installed or in a file!", pkg);
144327Sjkh	    return 1;
145327Sjkh	}
146327Sjkh	if (chdir(log_dir) == FAIL) {
14730221Scharnier	    warnx("can't change directory to '%s'!", log_dir);
148327Sjkh	    return 1;
149327Sjkh	}
150327Sjkh	installed = TRUE;
151327Sjkh    }
152327Sjkh
153327Sjkh    /* Suck in the contents list */
154327Sjkh    plist.head = plist.tail = NULL;
155327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
156327Sjkh    if (!fp) {
15730221Scharnier	warnx("unable to open %s file", CONTENTS_FNAME);
1588086Sjkh	code = 1;
1598086Sjkh	goto bail;
160327Sjkh    }
161327Sjkh    /* If we have a prefix, add it now */
162327Sjkh    read_plist(&plist, fp);
163327Sjkh    fclose(fp);
164327Sjkh
165327Sjkh    /*
166327Sjkh     * Index is special info type that has to override all others to make
167327Sjkh     * any sense.
168327Sjkh     */
169327Sjkh    if (Flags & SHOW_INDEX) {
1708086Sjkh	char tmp[FILENAME_MAX];
171327Sjkh
1728086Sjkh	snprintf(tmp, FILENAME_MAX, "%-19s ", pkg);
1738086Sjkh	show_index(tmp, COMMENT_FNAME);
174327Sjkh    }
175327Sjkh    else {
176327Sjkh	/* Start showing the package contents */
177411Sjkh	if (!Quiet)
178411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
179327Sjkh	if (Flags & SHOW_COMMENT)
180379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
1814996Sjkh	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
1824996Sjkh	    show_file("Required by:\n", REQUIRED_BY_FNAME);
183327Sjkh	if (Flags & SHOW_DESC)
184379Sjkh	    show_file("Description:\n", DESC_FNAME);
1854996Sjkh	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
1864996Sjkh	    show_file("Install notice:\n", DISPLAY_FNAME);
187327Sjkh	if (Flags & SHOW_PLIST)
188379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
189327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
190379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
19141866Sjkh	if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME))
19241866Sjkh	    show_file("Post-Install script:\n", POST_INSTALL_FNAME);
193327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
194379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
19541866Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME))
19641866Sjkh	    show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME);
1974996Sjkh	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
1984996Sjkh	    show_file("mtree file:\n", MTREE_FNAME);
199327Sjkh	if (Flags & SHOW_PREFIX)
200379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
201411Sjkh	if (Flags & SHOW_FILES)
202411Sjkh	    show_files("Files:\n", &plist);
203411Sjkh	if (!Quiet)
204411Sjkh	    puts(InfoPrefix);
205327Sjkh    }
206327Sjkh    free_plist(&plist);
2078086Sjkh bail:
20833427Sjkh    leave_playpen();
2098086Sjkh    if (isTMP)
2108086Sjkh	unlink(fname);
2118086Sjkh    return code;
212327Sjkh}
213327Sjkh
214327Sjkhvoid
215327Sjkhcleanup(int sig)
216327Sjkh{
21733427Sjkh    static int in_cleanup = 0;
21833427Sjkh
21933427Sjkh    if (!in_cleanup) {
22033427Sjkh	in_cleanup = 1;
22133427Sjkh    	leave_playpen();
22233427Sjkh    }
22339068Sjkh    if (sig)
22439068Sjkh	exit(1);
225327Sjkh}
22649300Sjdp
22749300Sjdpstatic int
22849300Sjdpfname_cmp(const FTSENT **a, const FTSENT **b)
22949300Sjdp{
23049300Sjdp    return strcmp((*a)->fts_name, (*b)->fts_name);
23149300Sjdp}
232