[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