3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
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
24 #include "cygwin/include/sys/cygwin.h"
25 #include "cygwin/include/mntent.h"
26 #undef cygwin_internal
28 #define alloca __builtin_alloca
39 int grep_packages
= 0;
41 /* This is global because it's used in both internet_display_error as well
43 BOOL (WINAPI
*pInternetCloseHandle
) (HINTERNET
);
46 typedef long long longlong
;
48 typedef __int64 longlong
;
51 void dump_setup (int, char **, bool);
52 void package_find (int, char **);
53 void package_list (int, char **);
55 static const char version
[] = "$Revision$";
57 static const char *known_env_vars
[] = {
65 "gcc_default_options",
87 static common_apps
[] = {
115 static int num_paths
, max_paths
;
117 int first_nonsys_path
;
120 eprintf (const char *format
, ...)
123 va_start (ap
, format
);
124 vfprintf (stderr
, format
, ap
);
129 * display_error() is used to report failure modes
132 display_error (const char *name
, bool show_error
= true, bool print_failed
= true)
135 fprintf (stderr
, "cygcheck: %s%s: %lu\n", name
,
136 print_failed
? " failed" : "", GetLastError ());
138 fprintf (stderr
, "cygcheck: %s%s\n", name
,
139 print_failed
? " failed" : "");
143 /* Display a WinInet error message, and close a variable number of handles.
144 (Passed a list of handles terminated by NULL.) */
146 display_internet_error (const char *message
, ...)
148 DWORD err
= GetLastError ();
153 /* in the case of a successful connection but 404 response, there is no
154 win32 error message, but we still get passed a message to display. */
157 if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE
,
158 GetModuleHandle ("wininet.dll"), err
, 0, err_buf
,
159 sizeof (err_buf
), NULL
) == 0)
160 strcpy (err_buf
, "(Unknown error)");
162 fprintf (stderr
, "cygcheck: %s: %s (win32 error %d)\n", message
,
166 fprintf (stderr
, "cygcheck: %s\n", message
);
168 va_start (hptr
, message
);
169 while ((h
= va_arg (hptr
, HINTERNET
)) != 0)
170 pInternetCloseHandle (h
);
177 add_path (char *s
, int maxlen
)
179 if (num_paths
>= max_paths
)
183 paths
= (char **) realloc (paths
, max_paths
* sizeof (char *));
185 paths
= (char **) malloc (max_paths
* sizeof (char *));
187 paths
[num_paths
] = (char *) malloc (maxlen
+ 1);
188 if (paths
[num_paths
] == NULL
)
190 display_error ("add_path: malloc()");
193 memcpy (paths
[num_paths
], s
, maxlen
);
194 paths
[num_paths
][maxlen
] = 0;
195 char *e
= paths
[num_paths
] + strlen (paths
[num_paths
]);
196 if (e
[-1] == '\\' && e
[-2] != ':')
198 for (int i
= 1; i
< num_paths
; i
++)
199 if (strcasecmp (paths
[num_paths
], paths
[i
]) == 0)
201 free (paths
[num_paths
]);
211 add_path ((char *) ".", 1); /* to be replaced later */
213 if (GetCurrentDirectory (4000, tmp
))
214 add_path (tmp
, strlen (tmp
));
216 display_error ("init_paths: GetCurrentDirectory()");
218 if (GetSystemDirectory (tmp
, 4000))
219 add_path (tmp
, strlen (tmp
));
221 display_error ("init_paths: GetSystemDirectory()");
222 sl
= strrchr (tmp
, '\\');
225 strcpy (sl
, "\\SYSTEM");
226 add_path (tmp
, strlen (tmp
));
228 GetWindowsDirectory (tmp
, 4000);
229 add_path (tmp
, strlen (tmp
));
230 first_nonsys_path
= num_paths
;
232 char *wpath
= getenv ("PATH");
234 fprintf (stderr
, "WARNING: PATH is not set at all!\n");
241 for (e
= b
; *e
&& *e
!= ';'; e
++);
242 if (strncmp(b
, ".", 1) && strncmp(b
, ".\\", 2))
252 find_on_path (char *file
, char *default_extension
,
253 int showall
= 0, int search_sysdirs
= 0)
255 static char rv
[4000];
256 char tmp
[4000], *ptr
= rv
;
260 display_error ("find_on_path: NULL pointer for file", false, false);
264 if (default_extension
== NULL
)
266 display_error ("find_on_path: NULL pointer for default_extension", false, false);
270 if (strchr (file
, ':') || strchr (file
, '\\') || strchr (file
, '/'))
272 char *fn
= cygpath (file
, NULL
);
273 if (access (fn
, F_OK
) == 0)
276 strcat (rv
, default_extension
);
277 return access (rv
, F_OK
) == 0 ? rv
: fn
;
280 if (strchr (file
, '.'))
281 default_extension
= (char *) "";
283 for (int i
= search_sysdirs
? 0 : first_nonsys_path
; i
< num_paths
; i
++)
285 if (i
== 0 || !search_sysdirs
|| strcasecmp (paths
[i
], paths
[0]))
287 sprintf (ptr
, "%s\\%s%s", paths
[i
], file
, default_extension
);
288 if (GetFileAttributes (ptr
) != (DWORD
) - 1)
291 printf ("Found: %s\n", ptr
);
292 if (ptr
== tmp
&& verbose
)
293 printf ("Warning: %s hides %s\n", rv
, ptr
);
307 #define DID_INACTIVE 3
318 already_did (char *file
)
321 for (d
= did
; d
; d
= d
->next
)
322 if (strcasecmp (d
->file
, file
) == 0)
324 d
= (Did
*) malloc (sizeof (Did
));
325 d
->file
= strdup (file
);
333 get_word (HANDLE fh
, int offset
)
338 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
339 && GetLastError () != NO_ERROR
)
340 display_error ("get_word: SetFilePointer()");
342 if (!ReadFile (fh
, &rv
, 2, (DWORD
*) &r
, 0))
343 display_error ("get_word: Readfile()");
349 get_dword (HANDLE fh
, int offset
)
354 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
355 && GetLastError () != NO_ERROR
)
356 display_error ("get_dword: SetFilePointer()");
358 if (!ReadFile (fh
, &rv
, 4, (DWORD
*) &r
, 0))
359 display_error ("get_dword: Readfile()");
369 int size_of_raw_data
;
370 int pointer_to_raw_data
;
374 rva_to_offset (int rva
, char *sections
, int nsections
, int *sz
)
378 if (sections
== NULL
)
380 display_error ("rva_to_offset: NULL passed for sections", true, false);
384 for (i
= 0; i
< nsections
; i
++)
386 Section
*s
= (Section
*) (sections
+ i
* 40);
388 printf ("%08x < %08x < %08x ? %08x\n",
389 s
->virtual_address
, rva
,
390 s
->virtual_address
+ s
->virtual_size
, s
->pointer_to_raw_data
);
392 if (rva
>= s
->virtual_address
393 && rva
< s
->virtual_address
+ s
->virtual_size
)
396 *sz
= s
->virtual_address
+ s
->virtual_size
- rva
;
397 return rva
- s
->virtual_address
+ s
->pointer_to_raw_data
;
414 unsigned characteristics
;
416 unsigned forwarder_chain
;
422 static bool track_down (char *file
, char *suffix
, int lvl
);
424 #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
426 cygwin_info (HANDLE h
)
428 char *buf
, *bufend
, *buf_start
= NULL
;
429 const char *hello
= " Cygwin DLL version info:\n";
430 DWORD size
= GetFileSize (h
, NULL
);
433 if (size
== 0xffffffff)
436 buf_start
= buf
= (char *) calloc (1, size
+ 1);
439 display_error ("cygwin_info: calloc()");
443 (void) SetFilePointer (h
, 0, NULL
, FILE_BEGIN
);
444 if (!ReadFile (h
, buf
, size
, &n
, NULL
))
450 static char dummy
[] = "\0\0\0\0\0\0\0";
451 char *dll_major
= dummy
;
454 if ((buf
= (char *) memchr (buf
, '%', bufend
- buf
)) == NULL
)
456 else if (strncmp ("%%% Cygwin ", buf
, CYGPREFIX
) != 0)
460 char *p
= strchr (buf
+= CYGPREFIX
, '\n');
463 if (strncasecmp (buf
, "dll major:", 10) == 0)
465 dll_major
= buf
+ 11;
471 if (strncasecmp (buf
, "dll minor:", 10) != 0)
475 char c
= dll_major
[1];
477 int maj
= atoi (dll_major
);
479 int min
= atoi (dll_major
+ 1);
480 sprintf (pbuf
, "DLL version: %d.%d.%.*s", maj
, min
, len
- 11,
482 len
= strlen (s
= pbuf
);
484 if (strncmp (s
, "dll", 3) == 0)
485 memcpy (s
, "DLL", 3);
486 else if (strncmp (s
, "api", 3) == 0)
487 memcpy (s
, "API", 3);
488 else if (islower (*s
))
490 fprintf (stdout
, "%s %.*s", hello
, len
, s
);
502 dll_info (const char *path
, HANDLE fh
, int lvl
, int recurse
)
506 int pe_header_offset
= get_dword (fh
, 0x3c);
507 int opthdr_ofs
= pe_header_offset
+ 4 + 20;
512 display_error ("dll_info: NULL passed for path", true, false);
516 if (SetFilePointer (fh
, opthdr_ofs
+ 40, 0, FILE_BEGIN
) ==
517 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
518 display_error ("dll_info: SetFilePointer()");
520 if (!ReadFile (fh
, &v
, sizeof (v
), &junk
, 0))
521 display_error ("dll_info: Readfile()");
524 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
525 v
[0], v
[1], v
[2], v
[3], v
[4], v
[5]);
529 int num_entries
= get_dword (fh
, opthdr_ofs
+ 92);
530 int export_rva
= get_dword (fh
, opthdr_ofs
+ 96);
531 int export_size
= get_dword (fh
, opthdr_ofs
+ 100);
532 int import_rva
= get_dword (fh
, opthdr_ofs
+ 104);
533 int import_size
= get_dword (fh
, opthdr_ofs
+ 108);
535 int nsections
= get_word (fh
, pe_header_offset
+ 4 + 2);
536 char *sections
= (char *) malloc (nsections
* 40);
538 if (SetFilePointer (fh
, pe_header_offset
+ 4 + 20 +
539 get_word (fh
, pe_header_offset
+ 4 + 16), 0,
540 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
541 && GetLastError () != NO_ERROR
)
542 display_error ("dll_info: SetFilePointer()");
544 if (!ReadFile (fh
, sections
, nsections
* 40, &junk
, 0))
545 display_error ("dll_info: Readfile()");
547 if (verbose
&& num_entries
>= 1 && export_size
> 0)
550 int expbase
= rva_to_offset (export_rva
, sections
, nsections
, &expsz
);
554 if (SetFilePointer (fh
, expbase
, 0, FILE_BEGIN
) ==
555 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
556 display_error ("dll_info: SetFilePointer()");
558 unsigned char *exp
= (unsigned char *) malloc (expsz
);
560 if (!ReadFile (fh
, exp
, expsz
, &junk
, 0))
561 display_error ("dll_info: Readfile()");
563 ExpDirectory
*ed
= (ExpDirectory
*) exp
;
564 int ofs
= ed
->name_rva
- export_rva
;
565 struct tm
*tm
= localtime ((const time_t *) &(ed
->timestamp
));
566 if (tm
->tm_year
< 60)
568 if (tm
->tm_year
< 200)
570 printf ("%*c", lvl
+ 2, ' ');
571 printf ("\"%s\" v%d.%d ts=", exp
+ ofs
,
572 ed
->major_ver
, ed
->minor_ver
);
573 printf ("%d/%d/%d %d:%02d\n",
574 tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
,
575 tm
->tm_hour
, tm
->tm_min
);
579 if (num_entries
>= 2 && import_size
> 0 && recurse
)
582 int impbase
= rva_to_offset (import_rva
, sections
, nsections
, &impsz
);
585 if (SetFilePointer (fh
, impbase
, 0, FILE_BEGIN
) ==
586 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
587 display_error ("dll_info: SetFilePointer()");
589 unsigned char *imp
= (unsigned char *) malloc (impsz
);
592 display_error ("dll_info: malloc()");
596 if (!ReadFile (fh
, imp
, impsz
, &junk
, 0))
597 display_error ("dll_info: Readfile()");
599 ImpDirectory
*id
= (ImpDirectory
*) imp
;
600 for (i
= 0; id
[i
].name_rva
; i
++)
602 /* int ofs = id[i].name_rva - import_rva; */
603 track_down ((char *) imp
+ id
[i
].name_rva
- import_rva
,
604 (char *) ".dll", lvl
+ 2);
608 if (strstr (path
, "\\cygwin1.dll"))
612 // Return true on success, false if error printed
614 track_down (char *file
, char *suffix
, int lvl
)
618 display_error ("track_down: NULL passed for file", true, false);
624 display_error ("track_down: NULL passed for suffix", false, false);
628 char *path
= find_on_path (file
, suffix
, 0, 1);
631 printf ("Error: could not find %s\n", file
);
635 Did
*d
= already_did (file
);
644 printf ("%*c", lvl
, ' ');
646 printf (" (recursive)\n");
653 printf ("%*c", lvl
, ' ');
655 printf (" (already done)\n");
663 printf ("%*c", lvl
, ' ');
667 printf ("%s not found\n", file
);
674 CreateFile (path
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
675 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
676 if (fh
== INVALID_HANDLE_VALUE
)
678 printf (" - Cannot open\n");
682 d
->state
= DID_ACTIVE
;
684 dll_info (path
, fh
, lvl
, 1);
685 d
->state
= DID_INACTIVE
;
686 if (!CloseHandle (fh
))
687 display_error ("track_down: CloseHandle()");
694 HANDLE h
= CreateFile (f
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
695 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
696 BY_HANDLE_FILE_INFORMATION info
;
698 if (!GetFileInformationByHandle (h
, &info
))
699 display_error ("ls: GetFileInformationByHandle()");
703 if (!FileTimeToSystemTime (&info
.ftLastWriteTime
, &systime
))
704 display_error ("ls: FileTimeToSystemTime()");
705 printf ("%5dk %04d/%02d/%02d %s",
706 (((int) info
.nFileSizeLow
) + 512) / 1024,
707 systime
.wYear
, systime
.wMonth
, systime
.wDay
, f
);
708 dll_info (f
, h
, 16, 0);
709 if (!CloseHandle (h
))
710 display_error ("ls: CloseHandle()");
713 // Return true on success, false if error printed
717 char *papp
= find_on_path (app
, (char *) ".exe", 1, 0);
720 printf ("Error: could not find %s\n", app
);
723 char *s
= strdup (papp
);
726 if (*t
== '/' || *t
== '\\' || *t
== ':')
729 paths
[0] = (char *) ".";
736 return track_down (papp
, (char *) ".exe", 0);
740 extern char **environ
;
750 show_reg (RegInfo
* ri
, int nest
)
754 show_reg (ri
->prev
, 1);
756 printf ("%s\\", ri
->name
);
758 printf ("%s\n", ri
->name
);
762 scan_registry (RegInfo
* prev
, HKEY hKey
, char *name
, int cygnus
)
770 for (cp
= name
; *cp
; cp
++)
771 if (strncasecmp (cp
, "cygnus", 6) == 0)
774 DWORD num_subkeys
, max_subkey_len
, num_values
;
775 DWORD max_value_len
, max_valdata_len
, i
;
776 if (RegQueryInfoKey (hKey
, 0, 0, 0, &num_subkeys
, &max_subkey_len
, 0,
777 &num_values
, &max_value_len
, &max_valdata_len
, 0, 0)
782 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, 0, GetLastError (),
783 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
), tmp
, 400, 0);
784 printf ("RegQueryInfoKey: %s\n", tmp
);
793 char *value_name
= (char *) malloc (max_value_len
+ 1);
794 if (value_name
== NULL
)
796 display_error ("scan_registry: malloc()");
800 char *value_data
= (char *) malloc (max_valdata_len
+ 1);
801 if (value_data
== NULL
)
803 display_error ("scan_registry: malloc()");
807 for (i
= 0; i
< num_values
; i
++)
809 DWORD dlen
= max_valdata_len
+ 1;
810 DWORD nlen
= max_value_len
+ 1;
812 RegEnumValue (hKey
, i
, value_name
, &nlen
, 0,
813 &type
, (BYTE
*) value_data
, &dlen
);
815 printf (" %s = ", i
? value_name
: "(default)");
819 printf ("0x%08x\n", *(unsigned *) value_data
);
823 printf ("'%s'\n", value_data
);
826 printf ("(unsupported type)\n");
835 char *subkey_name
= (char *) malloc (max_subkey_len
+ 1);
836 for (i
= 0; i
< num_subkeys
; i
++)
838 if (RegEnumKey (hKey
, i
, subkey_name
, max_subkey_len
+ 1) ==
842 if (RegOpenKeyEx (hKey
, subkey_name
, 0, KEY_READ
, &sKey
)
845 scan_registry (&ri
, sKey
, subkey_name
, cygnus
);
846 if (RegCloseKey (sKey
) != ERROR_SUCCESS
)
847 display_error ("scan_registry: RegCloseKey()");
855 pretty_id (const char *s
, char *cygwin
, size_t cyglen
)
859 strcpy (cygwin
+ cyglen
++, " ");
860 strcpy (cygwin
+ cyglen
, s
);
863 char *id
= cygpath ("/bin/id.exe", NULL
);
864 for (char *p
= id
; (p
= strchr (p
, '/')); p
++)
867 if (access (id
, X_OK
))
869 fprintf (stderr
, "'id' program not found\n");
873 FILE *f
= popen (id
, "rt");
877 fgets (buf
, sizeof (buf
), f
);
879 char *uid
= strtok (buf
, ")");
881 uid
+= strlen ("uid=");
884 fprintf (stderr
, "garbled output from 'id' command - no uid= found\n");
887 char *gid
= strtok (NULL
, ")");
889 gid
+= strlen ("gid=") + 1;
892 fprintf (stderr
, "garbled output from 'id' command - no gid= found\n");
896 char **ng
= groups
- 1;
897 size_t len_uid
= strlen ("UID: )") + strlen (uid
);
898 size_t len_gid
= strlen ("GID: )") + strlen (gid
);
899 *++ng
= groups
[0] = (char *) alloca (len_uid
+ 1);
900 *++ng
= groups
[1] = (char *) alloca (len_gid
+ 1);
901 sprintf (groups
[0], "UID: %s)", uid
);
902 sprintf (groups
[1], "GID: %s)", gid
);
903 size_t sz
= max (len_uid
, len_gid
);
904 while ((*++ng
= strtok (NULL
, ",")))
906 char *p
= strchr (*ng
, '\n');
909 if (ng
== groups
+ 2)
910 *ng
+= strlen (" groups=");
911 size_t len
= strlen (*ng
);
917 printf ("\nOutput from %s (%s)\n", id
, s
);
918 int n
= 80 / (int) ++sz
;
919 int i
= n
> 2 ? n
- 2 : 0;
921 for (char **g
= groups
; g
<= ng
; g
++)
922 if ((g
!= ng
) && (++i
< n
))
923 printf ("%*s", sz
, *g
);
931 /* This dumps information about each installed cygwin service, if cygrunsrv
934 dump_sysinfo_services ()
939 bool no_services
= false;
942 printf ("\nChecking for any Cygwin services... %s\n\n",
943 verbose
? "" : "(use -v for more detail)");
945 fputc ('\n', stdout
);
947 /* find the location of cygrunsrv.exe */
948 char *cygrunsrv
= cygpath ("/bin/cygrunsrv.exe", NULL
);
949 for (char *p
= cygrunsrv
; (p
= strchr (p
, '/')); p
++)
952 if (access (cygrunsrv
, X_OK
))
954 puts ("Can't find the cygrunsrv utility, skipping services check.\n");
958 /* check for a recent cygrunsrv */
959 snprintf (buf
, sizeof (buf
), "%s --version", cygrunsrv
);
960 if ((f
= popen (buf
, "rt")) == NULL
)
962 printf ("Failed to execute '%s', skipping services check.\n", buf
);
966 int ret
= fscanf (f
, "cygrunsrv V%u.%u", &maj
, &min
);
967 if (ferror (f
) || feof (f
) || ret
== EOF
|| maj
< 1 || min
< 10)
969 puts ("The version of cygrunsrv installed is too old to dump service info.\n");
974 /* For verbose mode, just run cygrunsrv --list --verbose and copy output
975 verbatim; otherwise run cygrunsrv --list and then cygrunsrv --query for
977 snprintf (buf
, sizeof (buf
), (verbose
? "%s --list --verbose" : "%s --list"),
979 if ((f
= popen (buf
, "rt")) == NULL
)
981 printf ("Failed to execute '%s', skipping services check.\n", buf
);
987 /* copy output to stdout */
989 while (!feof (f
) && !ferror (f
))
990 nchars
+= fwrite ((void *) buf
, 1,
991 fread ((void *) buf
, 1, sizeof (buf
), f
), stdout
);
993 /* cygrunsrv outputs nothing if there are no cygwin services found */
1000 /* read the output of --list, and then run --query for each service */
1001 size_t nchars
= fread ((void *) buf
, 1, sizeof (buf
) - 1, f
);
1006 for (char *srv
= strtok (buf
, "\n"); srv
; srv
= strtok (NULL
, "\n"))
1008 snprintf (buf2
, sizeof (buf2
), "%s --query %s", cygrunsrv
, srv
);
1009 if ((f
= popen (buf2
, "rt")) == NULL
)
1011 printf ("Failed to execute '%s', skipping services check.\n", buf2
);
1015 /* copy output to stdout */
1016 while (!feof (f
) && !ferror (f
))
1017 fwrite ((void *) buf2
, 1,
1018 fread ((void *) buf2
, 1, sizeof (buf2
), f
), stdout
);
1025 /* inform the user if nothing found */
1027 puts ("No Cygwin services found.\n");
1036 char *found_cygwin_dll
;
1039 printf ("\nCygwin Configuration Diagnostics\n");
1041 printf ("Current System Time: %s\n", ctime (&now
));
1043 OSVERSIONINFO osversion
;
1044 osversion
.dwOSVersionInfoSize
= sizeof (osversion
);
1045 if (!GetVersionEx (&osversion
))
1046 display_error ("dump_sysinfo: GetVersionEx()");
1047 const char *osname
= "unknown OS";
1048 switch (osversion
.dwPlatformId
)
1050 case VER_PLATFORM_WIN32s
:
1053 case VER_PLATFORM_WIN32_WINDOWS
:
1054 switch (osversion
.dwMinorVersion
)
1057 if (strchr (osversion
.szCSDVersion
, 'C'))
1063 if (strchr (osversion
.szCSDVersion
, 'A'))
1076 case VER_PLATFORM_WIN32_NT
:
1078 if (osversion
.dwMajorVersion
== 6)
1079 osname
= "Longhorn/Vista (not yet supported!)";
1080 else if (osversion
.dwMajorVersion
== 5)
1082 BOOL more_info
= FALSE
;
1083 OSVERSIONINFOEX osversionex
;
1084 osversionex
.dwOSVersionInfoSize
= sizeof (osversionex
);
1085 if (GetVersionEx ((OSVERSIONINFO
*) &osversionex
))
1087 if (osversion
.dwMinorVersion
== 0)
1091 else if (osversionex
.wProductType
== VER_NT_SERVER
1092 || osversionex
.wProductType
== VER_NT_DOMAIN_CONTROLLER
)
1094 if (osversionex
.wSuiteMask
& VER_SUITE_DATACENTER
)
1095 osname
= "2000 Datacenter Server";
1096 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1097 osname
= "2000 Advanced Server";
1099 osname
= "2000 Server";
1102 osname
= "2000 Professional";
1104 else if (osversion
.dwMinorVersion
== 1)
1106 if (GetSystemMetrics (SM_MEDIACENTER
))
1107 osname
= "XP Media Center Edition";
1108 else if (GetSystemMetrics (SM_TABLETPC
))
1109 osname
= "XP Tablet PC Edition";
1110 else if (!more_info
)
1112 else if (osversionex
.wSuiteMask
& VER_SUITE_PERSONAL
)
1113 osname
= "XP Home Edition";
1115 osname
= "XP Professional";
1117 else if (osversion
.dwMinorVersion
== 2)
1120 osname
= "2003 Server";
1121 else if (osversionex
.wSuiteMask
& VER_SUITE_BLADE
)
1122 osname
= "2003 Web Server";
1123 else if (osversionex
.wSuiteMask
& VER_SUITE_DATACENTER
)
1124 osname
= "2003 Datacenter Server";
1125 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1126 osname
= "2003 Enterprise Server";
1128 osname
= "2003 Server";
1138 printf ("Windows %s Ver %lu.%lu Build %lu %s\n", osname
,
1139 osversion
.dwMajorVersion
, osversion
.dwMinorVersion
,
1140 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1141 osversion
.dwBuildNumber
: (osversion
.dwBuildNumber
& 0xffff),
1142 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1143 osversion
.szCSDVersion
: "");
1145 HMODULE k32
= LoadLibrary ("kernel32.dll");
1147 BOOL (WINAPI
*wow64_func
) (HANDLE
, PBOOL
) = (BOOL (WINAPI
*) (HANDLE
, PBOOL
))
1148 GetProcAddress (k32
, "IsWow64Process");
1149 BOOL is_wow64
= FALSE
;
1150 if (wow64_func
&& wow64_func (GetCurrentProcess (), &is_wow64
) && is_wow64
)
1152 void (WINAPI
*nativinfo
) (LPSYSTEM_INFO
) = (void (WINAPI
*)
1153 (LPSYSTEM_INFO
)) GetProcAddress (k32
, "GetNativeSystemInfo");
1154 SYSTEM_INFO natinfo
;
1155 nativinfo (&natinfo
);
1156 fputs ("\nRunning under WOW64 on ", stdout
);
1157 switch (natinfo
.wProcessorArchitecture
)
1159 case PROCESSOR_ARCHITECTURE_IA64
:
1162 case PROCESSOR_ARCHITECTURE_AMD64
:
1171 if (GetSystemMetrics (SM_REMOTESESSION
))
1172 printf ("\nRunning in Terminal Service session\n");
1175 char *s
= getenv ("PATH"), *e
;
1180 char sep
= strchr (s
, ';') ? ';' : ':';
1181 int count_path_items
= 0;
1184 for (e
= s
; *e
&& *e
!= sep
; e
++);
1186 printf ("\t%.*s\n", e
- s
, s
);
1198 char *cygwin
= getenv ("CYGWIN");
1200 cygwin
-= strlen ("CYGWIN=");
1202 cygwin
= const_cast <char *> ("CYGWIN=");
1203 size_t cyglen
= strlen (cygwin
);
1204 cygwin
= strcpy ((char *) malloc (cyglen
+ sizeof (" nontsec")), cygwin
);
1205 pretty_id ("nontsec", cygwin
, cyglen
);
1206 pretty_id ("ntsec", cygwin
, cyglen
);
1210 if (!GetSystemDirectory (tmp
, 4000))
1211 display_error ("dump_sysinfo: GetSystemDirectory()");
1212 printf ("\nSysDir: %s\n", tmp
);
1214 GetWindowsDirectory (tmp
, 4000);
1215 printf ("WinDir: %s\n\n", tmp
);
1219 printf ("Here's some environment variables that may affect cygwin:\n");
1220 for (i
= 0; environ
[i
]; i
++)
1222 char *eq
= strchr (environ
[i
], '=');
1225 /* int len = eq - environ[i]; */
1226 for (j
= 0; known_env_vars
[j
]; j
++)
1229 if (strcmp (environ
[i
], "PATH") == 0)
1230 continue; /* we handle this one specially */
1231 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1232 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1241 printf ("Here's the rest of your environment variables:\n");
1242 for (i
= 0; environ
[i
]; i
++)
1245 char *eq
= strchr (environ
[i
], '=');
1248 /* int len = eq - environ[i]; */
1249 for (j
= 0; known_env_vars
[j
]; j
++)
1252 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1259 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1269 printf ("Scanning registry for keys with 'Cygnus' in them...\n");
1271 /* big and not generally useful */
1272 scan_registry (0, HKEY_CLASSES_ROOT
, (char *) "HKEY_CLASSES_ROOT", 0);
1274 scan_registry (0, HKEY_CURRENT_CONFIG
,
1275 (char *) "HKEY_CURRENT_CONFIG", 0);
1276 scan_registry (0, HKEY_CURRENT_USER
, (char *) "HKEY_CURRENT_USER", 0);
1277 scan_registry (0, HKEY_LOCAL_MACHINE
, (char *) "HKEY_LOCAL_MACHINE", 0);
1279 /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */
1280 scan_registry (0, HKEY_USERS
, (char *) "HKEY_USERS", 0);
1285 printf ("Use '-r' to scan registry\n\n");
1289 printf ("Listing available drives...\n");
1290 printf ("Drv Type Size Used Flags Name\n");
1293 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
);
1294 int drivemask
= GetLogicalDrives ();
1296 BOOL (WINAPI
* gdfse
) (LPCSTR
, long long *, long long *, long long *) =
1297 (BOOL (WINAPI
*) (LPCSTR
, long long *, long long *, long long *))
1298 GetProcAddress (k32
, "GetDiskFreeSpaceExA");
1300 for (i
= 0; i
< 26; i
++)
1302 if (!(drivemask
& (1 << i
)))
1304 char drive
[4], name
[200], fsname
[200];
1305 DWORD serno
= 0, maxnamelen
= 0, flags
= 0;
1306 name
[0] = name
[0] = fsname
[0] = 0;
1307 sprintf (drive
, "%c:\\", i
+ 'a');
1308 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1309 ERROR_NOT_READY is returned when removeable media drives are empty
1310 (CD, floppy, etc.) */
1311 if (!GetVolumeInformation (drive
, name
, sizeof (name
), &serno
,
1312 &maxnamelen
, &flags
, fsname
,
1314 && GetLastError () != ERROR_NOT_READY
)
1316 # define FMT "dump_sysinfo: GetVolumeInformation() for drive %c:"
1317 char buf
[sizeof (FMT
)];
1318 sprintf (buf
, FMT
, 'A' + i
);
1319 display_error (buf
);
1323 int dtype
= GetDriveType (drive
);
1324 char drive_type
[4] = "unk";
1327 case DRIVE_REMOVABLE
:
1328 strcpy (drive_type
, "fd ");
1331 strcpy (drive_type
, "hd ");
1334 strcpy (drive_type
, "net");
1337 strcpy (drive_type
, "cd ");
1340 strcpy (drive_type
, "ram");
1343 strcpy (drive_type
, "unk");
1346 long capacity_mb
= -1;
1347 int percent_full
= -1;
1349 long long free_me
= 0ULL, free_bytes
= 0ULL, total_bytes
= 1ULL;
1350 if (gdfse
!= NULL
&& gdfse (drive
, &free_me
, &total_bytes
, &free_bytes
))
1352 capacity_mb
= total_bytes
/ (1024L * 1024L);
1353 percent_full
= 100 - (int) ((100.0 * free_me
) / total_bytes
);
1357 DWORD spc
= 0, bps
= 0, fc
= 0, tc
= 1;
1358 if (GetDiskFreeSpace (drive
, &spc
, &bps
, &fc
, &tc
))
1360 capacity_mb
= (spc
* bps
* tc
) / (1024 * 1024);
1361 percent_full
= 100 - (int) ((100.0 * fc
) / tc
);
1365 printf ("%.2s %s %-6s ", drive
, drive_type
, fsname
);
1366 if (capacity_mb
>= 0)
1367 printf ("%7dMb %3d%% ", (int) capacity_mb
, (int) percent_full
);
1369 printf (" N/A N/A ");
1370 printf ("%s %s %s %s %s %s %s\n",
1371 flags
& FS_CASE_IS_PRESERVED
? "CP" : " ",
1372 flags
& FS_CASE_SENSITIVE
? "CS" : " ",
1373 flags
& FS_UNICODE_STORED_ON_DISK
? "UN" : " ",
1374 flags
& FS_PERSISTENT_ACLS
? "PA" : " ",
1375 flags
& FS_FILE_COMPRESSION
? "FC" : " ",
1376 flags
& FS_VOL_IS_COMPRESSED
? "VC" : " ",
1378 flags
& FILE_SUPPORTS_ENCRYPTION
? "EN" : " ",
1379 flags
& FILE_SUPPORTS_OBJECT_IDS
? "OI" : " ",
1380 flags
& FILE_SUPPORTS_REPARSE_POINTS
? "RP" : " ",
1381 flags
& FILE_SUPPORTS_SPARSE_FILES
? "SP" : " ",
1382 flags
& FILE_VOLUME_QUOTAS
? "QU" : " ",
1387 if (!FreeLibrary (k32
))
1388 display_error ("dump_sysinfo: FreeLibrary()");
1389 SetErrorMode (prev_mode
);
1393 "fd = floppy, hd = hard drive, cd = CD-ROM\n"
1394 "net= Network Share, ram= RAM drive, unk= Unknown\n"
1395 "CP = Case Preserving, CS = Case Sensitive, UN = Unicode\n"
1396 "PA = Persistent ACLS, FC = File Compression, VC = Volume Compression");
1400 unsigned ml_fsname
= 4, ml_dir
= 7, ml_type
= 6;
1401 bool ml_trailing
= false;
1405 while ((mnt
= getmntent (0)))
1407 unsigned n
= (int) strlen (mnt
->mnt_fsname
);
1408 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_fsname
[n
- 1]));
1411 n
= (int) strlen (mnt
->mnt_dir
);
1412 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_dir
[n
- 1]));
1418 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1423 ("Mount entries: these map POSIX directories to your NT drives.\n");
1424 printf ("%-*s %-*s %-*s %s\n", ml_fsname
, "-NT-", ml_dir
, "-POSIX-",
1425 ml_type
, "-Type-", "-Flags-");
1429 while ((mnt
= getmntent (0)))
1431 printf ("%-*s %-*s %-*s %s\n",
1432 ml_fsname
, mnt
->mnt_fsname
,
1433 ml_dir
, mnt
->mnt_dir
, ml_type
, mnt
->mnt_type
, mnt
->mnt_opts
);
1437 add_path ((char *) "\\bin", 4); /* just in case */
1441 ("Looking to see where common programs can be found, if at all...\n");
1442 for (i
= 0; common_apps
[i
].name
; i
++)
1443 if (!find_on_path ((char *) common_apps
[i
].name
, (char *) ".exe", 1, 0))
1445 if (common_apps
[i
].missing_is_good
)
1446 printf ("Not Found: %s (good!)\n", common_apps
[i
].name
);
1448 printf ("Not Found: %s\n", common_apps
[i
].name
);
1453 printf ("Looking for various Cygwin DLLs... (-v gives version info)\n");
1454 int cygwin_dll_count
= 0;
1455 for (i
= 1; i
< num_paths
; i
++)
1457 WIN32_FIND_DATA ffinfo
;
1458 sprintf (tmp
, "%s/*.*", paths
[i
]);
1459 HANDLE ff
= FindFirstFile (tmp
, &ffinfo
);
1460 int found
= (ff
!= INVALID_HANDLE_VALUE
);
1461 found_cygwin_dll
= NULL
;
1464 char *f
= ffinfo
.cFileName
;
1465 if (strcasecmp (f
+ strlen (f
) - 4, ".dll") == 0)
1467 if (strncasecmp (f
, "cyg", 3) == 0)
1469 sprintf (tmp
, "%s\\%s", paths
[i
], f
);
1470 if (strcasecmp (f
, "cygwin1.dll") == 0)
1473 found_cygwin_dll
= strdup (tmp
);
1479 found
= FindNextFile (ff
, &ffinfo
);
1481 if (found_cygwin_dll
)
1483 ls (found_cygwin_dll
);
1484 free (found_cygwin_dll
);
1489 if (cygwin_dll_count
> 1)
1490 puts ("Warning: There are multiple cygwin1.dlls on your path");
1491 if (!cygwin_dll_count
)
1492 puts ("Warning: cygwin1.dll not found on your path");
1495 dump_sysinfo_services ();
1501 HANDLE h
= CreateFileA ("CONIN$", GENERIC_READ
| GENERIC_WRITE
,
1502 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
1503 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1505 if (h
== INVALID_HANDLE_VALUE
|| h
== NULL
)
1506 return (display_error ("check_keys: Opening CONIN$"));
1510 if (!GetConsoleMode (h
, &mode
))
1511 display_error ("check_keys: GetConsoleMode()");
1514 mode
&= ~ENABLE_PROCESSED_INPUT
;
1515 if (!SetConsoleMode (h
, mode
))
1516 display_error ("check_keys: SetConsoleMode()");
1519 fputs ("\nThis key check works only in a console window,", stderr
);
1520 fputs (" _NOT_ in a terminal session!\n", stderr
);
1521 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr
);
1522 fputs ("Press 'q' to exit.\n", stderr
);
1524 INPUT_RECORD in
, prev_in
;
1526 // Drop first <RETURN> key
1527 ReadConsoleInput (h
, &in
, 1, &mode
);
1529 memset (&in
, 0, sizeof in
);
1534 if (!ReadConsoleInput (h
, &in
, 1, &mode
))
1535 display_error ("check_keys: ReadConsoleInput()");
1537 if (!memcmp (&in
, &prev_in
, sizeof in
))
1540 switch (in
.EventType
)
1543 printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ",
1544 in
.Event
.KeyEvent
.bKeyDown
? "Pressed " : "Released",
1545 in
.Event
.KeyEvent
.wRepeatCount
,
1546 in
.Event
.KeyEvent
.wVirtualKeyCode
,
1547 in
.Event
.KeyEvent
.wVirtualScanCode
,
1548 (unsigned char) in
.Event
.KeyEvent
.uChar
.AsciiChar
);
1549 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& CAPSLOCK_ON
?
1550 "CL " : "-- ", stdout
);
1551 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& ENHANCED_KEY
?
1552 "EK " : "-- ", stdout
);
1553 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_ALT_PRESSED
?
1554 "LA " : "-- ", stdout
);
1555 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_CTRL_PRESSED
?
1556 "LC " : "-- ", stdout
);
1557 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& NUMLOCK_ON
?
1558 "NL " : "-- ", stdout
);
1559 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
?
1560 "RA " : "-- ", stdout
);
1561 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_CTRL_PRESSED
?
1562 "RC " : "-- ", stdout
);
1563 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SCROLLLOCK_ON
?
1564 "SL " : "-- ", stdout
);
1565 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
?
1566 "SH " : "-- ", stdout
);
1567 fputc ('\n', stdout
);
1574 while (in
.EventType
!= KEY_EVENT
||
1575 in
.Event
.KeyEvent
.bKeyDown
!= FALSE
||
1576 in
.Event
.KeyEvent
.uChar
.AsciiChar
!= 'q');
1582 /* RFC1738 says that these do not need to be escaped. */
1583 static const char safe_chars
[] = "$-_.+!*'(),";
1585 /* the URL to query. */
1586 static const char base_url
[] =
1587 "http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep=";
1589 /* Queries Cygwin web site for packages containing files matching a regexp.
1590 Return value is 1 if there was a problem, otherwise 0. */
1592 package_grep (char *search
)
1596 /* Attempt to dynamically load the necessary WinInet API functions so that
1597 cygcheck can still function on older systems without IE. */
1599 if (!(hWinInet
= LoadLibrary ("wininet.dll")))
1601 fputs ("Unable to locate WININET.DLL. This feature requires Microsoft "
1602 "Internet Explorer v3 or later to function.\n", stderr
);
1606 /* InternetCloseHandle is used outside this function so it is declared
1607 global. The rest of these functions are only used here, so declare them
1608 and call GetProcAddress for each of them with the following macro. */
1610 pInternetCloseHandle
= (BOOL (WINAPI
*) (HINTERNET
))
1611 GetProcAddress (hWinInet
, "InternetCloseHandle");
1612 #define make_func_pointer(name, ret, args) ret (WINAPI * p##name) args = \
1613 (ret (WINAPI *) args) GetProcAddress (hWinInet, #name);
1614 make_func_pointer (InternetAttemptConnect
, DWORD
, (DWORD
));
1615 make_func_pointer (InternetOpenA
, HINTERNET
, (LPCSTR
, DWORD
, LPCSTR
, LPCSTR
,
1617 make_func_pointer (InternetOpenUrlA
, HINTERNET
, (HINTERNET
, LPCSTR
, LPCSTR
,
1618 DWORD
, DWORD
, DWORD
));
1619 make_func_pointer (InternetReadFile
, BOOL
, (HINTERNET
, PVOID
, DWORD
, PDWORD
));
1620 make_func_pointer (HttpQueryInfoA
, BOOL
, (HINTERNET
, DWORD
, PVOID
, PDWORD
,
1622 #undef make_func_pointer
1624 if(!pInternetCloseHandle
|| !pInternetAttemptConnect
|| !pInternetOpenA
1625 || !pInternetOpenUrlA
|| !pInternetReadFile
|| !pHttpQueryInfoA
)
1627 fputs ("Unable to load one or more functions from WININET.DLL. This "
1628 "feature requires Microsoft Internet Explorer v3 or later to "
1629 "function.\n", stderr
);
1633 /* construct the actual URL by escaping */
1634 char *url
= (char *) alloca (sizeof (base_url
) + strlen (search
) * 3);
1635 strcpy (url
, base_url
);
1638 for (dest
= &url
[sizeof (base_url
) - 1]; *search
; search
++)
1640 if (isalnum (*search
)
1641 || memchr (safe_chars
, *search
, sizeof (safe_chars
) - 1))
1648 sprintf (dest
, "%02x", (unsigned char) *search
);
1654 /* Connect to the net and open the URL. */
1655 if (pInternetAttemptConnect (0) != ERROR_SUCCESS
)
1657 fputs ("An internet connection is required for this function.\n", stderr
);
1661 /* Initialize WinInet and attempt to fetch our URL. */
1662 HINTERNET hi
= NULL
, hurl
= NULL
;
1663 if (!(hi
= pInternetOpenA ("cygcheck", INTERNET_OPEN_TYPE_PRECONFIG
, NULL
, NULL
, 0)))
1664 return display_internet_error ("InternetOpen() failed", NULL
);
1666 if (!(hurl
= pInternetOpenUrlA (hi
, url
, NULL
, 0, 0, 0)))
1667 return display_internet_error ("unable to contact cygwin.com site, "
1668 "InternetOpenUrl() failed", hi
, NULL
);
1670 /* Check the HTTP response code. */
1671 DWORD rc
= 0, rc_s
= sizeof (DWORD
);
1672 if (!pHttpQueryInfoA (hurl
, HTTP_QUERY_STATUS_CODE
| HTTP_QUERY_FLAG_NUMBER
,
1673 (void *) &rc
, &rc_s
, NULL
))
1674 return display_internet_error ("HttpQueryInfo() failed", hurl
, hi
, NULL
);
1676 if (rc
!= HTTP_STATUS_OK
)
1678 sprintf (buf
, "error retrieving results from cygwin.com site, "
1679 "HTTP status code %lu", rc
);
1680 return display_internet_error (buf
, hurl
, hi
, NULL
);
1683 /* Fetch result and print to stdout. */
1687 if (!pInternetReadFile (hurl
, (void *) buf
, sizeof (buf
), &numread
))
1688 return display_internet_error ("InternetReadFile failed", hurl
, hi
, NULL
);
1690 fwrite ((void *) buf
, (size_t) numread
, 1, stdout
);
1694 pInternetCloseHandle (hurl
);
1695 pInternetCloseHandle (hi
);
1700 usage (FILE * stream
, int status
)
1703 Usage: cygcheck PROGRAM [ -v ] [ -h ]\n\
1704 cygcheck -c [ PACKAGE ] [ -d ]\n\
1705 cygcheck -s [ -r ] [ -v ] [ -h ]\n\
1707 cygcheck -f FILE [ FILE ... ]\n\
1708 cygcheck -l [ PACKAGE ] [ PACKAGE ... ]\n\
1709 cygcheck -p REGEXP\n\
1710 List system information, check installed packages, or query package database.\n\
1712 At least one command option or a PROGRAM is required, as shown above.\n\
1714 PROGRAM list library (DLL) dependencies of PROGRAM\n\
1715 -c, --check-setup show installed version of PACKAGE and verify integrity\n\
1716 (or for all installed packages if none specified)\n\
1717 -d, --dump-only just list packages, do not verify (with -c)\n\
1718 -s, --sysinfo produce diagnostic system information (implies -c -d)\n\
1719 -r, --registry also scan registry for Cygwin settings (with -s)\n\
1720 -k, --keycheck perform a keyboard check session (must be run from a\n\
1721 plain console only, not from a pty/rxvt/xterm)\n\
1722 -f, --find-package find the package that FILE belongs to\n\
1723 -l, --list-package list contents of PACKAGE (or all packages if none given)\n\
1724 -p, --package-query search for REGEXP in the entire cygwin.com package\n\
1725 repository (requies internet connectivity)\n\
1726 -v, --verbose produce more verbose output\n\
1727 -h, --help annotate output with explanatory comments when given\n\
1728 with another command, otherwise print this help\n\
1729 -V, --version print the version of cygcheck and exit\n\
1731 Note: -c, -f, and -l only report on packages that are currently installed. To\n\
1732 search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
1733 package names, descriptions, and names of files/paths within all packages.\n\
1738 struct option longopts
[] = {
1739 {"check-setup", no_argument
, NULL
, 'c'},
1740 {"dump-only", no_argument
, NULL
, 'd'},
1741 {"sysinfo", no_argument
, NULL
, 's'},
1742 {"registry", no_argument
, NULL
, 'r'},
1743 {"verbose", no_argument
, NULL
, 'v'},
1744 {"keycheck", no_argument
, NULL
, 'k'},
1745 {"find-package", no_argument
, NULL
, 'f'},
1746 {"list-package", no_argument
, NULL
, 'l'},
1747 {"package-query", no_argument
, NULL
, 'p'},
1748 {"help", no_argument
, NULL
, 'h'},
1749 {"version", no_argument
, 0, 'V'},
1750 {0, no_argument
, NULL
, 0}
1753 static char opts
[] = "cdsrvkflphV";
1758 const char *v
= strchr (version
, ':');
1768 len
= strchr (v
, ' ') - v
;
1771 cygcheck version %.*s\n\
1772 System Checker for Cygwin\n\
1773 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.\n\
1775 ", len
, v
, __DATE__
);
1781 int n
= 1 + strchr (ev
, '=') - ev
;
1782 char *s
= (char *) alloca (n
+ 1);
1789 unsigned long (*cygwin_internal
) (int, ...);
1793 load_cygwin (int& argc
, char **&argv
)
1797 if (!(h
= LoadLibrary ("cygwin1.dll")))
1799 if (!(cygwin_internal
= (DWORD (*) (int, ...)) GetProcAddress (h
, "cygwin_internal")))
1802 char **av
= (char **) cygwin_internal (CW_ARGV
);
1803 if (av
&& ((DWORD
) av
!= (DWORD
) -1))
1804 for (argc
= 0, argv
= av
; *av
; av
++)
1807 char **envp
= (char **) cygwin_internal (CW_ENVP
);
1808 if (envp
&& ((DWORD
) envp
!= (DWORD
) -1))
1810 /* Store path and revert to this value, otherwise path gets overwritten
1811 by the POSIXy Cygwin variation, which breaks cygcheck.
1812 Another approach would be to use the Cygwin PATH and convert it to
1816 while (*(env
= _environ
))
1818 if (strncmp (*env
, "PATH=", 5) == 0)
1819 path
= strdup (*env
);
1822 for (char **ev
= envp
; *ev
; ev
++)
1823 if (strncmp (*ev
, "PATH=", 5) != 0)
1831 main (int argc
, char **argv
)
1835 load_cygwin (argc
, argv
);
1837 (void) putenv("POSIXLY_CORRECT=1");
1838 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
1880 if (argc
== 0 && !sysinfo
&& !keycheck
&& !check_setup
&& !list_package
)
1886 if ((check_setup
|| sysinfo
|| find_package
|| list_package
|| grep_packages
)
1890 if ((find_package
|| list_package
|| grep_packages
) && check_setup
)
1893 if (dump_only
&& !check_setup
)
1896 if (find_package
+ list_package
+ grep_packages
> 1)
1900 return check_keys ();
1902 return package_grep (*argv
);
1906 /* FIXME: Add help for check_setup and {list,find}_package */
1907 if (argc
>= 1 && givehelp
&& !check_setup
&& !find_package
&& !list_package
)
1909 printf("Here is where the OS will find your program%s, and which dlls\n",
1910 argc
> 1 ? "s" : "");
1911 printf ("will be used for it. Use -v to see DLL version info\n");
1918 dump_setup (verbose
, argv
, !dump_only
);
1919 else if (find_package
)
1920 package_find (verbose
, argv
);
1921 else if (list_package
)
1922 package_list (verbose
, argv
);
1924 for (i
= 0; i
< argc
; i
++)
1928 ok
&= cygcheck (argv
[i
]);
1937 dump_setup (verbose
, NULL
, false);
1941 puts ("Use -h to see help about each section");
1944 return ok
? EXIT_SUCCESS
: EXIT_FAILURE
;