From andreas@klemm.apsfilter.org  Sun Jul 13 10:00:13 2003
Return-Path: <andreas@klemm.apsfilter.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id B77D537B404
	for <FreeBSD-gnats-submit@FreeBSD.org>; Sun, 13 Jul 2003 10:00:13 -0700 (PDT)
Received: from srv1.cosmo-project.de (srv1.cosmo-project.de [213.83.6.106])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 3836B43F93
	for <FreeBSD-gnats-submit@FreeBSD.org>; Sun, 13 Jul 2003 10:00:12 -0700 (PDT)
	(envelope-from andreas@klemm.apsfilter.org)
Received: from srv1.cosmo-project.de (localhost [IPv6:::1])
	by srv1.cosmo-project.de (8.12.9/8.12.9) with ESMTP id h6DH09hR055991
	(version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO)
	for <FreeBSD-gnats-submit@FreeBSD.org>; Sun, 13 Jul 2003 19:00:10 +0200 (CEST)
	(envelope-from andreas@klemm.apsfilter.org)
Received: (from uucp@localhost)
	by srv1.cosmo-project.de (8.12.9/8.12.9/Submit) with UUCP id h6DH09xe055990
	for FreeBSD-gnats-submit@FreeBSD.org; Sun, 13 Jul 2003 19:00:09 +0200 (CEST)
	(envelope-from andreas@klemm.apsfilter.org)
Received: from titan.klemm.apsfilter.org (localhost.klemm.apsfilter.org [127.0.0.1])
	by klemm.apsfilter.org (8.12.9/8.12.9) with ESMTP id h6DGw7Tv002352
	for <FreeBSD-gnats-submit@FreeBSD.org>; Sun, 13 Jul 2003 18:58:07 +0200 (CEST)
	(envelope-from andreas@titan.klemm.apsfilter.org)
Received: (from andreas@localhost)
	by titan.klemm.apsfilter.org (8.12.9/8.12.9/Submit) id h6DGw73R002351;
	Sun, 13 Jul 2003 18:58:07 +0200 (CEST)
Message-Id: <200307131658.h6DGw73R002351@titan.klemm.apsfilter.org>
Date: Sun, 13 Jul 2003 18:58:07 +0200 (CEST)
From: Andreas Klemm <andreas@klemm.apsfilter.org>
Reply-To: Andreas Klemm <andreas@klemm.apsfilter.org>
To: FreeBSD-gnats-submit@FreeBSD.org
Cc:
Subject: pkg_delete doesn't honour symlinks, portupgrades leads to failing services (i.e. squid)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         54446
>Category:       bin
>Synopsis:       [patch] pkg_delete(1) doesn't honour symlinks, portupgrades leads to failing services (i.e. squid)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    portmgr
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 13 10:00:32 PDT 2003
>Closed-Date:    Mon May 07 03:55:12 UTC 2012
>Last-Modified:  Mon May 07 03:55:12 UTC 2012
>Originator:     Andreas Klemm
>Release:        FreeBSD-current
>Organization:
FreeBSD
>Environment:
System: FreeBSD titan.klemm.apsfilter.org 5.1-CURRENT FreeBSD 5.1-CURRENT #0: Sat Jul 12 16:46:09 CEST 2003 root@titan.klemm.apsfilter.org:/usr/src/sys/i386/compile/TITAN i386

FreeBSD 5.2-current and all other FreeBSD releases

Always happended to me when upgrading squid on a machine, since
I always use symlinks to move the cache to a larger directory than
/usr/local ...

>Description:

Upgrade of squid port brings squid into non operational state,
if the toplevel of the data directory (/usr/local/squid) is a symlink
(to /var/squid for example) and not a real directory.

I assume the reason is, that pkg_delete doesn't honor symlinks.

The toplevel directory of squid data and logs (/usr/local/squid)
would normally not being removed by pkg_delete, if there are additional
files under /usr/local/squid/{cache, logs}. This is the case, if you
use squid for a while and then upgrade the port.

But if its a symlink then /usr/local/sqzid will be deleted and
the upgrade of the port installs the usual fresh/empty /usr/local/squid
data directory ...

The result is a dying squid that doesn't find its data directory.

This behaviour should be changed in pkg_delete to make upgrade of
ports more smoothly / reliable, if part of a large tree had to be moved
away.

Since this could also be a subtree somewhere under /usr/local/squid,
pkg_delete should alway check, if file is a symlink and follow.

>How-To-Repeat:

	install squid from ports
	mv /usr/local/squid /var/squid
	ln -s /var/squid /usr/local/squid
	squid -z
	Then remove and reinstall the squid port or
	perform:
	portupgrade -af
	All squid ports of today and in the past have the negativ side
	effect, that the symlink /usr/local/squid to the real data
	directory /var/squid simply gets removed.

