コード例 #1
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotRemoveKey(const QString &_key)
{
    QString key = _key.trimmed();

    if (key.isEmpty()) {
        logFileError() << "RemoveKey specifies invalid key" << endl;
        return;
    }

    if (!m_oldConfig1) {
        logFileError() << "Key without previous File specification" << endl;
        return;
    }

    KConfigGroup cg1 = KConfigUtils::openGroup(m_oldConfig1, m_oldGroup);
    if (!cg1.hasKey(key)) {
        return;
    }
    log() << m_currentFilename << ": RemoveKey removes " << m_oldFile << ":" << m_oldGroup << ":" << key << endl;

    // Delete old entry
    KConfigGroup cg2 = KConfigUtils::openGroup(m_oldConfig2, m_oldGroup);
    cg2.deleteEntry(key);
    /*if (m_oldConfig2->deleteGroup(m_oldGroup, KConfig::Normal)) { // Delete group if empty.
       log() << m_currentFilename << ": Removing empty group " << m_oldFile << ":" << m_oldGroup << endl;
    }   (this should be automatic)*/
}
コード例 #2
0
void MDSAttrParser::parseFile(CFURLRef infoUrl, CFStringRef subdir)
{
	CFStringRef infoType = NULL;
	
	/* Get contents of mdsinfo file as dictionary */
	MDSDictionary mdsDict(infoUrl, subdir, mPath);
	/* Make sure we set all possible MDS values before checking for GUID */
	mdsDict.setDefaults(mDefaults);
	if (mGuid == NULL) {
		CFStringRef guid = (CFStringRef)mdsDict.lookup("ModuleID", true, CFStringGetTypeID());
		if (guid) {
			CFIndex copylen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(guid), kCFStringEncodingUTF8) + 1/*nul terminator*/;
			mGuid = new char[copylen];
			if (false == CFStringGetCString(guid, mGuid, copylen, kCFStringEncodingUTF8)) {
				logFileError("Error copying GUID", infoUrl, NULL, NULL);
				delete [] mGuid;
				mGuid = NULL;
				CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
			}
		}
		else {
			logFileError("No GUID associated with plugin?", infoUrl, NULL, NULL);
			CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
		}
	}
	
	MPDebug("Parsing mdsinfo file %s", mdsDict.fileDesc());
	
	/* Determine what kind of info file this is and dispatch accordingly */
	infoType = (CFStringRef)mdsDict.lookup(CFSTR(MDS_INFO_FILE_TYPE),
		true, CFStringGetTypeID());
	if(infoType == NULL) {
		logFileError("Malformed MDS Info file", infoUrl, NULL, NULL);
		CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
	}
	
	/* be robust here, errors in these low-level routines do not affect
	 * the rest of our task */
	try {
		if(CFStringCompare(infoType, CFSTR(MDS_INFO_FILE_TYPE_CSSM), 0) 
				== kCFCompareEqualTo) {
			parseCssmInfo(&mdsDict);
		}
		else if(CFStringCompare(infoType, CFSTR(MDS_INFO_FILE_TYPE_PLUGIN), 0) 
				== kCFCompareEqualTo) {
			parsePluginCommon(&mdsDict);
		}
		else if(CFStringCompare(infoType, CFSTR(MDS_INFO_FILE_TYPE_RECORD), 0) 
				== kCFCompareEqualTo) {
			parsePluginSpecific(&mdsDict);
		}
		else {
			logFileError("Malformed MDS Info file", infoUrl, NULL, NULL);
		}
	}
	catch(...) {
	
	}
}
コード例 #3
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotAllKeys()
{
    if (!m_oldConfig1) {
        logFileError() << "AllKeys without previous File specification" << endl;
        return;
    }

    copyOrMoveGroup(m_oldGroup, m_newGroup);
}
コード例 #4
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
QStringList KonfUpdate::parseGroupString(const QString &str)
{
    bool ok;
    QString error;
    QStringList lst = KConfigUtils::parseGroupString(str, &ok, &error);
    if (!ok) {
        logFileError() << error;
    }
    return lst;
}
コード例 #5
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotKey(const QString &_key)
{
    QString oldKey, newKey;
    int i = _key.indexOf(',');
    if (i == -1) {
        oldKey = _key.trimmed();
        newKey = oldKey;
    } else {
        oldKey = _key.left(i).trimmed();
        newKey = _key.mid(i + 1).trimmed();
    }

    if (oldKey.isEmpty() || newKey.isEmpty()) {
        logFileError() << "Key specifies invalid key" << endl;
        return;
    }
    if (!m_oldConfig1) {
        logFileError() << "Key without previous File specification" << endl;
        return;
    }
    copyOrMoveKey(m_oldGroup, oldKey, m_newGroup, newKey);
}
コード例 #6
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotAllGroups()
{
    if (!m_oldConfig1) {
        logFileError() << "AllGroups without previous File specification" << endl;
        return;
    }

    const QStringList allGroups = m_oldConfig1->groupList();
    for (QStringList::ConstIterator it = allGroups.begin();
            it != allGroups.end(); ++it) {
        m_oldGroup = QStringList() << *it;
        m_newGroup = m_oldGroup;
        gotAllKeys();
    }
}
コード例 #7
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotRemoveGroup(const QString &_group)
{
    m_oldGroup = parseGroupString(_group);

    if (!m_oldConfig1) {
        logFileError() << "RemoveGroup without previous File specification" << endl;
        return;
    }

    KConfigGroup cg = KConfigUtils::openGroup(m_oldConfig2, m_oldGroup);
    if (!cg.exists()) {
        return;
    }
    // Delete group.
    cg.deleteGroup();
    log() << m_currentFilename << ": RemoveGroup removes group " << m_oldFile << ":" << m_oldGroup << endl;
}
コード例 #8
0
ファイル: SampleSourceWave.c プロジェクト: JC-Morph/MrsWatson
static boolByte _readWaveFileInfo(const char *filename, SampleSourcePcmData extraData)
{
    int chunkOffset = 0;
    RiffChunk chunk = newRiffChunk();
    boolByte dataChunkFound = false;
    char format[4];
    size_t itemsRead;
    unsigned int audioFormat;
    unsigned int byteRate;
    unsigned int expectedByteRate;
    unsigned int blockAlign;
    unsigned int expectedBlockAlign;

    if (riffChunkReadNext(chunk, extraData->fileHandle, false)) {
        if (!riffChunkIsIdEqualTo(chunk, "RIFF")) {
            logFileError(filename, "Invalid RIFF chunk descriptor");
            freeRiffChunk(chunk);
            return false;
        }

        // The WAVE file format has two sub-chunks, with the size of both calculated in the size field. Before
        // either of the subchunks, there are an extra 4 bytes which indicate the format type. We need to read
        // that before either of the subchunks can be parsed.
        itemsRead = fread(format, sizeof(byte), 4, extraData->fileHandle);

        if (itemsRead != 4 || strncmp(format, "WAVE", 4)) {
            logFileError(filename, "Invalid format description");
            freeRiffChunk(chunk);
            return false;
        }
    } else {
        logFileError(filename, "No chunks following descriptor");
        freeRiffChunk(chunk);
        return false;
    }

    if (riffChunkReadNext(chunk, extraData->fileHandle, true)) {
        if (!riffChunkIsIdEqualTo(chunk, "fmt ")) {
            logError(filename, "Invalid format chunk header");
            freeRiffChunk(chunk);
            return false;
        }

        audioFormat = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
        chunkOffset += 2;

        if (audioFormat != 1) {
            logError("WAVE file with audio format %d is not supported", audioFormat);
            freeRiffChunk(chunk);
            return false;
        }

        extraData->numChannels = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
        chunkOffset += 2;
        setNumChannels(extraData->numChannels);

        extraData->sampleRate = convertByteArrayToUnsignedInt(chunk->data + chunkOffset);
        chunkOffset += 4;
        setSampleRate(extraData->sampleRate);

        byteRate = convertByteArrayToUnsignedInt(chunk->data + chunkOffset);
        chunkOffset += 4;

        blockAlign = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
        chunkOffset += 2;

        extraData->bitDepth = (BitDepth) convertByteArrayToUnsignedShort(chunk->data + chunkOffset);

        if (extraData->bitDepth != kBitDepth16Bit) {
            logUnsupportedFeature("Non-16-bit files with internal WAVE file support (build with audiofile instead!)");
            freeRiffChunk(chunk);
            return false;
        }

        expectedByteRate = (unsigned int)(extraData->sampleRate) *
                           extraData->numChannels * extraData->bitDepth / 8;

        if (expectedByteRate != byteRate) {
            logWarn("Possibly invalid bitrate %d, expected %d", byteRate, expectedByteRate);
        }

        expectedBlockAlign = (unsigned int)(extraData->numChannels * extraData->bitDepth / 8);

        if (expectedBlockAlign != blockAlign) {
            logWarn("Possibly invalid block align %d, expected %d", blockAlign, expectedBlockAlign);
        }
    } else {
        logFileError(filename, "WAVE file has no chunks following format");
        freeRiffChunk(chunk);
        return false;
    }

    // We don't need the format data anymore, so free and re-alloc the chunk to avoid a small memory leak
    freeRiffChunk(chunk);
    chunk = newRiffChunk();

    // FFMpeg (and possibly other programs) have extra sections between the fmt and data chunks. They
    // can be safely ignored. We just need to find the data chunk. See also:
    // http://forum.videohelp.com/threads/359689-ffmpeg-Override-Set-ISFT-Metadata
    while (!dataChunkFound) {
        if (riffChunkReadNext(chunk, extraData->fileHandle, false)) {
            if (riffChunkIsIdEqualTo(chunk, "data")) {
                logDebug("WAVE file has %d bytes", chunk->size);
                dataChunkFound = true;
            } else {
                fseek(extraData->fileHandle, (long) chunk->size, SEEK_CUR);
            }
        } else {
            break;
        }
    }

    if (!dataChunkFound) {
        logFileError(filename, "Could not find a data chunk. Possibly malformed WAVE file.");
        freeRiffChunk(chunk);
        return false;
    }

    freeRiffChunk(chunk);
    return true;
}
コード例 #9
0
ファイル: SampleSourceWave.c プロジェクト: jzinkdi/MrsWatson
static boolByte _readWaveFileInfo(const char* filename, SampleSourcePcmData extraData) {
  int chunkOffset = 0;
  RiffChunk chunk = newRiffChunk();
  char format[4];
  size_t itemsRead;
  unsigned int audioFormat;
  unsigned int byteRate;
  unsigned int expectedByteRate;
  unsigned int blockAlign;
  unsigned int expectedBlockAlign;

  if(riffChunkReadNext(chunk, extraData->fileHandle, false)) {
    if(!riffChunkIsIdEqualTo(chunk, "RIFF")) {
      logFileError(filename, "Invalid RIFF chunk descriptor");
      freeRiffChunk(chunk);
      return false;
    }

    // The WAVE file format has two sub-chunks, with the size of both calculated in the size field. Before
    // either of the subchunks, there are an extra 4 bytes which indicate the format type. We need to read
    // that before either of the subchunks can be parsed.
    itemsRead = fread(format, sizeof(byte), 4, extraData->fileHandle);
    if(itemsRead != 4 || strncmp(format, "WAVE", 4)) {
      logFileError(filename, "Invalid format description");
      freeRiffChunk(chunk);
      return false;
    }
  }
  else {
    logFileError(filename, "No chunks following descriptor");
    freeRiffChunk(chunk);
    return false;
  }

  if(riffChunkReadNext(chunk, extraData->fileHandle, true)) {
    if(!riffChunkIsIdEqualTo(chunk, "fmt ")) {
      logError(filename, "Invalid format chunk header");
      freeRiffChunk(chunk);
      return false;
    }

    audioFormat = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
    chunkOffset += 2;
    if(audioFormat != 1) {
      logUnsupportedFeature("Compressed WAVE files");
      freeRiffChunk(chunk);
      return false;
    }

    extraData->numChannels = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
    chunkOffset += 2;
    setNumChannels(extraData->numChannels);

    extraData->sampleRate = convertByteArrayToUnsignedInt(chunk->data + chunkOffset);
    chunkOffset += 4;
    setSampleRate(extraData->sampleRate);

    byteRate = convertByteArrayToUnsignedInt(chunk->data + chunkOffset);
    chunkOffset += 4;

    blockAlign = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
    chunkOffset += 2;

    extraData->bitsPerSample = convertByteArrayToUnsignedShort(chunk->data + chunkOffset);
    if(extraData->bitsPerSample > 16) {
      logUnsupportedFeature("Bitrates greater than 16");
      freeRiffChunk(chunk);
      return false;
    }
    else if(extraData->bitsPerSample < 16) {
      logUnsupportedFeature("Bitrates lower than 16");
      freeRiffChunk(chunk);
      return false;
    }

    expectedByteRate = extraData->sampleRate * extraData->numChannels * extraData->bitsPerSample / 8;
    if(expectedByteRate != byteRate) {
      logWarn("Possibly invalid bitrate %d, expected %d", byteRate, expectedByteRate);
    }

    expectedBlockAlign = extraData->numChannels * extraData->bitsPerSample / 8;
    if(expectedBlockAlign != blockAlign) {
      logWarn("Possibly invalid block align %d, expected %d", blockAlign, expectedBlockAlign);
    }
  }
  else {
    logFileError(filename, "WAVE file has no chunks following format");
    freeRiffChunk(chunk);
    return false;
  }

  // We don't need the format data anymore, so free and re-alloc the chunk to avoid a small memory leak
  freeRiffChunk(chunk);
  chunk = newRiffChunk();

  if(riffChunkReadNext(chunk, extraData->fileHandle, false)) {
    if(!riffChunkIsIdEqualTo(chunk, "data")) {
      logFileError(filename, "WAVE file has invalid data chunk header");
      freeRiffChunk(chunk);
      return false;
    }

    logDebug("WAVE file has %d bytes", chunk->size);
  }

  freeRiffChunk(chunk);
  return true;
}
コード例 #10
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
void KonfUpdate::gotScript(const QString &_script)
{
    QString script, interpreter;
    int i = _script.indexOf(',');
    if (i == -1) {
        script = _script.trimmed();
    } else {
        script = _script.left(i).trimmed();
        interpreter = _script.mid(i + 1).trimmed();
    }


    if (script.isEmpty()) {
        logFileError() << "Script fails to specify filename";
        m_skip = true;
        return;
    }



    QString path = KStandardDirs::locate("data", "kconf_update/" + script);
    if (path.isEmpty()) {
        if (interpreter.isEmpty()) {
            path = KStandardDirs::locate("lib", "kconf_update_bin/" + script);
        }

        if (path.isEmpty()) {
            logFileError() << "Script '" << script << "' not found" << endl;
            m_skip = true;
            return;
        }
    }

    if (!m_arguments.isNull()) {
        log() << m_currentFilename << ": Running script '" << script << "' with arguments '" << m_arguments << "'" << endl;
    } else {
        log() << m_currentFilename << ": Running script '" << script << "'" << endl;
    }

    QString cmd;
    if (interpreter.isEmpty()) {
        cmd = path;
    } else {
        cmd = interpreter + ' ' + path;
    }

    if (!m_arguments.isNull()) {
        cmd += ' ';
        cmd += m_arguments;
    }

    KTemporaryFile scriptIn;
    scriptIn.open();
    KTemporaryFile scriptOut;
    scriptOut.open();
    KTemporaryFile scriptErr;
    scriptErr.open();

    int result;
    if (m_oldConfig1) {
        if (m_debug) {
            scriptIn.setAutoRemove(false);
            log() << "Script input stored in " << scriptIn.fileName() << endl;
        }
        KConfig cfg(scriptIn.fileName(), KConfig::SimpleConfig);

        if (m_oldGroup.isEmpty()) {
            // Write all entries to tmpFile;
            const QStringList grpList = m_oldConfig1->groupList();
            for (QStringList::ConstIterator it = grpList.begin();
                    it != grpList.end();
                    ++it) {
                copyGroup(m_oldConfig1, *it, &cfg, *it);
            }
        } else {
            KConfigGroup cg1 = KConfigUtils::openGroup(m_oldConfig1, m_oldGroup);
            KConfigGroup cg2(&cfg, QString());
            copyGroup(cg1, cg2);
        }
        cfg.sync();
#ifndef _WIN32_WCE
        result = system(QFile::encodeName(QString("%1 < %2 > %3 2> %4").arg(cmd, scriptIn.fileName(), scriptOut.fileName(), scriptErr.fileName())));
#else
        QString path_ = QDir::convertSeparators ( QFileInfo ( cmd ).absoluteFilePath() );
        QString file_ = QFileInfo ( cmd ).fileName();
        SHELLEXECUTEINFO execInfo;
        memset ( &execInfo,0,sizeof ( execInfo ) );
        execInfo.cbSize = sizeof ( execInfo );
        execInfo.fMask =  SEE_MASK_FLAG_NO_UI;
        execInfo.lpVerb = L"open";
        execInfo.lpFile = (LPCWSTR) path_.utf16();
        execInfo.lpDirectory = (LPCWSTR) file_.utf16();
        execInfo.lpParameters = (LPCWSTR) QString(" < %1 > %2 2> %3").arg( scriptIn.fileName(), scriptOut.fileName(), scriptErr.fileName()).utf16();
        result = ShellExecuteEx ( &execInfo );
        if (result != 0)
        {
            result = 0;
        }
        else
        {
            result = -1;
        }
#endif
    } else {
        // No config file
#ifndef _WIN32_WCE
        result = system(QFile::encodeName(QString("%1 2> %2").arg(cmd, scriptErr.fileName())));
#else
        QString path_ = QDir::convertSeparators ( QFileInfo ( cmd ).absoluteFilePath() );
        QString file_ = QFileInfo ( cmd ).fileName();
        SHELLEXECUTEINFO execInfo;
        memset ( &execInfo,0,sizeof ( execInfo ) );
        execInfo.cbSize = sizeof ( execInfo );
        execInfo.fMask =  SEE_MASK_FLAG_NO_UI;
        execInfo.lpVerb = L"open";
        execInfo.lpFile = (LPCWSTR) path_.utf16();
        execInfo.lpDirectory = (LPCWSTR) file_.utf16();
        execInfo.lpParameters = (LPCWSTR) QString(" 2> %1").arg( scriptErr.fileName()).utf16();
        result = ShellExecuteEx ( &execInfo );
        if (result != 0)
        {
            result = 0;
        }
        else
        {
            result = -1;
        }
#endif
    }

    // Copy script stderr to log file
    {
        QFile output(scriptErr.fileName());
        if (output.open(QIODevice::ReadOnly)) {
            QTextStream ts(&output);
            ts.setCodec(QTextCodec::codecForName("UTF-8"));
            while (!ts.atEnd()) {
                QString line = ts.readLine();
                log() << "[Script] " << line << endl;
            }
        }
    }

    if (result) {
        log() << m_currentFilename << ": !! An error occurred while running '" << cmd << "'" << endl;
        return;
    }

    if (!m_oldConfig1) {
        return; // Nothing to merge
    }

    if (m_debug) {
        scriptOut.setAutoRemove(false);
        log() << "Script output stored in " << scriptOut.fileName() << endl;
    }

    // Deleting old entries
    {
        QStringList group = m_oldGroup;
        QFile output(scriptOut.fileName());
        if (output.open(QIODevice::ReadOnly)) {
            QTextStream ts(&output);
            ts.setCodec(QTextCodec::codecForName("UTF-8"));
            while (!ts.atEnd()) {
                QString line = ts.readLine();
                if (line.startsWith('[')) {
                    group = parseGroupString(line);
                } else if (line.startsWith(QLatin1String("# DELETE "))) {
                    QString key = line.mid(9);
                    if (key[0] == '[') {
                        int j = key.lastIndexOf(']') + 1;
                        if (j > 0) {
                            group = parseGroupString(key.left(j));
                            key = key.mid(j);
                        }
                    }
                    KConfigGroup cg = KConfigUtils::openGroup(m_oldConfig2, group);
                    cg.deleteEntry(key);
                    log() << m_currentFilename << ": Script removes " << m_oldFile << ":" << group << ":" << key << endl;
                    /*if (m_oldConfig2->deleteGroup(group, KConfig::Normal)) { // Delete group if empty.
                       log() << m_currentFilename << ": Removing empty group " << m_oldFile << ":" << group << endl;
                    } (this should be automatic)*/
                } else if (line.startsWith(QLatin1String("# DELETEGROUP"))) {
                    QString str = line.mid(13).trimmed();
                    if (!str.isEmpty()) {
                        group = parseGroupString(str);
                    }
                    KConfigGroup cg = KConfigUtils::openGroup(m_oldConfig2, group);
                    cg.deleteGroup();
                    log() << m_currentFilename << ": Script removes group " << m_oldFile << ":" << group << endl;
                }
            }
        }
    }

    // Merging in new entries.
    KConfig scriptOutConfig(scriptOut.fileName(), KConfig::NoGlobals);
    if (m_newGroup.isEmpty()) {
        // Copy "default" keys as members of "default" keys
        copyGroup(&scriptOutConfig, QString(), m_newConfig, QString());
    } else {
        // Copy default keys as members of m_newGroup
        KConfigGroup srcCg = KConfigUtils::openGroup(&scriptOutConfig, QStringList());
        KConfigGroup dstCg = KConfigUtils::openGroup(m_newConfig, m_newGroup);
        copyGroup(srcCg, dstCg);
    }
    Q_FOREACH(const QString &group, scriptOutConfig.groupList()) {
        copyGroup(&scriptOutConfig, group, m_newConfig, group);
    }
}
コード例 #11
0
ファイル: kconf_update.cpp プロジェクト: vasi/kdelibs
/**
 * Syntax:
 * # Comment
 * Id=id
 * File=oldfile[,newfile]
 * AllGroups
 * Group=oldgroup[,newgroup]
 * RemoveGroup=oldgroup
 * Options=[copy,][overwrite,]
 * Key=oldkey[,newkey]
 * RemoveKey=ldkey
 * AllKeys
 * Keys= [Options](AllKeys|(Key|RemoveKey)*)
 * ScriptArguments=arguments
 * Script=scriptfile[,interpreter]
 *
 * Sequence:
 * (Id,(File(Group,Keys)*)*)*
 **/
