2 * Copyright (C) 2010-2016 jeanfi@gmail.com
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * 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
19 #define _LARGEFILE_SOURCE 1
27 #include <sys/types.h>
32 /* Directory separator is \ when cross-compiling for MS Windows
35 #if defined(__MINGW32__)
41 #define FCOPY_BUF_SZ 4096
43 int is_dir(const char *path)
47 int ret = lstat(path, &st);
49 if (ret == 0 && S_ISDIR(st.st_mode))
55 int is_file(const char *path)
59 int ret = lstat(path, &st);
61 if (ret == 0 && S_ISREG(st.st_mode))
67 static char *dir_normalize(const char *dpath)
72 if (!dpath || !strlen(dpath))
75 npath = strdup(dpath);
79 if (n > 1 && npath[n - 1] == '/')
85 static char **paths_add(char **paths, int n, char *path)
89 result = malloc((n+1) * sizeof(void *));
91 memcpy(result + 1, paths, n * sizeof(void *));
98 char **dir_list(const char *dpath, int (*filter) (const char *))
102 char **paths, *path, *name, **tmp;
105 dir = opendir(dpath);
111 paths = malloc(sizeof(void *));
114 while ((ent = readdir(dir)) != NULL) {
117 if (!strcmp(name, ".") || !strcmp(name, ".."))
120 path = path_append(dpath, name);
122 if (!filter || filter(path)) {
123 tmp = paths_add(paths, n, path);
138 void paths_free(char **paths)
152 char *file_get_content(const char *fpath)
158 size = file_get_size(fpath);
162 } else if (size == 0) {
167 FILE *fp = fopen(fpath, "rb");
170 page = malloc(size + 1);
171 if (!page || size != fread(page, 1, size, fp)) {
175 *(page + size) = '\0';
187 long file_get_size(const char *path)
195 fp = fopen(path, "rb");
197 if (fseek(fp, 0, SEEK_END) == -1)
210 #define FCOPY_BUF_SZ 4096
211 static int FILE_copy(FILE *src, FILE *dst)
214 char *buf = malloc(FCOPY_BUF_SZ);
218 return FILE_COPY_ERROR_ALLOC_BUFFER;
221 n = fread(buf, 1, FCOPY_BUF_SZ, src);
223 if (fwrite(buf, 1, n, dst) != n)
224 ret = FILE_COPY_ERROR_WRITE;
227 ret = FILE_COPY_ERROR_READ;
239 file_copy(const char *src, const char *dst)
244 log_fct("copy %s to %s", src, dst);
246 fsrc = fopen(src, "r");
249 fdst = fopen(dst, "w+");
252 ret = FILE_copy(fsrc, fdst);
255 ret = FILE_COPY_ERROR_OPEN_DST;
260 ret = FILE_COPY_ERROR_OPEN_SRC;
266 char *path_append(const char *dir, const char *path)
270 ndir = dir_normalize(dir);
272 if (!ndir && (!path || !strlen(path)))
278 } else if (!path || !strlen(path)) {
282 ret = malloc(strlen(ndir) + 1 + strlen(path) + 1);
293 void mkdirs(const char *dirs, mode_t mode)
298 log_fct("mkdirs %s", dirs);
301 dir = malloc(strlen(dirs) + 1);
305 if ((*c == DIRSEP || *c == '\0') && c != dirs) {
306 strncpy(dir, dirs, i);
321 file_copy_print_error(int code, const char *src, const char *dst)
326 case FILE_COPY_ERROR_OPEN_SRC:
327 printf("File copy error: failed to open %s.\n", src);
329 case FILE_COPY_ERROR_OPEN_DST:
330 printf("File copy error: failed to open %s.\n", dst);
332 case FILE_COPY_ERROR_READ:
333 printf("File copy error: failed to read %s.\n", src);
335 case FILE_COPY_ERROR_WRITE:
336 printf("File copy error: failed to write %s.\n", src);
338 case FILE_COPY_ERROR_ALLOC_BUFFER:
339 printf("File copy error: failed to allocate buffer.\n");
342 printf("File copy error: unknown error %d.\n", code);