Rizin
unix-like reverse engineering framework and cli tools
spp.h
Go to the documentation of this file.
1 /* Mini MCMS :: renamed to 'spp'? */
2 
3 #ifndef INCLUDE_P_SPP_H
4 #define INCLUDE_P_SPP_H
5 
6 #if __UNIX__
7 #include <unistd.h>
8 #endif
9 
10 static char *spp_var_get(char *var) {
11  return rz_sys_getenv (var);
12 }
13 
14 static int spp_var_set(const char *var, const char *val) {
15  return rz_sys_setenv (var, val);
16 }
17 
18 #if HAVE_SYSTEM
19 /* Should be dynamic buffer */
20 static char *cmd_to_str(const char *cmd) {
21  char *out = (char *)calloc (4096, 1);
22  char *tout;
23  int ret = 0, len = 0, outlen = 4096;
24  FILE *fd = popen (cmd, "r");
25  while (fd) {
26  len += ret;
27  ret = fread (out + len, 1, 1023, fd);
28  if (ret < 1) {
29  pclose (fd);
30  fd = NULL;
31  }
32  if (ret + 1024 > outlen) {
33  outlen += 4096;
34  tout = realloc (out, outlen);
35  if (!tout) {
36  if (fd) {
37  pclose (fd);
38  fd = NULL;
39  }
40  fprintf (stderr, "Out of memory.\n");
41  break;
42  }
43  out = tout;
44  }
45  }
46  out[len] = '\0';
47  return out;
48 }
49 #endif
50 
51 static TAG_CALLBACK(spp_set) {
52  char *eq, *val = "";
53  if (!state->echo[state->ifl]) {
54  return 0;
55  }
56  for (eq=buf; eq[0]; eq++) {
57  switch (eq[0]) {
58  case '-':
59  case '.':
60  eq[0] = '_';
61  break;
62  }
63  }
64  eq = strchr (buf, ' ');
65  if (eq) {
66  *eq = '\0';
67  val = eq + 1;
68  }
69  if (spp_var_set (buf, val) == -1) {
70  fprintf (stderr, "Invalid variable name '%s' at line %d\n", buf, state->lineno);
71  }
72  return 0;
73 }
74 
75 static TAG_CALLBACK(spp_get) {
76  char *var;
77  if (!state->echo[state->ifl]) {
78  return 0;
79  }
80  var = spp_var_get (buf);
81  if (var) {
82  out_printf (out, "%s", var);
83  }
84  return 0;
85 }
86 
87 static TAG_CALLBACK(spp_getrandom) {
88  int max;
89  if (!state->echo[state->ifl]) {
90  return 0;
91  }
92  // XXX srsly? this is pretty bad random
93  srandom (rz_sys_getpid ()); // TODO: change this to be portable
94  max = atoi (buf);
95  if (max > 0) {
96  max = (int)(rand () % max);
97  }
98  out_printf (out, "%d", max);
99  return 0;
100 }
101 
102 static TAG_CALLBACK(spp_add) {
103  char res[32];
104  char *var, *eq = strchr (buf, ' ');
105  int ret = 0;
106  if (!state->echo[state->ifl]) {
107  return 0;
108  }
109  if (eq) {
110  *eq = '\0';
111  var = spp_var_get (buf);
112  if (var) {
113  ret = atoi (var);
114  }
115  ret += atoi (eq + 1);
116  snprintf (res, sizeof (res), "%d", ret);
117  rz_sys_setenv (buf, res);
118  } else {
119  /* syntax error */
120  }
121  return 0;
122 }
123 
124 static TAG_CALLBACK(spp_sub) {
125  char *eq = strchr(buf, ' ');
126  char *var;
127  int ret = 0;
128  if (!state->echo[state->ifl]) {
129  return 0;
130  }
131  if (eq) {
132  *eq = '\0';
133  var = spp_var_get (buf);
134  ret = var? atoi (var): 0;
135  ret -= atoi (eq + 1);
136  rz_sys_setenv (buf, eq + 1);
137  } else {
138  /* syntax error */
139  }
140  return ret;
141 }
142 
143 static TAG_CALLBACK(spp_trace) {
144  if (state->echo[state->ifl]) {
145  fprintf (stderr, "%.1000s\n", buf);
146  }
147  return 0;
148 }
149 
150 /* TODO: deprecate */
151 static TAG_CALLBACK(spp_echo) {
152  if (state->echo[state->ifl]) {
153  out_printf (out, "%s", buf);
154  }
155  // TODO: add variable replacement here?? not necessary, done by {{get}}
156  return 0;
157 }
158 
159 static TAG_CALLBACK(spp_error) {
160  if (!state->echo[state->ifl]) {
161  return 0;
162  }
163  fprintf (stderr, "ERROR: %s (line=%d)\n", buf, state->lineno);
164  return -1;
165 }
166 
167 static TAG_CALLBACK(spp_warning) {
168  if (!state->echo[state->ifl]) {
169  return 0;
170  }
171  fprintf (stderr, "WARNING: %s (line=%d)\n", buf, state->lineno);
172  return 0;
173 }
174 
175 static TAG_CALLBACK(spp_system) {
176  if (!state->echo[state->ifl]) {
177  return 0;
178  }
179 #if HAVE_SYSTEM
180  char *str = cmd_to_str (buf);
181  out_printf (out, "%s", str);
182  free(str);
183 #endif
184  return 0;
185 }
186 
187 static TAG_CALLBACK(spp_include) {
188  char *incdir;
189  if (!state->echo[state->ifl]) {
190  return 0;
191  }
192  incdir = getenv("SPP_INCDIR");
193  if (incdir) {
194  char *b = strdup (incdir);
195  char *p = realloc (b, strlen (b) + strlen (buf) + 3);
196  if (p) {
197  b = p;
198  strcat (b, "/");
199  strcat (b, buf);
200  spp_file (b, out);
201  }
202  free (b);
203  } else {
204  spp_file(buf, out);
205  }
206  return 0;
207 }
208 
209 static TAG_CALLBACK(spp_if) {
210  char *var = spp_var_get(buf);
211  state->echo[state->ifl + 1] = (var && *var != '0' && *var != '\0') ? 1 : 0;
212  return 1;
213 }
214 
215 /* {{ ifeq $path / }} */
216 static TAG_CALLBACK(spp_ifeq) {
217  char *value = buf;
218  char *eq = strchr(buf, ' ');
219  if (eq) {
220  *eq = '\0';
222  if (value && !strcmp(value, eq+1)) {
223  state->echo[state->ifl + 1] = 1;
224  } else state->echo[state->ifl + 1] = 0;
225 //fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, eq+1, echo[ifl]);
226  } else {
227  value = spp_var_get(buf);
228  if (!value || *value=='\0')
229  state->echo[state->ifl + 1] = 1;
230  else state->echo[state->ifl + 1] = 0;
231 //fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, value, echo[ifl]);
232  }
233  return 1;
234 }
235 
236 static TAG_CALLBACK(spp_hex) {
237  int i;
238  for(i = 0; buf[i]; i++) {
239  if (buf[i] >= '0' && buf[i] <= '9') {
240  int b;
241  unsigned int ch;
242  b = buf[i + 2];
243  buf[i + 2] = '\0';
244  sscanf(buf + i, "%02x", &ch);
245  out_printf (out, "%c", ch);
246  buf[i + 2] = b;
247  buf = buf + 2;
248  }
249  }
250  return 0;
251 }
252 
253 static TAG_CALLBACK(spp_grepline) {
254  FILE *fd;
255  char b[1024];
256  char *ptr;
257  int line;
258 
259  if (!state->echo[state->ifl]) return 1;
260  ptr = strchr(buf, ' ');
261  if (ptr) {
262  *ptr= '\0';
263  fd = fopen (buf, "r");
264  line = atoi (ptr+1);
265  if (fd) {
266  while (!feof (fd) && line--) {
267  if (!fgets (b, 1023, fd)) {
268  break;
269  }
270  }
271  fclose (fd);
272  out_printf (out, "%s", b);
273  } else {
274  fprintf(stderr, "Unable to open '%s'\n", buf);
275  }
276  }
277  return 0;
278 }
279 
280 static TAG_CALLBACK(spp_else) {
281  state->echo[state->ifl] = state->echo[state->ifl] ? 0 : 1;
282  return 0;
283 }
284 
285 static TAG_CALLBACK(spp_ifnot) {
286  spp_if (state, out, buf);
287  spp_else (state, out, buf);
288  return 1;
289 }
290 
291 static TAG_CALLBACK(spp_ifin) {
292  char *var, *ptr;
293  if (!state->echo[state->ifl]) {
294  return 1;
295  }
296  ptr = strchr (buf, ' ');
297  state->echo[state->ifl + 1] = 0;
298  if (ptr) {
299  *ptr='\0';
300  var = getenv(buf);
301  if (strstr (ptr + 1, var)) {
302  state->echo[state->ifl + 1] = 1;
303  }
304  }
305  return 1;
306 }
307 
308 static TAG_CALLBACK(spp_endif) {
309  return -1;
310 }
311 
312 static TAG_CALLBACK(spp_default) {
313  if (!state->echo[state->ifl]) {
314  return 0;
315  }
316  if (buf[-1] != ';') { /* commented tag */
317  fprintf (stderr, "WARNING: invalid command: '%s' at line %d\n", buf, state->lineno);
318  }
319  return 0;
320 }
321 
322 #if HAVE_SYSTEM
323 static FILE *spp_pipe_fd = NULL;
324 #endif
325 
326 static TAG_CALLBACK(spp_pipe) {
327 #if HAVE_SYSTEM
328  spp_pipe_fd = popen (buf, "w");
329 #endif
330  return 0;
331 }
332 
333 static char *spp_switch_str = NULL;
334 
335 static TAG_CALLBACK(spp_switch) {
336  char *var = spp_var_get (buf);
337  if (var) {
338  spp_switch_str = strdup (var);
339  } else {
340  spp_switch_str = strdup ("");
341  }
342  return 1;
343 }
344 
345 static TAG_CALLBACK(spp_case) {
346  state->echo[state->ifl] = strcmp (buf, spp_switch_str)?0:1;
347  return 0;
348 }
349 
350 static TAG_CALLBACK(spp_endswitch) {
353  return -1;
354 }
355 
356 static TAG_CALLBACK(spp_endpipe) {
357 #if HAVE_SYSTEM
358  /* TODO: Get output here */
359  int ret = 0, len = 0;
360  int outlen = 4096;
361  char *str = (char *)malloc (4096);
362  char *tstr;
363  do {
364  len += ret;
365  ret = fread (str + len, 1, 1023, spp_pipe_fd);
366  if (ret + 1024 > outlen) {
367  outlen += 4096;
368  tstr = realloc (str, outlen);
369  if (!tstr) {
370  fprintf (stderr, "Out of memory.\n");
371  break;
372  }
373  str = tstr;
374  }
375  } while (ret > 0);
376  str[len] = '\0';
377  out_printf (out, "%s", str);
378  if (spp_pipe_fd) {
379  pclose (spp_pipe_fd);
380  }
381  spp_pipe_fd = NULL;
382  free (str);
383 #endif
384  return 0;
385 }
386 
387 static PUT_CALLBACK(spp_fputs) {
388 #if HAVE_SYSTEM
389  if (spp_pipe_fd) {
390  fprintf (spp_pipe_fd, "%s", buf);
391  } else
392 #endif
393  {
394  out_printf (out, "%s", buf);
395  }
396  return 0;
397 }
398 
399 static struct Tag spp_tags[] = {
400  { "get", spp_get },
401  { "hex", spp_hex },
402  { "getrandom", spp_getrandom },
403  { "grepline", spp_grepline },
404  { "set", spp_set },
405  { "add", spp_add },
406  { "sub", spp_sub },
407  { "switch", spp_switch },
408  { "case", spp_case },
409  { "endswitch", spp_endswitch },
410  { "echo", spp_echo },
411  { "error", spp_error },
412  { "warning", spp_warning },
413  { "trace", spp_trace },
414  { "ifin", spp_ifin },
415  { "ifnot", spp_ifnot },
416  { "ifeq", spp_ifeq },
417  { "if", spp_if },
418  { "else", spp_else },
419  { "endif", spp_endif },
420  { "pipe", spp_pipe },
421  { "endpipe", spp_endpipe },
422  { "include", spp_include },
423  { "system", spp_system },
424  { NULL, spp_default },
425  { NULL }
426 };
427 
428 static ARG_CALLBACK(spp_arg_i) {
429  rz_sys_setenv ("SPP_INCDIR", arg);
430  return 0;
431 }
432 
433 static ARG_CALLBACK(spp_arg_d) {
434  /* TODO: Handle error */
435  char *eq = strchr (arg, '=');
436  if (eq) {
437  *eq = '\0';
438  spp_var_set (arg, eq+1);
439  } else {
440  spp_var_set (arg, "");
441  }
442  return 0;
443 }
444 
445 static struct Arg spp_args[] = {
446  { "-I", "add include directory", 1, spp_arg_i },
447  { "-D", "define value of variable", 1, spp_arg_d },
448  { NULL }
449 };
450 
452  .name = "spp",
453  .tags = (struct Tag **)spp_tags,
454  .args = (struct Arg **)spp_args,
455  .token = " ",
456  .eof = NULL,
457  .tag_pre = "<{",
458  .tag_post = "}>",
459  .chop = 1,
460  .fputs = spp_fputs,
461  .multiline = NULL,
462  .default_echo = 1,
463  .tag_begin = 0,
464 };
465 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static int value
Definition: cmd_api.c:93
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
int max
Definition: enough.c:225
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
void * p
Definition: libc.cpp:67
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int args
Definition: mipsasm.c:18
string FILE
Definition: benchmark.py:21
line
Definition: setup.py:34
static ARG_CALLBACK(spp_arg_i)
Definition: spp.h:428
static int spp_var_set(const char *var, const char *val)
Definition: spp.h:14
static TAG_CALLBACK(spp_set)
Definition: spp.h:51
static char * spp_switch_str
Definition: spp.h:333
DLL_LOCAL struct Proc spp_proc
Definition: spp.h:451
static char * spp_var_get(char *var)
Definition: spp.h:10
static struct Arg spp_args[]
Definition: spp.h:445
static struct Tag spp_tags[]
Definition: spp.h:399
static PUT_CALLBACK(spp_fputs)
Definition: spp.h:387
void out_printf(Output *out, char *str,...) __attribute__((format(printf
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
RZ_API int rz_sys_setenv(const char *key, const char *value)
Set an environment variable in the calling process.
Definition: sys.c:405
RZ_API int rz_sys_getpid(void)
Definition: sys.c:1164
static int
Definition: sfsocketcall.h:114
#define b(i)
Definition: sha256.c:42
S_API int spp_file(const char *file, Output *out)
Definition: spp.c:272
#define DLL_LOCAL
Definition: spp.h:69
Definition: spp.h:121
Definition: spp.h:128
const char * name
Definition: spp.h:129
Definition: spp.h:116
Definition: dis.h:43
char * getenv()
static const z80_opcode fd[]
Definition: z80_tab.h:997