Example #1
0
	KVIRC_API void printSSLCertificate(KviWindow * wnd, const char * description, KviSSLCertificate * c)
	{
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]: %c%s"), KviControlCodes::Bold, description);
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:  Version: %c%d"), KviControlCodes::Bold, c->version());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:  Serial number: %c%d"), KviControlCodes::Bold, c->serialNumber());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:  Subject:"));
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Common name: %c%s"), KviControlCodes::Bold, c->subjectCommonName());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Organization: %c%s"), KviControlCodes::Bold, c->subjectOrganization());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Organizational unit: %c%s"), KviControlCodes::Bold, c->subjectOrganizationalUnit());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Country: %c%s"), KviControlCodes::Bold, c->subjectCountry());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     State or province: %c%s"), KviControlCodes::Bold, c->subjectStateOrProvince());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Locality: %c%s"), KviControlCodes::Bold, c->subjectLocality());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:   Issuer:"));
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Common name: %c%s"), KviControlCodes::Bold, c->issuerCommonName());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Organization: %c%s"), KviControlCodes::Bold, c->issuerOrganization());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Organizational unit: %c%s"), KviControlCodes::Bold, c->issuerOrganizationalUnit());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Country: %c%s"), KviControlCodes::Bold, c->issuerCountry());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     State or province: %c%s"), KviControlCodes::Bold, c->issuerStateOrProvince());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:     Locality: %c%s"), KviControlCodes::Bold, c->issuerLocality());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:   Public key: %c%s (%d bits)"), KviControlCodes::Bold, c->publicKeyType(), c->publicKeyBits());
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:   Signature type: %c%s"), KviControlCodes::Bold, c->signatureType());
		KviCString tmp = c->signatureContents();
		if(tmp.len() > 40)
		{
			tmp.cutRight(tmp.len() - 40);
			tmp.append("...");
		}
		wnd->output(KVI_OUT_SSL, __tr2qs("[SSL]:   Signature contents: %c%s"), KviControlCodes::Bold, tmp.ptr());
	}
Example #2
0
	KviIpcSentinel::KviIpcSentinel()
	: QWidget(0)
	{
		setObjectName("kvirc4_ipc_sentinel");
#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
		setWindowTitle("kvirc4_ipc_sentinel");
		setWindowFlags(Qt::FramelessWindowHint);
#else
	#if defined(COMPILE_X11_SUPPORT) && defined(COMPILE_QX11INFO_SUPPORT)
		kvi_ipcLoadAtoms();

		XChangeProperty(kvi_ipc_get_xdisplay(),winId(),kvi_atom_ipc_sentinel_window,XA_STRING,8,
			PropModeReplace,(const unsigned char *)kvi_sentinel_id.ptr(),kvi_sentinel_id.len());

		kvi_ipcSetRemoteCommand(winId(),"");
	#endif //!COMPILE_NO_X
#endif

		move(-50,-50);
		resize(1,1);
#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
		// we need to show the window once otherwise it will never get "realized"
		// and we will not be able to find it via FindWindow()
		show();
#endif
		hide();

	}
