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