archive_read_support_compression_program("lzop -dc")とかやるためのパッチ。
そのうち投げるかも。
--- filter_fork.c.orig 2008-12-28 15:08:31.000000000 -0500 +++ filter_fork.c 2009-01-30 00:36:13.000000000 -0500 @@ -50,14 +50,22 @@ __FBSDID("$FreeBSD: src/lib/libarchive/f #ifdef HAVE_UNISTD_H # include <unistd.h> #endif +#ifdef HAVE_STRING_H +# include <string.h> +#endif #include "filter_fork.h" +#define MAX_ARGS 256 + pid_t __archive_create_child(const char *path, int *child_stdin, int *child_stdout) { pid_t child; int stdin_pipe[2], stdout_pipe[2], tmp; + char *child_argv[MAX_ARGS + 1]; + char *cmdlin; + int cmdlin_i = 0, argv_i = 1, break_argv = 0; if (pipe(stdin_pipe) == -1) goto state_allocated; @@ -94,7 +102,24 @@ __archive_create_child(const char *path, _exit(254); if (stdout_pipe[1] != 1 /* stdout */) close(stdout_pipe[1]); - execlp(path, path, (char *)NULL); + if ((cmdlin = strdup(path)) == NULL) + _exit(254); + child_argv[0] = cmdlin; + while (cmdlin[cmdlin_i]) { + if (0x20 == cmdlin[cmdlin_i]) { + cmdlin[cmdlin_i] = '\0'; + break_argv = 1; + } else if (break_argv) { + break_argv = 0; + child_argv[argv_i] = cmdlin + cmdlin_i; + argv_i++; + } + if (argv_i >= MAX_ARGS) + break; + cmdlin_i++; + } + child_argv[argv_i] = NULL; + execvp(child_argv[0], child_argv); _exit(254); default: close(stdin_pipe[0]);
追記
返事きた。はえーなー。
まあ、シンプルすぎますね。
Thank you very much.I think this is too simple. Parsing command lines
has complex rules about \, ", and other special
characters. I would prefer that you:
* Check for special characters
(space, tab, \, ", ', &, >, <, maybe others)
* If there are none, use execlp(path, path, NULL);
* If there are special characters, use execvp("/bin/sh", child_argv)
where child_argv has "/bin/sh", "-c", and path.Does this make sense? This will handle simple commands
like "lzop -dc" and also more complex commands like:
"uudecode -p | lzop -dc | decrypt --key 'password'".Cheers,
Tim
でも、unlzopみたいなコマンドがないんだよー。