|
|
1.1 root 1: /*
2: * cp oldfile newfile
3: */
4:
5: #include <stdio.h>
6: #include <sys/types.h>
7: #include <sys/stat.h>
8: #define BLOCKSIZE BUFSIZE
9: struct stat stbuf1, stbuf2;
10: char iobuf[BLOCKSIZE];
11: char zero[BLOCKSIZE]; /* keep as zero */
12: int zflag = 0;
13: #define wrcp() write(2, "cp: ", 4)
14:
15: main(argc, argv)
16: char *argv[];
17: {
18: register i, r;
19:
20: if (argc < 3)
21: goto usage;
22: i = 1;
23: if(strcmp(argv[i], "-z") == 0)
24: zflag = 1, i++;
25: if ((argc-i) > 2) {
26: if (stat(argv[argc-1], &stbuf2) < 0)
27: goto usage;
28: if ((stbuf2.st_mode&S_IFMT) != S_IFDIR)
29: goto usage;
30: }
31: r = 0;
32: for(; i<argc-1;i++)
33: r |= copy(argv[i], argv[argc-1]);
34: exit(r);
35: usage:
36: fprintf(stderr, "Usage: cp: [-z] f1 f2; or cp [-z] f1 ... fn d2\n");
37: exit(1);
38: }
39:
40: copy(from, to)
41: char *from, *to;
42: {
43: int fold, fnew, n;
44: register char *p1, *p2, *bp;
45: int mode;
46: int bsize, zsize;
47: long lseek();
48:
49: if ((fold = open(from, 0)) < 0) {
50: wrcp();
51: perror(from);
52: return(1);
53: }
54: fstat(fold, &stbuf1);
55: mode = stbuf1.st_mode;
56: /* is source a directory? */
57: if ((mode&S_IFMT) == S_IFDIR) {
58: fprintf(stderr, "cp: %s is a directory\n", from);
59: close(fold);
60: return(1);
61: }
62: /* is target a directory? */
63: if (stat(to, &stbuf2) >=0 &&
64: (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
65: p1 = from;
66: p2 = to;
67: bp = iobuf;
68: while(*bp++ = *p2++)
69: ;
70: bp[-1] = '/';
71: p2 = bp;
72: while(*bp = *p1++)
73: if (*bp++ == '/')
74: bp = p2;
75: to = iobuf;
76: }
77: if (stat(to, &stbuf2) >= 0) {
78: if (stbuf1.st_dev == stbuf2.st_dev &&
79: stbuf1.st_ino == stbuf2.st_ino) {
80: fprintf(stderr, "cp: cannot copy file to itself\n");
81: close(fold);
82: return(1);
83: }
84: }
85: bsize = BSIZE(stbuf2.st_dev);
86: if (bsize > BLOCKSIZE) {
87: fprintf(stderr, "cp: BSIZE(%s) > %d\n", to, BLOCKSIZE);
88: return 1;
89: }
90: if ((fnew = creat(to, mode)) < 0) {
91: wrcp();
92: perror(to);
93: close(fold);
94: return(1);
95: }
96: zsize = 0;
97: while(n = read(fold, iobuf, bsize)) {
98: if (n < 0) {
99: wrcp();
100: perror(from);
101: close(fold);
102: close(fnew);
103: return(1);
104: } else
105: if(zflag && (n == bsize) && (memcmp(iobuf, zero, bsize) == 0)){
106: if (lseek(fnew, (long)bsize, 1) < 0) {
107: wrcp();
108: perror(to);
109: close(fold);
110: close(fnew);
111: return(1);
112: }
113: zsize = bsize;
114: } else {
115: if (write(fnew, iobuf, n) != n) {
116: wrcp();
117: perror(to);
118: close(fold);
119: close(fnew);
120: return(1);
121: }
122: zsize = 0;
123: }
124: }
125:
126: if (zsize) {
127: if (lseek(fnew, (long)-zsize, 1) < 0
128: || write(fnew,zero,zsize) != zsize) {
129: wrcp();
130: perror(to);
131: close(fold);
132: close(fnew);
133: return(1);
134: }
135: }
136:
137: close(fold);
138: close(fnew);
139: return(0);
140: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.