天天看點

20145203 《資訊安全系統設計基礎》第10周學習總結20145203 《資訊安全系統設計基礎》第10周學習總結

20145203 《資訊安全系統設計基礎》第10周學習總結

視訊資源内容

1、ls-l指令可以顯示目前工作目錄下包含目錄或者檔案的詳細資訊。資訊包含七列:

①第一列:

第一位:檔案類型,-代表檔案,d代表目錄。

第二、三、四位:代表檔案建立者權限,-為無權限,r為可讀,w為可寫,x為可執行。

第五、六、七位:代表同組使用者權限。

第八、九、十位:代表其他使用者權限,其中其他使用者沒有寫權限。

②第二列:檔案的目錄、子目錄數。(目錄的該字段至少2)

③第三列:所有者

④第四列:所屬使用者組

⑤第五列:檔案大小

⑥第六列:檔案最後修改時間

⑦第七列:檔案名

2、什麼是目錄?

①目錄是一種特殊的檔案,它的内容是檔案和目錄的名字。

②目錄包含很多記錄,記錄通過結構體定義。

③每條記錄内容代表一個檔案或者目錄。

④目錄檔案至少包含兩個特殊項

‘.’  :代表目前目錄
‘..’ :代表上一級目錄
           

3、man -k:

常用來搜尋。例句如下:

man -k key1 | grep key2 | grep 2
           

搜尋同時含有k1和k2,且屬于系統調用。最後的數字意味着幫助手冊中的區段,man手冊共有8個區段,最常用的是123,含義如下:

1.Linux
2.系統調用
3.c語言
           

單獨用man語句的時候,想檢視其中的單獨某個區段内的解釋時,例句如下:

man 3 printf
           

即查找c語言中printf的用法。

4、grep -nr

這條語句可以用來查找關鍵字,全文搜尋,并且可以直接查找檔案内的内容。其中:

n:為顯示行号
r:為遞歸查找
           

例如,如果想查找某個宏,我們已知宏儲存在include檔案夾中,是以例句如下:

grep -nr XXX /usr/include(XXX為所要找的宏)
           

5、通過系統調用stat可以擷取檔案相關資訊

20145203 《資訊安全系統設計基礎》第10周學習總結20145203 《資訊安全系統設計基礎》第10周學習總結

檔案連結數、檔案最後修改時間、檔案最後通路時間可以直接擷取。

st_mode十六位二進制數

20145203 《資訊安全系統設計基礎》第10周學習總結20145203 《資訊安全系統設計基礎》第10周學習總結

注意:權限讀寫執行都是三位一組的,是以二進制掩碼都是三位一組用八進制表示的。

20145203 《資訊安全系統設計基礎》第10周學習總結20145203 《資訊安全系統設計基礎》第10周學習總結

①:與:之間分别是:使用者名、密碼、使用者id、所屬的組等等。

②使用getpwuid(uid_t uid)函數可以通過使用者的id得到使用者名。

附錄A

附錄A中主要講了這本書中的錯誤處理方式

1.錯誤處理風格

(1)Unix風格

遇到錯誤後傳回-1,并且将全局變量errno設定為指明錯誤原因的錯誤代碼;

如果成功完成,就傳回有用的結果。

(2)Posix風格

傳回0表示成功,傳回非0表示失敗;

有用的結果在傳進來的函數參數中。

(3)DNS風格

有兩個函數,gethostbyname和gethostbyaddr,失敗時傳回NULL指針,并設定全局變量h_errno。

(4)錯誤報告函數

void unix_error(char *msg) /* unix-style error */
{
    fprintf(stderr, "%s: %s\n", msg, strerror(errno));
    exit(0);
}
/* $end unixerror */

void posix_error(int code, char *msg) /* posix-style error */
{
    fprintf(stderr, "%s: %s\n", msg, strerror(code));
    exit(0);
}

void dns_error(char *msg) /* dns-style error */
{
    fprintf(stderr, "%s: DNS error %d\n", msg, h_errno);
    exit(0);
}

void app_error(char *msg) /* application error */
{
    fprintf(stderr, "%s\n", msg);
    exit(0);
}
           

2.錯誤處理包裝函數

Unix風格

成功時傳回void,傳回錯誤時包裝函數列印一條資訊,然後退出。

