Merge branch 'maint'
[paraslash.git] / command.c
index e8f6948437aac8c0f03b538381afc5ea20b55fe4..fe4b92329b417009613e0f1034f747783699c2e0 100644 (file)
--- a/command.c
+++ b/command.c
@@ -75,20 +75,14 @@ static void dummy(__a_unused int s)
 {
 }
 
-static void mmd_dup(struct misc_meta_data *new_mmd)
-{
-       mutex_lock(mmd_mutex);
-       *new_mmd = *mmd;
-       mutex_unlock(mmd_mutex);
-}
-
 /*
- * Compute human readable string containing vss status for given integer value.
+ * Compute human readable vss status text.
  *
- * We don't want to use vss_playing() and friends here because we take a
- * snapshot of the mmd struct and use the copy for computing the state of the
- * vss. If the real data were used, we would take the mmd lock for a rather
- * long time or risk to get an inconsistent view.
+ * We can't call vss_playing() and friends here because those functions read
+ * the flags from the primary mmd structure, so calling them from command
+ * handler context would require to take the mmd lock. At the time the function
+ * is called we already took a copy of the mmd structure and want to use the
+ * flags value of the copy for computing the vss status text.
  */
 static char *vss_status_tohuman(unsigned int flags)
 {
@@ -167,9 +161,8 @@ static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
 static int check_sender_args(int argc, char * const * argv, struct sender_command_data *scd)
 {
        int i;
-       /* this has to match sender.h */
-       const char *subcmds[] = {"add", "delete", "allow", "deny", "on", "off", NULL};
 
+       const char *subcmds[] = {SENDER_SUBCOMMANDS NULL};
        scd->sender_num = -1;
        if (argc < 3)
                return -E_COMMAND_SYNTAX;
@@ -189,19 +182,19 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman
        if (!senders[scd->sender_num].client_cmds[scd->cmd_num])
                return -E_SENDER_CMD;
        switch (scd->cmd_num) {
-       case SENDER_ON:
-       case SENDER_OFF:
+       case SENDER_on:
+       case SENDER_off:
                if (argc != 3)
                        return -E_COMMAND_SYNTAX;
                break;
-       case SENDER_DENY:
-       case SENDER_ALLOW:
+       case SENDER_deny:
+       case SENDER_allow:
                if (argc != 4 || parse_cidr(argv[3], scd->host,
                                sizeof(scd->host), &scd->netmask) == NULL)
                        return -E_COMMAND_SYNTAX;
                break;
-       case SENDER_ADD:
-       case SENDER_DELETE:
+       case SENDER_add:
+       case SENDER_delete:
                if (argc != 4)
                        return -E_COMMAND_SYNTAX;
                return parse_fec_url(argv[3], scd);
@@ -364,8 +357,8 @@ static int com_sender(struct command_context *cc)
        }
 
        switch (scd.cmd_num) {
-       case SENDER_ADD:
-       case SENDER_DELETE:
+       case SENDER_add:
+       case SENDER_delete:
                assert(senders[scd.sender_num].resolve_target);
                ret = senders[scd.sender_num].resolve_target(cc->argv[3], &scd);
                if (ret < 0)
@@ -480,7 +473,7 @@ static unsigned empty_status_items(int parser_friendly, char **result)
                        #define ITEM(x) "0004 %02x:\n"
                        EMPTY_STATUS_ITEMS
                        #undef ITEM
-                       #define ITEM(x) , SI_ ## x
+                       #define ITEM(x) , (unsigned) SI_ ## x
                        EMPTY_STATUS_ITEMS
                        #undef ITEM
                );
@@ -532,7 +525,13 @@ static int com_stat(struct command_context *cc)
        if (i != cc->argc)
                return -E_COMMAND_SYNTAX;
        for (;;) {
-               mmd_dup(nmmd);
+               /*
+                * Copy the mmd structure to minimize the time we hold the mmd
+                * lock.
+                */
+               mutex_lock(mmd_mutex);
+               *nmmd = *mmd;
+               mutex_unlock(mmd_mutex);
                ret = get_status(nmmd, parser_friendly, &s);
                ret = send_sb(&cc->scc, s, ret, SBD_OUTPUT, false);
                if (ret < 0)
@@ -768,7 +767,7 @@ static int com_jmp(struct command_context *cc)
                i = 100;
        PARA_INFO_LOG("jumping to %lu%%\n", i);
        mmd->repos_request = (mmd->afd.afhi.chunks_total * i + 50) / 100;
-       PARA_INFO_LOG("sent: %lu, offset before jmp: %lu\n",
+       PARA_INFO_LOG("sent: %lu, offset before jmp: %li\n",
                mmd->chunks_sent, mmd->offset);
        mmd->new_vss_status_flags |= VSS_REPOS;
        mmd->new_vss_status_flags &= ~VSS_NEXT;
@@ -808,7 +807,6 @@ static void reset_signals(void)
 }
 
 struct connection_features {
-       bool sideband_requested;
        bool aes_ctr128_requested;
 };
 
@@ -836,8 +834,8 @@ static int parse_auth_request(char *buf, int len, struct user **u,
                create_argv(p, ",", &features);
                for (i = 0; features[i]; i++) {
                        if (strcmp(features[i], "sideband") == 0)
-                               cf->sideband_requested = true;
-                       else if (strcmp(features[i], "aes_ctr128") == 0)
+                               continue;
+                       if (strcmp(features[i], "aes_ctr128") == 0)
                                cf->aes_ctr128_requested = true;
                        else {
                                ret = -E_BAD_FEATURE;
@@ -950,11 +948,6 @@ __noreturn void handle_connect(int fd, const char *peername)
        ret = parse_auth_request(buf, ret, &cc->u, &cf);
        if (ret < 0)
                goto net_err;
-       if (!cf.sideband_requested) { /* sideband is mandatory */
-               PARA_ERROR_LOG("client did not request sideband\n");
-               ret = -E_BAD_FEATURE;
-               goto net_err;
-       }
        if (cc->u) {
                get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
                ret = pub_encrypt(cc->u->pubkey, rand_buf, sizeof(rand_buf),
@@ -971,7 +964,7 @@ __noreturn void handle_connect(int fd, const char *peername)
                numbytes = 256;
                get_random_bytes_or_die((unsigned char *)buf, numbytes);
        }
-       PARA_DEBUG_LOG("sending %u byte challenge + session key (%zu bytes)\n",
+       PARA_DEBUG_LOG("sending %d byte challenge + session key (%zu bytes)\n",
                CHALLENGE_SIZE, numbytes);
        ret = send_sb(&cc->scc, buf, numbytes, SBD_CHALLENGE, false);
        buf = NULL;