Ejemplo n.º 1
0
Boolean FileSystem::compareFiles(
    const String& path1,
    const String& path2)
{
    Uint32 fileSize1;

    if (!getFileSize(path1, fileSize1))
        throw CannotOpenFile(path1);

    Uint32 fileSize2;

    if (!getFileSize(path2, fileSize2))
        throw CannotOpenFile(path2);

    if (fileSize1 != fileSize2)
        return false;

    FILE* fp1 = fopen(path1.getCString(), "rb");

    if (fp1 == NULL)
        throw CannotOpenFile(path1);

    FILE* fp2 = fopen(path2.getCString(), "rb");

    if (fp2 == NULL)
    {
        fclose(fp1);
        throw CannotOpenFile(path2);
    }

    int c1;
    int c2;

    while ((c1 = fgetc(fp1)) != EOF && (c2 = fgetc(fp2)) != EOF)
    {
        if (c1 != c2)
        {
            fclose(fp1);
            fclose(fp2);
            return false;
        }
    }

    fclose(fp1);
    fclose(fp2);
    return true;
}
Ejemplo n.º 2
0
	RawDataFile::RawDataFile(const std::string& file) : m_file(file), m_stream(m_file.c_str(), std::ios::binary), m_filesize(0) {
		if (!m_stream)
			throw CannotOpenFile(m_file);

		m_stream.seekg(0, std::ios::end);
		m_filesize = m_stream.tellg();
		m_stream.seekg(0, std::ios::beg);
	}
Ejemplo n.º 3
0
void FileSystem::loadFileToMemory(
    Buffer& array,
    const String& fileName)
{
    Uint32 fileSize;

    if (!getFileSize(fileName, fileSize))
        throw CannotOpenFile(fileName);

    FILE* fp = fopen(fileName.getCString(), "rb");

    if (fp == NULL)
        throw CannotOpenFile(fileName);

    array.reserveCapacity(fileSize);
    char buffer[4096];
    size_t n;

    while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0)
        array.append(buffer, static_cast<Uint32>(n));

    fclose(fp);
}
Ejemplo n.º 4
0
void ExportEPUB::CreateEncryptionXML(const QString &fullfolderpath)
{
    QTemporaryFile file;

    if (!file.open()) {
        boost_throw(CannotOpenFile()
                    << errinfo_file_fullpath(file.fileName().toStdString())
                    << errinfo_file_errorstring(file.errorString().toStdString())
                   );
    }

    EncryptionXmlWriter enc(*m_Book, file);
    enc.WriteXML();
    // Write to disk immediately
    file.flush();
    QFile::copy(file.fileName(), fullfolderpath + "/" + ENCRYPTION_XML_FILE_NAME);
}
Ejemplo n.º 5
0
// Accepts a full path to an HTML file.
// Reads the file, detects the encoding
// and returns the text converted to Unicode. 
QString HTMLEncodingResolver::ReadHTMLFile( const QString &fullfilepath )
{
    QFile file( fullfilepath );

    // Check if we can open the file
    if ( !file.open( QFile::ReadOnly ) ) 
    {
        boost_throw( CannotOpenFile() 
                     << errinfo_file_fullpath( file.fileName().toStdString() )
                     << errinfo_file_errorstring( file.errorString().toStdString() ) 
                   );
    }

    QByteArray data = file.readAll();

    return Utility::ConvertLineEndings( GetCodecForHTML( data ).toUnicode( data ) );
}
Ejemplo n.º 6
0
// Accepts a full path to an HTML file.
// Reads the file, detects the encoding
// and returns the text converted to Unicode.
QString HTMLEncodingResolver::ReadHTMLFile(const QString &fullfilepath)
{
    QFile file(fullfilepath);

    // Check if we can open the file
    if (!file.open(QFile::ReadOnly)) {
        std::string msg = file.fileName().toStdString() + ": " + file.errorString().toStdString();
        throw (CannotOpenFile(msg));
    }

    QByteArray data = file.readAll();

    if (IsValidUtf8(data)) {
        data.replace("\xC2\xA0", "&#160;");
    }

    return Utility::ConvertLineEndings(GetCodecForHTML(data)->toUnicode(data));
}
Ejemplo n.º 7
0
//
// create a file and make a random token data entry to it.
// send the file name back to caller
//
String LocalAuthFile::create()
{
    PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::create()");

    Uint32 secs, milliSecs;
    Uint32 mySequenceNumber;

    System::getCurrentTime(secs, milliSecs);

    //
    // extension size is username plus the sequence count
    //
    {
        AutoMutex autoMut(sequenceCountLock);
        mySequenceNumber = sequenceCount++;
    } // mutex unlocks here

    char extension[2*INT_BUFFER_SIZE];
    sprintf(extension,"_%u_%u", mySequenceNumber, milliSecs);
    extension[strlen(extension)] = 0;

    String filePath;

    // Check to see whether a domain was specified. If so, strip the domain
    // from the local auth file name, since the backslash and '@' are invalid
    // filename characters.  Store this in another variable, since we need to
    // keep the domain around for the rest of the operations.
    String fileUserName = _userName;
    Uint32 index = _userName.find('\\');
    if (index != PEG_NOT_FOUND)
    {
        fileUserName = _userName.subString(index + 1);
    }
    else
    {
        index = _userName.find('@');
        if (index != PEG_NOT_FOUND)
        {
            fileUserName = _userName.subString(0, index);
        }
    }

    filePath.append(_authFilePath);
    filePath.append(fileUserName);//_userName);
    filePath.append(extension);
    CString filePathCString = filePath.getCString();

    //
    // 1. Create a file name for authentication.
    //
    ofstream outfs(filePathCString);

    if (!outfs)
    {
        // unable to create file
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "Security.Authentication.LocalAuthFile.NO_CREATE",
                "Creation of the local authentication security file"
                    " $0 failed: $1",
                filePath, strerror(errno)));
        PEG_METHOD_EXIT();
        throw CannotOpenFile (filePath);
    }
    outfs.clear();

    //
    // 2. Set file permission to read/write by the owner only.
    //

