2012-08-08 15:19:48 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2012 - pancake, nibble */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include <r_cons.h>
|
2010-08-12 23:18:06 +00:00
|
|
|
#include <r_util.h>
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2012-08-09 16:19:00 +00:00
|
|
|
R_API void r_cons_grep_help() {
|
|
|
|
eprintf (
|
|
|
|
"Usage: [command]~[modifier][word,word]\n"
|
|
|
|
" modifiers\n"
|
|
|
|
" & all words must match to grep the line\n"
|
|
|
|
" ^ words must be placed at the begining of line\n"
|
|
|
|
" ! negate grep\n"
|
|
|
|
" ? count number of matching lines\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2010-02-21 19:21:36 +00:00
|
|
|
R_API void r_cons_grep(const char *str) {
|
2012-08-09 16:19:00 +00:00
|
|
|
int wlen, len;
|
2010-02-21 19:21:36 +00:00
|
|
|
RCons *cons;
|
2012-08-08 08:56:25 +00:00
|
|
|
char buf[4096];
|
2010-07-16 12:53:06 +00:00
|
|
|
char *ptr, *optr, *ptr2, *ptr3;
|
2012-08-03 22:46:00 +00:00
|
|
|
|
2012-08-08 08:56:25 +00:00
|
|
|
if (!str || !*str)
|
|
|
|
return;
|
|
|
|
|
2010-02-21 19:21:36 +00:00
|
|
|
cons = r_cons_singleton ();
|
2010-07-16 12:53:06 +00:00
|
|
|
cons->grep.str = NULL;
|
2012-06-21 08:12:02 +00:00
|
|
|
cons->grep.neg = 0;
|
2012-08-09 16:19:00 +00:00
|
|
|
cons->grep.amp = 0;
|
2012-06-21 08:12:02 +00:00
|
|
|
cons->grep.begin = 0;
|
|
|
|
cons->grep.end = 0;
|
2010-07-16 12:53:06 +00:00
|
|
|
cons->grep.nstrings = 0;
|
2010-08-03 09:36:41 +00:00
|
|
|
cons->grep.tokenfrom = 0;
|
|
|
|
cons->grep.tokento = ST32_MAX;
|
|
|
|
cons->grep.line = -1;
|
2010-07-16 12:53:06 +00:00
|
|
|
cons->grep.counter = cons->grep.neg = 0;
|
2010-01-30 13:02:53 +00:00
|
|
|
|
2012-08-09 16:19:00 +00:00
|
|
|
while (*str) {
|
|
|
|
switch (*str) {
|
|
|
|
case '&': str++; cons->grep.amp = 1; break;
|
|
|
|
case '^': str++; cons->grep.begin = 1; break;
|
|
|
|
case '!': str++; cons->grep.neg = 1; break;
|
|
|
|
case '?': str++; cons->grep.counter = 1;
|
|
|
|
if (*str=='?') {
|
|
|
|
r_cons_grep_help ();
|
|
|
|
str = "THIS\x01IS\x02A\x03HACK\x04:D";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default: goto while_end;
|
|
|
|
}
|
|
|
|
} while_end:
|
|
|
|
|
2012-08-03 22:46:00 +00:00
|
|
|
len = strlen (str)-1;
|
2012-08-08 08:56:25 +00:00
|
|
|
if (len>0 && str[len] == '?') {
|
2012-08-03 22:46:00 +00:00
|
|
|
cons->grep.counter = 1;
|
2012-08-08 08:56:25 +00:00
|
|
|
strncpy (buf, str, R_MIN (len, sizeof (buf)-1));
|
|
|
|
buf[len]=0;
|
2012-08-03 22:46:00 +00:00
|
|
|
len--;
|
|
|
|
} else strncpy (buf, str, sizeof (buf)-1);
|
2010-07-16 12:53:06 +00:00
|
|
|
|
2012-08-03 22:46:00 +00:00
|
|
|
if (len>1 && buf[len]=='$' && buf[len-1]!='\\') {
|
|
|
|
cons->grep.end = 1;
|
|
|
|
buf[len] = 0;
|
2012-06-21 08:12:02 +00:00
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
ptr = buf;
|
|
|
|
ptr3 = strchr (ptr, '['); // column number
|
|
|
|
if (ptr3) {
|
2012-08-03 22:46:00 +00:00
|
|
|
ptr3[0] = '\0';
|
2011-06-26 21:49:11 +00:00
|
|
|
cons->grep.tokenfrom = r_num_get (cons->num, ptr3+1);
|
2010-08-03 09:36:41 +00:00
|
|
|
ptr3 = strchr (ptr3+1, '-');
|
|
|
|
if (ptr3) {
|
2011-06-26 21:49:11 +00:00
|
|
|
cons->grep.tokento = r_num_get (cons->num, ptr3+1);
|
2010-08-03 09:36:41 +00:00
|
|
|
if (cons->grep.tokento == 0)
|
|
|
|
cons->grep.tokento = ST32_MAX;
|
|
|
|
} else cons->grep.tokento = cons->grep.tokenfrom;
|
|
|
|
if (cons->grep.tokenfrom<0)
|
|
|
|
cons->grep.tokenfrom = 0;
|
|
|
|
if (cons->grep.tokento<0)
|
|
|
|
cons->grep.tokento = ST32_MAX;
|
2010-07-16 12:53:06 +00:00
|
|
|
}
|
|
|
|
ptr2 = strchr (ptr, ':'); // line number
|
|
|
|
if (ptr2) {
|
2011-06-26 21:49:11 +00:00
|
|
|
*ptr2 = '\0';
|
|
|
|
cons->grep.line = r_num_get (cons->num, ptr2+1);
|
2010-07-16 12:53:06 +00:00
|
|
|
if (cons->grep.line<0)
|
|
|
|
cons->grep.line = -1;
|
|
|
|
}
|
2011-02-05 01:55:50 +00:00
|
|
|
free (cons->grep.str);
|
2010-07-16 12:53:06 +00:00
|
|
|
if (*ptr) {
|
|
|
|
cons->grep.str = (char *)strdup (ptr);
|
|
|
|
do {
|
|
|
|
optr = ptr;
|
|
|
|
ptr = strchr (ptr, ','); // grep keywords
|
2011-09-18 18:41:36 +00:00
|
|
|
if (ptr) *ptr++ = '\0';
|
2012-08-09 16:19:00 +00:00
|
|
|
wlen = strlen (optr);
|
|
|
|
if (wlen==0) continue;
|
|
|
|
if (wlen>=R_CONS_GREP_WORD_SIZE-1) {
|
|
|
|
eprintf ("grep string too long\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
strncpy (cons->grep.strings[cons->grep.nstrings], optr, R_CONS_GREP_WORD_SIZE-1);
|
2010-02-21 19:21:36 +00:00
|
|
|
cons->grep.nstrings++;
|
2012-08-09 16:19:00 +00:00
|
|
|
if (cons->grep.nstrings>R_CONS_GREP_WORDS-1) {
|
|
|
|
eprintf ("too many grep strings\n");
|
|
|
|
break;
|
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
} while (ptr);
|
2011-02-05 01:55:50 +00:00
|
|
|
} else {
|
|
|
|
cons->grep.str = strdup (ptr);
|
|
|
|
cons->grep.nstrings++;
|
|
|
|
cons->grep.strings[0][0] = 0;
|
2010-01-30 13:02:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-24 23:44:15 +00:00
|
|
|
R_API int r_cons_grepbuf(char *buf, int len) {
|
2010-07-16 12:53:06 +00:00
|
|
|
RCons *cons = r_cons_singleton ();
|
2010-08-03 11:30:58 +00:00
|
|
|
char *tline, *tbuf, *p, *out, *in = buf;
|
2010-08-12 23:18:06 +00:00
|
|
|
int ret, buffer_len = 0, l = 0, tl = 0;
|
2010-07-16 12:53:06 +00:00
|
|
|
|
2012-08-28 15:50:49 +00:00
|
|
|
if (!cons->buffer) {
|
|
|
|
cons->buffer_len = len+20;
|
|
|
|
cons->buffer = malloc (cons->buffer_len);
|
|
|
|
cons->buffer[0] = 0;
|
|
|
|
}
|
2010-07-16 16:44:39 +00:00
|
|
|
out = tbuf = calloc (1, len);
|
2010-08-03 11:30:58 +00:00
|
|
|
tline = malloc (len);
|
2010-07-16 12:53:06 +00:00
|
|
|
cons->lines = 0;
|
|
|
|
while (in-buf<len) {
|
|
|
|
p = strchr (in, '\n');
|
2010-07-16 16:44:39 +00:00
|
|
|
if (!p) {
|
|
|
|
free (tbuf);
|
2010-08-03 11:30:58 +00:00
|
|
|
free (tline);
|
2010-07-16 16:44:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2010-07-18 10:33:47 +00:00
|
|
|
l = p-in;
|
2010-08-03 11:30:58 +00:00
|
|
|
if (l > 0) {
|
2010-07-16 12:53:06 +00:00
|
|
|
memcpy (tline, in, l);
|
2010-08-12 23:18:06 +00:00
|
|
|
tl = r_str_ansi_filter (tline, l);
|
|
|
|
if (tl < 0)
|
|
|
|
ret = -1;
|
|
|
|
else ret = r_cons_grep_line (tline, tl);
|
2010-07-16 12:53:06 +00:00
|
|
|
if (ret > 0) {
|
2010-07-16 16:44:39 +00:00
|
|
|
if (cons->grep.line == -1 ||
|
|
|
|
(cons->grep.line != -1 && cons->grep.line == cons->lines)) {
|
2010-07-16 12:53:06 +00:00
|
|
|
memcpy (out, tline, ret);
|
2010-08-03 11:30:58 +00:00
|
|
|
memcpy (out+ret, "\n", 1);
|
|
|
|
out += ret+1;
|
|
|
|
buffer_len += ret+1;
|
2010-07-16 12:53:06 +00:00
|
|
|
}
|
|
|
|
cons->lines++;
|
2010-07-16 16:44:39 +00:00
|
|
|
} else if (ret < 0) {
|
2010-07-16 12:53:06 +00:00
|
|
|
free (tbuf);
|
2010-08-03 11:30:58 +00:00
|
|
|
free (tline);
|
2010-07-16 12:53:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
in += l+1;
|
|
|
|
} else in++;
|
2010-06-24 23:44:15 +00:00
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
memcpy (buf, tbuf, len);
|
|
|
|
cons->buffer_len = buffer_len;
|
|
|
|
free (tbuf);
|
2010-08-03 11:30:58 +00:00
|
|
|
free (tline);
|
2011-02-05 01:55:50 +00:00
|
|
|
if (cons->grep.counter) {
|
2012-08-28 15:50:49 +00:00
|
|
|
if (cons->buffer_len<10) cons->buffer_len = 10; // HACK
|
2011-04-04 16:33:27 +00:00
|
|
|
snprintf (cons->buffer, cons->buffer_len, "%d\n", cons->lines);
|
2012-08-28 15:50:49 +00:00
|
|
|
cons->buffer_len = strlen (cons->buffer);
|
2011-02-05 01:55:50 +00:00
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
return cons->lines;
|
2010-06-24 23:44:15 +00:00
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
|
2010-06-24 23:44:15 +00:00
|
|
|
R_API int r_cons_grep_line(char *buf, int len) {
|
2010-02-21 19:21:36 +00:00
|
|
|
RCons *cons = r_cons_singleton ();
|
2010-06-24 23:44:15 +00:00
|
|
|
const char delims[6][2] = { "|", "/", "\\", ",", ";", "\t" };
|
2010-08-03 11:30:58 +00:00
|
|
|
char *in, *out, *tok = NULL;
|
2010-07-16 12:53:06 +00:00
|
|
|
int hit = cons->grep.neg;
|
2011-04-04 16:33:27 +00:00
|
|
|
int i, j, outlen = 0;
|
2010-01-30 13:02:53 +00:00
|
|
|
|
2010-08-03 11:30:58 +00:00
|
|
|
in = calloc (1, len+1);
|
|
|
|
out = calloc (1, len+2);
|
|
|
|
memcpy (in, buf, len);
|
|
|
|
|
2010-07-18 10:33:47 +00:00
|
|
|
if (cons->grep.nstrings>0) {
|
2012-08-09 16:19:00 +00:00
|
|
|
int ampfail = cons->grep.amp;
|
2012-06-21 08:12:02 +00:00
|
|
|
for (i=0; i<cons->grep.nstrings; i++) {
|
|
|
|
char *p = strstr (in, cons->grep.strings[i]);
|
2012-08-09 16:19:00 +00:00
|
|
|
if (!p) {
|
|
|
|
ampfail = 0;
|
|
|
|
continue;
|
|
|
|
}
|
2012-06-21 08:12:02 +00:00
|
|
|
if (cons->grep.begin)
|
|
|
|
hit = (p == in)? 1: 0;
|
|
|
|
else hit = !cons->grep.neg;
|
2012-08-09 16:19:00 +00:00
|
|
|
// TODO: optimize this strlen
|
2012-06-21 08:12:02 +00:00
|
|
|
if (cons->grep.end && (strlen (cons->grep.strings[i]) != strlen (p)))
|
|
|
|
hit = 0;
|
2012-08-09 16:19:00 +00:00
|
|
|
if (!cons->grep.amp)
|
|
|
|
break;
|
2012-06-21 08:12:02 +00:00
|
|
|
}
|
2012-08-09 16:19:00 +00:00
|
|
|
if (cons->grep.amp)
|
|
|
|
hit = ampfail;
|
2010-07-18 10:33:47 +00:00
|
|
|
} else hit = 1;
|
2010-01-30 13:02:53 +00:00
|
|
|
|
2010-07-16 12:53:06 +00:00
|
|
|
if (hit) {
|
2010-08-03 09:36:41 +00:00
|
|
|
if ((cons->grep.tokenfrom != 0 || cons->grep.tokento != ST32_MAX) &&
|
|
|
|
(cons->grep.line == -1 || cons->grep.line == cons->lines)) {
|
2010-03-07 23:18:58 +00:00
|
|
|
for (i=0; i<len; i++) for (j=0; j<6; j++)
|
2010-08-03 09:36:41 +00:00
|
|
|
if (in[i] == delims[j][0])
|
|
|
|
in[i] = ' ';
|
2010-08-03 11:30:58 +00:00
|
|
|
for (i=0; i <= cons->grep.tokento; i++) {
|
2011-04-04 16:33:27 +00:00
|
|
|
tok = (char *) strtok (i?NULL:in, " ");
|
|
|
|
if (tok) {
|
|
|
|
if (i >= cons->grep.tokenfrom) {
|
|
|
|
int toklen = strlen (tok);
|
|
|
|
memcpy (out+outlen, tok, toklen);
|
|
|
|
memcpy (out+outlen+toklen, " ", 2);
|
|
|
|
outlen += toklen+1;
|
|
|
|
}
|
|
|
|
} else {
|
2010-08-03 11:30:58 +00:00
|
|
|
if (strlen (out) == 0) {
|
|
|
|
free (in);
|
|
|
|
free (out);
|
|
|
|
return -1;
|
|
|
|
} else break;
|
2010-08-03 09:36:41 +00:00
|
|
|
}
|
2010-01-30 13:02:53 +00:00
|
|
|
}
|
2011-04-04 16:33:27 +00:00
|
|
|
outlen = outlen>0? outlen - 1: 0;
|
|
|
|
if (outlen>len) { // should never happen
|
|
|
|
eprintf ("r_cons_grep_line: wtf, how you reach this?\n");
|
2012-08-08 15:19:48 +00:00
|
|
|
free (in);
|
|
|
|
free (out);
|
2011-04-04 16:33:27 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2010-08-03 09:36:41 +00:00
|
|
|
memcpy (buf, out, len);
|
2011-04-04 16:33:27 +00:00
|
|
|
len = outlen;
|
|
|
|
|
2010-06-25 09:22:14 +00:00
|
|
|
}
|
2010-07-16 12:53:06 +00:00
|
|
|
} else len = 0;
|
|
|
|
|
2010-08-03 11:30:58 +00:00
|
|
|
free (in);
|
|
|
|
free (out);
|
|
|
|
|
2010-07-16 12:53:06 +00:00
|
|
|
return len;
|
2010-01-30 13:02:53 +00:00
|
|
|
}
|
|
|
|
|
2011-04-29 08:38:01 +00:00
|
|
|
static const char *gethtmlcolor(const char ptrch, const char *def) {
|
|
|
|
switch (ptrch) {
|
|
|
|
case '0': return "#000"; // BLACK
|
|
|
|
case '1': return "#f00"; // RED
|
|
|
|
case '2': return "#0f0"; // GREEN
|
|
|
|
case '3': return "#ff0"; // YELLOW
|
|
|
|
case '4': return "#00f"; // BLUE
|
|
|
|
case '5': return "#f0f"; // MAGENTA
|
|
|
|
case '6': return "#aaf"; // TURQOISE
|
|
|
|
case '7': return "#fff"; // WHITE
|
|
|
|
case '8': return "#777"; // GREY
|
|
|
|
case '9': break; // ???
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2010-01-26 00:28:33 +00:00
|
|
|
// XXX: rename char *r_cons_filter_html(const char *ptr)
|
2010-03-07 23:18:58 +00:00
|
|
|
R_API int r_cons_html_print(const char *ptr) {
|
2010-01-26 00:28:33 +00:00
|
|
|
const char *str = ptr;
|
2009-02-05 21:08:46 +00:00
|
|
|
int esc = 0;
|
|
|
|
int len = 0;
|
|
|
|
int inv = 0;
|
2010-10-27 14:31:51 +00:00
|
|
|
int tmp;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2011-09-02 00:03:38 +00:00
|
|
|
if (!ptr)
|
|
|
|
return 0;
|
2009-02-05 21:08:46 +00:00
|
|
|
for (;ptr[0]; ptr = ptr + 1) {
|
|
|
|
if (ptr[0] == '\n') {
|
2010-06-24 23:44:15 +00:00
|
|
|
printf ("<br />");
|
|
|
|
fflush (stdout);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
if (ptr[0] == 0x1b) {
|
|
|
|
esc = 1;
|
2010-10-27 14:31:51 +00:00
|
|
|
tmp = (int) (size_t) (ptr-str);
|
|
|
|
if (write (1, str, tmp) != tmp)
|
|
|
|
eprintf ("r_cons_html_print: write: error\n");
|
2009-02-05 21:08:46 +00:00
|
|
|
str = ptr + 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (esc == 1) {
|
|
|
|
// \x1b[2J
|
|
|
|
if (ptr[0] != '[') {
|
2010-06-24 23:44:15 +00:00
|
|
|
eprintf ("Oops invalid escape char\n");
|
2009-02-05 21:08:46 +00:00
|
|
|
esc = 0;
|
|
|
|
str = ptr + 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
esc = 2;
|
|
|
|
continue;
|
|
|
|
} else
|
|
|
|
if (esc == 2) {
|
2012-08-03 22:46:00 +00:00
|
|
|
// TODO: use dword comparison here
|
|
|
|
if (ptr[0]=='2' && ptr[1]=='J') {
|
2010-06-24 23:44:15 +00:00
|
|
|
printf ("<hr />\n"); fflush(stdout);
|
2011-04-29 08:38:01 +00:00
|
|
|
ptr++;
|
2009-02-05 21:08:46 +00:00
|
|
|
esc = 0;
|
|
|
|
str = ptr;
|
|
|
|
continue;
|
|
|
|
} else
|
2012-08-03 22:46:00 +00:00
|
|
|
if (ptr[0]=='0' && ptr[1]==';' && ptr[2]=='0') {
|
|
|
|
r_cons_gotoxy (0, 0);
|
2011-04-29 08:38:01 +00:00
|
|
|
ptr += 4;
|
2009-02-05 21:08:46 +00:00
|
|
|
esc = 0;
|
|
|
|
str = ptr;
|
|
|
|
continue;
|
|
|
|
} else
|
2012-08-03 22:46:00 +00:00
|
|
|
if (ptr[0]=='0' && ptr[1]=='m') {
|
|
|
|
str = (++ptr) + 1;
|
2011-04-29 08:38:01 +00:00
|
|
|
esc = inv = 0;
|
2009-02-05 21:08:46 +00:00
|
|
|
continue;
|
|
|
|
// reset color
|
|
|
|
} else
|
2012-08-03 22:46:00 +00:00
|
|
|
if (ptr[0]=='7' && ptr[1]=='m') {
|
2011-04-29 08:38:01 +00:00
|
|
|
str = (++ptr) +1;
|
2009-02-05 21:08:46 +00:00
|
|
|
inv = 128;
|
|
|
|
esc = 0;
|
|
|
|
continue;
|
|
|
|
// reset color
|
|
|
|
} else
|
|
|
|
if (ptr[0]=='3' && ptr[2]=='m') {
|
2011-04-29 08:38:01 +00:00
|
|
|
// TODO: honor inv here
|
|
|
|
printf ("<font color='%s'>", gethtmlcolor (ptr[1], "#000"));
|
|
|
|
fflush(stdout);
|
2009-02-05 21:08:46 +00:00
|
|
|
ptr = ptr + 1;
|
|
|
|
str = ptr + 2;
|
|
|
|
esc = 0;
|
|
|
|
continue;
|
|
|
|
} else
|
|
|
|
if (ptr[0]=='4' && ptr[2]=='m') {
|
2011-04-29 08:38:01 +00:00
|
|
|
// TODO: USE INV HERE
|
|
|
|
printf ("<font style='background-color:%s'>", gethtmlcolor (ptr[1], "#fff"));
|
|
|
|
fflush(stdout);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
len++;
|
|
|
|
}
|
2010-01-26 00:28:33 +00:00
|
|
|
write (1, str, ptr-str);
|
2009-02-05 21:08:46 +00:00
|
|
|
return len;
|
|
|
|
}
|