From: Eric Andersen Date: Wed, 28 Jun 2000 16:56:25 +0000 (-0000) Subject: * Fixed a _horrible_ bug where 'tar -tvf' could unlink X-Git-Tag: 0_46~82 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1c314ad655af140b8ef4a271f4e657bf50218236;p=oweals%2Fbusybox.git * Fixed a _horrible_ bug where 'tar -tvf' could unlink local files!!! Fix thanks to Marius Groeger * Added support for "sh -c command args...", also thanks to Marius Groeger -Erik --- diff --git a/Changelog b/Changelog index f747ebe6c..c674ab275 100644 --- a/Changelog +++ b/Changelog @@ -1,13 +1,17 @@ 0.46 + * Fixed a _horrible_ bug where 'tar -tvf' could unlink + local files!!! Fix thanks to Marius Groeger + * Fixed a nasty bug in tar when could mess up saved symlinks. * Updates to handle Linux 2.4.0 kernels (kludged around the "none" entries in /proc/mounts, added a hack to make sysinfo work with both old and new kernels). - * Fixed a nasty bug in tar when could mess up saved symlinks. * Fixed insmod module option parsing for options lacking an '='. Fix thanks to Marc Nijdam * Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport. Fix thanks to Arne Bernin + * Added support for "sh -c command args...", thanks to + Marius Groeger -Erik Andersen diff --git a/archival/tar.c b/archival/tar.c index 836d127e7..611bbd9a0 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -648,7 +648,8 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, } /* Remove any clutter lying in our way */ - unlink( header.name); + if (extractFlag == TRUE) /* .. but only if we are extracting (as */ + unlink( header.name); /* opposed to listing) (rob@sysgo.de) */ /* If we got here, we can be certain we have a legitimate * header to work with. So work with it. */ diff --git a/lash.c b/lash.c index 56d94258c..785e9cc3f 100644 --- a/lash.c +++ b/lash.c @@ -131,8 +131,8 @@ static struct builtInCommand bltins_forking[] = { }; static const char shell_usage[] = - - "sh [FILE]...\n" + "sh [FILE]...\n" + " or: sh -c command [args]...\n" #ifndef BB_FEATURE_TRIVIAL_HELP "\nlash: The BusyBox command interpreter (shell).\n\n" #endif @@ -140,6 +140,7 @@ static const char shell_usage[] = static char cwd[1024]; static char *prompt = "# "; +static char *local_pending_command = NULL; #ifdef BB_FEATURE_SH_COMMAND_EDITING void win_changed(int sig) @@ -225,8 +226,9 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList) if (*cmd->progs[0].argv[0] == 'f') { /* Make this job the foreground job */ - if (tcsetpgrp(0, job->pgrp)) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) + perror("tcsetpgrp"); jobList->fg = job; } @@ -411,6 +413,17 @@ static void checkJobs(struct jobSet *jobList) static int getCommand(FILE * source, char *command) { + if (source == NULL) { + if (local_pending_command) { + /* a command specified (-c option): return it & mark it done */ + strcpy(command, local_pending_command); + free(local_pending_command); + local_pending_command = NULL; + return 0; + } + return 1; + } + if (source == stdin) { #ifdef BB_FEATURE_SH_COMMAND_EDITING int len; @@ -842,7 +855,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) jobList->fg = job; /* move the new process group into the foreground */ - if (tcsetpgrp(0, newJob.pgrp)) + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) perror("tcsetpgrp"); } @@ -894,10 +908,14 @@ static int busy_loop(FILE * input) char *nextCommand = NULL; struct jobSet jobList = { NULL, NULL }; struct job newJob; + pid_t parent_pgrp; int i; int status; int inBg; + /* save current owner of TTY so we can restore it on exit */ + parent_pgrp = tcgetpgrp(0); + command = (char *) calloc(BUFSIZ, sizeof(char)); /* don't pay any attention to this signal; it just confuses @@ -939,10 +957,6 @@ static int busy_loop(FILE * input) removeJob(&jobList, jobList.fg); jobList.fg = NULL; - - /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); } } else { /* the child was stopped */ @@ -958,13 +972,18 @@ static int busy_loop(FILE * input) if (!jobList.fg) { /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, getpid()) && errno != ENOTTY) + perror("tcsetpgrp"); } } } free(command); + /* return controlling TTY back to parent process group before exiting */ + if (tcsetpgrp(0, parent_pgrp)) + perror("tcsetpgrp"); + return 0; } @@ -973,9 +992,6 @@ int shell_main(int argc, char **argv) { FILE *input = stdin; - if (argc > 2) { - usage(shell_usage); - } /* initialize the cwd */ getcwd(cwd, sizeof(cwd)); @@ -993,13 +1009,33 @@ int shell_main(int argc, char **argv) fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); } else { - if (*argv[1]=='-') { - usage("sh\n\nlash -- the BusyBox LAme SHell (command interpreter)\n"); + if (argv[1][0]=='-' && argv[1][1]=='c') { + int i; + local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); + if (local_pending_command == 0) { + fatalError("sh: out of memory\n"); + } + for(i=2; i= BUFSIZ) { + fatalError("sh: commands for -c option too long\n"); + } + strcat(local_pending_command, argv[i]); + if (i + 1 < argc) + strcat(local_pending_command, " "); + } + input = NULL; + } - input = fopen(argv[1], "r"); - if (!input) { - fatalError("sh: Couldn't open file '%s': %s\n", argv[1], - strerror(errno)); + else if (argv[1][0]=='-') { + usage(shell_usage); + } + else { + input = fopen(argv[1], "r"); + if (!input) { + fatalError("sh: Couldn't open file '%s': %s\n", argv[1], + strerror(errno)); + } } } diff --git a/sh.c b/sh.c index 56d94258c..785e9cc3f 100644 --- a/sh.c +++ b/sh.c @@ -131,8 +131,8 @@ static struct builtInCommand bltins_forking[] = { }; static const char shell_usage[] = - - "sh [FILE]...\n" + "sh [FILE]...\n" + " or: sh -c command [args]...\n" #ifndef BB_FEATURE_TRIVIAL_HELP "\nlash: The BusyBox command interpreter (shell).\n\n" #endif @@ -140,6 +140,7 @@ static const char shell_usage[] = static char cwd[1024]; static char *prompt = "# "; +static char *local_pending_command = NULL; #ifdef BB_FEATURE_SH_COMMAND_EDITING void win_changed(int sig) @@ -225,8 +226,9 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList) if (*cmd->progs[0].argv[0] == 'f') { /* Make this job the foreground job */ - if (tcsetpgrp(0, job->pgrp)) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) + perror("tcsetpgrp"); jobList->fg = job; } @@ -411,6 +413,17 @@ static void checkJobs(struct jobSet *jobList) static int getCommand(FILE * source, char *command) { + if (source == NULL) { + if (local_pending_command) { + /* a command specified (-c option): return it & mark it done */ + strcpy(command, local_pending_command); + free(local_pending_command); + local_pending_command = NULL; + return 0; + } + return 1; + } + if (source == stdin) { #ifdef BB_FEATURE_SH_COMMAND_EDITING int len; @@ -842,7 +855,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) jobList->fg = job; /* move the new process group into the foreground */ - if (tcsetpgrp(0, newJob.pgrp)) + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) perror("tcsetpgrp"); } @@ -894,10 +908,14 @@ static int busy_loop(FILE * input) char *nextCommand = NULL; struct jobSet jobList = { NULL, NULL }; struct job newJob; + pid_t parent_pgrp; int i; int status; int inBg; + /* save current owner of TTY so we can restore it on exit */ + parent_pgrp = tcgetpgrp(0); + command = (char *) calloc(BUFSIZ, sizeof(char)); /* don't pay any attention to this signal; it just confuses @@ -939,10 +957,6 @@ static int busy_loop(FILE * input) removeJob(&jobList, jobList.fg); jobList.fg = NULL; - - /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); } } else { /* the child was stopped */ @@ -958,13 +972,18 @@ static int busy_loop(FILE * input) if (!jobList.fg) { /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, getpid()) && errno != ENOTTY) + perror("tcsetpgrp"); } } } free(command); + /* return controlling TTY back to parent process group before exiting */ + if (tcsetpgrp(0, parent_pgrp)) + perror("tcsetpgrp"); + return 0; } @@ -973,9 +992,6 @@ int shell_main(int argc, char **argv) { FILE *input = stdin; - if (argc > 2) { - usage(shell_usage); - } /* initialize the cwd */ getcwd(cwd, sizeof(cwd)); @@ -993,13 +1009,33 @@ int shell_main(int argc, char **argv) fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); } else { - if (*argv[1]=='-') { - usage("sh\n\nlash -- the BusyBox LAme SHell (command interpreter)\n"); + if (argv[1][0]=='-' && argv[1][1]=='c') { + int i; + local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); + if (local_pending_command == 0) { + fatalError("sh: out of memory\n"); + } + for(i=2; i= BUFSIZ) { + fatalError("sh: commands for -c option too long\n"); + } + strcat(local_pending_command, argv[i]); + if (i + 1 < argc) + strcat(local_pending_command, " "); + } + input = NULL; + } - input = fopen(argv[1], "r"); - if (!input) { - fatalError("sh: Couldn't open file '%s': %s\n", argv[1], - strerror(errno)); + else if (argv[1][0]=='-') { + usage(shell_usage); + } + else { + input = fopen(argv[1], "r"); + if (!input) { + fatalError("sh: Couldn't open file '%s': %s\n", argv[1], + strerror(errno)); + } } } diff --git a/shell/lash.c b/shell/lash.c index 56d94258c..785e9cc3f 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -131,8 +131,8 @@ static struct builtInCommand bltins_forking[] = { }; static const char shell_usage[] = - - "sh [FILE]...\n" + "sh [FILE]...\n" + " or: sh -c command [args]...\n" #ifndef BB_FEATURE_TRIVIAL_HELP "\nlash: The BusyBox command interpreter (shell).\n\n" #endif @@ -140,6 +140,7 @@ static const char shell_usage[] = static char cwd[1024]; static char *prompt = "# "; +static char *local_pending_command = NULL; #ifdef BB_FEATURE_SH_COMMAND_EDITING void win_changed(int sig) @@ -225,8 +226,9 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList) if (*cmd->progs[0].argv[0] == 'f') { /* Make this job the foreground job */ - if (tcsetpgrp(0, job->pgrp)) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) + perror("tcsetpgrp"); jobList->fg = job; } @@ -411,6 +413,17 @@ static void checkJobs(struct jobSet *jobList) static int getCommand(FILE * source, char *command) { + if (source == NULL) { + if (local_pending_command) { + /* a command specified (-c option): return it & mark it done */ + strcpy(command, local_pending_command); + free(local_pending_command); + local_pending_command = NULL; + return 0; + } + return 1; + } + if (source == stdin) { #ifdef BB_FEATURE_SH_COMMAND_EDITING int len; @@ -842,7 +855,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) jobList->fg = job; /* move the new process group into the foreground */ - if (tcsetpgrp(0, newJob.pgrp)) + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) perror("tcsetpgrp"); } @@ -894,10 +908,14 @@ static int busy_loop(FILE * input) char *nextCommand = NULL; struct jobSet jobList = { NULL, NULL }; struct job newJob; + pid_t parent_pgrp; int i; int status; int inBg; + /* save current owner of TTY so we can restore it on exit */ + parent_pgrp = tcgetpgrp(0); + command = (char *) calloc(BUFSIZ, sizeof(char)); /* don't pay any attention to this signal; it just confuses @@ -939,10 +957,6 @@ static int busy_loop(FILE * input) removeJob(&jobList, jobList.fg); jobList.fg = NULL; - - /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); } } else { /* the child was stopped */ @@ -958,13 +972,18 @@ static int busy_loop(FILE * input) if (!jobList.fg) { /* move the shell to the foreground */ - if (tcsetpgrp(0, getpid())) - perror("tcsetpgrp"); + /* suppress messages when run from /linuxrc mag@sysgo.de */ + if (tcsetpgrp(0, getpid()) && errno != ENOTTY) + perror("tcsetpgrp"); } } } free(command); + /* return controlling TTY back to parent process group before exiting */ + if (tcsetpgrp(0, parent_pgrp)) + perror("tcsetpgrp"); + return 0; } @@ -973,9 +992,6 @@ int shell_main(int argc, char **argv) { FILE *input = stdin; - if (argc > 2) { - usage(shell_usage); - } /* initialize the cwd */ getcwd(cwd, sizeof(cwd)); @@ -993,13 +1009,33 @@ int shell_main(int argc, char **argv) fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); } else { - if (*argv[1]=='-') { - usage("sh\n\nlash -- the BusyBox LAme SHell (command interpreter)\n"); + if (argv[1][0]=='-' && argv[1][1]=='c') { + int i; + local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); + if (local_pending_command == 0) { + fatalError("sh: out of memory\n"); + } + for(i=2; i= BUFSIZ) { + fatalError("sh: commands for -c option too long\n"); + } + strcat(local_pending_command, argv[i]); + if (i + 1 < argc) + strcat(local_pending_command, " "); + } + input = NULL; + } - input = fopen(argv[1], "r"); - if (!input) { - fatalError("sh: Couldn't open file '%s': %s\n", argv[1], - strerror(errno)); + else if (argv[1][0]=='-') { + usage(shell_usage); + } + else { + input = fopen(argv[1], "r"); + if (!input) { + fatalError("sh: Couldn't open file '%s': %s\n", argv[1], + strerror(errno)); + } } } diff --git a/tar.c b/tar.c index 836d127e7..611bbd9a0 100644 --- a/tar.c +++ b/tar.c @@ -648,7 +648,8 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, } /* Remove any clutter lying in our way */ - unlink( header.name); + if (extractFlag == TRUE) /* .. but only if we are extracting (as */ + unlink( header.name); /* opposed to listing) (rob@sysgo.de) */ /* If we got here, we can be certain we have a legitimate * header to work with. So work with it. */