From 6c97f1251c65310ead57c3688018544c71d09c30 Mon Sep 17 00:00:00 2001 From: Gregory Date: Fri, 31 Mar 2017 18:21:24 +0300 Subject: [PATCH] working -l flag --- CMakeLists.txt | 2 +- inc/ft_ls.h | 25 +++--- libft/Makefile | 3 +- libft/ft_num_len.c | 16 ++++ libft/includes/libft.h | 2 + src/ft_ls.c | 186 +++++++++++++++++++++++++++-------------- src/main.c | 11 ++- src/output.c | 123 +++++++++++++++++++-------- 8 files changed, 255 insertions(+), 113 deletions(-) create mode 100644 libft/ft_num_len.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 036e8e7..a9f8c85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ set(SOURCE_FILES src/flags.c src/sort.c src/output.c - src/error.c libft/ft_strcmp_lex.c) # sources + src/error.c) # sources add_executable(ft_ls ${SOURCE_FILES}) # compilation diff --git a/inc/ft_ls.h b/inc/ft_ls.h index 378ed0b..0205cc9 100644 --- a/inc/ft_ls.h +++ b/inc/ft_ls.h @@ -25,9 +25,6 @@ # include # include -# define FILES 0 -# define DIRS 1 - typedef struct s_flags { int l; @@ -39,19 +36,26 @@ typedef struct s_flags int abn; } t_flags; +typedef struct s_col_len +{ + int link_col; + int name_col; + int size_col; + int group_col; +} t_col_len; + + typedef struct s_dir_elm { char *elm_name; - char *parent_dir; - char *a_time_str; - int size; + char *m_time; char *g_name; char *u_name; - int links; char *attr_str; int link_fd; struct stat *stat_buf_struc; t_flags *flags; + t_col_len columns_len; } t_dir_elm; typedef struct s_ft_ls @@ -63,13 +67,14 @@ typedef struct s_ft_ls int no_ops; int first_print; t_flags *flgs; + t_col_len *padding; } t_ft_ls; -void ft_ls(t_ft_ls *s_ls); +void ft_ls(t_ft_ls s_ls); void ft_ls_fil(t_ft_ls *s_ls, char *full_path); -void ft_ls_dir(t_ft_ls *s_ls, char *full_path); +void ft_ls_dir(t_ft_ls s_ls, char *full_path); int parse_input(int ac, char **av, t_ft_ls *ft_ls_strct); @@ -79,7 +84,7 @@ void fill_path_lst(t_list **path_lst, char *path); void sort_files(t_list **del, t_flags *flgs); void sort_dirs(t_list **dirs, t_flags *flgs); -void output(t_ft_ls *s_ls); +void output(t_ft_ls s_ls); void print_full_path(t_ft_ls *s_ls, char *path); int chck_flgs(char *flg, t_flags *flgs); diff --git a/libft/Makefile b/libft/Makefile index a8f440d..019865a 100644 --- a/libft/Makefile +++ b/libft/Makefile @@ -82,7 +82,8 @@ SRC = ft_memset.c \ \ ft_realloc.c \ ft_read_file.c \ - get_next_line.c + get_next_line.c \ + ft_num_len.c OBJ = $(SRC:.c=.o) INC = -I ./includes/ diff --git a/libft/ft_num_len.c b/libft/ft_num_len.c new file mode 100644 index 0000000..1e43c58 --- /dev/null +++ b/libft/ft_num_len.c @@ -0,0 +1,16 @@ +#include "libft.h" + +int ft_num_len(long num) +{ + int len; + + len = 1; + if (num > 9) + while (num) + { + num /= 10; + if (num) + len++; + } + return (len); +} \ No newline at end of file diff --git a/libft/includes/libft.h b/libft/includes/libft.h index cd8ad9a..80bd4ca 100644 --- a/libft/includes/libft.h +++ b/libft/includes/libft.h @@ -113,4 +113,6 @@ void *ft_realloc(void *old, unsigned int new_size, char *ft_read_file(const int fd); int get_next_line(const int fd, char **line); +int ft_num_len(long num); + #endif diff --git a/src/ft_ls.c b/src/ft_ls.c index e6ca76e..5dde385 100644 --- a/src/ft_ls.c +++ b/src/ft_ls.c @@ -26,6 +26,105 @@ char *get_full_path(char *path, char *dir_ent_name) return (ft_strdup(dir_ent_name)); } + +char get_file_type(t_dir_elm *d_elm) +{ + char ch; + + ch = '-'; + if (S_ISDIR(d_elm->stat_buf_struc->st_mode)) + ch = 'd'; + if (S_ISLNK(d_elm->stat_buf_struc->st_mode)) + ch = 'l'; + if (S_ISFIFO(d_elm->stat_buf_struc->st_mode)) + ch = 'p'; + if (S_ISSOCK(d_elm->stat_buf_struc->st_mode)) + ch = 's'; + if (S_ISBLK(d_elm->stat_buf_struc->st_mode)) + ch = 'b'; + if (S_ISCHR(d_elm->stat_buf_struc->st_mode)) + ch = 'c'; + return (ch); +} + +void get_file_permissions(char *attr_str, t_dir_elm *d_elm) +{ + struct stat *st; + char r; + char w; + char x; + char f; + + r = 'r'; + w = 'w'; + x = 'x'; + f = '-'; + st = d_elm->stat_buf_struc; + attr_str[0] = (st->st_mode & S_IRUSR) ? r : f; + attr_str[1] = (st->st_mode & S_IWUSR) ? w : f; + attr_str[2] = (st->st_mode & S_IXUSR) ? x : f; + attr_str[3] = (st->st_mode & S_IRGRP) ? r : f; + attr_str[4] = (st->st_mode & S_IWGRP) ? w : f; + attr_str[5] = (st->st_mode & S_IXGRP) ? x : f; + attr_str[6] = (st->st_mode & S_IROTH) ? r : f; + attr_str[7] = (st->st_mode & S_IWOTH) ? w : f; + attr_str[8] = (st->st_mode & S_IXOTH) ? x : f; +} + +char *get_attr(t_dir_elm *d_elm) +{ + char *attr_str; + + attr_str = ft_memalloc(sizeof(11)); + + attr_str[10] = '\0'; + attr_str[0] = get_file_type(d_elm); + get_file_permissions(attr_str + 1, d_elm); + return (attr_str); +} + +char *get_time(t_dir_elm *d_elm) +{ + char *time; + char *time_tmp; + + time_tmp = ctime(&(d_elm->stat_buf_struc->st_mtim.tv_sec)); + time_tmp[16] = 0; + time = ft_strdup(time_tmp + 4); + return (time); +} + +void get_padding(t_ft_ls *s_ls, t_dir_elm *d_elem) +{ + int links_len; + int name_len; + int group_len; + int size_len; + + links_len = ft_num_len(d_elem->stat_buf_struc->st_nlink); + name_len = (int)ft_strlen(d_elem->u_name); + group_len = (int)ft_strlen(d_elem->g_name); + size_len = ft_num_len(d_elem->stat_buf_struc->st_size); + if (links_len > s_ls->padding->link_col) + s_ls->padding->link_col = links_len; + if (name_len > s_ls->padding->name_col) + s_ls->padding->name_col = name_len; + if (group_len > s_ls->padding->group_col) + s_ls->padding->group_col = group_len; + if (size_len > s_ls->padding->size_col) + s_ls->padding->size_col = size_len; +} + +void get_info_from_stat(t_dir_elm *dir_elm, t_ft_ls *s_ls) +{ + dir_elm->attr_str = get_attr(dir_elm); + dir_elm->u_name = ft_strdup(getpwuid(dir_elm->stat_buf_struc->st_uid)->pw_name); + dir_elm->g_name = ft_strdup(getgrgid(dir_elm->stat_buf_struc->st_gid)->gr_name); + dir_elm->m_time = get_time(dir_elm); + get_padding(s_ls, dir_elm); +} + + void init_file_meta_lst(t_ft_ls *s_ls, char *full_path) { t_dir_elm de; @@ -36,53 +135,17 @@ void init_file_meta_lst(t_ft_ls *s_ls, char *full_path) s_ls->lst_fil_meta = NULL; while (lst_rnr) { - de.flags = s_ls->flgs; de.stat_buf_struc = malloc(sizeof(struct stat)); de.elm_name = (char *)lst_rnr->content; tmp_path = get_full_path(full_path, de.elm_name); stat(tmp_path, de.stat_buf_struc); + get_info_from_stat(&de, s_ls); ft_lstadd(&s_ls->lst_fil_meta, ft_lstnew(&de, sizeof(t_dir_elm))); free(tmp_path); lst_rnr = lst_rnr->next; } } -//void init_dir_ent_lst(t_list **fil_ent_lst, t_list *dirs, t_flags *flgs) -//{ -// -// t_dir_elm de; -// -// while (dirs) -// { -// de.flags = flgs; -// de.stat_buf_struc = malloc(sizeof(struct stat)); -// de.elm_name = (char *)dirs->content; -// de.full_path =(char *)dirs->content; -// stat(de.full_path, de.stat_buf_struc); -// ft_lstadd(fil_ent_lst, ft_lstnew(&de, sizeof(t_dir_elm))); -// dirs = dirs->next; -// } -//} -// -//void init_dir_ent_list(t_list **del, t_flags *flgs, char *path) -//{ -// DIR *dp; -// t_dir_elm de; -// struct dirent *dir_ent; -// -// dp = opendir(path); -// while ((dir_ent = readdir(dp))) -// { -// de.flags = flgs; -// de.stat_buf_struc = malloc(sizeof(struct stat)); -// de.elm_name = ft_strdup(dir_ent->d_name); -// de.full_path = get_full_path(path, dir_ent->d_name); -// stat(de.full_path, de.stat_buf_struc); -// ft_lstadd(del, ft_lstnew(&de, sizeof(t_dir_elm))); -// } -// closedir(dp); -//} - t_list *extract_filenames_from_dir(char *full_path) { DIR *dp; @@ -98,40 +161,41 @@ t_list *extract_filenames_from_dir(char *full_path) return (dir_files); } -t_ft_ls *extract_dirs_from_filenames(t_ft_ls *s_ls, char *full_path) +t_ft_ls extract_dirs_from_filenames(t_ft_ls s_ls, char *full_path) { char *full_path_with_file; - s_ls->lst_dir_paths = NULL; - while (s_ls->lst_fil_names) + s_ls.lst_dir_paths = NULL; + while (s_ls.lst_fil_names) { - full_path_with_file = get_full_path(full_path, s_ls->lst_fil_names->content); - if (opendir(full_path_with_file) && (ft_strcmp(s_ls->lst_fil_names->content, ".") != 0) && (ft_strcmp(s_ls->lst_fil_names->content, "..") != 0)) - { - if (s_ls->flgs->a) - fill_path_lst(&s_ls->lst_dir_paths, s_ls->lst_fil_names->content); - else if (*(char *)s_ls->lst_fil_names->content != '.') - fill_path_lst(&s_ls->lst_dir_paths, s_ls->lst_fil_names->content); - } - s_ls->lst_fil_names = s_ls->lst_fil_names->next; + full_path_with_file = get_full_path(full_path, s_ls.lst_fil_names->content); + if (access(full_path_with_file, F_OK)) + if (access(full_path_with_file, R_OK) && (ft_strcmp(s_ls.lst_fil_names->content, ".") != 0) && (ft_strcmp(s_ls.lst_fil_names->content, "..") != 0)) + { + if (s_ls.flgs->a) + fill_path_lst(&s_ls.lst_dir_paths, s_ls.lst_fil_names->content); + else if (*(char *)s_ls.lst_fil_names->content != '.') + fill_path_lst(&s_ls.lst_dir_paths, s_ls.lst_fil_names->content); + } + s_ls.lst_fil_names = s_ls.lst_fil_names->next; free(full_path_with_file); } return (s_ls); } -void ft_ls_dir(t_ft_ls *s_ls, char *full_path) +void ft_ls_dir(t_ft_ls s_ls, char *full_path) { char *full_path_next; t_list *tmp_rnr; - sort_dirs(&s_ls->lst_dir_paths, s_ls->flgs); - tmp_rnr = s_ls->lst_dir_paths; + sort_dirs(&s_ls.lst_dir_paths, s_ls.flgs); + tmp_rnr = s_ls.lst_dir_paths; while (tmp_rnr) { full_path_next = get_full_path(full_path, tmp_rnr->content); - s_ls->lst_fil_names = extract_filenames_from_dir(full_path_next); - ft_ls_fil(s_ls, full_path_next); - if (s_ls->flgs->R) + s_ls.lst_fil_names = extract_filenames_from_dir(full_path_next); + ft_ls_fil(&s_ls, full_path_next); + if (s_ls.flgs->R) ft_ls_dir(extract_dirs_from_filenames(s_ls, full_path_next), full_path_next); tmp_rnr = tmp_rnr->next; } @@ -142,15 +206,15 @@ void ft_ls_fil(t_ft_ls *s_ls, char *full_path) init_file_meta_lst(s_ls, full_path); sort_files(&s_ls->lst_fil_meta, s_ls->flgs); - if (full_path && !s_ls->one_dir && !s_ls->no_ops) + if ((!s_ls->one_dir && !s_ls->no_ops) || s_ls->flgs->R) print_full_path(s_ls, full_path); - output(s_ls); + output(*s_ls); } -void ft_ls(t_ft_ls *s_ls) +void ft_ls(t_ft_ls s_ls) { - if (s_ls->lst_fil_names) - ft_ls_fil(s_ls, NULL); - if (s_ls->lst_dir_paths) + if (s_ls.lst_fil_names) + ft_ls_fil(&s_ls, NULL); + if (s_ls.lst_dir_paths) ft_ls_dir(s_ls, NULL); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5acbf90..62d5f4c 100644 --- a/src/main.c +++ b/src/main.c @@ -15,23 +15,26 @@ int main(int argc, char **argv) { static t_flags flgs; + static t_col_len padding; static t_ft_ls s_ls; int no_errors_and_valid_args; s_ls.flgs = &flgs; + s_ls.padding = &padding; s_ls.first_print = 1; no_errors_and_valid_args = parse_input(argc, argv, &s_ls); if (s_ls.lst_dir_paths || s_ls.lst_fil_names) { - if (ft_lst_len(s_ls.lst_dir_paths) == 1 && ft_lst_len(s_ls.lst_fil_names) == 0 && !s_ls.flgs->R) - s_ls.one_dir = 1; - ft_ls(&s_ls); + if (ft_lst_len(s_ls.lst_fil_names) == 0 && ft_lst_len(s_ls.lst_dir_paths) == 1) + if (!s_ls.flgs->R) + s_ls.one_dir = 1; + ft_ls(s_ls); } else if (no_errors_and_valid_args) { s_ls.no_ops = 1; fill_path_lst(&s_ls.lst_dir_paths, "./"); - ft_ls(&s_ls); + ft_ls(s_ls); } return 0; } diff --git a/src/output.c b/src/output.c index d622b63..188ff94 100644 --- a/src/output.c +++ b/src/output.c @@ -1,19 +1,5 @@ #include "ft_ls.h" -void column_or_line(t_list *entity) -{ - t_dir_elm *d_elm; - - d_elm = (t_dir_elm *)entity->content; - ft_putstr(d_elm->elm_name); - if (!entity->next) - ft_putstr("\n"); - else if (d_elm->flags->col) - ft_putstr("\n"); - else - ft_putstr(" "); -} - int is_hidden(char *path) { char *begin; @@ -39,33 +25,46 @@ int is_hidden(char *path) return (0); } -int out(t_list *entity) -{ - t_dir_elm *d_elm; - - d_elm = (t_dir_elm *)entity->content; - if (d_elm->flags->a) - { - column_or_line(entity); - return (1); - } - else - if (!is_hidden(d_elm->elm_name)) - { - column_or_line(entity); - return (1); - } - return (0); -} +//int out(t_list *entity) +//{ +// t_dir_elm *d_elm; +// +// d_elm = (t_dir_elm *)entity->content; +// if (d_elm->flags->a) +// { +// column_or_line(entity); +// return (1); +// } +// else +// if (!is_hidden(d_elm->elm_name)) +// { +// column_or_line(entity); +// return (1); +// } +// return (0); +//} void print_full_path(t_ft_ls *s_ls, char *path) { char *cur_dir_semi_n; + char *n_cur_dir; - s_ls = s_ls; - cur_dir_semi_n = ft_strjoin(path, ":\n"); + n_cur_dir = NULL; + if (!path) + s_ls->first_print = 0; + if (s_ls->first_print) + { + cur_dir_semi_n = ft_strjoin(path, ":\n"); + s_ls->first_print = 0; + } + else + { + n_cur_dir = ft_strjoin("\n", path); + cur_dir_semi_n = ft_strjoin(n_cur_dir, ":\n"); + } ft_putstr(cur_dir_semi_n); free(cur_dir_semi_n); + free(n_cur_dir); } @@ -83,8 +82,60 @@ int ft_lstiter_ret(t_list *lst, int (*f)(t_list *elem)) return (i); } -void output(t_ft_ls *s_ls) +void put_spaces(int num) { - ft_lstiter_ret(s_ls->lst_fil_meta, out); + while (num--) + ft_putstr(" "); +} + +void format_string(t_dir_elm *d_elem, t_col_len *padd) +{ + int links_len; + int owner_len; + int group_len; + int size_len; + + links_len = ft_num_len(d_elem->stat_buf_struc->st_nlink); + owner_len = (int)ft_strlen(d_elem->u_name); + group_len = (int)ft_strlen(d_elem->g_name); + size_len = ft_num_len(d_elem->stat_buf_struc->st_size); + ft_putstr(d_elem->attr_str); + put_spaces(padd->link_col - links_len + 1); + ft_putnbr((int)d_elem->stat_buf_struc->st_nlink); + ft_putstr(" "); + ft_putstr(d_elem->u_name); + put_spaces(padd->name_col - owner_len + 1); + ft_putstr(d_elem->g_name); + put_spaces(padd->group_col - group_len); + put_spaces(padd->size_col - size_len + 1); + ft_putnbr((int)d_elem->stat_buf_struc->st_size); + ft_putstr(" "); + ft_putstr(d_elem->m_time); + ft_putstr(" "); + ft_putstr(d_elem->elm_name); ft_putstr("\n"); +} + +void long_output(t_ft_ls s_ls) +{ + t_list *lst_rnr; + + lst_rnr = s_ls.lst_fil_meta; + while (lst_rnr) + { + format_string(lst_rnr->content, s_ls.padding); + lst_rnr = lst_rnr->next; + } +} + +void output(t_ft_ls s_ls) +{ + if (s_ls.flgs->l) + long_output(s_ls); +// else if (s_ls.flgs->col) +// one_column(s_ls); +// else +// mult_column(s_ls); + +// ft_lstiter_ret(s_ls.lst_fil_meta, out); } \ No newline at end of file