void Kill(pid_t pid, int signum) 
{
    int rc;

    if ((rc = kill(pid, signum)) < 0)
    unix_error("Kill error");
}
           

Posix風格

成功時傳回void,錯誤傳回碼中不會包含有用的結果。

void Pthread_detach(pthread_t tid) {
    int rc;

    if ((rc = pthread_detach(tid)) != 0)
    posix_error(rc, "Pthread_detach error");
}
           

DNS風格

struct hostent *Gethostbyname(const char *name) 
{
    struct hostent *p;

    if ((p = gethostbyname(name)) == NULL)
    dns_error("Gethostbyname error");
    return p;
}
           

實踐代碼

main函數的定義與頭檔案的含義:

int main(int argc, char *argv[]){}
           

   argc是用來表示在指令行下輸入指令時的參數個數,包括指令本身。

   argv[]是用來取得你輸入的參數。

stdio.h 标準輸入輸出

stdlib.h C标準函數庫

unistd.h Unix類系統定義符号常量

fcntl.h 定義了很多宏和open,fcntl函數原型

sys/types.h 基本系統資料類型,(是檔案還是目錄)

dirent.h unix類目錄操作的頭檔案,包含了許多UNIX系統服務的函數原型,例如opendir函數、readdir函數。

termios.h 在Posix規範中定義的标準接口

cp.c

#include        <stdio.h>//标準輸入輸出
#include        <stdlib.h>//C标準函數庫
#include        <unistd.h>//Unix類系統定義符号常量
#include        <fcntl.h>//定義了很多宏和open,fcntl函數原型

#define BUFFERSIZE      4096//定義存儲器容量
#define COPYMODE        0644//定義複制的長度

void oops(char *, char *);

