perform.c revision 3364
1327Sjkh#ifndef lint
23364Sjkhstatic const char *rcsid = "$Id: perform.c,v 1.6 1993/09/08 01:46:57 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;
63327Sjkh	}
64327Sjkh    }
65327Sjkh    for (i = 0; pkgs[i]; i++)
66327Sjkh	err_cnt += pkg_do(pkgs[i]);
67327Sjkh    return err_cnt;
68327Sjkh}
69327Sjkh
70327Sjkhstatic int
71327Sjkhpkg_do(char *pkg)
72327Sjkh{
73327Sjkh    Boolean installed = FALSE;
74327Sjkh    char log_dir[FILENAME_MAX];
75327Sjkh    char *home;
76327Sjkh    Package plist;
77327Sjkh    FILE *fp;
78327Sjkh
79327Sjkh    if (fexists(pkg)) {
80327Sjkh	char fname[FILENAME_MAX];
813364Sjkh	struct stat sb;
82327Sjkh
83327Sjkh	if (pkg[0] == '/')
84327Sjkh	    strcpy(fname, pkg);
85327Sjkh	else
86327Sjkh	    sprintf(fname, "%s/%s", home, pkg);
873364Sjkh	/*
883364Sjkh	 * Apply a crude heuristic to see how much space the package will
893364Sjkh	 * take up once it's unpacked.  I've noticed that most packages
903364Sjkh	 * compress an average of 65%.
913364Sjkh	 */
923364Sjkh	if (stat(fname, &sb) == FAIL) {
933364Sjkh	    whinge("Can't stat package file '%s'.", fname);
943364Sjkh	    return 1;
953364Sjkh	}
963364Sjkh	sb.st_size *= 1.65;
973364Sjkh	home = make_playpen(PlayPen, sb.st_size);
98327Sjkh	if (unpack(fname, "+*")) {
99327Sjkh	    whinge("Error during unpacking, no info for '%s' available.", pkg);
100327Sjkh	    return 1;
101327Sjkh	}
102327Sjkh    }
103327Sjkh    else {
104327Sjkh	sprintf(log_dir, "%s/%s", LOG_DIR, pkg);
105327Sjkh	if (!fexists(log_dir)) {
106327Sjkh	    whinge("Can't find package '%s' installed or in a file!", pkg);
107327Sjkh	    return 1;
108327Sjkh	}
109327Sjkh	if (chdir(log_dir) == FAIL) {
110327Sjkh	    whinge("Can't change directory to '%s'!", log_dir);
111327Sjkh	    return 1;
112327Sjkh	}
113327Sjkh	installed = TRUE;
114327Sjkh    }
115327Sjkh
116327Sjkh    /* Suck in the contents list */
117327Sjkh    plist.head = plist.tail = NULL;
118327Sjkh    fp = fopen(CONTENTS_FNAME, "r");
119327Sjkh    if (!fp) {
120327Sjkh	whinge("Unable to open %s file.", CONTENTS_FNAME);
121327Sjkh	return 1;
122327Sjkh    }
123327Sjkh    /* If we have a prefix, add it now */
124327Sjkh    read_plist(&plist, fp);
125327Sjkh    fclose(fp);
126327Sjkh
127327Sjkh    /*
128327Sjkh     * Index is special info type that has to override all others to make
129327Sjkh     * any sense.
130327Sjkh     */
131327Sjkh    if (Flags & SHOW_INDEX) {
132327Sjkh	char fname[FILENAME_MAX];
133327Sjkh
134327Sjkh	sprintf(fname, "%s\t", pkg);
135327Sjkh	show_file(fname, COMMENT_FNAME);
136327Sjkh    }
137327Sjkh    else {
138327Sjkh	/* Start showing the package contents */
139411Sjkh	if (!Quiet)
140411Sjkh	    printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
141327Sjkh	if (Flags & SHOW_COMMENT)
142379Sjkh	    show_file("Comment:\n", COMMENT_FNAME);
143327Sjkh	if (Flags & SHOW_DESC)
144379Sjkh	    show_file("Description:\n", DESC_FNAME);
145327Sjkh	if (Flags & SHOW_PLIST)
146379Sjkh	    show_plist("Packing list:\n", &plist, (plist_t)-1);
147327Sjkh	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
148379Sjkh	    show_file("Install script:\n", INSTALL_FNAME);
149327Sjkh	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
150379Sjkh	    show_file("De-Install script:\n", DEINSTALL_FNAME);
151327Sjkh	if (Flags & SHOW_PREFIX)
152379Sjkh	    show_plist("Prefix(s):\n", &plist, PLIST_CWD);
153411Sjkh	if (Flags & SHOW_FILES)
154411Sjkh	    show_files("Files:\n", &plist);
155411Sjkh	if (!Quiet)
156411Sjkh	    puts(InfoPrefix);
157327Sjkh    }
158327Sjkh    free_plist(&plist);
159327Sjkh    leave_playpen();
160327Sjkh    return 0;
161327Sjkh}
162327Sjkh
163327Sjkhvoid
164327Sjkhcleanup(int sig)
165327Sjkh{
166327Sjkh    leave_playpen();
167327Sjkh}
168