Merge branch 'master' of ctdb into 'master' of samba
[samba.git] / examples / libsmbclient / testbrowse.c
1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <dirent.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <popt.h>
8 #include <stdlib.h>
9 #include <libsmbclient.h>
10 #include "get_auth_data_fn.h"
11
12 static void browse(char * path,
13                    int scan,
14                    int indent);
15
16
17 static void
18 get_auth_data_with_context_fn(SMBCCTX * context,
19                               const char * pServer,
20                               const char * pShare,
21                               char * pWorkgroup,
22                               int maxLenWorkgroup,
23                               char * pUsername,
24                               int maxLenUsername,
25                               char * pPassword,
26                               int maxLenPassword);
27
28 int
29 main(int argc, char * argv[])
30 {
31     int                         debug = 0;
32     int                         debug_stderr = 0;
33     int                         no_auth = 0;
34     int                         context_auth = 0;
35     int                         scan = 0;
36     int                         iterations = -1;
37     int                         opt;
38     char *                      p;
39     char                        buf[1024];
40     poptContext                 pc;
41     SMBCCTX *                   context;
42     struct poptOption           long_options[] =
43         {
44             POPT_AUTOHELP
45             {
46                 "debug", 'd', POPT_ARG_INT, &debug,
47                 0, "Set debug level", "integer"
48             },
49             {
50                 "stderr", 'e', POPT_ARG_NONE, &debug_stderr,
51                 0, "Debug log to stderr instead of stdout", "integer"
52             },
53             {
54                 "scan", 's', POPT_ARG_NONE, &scan,
55                 0, "Scan for servers and shares", "integer"
56             },
57             {
58                 "iterations", 'i', POPT_ARG_INT, &iterations,
59                 0, "Iterations", "integer"
60             },
61             {
62                 "noauth", 'A', POPT_ARG_NONE, &no_auth,
63                 0, "Do not request authentication data", "integer"
64             },
65             {
66                 "contextauth", 'C', POPT_ARG_NONE, &context_auth,
67                 0, "Use new authentication function with context", "integer"
68             },
69             {
70                 NULL
71             }
72         };
73     
74     setbuf(stdout, NULL);
75
76     pc = poptGetContext("opendir", argc, (const char **)argv, long_options, 0);
77     
78     poptSetOtherOptionHelp(pc, "");
79     
80     while ((opt = poptGetNextOpt(pc)) != -1) {
81         printf("Got option %d = %c\n", opt, opt);
82         switch (opt) {
83         }
84     }
85
86     /* Allocate a new context */
87     context = smbc_new_context();
88     if (!context) {
89         printf("Could not allocate new smbc context\n");
90         return 1;
91     }
92         
93     /* If we're scanning, do no requests for authentication data */
94     if (scan) {
95         no_auth = 1;
96     }
97
98     /* Set mandatory options (is that a contradiction in terms?) */
99     smbc_setDebug(context, debug);
100     if (context_auth) {
101         smbc_setFunctionAuthDataWithContext(context,
102                                             get_auth_data_with_context_fn);
103         smbc_setOptionUserData(context, (void *)"hello world");
104     } else {
105         smbc_setFunctionAuthData(context, get_auth_data_fn);
106     }
107
108     smbc_setOptionUseKerberos(context, 1);
109     smbc_setOptionFallbackAfterKerberos(context, 1);
110
111     /* If we've been asked to log to stderr instead of stdout, ... */
112     if (debug_stderr) {
113         /* ... then set the option to do so */
114         smbc_setOptionDebugToStderr(context, 1);
115     }
116
117     /* Initialize the context using the previously specified options */
118     if (!smbc_init_context(context)) {
119         smbc_free_context(context, 0);
120         printf("Could not initialize smbc context\n");
121         return 1;
122     }
123
124     /* Tell the compatibility layer to use this context */
125     smbc_set_context(context);
126
127     if (scan)
128     {
129         for (;
130              iterations == -1 || iterations > 0;
131              iterations = (iterations == -1 ? iterations : --iterations))
132         {
133             snprintf(buf, sizeof(buf), "smb://");
134             browse(buf, scan, 0);
135         }
136     }
137     else
138     {
139         for (;
140              iterations == -1 || iterations > 0;
141              iterations = (iterations == -1 ? iterations : --iterations))
142         {
143             fputs("url: ", stdout);
144             p = fgets(buf, sizeof(buf), stdin);
145             if (! p)
146             {
147                 break;
148             }
149
150             if ((p = strchr(buf, '\n')) != NULL)
151             {
152                 *p = '\0';
153             }
154             
155             browse(buf, scan, 0);
156         }
157     }
158
159     exit(0);
160 }
161
162 static void
163 get_auth_data_with_context_fn(SMBCCTX * context,
164                               const char * pServer,
165                               const char * pShare,
166                               char * pWorkgroup,
167                               int maxLenWorkgroup,
168                               char * pUsername,
169                               int maxLenUsername,
170                               char * pPassword,
171                               int maxLenPassword)
172 {
173     printf("Authenticating with context %p", context);
174     if (context != NULL) {
175         char *user_data = smbc_getOptionUserData(context);
176         printf(" with user data %s", user_data);
177     }
178     printf("\n");
179
180     get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup,
181                      pUsername, maxLenUsername, pPassword, maxLenPassword);
182 }
183
184 static void browse(char * path, int scan, int indent)
185 {
186     char *                      p;
187     char                        buf[1024];
188     int                         dir;
189     struct stat                 st;
190     struct smbc_dirent *        dirent;
191
192     if (! scan)
193     {
194         printf("Opening (%s)...\n", path);
195     }
196         
197     if ((dir = smbc_opendir(path)) < 0)
198     {
199         printf("Could not open directory [%s] (%d:%s)\n",
200                path, errno, strerror(errno));
201         return;
202     }
203
204     while ((dirent = smbc_readdir(dir)) != NULL)
205     {
206         printf("%*.*s%-30s", indent, indent, "", dirent->name);
207
208         switch(dirent->smbc_type)
209         {
210         case SMBC_WORKGROUP:
211             printf("WORKGROUP");
212             break;
213             
214         case SMBC_SERVER:
215             printf("SERVER");
216             break;
217             
218         case SMBC_FILE_SHARE:
219             printf("FILE_SHARE");
220             break;
221             
222         case SMBC_PRINTER_SHARE:
223             printf("PRINTER_SHARE");
224             break;
225             
226         case SMBC_COMMS_SHARE:
227             printf("COMMS_SHARE");
228             break;
229             
230         case SMBC_IPC_SHARE:
231             printf("IPC_SHARE");
232             break;
233             
234         case SMBC_DIR:
235             printf("DIR");
236             break;
237             
238         case SMBC_FILE:
239             printf("FILE");
240
241             p = path + strlen(path);
242             strcat(p, "/");
243             strcat(p+1, dirent->name);
244             if (smbc_stat(path, &st) < 0)
245             {
246                 printf(" unknown size (reason %d: %s)",
247                        errno, strerror(errno));
248             }
249             else
250             {
251                 printf(" size %lu", (unsigned long) st.st_size);
252             }
253             *p = '\0';
254
255             break;
256             
257         case SMBC_LINK:
258             printf("LINK");
259             break;
260         }
261
262         printf("\n");
263
264         if (scan &&
265             (dirent->smbc_type == SMBC_WORKGROUP ||
266              dirent->smbc_type == SMBC_SERVER))
267         {
268             /*
269              * don't append server name to workgroup; what we want is:
270              *
271              *   smb://workgroup_name
272              * or
273              *   smb://server_name
274              *
275              */
276             snprintf(buf, sizeof(buf), "smb://%s", dirent->name);
277             browse(buf, scan, indent + 2);
278         }
279     }
280
281     smbc_closedir(dir);
282 }
283