コード例 #1
0
ファイル: cmd_eval.c プロジェクト: XVilka/radare2
R_API RList *r_core_list_themes(RCore *core) {
	RList *files = NULL;
	RListIter *iter;
	const char *fn;
	char *home = r_str_home (".config/radare2/cons/");

	RList *list = r_list_new ();
	getNext = false;
	if (home) {
		files = r_sys_dir (home);
		r_list_foreach (files, iter, fn) {
			if (*fn && *fn != '.') {
				r_list_append (list, strdup (fn));
			}
		}
		r_list_free (files);
		R_FREE (home);
	}
	files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/");
	r_list_foreach (files, iter, fn) {
		if (*fn && *fn != '.') {
			r_list_append (list, strdup (fn));
		}
	}
	r_list_free (files);
	files = NULL;
	return list;
}
コード例 #2
0
ファイル: hud.c プロジェクト: commiebstrd/radare2
R_API char *r_cons_hud_path(const char *path, int dir) {
	char *tmp = NULL, *ret = NULL;
	RList *files;
	if (path){
		while (*path==' ')
			path++;
		tmp = (*path)? strdup(path): strdup ("./");
	} else
		tmp = strdup ("./");

	files = r_sys_dir (tmp);
	if (files) {
		ret = r_cons_hud (files, tmp);
		if (ret) {
			tmp = r_str_concat (tmp, "/");
			tmp = r_str_concat (tmp, ret);
			ret = r_file_abspath (tmp);
			free (tmp);
			tmp = ret;
			if (r_file_is_directory (tmp)) {
				ret = r_cons_hud_path (tmp, dir);
				free (tmp);
				tmp = ret;
			}
		}
		r_list_free (files);
	} else eprintf ("No files found\n");
	if (!ret) {
		free (tmp);
		return NULL;
	}
	return tmp;
}
コード例 #3
0
ファイル: project.c プロジェクト: AmesianX/radare2
R_API int r_core_project_list(RCore *core, int mode) {
	RListIter *iter;
	RList *list;
	int isfirst = 1;
	char *foo, *path = r_file_abspath (r_config_get (core->config, "dir.projects"));
	if (!path)
		return 0;
	list = r_sys_dir (path);
	switch (mode) {
	case 'j':
		r_cons_printf ("[");
		r_list_foreach (list, iter, foo) {
			// todo. escape string
			if (r_core_is_project (core, foo)) {
				r_cons_printf ("%s\"%s\"",
					isfirst?"":",", foo);
				isfirst = 0;
			}
		}
		r_cons_printf ("]\n");
		break;
	default:
		r_list_foreach (list, iter, foo) {
			if (r_core_is_project (core, foo))
				r_cons_println (foo);
		}
		break;
	}
	r_list_free (list);
	free (path);
	return 0;
}
コード例 #4
0
ファイル: cmd_eval.c プロジェクト: chinmaydd/radare2
static void nextpal(RCore *core, int mode) {
	RList *files;
	RListIter *iter;
	const char *fn;
	char *home = r_str_home (".config/radare2/cons/");

	getNext = false;
	if (home) {
		files = r_sys_dir (home);
		r_list_foreach (files, iter, fn) {
			if (*fn && *fn != '.') {
				if (!nextpal_item (core, mode, fn)) {
					r_list_free (files);
					R_FREE (home);
					goto done;
				}
			}
		}
		r_list_free (files);
		R_FREE (home);
	}
	files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/");
	r_list_foreach (files, iter, fn) {
		if (*fn && *fn != '.') {
			if (!nextpal_item (core, mode, fn))
				goto done;
		}
	}
done:
	if (getNext) {
		R_FREE (curtheme);
		nextpal (core, mode);
		return;
	}
	if (mode == 'l' && !curtheme && !r_list_empty (files)) {
		nextpal (core, mode);
		// beware infinite loop here
		return;
	}
	r_list_free (files);
	if (curtheme) {
		r_core_cmdf (core, "eco %s", curtheme);
	}
}
コード例 #5
0
ファイル: project.c プロジェクト: csarn/radare2
R_API int r_core_project_delete(RCore *core, const char *prjfile) {
	if (r_sandbox_enable (0)) {
		eprintf ("Cannot delete project in sandbox mode\n");
		return 0;
	}
	char *path = projectScriptPath (core, prjfile);
	if (!path) {
		eprintf ("Invalid project name '%s'\n", prjfile);
		return false;
	}
	if (r_core_is_project (core, prjfile)) {
		char *prjDir = r_file_dirname (path);
		if (!prjDir) {
			eprintf ("Cannot resolve directory\n");
			free (path);
			return false;
		}
		// rm project file
		if (r_file_exists (path)) {
			r_file_rm (path);
			eprintf ("rm %s\n", path);
		}

		//rm notes.txt file
		char *notes_txt = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "notes.txt");
		if (r_file_exists (notes_txt)) {
			r_file_rm (notes_txt);
			eprintf ("rm %s\n", notes_txt);
		}
		free(notes_txt);

		char *rop_d = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "rop.d");

		if (r_file_is_directory (rop_d)) {
			char *f;
			RListIter *iter;
			RList *files = r_sys_dir (rop_d);
			r_list_foreach (files, iter, f) {
				char *filepath = r_str_append (strdup (rop_d), R_SYS_DIR);
				filepath = r_str_append (filepath, f);
				if (!r_file_is_directory (filepath)) {
					eprintf ("rm %s\n", filepath);
					r_file_rm (filepath);
				}
				free (filepath);
			}
			r_file_rm (rop_d);
			eprintf ("rm %s\n", rop_d);
			r_list_free (files);
		}
		free (rop_d);
		// remove directory only if it's empty
		r_file_rm (prjDir);
		free (prjDir);
	}
