1 /* 2 * ReactOS log2lines 3 * Written by Jan Roeloffzen 4 * 5 * - Cli for escape commands 6 */ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 12 #include "util.h" 13 #include "cmd.h" 14 #include "options.h" 15 #include "log2lines.h" 16 #include "help.h" 17 18 /* When you edit the cmd line and/or use the history instead of just typing, 19 * a bunch of editing BS and space characters 20 * is inserted, so the string looks right on the console but still 21 * contains the original string, plus other garbage: 22 */ 23 static char 24 *backSpaceEdit(char *s) 25 { 26 char c; 27 char *edit = s; 28 char *text = s; 29 30 while (( c = *edit++ )) 31 { 32 switch (c) 33 { 34 case KDBG_BS_CHAR: 35 if (text > s) 36 text --; 37 break; 38 default: 39 *text++ = c; 40 } 41 } 42 *text = '\0'; 43 44 return s; 45 } 46 47 static int 48 handle_switch(FILE *outFile, int *sw, char *arg, char *desc) 49 { 50 int changed =0; 51 int x = 0; 52 53 if (arg && (strcmp(arg,"") != 0)) 54 { 55 x = atoi(arg); 56 if (x != *sw) 57 { 58 *sw = x; 59 changed = 1; 60 } 61 } 62 if (desc) 63 { 64 esclog(outFile, "%s is %d (%s)\n", desc, *sw, changed ? "changed":"unchanged"); 65 if (!arg) 66 esclog(outFile, "(readonly)\n"); 67 } 68 69 return changed; 70 } 71 72 static int 73 handle_switch_str(FILE *outFile, char *sw, char *arg, char *desc) 74 { 75 int changed =0; 76 77 if (arg) 78 { 79 if (strcmp(arg,"") != 0) 80 { 81 if (strcmp(arg,KDBG_ESC_OFF) == 0) 82 { 83 if (*sw) 84 changed = 1; 85 *sw = '\0'; 86 } 87 else if (strcmp(arg, sw) != 0) 88 { 89 strcpy(sw, arg); 90 changed = 1; 91 } 92 } 93 } 94 if (desc) 95 { 96 esclog(outFile, "%s is \"%s\" (%s)\n", desc, sw, changed ? "changed":"unchanged"); 97 if (!arg) 98 esclog(outFile, "(readonly)\n"); 99 } 100 101 return changed; 102 } 103 104 static int 105 handle_address_cmd(FILE *outFile, char *arg) 106 { 107 PLIST_MEMBER plm; 108 char Image[NAMESIZE]; 109 DWORD Offset; 110 int cnt; 111 char *s; 112 113 if(( s = strchr(arg, ':') )) 114 { 115 *s = ' '; 116 if ( (cnt = sscanf(arg,"%20s %x", Image, &Offset)) == 2) 117 { 118 if (( plm = entry_lookup(&cache, Image) )) 119 { 120 if (plm->RelBase != INVALID_BASE) 121 esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset) 122 else 123 esclog(outFile, "Relocated base missing for '%s' ('mod' will update)\n", Image); 124 } 125 else 126 esclog(outFile, "Image '%s' not found\n", Image); 127 } 128 else 129 esclog(outFile, "usage: `a <Image>:<offset>\n"); 130 } 131 else 132 esclog(outFile, "':' expected\n"); 133 134 return 1; 135 } 136 137 char 138 handle_escape_cmd(FILE *outFile, char *Line) 139 { 140 char cmd; 141 char sep = '\n'; 142 char *arg; 143 char *l = Line; 144 int res = 1; 145 int cnt = 0; 146 int changed = 0; 147 148 l = backSpaceEdit(l); 149 if (l[1] != KDBG_ESC_CHAR) 150 return l[1]; //for reprocessing as not escaped 151 152 log(outFile, "\n"); 153 154 l += 2; //skip space+escape character 155 if ( (cnt=sscanf(l,"%c%c",&cmd,&sep)) < 1) 156 { 157 esclog(outFile, "Command expected\n"); 158 res = 0; 159 } 160 161 if (res && cnt==2 && sep != ' ') 162 { 163 esclog(outFile, "' ' expected\n"); 164 res = 0; 165 } 166 l++; //skip cmd 167 while ( *l == ' ')l++; //skip more spaces 168 arg = l; 169 opt_cli = 1; 170 switch (cmd) 171 { 172 case 'a': 173 handle_address_cmd(outFile, arg); 174 break; 175 case 'h': 176 usage(1); 177 break; 178 case 'b': 179 if (handle_switch(outFile, &opt_buffered, arg, "-b Logfile buffering")) 180 set_LogFile(&logFile); //re-open same logfile 181 break; 182 case 'c': 183 handle_switch(outFile, &opt_console, NULL, "-c Console option"); 184 break; 185 case 'd': 186 handle_switch_str(outFile, opt_dir, NULL, "-d Directory option"); 187 break; 188 case 'l': 189 if (handle_switch_str(outFile, opt_logFile, arg, "-l logfile") || (strcmp(opt_mod,"a")!=0)) 190 { 191 opt_mod = "a"; 192 set_LogFile(&logFile); //open new logfile 193 } 194 break; 195 case 'L': 196 if (handle_switch_str(outFile, opt_logFile, arg, "-L logfile") || (strcmp(opt_mod,"w")!=0)) 197 { 198 opt_mod = "w"; 199 set_LogFile(&logFile); //open new logfile 200 } 201 break; 202 case 'm': 203 handle_switch(outFile, &opt_Mark, arg, "-m mark (*)"); 204 break; 205 case 'M': 206 handle_switch(outFile, &opt_Mark, arg, "-M Mark (?)"); 207 break; 208 case 'P': 209 handle_switch_str(outFile, opt_Pipe, NULL, "-P Pipeline option"); 210 break; 211 case 'q': 212 opt_quit = 1; 213 esclog(outFile, "Bye!\n"); 214 break; 215 case 'r': 216 handle_switch(outFile, &opt_raw, arg, "-r Raw"); 217 break; 218 case 's': 219 if (strcmp(arg,"clear") == 0) 220 { 221 memset(&summ, 0, sizeof(SUMM)); 222 esclog(outFile, "Statistics cleared\n"); 223 } 224 else 225 stat_print(outFile, &summ); 226 break; 227 case 'S': 228 cnt = sscanf(arg, "%d+%d", &opt_Source, &opt_SrcPlus); 229 if (opt_Source) 230 { 231 handle_switch(outFile, &opt_undo, "1", "-u Undo"); 232 handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess"); 233 } 234 esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath); 235 esclog(outFile, "(Setting source tree not implemented)\n"); 236 break; 237 case 't': 238 handle_switch(outFile, &opt_twice, arg, "-t Translate twice"); 239 break; 240 case 'T': 241 handle_switch(outFile, &opt_twice, arg, NULL); 242 handle_switch(outFile, &opt_Twice, arg, "-T Translate for (address-1)"); 243 break; 244 case 'u': 245 handle_switch(outFile, &opt_undo, arg, "-u undo"); 246 break; 247 case 'U': 248 handle_switch(outFile, &opt_undo, arg, NULL); 249 handle_switch(outFile, &opt_redo, arg, "-U Undo and reprocess"); 250 break; 251 case 'v': 252 handle_switch(outFile, &opt_verbose, arg, "-v Verbosity"); 253 break; 254 case 'z': 255 handle_switch_str(outFile, opt_7z, NULL, "-z 7z path"); 256 break; 257 default: 258 if (strchr(optchars, cmd)) 259 esclog(outFile, "Command not implemented in cli: %c %s\n",cmd, arg) 260 else 261 esclog(outFile, "Unknown command: %c %s\n",cmd, arg); 262 } 263 opt_cli = 0; 264 265 memset(Line, '\0', LINESIZE); // flushed 266 267 return KDBG_ESC_CHAR; //handled escaped command 268 } 269 270 /* EOF */ 271