fixing 20 VS waring msg
[reactos.git] / reactos / tools / rcopy.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <sys/stat.h>
5 #include <utime.h>
6 #ifdef WIN32
7 #include <io.h>
8 #include <dos.h>
9 #else
10 #include <sys/io.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <dirent.h>
14 #include <unistd.h>
15 #include <string.h>
16 #endif
17 #ifndef MAX_PATH
18 #define MAX_PATH 260
19 #endif
20 #ifndef WIN32
21 #define DIR_SEPARATOR_CHAR '/'
22 #define DIR_SEPARATOR_STRING "/"
23 #else
24 #define DIR_SEPARATOR_CHAR '\\'
25 #define DIR_SEPARATOR_STRING "\\"
26 #endif
27
28 char *
29 make_absolute(char *absolute, char *path)
30 {
31 #ifndef WIN32
32 if (path[0] == DIR_SEPARATOR_CHAR)
33 {
34 strcpy(absolute, path);
35 }
36 else
37 {
38 getcwd(absolute, MAX_PATH);
39 strcat(absolute, DIR_SEPARATOR_STRING);
40 strcat(absolute, path);
41 }
42 #else
43 _fullpath(absolute, path, MAX_PATH);
44 #endif
45
46 return absolute;
47 }
48
49 char* convert_path(char* origpath)
50 {
51 char* newpath;
52 int i;
53
54 //newpath = strdup(origpath);
55 newpath = malloc(strlen(origpath)+1);
56 strcpy(newpath, origpath);
57
58 i = 0;
59 while (newpath[i] != 0)
60 {
61 #ifdef UNIX_PATHS
62 if (newpath[i] == '\\')
63 {
64 newpath[i] = '/';
65 }
66 #else
67 #ifdef DOS_PATHS
68 if (newpath[i] == '/')
69 {
70 newpath[i] = '\\';
71 }
72 #endif
73 #endif
74 i++;
75 }
76 return(newpath);
77 }
78
79 #define TRANSFER_SIZE (65536)
80
81 static void
82 copy_file(char* path1, char* path2)
83 {
84 FILE* in;
85 FILE* out;
86 char* buf;
87 int n_in;
88 int n_out;
89 struct stat st_buffer;
90 struct utimbuf ut_buffer;
91
92 in = fopen(path1, "rb");
93 if (in == NULL)
94 {
95 perror("Cannot open input file");
96 exit(1);
97 }
98
99 out = fopen(path2, "wb");
100 if (out == NULL)
101 {
102 perror("Cannot open output file");
103 fclose(in);
104 exit(1);
105 }
106
107 buf = malloc(TRANSFER_SIZE);
108 while (!feof(in))
109 {
110 n_in = fread(buf, 1, TRANSFER_SIZE, in);
111 n_out = fwrite(buf, 1, n_in, out);
112 if (n_in != n_out)
113 {
114 perror("Failed to write to output file\n");
115 free(buf);
116 fclose(in);
117 fclose(out);
118 exit(1);
119 }
120 }
121 free(buf);
122 fclose(in);
123 fclose(out);
124
125 if (stat(path2, &st_buffer) >= 0)
126 {
127 ut_buffer.actime = st_buffer.st_atime;
128
129 if (stat(path1, &st_buffer) >= 0)
130 {
131 ut_buffer.modtime = st_buffer.st_mtime;
132 utime(path2, &ut_buffer);
133 }
134 }
135
136 }
137
138 #ifdef WIN32
139
140 static void
141 copy_directory (char *path1, char *path2)
142 {
143 struct _finddata_t f;
144 int findhandle;
145 char buf[MAX_PATH];
146 char tobuf[MAX_PATH];
147
148 strcpy(buf, path1);
149 if (path1[strlen(path1) - 1] != DIR_SEPARATOR_CHAR)
150 strcat(buf, DIR_SEPARATOR_STRING);
151 strcat(buf, "*.*");
152 findhandle =_findfirst(buf, &f);
153 if (findhandle != 0)
154 {
155 do
156 {
157 if ((f.attrib & _A_SUBDIR) == 0 && f.name[0] != '.')
158 {
159 // Convert to absolute path
160 make_absolute(buf, path1);
161 if (path1[strlen(path1) - 1] != DIR_SEPARATOR_CHAR)
162 strcat(buf, DIR_SEPARATOR_STRING);
163 strcat(buf, f.name);
164
165 //printf("copying file %s\n", buf);
166 if (path2[strlen(path2) - 1] == DIR_SEPARATOR_CHAR)
167 {
168 strcpy(tobuf, path2);
169 strcat(tobuf, f.name);
170 }
171 else
172 {
173 strcpy(tobuf, path2);
174 strcat(tobuf, DIR_SEPARATOR_STRING);
175 strcat(tobuf, f.name);
176 }
177 copy_file(buf, tobuf);
178 }
179 else
180 {
181 //printf("skipping directory '%s'\n", f.name);
182 }
183 }
184 while (_findnext(findhandle, &f) == 0);
185
186 _findclose(findhandle);
187 }
188 }
189
190 #else
191 /* Linux version */
192
193 static int
194 is_reg (char *path, char *fn)
195 {
196 char buf[MAX_PATH];
197 char buf2[MAX_PATH];
198 struct stat sbuf;
199
200 strcpy(buf, path);
201 if (buf[strlen(buf)-1] != '/')
202 strcat(buf, "/");
203 strcat(buf, fn);
204
205 make_absolute(buf2, buf);
206
207 if (stat(buf2, &sbuf) == -1)
208 return 0;
209 else {
210 if (S_ISREG(sbuf.st_mode))
211 return 1;
212 else
213 return 0;
214 }
215 }
216
217 static void
218 copy_directory (char *path1, char *path2)
219 {
220 DIR *dirp;
221 struct dirent *entry;
222 struct stat stbuf;
223 char buf[MAX_PATH];
224 char tobuf[MAX_PATH];
225 char err[400];
226
227 dirp = opendir(path1);
228
229 if (dirp != NULL)
230 {
231 while ((entry = readdir (dirp)) != NULL)
232 {
233 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
234 continue; // skip self and parent
235
236 if (entry->d_type == DT_REG || is_reg(path1, entry->d_name)) // normal file
237 {
238 // Convert to absolute path
239 make_absolute(buf, path1);
240 if (path1[strlen(path1) - 1] != DIR_SEPARATOR_CHAR)
241 strcat(buf, DIR_SEPARATOR_STRING);
242 strcat(buf, entry->d_name);
243 if (stat(buf, &stbuf) == -1)
244 {
245 sprintf(err, "Can't access '%s' (%s)\n", buf, strerror(errno));
246 perror(err);
247 exit(1);
248 return;
249 }
250
251 //printf("copying file '%s'\n", entry->d_name);
252 if (path2[strlen(path2) - 1] == DIR_SEPARATOR_CHAR)
253 {
254 strcpy(tobuf, path2);
255 strcat(tobuf, entry->d_name);
256 }
257 else
258 {
259 strcpy(tobuf, path2);
260 strcat(tobuf, DIR_SEPARATOR_STRING);
261 strcat(tobuf, entry->d_name);
262 }
263 copy_file(buf, tobuf);
264 }
265 else
266 {
267 //printf("skipping directory '%s'\n", entry->d_name);
268 }
269 }
270 closedir (dirp);
271 }
272 else
273 {
274 sprintf(err, "Can't open %s\n", path1);
275 perror(err);
276 exit(1);
277 return;
278 }
279 }
280
281 #endif
282
283 static int
284 is_directory(char *path)
285 {
286 struct stat stbuf;
287 char buf[MAX_PATH];
288
289 // Convert to absolute path
290 make_absolute(buf, path);
291 if (stat(buf, &stbuf) == -1)
292 {
293 /* Assume a destination file */
294 return 0;
295 }
296 if (S_ISDIR(stbuf.st_mode))
297 return 1;
298 else
299 return 0;
300 }
301
302 int main(int argc, char* argv[])
303 {
304 char* path1;
305 char* path2;
306 int dir1;
307 int dir2;
308
309 if (argc != 3)
310 {
311 fprintf(stderr, "Wrong argument count\n");
312 exit(1);
313 }
314
315 path1 = convert_path(argv[1]);
316 path2 = convert_path(argv[2]);
317
318 dir1 = is_directory(path1);
319 dir2 = is_directory(path2);
320
321 if ((dir1 && !dir2) || (!dir1 && dir2))
322 {
323 perror("None or both paramters must be a directory\n");
324 exit(1);
325 }
326
327 if (dir1)
328 {
329 copy_directory(path1, path2);
330 }
331 else
332 {
333 copy_file(path1, path2);
334 }
335
336 exit(0);
337 }