static void config_Defaults( output_config_t *p_config ) { config_Init( p_config ); p_config->i_config = (b_udp_global ? OUTPUT_UDP : 0) | (b_dvb_global ? OUTPUT_DVB : 0) | (b_epg_global ? OUTPUT_EPG : 0); p_config->i_max_retention = i_retention_global; p_config->i_output_latency = i_latency_global; p_config->i_tsid = -1; p_config->i_ttl = i_ttl_global; memcpy( p_config->pi_ssrc, pi_ssrc_global, 4 * sizeof(uint8_t) ); }
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 ); } }
/***************************************************************************** * output_Init : set up the output initial config *****************************************************************************/ int output_Init( output_t *p_output, const output_config_t *p_config ) { socklen_t i_sockaddr_len = (p_config->i_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); memset( p_output, 0, sizeof(output_t) ); config_Init( &p_output->config ); /* Init run-time values */ p_output->p_packets = p_output->p_last_packet = NULL; p_output->i_seqnum = rand() & 0xffff; p_output->i_pat_cc = rand() & 0xf; p_output->i_pmt_cc = rand() & 0xf; p_output->i_nit_cc = rand() & 0xf; p_output->i_sdt_cc = rand() & 0xf; p_output->i_eit_cc = rand() & 0xf; p_output->i_pat_version = rand() & 0xff; p_output->i_pmt_version = rand() & 0xff; p_output->i_nit_version = rand() & 0xff; p_output->i_sdt_version = rand() & 0xff; p_output->p_pat_section = NULL; p_output->p_pmt_section = NULL; p_output->p_nit_section = NULL; p_output->p_sdt_section = NULL; p_output->p_eit_ts_buffer = NULL; if ( b_random_tsid ) p_output->i_tsid = rand() & 0xffff; /* Init the mapped pids to unused */ p_output->b_do_remap = p_config->b_do_remap; init_pid_mapping( p_output ); /* Init socket-related fields */ p_output->config.i_family = p_config->i_family; memcpy( &p_output->config.connect_addr, &p_config->connect_addr, sizeof(struct sockaddr_storage) ); memcpy( &p_output->config.bind_addr, &p_config->bind_addr, sizeof(struct sockaddr_storage) ); p_output->config.i_if_index_v6 = p_config->i_if_index_v6; if ( (p_config->i_config & OUTPUT_RAW) ) { p_output->config.i_config |= OUTPUT_RAW; p_output->i_handle = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ); } else { p_output->i_handle = socket( p_config->i_family, SOCK_DGRAM, IPPROTO_UDP ); } if ( p_output->i_handle < 0 ) { msg_Err( NULL, "couldn't create socket (%s)", strerror(errno) ); p_output->config.i_config &= ~OUTPUT_VALID; return -errno; } int ret = 0; if ( p_config->bind_addr.ss_family != AF_UNSPEC ) { if ( bind( p_output->i_handle, (struct sockaddr *)&p_config->bind_addr, i_sockaddr_len ) < 0 ) msg_Warn( NULL, "couldn't bind socket (%s)", strerror(errno) ); if ( p_config->i_family == AF_INET ) { struct sockaddr_in *p_connect_addr = (struct sockaddr_in *)&p_output->config.connect_addr; struct sockaddr_in *p_bind_addr = (struct sockaddr_in *)&p_output->config.bind_addr; if ( IN_MULTICAST( ntohl( p_connect_addr->sin_addr.s_addr ) ) ) ret = setsockopt( p_output->i_handle, IPPROTO_IP, IP_MULTICAST_IF, (void *)&p_bind_addr->sin_addr.s_addr, sizeof(p_bind_addr->sin_addr.s_addr) ); } } if ( (p_config->i_config & OUTPUT_RAW) ) { struct sockaddr_in *p_connect_addr = (struct sockaddr_in *)&p_output->config.connect_addr; RawFillHeaders(&p_output->raw_pkt_header, inet_addr(p_config->psz_srcaddr), p_connect_addr->sin_addr.s_addr, (uint16_t) p_config->i_srcport, ntohs(p_connect_addr->sin_port), p_config->i_ttl, p_config->i_tos, 0); } if ( p_config->i_family == AF_INET6 && p_config->i_if_index_v6 != -1 ) { struct sockaddr_in6 *p_addr = (struct sockaddr_in6 *)&p_output->config.connect_addr; if ( IN6_IS_ADDR_MULTICAST( &p_addr->sin6_addr ) ) ret = setsockopt( p_output->i_handle, IPPROTO_IPV6, IPV6_MULTICAST_IF, (void *)&p_config->i_if_index_v6, sizeof(p_config->i_if_index_v6) ); } if (ret == -1) msg_Warn( NULL, "couldn't join multicast address (%s)", strerror(errno) ); if ( connect( p_output->i_handle, (struct sockaddr *)&p_output->config.connect_addr, i_sockaddr_len ) < 0 ) { msg_Err( NULL, "couldn't connect socket (%s)", strerror(errno) ); close( p_output->i_handle ); p_output->config.i_config &= ~OUTPUT_VALID; return -errno; } p_output->config.i_config |= OUTPUT_VALID; return 0; }