src/options.c
/**
 * Returns 0 for help, 1 on error, 2 on success.
 */
Returns 0 for help, 1 on error, 2 on success.
Returns 0 for help 1 on error 2 on success .
int options_parse(struct config *conf, const int argc, char *const argv[])
{
    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {"addr",       required_argument, 0, 'a'},
            {"config",     required_argument, 0, 'c'},
            {"log",        required_argument, 0, 'l'},
            {"max-peers",  required_argument, 0, 'm'},
            {"output",     required_argument, 0, 'o'},
            {"port",       required_argument, 0, 'p'},
            {"syslog",     no_argument,       0, 's'},
            {"help",       no_argument,       0, 'h'},
            {"version",    no_argument,       0, 'v'},
            {0}
        };
        int c = getopt_long(argc, argv, "a:c:l:m:o:p:shv",
                            long_options, &option_index);
        if (c == -1)
            break;
        switch (c) {
        case 'a':
            if (!strcpy_safer(conf->bind_addr, optarg, sizeof(conf->bind_addr))) {
                fprintf(stderr, "Wrong value for --listen.\n");
                return 1;
            }
            break;
        case 'c':
            if (!strcpy_safer(conf->conf_dir, optarg, sizeof(conf->conf_dir))) {
                fprintf(stderr, "Wrong value for --config.\n");
                return 1;
            }
            break;
        case 'l': {
            int sevmask = 0;
            for (int i = 0; log_severities[i].id; i++) {
                if (strcmp(log_severities[i].name, optarg) == 0) {
                    sevmask = log_severities[i].id;
                    break;
                }
            }
            if (!sevmask) {
                fprintf(stderr, "Wrong value for --log.\n");
                return 1;
            }
            conf->log_level = sevmask;
            break;
        }
        case 'm': {
            struct rlimit nofile = {0};
            if (getrlimit(RLIMIT_NOFILE, &nofile) == -1) {
                perror("getrlimit");
                return 1;
            }
            errno = 0;
            long val = strtol(optarg, NULL, 10);
            if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
                || (errno != 0 && val == 0)
                || (val < 1 || val > (long)nofile.rlim_cur)) {
                fprintf(stderr, "Wrong value for --max-peers."
                        " Should be in [1, %zd].\n", nofile.rlim_cur);
                return 1;
            }
            conf->max_peers = (size_t)val;
            break;
        }
        case 'o':
            break;
        case 'p':
            if (!strcpy_safer(conf->bind_port, optarg, sizeof(conf->bind_port))) {
                fprintf(stderr, "Wrong value for --port.\n");
                return 1;
            }
            break;
        case 's':
            conf->log_type = LOG_TYPE_SYSLOG;
            break;
        case 'h':
            usage();
            return 0;
        case 'v':
            printf("%s\n", PACKAGE_VERSION);
            return 0;
        case '?': 
        case ':': 
            return 1;
        default:
            usage();
            return 1;
        }
    }
    if (optind < argc) {
        fprintf(stderr, "Ignored arguments: ");
        while (optind < argc)
            fprintf(stderr, "%s ", argv[optind++]);
        fprintf(stderr, "\n");
    }
    if (!init_config(conf)) {
        fprintf(stderr, "Configuration initialization failed. Aborting\n");
        return 1;
    }
    return 2;
}
int options_parse ( struct config * conf , const int argc , char * const argv [ ] ) { while ( 1 ) { int option_index = 0 ; static struct option long_options [ ] = { { " " , required_argument , 0 , ' ' } , { " " , required_argument , 0 , ' ' } , { " " , required_argument , 0 , ' ' } , { " " , required_argument , 0 , ' ' } , { " " , required_argument , 0 , ' ' } , { " " , required_argument , 0 , ' ' } , { " " , no_argument , 0 , ' ' } , { " " , no_argument , 0 , ' ' } , { " " , no_argument , 0 , ' ' } , { 0 } } ; int c = getopt_long ( argc , argv , " " , long_options , & option_index ) ; if ( c == -1 ) break ; switch ( c ) { case ' ' : if ( ! strcpy_safer ( conf -> bind_addr , optarg , sizeof ( conf -> bind_addr ) ) ) { fprintf ( stderr , " \n " ) ; return 1 ; } break ; case ' ' : if ( ! strcpy_safer ( conf -> conf_dir , optarg , sizeof ( conf -> conf_dir ) ) ) { fprintf ( stderr , " \n " ) ; return 1 ; } break ; case ' ' : { int sevmask = 0 ; for ( int i = 0 ; log_severities [ i ] . id ; i ++ ) { if ( strcmp ( log_severities [ i ] . name , optarg ) == 0 ) { sevmask = log_severities [ i ] . id ; break ; } } if ( ! sevmask ) { fprintf ( stderr , " \n " ) ; return 1 ; } conf -> log_level = sevmask ; break ; } case ' ' : { struct rlimit nofile = { 0 } ; if ( getrlimit ( RLIMIT_NOFILE , & nofile ) == -1 ) { perror ( " " ) ; return 1 ; } errno = 0 ; long val = strtol ( optarg , NULL , 10 ) ; if ( ( errno == ERANGE && ( val == LONG_MAX || val == LONG_MIN ) ) || ( errno != 0 && val == 0 ) || ( val < 1 || val > ( long ) nofile . rlim_cur ) ) { fprintf ( stderr , " " " \n " , nofile . rlim_cur ) ; return 1 ; } conf -> max_peers = ( size_t ) val ; break ; } case ' ' : break ; case ' ' : if ( ! strcpy_safer ( conf -> bind_port , optarg , sizeof ( conf -> bind_port ) ) ) { fprintf ( stderr , " \n " ) ; return 1 ; } break ; case ' ' : conf -> log_type = LOG_TYPE_SYSLOG ; break ; case ' ' : usage ( ) ; return 0 ; case ' ' : printf ( " \n " , PACKAGE_VERSION ) ; return 0 ; case ' ' : case ' ' : return 1 ; default : usage ( ) ; return 1 ; } } if ( optind < argc ) { fprintf ( stderr , " " ) ; while ( optind < argc ) fprintf ( stderr , " " , argv [ optind ++ ] ) ; fprintf ( stderr , " \n " ) ; } if ( ! init_config ( conf ) ) { fprintf ( stderr , " \n " ) ; return 1 ; } return 2 ; }
Returns 0 for help, 1 on error, 2 on success.
Returns 0 for help 1 on error 2 on success .
// TODO: /* unknown option */ /* missing argument */