void args_execute(int argc, char *argv[]) { poptContext con; int nextopt; if (iopt_tables == NULL) return; con = poptGetContext(PACKAGE, argc, argv, (struct poptOption *) (iopt_tables->data), 0); poptReadDefaultConfig(con, TRUE); while ((nextopt = poptGetNextOpt(con)) > 0) ; if (nextopt != -1) { printf("Error on option %s: %s.\n" "Run '%s --help' to see a full list of " "available command line options.\n", poptBadOption(con, 0), poptStrerror(nextopt), argv[0]); exit(1); } g_array_free(iopt_tables, TRUE); iopt_tables = NULL; poptFreeContext(con); }
/* * Parsing arguments using libpopt. */ static int parse_args(int argc, const char **argv) { int opt; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stderr); goto error; case OPT_PRINT_RR: { int i; for (i = 0; i < open_dns_count; i++) { printf("%d) %s\n", i, open_dns_list[i]); } exit(EXIT_SUCCESS); break; } default: usage(stderr); goto error; } } return 0; error: return -1; }
/* * The 'view <options>' first level command */ int cmd_view(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); if (lttng_opt_mi) { WARN("mi does not apply to view command"); } while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: ret = CMD_UNDEFINED; goto end; } } opt_session_name = (char*) poptGetArg(pc); ret = view_trace(); end: poptFreeContext(pc); return ret; }
/* * cmd_version */ int cmd_version(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } MSG("lttng version " VERSION " - " VERSION_NAME); MSG("\n" VERSION_DESCRIPTION "\n"); MSG("Web site: http://lttng.org"); MSG("\nlttng is free software and under the GPL license and part LGPL"); end: poptFreeContext(pc); return ret; }
/* * cmd_disable_events * * Disable event to trace session */ int cmd_disable_events(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } opt_event_list = (char*) poptGetArg(pc); if (opt_event_list == NULL && opt_disable_all == 0) { ERR("Missing event name(s).\n"); usage(stderr); ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { ret = CMD_ERROR; goto end; } } else { session_name = opt_session_name; } ret = disable_events(session_name); end: if (!opt_session_name && session_name) { free(session_name); } poptFreeContext(pc); return ret; }
/* * Calibrate LTTng tracer. * * Returns a CMD_* error. */ int cmd_calibrate(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); /* Default event type */ opt_event_type = LTTNG_EVENT_FUNCTION; while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_TRACEPOINT: ret = CMD_UNDEFINED; goto end; case OPT_MARKER: ret = CMD_UNDEFINED; goto end; case OPT_PROBE: ret = CMD_UNDEFINED; break; case OPT_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; case OPT_FUNCTION_ENTRY: ret = CMD_UNDEFINED; goto end; case OPT_SYSCALL: ret = CMD_UNDEFINED; goto end; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } ret = calibrate_lttng(); end: poptFreeContext(pc); return ret; }
/* * cmd_version */ int cmd_version(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } if (lttng_opt_mi) { ret = print_mi(); } else { MSG("lttng version " VERSION " - " VERSION_NAME "%s", GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION); MSG("\n" VERSION_DESCRIPTION "\n"); MSG("Web site: http://lttng.org"); MSG("\n%s", lttng_license); } end: poptFreeContext(pc); return ret; }
poptContext rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable) { poptContext optCon; int rc; const char *ctx, *execPath; setprogname(argv[0]); /* Retrofit glibc __progname */ /* XXX glibc churn sanity */ if (__progname == NULL) { if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++; else __progname = argv[0]; } #if defined(ENABLE_NLS) (void) setlocale(LC_ALL, "" ); (void) bindtextdomain(PACKAGE, LOCALEDIR); (void) textdomain(PACKAGE); #endif rpmSetVerbosity(RPMLOG_NOTICE); if (optionsTable == NULL) { /* Read rpm configuration (if not already read). */ rpmcliConfigured(); return NULL; } /* XXX hack to get popt working from build tree wrt lt-foo names */ ctx = rstreqn(__progname, "lt-", 3) ? __progname + 3 : __progname; optCon = poptGetContext(ctx, argc, (const char **)argv, optionsTable, 0); { char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL); (void) poptReadConfigFile(optCon, poptfile); free(poptfile); } (void) poptReadDefaultConfig(optCon, 1); if ((execPath = getenv("RPM_POPTEXEC_PATH")) == NULL) execPath = LIBRPMALIAS_EXECPATH; poptSetExecPath(optCon, execPath, 1); /* Process all options, whine if unknown. */ while ((rc = poptGetNextOpt(optCon)) > 0) { fprintf(stderr, _("%s: option table misconfigured (%d)\n"), __progname, rc); exit(EXIT_FAILURE); } if (rc < -1) { fprintf(stderr, "%s: %s: %s\n", __progname, poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); exit(EXIT_FAILURE); } /* Read rpm configuration (if not already read). */ rpmcliConfigured(); if (_debug) { rpmIncreaseVerbosity(); rpmIncreaseVerbosity(); } return optCon; }
.val = 1, .descrip = "be very verbose" }, {.longName = "padding", .shortName = 'P', .argInfo = POPT_ARG_VAL, .arg = &padding, .val = 1, .descrip = "pad data section" }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; optCon = poptGetContext("pesign", argc, (const char **)argv, options,0); rc = poptReadDefaultConfig(optCon, 0); if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) { fprintf(stderr, "pesign: poptReadDefaultConfig failed: %s\n", poptStrerror(rc)); exit(1); } while ((rc = poptGetNextOpt(optCon)) > 0) ; if (rc < -1) { fprintf(stderr, "pesign: Invalid argument: %s: %s\n", poptBadOption(optCon, 0), poptStrerror(rc)); exit(1); }
/* * The 'destroy <options>' first level command */ int cmd_destroy(int argc, const char **argv) { int opt; int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; const char *leftover = NULL; struct lttng_session *sessions; int count; int found; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); break; default: ret = CMD_UNDEFINED; break; } goto end; } /* Mi preparation */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_destroy); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } /* For validation and semantic purpose we open a sessions element */ ret = mi_lttng_sessions_open(writer); if (ret) { ret = CMD_ERROR; goto end; } } /* Recuperate all sessions for further operation */ count = lttng_list_sessions(&sessions); if (count < 0) { ERR("%s", lttng_strerror(count)); command_ret = CMD_ERROR; success = 0; goto mi_closing; } /* Ignore session name in case all sessions are to be destroyed */ if (opt_destroy_all) { command_ret = destroy_all_sessions(sessions, count); if (command_ret) { success = 0; } } else { opt_session_name = (char *) poptGetArg(pc); if (!opt_session_name) { /* No session name specified, lookup default */ session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; success = 0; goto mi_closing; } } else { session_name = opt_session_name; } /* Find the corresponding lttng_session struct */ found = 0; for (i = 0; i < count; i++) { if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) { found = 1; command_ret = destroy_session(&sessions[i]); if (command_ret) { success = 0; } } } if (!found) { ERR("Session name %s not found", session_name); command_ret = LTTNG_ERR_SESS_NOT_FOUND; success = 0; goto mi_closing; } } leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; success = 0; goto mi_closing; } mi_closing: /* Mi closing */ if (lttng_opt_mi) { /* Close sessions and output element element */ ret = mi_lttng_close_multi_element(writer, 2); if (ret) { ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } if (opt_session_name == NULL) { free(session_name); } /* Overwrite ret if an error occurred during destroy_session/all */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * Add event to trace session */ int cmd_enable_events(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; const char *leftover = NULL; int event_type = -1; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); /* Default event type */ opt_event_type = LTTNG_EVENT_ALL; while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_TRACEPOINT: opt_event_type = LTTNG_EVENT_TRACEPOINT; break; case OPT_PROBE: opt_event_type = LTTNG_EVENT_PROBE; break; case OPT_USERSPACE_PROBE: opt_event_type = LTTNG_EVENT_USERSPACE_PROBE; break; case OPT_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; case OPT_SYSCALL: opt_event_type = LTTNG_EVENT_SYSCALL; break; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LOGLEVEL: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE; opt_loglevel = poptGetOptArg(pc); break; case OPT_LOGLEVEL_ONLY: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE; opt_loglevel = poptGetOptArg(pc); break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; case OPT_FILTER: break; case OPT_EXCLUDE: break; default: ret = CMD_UNDEFINED; goto end; } /* Validate event type. Multiple event type are not supported. */ if (event_type == -1) { event_type = opt_event_type; } else { if (event_type != opt_event_type) { ERR("Multiple event type not supported."); ret = CMD_ERROR; goto end; } } } ret = print_missing_or_multiple_domains( opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python); if (ret) { ret = CMD_ERROR; goto end; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_enable_event); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } opt_event_list = (char*) poptGetArg(pc); if (opt_event_list == NULL && opt_enable_all == 0) { ERR("Missing event name(s).\n"); ret = CMD_ERROR; goto end; } leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; success = 0; goto mi_closing; } } else { session_name = opt_session_name; } command_ret = enable_events(session_name); if (command_ret) { success = 0; goto mi_closing; } mi_closing: /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } if (opt_session_name == NULL) { free(session_name); } /* Overwrite ret if an error occurred in enable_events */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * The 'list <options>' first level command */ int cmd_list(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; const char *session_name; static poptContext pc; struct lttng_domain domain; struct lttng_domain *domains = NULL; memset(&domain, 0, sizeof(domain)); if (argc < 1) { usage(stderr); ret = CMD_ERROR; goto end; } pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } /* Get session name (trailing argument) */ session_name = poptGetArg(pc); DBG2("Session name: %s", session_name); if (opt_kernel) { domain.type = LTTNG_DOMAIN_KERNEL; } else if (opt_userspace) { DBG2("Listing userspace global domain"); domain.type = LTTNG_DOMAIN_UST; } else if (opt_jul) { DBG2("Listing JUL domain"); domain.type = LTTNG_DOMAIN_JUL; } if (opt_kernel || opt_userspace || opt_jul) { handle = lttng_create_handle(session_name, &domain); if (handle == NULL) { ret = CMD_FATAL; goto end; } } if (session_name == NULL) { if (!opt_kernel && !opt_userspace && !opt_jul) { ret = list_sessions(NULL); if (ret != 0) { goto end; } } if (opt_kernel) { ret = list_kernel_events(); if (ret < 0) { ret = CMD_ERROR; goto end; } } if (opt_userspace) { if (opt_fields) { ret = list_ust_event_fields(); } else { ret = list_ust_events(); } if (ret < 0) { ret = CMD_ERROR; goto end; } } if (opt_jul) { ret = list_jul_events(); if (ret < 0) { ret = CMD_ERROR; goto end; } } } else { /* List session attributes */ ret = list_sessions(session_name); if (ret != 0) { goto end; } /* Domain listing */ if (opt_domain) { ret = list_domains(session_name); goto end; } if (opt_kernel || opt_userspace) { /* Channel listing */ ret = list_channels(opt_channel); if (ret < 0) { goto end; } } else { int i, nb_domain; /* We want all domain(s) */ nb_domain = lttng_list_domains(session_name, &domains); if (nb_domain < 0) { ret = nb_domain; ERR("%s", lttng_strerror(ret)); goto end; } for (i = 0; i < nb_domain; i++) { switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: MSG("=== Domain: Kernel ===\n"); break; case LTTNG_DOMAIN_UST: MSG("=== Domain: UST global ===\n"); MSG("Buffer type: %s\n", domains[i].buf_type == LTTNG_BUFFER_PER_PID ? "per PID" : "per UID"); break; case LTTNG_DOMAIN_JUL: MSG("=== Domain: JUL (Java Util Logging) ===\n"); break; default: MSG("=== Domain: Unimplemented ===\n"); break; } /* Clean handle before creating a new one */ if (handle) { lttng_destroy_handle(handle); } handle = lttng_create_handle(session_name, &domains[i]); if (handle == NULL) { ret = CMD_FATAL; goto end; } if (domains[i].type == LTTNG_DOMAIN_JUL) { ret = list_session_jul_events(); if (ret < 0) { goto end; } continue; } ret = list_channels(opt_channel); if (ret < 0) { goto end; } } } } end: free(domains); if (handle) { lttng_destroy_handle(handle); } poptFreeContext(pc); return ret; }
/*@-globstate@*/ poptContext rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable) /*@globals rpmpoptfiles @*/ /*@modifies rpmpoptfiles @*/ { poptContext optCon; int rc; int xx; int i; #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-noeffect@*/ mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=noeffect@*/ #endif /*@-globs -mods@*/ setprogname(argv[0]); /* Retrofit glibc __progname */ /* XXX glibc churn sanity */ if (__progname == NULL) { if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++; else __progname = argv[0]; } /*@=globs =mods@*/ /* Insure that stdin/stdout/stderr are open, lest stderr end up in rpmdb. */ { static const char _devnull[] = "/dev/null"; #if defined(STDIN_FILENO) (void) checkfd(_devnull, STDIN_FILENO, O_RDONLY); #endif #if defined(STDOUT_FILENO) (void) checkfd(_devnull, STDOUT_FILENO, O_WRONLY); #endif #if defined(STDERR_FILENO) (void) checkfd(_devnull, STDERR_FILENO, O_WRONLY); #endif } #if defined(RPM_VENDOR_WINDRIVER) (void) setRuntimeRelocPaths(); #endif #if defined(ENABLE_NLS) && !defined(__LCLINT__) (void) setlocale(LC_ALL, "" ); (void) bindtextdomain(PACKAGE, __localedir); (void) textdomain(PACKAGE); #endif rpmSetVerbosity(RPMLOG_NOTICE); if (optionsTable == NULL) { /* Read rpm configuration (if not already read). */ rpmcliConfigured(); return NULL; } /* read all RPM POPT configuration files */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--rpmpopt") == 0 && i+1 < argc) { rpmpoptfiles = argv[i+1]; break; } else if (strncmp(argv[i], "--rpmpopt=", 10) == 0) { rpmpoptfiles = argv[i]+10; break; } } /* XXX strip off the "lt-" prefix so that rpmpopt aliases "work". */ { static const char lt_[] = "lt-"; const char * s = __progname; if (!strncmp(s, lt_, sizeof(lt_)-1)) s += sizeof(lt_)-1; /*@-nullpass -temptrans@*/ optCon = poptGetContext(s, argc, (const char **)argv, optionsTable, 0); /*@=nullpass =temptrans@*/ } #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \ !defined(POPT_ERROR_BADCONFIG) /* XXX POPT 1.15 retrofit */ { char * path_buf = xstrdup(rpmpoptfiles); char *path; char *path_next; for (path = path_buf; path != NULL && *path != '\0'; path = path_next) { const char **av; int ac; /* locate start of next path element */ path_next = strchr(path, ':'); if (path_next != NULL && *path_next == ':') *path_next++ = '\0'; else path_next = path + strlen(path); /* glob-expand the path element */ ac = 0; av = NULL; if ((xx = rpmGlob(path, &ac, &av)) != 0) continue; /* work-off each resulting file from the path element */ for (i = 0; i < ac; i++) { const char *fn = av[i]; if (fn[0] == '@' /* attention */) { fn++; if (!rpmSecuritySaneFile(fn)) { rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", fn); /*@innercontinue@*/ continue; } } (void) poptReadConfigFile(optCon, fn); av[i] = _free(av[i]); } av = _free(av); } path_buf = _free(path_buf); } #else /* XXX FIXME: better error message is needed. */ if ((xx = poptReadConfigFiles(optCon, rpmpoptfiles)) != 0) rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", rpmpoptfiles); #endif #if defined(RPM_VENDOR_WINDRIVER) { const char * poptAliasFn = rpmGetPath(__usrlibrpm, "/rpmpopt", NULL); (void) poptReadConfigFile(optCon, poptAliasFn); poptAliasFn = _free(poptAliasFn); } #endif /* read standard POPT configuration files */ /* XXX FIXME: the 2nd arg useEnv flag is UNUSED. */ (void) poptReadDefaultConfig(optCon, 1); #if defined(RPM_VENDOR_WINDRIVER) { const char * poptExecPath = rpmGetPath(__usrlibrpm, NULL); poptSetExecPath(optCon, poptExecPath, 1); poptExecPath = _free(poptExecPath); } #else poptSetExecPath(optCon, USRLIBRPM, 1); #endif /* Process all options, whine if unknown. */ while ((rc = poptGetNextOpt(optCon)) > 0) { const char * optArg = poptGetOptArg(optCon); /*@-dependenttrans -observertrans@*/ /* Avoid popt memory leaks. */ optArg = _free(optArg); /*@=dependenttrans =observertrans @*/ switch (rc) { default: /*@-nullpass@*/ fprintf(stderr, _("%s: option table misconfigured (%d)\n"), __progname, rc); /*@=nullpass@*/ exit(EXIT_FAILURE); /*@notreached@*/ /*@switchbreak@*/ break; } } if (rc < -1) { /*@-nullpass@*/ fprintf(stderr, "%s: %s: %s\n", __progname, poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); /*@=nullpass@*/ exit(EXIT_FAILURE); } /* Read rpm configuration (if not already read). */ rpmcliConfigured(); if (_debug) { rpmIncreaseVerbosity(); rpmIncreaseVerbosity(); } /* Initialize header stat collection. */ /*@-mods@*/ _hdr_stats = _rpmts_stats; /*@=mods@*/ return optCon; }
/* * Add channel to trace session */ int cmd_enable_channels(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; char *opt_arg = NULL; const char *leftover = NULL; init_channel_config(); pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_DISCARD: chan_opts.attr.overwrite = 0; DBG("Channel set to discard"); break; case OPT_OVERWRITE: chan_opts.attr.overwrite = 1; DBG("Channel set to overwrite"); break; case OPT_SUBBUF_SIZE: { uint64_t rounded_size; int order; /* Parse the size */ opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan_opts.attr.subbuf_size) < 0 || !chan_opts.attr.subbuf_size) { ERR("Wrong value in --subbuf-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan_opts.attr.subbuf_size); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size < chan_opts.attr.subbuf_size) { ERR("The subbuf size (%" PRIu64 ") is rounded and overflows!", chan_opts.attr.subbuf_size); ret = CMD_ERROR; goto end; } if (rounded_size != chan_opts.attr.subbuf_size) { WARN("The subbuf size (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan_opts.attr.subbuf_size, rounded_size); chan_opts.attr.subbuf_size = rounded_size; } /* Should now be power of 2 */ assert(!((chan_opts.attr.subbuf_size - 1) & chan_opts.attr.subbuf_size)); DBG("Channel subbuf size set to %" PRIu64, chan_opts.attr.subbuf_size); break; } case OPT_NUM_SUBBUF: { uint64_t rounded_size; int order; errno = 0; opt_arg = poptGetOptArg(pc); chan_opts.attr.num_subbuf = strtoull(opt_arg, NULL, 0); if (errno != 0 || !chan_opts.attr.num_subbuf || !isdigit(opt_arg[0])) { ERR("Wrong value in --num-subbuf parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan_opts.attr.num_subbuf); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size < chan_opts.attr.num_subbuf) { ERR("The number of subbuffers (%" PRIu64 ") is rounded and overflows!", chan_opts.attr.num_subbuf); ret = CMD_ERROR; goto end; } if (rounded_size != chan_opts.attr.num_subbuf) { WARN("The number of subbuffers (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan_opts.attr.num_subbuf, rounded_size); chan_opts.attr.num_subbuf = rounded_size; } /* Should now be power of 2 */ assert(!((chan_opts.attr.num_subbuf - 1) & chan_opts.attr.num_subbuf)); DBG("Channel subbuf num set to %" PRIu64, chan_opts.attr.num_subbuf); break; } case OPT_SWITCH_TIMER: { uint64_t v; errno = 0; opt_arg = poptGetOptArg(pc); if (utils_parse_time_suffix(opt_arg, &v) < 0) { ERR("Wrong value for --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan_opts.attr.switch_timer_interval = (uint32_t) v; DBG("Channel switch timer interval set to %d %s", chan_opts.attr.switch_timer_interval, USEC_UNIT); break; } case OPT_READ_TIMER: { uint64_t v; errno = 0; opt_arg = poptGetOptArg(pc); if (utils_parse_time_suffix(opt_arg, &v) < 0) { ERR("Wrong value for --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan_opts.attr.read_timer_interval = (uint32_t) v; DBG("Channel read timer interval set to %d %s", chan_opts.attr.read_timer_interval, USEC_UNIT); break; } case OPT_MONITOR_TIMER: { uint64_t v; errno = 0; opt_arg = poptGetOptArg(pc); if (utils_parse_time_suffix(opt_arg, &v) < 0) { ERR("Wrong value for --monitor-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } opt_monitor_timer.interval = (uint64_t) v; opt_monitor_timer.set = true; DBG("Channel monitor timer interval set to %" PRIu64 " %s", opt_monitor_timer.interval, USEC_UNIT); break; } case OPT_BLOCKING_TIMEOUT: { uint64_t v; long long v_msec; errno = 0; opt_arg = poptGetOptArg(pc); if (strcmp(opt_arg, "inf") == 0) { opt_blocking_timeout.value = (int64_t) -1; opt_blocking_timeout.set = true; DBG("Channel blocking timeout set to infinity"); break; } if (utils_parse_time_suffix(opt_arg, &v) < 0) { ERR("Wrong value for --blocking-timeout parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } /* * While LTTng-UST and LTTng-tools will accept a * blocking timeout expressed in µs, the current * tracer implementation relies on poll() which * takes an "int timeout" parameter expressed in * msec. * * Since the error reporting from the tracer is * not precise, we perform this check here to * provide a helpful error message in case of * overflow. * * The setter (liblttng-ctl) also performs an * equivalent check. */ v_msec = v / 1000; if (v_msec != (int32_t) v_msec) { ERR("32-bit milliseconds overflow in --blocking-timeout parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } opt_blocking_timeout.value = (int64_t) v; opt_blocking_timeout.set = true; DBG("Channel blocking timeout set to %" PRId64 " %s%s", opt_blocking_timeout.value, USEC_UNIT, opt_blocking_timeout.value == 0 ? " (non-blocking)" : ""); break; } case OPT_USERSPACE: opt_userspace = 1; break; case OPT_TRACEFILE_SIZE: opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan_opts.attr.tracefile_size) < 0) { ERR("Wrong value in --tracefile-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } DBG("Maximum tracefile size set to %" PRIu64, chan_opts.attr.tracefile_size); break; case OPT_TRACEFILE_COUNT: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan_opts.attr.tracefile_count = (uint32_t) v; DBG("Maximum tracefile count set to %" PRIu64, chan_opts.attr.tracefile_count); break; } case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: ret = CMD_UNDEFINED; goto end; } } ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace); if (ret) { ret = CMD_ERROR; goto end; } if (chan_opts.attr.overwrite == 1 && opt_blocking_timeout.set && opt_blocking_timeout.value != 0) { ERR("You cannot specify --overwrite and --blocking-timeout=N, " "where N is different than 0"); ret = CMD_ERROR; goto end; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_enable_channels); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } opt_channels = (char*) poptGetArg(pc); if (opt_channels == NULL) { ERR("Missing channel name.\n"); ret = CMD_ERROR; success = 0; goto mi_closing; } leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; success = 0; goto mi_closing; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; success = 0; goto mi_closing; } } else { session_name = opt_session_name; } command_ret = enable_channel(session_name); if (command_ret) { success = 0; } mi_closing: /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } if (!opt_session_name && session_name) { free(session_name); } /* Overwrite ret if an error occurred when enable_channel */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
int main(int argc, char *argv[]) { int rc; pesign_context *ctxp; int list = 0; int remove = 0; int daemon = 0; int fork = 1; int padding = 0; int need_db = 0; char *digest_name = "sha256"; char *tokenname = "NSS Certificate DB"; char *origtoken = tokenname; char *certname = NULL; char *certdir = "/etc/pki/pesign"; char *signum = NULL; rc = pesign_context_new(&ctxp); if (rc < 0) { fprintf(stderr, "Could not initialize context: %m\n"); exit(1); } poptContext optCon; struct poptOption options[] = { {NULL, '\0', POPT_ARG_INTL_DOMAIN, "pesign" }, {"in", 'i', POPT_ARG_STRING, &ctxp->infile, 0, "specify input file", "<infile>"}, {"out", 'o', POPT_ARG_STRING, &ctxp->outfile, 0, "specify output file", "<outfile>" }, {"certficate", 'c', POPT_ARG_STRING, &certname, 0, "specify certificate nickname", "<certificate nickname>" }, {"certdir", 'n', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &certdir, 0, "specify nss certificate database directory", "<certificate directory path>" }, {"force", 'f', POPT_ARG_VAL, &ctxp->force, 1, "force overwriting of output file", NULL }, {"sign", 's', POPT_ARG_VAL, &ctxp->sign, 1, "create a new signature", NULL }, {"hash", 'h', POPT_ARG_VAL, &ctxp->hash, 1, "hash binary", NULL }, {"digest_type", 'd', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &digest_name, 0, "digest type to use for pe hash" }, {"import-signed-certificate", 'm', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->insig, 0,"import signature from file", "<insig>" }, {"export-signed-attributes", 'E', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->outsattrs, 0, "export signed attributes to file", "<signed_attributes_file>" }, {"import-signed-attributes", 'I', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->insattrs, 0, "import signed attributes from file", "<signed_attributes_file>" }, {"import-raw-signature", 'R', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->rawsig, 0, "import raw signature from file", "<inraw>" }, {"signature-number", 'u', POPT_ARG_STRING, &signum, 0, "specify which signature to operate on","<sig-number>"}, {"list-signatures", 'l', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &list, 1, "list signatures", NULL }, {"nss-token", 't', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &tokenname, 0, "NSS token holding signing key" }, {"show-signature", 'S', POPT_ARG_VAL, &list, 1, "show signature", NULL }, {"remove-signature", 'r', POPT_ARG_VAL, &remove, 1, "remove signature" }, {"export-signature", 'e', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->outsig, 0, "export signature to file", "<outsig>" }, {"export-pubkey", 'K', POPT_ARG_STRING, &ctxp->outkey, 0, "export pubkey to file", "<outkey>" }, {"export-cert", 'C', POPT_ARG_STRING, &ctxp->outcert, 0, "export signing cert to file", "<outcert>" }, {"ascii-armor", 'a', POPT_ARG_VAL, &ctxp->ascii, 1, "use ascii armoring", NULL }, {"daemonize", 'D', POPT_ARG_VAL, &daemon, 1, "run as a daemon process", NULL }, {"nofork", 'N', POPT_ARG_VAL, &fork, 0, "don't fork when daemonizing", NULL }, {"verbose", 'v', POPT_ARG_VAL, &ctxp->verbose, 1, "be very verbose", NULL }, {"padding", 'P', POPT_ARG_VAL, &padding, 1, "pad data section", NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; optCon = poptGetContext("pesign", argc, (const char **)argv, options,0); rc = poptReadDefaultConfig(optCon, 0); if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) { fprintf(stderr, "pesign: poptReadDefaultConfig failed: %s\n", poptStrerror(rc)); exit(1); } while ((rc = poptGetNextOpt(optCon)) > 0) ; if (rc < -1) { fprintf(stderr, "pesign: Invalid argument: %s: %s\n", poptBadOption(optCon, 0), poptStrerror(rc)); exit(1); } if (poptPeekArg(optCon)) { fprintf(stderr, "pesign: Invalid Argument: \"%s\"\n", poptPeekArg(optCon)); exit(1); } poptFreeContext(optCon); if (signum) { errno = 0; ctxp->signum = strtol(signum, NULL, 0); if (errno != 0) { fprintf(stderr, "invalid signature number: %m\n"); exit(1); } } int action = 0; if (daemon) action |= DAEMONIZE; if (ctxp->rawsig) { action |= IMPORT_RAW_SIGNATURE; need_db = 1; } if (ctxp->insattrs) action |= IMPORT_SATTRS; if (ctxp->outsattrs) action |= EXPORT_SATTRS; if (ctxp->insig) action |= IMPORT_SIGNATURE; if (ctxp->outkey) { action |= EXPORT_PUBKEY; need_db = 1; } if (ctxp->outcert) { action |= EXPORT_CERT; need_db = 1; } if (ctxp->outsig) action |= EXPORT_SIGNATURE; if (remove != 0) action |= REMOVE_SIGNATURE; if (list != 0) action |= LIST_SIGNATURES; if (ctxp->sign) { action |= GENERATE_SIGNATURE; if (!(action & EXPORT_SIGNATURE)) action |= IMPORT_SIGNATURE; need_db = 1; } if (ctxp->hash) action |= GENERATE_DIGEST|PRINT_DIGEST; if (!daemon) { SECStatus status; if (need_db) status = NSS_Init(certdir); else status = NSS_NoDB_Init(NULL); if (status != SECSuccess) { fprintf(stderr, "Could not initialize nss: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } status = register_oids(ctxp->cms_ctx); if (status != SECSuccess) { fprintf(stderr, "Could not register OIDs\n"); exit(1); } } rc = set_digest_parameters(ctxp->cms_ctx, digest_name); int is_help = strcmp(digest_name, "help") ? 0 : 1; if (rc < 0) { if (!is_help) { fprintf(stderr, "Digest \"%s\" not found.\n", digest_name); } exit(!is_help); } ctxp->cms_ctx->tokenname = tokenname ? PORT_ArenaStrdup(ctxp->cms_ctx->arena, tokenname) : NULL; if (tokenname && !ctxp->cms_ctx->tokenname) { fprintf(stderr, "could not allocate token name: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } if (tokenname != origtoken) free(tokenname); ctxp->cms_ctx->certname = certname ? PORT_ArenaStrdup(ctxp->cms_ctx->arena, certname) : NULL; if (certname && !ctxp->cms_ctx->certname) { fprintf(stderr, "could not allocate certificate name: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } if (certname) free(certname); if (ctxp->sign) { if (!ctxp->cms_ctx->certname) { fprintf(stderr, "pesign: signing requested but no " "certificate nickname provided\n"); exit(1); } } ssize_t sigspace = 0; switch (action) { case NO_FLAGS: fprintf(stderr, "pesign: Nothing to do.\n"); exit(0); break; /* in this case we have the actual binary signature and the * signing cert, but not the pkcs7ish certificate that goes * with it. */ case IMPORT_RAW_SIGNATURE|IMPORT_SATTRS: check_inputs(ctxp); rc = find_certificate(ctxp->cms_ctx, 0); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_rawsig_input(ctxp); open_sattr_input(ctxp); import_raw_signature(ctxp); close_sattr_input(ctxp); close_rawsig_input(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); sigspace = calculate_signature_space(ctxp->cms_ctx, ctxp->outpe); allocate_signature_space(ctxp->outpe, sigspace); generate_signature(ctxp->cms_ctx); insert_signature(ctxp->cms_ctx, ctxp->signum); close_output(ctxp); break; case EXPORT_SATTRS: open_input(ctxp); open_sattr_output(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, 1); generate_sattr_blob(ctxp); close_sattr_output(ctxp); close_input(ctxp); break; /* add a signature from a file */ case IMPORT_SIGNATURE: check_inputs(ctxp); if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } open_input(ctxp); open_output(ctxp); close_input(ctxp); open_sig_input(ctxp); parse_signature(ctxp); sigspace = get_sigspace_extend_amount(ctxp->cms_ctx, ctxp->outpe, &ctxp->cms_ctx->newsig); allocate_signature_space(ctxp->outpe, sigspace); check_signature_space(ctxp); insert_signature(ctxp->cms_ctx, ctxp->signum); close_sig_input(ctxp); close_output(ctxp); break; case EXPORT_PUBKEY: rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_pubkey_output(ctxp); export_pubkey(ctxp); break; case EXPORT_CERT: rc = find_certificate(ctxp->cms_ctx, 0); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_cert_output(ctxp); export_cert(ctxp); break; /* find a signature in the binary and save it to a file */ case EXPORT_SIGNATURE: open_input(ctxp); open_sig_output(ctxp); if (ctxp->signum > ctxp->cms_ctx->num_signatures) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } if (ctxp->signum < 0) ctxp->signum = 0; if (ctxp->signum >= ctxp->cms_ctx->num_signatures) { fprintf(stderr, "No valid signature #%d.\n", ctxp->signum); exit(1); } memcpy(&ctxp->cms_ctx->newsig, ctxp->cms_ctx->signatures[ctxp->signum], sizeof (ctxp->cms_ctx->newsig)); export_signature(ctxp->cms_ctx, ctxp->outsigfd, ctxp->ascii); close_input(ctxp); close_sig_output(ctxp); memset(&ctxp->cms_ctx->newsig, '\0', sizeof (ctxp->cms_ctx->newsig)); break; /* remove a signature from the binary */ case REMOVE_SIGNATURE: check_inputs(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); if (ctxp->signum < 0 || ctxp->signum >= ctxp->cms_ctx->num_signatures) { fprintf(stderr, "Invalid signature number %d. " "Must be between 0 and %d.\n", ctxp->signum, ctxp->cms_ctx->num_signatures - 1); exit(1); } remove_signature(ctxp); close_output(ctxp); break; /* list signatures in the binary */ case LIST_SIGNATURES: open_input(ctxp); list_signatures(ctxp); break; case GENERATE_DIGEST|PRINT_DIGEST: open_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, padding); print_digest(ctxp); break; /* generate a signature and save it in a separate file */ case EXPORT_SIGNATURE|GENERATE_SIGNATURE: rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_input(ctxp); open_sig_output(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, 1); generate_signature(ctxp->cms_ctx); export_signature(ctxp->cms_ctx, ctxp->outsigfd, ctxp->ascii); break; /* generate a signature and embed it in the binary */ case IMPORT_SIGNATURE|GENERATE_SIGNATURE: check_inputs(ctxp); rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } open_input(ctxp); open_output(ctxp); close_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); sigspace = calculate_signature_space(ctxp->cms_ctx, ctxp->outpe); allocate_signature_space(ctxp->outpe, sigspace); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); generate_signature(ctxp->cms_ctx); insert_signature(ctxp->cms_ctx, ctxp->signum); close_output(ctxp); break; case DAEMONIZE: rc = daemonize(ctxp->cms_ctx, certdir, fork); break; default: fprintf(stderr, "Incompatible flags (0x%08x): ", action); for (int i = 1; i < FLAG_LIST_END; i <<= 1) { if (action & i) print_flag_name(stderr, i); } fprintf(stderr, "\n"); exit(1); } pesign_context_free(ctxp); if (!daemon) { SECStatus status = NSS_Shutdown(); if (status != SECSuccess) { fprintf(stderr, "could not shut down NSS: %s", PORT_ErrorToString(PORT_GetError())); exit(1); } } return (rc < 0); }
/* * Add/remove tracker to/from session. */ static int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str, int argc, const char **argv) { int opt, ret = 0; enum cmd_error_code command_ret = CMD_SUCCESS; int success = 1; static poptContext pc; char *session_name = NULL; struct mi_writer *writer = NULL; if (argc < 1) { command_ret = CMD_ERROR; goto end; } pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; case OPT_SESSION: case OPT_PID: opt_pid = 1; break; default: command_ret = CMD_UNDEFINED; goto end; } } ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace); if (ret) { ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; goto end; } } else { session_name = opt_session_name; } /* Currently only PID tracker is supported */ if (!opt_pid) { ERR("Please specify at least one tracker with its expected arguments"); command_ret = CMD_ERROR; goto end; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { command_ret = CMD_ERROR; goto end; } } if (writer) { /* Open command element */ ret = mi_lttng_writer_command_open(writer, get_mi_element_command(cmd_type)); if (ret) { command_ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { command_ret = CMD_ERROR; goto end; } } command_ret = track_untrack_pid(cmd_type, cmd_str, session_name, opt_pid_string, opt_all, writer); if (command_ret != CMD_SUCCESS) { success = 0; } /* Mi closing */ if (writer) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { command_ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { command_ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { command_ret = CMD_ERROR; goto end; } } end: if (!opt_session_name) { free(session_name); } /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ command_ret = CMD_ERROR; } poptFreeContext(pc); return (int) command_ret; }
/* * The 'list <options>' first level command */ int cmd_list(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; const char *session_name; static poptContext pc; struct lttng_domain domain; struct lttng_domain *domains = NULL; memset(&domain, 0, sizeof(domain)); if (argc < 1) { usage(stderr); ret = CMD_ERROR; goto end; } pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = CMD_ERROR; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_list); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } /* Get session name (trailing argument) */ session_name = poptGetArg(pc); DBG2("Session name: %s", session_name); if (opt_kernel) { domain.type = LTTNG_DOMAIN_KERNEL; } else if (opt_userspace) { DBG2("Listing userspace global domain"); domain.type = LTTNG_DOMAIN_UST; } else if (opt_jul) { DBG2("Listing JUL domain"); domain.type = LTTNG_DOMAIN_JUL; } else if (opt_log4j) { domain.type = LTTNG_DOMAIN_LOG4J; } else if (opt_python) { domain.type = LTTNG_DOMAIN_PYTHON; } if (!opt_kernel && opt_syscall) { WARN("--syscall will only work with the Kernel domain (-k)"); ret = CMD_ERROR; goto end; } if (opt_kernel || opt_userspace || opt_jul || opt_log4j || opt_python) { handle = lttng_create_handle(session_name, &domain); if (handle == NULL) { ret = CMD_FATAL; goto end; } } if (session_name == NULL) { if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j && !opt_python) { ret = list_sessions(NULL); if (ret) { goto end; } } if (opt_kernel) { if (opt_syscall) { ret = list_syscalls(); if (ret) { goto end; } } else { ret = list_kernel_events(); if (ret) { goto end; } } } if (opt_userspace) { if (opt_fields) { ret = list_ust_event_fields(); } else { ret = list_ust_events(); } if (ret) { goto end; } } if (opt_jul || opt_log4j || opt_python) { ret = list_agent_events(); if (ret) { goto end; } } } else { /* List session attributes */ if (lttng_opt_mi) { /* Open element sessions * Present for xml consistency */ ret = mi_lttng_sessions_open(writer); if (ret) { goto end; } } /* MI: the ouptut of list_sessions is an unclosed session element */ ret = list_sessions(session_name); if (ret) { goto end; } /* Domain listing */ if (opt_domain) { ret = list_domains(session_name); goto end; } /* Channel listing */ if (opt_kernel || opt_userspace) { if (lttng_opt_mi) { /* Add of domains and domain element for xml * consistency and validation */ ret = mi_lttng_domains_open(writer); if (ret) { goto end; } /* Open domain and leave it open for * nested channels printing */ ret = mi_lttng_domain(writer, &domain, 1); if (ret) { goto end; } } ret = list_tracker_pids(); if (ret) { goto end; } ret = list_channels(opt_channel); if (ret) { goto end; } if (lttng_opt_mi) { /* Close domain and domain element */ ret = mi_lttng_close_multi_element(writer, 2); } if (ret) { goto end; } } else { int i, nb_domain; /* We want all domain(s) */ nb_domain = lttng_list_domains(session_name, &domains); if (nb_domain < 0) { ret = CMD_ERROR; ERR("%s", lttng_strerror(nb_domain)); goto end; } if (lttng_opt_mi) { ret = mi_lttng_domains_open(writer); if (ret) { ret = CMD_ERROR; goto end; } } for (i = 0; i < nb_domain; i++) { switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: MSG("=== Domain: Kernel ===\n"); break; case LTTNG_DOMAIN_UST: MSG("=== Domain: UST global ===\n"); MSG("Buffer type: %s\n", domains[i].buf_type == LTTNG_BUFFER_PER_PID ? "per PID" : "per UID"); break; case LTTNG_DOMAIN_JUL: MSG("=== Domain: JUL (Java Util Logging) ===\n"); break; case LTTNG_DOMAIN_LOG4J: MSG("=== Domain: LOG4j (Logging for Java) ===\n"); break; case LTTNG_DOMAIN_PYTHON: MSG("=== Domain: Python (logging) ===\n"); break; default: MSG("=== Domain: Unimplemented ===\n"); break; } if (lttng_opt_mi) { ret = mi_lttng_domain(writer, &domains[i], 1); if (ret) { ret = CMD_ERROR; goto end; } } /* Clean handle before creating a new one */ if (handle) { lttng_destroy_handle(handle); } handle = lttng_create_handle(session_name, &domains[i]); if (handle == NULL) { ret = CMD_FATAL; goto end; } if (domains[i].type == LTTNG_DOMAIN_JUL || domains[i].type == LTTNG_DOMAIN_LOG4J || domains[i].type == LTTNG_DOMAIN_PYTHON) { ret = list_session_agent_events(); if (ret) { goto end; } continue; } switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: case LTTNG_DOMAIN_UST: ret = list_tracker_pids(); if (ret) { goto end; } break; default: break; } ret = list_channels(opt_channel); if (ret) { goto end; } if (lttng_opt_mi) { /* Close domain element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } } } if (lttng_opt_mi) { /* Close the domains, session and sessions element */ ret = mi_lttng_close_multi_element(writer, 3); if (ret) { ret = CMD_ERROR; goto end; } } } } /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } free(domains); if (handle) { lttng_destroy_handle(handle); } poptFreeContext(pc); return ret; }
static int parse_params(int argc, char *argv[], char **output_path, bool *no_extract_ts) { enum { OPT_WITH_TIMESTAMPS = 1, OPT_HELP = 2, }; static struct poptOption opts[] = { { "with-timestamps", 't', POPT_ARG_NONE, NULL, OPT_WITH_TIMESTAMPS, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL }, { NULL, '\0', 0, NULL, 0, NULL, NULL }, }; poptContext pc = NULL; int opt; int ret = 0; const char *leftover; *no_extract_ts = true; pc = poptGetContext(NULL, argc, (const char **) argv, opts, 0); if (!pc) { fprintf(stderr, "Cannot get popt context\n"); goto error; } poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) > 0) { switch (opt) { case OPT_HELP: print_usage(stdout); goto end; case OPT_WITH_TIMESTAMPS: *no_extract_ts = false; break; default: fprintf(stderr, "Unknown command-line option specified (option code %d)\n", opt); goto error; } } if (opt < -1) { fprintf(stderr, "While parsing command-line options, at option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); goto error; } leftover = poptGetArg(pc); if (!leftover) { fprintf(stderr, "Command line error: Missing output path\n"); print_usage(stderr); goto error; } *output_path = strdup(leftover); assert(*output_path); goto end; error: ret = 1; end: if (pc) { poptFreeContext(pc); } return ret; }
/* * cmd_set_session */ int cmd_set_session(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } opt_session_name = (char *) poptGetArg(pc); if (opt_session_name == NULL) { ERR("Missing session name"); usage(stderr); ret = CMD_ERROR; goto end; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_set_session); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } command_ret = set_session(); if (command_ret) { success = 0; } /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } /* Overwrite ret if an error occured during set_session() */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * The 'create <options>' first level command * * Returns one of the CMD_* result constants. */ int cmd_create(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; char *opt_arg = NULL; const char *leftover = NULL; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; case OPT_LIVE_TIMER: { uint64_t v; errno = 0; opt_arg = poptGetOptArg(pc); if (!opt_arg) { /* Set up default values. */ opt_live_timer = (uint32_t) DEFAULT_LTTNG_LIVE_TIMER; DBG("Session live timer interval set to default value %d", opt_live_timer); break; } if (utils_parse_time_suffix(opt_arg, &v) < 0) { ERR("Wrong value for --live parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --live parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v == 0) { ERR("Live timer interval must be greater than zero"); ret = CMD_ERROR; goto end; } opt_live_timer = (uint32_t) v; DBG("Session live timer interval set to %d", opt_live_timer); break; } default: ret = CMD_UNDEFINED; goto end; } } if (opt_no_consumer) { MSG("The option --no-consumer is obsolete. Use --no-output now."); ret = CMD_WARNING; goto end; } ret = validate_url_option_combination(); if (ret) { ret = CMD_ERROR; goto end; } /* Spawn a session daemon if needed */ if (!opt_no_sessiond) { ret = launch_sessiond(); if (ret) { ret = CMD_ERROR; goto end; } } /* MI initialization */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_create); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } opt_session_name = (char*) poptGetArg(pc); leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; goto end; } command_ret = create_session(); if (command_ret) { success = 0; } if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } /* Overwrite ret if an error occurred in create_session() */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * cmd_disable_events * * Disable event to trace session */ int cmd_disable_events(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; int event_type = -1; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); /* Default event type */ opt_event_type = LTTNG_EVENT_ALL; while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_TYPE_SYSCALL: opt_event_type = LTTNG_EVENT_SYSCALL; break; case OPT_TYPE_TRACEPOINT: opt_event_type = LTTNG_EVENT_TRACEPOINT; break; case OPT_TYPE_PROBE: opt_event_type = LTTNG_EVENT_PROBE; break; case OPT_TYPE_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; case OPT_TYPE_ALL: opt_event_type = LTTNG_EVENT_ALL; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: ret = CMD_UNDEFINED; goto end; } /* Validate event type. Multiple event type are not supported. */ if (event_type == -1) { event_type = opt_event_type; } else { if (event_type != opt_event_type) { ERR("Multiple event type not supported."); ret = CMD_ERROR; goto end; } } } ret = print_missing_or_multiple_domains( opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python); if (ret) { ret = CMD_ERROR; goto end; } /* Ust and agent only support ALL event type */ if ((opt_userspace || opt_jul || opt_log4j || opt_python) && opt_event_type != LTTNG_EVENT_ALL) { ERR("Disabling userspace and agent (-j | -l | -p) event(s) based on instrumentation type is not supported.\n"); ret = CMD_ERROR; goto end; } opt_event_list = (char*) poptGetArg(pc); if (opt_event_list == NULL && opt_disable_all == 0) { ERR("Missing event name(s).\n"); ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { ret = CMD_ERROR; goto end; } } else { session_name = opt_session_name; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_disable_event); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } command_ret = disable_events(session_name); if (command_ret) { success = 0; } /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: if (!opt_session_name && session_name) { free(session_name); } /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } /* Overwrite ret if an error occurred in disable_events */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * Return 0 if caller should continue, < 0 if caller should return * error, > 0 if caller should exit without reporting error. */ static int parse_options(int argc, char **argv) { poptContext pc; int opt, ret = 0; const char *ipath; if (argc == 1) { usage(stdout); return 1; /* exit cleanly */ } pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 0); poptReadDefaultConfig(pc, 0); /* set default */ opt_context_field_names = 1; opt_payload_field_names = 1; while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_OUTPUT_PATH: opt_output_path = (char *) poptGetOptArg(pc); if (!opt_output_path) { ret = -EINVAL; goto end; } break; case OPT_INPUT_FORMAT: opt_input_format = (char *) poptGetOptArg(pc); if (!opt_input_format) { ret = -EINVAL; goto end; } break; case OPT_OUTPUT_FORMAT: opt_output_format = (char *) poptGetOptArg(pc); if (!opt_output_format) { ret = -EINVAL; goto end; } break; case OPT_HELP: usage(stdout); ret = 1; /* exit cleanly */ goto end; case OPT_LIST: list_formats(stdout); ret = 1; goto end; case OPT_VERBOSE: babeltrace_verbose = 1; break; case OPT_NAMES: if (get_names_args(&pc)) { ret = -EINVAL; goto end; } break; case OPT_FIELDS: if (get_fields_args(&pc)) { ret = -EINVAL; goto end; } break; case OPT_DEBUG: babeltrace_debug = 1; break; case OPT_NO_DELTA: opt_delta_field = 0; break; case OPT_CLOCK_CYCLES: opt_clock_cycles = 1; break; case OPT_CLOCK_OFFSET: { char *str; char *endptr; str = (char *) poptGetOptArg(pc); if (!str) { fprintf(stderr, "[error] Missing --clock-offset argument\n"); ret = -EINVAL; goto end; } errno = 0; opt_clock_offset = strtoull(str, &endptr, 0); if (*endptr != '\0' || str == endptr || errno != 0) { fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str); ret = -EINVAL; free(str); goto end; } free(str); break; } case OPT_CLOCK_SECONDS: opt_clock_seconds = 1; break; case OPT_CLOCK_OFFSET_NS: { char *str; char *endptr; str = (char *) poptGetOptArg(pc); if (!str) { fprintf(stderr, "[error] Missing --clock-offset-ns argument\n"); ret = -EINVAL; goto end; } errno = 0; opt_clock_offset_ns = strtoull(str, &endptr, 0); if (*endptr != '\0' || str == endptr || errno != 0) { fprintf(stderr, "[error] Incorrect --clock-offset-ns argument: %s\n", str); ret = -EINVAL; free(str); goto end; } free(str); break; } case OPT_CLOCK_DATE: opt_clock_date = 1; break; case OPT_CLOCK_GMT: opt_clock_gmt = 1; break; case OPT_CLOCK_FORCE_CORRELATE: opt_clock_force_correlate = 1; break; case OPT_STREAM_INTERSECTION: opt_stream_intersection = 1; break; case OPT_DEBUG_INFO_DIR: opt_debug_info_dir = (char *) poptGetOptArg(pc); if (!opt_debug_info_dir) { ret = -EINVAL; goto end; } break; case OPT_DEBUG_INFO_FULL_PATH: opt_debug_info_full_path = 1; break; case OPT_DEBUG_INFO_TARGET_PREFIX: opt_debug_info_target_prefix = (char *) poptGetOptArg(pc); if (!opt_debug_info_target_prefix) { ret = -EINVAL; goto end; } break; default: ret = -EINVAL; goto end; } } do { ipath = poptGetArg(pc); if (ipath) g_ptr_array_add(opt_input_paths, (gpointer) ipath); } while (ipath); if (opt_input_paths->len == 0) { ret = -EINVAL; goto end; } end: if (pc) { poptFreeContext(pc); } return ret; }
/* * Add channel to trace session */ int cmd_enable_channels(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; char *opt_arg = NULL; init_channel_config(); pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_DISCARD: chan.attr.overwrite = 0; DBG("Channel set to discard"); break; case OPT_OVERWRITE: chan.attr.overwrite = 1; DBG("Channel set to overwrite"); break; case OPT_SUBBUF_SIZE: { uint64_t rounded_size; int order; /* Parse the size */ opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan.attr.subbuf_size) < 0 || !chan.attr.subbuf_size) { ERR("Wrong value in --subbuf-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan.attr.subbuf_size); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size < chan.attr.subbuf_size) { ERR("The subbuf size (%" PRIu64 ") is rounded and overflows!", chan.attr.subbuf_size); ret = CMD_ERROR; goto end; } if (rounded_size != chan.attr.subbuf_size) { WARN("The subbuf size (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan.attr.subbuf_size, rounded_size); chan.attr.subbuf_size = rounded_size; } /* Should now be power of 2 */ assert(!((chan.attr.subbuf_size - 1) & chan.attr.subbuf_size)); DBG("Channel subbuf size set to %" PRIu64, chan.attr.subbuf_size); break; } case OPT_NUM_SUBBUF: { uint64_t rounded_size; int order; errno = 0; opt_arg = poptGetOptArg(pc); chan.attr.num_subbuf = strtoull(opt_arg, NULL, 0); if (errno != 0 || !chan.attr.num_subbuf || !isdigit(opt_arg[0])) { ERR("Wrong value in --num-subbuf parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan.attr.num_subbuf); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size < chan.attr.num_subbuf) { ERR("The number of subbuffers (%" PRIu64 ") is rounded and overflows!", chan.attr.num_subbuf); ret = CMD_ERROR; goto end; } if (rounded_size != chan.attr.num_subbuf) { WARN("The number of subbuffers (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan.attr.num_subbuf, rounded_size); chan.attr.num_subbuf = rounded_size; } /* Should now be power of 2 */ assert(!((chan.attr.num_subbuf - 1) & chan.attr.num_subbuf)); DBG("Channel subbuf num set to %" PRIu64, chan.attr.num_subbuf); break; } case OPT_SWITCH_TIMER: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.switch_timer_interval = (uint32_t) v; DBG("Channel switch timer interval set to %d", chan.attr.switch_timer_interval); break; } case OPT_READ_TIMER: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.read_timer_interval = (uint32_t) v; DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval); break; } case OPT_USERSPACE: opt_userspace = 1; break; case OPT_TRACEFILE_SIZE: opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan.attr.tracefile_size) < 0) { ERR("Wrong value in --tracefile-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } DBG("Maximum tracefile size set to %" PRIu64, chan.attr.tracefile_size); break; case OPT_TRACEFILE_COUNT: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.tracefile_count = (uint32_t) v; DBG("Maximum tracefile count set to %" PRIu64, chan.attr.tracefile_count); break; } case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_enable_channels); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } opt_channels = (char*) poptGetArg(pc); if (opt_channels == NULL) { ERR("Missing channel name.\n"); usage(stderr); ret = CMD_ERROR; success = 0; goto mi_closing; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; success = 0; goto mi_closing; } } else { session_name = opt_session_name; } command_ret = enable_channel(session_name); if (command_ret) { success = 0; } mi_closing: /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } if (!opt_session_name && session_name) { free(session_name); } /* Overwrite ret if an error occurred when enable_channel */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * The 'save <options>' first level command */ int cmd_save(int argc, const char **argv) { int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success; int opt; const char *session_name = NULL; poptContext pc; struct lttng_save_session_attr *attr; pc = poptGetContext(NULL, argc, argv, save_opts, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_ALL: opt_save_all = 1; break; case OPT_FORCE: opt_force = 1; break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, save_opts); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } if (!opt_save_all) { session_name = poptGetArg(pc); if (session_name) { DBG2("Session name: %s", session_name); } else { /* default to opt_save_all */ opt_save_all = 1; } } attr = lttng_save_session_attr_create(); if (!attr) { ret = CMD_FATAL; goto end_destroy; } if (lttng_save_session_attr_set_session_name(attr, session_name)) { ret = CMD_ERROR; goto end_destroy; } if (lttng_save_session_attr_set_overwrite(attr, opt_force)) { ret = CMD_ERROR; goto end_destroy; } if (lttng_save_session_attr_set_output_url(attr, opt_output_path)) { ret = CMD_ERROR; goto end_destroy; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end_destroy; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_save); if (ret) { ret = CMD_ERROR; goto end_destroy; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end_destroy; } } command_ret = lttng_save_session(attr); if (command_ret < 0) { ERR("%s", lttng_strerror(command_ret)); success = 0; } else { /* Inform the user of what just happened on success. */ if (session_name && opt_output_path) { MSG("Session %s saved successfully in %s.", session_name, opt_output_path); } else if (session_name && !opt_output_path) { MSG("Session %s saved successfully.", session_name); } else if (!session_name && opt_output_path) { MSG("All sessions have been saved successfully in %s.", opt_output_path); } else { MSG("All sessions have been saved successfully."); } success = 1; } /* Mi Printing and closing */ if (lttng_opt_mi) { /* Mi print */ ret = mi_save_print(session_name); if (ret) { ret = CMD_ERROR; goto end_destroy; } /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end_destroy; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end_destroy; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end_destroy; } } end_destroy: lttng_save_session_attr_destroy(attr); end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } /* Overwrite ret if command failed */ ret = command_ret ? -command_ret : ret; poptFreeContext(pc); return ret; }
/* * The 'snapshot <cmd> <options>' first level command */ int cmd_snapshot(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; char *session_name = NULL; static poptContext pc; pc = poptGetContext(NULL, argc, argv, snapshot_opts, 0); poptReadDefaultConfig(pc, 0); /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_snapshot); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, snapshot_opts); goto end; case OPT_LIST_COMMANDS: list_commands(actions, stdout); goto end; case OPT_MAX_SIZE: { uint64_t val; const char *opt = poptGetOptArg(pc); if (utils_parse_size_suffix((char *) opt, &val) < 0) { ERR("Unable to handle max-size value %s", opt); ret = CMD_ERROR; goto end; } opt_max_size = val; break; } default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { ret = CMD_ERROR; goto end; } current_session_name = session_name; } else { current_session_name = opt_session_name; } command_ret = handle_command(poptGetArgs(pc)); if (command_ret) { switch (-command_ret) { case LTTNG_ERR_EPERM: ERR("The session needs to be set in no output mode (--no-output)"); break; case LTTNG_ERR_SNAPSHOT_NODATA: WARN("%s", lttng_strerror(command_ret)); break; default: ERR("%s", lttng_strerror(command_ret)); break; } success = 0; } if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } if (!opt_session_name) { free(session_name); } /* Overwrite ret if an error occured during handle_command */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * cmd_stop * * The 'stop <options>' first level command */ int cmd_stop(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; const char *leftover = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: ret = CMD_UNDEFINED; goto end; } } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_stop); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } /* * Open sessions element * For validation */ ret = mi_lttng_writer_open_element(writer, config_element_sessions); if (ret) { ret = CMD_ERROR; goto end; } } opt_session_name = (char*) poptGetArg(pc); leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; goto end; } command_ret = stop_tracing(); if (command_ret) { success = 0; } /* Mi closing */ if (lttng_opt_mi) { /* Close sessions and output element */ ret = mi_lttng_close_multi_element(writer, 2); if (ret) { ret = CMD_ERROR; goto end; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; } /* Overwrite ret if an error occurred in stop_tracing() */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
/* * Add channel to trace session */ int cmd_enable_channels(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; static poptContext pc; char *session_name = NULL; char *opt_arg = NULL; init_channel_config(); pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: usage(stdout); goto end; case OPT_DISCARD: chan.attr.overwrite = 0; DBG("Channel set to discard"); break; case OPT_OVERWRITE: chan.attr.overwrite = 1; DBG("Channel set to overwrite"); break; case OPT_SUBBUF_SIZE: { uint64_t rounded_size; int order; /* Parse the size */ opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan.attr.subbuf_size) < 0 || !chan.attr.subbuf_size) { ERR("Wrong value in --subbuf-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan.attr.subbuf_size); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size != chan.attr.subbuf_size) { WARN("The subbuf size (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan.attr.subbuf_size, rounded_size); chan.attr.subbuf_size = rounded_size; } /* Should now be power of 2 */ assert(!((chan.attr.subbuf_size - 1) & chan.attr.subbuf_size)); DBG("Channel subbuf size set to %" PRIu64, chan.attr.subbuf_size); break; } case OPT_NUM_SUBBUF: { uint64_t rounded_size; int order; errno = 0; opt_arg = poptGetOptArg(pc); chan.attr.num_subbuf = strtoull(opt_arg, NULL, 0); if (errno != 0 || !chan.attr.num_subbuf || !isdigit(opt_arg[0])) { ERR("Wrong value in --num-subbuf parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } order = get_count_order_u64(chan.attr.num_subbuf); assert(order >= 0); rounded_size = 1ULL << order; if (rounded_size != chan.attr.num_subbuf) { WARN("The number of subbuffers (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")", chan.attr.num_subbuf, rounded_size); chan.attr.num_subbuf = rounded_size; } /* Should now be power of 2 */ assert(!((chan.attr.num_subbuf - 1) & chan.attr.num_subbuf)); DBG("Channel subbuf num set to %" PRIu64, chan.attr.num_subbuf); break; } case OPT_SWITCH_TIMER: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --switch-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.switch_timer_interval = (uint32_t) v; DBG("Channel switch timer interval set to %d", chan.attr.switch_timer_interval); break; } case OPT_READ_TIMER: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --read-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.read_timer_interval = (uint32_t) v; DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval); break; } case OPT_USERSPACE: opt_userspace = 1; break; case OPT_TRACEFILE_SIZE: opt_arg = poptGetOptArg(pc); if (utils_parse_size_suffix(opt_arg, &chan.attr.tracefile_size) < 0) { ERR("Wrong value in --tracefile-size parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } DBG("Maximum tracefile size set to %" PRIu64, chan.attr.tracefile_size); break; case OPT_TRACEFILE_COUNT: { unsigned long v; errno = 0; opt_arg = poptGetOptArg(pc); v = strtoul(opt_arg, NULL, 0); if (errno != 0 || !isdigit(opt_arg[0])) { ERR("Wrong value in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } if (v != (uint32_t) v) { ERR("32-bit overflow in --tracefile-count parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } chan.attr.tracefile_count = (uint32_t) v; DBG("Maximum tracefile count set to %" PRIu64, chan.attr.tracefile_count); break; } case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; default: usage(stderr); ret = CMD_UNDEFINED; goto end; } } opt_channels = (char*) poptGetArg(pc); if (opt_channels == NULL) { ERR("Missing channel name.\n"); usage(stderr); ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { ret = CMD_ERROR; goto end; } } else { session_name = opt_session_name; } ret = enable_channel(session_name); end: if (!opt_session_name && session_name) { free(session_name); } poptFreeContext(pc); return ret; }
int main(int argc, const char ** argv) /*@globals pass2, fileSystem, internalState @*/ /*@modifies pass2, fileSystem, internalState @*/ { int rc; int ec = 0; poptContext optCon; const char ** rest; int help = 0; int usage = 0; #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-moduncon -noeffectuncon@*/ mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=moduncon =noeffectuncon@*/ #endif /*@-modobserver@*/ resetVars(); /*@=modobserver@*/ /*@-temptrans@*/ optCon = poptGetContext("test1", argc, argv, options, 0); /*@=temptrans@*/ (void) poptReadConfigFile(optCon, "./test-poptrc"); (void) poptReadDefaultConfig(optCon, 1); poptSetExecPath(optCon, ".", 1); #if 1 while ((rc = poptGetNextOpt(optCon)) > 0) /* Read all the options ... */ {}; poptResetContext(optCon); /* ... and then start over. */ /*@-modobserver@*/ resetVars(); /*@=modobserver@*/ #endif pass2 = 1; if ((rc = poptGetNextOpt(optCon)) < -1) { fprintf(stderr, "test1: bad argument %s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); ec = 2; goto exit; } if (help) { poptPrintHelp(optCon, stdout, 0); goto exit; } if (usage) { poptPrintUsage(optCon, stdout, 0); goto exit; } fprintf(stdout, "arg1: %d arg2: %s", arg1, arg2); if (arg3) fprintf(stdout, " arg3: %d", arg3); if (inc) fprintf(stdout, " inc: %d", inc); if (shortopt) fprintf(stdout, " short: %d", shortopt); if (aVal != bVal) fprintf(stdout, " aVal: %d", aVal); if (aFlag != bFlag) fprintf(stdout, " aFlag: 0x%x", aFlag); if (aShort != bShort) fprintf(stdout, " aShort: %hd", aShort); if (aInt != bInt) fprintf(stdout, " aInt: %d", aInt); if (aLong != bLong) fprintf(stdout, " aLong: %ld", aLong); if (aLongLong != bLongLong) fprintf(stdout, " aLongLong: %lld", aLongLong); /*@-realcompare@*/ if (aFloat != bFloat) fprintf(stdout, " aFloat: %g", (double)aFloat); if (aDouble != bDouble) fprintf(stdout, " aDouble: %g", aDouble); /*@=realcompare@*/ if (aArgv != NULL) { const char **av = aArgv; const char * arg; fprintf(stdout, " aArgv:"); while ((arg = *av++) != NULL) fprintf(stdout, " %s", arg); } if (aBits) { const char * separator = " "; size_t i; fprintf(stdout, " aBits:"); for (i = 0; i < nattributes; i++) { if (!poptBitsChk(aBits, attributes[i])) continue; fprintf(stdout, "%s%s", separator, attributes[i]); separator = ","; } } /*@-nullpass@*/ if (oStr != (char *)-1) fprintf(stdout, " oStr: %s", (oStr ? oStr : "(none)")); /*@=nullpass@*/ if (singleDash) fprintf(stdout, " -"); if (poptPeekArg(optCon) != NULL) { rest = poptGetArgs(optCon); if (rest) { fprintf(stdout, " rest:"); while (*rest) { fprintf(stdout, " %s", *rest); rest++; } } } fprintf(stdout, "\n"); exit: optCon = poptFreeContext(optCon); #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-moduncon -noeffectuncon@*/ muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=moduncon =noeffectuncon@*/ #endif return ec; }