diff options
author | joerg <joerg@pkgsrc.org> | 2009-04-24 14:00:25 +0000 |
---|---|---|
committer | joerg <joerg@pkgsrc.org> | 2009-04-24 14:00:25 +0000 |
commit | 15e7419096b963917f6e17df477f925a2c38f0c1 (patch) | |
tree | aebf25295b0320a109f3c1465ce6dcdf8948e9d1 | |
parent | f93313e5ff28ff34953e734d7608fbe0cc4d61e6 (diff) | |
download | pkgsrc-15e7419096b963917f6e17df477f925a2c38f0c1.tar.gz |
pkg_install-20090424:
Make pkg_delete -d the default behavior, remove the option.
Remove pkg_create -R support (reorder @dirrm entries).
Introduce new plist command @pkgdir, which makes pkg_add add
this directory if it doesn't exist already and pkg_delete remove it
only if no other package has a @pkgdir entry for it. Otherwise
directories are pruned when the last file or directory in them is
removed. @dirrm is now a pure hint, if the directory doesn't exist, it
will be silently skipped.
-rw-r--r-- | pkgtools/pkg_install/files/add/perform.c | 13 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/admin/check.c | 5 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/admin/main.c | 8 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/create.h | 3 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/main.c | 13 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/pkg_create.1 | 30 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/pl.c | 64 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/delete/pkg_delete.1 | 16 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/delete/pkg_delete.c | 12 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/info/show.c | 8 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/lib.h | 12 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/plist.c | 223 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/version.h | 4 |
13 files changed, 218 insertions, 193 deletions
diff --git a/pkgtools/pkg_install/files/add/perform.c b/pkgtools/pkg_install/files/add/perform.c index 58dc5770b0a..a0cac921217 100644 --- a/pkgtools/pkg_install/files/add/perform.c +++ b/pkgtools/pkg_install/files/add/perform.c @@ -1,4 +1,4 @@ -/* $NetBSD: perform.c,v 1.85 2009/04/06 14:34:15 joerg Exp $ */ +/* $NetBSD: perform.c,v 1.86 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" #endif @@ -6,7 +6,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: perform.c,v 1.85 2009/04/06 14:34:15 joerg Exp $"); +__RCSID("$NetBSD: perform.c,v 1.86 2009/04/24 14:00:25 joerg Exp $"); /*- * Copyright (c) 2003 Grant Beattie <grant@NetBSD.org> @@ -666,6 +666,13 @@ extract_files(struct pkg_task *pkg) printf("%s", p->name); break; + case PLIST_PKGDIR: + fullpath = xasprintf("%s/%s", pkg->prefix, p->name); + mkdir_p(fullpath); + free(fullpath); + add_pkgdir(pkg->pkgname, pkg->prefix, p->name); + continue; + case PLIST_CMD: if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file)) return -1; @@ -1386,7 +1393,7 @@ nuke_pkg: pkg->other_version, pkg->pkgname); warnx("Remember to run pkg_admin rebuild-tree after fixing this."); } - delete_package(FALSE, FALSE, &pkg->plist, FALSE, Destdir); + delete_package(FALSE, &pkg->plist, FALSE, Destdir); } nuke_pkgdb: diff --git a/pkgtools/pkg_install/files/admin/check.c b/pkgtools/pkg_install/files/admin/check.c index fd9f2fcac8c..82f77e1bcb5 100644 --- a/pkgtools/pkg_install/files/admin/check.c +++ b/pkgtools/pkg_install/files/admin/check.c @@ -1,4 +1,4 @@ -/* $NetBSD: check.c,v 1.8 2009/04/23 19:35:52 joerg Exp $ */ +/* $NetBSD: check.c,v 1.9 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: check.c,v 1.8 2009/04/23 19:35:52 joerg Exp $"); +__RCSID("$NetBSD: check.c,v 1.9 2009/04/24 14:00:25 joerg Exp $"); /*- * Copyright (c) 1999-2008 The NetBSD Foundation, Inc. @@ -173,6 +173,7 @@ check1pkg(const char *pkgdir, int *filecnt, int *pkgcnt) case PLIST_OPTION: case PLIST_PKGCFL: case PLIST_BLDDEP: + case PLIST_PKGDIR: break; } } diff --git a/pkgtools/pkg_install/files/admin/main.c b/pkgtools/pkg_install/files/admin/main.c index 40d85318d46..81e967cd8b0 100644 --- a/pkgtools/pkg_install/files/admin/main.c +++ b/pkgtools/pkg_install/files/admin/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.50 2009/04/23 19:35:52 joerg Exp $ */ +/* $NetBSD: main.c,v 1.51 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: main.c,v 1.50 2009/04/23 19:35:52 joerg Exp $"); +__RCSID("$NetBSD: main.c,v 1.51 2009/04/24 14:00:25 joerg Exp $"); /*- * Copyright (c) 1999-2008 The NetBSD Foundation, Inc. @@ -175,6 +175,10 @@ add_pkg(const char *pkgdir, void *vp) (*cnt)++; } break; + case PLIST_PKGDIR: + add_pkgdir(PkgName, dirp, p->name); + (*cnt)++; + break; case PLIST_CWD: if (strcmp(p->name, ".") != 0) { dirp = p->name; diff --git a/pkgtools/pkg_install/files/create/create.h b/pkgtools/pkg_install/files/create/create.h index c3fe149ae3c..00fc7dcba3a 100644 --- a/pkgtools/pkg_install/files/create/create.h +++ b/pkgtools/pkg_install/files/create/create.h @@ -1,4 +1,4 @@ -/* $NetBSD: create.h,v 1.9 2007/08/03 13:15:59 joerg Exp $ */ +/* $NetBSD: create.h,v 1.10 2009/04/24 14:00:25 joerg Exp $ */ /* from FreeBSD Id: create.h,v 1.13 1997/10/08 07:46:19 charnier Exp */ @@ -59,7 +59,6 @@ extern char PlayPen[]; extern size_t PlayPenSize; extern int PlistOnly; extern int RelativeLinks; -extern int ReorderDirs; extern int update_pkgdb; extern int create_views; diff --git a/pkgtools/pkg_install/files/create/main.c b/pkgtools/pkg_install/files/create/main.c index aa316d80229..28fa78e10df 100644 --- a/pkgtools/pkg_install/files/create/main.c +++ b/pkgtools/pkg_install/files/create/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.12 2009/02/02 12:35:01 joerg Exp $ */ +/* $NetBSD: main.c,v 1.13 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: main.c,v 1.12 2009/02/02 12:35:01 joerg Exp $"); +__RCSID("$NetBSD: main.c,v 1.13 2009/04/24 14:00:25 joerg Exp $"); /* * FreeBSD install - a package for the installation and maintainance @@ -26,7 +26,7 @@ __RCSID("$NetBSD: main.c,v 1.12 2009/02/02 12:35:01 joerg Exp $"); #include "lib.h" #include "create.h" -static const char Options[] = "B:C:D:EFI:K:L:OP:RS:T:UVb:c:d:f:g:i:k:ln:p:r:s:u:v"; +static const char Options[] = "B:C:D:EFI:K:L:OP:S:T:UVb:c:d:f:g:i:k:ln:p:r:s:u:v"; char *Prefix = NULL; char *Comment = NULL; @@ -53,14 +53,13 @@ int update_pkgdb = 1; int create_views = 0; int PlistOnly = 0; int RelativeLinks = 0; -int ReorderDirs = 0; Boolean File2Pkg = FALSE; static void usage(void) { fprintf(stderr, - "usage: pkg_create [-ElORUVv] [-B build-info-file] [-b build-version-file]\n" + "usage: pkg_create [-ElOUVv] [-B build-info-file] [-b build-version-file]\n" " [-C cpkgs] [-D displayfile] [-I realprefix] [-i iscript]\n" " [-K pkg_dbdir] [-k dscript] [-L SrcDir]\n" " [-n preserve-file] [-P dpkgs] [-p prefix] [-r rscript]\n" @@ -100,10 +99,6 @@ main(int argc, char **argv) PlistOnly = 1; break; - case 'R': - ReorderDirs = 1; - break; - case 'U': update_pkgdb = 0; break; diff --git a/pkgtools/pkg_install/files/create/pkg_create.1 b/pkgtools/pkg_install/files/create/pkg_create.1 index a8d6d258b2b..143603dddc8 100644 --- a/pkgtools/pkg_install/files/create/pkg_create.1 +++ b/pkgtools/pkg_install/files/create/pkg_create.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: pkg_create.1,v 1.18 2009/04/23 19:34:04 joerg Exp $ +.\" $NetBSD: pkg_create.1,v 1.19 2009/04/24 14:00:25 joerg Exp $ .\" .\" FreeBSD install - a package for the installation and maintenance .\" of non-core utilities. @@ -24,7 +24,7 @@ .\" [jkh] Took John's changes back and made some additional extensions for .\" better integration with FreeBSD's new ports collection. .\" -.Dd July 28, 2008 +.Dd April 24, 2009 .Dt PKG_CREATE 1 .Os .Sh NAME @@ -32,7 +32,7 @@ .Nd a utility for creating software package distributions .Sh SYNOPSIS .Nm -.Op Fl ElORUVv +.Op Fl ElOUVv .Bk -words .Op Fl B Ar build-info-file .Ek @@ -256,10 +256,6 @@ as the initial directory .Pq base to start from in selecting files for the package. -.It Fl R -Re-order any directories in the PLIST file into reverse alphabetic -order, so that child directories will automatically be removed before -parent directories. .It Fl S Ar size-all-file Store the given file for later querying with the .Xr pkg_info 1 @@ -435,20 +431,18 @@ Note that will derive this field from the .Ar pkg-name and add it automatically if none is given. -.It Cm @dirrm Ar name +.It Cm @pkgdir Ar name Declare directory .Pa name -to be deleted at deinstall time. -By default, directories created by a package installation are not deleted -when the package is deinstalled; this provides an explicit directory cleanup -method. -This directive should appear at the end of the package list. -If more than one -.Cm @dirrm -directives are used, the directories are removed in the order specified. -The +as managed. +If it does not exist at installation time, it is created. +If this directory is no longer referenced by packages and the last +file or directory in it is deleted, the directory is removed as well. +.It Cm @dirrm Ar name +This command is supported for compatibility only. +If directory .Pa name -directory will not be removed unless it is empty. +exists, it will be deleted at deinstall time. .It Cm @display Ar name Declare .Pa name diff --git a/pkgtools/pkg_install/files/create/pl.c b/pkgtools/pkg_install/files/create/pl.c index 7218167f520..429d454b52e 100644 --- a/pkgtools/pkg_install/files/create/pl.c +++ b/pkgtools/pkg_install/files/create/pl.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl.c,v 1.12 2009/02/02 12:35:01 joerg Exp $ */ +/* $NetBSD: pl.c,v 1.13 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: pl.c,v 1.12 2009/02/02 12:35:01 joerg Exp $"); +__RCSID("$NetBSD: pl.c,v 1.13 2009/04/24 14:00:25 joerg Exp $"); /* * FreeBSD install - a package for the installation and maintainance @@ -74,39 +74,6 @@ CheckSymlink(char *name, char *prefix, size_t prefixcc) } /* - * (Reversed) comparison routine for directory name sorting - */ -static int -dircmp(const void *vp1, const void *vp2) -{ - return strcmp((const char *) vp2, (const char *) vp1); -} - -/* - * Re-order the PLIST_DIR_RM entries into reverse alphabetic order - */ -static void -reorder(package_t *pkg, int dirc) -{ - plist_t *p; - char **dirv; - int i; - - dirv = xcalloc(dirc, sizeof(char *)); - - for (p = pkg->head, i = 0; p; p = p->next) { - if (p->type == PLIST_DIR_RM) - dirv[i++] = p->name; - } - qsort(dirv, dirc, sizeof(char *), dircmp); - for (p = pkg->head, i = 0; p; p = p->next) { - if (p->type == PLIST_DIR_RM) - p->name = dirv[i++]; - } - free(dirv); -} - -/* * Check a list for files that require preconversion */ void @@ -120,26 +87,36 @@ check_list(package_t *pkg, const char *PkgName) char name[MaxPathSize]; char *cwd = NULL; char *srcdir = NULL; - int dirc; + char *pkgname = NULL; int cc; /* Open Package Database for writing */ if (update_pkgdb && !pkgdb_open(ReadWrite)) err(EXIT_FAILURE, "can't open pkgdb"); - for (dirc = 0, p = pkg->head; p; p = p->next) { + for (p = pkg->head; p; p = p->next) { switch (p->type) { case PLIST_CWD: cwd = p->name; break; + case PLIST_NAME: + pkgname = p->name; + break; case PLIST_IGNORE: p = p->next; break; case PLIST_SRC: srcdir = p->name; break; - case PLIST_DIR_RM: - dirc++; + case PLIST_PKGDIR: + if (cwd == NULL) + errx(2, "@pkgdir without preceding @cwd found"); + if (pkgname == NULL) + errx(2, "@pkgdir without preceding @name found"); + if (update_pkgdb) { + add_pkgdir(pkgname, cwd, p->name); + /* mkdir_p(cwd, p->name); */ + } break; case PLIST_FILE: /* @@ -178,9 +155,8 @@ check_list(package_t *pkg, const char *PkgName) } switch (st.st_mode & S_IFMT) { case S_IFDIR: - p->type = PLIST_DIR_RM; - dirc++; - continue; + warnx("Warning - directory `%s' in PLIST", name); + break; case S_IFLNK: if (RelativeLinks) { CheckSymlink(name, cwd, strlen(cwd)); @@ -236,8 +212,4 @@ check_list(package_t *pkg, const char *PkgName) if (update_pkgdb) { pkgdb_close(); } - - if (ReorderDirs && dirc > 0) { - reorder(pkg, dirc); - } } diff --git a/pkgtools/pkg_install/files/delete/pkg_delete.1 b/pkgtools/pkg_install/files/delete/pkg_delete.1 index 1721d6e1669..e0039dcf0d4 100644 --- a/pkgtools/pkg_install/files/delete/pkg_delete.1 +++ b/pkgtools/pkg_install/files/delete/pkg_delete.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: pkg_delete.1,v 1.19 2009/02/25 16:57:51 wiz Exp $ +.\" $NetBSD: pkg_delete.1,v 1.20 2009/04/24 14:00:25 joerg Exp $ .\" .\" FreeBSD install - a package for the installation and maintenance .\" of non-core utilities. @@ -17,7 +17,7 @@ .\" .\" from FreeBSD: @(#)pkg_delete.1 .\" -.Dd February 25, 2009 +.Dd April 24, 2009 .Dt PKG_DELETE 1 .Os .Sh NAME @@ -25,7 +25,7 @@ .Nd a utility for deleting previously installed software package distributions .Sh SYNOPSIS .Nm -.Op Fl ADdFfNnORrVv +.Op Fl ADFfNnORrVv .Bk -words .Op Fl K Ar pkg_dbdir .Ek @@ -109,16 +109,6 @@ See also the flag. .It Fl D If a deinstallation script exists for a given package, do not execute it. -.It Fl d -Remove empty directories created by file cleanup. -By default, only files/directories explicitly listed in a package's -contents (either as normal files/directories or with the -.Cm @dirrm -directive) will be removed at deinstallation time. -This option tells -.Nm -to also remove any directories that were emptied as a result of removing -the package. .It Fl F Any pkg-name given will be interpreted as pathname which is subsequently transformed in a (real) package name via the Package diff --git a/pkgtools/pkg_install/files/delete/pkg_delete.c b/pkgtools/pkg_install/files/delete/pkg_delete.c index 803b0269315..65bb95e7d49 100644 --- a/pkgtools/pkg_install/files/delete/pkg_delete.c +++ b/pkgtools/pkg_install/files/delete/pkg_delete.c @@ -34,7 +34,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: pkg_delete.c,v 1.5 2009/04/23 22:13:00 joerg Exp $"); +__RCSID("$NetBSD: pkg_delete.c,v 1.6 2009/04/24 14:00:25 joerg Exp $"); #if HAVE_ERR_H #include <err.h> @@ -53,7 +53,6 @@ static const char *destdir; static const char *prefix; static int no_deinstall; -static int prune_empty; static int find_by_filename; static int unregister_only; static int pkgdb_update_only; @@ -64,7 +63,7 @@ static int delete_automatic_leaves; static void usage(void) { - fprintf(stderr, "usage: pkg_delete [-DdFfNnORrVv] [-K pkg_dbdir]" + fprintf(stderr, "usage: pkg_delete [-DFfNnORrVv] [-K pkg_dbdir]" " [-P destdir] [-p prefix] pkg-name ...\n"); exit(1); } @@ -691,7 +690,7 @@ remove_pkg(const char *pkg) if (Fake) printf("Attempting to delete package `%s'\n", pkg); - else if (delete_package(FALSE, prune_empty, &plist, unregister_only, + else if (delete_package(FALSE, &plist, unregister_only, destdir) == FAIL) { warnx("couldn't entirely delete package `%s'", pkg); /* @@ -774,7 +773,7 @@ main(int argc, char *argv[]) TAILQ_INIT(&sorted_pkgs); setprogname(argv[0]); - while ((ch = getopt(argc, argv, "ADdFfNnORrVvK:P:p:")) != -1) { + while ((ch = getopt(argc, argv, "ADFfNnORrVvK:P:p:")) != -1) { switch (ch) { case 'A': delete_automatic_leaves = 1; @@ -782,9 +781,6 @@ main(int argc, char *argv[]) case 'D': no_deinstall = 1; break; - case 'd': - prune_empty = 1; - break; case 'F': find_by_filename = 1; break; diff --git a/pkgtools/pkg_install/files/info/show.c b/pkgtools/pkg_install/files/info/show.c index f59a4043df0..a7a621e3fc4 100644 --- a/pkgtools/pkg_install/files/info/show.c +++ b/pkgtools/pkg_install/files/info/show.c @@ -1,4 +1,4 @@ -/* $NetBSD: show.c,v 1.27 2009/04/23 19:35:52 joerg Exp $ */ +/* $NetBSD: show.c,v 1.28 2009/04/24 14:00:25 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: show.c,v 1.27 2009/04/23 19:35:52 joerg Exp $"); +__RCSID("$NetBSD: show.c,v 1.28 2009/04/24 14:00:25 joerg Exp $"); /* * FreeBSD install - a package for the installation and maintainance @@ -90,10 +90,11 @@ static const show_t showv[] = { {PLIST_SRC, "@src: %s", "\tSRC to: %s"}, {PLIST_DISPLAY, "@display %s", "\tInstall message file: %s"}, {PLIST_PKGDEP, "@pkgdep %s", "\tPackage depends on: %s"}, - {PLIST_DIR_RM, "@dirrm %s", "\tDeinstall directory remove: %s"}, + {PLIST_DIR_RM, "@dirrm %s", "\tObsolete deinstall directory removal hint: %s"}, {PLIST_OPTION, "@option %s", "\tPackage has option: %s"}, {PLIST_PKGCFL, "@pkgcfl %s", "\tPackage conflicts with: %s"}, {PLIST_BLDDEP, "@blddep %s", "\tPackage depends exactly on: %s"}, + {PLIST_PKGDIR, "@pkgdir %s", "\tManaged directory: %s"}, {-1, NULL, NULL} }; @@ -192,6 +193,7 @@ show_plist(const char *title, package_t *plist, pl_ent_t type) case PLIST_OPTION: case PLIST_PKGCFL: case PLIST_BLDDEP: + case PLIST_PKGDIR: printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name); break; default: diff --git a/pkgtools/pkg_install/files/lib/lib.h b/pkgtools/pkg_install/files/lib/lib.h index a8edac7acb8..95e449823a0 100644 --- a/pkgtools/pkg_install/files/lib/lib.h +++ b/pkgtools/pkg_install/files/lib/lib.h @@ -1,4 +1,4 @@ -/* $NetBSD: lib.h,v 1.53 2009/04/24 01:03:41 joerg Exp $ */ +/* $NetBSD: lib.h,v 1.54 2009/04/24 14:00:26 joerg Exp $ */ /* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */ @@ -168,7 +168,8 @@ typedef enum pl_ent_t { PLIST_DIR_RM, /* 13 */ PLIST_OPTION, /* 14 */ PLIST_PKGCFL, /* 15 */ - PLIST_BLDDEP /* 16 */ + PLIST_BLDDEP, /* 16 */ + PLIST_PKGDIR /* 17 */ } pl_ent_t; /* Enumerated constants for build info */ @@ -304,11 +305,14 @@ Boolean isempty(const char *); int URLlength(const char *); Boolean make_preserve_name(char *, size_t, const char *, const char *); void remove_files(const char *, const char *); -int delete_hierarchy(const char *, Boolean, Boolean); int format_cmd(char *, size_t, const char *, const char *, const char *); int recursive_remove(const char *, int); +void add_pkgdir(const char *, const char *, const char *); +void delete_pkgdir(const char *, const char *, const char *); +int has_pkgdir(const char *); + /* pkg_io.c: Local and remote archive handling */ struct archive; struct archive_entry; @@ -334,7 +338,7 @@ void stringify_plist(package_t *, char **, size_t *, const char *); void parse_plist(package_t *, const char *); void read_plist(package_t *, FILE *); void append_plist(package_t *, FILE *); -int delete_package(Boolean, Boolean, package_t *, Boolean, const char *); +int delete_package(Boolean, package_t *, Boolean, const char *); /* Package Database */ int pkgdb_open(int); diff --git a/pkgtools/pkg_install/files/lib/plist.c b/pkgtools/pkg_install/files/lib/plist.c index 454a71fcc6b..5489a396354 100644 --- a/pkgtools/pkg_install/files/lib/plist.c +++ b/pkgtools/pkg_install/files/lib/plist.c @@ -1,4 +1,4 @@ -/* $NetBSD: plist.c,v 1.27 2009/04/23 19:53:52 joerg Exp $ */ +/* $NetBSD: plist.c,v 1.28 2009/04/24 14:00:26 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: plist.c,v 1.27 2009/04/23 19:53:52 joerg Exp $"); +__RCSID("$NetBSD: plist.c,v 1.28 2009/04/24 14:00:26 joerg Exp $"); /* * FreeBSD install - a package for the installation and maintainance @@ -30,7 +30,7 @@ __RCSID("$NetBSD: plist.c,v 1.27 2009/04/23 19:53:52 joerg Exp $"); */ /*- - * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>. + * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg@NetBSD.org>. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,6 +71,8 @@ __RCSID("$NetBSD: plist.c,v 1.27 2009/04/23 19:53:52 joerg Exp $"); #include <md5.h> #endif +static int delete_with_parents(const char *, Boolean, Boolean); + /* This struct defines a plist command type */ typedef struct cmd_t { const char *c_s; /* string to recognise */ @@ -94,6 +96,7 @@ static const cmd_t cmdv[] = { {"display", PLIST_DISPLAY, 1, 0}, {"pkgdep", PLIST_PKGDEP, 1, 0}, {"pkgcfl", PLIST_PKGCFL, 1, 0}, + {"pkgdir", PLIST_PKGDIR, 1, 0}, {"dirrm", PLIST_DIR_RM, 1, 0}, {"option", PLIST_OPTION, 1, 0}, {"blddep", PLIST_BLDDEP, 1, 0}, @@ -501,40 +504,81 @@ do { \ * run it too in cases of failure. */ int -delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg, - Boolean NoDeleteFiles, const char *destdir) +delete_package(Boolean ign_err, package_t *pkg, Boolean NoDeleteFiles, + const char *destdir) { plist_t *p; - char *Where = ".", *last_file = ""; + char *last_file = ""; int fail = SUCCESS; Boolean preserve; - char tmp[MaxPathSize], *name = NULL; + char tmp[MaxPathSize]; + const char *prefix = NULL, *name = NULL; if (!pkgdb_open(ReadWrite)) { err(EXIT_FAILURE, "cannot open pkgdb"); } 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_CWD: + if (prefix == NULL) + prefix = p->name; + break; + default: + break; + } + } - case PLIST_IGNORE: - p = p->next; + if (name == NULL || prefix == NULL) + errx(EXIT_FAILURE, "broken PLIST"); + + /* + * Remove database entries first, directory removal is done + * in the main loop below. + */ + for (p = pkg->head; p; p = p->next) { + if (p->type == PLIST_PKGDIR) + delete_pkgdir(name, prefix, p->name); + } + + for (p = pkg->head; p; p = p->next) { + switch (p->type) { + case PLIST_NAME: + /* Handled already */ break; - case PLIST_CWD: - Where = p->name; - if (Verbose) - printf("Change working directory to %s\n", Where); + case PLIST_PKGDIR: + case PLIST_DIR_RM: + (void) snprintf(tmp, sizeof(tmp), "%s/%s", + prefix, p->name); + if (has_pkgdir(tmp)) + continue; + (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", + destdir ? destdir : "", destdir ? "/" : "", + prefix, p->name); + if (!fexists(tmp)) { + if (p->type == PLIST_PKGDIR) + warnx("Directory `%s' disappeared, skipping", tmp); + } else if (!isdir(tmp)) { + warnx("attempting to delete a file `%s' as a directory\n" + "this packing list is incorrect - ignoring delete request", tmp); + } else if (delete_with_parents(tmp, ign_err, TRUE)) + fail = FAIL; + break; + + case PLIST_IGNORE: + p = p->next; break; case PLIST_UNEXEC: if (NoDeleteFiles) break; - format_cmd(tmp, sizeof(tmp), p->name, Where, last_file); + format_cmd(tmp, sizeof(tmp), p->name, prefix, last_file); /* XXX cleanup(0); */ printf("Executing `%s'\n", tmp); if (!Fake && system(tmp)) { @@ -547,7 +591,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg, last_file = p->name; (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", destdir ? destdir : "", destdir ? "/" : "", - Where, p->name); + prefix, p->name); if (isdir(tmp)) { warnx("attempting to delete directory `%s' as a file\n" "this packing list is incorrect - ignoring delete request", tmp); @@ -606,7 +650,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg, if (Verbose && !NoDeleteFiles) printf("Delete file %s\n", tmp); if (!Fake && !NoDeleteFiles) { - if (delete_hierarchy(tmp, ign_err, nukedirs)) + if (delete_with_parents(tmp, ign_err, FALSE)) fail = FAIL; if (preserve && name) { char tmp2[MaxPathSize]; @@ -633,32 +677,6 @@ pkgdb_cleanup: } } break; - - case PLIST_DIR_RM: - if (NoDeleteFiles || nukedirs) - break; - - (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", - destdir ? destdir : "", destdir ? "/" : "", - Where, p->name); - if (fexists(tmp)) { - if (!isdir(tmp)) { - warnx("cannot remove `%s' as a directory\n" - "this packing list is incorrect - ignoring delete request", tmp); - } else { - if (Verbose) - printf("Delete directory %s\n", tmp); - if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) { - warnx("unable to completely remove directory '%s'", tmp); - fail = FAIL; - } - } - } else { - warnx("cannot remove non-existent directory `%s'\n" - "this packing list is incorrect - ignoring delete request", tmp); - } - last_file = p->name; - break; default: break; } @@ -671,51 +689,94 @@ pkgdb_cleanup: * Selectively delete a hierarchy * Returns 1 on error, 0 else. */ -int -delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs) +static int +delete_with_parents(const char *fname, Boolean ign_err, Boolean ign_nonempty) { - char *cp1, *cp2, *tmp_dir; - - if (!fexists(dir)) { - if (!ign_err) - warnx("%s `%s' doesn't really exist", - isdir(dir) ? "directory" : "file", dir); - return !ign_err; - } else if (nukedirs) { - if (recursive_remove(dir, ign_err)) { - warn("Couldn't remove %s", dir); - return 1; - } - } else if (isdir(dir)) { - if (rmdir(dir) && !ign_err) - return 1; - } else { - if (remove(dir) && !ign_err) - return 1; - } + char *cp, *cp2; - if (!nukedirs) + if (remove(fname)) { + if (!ign_err && (!ign_nonempty || errno != ENOTEMPTY)) + warnx("Couldn't remove %s", fname); return 0; - - cp1 = cp2 = tmp_dir = xstrdup(dir);; - - while (cp2) { - if ((cp2 = strrchr(cp1, '/')) != NULL) + } + cp = xstrdup(fname); + while (*cp) { + if ((cp2 = strrchr(cp, '/')) != NULL) *cp2 = '\0'; - if (!isemptydir(tmp_dir)) + if (!isemptydir(cp)) + break; + if (has_pkgdir(cp)) + break; + if (rmdir(cp)) break; - if (rmdir(tmp_dir) && !ign_err) { - if (fexists(tmp_dir)) { - free(tmp_dir); - return 1; + } + free(cp); + + return 0; +} + +void +add_pkgdir(const char *pkg, const char *prefix, const char *path) +{ + char *fullpath, *oldvalue, *newvalue; + + fullpath = xasprintf("%s/%s", prefix, path); + oldvalue = pkgdb_retrieve(fullpath); + if (oldvalue) { + if (strncmp(oldvalue, "@pkgdir ", 8) != 0) + errx(EXIT_FAILURE, "Internal error while processing pkgdb, run pkg_admin rebuild"); + newvalue = xasprintf("%s %s", oldvalue, pkg); + pkgdb_remove(fullpath); + } else { + newvalue = xasprintf("@pkgdir %s", pkg); + } + pkgdb_store(fullpath, newvalue); + + free(fullpath); + free(newvalue); +} + +void +delete_pkgdir(const char *pkg, const char *prefix, const char *path) +{ + size_t pkg_len, len; + char *fullpath, *oldvalue, *newvalue, *iter; + + fullpath = xasprintf("%s/%s", prefix, path); + oldvalue = pkgdb_retrieve(fullpath); + if (oldvalue && strncmp(oldvalue, "@pkgdir ", 8) == 0) { + newvalue = xstrdup(oldvalue); + iter = newvalue + 8; + pkg_len = strlen(pkg); + while (*iter) { + if (strncmp(iter, pkg, pkg_len) == 0 && + (iter[pkg_len] == ' ' || iter[pkg_len] == '\0')) { + len = strlen(iter + pkg_len); + memmove(iter, iter + pkg_len + 1, len); + if (len == 0) + *iter = '\0'; + } else { + iter += strcspn(iter, " "); + iter += strspn(iter, " "); } - warnx("directory `%s' doesn't really exist", tmp_dir); - } - /* back up the pathname one component */ - if (cp2) { - cp1 = tmp_dir; } + pkgdb_remove(fullpath); + if (iter != newvalue + 8) + pkgdb_store(fullpath, newvalue); + free(newvalue); } - free(tmp_dir); - return 0; + free(fullpath); +} + +int +has_pkgdir(const char *path) +{ + const char *value; + + value = pkgdb_retrieve(path); + + if (value && strncmp(value, "@pkgdir ", 8) == 0) + return 1; + else + return 0; } diff --git a/pkgtools/pkg_install/files/lib/version.h b/pkgtools/pkg_install/files/lib/version.h index e664698a58b..09fa580285e 100644 --- a/pkgtools/pkg_install/files/lib/version.h +++ b/pkgtools/pkg_install/files/lib/version.h @@ -1,4 +1,4 @@ -/* $NetBSD: version.h,v 1.123 2009/04/22 19:18:06 joerg Exp $ */ +/* $NetBSD: version.h,v 1.124 2009/04/24 14:00:26 joerg Exp $ */ /* * Copyright (c) 2001 Thomas Klausner. All rights reserved. @@ -27,6 +27,6 @@ #ifndef _INST_LIB_VERSION_H_ #define _INST_LIB_VERSION_H_ -#define PKGTOOLS_VERSION "20090422" +#define PKGTOOLS_VERSION "20090424" #endif /* _INST_LIB_VERSION_H_ */ |