Fix to cmdedit.c from Vladimir
[oweals/busybox.git] / shell / lash.c
index dcec14abae68b07ad18a96344485f10ba3ccf911..8727e12ae74ecb1be4998f9e0988b3288014ea99 100644 (file)
@@ -65,9 +65,9 @@
 #include <unistd.h>
 #include <getopt.h>
 
-#undef BB_FEATURE_SH_WORDEXP
+//#define BB_FEATURE_SH_WORDEXP
 
-#if BB_FEATURE_SH_WORDEXP
+#ifdef BB_FEATURE_SH_WORDEXP
 #include <wordexp.h>
 #define expand_t       wordexp_t
 #undef BB_FEATURE_SH_BACKTICKS
@@ -669,17 +669,22 @@ static void close_all()
 static void free_job(struct job *cmd)
 {
        int i;
+       struct jobset *keep;
 
        for (i = 0; i < cmd->num_progs; i++) {
                free(cmd->progs[i].argv);
                if (cmd->progs[i].redirects)
                        free(cmd->progs[i].redirects);
        }
-       free(cmd->progs);
+       if (cmd->progs)
+               free(cmd->progs);
        if (cmd->text)
                free(cmd->text);
-       free(cmd->cmdbuf);
+       if (cmd->cmdbuf)
+               free(cmd->cmdbuf);
+       keep = cmd->job_list;
        memset(cmd, 0, sizeof(struct job));
+       cmd->job_list = keep;
 }
 
 /* remove a job from the job_list */
@@ -876,9 +881,6 @@ static int get_command(FILE * source, char *command)
                return 1;
        }
 
-       /* remove trailing newline */
-       chomp(command);
-
        return 0;
 }
 
@@ -931,7 +933,7 @@ char * strsep_space( char *string, int * index)
                return NULL;
        }
 
-       token = xmalloc(*index);
+       token = xmalloc(*index+1);
        token[*index] = '\0';
        strncpy(token, string,  *index); 
 
@@ -957,8 +959,8 @@ static int expand_arguments(char *command)
        while( command && command[index]) {
                if (command[index] == '\\') {
                        char *tmp = command+index+1;
-                       command[index+1] = process_escape_sequence(  &tmp );
-                       memmove(command+index, command+index+1, strlen(command+index));
+                       command[index] = process_escape_sequence(  &tmp );
+                       memmove(command+index + 1, tmp, strlen(tmp)+1);
                }
                index++;
        }
@@ -966,7 +968,7 @@ static int expand_arguments(char *command)
 #ifdef BB_FEATURE_SH_ENVIRONMENT
 
 
-#if BB_FEATURE_SH_WORDEXP
+#ifdef BB_FEATURE_SH_WORDEXP
        /* This first part uses wordexp() which is a wonderful C lib 
         * function which expands nearly everything.  */ 
        retval = wordexp (command, &expand_result, WRDE_SHOWERR);
@@ -1010,7 +1012,14 @@ static int expand_arguments(char *command)
         * (char*) into cmd (char**, one word per string) */
        {
         
-               int flags = GLOB_NOCHECK|GLOB_BRACE|GLOB_TILDE;
+               int flags = GLOB_NOCHECK
+#ifdef GLOB_BRACE
+                               | GLOB_BRACE
+#endif 
+#ifdef GLOB_TILDE
+                               | GLOB_TILDE
+#endif 
+                       ;
                char *tmpcmd, *cmd, *cmd_copy;
                /* We need a clean copy, so strsep can mess up the copy while
                 * we write stuff into the original (in a minute) */
@@ -1037,13 +1046,16 @@ static int expand_arguments(char *command)
                        /* Convert from char** (one word per string) to a simple char*,
                         * but don't overflow command which is BUFSIZ in length */
                                for (i=0; i < expand_result.gl_pathc; i++) {
-                                       length=strlen(expand_result.gl_pathv[i])+1;
-                                       if (BUFSIZ-total_length-length <= 0) {
+                                       length=strlen(expand_result.gl_pathv[i]);
+                                       if (total_length+length+1 >= BUFSIZ) {
                                                error_msg(out_of_space);
                                                return FALSE;
                                        }
+                                       if (i>0) {
+                                               strcat(command+total_length, " ");
+                                               total_length+=1;
+                                       }
                                        strcat(command+total_length, expand_result.gl_pathv[i]);
-                                       strcat(command+total_length, " ");
                                        total_length+=length;
                                }
                                globfree (&expand_result);
@@ -1101,25 +1113,24 @@ static int expand_arguments(char *command)
                } else {
                        /* Looks like an environment variable */
                        char delim_hold;
-                       int num_skip_chars=1;
+                       int num_skip_chars=0;
                        int dstlen = strlen(dst);
                        /* Is this a ${foo} type variable? */
                        if (dstlen >=2 && *(dst+1) == '{') {
                                src=strchr(dst+1, '}');
-                               num_skip_chars=2;
+                               num_skip_chars=1;
                        } else {
-                               src=strpbrk(dst+1, " \t~`!$^&*()=|\\[];\"'<>?./");
+                               src=dst+1;
+                               while(isalnum(*src) || *src=='_') src++;
                        }
                        if (src == NULL) {
                                src = dst+dstlen;
                        }
                        delim_hold=*src;
                        *src='\0';  /* temporary */
-                       var = getenv(dst + num_skip_chars);
+                       var = getenv(dst + 1 + num_skip_chars);
                        *src=delim_hold;
-                       if (num_skip_chars==2) {
-                               src++;
-                       }
+                       src += num_skip_chars;
                }
                if (var == NULL) {
                        /* Seems we got an un-expandable variable.  So delete it. */
@@ -1134,8 +1145,7 @@ static int expand_arguments(char *command)
                        }
                        /* Move stuff to the end of the string to accommodate
                         * filling the created gap with the new stuff */
-                       memmove(dst+subst_len, src, trail_len);
-                       *(dst+subst_len+trail_len)='\0';
+                       memmove(dst+subst_len, src, trail_len+1);
                        /* Now copy in the new stuff */
                        memcpy(dst, var, subst_len);
                        src = dst+subst_len;
@@ -1289,7 +1299,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
                                        chptr++;
 
                                if (!*chptr) {
-                                       error_msg("file name expected after %c", *src);
+                                       error_msg("file name expected after %c", *(src-1));
                                        free_job(job);
                                        job->num_progs=0;
                                        return 1;
@@ -1460,7 +1470,6 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
                                        break;
 #else
                                        error_msg("character expected after \\");
-                                       free(command);
                                        free_job(job);
                                        return 1;
 #endif