int main(int argc, char *argv[])
{
    int in_fd, out_fd, n_chars;//三個描述符值
    char buf[BUFFERSIZE];//存儲器位置

    /*cp的參數有兩個,分别是要複制的檔案,和目的目錄,這樣一共應該是有三個操作數
    是以要先檢查argc的值是否為三,如果不是,傳回标準錯誤*/
    if (argc != 3) {
        fprintf(stderr, "usage: %s source destination\n", *argv);
        exit(1);
    }
    /*檢查cp的第一個參數,要複制的檔案,用open打開,in_fd為open傳回的描述符
    如果傳回-1,代表打開失敗,提示錯誤*/
    if ((in_fd = open(argv[1], O_RDONLY)) == -1)
        oops("Cannot open ", argv[1]);

    /*檢查cp的第二個參數,複制的目的位址,用create在目的位址建立新檔案,out_fd為open傳回的描述符    
    如果傳回-1,代表建立失敗,提示錯誤*/
    if ((out_fd = creat(argv[2], COPYMODE)) == -1)
        oops("Cannot creat", argv[2]);

    /*cp指令的動作就是讀取一個檔案的内容到存儲器,在新的位址建立空白檔案,再從存儲器将内容寫入新檔案。
    這裡判斷複制是否成功:
    如果能讀取順利,而讀取的位數和寫的位數不同,是寫錯誤;
    如果讀取失敗,是讀錯誤。*/
    while ((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)
        if (write(out_fd, buf, n_chars) != n_chars)
            oops("Write error to ", argv[2]);
    if (n_chars == -1)
        oops("Read error from ", argv[1]);

    /*這裡執行的是關閉檔案的動作,in_fd和out_fd兩個檔案描述符
    所指向的檔案隻要有一個關閉錯誤,就提示關閉錯誤。*/
    if (close(in_fd) == -1 || close(out_fd) == -1)
        oops("Error closing files", "");
}

/*這個是用來輸出錯誤資訊的函數*/
void oops(char *s1, char *s2)
{
    fprintf(stderr, "Error: %s ", s1);
    perror(s2);//用來将上一個函數發生錯誤的原因輸出到标準裝置(stderr)
    exit(1);
}
           

輸入:源檔案和目的檔案

輸出:./cp1 cp1.c cp2.c 指令可将

ls1.c

#include    <stdio.h>
#include    <sys/types.h>
#include    <dirent.h>

void do_ls(char []);

int main(int argc, char *argv[])
{
    /*如果操作數隻有1個,表明ls後面沒有帶參數,預設為目前目錄,‘.’表示目前目錄。*/
    if ( argc == 1 )
        do_ls( "." );
    /*如果ls後面有參數,就把參數讀入argv中。*/
    else
        while ( --argc ){
            printf("%s:\n", *++argv );
            do_ls( *argv );
        }

    return 0;
}


/*因為ls和dir功能相近,用dir來實作ls*/
void do_ls( char dirname[] )
{
    DIR     *dir_ptr;
    struct dirent   *direntp;

    /*如果沒有指向的那個位址,報錯*/
    if ( ( dir_ptr = opendir( dirname ) ) == NULL )
        fprintf(stderr,"ls1: cannot open %s\n", dirname);
    else
    {
        /*遞歸的方式來讀取*/
        while ( ( direntp = readdir( dir_ptr ) ) != NULL )
            printf("%s\n", direntp->d_name );
        closedir(dir_ptr);
    }
}
           

輸出:./ls1指令可以顯示目前工作目錄下包含什麼目錄或檔案。

ls2.c

ls2前半部分和ls1一樣,所不同的隻是多出來了一部分,用來顯示檔案的詳細資訊,比如使用者名,群組名,大小,建立時間,讀寫權限等。

輸出:./ls2指令可以顯示目前工作目錄下包含目錄或者檔案的詳細資訊。

who.c

作用:從UTMP_FILE檔案中讀取想要的資訊到存儲器中,然後再用标準輸出函數列印到螢幕上,最後關閉檔案。

#include    <stdio.h>
#include    <stdlib.h>
#include    <utmp.h>
#include    <fcntl.h>
#include    <unistd.h>

#define SHOWHOST    

int show_info( struct utmp *utbufp )
{
    printf("%-8.8s", utbufp->ut_name);  
    printf(" ");                
    printf("%-8.8s", utbufp->ut_line);  
    printf(" ");                
    printf("%10ld", utbufp->ut_time);   
    printf(" ");                
#ifdef  SHOWHOST
    printf("(%s)", utbufp->ut_host);    
#endif
    printf("\n");               

    return 0;
}
int main()
{
    struct utmp  current_record;    
    int     utmpfd;     
    int     reclen = sizeof(current_record);

/*打開UTMP_FILE讀取資訊,如果打開失敗則輸出失敗資訊。*/
    if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
        perror( UTMP_FILE );    
        exit(1);
    }
    /*讀取資訊到存儲器中,reclen就是是讀的位元組數,然後再調用函數列印出來。*/
    while ( read(utmpfd, &current_record, reclen) == reclen )
        show_info(&current_record);
    close(utmpfd);
    return 0;           
           

  }

  

  輸出:./who 指令可以輸出正在本系統中的使用者的資訊。

  

echostate.c

作用:用來檢查指令行中的提示符是否顯示的,如果顯示,輸入的指令都可見,不顯示則表示輸入的指令不可見,具體例子結合setecho代碼一起

#include        <stdio.h>
#include        <stdlib.h>
#include        <termios.h>

int main()
{
        struct termios info;
        int rv;

        rv = tcgetattr( 0, &info );     /* read values from driver      */

        if ( rv == -1 ){
                perror( "tcgetattr");
                exit(1);
        }
        if ( info.c_lflag & ECHO )
                printf(" echo is on , since its bit is 1\n");
        else
                printf(" echo is OFF, since its bit is 0\n");

        return 0;
}
           

輸出:./echostate 即可顯示指令行中的提示符是否顯示。

setecho

作用:改變echo的狀态,設定指令行中的提示符是否顯示。

#include        <stdio.h>
#include        <stdlib.h>
#include        <termios.h>

#define  oops(s,x) { perror(s); exit(x); }

int main(int argc, char *argv[])
{
        struct termios info;

        if ( argc == 1 ) 
        exit(0);

        if ( tcgetattr(0,&info) == -1 )
            oops("tcgettattr", 1);

        if ( argv[1][0] == 'y' )
                info.c_lflag |= ECHO ;/*打開提示符*/
        else
                info.c_lflag &= ~ECHO ;/*隐藏提示符*/

        if ( tcsetattr(0,TCSANOW,&info) == -1 )
               oops("tcsetattr",2);
    
        return 0;
}
           