#if defined(PEGASUS_OS_TYPE_WINDOWS)
    Boolean success =
        FileSystem::changeFilePermissions(filePath, _S_IREAD | _S_IWRITE);
#else
    Boolean success =
        FileSystem::changeFilePermissions(filePath, S_IRUSR | S_IWUSR);
#endif

    if (!success)
    {
        // Unable to change the local auth file permissions, remove the file
        // and throw CannotOpenFile error.
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "Security.Authentication.LocalAuthFile.NO_CHMOD",
                "Changing permissions of the local authentication security "
                    "file $0 failed: $1",
                filePath, strerror(errno)));

        if (filePath.size())
        {
            if (FileSystem::exists(filePath))
            {
                FileSystem::removeFile(filePath);
            }
        }

        PEG_METHOD_EXIT();
        throw CannotOpenFile (filePath);
    }

    //
    // 3. Generate random token and write the token to the file.
    //
    String randomToken = _generateRandomTokenString();
    outfs << randomToken;

    // test if the write was successful
    if (outfs.fail())
    {
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "Security.Authentication.LocalAuthFile.NO_WRITE",
                "Cannot write security token to the local authentication "
                    "security file $0.",
                filePath));

        if (filePath.size())
        {
            if (FileSystem::exists(filePath))
            {
                FileSystem::removeFile(filePath);
            }
        }

        PEG_METHOD_EXIT();
        throw CannotOpenFile (filePath);

    }

    outfs.close();

    //
    // 4. Set file permission to read only by the owner.
    //
#if defined(PEGASUS_OS_TYPE_WINDOWS)
    success = FileSystem::changeFilePermissions(filePath, _S_IREAD);
#else
    success = FileSystem::changeFilePermissions(filePath, S_IRUSR);
