static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct opts *opts = state->input; switch (key) { case 'a': new_op(opts, OPT_OP_ADD, arg); break; case 'r': new_op(opts, OPT_OP_REM, arg); break; case 'j': opts->journal_resume = true; break; case 'b': opts->journal_abort = true; break; case ARGP_KEY_END: if (!opts->journal_abort && !opts->journal_resume && opts->ops_cnt == 0) argp_error(state, "No operation specified. Please specify what to do."); break; default: return ARGP_ERR_UNKNOWN; }; if (opts->journal_abort && opts->journal_resume) argp_error(state, "Aborting and resuming journal at the same time is not possible."); return 0; }
/*** argument handling ************************************************/ static void parse_cpu_map(const char *arg, struct argp_state *state) { errno = 0; const char *s = arg; while (*s) { char *endptr; long cpu; if (num_mappings >= MAX_CPUS) argp_error(state, "Unsupported number of CPU mappings, only " "%i CPUs supported", MAX_CPUS); cpu = strtol(s, &endptr, 0); if (s == endptr || errno != 0) argp_error(state, "Invalid CPU map specification"); if (cpu > INT_MAX || cpu < INT_MIN) argp_error(state, "CPU number out of range"); if (*endptr != '\0' && *endptr != CPU_DELIM) argp_error(state, "Invalid character in CPU map specification"); if (*endptr == CPU_DELIM) endptr++; cpu_map[num_mappings++] = (int)cpu; s = endptr; } }
static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *arguments = state->input; long value; char *end; switch (key) { case 'r': ; value = strtol(arg, &end, 10); if (*end != '\0' || value <= 0 || value > 255) { argp_error(state, "invalid radius integer: '%s'", arg); } arguments->radius = value; break; case 'i': ; value = strtol(arg, &end, 10); if (*end != '\0' || value <= 0 || value > 255) { argp_error(state, "invalid iterations integer: '%s'", arg); } arguments->iterations = value; break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_opt(int key, char* arg, struct argp_state* state) { Args& a = *((Args*)state->input); switch (key) { case 'g': a.generator = getMGTypeFromName(arg); if (a.generator == MazeGenerator::Type::UNKNOWN) { argp_error(state, "unknown generator -- '%s'", arg); } break; case 'c': a.renderer = ConsoleMazeRenderer::RenderType::COLOR; break; case 'n': a.renderer = ConsoleMazeRenderer::RenderType::NO_COLOR; break; case ARGP_KEY_ARG: handleArg(state, arg, a); break; case ARGP_KEY_END: if (!a.valid()) argp_error(state, "too few arguments"); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
error_t miaoDetectParser (int key, char *arg, struct argp_state *state) { miaoDetectArgs *args = (miaoDetectArgs*) state->input; switch (key) { case LOW_K_KEY: args->lowK = atoi(arg); return 0; case HIGH_K_KEY: args->highK = atoi(arg); return 0; case ARGP_KEY_ARG: // A non-option key - the audio file or output file switch (state->arg_num) { case 0: args->audioFile = arg; break; default: argp_usage(state); } return 0; case ARGP_KEY_END: // End of non-options - check to make sure we have the audio file and ks are valid if (!args->audioFile) argp_usage(state); if (args->lowK == -1 || args->highK == -1) argp_usage(state); if (args->lowK > args->highK) argp_error(state, "incorrect order for k values"); if (args->lowK < 1 || args->lowK > 79) argp_error(state, "invalid lower k - try 1-79"); if (args->highK < 1 || args->highK > 79) argp_error(state, "invalid upper k - try 1-79"); return 0; default: return ARGP_ERR_UNKNOWN; } }
long arg_to_long(const struct argp_state *state, const char *arg) { char *end; long l = strtol(arg, &end, 0); if (!arg) argp_error(state, "An integer must be provided"); if (!*arg || *end) argp_error(state, "'%s' is not an integer", arg); return l; }
static void parse_exec_spec(int argc, char *argv[], struct argp_state *state) { bench_process_t *p = processes; while (argc) { if (num_processes >= MAX_CPUS) argp_error(state, "Unsupported number of processes, only " "%i processes supported", MAX_CPUS); memset(p, '\0', sizeof(bench_process_t)); p->cpu = parse_exec_spec_get_cpu(p - processes, state); p->pid = 0; p->argc = 0; if (*argv[0] == '@') { p->wd = argv[0] + 1; --argc; ++argv; } if (!argc) argp_error(state, "Target specification lacks binary name"); p->argv = argv; while (argc) { if (!strcmp("--", *argv)) { *argv = NULL; ++argv; --argc; break; } else if (!strcmp("<", *argv)) { if (argc <= 1) argp_error(state, "No input file specified for STDIN " "redirection."); if (argc > 2 && strcmp("--", argv[2])) argp_error(state, "Illegal token after STDIN redirection"); p->stdin = fopen(argv[1], "r"); if (!p->stdin) argp_failure(state, EXIT_FAILURE, errno, "Failed to open input file"); argv += 2; argc -= 2; } else { ++p->argc; ++argv; --argc; } } ++p; ++num_processes; } }
/* Parse a single option. */ static error_t parse_opt(int key, char *arg, struct argp_state *state) { OFDPA_ERROR_t rc; switch (key) { case 'c': /* count */ errno = 0; count = strtoul(arg, NULL, 0); if (errno != 0) { argp_error(state, "Invalid count \"%s\"", arg); return errno; } break; case 'l': showValidTableIds = 1; break; case 'v': showEmptyTables = 1; break; case ARGP_KEY_ARG: errno = 0; tableId = strtoul(arg, NULL, 0); if (errno != 0) { argp_error(state, "Invalid table ID argument\"%s\"", arg); return errno; } rc = ofdpaFlowTableSupported(tableId); if (rc != OFDPA_E_NONE) { argp_error(state, "Unsupported table ID (%d) (ofdpaFlowTableSupported() returns %d)", tableId, rc); return ENOTSUP; } tableIdSpecified = 1; break; case ARGP_KEY_NO_ARGS: break; case ARGP_KEY_END: break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct args *args = state->input; long l; switch (key) { case 's': l = arg_to_long(state, arg); if (l <= 0) argp_error(state, "NUM must be greater than zero"); args->start_at = l - 1; break; case 'e': l = arg_to_long(state, arg); if (l <= 0) argp_error(state, "NUM must be greater than zero"); args->end_at = l - 1; break; case 'p': args->show_progress = !!arg_to_long(state, arg); break; case ARGP_KEY_INIT: args->dev_path = NULL; break; case ARGP_KEY_ARG: if (args->dev_path) argp_error(state, "Wrong number of arguments; only one is allowed"); args->dev_path = arg; break; case ARGP_KEY_END: if (!args->dev_path) argp_error(state, "The disk path was not specified"); if (args->start_at > args->end_at) argp_error(state, "Option --start-at must be less or equal to option --end-at"); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_opt (int key, char *arg, struct argp_state *state) { char *p; static bool host_is_given = false; switch (key) { case 'p': opt_port = strtoul (arg, &p, 0); if (*p || opt_port == 0 || opt_port > 65536) error (EXIT_FAILURE, 0, "invalid port number `%s'", arg); break; case OPT_RESOLVE: opt_resolve_hostnames = 1; break; case 'q': opt_max_tries = (int) strtol (arg, &p, 10); if (*p) argp_error (state, "invalid value (`%s' near `%s')", arg, p); if (opt_max_tries < 1 || opt_max_tries > 10) error (EXIT_FAILURE, 0, "number of tries should be between 1 and 10"); break; case 'M': if (strcmp (arg, "icmp") == 0) opt_type = TRACE_ICMP; else if (strcmp (arg, "udp") == 0) opt_type = TRACE_UDP; else argp_error (state, "invalid method"); break; case ARGP_KEY_ARG: host_is_given = true; hostname = xstrdup(arg); break; case ARGP_KEY_SUCCESS: if (!host_is_given) argp_error (state, "missing host operand"); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_opt (int key, char *arg, struct argp_state *state) { static mu_list_t lst; switch (key) { case 'd': mu_argp_node_list_new (lst, "debug", "yes"); break; case 'u': unlock = 1; break; case 'r': if (arg) mu_argp_node_list_new (lst, "retry", arg); break; case 'f': mu_argp_node_list_new (lst, "force", arg ? arg : "0"); break; case ARGP_KEY_ARG: if (file) argp_error (state, _("only one FILE can be specified")); file = arg; break; case ARGP_KEY_NO_ARGS: if (!mu_help_config_mode) argp_error (state, _("FILE must be specified")); return ARGP_ERR_UNKNOWN; case ARGP_KEY_INIT: mu_argp_node_list_init (&lst); break; case ARGP_KEY_FINI: mu_argp_node_list_finish (lst, NULL, NULL); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
int parse_options(int key, char *arg, struct argp_state *state) { int r; if ((r = argp_action_wrapper(key, arg, state)) != ARGP_ERR_UNKNOWN) { switch (key) { case 'i': if (r == EINVAL || !inrange(waitproc_options.interval_sec, 1, UINT_MAX+1)) { argp_error(state, "'%s' is not a time period from 1 to %u seconds.", arg, UINT_MAX); return EINVAL; } break; } return r; } switch (key) { case ARGP_KEY_ARG: { unsigned int remainig_argc = (unsigned int)(state->argc - state->next + 1); a_flagged_int_init(&waitproc_options.pids, remainig_argc); if (parse_pids(remainig_argc, &state->argv[state->next-1]) > 0) { state->next = state->argc; return 0; } // else: fall through } case ARGP_KEY_NO_ARGS: argp_usage(state); // don't return or fall through } return ARGP_ERR_UNKNOWN; }
/** \brief Enable debug-level \p name. * * \details This function enables the debug-level \p name. It will be OR'ed with * the current enabled levels. * * * \param state The argp parser state. * \param name Name of the level to be enabled. */ static void set_dbglevel(const struct argp_state *state, const char *name) { /* Store the selected level in a static int, so it doesn't have to be looked * up in the next invocation of this function and can be OR'ed directly. */ static int level = 0; /* Compare the debug level name with the available debug levels of PnMPI. If * the name is known, it will be OR'ed with the current debug level to get the * new one. If the level is unknown an error will be printed and PnMPIze * exits. */ if (strcmp(name, "init") == 0) level = level | PNMPI_DEBUG_INIT; else if (strcmp(name, "modules") == 0) level = level | PNMPI_DEBUG_MODULE; else if (strcmp(name, "call") == 0) level = level | PNMPI_DEBUG_CALL; else argp_error(state, "Unknown debug level %s.", name); /* Set the new debug level as PNMPI_DBGLEVEL environment variable. For this * the level must be converted into a string. */ char buffer[11]; snprintf(buffer, 11, "%d", level); setenv("PNMPI_DBGLEVEL", buffer, 1); }
void handleArg(struct argp_state *state, char* arg, Args& a) { char* p = nullptr; //initialized to suppress warnings; the program exits before it's used w/o initialization if (a.width == -1) { a.width = strtol(arg, &p, 10); if (a.width <= 0) argp_error(state, "width must be greater than 0"); } else if (a.height == -1) { a.height = strtol(arg, &p, 10); if (a.height <= 0) argp_error(state, "height must be greater than 0"); } else { argp_error(state, "too many args"); } if (*p != 0) { argp_error(state, "invalid arg -- '%s'", arg); } }
static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct parse *p = state->input; switch (key) { case 1: /* * We must check that arg is not NULL as passing --tool * (with no =...) leads to argp giving us a null pointer for arg. */ if (arg) { size_t i; for (i = 0; i < n_tools; i++) { if (strcmp(arg, tools[i].key) == 0) { p->tool = i; return 0; } } argp_error(state, "Unknown tool '%s', try 'memcheck'.", arg); } argp_error(state, "No tool specified."); case 2: /* Library path. */ if (arg) { /* * Stat the argument to verify that it is a file or directory, * caching the result. */ int ret = stat(arg, &p->library_stat); if (ret < 0) { argp_error(state, "Unable to stat '%s'.", arg); } else if (!(p->library_stat.st_mode & (S_IFREG | S_IFDIR))) { argp_error(state, "'%s' is not a file or directory.", arg); } p->library_path = arg; } break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { case 's': scale = 0; break; case 'c': parse_cpu_map(arg, state); break; case 'l': log_base = arg; break; case 'q': quiet = 1; break; case OPT_NO_SPLIT_LOGS: split_logs = 0; break; case ARGP_KEY_ARG: if (!state->quoted) argp_error(state, "Invalid argument."); break; case ARGP_KEY_END: if (state->quoted && state->quoted < state->argc) parse_exec_spec(state->argc - state->quoted, state->argv + state->quoted, state); if (num_processes == 0) argp_error(state, "No target processes specified"); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
/* Parse a single option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { struct storeio_argp_params *params = state->input; switch (key) { case 'r': params->dev->readonly = 1; break; case 'w': params->dev->readonly = 0; break; case 'c': params->dev->inhibit_cache = 1; break; case 'e': params->dev->enforced = 1; break; case 'F': params->dev->no_fileio = 1; break; case 'n': { char *start = arg, *end; dev_t rdev; rdev = strtoul (start, &end, 0); if (*end == ',') /* MAJOR,MINOR form */ { start = end + 1; rdev = makedev (rdev, strtoul (start, &end, 0)); } if (end == start || *end != '\0') { argp_error (state, "%s: Invalid argument to --rdev", arg); return EINVAL; } params->dev->rdev = rdev; } break; case ARGP_KEY_INIT: /* Now store_argp's parser will get to initialize its state. The default_type member is our input parameter to it. */ bzero (¶ms->store_params, sizeof params->store_params); params->store_params.default_type = "device"; params->store_params.store_optional = 1; state->child_inputs[0] = ¶ms->store_params; break; case ARGP_KEY_SUCCESS: params->dev->store_name = params->store_params.result; break; default: return ARGP_ERR_UNKNOWN; } return 0; }
error_t MiaoStegAlgorithm::argp(int key, char *arg, struct argp_state *state) { if (key == KVAR_KEY) { k = atoi(arg); if (k < 1 || k > 79) argp_error(state, "%s is not a valid k - try 1-79", arg); std::cout << "[Miao] K: " << arg << std::endl; return 0; } else if (key == LAMBDA_KEY) { maxLambda = atoi(arg); if (maxLambda < 8 || maxLambda > 127) argp_error(state, "%s is not a valid lambda - try 8-127", arg); std::cout << "[Miao] Max Lambda: " << arg << std::endl; return 0; } else { return ARGP_ERR_UNKNOWN; } }
/* Parse a command line option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { /* We save our parsed values in this structure, hung off STATE->hook. Only after parsing all options successfully will we use these values. */ struct { int debug_flag; unsigned int sb_block; } *values = state->hook; switch (key) { case 'D': values->debug_flag = 1; break; case 'S': values->sb_block = strtoul (arg, &arg, 0); if (!arg || *arg != '\0') { argp_error (state, "invalid number for --sblock"); return EINVAL; } break; case ARGP_KEY_INIT: state->child_inputs[0] = state->input; values = malloc (sizeof *values); if (values == 0) return ENOMEM; state->hook = values; memset (values, 0, sizeof *values); values->sb_block = SBLOCK_BLOCK; break; case ARGP_KEY_SUCCESS: /* All options parse successfully, so implement ours if possible. */ if (values->debug_flag) { #ifdef EXT2FS_DEBUG ext2_debug_flag = !ext2_debug_flag; #else argp_failure (state, 2, 0, "debugging support not compiled in"); return EINVAL; #endif } break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static int parse_exec_spec_get_cpu(int logical_cpu, struct argp_state *state) { if (!num_mappings) return logical_cpu; if (logical_cpu >= num_mappings) argp_error(state, "Error: No mapping for logical CPU '%i'.\n", logical_cpu); return cpu_map[logical_cpu]; }
static void init_hw_ctr(const char *arg, struct argp_state *state) { assert(is_hw_event(arg)); const char *ctr = arg + sizeof(prefix_hw_event) - 1; const event_name_id_t *event = find_event(hw_events, ctr, 0); if (event) init_ctr(PERF_TYPE_HARDWARE, event->id); else argp_error(state, "Invalid hardware event specified.\n"); }
long perf_argp_parse_long(const char *name, const char *arg, struct argp_state *state) { char *endptr; long value; errno = 0; value = strtol(arg, &endptr, 0); if (errno) argp_failure(state, EXIT_FAILURE, errno, "Invalid %s", name); else if (*arg == '\0' || *endptr != '\0') argp_error(state, "Invalid %s: '%s' is not a number.\n", name, arg); return value; }
static void init_hwc_ctr(const char *arg, struct argp_state *state) { assert(is_hwc_event(arg)); const char *ctr = arg + sizeof(prefix_hwc_event) - 1; const event_name_id_t *event = find_event(hwc_events, ctr, 1); if (event) { const int event_name_len = strlen(event->name); const char *cur = ctr + event_name_len; uint8_t cache_id = (uint8_t)event->id; uint8_t op_id; uint8_t res_id; if (cur[0] != ':' || cur[1] == '\0') argp_error(state, "No cache op specified.\n"); switch (*(++cur)) { case 'r': op_id = PERF_COUNT_HW_CACHE_OP_READ; break; case 'w': op_id = PERF_COUNT_HW_CACHE_OP_WRITE; break; case 'p': op_id = PERF_COUNT_HW_CACHE_OP_PREFETCH; break; default: argp_error(state, "Invalid cache op specified.\n"); } cur++; if (cur[0] != ':' || cur[1] == '\0') argp_error(state, "No cache result specified.\n"); switch (*(++cur)) { case 'a': res_id = PERF_COUNT_HW_CACHE_RESULT_ACCESS; break; case 'm': res_id = PERF_COUNT_HW_CACHE_RESULT_MISS; break; default: argp_error(state, "Invalid cache result specified.\n"); } cur++; if (cur[0] != '\0') argp_error(state, "Illegal HWC string specified.\n"); init_ctr(PERF_TYPE_HW_CACHE, (res_id << 16) | (op_id << 8) | cache_id); } else argp_error(state, "Invalid cache specified.\n"); }
///@brief Argp Parser Function for example-specific command line options ///@return Zero or error code specifying how to continue static error_t dummy_parse_opt( const int key, ///< [in] Key field from the options vector char *arg, ///< [in,out] Value given as option argument struct argp_state *state) ///< [in,out] Parsing state for use by parser { // Retreive the input argument from argp_parse struct tool_config *tool = state->input; switch (key) { case OPT_SET_SERIAL: if (0 != parse_serial(&tool->overrides, arg)) { argp_error(state, _("Invalid serial number `%s' specified."), arg); } break; default: return ARGP_ERR_UNKNOWN; } return 0; }
/* Parse a single option: */ error_t parse_opt(int key, char *arg, struct argp_state *state) { struct cropparams *p = state->input; /* Pass `gal_options_common_params' into the child parser. */ state->child_inputs[0] = &p->cp; /* In case the user incorrectly uses the equal sign (for example with a short format or with space in the long format, then `arg` start with (if the short version was called) or be (if the long version was called with a space) the equal sign. So, here we check if the first character of arg is the equal sign, then the user is warned and the program is stopped: */ if(arg && arg[0]=='=') argp_error(state, "incorrect use of the equal sign (`=`). For short " "options, `=` should not be used and for long options, " "there should be no space between the option, equal sign " "and value"); /* Set the key to this option. */ switch(key) { /* Read the non-option tokens (arguments): */ case ARGP_KEY_ARG: gal_list_str_add(&p->inputs, arg, 0); ++p->numin; break; /* This is an option, set its value. */ default: return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp); } return 0; }
static error_t parse_opt (int key, char *arg, struct argp_state *state) { char *endptr; u_char pattern[16]; switch (key) { case 'c': count = ping_cvt_number (arg, 0, 0); break; case 'd': socket_type |= SO_DEBUG; break; case 'f': if (!is_root) error (EXIT_FAILURE, errno, NULL); options |= OPT_FLOOD; setbuf (stdout, (char *) NULL); break; case 'i': options |= OPT_INTERVAL; interval = ping_cvt_number (arg, 0, 0); break; case 'l': if (!is_root) error (EXIT_FAILURE, errno, NULL); preload = strtoul (arg, &endptr, 0); if (*endptr || preload > INT_MAX) error (EXIT_FAILURE, errno, NULL); break; case 'n': options |= OPT_NUMERIC; break; case 'p': decode_pattern (arg, &pattern_len, pattern); patptr = pattern; break; case 'q': options |= OPT_QUIET; break; case 'r': socket_type |= SO_DONTROUTE; break; case 'w': timeout = ping_cvt_number (arg, INT_MAX, 0); break; case 's': data_length = ping_cvt_number (arg, PING_MAX_DATALEN, 1); break; case ARGP_KEY_NO_ARGS: argp_error (state, "missing host operand"); default: return ARGP_ERR_UNKNOWN; } return 0; }
/** Argument parsing routine. * Used by the argp suite. */ static error_t _crywrap_config_parse_opt(int key, char *arg, struct argp_state *state) { crywrap_config_t *cfg = (crywrap_config_t *) state->input; int ret; switch (key) { case 'D': cfg->debug = 1; cry_log = debug_log; cry_error = debug_log; break; case 'd': if (_crywrap_parse_ip (arg, &cfg->dest.port, &cfg->dest.addr, &cfg->dest.host) < 0) argp_error(state, "Could not resolve address: `%s'", arg); break; case 'l': if (_crywrap_parse_ip(arg, &cfg->listen.port, &cfg->listen.addr, NULL) < 0) argp_error(state, "Could not resolve address: `%s'", arg); break; case 'u': cfg->uid = atoi(arg); break; case 'P': if (arg && *arg) cfg->pidfile = strdup(arg); else cfg->pidfile = NULL; break; case 'r': if (arg && *arg) { dh_file = load_file(arg); if (dh_file.data == NULL) argp_error(state, "error loading Diffie Hellman parameters file: %s.", arg); } break; case 'p': if (arg && *arg) { const char *pos; ret = gnutls_priority_init(&cfg->priority, arg, &pos); if (ret < 0) argp_error(state, "error in priority string at: %s.", pos); } break; case 'c': if (arg && *arg) pem_cert = strdup(arg); break; case 'k': if (arg && *arg) pem_key = strdup(arg); break; break; case 'i': cfg->inetd = 1; break; case 'a': { const char *pos; ret = gnutls_priority_init(&cfg->priority, "NORMAL:+ANON-ECDH:+ANON-DH", &pos); if (ret < 0) argp_error(state, "error in priority string at: %s.", pos); } cfg->verify = 0; cfg->anon = 1; break; case 'v': cfg->verify = (arg) ? atoi(arg) : 1; break; case 'z': ret = gnutls_certificate_set_x509_trust_file(cred, arg, GNUTLS_X509_FMT_PEM); if (ret < 0) argp_error(state, "error reading X.509 CA file: %s.", gnutls_strerror(ret)); break; case ARGP_KEY_END: if (!cfg->inetd) { if (!cfg->listen.addr || !cfg->dest.addr) argp_error (state, "a listening and a destination address must be set!"); } else if (!cfg->dest.addr) argp_error(state, "a destination address must be set!"); if (cfg->anon) break; if (pem_cert == NULL || pem_key == NULL) ret = gnutls_certificate_set_x509_key_file(cred, _CRYWRAP_PEMFILE, _CRYWRAP_PEMFILE, GNUTLS_X509_FMT_PEM); else ret = gnutls_certificate_set_x509_key_file(cred, pem_cert, pem_key, GNUTLS_X509_FMT_PEM); if (ret < 0) argp_error(state, "Error reading X.509 key or certificate file: %s", gnutls_strerror(ret)); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
static error_t parse_arg( int key, char * arg, struct argp_state *state ) { struct opdis_options * opts = state->input; switch ( key ) { case 'c': if (! add_job( opts->jobs, job_cflow, arg ) ) { argp_error( state, "Invalid argument for -c" ); } break; case 'l': if (! add_job( opts->jobs, job_linear, arg ) ) { argp_error( state, "Invalid argument for -l" ); } break; case 'a': if (! set_arch( opts, arg ) ) { argp_error( state, "Invalid argument for -s" ); } break; case 's': if (! set_syntax( opts, arg ) ) { argp_error( state, "Invalid argument for -s" ); } break; case 'f': if (! set_format( opts, arg ) ) { argp_error( state, "Invalid argument for -f" ); } break; case 'o': if (! set_output_file( opts, arg ) ) { argp_error( state, "Invalid argument for -o" ); } break; case 'b': if (! tgt_list_add( opts->targets, tgt_bytes, arg ) ) { argp_error( state, "Invalid argument for -b" ); } break; case 'm': if (! add_map( opts->map, arg ) ) { argp_error( state, "Invalid argument for -m" ); } break; case 'O': opts->disasm_opts = arg; break; case 'B': if (! set_bfd_target( opts, arg ) ) { argp_error( state, "Invalid argument for -B" ); } break; case 'E': add_bfd_job( opts, job_bfd_entry, NULL ); break; case 'N': if (! add_bfd_job( opts, job_bfd_symbol, arg ) ) { argp_error( state, "Invalid argument for -N" ); } break; case 'S': if (! add_bfd_job( opts, job_bfd_section, arg ) ) { argp_error( state, "Invalid argument for -N" ); } break; case 'q': opts->quiet = 1; break; case 1: opts->list_arch = 1; break; case 2: opts->list_disasm_opt = 1; break; case 3: opts->list_syntax = 1; break; case 4: opts->list_format = 1; break; case 5: opts->dry_run = 1; break; case ARGP_KEY_ARG: tgt_list_add( opts->targets, tgt_file, arg ); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
int main(int argc, char *argv[]) { error_t err; /* The filesystem node we're putting a translator on. */ char *node_name = 0; file_t node; /* The translator's arg vector, in '\0' separated format. */ char *argz = 0; size_t argz_len = 0; /* The control port for any active translator we start up. */ fsys_t active_control = MACH_PORT_NULL; /* Flags to pass to file_set_translator. */ int active_flags = 0; int passive_flags = 0; int lookup_flags = O_NOTRANS; int goaway_flags = 0; /* Various option flags. */ int passive = 0, active = 0, keep_active = 0, pause = 0, kill_active = 0, orphan = 0; int start = 0; int stack = 0; char *pid_file = NULL; int excl = 0; int timeout = DEFAULT_TIMEOUT * 1000; /* ms */ char *underlying_node_name = NULL; int underlying_lookup_flags; char **chroot_command = 0; char *chroot_chdir = "/"; /* Parse our options... */ error_t parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { case ARGP_KEY_ARG: if (state->arg_num == 0) node_name = arg; else /* command */ { if (start) argp_error (state, "both --start and TRANSLATOR given"); error_t err = argz_create (state->argv + state->next - 1, &argz, &argz_len); if (err) error(3, err, "Can't create options vector"); state->next = state->argc; /* stop parsing */ } break; case ARGP_KEY_NO_ARGS: argp_usage (state); return EINVAL; case 'a': active = 1; break; case 's': start = 1; active = 1; /* start implies active */ break; case OPT_STACK: stack = 1; active = 1; /* stack implies active */ orphan = 1; /* stack implies orphan */ break; case 'p': passive = 1; break; case 'k': keep_active = 1; break; case 'g': kill_active = 1; break; case 'x': excl = 1; break; case 'P': pause = 1; break; case 'F': pid_file = strdup (arg); if (pid_file == NULL) error(3, ENOMEM, "Failed to duplicate argument"); break; case 'o': orphan = 1; break; case 'U': underlying_node_name = strdup (arg); if (underlying_node_name == NULL) error(3, ENOMEM, "Failed to duplicate argument"); break; case 'C': if (chroot_command) { argp_error (state, "--chroot given twice"); return EINVAL; } chroot_command = &state->argv[state->next]; while (state->next < state->argc) { if (!strcmp (state->argv[state->next], "--")) { state->argv[state->next++] = 0; if (chroot_command[0] == 0) { argp_error (state, "--chroot must be followed by a command"); return EINVAL; } return 0; } ++state->next; } argp_error (state, "--chroot command must be terminated with `--'"); return EINVAL; case OPT_CHROOT_CHDIR: if (arg[0] != '/') argp_error (state, "--chroot-chdir must be absolute"); chroot_chdir = arg; break; case 'c': lookup_flags |= O_CREAT; break; case 'L': lookup_flags &= ~O_NOTRANS; break; case 'R': goaway_flags |= FSYS_GOAWAY_RECURSE; break; case 'S': goaway_flags |= FSYS_GOAWAY_NOSYNC; break; case 'f': goaway_flags |= FSYS_GOAWAY_FORCE; break; /* Use atof so the user can specifiy fractional timeouts. */ case 't': timeout = atof (arg) * 1000.0; break; default: return ARGP_ERR_UNKNOWN; } return 0; } struct argp argp = {options, parse_opt, args_doc, doc}; argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0); if (stack) { underlying_node_name = node_name; underlying_lookup_flags = lookup_flags && ~O_NOTRANS; } else underlying_lookup_flags = lookup_flags; if (!active && !passive && !chroot_command) passive = 1; /* By default, set the passive translator. */ if (passive) passive_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0); if (active) active_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0) | (orphan ? FS_TRANS_ORPHAN : 0); if (passive && !active) { /* When setting just the passive, decide what to do with any active. */ if (kill_active) /* Make it go away. */ active_flags = FS_TRANS_SET; else if (! keep_active) /* Ensure that there isn't one. */ active_flags = FS_TRANS_SET | FS_TRANS_EXCL; } if (start) { /* Retrieve the passive translator record in argz. */ mach_port_t node = file_name_lookup (node_name, lookup_flags, 0); if (node == MACH_PORT_NULL) error (4, errno, "%s", node_name); char buf[1024]; argz = buf; argz_len = sizeof (buf); err = file_get_translator (node, &argz, &argz_len); if (err == EINVAL) error (4, 0, "%s: no passive translator record found", node_name); if (err) error (4, err, "%s", node_name); mach_port_deallocate (mach_task_self (), node); } if ((active || chroot_command) && argz_len > 0) { /* Error during file lookup; we use this to avoid duplicating error messages. */ error_t open_err = 0; /* The callback to start_translator opens NODE as a side effect. */ error_t open_node (int flags, mach_port_t *underlying, mach_msg_type_name_t *underlying_type, task_t task, void *cookie) { if (pause) { fprintf (stderr, "Translator pid: %d\nPausing...", task2pid (task)); getchar (); } if (pid_file != NULL) { FILE *h; h = fopen (pid_file, "w"); if (h == NULL) error (4, errno, "Failed to open pid file"); fprintf (h, "%i\n", task2pid (task)); fclose (h); } node = file_name_lookup (node_name, flags | lookup_flags, 0666); if (node == MACH_PORT_NULL) { open_err = errno; return open_err; } if (underlying_node_name) { *underlying = file_name_lookup (underlying_node_name, flags | underlying_lookup_flags, 0666); if (! MACH_PORT_VALID (*underlying)) { /* For the error message. */ node_name = underlying_node_name; open_err = errno; return open_err; } } else *underlying = node; *underlying_type = MACH_MSG_TYPE_COPY_SEND; return 0; } err = fshelp_start_translator (open_node, NULL, argz, argz, argz_len, timeout, &active_control); if (err) /* If ERR is due to a problem opening the translated node, we print that name, otherwise, the name of the translator. */ error(4, err, "%s", (err == open_err) ? node_name : argz); }
/* Parse our options... */ error_t parse_opt (int key, char *arg, struct argp_state *state) { error_t err; switch (key) { case 'v': verbose = 1; break; case 'n': numeric = 1; break; case 's': subsystem = 1; break; #define SELECT_TARGET(target) \ if (setup_target) \ argp_error (state, "Multiple targets specified."); \ setup_target = target; case OPT_TARGET_TASK: SELECT_TARGET (setup_task_target); break; case OPT_TARGET_THREAD: SELECT_TARGET (setup_thread_target); break; case OPT_TARGET_PROC: SELECT_TARGET (setup_proc_target); break; case OPT_TARGET_AUTH: SELECT_TARGET (setup_auth_target); break; case OPT_TARGET_EXTRACT:; process_t proc; pid_t pid; char *end; pid = strtol (arg, &end, 10); if (arg == end || *end != '.') argp_error (state, "Expected format PID.PORT, got `%s'.", arg); arg = end + 1; extract_target_port = strtol (arg, &end, 10); if (arg == end || *end != '\0') argp_error (state, "Expected format PORT, got `%s'.", arg); proc = getproc (); err = proc_pid2task (proc, pid, &extract_target_task); if (err) argp_failure (state, 1, err, "Could not get task of process %d", pid); extract_target_type = MACH_MSG_TYPE_COPY_SEND; /* XXX */ SELECT_TARGET (setup_extract_target); break; case ARGP_KEY_ARG: SELECT_TARGET (setup_hurd_target); setup_argument = arg; break; #undef SELECT_TARGET case ARGP_KEY_NO_ARGS: if (setup_target == NULL) argp_usage (state); break; default: return ARGP_ERR_UNKNOWN; } return 0; }