feat(tools): better ls
This commit is contained in:
parent
8618a18754
commit
8fdb8beb12
95
libfs/dir.c
95
libfs/dir.c
|
@ -11,7 +11,7 @@ fs_dir_lookup(struct fs_inode *dp, const char *name, size_t *offset)
|
|||
size_t idx;
|
||||
struct stpdfs_dirent dirent;
|
||||
|
||||
if (!(dp->inode.flags & STPDFS_S_IFDIR))
|
||||
if ((dp->inode.flags & STPDFS_S_IFMT) != STPDFS_S_IFDIR)
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return (NULL);
|
||||
|
@ -82,56 +82,61 @@ 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 offset;
|
||||
struct fs_inode *ip;
|
||||
struct stpdfs_dirent dirent;
|
||||
int offset;
|
||||
struct fs_inode *ip;
|
||||
struct stpdfs_dirent dirent;
|
||||
|
||||
ip = fs_dir_lookup(dp, name, 0);
|
||||
if (ip == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ip->inode.nlink -= 1;
|
||||
|
||||
fs_inode_update(ip);
|
||||
fs_inode_release(ip);
|
||||
|
||||
for (offset = 0; offset < dp->inode.size; offset += STPDFS_DIRENT_SIZE)
|
||||
{
|
||||
fs_read(dp, (uint8_t *)&dirent, offset, STPDFS_DIRENT_SIZE);
|
||||
if (strncmp(dirent.filename, name, STPDFS_NAME_MAX) == 0)
|
||||
ip = fs_dir_lookup(dp, name, 0);
|
||||
if (ip == NULL)
|
||||
{
|
||||
memset(dirent.filename, 0, STPDFS_NAME_MAX);
|
||||
dirent.inode = 0;
|
||||
fs_write(dp, (uint8_t *)&dirent, offset, STPDFS_DIRENT_SIZE);
|
||||
break;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ip->inode.nlink -= 1;
|
||||
|
||||
fs_inode_update(ip);
|
||||
fs_inode_release(ip);
|
||||
|
||||
for (offset = 0; offset < dp->inode.size; offset += STPDFS_DIRENT_SIZE)
|
||||
{
|
||||
fs_read(dp, (uint8_t *)&dirent, offset, STPDFS_DIRENT_SIZE);
|
||||
if (strncmp(dirent.filename, name, STPDFS_NAME_MAX) == 0)
|
||||
{
|
||||
memset(dirent.filename, 0, STPDFS_NAME_MAX);
|
||||
dirent.inode = 0;
|
||||
fs_write(dp, (uint8_t *)&dirent, offset, STPDFS_DIRENT_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_IFMT) != STPDFS_S_IFDIR)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ndp = fs_inode_alloc(dp->super);
|
||||
if (ndp == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
if (ndp->valid == 0)
|
||||
{
|
||||
fs_inode_read(ndp);
|
||||
}
|
||||
|
||||
if (!(dp->inode.mode & STPDFS_S_IFDIR))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ndp = fs_inode_alloc(dp->super);
|
||||
if (ndp == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ndp->inode.mode |= STPDFS_S_IFDIR;
|
||||
|
||||
fs_dir_link(ndp, ".", ndp->inum);
|
||||
fs_dir_link(ndp, "..", dp->inum);
|
||||
|
||||
fs_dir_link(dp, name, ndp->inum);
|
||||
|
||||
return (0);
|
||||
ndp->inode.mode = mode;
|
||||
ndp->inode.mode |= STPDFS_S_IFDIR;
|
||||
|
||||
fs_dir_link(ndp, ".", ndp->inum);
|
||||
fs_dir_link(ndp, "..", dp->inum);
|
||||
|
||||
fs_dir_link(dp, name, ndp->inum);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@ struct fs_dir {
|
|||
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_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 */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "inode.h"
|
||||
#include "bio/bio.h"
|
||||
#include "stupidfs.h"
|
||||
|
@ -23,6 +24,8 @@ fs_inode_alloc(struct fs_super *super)
|
|||
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
|
||||
{
|
||||
memset(dinode, 0, sizeof(struct stpdfs_inode));
|
||||
dinode->actime = time(NULL);
|
||||
dinode->modtime = dinode->actime;
|
||||
dinode->flags = STPDFS_INO_FLAG_ALOC;
|
||||
fs_bio_bwrite(buff);
|
||||
fs_bio_brelse(buff);
|
||||
|
|
|
@ -6,7 +6,7 @@ bin_PROGRAMS = mkfs.stpd tools.stpd inspect.stpd
|
|||
mkfs_stpd_SOURCES = mkfs/main.c
|
||||
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
|
||||
|
||||
|
|
|
@ -158,6 +158,8 @@ mkfs()
|
|||
|
||||
rootip->valid = 1;
|
||||
|
||||
rootip->inode.gid = 0;
|
||||
rootip->inode.uid = 0;
|
||||
rootip->inode.modtime = time(NULL);
|
||||
rootip->inode.actime = time(NULL);
|
||||
memset(rootip->inode.zones, 0, sizeof(uint32_t) * 10);
|
||||
|
|
|
@ -22,6 +22,8 @@ static struct option long_options[] = {
|
|||
{"image", required_argument, 0, 'i'},
|
||||
{"uid", required_argument, 0, 'u'},
|
||||
{"gid", required_argument, 0, 'g'},
|
||||
{"mode", required_argument, 0, 'm'},
|
||||
{"recursive", no_argument, 0, 'r'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
#endif /* HAVE_STRUCT_OPTION */
|
||||
|
@ -31,6 +33,8 @@ static char *src = NULL;
|
|||
static char *image = NULL;
|
||||
static int gid = -1;
|
||||
static int uid = -1;
|
||||
static int recursive = 0;
|
||||
static int mode = -1;
|
||||
|
||||
extern char *prg_name;
|
||||
|
||||
|
@ -43,7 +47,14 @@ usage(int retval)
|
|||
}
|
||||
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);
|
||||
}
|
||||
ip->inode.mode = st.st_mode;
|
||||
|
||||
if (uid >= 0)
|
||||
{
|
||||
ip->inode.uid = uid;
|
||||
|
@ -100,7 +112,6 @@ do_copy(void)
|
|||
ip->inode.actime = st.st_atime;
|
||||
ip->inode.flags = STPDFS_INO_FLAG_ALOC;
|
||||
|
||||
|
||||
fs_inode_update(ip);
|
||||
|
||||
fp = fopen(src, "rb");
|
||||
|
@ -134,9 +145,9 @@ cmd_copy(int argc, char **argv)
|
|||
int c;
|
||||
|
||||
#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
|
||||
while ((c = getopt(argc, argv, "hi:u:g:")) != EOF)
|
||||
while ((c = getopt(argc, argv, "hi:u:g:rm:")) != EOF)
|
||||
#endif
|
||||
{
|
||||
switch (c)
|
||||
|
@ -157,6 +168,14 @@ cmd_copy(int argc, char **argv)
|
|||
gid = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
mode = strtol(optarg, NULL, 8);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
recursive = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(EXIT_FAILURE);
|
||||
break;
|
||||
|
|
105
tools/tools/ls.c
105
tools/tools/ls.c
|
@ -1,6 +1,7 @@
|
|||
#include "libfs/inode.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -20,6 +21,9 @@ static struct option long_options[] = {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{"image", required_argument, 0, 'i'},
|
||||
{"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}
|
||||
};
|
||||
#endif /* HAVE_STRUCT_OPTION */
|
||||
|
@ -27,6 +31,8 @@ static struct option long_options[] = {
|
|||
static char *path = "/";
|
||||
static char *image = NULL;
|
||||
static int all = 0;
|
||||
static int human = 0;
|
||||
static int color = 0;
|
||||
|
||||
extern char *prg_name;
|
||||
|
||||
|
@ -39,10 +45,13 @@ usage(int retval)
|
|||
}
|
||||
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(" -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(" --color colorize the output\n");
|
||||
printf(" -H, --human-readable XXX\n");
|
||||
printf(" --si XXX\n");
|
||||
printf(" -h, --help display this menu\n");
|
||||
}
|
||||
|
||||
|
@ -54,10 +63,14 @@ print_mode(struct fs_inode *ip)
|
|||
{
|
||||
char modebuff[] = "----------";
|
||||
|
||||
if (ip->inode.mode & STPDFS_S_IFDIR)
|
||||
if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFDIR)
|
||||
{
|
||||
modebuff[0] = 'd';
|
||||
}
|
||||
if ((ip->inode.mode & STPDFS_S_IFMT) == STPDFS_S_IFLNK)
|
||||
{
|
||||
modebuff[0] = 'l';
|
||||
}
|
||||
|
||||
if (ip->inode.mode & STPDFS_S_IRUSR)
|
||||
{
|
||||
|
@ -119,6 +132,69 @@ print_time(struct fs_inode *ip)
|
|||
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
|
||||
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);
|
||||
printf("%u ", ip->inode.nlink);
|
||||
printf("%3u %3u ", ip->inode.uid, ip->inode.gid);
|
||||
printf("%5u ", ip->inode.size);
|
||||
print_size(ip);
|
||||
|
||||
print_time(ip);
|
||||
|
||||
printf("%s\n", dirent->filename);
|
||||
print_name(dirent, ip);
|
||||
|
||||
fs_inode_release(ip);
|
||||
}
|
||||
|
@ -190,9 +266,9 @@ cmd_ls(int argc, char **argv)
|
|||
int c;
|
||||
|
||||
#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
|
||||
while ((c = getopt(argc, argv, "hi:a")) != EOF)
|
||||
while ((c = getopt(argc, argv, "hi:aH")) != EOF)
|
||||
#endif
|
||||
{
|
||||
switch (c)
|
||||
|
@ -208,6 +284,18 @@ cmd_ls(int argc, char **argv)
|
|||
case 'a':
|
||||
all = 1;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
human = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
human = 2;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
color = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(EXIT_FAILURE);
|
||||
|
@ -225,6 +313,5 @@ cmd_ls(int argc, char **argv)
|
|||
path = argv[optind];
|
||||
}
|
||||
|
||||
|
||||
return (do_ls());
|
||||
}
|
|
@ -21,6 +21,7 @@ struct command commands[] = {
|
|||
{"ls", &cmd_ls},
|
||||
{"copy", &cmd_copy},
|
||||
{"mkdir", &cmd_mkdir},
|
||||
{"rm", &cmd_rm},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "libfs/inode.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -28,7 +27,7 @@ static struct option long_options[] = {
|
|||
#endif /* HAVE_STRUCT_OPTION */
|
||||
|
||||
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 verbose = 0;
|
||||
|
||||
|
@ -54,7 +53,7 @@ usage(int retval)
|
|||
}
|
||||
|
||||
int
|
||||
do_mkdir(struct fs_inode *root, char *path)
|
||||
do_mkdir(struct fs_super *super, char *path)
|
||||
{
|
||||
char *dir;
|
||||
char *tmp;
|
||||
|
@ -62,9 +61,27 @@ do_mkdir(struct fs_inode *root, char *path)
|
|||
struct fs_inode *subdp;
|
||||
|
||||
dir = strtok(path, "/");
|
||||
dp = fs_inode_get(super, STPDFS_ROOTINO);
|
||||
if (dp->valid == 0)
|
||||
{
|
||||
fs_inode_read(dp);
|
||||
}
|
||||
|
||||
while (dir != 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);
|
||||
dir = tmp;
|
||||
}
|
||||
|
@ -131,17 +148,11 @@ cmd_mkdir(int argc, char **argv)
|
|||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
root = fs_inode_get(&super, STPDFS_ROOTINO);
|
||||
if (root->valid == 0)
|
||||
{
|
||||
fs_inode_read(root);
|
||||
}
|
||||
|
||||
status = EXIT_SUCCESS;
|
||||
|
||||
while (optind < argc)
|
||||
{
|
||||
if (do_mkdir(root, argv[optind++]))
|
||||
if (do_mkdir(&super, argv[optind++]))
|
||||
{
|
||||
status = EXIT_FAILURE;
|
||||
break;
|
||||
|
|
7
tools/tools/rm.c
Normal file
7
tools/tools/rm.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
cmd_rm(int argc, char **argv)
|
||||
{
|
||||
return (EXIT_FAILURE);
|
||||
}
|
|
@ -4,5 +4,6 @@
|
|||
int cmd_ls(int argc, char **argv);
|
||||
int cmd_copy(int argc, char **argv);
|
||||
int cmd_mkdir(int argc, char **argv);
|
||||
int cmd_rm(int argc, char **argv);
|
||||
|
||||
#endif /* !TOOLS_H */
|
Loading…
Reference in a new issue