Index: cygcheck.cc =================================================================== RCS file: /cvs/src/src/winsup/utils/cygcheck.cc,v retrieving revision 1.35 diff -u -p -r1.35 cygcheck.cc --- cygcheck.cc 13 Jun 2003 02:36:12 -0000 1.35 +++ cygcheck.cc 14 Aug 2003 19:01:11 -0000 @@ -26,6 +26,8 @@ int sysinfo = 0; int givehelp = 0; int keycheck = 0; int check_setup = 0; +int find_package = 0; +int list_package = 0; #ifdef __GNUC__ typedef long long longlong; @@ -34,6 +36,8 @@ 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: 1.35 $"; @@ -1317,13 +1321,15 @@ usage (FILE * stream, int status) Usage: cygcheck [OPTIONS] [PROGRAM...]\n\ Check system information or PROGRAM library dependencies\n\ \n\ - -c, --check-setup check packages installed via setup.exe\n\ - -s, --sysinfo system information (not with -k)\n\ - -v, --verbose verbose output (indented) (for -s or programs)\n\ - -r, --registry registry search (requires -s)\n\ - -k, --keycheck perform a keyboard check session (not with -s)\n\ - -h, --help give help about the info (not with -c)\n\ - -V, --version output version information and exit\n\ + -c, --check-setup check packages installed via setup.exe\n\ + -s, --sysinfo system information (not with -k)\n\ + -v, --verbose verbose output (indented) (for -s 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); } @@ -1334,12 +1340,14 @@ struct option longopts[] = { {"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[] = "chkrsvV"; +static char opts[] = "cfhklrsvV"; static void print_version () @@ -1387,6 +1395,12 @@ main (int argc, char **argv) case 'k': keycheck = 1; break; + case 'f': + find_package = 1; + break; + case 'l': + list_package = 1; + break; case 'h': givehelp = 1; break; @@ -1405,7 +1419,13 @@ main (int argc, char **argv) else usage (stderr, 1); - if ((check_setup || sysinfo) && keycheck) + if ((check_setup || sysinfo || find_package || list_package) && keycheck) + usage (stderr, 1); + + if ((find_package || list_package) && check_setup) + usage (stderr, 1); + + if (find_package && list_package) usage (stderr, 1); if (keycheck) @@ -1413,7 +1433,7 @@ main (int argc, char **argv) init_paths (); - /* FIXME: Add help for check_setup */ + /* FIXME: Add help for check_setup and {list,find}_package */ if (argc >= 1 && givehelp && !check_setup) { if (argc == 1) @@ -1436,6 +1456,16 @@ main (int argc, char **argv) if (check_setup) { dump_setup (verbose, argv, true); + puts (""); + } + else if (find_package) + { + package_find (verbose, argv); + puts (""); + } + else if (list_package) + { + package_list (verbose, argv); puts (""); } else Index: dump_setup.cc =================================================================== RCS file: /cvs/src/src/winsup/utils/dump_setup.cc,v retrieving revision 1.9 diff -u -p -r1.9 dump_setup.cc --- dump_setup.cc 13 Aug 2003 19:37:40 -0000 1.9 +++ dump_setup.cc 14 Aug 2003 19:01:11 -0000 @@ -1,4 +1,4 @@ -/* path.cc +/* dump_setup.cc Copyright 2001 Red Hat, Inc. @@ -165,15 +165,15 @@ compar (const void *a, const void *b) } } -bool +int match_argv (char **argv, const char *name) { if (!argv || !*argv) - return true; + return -1; for (char **a = argv; *a; a++) if (strcasecmp (*a, name) == 0) - return true; - return false; + return a - argv + 1; + return 0; } static bool @@ -234,17 +234,13 @@ file_exists (int verbose, char *filename return true; } -static bool -check_package_files (int verbose, char *package) +static FILE * +open_package_list (char *package) { char filelist[MAX_PATH + 1] = "etc/setup/"; strcat (strcat (filelist, package), ".lst.gz"); if (!file_exists (false, filelist, NULL, NULL)) - { - if (verbose) - printf ("Missing file list /%s for package %s\n", filelist, package); - return false; - } + return NULL; static char *zcat; static char *zcat_end; @@ -260,6 +256,21 @@ check_package_files (int verbose, char * strcpy (zcat_end, filelist); FILE *fp = popen (zcat, "rt"); + return fp; +} + +static bool +check_package_files (int verbose, char *package) +{ + FILE *fp = open_package_list (package); + if (!fp) + { + if (verbose) + printf ("Can't open file list /etc/setup/%s.lst.gz for package %s\n", + package, package); + return false; + } + bool result = true; char buf[MAX_PATH + 1]; while (fgets (buf, MAX_PATH, fp)) @@ -286,25 +297,17 @@ check_package_files (int verbose, char * return result; } -void -dump_setup (int verbose, char **argv, bool check_files) -{ +/** + * Returns a calloc'd sorted list of packages or NULL if no info. + * The last entry in the list is {NULL,NULL}. + */ +static pkgver * +get_packages (char **argv) { char *setup = cygpath ("/etc/setup/installed.db", NULL); FILE *fp = fopen (setup, "rt"); - puts ("Cygwin Package Information"); if (fp == NULL) - { - puts ("No package information found"); - goto err; - } - - if (verbose) - { - bool need_nl = dump_file ("Last downloaded files to: ", "last-cache"); - if (dump_file ("Last downloaded files from: ", "last-mirror") || need_nl) - puts (""); - } + return NULL; int nlines; nlines = 0; @@ -312,12 +315,15 @@ dump_setup (int verbose, char **argv, bo while (fgets (buf, 4096, fp)) nlines += 2; /* potentially binary + source */ if (!nlines) - goto err; + { + fclose (fp); + return NULL; + } rewind (fp); pkgver *packages; - packages = (pkgver *) calloc (nlines, sizeof(packages[0])); + packages = (pkgver *) calloc (nlines + 1, sizeof(packages[0])); int n; for (n = 0; fgets (buf, 4096, fp) && n < nlines;) { @@ -349,23 +355,127 @@ dump_setup (int verbose, char **argv, bo } } + packages[n].name = packages[n].ver = NULL; + qsort (packages, n, sizeof (packages[0]), compar); + fclose (fp); + + return packages; +} + +void +dump_setup (int verbose, char **argv, bool check_files) +{ + pkgver *packages = get_packages(argv); + + puts ("Cygwin Package Information"); + if (packages == NULL) + { + puts ("No setup information found"); + return; + } + + if (verbose) + { + bool need_nl = dump_file ("Last downloaded files to: ", "last-cache"); + if (dump_file ("Last downloaded files from: ", "last-mirror") || need_nl) + puts (""); + } + printf ("%-*s %-*s %s\n", package_len, "Package", version_len, "Version", check_files?"Status":""); - for (int i = 0; i < n; i++) + for (int i = 0; packages[i].name; i++) { printf ("%-*s %-*s %s\n", package_len, packages[i].name, version_len, packages[i].ver, check_files ? (check_package_files (verbose, packages[i].name) ? "OK" : "Incomplete") : ""); fflush(stdout); } - fclose (fp); + + free (packages); return; +} + +void +package_list (int verbose, char **argv) +{ + pkgver *packages = get_packages(argv); + if (packages == NULL) + { + puts ("No setup information found"); + return; + } + + for (int i = 0; packages[i].name; i++) + { + FILE *fp = open_package_list (packages[i].name); + if (!fp) + { + if (verbose) + printf ("Can't open file list /etc/setup/%s.lst.gz for package %s\n", + packages[i].name, packages[i].name); + return; + } + + printf ("Package: %s-%s\n", packages[i].name, packages[i].ver); + + char buf[MAX_PATH + 1]; + while (fgets (buf, MAX_PATH, fp)) + { + char *lastchar = strchr(buf, '\n'); + if (lastchar[-1] != '/') + printf (" /%s", buf); + } + + fclose (fp); + } + + free (packages); + + return; +} + +void +package_find (int verbose, char **argv) +{ + pkgver *packages = get_packages(NULL); + if (packages == NULL) + { + puts ("No setup information found"); + return; + } + + for (int i = 0; packages[i].name; i++) + { + FILE *fp = open_package_list (packages[i].name); + if (!fp) + { + if (verbose) + printf ("Can't open file list /etc/setup/%s.lst.gz for package %s\n", + packages[i].name, packages[i].name); + return; + } + + char buf[MAX_PATH + 2]; + buf[0] = '/'; + while (fgets (buf + 1, MAX_PATH, fp)) + { + char *filename = strtok(buf, "\n"); + if (filename[strlen (filename) - 1] != '/') + { + int a = match_argv (argv, filename); + if (a > 0) + printf ("%s: found in package %s-%s\n", filename, + packages[i].name, packages[i].ver); + } + } + + fclose (fp); + } + + free (packages); -err: - puts ("No setup information found"); - if (fp) - fclose (fp); return; } +