|
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); }