1 /* radare - LGPL - Copyright 2009-2020 - pancake */
2 
3 #include <r_core.h>
4 
r_core_log_list(RCore * core,int n,int nth,char fmt)5 R_API int r_core_log_list(RCore *core, int n, int nth, char fmt) {
6 	int printed = 0;
7 	int count = 0, i, idx, id = core->log->first;
8 	RStrpool *sp = core->log->sp;
9 	char *str = sp->str;
10 
11 	if (fmt == 'j') {
12 		r_cons_printf ("[");
13 	}
14 	for (i = idx = 0; str && *str; i++, id++) {
15 		if ((n && n <= id) || !n) {
16 			switch (fmt) {
17 			case 'j':
18 				r_cons_printf ("%s[%d,\"%s\"]",
19 					printed? ",": "", id, str);
20 				break;
21 			case 't':
22 				r_cons_println (str);
23 				break;
24 			case '*':
25 				r_cons_printf ("\"T %s\"\n", str);
26 				break;
27 			default:
28 				r_cons_printf ("%d %s\n", id, str);
29 				break;
30 			}
31 			printed++;
32 			if (nth && printed >= nth) {
33 				break;
34 			}
35 		}
36 		str = r_strpool_next (sp, idx);
37 		if (!str) {
38 			break;
39 		}
40 		idx = r_strpool_get_index (sp, str);
41 		count++;
42 	}
43 	if (fmt == 'j') {
44 		r_cons_printf ("]\n");
45 	}
46 	return count;
47 }
48 
r_core_log_new(void)49 R_API RCoreLog *r_core_log_new(void) {
50 	RCoreLog *log = R_NEW0 (RCoreLog);
51 	if (!log) {
52 		return NULL;
53 	}
54 	r_core_log_init (log);
55 	return log;
56 }
57 
r_core_log_init(RCoreLog * log)58 R_API void r_core_log_init(RCoreLog *log) {
59 	log->first = 1;
60 	log->last = 1;
61 	log->sp = r_strpool_new (0);
62 }
63 
r_core_log_free(RCoreLog * log)64 R_API void r_core_log_free(RCoreLog *log) {
65 	r_strpool_free (log->sp);
66 	free (log);
67 }
68 
r_core_log_run(RCore * core,const char * _buf,RCoreLogCallback runLine)69 R_API bool r_core_log_run(RCore *core, const char *_buf, RCoreLogCallback runLine) {
70 	char *obuf = strdup (_buf);
71 	char *buf = obuf;
72 	while (buf) {
73 		char *nl = strchr (buf, '\n');
74 		if (nl) {
75 			*nl = 0;
76 		}
77 		char *sp = strchr (buf, ' ');
78 		if (sp) {
79 			runLine (core, atoi (buf), sp + 1);
80 		}
81 		if (nl) {
82 			buf = nl + 1;
83 		} else {
84 			break;
85 		}
86 	}
87 	free (obuf);
88 	return true;
89 }
90 
r_core_log_get(RCore * core,int index)91 R_API char *r_core_log_get(RCore *core, int index) {
92 	const char *host = r_config_get (core->config, "http.sync");
93 	if (host && *host) {
94 		char *url = index > 0
95 			? r_str_newf ("%s/cmd/T%%20%d", host, index)
96 			: r_str_newf ("%s/cmd/T", host);
97 		char *res = r_socket_http_get (url, NULL, NULL);
98 		free (url);
99 		return res? res: strdup ("");
100 	}
101 	return NULL;
102 }
103 
r_core_log_add(RCore * core,const char * msg)104 R_API void r_core_log_add(RCore *core, const char *msg) {
105 	static bool inProcess = false;
106 	r_strpool_append (core->log->sp, msg);
107 	core->log->last++;
108 	if (core->cmdlog && *core->cmdlog) {
109 		if (inProcess) {
110 			// avoid infinite recursive calls
111 			return;
112 		}
113 		inProcess = true;
114 		r_core_cmd0 (core, core->cmdlog);
115 		inProcess = false;
116 	}
117 }
118 
r_core_log_del(RCore * core,int n)119 R_API void r_core_log_del(RCore *core, int n) {
120 	int idx;
121 	if (n > 0) {
122 		if (n + 1 >= core->log->last) {
123 			core->log->first = core->log->last;
124 			r_strpool_empty (core->log->sp);
125 			return;
126 		}
127 		if (n < core->log->first) {
128 			return;
129 		}
130 		idx = n - core->log->first;
131 		if (idx < 0) {
132 			return;
133 		}
134 		core->log->first += idx + 1;
135 		char *msg = r_strpool_get_i (core->log->sp, idx);
136 		// if (idx >= core->log->last) {
137 		if (!msg || !*msg) {
138 			core->log->first = core->log->last;
139 			r_strpool_empty (core->log->sp);
140 		} else {
141 			r_strpool_slice (core->log->sp, idx);
142 		}
143 	} else {
144 		core->log->first = core->log->last;
145 		r_strpool_empty (core->log->sp);
146 	}
147 }
148