// // utils.c // electra // // Created by Jamie on 27/01/2018. // Copyright © 2018 Electra Team. All rights reserved. // #include "utils.h" #include #include #include #include #include #include #include #include #define PROC_PIDPATHINFO_MAXSIZE (4*MAXPATHLEN) extern char **environ; static int file_exist(const char *filename) { struct stat buffer; int r = stat(filename, &buffer); return (r == 0); } static char *searchpath(const char *binaryname){ if (strstr(binaryname, "/") != NULL){ if (file_exist(binaryname)){ char *foundpath = malloc((strlen(binaryname) + 1) * (sizeof(char))); strcpy(foundpath, binaryname); return foundpath; } else { return NULL; } } char *pathvar = getenv("PATH"); char *dir = strtok(pathvar,":"); while (dir != NULL){ char searchpth[PROC_PIDPATHINFO_MAXSIZE]; strcpy(searchpth, dir); strcat(searchpth, "/"); strcat(searchpth, binaryname); if (file_exist(searchpth)){ char *foundpath = malloc((strlen(searchpth) + 1) * (sizeof(char))); strcpy(foundpath, searchpth); return foundpath; } dir = strtok(NULL, ":"); } return NULL; } static int isShellScript(const char *path){ FILE *file = fopen(path, "r"); uint8_t header[2]; if (fread(header, sizeof(uint8_t), 2, file) == 2){ if (header[0] == '#' && header[1] == '!'){ fclose(file); return 1; } } fclose(file); return -1; } static char *getInterpreter(char *path){ FILE *file = fopen(path, "r"); char *interpreterLine = NULL; unsigned long lineSize = 0; getline(&interpreterLine, &lineSize, file); char *rawInterpreter = (interpreterLine+2); rawInterpreter = strtok(rawInterpreter, " "); rawInterpreter = strtok(rawInterpreter, "\n"); char *interpreter = malloc((strlen(rawInterpreter)+1) * sizeof(char)); strcpy(interpreter, rawInterpreter); free(interpreterLine); fclose(file); return interpreter; } static char *fixedCmd(const char *cmdStr){ char *cmdCpy = malloc((strlen(cmdStr)+1) * sizeof(char)); strcpy(cmdCpy, cmdStr); char *cmd = strtok(cmdCpy, " "); uint8_t size = strlen(cmd) + 1; char *args = cmdCpy + size; if ((strlen(cmdStr) - strlen(cmd)) == 0) args = NULL; char *abs_path = searchpath(cmd); if (abs_path){ int isScript = isShellScript(abs_path); if (isScript == 1){ char *interpreter = getInterpreter(abs_path); uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path); if (args){ commandSize += 1 + strlen(args); } char *rawCommand = malloc(sizeof(char) * (commandSize + 1)); strcpy(rawCommand, interpreter); strcat(rawCommand, " "); strcat(rawCommand, abs_path); if (args){ strcat(rawCommand, " "); strcat(rawCommand, args); } rawCommand[(commandSize)+1] = '\0'; free(interpreter); free(abs_path); free(cmdCpy); return rawCommand; } else { uint8_t commandSize = strlen(abs_path); if (args){ commandSize += 1 + strlen(args); } char *rawCommand = malloc(sizeof(char) * (commandSize + 1)); strcat(rawCommand, abs_path); if (args){ strcat(rawCommand, " "); strcat(rawCommand, args); } rawCommand[(commandSize)+1] = '\0'; free(abs_path); free(cmdCpy); return rawCommand; } } return cmdCpy; } int run(const char *cmd) { char *myenviron[] = { "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games", "PS1=\\h:\\w \\u\\$ ", NULL }; pid_t pid; char *rawCmd = fixedCmd(cmd); char *argv[] = {"sh", "-c", (char*)rawCmd, NULL}; int status; status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, (char **)&myenviron); if (status == 0) { if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); } } else { printf("posix_spawn: %s\n", strerror(status)); } free(rawCmd); return status; } char *itoa_electra(long n) { int len = n==0 ? 1 : floor(log10l(labs(n)))+1; if (n<0) len++; // room for negative sign '-' char *buf = calloc(sizeof(char), len+1); // +1 for null snprintf(buf, len+1, "%ld", n); return buf; }