summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lndir.c162
-rw-r--r--lndir.man30
2 files changed, 109 insertions, 83 deletions
diff --git a/lndir.c b/lndir.c
index 470c432..05b5df5 100644
--- a/lndir.c
+++ b/lndir.c
@@ -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;
diff --git a/lndir.man b/lndir.man
index 4821021..73abfcb 100644
--- a/lndir.man
+++ b/lndir.man
@@ -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.