4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-18 12:29:32 +08:00

* cygcheck.cc (pathlike): New class.

(paths): Redefine as type pathlike.
(display_error): Declare a few different ways to allow more flexible usage
throughout.
(display_error_fmt): New function for those cases where C++ just isn't enough.
(add_path): Rewrite to allocate pathlike paths.  Always tack on a trailing
slash since that's what everyone who uses it wants.  NULL terminate the path
list.  Register "it's a system path" field.
(init_path): Call add_path with info regarding whether path is a system path or
not.
(pathlike::check_existence): Move into pathlike class.  Accept file and
extension arguments to build up path on the fly.  Modify other arguments.
(find_on_path): Constify return value and appropriate arguments.  Eliminate
short-circuit for fully-qualified paths.  Simplify loop which iterates over
path.
(already_did): Constify argument.
(track_down): Ditto.  Regularize some error messages.
(find_app_on_path): Ditto.
(cygcheck): Constify argument.  Use 20th century string handling functions.
(dump_sysinfo): Remove odd inclusion of '\\bin' "Just in case".  Accommodate
change of paths to pathlike.
* path.cc (isslash): Rename from SLASH_P and use throughout.
(rel_vconcat): Front-end to vconcat which prepends cwd to path before passing
along for conversion to native windows.
(cygpath): Remove "./" test.  Call rel_vconcat if filename appears to be
relative.
This commit is contained in:
Christopher Faylor 2007-06-04 01:57:16 +00:00
parent 1fec1363bb
commit f0136ac908
3 changed files with 310 additions and 191 deletions

View File

@ -1,3 +1,35 @@
2007-06-03 Christopher Faylor <me+cygwin@cgf.cx>
* cygcheck.cc (pathlike): New class.
(paths): Redefine as type pathlike.
(display_error): Declare a few different ways to allow more flexible
usage throughout.
(display_error_fmt): New function for those cases where C++ just isn't
enough.
(add_path): Rewrite to allocate pathlike paths. Always tack on a
trailing slash since that's what everyone who uses it wants. NULL
terminate the path list. Register "it's a system path" field.
(init_path): Call add_path with info regarding whether path is a system
path or not.
(pathlike::check_existence): Move into pathlike class. Accept file and
extension arguments to build up path on the fly. Modify other
arguments.
(find_on_path): Constify return value and appropriate arguments.
Eliminate short-circuit for fully-qualified paths. Simplify loop which
iterates over path.
(already_did): Constify argument.
(track_down): Ditto. Regularize some error messages.
(find_app_on_path): Ditto.
(cygcheck): Constify argument. Use 20th century string handling
functions.
(dump_sysinfo): Remove odd inclusion of '\\bin' "Just in case".
Accommodate change of paths to pathlike.
* path.cc (isslash): Rename from SLASH_P and use throughout.
(rel_vconcat): Front-end to vconcat which prepends cwd to path before
passing along for conversion to native windows.
(cygpath): Remove "./" test. Call rel_vconcat if filename appears to
be relative.
2007-05-29 Pedro Alves <pedro_alves@portugalmail.pt> 2007-05-29 Pedro Alves <pedro_alves@portugalmail.pt>
* dumper.cc (dumper::prepare_core_dump): Record a phdr for each section. * dumper.cc (dumper::prepare_core_dump): Record a phdr for each section.

View File

