/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmFileCommand.h"
#include "cmCryptoHash.h"
#include "cmake.h"
#include "cmHexFileConverter.h"
#include "cmInstallType.h"
#include "cmFileTimeComparison.h"
#include "cmCryptoHash.h"

#include "cmTimestamp.h"

#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cm_curl.h"
#endif

#undef GetCurrentDirectory
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <cmsys/auto_ptr.hxx>
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>

// Table of permissions flags.
#if defined(_WIN32) && !defined(__CYGWIN__)
static mode_t mode_owner_read = S_IREAD;
static mode_t mode_owner_write = S_IWRITE;
static mode_t mode_owner_execute = S_IEXEC;
static mode_t mode_group_read = 0;
static mode_t mode_group_write = 0;
static mode_t mode_group_execute = 0;
static mode_t mode_world_read = 0;
static mode_t mode_world_write = 0;
static mode_t mode_world_execute = 0;
static mode_t mode_setuid = 0;
static mode_t mode_setgid = 0;
#else
static mode_t mode_owner_read = S_IRUSR;
static mode_t mode_owner_write = S_IWUSR;
static mode_t mode_owner_execute = S_IXUSR;
static mode_t mode_group_read = S_IRGRP;
static mode_t mode_group_write = S_IWGRP;
static mode_t mode_group_execute = S_IXGRP;
static mode_t mode_world_read = S_IROTH;
static mode_t mode_world_write = S_IWOTH;
static mode_t mode_world_execute = S_IXOTH;
static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID;
#endif

