X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=client_common.c;h=a7eee85d3cc0d5cf94073ca39c6223a7c4a639d4;hp=eea7510fd0589e86fb4058dd7f4361f3c79901aa;hb=ba83a291cd486e8ab53ac64d81b17d8f5705d715;hpb=9165680a9639a8412adef13b96e466efdbb9d806 diff --git a/client_common.c b/client_common.c index eea7510f..a7eee85d 100644 --- a/client_common.c +++ b/client_common.c @@ -1,8 +1,4 @@ -/* - * Copyright (C) 1997 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ +/* Copyright (C) 1997 Andre Noll , see file COPYING. */ /** \file client_common.c Common functions of para_client and para_audiod. */ @@ -13,21 +9,22 @@ #include #include #include +#include +#include "client.lsg.h" #include "para.h" #include "error.h" #include "list.h" +#include "lsu.h" #include "sched.h" #include "crypt.h" #include "net.h" #include "fd.h" #include "sideband.h" #include "string.h" -#include "client.cmdline.h" #include "client.h" #include "buffer_tree.h" #include "version.h" -#include "ggo.h" /** The size of the receiving buffer. */ #define CLIENT_BUFSIZE 4000 @@ -44,9 +41,8 @@ void client_close(struct client_task *ct) if (!ct) return; free(ct->user); - free(ct->config_file); free(ct->key_file); - client_cmdline_parser_free(&ct->conf); + lls_free_parse_result(ct->lpr, CLIENT_CMD_PTR); free(ct->challenge_hash); sb_free(ct->sbc[0]); sb_free(ct->sbc[1]); @@ -90,7 +86,7 @@ static void client_pre_select(struct sched *s, void *context) else if (ret > 0) para_fd_set(ct->scc.fd, &s->wfds, &s->max_fileno); } - /* fall though */ + /* fallthrough */ case CL_EXECUTING: if (ct->btrn[0]) { ret = btr_node_status(ct->btrn[0], 0, BTR_NT_ROOT); @@ -241,26 +237,23 @@ out: return ret; } -static bool has_feature(const char *feature, struct client_task *ct) -{ - return find_arg(feature, ct->features) >= 0? true : false; -} - static int send_sb_command(struct client_task *ct) { int i; char *command, *p; size_t len = 0; + unsigned num_inputs = lls_num_inputs(ct->lpr); if (ct->sbc[1]) return send_sb(ct, 0, NULL, 0, 0, false); - for (i = 0; i < ct->conf.inputs_num; i++) - len += strlen(ct->conf.inputs[i]) + 1; + for (i = 0; i < num_inputs; i++) + len += strlen(lls_input(i, ct->lpr)) + 1; p = command = para_malloc(len); - for (i = 0; i < ct->conf.inputs_num; i++) { - strcpy(p, ct->conf.inputs[i]); - p += strlen(ct->conf.inputs[i]) + 1; + for (i = 0; i < num_inputs; i++) { + const char *str = lls_input(i, ct->lpr); + strcpy(p, str); + p += strlen(str) + 1; } PARA_DEBUG_LOG("--> %s\n", command); return send_sb(ct, 0, command, len, SBD_COMMAND, false); @@ -297,8 +290,8 @@ static int client_post_select(struct sched *s, void *context) case CL_RECEIVED_WELCOME: /* send auth command */ if (!FD_ISSET(ct->scc.fd, &s->wfds)) return 0; - sprintf(buf, AUTH_REQUEST_MSG "%s sideband%s", ct->user, - has_feature("aes_ctr128", ct)? ",aes_ctr128" : ""); + sprintf(buf, AUTH_REQUEST_MSG "%s sideband,aes_ctr128", + ct->user); PARA_INFO_LOG("--> %s\n", buf); ret = write_buffer(ct->scc.fd, buf); if (ret < 0) @@ -314,7 +307,6 @@ static int client_post_select(struct sched *s, void *context) /* decrypted challenge/session key buffer */ unsigned char crypt_buf[1024]; struct sb_buffer sbb; - bool use_aes; ret = recv_sb(ct, &s->rfds, &sbb); if (ret <= 0) @@ -326,17 +318,16 @@ static int client_post_select(struct sched *s, void *context) } n = sbb.iov.iov_len; PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = priv_decrypt(ct->key_file, crypt_buf, + ret = apc_priv_decrypt(ct->key_file, crypt_buf, sbb.iov.iov_base, n); free(sbb.iov.iov_base); if (ret < 0) goto out; ct->challenge_hash = para_malloc(HASH_SIZE); - hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->challenge_hash); - use_aes = has_feature("aes_ctr128", ct); - ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN, use_aes); - ct->scc.recv = sc_new(crypt_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, - SESSION_KEY_LEN, use_aes); + hash_function((char *)crypt_buf, APC_CHALLENGE_SIZE, ct->challenge_hash); + ct->scc.send = sc_new(crypt_buf + APC_CHALLENGE_SIZE, SESSION_KEY_LEN); + ct->scc.recv = sc_new(crypt_buf + APC_CHALLENGE_SIZE + SESSION_KEY_LEN, + SESSION_KEY_LEN); hash_to_asc(ct->challenge_hash, buf); PARA_INFO_LOG("--> %s\n", buf); ct->status = CL_RECEIVED_CHALLENGE; @@ -467,12 +458,12 @@ int client_connect(struct client_task *ct, struct sched *s, struct btr_node *parent, struct btr_node *child) { int ret; + const char *host = CLIENT_OPT_STRING_VAL(HOSTNAME, ct->lpr); + uint32_t port = CLIENT_OPT_UINT32_VAL(SERVER_PORT, ct->lpr); - PARA_NOTICE_LOG("connecting %s:%d\n", ct->conf.hostname_arg, - ct->conf.server_port_arg); + PARA_NOTICE_LOG("connecting %s:%u\n", host, port); ct->scc.fd = -1; - ret = para_connect_simple(IPPROTO_TCP, ct->conf.hostname_arg, - ct->conf.server_port_arg); + ret = para_connect_simple(IPPROTO_TCP, host, port); if (ret < 0) return ret; ct->scc.fd = ret; @@ -498,13 +489,19 @@ err_out: return ret; } -__noreturn static void print_help_and_die(struct client_task *ct) +static void handle_help_flag(struct lls_parse_result *lpr) { - struct ggo_help h = DEFINE_GGO_HELP(client); - bool d = ct->conf.detailed_help_given; + char *help; - ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS); - exit(0); + if (CLIENT_OPT_GIVEN(DETAILED_HELP, lpr)) + help = lls_long_help(CLIENT_CMD_PTR); + else if (CLIENT_OPT_GIVEN(HELP, lpr)) + help = lls_short_help(CLIENT_CMD_PTR); + else + return; + printf("%s\n", help); + free(help); + exit(EXIT_SUCCESS); } /** @@ -528,65 +525,56 @@ __noreturn static void print_help_and_die(struct client_task *ct) int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr, int *loglevel) { - char *home = para_homedir(); - int ret; - struct client_task *ct = para_calloc(sizeof(struct client_task)); + const struct lls_command *cmd = CLIENT_CMD_PTR; + struct lls_parse_result *lpr; + int ret, ll; + struct client_task *ct; + char *kf = NULL, *user, *errctx, *home = para_homedir(); - *ct_ptr = ct; - ct->scc.fd = -1; - ret = -E_CLIENT_SYNTAX; - if (client_cmdline_parser(argc, argv, &ct->conf)) + ret = lls(lls_parse(argc, argv, cmd, &lpr, &errctx)); + if (ret < 0) goto out; - version_handle_flag("client", ct->conf.version_given); - if (ct->conf.help_given || ct->conf.detailed_help_given) - print_help_and_die(ct); - - ct->config_file = ct->conf.config_file_given? - para_strdup(ct->conf.config_file_arg) : - make_message("%s/.paraslash/client.conf", home); - ret = file_exists(ct->config_file); - if (!ret && ct->conf.config_file_given) { - ret = -E_NO_CONFIG; + version_handle_flag("client", CLIENT_OPT_GIVEN(VERSION, lpr)); + handle_help_flag(lpr); + + ret = lsu_merge_config_file_options(CLIENT_OPT_STRING_VAL(CONFIG_FILE, lpr), + "client.conf", &lpr, cmd, client_suite, 0U /* default flags */); + if (ret < 0) goto out; - } - if (ret) { - struct client_cmdline_parser_params params = { - .override = 0, - .initialize = 0, - .check_required = 0, - .check_ambiguity = 0, - .print_errors = 0 - }; - ret = -E_BAD_CONFIG; - if (client_cmdline_parser_config_file(ct->config_file, - &ct->conf, ¶ms)) - goto out; - } - ct->user = ct->conf.user_given? - para_strdup(ct->conf.user_arg) : para_logname(); + /* success */ + ll = CLIENT_OPT_UINT32_VAL(LOGLEVEL, lpr); + if (loglevel) + *loglevel = ll; + user = CLIENT_OPT_GIVEN(USER, lpr)? + para_strdup(CLIENT_OPT_STRING_VAL(USER, lpr)) : para_logname(); - if (ct->conf.key_file_given) - ct->key_file = para_strdup(ct->conf.key_file_arg); + if (CLIENT_OPT_GIVEN(KEY_FILE, lpr)) + kf = para_strdup(CLIENT_OPT_STRING_VAL(KEY_FILE, lpr)); else { - ct->key_file = make_message("%s/.paraslash/key.%s", - home, ct->user); - if (!file_exists(ct->key_file)) { - free(ct->key_file); - ct->key_file = make_message("%s/.ssh/id_rsa", home); + kf = make_message("%s/.paraslash/key.%s", home, user); + if (!file_exists(kf)) { + free(kf); + kf = make_message("%s/.ssh/id_rsa", home); } } - - if (loglevel) - *loglevel = get_loglevel_by_name(ct->conf.loglevel_arg); - PARA_INFO_LOG("loglevel: %s\n", ct->conf.loglevel_arg); - PARA_INFO_LOG("config_file: %s\n", ct->config_file); - PARA_INFO_LOG("key_file: %s\n", ct->key_file); - ret = ct->conf.inputs_num; + PARA_INFO_LOG("user: %s\n", user); + PARA_INFO_LOG("key file: %s\n", kf); + PARA_INFO_LOG("loglevel: %d\n", ll); + ct = para_calloc(sizeof(*ct)); + ct->scc.fd = -1; + ct->lpr = lpr; + ct->key_file = kf; + ct->user = user; + *ct_ptr = ct; + ret = lls_num_inputs(lpr); out: free(home); if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - client_close(ct); + if (errctx) + PARA_ERROR_LOG("%s\n", errctx); + free(errctx); + lls_free_parse_result(lpr, cmd); + free(kf); *ct_ptr = NULL; } return ret;