client: Fix typo in comment.
[paraslash.git] / client_common.c
index daead879faa7f4dff4d9016c68f95426269551f0..f4b09cd23c2eeedf7974583f3bf2cf145c993fc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1997-2012 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2013 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -13,7 +13,6 @@
 #include "error.h"
 #include "list.h"
 #include "sched.h"
-#include "client.cmdline.h"
 #include "crypt.h"
 #include "net.h"
 #include "fd.h"
 #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().
@@ -44,12 +43,12 @@ void client_disconnect(struct client_task *ct)
        if (ct->scc.fd >= 0)
                close(ct->scc.fd);
        free_argv(ct->features);
+       ct->features = NULL;
        sc_free(ct->scc.recv);
        ct->scc.recv = NULL;
        sc_free(ct->scc.send);
        ct->scc.send = NULL;
-       btr_free_node(ct->btrn);
-       ct->btrn = NULL;
+       btr_remove_node(&ct->btrn);
 }
 
 /**
@@ -242,14 +241,19 @@ static char **parse_features(char *buf)
 
 static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb)
 {
-       int ret, ll;
+       int ret;
+       const char *designator[] = {SB_DESIGNATORS_ARRAY};
 
-       if (!sbb || !sbb->iov.iov_base || sbb->iov.iov_len == 0)
+       if (!sbb)
                return 0;
+       if (sbb->band < NUM_SB_DESIGNATORS)
+               PARA_DEBUG_LOG("band: %s\n", designator[sbb->band]);
 
        switch (sbb->band) {
        case SBD_OUTPUT:
-               btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len, ct->btrn);
+               if (iov_valid(&sbb->iov))
+                       btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len,
+                               ct->btrn);
                ret = 1;
                goto out;
        case SBD_DEBUG_LOG:
@@ -259,10 +263,18 @@ static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb)
        case SBD_ERROR_LOG:
        case SBD_CRIT_LOG:
        case SBD_EMERG_LOG:
-               ll = sbb->band - SBD_DEBUG_LOG;
-               para_log(ll, "remote: %s", (char *)sbb->iov.iov_base);
+               if (iov_valid(&sbb->iov)) {
+                       int ll = sbb->band - SBD_DEBUG_LOG;
+                       para_log(ll, "remote: %s", (char *)sbb->iov.iov_base);
+               }
                ret = 1;
                goto deallocate;
+       case SBD_EXIT__SUCCESS:
+               ret = -E_SERVER_CMD_SUCCESS;
+               goto deallocate;
+       case SBD_EXIT__FAILURE:
+               ret = -E_SERVER_CMD_FAILURE;
+               goto deallocate;
        default:
                PARA_ERROR_LOG("invalid band %d\n", sbb->band);
                ret = -E_BAD_BAND;
@@ -313,7 +325,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);
        struct btr_node *btrn = ct->btrn;
@@ -321,9 +333,11 @@ static void client_post_select(struct sched *s, struct task *t)
        size_t n;
        char buf[CLIENT_BUFSIZE];
 
-       t->error = 0;
+       ret = task_get_notification(t);
+       if (ret < 0)
+               goto out;
        if (ct->scc.fd < 0)
-               return;
+               return 0;
        switch (ct->status) {
        case CL_CONNECTED: /* receive welcome message */
                ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n);
@@ -331,10 +345,10 @@ static void client_post_select(struct sched *s, struct task *t)
                        goto out;
                ct->features = parse_features(buf);
                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;
                if (has_feature("sideband", ct)) {
                        ct->use_sideband = true;
                        sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user);
@@ -345,7 +359,7 @@ static void client_post_select(struct sched *s, struct task *t)
                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
@@ -391,7 +405,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:
                if (ct->use_sideband) {
@@ -432,20 +446,20 @@ static void client_post_select(struct sched *s, struct task *t)
                if (!strstr(buf, PROCEED_MSG))
                        goto out;
                ct->status = CL_RECEIVED_PROCEED;
-               return;
+               return 0;
                }
        case CL_RECEIVED_PROCEED: /* concat args and send command */
                {
                int i;
                char *command = NULL;
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
-                       return;
+                       return 0;
                if (ct->use_sideband) {
                        ret = send_sb_command(ct);
                        if (ret <= 0)
                                goto out;
                        ct->status = CL_SENT_COMMAND;
-                       return;
+                       return 0;
                }
                for (i = 0; i < ct->conf.inputs_num; i++) {
                        char *tmp = command;
@@ -460,7 +474,7 @@ static void client_post_select(struct sched *s, struct task *t)
                if (ret < 0)
                        goto out;
                ct->status = CL_SENT_COMMAND;
-               return;
+               return 0;
                }
        case CL_SENT_COMMAND:
                {
@@ -486,7 +500,7 @@ static void client_post_select(struct sched *s, struct task *t)
                        if (strstr(buf2, AWAITING_DATA_MSG)) {
                                free(buf2);
                                ct->status = CL_SENDING;
-                               return;
+                               return 0;
                        }
                        ct->status = CL_RECEIVING;
                        btr_add_output(buf2, n, btrn);
@@ -502,15 +516,15 @@ static void client_post_select(struct sched *s, struct task *t)
                if (ret < 0)
                        goto out;
                if (ret == 0)
-                       return;
+                       return 0;
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
-                       return;
+                       return 0;
                sz = btr_next_buffer(btrn, &buf2);
                ret = sc_send_bin_buffer(&ct->scc, buf2, sz);
                if (ret < 0)
                        goto out;
                btr_consume(btrn, sz);
-               return;
+               return 0;
                }
        case CL_RECEIVING:
                {
@@ -519,13 +533,13 @@ static void client_post_select(struct sched *s, struct task *t)
                if (ret < 0)
                        goto out;
                if (ret == 0)
-                       return;
+                       return 0;
                /*
                 * The FD_ISSET() is not strictly necessary, but is allows us
                 * to skip the malloc below if there is nothing to read anyway.
                 */
                if (!FD_ISSET(ct->scc.fd, &s->rfds))
-                       return;
+                       return 0;
                if (ct->use_sideband) {
                        struct sb_buffer sbb;
                        ret = recv_sb(ct, &s->rfds, &sbb);
@@ -544,12 +558,13 @@ static void client_post_select(struct sched *s, struct task *t)
                }
        }
 out:
-       t->error = ret;
        if (ret < 0) {
-               if (ret != -E_SERVER_EOF && ret != -E_BTR_EOF && ret != -E_EOF)
-                       PARA_ERROR_LOG("%s\n", para_strerror(-t->error));
-               btr_remove_node(btrn);
+               if (!ct->use_sideband && ret != -E_SERVER_EOF &&
+                               ret != -E_BTR_EOF && ret != -E_EOF)
+                       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+               btr_remove_node(&ct->btrn);
        }
+       return ret;
 }
 
 /**