diff options
Diffstat (limited to 'bin/clone.cpp')
-rw-r--r-- | bin/clone.cpp | 955 |
1 files changed, 0 insertions, 955 deletions
diff --git a/bin/clone.cpp b/bin/clone.cpp deleted file mode 100644 index 6de3139eb1e..00000000000 --- a/bin/clone.cpp +++ /dev/null @@ -1,955 +0,0 @@ -#include "ace/OS.h" -// $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 - -extern char *sys_errlist[]; -static void clone (char* s_path, char* d_path, int sroot_flag); - -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 (char* s1, 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 (char *s_path, char *d_path) -{ - 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); - } -} -#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) -{ - 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; - char symlink_buf[MAXPATHLEN + 1]; - int len; - - 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); - - 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); /* 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) -{ - struct stat src_stat_buf; - struct stat dst_stat_buf; - int dir_already_exists = 0; - 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 - { - 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); - - /* 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); - 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); - return 0; -} |