aboutsummaryrefslogtreecommitdiff
path: root/dico
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-01-10 20:46:24 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2012-01-10 22:12:04 +0200
commit0b4a6a095e1384ff16c786a17b66bcc392a0d57b (patch)
tree4a0caf29bc70b39c3b59ee550596e0a9032993fc /dico
parent2fcdaba8d0358036e8d70b25eba5f1fa30975db1 (diff)
downloaddico-0b4a6a095e1384ff16c786a17b66bcc392a0d57b.tar.gz
dico-0b4a6a095e1384ff16c786a17b66bcc392a0d57b.tar.bz2
Use wordsplit instead of dico_argcv.
* dico/autologin.c (parse_autologin): Rewrite using wordsplit. * dico/dico-priv.h: Include wordsplit.h * dicod/dicod.h: Likewise. * dico/saslauth.c (get_implemented_mechs): Use wordsplit. * dico/shell.c (_command_completion): Likewise. * dicod/gsasl.c (register_sasl): Likewise. * dicod/loader.c (dicod_load_module): Likewise. * dicod/main.c (set_dict_handler): Likewise. * modules/guile/guile.c (guile_load): Likewise. * modules/ldap/ldap.c (db_open): Likewise. * modules/guile/Makefile.am (INCLUDES): Add @GRECS_INCLUDES@ * modules/ldap/Makefile.am: Likewise. * modules/outline/Makefile.am: Likewise. * modules/outline/outline.c (outline_lang): Likewise.
Diffstat (limited to 'dico')
-rw-r--r--dico/autologin.c183
-rw-r--r--dico/dico-priv.h1
-rw-r--r--dico/saslauth.c12
-rw-r--r--dico/shell.c20
4 files changed, 117 insertions, 99 deletions
diff --git a/dico/autologin.c b/dico/autologin.c
index 8c995ba..c3030de 100644
--- a/dico/autologin.c
+++ b/dico/autologin.c
@@ -75,15 +75,13 @@ hostcmp(const char *a, const char *b)
return 1;
}
-static void
-argv_expand(int *pargc, char ***pargv, int xargc, char **xargv)
+static int
+begins_with(const char *str, const char *prefix)
{
- size_t nargc = *pargc + xargc + 1;
- char **nargv = xrealloc(*pargv, (nargc + 1) * sizeof nargv[0]);
- nargv[*pargc] = xstrdup("\n");
- memcpy(nargv + 1 + *pargc, xargv, (xargc + 1) * sizeof nargv[0]);
- *pargc = nargc;
- *pargv = nargv;
+ size_t len = strlen (prefix);
+
+ return strlen (str) >= len && strncmp (str, prefix, len) == 0
+ && (str[len] == 0 || str[len] == ' ' || str[len] == '\t');
}
enum kw_tok {
@@ -134,6 +132,44 @@ _cred_free(void *item, void *data)
return 0;
}
+struct matches {
+ const char *host;
+ int def_line;
+ int def_argc;
+ char **def_argv;
+ int host_argc;
+ char **host_argv;
+};
+
+static int
+match_line(struct wordsplit *ws, struct matches *matches, int line)
+{
+ int rc = 0;
+
+ if (strcmp(ws->ws_wordv[0], "machine") == 0) {
+ if (hostcmp(ws->ws_wordv[1], matches->host) == 0) {
+ XDICO_DEBUG_F1(1, _("Found matching line %d\n"), line);
+ if (matches->host_argv)
+ dico_argcv_free(matches->host_argc, matches->host_argv);
+ matches->host_argc = ws->ws_wordc;
+ matches->host_argv = ws->ws_wordv;
+ matches->def_line = line;
+ rc = 1;
+ }
+ } else if (strcmp(ws->ws_wordv[0], "default") == 0) {
+ XDICO_DEBUG_F1(1, _("Found default line %d\n"), line);
+ if (matches->def_argv)
+ dico_argcv_free(matches->def_argc, matches->def_argv);
+ matches->def_argc = ws->ws_wordc;
+ matches->def_argv = ws->ws_wordv;
+ matches->def_line = line;
+ }
+ ws->ws_wordc = 0;
+ ws->ws_wordv = NULL;
+ return rc;
+}
+
+
/* Parse netrc-like autologin file and set up user and key accordingly. */
int
parse_autologin(const char *filename, char *host, struct auth_cred *pcred,
@@ -142,17 +178,13 @@ parse_autologin(const char *filename, char *host, struct auth_cred *pcred,
FILE *fp;
char *buf = NULL;
size_t n = 0;
- int def_argc = 0;
- char **def_argv = NULL;
- int def_line = 0;
- char **host_argv = NULL;
- int host_argc = 0;
- char ***pp_argv;
- int *pp_argc;
+ struct matches matches;
char **p_argv = NULL;
int line = 0;
int flags = 0;
- int stop = 0;
+ struct wordsplit ws;
+ int wsflags = 0;
+ int beg_line = 0;
fp = fopen (filename, "r");
if (!fp) {
@@ -164,83 +196,68 @@ parse_autologin(const char *filename, char *host, struct auth_cred *pcred,
} else
XDICO_DEBUG_F1(1, _("Reading autologin file %s...\n"), filename);
+ memset(&matches, 0, sizeof matches);
+ matches.host = host;
while (getline (&buf, &n, fp) > 0 && n > 0) {
- int rc;
char *p;
- size_t len;
- int argc;
- char **argv;
line++;
- len = strlen(buf);
- if (len > 1 && buf[len - 1] == '\n')
- buf[len - 1] = 0;
p = skipws(buf);
- if (*p == 0 || *p == '#')
- continue;
- if ((rc = dico_argcv_get(buf, "", "#", &argc, &argv))) {
- dico_log(L_ERR, rc, _("dico_argcv_get failed"));
+ if ((wsflags & WRDSF_APPEND) &&
+ (begins_with(p, "machine") || begins_with(p, "default"))) {
+ wsflags &= ~WRDSF_APPEND;
+ if (match_line(&ws, &matches, beg_line))
+ break;
+ beg_line = line;
+ } else if (!(wsflags & WRDSF_REUSE))
+ beg_line = line;
+
+ ws.ws_comment = "#";
+ if (wordsplit(p, &ws, WRDSF_DEFFLAGS|WRDSF_COMMENT|wsflags)) {
+ dico_log(L_ERR, 0, _("failed to parse command `%s': %s"),
+ p, wordsplit_strerror(&ws));
fclose(fp);
free(buf);
+ if (wsflags & WRDSF_REUSE)
+ wordsplit_free(&ws);
return 1;
}
-
- if (pp_argv) {
- if (strcmp(argv[0], "machine") == 0
- || strcmp(argv[0], "default") == 0) {
- if (stop) {
- dico_argcv_free(argc, argv);
- break;
- }
- pp_argv = NULL;
- pp_argc = 0;
- } else {
- argv_expand(pp_argc, pp_argv, argc, argv);
- free(argv);
- continue;
- }
+ wsflags |= WRDSF_REUSE | WRDSF_APPEND;
+ /* Add newline marker */
+ if (wordsplit("#", &ws, WRDSF_DEFFLAGS|WRDSF_NOSPLIT|wsflags)) {
+ dico_log(L_ERR, 0, _("failed to add line marker: %s"),
+ wordsplit_strerror(&ws));
+ fclose(fp);
+ free(buf);
+ if (wsflags & WRDSF_REUSE)
+ wordsplit_free(&ws);
+ return 1;
}
- if (strcmp(argv[0], "machine") == 0) {
- if (hostcmp(argv[1], host) == 0) {
- XDICO_DEBUG_F1(1, _("Found matching line %d\n"), line);
- stop = 1;
- host_argc = argc;
- host_argv = argv;
- pp_argc = &host_argc;
- pp_argv = &host_argv;
- def_line = line;
- continue;
- }
- } else if (strcmp(argv[0], "default") == 0) {
- XDICO_DEBUG_F1(1, _("Found default line %d\n"), line);
- def_argc = argc;
- def_argv = argv;
- pp_argc = &def_argc;
- pp_argv = &def_argv;
- def_line = line;
- continue;
- }
- dico_argcv_free(argc, argv);
}
+ if (wsflags & WRDSF_APPEND)
+ match_line(&ws, &matches, line);
+ if (wsflags & WRDSF_REUSE)
+ wordsplit_free(&ws);
+
fclose(fp);
free(buf);
- if (host_argv)
- p_argv = host_argv + 2;
- else if (def_argv)
- p_argv = def_argv + 1;
+ if (matches.host_argv)
+ p_argv = matches.host_argv + 2;
+ else if (matches.def_argv)
+ p_argv = matches.def_argv + 1;
else {
XDICO_DEBUG(1, _("No matching line found\n"));
p_argv = NULL;
}
if (p_argv) {
- line = def_line;
+ line = matches.def_line;
pcred->sasl = sasl_enabled_p();
- while (*p_argv) {
- if (strcmp(*p_argv, "\n") == 0) {
+ while (*p_argv) {
+ if (**p_argv == '#') {
line++;
p_argv++;
} else {
@@ -302,33 +319,37 @@ parse_autologin(const char *filename, char *host, struct auth_cred *pcred,
break;
case kw_mechanism: {
- int i, c;
- char **v;
-
+ int i;
+ struct wordsplit mechws;
+
if (!(flags & AUTOLOGIN_MECH)) {
pcred->mech = xdico_list_create();
dico_list_set_free_item(pcred->mech, _cred_free, NULL);
flags |= AUTOLOGIN_MECH;
}
- if (dico_argcv_get(arg, ",", NULL, &c, &v)) {
+ mechws.ws_delim = ",";
+ if (wordsplit(arg, &mechws,
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM |
+ WRDSF_WS)) {
dico_log(L_ERR, 0,
- _("%s:%d: not enough memory"),
- filename, line);
+ _("%s:%d: failed to parse line: %s"),
+ filename, line, wordsplit_strerror (&mechws));
exit(1);
}
- for (i = 0; i < c; i++)
- xdico_list_append(pcred->mech, v[i]);
+ for (i = 0; i < mechws.ws_wordc; i++)
+ xdico_list_append(pcred->mech, mechws.ws_wordv[i]);
- free(v);
+ mechws.ws_wordc = 0;
+ wordsplit_free(&mechws);
break;
}
}
}
}
}
- dico_argcv_free(def_argc, def_argv);
- dico_argcv_free(host_argc, host_argv);
+ dico_argcv_free(matches.def_argc, matches.def_argv);
+ dico_argcv_free(matches.host_argc, matches.host_argv);
if (pflags)
*pflags = flags;
diff --git a/dico/dico-priv.h b/dico/dico-priv.h
index 60a64a1..046ad3f 100644
--- a/dico/dico-priv.h
+++ b/dico/dico-priv.h
@@ -39,6 +39,7 @@
#include <netdb.h>
#include <signal.h>
#include <ltdl.h>
+#include "wordsplit.h"
#include <xdico.h>
#include <inttostr.h>
diff --git a/dico/saslauth.c b/dico/saslauth.c
index 1048e2f..9ca95d3 100644
--- a/dico/saslauth.c
+++ b/dico/saslauth.c
@@ -32,8 +32,7 @@ get_implemented_mechs(Gsasl *ctx)
char *listmech;
dico_list_t supp = NULL;
int rc;
- int mechc;
- char **mechv;
+ struct wordsplit ws;
rc = gsasl_server_mechlist(ctx, &listmech);
if (rc != GSASL_OK) {
@@ -43,13 +42,14 @@ get_implemented_mechs(Gsasl *ctx)
return NULL;
}
- if (dico_argcv_get(listmech, "", NULL, &mechc, &mechv) == 0) {
+ if (wordsplit(listmech, &ws, WRDSF_DEFFLAGS) == 0) {
int i;
supp = xdico_list_create();
dico_list_set_free_item(supp, _free_el, NULL);
- for (i = 0; i < mechc; i++)
- xdico_list_append(supp, mechv[i]);
- free(mechv);
+ for (i = 0; i < ws.ws_wordc; i++)
+ xdico_list_append(supp, ws.ws_wordv[i]);
+ ws.ws_wordc = 0;
+ wordsplit_free(&ws);
}
free(listmech);
return supp;
diff --git a/dico/shell.c b/dico/shell.c
index 947cfef..f38c462 100644
--- a/dico/shell.c
+++ b/dico/shell.c
@@ -459,27 +459,23 @@ _command_generator(const char *text, int state)
static char **
_command_completion(char *cmd, int start, int end)
{
- int argc;
- char **argv;
char **ret;
- char *p;
-
- for (p = rl_line_buffer; p < rl_line_buffer + start && isspace (*p); p++)
- ;
-
+ struct wordsplit ws;
+
/* FIXME: Use tokenizer */
- if (dico_argcv_get_n (p, end, NULL, NULL, &argc, &argv))
+ if (wordsplit_len (rl_line_buffer, end, &ws, WRDSF_DEFFLAGS))
return NULL;
rl_completion_append_character = ' ';
- if (argc == 0 || (argc == 1 && strlen (argv[0]) <= end - start)) {
+ if (ws.ws_wordc == 0 ||
+ (ws.ws_wordc == 1 && strlen (ws.ws_wordv[0]) <= end - start)) {
ret = rl_completion_matches (cmd, _command_generator);
rl_attempted_completion_over = 1;
} else {
- struct funtab *ft = find_funtab(argv[0] + (cmdprefix ? 1 : 0));
+ struct funtab *ft = find_funtab(ws.ws_wordv[0] + (cmdprefix ? 1 : 0));
if (ft) {
if (ft->compl)
- ret = ft->compl(argc, argv, start == end);
+ ret = ft->compl(ws.ws_wordc, ws.ws_wordv, start == end);
else if (ft->argmax == 1) {
rl_attempted_completion_over = 1;
ret = NULL;
@@ -490,7 +486,7 @@ _command_completion(char *cmd, int start, int end)
ret = NULL;
}
}
- dico_argcv_free(argc, argv);
+ wordsplit_free(&ws);
return ret;
}

Return to:

Send suggestions and report system problems to the System administrator.