Date: Fri, 4 Feb 2005 00:49:25 +0100 (CET) From: Florent Thoumie <flz@xbsd.org> To: FreeBSD-gnats-submit@FreeBSD.org Cc: hq@FreeBSD.org Subject: bin/77082: src/usr.sbin/pkg_install - Add 3 new macros to clean pkg-plist Message-ID: <20050203234925.F2FB0119F1@gate.xbsd.org> Resent-Message-ID: <200502032350.j13NoKVj045843@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 77082 >Category: bin >Synopsis: src/usr.sbin/pkg_install - Add 3 new macros to clean pkg-plist >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Feb 03 23:50:20 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Florent Thoumie >Release: FreeBSD 5.3-RELEASE i386 >Organization: Xbsd.org >Environment: System: FreeBSD gate.xbsd.org 5.3-RELEASE FreeBSD 5.3-RELEASE #2: Wed Nov 24 16:35:34 CET 2004 root@gate.xbsd.org:/usr/src/sys/i386/compile/GATE i386 >Description: Rationale: Packing lists are clobbered with lines like : @exec [ ! -f %B/foo ] && cp %B/%f %B/foo @unexec cmp -s %D/etc/foo %D/etc/foo-dist && rm %D/etc/foo @unexec rmdir %D/share/foo 2> /dev/null || true This patch introduces 3 new macros : @dirrmie name : remove directory if empty, actually just don't bother with error messages when trying to remove the directory. @cpin name : copy if non-existent, copy name from name-dist if name doesn't exist yet. @rmiu name : remove if unchanged, remove name if name and name-dist are no different. A simple port is attached to test these new macros. >How-To-Repeat: >Fix: --- pkg_install.diff begins here --- diff -ruN src/usr.sbin/pkg_install/add/extract.c src/usr.sbin/pkg_install.new/add/extract.c --- src/usr.sbin/pkg_install/add/extract.c Wed Jul 28 09:19:15 2004 +++ src/usr.sbin/pkg_install.new/add/extract.c Fri Feb 4 00:00:35 2005 @@ -137,6 +137,7 @@ /* Do it */ while (p) { char cmd[FILENAME_MAX]; + char tmp[FILENAME_MAX], tmp2[FILENAME_MAX]; switch(p->type) { case PLIST_NAME: @@ -266,6 +267,25 @@ case PLIST_IGNORE: p = p->next; + break; + + case PLIST_CPIN: + sprintf(tmp, "%s/%s", Directory, p->name); + sprintf(tmp2, "%s/%s-dist", Directory, p->name); + PUSHOUT(Directory); + if (!fexists(tmp2)) { + warnx("file '%s' does not exist!\n" + "this packing list is incorrect - ignoring delete request", tmp2); + } + else if (!fexists(tmp)) { + if (Verbose) + printf("Installing '%s' in '%s' (non-existent)\n", tmp2, tmp); + if (!Fake && vsystem("cp %s %s", tmp2, tmp)) { + errx(2, "%s: unable to copy '%s' to '%s'", __func__, p->name, + tmp2, tmp); + } + } + last_file = p->name; break; default: diff -ruN src/usr.sbin/pkg_install/create/pkg_create.1 src/usr.sbin/pkg_install.new/create/pkg_create.1 --- src/usr.sbin/pkg_install/create/pkg_create.1 Sat Jul 3 01:12:52 2004 +++ src/usr.sbin/pkg_install.new/create/pkg_create.1 Fri Feb 4 00:00:35 2005 @@ -504,6 +504,29 @@ The .Pa name directory will not be removed unless it is empty. +.It Cm @dirrmie Ar name +Same as +.Cm @dirrm , +but there will be no error message nor warning if the directory is not +empty. +.It Cm @cpin Ar name +Declare file +.Pa name +to be copied from file +.Pa name-dist +if it does not exist yet. +.Cm @cpin +stands for copy if non-existent. +.It Cm @rmiu Ar name +Declare file +.Pa name +to be deleted at deinstall time. Note that this file will only be deleted +if it is the same file as +.Pa name-dist. +.Cm @rmiu +(which stands for remove if unchanged) is intended to be used in conjonction +with +.Cm @cpin . .It Cm @mtree Ar name Declare .Pa name diff -ruN src/usr.sbin/pkg_install/delete/pkg_delete.1 src/usr.sbin/pkg_install.new/delete/pkg_delete.1 --- src/usr.sbin/pkg_install/delete/pkg_delete.1 Sat Jul 3 01:12:52 2004 +++ src/usr.sbin/pkg_install.new/delete/pkg_delete.1 Fri Feb 4 00:00:35 2005 @@ -60,6 +60,9 @@ .Cm @mode (check for setuid), .Cm @dirrm , +.Cm @dirrmie , +.Cm @cpin , +.Cm @rmiu , .Cm @exec , and .Cm @unexec diff -ruN src/usr.sbin/pkg_install/info/show.c src/usr.sbin/pkg_install.new/info/show.c --- src/usr.sbin/pkg_install/info/show.c Mon May 26 19:06:05 2003 +++ src/usr.sbin/pkg_install.new/info/show.c Fri Feb 4 00:00:35 2005 @@ -179,6 +179,18 @@ printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name); break; + case PLIST_DIR_RMIE: + printf(Quiet ? "@dirrmie %s\n" : "\tDeinstall directory remove if empty: %s\n", p->name); + break; + + case PLIST_RMIU: + printf(Quiet ? "@rmiu %s\n" : "\tFile (removed if unchanged): %s\n", p->name); + break; + + case PLIST_CPIN: + printf(Quiet ? "@cpin %s\n" : "\tFile (copied if non-existent): %s\n", p->name); + break; + case PLIST_OPTION: printf(Quiet ? "@option %s\n" : "\tOption \"%s\" controlling package installation behaviour\n", diff -ruN src/usr.sbin/pkg_install/lib/file.c src/usr.sbin/pkg_install.new/lib/file.c --- src/usr.sbin/pkg_install/lib/file.c Wed Jul 28 18:03:13 2004 +++ src/usr.sbin/pkg_install.new/lib/file.c Fri Feb 4 00:00:35 2005 @@ -113,6 +113,20 @@ return FALSE; } +/* + * Returns 0 if the two files are the same, 1 if they are different and + * other values and another value if an error occured. + */ +int +isdifferent(const char *fname, const char *sname) +{ + char cmd[FILENAME_MAX]; + if (!fname || !sname) + return FALSE; + snprintf(cmd, FILENAME_MAX, "/usr/bin/cmp -s %s %s", fname, sname); + return vsystem(cmd); +} + /* Returns TRUE if file is a URL specification */ Boolean isURL(const char *fname) diff -ruN src/usr.sbin/pkg_install/lib/lib.h src/usr.sbin/pkg_install.new/lib/lib.h --- src/usr.sbin/pkg_install/lib/lib.h Tue Jan 4 17:18:55 2005 +++ src/usr.sbin/pkg_install.new/lib/lib.h Fri Feb 4 00:07:09 2005 @@ -108,7 +108,8 @@ PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE, PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY, PLIST_PKGDEP, PLIST_CONFLICTS, PLIST_MTREE, PLIST_DIR_RM, - PLIST_IGNORE_INST, PLIST_OPTION, PLIST_ORIGIN, PLIST_DEPORIGIN + PLIST_DIR_RMIE, PLIST_RMIU, PLIST_CPIN, PLIST_IGNORE_INST, + PLIST_OPTION, PLIST_ORIGIN, PLIST_DEPORIGIN }; typedef enum _plist_t plist_t; @@ -170,6 +171,7 @@ Boolean isfile(const char *); Boolean isempty(const char *); Boolean issymlink(const char *); +int isdifferent(const char *, const char *); Boolean isURL(const char *); char *fileGetURL(const char *, const char *); char *fileFindByPath(const char *, const char *); diff -ruN src/usr.sbin/pkg_install/lib/plist.c src/usr.sbin/pkg_install.new/lib/plist.c --- src/usr.sbin/pkg_install/lib/plist.c Wed Jul 28 09:19:15 2004 +++ src/usr.sbin/pkg_install.new/lib/plist.c Fri Feb 4 00:00:35 2005 @@ -247,6 +247,12 @@ return PLIST_MTREE; else if (!strcmp(cmd, "dirrm")) return PLIST_DIR_RM; + else if (!strcmp(cmd, "dirrmie")) + return PLIST_DIR_RMIE; + else if (!strcmp(cmd, "rmiu")) + return PLIST_RMIU; + else if (!strcmp(cmd, "cpin")) + return PLIST_CPIN; else if (!strcmp(cmd, "option")) return PLIST_OPTION; else @@ -378,6 +384,18 @@ fprintf(fp, "%cdirrm %s\n", CMD_CHAR, plist->name); break; + case PLIST_DIR_RMIE: + fprintf(fp, "%cdirrmie %s\n", CMD_CHAR, plist->name); + break; + + case PLIST_RMIU: + fprintf(fp, "%crmiu %s\n", CMD_CHAR, plist->name); + break; + + case PLIST_CPIN: + fprintf(fp, "%ccpin %s\n", CMD_CHAR, plist->name); + break; + case PLIST_OPTION: fprintf(fp, "%coption %s\n", CMD_CHAR, plist->name); break; @@ -413,7 +431,7 @@ const char *Where = ".", *last_file = ""; Boolean fail = SUCCESS; Boolean preserve; - char tmp[FILENAME_MAX], *name = NULL; + char tmp[FILENAME_MAX], tmp2[FILENAME_MAX], *name = NULL; preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE; for (p = pkg->head; p; p = p->next) { @@ -500,6 +518,7 @@ break; case PLIST_DIR_RM: + case PLIST_DIR_RMIE: sprintf(tmp, "%s/%s", Where, p->name); if (!isdir(tmp) && fexists(tmp)) { warnx("cannot delete specified directory '%s' - it is a file!\n" @@ -508,8 +527,26 @@ else { if (Verbose) printf("Delete directory %s\n", tmp); - if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) { + if (!Fake && delete_hierarchy(tmp, ign_err, FALSE) && p->type != PLIST_DIR_RMIE) { warnx("unable to completely remove directory '%s'", tmp); + fail = FAIL; + } + } + last_file = p->name; + break; + + case PLIST_RMIU: + sprintf(tmp, "%s/%s", Where, p->name); + sprintf(tmp2, "%s/%s-dist", Where, p->name); + if (!fexists(tmp) || !fexists(tmp2)) { + warnx("specified file '%s' or '%s' does not exist!\n" + "this packing list is incorrect - ignoring delete request", tmp, tmp2); + } + else if (!isdifferent(tmp, tmp2)) { + if (Verbose) + printf("Delete file %s (unchanged)\n", tmp); + if (!Fake && vsystem("%s %s %s", REMOVE_CMD, (ign_err ? "-f" : ""), tmp)) { + warnx("unable to remove file '%s'", tmp); fail = FAIL; } } --- pkg_install.diff ends here --- --- dummy-1.0.shar begins here --- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # dummy # dummy/Makefile # dummy/pkg-descr # dummy/pkg-plist # echo c - dummy mkdir -p dummy > /dev/null 2>&1 echo x - dummy/Makefile sed 's/^X//' >dummy/Makefile << 'END-of-dummy/Makefile' XPORTNAME= dummy XPORTVERSION= 1.0 XCATEGORIES= misc XDISTFILES= X XMAINTAINER= ports@FreeBSD.org XCOMMENT= Dummy port X XNO_BUILD= yes X Xdo-install: X ${MKDIR} ${DATADIR} X ${INSTALL_DATA} ${.CURDIR}/Makefile ${DATADIR}/Makefile-dist X [ ! -f ${DATADIR}/Makefile ] && ${INSTALL_DATA} ${.CURDIR}/Makefile ${DATADIR}/Makefile X X.include <bsd.port.mk> END-of-dummy/Makefile echo x - dummy/pkg-descr sed 's/^X//' >dummy/pkg-descr << 'END-of-dummy/pkg-descr' XThis is a dummy port, for testing purposes. X XWWW: http://www.freebsd.org/ X X- Florent Thoumie Xflz@xbsd.org END-of-dummy/pkg-descr echo x - dummy/pkg-plist sed 's/^X//' >dummy/pkg-plist << 'END-of-dummy/pkg-plist' X@rmiu %%DATADIR%%/Makefile X%%DATADIR%%/Makefile-dist X@cpin %%DATADIR%%/Makefile X@dirrmie %%DATADIR%% END-of-dummy/pkg-plist exit --- dummy-1.0.shar ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050203234925.F2FB0119F1>