33 |
33 |
34 /* Calculate the MD5 Sum for a GRF */ |
34 /* Calculate the MD5 Sum for a GRF */ |
35 static bool CalcGRFMD5Sum(GRFConfig *config) |
35 static bool CalcGRFMD5Sum(GRFConfig *config) |
36 { |
36 { |
37 FILE *f; |
37 FILE *f; |
38 char filename[MAX_PATH]; |
|
39 md5_state_t md5state; |
38 md5_state_t md5state; |
40 md5_byte_t buffer[1024]; |
39 md5_byte_t buffer[1024]; |
41 size_t len; |
40 size_t len; |
42 |
41 |
43 /* open the file */ |
42 /* open the file */ |
44 snprintf(filename, lengthof(filename), "%s%s", _paths.data_dir, config->filename); |
43 f = fopen(config->full_path, "rb"); |
45 f = fopen(filename, "rb"); |
|
46 if (f == NULL) return false; |
44 if (f == NULL) return false; |
47 |
45 |
48 /* calculate md5sum */ |
46 /* calculate md5sum */ |
49 md5_init(&md5state); |
47 md5_init(&md5state); |
50 while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) { |
48 while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) { |
89 void ClearGRFConfig(GRFConfig **config) |
87 void ClearGRFConfig(GRFConfig **config) |
90 { |
88 { |
91 /* GCF_COPY as in NOT strdupped/alloced the filename, name and info */ |
89 /* GCF_COPY as in NOT strdupped/alloced the filename, name and info */ |
92 if (!HASBIT((*config)->flags, GCF_COPY)) { |
90 if (!HASBIT((*config)->flags, GCF_COPY)) { |
93 free((*config)->filename); |
91 free((*config)->filename); |
|
92 free((*config)->full_path); |
94 free((*config)->name); |
93 free((*config)->name); |
95 free((*config)->info); |
94 free((*config)->info); |
96 free((*config)->error); |
95 free((*config)->error); |
97 } |
96 } |
98 free(*config); |
97 free(*config); |
121 /* Clear destination as it will be overwritten */ |
120 /* Clear destination as it will be overwritten */ |
122 ClearGRFConfigList(dst); |
121 ClearGRFConfigList(dst); |
123 for (; src != NULL; src = src->next) { |
122 for (; src != NULL; src = src->next) { |
124 GRFConfig *c = CallocT<GRFConfig>(1); |
123 GRFConfig *c = CallocT<GRFConfig>(1); |
125 *c = *src; |
124 *c = *src; |
126 if (src->filename != NULL) c->filename = strdup(src->filename); |
125 if (src->filename != NULL) c->filename = strdup(src->filename); |
127 if (src->name != NULL) c->name = strdup(src->name); |
126 if (src->full_path != NULL) c->full_path = strdup(src->full_path); |
128 if (src->info != NULL) c->info = strdup(src->info); |
127 if (src->name != NULL) c->name = strdup(src->name); |
129 if (src->error != NULL) { |
128 if (src->info != NULL) c->info = strdup(src->info); |
|
129 if (src->error != NULL) { |
130 c->error = CallocT<GRFError>(1); |
130 c->error = CallocT<GRFError>(1); |
131 memcpy(c->error, src->error, sizeof(GRFError)); |
131 memcpy(c->error, src->error, sizeof(GRFError)); |
132 } |
132 } |
133 |
133 |
134 *dst = c; |
134 *dst = c; |
253 * in any case and set the name and info when it is not set already. |
253 * in any case and set the name and info when it is not set already. |
254 * When the GCF_COPY flag is set, it is certain that the filename is |
254 * When the GCF_COPY flag is set, it is certain that the filename is |
255 * already a local one, so there is no need to replace it. */ |
255 * already a local one, so there is no need to replace it. */ |
256 if (!HASBIT(c->flags, GCF_COPY)) { |
256 if (!HASBIT(c->flags, GCF_COPY)) { |
257 free(c->filename); |
257 free(c->filename); |
|
258 free(c->full_path); |
258 c->filename = strdup(f->filename); |
259 c->filename = strdup(f->filename); |
|
260 c->full_path = strdup(f->full_path); |
259 memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum)); |
261 memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum)); |
260 if (c->name == NULL && f->name != NULL) c->name = strdup(f->name); |
262 if (c->name == NULL && f->name != NULL) c->name = strdup(f->name); |
261 if (c->info == NULL && f->info != NULL) c->info = strdup(f->info); |
263 if (c->info == NULL && f->info != NULL) c->info = strdup(f->info); |
262 c->error = NULL; |
264 c->error = NULL; |
263 } |
265 } |
276 uint num = 0; |
278 uint num = 0; |
277 struct stat sb; |
279 struct stat sb; |
278 struct dirent *dirent; |
280 struct dirent *dirent; |
279 DIR *dir; |
281 DIR *dir; |
280 |
282 |
281 if ((dir = ttd_opendir(path)) == NULL) return 0; |
283 if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0; |
282 |
284 |
283 while ((dirent = readdir(dir)) != NULL) { |
285 while ((dirent = readdir(dir)) != NULL) { |
284 const char *d_name = FS2OTTD(dirent->d_name); |
286 const char *d_name = FS2OTTD(dirent->d_name); |
285 char filename[MAX_PATH]; |
287 char filename[MAX_PATH]; |
286 |
288 |
287 if (!FiosIsValidFile(path, dirent, &sb)) continue; |
289 if (!FiosIsValidFile(path, dirent, &sb)) continue; |
288 |
290 |
289 snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name); |
291 snprintf(filename, lengthof(filename), "%s%s", path, d_name); |
290 |
292 |
291 if (sb.st_mode & S_IFDIR) { |
293 if (sb.st_mode & S_IFDIR) { |
292 /* Directory */ |
294 /* Directory */ |
293 if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue; |
295 if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue; |
|
296 AppendPathSeparator(filename, lengthof(filename)); |
294 num += ScanPath(filename); |
297 num += ScanPath(filename); |
295 } else if (sb.st_mode & S_IFREG) { |
298 } else if (sb.st_mode & S_IFREG) { |
296 /* File */ |
299 /* File */ |
297 char *ext = strrchr(filename, '.'); |
300 char *ext = strrchr(filename, '.'); |
298 char *file = filename + strlen(_paths.data_dir) + 1; // Crop base path |
|
299 |
301 |
300 /* If no extension or extension isn't .grf, skip the file */ |
302 /* If no extension or extension isn't .grf, skip the file */ |
301 if (ext == NULL) continue; |
303 if (ext == NULL) continue; |
302 if (strcasecmp(ext, ".grf") != 0) continue; |
304 if (strcasecmp(ext, ".grf") != 0) continue; |
303 |
305 |
304 GRFConfig *c = CallocT<GRFConfig>(1); |
306 GRFConfig *c = CallocT<GRFConfig>(1); |
305 c->filename = strdup(file); |
307 c->full_path = strdup(filename); |
306 |
308 c->filename = strdup(strrchr(filename, PATHSEPCHAR) + 1); |
|
309 |
|
310 bool added = true; |
307 if (FillGRFDetails(c, false)) { |
311 if (FillGRFDetails(c, false)) { |
308 if (_all_grfs == NULL) { |
312 if (_all_grfs == NULL) { |
309 _all_grfs = c; |
313 _all_grfs = c; |
310 } else { |
314 } else { |
311 /* Insert file into list at a position determined by its |
315 /* Insert file into list at a position determined by its |
312 * name, so the list is sorted as we go along */ |
316 * name, so the list is sorted as we go along */ |
313 GRFConfig **pd, *d; |
317 GRFConfig **pd, *d; |
314 for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) { |
318 for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) { |
|
319 if (c->grfid == d->grfid && memcmp(c->md5sum, d->md5sum, sizeof(c->md5sum)) == 0) added = false; |
315 if (strcasecmp(c->name, d->name) <= 0) break; |
320 if (strcasecmp(c->name, d->name) <= 0) break; |
316 } |
321 } |
317 c->next = d; |
322 if (added) { |
318 *pd = c; |
323 c->next = d; |
|
324 *pd = c; |
|
325 } |
319 } |
326 } |
320 |
|
321 num++; |
|
322 } else { |
327 } else { |
|
328 added = false; |
|
329 } |
|
330 |
|
331 if (!added) { |
323 /* File couldn't be opened, or is either not a NewGRF or is a |
332 /* File couldn't be opened, or is either not a NewGRF or is a |
324 * 'system' NewGRF, so forget about it. */ |
333 * 'system' NewGRF or it's already known, so forget about it. */ |
325 free(c->filename); |
334 free(c->filename); |
|
335 free(c->full_path); |
326 free(c->name); |
336 free(c->name); |
327 free(c->info); |
337 free(c->info); |
328 free(c); |
338 free(c); |
|
339 } else { |
|
340 num++; |
329 } |
341 } |
330 } |
342 } |
331 } |
343 } |
332 |
344 |
333 closedir(dir); |
345 closedir(dir); |
342 uint num; |
354 uint num; |
343 |
355 |
344 ClearGRFConfigList(&_all_grfs); |
356 ClearGRFConfigList(&_all_grfs); |
345 |
357 |
346 DEBUG(grf, 1, "Scanning for NewGRFs"); |
358 DEBUG(grf, 1, "Scanning for NewGRFs"); |
347 num = ScanPath(_paths.data_dir); |
359 num = ScanPath(_paths.data_dir); |
|
360 num += ScanPath(_paths.second_data_dir); |
348 DEBUG(grf, 1, "Scan complete, found %d files", num); |
361 DEBUG(grf, 1, "Scan complete, found %d files", num); |
349 } |
362 } |
350 |
363 |
351 |
364 |
352 /* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/ |
365 /* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/ |