1 /* 2 * ReactOS log2lines 3 * Written by Jan Roeloffzen 4 * 5 * - Image directory caching 6 */ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 12 #include "util.h" 13 #include "version.h" 14 #include "compat.h" 15 #include "options.h" 16 #include "help.h" 17 #include "image.h" 18 19 #include "log2lines.h" 20 21 static char CacheName[PATH_MAX]; 22 static char *cache_name = CacheName; 23 static char TmpName[PATH_MAX]; 24 static char *tmp_name = TmpName; 25 26 static int 27 unpack_iso(char *dir, char *iso) 28 { 29 char Line[LINESIZE]; 30 int res = 0; 31 char iso_tmp[PATH_MAX]; 32 int iso_copied = 0; 33 FILE *fiso; 34 35 strcpy(iso_tmp, iso); 36 if ((fiso = fopen(iso, "a")) == NULL) 37 { 38 l2l_dbg(1, "Open of %s failed (locked for writing?), trying to copy first\n", iso); 39 40 strcat(iso_tmp, "~"); 41 if (copy_file(iso, iso_tmp)) 42 return 3; 43 iso_copied = 1; 44 } 45 else 46 fclose(fiso); 47 48 sprintf(Line, UNZIP_FMT, opt_7z, iso_tmp, dir); 49 if (system(Line) < 0) 50 { 51 l2l_dbg(0, "\nCannot unpack %s (check 7z path!)\n", iso_tmp); 52 l2l_dbg(1, "Failed to execute: '%s'\n", Line); 53 res = 1; 54 } 55 else 56 { 57 l2l_dbg(2, "\nUnpacking reactos.cab in %s\n", dir); 58 sprintf(Line, UNZIP_FMT_CAB, opt_7z, dir, dir); 59 if (system(Line) < 0) 60 { 61 l2l_dbg(0, "\nCannot unpack reactos.cab in %s\n", dir); 62 l2l_dbg(1, "Failed to execute: '%s'\n", Line); 63 res = 2; 64 } 65 } 66 if (iso_copied) 67 remove(iso_tmp); 68 return res; 69 } 70 71 int 72 cleanable(char *path) 73 { 74 if (strcmp(basename(path),DEF_OPT_DIR) == 0) 75 return 1; 76 return 0; 77 } 78 79 int 80 check_directory(int force) 81 { 82 char Line[LINESIZE]; 83 char freeldr_path[PATH_MAX]; 84 char iso_path[PATH_MAX]; 85 char compressed_7z_path[PATH_MAX]; 86 char *check_iso; 87 char *check_dir; 88 89 check_iso = strrchr(opt_dir, '.'); 90 l2l_dbg(1, "Checking directory: %s\n", opt_dir); 91 if (check_iso && PATHCMP(check_iso, ".7z") == 0) 92 { 93 l2l_dbg(1, "Checking 7z image: %s\n", opt_dir); 94 95 // First attempt to decompress to an .iso image 96 strcpy(compressed_7z_path, opt_dir); 97 if ((check_dir = strrchr(compressed_7z_path, PATH_CHAR))) 98 *check_dir = '\0'; 99 else 100 strcpy(compressed_7z_path, "."); // default to current dir 101 102 sprintf(Line, UNZIP_FMT_7Z, opt_7z, opt_dir, compressed_7z_path); 103 104 /* This of course only works if the .7z and .iso basenames are identical 105 * which is normally true for ReactOS trunk builds: 106 */ 107 strcpy(check_iso, ".iso"); 108 if (!file_exists(opt_dir) || force) 109 { 110 l2l_dbg(1, "Decompressing 7z image: %s\n", opt_dir); 111 if (system(Line) < 0) 112 { 113 l2l_dbg(0, "\nCannot decompress to iso image %s\n", opt_dir); 114 l2l_dbg(1, "Failed to execute: '%s'\n", Line); 115 return 2; 116 } 117 } 118 else 119 l2l_dbg(2, "%s already decompressed\n", opt_dir); 120 } 121 122 if (check_iso && PATHCMP(check_iso, ".iso") == 0) 123 { 124 l2l_dbg(1, "Checking ISO image: %s\n", opt_dir); 125 if (file_exists(opt_dir)) 126 { 127 l2l_dbg(2, "ISO image exists: %s\n", opt_dir); 128 strcpy(iso_path, opt_dir); 129 *check_iso = '\0'; 130 sprintf(freeldr_path, "%s" PATH_STR "freeldr.ini", opt_dir); 131 if (!file_exists(freeldr_path) || force) 132 { 133 l2l_dbg(0, "Unpacking %s to: %s ...", iso_path, opt_dir); 134 unpack_iso(opt_dir, iso_path); 135 l2l_dbg(0, "... done\n"); 136 } 137 else 138 l2l_dbg(2, "%s already unpacked in: %s\n", iso_path, opt_dir); 139 } 140 else 141 { 142 l2l_dbg(0, "ISO image not found: %s\n", opt_dir); 143 return 1; 144 } 145 } 146 strcpy(cache_name, opt_dir); 147 if (cleanable(opt_dir)) 148 strcat(cache_name, ALT_PATH_STR CACHEFILE); 149 else 150 strcat(cache_name, PATH_STR CACHEFILE); 151 strcpy(tmp_name, cache_name); 152 strcat(tmp_name, "~"); 153 return 0; 154 } 155 156 int 157 read_cache(void) 158 { 159 FILE *fr; 160 LIST_MEMBER *pentry; 161 char Line[LINESIZE + 1]; 162 int result = 0; 163 164 Line[LINESIZE] = '\0'; 165 166 fr = fopen(cache_name, "r"); 167 if (!fr) 168 { 169 l2l_dbg(1, "Open %s failed\n", cache_name); 170 return 2; 171 } 172 cache.phead = cache.ptail = NULL; 173 174 while (fgets(Line, LINESIZE, fr) != NULL) 175 { 176 pentry = cache_entry_create(Line); 177 if (!pentry) 178 { 179 l2l_dbg(2, "** Create entry failed of: %s\n", Line); 180 } 181 else 182 entry_insert(&cache, pentry); 183 } 184 185 fclose(fr); 186 return result; 187 } 188 189 int 190 create_cache(int force, int skipImageBase) 191 { 192 FILE *fr, *fw; 193 char Line[LINESIZE + 1], *Fname = NULL; 194 int len, err; 195 size_t ImageBase; 196 197 if ((fw = fopen(tmp_name, "w")) == NULL) 198 { 199 l2l_dbg(1, "Apparently %s is not writable (mounted ISO?), using current dir\n", tmp_name); 200 cache_name = basename(cache_name); 201 tmp_name = basename(tmp_name); 202 } 203 else 204 { 205 l2l_dbg(3, "%s is writable\n", tmp_name); 206 fclose(fw); 207 remove(tmp_name); 208 } 209 210 if (force) 211 { 212 l2l_dbg(3, "Removing %s ...\n", cache_name); 213 remove(cache_name); 214 } 215 else 216 { 217 if (file_exists(cache_name)) 218 { 219 l2l_dbg(3, "Cache %s already exists\n", cache_name); 220 return 0; 221 } 222 } 223 224 Line[LINESIZE] = '\0'; 225 226 remove(tmp_name); 227 l2l_dbg(0, "Scanning %s ...\n", opt_dir); 228 snprintf(Line, LINESIZE, DIR_FMT, opt_dir, tmp_name); 229 l2l_dbg(1, "Executing: %s\n", Line); 230 if (system(Line) != 0) 231 { 232 l2l_dbg(0, "Cannot list directory %s\n", opt_dir); 233 l2l_dbg(1, "Failed to execute: '%s'\n", Line); 234 remove(tmp_name); 235 return 2; 236 } 237 l2l_dbg(0, "Creating cache ..."); 238 239 if ((fr = fopen(tmp_name, "r")) != NULL) 240 { 241 if ((fw = fopen(cache_name, "w")) != NULL) 242 { 243 while (fgets(Line, LINESIZE, fr) != NULL) 244 { 245 len = strlen(Line); 246 if (!len) 247 continue; 248 249 Fname = Line + len - 1; 250 if (*Fname == '\n') 251 *Fname = '\0'; 252 253 while (Fname > Line && *Fname != PATH_CHAR) 254 Fname--; 255 if (*Fname == PATH_CHAR) 256 Fname++; 257 if (*Fname && !skipImageBase) 258 { 259 if ((err = get_ImageBase(Line, &ImageBase)) == 0) 260 fprintf(fw, "%s|%s|%0x\n", Fname, Line, (unsigned int)ImageBase); 261 else 262 l2l_dbg(3, "%s|%s|%0x, ERR=%d\n", Fname, Line, (unsigned int)ImageBase, err); 263 } 264 } 265 fclose(fw); 266 } 267 l2l_dbg(0, "... done\n"); 268 fclose(fr); 269 } 270 remove(tmp_name); 271 return 0; 272 } 273 274 /* EOF */ 275