shell.c (3035B)
1 #include "shell.h" 2 3 static void cleanwhitespaces(char *line); 4 static int parseline(char *line, char **v); 5 6 bool 7 checkfiles(void) 8 { 9 /* TODO: add more checks (other files, use checksum...) */ 10 FILE *f; 11 char fname[strlen(tabledir)+100]; 12 int i; 13 14 for (i = 0; all_pd[i] != NULL; i++) { 15 strcpy(fname, tabledir); 16 strcat(fname, "/"); 17 strcat(fname, all_pd[i]->filename); 18 if ((f = fopen(fname, "rb")) == NULL) 19 return false; 20 else 21 fclose(f); 22 } 23 24 return true; 25 } 26 27 static void 28 cleanwhitespaces(char *line) 29 { 30 char *i; 31 32 for (i = line; *i != 0; i++) 33 if (*i == '\t' || *i == '\n') 34 *i = ' '; 35 } 36 37 /* This function assumes that **v is large enough */ 38 static int 39 parseline(char *line, char **v) 40 { 41 char *t; 42 int n = 0; 43 44 cleanwhitespaces(line); 45 46 for (t = strtok(line, " "); t != NULL; t = strtok(NULL, " ")) 47 strcpy(v[n++], t); 48 49 return n; 50 } 51 52 void 53 exec_args(int c, char **v) 54 { 55 int i; 56 char line[MAXLINELEN]; 57 Command *cmd = NULL; 58 CommandArgs *args; 59 Alg *scramble; 60 61 for (i = 0; commands[i] != NULL; i++) 62 if (!strcmp(v[0], commands[i]->name)) 63 cmd = commands[i]; 64 65 if (cmd == NULL) { 66 fprintf(stderr, "%s: command not found\n", v[0]); 67 return; 68 } 69 70 args = cmd->parse_args(c-1, &v[1]); 71 if (!args->success) { 72 fprintf(stderr, "usage: %s\n", cmd->usage); 73 goto exec_args_end; 74 } 75 76 if (args->scrstdin) { 77 while (true) { 78 if (fgets(line, MAXLINELEN, stdin) == NULL) { 79 clearerr(stdin); 80 break; 81 } 82 83 scramble = new_alg(line); 84 85 printf(">>> Line: %s", line); 86 87 if (scramble != NULL && scramble->len > 0) { 88 args->scramble = scramble; 89 cmd->exec(args); 90 free_alg(scramble); 91 args->scramble = NULL; 92 } 93 fflush(stdout); 94 } 95 } else { 96 cmd->exec(args); 97 } 98 99 exec_args_end: 100 free_args(args); 101 } 102 103 void 104 launch(bool batchmode) 105 { 106 int i, shell_argc; 107 char line[MAXLINELEN], **shell_argv; 108 109 shell_argv = malloc(MAXNTOKENS * sizeof(char *)); 110 for (i = 0; i < MAXNTOKENS; i++) 111 shell_argv[i] = malloc((MAXTOKENLEN+1) * sizeof(char)); 112 113 if (!batchmode) { 114 fprintf(stderr, "Welcome to Nissy "VERSION".\n" 115 "Type \"commands\" for a list of commands.\n"); 116 } 117 118 while (true) { 119 if (!batchmode) { 120 fprintf(stdout, "nissy-# "); 121 } 122 123 if (fgets(line, MAXLINELEN, stdin) == NULL) 124 break; 125 126 if (batchmode) { 127 printf(">>>\n" 128 ">>> Executing command: %s" 129 ">>>\n", line); 130 } 131 132 shell_argc = parseline(line, shell_argv); 133 134 if (shell_argc > 0) 135 exec_args(shell_argc, shell_argv); 136 137 fflush(stdout); 138 } 139 140 for (i = 0; i < MAXNTOKENS; i++) 141 free(shell_argv[i]); 142 free(shell_argv); 143 } 144 145 int 146 main(int argc, char *argv[]) 147 { 148 char *closing_cmd[1] = { "freemem" }; 149 150 init_env(); 151 152 if (!checkfiles()) { 153 fprintf(stderr, 154 "--- Warning ---\n" 155 "Some pruning tables are missing or unreadable\n" 156 "You can generate them with `nissy gen'.\n" 157 "---------------\n\n" 158 ); 159 } 160 161 if (argc > 1) { 162 if (!strcmp(argv[1], "-b")) { 163 launch(true); 164 } else { 165 exec_args(argc-1, &argv[1]); 166 } 167 } else { 168 launch(false); 169 } 170 171 exec_args(1, closing_cmd); 172 173 return 0; 174 }