michael%odie.cs.mun.ca@MITVMA.MIT.EDU (Mike Rendell) (02/21/90)
Two problems with gnu ln in the fileutils-1.0 distribution: * does not check to see if it is linking to a directory: (as root) # mkdir A # ln A B A is a directory # ln.gnu A B # this is hard to fix on some systems (e.g. clri must be used on suns) * using -f as root can make a mess of the file system: (as root) # mkdir A A/B # ls -ldg A/B drwxrwx--- 2 michael wheel 512 Feb 21 11:07 A/B # touch B # ln.gnu -f B A # ls -ldg A/B -rw-rw---- 2 michael wheel 512 Feb 21 11:09 A/B # Diffs two fix these problems: *** /tmp/,RCSt1012657 Wed Feb 21 11:44:38 1990 --- ln.c Wed Feb 21 11:35:24 1990 *************** *** 161,166 **** --- 168,174 ---- char *new; { struct stat stats; + int ulink = 0; if (isdir (new)) { *************** *** 177,192 **** if (verbose) printf (" %s -> %s\n", old, new); ! if (force) ! unlink (new); else if (interactive && lstat (new, &stats) == 0) { if (!confirm (new)) return 0; else ! unlink (new); } ! if ((*linkfunc) (old, new) < 0) { fprintf (stderr, "%s: cannot %slink %s to ", --- 185,216 ---- if (verbose) printf (" %s -> %s\n", old, new); ! if (isdir(old)) ! { ! /* On bsd systems -f means links to directories are ok, on sysV it ! means try to force the link by unlinking the target first. ! Go with the sysV method - /etc/link, should be used to link ! directories. */ ! fprintf (stderr, "%s: %s is a directory\n", program, new); ! return 1; ! } ! else if (force) ! ulink = 1; else if (interactive && lstat (new, &stats) == 0) { if (!confirm (new)) return 0; else ! ulink = 1; } ! ! /* Watch that we don't try to unlink a directory as this can have bad ! consequences when done by root. */ ! if (ulink && !isdir(new)) ! { ! unlink(new); ! } ! if ((*linkfunc) (old, new) < 0) { fprintf (stderr, "%s: cannot %slink %s to ", -- Mike Rendell - Dept. of Comp. Sci, Memorial University of Newfoundland