[PATCH] Checking integrity of installed packages in cygcheck
Igor Pechtchanski
pechtcha@cs.nyu.edu
Thu Aug 7 22:50:00 GMT 2003
Hi,
This patch adds most of the capability of the script from
<http://cygwin.com/ml/cygwin-apps/2003-08/msg00106.html> to cygcheck.
It is triggered by the "-c" flag to cygcheck. "Integrity" is a rather
strong word, actually, as all this checks for is the existence of files
and directories, but this could be further built upon (for example, tar
has a diff option that could be useful). The patch is against cvs HEAD
with my previous micropatch
(<http://cygwin.com/ml/cygwin-patches/2003-q3/msg00058.html>) applied.
Comments and suggestions welcome.
Igor
==============================================================================
ChangeLog:
2003-08-07 Igor Pechtchanski <pechtcha@cs.nyu.edu>
* dump_setup.cc (version_len): New static variable.
(could_not_access,directory_exists,file_exists)
(check_package_files): New static functions.
(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.
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ pechtcha@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ igor@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski, Ph.D.
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!
"I have since come to realize that being between your mentor and his route
to the bathroom is a major career booster." -- Patrick Naughton
-------------- next part --------------
Index: winsup/utils/dump_setup.cc
===================================================================
RCS file: /cvs/src/src/winsup/utils/dump_setup.cc,v
retrieving revision 1.6
diff -u -p -r1.6 dump_setup.cc
--- winsup/utils/dump_setup.cc 7 Feb 2003 21:34:34 -0000 1.6
+++ winsup/utils/dump_setup.cc 7 Aug 2003 22:34:16 -0000
@@ -15,9 +15,12 @@ details. */
#include <stdlib.h>
#include <string.h>
#include <io.h>
+#include <sys/stat.h>
+#include <errno.h>
#include "path.h"
static int package_len = 20;
+static unsigned int version_len = 10;
typedef struct
@@ -173,8 +176,100 @@ match_argv (char **argv, const char *nam
return false;
}
+static bool
+could_not_access (int verbose, char *filename, char *package, const char *type)
+{
+ switch (errno)
+ {
+ case ENOTDIR:
+ break;
+ case ENOENT:
+ if (verbose)
+ printf ("Missing %s: /%s from package %s\n",
+ type, filename, package);
+ return true;
+ case EACCES:
+ if (verbose)
+ printf ("Unable to access %s /%s from package %s\n",
+ type, filename, package);
+ return true;
+ }
+ return false;
+}
+
+static bool
+directory_exists (int verbose, char *filename, char *package)
+{
+ struct stat status;
+ if (stat(cygpath("/", filename, ".", NULL), &status))
+ {
+ if (could_not_access (verbose, filename, package, "directory"))
+ return false;
+ }
+ else if (!S_ISDIR(status.st_mode))
+ {
+ if (verbose)
+ printf ("Directory/file mismatch: /%s from package %s\n", filename, package);
+ return false;
+ }
+ return true;
+}
+
+static bool
+file_exists (int verbose, char *filename, const char *alt, char *package)
+{
+ struct stat status;
+ if (stat(cygpath("/", filename, NULL), &status) &&
+ (!alt || stat(cygpath("/", filename, alt, NULL), &status)))
+ {
+ if (could_not_access (verbose, filename, package, "file"))
+ return false;
+ }
+ else if (!S_ISREG(status.st_mode))
+ {
+ if (verbose)
+ printf ("File type mismatch: /%s from package %s\n", filename, package);
+ return false;
+ }
+ return true;
+}
+
+static bool
+check_package_files (int verbose, char *package)
+{
+ bool result = true;
+ char filelist[4096] = " -dc /etc/setup/";
+ strcat(strcat(filelist, package), ".lst.gz");
+ char *zcat = cygpath("/bin/gzip.exe", NULL);
+ char command[4096];
+ strcat(strcpy(command, zcat), filelist);
+ FILE *fp = popen (command, "rt");
+ char buf[4096];
+ while (fgets (buf, 4096, fp))
+ {
+ char *filename = strtok(buf, "\n");
+ if (filename[strlen(filename)-1] == '/')
+ {
+ if (!directory_exists(verbose, filename, package))
+ result = false;
+ }
+ else if (!strncmp(filename, "etc/postinstall/", 16))
+ {
+ if (!file_exists(verbose, filename, ".done", package))
+ result = false;
+ }
+ else
+ {
+ if (!file_exists(verbose, filename, ".lnk", package))
+ result = false;
+ }
+ }
+ fclose(fp);
+ return result;
+}
+
void
-dump_setup (int verbose, char **argv, bool /*check_files*/)
+dump_setup (int verbose, char **argv, bool check_files)
{
char *setup = cygpath ("/etc/setup/installed.db", NULL);
FILE *fp = fopen (setup, "rt");
@@ -223,6 +318,8 @@ dump_setup (int verbose, char **argv, bo
if (f.what[0])
strcat (strcat (packages[n].name, "-"), f.what);
packages[n].ver = strdup (f.ver);
+ if (strlen(f.ver) > version_len)
+ version_len = strlen(f.ver);
n++;
if (strtok (NULL, " ") == NULL)
break;
@@ -231,9 +328,12 @@ dump_setup (int verbose, char **argv, bo
qsort (packages, n, sizeof (packages[0]), compar);
- printf ("%-*s %s\n", package_len, "Package", "Version");
+ printf ("%-*s %-*s %s\n", package_len, "Package", version_len, "Version", check_files?"Status":"");
for (int i = 0; i < n; i++)
- printf ("%-*s %s\n", package_len, packages[i].name, packages[i].ver);
+ {
+ 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);
return;
More information about the Cygwin-patches
mailing list