static char * next_field (char *str, char sep, char **next) { char *p; p = remove_leading_whitespaces (str); for (str = p; *str != sep && *str != '\0'; str++); *str = '\0'; remove_trailing_whitespaces (p); *next = str + 1; return p; }
int main (int argc, char *argv[]) { if (argc == 2) { // Might got called as Script Executioner //FILE *fp = fopen(argv[1],"r"); // Prepare a file Pointer char *readString; // Read lines here /*while (fgets(readString, READBUFFERSIZE, fp) != NULL) {*/ while ((readString = readline("Test"))) { remove_leading_whitespaces(readString); if (*readString != '#') { parse_cmd(readString); } } return EXIT_SUCCESS; // Exit this instance of shawn. } last_exit_code = 0; char *shell = malloc(sizeof(char[80])); // Prepare variable for path if (*argv[0] == '.') { // Has shawn been called with a relative path? strcat(shell,getenv("PWD")); // Yes, prepare string strcat(shell,strchr(argv[0],'/')); // Concat Strings to an absolute path } else { shell = argv[0]; // No, just take call of shawn } char *hostname = malloc(sizeof(char[80])); // Whats the Name of this Host? if (gethostname(hostname,80) != 0) { // Could we read it? errno_msg("Reading hostname",0); // No, give an error and quit } set("SHELL",shell); // Set SHELL Env Variable. debug_msg("Debugmode enabled!"); // Inform user, he is running in DEBUG mode. printf("Welcome to shawn 1.1\n"); char readString[READBUFFERSIZE]; // Prepare Buffer do { // Loop. printf("%s:(%s)%s$ ",hostname,getenv("USER"),getenv("PWD")); fgets(readString, READBUFFERSIZE, stdin); // Read user command. parse_cmd(readString); } while (quit==0); // Infinite loop, quit is now recognized and handled in parsecmd() return EXIT_SUCCESS; // We can quit now, but this will never get called. }
static void process_i386_opcodes (FILE *table) { FILE *fp; char buf[2048]; unsigned int i, j; char *str, *p, *last, *name; struct opcode_hash_entry **hash_slot, **entry, *next; htab_t opcode_hash_table; struct opcode_hash_entry **opcode_array; unsigned int opcode_array_size = 1024; int lineno = 0; filename = "i386-opc.tbl"; fp = fopen (filename, "r"); if (fp == NULL) fail (_("can't find i386-opc.tbl for reading, errno = %s\n"), xstrerror (errno)); i = 0; opcode_array = (struct opcode_hash_entry **) xmalloc (sizeof (*opcode_array) * opcode_array_size); opcode_hash_table = htab_create_alloc (16, opcode_hash_hash, opcode_hash_eq, NULL, xcalloc, free); fprintf (table, "\n/* i386 opcode table. */\n\n"); fprintf (table, "const insn_template i386_optab[] =\n{\n"); /* Put everything on opcode array. */ while (!feof (fp)) { if (fgets (buf, sizeof (buf), fp) == NULL) break; lineno++; p = remove_leading_whitespaces (buf); /* Skip comments. */ str = strstr (p, "//"); if (str != NULL) str[0] = '\0'; /* Remove trailing white spaces. */ remove_trailing_whitespaces (p); switch (p[0]) { case '#': /* Ignore comments. */ case '\0': continue; break; default: break; } last = p + strlen (p); /* Find name. */ name = next_field (p, ',', &str, last); /* Get the slot in hash table. */ hash_slot = (struct opcode_hash_entry **) htab_find_slot_with_hash (opcode_hash_table, name, htab_hash_string (name), INSERT); if (*hash_slot == NULL) { /* It is the new one. Put it on opcode array. */ if (i >= opcode_array_size) { /* Grow the opcode array when needed. */ opcode_array_size += 1024; opcode_array = (struct opcode_hash_entry **) xrealloc (opcode_array, sizeof (*opcode_array) * opcode_array_size); } opcode_array[i] = (struct opcode_hash_entry *) xmalloc (sizeof (struct opcode_hash_entry)); opcode_array[i]->next = NULL; opcode_array[i]->name = xstrdup (name); opcode_array[i]->opcode = xstrdup (str); opcode_array[i]->lineno = lineno; *hash_slot = opcode_array[i]; i++; } else { /* Append it to the existing one. */ entry = hash_slot; while ((*entry) != NULL) entry = &(*entry)->next; *entry = (struct opcode_hash_entry *) xmalloc (sizeof (struct opcode_hash_entry)); (*entry)->next = NULL; (*entry)->name = (*hash_slot)->name; (*entry)->opcode = xstrdup (str); (*entry)->lineno = lineno; } } /* Process opcode array. */ for (j = 0; j < i; j++) { for (next = opcode_array[j]; next; next = next->next) { name = next->name; str = next->opcode; lineno = next->lineno; last = str + strlen (str); output_i386_opcode (table, name, str, last, lineno); } } fclose (fp); fprintf (table, " { NULL, 0, 0, 0, 0,\n"); process_i386_cpu_flag (table, "0", 0, ",", " ", -1); process_i386_opcode_modifier (table, "0", -1); fprintf (table, " { "); process_i386_operand_type (table, "0", 0, "\t ", -1); fprintf (table, " } }\n"); fprintf (table, "};\n"); }
static void output_i386_opcode (FILE *table, const char *name, char *str, char *last, int lineno) { unsigned int i; char *operands, *base_opcode, *extension_opcode, *opcode_length; char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS]; /* Find number of operands. */ operands = next_field (str, ',', &str, last); /* Find base_opcode. */ base_opcode = next_field (str, ',', &str, last); /* Find extension_opcode. */ extension_opcode = next_field (str, ',', &str, last); /* Find opcode_length. */ opcode_length = next_field (str, ',', &str, last); /* Find cpu_flags. */ cpu_flags = next_field (str, ',', &str, last); /* Find opcode_modifier. */ opcode_modifier = next_field (str, ',', &str, last); /* Remove the first {. */ str = remove_leading_whitespaces (str); if (*str != '{') abort (); str = remove_leading_whitespaces (str + 1); i = strlen (str); /* There are at least "X}". */ if (i < 2) abort (); /* Remove trailing white spaces and }. */ do { i--; if (ISSPACE (str[i]) || str[i] == '}') str[i] = '\0'; else break; } while (i != 0); last = str + i; /* Find operand_types. */ for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (str >= last) { operand_types [i] = NULL; break; } operand_types [i] = next_field (str, ',', &str, last); if (*operand_types[i] == '0') { if (i != 0) operand_types[i] = NULL; break; } } fprintf (table, " { \"%s\", %s, %s, %s, %s,\n", name, operands, base_opcode, extension_opcode, opcode_length); process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno); process_i386_opcode_modifier (table, opcode_modifier, lineno); fprintf (table, " { "); for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (operand_types[i] == NULL || *operand_types[i] == '0') { if (i == 0) process_i386_operand_type (table, "0", 0, "\t ", lineno); break; } if (i != 0) fprintf (table, ",\n "); process_i386_operand_type (table, operand_types[i], 0, "\t ", lineno); } fprintf (table, " } },\n"); }
static void process_i386_registers (FILE *table) { FILE *fp; char buf[2048]; char *str, *p, *last; char *reg_name, *reg_type, *reg_flags, *reg_num; char *dw2_32_num, *dw2_64_num; int lineno = 0; filename = "i386-reg.tbl"; fp = fopen (filename, "r"); if (fp == NULL) fail (_("can't find i386-reg.tbl for reading, errno = %s\n"), xstrerror (errno)); fprintf (table, "\n/* i386 register table. */\n\n"); fprintf (table, "const reg_entry i386_regtab[] =\n{\n"); while (!feof (fp)) { if (fgets (buf, sizeof (buf), fp) == NULL) break; lineno++; p = remove_leading_whitespaces (buf); /* Skip comments. */ str = strstr (p, "//"); if (str != NULL) str[0] = '\0'; /* Remove trailing white spaces. */ remove_trailing_whitespaces (p); switch (p[0]) { case '#': fprintf (table, "%s\n", p); case '\0': continue; break; default: break; } last = p + strlen (p); /* Find reg_name. */ reg_name = next_field (p, ',', &str, last); /* Find reg_type. */ reg_type = next_field (str, ',', &str, last); /* Find reg_flags. */ reg_flags = next_field (str, ',', &str, last); /* Find reg_num. */ reg_num = next_field (str, ',', &str, last); fprintf (table, " { \"%s\",\n ", reg_name); process_i386_operand_type (table, reg_type, 0, "\t", lineno); /* Find 32-bit Dwarf2 register number. */ dw2_32_num = next_field (str, ',', &str, last); /* Find 64-bit Dwarf2 register number. */ dw2_64_num = next_field (str, ',', &str, last); fprintf (table, ",\n %s, %s, { %s, %s } },\n", reg_flags, reg_num, dw2_32_num, dw2_64_num); } fclose (fp); fprintf (table, "};\n"); fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n"); }
static void process_i386_opcodes (FILE *table) { FILE *fp; char buf[2048]; unsigned int i; char *str, *p, *last; char *name, *operands, *base_opcode, *extension_opcode; char *opcode_length; char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS]; filename = "i386-opc.tbl"; fp = fopen (filename, "r"); if (fp == NULL) fail (_("can't find i386-opc.tbl for reading, errno = %s\n"), xstrerror (errno)); fprintf (table, "\n/* i386 opcode table. */\n\n"); fprintf (table, "const template i386_optab[] =\n{\n"); while (!feof (fp)) { if (fgets (buf, sizeof (buf), fp) == NULL) break; lineno++; p = remove_leading_whitespaces (buf); /* Skip comments. */ str = strstr (p, "//"); if (str != NULL) str[0] = '\0'; /* Remove trailing white spaces. */ remove_trailing_whitespaces (p); switch (p[0]) { case '#': fprintf (table, "%s\n", p); case '\0': continue; break; default: break; } last = p + strlen (p); /* Find name. */ name = next_field (p, ',', &str); if (str >= last) abort (); /* Find number of operands. */ operands = next_field (str, ',', &str); if (str >= last) abort (); /* Find base_opcode. */ base_opcode = next_field (str, ',', &str); if (str >= last) abort (); /* Find extension_opcode. */ extension_opcode = next_field (str, ',', &str); if (str >= last) abort (); /* Find opcode_length. */ opcode_length = next_field (str, ',', &str); if (str >= last) abort (); /* Find cpu_flags. */ cpu_flags = next_field (str, ',', &str); if (str >= last) abort (); /* Find opcode_modifier. */ opcode_modifier = next_field (str, ',', &str); if (str >= last) abort (); /* Remove the first {. */ str = remove_leading_whitespaces (str); if (*str != '{') abort (); str = remove_leading_whitespaces (str + 1); i = strlen (str); /* There are at least "X}". */ if (i < 2) abort (); /* Remove trailing white spaces and }. */ do { i--; if (ISSPACE (str[i]) || str[i] == '}') str[i] = '\0'; else break; } while (i != 0); last = str + i; /* Find operand_types. */ for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (str >= last) { operand_types [i] = NULL; break; } operand_types [i] = next_field (str, ',', &str); if (*operand_types[i] == '0') { if (i != 0) operand_types[i] = NULL; break; } } fprintf (table, " { \"%s\", %s, %s, %s, %s,\n", name, operands, base_opcode, extension_opcode, opcode_length); process_i386_cpu_flag (table, cpu_flags, 0, ",", " "); process_i386_opcode_modifier (table, opcode_modifier); fprintf (table, " { "); for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (operand_types[i] == NULL || *operand_types[i] == '0') { if (i == 0) process_i386_operand_type (table, "0", 0, "\t "); break; } if (i != 0) fprintf (table, ",\n "); process_i386_operand_type (table, operand_types[i], 0, "\t "); } fprintf (table, " } },\n"); } fclose (fp); fprintf (table, " { NULL, 0, 0, 0, 0,\n"); process_i386_cpu_flag (table, "0", 0, ",", " "); process_i386_opcode_modifier (table, "0"); fprintf (table, " { "); process_i386_operand_type (table, "0", 0, "\t "); fprintf (table, " } }\n"); fprintf (table, "};\n"); }
void parse_cmd(char *cmd) { cmd = remove_leading_whitespaces(cmd); char *tok = find_next_space(cmd); // Find Command int status; debug_msg(cmd); #if USEBUILTINCLEAR if (strcmp(cmd, "clear") == 0) { clear(); } else #endif if (strcmp(cmd, "env") == 0) { env(); } else if (strcmp(cmd, "quit") == 0) { exit(EXIT_SUCCESS); } else if (strcmp(cmd, "version") == 0) { version(); } else if (strcmp(cmd, "pwd") == 0) { pwd(); } #if USEBUILTINLS else if (strcmp(cmd, "ls") == 0) { ls(); } #endif else if (strcmp(cmd, "echo") == 0) { find_next_space(tok); remove_character(tok,'\\'); echo(tok); } else if (strcmp(cmd, "cd") == 0) { find_next_space(tok); // Get Path remove_character(tok,'\\'); // Remove all '\' in target Path. debug_msg(tok); cd(tok); } else if (strcmp(cmd, "set") == 0) { // Get Name of Variable char *buffer = strtok(tok,"="); // Get new Value of Variable and set. set(buffer, strtok(NULL,"=")); } else if (strcmp(cmd, "\0") == 0) { // Do nothing. } else { // Fork application here pid_t pID = fork(); if (pID < 0) { // pID == -1: There was an error! Quit shawn!! errno_msg("Could not fork.",0); } else if (pID > 0) { // Parent Process, pID is PID of child. pID = wait(&status); // Wait for childs completion. if (WIFEXITED(status)) { // Has Child ended? last_exit_code = WEXITSTATUS(status); // Set our internal $? #if DEBUG printf("[DEBUG] Child exited with %i\n",last_exit_code); #endif } } else { // PID == 0 // Child Process. // We need to fork here. unsigned int i = 2; // Prepare a counter char *parameters[count_paramters(tok)]; // Create a list for parameters char *buffer = find_next_space(tok); // Select first parameter. remove_character(tok,'\\'); parameters[0] = cmd; // Set name of call. See execvp() Documentation parameters[1] = tok; // Set first parameter. // Save every Parameter now for our Call while (buffer != NULL) { // We need a second pointer here. char *placeholder = find_next_space(buffer); // remove all \ characters while(remove_next_special_character(buffer,'\\') == 1); // Set the Parameter to our newly delimited string parameters[i] = buffer; // Replace buffer with our placeholder buffer = placeholder; i++; // Increment i, so we set the next parameter } parameters[i-1] = NULL; // Remove an empty Parameter. Else This would be a whitespace // Run Application now. int result = execvp(cmd,parameters); if (result != 0) { errno_msg("Executing Application",1); } exit(result); } } // End of fork() Stuff. }