2006-05-21 18:11:05 -05:00
|
|
|
/*
|
|
|
|
* moofilesystem.c
|
2005-08-25 09:29:01 +00:00
|
|
|
*
|
2007-01-04 04:42:10 -06:00
|
|
|
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
2005-08-25 09:29:01 +00:00
|
|
|
*
|
2007-06-24 12:56:20 -05:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
2007-09-23 11:47:28 -05:00
|
|
|
* License version 2.1 as published by the Free Software Foundation.
|
2005-08-25 09:29:01 +00:00
|
|
|
*
|
|
|
|
* See COPYING file that comes with this distribution.
|
|
|
|
*/
|
|
|
|
|
2006-12-10 16:48:59 -06:00
|
|
|
#include <config.h>
|
|
|
|
|
2006-08-13 04:00:15 -05:00
|
|
|
#define MOO_FILE_VIEW_COMPILATION
|
2005-08-25 09:29:01 +00:00
|
|
|
#include "moofilesystem.h"
|
2006-12-09 01:51:10 -06:00
|
|
|
#include "moofolder-private.h"
|
2006-03-16 04:39:35 -06:00
|
|
|
#include "mooutils/mooutils-fs.h"
|
2008-01-18 21:45:53 -06:00
|
|
|
#include "mooutils/mooutils-mem.h"
|
2006-06-07 00:36:21 -05:00
|
|
|
#include "mooutils/moomarshals.h"
|
2005-08-25 09:29:01 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#ifndef __WIN32__
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#else
|
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
|
2007-08-20 22:15:58 -05:00
|
|
|
#if 0 && MOO_DEBUG_ENABLED
|
2006-12-10 16:48:59 -06:00
|
|
|
#define DEBUG_MESSAGE g_message
|
|
|
|
#else
|
|
|
|
static void DEBUG_MESSAGE (G_GNUC_UNUSED const char *format, ...)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
#define BROKEN_NAME "<" "????" ">"
|
2006-12-09 01:51:10 -06:00
|
|
|
#define FOLDERS_CACHE_SIZE 10
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GQueue *queue;
|
|
|
|
GHashTable *paths;
|
|
|
|
} FoldersCache;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
struct _MooFileSystemPrivate {
|
|
|
|
GHashTable *folders;
|
|
|
|
MooFileWatch *fam;
|
2006-12-09 01:51:10 -06:00
|
|
|
FoldersCache cache;
|
2007-03-13 01:29:11 -05:00
|
|
|
guint debug_timeout;
|
2005-08-25 09:29:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static MooFileSystem *fs_instance = NULL;
|
|
|
|
|
|
|
|
|
2006-12-31 04:53:45 -06:00
|
|
|
static void moo_file_system_dispose (GObject *object);
|
|
|
|
static char *_moo_file_system_normalize_path (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean is_folder,
|
|
|
|
GError **error);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
static MooFolder *get_folder (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
MooFileFlags wanted,
|
|
|
|
GError **error);
|
|
|
|
static gboolean create_folder (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
GError **error);
|
2006-03-10 22:41:41 -06:00
|
|
|
static MooFolder *get_parent_folder (MooFileSystem *fs,
|
|
|
|
MooFolder *folder,
|
|
|
|
MooFileFlags flags);
|
2006-04-16 12:14:12 -05:00
|
|
|
static gboolean delete_file (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean recursive,
|
|
|
|
GError **error);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
static gboolean move_file_unix (MooFileSystem *fs,
|
|
|
|
const char *old_path,
|
|
|
|
const char *new_path,
|
|
|
|
GError **error);
|
2007-01-04 04:42:10 -06:00
|
|
|
|
|
|
|
#ifndef __WIN32__
|
|
|
|
static MooFolder *get_root_folder_unix (MooFileSystem *fs,
|
|
|
|
MooFileFlags wanted);
|
2005-08-25 09:29:01 +00:00
|
|
|
static char *normalize_path_unix (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean is_folder,
|
|
|
|
GError **error);
|
|
|
|
static char *make_path_unix (MooFileSystem *fs,
|
|
|
|
const char *base_path,
|
|
|
|
const char *display_name,
|
|
|
|
GError **error);
|
|
|
|
static gboolean parse_path_unix (MooFileSystem *fs,
|
|
|
|
const char *path_utf8,
|
|
|
|
char **dirname,
|
|
|
|
char **display_dirname,
|
|
|
|
char **display_basename,
|
|
|
|
GError **error);
|
2005-09-02 23:27:25 +00:00
|
|
|
static char *get_absolute_path_unix (MooFileSystem *fs,
|
|
|
|
const char *display_name,
|
|
|
|
const char *current_dir);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
#else /* __WIN32__ */
|
|
|
|
|
|
|
|
static MooFolder *get_root_folder_win32 (MooFileSystem *fs,
|
|
|
|
MooFileFlags wanted);
|
2007-01-04 04:42:10 -06:00
|
|
|
#if 0
|
2005-08-25 09:29:01 +00:00
|
|
|
static gboolean move_file_win32 (MooFileSystem *fs,
|
|
|
|
const char *old_path,
|
|
|
|
const char *new_path,
|
|
|
|
GError **error);
|
2007-01-04 04:42:10 -06:00
|
|
|
#endif
|
2005-08-25 09:29:01 +00:00
|
|
|
static char *normalize_path_win32 (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean is_folder,
|
|
|
|
GError **error);
|
|
|
|
static char *make_path_win32 (MooFileSystem *fs,
|
|
|
|
const char *base_path,
|
|
|
|
const char *display_name,
|
|
|
|
GError **error);
|
|
|
|
static gboolean parse_path_win32 (MooFileSystem *fs,
|
|
|
|
const char *path_utf8,
|
|
|
|
char **dirname,
|
|
|
|
char **display_dirname,
|
|
|
|
char **display_basename,
|
|
|
|
GError **error);
|
2005-09-02 23:27:25 +00:00
|
|
|
static char *get_absolute_path_win32 (MooFileSystem *fs,
|
|
|
|
const char *display_name,
|
|
|
|
const char *current_dir);
|
2005-08-25 09:29:01 +00:00
|
|
|
#endif /* __WIN32__ */
|
|
|
|
|
|
|
|
|
|
|
|
/* MOO_TYPE_FILE_SYSTEM */
|
2006-05-13 16:09:46 -05:00
|
|
|
G_DEFINE_TYPE (MooFileSystem, _moo_file_system, G_TYPE_OBJECT)
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
static void
|
|
|
|
_moo_file_system_class_init (MooFileSystemClass *klass)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
gobject_class->dispose = moo_file_system_dispose;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
klass->get_folder = get_folder;
|
|
|
|
klass->create_folder = create_folder;
|
2006-03-10 22:41:41 -06:00
|
|
|
klass->get_parent_folder = get_parent_folder;
|
2006-04-16 12:14:12 -05:00
|
|
|
klass->delete_file = delete_file;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
#ifdef __WIN32__
|
|
|
|
klass->get_root_folder = get_root_folder_win32;
|
2007-01-04 04:42:10 -06:00
|
|
|
klass->move_file = move_file_unix;
|
2005-08-25 09:29:01 +00:00
|
|
|
klass->normalize_path = normalize_path_win32;
|
|
|
|
klass->make_path = make_path_win32;
|
|
|
|
klass->parse_path = parse_path_win32;
|
2005-09-02 23:27:25 +00:00
|
|
|
klass->get_absolute_path = get_absolute_path_win32;
|
2005-08-25 09:29:01 +00:00
|
|
|
#else /* !__WIN32__ */
|
|
|
|
klass->get_root_folder = get_root_folder_unix;
|
|
|
|
klass->move_file = move_file_unix;
|
|
|
|
klass->normalize_path = normalize_path_unix;
|
|
|
|
klass->make_path = make_path_unix;
|
|
|
|
klass->parse_path = parse_path_unix;
|
2005-09-02 23:27:25 +00:00
|
|
|
klass->get_absolute_path = get_absolute_path_unix;
|
2005-08-25 09:29:01 +00:00
|
|
|
#endif /* !__WIN32__ */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
static void
|
|
|
|
add_folder_cache (MooFileSystem *fs,
|
|
|
|
MooFolderImpl *impl)
|
|
|
|
{
|
|
|
|
FoldersCache *cache = &fs->priv->cache;
|
|
|
|
|
2006-12-10 16:48:59 -06:00
|
|
|
DEBUG_MESSAGE ("%s: adding folder %s to cache", G_STRFUNC, impl->path);
|
2006-12-09 01:51:10 -06:00
|
|
|
g_queue_push_head (cache->queue, impl);
|
|
|
|
g_hash_table_insert (cache->paths, impl->path, impl);
|
|
|
|
|
|
|
|
if (cache->queue->length > FOLDERS_CACHE_SIZE)
|
|
|
|
{
|
|
|
|
MooFolderImpl *old = g_queue_pop_tail (cache->queue);
|
|
|
|
g_hash_table_remove (cache->paths, old->path);
|
2006-12-10 16:48:59 -06:00
|
|
|
DEBUG_MESSAGE ("%s: removing folder %s from cache", G_STRFUNC, old->path);
|
2006-12-09 01:51:10 -06:00
|
|
|
_moo_folder_impl_free (old);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_file_system_folder_finalized (MooFileSystem *fs,
|
|
|
|
MooFolder *folder)
|
|
|
|
{
|
|
|
|
MooFolderImpl *impl;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_FILE_SYSTEM (fs));
|
|
|
|
g_return_if_fail (MOO_IS_FOLDER (folder));
|
|
|
|
|
|
|
|
impl = folder->impl;
|
|
|
|
folder->impl = NULL;
|
|
|
|
impl->proxy = NULL;
|
|
|
|
|
|
|
|
g_hash_table_remove (fs->priv->folders, impl->path);
|
|
|
|
|
|
|
|
if (!impl->deleted)
|
2006-12-10 16:48:59 -06:00
|
|
|
{
|
2006-12-09 01:51:10 -06:00
|
|
|
add_folder_cache (fs, impl);
|
2006-12-10 16:48:59 -06:00
|
|
|
}
|
2006-12-09 01:51:10 -06:00
|
|
|
else
|
2006-12-10 16:48:59 -06:00
|
|
|
{
|
|
|
|
DEBUG_MESSAGE ("%s: folder %s deleted, freeing", G_STRFUNC, impl->path);
|
2006-12-09 01:51:10 -06:00
|
|
|
_moo_folder_impl_free (impl);
|
2006-12-10 16:48:59 -06:00
|
|
|
}
|
2006-12-09 01:51:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-13 01:29:11 -05:00
|
|
|
static void
|
|
|
|
calc_mem_hash_cb (G_GNUC_UNUSED const char *name,
|
|
|
|
MooFolder *folder,
|
|
|
|
gsize *mem)
|
|
|
|
{
|
|
|
|
mem[0] += _moo_folder_mem_usage (folder);
|
|
|
|
mem[1] += g_hash_table_size (folder->impl->files);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
debug_timeout (MooFileSystem *fs)
|
|
|
|
{
|
|
|
|
gsize mem[2] = {0, 0};
|
|
|
|
g_hash_table_foreach (fs->priv->folders, (GHFunc) calc_mem_hash_cb, mem);
|
2007-06-20 13:46:39 -05:00
|
|
|
g_print ("%" G_GSIZE_FORMAT " bytes in %" G_GSIZE_FORMAT " files\n", mem[0], mem[1]);
|
2007-03-13 01:29:11 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
static void
|
|
|
|
_moo_file_system_init (MooFileSystem *fs)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
fs->priv = g_new0 (MooFileSystemPrivate, 1);
|
2006-12-09 01:51:10 -06:00
|
|
|
fs->priv->folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
fs->priv->cache.queue = g_queue_new ();
|
|
|
|
fs->priv->cache.paths = g_hash_table_new (g_str_hash, g_str_equal);
|
2007-03-13 01:29:11 -05:00
|
|
|
|
|
|
|
if (0)
|
|
|
|
fs->priv->debug_timeout = g_timeout_add (5000, (GSourceFunc) debug_timeout, fs);
|
2005-08-25 09:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
static void
|
2006-12-09 01:51:10 -06:00
|
|
|
moo_file_system_dispose (GObject *object)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
MooFileSystem *fs = MOO_FILE_SYSTEM (object);
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
if (fs->priv)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2006-12-09 01:51:10 -06:00
|
|
|
g_hash_table_destroy (fs->priv->folders);
|
|
|
|
g_hash_table_destroy (fs->priv->cache.paths);
|
|
|
|
g_queue_foreach (fs->priv->cache.queue, (GFunc) _moo_folder_impl_free, NULL);
|
|
|
|
g_queue_free (fs->priv->cache.queue);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
if (fs->priv->fam)
|
|
|
|
{
|
|
|
|
moo_file_watch_close (fs->priv->fam, NULL);
|
|
|
|
moo_file_watch_unref (fs->priv->fam);
|
|
|
|
}
|
|
|
|
|
2007-03-13 01:29:11 -05:00
|
|
|
if (fs->priv->debug_timeout)
|
|
|
|
g_source_remove (fs->priv->debug_timeout);
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
g_free (fs->priv);
|
|
|
|
fs->priv = NULL;
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
G_OBJECT_CLASS (_moo_file_system_parent_class)->finalize (object);
|
2005-08-25 09:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
MooFileSystem *
|
|
|
|
_moo_file_system_create (void)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
if (!fs_instance)
|
|
|
|
{
|
|
|
|
fs_instance = MOO_FILE_SYSTEM (g_object_new (MOO_TYPE_FILE_SYSTEM, NULL));
|
|
|
|
g_object_weak_ref (G_OBJECT (fs_instance),
|
|
|
|
(GWeakNotify) g_nullify_pointer, &fs_instance);
|
|
|
|
return fs_instance;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return g_object_ref (fs_instance);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
MooFolder *
|
|
|
|
_moo_file_system_get_root_folder (MooFileSystem *fs,
|
|
|
|
MooFileFlags wanted)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->get_root_folder (fs, wanted);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
MooFolder *
|
|
|
|
_moo_file_system_get_folder (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
MooFileFlags wanted,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->get_folder (fs, path, wanted, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
MooFolder *
|
|
|
|
_moo_file_system_get_parent_folder (MooFileSystem *fs,
|
|
|
|
MooFolder *folder,
|
|
|
|
MooFileFlags wanted)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
g_return_val_if_fail (MOO_IS_FOLDER (folder), NULL);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->get_parent_folder (fs, folder, wanted);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
gboolean
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_create_folder (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), FALSE);
|
|
|
|
g_return_val_if_fail (path != NULL, FALSE);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->create_folder (fs, path, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
gboolean
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_delete_file (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean recursive,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), FALSE);
|
|
|
|
g_return_val_if_fail (path != NULL, FALSE);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->delete_file (fs, path, recursive, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
gboolean
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_move_file (MooFileSystem *fs,
|
|
|
|
const char *old_path,
|
|
|
|
const char *new_path,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), FALSE);
|
|
|
|
g_return_val_if_fail (old_path && new_path, FALSE);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->move_file (fs, old_path, new_path, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
char *
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_make_path (MooFileSystem *fs,
|
|
|
|
const char *base_path,
|
|
|
|
const char *display_name,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2007-05-20 04:44:37 -05:00
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
g_return_val_if_fail (base_path != NULL && display_name != NULL, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->make_path (fs, base_path, display_name, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-31 04:53:45 -06:00
|
|
|
static char *
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_normalize_path (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean is_folder,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2007-05-20 04:44:37 -05:00
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->normalize_path (fs, path, is_folder, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
gboolean
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_parse_path (MooFileSystem *fs,
|
|
|
|
const char *path_utf8,
|
|
|
|
char **dirname,
|
|
|
|
char **display_dirname,
|
|
|
|
char **display_basename,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), FALSE);
|
|
|
|
g_return_val_if_fail (path_utf8 != NULL, FALSE);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->parse_path (fs, path_utf8, dirname,
|
|
|
|
display_dirname, display_basename,
|
|
|
|
error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
char *
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_get_absolute_path (MooFileSystem *fs,
|
|
|
|
const char *display_name,
|
|
|
|
const char *current_dir)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
g_return_val_if_fail (display_name != NULL, NULL);
|
|
|
|
return MOO_FILE_SYSTEM_GET_CLASS(fs)->get_absolute_path (fs, display_name, current_dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 12:14:12 -05:00
|
|
|
MooFileWatch *
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_file_system_get_file_watch (MooFileSystem *fs)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
|
|
|
|
if (!fs->priv->fam)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
fs->priv->fam = moo_file_watch_new (&error);
|
|
|
|
if (!fs->priv->fam)
|
|
|
|
{
|
|
|
|
g_warning ("%s: moo_fam_open failed", G_STRLOC);
|
|
|
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fs->priv->fam;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO what's this? */
|
2006-12-09 01:51:10 -06:00
|
|
|
void
|
|
|
|
_moo_file_system_folder_deleted (MooFileSystem *fs,
|
|
|
|
MooFolderImpl *impl)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2006-12-09 01:51:10 -06:00
|
|
|
if (impl->proxy)
|
|
|
|
{
|
|
|
|
g_hash_table_remove (fs->priv->folders, impl->path);
|
2006-12-10 16:48:59 -06:00
|
|
|
DEBUG_MESSAGE ("%s: folder %s deleted, proxy alive", G_STRFUNC, impl->path);
|
2006-12-09 01:51:10 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-12-10 16:48:59 -06:00
|
|
|
DEBUG_MESSAGE ("%s: cached folder %s deleted, freeing", G_STRFUNC, impl->path);
|
2006-12-09 01:51:10 -06:00
|
|
|
g_hash_table_remove (fs->priv->cache.paths, impl->path);
|
|
|
|
g_queue_remove (fs->priv->cache.queue, impl);
|
|
|
|
_moo_folder_impl_free (impl);
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
static MooFolder *
|
2006-04-16 12:14:12 -05:00
|
|
|
get_folder (MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
MooFileFlags wanted,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
MooFolder *folder;
|
2006-12-09 01:51:10 -06:00
|
|
|
MooFolderImpl *impl;
|
2005-08-25 09:29:01 +00:00
|
|
|
char *norm_path = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
|
|
#ifdef __WIN32__
|
2006-05-31 22:58:15 -05:00
|
|
|
if (!*path)
|
2005-08-25 09:29:01 +00:00
|
|
|
return get_root_folder_win32 (fs, wanted);
|
|
|
|
#endif /* __WIN32__ */
|
|
|
|
|
2006-05-31 22:58:15 -05:00
|
|
|
/* XXX check the caller */
|
2008-01-27 00:07:18 -06:00
|
|
|
if (!_moo_path_is_absolute (path))
|
2006-05-31 22:58:15 -05:00
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_BAD_FILENAME,
|
|
|
|
"folder path '%s' is not absolute",
|
|
|
|
path);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
norm_path = _moo_file_system_normalize_path (fs, path, TRUE, error);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
if (!norm_path)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
folder = g_hash_table_lookup (fs->priv->folders, norm_path);
|
|
|
|
|
|
|
|
if (folder)
|
|
|
|
{
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_folder_set_wanted (folder, wanted, TRUE);
|
2005-08-25 09:29:01 +00:00
|
|
|
g_object_ref (folder);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
impl = g_hash_table_lookup (fs->priv->cache.paths, norm_path);
|
|
|
|
|
|
|
|
if (impl)
|
|
|
|
{
|
|
|
|
g_hash_table_remove (fs->priv->cache.paths, impl->path);
|
|
|
|
g_queue_remove (fs->priv->cache.queue, impl);
|
|
|
|
folder = _moo_folder_new_with_impl (impl);
|
|
|
|
g_hash_table_insert (fs->priv->folders, norm_path, folder);
|
|
|
|
norm_path = NULL;
|
|
|
|
_moo_folder_set_wanted (folder, wanted, TRUE);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2005-08-25 09:29:01 +00:00
|
|
|
if (!g_file_test (norm_path, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_NONEXISTENT,
|
|
|
|
"'%s' does not exist", norm_path);
|
|
|
|
folder = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_file_test (norm_path, G_FILE_TEST_IS_DIR))
|
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_NOT_FOLDER,
|
|
|
|
"'%s' is not a folder", norm_path);
|
|
|
|
folder = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
folder = _moo_folder_new (fs, norm_path, wanted, error);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
if (folder)
|
|
|
|
{
|
2006-12-09 01:51:10 -06:00
|
|
|
g_hash_table_insert (fs->priv->folders, norm_path, folder);
|
2005-08-25 09:29:01 +00:00
|
|
|
norm_path = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_free (norm_path);
|
|
|
|
return folder;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO */
|
2006-12-09 01:51:10 -06:00
|
|
|
static gboolean
|
2006-04-16 12:14:12 -05:00
|
|
|
create_folder (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (path != NULL, FALSE);
|
2006-05-31 22:58:15 -05:00
|
|
|
|
|
|
|
/* XXX check the caller */
|
2008-01-27 00:07:18 -06:00
|
|
|
if (!_moo_path_is_absolute (path))
|
2006-05-31 22:58:15 -05:00
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_BAD_FILENAME,
|
|
|
|
"folder path '%s' is not absolute",
|
|
|
|
path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
/* TODO mkdir must (?) adjust permissions according to umask */
|
|
|
|
#ifndef __WIN32__
|
|
|
|
if (mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO))
|
|
|
|
#else
|
2006-11-03 23:57:57 -06:00
|
|
|
if (_moo_mkdir (path))
|
2005-08-25 09:29:01 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int saved_errno = errno;
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
2006-08-01 20:28:28 -05:00
|
|
|
_moo_file_error_from_errno (saved_errno),
|
2006-05-31 22:58:15 -05:00
|
|
|
"%s", g_strerror (saved_errno));
|
2005-08-25 09:29:01 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************/
|
2006-03-10 22:41:41 -06:00
|
|
|
/* common methods
|
2005-08-25 09:29:01 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* folder may be deleted, but this function returns parent
|
|
|
|
folder anyway, if that exists */
|
2006-03-10 22:41:41 -06:00
|
|
|
static MooFolder *
|
|
|
|
get_parent_folder (MooFileSystem *fs,
|
|
|
|
MooFolder *folder,
|
|
|
|
MooFileFlags wanted)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
char *parent_path;
|
|
|
|
MooFolder *parent;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_FILE_SYSTEM (fs), NULL);
|
|
|
|
g_return_val_if_fail (MOO_IS_FOLDER (folder), NULL);
|
2006-05-13 16:09:46 -05:00
|
|
|
g_return_val_if_fail (_moo_folder_get_file_system (folder) == fs, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-03-11 01:09:12 -06:00
|
|
|
parent_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "..",
|
2006-05-13 16:09:46 -05:00
|
|
|
_moo_folder_get_path (folder));
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
parent = _moo_file_system_get_folder (fs, parent_path, wanted, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
g_free (parent_path);
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 11:39:47 -05:00
|
|
|
static char *
|
|
|
|
normalize_path (const char *path)
|
|
|
|
{
|
|
|
|
GPtrArray *comps;
|
|
|
|
gboolean first_slash;
|
|
|
|
char **pieces, **p;
|
|
|
|
char *normpath;
|
|
|
|
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
|
|
first_slash = (path[0] == G_DIR_SEPARATOR);
|
|
|
|
|
|
|
|
pieces = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
|
|
|
|
g_return_val_if_fail (pieces != NULL, NULL);
|
|
|
|
|
|
|
|
comps = g_ptr_array_new ();
|
|
|
|
|
|
|
|
for (p = pieces; *p != NULL; ++p)
|
|
|
|
{
|
|
|
|
char *s = *p;
|
|
|
|
gboolean push = TRUE;
|
|
|
|
gboolean pop = FALSE;
|
|
|
|
|
|
|
|
if (!strcmp (s, "") || !strcmp (s, "."))
|
|
|
|
{
|
|
|
|
push = FALSE;
|
|
|
|
}
|
|
|
|
else if (!strcmp (s, ".."))
|
|
|
|
{
|
|
|
|
if (!comps->len && first_slash)
|
|
|
|
{
|
|
|
|
push = FALSE;
|
|
|
|
}
|
|
|
|
else if (comps->len)
|
|
|
|
{
|
|
|
|
push = FALSE;
|
|
|
|
pop = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pop)
|
|
|
|
{
|
|
|
|
g_free (comps->pdata[comps->len - 1]);
|
|
|
|
g_ptr_array_remove_index (comps, comps->len - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (push)
|
|
|
|
g_ptr_array_add (comps, g_strdup (s));
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ptr_array_add (comps, NULL);
|
|
|
|
|
|
|
|
if (comps->len == 1)
|
|
|
|
{
|
|
|
|
if (first_slash)
|
|
|
|
normpath = g_strdup (G_DIR_SEPARATOR_S);
|
|
|
|
else
|
|
|
|
normpath = g_strdup (".");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-01-18 21:45:53 -06:00
|
|
|
normpath = g_strjoinv (G_DIR_SEPARATOR_S, (char**) comps->pdata);
|
2006-04-16 11:39:47 -05:00
|
|
|
|
|
|
|
if (first_slash)
|
|
|
|
{
|
2008-01-18 21:45:53 -06:00
|
|
|
gsize len = strlen (normpath);
|
|
|
|
normpath = g_renew (char, normpath, len + 2);
|
|
|
|
memmove (normpath + 1, normpath, len + 1);
|
2006-04-16 11:39:47 -05:00
|
|
|
normpath[0] = G_DIR_SEPARATOR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (pieces);
|
|
|
|
g_strfreev ((char**) comps->pdata);
|
|
|
|
g_ptr_array_free (comps, FALSE);
|
|
|
|
|
|
|
|
return normpath;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-09 01:51:10 -06:00
|
|
|
static gboolean
|
2006-04-16 12:14:12 -05:00
|
|
|
delete_file (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean recursive,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean isdir;
|
|
|
|
|
|
|
|
g_return_val_if_fail (path != NULL, FALSE);
|
2008-01-27 00:07:18 -06:00
|
|
|
g_return_val_if_fail (_moo_path_is_absolute (path), FALSE);
|
2006-04-16 12:14:12 -05:00
|
|
|
|
|
|
|
if (g_file_test (path, G_FILE_TEST_IS_SYMLINK))
|
|
|
|
isdir = FALSE;
|
|
|
|
else
|
|
|
|
isdir = g_file_test (path, G_FILE_TEST_IS_DIR);
|
|
|
|
|
|
|
|
if (isdir)
|
2006-11-03 23:57:57 -06:00
|
|
|
return _moo_remove_dir (path, recursive, error);
|
2006-04-16 12:14:12 -05:00
|
|
|
|
2006-11-03 23:57:57 -06:00
|
|
|
if (_moo_remove (path))
|
2006-04-16 12:14:12 -05:00
|
|
|
{
|
|
|
|
int err = errno;
|
2007-04-09 05:02:50 -05:00
|
|
|
char *path_utf8 = g_filename_display_name (path);
|
2006-04-16 12:14:12 -05:00
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
2006-08-01 20:28:28 -05:00
|
|
|
_moo_file_error_from_errno (err),
|
2006-04-16 12:14:12 -05:00
|
|
|
"Could not delete file '%s': %s",
|
|
|
|
path_utf8 ? path_utf8 : BROKEN_NAME,
|
|
|
|
g_strerror (err));
|
|
|
|
g_free (path_utf8);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-10 22:41:41 -06:00
|
|
|
/***************************************************************************/
|
|
|
|
/* UNIX methods
|
|
|
|
*/
|
2006-05-13 16:09:46 -05:00
|
|
|
static gboolean
|
|
|
|
move_file_unix (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *old_path,
|
|
|
|
const char *new_path,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (old_path && new_path, FALSE);
|
2008-01-27 00:07:18 -06:00
|
|
|
g_return_val_if_fail (_moo_path_is_absolute (old_path), FALSE);
|
|
|
|
g_return_val_if_fail (_moo_path_is_absolute (new_path), FALSE);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
/* XXX */
|
2006-11-03 23:57:57 -06:00
|
|
|
if (_moo_rename (old_path, new_path))
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
int saved_errno = errno;
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
2006-08-01 20:28:28 -05:00
|
|
|
_moo_file_error_from_errno (saved_errno),
|
2005-08-25 09:29:01 +00:00
|
|
|
"%s", g_strerror (saved_errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-04 04:42:10 -06:00
|
|
|
#ifndef __WIN32__
|
|
|
|
|
|
|
|
static MooFolder *
|
|
|
|
get_root_folder_unix (MooFileSystem *fs,
|
|
|
|
MooFileFlags wanted)
|
|
|
|
{
|
|
|
|
return _moo_file_system_get_folder (fs, "/", wanted, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
static char *
|
|
|
|
make_path_unix (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *base_path,
|
|
|
|
const char *display_name,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
GError *error_here = NULL;
|
|
|
|
char *path, *name;
|
|
|
|
|
2006-04-16 11:39:47 -05:00
|
|
|
g_return_val_if_fail (base_path != NULL, NULL);
|
|
|
|
g_return_val_if_fail (display_name != NULL, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-05-31 22:58:15 -05:00
|
|
|
/* XXX check the caller */
|
2008-01-27 00:07:18 -06:00
|
|
|
if (!_moo_path_is_absolute (base_path))
|
2006-05-31 22:58:15 -05:00
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_BAD_FILENAME,
|
|
|
|
"path '%s' is not absolute",
|
|
|
|
base_path);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-08-25 09:29:01 +00:00
|
|
|
name = g_filename_from_utf8 (display_name, -1, NULL, NULL, &error_here);
|
|
|
|
|
|
|
|
if (error_here)
|
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_BAD_FILENAME,
|
|
|
|
"Could not convert '%s' to filename encoding: %s",
|
|
|
|
display_name, error_here->message);
|
|
|
|
g_free (name);
|
|
|
|
g_error_free (error_here);
|
2006-04-16 11:39:47 -05:00
|
|
|
return NULL;
|
2005-08-25 09:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
path = g_strdup_printf ("%s/%s", base_path, name);
|
|
|
|
g_free (name);
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-18 21:45:53 -06:00
|
|
|
/* XXX make sure error is set TODO: error checking, etc. */
|
2006-05-13 16:09:46 -05:00
|
|
|
static char *
|
|
|
|
normalize_path_unix (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *path,
|
|
|
|
gboolean is_folder,
|
|
|
|
G_GNUC_UNUSED GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
guint len;
|
2008-01-18 21:45:53 -06:00
|
|
|
char *normpath;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
2008-01-18 21:45:53 -06:00
|
|
|
normpath = normalize_path (path);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
if (!is_folder)
|
2008-01-18 21:45:53 -06:00
|
|
|
return normpath;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2008-01-18 21:45:53 -06:00
|
|
|
len = strlen (normpath);
|
|
|
|
g_return_val_if_fail (len > 0, normpath);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2008-01-18 21:45:53 -06:00
|
|
|
if (normpath[len-1] != G_DIR_SEPARATOR)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2008-01-18 21:45:53 -06:00
|
|
|
normpath = g_renew (char, normpath, len + 2);
|
2005-08-25 09:29:01 +00:00
|
|
|
normpath[len] = G_DIR_SEPARATOR;
|
|
|
|
normpath[len+1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
g_print ("path: '%s'\nnormpath: '%s'\n",
|
|
|
|
path, normpath);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return normpath;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* XXX must set error */
|
2006-05-13 16:09:46 -05:00
|
|
|
static gboolean
|
|
|
|
parse_path_unix (MooFileSystem *fs,
|
|
|
|
const char *path_utf8,
|
|
|
|
char **dirname_p,
|
|
|
|
char **display_dirname_p,
|
|
|
|
char **display_basename_p,
|
|
|
|
GError **error)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
|
|
|
const char *separator;
|
|
|
|
char *dirname = NULL, *norm_dirname = NULL;
|
|
|
|
char *display_dirname = NULL, *display_basename = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (path_utf8 && path_utf8[0], FALSE);
|
2006-05-31 22:58:15 -05:00
|
|
|
|
|
|
|
/* XXX check the caller */
|
2008-01-27 00:07:18 -06:00
|
|
|
if (!_moo_path_is_absolute (path_utf8))
|
2006-05-31 22:58:15 -05:00
|
|
|
{
|
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_BAD_FILENAME,
|
|
|
|
"path '%s' is not absolute",
|
|
|
|
path_utf8);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
if (!strcmp (path_utf8, "/"))
|
|
|
|
{
|
|
|
|
display_dirname = g_strdup ("/");
|
|
|
|
display_basename = g_strdup ("");
|
|
|
|
norm_dirname = g_strdup ("/");
|
|
|
|
goto success;
|
|
|
|
}
|
|
|
|
|
|
|
|
separator = strrchr (path_utf8, '/');
|
|
|
|
g_return_val_if_fail (separator != NULL, FALSE);
|
|
|
|
|
|
|
|
display_dirname = g_strndup (path_utf8, separator - path_utf8 + 1);
|
|
|
|
display_basename = g_strdup (separator + 1);
|
|
|
|
dirname = g_filename_from_utf8 (display_dirname, -1, NULL, NULL, error);
|
|
|
|
|
|
|
|
if (!dirname)
|
2006-11-12 13:11:42 -06:00
|
|
|
goto error;
|
2005-08-25 09:29:01 +00:00
|
|
|
|
2006-05-13 16:09:46 -05:00
|
|
|
norm_dirname = _moo_file_system_normalize_path (fs, dirname, TRUE, error);
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
if (!norm_dirname)
|
2006-11-12 13:11:42 -06:00
|
|
|
goto error;
|
2005-08-25 09:29:01 +00:00
|
|
|
else
|
|
|
|
goto success;
|
|
|
|
|
|
|
|
/* no fallthrough */
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
2006-11-12 13:11:42 -06:00
|
|
|
error:
|
2005-08-25 09:29:01 +00:00
|
|
|
g_free (dirname);
|
|
|
|
g_free (norm_dirname);
|
|
|
|
g_free (display_dirname);
|
|
|
|
g_free (display_basename);
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
success:
|
|
|
|
g_clear_error (error);
|
|
|
|
g_free (dirname);
|
|
|
|
*dirname_p = norm_dirname;
|
|
|
|
*display_dirname_p = display_dirname;
|
|
|
|
*display_basename_p = display_basename;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
|
|
|
|
/* XXX unicode */
|
2006-05-13 16:09:46 -05:00
|
|
|
static char *
|
|
|
|
get_absolute_path_unix (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *short_name,
|
|
|
|
const char *current_dir)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (short_name && short_name[0], NULL);
|
|
|
|
|
|
|
|
if (short_name[0] == '~')
|
|
|
|
{
|
|
|
|
const char *home = g_get_home_dir ();
|
|
|
|
g_return_val_if_fail (home != NULL, NULL);
|
|
|
|
|
|
|
|
if (short_name[1])
|
|
|
|
return g_build_filename (home, short_name + 1, NULL);
|
|
|
|
else
|
|
|
|
return g_strdup (home);
|
|
|
|
}
|
|
|
|
|
2008-01-27 00:07:18 -06:00
|
|
|
if (_moo_path_is_absolute (short_name))
|
2005-09-02 23:27:25 +00:00
|
|
|
return g_strdup (short_name);
|
|
|
|
|
|
|
|
if (current_dir)
|
|
|
|
return g_build_filename (current_dir, short_name, NULL);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-08-25 09:29:01 +00:00
|
|
|
#endif /* !__WIN32__ */
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************/
|
|
|
|
/* Win32 methods
|
|
|
|
*/
|
|
|
|
#ifdef __WIN32__
|
|
|
|
|
2006-04-20 14:13:42 -05:00
|
|
|
static MooFolder *
|
|
|
|
get_root_folder_win32 (MooFileSystem *fs,
|
|
|
|
MooFileFlags wanted)
|
2005-08-25 09:29:01 +00:00
|
|
|
{
|
2006-06-13 00:55:05 -05:00
|
|
|
#ifdef __GNUC__
|
2006-08-20 22:47:28 -05:00
|
|
|
#warning "Implement get_root_folder_win32()"
|
2006-06-13 00:55:05 -05:00
|
|
|
#endif
|
2006-05-13 16:09:46 -05:00
|
|
|
return _moo_file_system_get_folder (fs, "c:\\", wanted, NULL);
|
2005-08-25 09:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-04 04:42:10 -06:00
|
|
|
#if 0
|
2006-03-10 22:41:41 -06:00
|
|
|
static gboolean
|
2006-04-20 14:13:42 -05:00
|
|
|
move_file_win32 (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
G_GNUC_UNUSED const char *old_path,
|
|
|
|
G_GNUC_UNUSED const char *new_path,
|
2006-03-10 22:41:41 -06:00
|
|
|
GError **error)
|
|
|
|
{
|
2006-06-13 00:55:05 -05:00
|
|
|
#ifdef __GNUC__
|
2006-08-20 22:47:28 -05:00
|
|
|
#warning "Implement move_file_win32()"
|
2006-06-13 00:55:05 -05:00
|
|
|
#endif
|
2006-03-10 22:41:41 -06:00
|
|
|
g_set_error (error, MOO_FILE_ERROR,
|
|
|
|
MOO_FILE_ERROR_NOT_IMPLEMENTED,
|
|
|
|
"Renaming files is not implemented on win32");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-01-04 04:42:10 -06:00
|
|
|
#endif
|
2006-03-10 22:41:41 -06:00
|
|
|
|
|
|
|
|
2006-04-16 11:39:47 -05:00
|
|
|
static void
|
|
|
|
splitdrive (const char *fullpath,
|
|
|
|
char **drive,
|
|
|
|
char **path)
|
|
|
|
{
|
|
|
|
if (fullpath[0] && fullpath[1] == ':')
|
|
|
|
{
|
|
|
|
*drive = g_strndup (fullpath, 2);
|
|
|
|
*path = g_strdup (fullpath + 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*drive = NULL;
|
|
|
|
*path = g_strdup (fullpath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-10 22:41:41 -06:00
|
|
|
static char *
|
2006-04-20 14:13:42 -05:00
|
|
|
normalize_path_win32 (G_GNUC_UNUSED MooFileSystem *fs,
|
2006-04-16 11:39:47 -05:00
|
|
|
const char *fullpath,
|
|
|
|
gboolean isdir,
|
2006-04-20 14:13:42 -05:00
|
|
|
G_GNUC_UNUSED GError **error)
|
2006-03-18 02:45:36 -06:00
|
|
|
{
|
2006-04-16 11:39:47 -05:00
|
|
|
char *drive, *path, *normpath;
|
2006-04-20 14:13:42 -05:00
|
|
|
guint slashes;
|
2008-01-17 19:27:10 -06:00
|
|
|
gboolean drive_slashes = FALSE;
|
2006-04-16 11:39:47 -05:00
|
|
|
|
|
|
|
g_return_val_if_fail (fullpath != NULL, NULL);
|
|
|
|
|
2006-04-20 14:13:42 -05:00
|
|
|
splitdrive (fullpath, &drive, &path);
|
2006-04-16 11:39:47 -05:00
|
|
|
g_strdelimit (path, "/", '\\');
|
|
|
|
|
|
|
|
for (slashes = 0; path[slashes] == '\\'; ++slashes) ;
|
|
|
|
|
2006-04-20 14:13:42 -05:00
|
|
|
if (drive && path[0] != '\\')
|
2006-04-16 11:39:47 -05:00
|
|
|
{
|
|
|
|
char *tmp = path;
|
2006-04-20 14:13:42 -05:00
|
|
|
path = g_strdup_printf ("\\%s", path);
|
2006-04-16 11:39:47 -05:00
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
|
2006-04-20 14:13:42 -05:00
|
|
|
if (!drive)
|
|
|
|
{
|
|
|
|
char *tmp = path;
|
|
|
|
drive = g_strndup (path, slashes);
|
|
|
|
path = g_strdup (tmp + slashes);
|
2006-04-16 11:39:47 -05:00
|
|
|
g_free (tmp);
|
2008-01-17 19:27:10 -06:00
|
|
|
drive_slashes = TRUE;
|
2006-04-16 11:39:47 -05:00
|
|
|
}
|
2006-04-20 14:13:42 -05:00
|
|
|
// else if (path[0] == '\\')
|
|
|
|
// {
|
|
|
|
// char *tmp;
|
|
|
|
//
|
|
|
|
// tmp = drive;
|
|
|
|
// drive = g_strdup_printf ("%s\\", drive);
|
|
|
|
// g_free (tmp);
|
|
|
|
//
|
|
|
|
// tmp = path;
|
|
|
|
// path = g_strdup (path + slashes);
|
|
|
|
// g_free (tmp);
|
|
|
|
// }
|
2006-04-16 11:39:47 -05:00
|
|
|
|
|
|
|
normpath = normalize_path (path);
|
|
|
|
|
|
|
|
if (!normpath[0] && !drive)
|
|
|
|
{
|
|
|
|
char *tmp = normpath;
|
|
|
|
normpath = g_strdup (".");
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
else if (drive)
|
|
|
|
{
|
|
|
|
char *tmp = normpath;
|
2006-11-12 13:11:42 -06:00
|
|
|
|
2008-01-17 19:27:10 -06:00
|
|
|
if (normpath[0] == '\\' || drive_slashes)
|
2006-11-12 13:11:42 -06:00
|
|
|
normpath = g_strdup_printf ("%s%s", drive, normpath);
|
|
|
|
else
|
|
|
|
normpath = g_strdup_printf ("%s\\%s", drive, normpath);
|
|
|
|
|
2006-04-16 11:39:47 -05:00
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isdir)
|
|
|
|
{
|
|
|
|
guint len = strlen (normpath);
|
|
|
|
|
|
|
|
if (!len || normpath[len -1] != '\\')
|
|
|
|
{
|
|
|
|
char *tmp = normpath;
|
|
|
|
normpath = g_strdup_printf ("%s\\", normpath);
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (drive);
|
|
|
|
g_free (path);
|
|
|
|
return normpath;
|
2006-03-18 02:45:36 -06:00
|
|
|
}
|
|
|
|
|
2006-03-10 22:41:41 -06:00
|
|
|
|
|
|
|
static char *
|
|
|
|
make_path_win32 (G_GNUC_UNUSED MooFileSystem *fs,
|
|
|
|
const char *base_path,
|
|
|
|
const char *display_name,
|
|
|
|
G_GNUC_UNUSED GError **error)
|
|
|
|
{
|
2008-01-27 00:07:18 -06:00
|
|
|
g_return_val_if_fail (_moo_path_is_absolute (base_path), NULL);
|
2006-04-16 11:39:47 -05:00
|
|
|
g_return_val_if_fail (display_name != NULL, NULL);
|
2006-03-10 22:41:41 -06:00
|
|
|
return g_strdup_printf ("%s\\%s", base_path, display_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
parse_path_win32 (MooFileSystem *fs,
|
|
|
|
const char *path_utf8,
|
2006-03-18 02:45:36 -06:00
|
|
|
char **dirname_p,
|
|
|
|
char **display_dirname_p,
|
|
|
|
char **display_basename_p,
|
|
|
|
GError **error)
|
|
|
|
{
|
2006-06-13 00:55:05 -05:00
|
|
|
#ifdef __GNUC__
|
2006-08-20 22:47:28 -05:00
|
|
|
#warning "Implement parse_path_win32()"
|
2006-06-13 00:55:05 -05:00
|
|
|
#endif
|
2006-03-18 02:45:36 -06:00
|
|
|
const char *separator;
|
2006-04-16 11:39:47 -05:00
|
|
|
char *norm_dirname = NULL, *dirname = NULL, *basename = NULL;
|
2006-11-12 13:11:42 -06:00
|
|
|
gsize len;
|
2006-03-18 02:45:36 -06:00
|
|
|
|
|
|
|
g_return_val_if_fail (path_utf8 && path_utf8[0], FALSE);
|
2008-01-27 00:07:18 -06:00
|
|
|
g_return_val_if_fail (_moo_path_is_absolute (path_utf8), FALSE);
|
2006-03-18 02:45:36 -06:00
|
|
|
|
|
|
|
separator = strrchr (path_utf8, '\\');
|
|
|
|
g_return_val_if_fail (separator != NULL, FALSE);
|
|
|
|
|
2006-11-12 13:11:42 -06:00
|
|
|
len = strlen (path_utf8);
|
2006-03-18 02:45:36 -06:00
|
|
|
|
2006-11-12 13:11:42 -06:00
|
|
|
if (path_utf8[len - 1] == '\\')
|
|
|
|
{
|
|
|
|
dirname = g_strdup (path_utf8);
|
|
|
|
basename = g_strdup ("");
|
|
|
|
}
|
2006-03-18 02:45:36 -06:00
|
|
|
else
|
2006-11-12 13:11:42 -06:00
|
|
|
{
|
|
|
|
dirname = g_path_get_dirname (path_utf8);
|
|
|
|
basename = g_path_get_basename (path_utf8);
|
|
|
|
}
|
2006-03-18 02:45:36 -06:00
|
|
|
|
2006-11-12 13:11:42 -06:00
|
|
|
norm_dirname = _moo_file_system_normalize_path (fs, dirname, TRUE, error);
|
2006-03-18 02:45:36 -06:00
|
|
|
|
2006-11-12 13:11:42 -06:00
|
|
|
if (!norm_dirname)
|
|
|
|
goto error;
|
2006-03-18 02:45:36 -06:00
|
|
|
|
|
|
|
*dirname_p = norm_dirname;
|
2006-04-16 11:39:47 -05:00
|
|
|
*display_dirname_p = dirname;
|
|
|
|
*display_basename_p = basename;
|
2006-11-12 13:11:42 -06:00
|
|
|
|
|
|
|
g_message ("parsed '%s' into '%s' and '%s'", path_utf8, dirname, basename);
|
|
|
|
|
2006-03-18 02:45:36 -06:00
|
|
|
return TRUE;
|
2006-11-12 13:11:42 -06:00
|
|
|
|
|
|
|
error:
|
|
|
|
g_free (dirname);
|
|
|
|
g_free (basename);
|
|
|
|
g_free (norm_dirname);
|
|
|
|
|
|
|
|
g_message ("could not parse '%s'", path_utf8);
|
|
|
|
|
|
|
|
return FALSE;
|
2006-03-18 02:45:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static char *
|
2006-04-20 14:13:42 -05:00
|
|
|
get_absolute_path_win32 (G_GNUC_UNUSED MooFileSystem *fs,
|
2006-03-18 02:45:36 -06:00
|
|
|
const char *short_name,
|
|
|
|
const char *current_dir)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (short_name && short_name[0], NULL);
|
|
|
|
|
2008-01-27 00:07:18 -06:00
|
|
|
if (_moo_path_is_absolute (short_name))
|
2006-03-18 02:45:36 -06:00
|
|
|
return g_strdup (short_name);
|
|
|
|
|
|
|
|
if (current_dir)
|
|
|
|
return g_build_filename (current_dir, short_name, NULL);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-08-25 09:29:01 +00:00
|
|
|
|
|
|
|
#endif /* __WIN32__ */
|