perform.c revision 327
1327Sjkh#ifndef lint
2327Sjkhstatic const char *rcsid = "$Id: perform.c,v 1.7 1993/08/26 08:46:55 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 * 18 July 1993
20327Sjkh *
21327Sjkh * This is the main body of the add module.
22327Sjkh *
23327Sjkh */
24327Sjkh
25327Sjkh#include "lib.h"
26327Sjkh#include "add.h"
27327Sjkh
28327Sjkh#include <signal.h>
29327Sjkh
30327Sjkhstatic int pkg_do(char *);
31327Sjkhstatic char *find_name(Package *);
32327Sjkhstatic int sanity_check(char *);
33327Sjkhstatic char LogDir[FILENAME_MAX];
34327Sjkh
35327Sjkh
36327Sjkhint
37327Sjkhpkg_perform(char **pkgs)
38327Sjkh{
39327Sjkh    int i, err_cnt = 0;
40327Sjkh
41327Sjkh    signal(SIGINT, cleanup);
42327Sjkh    signal(SIGHUP, cleanup);
43327Sjkh
44327Sjkh    for (i = 0; pkgs[i]; i++)
45327Sjkh	err_cnt += pkg_do(pkgs[i]);
46327Sjkh    return err_cnt;
47327Sjkh}
48327Sjkh
49327Sjkhstatic Package Plist;
50327Sjkh
51327Sjkh/* This is seriously ugly code following.  Written very fast! */
52327Sjkhstatic int
53327Sjkhpkg_do(char *pkg)
54327Sjkh{
55327Sjkh    char pkg_fullname[FILENAME_MAX];
56327Sjkh    FILE *cfile;
57327Sjkh    char *home;
58327Sjkh    int code = 0;
59327Sjkh
60327Sjkh    /* Reset some state */
61327Sjkh    if (Plist.head)
62327Sjkh	free_plist(&Plist);
63327Sjkh    LogDir[0] = '\0';
64327Sjkh    home = make_playpen();
65327Sjkh    if (pkg[0] == '/')	/* full pathname? */
66327Sjkh	strcpy(pkg_fullname, pkg);
67327Sjkh    else
68327Sjkh	sprintf(pkg_fullname, "%s/%s", home, pkg);
69327Sjkh    if (!fexists(pkg_fullname)) {
70327Sjkh	whinge("Can't open package '%s'.", pkg_fullname);
71327Sjkh	return 1;
72327Sjkh    }
73327Sjkh
74327Sjkh    if (unpack(pkg_fullname, NULL))
75327Sjkh	return 1;
76327Sjkh
77327Sjkh    if (sanity_check(pkg_fullname))
78327Sjkh	return 1;
79327Sjkh
80327Sjkh    cfile = fopen(CONTENTS_FNAME, "r");
81327Sjkh    if (!cfile) {
82327Sjkh	whinge("Unable to open %s file.", CONTENTS_FNAME);
83327Sjkh	goto fail;
84327Sjkh    }
85327Sjkh    /* If we have a prefix, add it now */
86327Sjkh    if (Prefix)
87327Sjkh	add_plist(&Plist, PLIST_CWD, Prefix);
88327Sjkh    else
89327Sjkh	add_plist(&Plist, PLIST_CWD, home);
90327Sjkh    read_plist(&Plist, cfile);
91327Sjkh    fclose(cfile);
92327Sjkh    PkgName = find_name(&Plist);
93327Sjkh    if (fexists(REQUIRE_FNAME)) {
94327Sjkh	vsystem("chmod +x %s", REQUIRE_FNAME);	/* be sure */
95327Sjkh	if (Verbose)
96327Sjkh	    printf("Running requirements file first for %s..\n", PkgName);
97327Sjkh	if (vsystem("%s %s INSTALL", REQUIRE_FNAME, PkgName)) {
98327Sjkh	    whinge("Package %s fails requirements - not installed.",
99327Sjkh		   pkg_fullname);
100327Sjkh	    goto fail;
101327Sjkh	}
102327Sjkh    }
103327Sjkh    if (!NoInstall && fexists(INSTALL_FNAME)) {
104327Sjkh	vsystem("chmod +x %s", INSTALL_FNAME);	/* make sure */
105327Sjkh	if (Verbose)
106327Sjkh	    printf("Running install with PRE-INSTALL for %s..\n", PkgName);
107327Sjkh	if (vsystem("%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) {
108327Sjkh	    whinge("Install script returned error status.");
109327Sjkh	    goto fail;
110327Sjkh	}
111327Sjkh    }
112327Sjkh    extract_plist(home, &Plist);
113327Sjkh    if (!NoInstall && fexists(INSTALL_FNAME)) {
114327Sjkh	if (Verbose)
115327Sjkh	    printf("Running install with POST-INSTALL for %s..\n", PkgName);
116327Sjkh	if (vsystem("%s %s POST-INSTALL", INSTALL_FNAME, PkgName)) {
117327Sjkh	    whinge("Install script returned error status.");
118327Sjkh	    goto fail;
119327Sjkh	}
120327Sjkh    }
121327Sjkh    if (!NoRecord && !Fake) {
122327Sjkh	if (getuid() != 0)
123327Sjkh	    whinge("Not running as root - trying to record install anyway.");
124327Sjkh	if (!PkgName) {
125327Sjkh	    whinge("No package name!  Can't record package, sorry.");
126327Sjkh	    code = 1;
127327Sjkh	    goto success;	/* well, partial anyway */
128327Sjkh	}
129327Sjkh	sprintf(LogDir, "%s/%s", LOG_DIR, PkgName);
130327Sjkh	if (Verbose)
131327Sjkh	    printf("Attempting to record package into %s..\n", LogDir);
132327Sjkh	if (make_hierarchy(LogDir)) {
133327Sjkh	    whinge("Can't record package into '%s', you're on your own!",
134327Sjkh		   LogDir);
135327Sjkh	    bzero(LogDir, FILENAME_MAX);
136327Sjkh	    code = 1;
137327Sjkh	    goto success;	/* close enough for government work */
138327Sjkh	}
139327Sjkh	if (fexists(DEINSTALL_FNAME))
140327Sjkh	    copy_file(".", DEINSTALL_FNAME, LogDir);
141327Sjkh	if (fexists(REQUIRE_FNAME))
142327Sjkh	    copy_file(".", REQUIRE_FNAME, LogDir);
143327Sjkh	copy_file(".", CONTENTS_FNAME, LogDir);
144327Sjkh	copy_file(".", DESC_FNAME, LogDir);
145327Sjkh	copy_file(".", COMMENT_FNAME, LogDir);
146327Sjkh	if (Verbose)
147327Sjkh	    printf("Package %s registered in %s\n", PkgName, LogDir);
148327Sjkh    }
149327Sjkh    goto success;
150327Sjkh
151327Sjkh fail:
152327Sjkh    /* Nuke the whole (installed) show */
153327Sjkh    if (!Fake)
154327Sjkh	delete_package(FALSE, &Plist);
155327Sjkh
156327Sjkh success:
157327Sjkh    /* delete the packing list contents */
158327Sjkh    leave_playpen();
159327Sjkh
160327Sjkh    return code;
161327Sjkh}
162327Sjkh
163327Sjkhstatic int
164327Sjkhsanity_check(char *pkg)
165327Sjkh{
166327Sjkh    if (!fexists(CONTENTS_FNAME)) {
167327Sjkh	whinge("Package %s has no CONTENTS file!", pkg);
168327Sjkh	return 1;
169327Sjkh    }
170327Sjkh    if (!fexists(COMMENT_FNAME)) {
171327Sjkh	whinge("Package %s has no COMMENT file!", pkg);
172327Sjkh	return 1;
173327Sjkh    }
174327Sjkh    if (!fexists(DESC_FNAME)) {
175327Sjkh	whinge("Package %s has no DESC file!", pkg);
176327Sjkh	return 1;
177327Sjkh    }
178327Sjkh    return 0;
179327Sjkh}
180327Sjkh
181327Sjkhstatic char *
182327Sjkhfind_name(Package *pkg)
183327Sjkh{
184327Sjkh    PackingList p = pkg->head;
185327Sjkh
186327Sjkh    while (p) {
187327Sjkh	if (p->type == PLIST_NAME)
188327Sjkh	    return p->name;
189327Sjkh	p = p->next;
190327Sjkh    }
191327Sjkh    return "anonymous";
192327Sjkh}
193327Sjkh
194327Sjkhvoid
195327Sjkhcleanup(int signo)
196327Sjkh{
197327Sjkh    if (Plist.head) {
198327Sjkh	if (!Fake)
199327Sjkh	    delete_package(FALSE, &Plist);
200327Sjkh	free_plist(&Plist);
201327Sjkh    }
202327Sjkh    if (!Fake && LogDir[0])
203327Sjkh	vsystem("%s -rf %s", REMOVE_CMD, LogDir);
204327Sjkh    leave_playpen();
205327Sjkh}
206