diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9ddaa6d --- /dev/null +++ b/.clang-format @@ -0,0 +1,8 @@ +--- +BasedOnStyle: LLVM +IndentWidth: 4 +UseTab: Never +BreakBeforeBraces: Linux +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +--- diff --git a/exec_tracker.c b/exec_tracker.c index 32613f0..e384b47 100644 --- a/exec_tracker.c +++ b/exec_tracker.c @@ -13,382 +13,376 @@ #define BUFFER_LEN 4096 -static void handle_event(int inotify_instance, int *watched, char **filenames, int *counter, size_t watched_len); -static char** filenames_in_dir(char *path, size_t *return_len); -static char** filenames_in_path_envvar(size_t *return_len); -static void free_null_terminated_pointer_array(char **ptr); -static void print_event(uint32_t event); -static void save_result(char **filenames, int* counter, size_t arr_len); - +static void handle_event(int inotify_instance, int *watched, char **filenames, + int *counter, size_t watched_len); +static char **filenames_in_dir(char *path, size_t *return_len); +static char **filenames_in_path_envvar(size_t *return_len); +static void free_null_terminated_pointer_array(char **ptr); +static void print_event(uint32_t event); +static void save_result(char **filenames, int *counter, size_t arr_len); /* This code is a bit over-commented in general */ -int -main(int argc, char * const argv[]) +int main(int argc, char *const argv[]) { - /* Get null terminated list of files to watch, create counter of same size */ + /* Get null terminated list of files to watch, create counter of same size + */ - char **file_names; - int *use_counter, *watched; - size_t files_len; + char **file_names; + int *use_counter, *watched; + size_t files_len; - switch (argc) { - case 1: - file_names = filenames_in_path_envvar(&files_len); - break; - case 2: - file_names = filenames_in_dir(argv[1], &files_len); - break; - default: - errx(EXIT_FAILURE, "Usage: `%s `. If dir is empty, directories in PATH will be monitored", argv[0]); - } + switch (argc) { + case 1: + file_names = filenames_in_path_envvar(&files_len); + break; + case 2: + file_names = filenames_in_dir(argv[1], &files_len); + break; + default: + errx(EXIT_FAILURE, + "Usage: `%s `. If dir is empty, directories in PATH will be " + "monitored", + argv[0]); + } if (file_names == NULL) err(EXIT_FAILURE, "Error when finding files"); - use_counter = calloc(files_len, sizeof(int)); + use_counter = calloc(files_len, sizeof(int)); - if( use_counter == NULL ) - err(EXIT_FAILURE, "Failed to allocate %zu bytes for use counter", files_len*sizeof(int)); + if (use_counter == NULL) + err(EXIT_FAILURE, "Failed to allocate %zu bytes for use counter", + files_len * sizeof(int)); + /* Create file descriptor for accessing the inotify API */ - /* Create file descriptor for accessing the inotify API */ + int inotify_instance = inotify_init(); - int inotify_instance = inotify_init(); - - if ( inotify_instance == -1 ) - err(EXIT_FAILURE, "Failed to initialize inotify instance"); + if (inotify_instance == -1) + err(EXIT_FAILURE, "Failed to initialize inotify instance"); + /* Mark files for events */ - /* Mark files for events */ + watched = calloc(files_len, sizeof(int)); - watched = calloc(files_len, sizeof(int)); + if (watched == NULL) + err(EXIT_FAILURE, "Failed to allocate %zu bytes for watch descriptors", + files_len * sizeof(int)); - if( watched == NULL ) - err(EXIT_FAILURE, "Failed to allocate %zu bytes for watch descriptors", files_len*sizeof(int)); + for (size_t i = 0; file_names[i] != NULL; i++) { + watched[i] = + inotify_add_watch(inotify_instance, file_names[i], IN_ACCESS); - for(size_t i=0; file_names[i] != NULL; i++) { - watched[i] = inotify_add_watch(inotify_instance, file_names[i], IN_ACCESS); + if (watched[i] == -1) + err(EXIT_FAILURE, "Cannot watch %s", file_names[i]); + } - if(watched[i] == -1) - err(EXIT_FAILURE, "Cannot watch %s", file_names[i]); - } + /* Prepare for polling */ + struct pollfd poll_fds[2]; + nfds_t fd_count = 2; - /* Prepare for polling */ + poll_fds[0].fd = STDIN_FILENO; + poll_fds[0].events = POLLIN; - struct pollfd poll_fds[2]; - nfds_t fd_count = 2; + poll_fds[1].fd = inotify_instance; + poll_fds[1].events = POLLIN; - poll_fds[0].fd = STDIN_FILENO; - poll_fds[0].events = POLLIN; + /* Wait for events and/or terminal input */ - poll_fds[1].fd = inotify_instance; - poll_fds[1].events = POLLIN; + int poll_num; + fprintf(stderr, "Listening for events... (Press enter to end)\n"); - /* Wait for events and/or terminal input */ + while (1) { + poll_num = poll(poll_fds, fd_count, -1); - int poll_num; + if (poll_num == -1 && errno != EINTR) + err(EXIT_FAILURE, "Failed to poll"); - fprintf(stderr, "Listening for events... (Press enter to end)\n"); + if (poll_num == 0) + continue; - while (1) { - poll_num = poll(poll_fds, fd_count, -1); - - if( poll_num == -1 && errno != EINTR) - err(EXIT_FAILURE, "Failed to poll"); + if (poll_fds[0].revents & POLLIN) { + char c; + while (read(STDIN_FILENO, &c, 1) > 0 && c != '\n') + /* noop */; + save_result(file_names, use_counter, files_len); + break; + } - if (poll_num == 0) - continue; + if (poll_fds[1].revents & POLLIN) { + handle_event(inotify_instance, watched, file_names, use_counter, + files_len); + } + } - if (poll_fds[0].revents & POLLIN) { - char c; - while (read(STDIN_FILENO, &c, 1) > 0 && c != '\n') - /* noop */; - save_result(file_names, use_counter, files_len); - break; - } - - if( poll_fds[1].revents & POLLIN ) { - handle_event(inotify_instance, watched, file_names, use_counter, files_len); - } - } + close(inotify_instance); - - close(inotify_instance); - - free_null_terminated_pointer_array(file_names); - free(watched); - free(use_counter); + free_null_terminated_pointer_array(file_names); + free(watched); + free(use_counter); return EXIT_SUCCESS; } - -/* Free allocated memory pointed to by pointers +/* Free allocated memory pointed to by pointers in 'ptr', then free 'ptr' itself */ -static void -free_null_terminated_pointer_array(char **ptr) +static void free_null_terminated_pointer_array(char **ptr) { - for(char **p = ptr; *p != NULL; p++ ){ - free(*p); - } + for (char **p = ptr; *p != NULL; p++) { + free(*p); + } - free(ptr); + free(ptr); } - /* Returns a null terminated array of strings for every file in PATH */ -static char** -filenames_in_path_envvar(size_t *return_len) { - size_t n_files, i, output_size; - char **filenames, **output, *saveptr, *path, *token; - void *tmp; - - path = strdup(getenv("PATH")); +static char **filenames_in_path_envvar(size_t *return_len) +{ + size_t n_files, i, output_size; + char **filenames, **output, *saveptr, *path, *token; + void *tmp; - saveptr = NULL; - output_size = 1024; - output = malloc(output_size * sizeof(char*)); + path = strdup(getenv("PATH")); - if (output == NULL) { - warn("Failed to allocate %zu bytes", output_size); - return NULL; - } + saveptr = NULL; + output_size = 1024; + output = malloc(output_size * sizeof(char *)); - token = strtok_r(path, ":", &saveptr); + if (output == NULL) { + warn("Failed to allocate %zu bytes", output_size); + return NULL; + } - i = 0; - while (token != NULL) { - n_files = 0; - filenames = filenames_in_dir(token, &n_files); - n_files -= 1; + token = strtok_r(path, ":", &saveptr); - if ( filenames == NULL ) { - fprintf(stderr, "failed to get filenames in %s\n", token); - token = strtok_r(NULL, ":", &saveptr); - continue; - } + i = 0; + while (token != NULL) { + n_files = 0; + filenames = filenames_in_dir(token, &n_files); + n_files -= 1; - if (i + n_files > output_size) { - while(i + n_files > output_size) - output_size *= 2; + if (filenames == NULL) { + fprintf(stderr, "failed to get filenames in %s\n", token); + token = strtok_r(NULL, ":", &saveptr); + continue; + } - tmp = realloc(output, output_size * sizeof(char*)); + if (i + n_files > output_size) { + while (i + n_files > output_size) + output_size *= 2; - if (tmp == NULL) { - warn("failed to reallocate %zu bytes", output_size * sizeof(char*)); - return NULL; - } + tmp = realloc(output, output_size * sizeof(char *)); - output = (char**) tmp; - } + if (tmp == NULL) { + warn("failed to reallocate %zu bytes", + output_size * sizeof(char *)); + return NULL; + } - memcpy(output+i, filenames, n_files * sizeof(char*)); - i += n_files; + output = (char **)tmp; + } - free(filenames); + memcpy(output + i, filenames, n_files * sizeof(char *)); + i += n_files; - token = strtok_r(NULL, ":", &saveptr); - } - output_size = i + 1; - tmp = realloc(output, output_size * sizeof(char*)); + free(filenames); - if (tmp != NULL){ - output = (char**)tmp; - } + token = strtok_r(NULL, ":", &saveptr); + } + output_size = i + 1; + tmp = realloc(output, output_size * sizeof(char *)); - output[i] = NULL; + if (tmp != NULL) { + output = (char **)tmp; + } - free(path); + output[i] = NULL; - *return_len = output_size; + free(path); - return output; + *return_len = output_size; + + return output; } - /* Returns null terminated array of filepaths in directory */ -static char** -filenames_in_dir(char *path, size_t *return_len) +static char **filenames_in_dir(char *path, size_t *return_len) { - size_t result_size, n_items=0; - char **result; - void *tmp; + size_t result_size, n_items = 0; + char **result; + void *tmp; struct dirent *dir_entity; - DIR *directory_stream; - - result_size = 64; - result = malloc(result_size * sizeof(char*)); + DIR *directory_stream; - if( result == NULL ){ - warn("Failed to malloc %zu bytes", result_size); - return NULL; - } + result_size = 64; + result = malloc(result_size * sizeof(char *)); + + if (result == NULL) { + warn("Failed to malloc %zu bytes", result_size); + return NULL; + } directory_stream = opendir(path); if (directory_stream == NULL) { warn("Failed to open directory %s", path); - goto fail; + goto fail; } - n_items = 0; - errno = 0; // To distinguish end of stream from an error, + n_items = 0; + errno = 0; // To distinguish end of stream from an error, // set errno to zero before calling readdir() while ((dir_entity = readdir(directory_stream)) != NULL) { - if(n_items >= result_size){ - result_size *= 2; - result = realloc(result, result_size * sizeof(char*)); - } + if (n_items >= result_size) { + result_size *= 2; + result = realloc(result, result_size * sizeof(char *)); + } - if (dir_entity->d_type == DT_REG ) { - result[n_items] = calloc(strlen(path) + strlen(dir_entity->d_name) + 2, sizeof(char)); - result[n_items] = strcat(result[n_items], path); - result[n_items] = strcat(result[n_items], "/"); - result[n_items] = strcat(result[n_items], dir_entity->d_name); - n_items += 1; - } + if (dir_entity->d_type == DT_REG) { + result[n_items] = calloc( + strlen(path) + strlen(dir_entity->d_name) + 2, sizeof(char)); + result[n_items] = strcat(result[n_items], path); + result[n_items] = strcat(result[n_items], "/"); + result[n_items] = strcat(result[n_items], dir_entity->d_name); + n_items += 1; + } - // dirent *dir_entity is statically allocated, dont free()! + // dirent *dir_entity is statically allocated, dont free()! } - result_size = n_items+1; - tmp = realloc(result, result_size * sizeof(char*)); + result_size = n_items + 1; + tmp = realloc(result, result_size * sizeof(char *)); - if ( tmp == NULL ) { - warn("Failed to realloc %zu bytes", result_size); - return NULL; - } + if (tmp == NULL) { + warn("Failed to realloc %zu bytes", result_size); + return NULL; + } - result = (char**)tmp; + result = (char **)tmp; - result[n_items] = NULL; + result[n_items] = NULL; - if ( errno != 0 ){ + if (errno != 0) { warn("Error when reading directory %s", path); - goto fail; + goto fail; } - - if ( closedir(directory_stream) == -1 ) + + if (closedir(directory_stream) == -1) warn("Failed to close directory"); - *return_len = result_size; + *return_len = result_size; return result; fail: - for(size_t i=0; ilen) { - event = (struct inotify_event *) p; + for (char *p = buffer; p < buffer + length; + p += sizeof(struct inotify_event) + event->len) { + event = (struct inotify_event *)p; - for (int i=0; i < watched_len; i++) { - if( watched[i] == event->wd ) { - fprintf(stderr, "%s ", filenames[i]); - counter[i] += 1; - break; - } - } - } + for (int i = 0; i < watched_len; i++) { + if (watched[i] == event->wd) { + fprintf(stderr, "%s ", filenames[i]); + counter[i] += 1; + break; + } + } + } } - /* Prints event mask values in a human-readable format */ -static void -print_event(uint32_t event) +static void print_event(uint32_t event) { - if(event & IN_ACCESS){ - fprintf(stderr,"IN_ACCESS "); - } - if(event & IN_ATTRIB){ - fprintf(stderr,"IN_ATTRIB "); - } - if(event & IN_CLOSE_WRITE){ - fprintf(stderr,"IN_CLOSE_WRITE "); - } - if(event & IN_CLOSE_NOWRITE){ - fprintf(stderr,"IN_CLOSE_NOWRITE "); - } - if(event & IN_CREATE){ - fprintf(stderr,"IN_CREATE "); - } - if(event & IN_DELETE){ - fprintf(stderr,"IN_DELETE "); - } - if(event & IN_DELETE_SELF){ - fprintf(stderr,"IN_DELETE_SELF "); - } - if(event & IN_MODIFY){ - fprintf(stderr,"IN_MODIFY "); - } - if(event & IN_MOVE_SELF){ - fprintf(stderr,"IN_MOVE_SELF "); - } - if(event & IN_MOVED_FROM){ - fprintf(stderr,"IN_MOVED_FROM "); - } - if(event & IN_OPEN){ - fprintf(stderr,"IN_OPEN "); - } + if (event & IN_ACCESS) { + fprintf(stderr, "IN_ACCESS "); + } + if (event & IN_ATTRIB) { + fprintf(stderr, "IN_ATTRIB "); + } + if (event & IN_CLOSE_WRITE) { + fprintf(stderr, "IN_CLOSE_WRITE "); + } + if (event & IN_CLOSE_NOWRITE) { + fprintf(stderr, "IN_CLOSE_NOWRITE "); + } + if (event & IN_CREATE) { + fprintf(stderr, "IN_CREATE "); + } + if (event & IN_DELETE) { + fprintf(stderr, "IN_DELETE "); + } + if (event & IN_DELETE_SELF) { + fprintf(stderr, "IN_DELETE_SELF "); + } + if (event & IN_MODIFY) { + fprintf(stderr, "IN_MODIFY "); + } + if (event & IN_MOVE_SELF) { + fprintf(stderr, "IN_MOVE_SELF "); + } + if (event & IN_MOVED_FROM) { + fprintf(stderr, "IN_MOVED_FROM "); + } + if (event & IN_OPEN) { + fprintf(stderr, "IN_OPEN "); + } } - -/* Saves number of recorded events for each +/* Saves number of recorded events for each executable t 'uses.log' */ -static void -save_result(char **filenames, int* counter, size_t arr_len) +static void save_result(char **filenames, int *counter, size_t arr_len) { - FILE *savefile; + FILE *savefile; - savefile = fopen("uses.log", "w"); + savefile = fopen("uses.log", "w"); - if (savefile == NULL) { - warn("Failed to save to file"); - return; - } + if (savefile == NULL) { + warn("Failed to save to file"); + return; + } - for (size_t i=0; i