* cygcheck.cc (get_word, get_dword): Move to path.cc.

(LINK_EXTENSION): New macro.
	(check_existence): New static function.
	(find_on_path): Check for symbolic links if asked.
	(dll_info): New error handling.
	(track_down): Only call dll_info() for executables, display
	an error for symlinks, and print magic number for others.
	(find_app_on_path): New static function.
	(cygcheck, dump_sysinfo): Call find_app_on_path() instead of
	find_on_path().
	* path.cc (cmp_shortcut_header): New static function.
	(get_word, get_dword): Moved from cygcheck.cc.
	(EXE_MAGIC, SHORTCUT_MAGIC, SYMLINK_COOKIE, SYMLINK_MAGIC): New
	macros.
	(is_exe, is_symlink, readlink): New functions.
	* path.h (is_exe, is_symlink, readlink): Declare.
	(get_word, get_dword): Ditto.
This commit is contained in:
Corinna Vinschen
2006-10-05 17:24:13 +00:00
parent 66845c62b1
commit cea9b62102
4 changed files with 363 additions and 46 deletions

View File

@@ -249,9 +249,41 @@ init_paths ()
}
}
#define LINK_EXTENSION ".lnk"
static bool
check_existence (char *file, int showall, int foundone, char *first)
{
if (GetFileAttributes (file) != (DWORD) - 1)
{
char *lastdot = strrchr (file, '.');
bool is_link = lastdot && !strcmp (lastdot, LINK_EXTENSION);
// If file is a link, fix up the extension before printing
if (is_link)
*lastdot = '\0';
if (showall)
printf ("Found: %s\n", file);
if (foundone)
{
char *flastdot = strrchr (first, '.');
bool f_is_link = flastdot && !strcmp (flastdot, LINK_EXTENSION);
// if first is a link, fix up the extension before printing
if (f_is_link)
*flastdot = '\0';
printf ("Warning: %s hides %s\n", first, file);
if (f_is_link)
*flastdot = '.';
}
if (is_link)
*lastdot = '.';
return true;
}
return false;
}
static char *
find_on_path (char *file, char *default_extension,
int showall = 0, int search_sysdirs = 0)
int showall = 0, int search_sysdirs = 0, int checklinks = 0)
{
static char rv[4000];
char tmp[4000], *ptr = rv;
@@ -270,11 +302,21 @@ find_on_path (char *file, char *default_extension,
if (strchr (file, ':') || strchr (file, '\\') || strchr (file, '/'))
{
// FIXME: this will find "foo" before "foo.exe" -- contrary to Windows
char *fn = cygpath (file, NULL);
if (access (fn, F_OK) == 0)
return fn;
strcpy (rv, fn);
strcat (rv, default_extension);
if (access (rv, F_OK) == 0)
return rv;
if (!checklinks)
return fn;
strcat (rv, LINK_EXTENSION);
if (access (rv, F_OK) == 0)
return rv;
strcpy (rv, fn);
strcat (rv, LINK_EXTENSION);
return access (rv, F_OK) == 0 ? strdup (rv) : fn;
}
@@ -286,14 +328,25 @@ find_on_path (char *file, char *default_extension,
if (i == 0 || !search_sysdirs || strcasecmp (paths[i], paths[0]))
{
sprintf (ptr, "%s\\%s%s", paths[i], file, default_extension);
if (GetFileAttributes (ptr) != (DWORD) - 1)
{
if (showall)
printf ("Found: %s\n", ptr);
if (ptr == tmp && verbose)
printf ("Warning: %s hides %s\n", rv, ptr);
ptr = tmp;
}
if (check_existence (ptr, showall, ptr == tmp && verbose, rv))
ptr = tmp;
if (!checklinks)
continue;
sprintf (ptr, "%s\\%s%s%s", paths[i], file, default_extension, LINK_EXTENSION);
if (check_existence (ptr, showall, ptr == tmp && verbose, rv))
ptr = tmp;
if (!*default_extension)
continue;
sprintf (ptr, "%s\\%s", paths[i], file);
if (check_existence (ptr, showall, ptr == tmp && verbose, rv))
ptr = tmp;
sprintf (ptr, "%s\\%s%s", paths[i], file, LINK_EXTENSION);
if (check_existence (ptr, showall, ptr == tmp && verbose, rv))
ptr = tmp;
}
}
@@ -330,38 +383,6 @@ already_did (char *file)
return d;
}
static int
get_word (HANDLE fh, int offset)
{
short rv;
unsigned r;
if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR)
display_error ("get_word: SetFilePointer()");
if (!ReadFile (fh, &rv, 2, (DWORD *) &r, 0))
display_error ("get_word: Readfile()");
return rv;
}
static int
get_dword (HANDLE fh, int offset)
{
int rv;
unsigned r;
if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR)
display_error ("get_dword: SetFilePointer()");
if (!ReadFile (fh, &rv, 4, (DWORD *) &r, 0))
display_error ("get_dword: Readfile()");
return rv;
}
struct Section
{
char name[8];
@@ -505,6 +526,8 @@ dll_info (const char *path, HANDLE fh, int lvl, int recurse)
DWORD junk;
int i;
int pe_header_offset = get_dword (fh, 0x3c);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int opthdr_ofs = pe_header_offset + 4 + 20;
unsigned short v[6];
@@ -528,12 +551,24 @@ dll_info (const char *path, HANDLE fh, int lvl, int recurse)
printf ("\n");
int num_entries = get_dword (fh, opthdr_ofs + 92);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int export_rva = get_dword (fh, opthdr_ofs + 96);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int export_size = get_dword (fh, opthdr_ofs + 100);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int import_rva = get_dword (fh, opthdr_ofs + 104);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int import_size = get_dword (fh, opthdr_ofs + 108);
if (GetLastError () != NO_ERROR)
display_error ("get_dword");
int nsections = get_word (fh, pe_header_offset + 4 + 2);
if (nsections == -1)
display_error ("get_word");
char *sections = (char *) malloc (nsections * 40);
if (SetFilePointer (fh, pe_header_offset + 4 + 20 +
@@ -682,7 +717,20 @@ track_down (char *file, char *suffix, int lvl)
d->state = DID_ACTIVE;
dll_info (path, fh, lvl, 1);
if (is_exe (fh))
dll_info (path, fh, lvl, 1);
else if (is_symlink (fh))
printf (" - Found a symlink instead of a DLL\n");
else
{
int magic = get_word (fh, 0x0);
if (magic == -1)
display_error ("get_word");
magic &= 0x00FFFFFF;
printf (" - Not a DLL: magic number %x (%d) '%s'\n",
magic, magic, (char *)&magic);
}
d->state = DID_INACTIVE;
if (!CloseHandle (fh))
display_error ("track_down: CloseHandle()");
@@ -711,11 +759,56 @@ ls (char *f)
display_error ("ls: CloseHandle()");
}
// Find a real application on the path (possibly following symlinks)
static char *
find_app_on_path (char *app, int showall = 0)
{
char *papp = find_on_path (app, (char *) ".exe", showall, 0, 1);
HANDLE fh =
CreateFile (papp, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
printf (" - Cannot open\n");
return NULL;
}
if (is_symlink (fh))
{
static char tmp[4000] = "";
char *ptr;
if (!readlink (fh, tmp, 3999))
display_error("readlink failed");
ptr = cygpath (tmp, NULL);
for (char *p = ptr; (p = strchr (p, '/')); p++)
*p = '\\';
printf (" -> %s\n", ptr);
if (!strchr (ptr, '\\'))
{
char *lastsep;
strncpy (tmp, cygpath (papp, NULL), 3999);
for (char *p = tmp; (p = strchr (p, '/')); p++)
*p = '\\';
lastsep = strrchr (tmp, '\\');
strncpy (lastsep+1, ptr, 3999-(lastsep-tmp));
ptr = tmp;
}
if (!CloseHandle (fh))
display_error ("find_app_on_path: CloseHandle()");
return find_app_on_path (ptr, showall);
}
if (!CloseHandle (fh))
display_error ("find_app_on_path: CloseHandle()");
return papp;
}
// Return true on success, false if error printed
static bool
cygcheck (char *app)
{
char *papp = find_on_path (app, (char *) ".exe", 1, 0);
char *papp = find_app_on_path (app, 1);
if (!papp)
{
printf ("Error: could not find %s\n", app);
@@ -1441,7 +1534,7 @@ dump_sysinfo ()
printf
("Looking to see where common programs can be found, if at all...\n");
for (i = 0; common_apps[i].name; i++)
if (!find_on_path ((char *) common_apps[i].name, (char *) ".exe", 1, 0))
if (!find_app_on_path ((char *) common_apps[i].name, 1))
{
if (common_apps[i].missing_is_good)
printf ("Not Found: %s (good!)\n", common_apps[i].name);