From 69aefc764dee032b2eb98a7ce36a78de7ade08d5 Mon Sep 17 00:00:00 2001 From: Xamora Date: Fri, 10 Jan 2025 09:12:14 +0100 Subject: [PATCH] ls finish, need more test --- compile_flags.txt | 2 + inc/main.h | 48 +++++++++++- lib/ft_printf/ft_printf.c | 2 +- lib/libft/ft_lstdelone.c | 8 +- lib/libft/ft_lstremove_back.c | 25 +++++++ lib/libft/ft_lstremove_front.c | 13 ++++ lib/libft/ft_putnbr_fd.c | 4 +- lib/libft/ft_strcat.c | 6 ++ lib/libft/ft_strcmp.c | 7 ++ lib/libft/ft_strcpy.c | 11 +++ lib/libft/ft_strlcat.c | 3 +- lib/libft/ft_strlcats.c | 19 +++++ lib/libft/ft_strlcpy.c | 19 ++--- lib/libft/ft_substr.c | 2 +- lib/libft/libft.h | 11 ++- src/directory.c | 102 ++++++++++++++++++++++++++ src/display.c | 96 ++++++++++++++++++++++++ src/display_stat.c | 129 +++++++++++++++++++++++++++++++++ src/free.c | 15 ++++ src/main.c | 53 +++++++++++--- src/parsing.c | 95 +++++++++++++++++++----- 21 files changed, 612 insertions(+), 58 deletions(-) create mode 100644 lib/libft/ft_lstremove_back.c create mode 100644 lib/libft/ft_lstremove_front.c create mode 100644 lib/libft/ft_strcat.c create mode 100644 lib/libft/ft_strcmp.c create mode 100644 lib/libft/ft_strcpy.c create mode 100644 lib/libft/ft_strlcats.c create mode 100644 src/directory.c create mode 100644 src/display.c create mode 100644 src/display_stat.c create mode 100644 src/free.c diff --git a/compile_flags.txt b/compile_flags.txt index ce6412a..3cb5529 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -7,3 +7,5 @@ -iquoteinc -iquotelib -g +-D_POSIX_C_SOURCE=200809L +-D_DEFAULT_SOURCE diff --git a/inc/main.h b/inc/main.h index eddb189..565da8f 100644 --- a/inc/main.h +++ b/inc/main.h @@ -1,6 +1,13 @@ #pragma once -#include +#include +#include +#include +#include +#include +#include +#include +#include typedef struct { bool l; @@ -8,8 +15,43 @@ typedef struct { bool R; bool r; bool t; + bool dashdash; int error[2]; } flags_t; -flags_t get_flags(char **argv); -void display_flags(flags_t flags); +typedef struct { + DIR *dir; + char *path; + char *name; + bool is_file; + struct stat stat; + struct stat lstat; + struct passwd *psswd; + struct group *grp; +} dir_t; + +extern flags_t flags; +extern struct winsize win; + +// Parsing +void get_flags(char **argv); +void parsing(char **argv, t_list ***files, t_list ***dirs, i32 *max_size, i32 *len, i32 *error); +dir_t *get_directory_files(char *path); + +// Display +void display_name(dir_t *dir); +void display_file(dir_t *dir, i32 max_size); +i32 display_files(t_list **files); +void display_directory(dir_t *dir); +i32 display_files_stat(t_list **files); +void display_single_stat(dir_t *dir, i32 max_size); +void space_between_files(t_list **files, dir_t *file); + +// Directory +void strmode(mode_t mode, char *buf); +void delete_directory(void *content); +t_list **get_all_in(dir_t *dir); +void add_sort(t_list **head, dir_t *new_dir, bool file_priority); + +// Free +void free_files(t_list **files); diff --git a/lib/ft_printf/ft_printf.c b/lib/ft_printf/ft_printf.c index c8730eb..03cac68 100644 --- a/lib/ft_printf/ft_printf.c +++ b/lib/ft_printf/ft_printf.c @@ -69,7 +69,7 @@ u32 ft_printf(const char *str, ...) { va_list args; va_start(args, str); - u32 count = ft_vdprintf(0, str, args); + u32 count = ft_vdprintf(1, str, args); va_end(args); return count; } diff --git a/lib/libft/ft_lstdelone.c b/lib/libft/ft_lstdelone.c index d06004c..39eb7a9 100644 --- a/lib/libft/ft_lstdelone.c +++ b/lib/libft/ft_lstdelone.c @@ -14,8 +14,8 @@ void ft_lstdelone(t_list *lst, void (*del)(void*)) { - if (lst == NULL || del == NULL) - return ; - del(lst->content); - free(lst); + if (lst == NULL || del == NULL) + return ; + del(lst->content); + free(lst); } diff --git a/lib/libft/ft_lstremove_back.c b/lib/libft/ft_lstremove_back.c new file mode 100644 index 0000000..c79ab9b --- /dev/null +++ b/lib/libft/ft_lstremove_back.c @@ -0,0 +1,25 @@ + +#include "libft.h" + +static void delete(t_list **deleted, void (*del)(void*)); + +void ft_lstremove_back(t_list **lst, void (*del)(void*)) +{ + if (lst == nullptr || del == nullptr) + return; + + if ((*lst)->next == nullptr) + return delete(lst, del); + + t_list *cur = *lst; + while (cur->next != nullptr && cur->next->next != nullptr) + cur = cur->next; + + delete(&(cur->next), del); +} + +static void delete(t_list **deleted, void (*del)(void*)) { + del(*deleted); + free(*deleted); + *deleted = nullptr; +} diff --git a/lib/libft/ft_lstremove_front.c b/lib/libft/ft_lstremove_front.c new file mode 100644 index 0000000..563b5f8 --- /dev/null +++ b/lib/libft/ft_lstremove_front.c @@ -0,0 +1,13 @@ + +#include "libft.h" + +void ft_lstremove_front(t_list **lst, void (*del)(void*)) +{ + if (lst == nullptr || del == nullptr) + return; + + t_list *next = (*lst)->next; + del(*lst); + free(*lst); + *lst = next; +} diff --git a/lib/libft/ft_putnbr_fd.c b/lib/libft/ft_putnbr_fd.c index 7f0747e..06f0bda 100644 --- a/lib/libft/ft_putnbr_fd.c +++ b/lib/libft/ft_putnbr_fd.c @@ -17,8 +17,8 @@ u32 ft_putnbr_fd(i64 n, int fd) if (n < 0) ft_putchar_fd('-', fd); n = ABS(n); - int len = ft_get_size(n) + 1; - while (--len > 1) + int len = ft_get_size(n); + while (--len > 0) ft_putchar_fd(n / ft_power(10, len) % 10 + 48, fd); ft_putchar_fd(n % 10 + 48, fd); return ft_get_size(n); diff --git a/lib/libft/ft_strcat.c b/lib/libft/ft_strcat.c new file mode 100644 index 0000000..2a6b007 --- /dev/null +++ b/lib/libft/ft_strcat.c @@ -0,0 +1,6 @@ +#include "libft.h" + +char *ft_strcat(char *dest, const char *src) { + ft_strcpy(dest + ft_strlen(dest), src); + return dest; +} diff --git a/lib/libft/ft_strcmp.c b/lib/libft/ft_strcmp.c new file mode 100644 index 0000000..4ed1ea3 --- /dev/null +++ b/lib/libft/ft_strcmp.c @@ -0,0 +1,7 @@ +i32 ft_strcmp(const char *s1, const char *s2) { + i32 i = 0; + for (; s1[i] != '\0' && s2[i] != '\0'; i++) + if (s1[i] != s2[i]) + return s1[i] - s2[i]; + return s1[i] - s2[i]; +} diff --git a/lib/libft/ft_strcpy.c b/lib/libft/ft_strcpy.c new file mode 100644 index 0000000..5250ee2 --- /dev/null +++ b/lib/libft/ft_strcpy.c @@ -0,0 +1,11 @@ +#include "libft.h" + +char *ft_strcpy(char *dest, const char *src) { + while (*src) { + char c = *src++; + *dest++ = c; + if (c == '\0') + return dest; + } + return dest; +} diff --git a/lib/libft/ft_strlcat.c b/lib/libft/ft_strlcat.c index dd71c78..39f35b8 100644 --- a/lib/libft/ft_strlcat.c +++ b/lib/libft/ft_strlcat.c @@ -14,8 +14,7 @@ size_t ft_strlcat(char *dest, const char *src, size_t size) { - size_t len_dest; - size_t len_src; + size_t len_dest, len_src; if (size == 0) return (ft_strlen(src)); diff --git a/lib/libft/ft_strlcats.c b/lib/libft/ft_strlcats.c new file mode 100644 index 0000000..fb0d9a7 --- /dev/null +++ b/lib/libft/ft_strlcats.c @@ -0,0 +1,19 @@ +#include "libft.h" + +char *ft_strlcats(u32 nbr_str, ...) { + va_list args; + u32 len = 0; + + va_start(args, nbr_str); + for (u32 i = 0; i < nbr_str; i++) + len += ft_strlen(va_arg(args, char *)); + va_end(args); + + va_start(args, nbr_str); + char *new_str = ft_calloc(len + 1, sizeof(char)); + for (u32 i = 0; i < nbr_str; i++) + ft_strcat(new_str, va_arg(args, char *)); + va_end(args); + + return new_str; +} diff --git a/lib/libft/ft_strlcpy.c b/lib/libft/ft_strlcpy.c index b80d474..8354b5a 100644 --- a/lib/libft/ft_strlcpy.c +++ b/lib/libft/ft_strlcpy.c @@ -12,19 +12,14 @@ #include "libft.h" -size_t ft_strlcpy(char *dest, const char *src, size_t size) +u32 ft_strlcpy(char *dest, const char *src, u32 size) { - size_t i; + if (!size) + return (ft_strlen(src)); - i = 0; - if (size) - { - while (i < size - 1 && src[i] != '\0') - { - dest[i] = src[i]; - i++; - } - dest[i] = '\0'; - } + u32 i = 0; + for (; i < size && src[i] != '\0'; i++) + dest[i] = src[i]; + dest[i] = '\0'; return (ft_strlen(src)); } diff --git a/lib/libft/ft_substr.c b/lib/libft/ft_substr.c index 2a41b7b..e96a25b 100644 --- a/lib/libft/ft_substr.c +++ b/lib/libft/ft_substr.c @@ -24,7 +24,7 @@ char *ft_substr(char const *s, unsigned int start, size_t len) size = 0; else if ((unsigned long)size > len) size = len; - new_s = malloc(size + 1); + new_s = ft_calloc(size + 2, 1); if (new_s == NULL) return (NULL); if (start <= ft_strlen(s)) diff --git a/lib/libft/libft.h b/lib/libft/libft.h index 92056fe..e6bfdc9 100644 --- a/lib/libft/libft.h +++ b/lib/libft/libft.h @@ -16,6 +16,7 @@ # include # include # include +# include typedef struct s_list { @@ -52,12 +53,16 @@ void *ft_memcpy(void *dest, const void *src, size_t s); void *ft_memmove(void *dest, const void *src, size_t s); void *ft_memchr(const void *memory_block, int searched_char, size_t size); int ft_memcmp(const void *pointer1, const void *pointer2, size_t size); -size_t ft_strlcpy(char *dest, const char *src, size_t size); +char *ft_strcpy(char *dest, const char *src); +u32 ft_strlcpy(char *dest, const char *src, u32 size); char *ft_strnstr(const char *big, const char *little, size_t len); char *ft_strchr(const char *str, int search); char *ft_strrchr(const char *str, int search); +i32 ft_strcmp(const char *s1, const char *s2); int ft_strncmp(const char *s1, const char *s2, size_t n); +char * ft_strcat(char *dest, const char *src); size_t ft_strlcat(char *dest, const char *src, size_t size); +char *ft_strlcats(u32 nbr_str, ...); char *ft_strdup(const char *src); int ft_atoi(const char *nptr); char **ft_split(char const *s, char c); @@ -76,12 +81,14 @@ char *ft_strtrim(char const *s1, char const *set); char *ft_substr(char const *s, unsigned int start, size_t len); t_list *ft_lstnew(void *content); void ft_lstadd_front(t_list **lst, t_list *new); +void ft_lstadd_back(t_list **lst, t_list *new); int ft_lstsize(t_list *lst); t_list *ft_lstlast(t_list *lst); -void ft_lstadd_back(t_list **lst, t_list *new); void ft_lstdelone(t_list *lst, void (*del)(void*)); void ft_lstclear(t_list **lst, void (*del)(void*)); void ft_lstiter(t_list *lst, void (*f)(void *)); t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)); +void ft_lstremove_front(t_list **lst, void (*del)(void*)); +void ft_lstremove_back(t_list **lst, void (*del)(void*)); int ft_atoi_check(const char *nptr); u32 ft_strslen(char **strs); diff --git a/src/directory.c b/src/directory.c new file mode 100644 index 0000000..3da00ea --- /dev/null +++ b/src/directory.c @@ -0,0 +1,102 @@ +void +strmode(mode_t mode, char *buf) { + const char chars[] = "rwxrwxrwx"; + for (size_t i = 0; i < 9; i++) + buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-'; + buf[9] = '\0'; +} + +void +delete_directory(void *deleted) { + t_list *lst = (t_list*)deleted; + dir_t *dir = (dir_t*)lst->content; + free(dir->path); + free(dir); +} + +void +remove_all_end_character(char *str, char c) { + for (i32 i = ft_strlen(str) - 1; i >= 0; i--) { + if (str[i] != c) + return; + str[i] = '\0'; + } +} + +t_list ** +get_all_in(dir_t *dir) { + struct dirent *in_dir; + t_list **head = ft_calloc(1, sizeof(t_list*)); + while ((in_dir = readdir(dir->dir)) != nullptr) { + if (!flags.a && ft_strncmp(".", in_dir->d_name, 1) == 0) + continue; + remove_all_end_character(dir->path, '/'); + char *new_path = ft_strlcats(3, dir->path, "/", in_dir->d_name); + dir_t *new_dir = get_directory_files(new_path); + free(new_path); + if (!new_dir) + continue; + new_dir->name = in_dir->d_name; + + if (ft_strcmp(new_dir->name, "switchpro_rstick_click_md.png") == 0) + ft_printf(""); + + add_sort(head, new_dir, false); + } + return head; +} + + +static bool compare_name(char *s1, char *s2); +static bool compare_time(dir_t *dir1, dir_t *dir2); + +void +add_sort(t_list **head, dir_t *new_dir, bool file_priority) { + t_list *cur = *head, *prev = NULL; + for (; cur != nullptr; prev = cur, cur = cur->next) { + dir_t *cur_dir = ((dir_t *)cur->content); + if (file_priority && !cur_dir->is_file && new_dir->is_file) + break; + else if (file_priority && cur_dir->is_file && !new_dir->is_file) + continue; + + if (flags.t) { + if (compare_time(new_dir, cur_dir)) + break; + } + else + if (compare_name(new_dir->name, cur_dir->name)) + break; + } + t_list *new = ft_lstnew(new_dir); + if (!prev) + *head = new; + else + prev->next = new; + new->next = cur; +} + +static bool compare_name(char *s1, char *s2) { + i32 cmp = ft_strcmp(s1, s2); + if ((flags.r && cmp > 0) || (!flags.r && cmp < 0)) + return true; + return false; +} + +static bool compare_time(dir_t *dir1, dir_t *dir2) { + time_t dir1_sec = dir1->lstat.st_mtim.tv_sec; + time_t dir2_sec = dir2->lstat.st_mtim.tv_sec; + time_t dir1_nsec = dir1->lstat.st_mtim.tv_nsec; + time_t dir2_nsec = dir2->lstat.st_mtim.tv_nsec; + i64 diff_sec = dir1_sec - dir2_sec; + i64 diff_nsec = dir1_nsec - dir2_nsec; + if (diff_sec == 0 && diff_nsec == 0) { + if (compare_name(dir1->name, dir2->name)) + return true; + } + else if ((flags.r && (diff_sec < 0 || (diff_sec == 0 && diff_nsec < 0))) || + (!flags.r && (diff_sec > 0 || (diff_sec == 0 && diff_nsec > 0)))) + return true; + return false; +} + diff --git a/src/display.c b/src/display.c new file mode 100644 index 0000000..628bb62 --- /dev/null +++ b/src/display.c @@ -0,0 +1,96 @@ +static void display_recursive(dir_t *dir); + +void space_between_files(t_list **files, dir_t *file) { + + if (win.ws_col == 0) { + ft_printf("\n"); + return; + } + + u32 max = 0, i = 0, index_file = 0; + for (t_list *cur = *files; cur != nullptr; cur = cur->next) { + dir_t *cur_file = (dir_t*)(cur)->content; + max = MAX(ft_strlen(cur_file->name), max); + if (ft_strcmp(cur_file->name, file->name) == 0) + index_file = i; + i++; + } + u32 col = MAX(win.ws_col / max, 1); + u32 cal = index_file % col; + if (col >= i && index_file != i - 1) + ft_printf(" "); + else if (col >= i && index_file == i - 1) + ft_printf("\n"); + else if (cal == col - 1 || index_file == i - 1) + ft_printf("\n"); + else + for (i = 0; i < max - ft_strlen(file->name) + 1; i++) + ft_printf(" "); +} + +void +display_name(dir_t *dir) { + ft_printf("%s", dir->name); +} + +void +display_directory(dir_t *dir) { + if (flags.R) { + if (!dir->is_file) + display_recursive(dir); + } + else { + t_list **files = get_all_in(dir); + display_files(files); + free_files(files); + } +} + +i32 +display_files(t_list **files) { + i32 drawed = 0; + if (flags.l) + return display_files_stat(files); + else { + for (t_list *cur = *files; cur != nullptr; cur = cur->next) { + dir_t *dir = (dir_t*)(cur)->content; + display_name(dir); + drawed++; + if (cur->next != nullptr) + space_between_files(files, dir); + } + if (drawed > 0) + ft_printf("\n"); + } + return drawed; +} + +static void +to_print_return_of_line() { + static int need_to_return_of_line = 0; + if (!need_to_return_of_line) + need_to_return_of_line = 1; + else { + ft_printf("\n"); + } +} + +static void +display_recursive(dir_t *dir) { + if (dir->is_file) + return; + + to_print_return_of_line(); + ft_printf("%s:\n", dir->path); + t_list **files = get_all_in(dir); + display_files(files); + for (t_list *cur = *files; cur != nullptr; cur = cur->next) { + dir_t *cur_dir = (dir_t*)cur->content; + if (!cur_dir->is_file + && ft_strcmp(".", cur_dir->name) != 0 + && ft_strcmp("..", cur_dir->name) != 0) + display_recursive(cur_dir); + } + free_files(files); +} + diff --git a/src/display_stat.c b/src/display_stat.c new file mode 100644 index 0000000..93a5c95 --- /dev/null +++ b/src/display_stat.c @@ -0,0 +1,129 @@ +static void display_type(dir_t *dir); +static void display_permission(dir_t *dir); +static void display_size(dir_t *dir, i32 max_size); +static void display_date(dir_t *dir); +static void display_path(dir_t *dir); + +i32 +display_files_stat(t_list **files) { + if (!files) + return 0; + if (ft_lstsize(*files) <= 0) { + ft_printf("total 0\n"); + return 0; + } + + + i32 max_size = ft_get_size(((dir_t*)(*files)->content)->lstat.st_size); + i32 total = 0; + t_list *cur; + for (cur = *files; cur != nullptr; cur = cur->next) { + dir_t *dir = (dir_t*)(cur)->content; + max_size = MAX(ft_get_size(dir->lstat.st_size), max_size); + total += dir->lstat.st_blocks; + } + + ft_printf("total %d\n", total / 2); + + i32 drawed = 0; + for (cur = *files; cur != nullptr; cur = cur->next) { + dir_t *dir = (dir_t*)(cur)->content; + display_single_stat(dir, max_size); + drawed++; + ft_printf("\n"); + } + return drawed; +} + +void +display_single_stat(dir_t *dir, i32 max_size) { + if (!dir) + return; + display_type(dir); + display_permission(dir); + ft_printf(" "); + ft_printf("%d", dir->lstat.st_nlink); + ft_printf(" "); + if (dir->psswd) + ft_printf("%s", dir->psswd->pw_name); + ft_printf(" "); + if (dir->grp) + ft_printf("%s", dir->grp->gr_name); + ft_printf(" "); + display_size(dir, max_size); + ft_printf(" "); + display_date(dir); + ft_printf(" "); + display_name(dir); + if (S_ISLNK(dir->lstat.st_mode)) + display_path(dir); +} + +static void +display_type(dir_t *dir) { + if (!dir) + return; + if (S_ISLNK(dir->lstat.st_mode)) + ft_printf("l"); + else if (!dir->is_file) + ft_printf("d"); + else if (S_ISSOCK(dir->lstat.st_mode)) + ft_printf("s"); + else if (S_ISFIFO(dir->lstat.st_mode)) + ft_printf("p"); + else if (S_ISCHR(dir->lstat.st_mode)) + ft_printf("c"); + else if (S_ISBLK(dir->lstat.st_mode)) + ft_printf("b"); + else + ft_printf("-"); +} + +static void +display_permission(dir_t *dir) { + if (!dir) + return; + char buf[10]; + strmode(dir->stat.st_mode, buf); + ft_printf("%s", buf); +} + +static void +display_size(dir_t *dir, i32 max_size) { + if (!dir) + return; + i32 len = ft_get_size(dir->lstat.st_size); + + for (int i = max_size - len; i > 0; i--) + ft_printf(" "); + ft_printf("%d", dir->lstat.st_size); +} + +static void +display_date(dir_t *dir) { + if (!dir) + return; + struct timespec last_edit = dir->lstat.st_mtim; + char *base_time_str = ctime(&last_edit.tv_sec); + if (!base_time_str) + return; + + char *time_str = ft_substr(base_time_str, 4, ft_strlen(base_time_str) - 14); + if (!time_str) + return; + ft_printf(time_str); + + free(time_str); +} + +static void +display_path(dir_t *dir) { + if (!dir || !dir->path) + return; + char buf[512] = {[0 ... 511] = 0}; + i32 error = readlink(dir->path, buf, dir->lstat.st_size); + if (error == -1) + return; + ft_printf(" -> %s", buf); +} + diff --git a/src/free.c b/src/free.c new file mode 100644 index 0000000..096040f --- /dev/null +++ b/src/free.c @@ -0,0 +1,15 @@ +void +free_files(t_list **files) { + for (t_list *cur = *files; cur != nullptr;) { + dir_t *file = (dir_t*)cur->content; + if (!file->is_file) + closedir(file->dir); + free(file->path); + free(file); + + t_list *next = cur->next; + free(cur); + cur = next; + } + free(files); +} diff --git a/src/main.c b/src/main.c index 4e1f7d4..68eeb46 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,48 @@ -int main(int argc, char **argv) { +flags_t flags = {false, false, false, false, false, false, + {-1, -1}}; +struct winsize win; - if (argc < 2) - return 1; +int +main(int argc, char **argv) { - flags_t flags = get_flags(argv); - if (flags.error[0] != -1) { - ft_printf_fd(2, "ls: invalid line width: \'%s\'", - &argv[flags.error[0]][flags.error[1]]); - return 2; + if (argc > 1) { + get_flags(argv); + if (flags.error[0] != -1) { + ft_printf_fd(2, "ft_ls: invalid option -- \'%s\'\n", + &argv[flags.error[0]][flags.error[1]]); + return 2; + } } - display_flags(flags); - //ft_ls(flags); + ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); + errno = 0; - return 0; + t_list **files = ft_calloc(ft_strslen(argv) + 1, sizeof(t_list*)); + t_list **dirs = ft_calloc(ft_strslen(argv) + 1, sizeof(t_list*)); + i32 max_size = 0, len = 0, error = 0; + parsing(argv, &files, &dirs, &max_size, &len, &error); + + if (len == 0 && error == 0) + add_sort(dirs, get_directory_files("."), true); + + i32 left = len; + if (ft_lstsize(*files) > 0) + left -= display_files(files); + free_files(files); + + if (left != len && left > 0) + ft_printf("\n"); + + for (t_list *cur = *dirs; cur != nullptr; cur = cur->next) { + dir_t *dir = (dir_t*)cur->content; + if (len > 1 && !flags.R) + ft_printf("%s:\n", dir->path); + display_directory(dir); + if (left > 1) + ft_printf("\n"); + left--; + } + free_files(dirs); + + return error; } diff --git a/src/parsing.c b/src/parsing.c index 8cc4466..d540e0d 100644 --- a/src/parsing.c +++ b/src/parsing.c @@ -1,10 +1,10 @@ -flags_t get_flags(char **argv) { - flags_t flags = {false, false, false, false, false, - {-1, -1}}; - - for (int i = 1; argv[i] != NULL; i++) { +void +get_flags(char **argv) { + for (i32 i = 1; argv[i] != nullptr; i++) { + if (ft_strcmp(argv[i], "--") == 0) + return; if (argv[i][0] == '-') { - for (int j = 1; argv[i][j] != '\0'; j++) { + for (i32 j = 1; argv[i][j] != '\0'; j++) { if (argv[i][j] == 'l') flags.l = true; else if (argv[i][j] == 'a') @@ -18,27 +18,82 @@ flags_t get_flags(char **argv) { else { flags.error[0] = i; flags.error[1] = j; - return flags; + + return ; } } } } - - return flags; } -void display_flags(flags_t flags) { - ft_printf("l: %b; a: %b; R: %b; r: %b; t: %b\n", - flags.l, flags.a, flags.R, flags.r, flags.t); -} - -char **get_files(char **argv) { - - char **files = ft_calloc(ft_strslen(argv), sizeof(char*)); - - for (int i = 1; argv[i] != NULL; i++) { - if (argv[i][0] == '-') { +void +parsing(char **argv, t_list ***files, t_list ***dirs, i32 *max_size, i32 *len, i32 *error) { + for (i32 i = 0; argv[i + 1] != nullptr; i++) { + if (ft_strcmp(argv[i + 1], "--") == 0) { + flags.dashdash = true; + continue; } + dir_t *dir = get_directory_files(argv[i + 1]); + if (dir != nullptr) { + (*len)++; + if (dir->is_file) { + *max_size = MAX(ft_get_size(dir->lstat.st_size), *max_size); + add_sort(*files, dir, true); + } + else + add_sort(*dirs, dir, true); + } + else if (errno > 0) + *error = 2; } + flags.dashdash = false; } +static void* +free_dir_return_null(dir_t *dir) { + free(dir->path); + free(dir); + return nullptr; +} + +dir_t * +get_directory_files(char *path) { + dir_t *dir = nullptr; + + if (!flags.dashdash) + if (path[0] == '-' && ft_strlen(path) != 1) + return nullptr; + + dir = ft_calloc(1, sizeof(dir_t)); + dir->path = ft_strdup(path); + dir->name = dir->path; + stat(path, &dir->stat); + lstat(path, &dir->lstat); + dir->psswd = getpwuid(dir->stat.st_uid); + if (!dir->psswd) + return free_dir_return_null(dir); + + dir->grp = getgrgid(dir->psswd->pw_gid); + if (!dir->grp) + return free_dir_return_null(dir); + + if (S_ISLNK(dir->lstat.st_mode)) { + dir->is_file = true; + return dir; + } + + dir->dir = opendir(path); + if (dir->dir == nullptr) { + if (errno == EACCES) + ft_printf_fd(2, "Permission denied\n"); + else if (errno == ENOENT) + ft_printf_fd(2, "ft_ls: cannot access '%s': No such file or directory\n", path); + else if (errno == ENOTDIR) { + dir->is_file = true; + return dir; + } + return free_dir_return_null(dir); + } + + return dir; +}