diff options
author | Aaron Ball <nullspoon@oper.io> | 2022-10-13 18:30:38 -0600 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2022-10-13 18:32:43 -0600 |
commit | 304ddad0a6d501189367ebdfc863eb7f542fbbc8 (patch) | |
tree | fced507dc01753e54ffbab7f064d4f840d5dc995 /src | |
download | psre-304ddad0a6d501189367ebdfc863eb7f542fbbc8.tar.gz psre-304ddad0a6d501189367ebdfc863eb7f542fbbc8.tar.xz |
Initial commit of first working version
This supports the -c,--cmdline option as well as extended regexes
(hardcoded to case sensitive at this time). A help text is included with
a README and this is licensed under the GPLv3 license.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2891623 --- /dev/null +++ b/src/main.c @@ -0,0 +1,130 @@ +/** + * Process snapshot utility with regex support + * Copyright (C) 2022 Aaron Ball <nullspoon@oper.io> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <stdio.h> +#include <stdlib.h> +#include <regex.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <dirent.h> + +struct config { + int print_cmdline; + const char* regex; +}; + +int re_match(char* str, char* restr) { + regex_t regex; + regmatch_t pmatch[1]; + + if(regcomp(®ex, restr, REG_EXTENDED) != 0) { + puts("Error compiling regex"); + puts(strerror(errno)); + return -1; + } + return regexec(®ex, str, 1, pmatch, 0); +} + +int read_cmdline(char* path, char* out, int size) { + FILE* fd = NULL; + int i = 0; + fd = fopen(path, "r"); + while((out[i] = fgetc(fd)) != EOF) { + // Stop reading at double null byte + if(out[i] == 0 && out[i - 1] == 0) + break; + // Convert null bytes to spaces + if(out[i] == 0) + out[i] = ' '; + i++; + } + // Terminate string + out[i] = 0; + fclose(fd); + return 0; +} + +int pid_search(struct config* c) { + DIR* dfd = NULL; + struct dirent* ent; + long pid = -1; + char pathbuf[64] = {'\0'}; + char cmdbuf[512] = {'\0'}; + + dfd = opendir("/proc"); + + while((ent = readdir(dfd)) != NULL) { + if(ent->d_type != DT_DIR) + continue; + + pid = strtol(ent->d_name, NULL, 10); + if(pid == 0) + continue; + + sprintf(pathbuf, "/proc/%ld/cmdline", pid); + read_cmdline(pathbuf, cmdbuf, 512); + + if(re_match(cmdbuf, (char*) c->regex) == 0) { + fputs(ent->d_name, stdout); + if(c->print_cmdline) { + fputc('\t', stdout); + fputs(cmdbuf, stdout); + } + fputc('\n', stdout); + } + } + + closedir(dfd); + return 0; +} + +void gethelp() { + puts("psre - Process snapshot regex\n\n" + "Usage:\n" + " psre [options] regex\n\n" + "Options:\n" + " -c,--cmdline Print cmdline with each matching pid\n" + " -h,--help Print this helptext\n" + ); +} + +int parseargs(struct config* c, int argc, char* argv[]) { + int i = 1; + c->print_cmdline = 0; + c->regex = ".*"; + + while(i < argc) { + if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--cmdline") == 0) { + c->print_cmdline = 1; + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + gethelp(); + return -1; + } else { + c->regex = argv[i]; + } + + i++; + } + return 0; +} + +int main(int argc, char* argv[]) { + struct config c; + if(parseargs(&c, argc, argv) != 0) + return 1; + + pid_search(&c); + return 0; +} |