From: sof Date: Wed, 3 Sep 1997 23:28:17 +0000 (+0000) Subject: [project @ 1997-09-03 23:28:17 by sof] X-Git-Tag: Approximately_1000_patches_recorded~72 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=d90a4ecc6620ddd78e7f376aa3752aa83f0881e1 [project @ 1997-09-03 23:28:17 by sof] Upgraded to util shipped with X11R6.3 --- diff --git a/glafp-utils/lndir/lndir.c b/glafp-utils/lndir/lndir.c index a932ae5..da8a467 100644 --- a/glafp-utils/lndir/lndir.c +++ b/glafp-utils/lndir/lndir.c @@ -1,29 +1,42 @@ -/* $XConsortium: lndir.c,v 1.5 91/07/21 15:52:11 rws Exp $ */ +/* $XConsortium: lndir.c /main/16 1996/09/28 16:16:40 rws $ */ /* Create shadow link tree (after X11R4 script of the same name) Mark Reinhold (mbr@lcs.mit.edu)/3 January 1990 */ -/* Copyright 1990, Massachusetts Institute of Technology - - Permission to use, copy, modify, and distribute this program for any purpose - and without fee is hereby granted, provided that this copyright and - permission notice appear on all copies and supporting documentation, that - the name of MIT not be used in advertising or publicity pertaining to - distribution of this program without specific prior permission, and that - notice be given in supporting documentation that copying and distribution is - by permission of MIT. MIT makes no representations about the suitability of - this software for any purpose. It is provided "as is" without expressed or - implied warranty. +/* +Copyright (c) 1990, X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + */ /* 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 or SCCS). If you are - building the distribution on more than one machine, you should use - this 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. - 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: + 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: % mkdir /usr/local/src/new-X % cd /usr/local/src/new-X @@ -52,43 +65,109 @@ #endif #endif #endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 2048 +#endif +#if NeedVarargsPrototypes +#include +#endif + +#ifdef X_NOT_STDC_ENV extern int errno; -int silent; +#endif +int silent = 0; /* -silent */ +int ignore_links = 0; /* -ignorelinks */ + +char *rcurdir; +char *curdir; void -quit (code, fmt, a1, a2, a3) -char *fmt; -int code, a1, a2, a3; /* partain */ +quit ( +#if NeedVarargsPrototypes + int code, char * fmt, ...) +#else + code, fmt, a1, a2, a3) + char *fmt; +#endif { +#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; -int code; /* partain */ + char *s; { perror (s); exit (code); } void -msg (fmt, a1, a2, a3) -char *fmt; -int a1, a2, a3; /* partain */ +msg ( +#if NeedVarargsPrototypes + char * fmt, ...) +#else + fmt, a1, a2, a3) + char *fmt; +#endif { +#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; +{ + if (curdir) { + fprintf (stderr, "%s:\n", curdir); + curdir = 0; + } + perror (s); +} + + +int equivalent(lname, rname) + char *lname; + char *rname; +{ + char *s; + + if (!strcmp(lname, rname)) + return 1; + for (s = lname; *s && (s = strchr(s, '/')); s++) { + while (s[1] == '/') + strcpy(s+1, s+2); + } + return !strcmp(lname, rname); +} + /* Recursively create symbolic links from the current directory to the "from" directory. Assumes that files described by fs and ts are directories. */ -int dodir (fn, fs, ts, rel) char *fn; /* name of "from" directory, either absolute or relative to cwd */ @@ -99,8 +178,12 @@ int rel; /* if true, prepend "../" to fn before using */ struct dirent *dp; char buf[MAXPATHLEN + 1], *p; char symbuf[MAXPATHLEN + 1]; + char basesym[MAXPATHLEN + 1]; struct stat sb, sc; int n_dirs; + int symlen; + int basesymlen = -1; + char *ocurdir; if ((fs->st_dev == ts->st_dev) && (fs->st_ino == ts->st_ino)) { msg ("%s: From and to directories are identical!", fn); @@ -122,61 +205,89 @@ int rel; /* if true, prepend "../" to fn before using */ *p++ = '/'; n_dirs = fs->st_nlink; while (dp = readdir (df)) { + if (dp->d_name[strlen(dp->d_name) - 1] == '~') + continue; strcpy (p, dp->d_name); if (n_dirs > 0) { if (stat (buf, &sb) < 0) { - perror (buf); + mperror (buf); continue; } - if (sb.st_mode & S_IFDIR) { +#ifdef S_ISDIR + if(S_ISDIR(sb.st_mode)) +#else + if (sb.st_mode & S_IFDIR) +#endif + { /* directory */ n_dirs--; if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) continue; - if (!strcmp (dp->d_name, "CVS")) /* partain */ - 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; + ocurdir = rcurdir; + rcurdir = buf; + curdir = silent ? buf : (char *)0; if (!silent) printf ("%s:\n", buf); if ((stat (dp->d_name, &sc) < 0) && (errno == ENOENT)) { if (mkdir (dp->d_name, 0777) < 0 || stat (dp->d_name, &sc) < 0) { - perror (dp->d_name); + mperror (dp->d_name); + curdir = rcurdir = ocurdir; continue; } } if (readlink (dp->d_name, symbuf, sizeof(symbuf) - 1) >= 0) { - msg ("%s: is a link instead of a directory\n", dp->d_name); + msg ("%s: is a link instead of a directory", dp->d_name); + curdir = rcurdir = ocurdir; continue; } if (chdir (dp->d_name) < 0) { - perror (dp->d_name); + mperror (dp->d_name); + curdir = rcurdir = ocurdir; continue; } dodir (buf, &sb, &sc, (buf[0] != '/')); if (chdir ("..") < 0) quiterr (1, ".."); + curdir = rcurdir = ocurdir; continue; } } /* non-directory */ - if (symlink (buf, dp->d_name) < 0) { - int saverrno = errno; - int symlen; - symlen = readlink(dp->d_name, symbuf, sizeof(symbuf) - 1); - errno = saverrno; - if (symlen > 0) - symbuf[symlen] = '\0'; - if (symlen < 0 || strcmp(symbuf, buf)) - perror (dp->d_name); + symlen = readlink (dp->d_name, symbuf, sizeof(symbuf) - 1); + if (symlen >= 0) + symbuf[symlen] = '\0'; + + /* The option to ignore links exists mostly because + checking for them slows us down by 10-20%. + But it is off by default because this really is a useful check. */ + if (!ignore_links) { + /* see if the file in the base tree was a symlink */ + basesymlen = readlink(buf, basesym, sizeof(basesym) - 1); + if (basesymlen >= 0) + basesym[basesymlen] = '\0'; + } + + if (symlen >= 0) { + /* Link exists in new tree. Print message if it doesn't match. */ + if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf)) + msg ("%s: %s", dp->d_name, symbuf); + } else { + if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0) + mperror (dp->d_name); } } @@ -184,31 +295,46 @@ int rel; /* if true, prepend "../" to fn before using */ return 0; } -void + main (ac, av) int ac; char **av; { + char *prog_name = av[0]; char *fn, *tn; struct stat fs, ts; - silent = 0; - if (ac > 1 && !strcmp(av[1], "-silent")) { - silent = 1; + while (++av, --ac) { + if (strcmp(*av, "-silent") == 0) + silent = 1; + else if (strcmp(*av, "-ignorelinks") == 0) + ignore_links = 1; + else if (strcmp(*av, "--") == 0) { + ++av, --ac; + break; + } + else + break; } - 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]; + if (ac < 1 || ac > 2) + quit (1, "usage: %s [-silent] [-ignorelinks] fromdir [todir]", + prog_name); + + fn = av[0]; + if (ac == 2) + tn = av[1]; else tn = "."; /* to directory */ if (stat (tn, &ts) < 0) quiterr (1, tn); +#ifdef S_ISDIR + if (!(S_ISDIR(ts.st_mode))) +#else if (!(ts.st_mode & S_IFDIR)) +#endif quit (2, "%s: Not a directory", tn); if (chdir (tn) < 0) quiterr (1, tn); @@ -216,7 +342,11 @@ char **av; /* from directory */ if (stat (fn, &fs) < 0) quiterr (1, fn); +#ifdef S_ISDIR + if (!(S_ISDIR(fs.st_mode))) +#else if (!(fs.st_mode & S_IFDIR)) +#endif quit (2, "%s: Not a directory", fn); exit (dodir (fn, &fs, &ts, 0));