LCOV - code coverage report
Current view: top level - src - custom_ls.c (source / functions) Coverage Total Hit
Test: report.info Lines: 78.8 % 104 82
Test Date: 2025-02-11 09:58:02 Functions: 100.0 % 9 9

            Line data    Source code
       1              : #include "custom_ls.h"
       2              : 
       3              : int max_size_user;
       4              : int max_size_group;
       5              : int max_size_file_size;
       6              : 
       7            6 : int ls(const char *path)
       8              : {
       9            6 :     max_size_user = 0;
      10            6 :     max_size_group = 0;
      11            6 :     max_size_file_size = 0;
      12              : 
      13              :     struct stat path_stat;
      14              : 
      15            6 :     if (path == NULL)
      16            1 :         path = ".";
      17              : 
      18            6 :     if (lstat(path, &path_stat) == -1)
      19              :     {
      20            2 :         print_error("[ERROR] stat on path");
      21            2 :         return EXIT_FAILURE;
      22              :     }
      23              : 
      24            4 :     if (S_ISDIR(path_stat.st_mode))
      25            3 :         list_directory(path);
      26              :     else
      27            1 :         file_info(path, path);
      28              : 
      29            4 :     return EXIT_SUCCESS;
      30              : }
      31              : 
      32           97 : int count_digits(long long value)
      33              : {
      34           97 :     if (value == 0)
      35            6 :         return 1;
      36              : 
      37           91 :     value = llabs(value);
      38           91 :     int count = 0;
      39              : 
      40          458 :     while (value > 0)
      41              :     {
      42          367 :         value /= 10;
      43          367 :         count++;
      44              :     }
      45              : 
      46           91 :     return count;
      47              : }
      48              : 
      49           46 : void file_info(const char *full_path, const char *file_name)
      50              : {
      51              :     int space_quantity;
      52              : 
      53              :     struct stat file_stat;
      54              : 
      55           46 :     if (lstat(full_path, &file_stat) == -1)
      56              :     {
      57            0 :         print_error("[ERROR] stat");
      58            0 :         return;
      59              :     }
      60              : 
      61              :     // User
      62           46 :     print_generic(STDOUT_FILENO, "%c%s ", get_filetype(file_stat.st_mode), get_permissions(file_stat.st_mode));
      63              : 
      64           46 :     space_quantity = max_size_user - strlen(get_owner(file_stat.st_uid));
      65           46 :     for (int i = 0; i < space_quantity && space_quantity > 0; i++)
      66            0 :         print_generic(STDOUT_FILENO, " ", get_owner(file_stat.st_uid));
      67              : 
      68           46 :     print_generic(STDOUT_FILENO, "%s ", get_owner(file_stat.st_uid));
      69              : 
      70              :     // Group
      71           46 :     space_quantity = max_size_group - strlen(get_group(file_stat.st_gid));
      72           46 :     for (int i = 0; i < space_quantity && space_quantity > 0; i++)
      73            0 :         print_generic(STDOUT_FILENO, " ", get_group(file_stat.st_gid));
      74              : 
      75           46 :     print_generic(STDOUT_FILENO, "%s ",
      76              :                   get_group(file_stat.st_gid));
      77              : 
      78              :     // Size
      79           46 :     space_quantity = max_size_file_size - count_digits(file_stat.st_size);
      80          100 :     for (int i = 0; i < space_quantity && space_quantity > 0; i++)
      81           54 :         print_generic(STDOUT_FILENO, " ");
      82              : 
      83           46 :     print_generic(STDOUT_FILENO, "%ld ", file_stat.st_size);
      84              : 
      85           46 :     print_generic(STDOUT_FILENO, "%s ", parse_time(file_stat.st_mtime));
      86              : 
      87              :     // File name with color
      88           46 :     if (get_filetype(file_stat.st_mode) == 'd')
      89           30 :         print_generic(STDOUT_FILENO, "\033[1;34m%s\033[0m\n", file_name);
      90              :     else
      91           16 :         print_generic(STDOUT_FILENO, "%s\n", file_name);
      92              : }
      93              : 
      94            3 : void list_directory(const char *path)
      95              : {
      96              :     char full_path[MAX_PATH_LENGTH];
      97              : 
      98            3 :     DIR *dir_count_size = opendir(path);
      99            3 :     if (dir_count_size == NULL)
     100              :     {
     101            0 :         print_error("[ERROR] Couldn't open the directory");
     102            0 :         return;
     103              :     }
     104              : 
     105              :     // Count the max size of user, group and file size
     106              :     struct dirent *file_count_size;
     107           48 :     while ((file_count_size = readdir(dir_count_size)) != NULL)
     108              :     {
     109           45 :         snprintf(full_path, MAX_PATH_LENGTH, "%s/%s", path, file_count_size->d_name);
     110              : 
     111              :         struct stat file_stat;
     112              : 
     113           45 :         if (lstat(full_path, &file_stat) == -1)
     114              :         {
     115            0 :             print_error("[ERROR] stat");
     116            0 :             return;
     117              :         }
     118              : 
     119           45 :         max_size_user = strlen(get_owner(file_stat.st_uid)) > max_size_user ? strlen(get_owner(file_stat.st_uid)) : max_size_user;
     120           45 :         max_size_group = strlen(get_group(file_stat.st_gid)) > max_size_group ? strlen(get_group(file_stat.st_gid)) : max_size_group;
     121           45 :         max_size_file_size = count_digits(file_stat.st_size) > max_size_file_size ? count_digits(file_stat.st_size) : max_size_file_size;
     122              :     }
     123              : 
     124            3 :     closedir(dir_count_size);
     125              : 
     126            3 :     DIR *dir = opendir(path);
     127            3 :     if (dir == NULL)
     128              :     {
     129            0 :         print_error("[ERROR] Couldn't open the directory");
     130            0 :         return;
     131              :     }
     132              : 
     133              :     struct dirent *file;
     134              : 
     135            3 :     print("[INFO] Listing directory %s\n", path);
     136              : 
     137           48 :     while ((file = readdir(dir)) != NULL)
     138              :     {
     139           45 :         snprintf(full_path, MAX_PATH_LENGTH, "%s/%s", path, file->d_name);
     140           45 :         file_info(full_path, file->d_name);
     141              :     }
     142              : 
     143            3 :     closedir(dir);
     144              : }
     145              : 
     146           46 : char *parse_time(time_t time)
     147              : {
     148              :     static char time_str[STR_SIZE];
     149           46 :     struct tm *broken_time = localtime(&time);
     150              : 
     151           46 :     strftime(time_str, STR_SIZE, "%b %d %H:%M", broken_time);
     152              : 
     153           46 :     return time_str;
     154              : }
     155              : 
     156           92 : char get_filetype(mode_t perm)
     157              : {
     158           92 :     switch (perm & S_IFMT)
     159              :     {
     160           32 :     case S_IFREG:
     161           32 :         return '-';
     162           60 :     case S_IFDIR:
     163           60 :         return 'd';
     164            0 :     case S_IFLNK:
     165            0 :         return 'l';
     166            0 :     case S_IFBLK:
     167            0 :         return 'b';
     168            0 :     case S_IFCHR:
     169            0 :         return 'c';
     170            0 :     case S_IFIFO:
     171            0 :         return 'p';
     172            0 :     case S_IFSOCK:
     173            0 :         return 's';
     174            0 :     default:
     175            0 :         return '?';
     176              :     }
     177              : }
     178              : 
     179           46 : char *get_permissions(mode_t perm)
     180              : {
     181              :     static char str[PERM_SIZE];
     182          414 :     snprintf(str, PERM_SIZE, "%c%c%c%c%c%c%c%c%c",
     183           46 :              (perm & S_IRUSR) ? 'r' : '-',
     184           46 :              (perm & S_IWUSR) ? 'w' : '-',
     185           46 :              (perm & S_IXUSR) ? 'x' : '-',
     186           46 :              (perm & S_IRGRP) ? 'r' : '-',
     187           46 :              (perm & S_IWGRP) ? 'w' : '-',
     188           46 :              (perm & S_IXGRP) ? 'x' : '-',
     189           46 :              (perm & S_IROTH) ? 'r' : '-',
     190           46 :              (perm & S_IWOTH) ? 'w' : '-',
     191           46 :              (perm & S_IXOTH) ? 'x' : '-');
     192           46 :     return str;
     193              : }
     194              : 
     195          140 : char *get_owner(uid_t uid)
     196              : {
     197          140 :     return getpwuid(uid)->pw_name;
     198              : }
     199              : 
     200          140 : char *get_group(gid_t gid)
     201              : {
     202          140 :     return getgrgid(gid)->gr_name;
     203              : }
        

Generated by: LCOV version 2.0-1