bookmarkctl: better handling of command-line args

This commit is contained in:
CismonX 2025-03-13 14:45:10 +08:00
parent 68aafe3d8d
commit 2ce0be8a18
No known key found for this signature in database
GPG key ID: 3094873E29A482FB
3 changed files with 81 additions and 79 deletions

View file

@ -9,14 +9,13 @@ bookmarkctl - manage a mounted BookmarkFS filesystem
.RI [ args ] .RI [ args ]
.PP .PP
.B "bookmarkctl permd" .B "bookmarkctl permd"
.I pathname .RI [ options ]
.I op
.I name1 .I name1
.I name2 .I name2
.I pathname
.PP .PP
.B "bookmarkctl fsck" .B "bookmarkctl fsck"
.I pathname .I pathname
.I op
.PP .PP
.B "bookmarkctl help" .B "bookmarkctl help"
.PP .PP
@ -30,7 +29,8 @@ filesystem.
.SS Permute directory entries .SS Permute directory entries
The The
.B permd .B permd
sub-command re-arranges the order of the directory entries returned from sub-command re-arranges the order of the directory entries to be returned
from future
.BR readdir (3) .BR readdir (3)
calls. calls.
.PP .PP
@ -42,41 +42,38 @@ The
and and
.I name2 .I name2
arguments are filenames under that directory. arguments are filenames under that directory.
.PP .SS Filesystem check
The The
.I op .B fsck
argument is the operation to perform on the directory: sub-command displays a list of filesystem errors found under the directory
referred to by
.IR pathname .
It does not recurse into subdirectories.
.PP
For the full fsck functionalities, use
.BR fsck.bookmarkfs (1).
.
.SH OPTIONS
.SS Permute directory entries
.TP .TP
.B swap .B \-s
Exchange the positions of the directory entries represented by Exchange the positions of the directory entries represented by
.I name1 .I name1
and and
.IR name2 . .IR name2 .
.TP .TP
.BR move\-before | move\-after .BR \-b ", " \-a
Move the directory entry represented by Move the directory entry represented by
.I name1 .I name1
to the position just before/after the one represented by to the position just before/after the one represented by
.IR name2 . .IR name2 .
.SS Filesystem check
The
.B fsck
sub-command checks for errors within a BookmarkFS filesystem.
.PP .PP
The The
.I pathname .BR \-s ", " \-b
argument is the path to the directory to perform checks on. and
.PP .B \-a
The options are mutually exclusive.
.I op If multiple options are provided, the last one takes effect.
argument is the operation to perform on the directory:
.TP
.B list
Display a list of errors found under the given directory.
Will not recurse into subdirectories.
.PP
For the full fsck functionalities, use
.BR fsck.bookmarkfs (1).
. .
.SH EXIT STATUS .SH EXIT STATUS
.TP .TP

View file

@ -547,59 +547,55 @@ Sub-commands:
@table @command @table @command
@item permd @item permd
Rearranges the order of the directory entries obtained from @code{readdir()}. Rearranges the order of the directory entries to be returned from
future calls to @code{readdir()}.
@xref{Permute Directory Entries}. @xref{Permute Directory Entries}.
@example @example
bookmarkctl permd @var{pathname} @var{op} @var{name1} @var{name2} bookmarkctl permd [@var{options}] @var{name1} @var{name2} @var{pathname}
@end example @end example
@table @var @table @var
@item pathname
Path to the directory.
@item name1 @item name1
@item name2 @item name2
Filename of entries under the directory. Filename of entries under the directory.
@item op @item pathname
Operation to perform on the directory: Path to the parent directory.
@end table
@table @samp Options:
@item swap
@table @option
@item -s
Exchange the positions of the directory entries represented by @var{name1} Exchange the positions of the directory entries represented by @var{name1}
and @var{name2}. and @var{name2}.
@item move-before @item -b
Move the directory entry represented by @var{name1} to the position just Move the directory entry represented by @var{name1} to the position just
@emph{before} the one represented by @var{name2}. @emph{before} the one represented by @var{name2}.
@item move-after @item -a
Move the directory entry represented by @var{name1} to the position just Move the directory entry represented by @var{name1} to the position just
@emph{after} the one represented by @var{name2}. @emph{after} the one represented by @var{name2}.
@end table @end table
@end table
The @option{-s}, @option{-b} and @option{-a} options are mutually exclusive.
If multiple options are provided, the last one takes effect.
@item fsck @item fsck
Check for errors within a BookmarkFS filesystem. Displays a list of filesystem errors found under the given directory.
@xref{Filesystem Check}. @xref{Filesystem Check}.
Does not recurse into subdirectories.
@example @example
bookmarkctl fsck @var{pathname} @var{op} bookmarkctl fsck @var{pathname}
@end example @end example
@table @var @table @var
@item pathname @item pathname
Path to the directory to perform checks on. Path to the directory to perform checks on.
@item op
Operation to perform on the directory:
@table @samp
@item list
Display a list of errors found under the given directory.
Will not recurse into subdirectories.
@end table
@end table @end table
For the full fsck functionalities, @pxref{fsck.bookmarkfs}. For the full fsck functionalities, @pxref{fsck.bookmarkfs}.

