Add support for @option preserve - moves existing files out of the way
before replacing them (using pkgname to make this hopefully unique). Delete also moves them back, if they exist, resulting in a package which can be "backed out" with reasonable safety.
This commit is contained in:
parent
5f88d2b8b4
commit
94d1d55871
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static const char *rcsid = "$Id: extract.c,v 1.12 1997/02/25 07:22:23 jkh Exp $";
|
||||
static const char *rcsid = "$Id: extract.c,v 1.13 1997/05/24 21:45:55 ache Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -45,6 +45,33 @@ static const char *rcsid = "$Id: extract.c,v 1.12 1997/02/25 07:22:23 jkh Exp $"
|
||||
perm_count = 0; \
|
||||
}
|
||||
|
||||
static void
|
||||
rollback(char *name, char *home, PackingList start, PackingList stop)
|
||||
{
|
||||
PackingList q;
|
||||
char try[FILENAME_MAX], bup[FILENAME_MAX], *dir;
|
||||
|
||||
dir = home;
|
||||
for (q = start; q != stop; q = q->next) {
|
||||
if (q->type == PLIST_FILE) {
|
||||
snprintf(try, FILENAME_MAX, "%s/%s", dir, q->name);
|
||||
snprintf(bup, FILENAME_MAX, "%s.%s", try, name);
|
||||
if (fexists(bup)) {
|
||||
(void)chflags(try, 0);
|
||||
(void)unlink(try);
|
||||
if (rename(bup, try))
|
||||
whinge("rollback: unable to rename %s back to %s.", bup, try);
|
||||
}
|
||||
}
|
||||
else if (q->type == PLIST_CWD) {
|
||||
if (strcmp(q->name, "."))
|
||||
dir = q->name;
|
||||
else
|
||||
dir = home;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
extract_plist(char *home, Package *pkg)
|
||||
{
|
||||
@ -52,6 +79,7 @@ extract_plist(char *home, Package *pkg)
|
||||
char *last_file;
|
||||
char *where_args, *perm_args, *last_chdir;
|
||||
int maxargs, where_count = 0, perm_count = 0, add_count;
|
||||
Boolean preserve;
|
||||
|
||||
maxargs = sysconf(_SC_ARG_MAX) / 2; /* Just use half the argument space */
|
||||
where_args = alloca(maxargs);
|
||||
@ -66,6 +94,7 @@ extract_plist(char *home, Package *pkg)
|
||||
perm_args[0] = 0;
|
||||
|
||||
last_chdir = 0;
|
||||
preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
|
||||
|
||||
/* Reset the world */
|
||||
Owner = NULL;
|
||||
@ -94,6 +123,21 @@ extract_plist(char *home, Package *pkg)
|
||||
|
||||
/* first try to rename it into place */
|
||||
sprintf(try, "%s/%s", Directory, p->name);
|
||||
if (preserve) {
|
||||
char pf[FILENAME_MAX];
|
||||
|
||||
if (!PkgName) {
|
||||
whinge("Package set preserve option but has no name - bailing out.");
|
||||
return;
|
||||
}
|
||||
snprintf(pf, FILENAME_MAX, "%s.%s", try, PkgName);
|
||||
(void)chflags(try, 0); /* XXX hack - if truly immutable, rename fails */
|
||||
if (rename(try, pf)) {
|
||||
whinge("Unable to back up %s to %s, aborting pkg_add", try, pf);
|
||||
rollback(PkgName, home, pkg->head, p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (rename(p->name, try) == 0) {
|
||||
/* try to add to list of perms to be changed and run in bulk. */
|
||||
if (p->name[0] == '/' || TOOBIG(p->name)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static const char *rcsid = "$Id$";
|
||||
static const char *rcsid = "$Id: perform.c,v 1.41 1997/02/22 16:09:20 peter Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -458,11 +458,6 @@ cleanup(int signo)
|
||||
{
|
||||
if (signo)
|
||||
printf("Signal %d received, cleaning up..\n", signo);
|
||||
if (Plist.head) {
|
||||
if (!Fake)
|
||||
delete_package(FALSE, FALSE, &Plist);
|
||||
free_plist(&Plist);
|
||||
}
|
||||
if (!Fake && LogDir[0])
|
||||
vsystem("%s -rf %s", REMOVE_CMD, LogDir);
|
||||
leave_playpen(Home);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static const char *rcsid = "$Id$";
|
||||
static const char *rcsid = "$Id: plist.c,v 1.19 1997/02/22 16:09:51 peter Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -23,6 +23,7 @@ static const char *rcsid = "$Id$";
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include <errno.h>
|
||||
#include <md5.h>
|
||||
|
||||
/* Add an item to a packing list */
|
||||
@ -352,10 +353,16 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
|
||||
PackingList p;
|
||||
char *Where = ".", *last_file = "";
|
||||
Boolean fail = SUCCESS;
|
||||
char tmp[FILENAME_MAX];
|
||||
Boolean preserve;
|
||||
char tmp[FILENAME_MAX], *name = NULL;
|
||||
|
||||
preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
|
||||
for (p = pkg->head; p; p = p->next) {
|
||||
switch (p->type) {
|
||||
case PLIST_NAME:
|
||||
name = p->name;
|
||||
break;
|
||||
|
||||
case PLIST_IGNORE:
|
||||
p = p->next;
|
||||
break;
|
||||
@ -401,8 +408,22 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
|
||||
}
|
||||
if (Verbose)
|
||||
printf("Delete file %s\n", tmp);
|
||||
if (!Fake && preserve) {
|
||||
if (!name)
|
||||
whinge("preserve set but no package name supplied!");
|
||||
else {
|
||||
char tmp2[FILENAME_MAX];
|
||||
|
||||
if (!Fake && delete_hierarchy(tmp, ign_err, nukedirs)) {
|
||||
snprintf(tmp2, FILENAME_MAX, "%s.%s", tmp, name);
|
||||
if (fexists(tmp2)) {
|
||||
(void)chflags(tmp, 0);
|
||||
delete_hierarchy(tmp, TRUE, TRUE);
|
||||
if (rename(tmp2, tmp))
|
||||
whinge("preserve: Unable to restore %s as %s, errno = %d", tmp2, tmp, errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Fake && delete_hierarchy(tmp, ign_err, nukedirs)) {
|
||||
whinge("Unable to completely remove file '%s'", tmp);
|
||||
fail = FAIL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user