radare2/libr/fs/fs.c

192 lines
4.7 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2011 pancake<nopcode.org> */
2011-01-07 18:22:02 +01:00
#include <r_fs.h>
#include "../config.h"
2011-01-07 18:22:02 +01:00
static RFSPlugin *fs_static_plugins[] = { R_FS_STATIC_PLUGINS };
/* lifecycle */
2011-01-07 18:22:02 +01:00
// TODO: needs much more love
R_API RFS *r_fs_new () {
int i;
RFSPlugin *static_plugin;
2011-01-07 18:22:02 +01:00
RFS *fs = R_NEW (RFS);
if (fs) {
fs->roots = r_list_new ();
fs->roots->free = (RListFree)r_fs_root_free;
2011-01-07 18:22:02 +01:00
fs->plugins = r_list_new ();
// XXX fs->roots->free = r_fs_plugin_free;
for (i=0; fs_static_plugins[i]; i++) {
static_plugin = R_NEW (RFSPlugin);
memcpy (static_plugin, fs_static_plugins[i], sizeof (RFSPlugin));
r_fs_add (fs, static_plugin);
}
2011-01-07 18:22:02 +01:00
}
return fs;
}
R_API RFSPlugin *r_fs_plugin_get (RFS *fs, const char *name) {
RListIter *iter;
RFSPlugin *p;
r_list_foreach (fs->plugins, iter, p) {
if (!strcmp (p->name, name))
return p;
}
return NULL;
}
2011-01-07 18:22:02 +01:00
R_API void r_fs_free (RFS* fs) {
r_list_free (fs->plugins);
r_list_free (fs->roots);
2011-01-07 18:22:02 +01:00
free (fs);
}
/* plugins */
R_API void r_fs_add (RFS *fs, RFSPlugin *p) {
// find coliding plugin name
if (p) {
if (p->init)
p->init ();
}
r_list_append (fs->plugins, p);
}
R_API void r_fs_del (RFS *fs, RFSPlugin *p) {
// TODO: implement
}
/* mountpoint */
R_API RFSRoot *r_fs_mount (RFS* fs, const char *fstype, const char *path, ut64 delta) {
RFSPlugin *p;
RFSRoot *root;
if (path[0] != '/') {
eprintf ("r_fs_mount: invalid mountpoint\n");
return NULL;
}
p = r_fs_plugin_get (fs, fstype);
if (p != NULL) {
root = r_fs_root_new (path, delta);
root->p = p;
//memcpy (&root->iob, &fs->iob, sizeof (root->iob));
root->iob = fs->iob;
p->mount (root);
r_list_append (fs->roots, root);
eprintf ("Mounted %s on %s at 0x%llx\n", fstype, path, 0LL);
} else eprintf ("r_fs_mount: Invalid filesystem type\n");
return root;
}
static inline int r_fs_match (const char *root, const char *path) {
return (!strncmp (path, root, strlen (path)));
}
R_API int r_fs_umount (RFS* fs, const char *path) {
RFSRoot *root;
RListIter *iter;
r_list_foreach (fs->roots, iter, root) {
if (r_fs_match (path, root->path)) {
r_list_delete (fs->roots, iter);
return R_TRUE;
}
}
return R_FALSE;
}
R_API RFSRoot *r_fs_root (RFS *fs, const char *path) {
RFSRoot *root;
RListIter *iter;
r_list_foreach (fs->roots, iter, root) {
if (r_fs_match (path, root->path))
return root;
}
2011-01-07 18:22:02 +01:00
return NULL;
}
/* filez */
R_API RFSFile *r_fs_open (RFS* fs, const char *path) {
RFSRoot *root = r_fs_root (fs, path);
if (root && root->p && root->p->open)
return root->p->open (root, path+strlen (root->path));
else eprintf ("r_fs_open: null root->p->open\n");
return NULL;
}
// TODO: close or free?
R_API void r_fs_close (RFS* fs, RFSFile *file) {
if (fs && file && file->p && file->p->close)
file->p->close (file);
}
R_API int r_fs_read (RFS* fs, RFSFile *file, ut64 addr, int len) {
if (len<1) {
eprintf ("r_fs_read: too short read\n");
} else
if (fs && file) {
free (file->data);
file->data = malloc (len+1);
if (file->p && file->p->read) {
file->p->read (file, addr, len);
return R_TRUE;
} else eprintf ("r_fs_read: file->p->read is null\n");
}
return R_FALSE;
}
R_API RList *r_fs_dir(RFS* fs, const char *path) {
if (fs) {
RFSRoot *root = r_fs_root (fs, path);
const char *dir = path + strlen (root->path);
if (!*dir) dir = "/";
if (root)
return root->p->dir (root, dir);
eprintf ("r_fs_dir: error, path %s is not mounted\n", path);
}
return NULL;
}
2011-01-14 01:05:23 +01:00
R_API RFSFile *r_fs_slurp(RFS* fs, const char *path) {
RFSFile *file = NULL;
RFSRoot *root = r_fs_root (fs, path);
if (root && root->p) {
if (root->p->open && root->p->read && root->p->close) {
file = root->p->open (root, path);
if (file) {
root->p->read (file, 0, file->size); //file->data, file->size);
2011-01-14 01:05:23 +01:00
} else eprintf ("r_fs_slurp: cannot open file\n");
} else {
2011-01-14 01:05:23 +01:00
if (root->p->slurp)
return root->p->slurp (root, path);
else eprintf ("r_fs_slurp: null root->p->slurp\n");
}
}
return file;
}
// TODO: move into grubfs
#include "p/grub/include/grubfs.h"
RList *list = NULL;
static int parhook (struct grub_disk *disk, struct grub_partition *par) {
RFSPartition *p = r_fs_partition_new (r_list_length (list), par->start*512, 512*par->len);
p->type = par->msdostype;
r_list_append (list, p);
return 0;
}
R_API RList *r_fs_partitions(RFS *fs, const char *ptype, ut64 delta) {
list = r_list_new ();
list->free = r_fs_partition_free;
if (!strcmp (ptype, "msdos")) {
struct grub_disk *disk = grubfs_disk (&fs->iob);
struct grub_partition_map *gpm = &grub_msdos_partition_map;
gpm->iterate (disk, parhook);
} else {
eprintf ("Unknown partition type '%s'. Try 'msdos'", ptype);
r_list_free (list);
list = NULL;
}
return list;
}