void CLDS_File::x_SyncWithDir(const string& path, CLDS_Set* deleted, CLDS_Set* updated, set<string>* scanned_files, TFlags flags) { CDir dir(path); if (!dir.Exists()) { LOG_POST_X(2, Info << "LDS: Directory is not found or access denied:" << path); return; } else { LOG_POST_X(3, Info << "LDS: scanning " << path); } CLDS_Query lds_query(m_DataBase); CChecksum checksum(CChecksum::eCRC32); // Scan the directory, compare it against File table // Here I intentionally take only files, skipping sub-directories, // Second pass scans for sub-dirs and implements recursion bool compute_check_sum = (flags & CLDS_Manager::fControlSumMask) == CLDS_Manager::fComputeControlSum; {{ CDir::TEntries content(dir.GetEntries()); ITERATE(CDir::TEntries, i, content) { if (!(*i)->IsFile()) { continue; } (*i)->DereferenceLink(); CTime modification; string entry = (*i)->GetPath(); string name = (*i)->GetName(); string ext = (*i)->GetExt(); (*i)->GetTime(&modification); time_t tm = modification.GetTimeT(); CFile aFile(entry); Int8 file_size = aFile.GetLength(); if (ext == ".db" || ext == ".idx") { continue; // Berkeley DB file, no need to index it. } bool found = lds_query.FindFile(entry); scanned_files->insert(entry); if (!found) { // new file arrived CFormatGuess fg; Uint4 crc = 0; if (compute_check_sum) { checksum.Reset(); ComputeFileChecksum(entry, checksum); crc = checksum.GetChecksum(); } CFormatGuess::EFormat format = fg.Format(entry); FindMaxRecId(); ++m_MaxRecId; m_FileDB.file_id = m_MaxRecId; m_FileDB.file_name = entry.c_str(); m_FileDB.format = format; m_FileDB.time_stamp = tm; m_FileDB.CRC = crc; m_FileDB.file_size = file_size; m_FileDB.Insert(); m_DataBase.GetTables().file_filename_idx.file_id = m_MaxRecId; m_DataBase.GetTables().file_filename_idx.file_name = entry.c_str(); m_DataBase.GetTables().file_filename_idx.UpdateInsert(); updated->set(m_MaxRecId); LOG_POST_X(4, Info << "New LDS file found: " << entry); continue; } if (tm != m_FileDB.time_stamp || file_size != m_FileDB.file_size) { updated->set(m_FileDB.file_id); UpdateEntry(m_FileDB.file_id, entry, 0, tm, file_size, compute_check_sum); } else { Uint4 crc = 0; if (compute_check_sum) { checksum.Reset(); ComputeFileChecksum(entry, checksum); crc = checksum.GetChecksum(); if (crc != (Uint4)m_FileDB.CRC) { updated->set(m_FileDB.file_id); UpdateEntry(m_FileDB.file_id, entry, crc, tm, file_size, compute_check_sum); } } } } // ITERATE }} if ( (flags & CLDS_Manager::fRecurseMask) == CLDS_Manager::fDontRecurse ) return; // Scan sub-directories {{ CDir::TEntries content(dir.GetEntries()); ITERATE(CDir::TEntries, i, content) { if ((*i)->IsDir()) { string name = (*i)->GetName(); if (name == "LDS" || name == "." || name == "..") { continue; } string entry = (*i)->GetPath(); x_SyncWithDir(entry, deleted, updated, scanned_files, flags); } } // ITERATE }} }