自己写的一个linux 远程控制工具

学习linux有些时日了,这个就是我的一第一真正的作品,发表一下作品,
希望其中的一些技巧对朋友们有所帮助,也希望达人指正一下其中的不足。

主要应用知识:
linux的网络通信
文件的属性及操作
多进程的应用
进程的回收
信号的应用

下面是客户端
文件的意义:
command.c 命令模块 ,common.h 公共声明, input.c 分割命令, main.c 主程序 ,
Makefile make工具用的,ssjio.c ssjio.h 是我自己的模块

main.c

#include "common.h"

int main(void)
{
char cline[COMMAND_LINE]="123";
struct command_line command;
int sock_fd;
struct sockaddr_in sin;

printf("ssj-soft$: ");
fflush(stdout);

while(fgets(cline,COMMAND_LINE,stdin)!=NULL)
{ //printf("%x,%x,%x,%xn",cline[0],cline[1],cline[2],cline[3]);fflush(stdout);
if(cline[0]==0xa){cline[1]=0xa;cline[2]='';}
if(split(&command,cline)==-1)
exit(1);

if(strcasecmp(command.name,"get")==0){
if(do_get(command.argv[1],command.argv[2],sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"put")==0){
if(do_put(command.argv[1],command.argv[2],sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"cd")==0){
if(do_cd(command.argv[1])==-1)
exit(1);
}else if(strcasecmp(command.name,"!cd")==0){
if(do_serv_cd(command.argv[1],sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"ls")==0){
if(do_ls(command.argv[1])==-1)
exit(1);
}else if(strcasecmp(command.name,"!ls")==0){
if(do_serv_ls(command.argv[1],sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"connect")==0){
if(do_connect(command.argv[1],&sin,&sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"RUN")==0){
if(do_serv_command(command.argv[1],sock_fd)==-1)
exit(1);
}else if(strcasecmp(command.name,"bye")==0){
if(do_bye(sock_fd)==-1)
exit(1);
break;
}else{
printf("wrong commandn");
printf("usage:connect <ip>n");
printf(" run <command>n");
printf(" cd <path>n");
printf(" !cd <path>n");
printf(" get <srcpathfile> <dstpath>n");
printf(" put <srcpathfile> <dstpath>n");
printf(" ls <path>n");
printf(" !ls <path>n");
printf(" byen");
}
printf("ssj-soft$: ");
fflush(stdout);
}
if(close(sock_fd)==-1)
{perror("Fail to close");exit(1);}

return 0;
}

command.c

#include "common.h"

//================connect==================
int do_connect(char *ip,struct sockaddr_in *sin,int *sock_fd)
{
int sfd;

bzero(sin,sizeof(struct sockaddr_in));
sin->sin_family=AF_INET;
if(inet_pton(AF_INET,ip,&sin->sin_addr)==-1)
{perror("wrong format of ip address");return -1;}

sin->sin_port=htons(PORT);
if((sfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{perror("fail to create socket");return -1;}

if(connect(sfd,(struct sockaddr *)sin,sizeof(struct sockaddr_in))==-1)
{perror("Fail to connetc");return -1;}

*sock_fd=sfd;
return 0;
}

//=====================get_file=======================
int do_get(const char *src,const char *dst,int sock_fd)
{
char *dst_file,*p,buf[MAX_LINE];
struct stat statbuf;
int n,fd,len,res=-1;

if(src==NULL || dst==NULL)
{printf("wrong commandn");return -1;}

if (src[strlen(src)-1]=='/')
{printf("source file should be a regular filen");return -1;}

if((dst_file=(char *)malloc(strlen(dst)+strlen(src)))==NULL)
{perror("Fail to malloc");return -1;}

strcpy(dst_file,dst);

if(dst_file[strlen(dst_file)-1]!='/')
strcat(dst_file,"/");
p=rindex(src,'/');
strcat(dst_file,p+1);

if((fd=open(dst_file,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{perror("Fail to open dst_file");goto end2;}

if(fstat(fd,&statbuf)==-1)
{perror("Fail to stat dst_file");goto end1;}

if(!S_ISREG(statbuf.st_mode))
{printf("dst_file should be a regular file");goto end1;}

sprintf(buf,"GET %s",src);

if(my_write(sock_fd,buf,strlen(buf)+1)==-1)
goto end1;

if((n=my_read(sock_fd,buf,MAX_LINE))<=0)
goto end1;

if(buf[0]=='E')
{write(STDOUT_FILENO,buf,n);res=0;goto end1;}

len=atoi(&buf[3]);
printf("len atoi:%dn",len);//no
if(my_write(sock_fd,"RDY",4)==-1)
{perror("Fail to write RDY");goto end1;}
printf("while……n");fflush(stdout);
while(1){
if(len!=0)
n=my_read(sock_fd,buf,MAX_LINE);
printf("read up len:%d,n:%d",len,n);fflush(stdout);
if(n>0)
{write(fd,buf,n);printf("len:%d,n:%d",len,n);fflush(stdout);len-=n;n=0;}
else if(len==0)
{printf("OKn");break;}
else
goto end1;
}
res=0;

end1:
close(fd);
end2:
free(dst_file);
return res;
}

//=====================!cd=======================
int do_serv_cd(char *path,int sock_fd)
{
char buf[MAX_LINE];
int n;
sprintf(buf,"CD %s",path);

if(my_write(sock_fd,buf,strlen(buf)+1)==-1)
{return -1;}

if((n=my_read(sock_fd,buf,MAX_LINE))<=0)
{return -1;}

if(buf[0]=='E')
write(STDOUT_FILENO,buf,n);

return 0;
}

//==================!ls=======================
int do_serv_ls(char *path,int sock_fd)
{
char buf[MAX_LINE];
int len,n;

sprintf(buf,"LS %s",path);

if(my_write(sock_fd,buf,strlen(buf)+1)==-1)
return -1;

if((n=my_read(sock_fd,buf,MAX_LINE))<=0)
return -1;

if(buf[0]=='E')
{write(STDOUT_FILENO,buf,n);return 0;}

len=atoi(&buf[3]);

if(my_write(sock_fd,"RDY",4)==-1)
return -1;

while(1)
{
if(len!=0)
n=my_read(sock_fd,buf,MAX_LINE);
if(n>0)
{write(STDOUT_FILENO,buf,n);len-=n;n=0;}
else if(len==0)
{printf("OKn");break;}
else
return -1;
}
return 0;
}

//================bye======================
int do_bye(int sock_fd)
{
if(my_write(sock_fd,"BYE",4)==-1)
return -1;

return 0;
}

//===============put=====================
int do_put(const char *src,const char *dst,int sock_fd)
{
char *dst_file,buf[MAX_LINE],*p;
struct stat statbuf;
int n,fd,res=-1;

if(src==NULL || dst==NULL)
{printf("wrong commandn");return -1;}

if(src[strlen(src)-1]=='/')
{printf("source file should be a regular filen");return -1;}

if((dst_file=malloc(strlen(src)+strlen(dst)+2))==NULL)
{perror("Fail to malloc");return -1;}

strcpy(dst_file,dst);
if(dst_file[strlen(dst_file)-1]!='/')
strcat(dst_file,"/");
p=rindex(src,'/');

strcat(dst_file,p+1);

if((fd=open(src,O_RDONLY))==-1)
{perror("Fail to open src_file");goto end1;}

if(fstat(fd,&statbuf)==-1)
{perror("Fail to stat src_file");goto end2;}
if(!S_ISREG(statbuf.st_mode))
{fputs("src_file should be a regular filen",stderr);goto end2;}

sprintf(buf,"PUT %d %s",statbuf.st_size,dst_file);
if(my_write(sock_fd,buf,strlen(buf)+1)==-1)
{goto end2;}
if((n=my_read(sock_fd,buf,MAX_LINE))<=0)
goto end2;
if(buf[0]=='E')
{write(STDOUT_FILENO,buf,n);goto end2;}

while(1)
{
n=read(fd,buf,MAX_LINE);

if(n>0)
{if(my_write(sock_fd,buf,n)==-1)
goto end2;}
else if(n==0)
{printf("OKn");break;}
else
{perror("Fail to readn");goto end2;}
}
res=0;
end2:
close(fd);
end1:
free(dst_file);
return res;
}

//===================cd=================
int do_cd(char *path)
{
if(chdir(path)==-1)
{perror("Fail to change directoryn");return -1;}

return 0;
}

//===================ls=================
int do_ls(char *path)
{
char cmd[128],buf[NAME_LEN];
FILE *fp;

sprintf(cmd,"ls %s > temp.txt",path);
system(cmd);

fp=fopen("temp.txt","r");
if(fp==NULL)
{perror("Fail to ls");return -1;}

while(fgets(buf,NAME_LEN,fp)!=NULL)
printf("%s",buf);

fclose(fp);
return 0;
}

//================command======================
int do_serv_command(char *path,int sock_fd)
{
char buf[MAX_LINE];
int len,n;

sprintf(buf,"RUN %s",path);

if(my_write(sock_fd,buf,strlen(buf)+1)==-1)
return -1;

if((n=my_read(sock_fd,buf,MAX_LINE))<=0)
return -1;

if(buf[0]=='E')
{write(STDOUT_FILENO,buf,n);return 0;}

len=atoi(&buf[3]);

if(my_write(sock_fd,"RDY",4)==-1)
return -1;

while(1)
{
if(len!=0)
n=my_read(sock_fd,buf,MAX_LINE);
if(n>0)
{write(STDOUT_FILENO,buf,n);len-=n;n=0;}
else if(len==0)
{printf("OKn");break;}
else
return -1;
}
return 0;
}

input.c

#include "common.h"
//去除命令之前的空格等
void del_blank(int *pos,char cline[])
{
while(*(cline+*pos)!=''&&(*(cline+*pos)==' '||*(cline+*pos)=='t'))
{(*pos)++;}
}

//得到参数部分,写入结构体
void get_arg(char arg[],int *pos,char cline[])
{
int i=0;
while(*(cline+*pos)!='' && *(cline+*pos)!=' ' && *(cline+*pos)!='t')
{*(arg+i)=*(cline+*pos);i++;(*pos)++;}
*(arg+i)='';
}

int split(struct command_line *command,char cline[])
{
int i=0,pos=0;
cline[strlen(cline)-1]=''; //fgets得到的字符串中有一个n,把它变成

del_blank(&pos,cline);
i=0;
while(cline[pos]!='')
{
if((command->argv[i]=(char *)malloc(MAX_LENGTH))==NULL)
{perror("Fail malloc");exit(-1);}
get_arg(command->argv[i],&pos,cline);
i++;
del_blank(&pos,cline);
}

if(strncasecmp(command->argv[0],"RUN",3)==0)
{strcpy(command->argv[1],cline+4);
i=2;}
command->argv[i]=NULL;
command->name=command->argv[0];
return i;
}

服务器端:

main.c

#include "common.h"
static void handler(int signo)
{
pid_t pid;
pid = waitpid(-1,NULL, WNOHANG);
printf("process id:%d closedn",pid);
}

int main(void)
{
signal(SIGCHLD,handler); //子程序退出的信号
//signal(SIGINT,handler); //CTRL-C的信号
//signal(SIGTERM,handler);

struct sockaddr_in sin;
struct sockaddr_in cin;
int lfd, cfd;
socklen_t len = sizeof(struct sockaddr_in);
char buf[MAX_LINE];
char str[ADDR_LEN];
int sock_opt = 1;
int n;
pid_t pid;

if(init(&sin, &lfd, sock_opt) == -1)
exit(1);

printf("waiting connections …n");

while(1){
if((cfd = accept(lfd, (struct sockaddr *)&cin, &len)) == -1){
perror("fail to accept");
exit(1);
}

if( (pid = fork()) < 0){
perror("fail to fork");
exit(1);
}else if(pid == 0){
close(lfd);

while(1){
if(my_read(cfd, buf, MAX_LINE) == -1)
exit(1);

if(strstr(buf, "GET") == buf)
{if(do_put(cfd, &buf[4]) == -1)
printf("error occours while puttingn");
else
printf("GET successful!n");
}
else if(strstr(buf, "PUT") == buf)
{if(do_get(cfd, &buf[4]) == -1)
printf("error occours while gettingn");}
else if(strstr(buf, "CD") == buf)
{if(do_cd(cfd, &buf[3]) == -1)
printf("error occours while changing directoryn");}
else if(strstr(buf, "LS") == buf)
{if(do_ls(cfd, &buf[3]) == -1)
printf("error occours while listingn");else printf("LS OKn");}
else if(strstr(buf, "RUN") == buf)
{if(do_command(cfd, &buf[4]) == -1)
printf("error occours while listingn");else printf("RUN OKn");}
else if(strstr(buf, "BYE") == buf)
break;
else{
printf("wrong commandn");
exit(1);
}
}

close(cfd);
exit(0);
}else
close(cfd);
}
return 0;
}

command.c

#include "common.h"

//================socket,bind,listen======================
int init(struct sockaddr_in *sin,int *lfd,int sock_opt)
{
int tfd;
bzero(sin,sizeof(struct sockaddr_in));
sin->sin_family=AF_INET;
sin->sin_addr.s_addr=INADDR_ANY;
sin->sin_port=htons(PORT);

if((tfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{perror("Fail to creat socket");return -1;}

setsockopt(tfd,SOL_SOCKET,SO_REUSEADDR,&sock_opt,sizeof(int));

if(bind(tfd,(struct sockaddr *)sin,sizeof(struct sockaddr_in))==-1)
{perror("Fail to bind");return -1;}

if(listen(tfd,20)==-1)
{perror("Fail to listen");return -1;}

*lfd=tfd;
return 0;
}

//=====================put==========================
int do_put(int cfd,char *file)
{
struct stat statbuf;
int n,fd,res=-1;
char buf[MAX_LINE];

if((fd=open(file,O_RDONLY))==-1)
{my_write(cfd,"ERR open server filen",22);return res;}

if(fstat(fd,&statbuf)==-1)
{my_write(cfd,"ERR stat server filen",22);goto end;}
if(!S_ISREG(statbuf.st_mode))
{if(my_write(cfd,"ERR server path should be a regular filen",42)==-1)
goto end;
res=0;
goto end;
}

sprintf(buf,"OK %d",statbuf.st_size);
if(my_write(cfd,buf,strlen(buf)+1)==1)
goto end;
if(my_read(cfd,buf,MAX_LINE)<=0)
goto end;

while(1)
{
n=read(fd,buf,MAX_LINE);
printf("n:%d – ",n);
if(n>0)
{if((my_write(cfd,buf,n))==-1)
goto end;}
else if(n==0){
printf("OKn");break;}
else{
perror("Fail to read");goto end;}
}
res=0;
end:
close(fd);
retur

n res;
}

//===================get==============================
int do_get(int cfd,char *file)
{
struct stat statbuf;
int n,fd,len,res=-1;
char buf[MAX_LINE],c[MAX_LINE],*save=file;
char *lenc=c;
printf("%sn",file);
while(*file!=' ')
{*lenc++ = *file++;*lenc='';}
len=atoi(c);
printf("lenc:%s,file:%s,len:%dn",c,file,len);
if((fd=open(file+1,O_WRONLY|O_CREAT|O_TRUNC,0644))==-1)
{
if(errno==EISDIR)
{
if(my_write(cfd,"ERR server has a dir with the same namen",41)==-1)
goto end;
res=0;
goto end;
}else{
my_write(cfd,"ERR open server filen",22);
goto end;
}
}

if(fstat(fd,&statbuf)==-1)
{my_write(cfd,"ERR stat server filen",22);goto end;}

if(!S_ISREG(statbuf.st_mode))
{
if(my_write(cfd,"ERR server path should be a regular filen",42)==-1)
goto end;
res=0;
goto end;
}

if(my_write(cfd,"OK",3)==-1)
goto end;

while(1)
{
if(len!=0)
n=my_read(cfd,buf,MAX_LINE);

if(n>0)
{write(fd,buf,n);len-=n;n=0;}
else if(len==0)
{printf("OKn");break;}
else
goto end;
}
res=0;
end:
close(fd);
return res;
}

//======================cd===========================
int do_cd(int cfd,char *path)
{
if(chdir(path)==-1)
{perror("Fail to change directoryn");
my_write(cfd,"ERR cat't change directoryn",28);return -1;
}
my_write(cfd,"OKn",4);
return 0;
}

//=====================ls===========================
int do_ls(int cfd,char *path)
{
char cmd[128],buf[NAME_LEN];
struct stat statbuf;
int n,fd,res=-1;

sprintf(cmd,"ls %s > temp.txt",path);
system(cmd);

if((fd=open("temp.txt",O_RDONLY))==-1)
{my_write(cfd,"ERR ls server filen",20);return res;}

if(fstat(fd,&statbuf)==-1)
{my_write(cfd,"ERR stat server filen",22);goto end;}

if(!S_ISREG(statbuf.st_mode))
{
if(my_write(cfd,"ERR server path should be a regular filen",42)==-1)
goto end;
res=0;
goto end;
}

sprintf(buf,"OK %d",statbuf.st_size);
if(my_write(cfd,buf,strlen(buf)+1)==-1)
goto end;

if(my_read(cfd,buf,MAX_LINE)<=0)
goto end;

while(1)
{
n=read(fd,buf,MAX_LINE);
printf("%d,%sn",n,buf);
if(n>0)
{ if(my_write(cfd,buf,n)==-1)
goto end;}
else if(n==0)
{printf("OKn");break;}
else
{perror("Fail to read");goto end;}

}

res=0;
end:
close(fd);
return res;
}

//==================command=========================
int do_command(int cfd,char *path)
{
char cmd[128],buf[MAX_LINE];
struct stat statbuf;
int n,fd,res=-1;

sprintf(cmd,"%s > temp.txt",path);
system(cmd);

if((fd=open("temp.txt",O_RDONLY))==-1)
{my_write(cfd,"ERR ls server filen",20);return res;}

if(fstat(fd,&statbuf)==-1)
{my_write(cfd,"ERR stat server filen",22);goto end;}

if(!S_ISREG(statbuf.st_mode))
{
if(my_write(cfd,"ERR server path should be a regular filen",42)==-1)
goto end;
res=0;
goto end;
}

sprintf(buf,"OK %d",statbuf.st_size);
if(my_write(cfd,buf,strlen(buf)+1)==-1)
goto end;

if(my_read(cfd,buf,MAX_LINE)<=0)
goto end;

while(1)
{
n=read(fd,buf,MAX_LINE);
printf("n:%d,buf:%sn",n,buf);fflush(stdout);
if(n>0)
{ if(my_write(cfd,buf,n)==-1)
goto end;n=0;}
else if(n==0)
{printf("OKn");break;}
else
{perror("Fail to read");goto end;}

}

res=0;
end:
close(fd);
return res;
}

以上是主要文件的内容,其它文件请下载压缩包。

点击下载

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注