2016-10-17 1 views
1

저는 C 언어를 처음 사용하기 때문에 코드에서 어디에 문제가 있는지 파악하는 데 어려움이 있습니다.C 언어 - 다른 디렉토리에서 파일 권한이 잘못되었습니다.

현재 프로그램이있는 현재 폴더에서 제대로 작동하는 것으로 보이지만 상위 디렉터리의 콘텐츠를 나열하려고하면 파일 정보를 제대로 가져올 수 없습니다.

163899 ?---------  0 root root  0  Jan 1 1:00 b 
163900 ?---------  0 root root  0  Jan 1 1:00 ship 
297613 drwxrwxr-x  4 me  me  4096 Oct 16 21:38 A.pdf 

방법 : 내가 상위 디렉토리 (..)를 나열하려고하면

165277 -rw-rw-r--  1 me me 4356 Oct 17 19:48 test.c 
147877 -rw-rw-r--  1 me me 4413 Oct 17 19:48 test.c~ 
157723 -rw-rw-r--  1 me me 95981 Sep 15 16:50 Doc.pdf 
157722 -rwxrwxr-x  1 me me 12176 Oct 17 20:20 a.out 
157720 -rw-rw-r--  1 me me 617 Sep 22 19:47 other.c 

그리고 이것은 출력 :

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

char TypeFile (mode_t m) 
{ 
switch (m&S_IFMT) { 
    case S_IFSOCK: return 's'; /*socket */ 
    case S_IFLNK: return 'l'; /*symbolic link*/ 
    case S_IFREG: return '-'; /* normal file*/ 
    case S_IFBLK: return 'b'; /*block device*/ 
    case S_IFDIR: return 'd'; /*directory */ 
    case S_IFCHR: return 'c'; /*char device*/ 
    case S_IFIFO: return 'p'; /*pipe*/ 
    default: return '?'; /*unknown*/ 
} 
} 

char * Permissions (mode_t m) 
{ 
static char p[12]; 
strcpy (p,"---------- "); 
p[0]=TypeFile(m); 
if (m&S_IRUSR) p[1]='r'; /*owner*/ 
if (m&S_IWUSR) p[2]='w'; 
if (m&S_IXUSR) p[3]='x'; 
if (m&S_IRGRP) p[4]='r'; /*group*/ 
if (m&S_IWGRP) p[5]='w'; 
if (m&S_IXGRP) p[6]='x'; 
if (m&S_IROTH) p[7]='r'; /*other*/ 
if (m&S_IWOTH) p[8]='w'; 
if (m&S_IXOTH) p[9]='x'; 
if (m&S_ISUID) p[3]='s'; /*setuid, setgid, stickybit*/ 
if (m&S_ISGID) p[6]='s'; 
if (m&S_ISVTX) p[9]='t'; 
return (p); 
} 



char * dateFormat (char *str, time_t val) { 
strftime(str, 36, "%b %e %k:%M ", localtime(&val)); 
return str; 
} 


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

/* Variables */ 
DIR *dirp; 
struct dirent *direntp; 
struct stat perm; 
struct passwd *owner; 
struct group *gr; 

char path[PATH_MAX + 1]; 


/* Open dir */ 
if (argc == 1){ dirp = opendir("."); } 
else { dirp = opendir(argv[1]);  } 

if (dirp == NULL){ 
printf("Error: Can't open dir \n"); 
exit(1); 
} 

/* Read dir content */ 

char dat[36]; 
while ((direntp = readdir(dirp)) != NULL) { 

    realpath(direntp->d_name,path); 
    lstat(path,&perm);   

    if (direntp->d_name[0] == '.') { continue; }  
    printf("%10ld\t%4s\t", direntp->d_ino, Permissions(perm.st_mode)); 
    printf("%4u\t", perm.st_nlink); 

    if ((owner= getpwuid(perm.st_uid)) != NULL) { 
     printf("%4s\t", owner->pw_name); 
    } 
    else { 
     printf("%4d\t", perm.st_uid); 
    } 

    if ((group = getgrgid(perm.st_gid)) != NULL) { 
     printf("%4s\t", group->gr_name); 
    } 
    else { 
     printf("%4d\t", perm.st_gid); 
    } 
    printf("%4ld\t", perm.st_size); 
    printf("%4s\t%4s\n", dateFormat(dat,perm.st_mtime),direntp->d_name); 

    } 

/* Close */ 
closedir(dirp); 

return 0; 
} 

이것은 현재 디렉토리에 출력 될 것이다 이 문제를 해결할 수 있을까요? 미리 감사드립니다.

+2

대부분의 함수 호출, 특히'lstat()'호출의 리턴 값을 테스트하지 않습니다. 내 첫 번째 추측은'lstat()'가 세부 사항이 정확하게 제시되지 않은 파일에서 실패하는 것입니다. 'ls' 유틸리티를 통해 그 디렉토리를 열거 할 때 올바른 결과를 얻는다면, 예를 들어 SELinux와 같은 유닉스 모드 비트 위에 추가적인 접근 제어 메커니즘이 있음을 알 수 있습니다. –

+2

당신은'realpath'를 사용하고 있습니다. 심볼릭 링크를 확장합니다. 심볼릭 링크가 사용자에게 액세스 할 수있는 경로를 가리키는 것은 아닙니다. 또한 결과를 확인하지 않고 lstat을 사용하고 있습니다. 디렉토리 내용을 나열 할 때'realpath'를 사용하지 말아야합니다 **. 오히려 기호 링크 자체를 나열하십시오. 호출 한 모든 함수의 반환 값을 항상 확인하십시오. –

답변

1

상대 파일 이름을 realpath()으로 지정하면 현재 작업 디렉토리와 관련하여 표준 파일 이름이 정식화됩니다. direntp->d_name에는 파일의 기본 이름 만 포함되어 있습니다. opendir("..")을 입력하면 ../이 포함되지 않습니다. opendir() 호출 후

  1. 사용 if (argc > 1) chdir(argv[1]); : 프로그램을 수정하는 방법은 두 가지가 있습니다.
  2. realpath()을 사용하지 말고 대신 lstat()에 전달하기 전에 argv [1], "/"direntp->d_name을 연결하십시오.
관련 문제