Ticket #12424: 0008-RemoteFile-CopyFile-Don-t-overwrite-existing-files-b.patch

File 0008-RemoteFile-CopyFile-Don-t-overwrite-existing-files-b.patch, 8.0 KB (added by Roger Siddons <dizygotheca@…>, 8 years ago)
  • mythplugins/mythmusic/mythmusic/cdrip.cpp

    From 78bbb5cf75a09153caba8546a71b58b170e92b5f Mon Sep 17 00:00:00 2001
    From: Roger Siddons <dizygotheca@ntlworld.com>
    Date: Sat, 22 Aug 2015 13:25:45 +0100
    Subject: [PATCH 08/15] RemoteFile::CopyFile: Don't overwrite existing files by
     default
    
    CopyFile doesn't check for a file's existance before writing to it.
    For storage groups containing multiple dirs this can lead to multiple versions of a remote file (only
    one of which will be read).
    
    This patch will fail the copy (by default) if the destination file exists.
    If the overwrite flag is set the destination file is deleted first, ensuring that multiple versions
    are not created.
    
    It also adds optional verification that the copy succeeded (by comparing file sizes) as write can fail
    silently if the filesystem fills up.
    
    diff --git a/mythplugins/mythmusic/mythmusic/cdrip.cpp b/mythplugins/mythmusic/mythmusic/cdrip.cpp
    index 77a5ce0..aadb893 100644
    a b void CDRipperThread::run(void) 
    394394                destFile = gCoreContext->GenMythURL(url.host(), 0, destFile, "Music");
    395395
    396396                QApplication::postEvent(m_parent, new RipStatusEvent(RipStatusEvent::kCopyStartEvent, 0));
    397                 RemoteFile::CopyFile(saveDir + outfile, destFile);
     397                RemoteFile::CopyFile(saveDir + outfile, destFile, true);
    398398                QApplication::postEvent(m_parent, new RipStatusEvent(RipStatusEvent::kCopyEndEvent, 0));
    399399            }
    400400        }
  • mythplugins/mythmusic/mythmusic/editmetadata.cpp

    diff --git a/mythplugins/mythmusic/mythmusic/editmetadata.cpp b/mythplugins/mythmusic/mythmusic/editmetadata.cpp
    index 0370b6b..37b6301 100644
    a b void EditMetadataDialog::customEvent(QEvent *event) 
    860860                    return;
    861861                }
    862862
    863                 RemoteFile::CopyFile(oldFilename, newFilename);
     863                RemoteFile::CopyFile(oldFilename, newFilename, true);
    864864                QFile::remove(oldFilename);
    865865
    866866                if (m_searchType == "album")
    void EditAlbumartDialog::doCopyImageToTag(const AlbumArtImage *image) 
    13731373                                                    QString("AlbumArt/") + fi.fileName(),
    13741374                                                    "MusicArt");
    13751375
    1376     RemoteFile::CopyFile(image->filename, saveFilename);
     1376    RemoteFile::CopyFile(image->filename, saveFilename, true);
    13771377
    13781378    // ask the backend to add the image to the tracks tag
    13791379    QStringList strList("MUSIC_TAG_ADDIMAGE");
  • mythplugins/mythmusic/mythmusic/importmusic.cpp

    diff --git a/mythplugins/mythmusic/mythmusic/importmusic.cpp b/mythplugins/mythmusic/mythmusic/importmusic.cpp
    index 4c465cf..f60b939 100644
    a b FileCopyThread::FileCopyThread(const QString &src, const QString &dst) : 
    5353void FileCopyThread::run()
    5454{
    5555    RunProlog();
    56     m_result = RemoteFile::CopyFile(m_srcFile, m_dstFile);
     56    m_result = RemoteFile::CopyFile(m_srcFile, m_dstFile, true);
    5757    RunEpilog();
    5858}
    5959
    void ImportMusicDialog::addPressed() 
    438438
    439439        m_somethingWasImported = true;
    440440
    441         m_tracks->at(m_currentTrack)->isNewTune = 
     441        m_tracks->at(m_currentTrack)->isNewTune =
    442442                isNewTune(meta->Artist(), meta->Album(), meta->Title());
    443443
    444444        // update the UI
    void ImportMusicDialog::startScan() 
    543543        location.append('/');
    544544
    545545    MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
    546     MythUIBusyDialog *busy = 
     546    MythUIBusyDialog *busy =
    547547            new MythUIBusyDialog(tr("Searching for music files"),
    548548                                     popupStack,
    549549                                     "scanbusydialog");
    void ImportMusicDialog::setAlbum(void) 
    814814    MusicMetadata *data = m_tracks->at(m_currentTrack)->metadata;
    815815    data->setAlbum(m_defaultAlbum);
    816816
    817     m_tracks->at(m_currentTrack)->isNewTune = 
     817    m_tracks->at(m_currentTrack)->isNewTune =
    818818            isNewTune(data->Artist(), data->Album(), data->Title());
    819819
    820820    fillWidgets();
    void ImportCoverArtDialog::copyPressed() 
    10751075{
    10761076    if (m_filelist.size() > 0)
    10771077    {
    1078         if (!RemoteFile::CopyFile(m_filelist[m_currentFile], m_saveFilename))
     1078        if (!RemoteFile::CopyFile(m_filelist[m_currentFile], m_saveFilename, true))
    10791079        {
    10801080            //: %1 is the filename
    10811081            ShowOkPopup(tr("Copy CoverArt Failed.\nCopying to %1").arg(m_saveFilename));
  • mythtv/libs/libmythbase/remotefile.cpp

    diff --git a/mythtv/libs/libmythbase/remotefile.cpp b/mythtv/libs/libmythbase/remotefile.cpp
    index 469c292..594a6eb 100644
    a b QString RemoteFile::GetFileHash(const QString &url) 
    558558    return result;
    559559}
    560560
    561 bool RemoteFile::CopyFile (const QString& src, const QString& dst)
     561bool RemoteFile::CopyFile (const QString& src, const QString& dst,
     562                           bool overwrite, bool verify)
    562563{
    563     LOG(VB_FILE, LOG_INFO, QString("RemoteFile::CopyFile: Copying file from '%1' to '%2'").arg(src).arg(dst));
     564    LOG(VB_FILE, LOG_INFO,
     565        QString("RemoteFile::CopyFile: Copying file from '%1' to '%2'").arg(src).arg(dst));
    564566
    565567    // sanity check
    566568    if (src == dst)
    bool RemoteFile::CopyFile (const QString& src, const QString& dst) 
    586588         return false;
    587589    }
    588590
     591    if (overwrite)
     592    {
     593        DeleteFile(dst);
     594    }
     595    else if (Exists(dst))
     596    {
     597        LOG(VB_GENERAL, LOG_ERR, "RemoteFile::CopyFile: File already exists");
     598        return false;
     599    }
     600
    589601    RemoteFile dstFile(dst, true);
    590602    if (!dstFile.isOpen())
    591603    {
    bool RemoteFile::CopyFile (const QString& src, const QString& dst) 
    596608         return false;
    597609    }
    598610
     611    dstFile.SetBlocking(true);
     612
     613    bool success = true;
    599614    int srcLen, dstLen;
    600615
    601616    while ((srcLen = srcFile.Read(buf, readSize)) > 0)
    bool RemoteFile::CopyFile (const QString& src, const QString& dst) 
    605620        if (dstLen == -1 || srcLen != dstLen)
    606621        {
    607622            LOG(VB_GENERAL, LOG_ERR,
    608                 "RemoteFile::CopyFile:: Error while trying to write to destination file.");
    609             srcFile.Close();
    610             dstFile.Close();
    611             delete[] buf;
    612             return false;
     623                "RemoteFile::CopyFile: Error while trying to write to destination file.");
     624            success = false;
    613625        }
    614626    }
    615627
    bool RemoteFile::CopyFile (const QString& src, const QString& dst) 
    617629    dstFile.Close();
    618630    delete[] buf;
    619631
    620     return true;
     632    if (success && verify)
     633    {
     634        // Check written file is correct size
     635        struct stat fileinfo;
     636        long long dstSize = Exists(dst, &fileinfo) ? fileinfo.st_size : -1;
     637        long long srcSize = srcFile.GetFileSize();
     638        if (dstSize != srcSize)
     639        {
     640            LOG(VB_GENERAL, LOG_ERR,
     641                QString("RemoteFile::CopyFile: Copied file is wrong size (%1 rather than %2)")
     642                    .arg(dstSize).arg(srcSize));
     643            success = false;
     644            DeleteFile(dst);
     645        }
     646    }
     647
     648    return success;
    621649}
    622650
    623651void RemoteFile::Reset(void)
  • mythtv/libs/libmythbase/remotefile.h

    diff --git a/mythtv/libs/libmythbase/remotefile.h b/mythtv/libs/libmythbase/remotefile.h
    index 3c18a05..42fd38e 100644
    a b class MBASE_PUBLIC RemoteFile 
    4141    static QStringList FindFileList(const QString &filename, const QString &host,
    4242                                    const QString &storageGroup, bool useRegex = false,
    4343                                    bool allowFallback = false);
    44     static bool CopyFile(const QString &src, const QString &dest);
     44    static bool CopyFile(const QString &src, const QString &dest,
     45                         bool overwrite = false, bool verify = false);
    4546
    4647    int Write(const void *data, int size);
    4748    int Read(void *data, int size);