|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)cp.c 4.8 83/07/01";
3: #endif
4:
5: /*
6: * cp
7: */
8: #include <stdio.h>
9: #include <sys/param.h>
10: #include <sys/stat.h>
11: #include <sys/dir.h>
12:
13: #define BSIZE 8192
14:
15: int iflag;
16: int rflag;
17: char *rindex(), *sprintf();
18:
19: main(argc, argv)
20: int argc;
21: char **argv;
22: {
23: struct stat stb;
24: int rc, i;
25:
26: argc--, argv++;
27: while (argc > 0 && **argv == '-') {
28: (*argv)++;
29: while (**argv) switch (*(*argv)++) {
30:
31: case 'i':
32: iflag++; break;
33:
34: case 'r':
35: rflag++; break;
36:
37: default:
38: goto usage;
39: }
40: argc--; argv++;
41: }
42: if (argc < 2)
43: goto usage;
44: if (argc > 2 || rflag) {
45: if (stat(argv[argc-1], &stb) < 0)
46: goto usage;
47: if ((stb.st_mode&S_IFMT) != S_IFDIR)
48: goto usage;
49: }
50: rc = 0;
51: for (i = 0; i < argc-1; i++)
52: rc |= copy(argv[i], argv[argc-1]);
53: exit(rc);
54: usage:
55: fprintf(stderr,
56: "Usage: cp f1 f2; or cp [ -r ] f1 ... fn d2\n");
57: exit(1);
58: }
59:
60: copy(from, to)
61: char *from, *to;
62: {
63: int fold, fnew, n;
64: char *last, destname[BSIZE], buf[BSIZE];
65: struct stat stfrom, stto;
66:
67: fold = open(from, 0);
68: if (fold < 0) {
69: Perror(from);
70: return (1);
71: }
72: if (fstat(fold, &stfrom) < 0) {
73: Perror(from);
74: (void) close(fold);
75: return (1);
76: }
77: if (stat(to, &stto) >= 0 &&
78: (stto.st_mode&S_IFMT) == S_IFDIR) {
79: last = rindex(from, '/');
80: if (last) last++; else last = from;
81: if (strlen(to) + strlen(last) >= BSIZE - 1) {
82: fprintf(stderr, "cp: %s/%s: Name too long", to, last);
83: (void) close(fold);
84: return(1);
85: }
86: (void) sprintf(destname, "%s/%s", to, last);
87: to = destname;
88: }
89: if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) {
90: (void) close(fold);
91: if (stat(to, &stto) < 0) {
92: if (mkdir(to, (int)stfrom.st_mode) < 0) {
93: Perror(to);
94: return (1);
95: }
96: } else if ((stto.st_mode&S_IFMT) != S_IFDIR) {
97: fprintf(stderr, "cp: %s: Not a directory.\n", to);
98: return (1);
99: }
100: return (rcopy(from, to));
101: }
102: if (stat(to, &stto) >= 0) {
103: if (stfrom.st_dev == stto.st_dev &&
104: stfrom.st_ino == stto.st_ino) {
105: fprintf(stderr, "cp: Cannot copy file to itself.\n");
106: (void) close(fold);
107: return (1);
108: }
109: if (iflag) {
110: int i, c;
111:
112: fprintf (stderr, "overwrite %s? ", to);
113: i = c = getchar();
114: while (c != '\n' && c != EOF)
115: c = getchar();
116: if (i != 'y') {
117: (void) close(fold);
118: return(1);
119: }
120: }
121: }
122: fnew = creat(to, (int)stfrom.st_mode);
123: if (fnew < 0) {
124: Perror(to);
125: (void) close(fold); return(1);
126: }
127: for (;;) {
128: n = read(fold, buf, BSIZE);
129: if (n == 0)
130: break;
131: if (n < 0) {
132: Perror(from);
133: (void) close(fold); (void) close(fnew); return (1);
134: }
135: if (write(fnew, buf, n) != n) {
136: Perror(to);
137: (void) close(fold); (void) close(fnew); return (1);
138: }
139: }
140: (void) close(fold); (void) close(fnew); return (0);
141: }
142:
143: rcopy(from, to)
144: char *from, *to;
145: {
146: DIR *fold = opendir(from);
147: struct direct *dp;
148: int errs = 0;
149: char fromname[BUFSIZ];
150:
151: if (fold == 0) {
152: Perror(from);
153: return (1);
154: }
155: for (;;) {
156: dp = readdir(fold);
157: if (dp == 0) {
158: closedir(fold);
159: return (errs);
160: }
161: if (dp->d_ino == 0)
162: continue;
163: if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
164: continue;
165: if (strlen(from) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
166: fprintf(stderr, "cp: %s/%s: Name too long.\n",
167: from, dp->d_name);
168: errs++;
169: continue;
170: }
171: (void) sprintf(fromname, "%s/%s", from, dp->d_name);
172: errs += copy(fromname, to);
173: }
174: }
175:
176: Perror(s)
177: char *s;
178: {
179:
180: fprintf(stderr, "cp: ");
181: perror(s);
182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.