ls/ls.c
2024-10-20 21:27:53 -04:00

147 lines
2.7 KiB
C

#define _POSIX_C_SOURCE 200809L
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
void ls_ent(const char *path);
void do_regfile(const char *path, const struct stat *sb);
void do_dir(const char *path, const struct stat *sb);
void do_symlink(const char *path, const struct stat *sb);
void do_blockdev(const char *path, const struct stat *sb);
void do_char(const char *path, const struct stat *sb);
void do_fifo(const char *path, const struct stat *sb);
void do_socket(const char *path, const struct stat *sb);
void do_unknown(const char *path, const struct stat *sb);
int
main(int argc, char *argv[])
{
int i;
if (argc == 1) {
ls_ent(".");
} else {
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
/* argparsing */
} else {
ls_ent(argv[i]);
}
}
}
return 0;
}
void
ls_ent(const char *path)
{
struct stat sb;
if (lstat(path, &sb) == -1) {
err(1, "Failed to stat %s", path);
}
if (S_ISREG(sb.st_mode)) {
do_regfile(path, &sb);
} else if (S_ISDIR(sb.st_mode)) {
do_dir(path, &sb);
} else if (S_ISLNK(sb.st_mode)) {
do_symlink(path, &sb);
} else if (S_ISCHR(sb.st_mode)) {
do_char(path, &sb);
} else if (S_ISFIFO(sb.st_mode)) {
do_fifo(path, &sb);
} else if (S_ISSOCK(sb.st_mode)) {
do_socket(path, &sb);
} else {
do_unknown(path, &sb);
}
}
void
do_regfile(const char *path, const struct stat *sb)
{
(void)sb;
printf("reg: %s\n", path);
}
void
do_dir(const char *path, const struct stat *sb)
{
DIR *d;
struct dirent *dir;
char full_path[PATH_MAX];
(void)sb;
d = opendir(path);
if (!d) {
err(1, "Failed to open dir: %s", path);
}
printf("dir: %s\n", path);
while ((dir = readdir(d))) {
/* avoids infinite recursion :( */
if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) {
continue;
}
snprintf(full_path, sizeof(full_path), "%s/%s", path, dir->d_name);
ls_ent(full_path);
}
closedir(d);
}
void
do_symlink(const char *path, const struct stat *sb)
{
(void)sb;
printf("sym: %s\n", path);
}
void
do_blockdev(const char *path, const struct stat *sb)
{
(void)sb;
printf("blk: %s\n", path);
}
void
do_char(const char *path, const struct stat *sb)
{
(void)sb;
printf("char: %s\n", path);
}
void
do_fifo(const char *path, const struct stat *sb)
{
(void)sb;
printf("fifo: %s\n", path);
}
void
do_socket(const char *path, const struct stat *sb)
{
(void)sb;
printf("sock: %s\n", path);
}
void
do_unknown(const char *path, const struct stat *sb)
{
(void)sb;
printf("wtf: %s\n", path);
}