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