Commit | Line | Data |
---|---|---|
4f011000 BJ |
1 | /* |
2 | * cp oldfile newfile | |
3 | */ | |
4 | ||
5 | #define BSIZE 1024 | |
6 | #include <stdio.h> | |
7 | #include <sys/types.h> | |
8 | #include <sys/stat.h> | |
9 | struct stat stbuf1, stbuf2; | |
10 | char iobuf[BSIZE]; | |
11 | ||
12 | main(argc, argv) | |
13 | char *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); | |
29 | usage: | |
30 | fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n"); | |
31 | exit(1); | |
32 | } | |
33 | ||
34 | copy(from, to) | |
35 | char *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 | perror("cp: read"); | |
76 | close(fold); | |
77 | close(fnew); | |
78 | return(1); | |
79 | } else | |
80 | if (write(fnew, iobuf, n) != n) { | |
81 | perror("cp: write"); | |
82 | close(fold); | |
83 | close(fnew); | |
84 | return(1); | |
85 | } | |
86 | } | |
87 | close(fold); | |
88 | close(fnew); | |
89 | return(0); | |
90 | } |