+static int string_match(const char *str1, const char *str2)
+{
+ return (str1 && str2) && !strcmp(str1, str2);
+}
+
+/*
+ * Take an option from the getopt output and set it in the right variable to be
+ * used later.
+ *
+ * Return 0 on success else a negative value.
+ */
+static int set_option(int opt, const char *arg, const char *optname)
+{
+ int ret = 0;
+
+ if (string_match(optname, "client-sock") || opt == 'c') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-c, --client-sock");
+ } else {
+ config_string_set(&config.client_unix_sock_path,
+ strdup(arg));
+ if (!config.client_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "apps-sock") || opt == 'a') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-a, --apps-sock");
+ } else {
+ config_string_set(&config.apps_unix_sock_path,
+ strdup(arg));
+ if (!config.apps_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "daemonize") || opt == 'd') {
+ config.daemonize = true;
+ } else if (string_match(optname, "background") || opt == 'b') {
+ config.background = true;
+ } else if (string_match(optname, "group") || opt == 'g') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-g, --group");
+ } else {
+ config_string_set(&config.tracing_group_name,
+ strdup(arg));
+ if (!config.tracing_group_name.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "help") || opt == 'h') {
+ ret = utils_show_help(8, "lttng-sessiond", help_msg);
+ if (ret) {
+ ERR("Cannot show --help for `lttng-sessiond`");
+ perror("exec");
+ }
+ exit(ret ? EXIT_FAILURE : EXIT_SUCCESS);
+ } else if (string_match(optname, "version") || opt == 'V') {
+ fprintf(stdout, "%s\n", VERSION);
+ exit(EXIT_SUCCESS);
+ } else if (string_match(optname, "sig-parent") || opt == 'S') {
+ config.sig_parent = true;
+ } else if (string_match(optname, "kconsumerd-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--kconsumerd-err-sock");
+ } else {
+ config_string_set(&config.kconsumerd_err_unix_sock_path,
+ strdup(arg));
+ if (!config.kconsumerd_err_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "kconsumerd-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--kconsumerd-cmd-sock");
+ } else {
+ config_string_set(&config.kconsumerd_cmd_unix_sock_path,
+ strdup(arg));
+ if (!config.kconsumerd_cmd_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "ustconsumerd64-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd64-err-sock");
+ } else {
+ config_string_set(&config.consumerd64_err_unix_sock_path,
+ strdup(arg));
+ if (!config.consumerd64_err_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "ustconsumerd64-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd64-cmd-sock");
+ } else {
+ config_string_set(&config.consumerd64_cmd_unix_sock_path,
+ strdup(arg));
+ if (!config.consumerd64_cmd_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "ustconsumerd32-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd32-err-sock");
+ } else {
+ config_string_set(&config.consumerd32_err_unix_sock_path,
+ strdup(arg));
+ if (!config.consumerd32_err_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "ustconsumerd32-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd32-cmd-sock");
+ } else {
+ config_string_set(&config.consumerd32_cmd_unix_sock_path,
+ strdup(arg));
+ if (!config.consumerd32_cmd_unix_sock_path.value) {
+ ret = -ENOMEM;
+ PERROR("strdup");
+ }
+ }
+ } else if (string_match(optname, "no-kernel")) {
+ config.no_kernel = true;
+ } else if (string_match(optname, "quiet") || opt == 'q') {
+ config.quiet = true;
+ } else if (string_match(optname, "verbose") || opt == 'v') {
+ /* Verbose level can increase using multiple -v */
+ if (arg) {
+ /* Value obtained from config file */
+ config.verbose = config_parse_value(arg);
+ } else {
+ /* -v used on command line */
+ config.verbose++;
+ }
+ /* Clamp value to [0, 3] */
+ config.verbose = config.verbose < 0 ? 0 :
+ (config.verbose <= 3 ? config.verbose : 3);
+ } else if (string_match(optname, "verbose-consumer")) {
+ if (arg) {
+ config.verbose_consumer = config_parse_value(arg);
+ } else {
+ config.verbose_consumer++;
+ }
+ } else if (string_match(optname, "consumerd32-path")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd32-path");
+ } else {
+ config_string_set(&config.consumerd32_bin_path,
+ strdup(arg));
+ if (!config.consumerd32_bin_path.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "consumerd32-libdir")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd32-libdir");
+ } else {
+ config_string_set(&config.consumerd32_lib_dir,
+ strdup(arg));
+ if (!config.consumerd32_lib_dir.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "consumerd64-path")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd64-path");
+ } else {
+ config_string_set(&config.consumerd64_bin_path,
+ strdup(arg));
+ if (!config.consumerd64_bin_path.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "consumerd64-libdir")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd64-libdir");
+ } else {
+ config_string_set(&config.consumerd64_lib_dir,
+ strdup(arg));
+ if (!config.consumerd64_lib_dir.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "pidfile") || opt == 'p') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-p, --pidfile");
+ } else {
+ config_string_set(&config.pid_file_path, strdup(arg));
+ if (!config.pid_file_path.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "agent-tcp-port")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--agent-tcp-port");
+ } else {
+ unsigned long v;
+
+ errno = 0;
+ v = strtoul(arg, NULL, 0);
+ if (errno != 0 || !isdigit(arg[0])) {
+ ERR("Wrong value in --agent-tcp-port parameter: %s", arg);
+ return -1;
+ }
+ if (v == 0 || v >= 65535) {
+ ERR("Port overflow in --agent-tcp-port parameter: %s", arg);
+ return -1;
+ }
+ config.agent_tcp_port.begin = config.agent_tcp_port.end = (int) v;
+ DBG3("Agent TCP port set to non default: %i", (int) v);
+ }
+ } else if (string_match(optname, "load") || opt == 'l') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-l, --load");
+ } else {
+ config_string_set(&config.load_session_path, strdup(arg));
+ if (!config.load_session_path.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "kmod-probes")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--kmod-probes");
+ } else {
+ config_string_set(&config.kmod_probes_list, strdup(arg));
+ if (!config.kmod_probes_list.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "extra-kmod-probes")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--extra-kmod-probes");
+ } else {
+ config_string_set(&config.kmod_extra_probes_list,
+ strdup(arg));
+ if (!config.kmod_extra_probes_list.value) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "config") || opt == 'f') {
+ /* This is handled in set_options() thus silent skip. */
+ goto end;
+ } else {
+ /* Unknown option or other error.
+ * Error is printed by getopt, just return */
+ ret = -1;
+ }
+
+end:
+ if (ret == -EINVAL) {
+ const char *opt_name = "unknown";
+ int i;
+
+ for (i = 0; i < sizeof(long_options) / sizeof(struct option);
+ i++) {
+ if (opt == long_options[i].val) {
+ opt_name = long_options[i].name;
+ break;
+ }
+ }
+
+ WARN("Invalid argument provided for option \"%s\", using default value.",
+ opt_name);
+ }
+
+ return ret;
+}