/*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "interpreter.h" #include "binarybuffer.h" #include #include var_t *variables = NULL; int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int interpreter_register_commands(struct command_context_s *cmd_ctx) { register_command(cmd_ctx, NULL, "var", handle_var_command, COMMAND_ANY, "allocate, display or delete variable [num_fields|'del'] [size1] ..."); register_command(cmd_ctx, NULL, "field", handle_field_command, COMMAND_ANY, "display/modify variable field [value|'flip']"); register_command(cmd_ctx, NULL, "script", handle_script_command, COMMAND_ANY, "execute commands from "); return ERROR_OK; } var_t* get_var_by_num(int num) { int count = 0; var_t *var = variables; if (var) { if (num == count) return var; while (var->next) { var = var->next; count++; if (num == count) return var; } } return NULL; } var_t* get_var_by_name(char *name) { var_t *var = variables; if (var) { if (strcmp(var->name, name) == 0) return var; while (var->next) { var = var->next; if (strcmp(var->name, name) == 0) return var; } } return NULL; } var_t* get_var_by_namenum(char *namenum) { if ((namenum[0] >= '0') && (namenum[0] <= '9')) return get_var_by_num(strtol(namenum, NULL, 0)); else return get_var_by_name(namenum); } int field_le_to_host(u8 *buffer, void *priv, struct scan_field_s *dummy) { var_field_t *field = priv; field->value = buf_get_u32(buffer, 0, field->num_bits); return ERROR_OK; } int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { var_t **last_var_p = &variables; int i; if (argc >= 2) { while (*last_var_p) { if (strcmp((*last_var_p)->name, args[0]) == 0) { if (strcmp(args[1], "del") == 0) { var_t *next = (*last_var_p)->next; free ((*last_var_p)->fields); free (*last_var_p); *last_var_p = next; command_print(cmd_ctx, "variable %s deleted", args[0]); } else command_print(cmd_ctx, "variable of that name already exists"); return ERROR_OK; } last_var_p = &((*last_var_p)->next); } if ((args[0][0] >= '0') && (args[0][0] <= '9')) { command_print(cmd_ctx, "invalid name specified (first character may not be a number)"); return ERROR_OK; } *last_var_p = malloc(sizeof(var_t)); (*last_var_p)->name = strdup(args[0]); (*last_var_p)->num_fields = argc - 1; (*last_var_p)->next = NULL; (*last_var_p)->fields = malloc(sizeof(var_field_t) * (*last_var_p)->num_fields); for (i = 0; i < (*last_var_p)->num_fields; i++) { (*last_var_p)->fields[i].num_bits = strtol(args[1+i], NULL, 0); (*last_var_p)->fields[i].value = 0x0; } return ERROR_OK; } if (argc == 1) { var_t *var = get_var_by_namenum(args[0]); if (var) { int i; command_print(cmd_ctx, "%s (%i fields):", var->name, var->num_fields); for (i = 0; i < (var->num_fields); i++) { command_print(cmd_ctx, "0x%x (/%i)", var->fields[i].value, var->fields[i].num_bits); } } else { command_print(cmd_ctx, "variable %s doesn't exist", args[0]); } } if (argc == 0) { var_t *var = variables; int count = 0; while (var) { command_print(cmd_ctx, "%i: %s (%i fields)", count, var->name, var->num_fields); var = var->next; count++; } } return ERROR_OK; } int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { if (argc < 2) command_print(cmd_ctx, "usage: field [value|'flip']"); if (argc >= 2) { var_t *var = get_var_by_namenum(args[0]); int field_num = strtol(args[1], NULL, 0); if (!var) { command_print(cmd_ctx, "variable %s doesn't exist", args[0]); return ERROR_OK; } if (field_num >= var->num_fields) command_print(cmd_ctx, "variable field %i is out of bounds (max. %i)", field_num, var->num_fields - 1); if ((var) && (field_num < var->num_fields)) { if (argc > 2) { if (strcmp(args[2], "flip") == 0) var->fields[field_num].value = flip_u32(var->fields[field_num].value, var->fields[field_num].num_bits); else var->fields[field_num].value = strtoul(args[2], NULL, 0); } command_print(cmd_ctx, "%s(%i): 0x%x (/%i)", var->name, field_num, var->fields[field_num].value, var->fields[field_num].num_bits); } } return ERROR_OK; } int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { FILE *script_file; int echo; if (argc != 1) command_print(cmd_ctx, "usage: script "); script_file = fopen(args[0], "r"); if (!script_file) { command_print(cmd_ctx, "couldn't open script file %s", args[0]); return ERROR_OK; } echo = cmd_ctx->echo; cmd_ctx->echo = 1; command_run_file(cmd_ctx, script_file, cmd_ctx->mode); cmd_ctx->echo = echo; fclose(script_file); return ERROR_OK; }