Ejemplo n.º 1
0
//------------------------------------------------------------------------------
void DirectoryComparer::copy () {
   // variables
   FileCopier copier(safe_mode);
   FileVector& f0 = _uc[0].f;    // for convenience
   vector<path>& d0 = _uc[0].d;  // for convenience
   path fullpath0;               // convenience (updated in loops)
   path fullpath1;               // convenience (updated in loops)
   FileVector errors;            // holds files that we fail to copy
   
   // precompute total number of files and bytes to be transferred
   annotate0();

   // prepare batch, print totals
   unsigned totalFiles = _uc[0].files();
   FileSize totalBytes = _uc[0].bytes();
   copier.startBatch(totalFiles, totalBytes);
   cout << "========== Copying Files from A to B ==========\n";
   cout << "Copying " << totalFiles  << " files totaling " << totalBytes
        << " from " << workingPath(0) << " to " << workingPath(1) << ".\n";
   cout << "  Bytes Processed   |   Current File\n";

   // copy files from _uc[0].f
   for (unsigned i=0; i<f0.size(); ++i) {
      fullpath0 = groundPath(f0[i], 0);
      fullpath1 = groundPath(f0[i], 1);
      if (exists(fullpath1)) {
         // error!
         errors.push_back(f0[i], fullpath0);
         cout << "Warning: Cannot copy " << fullpath0 << " to " << fullpath1 << " because the latter already exists.\n";
      } else {
         copier.copy(fullpath0, fullpath1, f0[i]);
      }
   }

   // copy files from _uc[0].d
   recursive_directory_iterator end;
   unsigned depth = 0;
   path connector;
   path new_extension;
   for (unsigned i=0; i<d0.size(); ++i) {
      // initialize for recursive crawl of this directory
      recursive_directory_iterator itr(groundPath(d0[i], 0));
      depth = 0;
      connector = d0[i];
      cout << copier.status << "Creating directory " << connector << '.' << '\n';
      if (!safe_mode) create_directory(_p[1] / connector);

      while (itr != end) {
         // update connector
         if (depth < itr.level()) {
            connector /= new_extension;
            cout << copier.status << "Creating directory " << connector << '.' << '\n';
            if (!safe_mode) create_directory(_p[1] / connector);
            ++depth;  // this makes depth equal to itr.level()
         } else while (depth > itr.level()) {
            connector.remove_filename();
            --depth;
         }

         // copy file or save name of directory we may iterate into
         if (is_regular_file(itr->path())) {
            fullpath0 = itr->path();
            fullpath1 = _p[1] / connector / fullpath0.filename();
            if (exists(fullpath1)) {
               // error!
               errors.push_back(connector / fullpath0.filename(), fullpath0);
               cout << copier.status << "Warning: Cannot copy " << fullpath0 << " to " << fullpath1 << " because the latter already exists.\n";
            } else {
               copier.copy(fullpath0, fullpath1, connector / fullpath0.filename());
            }
         } else if (is_directory(itr->path())) {
            new_extension = itr->path().filename();
         }
         ++itr;
      }
   }

   // cleanup
   _uc[0].f.clear();
   _uc[0].d.clear();
   _annotations &= ~A0;

   // print outline
   cout << setw(9) << totalBytes << '/' << setw(9) << totalBytes << " | ";
   cout << totalFiles - errors.size() << " of " << totalFiles << " files were copied.\n";
   if (errors.size()) {
      cout << "The following files were not copied:\n";
      for (unsigned i=0; i<errors.size(); ++i) {
         cout << errors[i] << '\n';
      }
   }
   cout << '\n';
}
Ejemplo n.º 2
0
KLUPD::CoreError KLUPD::UpdateInfo::parse(const Path &path,
                                          FileInfo &fileInfo,
                                          const ChangeStateCheck &changeStateCheck,
                                          const FileVector &localFilesToCheckAgainst,
                                          const bool suppressSuccessLogMessages)
{
    // index is already parsed, files already attached
    if(fileAlreadyParsed(fileInfo))
        return CORE_NO_ERROR;

    const Path fullFileName = path + fileInfo.m_filename;

    if(!suppressSuccessLogMessages)
        TRACE_MESSAGE2("Parsing XML index file '%S'", fullFileName.toWideChar());

    std::vector<unsigned char> buffer;
    const CoreError readFileResult = LocalFile(fullFileName, pLog).read(buffer);
    if(!KLUPD::isSuccess(readFileResult))
    {
        TRACE_MESSAGE3("Failed to read XML index file '%S', result '%S'",
            fullFileName.toWideChar(), KLUPD::toString(readFileResult).toWideChar());
        return readFileResult;
    }
    if(buffer.empty())
    {
        TRACE_MESSAGE3("Index XML file '%S' is corrupted, file size is %d", fullFileName.toWideChar(), buffer.size());
        return CORE_UPDATE_DESCRIPTION_DAMAGED;
    }

    // a file list obtained from XML
    FileVector fileList;
    IndexFileXMLParser xmler(fileInfo.m_filename.m_value, fileList, m_signature6Checker, fileInfo.m_relativeURLPath, m_retranslationMode, m_callbacks, pLog);

    XmlReader xmlReader(reinterpret_cast<const char *>(&buffer[0]), buffer.size());
    if(!xmler.parseXMLRecursively(xmlReader, 0)
        || fileList.empty())
    {
        TRACE_MESSAGE3("\tXML file parse error '%S', file number found %d",
            fullFileName.toWideChar(), fileList.size());
        return CORE_UPDATE_DESCRIPTION_DAMAGED;
    }
    m_parsedIndexCache.push_back(fileInfo);

    xmler.GetUpdateDate(fileInfo.m_strUpdateDate);
    xmler.GetBlackDate(fileInfo.m_strBlackDate);

    // save variables to write into settings storage
    std::vector<UpdatedSettings> updatedSettings = xmler.updatedSettings();
    m_updatedSettings.insert(m_updatedSettings.end(), updatedSettings.begin(), updatedSettings.end());

    // copy to match list only those items which suits download criteria
    for(FileVector::iterator fileIter = fileList.begin(); fileIter != fileList.end(); ++fileIter)
    {
        // check download filters criteria should be performed
        NoCaseString reasonNotMatch;
        if(!matchesSettings(reasonNotMatch, *fileIter))
        {
            if(!suppressSuccessLogMessages)
            {
                TRACE_MESSAGE3("\tFile filtered, download criteria does not matches: '%S', %S",
                    reasonNotMatch.toWideChar(), fileIter->toString().toWideChar());
            }
            continue;
        }

        // check download mandatory criteria
        reasonNotMatch.erase();
        if(!isEntryRequired(reasonNotMatch, *fileIter, m_filterFlags))
        {
            if(!suppressSuccessLogMessages)
            {
                TRACE_MESSAGE3("\tFile filtered, mandatory criteria does not matches: '%S', %S",
                    reasonNotMatch.toWideChar(), fileIter->toString().toWideChar());
            }
            continue;
        }

        // setup transaction folders
        fileIter->m_transactionInformation.m_currentLocation = m_callbacks.productFolder(*fileIter, m_retranslationMode);
        fileIter->m_transactionInformation.m_newLocation = m_callbacks.temporaryFolder(*fileIter);
        NoCaseString statusExplanations;
        fileIter->m_transactionInformation.m_changeStatus = getFileStatusAgainstLocal(*fileIter,
            changeStateCheck, localFilesToCheckAgainst, statusExplanations);

        // insert file with filtering duplicates
        bool fileDuplicate = false;

        // insert black list into the beginning of list, because it should be checked before downloading other bases
        if(fileIter->m_type == FileInfo::blackList)
            m_matchFileList.insertNewInTheBeginOfListOrUpdateTheSame(*fileIter, *fileIter, fileDuplicate, m_retranslationMode);
        else
            m_matchFileList.insertNewOrUpdateTheSame(*fileIter, *fileIter, fileDuplicate, m_retranslationMode);


        if(!suppressSuccessLogMessages)
        {
            // to avoid empty brackets output to trace
            if(!statusExplanations.empty())
                statusExplanations = NoCaseString(L"(") + statusExplanations + L")";

            if(fileDuplicate)
            {
                TRACE_MESSAGE3("\tDuplicate file information updated: %S %S",
                    fileIter->toString().toWideChar(), statusExplanations.toWideChar());
            }
            else
            {
                TRACE_MESSAGE3("\tFile matches download criteria: %S %S",
                    fileIter->toString().toWideChar(), statusExplanations.toWideChar());
            }
        }
    }

    return CORE_NO_ERROR;
}