Merge branch 'refs/heads/t/openssl-header-check'
[paraslash.git] / command.c
index 25b92715497d74caa06d2d2b47a94ad473ce0ecd..481fd0f637352fb21ff97536d426ece42ec0fda3 100644 (file)
--- a/command.c
+++ b/command.c
@@ -16,6 +16,7 @@
 #include "server.lsg.h"
 #include "para.h"
 #include "error.h"
+#include "lsu.h"
 #include "crypt.h"
 #include "sideband.h"
 #include "command.h"
@@ -278,7 +279,7 @@ static int check_sender_args(struct command_context *cc,
 }
 
 /**
- * Send a sideband packet through a blocking file descriptor.
+ * Receive a sideband packet from a blocking file descriptor.
  *
  * \param scc fd and crypto keys.
  * \param expected_band The expected band designator.
@@ -552,63 +553,35 @@ out:
 }
 EXPORT_SERVER_CMD_HANDLER(stat);
 
-/* fixed-length, human readable permission string */
-const char *server_cmd_perms_str(unsigned int perms)
+const char *aux_info_cb(unsigned cmd_num, bool verbose)
 {
-       static char result[5];
-
-       result[0] = perms & AFS_READ? 'a' : '-';
-       result[1] = perms & AFS_WRITE? 'A' : '-';
-       result[2] = perms & VSS_READ? 'v' : '-';
-       result[3] = perms & VSS_WRITE? 'V' : '-';
-       result[4] = '\0';
-       return result;
-}
+       static char result[80];
+       unsigned perms = server_command_perms[cmd_num];
 
-static int send_list_of_commands(struct command_context *cc)
-{
-       int i;
-       const struct lls_command *cmd;
-       char *msg = para_strdup("");
-
-       for (i = 1; (cmd = lls_cmd(i, server_cmd_suite)); i++) {
-               const char *perms = server_cmd_perms_str(server_command_perms[i]);
-               char *tmp = make_message("%s%s\t%s\t%s\n", msg,
-                       lls_command_name(cmd), perms, lls_purpose(cmd));
-               free(msg);
-               msg = tmp;
+       if (verbose) {
+               /* permissions: VSS_READ | VSS_WRITE */
+               sprintf(result, "permissions: %s",
+                       server_command_perms_txt[cmd_num]);
+       } else {
+               result[0] = perms & AFS_READ? 'a' : '-';
+               result[1] = perms & AFS_WRITE? 'A' : '-';
+               result[2] = perms & VSS_READ? 'v' : '-';
+               result[3] = perms & VSS_WRITE? 'V' : '-';
+               result[4] = '\0';
        }
-       return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false);
+       return result;
 }
 
 static int com_help(struct command_context *cc, struct lls_parse_result *lpr)
 {
-       const char *perms;
-       char *long_help, *buf, *errctx;
+       char *buf;
        int ret;
-       const struct lls_command *cmd;
+       unsigned n;
+       bool long_help = SERVER_CMD_OPT_GIVEN(HELP, LONG, lpr);
 
-       ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx));
-       if (ret < 0) {
-               send_errctx(cc, errctx);
-               return ret;
-       }
-       if (lls_num_inputs(lpr) == 0)
-               return send_list_of_commands(cc);
-       /* argument given for help */
-       ret = lls(lls_lookup_subcmd(lls_input(0, lpr), server_cmd_suite,
-               &errctx));
-       if (ret < 0) {
-               send_errctx(cc, errctx);
-               return ret;
-       }
-       cmd = lls_cmd(ret, server_cmd_suite);
-       perms = server_command_perms_txt[ret];
-       long_help = lls_long_help(cmd);
-       assert(long_help);
-       ret = xasprintf(&buf, "%spermissions: %s\n", long_help, perms);
-       free(long_help);
-       return send_sb(&cc->scc, buf, ret, SBD_OUTPUT, false);
+       lsu_com_help(long_help, lpr, server_cmd_suite, aux_info_cb, &buf, &n);
+       ret = send_sb(&cc->scc, buf, n, SBD_OUTPUT, false);
+       return ret;
 }
 EXPORT_SERVER_CMD_HANDLER(help);
 
@@ -690,8 +663,7 @@ EXPORT_SERVER_CMD_HANDLER(nomore);
 static int com_ff(struct command_context *cc, struct lls_parse_result *lpr)
 {
        long promille;
-       int ret, backwards = 0;
-       unsigned i;
+       int i, ret;
        char c, *errctx;
 
        ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
@@ -699,20 +671,33 @@ static int com_ff(struct command_context *cc, struct lls_parse_result *lpr)
                send_errctx(cc, errctx);
                return ret;
        }
-       if (!(ret = sscanf(lls_input(0, lpr), "%u%c", &i, &c)))
-               return -E_COMMAND_SYNTAX;
-       if (ret > 1 && c == '-')
-               backwards = 1; /* jmp backwards */
+       ret = para_atoi32(lls_input(0, lpr), &i);
+       if (ret < 0) {
+               if (ret != -E_ATOI_JUNK_AT_END)
+                       return ret;
+               /*
+                * Compatibility code to keep the historic syntax (ff 30-)
+                * working. This can be removed after 0.7.0.
+                */
+               ret = sscanf(lls_input(0, lpr), "%i%c", &i, &c);
+               if (ret <= 0)
+                       return -E_COMMAND_SYNTAX;
+               if (ret > 1 && c == '-') {
+                       PARA_WARNING_LOG("use of obsolete syntax\n");
+                       i = -i;
+               }
+       }
        mutex_lock(mmd_mutex);
        ret = -E_NO_AUDIO_FILE;
        if (!mmd->afd.afhi.chunks_total || !mmd->afd.afhi.seconds_total)
                goto out;
        ret = 1;
        promille = (1000 * mmd->current_chunk) / mmd->afd.afhi.chunks_total;
-       if (backwards)
-               promille -= 1000 * i / mmd->afd.afhi.seconds_total;
-       else
-               promille += 1000 * i / mmd->afd.afhi.seconds_total;
+       /*
+        * We need this cast because without it the expression on the right
+        * hand side is of unsigned type.
+        */
+       promille += 1000 * i / (int)mmd->afd.afhi.seconds_total;
        if (promille < 0)
                promille = 0;
        if (promille > 1000) {