用重定向原理实现远程执行交互
来源:互联网 发布:现在淘宝开店怎么样 编辑:程序博客网 时间:2024/05/01 09:53
用重定向原理实现远程执行交互
这是一个简单工具,用于远程执行在服务器上的脚本或进程。
原理是在服务器上将socket重定向到所运行的进程的标准输入输出流,这样进程的标准输出(STDOUT)会自动发送到客户端,客户端写到socket上的数据自动输出到进程的标准输入(STDIN),这样就实现了远程交互,类似telnet服务.
代码如下:
//句柄复制 from qmail tcpserver
int fd_copy(int to,int from)
{
if (to == from) return 0;
if (fcntl(from,F_GETFL,0) == -1) return -1;
close(to);
if (fcntl(from,F_DUPFD,to) == -1) return -1;
return 0;
}
//句柄复制,并关闭源句柄 from from qmail tcpserver
int fd_move(int to,int from)
{
if (to == from) return 0;
if (fd_copy(to,from) == -1) return -1;
close(from);
return 0;
}
//处理客户端连接的主循环
void clientloop(CONNECT_INFO *pConn)
{
int pid ;
int stat = 0;
int res = 0;
char cmd[100]="";
char Prompt[]="->"; //定义提示符
int i;
SendData(pConn->socket,Prompt,strlen(Prompt)); //输出提示符
while(1) //主循环
{
memset(cmd,0,sizeof(cmd));
if(RecvData(pConn->socket,cmd,sizeof(cmd),1000 )>0) //从socket上获取指令(主进程)
{
chomp(cmd); //去掉回车换行,TAB,空格
printf("Get cmd:[%s]/n",cmd); //在服务器端打印出收到的命令
if(strcmp(cmd,"quit")==0) //收到quit则退出
{ break; }
pid = fork(); //创建子进程
if(pid < 0) //错误
{
perror("fork error");
break;
}
if(pid > 0) //主进程
{
waitpid(pid,&stat,WCONTINUED); //等待子进程退出
kill(pid,9); //再kill一次防止僵死进程
SendData(pConn->socket,Prompt,strlen(Prompt)); //发送提示符号
}else{
fd_copy(0,pConn->socket); //将socket重定向到标准输入
fd_move(1,pConn->socket); //将标准输出重定向到socket
printf("[%d]run cmd %s/n",getpid(),cmd); //打印当前命令
res = execl(cmd,"",(char*)0); //使用execl运行指令,子进程被指令创建的进程取代,该进程的输入输出已经被重定向
if (errno == ENOEXEC) //这是处理某些没有指定默认shell的脚本
execl ("/bin/sh", "sh", "-c", cmd, (char *)0);
else
printf("run res = %d,%s/n",res,strerror(errno)); //错误输出到客户端
exit(0);
}//pid
}//recvdata
}//while
}//主程序入口
main(){/*建立监听socket,获得客户端连接,对新连接fork进程,调用clientloop*/
}
目前这个代码还比较粗糙,能实现基本的运行和交互,最需要优化的主要是execl的调用方法,这样的写法只能输入完整路径名,而且不能带参数。可以
1:根据当前的PATH环境变量,实现类似whereis功能,
2:对输入的命令行进行解析,获取命令参数,构造成char **字符数组传递给execl.
还有一种方式是用popen,用popen的效果也满不错,比起用execl来,避免了以上1,2问题,还可以对输出的信息先进行处理再发给客户端
int runcmdpipe(const char *sCmd)
{
char pline [1024];
FILE *fp = NULL;
if ((fp = popen (sCmd, "r")) == NULL)
return -1;
while (fgets (pline, sizeof(pline)-1, fp)!= NULL)
{
printf(">> %s",pline); //输出到客户端
}
pclose (fp);
return ncount;
}
客户端可以用telnet程序,但unix和windows的telnet客户端有小小差异,unix的telnet输入回车才发送,而windows的telnet一击键即刻发送,所以程序应该判断是否得到回车换行,才认为是一个完整的指令。
还有一些unix命令如su,top,vi在这种模式下运行不太顺畅,但此工具已经满足要求了,以后有空再研究如何解决。
- 用重定向原理实现远程执行交互
- 重定向底层实现原理相关知识点
- Servlet 重定向原理
- ICMP重定向原理
- Servlet 重定向原理
- I/O重定向的原理和实现
- I/O重定向的原理和实现
- I/O重定向的原理和实现
- I/O重定向的原理和实现
- 重定向Redirect函数实现的原理和方法
- 执行体的重定向
- 输出重定向执行顺序
- Apache Struts远程命令执行漏洞、开放式式重定向漏洞
- 用iptables实现网页重定向
- 用链接实现的重定向
- 用iptables实现网页重定向
- 用Apache HttpClient实现URL重定向
- 《用Apache HttpClient实现URL重定向》
- 控件之美_甘特图
- Jsp 连接 mySQL、Oracle 数据库备忘(Windows平台)
- [软工]极端分子之歌--读XProgrammer笔记
- 在单位上班,个人的前途重要,还是单位的利益重要?
- 同济大学软件学院万院长谈择业
- 用重定向原理实现远程执行交互
- VI命令
- UNIX内存占用基本检查
- 同济大学软件学院万院长谈择业
- CSDN的Blog越来越差了
- 关于DataGrid等控件中的自动编号
- 闲来无事,写了个删除文件夹的java类
- ADO.NET 和 ADO 的比较
- what?