コード例 #6
0
ファイル: cmd_eval.c プロジェクト: nmatt0/radare2
static void list_themes_in_path(RList *list, const char *path) {
	RListIter *iter;
	const char *fn;
	RList *files = r_sys_dir (path);
	r_list_foreach (files, iter, fn) {
		if (*fn && *fn != '.') {
			r_list_append (list, strdup (fn));
		}
	}
	r_list_free (files);
}
コード例 #7
0
ファイル: cmd.c プロジェクト: BatchDrake/radare2
static int cmd_log(void *data, const char *input) {
	RCore *core = (RCore *)data;
	const char *input2 = input + (*input? (*input==' '? 2: 1): 0);
	char *arg = strchr (input2, ' ');
	int n = atoi (input2);
	int n2 = arg? atoi (arg+1): 0;
	switch (*input) {
	case 'l':
		r_cons_printf ("%d\n", core->log->last-1);
		break;
	case '-':
		r_core_log_del (core, n);
		break;
	case '?':
		r_cons_printf ("Usage: l[-][ num|msg]\n"
			"  l new comment 0x80480\n"
			"  ll      get last log message id\n"
			"  l-      delete all logs\n"
			"  l-123   delete logs before 123\n"
			"  l 123   list log from 123 \n"
			"  l       list all log messages\n"
			"  l 10 3  list 3 log messages starting from 10\n"
			"  ls      list files in current directory (see pwd, cd)\n"
			"  lj      list in json format\n"
			"  l*      list in radare commands\n"
		);
		break;
	case ' ':
		if (!n) {
			r_core_log_add (core, input+1);
			break;
		}
	case 's':
		{
		char *name;
		RListIter *iter;
		RList *files = r_sys_dir (".");
		r_list_foreach (files, iter, name) {
			r_cons_printf ("%s%s\n", name,
				r_file_is_directory (name)? "/":"");
		}
		r_list_free (files);
		}
		break;
	case 'j':
	case '*':
	case '\0':
		r_core_log_list (core, n, n2, *input);
		break;
	}
コード例 #8
0
ファイル: radare2.c プロジェクト: P4N74/radare2
static void radare2_rc(RCore *r) {
	char* env_debug = r_sys_getenv ("R_DEBUG");
	bool has_debug = false;
	if (env_debug) {
		has_debug = true;
		R_FREE (env_debug);
	}

	char *homerc = r_str_home (".radare2rc");
	if (homerc && r_file_is_regular (homerc)) {
		if (has_debug) {
			eprintf ("USER CONFIG loaded from %s\n", homerc);
		}
		r_core_cmd_file (r, homerc);
	}
	free (homerc);
	homerc = r_str_home (".config/radare2/radare2rc");
	if (homerc && r_file_is_regular (homerc)) {
		if (has_debug) {
			eprintf ("USER CONFIG loaded from %s\n", homerc);
		}
		r_core_cmd_file (r, homerc);
	}
	free (homerc);
	homerc = r_str_home (".config/radare2/radare2rc.d");
	if (homerc) {
		if (r_file_is_directory (homerc)) {
			char *file;
			RListIter *iter;
			RList *files = r_sys_dir (homerc);
			r_list_foreach (files, iter, file) {
				if (*file != '.') {
					char *path = r_str_newf ("%s/%s", homerc, file);
					if (r_file_is_regular (path)) {
						if (has_debug) {
							eprintf ("USER CONFIG loaded from %s\n", homerc);
						}
						r_core_cmd_file (r, path);
					}
					free (path);
				}
			}
			r_list_free (files);
		}
		free (homerc);
	}
}
コード例 #9
0
ファイル: rtr.c プロジェクト: dialeth/radare2
- follow symlinks
#endif

static char *rtr_dir_files (const char *path) {
	char *ptr = strdup ("<html><body>\n");
	const char *file;
	RListIter *iter;
	// list files
	RList *files = r_sys_dir (path);
	eprintf ("Listing directory %s\n", path);
	r_list_foreach (files, iter, file) {
		if (file[0] == '.') continue;
		ptr = r_str_concatf (ptr, "<a href=\"%s%s\">%s</a><br />\n",
			path, file, file);
	}
	r_list_free (files);
	return r_str_concat (ptr, "</body></html>\n");
}
コード例 #10
0
ファイル: project.c プロジェクト: csarn/radare2
R_API int r_core_project_list(RCore *core, int mode) {
	PJ *pj = NULL;
	RListIter *iter;
	RList *list;

	char *foo, *path = r_file_abspath (r_config_get (core->config, "dir.projects"));
	if (!path) {
		return 0;
	}
	list = r_sys_dir (path);
	switch (mode) {
	case 'j':
		pj = pj_new ();
		if (!pj) {
			break;
		}
		pj_a (pj);
		r_list_foreach (list, iter, foo) {
			// todo. escape string
			if (r_core_is_project (core, foo)) {
				pj_s (pj, foo);
			}
		}
		pj_end (pj);
		r_cons_printf ("%s\n", pj_string (pj));
		pj_free (pj);
		break;
	default:
		r_list_foreach (list, iter, foo) {
			if (r_core_is_project (core, foo)) {
				r_cons_println (foo);
			}
		}
		break;
	}
	r_list_free (list);
	free (path);
	return 0;
}
コード例 #11
0
ファイル: project.c プロジェクト: AmesianX/radare2
R_API int r_core_project_delete(RCore *core, const char *prjfile) {
	char *path;
	if (r_sandbox_enable (0)) {
		eprintf ("Cannot delete project in sandbox mode\n");
		return 0;
	}
	path = r_core_project_file (core, prjfile);
	if (!path) {
		eprintf ("Invalid project name '%s'\n", prjfile);
		return false;
	}
	if (r_core_is_project (core, prjfile)) {
		// rm project file
		r_file_rm (path);
		eprintf ("rm %s\n", path);
		path = r_str_concat (path, ".d");
		if (r_file_is_directory (path)) {
			char *f;
			RListIter *iter;
			RList *files = r_sys_dir (path);
			r_list_foreach (files, iter, f) {
				char *filepath = r_str_concat (strdup (path), R_SYS_DIR);
				filepath =r_str_concat (filepath, f);
				if (!r_file_is_directory (filepath)) {
					eprintf ("rm %s\n", filepath);
					r_file_rm (filepath);
				}
				free (filepath);
			}
			r_file_rm (path);
			eprintf ("rm %s\n", path);
			r_list_free (files);
		}
		// TODO: remove .d directory (BEWARE OF ROOT RIMRAFS!)
		// TODO: r_file_rmrf (path);
	}
コード例 #12
0
ファイル: cmd_eval.c プロジェクト: superr4y/radare2
static int cmd_eval(void *data, const char *input) {
	char *p;
	RCore *core = (RCore *)data;
	switch (input[0]) {
	case 'n': // env
		if (!strchr (input, '=')) {
			char *var, *p;
			var = strchr (input, ' ');
			if (var) while (*var==' ') var++;
			p = r_sys_getenv (var);
			if (p) {
				r_cons_printf ("%s\n", p);
				free (p);
			} else {
				char **e = r_sys_get_environ ();
				while (e && *e) {
					r_cons_printf ("%s\n", *e);
					e++;
				}
			}
		} else if (strlen (input)>3) {
			char *v, *k = strdup (input+3);
			if (!k) break;
			v = strchr (k, '=');
			if (v) {
				*v++ = 0;
				r_sys_setenv (k, v);
			}
			free (k);
		}
		return true;
	case 'x': // exit
		return cmd_quit (data, "");
	case 'j':
		r_config_list (core->config, NULL, 'j');
		break;
	case '\0':
		r_config_list (core->config, NULL, 0);
		break;
	case 'c':
		switch (input[1]) {
		case 'h': // echo
			if (( p = strchr (input, ' ') )) {
				r_cons_strcat (p+1);
				r_cons_newline ();
			}
			break;
		case 'd':
			r_cons_pal_init (NULL);
			break;
		case '?': {
			const char *helpmsg[] = {
			"Usage ec[s?] [key][[=| ]fg] [bg]","","",
			"ec","","list all color keys",
			"ec*","","same as above, but using r2 commands",
			"ecd","","set default palette",
			"ecr","","set random palette",
			"ecs","","show a colorful palette",
			"ecj","","show palette in JSON",
			"ecc","","show palette in CSS",
			"eco"," dark|white","load white color scheme template",
			"ec"," prompt red","change color of prompt",
			"ec"," prompt red blue","change color and background of prompt",
			""," ","",
			"colors:","","rgb:000, red, green, blue, ...",
			"e scr.rgbcolor","=1|0","for 256 color cube (boolean)",
			"e scr.truecolor","=1|0","for 256*256*256 colors (boolean)",
			"$DATADIR/radare2/cons","","~/.config/radare2/cons ./",
			NULL};
			r_core_cmd_help (core, helpmsg);
			}
			break;
		case 'o': // "eco"
			if (input[2] == ' ') {
				char *home, path[512];
				snprintf (path, sizeof (path), ".config/radare2/cons/%s", input+3);
				home = r_str_home (path);
				snprintf (path, sizeof (path), R2_DATDIR"/radare2/"
					R2_VERSION"/cons/%s", input+3);
				if (!r_core_cmd_file (core, home))
					if (!r_core_cmd_file (core, path))
						if (!r_core_cmd_file (core, input+3))
							eprintf ("eco: cannot open colorscheme profile (%s)\n", path);
				free (home);
			} else {
				RList *files;
				RListIter *iter;
				const char *fn;
				char *home = r_str_home (".config/radare2/cons/");
				if (home) {
					files = r_sys_dir (home);
					r_list_foreach (files, iter, fn) {
						if (*fn && *fn != '.')
							r_cons_printf ("%s\n", fn);
					}
					r_list_free (files);
					free (home);
				}
				files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/");
				r_list_foreach (files, iter, fn) {
					if (*fn && *fn != '.')
						r_cons_printf ("%s\n", fn);
				}
				r_list_free (files);
			}
			break;
		case 's': r_cons_pal_show (); break;
		case '*': r_cons_pal_list (1); break;
		case 'j': r_cons_pal_list ('j'); break;
		case 'c': r_cons_pal_list ('c'); break;
		case '\0': r_cons_pal_list (0); break;
		case 'r': r_cons_pal_random (); break;
		default: {
			char *p = strdup (input+2);
			char *q = strchr (p, '=');
			if (!q) q = strchr (p, ' ');
			if (q) {
				// set
				*q++ = 0;
				r_cons_pal_set (p, q);
			} else {
				const char *k = r_cons_pal_get (p);
				if (k)
					eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k);
			}
			free (p);
		}
		}
		break;
	case 'e':
		if (input[1]==' ') {
			char *p;
			const char *val, *input2 = strchr (input+2, ' ');
			if (input2) input2++; else input2 = input+2;
			val = r_config_get (core->config, input2);
			p = r_core_editor (core, NULL, val);
			if (p) {
				r_str_replace_char (p, '\n', ';');
				r_config_set (core->config, input2, p);
			}
		} else eprintf ("Usage: ee varname\n");
		break;
	case '!':
		input = r_str_chop_ro (input+1);
		if (!r_config_swap (core->config, input))
			eprintf ("r_config: '%s' is not a boolean variable.\n", input);
		break;
	case '-':
		r_core_config_init (core);
		eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n");
		break;
	case 'v': eprintf ("Invalid command '%s'. Use 'e?'\n", input); break;
	case '*': r_config_list (core->config, NULL, 1); break;
	case '?':
		switch (input[1]) {
		case '?': r_config_list (core->config, input+2, 2); break;
		default: r_config_list (core->config, input+1, 2); break;
		case 0:{
			const char* help_msg[] = {
			"Usage:", "e[?] [var[=value]]", "Evaluable vars",
			"e","?asm.bytes", "show description",
			"e", "??", "list config vars with description",
			"e", "", "list config vars",
			"e-", "", "reset config vars",
			"e*", "", "dump config vars in r commands",
			"e!", "a", "invert the boolean value of 'a' var",
			"er", " [key]", "set config key as readonly. no way back",
			"ec", " [k] [color]", "set color for given key (prompt, offset, ...)",
			"e", " a", "get value of var 'a'",
			"e", " a=b", "set var 'a' the 'b' value",
			"env", " [k[=v]]", "get/set environment variable",
			NULL};
			r_core_cmd_help (core, help_msg);
			}
		}
		break;
	case 'r':
		if (input[1]) {
			const char *key = input+((input[1]==' ')?2:1);
			if (!r_config_readonly (core->config, key))
				eprintf ("cannot find key '%s'\n", key);
		} else eprintf ("Usage: er [key]\n");
		break;
	case ' ': r_config_eval (core->config, input+1); break;
	default: r_config_eval (core->config, input); break;
	}
	return 0;
}
コード例 #13
0
ファイル: rtr.c プロジェクト: 0xroot/radare2
- follow symlinks
#endif

R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
	RSocketHTTPRequest *rs;
	int oldsandbox = -1;
	int timeout = r_config_get_i (core->config, "http.timeout");
	int x = r_config_get_i (core->config, "scr.html");
	int y = r_config_get_i (core->config, "scr.color");
	int z = r_config_get_i (core->config, "asm.bytes");
	int u = r_config_get_i (core->config, "scr.interactive");
	int v = r_config_get_i (core->config, "asm.cmtright");
	const char *port = r_config_get (core->config, "http.port");
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return 1;
	}
	s = r_socket_new (R_FALSE);
	s->local = !r_config_get_i (core->config, "http.public");
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on http.port\n");
		return 1;
	}
	if (launch) {
		char cmd[128];
		const char *browser = r_config_get (core->config, "http.browser");
		snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s",
			browser, atoi (port), path?path:"");
		r_sys_cmd (cmd);
	}
	r_config_set (core->config, "asm.cmtright", "false");
	r_config_set (core->config, "scr.html", "true");
	r_config_set (core->config, "scr.color", "false");
	r_config_set (core->config, "asm.bytes", "false");
	r_config_set (core->config, "scr.interactive", "false");
	if (r_config_get_i (core->config, "http.sandbox")) {
		oldsandbox = r_config_get_i (core->config, "cfg.sandbox");
		r_config_set (core->config, "cfg.sandbox", "true");
	}
	eprintf ("Starting http server...\n");
	eprintf ("http://localhost:%d/\n", atoi (port));
	while (!r_cons_singleton ()->breaked) {
		r_cons_break (http_break, core);
		rs = r_socket_http_accept (s, timeout);
		if (!rs) {
			if (!s) break;
			r_sys_usleep (200);
			continue;
		}
		if (!rs->method || !rs->path) {
			r_socket_http_close (rs);
			continue;
		}
		if (!strcmp (rs->method, "GET")) {
			if (!memcmp (rs->path, "/up", 3)) {
				if (r_config_get_i (core->config, "http.upget")) {
					const char *uproot = r_config_get (core->config, "http.uproot");
					if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) {
						char *ptr = strdup ("<html><body>\n");
						const char *file;
						RListIter *iter;
						// list files
						RList *files = r_sys_dir (uproot);
						eprintf ("Listing directory %s\n", uproot);
						r_list_foreach (files, iter, file) {
							if (file[0] == '.') continue;
							ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n",
								file, file);
						}
						r_list_free (files);
						ptr = r_str_concat (ptr, "<html><body>\n");
						r_socket_http_response (rs, 200, ptr, 0, NULL);
					} else {
						char *path = r_file_root (uproot, rs->path + 4);
						if (r_file_exists (path)) {
							int sz = 0;
							char *f = r_file_slurp (path, &sz);
							if (f) {
								r_socket_http_response (rs, 200, f, sz, NULL);
								free (f);
							} else {
								r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
								eprintf ("http: Cannot open '%s'\n", path);
							}
						} else {
							eprintf ("File '%s' not found\n", path);
							r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
						}
						free (path);
					}
				} else {
					r_socket_http_response (rs, 403,
							"Permission denied\n", 0, NULL);
				}
			} else if (!memcmp (rs->path, "/cmd/", 5)) {
コード例 #14
0
ファイル: cmd_eval.c プロジェクト: XVilka/radare2
static void nextpal(RCore *core, int mode) {
// TODO: use r_core_list_themes() here instead of rewalking all the time
	RList *files = NULL;
	RListIter *iter;
	const char *fn;
	int ctr = 0;
	char *home = r_str_home (".config/radare2/cons/");

	getNext = false;
	if (mode == 'j') {
		r_cons_printf ("[");
	}
	if (home) {
		files = r_sys_dir (home);
		r_list_foreach (files, iter, fn) {
			if (*fn && *fn != '.') {
				if (mode == 'p') {
					const char *nfn = iter->n? iter->n->data: NULL;
					if (!curtheme) {
						free (home);
						r_list_free (files);
						return;
					}
					eprintf ("%s %s %s\n", nfn, curtheme, fn);
					if (nfn && !strcmp (nfn, curtheme)) {
						r_list_free (files);
						files = NULL;
						free (curtheme);
						curtheme = strdup (fn);
						R_FREE (home);
						goto done;
					}
				} else {
					if (!nextpal_item (core, mode, fn, ctr++)) {
						r_list_free (files);
						files = NULL;
						R_FREE (home);
						goto done;
					}
				}
			}
		}
		r_list_free (files);
		R_FREE (home);
	}
	files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/");
	r_list_foreach (files, iter, fn) {
		if (*fn && *fn != '.') {
			if (mode == 'p') {
				const char *nfn = iter->n? iter->n->data: NULL;
				if (!curtheme) {
					free (home);
					r_list_free (files);
					return;
				}
				eprintf ("%s %s %s\n", nfn, curtheme, fn);
				if (nfn && !strcmp (nfn, curtheme)) {
					free (curtheme);
					curtheme = strdup (fn);
					goto done;
				}
			} else {
				if (!nextpal_item (core, mode, fn, ctr++)) {
					goto done;
				}
			}
		}
	}
done:
	if (getNext) {
		R_FREE (curtheme);
		nextpal (core, mode);
		return;
	}
	if (mode == 'l' && !curtheme && !r_list_empty (files)) {
		//nextpal (core, mode);
	} else {
		if (curtheme) {
			r_core_cmdf (core, "eco %s", curtheme);
		}
	}
	r_list_free (files);
	files = NULL;
	if (mode == 'j') {
		r_cons_printf ("]\n");
	}
}