/* SPDX-License-Identifier: GPL-2.0 */ /** \file recv_common.c common functions of para_recv and para_audiod */ #include #include #include "recv_cmd.lsg.h" #include "para.h" #include "error.h" #include "list.h" #include "sched.h" #include "buffer_tree.h" #include "recv.h" #include "string.h" /** * Check if the given string is a valid receiver specifier. * * \param ra string of the form receiver_name [options...] * \param lprp Filled in on success, undefined else. * * This function checks whether \a ra starts with the name of a receiver, * optionally followed by options for that receiver. If a valid receiver name * was found the remaining part of \a ra is passed to the receiver's config * parser. * * If a NULL pointer or an empty string is passed as the first argument, the * hhtp receiver with no options is assumed. * * \return On success the number of the receiver is returned. On errors, the * function calls exit(EXIT_FAILURE). */ int check_receiver_arg(const char *ra, struct lls_parse_result **lprp) { int ret, argc, receiver_num; char *errctx = NULL, **argv; const struct lls_command *cmd; *lprp = NULL; if (!ra || !*ra) { argc = 1; argv = alloc(2 * sizeof(char*)); argv[0] = para_strdup("http"); argv[1] = NULL; } else { ret = create_argv(ra, " \t\n", &argv); if (ret < 0) { PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(EXIT_FAILURE); } argc = ret; } ret = lls(lls_lookup_subcmd(argv[0], recv_cmd_suite, &errctx)); if (ret < 0) { PARA_EMERG_LOG("%s: %s\n", errctx? errctx : argv[0], para_strerror(-ret)); exit(EXIT_FAILURE); } receiver_num = ret; cmd = RECV_CMD(receiver_num); ret = lls(lls_parse(argc, argv, cmd, lprp, &errctx)); if (ret < 0) { if (errctx) PARA_ERROR_LOG("%s\n", errctx); PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(EXIT_FAILURE); } ret = receiver_num; free_argv(argv); return ret; } #define FOR_EACH_RECEIVER(i) for (i = 1; lls_cmd(i, recv_cmd_suite); i++) /** * Print out the help texts to all receivers. * * \param detailed Whether to print the short or the detailed help. */ void print_receiver_helps(bool detailed) { int i; printf("\nAvailable receivers: "); FOR_EACH_RECEIVER(i) { const struct lls_command *cmd = RECV_CMD(i); printf("%s%s", i? " " : "", lls_command_name(cmd)); } printf("\n\n"); FOR_EACH_RECEIVER(i) { const struct lls_command *cmd = RECV_CMD(i); char *help = detailed? lls_long_help(cmd) : lls_short_help(cmd); if (!help) continue; printf("%s\n", help); free(help); } } /** * Request a minimal timeout in case of buffer tree errors. * * \param s The scheduler instance. * \param rn The buffer tree node is derived from this. * * If the buffer tree node of the given receiver node is in error or EOF state, * a minimal I/O timeout is requested from the scheduler. Otherwise, the * function does nothing. No file descriptors are asked to be monitored. * * \return The status of of the receiver node's buffer tree node. That is, the * return value of the underlying call to \ref btr_node_status(). */ int generic_recv_pre_monitor(struct sched *s, struct receiver_node *rn) { int ret = btr_node_status(rn->btrn, 0, BTR_NT_ROOT); if (ret < 0) sched_min_delay(s); return ret; }