+/* built-in 'read VAR' handler */
+static int builtin_read(struct job *cmd, struct jobSet *junk)
+{
+ int res = 0, len, newlen;
+ char *s;
+ char string[MAX_READ];
+
+ if (cmd->progs[0].argv[1]) {
+ /* argument (VAR) given: put "VAR=" into buffer */
+ strcpy(string, cmd->progs[0].argv[1]);
+ len = strlen(string);
+ string[len++] = '=';
+ string[len] = '\0';
+ fgets(&string[len], sizeof(string) - len, stdin); /* read string */
+ newlen = strlen(string);
+ if(newlen > len)
+ string[--newlen] = '\0'; /* chomp trailing newline */
+ /*
+ ** string should now contain "VAR=<value>"
+ ** copy it (putenv() won't do that, so we must make sure
+ ** the string resides in a static buffer!)
+ */
+ res = -1;
+ if((s = strdup(string)))
+ res = putenv(s);
+ if (res)
+ fprintf(stdout, "read: %s\n", strerror(errno));
+ }
+ else
+ fgets(string, sizeof(string), stdin);
+
+ return (res);
+}
+
+#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
+/* Built-in handler for 'if' commands */
+static int builtin_if(struct job *cmd, struct jobSet *jobList)
+{
+ int status;
+ char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
+
+ /* Now run the 'if' command */
+ status=strlen(charptr1);
+ local_pending_command = xmalloc(status+1);
+ strncpy(local_pending_command, charptr1, status);
+ local_pending_command[status]='\0';
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "'if' now testing '%s'\n", local_pending_command);
+#endif
+ status = busy_loop(NULL); /* Frees local_pending_command */
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "if test returned ");
+#endif
+ if (status == 0) {
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "TRUE\n");
+#endif
+ cmd->jobContext |= IF_TRUE_CONTEXT;
+ } else {
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "FALSE\n");
+#endif
+ cmd->jobContext |= IF_FALSE_CONTEXT;
+ }
+
+ return status;
+}
+
+/* Built-in handler for 'then' (part of the 'if' command) */
+static int builtin_then(struct job *cmd, struct jobSet *junk)
+{
+ int status;
+ char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
+
+ if (! (cmd->jobContext & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
+ errorMsg("unexpected token `then'\n");
+ return FALSE;
+ }
+ /* If the if result was FALSE, skip the 'then' stuff */
+ if (cmd->jobContext & IF_FALSE_CONTEXT) {
+ return TRUE;
+ }
+
+ cmd->jobContext |= THEN_EXP_CONTEXT;
+ //printf("Hit an then -- jobContext=%d\n", cmd->jobContext);
+
+ /* Now run the 'then' command */
+ status=strlen(charptr1);
+ local_pending_command = xmalloc(status+1);
+ strncpy(local_pending_command, charptr1, status);
+ local_pending_command[status]='\0';
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "'then' now running '%s'\n", charptr1);
+#endif
+ return( busy_loop(NULL));
+}
+
+/* Built-in handler for 'else' (part of the 'if' command) */
+static int builtin_else(struct job *cmd, struct jobSet *junk)
+{
+ int status;
+ char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
+
+ if (! (cmd->jobContext & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
+ errorMsg("unexpected token `else'\n");
+ return FALSE;
+ }
+ /* If the if result was TRUE, skip the 'else' stuff */
+ if (cmd->jobContext & IF_TRUE_CONTEXT) {
+ return TRUE;
+ }
+
+ cmd->jobContext |= ELSE_EXP_CONTEXT;
+ //printf("Hit an else -- jobContext=%d\n", cmd->jobContext);
+
+ /* Now run the 'else' command */
+ status=strlen(charptr1);
+ local_pending_command = xmalloc(status+1);
+ strncpy(local_pending_command, charptr1, status);
+ local_pending_command[status]='\0';
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "'else' now running '%s'\n", charptr1);
+#endif
+ return( busy_loop(NULL));
+}
+
+/* Built-in handler for 'fi' (part of the 'if' command) */
+static int builtin_fi(struct job *cmd, struct jobSet *junk)
+{
+ if (! (cmd->jobContext & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
+ errorMsg("unexpected token `fi'\n");
+ return FALSE;
+ }
+ /* Clear out the if and then context bits */
+ cmd->jobContext &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
+#ifdef DEBUG_SHELL
+ fprintf(stderr, "Hit an fi -- jobContext=%d\n", cmd->jobContext);
+#endif
+ return TRUE;
+}
+#endif
+