aboutsummaryrefslogtreecommitdiff
path: root/src/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/system.c')
-rw-r--r--src/system.c201
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;
+}