ls小程序,使用到文件信息和權限等的獲取

/*

 *只支持當前目錄下的-a, -l, -al的顯示。希望對初學者有所幫助。

 */

# include < stdio. h>
# include < stdlib. h>
# include < string . h>
# include < time . h>
# include < sys/ stat. h>
# include < unistd. h>
# include < sys/ types. h>
# include < linux/ limits. h>
# include < dirent. h>
# include < grp. h>
# include < pwd. h>
# include < error . h>

# define NONE 0 //沒有參數

# define HAVE_A 1 //參數是-a

# define HAVE_L 2 //參數是-l

# define HAVE_AL 3

# define HANGMAX 123 //一行最多打印的字符數

# define FILEMAX    256

int leave_max = HANGMAX; //記錄一行剩餘的字符數

int len_max;          //目錄下最長的文件

int count = 0;

typedef struct file {     //記錄當前目錄下的所用文件名和文件長度    

    char filename[ FILEMAX] [ 30] ;
    int filelen[ FILEMAX] ;
} filelan;

/*
 *函數名稱:filelan copy_file(char *pathname)
 *函數功能:將當前目錄下的所用文件拷貝到結構體filelan裏
 *傳遞參數:pathname:當前的目錄
 *返回類型:將拷貝完的文件返回給filelan F
 */

filelan copy_file( char * pathname)
{
    DIR * dp;
    struct dirent * dirp;
    filelan F;
    int i;

    if ( ( dp = opendir( pathname) ) = = NULL )
        printf ( "Cannot open %s/n" , pathname) ;
    len_max = 0;
    i = 0;
    while ( ( dirp = readdir( dp) ) ! = NULL ) {
        if ( len_max < ( strlen ( dirp- > d_name) ) )
            len_max = strlen ( dirp- > d_name) ;
        F. filelen[ i] = strlen ( dirp- > d_name) ;
        strcpy ( F. filename[ i] , dirp- > d_name) ;
        i+ + ;
        count + + ;
    }
    if ( count > FILEMAX) {
        printf ( "Too Many Files!/n" ) ;
        exit ( 0) ;
    }
//    printf("i = %d/n", i);

//    printf("count = %d/n", count);

//    printf("len_max = %d/n", len_max);

    closedir( dp) ;
    return F;
}
/*
 *函數名稱:int part_parameter(int argc, char **argv)
 *函數功能:分離主函數傳入的參數
 *傳遞參數:argc:主函數參數個數,argv:主函數參數本身
 *返回類型:flag:參數分離的結果
 */

int part_parameter( int argc, char * * argv)
{
    int flag;
    if ( argc = = 1)
        flag = NONE ;
    else if ( argc = = 2) {
        if ( ( strcmp ( argv[ 1] , "-a" ) ) = = 0)
            flag = HAVE_A;
        else if ( ( strcmp ( argv[ 1] , "-l" ) ) = = 0)
            flag = HAVE_L;
        else if ( ( strcmp ( argv[ 1] , "-al" ) ) = = 0 | | ( strcmp ( argv[ 1] , "-la" ) ) = = 0)
            flag = HAVE_AL;
        else {
            perror ( "ERROR: <1>can shu/n" ) ;
            exit ( 0) ;
        }
    }
    else if ( argc = = 3) {
        if ( ( ( strcmp ( argv[ 1] , "-a" ) ) = = 0) & & ( ( strcmp ( argv[ 2] , "-l" ) ) ) = = 0)
            flag = HAVE_AL;
        else if ( ( ( strcmp ( argv[ 1] , "-l" ) ) = = 0) & & ( ( strcmp ( argv[ 2] , "-a" ) ) ) = = 0)
            flag = HAVE_AL;
        else {
            perror ( "ERROR: <2>cna shu/n" ) ;
            exit ( 0) ;
        }
    }
    return flag;
}
/*
 *函數名稱:show_file(int flag, filelan F)
 *函數功能:顯示當前目錄下的文件。
 *傳遞參數:flag:判斷是否爲-a的參數。F:將拷貝好的結構體傳入此函數。
 *返回類型:無
 */

