Finally mount works properly. Made debugging work (no more -s ld flag
[oweals/busybox.git] / cp.c
1 #include "internal.h"
2 #include <stdio.h>
3 #include <sys/stat.h>
4 #include <sys/fcntl.h>
5 #include <sys/param.h>
6 #include <errno.h>
7
8 const char  cp_usage[] = "cp [-r] source-file destination-file\n"
9 "\t\tcp [-r] source-file [source-file ...] destination-directory\n"
10 "\n"
11 "\tCopy the source files to the destination.\n"
12 "\n"
13 "\t-r:\tRecursively copy all files and directories\n"
14 "\t\tunder the argument directory.";
15
16 extern int
17 cp_fn(const struct FileInfo * i)
18 {
19     int         sourceFd;
20     int         destinationFd;
21     const char * destination = i->destination;
22     struct stat destination_stat;
23     int         status;
24     char        buf[8192];
25     char        d[PATH_MAX];
26
27     if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) {
28         if ( mkdir(destination, i->stat.st_mode & ~S_IFMT)
29          != 0 && errno != EEXIST ) {
30             name_and_error(destination);
31             return 1;
32         }
33         return 0;
34     }
35     if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) {
36         name_and_error(i->source);
37         return 1;
38     }
39     if ( stat(destination, &destination_stat) == 0 ) {
40         if ( i->stat.st_ino == destination_stat.st_ino
41          &&  i->stat.st_dev == destination_stat.st_dev ) {
42             fprintf(stderr
43             ,"copy of %s to %s would copy file to itself.\n"
44             ,i->source
45             ,destination);
46             close(sourceFd);
47             return 1;
48         }
49     }
50     /*
51      * If the destination is a directory, create a file within it.
52      */
53     if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) {
54                 destination = join_paths(
55                  d
56                 ,i->destination
57                 ,&i->source[i->directoryLength]);
58
59         if ( stat(destination, &destination_stat) == 0 ) {
60             if ( i->stat.st_ino == destination_stat.st_ino
61              &&  i->stat.st_dev == destination_stat.st_dev ) {
62                 fprintf(stderr
63                 ,"copy of %s to %s would copy file to itself.\n"
64                 ,i->source
65                 ,destination);
66                 close(sourceFd);
67                 return 1;
68             }
69         }
70     }
71
72     destinationFd = creat(destination, i->stat.st_mode & 07777);
73
74     while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) {
75         if ( write(destinationFd, buf, status) != status ) {
76             name_and_error(destination);
77             close(sourceFd);
78             close(destinationFd);
79             return 1;
80         }
81     }
82     close(sourceFd);
83     close(destinationFd);
84     if ( status < 0 ) {
85         name_and_error(i->source);
86         return 1;
87     }
88     return 0;
89 }