diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-01-10 20:46:24 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-01-10 22:12:04 +0200 |
commit | 0b4a6a095e1384ff16c786a17b66bcc392a0d57b (patch) | |
tree | 4a0caf29bc70b39c3b59ee550596e0a9032993fc /dico | |
parent | 2fcdaba8d0358036e8d70b25eba5f1fa30975db1 (diff) | |
download | dico-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.c | 183 | ||||
-rw-r--r-- | dico/dico-priv.h | 1 | ||||
-rw-r--r-- | dico/saslauth.c | 12 | ||||
-rw-r--r-- | dico/shell.c | 20 |
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; } |