#endif

    if (!success)
    {
        // Unable to change the local auth file permissions, remove the file
        // and throw CannotOpenFile error.
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "Security.Authentication.LocalAuthFile.NO_CHMOD",
                "Changing permissions of the local authentication security "
                    "file $0 failed: $1",
                filePath, strerror(errno)));

        if (filePath.size())
        {
            if (FileSystem::exists(filePath))
            {
                FileSystem::removeFile(filePath);
            }
        }

        PEG_METHOD_EXIT();
        throw CannotOpenFile (filePath);
    }

    //
    // 5. Change the file owner to the requesting user.
    //

    if (!FileSystem::changeFileOwner(filePath,_userName))
    {
        // Unable to change owner on local auth file, remove the file
        // and throw CannotOpenFile error.

        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "Security.Authentication.LocalAuthFile.NO_CHOWN_REQUSER",
                "Changing ownership of the local authentication "
                    "security file $0 to the requesting user failed: $1",
                filePath, strerror(errno)));

        if (filePath.size())
        {
            if (FileSystem::exists(filePath))
            {
                FileSystem::removeFile(filePath);
            }
        }

        PEG_METHOD_EXIT();
        throw CannotOpenFile (filePath);
    }

    _secret = randomToken;

    _filePathName = filePath;

    PEG_METHOD_EXIT();

    return _filePathName;
}
Ejemplo n.º 8
0
	SubImageFont::SubImageFont(const std::string& filename, const std::string& glyphs)
		: ImageFontBase() {

		FL_LOG(_log, LMsg("guichan_image_font, loading ") << filename << " glyphs " << glyphs);

//prock - 504
		ImagePtr img = ImageManager::instance()->load(filename);
		int32_t image_id = img->getHandle();
		SDL_Surface* surface = img->getSurface();
		m_colorkey = RenderBackend::instance()->getColorKey();

		if( !surface ) {
			throw CannotOpenFile(filename);
		}

		// Make sure we get 32bit RGB
		// and copy the Pixelbuffers surface
		SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
			surface->w,surface->h,32,
			RMASK, GMASK, BMASK ,NULLMASK);

		SDL_BlitSurface(surface,0,tmp,0);
		surface = tmp;

		// Prepare the data for extracting the glyphs.
		uint32_t *pixels = reinterpret_cast<uint32_t*>(surface->pixels);

		int32_t x, w;
		x = 0; w=0;

		SDL_Rect src;

		src.h = surface->h;
		src.y = 0;
		
		uint32_t separator = pixels[0];
		uint32_t colorkey = SDL_MapRGB(surface->format, m_colorkey.r, m_colorkey.g, m_colorkey.b);

		// if colorkey feature is not enabled then manually find the color key in the font
		if (!RenderBackend::instance()->isColorKeyEnabled()) {
			while(x < surface->w && pixels[x] == separator) {
				++x;
			}
			
			colorkey = pixels[x];
		}
		
		// Disable alpha blending, so that we use color keying
		SDL_SetAlpha(surface,0,255);
		SDL_SetColorKey(surface,SDL_SRCCOLORKEY,colorkey);

		FL_DBG(_log, LMsg("image_font")
			<< " glyph separator is " 
			<< pprint(reinterpret_cast<void*>(separator))
			<< " transparent color is " 
			<< pprint(reinterpret_cast<void*>(colorkey)));

		// Finally extract all glyphs
		std::string::const_iterator text_it = glyphs.begin();
		while(text_it != glyphs.end()) {
			w=0;
			while(x < surface->w && pixels[x] == separator)
				++x;
			if( x == surface->w )
				break;

			while(x + w < surface->w && pixels[x + w] != separator)
				++w;

			src.x = x;
			src.w = w;

			tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
					w,surface->h,32,
					RMASK, GMASK, BMASK ,NULLMASK);

			SDL_FillRect(tmp,0,colorkey);
			SDL_BlitSurface(surface,&src,tmp,0);

			// Disable alpha blending, so that we use colorkeying
			SDL_SetAlpha(tmp,0,255);
			SDL_SetColorKey(tmp,SDL_SRCCOLORKEY,colorkey);


			uint32_t codepoint = utf8::next(text_it, glyphs.end());
			m_glyphs[ codepoint ].surface = tmp;

			x += w;
		}

		// Set placeholder glyph
		// This should actually work ith utf8.
		if( m_glyphs.find('?') != m_glyphs.end() ) {
			m_placeholder = m_glyphs['?'];
		} else {
			m_placeholder.surface = 0;
		}

		mHeight = surface->h;
		SDL_FreeSurface(surface);
	}
