1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
23 #include "DbeSession.h"
24 #include "Experiment.h"
27 #include "DbeJarFile.h"
29 DbeFile::DbeFile (const char *filename)
32 name = dbe_strdup (filename);
33 name = canonical_path (name);
41 sbuf.st_atim.tv_sec = 0;
54 DbeFile::set_need_refind (bool val)
56 if (val != need_refind)
65 DbeFile::set_location (const char *filename)
71 if (strncmp (filename, NTXT ("./"), 2) == 0)
73 location = canonical_path (dbe_strdup (filename));
77 set_need_refind (false);
81 DbeFile::get_location_info ()
83 if (location_info == NULL)
85 char *fnm = get_name ();
86 char *loc = get_location ();
87 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location_info: %s %s\n"),
88 STR (fnm), STR (loc));
91 if (filetype & F_FICTION)
92 location_info = dbe_strdup (fnm);
94 location_info = dbe_sprintf (GTXT ("%s (not found)"),
95 get_relative_path (fnm));
99 char *r_fnm = get_relative_path (fnm);
100 char *r_loc = get_relative_path (loc);
101 if (strcmp (r_fnm, r_loc) == 0)
102 location_info = dbe_strdup (r_fnm);
105 char *bname = get_basename (r_fnm);
106 if (strcmp (bname, r_loc) == 0) // found in current directory
107 location_info = dbe_strdup (bname);
109 location_info = dbe_sprintf (GTXT ("%s (found as %s)"), bname, r_loc);
113 return location_info;
117 DbeFile::getResolvedPath ()
125 DbeFile::getJarDbeFile (char *fnm, int sym)
127 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::getJarDbeFile: %s fnm='%s' sym=%d\n"),
128 STR (name), STR (fnm), sym);
132 char *s = strchr (fnm, sym);
135 s = dbe_strndup (fnm, s - fnm);
136 df = dbeSession->getDbeFile (s, F_JAR_FILE | F_FILE);
141 df = dbeSession->getDbeFile (fnm, F_JAR_FILE | F_FILE);
142 if (df && (df->experiment == NULL))
143 df->experiment = experiment;
148 DbeFile::get_location (bool find_needed)
150 Dprintf (DEBUG_DBE_FILE, NTXT ("get_location 0x%x %s\n"), filetype, STR (name));
152 return need_refind ? NULL : location;
153 if (location || !need_refind)
155 set_need_refind (false);
156 if ((filetype & F_FICTION) != 0)
158 if (filetype == F_DIR_OR_JAR)
160 find_in_archives (name);
163 filetype |= F_JAR_FILE | F_FILE;
166 find_in_pathmap (name);
169 if (check_access (name) == F_DIRECTORY)
171 filetype |= F_DIRECTORY;
177 if ((filetype & F_FILE) != 0)
181 char *fnm = experiment->checkFileInArchive (name, false);
186 sbuf.st_mtime = 0; // Don't check timestamps
190 if ((filetype & F_JAVACLASS) != 0)
194 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d name='%s' orig_location='%s'\n"),
195 (int) __LINE__, name, orig_location);
196 // Parse a fileName attribute. There are 4 possibilities:
198 // file:<name_of_jar_or_zip_file>
199 // jar:file:<name_of_jar_or_zip_file>!<Class_Name>
200 // zip:<name_of_jar_or_zip_file>!<Class_Name>
201 DbeFile *jar_df = NULL;
202 if (strncmp (orig_location, NTXT ("zip:"), 4) == 0)
203 jar_df = getJarDbeFile (orig_location + 4, '!');
204 else if (strncmp (orig_location, NTXT ("jar:file:"), 9) == 0)
205 jar_df = getJarDbeFile (orig_location + 9, '!');
206 else if (strncmp (orig_location, NTXT ("file:"), 5) == 0
207 && isJarOrZip (orig_location + 5))
208 jar_df = getJarDbeFile (orig_location + 5, 0);
211 if (find_in_jar_file (name, jar_df->get_jar_file ()))
213 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s' jar='%s'\n"),
214 (int) __LINE__, name, STR (location), STR (jar_df->get_location ()));
215 inArchive = jar_df->inArchive;
220 if (strncmp (orig_location, NTXT ("file:"), 5) == 0
221 && !isJarOrZip (orig_location + 5))
223 DbeFile *df = new DbeFile (orig_location + 5);
224 df->filetype = DbeFile::F_FILE;
225 df->experiment = experiment;
226 fnm = df->get_location ();
230 inArchive = df->inArchive;
231 sbuf.st_mtime = df->sbuf.st_mtime;
232 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' orig_location='%s' location='%s'\n"),
233 (int) __LINE__, name, orig_location, fnm);
240 fnm = dbe_sprintf (NTXT ("%s/%s/%s"), experiment->get_expt_name (), SP_DYNAMIC_CLASSES, name);
244 sbuf.st_mtime = 0; // Don't check timestamps
245 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s'\n"),
246 (int) __LINE__, name, fnm);
255 if (dbeSession->archive_mode)
262 bool inPathMap = find_in_pathmap (name);
265 find_in_setpath (name, dbeSession->get_search_path ());
268 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
270 find_in_classpath (name, dbeSession->get_classpath ());
276 Dprintf (DEBUG_DBE_FILE && (location == NULL),
277 "DbeFile::get_location:%d NOT FOUND name='%s'\n", __LINE__, name);
282 DbeFile::check_access (const char *filename)
284 if (filename == NULL)
286 int st = dbe_stat (filename, &sbuf);
287 Dprintf (DEBUG_DBE_FILE, NTXT ("check_access: %d 0x%x %s\n"), st, filetype, filename);
290 if (S_ISDIR (sbuf.st_mode))
292 else if (S_ISREG (sbuf.st_mode))
294 return F_UNKNOWN; // Symbolic link or unknown type of file
296 sbuf.st_atim.tv_sec = 0;
297 sbuf.st_mtime = 0; // Don't check timestamps
298 return F_NOT_FOUND; // File not found
302 DbeFile::isJarOrZip (const char *fnm)
304 size_t len = strlen (fnm) - 4;
305 return len > 0 && (strcmp (fnm + len, NTXT (".jar")) == 0
306 || strcmp (fnm + len, NTXT (".zip")) == 0);
310 DbeFile::find_file (const char *filename)
312 switch (check_access (filename))
315 if (filetype == F_DIR_OR_JAR)
316 filetype |= F_DIRECTORY;
317 if ((filetype & F_DIRECTORY) != 0)
318 set_location (filename);
321 if (filetype == F_DIR_OR_JAR)
324 if (isJarOrZip (filename))
325 filetype |= F_JAR_FILE;
327 if ((filetype & F_DIRECTORY) == 0)
328 set_location (filename);
335 DbeFile::get_jar_file ()
339 char *fnm = get_location ();
341 jarFile = dbeSession->get_JarFile (fnm);
347 DbeFile::find_package_name (const char *filename, const char *dirname)
349 char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
350 if (!find_in_pathmap (nm))
357 DbeFile::find_in_directory (const char *filename, const char *dirname)
359 if (filename && dirname)
361 char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
369 DbeFile::find_in_jar_file (const char *filename, DbeJarFile *jfile)
374 int entry = jfile->get_entry (filename);
377 char *fnm = dbeSession->get_tmp_file_name (filename, true);
378 long long fsize = jfile->copy (fnm, entry);
381 dbeSession->tmp_files->append (fnm);
383 sbuf.st_size = fsize;
384 sbuf.st_mtime = 0; // Don't check timestamps
393 DbeFile::find_in_pathmap (char *filename)
395 Vector<pathmap_t*> *pathmaps = dbeSession->get_pathmaps ();
396 bool inPathMap = false;
397 if (strncmp (filename, NTXT ("./"), 2) == 0)
399 for (int i = 0, sz = pathmaps ? pathmaps->size () : 0; i < sz; i++)
401 pathmap_t *pmp = pathmaps->fetch (i);
402 size_t len = strlen (pmp->old_prefix);
403 if (strncmp (pmp->old_prefix, filename, len) == 0
404 && (filename[len] == '/' || filename[len] == '\0'))
407 if (find_in_directory (filename + len, pmp->new_prefix))
417 DbeFile::find_in_archives (char *filename)
419 for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
421 ExpGroup *gr = dbeSession->expGroups->fetch (i1);
424 char *nm = gr->founder->checkFileInArchive (filename, false);
430 sbuf.st_mtime = 0; // Don't check timestamps
439 DbeFile::find_in_setpath (char *filename, Vector<char*> *searchPath)
441 char *base = get_basename (filename);
442 for (int i = 0, sz = searchPath ? searchPath->size () : 0; i < sz; i++)
444 char *spath = searchPath->fetch (i);
445 // Check file in each experiment directory
446 if (streq (spath, "$") || streq (spath, NTXT ("$expts")))
448 // find only in founders and only LoadObj.
449 for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
451 ExpGroup *gr = dbeSession->expGroups->fetch (i1);
452 char *exp_name = gr->founder->get_expt_name ();
455 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
457 // Find with the package name
458 if (find_in_directory (filename, exp_name))
461 if (find_in_directory (base, exp_name))
467 DbeFile *df = dbeSession->getDbeFile (spath, DbeFile::F_DIR_OR_JAR);
468 if (df->get_location () == NULL)
470 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
472 if ((df->filetype & F_JAR_FILE) != 0)
474 if (find_in_jar_file (filename, df->get_jar_file ()))
481 else if ((df->filetype & F_DIRECTORY) != 0)
482 // Find with the package name
483 if (find_package_name (filename, spath))
486 if ((df->filetype & F_DIRECTORY) != 0)
487 if (find_in_directory (base, df->get_location ()))
493 DbeFile::find_in_classpath (char *filename, Vector<DbeFile*> *classPath)
495 for (int i = 0, sz = classPath ? classPath->size () : 0; i < sz; i++)
497 DbeFile *df = classPath->fetch (i);
498 if (df->get_location () == NULL)
500 if ((df->filetype & F_JAR_FILE) != 0)
502 if (find_in_jar_file (filename, df->get_jar_file ()))
508 else if ((df->filetype & F_DIRECTORY) != 0)
509 // Find with the package name
510 if (find_package_name (filename, df->get_name ()))
518 if (sbuf.st_atim.tv_sec == 0)
520 int st = check_access (get_location (false));
521 if (st == F_NOT_FOUND)
528 DbeFile::compare (DbeFile *df)
532 struct stat64 *st1 = get_stat ();
533 struct stat64 *st2 = df->get_stat ();
534 if (st1 == NULL || st2 == NULL)
536 if (st1->st_size != st2->st_size)
538 if (st1->st_mtim.tv_sec != st2->st_mtim.tv_sec)