2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
9 #ifndef _FILE_OFFSET_BITS
10 # define _FILE_OFFSET_BITS 64
13 #ifdef HAVE_FEATURES_H
14 # include <features.h>
19 #include "ecore_file_private.h"
24 /* externally accessible functions */
26 * Initialize Ecore_File and the services it will use. Call this function
27 * once before you use any of the ecore file functions.
28 * @return Return the number howoften ecore_file_init() was call succesfully;
34 if (++init != 1) return init;
36 if (!ecore_file_monitor_init())
38 if (!ecore_file_path_init())
40 if (!ecore_file_download_init())
46 ecore_file_monitor_shutdown();
47 ecore_file_path_shutdown();
48 ecore_file_download_shutdown();
54 * Shutdown the Ecore_File
55 * @return returns the number of libraries that still uses Ecore_File
60 if (--init != 0) return init;
62 ecore_file_monitor_shutdown();
63 ecore_file_path_shutdown();
64 ecore_file_download_shutdown();
70 * Get the time of the last modification to the give file
71 * @param file The name of the file
72 * @return Return the time of the last data modification, if an error should
73 * occur it will return 0
76 ecore_file_mod_time(const char *file)
80 if (stat(file, &st) < 0) return 0;
85 * Get the size of the given file
86 * @param file The name of the file
87 * @return The size of the file in byte
90 ecore_file_size(const char *file)
94 if (stat(file, &st) < 0) return 0;
99 * Check if file exists
100 * @param file The name of the file
101 * @return 1 if file exists on local filesystem, 0 otherwise
104 ecore_file_exists(const char *file)
108 /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
109 if (stat(file, &st) < 0 && strcmp(file, "/")) return 0;
114 * Check if file is a directory
115 * @param file The name of the file
116 * @return 1 if file exist and is a directory, 0 otherwise
119 ecore_file_is_dir(const char *file)
123 if (stat(file, &st) < 0) return 0;
124 if (S_ISDIR(st.st_mode)) return 1;
128 static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
131 * Create a new directory
132 * @param dir The name of the directory to create
133 * @return 1 on successfull creation, 0 on failure
135 * The directory is created with the mode: S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
138 ecore_file_mkdir(const char *dir)
140 if (mkdir(dir, default_mode) < 0) return 0;
145 * Delete the given dir
146 * @param dir The name of the directory to delete
147 * @return 1 on success, 0 on failure
150 ecore_file_rmdir(const char *dir)
152 if (rmdir(dir) < 0) return 0;
157 * Delete the given file
158 * @param file The name of the file to delete
159 * @return 1 on success, 0 on failure
162 ecore_file_unlink(const char *file)
164 if (unlink(file) < 0) return 0;
169 * Delete a directory and all its contents
170 * @param dir The name of the directory to delete
171 * @return 1 on success, 0 on failure
173 * If dir is a link only the link is removed
176 ecore_file_recursive_rm(const char *dir)
185 if (readlink(dir, buf, sizeof(buf)) > 0)
187 return ecore_file_unlink(dir);
190 ret = stat(dir, &st);
191 if ((ret == 0) && (S_ISDIR(st.st_mode)))
194 if (stat(dir, &st) == -1) return 0;
198 while ((dp = readdir(dirp)))
200 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
202 snprintf(path, PATH_MAX, "%s/%s", dir, dp->d_name);
203 if (!ecore_file_recursive_rm(path))
209 if (!ecore_file_rmdir(dir)) ret = 0;
214 if (ret == -1) return 0;
215 return ecore_file_unlink(dir);
222 * Create a complete path
223 * @param path The path to create
224 * @return 1 on success, 0 on failure
227 ecore_file_mkpath(const char *path)
236 if (i == sizeof(ss) - 1) return 0;
242 if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0;
243 else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss);
248 if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0;
249 else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss);
255 * @param src The name of the source file
256 * @param dst The name of the destination file
257 * @return 1 on success, 0 on failure
260 ecore_file_cp(const char *src, const char *dst)
264 char realpath1[PATH_MAX];
265 char realpath2[PATH_MAX];
269 if (!realpath(src, realpath1)) return 0;
270 if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return 0;
272 f1 = fopen(src, "rb");
274 f2 = fopen(dst, "wb");
280 while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
282 if (fwrite(buf, 1, num, f2) != num) ret = 0;
291 * @param src The name of the source file
292 * @param dst The name of the destination file
293 * @return 1 on success, 0 on failure
296 ecore_file_mv(const char *src, const char *dst)
298 if (ecore_file_exists(dst)) return 0;
299 if (rename(src, dst))
306 if (S_ISREG(st.st_mode))
308 ecore_file_cp(src, dst);
309 chmod(dst, st.st_mode);
310 ecore_file_unlink(src);
320 * Create a symbolic link
321 * @param src The name of the file to link
322 * @param dest The name of link
323 * @return 1 on success, 0 on failure
326 ecore_file_symlink(const char *src, const char *dest)
328 if (!symlink(src, dest)) return 1;
334 * Get the canonicalized absolute pathname
335 * @param file The file path
336 * @return The canonicalized absolute pathname; on failure it will return
340 ecore_file_realpath(const char *file)
345 * Some implementations of realpath do not conform to the SUS.
346 * And as a result we must prevent a null arg from being passed.
348 if (!file) return strdup("");
349 if (!realpath(file, buf)) return strdup("");
355 * Get the filename from a give path
356 * @param path The complete path
357 * @return Only the file name
360 ecore_file_file_get(const char *path)
364 if (!path) return NULL;
365 if ((result = strrchr(path, '/'))) result++;
366 else result = (char *)path;
371 * Get the directory where file reside
372 * @param file The name of the file
373 * @return The directory name
376 ecore_file_dir_get(const char *file)
381 strncpy(buf, file, PATH_MAX);
382 p = strrchr(buf, '/');
388 if (p == buf) return strdup("/");
395 * Check if file can be read
396 * @param file The name of the file
397 * @return 1 if the file is readable, 0 otherwise
400 ecore_file_can_read(const char *file)
403 if (!access(file, R_OK)) return 1;
408 * Check if file can be written
409 * @param file The name of the file
410 * @return 1 if the file is writable, 0 otherwise
413 ecore_file_can_write(const char *file)
416 if (!access(file, W_OK)) return 1;
421 * Check if file can be executed
422 * @param file The name of the file
423 * @return 1 if the file can be executed, 0 otherwise
426 ecore_file_can_exec(const char *file)
429 if (!access(file, X_OK)) return 1;
434 * Get the path pointed by link
435 * @param link The name of the link
436 * @return The path pointed by link or NULL
439 ecore_file_readlink(const char *link)
444 if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL;
450 * Get the list of the files and directories in a given directory. The list
451 * will be sorted with strcoll as compare function. That means that you may
452 * want to set the current locale for the category LC_COLLATE with setlocale().
453 * For more information see the manual pages of strcoll and setlocale.
454 * The list will not contain the directory entries for '.' and '..'.
455 * @param dir The name of the directory to list
456 * @return Return an Ecore_List containing all the files in the directory;
457 * on failure it returns NULL.
460 ecore_file_ls(const char *dir)
468 if (!dirp) return NULL;
470 list = ecore_list_new();
471 ecore_list_free_cb_set(list, free);
473 while ((dp = readdir(dirp)))
475 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
477 f = strdup(dp->d_name);
478 ecore_list_append(list, f);
483 ecore_list_sort(list, ECORE_COMPARE_CB(strcoll), ECORE_SORT_MIN);
485 ecore_list_first_goto(list);
490 * FIXME: To be documented.
493 ecore_file_app_exe_get(const char *app)
495 char *p, *pp, *exe1 = NULL, *exe2 = NULL;
497 int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
499 if (!app) return NULL;
503 while ((*p) && (isspace(*p))) p++;
512 else if (in_quot_dbl)
523 if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
529 if (exe2 == exe1) return NULL;
538 homedir = getenv("HOME");
539 if (!homedir) return NULL;
540 len = strlen(homedir);
542 exe = malloc(len + exe2 - exe1 + 2);
543 if (!exe) return NULL;
547 strcpy(exe, homedir);
549 if (*(pp - 1) != '/')
559 exe = malloc(exe2 - exe1 + 1);
560 if (!exe) return NULL;
579 else if (in_quot_dbl)
585 /* techcincally this is wrong. double quotes also accept
596 /* technically we should handle special chars:
600 if ((p > exe1) && (p[-1] == '\\'))
608 else if ((p > exe1) && (*p == '='))
618 else if (isspace(*p))
638 * Add the escape sequence ('\\') to the given filename
639 * @param filename The file name
640 * @return The file name with special characters escaped; if the length of the
641 * resulting string is longer than PATH_MAX it will return NULL
644 ecore_file_escape_name(const char *filename)
654 if ((q - buf) > (PATH_MAX - 6)) return NULL;
656 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
657 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
658 (*p == ';') || (*p == '!') || (*p == '#') ||
659 (*p == '$') || (*p == '%') || (*p == '&') ||
660 (*p == '*') || (*p == '(') || (*p == ')') ||
661 (*p == '[') || (*p == ']') || (*p == '{') ||
662 (*p == '}') || (*p == '|') || (*p == '<') ||
663 (*p == '>') || (*p == '?')
678 * Remove the extension from a given path
679 * @param path The name of the file
680 * @return A newly allocated string with the extension stripped out or NULL on errors
683 ecore_file_strip_ext(const char *path)
685 char *p, *file = NULL;
687 p = strrchr(path, '.');
694 file = malloc(((p - path) + 1) * sizeof(char));
697 memcpy(file, path, (p - path));
706 * Check if the given directory is empty. The '.' and '..' files will be ignored.
707 * @param dir The name of the directory to check
708 * @return 1 if directory is empty, 0 if it has at least one file or -1 in case of errors
711 ecore_file_dir_is_empty(const char *dir)
717 if (!dirp) return -1;
719 while ((dp = readdir(dirp)))
721 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))