//******************************************************************* // join_dirs PRIVATE //******************************************************************* void QBtCompareDirsDialog::join_dirs( AllItems& out_set, const DirMap& in_map ) const { if( in_map.empty() ) return; DirMap::const_iterator it = in_map.begin(); const DirMap::const_iterator end = in_map.end(); while( continue_ && ( it != end ) ) { out_set.insert( it.key(), QString() ); ++it; } }
//******************************************************************* // read_dir PRIVATE //------------------------------------------------------------------- // Rekursywne odczytywanie calej zawartosci wskazanego katalogu. // Odczytana zawrtosc katalogu jest zapamietywania w hash-tablicy. //******************************************************************* void QBtCompareDirsDialog::read_dir( const QString& in_parent, const QString& in_dir, DirMap& out_data ) const { static const int sflag = QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::Writable | QDir::Hidden; const QDir dir( in_dir, "*", QDir::Unsorted, QFlags<QDir::Filter>( sflag ) ); const QFileInfoList items = dir.entryInfoList(); FileMap files_map = FileMap(); QFileInfoList::const_iterator it = items.begin(); const QFileInfoList::const_iterator end = items.end(); while( continue_ && ( it != end ) ) { if( it->isDir() ) read_dir( in_parent, it->absoluteFilePath(), out_data ); else files_map.insert( it->fileName(), *it ); ++it; } QString path = in_dir; out_data.insert( path.remove( in_parent ), files_map ); }
void DirInstaller::sortAddDel(HashDir &add, HashDir &del, DirMap &upgrade) { add.clear(); del.clear(); upgrade.clear(); // 'post' lists files we are creating for(DirMap::const_iterator it = post.begin(); it != post.end(); it++) { const std::string &file = it->first; const std::string &full = prefix + file; const Hash &hash = it->second; assert(file != ""); assert(hash.isSet()); // Is there a matching file in the 'pre' directory? if(pre.find(file) != pre.end()) { const Hash &pHash = pre[file]; assert(pHash.isSet()); // Do the hashes match? if(hash == pHash) /* Then this file is not to be upgraded. Ignore it completely (since it may contain user modifications that we are not going to overwrite.) */ continue; // The hashes do not match, this is an upgrade. Store the // old hash. upgrade[full] = pHash; } // Add the file add.insert(HDValue(hash, full)); } // 'pre' list are files already expected to be in the install // directory for(DirMap::const_iterator it = pre.begin(); it != pre.end(); it++) { const std::string &file = it->first; const Hash &hash = it->second; assert(hash.isSet()); assert(file != ""); // If post contains the same file, assume we have already // handled it above if(post.find(file) != post.end()) continue; // A file only listed in the 'pre' dir means the file should be // deleted. const std::string &full = prefix + file; del.insert(HDValue(hash, full)); } pre.clear(); post.clear(); }
void DirInstaller::resolveConflicts(HashDir &add, HashDir &del, const DirMap &upgrade, bool _doAsk) { HashDir backups; // Create a list of all the file locations we want to check DirMap lookup; HashDir::iterator it, it2; for(it = add.begin(); it != add.end(); it++) lookup[it->second] = Hash(); for(it = del.begin(); it != del.end(); it++) lookup[it->second] = Hash(); // Check all the files in one run index.checkMany(lookup); // Go through the list of created elements for(it = add.begin(); it != add.end();) { // Keep two iterators so we can remove elements from the list // while iterating HashDir::iterator it2 = it++; const Hash &hash = it2->first; const std::string &file = it2->second; assert(hash.isSet()); assert(file != ""); const Hash &fHash = lookup[file]; // Always overwrite missing files if(fHash.isNull()) continue; // Also overwrite if the file matches what we expected it to be bool upg = false; { DirMap::const_iterator res = upgrade.find(file); upg = (res != upgrade.end()); if(upg && res->second == fHash) continue; } /* If a unexpected file was found, and it's not the file we are writing, then ask the user what to do. */ if(fHash != hash) { int i = 1; if(_doAsk) { std::string text; if(upg) text = "File '" + file + "' contains modifications. Overwrite anyway?"; else text = "File '" + file + "' already exists. Overwrite it?"; i = ask(text, "Overwrite with backup (recommended)", "Overwrite without backup", "Keep file"); } if(i == 0 || i == 1) { if(i == 0) backups.insert(HDValue(fHash, file + ".___backup___")); continue; } assert(i == 2); } // Remove the file addition entry add.erase(it2); } // Add backups back into the addition list for(it = backups.begin(); it != backups.end(); it++) add.insert(*it); // Do the same for the delete list for(it = del.begin(); it != del.end();) { it2 = it++; const Hash &hash = it2->first; const std::string &file = it2->second; assert(hash.isSet()); assert(file != ""); const Hash &fHash = lookup[file]; // Delete file if it matches the expected hash if(fHash == hash) continue; if(fHash.isSet()) { // There is a file, and it doesn't match what we want int i = 0; if(_doAsk) i = ask("Deleted file '" + file + "' has changes. Delete anyway?", "Delete file", "Keep file"); if(i == 0) continue; assert(i == 1); } // Don't delete this file del.erase(it2); } }
void Spread::Dir::add(DirMap &dir, const DirMap &d, const std::string &prefix) { for(DirMap::const_iterator it = d.begin(); it != d.end(); it++) dir[prefix+it->first] = it->second; }