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 /sh.c | |
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 'sh.c')
-rw-r--r-- | sh.c | 47 |
1 files changed, 30 insertions, 17 deletions
@@ -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); |