// cmLibraryCommand
bool cmFileCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 2 )
    {
    this->SetError("must be called with at least two arguments.");
    return false;
    }
  std::string subCommand = args[0];
  if ( subCommand == "WRITE" )
    {
    return this->HandleWriteCommand(args, false);
    }
  else if ( subCommand == "APPEND" )
    {
    return this->HandleWriteCommand(args, true);
    }
  else if ( subCommand == "DOWNLOAD" )
    {
    return this->HandleDownloadCommand(args);
    }
  else if ( subCommand == "UPLOAD" )
    {
    return this->HandleUploadCommand(args);
    }
  else if ( subCommand == "READ" )
    {
    return this->HandleReadCommand(args);
    }
  else if ( subCommand == "MD5" ||
            subCommand == "SHA1" ||
            subCommand == "SHA224" ||
            subCommand == "SHA256" ||
            subCommand == "SHA384" ||
            subCommand == "SHA512" )
    {
    return this->HandleHashCommand(args);
    }
  else if ( subCommand == "STRINGS" )
    {
    return this->HandleStringsCommand(args);
    }
  else if ( subCommand == "GLOB" )
    {
    return this->HandleGlobCommand(args, false);
    }
  else if ( subCommand == "GLOB_RECURSE" )
    {
    return this->HandleGlobCommand(args, true);
    }
  else if ( subCommand == "MAKE_DIRECTORY" )
    {
    return this->HandleMakeDirectoryCommand(args);
    }
  else if ( subCommand == "RENAME" )
    {
    return this->HandleRename(args);
    }
  else if ( subCommand == "REMOVE" )
    {
    return this->HandleRemove(args, false);
    }
  else if ( subCommand == "REMOVE_RECURSE" )
    {
    return this->HandleRemove(args, true);
    }
  else if ( subCommand == "COPY" )
    {
    return this->HandleCopyCommand(args);
    }
  else if ( subCommand == "INSTALL" )
    {
    return this->HandleInstallCommand(args);
    }
  else if ( subCommand == "DIFFERENT" )
    {
    return this->HandleDifferentCommand(args);
    }
  else if ( subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH" )
    {
    return this->HandleRPathChangeCommand(args);
    }
  else if ( subCommand == "RPATH_CHECK" )
    {
    return this->HandleRPathCheckCommand(args);
    }
  else if ( subCommand == "RPATH_REMOVE" )
    {
    return this->HandleRPathRemoveCommand(args);
    }
  else if ( subCommand == "RELATIVE_PATH" )
    {
    return this->HandleRelativePathCommand(args);
    }
  else if ( subCommand == "TO_CMAKE_PATH" )
    {
    return this->HandleCMakePathCommand(args, false);
    }
  else if ( subCommand == "TO_NATIVE_PATH" )
    {
    return this->HandleCMakePathCommand(args, true);
    }
  else if ( subCommand == "TIMESTAMP" )
    {
    return this->HandleTimestampCommand(args);
    }
  else if ( subCommand == "GENERATE" )
    {
    return this->HandleGenerateCommand(args);
    }

  std::string e = "does not recognize sub-command "+subCommand;
  this->SetError(e.c_str());
  return false;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
  bool append)
{
  std::string message;
  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string fileName = *i;
  if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + *i;
    }

  i++;

  for(;i != args.end(); ++i)
    {
    message += *i;
    }
  if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) )
    {
    std::string e
      = "attempted to write a file: " + fileName +
      " into a source directory.";
    this->SetError(e.c_str());
    cmSystemTools::SetFatalErrorOccured();
    return false;
    }
  std::string dir = cmSystemTools::GetFilenamePath(fileName);
  cmSystemTools::MakeDirectory(dir.c_str());

  mode_t mode = 0;

  // Set permissions to writable
  if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) )
    {
    cmSystemTools::SetPermissions(fileName.c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
      mode | S_IWRITE
#elif defined( __BORLANDC__ )
      mode | S_IWUSR
#else
      mode | S_IWUSR | S_IWGRP
#endif
    );
    }
  // If GetPermissions fails, pretend like it is ok. File open will fail if
  // the file is not writable
  std::ofstream file(fileName.c_str(), append?std::ios::app: std::ios::out);
  if ( !file )
    {
    std::string error = "Internal CMake error when trying to open file: ";
    error += fileName.c_str();
    error += " for writing.";
    this->SetError(error.c_str());
    return false;
    }
  file << message;
  file.close();
  if(mode)
    {
    cmSystemTools::SetPermissions(fileName.c_str(), mode);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
{
  if ( args.size() < 3 )
    {
    this->SetError("READ must be called with at least two additional "
                   "arguments");
    return false;
    }

  cmCommandArgumentsHelper argHelper;
  cmCommandArgumentGroup group;

  cmCAString readArg    (&argHelper, "READ");
  cmCAString fileNameArg    (&argHelper, 0);
  cmCAString resultArg      (&argHelper, 0);

  cmCAString offsetArg      (&argHelper, "OFFSET", &group);
  cmCAString limitArg       (&argHelper, "LIMIT", &group);
  cmCAEnabler hexOutputArg  (&argHelper, "HEX", &group);
  readArg.Follows(0);
  fileNameArg.Follows(&readArg);
  resultArg.Follows(&fileNameArg);
  group.Follows(&resultArg);
  argHelper.Parse(&args, 0);

  std::string fileName = fileNameArg.GetString();
  if ( !cmsys::SystemTools::FileIsFullPath(fileName.c_str()) )
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + fileNameArg.GetString();
    }

  std::string variable = resultArg.GetString();

  // Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
  std::ifstream file(fileName.c_str(), std::ios::in |
               (hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in));
#else
  std::ifstream file(fileName.c_str(), std::ios::in);
#endif

  if ( !file )
    {
    std::string error = "Internal CMake error when trying to open file: ";
    error += fileName.c_str();
    error += " for reading.";
    this->SetError(error.c_str());
    return false;
    }

  // is there a limit?
  long sizeLimit = -1;
  if (limitArg.GetString().size() > 0)
    {
    sizeLimit = atoi(limitArg.GetCString());
    }

  // is there an offset?
  long offset = 0;
  if (offsetArg.GetString().size() > 0)
    {
    offset = atoi(offsetArg.GetCString());
    }

  file.seekg(offset, std::ios::beg); // explicit ios::beg for IBM VisualAge 6

  std::string output;

  if (hexOutputArg.IsEnabled())
    {
    // Convert part of the file into hex code
    char c;
    while((sizeLimit != 0) && (file.get(c)))
      {
      char hex[4];
      sprintf(hex, "%.2x", c&0xff);
      output += hex;
      if (sizeLimit > 0)
        {
        sizeLimit--;
        }
      }
    }
  else
    {
    std::string line;
    bool has_newline = false;
    while (sizeLimit != 0 &&
          cmSystemTools::GetLineFromStream(file, line, &has_newline,
                                            sizeLimit) )
      {
      if (sizeLimit > 0)
        {
        sizeLimit = sizeLimit - static_cast<long>(line.size());
        if (has_newline)
          {
          sizeLimit--;
          }
        if (sizeLimit < 0)
          {
          sizeLimit = 0;
          }
        }
      output += line;
      if ( has_newline )
        {
        output += "\n";
        }
      }
    }
  this->Makefile->AddDefinition(variable.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
  if(args.size() != 3)
    {
    cmOStringStream e;
    e << args[0] << " requires a file name and output variable";
    this->SetError(e.str().c_str());
    return false;
    }

  cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
  if(hash.get())
    {
    std::string out = hash->HashFile(args[1].c_str());
    if(!out.empty())
      {
      this->Makefile->AddDefinition(args[2].c_str(), out.c_str());
      return true;
      }
    cmOStringStream e;
    e << args[0] << " failed to read file \"" << args[1] << "\": "
      << cmSystemTools::GetLastSystemError();
    this->SetError(e.str().c_str());
    }
  return false;
#else
  cmOStringStream e;
  e << args[0] << " not available during bootstrap";
  this->SetError(e.str().c_str());
  return false;
#endif
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
{
  if(args.size() < 3)
    {
    this->SetError("STRINGS requires a file name and output variable");
    return false;
    }

  // Get the file to read.
  std::string fileName = args[1];
  if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + args[1];
    }

  // Get the variable in which to store the results.
  std::string outVar = args[2];

  // Parse the options.
  enum { arg_none,
         arg_limit_input,
         arg_limit_output,
         arg_limit_count,
         arg_length_minimum,
         arg_length_maximum,
         arg__maximum,
         arg_regex };
  unsigned int minlen = 0;
  unsigned int maxlen = 0;
  int limit_input = -1;
  int limit_output = -1;
  unsigned int limit_count = 0;
  cmsys::RegularExpression regex;
  bool have_regex = false;
  bool newline_consume = false;
  bool hex_conversion_enabled = true;
  int arg_mode = arg_none;
  for(unsigned int i=3; i < args.size(); ++i)
    {
    if(args[i] == "LIMIT_INPUT")
      {
      arg_mode = arg_limit_input;
      }
    else if(args[i] == "LIMIT_OUTPUT")
      {
      arg_mode = arg_limit_output;
      }
    else if(args[i] == "LIMIT_COUNT")
      {
      arg_mode = arg_limit_count;
      }
    else if(args[i] == "LENGTH_MINIMUM")
      {
      arg_mode = arg_length_minimum;
      }
    else if(args[i] == "LENGTH_MAXIMUM")
      {
      arg_mode = arg_length_maximum;
      }
    else if(args[i] == "REGEX")
      {
      arg_mode = arg_regex;
      }
    else if(args[i] == "NEWLINE_CONSUME")
      {
      newline_consume = true;
      arg_mode = arg_none;
      }
    else if(args[i] == "NO_HEX_CONVERSION")
      {
      hex_conversion_enabled = false;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_input)
      {
      if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
         limit_input < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_INPUT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_output)
      {
      if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
         limit_output < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_OUTPUT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_count)
      {
      int count;
      if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_COUNT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      limit_count = count;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_length_minimum)
      {
      int len;
      if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LENGTH_MINIMUM value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      minlen = len;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_length_maximum)
      {
      int len;
      if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LENGTH_MAXIMUM value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      maxlen = len;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_regex)
      {
      if(!regex.compile(args[i].c_str()))
        {
        cmOStringStream e;
        e << "STRINGS option REGEX value \""
          << args[i] << "\" could not be compiled.";
        this->SetError(e.str().c_str());
        return false;
        }
      have_regex = true;
      arg_mode = arg_none;
      }
    else
      {
      cmOStringStream e;
      e << "STRINGS given unknown argument \""
        << args[i] << "\"";
      this->SetError(e.str().c_str());
      return false;
      }
    }

  if (hex_conversion_enabled)
    {
    // TODO: should work without temp file, but just on a memory buffer
    std::string binaryFileName = this->Makefile->GetCurrentOutputDirectory();
    binaryFileName += cmake::GetCMakeFilesDirectory();
    binaryFileName += "/FileCommandStringsBinaryFile";
    if(cmHexFileConverter::TryConvert(fileName.c_str(),binaryFileName.c_str()))
      {
      fileName = binaryFileName;
      }
    }

  // Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
  std::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
#else
  std::ifstream fin(fileName.c_str(), std::ios::in);
#endif
  if(!fin)
    {
    cmOStringStream e;
    e << "STRINGS file \"" << fileName << "\" cannot be read.";
    this->SetError(e.str().c_str());
    return false;
    }

  // Parse strings out of the file.
  int output_size = 0;
  std::vector<std::string> strings;
  std::string s;
  int c;
  while((!limit_count || strings.size() < limit_count) &&
        (limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
        (c = fin.get(), fin))
    {
    if(c == '\n' && !newline_consume)
      {
      // The current line has been terminated.  Check if the current
      // string matches the requirements.  The length may now be as
      // low as zero since blank lines are allowed.
      if(s.length() >= minlen &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }

      // Reset the string to empty.
      s = "";
      }
    else if(c == '\r')
      {
      // Ignore CR character to make output always have UNIX newlines.
      }
    else if((c >= 0x20 && c < 0x7F) || c == '\t' ||
            (c == '\n' && newline_consume))
      {
      // This is an ASCII character that may be part of a string.
      // Cast added to avoid compiler warning. Cast is ok because
      // c is guaranteed to fit in char by the above if...
      s += static_cast<char>(c);
      }
    else
      {
      // TODO: Support ENCODING option.  See issue #10519.
      // A non-string character has been found.  Check if the current
      // string matches the requirements.  We require that the length
      // be at least one no matter what the user specified.
      if(s.length() >= minlen && s.length() >= 1 &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }

      // Reset the string to empty.
      s = "";
      }

    // Terminate a string if the maximum length is reached.
    if(maxlen > 0 && s.size() == maxlen)
      {
      if(s.length() >= minlen &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }
      s = "";
      }
    }

  // If there is a non-empty current string we have hit the end of the
  // input file or the input size limit.  Check if the current string
  // matches the requirements.
  if((!limit_count || strings.size() < limit_count) &&
     !s.empty() && s.length() >= minlen &&
     (!have_regex || regex.find(s.c_str())))
    {
    output_size += static_cast<int>(s.size()) + 1;
    if(limit_output < 0 || output_size < limit_output)
      {
      strings.push_back(s);
      }
    }

  // Encode the result in a CMake list.
  const char* sep = "";
  std::string output;
  for(std::vector<std::string>::const_iterator si = strings.begin();
      si != strings.end(); ++si)
    {
    // Separate the strings in the output to make it a list.
    output += sep;
    sep = ";";

    // Store the string in the output, but escape semicolons to
    // make sure it is a list.
    std::string const& sr = *si;
    for(unsigned int i=0; i < sr.size(); ++i)
      {
      if(sr[i] == ';')
        {
        output += '\\';
        }
      output += sr[i];
      }
    }

  // Save the output in a makefile variable.
  this->Makefile->AddDefinition(outVar.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
  bool recurse)
{
  // File commands has at least one argument
  assert(args.size() > 1);

  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string variable = *i;
  i++;
  cmsys::Glob g;
  g.SetRecurse(recurse);

  bool explicitFollowSymlinks = false;
  cmPolicies::PolicyStatus status =
    this->Makefile->GetPolicyStatus(cmPolicies::CMP0009);
  if(recurse)
    {
    switch(status)
      {
      case cmPolicies::NEW:
        g.RecurseThroughSymlinksOff();
        break;
      case cmPolicies::OLD:
      case cmPolicies::WARN:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        g.RecurseThroughSymlinksOn();
        break;
      }
    }

  std::string output = "";
  bool first = true;
  for ( ; i != args.end(); ++i )
    {
    if ( recurse && (*i == "FOLLOW_SYMLINKS") )
      {
      explicitFollowSymlinks = true;
      g.RecurseThroughSymlinksOn();
      ++i;
      if ( i == args.end() )
        {
        this->SetError(
          "GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS");
        return false;
        }
      }

    if ( *i == "RELATIVE" )
      {
      ++i; // skip RELATIVE
      if ( i == args.end() )
        {
        this->SetError("GLOB requires a directory after the RELATIVE tag");
        return false;
        }
      g.SetRelative(i->c_str());
      ++i;
      if(i == args.end())
        {
        this->SetError("GLOB requires a glob expression after the directory");
        return false;
        }
      }

    if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
      {
      std::string expr = this->Makefile->GetCurrentDirectory();
      // Handle script mode
      if ( expr.size() > 0 )
        {
        expr += "/" + *i;
        g.FindFiles(expr);
        }
      else
        {
        g.FindFiles(*i);
        }
      }
    else
      {
      g.FindFiles(*i);
      }

    std::vector<std::string>::size_type cc;
    std::vector<std::string>& files = g.GetFiles();
    for ( cc = 0; cc < files.size(); cc ++ )
      {
      if ( !first )
        {
        output += ";";
        }
      output += files[cc];
      first = false;
      }
    }

  if(recurse && !explicitFollowSymlinks)
    {
    switch (status)
      {
      case cmPolicies::NEW:
        // Correct behavior, yay!
        break;
      case cmPolicies::OLD:
        // Probably not really the expected behavior, but the author explicitly
        // asked for the old behavior... no warning.
      case cmPolicies::WARN:
        // Possibly unexpected old behavior *and* we actually traversed
        // symlinks without being explicitly asked to: warn the author.
        if(g.GetFollowedSymlinkCount() != 0)
          {
          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
            this->Makefile->GetPolicies()->
              GetPolicyWarning(cmPolicies::CMP0009));
          }
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        this->SetError("policy CMP0009 error");
        this->Makefile->IssueMessage(cmake::FATAL_ERROR,
          this->Makefile->GetPolicies()->
            GetRequiredPolicyError(cmPolicies::CMP0009));
        return false;
      }
    }

  this->Makefile->AddDefinition(variable.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleMakeDirectoryCommand(
  std::vector<std::string> const& args)
{
  // File command has at least one argument
  assert(args.size() > 1);

  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string expr;
  for ( ; i != args.end(); ++i )
    {
    const std::string* cdir = &(*i);
    if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
      {
      expr = this->Makefile->GetCurrentDirectory();
      expr += "/" + *i;
      cdir = &expr;
      }
    if ( !this->Makefile->CanIWriteThisFile(cdir->c_str()) )
      {
      std::string e = "attempted to create a directory: " + *cdir
        + " into a source directory.";
      this->SetError(e.c_str());
      cmSystemTools::SetFatalErrorOccured();
      return false;
      }
    if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
      {
      std::string error = "problem creating directory: " + *cdir;
      this->SetError(error.c_str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args)
{
  /*
    FILE(DIFFERENT <variable> FILES <lhs> <rhs>)
   */

  // Evaluate arguments.
  const char* file_lhs = 0;
  const char* file_rhs = 0;
  const char* var = 0;
  enum Doing { DoingNone, DoingVar, DoingFileLHS, DoingFileRHS };
  Doing doing = DoingVar;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "FILES")
      {
      doing = DoingFileLHS;
      }
    else if(doing == DoingVar)
      {
      var = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingFileLHS)
      {
      file_lhs = args[i].c_str();
      doing = DoingFileRHS;
      }
    else if(doing == DoingFileRHS)
      {
      file_rhs = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "DIFFERENT given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!var)
    {
    this->SetError("DIFFERENT not given result variable name.");
    return false;
    }
  if(!file_lhs || !file_rhs)
    {
    this->SetError("DIFFERENT not given FILES option with two file names.");
    return false;
    }

  // Compare the files.
  const char* result =
    cmSystemTools::FilesDiffer(file_lhs, file_rhs)? "1" : "0";
  this->Makefile->AddDefinition(var, result);
  return true;
}

//----------------------------------------------------------------------------
// File installation helper class.
struct cmFileCopier
{
  cmFileCopier(cmFileCommand* command, const char* name = "COPY"):
    FileCommand(command),
    Makefile(command->GetMakefile()),
    Name(name),
    Always(false),
    MatchlessFiles(true),
    FilePermissions(0),
    DirPermissions(0),
    CurrentMatchRule(0),
    UseGivenPermissionsFile(false),
    UseGivenPermissionsDir(false),
    UseSourcePermissions(true),
    Doing(DoingNone)
    {
    }
  virtual ~cmFileCopier() {}

  bool Run(std::vector<std::string> const& args);
protected:

  cmFileCommand* FileCommand;
  cmMakefile* Makefile;
  const char* Name;
  bool Always;
  cmFileTimeComparison FileTimes;

  // Whether to install a file not matching any expression.
  bool MatchlessFiles;

  // Permissions for files and directories installed by this object.
  mode_t FilePermissions;
  mode_t DirPermissions;

  // Properties set by pattern and regex match rules.
  struct MatchProperties
  {
    bool Exclude;
    mode_t Permissions;
    MatchProperties(): Exclude(false), Permissions(0) {}
  };
  struct MatchRule;
  friend struct MatchRule;
  struct MatchRule
  {
    cmsys::RegularExpression Regex;
    MatchProperties Properties;
    std::string RegexString;
    MatchRule(std::string const& regex):
      Regex(regex.c_str()), RegexString(regex) {}
  };
  std::vector<MatchRule> MatchRules;

  // Get the properties from rules matching this input file.
  MatchProperties CollectMatchProperties(const char* file)
    {
    // Match rules are case-insensitive on some platforms.
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
    std::string lower = cmSystemTools::LowerCase(file);
    const char* file_to_match = lower.c_str();
#else
    const char* file_to_match = file;
#endif

    // Collect properties from all matching rules.
    bool matched = false;
    MatchProperties result;
    for(std::vector<MatchRule>::iterator mr = this->MatchRules.begin();
        mr != this->MatchRules.end(); ++mr)
      {
      if(mr->Regex.find(file_to_match))
        {
        matched = true;
        result.Exclude |= mr->Properties.Exclude;
        result.Permissions |= mr->Properties.Permissions;
        }
      }
    if(!matched && !this->MatchlessFiles)
      {
      result.Exclude = !cmSystemTools::FileIsDirectory(file);
      }
    return result;
    }

  bool SetPermissions(const char* toFile, mode_t permissions)
    {
    if(permissions && !cmSystemTools::SetPermissions(toFile, permissions))
      {
      cmOStringStream e;
      e << this->Name << " cannot set permissions on \"" << toFile << "\"";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    return true;
    }

  // Translate an argument to a permissions bit.
  bool CheckPermissions(std::string const& arg, mode_t& permissions)
    {
    if(arg == "OWNER_READ")         { permissions |= mode_owner_read; }
    else if(arg == "OWNER_WRITE")   { permissions |= mode_owner_write; }
    else if(arg == "OWNER_EXECUTE") { permissions |= mode_owner_execute; }
    else if(arg == "GROUP_READ")    { permissions |= mode_group_read; }
    else if(arg == "GROUP_WRITE")   { permissions |= mode_group_write; }
    else if(arg == "GROUP_EXECUTE") { permissions |= mode_group_execute; }
    else if(arg == "WORLD_READ")    { permissions |= mode_world_read; }
    else if(arg == "WORLD_WRITE")   { permissions |= mode_world_write; }
    else if(arg == "WORLD_EXECUTE") { permissions |= mode_world_execute; }
    else if(arg == "SETUID")        { permissions |= mode_setuid; }
    else if(arg == "SETGID")        { permissions |= mode_setgid; }
    else
      {
      cmOStringStream e;
      e << this->Name << " given invalid permission \"" << arg << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    return true;
    }

  bool InstallSymlink(const char* fromFile, const char* toFile);
  bool InstallFile(const char* fromFile, const char* toFile,
                   MatchProperties const& match_properties);
  bool InstallDirectory(const char* source, const char* destination,
                        MatchProperties const& match_properties);
  virtual bool Install(const char* fromFile, const char* toFile);
  virtual std::string const& ToName(std::string const& fromName)
    { return fromName; }

  enum Type
  {
    TypeFile,
    TypeDir,
    TypeLink
  };
  virtual void ReportCopy(const char*, Type, bool) {}
  virtual bool ReportMissing(const char* fromFile)
    {
    // The input file does not exist and installation is not optional.
    cmOStringStream e;
    e << this->Name << " cannot find \"" << fromFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  MatchRule* CurrentMatchRule;
  bool UseGivenPermissionsFile;
  bool UseGivenPermissionsDir;
  bool UseSourcePermissions;
  std::string Destination;
  std::vector<std::string> Files;
  int Doing;

  virtual bool Parse(std::vector<std::string> const& args);
  enum
  {
    DoingNone,
    DoingError,
    DoingDestination,
    DoingFiles,
    DoingPattern,
    DoingRegex,
    DoingPermissionsFile,
    DoingPermissionsDir,
    DoingPermissionsMatch,
    DoingLast1
  };
  virtual bool CheckKeyword(std::string const& arg);
  virtual bool CheckValue(std::string const& arg);

  void NotBeforeMatch(std::string const& arg)
    {
    cmOStringStream e;
    e << "option " << arg << " may not appear before PATTERN or REGEX.";
    this->FileCommand->SetError(e.str().c_str());
    this->Doing = DoingError;
    }
  void NotAfterMatch(std::string const& arg)
    {
    cmOStringStream e;
    e << "option " << arg << " may not appear after PATTERN or REGEX.";
    this->FileCommand->SetError(e.str().c_str());
    this->Doing = DoingError;
    }
  virtual void DefaultFilePermissions()
    {
    // Use read/write permissions.
    this->FilePermissions = 0;
    this->FilePermissions |= mode_owner_read;
    this->FilePermissions |= mode_owner_write;
    this->FilePermissions |= mode_group_read;
    this->FilePermissions |= mode_world_read;
    }
  virtual void DefaultDirectoryPermissions()
    {
    // Use read/write/executable permissions.
    this->DirPermissions = 0;
    this->DirPermissions |= mode_owner_read;
    this->DirPermissions |= mode_owner_write;
    this->DirPermissions |= mode_owner_execute;
    this->DirPermissions |= mode_group_read;
    this->DirPermissions |= mode_group_execute;
    this->DirPermissions |= mode_world_read;
    this->DirPermissions |= mode_world_execute;
    }
};

//----------------------------------------------------------------------------
bool cmFileCopier::Parse(std::vector<std::string> const& args)
{
  this->Doing = DoingFiles;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    // Check this argument.
    if(!this->CheckKeyword(args[i]) &&
       !this->CheckValue(args[i]))
      {
      cmOStringStream e;
      e << "called with unknown argument \"" << args[i] << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }

    // Quit if an argument is invalid.
    if(this->Doing == DoingError)
      {
      return false;
      }
    }

  // Require a destination.
  if(this->Destination.empty())
    {
    cmOStringStream e;
    e << this->Name << " given no DESTINATION";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // If file permissions were not specified set default permissions.
  if(!this->UseGivenPermissionsFile && !this->UseSourcePermissions)
    {
    this->DefaultFilePermissions();
    }

  // If directory permissions were not specified set default permissions.
  if(!this->UseGivenPermissionsDir && !this->UseSourcePermissions)
    {
    this->DefaultDirectoryPermissions();
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::CheckKeyword(std::string const& arg)
{
  if(arg == "DESTINATION")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingDestination;
      }
    }
  else if(arg == "PATTERN")
    {
    this->Doing = DoingPattern;
    }
  else if(arg == "REGEX")
    {
    this->Doing = DoingRegex;
    }
  else if(arg == "EXCLUDE")
    {
    // Add this property to the current match rule.
    if(this->CurrentMatchRule)
      {
      this->CurrentMatchRule->Properties.Exclude = true;
      this->Doing = DoingNone;
      }
    else
      {
      this->NotBeforeMatch(arg);
      }
    }
  else if(arg == "PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->Doing = DoingPermissionsMatch;
      }
    else
      {
      this->NotBeforeMatch(arg);
      }
    }
  else if(arg == "FILE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingPermissionsFile;
      this->UseGivenPermissionsFile = true;
      }
    }
  else if(arg == "DIRECTORY_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingPermissionsDir;
      this->UseGivenPermissionsDir = true;
      }
    }
  else if(arg == "USE_SOURCE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->UseSourcePermissions = true;
      }
    }
  else if(arg == "NO_SOURCE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->UseSourcePermissions = false;
      }
    }
  else if(arg == "FILES_MATCHING")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->MatchlessFiles = false;
      }
    }
  else
    {
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::CheckValue(std::string const& arg)
{
  switch(this->Doing)
    {
    case DoingFiles:
      if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
        {
        this->Files.push_back(arg);
        }
      else
        {
        std::string file = this->Makefile->GetCurrentDirectory();
        file += "/" + arg;
        this->Files.push_back(file);
        }
      break;
    case DoingDestination:
      if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
        {
        this->Destination = arg;
        }
      else
        {
        this->Destination = this->Makefile->GetCurrentOutputDirectory();
        this->Destination += "/" + arg;
        }
      this->Doing = DoingNone;
      break;
    case DoingPattern:
      {
      // Convert the pattern to a regular expression.  Require a
      // leading slash and trailing end-of-string in the matched
      // string to make sure the pattern matches only whole file
      // names.
      std::string regex = "/";
      regex += cmsys::Glob::PatternToRegex(arg, false);
      regex += "$";
      this->MatchRules.push_back(MatchRule(regex));
      this->CurrentMatchRule = &*(this->MatchRules.end()-1);
      if(this->CurrentMatchRule->Regex.is_valid())
        {
        this->Doing = DoingNone;
        }
      else
        {
        cmOStringStream e;
        e << "could not compile PATTERN \"" << arg << "\".";
        this->FileCommand->SetError(e.str().c_str());
        this->Doing = DoingError;
        }
      }
      break;
    case DoingRegex:
      this->MatchRules.push_back(MatchRule(arg));
      this->CurrentMatchRule = &*(this->MatchRules.end()-1);
      if(this->CurrentMatchRule->Regex.is_valid())
        {
        this->Doing = DoingNone;
        }
      else
        {
        cmOStringStream e;
        e << "could not compile REGEX \"" << arg << "\".";
        this->FileCommand->SetError(e.str().c_str());
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsFile:
      if(!this->CheckPermissions(arg, this->FilePermissions))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsDir:
      if(!this->CheckPermissions(arg, this->DirPermissions))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsMatch:
      if(!this->CheckPermissions(
           arg, this->CurrentMatchRule->Properties.Permissions))
        {
        this->Doing = DoingError;
        }
      break;
    default:
      return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::Run(std::vector<std::string> const& args)
{
  if(!this->Parse(args))
    {
    return false;
    }

  std::vector<std::string> const& files = this->Files;
  for(std::vector<std::string>::size_type i = 0; i < files.size(); ++i)
    {
    // Split the input file into its directory and name components.
    std::vector<std::string> fromPathComponents;
    cmSystemTools::SplitPath(files[i].c_str(), fromPathComponents);
    std::string fromName = *(fromPathComponents.end()-1);
    std::string fromDir = cmSystemTools::JoinPath(fromPathComponents.begin(),
                                                  fromPathComponents.end()-1);

    // Compute the full path to the destination file.
    std::string toFile = this->Destination;
    std::string const& toName = this->ToName(fromName);
    if(!toName.empty())
      {
      toFile += "/";
      toFile += toName;
      }

    // Construct the full path to the source file.  The file name may
    // have been changed above.
    std::string fromFile = fromDir;
    if(!fromName.empty())
      {
      fromFile += "/";
      fromFile += fromName;
      }

    if(!this->Install(fromFile.c_str(), toFile.c_str()))
      {
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::Install(const char* fromFile, const char* toFile)
{
  if(!*fromFile)
    {
    cmOStringStream e;
    e << "INSTALL encountered an empty string input file name.";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Collect any properties matching this file name.
  MatchProperties match_properties = this->CollectMatchProperties(fromFile);

  // Skip the file if it is excluded.
  if(match_properties.Exclude)
    {
    return true;
    }

  if(cmSystemTools::SameFile(fromFile, toFile))
    {
    return true;
    }
  else if(cmSystemTools::FileIsSymlink(fromFile))
    {
    return this->InstallSymlink(fromFile, toFile);
    }
  else if(cmSystemTools::FileIsDirectory(fromFile))
    {
    return this->InstallDirectory(fromFile, toFile, match_properties);
    }
  else if(cmSystemTools::FileExists(fromFile))
    {
    return this->InstallFile(fromFile, toFile, match_properties);
    }
  return this->ReportMissing(fromFile);
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
{
  // Read the original symlink.
  std::string symlinkTarget;
  if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
    {
    cmOStringStream e;
    e << this->Name << " cannot read symlink \"" << fromFile
      << "\" to duplicate at \"" << toFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Compare the symlink value to that at the destination if not
  // always installing.
  bool copy = true;
  if(!this->Always)
    {
    std::string oldSymlinkTarget;
    if(cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget))
      {
      if(symlinkTarget == oldSymlinkTarget)
        {
        copy = false;
        }
      }
    }

  // Inform the user about this file installation.
  this->ReportCopy(toFile, TypeLink, copy);

  if(copy)
    {
    // Remove the destination file so we can always create the symlink.
    cmSystemTools::RemoveFile(toFile);

    // Create the symlink.
    if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
      {
      cmOStringStream e;
      e << this->Name <<  " cannot duplicate symlink \"" << fromFile
        << "\" at \"" << toFile << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
                               MatchProperties const& match_properties)
{
  // Determine whether we will copy the file.
  bool copy = true;
  if(!this->Always)
    {
    // If both files exist with the same time do not copy.
    if(!this->FileTimes.FileTimesDiffer(fromFile, toFile))
      {
      copy = false;
      }
    }

  // Inform the user about this file installation.
  this->ReportCopy(toFile, TypeFile, copy);

  // Copy the file.
  if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true))
    {
    cmOStringStream e;
    e << this->Name << " cannot copy file \"" << fromFile
      << "\" to \"" << toFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Set the file modification time of the destination file.
  if(copy && !this->Always)
    {
    // Add write permission so we can set the file time.
    // Permissions are set unconditionally below anyway.
    mode_t perm = 0;
    if(cmSystemTools::GetPermissions(toFile, perm))
      {
      cmSystemTools::SetPermissions(toFile, perm | mode_owner_write);
      }
    if (!cmSystemTools::CopyFileTime(fromFile, toFile))
      {
      cmOStringStream e;
      e << this->Name << " cannot set modification time on \""
        << toFile << "\"";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    }

  // Set permissions of the destination file.
  mode_t permissions = (match_properties.Permissions?
                        match_properties.Permissions : this->FilePermissions);
  if(!permissions)
    {
    // No permissions were explicitly provided but the user requested
    // that the source file permissions be used.
    cmSystemTools::GetPermissions(fromFile, permissions);
    }
  return this->SetPermissions(toFile, permissions);
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallDirectory(const char* source,
                                    const char* destination,
                                    MatchProperties const& match_properties)
{
  // Inform the user about this directory installation.
  this->ReportCopy(destination, TypeDir, true);

  // Make sure the destination directory exists.
  if(!cmSystemTools::MakeDirectory(destination))
    {
    cmOStringStream e;
    e << this->Name << " cannot make directory \"" << destination << "\": "
      << cmSystemTools::GetLastSystemError();
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Compute the requested permissions for the destination directory.
  mode_t permissions = (match_properties.Permissions?
                        match_properties.Permissions : this->DirPermissions);
  if(!permissions)
    {
    // No permissions were explicitly provided but the user requested
    // that the source directory permissions be used.
    cmSystemTools::GetPermissions(source, permissions);
    }

  // Compute the set of permissions required on this directory to
  // recursively install files and subdirectories safely.
  mode_t required_permissions =
    mode_owner_read | mode_owner_write | mode_owner_execute;

  // If the required permissions are specified it is safe to set the
  // final permissions now.  Otherwise we must add the required
  // permissions temporarily during file installation.
  mode_t permissions_before = 0;
  mode_t permissions_after = 0;
  if((permissions & required_permissions) == required_permissions)
    {
    permissions_before = permissions;
    }
  else
    {
    permissions_before = permissions | required_permissions;
    permissions_after = permissions;
    }

  // Set the required permissions of the destination directory.
  if(!this->SetPermissions(destination, permissions_before))
    {
    return false;
    }

  // Load the directory contents to traverse it recursively.
  cmsys::Directory dir;
  if(source && *source)
    {
    dir.Load(source);
    }
  unsigned long numFiles = static_cast<unsigned long>(dir.GetNumberOfFiles());
  for(unsigned long fileNum = 0; fileNum < numFiles; ++fileNum)
    {
    if(!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
         strcmp(dir.GetFile(fileNum), "..") == 0))
      {
      cmsys_stl::string fromPath = source;
      fromPath += "/";
      fromPath += dir.GetFile(fileNum);
      std::string toPath = destination;
      toPath += "/";
      toPath += dir.GetFile(fileNum);
      if(!this->Install(fromPath.c_str(), toPath.c_str()))
        {
        return false;
        }
      }
    }

  // Set the requested permissions of the destination directory.
  return this->SetPermissions(destination, permissions_after);
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args)
{
  cmFileCopier copier(this);
  return copier.Run(args);
}

//----------------------------------------------------------------------------
struct cmFileInstaller: public cmFileCopier
{
  cmFileInstaller(cmFileCommand* command):
    cmFileCopier(command, "INSTALL"),
    InstallType(cmInstallType_FILES),
    Optional(false),
    DestDirLength(0)
    {
    // Installation does not use source permissions by default.
    this->UseSourcePermissions = false;
    // Check whether to copy files always or only if they have changed.
    this->Always =
      cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS"));
    // Get the current manifest.
    this->Manifest =
      this->Makefile->GetSafeDefinition("CMAKE_INSTALL_MANIFEST_FILES");
    }
  ~cmFileInstaller()
    {
    // Save the updated install manifest.
    this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
                                  this->Manifest.c_str());
    }

protected:
  cmInstallType InstallType;
  bool Optional;
  int DestDirLength;
  std::string Rename;

  std::string Manifest;
  void ManifestAppend(std::string const& file)
    {
    this->Manifest += ";";
    this->Manifest += file.substr(this->DestDirLength);
    }

  virtual std::string const& ToName(std::string const& fromName)
    { return this->Rename.empty()? fromName : this->Rename; }

  virtual void ReportCopy(const char* toFile, Type type, bool copy)
    {
    std::string message = (copy? "Installing: " : "Up-to-date: ");
    message += toFile;
    this->Makefile->DisplayStatus(message.c_str(), -1);
    if(type != TypeDir)
      {
      // Add the file to the manifest.
      this->ManifestAppend(toFile);
      }
    }
  virtual bool ReportMissing(const char* fromFile)
    {
    return (this->Optional ||
            this->cmFileCopier::ReportMissing(fromFile));
    }
  virtual bool Install(const char* fromFile, const char* toFile)
    {
    // Support installing from empty source to make a directory.
    if(this->InstallType == cmInstallType_DIRECTORY && !*fromFile)
      {
      return this->InstallDirectory(fromFile, toFile, MatchProperties());
      }
    return this->cmFileCopier::Install(fromFile, toFile);
    }

  virtual bool Parse(std::vector<std::string> const& args);
  enum
  {
    DoingType = DoingLast1,
    DoingRename,
    DoingLast2
  };
  virtual bool CheckKeyword(std::string const& arg);
  virtual bool CheckValue(std::string const& arg);
  virtual void DefaultFilePermissions()
    {
    this->cmFileCopier::DefaultFilePermissions();
    // Add execute permissions based on the target type.
    switch(this->InstallType)
      {
      case cmInstallType_SHARED_LIBRARY:
      case cmInstallType_MODULE_LIBRARY:
        if(this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE"))
          {
          break;
          }
      case cmInstallType_EXECUTABLE:
      case cmInstallType_PROGRAMS:
        this->FilePermissions |= mode_owner_execute;
        this->FilePermissions |= mode_group_execute;
        this->FilePermissions |= mode_world_execute;
        break;
      default: break;
      }
    }
  bool GetTargetTypeFromString(const std::string& stype);
  bool HandleInstallDestination();
};

//----------------------------------------------------------------------------
bool cmFileInstaller::Parse(std::vector<std::string> const& args)
{
  if(!this->cmFileCopier::Parse(args))
    {
    return false;
    }

  if(!this->Rename.empty())
    {
    if(this->InstallType != cmInstallType_FILES &&
       this->InstallType != cmInstallType_PROGRAMS)
      {
      this->FileCommand->SetError("INSTALL option RENAME may be used "
                                  "only with FILES or PROGRAMS.");
      return false;
      }
    if(this->Files.size() > 1)
      {
      this->FileCommand->SetError("INSTALL option RENAME may be used "
                                  "only with one file.");
      return false;
      }
    }

  if(!this->HandleInstallDestination())
    {
    return false;
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::CheckKeyword(std::string const& arg)
{
  if(arg == "TYPE")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingType;
      }
    }
  else if(arg == "FILES")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingFiles;
      }
    }
  else if(arg == "RENAME")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingRename;
      }
    }
  else if(arg == "OPTIONAL")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->Optional = true;
      }
    }
  else if(arg == "PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->Doing = DoingPermissionsMatch;
      }
    else
      {
      // file(INSTALL) aliases PERMISSIONS to FILE_PERMISSIONS
      this->Doing = DoingPermissionsFile;
      this->UseGivenPermissionsFile = true;
      }
    }
  else if(arg == "DIR_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      // file(INSTALL) aliases DIR_PERMISSIONS to DIRECTORY_PERMISSIONS
      this->Doing = DoingPermissionsDir;
      this->UseGivenPermissionsDir = true;
      }
    }
  else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
          arg == "PROPERTIES")
    {
    cmOStringStream e;
    e << "INSTALL called with old-style " << arg << " argument.  "
      << "This script was generated with an older version of CMake.  "
      << "Re-run this cmake version on your build tree.";
    this->FileCommand->SetError(e.str().c_str());
    this->Doing = DoingError;
    }
  else
    {
    return this->cmFileCopier::CheckKeyword(arg);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::CheckValue(std::string const& arg)
{
  switch(this->Doing)
    {
    case DoingType:
      if(!this->GetTargetTypeFromString(arg))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingRename:
      this->Rename = arg;
      break;
    default:
      return this->cmFileCopier::CheckValue(arg);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller
::GetTargetTypeFromString(const std::string& stype)
{
  if ( stype == "EXECUTABLE" )
    {
    this->InstallType = cmInstallType_EXECUTABLE;
    }
  else if ( stype == "FILE" )
    {
    this->InstallType = cmInstallType_FILES;
    }
  else if ( stype == "PROGRAM" )
    {
    this->InstallType = cmInstallType_PROGRAMS;
    }
  else if ( stype == "STATIC_LIBRARY" )
    {
    this->InstallType = cmInstallType_STATIC_LIBRARY;
    }
  else if ( stype == "SHARED_LIBRARY" )
    {
    this->InstallType = cmInstallType_SHARED_LIBRARY;
    }
  else if ( stype == "MODULE" )
    {
    this->InstallType = cmInstallType_MODULE_LIBRARY;
    }
  else if ( stype == "DIRECTORY" )
    {
    this->InstallType = cmInstallType_DIRECTORY;
    }
  else
    {
    cmOStringStream e;
    e << "Option TYPE given unknown value \"" << stype << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::HandleInstallDestination()
{
  std::string& destination = this->Destination;

  // allow for / to be a valid destination
  if ( destination.size() < 2 && destination != "/" )
    {
    this->FileCommand->SetError("called with inappropriate arguments. "
        "No DESTINATION provided or .");
    return false;
    }

  const char* destdir = cmSystemTools::GetEnv("DESTDIR");
  if ( destdir && *destdir )
    {
    std::string sdestdir = destdir;
    cmSystemTools::ConvertToUnixSlashes(sdestdir);
    char ch1 = destination[0];
    char ch2 = destination[1];
    char ch3 = 0;
    if ( destination.size() > 2 )
      {
      ch3 = destination[2];
      }
    int skip = 0;
    if ( ch1 != '/' )
      {
      int relative = 0;
      if (((ch1 >= 'a' && ch1 <= 'z') || (ch1 >= 'A' && ch1 <= 'Z')) &&
             ch2 == ':' )
        {
        // Assume windows
        // let's do some destdir magic:
        skip = 2;
        if ( ch3 != '/' )
          {
          relative = 1;
          }
        }
      else
        {
        relative = 1;
        }
      if ( relative )
        {
        // This is relative path on unix or windows. Since we are doing
        // destdir, this case does not make sense.
        this->FileCommand->SetError(
          "called with relative DESTINATION. This "
          "does not make sense when using DESTDIR. Specify "
          "absolute path or remove DESTDIR environment variable.");
        return false;
        }
      }
    else
      {
      if ( ch2 == '/' )
        {
        // looks like a network path.
        std::string message = "called with network path DESTINATION. This "
          "does not make sense when using DESTDIR. Specify local "
          "absolute path or remove DESTDIR environment variable."
          "\nDESTINATION=\n";
        message += destination;
        this->FileCommand->SetError(message.c_str());
        return false;
        }
      }
    destination = sdestdir + (destination.c_str() + skip);
    this->DestDirLength = int(sdestdir.size());
    }

  if ( !cmSystemTools::FileExists(destination.c_str()) )
    {
    if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
      {
      std::string errstring = "cannot create directory: " + destination +
          ". Maybe need administrative privileges.";
      this->FileCommand->SetError(errstring.c_str());
      return false;
      }
    }
  if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
    {
    std::string errstring = "INSTALL destination: " + destination +
        " is not a directory.";
    this->FileCommand->SetError(errstring.c_str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  const char* oldRPath = 0;
  const char* newRPath = 0;
  enum Doing { DoingNone, DoingFile, DoingOld, DoingNew };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "OLD_RPATH")
      {
      doing = DoingOld;
      }
    else if(args[i] == "NEW_RPATH")
      {
      doing = DoingNew;
      }
    else if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingOld)
      {
      oldRPath = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingNew)
      {
      newRPath = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_CHANGE given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_CHANGE not given FILE option.");
    return false;
    }
  if(!oldRPath)
    {
    this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
    return false;
    }
  if(!newRPath)
    {
    this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
    return false;
    }
  if(!cmSystemTools::FileExists(file, true))
    {
    cmOStringStream e;
    e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
    this->SetError(e.str().c_str());
    return false;
    }
  bool success = true;
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
  std::string emsg;
  bool changed;
  if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed))
    {
    cmOStringStream e;
    e << "RPATH_CHANGE could not write new RPATH:\n"
      << "  " << newRPath << "\n"
      << "to the file:\n"
      << "  " << file << "\n"
      << emsg;
    this->SetError(e.str().c_str());
    success = false;
    }
  if(success)
    {
    if(changed)
      {
      std::string message = "Set runtime path of \"";
      message += file;
      message += "\" to \"";
      message += newRPath;
      message += "\"";
      this->Makefile->DisplayStatus(message.c_str(), -1);
      }
    if(have_ft)
      {
      cmSystemTools::FileTimeSet(file, ft);
      }
    }
  cmSystemTools::FileTimeDelete(ft);
  return success;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  enum Doing { DoingNone, DoingFile };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_REMOVE given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_REMOVE not given FILE option.");
    return false;
    }
  if(!cmSystemTools::FileExists(file, true))
    {
    cmOStringStream e;
    e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
    this->SetError(e.str().c_str());
    return false;
    }
  bool success = true;
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
  std::string emsg;
  bool removed;
  if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
    {
    cmOStringStream e;
    e << "RPATH_REMOVE could not remove RPATH from file:\n"
      << "  " << file << "\n"
      << emsg;
    this->SetError(e.str().c_str());
    success = false;
    }
  if(success)
    {
    if(removed)
      {
      std::string message = "Removed runtime path from \"";
      message += file;
      message += "\"";
      this->Makefile->DisplayStatus(message.c_str(), -1);
      }
    if(have_ft)
      {
      cmSystemTools::FileTimeSet(file, ft);
      }
    }
  cmSystemTools::FileTimeDelete(ft);
  return success;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  const char* rpath = 0;
  enum Doing { DoingNone, DoingFile, DoingRPath };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "RPATH")
      {
      doing = DoingRPath;
      }
    else if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingRPath)
      {
      rpath = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_CHECK given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_CHECK not given FILE option.");
    return false;
    }
  if(!rpath)
    {
    this->SetError("RPATH_CHECK not given RPATH option.");
    return false;
    }

  // If the file exists but does not have the desired RPath then
  // delete it.  This is used during installation to re-install a file
  // if its RPath will change.
  if(cmSystemTools::FileExists(file, true) &&
     !cmSystemTools::CheckRPath(file, rpath))
    {
    cmSystemTools::RemoveFile(file);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
{
  cmFileInstaller installer(this);
  return installer.Run(args);
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleRelativePathCommand(
  std::vector<std::string> const& args)
{
  if(args.size() != 4 )
    {
    this->SetError("RELATIVE_PATH called with incorrect number of arguments");
    return false;
    }

  const std::string& outVar = args[1];
  const std::string& directoryName = args[2];
  const std::string& fileName = args[3];

  if(!cmSystemTools::FileIsFullPath(directoryName.c_str()))
    {
    std::string errstring =
      "RELATIVE_PATH must be passed a full path to the directory: "
      + directoryName;
    this->SetError(errstring.c_str());
    return false;
    }
  if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
    {
    std::string errstring =
      "RELATIVE_PATH must be passed a full path to the file: "
      + fileName;
    this->SetError(errstring.c_str());
    return false;
    }

  std::string res = cmSystemTools::RelativePath(directoryName.c_str(),
                                                fileName.c_str());
  this->Makefile->AddDefinition(outVar.c_str(),
    res.c_str());
  return true;
}


//----------------------------------------------------------------------------
bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
{
  if(args.size() != 3)
    {
    this->SetError("RENAME given incorrect number of arguments.");
    return false;
    }

  // Compute full path for old and new names.
  std::string oldname = args[1];
  if(!cmsys::SystemTools::FileIsFullPath(oldname.c_str()))
    {
    oldname = this->Makefile->GetCurrentDirectory();
    oldname += "/" + args[1];
    }
  std::string newname = args[2];
  if(!cmsys::SystemTools::FileIsFullPath(newname.c_str()))
    {
    newname = this->Makefile->GetCurrentDirectory();
    newname += "/" + args[2];
    }

  if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str()))
    {
    std::string err = cmSystemTools::GetLastSystemError();
    cmOStringStream e;
    e << "RENAME failed to rename\n"
      << "  " << oldname << "\n"
      << "to\n"
      << "  " << newname << "\n"
      << "because: " << err << "\n";
    this->SetError(e.str().c_str());
    return false;
    }
  return true;
}


//----------------------------------------------------------------------------
bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
                                 bool recurse)
{

  std::string message;
  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand
  for(;i != args.end(); ++i)
    {
    std::string fileName = *i;
    if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
      {
      fileName = this->Makefile->GetCurrentDirectory();
      fileName += "/" + *i;
      }

    if(cmSystemTools::FileIsDirectory(fileName.c_str()) &&
       !cmSystemTools::FileIsSymlink(fileName.c_str()) && recurse)
      {
      cmSystemTools::RemoveADirectory(fileName.c_str());
      }
    else
      {
      cmSystemTools::RemoveFile(fileName.c_str());
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string>
                                           const& args,
                                           bool nativePath)
{
  std::vector<std::string>::const_iterator i = args.begin();
  if(args.size() != 3)
    {
    this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
      "called with exactly three arguments.");
    return false;
    }
  i++; // Get rid of subcommand
#if defined(_WIN32) && !defined(__CYGWIN__)
  char pathSep = ';';
#else
  char pathSep = ':';
#endif
  std::vector<cmsys::String> path = cmSystemTools::SplitString(i->c_str(),
                                                             pathSep);
  i++;
  const char* var =  i->c_str();
  std::string value;
  for(std::vector<cmsys::String>::iterator j = path.begin();
      j != path.end(); ++j)
    {
    if(j != path.begin())
      {
      value += ";";
      }
    if(!nativePath)
      {
      cmSystemTools::ConvertToUnixSlashes(*j);
      }
    else
      {
      *j = cmSystemTools::ConvertToOutputPath(j->c_str());
      // remove double quotes in the path
      cmsys::String& s = *j;

      if(s.size() > 1 && s[0] == '\"' && s[s.size()-1] == '\"')
        {
        s = s.substr(1,s.size()-2);
        }
      }
    value += *j;
    }
  this->Makefile->AddDefinition(var, value.c_str());
  return true;
}


#if defined(CMAKE_BUILD_WITH_CMAKE)

// Stuff for curl download/upload
typedef std::vector<char> cmFileCommandVectorOfChar;

namespace {

  size_t
  cmWriteToFileCallback(void *ptr, size_t size, size_t nmemb,
                        void *data)
    {
    int realsize = (int)(size * nmemb);
    std::ofstream* fout = static_cast<std::ofstream*>(data);
    const char* chPtr = static_cast<char*>(ptr);
    fout->write(chPtr, realsize);
    return realsize;
    }


  size_t
  cmWriteToMemoryCallback(void *ptr, size_t size, size_t nmemb,
                          void *data)
    {
    int realsize = (int)(size * nmemb);
    cmFileCommandVectorOfChar *vec
      = static_cast<cmFileCommandVectorOfChar*>(data);
    const char* chPtr = static_cast<char*>(ptr);
    vec->insert(vec->end(), chPtr, chPtr + realsize);
    return realsize;
    }


  static size_t
  cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
                                 size_t size, void *data)
    {
    cmFileCommandVectorOfChar *vec
      = static_cast<cmFileCommandVectorOfChar*>(data);
    vec->insert(vec->end(), chPtr, chPtr + size);
    return size;
    }


  class cURLProgressHelper
  {
  public:
    cURLProgressHelper(cmFileCommand *fc, const char *text)
      {
      this->CurrentPercentage = -1;
      this->FileCommand = fc;
      this->Text = text;
      }

    bool UpdatePercentage(double value, double total, std::string &status)
      {
      int OldPercentage = this->CurrentPercentage;

      if (total > 0.0)
        {
        this->CurrentPercentage = static_cast<int>(value/total*100.0 + 0.5);
        }

      bool updated = (OldPercentage != this->CurrentPercentage);

      if (updated)
        {
        cmOStringStream oss;
        oss << "[" << this->Text << " " << this->CurrentPercentage
            << "% complete]";
        status = oss.str();
        }

      return updated;
      }

    cmFileCommand *GetFileCommand()
      {
      return this->FileCommand;
      }

  private:
    int CurrentPercentage;
    cmFileCommand *FileCommand;
    std::string Text;
  };


  static int
  cmFileDownloadProgressCallback(void *clientp,
                                 double dltotal, double dlnow,
                                 double ultotal, double ulnow)
    {
    cURLProgressHelper *helper =
      reinterpret_cast<cURLProgressHelper *>(clientp);

    static_cast<void>(ultotal);
    static_cast<void>(ulnow);

    std::string status;
    if (helper->UpdatePercentage(dlnow, dltotal, status))
      {
      cmFileCommand *fc = helper->GetFileCommand();
      cmMakefile *mf = fc->GetMakefile();
      mf->DisplayStatus(status.c_str(), -1);
      }

    return 0;
    }


  static int
  cmFileUploadProgressCallback(void *clientp,
                               double dltotal, double dlnow,
                               double ultotal, double ulnow)
    {
    cURLProgressHelper *helper =
    reinterpret_cast<cURLProgressHelper *>(clientp);

    static_cast<void>(dltotal);
    static_cast<void>(dlnow);

    std::string status;
    if (helper->UpdatePercentage(ulnow, ultotal, status))
      {
      cmFileCommand *fc = helper->GetFileCommand();
      cmMakefile *mf = fc->GetMakefile();
      mf->DisplayStatus(status.c_str(), -1);
      }

    return 0;
    }
}


namespace {

  class cURLEasyGuard
  {
  public:
    cURLEasyGuard(CURL * easy)
      : Easy(easy)
      {}

    ~cURLEasyGuard(void)
      {
        if (this->Easy)
          {
          ::curl_easy_cleanup(this->Easy);
          }
      }

    inline void release(void)
      {
        this->Easy = 0;
        return;
      }

  private:
    ::CURL * Easy;
  };

}
#endif


#define check_curl_result(result, errstr) \
  if (result != CURLE_OK)                 \
    {                                     \
    std::string e(errstr);                \
    e += ::curl_easy_strerror(result);    \
    this->SetError(e.c_str());            \
    return false;                         \
    }


bool
cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
  std::vector<std::string>::const_iterator i = args.begin();
  if(args.size() < 3)
    {
    this->SetError("DOWNLOAD must be called with at least three arguments.");
    return false;
    }
  ++i; // Get rid of subcommand
  std::string url = *i;
  ++i;
  std::string file = *i;
  ++i;

  long timeout = 0;
  long inactivity_timeout = 0;
  std::string verboseLog;
  std::string statusVar;
  bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
  const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
  std::string expectedHash;
  std::string hashMatchMSG;
  cmsys::auto_ptr<cmCryptoHash> hash;
  bool showProgress = false;

  while(i != args.end())
    {
    if(*i == "TIMEOUT")
      {
      ++i;
      if(i != args.end())
        {
        timeout = atol(i->c_str());
        }
      else
        {
        this->SetError("DOWNLOAD missing time for TIMEOUT.");
        return false;
        }
      }
    else if(*i == "INACTIVITY_TIMEOUT")
      {
      ++i;
      if(i != args.end())
        {
        inactivity_timeout = atol(i->c_str());
        }
      else
        {
        this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
        return false;
        }
      }
    else if(*i == "LOG")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("DOWNLOAD missing VAR for LOG.");
        return false;
        }
      verboseLog = *i;
      }
    else if(*i == "STATUS")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("DOWNLOAD missing VAR for STATUS.");
        return false;
        }
      statusVar = *i;
      }
    else if(*i == "TLS_VERIFY")
      {
      ++i;
      if(i != args.end())
        {
        tls_verify = cmSystemTools::IsOn(i->c_str());
        }
      else
        {
        this->SetError("TLS_VERIFY missing bool value.");
        return false;
        }
      }
    else if(*i == "TLS_CAINFO")
      {
      ++i;
      if(i != args.end())
        {
        cainfo = i->c_str();
        }
      else
        {
        this->SetError("TLS_CAFILE missing file value.");
        return false;
        }
      }
    else if(*i == "EXPECTED_MD5")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
        return false;
        }
      hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New("MD5"));
      hashMatchMSG = "MD5 sum";
      expectedHash = cmSystemTools::LowerCase(*i);
      }
    else if(*i == "SHOW_PROGRESS")
      {
      showProgress = true;
      }
    else if(*i == "EXPECTED_HASH")
      {
      ++i;
      if(i == args.end())
        {
        this->SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
        return false;
        }
      std::string::size_type pos = i->find("=");
      if(pos == std::string::npos)
        {
        std::string err =
          "DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ";
        err += *i;
        this->SetError(err.c_str());
        return false;
        }
      std::string algo = i->substr(0, pos);
      expectedHash = cmSystemTools::LowerCase(i->substr(pos+1));
      hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New(algo.c_str()));
      if(!hash.get())
        {
        std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: ";
        err += algo;
        this->SetError(err.c_str());
        return false;
        }
      hashMatchMSG = algo + " hash";
      }
    ++i;
    }
  // If file exists already, and caller specified an expected md5 or sha,
  // and the existing file already has the expected hash, then simply
  // return.
  //
  if(cmSystemTools::FileExists(file.c_str()) && hash.get())
    {
    std::string msg;
    std::string actualHash = hash->HashFile(file.c_str());
    if(actualHash == expectedHash)
      {
      msg = "returning early; file already exists with expected ";
      msg += hashMatchMSG;
      msg += "\"";
      if(statusVar.size())
        {
        cmOStringStream result;
        result << (int)0 << ";\"" << msg;
        this->Makefile->AddDefinition(statusVar.c_str(),
                                      result.str().c_str());
        }
      return true;
      }
    }
  // Make sure parent directory exists so we can write to the file
  // as we receive downloaded bits from curl...
  //
  std::string dir = cmSystemTools::GetFilenamePath(file.c_str());
  if(!cmSystemTools::FileExists(dir.c_str()) &&
     !cmSystemTools::MakeDirectory(dir.c_str()))
    {
    std::string errstring = "DOWNLOAD error: cannot create directory '"
      + dir + "' - Specify file by full path name and verify that you "
      "have directory creation and file write privileges.";
    this->SetError(errstring.c_str());
    return false;
    }

  std::ofstream fout(file.c_str(), std::ios::binary);
  if(!fout)
    {
    this->SetError("DOWNLOAD cannot open file for write.");
    return false;
    }

  ::CURL *curl;
  ::curl_global_init(CURL_GLOBAL_DEFAULT);
  curl = ::curl_easy_init();
  if(!curl)
    {
    this->SetError("DOWNLOAD error initializing curl.");
    return false;
    }

  cURLEasyGuard g_curl(curl);
  ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  check_curl_result(res, "DOWNLOAD cannot set url: ");

  // enable HTTP ERROR parsing
  res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
  check_curl_result(res, "DOWNLOAD cannot set http failure option: ");

  res = ::curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/" LIBCURL_VERSION);
  check_curl_result(res, "DOWNLOAD cannot set user agent option: ");

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
                           cmWriteToFileCallback);
  check_curl_result(res, "DOWNLOAD cannot set write function: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
                           cmFileCommandCurlDebugCallback);
  check_curl_result(res, "DOWNLOAD cannot set debug function: ");

  // check to see if TLS verification is requested
  if(tls_verify)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
    check_curl_result(res, "Unable to set TLS/SSL Verify on: ");
    }
  else
    {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    check_curl_result(res, "Unable to set TLS/SSL Verify off: ");
    }
  // check to see if a CAINFO file has been specified
  // command arg comes first
  if(cainfo && *cainfo)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo);
    check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
    }

  cmFileCommandVectorOfChar chunkDebug;

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout);
  check_curl_result(res, "DOWNLOAD cannot set write data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  check_curl_result(res, "DOWNLOAD cannot set debug data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: ");

  if(verboseLog.size())
    {
    res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
    check_curl_result(res, "DOWNLOAD cannot set verbose: ");
    }

  if(timeout > 0)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout );
    check_curl_result(res, "DOWNLOAD cannot set timeout: ");
    }

  if(inactivity_timeout > 0)
    {
    // Give up if there is no progress for a long time.
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
    }

  // Need the progress helper's scope to last through the duration of
  // the curl_easy_perform call... so this object is declared at function
  // scope intentionally, rather than inside the "if(showProgress)"
  // block...
  //
  cURLProgressHelper helper(this, "download");

  if(showProgress)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    check_curl_result(res, "DOWNLOAD cannot set noprogress value: ");

    res = ::curl_easy_setopt(curl,
      CURLOPT_PROGRESSFUNCTION, cmFileDownloadProgressCallback);
    check_curl_result(res, "DOWNLOAD cannot set progress function: ");

    res = ::curl_easy_setopt(curl,
      CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper));
    check_curl_result(res, "DOWNLOAD cannot set progress data: ");
    }

  res = ::curl_easy_perform(curl);

  /* always cleanup */
  g_curl.release();
  ::curl_easy_cleanup(curl);

  if(statusVar.size())
    {
    cmOStringStream result;
    result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
    this->Makefile->AddDefinition(statusVar.c_str(),
                                  result.str().c_str());
    }

  ::curl_global_cleanup();

  // Explicitly flush/close so we can measure the md5 accurately.
  //
  fout.flush();
  fout.close();

  // Verify MD5 sum if requested:
  //
  if (hash.get())
    {
    std::string actualHash = hash->HashFile(file.c_str());
    if (actualHash.size() == 0)
      {
      this->SetError("DOWNLOAD cannot compute hash on downloaded file");
      return false;
      }

    if (expectedHash != actualHash)
      {
      cmOStringStream oss;
      oss << "DOWNLOAD HASH mismatch" << std::endl
        << "  for file: [" << file << "]" << std::endl
        << "    expected hash: [" << expectedHash << "]" << std::endl
        << "      actual hash: [" << actualHash << "]" << std::endl
        ;
      this->SetError(oss.str().c_str());
      return false;
      }
    }

  if(chunkDebug.size())
    {
    chunkDebug.push_back(0);
    if(CURLE_OPERATION_TIMEOUTED == res)
      {
      std::string output = &*chunkDebug.begin();

      if(verboseLog.size())
        {
        this->Makefile->AddDefinition(verboseLog.c_str(),
                                      &*chunkDebug.begin());
        }
      }

    this->Makefile->AddDefinition(verboseLog.c_str(),
                                  &*chunkDebug.begin());
    }

  return true;
