home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 21
/
CD_ASCQ_21_040595.iso
/
dos
/
prg
/
c
/
freedos3
/
source
/
com020
/
command.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-15
|
7KB
|
316 lines
/* 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 */
}