]> sourceware.org Git - newlib-cygwin.git/blame - winsup/utils/cygcheck.cc
* cygcheck.cc (pretty_id): Don't let i become negative. Fix
[newlib-cygwin.git] / winsup / utils / cygcheck.cc
CommitLineData
1fd5e000
CF
1/* cygcheck.cc
2
c662f402 3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
1fd5e000
CF
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
468b26c5 14#include <sys/time.h>
4ddb62e7 15#include <ctype.h>
dbc49afd 16#include <io.h>
1fd5e000 17#include <windows.h>
dbc49afd 18#include "path.h"
bd79b736 19#include <getopt.h>
012858ec 20#include "cygwin/include/sys/cygwin.h"
4239e5ec 21#include "cygwin/include/mntent.h"
1fd5e000 22
902edd45
CF
23#define alloca __builtin_alloca
24
1fd5e000
CF
25int verbose = 0;
26int registry = 0;
27int sysinfo = 0;
28int givehelp = 0;
41a0695b 29int keycheck = 0;
d0d51791 30int check_setup = 0;
59a76035 31int dump_only = 0;
200f243c
CV
32int find_package = 0;
33int list_package = 0;
1fd5e000
CF
34
35#ifdef __GNUC__
36typedef long long longlong;
37#else
38typedef __int64 longlong;
39#endif
40
71f90de8 41void dump_setup (int, char **, bool);
200f243c
CV
42void package_find (int, char **);
43void package_list (int, char **);
d0d51791 44
67763c0c
CF
45static const char version[] = "$Revision$";
46
47static const char *known_env_vars[] = {
1fd5e000
CF
48 "c_include_path",
49 "compiler_path",
50 "cxx_include_path",
51 "cygwin",
52 "cygwin32",
53 "dejagnu",
54 "expect",
55 "gcc_default_options",
56 "gcc_exec_prefix",
57 "home",
58 "ld_library_path",
59 "library_path",
60 "login",
61 "lpath",
62 "make_mode",
63 "makeflags",
64 "path",
65 "pwd",
66 "strace",
67 "tcl_library",
68 "user",
69 0
70};
71
eedc36cb
CF
72struct
73{
1fd5e000
CF
74 const char *name;
75 int missing_is_good;
eedc36cb 76}
b56dedef 77static common_apps[] = {
4a9cbef0 78 {"awk", 0},
ce475802
CF
79 {"bash", 0},
80 {"cat", 0},
4a9cbef0 81 {"cp", 0},
ce475802
CF
82 {"cpp", 1},
83 {"find", 0},
84 {"gcc", 0},
85 {"gdb", 0},
4a9cbef0 86 {"grep", 0},
ce475802
CF
87 {"ld", 0},
88 {"ls", 0},
89 {"make", 0},
4a9cbef0
CF
90 {"mv", 0},
91 {"rm", 0},
92 {"sed", 0},
ce475802 93 {"sh", 0},
4a9cbef0 94 {"tar", 0},
ce475802 95 {0, 0}
1fd5e000
CF
96};
97
67763c0c
CF
98static int num_paths = 0, max_paths = 0;
99static char **paths = 0;
1fd5e000 100
64069abe
CF
101/*
102 * keyeprint() is used to report failure modes
103 */
67763c0c 104static int
64069abe
CF
105keyeprint (const char *name)
106{
107 fprintf (stderr, "cygcheck: %s failed: %lu\n", name, GetLastError ());
108 return 1;
109}
110
67763c0c 111static void
1fd5e000
CF
112add_path (char *s, int maxlen)
113{
114 if (num_paths >= max_paths)
115 {
116 max_paths += 10;
117 if (paths)
118 paths = (char **) realloc (paths, max_paths * sizeof (char *));
119 else
120 paths = (char **) malloc (max_paths * sizeof (char *));
121 }
122 paths[num_paths] = (char *) malloc (maxlen + 1);
64069abe
CF
123 if (paths[num_paths] == NULL)
124 {
125 keyeprint ("add_path: malloc()");
126 return;
127 }
1fd5e000
CF
128 memcpy (paths[num_paths], s, maxlen);
129 paths[num_paths][maxlen] = 0;
130 char *e = paths[num_paths] + strlen (paths[num_paths]);
131 if (e[-1] == '\\' && e[-2] != ':')
132 *--e = 0;
133 for (int i = 1; i < num_paths; i++)
134 if (strcasecmp (paths[num_paths], paths[i]) == 0)
76ad4d0a
CF
135 {
136 free (paths[num_paths]);
137 return;
138 }
1fd5e000
CF
139 num_paths++;
140}
141
67763c0c 142static void
1fd5e000
CF
143init_paths ()
144{
145 char tmp[4000], *sl;
eedc36cb
CF
146 add_path ((char *) ".", 1); /* to be replaced later */
147 add_path ((char *) ".", 1); /* the current directory */
64069abe
CF
148 if (GetSystemDirectory (tmp, 4000))
149 add_path (tmp, strlen (tmp));
150 else
151 keyeprint ("init_paths: GetSystemDirectory()");
1fd5e000
CF
152 sl = strrchr (tmp, '\\');
153 if (sl)
154 {
155 strcpy (sl, "\\SYSTEM");
156 add_path (tmp, strlen (tmp));
157 }
158 GetWindowsDirectory (tmp, 4000);
159 add_path (tmp, strlen (tmp));
160
2fac517d
CF
161 char *wpath = getenv ("PATH");
162 if (wpath)
1fd5e000 163 {
2fac517d 164 char *b, *e;
1fd5e000
CF
165 b = wpath;
166 while (1)
167 {
2fac517d 168 for (e = b; *e && *e != ';'; e++);
1fd5e000
CF
169 add_path (b, e - b);
170 if (!*e)
171 break;
172 b = e + 1;
173 }
174 }
175 else
176 printf ("WARNING: PATH is not set at all!\n");
177}
178
67763c0c 179static char *
1fd5e000
CF
180find_on_path (char *file, char *default_extension,
181 int showall = 0, int search_sysdirs = 0)
182{
183 static char rv[4000];
184 char tmp[4000], *ptr = rv;
185
dbc49afd 186 if (!file)
64069abe
CF
187 {
188 keyeprint ("find_on_path: NULL pointer for file");
189 return 0;
190 }
191
192 if (default_extension == NULL)
193 {
194 keyeprint ("find_on_path: NULL pointer for default_extension");
195 return 0;
196 }
197
1fd5e000 198 if (strchr (file, ':') || strchr (file, '\\') || strchr (file, '/'))
dbc49afd 199 return cygpath (file, NULL);
1fd5e000
CF
200
201 if (strchr (file, '.'))
eedc36cb 202 default_extension = (char *) "";
1fd5e000
CF
203
204 for (int i = 0; i < num_paths; i++)
205 {
206 if (!search_sysdirs && (i == 0 || i == 2 || i == 3))
207 continue;
208 if (i == 0 || !search_sysdirs || strcasecmp (paths[i], paths[0]))
209 {
210 sprintf (ptr, "%s\\%s%s", paths[i], file, default_extension);
64069abe 211 if (GetFileAttributes (ptr) != (DWORD) - 1)
1fd5e000
CF
212 {
213 if (showall)
214 printf ("Found: %s\n", ptr);
215 if (ptr == tmp && verbose)
216 printf ("Warning: %s hides %s\n", rv, ptr);
217 ptr = tmp;
218 }
219 }
220 }
221
222 if (ptr == tmp)
223 return rv;
224
225 return 0;
226}
227
228#define DID_NEW 1
229#define DID_ACTIVE 2
230#define DID_INACTIVE 3
231
232struct Did
233{
234 Did *next;
235 char *file;
236 int state;
237};
67763c0c 238static Did *did = 0;
1fd5e000 239
67763c0c 240static Did *
1fd5e000
CF
241already_did (char *file)
242{
243 Did *d;
244 for (d = did; d; d = d->next)
245 if (strcasecmp (d->file, file) == 0)
246 return d;
e47cd9cd 247 d = (Did *) malloc (sizeof (Did));
1fd5e000
CF
248 d->file = strdup (file);
249 d->next = did;
250 d->state = DID_NEW;
251 did = d;
252 return d;
253}
254
67763c0c 255static int
1fd5e000
CF
256get_word (HANDLE fh, int offset)
257{
258 short rv;
259 unsigned r;
64069abe
CF
260
261 if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER
262 && GetLastError () != NO_ERROR)
263 keyeprint ("get_word: SetFilePointer()");
264
b56dedef 265 if (!ReadFile (fh, &rv, 2, (DWORD *) &r, 0))
64069abe
CF
266 keyeprint ("get_word: Readfile()");
267
1fd5e000
CF
268 return rv;
269}
270
67763c0c 271static int
1fd5e000
CF
272get_dword (HANDLE fh, int offset)
273{
274 int rv;
275 unsigned r;
64069abe
CF
276
277 if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER
278 && GetLastError () != NO_ERROR)
279 keyeprint ("get_word: SetFilePointer()");
280
b56dedef 281 if (!ReadFile (fh, &rv, 4, (DWORD *) &r, 0))
64069abe
CF
282 keyeprint ("get_dword: Readfile()");
283
1fd5e000
CF
284 return rv;
285}
286
287struct Section
288{
289 char name[8];
290 int virtual_size;
291 int virtual_address;
292 int size_of_raw_data;
293 int pointer_to_raw_data;
294};
295
67763c0c 296static int
1fd5e000
CF
297rva_to_offset (int rva, char *sections, int nsections, int *sz)
298{
299 int i;
64069abe
CF
300
301 if (sections == NULL)
302 {
303 keyeprint ("rva_to_offset: NULL passed for sections");
304 return 0;
305 }
306
1fd5e000
CF
307 for (i = 0; i < nsections; i++)
308 {
309 Section *s = (Section *) (sections + i * 40);
310#if 0
311 printf ("%08x < %08x < %08x ? %08x\n",
312 s->virtual_address, rva,
313 s->virtual_address + s->virtual_size, s->pointer_to_raw_data);
314#endif
315 if (rva >= s->virtual_address
316 && rva < s->virtual_address + s->virtual_size)
317 {
318 if (sz)
319 *sz = s->virtual_address + s->virtual_size - rva;
320 return rva - s->virtual_address + s->pointer_to_raw_data;
321 }
322 }
323 return 0; /* punt */
324}
325
326struct ExpDirectory
327{
328 int flags;
329 int timestamp;
330 short major_ver;
331 short minor_ver;
332 int name_rva;
333};
334
335struct ImpDirectory
eedc36cb
CF
336{
337 unsigned characteristics;
338 unsigned timestamp;
339 unsigned forwarder_chain;
340 unsigned name_rva;
341 unsigned iat_rva;
342};
1fd5e000
CF
343
344
67763c0c 345static void track_down (char *file, char *suffix, int lvl);
1fd5e000 346
749bdbe9
CF
347#define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
348static void
349cygwin_info (HANDLE h)
350{
64069abe 351 char *buf, *bufend, *buf_start = NULL;
749bdbe9
CF
352 const char *hello = " Cygwin DLL version info:\n";
353 DWORD size = GetFileSize (h, NULL);
354 DWORD n;
355
356 if (size == 0xffffffff)
357 return;
358
64069abe
CF
359 buf_start = buf = (char *) calloc (1, size + 1);
360 if (buf == NULL)
361 {
362 keyeprint ("cygwin_info: malloc()");
363 return;
364 }
749bdbe9
CF
365
366 (void) SetFilePointer (h, 0, NULL, FILE_BEGIN);
367 if (!ReadFile (h, buf, size, &n, NULL))
64069abe
CF
368 {
369 free (buf_start);
370 return;
371 }
749bdbe9 372
ad466e2f
CF
373 static char dummy[] = "\0\0\0\0\0\0\0";
374 char *dll_major = dummy;
749bdbe9 375 bufend = buf + size;
749bdbe9
CF
376 while (buf < bufend)
377 if ((buf = (char *) memchr (buf, '%', bufend - buf)) == NULL)
eedc36cb 378 break;
749bdbe9 379 else if (strncmp ("%%% Cygwin ", buf, CYGPREFIX) != 0)
eedc36cb 380 buf++;
749bdbe9
CF
381 else
382 {
383 char *p = strchr (buf += CYGPREFIX, '\n');
64069abe
CF
384 if (!p)
385 break;
2fac517d
CF
386 if (strncasecmp (buf, "dll major:", 10) == 0)
387 {
388 dll_major = buf + 11;
389 continue;
390 }
391 char *s, pbuf[80];
392 int len;
393 len = 1 + p - buf;
394 if (strncasecmp (buf, "dll minor:", 10) != 0)
395 s = buf;
396 else
397 {
398 char c = dll_major[1];
399 dll_major[1] = '\0';
400 int maj = atoi (dll_major);
401 dll_major[1] = c;
402 int min = atoi (dll_major + 1);
b56dedef
CF
403 sprintf (pbuf, "DLL version: %d.%d.%.*s", maj, min, len - 11,
404 buf + 11);
2fac517d
CF
405 len = strlen (s = pbuf);
406 }
407 if (strncmp (s, "dll", 3) == 0)
408 memcpy (s, "DLL", 3);
409 else if (strncmp (s, "api", 3) == 0)
410 memcpy (s, "API", 3);
411 else if (islower (*s))
412 *s = toupper (*s);
413 fprintf (stdout, "%s %.*s", hello, len, s);
749bdbe9
CF
414 hello = "";
415 }
416
417 if (!*hello)
418 puts ("");
64069abe
CF
419
420 free (buf_start);
749bdbe9
CF
421 return;
422}
423
67763c0c 424static void
749bdbe9 425dll_info (const char *path, HANDLE fh, int lvl, int recurse)
1fd5e000
CF
426{
427 DWORD junk;
428 int i;
429 int pe_header_offset = get_dword (fh, 0x3c);
430 int opthdr_ofs = pe_header_offset + 4 + 20;
431 unsigned short v[6];
64069abe
CF
432
433 if (path == NULL)
434 {
435 keyeprint ("dll_info: NULL passed for path");
436 return;
437 }
438
b56dedef
CF
439 if (SetFilePointer (fh, opthdr_ofs + 40, 0, FILE_BEGIN) ==
440 INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
64069abe
CF
441 keyeprint ("dll_info: SetFilePointer()");
442
443 if (!ReadFile (fh, &v, sizeof (v), &junk, 0))
444 keyeprint ("dll_info: Readfile()");
445
1fd5e000
CF
446 if (verbose)
447 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
448 v[0], v[1], v[2], v[3], v[4], v[5]);
449 else
450 printf ("\n");
64069abe 451
1fd5e000
CF
452 int num_entries = get_dword (fh, opthdr_ofs + 92);
453 int export_rva = get_dword (fh, opthdr_ofs + 96);
454 int export_size = get_dword (fh, opthdr_ofs + 100);
455 int import_rva = get_dword (fh, opthdr_ofs + 104);
456 int import_size = get_dword (fh, opthdr_ofs + 108);
457
458 int nsections = get_word (fh, pe_header_offset + 4 + 2);
459 char *sections = (char *) malloc (nsections * 40);
64069abe
CF
460
461 if (SetFilePointer (fh, pe_header_offset + 4 + 20 +
462 get_word (fh, pe_header_offset + 4 + 16), 0,
463 FILE_BEGIN) == INVALID_SET_FILE_POINTER
464 && GetLastError () != NO_ERROR)
465 keyeprint ("dll_info: SetFilePointer()");
466
467 if (!ReadFile (fh, sections, nsections * 40, &junk, 0))
468 keyeprint ("dll_info: Readfile()");
1fd5e000
CF
469
470 if (verbose && num_entries >= 1 && export_size > 0)
471 {
472 int expsz;
473 int expbase = rva_to_offset (export_rva, sections, nsections, &expsz);
64069abe 474
1fd5e000
CF
475 if (expbase)
476 {
b56dedef
CF
477 if (SetFilePointer (fh, expbase, 0, FILE_BEGIN) ==
478 INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
64069abe
CF
479 keyeprint ("dll_info: SetFilePointer()");
480
1fd5e000 481 unsigned char *exp = (unsigned char *) malloc (expsz);
64069abe
CF
482
483 if (!ReadFile (fh, exp, expsz, &junk, 0))
484 keyeprint ("dll_info: Readfile()");
485
1fd5e000
CF
486 ExpDirectory *ed = (ExpDirectory *) exp;
487 int ofs = ed->name_rva - export_rva;
488 struct tm *tm = localtime ((const time_t *) &(ed->timestamp));
489 if (tm->tm_year < 60)
490 tm->tm_year += 2000;
491 if (tm->tm_year < 200)
492 tm->tm_year += 1900;
493 printf ("%*c", lvl + 2, ' ');
494 printf ("\"%s\" v%d.%d ts=", exp + ofs,
495 ed->major_ver, ed->minor_ver);
496 printf ("%d/%d/%d %d:%02d\n",
497 tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
498 tm->tm_hour, tm->tm_min);
499 }
500 }
501
502 if (num_entries >= 2 && import_size > 0 && recurse)
503 {
504 int impsz;
505 int impbase = rva_to_offset (import_rva, sections, nsections, &impsz);
506 if (impbase)
507 {
b56dedef
CF
508 if (SetFilePointer (fh, impbase, 0, FILE_BEGIN) ==
509 INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
64069abe
CF
510 keyeprint ("dll_info: SetFilePointer()");
511
1fd5e000 512 unsigned char *imp = (unsigned char *) malloc (impsz);
64069abe
CF
513 if (imp == NULL)
514 {
515 keyeprint ("dll_info: malloc()");
516 return;
517 }
518
519 if (!ReadFile (fh, imp, impsz, &junk, 0))
520 keyeprint ("dll_info: Readfile()");
521
1fd5e000
CF
522 ImpDirectory *id = (ImpDirectory *) imp;
523 for (i = 0; id[i].name_rva; i++)
524 {
525 /* int ofs = id[i].name_rva - import_rva; */
526 track_down ((char *) imp + id[i].name_rva - import_rva,
527 (char *) ".dll", lvl + 2);
528 }
529 }
530 }
749bdbe9
CF
531 if (strstr (path, "\\cygwin1.dll"))
532 cygwin_info (fh);
1fd5e000
CF
533}
534
67763c0c 535static void
1fd5e000
CF
536track_down (char *file, char *suffix, int lvl)
537{
64069abe
CF
538 if (file == NULL)
539 {
540 keyeprint ("track_down: malloc()");
541 return;
542 }
543
544 if (suffix == NULL)
545 {
546 keyeprint ("track_down: malloc()");
547 return;
548 }
549
1fd5e000
CF
550 char *path = find_on_path (file, suffix, 0, 1);
551 if (!path)
552 {
553 printf ("Error: could not find %s\n", file);
554 return;
555 }
556
557 Did *d = already_did (file);
558 switch (d->state)
559 {
560 case DID_NEW:
561 break;
562 case DID_ACTIVE:
563 if (verbose)
564 {
565 if (lvl)
566 printf ("%*c", lvl, ' ');
567 printf ("%s", path);
568 printf (" (recursive)\n");
569 }
570 return;
571 case DID_INACTIVE:
572 if (verbose)
573 {
574 if (lvl)
575 printf ("%*c", lvl, ' ');
576 printf ("%s", path);
577 printf (" (already done)\n");
578 }
579 return;
64069abe
CF
580 default:
581 break;
1fd5e000
CF
582 }
583
584 if (lvl)
585 printf ("%*c", lvl, ' ');
586
587 if (!path)
588 {
589 printf ("%s not found\n", file);
590 return;
591 }
592
593 printf ("%s", path);
594
eedc36cb
CF
595 HANDLE fh =
596 CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
597 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1fd5e000
CF
598 if (fh == INVALID_HANDLE_VALUE)
599 {
600 printf (" - Cannot open\n");
601 return;
602 }
603
604 d->state = DID_ACTIVE;
605
749bdbe9 606 dll_info (path, fh, lvl, 1);
1fd5e000 607 d->state = DID_INACTIVE;
64069abe
CF
608 if (!CloseHandle (fh))
609 keyeprint ("track_down: CloseHandle()");
1fd5e000
CF
610}
611
67763c0c 612static void
1fd5e000
CF
613ls (char *f)
614{
615 HANDLE h = CreateFile (f, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
616 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
617 BY_HANDLE_FILE_INFORMATION info;
64069abe
CF
618
619 if (!GetFileInformationByHandle (h, &info))
620 keyeprint ("ls: GetFileInformationByHandle()");
621
1fd5e000 622 SYSTEMTIME systime;
64069abe
CF
623
624 if (!FileTimeToSystemTime (&info.ftLastWriteTime, &systime))
625 keyeprint ("ls: FileTimeToSystemTime()");
1fd5e000
CF
626 printf ("%5dk %04d/%02d/%02d %s",
627 (((int) info.nFileSizeLow) + 512) / 1024,
eedc36cb 628 systime.wYear, systime.wMonth, systime.wDay, f);
749bdbe9 629 dll_info (f, h, 16, 0);
64069abe
CF
630 if (!CloseHandle (h))
631 keyeprint ("ls: CloseHandle()");
1fd5e000
CF
632}
633
67763c0c 634static void
1fd5e000
CF
635cygcheck (char *app)
636{
637 char *papp = find_on_path (app, (char *) ".exe", 1, 0);
638 if (!papp)
639 {
640 printf ("Error: could not find %s\n", app);
641 return;
642 }
643 char *s = strdup (papp);
644 char *sl = 0, *t;
645 for (t = s; *t; t++)
646 if (*t == '/' || *t == '\\' || *t == ':')
647 sl = t;
648 if (sl == 0)
649 paths[0] = (char *) ".";
650 else
651 {
652 *sl = 0;
653 paths[0] = s;
654 }
655 did = 0;
656 track_down (papp, (char *) ".exe", 0);
657}
658
659
660extern char **environ;
661
662struct RegInfo
eedc36cb
CF
663{
664 RegInfo *prev;
665 char *name;
666 HKEY key;
667};
1fd5e000 668
67763c0c 669static void
1fd5e000
CF
670show_reg (RegInfo * ri, int nest)
671{
672 if (!ri)
673 return;
674 show_reg (ri->prev, 1);
675 if (nest)
676 printf ("%s\\", ri->name);
677 else
678 printf ("%s\n", ri->name);
679}
680
67763c0c 681static void
1fd5e000
CF
682scan_registry (RegInfo * prev, HKEY hKey, char *name, int cygnus)
683{
684 RegInfo ri;
685 ri.prev = prev;
686 ri.name = name;
687 ri.key = hKey;
688
689 char *cp;
690 for (cp = name; *cp; cp++)
691 if (strncasecmp (cp, "cygnus", 6) == 0)
692 cygnus = 1;
693
694 DWORD num_subkeys, max_subkey_len, num_values;
695 DWORD max_value_len, max_valdata_len, i;
696 if (RegQueryInfoKey (hKey, 0, 0, 0, &num_subkeys, &max_subkey_len, 0,
697 &num_values, &max_value_len, &max_valdata_len, 0, 0)
698 != ERROR_SUCCESS)
699 {
700#if 0
701 char tmp[400];
702 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError (),
eedc36cb 703 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), tmp, 400, 0);
1fd5e000
CF
704 printf ("RegQueryInfoKey: %s\n", tmp);
705#endif
706 return;
707 }
708
709 if (cygnus)
710 {
711 show_reg (&ri, 0);
64069abe 712
1fd5e000 713 char *value_name = (char *) malloc (max_value_len + 1);
64069abe
CF
714 if (value_name == NULL)
715 {
716 keyeprint ("scan_registry: malloc()");
717 return;
718 }
719
1fd5e000 720 char *value_data = (char *) malloc (max_valdata_len + 1);
64069abe
CF
721 if (value_data == NULL)
722 {
723 keyeprint ("scan_registry: malloc()");
724 return;
725 }
1fd5e000
CF
726
727 for (i = 0; i < num_values; i++)
728 {
729 DWORD dlen = max_valdata_len + 1;
730 DWORD nlen = max_value_len + 1;
731 DWORD type;
732 RegEnumValue (hKey, i, value_name, &nlen, 0,
733 &type, (BYTE *) value_data, &dlen);
734 {
735 printf (" %s = ", i ? value_name : "(default)");
736 switch (type)
737 {
738 case REG_DWORD:
739 printf ("0x%08x\n", *(unsigned *) value_data);
740 break;
741 case REG_EXPAND_SZ:
742 case REG_SZ:
743 printf ("`%s'\n", value_data);
744 break;
745 default:
746 printf ("(unsupported type)\n");
747 break;
748 }
749 }
1fd5e000
CF
750 }
751 free (value_name);
752 free (value_data);
753 }
754
755 char *subkey_name = (char *) malloc (max_subkey_len + 1);
756 for (i = 0; i < num_subkeys; i++)
757 {
eedc36cb
CF
758 if (RegEnumKey (hKey, i, subkey_name, max_subkey_len + 1) ==
759 ERROR_SUCCESS)
1fd5e000
CF
760 {
761 HKEY sKey;
71f90de8 762 if (RegOpenKeyEx (hKey, subkey_name, 0, KEY_READ, &sKey)
1fd5e000
CF
763 == ERROR_SUCCESS)
764 {
765 scan_registry (&ri, sKey, subkey_name, cygnus);
64069abe
CF
766 if (RegCloseKey (sKey) != ERROR_SUCCESS)
767 keyeprint ("scan_registry: RegCloseKey()");
1fd5e000
CF
768 }
769 }
770 }
771 free (subkey_name);
772}
773
dbc49afd
CF
774void
775pretty_id (const char *s, char *cygwin, size_t cyglen)
776{
777 char *groups[16384];
778
779 strcpy (cygwin + cyglen++, " ");
780 strcpy (cygwin + cyglen, s);
781 putenv (cygwin);
782
783 char *id = cygpath ("/bin/id.exe", NULL);
bd79b736 784 for (char *p = id; (p = strchr (p, '/')); p++)
dbc49afd
CF
785 *p = '\\';
786
787 if (access (id, X_OK))
7dddf53f
CF
788 {
789 fprintf (stderr, "`id' program not found\n");
790 return;
791 }
dbc49afd
CF
792
793 FILE *f = popen (id, "rt");
794
795 char buf[16384];
7dddf53f 796 buf[0] = '\0';
dbc49afd 797 fgets (buf, sizeof (buf), f);
a5aa8c3e 798 pclose (f);
7dddf53f
CF
799 char *uid = strtok (buf, ")");
800 if (uid)
801 uid += strlen ("uid=");
802 else
902edd45
CF
803 {
804 fprintf (stderr, "garbled output from `id' command - no uid= found\n");
167f0d85 805 return;
902edd45 806 }
7dddf53f
CF
807 char *gid = strtok (NULL, ")");
808 if (gid)
809 gid += strlen ("gid=") + 1;
810 else
902edd45
CF
811 {
812 fprintf (stderr, "garbled output from `id' command - no gid= found\n");
167f0d85 813 return;
902edd45
CF
814 }
815
816 char **ng = groups - 1;
0ffa77a9
CF
817 size_t len_uid = strlen ("UID: )") + strlen (uid);
818 size_t len_gid = strlen ("GID: )") + strlen (gid);
0597641a
CF
819 *++ng = groups[0] = (char *) alloca (len_uid + 1);
820 *++ng = groups[1] = (char *) alloca (len_gid + 1);
902edd45
CF
821 sprintf (groups[0], "UID: %s)", uid);
822 sprintf (groups[1], "GID: %s)", gid);
823 size_t sz = max (len_uid, len_gid);
824 while ((*++ng = strtok (NULL, ",")))
dbc49afd
CF
825 {
826 char *p = strchr (*ng, '\n');
827 if (p)
828 *p = '\0';
902edd45 829 if (ng == groups + 2)
6806f4f6 830 *ng += strlen (" groups=");
dbc49afd
CF
831 size_t len = strlen (*ng);
832 if (sz < len)
833 sz = len;
834 }
167f0d85 835 ng--;
dbc49afd 836
6806f4f6 837 printf ("\nOutput from %s (%s)\n", id, s);
167f0d85 838 int n = 80 / (int) ++sz;
eedf2474 839 int i = n > 2 ? n - 2 : 0;
167f0d85
CF
840 sz = -sz;
841 for (char **g = groups; g <= ng; g++)
842 if ((g != ng) && (++i < n))
eedf2474 843 printf ("%*s", sz, *g);
902edd45
CF
844 else
845 {
846 puts (*g);
847 i = 0;
848 }
dbc49afd
CF
849}
850
67763c0c 851static void
1fd5e000
CF
852dump_sysinfo ()
853{
854 int i, j;
855 char tmp[4000];
856 time_t now;
749bdbe9 857 char *found_cygwin_dll;
1fd5e000 858
0cf94b8c 859 printf ("\nCygwin Configuration Diagnostics\n");
1fd5e000
CF
860 time (&now);
861 printf ("Current System Time: %s\n", ctime (&now));
862
863 OSVERSIONINFO osversion;
864 osversion.dwOSVersionInfoSize = sizeof (osversion);
64069abe
CF
865 if (!GetVersionEx (&osversion))
866 keyeprint ("dump_sysinfo: GetVersionEx()");
1fd5e000
CF
867 char *osname = (char *) "unknown OS";
868 switch (osversion.dwPlatformId)
869 {
870 case VER_PLATFORM_WIN32s:
e4087b75 871 osname = (char *) "32s";
1fd5e000
CF
872 break;
873 case VER_PLATFORM_WIN32_WINDOWS:
874 switch (osversion.dwMinorVersion)
875 {
876 case 0:
b56dedef 877 if (strchr (osversion.szCSDVersion, 'C'))
e4087b75 878 osname = (char *) "95 OSR2";
9a6c0a24 879 else
e4087b75 880 osname = (char *) "95";
1fd5e000 881 break;
9a6c0a24 882 case 10:
b56dedef 883 if (strchr (osversion.szCSDVersion, 'A'))
e4087b75 884 osname = (char *) "98 SE";
9a6c0a24 885 else
e4087b75 886 osname = (char *) "98";
9a6c0a24
CV
887 break;
888 case 90:
e4087b75 889 osname = (char *) "ME";
1fd5e000
CF
890 break;
891 default:
e4087b75 892 osname = (char *) "9X";
1fd5e000
CF
893 break;
894 }
895 break;
896 case VER_PLATFORM_WIN32_NT:
9a6c0a24
CV
897 if (osversion.dwMajorVersion == 5)
898 {
e4087b75
CV
899 BOOL more_info = FALSE;
900 OSVERSIONINFOEX osversionex;
901 osversionex.dwOSVersionInfoSize = sizeof (osversionex);
b56dedef 902 if (GetVersionEx ((OSVERSIONINFO *) &osversionex))
e4087b75 903 more_info = TRUE;
9a6c0a24 904 if (osversion.dwMinorVersion == 0)
e4087b75
CV
905 {
906 if (!more_info)
907 osname = (char *) "2000";
5e051b1b 908 else if (osversionex.wProductType == VER_NT_SERVER
b56dedef
CF
909 || osversionex.wProductType ==
910 VER_NT_DOMAIN_CONTROLLER)
911 {
912 if (osversionex.wSuiteMask &VER_SUITE_DATACENTER)
5e051b1b
CV
913 osname = (char *) "2000 Datacenter Server";
914 else if (osversionex.wSuiteMask & VER_SUITE_ENTERPRISE)
915 osname = (char *) "2000 Advanced Server";
916 else
917 osname = (char *) "2000 Server";
b56dedef 918 }
e4087b75 919 else
b56dedef 920 osname = (char *) "2000 Professional";
e4087b75 921 }
9a6c0a24 922 else
e4087b75
CV
923 {
924 if (!more_info)
925 osname = (char *) "XP";
5e051b1b 926 else if (osversionex.wProductType == VER_NT_SERVER
b56dedef
CF
927 || osversionex.wProductType ==
928 VER_NT_DOMAIN_CONTROLLER)
929 {
5e051b1b
CV
930 if (osversionex.wSuiteMask & VER_SUITE_ENTERPRISE)
931 osname = (char *) ".NET Enterprise Server";
932 else
933 osname = (char *) ".NET Server";
934 }
e4087b75 935 else if (osversionex.wSuiteMask & VER_SUITE_PERSONAL)
b56dedef 936 osname = (char *) "XP Home Edition";
e4087b75 937 else
b56dedef
CF
938 osname = (char *) "XP Professional";
939
e4087b75 940 }
b56dedef 941 }
9a6c0a24 942 else
e4087b75 943 osname = (char *) "NT";
1fd5e000
CF
944 break;
945 default:
e4087b75 946 osname = (char *) "??";
1fd5e000
CF
947 break;
948 }
d1ba802d
CV
949 printf ("Windows %s Ver %lu.%lu Build %lu %s\n\n", osname,
950 osversion.dwMajorVersion, osversion.dwMinorVersion,
951 osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ?
b56dedef 952 osversion.dwBuildNumber : (osversion.dwBuildNumber & 0xffff),
d1ba802d 953 osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ?
b56dedef 954 osversion.szCSDVersion : "");
1fd5e000
CF
955
956 printf ("Path:");
957 char *s = getenv ("PATH"), *e;
958 char sep = strchr (s, ';') ? ';' : ':';
959 int count_path_items = 0;
960 while (1)
961 {
962 for (e = s; *e && *e != sep; e++);
5f175ea6 963 if (e-s)
82e127ca 964 printf ("\t%.*s\n", e - s, s);
5f175ea6 965 else
82e127ca 966 puts ("\t.");
1fd5e000
CF
967 count_path_items++;
968 if (!*e)
969 break;
970 s = e + 1;
971 }
972
dbc49afd
CF
973 fflush (stdout);
974
ce7a3610
CF
975 char *cygwin = getenv ("CYGWIN");
976 if (cygwin)
977 cygwin -= strlen ("CYGWIN=");
978 else
979 cygwin = const_cast <char *> ("CYGWIN=");
dbc49afd
CF
980 size_t cyglen = strlen (cygwin);
981 cygwin = strcpy ((char *) malloc (cyglen + sizeof (" nontsec")), cygwin);
982 pretty_id ("nontsec", cygwin, cyglen);
983 pretty_id ("ntsec", cygwin, cyglen);
984 cygwin[cyglen] = 0;
985 putenv (cygwin);
986
64069abe
CF
987 if (!GetSystemDirectory (tmp, 4000))
988 keyeprint ("dump_sysinfo: GetSystemDirectory()");
1fd5e000 989 printf ("\nSysDir: %s\n", tmp);
64069abe 990
1fd5e000
CF
991 GetWindowsDirectory (tmp, 4000);
992 printf ("WinDir: %s\n\n", tmp);
993
994
995 if (givehelp)
996 printf ("Here's some environment variables that may affect cygwin:\n");
997 for (i = 0; environ[i]; i++)
998 {
999 char *eq = strchr (environ[i], '=');
1000 if (!eq)
1001 continue;
1002 /* int len = eq - environ[i]; */
1003 for (j = 0; known_env_vars[j]; j++)
1004 {
1005 *eq = 0;
1006 if (strcmp (environ[i], "PATH") == 0)
1007 continue; /* we handle this one specially */
1008 if (strcasecmp (environ[i], known_env_vars[j]) == 0)
1009 printf ("%s = `%s'\n", environ[i], eq + 1);
1010 *eq = '=';
1011 }
1012 }
1013 printf ("\n");
1014
1015 if (verbose)
1016 {
1017 if (givehelp)
1018 printf ("Here's the rest of your environment variables:\n");
1019 for (i = 0; environ[i]; i++)
1020 {
1021 int found = 0;
1022 char *eq = strchr (environ[i], '=');
1023 if (!eq)
1024 continue;
1025 /* int len = eq - environ[i]; */
1026 for (j = 0; known_env_vars[j]; j++)
1027 {
1028 *eq = 0;
1029 if (strcasecmp (environ[i], known_env_vars[j]) == 0)
1030 found = 1;
1031 *eq = '=';
1032 }
1033 if (!found)
1034 {
1035 *eq = 0;
1036 printf ("%s = `%s'\n", environ[i], eq + 1);
1037 *eq = '=';
1038 }
1039 }
1040 printf ("\n");
1041 }
1042
1043 if (registry)
1044 {
1045 if (givehelp)
1046 printf ("Scanning registry for keys with `Cygnus' in them...\n");
1047#if 0
1048 /* big and not generally useful */
1049 scan_registry (0, HKEY_CLASSES_ROOT, (char *) "HKEY_CLASSES_ROOT", 0);
1050#endif
1051 scan_registry (0, HKEY_CURRENT_CONFIG,
1052 (char *) "HKEY_CURRENT_CONFIG", 0);
1053 scan_registry (0, HKEY_CURRENT_USER, (char *) "HKEY_CURRENT_USER", 0);
1054 scan_registry (0, HKEY_LOCAL_MACHINE, (char *) "HKEY_LOCAL_MACHINE", 0);
1055#if 0
1056 /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */
1057 scan_registry (0, HKEY_USERS, (char *) "HKEY_USERS", 0);
1058#endif
1059 printf ("\n");
1060 }
1061 else
1062 printf ("Use `-r' to scan registry\n\n");
1063
1064 if (givehelp)
1065 {
1066 printf ("Listing available drives...\n");
1067 printf ("Drv Type Size Free Flags Name\n");
1068 }
eedc36cb
CF
1069 int prev_mode =
1070 SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1fd5e000
CF
1071 int drivemask = GetLogicalDrives ();
1072
1073 HINSTANCE k32 = LoadLibrary ("kernel32.dll");
eedc36cb 1074 BOOL (WINAPI * gdfse) (LPCSTR, long long *, long long *, long long *) =
1fd5e000 1075 (BOOL (WINAPI *) (LPCSTR, long long *, long long *, long long *))
eedc36cb 1076 GetProcAddress (k32, "GetDiskFreeSpaceExA");
1fd5e000
CF
1077
1078 for (i = 0; i < 26; i++)
1079 {
1080 if (!(drivemask & (1 << i)))
1081 continue;
1082 char drive[4], name[200], fsname[200];
1083 DWORD serno = 0, maxnamelen = 0, flags = 0;
1084 name[0] = name[0] = fsname[0] = 0;
1085 sprintf (drive, "%c:\\", i + 'a');
64069abe
CF
1086 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1087 ERROR_NOT_READY is returned when removeable media drives are empty
b56dedef
CF
1088 (CD, floppy, etc.) */
1089 if (!GetVolumeInformation
1090 (drive, name, sizeof (name), &serno, &maxnamelen, &flags, fsname,
1091 sizeof (fsname)) && GetLastError () != ERROR_NOT_READY)
64069abe 1092 keyeprint ("dump_sysinfo: GetVolumeInformation()");
1fd5e000
CF
1093
1094 int dtype = GetDriveType (drive);
1095 char drive_type[4] = "unk";
1096 switch (dtype)
1097 {
1098 case DRIVE_REMOVABLE:
1099 strcpy (drive_type, "fd ");
1100 break;
1101 case DRIVE_FIXED:
1102 strcpy (drive_type, "hd ");
1103 break;
1104 case DRIVE_REMOTE:
1105 strcpy (drive_type, "net");
1106 break;
1107 case DRIVE_CDROM:
1108 strcpy (drive_type, "cd ");
1109 break;
1110 case DRIVE_RAMDISK:
1111 strcpy (drive_type, "ram");
1112 break;
64069abe
CF
1113 default:
1114 strcpy (drive_type, "unk");
1fd5e000
CF
1115 }
1116
1117 long capacity_mb = -1;
1118 int percent_full = -1;
1119
1120 long long free_me = 0ULL, free_bytes = 0ULL, total_bytes = 1ULL;
eedc36cb 1121 if (gdfse != NULL && gdfse (drive, &free_me, &total_bytes, &free_bytes))
1fd5e000
CF
1122 {
1123 capacity_mb = total_bytes / (1024L * 1024L);
1124 percent_full = 100 - (int) ((100.0 * free_me) / total_bytes);
1125 }
1126 else
1127 {
1128 DWORD spc = 0, bps = 0, fc = 0, tc = 1;
1129 if (GetDiskFreeSpace (drive, &spc, &bps, &fc, &tc))
1130 {
1131 capacity_mb = (spc * bps * tc) / (1024 * 1024);
1132 percent_full = 100 - (int) ((100.0 * fc) / tc);
1133 }
1134 }
1135
1136 printf ("%.2s %s %-6s ", drive, drive_type, fsname);
1137 if (capacity_mb >= 0)
1138 printf ("%5dMb %3d%% ", (int) capacity_mb, (int) percent_full);
1139 else
1140 printf (" N/A N/A ");
1141 printf ("%s %s %s %s %s %s %s\n",
1142 flags & FS_CASE_IS_PRESERVED ? "CP" : " ",
1143 flags & FS_CASE_SENSITIVE ? "CS" : " ",
1144 flags & FS_UNICODE_STORED_ON_DISK ? "UN" : " ",
1145 flags & FS_PERSISTENT_ACLS ? "PA" : " ",
1146 flags & FS_FILE_COMPRESSION ? "FC" : " ",
1147 flags & FS_VOL_IS_COMPRESSED ? "VC" : " ",
1148#if 0
1149 flags & FILE_SUPPORTS_ENCRYPTION ? "EN" : " ",
1150 flags & FILE_SUPPORTS_OBJECT_IDS ? "OI" : " ",
1151 flags & FILE_SUPPORTS_REPARSE_POINTS ? "RP" : " ",
1152 flags & FILE_SUPPORTS_SPARSE_FILES ? "SP" : " ",
1153 flags & FILE_VOLUME_QUOTAS ? "QU" : " ",
1154#endif
1155 name);
1156 }
1157
64069abe
CF
1158 if (!FreeLibrary (k32))
1159 keyeprint ("dump_sysinfo: FreeLibrary()");
1fd5e000
CF
1160 SetErrorMode (prev_mode);
1161 if (givehelp)
1162 {
1163 printf ("fd=floppy, hd=hard drive, cd=CD-ROM, net=Network Share\n");
1164 printf ("CP=Case Preserving, CS=Case Sensitive, UN=Unicode\n");
eedc36cb
CF
1165 printf
1166 ("PA=Persistent ACLS, FC=File Compression, VC=Volume Compression\n");
1fd5e000
CF
1167 }
1168 printf ("\n");
1169
ad466e2f 1170 unsigned ml_fsname = 4, ml_dir = 7, ml_type = 6;
0795a245 1171 bool ml_trailing = false;
1fd5e000 1172
2fac517d
CF
1173 struct mntent *mnt;
1174 setmntent (0, 0);
1175 while ((mnt = getmntent (0)))
1176 {
ad466e2f 1177 unsigned n = (int) strlen (mnt->mnt_fsname);
0795a245 1178 ml_trailing |= (n > 1 && strchr ("\\/", mnt->mnt_fsname[n - 1]));
2fac517d
CF
1179 if (ml_fsname < n)
1180 ml_fsname = n;
1181 n = (int) strlen (mnt->mnt_dir);
0795a245 1182 ml_trailing |= (n > 1 && strchr ("\\/", mnt->mnt_dir[n - 1]));
2fac517d
CF
1183 if (ml_dir < n)
1184 ml_dir = n;
1185 }
1186
0795a245
CF
1187 if (ml_trailing)
1188 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1189
1fd5e000
CF
1190 if (givehelp)
1191 {
eedc36cb
CF
1192 printf
1193 ("Mount entries: these map POSIX directories to your NT drives.\n");
1194 printf ("%-*s %-*s %-*s %s\n", ml_fsname, "-NT-", ml_dir, "-POSIX-",
1fd5e000
CF
1195 ml_type, "-Type-", "-Flags-");
1196 }
1197
1fd5e000 1198 setmntent (0, 0);
1fd5e000
CF
1199 while ((mnt = getmntent (0)))
1200 {
1201 printf ("%-*s %-*s %-*s %s\n",
1202 ml_fsname, mnt->mnt_fsname,
eedc36cb 1203 ml_dir, mnt->mnt_dir, ml_type, mnt->mnt_type, mnt->mnt_opts);
1fd5e000
CF
1204 }
1205 printf ("\n");
1206
1207 add_path ((char *) "\\bin", 4); /* just in case */
1208
1209 if (givehelp)
eedc36cb
CF
1210 printf
1211 ("Looking to see where common programs can be found, if at all...\n");
1fd5e000
CF
1212 for (i = 0; common_apps[i].name; i++)
1213 if (!find_on_path ((char *) common_apps[i].name, (char *) ".exe", 1, 0))
eedc36cb
CF
1214 {
1215 if (common_apps[i].missing_is_good)
1216 printf ("Not Found: %s (good!)\n", common_apps[i].name);
1217 else
1218 printf ("Not Found: %s\n", common_apps[i].name);
1219 }
1fd5e000
CF
1220 printf ("\n");
1221
1222 if (givehelp)
1223 printf ("Looking for various Cygnus DLLs... (-v gives version info)\n");
1224 for (i = 0; i < num_paths; i++)
1225 {
1226 WIN32_FIND_DATA ffinfo;
1227 sprintf (tmp, "%s/*.*", paths[i]);
1228 HANDLE ff = FindFirstFile (tmp, &ffinfo);
1229 int found = (ff != INVALID_HANDLE_VALUE);
749bdbe9 1230 found_cygwin_dll = NULL;
1fd5e000
CF
1231 while (found)
1232 {
1233 char *f = ffinfo.cFileName;
1234 if (strcasecmp (f + strlen (f) - 4, ".dll") == 0)
1235 {
1236 if (strncasecmp (f, "cyg", 3) == 0)
1237 {
1238 sprintf (tmp, "%s\\%s", paths[i], f);
749bdbe9
CF
1239 if (strcasecmp (f, "cygwin1.dll") == 0)
1240 found_cygwin_dll = strdup (tmp);
1241 else
1242 ls (tmp);
1fd5e000
CF
1243 }
1244 }
1245 found = FindNextFile (ff, &ffinfo);
1246 }
749bdbe9
CF
1247 if (found_cygwin_dll)
1248 {
1249 ls (found_cygwin_dll);
1250 free (found_cygwin_dll);
1251 }
1252
1fd5e000
CF
1253 FindClose (ff);
1254 }
1255}
1256
67763c0c 1257static int
41a0695b
CV
1258check_keys ()
1259{
1260 HANDLE h = CreateFileA ("CONIN$", GENERIC_READ | GENERIC_WRITE,
eedc36cb
CF
1261 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1262 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
41a0695b
CV
1263
1264 if (h == INVALID_HANDLE_VALUE || h == NULL)
64069abe 1265 return (keyeprint ("check_key: Opening CONIN$"));
41a0695b
CV
1266
1267 DWORD mode;
1268
1269 if (!GetConsoleMode (h, &mode))
64069abe 1270 keyeprint ("check_keys: GetConsoleMode()");
41a0695b
CV
1271 else
1272 {
1273 mode &= ~ENABLE_PROCESSED_INPUT;
1274 if (!SetConsoleMode (h, mode))
64069abe 1275 keyeprint ("check_keys: GetConsoleMode()");
41a0695b
CV
1276 }
1277
1278 fputs ("\nThis key check works only in a console window,", stderr);
1279 fputs (" _NOT_ in a terminal session!\n", stderr);
1280 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr);
1281 fputs ("Press `q' to exit.\n", stderr);
1282
1283 INPUT_RECORD in, prev_in;
1284
1285 // Drop first <RETURN> key
1286 ReadConsoleInput (h, &in, 1, &mode);
1287
1288 memset (&in, 0, sizeof in);
1289
1290 do
1291 {
1292 prev_in = in;
1293 if (!ReadConsoleInput (h, &in, 1, &mode))
eedc36cb 1294 keyeprint ("ReadConsoleInput");
41a0695b
CV
1295
1296 if (!memcmp (&in, &prev_in, sizeof in))
eedc36cb 1297 continue;
41a0695b
CV
1298
1299 switch (in.EventType)
eedc36cb
CF
1300 {
1301 case KEY_EVENT:
1302 printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ",
1303 in.Event.KeyEvent.bKeyDown ? "Pressed " : "Released",
1304 in.Event.KeyEvent.wRepeatCount,
1305 in.Event.KeyEvent.wVirtualKeyCode,
1306 in.Event.KeyEvent.wVirtualScanCode,
1307 (unsigned char) in.Event.KeyEvent.uChar.AsciiChar);
1308 fputs (in.Event.KeyEvent.dwControlKeyState & CAPSLOCK_ON ?
1309 "CL " : "-- ", stdout);
1310 fputs (in.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY ?
1311 "EK " : "-- ", stdout);
1312 fputs (in.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED ?
1313 "LA " : "-- ", stdout);
1314 fputs (in.Event.KeyEvent.dwControlKeyState & LEFT_CTRL_PRESSED ?
1315 "LC " : "-- ", stdout);
1316 fputs (in.Event.KeyEvent.dwControlKeyState & NUMLOCK_ON ?
1317 "NL " : "-- ", stdout);
1318 fputs (in.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED ?
1319 "RA " : "-- ", stdout);
1320 fputs (in.Event.KeyEvent.dwControlKeyState & RIGHT_CTRL_PRESSED ?
1321 "RC " : "-- ", stdout);
1322 fputs (in.Event.KeyEvent.dwControlKeyState & SCROLLLOCK_ON ?
1323 "SL " : "-- ", stdout);
1324 fputs (in.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED ?
1325 "SH " : "-- ", stdout);
1326 fputc ('\n', stdout);
1327 break;
1328
64069abe
CF
1329 default:
1330 break;
eedc36cb 1331 }
41a0695b
CV
1332 }
1333 while (in.EventType != KEY_EVENT ||
eedc36cb
CF
1334 in.Event.KeyEvent.bKeyDown != FALSE ||
1335 in.Event.KeyEvent.uChar.AsciiChar != 'q');
41a0695b
CV
1336
1337 CloseHandle (h);
1338 return 0;
1339}
eedc36cb 1340
67763c0c 1341static void
b56dedef 1342usage (FILE * stream, int status)
1fd5e000 1343{
67763c0c 1344 fprintf (stream, "\
aa275fe0
JDF
1345Usage: cygcheck [OPTIONS] [PROGRAM...]\n\
1346Check system information or PROGRAM library dependencies\n\
1347\n\
200f243c 1348 -c, --check-setup check packages installed via setup.exe\n\
59a76035 1349 -d, --dump-only no integrity checking of package contents (requires -c)\n\
200f243c 1350 -s, --sysinfo system information (not with -k)\n\
59a76035 1351 -v, --verbose verbose output (indented) (for -[cfls] or programs)\n\
200f243c
CV
1352 -r, --registry registry search (requires -s)\n\
1353 -k, --keycheck perform a keyboard check session (not with -[scfl])\n\
1354 -f, --find-package find installed packages containing files (not with -[cl])\n\
1355 -l, --list-package list the contents of installed packages (not with -[cf])\n\
1356 -h, --help give help about the info (not with -[cfl])\n\
1357 -V, --version output version information and exit\n\
67763c0c
CF
1358You must at least give either -s or -k or a program name\n");
1359 exit (status);
1fd5e000
CF
1360}
1361
41a0695b 1362struct option longopts[] = {
d0d51791 1363 {"check-setup", no_argument, NULL, 'c'},
59a76035 1364 {"dump-only", no_argument, NULL, 'd'},
eedc36cb
CF
1365 {"sysinfo", no_argument, NULL, 's'},
1366 {"registry", no_argument, NULL, 'r'},
1367 {"verbose", no_argument, NULL, 'v'},
1368 {"keycheck", no_argument, NULL, 'k'},
200f243c
CV
1369 {"find-package", no_argument, NULL, 'f'},
1370 {"list-package", no_argument, NULL, 'l'},
eedc36cb 1371 {"help", no_argument, NULL, 'h'},
b9262dd9 1372 {"version", no_argument, 0, 'V'},
eedc36cb 1373 {0, no_argument, NULL, 0}
41a0695b 1374};
ce475802 1375
59a76035 1376static char opts[] = "cdfhklrsvV";
67763c0c
CF
1377
1378static void
1379print_version ()
1380{
1381 const char *v = strchr (version, ':');
1382 int len;
1383 if (!v)
1384 {
1385 v = "?";
1386 len = 1;
1387 }
1388 else
1389 {
1390 v += 2;
1391 len = strchr (v, ' ') - v;
1392 }
1393 printf ("\
1394cygcheck version %.*s\n\
1395System Checker for Cygwin\n\
c662f402 1396Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.\n\
98467dae
JDF
1397Compiled on %s\n\
1398", len, v, __DATE__);
67763c0c 1399}
41a0695b 1400
1fd5e000
CF
1401int
1402main (int argc, char **argv)
1403{
1404 int i;
1fd5e000 1405
744ed079 1406 (void) putenv("POSIXLY_CORRECT=1");
41a0695b
CV
1407 while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
1408 switch (i)
1409 {
1410 case 's':
eedc36cb
CF
1411 sysinfo = 1;
1412 break;
d0d51791
CF
1413 case 'c':
1414 check_setup = 1;
1415 break;
59a76035
CV
1416 case 'd':
1417 dump_only = 1;
1418 break;
41a0695b 1419 case 'r':
eedc36cb
CF
1420 registry = 1;
1421 break;
41a0695b 1422 case 'v':
eedc36cb
CF
1423 verbose = 1;
1424 break;
41a0695b 1425 case 'k':
eedc36cb
CF
1426 keycheck = 1;
1427 break;
200f243c
CV
1428 case 'f':
1429 find_package = 1;
1430 break;
1431 case 'l':
1432 list_package = 1;
1433 break;
41a0695b 1434 case 'h':
eedc36cb
CF
1435 givehelp = 1;
1436 break;
67763c0c
CF
1437 case 'V':
1438 print_version ();
b56dedef 1439 exit (0);
41a0695b 1440 default:
67763c0c 1441 usage (stderr, 1);
eedc36cb 1442 /*NOTREACHED*/}
41a0695b
CV
1443 argc -= optind;
1444 argv += optind;
1445
35e15d99 1446 if (argc == 0 && !sysinfo && !keycheck && !check_setup)
b56dedef
CF
1447 if (givehelp)
1448 usage (stdout, 0);
1449 else
1450 usage (stderr, 1);
41a0695b 1451
200f243c
CV
1452 if ((check_setup || sysinfo || find_package || list_package) && keycheck)
1453 usage (stderr, 1);
1454
1455 if ((find_package || list_package) && check_setup)
1456 usage (stderr, 1);
1457
59a76035
CV
1458 if (dump_only && !check_setup)
1459 usage (stderr, 1);
1460
200f243c 1461 if (find_package && list_package)
67763c0c 1462 usage (stderr, 1);
1fd5e000 1463
41a0695b 1464 if (keycheck)
eedc36cb 1465 return check_keys ();
41a0695b 1466
1fd5e000
CF
1467 init_paths ();
1468
200f243c
CV
1469 /* FIXME: Add help for check_setup and {list,find}_package */
1470 if (argc >= 1 && givehelp && !check_setup && !find_package && !list_package)
1fd5e000 1471 {
200f243c
CV
1472 printf("Here is where the OS will find your program%s, and which dlls\n",
1473 argc > 1 ? "s" : "");
1474 printf ("will be used for it. Use -v to see DLL version info\n");
1fd5e000
CF
1475
1476 if (!sysinfo)
1477 printf ("\n");
1478 }
1479
d0d51791 1480 if (check_setup)
1fd5e000 1481 {
59a76035 1482 dump_setup (verbose, argv, !dump_only);
200f243c
CV
1483 }
1484 else if (find_package)
1485 {
1486 package_find (verbose, argv);
1487 }
1488 else if (list_package)
1489 {
1490 package_list (verbose, argv);
1fd5e000 1491 }
d0d51791
CF
1492 else
1493 for (i = 0; i < argc; i++)
1494 {
200f243c
CV
1495 if (i)
1496 puts ("");
d0d51791 1497 cygcheck (argv[i]);
d0d51791 1498 }
1fd5e000
CF
1499
1500 if (sysinfo)
da9e28d0
CF
1501 {
1502 dump_sysinfo ();
1503 if (!check_setup)
1504 {
e1af9739 1505 puts ("");
71f90de8 1506 dump_setup (verbose, NULL, false);
da9e28d0 1507 }
1fd5e000 1508
200f243c
CV
1509 if (!givehelp)
1510 puts ("Use -h to see help about each section");
1511 }
1fd5e000
CF
1512
1513 return 0;
1514}
This page took 0.295066 seconds and 5 git commands to generate.