/***************************************************************************** * output_Close *****************************************************************************/ void output_Close( output_t *p_output ) { packet_t *p_packet = p_output->p_packets; while ( p_packet != NULL ) { int i; for ( i = 0; i < p_packet->i_depth; i++ ) { p_packet->pp_blocks[i]->i_refcount--; if ( !p_packet->pp_blocks[i]->i_refcount ) block_Delete( p_packet->pp_blocks[i] ); } p_output->p_packets = p_packet->p_next; free( p_packet ); p_packet = p_output->p_packets; } p_output->p_packets = p_output->p_last_packet = NULL; free( p_output->p_pat_section ); free( p_output->p_pmt_section ); free( p_output->p_nit_section ); free( p_output->p_sdt_section ); free( p_output->p_eit_ts_buffer ); p_output->config.i_config &= ~OUTPUT_VALID; close( p_output->i_handle ); config_Free( &p_output->config ); }
int main(int argc, char **argv) { SetDefaultLogging("TEST"); SetNamePgm("verif_syntax"); char *errtxt; char *fichier; config_file_t config; if ((argc > 1) && (argv[1])) { fichier = argv[1]; } else { LogTest("Usage %s <config_file>", argv[0]); exit(EINVAL); } /* test de la syntaxe du fichier */ config = config_ParseFile(fichier); if (config == NULL) { LogTest("Error parsing %s", argv[1]); exit(EINVAL); } else { LogTest("The syntax of the file %s is correct!", argv[1]); exit(0); } config_Free(config); return 0; }
/** * Destroys a plug-in. * @warning If the plug-in is loaded in memory, the handle will be leaked. */ void vlc_module_destroy (module_t *module) { assert (!module->b_loaded || !module->b_unloadable); for (module_t *m = module->submodule, *next; m != NULL; m = next) { next = m->next; vlc_module_destroy (m); } config_Free (module->p_config, module->confsize); free (module->domain); free (module->psz_filename); for (unsigned i = 0; i < module->i_shortcuts; i++) free (module->pp_shortcuts[i]); free (module->pp_shortcuts); free (module->psz_capability); free (module->psz_help); free (module->psz_longname); free (module->psz_shortname); free (module); }
int main( int i_argc, char **pp_argv ) { const char *psz_network_name = "DVBlast - http://www.videolan.org/projects/dvblast.html"; const char *psz_provider_name = NULL; char *psz_dup_config = NULL; struct sched_param param; int i_error; int c; int b_enable_syslog = 0; struct ev_signal sigint_watcher, sigterm_watcher, sighup_watcher; struct ev_timer quit_watcher; print_fh = stdout; if ( i_argc == 1 ) usage(); /* * The only short options left are: 489 * Use them wisely. */ static const struct option long_options[] = { { "config-file", required_argument, NULL, 'c' }, { "remote-socket", required_argument, NULL, 'r' }, { "ttl", required_argument, NULL, 't' }, { "rtp-output", required_argument, NULL, 'o' }, { "priority", required_argument, NULL, 'i' }, { "adapter", required_argument, NULL, 'a' }, { "frontend-number", required_argument, NULL, 'n' }, { "delsys", required_argument, NULL, '5' }, { "dvb-plp-id", required_argument, NULL, '9' }, { "frequency", required_argument, NULL, 'f' }, { "fec-inner", required_argument, NULL, 'F' }, { "rolloff", required_argument, NULL, 'R' }, { "symbol-rate", required_argument, NULL, 's' }, { "diseqc", required_argument, NULL, 'S' }, { "uncommitted", required_argument, NULL, 'k' }, { "voltage", required_argument, NULL, 'v' }, { "force-pulse", no_argument, NULL, 'p' }, { "bandwidth", required_argument, NULL, 'b' }, { "inversion", required_argument, NULL, 'I' }, { "modulation", required_argument, NULL, 'm' }, { "pilot", required_argument, NULL, 'P' }, { "multistream-id", required_argument, NULL, '1' }, { "fec-lp", required_argument, NULL, 'K' }, { "guard", required_argument, NULL, 'G' }, { "hierarchy", required_argument, NULL, 'H' }, { "transmission", required_argument, NULL, 'X' }, { "lock-timeout", required_argument, NULL, 'O' }, { "budget-mode", no_argument, NULL, 'u' }, { "select-pmts", no_argument, NULL, 'w' }, { "udp", no_argument, NULL, 'U' }, { "unique-ts-id", no_argument, NULL, 'T' }, { "latency", required_argument, NULL, 'L' }, { "retention", required_argument, NULL, 'E' }, { "duplicate", required_argument, NULL, 'd' }, { "passthrough", no_argument, NULL, '3' }, { "rtp-input", required_argument, NULL, 'D' }, { "asi-adapter", required_argument, NULL, 'A' }, { "any-type", no_argument, NULL, 'z' }, { "dvb-compliance", no_argument, NULL, 'C' }, { "emm-passthrough", no_argument, NULL, 'W' }, { "ecm-passthrough", no_argument, NULL, 'Y' }, { "epg-passthrough", no_argument, NULL, 'e' }, { "network-name", no_argument, NULL, 'M' }, { "network-id", no_argument, NULL, 'N' }, { "system-charset", required_argument, NULL, 'j' }, { "dvb-charset", required_argument, NULL, 'J' }, { "provider-name", required_argument, NULL, 'B' }, { "logger", no_argument, NULL, 'l' }, { "logger-ident", required_argument, NULL, 'g' }, { "print", required_argument, NULL, 'x' }, { "quit-timeout", required_argument, NULL, 'Q' }, { "print-period", required_argument, NULL, '6' }, { "es-timeout", required_argument, NULL, '7' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "mrtg-file", required_argument, NULL, 'Z' }, { "ca-number", required_argument, NULL, 'y' }, { "pidmap", required_argument, NULL, '0' }, { "dvr-buf-size", required_argument, NULL, '2' }, { 0, 0, 0, 0 } }; while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:5:f:F:R:s:S:k:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:3D:A:lg:zCWYeM:N:j:J:B:x:Q:6:7:hVZ:y:0:1:2:9:", long_options, NULL)) != -1 ) { switch ( c ) { case 'q': if ( optarg ) { if ( *optarg == 'q' ) /* e.g. -qqq */ { i_verbose--; while ( *optarg == 'q' ) { i_verbose--; optarg++; } } else { i_verbose -= atoi( optarg ); /* e.g. -q2 */ } } else { i_verbose--; /* -q */ } break; case 'c': psz_conf_file = optarg; /* * When configuration file is used it is reasonable to assume that * services may be added/removed. If b_select_pmts is not set dvblast * is unable to start streaming newly added services in the config. */ b_select_pmts = 1; break; case 'r': psz_srv_socket = optarg; break; case 't': i_ttl_global = strtol( optarg, NULL, 0 ); break; case 'o': { struct in_addr maddr; if ( !inet_aton( optarg, &maddr ) ) usage(); memcpy( pi_ssrc_global, &maddr.s_addr, 4 * sizeof(uint8_t) ); break; } case 'i': i_priority = strtol( optarg, NULL, 0 ); break; case 'a': i_adapter = strtol( optarg, NULL, 0 ); break; case 'n': i_fenum = strtol( optarg, NULL, 0 ); break; case 'y': i_canum = strtol( optarg, NULL, 0 ); break; case '5': psz_delsys = optarg; break; case '9': dvb_plp_id = strtol( optarg, NULL, 0 ); break; case 'f': if (optarg && optarg[0] != '-') i_frequency = strtol( optarg, NULL, 0 ); if ( pf_Open != NULL ) usage(); #ifdef HAVE_DVB_SUPPORT pf_Open = dvb_Open; pf_Reset = dvb_Reset; pf_SetFilter = dvb_SetFilter; pf_UnsetFilter = dvb_UnsetFilter; #else msg_Err( NULL, "DVBlast is compiled without DVB support."); exit(1); #endif break; case 'F': i_fec = strtol( optarg, NULL, 0 ); break; case 'R': i_rolloff = strtol( optarg, NULL, 0 ); break; case 's': i_srate = strtol( optarg, NULL, 0 ); break; case 'S': i_satnum = strtol( optarg, NULL, 16 ); break; case 'k': i_uncommitted = strtol( optarg, NULL, 16 ); break; case 'v': i_voltage = strtol( optarg, NULL, 0 ); break; case 'p': b_tone = 1; break; case 'b': i_bandwidth = strtol( optarg, NULL, 0 ); break; case 'I': i_inversion = strtol( optarg, NULL, 0 ); break; case 'm': psz_modulation = optarg; break; case 'P': i_pilot = strtol( optarg, NULL, 0 ); break; case '1': i_mis = strtol( optarg, NULL, 0 ); break; case 'K': i_fec_lp = strtol( optarg, NULL, 0 ); break; case 'G': i_guard = strtol( optarg, NULL, 0 ); break; case 'X': i_transmission = strtol( optarg, NULL, 0 ); break; case 'O': i_frontend_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case 'H': i_hierarchy = strtol( optarg, NULL, 0 ); break; case 'u': b_budget_mode = 1; break; case 'w': b_select_pmts = !b_select_pmts; break; case 'U': b_udp_global = true; break; case 'L': i_latency_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'E': i_retention_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'd': psz_dup_config = optarg; break; case '3': b_passthrough = true; print_fh = stderr; break; case 'D': psz_udp_src = optarg; if ( pf_Open != NULL ) usage(); pf_Open = udp_Open; pf_Reset = udp_Reset; pf_SetFilter = udp_SetFilter; pf_UnsetFilter = udp_UnsetFilter; break; case 'A': #ifdef HAVE_ASI_SUPPORT if ( pf_Open != NULL ) usage(); if ( strncmp(optarg, "deltacast:", 10) == 0) { #ifdef HAVE_ASI_DELTACAST_SUPPORT i_asi_adapter = strtol( optarg+10, NULL, 0 ); pf_Open = asi_deltacast_Open; pf_Reset = asi_deltacast_Reset; pf_SetFilter = asi_deltacast_SetFilter; pf_UnsetFilter = asi_deltacast_UnsetFilter; #else msg_Err( NULL, "DVBlast is compiled without Deltacast ASI support."); exit(1); #endif } else { i_asi_adapter = strtol( optarg, NULL, 0 ); pf_Open = asi_Open; pf_Reset = asi_Reset; pf_SetFilter = asi_SetFilter; pf_UnsetFilter = asi_UnsetFilter; } #else msg_Err( NULL, "DVBlast is compiled without ASI support."); exit(1); #endif break; case 'z': b_any_type = 1; break; case 'C': b_dvb_global = true; break; case 'W': b_enable_emm = true; break; case 'Y': b_enable_ecm = true; break; case 'e': b_epg_global = true; break; case 'M': psz_network_name = optarg; break; case 'N': i_network_id = strtoul( optarg, NULL, 0 ); break; case 'T': b_random_tsid = 1; break; case 'j': psz_native_charset = optarg; break; case 'J': psz_dvb_charset = optarg; break; case 'B': psz_provider_name = optarg; break; case 'l': b_enable_syslog = 1; break; case 'g': psz_syslog_ident = optarg; break; case 'x': b_print_enabled = true; if ( !strcmp(optarg, "text") ) i_print_type = PRINT_TEXT; else if ( !strcmp(optarg, "xml") ) i_print_type = PRINT_XML; else { b_print_enabled = false; msg_Warn( NULL, "unrecognized print type %s", optarg ); } break; case 'Q': i_quit_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case '6': i_print_period = strtoll( optarg, NULL, 0 ) * 1000; break; case '7': i_es_timeout = strtoll( optarg, NULL, 0 ) * 1000; break; case 'V': DisplayVersion(); exit(0); break; case 'Z': psz_mrtg_file = optarg; break; case '0': { /* We expect a comma separated list of numbers. Put them into the pi_newpids array as they appear */ char *str1; char *saveptr = NULL; char *tok = NULL; int i, i_newpid; for (i = 0, str1 = optarg; i < N_MAP_PIDS; i++, str1 = NULL) { tok = strtok_r(str1, ",", &saveptr); if ( !tok ) break; i_newpid = strtoul(tok, NULL, 0); if ( !i_newpid ) { msg_Err( NULL, "Invalid pidmap string" ); usage(); } pi_newpids[i] = i_newpid; } b_do_remap = true; break; } #ifdef HAVE_DVB_SUPPORT case '2': i_dvr_buffer_size = strtol( optarg, NULL, 0 ); if (!i_dvr_buffer_size) usage(); // it exits /* roundup to packet size */ i_dvr_buffer_size += TS_SIZE - 1; i_dvr_buffer_size /= TS_SIZE; i_dvr_buffer_size *= TS_SIZE; break; #endif case 'h': default: usage(); } } if ( optind < i_argc || pf_Open == NULL ) usage(); if ( b_enable_syslog ) msg_Connect( psz_syslog_ident ? psz_syslog_ident : pp_argv[0] ); if ( b_print_enabled ) { /* Make std* line-buffered */ setvbuf(print_fh, NULL, _IOLBF, 0); } if ( i_verbose ) DisplayVersion(); msg_Warn( NULL, "restarting" ); switch (i_print_type) { case PRINT_XML: fprintf(print_fh, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); fprintf(print_fh, "<TS>\n"); break; default: break; } if ( b_udp_global ) { msg_Warn( NULL, "raw UDP output is deprecated. Please consider using RTP." ); msg_Warn( NULL, "for DVB-IP compliance you should use RTP." ); } if ( b_epg_global && !b_dvb_global ) { msg_Dbg( NULL, "turning on DVB compliance, required by EPG information" ); b_dvb_global = true; } if ((event_loop = ev_default_loop(0)) == NULL) { msg_Err( NULL, "unable to initialize libev" ); exit(EXIT_FAILURE); } memset( &output_dup, 0, sizeof(output_dup) ); if ( psz_dup_config != NULL ) { output_config_t config; config_Defaults( &config ); if ( !config_ParseHost( &config, psz_dup_config ) ) msg_Err( NULL, "Invalid target address for -d switch" ); else { output_Init( &output_dup, &config ); output_Change( &output_dup, &config ); } config_Free( &config ); } config_strdvb( &network_name, psz_network_name ); config_strdvb( &provider_name, psz_provider_name ); /* Set signal handlers */ signal_watcher_init(&sigint_watcher, event_loop, sighandler, SIGINT); signal_watcher_init(&sigterm_watcher, event_loop, sighandler, SIGTERM); signal_watcher_init(&sighup_watcher, event_loop, sighandler, SIGHUP); srand( time(NULL) * getpid() ); demux_Open(); // init the mrtg logfile mrtgInit(psz_mrtg_file); if ( i_priority > 0 ) { memset( ¶m, 0, sizeof(struct sched_param) ); param.sched_priority = i_priority; if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m )) ) { msg_Warn( NULL, "couldn't set thread priority: %s", strerror(i_error) ); } } config_ReadFile(); if ( psz_srv_socket != NULL ) comm_Open(); if ( i_quit_timeout_duration ) { ev_timer_init(&quit_watcher, quit_cb, i_quit_timeout_duration / 1000000., 0); ev_timer_start(event_loop, &quit_watcher); } outputs_Init(); ev_run(event_loop, 0); mrtgClose(); outputs_Close( i_nb_outputs ); demux_Close(); dvb_string_clean( &network_name ); dvb_string_clean( &provider_name ); if ( conf_iconv != (iconv_t)-1 ) iconv_close( conf_iconv ); switch (i_print_type) { case PRINT_XML: fprintf(print_fh, "</TS>\n"); break; default: break; } if ( b_enable_syslog ) msg_Disconnect(); comm_Close(); block_Vacuum(); return EXIT_SUCCESS; }
void config_ReadFile(void) { FILE *p_file; char psz_line[2048]; int i; if ( psz_conf_file == NULL ) { msg_Err( NULL, "no config file" ); return; } if ( (p_file = fopen( psz_conf_file, "r" )) == NULL ) { msg_Err( NULL, "can't fopen config file %s", psz_conf_file ); return; } while ( fgets( psz_line, sizeof(psz_line), p_file ) != NULL ) { output_config_t config; output_t *p_output; char *psz_token, *psz_parser; psz_parser = strchr( psz_line, '#' ); if ( psz_parser != NULL ) *psz_parser-- = '\0'; while ( psz_parser >= psz_line && isblank( *psz_parser ) ) *psz_parser-- = '\0'; if ( psz_line[0] == '\0' ) continue; config_Defaults( &config ); psz_token = strtok_r( psz_line, "\t\n ", &psz_parser ); if ( psz_token == NULL || !config_ParseHost( &config, psz_token )) { config_Free( &config ); continue; } psz_token = strtok_r( NULL, "\t\n ", &psz_parser ); if ( psz_token == NULL ) { config_Free( &config ); continue; } if( atoi( psz_token ) == 1 ) config.i_config |= OUTPUT_WATCH; else config.i_config &= ~OUTPUT_WATCH; psz_token = strtok_r( NULL, "\t\n ", &psz_parser ); if ( psz_token == NULL ) { config_Free( &config ); continue; } if ( psz_token[0] == '*' ) { config.b_passthrough = true; } else { config.i_sid = strtol(psz_token, NULL, 0); psz_token = strtok_r( NULL, "\t\n ", &psz_parser ); if ( psz_token != NULL ) { psz_parser = NULL; for ( ; ; ) { psz_token = strtok_r( psz_token, ",", &psz_parser ); if ( psz_token == NULL ) break; config.pi_pids = realloc( config.pi_pids, (config.i_nb_pids + 1) * sizeof(uint16_t) ); config.pi_pids[config.i_nb_pids++] = strtol(psz_token, NULL, 0); psz_token = NULL; } } } config_Print( &config ); p_output = output_Find( &config ); if ( p_output == NULL ) p_output = output_Create( &config ); if ( p_output != NULL ) { free( p_output->config.psz_displayname ); p_output->config.psz_displayname = strdup( config.psz_displayname ); config.i_config |= OUTPUT_VALID | OUTPUT_STILL_PRESENT; output_Change( p_output, &config ); demux_Change( p_output, &config ); } config_Free( &config ); } fclose( p_file ); for ( i = 0; i < i_nb_outputs; i++ ) { output_t *p_output = pp_outputs[i]; output_config_t config; config_Init( &config ); if ( (p_output->config.i_config & OUTPUT_VALID) && !(p_output->config.i_config & OUTPUT_STILL_PRESENT) ) { msg_Dbg( NULL, "closing %s", p_output->config.psz_displayname ); demux_Change( p_output, &config ); output_Close( p_output ); } p_output->config.i_config &= ~OUTPUT_STILL_PRESENT; config_Free( &config ); } }
int main(int argc, char *argv[]) { char *tempo_exec_name = NULL; char localmachine[MAXHOSTNAMELEN + 1]; int c; int pidfile; #ifndef HAVE_DAEMON pid_t son_pid; #endif sigset_t signals_to_block; /* Set the server's boot time and epoch */ now(&ServerBootTime); ServerEpoch = (time_t) ServerBootTime.tv_sec; tempo_exec_name = strrchr(argv[0], '/'); if (tempo_exec_name != NULL) { exec_name = gsh_strdup(tempo_exec_name + 1); if (!exec_name) { fprintf(stderr, "Unable to allocate memory for exec name, exiting...\n"); exit(1); } } if (*exec_name == '\0') exec_name = argv[0]; /* get host name */ if (gethostname(localmachine, sizeof(localmachine)) != 0) { fprintf(stderr, "Could not get local host name, exiting...\n"); exit(1); } else { host_name = gsh_strdup(localmachine); if (!host_name) { fprintf(stderr, "Unable to allocate memory for hostname, exiting...\n"); exit(1); } } /* now parsing options with getopt */ while ((c = getopt(argc, argv, options)) != EOF) { switch (c) { case '@': /* A litlle backdoor to keep track of binary versions */ printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); printf("Release = %s\n", VERSION); printf("Release comment = %s\n", VERSION_COMMENT); printf("Git HEAD = %s\n", _GIT_HEAD_COMMIT); printf("Git Describe = %s\n", _GIT_DESCRIBE); exit(0); break; case 'L': /* Default Log */ log_path = gsh_strdup(optarg); if (!log_path) { fprintf(stderr, "Unable to allocate memory for log path.\n"); exit(1); } break; case 'N': /* debug level */ debug_level = ReturnLevelAscii(optarg); if (debug_level == -1) { fprintf(stderr, "Invalid value for option 'N': NIV_NULL, NIV_MAJ, NIV_CRIT, NIV_EVENT, NIV_DEBUG, NIV_MID_DEBUG or NIV_FULL_DEBUG expected.\n"); exit(1); } break; case 'f': /* config file */ config_path = gsh_strdup(optarg); if (!config_path) { fprintf(stderr, "Unable to allocate memory for config path.\n"); exit(1); } break; case 'p': /* PID file */ pidfile_path = gsh_strdup(optarg); if (!pidfile_path) { fprintf(stderr, "Path %s too long for option 'f'.\n", optarg); exit(1); } break; case 'd': /* Detach or not detach ? */ detach_flag = true; break; case 'R': /* Shall we manage RPCSEC_GSS ? */ fprintf(stderr, "\n\nThe -R flag is deprecated, use this syntax in the configuration file instead:\n\n"); fprintf(stderr, "NFS_KRB5\n"); fprintf(stderr, "{\n"); fprintf(stderr, "\tPrincipalName = nfs@<your_host> ;\n"); fprintf(stderr, "\tKeytabPath = /etc/krb5.keytab ;\n"); fprintf(stderr, "\tActive_krb5 = true ;\n"); fprintf(stderr, "}\n\n\n"); exit(1); break; case 'T': /* Dump the default configuration on stdout */ my_nfs_start_info.dump_default_config = true; break; case 'E': ServerEpoch = (time_t) atoll(optarg); break; case '?': case 'h': default: /* display the help */ fprintf(stderr, usage, exec_name); exit(0); break; } } /* initialize memory and logging */ nfs_prereq_init(exec_name, host_name, debug_level, log_path); LogEvent(COMPONENT_MAIN, "%s Starting: Version %s, built at %s %s on %s", exec_name, GANESHA_VERSION, __DATE__, __TIME__, BUILD_HOST); /* Start in background, if wanted */ if (detach_flag) { #ifdef HAVE_DAEMON /* daemonize the process (fork, close xterm fds, * detach from parent process) */ if (daemon(0, 0)) LogFatal(COMPONENT_MAIN, "Error detaching process from parent: %s", strerror(errno)); #else /* Step 1: forking a service process */ switch (son_pid = fork()) { case -1: /* Fork failed */ LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (fork error %d (%s)", errno, strerror(errno)); break; case 0: /* This code is within the son (that will actually work) * Let's make it the leader of its group of process */ if (setsid() == -1) { LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (setsid error %d (%s)", errno, strerror(errno)); } break; default: /* This code is within the parent process, * it is useless, it must die */ LogFullDebug(COMPONENT_MAIN, "Starting a child of pid %d", son_pid); exit(0); break; } #endif } /* Make sure Linux file i/o will return with error * if file size is exceeded. */ #ifdef _LINUX signal(SIGXFSZ, SIG_IGN); #endif /* Echo PID into pidfile */ pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0644); if (pidfile == -1) { LogFatal(COMPONENT_MAIN, "Can't open pid file %s for writing", pidfile_path); } else { char linebuf[1024]; struct flock lk; /* Try to obtain a lock on the file */ lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; lk.l_start = (off_t) 0; lk.l_len = (off_t) 0; if (fcntl(pidfile, F_SETLK, &lk) == -1) LogFatal(COMPONENT_MAIN, "Ganesha already started"); /* Put pid into file, then close it */ (void)snprintf(linebuf, sizeof(linebuf), "%u\n", getpid()); if (write(pidfile, linebuf, strlen(linebuf)) == -1) LogCrit(COMPONENT_MAIN, "Couldn't write pid to file %s", pidfile_path); } /* Set up for the signal handler. * Blocks the signals the signal handler will handle. */ sigemptyset(&signals_to_block); sigaddset(&signals_to_block, SIGTERM); sigaddset(&signals_to_block, SIGHUP); sigaddset(&signals_to_block, SIGPIPE); if (pthread_sigmask(SIG_BLOCK, &signals_to_block, NULL) != 0) LogFatal(COMPONENT_MAIN, "Could not start nfs daemon, pthread_sigmask failed"); /* Parse the configuration file so we all know what is going on. */ if (config_path == NULL) { LogFatal(COMPONENT_INIT, "start_fsals: No configuration file named."); return 1; } config_struct = config_ParseFile(config_path); if (!config_struct) { LogFatal(COMPONENT_INIT, "Error while parsing %s: %s", config_path, config_GetErrorMsg()); } /* We need all the fsal modules loaded so we can have * the list available at exports parsing time. */ start_fsals(config_struct); /* parse configuration file */ if (nfs_set_param_from_conf(config_struct, &my_nfs_start_info)) { LogFatal(COMPONENT_INIT, "Error setting parameters from configuration file."); } if (nfs_check_param_consistency()) { LogFatal(COMPONENT_INIT, "Inconsistent parameters found. Exiting..."); } if (init_fsals(config_struct)) { /* init the FSALs from the config */ LogFatal(COMPONENT_INIT, "FSALs could not initialize. Exiting..."); } /* freeing syntax tree : */ config_Free(config_struct); /* Everything seems to be OK! We can now start service threads */ nfs_start(&my_nfs_start_info); return 0; }
int auks_acl_init_from_config_file(auks_acl_t * p_acl, char *acl_file) { int fstatus = AUKS_ERROR; config_file_t config; int block_nb; char *principal; char *host; char *role_string; enum AUKS_ACL_ROLE role; int i; /* conf parsing */ config = config_ParseFile(acl_file); if (!config) { auks_error("unable to parse configuration file %s : %s", acl_file, extern_errormsg); fstatus = AUKS_ERROR_ACL_PARSING; goto exit; } auks_log("configuration file (%s) successfully parsed", acl_file); /* block nb */ block_nb = config_GetNbBlocks(config); if (block_nb <= 0) { auks_error("unable to get configuration blocks nb from " "config file %s : %s", acl_file, extern_errormsg); fstatus = AUKS_ERROR_ACL_FILE_IS_EMPTY; goto parse_exit; } auks_log2("configuration blocks nb (%d) successfully extracted", block_nb); /* acl init */ if (auks_acl_init(p_acl, block_nb) != 0) { auks_error("unable to init Auks ACL structure"); fstatus = AUKS_ERROR_ACL_INIT; goto parse_exit; } auks_log2("Auks ACL structure successfully initialized"); /* block loop */ fstatus = 0; for (i = 0; i < block_nb; i++) { char *block_name; block_name = config_GetBlockName(config, i); /* keep only rule block */ if (strncmp("rule", block_name, 7) != 0) continue; role_string = config_GetKeyValueByName(config, i, "role"); principal = config_GetKeyValueByName(config, i, "principal"); host = config_GetKeyValueByName(config, i, "host"); if (role_string == NULL) { auks_error("no role defined in rule[%d] of %s", i, acl_file); continue; } if (strncmp("user", role_string, 5) == 0) { role = AUKS_ACL_ROLE_USER; } else if (strncmp("admin", role_string, 6) == 0) { role = AUKS_ACL_ROLE_ADMIN; } else if (strncmp("guest", role_string, 5) == 0) { role = AUKS_ACL_ROLE_GUEST; } else { auks_error("invalid role for rule[%d]", i, acl_file, extern_errormsg); fstatus++; continue; } if (auks_acl_add_rule(p_acl, principal, host, role)) { auks_error("unable to add rule[%d] to auks_acl", i); fstatus++; } else { auks_log("rule[%d] '%s:%s => %s' successfully add", i, principal, host, role_string); } } /* EOF block loop */ /* clean acl if errors occured during creation */ if (fstatus) { auks_acl_free_contents(p_acl); fstatus = AUKS_ERROR_ACL_FILE_IS_INVALID; } parse_exit: /* free config file */ config_Free(config); exit: return fstatus; }
int auksd_engine_init_from_config_file(auksd_engine_t * engine, char *conf_file) { int fstatus = AUKS_ERROR; char* l_conf_file; char* e_conf_file; config_file_t config; int block_nb; char *phost; char *padd; char *pport; char *pprinc; char *pktb; char *shost; char *sadd; char *sport; char *sprinc; char *sktb; char *cdir; char *afile; char *lfile; char *dfile; char *ll_str; char *dl_str; char *tnb_str; char *qs_str; char *rs_str; char *rd_str; char *nat_str; char *krc_str; long int ll, dl, tnb, qs, rs, rd; int nat, krc; int i; int valid_block_nb=0; if ( conf_file != NULL ) l_conf_file = conf_file; else { e_conf_file = getenv("AUKSD_CONF"); if ( e_conf_file != NULL ) l_conf_file = e_conf_file ; else l_conf_file = DEFAULT_AUKSD_CONF ; } /* parse configuration file */ config = config_ParseFile(l_conf_file); if (!config) { auks_error("unable to parse configuration file %s : %s", l_conf_file, extern_errormsg); fstatus = AUKS_ERROR_ENGINE_CONFFILE_PARSING ; goto exit; } /* get conf blocks quantity */ block_nb = config_GetNbBlocks(config); if (block_nb <= 0) { auks_error("unable to get configuration blocks from config " "file %s : %s", l_conf_file, extern_errormsg); fstatus = AUKS_ERROR_ENGINE_CONFFILE_INVALID ; goto parse_exit; } /* look for relevants block and add contents to engine conf */ fstatus = AUKS_ERROR_ENGINE_CONFFILE_INCOMPLETE ; for (i = 0; i < block_nb; i++) { char *block_name; block_name = config_GetBlockName(config, i); /* skip non config blocks */ if (strncmp("common", block_name, 7) != 0) { continue; } auks_log ("initializing engine from 'common' block of file %s", l_conf_file); /* primary server conf value */ phost = config_GetKeyValueByName(config,i,"PrimaryHost"); if (phost == NULL) phost = DEFAULT_AUKSD_PRIMARY_HOST; padd = config_GetKeyValueByName(config,i,"PrimaryAddress"); if (padd == NULL) padd = DEFAULT_AUKSD_PRIMARY_ADDR; pport = config_GetKeyValueByName(config,i,"PrimaryPort"); if (pport == NULL) pport = DEFAULT_AUKSD_PRIMARY_PORT; pprinc = config_GetKeyValueByName(config,i,"PrimaryPrincipal"); if (pprinc == NULL) pprinc = DEFAULT_AUKSD_PRIMARY_PRINC; /* secondary server conf value */ shost = config_GetKeyValueByName(config,i,"SecondaryHost"); if (shost == NULL) shost = DEFAULT_AUKSD_SECONDARY_HOST; sadd = config_GetKeyValueByName(config,i,"SecondaryAddress"); if (sadd == NULL) sadd = DEFAULT_AUKSD_SECONDARY_ADDR; sport = config_GetKeyValueByName(config,i,"SecondaryPort"); if (sport == NULL) sport = DEFAULT_AUKSD_SECONDARY_PORT; sprinc = config_GetKeyValueByName(config,i, "SecondaryPrincipal"); if (sprinc == NULL) sprinc = DEFAULT_AUKSD_SECONDARY_PRINC; /* NAT traversal mode */ nat_str = config_GetKeyValueByName(config, i, "NAT") ; if (nat_str == NULL) nat = DEFAULT_AUKS_NAT_TRAVERSAL ; else if ( strncasecmp(nat_str,"yes",4) ==0 ) nat = 1 ; else nat = 0 ; valid_block_nb++; } /* EOF for */ for (i = 0; i < block_nb; i++) { char *block_name; block_name = config_GetBlockName(config, i); /* skip non config blocks */ if (strncmp("auksd", block_name, 5) != 0) { continue; } auks_log ("initializing engine from 'auksd' block of file %s", l_conf_file); /* primary server conf value */ pktb = config_GetKeyValueByName(config,i,"PrimaryKeytab"); if (pktb == NULL) pktb = DEFAULT_AUKSD_PRIMARY_KEYTAB; /* secondary server conf value */ sktb = config_GetKeyValueByName(config,i,"SecondaryKeytab"); if (sktb == NULL) sktb = DEFAULT_AUKSD_SECONDARY_KEYTAB; /* cache dir value */ cdir = config_GetKeyValueByName(config,i,"CacheDir"); if (cdir == NULL) cdir = DEFAULT_AUKSD_CACHEDIR; /* acl file value */ afile = config_GetKeyValueByName(config,i,"ACLFile"); if (afile == NULL) afile = DEFAULT_AUKSD_ACLFILE; /* read log file value */ lfile = config_GetKeyValueByName(config,i,"LogFile"); if (lfile == NULL) lfile = DEFAULT_AUKSD_LOGFILE; /* read log level value */ ll_str = config_GetKeyValueByName(config,i,"LogLevel"); if (ll_str == NULL) ll = DEFAULT_AUKSD_LOGLEVEL; else ll = strtol(ll_str, NULL, 10); if (ll == LONG_MIN || ll == LONG_MAX) ll = DEFAULT_AUKSD_LOGLEVEL; /* read debug file value */ dfile = config_GetKeyValueByName(config,i,"DebugFile"); if (dfile == NULL) dfile = DEFAULT_AUKSD_DEBUGFILE; /* read debug level value */ dl_str = config_GetKeyValueByName(config,i,"DebugLevel"); if (dl_str == NULL) dl = DEFAULT_AUKSD_DEBUGLEVEL; else dl = strtol(dl_str, NULL, 10); if (dl == LONG_MIN || dl == LONG_MAX) dl = DEFAULT_AUKSD_DEBUGLEVEL; /* read threads nb value */ tnb_str = config_GetKeyValueByName(config,i,"Workers"); if (tnb_str == NULL) tnb = DEFAULT_AUKSD_THREADS_NB; else tnb = strtol(tnb_str, NULL, 10); if (tnb == LONG_MIN || tnb == LONG_MAX) tnb = DEFAULT_AUKSD_THREADS_NB; /* read queue size */ qs_str = config_GetKeyValueByName(config,i,"QueueSize"); if (qs_str == NULL) qs = DEFAULT_AUKSD_QUEUE_SIZE; else qs = strtol(qs_str, NULL, 10); if (qs == LONG_MIN || qs == LONG_MAX) qs = DEFAULT_AUKSD_QUEUE_SIZE; /* read repository size */ rs_str = config_GetKeyValueByName(config,i,"RepoSize"); if (rs_str == NULL) rs = DEFAULT_AUKSD_REPO_SIZE; else rs = strtol(rs_str, NULL, 10); if (rs == LONG_MIN || rs == LONG_MAX) rs = DEFAULT_AUKSD_REPO_SIZE; /* clean delay */ rd_str = config_GetKeyValueByName(config,i,"CleanDelay"); if (rd_str == NULL) rd = DEFAULT_AUKSD_CLEAN_DELAY; else rd = strtol(rd_str, NULL, 10); if (rd == LONG_MIN || rd == LONG_MAX) rd = DEFAULT_AUKSD_CLEAN_DELAY; /* Kerberos Replay cache mode */ krc_str = config_GetKeyValueByName(config, i, "ReplayCache") ; if (krc_str == NULL) krc = DEFAULT_AUKS_REPLAY_CACHE ; else if ( strncasecmp(krc_str,"yes",4) ==0 ) krc = 1 ; else krc = 0 ; valid_block_nb++; } /* EOF for */ if ( valid_block_nb == 2 ) fstatus = AUKS_SUCCESS; if ( fstatus == AUKS_SUCCESS ) { /* init auksd engine */ fstatus = auksd_engine_init(engine, phost,padd, pport, pprinc, pktb, shost,sadd, sport, sprinc, sktb, cdir, afile, lfile, ll, dfile, dl, tnb, qs, rs, rd,nat,krc); /* init ok, break */ if (fstatus == 0) { auks_log("initialization succeed"); } else auks_error("initialization failed"); } parse_exit: /* free config file */ config_Free(config); exit: return fstatus; }
int main(int argc, char *argv[]) { char *tempo_exec_name = NULL; char localmachine[MAXHOSTNAMELEN + 1]; int c; int dsc; int rc; int pidfile; char *log_path = NULL; char *exec_name = "nfs-ganesha"; int debug_level = -1; int detach_flag = true; bool dump_trace = false; #ifndef HAVE_DAEMON int dev_null_fd = 0; pid_t son_pid; #endif sigset_t signals_to_block; struct config_error_type err_type; /* Set the server's boot time and epoch */ now(&nfs_ServerBootTime); nfs_ServerEpoch = (time_t) nfs_ServerBootTime.tv_sec; srand(nfs_ServerEpoch); tempo_exec_name = strrchr(argv[0], '/'); if (tempo_exec_name != NULL) exec_name = main_strdup("exec_name", tempo_exec_name + 1); if (*exec_name == '\0') exec_name = argv[0]; /* get host name */ if (gethostname(localmachine, sizeof(localmachine)) != 0) { fprintf(stderr, "Could not get local host name, exiting...\n"); exit(1); } else { nfs_host_name = main_strdup("host_name", localmachine); } /* now parsing options with getopt */ while ((c = getopt(argc, argv, options)) != EOF) { switch (c) { case 'v': case '@': printf("NFS-Ganesha Release = V%s\n", GANESHA_VERSION); #if !GANESHA_BUILD_RELEASE /* A little backdoor to keep track of binary versions */ printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); printf("Release comment = %s\n", VERSION_COMMENT); printf("Git HEAD = %s\n", _GIT_HEAD_COMMIT); printf("Git Describe = %s\n", _GIT_DESCRIBE); #endif exit(0); break; case 'L': /* Default Log */ log_path = main_strdup("log_path", optarg); break; case 'N': /* debug level */ debug_level = ReturnLevelAscii(optarg); if (debug_level == -1) { fprintf(stderr, "Invalid value for option 'N': NIV_NULL, NIV_MAJ, NIV_CRIT, NIV_EVENT, NIV_DEBUG, NIV_MID_DEBUG or NIV_FULL_DEBUG expected.\n"); exit(1); } break; case 'f': /* config file */ nfs_config_path = main_strdup("config_path", optarg); break; case 'p': /* PID file */ nfs_pidfile_path = main_strdup("pidfile_path", optarg); break; case 'F': /* Don't detach, foreground mode */ detach_flag = false; break; case 'R': /* Shall we manage RPCSEC_GSS ? */ fprintf(stderr, "\n\nThe -R flag is deprecated, use this syntax in the configuration file instead:\n\n"); fprintf(stderr, "NFS_KRB5\n"); fprintf(stderr, "{\n"); fprintf(stderr, "\tPrincipalName = nfs@<your_host> ;\n"); fprintf(stderr, "\tKeytabPath = /etc/krb5.keytab ;\n"); fprintf(stderr, "\tActive_krb5 = true ;\n"); fprintf(stderr, "}\n\n\n"); exit(1); break; case 'T': /* Dump the default configuration on stdout */ my_nfs_start_info.dump_default_config = true; break; case 'C': dump_trace = true; break; case 'E': nfs_ServerEpoch = (time_t) atoll(optarg); break; case 'h': fprintf(stderr, usage, exec_name); exit(0); default: /* '?' */ fprintf(stderr, "Try '%s -h' for usage\n", exec_name); exit(1); } } /* initialize memory and logging */ nfs_prereq_init(exec_name, nfs_host_name, debug_level, log_path, dump_trace); #if GANESHA_BUILD_RELEASE LogEvent(COMPONENT_MAIN, "%s Starting: Ganesha Version %s", exec_name, GANESHA_VERSION); #else LogEvent(COMPONENT_MAIN, "%s Starting: %s", exec_name, "Ganesha Version " _GIT_DESCRIBE ", built at " __DATE__ " " __TIME__ " on " BUILD_HOST); #endif /* initialize nfs_init */ nfs_init_init(); nfs_check_malloc(); /* Start in background, if wanted */ if (detach_flag) { #ifdef HAVE_DAEMON /* daemonize the process (fork, close xterm fds, * detach from parent process) */ if (daemon(0, 0)) LogFatal(COMPONENT_MAIN, "Error detaching process from parent: %s", strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); #else /* Step 1: forking a service process */ switch (son_pid = fork()) { case -1: /* Fork failed */ LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (fork error %d (%s)", errno, strerror(errno)); break; case 0: /* This code is within the son (that will actually work) * Let's make it the leader of its group of process */ if (setsid() == -1) { LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (setsid error %d (%s)", errno, strerror(errno)); } /* stdin, stdout and stderr should not refer to a tty * I close 0, 1 & 2 and redirect them to /dev/null */ dev_null_fd = open("/dev/null", O_RDWR); if (dev_null_fd < 0) LogFatal(COMPONENT_MAIN, "Could not open /dev/null: %d (%s)", errno, strerror(errno)); if (close(STDIN_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdin: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdin closed"); dup(dev_null_fd); } if (close(STDOUT_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdout: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdout closed"); dup(dev_null_fd); } if (close(STDERR_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stderr: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stderr closed"); dup(dev_null_fd); } if (close(dev_null_fd) == -1) LogFatal(COMPONENT_MAIN, "Could not close tmp fd to /dev/null: %d (%s)", errno, strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); break; default: /* This code is within the parent process, * it is useless, it must die */ LogFullDebug(COMPONENT_MAIN, "Starting a child of pid %d", son_pid); exit(0); break; } #endif } /* Make sure Linux file i/o will return with error * if file size is exceeded. */ #ifdef _LINUX signal(SIGXFSZ, SIG_IGN); #endif /* Echo PID into pidfile */ pidfile = open(nfs_pidfile_path, O_CREAT | O_RDWR, 0644); if (pidfile == -1) { LogFatal(COMPONENT_MAIN, "Can't open pid file %s for writing", nfs_pidfile_path); } else { char linebuf[1024]; struct flock lk; /* Try to obtain a lock on the file */ lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; lk.l_start = (off_t) 0; lk.l_len = (off_t) 0; if (fcntl(pidfile, F_SETLK, &lk) == -1) LogFatal(COMPONENT_MAIN, "Ganesha already started"); /* Put pid into file, then close it */ (void)snprintf(linebuf, sizeof(linebuf), "%u\n", getpid()); if (write(pidfile, linebuf, strlen(linebuf)) == -1) LogCrit(COMPONENT_MAIN, "Couldn't write pid to file %s", nfs_pidfile_path); } /* Set up for the signal handler. * Blocks the signals the signal handler will handle. */ sigemptyset(&signals_to_block); sigaddset(&signals_to_block, SIGTERM); sigaddset(&signals_to_block, SIGHUP); sigaddset(&signals_to_block, SIGPIPE); if (pthread_sigmask(SIG_BLOCK, &signals_to_block, NULL) != 0) LogFatal(COMPONENT_MAIN, "Could not start nfs daemon, pthread_sigmask failed"); /* init URL package */ config_url_init(); /* Create a memstream for parser+processing error messages */ if (!init_error_type(&err_type)) goto fatal_die; /* Parse the configuration file so we all know what is going on. */ if (nfs_config_path == NULL || nfs_config_path[0] == '\0') { LogWarn(COMPONENT_INIT, "No configuration file named."); nfs_config_struct = NULL; } else nfs_config_struct = config_ParseFile(nfs_config_path, &err_type); if (!config_error_no_error(&err_type)) { char *errstr = err_type_str(&err_type); if (!config_error_is_harmless(&err_type)) { LogCrit(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); goto fatal_die; } else LogWarn(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); } if (read_log_config(nfs_config_struct, &err_type) < 0) { LogCrit(COMPONENT_INIT, "Error while parsing log configuration"); goto fatal_die; } /* We need all the fsal modules loaded so we can have * the list available at exports parsing time. */ start_fsals(); /* parse configuration file */ if (nfs_set_param_from_conf(nfs_config_struct, &my_nfs_start_info, &err_type)) { LogCrit(COMPONENT_INIT, "Error setting parameters from configuration file."); goto fatal_die; } /* initialize core subsystems and data structures */ if (init_server_pkgs() != 0) { LogCrit(COMPONENT_INIT, "Failed to initialize server packages"); goto fatal_die; } /* Load Data Server entries from parsed file * returns the number of DS entries. */ dsc = ReadDataServers(nfs_config_struct, &err_type); if (dsc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing DS entries"); goto fatal_die; } /* Create stable storage directory, this needs to be done before * starting the recovery thread. */ rc = nfs4_recovery_init(); if (rc) { LogCrit(COMPONENT_INIT, "Recovery backend initialization failed!"); goto fatal_die; } /* Start grace period */ nfs_start_grace(NULL); /* Wait for enforcement to begin */ nfs_wait_for_grace_enforcement(); /* Load export entries from parsed file * returns the number of export entries. */ rc = ReadExports(nfs_config_struct, &err_type); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing export entries"); goto fatal_die; } if (rc == 0 && dsc == 0) LogWarn(COMPONENT_INIT, "No export entries found in configuration file !!!"); report_config_errors(&err_type, NULL, config_errs_to_log); /* freeing syntax tree : */ config_Free(nfs_config_struct); /* Everything seems to be OK! We can now start service threads */ nfs_start(&my_nfs_start_info); return 0; fatal_die: report_config_errors(&err_type, NULL, config_errs_to_log); LogFatal(COMPONENT_INIT, "Fatal errors. Server exiting..."); /* NOT REACHED */ return 2; }
int main( int i_argc, char **pp_argv ) { const char *psz_network_name = "DVBlast - http://www.videolan.org/projects/dvblast.html"; char *p_network_name_tmp = NULL; size_t i_network_name_tmp_size; char *psz_dup_config = NULL; mtime_t i_poll_timeout = MAX_POLL_TIMEOUT; struct sched_param param; int i_error; int c; struct sigaction sa; sigset_t set; int b_enable_syslog = 0; if ( i_argc == 1 ) usage(); /* * The only short options left are: ky0123456789 * Use them wisely. */ static const struct option long_options[] = { { "config-file", required_argument, NULL, 'c' }, { "remote-socket", required_argument, NULL, 'r' }, { "ttl", required_argument, NULL, 't' }, { "rtp-output", required_argument, NULL, 'o' }, { "priority", required_argument, NULL, 'i' }, { "adapter", required_argument, NULL, 'a' }, { "frontend-number", required_argument, NULL, 'n' }, { "frequency", required_argument, NULL, 'f' }, { "fec-inner", required_argument, NULL, 'F' }, { "rolloff", required_argument, NULL, 'R' }, { "symbol-rate", required_argument, NULL, 's' }, { "diseqc", required_argument, NULL, 'S' }, { "voltage", required_argument, NULL, 'v' }, { "force-pulse", no_argument, NULL, 'p' }, { "bandwidth", required_argument, NULL, 'b' }, { "inversion", required_argument, NULL, 'I' }, { "modulation", required_argument, NULL, 'm' }, { "pilot", required_argument, NULL, 'P' }, { "fec-lp", required_argument, NULL, 'K' }, { "guard", required_argument, NULL, 'G' }, { "hierarchy", required_argument, NULL, 'H' }, { "transmission", required_argument, NULL, 'X' }, { "lock-timeout", required_argument, NULL, 'O' }, { "budget-mode", no_argument, NULL, 'u' }, { "select-pmts", no_argument, NULL, 'w' }, { "udp", no_argument, NULL, 'U' }, { "unique-ts-id", no_argument, NULL, 'T' }, { "latency", required_argument, NULL, 'L' }, { "retention", required_argument, NULL, 'E' }, { "duplicate", required_argument, NULL, 'd' }, { "rtp-input", required_argument, NULL, 'D' }, { "asi-adapter", required_argument, NULL, 'A' }, { "any-type", no_argument, NULL, 'z' }, { "dvb-compliance", no_argument, NULL, 'C' }, { "emm-passthrough", no_argument, NULL, 'W' }, { "ecm-passthrough", no_argument, NULL, 'Y' }, { "epg-passthrough", no_argument, NULL, 'e' }, { "network-name", no_argument, NULL, 'M' }, { "network-id", no_argument, NULL, 'N' }, { "system-charset", required_argument, NULL, 'j' }, { "dvb-charset", required_argument, NULL, 'J' }, { "provider-name", required_argument, NULL, 'B' }, { "logger", no_argument, NULL, 'l' }, { "logger-ident", required_argument, NULL, 'g' }, { "print", required_argument, NULL, 'x' }, { "quit-timeout", required_argument, NULL, 'Q' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "mrtg-file", required_argument, NULL, 'Z' }, { 0, 0, 0, 0 } }; while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lg:zCWYeM:N:j:J:B:x:Q:hVZ:", long_options, NULL)) != -1 ) { switch ( c ) { case 'q': if ( optarg ) { if ( *optarg == 'q' ) /* e.g. -qqq */ { i_verbose--; while ( *optarg == 'q' ) { i_verbose--; optarg++; } } else { i_verbose -= atoi( optarg ); /* e.g. -q2 */ } } else { i_verbose--; /* -q */ } break; case 'c': psz_conf_file = optarg; break; case 'r': psz_srv_socket = optarg; break; case 't': i_ttl_global = strtol( optarg, NULL, 0 ); break; case 'o': { struct in_addr maddr; if ( !inet_aton( optarg, &maddr ) ) usage(); memcpy( pi_ssrc_global, &maddr.s_addr, 4 * sizeof(uint8_t) ); break; } case 'i': i_priority = strtol( optarg, NULL, 0 ); break; case 'a': i_adapter = strtol( optarg, NULL, 0 ); break; case 'n': i_fenum = strtol( optarg, NULL, 0 ); break; case 'f': i_frequency = strtol( optarg, NULL, 0 ); if ( pf_Open != NULL ) usage(); pf_Open = dvb_Open; pf_Read = dvb_Read; pf_Reset = dvb_Reset; pf_SetFilter = dvb_SetFilter; pf_UnsetFilter = dvb_UnsetFilter; break; case 'F': i_fec = strtol( optarg, NULL, 0 ); break; case 'R': i_rolloff = strtol( optarg, NULL, 0 ); break; case 's': i_srate = strtol( optarg, NULL, 0 ); break; case 'S': i_satnum = strtol( optarg, NULL, 16 ); break; case 'v': i_voltage = strtol( optarg, NULL, 0 ); break; case 'p': b_tone = 1; break; case 'b': i_bandwidth = strtol( optarg, NULL, 0 ); break; case 'I': i_inversion = strtol( optarg, NULL, 0 ); break; case 'm': psz_modulation = optarg; break; case 'P': i_pilot = strtol( optarg, NULL, 0 ); break; case 'K': i_fec_lp = strtol( optarg, NULL, 0 ); break; case 'G': i_guard = strtol( optarg, NULL, 0 ); break; case 'X': i_transmission = strtol( optarg, NULL, 0 ); break; case 'O': i_frontend_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case 'H': i_hierarchy = strtol( optarg, NULL, 0 ); break; case 'u': b_budget_mode = 1; break; case 'w': b_select_pmts = 1; break; case 'U': b_udp_global = true; break; case 'L': i_latency_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'E': i_retention_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'd': psz_dup_config = optarg; break; case 'D': psz_udp_src = optarg; if ( pf_Open != NULL ) usage(); pf_Open = udp_Open; pf_Read = udp_Read; pf_Reset = udp_Reset; pf_SetFilter = udp_SetFilter; pf_UnsetFilter = udp_UnsetFilter; break; case 'A': i_asi_adapter = strtol( optarg, NULL, 0 ); if ( pf_Open != NULL ) usage(); pf_Open = asi_Open; pf_Read = asi_Read; pf_Reset = asi_Reset; pf_SetFilter = asi_SetFilter; pf_UnsetFilter = asi_UnsetFilter; break; case 'z': b_any_type = 1; break; case 'C': b_dvb_global = true; break; case 'W': b_enable_emm = true; break; case 'Y': b_enable_ecm = true; b_dvb_global = true; break; case 'e': b_epg_global = true; break; case 'M': psz_network_name = optarg; break; case 'N': i_network_id = strtoul( optarg, NULL, 0 ); break; case 'T': b_random_tsid = 1; break; case 'j': psz_native_charset = optarg; break; case 'J': psz_dvb_charset = optarg; break; case 'B': psz_provider_name = optarg; break; case 'l': b_enable_syslog = 1; break; case 'g': psz_syslog_ident = optarg; break; case 'x': if ( !strcmp(optarg, "text") ) i_print_type = PRINT_TEXT; else if ( !strcmp(optarg, "xml") ) i_print_type = PRINT_XML; else msg_Warn( NULL, "unrecognized print type %s", optarg ); /* Make stdout line-buffered */ setvbuf(stdout, NULL, _IOLBF, 0); break; case 'Q': i_quit_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case 'V': DisplayVersion(); exit(0); break; case 'Z': psz_mrtg_file = optarg; break; case 'h': default: usage(); } } if ( optind < i_argc || pf_Open == NULL ) usage(); if ( b_enable_syslog ) msg_Connect( psz_syslog_ident ? psz_syslog_ident : pp_argv[0] ); if ( i_verbose ) DisplayVersion(); msg_Warn( NULL, "restarting" ); switch (i_print_type) { case PRINT_XML: printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); printf("<TS>\n"); break; default: break; } if ( b_udp_global ) { msg_Warn( NULL, "raw UDP output is deprecated. Please consider using RTP." ); msg_Warn( NULL, "for DVB-IP compliance you should use RTP." ); } if ( b_epg_global && !b_dvb_global ) { msg_Dbg( NULL, "turning on DVB compliance, required by EPG information" ); b_dvb_global = true; } memset( &output_dup, 0, sizeof(output_dup) ); if ( psz_dup_config != NULL ) { output_config_t config; config_Defaults( &config ); if ( !config_ParseHost( &config, psz_dup_config ) ) msg_Err( NULL, "Invalid target address for -d switch" ); else { output_Init( &output_dup, &config ); output_Change( &output_dup, &config ); } config_Free( &config ); } if ( strcasecmp( psz_native_charset, psz_dvb_charset ) ) { #ifdef HAVE_ICONV iconv_t iconv_system = iconv_open( psz_dvb_charset, psz_native_charset ); if ( iconv_system != (iconv_t)-1 ) { size_t i = strlen( psz_network_name ); char *p, *psz_string; i_network_name_tmp_size = i * 6; p = psz_string = malloc(i_network_name_tmp_size); if ( iconv( iconv_system, (char **)&psz_network_name, &i, &p, &i_network_name_tmp_size ) == -1 ) free( psz_string ); else { p_network_name_tmp = psz_string; i_network_name_tmp_size = p - psz_string; } iconv_close( iconv_system ); } #else msg_Warn( NULL, "unable to convert from %s to %s (iconv is not available)", psz_native_charset, psz_dvb_charset ); #endif } if ( p_network_name_tmp == NULL ) { p_network_name_tmp = strdup(psz_network_name); i_network_name_tmp_size = strlen(psz_network_name); } p_network_name = dvb_string_set( (uint8_t *)p_network_name_tmp, i_network_name_tmp_size, psz_dvb_charset, &i_network_name_size ); free( p_network_name_tmp ); /* Set signal handlers */ memset( &sa, 0, sizeof(struct sigaction) ); sa.sa_handler = SigHandler; sigfillset( &set ); if ( sigaction( SIGHUP, &sa, NULL ) == -1 || sigaction( SIGINT, &sa, NULL ) == -1 ) { msg_Err( NULL, "couldn't set signal handler: %s", strerror(errno) ); exit(EXIT_FAILURE); } srand( time(NULL) * getpid() ); demux_Open(); // init the mrtg logfile mrtgInit(psz_mrtg_file); if ( i_priority > 0 ) { memset( ¶m, 0, sizeof(struct sched_param) ); param.sched_priority = i_priority; if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m )) ) { msg_Warn( NULL, "couldn't set thread priority: %s", strerror(i_error) ); } } config_ReadFile( psz_conf_file ); if ( psz_srv_socket != NULL ) comm_Open(); for ( ; ; ) { block_t *p_ts; if ( b_exit_now ) { msg_Info( NULL, "Shutdown was requested." ); break; } if ( b_conf_reload ) { b_conf_reload = 0; msg_Info( NULL, "Configuration reload was requested." ); config_ReadFile( psz_conf_file ); } if ( i_quit_timeout && i_quit_timeout <= i_wallclock ) { switch (i_print_type) { case PRINT_XML: printf("</TS>\n"); break; default: break; } exit(EXIT_SUCCESS); } p_ts = pf_Read( i_poll_timeout ); if ( p_ts != NULL ) { mrtgAnalyse(p_ts); demux_Run( p_ts ); } i_poll_timeout = output_Send(); if ( i_poll_timeout == -1 || i_poll_timeout > MAX_POLL_TIMEOUT ) i_poll_timeout = MAX_POLL_TIMEOUT; } mrtgClose(); outputs_Close( i_nb_outputs ); demux_Close(); free( p_network_name ); if ( b_enable_syslog ) msg_Disconnect(); if ( psz_srv_socket && i_comm_fd > -1 ) unlink( psz_srv_socket ); return EXIT_SUCCESS; }