ls finish, need more test
This commit is contained in:
parent
411659db94
commit
69aefc764d
|
@ -7,3 +7,5 @@
|
|||
-iquoteinc
|
||||
-iquotelib
|
||||
-g
|
||||
-D_POSIX_C_SOURCE=200809L
|
||||
-D_DEFAULT_SOURCE
|
||||
|
|
48
inc/main.h
48
inc/main.h
|
@ -1,6 +1,13 @@
|
|||
#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 {
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
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)
|
||||
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);
|
||||
|
|
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 len_dest;
|
||||
size_t len_src;
|
||||
size_t len_dest, len_src;
|
||||
|
||||
if (size == 0)
|
||||
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"
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# include <unistd.h>
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
# include <stdarg.h>
|
||||
|
||||
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);
|
||||
|
|
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);
|
||||
}
|
53
src/main.c
53
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue