首页 > 技术文章 > 20145319 《信息安全系统设计基础》第十周补充

20145319zk 2016-11-28 22:59 原文

20145319 《信息安全系统设计基础》第十周补充

一 课后代码分析补充

  • echostate.c&setecho.c:

    • tcgetattr(int fd, & termios info)函数:用于获取和终端相关的参数赋给info

    • tcsetattr(int fd, int actions,&termios info):设置与终端相关的参数,actions参数决定修改什么时候生效,TCSANOW为改变立即发生

    • 结构体termios:是在POSIX规范中定义的标准接口,用于存储一些和终端接口相关的信息

    • man -k terminal|grep set|grep 1可以找到系统自带的设置终端属性命令sttystty echo即打开echo.stty -echo关闭echo

    • 为了仔细观察在开关echo时c_lflagc_lflag|ECHOc_lflag&~ECHO的值的变化,编写一个echotest将三者值输出出来,当echo打开时三者值如下:

    • 使用stty将echo关闭时,三者的值:

      • 可见无论echo是打开还是关闭,c_lflag|ECHOc_lflag&~ECHO的值始终没有改变,不过具体原因还没有想清楚,要继续查询或者GDB调试或许能更清楚具体是怎么变化的

  • filesize&fileinfo:

    • 关于文件大小,权限,时间等操作通常与结构体stat有关

    • stat结构体具体如下:

        struct stat {   
            mode_t     st_mode;    //文件访问权限   
                    ino_t      st_ino;     //索引节点号   
                    dev_t      st_dev;     //文件使用的设备号   
                    dev_t      st_rdev;     //设备文件的设备号   
                    nlink_t    st_nlink;    //文件的硬连接数   
            uid_t      st_uid;      //所有者用户识别号     
                    gid_t      st_gid;      //组识别号   
                    off_t      st_size;      //以字节为单位的文件容量   
                    time_t     st_atime;   //最后一次访问该文件的时间   
                    time_t     st_mtime;   //最后一次修改该文件的时间   
                    time_t     st_ctime;//最后一次改变该文件状态的时间   
                    blksize_t  st_blksize; //包含该文件的磁盘块的大小   
                    blkcnt_t   st_blocks; //该文件所占的磁盘块   
                };  
      
    • filesize.c中显示的文件时间是直接输出st_mtime是系统时间,对于用户来说并不友好,但是可以调用函数ctime(),将输出模式改成用户友好的年月日(localtime()可以将其修改成对应中文格式)

  • ls1.c&ls2.c

    • linux ls命令中还涉及目录的操作,所以除了stat结构体之外,还需要用到目录相关的结构体DIR&dirent

    • DIR结构体如下:

        struct __dirstream   
        {   
        	void *__fd;    
        	char *__data;    
        	int __entry_data;    
        	char *__ptr;    
        	int __entry_ptr;    
        	size_t __allocation;    
        	size_t __size;    
        	__libc_lock_define (, __lock)    
        };   
      
    • dirent结构体如下:

        struct dirent   
        {   
        	long d_ino; /* 索引节点号 */  
        	off_t d_off; /* 在目录文件中的偏移 */  
        	unsigned short d_reclen; /*  文件名长 */  
        	unsigned char d_type; /*文件类型 */   	   
        	char d_name [NAME_MAX+1]; /*文件名 */  
        }
      
    • 通过DIR *opendir(const char *filename)dirent *readdir(DIR *dirp)等目录相关函数取得相应数据输出即可(opendir()对应记得closedir(),目录的打开,读取可以类比c语言中FILE的打开,读取,这也从侧面体现了在linux系统中一切都是以文件的形式来管理的)

  • spwd.c

    • spwd.c要输出当前的工作路径,所以在编写的整体思路上采用一种循环调用的思路:

      • 首先找到本目录的索引节点,并取得其父目录索引节点(比较是否相等,判断是否抵达根目录)
      • 然后进入父目录,找到节点对应的文件名,将其存储起来,准备输出
      • 循环以上过程,直到到达根目录,开始输出路径名
    • 代码除了主函数主要功能由其他三个函数实现:get_inode函数&printpathto函数&inum_to_name函数

    • get_inode()

      • 取某个文件的索引信息(进入点)
    • printpaththo()

        void printpathto( ino_t this_inode )
        {
        	ino_t   my_inode ;
        	char    its_name[BUFSIZ];
      
        	if ( get_inode("..") != this_inode )
        	{
        		chdir( ".." );  /*切换至父目录*/              
      
        		inum_to_name(this_inode,its_name,BUFSIZ);
      
        		my_inode = get_inode( "." );        
        		printpathto( my_inode );        
        	    printf("/%s", its_name );       
                        
        	}
        }
      
      • 这部分代码实现了主要的递归调用,chdir(..)即切换至其父目录的函数
    • inum_to_name()

      • 将长整型的索引信息转化为字符串的形式

推荐阅读