From e3763f1a9a25cf20b28b3cd44943d77a8f789280 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Dec 2009 16:54:04 +1100 Subject: [PATCH] Add support to log in to the SMB server/share and for the MKDIR and RMDIR operations Add initial example loadfile for these two operations --- Makefile.in | 2 +- loadfiles/smb.txt | 14 +++++ smb.c | 131 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 loadfiles/smb.txt diff --git a/Makefile.in b/Makefile.in index c852dbf..64cf675 100644 --- a/Makefile.in +++ b/Makefile.in @@ -10,7 +10,7 @@ mandir=@mandir@ datadir=@datadir@ XSLTPROC = /usr/bin/xsltproc INSTALLCMD=@INSTALL@ -LIBS=@LIBS@ -lpopt -lz +LIBS=@LIBS@ -lpopt -lz -lsmbclient CC=@CC@ CFLAGS=@CFLAGS@ -I. -DVERSION=\"$(VERSION)\" -DDATADIR=\"$(datadir)\" diff --git a/loadfiles/smb.txt b/loadfiles/smb.txt new file mode 100644 index 0000000..fa5b540 --- /dev/null +++ b/loadfiles/smb.txt @@ -0,0 +1,14 @@ +# example laodfile for SMB +# We do not distinguish between different status codes here so we basically +# treat the status code as a binary. It is either NT_STATUS_OK +# which means we expect the operation to succeed, or it is something +# else which means we expect it to fail. +# +# Filenames in SMB MUST start with '\' or '/' +# +# +# MKDIR +Mkdir "\foo" NT_STATUS_OK +# +# RMDIR +Rmdir "\foo" NT_STATUS_OK diff --git a/smb.c b/smb.c index ee92ac5..b7f882a 100644 --- a/smb.c +++ b/smb.c @@ -22,12 +22,38 @@ #include #include #include +#include #include "dbench.h" #define discard_const(ptr) ((void *)((intptr_t)(ptr))) +static char *smb_domain; +static char *smb_user; +static char *smb_password; + +struct smb_child { + SMBCCTX *ctx; +}; + +void smb_auth_fn(const char *server, const char *share, char *wrkgrp, int wrkgrplen, char *user, int userlen, char *passwd, int passwdlen) +{ + (void)server; + (void)share; + + if (smb_domain != NULL) { + strncpy(wrkgrp, smb_domain, wrkgrplen - 1); wrkgrp[wrkgrplen - 1] = 0; + } + strncpy(user, smb_user, userlen - 1); user[userlen - 1] = 0; + strncpy(passwd, smb_password, passwdlen - 1); passwd[passwdlen - 1] = 0; +} + static int smb_init(void) { + SMBCCTX *ctx; + char *tmp; + int ret; + char *str; + if (options.smb_server == NULL) { printf("You must specify --smb-server= with the \"smb\" backend.\n"); return 1; @@ -37,28 +63,123 @@ static int smb_init(void) return 1; } if (options.smb_user == NULL) { - printf("You must specify --smb-user=[/]% with the \"smb\" backend.\n"); + printf("You must specify --smb-user=[/]%% with the \"smb\" backend.\n"); + return 1; + } + + smb_domain = strdup(options.smb_user); + tmp = index(smb_domain, '/'); + if (tmp == NULL) { + smb_user = smb_domain; + smb_domain = NULL; + } else { + smb_user = tmp+1; + *tmp = '\0'; + } + tmp = index(smb_user, '%'); + if (tmp == NULL) { + smb_password = NULL; + } else { + smb_password = tmp+1; + *tmp = '\0'; + } + + ctx = smbc_new_context(); + if (ctx == NULL) { + printf("Could not allocate SMB Context\n"); return 1; } - printf("smb_init\n"); + smbc_setDebug(ctx, 0); + smbc_setFunctionAuthData(ctx, smb_auth_fn); + if (!smbc_init_context(ctx)) { + smbc_free_context(ctx, 0); + printf("failed to initialize context\n"); + return 1; + } + smbc_set_context(ctx); + + asprintf(&str, "smb://%s/%s", options.smb_server, options.smb_share); + ret = smbc_opendir(str); + free(str); + + if (ret == -1) { + printf("Failed to access //%s/%s\n", options.smb_server, options.smb_share); + return 1; + } - return 1; + smbc_free_context(ctx, 1); + return 0; } static void smb_setup(struct child_struct *child) { - printf("smb_setup\n"); + struct smb_child *ctx; + + ctx = malloc(sizeof(struct smb_child)); + if (ctx == NULL) { + printf("Failed to malloc child ctx\n"); + exit(10); + } + child->private =ctx; + + ctx->ctx = smbc_new_context(); + if (ctx->ctx == NULL) { + printf("Could not allocate SMB Context\n"); + exit(10); + } + + smbc_setDebug(ctx->ctx, 0); + smbc_setFunctionAuthData(ctx->ctx, smb_auth_fn); + + if (!smbc_init_context(ctx->ctx)) { + smbc_free_context(ctx->ctx, 0); + printf("failed to initialize context\n"); + exit(10); + } + smbc_set_context(ctx->ctx); } static void smb_cleanup(struct child_struct *child) { - printf("smb_cleanup\n"); + struct smb_child *ctx = child->private; + + smbc_free_context(ctx->ctx, 1); + free(ctx); +} + +static void smb_mkdir(struct dbench_op *op) +{ + char *str; + const char *dir; + int ret; + + dir = op->fname + 2; + + asprintf(&str, "smb://%s/%s/%s", options.smb_server, options.smb_share, dir); + + ret = smbc_mkdir(str, 0777); + + free(str); } +static void smb_rmdir(struct dbench_op *op) +{ + char *str; + const char *dir; + int ret; + + dir = op->fname + 2; + asprintf(&str, "smb://%s/%s/%s", options.smb_server, options.smb_share, dir); + ret = smbc_rmdir(str); + + free(str); +} static struct backend_op ops[] = { + { "Mkdir", smb_mkdir }, + { "Rmdir", smb_rmdir }, { NULL, NULL} }; -- 2.34.1