3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #define cygwin_internal cygwin_internal_dontuse
23 #include "wide_path.h"
25 #include "../cygwin/include/cygwin/version.h"
26 #include "../cygwin/include/sys/cygwin.h"
27 #define _NOMNTENT_MACROS
28 #include "../cygwin/include/mntent.h"
29 #include "../cygwin/cygprops.h"
30 #undef cygwin_internal
38 #define alloca __builtin_alloca
50 int grep_packages
= 0;
51 int del_orphaned_reg
= 0;
52 int unique_object_name_opt
= 0;
54 static char emptystr
[] = "";
56 /* This is global because it's used in both internet_display_error as well
58 BOOL (WINAPI
*pInternetCloseHandle
) (HINTERNET
);
61 typedef long long longlong
;
63 typedef __int64 longlong
;
66 /* In dump_setup.cc */
67 void dump_setup (int, char **, bool);
68 void package_find (int, char **);
69 void package_list (int, char **);
71 void dump_dodgy_apps (int verbose
);
72 /* Forward declaration */
73 static void usage (FILE *, int);
75 static const char *known_env_vars
[] = {
83 "gcc_default_options",
105 static common_apps
[] = {
134 /* Options without ASCII single char representation. */
137 CO_DELETE_KEYS
= 0x100,
138 CO_ENABLE_UON
= 0x101,
139 CO_DISABLE_UON
= 0x102,
143 static int num_paths
, max_paths
;
148 void check_existence (const char *fn
, int showall
, int verbose
,
149 char* first
, const char *ext1
= "",
150 const char *ext2
= "");
154 int first_nonsys_path
;
157 eprintf (const char *format
, ...)
160 va_start (ap
, format
);
161 vfprintf (stderr
, format
, ap
);
166 * display_error() is used to report failure modes
169 display_error (const char *name
, bool show_error
, bool print_failed
)
171 fprintf (stderr
, "cygcheck: %s", name
);
173 fprintf (stderr
, "%s: %lu\n",
174 print_failed
? " failed" : "", GetLastError ());
176 fprintf (stderr
, "%s\n",
177 print_failed
? " failed" : "");
182 display_error (const char *name
)
184 return display_error (name
, true, true);
188 display_error (const char *fmt
, const char *x
)
191 snprintf (buf
, sizeof buf
, fmt
, x
);
192 return display_error (buf
, false, false);
196 display_error_fmt (const char *fmt
, ...)
202 vsnprintf (buf
, sizeof buf
, fmt
, va
);
203 return display_error (buf
, false, false);
206 /* Display a WinInet error message, and close a variable number of handles.
207 (Passed a list of handles terminated by NULL.) */
209 display_internet_error (const char *message
, ...)
211 DWORD err
= GetLastError ();
216 /* in the case of a successful connection but 404 response, there is no
217 win32 error message, but we still get passed a message to display. */
220 if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE
,
221 GetModuleHandle ("wininet.dll"), err
, 0, err_buf
,
222 sizeof (err_buf
), NULL
) == 0)
223 strcpy (err_buf
, "(Unknown error)");
225 fprintf (stderr
, "cygcheck: %s: %s (win32 error %lu)\n", message
,
229 fprintf (stderr
, "cygcheck: %s\n", message
);
231 va_start (hptr
, message
);
232 while ((h
= va_arg (hptr
, HINTERNET
)) != 0)
233 pInternetCloseHandle (h
);
240 add_path (char *s
, int maxlen
, bool issys
)
242 if (num_paths
>= max_paths
)
245 /* Extend path array */
246 paths
= (pathlike
*) realloc (paths
, (1 + max_paths
) * sizeof (paths
[0]));
249 pathlike
*pth
= paths
+ num_paths
;
251 /* Allocate space for directory in path list */
252 char *dir
= (char *) calloc (maxlen
+ 2, sizeof (char));
255 display_error ("add_path: calloc() failed");
259 /* Copy input directory to path list */
260 memcpy (dir
, s
, maxlen
);
262 /* Add a trailing slash by default */
263 char *e
= strchr (dir
, '\0');
264 if (e
!= dir
&& e
[-1] != '\\')
267 /* Fill out this element */
278 add_path ((char *) ".", 1, true); /* to be replaced later */
280 if (GetCurrentDirectory (4000, tmp
))
281 add_path (tmp
, strlen (tmp
), true);
283 display_error ("init_paths: GetCurrentDirectory()");
285 if (GetSystemDirectory (tmp
, 4000))
286 add_path (tmp
, strlen (tmp
), true);
288 display_error ("init_paths: GetSystemDirectory()");
289 sl
= strrchr (tmp
, '\\');
292 strcpy (sl
, "\\SYSTEM");
293 add_path (tmp
, strlen (tmp
), true);
295 GetWindowsDirectory (tmp
, 4000);
296 add_path (tmp
, strlen (tmp
), true);
298 char *wpath
= getenv ("PATH");
300 display_error ("WARNING: PATH is not set\n", "");
307 for (e
= b
; *e
&& *e
!= ';'; e
++)
308 continue; /* loop terminates at first ';' or EOS */
309 if (strncmp(b
, ".\\", 2) != 0)
310 add_path (b
, e
- b
, false);
318 #define LINK_EXTENSION ".lnk"
321 pathlike::check_existence (const char *fn
, int showall
, int verbose
,
322 char* first
, const char *ext1
, const char *ext2
)
330 wide_path
wpath (file
);
331 if (GetFileAttributesW (wpath
) != (DWORD
) - 1)
333 char *lastdot
= strrchr (file
, '.');
334 bool is_link
= lastdot
&& !strcmp (lastdot
, LINK_EXTENSION
);
335 // If file is a link, fix up the extension before printing
339 printf ("Found: %s\n", file
);
340 if (verbose
&& *first
!= '\0' && strcasecmp (first
, file
) != 0)
342 char *flastdot
= strrchr (first
, '.');
343 bool f_is_link
= flastdot
&& !strcmp (flastdot
, LINK_EXTENSION
);
344 // if first is a link, fix up the extension before printing
347 printf ("Warning: %s hides %s\n", first
, file
);
354 strcpy (first
, file
);
359 find_on_path (const char *in_file
, const char *ext
, bool showall
= false,
360 bool search_sys
= false, bool checklinks
= false)
362 static char rv
[4000];
364 /* Sort of a kludge but we've already tested this once, so don't try it again */
368 static pathlike abspath
[2] =
377 display_error ("internal error find_on_path: NULL pointer for file", false, false);
383 display_error ("internal error find_on_path: NULL pointer for default_extension", false, false);
388 pathlike
*search_paths
;
389 if (!strpbrk (in_file
, ":/\\"))
392 search_paths
= paths
;
396 file
= cygpath (in_file
, NULL
);
397 search_paths
= abspath
;
403 display_error ("internal error find_on_path: cygpath conversion failed for %s\n", in_file
);
407 char *hasext
= strrchr (file
, '.');
408 if (hasext
&& !strpbrk (hasext
, "/\\"))
411 for (pathlike
*pth
= search_paths
; pth
->dir
; pth
++)
412 if (!pth
->issys
|| search_sys
)
414 pth
->check_existence (file
, showall
, verbose
, rv
, ext
);
417 pth
->check_existence (file
, showall
, verbose
, rv
, ext
, LINK_EXTENSION
);
422 pth
->check_existence (file
, showall
, verbose
, rv
);
424 pth
->check_existence (file
, showall
, verbose
, rv
, LINK_EXTENSION
);
427 return *rv
? rv
: NULL
;
432 #define DID_INACTIVE 3
443 already_did (const char *file
)
446 for (d
= did
; d
; d
= d
->next
)
447 if (strcasecmp (d
->file
, file
) == 0)
449 d
= (Did
*) malloc (sizeof (Did
));
450 d
->file
= strdup (file
);
462 int size_of_raw_data
;
463 int pointer_to_raw_data
;
467 rva_to_offset (int rva
, char *sections
, int nsections
, int *sz
)
471 if (sections
== NULL
)
473 display_error ("rva_to_offset: NULL passed for sections", true, false);
477 for (i
= 0; i
< nsections
; i
++)
479 Section
*s
= (Section
*) (sections
+ i
* 40);
481 printf ("%08x < %08x < %08x ? %08x\n",
482 s
->virtual_address
, rva
,
483 s
->virtual_address
+ s
->virtual_size
, s
->pointer_to_raw_data
);
485 if (rva
>= s
->virtual_address
486 && rva
< s
->virtual_address
+ s
->virtual_size
)
489 *sz
= s
->virtual_address
+ s
->virtual_size
- rva
;
490 return rva
- s
->virtual_address
+ s
->pointer_to_raw_data
;
507 unsigned characteristics
;
509 unsigned forwarder_chain
;
514 static bool track_down (const char *file
, const char *suffix
, int lvl
);
516 #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
518 cygwin_info (HANDLE h
)
520 char *buf
, *bufend
, *buf_start
= NULL
;
521 const char *hello
= " Cygwin DLL version info:\n";
522 DWORD size
= GetFileSize (h
, NULL
);
525 if (size
== 0xffffffff)
528 buf_start
= buf
= (char *) calloc (1, size
+ 1);
531 display_error ("cygwin_info: calloc()");
535 (void) SetFilePointer (h
, 0, NULL
, FILE_BEGIN
);
536 if (!ReadFile (h
, buf
, size
, &n
, NULL
))
542 static char dummy
[] = "\0\0\0\0\0\0\0";
543 char *dll_major
= dummy
;
546 if ((buf
= (char *) memchr (buf
, '%', bufend
- buf
)) == NULL
)
548 else if (strncmp ("%%% Cygwin ", buf
, CYGPREFIX
) != 0)
552 char *p
= strchr (buf
+= CYGPREFIX
, '\n');
555 if (strncasecmp (buf
, "dll major:", 10) == 0)
557 dll_major
= buf
+ 11;
563 if (strncasecmp (buf
, "dll minor:", 10) != 0)
567 char c
= dll_major
[1];
569 int maj
= atoi (dll_major
);
571 int min
= atoi (dll_major
+ 1);
572 sprintf (pbuf
, "DLL version: %d.%d.%.*s", maj
, min
, len
- 11,
574 len
= strlen (s
= pbuf
);
576 if (strncmp (s
, "dll", 3) == 0)
577 memcpy (s
, "DLL", 3);
578 else if (strncmp (s
, "api", 3) == 0)
579 memcpy (s
, "API", 3);
580 else if (islower (*s
))
582 fprintf (stdout
, "%s %.*s", hello
, len
, s
);
594 dll_info (const char *path
, HANDLE fh
, int lvl
, int recurse
)
598 int pe_header_offset
= get_dword (fh
, 0x3c);
599 if (GetLastError () != NO_ERROR
)
600 display_error ("get_dword");
601 WORD arch
= get_word (fh
, pe_header_offset
+ 4);
602 if (GetLastError () != NO_ERROR
)
603 display_error ("get_word");
605 if (arch
!= IMAGE_FILE_MACHINE_AMD64
)
607 fputc ('\n', stderr
);
608 display_error ("Wrong architecture. Only x86_64 executables supported.",
614 if (arch
!= IMAGE_FILE_MACHINE_I386
)
616 fputc ('\n', stderr
);
617 display_error ("Wrong architecture. Only ix86 executables supported.",
623 int opthdr_ofs
= pe_header_offset
+ 4 + 20;
628 display_error ("dll_info: NULL passed for path", true, false);
632 if (SetFilePointer (fh
, opthdr_ofs
+ 40, 0, FILE_BEGIN
) ==
633 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
634 display_error ("dll_info: SetFilePointer()");
636 if (!ReadFile (fh
, &v
, sizeof (v
), &junk
, 0))
637 display_error ("dll_info: Readfile()");
640 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
641 v
[0], v
[1], v
[2], v
[3], v
[4], v
[5]);
645 int num_entries
= get_dword (fh
, opthdr_ofs
+ base_off
+ 0);
646 if (GetLastError () != NO_ERROR
)
647 display_error ("get_dword");
648 int export_rva
= get_dword (fh
, opthdr_ofs
+ base_off
+ 4);
649 if (GetLastError () != NO_ERROR
)
650 display_error ("get_dword");
651 int export_size
= get_dword (fh
, opthdr_ofs
+ base_off
+ 8);
652 if (GetLastError () != NO_ERROR
)
653 display_error ("get_dword");
654 int import_rva
= get_dword (fh
, opthdr_ofs
+ base_off
+ 12);
655 if (GetLastError () != NO_ERROR
)
656 display_error ("get_dword");
657 int import_size
= get_dword (fh
, opthdr_ofs
+ base_off
+ 16);
658 if (GetLastError () != NO_ERROR
)
659 display_error ("get_dword");
661 int nsections
= get_word (fh
, pe_header_offset
+ 4 + 2);
663 display_error ("get_word");
664 char *sections
= (char *) malloc (nsections
* 40);
666 if (SetFilePointer (fh
, pe_header_offset
+ 4 + 20 +
667 get_word (fh
, pe_header_offset
+ 4 + 16), 0,
668 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
669 && GetLastError () != NO_ERROR
)
670 display_error ("dll_info: SetFilePointer()");
672 if (!ReadFile (fh
, sections
, nsections
* 40, &junk
, 0))
673 display_error ("dll_info: Readfile()");
675 if (verbose
&& num_entries
>= 1 && export_size
> 0)
678 int expbase
= rva_to_offset (export_rva
, sections
, nsections
, &expsz
);
682 if (SetFilePointer (fh
, expbase
, 0, FILE_BEGIN
) ==
683 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
684 display_error ("dll_info: SetFilePointer()");
686 unsigned char *exp
= (unsigned char *) malloc (expsz
);
688 if (!ReadFile (fh
, exp
, expsz
, &junk
, 0))
689 display_error ("dll_info: Readfile()");
691 ExpDirectory
*ed
= (ExpDirectory
*) exp
;
692 int ofs
= ed
->name_rva
- export_rva
;
693 time_t ts
= ed
->timestamp
; /* timestamp is only 4 bytes! */
694 struct tm
*tm
= localtime (&ts
);
695 if (tm
&& tm
->tm_year
< 60)
697 if (tm
&& tm
->tm_year
< 200)
699 printf ("%*c", lvl
+ 2, ' ');
700 printf ("\"%s\" v%d.%d", exp
+ ofs
,
701 ed
->major_ver
, ed
->minor_ver
);
703 printf (" ts=%04d-%02d-%02d %02d:%02d",
704 tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
,
705 tm
->tm_hour
, tm
->tm_min
);
710 if (num_entries
>= 2 && import_size
> 0 && recurse
)
713 int impbase
= rva_to_offset (import_rva
, sections
, nsections
, &impsz
);
716 if (SetFilePointer (fh
, impbase
, 0, FILE_BEGIN
) ==
717 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
718 display_error ("dll_info: SetFilePointer()");
720 unsigned char *imp
= (unsigned char *) malloc (impsz
);
723 display_error ("dll_info: malloc()");
727 if (!ReadFile (fh
, imp
, impsz
, &junk
, 0))
728 display_error ("dll_info: Readfile()");
730 ImpDirectory
*id
= (ImpDirectory
*) imp
;
731 for (i
= 0; id
[i
].name_rva
; i
++)
733 /* int ofs = id[i].name_rva - import_rva; */
734 track_down ((char *) imp
+ id
[i
].name_rva
- import_rva
,
735 (char *) ".dll", lvl
+ 2);
739 if (strstr (path
, "\\cygwin1.dll"))
743 // Return true on success, false if error printed
745 track_down (const char *file
, const char *suffix
, int lvl
)
749 display_error ("track_down: NULL passed for file", true, false);
755 display_error ("track_down: NULL passed for suffix", false, false);
759 const char *path
= find_on_path (file
, suffix
, false, true);
762 display_error ("track_down: could not find %s\n", file
);
766 Did
*d
= already_did (file
);
775 printf ("%*c", lvl
, ' ');
777 printf (" (recursive)\n");
784 printf ("%*c", lvl
, ' ');
786 printf (" (already done)\n");
794 printf ("%*c", lvl
, ' ');
798 display_error ("file not found - '%s'\n", file
);
804 wide_path
wpath (path
);
806 CreateFileW (wpath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
807 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
808 if (fh
== INVALID_HANDLE_VALUE
)
810 display_error ("cannot open - '%s'\n", path
);
814 d
->state
= DID_ACTIVE
;
817 dll_info (path
, fh
, lvl
, 1);
818 else if (is_symlink (fh
))
819 display_error ("%s is a symlink instead of a DLL\n", path
);
822 int magic
= get_word (fh
, 0x0);
824 display_error ("get_word");
826 display_error_fmt ("%s is not a DLL: magic number %x (%d) '%s'\n",
827 path
, magic
, magic
, (char *)&magic
);
830 d
->state
= DID_INACTIVE
;
831 if (!CloseHandle (fh
))
832 display_error ("track_down: CloseHandle()");
840 HANDLE h
= CreateFileW (wpath
, GENERIC_READ
,
841 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
842 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
843 BY_HANDLE_FILE_INFORMATION info
;
845 if (!GetFileInformationByHandle (h
, &info
))
846 display_error ("ls: GetFileInformationByHandle()");
850 if (!FileTimeToSystemTime (&info
.ftLastWriteTime
, &systime
))
851 display_error ("ls: FileTimeToSystemTime()");
852 printf ("%5dk %04d/%02d/%02d %s",
853 (((int) info
.nFileSizeLow
) + 512) / 1024,
854 systime
.wYear
, systime
.wMonth
, systime
.wDay
, f
);
855 dll_info (f
, h
, 16, 0);
856 if (!CloseHandle (h
))
857 display_error ("ls: CloseHandle()");
860 /* Remove filename from 's' and return directory name without trailing
861 backslash, or NULL if 's' doesn't seem to have a dirname. */
863 dirname (const char *s
)
865 static char buf
[PATH_MAX
];
870 strncpy (buf
, s
, PATH_MAX
);
871 buf
[PATH_MAX
- 1] = '\0'; // in case strlen(s) > PATH_MAX
872 char *lastsep
= strrchr (buf
, '\\');
874 return NULL
; // no backslash -> no dirname
875 else if (lastsep
- buf
<= 2 && buf
[1] == ':')
876 lastsep
[1] = '\0'; // can't remove backslash of "x:\"
882 // Find a real application on the path (possibly following symlinks)
884 find_app_on_path (const char *app
, bool showall
= false)
886 const char *papp
= find_on_path (app
, ".exe", showall
, false, true);
891 wide_path
wpath (papp
);
893 CreateFileW (wpath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
894 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
895 if (fh
== INVALID_HANDLE_VALUE
)
900 static char tmp
[SYMLINK_MAX
+ 1];
901 if (!readlink (fh
, tmp
, SYMLINK_MAX
))
902 display_error("readlink failed");
904 /* Resolve the linkname relative to the directory of the link. */
905 char *ptr
= cygpath_rel (dirname (papp
), tmp
, NULL
);
906 printf (" -> %s\n", ptr
);
907 if (!strchr (ptr
, '\\'))
910 strncpy (tmp
, cygpath (papp
, NULL
), SYMLINK_MAX
);
911 lastsep
= strrchr (tmp
, '\\');
912 strncpy (lastsep
+1, ptr
, SYMLINK_MAX
- (lastsep
-tmp
));
915 if (!CloseHandle (fh
))
916 display_error ("find_app_on_path: CloseHandle()");
917 /* FIXME: We leak the ptr returned by cygpath() here which is a
919 return find_app_on_path (ptr
, showall
);
922 if (!CloseHandle (fh
))
923 display_error ("find_app_on_path: CloseHandle()");
927 // Return true on success, false if error printed
929 cygcheck (const char *app
)
931 const char *papp
= find_app_on_path (app
, 1);
934 display_error ("could not find '%s'\n", app
);
939 char *sep
= strpbrk (papp
, ":/\\");
942 static char dot
[] = ".";
948 s
= (char *) malloc (n
+ 2);
949 memcpy ((char *) s
, papp
, n
);
950 strcpy (s
+ n
, "\\");
955 return track_down (papp
, ".exe", 0);
966 show_reg (RegInfo
* ri
, int nest
)
970 show_reg (ri
->prev
, 1);
972 printf ("%s\\", ri
->name
);
974 printf ("%s\n", ri
->name
);
978 scan_registry (RegInfo
* prev
, HKEY hKey
, char *name
, int cygwin
, bool wow64
)
986 for (cp
= name
; *cp
; cp
++)
987 if (strncasecmp (cp
, "Cygwin", 6) == 0)
990 DWORD num_subkeys
, max_subkey_len
, num_values
;
991 DWORD max_value_len
, max_valdata_len
, i
;
992 if (RegQueryInfoKey (hKey
, 0, 0, 0, &num_subkeys
, &max_subkey_len
, 0,
993 &num_values
, &max_value_len
, &max_valdata_len
, 0, 0)
998 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, 0, GetLastError (),
999 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
), tmp
, 400, 0);
1000 printf ("RegQueryInfoKey: %s\n", tmp
);
1009 char *value_name
= (char *) malloc (max_value_len
+ 1);
1010 if (value_name
== NULL
)
1012 display_error ("scan_registry: malloc()");
1016 char *value_data
= (char *) malloc (max_valdata_len
+ 1);
1017 if (value_data
== NULL
)
1019 display_error ("scan_registry: malloc()");
1023 for (i
= 0; i
< num_values
; i
++)
1025 DWORD dlen
= max_valdata_len
+ 1;
1026 DWORD nlen
= max_value_len
+ 1;
1028 RegEnumValue (hKey
, i
, value_name
, &nlen
, 0,
1029 &type
, (BYTE
*) value_data
, &dlen
);
1031 printf (" %s = ", i
? value_name
: "(default)");
1035 printf ("0x%08x\n", *(unsigned *) value_data
);
1039 printf ("'%s'\n", value_data
);
1042 printf ("(unsupported type)\n");
1051 char *subkey_name
= (char *) malloc (max_subkey_len
+ 1);
1052 for (i
= 0; i
< num_subkeys
; i
++)
1054 if (RegEnumKey (hKey
, i
, subkey_name
, max_subkey_len
+ 1) ==
1058 /* Don't recurse more than one level into the WOW64 subkey since
1059 that would lead to an endless recursion. */
1060 if (!strcasecmp (subkey_name
, "Wow6432Node"))
1066 if (RegOpenKeyEx (hKey
, subkey_name
, 0, KEY_READ
, &sKey
)
1069 scan_registry (&ri
, sKey
, subkey_name
, cygwin
, wow64
);
1070 if (RegCloseKey (sKey
) != ERROR_SUCCESS
)
1071 display_error ("scan_registry: RegCloseKey()");
1081 char *groups
[16384];
1083 char *id
= cygpath ("/bin/id.exe", NULL
);
1084 for (char *p
= id
; (p
= strchr (p
, '/')); p
++)
1087 if (access (id
, X_OK
))
1089 fprintf (stderr
, "'id' program not found\n");
1094 snprintf (buf
, sizeof (buf
), "\"%s\"", id
);
1095 FILE *f
= popen (buf
, "rt");
1098 fgets (buf
, sizeof (buf
), f
);
1100 char *uid
= strtok (buf
, ")");
1102 uid
+= strlen ("uid=");
1105 fprintf (stderr
, "garbled output from 'id' command - no uid= found\n");
1108 char *gid
= strtok (NULL
, ")");
1110 gid
+= strlen ("gid=") + 1;
1113 fprintf (stderr
, "garbled output from 'id' command - no gid= found\n");
1117 char **ng
= groups
- 1;
1118 size_t len_uid
= strlen ("UID: )") + strlen (uid
);
1119 size_t len_gid
= strlen ("GID: )") + strlen (gid
);
1120 *++ng
= groups
[0] = (char *) alloca (len_uid
+ 1);
1121 *++ng
= groups
[1] = (char *) alloca (len_gid
+ 1);
1122 sprintf (groups
[0], "UID: %s)", uid
);
1123 sprintf (groups
[1], "GID: %s)", gid
);
1124 size_t sz
= max (len_uid
, len_gid
);
1125 while ((*++ng
= strtok (NULL
, ",")))
1127 char *p
= strchr (*ng
, '\n');
1130 if (ng
== groups
+ 2)
1131 *ng
+= strlen (" groups=");
1132 size_t len
= strlen (*ng
);
1138 printf ("\nOutput from %s\n", id
);
1139 int n
= 80 / (int) ++sz
;
1140 int i
= n
> 2 ? n
- 2 : 0;
1142 for (char **g
= groups
; g
<= ng
; g
++)
1143 if ((g
!= ng
) && (++i
< n
))
1144 printf ("%*s", (int) sz
, *g
);
1152 /* This dumps information about each installed cygwin service, if cygrunsrv
1155 dump_sysinfo_services ()
1160 bool no_services
= false;
1163 printf ("\nChecking for any Cygwin services... %s\n\n",
1164 verbose
? "" : "(use -v for more detail)");
1166 fputc ('\n', stdout
);
1168 /* find the location of cygrunsrv.exe */
1169 char *cygrunsrv
= cygpath ("/bin/cygrunsrv.exe", NULL
);
1170 for (char *p
= cygrunsrv
; (p
= strchr (p
, '/')); p
++)
1173 if (access (cygrunsrv
, X_OK
))
1175 puts ("Can't find the cygrunsrv utility, skipping services check.\n");
1179 /* check for a recent cygrunsrv */
1180 snprintf (buf
, sizeof (buf
), "\"%s\" --version", cygrunsrv
);
1181 if ((f
= popen (buf
, "rt")) == NULL
)
1183 printf ("Failed to execute '%s', skipping services check.\n", buf
);
1187 int ret
= fscanf (f
, "cygrunsrv V%u.%u", &maj
, &min
);
1188 if (ferror (f
) || feof (f
) || ret
== EOF
|| maj
< 1 || min
< 10)
1190 puts ("The version of cygrunsrv installed is too old to dump service info.\n");
1195 /* For verbose mode, just run cygrunsrv --list --verbose and copy output
1196 verbatim; otherwise run cygrunsrv --list and then cygrunsrv --query for
1198 snprintf (buf
, sizeof (buf
), (verbose
? "\"%s\" --list --verbose" : "\"%s\" --list"),
1200 if ((f
= popen (buf
, "rt")) == NULL
)
1202 printf ("Failed to execute '%s', skipping services check.\n", buf
);
1208 /* copy output to stdout */
1210 while (!feof (f
) && !ferror (f
))
1211 nchars
+= fwrite ((void *) buf
, 1,
1212 fread ((void *) buf
, 1, sizeof (buf
), f
), stdout
);
1214 /* cygrunsrv outputs nothing if there are no cygwin services found */
1221 /* read the output of --list, and then run --query for each service */
1222 size_t nchars
= fread ((void *) buf
, 1, sizeof (buf
) - 1, f
);
1227 for (char *srv
= strtok (buf
, "\n"); srv
; srv
= strtok (NULL
, "\n"))
1229 snprintf (buf2
, sizeof (buf2
), "\"%s\" --query %s", cygrunsrv
, srv
);
1230 if ((f
= popen (buf2
, "rt")) == NULL
)
1232 printf ("Failed to execute '%s', skipping services check.\n", buf2
);
1236 /* copy output to stdout */
1237 while (!feof (f
) && !ferror (f
))
1238 fwrite ((void *) buf2
, 1,
1239 fread ((void *) buf2
, 1, sizeof (buf2
), f
), stdout
);
1246 /* inform the user if nothing found */
1248 puts ("No Cygwin services found.\n");
1258 handle_reg_installation (handle_reg_t what
)
1262 if (what
== PRINT_KEY
)
1263 printf ("Cygwin installations found in the registry:\n");
1264 for (int i
= 0; i
< 2; ++i
)
1265 if (RegOpenKeyEx (i
? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,
1266 "SOFTWARE\\Cygwin\\Installations", 0,
1267 what
== DELETE_KEY
? KEY_READ
| KEY_WRITE
: KEY_READ
,
1271 char name
[32], data
[PATH_MAX
];
1272 DWORD nsize
, dsize
, type
;
1275 for (DWORD index
= 0;
1276 (ret
= RegEnumValue (key
, index
, name
, (nsize
= 32, &nsize
), 0,
1277 &type
, (PBYTE
) data
,
1278 (dsize
= PATH_MAX
, &dsize
)))
1279 != ERROR_NO_MORE_ITEMS
; ++index
)
1280 if (ret
== ERROR_SUCCESS
&& dsize
> 5)
1282 char *path
= data
+ 4;
1284 *(path
+= 2) = '\\';
1285 if (what
== PRINT_KEY
)
1286 printf (" %s Key: %s Path: %s", i
? "User: " : "System:",
1288 strcat (path
, "\\bin\\cygwin1.dll");
1289 if (what
== PRINT_KEY
)
1290 printf ("%s\n", access (path
, F_OK
) ? " (ORPHANED)" : "");
1291 else if (access (path
, F_OK
))
1293 RegDeleteValue (key
, name
);
1294 /* Start over since index is not reliable anymore. */
1301 if (what
== PRINT_KEY
)
1306 print_reg_installations ()
1308 handle_reg_installation (PRINT_KEY
);
1312 del_orphaned_reg_installations ()
1314 handle_reg_installation (DELETE_KEY
);
1317 /* Unfortunately neither mingw nor Windows know this function. */
1319 memmem (char *haystack
, size_t haystacklen
,
1320 const char *needle
, size_t needlelen
)
1324 while (needlelen
<= haystacklen
)
1326 if (!memcmp (haystack
, needle
, needlelen
))
1335 handle_unique_object_name (int opt
, char *path
)
1338 void *haystack
= NULL
;
1340 if (!path
|| !*path
)
1343 DWORD access
, share
, protect
, mapping
;
1345 if (opt
== CO_SHOW_UON
)
1347 access
= GENERIC_READ
;
1348 share
= FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
1349 protect
= PAGE_READONLY
;
1350 mapping
= FILE_MAP_READ
;
1354 access
= GENERIC_READ
| GENERIC_WRITE
;
1356 protect
= PAGE_READWRITE
;
1357 mapping
= FILE_MAP_WRITE
;
1360 fh
= CreateFile (path
, access
, share
, NULL
, OPEN_EXISTING
,
1361 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
1362 if (fh
== INVALID_HANDLE_VALUE
)
1364 DWORD err
= GetLastError ();
1367 case ERROR_SHARING_VIOLATION
:
1368 display_error ("%s still used by other Cygwin processes.\n"
1369 "Please stop all of them and retry.", path
);
1371 case ERROR_ACCESS_DENIED
:
1373 "Your permissions are not sufficient to change the file \"%s\"",
1376 case ERROR_FILE_NOT_FOUND
:
1377 display_error ("%s: No such file.", path
);
1380 display_error (path
, true, false);
1385 if (!(fm
= CreateFileMapping (fh
, NULL
, protect
, 0, 0, NULL
)))
1386 display_error ("CreateFileMapping");
1387 else if (!(haystack
= MapViewOfFile (fm
, mapping
, 0, 0, 0)))
1388 display_error ("MapViewOfFile");
1391 size_t haystacklen
= GetFileSize (fh
, NULL
);
1392 cygwin_props_t
*cygwin_props
= (cygwin_props_t
*)
1393 memmem ((char *) haystack
, haystacklen
,
1394 CYGWIN_PROPS_MAGIC
, sizeof (CYGWIN_PROPS_MAGIC
));
1396 display_error ("Can't find Cygwin properties in %s", path
);
1399 if (opt
!= CO_SHOW_UON
)
1400 cygwin_props
->disable_key
= opt
- CO_ENABLE_UON
;
1401 printf ("Unique object names are %s\n",
1402 cygwin_props
->disable_key
? "disabled" : "enabled");
1403 UnmapViewOfFile (haystack
);
1410 UnmapViewOfFile (haystack
);
1423 char *found_cygwin_dll
;
1425 bool more_info
= true;
1427 DWORD obcaseinsensitive
= 1;
1430 printf ("\nCygwin Configuration Diagnostics\n");
1432 printf ("Current System Time: %s\n", ctime (&now
));
1434 OSVERSIONINFOEX osversion
;
1435 osversion
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFOEX
);
1436 if (!GetVersionEx (reinterpret_cast<LPOSVERSIONINFO
>(&osversion
)))
1439 osversion
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
1440 if (!GetVersionEx (reinterpret_cast<LPOSVERSIONINFO
>(&osversion
)))
1441 display_error ("dump_sysinfo: GetVersionEx()");
1444 HMODULE k32
= GetModuleHandleW (L
"kernel32.dll");
1446 switch (osversion
.dwPlatformId
)
1448 case VER_PLATFORM_WIN32s
:
1449 strcpy (osname
, "32s (not supported)");
1451 case VER_PLATFORM_WIN32_WINDOWS
:
1452 strcpy (osname
, "95/98/Me (not supported)");
1454 case VER_PLATFORM_WIN32_NT
:
1456 if (osversion
.dwMajorVersion
== 6)
1458 BOOL (WINAPI
*GetProductInfo
) (DWORD
, DWORD
, DWORD
, DWORD
, PDWORD
) =
1459 (BOOL (WINAPI
*)(DWORD
, DWORD
, DWORD
, DWORD
, PDWORD
))
1460 GetProcAddress (k32
, "GetProductInfo");
1461 switch (osversion
.dwMinorVersion
)
1464 strcpy (osname
, osversion
.wProductType
== VER_NT_WORKSTATION
1465 ? "Vista" : "2008");
1468 strcpy (osname
, osversion
.wProductType
== VER_NT_WORKSTATION
1472 strcpy (osname
, osversion
.wProductType
== VER_NT_WORKSTATION
1477 if (GetProductInfo (osversion
.dwMajorVersion
,
1478 osversion
.dwMinorVersion
,
1479 osversion
.wServicePackMajor
,
1480 osversion
.wServicePackMinor
,
1483 #define PRODUCT_UNLICENSED 0xabcdabcd
1484 #ifndef PRODUCT_PROFESSIONAL_WMC
1485 #define PRODUCT_PROFESSIONAL_WMC 0x00000067
1487 const char *products
[] =
1489 /* 0x00000000 */ "",
1490 /* 0x00000001 */ " Ultimate",
1491 /* 0x00000002 */ " Home Basic",
1492 /* 0x00000003 */ " Home Premium",
1493 /* 0x00000004 */ " Enterprise",
1494 /* 0x00000005 */ " Home Basic N",
1495 /* 0x00000006 */ " Business",
1496 /* 0x00000007 */ " Server Standard",
1497 /* 0x00000008 */ " Server Datacenter",
1498 /* 0x00000009 */ " Small Business Server",
1499 /* 0x0000000a */ " Server Enterprise",
1500 /* 0x0000000b */ " Starter",
1501 /* 0x0000000c */ " Server Datacenter Core",
1502 /* 0x0000000d */ " Server Standard Core",
1503 /* 0x0000000e */ " Server Enterprise Core",
1504 /* 0x0000000f */ " Server Enterprise for Itanium-based Systems",
1505 /* 0x00000010 */ " Business N",
1506 /* 0x00000011 */ " Web Server",
1507 /* 0x00000012 */ " HPC Edition",
1508 /* 0x00000013 */ " Home Server",
1509 /* 0x00000014 */ " Storage Server Express",
1510 /* 0x00000015 */ " Storage Server Standard",
1511 /* 0x00000016 */ " Storage Server Workgroup",
1512 /* 0x00000017 */ " Storage Server Enterprise",
1513 /* 0x00000018 */ " for Windows Essential Server Solutions",
1514 /* 0x00000019 */ " Small Business Server Premium",
1515 /* 0x0000001a */ " Home Premium N",
1516 /* 0x0000001b */ " Enterprise N",
1517 /* 0x0000001c */ " Ultimate N",
1518 /* 0x0000001d */ " Web Server Core",
1519 /* 0x0000001e */ " Essential Business Server Management Server",
1520 /* 0x0000001f */ " Essential Business Server Security Server"
1521 /* 0x00000020 */ " Essential Business Server Messaging Server",
1522 /* 0x00000021 */ " Server Foundation",
1523 /* 0x00000022 */ " Home Server 2011",
1524 /* 0x00000023 */ " without Hyper-V for Windows Essential Server Solutions",
1525 /* 0x00000024 */ " Server Standard without Hyper-V",
1526 /* 0x00000025 */ " Server Datacenter without Hyper-V",
1527 /* 0x00000026 */ " Server Enterprise without Hyper-V",
1528 /* 0x00000027 */ " Server Datacenter Core without Hyper-V",
1529 /* 0x00000028 */ " Server Standard Core without Hyper-V",
1530 /* 0x00000029 */ " Server Enterprise Core without Hyper-V",
1531 /* 0x0000002a */ " Hyper-V Server",
1532 /* 0x0000002b */ " Storage Server Express Core",
1533 /* 0x0000002c */ " Storage Server Standard Core",
1534 /* 0x0000002d */ " Storage Server Workgroup Core",
1535 /* 0x0000002e */ " Storage Server Enterprise Core",
1536 /* 0x0000002f */ " Starter N",
1537 /* 0x00000030 */ " Professional",
1538 /* 0x00000031 */ " Professional N",
1539 /* 0x00000032 */ " Small Business Server 2011 Essentials"
1540 /* 0x00000033 */ " Server For SB Solutions",
1541 /* 0x00000034 */ " Server Solutions Premium",
1542 /* 0x00000035 */ " Server Solutions Premium Core",
1543 /* 0x00000036 */ " Server For SB Solutions EM", /* per MSDN, 2012-09-01 */
1544 /* 0x00000037 */ " Server For SB Solutions EM", /* per MSDN, 2012-09-01 */
1545 /* 0x00000038 */ " Multipoint Server",
1546 /* 0x00000039 */ "",
1547 /* 0x0000003a */ "",
1548 /* 0x0000003b */ " Essential Server Solution Management",
1549 /* 0x0000003c */ " Essential Server Solution Additional",
1550 /* 0x0000003d */ " Essential Server Solution Management SVC",
1551 /* 0x0000003e */ " Essential Server Solution Additional SVC",
1552 /* 0x0000003f */ " Small Business Server Premium Core",
1553 /* 0x00000040 */ " Server Hyper Core V",
1554 /* 0x00000041 */ "",
1555 /* 0x00000042 */ " Starter E",
1556 /* 0x00000043 */ " Home Basic E",
1557 /* 0x00000044 */ " Home Premium E",
1558 /* 0x00000045 */ " Professional E",
1559 /* 0x00000046 */ " Enterprise E",
1560 /* 0x00000047 */ " Ultimate E"
1561 /* 0x00000048 */ " Server Enterprise (Evaluation inst.)",
1562 /* 0x00000049 */ "",
1563 /* 0x0000004a */ "",
1564 /* 0x0000004b */ "",
1565 /* 0x0000004c */ " MultiPoint Server Standard",
1566 /* 0x0000004d */ " MultiPoint Server Premium",
1567 /* 0x0000004e */ "",
1568 /* 0x0000004f */ " Server Standard (Evaluation inst.)",
1569 /* 0x00000050 */ " Server Datacenter (Evaluation inst.)",
1570 /* 0x00000051 */ "",
1571 /* 0x00000052 */ "",
1572 /* 0x00000053 */ "",
1573 /* 0x00000054 */ " Enterprise N (Evaluation inst.)",
1574 /* 0x00000055 */ "",
1575 /* 0x00000056 */ "",
1576 /* 0x00000057 */ "",
1577 /* 0x00000058 */ "",
1578 /* 0x00000059 */ "",
1579 /* 0x0000005a */ "",
1580 /* 0x0000005b */ "",
1581 /* 0x0000005c */ "",
1582 /* 0x0000005d */ "",
1583 /* 0x0000005e */ "",
1584 /* 0x0000005f */ " Storage Server Workgroup (Evaluation inst.)",
1585 /* 0x00000060 */ " Storage Server Standard (Evaluation inst.)",
1586 /* 0x00000061 */ "",
1587 /* 0x00000062 */ " N", /* "8 N" */
1588 /* 0x00000063 */ " China", /* "8 China" */
1589 /* 0x00000064 */ " Single Language", /* "8 Single Language" */
1590 /* 0x00000065 */ "", /* "8" */
1591 /* 0x00000066 */ "",
1592 /* 0x00000067 */ " Professional with Media Center"
1594 if (prod
== PRODUCT_UNLICENSED
)
1595 strcat (osname
, "Unlicensed");
1596 else if (prod
> PRODUCT_PROFESSIONAL_WMC
)
1597 strcat (osname
, "");
1599 strcat (osname
, products
[prod
]);
1605 else if (osversion
.dwMajorVersion
== 5)
1607 if (osversion
.dwMinorVersion
== 0)
1609 strcpy (osname
, "2000");
1610 if (osversion
.wProductType
== VER_NT_WORKSTATION
)
1611 strcat (osname
, " Professional");
1612 else if (osversion
.wSuiteMask
& VER_SUITE_DATACENTER
)
1613 strcat (osname
, " Datacenter Server");
1614 else if (osversion
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1615 strcat (osname
, " Advanced Server");
1617 strcat (osname
, " Server");
1619 else if (osversion
.dwMinorVersion
== 1)
1621 strcpy (osname
, "XP");
1622 if (GetSystemMetrics (SM_MEDIACENTER
))
1623 strcat (osname
, " Media Center Edition");
1624 else if (GetSystemMetrics (SM_TABLETPC
))
1625 strcat (osname
, " Tablet PC Edition");
1626 else if (GetSystemMetrics (SM_STARTER
))
1627 strcat (osname
, " Starter Edition");
1628 else if (osversion
.wSuiteMask
& VER_SUITE_PERSONAL
)
1629 strcat (osname
, " Home Edition");
1631 strcat (osname
, " Professional");
1633 else if (osversion
.dwMinorVersion
== 2)
1635 strcpy (osname
, "2003 Server");
1636 if (GetSystemMetrics (SM_SERVERR2
))
1637 strcat (osname
, " R2");
1638 if (osversion
.wSuiteMask
& VER_SUITE_BLADE
)
1639 strcat (osname
, " Web Edition");
1640 else if (osversion
.wSuiteMask
& VER_SUITE_DATACENTER
)
1641 strcat (osname
, " Datacenter Edition");
1642 else if (osversion
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1643 strcat (osname
, " Enterprise Edition");
1644 else if (osversion
.wSuiteMask
& VER_SUITE_COMPUTE_SERVER
)
1645 strcat (osname
, " Compute Cluster Edition");
1648 else if (osversion
.dwMajorVersion
== 4)
1650 strcpy (osname
, "NT 4");
1653 if (osversion
.wProductType
== VER_NT_WORKSTATION
)
1654 strcat (osname
, " Workstation");
1657 strcat (osname
, " Server");
1658 if (osversion
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1659 strcat (osname
, " Enterprise Edition");
1664 strcpy (osname
, "NT");
1667 strcpy (osname
, "??");
1670 printf ("Windows %s Ver %lu.%lu Build %lu %s\n", osname
,
1671 osversion
.dwMajorVersion
, osversion
.dwMinorVersion
,
1672 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1673 osversion
.dwBuildNumber
: (osversion
.dwBuildNumber
& 0xffff),
1674 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1675 osversion
.szCSDVersion
: "");
1677 if (osversion
.dwPlatformId
== VER_PLATFORM_WIN32s
1678 || osversion
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
)
1679 exit (EXIT_FAILURE
);
1681 BOOL (WINAPI
*wow64_func
) (HANDLE
, PBOOL
) = (BOOL (WINAPI
*) (HANDLE
, PBOOL
))
1682 GetProcAddress (k32
, "IsWow64Process");
1683 BOOL is_wow64
= FALSE
;
1684 if (wow64_func
&& wow64_func (GetCurrentProcess (), &is_wow64
) && is_wow64
)
1686 void (WINAPI
*nativinfo
) (LPSYSTEM_INFO
) = (void (WINAPI
*)
1687 (LPSYSTEM_INFO
)) GetProcAddress (k32
, "GetNativeSystemInfo");
1688 SYSTEM_INFO natinfo
;
1689 nativinfo (&natinfo
);
1690 fputs ("\nRunning under WOW64 on ", stdout
);
1691 switch (natinfo
.wProcessorArchitecture
)
1693 case PROCESSOR_ARCHITECTURE_IA64
:
1696 case PROCESSOR_ARCHITECTURE_AMD64
:
1705 if (GetSystemMetrics (SM_REMOTESESSION
))
1706 printf ("\nRunning in Terminal Service session\n");
1709 char *s
= getenv ("PATH"), *e
;
1714 char sep
= strchr (s
, ';') ? ';' : ':';
1715 int count_path_items
= 0;
1718 for (e
= s
; *e
&& *e
!= sep
; e
++);
1720 printf ("\t%.*s\n", (int) (e
- s
), s
);
1734 if (!GetSystemDirectory (tmp
, 4000))
1735 display_error ("dump_sysinfo: GetSystemDirectory()");
1736 printf ("\nSysDir: %s\n", tmp
);
1738 GetWindowsDirectory (tmp
, 4000);
1739 printf ("WinDir: %s\n\n", tmp
);
1743 printf ("Here's some environment variables that may affect cygwin:\n");
1744 for (i
= 0; environ
[i
]; i
++)
1746 char *eq
= strchr (environ
[i
], '=');
1749 /* int len = eq - environ[i]; */
1750 for (j
= 0; known_env_vars
[j
]; j
++)
1753 if (strcmp (environ
[i
], "PATH") == 0)
1754 continue; /* we handle this one specially */
1755 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1756 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1765 printf ("Here's the rest of your environment variables:\n");
1766 for (i
= 0; environ
[i
]; i
++)
1769 char *eq
= strchr (environ
[i
], '=');
1772 /* int len = eq - environ[i]; */
1773 for (j
= 0; known_env_vars
[j
]; j
++)
1776 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1783 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1793 printf ("Scanning registry for keys with 'Cygwin' in them...\n");
1794 scan_registry (0, HKEY_CURRENT_USER
,
1795 (char *) "HKEY_CURRENT_USER", 0, false);
1796 scan_registry (0, HKEY_LOCAL_MACHINE
,
1797 (char *) "HKEY_LOCAL_MACHINE", 0, false);
1801 printf ("Use '-r' to scan registry\n\n");
1803 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE
,
1804 "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\kernel",
1805 0, KEY_READ
, &key
) == ERROR_SUCCESS
)
1808 RegQueryValueEx (key
, "obcaseinsensitive", NULL
, NULL
,
1809 (LPBYTE
) &obcaseinsensitive
, &size
);
1812 printf ("obcaseinsensitive set to %lu\n\n", obcaseinsensitive
);
1814 print_reg_installations ();
1818 printf ("Listing available drives...\n");
1819 printf ("Drv Type Size Used Flags Name\n");
1822 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
);
1823 int drivemask
= GetLogicalDrives ();
1825 BOOL (WINAPI
* gdfse
) (LPCSTR
, long long *, long long *, long long *) =
1826 (BOOL (WINAPI
*) (LPCSTR
, long long *, long long *, long long *))
1827 GetProcAddress (k32
, "GetDiskFreeSpaceExA");
1829 for (i
= 0; i
< 26; i
++)
1831 if (!(drivemask
& (1 << i
)))
1833 char drive
[4], name
[200], fsname
[200];
1834 DWORD serno
= 0, maxnamelen
= 0, flags
= 0;
1835 name
[0] = fsname
[0] = 0;
1836 sprintf (drive
, "%c:\\", i
+ 'a');
1837 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1838 ERROR_NOT_READY is returned when removeable media drives are empty
1839 (CD, floppy, etc.) */
1840 if (!GetVolumeInformation (drive
, name
, sizeof (name
), &serno
,
1841 &maxnamelen
, &flags
, fsname
,
1843 && GetLastError () != ERROR_NOT_READY
)
1845 # define FMT "dump_sysinfo: GetVolumeInformation() for drive %c:"
1846 char buf
[sizeof (FMT
)];
1847 sprintf (buf
, FMT
, 'A' + i
);
1848 display_error (buf
);
1852 int dtype
= GetDriveType (drive
);
1853 char drive_type
[4] = "unk";
1856 case DRIVE_REMOVABLE
:
1857 strcpy (drive_type
, "fd ");
1860 strcpy (drive_type
, "hd ");
1863 strcpy (drive_type
, "net");
1866 strcpy (drive_type
, "cd ");
1869 strcpy (drive_type
, "ram");
1872 strcpy (drive_type
, "unk");
1875 long capacity_mb
= -1;
1876 int percent_full
= -1;
1878 long long free_me
= 0ULL, free_bytes
= 0ULL, total_bytes
= 1ULL;
1879 if (gdfse
!= NULL
&& gdfse (drive
, &free_me
, &total_bytes
, &free_bytes
))
1881 capacity_mb
= total_bytes
/ (1024L * 1024L);
1882 percent_full
= 100 - (int) ((100.0 * free_me
) / total_bytes
);
1886 DWORD spc
= 0, bps
= 0, fc
= 0, tc
= 1;
1887 if (GetDiskFreeSpace (drive
, &spc
, &bps
, &fc
, &tc
))
1889 capacity_mb
= (spc
* bps
* tc
) / (1024 * 1024);
1890 percent_full
= 100 - (int) ((100.0 * fc
) / tc
);
1894 printf ("%.2s %s %-6s ", drive
, drive_type
, fsname
);
1895 if (capacity_mb
>= 0)
1896 printf ("%7dMb %3d%% ", (int) capacity_mb
, (int) percent_full
);
1898 printf (" N/A N/A ");
1899 printf ("%s %s %s %s %s %s %s\n",
1900 flags
& FS_CASE_IS_PRESERVED
? "CP" : " ",
1901 flags
& FS_CASE_SENSITIVE
? "CS" : " ",
1902 flags
& FS_UNICODE_STORED_ON_DISK
? "UN" : " ",
1903 flags
& FS_PERSISTENT_ACLS
? "PA" : " ",
1904 flags
& FS_FILE_COMPRESSION
? "FC" : " ",
1905 flags
& FS_VOL_IS_COMPRESSED
? "VC" : " ",
1907 flags
& FILE_SUPPORTS_ENCRYPTION
? "EN" : " ",
1908 flags
& FILE_SUPPORTS_OBJECT_IDS
? "OI" : " ",
1909 flags
& FILE_SUPPORTS_REPARSE_POINTS
? "RP" : " ",
1910 flags
& FILE_SUPPORTS_SPARSE_FILES
? "SP" : " ",
1911 flags
& FILE_VOLUME_QUOTAS
? "QU" : " ",
1916 SetErrorMode (prev_mode
);
1920 "fd = floppy, hd = hard drive, cd = CD-ROM\n"
1921 "net= Network Share, ram= RAM drive, unk= Unknown\n"
1922 "CP = Case Preserving, CS = Case Sensitive, UN = Unicode\n"
1923 "PA = Persistent ACLS, FC = File Compression, VC = Volume Compression");
1927 unsigned ml_fsname
= 4, ml_dir
= 7, ml_type
= 6;
1928 bool ml_trailing
= false;
1932 while ((mnt
= getmntent (0)))
1934 unsigned n
= (int) strlen (mnt
->mnt_fsname
);
1935 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_fsname
[n
- 1]));
1938 n
= (int) strlen (mnt
->mnt_dir
);
1939 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_dir
[n
- 1]));
1945 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1950 ("Mount entries: these map POSIX directories to your NT drives.\n");
1951 printf ("%-*s %-*s %-*s %s\n", ml_fsname
, "-NT-", ml_dir
, "-POSIX-",
1952 ml_type
, "-Type-", "-Flags-");
1956 while ((mnt
= getmntent (0)))
1958 printf ("%-*s %-*s %-*s %s\n",
1959 ml_fsname
, mnt
->mnt_fsname
,
1960 ml_dir
, mnt
->mnt_dir
, ml_type
, mnt
->mnt_type
, mnt
->mnt_opts
);
1966 ("Looking to see where common programs can be found, if at all...\n");
1967 for (i
= 0; common_apps
[i
].name
; i
++)
1968 if (!find_app_on_path ((char *) common_apps
[i
].name
, 1))
1970 if (common_apps
[i
].missing_is_good
)
1971 printf ("Not Found: %s (good!)\n", common_apps
[i
].name
);
1973 printf ("Not Found: %s\n", common_apps
[i
].name
);
1978 printf ("Looking for various Cygwin DLLs... (-v gives version info)\n");
1979 int cygwin_dll_count
= 0;
1980 char cygdll_path
[32768];
1981 for (pathlike
*pth
= paths
; pth
->dir
; pth
++)
1983 WIN32_FIND_DATAW ffinfo
;
1984 sprintf (tmp
, "%s*.*", pth
->dir
);
1985 wide_path
wpath (tmp
);
1986 HANDLE ff
= FindFirstFileW (wpath
, &ffinfo
);
1987 int found
= (ff
!= INVALID_HANDLE_VALUE
);
1988 found_cygwin_dll
= NULL
;
1991 char f
[FILENAME_MAX
+ 1];
1992 wcstombs (f
, ffinfo
.cFileName
, sizeof f
);
1993 if (strcasecmp (f
+ strlen (f
) - 4, ".dll") == 0)
1995 if (strncasecmp (f
, "cyg", 3) == 0)
1997 sprintf (tmp
, "%s%s", pth
->dir
, f
);
1998 if (strcasecmp (f
, "cygwin1.dll") == 0)
2000 if (!cygwin_dll_count
)
2001 strcpy (cygdll_path
, pth
->dir
);
2002 if (!cygwin_dll_count
2003 || strcasecmp (cygdll_path
, pth
->dir
) != 0)
2005 found_cygwin_dll
= strdup (tmp
);
2011 found
= FindNextFileW (ff
, &ffinfo
);
2013 if (found_cygwin_dll
)
2015 ls (found_cygwin_dll
);
2016 free (found_cygwin_dll
);
2021 if (cygwin_dll_count
> 1)
2022 puts ("Warning: There are multiple cygwin1.dlls on your path");
2023 if (!cygwin_dll_count
)
2024 puts ("Warning: cygwin1.dll not found on your path");
2026 dump_dodgy_apps (verbose
);
2029 dump_sysinfo_services ();
2035 HANDLE h
= CreateFileW (L
"CONIN$", GENERIC_READ
| GENERIC_WRITE
,
2036 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
2037 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2039 if (h
== INVALID_HANDLE_VALUE
|| h
== NULL
)
2040 return (display_error ("check_keys: Opening CONIN$"));
2044 if (!GetConsoleMode (h
, &mode
))
2045 display_error ("check_keys: GetConsoleMode()");
2048 mode
&= ~ENABLE_PROCESSED_INPUT
;
2049 if (!SetConsoleMode (h
, mode
))
2050 display_error ("check_keys: SetConsoleMode()");
2053 fputs ("\nThis key check works only in a console window,", stderr
);
2054 fputs (" _NOT_ in a terminal session!\n", stderr
);
2055 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr
);
2056 fputs ("Press 'q' to exit.\n", stderr
);
2058 INPUT_RECORD in
, prev_in
;
2060 // Drop first <RETURN> key
2061 ReadConsoleInputW (h
, &in
, 1, &mode
);
2063 memset (&in
, 0, sizeof in
);
2068 if (!ReadConsoleInputW (h
, &in
, 1, &mode
))
2069 display_error ("check_keys: ReadConsoleInput()");
2071 if (!memcmp (&in
, &prev_in
, sizeof in
))
2074 switch (in
.EventType
)
2077 printf ("%s %ux VK: 0x%04x VS: 0x%04x C: 0x%04x CTRL: ",
2078 in
.Event
.KeyEvent
.bKeyDown
? "Pressed " : "Released",
2079 in
.Event
.KeyEvent
.wRepeatCount
,
2080 in
.Event
.KeyEvent
.wVirtualKeyCode
,
2081 in
.Event
.KeyEvent
.wVirtualScanCode
,
2082 (unsigned char) in
.Event
.KeyEvent
.uChar
.UnicodeChar
);
2083 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& CAPSLOCK_ON
?
2084 "CL " : "-- ", stdout
);
2085 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& ENHANCED_KEY
?
2086 "EK " : "-- ", stdout
);
2087 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_ALT_PRESSED
?
2088 "LA " : "-- ", stdout
);
2089 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_CTRL_PRESSED
?
2090 "LC " : "-- ", stdout
);
2091 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& NUMLOCK_ON
?
2092 "NL " : "-- ", stdout
);
2093 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
?
2094 "RA " : "-- ", stdout
);
2095 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_CTRL_PRESSED
?
2096 "RC " : "-- ", stdout
);
2097 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SCROLLLOCK_ON
?
2098 "SL " : "-- ", stdout
);
2099 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
?
2100 "SH " : "-- ", stdout
);
2101 fputc ('\n', stdout
);
2108 while (in
.EventType
!= KEY_EVENT
||
2109 in
.Event
.KeyEvent
.bKeyDown
!= FALSE
||
2110 in
.Event
.KeyEvent
.uChar
.UnicodeChar
!= L
'q');
2116 /* RFC1738 says that these do not need to be escaped. */
2117 static const char safe_chars
[] = "$-_.+!*'(),";
2119 /* the URL to query. */
2120 static const char base_url
[] =
2121 "http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep=";
2123 /* Queries Cygwin web site for packages containing files matching a regexp.
2124 Return value is 1 if there was a problem, otherwise 0. */
2126 package_grep (char *search
)
2130 /* Attempt to dynamically load the necessary WinInet API functions so that
2131 cygcheck can still function on older systems without IE. */
2133 if (!(hWinInet
= LoadLibrary ("wininet.dll")))
2135 fputs ("Unable to locate WININET.DLL. This feature requires Microsoft "
2136 "Internet Explorer v3 or later to function.\n", stderr
);
2140 /* InternetCloseHandle is used outside this function so it is declared
2141 global. The rest of these functions are only used here, so declare them
2142 and call GetProcAddress for each of them with the following macro. */
2144 pInternetCloseHandle
= (BOOL (WINAPI
*) (HINTERNET
))
2145 GetProcAddress (hWinInet
, "InternetCloseHandle");
2146 #define make_func_pointer(name, ret, args) ret (WINAPI * p##name) args = \
2147 (ret (WINAPI *) args) GetProcAddress (hWinInet, #name);
2148 make_func_pointer (InternetAttemptConnect
, DWORD
, (DWORD
));
2149 make_func_pointer (InternetOpenA
, HINTERNET
, (LPCSTR
, DWORD
, LPCSTR
, LPCSTR
,
2151 make_func_pointer (InternetOpenUrlA
, HINTERNET
, (HINTERNET
, LPCSTR
, LPCSTR
,
2152 DWORD
, DWORD
, DWORD
));
2153 make_func_pointer (InternetReadFile
, BOOL
, (HINTERNET
, PVOID
, DWORD
, PDWORD
));
2154 make_func_pointer (HttpQueryInfoA
, BOOL
, (HINTERNET
, DWORD
, PVOID
, PDWORD
,
2156 #undef make_func_pointer
2158 if(!pInternetCloseHandle
|| !pInternetAttemptConnect
|| !pInternetOpenA
2159 || !pInternetOpenUrlA
|| !pInternetReadFile
|| !pHttpQueryInfoA
)
2161 fputs ("Unable to load one or more functions from WININET.DLL. This "
2162 "feature requires Microsoft Internet Explorer v3 or later to "
2163 "function.\n", stderr
);
2167 /* construct the actual URL by escaping */
2168 char *url
= (char *) alloca (sizeof (base_url
) + strlen (search
) * 3);
2169 strcpy (url
, base_url
);
2172 for (dest
= &url
[sizeof (base_url
) - 1]; *search
; search
++)
2174 if (isalnum (*search
)
2175 || memchr (safe_chars
, *search
, sizeof (safe_chars
) - 1))
2182 sprintf (dest
, "%02x", (unsigned char) *search
);
2188 /* Connect to the net and open the URL. */
2189 if (pInternetAttemptConnect (0) != ERROR_SUCCESS
)
2191 fputs ("An internet connection is required for this function.\n", stderr
);
2195 /* Initialize WinInet and attempt to fetch our URL. */
2196 HINTERNET hi
= NULL
, hurl
= NULL
;
2197 if (!(hi
= pInternetOpenA ("cygcheck", INTERNET_OPEN_TYPE_PRECONFIG
, NULL
, NULL
, 0)))
2198 return display_internet_error ("InternetOpen() failed", NULL
);
2200 if (!(hurl
= pInternetOpenUrlA (hi
, url
, NULL
, 0, 0, 0)))
2201 return display_internet_error ("unable to contact cygwin.com site, "
2202 "InternetOpenUrl() failed", hi
, NULL
);
2204 /* Check the HTTP response code. */
2205 DWORD rc
= 0, rc_s
= sizeof (DWORD
);
2206 if (!pHttpQueryInfoA (hurl
, HTTP_QUERY_STATUS_CODE
| HTTP_QUERY_FLAG_NUMBER
,
2207 (void *) &rc
, &rc_s
, NULL
))
2208 return display_internet_error ("HttpQueryInfo() failed", hurl
, hi
, NULL
);
2210 if (rc
!= HTTP_STATUS_OK
)
2212 sprintf (buf
, "error retrieving results from cygwin.com site, "
2213 "HTTP status code %lu", rc
);
2214 return display_internet_error (buf
, hurl
, hi
, NULL
);
2217 /* Fetch result and print to stdout. */
2221 if (!pInternetReadFile (hurl
, (void *) buf
, sizeof (buf
), &numread
))
2222 return display_internet_error ("InternetReadFile failed", hurl
, hi
, NULL
);
2224 fwrite ((void *) buf
, (size_t) numread
, 1, stdout
);
2228 pInternetCloseHandle (hurl
);
2229 pInternetCloseHandle (hi
);
2234 usage (FILE * stream
, int status
)
2237 Usage: cygcheck [-v] [-h] PROGRAM\n\
2238 cygcheck -c [-d] [PACKAGE]\n\
2239 cygcheck -s [-r] [-v] [-h]\n\
2241 cygcheck -f FILE [FILE]...\n\
2242 cygcheck -l [PACKAGE]...\n\
2243 cygcheck -p REGEXP\n\
2244 cygcheck --delete-orphaned-installation-keys\n\
2245 cygcheck --enable-unique-object-names Cygwin-DLL\n\
2246 cygcheck --disable-unique-object-names Cygwin-DLL\n\
2247 cygcheck --show-unique-object-names Cygwin-DLL\n\
2249 List system information, check installed packages, or query package database.\n\
2251 At least one command option or a PROGRAM is required, as shown above.\n\
2253 PROGRAM list library (DLL) dependencies of PROGRAM\n\
2254 -c, --check-setup show installed version of PACKAGE and verify integrity\n\
2255 (or for all installed packages if none specified)\n\
2256 -d, --dump-only just list packages, do not verify (with -c)\n\
2257 -s, --sysinfo produce diagnostic system information (implies -c)\n\
2258 -r, --registry also scan registry for Cygwin settings (with -s)\n\
2259 -k, --keycheck perform a keyboard check session (must be run from a\n\
2260 plain console only, not from a pty/rxvt/xterm)\n\
2261 -f, --find-package find the package to which FILE belongs\n\
2262 -l, --list-package list contents of PACKAGE (or all packages if none given)\n\
2263 -p, --package-query search for REGEXP in the entire cygwin.com package\n\
2264 repository (requires internet connectivity)\n\
2265 --delete-orphaned-installation-keys\n\
2266 Delete installation keys of old, now unused\n\
2267 installations from the registry. Requires the right\n\
2268 to change the registry.\n\
2269 --enable-unique-object-names Cygwin-DLL\n\
2270 --disable-unique-object-names Cygwin-DLL\n\
2271 --show-unique-object-names Cygwin-DLL\n\
2272 Enable, disable, or show the setting of the\n\
2273 \"unique object names\" setting in the Cygwin DLL\n\
2274 given as argument to this option. The DLL path must\n\
2275 be given as valid Windows(!) path.\n\
2276 See the users guide for more information.\n\
2277 If you don't know what this means, don't change it.\n\
2278 -v, --verbose produce more verbose output\n\
2279 -h, --help annotate output with explanatory comments when given\n\
2280 with another command, otherwise print this help\n\
2281 -V, --version print the version of cygcheck and exit\n\
2283 Note: -c, -f, and -l only report on packages that are currently installed. To\n\
2284 search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
2285 package names, descriptions, and names of files/paths within all packages.\n\
2290 struct option longopts
[] = {
2291 {"check-setup", no_argument
, NULL
, 'c'},
2292 {"dump-only", no_argument
, NULL
, 'd'},
2293 {"sysinfo", no_argument
, NULL
, 's'},
2294 {"registry", no_argument
, NULL
, 'r'},
2295 {"verbose", no_argument
, NULL
, 'v'},
2296 {"keycheck", no_argument
, NULL
, 'k'},
2297 {"find-package", no_argument
, NULL
, 'f'},
2298 {"list-package", no_argument
, NULL
, 'l'},
2299 {"package-query", no_argument
, NULL
, 'p'},
2300 {"delete-orphaned-installation-keys", no_argument
, NULL
, CO_DELETE_KEYS
},
2301 {"enable-unique-object-names", no_argument
, NULL
, CO_ENABLE_UON
},
2302 {"disable-unique-object-names", no_argument
, NULL
, CO_DISABLE_UON
},
2303 {"show-unique-object-names", no_argument
, NULL
, CO_SHOW_UON
},
2304 {"help", no_argument
, NULL
, 'h'},
2305 {"version", no_argument
, 0, 'V'},
2306 {0, no_argument
, NULL
, 0}
2309 static char opts
[] = "cdsrvkflphV";
2314 printf ("cygcheck (cygwin) %d.%d.%d\n"
2315 "System Checker for Cygwin\n"
2316 "Copyright (C) 1998 - %s Red Hat, Inc.\n"
2317 "This is free software; see the source for copying conditions. There is NO\n"
2318 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
2319 CYGWIN_VERSION_DLL_MAJOR
/ 1000,
2320 CYGWIN_VERSION_DLL_MAJOR
% 1000,
2321 CYGWIN_VERSION_DLL_MINOR
,
2322 strrchr (__DATE__
, ' ') + 1);
2328 int n
= 1 + strchr (ev
, '=') - ev
;
2329 char *s
= (char *) malloc (n
+ 1);
2336 uintptr_t (*cygwin_internal
) (int, ...);
2337 WCHAR cygwin_dll_path
[32768];
2341 load_cygwin (int& argc
, char **&argv
)
2345 if (!(h
= LoadLibrary ("cygwin1.dll")))
2347 GetModuleFileNameW (h
, cygwin_dll_path
, 32768);
2348 if ((cygwin_internal
= (uintptr_t (*) (int, ...))
2349 GetProcAddress (h
, "cygwin_internal")))
2351 char **av
= (char **) cygwin_internal (CW_ARGV
);
2352 if (av
&& ((uintptr_t) av
!= (uintptr_t) -1))
2354 /* Copy cygwin's idea of the argument list into this Window application. */
2355 for (argc
= 0; av
[argc
]; argc
++)
2357 argv
= (char **) calloc (argc
+ 1, sizeof (char *));
2358 for (char **argvp
= argv
; *av
; av
++)
2359 *argvp
++ = strdup (*av
);
2363 char **envp
= (char **) cygwin_internal (CW_ENVP
);
2364 if (envp
&& ((uintptr_t) envp
!= (uintptr_t) -1))
2366 /* Store path and revert to this value, otherwise path gets overwritten
2367 by the POSIXy Cygwin variation, which breaks cygcheck.
2368 Another approach would be to use the Cygwin PATH and convert it to
2372 while (*(env
= _environ
))
2374 if (strncmp (*env
, "PATH=", 5) == 0)
2375 path
= strdup (*env
);
2378 for (char **ev
= envp
; *ev
; ev
++)
2379 if (strncmp (*ev
, "PATH=", 5) != 0)
2380 putenv (strdup (*ev
));
2389 main (int argc
, char **argv
)
2393 load_cygwin (argc
, argv
);
2395 /* Need POSIX sorting while parsing args, but don't forget the
2396 user's original environment. */
2397 char *posixly
= getenv ("POSIXLY_CORRECT");
2398 if (posixly
== NULL
)
2399 (void) putenv ("POSIXLY_CORRECT=1");
2400 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
2433 case CO_DELETE_KEYS
:
2434 del_orphaned_reg
= 1;
2437 case CO_DISABLE_UON
:
2439 unique_object_name_opt
= i
;
2445 fprintf (stderr
, "Try `cygcheck --help' for more information.\n");
2451 if (posixly
== NULL
)
2452 putenv ("POSIXLY_CORRECT=");
2454 if ((argc
== 0) && !sysinfo
&& !keycheck
&& !check_setup
&& !list_package
2455 && !del_orphaned_reg
)
2463 if ((check_setup
|| sysinfo
|| find_package
|| list_package
|| grep_packages
2464 || del_orphaned_reg
|| unique_object_name_opt
)
2468 if ((find_package
|| list_package
|| grep_packages
)
2469 && (check_setup
|| del_orphaned_reg
))
2472 if ((check_setup
|| sysinfo
|| find_package
|| list_package
|| grep_packages
2473 || del_orphaned_reg
)
2474 && unique_object_name_opt
)
2477 if (dump_only
&& !check_setup
&& !sysinfo
)
2480 if (find_package
+ list_package
+ grep_packages
> 1)
2484 return check_keys ();
2485 if (unique_object_name_opt
)
2486 return handle_unique_object_name (unique_object_name_opt
, *argv
);
2487 if (del_orphaned_reg
)
2488 del_orphaned_reg_installations ();
2490 return package_grep (*argv
);
2494 /* FIXME: Add help for check_setup and {list,find}_package */
2495 if (argc
>= 1 && givehelp
&& !check_setup
&& !find_package
&& !list_package
)
2497 printf("Here is where the OS will find your program%s, and which dlls\n",
2498 argc
> 1 ? "s" : "");
2499 printf ("will be used for it. Use -v to see DLL version info\n");
2506 dump_setup (verbose
, argv
, !dump_only
);
2507 else if (find_package
)
2508 package_find (verbose
, argv
);
2509 else if (list_package
)
2510 package_list (verbose
, argv
);
2512 for (i
= 0; i
< argc
; i
++)
2516 ok
&= cygcheck (argv
[i
]);
2525 dump_setup (verbose
, NULL
, !dump_only
);
2529 puts ("Use -h to see help about each section");
2532 return ok
? EXIT_SUCCESS
: EXIT_FAILURE
;