xref: /reactos/sdk/tools/log2lines/cache.c (revision 40462c92)
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