/* * ReactOS log2lines * Written by Jan Roeloffzen * * - Cli for escape commands */ #include #include #include #include "util.h" #include "cmd.h" #include "options.h" #include "log2lines.h" #include "help.h" /* When you edit the cmd line and/or use the history instead of just typing, * a bunch of editing BS and space characters * is inserted, so the string looks right on the console but still * contains the original string, plus other garbage: */ static char *backSpaceEdit(char *s) { char c; char *edit = s; char *text = s; while (( c = *edit++ )) { switch (c) { case KDBG_BS_CHAR: if (text > s) text --; break; default: *text++ = c; } } *text = '\0'; return s; } static int handle_switch(FILE *outFile, int *sw, char *arg, char *desc) { int changed =0; int x = 0; if (arg && (strcmp(arg,"") != 0)) { x = atoi(arg); if (x != *sw) { *sw = x; changed = 1; } } if (desc) { esclog(outFile, "%s is %d (%s)\n", desc, *sw, changed ? "changed":"unchanged"); if (!arg) esclog(outFile, "(readonly)\n"); } return changed; } static int handle_switch_str(FILE *outFile, char *sw, char *arg, char *desc) { int changed =0; if (arg) { if (strcmp(arg,"") != 0) { if (strcmp(arg,KDBG_ESC_OFF) == 0) { if (*sw) changed = 1; *sw = '\0'; } else if (strcmp(arg, sw) != 0) { strcpy(sw, arg); changed = 1; } } } if (desc) { esclog(outFile, "%s is \"%s\" (%s)\n", desc, sw, changed ? "changed":"unchanged"); if (!arg) esclog(outFile, "(readonly)\n"); } return changed; } static int handle_address_cmd(FILE *outFile, char *arg) { PLIST_MEMBER plm; char Image[NAMESIZE]; DWORD Offset; int cnt; char *s; if(( s = strchr(arg, ':') )) { *s = ' '; if ( (cnt = sscanf(arg,"%20s %x", Image, &Offset)) == 2) { if (( plm = entry_lookup(&cache, Image) )) { if (plm->RelBase != INVALID_BASE) esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset) else esclog(outFile, "Relocated base missing for '%s' ('mod' will update)\n", Image); } else esclog(outFile, "Image '%s' not found\n", Image); } else esclog(outFile, "usage: `a :\n"); } else esclog(outFile, "':' expected\n"); return 1; } char handle_escape_cmd(FILE *outFile, char *Line) { char cmd; char sep = '\n'; char *arg; char *l = Line; int res = 1; int cnt = 0; int changed = 0; l = backSpaceEdit(l); if (l[1] != KDBG_ESC_CHAR) return l[1]; //for reprocessing as not escaped log(outFile, "\n"); l += 2; //skip space+escape character if ( (cnt=sscanf(l,"%c%c",&cmd,&sep)) < 1) { esclog(outFile, "Command expected\n"); res = 0; } if (res && cnt==2 && sep != ' ') { esclog(outFile, "' ' expected\n"); res = 0; } l++; //skip cmd while ( *l == ' ')l++; //skip more spaces arg = l; opt_cli = 1; switch (cmd) { case 'a': handle_address_cmd(outFile, arg); break; case 'h': usage(1); break; case 'b': if (handle_switch(outFile, &opt_buffered, arg, "-b Logfile buffering")) set_LogFile(&logFile); //re-open same logfile break; case 'c': handle_switch(outFile, &opt_console, NULL, "-c Console option"); break; case 'd': handle_switch_str(outFile, opt_dir, NULL, "-d Directory option"); break; case 'l': if (handle_switch_str(outFile, opt_logFile, arg, "-l logfile") || (strcmp(opt_mod,"a")!=0)) { opt_mod = "a"; set_LogFile(&logFile); //open new logfile } break; case 'L': if (handle_switch_str(outFile, opt_logFile, arg, "-L logfile") || (strcmp(opt_mod,"w")!=0)) { opt_mod = "w"; set_LogFile(&logFile); //open new logfile } break; case 'm': handle_switch(outFile, &opt_Mark, arg, "-m mark (*)"); break; case 'M': handle_switch(outFile, &opt_Mark, arg, "-M Mark (?)"); break; case 'P': handle_switch_str(outFile, opt_Pipe, NULL, "-P Pipeline option"); break; case 'q': opt_quit = 1; esclog(outFile, "Bye!\n"); break; case 'r': handle_switch(outFile, &opt_raw, arg, "-r Raw"); break; case 's': if (strcmp(arg,"clear") == 0) { memset(&summ, 0, sizeof(SUMM)); esclog(outFile, "Statistics cleared\n"); } else stat_print(outFile, &summ); break; case 'S': cnt = sscanf(arg, "%d+%d", &opt_Source, &opt_SrcPlus); if (opt_Source) { handle_switch(outFile, &opt_undo, "1", "-u Undo"); handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess"); } esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath); esclog(outFile, "(Setting source tree not implemented)\n"); break; case 't': handle_switch(outFile, &opt_twice, arg, "-t Translate twice"); break; case 'T': handle_switch(outFile, &opt_twice, arg, NULL); handle_switch(outFile, &opt_Twice, arg, "-T Translate for (address-1)"); break; case 'u': handle_switch(outFile, &opt_undo, arg, "-u undo"); break; case 'U': handle_switch(outFile, &opt_undo, arg, NULL); handle_switch(outFile, &opt_redo, arg, "-U Undo and reprocess"); break; case 'v': handle_switch(outFile, &opt_verbose, arg, "-v Verbosity"); break; case 'z': handle_switch_str(outFile, opt_7z, NULL, "-z 7z path"); break; default: if (strchr(optchars, cmd)) esclog(outFile, "Command not implemented in cli: %c %s\n",cmd, arg) else esclog(outFile, "Unknown command: %c %s\n",cmd, arg); } opt_cli = 0; memset(Line, '\0', LINESIZE); // flushed return KDBG_ESC_CHAR; //handled escaped command } /* EOF */