summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/libsmbclient/testbrowse.c238
-rw-r--r--source3/libsmb/libsmbclient.c32
2 files changed, 195 insertions, 75 deletions
diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c
index 27d6a69738..6fa70eab41 100644
--- a/examples/libsmbclient/testbrowse.c
+++ b/examples/libsmbclient/testbrowse.c
@@ -9,24 +9,34 @@
#include <libsmbclient.h>
#include "get_auth_data_fn.h"
-void error_message(char * pMessage)
-{
- printf("ERROR: %s\n", pMessage);
-}
+static void
+no_auth_data_fn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword);
+
+static void browse(char * path,
+ int scan,
+ int indent);
+
int
main(int argc, char * argv[])
{
int debug = 0;
+ int scan = 0;
+ int iterations = -1;
+ int again;
int opt;
char * p;
char * q;
char buf[1024];
- int dir;
- struct stat stat;
- struct smbc_dirent * dirent;
- poptContext pc;
+ poptContext pc;
struct poptOption long_options[] =
{
POPT_AUTOHELP
@@ -35,6 +45,14 @@ main(int argc, char * argv[])
0, "Set debug level", "integer"
},
{
+ "scan", 's', POPT_ARG_NONE, &scan,
+ 0, "Scan for servers and shares", "integer"
+ },
+ {
+ "iterations", 'i', POPT_ARG_INT, &iterations,
+ 0, "Iterations", "integer"
+ },
+ {
NULL
}
};
@@ -51,94 +69,164 @@ main(int argc, char * argv[])
}
}
- if (smbc_init(get_auth_data_fn, debug) != 0)
+ if (scan)
{
- printf("Could not initialize smbc_ library\n");
- return 1;
+ if (smbc_init(no_auth_data_fn, debug) != 0)
+ {
+ printf("Could not initialize smbc_ library\n");
+ return 1;
+ }
+
+ for (;
+ iterations == -1 || iterations > 0;
+ iterations = (iterations == -1 ? iterations : --iterations))
+ {
+ snprintf(buf, sizeof(buf), "smb://");
+ browse(buf, scan, 0);
+ }
}
-
- for (fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin);
- p != NULL && *p != '\n' && *p != '\0';
- fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin))
+ else
{
- if ((p = strchr(buf, '\n')) != NULL)
+ if (smbc_init(get_auth_data_fn, debug) != 0)
{
- *p = '\0';
+ printf("Could not initialize smbc_ library\n");
+ return 1;
}
-
- printf("Opening (%s)...\n", buf);
-
- if ((dir = smbc_opendir(buf)) < 0)
+
+ for (;
+ iterations == -1 || iterations > 0;
+ iterations = (iterations == -1 ? iterations : --iterations))
{
- printf("Could not open directory [%s] (%d:%s)\n",
- buf, errno, strerror(errno));
- continue;
+ fputs("url: ", stdout);
+ p = fgets(buf, sizeof(buf), stdin);
+ if (! p)
+ {
+ break;
+ }
+
+ if ((p = strchr(buf, '\n')) != NULL)
+ {
+ *p = '\0';
+ }
+
+ browse(buf, scan, 0);
}
+ }
- while ((dirent = smbc_readdir(dir)) != NULL)
- {
- printf("%-30s", dirent->name);
- printf("%-30s", dirent->comment);
+ exit(0);
+}
- switch(dirent->smbc_type)
- {
- case SMBC_WORKGROUP:
- printf("WORKGROUP");
- break;
+
+static void
+no_auth_data_fn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword)
+{
+ return;
+}
+
+static void browse(char * path, int scan, int indent)
+{
+ char * p;
+ char buf[1024];
+ int dir;
+ struct stat stat;
+ struct smbc_dirent * dirent;
+
+ if (! scan)
+ {
+ printf("Opening (%s)...\n", path);
+ }
+
+ if ((dir = smbc_opendir(path)) < 0)
+ {
+ printf("Could not open directory [%s] (%d:%s)\n",
+ path, errno, strerror(errno));
+ return;
+ }
+
+ while ((dirent = smbc_readdir(dir)) != NULL)
+ {
+ printf("%*.*s%-30s", indent, indent, "", dirent->name);
+
+ switch(dirent->smbc_type)
+ {
+ case SMBC_WORKGROUP:
+ printf("WORKGROUP");
+ break;
- case SMBC_SERVER:
- printf("SERVER");
- break;
+ case SMBC_SERVER:
+ printf("SERVER");
+ break;
- case SMBC_FILE_SHARE:
- printf("FILE_SHARE");
- break;
+ case SMBC_FILE_SHARE:
+ printf("FILE_SHARE");
+ break;
- case SMBC_PRINTER_SHARE:
- printf("PRINTER_SHARE");
- break;
+ case SMBC_PRINTER_SHARE:
+ printf("PRINTER_SHARE");
+ break;
- case SMBC_COMMS_SHARE:
- printf("COMMS_SHARE");
- break;
+ case SMBC_COMMS_SHARE:
+ printf("COMMS_SHARE");
+ break;
- case SMBC_IPC_SHARE:
- printf("IPC_SHARE");
- break;
+ case SMBC_IPC_SHARE:
+ printf("IPC_SHARE");
+ break;
- case SMBC_DIR:
- printf("DIR");
- break;
+ case SMBC_DIR:
+ printf("DIR");
+ break;
- case SMBC_FILE:
- printf("FILE");
-
- q = buf + strlen(buf);
- strcat(q, "/");
- strcat(q+1, dirent->name);
- if (smbc_stat(buf, &stat) < 0)
- {
- printf(" unknown size (reason %d: %s)",
- errno, strerror(errno));
- }
- else
- {
- printf(" size %lu", (unsigned long) stat.st_size);
- }
- *p = '\0';
+ case SMBC_FILE:
+ printf("FILE");
- break;
-
- case SMBC_LINK:
- printf("LINK");
- break;
+ p = path + strlen(path);
+ strcat(p, "/");
+ strcat(p+1, dirent->name);
+ if (smbc_stat(path, &stat) < 0)
+ {
+ printf(" unknown size (reason %d: %s)",
+ errno, strerror(errno));
}
+ else
+ {
+ printf(" size %lu", (unsigned long) stat.st_size);
+ }
+ *p = '\0';
- printf("\n");
+ break;
+
+ case SMBC_LINK:
+ printf("LINK");
+ break;
}
- smbc_closedir(dir);
+ printf("\n");
+
+ if (scan &&
+ (dirent->smbc_type == SMBC_WORKGROUP ||
+ dirent->smbc_type == SMBC_SERVER))
+ {
+ /*
+ * don't append server name to workgroup; what we want is:
+ *
+ * smb://workgroup_name
+ * or
+ * smb://server_name
+ *
+ */
+ snprintf(buf, sizeof(buf), "smb://%s", dirent->name);
+ browse(buf, scan, indent + 2);
+ }
}
- exit(0);
+ smbc_closedir(dir);
}
+
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index f180072a70..f482c9584f 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -584,9 +584,25 @@ SMBCSRV *smbc_server(SMBCCTX *context,
return NULL;
}
+#if 0 /* choice 1 */
+ /* Look for a cached connection, using the provided authinfo */
srv = find_server(context, server, share,
workgroup, username, password);
+ /* If we didn't find one... */
+ if (! srv)
+ {
+ /* ... then see if there's one using anonymous login */
+ fstring anonymous = "";
+ srv = find_server(context, server, share,
+ workgroup, anonymous, password);
+ }
+#else
+ /* Look for a cached connection */
+ srv = find_server(context, server, share,
+ workgroup, username, password);
+#endif
+
/*
* If we found a connection and we're only allowed one share per
* server...
@@ -780,7 +796,11 @@ SMBCSRV *smbc_server(SMBCCTX *context,
/* now add it to the cache (internal or external) */
/* Let the cache function set errno if it wants to */
errno = 0;
+#if 0 /* choice 2 */
if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) {
+#else
+ if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
+#endif
int saved_errno = errno;
DEBUG(3, (" Failed to add server to cache\n"));
errno = saved_errno;
@@ -2169,6 +2189,7 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat
/* Found the end of the list. Remove it. */
dir->dir_end = dir_list;
free(dir_list->next);
+ free(dirent);
dir_list->next = NULL;
break;
}
@@ -2337,7 +2358,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
* a single master browser.
*/
+ ip_list = NULL;
if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
+
+ SAFE_FREE(ip_list);
+
if (!find_master_ip(workgroup, &server_addr.ip)) {
errno = ENOENT;
@@ -2383,9 +2408,16 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
(void *)dir)) {
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+
continue;
}
}
+
+ SAFE_FREE(ip_list);
} else {
/*
* Server not an empty string ... Check the rest and see what