ls finish, need more test
This commit is contained in:
parent
411659db94
commit
69aefc764d
|
@ -7,3 +7,5 @@
|
||||||
-iquoteinc
|
-iquoteinc
|
||||||
-iquotelib
|
-iquotelib
|
||||||
-g
|
-g
|
||||||
|
-D_POSIX_C_SOURCE=200809L
|
||||||
|
-D_DEFAULT_SOURCE
|
||||||
|
|
48
inc/main.h
48
inc/main.h
|
@ -1,6 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool l;
|
bool l;
|
||||||
|
@ -8,8 +15,43 @@ typedef struct {
|
||||||
bool R;
|
bool R;
|
||||||
bool r;
|
bool r;
|
||||||
bool t;
|
bool t;
|
||||||
|
bool dashdash;
|
||||||
int error[2];
|
int error[2];
|
||||||
} flags_t;
|
} flags_t;
|
||||||
|
|
||||||
flags_t get_flags(char **argv);
|
typedef struct {
|
||||||
void display_flags(flags_t flags);
|
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);
|
||||||
|
|
|
@ -69,7 +69,7 @@ u32 ft_printf(const char *str, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, str);
|
va_start(args, str);
|
||||||
u32 count = ft_vdprintf(0, str, args);
|
u32 count = ft_vdprintf(1, str, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
25
lib/libft/ft_lstremove_back.c
Normal file
25
lib/libft/ft_lstremove_back.c
Normal file
|
@ -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;
|
||||||
|
}
|
13
lib/libft/ft_lstremove_front.c
Normal file
13
lib/libft/ft_lstremove_front.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -17,8 +17,8 @@ u32 ft_putnbr_fd(i64 n, int fd)
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
ft_putchar_fd('-', fd);
|
ft_putchar_fd('-', fd);
|
||||||
n = ABS(n);
|
n = ABS(n);
|
||||||
int len = ft_get_size(n) + 1;
|
int len = ft_get_size(n);
|
||||||
while (--len > 1)
|
while (--len > 0)
|
||||||
ft_putchar_fd(n / ft_power(10, len) % 10 + 48, fd);
|
ft_putchar_fd(n / ft_power(10, len) % 10 + 48, fd);
|
||||||
ft_putchar_fd(n % 10 + 48, fd);
|
ft_putchar_fd(n % 10 + 48, fd);
|
||||||
return ft_get_size(n);
|
return ft_get_size(n);
|
||||||
|
|
6
lib/libft/ft_strcat.c
Normal file
6
lib/libft/ft_strcat.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "libft.h"
|
||||||
|
|
||||||
|
char *ft_strcat(char *dest, const char *src) {
|
||||||
|
ft_strcpy(dest + ft_strlen(dest), src);
|
||||||
|
return dest;
|
||||||
|
}
|
7
lib/libft/ft_strcmp.c
Normal file
7
lib/libft/ft_strcmp.c
Normal file
|
@ -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];
|
||||||
|
}
|
11
lib/libft/ft_strcpy.c
Normal file
11
lib/libft/ft_strcpy.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
size_t ft_strlcat(char *dest, const char *src, size_t size)
|
size_t ft_strlcat(char *dest, const char *src, size_t size)
|
||||||
{
|
{
|
||||||
size_t len_dest;
|
size_t len_dest, len_src;
|
||||||
size_t len_src;
|
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return (ft_strlen(src));
|
return (ft_strlen(src));
|
||||||
|
|
19
lib/libft/ft_strlcats.c
Normal file
19
lib/libft/ft_strlcats.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -12,19 +12,14 @@
|
||||||
|
|
||||||
#include "libft.h"
|
#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;
|
u32 i = 0;
|
||||||
if (size)
|
for (; i < size && src[i] != '\0'; i++)
|
||||||
{
|
|
||||||
while (i < size - 1 && src[i] != '\0')
|
|
||||||
{
|
|
||||||
dest[i] = src[i];
|
dest[i] = src[i];
|
||||||
i++;
|
|
||||||
}
|
|
||||||
dest[i] = '\0';
|
dest[i] = '\0';
|
||||||
}
|
|
||||||
return (ft_strlen(src));
|
return (ft_strlen(src));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ char *ft_substr(char const *s, unsigned int start, size_t len)
|
||||||
size = 0;
|
size = 0;
|
||||||
else if ((unsigned long)size > len)
|
else if ((unsigned long)size > len)
|
||||||
size = len;
|
size = len;
|
||||||
new_s = malloc(size + 1);
|
new_s = ft_calloc(size + 2, 1);
|
||||||
if (new_s == NULL)
|
if (new_s == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (start <= ft_strlen(s))
|
if (start <= ft_strlen(s))
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
|
# include <stdarg.h>
|
||||||
|
|
||||||
typedef struct s_list
|
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_memmove(void *dest, const void *src, size_t s);
|
||||||
void *ft_memchr(const void *memory_block, int searched_char, size_t size);
|
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);
|
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_strnstr(const char *big, const char *little, size_t len);
|
||||||
char *ft_strchr(const char *str, int search);
|
char *ft_strchr(const char *str, int search);
|
||||||
char *ft_strrchr(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);
|
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);
|
size_t ft_strlcat(char *dest, const char *src, size_t size);
|
||||||
|
char *ft_strlcats(u32 nbr_str, ...);
|
||||||
char *ft_strdup(const char *src);
|
char *ft_strdup(const char *src);
|
||||||
int ft_atoi(const char *nptr);
|
int ft_atoi(const char *nptr);
|
||||||
char **ft_split(char const *s, char c);
|
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);
|
char *ft_substr(char const *s, unsigned int start, size_t len);
|
||||||
t_list *ft_lstnew(void *content);
|
t_list *ft_lstnew(void *content);
|
||||||
void ft_lstadd_front(t_list **lst, t_list *new);
|
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);
|
int ft_lstsize(t_list *lst);
|
||||||
t_list *ft_lstlast(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_lstdelone(t_list *lst, void (*del)(void*));
|
||||||
void ft_lstclear(t_list **lst, void (*del)(void*));
|
void ft_lstclear(t_list **lst, void (*del)(void*));
|
||||||
void ft_lstiter(t_list *lst, void (*f)(void *));
|
void ft_lstiter(t_list *lst, void (*f)(void *));
|
||||||
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(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);
|
int ft_atoi_check(const char *nptr);
|
||||||
u32 ft_strslen(char **strs);
|
u32 ft_strslen(char **strs);
|
||||||
|
|
102
src/directory.c
Normal file
102
src/directory.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
|
96
src/display.c
Normal file
96
src/display.c
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
|
129
src/display_stat.c
Normal file
129
src/display_stat.c
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
|
15
src/free.c
Normal file
15
src/free.c
Normal file
|
@ -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);
|
||||||
|
}
|
51
src/main.c
51
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)
|
int
|
||||||
return 1;
|
main(int argc, char **argv) {
|
||||||
|
|
||||||
flags_t flags = get_flags(argv);
|
if (argc > 1) {
|
||||||
|
get_flags(argv);
|
||||||
if (flags.error[0] != -1) {
|
if (flags.error[0] != -1) {
|
||||||
ft_printf_fd(2, "ls: invalid line width: \'%s\'",
|
ft_printf_fd(2, "ft_ls: invalid option -- \'%s\'\n",
|
||||||
&argv[flags.error[0]][flags.error[1]]);
|
&argv[flags.error[0]][flags.error[1]]);
|
||||||
return 2;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
flags_t get_flags(char **argv) {
|
void
|
||||||
flags_t flags = {false, false, false, false, false,
|
get_flags(char **argv) {
|
||||||
{-1, -1}};
|
for (i32 i = 1; argv[i] != nullptr; i++) {
|
||||||
|
if (ft_strcmp(argv[i], "--") == 0)
|
||||||
for (int i = 1; argv[i] != NULL; i++) {
|
return;
|
||||||
if (argv[i][0] == '-') {
|
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')
|
if (argv[i][j] == 'l')
|
||||||
flags.l = true;
|
flags.l = true;
|
||||||
else if (argv[i][j] == 'a')
|
else if (argv[i][j] == 'a')
|
||||||
|
@ -18,27 +18,82 @@ flags_t get_flags(char **argv) {
|
||||||
else {
|
else {
|
||||||
flags.error[0] = i;
|
flags.error[0] = i;
|
||||||
flags.error[1] = j;
|
flags.error[1] = j;
|
||||||
return flags;
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return flags;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_flags(flags_t flags) {
|
static void*
|
||||||
ft_printf("l: %b; a: %b; R: %b; r: %b; t: %b\n",
|
free_dir_return_null(dir_t *dir) {
|
||||||
flags.l, flags.a, flags.R, flags.r, flags.t);
|
free(dir->path);
|
||||||
|
free(dir);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **get_files(char **argv) {
|
dir_t *
|
||||||
|
get_directory_files(char *path) {
|
||||||
|
dir_t *dir = nullptr;
|
||||||
|
|
||||||
char **files = ft_calloc(ft_strslen(argv), sizeof(char*));
|
if (!flags.dashdash)
|
||||||
|
if (path[0] == '-' && ft_strlen(path) != 1)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
for (int i = 1; argv[i] != NULL; i++) {
|
dir = ft_calloc(1, sizeof(dir_t));
|
||||||
if (argv[i][0] == '-') {
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue