#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);
+static void
+get_auth_data_with_context_fn(SMBCCTX * context,
+ const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword);
+
int
main(int argc, char * argv[])
{
int debug = 0;
+ int debug_stderr = 0;
+ int no_auth = 0;
+ int context_auth = 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;
+ SMBCCTX * context;
struct poptOption long_options[] =
{
POPT_AUTOHELP
"debug", 'd', POPT_ARG_INT, &debug,
0, "Set debug level", "integer"
},
+ {
+ "stderr", 'e', POPT_ARG_NONE, &debug_stderr,
+ 0, "Debug log to stderr instead of stdout", "integer"
+ },
+ {
+ "scan", 's', POPT_ARG_NONE, &scan,
+ 0, "Scan for servers and shares", "integer"
+ },
+ {
+ "iterations", 'i', POPT_ARG_INT, &iterations,
+ 0, "Iterations", "integer"
+ },
+ {
+ "noauth", 'A', POPT_ARG_NONE, &no_auth,
+ 0, "Do not request authentication data", "integer"
+ },
+ {
+ "contextauth", 'C', POPT_ARG_NONE, &context_auth,
+ 0, "Use new authentication function with context", "integer"
+ },
{
NULL
}
}
}
- if (smbc_init(get_auth_data_fn, debug) != 0)
- {
- printf("Could not initialize smbc_ library\n");
+ /* Allocate a new context */
+ context = smbc_new_context();
+ if (!context) {
+ printf("Could not allocate new smbc context\n");
return 1;
}
-
- 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))
+
+ /* If we're scanning, do no requests for authentication data */
+ if (scan) {
+ no_auth = 1;
+ }
+
+ /* Set mandatory options (is that a contradiction in terms?) */
+ context->debug = debug;
+ if (context_auth) {
+ context->callbacks.auth_fn = NULL;
+ smbc_option_set(context,
+ "auth_function",
+ (void *) get_auth_data_with_context_fn);
+ smbc_option_set(context, "user_data", "hello world");
+ } else {
+ context->callbacks.auth_fn =
+ (no_auth ? no_auth_data_fn : get_auth_data_fn);
+ }
+
+ /* If we've been asked to log to stderr instead of stdout, ... */
+ if (debug_stderr) {
+ /* ... then set the option to do so */
+ smbc_option_set(context, "debug_to_stderr", 1);
+ }
+
+ /* Initialize the context using the previously specified options */
+ if (!smbc_init_context(context)) {
+ smbc_free_context(context, 0);
+ printf("Could not initialize smbc context\n");
+ return 1;
+ }
+
+ /* Tell the compatibility layer to use this context */
+ smbc_set_context(context);
+
+ if (scan)
{
- if ((p = strchr(buf, '\n')) != NULL)
+ for (;
+ iterations == -1 || iterations > 0;
+ iterations = (iterations == -1 ? iterations : --iterations))
{
- *p = '\0';
+ snprintf(buf, sizeof(buf), "smb://");
+ browse(buf, scan, 0);
}
-
- printf("Opening (%s)...\n", buf);
-
- if ((dir = smbc_opendir(buf)) < 0)
+ }
+ else
+ {
+ 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
+get_auth_data_with_context_fn(SMBCCTX * context,
+ const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword)
+{
+ printf("Authenticating with context 0x%lx", context);
+ if (context != NULL) {
+ char *user_data = smbc_option_get(context, "user_data");
+ printf(" with user data %s", user_data);
+ }
+ printf("\n");
+
+ get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup,
+ pUsername, maxLenUsername, pPassword, maxLenPassword);
+}
+
+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);
}
+