void show_file( int flag, filelan F)
{
    int i, j;
    int len;
    for ( i = 0; i < count ; i+ + )
    {
        if ( len_max > leave_max) {
            printf ( "/n" ) ;
            leave_max = HANGMAX;
        }
        if ( flag = = NONE )
            if ( F. filename[ i] [ 0] = = '.' )
                continue ;
        len = F. filelen[ i] ;
        len = len_max - len;
        printf ( "%s" , F. filename[ i] ) ;
        for ( j = 0; j < len; j+ + )
            printf ( " " ) ;
        printf ( " " ) ;
        leave_max = leave_max - ( len_max+ 2) ;
    }
    printf ( "/n" ) ;
}

/*
 *函數名稱:void show_file_l(char *filename)
 *函數功能:主要顯示有-l參數的文件
 *傳遞參數:filename:要顯示的文件名
 *返回類型:無
 */

void show_file_l( char * filename)
{
    char file_time[ 32] ;
    struct stat file_stat;
    struct passwd * psd;     //獲得文件所有者的用戶名

    struct group * grp;     //獲取文件所有者的所屬組的組名

    
    if ( lstat( filename, & file_stat) = = - 1) {
        perror ( "Cannot get the information of the file!/n" ) ;
        exit ( 0) ;
    }
    //獲取並打印文件類型

    if ( S_ISREG( file_stat. st_mode ) )
        printf ( "-" ) ;
    else if ( S_ISDIR( file_stat. st_mode ) )
        printf ( "d" ) ;
    else if ( S_ISCHR( file_stat. st_mode ) )
        printf ( "c" ) ;
    else if ( S_ISBLK( file_stat. st_mode ) )
        printf ( "b" ) ;
    else if ( S_ISFIFO( file_stat. st_mode ) )
        printf ( "f" ) ;
    else if ( S_ISLNK( file_stat. st_mode ) )
        printf ( "l" ) ;
    else if ( S_ISSOCK( file_stat. st_mode ) )
        printf ( "s" ) ;

    //獲取並打印文件所有者的權限

    if ( file_stat. st_mode & S_IRUSR)
        printf ( "r" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IWUSR)
        printf ( "w" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IXUSR)
        printf ( "x" ) ;
    else printf ( "-" ) ;

    //獲取並打印文件所有者同組成員的權限

    if ( file_stat. st_mode & S_IRGRP)
        printf ( "r" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IWGRP)
        printf ( "w" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IXGRP)
        printf ( "x" ) ;
    else printf ( "-" ) ;

    //獲取並打印其他用戶的權限

    if ( file_stat. st_mode & S_IROTH )
        printf ( "r" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IWOTH)
        printf ( "w" ) ;
    else printf ( "-" ) ;
    if ( file_stat. st_mode & S_IXOTH)
        printf ( "x" ) ;
    else printf ( "-" ) ;

    printf ( " " ) ;

    psd = getpwuid( file_stat. st_uid) ;
    grp = getgrgid( file_stat. st_gid) ;

    printf ( "%4d " , file_stat. st_nlink) ;
    printf ( "%-8s" , psd- > pw_name) ;
    printf ( "%-8s" , grp- > gr_name) ;
    printf ( "%6d " , file_stat. st_size) ;
    
    strcpy ( file_time, ctime ( & file_stat. st_mtime) ) ;
    file_time[ strlen ( file_time) - 1] = '/0' ;
    printf ( " %s" , file_time) ;
    printf ( " %s/n" , filename) ;
}

//主函數:分離參數並且調用以上函數實現功能

int main( int argc, char * * argv)
{
    int flag, i;
    filelan F;
    F = copy_file( "./" ) ;
    flag = part_parameter( argc, argv) ;

//    printf("flag = %d/n", flag);

    switch ( flag) {
        case NONE :
            show_file( NONE , F) ;
            break ;

        case HAVE_A:
            show_file( HAVE_A, F) ;
            break ;

        case HAVE_L:
            for ( i = 0; i < count ; i+ + ) {
                if ( F. filename[ i] [ 0] = = '.' )
                    continue ;
                show_file_l( F. filename[ i] ) ;             
            }
            break ;

        case HAVE_AL:
            for ( i = 0; i < count ; i+ + ) {
                show_file_l( F. filename[ i] ) ;
            }
            break ;
    }
    return 0;
}

 

發佈了18 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章