Date: Mon, 04 Sep 2000 10:33:01 +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: <39B3502D.55BDAB6E@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------96BF9B1B3805CE2E14A0912B Content-Type: text/plain; charset=x-user-defined 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 --------------96BF9B1B3805CE2E14A0912B Content-Type: text/plain; charset=x-user-defined; 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:13:16 @@ -129,6 +129,7 @@ Boolean isemptyfile(char *fname); Boolean isfile(char *); Boolean isempty(char *); +Boolean isfile(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; } --------------96BF9B1B3805CE2E14A0912B 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 --------------96BF9B1B3805CE2E14A0912B-- 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?39B3502D.55BDAB6E>