9 /* #include <exec_command.h>
11 /* NORETURN exec_command(command)
12 /* const char *command;
14 /* \fIexec_command\fR() replaces the current process by an instance
15 /* of \fIcommand\fR. This routine uses a simple heuristic to avoid
16 /* the overhead of running a command shell interpreter.
18 /* This routine never returns. All errors are fatal.
22 /* The Secure Mailer license must be distributed with this software.
25 /* IBM T.J. Watson Research
27 /* Yorktown Heights, NY 10598, USA
41 /* Utility library. */
45 #include <exec_command.h>
47 /* Application-specific. */
49 #define SPACE_TAB " \t"
51 /* exec_command - exec command */
53 NORETURN
exec_command(const char *command
)
58 * Character filter. In this particular case, we allow space and tab in
59 * addition to the regular character set.
61 static char ok_chars
[] = "1234567890!@%-_=+:,./\
62 abcdefghijklmnopqrstuvwxyz\
63 ABCDEFGHIJKLMNOPQRSTUVWXYZ" SPACE_TAB
;
66 * See if this command contains any shell magic characters.
68 if (command
[strspn(command
, ok_chars
)] == 0) {
71 * No shell meta characters found, so we can try to avoid the overhead
72 * of running a shell. Just split the command on whitespace and exec
73 * the result directly.
75 argv
= argv_split(command
, SPACE_TAB
);
76 (void) execvp(argv
->argv
[0], argv
->argv
);
79 * Auch. Perhaps they're using some shell built-in command.
81 if (errno
!= ENOENT
|| strchr(argv
->argv
[0], '/') != 0)
82 msg_fatal("execvp %s: %m", argv
->argv
[0]);
85 * Not really necessary, but...
91 * Pass the command to a shell.
93 (void) execl(_PATH_BSHELL
, "sh", "-c", command
, (char *) 0);
94 msg_fatal("execl %s: %m", _PATH_BSHELL
);
100 * Yet another proof-of-concept test program.
103 #include <msg_vstream.h>
105 int main(int argc
, char **argv
)
107 msg_vstream_init(argv
[0], VSTREAM_ERR
);
109 msg_fatal("usage: %s 'command'", argv
[0]);
110 exec_command(argv
[1]);