X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui_fileops.c;h=2c35490d3de436b31741b55aa554e2fe6ac3899a;hb=refs%2Fheads%2Fmaster;hp=f6b8ef9721513f0a6470d53497873b995d31c6b9;hpb=7fd292e32d3445f1cf7c60d2268f8a3c0d10d49b;p=geeqie.git diff --git a/src/ui_fileops.c b/src/ui_fileops.c deleted file mode 100644 index f6b8ef97..00000000 --- a/src/ui_fileops.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * (SLIK) SimpLIstic sKin functions - * (C) 2006 John Ellis - * Copyright (C) 2008 The Geeqie Team - * - * Author: John Ellis - * - * This software is released under the GNU General Public License (GNU GPL). - * Please read the included file COPYING for more information. - * This software comes with no warranty of any kind, use at your own risk! - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include /* for locale warning dialog */ - -#include "main.h" -#include "ui_fileops.h" - -#include "debug.h" -#include "ui_utildlg.h" /* for locale warning dialog */ - -/* - *----------------------------------------------------------------------------- - * generic file information and manipulation routines (public) - *----------------------------------------------------------------------------- - */ - - - -void print_term(const gchar *text_utf8) -{ - gchar *text_l; - - text_l = g_locale_from_utf8(text_utf8, -1, NULL, NULL, NULL); - printf((text_l) ? text_l : text_utf8); - g_free(text_l); -} - -static void encoding_dialog(const gchar *path); - -static gint encoding_dialog_idle(gpointer data) -{ - gchar *path = data; - - encoding_dialog(path); - g_free(path); - - return FALSE; -} - -static gint encoding_dialog_delay(gpointer data) -{ - g_idle_add(encoding_dialog_idle, data); - - return 0; -} - -static void encoding_dialog(const gchar *path) -{ - static gint warned_user = FALSE; - GenericDialog *gd; - GString *string; - const gchar *lc; - const gchar *bf; - - /* check that gtk is initialized (loop is level > 0) */ - if (gtk_main_level() == 0) - { - /* gtk not initialized */ - gtk_init_add(encoding_dialog_delay, g_strdup(path)); - return; - } - - if (warned_user) return; - warned_user = TRUE; - - lc = getenv("LANG"); - bf = getenv("G_BROKEN_FILENAMES"); - warned_user = TRUE; - - string = g_string_new(""); - g_string_append(string, "One or more filenames are not encoded with the preferred locale character set.\n"); - g_string_append_printf(string, "Operations on, and display of these files with %s may not succeed.\n\n", PACKAGE); - g_string_append(string, "If your filenames are not encoded in utf-8, try setting\n"); - g_string_append(string, "the environment variable G_BROKEN_FILENAMES=1\n"); - g_string_append_printf(string, "It appears G_BROKEN_FILENAMES is %s%s\n\n", - (bf) ? "set to " : "not set.", (bf) ? bf : ""); - g_string_append_printf(string, "The locale appears to be set to \"%s\"\n(set by the LANG environment variable)\n", (lc) ? lc : "undefined"); - if (lc && (strstr(lc, "UTF-8") || strstr(lc, "utf-8"))) - { - gchar *name; - name = g_convert(path, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL); - string = g_string_append(string, "\nPreferred encoding appears to be UTF-8, however the file:\n"); - g_string_append_printf(string, "\"%s\"\n%s encoded in valid UTF-8.\n", - (name) ? name : "[name not displayable]", - (g_utf8_validate(path, -1, NULL)) ? "is": "is NOT"); - g_free(name); - } - - gd = generic_dialog_new("Filename encoding locale mismatch", - GQ_WMCLASS, "locale warning", NULL, TRUE, NULL, NULL); - generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE); - - generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING, - "Filename encoding locale mismatch", string->str); - - gtk_widget_show(gd->dialog); - - g_string_free(string, TRUE); -} - -gchar *path_to_utf8(const gchar *path) -{ - gchar *utf8; - GError *error = NULL; - - if (!path) return NULL; - - utf8 = g_filename_to_utf8(path, -1, NULL, NULL, &error); - if (error) - { - printf("Unable to convert filename to UTF-8:\n%s\n%s\n", path, error->message); - g_error_free(error); - encoding_dialog(path); - } - if (!utf8) - { - /* just let it through, but bad things may happen */ - utf8 = g_strdup(path); - } - - return utf8; -} - -gchar *path_from_utf8(const gchar *utf8) -{ - gchar *path; - GError *error = NULL; - - if (!utf8) return NULL; - - path = g_filename_from_utf8(utf8, -1, NULL, NULL, &error); - if (error) - { - printf("Unable to convert filename to locale from UTF-8:\n%s\n%s\n", utf8, error->message); - g_error_free(error); - } - if (!path) - { - /* if invalid UTF-8, text probaby still in original form, so just copy it */ - path = g_strdup(utf8); - } - - return path; -} - -/* first we try the HOME environment var, if that doesn't work, we try getpwuid(). */ -const gchar *homedir(void) -{ - static gchar *home = NULL; - - if (!home) - { - home = path_to_utf8(getenv("HOME")); - } - if (!home) - { - struct passwd *pw = getpwuid(getuid()); - if (pw) home = path_to_utf8(pw->pw_dir); - } - - return home; -} - -gint stat_utf8(const gchar *s, struct stat *st) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - sl = path_from_utf8(s); - ret = (stat(sl, st) == 0); - g_free(sl); - - return ret; -} - -gint lstat_utf8(const gchar *s, struct stat *st) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - sl = path_from_utf8(s); - ret = (lstat(sl, st) == 0); - g_free(sl); - - return ret; -} - -gint isname(const gchar *s) -{ - struct stat st; - - return stat_utf8(s, &st); -} - -gint isfile(const gchar *s) -{ - struct stat st; - - return (stat_utf8(s, &st) && S_ISREG(st.st_mode)); -} - -gint isdir(const gchar *s) -{ - struct stat st; - - return (stat_utf8(s ,&st) && S_ISDIR(st.st_mode)); -} - -gint islink(const gchar *s) -{ - struct stat st; - - return (lstat_utf8(s ,&st) && S_ISLNK(st.st_mode)); -} - -gint64 filesize(const gchar *s) -{ - struct stat st; - - if (!stat_utf8(s, &st)) return 0; - return (gint)st.st_size; -} - -time_t filetime(const gchar *s) -{ - struct stat st; - - if (!stat_utf8(s, &st)) return 0; - return st.st_mtime; -} - -gint filetime_set(const gchar *s, time_t tval) -{ - gint ret = FALSE; - - if (tval > 0) - { - struct utimbuf ut; - gchar *sl; - - ut.actime = ut.modtime = tval; - - sl = path_from_utf8(s); - ret = (utime(sl, &ut) == 0); - g_free(sl); - } - - return ret; -} - -gint access_file(const gchar *s, int mode) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - - sl = path_from_utf8(s); - ret = (access(sl, mode) == 0); - g_free(sl); - - return ret; -} - -gint unlink_file(const gchar *s) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - - sl = path_from_utf8(s); - ret = (unlink(sl) == 0); - g_free(sl); - - return ret; -} - -gint symlink_utf8(const gchar *source, const gchar *target) -{ - gchar *sl; - gchar *tl; - gint ret; - - if (!source || !target) return FALSE; - - sl = path_from_utf8(source); - tl = path_from_utf8(target); - - ret = (symlink(sl, tl) == 0); - - g_free(sl); - g_free(tl); - - return ret; -} - -gint mkdir_utf8(const gchar *s, int mode) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - - sl = path_from_utf8(s); - ret = (mkdir(sl, mode) == 0); - g_free(sl); - return ret; -} - -gint rmdir_utf8(const gchar *s) -{ - gchar *sl; - gint ret; - - if (!s) return FALSE; - - sl = path_from_utf8(s); - ret = (rmdir(sl) == 0); - g_free(sl); - - return ret; -} - -gint copy_file_attributes(const gchar *s, const gchar *t, gint perms, gint mtime) -{ - struct stat st; - gchar *sl, *tl; - gint ret = FALSE; - - if (!s || !t) return FALSE; - - sl = path_from_utf8(s); - tl = path_from_utf8(t); - - if (stat(sl, &st) == 0) - { - struct utimbuf tb; - - ret = TRUE; - - /* set the dest file attributes to that of source (ignoring errors) */ - - if (perms && chown(tl, st.st_uid, st.st_gid) < 0) ret = FALSE; - if (perms && chmod(tl, st.st_mode) < 0) ret = FALSE; - - tb.actime = st.st_atime; - tb.modtime = st.st_mtime; - if (mtime && utime(tl, &tb) < 0) ret = FALSE; - } - - g_free(sl); - g_free(tl); - - return ret; -} - -/* paths are in filesystem encoding */ -static gint hard_linked(const gchar *a, const gchar *b) -{ - struct stat sta; - struct stat stb; - - if (stat(a, &sta) != 0 || stat(b, &stb) != 0) return FALSE; - - return (sta.st_dev == stb.st_dev && - sta.st_ino == stb.st_ino); -} - -gint copy_file(const gchar *s, const gchar *t) -{ - FILE *fi = NULL; - FILE *fo = NULL; - gchar *sl, *tl; - gchar buf[4096]; - gint b; - - sl = path_from_utf8(s); - tl = path_from_utf8(t); - - if (hard_linked(sl, tl)) - { - g_free(sl); - g_free(tl); - return TRUE; - } - - fi = fopen(sl, "rb"); - if (fi) - { - fo = fopen(tl, "wb"); - if (!fo) - { - fclose(fi); - fi = NULL; - } - } - - g_free(sl); - g_free(tl); - - if (!fi || !fo) return FALSE; - - while ((b = fread(buf, sizeof(char), sizeof(buf), fi)) && b != 0) - { - if (fwrite(buf, sizeof(char), b, fo) != b) - { - fclose(fi); - fclose(fo); - return FALSE; - } - } - - fclose(fi); - fclose(fo); - - copy_file_attributes(s, t, TRUE, TRUE); - - return TRUE; -} - -gint move_file(const gchar *s, const gchar *t) -{ - gchar *sl, *tl; - gint ret = TRUE; - - if (!s || !t) return FALSE; - - sl = path_from_utf8(s); - tl = path_from_utf8(t); - if (rename(sl, tl) < 0) - { - /* this may have failed because moving a file across filesystems - was attempted, so try copy and delete instead */ - if (copy_file(s, t)) - { - if (unlink(sl) < 0) - { - /* err, now we can't delete the source file so return FALSE */ - ret = FALSE; - } - } - else - { - ret = FALSE; - } - } - g_free(sl); - g_free(tl); - - return ret; -} - -gint rename_file(const gchar *s, const gchar *t) -{ - gchar *sl, *tl; - gint ret; - - if (!s || !t) return FALSE; - - sl = path_from_utf8(s); - tl = path_from_utf8(t); - ret = (rename(sl, tl) == 0); - g_free(sl); - g_free(tl); - - return ret; -} - -gchar *get_current_dir(void) -{ - gchar *pathl; - gchar *path8; - - pathl = g_get_current_dir(); - path8 = path_to_utf8(pathl); - g_free(pathl); - - return path8; -} - -static gint path_list_real(const gchar *path, GList **files, GList **dirs, - gint follow_links) -{ - DIR *dp; - struct dirent *dir; - GList *f_list = NULL; - GList *d_list = NULL; - gchar *pathl; - - if (!path) return FALSE; - - pathl = path_from_utf8(path); - dp = opendir(pathl); - if (!dp) - { - /* dir not found */ - g_free(pathl); - return FALSE; - } - - /* root dir fix */ - if (pathl[0] == '/' && pathl[1] == '\0') - { - g_free(pathl); - pathl = g_strdup(""); - } - - while ((dir = readdir(dp)) != NULL) - { - struct stat st_buf; - gchar *name; - gchar *filepath; - gint result; - - name = dir->d_name; - filepath = g_strconcat(pathl, "/", name, NULL); - - if (follow_links) - { - result = stat(filepath, &st_buf); - } - else - { - result = lstat(filepath, &st_buf); - } - - if (result == 0) - { - gchar *path8; - gchar *name8; - - name8 = path_to_utf8(name); - path8 = g_strconcat(path, "/", name8, NULL); - g_free(name8); - - if (dirs && S_ISDIR(st_buf.st_mode) && - !(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ) - { - d_list = g_list_prepend(d_list, path8); - path8 = NULL; - } - else if (files && - (S_ISREG(st_buf.st_mode) || (!follow_links && S_ISLNK(st_buf.st_mode))) ) - { - f_list = g_list_prepend(f_list, path8); - path8 = NULL; - } - g_free(path8); - } - - g_free(filepath); - } - - closedir(dp); - - g_free(pathl); - - if (dirs) *dirs = g_list_reverse(d_list); - if (files) *files = g_list_reverse(f_list); - - return TRUE; -} - -gint path_list(const gchar *path, GList **files, GList **dirs) -{ - return path_list_real(path, files, dirs, TRUE); -} - -gint path_list_lstat(const gchar *path, GList **files, GList **dirs) -{ - return path_list_real(path, files, dirs, FALSE); -} - -void path_list_free(GList *list) -{ - g_list_foreach(list, (GFunc)g_free, NULL); - g_list_free(list); -} - -GList *path_list_copy(GList *list) -{ - GList *new_list = NULL; - GList *work; - - work = list; - while (work) - { - gchar *path; - - path = work->data; - work = work->next; - - new_list = g_list_prepend(new_list, g_strdup(path)); - } - - return g_list_reverse(new_list); -} - -long checksum_simple(const gchar *path) -{ - gchar *path8; - FILE *f; - long sum = 0; - gint c; - - path8 = path_from_utf8(path); - f = fopen(path8, "r"); - g_free(path8); - if (!f) return -1; - - while ((c = fgetc(f)) != EOF) - { - sum += c; - } - - fclose(f); - - return sum; -} - -gchar *unique_filename(const gchar *path, const gchar *ext, const gchar *divider, gint pad) -{ - gchar *unique; - gint n = 1; - - if (!ext) ext = ""; - if (!divider) divider = ""; - - unique = g_strconcat(path, ext, NULL); - while (isname(unique)) - { - g_free(unique); - if (pad) - { - unique = g_strdup_printf("%s%s%03d%s", path, divider, n, ext); - } - else - { - unique = g_strdup_printf("%s%s%d%s", path, divider, n, ext); - } - n++; - if (n > 999) - { - /* well, we tried */ - g_free(unique); - return NULL; - } - } - - return unique; -} - -gchar *unique_filename_simple(const gchar *path) -{ - gchar *unique; - const gchar *name; - const gchar *ext; - - if (!path) return NULL; - - name = filename_from_path(path); - if (!name) return NULL; - - ext = extension_from_path(name); - - if (!ext) - { - unique = unique_filename(path, NULL, "_", TRUE); - } - else - { - gchar *base; - - base = remove_extension_from_path(path); - unique = unique_filename(base, ext, "_", TRUE); - g_free(base); - } - - return unique; -} - -const gchar *filename_from_path(const gchar *path) -{ - const gchar *base; - - if (!path) return NULL; - - base = strrchr(path, '/'); - if (base) return base + 1; - - return path; -} - -gchar *remove_level_from_path(const gchar *path) -{ - gint p = 0, n = -1; - - if (!path) return NULL; - - while (path[p]) - { - if (path[p] == '/') n = p; - p++; - } - if (n <= 0) n++; - - return g_strndup(path, (gsize) n); -} - -gchar *concat_dir_and_file(const gchar *base, const gchar *name) -{ - if (!base || !name) return NULL; - - if (strcmp(base, "/") == 0) return g_strconcat(base, name, NULL); - - return g_strconcat(base, "/", name, NULL); -} - -const gchar *extension_from_path(const gchar *path) -{ - if (!path) return NULL; - return strrchr(path, '.'); -} - -gint file_extension_match(const gchar *path, const gchar *ext) -{ - gint p; - gint e; - - if (!path) return FALSE; - if (!ext) return TRUE; - - p = strlen(path); - e = strlen(ext); - - return (p > e && strncasecmp(path + p - e, ext, e) == 0); -} - -gchar *remove_extension_from_path(const gchar *path) -{ - gint p = 0, n = -1; - - if (!path) return NULL; - - while (path[p]) - { - if (path[p] == '.') n = p; - p++; - } - if (n < 0) n = p; - - return g_strndup(path, (gsize) n); -} - -void parse_out_relatives(gchar *path) -{ - gint s, t; - - if (!path) return; - - s = t = 0; - - while (path[s] != '\0') - { - if (path[s] == '/' && path[s+1] == '.' && (path[s+2] == '/' || path[s+2] == '\0') ) - { - s += 2; - } - else if (path[s] == '/' && path[s+1] == '.' && path[s+2] == '.' && (path[s+3] == '/' || path[s+3] == '\0') ) - { - s += 3; - if (t > 0) t--; - while (path[t] != '/' && t > 0) t--; - } - else - { - if (s != t) path[t] = path[s]; - t++; - s++; - } - } - if (t == 0 && path[t] == '/') t++; - if (t > 1 && path[t-1] == '/') t--; - path[t] = '\0'; -} - -gint file_in_path(const gchar *name) -{ - gchar *path; - gchar *namel; - gint p, l; - gint ret = FALSE; - - if (!name) return FALSE; - path = g_strdup(getenv("PATH")); - if (!path) return FALSE; - namel = path_from_utf8(name); - - p = 0; - l = strlen(path); - while (p < l && !ret) - { - gchar *f; - gint e = p; - while (path[e] != ':' && path[e] != '\0') e++; - path[e] = '\0'; - e++; - f = g_strconcat(path + p, "/", namel, NULL); - if (isfile(f)) ret = TRUE; - g_free(f); - p = e; - } - g_free(namel); - g_free(path); - - return ret; -}