BSD 4 release
[unix-history] / usr / src / cmd / cp.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)cp.c 4.1 (Berkeley) 10/1/80";
84592a94
BJ
2/*
3 * cp oldfile newfile
4 */
5
6#define BSIZE 1024
7#include <stdio.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10struct stat stbuf1, stbuf2;
11char iobuf[BSIZE];
12int iflag = 0; /* interactive flag. If this flag is set,
13 * the user is queried before files are
14 * destroyed by cp.
15 */
16
17main(argc, argv)
18char *argv[];
19{
20 register i, r;
21
22 /* get the flag(s) */
23
24 if (argc < 2)
25 goto usage;
26 if (*argv[1] == '-') {
27 argc--;
28 while (*++argv[1] != '\0')
29 switch (*argv[1]) {
30
31 /* interactive mode */
32 case 'i':
33 iflag++;
34 break;
35
36 /* don't live with bad options */
37 default:
38 goto usage;
39 }
40 argv++;
41 }
42 if (argc < 3)
43 goto usage;
44 if (argc > 3) {
45 if (stat(argv[argc-1], &stbuf2) < 0)
46 goto usage;
47 if ((stbuf2.st_mode&S_IFMT) != S_IFDIR)
48 goto usage;
49 }
50 r = 0;
51 for(i=1; i<argc-1;i++)
52 r |= copy(argv[i], argv[argc-1]);
53 exit(r);
54usage:
55 fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
56 exit(1);
57}
58
59copy(from, to)
60char *from, *to;
61{
62 int fold, fnew, n;
63 register char *p1, *p2, *bp;
64 int mode;
65 char c,i;
66 if ((fold = open(from, 0)) < 0) {
67 fprintf(stderr, "cp: cannot open %s\n", from);
68 return(1);
69 }
70 fstat(fold, &stbuf1);
71 mode = stbuf1.st_mode;
72 /* is target a directory? */
73 if (stat(to, &stbuf2) >=0 &&
74 (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
75 p1 = from;
76 p2 = to;
77 bp = iobuf;
78 while(*bp++ = *p2++)
79 ;
80 bp[-1] = '/';
81 p2 = bp;
82 while(*bp = *p1++)
83 if (*bp++ == '/')
84 bp = p2;
85 to = iobuf;
86 }
87 if (stat(to, &stbuf2) >= 0) {
88 if (stbuf1.st_dev == stbuf2.st_dev &&
89 stbuf1.st_ino == stbuf2.st_ino) {
90 fprintf(stderr, "cp: cannot copy file to itself.\n");
91 return(1);
92 } else if (iflag) {
93 fprintf (stderr, "overwrite %s? ", to);
94 i = c = getchar();
95 while (c != '\n' && c != EOF)
96 c = getchar();
97 if (i != 'y')
98 return(1);
99 }
100 }
101 if ((fnew = creat(to, mode)) < 0) {
102 fprintf(stderr, "cp: cannot create %s\n", to);
103 close(fold);
104 return(1);
105 }
106 while(n = read(fold, iobuf, BSIZE)) {
107 if (n < 0) {
108 perror("cp: read");
109 close(fold);
110 close(fnew);
111 return(1);
112 } else
113 if (write(fnew, iobuf, n) != n) {
114 perror("cp: write");
115 close(fold);
116 close(fnew);
117 return(1);
118 }
119 }
120 close(fold);
121 close(fnew);
122 return(0);
123}