From 4a9125364a6e943c881b8d32f86f8f97e748bbe5 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Tue, 3 Feb 2009 03:18:00 +0100 Subject: [PATCH] xbps-bin: added WIP remove target. --HG-- extra : convert_revision : 71314f7183384094223cf10bf16ff704ca084883 --- bin/xbps-bin.c | 32 ++++++++---- include/plist.h | 2 + lib/Makefile | 2 +- lib/remove.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 lib/remove.c diff --git a/bin/xbps-bin.c b/bin/xbps-bin.c index d2f1abcd150..0a28fa07e99 100644 --- a/bin/xbps-bin.c +++ b/bin/xbps-bin.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008 Juan Romero Pardines. + * Copyright (c) 2008-2009 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,9 +53,10 @@ usage(void) { printf("Usage: xbps-bin [options] [action] [arguments]\n\n" " Available actions:\n" - " install, list, repo-add, repo-list, repo-rm, search, show\n" + " install, list, remove, repo-add, repo-list, repo-rm, search, show\n" " Actions with arguments:\n" " install\t\n" + " remove\t\n" " repo-add\t\n" " repo-rm\t\n" " search\t\n" @@ -67,6 +68,7 @@ usage(void) " $ xbps-bin install klibc\n" " $ xbps-bin -r /path/to/root install klibc\n" " $ xbps-bin list\n" + " $ xbps-bin remove klibc\n" " $ xbps-bin repo-add /path/to/directory\n" " $ xbps-bin repo-add http://www.location.org/xbps-repo\n" " $ xbps-bin repo-list\n" @@ -329,23 +331,35 @@ main(int argc, char **argv) prop_object_release(dict); free(plist); - } else if (strcasecmp(argv[0], "install") == 0) { + } else if ((strcasecmp(argv[0], "install") == 0) || + (strcasecmp(argv[0], "remove") == 0)) { /* Installs a binary package and required deps. */ if (argc != 2) usage(); if (geteuid() != 0) { - printf("ERROR: root permissions are needed to install " - "binary packages.\n"); + printf("ERROR: root permissions are needed to install" + "and remove binary packages.\n"); exit(EXIT_FAILURE); } /* Install into root directory by default. */ - rv = xbps_install_binary_pkg(argv[1], root); - if (rv) { - printf("ERROR: unable to install %s.\n", argv[1]); - exit(rv); + if (strcasecmp(argv[0], "install") == 0) { + rv = xbps_install_binary_pkg(argv[1], root); + if (rv) { + printf("ERROR: unable to install %s.\n", argv[1]); + exit(rv); + } + printf("Package %s installed successfully.\n", argv[1]); + } else { + rv = xbps_remove_binary_pkg(argv[1], root); + if (rv) { + printf("ERROR: unable to remove %s.\n", argv[1]); + exit(rv); + } + printf("Package %s removed successfully.\n", argv[1]); } + } else { usage(); } diff --git a/include/plist.h b/include/plist.h index e6652802c08..c000a9f6db3 100644 --- a/include/plist.h +++ b/include/plist.h @@ -162,7 +162,9 @@ char * xbps_get_pkg_name(const char *); int xbps_install_pkg_deps(prop_dictionary_t); int xbps_install_binary_pkg(const char *, const char *); int xbps_install_binary_pkg_from_repolist(prop_object_t, void *, bool *); +int xbps_remove_binary_pkg(const char *, const char *); int xbps_register_pkg(const char *, const char *, const char *); +int xbps_unregister_pkg(const char *); int xbps_unpack_binary_pkg(prop_dictionary_t, prop_dictionary_t, int (*cb)(struct archive *, prop_dictionary_t)); int xbps_unpack_archive_cb(struct archive *, prop_dictionary_t); diff --git a/lib/Makefile b/lib/Makefile index b9d71507013..a5cff148cc8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ LIBXBPS = libxbps.so LIBXBPS_LDFLAGS = -larchive -lprop -shared -Wl,-soname,$(LIBXBPS).$(MAJOR) OBJECTS = cmpver.o depends.o humanize_number.o install.o plist.o -OBJECTS += sha256.o util.o repository.o fexec.o info.o +OBJECTS += sha256.o util.o repository.o fexec.o info.o remove.o all: $(LIBXBPS) .PHONY: all diff --git a/lib/remove.c b/lib/remove.c new file mode 100644 index 00000000000..afa954cfbe5 --- /dev/null +++ b/lib/remove.c @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 2009 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int +xbps_unregister_pkg(const char *pkgname) +{ + char *plist; + int rv = 0; + + assert(pkgname != NULL); + + plist = xbps_append_full_path(true, NULL, XBPS_REGPKGDB); + if (plist == NULL) + return EINVAL; + + if (!xbps_remove_pkg_dict_from_file(pkgname, plist)) + rv = errno; + + return rv; +} + +int +xbps_remove_binary_pkg(const char *pkgname, const char *destdir) +{ + FILE *flist; + char path[PATH_MAX - 1], line[LINE_MAX - 1], *p; + int rv = 0; + size_t len = 0; + + assert(pkgname != NULL); + + if (destdir) { + if ((rv = chdir(destdir)) != 0) + return errno; + } else + destdir = ""; + + (void)snprintf(path, sizeof(path), "%s%s/metadata/%s/flist", + destdir, XBPS_META_PATH, pkgname); + + if ((flist = fopen(path, "r")) == NULL) + return errno; + + while (!feof(flist)) { + p = fgets(line, sizeof(line), flist); + if (p == NULL) { + if (feof(flist)) + break; + if (ferror(flist)) { + rv = errno; + break; + } + } + if (strlen(line) == 0 || line[0] == '#' || + isspace((unsigned char)line[0]) != 0) + continue; + + len = strlen(line) + 1; + p = calloc(1, len); + if (p == NULL) { + rv = errno; + break; + } + + (void)strncpy(p, line, len - 2); + (void)snprintf(path, sizeof(path), "%s%s", + destdir, p); + + /* + * Remove the file or the directory if it's empty. + */ + if ((rv = unlink(path)) == -1) { + if (errno == EISDIR) { + if ((rv = rmdir(path)) == -1) { + if (errno == ENOTEMPTY) { + rv = 0; + goto next; + } + printf("WARNING: can't remove directory" + " %s (%s)\n", path, strerror(errno)); + goto next; + } + printf("Removed directory: %s\n", path); + goto next; + } + printf("WARNING: can't remove file %s (%s)\n", path, + strerror(errno)); + goto next; + } + + printf("Removed file: %s\n", path); +next: + free(p); + p = NULL; + } + + (void)fclose(flist); + + /* If successful, unregister pkg from db */ + return rv ? rv : xbps_unregister_pkg(pkgname); +}