X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Ftools%2Fsysdb%2Fmain.c;h=331cfa25e640912ac79ac6b37c44d3a91f374323;hp=9b575cc825746c47548b87968090c65c0d77b6b2;hb=ee8df3b190c2eb49e460dcf03f81288a5d825c39;hpb=3dfbb8002ceb61be3cb61a7764c98fef4b6c011a diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c index 9b575cc..331cfa2 100644 --- a/src/tools/sysdb/main.c +++ b/src/tools/sysdb/main.c @@ -29,11 +29,13 @@ # include "config.h" #endif /* HAVE_CONFIG_H */ +#include "tools/sysdb/command.h" #include "tools/sysdb/input.h" #include "client/sysdb.h" #include "client/sock.h" #include "utils/error.h" +#include "utils/llist.h" #include "utils/strbuf.h" #include @@ -78,39 +80,6 @@ # define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" #endif -extern int yylex(void); - -static void -exit_usage(char *name, int status) -{ - printf( -"Usage: %s \n" - -"\nOptions:\n" -" -h display this help and exit\n" -" -V display the version number and copyright\n" - -"\nSysDB client "SDB_CLIENT_VERSION_STRING SDB_CLIENT_VERSION_EXTRA", " -PACKAGE_URL"\n", basename(name)); - exit(status); -} /* exit_usage */ - -static void -exit_version(void) -{ - printf("SysDB version "SDB_CLIENT_VERSION_STRING - SDB_CLIENT_VERSION_EXTRA", built "BUILD_DATE"\n" - "using libsysdbclient version %s%s\n" - "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" - - "\nThis is free software under the terms of the BSD license, see " - "the source for\ncopying conditions. There is NO WARRANTY; not " - "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " - "PURPOSE.\n", sdb_client_version_string(), - sdb_client_version_extra()); - exit(0); -} /* exit_version */ - static const char * get_current_user(void) { @@ -164,6 +133,95 @@ get_homedir(const char *username) return result->pw_dir; } /* get_homedir */ +static void +exit_usage(char *name, int status) +{ + printf( +"Usage: %s \n" + +"\nOptions:\n" +" -H HOST the host to connect to\n" +" default: "DEFAULT_SOCKET"\n" +" -U USER the username to connect as\n" +" default: %s\n" +" -c CMD execute the specified command and then exit\n" +"\n" +" -h display this help and exit\n" +" -V display the version number and copyright\n" + +"\nSysDB client "SDB_CLIENT_VERSION_STRING SDB_CLIENT_VERSION_EXTRA", " +PACKAGE_URL"\n", basename(name), get_current_user()); + exit(status); +} /* exit_usage */ + +static void +exit_version(void) +{ + printf("SysDB version "SDB_CLIENT_VERSION_STRING + SDB_CLIENT_VERSION_EXTRA", built "BUILD_DATE"\n" + "using libsysdbclient version %s%s\n" + "Copyright (C) 2012-2014 "PACKAGE_MAINTAINER"\n" + + "\nThis is free software under the terms of the BSD license, see " + "the source for\ncopying conditions. There is NO WARRANTY; not " + "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " + "PURPOSE.\n", sdb_client_version_string(), + sdb_client_version_extra()); + exit(0); +} /* exit_version */ + +static int +execute_commands(sdb_client_t *client, sdb_llist_t *commands) +{ + sdb_llist_iter_t *iter; + int status = 0; + + iter = sdb_llist_get_iter(commands); + if (! iter) { + sdb_log(SDB_LOG_ERR, "Failed to iterate commands"); + return 1; + } + + while (sdb_llist_iter_has_next(iter)) { + sdb_object_t *obj = sdb_llist_iter_get_next(iter); + + if (sdb_client_send(client, CONNECTION_QUERY, + (uint32_t)strlen(obj->name), obj->name) <= 0) { + sdb_log(SDB_LOG_ERR, "Failed to send command '%s' to server", + obj->name); + status = 1; + break; + } + + /* Wait for server replies. We might get any number of log messages + * but eventually see the reply to the query, which is either DATA or + * ERROR. */ + while (42) { + status = sdb_command_print_reply(client); + if (status < 0) { + sdb_log(SDB_LOG_ERR, "Failed to read reply from server"); + break; + } + + if ((status == CONNECTION_DATA) || (status == CONNECTION_ERROR)) + break; + if (status == CONNECTION_OK) { + /* pre 0.4 versions used OK instead of DATA */ + sdb_log(SDB_LOG_WARNING, "Received unexpected OK status from " + "server in response to a QUERY (expected DATA); " + "assuming we're talking to an old server"); + break; + } + } + + if ((status != CONNECTION_OK) && (status != CONNECTION_DATA)) + break; /* error */ + } + + sdb_llist_iter_destroy(iter); + return status; +} /* execute_commands */ + int main(int argc, char **argv) { @@ -174,9 +232,10 @@ main(int argc, char **argv) char hist_file[1024] = ""; sdb_input_t input = SDB_INPUT_INIT; + sdb_llist_t *commands = NULL; while (42) { - int opt = getopt(argc, argv, "H:U:hV"); + int opt = getopt(argc, argv, "H:U:c:hV"); if (-1 == opt) break; @@ -189,6 +248,30 @@ main(int argc, char **argv) user = optarg; break; + case 'c': + { + sdb_object_t *obj; + + if (! commands) + commands = sdb_llist_create(); + if (! commands) { + sdb_log(SDB_LOG_ERR, "Failed to create list object"); + exit(1); + } + + if (! (obj = sdb_object_create_T(optarg, sdb_object_t))) { + sdb_log(SDB_LOG_ERR, "Failed to create object"); + exit(1); + } + if (sdb_llist_append(commands, obj)) { + sdb_log(SDB_LOG_ERR, "Failed to append command to list"); + sdb_object_deref(obj); + exit(1); + } + sdb_object_deref(obj); + } + break; + case 'h': exit_usage(argv[0], 0); break; @@ -222,8 +305,18 @@ main(int argc, char **argv) exit(1); } + if (commands) { + int status = execute_commands(input.client, commands); + sdb_llist_destroy(commands); + sdb_client_destroy(input.client); + if ((status != CONNECTION_OK) && (status != CONNECTION_DATA)) + exit(1); + exit(0); + } + sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING - SDB_CLIENT_VERSION_EXTRA"\n"); + SDB_CLIENT_VERSION_EXTRA" (libsysdbclient %s%s)\n", + sdb_client_version_string(), sdb_client_version_extra()); using_history(); @@ -242,7 +335,13 @@ main(int argc, char **argv) input.input = sdb_strbuf_create(2048); sdb_input_init(&input); - yylex(); + sdb_input_mainloop(); + + sdb_client_shutdown(input.client, SHUT_WR); + while (! sdb_client_eof(input.client)) { + /* wait for remaining data to arrive */ + sdb_command_print_reply(input.client); + } if (hist_file[0] != '\0') { errno = 0;