Fixing SMB browsing
- From: Federico Mena Quintero <federico ximian com>
- To: "gnome-vfs-list gnome org" <gnome-vfs-list gnome org>
- Subject: Fixing SMB browsing
- Date: Mon, 20 Feb 2006 15:05:52 -0600
Hi,
For the past few months at Novell, I've been working on Samba-related
stuff for gnome-vfs and Nautilus. Attached is a patch for gnome-vfs's
smb-method.c which does a few things:
- Turns off SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON. This is what causes
the "I get prompted for a password for everything" bug. I have tried to
figure out why this flag got introduced, but it only seems to cause
trouble --- our perform_authentication() and its series of fallbacks
already take the proper steps to ensure that the user is only prompted
for authentication if absolutely required.
- Enables browsing for SMB printers. When you double-click on a SMB
printer in Nautilus, it will launch gnome-cups-add to let you configure
the printer.
- Adds a bunch of debugging code, which can be enabled by touching
~/.debug-gnome-vfs-smb --- if this file exists, the code will create a
log in ~/debug-gnome-vfs-smb.log. This is useful so that random users
can send you a debug log without recompiling.
- Hides administrative shares like IPC$ and ADMIN$, while showing
user-created shares that end in "$".
With this patch, SMB browsing works very well, including kerberized
setups like Active Directory. "Works very well" assumes that the
network is configured for browsing --- it turns out that many networks
with a mixture of Windows and Unix boxes in various subnets are just not
properly set up for that.
The patch is large, but that is due to the code that produces debug
output. The meat is pretty small. I'm surprised that the only changed
really needed to get browsing to work well is the flag I mentioned
above.
OK to commit? :)
Federico
2006-02-10 Federico Mena Quintero <federico novell com>
* modules/smb-method.c (try_init): Add debugging output for the
default workgroup we get from GConf and smbc_init_context().
2006-02-06 Federico Mena Quintero <federico ximian com>
* modules/smb-method.c (is_hidden_entry): Only consider these
administrative share names to be truly invisible: IPC$, ADMIN$,
print$, printer$. Fixes
https://bugzilla.novell.com/show_bug.cgi?id=127526
2006-01-30 Federico Mena Quintero <federico ximian com>
https://bugzilla.novell.com/show_bug.cgi?id=145199 - allow
browsing for printers.
* modules/smb-method.c (printer_hash): New hash table where we
remember the printers we find during calls to smbcctx->readdir().
This method gives us a struct smbc_dirent that identifies a
printer, but you cannot perform a smbcctx->stat() on a path to
know if that path refers to a printer. So, when doing readdir(),
we must remember the URIs of the printers we have found. Later in
our own do_get_file_info(), we will match the passed URI to this
hash table and return a magic "it is a printer" datum if
appropriate.
(try_init): Create the printer_hash.
(vfs_module_shutdown): Destroy the printer_hash.
(do_read_directory): Do not filter out printers, and add them to
our hash table. Use a MIME type of "application/x-desktop" for
printers; we'll generate a fake .desktop item for them.
(add_printer_to_hash): New helper function
(make_path_from_uri_and_name): New function to create a URI from
another parent URI and a name.
(do_read_directory): Use make_path_from_uri_and_name() to avoid
leaking the escaped file_info->name.
(is_printer): New helper function.
(set_file_info_to_readonly_desktop_file): New helper function.
(do_get_file_info): Use set_file_info_to_readonly_desktop_file()
in the case of workgroup or server links. Use this as well for
printers.
(file_handle_new_from_desktop_file_contents): New helper function.
(do_open): Handle printers by generating .desktop data for them.
Shorten the code by using
file_handle_new_from_desktop_file_contents() for this and the
other cases that generate .desktop data.
(get_printer_data): New helper function; creates .desktop data for
a printer.
2006-01-27 Federico Mena Quintero <federico ximian com>
Add debug logging to smb-method if there is a
"~/.debug-gnome-vfs-smb" file. If this file exists, the SMB
method will write a ~/debug-gnome-vfs-smb.log file.
* modules/smb-method.c (debug_init): New function to initialize
debugging. This module gets loaded in gnome-vfs-daemon, so it's
hard to get output from it.
(debug_shutdown): New function.
(debug_print): New function.
(debug_indent): New function.
(vfs_module_init): Initialize debugging.
(vfs_module_shutdown): Shut down debugging.
(debug_print): New function.
(DEBUG_SMB): Use debug_print() instead of g_print().
(DEBUG_IN): New macro.
(DEBUG_OUT): New macro.
(LOCK_SMB): Use debug_print().
(UNLOCK_SMB): Use debug_print().
(do_read_directory): Restore printer filtering until we find out
how to pick up this info from libsmbclient with a ctx->stat() or similar.
(*) Add calls to DEBUG_IN() / DEBUG_OUT().
(debug_dump_auth_context): New function.
2006-01-26 Federico Mena Quintero <federico ximian com>
* modules/smb-method.c (do_read_directory): Don't filter out
printer shares. Break properly out of the switch() for the case
of SMBC_PRINTER_SHARE.
2006-01-19 Federico Mena Quintero <federico ximian com>
* modules/smb-method.c (try_init): Clean up the code a bit. Do
*not* turn on SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON for the global
smb_context; we only want that to go into a specific share.
Index: modules/smb-method.c
===================================================================
RCS file: /cvsroot/gnome-vfs/modules/smb-method.c,v
retrieving revision 1.1.1.1
retrieving revision 1.14
diff -u -p -r1.1.1.1 -r1.14
--- modules/smb-method.c 16 Jan 2006 22:00:40 -0000 1.1.1.1
+++ modules/smb-method.c 20 Feb 2006 17:38:38 -0000 1.14
@@ -37,6 +37,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <stdio.h>
#include <gconf/gconf-client.h>
#include <libgnomevfs/gnome-vfs.h>
@@ -90,6 +91,17 @@ static GHashTable *server_cache = NULL;
static GHashTable *user_cache = NULL;
+/* smbcctx->readdir() can give us a struct smbc_dirent that identifies a
+ * printer, but you cannot perform a smbcctx->stat() on a path to know if that
+ * path refers to a printer. So, when doing readdir(), we must remember the
+ * URIs of the printers we have found. Later in our own do_get_file_info(), we
+ * will match the passed URI to this hash table and return a magic "it is a
+ * printer" datum if appropriate.
+ */
+static GHashTable *printer_hash = NULL;
+
+static FILE *debug_file;
+
#define SMB_BLOCK_SIZE (32*1024)
/* Reap unused server connections and user cache after 30 minutes */
@@ -144,32 +156,105 @@ typedef struct _SmbAuthContext {
static void init_authentication (SmbAuthContext *actx, GnomeVFSURI *uri);
static int perform_authentication (SmbAuthContext *actx);
+static gboolean is_printer (const char *uri);
+
static SmbAuthContext *current_auth_context = NULL;
static void auth_callback (const char *server_name, const char *share_name,
char *domain, int domainmaxlen,
char *username, int unmaxlen,
char *password, int pwmaxlen);
+
+static void debug_print (const char *format, ...);
+static void debug_indent (int amount);
+static int debug_indentation;
-#if 0
+#if 1
#define DEBUG_SMB_ENABLE
#define DEBUG_SMB_LOCKS
#endif
#ifdef DEBUG_SMB_ENABLE
-#define DEBUG_SMB(x) g_print x
+#define DEBUG_SMB(x) debug_print x
+#define DEBUG_IN() debug_print ("%s() {\n", G_STRFUNC); debug_indent(1)
+#define DEBUG_OUT() debug_indent(-1); debug_print ("} %s()\n", G_STRFUNC)
#else
-#define DEBUG_SMB(x)
+#define DEBUG_SMB(x)
+#define DEBUG_IN()
+#define DEBUG_OUT()
#endif
#ifdef DEBUG_SMB_LOCKS
-#define LOCK_SMB() {g_mutex_lock (smb_lock); g_print ("LOCK %s\n", G_GNUC_PRETTY_FUNCTION);}
-#define UNLOCK_SMB() {g_print ("UNLOCK %s\n", G_GNUC_PRETTY_FUNCTION); g_mutex_unlock (smb_lock);}
+#define LOCK_SMB() {g_mutex_lock (smb_lock); debug_print ("LOCK %s\n", G_STRFUNC);}
+#define UNLOCK_SMB() {debug_print ("UNLOCK %s\n", G_STRFUNC); g_mutex_unlock (smb_lock);}
#else
#define LOCK_SMB() g_mutex_lock (smb_lock)
#define UNLOCK_SMB() g_mutex_unlock (smb_lock)
#endif
+static void
+debug_print (const char *format, ...)
+{
+ va_list args;
+ char *str;
+ int i;
+
+ if (!debug_file)
+ return;
+
+ va_start (args, format);
+ str = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ fprintf (debug_file, "%p: ", g_thread_self ());
+
+ for (i = 0; i < debug_indentation * 4; i++)
+ fputc (' ', debug_file);
+
+ fputs (str, debug_file);
+ g_free (str);
+ fflush (debug_file);
+}
+
+static void
+debug_indent (int amount)
+{
+ debug_indentation += amount;
+ if (debug_indentation < 0)
+ g_error ("You fucked up your indentation");
+}
+
+static void
+DEBUG_DUMP_AUTH_CONTEXT (SmbAuthContext *actx)
+{
+ char *str_uri;
+
+ if (actx->uri)
+ str_uri = gnome_vfs_uri_to_string (actx->uri, 0);
+ else
+ str_uri = g_strdup ("(null)");
+
+ debug_print ("AUTH CONTEXT %p {\n", actx);
+ debug_print (" uri: %s\n", str_uri);
+ debug_print (" vfs_result: %d\n", (int) actx->res);
+ debug_print (" passes: %d\n", actx->passes);
+ debug_print (" state: %x\n", actx->state);
+ debug_print (" save_auth: %d\n", actx->save_auth);
+ debug_print (" keyring: %s\n", actx->keyring);
+ debug_print (" auth_called: %d\n", actx->auth_called);
+ debug_print (" for_server: %s\n", actx->for_server);
+ debug_print (" for_share: %s\n", actx->for_share);
+ debug_print (" use_user: %s\n", actx->use_user);
+ debug_print (" use_domain: %s\n", actx->use_domain);
+ debug_print (" use_password: %s\n", actx->use_password);
+ debug_print (" cache_added: %d\n", actx->cache_added);
+ debug_print (" cache_used: %d\n", actx->cache_used);
+ debug_print (" prompt_flags: %x\n", actx->prompt_flags);
+ debug_print ("}\n");
+
+ g_free (str_uri);
+}
+
static gchar*
string_dup_nzero (const gchar *s)
{
@@ -306,7 +391,8 @@ cache_reap_cb (void)
* sure when we'll be called */
if (!g_mutex_trylock (smb_lock))
return TRUE;
- DEBUG_SMB(("LOCK %s\n", G_GNUC_PRETTY_FUNCTION));
+ DEBUG_IN ();
+ DEBUG_SMB(("LOCK %s\n", G_STRFUNC));
size = g_hash_table_size (server_cache);
servers = g_ptr_array_sized_new (size);
@@ -329,6 +415,7 @@ cache_reap_cb (void)
if (!ret)
cache_reap_timeout = 0;
+ DEBUG_OUT ();
UNLOCK_SMB();
return ret;
@@ -350,6 +437,7 @@ add_cached_server (SMBCCTX *context, SMB
{
SmbServerCacheEntry *entry = NULL;
+ DEBUG_IN ();
DEBUG_SMB(("[auth] adding cached server: server: %s, share: %s, domain: %s, user: %s\n",
server_name, share_name, domain, username));
@@ -367,6 +455,8 @@ add_cached_server (SMBCCTX *context, SMB
g_hash_table_insert (server_cache, entry, entry);
current_auth_context->cache_added = TRUE;
+
+ DEBUG_OUT ();
return 0;
}
@@ -377,6 +467,7 @@ find_cached_server (const char *server_n
SmbServerCacheEntry entry;
SmbServerCacheEntry *res;
+ DEBUG_IN ();
DEBUG_SMB(("find_cached_server: server: %s, share: %s, domain: %s, user: %s\n", server_name, share_name, domain, username));
entry.server_name = (char *)server_name;
@@ -388,9 +479,13 @@ find_cached_server (const char *server_n
if (res != NULL) {
res->last_time = time (NULL);
+ DEBUG_OUT ();
+ DEBUG_SMB (("found server %p\n", res->server));
return res->server;
- }
+ }
+ DEBUG_SMB (("found nothing; returning NULL\n"));
+ DEBUG_OUT ();
return NULL;
}
@@ -400,14 +495,19 @@ get_cached_server (SMBCCTX * context,
const char *domain, const char *username)
{
SMBCSRV *srv;
+
+ DEBUG_IN ();
srv = find_cached_server (server_name, share_name, domain, username);
if (srv != NULL) {
DEBUG_SMB(("got cached server: server: %s, share: %s, domain: %s, user: %s\n",
server_name, share_name, domain, username));
current_auth_context->cache_used = TRUE;
+ DEBUG_OUT ();
return srv;
}
+
+ DEBUG_OUT ();
return NULL;
}
@@ -418,7 +518,7 @@ remove_server (gpointer key,
{
SmbServerCacheEntry *entry;
SMBCSRV *server;
-
+
entry = key;
server = user_data;
@@ -432,9 +532,13 @@ remove_server (gpointer key,
static int remove_cached_server(SMBCCTX * context, SMBCSRV * server)
{
int removed;
+
+ DEBUG_IN ();
removed = g_hash_table_foreach_remove (server_cache, remove_server, server);
+ DEBUG_OUT ();
+
/* return 1 if failed */
return removed == 0;
}
@@ -461,6 +565,8 @@ purge_cached(SMBCCTX * context)
gboolean could_not_purge_all;
int i;
+ DEBUG_IN ();
+
size = g_hash_table_size (server_cache);
servers = g_ptr_array_sized_new (size);
@@ -477,6 +583,10 @@ purge_cached(SMBCCTX * context)
}
g_ptr_array_free (servers, TRUE);
+
+ DEBUG_SMB (("returning could_not_purge_all = %d\n", could_not_purge_all));
+
+ DEBUG_OUT ();
return could_not_purge_all;
}
@@ -497,6 +607,8 @@ update_workgroup_cache (void)
SMBCFILE *dir = NULL;
time_t t;
struct smbc_dirent *dirent;
+
+ DEBUG_IN ();
t = time (NULL);
@@ -504,6 +616,7 @@ update_workgroup_cache (void)
workgroups_timestamp < t &&
t < workgroups_timestamp + WORKGROUP_CACHE_TIMEOUT) {
/* Up to date */
+ DEBUG_OUT ();
return;
}
workgroups_timestamp = t;
@@ -515,15 +628,20 @@ update_workgroup_cache (void)
LOCK_SMB();
init_authentication (&actx, NULL);
+ DEBUG_DUMP_AUTH_CONTEXT (&actx);
/* Important: perform_authentication leaves and re-enters the lock! */
while (perform_authentication (&actx) > 0) {
+ DEBUG_SMB (("calling ctx->opendir (\"smb://\")\n"));
dir = smb_context->opendir (smb_context, "smb://");
actx.res = (dir != NULL) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB (("it returned %d\n", (int) actx.res));
}
if (dir != NULL) {
+ DEBUG_SMB (("calling ctx->readdir() in a loop\n"));
while ((dirent = smb_context->readdir (smb_context, dir)) != NULL) {
+ DEBUG_SMB (("got dirent '%s' of type %d\n", dirent->name, dirent->smbc_type));
if (dirent->smbc_type == SMBC_WORKGROUP &&
dirent->name != NULL &&
strlen (dirent->name) > 0) {
@@ -535,9 +653,13 @@ update_workgroup_cache (void)
}
}
+ DEBUG_SMB (("calling ctx->closedir()\n"));
smb_context->closedir (smb_context, dir);
}
+ DEBUG_DUMP_AUTH_CONTEXT (&actx);
UNLOCK_SMB();
+
+ DEBUG_OUT ();
}
static SmbUriType
@@ -545,6 +667,9 @@ smb_uri_type (GnomeVFSURI *uri)
{
GnomeVFSToplevelURI *toplevel;
char *first_slash;
+ SmbUriType type;
+
+ DEBUG_IN ();
toplevel = (GnomeVFSToplevelURI *)uri;
@@ -553,12 +678,16 @@ smb_uri_type (GnomeVFSURI *uri)
if (uri->text == NULL ||
uri->text[0] == 0 ||
strcmp (uri->text, "/") == 0) {
- return SMB_URI_WHOLE_NETWORK;
+ type = SMB_URI_WHOLE_NETWORK;
+ goto out;
}
if (strchr (uri->text + 1, '/')) {
- return SMB_URI_ERROR;
+ type = SMB_URI_ERROR;
+ goto out;
}
- return SMB_URI_WORKGROUP_LINK;
+
+ type = SMB_URI_WORKGROUP_LINK;
+ goto out;
}
if (uri->text == NULL ||
uri->text[0] == 0 ||
@@ -568,9 +697,11 @@ smb_uri_type (GnomeVFSURI *uri)
if (!g_ascii_strcasecmp(toplevel->host_name,
DEFAULT_WORKGROUP_NAME) ||
g_hash_table_lookup (workgroups, toplevel->host_name)) {
- return SMB_URI_WORKGROUP;
+ type = SMB_URI_WORKGROUP;
+ goto out;
} else {
- return SMB_URI_SERVER;
+ type = SMB_URI_SERVER;
+ goto out;
}
}
first_slash = strchr (uri->text + 1, '/');
@@ -580,13 +711,21 @@ smb_uri_type (GnomeVFSURI *uri)
if (!g_ascii_strcasecmp(toplevel->host_name,
DEFAULT_WORKGROUP_NAME) ||
g_hash_table_lookup (workgroups, toplevel->host_name)) {
- return SMB_URI_SERVER_LINK;
+ type = SMB_URI_SERVER_LINK;
+ goto out;
} else {
- return SMB_URI_SHARE;
+ type = SMB_URI_SHARE;
+ goto out;
}
}
-
- return SMB_URI_SHARE_FILE;
+
+ type = SMB_URI_SHARE_FILE;
+
+ out:
+
+ DEBUG_OUT ();
+
+ return type;
}
@@ -594,9 +733,25 @@ smb_uri_type (GnomeVFSURI *uri)
static gboolean
is_hidden_entry (char *name)
{
+ static const char *hidden_names[] = {
+ "IPC$",
+ "ADMIN$",
+ "print$",
+ "printer$"
+ };
+
+ int i;
+
if (name == NULL) return TRUE;
- if (*(name + strlen (name) -1) == '$') return TRUE;
+ for (i = 0; i < G_N_ELEMENTS (hidden_names); i++)
+ if (g_ascii_strcasecmp (name, hidden_names[i]) == 0)
+ return TRUE;
+
+ /* Shares that end in "$" are administrative shares, and Windows hides
+ * them by default. We have no way to say "this is a hidden file" in a
+ * GnomeVFSFileInfo, so we'll make them visible for now.
+ */
return FALSE;
@@ -628,42 +783,56 @@ try_init (void)
g_free (path);
smb_context = smbc_new_context ();
- if (smb_context != NULL) {
- smb_context->debug = 0;
- smb_context->callbacks.auth_fn = auth_callback;
- smb_context->callbacks.add_cached_srv_fn = add_cached_server;
- smb_context->callbacks.get_cached_srv_fn = get_cached_server;
- smb_context->callbacks.remove_cached_srv_fn = remove_cached_server;
- smb_context->callbacks.purge_cached_fn = purge_cached;
-
- gclient = gconf_client_get_default ();
- if (gclient) {
- workgroup = gconf_client_get_string (gclient,
- PATH_GCONF_GNOME_VFS_SMB_WORKGROUP, NULL);
-
- /* libsmbclient frees this on it's own, so make sure
- * to use simple system malloc */
- if (workgroup && workgroup[0])
- smb_context->workgroup = strdup (workgroup);
-
- g_free (workgroup);
- g_object_unref (gclient);
- }
+ if (smb_context == NULL)
+ goto out;
- if (!smbc_init_context (smb_context)) {
- smbc_free_context (smb_context, FALSE);
- smb_context = NULL;
- }
+ smb_context->debug = 0;
+ smb_context->callbacks.auth_fn = auth_callback;
+ smb_context->callbacks.add_cached_srv_fn = add_cached_server;
+ smb_context->callbacks.get_cached_srv_fn = get_cached_server;
+ smb_context->callbacks.remove_cached_srv_fn = remove_cached_server;
+ smb_context->callbacks.purge_cached_fn = purge_cached;
+
+ DEBUG_SMB (("created the SMBCCTX; it has smbcctx->workgroup=\"%s\"\n",
+ smb_context->workgroup ? smb_context->workgroup : "(null)"));
+
+ gclient = gconf_client_get_default ();
+ if (gclient) {
+ workgroup = gconf_client_get_string (gclient,
+ PATH_GCONF_GNOME_VFS_SMB_WORKGROUP, NULL);
+
+ /* libsmbclient frees this on it's own, so make sure
+ * to use simple system malloc */
+ if (workgroup && workgroup[0])
+ smb_context->workgroup = strdup (workgroup);
+
+ g_free (workgroup);
+ g_object_unref (gclient);
+ }
+
+ DEBUG_SMB (("after reading from gconf, we have smbcctx->workgroup=\"%s\"\n",
+ smb_context->workgroup ? smb_context->workgroup : "(null)"));
+ if (!smbc_init_context (smb_context)) {
+ smbc_free_context (smb_context, FALSE);
+ smb_context = NULL;
+ DEBUG_SMB (("smbc_init_context() failed!\n"));
+ goto out;
+ }
+
+ DEBUG_SMB (("called smbc_init_context(); we have smbcctx->workgroup=\"%s\"\n",
+ smb_context->workgroup ? smb_context->workgroup : "(null)"));
+
#if defined(HAVE_SAMBA_FLAGS)
#if defined(SMB_CTX_FLAG_USE_KERBEROS) && defined(SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS)
- smb_context->flags |= SMB_CTX_FLAG_USE_KERBEROS | SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
+ smb_context->flags |= SMB_CTX_FLAG_USE_KERBEROS | SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
#endif
-#if defined(SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON)
- smb_context->flags |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
+# if 0
+# if defined(SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON)
+ smb_context->flags |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
+# endif
+# endif
#endif
-#endif
- }
server_cache = g_hash_table_new_full (server_hash, server_equal,
(GDestroyNotify)server_free, NULL);
@@ -671,7 +840,10 @@ try_init (void)
g_free, NULL);
user_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify)user_free);
-
+ printer_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ out:
UNLOCK_SMB();
if (smb_context == NULL) {
@@ -712,6 +884,8 @@ update_user_cache (SmbAuthContext *actx,
{
SmbCachedUser *user;
gchar *key;
+
+ DEBUG_IN ();
g_return_if_fail (actx->for_server != NULL);
@@ -732,6 +906,8 @@ update_user_cache (SmbAuthContext *actx,
user->username = string_realloc (user->username, actx->use_user);
user->password = string_realloc (user->password, actx->use_password);
user->stamp = time (NULL);
+
+ DEBUG_OUT ();
}
static gboolean
@@ -739,9 +915,13 @@ lookup_user_cache (SmbAuthContext *actx,
{
SmbCachedUser *user;
gchar *key;
-
+ gboolean retval;
+
g_return_val_if_fail (actx->for_server != NULL, FALSE);
+ DEBUG_IN ();
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+
key = g_strdup_printf ("%s/%s", actx->for_server, with_share ? actx->for_share : "");
user = (SmbCachedUser*)g_hash_table_lookup (user_cache, key);
g_free (key);
@@ -749,20 +929,33 @@ lookup_user_cache (SmbAuthContext *actx,
if (user) {
/* If we already have a user name or domain double check that... */
if (!(actx->prompt_flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME) &&
- !string_compare(user->username, actx->use_user))
- return FALSE;
+ !string_compare(user->username, actx->use_user)) {
+ retval = FALSE;
+ goto out;
+ }
+
if (!(actx->prompt_flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN) &&
- !string_compare(user->domain, actx->use_domain))
- return FALSE;
+ !string_compare(user->domain, actx->use_domain)) {
+ retval = FALSE;
+ goto out;
+ }
actx->use_user = string_realloc (actx->use_user, user->username);
actx->use_domain = string_realloc (actx->use_domain, user->domain);
actx->use_password = string_realloc (actx->use_password, user->password);
DEBUG_SMB(("[auth] Looked up in cache: %s:%s %s\n", actx->use_user, actx->use_domain, actx->use_password));
- return TRUE;
+ retval = TRUE;
+ goto out;
}
+
+ retval = FALSE;
+
+ out:
+
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+ DEBUG_OUT ();
- return FALSE;
+ return retval;
}
static gboolean
@@ -777,7 +970,10 @@ initial_authentication (SmbAuthContext *
gboolean preset_user = FALSE;
char *tmp;
+ DEBUG_IN ();
+
DEBUG_SMB(("[auth] Initial authentication lookups\n"));
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
toplevel_uri = (GnomeVFSToplevelURI*)actx->uri;
actx->prompt_flags = GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME |
@@ -843,6 +1039,8 @@ initial_authentication (SmbAuthContext *
}
}
+ DEBUG_OUT ();
+
return found_user;
}
@@ -856,7 +1054,10 @@ prefill_authentication (SmbAuthContext *
gboolean invoked;
g_return_val_if_fail (actx != NULL, FALSE);
- g_return_val_if_fail (actx->for_server != NULL, FALSE);
+ g_return_val_if_fail (actx->for_server != NULL, FALSE);
+
+ DEBUG_IN ();
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
memset (&in_args, 0, sizeof (in_args));
in_args.uri = get_auth_display_uri (actx, FALSE);
@@ -876,6 +1077,8 @@ prefill_authentication (SmbAuthContext *
&in_args, sizeof (in_args),
&out_args, sizeof (out_args));
+ DEBUG_SMB(("[auth] vfs module callback for FILL_AUTHENTICATION returned invoked=%d\n", invoked));
+
g_free (in_args.uri);
/* If that didn't work then try without the share name */
@@ -902,6 +1105,7 @@ prefill_authentication (SmbAuthContext *
(GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION,
&in_args, sizeof (in_args),
&out_args, sizeof (out_args));
+ DEBUG_SMB(("[auth] vfs module callback for FILL_AUTHENTICATION returned invoked=%d\n", invoked));
}
if (invoked && out_args.valid) {
@@ -918,6 +1122,9 @@ prefill_authentication (SmbAuthContext *
g_free (out_args.domain);
g_free (out_args.password);
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+ DEBUG_OUT ();
+
return invoked && out_args.valid;
}
@@ -933,6 +1140,9 @@ prompt_authentication (SmbAuthContext *a
g_return_val_if_fail (actx != NULL, FALSE);
g_return_val_if_fail (actx->for_server != NULL, FALSE);
+
+ DEBUG_IN ();
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
memset (&in_args, 0, sizeof (in_args));
@@ -954,29 +1164,38 @@ prompt_authentication (SmbAuthContext *a
memset (&out_args, 0, sizeof (out_args));
- DEBUG_SMB(("[auth] Prompting credentials for: %s\n", in_args.uri));
+ DEBUG_SMB(("[auth] Prompting credentials for: uri=%s, server=%s, object=%s, username=%s, domain=%s, default_user=%s, default_domain=%s\n",
+ in_args.uri,
+ in_args.server,
+ in_args.object,
+ in_args.username,
+ in_args.domain,
+ in_args.default_user,
+ in_args.default_domain));
invoked = gnome_vfs_module_callback_invoke
(GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION,
&in_args, sizeof (in_args),
&out_args, sizeof (out_args));
+ DEBUG_SMB(("[auth] vfs module callback for FULL_AUTHENTICATION returned invoked=%d\n", invoked));
+
if (invoked) {
if (in_args.flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME) {
- g_free (actx->use_user);
- actx->use_user = string_dup_nzero (out_args.username);
+ g_free (actx->use_user);
+ actx->use_user = string_dup_nzero (out_args.username);
}
if (in_args.flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN) {
- g_free (actx->use_domain);
- actx->use_domain = string_dup_nzero (out_args.domain);
+ g_free (actx->use_domain);
+ actx->use_domain = string_dup_nzero (out_args.domain);
}
g_free (actx->use_password);
actx->use_password = out_args.password ? g_strdup (out_args.password) : NULL;
g_free (actx->keyring);
actx->save_auth = out_args.save_password;
actx->keyring = actx->save_auth && out_args.keyring ? g_strdup (out_args.keyring) : NULL;
- DEBUG_SMB(("[auth] Prompted credentials: %s %s:%s\n", actx->use_user, actx->use_domain, actx->use_password));
- }
+ DEBUG_SMB(("[auth] Prompted credentials: %s %s:%s keyring=%s\n", actx->use_user, actx->use_domain, actx->use_password, actx->keyring));
+ }
*cancelled = out_args.abort_auth;
@@ -989,6 +1208,9 @@ prompt_authentication (SmbAuthContext *a
g_free (in_args.uri);
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+ DEBUG_OUT ();
+
return invoked && !*cancelled;
}
@@ -999,14 +1221,19 @@ save_authentication (SmbAuthContext *act
GnomeVFSModuleCallbackSaveAuthenticationOut out_args;
gboolean invoked;
+ DEBUG_IN ();
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+
/* Add to the user cache both with and without shares */
if (actx->for_server) {
update_user_cache (actx, TRUE);
update_user_cache (actx, FALSE);
}
- if (!actx->save_auth)
+ if (!actx->save_auth) {
+ DEBUG_OUT ();
return;
+ }
/* Save with the domain name */
memset (&in_args, 0, sizeof (in_args));
@@ -1030,6 +1257,8 @@ save_authentication (SmbAuthContext *act
&in_args, sizeof (in_args),
&out_args, sizeof (out_args));
+ DEBUG_SMB(("[auth] vfs module callback for SAVE_AUTHENTICATION returned invoked=%d\n", invoked));
+
g_free (in_args.uri);
/* Save without the domain name */
@@ -1054,14 +1283,18 @@ save_authentication (SmbAuthContext *act
&in_args, sizeof (in_args),
&out_args, sizeof (out_args));
+ DEBUG_SMB(("[auth] vfs module callback for SAVE_AUTHENTICATION returned invoked=%d\n", invoked));
+
g_free (in_args.uri);
+
+ DEBUG_OUT ();
}
static void
cleanup_authentication (SmbAuthContext *actx)
{
/* IMPORTANT: We are IN the lock at this point */
-
+ DEBUG_IN ();
DEBUG_SMB(("[auth] Cleaning up Authentication\n"));
g_return_if_fail (actx != NULL);
@@ -1085,6 +1318,9 @@ cleanup_authentication (SmbAuthContext *
g_return_if_fail (current_auth_context == actx);
current_auth_context = NULL;
+
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
+ DEBUG_OUT ();
}
/*
@@ -1129,9 +1365,12 @@ perform_authentication (SmbAuthContext *
{
gboolean cont, auth_failed = FALSE, auth_cancelled = FALSE;
int ret = -1;
+
+ DEBUG_IN ();
/* IMPORTANT: We are IN the lock at this point */
DEBUG_SMB(("[auth] perform_authentication called.\n"));
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
switch (actx->res) {
case GNOME_VFS_OK:
@@ -1147,8 +1386,9 @@ perform_authentication (SmbAuthContext *
/* Other errors mean we're done */
default:
- DEBUG_SMB(("[auth] Non-authentication error. Leaving auth loop.\n"));
+ DEBUG_SMB(("[auth] Non-authentication VFS error %d. Leaving auth loop.\n", (int) actx->res));
cleanup_authentication (actx);
+ DEBUG_OUT ();
return -1;
}
@@ -1189,7 +1429,7 @@ perform_authentication (SmbAuthContext *
/* A failed authentication */
} else if (actx->auth_called) {
-
+
/* We need a server to perform any authentication */
g_return_val_if_fail (actx->for_server != NULL, GNOME_VFS_ERROR_INTERNAL);
@@ -1199,23 +1439,27 @@ perform_authentication (SmbAuthContext *
UNLOCK_SMB();
- if (!(actx->state & SMB_AUTH_STATE_PREFILLED)) {
- actx->state |= SMB_AUTH_STATE_PREFILLED;
- cont = prefill_authentication (actx);
- }
-
- if (!cont)
- cont = prompt_authentication (actx, &auth_cancelled);
-
+ if (!(actx->state & SMB_AUTH_STATE_PREFILLED)) {
+ DEBUG_SMB(("[auth] failed authentication; will prefill from the vfs callback\n"));
+ actx->state |= SMB_AUTH_STATE_PREFILLED;
+ cont = prefill_authentication (actx);
+ } else {
+ DEBUG_SMB(("[auth] failed authentication; will prompt the user for authentication\n"));
+ }
+
+ if (!cont)
+ cont = prompt_authentication (actx, &auth_cancelled);
+
LOCK_SMB();
/* Claim the global context back */
g_return_val_if_fail (current_auth_context == NULL, GNOME_VFS_ERROR_INTERNAL);
current_auth_context = actx;
- if (cont)
+ if (cont) {
+ DEBUG_SMB(("[auth] prefill or prompt returned 1\n"));
ret = 1;
- else {
+ } else {
ret = -1;
if (auth_cancelled) {
@@ -1230,12 +1474,15 @@ perform_authentication (SmbAuthContext *
/* Weird, don't want authentication, but failed */
} else {
+ DEBUG_SMB(("[auth] don't want authentication, but failed\n"));
ret = -1;
}
}
if (ret <= 0)
cleanup_authentication (actx);
+
+ DEBUG_OUT ();
return ret;
/* IMPORTANT: We need to still be in the lock when returning from this func */
@@ -1250,16 +1497,22 @@ auth_callback (const char *server_name,
/* IMPORTANT: We are IN the global lock */
SmbAuthContext *actx;
SMBCSRV *server;
+
+ DEBUG_IN ();
- DEBUG_SMB (("[auth] auth_callback called: server: %s share: %s\n",
- server_name, share_name));
+ DEBUG_SMB (("[auth] auth_callback called: server=%s, share=%s, domain_out=%s, username_out=%s, password_out=%s\n",
+ server_name, share_name, domain_out, username_out, password_out));
g_return_if_fail (current_auth_context != NULL);
actx = current_auth_context;
+
+ DEBUG_DUMP_AUTH_CONTEXT (actx);
/* We never authenticate for the toplevel (enumerating workgroups) */
- if (!server_name || !server_name[0])
+ if (!server_name || !server_name[0]) {
+ DEBUG_OUT ();
return;
+ }
actx->auth_called = TRUE;
@@ -1270,8 +1523,10 @@ auth_callback (const char *server_name,
actx->for_share = string_dup_nzero (share_name);
/* The first pass, try the cache, fill in anything we know */
- if (actx->passes == 1)
+ if (actx->passes == 1) {
+ DEBUG_SMB(("[auth] first pass; call initial_authentication()\n"));
initial_authentication (actx);
+ }
/* If we have a valid user then go for it */
if (actx->use_user) {
@@ -1285,13 +1540,13 @@ auth_callback (const char *server_name,
} else if (actx->passes == 1) {
strncpy (username_out, "guest", unmaxlen);
strncpy (password_out, "", pwmaxlen);
- DEBUG_SMB(("[auth] No credentials, trying 'guest' user login\n"));
+ DEBUG_SMB(("[auth] No credentials, trying 'guest' user login with empty password\n"));
/* We have no credentials ... */
} else {
strncpy (username_out, "", unmaxlen);
strncpy (password_out, "", pwmaxlen);
- DEBUG_SMB(("[auth] No credentials, returning null values\n"));
+ DEBUG_SMB(("[auth] No credentials, returning empty user and password\n"));
}
/* Put in the default workgroup if none specified */
@@ -1304,15 +1559,30 @@ auth_callback (const char *server_name,
* this doesn't make much sense, but such is life with libsmbclient.
*/
if ((actx->state & SMB_AUTH_STATE_PROMPTED) && actx->res != GNOME_VFS_OK) {
+ DEBUG_SMB(("[auth] we had prompted already but auth failed. Calling find_cached_server() again\n"));
server = find_cached_server (server_name, share_name, domain_out, username_out);
if (server) {
DEBUG_SMB (("[auth] auth_callback. Remove the wrong server entry from server_cache.\n"));
g_hash_table_foreach_remove (server_cache, remove_server, server);
}
}
+
+ DEBUG_OUT ();
}
static char *
+get_printer_data (const char *display_name, const char *path)
+{
+ return g_strdup_printf ("[Desktop Entry]\n"
+ "Encoding=UTF-8\n"
+ "Name=%s\n"
+ "Type=Application\n"
+ "Exec=gnome-cups-add --printer=%s\n"
+ "Icon=printer-remote\n", /* per the freedesktop.org icon naming spec */
+ display_name, path);
+}
+
+static char *
get_workgroup_data (const char *display_name, const char *name)
{
return g_strdup_printf ("[Desktop Entry]\n"
@@ -1359,6 +1629,21 @@ typedef struct {
GnomeVFSFileOffset file_size;
} FileHandle;
+/* Takes ownership of desktop_file_contents */
+static FileHandle *
+file_handle_new_from_desktop_file_contents (char *desktop_file_contents)
+{
+ FileHandle *handle;
+
+ handle = g_new (FileHandle, 1);
+ handle->is_data = TRUE;
+ handle->offset = 0;
+ handle->file_data = desktop_file_contents;
+ handle->file_size = strlen (handle->file_data);
+
+ return handle;
+}
+
static GnomeVFSResult
do_open (GnomeVFSMethod *method,
GnomeVFSMethodHandle **method_handle,
@@ -1372,59 +1657,84 @@ do_open (GnomeVFSMethod *method,
int type;
mode_t unix_mode;
SMBCFILE *file = NULL;
-
+ GnomeVFSResult result;
+
+ DEBUG_IN ();
DEBUG_SMB(("do_open() %s mode %d\n",
gnome_vfs_uri_to_string (uri, 0), mode));
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
+
+ path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
+
+ if (is_printer (path)) {
+ if (mode & GNOME_VFS_OPEN_WRITE) {
+ result = GNOME_VFS_ERROR_READ_ONLY;
+ goto out;
+ }
+
+ unescaped_name = get_base_from_uri (uri);
+ name = gnome_vfs_uri_extract_short_path_name (uri);
+
+ handle = file_handle_new_from_desktop_file_contents (get_printer_data (unescaped_name, path));
+ *method_handle = (GnomeVFSMethodHandle *)handle;
+
+ g_free (unescaped_name);
+ g_free (name);
+
+ result = GNOME_VFS_OK;
+ goto out;
+ }
if (type == SMB_URI_WHOLE_NETWORK ||
type == SMB_URI_WORKGROUP ||
type == SMB_URI_SERVER ||
type == SMB_URI_SHARE) {
- return GNOME_VFS_ERROR_IS_DIRECTORY;
+ result = GNOME_VFS_ERROR_IS_DIRECTORY;
+ goto out;
}
if (type == SMB_URI_WORKGROUP_LINK) {
if (mode & GNOME_VFS_OPEN_WRITE) {
- return GNOME_VFS_ERROR_READ_ONLY;
+ result = GNOME_VFS_ERROR_READ_ONLY;
+ goto out;
}
- handle = g_new (FileHandle, 1);
- handle->is_data = TRUE;
- handle->offset = 0;
+
unescaped_name = get_base_from_uri (uri);
name = gnome_vfs_uri_extract_short_path_name (uri);
- handle->file_data = get_workgroup_data (unescaped_name, name);
- handle->file_size = strlen (handle->file_data);
+
+ handle = file_handle_new_from_desktop_file_contents (get_workgroup_data (unescaped_name, name));
+ *method_handle = (GnomeVFSMethodHandle *)handle;
+
g_free (unescaped_name);
g_free (name);
- *method_handle = (GnomeVFSMethodHandle *)handle;
-
- return GNOME_VFS_OK;
+ result = GNOME_VFS_OK;
+ goto out;
}
if (type == SMB_URI_SERVER_LINK) {
if (mode & GNOME_VFS_OPEN_WRITE) {
- return GNOME_VFS_ERROR_READ_ONLY;
+ result = GNOME_VFS_ERROR_READ_ONLY;
+ goto out;
}
- handle = g_new (FileHandle, 1);
- handle->is_data = TRUE;
- handle->offset = 0;
+
unescaped_name = get_base_from_uri (uri);
name = gnome_vfs_uri_extract_short_path_name (uri);
- handle->file_data = get_computer_data (unescaped_name, name);
- handle->file_size = strlen (handle->file_data);
+
+ handle = file_handle_new_from_desktop_file_contents (get_computer_data (unescaped_name, name));
+ *method_handle = (GnomeVFSMethodHandle *)handle;
+
g_free (unescaped_name);
g_free (name);
- *method_handle = (GnomeVFSMethodHandle *)handle;
-
- return GNOME_VFS_OK;
+ result = GNOME_VFS_OK;
+ goto out;
}
g_assert (type == SMB_URI_SHARE_FILE);
@@ -1437,16 +1747,16 @@ do_open (GnomeVFSMethod *method,
} else {
if (mode & GNOME_VFS_OPEN_WRITE)
unix_mode = O_WRONLY;
- else
- return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
+ else {
+ result = GNOME_VFS_ERROR_INVALID_OPEN_MODE;
+ goto out;
+ }
}
if ((mode & GNOME_VFS_OPEN_TRUNCATE) ||
(!(mode & GNOME_VFS_OPEN_RANDOM) && (mode & GNOME_VFS_OPEN_WRITE)))
unix_mode |= O_TRUNC;
- path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
-
LOCK_SMB();
init_authentication (&actx, uri);
@@ -1454,14 +1764,15 @@ do_open (GnomeVFSMethod *method,
while (perform_authentication (&actx) > 0) {
file = smb_context->open (smb_context, path, unix_mode, 0666);
actx.res = (file != NULL) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->open(\"%s\") returned file %p and error %d\n", path, file, (int) actx.res));
}
UNLOCK_SMB();
- g_free (path);
-
- if (file == NULL)
+ if (file == NULL) {
+ DEBUG_OUT ();
return actx.res;
+ }
handle = g_new (FileHandle, 1);
handle->is_data = FALSE;
@@ -1469,7 +1780,14 @@ do_open (GnomeVFSMethod *method,
*method_handle = (GnomeVFSMethodHandle *)handle;
- return GNOME_VFS_OK;
+ result = GNOME_VFS_OK;
+
+ out:
+
+ g_free (path);
+
+ DEBUG_OUT ();
+ return result;
}
static GnomeVFSResult
@@ -1483,6 +1801,7 @@ do_close (GnomeVFSMethod *method,
GnomeVFSResult res;
int r;
+ DEBUG_IN ();
DEBUG_SMB(("do_close()\n"));
res = GNOME_VFS_OK;
@@ -1501,6 +1820,7 @@ do_close (GnomeVFSMethod *method,
r = smb_context->close_fn (smb_context, handle->file);
#endif
actx.res = (r >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->close(%p) returned error %d\n", handle->file, (int) actx.res));
}
res = actx.res;
@@ -1508,6 +1828,7 @@ do_close (GnomeVFSMethod *method,
}
g_free (handle);
+ DEBUG_OUT ();
return res;
}
@@ -1524,6 +1845,7 @@ do_read (GnomeVFSMethod *method,
SmbAuthContext actx;
ssize_t n = 0;
+ DEBUG_IN ();
DEBUG_SMB(("do_read() %Lu bytes\n", num_bytes));
if (handle->is_data) {
@@ -1549,11 +1871,14 @@ do_read (GnomeVFSMethod *method,
*bytes_read = (n < 0) ? 0 : n;
- if (n == 0)
+ if (n == 0) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_EOF;
+ }
handle->offset += n;
+ DEBUG_OUT ();
return res;
}
@@ -1571,10 +1896,13 @@ do_write (GnomeVFSMethod *method,
SmbAuthContext actx;
ssize_t written = 0;
+ DEBUG_IN ();
DEBUG_SMB (("do_write() %p\n", method_handle));
- if (handle->is_data)
+ if (handle->is_data) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_READ_ONLY;
+ }
LOCK_SMB();
init_authentication (&actx, NULL);
@@ -1588,6 +1916,7 @@ do_write (GnomeVFSMethod *method,
UNLOCK_SMB();
*bytes_written = (written < 0) ? 0 : written;
+ DEBUG_OUT ();
return actx.res;
}
@@ -1606,30 +1935,39 @@ do_create (GnomeVFSMethod *method,
SMBCFILE *file = NULL;
FileHandle *handle;
SmbAuthContext actx;
-
+
+ DEBUG_IN ();
DEBUG_SMB (("do_create() %s mode %d\n",
gnome_vfs_uri_to_string (uri, 0), mode));
type = smb_uri_type (uri);
- if (type == SMB_URI_ERROR)
+ if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
+ }
if (type == SMB_URI_WHOLE_NETWORK ||
type == SMB_URI_WORKGROUP ||
type == SMB_URI_SERVER ||
- type == SMB_URI_SHARE)
+ type == SMB_URI_SHARE) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_IS_DIRECTORY;
+ }
if (type == SMB_URI_WORKGROUP_LINK ||
- type == SMB_URI_SERVER_LINK)
+ type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
+ }
unix_mode = O_CREAT | O_TRUNC;
- if (!(mode & GNOME_VFS_OPEN_WRITE))
+ if (!(mode & GNOME_VFS_OPEN_WRITE)) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
+ }
if (mode & GNOME_VFS_OPEN_READ)
unix_mode |= O_RDWR;
@@ -1648,24 +1986,44 @@ do_create (GnomeVFSMethod *method,
while (perform_authentication (&actx) > 0) {
file = smb_context->open (smb_context, path, unix_mode, perm);
actx.res = (file != NULL) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->open(\"%s\") returned file %p and error %d\n", path, file, (int) actx.res));
}
UNLOCK_SMB();
g_free (path);
- if (file == NULL)
+ if (file == NULL) {
+ DEBUG_OUT ();
return actx.res;
+ }
handle = g_new (FileHandle, 1);
handle->is_data = FALSE;
handle->file = file;
*method_handle = (GnomeVFSMethodHandle *)handle;
-
+
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
+static void
+set_file_info_to_readonly_desktop_file (GnomeVFSFileInfo *file_info, GnomeVFSURI *uri)
+{
+ file_info->name = get_base_from_uri (uri);
+ file_info->valid_fields = file_info->valid_fields
+ | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FIELDS_TYPE
+ | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
+ file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
+ file_info->mime_type = g_strdup ("application/x-desktop");
+ file_info->permissions =
+ GNOME_VFS_PERM_USER_READ |
+ GNOME_VFS_PERM_OTHER_READ |
+ GNOME_VFS_PERM_GROUP_READ;
+}
+
static GnomeVFSResult
do_get_file_info (GnomeVFSMethod *method,
GnomeVFSURI *uri,
@@ -1680,19 +2038,34 @@ do_get_file_info (GnomeVFSMethod *method
const char *mime_type;
SmbAuthContext actx;
+ DEBUG_IN ();
DEBUG_SMB (("do_get_file_info() %s\n",
gnome_vfs_uri_to_string (uri, 0)));
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
+
+ path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
+
+ if (is_printer (path)) {
+ DEBUG_SMB (("is a printer we already saw; will fill in info\n"));
+
+ set_file_info_to_readonly_desktop_file (file_info, uri);
+ g_free (path);
+
+ DEBUG_OUT ();
+ return GNOME_VFS_OK;
+ }
if (type == SMB_URI_WHOLE_NETWORK ||
type == SMB_URI_WORKGROUP ||
type == SMB_URI_SERVER ||
type == SMB_URI_SHARE) {
+ DEBUG_SMB (("is whole network, workgroup, server, or share\n"));
file_info->name = get_base_from_uri (uri);
file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
@@ -1713,29 +2086,22 @@ do_get_file_info (GnomeVFSMethod *method
GNOME_VFS_PERM_OTHER_READ |
GNOME_VFS_PERM_GROUP_READ;
}
+ DEBUG_OUT();
return GNOME_VFS_OK;
}
if (type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
- file_info->name = get_base_from_uri (uri);
- file_info->valid_fields = file_info->valid_fields
- | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FIELDS_TYPE
- | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
- file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
- file_info->mime_type = g_strdup ("application/x-desktop");
- file_info->permissions =
- GNOME_VFS_PERM_USER_READ |
- GNOME_VFS_PERM_OTHER_READ |
- GNOME_VFS_PERM_GROUP_READ;
+ DEBUG_SMB (("is workgroup link, or server link\n"));
+ set_file_info_to_readonly_desktop_file (file_info, uri);
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
g_assert (type == SMB_URI_SHARE_FILE);
-
- path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
+ DEBUG_SMB (("is share file\n"));
+
LOCK_SMB();
init_authentication (&actx, uri);
@@ -1743,14 +2109,17 @@ do_get_file_info (GnomeVFSMethod *method
while (perform_authentication (&actx) > 0) {
err = smb_context->stat (smb_context, path, &st);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->stat(\"%s\") returned error %d\n", path, (int) actx.res));
}
UNLOCK_SMB();
g_free (path);
- if (err < 0)
+ if (err < 0) {
+ DEBUG_OUT ();
return actx.res;
+ }
gnome_vfs_stat_to_file_info (file_info, &st);
file_info->name = get_base_from_uri (uri);
@@ -1776,6 +2145,7 @@ do_get_file_info (GnomeVFSMethod *method
file_info->name, type,
file_info->mime_type, file_info->type));
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -1791,6 +2161,7 @@ do_get_file_info_from_handle (GnomeVFSMe
struct stat st;
int err = -1;
+ DEBUG_IN ();
LOCK_SMB();
init_authentication (&actx, NULL);
@@ -1798,17 +2169,22 @@ do_get_file_info_from_handle (GnomeVFSMe
while (perform_authentication (&actx) > 0) {
err = smb_context->fstat (smb_context, handle->file, &st);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->fstat(%p) returned error %d\n", handle->file, (int) actx.res));
}
UNLOCK_SMB();
- if (err < 0)
+ if (err < 0) {
+ DEBUG_OUT ();
return actx.res;
+ }
gnome_vfs_stat_to_file_info (file_info, &st);
file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE;
file_info->io_block_size = SMB_BLOCK_SIZE;
+
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -1816,7 +2192,19 @@ static gboolean
do_is_local (GnomeVFSMethod *method,
const GnomeVFSURI *uri)
{
- return FALSE;
+ char *path;
+ gboolean is_local;
+
+ /* FIXME: This is a hack. In get_printer_data(), we generate data for a desktop item. This item
+ * is a "Type=Application" launcher, which launches gnome-cups-add. However, since we can't execute
+ * .desktop files from remote sites, we only advertise that printers "are local files".
+ */
+
+ path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
+ is_local = is_printer (path);
+ g_free (path);
+
+ return is_local;
}
typedef struct {
@@ -1854,6 +2242,7 @@ do_open_directory (GnomeVFSMethod *metho
SMBCFILE *dir = NULL;
SmbAuthContext actx;
+ DEBUG_IN ();
DEBUG_SMB(("do_open_directory() %s\n",
gnome_vfs_uri_to_string (uri, 0)));
@@ -1865,12 +2254,14 @@ do_open_directory (GnomeVFSMethod *metho
directory_handle = g_new0 (DirectoryHandle, 1);
g_hash_table_foreach (workgroups, add_workgroup, directory_handle);
*method_handle = (GnomeVFSMethodHandle *) directory_handle;
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
if (type == SMB_URI_ERROR ||
type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_A_DIRECTORY;
}
@@ -1879,11 +2270,22 @@ do_open_directory (GnomeVFSMethod *metho
host_name = gnome_vfs_uri_get_host_name (uri);
if (type == SMB_URI_WORKGROUP && host_name != NULL &&
!g_ascii_strcasecmp(host_name, DEFAULT_WORKGROUP_NAME)) {
+ char *new_workgroup;
+
new_uri = gnome_vfs_uri_dup (uri);
- gnome_vfs_uri_set_host_name (new_uri,
- smb_context->workgroup
- ? smb_context->workgroup
- : "WORKGROUP");
+ if (smb_context->workgroup)
+ new_workgroup = smb_context->workgroup;
+ else
+ new_workgroup = "WORKGROUP";
+
+ DEBUG_SMB (("we are being asked for %s; substituting it for workgroup \"%s\"%s\n",
+ DEFAULT_WORKGROUP_NAME,
+ new_workgroup,
+ (smb_context->workgroup
+ ? " because that is what was in the smbcctx->workgroup"
+ : " because smbcctx->workgroup=NULL, so we use this as a last resort")));
+
+ gnome_vfs_uri_set_host_name (new_uri, new_workgroup);
uri = new_uri;
}
@@ -1898,6 +2300,7 @@ do_open_directory (GnomeVFSMethod *metho
while (perform_authentication (&actx) > 0) {
dir = smb_context->opendir (smb_context, path);
actx.res = (dir != NULL) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->opendir(\"%s\") returned dir %p and error %d\n", path, dir, (int) actx.res));
}
UNLOCK_SMB();
@@ -1907,6 +2310,7 @@ do_open_directory (GnomeVFSMethod *metho
if (dir == NULL) {
g_free (path);
+ DEBUG_OUT ();
return actx.res;
}
@@ -1916,6 +2320,7 @@ do_open_directory (GnomeVFSMethod *metho
directory_handle->path = path;
*method_handle = (GnomeVFSMethodHandle *) directory_handle;
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -1930,10 +2335,13 @@ do_close_directory (GnomeVFSMethod *meth
GList *l;
int err = -1;
+ DEBUG_IN ();
DEBUG_SMB(("do_close_directory: %p\n", directory_handle));
- if (directory_handle == NULL)
+ if (directory_handle == NULL) {
+ DEBUG_OUT ();
return GNOME_VFS_OK;
+ }
if (directory_handle->workgroups != NULL) {
for (l = directory_handle->workgroups; l != NULL; l = l->next) {
@@ -1952,6 +2360,7 @@ do_close_directory (GnomeVFSMethod *meth
while (perform_authentication (&actx) > 0) {
err = smb_context->closedir (smb_context, directory_handle->dir);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->closedir(%p) returned error %d\n", directory_handle->dir, (int) actx.res));
}
res = actx.res;
@@ -1960,9 +2369,46 @@ do_close_directory (GnomeVFSMethod *meth
g_free (directory_handle->path);
g_free (directory_handle);
+ DEBUG_OUT ();
return res;
}
+static char *
+make_path_from_uri_and_name (const char *path, const char *name)
+{
+ char *escaped_name;
+ char *new_path;
+
+ escaped_name = gnome_vfs_escape_string (name);
+
+ if (path[strlen(path) - 1] == '/') {
+ new_path = g_strconcat (path, escaped_name, NULL);
+ } else {
+ new_path = g_strconcat (path, "/", escaped_name, NULL);
+ }
+
+ g_free (escaped_name);
+
+ return new_path;
+}
+
+static void
+add_printer_to_hash (DirectoryHandle *dh,
+ GnomeVFSFileInfo *file_info)
+{
+ char *path;
+
+ path = make_path_from_uri_and_name (dh->path, file_info->name);
+
+ g_hash_table_insert (printer_hash, path, path);
+}
+
+static gboolean
+is_printer (const char *uri)
+{
+ return g_hash_table_lookup (printer_hash, uri) != NULL;
+}
+
static GnomeVFSResult
do_read_directory (GnomeVFSMethod *method,
GnomeVFSMethodHandle *method_handle,
@@ -1974,14 +2420,15 @@ do_read_directory (GnomeVFSMethod *metho
SmbAuthContext actx;
struct stat st;
char *statpath;
- char *path;
int r = -1;
GList *l;
+ DEBUG_IN ();
DEBUG_SMB (("do_read_directory()\n"));
if (dh->dir == NULL) {
if (dh->workgroups == NULL) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_EOF;
} else {
/* workgroup link */
@@ -1995,6 +2442,7 @@ do_read_directory (GnomeVFSMethod *metho
| GNOME_VFS_FILE_INFO_FIELDS_TYPE;
file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
file_info->mime_type = g_strdup ("application/x-desktop");
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
}
@@ -2018,16 +2466,20 @@ do_read_directory (GnomeVFSMethod *metho
} else {
actx.res = GNOME_VFS_OK;
}
+ DEBUG_SMB(("ctx->readdir(%p) returned entry %p and error %d\n", dh->dir, entry, (int) actx.res));
}
if (entry == NULL) {
UNLOCK_SMB();
+ DEBUG_OUT ();
return actx.res;
}
} while (entry->smbc_type == SMBC_COMMS_SHARE ||
entry->smbc_type == SMBC_IPC_SHARE ||
+#if 0
entry->smbc_type == SMBC_PRINTER_SHARE ||
+#endif
entry->name == NULL ||
strlen (entry->name) == 0 ||
(entry->smbc_type == SMBC_FILE_SHARE &&
@@ -2057,29 +2509,24 @@ do_read_directory (GnomeVFSMethod *metho
file_info->mime_type = g_strdup ("application/x-desktop");
break;
case SMBC_PRINTER_SHARE:
+#if 0
/* Ignored above for now */
+#endif
file_info->valid_fields = file_info->valid_fields
| GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
| GNOME_VFS_FILE_INFO_FIELDS_TYPE;
file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
- file_info->mime_type = g_strdup ("application/x-smb-printer");
+ file_info->mime_type = g_strdup ("application/x-desktop"); /* we'll generate the fake .desktop in do_open() */
+ add_printer_to_hash (dh, file_info);
+ debug_print ("GOT PRINTER: \"%s\"", file_info->name);
+ break;
case SMBC_COMMS_SHARE:
case SMBC_IPC_SHARE:
break;
case SMBC_DIR:
case SMBC_FILE:
- path = dh->path;
-
- if (path[strlen(path)-1] == '/') {
- statpath = g_strconcat (path,
- gnome_vfs_escape_string (file_info->name),
- NULL);
- } else {
- statpath = g_strconcat (path,
- "/",
- gnome_vfs_escape_string (file_info->name),
- NULL);
- }
+ statpath = make_path_from_uri_and_name (dh->path, file_info->name);
+
/* TODO: might give an auth error, but should be rare due
to the succeeding opendir. If this happens and we can't
auth, we should terminate the readdir to avoid multiple
@@ -2093,6 +2540,7 @@ do_read_directory (GnomeVFSMethod *metho
while (perform_authentication (&actx) > 0) {
r = smb_context->stat (smb_context, statpath, &st);
actx.res = (r == 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->stat(\"%s\") returned error %d\n", statpath, (int) actx.res));
}
UNLOCK_SMB();
@@ -2127,6 +2575,7 @@ do_read_directory (GnomeVFSMethod *metho
g_assert_not_reached ();
}
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2142,6 +2591,8 @@ do_seek (GnomeVFSMethod *method,
int meth_whence;
off_t ret = (off_t) -1;
+ DEBUG_IN ();
+
if (handle->is_data) {
switch (whence) {
case GNOME_VFS_SEEK_START:
@@ -2158,8 +2609,11 @@ do_seek (GnomeVFSMethod *method,
}
break;
default:
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_SUPPORTED;
}
+
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2174,6 +2628,7 @@ do_seek (GnomeVFSMethod *method,
meth_whence = SEEK_END;
break;
default:
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_SUPPORTED;
}
@@ -2186,7 +2641,8 @@ do_seek (GnomeVFSMethod *method,
actx.res = (ret != (off_t) -1) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
}
UNLOCK_SMB();
-
+
+ DEBUG_OUT ();
return actx.res;
}
@@ -2199,8 +2655,11 @@ do_tell (GnomeVFSMethod *method,
SmbAuthContext actx;
off_t ret = (off_t) -1;
+ DEBUG_IN ();
+
if (handle->is_data) {
*offset_return = handle->offset;
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2215,6 +2674,8 @@ do_tell (GnomeVFSMethod *method,
UNLOCK_SMB();
*offset_return = (ret == (off_t) -1) ? 0 : (GnomeVFSFileOffset) ret;
+
+ DEBUG_OUT ();
return actx.res;
}
@@ -2227,12 +2688,14 @@ do_unlink (GnomeVFSMethod *method,
SmbAuthContext actx;
int type, err = -1;
+ DEBUG_IN ();
DEBUG_SMB (("do_unlink() %s\n",
gnome_vfs_uri_to_string (uri, 0)));
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
@@ -2242,6 +2705,7 @@ do_unlink (GnomeVFSMethod *method,
type == SMB_URI_SHARE ||
type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
}
@@ -2254,12 +2718,14 @@ do_unlink (GnomeVFSMethod *method,
while (perform_authentication (&actx) > 0) {
err = smb_context->unlink (smb_context, path);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->unlink(\"%s\") returned error %d\n", path, (int) actx.res));
}
UNLOCK_SMB();
g_free (path);
-
+
+ DEBUG_OUT ();
return actx.res;
}
@@ -2276,6 +2742,7 @@ do_check_same_fs (GnomeVFSMethod *method
char *path2;
char *p1, *p2;
+ DEBUG_IN ();
DEBUG_SMB (("do_check_same_fs()\n"));
server1 =
@@ -2296,6 +2763,7 @@ do_check_same_fs (GnomeVFSMethod *method
g_free (path1);
g_free (path2);
*same_fs_return = FALSE;
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2324,6 +2792,7 @@ do_check_same_fs (GnomeVFSMethod *method
g_free (path1);
g_free (path2);
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2340,7 +2809,7 @@ do_move (GnomeVFSMethod *method,
SmbAuthContext actx;
int old_type, new_type;
-
+ DEBUG_IN ();
DEBUG_SMB (("do_move() %s %s\n",
gnome_vfs_uri_to_string (old_uri, 0),
gnome_vfs_uri_to_string (new_uri, 0)));
@@ -2350,6 +2819,7 @@ do_move (GnomeVFSMethod *method,
if (old_type != SMB_URI_SHARE_FILE ||
new_type != SMB_URI_SHARE_FILE) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
}
@@ -2367,6 +2837,7 @@ do_move (GnomeVFSMethod *method,
err = smb_context->rename (smb_context, old_path, smb_context, new_path);
errnox = errno;
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->rename(\"%s\", \"%s\") returned error %d\n", old_path, new_path, (int) actx.res));
}
UNLOCK_SMB();
@@ -2383,6 +2854,7 @@ do_move (GnomeVFSMethod *method,
while (perform_authentication (&actx) > 0) {
err = smb_context->unlink (smb_context, new_path);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->unlink(\"%s\") returned error %d\n", new_path, (int) actx.res));
}
UNLOCK_SMB();
@@ -2399,6 +2871,7 @@ do_move (GnomeVFSMethod *method,
g_free (old_path);
g_free (new_path);
+ DEBUG_OUT ();
return actx.res;
}
@@ -2423,9 +2896,11 @@ do_make_directory (GnomeVFSMethod *metho
int type, err = -1;
SmbAuthContext actx;
+ DEBUG_IN ();
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
@@ -2435,6 +2910,7 @@ do_make_directory (GnomeVFSMethod *metho
type == SMB_URI_SHARE ||
type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
}
@@ -2448,12 +2924,14 @@ do_make_directory (GnomeVFSMethod *metho
while (perform_authentication (&actx) > 0) {
err = smb_context->mkdir (smb_context, path, perm);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->mkdir(\"%s\") returned error %d\n", path, (int) actx.res));
}
UNLOCK_SMB();
g_free (path);
+ DEBUG_OUT ();
return actx.res;
}
@@ -2466,9 +2944,11 @@ do_remove_directory (GnomeVFSMethod *met
int err = -1, type;
SmbAuthContext actx;
+ DEBUG_IN ();
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
@@ -2478,6 +2958,7 @@ do_remove_directory (GnomeVFSMethod *met
type == SMB_URI_SHARE ||
type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
}
@@ -2490,11 +2971,13 @@ do_remove_directory (GnomeVFSMethod *met
while (perform_authentication (&actx) > 0) {
err = smb_context->rmdir (smb_context, path);
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->rmdir(\"%s\") returned error %d\n", path, (int) actx.res));
}
UNLOCK_SMB();
g_free (path);
+ DEBUG_OUT ();
return actx.res;
}
@@ -2509,11 +2992,13 @@ do_set_file_info (GnomeVFSMethod *method
int err = -1, errnox = 0, type;
SmbAuthContext actx;
+ DEBUG_IN ();
DEBUG_SMB (("do_set_file_info: mask %x\n", mask));
type = smb_uri_type (uri);
if (type == SMB_URI_ERROR) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_INVALID_URI;
}
@@ -2523,6 +3008,7 @@ do_set_file_info (GnomeVFSMethod *method
type == SMB_URI_SHARE ||
type == SMB_URI_WORKGROUP_LINK ||
type == SMB_URI_SERVER_LINK) {
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_PERMITTED;
}
@@ -2546,6 +3032,7 @@ do_set_file_info (GnomeVFSMethod *method
err = smb_context->rename (smb_context, path, smb_context, new_path);
errnox = errno;
actx.res = (err >= 0) ? GNOME_VFS_OK : gnome_vfs_result_from_errno ();
+ DEBUG_SMB(("ctx->rename(\"%s\", \"%s\") returned error %d\n", path, new_path, (int) actx.res));
}
UNLOCK_SMB();
@@ -2558,31 +3045,37 @@ do_set_file_info (GnomeVFSMethod *method
if (actx.res != GNOME_VFS_OK) {
g_free (path);
+ DEBUG_OUT ();
return actx.res;
}
}
if (gnome_vfs_context_check_cancellation (context)) {
g_free (path);
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_CANCELLED;
}
if (mask & GNOME_VFS_SET_FILE_INFO_PERMISSIONS) {
g_free (path);
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_SUPPORTED;
}
if (mask & GNOME_VFS_SET_FILE_INFO_OWNER) {
g_free (path);
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_SUPPORTED;
}
if (mask & GNOME_VFS_SET_FILE_INFO_TIME) {
g_free (path);
+ DEBUG_OUT ();
return GNOME_VFS_ERROR_NOT_SUPPORTED;
}
g_free (path);
+ DEBUG_OUT ();
return GNOME_VFS_OK;
}
@@ -2614,11 +3107,50 @@ static GnomeVFSMethod method = {
NULL /* do_create_symbolic_link */
};
+static void
+debug_init (void)
+{
+ char *debug_flag_path;
+ struct stat st;
+
+ LOCK_SMB ();
+
+ debug_flag_path = g_build_filename (g_get_home_dir (), ".debug-gnome-vfs-smb", NULL);
+
+ if (stat (debug_flag_path, &st) == 0) {
+ char *debug_filename;
+
+ debug_filename = g_build_filename (g_get_home_dir (), "debug-gnome-vfs-smb.log", NULL);
+ debug_file = fopen (debug_filename, "w");
+ g_free (debug_filename);
+ } else
+ debug_file = NULL;
+
+ g_free (debug_flag_path);
+
+ UNLOCK_SMB ();
+}
+
+static void
+debug_shutdown (void)
+{
+ LOCK_SMB ();
+
+ if (debug_file) {
+ fclose (debug_file);
+ debug_file = NULL;
+ }
+
+ UNLOCK_SMB ();
+}
+
GnomeVFSMethod *
vfs_module_init (const char *method_name, const char *args)
{
smb_lock = g_mutex_new ();
+ debug_init ();
+
DEBUG_SMB (("<-- smb module init called -->\n"));
if (try_init ()) {
@@ -2641,9 +3173,12 @@ vfs_module_shutdown (GnomeVFSMethod *met
g_hash_table_destroy (server_cache);
g_hash_table_destroy (workgroups);
g_hash_table_destroy (user_cache);
+ g_hash_table_destroy (printer_hash);
g_mutex_free (smb_lock);
DEBUG_SMB (("<-- smb module shutdown called -->\n"));
+
+ debug_shutdown ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]