#include <string.h>
#include <errno.h>
#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#include "glocalfileoutputstream.h"
#include "glocaldirectorymonitor.h"
#include "glocalfilemonitor.h"
-#include "gvolumeprivate.h"
+#include "gmountprivate.h"
#include <glib/gstdio.h>
#include "glibintl.h"
-static void g_local_file_file_iface_init (GFileIface *iface);
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <io.h>
+#include <direct.h>
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#endif
+#ifndef S_ISLNK
+#define S_ISLNK(m) (0)
+#endif
+#endif
+
+#include "gioalias.h"
+
+static void g_local_file_file_iface_init (GFileIface *iface);
static GFileAttributeInfoList *local_writable_attributes = NULL;
static GFileAttributeInfoList *local_writable_namespaces = NULL;
char *filename;
};
+#define g_local_file_get_type _g_local_file_get_type
G_DEFINE_TYPE_WITH_CODE (GLocalFile, g_local_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
g_local_file_file_iface_init))
-static char * find_mountpoint_for (const char *file, dev_t dev);
+static char *find_mountpoint_for (const char *file, dev_t dev);
static void
g_local_file_finalize (GObject *object)
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_UNIX_MODE,
G_FILE_ATTRIBUTE_TYPE_UINT32,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
#ifdef HAVE_CHOWN
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_UNIX_UID,
G_FILE_ATTRIBUTE_TYPE_UINT32,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_UNIX_GID,
G_FILE_ATTRIBUTE_TYPE_UINT32,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
#endif
#ifdef HAVE_SYMLINK
g_file_attribute_info_list_add (list,
- G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET,
+ G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
G_FILE_ATTRIBUTE_TYPE_BYTE_STRING,
0);
#endif
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_ATTRIBUTE_TYPE_UINT64,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
G_FILE_ATTRIBUTE_TYPE_UINT32,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_TIME_ACCESS,
G_FILE_ATTRIBUTE_TYPE_UINT64,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
g_file_attribute_info_list_add (list,
G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
G_FILE_ATTRIBUTE_TYPE_UINT32,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
#endif
local_writable_attributes = list;
g_file_attribute_info_list_add (list,
"xattr",
G_FILE_ATTRIBUTE_TYPE_STRING,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WITH_FILE |
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
g_file_attribute_info_list_add (list,
- "xattr_sys",
+ "xattr-sys",
G_FILE_ATTRIBUTE_TYPE_STRING,
- G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED);
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
#endif
local_writable_namespaces = list;
}
/**
- * g_local_file_new:
+ * _g_local_file_new:
* @filename: filename of the file to create.
*
* Returns: new local #GFile.
**/
GFile *
-g_local_file_new (const char *filename)
+_g_local_file_new (const char *filename)
{
GLocalFile *local;
}
static gboolean
-g_local_file_has_uri_scheme (GFile *file,
+g_local_file_has_uri_scheme (GFile *file,
const char *uri_scheme)
{
return g_ascii_strcasecmp (uri_scheme, "file") == 0;
static gboolean
name_is_valid_for_display (const char *string,
- gboolean is_valid_utf8)
+ gboolean is_valid_utf8)
{
char c;
while ((c = *string++) != 0)
{
- if (g_ascii_iscntrl(c))
+ if (g_ascii_iscntrl (c))
return FALSE;
}
return NULL;
dirname = g_path_get_dirname (local->filename);
- parent = g_local_file_new (dirname);
+ parent = _g_local_file_new (dirname);
g_free (dirname);
return parent;
}
{
GLocalFile *local = G_LOCAL_FILE (file);
- return g_local_file_new (local->filename);
+ return _g_local_file_new (local->filename);
}
static guint
}
static const char *
-match_prefix (const char *path, const char *prefix)
+match_prefix (const char *path,
+ const char *prefix)
{
int prefix_len;
prefix_len = strlen (prefix);
if (strncmp (path, prefix, prefix_len) != 0)
return NULL;
+
+ /* Handle the case where prefix is the root, so that
+ * the IS_DIR_SEPRARATOR check below works */
+ if (prefix_len > 0 &&
+ G_IS_DIR_SEPARATOR (prefix[prefix_len-1]))
+ prefix_len--;
+
return path + prefix_len;
}
}
static GFile *
-g_local_file_resolve_relative_path (GFile *file,
+g_local_file_resolve_relative_path (GFile *file,
const char *relative_path)
{
GLocalFile *local = G_LOCAL_FILE (file);
GFile *child;
if (g_path_is_absolute (relative_path))
- return g_local_file_new (relative_path);
+ return _g_local_file_new (relative_path);
filename = g_build_filename (local->filename, relative_path, NULL);
- child = g_local_file_new (filename);
+ child = _g_local_file_new (filename);
g_free (filename);
return child;
}
static GFileEnumerator *
-g_local_file_enumerate_children (GFile *file,
- const char *attributes,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_enumerate_children (GFile *file,
+ const char *attributes,
+ GFileQueryInfoFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
- return g_local_file_enumerator_new (local->filename,
- attributes, flags,
- cancellable, error);
+ return _g_local_file_enumerator_new (local->filename,
+ attributes, flags,
+ cancellable, error);
}
static GFile *
{
/* filesystem ids taken from linux manpage */
- switch (f_type) {
- case 0xadf5:
- return "adfs";
- case 0xADFF:
- return "affs";
- case 0x42465331:
- return "befs";
- case 0x1BADFACE:
- return "bfs";
- case 0xFF534D42:
- return "cifs";
- case 0x73757245:
- return "coda";
- case 0x012FF7B7:
- return "coh";
- case 0x28cd3d45:
- return "cramfs";
- case 0x1373:
- return "devfs";
- case 0x00414A53:
- return "efs";
- case 0x137D:
- return "ext";
- case 0xEF51:
- return "ext2";
- case 0xEF53:
- return "ext3";
- case 0x4244:
- return "hfs";
- case 0xF995E849:
- return "hpfs";
- case 0x958458f6:
- return "hugetlbfs";
- case 0x9660:
- return "isofs";
- case 0x72b6:
- return "jffs2";
- case 0x3153464a:
- return "jfs";
- case 0x137F:
- return "minix";
- case 0x138F:
- return "minix2";
- case 0x2468:
- return "minix2";
- case 0x2478:
- return "minix22";
- case 0x4d44:
- return "msdos";
- case 0x564c:
- return "ncp";
- case 0x6969:
- return "nfs";
- case 0x5346544e:
- return "ntfs";
- case 0x9fa1:
- return "openprom";
- case 0x9fa0:
- return "proc";
- case 0x002f:
- return "qnx4";
- case 0x52654973:
- return "reiserfs";
- case 0x7275:
- return "romfs";
- case 0x517B:
- return "smb";
- case 0x012FF7B6:
- return "sysv2";
- case 0x012FF7B5:
- return "sysv4";
- case 0x01021994:
- return "tmpfs";
- case 0x15013346:
- return "udf";
- case 0x00011954:
- return "ufs";
- case 0x9fa2:
- return "usbdevice";
- case 0xa501FCF5:
- return "vxfs";
- case 0x012FF7B4:
- return "xenix";
- case 0x58465342:
- return "xfs";
- case 0x012FD16D:
- return "xiafs";
- default:
- return NULL;
- }
+ switch (f_type)
+ {
+ case 0xadf5:
+ return "adfs";
+ case 0xADFF:
+ return "affs";
+ case 0x42465331:
+ return "befs";
+ case 0x1BADFACE:
+ return "bfs";
+ case 0xFF534D42:
+ return "cifs";
+ case 0x73757245:
+ return "coda";
+ case 0x012FF7B7:
+ return "coh";
+ case 0x28cd3d45:
+ return "cramfs";
+ case 0x1373:
+ return "devfs";
+ case 0x00414A53:
+ return "efs";
+ case 0x137D:
+ return "ext";
+ case 0xEF51:
+ return "ext2";
+ case 0xEF53:
+ return "ext3";
+ case 0x4244:
+ return "hfs";
+ case 0xF995E849:
+ return "hpfs";
+ case 0x958458f6:
+ return "hugetlbfs";
+ case 0x9660:
+ return "isofs";
+ case 0x72b6:
+ return "jffs2";
+ case 0x3153464a:
+ return "jfs";
+ case 0x137F:
+ return "minix";
+ case 0x138F:
+ return "minix2";
+ case 0x2468:
+ return "minix2";
+ case 0x2478:
+ return "minix22";
+ case 0x4d44:
+ return "msdos";
+ case 0x564c:
+ return "ncp";
+ case 0x6969:
+ return "nfs";
+ case 0x5346544e:
+ return "ntfs";
+ case 0x9fa1:
+ return "openprom";
+ case 0x9fa0:
+ return "proc";
+ case 0x002f:
+ return "qnx4";
+ case 0x52654973:
+ return "reiserfs";
+ case 0x7275:
+ return "romfs";
+ case 0x517B:
+ return "smb";
+ case 0x012FF7B6:
+ return "sysv2";
+ case 0x012FF7B5:
+ return "sysv4";
+ case 0x01021994:
+ return "tmpfs";
+ case 0x15013346:
+ return "udf";
+ case 0x00011954:
+ return "ufs";
+ case 0x9fa2:
+ return "usbdevice";
+ case 0xa501FCF5:
+ return "vxfs";
+ case 0x012FF7B4:
+ return "xenix";
+ case 0x58465342:
+ return "xfs";
+ case 0x012FD16D:
+ return "xiafs";
+ default:
+ return NULL;
+ }
}
#endif
+#ifndef G_OS_WIN32
+
G_LOCK_DEFINE_STATIC(mount_info_hash);
static GHashTable *mount_info_hash = NULL;
-guint64 mount_info_hash_cache_time = 0;
+static guint64 mount_info_hash_cache_time = 0;
typedef enum {
MOUNT_INFO_READONLY = 1<<0
static gboolean
device_equal (gconstpointer v1,
- gconstpointer v2)
+ gconstpointer v2)
{
- return *(dev_t *)v1 == * (dev_t *)v2;
+ return *(dev_t *)v1 == *(dev_t *)v2;
}
static guint
-device_hash (gconstpointer v)
+device_hash (gconstpointer v)
{
return (guint) *(dev_t *)v;
}
static void
-get_mount_info (GFileInfo *fs_info,
- const char *path,
+get_mount_info (GFileInfo *fs_info,
+ const char *path,
GFileAttributeMatcher *matcher)
{
struct stat buf;
guint mount_info;
char *mountpoint;
dev_t *dev;
- GUnixMount *mount;
+ GUnixMountEntry *mount;
guint64 cache_time;
- if (lstat (path, &buf) != 0)
+ if (g_lstat (path, &buf) != 0)
return;
G_LOCK (mount_info_hash);
if (mountpoint == NULL)
mountpoint = "/";
- mount = g_get_unix_mount_at (mountpoint, &cache_time);
+ mount = g_unix_mount_at (mountpoint, &cache_time);
if (mount)
{
if (g_unix_mount_is_readonly (mount))
}
if (mount_info & MOUNT_INFO_READONLY)
- g_file_info_set_attribute_boolean (fs_info, G_FILE_ATTRIBUTE_FS_READONLY, TRUE);
+ g_file_info_set_attribute_boolean (fs_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE);
}
+#endif
+
static GFileInfo *
-g_local_file_query_filesystem_info (GFile *file,
- const char *attributes,
- GCancellable *cancellable,
- GError **error)
+g_local_file_query_filesystem_info (GFile *file,
+ const char *attributes,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
GFileInfo *info;
int statfs_result;
gboolean no_size;
+#ifndef G_OS_WIN32
guint64 block_size;
#ifdef USE_STATFS
struct statfs statfs_buffer;
#elif defined(USE_STATVFS)
struct statvfs statfs_buffer;
#endif
+#endif
GFileAttributeMatcher *attribute_matcher;
no_size = FALSE;
attribute_matcher = g_file_attribute_matcher_new (attributes);
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_FS_FREE))
- g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FS_FREE, block_size * statfs_buffer.f_bavail);
+ G_FILE_ATTRIBUTE_FILESYSTEM_FREE))
+ {
+#ifdef G_OS_WIN32
+ gchar *localdir = g_path_get_dirname (local->filename);
+ wchar_t *wdirname = g_utf8_to_utf16 (localdir, -1, NULL, NULL, NULL);
+ ULARGE_INTEGER li;
+
+ g_free (localdir);
+ if (GetDiskFreeSpaceExW (wdirname, &li, NULL, NULL))
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, (guint64)li.QuadPart);
+ g_free (wdirname);
+#else
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, block_size * statfs_buffer.f_bavail);
+#endif
+ }
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_FS_SIZE))
- g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FS_SIZE, block_size * statfs_buffer.f_blocks);
-
+ G_FILE_ATTRIBUTE_FILESYSTEM_SIZE))
+ {
+#ifdef G_OS_WIN32
+ gchar *localdir = g_path_get_dirname (local->filename);
+ wchar_t *wdirname = g_utf8_to_utf16 (localdir, -1, NULL, NULL, NULL);
+ ULARGE_INTEGER li;
+
+ g_free (localdir);
+ if (GetDiskFreeSpaceExW (wdirname, NULL, &li, NULL))
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, (guint64)li.QuadPart);
+ g_free (wdirname);
+#else
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, block_size * statfs_buffer.f_blocks);
+#endif
+ }
#ifdef USE_STATFS
fstype = get_fs_type (statfs_buffer.f_type);
if (fstype &&
g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_FS_TYPE))
- g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FS_TYPE, fstype);
+ G_FILE_ATTRIBUTE_FILESYSTEM_TYPE))
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, fstype);
#endif
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_FS_READONLY))
+ G_FILE_ATTRIBUTE_FILESYSTEM_READONLY))
{
+#ifdef G_OS_WIN32
+ /* need to implement with *unix_mount* */
+#else
get_mount_info (info, local->filename, attribute_matcher);
+#endif
}
g_file_attribute_matcher_unref (attribute_matcher);
return info;
}
-static GVolume *
-g_local_file_find_enclosing_volume (GFile *file,
- GCancellable *cancellable,
- GError **error)
+static GMount *
+g_local_file_find_enclosing_mount (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
struct stat buf;
char *mountpoint;
- GVolume *volume;
+ GMount *mount;
- if (lstat (local->filename, &buf) != 0)
+ if (g_lstat (local->filename, &buf) != 0)
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
- volume = g_volume_get_for_mount_path (mountpoint);
+ mount = _g_mount_get_for_mount_path (mountpoint, cancellable);
g_free (mountpoint);
- if (volume)
- return volume;
+ if (mount)
+ return mount;
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
static GFile *
-g_local_file_set_display_name (GFile *file,
- const char *display_name,
- GCancellable *cancellable,
- GError **error)
+g_local_file_set_display_name (GFile *file,
+ const char *display_name,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local, *new_local;
GFile *new_file, *parent;
return NULL;
}
- new_file = g_file_get_child_for_display_name (parent, display_name, error);
+ new_file = g_file_get_child_for_display_name (parent, display_name, error);
g_object_unref (parent);
if (new_file == NULL)
}
static GFileAttributeInfoList *
-g_local_file_query_settable_attributes (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_query_settable_attributes (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
return g_file_attribute_info_list_ref (local_writable_attributes);
}
static GFileAttributeInfoList *
-g_local_file_query_writable_namespaces (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_query_writable_namespaces (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
return g_file_attribute_info_list_ref (local_writable_namespaces);
}
static gboolean
-g_local_file_set_attribute (GFile *file,
- const char *attribute,
- const GFileAttributeValue *value,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_set_attribute (GFile *file,
+ const char *attribute,
+ GFileAttributeType type,
+ gpointer value_p,
+ GFileQueryInfoFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
return _g_local_file_info_set_attribute (local->filename,
attribute,
- value,
+ type,
+ value_p,
flags,
cancellable,
error);
}
static gboolean
-g_local_file_set_attributes_from_info (GFile *file,
- GFileInfo *info,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_set_attributes_from_info (GFile *file,
+ GFileInfo *info,
+ GFileQueryInfoFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
int res, chained_res;
- GFileIface* default_iface;
+ GFileIface *default_iface;
res = _g_local_file_info_set_attributes (local->filename,
info, flags,
}
static GFileInputStream *
-g_local_file_read (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_read (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
int fd;
return NULL;
}
- return g_local_file_input_stream_new (fd);
+ return _g_local_file_input_stream_new (fd);
}
static GFileOutputStream *
-g_local_file_append_to (GFile *file,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_append_to (GFile *file,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
- return g_local_file_output_stream_append (G_LOCAL_FILE (file)->filename,
- flags, cancellable, error);
+ return _g_local_file_output_stream_append (G_LOCAL_FILE (file)->filename,
+ flags, cancellable, error);
}
static GFileOutputStream *
-g_local_file_create (GFile *file,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_create (GFile *file,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
- return g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename,
- flags, cancellable, error);
+ return _g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename,
+ flags, cancellable, error);
}
static GFileOutputStream *
-g_local_file_replace (GFile *file,
- const char *etag,
- gboolean make_backup,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
+g_local_file_replace (GFile *file,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
- return g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename,
- etag, make_backup, flags,
- cancellable, error);
+ return _g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename,
+ etag, make_backup, flags,
+ cancellable, error);
}
static gboolean
-g_local_file_delete (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_delete (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
{
char *resolved, *canonical, *parent, *link2;
char symlink_value[4096];
+#ifdef G_OS_WIN32
+#else
ssize_t res;
+#endif
+#ifdef G_OS_WIN32
+#else
res = readlink (link, symlink_value, sizeof (symlink_value) - 1);
+
if (res == -1)
return g_strdup (link);
symlink_value[res] = 0;
+#endif
if (g_path_is_absolute (symlink_value))
return canonicalize_filename (symlink_value);
}
static char *
-get_parent (const char *path, dev_t *parent_dev)
+get_parent (const char *path,
+ dev_t *parent_dev)
{
char *parent, *tmp;
struct stat parent_stat;
}
static char *
-find_mountpoint_for (const char *file, dev_t dev)
+find_mountpoint_for (const char *file,
+ dev_t dev)
{
char *dir, *parent;
dev_t dir_dev, parent_dev;
dir = g_strdup (file);
dir_dev = dev;
- while (1) {
- parent = get_parent (dir, &parent_dev);
- if (parent == NULL)
- return dir;
+ while (1)
+ {
+ parent = get_parent (dir, &parent_dev);
+ if (parent == NULL)
+ return dir;
- if (parent_dev != dir_dev)
- {
- g_free (parent);
- return dir;
- }
+ if (parent_dev != dir_dev)
+ {
+ g_free (parent);
+ return dir;
+ }
- g_free (dir);
- dir = parent;
- }
+ g_free (dir);
+ dir = parent;
+ }
}
+#ifndef G_OS_WIN32
+
static char *
find_topdir_for (const char *file)
{
return find_mountpoint_for (dir, dir_dev);
}
+#endif
+
static char *
-get_unique_filename (const char *basename, int id)
+get_unique_filename (const char *basename,
+ int id)
{
const char *dot;
dot = strchr (basename, '.');
if (dot)
- return g_strdup_printf ("%.*s.%d%s", dot - basename, basename, id, dot);
+ return g_strdup_printf ("%.*s.%d%s", (int)(dot - basename), basename, id, dot);
else
return g_strdup_printf ("%s.%d", basename, id);
}
static gboolean
-path_has_prefix (const char *path, const char *prefix)
+path_has_prefix (const char *path,
+ const char *prefix)
{
int prefix_len;
}
static char *
-try_make_relative (const char *path, const char *base)
+try_make_relative (const char *path,
+ const char *base)
{
char *path2, *base2;
char *relative;
}
static gboolean
-g_local_file_trash (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_trash (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
- struct stat file_stat, home_stat, trash_stat, global_stat;
+ struct stat file_stat, home_stat;
const char *homedir;
- char *dirname;
- char *trashdir, *globaldir, *topdir, *infodir, *filesdir;
+ char *trashdir, *topdir, *infodir, *filesdir;
char *basename, *trashname, *trashfile, *infoname, *infofile;
char *original_name, *original_name_escaped;
- uid_t uid;
- char uid_str[32];
int i;
char *data;
gboolean is_homedir_trash;
- time_t t;
- struct tm now;
char delete_time[32];
int fd;
+#ifndef G_OS_WIN32
+ struct stat trash_stat, global_stat;
+ char *dirname, *globaldir;
+#endif
if (g_lstat (local->filename, &file_stat) != 0)
{
}
else
{
+#ifdef G_OS_WIN32
+ g_warning ("Recycle bin not implemented");
+#else
+ uid_t uid;
+ char uid_str[32];
+
uid = geteuid ();
g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid);
trashdir = NULL;
}
}
+#endif
if (trashdir == NULL)
{
g_free (original_name);
g_free (topdir);
- t = time (NULL);
- localtime_r (&t, &now);
- delete_time[0] = 0;
- strftime(delete_time, sizeof (delete_time), "%Y-%m-%dT%H:%M:%S", &now);
+#ifdef G_OS_WIN32
+ {
+ GTimeVal now;
+ g_get_current_time (&now);
+ strncpy (delete_time, g_time_val_to_iso8601 (&now), sizeof (delete_time));
+ }
+#else
+ {
+ time_t t;
+ struct tm now;
+ t = time (NULL);
+ localtime_r (&t, &now);
+ delete_time[0] = 0;
+ strftime(delete_time, sizeof (delete_time), "%Y-%m-%dT%H:%M:%S", &now);
+ }
+#endif
data = g_strdup_printf ("[Trash Info]\nPath=%s\nDeletionDate=%s\n",
original_name_escaped, delete_time);
}
static gboolean
-g_local_file_make_directory (GFile *file,
- GCancellable *cancellable,
- GError **error)
+g_local_file_make_directory (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
}
static gboolean
-g_local_file_make_symbolic_link (GFile *file,
- const char *symlink_value,
- GCancellable *cancellable,
- GError **error)
+g_local_file_make_symbolic_link (GFile *file,
+ const char *symlink_value,
+ GCancellable *cancellable,
+ GError **error)
{
#ifdef HAVE_SYMLINK
GLocalFile *local = G_LOCAL_FILE (file);
static gboolean
-g_local_file_copy (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
+g_local_file_copy (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
{
/* Fall back to default copy */
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Copy not supported");
}
static gboolean
-g_local_file_move (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
+g_local_file_move (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
{
- GLocalFile *local_source = G_LOCAL_FILE (source);
+ GLocalFile *local_source;
GLocalFile *local_destination = G_LOCAL_FILE (destination);
struct stat statbuf;
gboolean destination_exist, source_is_dir;
char *backup_name;
int res;
-
+ off_t source_size;
+
+ if (!G_IS_LOCAL_FILE (source) ||
+ !G_IS_LOCAL_FILE (destination))
+ {
+ /* Fall back to default move */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Move not supported");
+ return FALSE;
+ }
+
+ local_source = G_LOCAL_FILE (source);
+
res = g_lstat (local_source->filename, &statbuf);
if (res == -1)
{
}
else
source_is_dir = S_ISDIR (statbuf.st_mode);
+
+ source_size = statbuf.st_size;
destination_exist = FALSE;
res = g_lstat (local_destination->filename, &statbuf);
if (rename (local_source->filename, local_destination->filename) == -1)
{
int errsv = errno;
- if (errsv == EXDEV)
- goto fallback;
- if (errsv == EINVAL)
+ if (errsv == EXDEV)
+ /* This will cause the fallback code to run */
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Move between mounts not supported"));
+ else if (errsv == EINVAL)
/* This must be an invalid filename, on e.g. FAT, or
we're trying to move the file into itself...
We return invalid filename for both... */
_("Error moving file: %s"),
g_strerror (errsv));
return FALSE;
-
}
- return TRUE;
-
- fallback:
- if (!g_file_copy (source, destination, G_FILE_COPY_OVERWRITE | G_FILE_COPY_ALL_METADATA, cancellable,
- progress_callback, progress_callback_data,
- error))
- return FALSE;
+ /* Make sure we send full copied size */
+ if (progress_callback)
+ progress_callback (source_size, source_size, progress_callback_data);
- return g_file_delete (source, cancellable, error);
+ return TRUE;
}
-
-static GDirectoryMonitor*
-g_local_file_monitor_dir (GFile* file,
- GFileMonitorFlags flags,
- GCancellable *cancellable)
+static GFileMonitor*
+g_local_file_monitor_dir (GFile *file,
+ GFileMonitorFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile* local_file = G_LOCAL_FILE(file);
- return g_local_directory_monitor_new (local_file->filename, flags);
+ return _g_local_directory_monitor_new (local_file->filename, flags, error);
}
static GFileMonitor*
-g_local_file_monitor_file (GFile* file,
- GFileMonitorFlags flags,
- GCancellable *cancellable)
+g_local_file_monitor_file (GFile *file,
+ GFileMonitorFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile* local_file = G_LOCAL_FILE(file);
- return g_local_file_monitor_new (local_file->filename, flags);
+ return _g_local_file_monitor_new (local_file->filename, flags, error);
}
static void
iface->enumerate_children = g_local_file_enumerate_children;
iface->query_info = g_local_file_query_info;
iface->query_filesystem_info = g_local_file_query_filesystem_info;
- iface->find_enclosing_volume = g_local_file_find_enclosing_volume;
+ iface->find_enclosing_mount = g_local_file_find_enclosing_mount;
iface->query_settable_attributes = g_local_file_query_settable_attributes;
iface->query_writable_namespaces = g_local_file_query_writable_namespaces;
iface->set_attribute = g_local_file_set_attribute;
iface->set_attributes_from_info = g_local_file_set_attributes_from_info;
- iface->read = g_local_file_read;
+ iface->read_fn = g_local_file_read;
iface->append_to = g_local_file_append_to;
iface->create = g_local_file_create;
iface->replace = g_local_file_replace;