diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-11 16:23:35 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-11 16:23:35 +0000 |
commit | 4949faf4b2090ca23c2aeb34535fdbe57754913a (patch) | |
tree | b292a499341d3c0314283e2822a93241a1c4e1dd /libbb/copy_file.c | |
parent | 5b20d02ea98c41bbd8a49cdbb84f425fa9ef446e (diff) | |
download | busybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.tar.gz busybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.tar.bz2 busybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.zip |
copy_file_chunk uses streams now.
Diffstat (limited to 'libbb/copy_file.c')
-rw-r--r-- | libbb/copy_file.c | 133 |
1 files changed, 75 insertions, 58 deletions
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 64b65b9fa..eb9cb1a16 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
@@ -41,49 +41,54 @@ | |||
41 | * -Erik Andersen | 41 | * -Erik Andersen |
42 | */ | 42 | */ |
43 | int | 43 | int |
44 | copy_file(const char *srcName, const char *destName, | 44 | copy_file(const char *src_name, const char *dst_name, |
45 | int setModes, int followLinks, int forceFlag) | 45 | int set_modes, int follow_links, int force_flag, int quiet_flag) |
46 | { | 46 | { |
47 | int rfd; | 47 | FILE *src_file = NULL; |
48 | int wfd; | 48 | FILE *dst_file = NULL; |
49 | int status; | ||
50 | struct stat srcStatBuf; | 49 | struct stat srcStatBuf; |
51 | struct stat dstStatBuf; | 50 | struct stat dstStatBuf; |
52 | struct utimbuf times; | 51 | struct utimbuf times; |
52 | int src_status; | ||
53 | int dst_status; | ||
54 | |||
55 | if (follow_links == TRUE) { | ||
56 | src_status = stat(src_name, &srcStatBuf); | ||
57 | dst_status = stat(dst_name, &dstStatBuf); | ||
58 | } else { | ||
59 | src_status = lstat(src_name, &srcStatBuf); | ||
60 | dst_status = lstat(dst_name, &dstStatBuf); | ||
61 | } | ||
53 | 62 | ||
54 | if (followLinks == TRUE) | 63 | if (src_status < 0) { |
55 | status = stat(srcName, &srcStatBuf); | 64 | if (!quiet_flag) { |
56 | else | 65 | perror_msg("%s", src_name); |
57 | status = lstat(srcName, &srcStatBuf); | 66 | } |
58 | |||
59 | if (status < 0) { | ||
60 | perror_msg("%s", srcName); | ||
61 | return FALSE; | 67 | return FALSE; |
62 | } | 68 | } |
63 | 69 | ||
64 | if (followLinks == TRUE) | 70 | if ((dst_status < 0) || force_flag) { |
65 | status = stat(destName, &dstStatBuf); | 71 | unlink(dst_name); |
66 | else | ||
67 | status = lstat(destName, &dstStatBuf); | ||
68 | |||
69 | if (status < 0 || forceFlag==TRUE) { | ||
70 | unlink(destName); | ||
71 | dstStatBuf.st_ino = -1; | 72 | dstStatBuf.st_ino = -1; |
72 | dstStatBuf.st_dev = -1; | 73 | dstStatBuf.st_dev = -1; |
73 | } | 74 | } |
74 | 75 | ||
75 | if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && | 76 | if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && |
76 | (srcStatBuf.st_ino == dstStatBuf.st_ino)) { | 77 | (srcStatBuf.st_ino == dstStatBuf.st_ino)) { |
77 | error_msg("Copying file \"%s\" to itself", srcName); | 78 | if (!quiet_flag) { |
79 | error_msg("Copying file \"%s\" to itself", src_name); | ||
80 | } | ||
78 | return FALSE; | 81 | return FALSE; |
79 | } | 82 | } |
80 | 83 | ||
81 | if (S_ISDIR(srcStatBuf.st_mode)) { | 84 | if (S_ISDIR(srcStatBuf.st_mode)) { |
82 | //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); | 85 | //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); |
83 | /* Make sure the directory is writable */ | 86 | /* Make sure the directory is writable */ |
84 | status = mkdir(destName, 0777777 ^ umask(0)); | 87 | dst_status = create_path(dst_name, 0777777 ^ umask(0)); |
85 | if (status < 0 && errno != EEXIST) { | 88 | if ((dst_status < 0) && (errno != EEXIST)) { |
86 | perror_msg("%s", destName); | 89 | if (!quiet_flag) { |
90 | perror_msg("%s", dst_name); | ||
91 | } | ||
87 | return FALSE; | 92 | return FALSE; |
88 | } | 93 | } |
89 | } else if (S_ISLNK(srcStatBuf.st_mode)) { | 94 | } else if (S_ISLNK(srcStatBuf.st_mode)) { |
@@ -92,80 +97,92 @@ copy_file(const char *srcName, const char *destName, | |||
92 | 97 | ||
93 | //fprintf(stderr, "copying link %s to %s\n", srcName, destName); | 98 | //fprintf(stderr, "copying link %s to %s\n", srcName, destName); |
94 | /* Warning: This could possibly truncate silently, to BUFSIZ chars */ | 99 | /* Warning: This could possibly truncate silently, to BUFSIZ chars */ |
95 | link_size = readlink(srcName, &link_val[0], BUFSIZ); | 100 | link_size = readlink(src_name, &link_val[0], BUFSIZ); |
96 | if (link_size < 0) { | 101 | if (link_size < 0) { |
97 | perror_msg("%s", srcName); | 102 | if (quiet_flag) { |
103 | perror_msg("%s", src_name); | ||
104 | } | ||
98 | return FALSE; | 105 | return FALSE; |
99 | } | 106 | } |
100 | link_val[link_size] = '\0'; | 107 | link_val[link_size] = '\0'; |
101 | status = symlink(link_val, destName); | 108 | src_status = symlink(link_val, dst_name); |
102 | if (status < 0) { | 109 | if (src_status < 0) { |
103 | perror_msg("%s", destName); | 110 | if (!quiet_flag) { |
111 | perror_msg("%s", dst_name); | ||
112 | } | ||
104 | return FALSE; | 113 | return FALSE; |
105 | } | 114 | } |
106 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 115 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) |
107 | if (setModes == TRUE) { | 116 | if (set_modes == TRUE) { |
108 | /* Try to set owner, but fail silently like GNU cp */ | 117 | /* Try to set owner, but fail silently like GNU cp */ |
109 | lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); | 118 | lchown(dst_name, srcStatBuf.st_uid, srcStatBuf.st_gid); |
110 | } | 119 | } |
111 | #endif | 120 | #endif |
112 | return TRUE; | 121 | return TRUE; |
113 | } else if (S_ISFIFO(srcStatBuf.st_mode)) { | 122 | } else if (S_ISFIFO(srcStatBuf.st_mode)) { |
114 | //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); | 123 | //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); |
115 | if (mkfifo(destName, 0644) < 0) { | 124 | if (mkfifo(dst_name, 0644) < 0) { |
116 | perror_msg("%s", destName); | 125 | if (!quiet_flag) { |
126 | perror_msg("%s", dst_name); | ||
127 | } | ||
117 | return FALSE; | 128 | return FALSE; |
118 | } | 129 | } |
119 | } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) | 130 | } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) |
120 | || S_ISSOCK(srcStatBuf.st_mode)) { | 131 | || S_ISSOCK(srcStatBuf.st_mode)) { |
121 | //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); | 132 | //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); |
122 | if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) { | 133 | if (mknod(dst_name, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) { |
123 | perror_msg("%s", destName); | 134 | if (!quiet_flag) { |
135 | perror_msg("%s", dst_name); | ||
136 | } | ||
124 | return FALSE; | 137 | return FALSE; |
125 | } | 138 | } |
126 | } else if (S_ISREG(srcStatBuf.st_mode)) { | 139 | } else if (S_ISREG(srcStatBuf.st_mode)) { |
127 | //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); | 140 | //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); |
128 | rfd = open(srcName, O_RDONLY); | 141 | src_file = fopen(src_name, "r"); |
129 | if (rfd < 0) { | 142 | if (src_file == NULL) { |
130 | perror_msg("%s", srcName); | 143 | if (!quiet_flag) { |
144 | perror_msg("%s", src_name); | ||
145 | } | ||
131 | return FALSE; | 146 | return FALSE; |
132 | } | 147 | } |
133 | 148 | ||
134 | wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, | 149 | dst_file = fopen(dst_name, "w"); |
135 | srcStatBuf.st_mode); | 150 | if (dst_file == NULL) { |
136 | if (wfd < 0) { | 151 | if (!quiet_flag) { |
137 | perror_msg("%s", destName); | 152 | perror_msg("%s", dst_name); |
138 | close(rfd); | 153 | } |
154 | fclose(src_file); | ||
139 | return FALSE; | 155 | return FALSE; |
140 | } | 156 | } |
141 | 157 | ||
142 | if (copy_file_chunk(rfd, wfd, srcStatBuf.st_size)==FALSE) | 158 | if (copy_file_chunk(src_file, dst_file, srcStatBuf.st_size)==FALSE) { |
143 | goto error_exit; | 159 | goto error_exit; |
144 | 160 | } | |
145 | close(rfd); | 161 | |
146 | if (close(wfd) < 0) { | 162 | fclose(src_file); |
163 | if (fclose(dst_file) < 0) { | ||
147 | return FALSE; | 164 | return FALSE; |
148 | } | 165 | } |
149 | } | 166 | } |
150 | 167 | ||
151 | if (setModes == TRUE) { | 168 | if (set_modes == TRUE) { |
152 | /* This is fine, since symlinks never get here */ | 169 | /* This is fine, since symlinks never get here */ |
153 | if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) | 170 | if (chown(dst_name, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) |
154 | perror_msg_and_die("%s", destName); | 171 | perror_msg("%s", dst_name); |
155 | if (chmod(destName, srcStatBuf.st_mode) < 0) | 172 | if (chmod(dst_name, srcStatBuf.st_mode) < 0) |
156 | perror_msg_and_die("%s", destName); | 173 | perror_msg("%s", dst_name); |
157 | times.actime = srcStatBuf.st_atime; | 174 | times.actime = srcStatBuf.st_atime; |
158 | times.modtime = srcStatBuf.st_mtime; | 175 | times.modtime = srcStatBuf.st_mtime; |
159 | if (utime(destName, ×) < 0) | 176 | if (utime(dst_name, ×) < 0) |
160 | perror_msg_and_die("%s", destName); | 177 | perror_msg("%s", dst_name); |
161 | } | 178 | } |
162 | 179 | ||
163 | return TRUE; | 180 | return TRUE; |
164 | 181 | ||
165 | error_exit: | 182 | error_exit: |
166 | perror_msg("%s", destName); | 183 | perror_msg("%s", dst_name); |
167 | close(rfd); | 184 | fclose(src_file); |
168 | close(wfd); | 185 | fclose(dst_file); |
169 | 186 | ||
170 | return FALSE; | 187 | return FALSE; |
171 | } | 188 | } |