Sat, 27 Feb 2016 19:39:55 +0100
added add-repository command to dav
The new add-repository command starts an interactive assistant and adds a new repository to the config.xml configuration file.
dav/Makefile | file | annotate | diff | comparison | revisions | |
dav/assistant.c | file | annotate | diff | comparison | revisions | |
dav/assistant.h | file | annotate | diff | comparison | revisions | |
dav/config.c | file | annotate | diff | comparison | revisions | |
dav/config.h | file | annotate | diff | comparison | revisions | |
dav/main.c | file | annotate | diff | comparison | revisions | |
dav/main.h | file | annotate | diff | comparison | revisions |
--- a/dav/Makefile Sat Feb 27 17:23:36 2016 +0100 +++ b/dav/Makefile Sat Feb 27 19:39:55 2016 +0100 @@ -32,6 +32,7 @@ DAV_SRC += config.c DAV_SRC += optparser.c DAV_SRC += error.c +DAV_SRC += assistant.c SYNC_SRC = sync.c SYNC_SRC += config.c @@ -39,6 +40,7 @@ SYNC_SRC += sopt.c SYNC_SRC += db.c SYNC_SRC += error.c +SYNC_SRC += assistant.c DAV_OBJ = $(DAV_SRC:%.c=../build/tool/%$(OBJ_EXT))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/assistant.c Sat Feb 27 19:39:55 2016 +0100 @@ -0,0 +1,92 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2016 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <ucx/string.h> +#include <ucx/utils.h> + +#include <libidav/utils.h> + +#include "assistant.h" + +char* assistant_getcfg(char *cfgname) { + sstr_t line; + char *value = NULL; + while(!value) { + printf("%s: ", cfgname); + line = util_readline(stdin); + if(line.length == 0 || !line.ptr) { + fprintf(stderr, "%s must be not empty\n", cfgname); + continue; + } + + value = line.ptr; + break; + } + return value; +} + +char* assistant_getoptcfg(char *cfgname) { + sstr_t line; + char *value = NULL; + while(!value) { + printf("%s (optional): ", cfgname); + line = util_readline(stdin); + if(line.length == 0 || !line.ptr) { + if(line.ptr) { + free(line.ptr); + } + break; + } + + value = line.ptr; + break; + } + return value; +} + +char* assistant_gethiddenoptcfg(char *cfgname) { + printf("%s (optional): ", cfgname); + char *pw = util_password_input(""); + if(pw[0] == 0) { + free(pw); + pw = NULL; + } + return pw; +} + + +char* assistant_getdefcfg(char *cfgname, char *defval) { + char *value = assistant_getoptcfg(cfgname); + if(!value) { + value = strdup(defval); + } + return value; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/assistant.h Sat Feb 27 19:39:55 2016 +0100 @@ -0,0 +1,63 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2016 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ASSISTANT_H +#define ASSISTANT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ask for a configuration value with the name cfgname + * which must be not empty + */ +char* assistant_getcfg(char *cfgname); + +/* + * ask for an optional configuration value with the name cfgname + */ +char* assistant_getoptcfg(char *cfgname); + +/* + * ask for an optional configuration value with the name cfgname + * with hidden input + */ +char* assistant_gethiddenoptcfg(char *cfgname); + +/* + * ask for an configuration value with the default value defval + */ +char* assistant_getdefcfg(char *cfgname, char *defval); + +#ifdef __cplusplus +} +#endif + +#endif /* ASSISTANT_H */ +
--- a/dav/config.c Sat Feb 27 17:23:36 2016 +0100 +++ b/dav/config.c Sat Feb 27 19:39:55 2016 +0100 @@ -477,3 +477,50 @@ return https_proxy; } + +int add_repository(Repository *repo) { + char *file = util_concat_path(ENV_HOME, ".dav/config.xml"); + xmlDoc *doc = xmlReadFile(file, NULL, 0); + if(!doc) { + free(file); + fprintf(stderr, "Cannot load config.xml\n"); + return 1; + } + + xmlNode *root = xmlDocGetRootElement(doc); + + xmlNode *repoNode = xmlNewNode(NULL, BAD_CAST "repository"); + xmlNodeAddContent(repoNode, BAD_CAST "\n\t\t"); + xmlNewTextChild(repoNode, NULL, BAD_CAST "name", BAD_CAST repo->name); + xmlNodeAddContent(repoNode, BAD_CAST "\n\t\t"); + xmlNewTextChild(repoNode, NULL, BAD_CAST "url", BAD_CAST repo->url); + xmlNodeAddContent(repoNode, BAD_CAST "\n"); + if(repo->user) { + xmlNodeAddContent(repoNode, BAD_CAST "\t\t"); + xmlNewChild(repoNode, NULL, BAD_CAST "user", BAD_CAST repo->user); + xmlNodeAddContent(repoNode, BAD_CAST "\n"); + if(repo->password) { + char *pwenc = util_base64encode( + repo->password, + strlen(repo->password)); + xmlNodeAddContent(repoNode, BAD_CAST "\t\t"); + xmlNewTextChild(repoNode, NULL, BAD_CAST "password", BAD_CAST pwenc); + free(pwenc); + xmlNodeAddContent(repoNode, BAD_CAST "\n"); + } + } + xmlNodeAddContent(repoNode, BAD_CAST "\t"); + + xmlNodeAddContent(root, "\n\t"); + xmlAddChild(root, repoNode); + xmlNodeAddContent(root, BAD_CAST "\n"); + + int ret = 0; + if(xmlSaveFormatFileEnc(file, doc, "UTF-8", 1) == -1) { + ret = 1; + } + xmlFreeDoc(doc); + free(file); + + return ret; +}
--- a/dav/config.h Sat Feb 27 17:23:36 2016 +0100 +++ b/dav/config.h Sat Feb 27 19:39:55 2016 +0100 @@ -90,6 +90,8 @@ Proxy* get_http_proxy(); Proxy* get_https_proxy(); +int add_repository(Repository *repo); + #ifdef __cplusplus } #endif
--- a/dav/main.c Sat Feb 27 17:23:36 2016 +0100 +++ b/dav/main.c Sat Feb 27 19:39:55 2016 +0100 @@ -43,6 +43,7 @@ #include <libidav/session.h> #include "config.h" #include "error.h" +#include "assistant.h" #include "main.h" static DavContext *ctx; @@ -120,6 +121,8 @@ ret = cmd_get_property(args); } else if(!strcasecmp(cmd, "info")) { ret = cmd_info(args); + } else if(!strcasecmp(cmd, "create-repository")) { + ret = cmd_create_repository(args); } else if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") || !strcasecmp(cmd, "--version")) { #ifdef DEBUG fprintf(stderr, "dav %s unstable\n", DAV_VERSION); @@ -180,6 +183,9 @@ fprintf(stderr, " -n <uri> specify namespace uri\n"); fprintf(stderr, " -v verbose output\n"); fprintf(stderr, "\n"); + fprintf(stderr, "Config Commands:\n"); + fprintf(stderr, " add-repository\n"); + fprintf(stderr, "\n"); fprintf(stderr, "Instead of an url you can pass a repository name " "with an optional path:\n"); @@ -1150,73 +1156,53 @@ } } + /* ---------- config commands ---------- */ -static int getkeyvalue(char *arg, char **key, char **value) { - // splits a key=value arg +int cmd_create_repository(CmdArgs *args) { + sstr_t line; - *key = NULL; - *value = NULL; - if(!arg && !key && !value) { + printf("Each repository must have an unique name.\n"); + char *name = assistant_getcfg("name"); + if(!name) { + fprintf(stderr, "Abort\n"); + return -1; + } + if(get_repository(sstr(name))) { + fprintf(stderr, "Repository %s already exists.\nAbort\n"); return -1; } - int haskey = 0; - size_t len = strlen(arg); - - if(len < 3) { + printf("\nSpecify the repository base url.\n"); + char *url = assistant_getcfg("url"); + if(!url) { + fprintf(stderr, "Abort\n"); return -1; } - int i; - for(i=0;i<len;i++) { - if(arg[i] == '=') { - haskey = 1; - break; - } + printf("\nUser for HTTP authentication.\n"); + char *user = assistant_getoptcfg("user"); + + char *password = NULL; + if(user) { + password = assistant_gethiddenoptcfg("password"); } + printf("\n"); - if(haskey) { - sstr_t k = sstrn(arg, i); - sstr_t v = sstrn(arg+i + 1, len - i - 1); - if(k.length > 0 && v.length > 0) { - *key = sstrdup(k).ptr; - *value = sstrdup(v).ptr; - return 0; - } + Repository repo; + memset(&repo, 0, sizeof(Repository)); + repo.name = name; + repo.url = url; + repo.user = user; + repo.password = password; + + int ret = 0; + if(add_repository(&repo)) { + fprintf(stderr, "Cannot write config.xml\n"); + ret = -1; + } else { + printf("Added repository: %s (%s)\n", name, url); } - return -1; + return ret; } - -void repository_assistent(Repository *repo, int mode) { - char *name = NULL; - sstr_t line; - - // name - while(!name) { - if(repo->name) { - printf("repository name [%s]: ", repo->name); - } else { - printf("repository name: "); - } - fflush(stdout); - - line = util_readline(stdin); - if(line.length == 0 && repo->name) { - break; - } else { - name = line.ptr; - } - } - if(name) { - if(repo->name) { - free(repo->name); - } - repo->name = name; - } - - // TODO - - return; -}
--- a/dav/main.h Sat Feb 27 17:23:36 2016 +0100 +++ b/dav/main.h Sat Feb 27 19:39:55 2016 +0100 @@ -68,12 +68,7 @@ char* stdin2str(); -void repository_assistent(Repository *repo, int mode); - -int cmd_add_repository(CmdArgs *args); -int cmd_modify_repository(CmdArgs *args); -int cmd_delete_repository(CmdArgs *args); -int cmd_list_repositories(CmdArgs *args); +int cmd_create_repository(CmdArgs *args); #ifdef __cplusplus }