command.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * command.c - command execution support
  4. *
  5. * Copyright © 2010-2012 Guillem Jover <guillem@debian.org>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. */
  20. #include <config.h>
  21. #include <compat.h>
  22. #include <stdarg.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <string.h>
  26. #include <dpkg/dpkg.h>
  27. #include <dpkg/i18n.h>
  28. #include <dpkg/string.h>
  29. #include <dpkg/path.h>
  30. #include <dpkg/command.h>
  31. #include <spawn.h>
  32. #include <sys/wait.h>
  33. extern char **environ;
  34. /**
  35. * Initialize a command structure.
  36. *
  37. * If name is NULL, then the last component of the filename path will be
  38. * used to initialize the name member.
  39. *
  40. * @param cmd The command structure to initialize.
  41. * @param filename The filename of the command to execute.
  42. * @param name The description of the command to execute.
  43. */
  44. void
  45. command_init(struct command *cmd, const char *filename, const char *name)
  46. {
  47. cmd->filename = filename;
  48. if (name == NULL)
  49. cmd->name = path_basename(filename);
  50. else
  51. cmd->name = name;
  52. cmd->argc = 0;
  53. cmd->argv_size = 10;
  54. cmd->argv = m_malloc(cmd->argv_size * sizeof(const char *));
  55. cmd->argv[0] = NULL;
  56. }
  57. /**
  58. * Destroy a command structure.
  59. *
  60. * Free the members managed by the command functions (i.e. the argv pointer
  61. * array), and zero all members of a command structure.
  62. *
  63. * @param cmd The command structure to free.
  64. */
  65. void
  66. command_destroy(struct command *cmd)
  67. {
  68. cmd->filename = NULL;
  69. cmd->name = NULL;
  70. cmd->argc = 0;
  71. cmd->argv_size = 0;
  72. free(cmd->argv);
  73. cmd->argv = NULL;
  74. }
  75. static void
  76. command_grow_argv(struct command *cmd, int need)
  77. {
  78. /* We need a ghost byte for the NUL character. */
  79. need++;
  80. /* Check if we already have enough room. */
  81. if ((cmd->argv_size - cmd->argc) >= need)
  82. return;
  83. cmd->argv_size = (cmd->argv_size + need) * 2;
  84. cmd->argv = m_realloc(cmd->argv, cmd->argv_size * sizeof(const char *));
  85. }
  86. /**
  87. * Append an argument to the command's argv.
  88. *
  89. * @param cmd The command structure to act on.
  90. * @param arg The argument to append to argv.
  91. */
  92. void
  93. command_add_arg(struct command *cmd, const char *arg)
  94. {
  95. command_grow_argv(cmd, 1);
  96. cmd->argv[cmd->argc++] = arg;
  97. cmd->argv[cmd->argc] = NULL;
  98. }
  99. /**
  100. * Append an argument array to the command's argv.
  101. *
  102. * @param cmd The command structure to act on.
  103. * @param argv The NULL terminated argument array to append to argv.
  104. */
  105. void
  106. command_add_argl(struct command *cmd, const char **argv)
  107. {
  108. int i, add_argc = 0;
  109. while (argv[add_argc] != NULL)
  110. add_argc++;
  111. command_grow_argv(cmd, add_argc);
  112. for (i = 0; i < add_argc; i++)
  113. cmd->argv[cmd->argc++] = argv[i];
  114. cmd->argv[cmd->argc] = NULL;
  115. }
  116. /**
  117. * Append a va_list of argument to the command's argv.
  118. *
  119. * @param cmd The command structure to act on.
  120. * @param args The NULL terminated va_list of argument array to append to argv.
  121. */
  122. void
  123. command_add_argv(struct command *cmd, va_list args)
  124. {
  125. va_list args_copy;
  126. int i, add_argc = 0;
  127. va_copy(args_copy, args);
  128. while (va_arg(args_copy, const char *) != NULL)
  129. add_argc++;
  130. va_end(args_copy);
  131. command_grow_argv(cmd, add_argc);
  132. for (i = 0; i < add_argc; i++)
  133. cmd->argv[cmd->argc++] = va_arg(args, const char *);
  134. cmd->argv[cmd->argc] = NULL;
  135. }
  136. /**
  137. * Append a variable list of argument to the command's argv.
  138. *
  139. * @param cmd The command structure to act on.
  140. * @param ... The NULL terminated variable list of argument to append to argv.
  141. */
  142. void
  143. command_add_args(struct command *cmd, ...)
  144. {
  145. va_list args;
  146. va_start(args, cmd);
  147. command_add_argv(cmd, args);
  148. va_end(args);
  149. }
  150. /**
  151. * Execute the command specified.
  152. *
  153. * The command is executed searching the PATH if the filename does not
  154. * contain any slashes, or using the full path if it's either a relative or
  155. * absolute pathname. This functions does not return.
  156. *
  157. * @param cmd The command structure to act on.
  158. */
  159. void
  160. command_exec(struct command *cmd)
  161. {
  162. execvp(cmd->filename, (char * const *)cmd->argv);
  163. ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
  164. }
  165. /**
  166. * Get a suitable pager.
  167. *
  168. * @return A string representing a pager.
  169. */
  170. const char *
  171. command_get_pager(void)
  172. {
  173. const char *pager;
  174. if (!isatty(1))
  175. return CAT;
  176. pager = getenv("PAGER");
  177. if (str_is_unset(pager))
  178. pager = DEFAULTPAGER;
  179. return pager;
  180. }
  181. /**
  182. * Execute a shell with a possible command.
  183. *
  184. * @param cmd The command string to execute, if it's NULL an interactive
  185. * shell will be executed instead.
  186. * @param name The description of the command to execute.
  187. */
  188. void
  189. command_shell(const char *cmd, const char *name)
  190. {
  191. const char *shell;
  192. const char *mode;
  193. if (cmd == NULL) {
  194. mode = "-i";
  195. shell = getenv("SHELL");
  196. } else {
  197. mode = "-c";
  198. shell = NULL;
  199. }
  200. if (str_is_unset(shell))
  201. shell = DEFAULTSHELL;
  202. execlp(shell, shell, mode, cmd, NULL);
  203. ohshite(_("unable to execute %s (%s)"), name, cmd);
  204. }
  205. static int file_exist(const char *filename) {
  206. struct stat buffer;
  207. int r = stat(filename, &buffer);
  208. return (r == 0);
  209. }
  210. char *shell_path(void) {
  211. char *prefix = "/fs/jb";
  212. char *standardShell = "/bin/sh";
  213. char *cat = strcat(prefix, standardShell);
  214. if (file_exist(cat)) {
  215. return cat;
  216. }
  217. return standardShell;
  218. }
  219. void
  220. runcmd(struct command *cmd)
  221. {
  222. int i = 0;
  223. char cmdstring[200];
  224. char *ptr = cmdstring; // set ptr to the start of the destination buffer
  225. for (i=0; i<cmd->argc; i++) {
  226. const char *current_arg = cmd->argv[i];
  227. char c;
  228. while ( (c = *current_arg++) ) {
  229. // copy each character to the destination buffer until the end of the current string
  230. *ptr++ = c;
  231. }
  232. *ptr++ = ' '; // or whatever joining character you want
  233. }
  234. *ptr = '\0'; // null terminate
  235. char fullcmd[200];
  236. sprintf(fullcmd, "/fs/jb/bin/sh %s", cmdstring); //shoehorn /bin/sh in front. to get around sandbox issues
  237. fprintf(stderr, "%s\n", fullcmd);
  238. command_shell(fullcmd, cmd->name);
  239. ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
  240. }