aboutsummaryrefslogtreecommitdiff
path: root/libbb/copy_file.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2001-04-11 16:23:35 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2001-04-11 16:23:35 +0000
commit4949faf4b2090ca23c2aeb34535fdbe57754913a (patch)
treeb292a499341d3c0314283e2822a93241a1c4e1dd /libbb/copy_file.c
parent5b20d02ea98c41bbd8a49cdbb84f425fa9ef446e (diff)
downloadbusybox-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.c133
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 */
43int 43int
44copy_file(const char *srcName, const char *destName, 44copy_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, &times) < 0) 176 if (utime(dst_name, &times) < 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: 182error_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}