paraslash 0.7.3
[paraslash.git] / audiod_command.c
index a6a49b7461d818b36a12b2eee0f30fbf359b3ed9..5f0b35a5dc0f3e4f02d134faa2ef828c6b357763 100644 (file)
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file audiod_command.c Commands for para_audiod. */
 
@@ -17,6 +13,7 @@
 
 #include "audiod.lsg.h"
 #include "para.h"
+#include "lsu.h"
 #include "audiod_cmd.lsg.h"
 #include "list.h"
 #include "sched.h"
@@ -84,27 +81,12 @@ static int num_clients;
 /** The list of all status items used by para_{server,audiod,gui}. */
 const char *status_item_list[] = {STATUS_ITEMS};
 
-static void dump_stat_client_list(void)
-{
-       struct stat_client *sc;
-
-       list_for_each_entry(sc, &client_list, node)
-               PARA_INFO_LOG("stat client on fd %d\n", sc->fd);
-}
-/**
- * Add a status client to the list.
- *
- * \param fd The file descriptor of the client.
- * \param mask Bitfield of status items for this client.
- * \param parser_friendly Enable parser-friendly output mode.
- *
- * Only those status items having the bit set in \a mask will be
- * sent to the client.
+/*
+ * Add a status client to the global client list and increment num_clients.
  *
- * \return Positive value on success, or -E_TOO_MANY_CLIENTS if
- * the number of connected clients exceeds #MAX_STAT_CLIENTS.
+ * The mask parameter specifies which status items are sent to the client.
  */
-static int stat_client_add(int fd, uint64_t mask, int parser_friendly)
+static int stat_client_add(int fd, uint64_t mask, bool parser_friendly)
 {
        struct stat_client *new_client;
        int ret;
@@ -117,14 +99,13 @@ static int stat_client_add(int fd, uint64_t mask, int parser_friendly)
        ret = dup(fd);
        if (ret < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
-       new_client = para_calloc(sizeof(*new_client));
+       new_client = zalloc(sizeof(*new_client));
        new_client->fd = ret;
        PARA_INFO_LOG("adding client on fd %d\n", new_client->fd);
        new_client->item_mask = mask;
        if (parser_friendly)
                new_client->flags = SCF_PARSER_FRIENDLY;
        para_list_add(&new_client->node, &client_list);
-       dump_stat_client_list();
        num_clients++;
        return 1;
 }
@@ -183,20 +164,12 @@ void stat_client_write_item(int item_num)
                        continue;
                /* write error or short write */
                close_stat_client(sc);
-               dump_stat_client_list();
        }
        free(pb.buf);
        free(pfpb.buf);
 }
 
-/**
- * Check if string is a known status item.
- *
- * \param item Buffer containing the text to check.
- *
- * \return If \a item is a valid status item, the number of that status item is
- * returned. Otherwise, this function returns \p -E_UNKNOWN_STAT_ITEM.
- */
+/* Check if the given string is a known status item and return its index. */
 static int stat_item_valid(const char *item)
 {
        int i;
@@ -228,62 +201,56 @@ __malloc static char *audiod_status_string(void)
        return para_strdup(status);
 }
 
-static int dump_commands(int fd)
+static int com_help(int fd, struct lls_parse_result *lpr)
 {
-       char *buf = para_strdup(""), *tmp = NULL;
-       int i;
-       ssize_t ret;
-       const struct lls_command *cmd;
+       char *buf;
+       int ret;
+       const struct lls_opt_result *r =
+               lls_opt_result(LSG_AUDIOD_CMD_HELP_OPT_LONG, lpr);
+       bool long_help = lls_opt_given(r);
 
-       for (i = 1; (cmd = lls_cmd(i, audiod_cmd_suite)); i++) {
-               tmp = make_message("%s%s\t%s\n", buf, lls_command_name(cmd),
-                       lls_purpose(cmd));
-               free(buf);
-               buf = tmp;
-       }
+       lsu_com_help(long_help, lpr, audiod_cmd_suite, NULL, &buf, NULL);
        ret = client_write(fd, buf);
        free(buf);
-       return ret;
+       return ret < 0? ret : 0;
 }
+EXPORT_AUDIOD_CMD_HANDLER(help)
 
-static int com_help(int fd, struct lls_parse_result *lpr)
+static int com_ll(int fd, struct lls_parse_result *lpr)
 {
-       int ret;
-       char *buf, *errctx;
-       const struct lls_command *cmd;
+       unsigned ll;
+       char *errctx;
+       const char *sev[] = {SEVERITIES};
+       const char *arg;
+       int ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx));
 
