Add NetGetJoinableOUs() to libnetapi (incl. example).
[nivanova/samba-autobuild/.git] / examples / libsmbclient / testbrowse.c
index 27d6a6973882e377f6b4429d7ac14d742408872f..562d2c2aeb8689dcddb32f7d090060d1158e5ff1 100644 (file)
@@ -9,24 +9,48 @@
 #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
@@ -34,6 +58,26 @@ main(int argc, char * argv[])
                 "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
             }
@@ -51,94 +95,216 @@ main(int argc, char * argv[])
         }
     }
 
-    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);
 }
+