Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 04 Sep 2000 10:40:42 +0300
From:      Maxim Sobolev <sobomax@FreeBSD.org>
To:        ports@FreeBSD.org
Cc:        asami@FreeBSD.org
Subject:   Handling of symlinks to directory in pkg_delete [patch for review]
Message-ID:  <39B351FA.A6CFD24F@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------F5EBA43B6A4A5E65749923B7
Content-Type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 7bit

Hi!

I wonder if anybody noticed that handling of symlinks in pkg_delete is somewhat
broken. Particularly, the problems exist with symlinks to a directories. The
pkg_delete code considers those symlinks as a directories (if the referred
directory exists), however they are not, and thus tries to delete it using
rmdir(2), which obviously doesn't work. The workaround exists to delete
directory symlink points to first and only then remove corresponding symlinks,
however it looks like an ugly hack (see lesstif's PLIST for example). The
attached patch is expected to solve this problem. Also in this message I'm
attaching small fake package, which exposes the bug (it consist of one symlink
and one directory this symlink points to).

-Maxim
--------------F5EBA43B6A4A5E65749923B7
Content-Type: application/x-compressed;
 name="fake-0.0.tgz"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
 filename="fake-0.0.tgz"

H4sIAG9VsTkAA+1ZbW/iOBDu182vGKl7qnS75I2EQKtKUKBXtoVWBHTSrfasNHFKlpBwcdjt
ne7HnwMUCCSOd9X2PjSjVomf53Fsz9iZUfjQvh2MuoORefRypshyTdPgCBKT967UtFoVwFB0
TdVVXTcAFFlX5COQX3BOG1uQ2IoAjqIwjFm67xOM/deY0OtaM7BmGFxriiuyKAtN+7sD0oJE
kh/ali8khO8FU0qEsxkOYuh39FOsNmwXY91wqm5VVqv3WLN01XXqDaNxL1uG0HS8KJotH0vv
hOYiwI/YBs+Fz1Bx4ZeO5AVuKFEOvpxBPMFBwhHsQAXDifJR6uNgcSo5Jynpv/AQ4TlU/oKT
Pz//+gVO1l3jaIHPAPsEAx10p8cZuF7yv1qWKDS9hyCMsPChfdvv002/BTpds71t9UfDbhd1
ekNTaM7iCGPYhf7vkD2rPbniJccoOv9JY+/8V+Xy/L+KLXf+C4/xw/EHw1C0Mv6vYTsvthcb
g8Zfy4+/ohhybe/8K3KZ/1/HjuH9JU1wF2bnFEhkSzi2pWXKkygkLosA0fFI/PEbKGJNBlWW
ZUk2JFkDpX6qKKeaApY9wdB9nMN74Vg4hjsfWzQVE5o2aXqm6dfHMOy2Ov0u3GOXJliYWVMv
eAB7YgUPmEAcUqFHlkqRPkKQCI4h/nuOz5O0v0hKlPMkPvCwvF2GAmahg89lQ9cFUUj20b0X
LK/iqkkXIjy9XiJbdDaNNb++eIHtLxychtxwt+1795vOcxz5+qaVmC7WaN0EezazggNsjVcz
ifVYDGivSbwYo2Q6B/2yZ5SYtYjDvNHfvVvNz55kKpjdM6bHgPPXlQ4N9XtSNe5CiVuzNgfF
c/bG06NtK1b2x1njag5ezcG1HFzPwWs5uJGD13PwRg7u5+BBFu5g1OmKPfMW1et6o6Ik2PaA
pQKTctneY9a8WsBXC3itgNcL+FoBbxTw9QK+UcD7BXywz//gm223N93jzHBQnhmOg1fPIc8M
B+WZ4aA8MxyUZ4aD8sxwUJ4ZDsozw0H5g3Bk3H61fvINk1h5ZMojk+bfwpFJuTmNZ+bWlFvT
eGZuTbkxjWfm1pTb0nhmbk25KY1n5taUW9I1C9mrQsnEivBGa9mrr2oZz3Q8O87Ew20Zmxh9
Pe02swOCaRlHUrqkWqz4Hpnz9H60ZnMfk8yle8TOwgM/PV6becoJav+xrUGYR9CxUOd6p15h
ajFqjfi17St+bapmYmlxgFpjfm27xa/97YJfOzZ5tQR1ebWuhy57vNoIXfD6jGq5/ZBoeeNG
tZdDTu0kQldDzj05WaCrMafWI6jH618v5l8b1fZ49/pXC326E7tj5qFcicxPPZNDNfHcGBVI
pyG6HhaN6lvoZiC2zHavVyzr9Mz1aplZdSXmc82elhnKPS0z8/sxuhlxagOf/6hQ7eCGVxui
wS2ndu6juxtOP8xjdMe79aIFMsdi+65eYxY6K9nmkczwrrTXt716ZcjSER+ZPc4lkW/I5A3B
YorGrdX4Y5bunwlqD4r2PxWNfhcvvIfcJe/ckik+qB3ohf79/Pe/px/4nu+L4qEpalKZ837/
1wAUTVWrR6Buf4iU1j8lPv/k3vj339JKK6200kor7e3Zf0CPOHgAKAAA
--------------F5EBA43B6A4A5E65749923B7
Content-Type: text/plain; charset=koi8-r;
 name="pkg_install-symlinks.to.dir.handling-diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="pkg_install-symlinks.to.dir.handling-diff"

--- pkg_install/lib/file.c	2000/09/02 19:31:59	1.1
+++ pkg_install/lib/file.c	2000/09/02 19:39:30
@@ -40,7 +40,7 @@
     return FALSE;
 }
 
