Improve the RFS API to support write and unlink operations ##fs
* In fs_r2: /seek and /bsize and fix flags and config writes * fs.shell supports echo and redirections '>'
This commit is contained in:
parent
23e906ea70
commit
d8b283f8c6
|
@ -77,8 +77,8 @@ static void cmd_debug_reg(RCore *core, const char *str);
|
|||
#include "cmd_hash.c"
|
||||
#include "cmd_debug.c"
|
||||
#include "cmd_log.c"
|
||||
#include "cmd_zign.c"
|
||||
#include "cmd_flag.c"
|
||||
#include "cmd_zign.c"
|
||||
#include "cmd_project.c"
|
||||
#include "cmd_write.c"
|
||||
#include "cmd_cmp.c"
|
||||
|
|
|
@ -109,6 +109,42 @@ static void cmd_flag_init(RCore *core) {
|
|||
DEFINE_CMD_DESCRIPTOR (core, fz);
|
||||
}
|
||||
|
||||
static void spaces_list(RSpaces *sp, int mode) {
|
||||
RSpaceIter it;
|
||||
RSpace *s;
|
||||
const RSpace *cur = r_spaces_current (sp);
|
||||
PJ *pj = NULL;
|
||||
if (mode == 'j') {
|
||||
pj = pj_new ();
|
||||
pj_a (pj);
|
||||
}
|
||||
r_spaces_foreach (sp, it, s) {
|
||||
int count = r_spaces_count (sp, s->name);
|
||||
if (mode == 'j') {
|
||||
pj_o (pj);
|
||||
pj_ks (pj, "name", s->name);
|
||||
pj_ki (pj, "count", count);
|
||||
pj_kb (pj, "selected", cur == s);
|
||||
pj_end (pj);
|
||||
} else if (mode == 'q') {
|
||||
r_cons_printf ("%s\n", s->name);
|
||||
} else if (mode == '*') {
|
||||
r_cons_printf ("%s %s\n", sp->name, s->name);
|
||||
} else {
|
||||
r_cons_printf ("%5d %c %s\n", count, (!cur || cur == s)? '*': '.',
|
||||
s->name);
|
||||
}
|
||||
}
|
||||
if (mode == '*' && r_spaces_current (sp)) {
|
||||
r_cons_printf ("%s %s # current\n", sp->name, r_spaces_current_name (sp));
|
||||
}
|
||||
if (mode == 'j') {
|
||||
pj_end (pj);
|
||||
r_cons_printf ("%s\n", pj_string (pj));
|
||||
pj_free (pj);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_fz(RCore *core, const char *input) {
|
||||
switch (*input) {
|
||||
case '?': // "fz?"
|
||||
|
@ -851,12 +887,6 @@ rep:
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
case '\0':
|
||||
case '*':
|
||||
case 'q':
|
||||
spaces_list (&core->flags->spaces, input[1]);
|
||||
break;
|
||||
case ' ':
|
||||
r_flag_space_set (core->flags, input+2);
|
||||
break;
|
||||
|
@ -874,6 +904,12 @@ rep:
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
case '\0':
|
||||
case '*':
|
||||
case 'q':
|
||||
spaces_list (&core->flags->spaces, input[1]);
|
||||
break;
|
||||
default:
|
||||
spaces_list (&core->flags->spaces, 0);
|
||||
break;
|
||||
|
|
|
@ -445,7 +445,7 @@ static int cmd_mount(void *data, const char *_input) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
case 's': // "ms"
|
||||
if (core->http_up) {
|
||||
free (oinput);
|
||||
return false;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <r_list.h>
|
||||
#include <r_cons.h>
|
||||
#include <r_util.h>
|
||||
#include "i/private.h"
|
||||
|
||||
static const char *help_msg_z[] = {
|
||||
"Usage:", "z[*j-aof/cs] [args] ", "# Manage zignatures",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#if __UNIX__
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include "i/private.h"
|
||||
|
||||
#define DB core->sdb
|
||||
|
||||
|
@ -2256,40 +2255,6 @@ static char *get_comments_cb(void *user, ut64 addr) {
|
|||
return r_core_anal_get_comments ((RCore *)user, addr);
|
||||
}
|
||||
|
||||
R_IPI void spaces_list(RSpaces *sp, int mode) {
|
||||
RSpaceIter it;
|
||||
RSpace *s;
|
||||
const RSpace *cur = r_spaces_current (sp);
|
||||
PJ *pj = NULL;
|
||||
if (mode == 'j') {
|
||||
pj = pj_new ();
|
||||
pj_a (pj);
|
||||
}
|
||||
r_spaces_foreach (sp, it, s) {
|
||||
int count = r_spaces_count (sp, s->name);
|
||||
if (mode == 'j') {
|
||||
pj_o (pj);
|
||||
pj_ks (pj, "name", s->name);
|
||||
pj_ki (pj, "count", count);
|
||||
pj_kb (pj, "selected", cur == s);
|
||||
pj_end (pj);
|
||||
} else if (mode == '*') {
|
||||
r_cons_printf ("%s %s\n", sp->name, s->name);
|
||||
} else {
|
||||
r_cons_printf ("%5d %c %s\n", count, (!cur || cur == s)? '*': '.',
|
||||
s->name);
|
||||
}
|
||||
}
|
||||
if (mode == '*' && r_spaces_current (sp)) {
|
||||
r_cons_printf ("%s %s # current\n", sp->name, r_spaces_current_name (sp));
|
||||
}
|
||||
if (mode == 'j') {
|
||||
pj_end (pj);
|
||||
r_cons_printf ("%s\n", pj_string (pj));
|
||||
pj_free (pj);
|
||||
}
|
||||
}
|
||||
|
||||
static void cb_event_handler(REvent *ev, int event_type, void *user, void *data) {
|
||||
RCore *core = (RCore *)ev->user;
|
||||
if (!core->log_events) {
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef R_CORE_PRIVATE_H_
|
||||
#define R_CORE_PRIVATE_H_
|
||||
|
||||
#include <r_core.h>
|
||||
#include <r_util.h>
|
||||
#include <r_types.h>
|
||||
|
||||
R_IPI void spaces_list(RSpaces *sp, int mode);
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2011 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2011-2019 - pancake */
|
||||
|
||||
#include <r_fs.h>
|
||||
|
||||
|
@ -8,15 +8,26 @@ R_API RFSFile* r_fs_file_new(RFSRoot* root, const char* path) {
|
|||
return NULL;
|
||||
}
|
||||
file->root = root;
|
||||
if (root) {
|
||||
file->p = file->root->p; // XXX dupe
|
||||
}
|
||||
file->path = strdup (path);
|
||||
char *last = (char *)r_str_rchr (file->path, NULL, '/');
|
||||
if (last) {
|
||||
*last++ = 0;
|
||||
file->name = strdup (last);
|
||||
} else {
|
||||
file->name = strdup (path);
|
||||
// TODO: concat path?
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
R_API void r_fs_file_free(RFSFile* file) {
|
||||
if (file) {
|
||||
free (file->name);
|
||||
free (file->data);
|
||||
free (file);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use RFSRoot and pass it in the stack instead of heap? problematic with bindings
|
||||
|
|
57
libr/fs/fs.c
57
libr/fs/fs.c
|
@ -1,4 +1,4 @@
|
|||
/* radare2 - LGPL - Copyright 2011-2018 - pancake */
|
||||
/* radare2 - LGPL - Copyright 2011-2019 - pancake */
|
||||
|
||||
#include <r_fs.h>
|
||||
#include "config.h"
|
||||
|
@ -147,7 +147,7 @@ R_API RFSRoot* r_fs_mount(RFS* fs, const char* fstype, const char* path, ut64 de
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
file = r_fs_open (fs, str);
|
||||
file = r_fs_open (fs, str, false);
|
||||
if (file) {
|
||||
r_fs_close (fs, file);
|
||||
eprintf ("r_fs_mount: Invalid mount point\n");
|
||||
|
@ -234,24 +234,29 @@ R_API RList* r_fs_root(RFS* fs, const char* p) {
|
|||
}
|
||||
|
||||
/* filez */
|
||||
R_API RFSFile* r_fs_open(RFS* fs, const char* p) {
|
||||
R_API RFSFile* r_fs_open(RFS* fs, const char* p, bool create) {
|
||||
RFSRoot* root;
|
||||
RList* roots;
|
||||
RListIter* iter;
|
||||
RFSFile* f = NULL;
|
||||
const char* dir;
|
||||
char* path = strdup (p);
|
||||
//r_str_trim_path (path);
|
||||
roots = r_fs_root (fs, path);
|
||||
char* path = r_str_trim (strdup (p));
|
||||
RList *roots = r_fs_root (fs, path);
|
||||
if (!r_list_empty (roots)) {
|
||||
r_list_foreach (roots, iter, root) {
|
||||
if (create) {
|
||||
if (root && root->p && root->p->write) {
|
||||
f = r_fs_file_new (root, path + strlen (root->path));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (root && root->p && root->p->open) {
|
||||
if (strlen (root->path) == 1) {
|
||||
dir = path;
|
||||
} else {
|
||||
dir = path + strlen (root->path);
|
||||
}
|
||||
f = root->p->open (root, dir);
|
||||
f = root->p->open (root, dir, false);
|
||||
if (f) {
|
||||
break;
|
||||
}
|
||||
|
@ -263,7 +268,7 @@ R_API RFSFile* r_fs_open(RFS* fs, const char* p) {
|
|||
return f;
|
||||
}
|
||||
|
||||
// TODO: close or free?
|
||||
// NOTE: close doesnt free
|
||||
R_API void r_fs_close(RFS* fs, RFSFile* file) {
|
||||
if (fs && file) {
|
||||
R_FREE (file->data);
|
||||
|
@ -273,16 +278,33 @@ R_API void r_fs_close(RFS* fs, RFSFile* file) {
|
|||
}
|
||||
}
|
||||
|
||||
R_API int r_fs_write(RFS* fs, RFSFile* file, ut64 addr, const ut8 *data, int len) {
|
||||
if (len < 1) {
|
||||
return false;
|
||||
}
|
||||
if (fs && file) {
|
||||
// TODO: fill file->data ? looks like dupe of rbuffer
|
||||
if (file->p && file->p->write) {
|
||||
file->p->write (file, addr, data, len);
|
||||
return true;
|
||||
}
|
||||
eprintf ("r_fs_write: file->p->write is null\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
if (fs && file) {
|
||||
#if 0
|
||||
free (file->data);
|
||||
file->data = calloc (1, len + 1);
|
||||
#endif
|
||||
// file->data_len = len;
|
||||
if (file->p && file->data && file->p->read) {
|
||||
if (file->p && file->p->read) {
|
||||
file->p->read (file, addr, len);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -293,13 +315,13 @@ R_API int r_fs_read(RFS* fs, RFSFile* file, ut64 addr, int len) {
|
|||
}
|
||||
|
||||
R_API RList* r_fs_dir(RFS* fs, const char* p) {
|
||||
RList* roots, * ret = NULL;
|
||||
RList *ret = NULL;
|
||||
RFSRoot* root;
|
||||
RListIter* iter;
|
||||
const char* dir;
|
||||
char* path = strdup (p);
|
||||
r_str_trim_path (path);
|
||||
roots = r_fs_root (fs, path);
|
||||
RList *roots = r_fs_root (fs, path);
|
||||
r_list_foreach (roots, iter, root) {
|
||||
if (root) {
|
||||
if (strlen (root->path) == 1) {
|
||||
|
@ -366,7 +388,7 @@ R_API int r_fs_dir_dump(RFS* fs, const char* path, const char* name) {
|
|||
}
|
||||
break;
|
||||
case R_FS_FILE_TYPE_REGULAR:
|
||||
item = r_fs_open (fs, npath);
|
||||
item = r_fs_open (fs, npath, false);
|
||||
if (item) {
|
||||
r_fs_read (fs, item, 0, item->size);
|
||||
if (!r_file_dump (str, item->data, item->size, 0)) {
|
||||
|
@ -407,7 +429,7 @@ static void r_fs_find_off_aux(RFS* fs, const char* name, ut64 offset, RList* lis
|
|||
if (item->type == R_FS_FILE_TYPE_DIRECTORY) {
|
||||
r_fs_find_off_aux (fs, found, offset, list);
|
||||
} else {
|
||||
file = r_fs_open (fs, found);
|
||||
file = r_fs_open (fs, found, false);
|
||||
if (file) {
|
||||
r_fs_read (fs, file, 0, file->size);
|
||||
if (file->off == offset) {
|
||||
|
@ -467,10 +489,9 @@ static void r_fs_find_name_aux(RFS* fs, const char* name, const char* glob, RLis
|
|||
|
||||
R_API RList* r_fs_find_name(RFS* fs, const char* name, const char* glob) {
|
||||
RList* list = r_list_newf (free);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
if (list) {
|
||||
r_fs_find_name_aux (fs, name, glob, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -484,7 +505,7 @@ R_API RFSFile* r_fs_slurp(RFS* fs, const char* path) {
|
|||
continue;
|
||||
}
|
||||
if (root->p->open && root->p->read && root->p->close) {
|
||||
file = root->p->open (root, path);
|
||||
file = root->p->open (root, path, false);
|
||||
if (file) {
|
||||
root->p->read (file, 0, file->size); //file->data
|
||||
}else {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <r_fs.h>
|
||||
#include "grubfs.h"
|
||||
|
||||
static RFSFile* FSP(_open)(RFSRoot *root, const char *path) {
|
||||
static RFSFile* FSP(_open)(RFSRoot *root, const char *path, bool create) {
|
||||
RFSFile *file = r_fs_file_new (root, path);
|
||||
GrubFS *gfs = grubfs_new (&FSIPTR, &root->iob);
|
||||
file->ptr = gfs;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2017 - pancake */
|
||||
/* radare - LGPL - Copyright 2017-2019 - pancake */
|
||||
|
||||
#include <r_fs.h>
|
||||
#include <r_lib.h>
|
||||
|
@ -6,24 +6,34 @@
|
|||
|
||||
|
||||
typedef RList *(*DirHandler)(RFSRoot *root, const char *path);
|
||||
typedef RFSFile *(*CatHandler)(RFSRoot *root, const char *path, RFSFile *file);
|
||||
typedef RFSFile *(*CatHandler)(RFSRoot *root, RFSFile *file, const char *path);
|
||||
typedef bool (*WriteHandler)(RFSFile *file, ut64 addr, const ut8 *data, int len);
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
DirHandler dir;
|
||||
CatHandler cat;
|
||||
WriteHandler write;
|
||||
} Routes;
|
||||
|
||||
static RFSFile *__cfg_cat(RFSRoot *root, const char *path, RFSFile *file);
|
||||
static RFSFile *__version(RFSRoot *root, const char *path, RFSFile *file);
|
||||
static RFSFile *__flags_cat(RFSRoot *root, RFSFile *file, const char *path);
|
||||
static RFSFile *__cfg_cat(RFSRoot *root, RFSFile *file, const char *path);
|
||||
static RFSFile *__seek_cat(RFSRoot *root, RFSFile *file, const char *path);
|
||||
static RFSFile *__bsize_cat(RFSRoot *root, RFSFile *file, const char *path);
|
||||
static bool __cfg_write(RFSFile *file, ut64 addr, const ut8 *data, int len);
|
||||
static bool __seek_write(RFSFile *file, ut64 addr, const ut8 *data, int len);
|
||||
static bool __bsize_write(RFSFile *file, ut64 addr, const ut8 *data, int len);
|
||||
static RFSFile *__version(RFSRoot *root, RFSFile *file, const char *path);
|
||||
static RList *__root(RFSRoot *root, const char *path);
|
||||
static RList *__cfg(RFSRoot *root, const char *path);
|
||||
static RList *__flags(RFSRoot *root, const char *path);
|
||||
|
||||
static Routes routes[] = {
|
||||
{"/cfg", &__cfg, &__cfg_cat},
|
||||
{"/flags", &__flags},
|
||||
{"/version", NULL, &__version},
|
||||
{"/cfg", &__cfg, &__cfg_cat, &__cfg_write },
|
||||
{"/flags", &__flags, &__flags_cat, NULL},
|
||||
{"/version", NULL, &__version, NULL},
|
||||
{"/seek", NULL, &__seek_cat, &__seek_write },
|
||||
{"/bsize", NULL, &__bsize_cat, &__bsize_write },
|
||||
{"/", &__root},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -64,22 +74,40 @@ static RList *fscmd(RFSRoot *root, const char *cmd, int type) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static RFSFile* fs_r2_open(RFSRoot *root, const char *path) {
|
||||
static RFSFile* fs_r2_open(RFSRoot *root, const char *path, bool create) {
|
||||
int i;
|
||||
for (i = 0; routes[i].path; i++) {
|
||||
if (routes[i].cat && !strncmp (path, routes[i].path, strlen (routes[i].path))) {
|
||||
return routes[i].cat (root, path, NULL);
|
||||
const char *cwd = routes[i].path;
|
||||
if (routes[i].cat && !strncmp (path, cwd, strlen (cwd))) {
|
||||
return routes[i].cat (root, NULL, path);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool fs_r2_write(RFSFile *file, ut64 addr, const ut8 *data, int len) {
|
||||
int i;
|
||||
const char *path = file->path;
|
||||
const char *name = file->name;
|
||||
for (i = 0; routes[i].path; i++) {
|
||||
if (routes[i].write) {
|
||||
if (!strncmp (name, routes[i].path + 1, strlen (routes[i].path) - 1)) {
|
||||
return routes[i].write (file, addr, data, len);
|
||||
}
|
||||
if (!strncmp (path, routes[i].path, strlen (routes[i].path))) {
|
||||
return routes[i].write (file, addr, data, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool fs_r2_read(RFSFile *file, ut64 addr, int len) {
|
||||
int i;
|
||||
const char *path = file->name;
|
||||
for (i = 0; routes[i].path; i++) {
|
||||
if (routes[i].cat && !strncmp (path, routes[i].path, strlen (routes[i].path))) {
|
||||
return routes[i].cat (file->root, path, file);
|
||||
return routes[i].cat (file->root, file, path);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -90,34 +118,93 @@ static void fs_r2_close(RFSFile *file) {
|
|||
//fclose (file->ptr);
|
||||
}
|
||||
|
||||
static RFSFile *__version(RFSRoot *root, const char *path, RFSFile *file) {
|
||||
if (strlen (path) < 6) {
|
||||
return NULL;
|
||||
}
|
||||
char *a = strdup (path + 5);
|
||||
r_str_replace_char (a, '/', '.');
|
||||
static RFSFile *__version(RFSRoot *root, RFSFile *file, const char *path) {
|
||||
char *res = root->cob.cmdstrf (root->cob.core, "?V");
|
||||
/// root->iob.io->cb_printf ("%s\n", res);
|
||||
// eprintf ("%s", res);
|
||||
// RFSFile *
|
||||
if (!file) {
|
||||
file = r_fs_file_new (root, path);
|
||||
}
|
||||
file->ptr = NULL;
|
||||
free (file->data);
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
return file;
|
||||
}
|
||||
|
||||
static RFSFile *__flags_cat(RFSRoot *root, RFSFile *file, const char *path) {
|
||||
r_return_val_if_fail (root && path, NULL);
|
||||
const char *last = r_str_rchr (path, NULL, '/');
|
||||
if (last) {
|
||||
last++;
|
||||
} else {
|
||||
last = path;
|
||||
}
|
||||
char *res = root->cob.cmdstrf (root->cob.core, "?v %s", last);
|
||||
if (file) {
|
||||
file->ptr = NULL;
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
free (res);
|
||||
} else {
|
||||
file = r_fs_file_new (root, path);
|
||||
file->ptr = NULL;
|
||||
file->data = NULL;
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
}
|
||||
free (a);
|
||||
return file;
|
||||
}
|
||||
|
||||
static RFSFile *__cfg_cat(RFSRoot *root, const char *path, RFSFile *file) {
|
||||
static bool __bsize_write(RFSFile *file, ut64 addr, const ut8 *data, int len) {
|
||||
void *core = file->root->cob.core;
|
||||
char *res = file->root->cob.cmdstrf (core, "b %s", data);
|
||||
free (res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static RFSFile *__bsize_cat(RFSRoot *root, RFSFile *file, const char *path) {
|
||||
char *res = root->cob.cmdstrf (root->cob.core, "b");
|
||||
if (!file) {
|
||||
file = r_fs_file_new (root, path);
|
||||
}
|
||||
file->ptr = NULL;
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
return file;
|
||||
}
|
||||
|
||||
static bool __seek_write(RFSFile *file, ut64 addr, const ut8 *data, int len) {
|
||||
void *core = file->root->cob.core;
|
||||
char *res = file->root->cob.cmdstrf (core, "s %s", data);
|
||||
free (res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static RFSFile *__seek_cat(RFSRoot *root, RFSFile *file, const char *path) {
|
||||
char *res = root->cob.cmdstrf (root->cob.core, "s");
|
||||
if (!file) {
|
||||
file = r_fs_file_new (root, path);
|
||||
}
|
||||
file->ptr = NULL;
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
return file;
|
||||
}
|
||||
|
||||
static bool __cfg_write(RFSFile *file, ut64 addr, const ut8 *data, int len) {
|
||||
const char *a = file->name;
|
||||
void *core = file->root->cob.core;
|
||||
char *prefix = strdup (file->path + strlen ("/cfg/"));
|
||||
char *res = file->root->cob.cmdstrf (core, "e %s.%s=%s", prefix, a, data);
|
||||
free (prefix);
|
||||
free (res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static RFSFile *__cfg_cat(RFSRoot *root, RFSFile *file, const char *path) {
|
||||
if (strlen (path) < 6) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -126,19 +213,13 @@ static RFSFile *__cfg_cat(RFSRoot *root, const char *path, RFSFile *file) {
|
|||
char *res = root->cob.cmdstrf (root->cob.core, "e %s", a);
|
||||
// root->iob.io->cb_printf ("%s\n", res);
|
||||
// eprintf ("%s", res);
|
||||
if (file) {
|
||||
if (!file) {
|
||||
file = r_fs_file_new (root, path);
|
||||
}
|
||||
file->ptr = NULL;
|
||||
file->data = (ut8*)res;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
free (res);
|
||||
} else {
|
||||
file = r_fs_file_new (root, path);
|
||||
file->ptr = NULL;
|
||||
file->data = NULL;
|
||||
file->p = root->p;
|
||||
file->size = strlen (res);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
@ -222,8 +303,9 @@ RFSPlugin r_fs_plugin_r2 = {
|
|||
.name = "r2",
|
||||
.desc = "r2-based filesystem",
|
||||
.license = "MIT",
|
||||
.open = fs_r2_open,
|
||||
.read = fs_r2_read,
|
||||
.open = fs_r2_open, // open == read
|
||||
.read = fs_r2_read, // read == open
|
||||
.write = fs_r2_write,
|
||||
.close = fs_r2_close,
|
||||
.dir = &fs_r2_dir,
|
||||
.mount = fs_r2_mount,
|
||||
|
|
|
@ -1,9 +1,32 @@
|
|||
/* radare2 - LGPL - Copyright 2018 - pancake */
|
||||
/* radare2 - LGPL - Copyright 2018-2019 - pancake */
|
||||
|
||||
#include <r_fs.h>
|
||||
|
||||
#define PROMPT_PATH_BUFSIZE 1024
|
||||
|
||||
static bool handlePipes(RFS *fs, char *msg, const char *cwd) {
|
||||
char *red = strchr (msg, '>');
|
||||
if (red) {
|
||||
*red++ = 0;
|
||||
r_str_trim (msg);
|
||||
red = strdup (r_str_trim (red));
|
||||
if (*red != '/') {
|
||||
char *blu = r_str_newf ("%s/%s", cwd, red);
|
||||
free (red);
|
||||
red = blu;
|
||||
} else {
|
||||
|
||||
}
|
||||
RFSFile *f = r_fs_open (fs, red, true);
|
||||
r_fs_write (fs, f, 0, (const ut8 *)msg, strlen (msg));
|
||||
free (red);
|
||||
r_fs_close (fs, f);
|
||||
r_fs_file_free (f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
|
||||
char buf[PROMPT_PATH_BUFSIZE];
|
||||
char path[PROMPT_PATH_BUFSIZE];
|
||||
|
@ -73,8 +96,21 @@ R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
|
|||
r_list_free (list);
|
||||
return true;
|
||||
}
|
||||
if (buf[0] == '!') {
|
||||
if (buf[0] == '#') {
|
||||
// comment
|
||||
continue;
|
||||
} else if (buf[0] == ':') {
|
||||
char *msg = fs->cob.cmdstr (fs->cob.core, buf+1);
|
||||
printf ("%s\n", msg);
|
||||
free (msg);
|
||||
} else if (buf[0] == '!') {
|
||||
r_sandbox_system (buf + 1, 1);
|
||||
} else if (!strncmp (buf, "echo", 4)) {
|
||||
char *msg = r_str_trim (strdup (buf + 4));
|
||||
if (!handlePipes (fs, msg, path)) {
|
||||
printf ("%s\n", msg);
|
||||
}
|
||||
free (msg);
|
||||
} else if (!strncmp (buf, "ls", 2)) {
|
||||
char *ptr = str;
|
||||
r_list_free (list);
|
||||
|
@ -155,9 +191,11 @@ R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
|
|||
found = true;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (!found) {
|
||||
strcpy (path, opath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (!memcmp (buf, "cat ", 4)) {
|
||||
input = buf + 3;
|
||||
|
@ -175,10 +213,20 @@ R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
|
|||
}
|
||||
strncat (str, "/", sizeof (str) - strlen (str) - 1);
|
||||
strncat (str, input, sizeof (str) - strlen (str) - 1);
|
||||
file = r_fs_open (fs, str);
|
||||
char *p = strchr (str, '>');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
}
|
||||
file = r_fs_open (fs, str, false);
|
||||
if (file) {
|
||||
if (p) {
|
||||
*p = '>';
|
||||
}
|
||||
r_fs_read (fs, file, 0, file->size);
|
||||
if (!handlePipes (fs, (char *)file->data, path)) {
|
||||
write (1, file->data, file->size);
|
||||
}
|
||||
write (1, "\n", 1);
|
||||
r_fs_close (fs, file);
|
||||
} else {
|
||||
eprintf ("Cannot open file\n");
|
||||
|
@ -217,7 +265,7 @@ R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
|
|||
}
|
||||
strcat (s, "/");
|
||||
strcat (s, input);
|
||||
file = r_fs_open (fs, s);
|
||||
file = r_fs_open (fs, s, false);
|
||||
if (file) {
|
||||
r_fs_read (fs, file, 0, file->size);
|
||||
r_file_dump (input, file->data, file->size, 0);
|
||||
|
|
|
@ -58,7 +58,9 @@ typedef struct r_fs_plugin_t {
|
|||
const char *desc;
|
||||
const char *license;
|
||||
RFSFile* (*slurp)(RFSRoot *root, const char *path);
|
||||
RFSFile* (*open)(RFSRoot *root, const char *path);
|
||||
RFSFile* (*open)(RFSRoot *root, const char *path, bool create);
|
||||
bool (*unlink)(RFSRoot *root, const char *path);
|
||||
bool (*write)(RFSFile *fs, ut64 addr, const ut8 *data, int len);
|
||||
bool (*read)(RFSFile *fs, ut64 addr, int len);
|
||||
void (*close)(RFSFile *fs);
|
||||
RList *(*dir)(RFSRoot *root, const char *path, int view);
|
||||
|
@ -115,9 +117,10 @@ R_API void r_fs_del(RFS *fs, RFSPlugin *p);
|
|||
R_API RFSRoot *r_fs_mount(RFS* fs, const char *fstype, const char *path, ut64 delta);
|
||||
R_API bool r_fs_umount(RFS* fs, const char *path);
|
||||
R_API RList *r_fs_root(RFS *fs, const char *path);
|
||||
R_API RFSFile *r_fs_open(RFS* fs, const char *path);
|
||||
R_API RFSFile *r_fs_open(RFS* fs, const char *path, bool create);
|
||||
R_API void r_fs_close(RFS* fs, RFSFile *file);
|
||||
R_API int r_fs_read(RFS* fs, RFSFile *file, ut64 addr, int len);
|
||||
R_API int r_fs_write(RFS* fs, RFSFile* file, ut64 addr, const ut8 *data, int len);
|
||||
R_API RFSFile *r_fs_slurp(RFS* fs, const char *path);
|
||||
R_API RList *r_fs_dir(RFS* fs, const char *path);
|
||||
R_API int r_fs_dir_dump(RFS* fs, const char *path, const char *name);
|
||||
|
|
Loading…
Reference in New Issue