1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00
samba-mirror/examples/libsmbclient/testbrowse.c
Jeremy Allison 019f643c69 Fix a boatload of warnings in the examples.
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Thu Oct 20 02:29:52 CEST 2011 on sn-devel-104
2011-10-20 02:29:52 +02:00

284 lines
7.8 KiB
C

#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <popt.h>
#include <stdlib.h>
#include <libsmbclient.h>
#include "get_auth_data_fn.h"
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 opt;
char * p;
char buf[1024];
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
}
};
setbuf(stdout, NULL);
pc = poptGetContext("opendir", argc, (const char **)argv, long_options, 0);
poptSetOtherOptionHelp(pc, "");
while ((opt = poptGetNextOpt(pc)) != -1) {
printf("Got option %d = %c\n", opt, opt);
switch (opt) {
}
}
/* Allocate a new context */
context = smbc_new_context();
if (!context) {
printf("Could not allocate new smbc context\n");
return 1;
}
/* If we're scanning, do no requests for authentication data */
if (scan) {
no_auth = 1;
}
/* Set mandatory options (is that a contradiction in terms?) */
smbc_setDebug(context, debug);
if (context_auth) {
smbc_setFunctionAuthDataWithContext(context,
get_auth_data_with_context_fn);
smbc_setOptionUserData(context, (void *)"hello world");
} else {
smbc_setFunctionAuthData(context, get_auth_data_fn);
}
smbc_setOptionUseKerberos(context, 1);
smbc_setOptionFallbackAfterKerberos(context, 1);
/* If we've been asked to log to stderr instead of stdout, ... */
if (debug_stderr) {
/* ... then set the option to do so */
smbc_setOptionDebugToStderr(context, 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)
{
for (;
iterations == -1 || iterations > 0;
iterations = (iterations == -1 ? iterations : --iterations))
{
snprintf(buf, sizeof(buf), "smb://");
browse(buf, scan, 0);
}
}
else
{
for (;
iterations == -1 || iterations > 0;
iterations = (iterations == -1 ? iterations : --iterations))
{
fputs("url: ", stdout);
p = fgets(buf, sizeof(buf), stdin);
if (! p)
{
break;
}
if ((p = strchr(buf, '\n')) != NULL)
{
*p = '\0';
}
browse(buf, scan, 0);
}
}
exit(0);
}
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 %p", context);
if (context != NULL) {
char *user_data = smbc_getOptionUserData(context);
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 st;
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_FILE_SHARE:
printf("FILE_SHARE");
break;
case SMBC_PRINTER_SHARE:
printf("PRINTER_SHARE");
break;
case SMBC_COMMS_SHARE:
printf("COMMS_SHARE");
break;
case SMBC_IPC_SHARE:
printf("IPC_SHARE");
break;
case SMBC_DIR:
printf("DIR");
break;
case SMBC_FILE:
printf("FILE");
p = path + strlen(path);
strcat(p, "/");
strcat(p+1, dirent->name);
if (smbc_stat(path, &st) < 0)
{
printf(" unknown size (reason %d: %s)",
errno, strerror(errno));
}
else
{
printf(" size %lu", (unsigned long) st.st_size);
}
*p = '\0';
break;
case SMBC_LINK:
printf("LINK");
break;
}
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);
}
}
smbc_closedir(dir);
}