diff --git a/reactos/tools/rsym/log2lines.c b/reactos/tools/rsym/log2lines.c index d79d5cc59af..c2616c25946 100644 --- a/reactos/tools/rsym/log2lines.c +++ b/reactos/tools/rsym/log2lines.c @@ -1,14 +1,6 @@ /* - * Usage: log2lines [-cd:fFhmrv] [ ] - * Try log2lines -h - * - * This is a tool and is compiled using the host compiler, - * i.e. on Linux gcc and not mingw-gcc (cross-compiler). - * Therefore we can't include SDK headers and we have to - * duplicate some definitions here. - * Also note that the internal functions are "old C-style", - * returning an int, where a return of 0 means success and - * non-zero is failure. + * ReactOS log2lines + * Written by Jan Roeloffzen */ #include @@ -18,7 +10,7 @@ #include "rsym.h" -#define LOG2LINES_VERSION "1.1" +#define LOG2LINES_VERSION "1.4" #define INVALID_BASE 0xFFFFFFFFL @@ -34,7 +26,7 @@ #define CP_CMD "copy /Y " #define DIR_FMT "dir /a:-d /s /b %s > %s" -#else /* not defined (__DJGPP__) || defined (__WIN32__) */ +#else /* not defined (__DJGPP__) || defined (__WIN32__) */ #include #include @@ -48,17 +40,26 @@ #define CP_CMD "cp -f " #define DIR_FMT "find %s -type f > %s" -#endif /* not defined (__DJGPP__) || defined (__WIN32__) */ +#endif /* not defined (__DJGPP__) || defined (__WIN32__) */ #define CP_FMT CP_CMD "%s %s > " DEV_NULL #define CMD_7Z "7z" +//#define UNZIP_FMT_7Z "%s e -y %s -o%s > " DEV_NULL +#define UNZIP_FMT_7Z "%s e -y %s -o%s" #define UNZIP_FMT "%s x -y -r %s -o%s > " DEV_NULL #define UNZIP_FMT_CAB \ "%s x -y -r %s" PATH_STR "reactos" PATH_STR "reactos.cab -o%s" PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL #define LINESIZE 1024 +#define log(outFile, fmt, ...) \ + { \ + fprintf(outFile, fmt, ##__VA_ARGS__); \ + if (logFile) \ + fprintf(logFile, fmt, ##__VA_ARGS__); \ + } + struct entry_struct { char *buf; @@ -79,20 +80,21 @@ struct cache_struct struct summ_struct { - int translated; - int undo; - int redo; - int skipped; - int diff; - int offset_errors; - int total; + int translated; + int undo; + int redo; + int skipped; + int diff; + int majordiff; + int offset_errors; + int total; }; typedef struct cache_struct CACHE; -typedef struct summ_struct SUMM; +typedef struct summ_struct SUMM; -static CACHE cache; -static SUMM summ; +static CACHE cache; +static SUMM summ; static char *optchars = "bcd:fFhl:mMrstTuUvz:"; static int opt_buffered= 0; // -b @@ -112,7 +114,7 @@ static int opt_redo = 0; // -U static char opt_dir[MAX_PATH]; // -d static char opt_logFile[MAX_PATH]; // -l static char opt_7z[MAX_PATH]; // -z -static char opt_scanned[LINESIZE]; // all scanned options +static char opt_scanned[LINESIZE]; // all scanned options static FILE *logFile = NULL; static char *cache_name; @@ -152,11 +154,11 @@ find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESec } static PROSSYM_ENTRY -find_offset(void *data, size_t offset, char *toString) +find_offset(void *data, size_t offset) { - PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data; - PROSSYM_ENTRY Entries = (PROSSYM_ENTRY) ((char *)data + RosSymHeader->SymbolsOffset); - size_t symbols = RosSymHeader->SymbolsLength / sizeof (ROSSYM_ENTRY); + PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; + PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset); + size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY); size_t i; for (i = 0; i < symbols; i++) @@ -177,80 +179,108 @@ find_offset(void *data, size_t offset, char *toString) static int print_offset(void *data, size_t offset, char *toString) { - PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data; + PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; PROSSYM_ENTRY e = NULL; PROSSYM_ENTRY e2 = NULL; + int bFileOffsetChanged = 0; + char fmt[LINESIZE]; char *Strings = (char *)data + RosSymHeader->StringsOffset; - - e = find_offset(data, offset, toString); + fmt[0] = '\0'; + e = find_offset(data, offset); if (opt_twice) { - e2 = find_offset(data, offset-1, toString); - - if ( e == e2 ) - e2 = NULL; + e2 = find_offset(data, offset - 1); - if ( opt_Twice && e2 ) + if (e == e2) + e2 = NULL; + else + summ.diff++; + + if (opt_Twice && e2) { e = e2; e2 = NULL; - /* replaced (transparantly), but update stats: */ - summ.diff ++; + /* replaced (transparantly), but updated stats */ } } - if ( e || e2 ) + if (e || e2) { - if (toString) - { // put in toString if provided - if ( e2 ) - { - snprintf(toString, LINESIZE, "%s:%u (%s) [%s:%u (%s)]", + if (e2) + { + bFileOffsetChanged = e->FileOffset != e2->FileOffset; + if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset) + summ.majordiff++; + + /* + * - "%.0s" displays nothing, but processes argument + * - bFileOffsetChanged implies always display 2nd SourceLine even if the same + * - also for FunctionOffset + */ + strcat(fmt, "%s"); + if (bFileOffsetChanged) + strcat(fmt, "[%s]"); + else + strcat(fmt, "%.0s"); + + strcat(fmt, ":%u"); + if (e->SourceLine != e2->SourceLine || bFileOffsetChanged) + strcat(fmt, "[%u]"); + else + strcat(fmt, "%.0u"); + + strcat(fmt, " (%s"); + if (e->FunctionOffset != e2->FunctionOffset || bFileOffsetChanged) + strcat(fmt, "[%s])"); + else + strcat(fmt, "%.0s)"); + + if (toString) + { // put in toString if provided + snprintf(toString, LINESIZE, fmt, &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset], &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], &Strings[e2->FunctionOffset]); - summ.diff ++; } else { + strcat(fmt, "\n"); + printf(fmt, + &Strings[e->FileOffset], + &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, + (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], + &Strings[e2->FunctionOffset]); + } + } + else + { + if (toString) + { // put in toString if provided snprintf(toString, LINESIZE, "%s:%u (%s)", &Strings[e->FileOffset], (unsigned int)e->SourceLine, &Strings[e->FunctionOffset]); } - return 0; - } - else - { // to stdout - if ( e2 ) - { - printf("%s:%u (%s) [%s:%u (%s)]\n", - &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset], - &Strings[e2->FileOffset], - (unsigned int)e2->SourceLine, - &Strings[e2->FunctionOffset]); - summ.diff ++; - } else { printf("%s:%u (%s)\n", - &Strings[e->FileOffset], + &Strings[e->FileOffset], (unsigned int)e->SourceLine, &Strings[e->FunctionOffset]); } - return 0; } + return 0; } return 1; } static int -process_data(const void *FileData, size_t FileSize, size_t offset, char *toString) +process_data(const void *FileData, size_t offset, char *toString) { PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_FILE_HEADER PEFileHeader; @@ -261,24 +291,24 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin int res; /* Check if MZ header exists */ - PEDosHeader = (PIMAGE_DOS_HEADER) FileData; + PEDosHeader = (PIMAGE_DOS_HEADER)FileData; if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) { fprintf(stderr, "Input file is not a PE image.\n"); - summ.offset_errors ++; + summ.offset_errors++; return 1; } /* Locate PE file header */ /* sizeof(ULONG) = sizeof(MAGIC) */ - PEFileHeader = (PIMAGE_FILE_HEADER) ((char *)FileData + PEDosHeader->e_lfanew + sizeof (ULONG)); + PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); /* Locate optional header */ - PEOptHeader = (PIMAGE_OPTIONAL_HEADER) (PEFileHeader + 1); + PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); ImageBase = PEOptHeader->ImageBase; /* Locate PE section headers */ - PESectionHeaders = (PIMAGE_SECTION_HEADER) ((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader); + PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader); /* make sure offset is what we want */ offset = fixup_offset(ImageBase, offset); @@ -288,7 +318,7 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin if (!PERosSymSectionHeader) { fprintf(stderr, "Couldn't find rossym section in executable\n"); - summ.offset_errors ++; + summ.offset_errors++; return 1; } res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString); @@ -303,16 +333,15 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin printf("??:0\n"); } fprintf(stderr, "Offset not found.\n"); - summ.offset_errors ++; + summ.offset_errors++; } return res; } -static long -my_atoi(const char *a) +static const char * +getFmt(const char *a) { - int i = 0; const char *fmt = "%x"; if (*a == '0') @@ -332,10 +361,26 @@ my_atoi(const char *a) break; } } - sscanf(a, fmt, &i); + return fmt; +} + +static long +my_atoi(const char *a) +{ + int i = 0; + sscanf(a, getFmt(a), &i); return i; } +static int +isOffset(const char *a) +{ + int i = 0; + if (strchr(a, '.')) + return 0; + return sscanf(a, getFmt(a), &i); +} + static int file_exists(char *name) { @@ -387,7 +432,7 @@ process_file(const char *file_name, size_t offset, char *toString) } else { - res = process_data(FileData, FileSize, offset, toString); + res = process_data(FileData, offset, toString); free(FileData); } return res; @@ -408,12 +453,12 @@ get_ImageBase(char *fname, size_t *ImageBase) fr = fopen(fname, "rb"); if (!fr) { - if (opt_verbose) + if (opt_verbose > 2) fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); return 1; } - readLen = fread(&PEDosHeader, sizeof (IMAGE_DOS_HEADER), 1, fr); + readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -432,8 +477,8 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Locate PE file header */ - res = fseek(fr, PEDosHeader.e_lfanew + sizeof (ULONG), SEEK_SET); - readLen = fread(&PEFileHeader, sizeof (IMAGE_FILE_HEADER), 1, fr); + res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET); + readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -443,7 +488,7 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Locate optional header */ - readLen = fread(&PEOptHeader, sizeof (IMAGE_OPTIONAL_HEADER), 1, fr); + readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -453,8 +498,8 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */ - if ((PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) && - (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)) + if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && + PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if (opt_verbose > 1) fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname); @@ -500,7 +545,7 @@ entry_create(char *Line) if (!Line) return NULL; - pentry = malloc(sizeof (CACHE_ENTRY)); + pentry = malloc(sizeof(CACHE_ENTRY)); if (!pentry) return NULL; @@ -557,7 +602,7 @@ entry_lookup(char *name) if (PATHCMP(name, pnext->name) == 0) { if (pprev) - { // move to head for faster lookup next time + { // move to head for faster lookup next time pprev->pnext = pnext->pnext; pnext->pnext = cache.phead; cache.phead = pnext; @@ -680,7 +725,7 @@ create_cache(int force, int skipImageBase) if (*Fname == '\n') *Fname = '\0'; - while ((Fname > Line) && (*Fname != PATH_CHAR)) + while (Fname > Line && *Fname != PATH_CHAR) Fname--; if (*Fname == PATH_CHAR) Fname++; @@ -770,9 +815,9 @@ translate_char(int c, FILE *outFile) static char * remove_mark(char *Line) { - if( Line[1] == ' ' && Line[2] == '<' ) - if ( Line[0] == '*' || Line[0] == '?' ) - return Line+2; + if (Line[1] == ' ' && Line[2] == '<') + if (Line[0] == '*' || Line[0] == '?') + return Line + 2; return Line; } @@ -799,33 +844,29 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) if (cnt == 3 && ch == ' ') { tail = strchr(s, '>'); - tail = tail ? tail-1 : tail; - if (tail && (tail[0] == ')') && (tail[1] == '>') ) + tail = tail ? tail - 1 : tail; + if (tail && tail[0] == ')' && tail[1] == '>') { res = 0; tail += 2; mark = opt_mark ? "* " : ""; if (opt_redo && !(res = translate_file(path, offset, LineOut))) { - fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - summ.redo ++; + log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); + summ.redo++; } else { - fprintf(outFile, "%s<%s:%x>%s", mark, path, offset, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x>%s", mark, path, offset, tail); - summ.undo ++; + log(outFile, "%s<%s:%x>%s", mark, path, offset, tail); + summ.undo++; } } else { mark = opt_Mark ? "? " : ""; - summ.skipped ++; + summ.skipped++; } - summ.total ++; + summ.total++; } } @@ -837,17 +878,15 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) if (!(res = translate_file(path, offset, LineOut))) { mark = opt_mark ? "* " : ""; - fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - summ.translated ++; + log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); + summ.translated++; } else { mark = opt_Mark ? "? " : ""; - summ.skipped ++; + summ.skipped++; } - summ.total ++; + summ.total++; } } } @@ -855,36 +894,35 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) { if (sep) *sep = ':'; // restore because not translated - fprintf(outFile, "%s%s", mark, s); // just copy - if (logFile) - fprintf(logFile, "%s%s", mark, s); // just copy + log(outFile, "%s%s", mark, s); } memset(Line, '\0', LINESIZE); // flushed } static void -print_summary(FILE * outFile) +print_summary(FILE *outFile) { if (outFile) { fprintf(outFile, "\n*** LOG2LINES SUMMARY ***\n"); - fprintf(outFile, "Translated: %d\n", summ.translated); - fprintf(outFile, "Reverted: %d\n", summ.undo); - fprintf(outFile, "Retranslated: %d\n", summ.redo); - fprintf(outFile, "Skipped: %d\n", summ.skipped); - fprintf(outFile, "Differ: %d\n", summ.diff); - fprintf(outFile, "Offset error: %d\n", summ.offset_errors); - fprintf(outFile, "Total: %d\n", summ.total); + fprintf(outFile, "Translated: %d\n", summ.translated); + fprintf(outFile, "Reverted: %d\n", summ.undo); + fprintf(outFile, "Retranslated: %d\n", summ.redo); + fprintf(outFile, "Skipped: %d\n", summ.skipped); + fprintf(outFile, "Differ: %d\n", summ.diff); + fprintf(outFile, "Differ (function/source): %d\n", summ.majordiff); + fprintf(outFile, "Offset error: %d\n", summ.offset_errors); + fprintf(outFile, "Total: %d\n", summ.total); fprintf(outFile, "-------------------------------\n"); fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n"); - fprintf(outFile, "Directory: %s\n",opt_dir); - fprintf(outFile, "Passed options: %s\n",opt_scanned); + fprintf(outFile, "Directory: %s\n", opt_dir); + fprintf(outFile, "Passed options: %s\n", opt_scanned); fprintf(outFile, "-------------------------------\n"); } } static int -translate_files(FILE * inFile, FILE * outFile) +translate_files(FILE *inFile, FILE *outFile) { char *Line = malloc(LINESIZE + 1); char *path = malloc(LINESIZE + 1); @@ -927,7 +965,6 @@ translate_files(FILE * inFile, FILE * outFile) translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); } - i = 0; } else { @@ -962,7 +999,7 @@ translate_files(FILE * inFile, FILE * outFile) } } else - { // Line by line, slightly faster but less interactive + { // Line by line, slightly faster but less interactive while (fgets(Line, LINESIZE, inFile) != NULL) { if (!opt_raw) @@ -971,9 +1008,7 @@ translate_files(FILE * inFile, FILE * outFile) } else { - fprintf(outFile, "%s", Line); // just copy - if (logFile) - fprintf(logFile, "%s", Line); // just copy + log(outFile, "%s", Line); } } } @@ -993,9 +1028,12 @@ translate_files(FILE * inFile, FILE * outFile) static char *verboseUsage = "\n" "Description:\n" -" When are given, log2lines works just like raddr2line\n" +" When are given, log2lines works like raddr2line:\n" +" - The combination can be repeated\n" +" - Also, can be repeated for each \n" +" - NOTE: some of the options below will have no effect in this form.\n" " Otherwise it reads stdin and tries to translate lines of the form:\n" -" \n\n" +" \n\n" " The result is written to stdout.\n" " log2lines uses a cache in order to avoid a directory scan at each\n" " image lookup, greatly increasing performance. Only image path and its\n" @@ -1008,7 +1046,9 @@ static char *verboseUsage = " -d |\n" " Directory to scan for images. (Do not append a '" PATH_STR "')\n" " This option also takes an ISO image as argument:\n" -" - The image is recognized by the '.iso' extension.\n" +" - The image is recognized by the '.iso' or '.7z' extension.\n" +" - NOTE: The '.7z' and extracted '.iso' basenames must be identical,\n" +" which is normally true for Reactos trunk builds.\n" " - The image will be unpacked to a directory with the same name.\n" " - The embedded reactos.cab file will also be unpacked.\n" " - Combined with -f the file will be re-unpacked.\n" @@ -1026,17 +1066,20 @@ static char *verboseUsage = " -r Raw output without translation.\n\n" " -s Statistics. A summary with the following info is printed after EOF:\n" " *** LOG2LINES SUMMARY ***\n" -" - Translated: Translated lines.\n" -" - Reverted: Lines translated back. See -u option\n" -" - Retranslated: Lines retranslated. See -U option\n" -" - Skipped: Lines not translated.\n" -" - Differ: Lines where (addr-1) info differs. See -tT options\n" -" - Offset error: Image exists, but error retrieving offset info.\n" -" - Total: Total number of lines attempted to translate.\n" +" - Translated: Translated lines.\n" +" - Reverted: Lines translated back. See -u option\n" +" - Retranslated: Lines retranslated. See -U option\n" +" - Skipped: Lines not translated.\n" +" - Differ: Lines where (addr-1) info differs. See -tT options\n" +" - Differ(func/src):Lines where also function or source info differ.\n" +" - Offset error: Image exists, but error retrieving offset info.\n" +" - Total: Total number of lines attempted to translate.\n" " Also some version info is displayed.\n\n" " -t Translate twice. The address itself and for (address - 1)\n" -" Display extra filename and linenumber between [..] if they differ\n\n" -" -T As -t, but the original filename+linenumber gets replaced\n\n" +" Show extra filename, func and linenumber between [..] if they differ\n" +" So if only the linenumbers differ, then only show the extra\n" +" linenumber.\n\n" +" -T As -t, but the original filename+func+linenumber gets replaced\n\n" " -u Undo translations.\n" " Lines are translated back (reverted) to the form \n" " Overrides console mode -c.\n\n" @@ -1053,7 +1096,7 @@ static char *verboseUsage = "Examples:\n" " Setup is a VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n" " Just recreate cache after a svn update or a new module has been added:\n" -" log2lines -F\n\n" +" log2lines -F\n\n" " Use kdbg debugger via console (interactive):\n" " log2lines -c < \\\\.\\pipe\\kdbg\n\n" " Use kdbg debugger via console, and append copy to logFile:\n" @@ -1061,14 +1104,22 @@ static char *verboseUsage = " Use kdbg debugger to send output to logfile:\n" " log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n" " Re-translate a debug log:\n" -" log2lines -d bootcd-38701-dbg.iso < bugxxxx.log\n\n" +" log2lines -U -d bootcd-38701-dbg.iso < bugxxxx.log\n\n" +" Re-translate a debug log. Specify a 7z file, which wil be decompressed.\n" +" Also check for (address) - (address - 1) differences:\n" +" log2lines -U -t -d bootcd-38701-dbg.7z < bugxxxx.log\n" +" This would generate loglines like:\n" +" ''\n\n" +" The following command line invocations are equivalent:\n" +" log2lines msi.dll 2e35d msi.dll 2235 msiexec.exe 30a8 msiexec.exe 2e89\n" +" log2lines msi.dll 2e35d 2235 msiexec.exe 30a8 2e89\n\n" "\n"; static void usage(int verbose) { fprintf(stderr, "log2lines " LOG2LINES_VERSION "\n\n"); - fprintf(stderr, "Usage: log2lines [-%s] [ ]\n", optchars); + fprintf(stderr, "Usage: log2lines -%s { {}}\n", optchars); if (verbose) { fprintf(stderr, "%s", verboseUsage); @@ -1085,7 +1136,7 @@ unpack_iso(char *dir, char *iso) char Line[LINESIZE]; int res = 0; char iso_tmp[MAX_PATH]; - int iso_copied = 0; + int iso_copied = 0; FILE *fiso; strcpy(iso_tmp, iso); @@ -1094,8 +1145,8 @@ unpack_iso(char *dir, char *iso) if (opt_verbose) fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso); - strcat(iso_tmp,"~"); - if (copy_file(iso,iso_tmp)) + strcat(iso_tmp, "~"); + if (copy_file(iso, iso_tmp)) return 3; iso_copied = 1; } @@ -1135,10 +1186,51 @@ unpack_iso(char *dir, char *iso) static int check_directory(int force) { + char Line[LINESIZE]; char freeldr_path[MAX_PATH]; char iso_path[MAX_PATH]; + char compressed_7z_path[MAX_PATH]; + char *check_iso; + char *check_dir; + + check_iso = strrchr(opt_dir, '.'); + if (check_iso && PATHCMP(check_iso, ".7z") == 0) + { + if (opt_verbose) + fprintf(stderr, "Uncompressing 7z image: %s\n", opt_dir); + + // First attempt to decompress to a .iso image + strcpy(compressed_7z_path, opt_dir); + if ((check_dir = strrchr(compressed_7z_path, PATH_CHAR))) + { + *check_dir = '\0'; + } + else + strcpy(compressed_7z_path, "."); // default to current dir + + sprintf(Line, UNZIP_FMT_7Z, opt_7z, opt_dir, compressed_7z_path); + + /* This of course only works if the .7z and .iso basenames are identical + * which is normally true for our trunk builds: + */ + strcpy(check_iso, ".iso"); + if (!file_exists(opt_dir) || force) + { + if (system(Line) < 0) + { + fprintf(stderr, "\nCannot decompress to iso image %s\n", opt_dir); + if (opt_verbose) + fprintf(stderr, "Failed to execute: '%s'\n", Line); + return 2; + } + } + else + { + if (opt_verbose > 1) + fprintf(stderr, "%s already decompressed\n", opt_dir); + } + } - char *check_iso = strrchr(opt_dir, '.'); if (check_iso && PATHCMP(check_iso, ".iso") == 0) { if (opt_verbose) @@ -1187,7 +1279,7 @@ main(int argc, const char **argv) int i; strcpy(opt_scanned, ""); - for (i=1; i - translate_file(argv[optCount + 1], my_atoi(argv[optCount + 2]), NULL); + + if (argc > 1) + { // translate { } + int i = 1; + const char *base = NULL; + const char *offset = NULL; + while (i < argc) + { + offset = argv[optCount + i++]; + if (isOffset(offset)) + { + if (base) + { + if (opt_verbose > 1) + fprintf(stderr, "translating %s %s\n", base, offset); + translate_file(base, my_atoi(offset), NULL); + } + else + { + fprintf(stderr, " expected\n"); + res = 3; + break; + } + } + else + { + // Must be exefile + base = offset; + } + } } else - { // translate logging from stdin + { // translate logging from stdin translate_files(stdin, stdout); } if (logFile) fclose(logFile); + return res; }