From a7c3a5c479812f1f69acac276402fdffc60371aa Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 3 Sep 2014 23:09:49 +0200 Subject: added initial code - based on rharchive --- src/options.c | 337 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 src/options.c (limited to 'src/options.c') 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 + * + * 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 . + */ + +#include "datatypes.h" +#include "config.h" + +#include "options.h" +#include "log.h" + +#include +#include +#include +#include + +#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;ilength_;++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] change to this user\n"); + printf(" [-g|--groupname] change to this group\n"); + printf(" [-C|--chroot] chroot to this directory\n"); + printf(" [-P|--write-pid] write pid to this file\n"); + printf(" [-L|--log] :[,[,..]]\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] 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 to the output directory\n"); + printf(" [-f|--name-format] the file name format, see manpage of strftime for the syntax\n"); + printf(" [-m|--mode] octal representation of the file permission mode\n"); + printf(" [-n|--nocache] Use O_DIRECT for recorded files\n"); + printf(" [-i|--interval] interval for time checks in ms\n"); + printf(" [-o|--offset] time offset for recordings in ms\n"); + printf(" [-x|--post-process]