>Fix:

	no fix available at this time.

	I assume, that the pkg_delete is the culprit, it doesn't know about
	symlinks ....
>Release-Note:
>Audit-Trail:

From: Andrea Barberio <insomniac@slackware.it>
To: bug-followup@FreeBSD.org
Cc: andreas@klemm.apsfilter.org
Subject: Re: bin/54446: pkg_delete(1) doesn't honour symlinks, portupgrades
 leads to failing services (i.e. squid)
Date: Wed, 26 Nov 2008 03:21:55 +0100

 --Sig_/ww9W5aXKFJzV4rqgrE3=6CM
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: quoted-printable
 
 This patch should fix the reported bug, and other ones, too, like
 memory leaks, missing checks of function return values, and wrong return
 values.
 
 http://insomniac.slackware.it/plist.c.diff
 
 Regards,
 --=20
 Andrea Barberio
 
 --Sig_/ww9W5aXKFJzV4rqgrE3=6CM
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Disposition: attachment; filename=signature.asc
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.9 (GNU/Linux)
 
 iQEcBAEBAgAGBQJJLLLIAAoJEF+mA7Lmigt9zykIAJN3Ci8UDljc8j7prbbNvVjf
 DxEUyuOM+VcMzH0DMYu6rzhfUeSF0vQIWW/QoNCHTkb2yQrBNnI71D+0hdUhBCKL
 +dnX6pi4IAnxZffCr0aHOgk3N8/a/pOGcigwysW1jHLy32d1V6SPuw4INRjMANGd
 luKFLUpm3ifW7sv7NqG3o+ZQMFpNGWF1+v24Y3VXZBiA9+9YHcppQpe0MhdBEQeV
 aslrsgnw0MeZb/Ij5ePlOE8zZQhh04zfVHSIfwPQDmFf+XV7xtSIlYwSvrWS8uSf
 PjSkRGiU7SvFx2L9HsXc8mQlY2Irln0ZGB/PXl7Y7v9/xXubuTrosrpCBii0XXU=
 =t7la
 -----END PGP SIGNATURE-----
 
 --Sig_/ww9W5aXKFJzV4rqgrE3=6CM--