#else
  this->SetError("DOWNLOAD not supported by bootstrap cmake.");
  return false;
#endif
}


bool
cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
  if(args.size() < 3)
    {
    this->SetError("UPLOAD must be called with at least three arguments.");
    return false;
    }
  std::vector<std::string>::const_iterator i = args.begin();
  ++i;
  std::string filename = *i;
  ++i;
  std::string url = *i;
  ++i;

  long timeout = 0;
  long inactivity_timeout = 0;
  std::string logVar;
  std::string statusVar;
  bool showProgress = false;

  while(i != args.end())
    {
    if(*i == "TIMEOUT")
      {
      ++i;
      if(i != args.end())
        {
        timeout = atol(i->c_str());
        }
      else
        {
        this->SetError("UPLOAD missing time for TIMEOUT.");
        return false;
        }
      }
    else if(*i == "INACTIVITY_TIMEOUT")
      {
      ++i;
      if(i != args.end())
        {
        inactivity_timeout = atol(i->c_str());
        }
      else
        {
        this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
        return false;
        }
      }
    else if(*i == "LOG")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("UPLOAD missing VAR for LOG.");
        return false;
        }
      logVar = *i;
      }
    else if(*i == "STATUS")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("UPLOAD missing VAR for STATUS.");
        return false;
        }
      statusVar = *i;
      }
    else if(*i == "SHOW_PROGRESS")
      {
      showProgress = true;
      }

    ++i;
    }

  // Open file for reading:
  //
  FILE *fin = fopen(filename.c_str(), "rb");
  if(!fin)
    {
    std::string errStr = "UPLOAD cannot open file '";
    errStr += filename + "' for reading.";
    this->SetError(errStr.c_str());
    return false;
    }

  struct stat st;
  if(::stat(filename.c_str(), &st))
    {
    std::string errStr = "UPLOAD cannot stat file '";
    errStr += filename + "'.";
    this->SetError(errStr.c_str());
    fclose(fin);
    return false;
    }

  ::CURL *curl;
  ::curl_global_init(CURL_GLOBAL_DEFAULT);
  curl = ::curl_easy_init();
  if(!curl)
    {
    this->SetError("UPLOAD error initializing curl.");
    fclose(fin);
    return false;
    }

  cURLEasyGuard g_curl(curl);

  // enable HTTP ERROR parsing
  ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);

  // enable uploading
  res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
  check_curl_result(res, "UPLOAD cannot set upload flag: ");

  res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  check_curl_result(res, "UPLOAD cannot set url: ");

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
                           cmWriteToMemoryCallback);
  check_curl_result(res, "UPLOAD cannot set write function: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
                           cmFileCommandCurlDebugCallback);
  check_curl_result(res, "UPLOAD cannot set debug function: ");

  cmFileCommandVectorOfChar chunkResponse;
  cmFileCommandVectorOfChar chunkDebug;

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunkResponse);
  check_curl_result(res, "UPLOAD cannot set write data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  check_curl_result(res, "UPLOAD cannot set debug data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  check_curl_result(res, "UPLOAD cannot set follow-redirect option: ");

  if(logVar.size())
    {
    res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
    check_curl_result(res, "UPLOAD cannot set verbose: ");
    }

  if(timeout > 0)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout );
    check_curl_result(res, "UPLOAD cannot set timeout: ");
    }

  if(inactivity_timeout > 0)
    {
    // Give up if there is no progress for a long time.
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
    }

  // Need the progress helper's scope to last through the duration of
  // the curl_easy_perform call... so this object is declared at function
  // scope intentionally, rather than inside the "if(showProgress)"
  // block...
  //
  cURLProgressHelper helper(this, "upload");

  if(showProgress)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    check_curl_result(res, "UPLOAD cannot set noprogress value: ");

    res = ::curl_easy_setopt(curl,
      CURLOPT_PROGRESSFUNCTION, cmFileUploadProgressCallback);
    check_curl_result(res, "UPLOAD cannot set progress function: ");

    res = ::curl_easy_setopt(curl,
      CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper));
    check_curl_result(res, "UPLOAD cannot set progress data: ");
    }

  // now specify which file to upload
  res = ::curl_easy_setopt(curl, CURLOPT_INFILE, fin);
  check_curl_result(res, "UPLOAD cannot set input file: ");

  // and give the size of the upload (optional)
  res = ::curl_easy_setopt(curl,
    CURLOPT_INFILESIZE, static_cast<long>(st.st_size));
  check_curl_result(res, "UPLOAD cannot set input file size: ");

  res = ::curl_easy_perform(curl);

  /* always cleanup */
  g_curl.release();
  ::curl_easy_cleanup(curl);

  if(statusVar.size())
    {
    cmOStringStream result;
    result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
    this->Makefile->AddDefinition(statusVar.c_str(),
                                  result.str().c_str());
    }

  ::curl_global_cleanup();

  fclose(fin);
  fin = NULL;

  if(logVar.size())
    {
    std::string log;

    if(chunkResponse.size())
      {
      chunkResponse.push_back(0);
      log += "Response:\n";
      log += &*chunkResponse.begin();
      log += "\n";
      }

    if(chunkDebug.size())
      {
      chunkDebug.push_back(0);
      log += "Debug:\n";
      log += &*chunkDebug.begin();
      log += "\n";
      }

    this->Makefile->AddDefinition(logVar.c_str(), log.c_str());
    }

  return true;
