Bell 32V development
[unix-history] / usr / src / cmd / cp.c
CommitLineData
3b600ead
TL
1/*
2 * cp oldfile newfile
3 */
4
5#define BSIZE 512
6#include <stdio.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9struct stat stbuf1, stbuf2;
10char iobuf[BSIZE];
11
12main(argc, argv)
13char *argv[];
14{
15 register i, r;
16
17 if (argc < 3)
18 goto usage;
19 if (argc > 3) {
20 if (stat(argv[argc-1], &stbuf2) < 0)
21 goto usage;
22 if ((stbuf2.st_mode&S_IFMT) != S_IFDIR)
23 goto usage;
24 }
25 r = 0;
26 for(i=1; i<argc-1;i++)
27 r |= copy(argv[i], argv[argc-1]);
28 exit(r);
29usage:
30 fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
31 exit(1);
32}
33
34copy(from, to)
35char *from, *to;
36{
37 int fold, fnew, n;
38 register char *p1, *p2, *bp;
39 int mode;
40 if ((fold = open(from, 0)) < 0) {
41 fprintf(stderr, "cp: cannot open %s\n", from);
42 return(1);
43 }
44 fstat(fold, &stbuf1);
45 mode = stbuf1.st_mode;
46 /* is target a directory? */
47 if (stat(to, &stbuf2) >=0 &&
48 (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
49 p1 = from;
50 p2 = to;
51 bp = iobuf;
52 while(*bp++ = *p2++)
53 ;
54 bp[-1] = '/';
55 p2 = bp;
56 while(*bp = *p1++)
57 if (*bp++ == '/')
58 bp = p2;
59 to = iobuf;
60 }
61 if (stat(to, &stbuf2) >= 0) {
62 if (stbuf1.st_dev == stbuf2.st_dev &&
63 stbuf1.st_ino == stbuf2.st_ino) {
64 fprintf(stderr, "cp: cannot copy file to itself.\n");
65 return(1);
66 }
67 }
68 if ((fnew = creat(to, mode)) < 0) {
69 fprintf(stderr, "cp: cannot create %s\n", to);
70 close(fold);
71 return(1);
72 }
73 while(n = read(fold, iobuf, BSIZE)) {
74 if (n < 0) {
75 fprintf(stderr, "cp: read error\n");
76 close(fold);
77 close(fnew);
78 return(1);
79 } else
80 if (write(fnew, iobuf, n) != n) {
81 fprintf(stderr, "cp: write error.\n");
82 close(fold);
83 close(fnew);
84 return(1);
85 }
86 }
87 close(fold);
88 close(fnew);
89 return(0);
90}