perform.c revision 4996
1327Sjkh#ifndef lint
24996Sjkhstatic const char *rcsid = "$Id: perform.c,v 1.9 1994/10/14 05:57:49 jkh 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;
36327Sjkh
37327Sjkh    signal(SIGINT, cleanup);
38327Sjkh
39327Sjkh    /* Overriding action? */
40392Sjkh    if (AllInstalled || CheckPkg) {
41327Sjkh	if (isdir(LOG_DIR)) {
42327Sjkh	    DIR *dirp;
43327Sjkh	    struct dirent *dp;
44327Sjkh
45327Sjkh	    dirp = opendir(LOG_DIR);
46327Sjkh	    if (dirp) {
47327Sjkh		for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
48392Sjkh		    if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
49392Sjkh			if (CheckPkg) {
50392Sjkh			    if (!strcmp(dp->d_name, CheckPkg))
51392Sjkh				return 0;
52392Sjkh			}
53392Sjkh			else
54392Sjkh			    err_cnt += pkg_do(dp->d_name);
55392Sjkh		    }
56327Sjkh		}
57327Sjkh		(void)closedir(dirp);
58392Sjkh		if (CheckPkg)
59392Sjkh		    return 1;
60327Sjkh	    }
61327Sjkh	    else
62327Sjkh		++err_cnt;
634996Sjkh	} else if (CheckPkg)
644996Sjkh	    return 1;			/* no dir -> not installed! */
654996Sjkh
66327Sjkh    }
67327Sjkh    for (i = 0; pkgs[i]; i++)
68327Sjkh	err_cnt += pkg_do(pkgs[i]);
69327Sjkh    return err_cnt;
70327Sjkh}
71327Sjkh
72327Sjkhstatic int
73327Sjkhpkg_do(char *pkg)
74327Sjkh{
75327Sjkh    Boolean installed = FALSE;
76327Sjkh    char log_dir[FILENAME_MAX];
773577Sjkh    char home[FILENAME_MAX];
78327Sjkh    Package plist;
79327Sjkh    FILE *fp;
80327Sjkh
81327Sjkh    if (fexists(pkg)) {
82327Sjkh	char fname[FILENAME_MAX];
833364Sjkh	struct stat sb;
84327Sjkh
853577Sjkh	if (!getcwd(home, FILENAME_MAX))
863577Sjkh	    upchuck("getcwd");
873577Sjkh
88327Sjkh	if (pkg[0] == '/')
89327Sjkh	    strcpy(fname, pkg);
90327Sjkh	else
91327Sjkh	    sprintf(fname, "%s/%s", home, pkg);
923364Sjkh	/*
933364Sjkh	 * Apply a crude heuristic to see how much space the package will
943364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
953577Sjkh	 * compress an average of 75%, but we're only unpacking the + files so
963577Sjkh	 * be very optimistic.
973364Sjkh	 */
983364Sjkh	if (stat(fname, &sb) == FAIL) {
993364Sjkh	    whinge("Can't stat package file '%s'.", fname);
1003364Sjkh	    return 1;
1013364Sjkh	}
1023579Sjkh	(void)make_playpen(PlayPen, sb.st_size / 2);
103327Sjkh	if (unpack(fname, "+*")) {
104327Sjkh	    whinge("Error during unpacking, no info for '%s' available.", pkg);
105327Sjkh	    return 1;
106327Sjkh	}
107327Sjkh    }
108327Sjkh    else {
109327Sjkh	sprintf(log_dir, "%s/%s", LOG_DIR, pkg);
110327Sjkh	if (!fexists(log_dir)) {
111327Sjkh	    whinge("Can't find package '%s' installed or in a file!", pkg);
112327Sjkh	    return 1;
113327Sjkh	}
114327Sjkh	if (chdir(log_dir) == FAIL) {
115327Sjkh	    whinge("Can't change directory to '%s'!", log_dir);
116327Sjkh	    return 1;
117327Sjkh	}
118327Sjkh	installed = TRUE;
119327Sjkh    }
120327Sjkh
121327Sjkh    /* Suck in the contents list */
122327Sjkh    plist.head = plist.tail = NULL;
123327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
124327Sjkh    if (!fp) {
125327Sjkh	whinge("Unable to open %s file.", CONTENTS_FNAME);
126327Sjkh	return 1;
127327Sjkh    }
128327Sjkh    /* If we have a prefix, add it now */
129327Sjkh    read_plist(&plist, fp);
130327Sjkh    fclose(fp);
131327Sjkh
132327Sjkh    /*
133327Sjkh     * Index is special info type that has to override all others to make
134327Sjkh     * any sense.
135327Sjkh     */
136327Sjkh    if (Flags & SHOW_INDEX) {
137327Sjkh	char fname[FILENAME_MAX];
138327Sjkh
139327Sjkh	sprintf(fname, "%s\t", pkg);
140327Sjkh	show_file(fname, COMMENT_FNAME);
141327Sjkh    }
142327Sjkh    else {
143327Sjkh	/* Start showing the package contents */
144411Sjkh	if (!Quiet)
145411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
146327Sjkh	if (Flags & SHOW_COMMENT)
147379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
1484996Sjkh	if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
1494996Sjkh	    show_file("Required by:\n", REQUIRED_BY_FNAME);
150327Sjkh	if (Flags & SHOW_DESC)
151379Sjkh	    show_file("Description:\n", DESC_FNAME);
1524996Sjkh	if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
1534996Sjkh	    show_file("Install notice:\n", DISPLAY_FNAME);
154327Sjkh	if (Flags & SHOW_PLIST)
155379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
156327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
157379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
158327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
159379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
1604996Sjkh	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
1614996Sjkh	    show_file("mtree file:\n", MTREE_FNAME);
162327Sjkh	if (Flags & SHOW_PREFIX)
163379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
164411Sjkh	if (Flags & SHOW_FILES)
165411Sjkh	    show_files("Files:\n", &plist);
166411Sjkh	if (!Quiet)
167411Sjkh	    puts(InfoPrefix);
168327Sjkh    }
169327Sjkh    free_plist(&plist);
170327Sjkh    leave_playpen();
171327Sjkh    return 0;
172327Sjkh}
173327Sjkh
174327Sjkhvoid
175327Sjkhcleanup(int sig)
176327Sjkh{
177327Sjkh    leave_playpen();
178327Sjkh}
179