Cleaned up some of the parsing code: o Boolean got_xxx rather than GString * == NULL, which smacks of in-band signalling. o Tidier checking of duplicate / missing IDs; checking now occurs in the start element. o struct mount includes a struct credentials * rather than the ID of the credentials entry. - susmb - mounting of SMB/CIFS shares via FUSE
(HTM) git clone git://git.codemadness.org/susmb
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit db77d112648c00a8456b39c1a5faa0ac061d14f7
(DIR) parent abe38e627824e686da4c8aa101a1ac750ba9e2be
(HTM) Author: geoff <devnull@localhost>
Date: Tue, 9 May 2006 23:31:22 +0000
Cleaned up some of the parsing code:
o Boolean got_xxx rather than GString * == NULL, which smacks of in-band
signalling.
o Tidier checking of duplicate / missing IDs; checking now occurs in the
start element.
o struct mount includes a struct credentials * rather than the ID of the
credentials entry.
Removed .mt-attrs from the tarballs.
Diffstat:
M Makefile | 2 +-
M conffile.c | 9 +++++----
M conffile.h | 5 +++--
M doc/README | 2 +-
M sax.c | 222 +++++++++++++++----------------
M usmb.c | 13 ++++++-------
6 files changed, 123 insertions(+), 130 deletions(-)
---
(DIR) diff --git a/Makefile b/Makefile
@@ -78,7 +78,7 @@ tar: STAGING=/tmp/usmb-$(VERSION)
tar:
mkdir $(STAGING)
cp -a $(PWD)/* $(STAGING)/
- rm -rf $(STAGING)/MT
+ rm -rf $(STAGING)/MT $(STAGING)/.mt-attrs
(cd $(STAGING)/..; \
make -C $(STAGING) distclean ; \
tar jcf $(PWD)/usmb-$(VERSION).tar.bz2 usmb-$(VERSION) ; \
(DIR) diff --git a/conffile.c b/conffile.c
@@ -69,11 +69,14 @@ void credentials_destroy (struct credentials *creds)
struct mount * mount_new (const char *server, const char *share,
- const char *mountpoint, const char *credentials,
+ const char *mountpoint,
+ const struct credentials *credentials,
const char *options)
{
struct mount *mount = malloc (sizeof (struct mount));
+ assert (NULL != credentials);
+
if (NULL == mount)
return NULL;
@@ -81,12 +84,11 @@ struct mount * mount_new (const char *server, const char *share,
mount->share = xstrdup (share);
mount->mountpoint = xstrdup (mountpoint);
mount->options = xstrdup (options);
- mount->credentials = xstrdup (credentials);
+ mount->credentials = credentials;
if ((NULL == mount->server) ||
(NULL == mount->share) ||
(NULL == mount->mountpoint) ||
- (NULL == mount->credentials) ||
(NULL == mount->options))
{
mount_destroy (mount);
@@ -101,7 +103,6 @@ void mount_destroy (struct mount *mount)
{
assert (NULL != mount);
- xfree (mount->credentials);
xfree (mount->options);
xfree (mount->mountpoint);
xfree (mount->share);
(DIR) diff --git a/conffile.h b/conffile.h
@@ -32,7 +32,7 @@
char *server;
char *share;
char *mountpoint;
- char *credentials;
+ const struct credentials *credentials;
char *options;
};
@@ -47,7 +47,8 @@
void credentials_destroy (struct credentials *creds);
struct mount * mount_new (const char *server, const char *share,
- const char *mountpoint, const char *credentials,
+ const char *mountpoint,
+ const struct credentials *credentials,
const char *options);
void mount_destroy (struct mount *mount);
(DIR) diff --git a/doc/README b/doc/README
@@ -35,7 +35,7 @@ Configuration
-------------
You need an XML configuration file - ${HOME}/.usmb.conf by default. There's an
-example doc/usmb.conf.
+example in doc/usmb.conf.
There are two main elements: credentials and mounts.
(DIR) diff --git a/sax.c b/sax.c
@@ -19,6 +19,7 @@
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <libxml/xmlreader.h>
@@ -113,13 +114,25 @@ struct sax_parser {
union {
struct {
char *id;
+
+ bool got_domain;
+ bool got_username;
+ bool got_password;
+
GString *domain;
GString *username;
GString *password;
} credentials;
+
struct {
char *id;
- char *creds;
+ struct credentials *creds;
+
+ bool got_server;
+ bool got_share;
+ bool got_mountpoint;
+ bool got_options;
+
GString *server;
GString *share;
GString *mountpoint;
@@ -135,13 +148,13 @@ static enum element get_element (const char *elt)
{
const char *elts[] = {
[ ELT_USMBCFG ] = "usmbconfig",
- [ ELT_CREDS ] = "credentials",
- [ ELT_DOMAIN ] = "domain",
- [ ELT_USER ] = "username",
- [ ELT_PASS ] = "password",
- [ ELT_MOUNT ] = "mount",
- [ ELT_SERVER ] = "server",
- [ ELT_SHARE ] = "share",
+ [ ELT_CREDS ] = "credentials",
+ [ ELT_DOMAIN ] = "domain",
+ [ ELT_USER ] = "username",
+ [ ELT_PASS ] = "password",
+ [ ELT_MOUNT ] = "mount",
+ [ ELT_SERVER ] = "server",
+ [ ELT_SHARE ] = "share",
[ ELT_MOUNTPT ] = "mountpoint",
[ ELT_OPTIONS ] = "options"
};
@@ -159,19 +172,6 @@ static void start_document (void *ctx)
struct sax_parser *sp = ctx;
assert (sp->state == START);
sp->state = INITIAL;
-
- // these four aren't strictly necessary as we're using a union
- sp->strs.credentials.id = NULL;
- sp->strs.credentials.domain = NULL;
- sp->strs.credentials.username = NULL;
- sp->strs.credentials.password = NULL;
-
- sp->strs.mount.id = NULL;
- sp->strs.mount.creds = NULL;
- sp->strs.mount.server = NULL;
- sp->strs.mount.share = NULL;
- sp->strs.mount.mountpoint = NULL;
- sp->strs.mount.options = NULL;
}
@@ -209,18 +209,24 @@ static void error (void *ctx, const char *msg, ...)
}
-static bool set_string (char **out, const char *in, const char *dup_err)
+typedef void * (* cf_get_fn) (struct conffile *, const char *);
+static bool handle_id (char **out, const char *in, cf_get_fn func,
+ struct conffile *cf)
{
assert (NULL != out);
assert (NULL != in);
if (NULL != *out)
{
- if (NULL != dup_err)
- {
- fputs (dup_err, stderr);
- return false;
- }
+ fprintf (stderr,
+ "Multiple ID attributes in <mount> or <credentials>: %s\n", in);
+ return false;
+ }
+
+ if (NULL != func (cf, in))
+ {
+ fprintf (stderr, "Duplicate ID: %s\n", in);
+ return false;
}
*out = xstrdup (in);
@@ -237,10 +243,8 @@ static bool set_string (char **out, const char *in, const char *dup_err)
static void start_mount (struct sax_parser *sp, const xmlChar **attrs)
{
- assert (NULL == sp->strs.mount.server);
- assert (NULL == sp->strs.mount.share);
- assert (NULL == sp->strs.mount.mountpoint);
- assert (NULL == sp->strs.mount.options);
+ sp->strs.mount.id = NULL;
+ sp->strs.mount.creds = NULL;
// must have id and credentials attributes
for (int i = 0; NULL != attrs[i]; i += 2)
@@ -249,8 +253,8 @@ static void start_mount (struct sax_parser *sp, const xmlChar **attrs)
if (!strcmp (attrs[i], "id"))
{
- if (!set_string (&sp->strs.mount.id, (const char *)attrs[i+1],
- "Duplicate id attribute in <mount>\n"))
+ if (!handle_id (&sp->strs.mount.id, (const char *)attrs[i+1],
+ (cf_get_fn)conffile_get_mount, sp->cf))
{
sp->state = ERROR;
return;
@@ -259,9 +263,19 @@ static void start_mount (struct sax_parser *sp, const xmlChar **attrs)
else if (!strcmp (attrs[i], "credentials"))
{
- if (!set_string (&sp->strs.mount.creds, (const char *)attrs[i+1],
- "Duplicate credentials attribute in <mount>\n"))
+ if (NULL != sp->strs.mount.creds)
{
+ fputs ("Duplicate credentials attribute in <mount>\n", stderr);
+ sp->state = ERROR;
+ return;
+ }
+
+ sp->strs.mount.creds =
+ conffile_get_credentials (sp->cf, (const char *)attrs[i+1]);
+
+ if (NULL == sp->strs.mount.creds)
+ {
+ fprintf (stderr, "Credentials %s not found for <mount>\n", attrs[i+1]);
sp->state = ERROR;
return;
}
@@ -283,6 +297,16 @@ static void start_mount (struct sax_parser *sp, const xmlChar **attrs)
return;
}
+ sp->strs.mount.server = g_string_new (NULL);
+ sp->strs.mount.share = g_string_new (NULL);
+ sp->strs.mount.mountpoint = g_string_new (NULL);
+ sp->strs.mount.options = g_string_new (NULL);
+
+ sp->strs.mount.got_server = false;
+ sp->strs.mount.got_share = false;
+ sp->strs.mount.got_mountpoint = false;
+ sp->strs.mount.got_options = false;
+
sp->state = MOUNT;
}
@@ -293,6 +317,8 @@ static void start_creds (struct sax_parser *sp, const xmlChar **attrs)
assert (NULL == sp->strs.credentials.username);
assert (NULL == sp->strs.credentials.password);
+ sp->strs.credentials.id = NULL;
+
// must have an id attribute
for (int i = 0; NULL != attrs[i]; i += 2)
{
@@ -300,8 +326,8 @@ static void start_creds (struct sax_parser *sp, const xmlChar **attrs)
if (!strcmp (attrs[i], "id"))
{
- if (!set_string (&sp->strs.credentials.id, (const char *)attrs[i+1],
- "Duplicate id attribute in <credentials>\n"))
+ if (!handle_id (&sp->strs.credentials.id, (const char *)attrs[i+1],
+ (cf_get_fn)conffile_get_credentials, sp->cf))
{
sp->state = ERROR;
return;
@@ -323,15 +349,26 @@ static void start_creds (struct sax_parser *sp, const xmlChar **attrs)
return;
}
+ sp->strs.credentials.domain = g_string_new (NULL);
+ sp->strs.credentials.username = g_string_new (NULL);
+ sp->strs.credentials.password = g_string_new (NULL);
+
+ sp->strs.credentials.got_domain = false;
+ sp->strs.credentials.got_username = false;
+ sp->strs.credentials.got_password = false;
+
sp->state = CREDS;
}
static void start_char_state (struct sax_parser *sp,
- GString **target,
+ GString *target,
+ bool *got,
const char *name,
const xmlChar **attrs)
{
+ assert (NULL != target);
+
if (ERROR == sp->state)
return;
@@ -342,62 +379,63 @@ static void start_char_state (struct sax_parser *sp,
return;
}
- if (NULL != *target)
+ if (false != *got)
{
fprintf (stderr, "Duplicate <%s>\n", name);
sp->state = ERROR;
return;
}
- *target = g_string_new (NULL);
- if (NULL == *target)
- {
- fputs ("Out of memory\n", stderr);
- sp->state = ERROR;
- return;
- }
+ *got = true;
}
static void start_server (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.mount.server, "server", attrs);
+ start_char_state (sp, sp->strs.mount.server, &sp->strs.mount.got_server,
+ "server", attrs);
}
static void start_share (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.mount.share, "share", attrs);
+ start_char_state (sp, sp->strs.mount.share, &sp->strs.mount.got_share,
+ "share", attrs);
}
static void start_mtpt (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.mount.mountpoint, "mountpoint", attrs);
+ start_char_state (sp, sp->strs.mount.mountpoint,
+ &sp->strs.mount.got_mountpoint, "mountpoint", attrs);
}
static void start_options (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.mount.options, "options", attrs);
+ start_char_state (sp, sp->strs.mount.options, &sp->strs.mount.got_options,
+ "options", attrs);
}
static void start_domain (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.credentials.domain, "domain", attrs);
+ start_char_state (sp, sp->strs.credentials.domain,
+ &sp->strs.credentials.got_domain, "domain", attrs);
}
static void start_username (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.credentials.username, "username", attrs);
+ start_char_state (sp, sp->strs.credentials.username,
+ &sp->strs.credentials.got_username, "username", attrs);
}
static void start_password (struct sax_parser *sp, const xmlChar **attrs)
{
- start_char_state (sp, &sp->strs.credentials.password, "password", attrs);
+ start_char_state (sp, sp->strs.credentials.password,
+ &sp->strs.credentials.got_password, "password", attrs);
}
@@ -455,32 +493,19 @@ static void end_mount (struct sax_parser *sp)
assert (NULL != sp->strs.mount.id);
assert (NULL != sp->strs.mount.creds);
- if (NULL == conffile_get_credentials (sp->cf, sp->strs.mount.creds))
- {
- fprintf (stderr, "Mount %s: credentials %s not found\n",
- sp->strs.mount.id, sp->strs.mount.creds);
- sp->state = ERROR;
- }
-
- else if (NULL != conffile_get_mount (sp->cf, sp->strs.mount.id))
- {
- fprintf (stderr, "Duplicate mount ID: %s\n", sp->strs.mount.id);
- sp->state = ERROR;
- }
-
- else if ((NULL == sp->strs.mount.server) || (0 == sp->strs.mount.server->len))
+ if (!sp->strs.mount.got_server || (0 == sp->strs.mount.server->len))
{
fprintf (stderr, "Mount %s: no server given\n", sp->strs.mount.id);
sp->state = ERROR;
}
- else if ((NULL == sp->strs.mount.share) || (0 == sp->strs.mount.share->len))
+ else if (!sp->strs.mount.got_share || (0 == sp->strs.mount.share->len))
{
fprintf (stderr, "Mount %s: no share given\n", sp->strs.mount.id);
sp->state = ERROR;
}
- else if ((NULL == sp->strs.mount.mountpoint) ||
+ else if (!sp->strs.mount.got_mountpoint ||
(0 == sp->strs.mount.mountpoint->len))
{
fprintf (stderr, "Mount %s: no mount point given\n", sp->strs.mount.id);
@@ -490,43 +515,25 @@ static void end_mount (struct sax_parser *sp)
else
{
struct mount *mount =
- mount_new (sp->strs.mount.server ? sp->strs.mount.server->str : "",
- sp->strs.mount.share ? sp->strs.mount.share->str : "",
- sp->strs.mount.mountpoint ?
- sp->strs.mount.mountpoint->str : "",
+ mount_new (sp->strs.mount.server->str,
+ sp->strs.mount.share->str,
+ sp->strs.mount.mountpoint->str,
sp->strs.mount.creds,
- sp->strs.mount.options ?
- sp->strs.mount.options->str : "");
+ sp->strs.mount.options->str);
if ((NULL == mount) ||
!conffile_add_mount (sp->cf, sp->strs.mount.id, mount))
sp->state = ERROR;
}
- if (sp->strs.mount.server)
- g_string_free (sp->strs.mount.server, TRUE);
-
- if (sp->strs.mount.share)
- g_string_free (sp->strs.mount.share, TRUE);
-
- if (sp->strs.mount.mountpoint)
- g_string_free (sp->strs.mount.mountpoint, TRUE);
-
- if (sp->strs.mount.options)
- g_string_free (sp->strs.mount.options, TRUE);
-
- sp->strs.mount.server = NULL;
- sp->strs.mount.share = NULL;
- sp->strs.mount.mountpoint = NULL;
- sp->strs.mount.options = NULL;
+ g_string_free (sp->strs.mount.server, TRUE);
+ g_string_free (sp->strs.mount.share, TRUE);
+ g_string_free (sp->strs.mount.mountpoint, TRUE);
+ g_string_free (sp->strs.mount.options, TRUE);
+ // we need the mount ID (for the hashtable key) if parsing succeeded
if (ERROR == sp->state)
xfree (sp->strs.mount.id);
-
- xfree (sp->strs.mount.creds);
-
- sp->strs.mount.id = NULL;
- sp->strs.mount.creds = NULL;
}
@@ -535,13 +542,7 @@ static void end_creds (struct sax_parser *sp)
// must have username; domain and password are optional
assert (NULL != sp->strs.credentials.id);
- if (NULL != conffile_get_credentials (sp->cf, sp->strs.credentials.id))
- {
- fprintf (stderr, "Duplicate credentials ID: %s\n", sp->strs.credentials.id);
- sp->state = ERROR;
- }
-
- else if ((NULL == sp->strs.credentials.username) ||
+ if (!sp->strs.credentials.got_username ||
(0 == sp->strs.credentials.username->len))
{
fprintf (stderr, "Credentials %s: no username given\n",
@@ -552,12 +553,9 @@ static void end_creds (struct sax_parser *sp)
else
{
struct credentials *creds =
- credentials_new (sp->strs.credentials.domain ?
- sp->strs.credentials.domain->str : "",
- sp->strs.credentials.username ?
- sp->strs.credentials.username->str : "",
- sp->strs.credentials.password ?
- sp->strs.credentials.password->str : "");
+ credentials_new (sp->strs.credentials.domain->str,
+ sp->strs.credentials.username->str,
+ sp->strs.credentials.password->str);
if ((NULL == creds) ||
!conffile_add_credentials (sp->cf, sp->strs.credentials.id, creds))
@@ -568,14 +566,8 @@ static void end_creds (struct sax_parser *sp)
g_string_free (sp->strs.credentials.username, TRUE);
g_string_free (sp->strs.credentials.password, TRUE);
- sp->strs.credentials.domain = NULL;
- sp->strs.credentials.username = NULL;
- sp->strs.credentials.password = NULL;
-
if (ERROR == sp->state)
xfree (sp->strs.credentials.id);
-
- sp->strs.credentials.id = NULL;
}
(DIR) diff --git a/usmb.c b/usmb.c
@@ -178,10 +178,9 @@ static bool check_conf_perms (const char *conffile)
}
-static bool fix_up_conf_details (struct conffile *cf, struct mount *mount)
+static bool fix_up_conf_details (struct mount *mount)
{
- struct credentials *creds = conffile_get_credentials (cf, mount->credentials);
- assert (NULL != creds);
+ assert (NULL != mount->credentials);
size_t len = strlen ("smb:///") +
strlen (mount->server) +
@@ -198,9 +197,9 @@ static bool fix_up_conf_details (struct conffile *cf, struct mount *mount)
strcat (str, "/");
strcat (str, mount->share);
- domain = xstrdup (creds->domain);
- username = xstrdup (creds->username);
- password = xstrdup (creds->password);
+ domain = xstrdup (mount->credentials->domain);
+ username = xstrdup (mount->credentials->username);
+ password = xstrdup (mount->credentials->password);
if ((NULL == domain) ||
(NULL == username) ||
@@ -264,7 +263,7 @@ int main (int argc, char **argv)
}
{
- bool ret = fix_up_conf_details (cf, mount);
+ bool ret = fix_up_conf_details (mount);
conffile_destroy (cf);
if (false == ret)