?? if.c
字號:
/*
* if exprression cmd [arg]....
* if 是 test 命令的前身。在測試完表達式之后,如果為真則執行后面的命令。
* 這里的 if 命令建立在 v7 test 命令基礎上。
*/
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#define EQ(a,b) ((tmp=a)==0?0:(strcmp(tmp,b)==0))
int ac;
char **av;
int ap;
char *tmp;
#define DIR 1
#define FIL 2
char *nxtarg(int mt);
int expr(void);
int e1(void);
int e2(void);
int e3(void);
int tio(char *a, int f);
int ftype(char *f);
int fsizep(char *f);
void synbad(char *s1, char *s2);
int length(char *s);
int doex(char *earg);
int main(int argc, char**argv)
{
ac = argc;
av = argv;
ap = 1;
argv[ac] = 0;
if (ac<=1)
return 1;
if (expr())
return doex(0);
else
return 1;
}
/*
* 獲得下一個參數。mt 指示在讀到列表尾部的時候是否為語法錯誤,
* 1 返回空指針,0 提示錯誤并退出。
*/
char *nxtarg(int mt)
{
if (ap>=ac) {
if(mt) {
ap++;
return(0);
}
synbad("argument exprected","");
}
return(av[ap++]);
}
/*
* expr ::= * e1 -o expr | expr
*/
int expr(void)
{
int p1;
p1 = e1();
if (EQ(nxtarg(1), "-o"))
return(p1 | expr());
ap--;
return(p1);
}
/*
* e1 ::= e2 -a e1 | e1
*/
int e1(void)
{
int p1;
p1 = e2();
if (EQ(nxtarg(1), "-a"))
return (p1 & e1());
ap--;
return(p1);
}
/*
* e2 ::= e3 | ! e3
*/
int e2(void)
{
if (EQ(nxtarg(0), "!"))
return(!e3());
ap--;
return(e3());
}
/*
* e3 ::= ( expr ) | { command ... } | -op file | string -op string
*/
int e3(void)
{
int p1,r;
register char *a;
char *p2;
int int1, int2;
int ccode;
a=nxtarg(0);
if(EQ(a, "(")) {
p1 = expr();
if(!EQ(nxtarg(0), ")"))
synbad(") exprected","");
return(p1);
}
if(EQ(a, "{")) { /* 執行一個命令并等待退出狀態 */
if(fork()) /* 父進程執行部分 */
wait(&ccode);
else { /* 子進程執行部分 */
if ((r=doex("}")) != 0)
if (r == 1)
synbad("} exprected","");
else
exit(r);
else
exit(0);
}
while((a=nxtarg(0)) && (!EQ(a,"}")));
return(ccode? 0 : 1);
}
if(EQ(a, "-r"))
return(tio(nxtarg(0), 0));
if(EQ(a, "-w"))
return(tio(nxtarg(0), 1));
if(EQ(a, "-d"))
return(ftype(nxtarg(0))==DIR);
if(EQ(a, "-f"))
return(ftype(nxtarg(0))==FIL);
if(EQ(a, "-s"))
return(fsizep(nxtarg(0)));
if(EQ(a, "-t")) {
if(ap>=ac)
return(isatty(1));
else
return(isatty(atoi(nxtarg(0))));
}
if(EQ(a, "-n"))
return(!EQ(nxtarg(0), ""));
if(EQ(a, "-z"))
return(EQ(nxtarg(0), ""));
p2 = nxtarg(1);
if (p2==0)
return(!EQ(a,""));
if(EQ(p2, "="))
return(EQ(nxtarg(0), a));
if(EQ(p2, "!="))
return(!EQ(nxtarg(0), a));
if(EQ(a, "-l")) {
int1=length(p2);
p2=nxtarg(0);
} else{ int1=atoi(a);
}
int2 = atoi(nxtarg(0));
if(EQ(p2, "-eq"))
return(int1==int2);
if(EQ(p2, "-ne"))
return(int1!=int2);
if(EQ(p2, "-gt"))
return(int1>int2);
if(EQ(p2, "-lt"))
return(int1<int2);
if(EQ(p2, "-ge"))
return(int1>=int2);
if(EQ(p2, "-le"))
return(int1<=int2);
synbad("unknown operator ",p2);
return 0;
}
/*
* 文件訪問測試
*/
int tio(char *a, int f)
{
f = open(a, f);
if (f>=0) {
close(f);
return(1);
}
return(0);
}
/*
* 文件類型測試
*/
int ftype(char *f)
{
struct stat statb;
if(stat(f,&statb)<0)
return(0);
if((statb.st_mode&S_IFMT)==S_IFDIR)
return(DIR);
return(FIL);
}
/*
* 文件大小測試
*/
int fsizep(char *f)
{
struct stat statb;
if(stat(f,&statb)<0)
return(0);
return(statb.st_size>0);
}
/*
* 打印錯誤信息并退出
*/
void synbad(char *s1, char *s2)
{
write(2, "if: ", 6);
write(2, s1, strlen(s1));
write(2, s2, strlen(s2));
write(2, "\n", 1);
exit(1);
}
/*
* 字符串長度測試
*/
int length(char *s)
{
char *es=s;
while(*es++);
return((int)(es-s-1));
}
/*
* 執行命令
* earg 是終止參數
*/
int doex(char *earg)
{
static char ncom[]="/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char *p=av[ap];
char **v=av+ap;
int i=0;
char c;
if (p == 0)
return 0;
if (earg != 0) {
while (*v != 0 && !EQ(*v,earg))
v++;
if (*v == 0)
return 1;
else
*v=0;
}
execv(p, av+ap);
while((c=p[i])) {
ncom[9+i++] = c;
}
ncom[9+i] = '\0';
execv(ncom+4, av+ap);
execv(ncom, av+ap);
return 127;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -