zoukankan      html  css  js  c++  java
  • 2018-2019-1 20165325 《信息安全系统设计基础》第六周学习总结

    2018-2019-1 20165325 《信息安全系统设计基础》第六周学习总结

    一、学习笔记

    1、输入输出是在主存和外部设备之间复制数据的过程

    输入是I/O设备复制数据到主存,输出是主存复制数据到I/O设备;

    2、Unix I/O

    Linux内核引出的一个简单低级的接口,用于文件的读写。

    描述符

    内核返回的一个非负整数,好比文件指针。打开文件时被创建,当内核释放文件,描述符恢复到描述符池当中。

    标准输入、标准输出、标准错误

    头文件<unistd.h>引入的常量,分别对应STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO,描述符分别是0、1、2,可用来代替显式的描述符值;

    例:一次一个字节地从标准输入复制到标准输出;

    当前文件位置

    对于当前文件位置,内核始终显式地保存着一个值k,这个k就是从文件开头起始字节的偏移量,发生读写操作以后,k值会更新。

    #include "csapp.h"
    
    int main (void){
        char c;
        
        while (Read(STDIN_FILENO,&c,1)!=0)
            Write(STDOUO_FILENO,&c,1);
        exit(0);
    }
    
    3、open()

    对应头文件<sys/type.h>、<sys/stat.h>、<fcntl.h>。

    int open(char *filename,int flags,mode_t mode);返回值是打开文件以后的标识符。

    flags参数

    • O_RDONLY:只读;
    • O_WRONLY:只写;
    • O_RDWD:可读可写;
    4、读、写文件

    头文件:<unistd.h>

    ssize_t read(int fd,void *buf,size_t n);
    
    ssize_t write(int fd,const void *buf,size_t n);
    

    ssize_t 是有符号long型;size_t 是无符号;

    5、RIO包

    提供更方便健壮高效的I/O,分为两种函数:无缓冲的输入输出和带缓冲的输入函数。

    二、课上笔记

    1、两个重要命令:
    • man -k key1 | grep key2| grep 2 : 根据关键字检索系统调用
    • grep -nr XXX /usr/include :查找宏定义,类型定义
    2、操作系统的功能我总结为两点:管家婆和服务生:
    • 管家婆:通过进程、虚拟内存和文件三个重要抽象管理计算机的CPU、内存、I/O设备
    • 服务生:为用户提供shell, 为程序员提供系统调用(API)。
    3、od命令复习

    $ od -tc -tx1 abc.txt

    4、echo命令创建二进制文件

    echo -ne "/x7b" > abc.bin

    5、who命令的编写

    who命令用作在Linux命令行中查看用户的身份,使用man who查询结果:

    DESCRIPTION
           Print information about users who are currently logged in.
           
           .....
           
           If FILE is not specified, use /var/run/utmp.  /var/log/wtmp as FILE  is
           common.   If  ARG1  ARG2  given, -m presumed: 'am i' or 'mom likes' are
           usual.
    
           
    

    所以可以想到,who命令的编写如下:

    1、fopen()函数从指定位置打开文件/var/run/utmp;

    2、用while循环读取文件直到文件末尾EOF;

    3、输出先关信息,实现和who相同的功能。

    问题的关键在于/var/run/utmp是怎么存储的,打开utmp.h如下:

    #ifndef _UTMP_H
    # error "Never include <bits/utmp.h> directly; use <utmp.h> instead."
    #endif
    
    #include <paths.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <bits/wordsize.h>
    
    
    #define UT_LINESIZE 32
    #define UT_NAMESIZE 32
    #define UT_HOSTSIZE 256
    
    
    /* The structure describing an entry in the database of
       previous logins.  */
    struct lastlog
      {
    #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
        int32_t ll_time;
    #else
        __time_t ll_time;
    #endif
        char ll_line[UT_LINESIZE];
        char ll_host[UT_HOSTSIZE];
      };
    
    
    /* The structure describing the status of a terminated process.  This
       type is used in `struct utmp' below.  */
    struct exit_status
      {
        short int e_termination;    /* Process termination status.  */
        short int e_exit;       /* Process exit status.  */
      };
    
    
    /* The structure describing an entry in the user accounting database.  */
    struct utmp
    {
      short int ut_type;        /* Type of login.  */
      pid_t ut_pid;         /* Process ID of login process.  */
      char ut_line[UT_LINESIZE];    /* Devicename.  */
      char ut_id[4];        /* Inittab ID.  */
      char ut_user[UT_NAMESIZE];    /* Username.  */
      char ut_host[UT_HOSTSIZE];    /* Hostname for remote login.  */
      struct exit_status ut_exit;   /* Exit status of a process marked
                       as DEAD_PROCESS.  */
    /* The ut_session and ut_tv fields must be the same size when compiled
       32- and 64-bit.  This allows data files and shared memory to be
       shared between 32- and 64-bit applications.  */
    #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
      int32_t ut_session;       /* Session ID, used for windowing.  */
      struct
      {
        int32_t tv_sec;     /* Seconds.  */
        int32_t tv_usec;        /* Microseconds.  */
      } ut_tv;          /* Time entry was made.  */
    #else
      long int ut_session;      /* Session ID, used for windowing.  */
      struct timeval ut_tv;     /* Time entry was made.  */
    #endif
    
      int32_t ut_addr_v6[4];    /* Internet address of remote host.  */
      char __unused[20];        /* Reserved for future use.  */
    };
    
    /* Backwards compatibility hacks.  */
    #define ut_name     ut_user
    #ifndef _NO_UT_TIME
    /* We have a problem here: `ut_time' is also used otherwise.  Define
       _NO_UT_TIME if the compiler complains.  */
    # define ut_time    ut_tv.tv_sec
    #endif
    #define ut_xtime    ut_tv.tv_sec
    #define ut_addr     ut_addr_v6[0]
    
    
    /* Values for the `ut_type' field of a `struct utmp'.  */
    #define EMPTY       0   /* No valid user accounting information.  */
    
    #define RUN_LVL     1   /* The system's runlevel.  */
    #define BOOT_TIME   2   /* Time of system boot.  */
    #define NEW_TIME    3   /* Time after system clock changed.  */
    #define OLD_TIME    4   /* Time when system clock changed.  */
    
    #define INIT_PROCESS    5   /* Process spawned by the init process.  */
    #define LOGIN_PROCESS   6   /* Session leader of a logged in user.  */
    #define USER_PROCESS    7   /* Normal process.  */
    #define DEAD_PROCESS    8   /* Terminated process.  */
    
    #define ACCOUNTING  9
    
    /* Old Linux name for the EMPTY type.  */
    #define UT_UNKNOWN  EMPTY
    
    
    /* Tell the user that we have a modern system with UT_HOST, UT_PID,
       UT_TYPE, UT_ID and UT_TV fields.  */
    #define _HAVE_UT_TYPE   1
    #define _HAVE_UT_PID    1
    #define _HAVE_UT_ID 1
    #define _HAVE_UT_TV 1
    #define _HAVE_UT_HOST   1
    

    看起来很长但是实际上关键的地方就是这里:

    struct utmp
    {
      short int ut_type;        /* Type of login.  */
      pid_t ut_pid;         /* Process ID of login process.  */
      char ut_line[UT_LINESIZE];    /* Devicename.  */
      char ut_id[4];        /* Inittab ID.  */
      char ut_user[UT_NAMESIZE];    /* Username.  */
      char ut_host[UT_HOSTSIZE];    /* Hostname for remote login.  */
      struct exit_status ut_exit;   /* Exit status of a process marked as DEAD_PROCESS.  */
       ·······//此处省略一部分
    

    现在我们明白了读取utmp文件的意义就是查找上面这样一个结构体,who命令所需要的信息都在里面。度娘表示:其中ut_type有很多种不同的登录方式,而我们需要的是用户的登陆,所以我们要对/var/log/utmp文件的文件内容进行筛选,只显示登录方式为USER_PROCESS的信息。

    我们运行who命令来试一下

    $ who
    paul     tty7         2018-11-03 15:51 (:0)
    

    这里解释一下,我的用户名是paul,设备名tty7,后面是时间,最后那个(:0)百度查到了是host;

    然后我们就可以开始自己写mywho.c了,这里的时间用的是用ctime函数。

    代码如下:

    /*
     *  mywho.c 
     *  author lidongjun
     */
    #include <stdio.h>
    #include <utmp.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <time.h>
    void show_time(long time){
            char * c;
            c = ctime(&time);
            printf("%12.20s", c+4);
    }
    void show_info(struct utmp *a){
            if(a->ut_type != USER_PROCESS)
                    return;
            printf("%-8s ", a->ut_user);
            printf("%-8s ", a->ut_line);
            show_time(a->ut_time);
            printf(" (%s)", a->ut_host);
            printf("
    ");
    }
    int main() {
            struct utmp a;
            int fd;
            int len = sizeof(a);
            if((fd = open("/var/run/utmp", O_RDONLY,0)) == -1){
                    return -1;
            }
            while(read(fd, &a, len) == len)
                    show_info(&a);
            close(fd);
            return 0;
    }
    
    

    运行结果:

  • 相关阅读:
    (16)JavaScript的流程控制(js的循环)
    (15)javaScript入门
    (14)定位布局(子级在父级中自由定位 父级在页面中自由定位)
    (0-1)CSS 标签语法的属性
    ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))
    手记-数学分析(高等数学)中有关算法效率的公式列举(O,Θ,Ω)
    2014北大研究生推免机试(校内)-复杂的整数划分(DP进阶)
    整数划分问题-解法汇总(暂有DP-递归)
    2014北大研究生推免机试(校内)-垃圾炸弹(基础枚举)
    ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)
  • 原文地址:https://www.cnblogs.com/maxeysblog/p/9896792.html
Copyright © 2011-2022 走看看