#include #include #include #include #include #include #include #include #include #include #include #include "make_path.h" #include "get_stat.h" unsigned int a_flag; unsigned int l_flag; void PrintPerm(struct stat sb) { if (S_ISDIR(sb.st_mode)) printf("d"); else if (S_ISLNK(sb.st_mode)) printf("l"); else if (S_ISCHR(sb.st_mode)) printf("c"); else if (S_ISFIFO(sb.st_mode)) printf("p"); else if (S_ISSOCK(sb.st_mode)) printf("s"); else printf("-"); printf("%c%c%c", (sb.st_mode & S_IRUSR) ? 'r' : '-', (sb.st_mode & S_IWUSR) ? 'w' : '-', (sb.st_mode & S_IXUSR) ? 'x' : '-'); printf("%c%c%c", (sb.st_mode & S_IRGRP) ? 'r' : '-', (sb.st_mode & S_IWGRP) ? 'w' : '-', (sb.st_mode & S_IXGRP) ? 'x' : '-'); printf("%c%c%c", (sb.st_mode & S_IROTH) ? 'r' : '-', (sb.st_mode & S_IWOTH) ? 'w' : '-', (sb.st_mode & S_IXOTH) ? 'x' : '-'); } char *fileflag(const char *path) { struct stat sb; if (mu_get_lstat("ls", path, &sb)) return " "; if (S_ISDIR(sb.st_mode)) return "/"; else if ((sb.st_mode & S_IXUSR) || (sb.st_mode & S_IXGRP) || (sb.st_mode & S_IXOTH)) return "*"; else return " "; } void PrintInfo(struct stat sb, const char *filename) { /* Permissions */ PrintPerm(sb); /* Date */ struct tm *tm = localtime(&sb.st_mtime); char date[14]; if (strftime(date, sizeof(date), "%b %d %H:%M", tm) == 0) { fprintf(stderr, "ls: strftime()\n"); return; } /* Group and user name */ struct passwd *pw = getpwuid(sb.st_uid); struct group *gr = getgrgid(sb.st_gid); printf(" %s %s %jd %s %s%s\n", (pw != 0) ? pw->pw_name : "nobody", (gr != 0) ? gr->gr_name : "nobody", (uintmax_t)sb.st_size, date, filename, fileflag(filename)); } int list(const char *path, int label) { struct stat sb; if (mu_get_lstat("ls", path, &sb)) return 1; /* If its file */ if (!S_ISDIR(sb.st_mode)) { if (l_flag) PrintInfo(sb, path); else puts(path); return 0; } /* Make label */ if (label) printf("\n%s: \n", path); /* Open and print dir */ DIR *dp = opendir(path); if (dp == NULL) { fprintf(stderr, "ls: %s: %s\n", path, strerror(errno)); return 1; } struct dirent *ep; while ((ep = readdir(dp)) != NULL) { if (ep->d_name[0] == '.' && !a_flag) continue; char *full_path = mu_make_path("ls", path, ep->d_name); if (full_path == NULL) return 1; if (l_flag) { if (mu_get_lstat("ls", full_path, &sb)) return 1; PrintInfo(sb, full_path); } else printf("%s%s\n", ep->d_name, fileflag(full_path)); free(full_path); } closedir(dp); printf("\n"); return 0; } int main(const int argc, const char **argv) { int i; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; else if (!strcmp(argv[i], "-a")) a_flag = 1; else if (!strcmp(argv[i], "-l")) l_flag = 1; else if (!strcmp(argv[i], "--help")) { printf("ls [-a show hidden files] [-l use a long listing format] [Path]\n"); return 0; } } if (i == argc) return list(".", 0); if (i == argc - 1) return list(argv[i], 0); else for (; i < argc; i++) if (list(argv[i], 1)) return 1; return 0; }