3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
11 #define cygwin_internal cygwin_internal_dontuse
23 #include "cygwin/include/sys/cygwin.h"
24 #include "cygwin/include/mntent.h"
25 #undef cygwin_internal
27 #define alloca __builtin_alloca
38 int grep_packages
= 0;
40 /* This is global because it's used in both internet_display_error as well
42 BOOL (WINAPI
*pInternetCloseHandle
) (HINTERNET
);
45 typedef long long longlong
;
47 typedef __int64 longlong
;
50 void dump_setup (int, char **, bool);
51 void package_find (int, char **);
52 void package_list (int, char **);
54 static const char version
[] = "$Revision$";
56 static const char *known_env_vars
[] = {
64 "gcc_default_options",
86 static common_apps
[] = {
114 static int num_paths
= 0, max_paths
= 0;
115 static char **paths
= 0;
118 eprintf (const char *format
, ...)
121 va_start (ap
, format
);
122 vfprintf (stderr
, format
, ap
);
127 * display_error() is used to report failure modes
130 display_error (const char *name
, bool show_error
= true, bool print_failed
= true)
133 fprintf (stderr
, "cygcheck: %s%s: %lu\n", name
,
134 print_failed
? " failed" : "", GetLastError ());
136 fprintf (stderr
, "cygcheck: %s%s\n", name
,
137 print_failed
? " failed" : "");
141 /* Display a WinInet error message, and close a variable number of handles.
142 (Passed a list of handles terminated by NULL.) */
144 display_internet_error (const char *message
, ...)
146 DWORD err
= GetLastError ();
151 /* in the case of a successful connection but 404 response, there is no
152 win32 error message, but we still get passed a message to display. */
155 if (FormatMessage (FORMAT_MESSAGE_FROM_HMODULE
,
156 GetModuleHandle ("wininet.dll"), err
, 0, err_buf
,
157 sizeof (err_buf
), NULL
) == 0)
158 strcpy (err_buf
, "(Unknown error)");
160 fprintf (stderr
, "cygcheck: %s: %s (win32 error %d)\n", message
,
164 fprintf (stderr
, "cygcheck: %s\n", message
);
166 va_start (hptr
, message
);
167 while ((h
= va_arg (hptr
, HINTERNET
)) != 0)
168 pInternetCloseHandle (h
);
175 add_path (char *s
, int maxlen
)
177 if (num_paths
>= max_paths
)
181 paths
= (char **) realloc (paths
, max_paths
* sizeof (char *));
183 paths
= (char **) malloc (max_paths
* sizeof (char *));
185 paths
[num_paths
] = (char *) malloc (maxlen
+ 1);
186 if (paths
[num_paths
] == NULL
)
188 display_error ("add_path: malloc()");
191 memcpy (paths
[num_paths
], s
, maxlen
);
192 paths
[num_paths
][maxlen
] = 0;
193 char *e
= paths
[num_paths
] + strlen (paths
[num_paths
]);
194 if (e
[-1] == '\\' && e
[-2] != ':')
196 for (int i
= 1; i
< num_paths
; i
++)
197 if (strcasecmp (paths
[num_paths
], paths
[i
]) == 0)
199 free (paths
[num_paths
]);
209 add_path ((char *) ".", 1); /* to be replaced later */
211 if (GetCurrentDirectory (4000, tmp
))
212 add_path (tmp
, strlen (tmp
));
214 display_error ("init_paths: GetCurrentDirectory()");
216 if (GetSystemDirectory (tmp
, 4000))
217 add_path (tmp
, strlen (tmp
));
219 display_error ("init_paths: GetSystemDirectory()");
220 sl
= strrchr (tmp
, '\\');
223 strcpy (sl
, "\\SYSTEM");
224 add_path (tmp
, strlen (tmp
));
226 GetWindowsDirectory (tmp
, 4000);
227 add_path (tmp
, strlen (tmp
));
229 char *wpath
= getenv ("PATH");
236 for (e
= b
; *e
&& *e
!= ';'; e
++);
237 if (strncmp(b
, ".", 1) && strncmp(b
, ".\\", 2))
245 printf ("WARNING: PATH is not set at all!\n");
249 find_on_path (char *file
, char *default_extension
,
250 int showall
= 0, int search_sysdirs
= 0)
252 static char rv
[4000];
253 char tmp
[4000], *ptr
= rv
;
257 display_error ("find_on_path: NULL pointer for file", false, false);
261 if (default_extension
== NULL
)
263 display_error ("find_on_path: NULL pointer for default_extension", false, false);
267 if (strchr (file
, ':') || strchr (file
, '\\') || strchr (file
, '/'))
269 char *fn
= cygpath (file
, NULL
);
270 if (access (fn
, F_OK
) == 0)
273 strcat (rv
, default_extension
);
274 return access (rv
, F_OK
) == 0 ? rv
: fn
;
277 if (strchr (file
, '.'))
278 default_extension
= (char *) "";
280 for (int i
= 0; i
< num_paths
; i
++)
282 if (!search_sysdirs
&& (i
== 0 || i
== 2 || i
== 3))
284 if (i
== 0 || !search_sysdirs
|| strcasecmp (paths
[i
], paths
[0]))
286 sprintf (ptr
, "%s\\%s%s", paths
[i
], file
, default_extension
);
287 if (GetFileAttributes (ptr
) != (DWORD
) - 1)
290 printf ("Found: %s\n", ptr
);
291 if (ptr
== tmp
&& verbose
)
292 printf ("Warning: %s hides %s\n", rv
, ptr
);
306 #define DID_INACTIVE 3
317 already_did (char *file
)
320 for (d
= did
; d
; d
= d
->next
)
321 if (strcasecmp (d
->file
, file
) == 0)
323 d
= (Did
*) malloc (sizeof (Did
));
324 d
->file
= strdup (file
);
332 get_word (HANDLE fh
, int offset
)
337 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
338 && GetLastError () != NO_ERROR
)
339 display_error ("get_word: SetFilePointer()");
341 if (!ReadFile (fh
, &rv
, 2, (DWORD
*) &r
, 0))
342 display_error ("get_word: Readfile()");
348 get_dword (HANDLE fh
, int offset
)
353 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
354 && GetLastError () != NO_ERROR
)
355 display_error ("get_dword: SetFilePointer()");
357 if (!ReadFile (fh
, &rv
, 4, (DWORD
*) &r
, 0))
358 display_error ("get_dword: Readfile()");
368 int size_of_raw_data
;
369 int pointer_to_raw_data
;
373 rva_to_offset (int rva
, char *sections
, int nsections
, int *sz
)
377 if (sections
== NULL
)
379 display_error ("rva_to_offset: NULL passed for sections", true, false);
383 for (i
= 0; i
< nsections
; i
++)
385 Section
*s
= (Section
*) (sections
+ i
* 40);
387 printf ("%08x < %08x < %08x ? %08x\n",
388 s
->virtual_address
, rva
,
389 s
->virtual_address
+ s
->virtual_size
, s
->pointer_to_raw_data
);
391 if (rva
>= s
->virtual_address
392 && rva
< s
->virtual_address
+ s
->virtual_size
)
395 *sz
= s
->virtual_address
+ s
->virtual_size
- rva
;
396 return rva
- s
->virtual_address
+ s
->pointer_to_raw_data
;
413 unsigned characteristics
;
415 unsigned forwarder_chain
;
421 static bool track_down (char *file
, char *suffix
, int lvl
);
423 #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
425 cygwin_info (HANDLE h
)
427 char *buf
, *bufend
, *buf_start
= NULL
;
428 const char *hello
= " Cygwin DLL version info:\n";
429 DWORD size
= GetFileSize (h
, NULL
);
432 if (size
== 0xffffffff)
435 buf_start
= buf
= (char *) calloc (1, size
+ 1);
438 display_error ("cygwin_info: calloc()");
442 (void) SetFilePointer (h
, 0, NULL
, FILE_BEGIN
);
443 if (!ReadFile (h
, buf
, size
, &n
, NULL
))
449 static char dummy
[] = "\0\0\0\0\0\0\0";
450 char *dll_major
= dummy
;
453 if ((buf
= (char *) memchr (buf
, '%', bufend
- buf
)) == NULL
)
455 else if (strncmp ("%%% Cygwin ", buf
, CYGPREFIX
) != 0)
459 char *p
= strchr (buf
+= CYGPREFIX
, '\n');
462 if (strncasecmp (buf
, "dll major:", 10) == 0)
464 dll_major
= buf
+ 11;
470 if (strncasecmp (buf
, "dll minor:", 10) != 0)
474 char c
= dll_major
[1];
476 int maj
= atoi (dll_major
);
478 int min
= atoi (dll_major
+ 1);
479 sprintf (pbuf
, "DLL version: %d.%d.%.*s", maj
, min
, len
- 11,
481 len
= strlen (s
= pbuf
);
483 if (strncmp (s
, "dll", 3) == 0)
484 memcpy (s
, "DLL", 3);
485 else if (strncmp (s
, "api", 3) == 0)
486 memcpy (s
, "API", 3);
487 else if (islower (*s
))
489 fprintf (stdout
, "%s %.*s", hello
, len
, s
);
501 dll_info (const char *path
, HANDLE fh
, int lvl
, int recurse
)
505 int pe_header_offset
= get_dword (fh
, 0x3c);
506 int opthdr_ofs
= pe_header_offset
+ 4 + 20;
511 display_error ("dll_info: NULL passed for path", true, false);
515 if (SetFilePointer (fh
, opthdr_ofs
+ 40, 0, FILE_BEGIN
) ==
516 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
517 display_error ("dll_info: SetFilePointer()");
519 if (!ReadFile (fh
, &v
, sizeof (v
), &junk
, 0))
520 display_error ("dll_info: Readfile()");
523 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
524 v
[0], v
[1], v
[2], v
[3], v
[4], v
[5]);
528 int num_entries
= get_dword (fh
, opthdr_ofs
+ 92);
529 int export_rva
= get_dword (fh
, opthdr_ofs
+ 96);
530 int export_size
= get_dword (fh
, opthdr_ofs
+ 100);
531 int import_rva
= get_dword (fh
, opthdr_ofs
+ 104);
532 int import_size
= get_dword (fh
, opthdr_ofs
+ 108);
534 int nsections
= get_word (fh
, pe_header_offset
+ 4 + 2);
535 char *sections
= (char *) malloc (nsections
* 40);
537 if (SetFilePointer (fh
, pe_header_offset
+ 4 + 20 +
538 get_word (fh
, pe_header_offset
+ 4 + 16), 0,
539 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
540 && GetLastError () != NO_ERROR
)
541 display_error ("dll_info: SetFilePointer()");
543 if (!ReadFile (fh
, sections
, nsections
* 40, &junk
, 0))
544 display_error ("dll_info: Readfile()");
546 if (verbose
&& num_entries
>= 1 && export_size
> 0)
549 int expbase
= rva_to_offset (export_rva
, sections
, nsections
, &expsz
);
553 if (SetFilePointer (fh
, expbase
, 0, FILE_BEGIN
) ==
554 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
555 display_error ("dll_info: SetFilePointer()");
557 unsigned char *exp
= (unsigned char *) malloc (expsz
);
559 if (!ReadFile (fh
, exp
, expsz
, &junk
, 0))
560 display_error ("dll_info: Readfile()");
562 ExpDirectory
*ed
= (ExpDirectory
*) exp
;
563 int ofs
= ed
->name_rva
- export_rva
;
564 struct tm
*tm
= localtime ((const time_t *) &(ed
->timestamp
));
565 if (tm
->tm_year
< 60)
567 if (tm
->tm_year
< 200)
569 printf ("%*c", lvl
+ 2, ' ');
570 printf ("\"%s\" v%d.%d ts=", exp
+ ofs
,
571 ed
->major_ver
, ed
->minor_ver
);
572 printf ("%d/%d/%d %d:%02d\n",
573 tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
,
574 tm
->tm_hour
, tm
->tm_min
);
578 if (num_entries
>= 2 && import_size
> 0 && recurse
)
581 int impbase
= rva_to_offset (import_rva
, sections
, nsections
, &impsz
);
584 if (SetFilePointer (fh
, impbase
, 0, FILE_BEGIN
) ==
585 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
586 display_error ("dll_info: SetFilePointer()");
588 unsigned char *imp
= (unsigned char *) malloc (impsz
);
591 display_error ("dll_info: malloc()");
595 if (!ReadFile (fh
, imp
, impsz
, &junk
, 0))
596 display_error ("dll_info: Readfile()");
598 ImpDirectory
*id
= (ImpDirectory
*) imp
;
599 for (i
= 0; id
[i
].name_rva
; i
++)
601 /* int ofs = id[i].name_rva - import_rva; */
602 track_down ((char *) imp
+ id
[i
].name_rva
- import_rva
,
603 (char *) ".dll", lvl
+ 2);
607 if (strstr (path
, "\\cygwin1.dll"))
611 // Return true on success, false if error printed
613 track_down (char *file
, char *suffix
, int lvl
)
617 display_error ("track_down: NULL passed for file", true, false);
623 display_error ("track_down: NULL passed for suffix", false, false);
627 char *path
= find_on_path (file
, suffix
, 0, 1);
630 printf ("Error: could not find %s\n", file
);
634 Did
*d
= already_did (file
);
643 printf ("%*c", lvl
, ' ');
645 printf (" (recursive)\n");
652 printf ("%*c", lvl
, ' ');
654 printf (" (already done)\n");
662 printf ("%*c", lvl
, ' ');
666 printf ("%s not found\n", file
);
673 CreateFile (path
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
674 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
675 if (fh
== INVALID_HANDLE_VALUE
)
677 printf (" - Cannot open\n");
681 d
->state
= DID_ACTIVE
;
683 dll_info (path
, fh
, lvl
, 1);
684 d
->state
= DID_INACTIVE
;
685 if (!CloseHandle (fh
))
686 display_error ("track_down: CloseHandle()");
693 HANDLE h
= CreateFile (f
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
694 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
695 BY_HANDLE_FILE_INFORMATION info
;
697 if (!GetFileInformationByHandle (h
, &info
))
698 display_error ("ls: GetFileInformationByHandle()");
702 if (!FileTimeToSystemTime (&info
.ftLastWriteTime
, &systime
))
703 display_error ("ls: FileTimeToSystemTime()");
704 printf ("%5dk %04d/%02d/%02d %s",
705 (((int) info
.nFileSizeLow
) + 512) / 1024,
706 systime
.wYear
, systime
.wMonth
, systime
.wDay
, f
);
707 dll_info (f
, h
, 16, 0);
708 if (!CloseHandle (h
))
709 display_error ("ls: CloseHandle()");
712 // Return true on success, false if error printed
716 char *papp
= find_on_path (app
, (char *) ".exe", 1, 0);
719 printf ("Error: could not find %s\n", app
);
722 char *s
= strdup (papp
);
725 if (*t
== '/' || *t
== '\\' || *t
== ':')
728 paths
[0] = (char *) ".";
735 return track_down (papp
, (char *) ".exe", 0);
739 extern char **environ
;
749 show_reg (RegInfo
* ri
, int nest
)
753 show_reg (ri
->prev
, 1);
755 printf ("%s\\", ri
->name
);
757 printf ("%s\n", ri
->name
);
761 scan_registry (RegInfo
* prev
, HKEY hKey
, char *name
, int cygnus
)
769 for (cp
= name
; *cp
; cp
++)
770 if (strncasecmp (cp
, "cygnus", 6) == 0)
773 DWORD num_subkeys
, max_subkey_len
, num_values
;
774 DWORD max_value_len
, max_valdata_len
, i
;
775 if (RegQueryInfoKey (hKey
, 0, 0, 0, &num_subkeys
, &max_subkey_len
, 0,
776 &num_values
, &max_value_len
, &max_valdata_len
, 0, 0)
781 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, 0, GetLastError (),
782 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
), tmp
, 400, 0);
783 printf ("RegQueryInfoKey: %s\n", tmp
);
792 char *value_name
= (char *) malloc (max_value_len
+ 1);
793 if (value_name
== NULL
)
795 display_error ("scan_registry: malloc()");
799 char *value_data
= (char *) malloc (max_valdata_len
+ 1);
800 if (value_data
== NULL
)
802 display_error ("scan_registry: malloc()");
806 for (i
= 0; i
< num_values
; i
++)
808 DWORD dlen
= max_valdata_len
+ 1;
809 DWORD nlen
= max_value_len
+ 1;
811 RegEnumValue (hKey
, i
, value_name
, &nlen
, 0,
812 &type
, (BYTE
*) value_data
, &dlen
);
814 printf (" %s = ", i
? value_name
: "(default)");
818 printf ("0x%08x\n", *(unsigned *) value_data
);
822 printf ("'%s'\n", value_data
);
825 printf ("(unsupported type)\n");
834 char *subkey_name
= (char *) malloc (max_subkey_len
+ 1);
835 for (i
= 0; i
< num_subkeys
; i
++)
837 if (RegEnumKey (hKey
, i
, subkey_name
, max_subkey_len
+ 1) ==
841 if (RegOpenKeyEx (hKey
, subkey_name
, 0, KEY_READ
, &sKey
)
844 scan_registry (&ri
, sKey
, subkey_name
, cygnus
);
845 if (RegCloseKey (sKey
) != ERROR_SUCCESS
)
846 display_error ("scan_registry: RegCloseKey()");
854 pretty_id (const char *s
, char *cygwin
, size_t cyglen
)
858 strcpy (cygwin
+ cyglen
++, " ");
859 strcpy (cygwin
+ cyglen
, s
);
862 char *id
= cygpath ("/bin/id.exe", NULL
);
863 for (char *p
= id
; (p
= strchr (p
, '/')); p
++)
866 if (access (id
, X_OK
))
868 fprintf (stderr
, "'id' program not found\n");
872 FILE *f
= popen (id
, "rt");
876 fgets (buf
, sizeof (buf
), f
);
878 char *uid
= strtok (buf
, ")");
880 uid
+= strlen ("uid=");
883 fprintf (stderr
, "garbled output from 'id' command - no uid= found\n");
886 char *gid
= strtok (NULL
, ")");
888 gid
+= strlen ("gid=") + 1;
891 fprintf (stderr
, "garbled output from 'id' command - no gid= found\n");
895 char **ng
= groups
- 1;
896 size_t len_uid
= strlen ("UID: )") + strlen (uid
);
897 size_t len_gid
= strlen ("GID: )") + strlen (gid
);
898 *++ng
= groups
[0] = (char *) alloca (len_uid
+ 1);
899 *++ng
= groups
[1] = (char *) alloca (len_gid
+ 1);
900 sprintf (groups
[0], "UID: %s)", uid
);
901 sprintf (groups
[1], "GID: %s)", gid
);
902 size_t sz
= max (len_uid
, len_gid
);
903 while ((*++ng
= strtok (NULL
, ",")))
905 char *p
= strchr (*ng
, '\n');
908 if (ng
== groups
+ 2)
909 *ng
+= strlen (" groups=");
910 size_t len
= strlen (*ng
);
916 printf ("\nOutput from %s (%s)\n", id
, s
);
917 int n
= 80 / (int) ++sz
;
918 int i
= n
> 2 ? n
- 2 : 0;
920 for (char **g
= groups
; g
<= ng
; g
++)
921 if ((g
!= ng
) && (++i
< n
))
922 printf ("%*s", sz
, *g
);
930 /* This dumps information about each installed cygwin service, if cygrunsrv
933 dump_sysinfo_services ()
938 bool no_services
= false;
941 printf ("\nChecking for any Cygwin services... %s\n\n",
942 verbose
? "" : "(use -v for more detail)");
944 fputc ('\n', stdout
);
946 /* find the location of cygrunsrv.exe */
947 char *cygrunsrv
= cygpath ("/bin/cygrunsrv.exe", NULL
);
948 for (char *p
= cygrunsrv
; (p
= strchr (p
, '/')); p
++)
951 if (access (cygrunsrv
, X_OK
))
953 puts ("Can't find the cygrunsrv utility, skipping services check.\n");
957 /* check for a recent cygrunsrv */
958 snprintf (buf
, sizeof (buf
), "%s --version", cygrunsrv
);
959 if ((f
= popen (buf
, "rt")) == NULL
)
961 printf ("Failed to execute '%s', skipping services check.\n", buf
);
965 int ret
= fscanf (f
, "cygrunsrv V%u.%u", &maj
, &min
);
966 if (ferror (f
) || feof (f
) || ret
== EOF
|| maj
< 1 || min
< 10)
968 puts ("The version of cygrunsrv installed is too old to dump service info.\n");
973 /* For verbose mode, just run cygrunsrv --list --verbose and copy output
974 verbatim; otherwise run cygrunsrv --list and then cygrunsrv --query for
976 snprintf (buf
, sizeof (buf
), (verbose
? "%s --list --verbose" : "%s --list"),
978 if ((f
= popen (buf
, "rt")) == NULL
)
980 printf ("Failed to execute '%s', skipping services check.\n", buf
);
986 /* copy output to stdout */
988 while (!feof (f
) && !ferror (f
))
989 nchars
+= fwrite ((void *) buf
, 1,
990 fread ((void *) buf
, 1, sizeof (buf
), f
), stdout
);
992 /* cygrunsrv outputs nothing if there are no cygwin services found */
999 /* read the output of --list, and then run --query for each service */
1000 size_t nchars
= fread ((void *) buf
, 1, sizeof (buf
) - 1, f
);
1005 for (char *srv
= strtok (buf
, "\n"); srv
; srv
= strtok (NULL
, "\n"))
1007 snprintf (buf2
, sizeof (buf2
), "%s --query %s", cygrunsrv
, srv
);
1008 if ((f
= popen (buf2
, "rt")) == NULL
)
1010 printf ("Failed to execute '%s', skipping services check.\n", buf2
);
1014 /* copy output to stdout */
1015 while (!feof (f
) && !ferror (f
))
1016 fwrite ((void *) buf2
, 1,
1017 fread ((void *) buf2
, 1, sizeof (buf2
), f
), stdout
);
1024 /* inform the user if nothing found */
1026 puts ("No Cygwin services found.\n");
1035 char *found_cygwin_dll
;
1038 printf ("\nCygwin Configuration Diagnostics\n");
1040 printf ("Current System Time: %s\n", ctime (&now
));
1042 OSVERSIONINFO osversion
;
1043 osversion
.dwOSVersionInfoSize
= sizeof (osversion
);
1044 if (!GetVersionEx (&osversion
))
1045 display_error ("dump_sysinfo: GetVersionEx()");
1046 const char *osname
= "unknown OS";
1047 switch (osversion
.dwPlatformId
)
1049 case VER_PLATFORM_WIN32s
:
1052 case VER_PLATFORM_WIN32_WINDOWS
:
1053 switch (osversion
.dwMinorVersion
)
1056 if (strchr (osversion
.szCSDVersion
, 'C'))
1062 if (strchr (osversion
.szCSDVersion
, 'A'))
1075 case VER_PLATFORM_WIN32_NT
:
1077 if (osversion
.dwMajorVersion
== 6)
1078 osname
= "Longhorn/Vista (not yet supported!)";
1079 else if (osversion
.dwMajorVersion
== 5)
1081 BOOL more_info
= FALSE
;
1082 OSVERSIONINFOEX osversionex
;
1083 osversionex
.dwOSVersionInfoSize
= sizeof (osversionex
);
1084 if (GetVersionEx ((OSVERSIONINFO
*) &osversionex
))
1086 if (osversion
.dwMinorVersion
== 0)
1090 else if (osversionex
.wProductType
== VER_NT_SERVER
1091 || osversionex
.wProductType
== VER_NT_DOMAIN_CONTROLLER
)
1093 if (osversionex
.wSuiteMask
& VER_SUITE_DATACENTER
)
1094 osname
= "2000 Datacenter Server";
1095 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1096 osname
= "2000 Advanced Server";
1098 osname
= "2000 Server";
1101 osname
= "2000 Professional";
1103 else if (osversion
.dwMinorVersion
== 1)
1105 if (GetSystemMetrics (SM_MEDIACENTER
))
1106 osname
= "XP Media Center Edition";
1107 else if (GetSystemMetrics (SM_TABLETPC
))
1108 osname
= "XP Tablet PC Edition";
1109 else if (!more_info
)
1111 else if (osversionex
.wSuiteMask
& VER_SUITE_PERSONAL
)
1112 osname
= "XP Home Edition";
1114 osname
= "XP Professional";
1116 else if (osversion
.dwMinorVersion
== 2)
1119 osname
= "2003 Server";
1120 else if (osversionex
.wSuiteMask
& VER_SUITE_BLADE
)
1121 osname
= "2003 Web Server";
1122 else if (osversionex
.wSuiteMask
& VER_SUITE_DATACENTER
)
1123 osname
= "2003 Datacenter Server";
1124 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
1125 osname
= "2003 Enterprise Server";
1127 osname
= "2003 Server";
1137 printf ("Windows %s Ver %lu.%lu Build %lu %s\n", osname
,
1138 osversion
.dwMajorVersion
, osversion
.dwMinorVersion
,
1139 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1140 osversion
.dwBuildNumber
: (osversion
.dwBuildNumber
& 0xffff),
1141 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
1142 osversion
.szCSDVersion
: "");
1144 HMODULE k32
= LoadLibrary ("kernel32.dll");
1146 BOOL (WINAPI
*wow64_func
) (HANDLE
, PBOOL
) = (BOOL (WINAPI
*) (HANDLE
, PBOOL
))
1147 GetProcAddress (k32
, "IsWow64Process");
1148 BOOL is_wow64
= FALSE
;
1149 if (wow64_func
&& wow64_func (GetCurrentProcess (), &is_wow64
) && is_wow64
)
1151 void (WINAPI
*nativinfo
) (LPSYSTEM_INFO
) = (void (WINAPI
*)
1152 (LPSYSTEM_INFO
)) GetProcAddress (k32
, "GetNativeSystemInfo");
1153 SYSTEM_INFO natinfo
;
1154 nativinfo (&natinfo
);
1155 fputs ("\nRunning under WOW64 on ", stdout
);
1156 switch (natinfo
.wProcessorArchitecture
)
1158 case PROCESSOR_ARCHITECTURE_IA64
:
1161 case PROCESSOR_ARCHITECTURE_AMD64
:
1170 if (GetSystemMetrics (SM_REMOTESESSION
))
1171 printf ("\nRunning in Terminal Service session\n");
1174 char *s
= getenv ("PATH"), *e
;
1179 char sep
= strchr (s
, ';') ? ';' : ':';
1180 int count_path_items
= 0;
1183 for (e
= s
; *e
&& *e
!= sep
; e
++);
1185 printf ("\t%.*s\n", e
- s
, s
);
1197 char *cygwin
= getenv ("CYGWIN");
1199 cygwin
-= strlen ("CYGWIN=");
1201 cygwin
= const_cast <char *> ("CYGWIN=");
1202 size_t cyglen
= strlen (cygwin
);
1203 cygwin
= strcpy ((char *) malloc (cyglen
+ sizeof (" nontsec")), cygwin
);
1204 pretty_id ("nontsec", cygwin
, cyglen
);
1205 pretty_id ("ntsec", cygwin
, cyglen
);
1209 if (!GetSystemDirectory (tmp
, 4000))
1210 display_error ("dump_sysinfo: GetSystemDirectory()");
1211 printf ("\nSysDir: %s\n", tmp
);
1213 GetWindowsDirectory (tmp
, 4000);
1214 printf ("WinDir: %s\n\n", tmp
);
1218 printf ("Here's some environment variables that may affect cygwin:\n");
1219 for (i
= 0; environ
[i
]; i
++)
1221 char *eq
= strchr (environ
[i
], '=');
1224 /* int len = eq - environ[i]; */
1225 for (j
= 0; known_env_vars
[j
]; j
++)
1228 if (strcmp (environ
[i
], "PATH") == 0)
1229 continue; /* we handle this one specially */
1230 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1231 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1240 printf ("Here's the rest of your environment variables:\n");
1241 for (i
= 0; environ
[i
]; i
++)
1244 char *eq
= strchr (environ
[i
], '=');
1247 /* int len = eq - environ[i]; */
1248 for (j
= 0; known_env_vars
[j
]; j
++)
1251 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1258 printf ("%s = '%s'\n", environ
[i
], eq
+ 1);
1268 printf ("Scanning registry for keys with 'Cygnus' in them...\n");
1270 /* big and not generally useful */
1271 scan_registry (0, HKEY_CLASSES_ROOT
, (char *) "HKEY_CLASSES_ROOT", 0);
1273 scan_registry (0, HKEY_CURRENT_CONFIG
,
1274 (char *) "HKEY_CURRENT_CONFIG", 0);
1275 scan_registry (0, HKEY_CURRENT_USER
, (char *) "HKEY_CURRENT_USER", 0);
1276 scan_registry (0, HKEY_LOCAL_MACHINE
, (char *) "HKEY_LOCAL_MACHINE", 0);
1278 /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */
1279 scan_registry (0, HKEY_USERS
, (char *) "HKEY_USERS", 0);
1284 printf ("Use '-r' to scan registry\n\n");
1288 printf ("Listing available drives...\n");
1289 printf ("Drv Type Size Used Flags Name\n");
1292 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
);
1293 int drivemask
= GetLogicalDrives ();
1295 BOOL (WINAPI
* gdfse
) (LPCSTR
, long long *, long long *, long long *) =
1296 (BOOL (WINAPI
*) (LPCSTR
, long long *, long long *, long long *))
1297 GetProcAddress (k32
, "GetDiskFreeSpaceExA");
1299 for (i
= 0; i
< 26; i
++)
1301 if (!(drivemask
& (1 << i
)))
1303 char drive
[4], name
[200], fsname
[200];
1304 DWORD serno
= 0, maxnamelen
= 0, flags
= 0;
1305 name
[0] = name
[0] = fsname
[0] = 0;
1306 sprintf (drive
, "%c:\\", i
+ 'a');
1307 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1308 ERROR_NOT_READY is returned when removeable media drives are empty
1309 (CD, floppy, etc.) */
1310 if (!GetVolumeInformation (drive
, name
, sizeof (name
), &serno
,
1311 &maxnamelen
, &flags
, fsname
,
1313 && GetLastError () != ERROR_NOT_READY
)
1315 # define FMT "dump_sysinfo: GetVolumeInformation() for drive %c:"
1316 char buf
[sizeof (FMT
)];
1317 sprintf (buf
, FMT
, 'A' + i
);
1318 display_error (buf
);
1322 int dtype
= GetDriveType (drive
);
1323 char drive_type
[4] = "unk";
1326 case DRIVE_REMOVABLE
:
1327 strcpy (drive_type
, "fd ");
1330 strcpy (drive_type
, "hd ");
1333 strcpy (drive_type
, "net");
1336 strcpy (drive_type
, "cd ");
1339 strcpy (drive_type
, "ram");
1342 strcpy (drive_type
, "unk");
1345 long capacity_mb
= -1;
1346 int percent_full
= -1;
1348 long long free_me
= 0ULL, free_bytes
= 0ULL, total_bytes
= 1ULL;
1349 if (gdfse
!= NULL
&& gdfse (drive
, &free_me
, &total_bytes
, &free_bytes
))
1351 capacity_mb
= total_bytes
/ (1024L * 1024L);
1352 percent_full
= 100 - (int) ((100.0 * free_me
) / total_bytes
);
1356 DWORD spc
= 0, bps
= 0, fc
= 0, tc
= 1;
1357 if (GetDiskFreeSpace (drive
, &spc
, &bps
, &fc
, &tc
))
1359 capacity_mb
= (spc
* bps
* tc
) / (1024 * 1024);
1360 percent_full
= 100 - (int) ((100.0 * fc
) / tc
);
1364 printf ("%.2s %s %-6s ", drive
, drive_type
, fsname
);
1365 if (capacity_mb
>= 0)
1366 printf ("%7dMb %3d%% ", (int) capacity_mb
, (int) percent_full
);
1368 printf (" N/A N/A ");
1369 printf ("%s %s %s %s %s %s %s\n",
1370 flags
& FS_CASE_IS_PRESERVED
? "CP" : " ",
1371 flags
& FS_CASE_SENSITIVE
? "CS" : " ",
1372 flags
& FS_UNICODE_STORED_ON_DISK
? "UN" : " ",
1373 flags
& FS_PERSISTENT_ACLS
? "PA" : " ",
1374 flags
& FS_FILE_COMPRESSION
? "FC" : " ",
1375 flags
& FS_VOL_IS_COMPRESSED
? "VC" : " ",
1377 flags
& FILE_SUPPORTS_ENCRYPTION
? "EN" : " ",
1378 flags
& FILE_SUPPORTS_OBJECT_IDS
? "OI" : " ",
1379 flags
& FILE_SUPPORTS_REPARSE_POINTS
? "RP" : " ",
1380 flags
& FILE_SUPPORTS_SPARSE_FILES
? "SP" : " ",
1381 flags
& FILE_VOLUME_QUOTAS
? "QU" : " ",
1386 if (!FreeLibrary (k32
))
1387 display_error ("dump_sysinfo: FreeLibrary()");
1388 SetErrorMode (prev_mode
);
1392 "fd = floppy, hd = hard drive, cd = CD-ROM\n"
1393 "net= Network Share, ram= RAM drive, unk= Unknown\n"
1394 "CP = Case Preserving, CS = Case Sensitive, UN = Unicode\n"
1395 "PA = Persistent ACLS, FC = File Compression, VC = Volume Compression");
1399 unsigned ml_fsname
= 4, ml_dir
= 7, ml_type
= 6;
1400 bool ml_trailing
= false;
1404 while ((mnt
= getmntent (0)))
1406 unsigned n
= (int) strlen (mnt
->mnt_fsname
);
1407 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_fsname
[n
- 1]));
1410 n
= (int) strlen (mnt
->mnt_dir
);
1411 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_dir
[n
- 1]));
1417 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1422 ("Mount entries: these map POSIX directories to your NT drives.\n");
1423 printf ("%-*s %-*s %-*s %s\n", ml_fsname
, "-NT-", ml_dir
, "-POSIX-",
1424 ml_type
, "-Type-", "-Flags-");
1428 while ((mnt
= getmntent (0)))
1430 printf ("%-*s %-*s %-*s %s\n",
1431 ml_fsname
, mnt
->mnt_fsname
,
1432 ml_dir
, mnt
->mnt_dir
, ml_type
, mnt
->mnt_type
, mnt
->mnt_opts
);
1436 add_path ((char *) "\\bin", 4); /* just in case */
1440 ("Looking to see where common programs can be found, if at all...\n");
1441 for (i
= 0; common_apps
[i
].name
; i
++)
1442 if (!find_on_path ((char *) common_apps
[i
].name
, (char *) ".exe", 1, 0))
1444 if (common_apps
[i
].missing_is_good
)
1445 printf ("Not Found: %s (good!)\n", common_apps
[i
].name
);
1447 printf ("Not Found: %s\n", common_apps
[i
].name
);
1452 printf ("Looking for various Cygwin DLLs... (-v gives version info)\n");
1453 int cygwin_dll_count
= 0;
1454 for (i
= 1; i
< num_paths
; i
++)
1456 WIN32_FIND_DATA ffinfo
;
1457 sprintf (tmp
, "%s/*.*", paths
[i
]);
1458 HANDLE ff
= FindFirstFile (tmp
, &ffinfo
);
1459 int found
= (ff
!= INVALID_HANDLE_VALUE
);
1460 found_cygwin_dll
= NULL
;
1463 char *f
= ffinfo
.cFileName
;
1464 if (strcasecmp (f
+ strlen (f
) - 4, ".dll") == 0)
1466 if (strncasecmp (f
, "cyg", 3) == 0)
1468 sprintf (tmp
, "%s\\%s", paths
[i
], f
);
1469 if (strcasecmp (f
, "cygwin1.dll") == 0)
1472 found_cygwin_dll
= strdup (tmp
);
1478 found
= FindNextFile (ff
, &ffinfo
);
1480 if (found_cygwin_dll
)
1482 ls (found_cygwin_dll
);
1483 free (found_cygwin_dll
);
1488 if (cygwin_dll_count
> 1)
1489 puts ("Warning: There are multiple cygwin1.dlls on your path");
1490 if (!cygwin_dll_count
)
1491 puts ("Warning: cygwin1.dll not found on your path");
1494 dump_sysinfo_services ();
1500 HANDLE h
= CreateFileA ("CONIN$", GENERIC_READ
| GENERIC_WRITE
,
1501 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
1502 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1504 if (h
== INVALID_HANDLE_VALUE
|| h
== NULL
)
1505 return (display_error ("check_keys: Opening CONIN$"));
1509 if (!GetConsoleMode (h
, &mode
))
1510 display_error ("check_keys: GetConsoleMode()");
1513 mode
&= ~ENABLE_PROCESSED_INPUT
;
1514 if (!SetConsoleMode (h
, mode
))
1515 display_error ("check_keys: SetConsoleMode()");
1518 fputs ("\nThis key check works only in a console window,", stderr
);
1519 fputs (" _NOT_ in a terminal session!\n", stderr
);
1520 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr
);
1521 fputs ("Press 'q' to exit.\n", stderr
);
1523 INPUT_RECORD in
, prev_in
;
1525 // Drop first <RETURN> key
1526 ReadConsoleInput (h
, &in
, 1, &mode
);
1528 memset (&in
, 0, sizeof in
);
1533 if (!ReadConsoleInput (h
, &in
, 1, &mode
))
1534 display_error ("check_keys: ReadConsoleInput()");
1536 if (!memcmp (&in
, &prev_in
, sizeof in
))
1539 switch (in
.EventType
)
1542 printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ",
1543 in
.Event
.KeyEvent
.bKeyDown
? "Pressed " : "Released",
1544 in
.Event
.KeyEvent
.wRepeatCount
,
1545 in
.Event
.KeyEvent
.wVirtualKeyCode
,
1546 in
.Event
.KeyEvent
.wVirtualScanCode
,
1547 (unsigned char) in
.Event
.KeyEvent
.uChar
.AsciiChar
);
1548 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& CAPSLOCK_ON
?
1549 "CL " : "-- ", stdout
);
1550 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& ENHANCED_KEY
?
1551 "EK " : "-- ", stdout
);
1552 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_ALT_PRESSED
?
1553 "LA " : "-- ", stdout
);
1554 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_CTRL_PRESSED
?
1555 "LC " : "-- ", stdout
);
1556 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& NUMLOCK_ON
?
1557 "NL " : "-- ", stdout
);
1558 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
?
1559 "RA " : "-- ", stdout
);
1560 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_CTRL_PRESSED
?
1561 "RC " : "-- ", stdout
);
1562 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SCROLLLOCK_ON
?
1563 "SL " : "-- ", stdout
);
1564 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
?
1565 "SH " : "-- ", stdout
);
1566 fputc ('\n', stdout
);
1573 while (in
.EventType
!= KEY_EVENT
||
1574 in
.Event
.KeyEvent
.bKeyDown
!= FALSE
||
1575 in
.Event
.KeyEvent
.uChar
.AsciiChar
!= 'q');
1581 /* RFC1738 says that these do not need to be escaped. */
1582 static const char safe_chars
[] = "$-_.+!*'(),";
1584 /* the URL to query. */
1585 static const char base_url
[] =
1586 "http://cygwin.com/cgi-bin2/package-grep.cgi?text=1&grep=";
1588 /* Queries Cygwin web site for packages containing files matching a regexp.
1589 Return value is 1 if there was a problem, otherwise 0. */
1591 package_grep (char *search
)
1595 /* Attempt to dynamically load the necessary WinInet API functions so that
1596 cygcheck can still function on older systems without IE. */
1598 if (!(hWinInet
= LoadLibrary ("wininet.dll")))
1600 fputs ("Unable to locate WININET.DLL. This feature requires Microsoft "
1601 "Internet Explorer v3 or later to function.\n", stderr
);
1605 /* InternetCloseHandle is used outside this function so it is declared
1606 global. The rest of these functions are only used here, so declare them
1607 and call GetProcAddress for each of them with the following macro. */
1609 pInternetCloseHandle
= (BOOL (WINAPI
*) (HINTERNET
))
1610 GetProcAddress (hWinInet
, "InternetCloseHandle");
1611 #define make_func_pointer(name, ret, args) ret (WINAPI * p##name) args = \
1612 (ret (WINAPI *) args) GetProcAddress (hWinInet, #name);
1613 make_func_pointer (InternetAttemptConnect
, DWORD
, (DWORD
));
1614 make_func_pointer (InternetOpenA
, HINTERNET
, (LPCSTR
, DWORD
, LPCSTR
, LPCSTR
,
1616 make_func_pointer (InternetOpenUrlA
, HINTERNET
, (HINTERNET
, LPCSTR
, LPCSTR
,
1617 DWORD
, DWORD
, DWORD
));
1618 make_func_pointer (InternetReadFile
, BOOL
, (HINTERNET
, PVOID
, DWORD
, PDWORD
));
1619 make_func_pointer (HttpQueryInfoA
, BOOL
, (HINTERNET
, DWORD
, PVOID
, PDWORD
,
1621 #undef make_func_pointer
1623 if(!pInternetCloseHandle
|| !pInternetAttemptConnect
|| !pInternetOpenA
1624 || !pInternetOpenUrlA
|| !pInternetReadFile
|| !pHttpQueryInfoA
)
1626 fputs ("Unable to load one or more functions from WININET.DLL. This "
1627 "feature requires Microsoft Internet Explorer v3 or later to "
1628 "function.\n", stderr
);
1632 /* construct the actual URL by escaping */
1633 char *url
= (char *) alloca (sizeof (base_url
) + strlen (search
) * 3);
1634 strcpy (url
, base_url
);
1637 for (dest
= &url
[sizeof (base_url
) - 1]; *search
; search
++)
1639 if (isalnum (*search
)
1640 || memchr (safe_chars
, *search
, sizeof (safe_chars
) - 1))
1647 sprintf (dest
, "%02x", (unsigned char) *search
);
1653 /* Connect to the net and open the URL. */
1654 if (pInternetAttemptConnect (0) != ERROR_SUCCESS
)
1656 fputs ("An internet connection is required for this function.\n", stderr
);
1660 /* Initialize WinInet and attempt to fetch our URL. */
1661 HINTERNET hi
= NULL
, hurl
= NULL
;
1662 if (!(hi
= pInternetOpenA ("cygcheck", INTERNET_OPEN_TYPE_PRECONFIG
, NULL
, NULL
, 0)))
1663 return display_internet_error ("InternetOpen() failed", NULL
);
1665 if (!(hurl
= pInternetOpenUrlA (hi
, url
, NULL
, 0, 0, 0)))
1666 return display_internet_error ("unable to contact cygwin.com site, "
1667 "InternetOpenUrl() failed", hi
, NULL
);
1669 /* Check the HTTP response code. */
1670 DWORD rc
= 0, rc_s
= sizeof (DWORD
);
1671 if (!pHttpQueryInfoA (hurl
, HTTP_QUERY_STATUS_CODE
| HTTP_QUERY_FLAG_NUMBER
,
1672 (void *) &rc
, &rc_s
, NULL
))
1673 return display_internet_error ("HttpQueryInfo() failed", hurl
, hi
, NULL
);
1675 if (rc
!= HTTP_STATUS_OK
)
1677 sprintf (buf
, "error retrieving results from cygwin.com site, "
1678 "HTTP status code %lu", rc
);
1679 return display_internet_error (buf
, hurl
, hi
, NULL
);
1682 /* Fetch result and print to stdout. */
1686 if (!pInternetReadFile (hurl
, (void *) buf
, sizeof (buf
), &numread
))
1687 return display_internet_error ("InternetReadFile failed", hurl
, hi
, NULL
);
1689 fwrite ((void *) buf
, (size_t) numread
, 1, stdout
);
1693 pInternetCloseHandle (hurl
);
1694 pInternetCloseHandle (hi
);
1699 usage (FILE * stream
, int status
)
1702 Usage: cygcheck PROGRAM [ -v ] [ -h ]\n\
1703 cygcheck -c [ PACKAGE ] [ -d ]\n\
1704 cygcheck -s [ -r ] [ -v ] [ -h ]\n\
1706 cygcheck -f FILE [ FILE ... ]\n\
1707 cygcheck -l [ PACKAGE ] [ PACKAGE ... ]\n\
1708 cygcheck -p REGEXP\n\
1709 List system information, check installed packages, or query package database.\n\
1711 At least one command option or a PROGRAM is required, as shown above.\n\
1713 PROGRAM list library (DLL) dependencies of PROGRAM\n\
1714 -c, --check-setup show installed version of PACKAGE and verify integrity\n\
1715 (or for all installed packages if none specified)\n\
1716 -d, --dump-only just list packages, do not verify (with -c)\n\
1717 -s, --sysinfo produce diagnostic system information (implies -c -d)\n\
1718 -r, --registry also scan registry for Cygwin settings (with -s)\n\
1719 -k, --keycheck perform a keyboard check session (must be run from a\n\
1720 plain console only, not from a pty/rxvt/xterm)\n\
1721 -f, --find-package find the package that FILE belongs to\n\
1722 -l, --list-package list contents of PACKAGE (or all packages if none given)\n\
1723 -p, --package-query search for REGEXP in the entire cygwin.com package\n\
1724 repository (requies internet connectivity)\n\
1725 -v, --verbose produce more verbose output\n\
1726 -h, --help annotate output with explanatory comments when given\n\
1727 with another command, otherwise print this help\n\
1728 -V, --version print the version of cygcheck and exit\n\
1730 Note: -c, -f, and -l only report on packages that are currently installed. To\n\
1731 search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
1732 package names, descriptions, and names of files/paths within all packages.\n\
1737 struct option longopts
[] = {
1738 {"check-setup", no_argument
, NULL
, 'c'},
1739 {"dump-only", no_argument
, NULL
, 'd'},
1740 {"sysinfo", no_argument
, NULL
, 's'},
1741 {"registry", no_argument
, NULL
, 'r'},
1742 {"verbose", no_argument
, NULL
, 'v'},
1743 {"keycheck", no_argument
, NULL
, 'k'},
1744 {"find-package", no_argument
, NULL
, 'f'},
1745 {"list-package", no_argument
, NULL
, 'l'},
1746 {"package-query", no_argument
, NULL
, 'p'},
1747 {"help", no_argument
, NULL
, 'h'},
1748 {"version", no_argument
, 0, 'V'},
1749 {0, no_argument
, NULL
, 0}
1752 static char opts
[] = "cdsrvkflphV";
1757 const char *v
= strchr (version
, ':');
1767 len
= strchr (v
, ' ') - v
;
1770 cygcheck version %.*s\n\
1771 System Checker for Cygwin\n\
1772 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.\n\
1774 ", len
, v
, __DATE__
);
1780 int n
= 1 + strchr (ev
, '=') - ev
;
1781 char *s
= (char *) alloca (n
+ 1);
1788 unsigned long (*cygwin_internal
) (int, ...);
1792 load_cygwin (int& argc
, char **&argv
)
1796 if (!(h
= LoadLibrary ("cygwin1.dll")))
1798 if (!(cygwin_internal
= (DWORD (*) (int, ...)) GetProcAddress (h
, "cygwin_internal")))
1801 char **av
= (char **) cygwin_internal (CW_ARGV
);
1802 if (av
&& ((DWORD
) av
!= (DWORD
) -1))
1803 for (argc
= 0, argv
= av
; *av
; av
++)
1806 char **envp
= (char **) cygwin_internal (CW_ENVP
);
1807 if (envp
&& ((DWORD
) envp
!= (DWORD
) -1))
1809 /* Store path and revert to this value, otherwise path gets overwritten
1810 by the POSIXy Cygwin variation, which breaks cygcheck.
1811 Another approach would be to use the Cygwin PATH and convert it to
1815 while (*(env
= _environ
))
1817 if (strncmp (*env
, "PATH=", 5) == 0)
1818 path
= strdup (*env
);
1821 for (char **ev
= envp
; *ev
; ev
++)
1822 if (strncmp (*ev
, "PATH=", 5) != 0)
1830 main (int argc
, char **argv
)
1834 load_cygwin (argc
, argv
);
1836 (void) putenv("POSIXLY_CORRECT=1");
1837 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
1879 if (argc
== 0 && !sysinfo
&& !keycheck
&& !check_setup
&& !list_package
)
1885 if ((check_setup
|| sysinfo
|| find_package
|| list_package
|| grep_packages
)
1889 if ((find_package
|| list_package
|| grep_packages
) && check_setup
)
1892 if (dump_only
&& !check_setup
)
1895 if (find_package
+ list_package
+ grep_packages
> 1)
1899 return check_keys ();
1901 return package_grep (*argv
);
1905 /* FIXME: Add help for check_setup and {list,find}_package */
1906 if (argc
>= 1 && givehelp
&& !check_setup
&& !find_package
&& !list_package
)
1908 printf("Here is where the OS will find your program%s, and which dlls\n",
1909 argc
> 1 ? "s" : "");
1910 printf ("will be used for it. Use -v to see DLL version info\n");
1917 dump_setup (verbose
, argv
, !dump_only
);
1918 else if (find_package
)
1919 package_find (verbose
, argv
);
1920 else if (list_package
)
1921 package_list (verbose
, argv
);
1923 for (i
= 0; i
< argc
; i
++)
1927 ok
&= cygcheck (argv
[i
]);
1936 dump_setup (verbose
, NULL
, false);
1940 puts ("Use -h to see help about each section");
1943 return ok
? EXIT_SUCCESS
: EXIT_FAILURE
;