build: Make default shell and pager selectable at configure time
[dpkg.git] / lib / dpkg / command.c
blob36a155337cd5e15365fde73d5a9c20320adbaccc
1 /*
2 * libdpkg - Debian packaging suite library routines
3 * command.c - command execution support
5 * Copyright © 2010-2012 Guillem Jover <guillem@debian.org>
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.
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.
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/>.
21 #include <config.h>
22 #include <compat.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <unistd.h>
28 #include <dpkg/dpkg.h>
29 #include <dpkg/i18n.h>
30 #include <dpkg/string.h>
31 #include <dpkg/varbuf.h>
32 #include <dpkg/file.h>
33 #include <dpkg/path.h>
34 #include <dpkg/command.h>
36 /**
37 * Initialize a command structure.
39 * If name is NULL, then the last component of the filename path will be
40 * used to initialize the name member.
42 * @param cmd The command structure to initialize.
43 * @param filename The filename of the command to execute.
44 * @param name The description of the command to execute.
46 void
47 command_init(struct command *cmd, const char *filename, const char *name)
49 cmd->filename = filename;
50 if (name == NULL)
51 cmd->name = path_basename(filename);
52 else
53 cmd->name = name;
54 cmd->argc = 0;
55 cmd->argv_size = 10;
56 cmd->argv = m_malloc(cmd->argv_size * sizeof(cmd->argv[0]));
57 cmd->argv[0] = NULL;
60 /**
61 * Destroy a command structure.
63 * Free the members managed by the command functions (i.e. the argv pointer
64 * array), and zero all members of a command structure.
66 * @param cmd The command structure to free.
68 void
69 command_destroy(struct command *cmd)
71 cmd->filename = NULL;
72 cmd->name = NULL;
73 cmd->argc = 0;
74 cmd->argv_size = 0;
75 free(cmd->argv);
76 cmd->argv = NULL;
79 static void
80 command_grow_argv(struct command *cmd, int need)
82 /* We need a ghost byte for the NUL character. */
83 need++;
85 /* Check if we already have enough room. */
86 if ((cmd->argv_size - cmd->argc) >= need)
87 return;
89 cmd->argv_size = (cmd->argv_size + need) * 2;
90 cmd->argv = m_realloc(cmd->argv, cmd->argv_size * sizeof(cmd->argv[0]));
93 /**
94 * Append an argument to the command's argv.
96 * @param cmd The command structure to act on.
97 * @param arg The argument to append to argv.
99 void
100 command_add_arg(struct command *cmd, const char *arg)
102 command_grow_argv(cmd, 1);
104 cmd->argv[cmd->argc++] = arg;
105 cmd->argv[cmd->argc] = NULL;
109 * Append an argument array to the command's argv.
111 * @param cmd The command structure to act on.
112 * @param argv The NULL terminated argument array to append to argv.
114 void
115 command_add_argl(struct command *cmd, const char **argv)
117 int i, add_argc = 0;
119 while (argv[add_argc] != NULL)
120 add_argc++;
122 command_grow_argv(cmd, add_argc);
124 for (i = 0; i < add_argc; i++)
125 cmd->argv[cmd->argc++] = argv[i];
127 cmd->argv[cmd->argc] = NULL;
131 * Append a va_list of argument to the command's argv.
133 * @param cmd The command structure to act on.
134 * @param args The NULL terminated va_list of argument array to append to argv.
136 void
137 command_add_argv(struct command *cmd, va_list args)
139 va_list args_copy;
140 int i, add_argc = 0;
142 va_copy(args_copy, args);
143 while (va_arg(args_copy, const char *) != NULL)
144 add_argc++;
145 va_end(args_copy);
147 command_grow_argv(cmd, add_argc);
149 for (i = 0; i < add_argc; i++)
150 cmd->argv[cmd->argc++] = va_arg(args, const char *);
152 cmd->argv[cmd->argc] = NULL;
156 * Append a variable list of argument to the command's argv.
158 * @param cmd The command structure to act on.
159 * @param ... The NULL terminated variable list of argument to append to argv.
161 void
162 command_add_args(struct command *cmd, ...)
164 va_list args;
166 va_start(args, cmd);
167 command_add_argv(cmd, args);
168 va_end(args);
172 * Execute the command specified.
174 * The command is executed searching the PATH if the filename does not
175 * contain any slashes, or using the full path if it's either a relative or
176 * absolute pathname. This functions does not return.
178 * @param cmd The command structure to act on.
180 void
181 command_exec(struct command *cmd)
183 execvp(cmd->filename, (char * const *)cmd->argv);
184 ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
188 * Execute a shell with a possible command.
190 * @param cmd The command string to execute, if it's NULL an interactive
191 * shell will be executed instead.
192 * @param name The description of the command to execute.
194 void
195 command_shell(const char *cmd, const char *name)
197 const char *shell;
198 const char *mode;
200 if (cmd == NULL) {
201 mode = "-i";
202 shell = getenv("SHELL");
203 } else {
204 mode = "-c";
205 shell = NULL;
208 if (str_is_unset(shell))
209 shell = DPKG_DEFAULT_SHELL;
211 execlp(shell, shell, mode, "--", cmd, NULL);
212 ohshite(_("unable to execute %s (%s)"), name, cmd);
216 * Check whether a command can be found in PATH.
218 * @param cmd The command name to check. This is a relative pathname.
220 * @return A boolean denoting whether the command has been found.
222 bool
223 command_in_path(const char *cmd)
225 struct varbuf filename = VARBUF_INIT;
226 const char *path_list;
227 const char *path, *path_end;
229 if (cmd[0] == '/')
230 return file_is_exec(cmd);
232 path_list = getenv("PATH");
233 if (!path_list)
234 ohshit(_("PATH is not set"));
236 for (path = path_list; path; path = *path_end ? path_end + 1 : NULL) {
237 size_t path_len;
239 path_end = strchrnul(path, ':');
240 path_len = (size_t)(path_end - path);
242 varbuf_set_buf(&filename, path, path_len);
243 if (path_len)
244 varbuf_add_char(&filename, '/');
245 varbuf_add_str(&filename, cmd);
246 varbuf_end_str(&filename);
248 if (file_is_exec(filename.buf)) {
249 varbuf_destroy(&filename);
250 return true;
254 varbuf_destroy(&filename);
255 return false;