summaryrefslogtreecommitdiff
path: root/src/options.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-09-03 23:09:49 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-09-03 23:09:49 +0200
commita7c3a5c479812f1f69acac276402fdffc60371aa (patch)
tree39bb07552103848862935d8e5c5df20f7135c3f0 /src/options.c
added initial code - based on rharchive
Diffstat (limited to 'src/options.c')
-rw-r--r--src/options.c337
1 files changed, 337 insertions, 0 deletions
diff --git a/src/options.c b/src/options.c
new file mode 100644
index 0000000..1273542
--- /dev/null
+++ b/src/options.c
@@ -0,0 +1,337 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ * Sydra is based on GStreamer and is written in C.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@helsinki.at>
+ *
+ * This file is part of sydra.
+ *
+ * sydra 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.
+ *
+ * sydra 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 sydra. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "datatypes.h"
+#include "config.h"
+
+#include "options.h"
+#include "log.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ VALUE = 1;
+
+#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ VALUE = 0;
+
+#define PARSE_INT_PARAM(SHORT, LONG, VALUE, BASE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1) \
+ return i; \
+ VALUE = strtol(argv[i+1], (char **)NULL, BASE); \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return i; \
+ if(VALUE) free(VALUE); \
+ VALUE = strdup(argv[i+1]); \
+ if(!VALUE) \
+ return -2; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_STRING_PARAM_SEC(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return i; \
+ if(VALUE) free(VALUE); \
+ VALUE = strdup(argv[i+1]); \
+ if(!VALUE) \
+ return -2; \
+ size_t j; \
+ for(j=0; j < strlen(argv[i+1]); ++j) \
+ argv[i+1][j] = '#'; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return i; \
+ int ret; \
+ ret = options_parse_hex_string(argv[i+1], &VALUE); \
+ if(ret > 0) \
+ return i+1; \
+ else if(ret < 0) \
+ return ret; \
+ size_t j; \
+ for(j=0; j < strlen(argv[i+1]); ++j) \
+ argv[i+1][j] = '#'; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_STRING_LIST(SHORT, LONG, LIST) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return i; \
+ int ret = string_list_add(&LIST, argv[i+1]); \
+ if(ret == -2) \
+ return ret; \
+ else if(ret) \
+ return i+1; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_RESOLV_TYPE(SHORT, LONG, VALUE) \
+ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return i; \
+ if(!strcmp(argv[i+1], "4") || \
+ !strcmp(argv[i+1], "ipv4")) \
+ VALUE = IPV4_ONLY; \
+ else if(!strcmp(argv[i+1], "6") || \
+ !strcmp(argv[i+1], "ipv6")) \
+ VALUE = IPV6_ONLY; \
+ else \
+ return i+1; \
+ argc--; \
+ i++; \
+ }
+
+int options_parse_hex_string(const char* hex, buffer_t* buffer)
+{
+ if(!hex || !buffer)
+ return -1;
+
+ u_int32_t hex_len = strlen(hex);
+ if(hex_len%2)
+ return 1;
+
+ if(buffer->buf_)
+ free(buffer->buf_);
+
+ buffer->length_ = hex_len/2;
+ buffer->buf_ = malloc(buffer->length_);
+ if(!buffer->buf_) {
+ buffer->length_ = 0;
+ return -2;
+ }
+
+ const char* ptr = hex;
+ int i;
+ for(i=0;i<buffer->length_;++i) {
+ u_int32_t tmp;
+ sscanf(ptr, "%2X", &tmp);
+ buffer->buf_[i] = (u_int8_t)tmp;
+ ptr += 2;
+ }
+
+ return 0;
+}
+
+
+int options_parse(options_t* opt, int argc, char* argv[])
+{
+ if(!opt)
+ return -1;
+
+ options_default(opt);
+
+ if(opt->progname_)
+ free(opt->progname_);
+ opt->progname_ = strdup(argv[0]);
+ if(!opt->progname_)
+ return -2;
+
+ argc--;
+
+ int i;
+ for(i=1; argc > 0; ++i)
+ {
+ char* str = argv[i];
+ argc--;
+
+ if(!strcmp(str,"-h") || !strcmp(str,"--help"))
+ return -1;
+ else if(!strcmp(str,"-v") || !strcmp(str,"--version"))
+ return -3;
+ PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", opt->daemonize_)
+ PARSE_STRING_PARAM("-u","--username", opt->username_)
+ PARSE_STRING_PARAM("-g","--groupname", opt->groupname_)
+ PARSE_STRING_PARAM("-C","--chroot", opt->chroot_dir_)
+ PARSE_STRING_PARAM("-P","--write-pid", opt->pid_file_)
+ PARSE_STRING_LIST("-L","--log", opt->log_targets_)
+ PARSE_BOOL_PARAM("-U", "--debug", opt->debug_)
+ PARSE_STRING_PARAM("-s","--source", opt->src_bin_desc_)
+ PARSE_STRING_PARAM("-d","--output-dir", opt->output_dir_)
+ PARSE_STRING_PARAM("-f","--name-format", opt->name_format_)
+ PARSE_INT_PARAM("-m","--mode", opt->mode_, 8)
+ PARSE_BOOL_PARAM("-n", "--nocache", opt->nocache_)
+ PARSE_INT_PARAM("-i","--interval", opt->interval_, 10)
+ PARSE_INT_PARAM("-o","--offset", opt->offset_, 10)
+ PARSE_STRING_PARAM("-x","--post-process", opt->post_process_)
+ else
+ return i;
+ }
+
+ if(opt->interval_ <= 0)
+ return -4;
+
+ if(opt->debug_) {
+ string_list_add(&opt->log_targets_, "stdout:5");
+ opt->daemonize_ = 0;
+ }
+
+ if(!opt->log_targets_.first_) {
+ string_list_add(&opt->log_targets_, "syslog:3,sydra,daemon");
+ }
+
+ return 0;
+}
+
+void options_parse_post(options_t* opt)
+{
+ if(!opt)
+ return;
+
+// nothing yet
+}
+
+void options_default(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ opt->progname_ = strdup("sydra");
+ opt->daemonize_ = 1;
+ opt->username_ = NULL;
+ opt->groupname_ = NULL;
+ opt->chroot_dir_ = NULL;
+ opt->pid_file_ = NULL;
+ string_list_init(&opt->log_targets_);
+ opt->debug_ = 0;
+ opt->src_bin_desc_ = NULL;
+ opt->output_dir_ = strdup("/srv/archiv");
+ opt->name_format_ = strdup("%Y-%m-%d-%H00.ogg");
+ opt->mode_ = 0644;
+ opt->nocache_ = 0;
+ opt->interval_ = 50;
+ opt->offset_ = 0;
+ opt->post_process_ = NULL;
+}
+
+void options_clear(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ if(opt->progname_)
+ free(opt->progname_);
+ if(opt->username_)
+ free(opt->username_);
+ if(opt->groupname_)
+ free(opt->groupname_);
+ if(opt->chroot_dir_)
+ free(opt->chroot_dir_);
+ if(opt->pid_file_)
+ free(opt->pid_file_);
+ string_list_clear(&opt->log_targets_);
+ if(opt->src_bin_desc_)
+ free(opt->src_bin_desc_);
+ if(opt->output_dir_)
+ free(opt->output_dir_);
+ if(opt->name_format_)
+ free(opt->name_format_);
+ if(opt->post_process_)
+ free(opt->post_process_);
+}
+
+void options_print_usage()
+{
+ printf("USAGE:\n");
+ printf("sydra [-h|--help] prints this...\n");
+ printf(" [-v|--version] print version info and exit\n");
+ printf(" [-D|--nodaemonize] don't run in background\n");
+ printf(" [-u|--username] <username> change to this user\n");
+ printf(" [-g|--groupname] <groupname> change to this group\n");
+ printf(" [-C|--chroot] <path> chroot to this directory\n");
+ printf(" [-P|--write-pid] <path> write pid to this file\n");
+ printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n");
+ printf(" add a log target, can be invoked several times\n");
+ printf(" [-U|--debug] don't daemonize and log to stdout with maximum log level\n");
+ printf(" [-s|--source] <description> a gstreamer pipeline-style description which will be used\n");
+ printf(" as data source, see gst-launch man-page for syntax\n");
+ printf(" [-d|--output-dir] <path> path to the output directory\n");
+ printf(" [-f|--name-format] <format> the file name format, see manpage of strftime for the syntax\n");
+ printf(" [-m|--mode] <value> octal representation of the file permission mode\n");
+ printf(" [-n|--nocache] Use O_DIRECT for recorded files\n");
+ printf(" [-i|--interval] <value> interval for time checks in ms\n");
+ printf(" [-o|--offset] <value> time offset for recordings in ms\n");
+ printf(" [-x|--post-process] <script> call script when file is finished\n");
+}
+
+void options_print_version()
+{
+ printf("%s\n", VERSION_STRING_0);
+ printf("%s\n", VERSION_STRING_1);
+}
+
+void options_print(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ printf("progname: '%s'\n", opt->progname_);
+ printf("daemonize: %d\n", opt->daemonize_);
+ 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");
+ string_list_print(&opt->log_targets_, " '", "'\n");
+ printf("debug: %s\n", !opt->debug_ ? "false" : "true");
+ printf("src_bin_desc: >>%s<<\n", opt->src_bin_desc_);
+ printf("output_dir: '%s'\n", opt->output_dir_);
+ printf("name_format: '%s'\n", opt->name_format_);
+ printf("mode: %04o\n", (int)opt->mode_);
+ printf("nocache: %s\n", !opt->nocache_ ? "false" : "true");
+ printf("interval: %d\n", opt->interval_);
+ printf("offset: %d\n", opt->offset_);
+ printf("post_process: '%s'\n", opt->post_process_);
+}