分类: LINUX
2012-12-10 16:36:09
scp.c中main
基本流程
1、解析参数;
2、根据"最后的参数"看是本地copy,还是远程copy。
分别指向toremote和tolocal函数。
3、toremote()分三种:(和下面分析的流程类似,请参考最下面的彩色字体描述)
1)远端到远端,通过本地。(分解为两步:远端到本地,本地到远端)
2)远端到远端,不通过本地
3)本地到远端
4、tolocal()分为
1)本地到本地
执行cp命令
2)远端到本地
此情况的详解如下:
“本地scp进程 <-----pipe----> 本地ssh子进程 < -------socket------> server端sshd进程 <-------pipe--------> server端scp进程”
蓝色为本地操作;紫色为对端操作。
大量使用了下面这连个机制:
使用“管道”作为“父子”进程之间的通信机制。
使用dup2将“管道”和“标准输入输出口”绑定。
发送时,在scp进程中,子进程为ssh。
1、本地启用子进程,执行ssh命令,作为ssh client端,连接远端ssh server。(在ssh子进程中,使用dup2将“标准输入输出”和“管道”绑定;此时scp进程监听管道另一端)。
2、ssh client通过SSH_CMSG_EXEC_CMD消息将“scp -f -- 文件名”命令发送给ssh server。
接收时,在sshd子进程中,创建scp孙进程。
ssh server进程隐藏的流程
1)解析参数;
2)主进程作为守护进程daemon,一直在server_accept_loop中循环监听端口;
3)监听到一个ssh client连接,则创建一个sshd子进程,监听socket。
3、sshd子进程收到scp命令后,启用scp孙进程执行此命令。 (在scp孙进程中,使用dup2将“标准输入输出”和“管道”绑定;此时sshd子进程监听管道另一端)
4、scp孙进程发现-f参数,知道自己是源端,执行source()函数,直接写入“标准输出”,即管道,被sshd子进程接收到。
因为此sshd子进程和ssh client是一一对应的,sshd子进程收到数据后,缓存到stdout_buffer,然后组成SSH_SMSG_STDOUT_DATA报文,进而发送到ssh client端;
5、 ssh client收到后,也存入stdout_buffer,然后打印到“标准输出”。
6、 因为第1步的原因,本地scp进程收到内容。
http://blog.csdn.net/an_zhenwei/article/details/7951527