View file

@ -32,6 +32,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include "frontend_util.h"
#include "fsck_util.h" #include "fsck_util.h"
#include "ioctl.h" #include "ioctl.h"
#include "macros.h" #include "macros.h"
@ -104,21 +105,15 @@ subcmd_fsck (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
#define FSCK_NARGS 2 if (--argc != 1) {
if (--argc != FSCK_NARGS) { if (argc == 0) {
log_printf("fsck: " STRINGIFY(FSCK_NARGS) " args expected, %d given", log_puts("fsck: pathname must be specified");
argc); } else {
return -1; log_puts("fsck: too many arguments");
} }
char const *path = *(++argv);
char const *opstr = *(++argv);
if (0 == strcmp("list", opstr)) {
// NOOP
} else {
log_printf("fsck: bad operation name '%s'", opstr);
return -1; return -1;
} }
char const *path = *(++argv);
int dirfd = open(path, O_RDONLY | O_DIRECTORY); int dirfd = open(path, O_RDONLY | O_DIRECTORY);
if (dirfd < 0) { if (dirfd < 0) {
@ -138,8 +133,10 @@ subcmd_fsck (
break; break;
} }
} while (status != BOOKMARKFS_FSCK_RESULT_END); } while (status != BOOKMARKFS_FSCK_RESULT_END);
close(dirfd); close(dirfd);
return status; return status;
} }
static int static int
@ -147,29 +144,41 @@ subcmd_permd (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
#define PERMD_NARGS 4 int op = -1;
if (--argc != PERMD_NARGS) {
log_printf("permd: " STRINGIFY(PERMD_NARGS) " args expected, %d given", OPT_START(argc, argv, "sba")
argc); OPT_OPT('s') {
op = BOOKMARKFS_PERMD_OP_SWAP;
break;
}
OPT_OPT('b') {
op = BOOKMARKFS_PERMD_OP_MOVE_BEFORE;
break;
}
OPT_OPT('a') {
op = BOOKMARKFS_PERMD_OP_MOVE_AFTER;
break;
}
OPT_END
if (op < 0) {
log_puts("permd: no operation specified");
return -1; return -1;
} }
char const *path = *(++argv);
char const *opstr = *(++argv);
char const *name1 = *(++argv);
char const *name2 = *(++argv);
struct bookmarkfs_permd_data permd_data; struct bookmarkfs_permd_data permd_data;
permd_data.op = op;
if (0 == strcmp("swap", opstr)) { if (argc != 3) {
permd_data.op = BOOKMARKFS_PERMD_OP_SWAP; if (argc < 3) {
} else if (0 == strcmp("move-before", opstr)) { log_puts("permd: dentry names and dir path must be specified");
permd_data.op = BOOKMARKFS_PERMD_OP_MOVE_BEFORE; } else {
} else if (0 == strcmp("move-after", opstr)) { log_puts("permd: too many arguments");
permd_data.op = BOOKMARKFS_PERMD_OP_MOVE_AFTER; }
} else {
log_printf("permd: bad operation name '%s'", opstr);
return -1; return -1;
} }
char const *name1 = argv[0];
char const *name2 = argv[1];
char const *path = argv[2];
#define COPY_NAME(dst, src) \ #define COPY_NAME(dst, src) \
if ((dst) + sizeof(dst) == stpncpy(dst, src, sizeof(dst))) { \ if ((dst) + sizeof(dst) == stpncpy(dst, src, sizeof(dst))) { \