version 1.58, 2015/01/16 06:40:15 |
version 1.59, 2015/04/18 03:15:46 |
|
|
gid_t gid; |
gid_t gid; |
|
|
void copy(int, char *, int, char *, off_t, int); |
void copy(int, char *, int, char *, off_t, int); |
int compare(int, const char *, size_t, int, const char *, size_t); |
int compare(int, const char *, off_t, int, const char *, off_t); |
void install(char *, char *, u_long, u_int); |
void install(char *, char *, u_long, u_int); |
void install_dir(char *); |
void install_dir(char *); |
void strip(char *); |
void strip(char *); |
|
|
install(char *from_name, char *to_name, u_long fset, u_int flags) |
install(char *from_name, char *to_name, u_long fset, u_int flags) |
{ |
{ |
struct stat from_sb, to_sb; |
struct stat from_sb, to_sb; |
struct utimbuf utb; |
struct timespec ts[2]; |
int devnull, from_fd, to_fd, serrno, files_match = 0; |
int devnull, from_fd, to_fd, serrno, files_match = 0; |
char *p; |
char *p; |
|
|
|
|
if (!devnull) { |
if (!devnull) { |
if (docompare && !safecopy) { |
if (docompare && !safecopy) { |
files_match = !(compare(from_fd, from_name, |
files_match = !(compare(from_fd, from_name, |
(size_t)from_sb.st_size, to_fd, |
from_sb.st_size, to_fd, |
to_name, (size_t)to_sb.st_size)); |
to_name, to_sb.st_size)); |
|
|
/* Truncate "to" file for copy unless we match */ |
/* Truncate "to" file for copy unless we match */ |
if (!files_match) { |
if (!files_match) { |
|
|
errc(EX_OSERR, serrno, "%s", tempfile); |
errc(EX_OSERR, serrno, "%s", tempfile); |
} |
} |
|
|
if (compare(temp_fd, tempfile, (size_t)temp_sb.st_size, to_fd, |
if (compare(temp_fd, tempfile, temp_sb.st_size, to_fd, |
to_name, (size_t)to_sb.st_size) == 0) { |
to_name, to_sb.st_size) == 0) { |
/* |
/* |
* If target has more than one link we need to |
* If target has more than one link we need to |
* replace it in order to snap the extra links. |
* replace it in order to snap the extra links. |
* Need to preserve target file times, though. |
* Need to preserve target file times, though. |
*/ |
*/ |
if (to_sb.st_nlink != 1) { |
if (to_sb.st_nlink != 1) { |
utb.actime = to_sb.st_atime; |
ts[0] = to_sb.st_atim; |
utb.modtime = to_sb.st_mtime; |
ts[1] = to_sb.st_mtim; |
(void)utime(tempfile, &utb); |
futimens(temp_fd, ts); |
} else { |
} else { |
files_match = 1; |
files_match = 1; |
(void)unlink(tempfile); |
(void)unlink(tempfile); |
|
|
* Preserve the timestamp of the source file if necessary. |
* Preserve the timestamp of the source file if necessary. |
*/ |
*/ |
if (dopreserve && !files_match) { |
if (dopreserve && !files_match) { |
utb.actime = from_sb.st_atime; |
ts[0] = from_sb.st_atim; |
utb.modtime = from_sb.st_mtime; |
ts[1] = from_sb.st_mtim; |
(void)utime(safecopy ? tempfile : to_name, &utb); |
futimens(to_fd, ts); |
} |
} |
|
|
/* |
/* |
|
|
* compare two files; non-zero means files differ |
* compare two files; non-zero means files differ |
*/ |
*/ |
int |
int |
compare(int from_fd, const char *from_name, size_t from_len, int to_fd, |
compare(int from_fd, const char *from_name, off_t from_len, int to_fd, |
const char *to_name, size_t to_len) |
const char *to_name, off_t to_len) |
{ |
{ |
caddr_t p1, p2; |
caddr_t p1, p2; |
size_t length, remainder; |
size_t length; |
off_t from_off, to_off; |
off_t from_off, to_off, remainder; |
int dfound; |
int dfound; |
|
|
if (from_len == 0 && from_len == to_len) |
if (from_len == 0 && from_len == to_len) |