Cleaned up some of the parsing code: o Boolean got_xxx rather than GString * ==… | |
git clone git://git.codemadness.org/susmb | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit db77d112648c00a8456b39c1a5faa0ac061d14f7 | |
parent abe38e627824e686da4c8aa101a1ac750ba9e2be | |
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(-) | |
--- | |
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) ; \ | |
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 *s… | |
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); | |
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); | |
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. | |
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 … | |
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 xmlCh… | |
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 xmlC… | |
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 xmlC… | |
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 xmlCh… | |
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 xmlCh… | |
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 xml… | |
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; | |
} | |
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, struc… | |
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) |