Subject: utils/progs: minor diffs to lndir.c to preserve links VERSION: R5, public-patch-13 CLIENT MACHINE and OPERATING SYSTEM: Sparc/SunOS 4.1.1 DISPLAY TYPE: WINDOW MANAGER: COMPILER: AREA: util/progs SYNOPSIS: In some cases it is useful to have lndir preserve values of links. DESCRIPTION: Normally for a directory such as this: craft% ls -lR ../src total 8 -rw-r--r-- 1 david 8 Jul 29 22:12 A lrwxrwxrwx 1 david 1 Jul 29 22:13 B -> A lrwxrwxrwx 1 david 12 Jul 29 22:10 C -> /tmp/junkdir lrwxrwxrwx 1 david 8 Jul 29 22:14 D -> /tmp/non lrwxrwxrwx 1 david 1 Jul 29 22:17 E -> . lrwxrwxrwx 1 david 12 Jul 29 22:17 F -> /usr/bin/X11 drwxr-xr-x 2 david 512 Jul 29 22:16 subdir drwxr-xr-x 2 david 512 Jul 29 22:16 subdir2 ./src/subdir: total 2 lrwxrwxrwx 1 david 7 Jul 29 22:16 testB -> testing -rw-r--r-- 1 david 6 Jul 29 22:03 testing ./src/subdir2: total 1 lrwxrwxrwx 1 david 17 Jul 29 22:16 testing -> ../subdir/testing the lndir binary will produce craft% lndir ../src craft% ls -lR total 8 lrwxrwxrwx 1 david 8 Jul 29 22:18 A -> ../src/A lrwxrwxrwx 1 david 8 Jul 29 22:18 B -> ../src/B lrwxrwxrwx 1 david 8 Jul 29 22:18 C -> ../src/C lrwxrwxrwx 1 david 8 Jul 29 22:18 D -> ../src/D lrwxrwxrwx 1 david 8 Jul 29 22:18 E -> ../src/E lrwxrwxrwx 1 david 8 Jul 29 22:18 F -> ../src/F drwxr-xr-x 2 david 512 Jul 29 22:18 subdir drwxr-xr-x 2 david 512 Jul 29 22:18 subdir2 subdir: total 2 lrwxrwxrwx 1 david 22 Jul 29 22:18 testB -> ../../src/subdir/testB lrwxrwxrwx 1 david 24 Jul 29 22:18 testing -> ../../src/subdir/testing subdir2: total 1 lrwxrwxrwx 1 david 25 Jul 29 22:18 testing -> ../../src/subdir2/testing but in many cases it is useful to preserve the structure of the link tree -- if file A changes in the local tree, for example, B is not correctly "updated" but points back to the original tree. It would be useful to have this happen: craft% newlndir -preserve ../src craft% ls -lR total 8 lrwxrwxrwx 1 david 8 Jul 29 22:20 A -> ../src/A lrwxrwxrwx 1 david 1 Jul 29 22:20 B -> A lrwxrwxrwx 1 david 12 Jul 29 22:20 C -> /tmp/junkdir lrwxrwxrwx 1 david 8 Jul 29 22:20 D -> /tmp/non lrwxrwxrwx 1 david 1 Jul 29 22:20 E -> . lrwxrwxrwx 1 david 12 Jul 29 22:20 F -> /usr/bin/X11 drwxr-xr-x 2 david 512 Jul 29 22:20 subdir drwxr-xr-x 2 david 512 Jul 29 22:20 subdir2 subdir: total 2 lrwxrwxrwx 1 david 7 Jul 29 22:20 testB -> testing lrwxrwxrwx 1 david 24 Jul 29 22:20 testing -> ../../src/subdir/testing subdir2: total 1 lrwxrwxrwx 1 david 17 Jul 29 22:20 testing -> ../subdir/testing where files which are links in the original tree preserve their relative structure. REPEAT BY: Here's the set of diffs I'm using: - one of my goals was changing as little as possible; there is probably a way to do this optimizing calls to readlink - hasn't been tested exhaustively; caveat emptor David B. Lewis Yet another new address!: david%craft@uunet.uu.net "This is a war of engines and octanes. I drink to the American auto industry and the American oil industry." -- Joseph Stalin, sometime during WWII. SAMPLE FIX: apply to mit/util/progs/lndir.c: *** lndir.c Mon Jul 22 14:48:57 1991 --- newlndir.c Wed Jul 29 21:22:43 1992 *************** *** 55,60 **** --- 55,61 ---- extern int errno; int silent; + int preserveLinks; void quit (code, fmt, a1, a2, a3) *************** *** 162,167 **** --- 163,181 ---- } /* non-directory */ + if (preserveLinks) + { + int srclen; + /* if the original file is a link, preserve the value */ + srclen = readlink(buf, symbuf, sizeof(symbuf) -1); + if ((-1 != srclen) && (srclen > 0)) + { + symbuf[srclen] = '\0'; + if (symlink (symbuf, dp->d_name) == 0) + continue; + /* else fall through and handle normally */ + } + } if (symlink (buf, dp->d_name) < 0) { int saverrno = errno; int symlen; *************** *** 183,202 **** int ac; char **av; { ! char *fn, *tn; struct stat fs, ts; silent = 0; ! if (ac > 1 && !strcmp(av[1], "-silent")) { silent = 1; ! } ! if (ac < silent + 2 || ac > silent + 3) ! quit (1, "usage: %s [-silent] fromdir [todir]", av[0]); ! ! fn = av[silent + 1]; ! if (ac == silent + 3) ! tn = av[silent + 2]; else tn = "."; /* to directory */ --- 197,231 ---- int ac; char **av; { ! char *fn = NULL, *tn = NULL; struct stat fs, ts; + int item; + #define USAGE "usage: %s [-silent] [-preserve] fromdir [todir]" silent = 0; ! preserveLinks = 0; ! for (item = 1; item < ac; item++) ! { ! if (!strcmp(av[item], "-silent")) silent = 1; ! else if (!strcmp(av[item], "-preserve")) ! preserveLinks = 1; else + { + if (NULL == fn) + fn = av[item]; + else + { + if (NULL == tn) + tn = av[item]; + else + quit (1, USAGE, av[0]); + } + } + } + if (NULL == fn) + quit (1, USAGE, av[0]); + if (NULL == tn) tn = "."; /* to directory */