home *** CD-ROM | disk | FTP | other *** search
- /* COMMAND.C
- * command-line interface
- * Tim Norman
- * Started: 8-17-94
- * v 0.02
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <dos.h>
- #include <process.h>
- #include <time.h>
- #include <errno.h>
- #include <dir.h>
-
- long history_size = 256; /* make this configurable later */
-
- #include "history.h"
- #include "cmdinput.h"
-
- #define ENV_SIZE 256
- #define MAX_ENV_VARS 32
-
- /* The first unused pointer in env_vars points to the next empty spot */
- /* That is: env_vars[num_environment_variables] ==
- env_vars[num_environment_variables - 1] +
- strlen (env_vars[num_environment_variables - 1]) + 1
- */
-
- char *environment;
- char **env_vars;
- int num_environment_variables = 0;
- char env_temp[128];
-
- #include "internal.h" /* internal functions */
-
- char exitflag = 0; /* indicates EXIT was typed */
- char canexit = 1; /* exitable shell? */
-
- void fatal_error (char *s)
- {
- puts (s);
- exit (100);
- }
-
- #include "prompt.h"
-
- /* is character a delimeter when used on first word? */
- char is_delim (char c)
- {
- return (c == '/' || c == '=');
- }
-
- /* strip the extra spaces between parameters on command-line. quotation */
- /* mark aware */
- int strip (char *command)
- {
- char temp[128] = "", foundspace = 0;
- unsigned char place = 0, tempplace = 0, firstword = 1, inquote = 0;
-
- while (isspace (command[place]))
- place++;
-
- while (command[place])
- {
- if (foundspace && !isspace (command[place]))
- {
- temp[tempplace++] = ' ';
- foundspace = 0;
- }
-
- if (isspace (command[place]) && !inquote)
- {
- foundspace = 1;
- firstword = 0;
- }
- else if (is_delim (command[place]) && firstword)
- {
- temp[tempplace++] = ' ';
- temp[tempplace++] = command[place];
- }
- else if (command[place] == '"')
- {
- if (!inquote && place > 0 && !isspace (command[place - 1]))
- temp[tempplace++] = ' ';
-
- temp[tempplace++] = '"';
-
- inquote = !inquote;
-
- if (!inquote && !isspace (command[place + 1]))
- temp[tempplace++] = ' ';
- }
- else
- temp[tempplace++] = command[place];
-
- place++;
- }
-
- temp[tempplace] = 0;
- strcpy (command, temp);
-
- if (inquote)
- return 0;
- else
- return 1; /* true on success */
- }
-
- /* split the command-line into parameters. Works with quotation marks */
- unsigned char split (char *command, char *p[128])
- {
- unsigned char count, place = 1, len, inquote = 0;
-
- p[0] = command;
-
- len = strlen (command);
-
- for (count = 0; count < len; count++)
- if (command[count] == '"')
- inquote = !inquote;
- else if (command[count] == ' ' && !inquote)
- {
- command[count] = 0;
- p[place++] = &command[count + 1];
- }
-
- p[place] = NULL;
-
- return place;
- }
-
- /* returns TRUE if the char is a delimiter char (i.e. can't be in a filename) */
- char is_special (char ch)
- {
- return (ch == '<' || ch == '>' || ch == '=' || ch == ',' || ch == ';' ||
- ch == ':' || ch == '*' || ch == '?' || ch == '[' || ch == ']' ||
- ch == '/' || ch == '\\'|| ch == '+' || ch == '"' || ch <= ' ');
- }
-
- /* splits up command-line and figures out what to call */
- void parsecommandline (char *command)
- {
- char *p[128]; /* array of char pointers for splitting up command */
- unsigned char args; /* number of words on command line */
- char origcommand[1024], tempcommand[1024];
-
- strcpy (origcommand, command);
-
- /* get rid of places with more than one space & beginning and ending space */
- if (!strip (command))
- {
- puts ("Syntax error."); /* unmatched quote */
- return;
- }
-
- /* replace spaces with null's and place in p */
- args = split (command, p);
-
- /* parse first word for known commands */
- if (p[0][0] && p[0][1] == ':' && p[0][2] == 0) /* change drives */
- {
- if (isalpha (p[0][0]))
- setdisk (toupper (p[0][0]) - 'A');
-
- if (getdisk () != toupper (p[0][0]) - 'A')
- puts ("Invalid drive specification");
- }
- else if (strcmpi (p[0], "SET") == 0) /* List */
- {
- if (p[1])
- SET (origcommand);
- else
- show_environment ();
- }
- else if (strcmpi (p[0], "PROMPT") == 0)
- {
- char *from, *to;
-
- from = origcommand;
- to = tempcommand + 11;
-
- strcpy (tempcommand, "SET PROMPT=");
-
- while (isspace (*from))
- from++;
-
- from += 6;
-
- while (isspace (*from))
- from++;
-
- if (*from == '=')
- {
- from++;
-
- while (isspace (*from))
- from++;
- }
-
- strcpy (to, from);
-
- SET (tempcommand);
- }
- else if (strcmpi (p[0], "EXIT") == 0)
- exitflag = 1;
- else if (strncmpi (p[0], "CD", 2) == 0 &&
- (p[0][2] == 0 || p[0][2] == '\\' || p[0][2] == '.'))
- CD (origcommand, p, args);
- else if (strcmpi (p[0], "DOSKEY") == 0)
- {
- puts ("DOSKEY features are already available to the DOS shell.");
- puts ("To create an alias, use the ALIAS command.");
- }
- else if (strcmpi (p[0], "REM") == 0)
- ; /* don't do anything */
- else if (!p[0][0]) /* nothing typed */
- ;
- else
- {
- int count;
- char *temp;
-
- /*
- printf ("p[0]=%s\n", p[0]);
- for (count = 0; p[count]; count++)
- printf ("%d: %s\n", count, p[count]);
- getch ();
- */
-
- temp = env_vars[num_environment_variables];
- env_vars[num_environment_variables] = NULL;
-
- if (spawnvpe (P_WAIT, p[0], p, env_vars) == -1)
- {
- /* call internal DIR if external one not found or error */
- if (strcmpi (p[0], "DIR") == 0)
- DIR (&p[1], args - 1);
- else switch (errno)
- {
- case E2BIG:
- puts ("Command line too long.");
- break;
-
- case EINVAL:
- puts ("Invalid argument.");
- break;
-
- case ENOENT:
- puts ("Bad command or filename.");
- break;
-
- case ENOEXEC:
- puts ("Exec format error.");
- break;
-
- case ENOMEM:
- puts ("Insufficient memory.");
- break;
-
- default:
- printf ("Unknown error %d. Contact the author!\n", errno);
- }
- }
-
- env_vars[num_environment_variables] = temp;
- }
- }
-
- int process_input ()
- {
- char commandline[1024];
-
- do
- {
- puts ("");
- printprompt ();
- readcommand (commandline, 128);
- parsecommandline (commandline);
- }
- while (!canexit || !exitflag);
-
- return 0;
- }
-
- int c_brk (void) /* ctrl-break handler */
- {
- return 1; /* continue execution */
- }
-
- void initialize (int argc, char *argv[], char *env[])
- {
- ctrlbrk (c_brk);
-
- puts ("FreeDOS Alpha COMMAND.COM\n");
-
- environment = malloc (ENV_SIZE);
-
- /* allocate space for environment variable pointers into environment */
- env_vars = malloc (MAX_ENV_VARS * sizeof (char *));
- env_vars[0] = environment;
-
- /* make it inherit the environment if run from another process */
- /* not implemented */
- }
-
- int main (int argc, char *argv[], char *env[])
- {
- /* check switches on command-line */
-
- initialize (argc, argv, env);
-
- return process_input (); /* call prompt routine */
- }
-