diff options
-rw-r--r-- | lndir.c | 162 | ||||
-rw-r--r-- | lndir.man | 30 |
2 files changed, 109 insertions, 83 deletions
@@ -26,13 +26,14 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/config/util/lndir.c,v 3.17 2002/10/07 15:28:51 tsi Exp $ */ /* From the original /bin/sh script: Used to create a copy of the a directory tree that has links for all - non-directories (except those named RCS, SCCS or CVS.adm). If you are - building the distribution on more than one machine, you should use - this technique. + non-directories (except, by default, those named RCS, SCCS or CVS.adm). + If you are building the distribution on more than one machine, you + should use this technique. If your master sources are located in /usr/local/src/X and you would like your link tree to be in /usr/local/src/new-X, do the following: @@ -45,8 +46,11 @@ in this Software without prior written authorization from The Open Group. #include <X11/Xos.h> #include <X11/Xfuncproto.h> #include <stdio.h> +#include <stdlib.h> #include <sys/stat.h> +#if !defined(MINIX) && !defined(Lynx) #include <sys/param.h> +#endif #include <errno.h> #ifndef X_NOT_POSIX @@ -69,77 +73,49 @@ in this Software without prior written authorization from The Open Group. #define MAXPATHLEN 2048 #endif -#if NeedVarargsPrototypes #include <stdarg.h> -#endif -#ifdef X_NOT_STDC_ENV -extern int errno; -#endif int silent = 0; /* -silent */ int ignore_links = 0; /* -ignorelinks */ +int with_revinfo = 0; /* -withrevinfo */ char *rcurdir; char *curdir; -void -quit ( -#if NeedVarargsPrototypes - int code, char * fmt, ...) -#else - code, fmt, a1, a2, a3) - char *fmt; -#endif +static void +quit (int code, char * fmt, ...) { -#if NeedVarargsPrototypes va_list args; va_start(args, fmt); vfprintf (stderr, fmt, args); va_end(args); -#else - fprintf (stderr, fmt, a1, a2, a3); -#endif putc ('\n', stderr); exit (code); } -void -quiterr (code, s) - char *s; +static void +quiterr (int code, char *s) { perror (s); exit (code); } -void -msg ( -#if NeedVarargsPrototypes - char * fmt, ...) -#else - fmt, a1, a2, a3) - char *fmt; -#endif +static void +msg (char * fmt, ...) { -#if NeedVarargsPrototypes va_list args; -#endif if (curdir) { fprintf (stderr, "%s:\n", curdir); curdir = 0; } -#if NeedVarargsPrototypes va_start(args, fmt); vfprintf (stderr, fmt, args); va_end(args); -#else - fprintf (stderr, fmt, a1, a2, a3); -#endif putc ('\n', stderr); } -void -mperror (s) - char *s; +static void +mperror (char *s) { if (curdir) { fprintf (stderr, "%s:\n", curdir); @@ -149,17 +125,18 @@ mperror (s) } -int equivalent(lname, rname) - char *lname; - char *rname; +static int +equivalent(char *lname, char *rname, char **p) { char *s; if (!strcmp(lname, rname)) return 1; for (s = lname; *s && (s = strchr(s, '/')); s++) { - while (s[1] == '/') + while (s[1] == '/') { strcpy(s+1, s+2); + if (*p) (*p)--; + } } return !strcmp(lname, rname); } @@ -167,12 +144,12 @@ int equivalent(lname, rname) /* Recursively create symbolic links from the current directory to the "from" directory. Assumes that files described by fs and ts are directories. */ - -dodir (fn, fs, ts, rel) -char *fn; /* name of "from" directory, either absolute or +static int +dodir (char *fn, /* name of "from" directory, either absolute or relative to cwd */ -struct stat *fs, *ts; /* stats for the "from" directory and cwd */ -int rel; /* if true, prepend "../" to fn before using */ + struct stat *fs, + struct stat *ts, /* stats for the "from" directory and cwd */ + int rel) /* if true, prepend "../" to fn before using */ { DIR *df; struct dirent *dp; @@ -202,11 +179,18 @@ int rel; /* if true, prepend "../" to fn before using */ } p = buf + strlen (buf); - *p++ = '/'; + if (*(p - 1) != '/') + *p++ = '/'; n_dirs = fs->st_nlink; while ((dp = readdir (df))) { if (dp->d_name[strlen(dp->d_name) - 1] == '~') continue; +#ifdef __DARWIN__ + /* Ignore these Mac OS X Finder data files */ + if (!strcmp(dp->d_name, ".DS_Store") || + !strcmp(dp->d_name, "._.DS_Store")) + continue; +#endif strcpy (p, dp->d_name); if (n_dirs > 0) { @@ -227,14 +211,16 @@ int rel; /* if true, prepend "../" to fn before using */ (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) continue; - if (!strcmp (dp->d_name, "RCS")) - continue; - if (!strcmp (dp->d_name, "SCCS")) - continue; - if (!strcmp (dp->d_name, "CVS")) - continue; - if (!strcmp (dp->d_name, "CVS.adm")) - continue; + if (!with_revinfo) { + if (!strcmp (dp->d_name, "RCS")) + continue; + if (!strcmp (dp->d_name, "SCCS")) + continue; + if (!strcmp (dp->d_name, "CVS")) + continue; + if (!strcmp (dp->d_name, "CVS.adm")) + continue; + } ocurdir = rcurdir; rcurdir = buf; curdir = silent ? buf : (char *)0; @@ -283,10 +269,58 @@ int rel; /* if true, prepend "../" to fn before using */ if (symlen >= 0) { /* Link exists in new tree. Print message if it doesn't match. */ - if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf)) + if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf, + basesymlen>=0 ? (char **) 0 : &p)) msg ("%s: %s", dp->d_name, symbuf); } else { - if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0) + char *sympath; + + if (basesymlen>=0) { + if ((buf[0] == '.') && (buf[1] == '.') && (buf[2] == '/') && + (basesym[0] == '.') && (basesym[1] == '.') && + (basesym[2] == '/')) { + /* It becomes very tricky here. We have + ../../bar/foo symlinked to ../xxx/yyy. We + can't just use ../xxx/yyy. We have to use + ../../bar/foo/../xxx/yyy. */ + + int i; + char *start, *end; + + strcpy (symbuf, buf); + /* Find the first char after "../" in symbuf. */ + start = symbuf; + do { + start += 3; + } while ((start[0] == '.') && (start[1] == '.') && + (start[2] == '/')); + + /* Then try to eliminate "../"s in basesym. */ + i = 0; + end = strrchr (symbuf, '/'); + if (start < end) { + do { + i += 3; + end--; + while ((*end != '/') && (end != start)) + end--; + if (end == start) + break; + } while ((basesym[i] == '.') && + (basesym[i + 1] == '.') && + (basesym[i + 2] == '/')); + } + if (*end == '/') + end++; + strcpy (end, &basesym[i]); + sympath = symbuf; + } + else + sympath = basesym; + } + else + sympath = buf; + if (symlink (sympath, dp->d_name) < 0) mperror (dp->d_name); } } @@ -295,10 +329,8 @@ int rel; /* if true, prepend "../" to fn before using */ return 0; } - -main (ac, av) -int ac; -char **av; +int +main (int ac, char *av[]) { char *prog_name = av[0]; char *fn, *tn; @@ -309,6 +341,8 @@ char **av; silent = 1; else if (strcmp(*av, "-ignorelinks") == 0) ignore_links = 1; + else if (strcmp(*av, "-withrevinfo") == 0) + with_revinfo = 1; else if (strcmp(*av, "--") == 0) { ++av, --ac; break; @@ -24,7 +24,10 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .\" -.TH LNDIR 1 "Release 6.4" "X Version 11" +.\" +.\" $XFree86: xc/config/util/lndir.man,v 1.4 2002/10/07 15:28:51 tsi Exp $ +.\" +.TH LNDIR 1 __xorgversion__ .SH NAME lndir \- create a shadow directory of symbolic links to another directory tree .SH SYNOPSIS @@ -33,6 +36,8 @@ lndir \- create a shadow directory of symbolic links to another directory tree .B \-silent ] [ .B \-ignorelinks +] [ +.B \-withrevinfo ] .I \|fromdir\| [ @@ -71,7 +76,8 @@ argument may be relative (e.g., ../src) and is relative to (not the current directory). .PP .\" CVS.adm is used by the Concurrent Versions System. -Note that RCS, SCCS, CVS and CVS.adm directories are not shadowed. +Note that RCS, SCCS, CVS and CVS.adm directories are shadowed only if +the \fB\-withrevinfo\fP flag is specified. .PP If you add files, simply run .I lndir @@ -98,6 +104,9 @@ If the link is to a directory, this is almost certainly the wrong thing. .IP This option exists mostly to emulate the behavior the C version of \fIlndir\fP had in X11R6. Its use is not recommended. +.IP \-withrevinfo +Causes any RCS, SCCS, CVS and CVS.adm subdirectories to be treated as any other +directory, rather than ignored. .SH DIAGNOSTICS The program displays the name of each subdirectory it enters, followed by a colon. The \fB\-silent\fP option suppresses these messages. @@ -108,20 +117,3 @@ exists. .PP If the link already exists but doesn't point to the correct file, the program prints the link name and the location where it does point. -.SH BUGS -The -.I patch -program gets upset if it cannot change the files. You should never run -.I patch -from a shadow directory anyway. -.PP -You need to use something like -.nf - find todir \|\-type l \|\-print \||\| xargs rm -.fi -to clear out all files before you can relink (if fromdir moved, for instance). -Something like -.nf - find . \|\\! \|\-type d \|\-print -.fi -will find all files that are not directories. |