/*============================================================================
  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>
#include <cmsys/FStream.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);
  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);
    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
  cmsys::ofstream file(fileName.c_str(), append?std::ios::app: std::ios::out);
  if ( !file )
    {
    std::string error = "failed to open for writing (";
    error += cmSystemTools::GetLastSystemError();
    error += "):\n  ";
    error += fileName;
    this->SetError(error);
    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__)
  cmsys::ifstream file(fileName.c_str(), std::ios::in |
               (hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in));
#else
  cmsys::ifstream file(fileName.c_str(), std::ios::in);
#endif

  if ( !file )
    {
    std::string error = "failed to open for reading (";
    error += cmSystemTools::GetLastSystemError();
    error += "):\n  ";
    error += fileName;
    this->SetError(error);
    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, 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());
    return false;
    }

  cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
  if(hash.get())
    {
    std::string out = hash->HashFile(args[1]);
    if(!out.empty())
      {
      this->Makefile->AddDefinition(args[2], out.c_str());
      return true;
      }
    cmOStringStream e;
    e << args[0] << " failed to read file \"" << args[1] << "\": "
      << cmSystemTools::GetLastSystemError();
    this->SetError(e.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,
         arg_encoding };
  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;
  bool utf8_encoding = false;
  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(args[i] == "ENCODING")
      {
      arg_mode = arg_encoding;
      }
    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());
        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());
        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());
        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());
        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());
        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());
        return false;
        }
      have_regex = true;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_encoding)
      {
      if(args[i] == "UTF-8")
        {
        utf8_encoding = true;
        }
      else
        {
        cmOStringStream e;
        e << "STRINGS option ENCODING \""
          << args[i] << "\" not recognized.";
        this->SetError(e.str());
        return false;
        }
      arg_mode = arg_none;
      }
    else
      {
      cmOStringStream e;
      e << "STRINGS given unknown argument \""
        << args[i] << "\"";
      this->SetError(e.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__)
  cmsys::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
#else
  cmsys::ifstream fin(fileName.c_str(), std::ios::in);
#endif
  if(!fin)
    {
    cmOStringStream e;
    e << "STRINGS file \"" << fileName << "\" cannot be read.";
    this->SetError(e.str());
    return false;
    }

  // Parse strings out of the file.
  int output_size = 0;
  std::vector<std::string> strings;
  std::string s;
  while((!limit_count || strings.size() < limit_count) &&
        (limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
        fin)
    {
    std::string current_str;

    int c = fin.get();

    if(c == '\r')
      {
      // Ignore CR character to make output always have UNIX newlines.
      continue;
      }

    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...
      current_str += static_cast<char>(c);
      }
    else if(utf8_encoding)
      {
      // Check for UTF-8 encoded string (up to 4 octets)
      static const unsigned char utf8_check_table[3][2] =
        {
          {0xE0, 0xC0},
          {0xF0, 0xE0},
          {0xF8, 0xF0},
        };

      // how many octets are there?
      unsigned int num_utf8_bytes = 0;
      for(unsigned int j=0; num_utf8_bytes == 0 && j<3; j++)
        {
        if((c & utf8_check_table[j][0]) == utf8_check_table[j][1])
          num_utf8_bytes = j+2;
        }

      // get subsequent octets and check that they are valid
      for(unsigned int j=0; j<num_utf8_bytes; j++)
        {
        if(j != 0)
          {
          c = fin.get();
          if(!fin || (c & 0xC0) != 0x80)
            {
            fin.putback(static_cast<char>(c));
            break;
            }
          }
        current_str += static_cast<char>(c);
        }

      // if this was an invalid utf8 sequence, discard the data, and put
      // back subsequent characters
      if((current_str.length() != num_utf8_bytes))
        {
        for(unsigned int j=0; j<current_str.size()-1; j++)
          {
          c = current_str[current_str.size() - 1 - j];
          fin.putback(static_cast<char>(c));
          }
        current_str = "";
        }
      }


    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(current_str.empty())
      {
      // 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 = "";
      }
    else
      {
      s += current_str;
      }


    if(maxlen > 0 && s.size() == maxlen)
      {
      // Terminate a string if the maximum length is reached.
      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, 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, 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);
      cmSystemTools::SetFatalErrorOccured();
      return false;
      }
    if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
      {
      std::string error = "problem creating directory: " + *cdir;
      this->SetError(error);
      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());
      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());
      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());
      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());
    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());
    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());
    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());
      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());
    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());
        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());
        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());
    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());
    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());
      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());
    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());
      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,
                   !cmSystemTools::FileIsDirectory(destination));

  // 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());
    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),
    MessageAlways(false),
    MessageLazy(false),
    MessageNever(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;
  bool MessageAlways;
  bool MessageLazy;
  bool MessageNever;
  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)
    {
    if(!this->MessageNever && (copy || !this->MessageLazy))
      {
      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;
    }

  if(((this->MessageAlways?1:0) +
      (this->MessageLazy?1:0) +
      (this->MessageNever?1:0)) > 1)
    {
    this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
                                "MESSAGE_LAZY, and MESSAGE_NEVER "
                                "are mutually exclusive.");
    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 == "MESSAGE_ALWAYS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->MessageAlways = true;
      }
    }
  else if(arg == "MESSAGE_LAZY")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->MessageLazy = true;
      }
    }
  else if(arg == "MESSAGE_NEVER")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->MessageNever = 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());
    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());
    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);
        return false;
        }
      }
    destination = sdestdir + (destination.c_str() + skip);
    this->DestDirLength = int(sdestdir.size());
    }

  if(this->InstallType != cmInstallType_DIRECTORY)
    {
    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);
        return false;
        }
      }
    if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
      {
      std::string errstring = "INSTALL destination: " + destination +
        " is not a directory.";
      this->FileCommand->SetError(errstring);
      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());
      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());
    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());
    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());
      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());
    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());
    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());
      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);
    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);
    return false;
    }

  std::string res = cmSystemTools::RelativePath(directoryName.c_str(),
                                                fileName.c_str());
  this->Makefile->AddDefinition(outVar,
    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());
    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);
    cmsys::ofstream* fout = static_cast<cmsys::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);
        if(this->CurrentPercentage > 100)
          {
          // Avoid extra progress reports for unexpected data beyond total.
          this->CurrentPercentage = 100;
          }
        }

      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);            \
    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);
        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);
        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);
    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,
                                      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);
  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);
    return false;
    }

  cmsys::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,
                                  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);
    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
        << "           status: [" << (int)res << ";\""
          << ::curl_easy_strerror(res) << "\"]" << std::endl
        ;
      this->SetError(oss.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,
                                      &*chunkDebug.begin());
        }
      }

    this->Makefile->AddDefinition(verboseLog,
                                  &*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 = cmsys::SystemTools::Fopen(filename.c_str(), "rb");
  if(!fin)
    {
    std::string errStr = "UPLOAD cannot open file '";
    errStr += filename + "' for reading.";
    this->SetError(errStr);
    return false;
    }

  unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str());

  ::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>(file_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,
                                  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, 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();

  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);
      return false;
      }
    }

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

  return true;
}
