C/Linux :: ls -l 을 수행하는 ll.c

과제로 유닉스 명령어 ls -l 과 비슷하게 수행하는 ll.c 를 만들어서 기록으로 남겨둡니다. 간단하게 구현했기 때문에 디렉토리 전체나 2개 이상의 파일에 대해서는 수행되지 않습니다.

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

#include <pwd.h>
#include <grp.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define PATHNAME_SIZE 1024
#define PERM_SIZE 10
#define TIME_SIZE 16

char * getperm (char *perm_c, const mode_t mode)
{
    char *ref = "xwr";
    int i;

    memset (perm_c, '-', PERM_SIZE);

    if ((mode & S_IFMT) == S_IFDIR)
        perm_c[0] = 'd';

    for (i = 0; i < 9; i++)
    {
        if (mode & (1 << i))
            perm_c[PERM_SIZE - i - 1] = ref[i % 3];
    }

    return perm_c;
}

char * gettime (char *time_c, const struct tm *tinfo)
{
    snprintf (time_c, TIME_SIZE + 1, "%04d-%02d-%02d %02d:%02d", \
              tinfo->tm_year + 1900, \
              tinfo->tm_mon + 1, \
              tinfo->tm_mday, \
              tinfo->tm_hour, \
              tinfo->tm_min
              );

    return time_c;
}

int main (int argc, char **argv)
{
    char pathname[PATHNAME_SIZE + 1] = {0};
    char perm_c[PERM_SIZE + 1] = {0};
    char time_c[TIME_SIZE + 1] = {0};
    struct stat finfo;

    if (argc > 1)
        strncpy (pathname, argv[1], PATHNAME_SIZE);
    else
        strcpy (pathname, "./");

    if (stat (pathname, &finfo) == -1)
    {
        perror ("[*] path error");
        exit (1);
    }

    printf ("%s %d %s %s %d %s %s\n", \
            getperm (perm_c, finfo.st_mode), \
            finfo.st_nlink, \
            getpwuid (finfo.st_uid)->pw_name, \
            getgrgid (finfo.st_gid)->gr_name, \
            (int)finfo.st_size, \
            gettime (time_c, localtime (&finfo.st_mtime)), \
            pathname
            );

    return 0;
}


사용자 삽입 이미지

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다