-/* Quick check to see if something is a directory */
+/* Quick check to see if something is a directory or symlink to a directory */
 Boolean
 isdir(char *fname)
 {
@@ -54,7 +54,7 @@
 	return FALSE;
 }
 
-/* Check to see if file is a dir, and is empty */
+/* Check to see if file is a dir or symlink to a dir, and is empty */
 Boolean
 isemptydir(char *fname)
 {
@@ -77,6 +77,10 @@
     return FALSE;
 }
 
+/*
+ * Returns TRUE if file is a regular file or symlink pointing to a regular
+ * file
+ */
 Boolean
 isfile(char *fname)
 {
@@ -86,8 +90,11 @@
     return FALSE;
 }
 
-/* Check to see if file is a file and is empty. If nonexistent or not
-   a file, say "it's empty", otherwise return TRUE if zero sized. */
+/* 
+ * Check to see if file is a file or symlink pointing to a file and is empty.
+ * If nonexistent or not a file, say "it's empty", otherwise return TRUE if
+ * zero sized.
+ */
 Boolean
 isemptyfile(char *fname)
 {
@@ -97,6 +104,16 @@
 	    return FALSE;
     }
     return TRUE;
+}
+
+/* Returns TRUE if file is a symbolic link. */
+Boolean
+issymlink(char *fname)
+{
+    struct stat sb;
+    if (lstat(fname, &sb) != FAIL && S_ISLNK(sb.st_mode))
+	return TRUE;
+    return FALSE;
 }
 
 /* Returns TRUE if file is a URL specification */
--- pkg_install/lib/lib.h	2000/09/04 07:12:52	1.1
+++ pkg_install/lib/lib.h	2000/09/04 07:15:41
@@ -129,6 +129,7 @@
 Boolean		isemptyfile(char *fname);
 Boolean         isfile(char *);
 Boolean		isempty(char *);
+Boolean		issymlink(char *);
 Boolean		isURL(char *);
 char		*fileGetURL(char *, char *);
 char		*fileFindByPath(char *, char *);
--- pkg_install/lib/plist.c	2000/09/02 19:31:59	1.1
+++ pkg_install/lib/plist.c	2000/09/02 19:32:17
@@ -390,7 +390,7 @@
 	case PLIST_FILE:
 	    last_file = p->name;
 	    sprintf(tmp, "%s/%s", Where, p->name);
-	    if (isdir(tmp) && fexists(tmp)) {
+	    if (isdir(tmp) && fexists(tmp) && !issymlink(tmp)) {
 		warnx("cannot delete specified file `%s' - it is a directory!\n"
 	   "this packing list is incorrect - ignoring delete request", tmp);
 	    }
@@ -477,7 +477,7 @@
 	if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
 	    return 1;
     }
-    else if (isdir(dir)) {
+    else if (isdir(dir) && !issymlink(dir)) {
 	if (RMDIR(dir) && !ign_err)
 	    return 1;
     }

--------------F5EBA43B6A4A5E65749923B7--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?39B351FA.A6CFD24F>