From be287e357921486f71c5679b1b8d3902640166aa Mon Sep 17 00:00:00 2001 From: cvs2svn <> Date: Fri, 23 Jan 2004 23:04:28 +0000 Subject: This commit was manufactured by cvs2svn to create branch 'cr-0x9e'. Cherrypick from master 2004-01-23 23:04:27 UTC Christopher Faylor '* cygcheck.cc (pretty_id): Make more robust in absence of id.exe.': winsup/utils/ChangeLog winsup/utils/cygcheck.cc winsup/utils/cygpath.cc --- winsup/utils/ChangeLog | 1331 ++++++++++++++++++++++++++++++++++++++++ winsup/utils/cygcheck.cc | 1500 ++++++++++++++++++++++++++++++++++++++++++++++ winsup/utils/cygpath.cc | 771 ++++++++++++++++++++++++ 3 files changed, 3602 insertions(+) create mode 100644 winsup/utils/ChangeLog create mode 100644 winsup/utils/cygcheck.cc create mode 100644 winsup/utils/cygpath.cc diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog new file mode 100644 index 000000000..cca686c46 --- /dev/null +++ b/winsup/utils/ChangeLog @@ -0,0 +1,1331 @@ +2004-01-23 Christopher Faylor + + * cygcheck.cc (pretty_id): Make more robust in absence of id.exe. + +2004-01-22 Corinna Vinschen + + * cygpath.cc (dowin): Revert accidental checkin from November. + +2003-11-26 Corinna Vinschen + + * mkgroup.c (main): Print "root" group with local admins group sid + and gid 0. + +2003-11-19 Corinna Vinschen + + * Makefile.in: Add rules to build ipcrm and ipcs. + * ipcrm.c: New file. + * ipcs.c: New file. + +2003-11-14 Corinna Vinschen + + * mkgroup.c: Avoid compiler warnings throughout. + * mkpasswd.c: Ditto. + * passwd.c: Ditto. + +2003-11-07 Mark Blackburn + + * cygpath.cc (main): Allow multiple pathnames on command line. + +2003-11-04 Corinna Vinschen + + * passwd.c (PrintPW): Turn around meaning printed for "Password not + required" option to be in line with Windows meaning. + (main): Use more appropriate 1008 option when calling + NetUserSetInfo to change flag values. + +2003-11-04 Corinna Vinschen + + * passwd.c (UF_LOCKOUT): Remove (defined in lmaccess.h). + (version): Bump version number to 1.5. + (longopts): Add -c, -C, -e, -E, -p, -P options. + (opts): Ditto. + (PrintPW): Print values of UF_PASSWD_CANT_CHANGE and + UF_DONT_EXPIRE_PASSWD flags. Slightly reformat output. Don't suppress + correct system password settings just because the account has admin + privileges. + (usage): Define as "noreturn" function. Restructure and rephrase + output. Accomodate new options. + (print_version): Fix copyright dates. + (main): Accomodate new options for setting UF_PASSWD_CANT_CHANGE, + UF_DONT_EXPIRE_PASSWD and UF_PASSWD_NOTREQD settings. + +2003-10-17 Christopher Faylor + + * cygcheck.cc (pretty_id): Don't exec if `id' program is not found. + +2003-09-20 Christopher Faylor + + * kill.cc (main): Allow negative pids (indicates process groups). + +2003-09-17 Christopher Faylor + + * parse_pe.cc (exclusion::sort_and_check): Make error message a little + more explicit and ignore (hopefully) harmless region overlap. + +2003-09-13 Christopher Faylor + + * kill.c (forcekill): Wait for process to terminate even if + TerminateProcess says it failed. + +2003-09-11 Christopher Faylor + + * Makefile.in: Tweak mingw libz.a detection to make it more reliably + detect when libz.a is not available. + +2003-09-11 Igor Pechtchanski + + * cygcheck.cc (dump_only): New global variable. + (usage): Add "--dump-only" option, fix "--verbose" line. + (longopts, opts): Add "--dump-only" option. + (main): Process the "--dump-only" flag. Add new semantic check. + Pass dump_only information to dump_setup(). + +2003-09-11 Corinna Vinschen + + * getfacl (main): Remove extern declaration of optind. + * setfacl (main): Remove extern declaration of optarg and optind. + +2003-09-10 Christopher Faylor + + * Makefile.in (cygcheck.o): Use MINGW_CXX for compilation. + * cygcheck.cc: Just include rather than cygwin version. + (pretty_id): Avoid compiler warnings. + * cygpath.cc (usage): Ditto. + +2003-09-10 Christopher Faylor + + * Makefile.in (MINGW_CXX): Define and use for mingw-compiled files. + * path.cc: Include more path info in cygwin-specific includes since the + cygwin directory is no longer included by default. + +2003-09-10 Christopher Faylor + + * Makefile.in: More fixups to adjust for the fact that mingw_getopt.o + is no longer built. + +2003-09-10 Christopher Faylor + + * Makefile.in: Remove references to getopt since it is now part of + mingwex. + +2003-09-08 Christopher Faylor + + * Makefile.in: Rename libz.h -> zlib.h. + +2003-09-07 Christopher Faylor + + * Makefile.in: Detect existence of mingw zlib headers and libraries. + Build cygcheck without package checking if they are unavailable. + * dump_setup.cc: Generate dummy zlib macros when zlib is not available. + (open_package_list): Use zlib functions to uncompress package lists. + Return gzFile rather than FILE *. + (check_package_files): Change fp to gzFile to accommodate zlib + functions. Use gzgets to read from package file. Use gzclose to close + the handle. + (package_list): Ditto. + (package_find): Ditto. + +2003-09-05 Igor Pechtchanski + + * dump_setup.cc (check_package_files): Don't fail on empty package. + +2003-09-01 AJ Reins + + * mount.cc (mount_commands): Ensure user mode is actually user mode and + not the default system mode. + +2003-08-31 Christopher Faylor + + * kill.cc (forcekill): Silence some compiler warnings. + +2003-08-31 Christopher Faylor + + * Makefile.in: Oops. Put the '...' in the right place. + +2003-08-31 Christopher Faylor + + * Makefile.in: Display "..." when not-verbose. + + * kill.cc (forcekill): Default to entered pid when pinfo fails. Issue + some warnings when things don't work. + +2003-08-17 David Rothenberger + + * dump_setup.cc (check_package_files): Strip leading / and ./ from + package file names. + +2003-08-16 David Rothenberger + + * dump_setup.cc (package_find): Don't stop searching on missing + file list. + (package_list): Ditto. + +2003-08-16 Igor Pechtchanski + + * dump_setup.cc: (package_list): Make output terse unless + verbose requested. Fix formatting. + (package_find): Ditto. + +2003-08-15 Corinna Vinschen + + * cygcheck.cc (main): Fix some formatting and help text printing. + +2003-08-15 Igor Pechtchanski + + * cygcheck.cc (find_package,list_package): New global + variables. + (usage): Add "--find-package" and "--list-package" options, + reformat output. + (longopts, opts): Add "--find-package" and "--list-package" + options. + (main): Process the "--find-package" and "--list-package" + flags. Add new semantic checks. Add calls to find_package() + and list_package(). + * dump_setup.cc: Fix header comment. + (match_argv): Change return type to int to distinguish + between real matches and default ones. + (open_package_list): New static function. + (check_package_files): Factor out opening the package list + file into open_package_list(). + (get_packages): New static function. + (dump_setup): Factor out getting a list of packages into + get_packages(). + (package_list, package_find): New global functions. + +2003-08-15 Corinna Vinschen + + * regtool.cc (usage): Add missing linefeed. Move example to --help + text. Fix forward slash description. + +2003-08-13 Igor Pechtchanski + + * dump_setup.cc (check_package_files): Fix extra '/' in filename. + Resize command buffer. Fix buffer overflow bug. + +2003-08-09 Igor Pechtchanski + Christopher Faylor + + * dump_setup.cc (dump_setup): Check for the existence of the package + list file. Rework slightly to use static buffer for popen commands. + +2003-08-07 Igor Pechtchanski + Christopher Faylor + + * dump_setup.cc (version_len): New static variable. + (could_not_access,directory_exists): New static function. + (file_exists): Ditto. + (check_package_files): Ditto. + (dump_setup): Check the contents of each package if check_files is true + and output the result in the "Status" column. Flush output after each + package. + +2003-08-07 Igor Pechtchanski + Christopher Faylor + + * dump_setup.cc (dump_setup): Remove redundant null check. Add + informative message if package info not found. + +2003-07-26 Christopher Faylor + + * mount.cc (do_mount): Issue warning when using managed mount option on + non-empty directory. + +2003-07-25 Christopher Faylor + + * configure.in: Use 'install-sh -c'. + * configure: Regenerate. + +2003-07-25 Christopher Faylor + + * configure.in: Always use install-sh. + * configure: Regenerate. + +2003-07-03 Christopher Faylor + + * mount.cc (struct opt): Remove posix option. + +2003-07-03 Christopher Faylor + + * mount.cc (longopts): Add long "options" keyword. + (opts): Add -o option. + (usage): Display -o option. + (struct opt): New. + (concat3): New function. + (main): Handle -o flag. + +2003-06-12 Christopher Faylor + + * cygcheck.cc (pretty_id): Rework slightly to not rely on spaces. + +2003-06-12 Christopher Faylor + + * cygpath.cc: Throughout, always return error when GetShortPathName + returns 0. + +2003-04-26 Joshua Daniel Franklin + + * mkpasswd.c (usage) Remove extra newline from description output. + +2003-04-26 Joshua Daniel Franklin + + * cygcheck.cc (usage) Add description output. + * cygpath.cc (usage) Add description output. + * dumper.cc (usage) Add newline to description output. + * kill.cc (usage) Add description output. + * mkgroup.c (usage) Grammatical change to description output. + * mkpasswd.c (usage) Grammatical change to description output. + * mount.cc (usage) Add description output. + * passwd.c (usage) Add description output. + * ps.cc (usage) Add description output. + * regtool.cc (usage) Add description output. + * setfacl.c (usage) Remove extra newline from description output. + * ssp.c (usage) Add description output. + * strace.cc (usage) Add description output. + * umount.cc (usage) Add description output. + +2003-04-10 Pierre Humblet + + * mkpasswd.c (current_user): print uid and gid as unsigned. + (enum_users): Ditto. Do not free servername. + (usage): Update to allow several domains and improve -p. + (main): On Win9x limit uids to 1000. Only print specials + when -l is specified. Add a loop to allow several domains + and free servername in the loop. + * mkgroup.c (enum_groups): Do not free servername. + (usage): Update to allow several domains. Change uid to gid. + (main): Only print specials when -l is specified. Add a + loop to allow several domains and free servername in the loop. + +2003-03-24 Christopher Faylor + + * cygcheck.cc (dump_sysinfo): Ensure that CYGWIN environment variable + is correctly set. + +2003-03-09 Corinna Vinschen + + * getfacl.c (username): Fix ambiguous printf calls. + (groupname): Ditto. + (main): Ditto. + +2003-03-04 Christopher Faylor + + * Makefile.in (strace.exe): Include mingw_getopt.o in link line. + * cygcheck.cc (print_version): Update copyright. + * strace.cc (print_version): Ditto. + (main): Allow cygwin paths for -o option. + (create_child): Allow cygwin path as argv[0]. + * path.cc (path.cc): Allow UNC paths. + +2003-03-01 Pierre Humblet + + * mkpasswd.cc (main): On Win95, output both a default line and a + line for the current user (if known) with a pseudorandom uid. If + the -u switch is given, produce a line for the specified user. + * mkgroup.cc (main): On Win95 change the group name from "unknown" to + "all". + +2003-02-28 Christopher Faylor + + * Makefile.in (cygcheck.o): Fix so that actual mingw include files are + used. + * cygcheck.cc (find_on_path): Translate from cygwin path when qualified + path name found. + (pretty_id): New function. Dump output of id command. + (dump_sysinfo): Call pretty_id for CYGWIN=ntsec and CYGWIN=nontsec cases. + +2003-02-12 Christopher Faylor + + * cygpath.cc (doit): Allocate more space for non-path filename. + +2003-02-07 Christopher Faylor + + * dump_setup.cc (compar): Use case insensitive comparisons. + (dump_setup): Calculate package_len based on already used "len". Don't + bother with version_len. + +2003-02-07 Igor Pechtchanski + + * dump_setup.cc (dump_setup): Compute the longest package name + and align columns properly. + +2003-02-06 Christopher Faylor + + * cygcheck.cc (common_apps): Add some more apps. + * path.cc (get_cygdrive): Correctly set system flag. + +2003-01-22 Corinna Vinschen + + * Makefile.in (ALL_LDFLAGS): Remove newlib/libm from tools paths. + (MINGW_LDFLAGS): Remove in favor of definition from Makefile.common. + +2003-01-15 Corinna Vinschen + + * mkgroup.c: Fix copyright date. + * mkpasswd.c: Ditto. + * setfacl.c: Ditto. + +2003-01-09 Pierre Humblet + + * setfacl.c (usage): Remove double ":" for mask and other. + +2003-01-07 Pierre Humblet + + * mkpasswd.c (current_user): Create. + (usage): Reorganize to support Win95/98/ME. + (main): Add option for -c. Reorganize to parse options for + Win95/98/ME and to call current_user. Add username in gecos field + on Win95/98/ME. + * mkgroup.c (enum_groups): Print gid with %u. + (print_win_error): Create from passwd.cc. + (current_group): Create. + (usage): Reorganize to support Win95/98/ME. + (main): Add option for -c. Reorganize to parse options for + Win95/98/ME and to call current_group. + +2002-12-14 Pierre Humblet + + * setfacl.c (main): Place a single : after other and mask. + * getfacl.c (getaclentry): Allow both : and :: for other and mask. + (main): Remove extraneous break. + +2002-11-25 Corinna Vinschen + + * mkpasswd.c (main): Set pw_passwd field to '*' on 9x/Me. + +2002-11-24 Corinna Vinschen + + * setfacl.c (getperm): Set only `other' permission bits. + (getaclentry): Set a_id to -1 by default. + +2002-11-24 Corinna Vinschen + + * getfacl.c (permstr): Use `other' permission bits for requesting + ace permissions. + +2002-11-08 Corinna Vinschen + + * setfacl.c (usage): Add missing LF. + +2002-10-30 Christopher Faylor + + * cygpath.cc (get_long_path_name_w32impl): Define similarly to + GetLongPathName. + (get_long_name): Correctly prototype GetLongPathName. + (get_long_paths): Implement using get_long_name to cut down on code + duplication. + (doit): Do various things to make path output work predictably. + +2002-10-19 Christopher Faylor + + * mount.cc (usage): Correctly report default mode. + * strace.cc (main): Use strtoul as appropriate. + +2002-09-29 Christopher Faylor + + * cygpath.cc (close_arg): Remove unused static. + * mkgroup.c (enum_local_users): Avoid compiler warning. + (enum_users): Ditto. + * mkpasswd.c: Ditto throughout. + * ssp.c: Ditto throughout. + +2002-09-18 Christopher Faylor + + * cygcheck.cc: Include sys/time.h rather than time.h to avoid a + compiler error. + +2002-09-17 Christopher Faylor + + * cygcheck.cc: Reorder includes to avoid compiler error. + +2002-09-15 Joshua Daniel Franklin + + * cygcheck.cc (print_version) Add final newline. + * getfacl.c (print_version) Add final newline. + * kill.cc (print_version) Add final newline. + * mkgroup.c (print_version) Add final newline. + * mkpasswd.c (print_version) Add final newline. + * mount.cc (print_version) Add final newline. + * passwd.c (print_version) Add final newline. + * ps.cc (print_version) Add final newline. + * regtool.cc (print_version) Add final newline. + * setfacl.c (print_version) Add final newline. + * ssp.c (print_version) Add final newline. + * strace.cc (print_version) Add final newline. + * umount.cc (print_version) Add final newline. + +2002-09-12 Igor Pechtchanski + + * cygpath.cc (options) New global variable. + (main) Make short options global for easier change. + (print_version) Add a missing newline. + +2002-08-07 Igor Pechtchanski + + * regtool.cc (find_key): Add support for custom key separator. + (usage): Document it. + +2002-08-02 Corinna Vinschen + + * mkgroup.c (main): Don't print an entry for "Everyone". + * mkpasswd.c (print_special): Set pw_gid to 544 for SYSTEM user. + (main): Don't print an entry for "Everyone". + +2002-07-06 Christopher Faylor + + * configure.in: Check for libiconv.a. + * configure: Regenerate. + * Makefile.in: Add libiconv.a to libraries required for dumper.exe. + +2002-07-06 Christopher Faylor + + * Makefile.in: Use MINGW stuff from Makefile.common. + +2002-07-01 Corinna Vinschen + + * mkgroup.c: Add function pointers for functions from advapi32.dll. + (load_netapi): Load used functions from advapi32.dll. + (main): Use function pointers instead of statically linked functions + from advapi32.dll. + +2002-07-01 Christopher Faylor + + * mount.cc (main): Ensure that mount_already_exists() also gets default + flag that is passed to do_mount. + +2002-06-22 Joshua Daniel Franklin + + * cygpath.cc (long_options): Add "dos" and "mixed", correct "close", + "file" and "type" to use NULL flag. + (usage): Clean up usage output (more), accomodate new options. + (main): Add --dos and --mixed options; accomodate all output forms in + --type. Make UNIXy output default. + +2002-06-18 Joshua Daniel Franklin + + * cygpath.cc (usage): Clean up usage output. + (dowin): Correct output of -t mixed for -ADHPSW options. + +2002-06-14 Corinna Vinschen + + * passwd.c: Rearrange includes to avoid unnecessary warnings. + (GetPW): Add parameter to (dis)allow printing of Windows username. + Use defines instead of numerical constants where possible. + Try avoiding impersonation problem. Rearrange to print Windows + username only if it's different from Cygwin username. + (ChangePW): Use defines instead of numerical constants where possible. + (main): Call GetPW with additional parameter. Change error text. + +2002-06-14 Joshua Daniel Franklin + + * passwd.c (GetPW): Handle case of user-edited /etc/passwd + with cygwin_internal (CW_EXTRACT_DOMAIN_AND_USER, ...). + +2002-06-09 Christopher Faylor + + * path.cc (cygpath): Change MOUNT_AUTO to MOUNT_CYGDRIVE. + (getmntent): Ditto. + +2002-06-09 Christopher Faylor + + * mount.cc (main): Use default system/user flag for cygdrive stuff, + too. + (change_cygdrive_prefix): Change MOUNT_AUTO to MOUNT_CYGDRIVE. + * umount.cc (remove_cygdrive_prefix): Ditto. + (main): Use default system/user flag for cygdrive stuff, too. + +2002-06-08 Christopher Faylor + + * mount.cc (opts): Remove '-i' option. + (usage): Ditto. + (main): Ditto. + (longopts): Remove --import-old-mounts option. + +2002-06-07 David Peterson + Christopher Faylor + + * cygpath.cc: Add option to output windows paths in different formats: + "dos" and "mixed". + (main): Process options. + (doit): Check new options flags. + +2002-06-06 Egor Duda + + * regtool.cc (Fail): Be more verbose. + (find_key): Add support for remote registry access. + (usage): Document it. + * utils.sgml: Document it. + +2002-06-06 Christopher Faylor + + * strace.cc (main): Make toggle a local variable. + +2002-06-07 Conrad Scott + + * strace.cc (toggle): New global variable. + (error): Use exit instead of ExitProcess so that stdio buffers get + flushed. + (create_child): Remove command line error checking. + (dostrace): Ditto. + (dotoggle): New function. + (usage): Add entry for new option -T|--toggle. Alphabetize. + (longopts): Add new option -T|--toggle. + (opts): Ditto. + (main): Handle new -T|--toggle option. Move all command line checking + here from other functions. + * utils.sgml: Update section for strace. + +2002-06-05 Joshua Daniel Franklin + + * strace.cc (version): New global variable. + (usage): Accommodate stdout output. + (print_version): New function. + +2002-06-03 Joshua Daniel Franklin + + * ssp.c (version): New global variable. + (longopts): Ditto. + (opts): Ditto. + (run_program): Correct cmd_line typos to cmdline. + (usage): New function. Standardize usage output. Add ssp.txt to + --help output. + (print_version): New function. + (main): Accommodate getopt. + +2002-06-03 Joshua Daniel Franklin + + * umount.cc (version): New global variable. + (longopts): Accommodate new --version option. + (opts): Ditto. + (usage): Standardize usage output. + (print_version): New function. + (main): Accommodate --help, --version options. + +2002-06-02 Joshua Daniel Franklin + + * regtool.cc (prog_name): New global variable. + (longopts): Ditto. + (opts): Ditto. + (usage): Standardize usage output. Rearrange/add descriptions. + (print_version): New function. + (main): Accommodate longopts and new --help, --version options. Add + check for (_argv[optind+1] == NULL). + +2002-06-02 Christopher Faylor + + * strace.cc (forkdebug): Make true by default. + (attach_process): Use window pid if cygwin pid isn't available (yet). + (create_child): Use either DEBUG_ONLY_THIS_PROCESS or DEBUG_PROCESS, + exclusively. (Suggested by Conrad.Scott@dsl.pipex.com) + +2002-05-30 Christopher Faylor + + * mkpasswd.cc (main): Don't reset to binmode if stdout is a terminal. + +2002-05-29 Christopher Faylor + + * mount.cc (main): Make -b the default. + +2002-05-29 Corinna Vinschen + + * ps.cc (main): Use uid or uid32 member of struct external_pinfo + dependent of the value of the struct's version member. + +2002-05-29 Corinna Vinschen + + * ps.cc (main): Change print format for uid to unsigned. Use uid32 + member of struct external_pinfo instead of uid. + +2002-05-28 Joshua Daniel Franklin + + * passwd.c (prog_name): New global variable. + (longopts): Ditto. + (opts): Ditto. + (usage): Standardize output. Accommodate new options. + (print_version): New function. + (main): Accommodate longopts and new --help, --version options. + +2002-05-28 Joshua Daniel Franklin + + * ps.cc (usage): Fix typo. + +2002-05-27 Joshua Daniel Franklin + + * ps.cc (prog_name): New global variable. + (longopts): Ditto. + (opts): Ditto. + (usage): New function. + (print_version): New function. + (main): Accommodate longopts and new --help, --version options. + +2002-05-26 Christopher Faylor + + * strace.cc (attach_process): Don't tell process to start stracing + here. + (proc_child): Do it here, instead, after first debug event. This + should work around inexplicable races with DebugActiveProcess. + (dostrace): Pass any pid argument to proc_child. + +2002-05-23 Joshua Daniel Franklin + + * getfacl.c (usage): Standardize usage output. Change return type to + static void. + (print_version): New function. + (longopts): Added longopts for all options. + (main): Accommodate new help and version options. + +2002-05-22 Joshua Daniel Franklin + + * mount.cc (version): New global variable. + (usage): Standardize usage output. Accommodate new version option. + (print_version): New function. + (longopts): Accommodate new version option. + (opts): Ditto. + (main): Ditto. + +2002-05-22 Corinna Vinschen + + * cygpath.cc (usage): Change usage output slightly. + +2002-05-20 Joerg Schaible + + * cygpath.cc (main): Add option l to support conversion to + Windows long file names. Refactured code for capital options. + Support of options from file for capital options. + (dowin): New function. Refactured from main. + (doit): Call long path conversion. + (get_long_name): New function. + (get_long_paths): New function. + (get_long_path_name_w32impl): New function. Reimplementation + of Windows API function GetLongPathName (only 98/Me/2000/XP or + higher). + (get_short_name): Call GetShortPathName only once. + (get_short_paths): Fix calculating buffer size. + * utils.sgml: Update cygpath section for l option. + +2002-05-18 Christopher Faylor + + * strace.cc (add_child): Use calloc since new requires working + libstdc++.a. + (remove_child): Ditto for delete/free. + +2002-05-15 Mark Blackburn + + * cygpath.cc (get_short_paths): Fix more error checking. + (get_short_name): Ditto. + +2002-05-14 Joerg Schaible + + * cygpath.cc (main): Add option H to show the Windows' profiles + directory. Support short names for options DPSW. Clean up + copied code lines. + * utils.sgml: Update cygpath section for H option and s support. + +2002-05-14 Mark Blackburn + + * cygpath.cc (get_short_paths): Fix error checking. + +2002-05-13 Joshua Daniel Franklin + + * kill.cc (prog_name): New global variable. + (usage): Standardize usage output. Add descriptions. + (print_version): New function. + (longopts): Accommodate new version option. + (opts): Ditto. + (main): Ditto. + +2002-05-13 Christopher Faylor + + * kill.cc (listsig): Display numeric id when given symbolic input. + +2002-05-13 Christopher Faylor + + * kill.cc (usage): Show new options. Allow specification of output + stream. + (main): Implement 'h' option. + +2002-05-13 Christopher Faylor + + * Makefile.in (kill.exe): Add as a specific target. + * kill.cc (longopts): New. + (opts): Ditto. + (get_sig): Accept const char * parameter. Return -1 on unknown signal. + (test_for_unknown_sig): New function. + (listsig): New function. + (main): Use getopt_long for option parsing. Implement -l, and -s + options. Use test_for_unknown_sig() to test for signal validity. + + * mount.cc (longopts): Make static. + (opts): Ditto. + +2002-05-12 Christopher Faylor + + * mount.cc (do_mount): Default to non-exec option for remote drives. + Report warnings before attempting a mount. + (longopts): Add no-executable option. + (mount_commands): Ditto. + (opts): Ditto. + (usage): Ditto. Indicate that system mount is now the default. + (main): Accommodate no-executable option. Make system mount the + default. + * umount.cc (usage): Indicate that system umount is now the default. + (main): Make system umount the default. + +2002-05-07 Joshua Daniel Franklin + + * dumper.cc (usage): Standardize usage output. Generalize to allow use + for help. + (longopts): New struct. Added longopts for all options. + (print_version): New function. + (main): Change getopt to getopt_long. Accommodate new help and version + options. + +2002-03-29 Corinna Vinschen + + * mkgroup.c (main): Change call to exit() to a return statement. + * mkpasswd.c (main): Ditto. + +2002-03-27 Joshua Daniel Franklin joshuadfranklin@yahoo.com + + * mkpasswd.c (usage): Simplify usage output. Generalize to allow use + for help. Correct '?' typo to 'h'. + (longopts): Add version option. + (opts): Add 'v' version option. + (print_version): New function. + (main): Accommodate new version option. Accommodate usage parameter + changes. + +2002-03-19 Christopher Faylor + + * mkgroup.c (usage): Use one just fprintf + string concatenation for + output message. + (print_version): Add void to function type and update copyright. + +2002-03-16 Joshua Daniel Franklin + + * mkgroup.c (usage): Simplify usage output. Generalize to allow use + for help. Correct '?' typo to 'h'. + (longopts): Add version option. + (opts): Add 'v' version option. + (print_version): New function. + (main): Accommodate new version option. Accommodate usage parameter + changes. Use usage to output help message. + +2002-03-15 Corinna Vinschen + + * mkgroup.c (main): When generating group 513, check for computer's + primary domain instead of current user's domain. + +2002-03-14 Corinna Vinschen + + * mkgroup.c (main): When generating group 513, check for domain SID + if computer name isn't mapped to a SID. + +2001-03-11 Joshua Daniel Franklin + + * kill.cc (usage): Move to top of file. + (getsig): Ditto. + (forcekill): Ditto. + +2002-03-06 Christopher Faylor + + * cygcheck.cc: Reformat. + +2002-03-06 Christopher Faylor + + * cygcheck.cc (longopts): Use correct short option for --version. + +2002-03-06 Christopher Faylor + + * cygpath.cc: Reformat. + +2002-02-27 Joshua Daniel Franklin + + * cygpath.cc (print_version): New function. + (main): Accommodate new version function. Initialize 'o' to prevent + warning. + +2002-02-27 Christopher Faylor + + * cygcheck.cc (main): Eliminate non-GNU formatting glitch. + +2002-02-27 Christopher Faylor + + * ssp.c (help_desk): Fix compiler warning. + +2002-02-27 Joshua Daniel Franklin + Christopher Faylor + + Change appropriate globals to statics throughout. + * cygcheck.cc (usage): Simplify usage output. Generalize to allow use + for help. + (longopts): Add version option. + (opts): Add 'V" version option. + (print_version): New function. + (main): Accommodate new version option. Accommodate usage parameter + changes. Use usage to output help message. + +002-02-19 Christopher Faylor + + * Makefile.in (CXXFLAGS): Add override so that HAVE_DECL_GETOPT is + defined. + (libbfd): Use -B rather than -L so that bfd from build directory is + correctly found. + (libintl): Ditto. + +2002-02-15 Christopher Faylor + + * mount.cc (usage): Fix typo in output. + +2002-02-14 Christopher Faylor + + * strace.cc (attach_process): Change CW_STRACE_ON to CW_STRACE_TOGGLE. + +2002-01-31 Corinna Vinschen + + * mkpasswd.c (main): Set default home path for 9x/Me if --path-to-home + isn't given. + +2002-01-30 Corinna Vinschen + + * passwd.cc (ChangePW): Add parameter to differ between called for + checking old password and called for changing password. If called + for checking old password, return non-zero only if password is surely + incorrect. + (main): Call ChangePW() with additional parameter. + +2002-01-29 Christopher Faylor + + * dump_setup.cc (parse_filename): Don't consider '_' part of the + version. + +2002-01-28 Christopher Faylor + + * cygcheck.cc: Fix typo. Remove uid_t kludge. Rely on kludge in + sys/cygwin.h instead. + * getfacl.c: Add include to remove warning. + * mkgroup.c (main): Assign variables outside of parameter passing. + This seems to eliminate some compiler warnings. + +2002-01-28 Christopher Faylor + + * cygcheck.cc: Use specific cygwin includes, as required. + +2002-01-28 Christopher Faylor + + * Makefile.in (MINGW_INCLUDES): Change cygwin include. + * strace.cc: Use specific cygwin includes, as required. + (load_cygwin): New function. Loads cygwin DLL, if necessary. + (attach_process): Attaches strace to a running process. + (dostrace): Accept pid argument. Attach to pid if supplied. + (usage): Describe -p option. Correct system description. + (longopts): Alphabetize. + (opts): Ditto. + (main): Ditto. Handle -p option. + +2002-01-21 Christopher Faylor + + * Makefile.in (CXXFLAGS): Ensure that important settings are preserved + even when overriden by command line. + +2002-01-21 Christopher Faylor + + * Makefile.in: Build intermediate cygcheck.o to force use of MINGW_CXXFLAGS. + * cygcheck.cc (cygwin_info): Intitialize variable to quiet g++ warning. + (dump_sysinfo): Make variables unsigned to quiet g++ warnings. + * strace.cc (version_string): Rename from SCCSid. + (add_child): Remove unused variable. + (version): Use version_string. Avoid use of fprintf. + +2002-01-21 DJ Delorie + + * Makefile.in: Use CXX instead of CC to compile C++ sources. + +2002-01-17 DJ Delorie + + * cygcheck.cc (already_did): Avoid default constructors, which may + require exception support. + +2001-01-16 Joshua Daniel Franklin + + * cygpath.cc (main): Add options to show Desktop and Start + Menu's Programs directory for current user or all users. + Move bulk of DPWS options outside the getopt case statement. + * utils.sgml: Update cygpath section for ADPWS options. + +2002-01-15 Joerg Schaible + + * cygpath.cc (doit): Empty file ignored using option -i. + +2002-01-15 Mark Bradshaw + + * mkpasswd.c (print_win_error): Add a new function. + (enum_users): Use print_win_error. + (enum_local_groups): Ditto. + (main): Ditto. + +2001-12-26 Jonathan Kamens + + * cygpath.cc (doit): Detect and warn about an empty path. Detect and + warn about errors converting a path. + (main): Set prog_name correctly -- don't leave an extra slash or + backslash at the beginning of it. + +Fri Dec 14 14:04:37 2001 Jason Tishler + + * mkpasswd.c (enum_users): Change to unconditionally use + the --path-to-home option, if supplied by the user. Use default + --path-to-home option value, if appropriate. + (usage): Change usage statement to reflect new semantics. + (main): Remove defaulting of the --path-to-home option. + +Fri Dec 14 12:10:39 2001 Jason Tishler + + * mkpasswd.c (opts): Add indication that '-p' option requires an + argument. + +2001-12-11 Christopher Faylor + + * Makefile.in: Add define to CXXFLAGS. + +2001-12-03 Christopher Faylor + + * cygcheck.cc (usage): Add -c description. + * cygpath.cc (usage): Alphabetize options. + * strace.cc (usage): Ditto. + +2001-11-21 Christopher Faylor + + * path.cc (cygpath): Don't consider cygdrive stuff when trying to derive + native paths. + +2001-11-20 Mark Bradshaw + + * mkpasswd.c: include lmerr.h + (main): New -u option to allow specifying a + specific user. If specified, groups aren't displayed and + output is limited to only the specified user. + (enum_users): If specific user is specified, via -u option, + display only that user's record. With -u use NetUserGetInfo + instead of NetUserEnum. + (load_netapi): Added netusergetinfo. + +2001-11-15 Gary R. Van Sickle + + * strace.cc (main): Change getopt() to getopt_long(). + Add support for help and version info. + Use new parse_mask() function for -m/--mask option. + (longopts): Add long options structure. + (opts): Move options string from getopts call to static var. + (usage): Print usage information. + (SCCSid): Version info. + (version): New function for displaying version info. + (parse_mask): New function supporting parsing of mnemonics, + hex, and basic expressions in masks. + (mnemonic2ul): New mnemonic parsing function. + (tag_mask_mnemonic): New type. + (mnemonic_table): New table of mnemonics for mnemonic2ul() to + search through. + +2001-11-12 Corinna Vinschen + + * cygcheck.cc (dump_sysinfo): Redefine output format slightly. + Print correct build number on 9x/ME systems. + +2001-11-12 Christopher Faylor + + * cygcheck.cc (main): Slight formatting tweak. + +2001-11-12 Corinna Vinschen + + * cygcheck.cc (dump_sysinfo): Add some more details. + +2001-11-12 Corinna Vinschen + + * cygcheck.cc (dump_sysinfo): Print more detailed OS information string + using OSVERSIONINFOEX information. + +2001-11-11 Christopher Faylor + + * path.h: New file. + +2001-11-11 Christopher Faylor + + * cygcheck.cc (scan_registry): Open registry with read-only access. + (main): Reflect argument change for dump_setup. + * dump_setup.cc (dump_setup): Add preliminary extra argument for future + use. + * path.cc (read_mounts): Open registry with read-only access. + +2001-11-11 Christopher Faylor + + * cygcheck.cc (main): Display package info when '-s' is specified. + * dump_setup.cc (dump_setup): Change header. Remove typo. Always sort + packages output. + +2001-11-11 Christopher Faylor + + * dump_setup.cc: New file. + * Makefile.in: Add info for dump_setup.o. + * cygcheck.cc (main): Recognize '-c' option for checking setup + installed base. + * path.cc (cygpath): Read mount table if not loaded. + +2001-11-10 Christopher Faylor + + * Makefile.in (cygcheck.exe): Compile as -mno-cygwin executable. + * path.cc: New file. + * cygcheck.cc (init_paths): Use MS-DOS path syntax. + (cygwin_info): Properly display cygwin version numbers. Prettify some + output. + (dump_sysinfo): Calculate max names of posix and ms-dos paths for + prettier output. + +2001-11-09 Corinna Vinschen + + * cygcheck.cc (dump_sysinfo): Print more detailed OS information string. + +2001-11-04 Corinna Vinschen + + * getfacl.c (username): New function. + (groupname): Ditto. + (usage): Ditto. Add more user friendly help text. + (main): Add -n and --help option. Print names instead of IDs + unless -n option is given. + * setfacl.c (getperm): Tolerate whitespace and comment chars in input. + (getaclentry): Fix several input string misdetections. + (getaclentries): Allow - as input file name to read from stdin. + Tolerate whitespace and comment chars in input. + (usage): Add more user friendly help text. + (main): Add --help option. + +2001-11-04 Egor Duda + + * strace.cc (main): New option '-w'. Start traced process in separate + window. New option '-S x'. Flush buffered output every x seconds. + (create_child): Start child process in new window, when requested. + When requested, periodically flush debugging output. + +2001-10-24 Christopher Faylor + + * Makefile.in: Remove EXEEXT consideration. We always need .exe + extensions. + +2001-10-20 Corinna Vinschen + + * mkgroup.c: Avoid compiler warnings. + (print_special): New function. + (main): Print special accounts by calling print_special(). + * mkpasswd.c: Avoid compiler warnings. + (enum_users): Print additional U-domain\username info in gecos + field when SIDs are printed. + (print_special): New function. + (main): Print special accounts by calling print_special(). + +2001-10-15 Christopher Faylor + + * mkpasswd.cc (enum_users): Shorten "unused" passwd field. + +2001-10-13 Christopher Faylor + + * Makefile.in: Allow stdinc searching for dumper. + +Tue Oct 9 21:59:00 2001 Christopher Faylor + + * Makefile.in (MINGW_INCLUDES): Accommodate changes in Makefile.common. + +Sun Oct 7 23:06:39 2001 Christopher Faylor + + * kill.cc (main): Set exit value to 1 on invalid pid. Perform minor + cleanup. + +Fri Sep 21 20:40:30 2001 Christopher Faylor + + * Makefile.in (mingw_getopt.o): Ensure that newlib include directories + are not searched. + +Thu Sep 20 21:00:20 2001 Christopher Faylor + + * Makefile.in (MINGW_INCLUDES): Still need cygwin/include directory. + +Wed Sep 19 12:22:08 2001 Christopher Faylor + + * Makefile.in: Filter newlib includes from mingw compilation. + +2001-09-14 Egor Duda + + * dumper.cc (dumper::dumper): Print error code in case of error. + (dumper::add_thread): Ditto. + (dumper::collect_memory_sections): Ditto. + (dumper::dump_memory_region): Ditto. + (dumper::collect_process_information): Ditto. + (print_section_name): Fix formatting. + +2001-09-13 Egor Duda + + * dumper.cc (main): Properly recognize negative pids (used by w9x). + +2001-09-09 Egor Duda + + * dumper.cc (main): Change command-line arguments format to be + similar to gdb. Allow adding error_start=x:\path\to\dumper.exe to + CYGWIN environment variable to perform core dumping in case of + program crash. + (usage): Ditto. + +Wed Sep 5 22:37:21 2001 Christopher Faylor + + * Makefile.in (dumper): Change logic for libbfd and libintl so that + they will be found either in the build tree or the installed directory. + * mkpasswd.c (enum_users): Add a comment as a password for NT. + +2001-09-03 Michael A Chase + + * mount.cc (mount_commands): Don't write /cygdrive/u mount points. + +2001-09-03 Michael A Chase + + * mount.cc (longopts): Add mount-commands to options list. + (usage): Add mount-commands option. + (mount_commands): New function. Write commands to recreate current + mounts. + +Sat Sep 1 15:58:11 2001 Christopher Faylor + + * mount.cc (main): Eliminate excess arguments in printf. + +2001-08-30 Egor Duda + + * dumper.h: Update copyright notice. + * dumper.cc: Ditto. + * dumper.cc: (dumper::print_core_section_list): New function. + * dumper.h: (dumper::print_core_section_list): Declare it. + * dumper.cc (print_section_name): New function. + (dumper::collect_process_information): Augment debugging output. + Stop debugee processing if it posts double exception. + (usage): Fix typo in option name. + +Tue Aug 28 14:45:02 2001 Christopher Faylor + + * mount.cc (main): Issue correct warning for 'not enough arguments'. + +2001-08-14 Joerg Schaible + + * cygpath.cc (main): Support -w for Windows (System) directories and + return physical correct orthography for the Windows System dir. + +2001-07-14 Chris Genly + + * regtool.cc (find_key): Handle keys with only one subkey. + +Wed Jun 27 22:46:10 2001 Christopher Faylor + + * regtool.cc (find_key): Revert previous change. + +Wed Jun 27 13:37:41 2001 Keith Starsmeare" + + * regtool.cc (find_key): Allow '/' as a synonym for '\\'. + +Fri Jun 15 00:49:21 2001 Christopher Faylor + + * mkpasswd.c (main): Output passwd file in binary mode so that there + are no CRs in the file. + * umount.cc (remove_all_user_mounts): Don't try to remove /cygdrive + mounts. + +Tue May 1 10:50:48 2001 Christopher Faylor + + * mkpasswd.c (enum_users): Use /bin/bash as the default shell. + (main): Ditto. + +Sat Apr 28 22:32:01 2001 Christopher Faylor + + * passwd.cc (ttymnam): New function. + (main): Use ttynam() to report name of tty. + +2001-04-19 Egor Duda + + * dumper.cc (dumper::init_core_dump): Set architecture field in dump + header. + +Mon Apr 16 15:08:00 2001 Corinna Vinschen + + * mkgroup.c: Add function pointers `netlocalgroupgetmembers' and + `netgroupgetusers'. + (load_netapi): Load function pointers `netlocalgroupgetmembers' + and `netgroupgetusers'. + (enum_local_users): New function. + (enum_local_groups): Call `enum_local_users' for each group if + `print_users' is set. + (enum_users): New function. + (enum_groups): Call `enum_users' for each group if `print_users' is set. + (usage): Add usage text for `-u/--users'. + (longopts): Add option `--users'. + (opts): Add option character `u'. + (main): Set `print_users' according to option `-u/--users'. + Call `enum_local_groups' and `enum_groups' with additional parameter + `print_users'. + +2001-04-15 Michael A Chase + + * mount.cc (longopts): Add help to options list. + (opts): Add 'h' to options string. + * umount.cc (longopts): Add help to options list. + (opts): Add 'h' to options string and change 'R' to 'A'. + +2001-04-13 Kazuhiro Fujieda + + * mkgroup.c (enum_groups): Use RID + offset specified an additional + argument as ID. + (usage): Add description of -o option. + (longopts, opts): Add specifications of -o/--id-offset option. + (main): Add -o option. Invoke enum_groups with specified offset. + * mkpasswd.c (enum_users): Just like mkgroup.c. + (usage, longopts, opts): Ditto. + (main): Add -o option. Invoke enum_users with specified offset only + against domain accounts. + +2001-04-11 Egor Duda + + * mkgroup.c (uni2ansi): Use native method to convert from Unicode + to multi-byte strings. + * mkpasswd.c (uni2ansi): Ditto. + (enum_users): Pass buffer size when converting string. + (enum_local_groups): Ditto. + * mkgroup.c (enum_groups): Ditto. + (enum_local_groups): Ditto. + +Mon Apr 2 22:41:33 2001 Christopher Faylor + + * mount.cc (main): Use getopt_long for parsing arguments. + (usage): Reformat, show long and short options. + * umount.cc (main): Ditto, all of the above. + +Mon Apr 2 10:58:26 2001 Christopher Faylor + + * mount.cc (show_mounts): Change format string to more closely resemble + UNIX when displaying mount table. + +Sat Mar 17 21:46:06 2001 Christopher Faylor + + * kill.cc (forcekill): Use dwProcessId when opening a process, not the + Cygwin pid. + +Mon Mar 5 18:50:00 2001 Corinna Vinschen + + * getfacl.c: Add copyright hint. + * setfacl.c: Ditto. + * strace.cc: Ditto. + +Tue Jan 09 10:26:23 2001 Tony Sideris + + * regtool.cc (cmd_list): Add new registry display options. + (cmd_list): Add code to implement -p, -k, and -l options. + + * regtool.cc (Fail): Add call to LocalFree to free memory allocated by + FormatMessage. + +Wed Jan 10 09:16:57 2001 Christopher Faylor + + * regtool.cc (translate): Ensure that 'c' is initialized. + (cmd_set): Ditto for rv. diff --git a/winsup/utils/cygcheck.cc b/winsup/utils/cygcheck.cc new file mode 100644 index 000000000..9652a5ba5 --- /dev/null +++ b/winsup/utils/cygcheck.cc @@ -0,0 +1,1500 @@ +/* cygcheck.cc + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. + + This file is part of Cygwin. + + This software is a copyrighted work licensed under the terms of the + Cygwin license. Please consult the file "CYGWIN_LICENSE" for + details. */ + +#include +#include +#include +#include +#include +#include +#include +#include "path.h" +#include +#include "cygwin/include/sys/cygwin.h" +#include "cygwin/include/mntent.h" + +int verbose = 0; +int registry = 0; +int sysinfo = 0; +int givehelp = 0; +int keycheck = 0; +int check_setup = 0; +int dump_only = 0; +int find_package = 0; +int list_package = 0; + +#ifdef __GNUC__ +typedef long long longlong; +#else +typedef __int64 longlong; +#endif + +void dump_setup (int, char **, bool); +void package_find (int, char **); +void package_list (int, char **); + +static const char version[] = "$Revision$"; + +static const char *known_env_vars[] = { + "c_include_path", + "compiler_path", + "cxx_include_path", + "cygwin", + "cygwin32", + "dejagnu", + "expect", + "gcc_default_options", + "gcc_exec_prefix", + "home", + "ld_library_path", + "library_path", + "login", + "lpath", + "make_mode", + "makeflags", + "path", + "pwd", + "strace", + "tcl_library", + "user", + 0 +}; + +struct +{ + const char *name; + int missing_is_good; +} +static common_apps[] = { + {"awk", 0}, + {"bash", 0}, + {"cat", 0}, + {"cp", 0}, + {"cpp", 1}, + {"find", 0}, + {"gcc", 0}, + {"gdb", 0}, + {"grep", 0}, + {"ld", 0}, + {"ls", 0}, + {"make", 0}, + {"mv", 0}, + {"rm", 0}, + {"sed", 0}, + {"sh", 0}, + {"tar", 0}, + {0, 0} +}; + +static int num_paths = 0, max_paths = 0; +static char **paths = 0; + +/* + * keyeprint() is used to report failure modes + */ +static int +keyeprint (const char *name) +{ + fprintf (stderr, "cygcheck: %s failed: %lu\n", name, GetLastError ()); + return 1; +} + +static void +add_path (char *s, int maxlen) +{ + if (num_paths >= max_paths) + { + max_paths += 10; + if (paths) + paths = (char **) realloc (paths, max_paths * sizeof (char *)); + else + paths = (char **) malloc (max_paths * sizeof (char *)); + } + paths[num_paths] = (char *) malloc (maxlen + 1); + if (paths[num_paths] == NULL) + { + keyeprint ("add_path: malloc()"); + return; + } + memcpy (paths[num_paths], s, maxlen); + paths[num_paths][maxlen] = 0; + char *e = paths[num_paths] + strlen (paths[num_paths]); + if (e[-1] == '\\' && e[-2] != ':') + *--e = 0; + for (int i = 1; i < num_paths; i++) + if (strcasecmp (paths[num_paths], paths[i]) == 0) + return; + num_paths++; +} + +static void +init_paths () +{ + char tmp[4000], *sl; + add_path ((char *) ".", 1); /* to be replaced later */ + add_path ((char *) ".", 1); /* the current directory */ + if (GetSystemDirectory (tmp, 4000)) + add_path (tmp, strlen (tmp)); + else + keyeprint ("init_paths: GetSystemDirectory()"); + sl = strrchr (tmp, '\\'); + if (sl) + { + strcpy (sl, "\\SYSTEM"); + add_path (tmp, strlen (tmp)); + } + GetWindowsDirectory (tmp, 4000); + add_path (tmp, strlen (tmp)); + + char *wpath = getenv ("PATH"); + if (wpath) + { + char *b, *e; + b = wpath; + while (1) + { + for (e = b; *e && *e != ';'; e++); + add_path (b, e - b); + if (!*e) + break; + b = e + 1; + } + } + else + printf ("WARNING: PATH is not set at all!\n"); +} + +static char * +find_on_path (char *file, char *default_extension, + int showall = 0, int search_sysdirs = 0) +{ + static char rv[4000]; + char tmp[4000], *ptr = rv; + + if (!file) + { + keyeprint ("find_on_path: NULL pointer for file"); + return 0; + } + + if (default_extension == NULL) + { + keyeprint ("find_on_path: NULL pointer for default_extension"); + return 0; + } + + if (strchr (file, ':') || strchr (file, '\\') || strchr (file, '/')) + return cygpath (file, NULL); + + if (strchr (file, '.')) + default_extension = (char *) ""; + + for (int i = 0; i < num_paths; i++) + { + if (!search_sysdirs && (i == 0 || i == 2 || i == 3)) + continue; + if (i == 0 || !search_sysdirs || strcasecmp (paths[i], paths[0])) + { + sprintf (ptr, "%s\\%s%s", paths[i], file, default_extension); + if (GetFileAttributes (ptr) != (DWORD) - 1) + { + if (showall) + printf ("Found: %s\n", ptr); + if (ptr == tmp && verbose) + printf ("Warning: %s hides %s\n", rv, ptr); + ptr = tmp; + } + } + } + + if (ptr == tmp) + return rv; + + return 0; +} + +#define DID_NEW 1 +#define DID_ACTIVE 2 +#define DID_INACTIVE 3 + +struct Did +{ + Did *next; + char *file; + int state; +}; +static Did *did = 0; + +static Did * +already_did (char *file) +{ + Did *d; + for (d = did; d; d = d->next) + if (strcasecmp (d->file, file) == 0) + return d; + d = (Did *) malloc (sizeof (Did)); + d->file = strdup (file); + d->next = did; + d->state = DID_NEW; + did = d; + return d; +} + +static int +get_word (HANDLE fh, int offset) +{ + short rv; + unsigned r; + + if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER + && GetLastError () != NO_ERROR) + keyeprint ("get_word: SetFilePointer()"); + + if (!ReadFile (fh, &rv, 2, (DWORD *) &r, 0)) + keyeprint ("get_word: Readfile()"); + + return rv; +} + +static int +get_dword (HANDLE fh, int offset) +{ + int rv; + unsigned r; + + if (SetFilePointer (fh, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER + && GetLastError () != NO_ERROR) + keyeprint ("get_word: SetFilePointer()"); + + if (!ReadFile (fh, &rv, 4, (DWORD *) &r, 0)) + keyeprint ("get_dword: Readfile()"); + + return rv; +} + +struct Section +{ + char name[8]; + int virtual_size; + int virtual_address; + int size_of_raw_data; + int pointer_to_raw_data; +}; + +static int +rva_to_offset (int rva, char *sections, int nsections, int *sz) +{ + int i; + + if (sections == NULL) + { + keyeprint ("rva_to_offset: NULL passed for sections"); + return 0; + } + + for (i = 0; i < nsections; i++) + { + Section *s = (Section *) (sections + i * 40); +#if 0 + printf ("%08x < %08x < %08x ? %08x\n", + s->virtual_address, rva, + s->virtual_address + s->virtual_size, s->pointer_to_raw_data); +#endif + if (rva >= s->virtual_address + && rva < s->virtual_address + s->virtual_size) + { + if (sz) + *sz = s->virtual_address + s->virtual_size - rva; + return rva - s->virtual_address + s->pointer_to_raw_data; + } + } + return 0; /* punt */ +} + +struct ExpDirectory +{ + int flags; + int timestamp; + short major_ver; + short minor_ver; + int name_rva; +}; + +struct ImpDirectory +{ + unsigned characteristics; + unsigned timestamp; + unsigned forwarder_chain; + unsigned name_rva; + unsigned iat_rva; +}; + + +static void track_down (char *file, char *suffix, int lvl); + +#define CYGPREFIX (sizeof ("%%% Cygwin ") - 1) +static void +cygwin_info (HANDLE h) +{ + char *buf, *bufend, *buf_start = NULL; + const char *hello = " Cygwin DLL version info:\n"; + DWORD size = GetFileSize (h, NULL); + DWORD n; + + if (size == 0xffffffff) + return; + + buf_start = buf = (char *) calloc (1, size + 1); + if (buf == NULL) + { + keyeprint ("cygwin_info: malloc()"); + return; + } + + (void) SetFilePointer (h, 0, NULL, FILE_BEGIN); + if (!ReadFile (h, buf, size, &n, NULL)) + { + free (buf_start); + return; + } + + static char dummy[] = "\0\0\0\0\0\0\0"; + char *dll_major = dummy; + bufend = buf + size; + while (buf < bufend) + if ((buf = (char *) memchr (buf, '%', bufend - buf)) == NULL) + break; + else if (strncmp ("%%% Cygwin ", buf, CYGPREFIX) != 0) + buf++; + else + { + char *p = strchr (buf += CYGPREFIX, '\n'); + if (!p) + break; + if (strncasecmp (buf, "dll major:", 10) == 0) + { + dll_major = buf + 11; + continue; + } + char *s, pbuf[80]; + int len; + len = 1 + p - buf; + if (strncasecmp (buf, "dll minor:", 10) != 0) + s = buf; + else + { + char c = dll_major[1]; + dll_major[1] = '\0'; + int maj = atoi (dll_major); + dll_major[1] = c; + int min = atoi (dll_major + 1); + sprintf (pbuf, "DLL version: %d.%d.%.*s", maj, min, len - 11, + buf + 11); + len = strlen (s = pbuf); + } + if (strncmp (s, "dll", 3) == 0) + memcpy (s, "DLL", 3); + else if (strncmp (s, "api", 3) == 0) + memcpy (s, "API", 3); + else if (islower (*s)) + *s = toupper (*s); + fprintf (stdout, "%s %.*s", hello, len, s); + hello = ""; + } + + if (!*hello) + puts (""); + + free (buf_start); + return; +} + +static void +dll_info (const char *path, HANDLE fh, int lvl, int recurse) +{ + DWORD junk; + int i; + int pe_header_offset = get_dword (fh, 0x3c); + int opthdr_ofs = pe_header_offset + 4 + 20; + unsigned short v[6]; + + if (path == NULL) + { + keyeprint ("dll_info: NULL passed for path"); + return; + } + + if (SetFilePointer (fh, opthdr_ofs + 40, 0, FILE_BEGIN) == + INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) + keyeprint ("dll_info: SetFilePointer()"); + + if (!ReadFile (fh, &v, sizeof (v), &junk, 0)) + keyeprint ("dll_info: Readfile()"); + + if (verbose) + printf (" - os=%d.%d img=%d.%d sys=%d.%d\n", + v[0], v[1], v[2], v[3], v[4], v[5]); + else + printf ("\n"); + + int num_entries = get_dword (fh, opthdr_ofs + 92); + int export_rva = get_dword (fh, opthdr_ofs + 96); + int export_size = get_dword (fh, opthdr_ofs + 100); + int import_rva = get_dword (fh, opthdr_ofs + 104); + int import_size = get_dword (fh, opthdr_ofs + 108); + + int nsections = get_word (fh, pe_header_offset + 4 + 2); + char *sections = (char *) malloc (nsections * 40); + + if (SetFilePointer (fh, pe_header_offset + 4 + 20 + + get_word (fh, pe_header_offset + 4 + 16), 0, + FILE_BEGIN) == INVALID_SET_FILE_POINTER + && GetLastError () != NO_ERROR) + keyeprint ("dll_info: SetFilePointer()"); + + if (!ReadFile (fh, sections, nsections * 40, &junk, 0)) + keyeprint ("dll_info: Readfile()"); + + if (verbose && num_entries >= 1 && export_size > 0) + { + int expsz; + int expbase = rva_to_offset (export_rva, sections, nsections, &expsz); + + if (expbase) + { + if (SetFilePointer (fh, expbase, 0, FILE_BEGIN) == + INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) + keyeprint ("dll_info: SetFilePointer()"); + + unsigned char *exp = (unsigned char *) malloc (expsz); + + if (!ReadFile (fh, exp, expsz, &junk, 0)) + keyeprint ("dll_info: Readfile()"); + + ExpDirectory *ed = (ExpDirectory *) exp; + int ofs = ed->name_rva - export_rva; + struct tm *tm = localtime ((const time_t *) &(ed->timestamp)); + if (tm->tm_year < 60) + tm->tm_year += 2000; + if (tm->tm_year < 200) + tm->tm_year += 1900; + printf ("%*c", lvl + 2, ' '); + printf ("\"%s\" v%d.%d ts=", exp + ofs, + ed->major_ver, ed->minor_ver); + printf ("%d/%d/%d %d:%02d\n", + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min); + } + } + + if (num_entries >= 2 && import_size > 0 && recurse) + { + int impsz; + int impbase = rva_to_offset (import_rva, sections, nsections, &impsz); + if (impbase) + { + if (SetFilePointer (fh, impbase, 0, FILE_BEGIN) == + INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) + keyeprint ("dll_info: SetFilePointer()"); + + unsigned char *imp = (unsigned char *) malloc (impsz); + if (imp == NULL) + { + keyeprint ("dll_info: malloc()"); + return; + } + + if (!ReadFile (fh, imp, impsz, &junk, 0)) + keyeprint ("dll_info: Readfile()"); + + ImpDirectory *id = (ImpDirectory *) imp; + for (i = 0; id[i].name_rva; i++) + { + /* int ofs = id[i].name_rva - import_rva; */ + track_down ((char *) imp + id[i].name_rva - import_rva, + (char *) ".dll", lvl + 2); + } + } + } + if (strstr (path, "\\cygwin1.dll")) + cygwin_info (fh); +} + +static void +track_down (char *file, char *suffix, int lvl) +{ + if (file == NULL) + { + keyeprint ("track_down: malloc()"); + return; + } + + if (suffix == NULL) + { + keyeprint ("track_down: malloc()"); + return; + } + + char *path = find_on_path (file, suffix, 0, 1); + if (!path) + { + printf ("Error: could not find %s\n", file); + return; + } + + Did *d = already_did (file); + switch (d->state) + { + case DID_NEW: + break; + case DID_ACTIVE: + if (verbose) + { + if (lvl) + printf ("%*c", lvl, ' '); + printf ("%s", path); + printf (" (recursive)\n"); + } + return; + case DID_INACTIVE: + if (verbose) + { + if (lvl) + printf ("%*c", lvl, ' '); + printf ("%s", path); + printf (" (already done)\n"); + } + return; + default: + break; + } + + if (lvl) + printf ("%*c", lvl, ' '); + + if (!path) + { + printf ("%s not found\n", file); + return; + } + + printf ("%s", path); + + HANDLE fh = + CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (fh == INVALID_HANDLE_VALUE) + { + printf (" - Cannot open\n"); + return; + } + + d->state = DID_ACTIVE; + + dll_info (path, fh, lvl, 1); + d->state = DID_INACTIVE; + if (!CloseHandle (fh)) + keyeprint ("track_down: CloseHandle()"); +} + +static void +ls (char *f) +{ + HANDLE h = CreateFile (f, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + BY_HANDLE_FILE_INFORMATION info; + + if (!GetFileInformationByHandle (h, &info)) + keyeprint ("ls: GetFileInformationByHandle()"); + + SYSTEMTIME systime; + + if (!FileTimeToSystemTime (&info.ftLastWriteTime, &systime)) + keyeprint ("ls: FileTimeToSystemTime()"); + printf ("%5dk %04d/%02d/%02d %s", + (((int) info.nFileSizeLow) + 512) / 1024, + systime.wYear, systime.wMonth, systime.wDay, f); + dll_info (f, h, 16, 0); + if (!CloseHandle (h)) + keyeprint ("ls: CloseHandle()"); +} + +static void +cygcheck (char *app) +{ + char *papp = find_on_path (app, (char *) ".exe", 1, 0); + if (!papp) + { + printf ("Error: could not find %s\n", app); + return; + } + char *s = strdup (papp); + char *sl = 0, *t; + for (t = s; *t; t++) + if (*t == '/' || *t == '\\' || *t == ':') + sl = t; + if (sl == 0) + paths[0] = (char *) "."; + else + { + *sl = 0; + paths[0] = s; + } + did = 0; + track_down (papp, (char *) ".exe", 0); +} + + +extern char **environ; + +struct RegInfo +{ + RegInfo *prev; + char *name; + HKEY key; +}; + +static void +show_reg (RegInfo * ri, int nest) +{ + if (!ri) + return; + show_reg (ri->prev, 1); + if (nest) + printf ("%s\\", ri->name); + else + printf ("%s\n", ri->name); +} + +static void +scan_registry (RegInfo * prev, HKEY hKey, char *name, int cygnus) +{ + RegInfo ri; + ri.prev = prev; + ri.name = name; + ri.key = hKey; + + char *cp; + for (cp = name; *cp; cp++) + if (strncasecmp (cp, "cygnus", 6) == 0) + cygnus = 1; + + DWORD num_subkeys, max_subkey_len, num_values; + DWORD max_value_len, max_valdata_len, i; + if (RegQueryInfoKey (hKey, 0, 0, 0, &num_subkeys, &max_subkey_len, 0, + &num_values, &max_value_len, &max_valdata_len, 0, 0) + != ERROR_SUCCESS) + { +#if 0 + char tmp[400]; + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError (), + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), tmp, 400, 0); + printf ("RegQueryInfoKey: %s\n", tmp); +#endif + return; + } + + if (cygnus) + { + show_reg (&ri, 0); + + char *value_name = (char *) malloc (max_value_len + 1); + if (value_name == NULL) + { + keyeprint ("scan_registry: malloc()"); + return; + } + + char *value_data = (char *) malloc (max_valdata_len + 1); + if (value_data == NULL) + { + keyeprint ("scan_registry: malloc()"); + return; + } + + for (i = 0; i < num_values; i++) + { + DWORD dlen = max_valdata_len + 1; + DWORD nlen = max_value_len + 1; + DWORD type; + RegEnumValue (hKey, i, value_name, &nlen, 0, + &type, (BYTE *) value_data, &dlen); + { + printf (" %s = ", i ? value_name : "(default)"); + switch (type) + { + case REG_DWORD: + printf ("0x%08x\n", *(unsigned *) value_data); + break; + case REG_EXPAND_SZ: + case REG_SZ: + printf ("`%s'\n", value_data); + break; + default: + printf ("(unsupported type)\n"); + break; + } + } + } + free (value_name); + free (value_data); + } + + char *subkey_name = (char *) malloc (max_subkey_len + 1); + for (i = 0; i < num_subkeys; i++) + { + if (RegEnumKey (hKey, i, subkey_name, max_subkey_len + 1) == + ERROR_SUCCESS) + { + HKEY sKey; + if (RegOpenKeyEx (hKey, subkey_name, 0, KEY_READ, &sKey) + == ERROR_SUCCESS) + { + scan_registry (&ri, sKey, subkey_name, cygnus); + if (RegCloseKey (sKey) != ERROR_SUCCESS) + keyeprint ("scan_registry: RegCloseKey()"); + } + } + } + free (subkey_name); +} + +void +pretty_id (const char *s, char *cygwin, size_t cyglen) +{ + char *groups[16384]; + + strcpy (cygwin + cyglen++, " "); + strcpy (cygwin + cyglen, s); + putenv (cygwin); + + char *id = cygpath ("/bin/id.exe", NULL); + for (char *p = id; (p = strchr (p, '/')); p++) + *p = '\\'; + + if (access (id, X_OK)) + { + fprintf (stderr, "`id' program not found\n"); + return; + } + + FILE *f = popen (id, "rt"); + + char buf[16384]; + static char empty[] = ""; + buf[0] = '\0'; + fgets (buf, sizeof (buf), f); + char *uid = strtok (buf, ")"); + if (uid) + uid += strlen ("uid="); + else + uid = empty; + char *gid = strtok (NULL, ")"); + if (gid) + gid += strlen ("gid=") + 1; + else + gid = empty; + char **ng; + size_t sz = 0; + for (ng = groups; (*ng = strtok (NULL, ",")); ng++) + { + char *p = strchr (*ng, '\n'); + if (p) + *p = '\0'; + if (ng == groups) + *ng += strlen (" groups="); + size_t len = strlen (*ng); + if (sz < len) + sz = len; + } + + printf ("\nOutput from %s (%s)\n", id, s); + size_t szmaybe = strlen ("UID: ") + strlen (uid); + if (sz < szmaybe) + sz = szmaybe; + sz += 1; + int n = 80 / (int) sz; + sz = -sz; + ng[0] += strlen ("groups="); + printf ("UID: %.*s) GID: %s)\n", sz + (sizeof ("UID: ") - 1), uid, gid); + int i = 0; + for (char **g = groups; g < ng; g++) + { + if (i < n) + i++; + else + { + i = 0; + puts (""); + } + if (++i <= n && g != (ng - 1)) + printf ("%*s ", sz, *g); + else + { + printf ("%s\n", *g); + i = 0; + } + } +} + +static void +dump_sysinfo () +{ + int i, j; + char tmp[4000]; + time_t now; + char *found_cygwin_dll; + + printf ("\nCygwin Win95/NT Configuration Diagnostics\n"); + time (&now); + printf ("Current System Time: %s\n", ctime (&now)); + + OSVERSIONINFO osversion; + osversion.dwOSVersionInfoSize = sizeof (osversion); + if (!GetVersionEx (&osversion)) + keyeprint ("dump_sysinfo: GetVersionEx()"); + char *osname = (char *) "unknown OS"; + switch (osversion.dwPlatformId) + { + case VER_PLATFORM_WIN32s: + osname = (char *) "32s"; + break; + case VER_PLATFORM_WIN32_WINDOWS: + switch (osversion.dwMinorVersion) + { + case 0: + if (strchr (osversion.szCSDVersion, 'C')) + osname = (char *) "95 OSR2"; + else + osname = (char *) "95"; + break; + case 10: + if (strchr (osversion.szCSDVersion, 'A')) + osname = (char *) "98 SE"; + else + osname = (char *) "98"; + break; + case 90: + osname = (char *) "ME"; + break; + default: + osname = (char *) "9X"; + break; + } + break; + case VER_PLATFORM_WIN32_NT: + if (osversion.dwMajorVersion == 5) + { + BOOL more_info = FALSE; + OSVERSIONINFOEX osversionex; + osversionex.dwOSVersionInfoSize = sizeof (osversionex); + if (GetVersionEx ((OSVERSIONINFO *) &osversionex)) + more_info = TRUE; + if (osversion.dwMinorVersion == 0) + { + if (!more_info) + osname = (char *) "2000"; + else if (osversionex.wProductType == VER_NT_SERVER + || osversionex.wProductType == + VER_NT_DOMAIN_CONTROLLER) + { + if (osversionex.wSuiteMask &VER_SUITE_DATACENTER) + osname = (char *) "2000 Datacenter Server"; + else if (osversionex.wSuiteMask & VER_SUITE_ENTERPRISE) + osname = (char *) "2000 Advanced Server"; + else + osname = (char *) "2000 Server"; + } + else + osname = (char *) "2000 Professional"; + } + else + { + if (!more_info) + osname = (char *) "XP"; + else if (osversionex.wProductType == VER_NT_SERVER + || osversionex.wProductType == + VER_NT_DOMAIN_CONTROLLER) + { + if (osversionex.wSuiteMask & VER_SUITE_ENTERPRISE) + osname = (char *) ".NET Enterprise Server"; + else + osname = (char *) ".NET Server"; + } + else if (osversionex.wSuiteMask & VER_SUITE_PERSONAL) + osname = (char *) "XP Home Edition"; + else + osname = (char *) "XP Professional"; + + } + } + else + osname = (char *) "NT"; + break; + default: + osname = (char *) "??"; + break; + } + printf ("Windows %s Ver %lu.%lu Build %lu %s\n\n", osname, + osversion.dwMajorVersion, osversion.dwMinorVersion, + osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ? + osversion.dwBuildNumber : (osversion.dwBuildNumber & 0xffff), + osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ? + osversion.szCSDVersion : ""); + + printf ("Path:"); + char *s = getenv ("PATH"), *e; + char sep = strchr (s, ';') ? ';' : ':'; + int count_path_items = 0; + while (1) + { + for (e = s; *e && *e != sep; e++); + printf ("\t%.*s\n", e - s, s); + count_path_items++; + if (!*e) + break; + s = e + 1; + } + + fflush (stdout); + + char *cygwin = getenv ("CYGWIN"); + if (cygwin) + cygwin -= strlen ("CYGWIN="); + else + cygwin = const_cast ("CYGWIN="); + size_t cyglen = strlen (cygwin); + cygwin = strcpy ((char *) malloc (cyglen + sizeof (" nontsec")), cygwin); + pretty_id ("nontsec", cygwin, cyglen); + pretty_id ("ntsec", cygwin, cyglen); + cygwin[cyglen] = 0; + putenv (cygwin); + + if (!GetSystemDirectory (tmp, 4000)) + keyeprint ("dump_sysinfo: GetSystemDirectory()"); + printf ("\nSysDir: %s\n", tmp); + + GetWindowsDirectory (tmp, 4000); + printf ("WinDir: %s\n\n", tmp); + + + if (givehelp) + printf ("Here's some environment variables that may affect cygwin:\n"); + for (i = 0; environ[i]; i++) + { + char *eq = strchr (environ[i], '='); + if (!eq) + continue; + /* int len = eq - environ[i]; */ + for (j = 0; known_env_vars[j]; j++) + { + *eq = 0; + if (strcmp (environ[i], "PATH") == 0) + continue; /* we handle this one specially */ + if (strcasecmp (environ[i], known_env_vars[j]) == 0) + printf ("%s = `%s'\n", environ[i], eq + 1); + *eq = '='; + } + } + printf ("\n"); + + if (verbose) + { + if (givehelp) + printf ("Here's the rest of your environment variables:\n"); + for (i = 0; environ[i]; i++) + { + int found = 0; + char *eq = strchr (environ[i], '='); + if (!eq) + continue; + /* int len = eq - environ[i]; */ + for (j = 0; known_env_vars[j]; j++) + { + *eq = 0; + if (strcasecmp (environ[i], known_env_vars[j]) == 0) + found = 1; + *eq = '='; + } + if (!found) + { + *eq = 0; + printf ("%s = `%s'\n", environ[i], eq + 1); + *eq = '='; + } + } + printf ("\n"); + } + + if (registry) + { + if (givehelp) + printf ("Scanning registry for keys with `Cygnus' in them...\n"); +#if 0 + /* big and not generally useful */ + scan_registry (0, HKEY_CLASSES_ROOT, (char *) "HKEY_CLASSES_ROOT", 0); +#endif + scan_registry (0, HKEY_CURRENT_CONFIG, + (char *) "HKEY_CURRENT_CONFIG", 0); + scan_registry (0, HKEY_CURRENT_USER, (char *) "HKEY_CURRENT_USER", 0); + scan_registry (0, HKEY_LOCAL_MACHINE, (char *) "HKEY_LOCAL_MACHINE", 0); +#if 0 + /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */ + scan_registry (0, HKEY_USERS, (char *) "HKEY_USERS", 0); +#endif + printf ("\n"); + } + else + printf ("Use `-r' to scan registry\n\n"); + + if (givehelp) + { + printf ("Listing available drives...\n"); + printf ("Drv Type Size Free Flags Name\n"); + } + int prev_mode = + SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + int drivemask = GetLogicalDrives (); + + HINSTANCE k32 = LoadLibrary ("kernel32.dll"); + BOOL (WINAPI * gdfse) (LPCSTR, long long *, long long *, long long *) = + (BOOL (WINAPI *) (LPCSTR, long long *, long long *, long long *)) + GetProcAddress (k32, "GetDiskFreeSpaceExA"); + + for (i = 0; i < 26; i++) + { + if (!(drivemask & (1 << i))) + continue; + char drive[4], name[200], fsname[200]; + DWORD serno = 0, maxnamelen = 0, flags = 0; + name[0] = name[0] = fsname[0] = 0; + sprintf (drive, "%c:\\", i + 'a'); + /* Report all errors, except if the Volume is ERROR_NOT_READY. + ERROR_NOT_READY is returned when removeable media drives are empty + (CD, floppy, etc.) */ + if (!GetVolumeInformation + (drive, name, sizeof (name), &serno, &maxnamelen, &flags, fsname, + sizeof (fsname)) && GetLastError () != ERROR_NOT_READY) + keyeprint ("dump_sysinfo: GetVolumeInformation()"); + + int dtype = GetDriveType (drive); + char drive_type[4] = "unk"; + switch (dtype) + { + case DRIVE_REMOVABLE: + strcpy (drive_type, "fd "); + break; + case DRIVE_FIXED: + strcpy (drive_type, "hd "); + break; + case DRIVE_REMOTE: + strcpy (drive_type, "net"); + break; + case DRIVE_CDROM: + strcpy (drive_type, "cd "); + break; + case DRIVE_RAMDISK: + strcpy (drive_type, "ram"); + break; + default: + strcpy (drive_type, "unk"); + } + + long capacity_mb = -1; + int percent_full = -1; + + long long free_me = 0ULL, free_bytes = 0ULL, total_bytes = 1ULL; + if (gdfse != NULL && gdfse (drive, &free_me, &total_bytes, &free_bytes)) + { + capacity_mb = total_bytes / (1024L * 1024L); + percent_full = 100 - (int) ((100.0 * free_me) / total_bytes); + } + else + { + DWORD spc = 0, bps = 0, fc = 0, tc = 1; + if (GetDiskFreeSpace (drive, &spc, &bps, &fc, &tc)) + { + capacity_mb = (spc * bps * tc) / (1024 * 1024); + percent_full = 100 - (int) ((100.0 * fc) / tc); + } + } + + printf ("%.2s %s %-6s ", drive, drive_type, fsname); + if (capacity_mb >= 0) + printf ("%5dMb %3d%% ", (int) capacity_mb, (int) percent_full); + else + printf (" N/A N/A "); + printf ("%s %s %s %s %s %s %s\n", + flags & FS_CASE_IS_PRESERVED ? "CP" : " ", + flags & FS_CASE_SENSITIVE ? "CS" : " ", + flags & FS_UNICODE_STORED_ON_DISK ? "UN" : " ", + flags & FS_PERSISTENT_ACLS ? "PA" : " ", + flags & FS_FILE_COMPRESSION ? "FC" : " ", + flags & FS_VOL_IS_COMPRESSED ? "VC" : " ", +#if 0 + flags & FILE_SUPPORTS_ENCRYPTION ? "EN" : " ", + flags & FILE_SUPPORTS_OBJECT_IDS ? "OI" : " ", + flags & FILE_SUPPORTS_REPARSE_POINTS ? "RP" : " ", + flags & FILE_SUPPORTS_SPARSE_FILES ? "SP" : " ", + flags & FILE_VOLUME_QUOTAS ? "QU" : " ", +#endif + name); + } + + if (!FreeLibrary (k32)) + keyeprint ("dump_sysinfo: FreeLibrary()"); + SetErrorMode (prev_mode); + if (givehelp) + { + printf ("fd=floppy, hd=hard drive, cd=CD-ROM, net=Network Share\n"); + printf ("CP=Case Preserving, CS=Case Sensitive, UN=Unicode\n"); + printf + ("PA=Persistent ACLS, FC=File Compression, VC=Volume Compression\n"); + } + printf ("\n"); + + unsigned ml_fsname = 4, ml_dir = 7, ml_type = 6; + + struct mntent *mnt; + setmntent (0, 0); + while ((mnt = getmntent (0))) + { + unsigned n = (int) strlen (mnt->mnt_fsname); + if (ml_fsname < n) + ml_fsname = n; + n = (int) strlen (mnt->mnt_dir); + if (ml_dir < n) + ml_dir = n; + } + + if (givehelp) + { + printf + ("Mount entries: these map POSIX directories to your NT drives.\n"); + printf ("%-*s %-*s %-*s %s\n", ml_fsname, "-NT-", ml_dir, "-POSIX-", + ml_type, "-Type-", "-Flags-"); + } + + setmntent (0, 0); + while ((mnt = getmntent (0))) + { + printf ("%-*s %-*s %-*s %s\n", + ml_fsname, mnt->mnt_fsname, + ml_dir, mnt->mnt_dir, ml_type, mnt->mnt_type, mnt->mnt_opts); + } + printf ("\n"); + + add_path ((char *) "\\bin", 4); /* just in case */ + + if (givehelp) + printf + ("Looking to see where common programs can be found, if at all...\n"); + for (i = 0; common_apps[i].name; i++) + if (!find_on_path ((char *) common_apps[i].name, (char *) ".exe", 1, 0)) + { + if (common_apps[i].missing_is_good) + printf ("Not Found: %s (good!)\n", common_apps[i].name); + else + printf ("Not Found: %s\n", common_apps[i].name); + } + printf ("\n"); + + if (givehelp) + printf ("Looking for various Cygnus DLLs... (-v gives version info)\n"); + for (i = 0; i < num_paths; i++) + { + WIN32_FIND_DATA ffinfo; + sprintf (tmp, "%s/*.*", paths[i]); + HANDLE ff = FindFirstFile (tmp, &ffinfo); + int found = (ff != INVALID_HANDLE_VALUE); + found_cygwin_dll = NULL; + while (found) + { + char *f = ffinfo.cFileName; + if (strcasecmp (f + strlen (f) - 4, ".dll") == 0) + { + if (strncasecmp (f, "cyg", 3) == 0) + { + sprintf (tmp, "%s\\%s", paths[i], f); + if (strcasecmp (f, "cygwin1.dll") == 0) + found_cygwin_dll = strdup (tmp); + else + ls (tmp); + } + } + found = FindNextFile (ff, &ffinfo); + } + if (found_cygwin_dll) + { + ls (found_cygwin_dll); + free (found_cygwin_dll); + } + + FindClose (ff); + } +} + +static int +check_keys () +{ + HANDLE h = CreateFileA ("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (h == INVALID_HANDLE_VALUE || h == NULL) + return (keyeprint ("check_key: Opening CONIN$")); + + DWORD mode; + + if (!GetConsoleMode (h, &mode)) + keyeprint ("check_keys: GetConsoleMode()"); + else + { + mode &= ~ENABLE_PROCESSED_INPUT; + if (!SetConsoleMode (h, mode)) + keyeprint ("check_keys: GetConsoleMode()"); + } + + fputs ("\nThis key check works only in a console window,", stderr); + fputs (" _NOT_ in a terminal session!\n", stderr); + fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr); + fputs ("Press `q' to exit.\n", stderr); + + INPUT_RECORD in, prev_in; + + // Drop first key + ReadConsoleInput (h, &in, 1, &mode); + + memset (&in, 0, sizeof in); + + do + { + prev_in = in; + if (!ReadConsoleInput (h, &in, 1, &mode)) + keyeprint ("ReadConsoleInput"); + + if (!memcmp (&in, &prev_in, sizeof in)) + continue; + + switch (in.EventType) + { + case KEY_EVENT: + printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ", + in.Event.KeyEvent.bKeyDown ? "Pressed " : "Released", + in.Event.KeyEvent.wRepeatCount, + in.Event.KeyEvent.wVirtualKeyCode, + in.Event.KeyEvent.wVirtualScanCode, + (unsigned char) in.Event.KeyEvent.uChar.AsciiChar); + fputs (in.Event.KeyEvent.dwControlKeyState & CAPSLOCK_ON ? + "CL " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY ? + "EK " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED ? + "LA " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & LEFT_CTRL_PRESSED ? + "LC " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & NUMLOCK_ON ? + "NL " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED ? + "RA " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & RIGHT_CTRL_PRESSED ? + "RC " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & SCROLLLOCK_ON ? + "SL " : "-- ", stdout); + fputs (in.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED ? + "SH " : "-- ", stdout); + fputc ('\n', stdout); + break; + + default: + break; + } + } + while (in.EventType != KEY_EVENT || + in.Event.KeyEvent.bKeyDown != FALSE || + in.Event.KeyEvent.uChar.AsciiChar != 'q'); + + CloseHandle (h); + return 0; +} + +static void +usage (FILE * stream, int status) +{ + fprintf (stream, "\ +Usage: cygcheck [OPTIONS] [PROGRAM...]\n\ +Check system information or PROGRAM library dependencies\n\ +\n\ + -c, --check-setup check packages installed via setup.exe\n\ + -d, --dump-only no integrity checking of package contents (requires -c)\n\ + -s, --sysinfo system information (not with -k)\n\ + -v, --verbose verbose output (indented) (for -[cfls] or programs)\n\ + -r, --registry registry search (requires -s)\n\ + -k, --keycheck perform a keyboard check session (not with -[scfl])\n\ + -f, --find-package find installed packages containing files (not with -[cl])\n\ + -l, --list-package list the contents of installed packages (not with -[cf])\n\ + -h, --help give help about the info (not with -[cfl])\n\ + -V, --version output version information and exit\n\ +You must at least give either -s or -k or a program name\n"); + exit (status); +} + +struct option longopts[] = { + {"check-setup", no_argument, NULL, 'c'}, + {"dump-only", no_argument, NULL, 'd'}, + {"sysinfo", no_argument, NULL, 's'}, + {"registry", no_argument, NULL, 'r'}, + {"verbose", no_argument, NULL, 'v'}, + {"keycheck", no_argument, NULL, 'k'}, + {"find-package", no_argument, NULL, 'f'}, + {"list-package", no_argument, NULL, 'l'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, 0, 'V'}, + {0, no_argument, NULL, 0} +}; + +static char opts[] = "cdfhklrsvV"; + +static void +print_version () +{ + const char *v = strchr (version, ':'); + int len; + if (!v) + { + v = "?"; + len = 1; + } + else + { + v += 2; + len = strchr (v, ' ') - v; + } + printf ("\ +cygcheck version %.*s\n\ +System Checker for Cygwin\n\ +Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.\n\ +Compiled on %s\n\ +", len, v, __DATE__); +} + +int +main (int argc, char **argv) +{ + int i; + + while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) + switch (i) + { + case 's': + sysinfo = 1; + break; + case 'c': + check_setup = 1; + break; + case 'd': + dump_only = 1; + break; + case 'r': + registry = 1; + break; + case 'v': + verbose = 1; + break; + case 'k': + keycheck = 1; + break; + case 'f': + find_package = 1; + break; + case 'l': + list_package = 1; + break; + case 'h': + givehelp = 1; + break; + case 'V': + print_version (); + exit (0); + default: + usage (stderr, 1); + /*NOTREACHED*/} + argc -= optind; + argv += optind; + + if (argc == 0 && !sysinfo && !keycheck && !check_setup) + if (givehelp) + usage (stdout, 0); + else + usage (stderr, 1); + + if ((check_setup || sysinfo || find_package || list_package) && keycheck) + usage (stderr, 1); + + if ((find_package || list_package) && check_setup) + usage (stderr, 1); + + if (dump_only && !check_setup) + usage (stderr, 1); + + if (find_package && list_package) + usage (stderr, 1); + + if (keycheck) + return check_keys (); + + init_paths (); + + /* FIXME: Add help for check_setup and {list,find}_package */ + if (argc >= 1 && givehelp && !check_setup && !find_package && !list_package) + { + printf("Here is where the OS will find your program%s, and which dlls\n", + argc > 1 ? "s" : ""); + printf ("will be used for it. Use -v to see DLL version info\n"); + + if (!sysinfo) + printf ("\n"); + } + + if (check_setup) + { + dump_setup (verbose, argv, !dump_only); + } + else if (find_package) + { + package_find (verbose, argv); + } + else if (list_package) + { + package_list (verbose, argv); + } + else + for (i = 0; i < argc; i++) + { + if (i) + puts (""); + cygcheck (argv[i]); + } + + if (sysinfo) + { + dump_sysinfo (); + if (!check_setup) + { + puts (""); + dump_setup (verbose, NULL, false); + } + + if (!givehelp) + puts ("Use -h to see help about each section"); + } + + return 0; +} diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc new file mode 100644 index 000000000..070b19bdc --- /dev/null +++ b/winsup/utils/cygpath.cc @@ -0,0 +1,771 @@ +/* cygpath.cc -- convert pathnames between Windows and Unix format + Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#define NOCOMATTRIBUTE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char version[] = "$Revision$"; + +static char *prog_name; +static char *file_arg; +static int path_flag, unix_flag, windows_flag, absolute_flag; +static int shortname_flag, longname_flag; +static int ignore_flag, allusers_flag, output_flag; +static int mixed_flag; +static const char *format_type_arg; + +static struct option long_options[] = { + {(char *) "absolute", no_argument, NULL, 'a'}, + {(char *) "close", required_argument, NULL, 'c'}, + {(char *) "dos", no_argument, NULL, 'd'}, + {(char *) "file", required_argument, NULL, 'f'}, + {(char *) "help", no_argument, NULL, 'h'}, + {(char *) "ignore", no_argument, NULL, 'i'}, + {(char *) "long-name", no_argument, NULL, 'l'}, + {(char *) "mixed", no_argument, NULL, 'm'}, + {(char *) "option", no_argument, NULL, 'o'}, + {(char *) "path", no_argument, NULL, 'p'}, + {(char *) "short-name", no_argument, NULL, 's'}, + {(char *) "type", required_argument, NULL, 't'}, + {(char *) "unix", no_argument, NULL, 'u'}, + {(char *) "version", no_argument, NULL, 'v'}, + {(char *) "windows", no_argument, NULL, 'w'}, + {(char *) "allusers", no_argument, NULL, 'A'}, + {(char *) "desktop", no_argument, NULL, 'D'}, + {(char *) "homeroot", no_argument, NULL, 'H'}, + {(char *) "smprograms", no_argument, NULL, 'P'}, + {(char *) "sysdir", no_argument, NULL, 'S'}, + {(char *) "windir", no_argument, NULL, 'W'}, + {0, no_argument, 0, 0} +}; + +static char options[] = "ac:df:hilmopst:uvwADHPSW"; + +static void +usage (FILE * stream, int status) +{ + if (!ignore_flag || !status) + fprintf (stream, "\ +Usage: %s (-d|-m|-u|-w|-t TYPE) [-c HANDLE] [-f FILE] [options] NAME\n\ + %s [-ADHPSW] \n\ +Convert Unix and Windows format paths, or output system path information\n\ +\n\ +Output type options:\n\ + -d, --dos print DOS (short) form of NAME (C:\\PROGRA~1\\)\n\ + -m, --mixed like --windows, but with regular slashes (C:/WINNT)\n\ + -u, --unix (default) print Unix form of NAME (/cygdrive/c/winnt)\n\ + -w, --windows print Windows form of NAME (C:\\WINNT)\n\ + -t, --type TYPE print TYPE form: 'dos', 'mixed', 'unix', or 'windows'\n\ +Path conversion options:\n\ + -a, --absolute output absolute path\n\ + -l, --long-name print Windows long form of NAME (with -w, -m only)\n\ + -p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')\n\ + -s, --short-name print DOS (short) form of NAME (with -w, -m only)\n\ +System information:\n\ + -A, --allusers use `All Users' instead of current user for -D, -P\n\ + -D, --desktop output `Desktop' directory and exit\n\ + -H, --homeroot output `Profiles' directory (home root) and exit\n\ + -P, --smprograms output Start Menu `Programs' directory and exit\n\ + -S, --sysdir output system directory and exit\n\ + -W, --windir output `Windows' directory and exit\n\ +", prog_name, prog_name); + if (stream == stdout) + { + fprintf (stream, "\ +Other options:\n\ + -f, --file FILE read FILE for input; use - to read from STDIN\n\ + -o, --option read options from FILE as well (for use with --file)\n\ + -c, --close HANDLE close HANDLE (for use in captured process)\n\ + -i, --ignore ignore missing argument\n\ + -h, --help output usage information and exit\n\ + -v, --version output version information and exit\n\ +"); + } + else + fprintf(stream, "Try `%s --help' for more information.\n", prog_name); + exit (ignore_flag ? 0 : status); +} + +static char * +get_short_paths (char *path) +{ + char *sbuf; + char *sptr; + char *next; + char *ptr = path; + char *end = strrchr (path, 0); + DWORD acc = 0; + DWORD len; + + while (ptr != NULL) + { + next = ptr; + ptr = strchr (ptr, ';'); + if (ptr) + *ptr++ = 0; + len = GetShortPathName (next, NULL, 0); + if (!len) + { + fprintf (stderr, "%s: cannot create short name of %s\n", prog_name, + next); + exit (2); + } + acc += len + 1; + } + sptr = sbuf = (char *) malloc (acc + 1); + if (sbuf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + ptr = path; + for (;;) + { + len = GetShortPathName (ptr, sptr, acc); + if (!len) + { + fprintf (stderr, "%s: cannot create short name of %s\n", prog_name, + ptr); + exit (2); + } + + ptr = strrchr (ptr, 0); + sptr = strrchr (sptr, 0); + if (ptr == end) + break; + *sptr = ';'; + ++ptr, ++sptr; + acc -= len + 1; + } + return sbuf; +} + +static char * +get_short_name (const char *filename) +{ + char *sbuf, buf[MAX_PATH]; + DWORD len = GetShortPathName (filename, buf, MAX_PATH); + if (!len) + { + fprintf (stderr, "%s: cannot create short name of %s\n", prog_name, + filename); + exit (2); + } + sbuf = (char *) malloc (++len); + if (sbuf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + return strcpy (sbuf, buf); +} + +static DWORD WINAPI +get_long_path_name_w32impl (LPCSTR src, LPSTR sbuf, DWORD) +{ + char buf1[MAX_PATH], buf2[MAX_PATH], *ptr; + const char *pelem, *next; + WIN32_FIND_DATA w32_fd; + int len; + + strcpy (buf1, src); + *buf2 = 0; + pelem = src; + ptr = buf2; + while (pelem) + { + next = pelem; + if (*next == '\\') + { + strcat (ptr++, "\\"); + pelem++; + if (!*pelem) + break; + continue; + } + pelem = strchr (next, '\\'); + len = pelem ? (pelem++ - next) : strlen (next); + strncpy (ptr, next, len); + ptr[len] = 0; + if (next[1] != ':' && strcmp(next, ".") && strcmp(next, "..")) + { + if (FindFirstFile (buf2, &w32_fd) != INVALID_HANDLE_VALUE) + strcpy (ptr, w32_fd.cFileName); + } + ptr += strlen (ptr); + if (pelem) + { + *ptr++ = '\\'; + *ptr = 0; + } + } + if (sbuf) + strcpy (sbuf, buf2); + SetLastError (0); + return strlen (buf2) + (sbuf ? 0 : 1); +} + +static char * +get_long_name (const char *filename, DWORD& len) +{ + char *sbuf, buf[MAX_PATH]; + static HINSTANCE k32 = LoadLibrary ("kernel32.dll"); + static DWORD (WINAPI *GetLongPathName) (LPCSTR, LPSTR, DWORD) = + (DWORD (WINAPI *) (LPCSTR, LPSTR, DWORD)) GetProcAddress (k32, "GetLongPathName"); + if (!GetLongPathName) + GetLongPathName = get_long_path_name_w32impl; + + len = GetLongPathName (filename, buf, MAX_PATH); + if (len == 0 && GetLastError () == ERROR_INVALID_PARAMETER) + { + fprintf (stderr, "%s: cannot create long name of %s\n", prog_name, + filename); + exit (2); + } + sbuf = (char *) malloc (len + 1); + if (!sbuf) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + return strcpy (sbuf, buf); +} + +static char * +get_long_paths (char *path) +{ + char *sbuf; + char *ptr; + int n = 1; + + ptr = path; + while ((ptr = strchr (ptr, ';'))) + { + ptr++; + n++; + } + + char *paths[n]; + DWORD acc = 0; + int i; + if (!n) + return strdup (""); + + for (i = 0, ptr = path; ptr; i++) + { + DWORD len; + char *next = ptr; + ptr = strchr (ptr, ';'); + if (ptr) + *ptr++ = 0; + paths[i] = get_long_name (next, len); + acc += len + 1; + } + + sbuf = (char *) malloc (acc + 1); + if (sbuf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + + sbuf[0] = '\0'; + for (i = 0; i < n; i++) + { + strcat (strcat (sbuf, paths[i]), ";"); + free (paths[i]); + } + + strchr (sbuf, '\0')[-1] = '\0'; + return sbuf; +} + +static void +convert_slashes (char* name) +{ + while ((name = strchr (name, '\\')) != NULL) + { + if (*name == '\\') + *name = '/'; + name++; + } +} + +static char * +get_mixed_name (const char* filename) +{ + char* mixed_buf = strdup (filename); + + if (mixed_buf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + + convert_slashes (mixed_buf); + + return mixed_buf; +} + +static void +dowin (char option) +{ + char *buf, buf1[MAX_PATH], buf2[MAX_PATH]; + DWORD len = MAX_PATH; + WIN32_FIND_DATA w32_fd; + LPITEMIDLIST id; + HINSTANCE k32; + BOOL (*GetProfilesDirectoryAPtr) (LPSTR, LPDWORD) = 0; + + buf = buf1; + switch (option) + { + case 'D': + SHGetSpecialFolderLocation (NULL, allusers_flag ? + CSIDL_COMMON_DESKTOPDIRECTORY : CSIDL_DESKTOPDIRECTORY, &id); + SHGetPathFromIDList (id, buf); + /* This if clause is a Fix for Win95 without any "All Users" */ + if (strlen (buf) == 0) + { + SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id); + SHGetPathFromIDList (id, buf); + } + break; + + case 'P': + SHGetSpecialFolderLocation (NULL, allusers_flag ? + CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id); + SHGetPathFromIDList (id, buf); + /* This if clause is a Fix for Win95 without any "All Users" */ + if (strlen (buf) == 0) + { + SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id); + SHGetPathFromIDList (id, buf); + } + break; + + case 'H': + k32 = LoadLibrary ("userenv"); + if (k32) + GetProfilesDirectoryAPtr = (BOOL (*) (LPSTR, LPDWORD)) + GetProcAddress (k32, "GetProfilesDirectoryA"); + if (GetProfilesDirectoryAPtr) + (*GetProfilesDirectoryAPtr) (buf, &len); + else + { + GetWindowsDirectory (buf, MAX_PATH); + strcat (buf, "\\Profiles"); + } + break; + + case 'S': + GetSystemDirectory (buf, MAX_PATH); + FindFirstFile (buf, &w32_fd); + strcpy (strrchr (buf, '\\') + 1, w32_fd.cFileName); + break; + + case 'W': + GetWindowsDirectory (buf, MAX_PATH); + break; + + default: + usage (stderr, 1); + } + + if (!windows_flag) + { + cygwin_conv_to_posix_path (buf, buf2); + buf = buf2; + } + else + { + if (shortname_flag) + buf = get_short_name (buf); + if (mixed_flag) + buf = get_mixed_name (buf); + } + printf ("%s\n", buf); + exit (0); +} + +static void +doit (char *filename) +{ + char *buf; + DWORD len; + int retval; + int (*conv_func) (const char *, char *); + + if (!path_flag) + { + len = strlen (filename); + if (len) + len += MAX_PATH + 1001; + else if (ignore_flag) + exit (0); + else + { + fprintf (stderr, "%s: can't convert empty path\n", prog_name); + exit (1); + } + } + else if (unix_flag) + len = cygwin_win32_to_posix_path_list_buf_size (filename); + else + len = cygwin_posix_to_win32_path_list_buf_size (filename); + + buf = (char *) malloc (len); + if (buf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + + if (path_flag) + { + if (unix_flag) + cygwin_win32_to_posix_path_list (filename, buf); + else + { + cygwin_posix_to_win32_path_list (filename, buf); + if (shortname_flag) + buf = get_short_paths (buf); + if (longname_flag) + buf = get_long_paths (buf); + if (mixed_flag) + buf = get_mixed_name (buf); + } + } + else + { + if (unix_flag) + conv_func = (absolute_flag ? cygwin_conv_to_full_posix_path : + cygwin_conv_to_posix_path); + else + conv_func = (absolute_flag ? cygwin_conv_to_full_win32_path : + cygwin_conv_to_win32_path); + retval = conv_func (filename, buf); + if (mixed_flag) + buf = get_mixed_name (buf); + if (retval < 0) + { + fprintf (stderr, "%s: error converting \"%s\"\n", + prog_name, filename); + exit (1); + } + if (!unix_flag) + { + if (shortname_flag) + buf = get_short_name (buf); + if (longname_flag) + buf = get_long_name (buf, len); + } + } + + puts (buf); +} + +static void +print_version () +{ + const char *v = strchr (version, ':'); + int len; + if (!v) + { + v = "?"; + len = 1; + } + else + { + v += 2; + len = strchr (v, ' ') - v; + } + printf ("\ +cygpath (cygwin) %.*s\n\ +Path Conversion Utility\n\ +Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.\n\ +Compiled on %s\n\ +", len, v, __DATE__); +} + +int +main (int argc, char **argv) +{ + int c, o = 0; + int options_from_file_flag; + char *filename; + + prog_name = strrchr (argv[0], '/'); + if (prog_name == NULL) + prog_name = strrchr (argv[0], '\\'); + if (prog_name == NULL) + prog_name = argv[0]; + else + prog_name++; + + path_flag = 0; + unix_flag = 1; + windows_flag = 0; + shortname_flag = 0; + longname_flag = 0; + mixed_flag = 0; + ignore_flag = 0; + options_from_file_flag = 0; + allusers_flag = 0; + output_flag = 0; + while ((c = getopt_long (argc, argv, options, + long_options, (int *) NULL)) != EOF) + { + switch (c) + { + case 'a': + absolute_flag = 1; + break; + + case 'c': + CloseHandle ((HANDLE) strtoul (optarg, NULL, 16)); + break; + + case 'd': + if (windows_flag) + usage (stderr, 1); + unix_flag = 0; + windows_flag = 1; + shortname_flag = 1; + break; + + case 'f': + file_arg = optarg; + break; + + case 'o': + options_from_file_flag = 1; + break; + + case 'p': + path_flag = 1; + break; + + case 'u': + if (windows_flag || mixed_flag) + usage (stderr, 1); + unix_flag = 1; + break; + + case 'w': + if (windows_flag || mixed_flag) + usage (stderr, 1); + unix_flag = 0; + windows_flag = 1; + break; + + case 'm': + unix_flag = 0; + windows_flag = 1; + mixed_flag = 1; + break; + + case 'l': + longname_flag = 1; + break; + + case 's': + shortname_flag = 1; + break; + + case 't': + if (optarg == NULL) + usage (stderr, 1); + + format_type_arg = (*optarg == '=') ? (optarg + 1) : (optarg); + if (strcasecmp (format_type_arg, "dos") == 0) + { + if (windows_flag || longname_flag) + usage (stderr, 1); + unix_flag = 0; + windows_flag = 1; + shortname_flag = 1; + } + else if (strcasecmp (format_type_arg, "mixed") == 0) + { + unix_flag = 0; + mixed_flag = 1; + } + else if (strcasecmp (format_type_arg, "unix") == 0) + { + if (windows_flag) + usage (stderr, 1); + unix_flag = 1; + } + else if (strcasecmp (format_type_arg, "windows") == 0) + { + if (mixed_flag) + usage (stderr, 1); + unix_flag = 0; + windows_flag = 1; + } + else + usage (stderr, 1); + break; + + case 'A': + allusers_flag = 1; + break; + + case 'D': + case 'H': + case 'P': + case 'S': + case 'W': + if (output_flag) + usage (stderr, 1); + output_flag = 1; + o = c; + break; + + case 'i': + ignore_flag = 1; + break; + + case 'h': + usage (stdout, 0); + break; + + case 'v': + print_version (); + exit (0); + + default: + usage (stderr, 1); + break; + } + } + + if (options_from_file_flag && !file_arg) + usage (stderr, 1); + + if (longname_flag && !windows_flag) + usage (stderr, 1); + + if (shortname_flag && !windows_flag) + usage (stderr, 1); + + if (!unix_flag && !windows_flag && !mixed_flag && !options_from_file_flag) + usage (stderr, 1); + + if (!file_arg) + { + if (output_flag) + dowin (o); + + if (optind > argc - 1) + usage (stderr, 1); + + for (int i=optind; argv[i]; i++) { + filename = argv[i]; + doit (filename); + } + } + else + { + FILE *fp; + char buf[PATH_MAX * 2 + 1]; + + if (argv[optind]) + usage (stderr, 1); + + if (strcmp (file_arg, "-") != 0) + fp = fopen (file_arg, "rt"); + else + { + fp = stdin; + setmode (0, O_TEXT); + } + if (fp == NULL) + { + perror ("cygpath"); + exit (1); + } + + setbuf (stdout, NULL); + while (fgets (buf, sizeof (buf), fp) != NULL) + { + char *s = buf; + char *p = strchr (s, '\n'); + if (p) + *p = '\0'; + if (options_from_file_flag && *s == '-') + { + char c; + for (c = *++s; c && !isspace (c); c = *++s) + switch (c) + { + case 'a': + absolute_flag = 1; + break; + case 'i': + ignore_flag = 1; + break; + case 's': + shortname_flag = 1; + longname_flag = 0; + break; + case 'l': + shortname_flag = 0; + longname_flag = 1; + break; + case 'm': + unix_flag = 0; + windows_flag = 1; + mixed_flag = 1; + case 'w': + unix_flag = 0; + windows_flag = 1; + break; + case 'u': + windows_flag = 0; + unix_flag = 1; + break; + case 'p': + path_flag = 1; + break; + case 'D': + case 'H': + case 'P': + case 'S': + case 'W': + output_flag = 1; + o = c; + break; + } + if (*s) + do + s++; + while (*s && isspace (*s)); + } + if (*s && !output_flag) + doit (s); + if (!*s && output_flag) + dowin (o); + } + } + + exit (0); +} -- cgit v1.2.3