31fd81f1ec52c3d0b6204e8b3663a7d36e14fbb3
[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  * Check if the given string is a valid receiver specifier.
20  *
21  * \param ra string of the form receiver_name [options...]
22  * \param lprp Filled in on success, undefined else.
23  *
24  * This function checks whether \a ra starts with the name of a receiver,
25  * optionally followed by options for that receiver. If a valid receiver name
26  * was found the remaining part of \a ra is passed to the receiver's config
27  * parser.
28  *
29  * If a NULL pointer or an empty string is passed as the first argument, the
30  * hhtp receiver with no options is assumed.
31  *
32  * \return On success the number of the receiver is returned. On errors, the
33  * function calls exit(EXIT_FAILURE).
34  */
35 int check_receiver_arg(const char *ra, struct lls_parse_result **lprp)
36 {
37         int ret, argc, receiver_num;
38         char *errctx = NULL, **argv;
39         const struct lls_command *cmd;
40
41         *lprp = NULL;
42         if (!ra || !*ra) {
43                 argc = 1;
44                 argv = para_malloc(2 * sizeof(char*));
45                 argv[0] = para_strdup("http");
46                 argv[1] = NULL;
47         } else {
48                 ret = create_argv(ra, " \t\n", &argv);
49                 if (ret < 0) {
50                         PARA_EMERG_LOG("%s\n", para_strerror(-ret));
51                         exit(EXIT_FAILURE);
52                 }
53                 argc = ret;
54         }
55         ret = lls(lls_lookup_subcmd(argv[0], recv_cmd_suite, &errctx));
56         if (ret < 0) {
57                 PARA_EMERG_LOG("%s: %s\n", errctx? errctx : argv[0],
58                         para_strerror(-ret));
59                 exit(EXIT_FAILURE);
60         }
61         receiver_num = ret;
62         cmd = RECV_CMD(receiver_num);
63         ret = lls(lls_parse(argc, argv, cmd, lprp, &errctx));
64         if (ret < 0) {
65                 if (errctx)
66                         PARA_ERROR_LOG("%s\n", errctx);
67                 PARA_EMERG_LOG("%s\n", para_strerror(-ret));
68                 exit(EXIT_FAILURE);
69         }
70         ret = receiver_num;
71         free_argv(argv);
72         return ret;
73 }
74
75 /**
76  * Print out the help texts to all receivers.
77  *
78  * \param detailed Whether to print the short or the detailed help.
79  */
80 void print_receiver_helps(bool detailed)
81 {
82         int i;
83
84         printf("\nAvailable receivers: ");
85         FOR_EACH_RECEIVER(i) {
86                 const struct lls_command *cmd = RECV_CMD(i);
87                 printf("%s%s", i? " " : "", lls_command_name(cmd));
88         }
89         printf("\n\n");
90         FOR_EACH_RECEIVER(i) {
91                 const struct lls_command *cmd = RECV_CMD(i);
92                 char *help = detailed? lls_long_help(cmd) : lls_short_help(cmd);
93                 if (!help)
94                         continue;
95                 printf("%s\n", help);
96                 free(help);
97         }
98 }
99
100 /**
101  * Simple pre-select hook, used by all receivers.
102  *
103  * \param s Scheduler info.
104  * \param rn The receiver node.
105  *
106  * This requests a minimal delay from the scheduler if the status of the buffer
107  * tree node indicates an error/eof condition. No file descriptors are added to
108  * the fd sets of \a s.
109  *
110  * \return The status of the btr node of the receiver node, i.e. the return
111  * value of the underlying call to \ref btr_node_status().
112  */
113 int generic_recv_pre_select(struct sched *s, struct receiver_node *rn)
114 {
115         int ret = btr_node_status(rn->btrn, 0, BTR_NT_ROOT);
116
117         if (ret < 0)
118                 sched_min_delay(s);
119         return ret;
120 }