diff options
-rw-r--r-- | examples/libsmbclient/testbrowse.c | 238 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 32 |
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 |