utils.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // utils.c
  3. // electra
  4. //
  5. // Created by Jamie on 27/01/2018.
  6. // Copyright © 2018 Electra Team. All rights reserved.
  7. //
  8. #include "utils.h"
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>
  12. #include <stdint.h>
  13. #include <spawn.h>
  14. #include <sys/stat.h>
  15. #include <sys/wait.h>
  16. #include <sys/param.h>
  17. #define PROC_PIDPATHINFO_MAXSIZE (4*MAXPATHLEN)
  18. extern char **environ;
  19. static int file_exist(const char *filename) {
  20. struct stat buffer;
  21. int r = stat(filename, &buffer);
  22. return (r == 0);
  23. }
  24. static char *searchpath(const char *binaryname){
  25. if (strstr(binaryname, "/") != NULL){
  26. if (file_exist(binaryname)){
  27. char *foundpath = malloc((strlen(binaryname) + 1) * (sizeof(char)));
  28. strcpy(foundpath, binaryname);
  29. return foundpath;
  30. } else {
  31. return NULL;
  32. }
  33. }
  34. char *pathvar = getenv("PATH");
  35. char *dir = strtok(pathvar,":");
  36. while (dir != NULL){
  37. char searchpth[PROC_PIDPATHINFO_MAXSIZE];
  38. strcpy(searchpth, dir);
  39. strcat(searchpth, "/");
  40. strcat(searchpth, binaryname);
  41. if (file_exist(searchpth)){
  42. char *foundpath = malloc((strlen(searchpth) + 1) * (sizeof(char)));
  43. strcpy(foundpath, searchpth);
  44. return foundpath;
  45. }
  46. dir = strtok(NULL, ":");
  47. }
  48. return NULL;
  49. }
  50. static int isShellScript(const char *path){
  51. FILE *file = fopen(path, "r");
  52. uint8_t header[2];
  53. if (fread(header, sizeof(uint8_t), 2, file) == 2){
  54. if (header[0] == '#' && header[1] == '!'){
  55. fclose(file);
  56. return 1;
  57. }
  58. }
  59. fclose(file);
  60. return -1;
  61. }
  62. static char *getInterpreter(char *path){
  63. FILE *file = fopen(path, "r");
  64. char *interpreterLine = NULL;
  65. unsigned long lineSize = 0;
  66. getline(&interpreterLine, &lineSize, file);
  67. char *rawInterpreter = (interpreterLine+2);
  68. rawInterpreter = strtok(rawInterpreter, " ");
  69. rawInterpreter = strtok(rawInterpreter, "\n");
  70. char *interpreter = malloc((strlen(rawInterpreter)+1) * sizeof(char));
  71. strcpy(interpreter, rawInterpreter);
  72. free(interpreterLine);
  73. fclose(file);
  74. return interpreter;
  75. }
  76. static char *fixedCmd(const char *cmdStr){
  77. char *cmdCpy = malloc((strlen(cmdStr)+1) * sizeof(char));
  78. strcpy(cmdCpy, cmdStr);
  79. char *cmd = strtok(cmdCpy, " ");
  80. uint8_t size = strlen(cmd) + 1;
  81. char *args = cmdCpy + size;
  82. if ((strlen(cmdStr) - strlen(cmd)) == 0)
  83. args = NULL;
  84. char *abs_path = searchpath(cmd);
  85. if (abs_path){
  86. int isScript = isShellScript(abs_path);
  87. if (isScript == 1){
  88. char *interpreter = getInterpreter(abs_path);
  89. uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path);
  90. if (args){
  91. commandSize += 1 + strlen(args);
  92. }
  93. char *rawCommand = malloc(sizeof(char) * (commandSize + 1));
  94. strcpy(rawCommand, interpreter);
  95. strcat(rawCommand, " ");
  96. strcat(rawCommand, abs_path);
  97. if (args){
  98. strcat(rawCommand, " ");
  99. strcat(rawCommand, args);
  100. }
  101. rawCommand[(commandSize)+1] = '\0';
  102. free(interpreter);
  103. free(abs_path);
  104. free(cmdCpy);
  105. return rawCommand;
  106. } else {
  107. uint8_t commandSize = strlen(abs_path);
  108. if (args){
  109. commandSize += 1 + strlen(args);
  110. }
  111. char *rawCommand = malloc(sizeof(char) * (commandSize + 1));
  112. strcat(rawCommand, abs_path);
  113. if (args){
  114. strcat(rawCommand, " ");
  115. strcat(rawCommand, args);
  116. }
  117. rawCommand[(commandSize)+1] = '\0';
  118. free(abs_path);
  119. free(cmdCpy);
  120. return rawCommand;
  121. }
  122. }
  123. return cmdCpy;
  124. }
  125. int run(const char *cmd) {
  126. char *myenviron[] = {
  127. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games",
  128. "PS1=\\h:\\w \\u\\$ ",
  129. NULL
  130. };
  131. pid_t pid;
  132. char *rawCmd = fixedCmd(cmd);
  133. char *argv[] = {"sh", "-c", (char*)rawCmd, NULL};
  134. int status;
  135. status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, (char **)&myenviron);
  136. if (status == 0) {
  137. if (waitpid(pid, &status, 0) == -1) {
  138. perror("waitpid");
  139. }
  140. } else {
  141. printf("posix_spawn: %s\n", strerror(status));
  142. }
  143. free(rawCmd);
  144. return status;
  145. }
  146. char *itoa_electra(long n) {
  147. int len = n==0 ? 1 : floor(log10l(labs(n)))+1;
  148. if (n<0) len++; // room for negative sign '-'
  149. char *buf = calloc(sizeof(char), len+1); // +1 for null
  150. snprintf(buf, len+1, "%ld", n);
  151. return buf;
  152. }