Index: Source/cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.338
diff -u -r1.338 cmSystemTools.cxx
--- Source/cmSystemTools.cxx	12 Mar 2007 17:50:28 -0000	1.338
+++ Source/cmSystemTools.cxx	13 Apr 2007 13:57:20 -0000
@@ -1040,6 +1040,11 @@
   return Superclass::CopyFileAlways(source, destination);
 }
 
+bool cmSystemTools::cmComputeFileMD5(const char* source, char* md5out)
+{
+  return Superclass::ComputeFileMD5(source, md5out);
+}
+
 bool cmSystemTools::CopyFileIfDifferent(const char* source, 
   const char* destination)
 {
Index: Source/cmSystemTools.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.h,v
retrieving revision 1.139
diff -u -r1.139 cmSystemTools.h
--- Source/cmSystemTools.h	12 Mar 2007 17:50:28 -0000	1.139
+++ Source/cmSystemTools.h	13 Apr 2007 13:57:20 -0000
@@ -165,6 +165,9 @@
   static bool CopyFileIfDifferent(const char* source, 
     const char* destination);
 
+  ///! Compute the md5sum of a file
+  static bool cmComputeFileMD5(const char* source, char* md5out);
+
   /**
    * Run an executable command and put the stdout in output.
    * A temporary file is created in the binaryDir for storing the
Index: Source/cmake.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmake.cxx,v
retrieving revision 1.290
diff -u -r1.290 cmake.cxx
--- Source/cmake.cxx	12 Mar 2007 20:10:00 -0000	1.290
+++ Source/cmake.cxx	13 Apr 2007 13:57:21 -0000
@@ -801,8 +801,9 @@
     " line\n"
     << "  environment             - display the current enviroment\n"
     << "  make_directory dir      - create a directory\n"
+    << "  md5sum file1 [...]      - compute md5sum of files\n"
     << "  remove_directory dir    - remove a directory and its contents\n"
-    << "  remove file1 file2 ...  - remove the file(s)\n"
+    << "  remove file1 file2 ...  - remove the file(s). Add -f to force removal\n"
     << "  tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar.\n"
     << "  time command [args] ... - run command and return elapsed time\n"
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -993,6 +994,30 @@
     }
 
     // Command to change directory and run a program.
+    else if (args[1] == "md5sum" && args.size() >= 3)
+      {
+      char md5out[32];
+      for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+        {
+        const char *filename = args[cc].c_str();
+        // Cannot compute md5sum of a directory
+        if(cmSystemTools::FileIsDirectory(filename))
+          {
+          std::cerr << "Error: " << filename << " is a directory" << std::endl;
+          }
+        else if(!cmSystemTools::ComputeFileMD5(filename, md5out))
+          {
+          // To mimic md5sum behavior in a shell:
+          std::cerr << filename << ": No such file or directory" << std::endl;
+          }
+        else
+          {
+          std::cout << std::string(md5out,32) << "  " << filename << std::endl;
+          }
+        }
+      return 1;
+      }
+    // Command to change directory and run a program.
     else if (args[1] == "chdir" && args.size() >= 4)
       {
       std::string directory = args[2];
Index: Source/kwsys/SystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/SystemTools.cxx,v
retrieving revision 1.198
diff -u -r1.198 SystemTools.cxx
--- Source/kwsys/SystemTools.cxx	12 Mar 2007 17:50:28 -0000	1.198
+++ Source/kwsys/SystemTools.cxx	13 Apr 2007 13:57:25 -0000
@@ -14,6 +14,7 @@
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(SystemTools.hxx)
 #include KWSYS_HEADER(Directory.hxx)
+#include KWSYS_HEADER(MD5.h)
 
 #include KWSYS_HEADER(ios/iostream)
 #include KWSYS_HEADER(ios/fstream)
@@ -24,6 +25,7 @@
 #if 0
 # include "SystemTools.hxx.in"
 # include "Directory.hxx.in"
+# include "MD5.h.in"
 # include "kwsys_ios_iostream.h.in"
 # include "kwsys_ios_fstream.h.in"
 # include "kwsys_ios_sstream.h.in"
@@ -1715,6 +1717,57 @@
 }
 
 //----------------------------------------------------------------------------
+/**
+ * compute the md5sum of file `source`
+ */
+bool SystemTools::ComputeFileMD5(const char* source, char* md5out)
+{
+  if(!SystemTools::FileExists(source))
+    {
+    return false;
+    }
+
+  // Open files
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+  kwsys_ios::ifstream fin(source, 
+                    kwsys_ios::ios::binary | kwsys_ios::ios::in);
+#else
+  kwsys_ios::ifstream fin(source);
+#endif
+  if(!fin)
+    {
+    return false;
+    }
+ 
+  kwsysMD5* md5 = kwsysMD5_New();
+  kwsysMD5_Initialize(md5);
+
+  // Should be efficient enough on most system:
+  const int bufferSize = 4096;
+  char buffer[bufferSize];
+  // This copy loop is very sensitive on certain platforms with
+  // slightly broken stream libraries (like HPUX).  Normally, it is
+  // incorrect to not check the error condition on the fin.read()
+  // before using the data, but the fin.gcount() will be zero if an
+  // error occurred.  Therefore, the loop should be safe everywhere.
+  while(fin)
+    {
+    fin.read(buffer, bufferSize);
+    if(fin.gcount())
+      {
+      kwsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(buffer), fin.gcount());
+      }
+    }
+  kwsysMD5_FinalizeHex(md5, md5out);
+  kwsysMD5_Delete(md5);
+
+  fin.close();
+
+  return true;
+}
+
+//----------------------------------------------------------------------------
 bool SystemTools::CopyAFile(const char* source, const char* destination,
                             bool always)
 {
Index: Source/kwsys/SystemTools.hxx.in
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/SystemTools.hxx.in,v
retrieving revision 1.65
diff -u -r1.65 SystemTools.hxx.in
--- Source/kwsys/SystemTools.hxx.in	12 Mar 2007 17:50:28 -0000	1.65
+++ Source/kwsys/SystemTools.hxx.in	13 Apr 2007 13:57:25 -0000
@@ -467,6 +467,12 @@
                                   const char* destination);
   
   /**
+   * Compute the md5sum of the file `source`
+   * return false in case source is not a file
+   */
+  static bool ComputeFileMD5(const char* source, char* md5out);
+
+  /**
    * Compare the contents of two files.  Return true if different
    */
   static bool FilesDiffer(const char* source, const char* destination);