Example #3
0
KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText, KviCString & outBuffer)
{
	KviCString szPlain = plainText;
	outBuffer = "";
	if(m_bEncryptCBC)
	{
		if(!doEncryptCBC(szPlain, outBuffer))
			return KviCryptEngine::EncryptError;
	}
	else
	{
		if(!doEncryptECB(szPlain, outBuffer))
			return KviCryptEngine::EncryptError;
	}
	outBuffer.prepend("+OK ");

	if(outBuffer.len() > maxEncryptLen())
	{
		if(maxEncryptLen() > 0)
		{
			setLastError(__tr2qs("Data buffer too long"));
			return KviCryptEngine::EncryptError;
		}
	}

	//outBuffer = MCPS2_STARTTAG;
	//outBuffer += MCPS2_ENDTAG;
	return KviCryptEngine::Encrypted;
}
Example #4
0
	void decode(KviCString & szText, unsigned char ** buf, int *len)
	{
		// make sure its length is multiple of 12 (eventually pad with zeroes)
		if(szText.len() % 12)
		{
			int oldL = szText.len();
			szText.setLen(szText.len() + (12 - (szText.len() % 12)));
			char * padB = szText.ptr() + oldL;
			char * padE = szText.ptr() + szText.len();
			while(padB < padE)*padB++ = 0;
		}

		*len = (int)(szText.len() * 2) / 3;

		*buf = (unsigned char *)KviMemory::allocate(*len);
		unsigned char * p = (unsigned char *)szText.ptr();
		unsigned char * e = p + szText.len();
		int i;
		unsigned char * bufp = *buf;
		while(p < e)
		{
			quint32 * dw1 = (quint32 *)bufp;
			bufp += 4;
			quint32 * dw2 = (quint32 *)bufp;
			bufp += 4;
			*dw2 = 0;
			for(i=0;i < 6;i++)*dw2 |= (fake_base64dec(*p++)) << (i * 6);
			*dw1 = 0;
			for(i=0;i < 6;i++)*dw1 |= (fake_base64dec(*p++)) << (i * 6);
		}

		// FIXME: this is probably needed only on LittleEndian machines!
		byteswap_buffer(*buf,*len);
	}
