diff --git a/src/ls/Makefile b/src/ls/Makefile index 4c12572..7eb0f83 100644 --- a/src/ls/Makefile +++ b/src/ls/Makefile @@ -4,6 +4,5 @@ SRC := main.c SRC += list_directories.c SRC += print_info.c SRC += recursive_walk.c -SRC += sort_entries.c include ../shared.mk diff --git a/src/ls/list_directories.c b/src/ls/list_directories.c index 69769fc..45fe1ea 100644 --- a/src/ls/list_directories.c +++ b/src/ls/list_directories.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -21,14 +20,12 @@ void get_file_info(const char *path, entry_t *entry) entry->group = getgrgid(entry->stat.st_gid); } -static -int read_directory(dirbuff_t *db, DIR *dir, char flags) +static __attribute__((nonnull)) +size_t read_directory(dirbuff_t *db, DIR *dir, char flags) { static char path[PATH_MAX]; - int i = 0; + size_t i = 0; - if (dir == NULL) - return -1; for (struct dirent *dirent = readdir(dir); dirent; dirent = readdir(dir)) { if (dirent->d_name[0] == '.' && ~flags & F_ALL_FILES) continue; @@ -66,38 +63,44 @@ void print_error(char *dirname) } static -int read_arg(dirbuff_t *db, char flags) +int compare_names(entry_t const *leftp, entry_t const *rightp) +{ + return strcoll(leftp->name, rightp->name); +} + +static +int compare_times(entry_t const *leftp, entry_t const *rightp) +{ + return (int)( + rightp->stat.st_mtim.tv_sec + - leftp->stat.st_mtim.tv_sec + ); +} + +int list_dir(dirbuff_t *db, char flags) { struct stat fi; - int count = 1; + size_t count = 1; DIR *dir; - db->is_file = 0; - if (stat(db->name, &fi) < 0) { - print_error(db->name); - return -1; - } - if (S_ISDIR(fi.st_mode) && ~flags & F_DIRECTORY) { + if (stat(db->name, &fi) < 0) + return print_error(db->name), -1; + + db->is_file = S_ISDIR(fi.st_mode) && ~flags & F_DIRECTORY; + if (db->is_file) { dir = opendir(db->name); count = read_directory(db, dir, flags); closedir(dir); } else { strcpy(db->entries[0].name, db->name); get_file_info(db->name, &db->entries[0]); - db->is_file = 1; } - return count; -} - -int list_dir(dirbuff_t *db, char flags) -{ - int count = read_arg(db, flags); - if (count == -1) - return -1; - sort_entries(db->entries, count); + qsort(db->entries, count, + sizeof *db->entries, (__compar_fn_t)&compare_names); if (flags & F_SORT_TIME) - sort_entries_by_time(db->entries, count); + qsort(db->entries, count, + sizeof *db->entries, (__compar_fn_t)&compare_times); if (flags & (F_SHOW_DIRS | F_RECURSIVE) && !db->is_file) printf("%s:\n", db->name); print_entries(db->entries, count, flags); diff --git a/src/ls/ls.h b/src/ls/ls.h index 6ae17fe..8a97628 100644 --- a/src/ls/ls.h +++ b/src/ls/ls.h @@ -1,6 +1,7 @@ #ifndef MY_LS_H #define MY_LS_H + #include #include #define ZERO_OR(expr, default) ((!!(expr)) * default) @@ -33,28 +34,25 @@ typedef struct { typedef struct { char *name; entry_t *entries; - int size; - int is_file; + size_t size; + bool is_file; } dirbuff_t; -inline +inline __attribute__((const)) int stridx(const char *str, char c) { for (const char *p = str; *p != '\0'; p++) if (*p == c) - return p - str; + return (int)(p - str); return -1; } char *strdup(char const *s); int list_dir(dirbuff_t *db, char flags); -int recurse(dirbuff_t *db, int count, char flags); +size_t recurse(dirbuff_t *db, size_t count, char flags); -void print_entries(entry_t *entry, int count, char flags); +void print_entries(entry_t *entry, size_t count, char flags); char *path_concat(char *dest, char *basepath, char *suffix); -void sort_entries(entry_t *entries, int count); -void sort_entries_by_time(entry_t *entries, int count); - #endif diff --git a/src/ls/main.c b/src/ls/main.c index f1cc724..e8f9e0c 100644 --- a/src/ls/main.c +++ b/src/ls/main.c @@ -2,8 +2,8 @@ #include "ls.h" -static const char *FLAGLIST = "alRdrt"; -static char DEFAULT_LOCATION[2] = "."; +static const char FLAGLIST[] = "alRdrt"; +static char DEFAULT_LOCATION[] = "."; static char compose_flaglist(int argc, char **argv) diff --git a/src/ls/print_info.c b/src/ls/print_info.c index 060ff5e..fcfb0a2 100644 --- a/src/ls/print_info.c +++ b/src/ls/print_info.c @@ -12,6 +12,8 @@ #include "ls.h" +typedef unsigned char uchar; + static void get_file_right(char bits[], entry_t *entry) { @@ -19,15 +21,15 @@ void get_file_right(char bits[], entry_t *entry) mode_t mode = entry->stat.st_mode; static const char *s = "-rwx"; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IRUSR, 1)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IWUSR, 2)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IXUSR, 3)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IRGRP, 1)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IWGRP, 2)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IXGRP, 3)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IROTH, 1)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IWOTH, 2)]; - *bitsp++ = s[(unsigned char)ZERO_OR(mode & S_IXOTH, 3)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IRUSR, 1)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IWUSR, 2)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IXUSR, 3)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IRGRP, 1)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IWGRP, 2)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IXGRP, 3)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IROTH, 1)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IWOTH, 2)]; + *bitsp++ = s[(uchar)ZERO_OR(mode & S_IXOTH, 3)]; if (mode & S_ISUID) bits[1] = (mode & S_IXUSR) ? 's' : 'S'; if (mode & S_ISGID) @@ -56,11 +58,13 @@ char get_file_type(entry_t *entry) static char *get_creation_time(entry_t *entry) { - static char fmt[12]; + static char fmt[sizeof("Jan 01 00:00")]; char *ct = ctime(&entry->stat.st_mtim.tv_sec); time_t now = time(NULL); const int six_month_sec = 6 * 24 * 3600 * 31; + if (strlen(ct) < 24) + return NULL; if (entry->stat.st_mtim.tv_sec + six_month_sec < now) { strncpy(fmt, ct + 4, 7); strncpy(fmt + 7, ct + 19, 5); @@ -73,9 +77,9 @@ static void print_file_infos(entry_t *entry) { struct stat *fi = &entry->stat; - char perms[10] = { [0] = get_file_type(entry) }; - const char *owner = (entry->passwd == NULL) ? "?" : entry->passwd->pw_name; - const char *grp = (entry->group == NULL) ? "?" : entry->group->gr_name; + char perms[sizeof("-rwxr-xr-x")] = { [0] = get_file_type(entry) }; + char const *owner = (entry->passwd == NULL) ? "?" : entry->passwd->pw_name; + char const *grp = (entry->group == NULL) ? "?" : entry->group->gr_name; char *time = get_creation_time(entry); get_file_right(perms + 1, entry); @@ -87,7 +91,7 @@ void print_file_infos(entry_t *entry) printf(" %.12s ", time); } -void print_entries(entry_t *entry, int count, char flags) +void print_entries(entry_t *entry, size_t count, char flags) { int d; @@ -96,7 +100,7 @@ void print_entries(entry_t *entry, int count, char flags) entry += (count - 1); } else d = 1; - for (int i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { if (flags & F_LONG_FORM) print_file_infos(entry); printf("%s", entry->name); diff --git a/src/ls/recursive_walk.c b/src/ls/recursive_walk.c index 154764f..916a8c3 100644 --- a/src/ls/recursive_walk.c +++ b/src/ls/recursive_walk.c @@ -5,7 +5,7 @@ char *path_concat(char *dest, char *basepath, char *suffix) { - int written = 0; + unsigned long written = 0; strcpy(dest, basepath); written = strlen(basepath); @@ -19,14 +19,12 @@ char *path_concat(char *dest, char *basepath, char *suffix) return dest; } -static -int find_directories(char **dirs, dirbuff_t *db, int count) +static __attribute__((nonnull)) +size_t find_directories(char **dirs, dirbuff_t *db, size_t count) { - int found = 0; + size_t found = 0; - if (dirs == NULL) - return -1; - for (int i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { if (!strcmp(db->entries[i].name, ".") || !strcmp(db->entries[i].name, "..")) continue; @@ -38,21 +36,19 @@ int find_directories(char **dirs, dirbuff_t *db, int count) return found; } -int recurse(dirbuff_t *db, int count, char flags) +size_t recurse(dirbuff_t *db, size_t count, char flags) { static char path[PATH_MAX]; - int dirsize = strlen(db->name); + size_t dirsize = strlen(db->name); char **dirs = malloc(count * sizeof(char *)); - int j = find_directories(dirs, db, count); + size_t j = find_directories(dirs, db, count); - if (j == -1) - return -1; - for (int i = 0; i < j; i++) { + for (size_t i = 0; i < j; i++) { db->name = path_concat(path, db->name, dirs[i]); list_dir(db, flags); db->name[dirsize] = '\0'; } - for (int i = 0; i < j; i++) + for (size_t i = 0; i < j; i++) free(dirs[i]); free(dirs); return 0; diff --git a/src/ls/sort_entries.c b/src/ls/sort_entries.c deleted file mode 100644 index c96247d..0000000 --- a/src/ls/sort_entries.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -#include "ls.h" - -static -int compare_names(entry_t const *leftp, entry_t const *rightp) -{ - return strcoll(leftp->name, rightp->name); -} - -static -int compare_times(entry_t const *leftp, entry_t const *rightp) -{ - return rightp->stat.st_mtim.tv_sec - leftp->stat.st_mtim.tv_sec; -} - -void sort_entries(entry_t *entries, int count) -{ - qsort(entries, count, sizeof(*entries), (__compar_fn_t)&compare_names); -} - -void sort_entries_by_time(entry_t *entries, int count) -{ - qsort(entries, count, sizeof(*entries), (__compar_fn_t)&compare_times); -} diff --git a/src/ls/strdup.c b/src/ls/strdup.c index 13fc67a..12d056b 100644 --- a/src/ls/strdup.c +++ b/src/ls/strdup.c @@ -5,7 +5,7 @@ char *strdup(char const *s) { - int len = strlen(s); + size_t len = strlen(s); char *dupped = malloc(len + 1); strcpy(dupped, s);