| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (C) 2022 Google Inc, Steven Rostedt <rostedt@goodmis.org> |
| */ |
| #include "ktrace.h" |
| |
| #define EXEC_NAME "ktrace" |
| |
| static void usage(char **argv) |
| { |
| printf("usage: %s\n" |
| "\n", EXEC_NAME); |
| exit(-1); |
| } |
| |
| static void __vdie(const char *fmt, va_list ap, int err) |
| { |
| int ret = errno; |
| |
| if (err && errno) |
| perror(EXEC_NAME); |
| else |
| ret = -1; |
| |
| fprintf(stderr, " "); |
| vfprintf(stderr, fmt, ap); |
| |
| fprintf(stderr, "\n"); |
| exit(ret); |
| } |
| |
| void pdie(const char *fmt, ...) |
| { |
| va_list ap; |
| |
| va_start(ap, fmt); |
| __vdie(fmt, ap, 1); |
| va_end(ap); |
| } |
| |
| static char *get_cache_file(void) |
| { |
| char *cache_path; |
| char *home; |
| char *file; |
| int ret; |
| |
| cache_path = secure_getenv("XDG_CACHE_HOME"); |
| if (!cache_path) { |
| home = secure_getenv("HOME"); |
| if (!home) |
| return NULL; |
| ret = asprintf(&cache_path, "%s/.cache", home); |
| if (ret < 0) |
| return NULL; |
| } else { |
| /* So we can always free it later */ |
| cache_path = strdup(cache_path); |
| } |
| if (!cache_path) |
| return NULL; |
| |
| ret = asprintf(&file, "%s/ktrace", cache_path); |
| free(cache_path); |
| |
| return ret < 0 ? NULL : file; |
| } |
| |
| static void load_history(struct ccli *ccli) |
| { |
| char *cache_file; |
| |
| cache_file = get_cache_file(); |
| if (!cache_file) |
| return; |
| ccli_history_load_file(ccli, "ktrace", cache_file); |
| free(cache_file); |
| } |
| |
| static void save_history(struct ccli *ccli) |
| { |
| char *cache_file; |
| |
| cache_file = get_cache_file(); |
| if (!cache_file) |
| return; |
| ccli_history_save_file(ccli, "ktrace", cache_file); |
| free(cache_file); |
| } |
| |
| int main (int argc, char **argv) |
| { |
| struct ccli *ccli; |
| struct tep_handle *tep; |
| |
| tep = tracefs_local_events(NULL); |
| if (!tep) { |
| if (errno == EACCES) |
| pdie("Failed to initialize tracing directory.\n" |
| " You do not have permission to read it"); |
| pdie("Failed to initialize tracing directory"); |
| } |
| ccli = ccli_alloc("ktrace> ", STDIN_FILENO, STDOUT_FILENO); |
| if (!ccli) |
| pdie("ccli initialization"); |
| |
| load_history(ccli); |
| |
| ccli_register_command(ccli, "help", cmd_help, NULL); |
| ccli_register_completion(ccli, "help", help_completion); |
| |
| ccli_register_command(ccli, "create", cmd_create, tep); |
| ccli_register_completion(ccli, "create", create_completion); |
| |
| ccli_register_command(ccli, "enable", cmd_enable, tep); |
| ccli_register_completion(ccli, "enable", enable_completion); |
| |
| ccli_register_command(ccli, "disable", cmd_disable, tep); |
| ccli_register_completion(ccli, "disable", disable_completion); |
| |
| ccli_loop(ccli); |
| |
| save_history(ccli); |
| ccli_free(ccli); |
| |
| tep_free(tep); |
| |
| return 0; |
| } |