feat(tools): better ls

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-09-07 11:31:36 +02:00
parent 8618a18754
commit 8fdb8beb12
11 changed files with 206 additions and 70 deletions

View file

@ -11,7 +11,7 @@ fs_dir_lookup(struct fs_inode *dp, const char *name, size_t *offset)
size_t idx; size_t idx;
struct stpdfs_dirent dirent; struct stpdfs_dirent dirent;
if (!(dp->inode.flags & STPDFS_S_IFDIR)) if ((dp->inode.flags & STPDFS_S_IFMT) != STPDFS_S_IFDIR)
{ {
errno = ENOTDIR; errno = ENOTDIR;
return (NULL); return (NULL);
@ -111,11 +111,11 @@ fs_dir_unlink(struct fs_inode *dp, const char *name)
} }
int int
fs_mkdir(struct fs_inode *dp, const char *name) fs_mkdir(struct fs_inode *dp, const char *name, uint16_t mode)
{ {
struct fs_inode *ndp; struct fs_inode *ndp;
if (!(dp->inode.mode & STPDFS_S_IFDIR)) if ((dp->inode.mode & STPDFS_S_IFMT) != STPDFS_S_IFDIR)
{ {
return (-1); return (-1);
} }
@ -125,7 +125,12 @@ fs_mkdir(struct fs_inode *dp, const char *name)
{ {
return (-1); return (-1);
} }
if (ndp->valid == 0)
{
fs_inode_read(ndp);
}
ndp->inode.mode = mode;
ndp->inode.mode |= STPDFS_S_IFDIR; ndp->inode.mode |= STPDFS_S_IFDIR;
fs_dir_link(ndp, ".", ndp->inum); fs_dir_link(ndp, ".", ndp->inum);

View file

@ -12,6 +12,6 @@ struct fs_dir {
struct fs_inode *fs_dir_lookup(struct fs_inode *dp, const char *name, size_t *offset); struct fs_inode *fs_dir_lookup(struct fs_inode *dp, const char *name, size_t *offset);
int fs_dir_link(struct fs_inode *dp, const char *name, uint32_t inum); int fs_dir_link(struct fs_inode *dp, const char *name, uint32_t inum);
int fs_dir_unlink(struct fs_inode *dp, const char *name); int fs_dir_unlink(struct fs_inode *dp, const char *name);
int fs_mkdir(struct fs_inode *dp, const char *name); int fs_mkdir(struct fs_inode *dp, const char *name, uint16_t mode);
#endif /* !FS_DIR_H */ #endif /* !FS_DIR_H */

View file

@ -1,6 +1,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include "inode.h" #include "inode.h"
#include "bio/bio.h" #include "bio/bio.h"
#include "stupidfs.h" #include "stupidfs.h"
@ -23,6 +24,8 @@ fs_inode_alloc(struct fs_super *super)
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0) if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
{ {
memset(dinode, 0, sizeof(struct stpdfs_inode)); memset(dinode, 0, sizeof(struct stpdfs_inode));
dinode->actime = time(NULL);
dinode->modtime = dinode->actime;
dinode->flags = STPDFS_INO_FLAG_ALOC; dinode->flags = STPDFS_INO_FLAG_ALOC;
fs_bio_bwrite(buff); fs_bio_bwrite(buff);
fs_bio_brelse(buff); fs_bio_brelse(buff);

View file

@ -6,7 +6,7 @@ bin_PROGRAMS = mkfs.stpd tools.stpd inspect.stpd
mkfs_stpd_SOURCES = mkfs/main.c mkfs_stpd_SOURCES = mkfs/main.c
mkfs_stpd_LDADD = ../libfs/libfs.a mkfs/bootsector.o mkfs_stpd_LDADD = ../libfs/libfs.a mkfs/bootsector.o
tools_stpd_SOURCES = tools/main.c tools/ls.c tools/copy.c tools/mkdir.c tools_stpd_SOURCES = tools/main.c tools/ls.c tools/copy.c tools/mkdir.c tools/rm.c
inspect_stpd_SOURCES = inspect/main.c inspect_stpd_SOURCES = inspect/main.c

View file

@ -158,6 +158,8 @@ mkfs()
rootip->valid = 1; rootip->valid = 1;
rootip->inode.gid = 0;
rootip->inode.uid = 0;
rootip->inode.modtime = time(NULL); rootip->inode.modtime = time(NULL);
rootip->inode.actime = time(NULL); rootip->inode.actime = time(NULL);
memset(rootip->inode.zones, 0, sizeof(uint32_t) * 10); memset(rootip->inode.zones, 0, sizeof(uint32_t) * 10);

View file

@ -22,6 +22,8 @@ static struct option long_options[] = {
{"image", required_argument, 0, 'i'}, {"image", required_argument, 0, 'i'},
{"uid", required_argument, 0, 'u'}, {"uid", required_argument, 0, 'u'},
{"gid", required_argument, 0, 'g'}, {"gid", required_argument, 0, 'g'},
{"mode", required_argument, 0, 'm'},
{"recursive", no_argument, 0, 'r'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
#endif /* HAVE_STRUCT_OPTION */ #endif /* HAVE_STRUCT_OPTION */
@ -31,6 +33,8 @@ static char *src = NULL;
static char *image = NULL; static char *image = NULL;
static int gid = -1; static int gid = -1;
static int uid = -1; static int uid = -1;
static int recursive = 0;
static int mode = -1;
extern char *prg_name; extern char *prg_name;
@ -43,7 +47,14 @@ usage(int retval)
} }
else else
{ {
printf("Usage: %s copy -i /dev/name source [dest]\n", prg_name); printf("Usage: %s copy -i /dev/name [OPTIONS]... SOURCE [DEST]\n", prg_name);
printf("Options:\n");
printf(" -i, --image <image> specify disk image\n");
printf(" -u, --uid <uid> XXX\n");
printf(" -g, --gid <gid> XXX\n");
printf(" -m, --mode <mode> XXX\n");
printf(" -r, --recursive XXX\n");
printf(" -h, --help display this menu\n");
} }
} }
@ -78,6 +89,7 @@ do_copy(void)
fs_inode_read(ip); fs_inode_read(ip);
} }
ip->inode.mode = st.st_mode; ip->inode.mode = st.st_mode;
if (uid >= 0) if (uid >= 0)
{ {
ip->inode.uid = uid; ip->inode.uid = uid;
@ -100,7 +112,6 @@ do_copy(void)
ip->inode.actime = st.st_atime; ip->inode.actime = st.st_atime;
ip->inode.flags = STPDFS_INO_FLAG_ALOC; ip->inode.flags = STPDFS_INO_FLAG_ALOC;
fs_inode_update(ip); fs_inode_update(ip);
fp = fopen(src, "rb"); fp = fopen(src, "rb");
@ -134,9 +145,9 @@ cmd_copy(int argc, char **argv)
int c; int c;
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION) #if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
while ((c = getopt_long(argc, argv, "hi:u:g:", long_options, &idx)) != EOF) while ((c = getopt_long(argc, argv, "hi:u:g:rm:", long_options, &idx)) != EOF)
#else #else
while ((c = getopt(argc, argv, "hi:u:g:")) != EOF) while ((c = getopt(argc, argv, "hi:u:g:rm:")) != EOF)
#endif #endif
{ {
switch (c) switch (c)
@ -157,6 +168,14 @@ cmd_copy(int argc, char **argv)
gid = atoi(optarg); gid = atoi(optarg);
break; break;
case 'm':
mode = strtol(optarg, NULL, 8);
break;
case 'r':
recursive = 1;
break;
default: default:
usage(EXIT_FAILURE); usage(EXIT_FAILURE);
break; break;

View file

@ -1,6 +1,7 @@
#include "libfs/inode.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -20,6 +21,9 @@ static struct option long_options[] = {
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"image", required_argument, 0, 'i'}, {"image", required_argument, 0, 'i'},
{"all", no_argument, 0, 'a'}, {"all", no_argument, 0, 'a'},
{"human-readable", no_argument, 0, 'H'},
{"si", no_argument, 0, 's'},
{"color", no_argument, 0, 'c'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
#endif /* HAVE_STRUCT_OPTION */ #endif /* HAVE_STRUCT_OPTION */
@ -27,6 +31,8 @@ static struct option long_options[] = {
static char *path = "/"; static char *path = "/";
static char *image = NULL; static char *image = NULL;
static int all = 0; static int all = 0;
static int human = 0;
static int color = 0;
extern char *prg_name; extern char *prg_name;
@ -39,10 +45,13 @@ usage(int retval)
} }
else else
{ {
printf("Usage: %s ls -i /dev/name [OPTIONS]... FILE...\n", prg_name); printf("Usage: %s ls -i /dev/name [OPTIONS]... [FILE]...\n", prg_name);
printf("Options:\n"); printf("Options:\n");
printf(" -i, --image <image> specify disk image.\n"); printf(" -i, --image <image> specify disk image\n");
printf(" -a, --all do not ignore entries starting with .\n"); printf(" -a, --all do not ignore entries starting with .\n");
printf(" --color colorize the output\n");
printf(" -H, --human-readable XXX\n");
printf(" --si XXX\n");
printf(" -h, --help display this menu\n"); printf(" -h, --help display this menu\n");
} }
@ -54,10 +63,14 @@ print_mode(struct fs_inode *ip)
{ {
char modebuff[] = "----------"; char modebuff[] = "----------";
if (ip->inode.mode & STPDFS_S_IFDIR) if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFDIR)
{ {
modebuff[0] = 'd'; modebuff[0] = 'd';
} }
if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFLNK)
{
modebuff[0] = 'l';
}
if (ip->inode.mode & STPDFS_S_IRUSR) if (ip->inode.mode & STPDFS_S_IRUSR)
{ {
@ -119,6 +132,69 @@ print_time(struct fs_inode *ip)
printf("%s ", timebuff); printf("%s ", timebuff);
} }
static void
print_size(struct fs_inode *ip)
{
uint32_t threshold;
double bytes;
int idx;
static const char *unit_si[] = {
"kB", "MB", "GB"
};
static const char *unit[] = {
"KiB", "MiB", "GiB"
};
if (!human)
{
printf("%5u ", ip->inode.size);
return;
}
threshold = (human > 1) ? 1000 : 1024;
if (ip->inode.size < threshold)
{
printf("%6u ", ip->inode.size);
return;
}
bytes = ip->inode.size;
idx = -1;
do {
bytes = round((bytes / threshold) * 10) / 10;
idx++;
} while (bytes >= threshold);
printf("%0.1f%s ", bytes, (human > 1) ? unit_si[idx] : unit[idx]);
}
static void
print_name(struct stpdfs_dirent *dirent, struct fs_inode *ip)
{
if (color)
{
if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFDIR)
{
printf("\033[01;34m");
}
else if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFLNK)
{
printf("\033[01;36m");
}
else if (ip->inode.mode & STPDFS_S_IXUSR)
{
printf("\033[01;32m");
}
}
printf("%s\n", dirent->filename);
if (color)
{
printf("\033[0m");
}
}
static void static void
print_dirent(struct fs_super *super, struct stpdfs_dirent *dirent) print_dirent(struct fs_super *super, struct stpdfs_dirent *dirent)
{ {
@ -132,11 +208,11 @@ print_dirent(struct fs_super *super, struct stpdfs_dirent *dirent)
print_mode(ip); print_mode(ip);
printf("%u ", ip->inode.nlink); printf("%u ", ip->inode.nlink);
printf("%3u %3u ", ip->inode.uid, ip->inode.gid); printf("%3u %3u ", ip->inode.uid, ip->inode.gid);
printf("%5u ", ip->inode.size); print_size(ip);
print_time(ip); print_time(ip);
printf("%s\n", dirent->filename); print_name(dirent, ip);
fs_inode_release(ip); fs_inode_release(ip);
} }
@ -190,9 +266,9 @@ cmd_ls(int argc, char **argv)
int c; int c;
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION) #if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
while ((c = getopt_long(argc, argv, "hi:a", long_options, &idx)) != EOF) while ((c = getopt_long(argc, argv, "hi:aH", long_options, &idx)) != EOF)
#else #else
while ((c = getopt(argc, argv, "hi:a")) != EOF) while ((c = getopt(argc, argv, "hi:aH")) != EOF)
#endif #endif
{ {
switch (c) switch (c)
@ -209,6 +285,18 @@ cmd_ls(int argc, char **argv)
all = 1; all = 1;
break; break;
case 'H':
human = 1;
break;
case 's':
human = 2;
break;
case 'c':
color = 1;
break;
default: default:
usage(EXIT_FAILURE); usage(EXIT_FAILURE);
break; break;
@ -225,6 +313,5 @@ cmd_ls(int argc, char **argv)
path = argv[optind]; path = argv[optind];
} }
return (do_ls()); return (do_ls());
} }

