command.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * command.c - command execution support
  4. *
  5. * Copyright © 2010 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 <http://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/command.h>
  28. /**
  29. * Initialize a command structure.
  30. *
  31. * If name is NULL, then the last component of the filename path will be
  32. * used to initialize the name member.
  33. *
  34. * @param cmd The command structure to initialize.
  35. * @param filename The filename of the command to execute.
  36. * @param name The description of the command to execute.
  37. */
  38. void
  39. command_init(struct command *cmd, const char *filename, const char *name)
  40. {
  41. cmd->filename = filename;
  42. if (name == NULL) {
  43. const char *progname = strrchr(filename, '/');
  44. cmd->name = progname ? progname + 1 : filename;
  45. } else
  46. cmd->name = name;
  47. cmd->argc = 0;
  48. cmd->argv_size = 10;
  49. cmd->argv = m_malloc(cmd->argv_size * sizeof(const char *));
  50. cmd->argv[0] = NULL;
  51. }
  52. /**
  53. * Destroy a command structure.
  54. *
  55. * Free the members managed by the command functions (i.e. the argv pointer
  56. * array), and zero all members of a command structure.
  57. *
  58. * @param cmd The command structure to free.
  59. */
  60. void
  61. command_destroy(struct command *cmd)
  62. {
  63. cmd->filename = NULL;
  64. cmd->name = NULL;
  65. cmd->argc = 0;
  66. cmd->argv_size = 0;
  67. free(cmd->argv);
  68. cmd->argv = NULL;
  69. }
  70. static void
  71. command_grow_argv(struct command *cmd, int need)
  72. {
  73. /* Check if we already have enough room. */
  74. if ((cmd->argv_size - cmd->argc) >= need)
  75. return;
  76. cmd->argv_size = (cmd->argv_size + need) * 2;
  77. cmd->argv = m_realloc(cmd->argv, cmd->argv_size * sizeof(const char *));
  78. }
  79. /**
  80. * Append an argument to the command's argv.
  81. *
  82. * @param cmd The command structure to act on.
  83. * @param arg The argument to append to argv.
  84. */
  85. void
  86. command_add_arg(struct command *cmd, const char *arg)
  87. {
  88. command_grow_argv(cmd, 1);
  89. cmd->argv[cmd->argc++] = arg;
  90. cmd->argv[cmd->argc] = NULL;
  91. }
  92. /**
  93. * Append an argument array to the command's argv.
  94. *
  95. * @param cmd The command structure to act on.
  96. * @param argv The NULL terminated argument array to append to argv.
  97. */
  98. void
  99. command_add_argl(struct command *cmd, const char **argv)
  100. {
  101. int i, add_argc = 0;
  102. while (argv[add_argc] != NULL)
  103. add_argc++;
  104. command_grow_argv(cmd, add_argc);
  105. for (i = 0; i < add_argc; i++)
  106. cmd->argv[cmd->argc++] = argv[i];
  107. cmd->argv[cmd->argc] = NULL;
  108. }
  109. /**
  110. * Append a va_list of argument to the command's argv.
  111. *
  112. * @param cmd The command structure to act on.
  113. * @param args The NULL terminated va_list of argument array to append to argv.
  114. */
  115. void
  116. command_add_argv(struct command *cmd, va_list args)
  117. {
  118. va_list args_copy;
  119. int i, add_argc = 0;
  120. va_copy(args_copy, args);
  121. while (va_arg(args_copy, const char *) != NULL)
  122. add_argc++;
  123. va_end(args_copy);
  124. command_grow_argv(cmd, add_argc);
  125. for (i = 0; i < add_argc; i++)
  126. cmd->argv[cmd->argc++] = va_arg(args, const char *);
  127. cmd->argv[cmd->argc] = NULL;
  128. }
  129. /**
  130. * Append a variable list of argument to the command's argv.
  131. *
  132. * @param cmd The command structure to act on.
  133. * @param ... The NULL terminated variable list of argument to append to argv.
  134. */
  135. void
  136. command_add_args(struct command *cmd, ...)
  137. {
  138. va_list args;
  139. va_start(args, cmd);
  140. command_add_argv(cmd, args);
  141. va_end(args);
  142. }
  143. /**
  144. * Execute the command specified.
  145. *
  146. * The command is executed searching the PATH if the filename does not
  147. * contain any slashes, or using the full path if it's either a relative or
  148. * absolute pathname. This functions does not return.
  149. *
  150. * @param cmd The command structure to act on.
  151. */
  152. void
  153. command_exec(struct command *cmd)
  154. {
  155. execvp(cmd->filename, (char * const *)cmd->argv);
  156. ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
  157. }
  158. /**
  159. * Execute a shell with a possible command.
  160. *
  161. * @param cmd The command string to execute, if it's NULL an interactive
  162. * shell will be executed instead.
  163. * @param name The description of the command to execute.
  164. */
  165. void
  166. command_shell(const char *cmd, const char *name)
  167. {
  168. const char *shell;
  169. const char *mode;
  170. shell = getenv("SHELL");
  171. if (shell == NULL || shell[0] == '\0')
  172. shell = DEFAULTSHELL;
  173. if (cmd == NULL)
  174. mode = "-i";
  175. else
  176. mode = "-c";
  177. execlp(shell, shell, mode, cmd, NULL);
  178. ohshite(_("unable to execute %s (%s)"), name, cmd);
  179. }