Ejemplo n.º 9
0
/** 
    Replace the properties in the config file with the properties from
    the given file.
*/
void ConfigFile::replace (const String& fileName)
{
    String line;

    //
    // Open the given config file for reading
    //
#if defined(PEGASUS_OS_OS400)
    ifstream ifs(fileName.getCString(), PEGASUS_STD(_CCSID_T(1208)));
#else
    ifstream ifs(fileName.getCString());
#endif

    //
    // Delete the backup configuration file
    //
    if (FileSystem::exists(_configBackupFile))
    {
        FileSystem::removeFile(_configBackupFile);
    }

    //
    // Rename the existing config file as a backup file
    //
    if (FileSystem::exists(_configFile))
    {
        if (!FileSystem::renameFile(_configFile, _configBackupFile))
        {
            ifs.close();
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the existing config file for writing
    //
#if defined(PEGASUS_OS_OS400)
    ofstream ofs(_configFile.getCString(), PEGASUS_STD(_CCSID_T(1208)));
#else
    ofstream ofs(_configFile.getCString());
#endif
    ofs.clear();

#if !defined(PEGASUS_OS_TYPE_WINDOWS)
    //
    // Set permissions on the config file to 0644
    //
    if ( !FileSystem::changeFilePermissions(_configFile,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) )    // set 0644 
    {
        throw CannotOpenFile(_configFile);
    }
#endif

    //
    // Read each line of the new file and write to the config file.
    //
    for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
    {
        ofs << line << endl;
    }

    // 
    // Close the file handles
    //
    ifs.close();
    ofs.close();
}
Ejemplo n.º 10
0
/** 
    Save the properties to the config file.
*/
void ConfigFile::save (ConfigTable* confTable)
{
    //
    // Delete the backup configuration file
    //
    if (FileSystem::exists(_configBackupFile))
    {
        FileSystem::removeFile(_configBackupFile);
    }

    //
    // Rename the configuration file as a backup file
    //
    if (FileSystem::exists(_configFile))
    {
        if (!FileSystem::renameFile(_configFile, _configBackupFile))
        {
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the config file for writing
    //
#if defined(PEGASUS_OS_OS400)
    ofstream ofs(_configFile.getCString(), PEGASUS_STD(_CCSID_T(1208)));
#else
    ofstream ofs(_configFile.getCString());
#endif
    ofs.clear();

#if !defined(PEGASUS_OS_TYPE_WINDOWS)
    //
    // Set permissions on the config file to 0644
    //
    if ( !FileSystem::changeFilePermissions(_configFile,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) )    // set 0644 
    {
        throw CannotOpenFile(_configFile);
    }
#endif

    //
    // Write config file header information
    //
    for (int index = 0; index < HEADER_SIZE; index++)
    {
        ofs << ConfigHeader[index] << endl;
    }

    ofs << endl;

    //
    // Save config properties and values to the file
    //
    for (Table::Iterator i = confTable->table.start(); i; i++)
    {
        ofs << i.key() << "=" << i.value() << endl;
    }

    ofs.close();
}
Ejemplo n.º 11
0
/**
    Replace the properties in the config file with the properties from
    the given file.
*/
void ConfigFile::replace (const String& fileName)
{
    //
    // Open the given config file for reading
    //

    FILE* ifs = fopen(fileName.getCString(), "r");

    if (!ifs)
    {
        throw CannotOpenFile(fileName);
    }

    //
    // Delete the backup configuration file
    //

    if (FileSystem::exists(_configBackupFile))
    {
        Executor::removeFile(_configBackupFile.getCString());
    }

    //
    // Rename the existing config file as a backup file
    //

    if (FileSystem::exists(_configFile))
    {
        if (Executor::renameFile(
            _configFile.getCString(), _configBackupFile.getCString()) != 0)
        {
            fclose(ifs);
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the existing config file for writing
    //

    FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');

    if (!ofs)
    {
        fclose(ifs);
        throw CannotOpenFile(_configFile);
    }

    //
    // Read each line of the new file and write to the config file.
    //

    char buffer[4096];

    while ((fgets(buffer, sizeof(buffer), ifs)) != NULL)
        fputs(buffer, ofs);

    //
    // Close the file handles
    //

    fclose(ifs);
    fclose(ofs);

#if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
# if !defined(PEGASUS_OS_TYPE_WINDOWS)
    //
    // Set permissions on the config file to 0644
    //
    if (!FileSystem::changeFilePermissions(_configFile,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
    {
        throw CannotChangeFilePerm(_configFile);
    }
# endif
#endif /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION */
}
Ejemplo n.º 12
0
/**
    Save the properties to the config file.
*/
void ConfigFile::save(ConfigTable* confTable)
{
    //
    // Delete the backup configuration file
    //
    if (FileSystem::exists(_configBackupFile))
    {
        Executor::removeFile(_configBackupFile.getCString());
    }

    //
    // Rename the configuration file as a backup file
    //

    if (FileSystem::exists(_configFile))
    {
        if (Executor::renameFile(
            _configFile.getCString(), _configBackupFile.getCString()) != 0)
        {
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the config file for writing
    //

    FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');

    if (!ofs)
    {
        throw CannotOpenFile(_configFile);
    }

    //
    // Write config file header information
    //

    for (int index = 0; index < HEADER_SIZE; index++)
    {
        fputs(ConfigHeader[index], ofs);
        fputc('\n', ofs);
    }

    //
    // Save config properties and values to the file
    //

    for (Table::Iterator i = confTable->table.start(); i; i++)
    {
        CString key = i.key().getCString();
        CString value = i.value().getCString();
        fprintf(ofs, "%s=%s\n", (const char*)key, (const char*)value);
    }

    fclose(ofs);

#if !defined(PEGASUS_OS_TYPE_WINDOWS)
    // Note:  The Executor process sets the permissions to 0644 when it
    // opens the config file for writing.
    if (Executor::detectExecutor() != 0)
    {
        //
        // Set permissions on the config file to 0644
        //
        if (!FileSystem::changeFilePermissions(
                _configFile,
                (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
        {
            throw CannotChangeFilePerm(_configFile);
        }
    }
#endif
}
Ejemplo n.º 13
0
void ExportEPUB::SaveFolderAsEpubToLocation(const QString &fullfolderpath, const QString &fullfilepath)
{
    QString tempFile = fullfolderpath + "-tmp.epub";
    QDateTime timeNow = QDateTime::currentDateTime();
    zip_fileinfo fileInfo;
#ifdef Q_OS_WIN32
    zlib_filefunc64_def ffunc;
    fill_win32_filefunc64W(&ffunc);
    zipFile zfile = zipOpen2_64(Utility::QStringToStdWString(QDir::toNativeSeparators(tempFile)).c_str(), APPEND_STATUS_CREATE, NULL, &ffunc);
#else
    zipFile zfile = zipOpen64(QDir::toNativeSeparators(tempFile).toUtf8().constData(), APPEND_STATUS_CREATE);
#endif

    if (zfile == NULL) {
        boost_throw(CannotOpenFile() << errinfo_file_fullpath(tempFile.toStdString()));
    }

    memset(&fileInfo, 0, sizeof(fileInfo));
    fileInfo.tmz_date.tm_sec = timeNow.time().second();
    fileInfo.tmz_date.tm_min = timeNow.time().minute();
    fileInfo.tmz_date.tm_hour = timeNow.time().hour();
    fileInfo.tmz_date.tm_mday = timeNow.date().day();
    fileInfo.tmz_date.tm_mon = timeNow.date().month() - 1;
    fileInfo.tmz_date.tm_year = timeNow.date().year();

    // Write the mimetype. This must be uncompressed and the first entry in the archive.
    if (zipOpenNewFileInZip64(zfile, "mimetype", &fileInfo, NULL, 0, NULL, 0, NULL, Z_NO_COMPRESSION, 0, 0) != Z_OK) {
        zipClose(zfile, NULL);
        QFile::remove(tempFile);
        boost_throw(CannotStoreFile() << errinfo_file_fullpath("mimetype"));
    }

    if (zipWriteInFileInZip(zfile, EPUB_MIME_DATA, (unsigned int)strlen(EPUB_MIME_DATA)) != Z_OK) {
        zipCloseFileInZip(zfile);
        zipClose(zfile, NULL);
        QFile::remove(tempFile);
        boost_throw(CannotStoreFile() << errinfo_file_fullpath("mimetype"));
    }

    zipCloseFileInZip(zfile);
    // Write all the files in our directory path to the archive.
    QDirIterator it(fullfolderpath, QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::Hidden, QDirIterator::Subdirectories);

    while (it.hasNext()) {
        it.next();
        QString relpath = it.filePath().remove(fullfolderpath);

        while (relpath.startsWith("/")) {
            relpath = relpath.remove(0, 1);
        }

        // Add the file entry to the archive.
        // We should check the uncompressed file size. If it's over >= 0xffffffff the last parameter (zip64) should be 1.
        if (zipOpenNewFileInZip4_64(zfile, relpath.toUtf8().constData(), &fileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 8, 0, 15, 8, Z_DEFAULT_STRATEGY, NULL, 0, 0x0b00, 1<<11, 0) != Z_OK) {
            zipClose(zfile, NULL);
            QFile::remove(tempFile);
            boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString()));
        }

        // Open the file on disk. We will read this and write what we read into
        // the archive.
        QFile dfile(it.filePath());

        if (!dfile.open(QIODevice::ReadOnly)) {
            zipCloseFileInZip(zfile);
            zipClose(zfile, NULL);
            QFile::remove(tempFile);
            boost_throw(CannotOpenFile() << errinfo_file_fullpath(it.fileName().toStdString()));
        }

        // Write the data from the file on disk into the archive.
        char buff[BUFF_SIZE] = {0};
        qint64 read = 0;

        while ((read = dfile.read(buff, BUFF_SIZE)) > 0) {
            if (zipWriteInFileInZip(zfile, buff, read) != Z_OK) {
                dfile.close();
                zipCloseFileInZip(zfile);
                zipClose(zfile, NULL);
                QFile::remove(tempFile);
                boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString()));
            }
        }

        dfile.close();

        // There was an error reading the file on disk.
        if (read < 0) {
            zipCloseFileInZip(zfile);
            zipClose(zfile, NULL);
            QFile::remove(tempFile);
            boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString()));
        }

        if (zipCloseFileInZip(zfile) != Z_OK) {
            zipClose(zfile, NULL);
            QFile::remove(tempFile);
            boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString()));
        }
    }

    zipClose(zfile, NULL);
    // Overwrite the contents of the real file with the contents from the temp
    // file we saved the data do. We do this instead of simply copying the file
    // because a file copy will lose extended attributes such as labels on OS X.
    QFile temp_epub(tempFile);

    if (!temp_epub.open(QFile::ReadOnly)) {
        boost_throw(CannotOpenFile() << errinfo_file_fullpath(tempFile.toStdString()));
    }

    QFile real_epub(fullfilepath);

    if (!real_epub.open(QFile::WriteOnly | QFile::Truncate)) {
        temp_epub.close();
        boost_throw(CannotWriteFile() << errinfo_file_fullpath(fullfilepath.toStdString()));
    }

    // Copy the contents from the temp file to the real file.
    char buff[BUFF_SIZE] = {0};
    qint64 read = 0;
    qint64 written = 0;

    while ((read = temp_epub.read(buff, BUFF_SIZE)) > 0) {
        written = real_epub.write(buff, read);

        if (written != read) {
            temp_epub.close();
            real_epub.close();
            QFile::remove(tempFile);
            boost_throw(CannotCopyFile() << errinfo_file_fullpath(fullfilepath.toStdString()));
        }
    }

    if (read == -1) {
        temp_epub.close();
        real_epub.close();
        QFile::remove(tempFile);
        boost_throw(CannotCopyFile() << errinfo_file_fullpath(fullfilepath.toStdString()));
    }

    temp_epub.close();
    real_epub.close();
    QFile::remove(tempFile);
}