struct audiod_command {
const char *name;
/* Pointer to the function that handles the command. */
+ /*
+ * Command handlers must never never close their file descriptor. A
+ * positive return value tells audiod that the status items have
+ * changed. In this case audiod will send an updated version of all
+ * status items to to each connected stat client.
+ */
audiod_command_handler_t *handler;
/* One-line description. */
const char *description;
continue;
b = (sc->flags & SCF_PARSER_FRIENDLY)? &pfpb : &pb;
if (!b->buf)
- (void)WRITE_STATUS_ITEM(b, item_num, "%s\n",
- msg? msg : "");
+ WRITE_STATUS_ITEM(b, item_num, "%s\n", msg? msg : "");
ret = write(sc->fd, b->buf, b->offset);
if (ret == b->offset)
continue;
{
int i, ret;
char *buf;
- const char *dflt = "No such command. Available commands:\n";
- if (argc < 2)
- return dump_commands(fd);
+ if (argc < 2) {
+ ret = dump_commands(fd);
+ goto out;
+ }
FOR_EACH_COMMAND(i) {
if (strcmp(audiod_cmds[i].name, argv[1]))
continue;
);
ret = client_write(fd, buf);
free(buf);
- return ret;
+ goto out;
}
- ret = client_write(fd, dflt);
+ ret = client_write(fd, "No such command. Available commands:\n");
if (ret > 0)
ret = dump_commands(fd);
- return ret;
+out:
+ return ret < 0? ret : 0;
}
static int com_tasks(int fd, __a_unused int argc, __a_unused char **argv)
if (tl)
ret = client_write(fd, tl);
free(tl);
- return ret;
+ return ret < 0? ret : 0;
}
static int com_stat(int fd, int argc, char **argv)
char *item = stat_item_values[i];
if (!((one << i) & mask))
continue;
- (void)WRITE_STATUS_ITEM(&b, i, "%s\n", item? item : "");
+ WRITE_STATUS_ITEM(&b, i, "%s\n", item? item : "");
}
ret = client_write(fd, b.buf);
if (ret >= 0)
ret = stat_client_add(fd, mask, parser_friendly);
free(b.buf);
- return ret;
+ return ret < 0? ret : 0;
}
static int com_grab(int fd, int argc, char **argv)
{
- return grab_client_new(fd, argc, argv, &sched);
+ int ret = grab_client_new(fd, argc, argv, &sched);
+ return ret < 0? ret : 0;
}
static int com_term(__a_unused int fd, __a_unused int argc, __a_unused char **argv)
msg = make_message("%s\n", version_single_line("audiod"));
ret = client_write(fd, msg);
free(msg);
- return ret;
-}
-
-static int check_perms(uid_t uid, uid_t *whitelist)
-{
- int i;
-
- if (!conf.user_allow_given)
- return 1;
- for (i = 0; i < conf.user_allow_given; i++)
- if (uid == whitelist[i])
- return 1;
- return -E_UCRED_PERM;
+ return ret < 0? ret : 0;
}
/**
*
* \param accept_fd The fd to accept connections on.
* \param rfds If \a accept_fd is not set in \a rfds, do nothing.
- * \param uid_whitelist Array of UIDs which are allowed to connect.
*
* 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,
*
* \sa para_accept(), recv_cred_buffer()
* */
-int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
+int handle_connect(int accept_fd, fd_set *rfds)
{
int i, argc, ret, clifd;
char buf[MAXLINE], **argv = NULL;
if (ret < 0)
goto out;
uid = ret;
- PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf);
- ret = check_perms(uid, uid_whitelist);
- if (ret < 0)
+ PARA_INFO_LOG("connection from UID %d, buf: %s\n", ret, buf);
+ ret = -E_UCRED_PERM;
+ if (!uid_is_whitelisted(uid))
goto out;
ret = create_argv(buf, "\n", &argv);
if (ret <= 0)