2 Copyright (C) 2010-2014 wpitchoune@gmail.com
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include <sys/types.h>
31 /* Directory separator is \ when cross-compiling for MS Windows
33 #if defined(__MINGW32__)
39 #define FCOPY_BUF_SZ 4096
41 int is_dir(const char *path)
45 int ret = lstat(path, &st);
47 if (ret == 0 && S_ISDIR(st.st_mode))
53 int is_file(const char *path)
57 int ret = lstat(path, &st);
59 if (ret == 0 && S_ISREG(st.st_mode))
65 char *dir_normalize(const char *dpath)
70 if (!dpath || !strlen(dpath))
73 npath = strdup(dpath);
77 if (n > 1 && npath[n - 1] == '/')
83 char **dir_list(const char *dpath, int (*filter) (const char *path))
96 paths = malloc(sizeof(void *));
99 while ((ent = readdir(dir)) != NULL) {
101 char *name = ent->d_name;
103 if (!strcmp(name, ".") || !strcmp(name, ".."))
106 fpath = malloc(strlen(dpath) + 1 + strlen(name) + 1);
108 strcpy(fpath, dpath);
112 if (!filter || filter(fpath)) {
116 npaths = malloc(n * sizeof(void *));
117 memcpy(npaths + 1, paths, (n - 1) * sizeof(void *));
132 void paths_free(char **paths)
146 char *file_get_content(const char *fpath)
152 size = file_get_size(fpath);
156 } else if (size == 0) {
161 FILE *fp = fopen(fpath, "rb");
163 page = malloc(size + 1);
164 if (!page || size != fread(page, 1, size, fp)) {
169 *(page + size) = '\0';
180 long file_get_size(const char *path)
187 fp = fopen(path, "rb");
191 if (fseek(fp, 0, SEEK_END) == -1)
204 #define FCOPY_BUF_SZ 4096
205 static int FILE_copy(FILE *src, FILE *dst)
208 char *buf = malloc(FCOPY_BUF_SZ);
212 return FILE_COPY_ERROR_ALLOC_BUFFER;
215 n = fread(buf, 1, FCOPY_BUF_SZ, src);
217 if (fwrite(buf, 1, n, dst) != n)
218 ret = FILE_COPY_ERROR_WRITE;
221 ret = FILE_COPY_ERROR_READ;
233 file_copy(const char *src, const char *dst)
238 log_fct("copy %s to %s", src, dst);
240 fsrc = fopen(src, "r");
243 fdst = fopen(dst, "w+");
246 ret = FILE_copy(fsrc, fdst);
249 ret = FILE_COPY_ERROR_OPEN_DST;
254 ret = FILE_COPY_ERROR_OPEN_SRC;
260 char *path_append(const char *dir, const char *path)
264 ndir = dir_normalize(dir);
266 if (!ndir && (!path || !strlen(path)))
272 } else if (!path || !strlen(path)) {
276 ret = malloc(strlen(ndir) + 1 + strlen(path) + 1);
287 void mkdirs(const char *dirs, mode_t mode)
292 log_fct("mkdirs %s", dirs);
295 dir = malloc(strlen(dirs) + 1);
299 if ((*c == DIRSEP || *c == '\0') && c != dirs) {
300 strncpy(dir, dirs, i);
315 file_copy_print_error(int code, const char *src, const char *dst)
320 case FILE_COPY_ERROR_OPEN_SRC:
321 printf("File copy error: failed to open %s.\n", src);
323 case FILE_COPY_ERROR_OPEN_DST:
324 printf("File copy error: failed to open %s.\n", dst);
326 case FILE_COPY_ERROR_READ:
327 printf("File copy error: failed to read %s.\n", src);
329 case FILE_COPY_ERROR_WRITE:
330 printf("File copy error: failed to write %s.\n", src);
332 case FILE_COPY_ERROR_ALLOC_BUFFER:
333 printf("File copy error: failed to allocate buffer.\n");
336 printf("File copy error: unknown error %d.\n", code);
340 int dir_rcopy(const char *src, const char *dst)
346 int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
351 log_fct("copy dir %s to %s", src, dst);
353 paths = malloc(2 * sizeof(char *));
354 paths[0] = strdup(src);
357 ftsp = fts_open(paths, fts_options, NULL);
361 chp = fts_children(ftsp, 0);
365 n_dst = dir_normalize(dst);
367 while ((p = fts_read(ftsp)) != NULL) {
368 switch (p->fts_info) {
370 p_dst = path_append(n_dst,
371 p->fts_path + strlen(src) + 1);
376 p_dst = path_append(n_dst,
377 p->fts_path + strlen(src) + 1);
378 file_copy(p->fts_path, p_dst);