bool KonfUpdate::updateFile(const QString &filename)
{
    m_currentFilename = filename;
    int i = m_currentFilename.lastIndexOf('/');
    if (i != -1) {
        m_currentFilename = m_currentFilename.mid(i + 1);
    }
    m_skip = true;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }

    log() << "Checking update-file '" << filename << "' for new updates" << endl;

    QTextStream ts(&file);
    ts.setCodec(QTextCodec::codecForName("ISO-8859-1"));
    m_lineCount = 0;
    resetOptions();
    while (!ts.atEnd()) {
        m_line = ts.readLine().trimmed();
        m_lineCount++;
        if (m_line.isEmpty() || (m_line[0] == '#')) {
            continue;
        }
        if (m_line.startsWith(QLatin1String("Id="))) {
            gotId(m_line.mid(3));
        } else if (m_skip) {
            continue;
        } else if (m_line.startsWith(QLatin1String("Options="))) {
            gotOptions(m_line.mid(8));
        } else if (m_line.startsWith(QLatin1String("File="))) {
            gotFile(m_line.mid(5));
        } else if (m_skipFile) {
            continue;
        } else if (m_line.startsWith(QLatin1String("Group="))) {
            gotGroup(m_line.mid(6));
        } else if (m_line.startsWith(QLatin1String("RemoveGroup="))) {
            gotRemoveGroup(m_line.mid(12));
            resetOptions();
        } else if (m_line.startsWith(QLatin1String("Script="))) {
            gotScript(m_line.mid(7));
            resetOptions();
        } else if (m_line.startsWith(QLatin1String("ScriptArguments="))) {
            gotScriptArguments(m_line.mid(16));
        } else if (m_line.startsWith(QLatin1String("Key="))) {
            gotKey(m_line.mid(4));
            resetOptions();
        } else if (m_line.startsWith(QLatin1String("RemoveKey="))) {
            gotRemoveKey(m_line.mid(10));
            resetOptions();
        } else if (m_line == "AllKeys") {
            gotAllKeys();
            resetOptions();
        } else if (m_line == "AllGroups") {
            gotAllGroups();
            resetOptions();
        } else {
            logFileError() << "Parse error" << endl;
        }
    }
    // Flush.
    gotId(QString());

    KDE_struct_stat buff;
    KDE::stat(filename, &buff);
    KConfigGroup cg(m_config, m_currentFilename);
    cg.writeEntry("ctime", int(buff.st_ctime));
    cg.writeEntry("mtime", int(buff.st_mtime));
    cg.sync();
    return true;
}