mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-20 19:43:01 +00:00
894cf70dd5
2004-01-28 Michael Natterer <mitch@gimp.org> Added infrastructure to make sure we don't write to the global brush, pattern etc. directories. Needed to make this configurable because we can't rely on the global directories being read-only, having certain names or being otherwise detectable at runtime in a sane way. Fixes bug #132214. * libgimpbase/gimpdatafiles.[ch]: added "const gchar *dirname" to the GimpDataFileData struct so callbacks don't need to call g_path_get_dirname() for each file. * libgimpwidgets/gimpfileentry.c: made it work with non UTF-8 encoded filenames. * libgimpwidgets/gimppatheditor.[ch]: ditto. Added GUI and API for setting/getting a second "writable_path". The widget makes sure that the writable_path is always a subset of the path. * app/config/gimpconfig-utils.[ch]: added new function gimp_config_build_writable_path(). * app/config/gimpcoreconfig.[ch]: added separate properties for the writable brush, pattern, gradient, palette and font paths. * app/config/gimprc-blurbs.h: added (still empty) blurbs for the new properties. * app/core/gimpdata.[ch] (gimp_data_set_filename): added parameter "gboolean writable". Set data->writable to FALSE by default. If "writable" is passed as TRUE, still check if we can write to the file before setting data->writable to TRUE. (gimp_data_create_filename): changed "data_path" parameter to "dest_dir" and assume dest_dir is writable. (gimp_data_duplicate): set data->dirty to TRUE to make sure duplicated things will be saved. * app/core/gimpbrush.c * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c * app/core/gimpgradient.c * app/core/gimppalette.c * app/core/gimppattern.c: don't set the data's filename and don't touch data->dirty in the _load() functions because that's done by the data factory now. Don't touch data->dirty in the _duplicate() functions because that's done by gimp_data_duplicate() itself now. * app/core/gimpdatafactory.[ch] (gimp_data_factory_new): added "writable_property_name" and remember it. Added utility function gimp_data_factory_get_save_dir() which determines the directory to save new datas to. Added public function gimp_data_factory_data_save_single() which saves a single data object. Make sure new things get saved to the first writable directory as specified in preferences. * app/core/gimp.c (gimp_real_initialize): pass the writable_paths' property names to gimp_data_factory_new(). * app/widgets/gimpdataeditor.c (gimp_data_editor_save_dirty): use gimp_data_factory_data_save_single() instead of implementing saving here. * app/widgets/gimppropwidgets.[ch] (gimp_prop_path_editor_new): added "const gchar *writable_property_name" parameter (can be NULL). Added the needed callbacks to handle the writable_path and made the path_editor and file_entry code aware of non UTF-8 filename encodings. Some general cleanup. * app/gui/preferences-dialog.c: changed accordingly.
196 lines
5.1 KiB
C
196 lines
5.1 KiB
C
/* LIBGIMP - The GIMP Library
|
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
|
*
|
|
* Datafiles module copyight (C) 1996 Federico Mena Quintero
|
|
* federico@nuclecu.unam.mx
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <glib-object.h>
|
|
|
|
#ifdef G_OS_WIN32
|
|
#include "gimpwin32-io.h"
|
|
#endif /* G_OS_WIN32 */
|
|
|
|
#include "gimpbasetypes.h"
|
|
|
|
#include "gimpdatafiles.h"
|
|
#include "gimpenv.h"
|
|
|
|
|
|
#ifdef G_OS_WIN32
|
|
/*
|
|
* On Windows there is no concept like the Unix executable flag.
|
|
* There is a weak emulation provided by the MS C Runtime using file
|
|
* extensions (com, exe, cmd, bat). This needs to be extended to treat
|
|
* scripts (Python, Perl, ...) as executables, too. We use the PATHEXT
|
|
* variable, which is also used by cmd.exe.
|
|
*/
|
|
static gboolean
|
|
is_script (const gchar *filename)
|
|
{
|
|
static gchar **exts = NULL;
|
|
|
|
const gchar *ext = strrchr (filename, '.');
|
|
gchar *pathext;
|
|
gint i;
|
|
|
|
if (exts == NULL)
|
|
{
|
|
pathext = g_getenv ("PATHEXT");
|
|
if (pathext != NULL)
|
|
{
|
|
exts = g_strsplit (pathext, G_SEARCHPATH_SEPARATOR_S, 100);
|
|
}
|
|
else
|
|
{
|
|
exts = g_new (gchar *, 1);
|
|
exts[0] = NULL;
|
|
}
|
|
}
|
|
|
|
i = 0;
|
|
while (exts[i] != NULL)
|
|
{
|
|
if (g_strcasecmp (ext, exts[i]) == 0)
|
|
return TRUE;
|
|
i++;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
#else /* !G_OS_WIN32 */
|
|
#define is_script(filename) FALSE
|
|
#endif
|
|
|
|
gboolean
|
|
gimp_datafiles_check_extension (const gchar *filename,
|
|
const gchar *extension)
|
|
{
|
|
gint name_len;
|
|
gint ext_len;
|
|
|
|
g_return_val_if_fail (filename != NULL, FALSE);
|
|
g_return_val_if_fail (extension != NULL, FALSE);
|
|
|
|
name_len = strlen (filename);
|
|
ext_len = strlen (extension);
|
|
|
|
if (! (name_len && ext_len && (name_len > ext_len)))
|
|
return FALSE;
|
|
|
|
return (g_ascii_strcasecmp (&filename[name_len - ext_len], extension) == 0);
|
|
}
|
|
|
|
void
|
|
gimp_datafiles_read_directories (const gchar *path_str,
|
|
GFileTest flags,
|
|
GimpDatafileLoaderFunc loader_func,
|
|
gpointer user_data)
|
|
{
|
|
GimpDatafileData file_data = { 0 };
|
|
struct stat filestat;
|
|
gchar *local_path;
|
|
GList *path;
|
|
GList *list;
|
|
gchar *filename;
|
|
gint err;
|
|
GDir *dir;
|
|
const gchar *dir_ent;
|
|
|
|
g_return_if_fail (path_str != NULL);
|
|
g_return_if_fail (loader_func != NULL);
|
|
|
|
local_path = g_strdup (path_str);
|
|
|
|
path = gimp_path_parse (local_path, 16, TRUE, NULL);
|
|
|
|
for (list = path; list; list = g_list_next (list))
|
|
{
|
|
dir = g_dir_open ((gchar *) list->data, 0, NULL);
|
|
|
|
if (dir)
|
|
{
|
|
while ((dir_ent = g_dir_read_name (dir)))
|
|
{
|
|
filename = g_build_filename ((gchar *) list->data,
|
|
dir_ent, NULL);
|
|
|
|
err = stat (filename, &filestat);
|
|
|
|
file_data.filename = filename;
|
|
file_data.dirname = (gchar *) list->data;
|
|
file_data.basename = dir_ent;
|
|
file_data.atime = filestat.st_atime;
|
|
file_data.mtime = filestat.st_mtime;
|
|
file_data.ctime = filestat.st_ctime;
|
|
|
|
if (! err)
|
|
{
|
|
if (flags & G_FILE_TEST_EXISTS)
|
|
{
|
|
(* loader_func) (&file_data, user_data);
|
|
}
|
|
else if ((flags & G_FILE_TEST_IS_REGULAR) &&
|
|
S_ISREG (filestat.st_mode))
|
|
{
|
|
(* loader_func) (&file_data, user_data);
|
|
}
|
|
else if ((flags & G_FILE_TEST_IS_DIR) &&
|
|
S_ISDIR (filestat.st_mode))
|
|
{
|
|
(* loader_func) (&file_data, user_data);
|
|
}
|
|
#ifndef G_OS_WIN32
|
|
else if ((flags & G_FILE_TEST_IS_SYMLINK) &&
|
|
S_ISLNK (filestat.st_mode))
|
|
{
|
|
(* loader_func) (&file_data, user_data);
|
|
}
|
|
#endif
|
|
else if ((flags & G_FILE_TEST_IS_EXECUTABLE) &&
|
|
(((filestat.st_mode & S_IXUSR) &&
|
|
!S_ISDIR (filestat.st_mode)) ||
|
|
(S_ISREG (filestat.st_mode) &&
|
|
is_script (filename))))
|
|
{
|
|
(* loader_func) (&file_data, user_data);
|
|
}
|
|
}
|
|
|
|
g_free (filename);
|
|
}
|
|
|
|
g_dir_close (dir);
|
|
}
|
|
}
|
|
|
|
gimp_path_free (path);
|
|
g_free (local_path);
|
|
}
|