From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1PrdqW-0005eT-RK for garchives@archives.gentoo.org; Mon, 21 Feb 2011 22:03:09 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id BCF381C07B; Mon, 21 Feb 2011 22:03:01 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 6AED31C080 for ; Mon, 21 Feb 2011 22:03:01 +0000 (UTC) Received: from flycatcher.gentoo.org (flycatcher.gentoo.org [81.93.255.6]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 7A3E81B4007 for ; Mon, 21 Feb 2011 22:03:00 +0000 (UTC) Received: by flycatcher.gentoo.org (Postfix, from userid 559) id 23A6520054; Mon, 21 Feb 2011 22:02:59 +0000 (UTC) From: "Mike Frysinger (vapier)" To: gentoo-commits@lists.gentoo.org Reply-To: gentoo-dev@lists.gentoo.org, vapier@gentoo.org Subject: [gentoo-commits] gentoo-projects commit in portage-utils: qmerge.c X-VCS-Repository: gentoo-projects X-VCS-Files: qmerge.c X-VCS-Directories: portage-utils X-VCS-Committer: vapier X-VCS-Committer-Name: Mike Frysinger Content-Type: text/plain; charset=utf8 Message-Id: <20110221220259.23A6520054@flycatcher.gentoo.org> Date: Mon, 21 Feb 2011 22:02:59 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: 6d875bc7f229aa921160d39a4918b3d7 vapier 11/02/21 22:02:59 Modified: qmerge.c Log: add support for CONFIG_PROTECT_MASK when unmerging, as well as running = the pkg_{pre,post}rm funcs Revision Changes Path 1.100 portage-utils/qmerge.c file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils= /qmerge.c?rev=3D1.100&view=3Dmarkup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils= /qmerge.c?rev=3D1.100&content-type=3Dtext/plain diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils= /qmerge.c?r1=3D1.99&r2=3D1.100 Index: qmerge.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v retrieving revision 1.99 retrieving revision 1.100 diff -u -r1.99 -r1.100 --- qmerge.c 21 Feb 2011 06:20:24 -0000 1.99 +++ qmerge.c 21 Feb 2011 22:02:59 -0000 1.100 @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 - * $Header: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v 1.99 2= 011/02/21 06:20:24 vapier Exp $ + * $Header: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v 1.100 = 2011/02/21 22:02:59 vapier Exp $ * * Copyright 2005-2010 Ned Ludd - * Copyright 2005-2010 Mike Frysinger - @@ -55,7 +55,7 @@ COMMON_OPTS_HELP }; =20 -static const char qmerge_rcsid[] =3D "$Id: qmerge.c,v 1.99 2011/02/21 06= :20:24 vapier Exp $"; +static const char qmerge_rcsid[] =3D "$Id: qmerge.c,v 1.100 2011/02/21 2= 2:02:59 vapier Exp $"; #define qmerge_usage(ret) usage(ret, QMERGE_FLAGS, qmerge_long_opts, qme= rge_opts_help, lookup_applet_idx("qmerge")) =20 char search_pkgs =3D 0; @@ -105,7 +105,6 @@ void pkg_process(int, char **, struct pkg_t *); void print_Pkg(int, struct pkg_t *); int parse_packages(const char *, int, char **); -int config_protected(const char *, int, char **); int match_pkg(const char *, struct pkg_t *); int pkg_verify_checksums(char *, struct pkg_t *, depend_atom *, int stri= ct, int display); int unmerge_packages(int, char **); @@ -129,8 +128,7 @@ return mkdir(dname, mode); } =20 -int q_unlink_q(char *, const char *, int); -int q_unlink_q(char *path, const char *func, int line) +static int q_unlink_q(char *path, const char *func, int line) { if ((strcmp(path, "/bin/sh") =3D=3D 0) || (strcmp(path, BUSYBOX) =3D=3D= 0)) { warn("Oh hell no: unlink(%s) from %s line %d", path, func, line); @@ -153,7 +151,7 @@ struct stat st; char check_interactive =3D interactive; =20 - if (check_interactive && (stat(dst, &st) !=3D (-1))) { + if (check_interactive && (stat(dst, &st) !=3D -1)) { snprintf(buf, sizeof(buf), "qfile -Cqev %s 2>/dev/null", dst); if ((fp =3D popen(buf, "r")) !=3D NULL) { buf[0] =3D '\0'; @@ -260,22 +258,29 @@ return (char *) buf; } =20 -int config_protected(const char *buf, int ARGC, char **ARGV) +static int +config_protected(const char *buf, int cp_argc, char **cp_argv, + int cpm_argc, char **cpm_argv) { int i; char dest[_Q_PATH_MAX]; snprintf(dest, sizeof(dest), "%s%s", portroot, buf); =20 - for (i =3D 1; i < ARGC; i++) - if (strncmp(ARGV[i], buf, strlen(ARGV[i])) =3D=3D 0) - if ((access(dest, R_OK)) =3D=3D 0) + /* Check CONFIG_PROTECT_MASK */ + for (i =3D 1; i < cpm_argc; ++i) + if (strncmp(cpm_argv[i], buf, strlen(cpm_argv[i])) =3D=3D 0) + return 0; + + /* Check CONFIG_PROTECT */ + for (i =3D 1; i < cp_argc; ++i) + if (strncmp(cp_argv[i], buf, strlen(cp_argv[i])) =3D=3D 0) + if (access(dest, R_OK) =3D=3D 0) return 1; =20 - if (strncmp("/etc", buf, 4) =3D=3D 0) - if (access(dest, R_OK) =3D=3D 0) - return 1; + /* this would probably be bad */ if (strcmp("/bin/sh", buf) =3D=3D 0) return 1; + return 0; } =20 @@ -286,7 +291,7 @@ =20 assert(pretend =3D=3D 0); =20 - if (lstat(buf, &lst) =3D=3D (-1)) + if (lstat(buf, &lst) =3D=3D -1) return; if (lst.st_dev !=3D st.st_dev) { warn("skipping crossmount install masking: %s", buf); @@ -623,7 +628,7 @@ } xchdir("image"); =20 - if (stat("./", &st) =3D=3D (-1)) + if (stat("./", &st) =3D=3D -1) err("Cant stat pwd"); =20 makeargv(install_mask, &iargc, &iargv); @@ -699,7 +704,7 @@ snprintf(line, sizeof(line), "obj %s %s %lu", &buf[1], hash, st.st_mt= ime); /* /etc /usr/kde/2/share/config /usr/kde/3/share/config /var/qmail/co= ntrol */ =20 - protected =3D config_protected(&buf[1], ARGC, ARGV); + protected =3D config_protected(&buf[1], ARGC, ARGV, 0, NULL); if (protected) { unsigned char *target_hash =3D hash_file(dest, HASH_MD5); if (memcmp(target_hash, hash, 16) !=3D 0) { @@ -757,7 +762,7 @@ =20 xgetcwd(pwd, sizeof(pwd)); xchdir(dirname(tmp)); /* tmp gets eatten up now by the dirname call *= / - if (lstat(path, &lst) !=3D (-1)) + if (lstat(path, &lst) !=3D -1) unlink_q(dest); /* if (path[0] !=3D '/') puts("path does not start with /"); @@ -822,12 +827,19 @@ =20 int pkg_unmerge(const char *cat, const char *pkgname) { - char buf[BUFSIZ]; + size_t buflen; + char *buf, *vdb_path; FILE *fp; - int argc; - char **argv; + int ret, fd, vdb_fd; + int cp_argc, cpm_argc; + char **cp_argv, **cpm_argv; llist_char *dirs =3D NULL; =20 + ret =3D 1; + buf =3D NULL; + vdb_path =3D NULL; + vdb_fd =3D fd =3D -1; + if ((strchr(pkgname, ' ') !=3D NULL) || (strchr(cat, ' ') !=3D NULL)) { qfprintf(stderr, "%s!!!%s '%s' '%s' (ambiguous name) specify fully-qua= lified pkgs\n", RED, NORM, cat, pkgname); qfprintf(stderr, "%s!!!%s %s/%s (ambiguous name) specify fully-qualifi= ed pkgs\n", RED, NORM, cat, pkgname); @@ -839,16 +851,44 @@ if (pretend =3D=3D 100) return 0; =20 - snprintf(buf, sizeof(buf), "%s/%s/%s/%s/CONTENTS", portroot, portvdb, c= at, pkgname); - - if ((fp =3D fopen(buf, "r")) =3D=3D NULL) - return 1; + /* Get a handle on the vdb path which we'll use everywhere else */ + xasprintf(&vdb_path, "%s/%s/%s/%s/", portroot, portvdb, cat, pkgname); + vdb_fd =3D open(vdb_path, O_RDONLY | O_CLOEXEC); + if (vdb_fd =3D=3D -1) { + warnp("unable to read %s", vdb_path); + goto done; + } =20 - argc =3D 0; - argv =3D NULL; - makeargv(config_protect, &argc, &argv); + /* First execute the pkg_prerm step */ + if (!pretend) { + qprintf(">>> pkg_prerm\n"); + xchdir(vdb_path); + xsystembash( + "bzip2 -dc environment.bz2 > environment && " + "pkg_prerm() { :; } && " + ". ./environment && " + "pkg_prerm" + ); + } + + /* Now start removing all the installed files */ + fd =3D openat(vdb_fd, "CONTENTS", O_RDONLY | O_CLOEXEC); + if (fd =3D=3D -1) { + warnp("unable to read %s", "CONTENTS"); + goto done; + } + fp =3D fdopen(fd, "r"); + if (fp =3D=3D NULL) + goto done; + + /* XXX: be nice to pull this out of the current func + * so we don't keep reparsing the same env var + * when unmerging multiple packages. + */ + makeargv(config_protect, &cp_argc, &cp_argv); + makeargv(config_protect_mask, &cpm_argc, &cpm_argv); =20 - while (fgets(buf, sizeof(buf), fp) !=3D NULL) { + while (getline(&buf, &buflen, fp) !=3D -1) { contents_entry *e; char zing[20]; int protected =3D 0; @@ -858,8 +898,9 @@ e =3D contents_parse_line(buf); if (!e) continue; snprintf(dst, sizeof(dst), "%s%s", portroot, e->name); - protected =3D config_protected(e->name, argc, argv); + protected =3D config_protected(e->name, cp_argc, cp_argv, cpm_argc, cp= m_argv); snprintf(zing, sizeof(zing), "%s%s%s", protected ? YELLOW : GREEN, pro= tected ? "***" : "<<<" , NORM); + /* Should we remove in order symlinks,objects,dirs ? */ switch (e->type) { case CONTENTS_DIR: @@ -870,17 +911,19 @@ list->next =3D dirs; dirs =3D list; } - qprintf("%s %s%s%s/\n", zing, DKBLUE, dst, NORM); break; case CONTENTS_OBJ: - if (!protected) unlink_q(dst); + if (!protected) + unlink_q(dst); qprintf("%s %s\n", zing, dst); break; case CONTENTS_SYM: - if (protected) break; - if (e->name[0] !=3D '/') break; + if (protected) + break; + if (e->name[0] !=3D '/') + break; if (e->sym_target[0] !=3D '/') { - if (lstat(dst, &lst) !=3D (-1)) { + if (lstat(dst, &lst) !=3D -1) { if (S_ISLNK(lst.st_mode)) { qprintf("%s %s%s -> %s%s\n", zing, CYAN, dst, e->sym_target, NORM= ); unlink_q(dst); @@ -892,7 +935,7 @@ warn("!!! %s -> %s", e->name, e->sym_target); break; } - if (lstat(dst, &lst) !=3D (-1)) { + if (lstat(dst, &lst) !=3D -1) { if (S_ISLNK(lst.st_mode)) { qprintf("%s %s%s -> %s%s\n", zing, CYAN, dst, e->sym_target, NORM)= ; unlink_q(dst); @@ -910,23 +953,68 @@ } =20 fclose(fp); + fd =3D -1; =20 - /* remove all dirs in reverse order */ + /* Then remove all dirs in reverse order */ while (dirs !=3D NULL) { llist_char *list =3D dirs; - dirs =3D dirs->next; - rmdir(list->data); + char *dir =3D list->data; + int rm; + + rm =3D pretend ? -1 : rmdir(dir); + qprintf("%s%s%s %s%s%s/\n", rm ? YELLOW : GREEN, rm ? "---" : "<<<", + NORM, DKBLUE, dir, NORM); + free(list->data); free(list); + dirs =3D dirs->next; } =20 - freeargv(argc, argv); + freeargv(cp_argc, cp_argv); + freeargv(cpm_argc, cpm_argv); =20 + /* Then execute the pkg_postrm step */ if (!pretend) { - snprintf(buf, sizeof(buf), BUSYBOX " rm -rf %s/%s/%s/%s", portroot, po= rtvdb, cat, pkgname); - xsystem(buf); + qprintf(">>> pkg_postrm\n"); + xsystembash( + /* "bzip2 -dc environment.bz2 > environment && " */ + "pkg_postrm() { :; } && " + ". ./environment && " + "pkg_postrm" + ); } - return 1; + + if (!pretend) { + /* Finally delete the vdb entry */ + DIR *dir; + struct dirent *de; + + dir =3D fdopendir(vdb_fd); + if (!dir) + goto done; + + while ((de =3D readdir(dir)) !=3D NULL) + unlinkat(vdb_fd, de->d_name, 0); + + closedir(dir); + vdb_fd =3D -1; + + rmdir(vdb_path); + + /* XXX: Really only needed because we shell out to qlist and such ... = */ + xchdir("/"); + } + + ret =3D 0; + done: + if (fd !=3D -1) + close(fd); + if (vdb_fd !=3D -1) + close(vdb_fd); + free(buf); + free(vdb_path); + + return ret; } =20 int unlink_empty(char *buf)