perform.c revision 328
1#ifndef lint
2static const char *rcsid = "$Id: perform.c,v 1.7 1993/08/26 08:46:55 jkh Exp $";
3#endif
4
5/*
6 * FreeBSD install - a package for the installation and maintainance
7 * of non-core utilities.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * Jordan K. Hubbard
19 * 18 July 1993
20 *
21 * This is the main body of the add module.
22 *
23 */
24
25#include "lib.h"
26#include "add.h"
27
28#include <signal.h>
29
30static int pkg_do(char *);
31static char *find_name(Package *);
32static int sanity_check(char *);
33static char LogDir[FILENAME_MAX];
34
35
36int
37pkg_perform(char **pkgs)
38{
39    int i, err_cnt = 0;
40
41    signal(SIGINT, cleanup);
42    signal(SIGHUP, cleanup);
43
44    for (i = 0; pkgs[i]; i++)
45	err_cnt += pkg_do(pkgs[i]);
46    return err_cnt;
47}
48
49static Package Plist;
50
51/* This is seriously ugly code following.  Written very fast! */
52static int
53pkg_do(char *pkg)
54{
55    char pkg_fullname[FILENAME_MAX];
56    FILE *cfile;
57    char *home;
58    int code = 0;
59
60    /* Reset some state */
61    if (Plist.head)
62	free_plist(&Plist);
63    LogDir[0] = '\0';
64    home = make_playpen();
65    if (pkg[0] == '/')	/* full pathname? */
66	strcpy(pkg_fullname, pkg);
67    else
68	sprintf(pkg_fullname, "%s/%s", home, pkg);
69    if (!fexists(pkg_fullname)) {
70	whinge("Can't open package '%s'.", pkg_fullname);
71	return 1;
72    }
73
74    if (unpack(pkg_fullname, NULL))
75	return 1;
76
77    if (sanity_check(pkg_fullname))
78	return 1;
79
80    cfile = fopen(CONTENTS_FNAME, "r");
81    if (!cfile) {
82	whinge("Unable to open %s file.", CONTENTS_FNAME);
83	goto fail;
84    }
85    /* If we have a prefix, add it now */
86    if (Prefix)
87	add_plist(&Plist, PLIST_CWD, Prefix);
88    else
89	add_plist(&Plist, PLIST_CWD, home);
90    read_plist(&Plist, cfile);
91    fclose(cfile);
92    PkgName = find_name(&Plist);
93    if (fexists(REQUIRE_FNAME)) {
94	vsystem("chmod +x %s", REQUIRE_FNAME);	/* be sure */
95	if (Verbose)
96	    printf("Running requirements file first for %s..\n", PkgName);
97	if (vsystem("%s %s INSTALL", REQUIRE_FNAME, PkgName)) {
98	    whinge("Package %s fails requirements - not installed.",
99		   pkg_fullname);
100	    goto fail;
101	}
102    }
103    if (!NoInstall && fexists(INSTALL_FNAME)) {
104	vsystem("chmod +x %s", INSTALL_FNAME);	/* make sure */
105	if (Verbose)
106	    printf("Running install with PRE-INSTALL for %s..\n", PkgName);
107	if (vsystem("%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) {
108	    whinge("Install script returned error status.");
109	    goto fail;
110	}
111    }
112    extract_plist(home, &Plist);
113    if (!NoInstall && fexists(INSTALL_FNAME)) {
114	if (Verbose)
115	    printf("Running install with POST-INSTALL for %s..\n", PkgName);
116	if (vsystem("%s %s POST-INSTALL", INSTALL_FNAME, PkgName)) {
117	    whinge("Install script returned error status.");
118	    goto fail;
119	}
120    }
121    if (!NoRecord && !Fake) {
122	if (getuid() != 0)
123	    whinge("Not running as root - trying to record install anyway.");
124	if (!PkgName) {
125	    whinge("No package name!  Can't record package, sorry.");
126	    code = 1;
127	    goto success;	/* well, partial anyway */
128	}
129	sprintf(LogDir, "%s/%s", LOG_DIR, PkgName);
130	if (Verbose)
131	    printf("Attempting to record package into %s..\n", LogDir);
132	if (make_hierarchy(LogDir)) {
133	    whinge("Can't record package into '%s', you're on your own!",
134		   LogDir);
135	    bzero(LogDir, FILENAME_MAX);
136	    code = 1;
137	    goto success;	/* close enough for government work */
138	}
139	if (fexists(DEINSTALL_FNAME))
140	    copy_file(".", DEINSTALL_FNAME, LogDir);
141	if (fexists(REQUIRE_FNAME))
142	    copy_file(".", REQUIRE_FNAME, LogDir);
143	copy_file(".", CONTENTS_FNAME, LogDir);
144	copy_file(".", DESC_FNAME, LogDir);
145	copy_file(".", COMMENT_FNAME, LogDir);
146	if (Verbose)
147	    printf("Package %s registered in %s\n", PkgName, LogDir);
148    }
149    goto success;
150
151 fail:
152    /* Nuke the whole (installed) show */
153    if (!Fake)
154	delete_package(FALSE, &Plist);
155
156 success:
157    /* delete the packing list contents */
158    leave_playpen();
159
160    return code;
161}
162
163static int
164sanity_check(char *pkg)
165{
166    if (!fexists(CONTENTS_FNAME)) {
167	whinge("Package %s has no CONTENTS file!", pkg);
168	return 1;
169    }
170    if (!fexists(COMMENT_FNAME)) {
171	whinge("Package %s has no COMMENT file!", pkg);
172	return 1;
173    }
174    if (!fexists(DESC_FNAME)) {
175	whinge("Package %s has no DESC file!", pkg);
176	return 1;
177    }
178    return 0;
179}
180
181static char *
182find_name(Package *pkg)
183{
184    PackingList p = pkg->head;
185
186    while (p) {
187	if (p->type == PLIST_NAME)
188	    return p->name;
189	p = p->next;
190    }
191    return "anonymous";
192}
193
194void
195cleanup(int signo)
196{
197    if (Plist.head) {
198	if (!Fake)
199	    delete_package(FALSE, &Plist);
200	free_plist(&Plist);
201    }
202    if (!Fake && LogDir[0])
203	vsystem("%s -rf %s", REMOVE_CMD, LogDir);
204    leave_playpen();
205}
206