|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4325 (0x10e5)
Types: TextFile
Notes: UNIX file
Names: »cp.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/cp.c«
/*
* Copy one file to another or
* copy several files into a directory.
* define SLOW for 'block at a time copying' .... (not recommended)
*/
#include <stdio.h>
#include <stat.h>
#include <errno.h>
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#define or ||
#define and &&
#define not !
#define TRUE (0==0)
#define FALSE (not TRUE)
extern int errno;
struct stat sb;
#ifndef SLOW
char buf[50*BUFSIZ];
#else
char buf[BUFSIZ];
#endif
char *target;
char *namebuf;
char *suffix;
main(argc, argv)
int argc;
char *argv[];
{
register int i;
register int n;
register int status = 0;
n = init(argc, argv);
if (namebuf == NULL)
return (cp(argv[1], target) ? 0 : 1);
for (i = 1; i <= n; ++i)
status |= cpdir(argv[i]);
return (status ? 0 : 1);
}
/*
* Copy inf to outf.
*/
cp(inf, outf)
char *inf, *outf;
{
#ifndef SLOW
register char *ip;
#endif
register int n;
register int i;
register short infd;
register short outfd;
register short mode;
register ino_t ino;
register dev_t dev;
register size_t size;
#ifndef SLOW
register char *wp;
register int wflag;
#endif
if (stat(inf, &sb) < 0) {
cperr("%s: can't find", inf);
return (FALSE);
}
if ((sb.st_mode & S_IFMT) == S_IFDIR) {
cperr("%s: directory", inf);
return (FALSE);
}
mode = sb.st_mode;
size = sb.st_size;
ino = sb.st_ino;
dev = sb.st_dev;
if (stat(outf, &sb) >= 0)
if (sb.st_ino==ino && sb.st_dev==dev) {
cperr("%s: can't copy file to itself", inf);
return (FALSE);
}
if ((infd = open(inf, 0)) < 0) {
cperr("%s: can't open", inf);
return (FALSE);
}
if ((outfd = creat(outf, mode&0777)) < 0) {
if (errno == ETXTBSY)
cperr("%s: can't copy over busy shared text file", outf);
else
cperr("%s: can't create", outf);
close(infd);
return (FALSE);
}
#ifndef SLOW
while ((n = read(infd, buf, sizeof(buf))) > 0) {
#else
while ((n = read(infd, buf, BUFSIZ)) > 0) {
#endif
/*
* Check for blocks of zeroes (holes in a sparse file).
* However, a block of zeroes at the end of a file must be
* written so the file has correct length.
*/
#ifndef SLOW
wp = ip = buf;
size -= n;
while ((n-BUFSIZ) > 0 || ((n-BUFSIZ) == 0 && size != 0)) {
n -= BUFSIZ;
wflag = FALSE;
ip = wp;
for (i = 0; i < BUFSIZ; ++i)
if (*ip++ != '\0') {
wflag = TRUE;
break;
}
if (wflag) {
if (write(outfd, wp, BUFSIZ) < BUFSIZ) {
cperr("write error on %s", outf);
close(infd);
close(outfd);
return (FALSE);
}
} else {
lseek(outfd, (long)BUFSIZ, 1);
}
wp += BUFSIZ;
}
if (write(outfd, wp, n) < n) {
cperr("write error on %s", outf);
close(infd);
close(outfd);
return (FALSE);
}
#else
if ((size -= n) == (size_t)0)
goto WRITE;
for (i = 0; i < n; ++i)
if (buf[i] != '\0')
goto WRITE;
lseek(outfd, (long)BUFSIZ, 1);
continue;
WRITE:
if (write(outfd, buf, n) < n) {
cperr("%s: write error", outf);
close(infd);
close(outfd);
return (FALSE);
}
#endif
}
close(infd);
close(outfd);
if (n < 0) {
cperr("%s: read error", inf);
return (FALSE);
}
return (TRUE);
}
/*
* The second form of cp, copy a file into a directory. This builds the name
* of the target file in namebuf and then just calls `cp'.
*/
cpdir(file)
char *file;
{
register char *a, *b;
for (a = b = file; *b != '\0'; )
if (*b++ == '/')
a = b;
strcpy(suffix, a);
return (cp(file, namebuf));
}
usage()
{
fprintf(stderr,
"Usage: cp file1 file2\n cp file ... directory\n");
exit (2);
}
cperr(arg0)
{
fprintf(stderr, "cp: ");
fprintf(stderr, "%r\n", &arg0);
}
/*
* Check whether target is a directory, regular file, non-extant or in error.
* If a directory, malloc namebuf big enough for all names.
* Also, set flags used by cperr.
*/
init(ac, av)
register int ac;
register char *av[];
{
register int n;
if (ac < 3)
usage();
target = av[ac-1];
if (stat(target, &sb) == 0 and (sb.st_mode & S_IFMT) == S_IFDIR) {
av[ac-1] = NULL;
n = 0;
while (*++av != NULL)
if (n < strlen(*av))
n = strlen(*av);
namebuf = malloc(n + strlen(target) + 2);
if (namebuf == NULL) {
cperr("out of memory");
exit(1);
}
strcpy(namebuf, target);
suffix = namebuf + strlen(target);
*suffix++ = '/';
return (ac - 2);
}
if (ac != 3)
usage();
return (1);
}