Example #5
0
bool KviMircryptionEngine::doEncryptCBC(KviCString & plain, KviCString & encoded)
{
	// make sure it is a multiple of 8 bytes (eventually pad with zeroes)
	if(plain.len() % 8)
	{
		int oldL = plain.len();
		plain.setLen(plain.len() + (8 - (plain.len() % 8)));
		char * padB = plain.ptr() + oldL;
		char * padE = plain.ptr() + plain.len();
		while(padB < padE)
			*padB++ = 0;
	}

	int ll = plain.len() + 8;
	unsigned char * in = (unsigned char *)KviMemory::allocate(ll);

	InitVectorEngine::fillRandomIV(in, 8);

	KviMemory::copy(in + 8, plain.ptr(), plain.len());

	// encrypt
	unsigned char * out = (unsigned char *)KviMemory::allocate(ll);
	BlowFish bf((unsigned char *)m_szEncryptKey.ptr(), m_szEncryptKey.len());
	bf.ResetChain();
	bf.Encrypt(in, out, ll, BlowFish::CBC);
	KviMemory::free(in);

	encoded.bufferToBase64((const char *)out, ll);
	KviMemory::free(out);

	encoded.prepend('*'); // prepend the signature

	return true;
}
Example #6
0
static Window kvi_x11_findIpcSentinel(Window win)
{
	Atom type;
	int format;
	unsigned long nItems, after;
	unsigned char * data = nullptr;
	if(XGetWindowProperty(kvi_ipc_get_xdisplay(), win, kvi_atom_ipc_sentinel_window,
		   0, 32, false, XA_STRING, &type, &format, &nItems, &after, &data) == Success)
	{
		if((type == XA_STRING) && (format == 8))
		{
			if((nItems == ((unsigned long)(kvi_sentinel_id.len()))) && data)
			{
				if(kvi_strEqualCSN((const char *)data, kvi_sentinel_id.ptr(), kvi_sentinel_id.len()))
				{
					XFree((char *)data);
					return win;
				}
			}
		}
	}

	Window root, parent;
	Window * children;
	unsigned int nChildren;

	if(!XQueryTree(kvi_ipc_get_xdisplay(), win, &root, &parent, &children, &nChildren))
	{
		if(children)
			XFree((char *)children);
		return 0;
	}

	Window found = 0;

	for(size_t i = 0; !found && i < nChildren; ++i)
		found = kvi_x11_findIpcSentinel(children[i]);

	if(children)
		XFree((char *)children);

	return found;
}
Example #7
0
KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText, KviCString & outBuffer)
{
	if(!m_pEncryptCipher)
	{
		setLastError(__tr2qs("Oops! Encryption cipher not initialized"));
		return KviCryptEngine::EncryptError;
	}
	int len = (int)kvi_strLen(plainText);
	char * buf = (char *)KviMemory::allocate(len + 16); // needed for the eventual padding
	unsigned char * iv = nullptr;
	if(m_bEncryptMode == CBC)
	{
		iv = (unsigned char *)KviMemory::allocate(MAX_IV_SIZE);
		InitVectorEngine::fillRandomIV(iv, MAX_IV_SIZE);
	}

	int retVal = m_pEncryptCipher->padEncrypt((const unsigned char *)plainText, len, (unsigned char *)buf, iv);
	if(retVal < 0)
	{
		KviMemory::free(buf);
		setLastErrorFromRijndaelErrorCode(retVal);
		return KviCryptEngine::EncryptError;
	}

	if(m_bEncryptMode == CBC)
	{
		// prepend the iv to the cyphered text
		buf = (char *)KviMemory::reallocate(buf, retVal + MAX_IV_SIZE);
		KviMemory::move(buf + MAX_IV_SIZE, buf, retVal);
		KviMemory::move(buf, iv, MAX_IV_SIZE);
		KviMemory::free(iv);
		retVal += MAX_IV_SIZE;
	}

	if(!binaryToAscii(buf, retVal, outBuffer))
	{
		KviMemory::free(buf);
		return KviCryptEngine::EncryptError;
	}
	KviMemory::free(buf);

	if(outBuffer.len() > maxEncryptLen())
	{
		if(maxEncryptLen() > 0)
		{
			setLastError(__tr2qs("Data buffer too long"));
			return KviCryptEngine::EncryptError;
		}
	}
	outBuffer.prepend(KviControlCodes::CryptEscape);
	return KviCryptEngine::Encrypted;
}
Example #8
0
bool KviWinampInterface::playMrl(const QString & mrl)
{
	HWND hWinamp = find_winamp(this);
	if(hWinamp)
	{
		QTextCodec * c = mediaplayer_get_codec();
		KviCString szMrl = c ? c->fromUnicode(mrl) : mrl.toUtf8();
		COPYDATASTRUCT cds;
		cds.dwData = IPC_PLAYFILE;
		cds.lpData = (void *)szMrl.ptr();
		cds.cbData = szMrl.len() + 1; // include space for null char
		SendMessage(hWinamp, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
		return true;
	}
	return false;
}
Example #9
0
bool KviMircryptionEngine::doEncryptECB(KviCString & plain, KviCString & encoded)
{
	// make sure it is a multiple of 8 bytes (eventually pad with zeroes)
	if(plain.len() % 8)
	{
		int oldL = plain.len();
		plain.setLen(plain.len() + (8 - (plain.len() % 8)));
		char * padB = plain.ptr() + oldL;
		char * padE = plain.ptr() + plain.len();
		while(padB < padE)
			*padB++ = 0;
	}

	unsigned char * out = (unsigned char *)KviMemory::allocate(plain.len()); // we use this to avoid endiannes problems

	BlowFish bf((unsigned char *)m_szEncryptKey.ptr(), m_szEncryptKey.len());
	bf.ResetChain();
	bf.Encrypt((unsigned char *)plain.ptr(), out, plain.len(), BlowFish::ECB);

	UglyBase64::encode(out, plain.len(), encoded);
	KviMemory::free(out);
	return true;
}
Example #10
0
	bool KviCryptController::initializeEngine(KviCryptEngine * pEngine)
	{
		KviCString szEncryptKey;
		KviCString szDecryptKey;
		KviCString szEncKey = "";
		KviCString szDecKey = "";

		if(m_pEnableEncrypt->isChecked())
		{
			bool bEcb=false, bOld=false;
			szEncryptKey = m_pEncryptKeyEdit->text();
			if(kvi_strEqualCIN("ecb:",szEncryptKey.ptr(),4) && (szEncryptKey.len() > 4))
			{
				szEncryptKey.cutLeft(4);
				bEcb=true;
			} else if(kvi_strEqualCIN("old:",szEncryptKey.ptr(),4) && (szEncryptKey.len() > 4)) {
				szEncryptKey.cutLeft(4);
				bOld=true;
			} else if(kvi_strEqualCIN("cbc:",szEncryptKey.ptr(),4)) {
				szEncryptKey.cutLeft(4);
			}

			if(m_pEncryptHexKeyCheck->isChecked())
			{
				char * pcTmpKey;
				if(szEncryptKey.hexToBuffer(&pcTmpKey,false))
				{
					szEncKey = pcTmpKey;
					KviCString::freeBuffer(pcTmpKey);
				}
			} else {
				szEncKey = szEncryptKey;
			}
			if(bEcb)
				szEncKey.prepend("ecb:");
			else if(bOld)
				szEncKey.prepend("old:");
		}

		if(m_pEnableDecrypt->isChecked())
		{
			bool bEcb=false, bOld=false;
			szDecryptKey = m_pDecryptKeyEdit->text();
			if(kvi_strEqualCIN("ecb:",szDecryptKey.ptr(),4) && (szDecryptKey.len() > 4))
			{
				szDecryptKey.cutLeft(4);
				bEcb=true;
			} else if(kvi_strEqualCIN("old:",szDecryptKey.ptr(),4) && (szDecryptKey.len() > 4)) {
				szDecryptKey.cutLeft(4);
				bOld=true;
			} else if(kvi_strEqualCIN("cbc:",szDecryptKey.ptr(),4)) {
				szDecryptKey.cutLeft(4);
			}

			if(m_pDecryptHexKeyCheck->isChecked())
			{
				char * pcTmpKey;
				if(szDecryptKey.hexToBuffer(&pcTmpKey,false))
				{
					szDecKey = pcTmpKey;
					KviCString::freeBuffer(pcTmpKey);
				}
			} else {
				szDecKey = szDecryptKey;
			}
			if(bEcb)
				szDecKey.prepend("ecb:");
			else if(bOld)
				szDecKey.prepend("old:");
		}

		bool bRet = pEngine->init(szEncKey.ptr(),szEncKey.len(),szDecKey.ptr(),szDecKey.len());

		return bRet;
	}
Example #11
0
bool KviRijndaelEngine::init(const char * encKey, int encKeyLen, const char * decKey, int decKeyLen)
{
	if(m_pEncryptCipher)
	{
		delete m_pEncryptCipher;
		m_pEncryptCipher = nullptr;
	}
	if(m_pDecryptCipher)
	{
		delete m_pDecryptCipher;
		m_pDecryptCipher = nullptr;
	}

	if(encKey && (encKeyLen > 0))
	{
		if(!(decKey && (decKeyLen > 0)))
		{
			decKey = encKey;
			decKeyLen = encKeyLen;
		} // else all
	}
	else
	{
		// no encrypt key specified...
		if(decKey && decKeyLen)
		{
			encKey = decKey;
			encKeyLen = decKeyLen;
		}
		else
		{
			// both keys missing
			setLastError(__tr2qs("Missing both encryption and decryption key: at least one is needed"));
			return false;
		}
	}

	KviCString szTmpEncryptKey = KviCString(encKey, encKeyLen);
	KviCString szTmpDecryptKey = KviCString(decKey, decKeyLen);

	m_bEncryptMode = CBC; // default mode
	m_bDecryptMode = CBC; // default mode

	if(kvi_strEqualCIN("ecb:", szTmpEncryptKey.ptr(), 4) && (szTmpEncryptKey.len() > 4))
	{
		szTmpEncryptKey.cutLeft(4);
		m_bEncryptMode = ECB;
	}
	else if(kvi_strEqualCIN("old:", szTmpEncryptKey.ptr(), 4) && (szTmpEncryptKey.len() > 4))
	{
		szTmpEncryptKey.cutLeft(4);
		m_bEncryptMode = OldCBC;
	}
	else if(kvi_strEqualCIN("cbc:", szTmpEncryptKey.ptr(), 4) && (szTmpEncryptKey.len() > 4))
	{
		szTmpEncryptKey.cutLeft(4);
	}

	if(kvi_strEqualCIN("ecb:", szTmpDecryptKey.ptr(), 4) && (szTmpDecryptKey.len() > 4))
	{
		szTmpDecryptKey.cutLeft(4);
		m_bDecryptMode = ECB;
	}
	else if(kvi_strEqualCIN("old:", szTmpDecryptKey.ptr(), 4) && (szTmpDecryptKey.len() > 4))
	{
		szTmpDecryptKey.cutLeft(4);
		m_bDecryptMode = OldCBC;
	}
	else if(kvi_strEqualCIN("cbc:", szTmpDecryptKey.ptr(), 4) && (szTmpDecryptKey.len() > 4))
	{
		szTmpDecryptKey.cutLeft(4);
	}

	int defLen = getKeyLen();

	szTmpEncryptKey.padRight(defLen);
	szTmpDecryptKey.padRight(defLen);

	m_pEncryptCipher = new Rijndael();

	int retVal = m_pEncryptCipher->init(
	    (m_bEncryptMode == ECB) ? Rijndael::ECB : Rijndael::CBC,
	    Rijndael::Encrypt,
	    (unsigned char *)szTmpEncryptKey.ptr(),
	    getKeyLenId());
	if(retVal != RIJNDAEL_SUCCESS)
	{
		delete m_pEncryptCipher;
		m_pEncryptCipher = nullptr;
		setLastErrorFromRijndaelErrorCode(retVal);
		return false;
	}

	m_pDecryptCipher = new Rijndael();
	retVal = m_pDecryptCipher->init(
	    (m_bEncryptMode == ECB) ? Rijndael::ECB : Rijndael::CBC,
	    Rijndael::Decrypt,
	    (unsigned char *)szTmpDecryptKey.ptr(),
	    getKeyLenId());
	if(retVal != RIJNDAEL_SUCCESS)
	{
		delete m_pEncryptCipher;
		m_pEncryptCipher = nullptr;
		delete m_pDecryptCipher;
		m_pDecryptCipher = nullptr;
		setLastErrorFromRijndaelErrorCode(retVal);
		return false;
	}

	return true;
}
Example #12
0
bool KviConfigurationFile::load()
{
	// this is really faster than the old version :)

	// open the file
	KviFile f(m_szFileName);
	if(!f.open(QFile::ReadOnly)) return false;

	KviCString tmp;
	KviConfigurationFileGroup * p_group = 0;

	int iLoadBlockSize = LOAD_BLOCK_SIZE;

	char * buffer = (char *)KviMemory::allocate(iLoadBlockSize * sizeof(char));

	int toRead;
	int readedLen;
	int remainingLen = 0;

	char * p = buffer; // start writing to the beginning of the buffer

	do {
		// compute the length to read
		toRead = iLoadBlockSize - remainingLen;
		if(toRead < 1)
		{
			// ops... a string longer than iLoadBlockSize - 1 chars
			iLoadBlockSize += LOAD_BLOCK_SIZE;
			int iOffset = p - buffer;
			buffer = (char *)KviMemory::reallocate(buffer,iLoadBlockSize * sizeof(char));
			p = buffer + iOffset;
			toRead += LOAD_BLOCK_SIZE;
		}

		// do read
		readedLen = f.read(p,toRead);
		if(readedLen < toRead)
		{
			// check for errors
			if(readedLen <= 0)
			{
				if(readedLen < 0)
				{
					// error at all
					f.close();
					KviMemory::free(buffer);
					return true; // nothing more to parse anyway
				} else {
					// just a zero byte read
					if(remainingLen == 0)
					{
						// there was nothing in the buffer
						f.close(); // nothing to parse anyway
						KviMemory::free(buffer);
						return true;
					}
					// there is something in the buffer but we have readed 0 bytes
					// this usually means that the last line in the file has no trailing newline
					// ...we just fake it :)
					*p = '\n';
					readedLen = 1;
				}
			} else {
				// just readed something but less than expected
				// check if the last readed char is a newline
				// if it isn't, fake it
				if(*(p + readedLen - 1) != '\n')
				{
					*(p + readedLen) = '\n';
					readedLen++;
				}
			}
		}
		// compute the end pointer
		char * endp = p + readedLen;

		p = buffer; // start from beginning of the data buffer at all
		// begin of the current string
		char * begin = p;

		// and loop
		while(p < endp)
		{
			// find a newline
			if(*p != '\n')
			{
				p++;
				continue;
			}
			// newline!
			*p = 0;
			// now begin points to the string that terminates in p
			// skip leading whitespace
			while((*begin == '\t') || (*begin == ' '))begin++;

			if(p == begin)
			{
				// empty line
				p++;
				begin = p;
				continue;
			}
			// now p > begin
			// check if there are trailing spaces (include CR so CRLF is trimmed too)
			char * trail = p - 1;

			p++;

			while(trail >= begin)
			{
				if((*trail == '\r') || (*trail == '\t') || (*trail == ' '))*trail = 0;
				else break;
				trail--;
			}

			// yeah, have some data in this line :D
			switch(*begin)
			{
				case 0:
					// empty line
				break;
				case '#':
					// comment: just skip it
				break;
				case '[':
					// group ?
					begin++;
					if(*begin && (*begin != ']'))
					{
						char * z = begin;
#define COMPAT_WITH_OLD_CONFIGS
#ifdef COMPAT_WITH_OLD_CONFIGS
						// run to the end of the string
						while(*z)z++;
						// run back to the trailing ']'
						while((z > begin) && (*z != ']'))z--;
						// if it is not ther just run back to the end of the string
						if(*z != ']')while(*z)z++;
#else
						// new configs have it always encoded properly
						while(*z && (*z != ']'))z++;
#endif
						*z = 0;
						tmp.hexDecode(begin);
						tmp.stripRightWhiteSpace(); // no external spaces in group names

						if(!tmp.isEmpty())
						{
							QString szGroup = m_bLocal8Bit ?
								QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
								QString::fromUtf8(tmp.ptr(),tmp.len());
							p_group = m_pDict->find(szGroup);
							if(!p_group)
							{
								p_group = new KviConfigurationFileGroup(17,false);
								p_group->setAutoDelete(true);
								m_pDict->insert(szGroup,p_group);
							}
						}
					}
				break;
				default:
				{
					// real data ?
					char * z = begin;
					while(*z && (*z != '='))z++;
					if(*z && (z != begin))
					{
						*z = 0;
						tmp.hexDecode(begin);
						tmp.stripRightWhiteSpace(); // No external spaces at all in keys
						if(!tmp.isEmpty())
						{
							QString szKey =  m_bLocal8Bit ?
									QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
									QString::fromUtf8(tmp.ptr(),tmp.len());
							z++;
							while(*z && ((*z == ' ') || (*z == '\t')))z++;
							if(*z)
							{
								tmp.hexDecode(z);
								QString * pVal = new QString( m_bLocal8Bit ?
									QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
									QString::fromUtf8(tmp.ptr(),tmp.len())
									);
								if(!p_group)
								{
									// ops...we're missing a group
									// use the default one
									p_group = new KviConfigurationFileGroup(17,false);
									p_group->setAutoDelete(true);
									m_pDict->insert(KVI_CONFIG_DEFAULT_GROUP,p_group);
								}
								p_group->replace(szKey,pVal);
							} else {
								// we in fact need this (mercy :D)
								// otherwise the empty options will be treated as non-existing ones
								// and will get the defaults (which is bad)
								QString * pVal = new QString(QString());
								p_group->replace(szKey,pVal);
							}
						}
					}
				}
				break;
			}
			begin = p;
		}
		if(begin != endp)
		{
			// there is data with no trailing newline in the buffer
			remainingLen = endp-begin;
			if(buffer != begin)
			{
				KviMemory::move(buffer,begin,remainingLen);
				p = buffer + remainingLen;
			} // else p remains where it is
		} else {
			p = buffer;
		}
	} while(readedLen == toRead);

	f.close();
	KviMemory::free(buffer);
	return true;
}
Example #13
0
bool KviFile::save(const KviCString & szData)
{
	if(!save((kvi_u32_t)(szData.len())))
		return false;
	return (write(szData.ptr(), szData.len()) == (unsigned int)szData.len());
}