#else
  this->SetError("UPLOAD not supported by bootstrap cmake.");
  return false;
#endif
}

//----------------------------------------------------------------------------
void cmFileCommand::AddEvaluationFile(const std::string &inputName,
                                      const std::string &outputExpr,
                                      const std::string &condition,
                                      bool inputIsContent
                                     )
{
  cmListFileBacktrace lfbt;
  this->Makefile->GetBacktrace(lfbt);

  cmGeneratorExpression outputGe(lfbt);
  cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge
                                                = outputGe.Parse(outputExpr);

  cmGeneratorExpression conditionGe(lfbt);
  cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge
                                              = conditionGe.Parse(condition);

  this->Makefile->GetLocalGenerator()
                ->GetGlobalGenerator()->AddEvaluationFile(inputName,
                                                          outputCge,
                                                          this->Makefile,
                                                          conditionCge,
                                                          inputIsContent);
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleGenerateCommand(
  std::vector<std::string> const& args)
{
  if (args.size() < 5)
    {
    this->SetError("Incorrect arguments to GENERATE subcommand.");
    return false;
    }
  if (args[1] != "OUTPUT")
    {
    this->SetError("Incorrect arguments to GENERATE subcommand.");
    return false;
    }
  std::string condition;
  if (args.size() > 5)
    {
    if (args[5] != "CONDITION")
      {
      this->SetError("Incorrect arguments to GENERATE subcommand.");
      return false;
      }
    if (args.size() != 7)
      {
      this->SetError("Incorrect arguments to GENERATE subcommand.");
      return false;
      }
    condition = args[6];
    if (condition.empty())
      {
      this->SetError("CONDITION of sub-command GENERATE must not be empty if "
        "specified.");
      return false;
      }
    }
  std::string output = args[2];
  const bool inputIsContent = args[3] != "INPUT";
  if (inputIsContent && args[3] != "CONTENT")
    {
    this->SetError("Incorrect arguments to GENERATE subcommand.");
    return false;
    }
  std::string input = args[4];

  this->AddEvaluationFile(input, output, condition, inputIsContent);
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleTimestampCommand(
  std::vector<std::string> const& args)
{
  if(args.size() < 3)
    {
    this->SetError("sub-command TIMESTAMP requires at least two arguments.");
    return false;
    }
  else if(args.size() > 5)
    {
    this->SetError("sub-command TIMESTAMP takes at most four arguments.");
    return false;
    }

  unsigned int argsIndex = 1;

  const std::string& filename = args[argsIndex++];

  const std::string& outputVariable = args[argsIndex++];

  std::string formatString;
  if(args.size() > argsIndex && args[argsIndex] != "UTC")
    {
    formatString = args[argsIndex++];
    }

  bool utcFlag = false;
  if(args.size() > argsIndex)
    {
    if(args[argsIndex] == "UTC")
      {
      utcFlag = true;
      }
    else
      {
      std::string e = " TIMESTAMP sub-command does not recognize option " +
          args[argsIndex] + ".";
      this->SetError(e.c_str());
      return false;
      }
    }

  cmTimestamp timestamp;
  std::string result = timestamp.FileModificationTime(
    filename.c_str(), formatString, utcFlag);
  this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());

  return true;
}
