diff --git a/capinfos.c b/capinfos.c index 109c579144..09bdfc32ff 100644 --- a/capinfos.c +++ b/capinfos.c @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -1466,9 +1467,13 @@ main(int argc, char *argv[]) static const struct ws_option long_options[] = { {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST" + static const char optstring[] = OPTSTRING; + int status = 0; /* Set the program name. */ @@ -1490,7 +1495,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -1526,7 +1531,7 @@ main(int argc, char *argv[]) wtap_init(true); /* Process the options */ - while ((opt = ws_getopt_long(argc, argv, "abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST", long_options, NULL)) !=-1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) !=-1) { switch (opt) { diff --git a/captype.c b/captype.c index 10b523e22e..5204007875 100644 --- a/captype.c +++ b/captype.c @@ -38,6 +38,8 @@ #endif #include +#include +#include #include #include "ui/failure_message.h" @@ -66,8 +68,11 @@ main(int argc, char *argv[]) static const struct ws_option long_options[] = { {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "hv" + static const char optstring[] = OPTSTRING; /* Set the program name. */ g_set_prgname("captype"); @@ -88,7 +93,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, 1); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -121,7 +126,7 @@ main(int argc, char *argv[]) wtap_init(true); /* Process the options */ - while ((opt = ws_getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) !=-1) { switch (opt) { diff --git a/dftest.c b/dftest.c index f585920391..40b817033b 100644 --- a/dftest.c +++ b/dftest.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -317,6 +318,27 @@ main(int argc, char **argv) char *text = NULL; int exit_status = EXIT_FAILURE; + const char* optstring = "hvC:dDflsmrtV0"; + static const struct ws_option long_options[] = { + { "help", ws_no_argument, 0, 'h' }, + { "version", ws_no_argument, 0, 'v' }, + { "debug", ws_optional_argument, 0, 'd' }, + { "flex", ws_no_argument, 0, 'f' }, + { "lemon", ws_no_argument, 0, 'l' }, + { "syntax", ws_no_argument, 0, 's' }, + { "macros", ws_no_argument, 0, 'm' }, + { "timer", ws_no_argument, 0, 't' }, + { "verbose", ws_no_argument, 0, 'V' }, + { "return-vals", ws_no_argument, 0, 'r' }, + { "optimize", ws_required_argument, 0, 1000 }, + { "types", ws_no_argument, 0, 2000 }, + { "refs", ws_no_argument, 0, 3000 }, + { "file", ws_required_argument, 0, 4000 }, + LONGOPT_WSLOG + { NULL, 0, 0, 0 } + }; + int opt; + /* Set the program name. */ g_set_prgname("dftest"); @@ -336,7 +358,7 @@ main(int argc, char **argv) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, 1); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -359,26 +381,6 @@ main(int argc, char **argv) ws_init_version_info("DFTest", NULL, NULL); - const char *optstring = "hvC:dDflsmrtV0"; - static struct ws_option long_options[] = { - { "help", ws_no_argument, 0, 'h' }, - { "version", ws_no_argument, 0, 'v' }, - { "debug", ws_optional_argument, 0, 'd' }, - { "flex", ws_no_argument, 0, 'f' }, - { "lemon", ws_no_argument, 0, 'l' }, - { "syntax", ws_no_argument, 0, 's' }, - { "macros", ws_no_argument, 0, 'm' }, - { "timer", ws_no_argument, 0, 't' }, - { "verbose", ws_no_argument, 0, 'V' }, - { "return-vals", ws_no_argument, 0, 'r' }, - { "optimize", ws_required_argument, 0, 1000 }, - { "types", ws_no_argument, 0, 2000 }, - { "refs", ws_no_argument, 0, 3000 }, - { "file", ws_required_argument, 0, 4000 }, - { NULL, 0, 0, 0 } - }; - int opt; - for (;;) { opt = ws_getopt_long(argc, argv, optstring, long_options, NULL); if (opt == -1) diff --git a/dumpcap.c b/dumpcap.c index d43f087427..29bfe41cac 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -5163,6 +5163,7 @@ main(int argc, char *argv[]) {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, LONGOPT_CAPTURE_COMMON + LONGOPT_WSLOG {"ifname", ws_required_argument, NULL, LONGOPT_IFNAME}, {"ifdescr", ws_required_argument, NULL, LONGOPT_IFDESCR}, {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT}, @@ -5173,6 +5174,23 @@ main(int argc, char *argv[]) {0, 0, 0, 0 } }; +#ifdef HAVE_PCAP_REMOTE +#define OPTSTRING_r "r" +#define OPTSTRING_u "u" +#else +#define OPTSTRING_r +#define OPTSTRING_u +#endif + +#ifdef HAVE_PCAP_SETSAMPLING +#define OPTSTRING_m "m:" +#else +#define OPTSTRING_m +#endif + +#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:dghk:" OPTSTRING_m "MN:nPqQ" OPTSTRING_r "St" OPTSTRING_u "vw:Z:" + static const char optstring[] = OPTSTRING; + bool arg_error = false; #ifndef _WIN32 @@ -5271,7 +5289,7 @@ main(int argc, char *argv[]) #endif /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, 1); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); #if DEBUG_CHILD_DUMPCAP /* Assume that if we're specially compiled with dumpcap debugging @@ -5306,22 +5324,6 @@ main(int argc, char *argv[]) ws_init_version_info("Dumpcap", gather_dumpcap_compiled_info, gather_dumpcap_runtime_info); -#ifdef HAVE_PCAP_REMOTE -#define OPTSTRING_r "r" -#define OPTSTRING_u "u" -#else -#define OPTSTRING_r -#define OPTSTRING_u -#endif - -#ifdef HAVE_PCAP_SETSAMPLING -#define OPTSTRING_m "m:" -#else -#define OPTSTRING_m -#endif - -#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:dghk:" OPTSTRING_m "MN:nPqQ" OPTSTRING_r "St" OPTSTRING_u "vw:Z:" - #if defined(__APPLE__) && defined(__LP64__) /* * Is this Mac OS X 10.6.0, 10.6.1, 10.6.3, or 10.6.4? If so, we need @@ -5500,7 +5502,7 @@ main(int argc, char *argv[]) global_capture_opts.capture_child = capture_child; /* Now get our args */ - while ((opt = ws_getopt_long(argc, argv, OPTSTRING, long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case 'h': /* Print help and exit */ show_help_header("Capture network packets and dump them into a pcapng or pcap file."); @@ -5667,6 +5669,10 @@ main(int argc, char *argv[]) pcap_queue_packet_limit = get_positive_int(ws_optarg, "packet_limit"); break; default: + /* wslog arguments are okay */ + if (ws_log_is_wslog_arg(opt)) + break; + cmdarg_err("Invalid Option: %s", argv[ws_optind-1]); /* FALLTHROUGH */ case '?': /* Bad flag - print usage message */ diff --git a/editcap.c b/editcap.c index c2f3955f26..2a0afff4b6 100644 --- a/editcap.c +++ b/editcap.c @@ -1413,9 +1413,13 @@ main(int argc, char *argv[]) {"preserve-packet-comments", ws_no_argument, NULL, LONGOPT_PRESERVE_PACKET_COMMENTS}, {"extract-secrets", ws_no_argument, NULL, LONGOPT_EXTRACT_SECRETS}, {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "a:A:B:c:C:dD:E:F:hi:I:Lo:rR:s:S:t:T:vVw:" + static const char optstring[] = OPTSTRING; + char *p; uint32_t snaplen = 0; /* No limit */ chop_t chop = {0, 0, 0, 0, 0, 0}; /* No chop */ @@ -1458,7 +1462,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -1490,7 +1494,7 @@ main(int argc, char *argv[]) wtap_init(true); /* Process the options */ - while ((opt = ws_getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lo:rR:s:S:t:T:vVw:", long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { if (opt != LONGOPT_EXTRACT_SECRETS && opt != 'V') { edit_option_specified = true; } diff --git a/epan/prefs.c b/epan/prefs.c index e4a59123b8..8fa46010a2 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -5913,7 +5913,41 @@ set_pref(char *pref_name, const char *value, void *private_data, } else if (deprecated_port_pref(pref_name, value)) { /* Handled within deprecated_port_pref() if found */ } else if (strcmp(pref_name, "console.log.level") == 0) { - /* Handled on the command line within ws_log_parse_args() */ + + uint32_t mask; + enum ws_log_level level; + + if (!ws_basestrtou32(value, NULL, &mask, 10)) { + ws_warning("%s is not a valid decimal number for %s.", value, pref_name); + return PREFS_SET_SYNTAX_ERR; + } + + /* + * The lowest priority bit in the mask defines the level. + */ + if (mask & G_LOG_LEVEL_DEBUG) + level = LOG_LEVEL_DEBUG; + else if (mask & G_LOG_LEVEL_INFO) + level = LOG_LEVEL_INFO; + else if (mask & G_LOG_LEVEL_MESSAGE) + level = LOG_LEVEL_MESSAGE; + else if (mask & G_LOG_LEVEL_WARNING) + level = LOG_LEVEL_WARNING; + else if (mask & G_LOG_LEVEL_CRITICAL) + level = LOG_LEVEL_CRITICAL; + else if (mask & G_LOG_LEVEL_ERROR) + level = LOG_LEVEL_ERROR; + else + level = LOG_LEVEL_NONE; + + if (level == LOG_LEVEL_NONE) { + /* Some values (like zero) might not contain any meaningful bits. + * Throwing an error in that case seems appropriate. */ + ws_warning("Value %s is not a valid log mask for %s.", value, pref_name); + return PREFS_SET_SYNTAX_ERR; + } + + ws_log_set_level(level); return PREFS_SET_OK; } else { /* Handle deprecated "global" options that don't have a module diff --git a/fuzz/fuzzshark.c b/fuzz/fuzzshark.c index fcddfe386d..7f6861fea3 100644 --- a/fuzz/fuzzshark.c +++ b/fuzz/fuzzshark.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -129,7 +131,7 @@ fuzz_prefs_apply(void) } static int -fuzz_init(int argc _U_, char **argv) +fuzz_init(int argc, char **argv) { char *configuration_init_error; @@ -138,6 +140,10 @@ fuzz_init(int argc _U_, char **argv) e_prefs *prefs_p; int ret = EXIT_SUCCESS; size_t i; + static const struct ws_option long_options[] = { + LONGOPT_WSLOG + {0, 0, 0, 0 } + }; const char *fuzz_target = #if defined(FUZZ_DISSECTOR_TARGET) @@ -218,7 +224,7 @@ fuzz_init(int argc _U_, char **argv) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, LOG_ARGS_NOEXIT); + ws_log_parse_args(&argc, argv, "v", long_options, vcmdarg_err, LOG_ARGS_NOEXIT); ws_noisy("Finished log init and parsing command line log arguments"); diff --git a/mergecap.c b/mergecap.c index 185d54717c..a3659352c3 100644 --- a/mergecap.c +++ b/mergecap.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -186,8 +187,11 @@ main(int argc, char *argv[]) {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "aF:hI:s:vVw:" + static const char optstring[] = OPTSTRING; bool do_append = false; bool verbose = false; int in_file_count = 0; @@ -208,7 +212,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, 1); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -241,7 +245,7 @@ main(int argc, char *argv[]) wtap_init(true); /* Process the options first */ - while ((opt = ws_getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case 'a': diff --git a/randpkt.c b/randpkt.c index dfe8601be3..054794fd55 100644 --- a/randpkt.c +++ b/randpkt.c @@ -116,8 +116,11 @@ main(int argc, char *argv[]) static const struct ws_option long_options[] = { {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "b:c:F:ht:rv" + static const char optstring[] = OPTSTRING; /* Set the program name. */ g_set_prgname("randpkt"); @@ -128,7 +131,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -159,7 +162,7 @@ main(int argc, char *argv[]) ws_init_version_info("Randpkt", NULL, NULL); - while ((opt = ws_getopt_long(argc, argv, "b:c:F:ht:rv", long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case 'b': /* max bytes */ produce_max_bytes = get_positive_int(ws_optarg, "max bytes"); diff --git a/rawshark.c b/rawshark.c index cfa092b41f..5cadb5d03a 100644 --- a/rawshark.c +++ b/rawshark.c @@ -421,6 +421,7 @@ main(int argc, char *argv[]) {"version", ws_no_argument, NULL, 'v'}, LONGOPT_DISSECT_COMMON LONGOPT_READ_CAPTURE_COMMON + LONGOPT_WSLOG {0, 0, 0, 0 } }; @@ -447,7 +448,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); diff --git a/reordercap.c b/reordercap.c index 5f42551ffc..ac4f002254 100644 --- a/reordercap.c +++ b/reordercap.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include "ui/failure_message.h" @@ -156,8 +157,11 @@ main(int argc, char *argv[]) static const struct ws_option long_options[] = { {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; +#define OPTSTRING "hnv" + static const char optstring[] = OPTSTRING; int file_count; char *infile; const char *outfile; @@ -171,7 +175,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); @@ -200,7 +204,7 @@ main(int argc, char *argv[]) wtap_init(true); /* Process the options first */ - while ((opt = ws_getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case 'n': write_output_regardless = false; diff --git a/sharkd.c b/sharkd.c index dd0f5259c9..1ba0ba23ea 100644 --- a/sharkd.c +++ b/sharkd.c @@ -71,6 +71,49 @@ capture_file cfile; static uint32_t cum_bytes; static frame_data ref_frame; +/* + * The leading + ensures that getopt_long() does not permute the argv[] + * entries. + * + * We have to make sure that the first getopt_long() preserves the content + * of argv[] for the subsequent getopt_long() call. + * + * We use getopt_long() in both cases to ensure that we're using a routine + * whose permutation behavior we can control in the same fashion on all + * platforms, and so that, if we ever need to process a long argument before + * doing further initialization, we can do so. + * + * Glibc and Solaris libc document that a leading + disables permutation + * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD + * and macOS don't document it, but do so anyway. + * + * We do *not* use a leading - because the behavior of a leading - is + * platform-dependent. + */ + +static const struct ws_option long_options[] = { + {"api", ws_required_argument, NULL, 'a'}, + {"foreground", ws_no_argument, NULL, LONGOPT_FOREGROUND}, + {"help", ws_no_argument, NULL, 'h'}, + {"version", ws_no_argument, NULL, 'v'}, + {"config-profile", ws_required_argument, NULL, 'C'}, + LONGOPT_WSLOG + {0, 0, 0, 0 } +}; + +const struct ws_option* sharkd_long_options(void) +{ + return long_options; +} + +const char* sharkd_optstring(void) +{ +#define OPTSTRING "+" "a:hmvC:" + static const char optstring[] = OPTSTRING; + + return optstring; +} + static void print_current_user(void) { @@ -108,7 +151,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, SHARKD_INIT_FAILED); + ws_log_parse_args(&argc, argv, sharkd_optstring(), sharkd_long_options(), vcmdarg_err, SHARKD_INIT_FAILED); ws_noisy("Finished log init and parsing command line log arguments"); diff --git a/sharkd.h b/sharkd.h index ce81423a3e..2524b3ba2d 100644 --- a/sharkd.h +++ b/sharkd.h @@ -28,6 +28,8 @@ typedef void (*sharkd_dissect_func_t)(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data); +#define LONGOPT_FOREGROUND 4000 + /* sharkd.c */ cf_status_t sharkd_cf_open(const char *fname, unsigned int type, bool is_tempfile, int *err); int sharkd_load_cap_file(void); @@ -49,6 +51,9 @@ wtap_block_t sharkd_get_modified_block(const frame_data *fd); wtap_block_t sharkd_get_packet_block(const frame_data *fd); int sharkd_set_modified_block(frame_data *fd, wtap_block_t new_block); const char *sharkd_version(void); +const struct ws_option* sharkd_long_options(void); +const char* sharkd_optstring(void); + /* sharkd_daemon.c */ int sharkd_init(int argc, char **argv); diff --git a/sharkd_daemon.c b/sharkd_daemon.c index b1c1201509..fccecad5bf 100644 --- a/sharkd_daemon.c +++ b/sharkd_daemon.c @@ -241,40 +241,6 @@ print_usage(FILE* output) int sharkd_init(int argc, char **argv) { - /* - * The leading + ensures that getopt_long() does not permute the argv[] - * entries. - * - * We have to make sure that the first getopt_long() preserves the content - * of argv[] for the subsequent getopt_long() call. - * - * We use getopt_long() in both cases to ensure that we're using a routine - * whose permutation behavior we can control in the same fashion on all - * platforms, and so that, if we ever need to process a long argument before - * doing further initialization, we can do so. - * - * Glibc and Solaris libc document that a leading + disables permutation - * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD - * and macOS don't document it, but do so anyway. - * - * We do *not* use a leading - because the behavior of a leading - is - * platform-dependent. - */ - -#define OPTSTRING "+" "a:hmvC:" -#define LONGOPT_FOREGROUND 4000 - - static const char optstring[] = OPTSTRING; - - static const struct ws_option long_options[] = { - {"api", ws_required_argument, NULL, 'a'}, - {"foreground", ws_no_argument, NULL, LONGOPT_FOREGROUND}, - {"help", ws_no_argument, NULL, 'h'}, - {"version", ws_no_argument, NULL, 'v'}, - {"config-profile", ws_required_argument, NULL, 'C'}, - {0, 0, 0, 0 } - }; - int opt; #ifndef _WIN32 @@ -333,7 +299,7 @@ sharkd_init(int argc, char **argv) if (ws_optind > (argc - 1)) break; - opt = ws_getopt_long(argc, argv, optstring, long_options, NULL); + opt = ws_getopt_long(argc, argv, sharkd_optstring(), sharkd_long_options(), NULL); switch (opt) { case 'C': /* Configuration Profile */ diff --git a/text2pcap.c b/text2pcap.c index 30a4d35781..49ec22fa59 100644 --- a/text2pcap.c +++ b/text2pcap.c @@ -378,6 +378,18 @@ cleanup_dump_params(wtap_dump_params *params) wtap_dump_params_cleanup(params); } +static const struct ws_option long_options[] = { + {"help", ws_no_argument, NULL, 'h'}, + {"version", ws_no_argument, NULL, 'v'}, + {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS}, + {"little-endian", ws_no_argument, NULL, LONGOPT_LITTLE_ENDIAN}, + LONGOPT_WSLOG + {0, 0, 0, 0 } +}; + +#define OPTSTRING "hqab:De:E:F:i:l:m:nN:o:u:P:r:s:S:t:T:v4:6:" +static const char optstring[] = OPTSTRING; + /*---------------------------------------------------------------------- * Parse CLI options */ @@ -387,13 +399,6 @@ parse_options(int argc, char *argv[], text_import_info_t * const info, wtap_dump int ret; int c; char *p; - static const struct ws_option long_options[] = { - {"help", ws_no_argument, NULL, 'h'}, - {"version", ws_no_argument, NULL, 'v'}, - {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS}, - {"little-endian", ws_no_argument, NULL, LONGOPT_LITTLE_ENDIAN}, - {0, 0, 0, 0 } - }; const char *interface_name = NULL; /* Link-layer type; see https://www.tcpdump.org/linktypes.html for details */ uint32_t pcap_link_type = 1; /* Default is LINKTYPE_ETHERNET */ @@ -414,7 +419,7 @@ parse_options(int argc, char *argv[], text_import_info_t * const info, wtap_dump ws_init_version_info("Text2pcap", NULL, NULL); /* Scan CLI parameters */ - while ((c = ws_getopt_long(argc, argv, "hqab:De:E:F:i:l:m:nN:o:u:P:r:s:S:t:T:v4:6:", long_options, NULL)) != -1) { + while ((c = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (c) { case 'h': show_help_header("Generate a capture file from an ASCII hexdump of packets."); @@ -1050,7 +1055,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); diff --git a/tfshark.c b/tfshark.c index 4a434f4e5b..7125169bac 100644 --- a/tfshark.c +++ b/tfshark.c @@ -263,6 +263,7 @@ main(int argc, char *argv[]) static const struct ws_option long_options[] = { {"help", ws_no_argument, NULL, 'h'}, {"version", ws_no_argument, NULL, 'v'}, + LONGOPT_WSLOG {0, 0, 0, 0 } }; bool arg_error = false; @@ -322,7 +323,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); diff --git a/tshark.c b/tshark.c index 9530915797..7f29d12a8d 100644 --- a/tshark.c +++ b/tshark.c @@ -1048,6 +1048,7 @@ main(int argc, char *argv[]) LONGOPT_CAPTURE_COMMON LONGOPT_DISSECT_COMMON LONGOPT_READ_CAPTURE_COMMON + LONGOPT_WSLOG {"print", ws_no_argument, NULL, 'P'}, {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS}, {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS}, @@ -1142,7 +1143,7 @@ main(int argc, char *argv[]) ws_log_init(vcmdarg_err); /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); ws_debug("tshark started with %d args", argc); diff --git a/ui/commandline.c b/ui/commandline.c index e935df0e86..b372fb9fae 100644 --- a/ui/commandline.c +++ b/ui/commandline.c @@ -235,10 +235,22 @@ static const struct ws_option long_options[] = { LONGOPT_CAPTURE_COMMON LONGOPT_DISSECT_COMMON LONGOPT_READ_CAPTURE_COMMON + LONGOPT_WSLOG {0, 0, 0, 0 } }; static const char optstring[] = OPTSTRING; + +const struct ws_option* commandline_long_options(void) +{ + return long_options; +} + +const char* commandline_optstring(void) +{ + return optstring; +} + #ifndef HAVE_LIBPCAP static void print_no_capture_support_error(void) { diff --git a/ui/commandline.h b/ui/commandline.h index 38aff5e8de..2bae0937a1 100644 --- a/ui/commandline.h +++ b/ui/commandline.h @@ -48,6 +48,10 @@ typedef struct commandline_param_info } commandline_param_info_t; +extern const struct ws_option* commandline_long_options(void); + +extern const char* commandline_optstring(void); + extern void commandline_override_prefs(int argc, char *argv[], bool opt_reset); extern void commandline_other_options(int argc, char *argv[], bool opt_reset); diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 6d22ca43cc..a4e7ef336a 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -576,7 +576,7 @@ int main(int argc, char *qt_argv[]) #endif /* _WIN32 */ /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, commandline_optstring(), commandline_long_options(), vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); /* diff --git a/ui/stratoshark/stratoshark_main.cpp b/ui/stratoshark/stratoshark_main.cpp index 483f4e35f6..a4bd5db8c7 100644 --- a/ui/stratoshark/stratoshark_main.cpp +++ b/ui/stratoshark/stratoshark_main.cpp @@ -547,7 +547,7 @@ int main(int argc, char *qt_argv[]) #endif /* _WIN32 */ /* Early logging command-line initialization. */ - ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION); + ws_log_parse_args(&argc, argv, commandline_optstring(), commandline_long_options(), vcmdarg_err, WS_EXIT_INVALID_OPTION); ws_noisy("Finished log init and parsing command line log arguments"); /* diff --git a/writecap/pcapio.c b/writecap/pcapio.c index b681902d8e..3b63b36535 100644 --- a/writecap/pcapio.c +++ b/writecap/pcapio.c @@ -153,7 +153,7 @@ struct epb { }; #define ENHANCED_PACKET_BLOCK_TYPE 0x00000006 -struct ws_option { +struct ws_option_tlv { uint16_t type; uint16_t value_length; }; @@ -501,7 +501,7 @@ pcapng_count_string_option(const char *option_value) { if ((option_value != NULL) && (strlen(option_value) > 0) && (strlen(option_value) < UINT16_MAX)) { /* There's a value to write; get its length */ - return (uint32_t)(sizeof(struct ws_option) + + return (uint32_t)(sizeof(struct ws_option_tlv) + (uint16_t)ADD_PADDING(strlen(option_value))); } return 0; /* nothing to write */ @@ -513,7 +513,7 @@ pcapng_write_string_option(pcapio_writer* pfile, uint64_t *bytes_written, int *err) { size_t option_value_length; - struct ws_option option; + struct ws_option_tlv option; const uint32_t padding = 0; if (option_value == NULL) @@ -524,7 +524,7 @@ pcapng_write_string_option(pcapio_writer* pfile, option.type = option_type; option.value_length = (uint16_t)option_value_length; - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)option_value, (int) option_value_length, bytes_written, err)) @@ -579,7 +579,7 @@ pcapng_write_section_header_block(pcapio_writer* pfile, int *err) { struct shb shb; - struct ws_option option; + struct ws_option_tlv option; uint32_t block_total_length; uint32_t options_length; @@ -596,7 +596,7 @@ pcapng_write_section_header_block(pcapio_writer* pfile, options_length += pcapng_count_string_option(appname); /* If we have options add size of end-of-options */ if (options_length != 0) { - options_length += (uint32_t)sizeof(struct ws_option); + options_length += (uint32_t)sizeof(struct ws_option_tlv); } block_total_length += options_length; @@ -632,7 +632,7 @@ pcapng_write_section_header_block(pcapio_writer* pfile, /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; } @@ -656,7 +656,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, int *err) { struct idb idb; - struct ws_option option; + struct ws_option_tlv option; uint32_t block_total_length; uint32_t options_length; const uint32_t padding = 0; @@ -674,20 +674,20 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, /* 08 - IDB_IF_SPEED */ if (if_speed != 0) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint64_t)); } /* 09 - IDB_TSRESOL */ if (tsresol != 0) { - options_length += (uint32_t)(sizeof(struct ws_option) + - sizeof(struct ws_option)); + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + + sizeof(struct ws_option_tlv)); } /* 11 - IDB_FILTER */ if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < UINT16_MAX - 1)) { /* No, this isn't a string, it has an extra type byte */ - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + (uint16_t)(ADD_PADDING(strlen(filter)+ 1))); } @@ -699,7 +699,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, /* If we have options add size of end-of-options */ if (options_length != 0) { - options_length += (uint32_t)sizeof(struct ws_option); + options_length += (uint32_t)sizeof(struct ws_option_tlv); } block_total_length += options_length; @@ -733,7 +733,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, option.type = IDB_IF_SPEED; option.value_length = sizeof(uint64_t); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&if_speed, sizeof(uint64_t), bytes_written, err)) @@ -745,7 +745,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, option.type = IDB_TSRESOL; option.value_length = sizeof(uint8_t); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&tsresol, sizeof(uint8_t), bytes_written, err)) @@ -762,7 +762,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < UINT16_MAX - 1)) { option.type = IDB_FILTER; option.value_length = (uint16_t)(strlen(filter) + 1 ); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */ @@ -790,7 +790,7 @@ pcapng_write_interface_description_block(pcapio_writer* pfile, /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; } @@ -813,7 +813,7 @@ pcapng_write_enhanced_packet_block(pcapio_writer* pfile, int *err) { struct epb epb; - struct ws_option option; + struct ws_option_tlv option; uint32_t block_total_length; uint64_t timestamp; uint32_t options_length; @@ -828,12 +828,12 @@ pcapng_write_enhanced_packet_block(pcapio_writer* pfile, options_length = 0; options_length += pcapng_count_string_option(comment); if (flags != 0) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint32_t)); } /* If we have options add size of end-of-options */ if (options_length != 0) { - options_length += (uint32_t)sizeof(struct ws_option); + options_length += (uint32_t)sizeof(struct ws_option_tlv); } block_total_length += options_length; timestamp = (uint64_t)sec * ts_mul + (uint64_t)usec; @@ -876,7 +876,7 @@ pcapng_write_enhanced_packet_block(pcapio_writer* pfile, if (flags != 0) { option.type = EPB_FLAGS; option.value_length = sizeof(uint32_t); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&flags, sizeof(uint32_t), bytes_written, err)) return false; @@ -885,7 +885,7 @@ pcapng_write_enhanced_packet_block(pcapio_writer* pfile, /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; } @@ -909,7 +909,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, #else struct timeval now; #endif - struct ws_option option; + struct ws_option_tlv option; uint32_t block_total_length; uint32_t options_length; uint64_t timestamp; @@ -956,26 +956,26 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, block_total_length = (uint32_t)(sizeof(struct isb) + sizeof(uint32_t)); options_length = 0; if (isb_ifrecv != UINT64_MAX) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint64_t)); } if (isb_ifdrop != UINT64_MAX) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint64_t)); } /* OPT_COMMENT */ options_length += pcapng_count_string_option(comment); if (isb_starttime !=0) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint64_t)); /* ISB_STARTTIME */ } if (isb_endtime !=0) { - options_length += (uint32_t)(sizeof(struct ws_option) + + options_length += (uint32_t)(sizeof(struct ws_option_tlv) + sizeof(uint64_t)); /* ISB_ENDTIME */ } /* If we have options add size of end-of-options */ if (options_length != 0) { - options_length += (uint32_t)sizeof(struct ws_option); + options_length += (uint32_t)sizeof(struct ws_option_tlv); } block_total_length += options_length; @@ -999,7 +999,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, option.value_length = sizeof(uint64_t); high = (uint32_t)((isb_starttime>>32) & 0xffffffff); low = (uint32_t)(isb_starttime & 0xffffffff); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&high, sizeof(uint32_t), bytes_written, err)) @@ -1015,7 +1015,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, option.value_length = sizeof(uint64_t); high = (uint32_t)((isb_endtime>>32) & 0xffffffff); low = (uint32_t)(isb_endtime & 0xffffffff); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&high, sizeof(uint32_t), bytes_written, err)) @@ -1027,7 +1027,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, if (isb_ifrecv != UINT64_MAX) { option.type = ISB_IFRECV; option.value_length = sizeof(uint64_t); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&isb_ifrecv, sizeof(uint64_t), bytes_written, err)) @@ -1036,7 +1036,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, if (isb_ifdrop != UINT64_MAX) { option.type = ISB_IFDROP; option.value_length = sizeof(uint64_t); - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; if (!write_to_file(pfile, (const uint8_t*)&isb_ifdrop, sizeof(uint64_t), bytes_written, err)) @@ -1046,7 +1046,7 @@ pcapng_write_interface_statistics_block(pcapio_writer* pfile, /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; - if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option), bytes_written, err)) + if (!write_to_file(pfile, (const uint8_t*)&option, sizeof(struct ws_option_tlv), bytes_written, err)) return false; } diff --git a/wsutil/wslog.c b/wsutil/wslog.c index 017573c2e1..950e1abd4a 100644 --- a/wsutil/wslog.c +++ b/wsutil/wslog.c @@ -28,6 +28,7 @@ #include #endif +#include "clopts_common.h" #include "file_util.h" #include "time_util.h" #include "to_str.h" @@ -368,19 +369,6 @@ enum ws_log_level ws_log_set_level_str(const char *str_level) } -static const char *opt_level = "--log-level"; -static const char *opt_domain = "--log-domain"; -/* Alias "domain" and "domains". */ -static const char *opt_domain_s = "--log-domains"; -static const char *opt_file = "--log-file"; -static const char *opt_fatal = "--log-fatal"; -static const char *opt_fatal_domain = "--log-fatal-domain"; -/* Alias "domain" and "domains". */ -static const char *opt_fatal_domain_s = "--log-fatal-domains"; -static const char *opt_debug = "--log-debug"; -static const char *opt_noisy = "--log-noisy"; - - static void print_err(void (*vcmdarg_err)(const char *, va_list ap), int exit_failure, const char *fmt, ...) @@ -397,277 +385,92 @@ static void print_err(void (*vcmdarg_err)(const char *, va_list ap), exit(exit_failure); } - -/* - * This tries to convert old log level preference to a wslog - * configuration. The string must start with "console.log.level:" - * It receives an argv for { '-o', 'console.log.level:nnn', ...} or - * { '-oconsole.log.level:nnn', ...}. - */ -static void -parse_console_compat_option(char *argv[], - void (*vcmdarg_err)(const char *, va_list ap), - int exit_failure) +int ws_log_parse_args(int* argc, char* argv[], + const char* optstring, const struct ws_option* long_options, + void (*vcmdarg_err)(const char*, va_list ap), + int exit_failure) { - const char *mask_str; - uint32_t mask; - enum ws_log_level level; + int opt; - ASSERT(argv != NULL); + /* Save the global setting of erroring on unknown options, because this list will probably contain application options + not handled here */ + int old_ws_opterr = ws_opterr; - if (argv[0] == NULL) - return; + /* Clear erroring on unknown options */ + ws_opterr = 0; - if (strcmp(argv[0], "-o") == 0) { - if (argv[1] == NULL || - !g_str_has_prefix(argv[1], "console.log.level:")) { - /* Not what we were looking for. */ - return; - } - mask_str = argv[1] + strlen("console.log.level:"); - } - else if (g_str_has_prefix(argv[0], "-oconsole.log.level:")) { - mask_str = argv[0] + strlen("-oconsole.log.level:"); - } - else { - /* Not what we were looking for. */ - return; - } + while ((opt = ws_getopt_long_only(*argc, argv, optstring, long_options, NULL)) != -1) { - print_err(vcmdarg_err, LOG_ARGS_NOEXIT, - "Option 'console.log.level' is deprecated, consult '--help' " - "for diagnostic message options."); - - if (*mask_str == '\0') { - print_err(vcmdarg_err, exit_failure, - "Missing value to 'console.log.level' option."); - return; - } - - if (!ws_basestrtou32(mask_str, NULL, &mask, 10)) { - print_err(vcmdarg_err, exit_failure, - "%s is not a valid decimal number.", mask_str); - return; - } - - /* - * The lowest priority bit in the mask defines the level. - */ - if (mask & G_LOG_LEVEL_DEBUG) - level = LOG_LEVEL_DEBUG; - else if (mask & G_LOG_LEVEL_INFO) - level = LOG_LEVEL_INFO; - else if (mask & G_LOG_LEVEL_MESSAGE) - level = LOG_LEVEL_MESSAGE; - else if (mask & G_LOG_LEVEL_WARNING) - level = LOG_LEVEL_WARNING; - else if (mask & G_LOG_LEVEL_CRITICAL) - level = LOG_LEVEL_CRITICAL; - else if (mask & G_LOG_LEVEL_ERROR) - level = LOG_LEVEL_ERROR; - else - level = LOG_LEVEL_NONE; - - if (level == LOG_LEVEL_NONE) { - /* Some values (like zero) might not contain any meaningful bits. - * Throwing an error in that case seems appropriate. */ - print_err(vcmdarg_err, exit_failure, - "Value %s is not a valid log mask.", mask_str); - return; - } - - ws_log_set_level(level); -} - -/* Match "arg_name=value" or "arg_name value" to opt_name. */ -static bool optequal(const char *arg, const char *opt) -{ - ASSERT(arg); - ASSERT(opt); -#define ARGEND(arg) (*(arg) == '\0' || *(arg) == ' ' || *(arg) == '=') - - while (!ARGEND(arg) && *opt != '\0') { - if (*arg != *opt) { - return false; - } - arg += 1; - opt += 1; - } - if (ARGEND(arg) && *opt == '\0') { - return true; - } - return false; -} - -int ws_log_parse_args(int *argc_ptr, char *argv[], - void (*vcmdarg_err)(const char *, va_list ap), - int exit_failure) -{ - char **ptr = argv; - int count = *argc_ptr; - int ret = 0; - size_t optlen; - const char *option, *value; - int extra; - - if (argc_ptr == NULL || argv == NULL) - return -1; - -#ifdef WS_DEBUG - /* Assert ws_log_init() was called before ws_log_parse_args(). */ - ASSERT(init_complete); -#endif - - /* Configure from command line. */ - - while (*ptr != NULL) { - if (optequal(*ptr, opt_level)) { - option = opt_level; - optlen = strlen(opt_level); - } - else if (optequal(*ptr, opt_domain)) { - option = opt_domain; - optlen = strlen(opt_domain); - } - else if (optequal(*ptr, opt_domain_s)) { - option = opt_domain; /* Alias */ - optlen = strlen(opt_domain_s); - } - else if (optequal(*ptr, opt_fatal_domain)) { - option = opt_fatal_domain; - optlen = strlen(opt_fatal_domain); - } - else if (optequal(*ptr, opt_fatal_domain_s)) { - option = opt_fatal_domain; /* Alias */ - optlen = strlen(opt_fatal_domain_s); - } - else if (optequal(*ptr, opt_file)) { - option = opt_file; - optlen = strlen(opt_file); - } - else if (optequal(*ptr, opt_fatal)) { - option = opt_fatal; - optlen = strlen(opt_fatal); - } - else if (optequal(*ptr, opt_debug)) { - option = opt_debug; - optlen = strlen(opt_debug); - } - else if (optequal(*ptr, opt_noisy)) { - option = opt_noisy; - optlen = strlen(opt_noisy); - } - else { - /* Check is we have the old '-o console.log.level' flag, - * or '-oconsole.log.level', for backward compatibility. - * Then if we do ignore it after processing and let the - * preferences module handle it later. */ - if (*(*ptr + 0) == '-' && *(*ptr + 1) == 'o') { - parse_console_compat_option(ptr, vcmdarg_err, exit_failure); - } - ptr += 1; - count -= 1; - continue; - } - - value = *ptr + optlen; - /* Two possibilities: - * --