summaryrefslogtreecommitdiff
path: root/gvfs
diff options
context:
space:
mode:
Diffstat (limited to 'gvfs')
-rw-r--r--gvfs/gvfs.c187
1 files changed, 169 insertions, 18 deletions
diff --git a/gvfs/gvfs.c b/gvfs/gvfs.c
index 3e1a0d8..c71faff 100644
--- a/gvfs/gvfs.c
+++ b/gvfs/gvfs.c
@@ -26,13 +26,14 @@
#include <gio/gio.h>
#include <glib/gtypes.h>
+// #include <gdk/gdk.h>
#include "vfs_types.h"
-#define VERSION "0.0.1"
-#define BUILD_DATE "2008-08-24"
+#define VERSION "0.0.2"
+#define BUILD_DATE "2008-08-25"
#define DEFAULT_BLOCK_SIZE 0x10000 /* 64kB */
#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," \
@@ -47,6 +48,8 @@ struct TVFSGlobs {
GFile *file;
GFileEnumerator *enumerator;
+ GMainLoop *mount_main_loop;
+
gboolean break_get_dir_size;
guint32 block_size;
};
@@ -113,6 +116,97 @@ g_error_to_TVFSResult (GError *error)
}
}
+static void
+ask_password_cb (GMountOperation *op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GAskPasswordFlags flags,
+ gpointer user_data)
+{
+ struct TVFSGlobs *globs;
+ char *s;
+
+
+ globs = (struct TVFSGlobs*) user_data;
+
+ g_print ("(II) ask_password_cb: message = '%s'\n", message);
+
+ if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+ {
+ g_print (" need username...\n");
+/*
+ s = prompt_for ("User", default_user, TRUE);
+ g_mount_operation_set_username (op, s);
+ g_free (s);
+*/
+ }
+
+ if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+ {
+ g_print (" need domain...\n");
+/*
+ s = prompt_for ("Domain", default_domain, TRUE);
+ g_mount_operation_set_domain (op, s);
+ g_free (s);
+*/
+ }
+
+ if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ {
+ g_print (" need password...\n");
+/*
+ s = prompt_for ("Password", NULL, FALSE);
+ g_mount_operation_set_password (op, s);
+ g_free (s);
+*/
+ }
+
+ g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
+}
+
+static void
+mount_done_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ struct TVFSGlobs *globs;
+ gboolean succeeded;
+ GError *error = NULL;
+
+ globs = (struct TVFSGlobs*) user_data;
+ succeeded = g_file_mount_enclosing_volume_finish (G_FILE (object), res, &error);
+
+ if (! succeeded) {
+ g_print ("(EE) Error mounting location: %s\n", error->message);
+ g_error_free (error);
+ }
+
+ g_main_loop_quit (globs->mount_main_loop);
+}
+
+static gboolean
+vfs_handle_mount (struct TVFSGlobs *globs, GFile *file)
+{
+ GMountOperation *op;
+
+ g_print ("(II) Mounting location...\n");
+
+ op = g_mount_operation_new ();
+ g_signal_connect (op, "ask_password", (GCallback)ask_password_cb, globs);
+
+// gdk_threads_enter ();
+ globs->mount_main_loop = g_main_loop_new (NULL, FALSE);
+ g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, op, NULL, mount_done_cb, globs);
+ g_main_loop_run (globs->mount_main_loop);
+/* g_main_loop_unref (globs->mount_main_loop);
+ globs->mount_main_loop = NULL; */
+// gdk_threads_leave ();
+
+
+ return FALSE;
+}
+
void
VFSInit (struct TVFSGlobs *globs, TVFSLogFunc log_func)
{
@@ -182,21 +276,49 @@ VFSGetPrefix (struct TVFSGlobs *globs)
TVFSResult
VFSOpen (struct TVFSGlobs *globs, char *sName)
{
- GFile *f;
+ GFile *f, *f2;
+ GFileInfo *info;
+ GError *error;
+ TVFSResult res;
+ gboolean try_again;
g_print ("(II) VFSOpen: opening URI '%s'\n", sName);
globs->file = NULL;
f = g_file_new_for_commandline_arg (sName);
- if (! g_file_query_exists (f, NULL)) {
- g_print ("(EE) VFSOpen: The URI specified doesn't exist\n");
- return cVFS_Failed;
- }
- else
- {
- globs->file = f;
- return cVFS_OK;
+
+ try_again = FALSE;
+ while (1) {
+ error = NULL;
+ info = g_file_query_info (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+ /* Fallback to parent directory if specified path doesn't exist */
+ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ f2 = g_file_get_parent (f);
+ if (f2) {
+ g_object_unref (f);
+ f = f2;
+ try_again = TRUE;
+ g_error_free (error);
+ continue;
+ }
+ }
+ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) {
+ vfs_handle_mount (globs, f);
+ }
+ if (error) {
+ g_print ("(EE) VFSOpen: g_file_query_info() error: %s\n", error->message);
+ res = g_error_to_TVFSResult (error);
+ g_error_free (error);
+ g_object_unref (f);
+ return res;
+ }
+ /* everything ok? */
+ break;
}
+
+ globs->file = f;
+ return cVFS_OK;
}
TVFSResult
@@ -273,8 +395,10 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
{
GFile *f;
GFileEnumerator *en;
- GError *error;
+ GError *error, *error_shortcut;
TVFSResult res;
+ GFileInfo *info;
+ gchar *target_uri;
if (globs->file == NULL) {
g_print ("(EE) VFSChangeDir: globs->file == NULL !\n");
@@ -290,8 +414,33 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
}
error = NULL;
+ res = cVFS_OK;
en = g_file_enumerate_children (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+
+ /* if the target is shortcut, change the URI */
+ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) {
+ error_shortcut = NULL;
+ info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error_shortcut);
+ if (info) {
+ target_uri = g_strdup (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI));
+ g_object_unref (info);
+ if (target_uri) {
+ g_print ("(WW) VFSChangeDir: following shortcut, changing URI to '%s'\n", target_uri);
+ g_object_unref (f);
+ f = g_file_new_for_uri (target_uri);
+ g_free (target_uri);
+ g_error_free (error);
+ error = NULL;
+ en = g_file_enumerate_children (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+ }
+ }
+ if (error_shortcut)
+ g_error_free (error_shortcut);
+ }
+
if (error) {
g_print ("(EE) VFSChangeDir: g_file_enumerate_children() error: %s\n", error->message);
res = g_error_to_TVFSResult (error);
@@ -303,7 +452,7 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
g_object_unref (globs->file);
globs->file = f;
- return cVFS_OK;
+ return res;
}
int
@@ -327,7 +476,7 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
g_assert (info != NULL);
g_assert (Item != NULL);
- Item->sFileName = g_strdup (g_file_info_get_display_name (info));
+ Item->sFileName = g_strdup (g_file_info_get_name (info));
Item->sLinkTo = g_file_info_get_symlink_target (info) == NULL ? NULL : g_strdup (g_file_info_get_symlink_target (info));
Item->iSize = g_file_info_get_size (info);
Item->iMode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
@@ -338,6 +487,8 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
Item->iUID = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID);
Item->iGID = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID);
+// g_print ("(II) g_file_info_to_TVFSItem: type = %d\n", g_file_info_get_file_type (info));
+
if (g_file_info_get_is_symlink (info)) {
Item->ItemType = vSymlink;
}
@@ -348,13 +499,13 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
Item->ItemType = vRegular;
break;
case G_FILE_TYPE_DIRECTORY:
+ case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */
case G_FILE_TYPE_MOUNTABLE:
Item->ItemType = vDirectory;
break;
case G_FILE_TYPE_SYMBOLIC_LINK:
Item->ItemType = vSymlink;
break;
- case G_FILE_TYPE_SHORTCUT:
case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */
Item->ItemType = vBlockdev;
break;
@@ -456,7 +607,7 @@ VFSFileExists (struct TVFSGlobs *globs, const char *FileName, const long Use_lst
Use_lstat ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : G_FILE_QUERY_INFO_NONE, NULL, &error);
g_object_unref (f);
if (error) {
- g_print ("(EE) VFSFileExists: g_file_query_info() error: %s\n", error->message);
+// g_print ("(EE) VFSFileExists: g_file_query_info() error: %s\n", error->message);
g_error_free (error);
return FALSE;
}
@@ -654,7 +805,7 @@ VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode)
g_print ("(EE) VFSChmod: g_file_resolve_relative_path() failed.\n");
return cVFS_Failed;
}
- g_print ("(II) VFSChmod (%s, %d): Going to set permissions on '%s'\n", FileName, Mode, g_file_get_uri (f));
+// g_print ("(II) VFSChmod (%s, %d): Going to set permissions on '%s'\n", FileName, Mode, g_file_get_uri (f));
error = NULL;
g_file_set_attribute_uint32 (f, G_FILE_ATTRIBUTE_UNIX_MODE, Mode, G_FILE_QUERY_INFO_NONE, NULL, &error);
@@ -986,7 +1137,7 @@ vfs_copy_progress_callback (goffset current_num_bytes,
{
struct CopyJobRef *ref;
- g_print ("(II) vfs_copy_progress_callback spawned: current_num_bytes = %lu, total_num_bytes = %lu\n", current_num_bytes, total_num_bytes);
+// g_print ("(II) vfs_copy_progress_callback spawned: current_num_bytes = %lu, total_num_bytes = %lu\n", current_num_bytes, total_num_bytes);
if (! user_data)
return;