Files
Arquivotheca.SunOS-4.1.4/usr.etc/tfs/libtfs/copy_file.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

174 lines
3.5 KiB
C

#ifndef lint
static char sccsid[] = "@(#)copy_file.c 1.1 94/10/31 Copyr 1988 Sun Micro";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/time.h>
#include <ar.h>
#include <errno.h>
#include <nse/util.h>
#include <nse/isafile.h>
extern long lseek();
/*
* Copy one file to another. (Recursive copy not handled.) Code stolen from
* cp.c.
*/
Nse_err
_nse_copy_file(to, from, pflag)
char *from;
char *to;
int pflag;
{
bool_t lib;
return _nse_copy_file_libscan(to, from, pflag, &lib);
}
/*
* Copy a file and check if it is a library.
*/
Nse_err
_nse_copy_file_libscan(to, from, pflag, ranlibp)
char *from;
char *to;
int pflag;
bool_t *ranlibp;
{
int fold, fnew, i, n, exists;
char buf[MAXBSIZE];
struct stat stfrom, stto;
Nse_err rt;
int has_holes; /* File has holes in it? */
int offset;
bool_t first;
fold = open(from, 0);
if (fold < 0) {
return nse_err_format_errno("Open of \"%s\"", from);
}
if (fstat(fold, &stfrom) < 0) {
rt = nse_err_format_errno("Fstat of \"%s\"", from);
(void) close(fold);
return rt;
}
if ((stfrom.st_mode&S_IFMT) == S_IFDIR) {
(void) close(fold);
errno = EISDIR;
return nse_err_format_errno("Copy from \"%s\"", from);
}
exists = stat(to, &stto) == 0;
if ((exists) && (stto.st_mode&S_IFMT) == S_IFDIR) {
(void) close(fold);
errno = EISDIR;
return nse_err_format_errno("Copy to \"%s\"", from);
}
if (exists) {
if (stfrom.st_dev == stto.st_dev &&
stfrom.st_ino == stto.st_ino) {
(void) close(fold);
return NULL;
}
}
fnew = creat(to, (int) (stfrom.st_mode & 07777));
if (fnew < 0) {
rt = nse_err_format_errno("Creat of \"%s\"", to);
(void) close(fold);
return rt;
}
if (exists && pflag) {
(void) fchmod(fnew, (int) (stfrom.st_mode & 07777));
}
has_holes = (stfrom.st_blocks * DEV_BSIZE < stfrom.st_size);
offset = 0;
*ranlibp = FALSE;
first = TRUE;
for (;;) {
n = read(fold, buf, sizeof buf);
if (n == 0)
break;
if (n < 0) {
rt = nse_err_format_errno("Read of \"%s\"", from);
(void) close(fold);
(void) close(fnew);
return rt;
}
if (first) {
first = FALSE;
if (n >= sizeof(NSE_RANLIB_HDR) &&
strncmp(buf, NSE_RANLIB_HDR,
sizeof(NSE_RANLIB_HDR) - 1) == 0) {
*ranlibp = TRUE;
}
}
if (has_holes) {
/*
* Preserve any holes in the file.
*/
i = 0;
do {
if (buf[i] != 0) {
break;
}
i++;
} while (i < n);
if (i == n) {
offset += n;
continue;
}
if (lseek(fnew, (long) offset, L_SET) < 0) {
rt = nse_err_format_errno("Lseek to %d in \"%s\"",
offset, to);
(void) close(fold);
(void) close(fnew);
return rt;
}
offset += n;
}
if (write(fnew, buf, n) != n) {
rt = nse_err_format_errno("Write to \"%s\"", to);
(void) close(fold);
(void) close(fnew);
return rt;
}
}
(void) close(fold);
/* In 4.0, sometimes close was returning a random error so check
* errno as well as the return value from close.
*/
errno = 0;
if (close(fnew) < 0 && errno != 0) {
return nse_err_format_errno("Close of \"%s\"", to);
}
if (pflag)
return _nse_copy_setimes(to, &stfrom);
return NULL;
}
Nse_err
_nse_copy_setimes(path, statp)
char *path;
struct stat *statp;
{
struct timeval tv[2];
tv[0].tv_sec = statp->st_atime;
tv[1].tv_sec = statp->st_mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(path, tv) < 0) {
return nse_err_format_errno("Utimes of \"%s\"", path);
}
return NULL;
}