|
Packit |
b099d7 |
/* $TOG: lndir.c /main/17 1998/02/06 11:23:50 kaleb $ */
|
|
Packit |
b099d7 |
/* Create shadow link tree (after X11R4 script of the same name)
|
|
Packit |
b099d7 |
Mark Reinhold (mbr@lcs.mit.edu)/3 January 1990 */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* From the original /bin/sh script:
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Used to create a copy of the a directory tree that has links for all
|
|
Packit |
b099d7 |
non-directories (except those named RCS, SCCS or CVS.adm). If you are
|
|
Packit |
b099d7 |
building the distribution on more than one machine, you should use
|
|
Packit |
b099d7 |
this technique.
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
If your master sources are located in /usr/local/src/X and you would like
|
|
Packit |
b099d7 |
your link tree to be in /usr/local/src/new-X, do the following:
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
% mkdir /usr/local/src/new-X
|
|
Packit |
b099d7 |
% cd /usr/local/src/new-X
|
|
Packit |
b099d7 |
% lndir ../X
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <X11/Xos.h>
|
|
Packit |
b099d7 |
#include <X11/Xfuncproto.h>
|
|
Packit |
b099d7 |
#include <stdio.h>
|
|
Packit |
b099d7 |
#include <sys/stat.h>
|
|
Packit |
b099d7 |
#include <sys/param.h>
|
|
Packit |
b099d7 |
#include <errno.h>
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifndef X_NOT_POSIX
|
|
Packit |
b099d7 |
#include <dirent.h>
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
#ifdef SYSV
|
|
Packit |
b099d7 |
#include <dirent.h>
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
#ifdef USG
|
|
Packit |
b099d7 |
#include <dirent.h>
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
#include <sys/dir.h>
|
|
Packit |
b099d7 |
#ifndef dirent
|
|
Packit |
b099d7 |
#define dirent direct
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#ifndef MAXPATHLEN
|
|
Packit |
b099d7 |
#define MAXPATHLEN 2048
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
#include <stdarg.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef X_NOT_STDC_ENV
|
|
Packit |
b099d7 |
extern int errno;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
int silent = 0; /* -silent */
|
|
Packit |
b099d7 |
int ignore_links = 0; /* -ignorelinks */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
char *rcurdir;
|
|
Packit |
b099d7 |
char *curdir;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
quit (
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
int code, char * fmt, ...)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
code, fmt, a1, a2, a3)
|
|
Packit |
b099d7 |
char *fmt;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
va_list args;
|
|
Packit |
b099d7 |
va_start(args, fmt);
|
|
Packit |
b099d7 |
vfprintf (stderr, fmt, args);
|
|
Packit |
b099d7 |
va_end(args);
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
fprintf (stderr, fmt, a1, a2, a3);
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
putc ('\n', stderr);
|
|
Packit |
b099d7 |
exit (code);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
quiterr (code, s)
|
|
Packit |
b099d7 |
char *s;
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
perror (s);
|
|
Packit |
b099d7 |
exit (code);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
msg (
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
char * fmt, ...)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
fmt, a1, a2, a3)
|
|
Packit |
b099d7 |
char *fmt;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
va_list args;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
if (curdir) {
|
|
Packit |
b099d7 |
fprintf (stderr, "%s:\n", curdir);
|
|
Packit |
b099d7 |
curdir = 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
#if NeedVarargsPrototypes
|
|
Packit |
b099d7 |
va_start(args, fmt);
|
|
Packit |
b099d7 |
vfprintf (stderr, fmt, args);
|
|
Packit |
b099d7 |
va_end(args);
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
fprintf (stderr, fmt, a1, a2, a3);
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
putc ('\n', stderr);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
mperror (s)
|
|
Packit |
b099d7 |
char *s;
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (curdir) {
|
|
Packit |
b099d7 |
fprintf (stderr, "%s:\n", curdir);
|
|
Packit |
b099d7 |
curdir = 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
perror (s);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
int equivalent(lname, rname)
|
|
Packit |
b099d7 |
char *lname;
|
|
Packit |
b099d7 |
char *rname;
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
char *s;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!strcmp(lname, rname))
|
|
Packit |
b099d7 |
return 1;
|
|
Packit |
b099d7 |
for (s = lname; *s && (s = strchr(s, '/')); s++) {
|
|
Packit |
b099d7 |
while (s[1] == '/')
|
|
Packit |
b099d7 |
strcpy(s+1, s+2);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return !strcmp(lname, rname);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Recursively create symbolic links from the current directory to the "from"
|
|
Packit |
b099d7 |
directory. Assumes that files described by fs and ts are directories. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
dodir (fn, fs, ts, rel)
|
|
Packit |
b099d7 |
char *fn; /* name of "from" directory, either absolute or
|
|
Packit |
b099d7 |
relative to cwd */
|
|
Packit |
b099d7 |
struct stat *fs, *ts; /* stats for the "from" directory and cwd */
|
|
Packit |
b099d7 |
int rel; /* if true, prepend "../" to fn before using */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
DIR *df;
|
|
Packit |
b099d7 |
struct dirent *dp;
|
|
Packit |
b099d7 |
char buf[MAXPATHLEN + 1], *p;
|
|
Packit |
b099d7 |
char symbuf[MAXPATHLEN + 1];
|
|
Packit |
b099d7 |
char basesym[MAXPATHLEN + 1];
|
|
Packit |
b099d7 |
struct stat sb, sc;
|
|
Packit |
b099d7 |
int n_dirs;
|
|
Packit |
b099d7 |
int symlen;
|
|
Packit |
b099d7 |
int basesymlen = -1;
|
|
Packit |
b099d7 |
char *ocurdir;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if ((fs->st_dev == ts->st_dev) && (fs->st_ino == ts->st_ino)) {
|
|
Packit |
b099d7 |
msg ("%s: From and to directories are identical!", fn);
|
|
Packit |
b099d7 |
return 1;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (rel)
|
|
Packit |
b099d7 |
strcpy (buf, "../");
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
buf[0] = '\0';
|
|
Packit |
b099d7 |
strcat (buf, fn);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!(df = opendir (buf))) {
|
|
Packit |
b099d7 |
msg ("%s: Cannot opendir", buf);
|
|
Packit |
b099d7 |
return 1;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
p = buf + strlen (buf);
|
|
Packit |
b099d7 |
*p++ = '/';
|
|
Packit |
b099d7 |
n_dirs = fs->st_nlink;
|
|
Packit |
b099d7 |
while (dp = readdir (df)) {
|
|
Packit |
b099d7 |
if (dp->d_name[strlen(dp->d_name) - 1] == '~')
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
strcpy (p, dp->d_name);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (n_dirs > 0) {
|
|
Packit |
b099d7 |
if (stat (buf, &sb) < 0) {
|
|
Packit |
b099d7 |
mperror (buf);
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef S_ISDIR
|
|
Packit |
b099d7 |
if(S_ISDIR(sb.st_mode))
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
if (sb.st_mode & S_IFDIR)
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* directory */
|
|
Packit |
b099d7 |
n_dirs--;
|
|
Packit |
b099d7 |
if (dp->d_name[0] == '.' &&
|
|
Packit |
b099d7 |
(dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
|
|
Packit |
b099d7 |
dp->d_name[2] == '\0')))
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
if (!strcmp (dp->d_name, "RCS"))
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
if (!strcmp (dp->d_name, "SCCS"))
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
if (!strcmp (dp->d_name, "CVS"))
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
if (!strcmp (dp->d_name, "CVS.adm"))
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
ocurdir = rcurdir;
|
|
Packit |
b099d7 |
rcurdir = buf;
|
|
Packit |
b099d7 |
curdir = silent ? buf : (char *)0;
|
|
Packit |
b099d7 |
if (!silent)
|
|
Packit |
b099d7 |
printf ("%s:\n", buf);
|
|
Packit |
b099d7 |
if ((stat (dp->d_name, &sc) < 0) && (errno == ENOENT)) {
|
|
Packit |
b099d7 |
if (mkdir (dp->d_name, 0777) < 0 ||
|
|
Packit |
b099d7 |
stat (dp->d_name, &sc) < 0) {
|
|
Packit |
b099d7 |
mperror (dp->d_name);
|
|
Packit |
b099d7 |
curdir = rcurdir = ocurdir;
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (readlink (dp->d_name, symbuf, sizeof(symbuf) - 1) >= 0) {
|
|
Packit |
b099d7 |
msg ("%s: is a link instead of a directory", dp->d_name);
|
|
Packit |
b099d7 |
curdir = rcurdir = ocurdir;
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (chdir (dp->d_name) < 0) {
|
|
Packit |
b099d7 |
mperror (dp->d_name);
|
|
Packit |
b099d7 |
curdir = rcurdir = ocurdir;
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
dodir (buf, &sb, &sc, (buf[0] != '/'));
|
|
Packit |
b099d7 |
if (chdir ("..") < 0)
|
|
Packit |
b099d7 |
quiterr (1, "..");
|
|
Packit |
b099d7 |
curdir = rcurdir = ocurdir;
|
|
Packit |
b099d7 |
continue;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* non-directory */
|
|
Packit |
b099d7 |
symlen = readlink (dp->d_name, symbuf, sizeof(symbuf) - 1);
|
|
Packit |
b099d7 |
if (symlen >= 0)
|
|
Packit |
b099d7 |
symbuf[symlen] = '\0';
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* The option to ignore links exists mostly because
|
|
Packit |
b099d7 |
checking for them slows us down by 10-20%.
|
|
Packit |
b099d7 |
But it is off by default because this really is a useful check. */
|
|
Packit |
b099d7 |
if (!ignore_links) {
|
|
Packit |
b099d7 |
/* see if the file in the base tree was a symlink */
|
|
Packit |
b099d7 |
basesymlen = readlink(buf, basesym, sizeof(basesym) - 1);
|
|
Packit |
b099d7 |
if (basesymlen >= 0)
|
|
Packit |
b099d7 |
basesym[basesymlen] = '\0';
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (symlen >= 0) {
|
|
Packit |
b099d7 |
/* Link exists in new tree. Print message if it doesn't match. */
|
|
Packit |
b099d7 |
if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf))
|
|
Packit |
b099d7 |
msg ("%s: %s", dp->d_name, symbuf);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0)
|
|
Packit |
b099d7 |
mperror (dp->d_name);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
closedir (df);
|
|
Packit |
b099d7 |
return 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
main (ac, av)
|
|
Packit |
b099d7 |
int ac;
|
|
Packit |
b099d7 |
char **av;
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
char *prog_name = av[0];
|
|
Packit |
b099d7 |
char *fn, *tn;
|
|
Packit |
b099d7 |
struct stat fs, ts;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (++av, --ac) {
|
|
Packit |
b099d7 |
if (strcmp(*av, "-silent") == 0)
|
|
Packit |
b099d7 |
silent = 1;
|
|
Packit |
b099d7 |
else if (strcmp(*av, "-ignorelinks") == 0)
|
|
Packit |
b099d7 |
ignore_links = 1;
|
|
Packit |
b099d7 |
else if (strcmp(*av, "--") == 0) {
|
|
Packit |
b099d7 |
++av, --ac;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ac < 1 || ac > 2)
|
|
Packit |
b099d7 |
quit (1, "usage: %s [-silent] [-ignorelinks] fromdir [todir]",
|
|
Packit |
b099d7 |
prog_name);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
fn = av[0];
|
|
Packit |
b099d7 |
if (ac == 2)
|
|
Packit |
b099d7 |
tn = av[1];
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
tn = ".";
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* to directory */
|
|
Packit |
b099d7 |
if (stat (tn, &ts) < 0)
|
|
Packit |
b099d7 |
quiterr (1, tn);
|
|
Packit |
b099d7 |
#ifdef S_ISDIR
|
|
Packit |
b099d7 |
if (!(S_ISDIR(ts.st_mode)))
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
if (!(ts.st_mode & S_IFDIR))
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
quit (2, "%s: Not a directory", tn);
|
|
Packit |
b099d7 |
if (chdir (tn) < 0)
|
|
Packit |
b099d7 |
quiterr (1, tn);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* from directory */
|
|
Packit |
b099d7 |
if (stat (fn, &fs) < 0)
|
|
Packit |
b099d7 |
quiterr (1, fn);
|
|
Packit |
b099d7 |
#ifdef S_ISDIR
|
|
Packit |
b099d7 |
if (!(S_ISDIR(fs.st_mode)))
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
if (!(fs.st_mode & S_IFDIR))
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
quit (2, "%s: Not a directory", fn);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
exit (dodir (fn, &fs, &ts, 0));
|
|
Packit |
b099d7 |
}
|