Annotation of prex-old/usr/bin/cp/cp.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 1988, 1993, 1994
3: * The Regents of the University of California. All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * David Hitz of Auspex Systems Inc.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #include <sys/stat.h>
34: #include <sys/fcntl.h>
35:
36: #include <unistd.h>
37: #include <err.h>
38: #include <string.h>
39: #include <stdlib.h>
40: #include <errno.h>
41: #include <limits.h>
42: #include <stdio.h>
43:
44: #ifdef CMDBOX
45: #define main(argc, argv) cp_main(argc, argv)
46: #endif
47:
48: static void usage(void);
49: static int copy(char *from, char *to, int dirflag);
50:
51:
52: static char iobuf[BUFSIZ];
53:
54: int
55: main(int argc, char *argv[])
56: {
57: int r, ch, checkch, i, iflag = 0;
58: char *target;
59: struct stat to_stat, tmp_stat;
60:
61: while ((ch = getopt(argc, argv, "i")) != -1)
62: switch(ch) {
63: case 'i':
64: iflag = isatty(fileno(stdin));
65: break;
66: case '?':
67: default:
68: usage();
69: }
70: argc -= optind;
71: argv += optind;
72:
73: if (argc < 2)
74: usage();
75:
76: target = argv[--argc];
77:
78: r = stat(target, &to_stat);
79: if (r == -1 && errno != ENOENT)
80: err(1, "%s", target);
81: if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
82: /*
83: * File to file
84: */
85: if (argc > 1) {
86: usage();
87: exit(1);
88: }
89: stat(argv[0], &tmp_stat);
90: if (!S_ISREG(tmp_stat.st_mode))
91: usage();
92:
93: /* interactive mode */
94: if (r != -1 && iflag) {
95: (void)fprintf(stderr, "overwrite %s? ", target);
96: checkch = ch = getchar();
97: while (ch != '\n' && ch != EOF)
98: ch = getchar();
99: if (checkch != 'y')
100: exit(0);
101: }
102: r = copy(argv[0], target, 0);
103: } else {
104: /*
105: * File(s) to directory
106: */
107: r = 0;
108: for (i = 0; i < argc; i++)
109: r = copy(argv[i], target, 1);
110: }
111: exit(r);
112: }
113:
114: static void
115: usage(void)
116: {
117: fprintf(stderr, "usage: cp [-i] src target\n"
118: " cp [-i] src1 ... srcN directory\n");
119: exit(1);
120: /* NOTREACHED */
121: }
122:
123: static int
124: copy(char *from, char *to, int dirflag)
125: {
126: char path[PATH_MAX];
127: int fold, fnew, n, mode;
128: struct stat stbuf;
129: char *p;
130:
131: if (dirflag) {
132: p = strrchr(from, '/');
133: p = p ? p + 1 : from;
134: strcpy(path, to);
135: if (strcmp(to, "/"))
136: strcat(path, "/");
137: strcat(path, p);
138: to = path;
139: }
140:
141: if ((fold = open(from, 0)) == -1) {
142: warn("%s", from);
143: return (1);
144: }
145: fstat(fold, &stbuf);
146: mode = stbuf.st_mode;
147:
148: if ((fnew = creat(to, mode)) == -1) {
149: warn("%s", to);
150: close(fold);
151: return (1);
152: }
153: while ((n = read(fold, iobuf, BUFSIZ)) > 0) {
154: if (write(fnew, iobuf, n) != n) {
155: warn("%s", to);
156: close(fold);
157: close(fnew);
158: return (1);
159: }
160: }
161: close(fold);
162: close(fnew);
163: return 0;
164: }
CVSweb