--- /dev/null
+#include <string.h>
+#include <lafs/lafs.h>
+#include "internal.h"
+
+u32 lafs_dir_lookup(struct lafs_ino *dir, char *name, int len)
+{
+ /* lookup a name and return ino number, or 0 if not found */
+ struct lafs_dblk *db;
+ u32 hash;
+
+ hash = lafs_hash_name(dir->md.file.seed, len, name);
+
+ while (1) {
+ u32 bnum;
+ int found;
+ u8 piece;
+ struct dir_ent de;
+ bnum = lafs_find_next(dir, hash+1);
+ if (bnum == LAFS_NOBLOCK)
+ bnum = 0;
+
+ db = lafs_dblk(dir, bnum);
+ if (!db ||
+ lafs_load_dblk(db))
+ return 0;
+
+ found = lafs_dir_find(db->b.data, dir->fs->blockbits-8,
+ dir->md.file.seed,
+ hash, &piece);
+ if (!found)
+ return 0;
+ lafs_dir_extract(db->b.data, dir->fs->blockbits-8,
+ &de, piece, NULL);
+ if (de.target &&
+ de.nlen == len &&
+ strncmp(de.name, name, len) == 0)
+ return de.target;
+ hash++;
+ }
+}
int verbose;
};
+static struct state *gen_state;
+
/* Every command can have arguments, both positional and
* named.
* Named arguments are specified with a leading hyphen, though
asprintf(&hist, "%s/.lafs_history", home);
read_history(hist);
+ gen_state = &st;
while (!st.done) {
char *line = readline("LaFS: ");
return NULL;
}
+static char *internal_gen(const char *prefix, int state)
+{
+ static char *cp;
+ static char *pre = NULL;
+ static struct lafs_ino *inode;
+ static u32 index;
+
+ u32 inum;
+ int type;
+ char name[257];
+
+ if (gen_state->lafs->ss.root == 0) {
+ rl_attempted_completion_over = 1;
+ return NULL;
+ }
+ if (state == 0) {
+ if (pre)
+ free(pre);
+ pre = strdup(prefix);
+ cp = pre + strlen(pre);
+ while (cp > pre && cp[-1] != '/')
+ cp--;
+ prefix = cp;
+ while (cp > pre && cp[-1] == '/')
+ cp--;
+ cp[0] = 0;
+ /*pre is the directory, prefix is the component prefix */
+ inode = lafs_get_itable(gen_state->lafs);
+ inode = lafs_get_inode(inode, 2);
+ inode = lafs_lookup_path(inode, inode, pre);
+ index = -1;
+ } else {
+ if (index + 1 == 0) {
+ rl_attempted_completion_over = 1;
+ return NULL;
+ }
+ }
+ if (lafs_dir_next(inode, &index, name, &inum, &type) == 1)
+ return strdup(name);
+
+ rl_attempted_completion_over = 1;
+ return NULL;
+}
/*
* This is the brains of the completion handler.
* We parse the line-so-far to determine way options have already
matches = rl_completion_matches(
prefix, rl_filename_completion_function);
break;
+ case internal:
+ matches = rl_completion_matches(prefix, internal_gen);
+ break;
case choice:
gen_options = args[p].options;
matches = rl_completion_matches(
};
static void c_show_inode(struct state *st, void **args)
{
- int ino;
struct lafs_ino *inode;
if (!args[2]) {
printf("show inode: please give file name or inode number\n");
return;
}
+ if (st->lafs->ss.root == 0) {
+ printf("show inode: filesytem not ready\n");
+ return;
+ }
+ inode = lafs_get_itable(st->lafs);
if (args[3]) {
char *inostr = args[3];
char *endp;
- ino = strtoul(inostr, &endp, 10);
+ int ino = strtoul(inostr, &endp, 10);
if (endp == inostr || *endp) {
printf("show inode: %s is not a valid inode number\n",
inostr);
return;
}
+ if (ino)
+ inode = lafs_get_inode(inode, ino);
+ if (!inode)
+ printf("show inode: cannot find inode %d\n",ino);
} else {
- /* For now, path lookup always finds '0' */
- ino = 0;
- }
- if (st->lafs->ss.root == 0) {
- printf("show inode: filesytem not ready\n");
- return;
+ char *path = args[2];
+ inode = lafs_get_inode(inode, 2);
+ inode = lafs_lookup_path(inode, inode, path);
+
+ if (!inode) {
+ printf("show inode: cannot find inode for %s\n", path);
+ return;
+ }
}
- inode = lafs_get_itable(st->lafs);
- if (ino)
- inode = lafs_get_inode(inode, ino);
- if (inode)
- lafs_print_inode(inode);
- else
- printf("show inode: cannot find inode %d\n",ino);
+ lafs_print_inode(inode);
}
/****** SHOW DEVICE ******/
u32 inum;
int type;
int col;
+ char *path = args[1];
if (st->lafs->ss.root == 0) {
printf("ls: filesytem not ready\n");
}
ino = lafs_get_itable(st->lafs);
ino = lafs_get_inode(ino, 2);
+ if (path)
+ ino = lafs_lookup_path(ino, ino, path);
+ if (!ino) {
+ printf("ls: cannot find inode for %s\n", path?:"/");
+ return;
+ }
+
+ if (ino->type != TypeDir) {
+ printf("ls: %s exists but is not a directory\n", path);
+ return;
+ }
col = 0;
while (lafs_dir_next(ino, &index, name, &inum, &type) == 1) {
if (args[2]) {