diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2023-10-26 19:53:29 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2023-10-26 19:53:29 -0400 |
commit | 17178535cc9df5e834dfd43e3b2b919e02e5798d (patch) | |
tree | 5e55e8b2c2453ccf6271b190cf45e90d2c25179d /src/system.c | |
download | stasis-17178535cc9df5e834dfd43e3b2b919e02e5798d.tar.gz |
Initial commit
Diffstat (limited to 'src/system.c')
-rw-r--r-- | src/system.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/system.c b/src/system.c new file mode 100644 index 0000000..ad89682 --- /dev/null +++ b/src/system.c @@ -0,0 +1,201 @@ +// +// Created by jhunk on 10/4/23. +// + +#include "system.h" + +int shell(struct Process *proc, char *args[]) { + FILE *fp_out, *fp_err; + pid_t pid; + pid_t status; + status = 0; + errno = 0; + + pid = fork(); + if (pid == -1) { + fprintf(stderr, "fork failed\n"); + exit(1); + } else if (pid == 0) { + int retval; + if (proc != NULL) { + if (strlen(proc->stdout)) { + fp_out = freopen(proc->stdout, "w+", stdout); + } + + if (strlen(proc->stderr)) { + fp_err = freopen(proc->stderr, "w+", stderr); + } + + if (proc->redirect_stderr) { + if (fp_err) { + fclose(fp_err); + fclose(stderr); + } + dup2(fileno(stdout), fileno(stderr)); + } + } + + retval = execv(args[0], args); + fprintf(stderr, "# executing: "); + for (size_t x = 0; args[x] != NULL; x++) { + fprintf(stderr, "%s ", args[x]); + } + + if (proc != NULL && strlen(proc->stdout)) { + fflush(fp_out); + fclose(fp_out); + fflush(stdout); + fclose(stdout); + } + if (proc != NULL && strlen(proc->stderr)) { + fflush(fp_err); + fclose(fp_err); + fflush(stderr); + fclose(stderr); + } + exit(retval); + } else { + if (waitpid(pid, &status, WUNTRACED) > 0) { + if (WIFEXITED(status) && WEXITSTATUS(status)) { + if (WEXITSTATUS(status) == 127) { + fprintf(stderr, "execv failed\n"); + } + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "signal received: %d\n", WIFSIGNALED(status)); + } + } else { + fprintf(stderr, "waitpid() failed\n"); + } + } + + + if (proc != NULL) { + proc->returncode = status; + } + return WEXITSTATUS(status); +} + +int shell2(struct Process *proc, char *args) { + FILE *fp_out = NULL; + FILE *fp_err = NULL; + pid_t pid; + pid_t status; + status = 0; + errno = 0; + + char t_name[PATH_MAX]; + strcpy(t_name, "/tmp/ohmycal.XXXXXX"); + int fd = mkstemp(t_name); + + FILE *tp; + tp = fdopen(fd, "w"); + if (!tp) { + return -1; + } + + fprintf(tp, "#!/bin/bash\n%s\n", args); + fflush(tp); + fclose(tp); + chmod(t_name, 0755); + + pid = fork(); + if (pid == -1) { + fprintf(stderr, "fork failed\n"); + exit(1); + } else if (pid == 0) { + int retval; + if (proc != NULL) { + if (strlen(proc->stdout)) { + fp_out = freopen(proc->stdout, "w+", stdout); + } + + if (strlen(proc->stderr)) { + fp_err = freopen(proc->stderr, "w+", stderr); + } + + if (proc->redirect_stderr) { + if (fp_err) { + fclose(fp_err); + fclose(stderr); + } + dup2(fileno(stdout), fileno(stderr)); + } + } + + retval = execl("/bin/bash", "bash", "-c", t_name, (char *) NULL); + if (proc != NULL && strlen(proc->stdout)) { + if (fp_out != NULL) { + fflush(fp_out); + fclose(fp_out); + } + fflush(stdout); + fclose(stdout); + } + if (proc != NULL && strlen(proc->stderr)) { + if (fp_err) { + fflush(fp_err); + fclose(fp_err); + } + fflush(stderr); + fclose(stderr); + } + return retval; + } else { + if (waitpid(pid, &status, WUNTRACED) > 0) { + if (WIFEXITED(status) && WEXITSTATUS(status)) { + if (WEXITSTATUS(status) == 127) { + fprintf(stderr, "execv failed\n"); + } + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "signal received: %d\n", WIFSIGNALED(status)); + } + } else { + fprintf(stderr, "waitpid() failed\n"); + } + } + + remove(t_name); + + if (proc != NULL) { + proc->returncode = status; + } + return WEXITSTATUS(status); +} + +int shell_safe(struct Process *proc, char *args[]) { + FILE *fp; + char buf[1024] = {0}; + int result; + + for (size_t i = 0; args[i] != NULL; i++) { + if (strpbrk(args[i], ";&|()")) { + args[i] = NULL; + break; + } + } + + result = shell(proc, args); + if (strlen(proc->stdout)) { + fp = fopen(proc->stdout, "r"); + if (fp) { + while (fgets(buf, sizeof(buf) - 1, fp)) { + fprintf(stdout, "%s", buf); + buf[0] = '\0'; + } + fclose(fp); + fp = NULL; + } + } + if (strlen(proc->stderr)) { + fp = fopen(proc->stderr, "r"); + if (fp) { + while (fgets(buf, sizeof(buf) - 1, fp)) { + fprintf(stderr, "%s", buf); + buf[0] = '\0'; + } + fclose(fp); + fp = NULL; + } + } + return result; +} |