-       ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx));
        if (ret < 0) {
-               if (errctx) {
-                       buf = make_message("%s\n", errctx);
-                       client_write(fd, buf);
-                       free(buf);
-                       free(errctx);
-               }
+               char *tmp = make_message("%s\n", errctx);
+               free(errctx);
+               client_write(fd, tmp);
+               free(tmp);
                return ret;
        }
-       if (lls_num_inputs(lpr) == 0)
-               return dump_commands(fd);
-       ret = lls(lls_lookup_subcmd(lls_input(0, lpr), audiod_cmd_suite,
-               &errctx));
-       if (ret < 0) {
-               buf = make_message("%s: %s\nAvailable commands:\n", errctx?
-                       errctx : lls_input(0, lpr), para_strerror(-ret));
-               if (client_write(fd, buf) >= 0)
-                       dump_commands(fd);
-               free(errctx);
-               free(buf);
-               goto out;
+       if (lls_num_inputs(lpr) == 0) {
+               char *msg;
+               ll = daemon_get_loglevel();
+               msg = make_message("%s\n", sev[ll]);
+               ret = client_write(fd, msg);
+               free(msg);
+               return ret;
        }
-       cmd = lls_cmd(ret, audiod_cmd_suite);
-       buf = lls_long_help(cmd);
-       assert(buf);
-       ret = client_write(fd, buf);
-       free(buf);
-out:
-       return ret < 0? ret : 0;
+       arg = lls_input(0, lpr);
+       for (ll = 0; ll < NUM_LOGLEVELS; ll++) {
+               if (!strcmp(arg, sev[ll]))
+                       break;
+       }
+       if (ll >= NUM_LOGLEVELS)
+               return -ERRNO_TO_PARA_ERROR(EINVAL);
+       PARA_INFO_LOG("new log level: %s\n", sev[ll]);
+       daemon_set_loglevel(ll);
+       return 1;
 }
-EXPORT_AUDIOD_CMD_HANDLER(help)
+EXPORT_AUDIOD_CMD_HANDLER(ll)
 
 static int com_tasks(int fd, __a_unused struct lls_parse_result *lpr)
 {
@@ -300,7 +267,8 @@ EXPORT_AUDIOD_CMD_HANDLER(tasks)
 
 static int com_stat(int fd, struct lls_parse_result *lpr)
 {
-       int i, ret, parser_friendly = 0;
+       int i, ret;
+       bool parser_friendly = false;
        uint64_t mask = 0;
        const uint64_t one = 1;
        struct para_buffer b = {.flags = 0};
@@ -312,7 +280,7 @@ static int com_stat(int fd, struct lls_parse_result *lpr)
                return ret;
        r = lls_opt_result(LSG_AUDIOD_CMD_STAT_OPT_PARSER_FRIENDLY, lpr);
        if (lls_opt_given(r) > 0) {
-               parser_friendly = 1;
+               parser_friendly = true;
                b.flags = PBF_SIZE_PREFIX;
        }
        num_inputs = lls_num_inputs(lpr);
@@ -405,10 +373,9 @@ EXPORT_AUDIOD_CMD_HANDLER(version)
  * Handle arriving connections on the local socket.
  *
  * \param accept_fd The fd to accept connections on.
- * \param rfds If \a accept_fd is not set in \a rfds, do nothing.
  *
- * This is called in each iteration of the select loop. If there is an incoming
- * connection on \a accept_fd, this function reads the command sent by the peer,
+ * This is called in each iteration of the main loop of the scheduler. If there
+ * is an incoming connection, the function reads the command sent by the peer,
  * checks the connecting user's permissions by using unix socket credentials
  * (if supported by the OS) and calls the corresponding command handler if
  * permissions are OK.
@@ -417,8 +384,8 @@ EXPORT_AUDIOD_CMD_HANDLER(version)
  * connection to accept.
  *
  * \sa \ref para_accept(), \ref recv_cred_buffer().
- * */
-int handle_connect(int accept_fd, fd_set *rfds)
+ */
+int dispatch_local_connection(int accept_fd)
 {
        int argc, ret, clifd;
        char buf[MAXLINE], **argv = NULL;
@@ -429,7 +396,7 @@ int handle_connect(int accept_fd, fd_set *rfds)
        char *errctx = NULL;
        const struct audiod_command_info *aci;
 
-       ret = para_accept(accept_fd, rfds, &unix_addr, sizeof(struct sockaddr_un), &clifd);
+       ret = para_accept(accept_fd, &unix_addr, sizeof(struct sockaddr_un), &clifd);
        if (ret <= 0)
                return ret;
        ret = recv_cred_buffer(clifd, buf, sizeof(buf) - 1);