command.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 <dpkg/dpkg.h>
  26. #include <dpkg/i18n.h>
  27. #include <dpkg/string.h>
  28. #include <dpkg/path.h>
  29. #include <dpkg/command.h>
  30. #include <spawn.h>
  31. #include <sys/wait.h>
  32. extern char **environ;
  33. /**
  34. * Initialize a command structure.
  35. *
  36. * If name is NULL, then the last component of the filename path will be
  37. * used to initialize the name member.
  38. *
  39. * @param cmd The command structure to initialize.
  40. * @param filename The filename of the command to execute.
  41. * @param name The description of the command to execute.
  42. */
  43. void
  44. command_init(struct command *cmd, const char *filename, const char *name)
  45. {
  46. cmd->filename = filename;
  47. if (name == NULL)
  48. cmd->name = path_basename(filename);
  49. else
  50. cmd->name = name;
  51. cmd->argc = 0;
  52. cmd->argv_size = 10;
  53. cmd->argv = m_malloc(cmd->argv_size * sizeof(const char *));
  54. cmd->argv[0] = NULL;
  55. }
  56. /**
  57. * Destroy a command structure.
  58. *
  59. * Free the members managed by the command functions (i.e. the argv pointer
  60. * array), and zero all members of a command structure.
  61. *
  62. * @param cmd The command structure to free.
  63. */
  64. void
  65. command_destroy(struct command *cmd)
  66. {
  67. cmd->filename = NULL;
  68. cmd->name = NULL;
  69. cmd->argc = 0;
  70. cmd->argv_size = 0;
  71. free(cmd->argv);
  72. cmd->argv = NULL;
  73. }
  74. static void
  75. command_grow_argv(struct command *cmd, int need)
  76. {
  77. /* We need a ghost byte for the NUL character. */
  78. need++;
  79. /* Check if we already have enough room. */
  80. if ((cmd->argv_size - cmd->argc) >= need)
  81. return;
  82. cmd->argv_size = (cmd->argv_size + need) * 2;
  83. cmd->argv = m_realloc(cmd->argv, cmd->argv_size * sizeof(const char *));
  84. }
  85. /**
  86. * Append an argument to the command's argv.
  87. *
  88. * @param cmd The command structure to act on.
  89. * @param arg The argument to append to argv.
  90. */
  91. void
  92. command_add_arg(struct command *cmd, const char *arg)
  93. {
  94. command_grow_argv(cmd, 1);
  95. cmd->argv[cmd->argc++] = arg;
  96. cmd->argv[cmd->argc] = NULL;
  97. }
  98. /**
  99. * Append an argument array to the command's argv.
  100. *
  101. * @param cmd The command structure to act on.
  102. * @param argv The NULL terminated argument array to append to argv.
  103. */
  104. void
  105. command_add_argl(struct command *cmd, const char **argv)
  106. {
  107. int i, add_argc = 0;
  108. while (argv[add_argc] != NULL)
  109. add_argc++;
  110. command_grow_argv(cmd, add_argc);
  111. for (i = 0; i < add_argc; i++)
  112. cmd->argv[cmd->argc++] = argv[i];
  113. cmd->argv[cmd->argc] = NULL;
  114. }
  115. /**
  116. * Append a va_list of argument to the command's argv.
  117. *
  118. * @param cmd The command structure to act on.
  119. * @param args The NULL terminated va_list of argument array to append to argv.
  120. */
  121. void
  122. command_add_argv(struct command *cmd, va_list args)
  123. {
  124. va_list args_copy;
  125. int i, add_argc = 0;
  126. va_copy(args_copy, args);
  127. while (va_arg(args_copy, const char *) != NULL)
  128. add_argc++;
  129. va_end(args_copy);
  130. command_grow_argv(cmd, add_argc);
  131. for (i = 0; i < add_argc; i++)
  132. cmd->argv[cmd->argc++] = va_arg(args, const char *);
  133. cmd->argv[cmd->argc] = NULL;
  134. }
  135. /**
  136. * Append a variable list of argument to the command's argv.
  137. *
  138. * @param cmd The command structure to act on.
  139. * @param ... The NULL terminated variable list of argument to append to argv.
  140. */
  141. void
  142. command_add_args(struct command *cmd, ...)
  143. {
  144. va_list args;
  145. va_start(args, cmd);
  146. command_add_argv(cmd, args);
  147. va_end(args);
  148. }
  149. /**
  150. * Execute the command specified.
  151. *
  152. * The command is executed searching the PATH if the filename does not
  153. * contain any slashes, or using the full path if it's either a relative or
  154. * absolute pathname. This functions does not return.
  155. *
  156. * @param cmd The command structure to act on.
  157. */
  158. void
  159. command_exec(struct command *cmd)
  160. {
  161. execvp(cmd->filename, (char * const *)cmd->argv);
  162. ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
  163. }
  164. /**
  165. * Get a suitable pager.
  166. *
  167. * @return A string representing a pager.
  168. */
  169. const char *
  170. command_get_pager(void)
  171. {
  172. const char *pager;
  173. if (!isatty(1))
  174. return CAT;
  175. pager = getenv("PAGER");
  176. if (str_is_unset(pager))
  177. pager = DEFAULTPAGER;
  178. return pager;
  179. }
  180. /**
  181. * Execute a shell with a possible command.
  182. *
  183. * @param cmd The command string to execute, if it's NULL an interactive
  184. * shell will be executed instead.
  185. * @param name The description of the command to execute.
  186. */
  187. void
  188. command_shell(const char *cmd, const char *name)
  189. {
  190. const char *shell;
  191. const char *mode;
  192. if (cmd == NULL) {
  193. mode = "-i";
  194. shell = getenv("SHELL");
  195. } else {
  196. mode = "-c";
  197. shell = NULL;
  198. }
  199. if (str_is_unset(shell))
  200. shell = DEFAULTSHELL;
  201. execlp(shell, shell, mode, cmd, NULL);
  202. ohshite(_("unable to execute %s (%s)"), name, cmd);
  203. }
  204. void
  205. runcmd(struct command *cmd)
  206. {
  207. int i = 0;
  208. char cmdstring[200];
  209. char *ptr = cmdstring; // set ptr to the start of the destination buffer
  210. for (i=0; i<cmd->argc; i++) {
  211. const char *current_arg = cmd->argv[i];
  212. char c;
  213. while ( (c = *current_arg++) ) {
  214. // copy each character to the destination buffer until the end of the current string
  215. *ptr++ = c;
  216. }
  217. *ptr++ = ' '; // or whatever joining character you want
  218. }
  219. *ptr = '\0'; // null terminate
  220. char fullcmd[200];
  221. sprintf(fullcmd, "/bin/sh %s", cmdstring); //shoehorn /bin/sh in front. to get around sandbox issues
  222. fprintf(stderr, "%s\n", fullcmd);
  223. command_shell(fullcmd, cmd->name);
  224. ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
  225. }