- for (;;) {
- int max_fileno = -1, check_write = 0;
- ssize_t len;
- fd_set rfd, wfd;
- FD_ZERO(&rfd);
- FD_ZERO(&wfd);
- if (loaded < conf.bufsize_arg)
- para_fd_set(fd, &rfd, &max_fileno);
- if (loaded > 0) {
- para_fd_set(STDOUT_FILENO, &wfd, &max_fileno);
- check_write = 1;
- }
- ret = -E_AUDIOC_OVERRUN;
- if (max_fileno < 0)
- goto out;
- ret = para_select(max_fileno + 1, &rfd, &wfd, NULL);
- if (ret < 0)
- goto out;
- if (loaded < conf.bufsize_arg && FD_ISSET(fd, &rfd)) {
- len = recv_bin_buffer(fd, buf + loaded,
- conf.bufsize_arg - loaded);
- if (len <= 0) {
- ret = len < 0? -E_AUDIOC_READ : 0;
+ para_log = i9e_log;
+ ret = schedule(&sched);
+ sched_shutdown(&sched);
+ i9e_close();
+ para_log = stderr_log;
+out:
+ free(history_file);
+ free(socket_name);
+ if (ret < 0)
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+ exit(ret < 0? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+__noreturn static void print_completions(void)
+{
+ int ret = i9e_print_completions(audiod_completers);
+ exit(ret <= 0? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+#else /* HAVE_READLINE */
+
+__noreturn static void interactive_session(void)
+{
+ PARA_EMERG_LOG("interactive sessions not available\n");
+ exit(EXIT_FAILURE);
+}
+
+__noreturn static void print_completions(void)
+{
+ PARA_EMERG_LOG("command completion not available\n");
+ exit(EXIT_FAILURE);
+}
+
+#endif /* HAVE_READLINE */
+
+static char *configfile_exists(void)
+{
+ char *config_file;
+ char *home = para_homedir();
+
+ config_file = make_message("%s/.paraslash/audioc.conf", home);
+ free(home);
+ if (file_exists(config_file))
+ return config_file;
+ free(config_file);
+ return NULL;
+}
+
+static void handle_help_flag(void)
+{
+ char *help;
+
+ if (OPT_GIVEN(DETAILED_HELP))
+ help = lls_long_help(CMD_PTR);
+ else if (OPT_GIVEN(HELP))
+ help = lls_short_help(CMD_PTR);
+ else
+ return;
+ printf("%s\n", help);
+ free(help);
+ exit(EXIT_SUCCESS);
+}
+
+/**
+ * The client program to connect to para_audiod.
+ *
+ * \param argc Usual argument count.
+ * \param argv Usual argument vector.
+ *
+ * It connects to the "well-known" local socket to communicate with
+ * para_audiod. Authentication is performed by sending a ucred buffer
+ * containing the user id to the local socket.
+ *
+ * Any data received from the socket is written to stdout.
+ *
+ * \return EXIT_SUCCESS or EXIT_FAILURE.
+ *
+ * \sa \ref send_cred_buffer(), para_audioc(1), para_audiod(1).
+ */
+int main(int argc, char *argv[])
+{
+ const struct lls_command *cmd = CMD_PTR;
+ int ret, fd;
+ char *cf = NULL, *buf, *args, *errctx = NULL;
+ size_t bufsize;
+ struct lls_parse_result *lpr1, *lpr2, *lpr3;
+ unsigned num_inputs;
+
+ ret = lls(lls_parse(argc, argv, cmd, &lpr1, &errctx));
+ if (ret < 0)
+ goto fail;
+ lpr = lpr1;
+ loglevel = OPT_UINT32_VAL(LOGLEVEL);
+ version_handle_flag("audioc", OPT_GIVEN(VERSION));
+ handle_help_flag();
+ cf = configfile_exists();
+ if (cf) {
+ void *map;
+ size_t sz;
+ int cf_argc;
+ char **cf_argv;
+ ret = mmap_full_file(cf, O_RDONLY, &map, &sz, NULL);
+ if (ret != -E_EMPTY) {
+ if (ret < 0)
+ goto out;
+ ret = lls(lls_convert_config(map, sz, NULL, &cf_argv,
+ &errctx));
+ para_munmap(map, sz);
+ if (ret < 0) {
+ PARA_ERROR_LOG("syntax error in %s\n", cf);