diff --git a/ls/.tags b/ls/.tags index aac50cdc..f39fbe7c 100644 --- a/ls/.tags +++ b/ls/.tags @@ -4,10 +4,18 @@ ft_ent_get_dirs src/lib_dirents.c /^t_list *ft_ent_get_dirs(t_list *ent)$/ ft_ent_handle src/lib_dirents.c /^void ft_ent_handle(t_list **ent, t_lsdata *topdir,/ ft_error_dir src/lib_error.c /^void ft_error_dir(char *s)$/ ft_error_option src/lib_error.c /^void ft_error_option(char c)$/ -ft_ls_l src/lib_print.c /^void ft_ls_l(t_lsdata *data)$/ +ft_ls_long src/lib_ls_long.c /^int ft_ls_long(t_list *ent)$/ +ft_ls_long_date src/lib_ls_long.c /^void ft_ls_long_date(struct stat *stat)$/ +ft_ls_long_lnk src/lib_ls_long_misc.c /^void ft_ls_long_lnk(t_lsdata *data)$/ +ft_ls_long_middle src/lib_ls_long.c /^int ft_ls_long_middle(struct stat *stat, t_pads */ +ft_ls_long_pads src/lib_ls_long_misc.c /^int ft_ls_long_pads(t_list *ent, t_pads *pads)$/ +ft_ls_long_rights src/lib_ls_long.c /^void ft_ls_long_rights(int st_mode)$/ +ft_ls_long_total src/lib_ls_long_misc.c /^int ft_ls_long_total(t_list *ent)$/ +ft_ls_long_type src/lib_ls_long.c /^void ft_ls_long_type(unsigned char d_type)$/ +ft_ls_long_xattr src/lib_ls_long_misc.c /^int ft_ls_long_xattr(char *path)$/ ft_ls_print src/lib_print.c /^void ft_ls_print(t_list *ent, char *opts, t_lsdata/ -ft_ls_print_dirents src/lib_print.c /^void ft_ls_print_dirents(t_list *ent, char *opts)$/ ft_ls_print_header src/lib_print.c /^void ft_ls_print_header(char *dirname)$/ +ft_ls_short src/lib_print.c /^void ft_ls_short(t_list *ent)$/ ft_lsdata_cmp0 src/lib_lsdata.c /^int ft_lsdata_cmp0(t_lsdata *dat1, char *dataref)/ ft_lsdata_cmp_name src/lib_lsdata.c /^int ft_lsdata_cmp_name(t_lsdata *dat1, t_lsdata */ ft_lsdata_cmp_time src/lib_lsdata.c /^int ft_lsdata_cmp_time(t_lsdata *dat1, t_lsdata */ diff --git a/ls/includes/ftls.h b/ls/includes/ftls.h index 743fa291..7a5f5aa0 100644 --- a/ls/includes/ftls.h +++ b/ls/includes/ftls.h @@ -7,6 +7,9 @@ # include # include # include +# include +# include +# include typedef struct s_lsdata { @@ -15,6 +18,14 @@ typedef struct s_lsdata struct dirent *dirent; } t_lsdata; +typedef struct s_pads +{ + int nlink; + int name; + int gr_name; + int size; +} t_pads; + int ft_parse_ls_options(int ac, char **av, char *opts); void ft_parse_ls(int ac, char **av, t_list **dir, t_list **ent, char *opts); @@ -28,9 +39,19 @@ t_list *ft_ent_get_dirs(t_list *ent); t_list *ft_dir_get_ents(t_lsdata *dir); +void ft_ls_short(t_list *ent); +int ft_ls_long(t_list *ent); +int ft_ls_long_total(t_list *ent); +int ft_ls_long_pads(t_list *ent, t_pads *pads); +void ft_ls_long_type(unsigned char d_type); +void ft_ls_long_rights(int st_mode); +int ft_ls_long_xattr(char *path); +int ft_ls_long_middle(struct stat *stat, t_pads *pads); +void ft_ls_long_date(struct stat *stat); +void ft_ls_long_lnk(t_lsdata *data); + void ft_ls_print(t_list *ent, char *opts, t_lsdata *topdir); void ft_ls_print_header(char *dirname); -void ft_ls_print_dirents(t_list *ent, char *opts); void ft_error_option(char c); void ft_error_dir(char *s); diff --git a/ls/libft b/ls/libft index 8bfb8fb4..d351b97f 160000 --- a/ls/libft +++ b/ls/libft @@ -1 +1 @@ -Subproject commit 8bfb8fb462d914837fb76e95141cdce59b3c99f9 +Subproject commit d351b97f35fbb2551cfaab92322cac8524112486 diff --git a/ls/src/lib_dirs.c b/ls/src/lib_dirs.c index 8be8745f..e41fc71a 100644 --- a/ls/src/lib_dirs.c +++ b/ls/src/lib_dirs.c @@ -15,7 +15,7 @@ t_list *ft_dir_get_ents(t_lsdata *topdir) data.path = ft_strjoin(data.path, dirent->d_name); /* ft_printf("looking at file: %s\n", data.path); */ /* ft_printf("stat ret: %i\n", stat(data.path, &data.stat)); */ - stat(data.path, &data.stat); + lstat(data.path, &data.stat); data.dirent = dirent; /* char *date = ctime(&data.stat.st_mtime); */ /* date[ft_strlen(date) - 1] = '\0'; */ diff --git a/ls/src/lib_ls_long.c b/ls/src/lib_ls_long.c new file mode 100644 index 00000000..eb32f922 --- /dev/null +++ b/ls/src/lib_ls_long.c @@ -0,0 +1,106 @@ +#include "ftls.h" + +int ft_ls_long(t_list *ent) +{ + t_lsdata *data; + struct stat stat; + struct dirent *dirent; + t_pads pads = {0, 0, 0, 0}; + + ft_ls_long_total(ent); + if (ft_ls_long_pads(ent, &pads)) + return (1); + while (ent) + { + data = ent->content; + stat = data->stat; + dirent = data->dirent; + ent = ent->next; + + ft_ls_long_type(dirent->d_type); + ft_ls_long_rights(stat.st_mode); + if (ft_ls_long_xattr(dirent->d_name)) + return (1); + if (ft_ls_long_middle(&stat, &pads)) + return (1); + ft_ls_long_date(&stat); + ft_printf(" %s", data->dirent->d_name); + ft_ls_long_lnk(data); + } + return (0); +} + +int ft_ls_long_middle(struct stat *stat, t_pads *pads) +{ + struct passwd *pwd; + struct group *grp; + + if ((pwd = getpwuid(stat->st_uid)) == NULL) + return (1); + if ((grp = getgrgid(stat->st_gid)) == NULL) + return (1); + printf(" %*hu", pads->nlink, stat->st_nlink); + printf(" %-*s", pads->name, pwd->pw_name); + printf(" %-*s", pads->gr_name, grp->gr_name); + printf(" %*lld", pads->size, stat->st_size); + fflush(stdout); + return (0); +} + +void ft_ls_long_date(struct stat *stat) +{ + char *date; + char *day; + char *month; + char *time; + + date = ctime(&stat->st_mtime); + month = ft_strsub(date, 4, 3); + month[0] += 32; + day = ft_strsub(date, 8, 2); + time = ft_time_isrecent(stat->st_mtime) + ? ft_strsub(date, 11, 5) + : ft_strsub(date, 20, 4); + ft_printf(" %s %s %5s", day, month, time); +} + +void ft_ls_long_type(unsigned char d_type) +{ + char type; + + type = '\0'; + type = d_type == DT_REG ? '-' : type; + type = d_type == DT_DIR ? 'd' : type; + type = d_type == DT_FIFO ? 'p' : type; + type = d_type == DT_SOCK ? 's' : type; + type = d_type == DT_CHR ? 'c' : type; + type = d_type == DT_BLK ? 'b' : type; + type = d_type == DT_LNK ? 'l' : type; + ft_printf("%c", type); +} + +void ft_ls_long_rights(int st_mode) +{ + int i; + char *rights; + + i = 0; + rights = ft_itoa_base(st_mode, "01", ""); + rights = rights + ft_strlen(rights) - 9; + while (rights[i]) + { + if (rights[i] == '0') + rights[i] = '-'; + else + { + if (i % 3 == 0) + rights[i] = 'r'; + else if (i % 3 == 1) + rights[i] = 'w'; + else if (i % 3 == 2) + rights[i] = 'x'; + } + i++; + } + ft_printf("%s", rights); +} diff --git a/ls/src/lib_ls_long_misc.c b/ls/src/lib_ls_long_misc.c new file mode 100644 index 00000000..b7ad6607 --- /dev/null +++ b/ls/src/lib_ls_long_misc.c @@ -0,0 +1,73 @@ +#include "ftls.h" + +void ft_ls_long_lnk(t_lsdata *data) +{ + struct stat stat; + struct dirent *dirent; + + dirent = data->dirent; + stat = data->stat; + + if (dirent->d_type == DT_LNK) + ft_printf(" -> unknown\n"); + else + ft_printf("\n"); +} + +int ft_ls_long_xattr(char *path) +{ + int n; + char x; + + if ((n = ft_xattr_count(path)) == -1) + return (1); + x = n > 0 ? '@' : '\0'; + ft_printf("%1c", x); + return (0); +} + +int ft_ls_long_total(t_list *ent) +{ + struct stat stat; + t_lsdata *data; + int total; + + total = 0; + while (ent) + { + data = ent->content; + stat = data->stat; + /* dirent = data->dirent; */ + ent = ent->next; + + total += stat.st_blocks; + } + ft_printf("total %i\n", total); + return (0); +} + +int ft_ls_long_pads(t_list *ent, t_pads *pads) +{ + struct passwd *pwd; + struct group *grp; + struct stat stat; + t_lsdata *data; + + while (ent) + { + data = ent->content; + stat = data->stat; + /* dirent = data->dirent; */ + ent = ent->next; + + if ((pwd = getpwuid(stat.st_uid)) == NULL) + return (1); + if ((grp = getgrgid(stat.st_gid)) == NULL) + return (1); + pads->nlink = FT_MAX(pads->nlink, (int)ft_uilen(stat.st_nlink)); + pads->name = FT_MAX(pads->name, (int)ft_strlen(pwd->pw_name)); + pads->gr_name = FT_MAX(pads->gr_name, (int)ft_strlen(grp->gr_name)); + pads->size = FT_MAX(pads->size, (int)ft_ilen(stat.st_size)); + } + return (0); +} diff --git a/ls/src/lib_parse.c b/ls/src/lib_parse.c index 251ec558..7853f8c0 100644 --- a/ls/src/lib_parse.c +++ b/ls/src/lib_parse.c @@ -16,13 +16,13 @@ void ft_parse_ls(int ac, char **av, t_list **dir, t_list **ent, char *opts) if (i == ac) { data.path = ft_strdup("."); - ft_printf("stat ret: %i\n", stat(data.path, &data.stat)); + /* ft_printf("stat ret: %i\n", stat(data.path, &data.stat)); */ ft_lstadd(dir, ft_lstnew(&data, sizeof(data))); } while (i < ac) { data.path = ft_strdup(av[i]); - if (stat(data.path, &data.stat) < 0) + if (lstat(data.path, &data.stat) < 0) { ft_error_dir(data.path); } diff --git a/ls/src/lib_print.c b/ls/src/lib_print.c index 833db00c..5ada278e 100644 --- a/ls/src/lib_print.c +++ b/ls/src/lib_print.c @@ -8,21 +8,16 @@ void ft_ls_print(t_list *ent, char *opts, t_lsdata *topdir) ft_ls_print_header(topdir->path); else *opt = '.'; - ft_ls_print_dirents(ent, opts); - ft_printf("\n"); + if (ent) + { + if (ft_strchr(opts, 'l')) + ft_ls_long(ent); + else + ft_ls_short(ent); + } } -void ft_ls_l(t_lsdata *data) -{ - char *date; - - /* date = ctime(&data->stat.st_mtimespec.tv_sec); */ - date = ctime(&data->stat.st_mtime); - date[ft_strlen(date) - 1] = '\0'; - ft_printf("%s %s\n", date, data->dirent->d_name); -} - -void ft_ls_print_dirents(t_list *ent, char *opts) +void ft_ls_short(t_list *ent) { t_lsdata *data; struct dirent *dirent; @@ -31,11 +26,8 @@ void ft_ls_print_dirents(t_list *ent, char *opts) { data = ent->content; dirent = data->dirent; - if (ft_strchr(opts, 'l')) - ft_ls_l(data); - else - ft_printf("%s\n", dirent->d_name); ent = ent->next; + ft_printf("%s\n", dirent->d_name); } } diff --git a/ls/src/main.c b/ls/src/main.c index 22dbf306..04b40cae 100644 --- a/ls/src/main.c +++ b/ls/src/main.c @@ -38,6 +38,8 @@ int main(int ac, char **av) ft_lst_merge(&dir_r, dir); dir = dir_r; } + if (dir) + ft_printf("\n"); /* ft_lsdata_print(dir); */ } return (0);