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)*/ }
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(...) { } }
void KonfUpdate::gotAllKeys() { if (!m_oldConfig1) { logFileError() << "AllKeys without previous File specification" << endl; return; } copyOrMoveGroup(m_oldGroup, m_newGroup); }
QStringList KonfUpdate::parseGroupString(const QString &str) { bool ok; QString error; QStringList lst = KConfigUtils::parseGroupString(str, &ok, &error); if (!ok) { logFileError() << error; } return lst; }
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); }
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(); } }
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; }
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; }
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; }
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); } }
/** * 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; }