]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - client_common.c
bitstream: Improve documentation.
[paraslash.git] / client_common.c
index 3ff43d1b7bffd2c1c2438078d431122ea9f6942d..900d3653893dea7067330d60a929ce0a4b13d902 100644 (file)
@@ -1,19 +1,23 @@
 /*
- * Copyright (C) 1997-2013 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2014 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
 
 /** \file client_common.c Common functions of para_client and para_audiod. */
 
+#include <netinet/in.h>
+#include <sys/socket.h>
 #include <regex.h>
 #include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <netdb.h>
 
 #include "para.h"
 #include "error.h"
 #include "list.h"
 #include "sched.h"
-#include "client.cmdline.h"
 #include "crypt.h"
 #include "net.h"
 #include "fd.h"
 #include "client.h"
 #include "buffer_tree.h"
 #include "version.h"
+#include "ggo.h"
 
 /** The size of the receiving buffer. */
 #define CLIENT_BUFSIZE 4000
 
 /**
- * Close the connection to para_server and deallocate per-command ressources.
+ * Close the connection to para_server and deallocate per-command resources.
  *
  * \param ct The client task.
  *
- * This frees all ressources of the current command but keeps the configuration
+ * This frees all resources of the current command but keeps the configuration
  * in \p ct->conf.
  *
  * \sa \ref client_close().
@@ -303,7 +308,7 @@ static int send_sb_command(struct client_task *ct)
  *
  * \sa struct sched, struct task.
  */
-static void client_post_select(struct sched *s, struct task *t)
+static int client_post_select(struct sched *s, struct task *t)
 {
        struct client_task *ct = container_of(t, struct client_task, task);
        int ret = 0;
@@ -314,7 +319,7 @@ static void client_post_select(struct sched *s, struct task *t)
        if (ret < 0)
                goto out;
        if (ct->scc.fd < 0)
-               return;
+               return 0;
        switch (ct->status) {
        case CL_CONNECTED: /* receive welcome message */
                ret = read_nonblock(ct->scc.fd, buf, sizeof(buf), &s->rfds, &n);
@@ -327,17 +332,18 @@ static void client_post_select(struct sched *s, struct task *t)
                        goto out;
                }
                ct->status = CL_RECEIVED_WELCOME;
-               return;
+               return 0;
        case CL_RECEIVED_WELCOME: /* send auth command */
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
-                       return;
-               sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user);
+                       return 0;
+               sprintf(buf, AUTH_REQUEST_MSG "%s sideband%s", ct->user,
+                       has_feature("aes_ctr128", ct)? ",aes_ctr128" : "");
                PARA_INFO_LOG("--> %s\n", buf);
                ret = write_buffer(ct->scc.fd, buf);
                if (ret < 0)
                        goto out;
                ct->status = CL_SENT_AUTH;
-               return;
+               return 0;
        case CL_SENT_AUTH:
                /*
                 * Receive challenge and session keys, decrypt the challenge and
@@ -347,6 +353,7 @@ static void client_post_select(struct sched *s, struct task *t)
                /* 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)
@@ -365,13 +372,14 @@ static void client_post_select(struct sched *s, struct task *t)
                        goto out;
                ct->challenge_hash = para_malloc(HASH_SIZE);
                hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->challenge_hash);
-               ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN);
+               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);
+                       SESSION_KEY_LEN, use_aes);
                hash_to_asc(ct->challenge_hash, buf);
                PARA_INFO_LOG("--> %s\n", buf);
                ct->status = CL_RECEIVED_CHALLENGE;
-               return;
+               return 0;
                }
        case CL_RECEIVED_CHALLENGE:
                ret = send_sb(ct, 0, ct->challenge_hash, HASH_SIZE,
@@ -398,12 +406,12 @@ static void client_post_select(struct sched *s, struct task *t)
        case CL_RECEIVED_PROCEED: /* concat args and send command */
                {
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
-                       return;
+                       return 0;
                ret = send_sb_command(ct);
                if (ret <= 0)
                        goto out;
                ct->status = CL_EXECUTING;
-               return;
+               return 0;
                }
        case CL_SENDING:
                if (ct->btrn[1]) {
@@ -454,21 +462,21 @@ close1:
        PARA_INFO_LOG("channel 1: %s\n", para_strerror(-ret));
        btr_remove_node(&ct->btrn[1]);
        if (ct->btrn[0])
-               return;
+               return 0;
        goto out;
 close0:
        PARA_INFO_LOG("channel 0: %s\n", para_strerror(-ret));
        btr_remove_node(&ct->btrn[0]);
        if (ct->btrn[1] && ct->status == CL_SENDING)
-               return;
+               return 0;
 out:
        if (ret >= 0)
-               return;
+               return 0;
        btr_remove_node(&ct->btrn[0]);
        btr_remove_node(&ct->btrn[1]);
        if (ret != -E_SERVER_CMD_SUCCESS && ret != -E_SERVER_CMD_FAILURE)
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
-       t->error = ret;
+       return ret;
 }
 
 /**
@@ -517,6 +525,15 @@ err_out:
        return ret;
 }
 
+__noreturn static void print_help_and_die(struct client_task *ct)
+{
+       struct ggo_help h = DEFINE_GGO_HELP(client);
+       bool d = ct->conf.detailed_help_given;
+
+       ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+       exit(0);
+}
+
 /**
  * Parse a client configuration.
  *
@@ -547,7 +564,9 @@ int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr,
        ret = -E_CLIENT_SYNTAX;
        if (client_cmdline_parser(argc, argv, &ct->conf))
                goto out;
-       HANDLE_VERSION_FLAG("client", ct->conf);
+       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) :