Added attribute copying support to "cp" and "mv".

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8401 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-07-15 12:31:49 +00:00
parent 26c008b793
commit de44737ef7
4 changed files with 82 additions and 0 deletions
+77
View File
@@ -46,6 +46,12 @@
#include "same.h"
#include "xreadlink.h"
#if __BEOS__
# define bool bool_t
# include <fs_attr.h>
# undef bool
#endif
#define DO_CHOWN(Chown, File, New_uid, New_gid) \
(Chown (File, New_uid, New_gid) \
/* If non-root uses -p, it's ok if we can't preserve ownership. \
@@ -136,6 +142,63 @@ is_ancestor (const struct stat *sb, const struct dir_list *ancestors)
return 0;
}
static int
copy_attributes(int fromFd, int toFd)
{
struct dirent *dirent;
char buffer[65536];
DIR *attributes = fs_fopen_attr_dir(fromFd);
if (attributes == NULL)
return -1;
while ((dirent = fs_read_attr_dir(attributes)) != NULL) {
attr_info info;
off_t pos = 0;
if (fs_stat_attr(fromFd, dirent->d_name, &info) != 0)
continue;
while (info.size > 0) {
ssize_t bytesRead, bytesWritten;
bytesRead = fs_read_attr(fromFd, dirent->d_name, info.type, pos, buffer, sizeof(buffer));
if (bytesRead < 0)
continue;
bytesWritten = fs_write_attr(toFd, dirent->d_name, info.type, pos, buffer, bytesRead);
if (bytesWritten != bytesRead)
continue;
pos += bytesRead;
info.size -= bytesRead;
}
}
fs_close_attr_dir(attributes);
}
static int
copy_attributes_by_name(const char *from, const char *to, int resolveLinks)
{
int fromFd, toFd;
printf("%s -> %s\n", from, to);
fromFd = open(from, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE));
if (fromFd < 0)
return -1;
toFd = open(to, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE));
if (toFd < 0) {
close(fromFd);
return -1;
}
return copy_attributes(fromFd, toFd);
}
/* Read the contents of the directory SRC_PATH_IN, and recursively
copy the contents to DST_PATH_IN. NEW_DST is nonzero if
DST_PATH_IN is a directory that was created previously in the
@@ -163,6 +226,10 @@ copy_dir (const char *src_path_in, const char *dst_path_in, int new_dst,
return -1;
}
if (x->ignore_attributes == 0
&& copy_attributes_by_name(src_path_in, dst_path_in, true) != 0)
fprintf(stderr, "%s: could not copy attributes\n", src_path_in);
/* For cp's -H option, dereference command line arguments, but do not
dereference symlinks that are found via recursive traversal. */
if (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
@@ -312,6 +379,10 @@ copy_reg (const char *src_path, const char *dst_path,
}
#endif
if (x->ignore_attributes == 0
&& copy_attributes(source_desc, dest_desc) != 0)
fprintf(stderr, "%s: could not copy attributes\n", src_path);
/* Make a buffer with space for a sentinel at the end. */
buf = (char *) alloca (buf_size + sizeof (int));
@@ -1133,6 +1204,12 @@ copy_internal (const char *src_path, const char *dst_path,
quote_n (0, dst_path), quote_n (1, earlier_file));
goto un_backup;
}
else
{
if (x->ignore_attributes == 0
&& copy_attributes_by_name(earlier_file, dst_path, false) != 0)
fprintf(stderr, "%s: could not copy attributes\n", earlier_file);
}
return 0;
}
+3
View File
@@ -124,6 +124,9 @@ struct cp_options
it be zero. */
int require_preserve;
/* If nonzero, attributes will be ignored when copying. */
int ignore_attributes;
/* If nonzero, copy directories recursively and copy special files
as themselves rather than copying their contents. */
int recursive;
+1
View File
@@ -730,6 +730,7 @@ cp_option_init (struct cp_options *x)
x->preserve_timestamps = 0;
x->require_preserve = 0;
x->ignore_attributes = 0;
x->recursive = 0;
x->sparse_mode = SPARSE_AUTO;
x->symbolic_link = 0;
+1
View File
@@ -130,6 +130,7 @@ cp_option_init (struct cp_options *x)
x->preserve_mode = 1;
x->preserve_timestamps = 1;
x->require_preserve = 0; /* FIXME: maybe make this an option */
x->ignore_attributes = 0;
x->recursive = 1;
x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */
x->symbolic_link = 0;