#ifndef AMIGA # include #endif #ifdef MSDOS # include #endif #include #include #include "make.h" #ifndef FALSE # define FALSE (0) #endif #ifndef TRUE # define TRUE (1) #endif #define BUFFSIZ (256) #ifdef MSDOS extern char *searchpath (); #endif extern char *getenv (); #ifdef MSDOS extern int _envseg; #ifndef NOREALEXECUTE static char param[256]; static char cmd[256]; static char *cmds[] = { "break", "chdir", "cd", "cls", "copy", "ctty", "date", "del", "erase", "dir", "echo", "exit", "for", "goto", "if", "mkdir", "md", "path", "pause", "prompt", "rem", "ren", "rename", "rmdir", "rd", "set", "shift", "time", "type", "ver", "verify", "vol", 0 }; #endif /* !NOREALEXECUTE */ #endif /* MSDOS */ execute (str, noexecflag) char *str; int noexecflag; { auto char tmp[BUFFSIZ]; auto char buf[10]; register int index = 0; register int rval; extern int ignore_errors; DBUG_ENTER ("execute"); tmp[0] = EOS; while (*str != EOS) { if (*str == '\n') { tmp[index] = EOS; index = 0; str++; if ((rval = run (tmp, noexecflag)) != 0 && !ignore_errors) { fputs ("***Error Code ", stderr); itoa (rval, buf); fputs (buf, stderr); fputc ('\n', stderr); DBUG_RETURN (rval); } } else if (index == (BUFFSIZ - 1)) { fputs ("Command Too Long: ", stderr); fputs (str, stderr); fputs ("\nShorten.\n", stderr); DBUG_RETURN (-1); } else { tmp[index++] = *str++; } } DBUG_RETURN (0); } #ifdef TESTING main () { auto char temp[128]; for (;;) { printf ("Command: "); gets (temp); if (temp[0] == EOS) { break; } printf (" Execute: %d\n", run (temp)); } } #endif /* run(str) * char *str; * returns the value of the executed command. If the command is * an MS-DOS resident command the command.com is executed else * the program is invoked (looking down the PATH). * * Written: Bradley N. Davis University of Utah VCIS group * Date: 4-Jan-84 * */ static int run (str, noexecflag) char *str; int noexecflag; { #ifdef MSDOS auto struct execp ep; auto struct SREGS segs; #else extern int system (); #endif auto int status = 0; DBUG_ENTER ("run"); while (*str == '\t' || *str == ' ') { str++; } putchar ('\t'); puts (str); fflush (stdout); if (!noexecflag) { #ifndef NOREALEXECUTE #ifdef MSDOS if (str[0] == EOS) { /* Blank Line? push to subshell */ strcpy (cmd, getenv ("COMSPEC")); param[0] = EOS; segread (&segs); ep.ex_envseg = _envseg; ep.ex_cmdadd = (unsigned) param; ep.ex_cmdseg = segs.ss; ep.ex_fcb1ad = 0; ep.ex_fcb1sg = 0; ep.ex_fcb2ad = 0; ep.ex_fcb2sg = 0; status = (exec (cmd, 0, &ep)); } else if (resident (str)) { status = (system (str)); } else { status = (program (cmd, param)); } #else CHECK_ABORT; status = system (str); #endif /* MSDOS */ #endif /* !NOREALEXECUTE */ } DBUG_3 ("sys", "subcommand returns status %d", status); DBUG_RETURN (status); } /* * resident(str) * char *str; * returns true if the command in str is an MS-DOS resident * command. * * Written: Bradley N. Davis University of Utah VCIS group * Date: 4-Jan-84 * */ #define iswhite(ch) (ch == ' ' || ch == '\t') #ifdef MSDOS #ifndef NOREALEXECUTE static int resident (str) char *str; { register char **t; extern char *strpbrk (); register int i; register int j; DBUG_ENTER ("resident"); while (iswhite (*str)) { str++; /* trim blanks */ } if (str[1] == ':' && isalpha (str[0])) { /* look for x: */ DBUG_RETURN (TRUE); } if (strpbrk (str, "<>|") != NULL) { /* redirection? use system */ DBUG_RETURN (TRUE); } i = 0; while (isalnum (*str)) { if (isupper (*str)) { cmd[i++] = *str++ - 'A' + 'a'; } else { cmd[i++] = *str++; } } cmd[i] = EOS; for (t = cmds; *t; t++) { if (strcmp (*t, cmd) == 0) { DBUG_RETURN (TRUE); } } strcat (cmd, ".bat"); /* Batch file? use system */ if (searchpath (cmd) != 0) { cmd[i] = EOS; DBUG_RETURN (TRUE); } cmd[i] = EOS; j = strlen (str); i = 1; while ((param[i++] = *str++) != 0); param[0] = j; param[j + 1] = '\r'; DBUG_RETURN (FALSE); } static int program (pcmd, pparam) char *pcmd; char *pparam; { #ifdef MSDOS auto struct execp ep; auto struct SREGS segs; register char *pathp; register int len; DBUG_ENTER ("program"); len = strlen (pcmd); strcat (pcmd, ".com"); pathp = searchpath (pcmd); if (pathp == 0) { pcmd[len] = EOS; strcat (pcmd, ".exe"); pathp = searchpath (pcmd); if (pathp == 0) { pcmd[len] = EOS; errno = ENOENT; DBUG_RETURN (-1); } } segread (&segs); ep.ex_envseg = _envseg; ep.ex_cmdadd = (unsigned) pparam; ep.ex_cmdseg = segs.ss; ep.ex_fcb1ad = 0; ep.ex_fcb1sg = 0; ep.ex_fcb2ad = 0; ep.ex_fcb2sg = 0; DBUG_RETURN (exec (pathp, 0, &ep)); #else fprintf (stderr, "Urk -- 'program()' unimplemented!\n"); DBUG_RETURN (0); #endif } #endif /* !NOREALEXECUTE */ #endif /* MSDOS */ #ifdef AMIGA /* * Do explicit check for abort. When Enable_Abort is non-zero, * Chk_Abort() cause program termination if CNTRL-C or CNTRL-D has * been received. Thus, we temporarily set it back to zero while we * do the explicit test, so we can do our own clean up and exit. * Note that if the -V flag was used, we spit out a confirming message * that we are quitting. * */ void Check_Abort () { DBUG_ENTER ("Check_Abort"); DBUG_2 ("abort", "do explicit test for CNTRL-C"); DISABLE_ABORT; if (Chk_Abort () != 0) { exit (1); } ENABLE_ABORT; DBUG_VOID_RETURN; } #endif /* AMIGA */