summaryrefslogtreecommitdiff
path: root/recv_common.c
blob: 021595a1c4e20af45a09c94d3f7570b947f36e2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* SPDX-License-Identifier: GPL-2.0 */

/** \file recv_common.c common functions of para_recv and para_audiod */

#include <inttypes.h>
#include <lopsub.h>

#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;
}