Example #1
0
bool CTorrent::LoadTorrentFromFile(const QByteArray& InfoHash)
{
    ASSERT(m_TorrentInfo == NULL);
    m_TorrentInfo = new CTorrentInfo(this);

    ASSERT(m_pHash.isNull());
    m_pHash = CFileHashPtr(new CFileHash(HashTorrent));
    m_pHash->SetHash(InfoHash);

    QString TorrentFile = QString(InfoHash.toHex()) + ".torrent";

    if(m_TorrentInfo->LoadTorrentFile(theCore->m_TorrentManager->GetTorrentDir() + TorrentFile))
    {
        if(m_TorrentInfo->GetInfoHash() == InfoHash)
        {
            CFile* pFile = GetFile();

            if(pFile->GetFileSize() == 0)
                pFile->SetFileSize(m_TorrentInfo->GetTotalLength());

            LoadPieceHashes();

            if(m_TorrentInfo->IsMultiFile() && !pFile->IsMultiFile())
            {
                CFileHashPtr pMasterHash = pFile->GetMasterHash();
                if(!pMasterHash.isNull() && pMasterHash->GetHash() == InfoHash)
                {
                    LogLine(LOG_DEBUG | LOG_ERROR, tr("The multi file %1 is missing its proper index, restoring form torrent").arg(pFile->GetFileName()));
                    InstallMetadata();
                }
            }

            if(!m_TorrentInfo->IsEmpty() && !pFile->IsComplete() && !pFile->GetPartMap())
                SetupPartMap();
        }
        else
        {
            LogLine(LOG_DEBUG | LOG_ERROR, tr("The torrent file %1 contains an invalid infohash").arg(TorrentFile));
            delete m_TorrentInfo;
            m_TorrentInfo = new CTorrentInfo(this);
            m_TorrentInfo->SetInfoHash(InfoHash);
        }
    }
    else
        m_TorrentInfo->SetInfoHash(InfoHash);
    theCore->m_TorrentManager->RegisterInfoHash(m_TorrentInfo->GetInfoHash());

    return true; // Note: that is always true even if we fail to load as we always wil be able to proceed one way or another
}
Example #2
0
bool CTorrent::InstallMetadata()
{
    CFile* pFile = GetFile();

    ASSERT(m_TorrentInfo);

    CPartMap* pPartMap = pFile->GetPartMap();
    if(pPartMap && !CompareSubFiles(pPartMap))
    {
        if(pFile->GetInspector()->BadMetaData(GetHash()))
            pPartMap = NULL;
        else
            return false;
    }

    if(m_pHash->Compare(pFile->GetMasterHash().data()))
        pFile->SetFileName(m_TorrentInfo->GetTorrentName());

    bool bOpenIO = false;
    CJoinedPartMap* pJoinedParts = qobject_cast<CJoinedPartMap*>(pPartMap);
    if((pPartMap == NULL && !pFile->IsComplete()) || (pJoinedParts && pJoinedParts->GetLinks().isEmpty()))
    {
        bOpenIO = true;
        if(!pPartMap)
            pFile->SetFileSize(m_TorrentInfo->GetTotalLength());

        SetupPartMap();

        if(!pPartMap && !pFile->IsPending())
            pFile->SetFilePath();
    }

    LoadPieceHashes();

    if(pFile->IsIncomplete() && pFile->GetMasterHash()->GetType() == HashTorrent)
        pFile->CleanUpHashes();

    // Note: if neo is the masterhash the IO is already opened
    if(bOpenIO && !pFile->IsPending())
        pFile->Resume();
    return true;
}
Example #3
0
void CTorrent::SetupPartMap()
{
    ASSERT(!m_TorrentInfo->IsEmpty());

    CFile* pFile = GetFile();

    // Single File
    if(!m_TorrentInfo->IsMultiFile())
    {
        if(!pFile->GetPartMap())
            pFile->SetPartMap(CPartMapPtr(new CSynced<CPartMap>(m_TorrentInfo->GetTotalLength())));
        return;
    }

    // Multi File:

    CJoinedPartMap* pParts = qobject_cast<CJoinedPartMap*>(pFile->GetPartMap());
    if(pParts)
    {
        ASSERT(!pParts->GetLinks().isEmpty());
        return; // is already set up
    }
    pParts = new CJoinedPartMap(pFile->GetFileSize());

    pFile->GetInspector()->SetIndexSource(HashTorrent);

    CFileList* pList = pFile->GetList();

    uint64 Offset = 0;
    foreach(const CTorrentInfo::SFileInfo& SubFile, m_TorrentInfo->GetFiles())
    {
        if(SubFile.Length == 0)
        {
            LogLine(LOG_DEBUG | LOG_WARNING, tr("Ignoring empty file '%1' in torrent '%2'").arg(SubFile.FileName).arg(pFile->GetFileName()));
            continue;
        }

        CFile* pSubFile = new CFile();
        if(pFile->GetProperty("Temp").toBool())
            pSubFile->SetProperty("Temp", true);

        QString Dir = pFile->GetFileDir();
        Dir += pFile->GetFileName() + "/";
        if(!SubFile.FilePath.isEmpty())
            Dir += SubFile.FilePath.join("/") + "/";
        pSubFile->SetFileDir(Dir);

        pSubFile->AddEmpty(HashTorrent, SubFile.FileName, SubFile.Length, pFile->IsPending());

        // Note: SubFile->MasterHash is set in MasterFile->Resume

        uint64 uBegin = Offset;
        uint64 uEnd = Offset + SubFile.Length;
        Offset += SubFile.Length;

        CSharedPartMap* pSubParts = new CSharedPartMap(uEnd - uBegin);
        pSubFile->SetPartMap(CPartMapPtr(pSubParts));

        pParts->SetupLink(uBegin, uEnd, pSubFile->GetFileID());
        pSubParts->SetupLink(uBegin, uEnd, pFile->GetFileID());

        pList->AddFile(pSubFile);

        if(!pSubFile->IsPending())
            pSubFile->Resume();

        if(pFile->IsPaused(true))
            pSubFile->Pause();
        else if(pFile->IsStarted())
            pSubFile->Start();
    }

    pFile->SetPartMap(CPartMapPtr(pParts));
}
Example #4
0
void CTorrent::OnFileHashed()
{
    CFile* pFile = GetFile();
    ASSERT(m_TorrentInfo);
    if(m_TorrentInfo->IsEmpty()) // are we making a torrent
    {
        QStringList Shared = theCore->Cfg()->GetStringList("Content/Shared");
        Shared.append(theCore->GetIncomingDir());
        Shared.append(theCore->GetTempDir());

        QList<CTorrentInfo::SFileInfo> Files;
        if(CJoinedPartMap* pParts = qobject_cast<CJoinedPartMap*>(pFile->GetPartMap()))
        {
            QMap<uint64, SPartMapLink*> Links = pParts->GetJoints();
            for(QMap<uint64, SPartMapLink*>::iterator I = Links.end(); I != Links.begin();)
            {
                SPartMapLink* pLink = *(--I);

                CFile* pSubFile = pFile->GetList()->GetFileByID(pLink->ID);
                if(!pSubFile)
                {
                    LogLine(LOG_DEBUG | LOG_ERROR, tr("A sub file of %1 has been being removed befoure the torrent was created").arg(pFile->GetFileName()));
                    pFile->TorrentHashed(this, false);
                    return;
                }

                CTorrentInfo::SFileInfo File;
                QString Root;
                QStringList Path = GetRelativeSharedPath(pSubFile->GetFilePath(), Shared, Root).split("/", QString::SkipEmptyParts);
                if(!Path.isEmpty())
                {
                    if(Path.count() > 1)
                        Path.removeFirst();
                    File.FileName = Path.takeLast();
                    File.FilePath = Path;
                }
                else
                    File.FileName = "unknown";
                File.Length = pSubFile->GetFileSize();
                Files.append(File);
            }
        }

        if(CFileHashTree* pHashTree = qobject_cast<CFileHashTree*>(m_pHash.data()))
            m_TorrentInfo->MakeMetadata(Files, pHashTree->GetPartSize(), QList<QByteArray>(), pHashTree->GetRootHash());
        else if(CFileHashSet* pHashSet = qobject_cast<CFileHashSet*>(m_pHash.data()))
            m_TorrentInfo->MakeMetadata(Files, pHashSet->GetPartSize(), pHashSet->GetHashSet());
        else {
            ASSERT(0);
        }

        if(!pFile->IsPending())
            SaveTorrentToFile();

        m_pHash->SetHash(m_TorrentInfo->GetInfoHash());
        theCore->m_TorrentManager->RegisterInfoHash(m_TorrentInfo->GetInfoHash());

        pFile->TorrentHashed(this, true);
    }
    else // we are importing a torrent
    {
        bool bMatch = false;

        if(CFileHashTree* pHashTree = qobject_cast<CFileHashTree*>(m_pHash.data()))
            bMatch = m_TorrentInfo->GetRootHash() == pHashTree->GetRootHash();
        else if(CFileHashSet* pHashSet = qobject_cast<CFileHashSet*>(m_pHash.data()))
            bMatch = m_TorrentInfo->GetPieceHashes() == pHashSet->GetHashSet();
        else {
            ASSERT(0);
        }

        if(bMatch)
        {
            if(!pFile->IsPending())
                SaveTorrentToFile();

            m_pHash->SetHash(m_TorrentInfo->GetInfoHash());
            theCore->m_TorrentManager->RegisterInfoHash(m_TorrentInfo->GetInfoHash());
        }

        pFile->TorrentHashed(this, bMatch);
    }
}