summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-11-22 17:19:17 +0000
committerChristopher Faylor <me@cgf.cx>2005-11-22 17:19:17 +0000
commita39cfda7ba28acc3b3c8251c4b61582ed7bbaca6 (patch)
tree340e88d73e2f752b06bfb621bb24f82b5779b049
parent9cd22f86fcd88171082c8b912eb407bd16c27837 (diff)
downloadcygnal-a39cfda7ba28acc3b3c8251c4b61582ed7bbaca6.tar.gz
cygnal-a39cfda7ba28acc3b3c8251c4b61582ed7bbaca6.tar.bz2
cygnal-a39cfda7ba28acc3b3c8251c4b61582ed7bbaca6.zip
* Makefile.in: Link cygcheck with libwininet.a.
* cygcheck.cc: Add includes. (grep_packages): New global variable. (display_internet_error): New function. (safe_chars): New global variable. (base_url): Ditto. (package_grep): New function. (usage): Reword --help output for clarity. Document new argument. (longopts): Add 'package-query' option. (opts): Add 'p' option, reorder to be consistent with 'longopts'. (main): Accommodate new option. * utils.sgml (cygcheck): Update --help output. Document new -p option.
-rw-r--r--winsup/utils/ChangeLog19
-rw-r--r--winsup/utils/Makefile.in8
-rw-r--r--winsup/utils/cygcheck.cc175
-rw-r--r--winsup/utils/cygpath.cc1
-rw-r--r--winsup/utils/utils.sgml107
5 files changed, 272 insertions, 38 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index fd8eebe42..53ef8b86b 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,18 @@
+2005-11-22 Brian Dessent <brian@dessent.net>
+
+ * Makefile.in: Link cygcheck with libwininet.a.
+ * cygcheck.cc: Add includes.
+ (grep_packages): New global variable.
+ (display_internet_error): New function.
+ (safe_chars): New global variable.
+ (base_url): Ditto.
+ (package_grep): New function.
+ (usage): Reword --help output for clarity. Document new argument.
+ (longopts): Add 'package-query' option.
+ (opts): Add 'p' option, reorder to be consistent with 'longopts'.
+ (main): Accommodate new option.
+ * utils.sgml (cygcheck): Update --help output. Document new -p option.
+
2005-09-22 Corinna Vinschen <corinna@vinschen.de>
Align error message handling to mkpasswd's error messages throughout.
@@ -457,9 +472,9 @@
correct system password settings just because the account has admin
privileges.
(usage): Define as "noreturn" function. Restructure and rephrase
- output. Accomodate new options.
+ output. Accommodate new options.
(print_version): Fix copyright dates.
- (main): Accomodate new options for setting UF_PASSWD_CANT_CHANGE,
+ (main): Accommodate new options for setting UF_PASSWD_CANT_CHANGE,
UF_DONT_EXPIRE_PASSWD and UF_PASSWD_NOTREQD settings.
2003-10-17 Christopher Faylor <cgf@redhat.com>
diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in
index e6069891f..1494996e8 100644
--- a/winsup/utils/Makefile.in
+++ b/winsup/utils/Makefile.in
@@ -99,15 +99,15 @@ else
$(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,2,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
endif
-cygcheck.exe: cygcheck.o path.o dump_setup.o $(MINGW_DEP_LDLIBS)
+cygcheck.exe: cygcheck.o path.o dump_setup.o $(MINGW_DEP_LDLIBS) $(w32api_lib)/libwininet.a
ifeq "$(libz)" ""
@echo '*** Building cygcheck without package content checking due to missing mingw libz.a.'
endif
ifdef VERBOSE
- $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) $(libz)
+ $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) $(libz) $(w32api_lib)/libwininet.a
else
- @echo $(CXX) -o $@ ${wordlist 1,3,$^} ${filter-out -B%, $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS)} $(libz);\
- $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) $(libz)
+ @echo $(CXX) -o $@ ${wordlist 1,3,$^} ${filter-out -B%, $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS)} $(libz) $(w32api_lib)/libwininet.a;\
+ $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) $(libz) $(w32api_lib)/libwininet.a
endif
dumper.o: dumper.cc dumper.h
diff --git a/winsup/utils/cygcheck.cc b/winsup/utils/cygcheck.cc
index af5871bca..0467a415a 100644
--- a/winsup/utils/cygcheck.cc
+++ b/winsup/utils/cygcheck.cc
@@ -11,11 +11,13 @@
#define cygwin_internal cygwin_internal_dontuse
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <ctype.h>
#include <io.h>
#include <windows.h>
+#include <wininet.h>
#include "path.h"
#include <getopt.h>
#include "cygwin/include/sys/cygwin.h"
@@ -33,6 +35,7 @@ int check_setup = 0;
int dump_only = 0;
int find_package = 0;
int list_package = 0;
+int grep_packages = 0;
#ifdef __GNUC__
typedef long long longlong;
@@ -124,6 +127,39 @@ display_error (const char *name, bool show_error = true, bool print_failed = tru
return 1;
}
+/* Display a WinInet error message, and close a variable number of handles.
+ (Passed a list of handles terminated by NULL.) */
+static int
+display_internet_error (const char *message, ...)
+{
+ DWORD err = GetLastError ();
+ TCHAR err_buf[256];
+ va_list hptr;
+ HINTERNET h;
+
+ /* in the case of a successful connection but 404 response, there is no
+ win32 error message, but we still get passed a message to display. */
+ if (err)
+ {
+ if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE,
+ GetModuleHandle ("wininet.dll"), err, 0, err_buf,
+ sizeof (err_buf), NULL) == 0)
+ strcpy (err_buf, "(Unknown error)");
+
+ fprintf (stderr, "cygcheck: %s: %s (win32 error %d)\n", message,
+ err_buf, err);
+ }
+ else
+ fprintf (stderr, "cygcheck: %s\n", message);
+
+ va_start (hptr, message);
+ while ((h = va_arg (hptr, HINTERNET)) != 0)
+ InternetCloseHandle (h);
+ va_end (hptr);
+
+ return 1;
+}
+
static void
add_path (char *s, int maxlen)
{
@@ -1496,24 +1532,122 @@ check_keys ()
return 0;
}
+/* RFC1738 says that these do not need to be escaped. */
+static const char safe_chars[] = "$-_.+!*'(),";
+
+/* the URL to query. */
+static const char base_url[] =
+ "http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep=";
+
+/* Queries Cygwin web site for packages containing files matching a regexp.
+ Return value is 1 if there was a problem, otherwise 0. */
+static int
+package_grep (char *search)
+{
+ char buf[1024];
+
+ /* construct the actual URL by escaping */
+ char *url = (char *) alloca (sizeof (base_url) + strlen (search) * 3);
+ strcpy (url, base_url);
+
+ char *dest;
+ for (dest = &url[sizeof (base_url) - 1]; *search; search++)
+ {
+ if (isalnum (*search)
+ || memchr (safe_chars, *search, sizeof (safe_chars) - 1))
+ {
+ *dest++ = *search;
+ }
+ else
+ {
+ *dest++ = '%';
+ sprintf (dest, "%02x", (unsigned char) *search);
+ dest += 2;
+ }
+ }
+ *dest = 0;
+
+ /* Connect to the net and open the URL. */
+ if (InternetAttemptConnect (0) != ERROR_SUCCESS)
+ {
+ fputs ("An internet connection is required for this function.\n", stderr);
+ return 1;
+ }
+
+ /* Initialize WinInet and attempt to fetch our URL. */
+ HINTERNET hi = NULL, hurl = NULL;
+ if (!(hi = InternetOpen ("cygcheck", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)))
+ return display_internet_error ("InternetOpen() failed", NULL);
+
+ if (!(hurl = InternetOpenUrl (hi, url, NULL, 0, 0, 0)))
+ return display_internet_error ("unable to contact cygwin.com site, "
+ "InternetOpenUrl() failed", hi, NULL);
+
+ /* Check the HTTP response code. */
+ DWORD rc = 0, rc_s = sizeof (DWORD);
+ if (!HttpQueryInfo (hurl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
+ (void *) &rc, &rc_s, NULL))
+ return display_internet_error ("HttpQueryInfo() failed", hurl, hi, NULL);
+
+ if (rc != HTTP_STATUS_OK)
+ {
+ sprintf (buf, "error retrieving results from cygwin.com site, "
+ "HTTP status code %lu", rc);
+ return display_internet_error (buf, hurl, hi, NULL);
+ }
+
+ /* Fetch result and print to stdout. */
+ DWORD numread;
+ do
+ {
+ if (!InternetReadFile (hurl, (void *) buf, sizeof (buf), &numread))
+ return display_internet_error ("InternetReadFile failed", hurl, hi, NULL);
+ if (numread)
+ fwrite ((void *) buf, (size_t) numread, 1, stdout);
+ }
+ while (numread);
+
+ InternetCloseHandle (hurl);
+ InternetCloseHandle (hi);
+ return 0;
+}
+
static void
usage (FILE * stream, int status)
{
fprintf (stream, "\
-Usage: cygcheck [OPTIONS] [PROGRAM...]\n\
-Check system information or PROGRAM library dependencies\n\
+Usage: cygcheck PROGRAM [ -v ] [ -h ]\n\
+ cygcheck -c [ PACKAGE ] [ -d ]\n\
+ cygcheck -s [ -r ] [ -v ] [ -h ]\n\
+ cygcheck -k\n\
+ cygcheck -f FILE [ FILE ... ]\n\
+ cygcheck -l [ PACKAGE ] [ PACKAGE ... ]\n\
+ cygcheck -p REGEXP\n\
+List system information, check installed packages, or query package database.\n\
+\n\
+At least one command option or a PROGRAM is required, as shown above.\n\
+\n\
+ PROGRAM list library (DLL) dependencies of PROGRAM\n\
+ -c, --check-setup show installed version of PACKAGE and verify integrity\n\
+ (or for all installed packages if none specified)\n\
+ -d, --dump-only just list packages, do not verify (with -c)\n\
+ -s, --sysinfo produce diagnostic system information (implies -c -d)\n\
+ -r, --registry also scan registry for Cygwin settings (with -s)\n\
+ -k, --keycheck perform a keyboard check session (must be run from a\n\
+ plain console only, not from a pty/rxvt/xterm)\n\
+ -f, --find-package find the package that FILE belongs to\n\
+ -l, --list-package list contents of PACKAGE (or all packages if none given)\n\
+ -p, --package-query search for REGEXP in the entire cygwin.com package\n\
+ repository (requies internet connectivity)\n\
+ -v, --verbose produce more verbose output\n\
+ -h, --help annotate output with explanatory comments when given\n\
+ with another command, otherwise print this help\n\
+ -V, --version print the version of cygcheck and exit\n\
\n\
- -c, --check-setup check packages installed via setup.exe\n\
- -d, --dump-only no integrity checking of package contents (requires -c)\n\
- -s, --sysinfo system information (not with -k)\n\
- -v, --verbose verbose output (indented) (for -[cfls] or programs)\n\
- -r, --registry registry search (requires -s)\n\
- -k, --keycheck perform a keyboard check session (not with -[scfl])\n\
- -f, --find-package find installed packages containing files (not with -[cl])\n\
- -l, --list-package list the contents of installed packages (not with -[cf])\n\
- -h, --help give help about the info (not with -[cfl])\n\
- -V, --version output version information and exit\n\
-You must at least give either -s or -k or a program name\n");
+Note: -c, -f, and -l only report on packages that are currently installed. To\n\
+ search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
+ package names, descriptions, and names of files/paths within all packages.\n\
+\n");
exit (status);
}
@@ -1526,12 +1660,13 @@ struct option longopts[] = {
{"keycheck", no_argument, NULL, 'k'},
{"find-package", no_argument, NULL, 'f'},
{"list-package", no_argument, NULL, 'l'},
+ {"package-query", no_argument, NULL, 'p'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, 0, 'V'},
{0, no_argument, NULL, 0}
};
-static char opts[] = "cdfhklrsvV";
+static char opts[] = "cdsrvkflphV";
static void
print_version ()
@@ -1643,6 +1778,9 @@ main (int argc, char **argv)
case 'l':
list_package = 1;
break;
+ case 'p':
+ grep_packages = 1;
+ break;
case 'h':
givehelp = 1;
break;
@@ -1661,20 +1799,23 @@ main (int argc, char **argv)
else
usage (stderr, 1);
- if ((check_setup || sysinfo || find_package || list_package) && keycheck)
+ if ((check_setup || sysinfo || find_package || list_package || grep_packages)
+ && keycheck)
usage (stderr, 1);
- if ((find_package || list_package) && check_setup)
+ if ((find_package || list_package || grep_packages) && check_setup)
usage (stderr, 1);
if (dump_only && !check_setup)
usage (stderr, 1);
- if (find_package && list_package)
+ if (find_package + list_package + grep_packages > 1)
usage (stderr, 1);
if (keycheck)
return check_keys ();
+ if (grep_packages)
+ return package_grep (*argv);
init_paths ();
diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc
index 62657594c..639bba5c1 100644
--- a/winsup/utils/cygpath.cc
+++ b/winsup/utils/cygpath.cc
@@ -379,6 +379,7 @@ dowin (char option)
GetWindowsDirectory (buf, MAX_PATH);
strcat (buf, "\\Profiles");
}
+fprintf (stderr, "************** buf %s\n", buf);
break;
case 'S':
diff --git a/winsup/utils/utils.sgml b/winsup/utils/utils.sgml
index b1932e53f..358b5eafa 100644
--- a/winsup/utils/utils.sgml
+++ b/winsup/utils/utils.sgml
@@ -13,19 +13,37 @@ command-line utilities support the <literal>--help</literal> and
<sect2 id="cygcheck"><title>cygcheck</title>
<screen>
-Usage: cygcheck [OPTIONS] [PROGRAM...]
-Check system information or PROGRAM library dependencies
-
- -c, --check-setup check packages installed via setup.exe
- -d, --dump-only no integrity checking of package contents (requires -c)
- -s, --sysinfo system information (not with -k)
- -v, --verbose verbose output (indented) (for -[cfls] or programs)
- -r, --registry registry search (requires -s)
- -k, --keycheck perform a keyboard check session (not with -[scfl])
- -f, --find-package find installed packages containing files (not with -[cl])
- -l, --list-package list the contents of installed packages (not with -[cf])
- -h, --help give help about the info (not with -[cfl])
- -V, --version output version information and exit
+Usage: cygcheck PROGRAM [ -v ] [ -h ]
+ cygcheck -c [ PACKAGE ... ] [ -d ]
+ cygcheck -s [ -r ] [ -v ] [ -h ]
+ cygcheck -k
+ cygcheck -f FILE [ FILE ... ]
+ cygcheck -l [ PACKAGE ... ]
+ cygcheck -p REGEXP
+List system information, check installed packages, or query package database.
+
+At least one command option or a PROGRAM is required, as shown above.
+
+ PROGRAM list library (DLL) dependencies of PROGRAM
+ -c, --check-setup show installed version of PACKAGE and verify integrity
+ (or for all installed packages if none specified)
+ -d, --dump-only just list packages, do not verify (with -c)
+ -s, --sysinfo produce diagnostic system information (implies -c -d)
+ -r, --registry also scan registry for Cygwin settings (with -s)
+ -k, --keycheck perform a keyboard check session (must be run from a
+ plain console only, not from a pty/rxvt/xterm)
+ -f, --find-package find the package that FILE belongs to
+ -l, --list-package list contents of PACKAGE (or all packages if none given)
+ -p, --package-query search for REGEXP in the entire cygwin.com package
+ repository (requies internet connectivity)
+ -v, --verbose produce more verbose output
+ -h, --help annotate output with explanatory comments when given
+ with another command, otherwise print this help
+ -V, --version print the version of cygcheck and exit
+
+Note: -c, -f, and -l only report on packages that are currently installed. To
+ search all official Cygwin packages use -p instead. The -p REGEXP matches
+ package names, descriptions, and names of files/paths within all packages.
</screen>
<para>
@@ -65,10 +83,10 @@ For example, to find out about <filename>/usr/bin/less</filename> and its
package:
<example><title>Example <command>cygcheck</command> usage</title>
<screen>
-$ cygcheck.exe -f /usr/bin/less
+$ cygcheck -f /usr/bin/less
less-381-1
-$ cygcheck.exe -l less
+$ cygcheck -l less
/usr/bin/less.exe
/usr/bin/lessecho.exe
/usr/bin/lesskey.exe
@@ -98,6 +116,65 @@ ones that have "Cygwin" in the name. If you are paranoid about
privacy, you may remove information from this report, but please keep
in mind that doing so makes it harder to diagnose your problems.</para>
+<para>In contrast to the other options that search the packages that are
+installed on your local system, the <literal>-p</literal> option can be used
+to search the entire official Cygwin package repository. It takes as argument
+a Perl-compatible regular expression which is used to match package names,
+package descriptions, and path/filenames of the contents of packages. This
+feature requires an active internet connection, since it must query the
+<literal>cygwin.com</literal> web site. In fact, it is equalivant to the
+search that is available on the <ulink url="http://cygwin.com/packages/">Cygwin
+package listing</ulink> page.</para>
+
+<para>For example, perhaps you are getting an error because you are missing a
+certain DLL and you want to know which package includes that file:
+<example><title>Searching all packages for a file</title>
+<screen>
+$ cygcheck -p 'cygintl-2\.dll'
+Found 1 matches for 'cygintl-2\.dll'.
+
+libintl2-0.12.1-3 GNU Internationalization runtime library
+
+$ cygcheck -p 'libexpat.*\.a'
+Found 2 matches for 'libexpat.*\.a'.
+
+expat-1.95.7-1 XML parser library written in C
+expat-1.95.8-1 XML parser library written in C
+
+$ cygcheck -p '/ls\.exe'
+Found 2 matches for '/ls\.exe'.
+
+coreutils-5.2.1-5 GNU core utilities (includes fileutils, sh-utils and textutils)
+coreutils-5.3.0-6 GNU core utilities (includes fileutils, sh-utils and textutils)
+</screen>
+</example>
+</para>
+
+<para>Note that this option takes a regular expression, not a glob or wildcard.
+This means that you need to use <literal>.*</literal> if you want something
+similar to the wildcard <literal>*</literal> commonly used in filename globbing.
+Similarly, to match the period character you should use <literal>\.</literal>
+since the <literal>.</literal> character in a regexp is a metacharacter that
+will match any character. Also be aware that the characters such as
+<literal>\</literal> and <literal>*</literal> are shell metacharacters, so
+they must be either escaped or quoted, as in the example above.</para>
+
+<para>The third example above illustrates that if you want to match a whole
+filename, you should include the <literal>/</literal> path seperator. In the
+given example this ensures that filenames that happen to end in
+<literal>ls.exe</literal> such as <literal>ncftpls.exe</literal> are not shown.
+Note that this use does not mean "look for packages with <literal>ls</literal>
+in the root directory," since the <literal>/</literal> can match anywhere in the
+path. It's just there to anchor the match so that it matches a full
+filename.</para>
+
+<para>By default the matching is case-sensitive. To get a case insensitive
+match, begin your regexp with <literal>(?i)</literal> which is a PCRE-specific
+feature. For complete documentation on Perl-compatible regular expression
+syntax and options, read the <command>perlre</command> manpage, or one of many
+websites such as <literal>perldoc.com</literal> that document the Perl
+language.</para>
+
<para>The <command>cygcheck</command> program should be used to send
information about your system for troubleshooting when requested.
When asked to run this command save the output so that you can email it,