Responsible-Changed-From-To: freebsd-bugs->flz 
Responsible-Changed-By: remko 
Responsible-Changed-When: Thu Nov 27 07:51:20 UTC 2008 
Responsible-Changed-Why:  
Sounds like Florent's region, Florent can you have a look at it please? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=54446 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/54446: commit references a PR
Date: Thu, 25 Dec 2008 16:59:46 +0000 (UTC)

 Author: flz
 Date: Thu Dec 25 16:59:35 2008
 New Revision: 186496
 URL: http://svn.freebsd.org/changeset/base/186496
 
 Log:
   Follow symlinks when deleting directories.
   Bump PKG_INSTALL_VER to 20081225 (Merry Christmas \o/).
   
   PR:		bin/54446
   Submitted by:	Andrea Barberio <insomniac@slackware.it>
   MFC after:	1 month
 
 Modified:
   head/usr.sbin/pkg_install/lib/lib.h
   head/usr.sbin/pkg_install/lib/plist.c
 
 Modified: head/usr.sbin/pkg_install/lib/lib.h
 ==============================================================================
 --- head/usr.sbin/pkg_install/lib/lib.h	Thu Dec 25 16:44:01 2008	(r186495)
 +++ head/usr.sbin/pkg_install/lib/lib.h	Thu Dec 25 16:59:35 2008	(r186496)
 @@ -105,7 +105,7 @@
   * Version of the package tools - increase only when some
   * functionality used by bsd.port.mk is changed, added or removed
   */
 -#define PKG_INSTALL_VERSION	20080708
 +#define PKG_INSTALL_VERSION	20081225
  
  #define PKG_WRAPCONF_FNAME	"/var/db/pkg_install.conf"
  #define main(argc, argv)	real_main(argc, argv)
 
 Modified: head/usr.sbin/pkg_install/lib/plist.c
 ==============================================================================
 --- head/usr.sbin/pkg_install/lib/plist.c	Thu Dec 25 16:44:01 2008	(r186495)
 +++ head/usr.sbin/pkg_install/lib/plist.c	Thu Dec 25 16:59:35 2008	(r186496)
 @@ -544,45 +544,92 @@ delete_package(Boolean ign_err, Boolean 
  int
  delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs)
  {
 -    char *cp1, *cp2;
 +    char *cp1, *cp2, *realdir;
  
 -    cp1 = cp2 = strdup(dir);
 -    if (!fexists(dir)) {
 +    realdir = malloc(FILENAME_MAX);
 +    if (realdir == NULL) {
 +	warnx("Couldn't allocate enough memory\n");
 +	return (ign_err ? SUCCESS : FAIL);
 +    }
 +
 +    if (issymlink(dir) && readlink(dir, realdir, FILENAME_MAX-1) == -1)
 +	return (ign_err ? SUCCESS : FAIL);
 +
 +    strlcpy(realdir, dir, FILENAME_MAX);
 +
 +    cp1 = cp2 = strdup(realdir);
 +    if (cp1 == NULL) {
 +	warnx("Couldn't allocate enough memory\n");
 +	return (ign_err ? SUCCESS : FAIL);
 +    }
 +
 +    if (!fexists(realdir)) {
  	if (!ign_err)
  	    warnx("%s '%s' doesn't exist",
 -		isdir(dir) ? "directory" : "file", dir);
 -	return !ign_err;
 +		isdir(realdir) ? "directory" : "file", realdir);
 +	free(cp1);
 +	free(realdir);
 +	return (ign_err ? SUCCESS : FAIL);
      }
      else if (nukedirs) {
 -	if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
 -	    return 1;
 +	if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), realdir)) {
 +	    free(cp1);
 +	    free(realdir);
 +	    return (ign_err ? SUCCESS : FAIL);
 +	}
      }
 -    else if (isdir(dir) && !issymlink(dir)) {
 -	if (RMDIR(dir) && !ign_err)
 -	    return 1;
 +    else if (isdir(realdir)) {
 +	if (RMDIR(realdir)) {
 +	    free(cp1);
 +	    free(realdir);
 +	    return (ign_err ? SUCCESS : FAIL);
 +	}
      }
      else {
 -	if (REMOVE(dir, ign_err))
 -	    return 1;
 +	if (REMOVE(realdir, ign_err)) {
 +	    free(cp1);
 +	    free(realdir);
 +	    return (ign_err ? SUCCESS : FAIL);
 +	}
      }
  
 -    if (!nukedirs)
 -	return 0;
 +    if (!nukedirs) {
 +	free(cp1);
 +	free(realdir);
 +	return (SUCCESS);
 +    }
      while (cp2) {
  	if ((cp2 = strrchr(cp1, '/')) != NULL)
  	    *cp2 = '\0';
 -	if (!isemptydir(dir))
 -	    return 0;
 -	if (RMDIR(dir) && !ign_err) {
 -	    if (!fexists(dir))
 -		warnx("directory '%s' doesn't exist", dir);
 -	    else
 -		return 1;
 +	if (!isemptydir(realdir)) {
 +	    free(cp1);
 +	    free(realdir);
 +	    return (SUCCESS);
 +	}
 +	if (RMDIR(realdir) && !ign_err) {
 +	    if (!fexists(realdir)) {
 +		warnx("directory '%s' doesn't exist", realdir);
 +		free(cp1);
 +		free(realdir);
 +		return (SUCCESS);
 +	    } else {
 +		free(cp1);
 +		free(realdir);
 +		return (FAIL);
 +	    }
  	}
  	/* back up the pathname one component */
  	if (cp2) {
 -	    cp1 = strdup(dir);
 +	    free(cp1);
 +	    cp1 = strdup(realdir);
 +	    if (cp1 == NULL) {
 +		warnx("Couldn't allocate enough memory\n");
 +		return (ign_err ? SUCCESS : FAIL);
 +	    }
  	}
      }
 -    return 0;
 +    free(cp1);
 +    free(realdir);
 +    return (SUCCESS);
  }
 +
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: flz 
State-Changed-When: Thu Dec 25 17:00:33 UTC 2008 
State-Changed-Why:  
Committed to HEAD, will MFC to RELENG_[67] after 1 month. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=54446 
Responsible-Changed-From-To: flz->portmgr 
Responsible-Changed-By: flz 
Responsible-Changed-When: Fri Jul 17 13:43:11 UTC 2009 
Responsible-Changed-Why:  
pkg_install is maintained by portmgr. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=54446 
State-Changed-From-To: patched->suspended 
State-Changed-By: flz 
State-Changed-When: Fri Jul 17 13:44:02 UTC 2009 
State-Changed-Why:  
The patch was backed out because it broke on pointyhat.  Waiting on 
another patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=54446 
State-Changed-From-To: suspended->closed 
State-Changed-By: eadler 
State-Changed-When: Mon May 7 03:55:09 UTC 2012 
State-Changed-Why:  
pkgng brings all kinds of goodness 

http://www.freebsd.org/cgi/query-pr.cgi?pr=54446 
>Unformatted:
