#include <readline/history.h>
#include <lafs/lafs.h>
#include <talloc.h>
+#include <uuid/uuid.h>
/* This is the global state which is passed around among
* the various commands.
struct state {
struct lafs *lafs;
int done;
+ int verbose;
};
/* Every command can have arguments, both positional and
return NULL;
}
+static int get_int(char *str, int *result)
+{
+ long int num;
+ char *ep;
+
+ num = strtol(str, &ep, 10);
+ if (*str && !*ep) {
+ *result = num;
+ return 0;
+ }
+ return -1;
+}
+
/* Return an array of void* corresponding to the entries in
* 'args'. If an arg is present, the array entry is not NULL.
* For flags, the array entry will be the full flag.
{
struct state st = {0};
st.lafs = lafs_alloc();
+ st.verbose = 1;
rl_attempted_completion_function = complete_in_context;
rl_basic_word_break_characters = " \t\n=";
rl_completer_quote_characters = "\"'";
{
struct state st = {0};
st.lafs = lafs_alloc();
+ st.verbose = 0;
while (!st.done) {
char *line = NULL;
- size_t len, size;
+ ssize_t len;
+ size_t size;
len = getline(&line, &size, f);
- if (execute_line(&st, line) < 0)
+ if (len <= 0)
+ st.done = 1;
+ else if (execute_line(&st, line) < 0)
st.done = 1;
free(line);
}
}
+/****** RESET ******/
+static char help_reset[] = "Forget all fs information, and prepare to start afresh";
+static struct args args_reset[] = {
+ { "-force", flag, -1, {NULL}, "Reset even if there are unflushed changes"},
+ TERMINAL_ARG
+};
+static void c_reset(struct state *st, void **args)
+{
+
+ if (st->lafs->blocksize == 0) {
+ printf("reset: Filesystem state is already clear\n");
+ return;
+ }
+
+ if (args[1] == NULL &&
+ !list_empty(&st->lafs->wc[0].blocks)) {
+ printf("reset: filesystem has unflushed changes. Consider using\n"
+ " \"flush\" command of \"--force\" argument\n");
+ return;
+ }
+ talloc_free(st->lafs);
+ st->lafs = lafs_alloc();
+ if (st->verbose)
+ printf("Filesystem state has been reset\n");
+}
+
+
/****** NEWFS ******/
static char help_newfs[] = "Create a new LaFS filesystem, which can then be stored on one or more devices.";
static char *block_sizes[] = { "512", "1024", "2048", "4096", NULL };
};
static void c_newfs(struct state *st, void **args)
{
- /* FIXME */
+ int blockbytes = 1024;
+ int state_size = 0;
+ char *err = NULL;
+ char uuidstr[37];
+ uuid_t uu;
+ if (st->lafs->blocksize) {
+ printf("newfs: Filesytem already has state - consider using \"reset\"\n");
+ return;
+ }
+
+ if (args[1])
+ /* As this is a 'choice' it must be a valid number. */
+ get_int(args[1], &blockbytes);
+
+ if (args[3]) {
+ /* state-size was given */
+ if (get_int(args[3], &state_size) < 0)
+ err = "state-size must be a number";
+ else if (state_size <= 0 || state_size % 1024)
+ err = "state-size must be a positive multiple of 1024";
+ if (err) {
+ printf("newfs: %s: %s\n", err, (char*)args[3]);
+ return;
+ }
+ }
+ if (args[4]) {
+ /* uuid was given */
+ if (uuid_parse((char*)args[4], uu) < 0) {
+ printf("newfs: UUID in wrong format: %s\n", (char*)args[4]);
+ return;
+ }
+ }
+ lafs_new(st->lafs, blockbytes);
+ if (state_size)
+ st->lafs->statesize = state_size;
+ if (args[4])
+ memcpy(st->lafs->uuid, uu, 16);
+
+ if (st->verbose) {
+ uuid_unparse(st->lafs->uuid, uuidstr);
+ printf("Filesystem has been initilised: block size %d, "
+ "state size %d\n UUID=%s\n",
+ st->lafs->blocksize, st->lafs->statesize,
+ uuidstr);
+ }
return;
}
CMD(help),
CMD(newfs),
CMD(quit),
+ CMD(reset),
CMD(store),
{ NULL, NULL, NULL, NULL}
};