compress: Fix off by one in help of --target-level.
[paraslash.git] / recv_common.c
1 /* Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /** \file recv_common.c common functions of para_recv and para_audiod */
4
5 #include <regex.h>
6 #include <inttypes.h>
7 #include <lopsub.h>
8
9 #include "recv_cmd.lsg.h"
10 #include "para.h"
11 #include "error.h"
12 #include "list.h"
13 #include "sched.h"
14 #include "buffer_tree.h"
15 #include "recv.h"
16 #include "string.h"
17
18 /**
19  * Call the init function of each paraslash receiver.
20  *
21  * Receivers employ the user_data feature of the lopsub library: Each receiver
22  * of the recv_cmd suite defines a struct receiver as its user data.
23  * recv_init() obtains a pointer to this structure by calling lls_user_data().
24  * If the receiver has an init function (i.e., if ->init is not NULL), ->init()
25  * is called to initialize the receiver.
26  */
27 void recv_init(void)
28 {
29         int i;
30
31         FOR_EACH_RECEIVER(i) {
32                 const struct lls_command *cmd = RECV_CMD(i);
33                 const struct receiver *r = lls_user_data(cmd);
34                 if (r && r->init)
35                         r->init();
36         }
37 }
38
39 /**
40  * Check if the given string is a valid receiver specifier.
41  *
42  * \param ra string of the form receiver_name [options...]
43  * \param lprp Filled in on success, undefined else.
44  *
45  * This function checks whether \a ra starts with the name of a receiver,
46  * optionally followed by options for that receiver. If a valid receiver name
47  * was found the remaining part of \a ra is passed to the receiver's config
48  * parser.
49  *
50  * If a NULL pointer or an empty string is passed as the first argument, the
51  * hhtp receiver with no options is assumed.
52  *
53  * \return On success the number of the receiver is returned. On errors, the
54  * function calls exit(EXIT_FAILURE).
55  */
56 int check_receiver_arg(const char *ra, struct lls_parse_result **lprp)
57 {
58         int ret, argc, receiver_num;
59         char *errctx = NULL, **argv;
60         const struct lls_command *cmd;
61
62         *lprp = NULL;
63         if (!ra || !*ra) {
64                 argc = 1;
65                 argv = para_malloc(2 * sizeof(char*));
66                 argv[0] = para_strdup("http");
67                 argv[1] = NULL;
68         } else {
69                 ret = create_argv(ra, " \t\n", &argv);
70                 if (ret < 0) {
71                         PARA_EMERG_LOG("%s\n", para_strerror(-ret));
72                         exit(EXIT_FAILURE);
73                 }
74                 argc = ret;
75         }
76         ret = lls(lls_lookup_subcmd(argv[0], recv_cmd_suite, &errctx));
77         if (ret < 0) {
78                 PARA_EMERG_LOG("%s: %s\n", errctx? errctx : argv[0],
79                         para_strerror(-ret));
80                 exit(EXIT_FAILURE);
81         }
82         receiver_num = ret;
83         cmd = RECV_CMD(receiver_num);
84         ret = lls(lls_parse(argc, argv, cmd, lprp, &errctx));
85         if (ret < 0) {
86                 if (errctx)
87                         PARA_ERROR_LOG("%s\n", errctx);
88                 PARA_EMERG_LOG("%s\n", para_strerror(-ret));
89                 exit(EXIT_FAILURE);
90         }
91         ret = receiver_num;
92         free_argv(argv);
93         return ret;
94 }
95
96 /**
97  * Print out the help texts to all receivers.
98  *
99  * \param detailed Whether to print the short or the detailed help.
100  */
101 void print_receiver_helps(bool detailed)
102 {
103         int i;
104
105         printf("\nAvailable receivers: ");
106         FOR_EACH_RECEIVER(i) {
107                 const struct lls_command *cmd = RECV_CMD(i);
108                 printf("%s%s", i? " " : "", lls_command_name(cmd));
109         }
110         printf("\n\n");
111         FOR_EACH_RECEIVER(i) {
112                 const struct lls_command *cmd = RECV_CMD(i);
113                 char *help = detailed? lls_long_help(cmd) : lls_short_help(cmd);
114                 if (!help)
115                         continue;
116                 printf("%s\n", help);
117                 free(help);
118         }
119 }
120
121 /**
122  * Simple pre-select hook, used by all receivers.
123  *
124  * \param s Scheduler info.
125  * \param rn The receiver node.
126  *
127  * This requests a minimal delay from the scheduler if the status of the buffer
128  * tree node indicates an error/eof condition. No file descriptors are added to
129  * the fd sets of \a s.
130  *
131  * \return The status of the btr node of the receiver node, i.e. the return
132  * value of the underlying call to \ref btr_node_status().
133  */
134 int generic_recv_pre_select(struct sched *s, struct receiver_node *rn)
135 {
136         int ret = btr_node_status(rn->btrn, 0, BTR_NT_ROOT);
137
138         if (ret < 0)
139                 sched_min_delay(s);
140         return ret;
141 }