Cygwin: cygcheck: package info / available package search, take 2
- if the user has no perms to write to /etc/setup, don't try to fetch user homedir from Cygwin (crashes galore). Use LOCALAPPDATA path instead. - info is more rpm like - print info of installed package - added info selectors --inst, --curr, --prev, --test - add installation date TODO: - Human-readable filesize - url and license needs to be added to setup.ini yet - Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
76d2053ec8
commit
022665af17
|
@ -20,6 +20,7 @@
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "wide_path.h"
|
#include "wide_path.h"
|
||||||
|
#include "cygcheck.h"
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <cygwin/version.h>
|
#include <cygwin/version.h>
|
||||||
#define cygwin_internal cygwin_internal_dontuse
|
#define cygwin_internal cygwin_internal_dontuse
|
||||||
|
@ -53,9 +54,15 @@ int find_package = 0;
|
||||||
int list_package = 0;
|
int list_package = 0;
|
||||||
int grep_packages = 0;
|
int grep_packages = 0;
|
||||||
int info_packages = 0;
|
int info_packages = 0;
|
||||||
|
int info_selector = 0;
|
||||||
int search_packages = 0;
|
int search_packages = 0;
|
||||||
int del_orphaned_reg = 0;
|
int del_orphaned_reg = 0;
|
||||||
|
|
||||||
|
#define INFO_INST 0x01
|
||||||
|
#define INFO_CURR 0x02
|
||||||
|
#define INFO_PREV 0x04
|
||||||
|
#define INFO_TEST 0x08
|
||||||
|
|
||||||
static char emptystr[] = "";
|
static char emptystr[] = "";
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -2097,11 +2104,6 @@ struct passwd {
|
||||||
char *pw_shell; /* default shell */
|
char *pw_shell; /* default shell */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sidbuf {
|
|
||||||
PSID psid;
|
|
||||||
int buffer[10];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Downloads setup.ini from cygwin.com, if it hasn't been downloaded
|
/* Downloads setup.ini from cygwin.com, if it hasn't been downloaded
|
||||||
already or is older than 24h. */
|
already or is older than 24h. */
|
||||||
static FILE *
|
static FILE *
|
||||||
|
@ -2111,8 +2113,6 @@ maybe_download_setup_ini ()
|
||||||
char *path;
|
char *path;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct passwd *pw;
|
|
||||||
sidbuf curr_user;
|
|
||||||
|
|
||||||
t24h_before = time (NULL) - 24 * 60 * 60;
|
t24h_before = time (NULL) - 24 * 60 * 60;
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
|
@ -2123,22 +2123,15 @@ maybe_download_setup_ini ()
|
||||||
path = cygpath ("/etc/setup/setup.ini", NULL);
|
path = cygpath ("/etc/setup/setup.ini", NULL);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOL ret;
|
char *localappdata = getenv ("LOCALAPPDATA");
|
||||||
DWORD len;
|
char *cp;
|
||||||
HANDLE ptok;
|
|
||||||
|
|
||||||
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
|
if (!localappdata)
|
||||||
return NULL;
|
return NULL;
|
||||||
ret = GetTokenInformation (ptok, TokenUser, &curr_user,
|
path = (char *) malloc (strlen (localappdata)
|
||||||
sizeof curr_user, &len);
|
+ strlen ("\\.setup.ini") + 1);
|
||||||
CloseHandle (ptok);
|
cp = stpcpy (path, localappdata);
|
||||||
if (!ret)
|
stpcpy (cp, "\\.setup.ini");
|
||||||
return NULL;
|
|
||||||
pw = (struct passwd *) cygwin_internal (CW_GETPWSID, FALSE,
|
|
||||||
curr_user.psid);
|
|
||||||
if (!pw)
|
|
||||||
return NULL;
|
|
||||||
path = cygpath (pw->pw_dir, "/.setup.ini", NULL);
|
|
||||||
}
|
}
|
||||||
/* If file exists, and has been downloaded less than 24h ago,
|
/* If file exists, and has been downloaded less than 24h ago,
|
||||||
and if we can open it for reading, just use it. */
|
and if we can open it for reading, just use it. */
|
||||||
|
@ -2149,11 +2142,12 @@ maybe_download_setup_ini ()
|
||||||
/* Otherwise, try to open it for writing and fetch from cygwin.com. */
|
/* Otherwise, try to open it for writing and fetch from cygwin.com. */
|
||||||
if ((fp = fopen (path, "w+")) != NULL)
|
if ((fp = fopen (path, "w+")) != NULL)
|
||||||
{
|
{
|
||||||
fputs ("Fetching setup.ini from cygwin.com...\n", stderr);
|
fprintf (stderr, "Fetching %s from cygwin.com...\n", path);
|
||||||
if (!fetch_url ("https://cygwin.com/ftp/cygwin/x86_64/setup.ini", fp))
|
if (!fetch_url ("https://cygwin.com/ftp/cygwin/x86_64/setup.ini", fp))
|
||||||
{
|
{
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
fp = fopen (path, "rt");
|
fp = fopen (path, "rt");
|
||||||
|
fputs ("\n", stderr);
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
@ -2168,6 +2162,9 @@ struct vers_info
|
||||||
char *install;
|
char *install;
|
||||||
char *source;
|
char *source;
|
||||||
char *depends2;
|
char *depends2;
|
||||||
|
time_t install_date;
|
||||||
|
bool matches;
|
||||||
|
bool installed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ini_package_info
|
struct ini_package_info
|
||||||
|
@ -2386,6 +2383,8 @@ package_info_print (ini_package_info *pi, vers_info *vers)
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
{
|
||||||
printf ("Architecture: %s\n", arch);
|
printf ("Architecture: %s\n", arch);
|
||||||
|
if (vers->install_date)
|
||||||
|
printf ("Install Date: %s", ctime (&vers->install_date));
|
||||||
printf ("Size : %s\n", size); /* FIXME: human-readable */
|
printf ("Size : %s\n", size); /* FIXME: human-readable */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2408,93 +2407,225 @@ package_info_print (ini_package_info *pi, vers_info *vers)
|
||||||
if (pi->license)
|
if (pi->license)
|
||||||
printf ("License : %s\n", pi->license);
|
printf ("License : %s\n", pi->license);
|
||||||
if (pi->ldesc)
|
if (pi->ldesc)
|
||||||
{
|
printf ("Description :\n%s\n", pi->ldesc);
|
||||||
char *ldesc = strcpy (buf, pi->ldesc);
|
|
||||||
|
|
||||||
while (ldesc)
|
|
||||||
{
|
|
||||||
char *nl = strchr (ldesc, '\n');
|
|
||||||
if (nl)
|
|
||||||
*nl = '\0';
|
|
||||||
printf ("%s : %s\n", ldesc == buf ? "Description " : " ",
|
|
||||||
ldesc);
|
|
||||||
ldesc = nl ? nl + 1 : NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
puts ("");
|
puts ("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
package_info_check (ini_package_info *pi, vers_info *vi, pkgver *pv,
|
||||||
|
bool &am, bool &ai)
|
||||||
|
{
|
||||||
|
vi->matches = true;
|
||||||
|
if (pv && !strcmp (vi->version, pv->ver))
|
||||||
|
vi->installed = true;
|
||||||
|
am |= vi->matches;
|
||||||
|
ai |= vi->installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
check_name_version (char *pkg_name, char *pkg_version, char *search)
|
||||||
|
{
|
||||||
|
char nv_buf[4096];
|
||||||
|
char *nvp, *cp;
|
||||||
|
|
||||||
|
nvp = stpcpy (nv_buf, pkg_name);
|
||||||
|
*nvp++ = '-';
|
||||||
|
stpcpy (nvp, pkg_version);
|
||||||
|
if (PathMatchSpecA (nv_buf, search))
|
||||||
|
return true;
|
||||||
|
if ((cp = strrchr (nvp, '-'))) /* try w/o release */
|
||||||
|
{
|
||||||
|
*cp = '\0';
|
||||||
|
if (PathMatchSpecA (nv_buf, search))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
package_info_vers_check (ini_package_info *pi, vers_info *vi, char *search,
|
||||||
|
pkgver *pv, bool &am, bool &ai)
|
||||||
|
{
|
||||||
|
vi->matches = check_name_version (pi->name, vi->version, search);
|
||||||
|
if (pv && !strcmp (vi->version, pv->ver))
|
||||||
|
vi->installed = true;
|
||||||
|
am |= vi->matches;
|
||||||
|
ai |= vi->installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pkg_comp (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
pkgver *pa = (pkgver *) a;
|
||||||
|
pkgver *pb = (pkgver *) b;
|
||||||
|
|
||||||
|
return strcmp (pa->name, pb->name);
|
||||||
|
}
|
||||||
|
|
||||||
/* Print full info for the package matching the search string in terms of
|
/* Print full info for the package matching the search string in terms of
|
||||||
name/version. */
|
name/version. */
|
||||||
static int
|
static int
|
||||||
package_info (char **search)
|
package_info (char **search, int selector)
|
||||||
{
|
{
|
||||||
FILE *fp = maybe_download_setup_ini ();
|
FILE *fp = maybe_download_setup_ini ();
|
||||||
ini_package_info pi_buf, *pi;
|
ini_package_info pi_buf, *pi;
|
||||||
|
size_t inst_pkg_count;
|
||||||
|
pkgver *inst_pkgs;
|
||||||
|
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (selector == 0)
|
||||||
|
selector = INFO_CURR | INFO_PREV | INFO_TEST | INFO_INST;
|
||||||
|
|
||||||
|
inst_pkgs = get_installed_packages (NULL, &inst_pkg_count);
|
||||||
|
|
||||||
while (search && *search)
|
while (search && *search)
|
||||||
{
|
{
|
||||||
rewind (fp);
|
rewind (fp);
|
||||||
while ((pi = collect_pkg_info (fp, &pi_buf)))
|
while ((pi = collect_pkg_info (fp, &pi_buf)))
|
||||||
{
|
{
|
||||||
|
pkgver pv = { pi->name, NULL }, *inst_pkg = NULL;
|
||||||
|
bool avail_installed = false;
|
||||||
|
bool avail_matches = false;
|
||||||
|
bool inst_matches = false;
|
||||||
|
|
||||||
|
if (selector & INFO_INST)
|
||||||
|
{
|
||||||
|
inst_pkg = (pkgver *) bsearch (&pv, inst_pkgs, inst_pkg_count,
|
||||||
|
sizeof *inst_pkgs, pkg_comp);
|
||||||
|
if (inst_pkg)
|
||||||
|
{
|
||||||
|
if (PathMatchSpecA (inst_pkg->name, *search))
|
||||||
|
inst_matches = true;
|
||||||
|
else
|
||||||
|
inst_matches = check_name_version (inst_pkg->name,
|
||||||
|
inst_pkg->ver,
|
||||||
|
*search);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Name matches? Print all versions */
|
/* Name matches? Print all versions */
|
||||||
if (PathMatchSpecA (pi->name, *search))
|
if (PathMatchSpecA (pi->name, *search))
|
||||||
{
|
{
|
||||||
if (pi->curr.version)
|
if (pi->curr.version)
|
||||||
package_info_print (pi, &pi->curr);
|
package_info_check (pi, &pi->curr, inst_pkg,
|
||||||
|
avail_matches, avail_installed);
|
||||||
for (size_t i = 0; i < pi->prev_count; ++i)
|
for (size_t i = 0; i < pi->prev_count; ++i)
|
||||||
package_info_print (pi, pi->prev + i);
|
package_info_check (pi, pi->prev + i, inst_pkg,
|
||||||
|
avail_matches, avail_installed);
|
||||||
for (size_t i = 0; i < pi->test_count; ++i)
|
for (size_t i = 0; i < pi->test_count; ++i)
|
||||||
package_info_print (pi, pi->test + i);
|
package_info_check (pi, pi->test + i, inst_pkg,
|
||||||
|
avail_matches, avail_installed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if search matches name-version string */
|
/* Check if search matches name-version string */
|
||||||
char nv_buf[4096], *nvp, *cp;
|
|
||||||
|
|
||||||
nvp = stpcpy (nv_buf, pi->name);
|
|
||||||
*nvp++ = '-';
|
|
||||||
|
|
||||||
if (pi->curr.version)
|
if (pi->curr.version)
|
||||||
{
|
package_info_vers_check (pi, &pi->curr, *search, inst_pkg,
|
||||||
stpcpy (nvp, pi->curr.version);
|
avail_matches, avail_installed);
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
for (size_t i = 0; i < pi->prev_count; ++i)
|
||||||
package_info_print (pi, &pi->curr);
|
package_info_vers_check (pi, pi->prev + i, *search, inst_pkg,
|
||||||
else if ((cp = strrchr (nvp, '-'))) /* try w/o release */
|
avail_matches, avail_installed);
|
||||||
{
|
for (size_t i = 0; i < pi->test_count; ++i)
|
||||||
*cp = '\0';
|
package_info_vers_check (pi, pi->test + i, *search, inst_pkg,
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
avail_matches, avail_installed);
|
||||||
package_info_print (pi, &pi->curr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First print installed package(s) */
|
||||||
|
if (inst_pkg && inst_matches)
|
||||||
|
{
|
||||||
|
time_t install_ts = 0;
|
||||||
|
struct stat st;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
printf ("Installed package:\n"
|
||||||
|
"------------------\n\n");
|
||||||
|
/* fetch timestamp of last install. */
|
||||||
|
|
||||||
|
path = cygpath ("/etc/setup/", inst_pkg->name, ".lst.gz", NULL);
|
||||||
|
if (path)
|
||||||
|
{
|
||||||
|
if (stat (path, &st) == 0)
|
||||||
|
install_ts = st.st_mtime;
|
||||||
|
free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fake min info if installed package is not available anymore */
|
||||||
|
if (!avail_installed)
|
||||||
|
{
|
||||||
|
ini_package_info inst_pi = { 0 };
|
||||||
|
|
||||||
|
inst_pi.name = inst_pkg->name;
|
||||||
|
inst_pi.sdesc = pi->sdesc;
|
||||||
|
inst_pi.ldesc = pi->ldesc;
|
||||||
|
inst_pi.url = pi->url;
|
||||||
|
inst_pi.license = pi->license;
|
||||||
|
inst_pi.curr.version = inst_pkg->ver;
|
||||||
|
inst_pi.curr.install_date = install_ts;
|
||||||
|
package_info_print (&inst_pi, &pi->curr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pi->curr.installed)
|
||||||
|
{
|
||||||
|
pi->curr.install_date = install_ts;
|
||||||
|
package_info_print (pi, &pi->curr);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < pi->prev_count; ++i)
|
for (size_t i = 0; i < pi->prev_count; ++i)
|
||||||
|
if (pi->prev[i].installed)
|
||||||
{
|
{
|
||||||
stpcpy (nvp, pi->prev[i].version);
|
pi->prev[i].install_date = install_ts;
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
|
||||||
package_info_print (pi, pi->prev + i);
|
package_info_print (pi, pi->prev + i);
|
||||||
else if ((cp = strrchr (nvp, '-'))) /* try w/o release */
|
|
||||||
{
|
|
||||||
*cp = '\0';
|
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
|
||||||
package_info_print (pi, pi->prev + i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < pi->test_count; ++i)
|
for (size_t i = 0; i < pi->test_count; ++i)
|
||||||
|
if (pi->test[i].installed)
|
||||||
{
|
{
|
||||||
stpcpy (nvp, pi->test[i].version);
|
pi->test[i].install_date = install_ts;
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
|
||||||
package_info_print (pi, pi->test + i);
|
|
||||||
else if ((cp = strrchr (nvp, '-'))) /* try w/o release */
|
|
||||||
{
|
|
||||||
*cp = '\0';
|
|
||||||
if (PathMatchSpecA (nv_buf, *search))
|
|
||||||
package_info_print (pi, pi->test + i);
|
package_info_print (pi, pi->test + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Next print available, matching packages */
|
||||||
|
if (avail_matches)
|
||||||
|
{
|
||||||
|
if ((selector & INFO_CURR) && pi->curr.matches)
|
||||||
|
{
|
||||||
|
puts ("Latest available package:\n"
|
||||||
|
"-------------------------\n");
|
||||||
|
package_info_print (pi, &pi->curr);
|
||||||
|
}
|
||||||
|
if (selector & INFO_PREV)
|
||||||
|
{
|
||||||
|
uint32_t header_printed = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pi->prev_count; ++i)
|
||||||
|
if (pi->prev[i].matches)
|
||||||
|
{
|
||||||
|
printf ("%s", header_printed++
|
||||||
|
? ""
|
||||||
|
: "Older available packages:\n"
|
||||||
|
"-------------------------\n\n");
|
||||||
|
package_info_print (pi, pi->prev + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selector & INFO_TEST)
|
||||||
|
{
|
||||||
|
uint32_t header_printed = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pi->test_count; ++i)
|
||||||
|
if (pi->test[i].matches)
|
||||||
|
{
|
||||||
|
printf ("%s", header_printed++
|
||||||
|
? ""
|
||||||
|
: "Available test packages:\n"
|
||||||
|
"------------------------\n\n");
|
||||||
|
package_info_print (pi, pi->test + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free_pkg_info (&pi_buf);
|
free_pkg_info (&pi_buf);
|
||||||
}
|
}
|
||||||
++search;
|
++search;
|
||||||
|
@ -2578,7 +2709,7 @@ Usage: cygcheck [-v] [-h] PROGRAM\n\
|
||||||
cygcheck -k\n\
|
cygcheck -k\n\
|
||||||
cygcheck -f FILE [FILE]...\n\
|
cygcheck -f FILE [FILE]...\n\
|
||||||
cygcheck -l [PACKAGE]...\n\
|
cygcheck -l [PACKAGE]...\n\
|
||||||
cygcheck -i [PATTERN]...\n\
|
cygcheck -i [--inst,--curr,--prev,--test] [PATTERN]...\n\
|
||||||
cygcheck -e [PATTERN]...\n\
|
cygcheck -e [PATTERN]...\n\
|
||||||
cygcheck -p REGEXP\n\
|
cygcheck -p REGEXP\n\
|
||||||
cygcheck --delete-orphaned-installation-keys\n\
|
cygcheck --delete-orphaned-installation-keys\n\
|
||||||
|
@ -2595,12 +2726,19 @@ At least one command option or a PROGRAM is required, as shown above.\n\
|
||||||
-r, --registry also scan registry for Cygwin settings (with -s)\n\
|
-r, --registry also scan registry for Cygwin settings (with -s)\n\
|
||||||
-k, --keycheck perform a keyboard check session (must be run from a\n\
|
-k, --keycheck perform a keyboard check session (must be run from a\n\
|
||||||
plain console only, not from a pty/rxvt/xterm)\n\
|
plain console only, not from a pty/rxvt/xterm)\n\
|
||||||
|
-e, --search-package list all available packages matching PATTERN\n\
|
||||||
|
PATTERN is a glob pattern with * and ? as wildcard chars\n\
|
||||||
|
-i, --info-package print full info on packages matching PATTERN, installed\n\
|
||||||
|
and available packages\n\
|
||||||
|
PATTERN is a glob pattern with * and ? as wildcard chars\n\
|
||||||
|
info selection specifiers (multiple allowed):\n\
|
||||||
|
--inst only print info on installed package\n\
|
||||||
|
--curr only print info on most recent available package\n\
|
||||||
|
--prev only print info on older, but still available packages\n\
|
||||||
|
--test only print info on test packages\n\
|
||||||
-f, --find-package find the installed package to which FILE belongs\n\
|
-f, --find-package find the installed package to which FILE belongs\n\
|
||||||
-l, --list-package list contents of the installed PACKAGE (or all\n\
|
-l, --list-package list contents of the installed PACKAGE (or all\n\
|
||||||
installed packages if none given)\n\
|
installed packages if none given)\n\
|
||||||
-i, --info-package print full info on packages matching PATTERN, installed\n\
|
|
||||||
and available packages\n\
|
|
||||||
-e, --search-package list all available packages matching PATTERN\n\
|
|
||||||
-p, --package-query search for REGEXP in the entire cygwin.com package\n\
|
-p, --package-query search for REGEXP in the entire cygwin.com package\n\
|
||||||
repository (requires internet connectivity)\n\
|
repository (requires internet connectivity)\n\
|
||||||
--delete-orphaned-installation-keys\n\
|
--delete-orphaned-installation-keys\n\
|
||||||
|
@ -2612,7 +2750,8 @@ At least one command option or a PROGRAM is required, as shown above.\n\
|
||||||
with another command, otherwise print this help\n\
|
with another command, otherwise print this help\n\
|
||||||
-V, --version print the version of cygcheck and exit\n\
|
-V, --version print the version of cygcheck and exit\n\
|
||||||
\n\
|
\n\
|
||||||
Note: -c, -f, and -l only report on packages that are currently installed. To\n\
|
Notes:\n\
|
||||||
|
-c, -f, and -l only report on packages that are currently installed. To\n\
|
||||||
search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
|
search all official Cygwin packages use -p instead. The -p REGEXP matches\n\
|
||||||
package names, descriptions, and names of files/paths within all packages.\n\
|
package names, descriptions, and names of files/paths within all packages.\n\
|
||||||
\n");
|
\n");
|
||||||
|
@ -2629,6 +2768,10 @@ struct option longopts[] = {
|
||||||
{"find-package", no_argument, NULL, 'f'},
|
{"find-package", no_argument, NULL, 'f'},
|
||||||
{"list-package", no_argument, NULL, 'l'},
|
{"list-package", no_argument, NULL, 'l'},
|
||||||
{"info-packages", no_argument, NULL, 'i'},
|
{"info-packages", no_argument, NULL, 'i'},
|
||||||
|
{"inst", no_argument, NULL, 0x1001},
|
||||||
|
{"curr", no_argument, NULL, 0x1002},
|
||||||
|
{"prev", no_argument, NULL, 0x1004},
|
||||||
|
{"test", no_argument, NULL, 0x1008},
|
||||||
{"search-packages", no_argument, NULL, 'e'},
|
{"search-packages", no_argument, NULL, 'e'},
|
||||||
{"package-query", no_argument, NULL, 'p'},
|
{"package-query", no_argument, NULL, 'p'},
|
||||||
{"delete-orphaned-installation-keys", no_argument, NULL, CO_DELETE_KEYS},
|
{"delete-orphaned-installation-keys", no_argument, NULL, CO_DELETE_KEYS},
|
||||||
|
@ -2763,6 +2906,12 @@ main (int argc, char **argv)
|
||||||
case 'i':
|
case 'i':
|
||||||
info_packages = 1;
|
info_packages = 1;
|
||||||
break;
|
break;
|
||||||
|
case 0x1001:
|
||||||
|
case 0x1002:
|
||||||
|
case 0x1004:
|
||||||
|
case 0x1008:
|
||||||
|
info_selector |= (i & 0xf);
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
search_packages = 1;
|
search_packages = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -2821,7 +2970,7 @@ main (int argc, char **argv)
|
||||||
if (grep_packages)
|
if (grep_packages)
|
||||||
return package_grep (*argv);
|
return package_grep (*argv);
|
||||||
if (info_packages)
|
if (info_packages)
|
||||||
return package_info (argv);
|
return package_info (argv, info_selector);
|
||||||
if (search_packages)
|
if (search_packages)
|
||||||
return package_search (argv);
|
return package_search (argv);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* cygcheck.h
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct pkgver
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *ver;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern pkgver *get_installed_packages (char **, size_t * = NULL);
|
|
@ -21,6 +21,7 @@ details. */
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
#include <ntstatus.h>
|
#include <ntstatus.h>
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "cygcheck.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
static int package_len = 20;
|
static int package_len = 20;
|
||||||
|
@ -151,12 +152,6 @@ dump_file (const char *msg, const char *fn)
|
||||||
return printed;
|
return printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pkgver
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *ver;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
int
|
int
|
||||||
compar (const void *a, const void *b)
|
compar (const void *a, const void *b)
|
||||||
|
@ -403,8 +398,8 @@ check_package_files (int verbose, char *package)
|
||||||
* Returns a calloc'd sorted list of packages or NULL if no info.
|
* Returns a calloc'd sorted list of packages or NULL if no info.
|
||||||
* The last entry in the list is {NULL,NULL}.
|
* The last entry in the list is {NULL,NULL}.
|
||||||
*/
|
*/
|
||||||
static pkgver *
|
pkgver *
|
||||||
get_packages (char **argv)
|
get_installed_packages (char **argv, size_t *count)
|
||||||
{
|
{
|
||||||
char *setup = cygpath ("/etc/setup/installed.db", NULL);
|
char *setup = cygpath ("/etc/setup/installed.db", NULL);
|
||||||
FILE *fp = fopen (setup, "rt");
|
FILE *fp = fopen (setup, "rt");
|
||||||
|
@ -464,13 +459,16 @@ get_packages (char **argv)
|
||||||
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
*count = n;
|
||||||
|
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dump_setup (int verbose, char **argv, bool check_files)
|
dump_setup (int verbose, char **argv, bool check_files)
|
||||||
{
|
{
|
||||||
pkgver *packages = get_packages(argv);
|
pkgver *packages = get_installed_packages (argv);
|
||||||
|
|
||||||
puts ("Cygwin Package Information");
|
puts ("Cygwin Package Information");
|
||||||
if (packages == NULL)
|
if (packages == NULL)
|
||||||
|
@ -509,7 +507,7 @@ dump_setup (int verbose, char **argv, bool check_files)
|
||||||
void
|
void
|
||||||
package_list (int verbose, char **argv)
|
package_list (int verbose, char **argv)
|
||||||
{
|
{
|
||||||
pkgver *packages = get_packages(argv);
|
pkgver *packages = get_installed_packages (argv);
|
||||||
if (packages == NULL)
|
if (packages == NULL)
|
||||||
{
|
{
|
||||||
puts ("No setup information found");
|
puts ("No setup information found");
|
||||||
|
@ -549,7 +547,7 @@ package_list (int verbose, char **argv)
|
||||||
void
|
void
|
||||||
package_find (int verbose, char **argv)
|
package_find (int verbose, char **argv)
|
||||||
{
|
{
|
||||||
pkgver *packages = get_packages(NULL);
|
pkgver *packages = get_installed_packages (NULL);
|
||||||
if (packages == NULL)
|
if (packages == NULL)
|
||||||
{
|
{
|
||||||
puts ("No setup information found");
|
puts ("No setup information found");
|
||||||
|
|
Loading…
Reference in New Issue