View file

@ -21,6 +21,7 @@ struct command commands[] = {
{"ls", &cmd_ls}, {"ls", &cmd_ls},
{"copy", &cmd_copy}, {"copy", &cmd_copy},
{"mkdir", &cmd_mkdir}, {"mkdir", &cmd_mkdir},
{"rm", &cmd_rm},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -1,4 +1,3 @@
#include "libfs/inode.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -28,7 +27,7 @@ static struct option long_options[] = {
#endif /* HAVE_STRUCT_OPTION */ #endif /* HAVE_STRUCT_OPTION */
static char *image = NULL; static char *image = NULL;
static mode_t mode = STPDFS_S_IFDIR | STPDFS_S_IRUSR | STPDFS_S_IWUSR | STPDFS_S_IXUSR | STPDFS_S_IRGRP | STPDFS_S_IXGRP | STPDFS_S_IXOTH; static mode_t mode = STPDFS_S_IRUSR | STPDFS_S_IWUSR | STPDFS_S_IXUSR | STPDFS_S_IRGRP | STPDFS_S_IXGRP | STPDFS_S_IXOTH;
static int parents = 0; static int parents = 0;
static int verbose = 0; static int verbose = 0;
@ -54,7 +53,7 @@ usage(int retval)
} }
int int
do_mkdir(struct fs_inode *root, char *path) do_mkdir(struct fs_super *super, char *path)
{ {
char *dir; char *dir;
char *tmp; char *tmp;
@ -62,9 +61,27 @@ do_mkdir(struct fs_inode *root, char *path)
struct fs_inode *subdp; struct fs_inode *subdp;
dir = strtok(path, "/"); dir = strtok(path, "/");
dp = fs_inode_get(super, STPDFS_ROOTINO);
if (dp->valid == 0)
{
fs_inode_read(dp);
}
while (dir != NULL) while (dir != NULL)
{ {
tmp = strtok(NULL, "/"); tmp = strtok(NULL, "/");
subdp = fs_dir_lookup(dp, dir, NULL);
if (tmp == NULL)
{
if (subdp != NULL)
{
fprintf(stderr, "mkdir: cannot create directory '%s': File exists", dir);
return (EXIT_FAILURE);
}
fs_mkdir(dp, dir, mode);
return (EXIT_SUCCESS);
}
printf("%s\n", dir); printf("%s\n", dir);
dir = tmp; dir = tmp;
} }
@ -131,17 +148,11 @@ cmd_mkdir(int argc, char **argv)
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
root = fs_inode_get(&super, STPDFS_ROOTINO);
if (root->valid == 0)
{
fs_inode_read(root);
}
status = EXIT_SUCCESS; status = EXIT_SUCCESS;
while (optind < argc) while (optind < argc)
{ {
if (do_mkdir(root, argv[optind++])) if (do_mkdir(&super, argv[optind++]))
{ {
status = EXIT_FAILURE; status = EXIT_FAILURE;
break; break;

7
tools/tools/rm.c Normal file
View file

@ -0,0 +1,7 @@
#include <stdlib.h>
int
cmd_rm(int argc, char **argv)
{
return (EXIT_FAILURE);
}

View file

@ -4,5 +4,6 @@
int cmd_ls(int argc, char **argv); int cmd_ls(int argc, char **argv);
int cmd_copy(int argc, char **argv); int cmd_copy(int argc, char **argv);
int cmd_mkdir(int argc, char **argv); int cmd_mkdir(int argc, char **argv);
int cmd_rm(int argc, char **argv);
#endif /* !TOOLS_H */ #endif /* !TOOLS_H */