Commit | Line | Data |
---|---|---|
1670bffd PP |
1 | /* |
2 | * Babeltrace common functions | |
3 | * | |
4 | * Copyright 2016 Philippe Proulx <pproulx@efficios.com> | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | * of this software and associated documentation files (the "Software"), to deal | |
8 | * in the Software without restriction, including without limitation the rights | |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | * copies of the Software, and to permit persons to whom the Software is | |
11 | * furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in | |
14 | * all copies or substantial portions of the Software. | |
15 | * | |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
22 | * SOFTWARE. | |
23 | */ | |
24 | ||
290725f7 | 25 | #include <unistd.h> |
1670bffd PP |
26 | #include <string.h> |
27 | #include <sys/types.h> | |
28 | #include <pwd.h> | |
29 | #include <unistd.h> | |
30 | #include <assert.h> | |
31 | #include <glib.h> | |
32 | #include <babeltrace/babeltrace-internal.h> | |
33 | ||
34 | #define SYSTEM_PLUGIN_PATH INSTALL_LIBDIR "/babeltrace/plugins" | |
35 | #define HOME_ENV_VAR "HOME" | |
36 | #define HOME_PLUGIN_SUBPATH "/.local/lib/babeltrace/plugins" | |
37 | ||
38 | BT_HIDDEN | |
39 | const char *bt_common_get_system_plugin_path(void) | |
40 | { | |
41 | return SYSTEM_PLUGIN_PATH; | |
42 | } | |
43 | ||
44 | BT_HIDDEN | |
45 | bool bt_common_is_setuid_setgid(void) | |
46 | { | |
47 | return (geteuid() != getuid() || getegid() != getgid()); | |
48 | } | |
49 | ||
50 | static char *bt_secure_getenv(const char *name) | |
51 | { | |
52 | if (bt_common_is_setuid_setgid()) { | |
53 | printf_error("Disregarding %s environment variable for setuid/setgid binary", | |
54 | name); | |
55 | return NULL; | |
56 | } | |
57 | return getenv(name); | |
58 | } | |
59 | ||
60 | static const char *get_home_dir(void) | |
61 | { | |
62 | char *val = NULL; | |
63 | struct passwd *pwd; | |
64 | ||
65 | val = bt_secure_getenv(HOME_ENV_VAR); | |
66 | if (val) { | |
67 | goto end; | |
68 | } | |
69 | /* Fallback on password file. */ | |
70 | pwd = getpwuid(getuid()); | |
71 | if (!pwd) { | |
72 | goto end; | |
73 | } | |
74 | val = pwd->pw_dir; | |
75 | end: | |
76 | return val; | |
77 | } | |
78 | ||
79 | BT_HIDDEN | |
80 | char *bt_common_get_home_plugin_path(void) | |
81 | { | |
82 | char *path = NULL; | |
83 | const char *home_dir; | |
84 | ||
85 | home_dir = get_home_dir(); | |
86 | if (!home_dir) { | |
87 | goto end; | |
88 | } | |
89 | ||
90 | if (strlen(home_dir) + strlen(HOME_PLUGIN_SUBPATH) + 1 >= PATH_MAX) { | |
91 | printf_error("Home directory path is too long: `%s`\n", | |
92 | home_dir); | |
93 | goto end; | |
94 | } | |
95 | ||
96 | path = malloc(PATH_MAX); | |
97 | if (!path) { | |
98 | goto end; | |
99 | } | |
100 | ||
101 | strcpy(path, home_dir); | |
102 | strcat(path, HOME_PLUGIN_SUBPATH); | |
103 | ||
104 | end: | |
105 | return path; | |
106 | } | |
107 | ||
108 | BT_HIDDEN | |
109 | int bt_common_append_plugin_path_dirs(const char *paths, GPtrArray *dirs) | |
110 | { | |
111 | int ret = 0; | |
112 | const char *at; | |
113 | const char *end; | |
114 | size_t init_dirs_len; | |
115 | ||
116 | assert(dirs); | |
117 | init_dirs_len = dirs->len; | |
118 | ||
119 | if (!paths) { | |
120 | /* Nothing to append */ | |
121 | goto end; | |
122 | } | |
123 | ||
124 | at = paths; | |
125 | end = paths + strlen(paths); | |
126 | ||
127 | while (at < end) { | |
128 | GString *path; | |
129 | const char *next_colon; | |
130 | ||
131 | next_colon = strchr(at, ':'); | |
132 | if (next_colon == at) { | |
133 | /* | |
134 | * Empty path: try next character (supported | |
135 | * to conform to the typical parsing of $PATH). | |
136 | */ | |
137 | at++; | |
138 | continue; | |
139 | } else if (!next_colon) { | |
140 | /* No more colon: use the remaining */ | |
141 | next_colon = paths + strlen(paths); | |
142 | } | |
143 | ||
144 | path = g_string_new(NULL); | |
145 | if (!path) { | |
146 | goto error; | |
147 | } | |
148 | ||
149 | g_string_append_len(path, at, next_colon - at); | |
150 | at = next_colon + 1; | |
151 | g_ptr_array_add(dirs, path); | |
152 | } | |
153 | ||
154 | goto end; | |
155 | ||
156 | error: | |
157 | ret = -1; | |
158 | ||
159 | /* Remove the new entries in dirs */ | |
160 | while (dirs->len > init_dirs_len) { | |
161 | g_ptr_array_remove_index(dirs, init_dirs_len); | |
162 | } | |
163 | ||
164 | end: | |
165 | return ret; | |
166 | } | |
290725f7 PP |
167 | |
168 | static bool supports_colors(void) | |
169 | { | |
170 | static bool supports_colors = false; | |
171 | static bool supports_colors_set = false; | |
172 | const char *term; | |
173 | ||
174 | if (supports_colors_set) { | |
175 | goto end; | |
176 | } | |
177 | ||
178 | supports_colors_set = true; | |
179 | ||
180 | term = getenv("TERM"); | |
181 | if (!term) { | |
182 | goto end; | |
183 | } | |
184 | ||
185 | if (strncmp(term, "xterm", 5) != 0 && | |
186 | strncmp(term, "rxvt", 4) != 0 && | |
187 | strncmp(term, "konsole", 7) != 0 && | |
188 | strncmp(term, "gnome", 5) != 0) { | |
189 | goto end; | |
190 | } | |
191 | ||
192 | if (!isatty(1)) { | |
193 | goto end; | |
194 | } | |
195 | ||
196 | supports_colors = true; | |
197 | ||
198 | end: | |
199 | return supports_colors; | |
200 | } | |
201 | ||
202 | BT_HIDDEN | |
203 | const char *bt_common_color_reset(void) | |
204 | { | |
205 | return supports_colors() ? "\033[0m" : ""; | |
206 | } | |
207 | ||
208 | BT_HIDDEN | |
209 | const char *bt_common_color_bold(void) | |
210 | { | |
211 | return supports_colors() ? "\033[1m" : ""; | |
212 | } | |
213 | ||
214 | BT_HIDDEN | |
215 | const char *bt_common_color_fg_default(void) | |
216 | { | |
217 | return supports_colors() ? "\033[39m" : ""; | |
218 | } | |
219 | ||
220 | BT_HIDDEN | |
221 | const char *bt_common_color_fg_red(void) | |
222 | { | |
223 | return supports_colors() ? "\033[31m" : ""; | |
224 | } | |
225 | ||
226 | BT_HIDDEN | |
227 | const char *bt_common_color_fg_green(void) | |
228 | { | |
229 | return supports_colors() ? "\033[32m" : ""; | |
230 | } | |
231 | ||
232 | BT_HIDDEN | |
233 | const char *bt_common_color_fg_yellow(void) | |
234 | { | |
235 | return supports_colors() ? "\033[33m" : ""; | |
236 | } | |
237 | ||
238 | BT_HIDDEN | |
239 | const char *bt_common_color_fg_blue(void) | |
240 | { | |
241 | return supports_colors() ? "\033[34m" : ""; | |
242 | } | |
243 | ||
244 | BT_HIDDEN | |
245 | const char *bt_common_color_fg_magenta(void) | |
246 | { | |
247 | return supports_colors() ? "\033[35m" : ""; | |
248 | } | |
249 | ||
250 | BT_HIDDEN | |
251 | const char *bt_common_color_fg_cyan(void) | |
252 | { | |
253 | return supports_colors() ? "\033[36m" : ""; | |
254 | } | |
255 | ||
256 | BT_HIDDEN | |
257 | const char *bt_common_color_fg_light_gray(void) | |
258 | { | |
259 | return supports_colors() ? "\033[37m" : ""; | |
260 | } | |
261 | ||
262 | BT_HIDDEN | |
263 | const char *bt_common_color_bg_default(void) | |
264 | { | |
265 | return supports_colors() ? "\033[49m" : ""; | |
266 | } | |
267 | ||
268 | BT_HIDDEN | |
269 | const char *bt_common_color_bg_red(void) | |
270 | { | |
271 | return supports_colors() ? "\033[41m" : ""; | |
272 | } | |
273 | ||
274 | BT_HIDDEN | |
275 | const char *bt_common_color_bg_green(void) | |
276 | { | |
277 | return supports_colors() ? "\033[42m" : ""; | |
278 | } | |
279 | ||
280 | BT_HIDDEN | |
281 | const char *bt_common_color_bg_yellow(void) | |
282 | { | |
283 | return supports_colors() ? "\033[43m" : ""; | |
284 | } | |
285 | ||
286 | BT_HIDDEN | |
287 | const char *bt_common_color_bg_blue(void) | |
288 | { | |
289 | return supports_colors() ? "\033[44m" : ""; | |
290 | } | |
291 | ||
292 | BT_HIDDEN | |
293 | const char *bt_common_color_bg_magenta(void) | |
294 | { | |
295 | return supports_colors() ? "\033[45m" : ""; | |
296 | } | |
297 | ||
298 | BT_HIDDEN | |
299 | const char *bt_common_color_bg_cyan(void) | |
300 | { | |
301 | return supports_colors() ? "\033[46m" : ""; | |
302 | } | |
303 | ||
304 | BT_HIDDEN | |
305 | const char *bt_common_color_bg_light_gray(void) | |
306 | { | |
307 | return supports_colors() ? "\033[47m" : ""; | |
308 | } |