#include #include #include #include #include #include #include #include #include #include #include unsigned int a_flag; unsigned int l_flag; void PrintPerm(struct stat sb) { printf("%c", (S_ISDIR(sb.st_mode)) ? 'd' : '-'); 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' : '-'); } int list(const char *path, int label) { struct stat sb; if (stat(path, &sb)) { fprintf(stderr, "ls: unable to stat %s: %s\n", path, strerror(errno)); return 1; } /* If its file */ if (!S_ISDIR(sb.st_mode)) { puts(path); return 0; } /* Make label */ if (label) printf("\n%s: \n", path); if (chdir(path)) { fprintf(stderr, "ls: %s: %s\n", path, strerror(errno)); return 1; } /* Open and print dir */ DIR *dp = opendir("."); if (dp == NULL) return 1; struct dirent *ep; while ((ep = readdir(dp)) != NULL) { if (ep->d_name[0] == '.' && !a_flag) continue; if (l_flag) { if (lstat(ep->d_name, &sb) == -1) { fprintf(stderr, "ls: lstat()\n"); return 1; } /* 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 1; } /* Group and user name */ struct passwd *pw = getpwuid(sb.st_uid); struct group *gr = getgrgid(sb.st_gid); printf(" %s %s %jd %s %s\n", (pw != 0) ? pw->pw_name : "nobody", (gr != 0) ? gr->gr_name : "nobody", (uintmax_t)sb.st_size, date, ep->d_name); } else printf("%s ", ep->d_name); } 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], "-h")) { printf("ls [-a (Show hidden files)] [-l (use a long listing format (month / day / hour:min))] [Path]\n"); return 0; } } if (i == argc) return list(".", 0); if (i == argc - 1) return list(argv[i], 0); else for (int i = 1; i < argc; i++) if (list(argv[i], 1)) return 1; return 0; }