- else {
- switch(*(prog->argv[argc_l - 1] + 1)) {
- case '?':
- prog->argv[argc_l - 1] = itoa(lastReturnCode);
- break;
- case '$':
- prog->argv[argc_l - 1] = itoa(getpid());
- break;
- case '#':
- prog->argv[argc_l - 1] = itoa(argc-1);
- break;
- case '!':
- if (lastBgPid==-1)
- *(prog->argv[argc_l - 1])='\0';
- else
- prog->argv[argc_l - 1] = itoa(lastBgPid);
- break;
- case '0':case '1':case '2':case '3':case '4':
- case '5':case '6':case '7':case '8':case '9':
- {
- int index=*(prog->argv[argc_l - 1] + 1)-48;
- if (index >= argc) {
- *(prog->argv[argc_l - 1])='\0';
- } else {
- prog->argv[argc_l - 1] = argv[index];
- }
+
+
+#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);
+ if (retval == WRDE_NOSPACE) {
+ /* Mem may have been allocated... */
+ wordfree (&expand_result);
+ error_msg(out_of_space);
+ return FALSE;
+ }
+ if (retval < 0) {
+ /* Some other error. */
+ error_msg("syntax error");
+ return FALSE;
+ }
+
+ if (expand_result.we_wordc > 0) {
+ /* Convert from char** (one word per string) to a simple char*,
+ * but don't overflow command which is BUFSIZ in length */
+ *command = '\0';
+ while (i < expand_result.we_wordc && total_length < BUFSIZ) {
+ length=strlen(expand_result.we_wordv[i])+1;
+ if (BUFSIZ-total_length-length <= 0) {
+ error_msg(out_of_space);
+ return FALSE;
+ }
+ strcat(command+total_length, expand_result.we_wordv[i++]);
+ strcat(command+total_length, " ");
+ total_length+=length;
+ }
+ wordfree (&expand_result);
+ }
+#else
+
+ /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
+ * are about 100% they don't have wordexp(). So instead the best we can do
+ * is use glob and then fixup environment variables and such ourselves.
+ * This is better then nothing, but certainly not perfect */
+
+ /* It turns out that glob is very stupid. We have to feed it one word at a
+ * time since it can't cope with a full string. Here we convert command
+ * (char*) into cmd (char**, one word per string) */
+ {
+
+ 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) */
+ cmd = cmd_copy = strdup(command);
+ *command = '\0';
+ for (index = 0, tmpcmd = cmd;
+ (tmpcmd = strsep_space(cmd, &index)) != NULL; cmd += index, index=0) {
+ if (*tmpcmd == '\0')
+ break;
+ retval = glob(tmpcmd, flags, NULL, &expand_result);
+ free(tmpcmd); /* Free mem allocated by strsep_space */
+ if (retval == GLOB_NOSPACE) {
+ /* Mem may have been allocated... */
+ globfree (&expand_result);
+ error_msg(out_of_space);
+ return FALSE;
+ } else if (retval != 0) {
+ /* Some other error. GLOB_NOMATCH shouldn't
+ * happen because of the GLOB_NOCHECK flag in
+ * the glob call. */
+ error_msg("syntax error");
+ return FALSE;
+ } else {
+ /* 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]);
+ if (total_length+length+1 >= BUFSIZ) {
+ error_msg(out_of_space);
+ return FALSE;