Пример #1
0
/*****************************************************************************
 * 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 );
}
Пример #2
0
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;

}
Пример #3
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);
}
Пример #4
0
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( &param, 0, sizeof(struct sched_param) );
        param.sched_priority = i_priority;
        if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR,
                                               &param )) )
        {
            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;
}
Пример #5
0
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 );
    }
}
Пример #6
0
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;

}
Пример #7
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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( &param, 0, sizeof(struct sched_param) );
        param.sched_priority = i_priority;
        if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR,
                                               &param )) )
        {
            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;
}