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