@ -38,6 +38,8 @@ int find_package = 0;
int list_package = 0; int list_package = 0;
int grep_packages = 0; int grep_packages = 0;
static char emptystr[] = "";
/* This is global because it's used in both internet_display_error as well /* This is global because it's used in both internet_display_error as well
as package_grep. */ as package_grep. */
BOOL (WINAPI *pInternetCloseHandle) (HINTERNET); BOOL (WINAPI *pInternetCloseHandle) (HINTERNET);
@ -114,7 +116,16 @@ static common_apps[] = {
}; };
static int num_paths, max_paths; static int num_paths, max_paths;
static char **paths; struct pathlike
{
char *dir;
bool issys;
void pathlike::check_existence (const char *fn, int showall, int verbose,
char* first, const char *ext1 = "",
const char *ext2 = "");
};
pathlike *paths;
int first_nonsys_path; int first_nonsys_path;
void void
@ -130,17 +141,43 @@ eprintf (const char *format, ...)
* display_error() is used to report failure modes * display_error() is used to report failure modes
*/ */
static int static int
display_error (const char *name, bool show_error = true, bool print_failed = true) display_error (const char *name, bool show_error, bool print_failed)
{ {
fprintf (stderr, "cygcheck: %s", name);
if (show_error) if (show_error)
fprintf (stderr, "cygcheck: %s%s: %lu\n", name, fprintf (stderr, "%s: %lu\n",
print_failed ? " failed" : "", GetLastError ()); print_failed ? " failed" : "", GetLastError ());
else else
fprintf (stderr, "cygcheck: %s%s\n", name, fprintf (stderr, "%s\n",
print_failed ? " failed" : ""); print_failed ? " failed" : "");
return 1; return 1;
} }
static int
display_error (const char *name)
{
return display_error (name, true, true);
}
static int
display_error (const char *fmt, const char *x)
{
char buf[4000];
sprintf (buf, fmt, x);
return display_error (buf, false, false);
}
static int
display_error_fmt (const char *fmt, ...)
{
char buf[4000];
va_list va;
va_start (va, fmt);
vsprintf (buf, fmt, va);
return display_error (buf, false, false);
}
/* Display a WinInet error message, and close a variable number of handles. /* Display a WinInet error message, and close a variable number of handles.
(Passed a list of handles terminated by NULL.) */ (Passed a list of handles terminated by NULL.) */
static int static int
@ -156,12 +193,12 @@ display_internet_error (const char *message, ...)
if (err) if (err)
{ {
if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE, if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle ("wininet.dll"), err, 0, err_buf, GetModuleHandle ("wininet.dll"), err, 0, err_buf,
sizeof (err_buf), NULL) == 0) sizeof (err_buf), NULL) == 0)
strcpy (err_buf, "(Unknown error)"); strcpy (err_buf, "(Unknown error)");
fprintf (stderr, "cygcheck: %s: %s (win32 error %d)\n", message, fprintf (stderr, "cygcheck: %s: %s (win32 error %d)\n", message,
err_buf, err); err_buf, err);
} }
else else
fprintf (stderr, "cygcheck: %s\n", message); fprintf (stderr, "cygcheck: %s\n", message);
@ -175,33 +212,37 @@ display_internet_error (const char *message, ...)
} }
static void static void
add_path (char *s, int maxlen) add_path (char *s, int maxlen, bool issys)
{ {
if (num_paths >= max_paths) if (num_paths >= max_paths)
{ {
max_paths += 10; max_paths += 10;
if (paths) /* Extend path array */
paths = (char **) realloc (paths, max_paths * sizeof (char *)); paths = (pathlike *) realloc (paths, (1 + max_paths) * sizeof (paths[0]));
else
paths = (char **) malloc (max_paths * sizeof (char *));
} }
paths[num_paths] = (char *) malloc (maxlen + 1);
if (paths[num_paths] == NULL) pathlike *pth = paths + num_paths;
/* Allocate space for directory in path list */
char *dir = (char *) calloc (maxlen + 2, sizeof (char));
if (dir == NULL)
{ {
display_error ("add_path: malloc()"); display_error ("add_path: calloc() failed");
return; return;
} }
memcpy (paths[num_paths], s, maxlen);
paths[num_paths][maxlen] = 0; /* Copy input directory to path list */
char *e = paths[num_paths] + strlen (paths[num_paths]); memcpy (dir, s, maxlen);
if (e[-1] == '\\' && e[-2] != ':')
*--e = 0; /* Add a trailing slash by default */
for (int i = 1; i < num_paths; i++) char *e = strchr (dir, '\0');
if (strcasecmp (paths[num_paths], paths[i]) == 0) if (e != dir && e[-1] != '\\')
{ strcpy (e, "\\");
free (paths[num_paths]);
return; /* Fill out this element */
} pth->dir = dir;
pth->issys = issys;
pth[1].dir = NULL;
num_paths++; num_paths++;
} }
@ -209,39 +250,39 @@ static void
init_paths () init_paths ()
{ {
char tmp[4000], *sl; char tmp[4000], *sl;
add_path ((char *) ".", 1); /* to be replaced later */ add_path ((char *) ".", 1, true); /* to be replaced later */
if (GetCurrentDirectory (4000, tmp)) if (GetCurrentDirectory (4000, tmp))
add_path (tmp, strlen (tmp)); add_path (tmp, strlen (tmp), true);
else else
display_error ("init_paths: GetCurrentDirectory()"); display_error ("init_paths: GetCurrentDirectory()");
if (GetSystemDirectory (tmp, 4000)) if (GetSystemDirectory (tmp, 4000))
add_path (tmp, strlen (tmp)); add_path (tmp, strlen (tmp), true);
else else
display_error ("init_paths: GetSystemDirectory()"); display_error ("init_paths: GetSystemDirectory()");
sl = strrchr (tmp, '\\'); sl = strrchr (tmp, '\\');
if (sl) if (sl)
{ {
strcpy (sl, "\\SYSTEM"); strcpy (sl, "\\SYSTEM");
add_path (tmp, strlen (tmp)); add_path (tmp, strlen (tmp), true);
} }
GetWindowsDirectory (tmp, 4000); GetWindowsDirectory (tmp, 4000);
add_path (tmp, strlen (tmp)); add_path (tmp, strlen (tmp), true);
first_nonsys_path = num_paths;
char *wpath = getenv ("PATH"); char *wpath = getenv ("PATH");
if (!wpath) if (!wpath)
fprintf (stderr, "WARNING: PATH is not set at all!\n"); display_error ("WARNING: PATH is not set\n", "");
else else
{ {
char *b, *e; char *b, *e;
b = wpath; b = wpath;
while (1) while (1)
{ {
for (e = b; *e && *e != ';'; e++); for (e = b; *e && *e != ';'; e++)
if (strncmp(b, ".", 1) && strncmp(b, ".\\", 2)) continue; /* loop terminates at first ';' or EOS */
add_path (b, e - b); if (strncmp(b, ".\\", 2) != 0)
add_path (b, e - b, false);
if (!*e) if (!*e)
break; break;
b = e + 1; b = e + 1;
@ -251,9 +292,16 @@ init_paths ()
#define LINK_EXTENSION ".lnk" #define LINK_EXTENSION ".lnk"
static bool void
check_existence (char *file, int showall, int foundone, char *first) pathlike::check_existence (const char *fn, int showall, int verbose,
char* first, const char *ext1, const char *ext2)
{ {
char file[4000];
strcpy (file, dir);
strcat (file, fn);
strcat (file, ext1);
strcat (file, ext2);
if (GetFileAttributes (file) != (DWORD) - 1) if (GetFileAttributes (file) != (DWORD) - 1)
{ {
char *lastdot = strrchr (file, '.'); char *lastdot = strrchr (file, '.');
@ -263,7 +311,7 @@ check_existence (char *file, int showall, int foundone, char *first)
*lastdot = '\0'; *lastdot = '\0';
if (showall) if (showall)
printf ("Found: %s\n", file); printf ("Found: %s\n", file);
if (foundone) if (verbose && *first != '\0' && strcasecmp (first, file) != 0)
{ {
char *flastdot = strrchr (first, '.'); char *flastdot = strrchr (first, '.');
bool f_is_link = flastdot && !strcmp (flastdot, LINK_EXTENSION); bool f_is_link = flastdot && !strcmp (flastdot, LINK_EXTENSION);
@ -276,84 +324,81 @@ check_existence (char *file, int showall, int foundone, char *first)
} }
if (is_link) if (is_link)
*lastdot = '.'; *lastdot = '.';
return true; if (!*first)
strcpy (first, file);
} }
return false;
} }
static char * static const char *
find_on_path (char *file, char *default_extension, find_on_path (const char *in_file, const char *ext, bool showall = false,
int showall = 0, int search_sysdirs = 0, int checklinks = 0) bool search_sys = false, bool checklinks = false)
{ {
static char rv[4000]; static char rv[4000];
char tmp[4000], *ptr = rv;
/* Sort of a kludge but we've already tested this once, so don't try it again */
if (in_file == rv)
return in_file;
static pathlike abspath[2] =
{
{emptystr, 0},
{NULL, 0}
};
*rv = '\0';
if (!in_file)
{
display_error ("internal error find_on_path: NULL pointer for file", false, false);
return 0;
}
if (!ext)
{
display_error ("internal error find_on_path: NULL pointer for default_extension", false, false);
return 0;
}
const char *file;
pathlike *search_paths;
if (!strpbrk (in_file, ":/\\"))
{
file = in_file;
search_paths = paths;
}
else
{
file = cygpath (in_file, NULL);
search_paths = abspath;
showall = false;
}
if (!file) if (!file)
{ {
display_error ("find_on_path: NULL pointer for file", false, false); display_error ("internal error find_on_path: cygpath conversion failed for %s\n", in_file);
return 0; return 0;
} }
if (default_extension == NULL) char *hasext = strrchr (file, '.');
{ if (hasext && !strpbrk (hasext, "/\\"))
display_error ("find_on_path: NULL pointer for default_extension", false, false); ext = "";
return 0;
}
if (strchr (file, ':') || strchr (file, '\\') || strchr (file, '/')) for (pathlike *pth = search_paths; pth->dir; pth++)
{ if (!pth->issys || search_sys)
// FIXME: this will find "foo" before "foo.exe" -- contrary to Windows {
char *fn = cygpath (file, NULL); pth->check_existence (file, showall, verbose, rv, ext);
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;
}
if (strchr (file, '.')) if (checklinks)
default_extension = (char *) ""; pth->check_existence (file, showall, verbose, rv, ext, LINK_EXTENSION);
for (int i = search_sysdirs ? 0 : first_nonsys_path; i < num_paths; i++) if (!*ext)
{ continue;
if (i == 0 || !search_sysdirs || strcasecmp (paths[i], paths[0]))
{
sprintf (ptr, "%s\\%s%s", paths[i], file, default_extension);
if (check_existence (ptr, showall, ptr == tmp && verbose, rv))
ptr = tmp;
if (!checklinks) pth->check_existence (file, showall, verbose, rv);
continue; if (checklinks)
pth->check_existence (file, showall, verbose, rv, LINK_EXTENSION);
}
sprintf (ptr, "%s\\%s%s%s", paths[i], file, default_extension, LINK_EXTENSION); return *rv ? rv : NULL;
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;
}
}
if (ptr == tmp)
return rv;
return 0;
} }
#define DID_NEW 1 #define DID_NEW 1
@ -369,7 +414,7 @@ struct Did
static Did *did = 0; static Did *did = 0;
static Did * static Did *
already_did (char *file) already_did (const char *file)
{ {
Did *d; Did *d;
for (d = did; d; d = d->next) for (d = did; d; d = d->next)
@ -440,8 +485,7 @@ struct ImpDirectory
unsigned iat_rva; unsigned iat_rva;
}; };
static bool track_down (const char *file, const char *suffix, int lvl);
static bool track_down (char *file, char *suffix, int lvl);
#define CYGPREFIX (sizeof ("%%% Cygwin ") - 1) #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
static void static void
@ -647,7 +691,7 @@ dll_info (const char *path, HANDLE fh, int lvl, int recurse)
// Return true on success, false if error printed // Return true on success, false if error printed
static bool static bool
track_down (char *file, char *suffix, int lvl) track_down (const char *file, const char *suffix, int lvl)
{ {
if (file == NULL) if (file == NULL)
{ {
@ -661,10 +705,10 @@ track_down (char *file, char *suffix, int lvl)
return false; return false;
} }
char *path = find_on_path (file, suffix, 0, 1); const char *path = find_on_path (file, suffix, false, true);
if (!path) if (!path)
{ {
printf ("Error: could not find %s\n", file); display_error ("track_down: could not find %s\n", file);
return false; return false;
} }
@ -700,7 +744,7 @@ track_down (char *file, char *suffix, int lvl)
if (!path) if (!path)
{ {
printf ("%s not found\n", file); display_error ("file not found - '%s'\n", file);
return false; return false;
} }
@ -711,7 +755,7 @@ track_down (char *file, char *suffix, int lvl)
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) if (fh == INVALID_HANDLE_VALUE)
{ {
printf (" - Cannot open\n"); display_error ("cannot open - '%s'\n", path);
return false; return false;
} }
@ -720,15 +764,15 @@ track_down (char *file, char *suffix, int lvl)
if (is_exe (fh)) if (is_exe (fh))
dll_info (path, fh, lvl, 1); dll_info (path, fh, lvl, 1);
else if (is_symlink (fh)) else if (is_symlink (fh))
printf (" - Found a symlink instead of a DLL\n"); display_error ("%s is a symlink instead of a DLL\n", path);
else else
{ {
int magic = get_word (fh, 0x0); int magic = get_word (fh, 0x0);
if (magic == -1) if (magic == -1)
display_error ("get_word"); display_error ("get_word");
magic &= 0x00FFFFFF; magic &= 0x00FFFFFF;
printf (" - Not a DLL: magic number %x (%d) '%s'\n", display_error_fmt ("%s is not a DLL: magic number %x (%d) '%s'\n",
magic, magic, (char *)&magic); path, magic, magic, (char *)&magic);
} }
d->state = DID_INACTIVE; d->state = DID_INACTIVE;
@ -760,19 +804,16 @@ ls (char *f)
} }
// Find a real application on the path (possibly following symlinks) // Find a real application on the path (possibly following symlinks)
static char * static const char *
find_app_on_path (char *app, int showall = 0) find_app_on_path (const char *app, bool showall = false)
{ {
char *papp = find_on_path (app, (char *) ".exe", showall, 0, 1); const char *papp = find_on_path (app, ".exe", showall, false, true);
HANDLE fh = HANDLE fh =
CreateFile (papp, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, CreateFile (papp, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) if (fh == INVALID_HANDLE_VALUE)
{ return NULL;
printf (" - Cannot open\n");
return NULL;
}
if (is_symlink (fh)) if (is_symlink (fh))
{ {
@ -806,28 +847,33 @@ find_app_on_path (char *app, int showall = 0)
// Return true on success, false if error printed // Return true on success, false if error printed
static bool static bool
cygcheck (char *app) cygcheck (const char *app)
{ {
char *papp = find_app_on_path (app, 1); const char *papp = find_app_on_path (app, 1);
if (!papp) if (!papp)
{ {
printf ("Error: could not find %s\n", app); display_error ("could not find '%s'\n", app);
return false; return false;
} }
char *s = strdup (papp);
char *sl = 0, *t; char *s;
for (t = s; *t; t++) char *sep = strpbrk (papp, ":/\\");
if (*t == '/' || *t == '\\' || *t == ':') if (!sep)
sl = t; {
if (sl == 0) static char dot[] = ".";
paths[0] = (char *) "."; s = dot;
}
else else
{ {
*sl = 0; int n = sep - papp;
paths[0] = s; s = (char *) malloc (n + 2);
memcpy ((char *) s, papp, n);
strcpy (s + n, "\\");
} }
did = 0;
return track_down (papp, (char *) ".exe", 0); paths[0].dir = s;
did = NULL;
return track_down (papp, ".exe", 0);
} }
@ -1192,15 +1238,15 @@ dump_sysinfo ()
else if (osversion.dwMinorVersion == 1) else if (osversion.dwMinorVersion == 1)
{ {
if (GetSystemMetrics (SM_MEDIACENTER)) if (GetSystemMetrics (SM_MEDIACENTER))
osname = "XP Media Center Edition"; osname = "XP Media Center Edition";
else if (GetSystemMetrics (SM_TABLETPC)) else if (GetSystemMetrics (SM_TABLETPC))
osname = "XP Tablet PC Edition"; osname = "XP Tablet PC Edition";
else if (!more_info) else if (!more_info)
osname = "XP"; osname = "XP";
else if (osversionex.wSuiteMask & VER_SUITE_PERSONAL) else if (osversionex.wSuiteMask & VER_SUITE_PERSONAL)
osname = "XP Home Edition"; osname = "XP Home Edition";
else else
osname = "XP Professional"; osname = "XP Professional";
} }
else if (osversion.dwMinorVersion == 2) else if (osversion.dwMinorVersion == 2)
{ {
@ -1238,12 +1284,12 @@ dump_sysinfo ()
if (wow64_func && wow64_func (GetCurrentProcess (), &is_wow64) && is_wow64) if (wow64_func && wow64_func (GetCurrentProcess (), &is_wow64) && is_wow64)
{ {
void (WINAPI *nativinfo) (LPSYSTEM_INFO) = (void (WINAPI *) void (WINAPI *nativinfo) (LPSYSTEM_INFO) = (void (WINAPI *)
(LPSYSTEM_INFO)) GetProcAddress (k32, "GetNativeSystemInfo"); (LPSYSTEM_INFO)) GetProcAddress (k32, "GetNativeSystemInfo");
SYSTEM_INFO natinfo; SYSTEM_INFO natinfo;
nativinfo (&natinfo); nativinfo (&natinfo);
fputs ("\nRunning under WOW64 on ", stdout); fputs ("\nRunning under WOW64 on ", stdout);
switch (natinfo.wProcessorArchitecture) switch (natinfo.wProcessorArchitecture)
{ {
case PROCESSOR_ARCHITECTURE_IA64: case PROCESSOR_ARCHITECTURE_IA64:
puts ("IA64"); puts ("IA64");
break; break;
@ -1522,8 +1568,6 @@ dump_sysinfo ()
} }
printf ("\n"); printf ("\n");
add_path ((char *) "\\bin", 4); /* just in case */
if (givehelp) if (givehelp)
printf printf
("Looking to see where common programs can be found, if at all...\n"); ("Looking to see where common programs can be found, if at all...\n");
@ -1540,10 +1584,10 @@ dump_sysinfo ()
if (givehelp) if (givehelp)
printf ("Looking for various Cygwin DLLs... (-v gives version info)\n"); printf ("Looking for various Cygwin DLLs... (-v gives version info)\n");
int cygwin_dll_count = 0; int cygwin_dll_count = 0;
for (i = 1; i < num_paths; i++) for (pathlike *pth = paths; pth->dir; pth++)
{ {
WIN32_FIND_DATA ffinfo; WIN32_FIND_DATA ffinfo;
sprintf (tmp, "%s/*.*", paths[i]); sprintf (tmp, "%s*.*", pth->dir);
HANDLE ff = FindFirstFile (tmp, &ffinfo); HANDLE ff = FindFirstFile (tmp, &ffinfo);
int found = (ff != INVALID_HANDLE_VALUE); int found = (ff != INVALID_HANDLE_VALUE);
found_cygwin_dll = NULL; found_cygwin_dll = NULL;
@ -1554,7 +1598,7 @@ dump_sysinfo ()
{ {
if (strncasecmp (f, "cyg", 3) == 0) if (strncasecmp (f, "cyg", 3) == 0)
{ {
sprintf (tmp, "%s\\%s", paths[i], f); sprintf (tmp, "%s%s", pth->dir, f);
if (strcasecmp (f, "cygwin1.dll") == 0) if (strcasecmp (f, "cygwin1.dll") == 0)
{ {
cygwin_dll_count++; cygwin_dll_count++;
@ -1672,7 +1716,7 @@ static const char safe_chars[] = "$-_.+!*'(),";
/* the URL to query. */ /* the URL to query. */
static const char base_url[] = static const char base_url[] =
"http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep="; "http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep=";
/* Queries Cygwin web site for packages containing files matching a regexp. /* Queries Cygwin web site for packages containing files matching a regexp.
Return value is 1 if there was a problem, otherwise 0. */ Return value is 1 if there was a problem, otherwise 0. */
@ -1687,7 +1731,7 @@ package_grep (char *search)
if (!(hWinInet = LoadLibrary ("wininet.dll"))) if (!(hWinInet = LoadLibrary ("wininet.dll")))
{ {
fputs ("Unable to locate WININET.DLL. This feature requires Microsoft " fputs ("Unable to locate WININET.DLL. This feature requires Microsoft "
"Internet Explorer v3 or later to function.\n", stderr); "Internet Explorer v3 or later to function.\n", stderr);
return 1; return 1;
} }
@ -1696,25 +1740,25 @@ package_grep (char *search)
and call GetProcAddress for each of them with the following macro. */ and call GetProcAddress for each of them with the following macro. */
pInternetCloseHandle = (BOOL (WINAPI *) (HINTERNET)) pInternetCloseHandle = (BOOL (WINAPI *) (HINTERNET))
GetProcAddress (hWinInet, "InternetCloseHandle"); GetProcAddress (hWinInet, "InternetCloseHandle");
#define make_func_pointer(name, ret, args) ret (WINAPI * p##name) args = \ #define make_func_pointer(name, ret, args) ret (WINAPI * p##name) args = \
(ret (WINAPI *) args) GetProcAddress (hWinInet, #name); (ret (WINAPI *) args) GetProcAddress (hWinInet, #name);
make_func_pointer (InternetAttemptConnect, DWORD, (DWORD)); make_func_pointer (InternetAttemptConnect, DWORD, (DWORD));
make_func_pointer (InternetOpenA, HINTERNET, (LPCSTR, DWORD, LPCSTR, LPCSTR, make_func_pointer (InternetOpenA, HINTERNET, (LPCSTR, DWORD, LPCSTR, LPCSTR,
DWORD)); DWORD));
make_func_pointer (InternetOpenUrlA, HINTERNET, (HINTERNET, LPCSTR, LPCSTR, make_func_pointer (InternetOpenUrlA, HINTERNET, (HINTERNET, LPCSTR, LPCSTR,
DWORD, DWORD, DWORD)); DWORD, DWORD, DWORD));
make_func_pointer (InternetReadFile, BOOL, (HINTERNET, PVOID, DWORD, PDWORD)); make_func_pointer (InternetReadFile, BOOL, (HINTERNET, PVOID, DWORD, PDWORD));
make_func_pointer (HttpQueryInfoA, BOOL, (HINTERNET, DWORD, PVOID, PDWORD, make_func_pointer (HttpQueryInfoA, BOOL, (HINTERNET, DWORD, PVOID, PDWORD,
PDWORD)); PDWORD));
#undef make_func_pointer #undef make_func_pointer
if(!pInternetCloseHandle || !pInternetAttemptConnect || !pInternetOpenA if(!pInternetCloseHandle || !pInternetAttemptConnect || !pInternetOpenA
|| !pInternetOpenUrlA || !pInternetReadFile || !pHttpQueryInfoA) || !pInternetOpenUrlA || !pInternetReadFile || !pHttpQueryInfoA)
{ {
fputs ("Unable to load one or more functions from WININET.DLL. This " fputs ("Unable to load one or more functions from WININET.DLL. This "
"feature requires Microsoft Internet Explorer v3 or later to " "feature requires Microsoft Internet Explorer v3 or later to "
"function.\n", stderr); "function.\n", stderr);
return 1; return 1;
} }
@ -1726,16 +1770,16 @@ package_grep (char *search)
for (dest = &url[sizeof (base_url) - 1]; *search; search++) for (dest = &url[sizeof (base_url) - 1]; *search; search++)
{ {
if (isalnum (*search) if (isalnum (*search)
|| memchr (safe_chars, *search, sizeof (safe_chars) - 1)) || memchr (safe_chars, *search, sizeof (safe_chars) - 1))
{ {
*dest++ = *search; *dest++ = *search;
} }
else else
{ {
*dest++ = '%'; *dest++ = '%';
sprintf (dest, "%02x", (unsigned char) *search); sprintf (dest, "%02x", (unsigned char) *search);
dest += 2; dest += 2;
} }
} }
*dest = 0; *dest = 0;
@ -1753,18 +1797,18 @@ package_grep (char *search)
if (!(hurl = pInternetOpenUrlA (hi, url, NULL, 0, 0, 0))) if (!(hurl = pInternetOpenUrlA (hi, url, NULL, 0, 0, 0)))
return display_internet_error ("unable to contact cygwin.com site, " return display_internet_error ("unable to contact cygwin.com site, "
"InternetOpenUrl() failed", hi, NULL); "InternetOpenUrl() failed", hi, NULL);
/* Check the HTTP response code. */ /* Check the HTTP response code. */
DWORD rc = 0, rc_s = sizeof (DWORD); DWORD rc = 0, rc_s = sizeof (DWORD);
if (!pHttpQueryInfoA (hurl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, if (!pHttpQueryInfoA (hurl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
(void *) &rc, &rc_s, NULL)) (void *) &rc, &rc_s, NULL))
return display_internet_error ("HttpQueryInfo() failed", hurl, hi, NULL); return display_internet_error ("HttpQueryInfo() failed", hurl, hi, NULL);
if (rc != HTTP_STATUS_OK) if (rc != HTTP_STATUS_OK)
{ {
sprintf (buf, "error retrieving results from cygwin.com site, " sprintf (buf, "error retrieving results from cygwin.com site, "
"HTTP status code %lu", rc); "HTTP status code %lu", rc);
return display_internet_error (buf, hurl, hi, NULL); return display_internet_error (buf, hurl, hi, NULL);
} }
@ -1773,9 +1817,9 @@ package_grep (char *search)
do do
{ {
if (!pInternetReadFile (hurl, (void *) buf, sizeof (buf), &numread)) if (!pInternetReadFile (hurl, (void *) buf, sizeof (buf), &numread))
return display_internet_error ("InternetReadFile failed", hurl, hi, NULL); return display_internet_error ("InternetReadFile failed", hurl, hi, NULL);
if (numread) if (numread)
fwrite ((void *) buf, (size_t) numread, 1, stdout); fwrite ((void *) buf, (size_t) numread, 1, stdout);
} }
while (numread); while (numread);
@ -1955,8 +1999,8 @@ main (int argc, char **argv)
list_package = 1; list_package = 1;
break; break;
case 'p': case 'p':
grep_packages = 1; grep_packages = 1;
break; break;
case 'h': case 'h':
givehelp = 1; givehelp = 1;
break; break;

View File

@ -1,6 +1,6 @@
/* path.cc /* path.cc
Copyright 2001, 2002, 2003, 2005 Red Hat, Inc. Copyright 2001, 2002, 2003, 2005, 2006, 2007 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -24,7 +24,7 @@ details. */
#include "cygwin/include/mntent.h" #include "cygwin/include/mntent.h"
/* Used when treating / and \ as equivalent. */ /* Used when treating / and \ as equivalent. */
#define SLASH_P(ch) \ #define isslash(ch) \
({ \ ({ \
char __c = (ch); \ char __c = (ch); \
((__c) == '/' || (__c) == '\\'); \ ((__c) == '/' || (__c) == '\\'); \
@ -150,7 +150,7 @@ is_symlink (HANDLE fh)
if (got != size || !cmp_shortcut_header ((win_shortcut_hdr *) buf)) if (got != size || !cmp_shortcut_header ((win_shortcut_hdr *) buf))
return false; /* Not a Cygwin symlink. */ return false; /* Not a Cygwin symlink. */
/* TODO: check for invalid path contents /* TODO: check for invalid path contents
(see symlink_info::check() in ../cygwin/path.cc) */ (see symlink_info::check() in ../cygwin/path.cc) */
} }
else /* magic == SYMLINK_MAGIC */ else /* magic == SYMLINK_MAGIC */
{ {
@ -161,7 +161,7 @@ is_symlink (HANDLE fh)
if (!ReadFile (fh, buf, sizeof (buf), &got, 0)) if (!ReadFile (fh, buf, sizeof (buf), &got, 0))
return false; return false;
if (got != sizeof (buf) || if (got != sizeof (buf) ||
memcmp (buf, SYMLINK_COOKIE, sizeof (buf)) != 0) memcmp (buf, SYMLINK_COOKIE, sizeof (buf)) != 0)
return false; /* Not a Cygwin symlink. */ return false; /* Not a Cygwin symlink. */
} }
return true; return true;
@ -184,11 +184,11 @@ readlink (HANDLE fh, char *path, int maxlen)
return false; return false;
} }
if (SetFilePointer (fh, 0x4c + offset + 4, 0, FILE_BEGIN) == if (SetFilePointer (fh, 0x4c + offset + 4, 0, FILE_BEGIN) ==
INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
return false; return false;
if (!ReadFile (fh, path, slen, (DWORD *) &got, 0)) if (!ReadFile (fh, path, slen, (DWORD *) &got, 0))
return false; return false;
else if (got < slen) else if (got < slen)
{ {
SetLastError (ERROR_READ_FAULT); SetLastError (ERROR_READ_FAULT);
@ -203,15 +203,15 @@ readlink (HANDLE fh, char *path, int maxlen)
if (SetFilePointer (fh, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER if (SetFilePointer (fh, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR) && GetLastError () != NO_ERROR)
return false; return false;
if (!ReadFile (fh, cookie_buf, sizeof (cookie_buf), (DWORD *) &got, 0)) if (!ReadFile (fh, cookie_buf, sizeof (cookie_buf), (DWORD *) &got, 0))
return false; return false;
else if (got == sizeof (cookie_buf) else if (got == sizeof (cookie_buf)
&& memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0)
{ {
if (!ReadFile (fh, path, maxlen, (DWORD *) &got, 0)) if (!ReadFile (fh, path, maxlen, (DWORD *) &got, 0))
return false; return false;
else if (got >= maxlen) else if (got >= maxlen)
{ {
SetLastError (ERROR_FILENAME_EXCED_RANGE); SetLastError (ERROR_FILENAME_EXCED_RANGE);
@ -378,16 +378,16 @@ static int
path_prefix_p (const char *path1, const char *path2, int len1) path_prefix_p (const char *path1, const char *path2, int len1)
{ {
/* Handle case where PATH1 has trailing '/' and when it doesn't. */ /* Handle case where PATH1 has trailing '/' and when it doesn't. */
if (len1 > 0 && SLASH_P (path1[len1 - 1])) if (len1 > 0 && isslash (path1[len1 - 1]))
len1--; len1--;
if (len1 == 0) if (len1 == 0)
return SLASH_P (path2[0]) && !SLASH_P (path2[1]); return isslash (path2[0]) && !isslash (path2[1]);
if (strncasecmp (path1, path2, len1) != 0) if (strncasecmp (path1, path2, len1) != 0)
return 0; return 0;
return SLASH_P (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':'; return isslash (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':';
} }
static char * static char *
@ -403,7 +403,7 @@ vconcat (const char *s, va_list v)
len = strlen (s); len = strlen (s);
unc = SLASH_P (*s) && SLASH_P (s[1]); unc = isslash (*s) && isslash (s[1]);
while (1) while (1)
{ {
@ -462,6 +462,43 @@ concat (const char *s, ...)
return vconcat (s, v); return vconcat (s, v);
} }
static char *
rel_vconcat (const char *s, va_list v)
{
char path[MAX_PATH + 1];
if (!GetCurrentDirectory (MAX_PATH, path))
return NULL;
int max_len = -1;
struct mnt *m, *match = NULL;
if (s[0] == '.' && isslash (s[1]))
s += 2;
for (m = mount_table; m->posix ; m++)
{
if (m->flags & MOUNT_CYGDRIVE)
continue;
int n = strlen (m->native);
if (n < max_len || !path_prefix_p (m->native, path, n))
continue;
max_len = n;
match = m;
}
if (match)
strcpy (path, match->posix);
if (!isslash (strchr (path, '\0')[-1]))
strcat (path, "/");
char *temppath = concat (path, s, NULL);
char *res = vconcat (temppath, v);
free (temppath);
return res;
}
char * char *
cygpath (const char *s, ...) cygpath (const char *s, ...)
{ {
@ -472,9 +509,15 @@ cygpath (const char *s, ...)
if (!mount_table[0].posix) if (!mount_table[0].posix)
read_mounts (); read_mounts ();
va_start (v, s); va_start (v, s);
char *path = vconcat (s, v); char *path;
if (strncmp (path, "./", 2) == 0) if (s[0] == '/' || s[1] == ':') /* FIXME: too crude? */
memmove (path, path + 2, strlen (path + 2) + 1); path = vconcat (s, v);
else
path = rel_vconcat (s, v);
if (!path)
return NULL;
if (strncmp (path, "/./", 3) == 0) if (strncmp (path, "/./", 3) == 0)
memmove (path + 1, path + 3, strlen (path + 3) + 1); memmove (path + 1, path + 3, strlen (path + 3) + 1);
@ -542,7 +585,7 @@ getmntent (FILE *)
strcat (mnt.mnt_opts, (char *) ",noexec"); strcat (mnt.mnt_opts, (char *) ",noexec");
if (m->flags & MOUNT_ENC) if (m->flags & MOUNT_ENC)
strcat (mnt.mnt_opts, ",managed"); strcat (mnt.mnt_opts, ",managed");
if ((m->flags & MOUNT_CYGDRIVE)) /* cygdrive */ if ((m->flags & MOUNT_CYGDRIVE)) /* cygdrive */
strcat (mnt.mnt_opts, (char *) ",cygdrive"); strcat (mnt.mnt_opts, (char *) ",cygdrive");
mnt.mnt_freq = 1; mnt.mnt_freq = 1;
mnt.mnt_passno = 1; mnt.mnt_passno = 1;