/* * gstdvbbackend * * gstdvbbackend is a small programm which captures a given set of dvb * channels from one dvb device and provides the streams via minimal http. * * * Copyright (C) 2011-2016 Christian Pointner * * This file is part of gstdvbbackend. * * gstdvbbackend is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * gstdvbbackend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with gstdvbbackend. If not, see . * * In addition, as a special exception, the copyright holders hereby * grant permission for non-GPL-compatible GStreamer plugins to be used * and distributed together with GStreamer and gstdvbbackend. * This permission goes above and beyond the permissions granted by the * GPL license gstdvbbackend is covered by. */ #include "datatypes.h" #include "config.h" #include "options.h" #include "log.h" #include #include #include #include #include static void options_defaults(options_t* opt) { if(!opt) return; opt->progname_ = g_strdup("gstdvbbackend"); opt->daemonize_ = TRUE; opt->username_ = NULL; opt->groupname_ = NULL; opt->chroot_dir_ = NULL; opt->pid_file_ = NULL; opt->log_targets_ = NULL; opt->debug_ = FALSE; opt->adapter_ = 0; opt->frontend_ = 0; opt->frequency_ = 514000000; opt->polarity_ = g_strdup("H"); opt->pids_ = g_strdup("5010:5011"); opt->host_ = NULL; opt->port_ = g_strdup("80"); } static GQuark options_error_quark() { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string("gstdvbbackend_options_error"); return quark; } static gboolean options_parse_remaining(const gchar *option_name, const gchar *value, gpointer data, GError **error) { g_set_error(error, options_error_quark(), G_OPTION_ERROR_FAILED, "unkown option '%s'", value); return FALSE; } static int options_parse_post(options_t* opt); int options_parse(options_t* opt, int argc, char* argv[]) { if(!opt) return -1; setlocale (LC_ALL, ""); options_defaults(opt); g_free(opt->progname_); opt->progname_ = g_strdup(argv[0]); if(!opt->progname_) return -127; gboolean show_version = FALSE; GOptionEntry main_entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, "print version info and exit", NULL }, { "nodaemonize", 'D', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt->daemonize_, "don't run in background", NULL }, { "username", 'u', 0, G_OPTION_ARG_STRING, &opt->username_, "change to this user", "USERNAME" }, { "group", 'g', 0, G_OPTION_ARG_STRING, &opt->groupname_, "change to this group", "GROUP" }, { "chroot", 'C', 0, G_OPTION_ARG_STRING, &opt->chroot_dir_, "chroot to this directory", "PATH" }, { "write-pid", 'P', 0, G_OPTION_ARG_STRING, &opt->pid_file_, "write pid to this file", "PATH" }, { "log", 'L', 0, G_OPTION_ARG_STRING_ARRAY, &opt->log_targets_, "add a log target, can be invoked several times", ":[,[,..]]" }, { "debug", 'U', 0, G_OPTION_ARG_NONE, &opt->debug_, "don't daemonize and log to stdout with maximum log level", NULL }, { "adapter", 'a', 0, G_OPTION_ARG_INT, &opt->adapter_, "the DVB adapter to use", "NUM" }, { "frontend", 'F', 0, G_OPTION_ARG_INT, &opt->frontend_, "the frontend of the DVB adapter to use", "NUM" }, { "frequency", 'f', 0, G_OPTION_ARG_INT, &opt->frequency_, "the frequency to tune to", "Hz" }, { "polarity", 'o', 0, G_OPTION_ARG_STRING, &opt->polarity_, "the polarity of the signal", "(H|V)" }, { "pids", 'i', 0, G_OPTION_ARG_STRING, &opt->pids_, "the pids of the stream", "PID:PID" }, { "host", 'H', 0, G_OPTION_ARG_STRING, &opt->host_, "the local interface to bind to", "ADDR" }, { "port", 'p', 0, G_OPTION_ARG_STRING, &opt->port_, "the port to listen to", "NUM" }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, options_parse_remaining, NULL, NULL}, { NULL } }; GOptionContext *ctx = g_option_context_new("- simple DVB to HTTP Streamer "); GOptionGroup* main_group = g_option_group_new ("main", "Application Options", "Show Application Options", opt, NULL); if(main_group) g_option_group_add_entries(main_group, main_entries); GOptionGroup* gst_group = gst_init_get_option_group(); if(!main_group || !gst_group) { printf("ERROR: Failed to initialize: memory error\n"); return -127; } g_option_context_set_main_group(ctx, main_group); g_option_context_add_group(ctx, gst_group); GError *err = NULL; if(!g_option_context_parse(ctx, &argc, &argv, &err)) { printf("ERROR: Failed to initialize: %s\n", err->message); g_error_free(err); return 1; } if(show_version) return -1; return options_parse_post(opt); } static int options_parse_post(options_t* opt) { if(opt->adapter_ < 0) { printf("ERROR: adapter must be a >= 0!\n"); return -2; } if(opt->frontend_ < 0) { printf("ERROR: frontend must be a >= 0!\n"); return -2; } if(opt->frequency_ < 0) { printf("ERROR: frequency must be a >= 0!\n"); return -2; } if(opt->debug_) { opt->daemonize_ = 0; g_strfreev(opt->log_targets_); opt->log_targets_ = g_new(gchar*, 2); if(!opt->log_targets_) return -127; opt->log_targets_[0] = g_strdup("stdout:5"); if(!(opt->log_targets_[0])) return -127; opt->log_targets_[1] = NULL; } if(!opt->log_targets_ || !g_strv_length(opt->log_targets_)) { opt->log_targets_ = g_new(gchar*, 2); if(!opt->log_targets_) return -127; opt->log_targets_[0] = g_strdup("syslog:3,gstdvbbackend,daemon"); if(!(opt->log_targets_[0])) return -127; opt->log_targets_[1] = NULL; } return 0; } void options_clear(options_t* opt) { if(!opt) return; g_free(opt->progname_); g_free(opt->username_); g_free(opt->groupname_); g_free(opt->chroot_dir_); g_free(opt->pid_file_); g_strfreev(opt->log_targets_); g_free(opt->polarity_); g_free(opt->pids_); g_free(opt->host_); g_free(opt->port_); } void options_print_version() { printf("%s\n", VERSION_STRING_0); #if defined(__clang__) printf("%s, using CLANG %s\n", VERSION_STRING_1, __clang_version__); #elif defined(__GNUC__) printf("%s, using GCC %d.%d.%d\n", VERSION_STRING_1, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); #else printf("%s\n", VERSION_STRING_1); #endif const gchar *nano_str; guint major, minor, micro, nano; gst_version(&major, &minor, µ, &nano); if (nano == 1) nano_str = " (CVS)"; else if (nano == 2) nano_str = " (Prerelease)"; else nano_str = ""; printf(" linked against GStreamer %d.%d.%d%s\n", major, minor, micro, nano_str); } void options_print(options_t* opt) { if(!opt) return; printf(" progname: '%s'\n", opt->progname_); printf(" daemonize: %s\n", opt->daemonize_ ? "true" : "false"); printf(" username: '%s'\n", opt->username_); printf(" groupname: '%s'\n", opt->groupname_); printf(" chroot_dir: '%s'\n", opt->chroot_dir_); printf(" pid_file: '%s'\n", opt->pid_file_); printf(" log_targets: \n"); gchar* lt = opt->log_targets_ ? g_strjoinv ("'\n '", opt->log_targets_) : NULL; if(lt) { printf(" '%s'\n", lt); g_free(lt); } printf(" debug: %s\n", opt->debug_ ? "true" : "false"); printf(" adapter: %d\n", opt->adapter_); printf(" frontend: %d\n", opt->frontend_); printf(" frequency: %d\n", opt->frequency_); printf(" polarity: '%s'\n", opt->polarity_); printf(" pids: '%s'\n", opt->pids_); printf(" host: '%s'\n", opt->host_); printf(" port: '%s'\n", opt->port_); }