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