5586eb9638aba32157a265887d63de5c23af009e
[lttng-tools.git] / src / bin / lttng / commands / remove_trigger.c
1 /*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include "../command.h"
9 #include "common/argpar/argpar.h"
10 #include <lttng/lttng.h>
11 #include <stdio.h>
12
13 #ifdef LTTNG_EMBED_HELP
14 static const char help_msg[] =
15 #include <lttng-remove-trigger.1.h>
16 ;
17 #endif
18
19 enum {
20 OPT_HELP,
21 OPT_LIST_OPTIONS,
22 OPT_OWNER_UID,
23 };
24
25 static const
26 struct argpar_opt_descr remove_trigger_options[] = {
27 { OPT_HELP, 'h', "help", false },
28 { OPT_LIST_OPTIONS, '\0', "list-options", false },
29 { OPT_OWNER_UID, '\0', "owner-uid", true },
30 ARGPAR_OPT_DESCR_SENTINEL,
31 };
32
33 static
34 bool assign_string(char **dest, const char *src, const char *opt_name)
35 {
36 bool ret;
37
38 if (*dest) {
39 ERR("Duplicate option '%s' given.", opt_name);
40 goto error;
41 }
42
43 *dest = strdup(src);
44 if (!*dest) {
45 ERR("Failed to allocate '%s' string.", opt_name);
46 goto error;
47 }
48
49 ret = true;
50 goto end;
51
52 error:
53 ret = false;
54
55 end:
56 return ret;
57 }
58
59 int cmd_remove_trigger(int argc, const char **argv)
60 {
61 int ret;
62 struct argpar_parse_ret argpar_parse_ret = {};
63 const char *name = NULL;
64 int i;
65 struct lttng_triggers *triggers = NULL;
66 unsigned int triggers_count;
67 enum lttng_trigger_status trigger_status;
68 const struct lttng_trigger *trigger_to_remove = NULL;
69 char *owner_uid = NULL;
70 long long uid;
71
72 argpar_parse_ret = argpar_parse(argc - 1, argv + 1,
73 remove_trigger_options, true);
74 if (!argpar_parse_ret.items) {
75 ERR("%s", argpar_parse_ret.error);
76 goto error;
77 }
78
79 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
80 const struct argpar_item *item =
81 argpar_parse_ret.items->items[i];
82
83 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
84 const struct argpar_item_opt *item_opt =
85 (const struct argpar_item_opt *) item;
86
87 switch (item_opt->descr->id) {
88 case OPT_HELP:
89 SHOW_HELP();
90 ret = 0;
91 goto end;
92 case OPT_LIST_OPTIONS:
93 list_cmd_options_argpar(stdout,
94 remove_trigger_options);
95 ret = 0;
96 goto end;
97 case OPT_OWNER_UID:
98 {
99 if (!assign_string(&owner_uid, item_opt->arg,
100 "--owner-uid")) {
101 goto error;
102 }
103 break;
104 }
105 default:
106 abort();
107 }
108 } else {
109 const struct argpar_item_non_opt *item_non_opt =
110 (const struct argpar_item_non_opt *) item;
111
112 if (name) {
113 ERR("Unexpected argument '%s'", item_non_opt->arg);
114 goto error;
115 }
116
117 name = item_non_opt->arg;
118 }
119 }
120
121 if (!name) {
122 ERR("Missing `name` argument.");
123 goto error;
124 }
125
126 if (owner_uid) {
127 char *end;
128
129 errno = 0;
130 uid = strtol(owner_uid, &end, 10);
131 if (end == owner_uid || *end != '\0' || errno != 0) {
132 ERR("Failed to parse `%s` as an integer.", owner_uid);
133 }
134 } else {
135 uid = geteuid();
136 }
137
138 ret = lttng_list_triggers(&triggers);
139 if (ret != LTTNG_OK) {
140 ERR("Failed to get the list of triggers.");
141 goto error;
142 }
143
144 trigger_status = lttng_triggers_get_count(triggers, &triggers_count);
145 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
146
147 for (i = 0; i < triggers_count; i++) {
148 const struct lttng_trigger *trigger;
149 const char *trigger_name;
150 uid_t trigger_uid;
151
152 trigger = lttng_triggers_get_at_index(triggers, i);
153 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
154 switch (trigger_status) {
155 case LTTNG_TRIGGER_STATUS_OK:
156 break;
157 case LTTNG_TRIGGER_STATUS_UNSET:
158 /* Don't compare against anonymous triggers. */
159 continue;
160 default:
161 abort();
162 }
163
164 trigger_status = lttng_trigger_get_owner_uid(
165 trigger, &trigger_uid);
166 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
167
168 if (trigger_uid == uid && strcmp(trigger_name, name) == 0) {
169 trigger_to_remove = trigger;
170 break;
171 }
172 }
173
174 if (!trigger_to_remove) {
175 ERR("Couldn't find trigger with name `%s`.", name);
176 goto error;
177 }
178
179 ret = lttng_unregister_trigger(trigger_to_remove);
180 if (ret != 0) {
181 ERR("Failed to unregister trigger `%s`.", name);
182 goto error;
183 }
184
185 MSG("Removed trigger `%s`.", name);
186
187 ret = 0;
188 goto end;
189
190 error:
191 ret = 1;
192
193 end:
194 argpar_parse_ret_fini(&argpar_parse_ret);
195 lttng_triggers_destroy(triggers);
196 free(owner_uid);
197
198 return ret;
199 }
This page took 0.037654 seconds and 3 git commands to generate.