/* * ReactOS log2lines * Written by Jan Roeloffzen * * - Image directory caching */ #include #include #include #include "util.h" #include "version.h" #include "compat.h" #include "options.h" #include "help.h" #include "image.h" #include "log2lines.h" static char CacheName[PATH_MAX]; static char *cache_name = CacheName; static char TmpName[PATH_MAX]; static char *tmp_name = TmpName; static int unpack_iso(char *dir, char *iso) { char Line[LINESIZE]; int res = 0; char iso_tmp[PATH_MAX]; int iso_copied = 0; FILE *fiso; strcpy(iso_tmp, iso); if ((fiso = fopen(iso, "a")) == NULL) { l2l_dbg(1, "Open of %s failed (locked for writing?), trying to copy first\n", iso); strcat(iso_tmp, "~"); if (copy_file(iso, iso_tmp)) return 3; iso_copied = 1; } else fclose(fiso); sprintf(Line, UNZIP_FMT, opt_7z, iso_tmp, dir); if (system(Line) < 0) { l2l_dbg(0, "\nCannot unpack %s (check 7z path!)\n", iso_tmp); l2l_dbg(1, "Failed to execute: '%s'\n", Line); res = 1; } else { l2l_dbg(2, "\nUnpacking reactos.cab in %s\n", dir); sprintf(Line, UNZIP_FMT_CAB, opt_7z, dir, dir); if (system(Line) < 0) { l2l_dbg(0, "\nCannot unpack reactos.cab in %s\n", dir); l2l_dbg(1, "Failed to execute: '%s'\n", Line); res = 2; } } if (iso_copied) remove(iso_tmp); return res; } int cleanable(char *path) { if (strcmp(basename(path),DEF_OPT_DIR) == 0) return 1; return 0; } int check_directory(int force) { char Line[LINESIZE]; char freeldr_path[PATH_MAX]; char iso_path[PATH_MAX]; char compressed_7z_path[PATH_MAX]; char *check_iso; char *check_dir; check_iso = strrchr(opt_dir, '.'); l2l_dbg(1, "Checking directory: %s\n", opt_dir); if (check_iso && PATHCMP(check_iso, ".7z") == 0) { l2l_dbg(1, "Checking 7z image: %s\n", opt_dir); // First attempt to decompress to an .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 ReactOS trunk builds: */ strcpy(check_iso, ".iso"); if (!file_exists(opt_dir) || force) { l2l_dbg(1, "Decompressing 7z image: %s\n", opt_dir); if (system(Line) < 0) { l2l_dbg(0, "\nCannot decompress to iso image %s\n", opt_dir); l2l_dbg(1, "Failed to execute: '%s'\n", Line); return 2; } } else l2l_dbg(2, "%s already decompressed\n", opt_dir); } if (check_iso && PATHCMP(check_iso, ".iso") == 0) { l2l_dbg(1, "Checking ISO image: %s\n", opt_dir); if (file_exists(opt_dir)) { l2l_dbg(2, "ISO image exists: %s\n", opt_dir); strcpy(iso_path, opt_dir); *check_iso = '\0'; sprintf(freeldr_path, "%s" PATH_STR "freeldr.ini", opt_dir); if (!file_exists(freeldr_path) || force) { l2l_dbg(0, "Unpacking %s to: %s ...", iso_path, opt_dir); unpack_iso(opt_dir, iso_path); l2l_dbg(0, "... done\n"); } else l2l_dbg(2, "%s already unpacked in: %s\n", iso_path, opt_dir); } else { l2l_dbg(0, "ISO image not found: %s\n", opt_dir); return 1; } } strcpy(cache_name, opt_dir); if (cleanable(opt_dir)) strcat(cache_name, ALT_PATH_STR CACHEFILE); else strcat(cache_name, PATH_STR CACHEFILE); strcpy(tmp_name, cache_name); strcat(tmp_name, "~"); return 0; } int read_cache(void) { FILE *fr; LIST_MEMBER *pentry; char Line[LINESIZE + 1]; int result = 0; Line[LINESIZE] = '\0'; fr = fopen(cache_name, "r"); if (!fr) { l2l_dbg(1, "Open %s failed\n", cache_name); return 2; } cache.phead = cache.ptail = NULL; while (fgets(Line, LINESIZE, fr) != NULL) { pentry = cache_entry_create(Line); if (!pentry) { l2l_dbg(2, "** Create entry failed of: %s\n", Line); } else entry_insert(&cache, pentry); } fclose(fr); return result; } int create_cache(int force, int skipImageBase) { FILE *fr, *fw; char Line[LINESIZE + 1], *Fname = NULL; int len, err; size_t ImageBase; if ((fw = fopen(tmp_name, "w")) == NULL) { l2l_dbg(1, "Apparently %s is not writable (mounted ISO?), using current dir\n", tmp_name); cache_name = basename(cache_name); tmp_name = basename(tmp_name); } else { l2l_dbg(3, "%s is writable\n", tmp_name); fclose(fw); remove(tmp_name); } if (force) { l2l_dbg(3, "Removing %s ...\n", cache_name); remove(cache_name); } else { if (file_exists(cache_name)) { l2l_dbg(3, "Cache %s already exists\n", cache_name); return 0; } } Line[LINESIZE] = '\0'; remove(tmp_name); l2l_dbg(0, "Scanning %s ...\n", opt_dir); snprintf(Line, LINESIZE, DIR_FMT, opt_dir, tmp_name); l2l_dbg(1, "Executing: %s\n", Line); if (system(Line) != 0) { l2l_dbg(0, "Cannot list directory %s\n", opt_dir); l2l_dbg(1, "Failed to execute: '%s'\n", Line); remove(tmp_name); return 2; } l2l_dbg(0, "Creating cache ..."); if ((fr = fopen(tmp_name, "r")) != NULL) { if ((fw = fopen(cache_name, "w")) != NULL) { while (fgets(Line, LINESIZE, fr) != NULL) { len = strlen(Line); if (!len) continue; Fname = Line + len - 1; if (*Fname == '\n') *Fname = '\0'; while (Fname > Line && *Fname != PATH_CHAR) Fname--; if (*Fname == PATH_CHAR) Fname++; if (*Fname && !skipImageBase) { if ((err = get_ImageBase(Line, &ImageBase)) == 0) fprintf(fw, "%s|%s|%0x\n", Fname, Line, (unsigned int)ImageBase); else l2l_dbg(3, "%s|%s|%0x, ERR=%d\n", Fname, Line, (unsigned int)ImageBase, err); } } fclose(fw); } l2l_dbg(0, "... done\n"); fclose(fr); } remove(tmp_name); return 0; } /* EOF */