2015-04-20 41 views
0

我想通過功能opendir()命令行的目錄名稱,但我不知道如何... 我已經實現了功能do_ls,我想通過命令給命令的名稱線作爲論點。如何使用opendir()獲取目錄名稱?

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

void do_ls(char *); 
void dostat(char *); 
void show_file_info(char *, struct stat *); 
void mode_to_letters(int , char []); 
char *uid_to_name(uid_t); 
char *gid_to_name(gid_t); 


int main(int ac, char *av[]) 
{ 
    if (ac == 1) 
     do_ls("."); 
    else 
     while (--ac){ 
      printf("%s:\n", *++av); 
      do_ls(*av); 
     } 
    return 0; 
} 


void do_ls(char argv[]) 
/* 
* list files in directory called dirname 
*/ 
{ 
    DIR  *dir_ptr;  
    struct dirent *direntp;  

    if ((dir_ptr = opendir(argv[0])) == NULL) 
     fprintf(stderr,"ls2: cannot open %s\n", argv[0]); 
    else 
    { 
     while ((direntp = readdir(dir_ptr)) != NULL) { 
      if (strcmp(direntp->d_name,".")==0 || 
       strcmp(direntp->d_name,"..")==0) continue; 
      dostat(direntp->d_name); 
     } 
     closedir(dir_ptr); 
    } 
} 


void dostat(char *filename) 
{ 
    struct stat info; 

    if (stat(filename, &info) == -1)  /* cannot stat */ 
     perror(filename);   /* say why */ 
    else     /* else show info */ 
     show_file_info(filename, &info); 
} 


void show_file_info(char *filename, struct stat *info_p) 
/* 
* display the info about 'filename'. The info is stored in struct at *info_p 
*/ 
{ 
    char *uid_to_name(), *ctime(), *gid_to_name(), *filemode(); 
    void mode_to_letters(); 
     char modestr[11]; 

    mode_to_letters(info_p->st_mode, modestr); 

    printf("%s" , modestr); 
    printf("%4d " , (int) info_p->st_nlink); 
    printf("%-8s " , uid_to_name(info_p->st_uid)); 
    printf("%-8s " , gid_to_name(info_p->st_gid)); 
    printf("%8ld " , (long)info_p->st_size); 
    printf("%.12s ", 4+ctime(&info_p->st_mtime)); 
    printf("%s\n" , filename); 

} 

/* 
* utility functions 
*/ 

/* 
* This function takes a mode value and a char array 
* and puts into the char array the file type and the 
* nine letters that correspond to the bits in mode. 
* NOTE: It does not code setuid, setgid, and sticky 
* codes 
*/ 

void mode_to_letters(int mode, char str[]) 
{ 
    strcpy(str, "----------");   /* default=no perms */ 

    if (S_ISDIR(mode)) str[0] = 'd'; /* directory?  */ 
    if (S_ISCHR(mode)) str[0] = 'c'; /* char devices  */ 
    if (S_ISBLK(mode)) str[0] = 'b'; /* block device  */ 

    if (mode & S_IRUSR) str[1] = 'r'; /* 3 bits for user */ 
    if (mode & S_IWUSR) str[2] = 'w'; 
    if (mode & S_IXUSR) str[3] = 'x'; 

    if (mode & S_IRGRP) str[4] = 'r'; /* 3 bits for group */ 
    if (mode & S_IWGRP) str[5] = 'w'; 
    if (mode & S_IXGRP) str[6] = 'x'; 

    if (mode & S_IROTH) str[7] = 'r'; /* 3 bits for other */ 
    if (mode & S_IWOTH) str[8] = 'w'; 
    if (mode & S_IXOTH) str[9] = 'x'; 
} 

#include <pwd.h> 

char *uid_to_name(uid_t uid) 
/* 
* returns pointer to username associated with uid, uses getpw() 
*/ 
{ 
    struct passwd *getpwuid(), *pw_ptr; 
    static char numstr[10]; 

    if ((pw_ptr = getpwuid(uid)) == NULL){ 
     sprintf(numstr,"%d", uid); 
     return numstr; 
    } 
    else 
     return pw_ptr->pw_name ; 
} 

#include <grp.h> 

char *gid_to_name(gid_t gid) 
/* 
* returns pointer to group number gid. used getgrgid(3) 
*/ 
{ 
    struct group *getgrgid(), *grp_ptr; 
    static char numstr[10]; 

    if ((grp_ptr = getgrgid(gid)) == NULL){ 
     sprintf(numstr,"%d", gid); 
     return numstr; 
    } 
    else 
     return grp_ptr->gr_name; 
} 
+0

請注意,需要將'dostat()'告知目錄名稱以及目錄中文件的名稱;否則它將無法找到該文件,除非該目錄的名稱是'.'(dot,當前目錄)。 –

回答

1

這一行:

(argv[0]) 

被提取傳遞的參數的第一個字符。

建議:

(argv) 

所以得到一個指針到NULL終止傳遞給函數的字符串。

+0

這確實是一個問題,編譯器應該告訴OP這個錯誤。注意編譯器警告是非常重要的,如果在發佈代碼時發現編譯器警告,請這麼說 - 它使人們不必交叉,因爲他們不必花費時間研究代碼的情況。 –