diff options
| author | Eric Andersen <andersen@codepoet.org> | 2001-02-20 06:38:44 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2001-02-20 06:38:44 +0000 |
| commit | caeeb367841416191d2670fa36545720ca970d5b (patch) | |
| tree | abdcb1ff56bc772d6c17d8c5bfb42a3f4efb422c /shell | |
| parent | a183f0582550c873e69fd806e051320957f77e0f (diff) | |
| download | busybox-w32-caeeb367841416191d2670fa36545720ca970d5b.tar.gz busybox-w32-caeeb367841416191d2670fa36545720ca970d5b.tar.bz2 busybox-w32-caeeb367841416191d2670fa36545720ca970d5b.zip | |
This fixes lash so it handles environment variable expansion, regardless
of where the environment variables are located in an argument. This allows
things like 'echo foo$1$SHELL' to expand the same way bash would expand it.
Of course, to make this work I introduced a memory leak, and I am too tired
to find a way to fix it.
-Erik
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/lash.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/shell/lash.c b/shell/lash.c index 76ef16a55..077cb1182 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | //#define DEBUG_SHELL | 49 | //#define DEBUG_SHELL |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | #include "busybox.h" | ||
| 53 | #include <stdio.h> | 52 | #include <stdio.h> |
| 54 | #include <stdlib.h> | 53 | #include <stdlib.h> |
| 55 | #include <ctype.h> | 54 | #include <ctype.h> |
| @@ -62,6 +61,7 @@ | |||
| 62 | #include <sys/wait.h> | 61 | #include <sys/wait.h> |
| 63 | #include <unistd.h> | 62 | #include <unistd.h> |
| 64 | #include <getopt.h> | 63 | #include <getopt.h> |
| 64 | #include "busybox.h" | ||
| 65 | #include "cmdedit.h" | 65 | #include "cmdedit.h" |
| 66 | 66 | ||
| 67 | static const int MAX_LINE = 256; /* size of input buffer for cwd data */ | 67 | static const int MAX_LINE = 256; /* size of input buffer for cwd data */ |
| @@ -916,44 +916,57 @@ static void expand_argument(struct child_prog *prog, int *argcPtr, | |||
| 916 | flags = 0; | 916 | flags = 0; |
| 917 | i = 0; | 917 | i = 0; |
| 918 | } | 918 | } |
| 919 | /* do shell variable substitution */ | ||
| 920 | if(*prog->argv[argc_l - 1] == '$') { | ||
| 921 | if ((var = getenv(prog->argv[argc_l - 1] + 1))) { | ||
| 922 | prog->argv[argc_l - 1] = var; | ||
| 923 | } | ||
| 924 | #ifdef BB_FEATURE_SH_ENVIRONMENT | 919 | #ifdef BB_FEATURE_SH_ENVIRONMENT |
| 925 | else { | 920 | /* do shell variable substitution */ |
| 926 | switch(*(prog->argv[argc_l - 1] + 1)) { | 921 | src = prog->argv[argc_l - 1]; |
| 922 | while((dst = strchr(src,'$')) != NULL){ | ||
| 923 | if (!(var = getenv(dst + 1))) { | ||
| 924 | switch(*(dst+1)) { | ||
| 927 | case '?': | 925 | case '?': |
| 928 | prog->argv[argc_l - 1] = itoa(last_return_code); | 926 | var = itoa(last_return_code); |
| 929 | break; | 927 | break; |
| 930 | case '$': | 928 | case '$': |
| 931 | prog->argv[argc_l - 1] = itoa(getpid()); | 929 | var = itoa(getpid()); |
| 932 | break; | 930 | break; |
| 933 | case '#': | 931 | case '#': |
| 934 | prog->argv[argc_l - 1] = itoa(argc-1); | 932 | var = itoa(argc-1); |
| 935 | break; | 933 | break; |
| 936 | case '!': | 934 | case '!': |
| 937 | if (last_bg_pid==-1) | 935 | if (last_bg_pid==-1) |
| 938 | *(prog->argv[argc_l - 1])='\0'; | 936 | *(var)='\0'; |
| 939 | else | 937 | else |
| 940 | prog->argv[argc_l - 1] = itoa(last_bg_pid); | 938 | var = itoa(last_bg_pid); |
| 941 | break; | 939 | break; |
| 942 | case '0':case '1':case '2':case '3':case '4': | 940 | case '0':case '1':case '2':case '3':case '4': |
| 943 | case '5':case '6':case '7':case '8':case '9': | 941 | case '5':case '6':case '7':case '8':case '9': |
| 944 | { | 942 | { |
| 945 | int index=*(prog->argv[argc_l - 1] + 1)-48; | 943 | int index=*(dst + 1)-48; |
| 946 | if (index >= argc) { | 944 | if (index >= argc) { |
| 947 | *(prog->argv[argc_l - 1])='\0'; | 945 | var='\0'; |
| 948 | } else { | 946 | } else { |
| 949 | prog->argv[argc_l - 1] = argv[index]; | 947 | var = argv[index]; |
| 950 | } | 948 | } |
| 951 | } | 949 | } |
| 952 | break; | 950 | break; |
| 953 | } | 951 | } |
| 954 | } | 952 | } |
| 955 | #endif | 953 | if (var) { |
| 954 | int offset = dst-src; | ||
| 955 | #warning I have a memory leak which needs to be plugged somehow | ||
| 956 | src = (char*)xmalloc(strlen(src)-strlen(dst)+strlen(var)+1); | ||
| 957 | strncpy(src, prog->argv[argc_l -1], offset); | ||
| 958 | safe_strncpy(src+offset, var, strlen(var)+1); | ||
| 959 | /* If there are any remaining $ variables in the src string, put them back */ | ||
| 960 | if ((dst = strchr(prog->argv[argc_l -1]+offset+1,'$')) != NULL) { | ||
| 961 | offset=strlen(src); | ||
| 962 | safe_strncpy(src+strlen(src), dst, strlen(dst)+1); | ||
| 963 | } | ||
| 964 | prog->argv[argc_l -1] = src; | ||
| 965 | } else { | ||
| 966 | memset(dst, 0, strlen(src)-strlen(dst)); | ||
| 967 | } | ||
| 956 | } | 968 | } |
| 969 | #endif | ||
| 957 | 970 | ||
| 958 | if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){ | 971 | if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){ |
| 959 | rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result); | 972 | rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result); |
