// 支持外部命令
#include "myshell.h"
int back_bat=0; // 标志既是后台运行,又是批处理;值为1有效。
int output_num=0; // 批处理的输出重定向个数
char batchfile[MAX_PATH] ; // 当前的批处理文件
int bat_line=0;// 批处理的命令行数
int isbat=0;// 批处理标志
int letter; // used in my_strtok( ) Error( )
char *open; // used in my_strtok( ) Error( )
/* ******************************* 辅助函数 ******************************* */
/* Function "my_strtok" : used to <1> token the input command line(stored in buf[]) into args[],
<2> record background execute,argc,etc in states[]
<3> record the indirection files and outdirection filesget */
int my_strtok(char *buf,char **args,int *states,Redirect *Inputs,Redirect *Outputs) // InPut和OutPuts记录重定向
{
int i,j,n,m, flag,argc,errortype; // flag是空白标记;argc是参数个数(不包括重定向和后台运行)
char c ;
states[0]=states[1]=states[2]=states[3]=states[4]=0;// states[0]是后台运行标志;states[1]是输入重定向个数;states[2]是输出重定向个数;
//states[3]是参数个数; states[4]标记输入重定向在键盘输入之前;
errortype=letter=argc=0;
args[0]=NULL;
open=NULL;// open 是打开方式;
flag=1;
i=m=n=-1;
while(buf[++i]&&buf[i]!='#') //扫描命令行, 容许用户把 '#' 用于注释
{
c=buf[i];
switch(c) // 字符解析
{
case '<': letter++;
if(flag==0)
{
flag=1;
buf[i]='\0';
}
open="<"; // "r" opentype
while(buf[++i]==' '|| buf[i]=='\t'); // // 跳过多个连续的空格
if(buf[i]<32|| buf[i]=='#' ) // invlid argument '<', without inputfile!
{
errortype=Error(1,NULL,NULL,NULL,"<");// invlid argument '<', without inputfile!
break;
}
else if(buf[i]=='&'|| buf[i]=='<'|| buf[i]=='>'|| buf[i]=='|'|| buf[i]==';') // can not be <& <; << <> <|
{
letter++;
errortype=Error(2,NULL,NULL,NULL,buf+i);
break;
}
if(argc<2)
states[4]=1;
m++;
i--;
break;
case '>': letter++;
if(flag==0)
{ flag=1;
buf[i]='\0';
}
n++;
if(buf[i+1]=='>')
{ buf[++i]='\0';
//n++;
open=">>"; // "a" opentype
}
else {
// n++;
open=">"; // "w" opentype
}
while(buf[++i]==' '|| buf[i]=='\t'); // 跳过多个连续的空格
if(buf[i]<32|| buf[i]=='#' )
{
errortype=Error(1,NULL,NULL,NULL,NULL);
break;
}
else if(buf[i]=='&'|| buf[i]=='<'|| buf[i]=='>'|| buf[i]=='|' || buf[i]==';') // can not be >& <; >< <|
{
letter++;
errortype=Error(2,NULL,NULL,NULL,buf+i);
break;
}
i--;
break;
case '&': letter++;
if(flag==0)
{ flag=1;
buf[i]='\0';
}
if(states[0])
{
errortype= Error(0,NULL,NULL,NULL,"Format Error: argument '&' occurs more than once!");
break;
}
states[0]=1;
break;
case ' ':
case '\t': if(flag==0)
{
flag=1;
buf[i]='\0';
}
while(buf[++i]==' '|| buf[i]=='\t'); // 跳过多个连续的空格
i--;
break;
case '\n':
case '\r': buf[i]='\0';
i--;
break;
default: letter++;
if(flag)
{ flag=0;
if(open&&m<=MAX_OPEN&&n<=MAX_OPEN)
{
if(m==MAX_OPEN)// too many input redirections ////////
errortype=Error(5,NULL,NULL,NULL,"input");
else if(n==MAX_OPEN)// too many output redirections ////////
errortype=Error(5,NULL,NULL,NULL,"output");
else if( !strcmp(open,"<" ) )
Inputs[m].filename=buf+i;
else if( !strcmp(open,">>" ) )
{
strcpy(Outputs[n].opentype,"a");
strcpy(Outputs[n].open,">>");
Outputs[n].filename=buf+i;
}
else if( !strcmp(open,">" ) )
{
strcpy(Outputs[n].opentype,"w");
strcpy(Outputs[n].open,">");
Outputs[n].filename=buf+i;
}
open=NULL;
}
else args[argc++]=buf+i;
}
if(c=='\\' &&buf[i+1]==' ') // 转义字符 e.g. "a\ b" means "a b" in filename or directoryname
{ buf[i]=' ';
if( ! isspace(buf[i+2]))
{
j=i+1;
while( buf[++j]) buf[j-1]=buf[j];
}
}
} // end switch
} // end for loop
- 1
- 2
- 3
- 4
- 5
前往页