summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2004-12-06 21:41:16 +0000
committerSteve Huston <shuston@riverace.com>2004-12-06 21:41:16 +0000
commit238910d2876bf2532544ab26ecbc6ed22b5be99c (patch)
treea24c06cdf11c21915539b7fcf4900e2f45e64bfd
parent5764dbe1796d332605b0d8f41977eed99a7e50c5 (diff)
downloadATCD-238910d2876bf2532544ab26ecbc6ed22b5be99c.tar.gz
ChangeLogTag:Mon Dec 6 16:34:29 2004 Steve Huston <shuston@riverace.com>
-rw-r--r--ACE-INSTALL.html60
-rw-r--r--ChangeLog13
-rw-r--r--bin/clone.1297
-rw-r--r--bin/clone.cpp982
4 files changed, 28 insertions, 1324 deletions
diff --git a/ACE-INSTALL.html b/ACE-INSTALL.html
index 948d7c9c232..25c9af87ebe 100644
--- a/ACE-INSTALL.html
+++ b/ACE-INSTALL.html
@@ -2642,37 +2642,25 @@ that for entry points named <code>main</code>.
On UNIX platforms, we typically like to support multiple platform
builds using the same ACE source tree. This idiom is supported by ACE
-using the $ACE_ROOT/bin/create_ace_build.pl script or
-$ACE_ROOT/bin/clone.cpp program.
-
-To use build and use the clone program, first make sure there's a file
-called <code>platform_macros.GNU</code> that contains the correct platform-specific
-Makefile configurations in the <code>$ACE_ROOT/include/makeinclude/</code>
-directory, as well as making sure there's a $ACE_ROOT/ace/config.h
-file that includes the desired platform/compiler specific
-configuration header. Then perform the following steps:<p>
-
-</p><pre>% cd $ACE_ROOT/bin
-% make -f GNUmakefile.clone
-% mv clone ~/bin
-% rehash
-</pre><p>
-
-Then create a ./build subdirectory someplace, e.g., under $ACE_ROOT.
-Once this is done, then invoke the top-level Makefile with the
-"clone" target, e.g.:</p><p>
-
-</p><pre>% cd $ACE_ROOT
-% mkdir build-SunOS5
-% cd build-SunOS5
-% make -f ../Makefile clone
+using the $ACE_ROOT/bin/create_ace_build.pl script.
+
+To clone the source tree, create ./build and ./build/{your build name}
+subdirectories under the ACE_wrappers directory.
+Then invoke the create_ace_build.pl script to clone the source tree using
+soft links from your build directory back to the actual sources.
+Here is an example:</p><p>
+
+</p><pre>% cd ACE_wrappers
+% mkdir build build/build-SunOS5
+% perl bin/create_ace_build.pl -a -v build-SunOS5
+% cd build/build-SunOS5
% setenv ACE_ROOT $cwd
% make
</pre><p>
This will establish a complete tree of links. In addition, make sure
you set your <code>LD_LIBRARY_PATH</code> to
-<code>$ACE_ROOT/ace:$ACE_ROOT/lib:$LD_LIBRARY_PATH</code> on SVR4 UNIX
+<code>$ACE_ROOT/lib:$LD_LIBRARY_PATH</code> on SVR4 UNIX
platforms.</p><p>
When you do a make in the $ACE_ROOT directory you will be producing
@@ -2680,26 +2668,8 @@ object code that is not stored in the same place as the original
source tree. This way, you can easily build another platform in a
parallel tree structure.</p><p>
-<b> VERY IMPORTANT! </b></p><p>
-
-If you use the "clone trick" discussed above, make sure that the
-symbolic links are correctly in place before starting the build. In
-particular, if you plan to clone the tree, it is preferable to do so
-before you start a build procedure on the original tree. This is
-because the build procedure create object directories (.obj and
-.shobj) and the cloning procedure will clone these directories also.
-You would end up with links pointing to object files of another
-platform. If you clone the tree after you've done a build on the
-original tree, make sure to remove all ".obj", ".shobj" and (any other
-files or directories) in all subdirectories before starting the build
-on your cloned tree.</p><p>
-
-Alternatively, the perl script
-<code>ACE_wrappers/bin/create_ace_build.pl</code> can be used to create
-build trees. It creates them below <code>ACE_wrappers/build</code>.
-It filters out all but the necessary files, so the warning above does
-not apply. See the comments at the top of the script itself for usage
-information.
+See the comments at the top of the create_ace_build.pl script for
+further usage information.
</p><p></p><hr align="left" width="50%"><p>
</p><h4><a name="mvs">Additional Build Tips for MVS</a></h4>
diff --git a/ChangeLog b/ChangeLog
index 05e6afc1479..3613e0fb55e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Mon Dec 6 16:34:29 2004 Steve Huston <shuston@riverace.com>
+
+ * ACE-INSTALL.html: Removed mention and instructions for the 'clone'
+ program. Favor use of bin/create_ace_build.pl since it is more
+ reliable, simpler, doesn't rely on Makefile content that's not
+ there, and doesn't need to be built first.
+
+ * bin/clone.1:
+ * bin/clone.cpp: Removed; this program has been superseded by the
+ bin/create_ace_build.pl script. See ACE-INSTALL.html for details.
+
+ Thanks to Neil Cohen <nbc@cisco.com> for bringing this up.
+
Mon Dec 6 10:46:02 2004 Chad Elliott <elliott_c@ociweb.com>
* examples/APG/Threads/Guards.cpp:
diff --git a/bin/clone.1 b/bin/clone.1
deleted file mode 100644
index 7c36d90fd85..00000000000
--- a/bin/clone.1
+++ /dev/null
@@ -1,297 +0,0 @@
-.TH CLONE 1 "6 June 1989" ""
-.SH NAME
-clone \- make a clone of an entire directory tree
-.SH SYNOPSIS
-.B clone
-[
-.B -q
-] [
-.B -v
-] [
-.B -f
-] [
-.B -c | -s
-] [
-.B -S
-]
-.I "dir1 dir2"
-.SH DESCRIPTION
-.I Clone
-makes an identical copy of an entire (source) directory tree rooted at
-the directory named
-.I dir1
-into the (target) directory tree
-rooted at
-.I dir2.
-The target directory
-.I dir2
-will be created if it does not already exist.
-On the other hand, if the directory
-.I dir2
-exists, or if the
-.I dir2
-directory has any existing subdirectories, then these
-directories will
-.B not
-be deleted or replaced by
-.I clone.
-.PP
-.I Clone
-normally creates the clone
-directory tree by creating any new directories needed
-beneath
-.I dir2
-(possibly including
-.I dir2
-itself).
-.I Clone
-then fills in the new directories with hard links
-to all of the files in the original (source) directory tree
-.I dir1
-such that the new (target) directory tree appears to also contain
-all of the files and subdirectories contained in the original (source)
-directory tree.
-Hard links are normally used when creating
-.I clones
-of the files in the source directory tree
-inside the new (target) directory tree.
-This insures that the cost (in disk space) of
-.I cloning
-a given source directory tree will be very low.
-If desired, the new (clone) directory tree can be filled in with
-symbolic links or with actual copies of the original files (instead of
-using hard links).
-.PP
-.I Clone
-may be particularly useful for maintaining multiple versions
-of nearly identical source trees.
-.PP
-An important feature of
-.I clone
-is that the
-.I dir2
-argument may already exist and may already contain some
-files and subdirectories. In such cases,
-.I clone
-does not disturb these existing files or subdirectories.
-Rather, it simply adds the material from the source directory,
-.I dir1,
-to the material already present within
-.I dir2.
-In cases where
-there are conflicts between files or directories which
-already exist in
-.I dir2
-but which also exist in
-.I dir1,
-.I clone
-(by default) leaves the files or directories in the target directory
-.I dir2
-untouched unless the
-.B -f
-(force) flag is used, in which case,
-.I clone
-will override (i.e. delete) the conflicting entries
-from the target directory
-.I dir2
-and replace them with clones from the source directory
-.I dir1.
-.SH OPTIONS
-.I Clone
-recognizes the following options:
-.TP
-.BI \-q
-Quite mode. Suppress all warnings and non-fatal error messages.
-.TP
-.BI \-v
-Verbose mode. Print verbose messages which describe each individual
-linking (or copying) action, as well as all
-.I mkdir
-actions that
-.I clone
-executes.
-.TP
-.BI \-f
-Force mode. In cases where an item (i.e. either a file or a directory)
-exists in the source directory tree
-.I dir1,
-and also already exists in the target directory tree
-.I dir2,
-delete the item (ether a file or a directory) in
-the target directory tree and then replace it with a clone
-of the corresponding item from the source directory tree.
-All such deletions causes warning to be issued to
-.I stderr
-unless the
-.B \-q
-(quite mode)
-option is also specified.
-Note that if a given item already exists in the target directory tree,
-and if it also exists in the source directory tree, and if both the
-(existing) source and target items are themselves directories, then the
-.B \-f
-option has no effect for these items. Existing directories in the
-target directory tree are never deleted by
-.I clone
-unless there is a corresponding item in the source directory tree which is
-.B not
-a directory (i.e. is a regular file) and the
-.B \-f
-option is in effect.
-.TP
-.BI \-s
-Symbolic link mode (not available on System V). When used, this
-option causes all non-directory files to be
-.I cloned
-by making symbolic links from the target directory tree into the source
-directory tree. This mode overrides the default mode in which
-hard links are used to clone all non-directory files.
-.TP
-.BI \-c
-Copy mode.
-In this mode, a physical copy of each non-directory file in the source directory
-tree is created in the target directory tree. Note that when this mode is used,
-it is an error for the source directory tree to contain any block or character
-device files, or any named pipe files.
-.TP
-.BI \-S
-SCCS mode.
-In this mode, only the source tree structure is cloned, not its contents.
-Symbolic links are created within the destination tree to subdirectories
-in the source tree named
-.B SCCS.
-This mode is useful when multiple developers work from a common SCCS project
-tree. To accomplish this, each developer creates a local project tree by
-.I cloning
-the common SCCS project directory, specifying the
-.B \-S
-option.
-Individual developers are then able to work within their local project tree while
-ensuring that all SCCS operations are applied to the common SCCS project tree.
-Use of the
-.B \-S
-option implies the use of the
-.B \-s
-option and is thus not available on System V.
-.SH EXAMPLES
-Assume that you have
-two directory trees called
-.I src1
-and
-.I src2
-and that you wish to combine the contents of these
-two directories into a new directory named
-.I dst
-such that if there are any files with duplicate names in both
-.I src1
-and in
-.I src2
-the files from the
-.I src2
-directory tree will take precedence
-over the corresponding files in the directory tree
-.I src1.
-The following commands would accomplish this task:
-.sp 1
-.in +0.4i
-.ft B
-clone src1 dst
-.br
-clone -f src2 dst
-.sp 1
-.in -0.4i
-.ft R
-Or alternatively, for this simple case, you could have said:
-.ft B
-.in +0.4i
-.sp 1
-clone src2 dst
-.br
-clone src1 dst
-.br
-.sp 1
-.in -04.i
-.ft R
-.PP
-To clone an SCCS project tree, such as
-.B /pub/EOS_client_server,
-one might use the following command, shown with the resulting output:
-.sp 1
-.in +0.4i
-.ft B
-doc% clone -S -v /pub/EOS_client_server ~/EOS_CS
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/bin
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/lib
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/include
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/cmd
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/cmd/clone
-.br
-clone: created symlink /home/ebupsn/EOS_CS/cmd/clone/SCCS -> /pub/EOS_client_server/cmd/clone/SCCS
-.br
-clone: created symlink /home/ebupsn/EOS_CS/cmd/SCCS -> /pub/EOS_client_server/cmd/SCCS
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/man
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/man/man1
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/man/man3
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/man/cat1
-.br
-clone: created new output directory: /home/ebupsn/EOS_CS/man/cat3
-.br
-clone: created symlink /home/ebupsn/EOS_CS/SCCS -> /pub/EOS_client_server/SCCS
-.br
-.sp 1
-.in -0.4i
-.ft R
-.SH CAVEATS
-On BSD systems, if there are symbolic links in the source tree,
-the effects of
-.I cloning
-may not be what you expect.
-A symbolic link within the source tree results in the creation of an
-identical symbolic link within the destination tree.
-A warning is issued if the symbolic link is either absolute and points
-into the source directory or if the symbolic link is relative and
-points out of the source tree.
-.PP
-If the
-.B \-S
-option is in effect and the source directory is itself a symbolic link
-to a directory, the contents of the symbolic link are cloned in the
-destination directory rather than setting the destination directory
-to be an identical symbolic link.
-The rational for this is as follows.
-In networked environments, SCCS project directories are often configured
-as NFS file systems managed by an NFS auto-mount daemon.
-The NFS auto-mount daemon mounts NFS file systems in a temporary locations
-and then creates symbolic links to the temporary locations.
-Accesses to this symbolic links trigger the NFS auto-mount daemon.
-It is therefore necessary that symbolic links in the destination tree
-refer to the NFS auto-mount point symbolic link rather than to the NFS
-auto-mount point itself.
-Symbolic links within the source tree are ignored.
-.SH WARNINGS
-There are numerous possible warning and/or error messages which
-.I clone
-will issue for strange circumstances.
-These should all be self-explanatory.
-.SH FILES
-.ta 1.7i
-/usr/local/bin/clone The clone program
-.SH "SEE ALSO"
-ln(1), link(2), symlink(2), readlink(2), mkdir (1), mkdir (2)
-.SH AUTHORS
-Written by Ron Guilmette at the Microelectronics and Computer Technology
-Corporation. Current E-mail address is rfg@ics.uci.edu.
-.PP
-SCCS mode added 07-April-1993 by Paul Stephenson at Ericsson Business
-Communications. Current E-mail address is paul.stephenson@ebu.ericsson.se.
diff --git a/bin/clone.cpp b/bin/clone.cpp
deleted file mode 100644
index d05d65a1a3c..00000000000
--- a/bin/clone.cpp
+++ /dev/null
@@ -1,982 +0,0 @@
-// $Id$
-
-#include "ace/OS_NS_stdio.h"
-#include "ace/OS_NS_dirent.h"
-#include "ace/OS_NS_string.h"
-
-ACE_RCSID (bin,
- clone,
- "$Id$")
-
-#if 0
-#if defined (USG)
-#define lstat stat
-#else
-extern "C" char *getwd (char *);
-#define getcwd(str,len) (getwd(str))
-#endif
-#endif
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif
-
-#ifndef BLKDEV_IOSIZE
-#define BLKDEV_IOSIZE 1024
-#endif
-
-#ifndef linux
-extern char *sys_errlist[];
-#endif
-static void clone (char* s_path, char* d_path, int sroot_flag, int level);
-
-static char *pname;
-static int errors = 0;
-
-static char* src_path = 0;
-static char* dst_path = 0;
-
-static int quiet_flag = 0;
-static int verbose_flag = 0;
-static int force_flag = 0;
-#ifndef USG
-static int symlink_flag = 0;
-#endif
-static int copy_flag = 0;
-static int sccs_flag = 0;
-
-static void
-usage (void)
-{
-#ifdef USG
- fprintf (stderr, "%s: usage: '%s [-q][-v][-f][-c] pathname1 pathname2'\n", pname, pname);
-#else
- fprintf (stderr, "%s: usage: '%s [-q][-v][-f][-S][-c | -s | -S] pathname1 pathname2'\n", pname, pname);
-#endif
- exit (1);
-}
-
-/* abspath(): return the absolutized pathname for the given relative
- pathname. Note that if that pathname is already absolute, it may
- still be returned in a modified form because this routine also
- eliminates redundant slashes and single dots and eliminates double
- dots to get a shortest possible pathname from the given input
- pathname. The absolutization of relative pathnames is made by
- assuming that the given pathname is to be taken as relative to the
- first argument (cwd) or to the current directory if cwd is null. */
-
-static char *
-abspath (char *cwd, char *rel_pathname)
-{
- static char cwd_buffer[MAXPATHLEN + 1];
- char abs_buffer[MAXPATHLEN + 1];
- register char *endp;
- register char *p;
- register char *inp = abs_buffer;
- register char *outp = abs_buffer;
-
- /* Setup the current working directory as needed. */
-
- if (!cwd)
- {
- if (!cwd_buffer[0])
- getcwd (cwd_buffer, MAXPATHLEN);
- cwd = cwd_buffer;
- }
- else if (*cwd != '/')
- abort (); /* base path must be absolute */
-
- /* Copy the pathname (possibly preceeded by the current working
- directory name) into the absolutization buffer. */
-
- endp = abs_buffer;
- if (rel_pathname[0] != '/')
- {
- p = cwd;
- while (*endp++ = *p++)
- continue;
- *(endp-1) = '/'; /* overwrite null */
- }
- p = rel_pathname;
- while (*endp++ = *p++)
- continue;
- if (endp[-1] == '/')
- *endp = (char) 0;
-
- /* Now make a copy of abs_buffer into abs_buffer, shortening the
- pathname (by taking out slashes and dots) as we go. */
-
- *outp++ = *inp++; /* copy first slash */
- for (;;)
- {
- if (!inp[0])
- break;
- else if (inp[0] == '/' && outp[-1] == '/')
- {
- inp++;
- continue;
- }
- else if (inp[0] == '.' && outp[-1] == '/')
- {
- if (!inp[1])
- break;
- else if (inp[1] == '/')
- {
- inp += 2;
- continue;
- }
- else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
- {
- inp += (inp[2] == '/') ? 3 : 2;
- outp -= 2;
- while (outp >= abs_buffer && *outp != '/')
- outp--;
- if (outp < abs_buffer)
- {
- /* Catch cases like /.. where we try to backup to a
- point above the absolute root of the logical file
- system. */
-
- fprintf (stderr, "%s: fatal: invalid pathname: %s\n",
- pname, rel_pathname);
- exit (1);
- }
- *++outp = (char) 0;
- continue;
- }
- }
- *outp++ = *inp++;
- }
-
- /* On exit, make sure that there is a trailing null, and make sure that
- the last character of the returned string is *not* a slash. */
-
- *outp = (char) 0;
- if (outp[-1] == '/')
- *--outp = (char) 0;
-
- /* Make a copy (in the heap) of the stuff left in the absolutization
- buffer and return a pointer to the copy. */
-
- return strcpy ((char *) malloc (outp - abs_buffer + 1), abs_buffer);
-}
-
-static char*
-path_concat (const char* s1, const char* s2)
-{
- int s1_len;
- char* ret_val = (char *) malloc ((s1_len = strlen (s1)) + strlen (s2) + 2);
-
- strcpy (ret_val, s1);
- ret_val[s1_len] = '/';
- strcpy (&ret_val[s1_len+1], s2);
- return ret_val;
-}
-
-/* Decide if the given path (which may be relative to . or absolute) designa
-tes
- a point within the original "src_path" directory, and return non-zero if
-it
- does, or zero otherwise. */
-
-static int
-in_original_tree (char* other_path)
-{
- char* abs_src_path = abspath (NULL, src_path);
- char* abs_src_path_slash = path_concat (abs_src_path, "");
- char* abs_other_path = abspath (NULL, other_path);
- int ret_val = !strncmp (abs_src_path_slash, abs_other_path, strlen (abs_src_path_slash));
-
- free (abs_src_path);
- free (abs_src_path_slash);
- free (abs_other_path);
- return ret_val;
-}
-
-static void
-fix_mode (int new_mode, char* d_path)
-{
- if (chmod (d_path, new_mode))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: warning: can't chmod on output entity %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- }
-}
-
-static int
-remove_item (char* s_path, char* d_path)
-{
- struct stat dst_stat_buf;
- DIR* dirp;
- char containing_dir[MAXPATHLEN + 1];
-
- if (lstat (d_path, &dst_stat_buf) == -1)
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: cannot get status of %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- return -1;
- }
-
- /* Before wasting a lot of time sniffing at the thing we are trying to
- delete, first make sure that we have write permission into the
- directory that contains this thing. Otherwise, it is all a waste
- of time. */
-
- if (*d_path == '/')
- strcpy(containing_dir, d_path);
- else
- {
- containing_dir[0] = '.';
- containing_dir[1] = '/';
- strcpy(containing_dir+2, d_path);
- }
- *(strrchr (containing_dir, '/')) = '\0';
- if (containing_dir[0] == '\0')
- {
- containing_dir[0] = '/';
- containing_dir[1] = '\0';
- }
- if (access (containing_dir, W_OK))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: don't have write access to %s: %s\n",
- pname, containing_dir, sys_errlist[errno]);
- return -1;
- }
-
- switch (dst_stat_buf.st_mode & S_IFMT)
- {
- case S_IFDIR:
- if (access (d_path, R_OK) != 0)
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: don't have read permission for directory %s\n",
- pname, d_path);
- return -1;
- }
- if (access (d_path, X_OK) != 0)
- {
- if (!quiet_flag)
- fprintf (stderr,
- "%s: error: don't have search permission for directory %s\n",
- pname, d_path);
- return -1;
- }
- if (access (d_path, W_OK) != 0)
- {
- if (!quiet_flag)
- fprintf (stderr,
- "%s: error: don't have write permission for directory %s\n",
- pname, d_path);
- return -1;
- }
- if ((dirp = opendir (d_path)) == NULL)
- {
- if (!quiet_flag)
- fprintf (stderr,
- "%s: error: can't open directory %s for reading: %s\n",
- pname, d_path, sys_errlist[errno]);
- return -1;
- }
- for (;;)
- {
- struct dirent* dir_entry_p;
- char* new_s_path;
- char* new_d_path;
-
- if ((dir_entry_p = readdir (dirp)) == NULL)
- break;
- if (!strcmp (dir_entry_p->d_name, "."))
- continue;
- if (!strcmp (dir_entry_p->d_name, ".."))
- continue;
- new_s_path = path_concat (s_path, dir_entry_p->d_name);
- new_d_path = path_concat (d_path, dir_entry_p->d_name);
- if (remove_item (new_s_path, new_d_path))
- {
- closedir (dirp);
- return -1;
- }
- free (new_s_path);
- free (new_d_path);
- }
- closedir (dirp);
- if (rmdir (d_path))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: can't delete existing directory %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- return -1;
- }
- if (!quiet_flag)
- fprintf (stderr, "%s: removed directory %s\n",
- pname, d_path);
- break;
-
- /* Note that symbolic links can be treated just like normal files
- when the time comes for deleting them. Unlinking a symbolic link
- just deletes the link and *not* the thing it points to. */
-
- default:
- if (unlink (d_path))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: can't delete existing file %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- return -1;
- }
- if (!quiet_flag)
- fprintf (stderr, "%s: removed file %s\n",
- pname, d_path);
- break;
- }
- return 0;
-}
-
-#ifndef USG
-static void
-mk_symbolic_link (const char *s_path,
- const char *d_path,
- int level)
-{
- int result = 0;
-
- if (s_path[0] == '/' || level < 2)
- result = symlink (s_path, d_path);
- else
- {
- int len;
- char *new_s_path = (char *) malloc (len = strlen(s_path) + 3 * level);
- int i;
- char *cp = new_s_path;
-
- for (i = 0; i < level-1; i++)
- {
- strcpy (cp, "../");
- cp += 3;
- }
- strcpy (cp, s_path);
- result = symlink (new_s_path, d_path);
- }
- if (result)
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: can't symlink %s to %s: %s\n",
- pname, s_path, d_path, sys_errlist[errno]);
- }
- else
- {
- if (verbose_flag)
- fprintf (stderr, "%s: created symlink %s -> %s\n",
- pname, d_path, s_path);
- }
-}
-#endif
-
-static void
-mk_hard_link (char *s_path, char *d_path)
-{
- if (link (s_path, d_path))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: can't link %s to %s: %s\n",
- pname, s_path, d_path, sys_errlist[errno]);
- }
- else
- {
- if (verbose_flag)
- fprintf (stderr, "%s: created hard link %s = %s\n",
- pname, d_path, s_path);
- }
-}
-
-static void
-copy_file (char *s_path, char *d_path)
-{
- int input, output;
- struct stat src_stat_buf;
-
- if (lstat (s_path, &src_stat_buf) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't get status of %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input entity %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- if ((input = open (s_path, O_RDONLY, 0)) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't open input file %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- if ((output = open (d_path, O_CREAT | O_WRONLY, src_stat_buf.st_mode & 07777)) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't create output file %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- for (;;)
- {
- int rlen, wlen;
- char block_buf[BLKDEV_IOSIZE];
-
- if ((rlen = read (input, block_buf, BLKDEV_IOSIZE)) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: bad read from input file %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s was not fully copied\n",
- pname, s_path);
- }
- break;
- }
-
- if (rlen == 0)
- break;
-
- if ((wlen = write (output, block_buf, rlen)) == -1 || wlen != rlen)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: bad write to output file %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s not fully copied\n",
- pname, s_path);
- }
- break;
- }
- }
-
- close (output);
- close (input);
-
- fix_mode (src_stat_buf.st_mode & 07777, d_path);
-
- if (verbose_flag)
- fprintf (stderr, "%s: created file copy %s = %s\n",
- pname, d_path, s_path);
-}
-
-static void
-symlink_SCCS (char* s_path, char* d_path)
-{
- struct stat dst_stat_buf;
- char symlink_buf[MAXPATHLEN + 1];
- int count;
-
- if (access (d_path, F_OK)) /* Does d_path exit? */
- {
- if (errno != ENOENT)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't check accessability of %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- }
- else /* d_path exists. What is it? */
- {
- if (lstat (d_path, &dst_stat_buf) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: unable to get status of %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- if (S_ISLNK(dst_stat_buf.st_mode)) /* d_path is a symbolic link */
- {
- if ((count = readlink (d_path, symlink_buf, MAXPATHLEN)) == -1)
- {
- fprintf (stderr, "%s: error: can't read symlink %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s will be ignored\n",
- pname, s_path);
- return;
- }
- symlink_buf[count] = '\0';
-
- if (!strcmp(s_path, symlink_buf)) /* symlink = s_path. Done */
- {
- return;
- }
- else /* symlink != s_path */
- {
- if (force_flag)
- {
- if (remove_item (s_path, d_path) != 0)
- return;
- }
- else
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: Symbolic link %s already exists \
- but does not point to %s\n",
- pname, d_path, s_path);
- fprintf (stderr, "%s: input s %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- }
- }
- else /* d_path is NOT a symbolic link */
- {
- if (force_flag)
- {
- if (remove_item (s_path, d_path))
- return;
- }
- else
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: output already exists: %s\n",
- pname, d_path);
- fprintf (stderr, "%s: input %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- }
- }
-
- if (symlink (s_path, d_path))
- {
- if (!quiet_flag)
- fprintf (stderr, "%s: error: can't symlink %s to %s: %s\n",
- pname, s_path, d_path, sys_errlist[errno]);
- }
- else
- {
- if (verbose_flag)
- fprintf (stderr, "%s: created symlink %s -> %s\n",
- pname, d_path, s_path);
- }
-}
-
-static void
-clone_dir (char* s_path, char* d_path, int level)
-{
- DIR* dirp;
-
- if (access (s_path, R_OK) != 0)
- {
- if (!quiet_flag)
- {
- fprintf (stderr,
- "%s: error: don't have read permission for input directory %s\n"
-,
- pname, s_path);
- fprintf (stderr, "%s: input directory %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- if (access (s_path, X_OK) != 0)
- {
- if (!quiet_flag)
- {
- fprintf (stderr,
- "%s: error: don't have search permission for input directory %s\n",
- pname, s_path);
- fprintf (stderr, "%s: input directory %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- if ((dirp = opendir (s_path)) == NULL)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't open directory %s for reading: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input directory %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
-
- for (;;)
- {
- struct dirent* dir_entry_p;
- char* new_s_path;
- char* new_d_path;
-
- if ((dir_entry_p = readdir (dirp)) == NULL)
- break;
- if (!strcmp (dir_entry_p->d_name, "."))
- continue;
- if (!strcmp (dir_entry_p->d_name, ".."))
- continue;
-
- new_s_path = path_concat (s_path, dir_entry_p->d_name);
- new_d_path = path_concat (d_path, dir_entry_p->d_name);
-
- if (sccs_flag && !strcmp (dir_entry_p->d_name, "SCCS"))
- symlink_SCCS(new_s_path, new_d_path);
- else
- clone (new_s_path, new_d_path, 0, level+1);
-
- free (new_s_path);
- free (new_d_path);
- }
-
- closedir (dirp);
-}
-
-static void
-clone_symbolic_link (char* s_path,char* d_path)
-{
- char symlink_buf[MAXPATHLEN + 1];
- int count;
-
- if ((count = readlink (s_path, symlink_buf, MAXPATHLEN)) == -1)
- {
- fprintf (stderr, "%s: error: can't read symlink %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input file %s will be ignored\n",
- pname, s_path);
- return;
- }
- symlink_buf[count] = '\0';
-
- if (symlink_buf[0] == '/') /* symlink is absolute */
- {
- if (in_original_tree (symlink_buf))
- {
- if (!quiet_flag)
- fprintf (stderr,
- "%s: warning: absolute symlink points into source tree %s -> %s\n",
- pname, s_path, symlink_buf);
- }
- }
- else /* symlink is relative */
- {
- char* src_root_relative = path_concat (s_path, symlink_buf);
- int in_orig = in_original_tree (src_root_relative);
-
- free (src_root_relative);
- if (!in_orig)
- {
- if (!quiet_flag)
- fprintf (stderr,
- "%s: warning: relative symlink points out of source tree %s -> %s\n",
- pname, s_path, symlink_buf);
- }
- }
-
- mk_symbolic_link(symlink_buf, d_path, 0); /* Make an identical symlink. */
-}
-
-
-/* clone: clone the item designated by s_path as the new item d_path. */
-
-#define IS_DIR(STAT_BUF) (((STAT_BUF).st_mode & S_IFMT) == S_IFDIR)
-
-static void
-clone (char* s_path, char* d_path, int sroot_flag, int level)
-{
- struct stat src_stat_buf;
- struct stat dst_stat_buf;
- int dir_already_exists = 0;
- const char* intype = "file";
-
- if (lstat (s_path, &src_stat_buf) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't get status of %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input entity %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- if (sccs_flag && sroot_flag && S_ISLNK (src_stat_buf.st_mode))
- {
-
- /* If root of the source path is a symbolic link and
- SCCS cloning is enabled, clone the target of the link */
-
- if (stat(s_path, &src_stat_buf) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't get status of %s: %s\n",
- pname, s_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input entity %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- }
- if (IS_DIR (src_stat_buf))
- intype = "directory";
- if (access (d_path, 0))
- {
- if (errno != ENOENT)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't check accessability of %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input %s %s will be ignored\n",
- pname, intype, s_path);
- }
- return;
- }
- }
- else
- {
- const char* outtype = "file";
-
- if (lstat (d_path, &dst_stat_buf) == -1)
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: unable to get status of %s: %s\n"
-,
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input %s %s will be ignored\n",
- pname, intype, s_path);
- }
- return;
- }
- if (IS_DIR (dst_stat_buf))
- outtype = "directory";
- if (IS_DIR (src_stat_buf) && IS_DIR (dst_stat_buf))
- {
- dir_already_exists = -1;
-
- /* Have to make sure that we have full access to the output
- directory (at least temporarily). */
-
- chmod (d_path, (dst_stat_buf.st_mode & 07777) | 0700);
- if (access (d_path, R_OK | W_OK | X_OK) != 0)
- {
- if (!quiet_flag)
- {
- fprintf (stderr,
- "%s: error: too few permissions for existing directory %s\n",
- pname, d_path);
- fprintf (stderr, "%s: input directory %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- }
- else
- {
- if (force_flag)
- {
- if (remove_item (s_path, d_path))
- return;
- }
- else
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: output %s already exists: %s\n",
- pname, outtype, d_path);
- fprintf (stderr, "%s: input %s %s will be ignored\n",
- pname, intype, s_path);
- }
- return;
- }
- }
- }
-
- switch (src_stat_buf.st_mode & S_IFMT)
- {
- case S_IFDIR: /* Clone a directory */
-
- if (!dir_already_exists)
- {
- /* Don't let others sneak in.
- Only we can write the new directory (for now). */
-
- if (mkdir (d_path, 0700))
- {
- if (!quiet_flag)
- {
- fprintf (stderr, "%s: error: can't create output directory %s: %s\n",
- pname, d_path, sys_errlist[errno]);
- fprintf (stderr, "%s: input directory %s will be ignored\n",
- pname, s_path);
- }
- return;
- }
- if (verbose_flag)
- fprintf (stderr, "%s: created new output directory: %s\n",
- pname, d_path);
- }
-
- clone_dir(s_path, d_path, level);
-
- /* By default, output directories which existed before this
- program was executed are reset back to their original
- permissions (when we are done adding things to them). For
- output directories which are actually created by this program
- however, these have their permissions set so that they are
- essentially the same as the permissions for their corresponding
- input directories, except that the owner is given full
- permissions. */
-
- if (dir_already_exists)
- fix_mode (dst_stat_buf.st_mode & 07777, d_path);
- else
- fix_mode ((src_stat_buf.st_mode & 07777) | 0700, d_path);
- break;
-
-#ifndef USG
- case S_IFLNK: /* Clone a symbolic link */
-
- if (!sccs_flag)
- clone_symbolic_link (s_path, d_path);
- break;
-#endif
-
- default: /* Clone a normal file */
-
- if (sccs_flag)
- break;
-
-#ifndef USG
- if (symlink_flag)
- mk_symbolic_link(s_path, d_path, level);
- else
-#endif
- if (copy_flag)
- copy_file(s_path, d_path);
- else
- mk_hard_link(s_path, d_path);
-
- break;
- } /* switch */
-}
-
-int
-main (int /* argc */, char *argv[])
-{
- char **argn;
-
- pname = (pname = strrchr (argv[0], '/')) ? pname+1 : argv[0];
- for (argn = argv+1; *argn; argn++)
- {
- if (**argn != '-')
- {
- if (!src_path)
- src_path = *argn;
- else if (!dst_path)
- dst_path = *argn;
- else
- usage ();
- }
- else
- {
- switch (* ((*argn)+1))
- {
- case 0:
- fprintf (stderr, "%s: invalid option: -\n", pname);
- errors = -1;
- break;
-
- case 'q':
- quiet_flag = -1;
- break;
-
- case 'v':
- verbose_flag = -1;
- break;
-
- case 'f':
- force_flag = -1;
- break;
-
-#ifndef USG
- case 'S':
- sccs_flag = -1;
-
- if (copy_flag)
- errors++;
- break;
-#endif
-
-#ifndef USG
- case 's':
- symlink_flag = -1;
- if (copy_flag)
- errors++;
- break;
-#endif
-
- case 'c':
- copy_flag = -1;
-#ifndef USG
- if (symlink_flag)
- errors++;
-
- if (sccs_flag)
- errors++;
-#endif
- break;
-
- default:
- fprintf (stderr, "%s: invalid option: -%c\n",
- pname, *((*argn)+1));
- errors = -1;
- }
- }
- }
- if (errors || src_path == 0 || dst_path == 0)
- usage ();
-#if 0 // ndef USG
- if (symlink_flag && *src_path != '/')
- {
- fprintf (stderr, "%s: error: source root pathname must be absolute when using -s\n",
- pname);
- exit (1);
- }
-#endif
- if (access (src_path, 0) == -1)
- {
- fprintf (stderr, "%s: error: accessing source root entity %s: %s\n",
- pname, src_path, sys_errlist[errno]);
- exit (1);
- }
- umask (0); /* disable all masking */
- clone (src_path, dst_path, 1, 0);
- return 0;
-}