輸入:./setecho no(yes)

輸出:當echo is on的時候,輸入的指令是可見的,當設定為off的時候,輸入指令不可見

fileinfo.c

作用:用來實作顯示檔案資訊,建立了一個stat資料結構。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

void show_stat_info(char *, struct stat *);
           

/先判斷指令是否有操作數,有的話才能繼續進行下去,如果沒有報錯就列印出來相關檔案資訊,報錯就用perror将報錯資訊列印出來。/

int main(int argc, char *argv[])
{
    struct stat info;        

    if (argc>1)
    {
    
        if( stat(argv[1], &info) != -1 ){
            show_stat_info( argv[1], &info );
            return 0;
        }
        else
            perror(argv[1]);  
    }
    return 1;
}
void show_stat_info(char *fname, struct stat *buf)
{
    printf("   mode: %o\n", buf->st_mode);         
    printf("  links: %d\n", buf->st_nlink);        
    printf("   user: %d\n", buf->st_uid);          
    printf("  group: %d\n", buf->st_gid);          
    printf("   size: %d\n", (int)buf->st_size);         
    printf("modtime: %d\n", (int)buf->st_mtime);        
    printf("   name: %s\n", fname );               
}
           

輸入:./fleinfo.c cp1.c

輸出:顯示cp1.c檔案的相關資訊

filesize.c

作用:用st_size成員來計算檔案的位元組數大小。

#include <stdio.h>
#include <sys/stat.h>
/*先判斷是否有錯誤,沒有的話就調用*/
int main()
{
    struct stat infobuf;           

    if ( stat( "/etc/passwd", &infobuf) == -1 )
        perror("/etc/passwd");
    else
        printf(" The size of /etc/passwd is %d\n", infobuf.st_size );
}
           

輸入:./filesize etc/passwd

輸出:可以計算出passwd檔案的位元組數為2298

spwd

作用:這個代碼的功能是列出目前所在目錄

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <dirent.h>

ino_t   get_inode(char *);
void    printpathto(ino_t);
void    inum_to_name(ino_t , char *, int );

int main()
{
    printpathto( get_inode( "." ) );    
    putchar('\n');              
    return 0;
}

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 );       
                            
    }
}

void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen)
{
    DIR     *dir_ptr;       
    struct dirent   *direntp;       

    dir_ptr = opendir( "." );
    if ( dir_ptr == NULL ){
        perror( "." );
        exit(1);
    }


    while ( ( direntp = readdir( dir_ptr ) ) != NULL )
        if ( direntp->d_ino == inode_to_find )
        {
            strncpy( namebuf, direntp->d_name, buflen);
            namebuf[buflen-1] = '\0';   
            closedir( dir_ptr );
            return;
        }
    fprintf(stderr, "error looking for inum %d\n", (int) inode_to_find);
    exit(1);
}

ino_t get_inode( char *fname )
{
    struct stat info;

    if ( stat( fname , &info ) == -1 ){
        fprintf(stderr, "Cannot stat ");
        perror(fname);
        exit(1);
    }
    return info.st_ino;
}
           

輸入:./spwd

輸出:顯示目前所在的目錄

testioctl.c

作用:計算目前指令行視窗的行列數大小

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
    struct winsize size;
    if( isatty(STDOUT_FILENO) == 0)
        exit(1);
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) < 0) {
        perror("ioctl TIOCGWINSZ error");
        exit(1);
    }

    printf("%d rows %d columns\n", size.ws_row, size.ws_col);
    return 0;
}
           

輸入:./testioctl.c

輸出:x行,y列。

本周代碼托管截圖

代碼連結

學習進度條

代碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目标 5000行 30篇 400小時
第一周 150/150 1/2 20/20
第二周 200/350 1/2 24/44
第三周 150/500 1/3 20/64
第五周 300/800 1/4 15/79
第六周 500/1300 1/5 20/99
第七周 200/1500 1/6 21/120
第九周 210/1710 1/9 10/130
第十周 530/2240 2/11 20/150

參考資料

  • 《深入了解計算機系統V2》學習指導
  • ...

轉載于:https://www.cnblogs.com/GZSdeboke/p/6083957.html

繼續閱讀