Merge branch 't/sync'
[paraslash.git] / client_common.c
index 3ff43d1b7bffd2c1c2438078d431122ea9f6942d..6652cc35477234a9dd4a9f0621be953c5cc9ba00 100644 (file)
@@ -6,14 +6,18 @@
 
 /** \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,17 @@ 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;
+                       return 0;
                sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user);
                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
@@ -371,7 +376,7 @@ static void client_post_select(struct sched *s, struct task *t)
                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 +403,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 +459,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 +522,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 +561,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) :