[LOG2LINES] Replace overkill malloc() usage.
[reactos.git] / sdk / tools / log2lines / cache.c
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 */