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