* Makefile.in (cygcheck.exe): Compile as -mno-cygwin executable.

* path.cc: New file.
* cygcheck.cc (init_paths): Use MS-DOS path syntax.
(cygwin_info): Properly display cygwin version numbers.  Prettify some output.
(dump_sysinfo): Calculate max names of posix and ms-dos paths for prettier
output.
This commit is contained in:
Christopher Faylor 2001-11-11 03:06:59 +00:00
parent c8b3452829
commit 2fac517df4
4 changed files with 423 additions and 13 deletions

View File

@ -1,3 +1,13 @@
2001-11-10 Christopher Faylor <cgf@redhat.com>
* Makefile.in (cygcheck.exe): Compile as -mno-cygwin executable.
* path.cc: New file.
* cygcheck.cc (init_paths): Use MS-DOS path syntax.
(cygwin_info): Properly display cygwin version numbers. Prettify some
output.
(dump_sysinfo): Calculate max names of posix and ms-dos paths for
prettier output.
2001-11-09 Corinna Vinschen <corinna@vinschen.de>
* cygcheck.cc (dump_sysinfo): Print more detailed OS information string.

View File

@ -94,6 +94,14 @@ else
$(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,2,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
endif
cygcheck.exe: cygcheck.cc mingw_getopt.o path.o $(MINGW_DEP_LDLIBS)
ifdef VERBOSE
$(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
else
@echo $(CXX) -o $@ ${wordlist 1,2,$^} ${filter-out -B%, $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS)};\
$(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
endif
dumper.o: dumper.cc dumper.h
ifdef VERBOSE
${filter-out -nostdinc,$(COMPILE_CXX)} $c -o $@ $(DUMPER_INCLUDES) ${firstword $^}
@ -127,6 +135,14 @@ else
${filter-out -I$(newlib_source)/%,$(COMPILE_CC)} $c -o $(@D)/$(basename $@)$o $(MINGW_CFLAGS) $<
endif
path.o: path.cc
ifdef VERBOSE
${filter-out -I$(newlib_source)/%,$(COMPILE_CC)} $c -o $(@D)/$(basename $@)$o $(MINGW_CFLAGS) $<
else
@echo $(CC) $c -o $(@D)/$(basename $@)$o $(MINGW_CFLAGS) ... $^;\
${filter-out -I$(newlib_source)/%,$(COMPILE_CC)} $c -o $(@D)/$(basename $@)$o $(MINGW_CFLAGS) $<
endif
clean:
rm -f *.o $(CLEAN_PROGS)

View File

@ -8,6 +8,8 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
typedef unsigned short uid_t;
typedef unsigned short gid_t;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -16,6 +18,7 @@
#include <mntent.h>
#include <time.h>
#include <getopt.h>
#include <ctype.h>
int verbose = 0;
int registry = 0;
@ -134,18 +137,14 @@ init_paths ()
GetWindowsDirectory (tmp, 4000);
add_path (tmp, strlen (tmp));
char *path = getenv ("PATH");
if (path)
char *wpath = getenv ("PATH");
if (wpath)
{
char wpath[4000];
cygwin_posix_to_win32_path_list (path, wpath);
char *b, *e, sep = ':';
if (strchr (wpath, ';'))
sep = ';';
char *b, *e;
b = wpath;
while (1)
{
for (e = b; *e && *e != sep; e++);
for (e = b; *e && *e != ';'; e++);
add_path (b, e - b);
if (!*e)
break;
@ -350,6 +349,7 @@ cygwin_info (HANDLE h)
return;
}
char *dll_major;
bufend = buf + size;
while (buf < bufend)
if ((buf = (char *) memchr (buf, '%', bufend - buf)) == NULL)
@ -361,9 +361,33 @@ cygwin_info (HANDLE h)
char *p = strchr (buf += CYGPREFIX, '\n');
if (!p)
break;
fputs (hello, stdout);
fputs (" ", stdout);
fwrite (buf, 1 + p - buf, 1, stdout);
if (strncasecmp (buf, "dll major:", 10) == 0)
{
dll_major = buf + 11;
continue;
}
char *s, pbuf[80];
int len;
len = 1 + p - buf;
if (strncasecmp (buf, "dll minor:", 10) != 0)
s = buf;
else
{
char c = dll_major[1];
dll_major[1] = '\0';
int maj = atoi (dll_major);
dll_major[1] = c;
int min = atoi (dll_major + 1);
sprintf (pbuf, "DLL version: %d.%d.%.*s", maj, min, len - 11, buf + 11);
len = strlen (s = pbuf);
}
if (strncmp (s, "dll", 3) == 0)
memcpy (s, "DLL", 3);
else if (strncmp (s, "api", 3) == 0)
memcpy (s, "API", 3);
else if (islower (*s))
*s = toupper (*s);
fprintf (stdout, "%s %.*s", hello, len, s);
hello = "";
}
@ -987,6 +1011,18 @@ dump_sysinfo ()
unsigned int ml_fsname = 4, ml_dir = 7, ml_type = 6;
struct mntent *mnt;
setmntent (0, 0);
while ((mnt = getmntent (0)))
{
int n = (int) strlen (mnt->mnt_fsname);
if (ml_fsname < n)
ml_fsname = n;
n = (int) strlen (mnt->mnt_dir);
if (ml_dir < n)
ml_dir = n;
}
if (givehelp)
{
printf
@ -995,9 +1031,7 @@ dump_sysinfo ()
ml_type, "-Type-", "-Flags-");
}
struct mntent *mnt;
setmntent (0, 0);
while ((mnt = getmntent (0)))
{
printf ("%-*s %-*s %-*s %s\n",

350
winsup/utils/path.cc Normal file
View File

@ -0,0 +1,350 @@
/*
* Copyright (c) 2000, Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* A copy of the GNU General Public License can be found at
* http://www.gnu.org/
*
* Written by DJ Delorie <dj@cygnus.com>
*
*/
/* The purpose of this file is to hide all the details about accessing
Cygwin's mount table. If the format or location of the mount table
changes, this is the file to change to match it. */
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <cygwin/version.h>
#include <sys/mount.h>
#include <mntent.h>
/* Used when treating / and \ as equivalent. */
#define SLASH_P(ch) \
({ \
char __c = (ch); \
((__c) == '/' || (__c) == '\\'); \
})
static struct mnt
{
const char *native;
char *posix;
unsigned flags;
int issys;
} mount_table[255];
struct mnt *root_here = NULL;
static char *
find2 (HKEY rkey, unsigned *flags, char *what)
{
char *retval = 0;
DWORD retvallen = 0;
DWORD type;
HKEY key;
if (RegOpenKeyEx (rkey, what, 0, KEY_READ, &key) != ERROR_SUCCESS)
return 0;
if (RegQueryValueEx (key, "native", 0, &type, 0, &retvallen)
== ERROR_SUCCESS)
{
retval = (char *) malloc (MAX_PATH + 1);
if (RegQueryValueEx (key, "native", 0, &type, (BYTE *) retval, &retvallen)
!= ERROR_SUCCESS)
{
free (retval);
retval = 0;
}
}
retvallen = sizeof (flags);
RegQueryValueEx (key, "flags", 0, &type, (BYTE *)flags, &retvallen);
RegCloseKey (key);
return retval;
}
static LONG
get_cygdrive0 (HKEY key, const char *what, void *val, DWORD len)
{
LONG status = RegQueryValueEx (key, what, 0, 0, (BYTE *)val, &len);
return status;
}
static mnt *
get_cygdrive (HKEY key, mnt *m, int issystem)
{
if (get_cygdrive0 (key, CYGWIN_INFO_CYGDRIVE_FLAGS, &m->flags,
sizeof (m->flags)) != ERROR_SUCCESS) {
free (m->posix);
return m;
}
get_cygdrive0 (key, CYGWIN_INFO_CYGDRIVE_PREFIX, m->posix, MAX_PATH);
m->native = strdup (".");
return m + 1;
}
void
read_mounts ()
{
DWORD posix_path_size;
int res;
struct mnt *m = mount_table;
DWORD disposition;
char buf[10000];
root_here = NULL;
for (mnt *m1 = mount_table; m1->posix; m1++)
{
free (m1->posix);
if (m1->native)
free ((char *) m1->native);
m1->posix = NULL;
}
/* Loop through subkeys */
/* FIXME: we would like to not check MAX_MOUNTS but the heap in the
shared area is currently statically allocated so we can't have an
arbitrarily large number of mounts. */
for (int issystem = 0; issystem <= 1; issystem++)
{
sprintf (buf, "Software\\%s\\%s\\%s",
CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME);
HKEY key = issystem ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
if (RegCreateKeyEx (key, buf, 0, (LPTSTR) "Cygwin", 0, KEY_ALL_ACCESS,
0, &key, &disposition) != ERROR_SUCCESS)
break;
for (int i = 0; ;i++, m++)
{
m->posix = (char *) malloc (MAX_PATH + 1);
posix_path_size = MAX_PATH;
/* FIXME: if maximum posix_path_size is 256, we're going to
run into problems if we ever try to store a mount point that's
over 256 but is under MAX_PATH. */
res = RegEnumKeyEx (key, i, m->posix, &posix_path_size, NULL,
NULL, NULL, NULL);
if (res == ERROR_NO_MORE_ITEMS)
{
m = get_cygdrive (key, m, issystem);
m->posix = NULL;
break;
}
if (!*m->posix)
goto no_go;
else if (res != ERROR_SUCCESS)
break;
else
{
m->native = find2 (key, &m->flags, m->posix);
m->issys = issystem;
if (!m->native)
goto no_go;
}
continue;
no_go:
free (m->posix);
m->posix = NULL;
m--;
}
RegCloseKey (key);
}
}
/* Return non-zero if PATH1 is a prefix of PATH2.
Both are assumed to be of the same path style and / vs \ usage.
Neither may be "".
LEN1 = strlen (PATH1). It's passed because often it's already known.
Examples:
/foo/ is a prefix of /foo <-- may seem odd, but desired
/foo is a prefix of /foo/
/ is a prefix of /foo/bar
/ is not a prefix of foo/bar
foo/ is a prefix foo/bar
/foo is not a prefix of /foobar
*/
static int
path_prefix_p (const char *path1, const char *path2, int len1)
{
/* Handle case where PATH1 has trailing '/' and when it doesn't. */
if (len1 > 0 && SLASH_P (path1[len1 - 1]))
len1--;
if (len1 == 0)
return SLASH_P (path2[0]) && !SLASH_P (path2[1]);
if (strncasecmp (path1, path2, len1) != 0)
return 0;
return SLASH_P (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':';
}
static char *
vconcat (const char *s, va_list v)
{
int len;
char *rv, *arg;
va_list save_v = v;
int unc;
if (!s)
return 0;
len = strlen (s);
unc = SLASH_P (*s) && SLASH_P (s[1]);
while (1)
{
arg = va_arg (v, char *);
if (arg == 0)
break;
len += strlen (arg);
}
va_end (v);
rv = (char *) malloc (len + 1);
strcpy (rv, s);
v = save_v;
while (1)
{
arg = va_arg (v, char *);
if (arg == 0)
break;
strcat (rv, arg);
}
va_end (v);
char *d, *p;
for (p = rv; *p; p++)
if (*p == '\\')
*p = '/';
/* concat is only used for urls and files, so we can safely
canonicalize the results */
for (p = d = rv; *p; p++)
{
*d++ = *p;
/* special case for URLs */
if (*p == ':' && p[1] == '/' && p[2] == '/' && p > rv + 1)
{
*d++ = *++p;
*d++ = *++p;
}
else if (*p == '/' || *p == '\\')
{
if (p == rv && unc)
p++;
while (p[1] == '/')
p++;
}
}
*d = 0;
return rv;
}
static char *
concat (const char *s, ...)
{
va_list v;
va_start (v, s);
return vconcat (s, v);
}
char *
cygpath (const char *s, ...)
{
va_list v;
int max_len = -1;
struct mnt *m, *match = NULL;
va_start (v, s);
char *path = vconcat (s, v);
if (strncmp (path, "./", 2) == 0)
memmove (path, path + 2, strlen (path + 2) + 1);
if (strncmp (path, "/./", 3) == 0)
memmove (path + 1, path + 3, strlen (path + 3) + 1);
for (m = mount_table; m->posix ; m++)
{
int n = strlen (m->posix);
if (n < max_len || !path_prefix_p (m->posix, path, n))
continue;
max_len = n;
match = m;
}
char *native;
if (match == NULL)
native = strdup (path);
else if (max_len == (int) strlen (path))
native = strdup (match->native);
else
native = concat (match->native, "/", path + max_len, NULL);
free (path);
return native;
}
static mnt *m = NULL;
extern "C" FILE *
setmntent (const char *, const char *)
{
m = mount_table;
if (!m->posix)
read_mounts ();
return NULL;
}
extern "C" struct mntent *
getmntent (FILE *)
{
static mntent mnt;
if (!m->posix)
return NULL;
mnt.mnt_fsname = (char *) m->native;
mnt.mnt_dir = (char *) m->posix;
if (!mnt.mnt_type)
mnt.mnt_type = (char *) malloc (1024);
if (!mnt.mnt_opts)
mnt.mnt_opts = (char *) malloc (1024);
if (!m->issys)
strcpy (mnt.mnt_type, (char *) "user");
else
strcpy (mnt.mnt_type, (char *) "system");
if (!(m->flags & MOUNT_BINARY))
strcpy (mnt.mnt_opts, (char *) "textmode");
else
strcpy (mnt.mnt_opts, (char *) "binmode");
if (m->flags & MOUNT_CYGWIN_EXEC)
strcat (mnt.mnt_opts, (char *) ",cygexec");
else if (m->flags & MOUNT_EXEC)
strcat (mnt.mnt_opts, (char *) ",exec");
if ((m->flags & MOUNT_AUTO)) /* cygdrive */
strcat (mnt.mnt_opts, (char *) ",noumount");
mnt.mnt_freq = 1;
mnt.mnt_passno = 1;
m++;
return &mnt;
}