Beispiel #1
0
TEST(CClipboardTests, unmarshall_withTextSize285_getTextIsValid)
{
	CClipboard clipboard;

	// 285 chars
	CString text;
	text.append("Synergy is Free and Open Source Software that lets you ");
	text.append("easily share your mouse and keyboard between multiple ");
	text.append("computers, where each computer has it's own display. No ");
	text.append("special hardware is required, all you need is a local area ");
	text.append("network. Synergy is supported on Windows, Mac OS X and Linux.");

	CString data;
	data += (char)0;
	data += (char)0;
	data += (char)0;
	data += (char)1; // 1 format added
	data += (char)0;
	data += (char)0;
	data += (char)0;
	data += (char)IClipboard::kText;
	data += (char)0; // 285 >> 24 = 285 / (256^3) = 0
	data += (char)0; // 285 >> 16 = 285 / (256^2) = 0
	data += (char)1; // 285 >> 8 = 285 / (256^1) = 1(.11328125)
	data += (char)29; // 285 - 256 = 29
	data += text;

	clipboard.unmarshall(data, 0);

	clipboard.open(0);
	CString actual = clipboard.get(IClipboard::kText);
	EXPECT_EQ(text, actual);
}
void
CClient::writeToDropDirThread(void*)
{
	LOG((CLOG_DEBUG "starting write to drop dir thread"));

	while (m_screen->isFakeDraggingStarted()) {
		ARCH->sleep(.1f);
	}
	
	m_fileTransferDes = m_screen->getDropTarget();
	LOG((CLOG_DEBUG "dropping file, files=%i target=%s", m_dragFileList.size(), m_fileTransferDes.c_str()));

	if (!m_fileTransferDes.empty() && m_dragFileList.size() > 0) {
		std::fstream file;
		CString dropTarget = m_fileTransferDes;
#ifdef SYSAPI_WIN32
		dropTarget.append("\\");
#else
		dropTarget.append("/");
#endif
		dropTarget.append(m_dragFileList.at(0).getFilename());
		file.open(dropTarget.c_str(), std::ios::out | std::ios::binary);
		if (!file.is_open()) {
			// TODO: file open failed
		}
		
		file.write(m_receivedFileData.c_str(), m_receivedFileData.size());
		file.close();
	}
	else {
		LOG((CLOG_ERR "drop file failed: drop target is empty"));
	}
}
Beispiel #3
0
// TODO: there's some integer -> char encoding going on here. i find it 
// hard to believe that the clipboard is the only thing doing this. maybe
// we should refactor this stuff out of the clipboard.
TEST(CClipboardTests, marshall_withTextSize285_sizeCharsValid)
{
	// 285 chars
	CString data;
	data.append("Synergy is Free and Open Source Software that lets you ");
	data.append("easily share your mouse and keyboard between multiple ");
	data.append("computers, where each computer has it's own display. No ");
	data.append("special hardware is required, all you need is a local area ");
	data.append("network. Synergy is supported on Windows, Mac OS X and Linux.");

	CClipboard clipboard;
	clipboard.open(0);
	clipboard.add(IClipboard::kText, data);
	clipboard.close();

	CString actual = clipboard.marshall();

	// 4 asserts here, but that's ok because we're really just asserting 1 
	// thing. the 32-bit size value is split into 4 chars. if the size is 285
	// (29 more than the 8-bit max size), the last char "rolls over" to 29 
	// (this is caused by a bit-wise & on 0xff and 8-bit truncation). each 
	// char before the last stores a bit-shifted version of the number, each 
	// 1 more power than the last, which is done by bit-shifting [0] by 24, 
	// [1] by 16, [2] by 8 ([3] is not bit-shifted).
	EXPECT_EQ(0, actual[8]); // 285 >> 24 = 285 / (256^3) = 0
	EXPECT_EQ(0, actual[9]); // 285 >> 16 = 285 / (256^2) = 0
	EXPECT_EQ(1, actual[10]); // 285 >> 8 = 285 / (256^1) = 1(.11328125)
	EXPECT_EQ(29, actual[11]); // 285 - 256 = 29
}
Beispiel #4
0
CString
CArgParser::assembleCommand(std::vector<CString>& argsArray,  CString ignoreArg, int parametersRequired)
{
	CString result;

	for (std::vector<CString>::iterator it = argsArray.begin(); it != argsArray.end(); ++it) {
		if (it->compare(ignoreArg) == 0) {
			it = it + parametersRequired;
			continue;
		}

		// if there is a space in this arg, use double quotes surround it
		if ((*it).find(" ") != CString::npos) {
			(*it).insert(0, "\"");
			(*it).push_back('\"');
		}

		result.append(*it);
		// add space to saperate args
		result.append(" ");
	}

	if (!result.empty()) {
		// remove the tail space
	  	result = result.substr(0, result.size() - 1);
	}

	return result;
}
Beispiel #5
0
	void ListCommand(const CString& sLine)
	{
		CString output = "The following aliases exist:";
		MCString::iterator i = BeginNV();
		if (i == EndNV()) output += " [none]";
		for (; i != EndNV(); ++i)
		{
			output.append(" ");
			output.append(i->first);
		}
		PutModule(output);
	}
int
CDragInformation::setupDragInfo(CDragFileList& fileList, CString& output)
{
	int size = fileList.size();
	for (int i = 0; i < size; ++i) {
		output.append(fileList.at(i).getFilename());
		output.append(",");
		CString filesize = getFileSize(fileList.at(i).getFilename());
		output.append(filesize);
		output.append(",");
	}
	return size;
}
Beispiel #7
0
	// read an IRC line and do token substitution
	// throws an exception if a required parameter is missing, and might also throw if you manage to make it bork
	CString Imprint(CString line) const
	{
		CString output;
		CString alias_data = GetCommands();
		alias_data = parent->ExpandString(alias_data);
		size_t lastfound = 0, skip = 0;

		// it would be very inefficient to attempt to blindly replace every possible token
		// so let's just parse the line and replace when we find them
		// token syntax:
		// %[?]n[+]%
		// adding ? makes the substitution optional (you'll get "" if there are insufficient tokens, otherwise the alias will fail)
		// adding + makes the substitution contain all tokens from the nth to the end of the line
		while (true)
		{
			// if (found >= (int) alias_data.length()) break; 		// shouldn't be possible.
			size_t found = alias_data.find("%", lastfound + skip);
			if (found == CString::npos) break; 				// if we found nothing, break
			output.append(alias_data.substr(lastfound, found - lastfound));	// capture everything between the last stopping point and here
			ParseToken(alias_data, line, output, found, skip);				// attempt to read a token, updates indices based on success/failure
			lastfound = found;
		}

		output += alias_data.substr(lastfound); // append from the final 
		return output;
	}
Beispiel #8
0
	// this function helps imprint out.  it checks if there is a substitution token at 'caret' in 'alias_data'
	// and if it finds one, pulls the appropriate token out of 'line' and appends it to 'output', and updates 'caret'.
	// 'skip' is updated based on the logic that we should skip the % at the caret if we fail to parse the token.
	static void ParseToken(const CString &alias_data, const CString &line, CString &output, size_t &caret, size_t &skip)
	{
		bool optional = false;
		bool subsequent = false;
		size_t index = caret + 1;
		int token = -1;

		skip = 1;

		if (alias_data.length() > index && alias_data[index] == '?') { optional = true; ++index; }			// try to read optional flag
		if (alias_data.length() > index && CString(alias_data.substr(index)).Convert(&token))				// try to read integer
		{
			while(alias_data.length() > index && alias_data[index] >= '0' && alias_data[index] <= '9') ++index;	// skip any numeric digits in string
		}														// (supposed to fail if whitespace precedes integer)
		else return;													// token was malformed. leave caret unchanged, and flag first character for skipping
		if (alias_data.length() > index && alias_data[index] == '+') { subsequent = true; ++index; }			// try to read subsequent flag
		if (alias_data.length() > index && alias_data[index] == '%') { ++index; }					// try to read end-of-substitution marker
		else return;

		CString stok = line.Token(token, subsequent, " ");								// if we get here, we're definitely dealing with a token, so get the token's value
		if (stok.empty() && !optional)
			throw std::invalid_argument(CString("missing required parameter: ") + CString(token));			// blow up if token is required and also empty
		output.append(stok);												// write token value to output

		skip = 0;													// since we're moving the cursor after the end of the token, skip no characters
		caret = index;													// advance the cursor forward by the size of the token
	}
Beispiel #9
0
int RageFile::Read( CString &buffer, int bytes )
{
	buffer.erase( buffer.begin(), buffer.end() );
	buffer.reserve( bytes != -1? bytes: this->GetFileSize() );

	int ret = 0;
	char buf[4096];
	while( bytes == -1 || ret < bytes )
	{
		int ToRead = sizeof(buf);
		if( bytes != -1 )
			ToRead  = min( ToRead, bytes-ret );

		const int got = Read( buf, ToRead );
		if( got == 0 )
			break;
		if( got == -1 )
			return -1;

		buffer.append( buf, got );
		ret += got;
	}

	return ret;
}
Beispiel #10
0
int RageFileObj::Read( CString &sBuffer, int iBytes )
{
	sBuffer.erase( sBuffer.begin(), sBuffer.end() );
	sBuffer.reserve( iBytes != -1? iBytes: this->GetFileSize() );

	int iRet = 0;
	char buf[4096];
	while( iBytes == -1 || iRet < iBytes )
	{
		int ToRead = sizeof(buf);
		if( iBytes != -1 )
			ToRead  = min( ToRead, iBytes-iRet );

		const int iGot = Read( buf, ToRead );
		if( iGot == 0 )
			break;
		if( iGot == -1 )
			return -1;

		sBuffer.append( buf, iGot );
		iRet += iGot;
	}

	return iRet;
}
Beispiel #11
0
	CString MakeIvec() {
		CString sRet;
		time_t t;
		time(&t);
		int r = rand();
		sRet.append((char*) &t, 4);
		sRet.append((char*) &r, 4);

		return sRet;
	}
Beispiel #12
0
void
COSXKeyState::fixStickyKeys()
{
	KeyModifierMask synergyMask = getActiveModifiers();
	KeyModifierMask hardwareMask = pollActiveModifiers();
	if (synergyMask != hardwareMask) {
		
		// modifier key stuck
		// compute changed modifiers
		KeyModifierMask changed = (hardwareMask ^ synergyMask);
		
		if (changed) {
			KeyButton kb;
			CString keyFixed;
			// synthesize changed modifier keys
			if ((changed & KeyModifierShift) != 0) {
				kb = mapVirtualKeyToKeyButton(s_shiftVK);
				fakeKeyUp(kb);
				keyFixed.append("shift ");
			}
			if ((changed & KeyModifierControl) != 0) {
				kb = mapVirtualKeyToKeyButton(s_controlVK);
				fakeKeyUp(kb);
				keyFixed.append("ctrl ");
			}
			if ((changed & KeyModifierAlt) != 0) {
				kb = mapVirtualKeyToKeyButton(s_altVK);
				fakeKeyUp(kb);
				keyFixed.append("alt ");
			}
			if ((changed & KeyModifierSuper) != 0) {
				kb = mapVirtualKeyToKeyButton(s_superVK);
				fakeKeyUp(kb);
				keyFixed.append("cmd ");
			}
			
			LOG((CLOG_DEBUG "fixed stuck modifier key: %s", keyFixed.c_str()));
		}
	}
}
Beispiel #13
0
void CDCCSock::ReadData(const char* data, size_t len) {
    if (!m_pFile) {
        DEBUG("File not open! closing get.");
        if (m_bSend) {
            m_pModule->PutModule(t_f("Sending [{1}] to [{2}]: File not open!")(
                m_sFileName, m_sRemoteNick));
        } else {
            m_pModule->PutModule(
                t_f("Receiving [{1}] from [{2}]: File not open!")(
                    m_sFileName, m_sRemoteNick));
        }
        Close();
        return;
    }

    // DCC specs says the receiving end sends the number of bytes it
    // received so far as a 4 byte integer in network byte order, so we need
    // uint32_t to do the job portably. This also means that the maximum
    // file that we can transfer is 4 GiB big (see OpenFile()).
    if (m_bSend) {
        m_sSendBuf.append(data, len);

        while (m_sSendBuf.size() >= 4) {
            uint32_t iRemoteSoFar;
            memcpy(&iRemoteSoFar, m_sSendBuf.data(), sizeof(iRemoteSoFar));
            iRemoteSoFar = ntohl(iRemoteSoFar);

            if ((iRemoteSoFar + 65536) >= m_uBytesSoFar) {
                SendPacket();
            }

            m_sSendBuf.erase(0, 4);
        }
    } else {
        m_pFile->Write(data, len);
        m_uBytesSoFar += len;
        uint32_t uSoFar = htonl((uint32_t)m_uBytesSoFar);
        Write((char*)&uSoFar, sizeof(uSoFar));

        if (m_uBytesSoFar >= m_uFileSize) {
            Close();
        }
    }
}
Beispiel #14
0
	void ShowCommand(const CString& sCommand) {
		map< CString, vector< CString> > msvOutput;
		for (u_int a = 0; a < m_vMessages.size(); a++) {
			CString sTime = m_vMessages[a].Token(0, false, ":");
			CString sWhom = m_vMessages[a].Token(1, false, ":");
			CString sMessage = m_vMessages[a].Token(2, true, ":");

			if ((sTime.empty()) || (sWhom.empty()) || (sMessage.empty())) {
				// illegal format
				PutModule("Corrupt message! [" + m_vMessages[a] + "]");
				m_vMessages.erase(m_vMessages.begin() + a--);
				continue;
			}

			time_t iTime = sTime.ToULong();
			char szFormat[64];
			struct tm t;
			localtime_r(&iTime, &t);
			size_t iCount = strftime(szFormat, 64, "%F %T", &t);

			if (iCount <= 0) {
				PutModule("Corrupt time stamp! [" + m_vMessages[a] + "]");
				m_vMessages.erase(m_vMessages.begin() + a--);
				continue;
			}

			CString sTmp = "    " + CString(a) + ") [";
			sTmp.append(szFormat, iCount);
			sTmp += "] ";
			sTmp += sMessage;
			msvOutput[sWhom].push_back(sTmp);
		}

		for (map< CString, vector< CString> >::iterator it = msvOutput.begin(); it != msvOutput.end(); ++it) {
			PutModule(it->first);
			for (u_int a = 0; a < it->second.size(); a++)
				PutModule(it->second[a]);
		}

		PutModule("#--- End Messages");
	}
Beispiel #15
0
bool CFile::ReadFile(CString& sData, size_t iMaxSize) {
	char buff[4096];
	size_t iBytesRead = 0;

	sData.clear();

	while (iBytesRead < iMaxSize) {
		ssize_t iBytes = Read(buff, sizeof(buff));

		if (iBytes < 0)
			// Error
			return false;

		if (iBytes == 0)
			// EOF
			return true;

		sData.append(buff, iBytes);
		iBytesRead += iBytes;
	}

	// Buffer limit reached
	return false;
}
void
CXWindowsClipboard::icccmFillCache()
{
	LOG((CLOG_DEBUG "ICCCM fill clipboard %d", m_id));

	// see if we can get the list of available formats from the selection.
	// if not then use a default list of formats.  note that some clipboard
	// owners are broken and report TARGETS as the type of the TARGETS data
	// instead of the correct type ATOM;  allow either.
	const Atom atomTargets = m_atomTargets;
	Atom target;
	CString data;
	if (!icccmGetSelection(atomTargets, &target, &data) ||
		(target != m_atomAtom && target != m_atomTargets)) {
		LOG((CLOG_DEBUG1 "selection doesn't support TARGETS"));
		data = "";

		target = XA_STRING;
		data.append(reinterpret_cast<char*>(&target), sizeof(target));
	}

	const Atom* targets = reinterpret_cast<const Atom*>(data.data());
	const UInt32 numTargets = data.size() / sizeof(Atom);
	LOG((CLOG_DEBUG "  available targets: %s", CXWindowsUtil::atomsToString(m_display, targets, numTargets).c_str()));

	// try each converter in order (because they're in order of
	// preference).
	for (ConverterList::const_iterator index = m_converters.begin();
								index != m_converters.end(); ++index) {
		IXWindowsClipboardConverter* converter = *index;

		// skip already handled targets
		if (m_added[converter->getFormat()]) {
			continue;
		}

		// see if atom is in target list
		Atom target = None;
		for (UInt32 i = 0; i < numTargets; ++i) {
			if (converter->getAtom() == targets[i]) {
				target = targets[i];
				break;
			}
		}
		if (target == None) {
			continue;
		}

		// get the data
		Atom actualTarget;
		CString targetData;
		if (!icccmGetSelection(target, &actualTarget, &targetData)) {
			LOG((CLOG_DEBUG1 "  no data for target %s", CXWindowsUtil::atomToString(m_display, target).c_str()));
			continue;
		}

		// add to clipboard and note we've done it
		IClipboard::EFormat format = converter->getFormat();
		m_data[format]  = converter->toIClipboard(targetData);
		m_added[format] = true;
		LOG((CLOG_DEBUG "  added format %d for target %s (%u %s)", format, CXWindowsUtil::atomToString(m_display, target).c_str(), targetData.size(), targetData.size() == 1 ? "byte" : "bytes"));
	}
}
Beispiel #17
0
void CLanguage::LoadFile ( const CString& szLangName, const CString& szEntryName )
{
    CString szPath ( "../lang/%s/%s.txt", szLangName.c_str (), szEntryName.c_str () );

    FILE* fp;
#ifdef WIN32
    fopen_s ( &fp, szPath.c_str (), "r" );
#else
    fp = fopen ( szPath.c_str (), "r" );
#endif
    if ( !fp )
        return;

    CString szCurTopic;
    CString szCurTopicName;
    char szBuffer [ 4096 ];
    char* p;

    t_topicMap* map = new t_topicMap ( );
    map->set_deleted_key ( (char*)HASH_STRING_DELETED );
    map->set_empty_key ( (char*)HASH_STRING_EMPTY );

    char* szKey = strdup ( szEntryName.c_str () );
    m_entriesMap.insert ( t_entriesMap::value_type ( szKey, map ) );

    while ( !feof ( fp ) )
    {
        fgets ( szBuffer, sizeof ( szBuffer ), fp );
        p = szBuffer + strlen ( szBuffer ) - 1;
        while ( p >= szBuffer && ( *p == '\r' || *p == '\n' ) )
        {
            *p = '\0';
            --p;
        }

        if ( *p == '#' )
        {
            // Es un comentario
            continue;
        }

        if ( *p == '%' && szBuffer [ 0 ] == '%' )
        {
            if ( p > szBuffer + 1 )
            {
                // Inicio de un tema
                szCurTopic.clear ();
                *p = '\0';
                szCurTopicName = szBuffer + 1;
            }
            else
            {
                // Fin de un tema
                if ( szCurTopicName.length () > 0 )
                {
                    char* szKey = strdup ( szCurTopicName.c_str () );
                    map->insert ( t_topicMap::value_type ( szKey, szCurTopic ) );
                }
                szCurTopicName.clear ();
            }
        }
        else
        {
            szCurTopic.append ( szBuffer );
            szCurTopic.append ( "\n" );
        }
    }

    fclose ( fp );
}
Beispiel #18
0
CString
CStringUtil::vformat(const char* fmt, va_list args)
{
	// find highest indexed substitution and the locations of substitutions
	std::vector<size_t> pos;
	std::vector<size_t> width;
	std::vector<int> index;
	int maxIndex = 0;
	for (const char* scan = fmt; *scan != '\0'; ++scan) {
		if (*scan == '%') {
			++scan;
			if (*scan == '\0') {
				break;
			}
			else if (*scan == '%') {
				// literal
				index.push_back(0);
				pos.push_back(static_cast<int>(scan - 1 - fmt));
				width.push_back(2);
			}
			else if (*scan == '{') {
				// get argument index
				char* end;
				int i = static_cast<int>(strtol(scan + 1, &end, 10));
				if (*end != '}') {
					// invalid index -- ignore
					scan = end - 1;
				}
				else {
					index.push_back(i);
					pos.push_back(static_cast<int>(scan - 1 - fmt));
					width.push_back(static_cast<int>(end - scan + 2));
					if (i > maxIndex) {
						maxIndex = i;
					}
					scan = end;
				}
			}
			else {
				// improper escape -- ignore
			}
		}
	}

	// get args
	std::vector<const char*> value;
	std::vector<size_t> length;
	value.push_back("%");
	length.push_back(1);
	for (int i = 0; i < maxIndex; ++i) {
		const char* arg = va_arg(args, const char*);
		size_t len = strlen(arg);
		value.push_back(arg);
		length.push_back(len);
	}

	// compute final length
	size_t resultLength = strlen(fmt);
	const int n = static_cast<int>(pos.size());
	for (int i = 0; i < n; ++i) {
		resultLength -= width[i];
		resultLength += length[index[i]];
	}

	// substitute
	CString result;
	result.reserve(resultLength);
	size_t src = 0;
	for (int i = 0; i < n; ++i) {
		result.append(fmt + src, pos[i] - src);
		result.append(value[index[i]]);
		src = pos[i] + width[i];
	}
	result.append(fmt + src);

	return result;
}
Beispiel #19
0
void FormatLogMessage(ELogMessageType type,
                      ELogMessageLevel nLevel,
                      LPCTSTR pszDate,
                      LPCTSTR pszTime,
                      LPCTSTR pszThreadId,
                      LPCTSTR pszThreadName,
                      LPCTSTR pszModule,
                      LPCTSTR pszMessage,
                      CString& output)
{
#if 1
    output.Empty();
    output.Preallocate(1024);

    if (type != eLM_DirectOutput)
    {
        output += pszDate;
        output += _T(' ');
        output += pszTime;
#if defined(LOG_THREAD_NAME)
        output += _T(" [");
        output += pszThreadId;
        output += _T(":");
        size_t nThreadNameLen = _tcslen(pszThreadName);
        if (nThreadNameLen > 12)
            output.append(pszThreadName, 12);
        else
        {
            output.append(12 - nThreadNameLen, _T(' '));
            output += pszThreadName;
        }
        output += _T("] ");
#else
        output += _T(" ");
#endif

        switch (type)
        {
        case eLM_Info:
            output += _T('I');
            break;
        case eLM_Debug:
            output += _T('-');
            break;
        case eLM_Warning:
            output += _T('W');
            break;
        case eLM_Error:
            output += _T('E');
            break;
        default:
            ASSERT(false);
        }

        if (nLevel>0)
            output.AppendFormat(_T("%i"), nLevel);
        else
            output += _T(' ');
#if 0
        output += _T(" : [");
        output += pszModule;
        output += _T("] ");
#else
        output += _T(" : ");
#endif
    }
    output += pszMessage;
    output.TrimRight();
#else
    output.Empty();
    output.reserve(1024);

    output += pszDate;
    output += _T(' ');
    output += pszTime;
    output += _T("\t");
    output += pszThreadId;
    output += _T("\t");
    output += pszThreadName;
    output += _T("\t");
    output += pszModule;
    output += _T("\t");

    switch (type)
    {
    case eLM_Info:
        output += _T("Inf");
        break;
    case eLM_Debug:
        output += _T("Dbg");
        break;
    case eLM_Warning:
        output += _T("Wrn");
        break;
    case eLM_Error:
        output += _T("Err");
        break;
    default:
        ASSERT(false);
    }

    if (nLevel>0)
        output.AppendFormat(_T("%i"), nLevel);
    output += _T('\t');
    output += pszMessage;
    output.TrimRight();
#endif
}
Beispiel #20
0
	virtual void OnModCommand(const CString& sCommand)
	{
		CString sCmdName = sCommand.Token(0);
		if (sCmdName == "away")
		{
			CString sReason;
			if (sCommand.Token(1) != "-quiet")
			{
				sReason = sCommand.Token(1, true);
				PutModNotice("You have been marked as away", "away");
			}
			else
				sReason = sCommand.Token(2, true);
			Away(false, sReason);
		}
		else if (sCmdName == "back")
		{
			if ((m_vMessages.empty()) && (sCommand.Token(1) != "-quiet"))
				PutModNotice("Welcome Back!", "away");
			Back();
		}
		else if (sCmdName == "messages")
		{
			for (u_int a = 0; a < m_vMessages.size(); a++)
				PutModule(m_vMessages[a], "away");
		}
		else if (sCmdName == "delete")
		{
			CString sWhich = sCommand.Token(1);
			if (sWhich == "all")
			{
				PutModNotice("Deleted " + CString(m_vMessages.size()) + " Messages.", "away");
				for (u_int a = 0; a < m_vMessages.size(); a++)
					m_vMessages.erase(m_vMessages.begin() + a--);

			}
			else if (sWhich.empty())
			{
				PutModNotice("USAGE: delete <num|all>", "away");
				return;
			} else
			{
				u_int iNum = sWhich.ToUInt();
				if (iNum >= m_vMessages.size())
				{
					PutModNotice("Illegal Message # Requested", "away");
					return;
				}
				else
				{
					m_vMessages.erase(m_vMessages.begin() + iNum);
					PutModNotice("Message Erased.", "away");
				}
				SaveBufferToDisk();
			}
		}
		else if (sCmdName == "save" && m_saveMessages)
		{
			SaveBufferToDisk();
			PutModNotice("Messages saved to disk.", "away");
		}
		else if (sCmdName == "ping")
		{
			Ping();
			if (m_bIsAway)
				Back();
		}
		else if (sCmdName == "pass")
		{
			m_sPassword = sCommand.Token(1);
			PutModNotice("Password Updated to [" + m_sPassword + "]");
		}
		else if (sCmdName == "show")
		{
			map< CString, vector< CString> > msvOutput;
			for (u_int a = 0; a < m_vMessages.size(); a++)
			{
				CString sTime = m_vMessages[a].Token(0, false, ":");
				CString sWhom = m_vMessages[a].Token(1, false, ":");
				CString sMessage = m_vMessages[a].Token(2, true, ":");

				if ((sTime.empty()) || (sWhom.empty()) || (sMessage.empty()))
				{
					// illegal format
					PutModule("Corrupt message! [" + m_vMessages[a] + "]", "away");
					m_vMessages.erase(m_vMessages.begin() + a--);
					continue;
				}
				time_t iTime = sTime.ToULong();
				char szFormat[64];
				struct tm t;
				localtime_r(&iTime, &t);
				size_t iCount = strftime(szFormat, 64, "%Y-%m-%d %H:%M:%S", &t);
				if (iCount <= 0)
				{
					PutModule("Corrupt time stamp! [" + m_vMessages[a] + "]", "away");
					m_vMessages.erase(m_vMessages.begin() + a--);
					continue;
				}
				CString sTmp = "    " + CString(a) + ") [";
				sTmp.append(szFormat, iCount);
				sTmp += "] ";
				sTmp += sMessage;
				msvOutput[sWhom].push_back(sTmp);
			}
			for (map< CString, vector< CString> >::iterator it = msvOutput.begin(); it != msvOutput.end(); ++it)
			{
				PutModule(it->first, "away");
				for (u_int a = 0; a < it->second.size(); a++)
					PutModule(it->second[a]);
			}
			PutModule("#--- End Messages", "away");
		} else if (sCmdName == "enabletimer")
		{
			SetAwayTime(300);
			PutModule("Timer set to 300 seconds");
		} else if (sCmdName == "disabletimer")
		{
			SetAwayTime(0);
			PutModule("Timer disabled");
		} else if (sCmdName == "settimer")
		{
			int iSetting = sCommand.Token(1).ToInt();

			SetAwayTime(iSetting);

			if (iSetting == 0)
				PutModule("Timer disabled");
			else
				PutModule("Timer set to " + CString(iSetting) + " seconds");

		} else if (sCmdName == "timer")
		{
			PutModule("Current timer setting: " + CString(GetAwayTime()) + " seconds");
		} else
		{
			PutModule("Commands: away [-quiet], back [-quiet], delete <num|all>, ping, show, save, enabletimer, disabletimer, settimer <secs>, timer", "away");
		}
	}
Beispiel #21
0
/* Read up to the next \n, and return it in out.  Strip the \n.  If the \n is
 * preceded by a \r (DOS newline), strip that, too. */
int RageFile::GetLine( CString &out )
{
	out = "";

    if ( !IsOpen() )
        RageException::Throw("\"%s\" is not open.", m_Path.c_str());

	if( !(m_Mode&READ) )
		RageException::Throw("\"%s\" is not open for reading", GetPath().c_str());

	if( m_EOF )
		return 0;

	bool GotData = false;
	while( 1 )
	{
		bool done = false;

		/* Find the end of the block we'll move to out. */
		char *p = (char *) memchr( m_pBuf, '\n', m_BufAvail );
		bool ReAddCR = false;
		if( p == NULL )
		{
			/* Hack: If the last character of the buffer is \r, then it's likely that an
			 * \r\n has been split across buffers.  Move everything else, then move the
			 * \r to the beginning of the buffer and handle it the next time around the loop. */
			if( m_BufAvail && m_pBuf[m_BufAvail-1] == '\r' )
			{
				ReAddCR = true;
				--m_BufAvail;
			}

			p = m_pBuf+m_BufAvail; /* everything */
		}
		else
			done = true;

		if( p >= m_pBuf )
		{
			char *RealEnd = p;
			if( done && p > m_pBuf && p[-1] == '\r' )
				--RealEnd; /* not including \r */
			out.append( m_pBuf, RealEnd );

			if( done )
				++p; /* skip \n */

			const int used = p-m_pBuf;
			if( used )
			{
				m_BufAvail -= used;
				m_FilePos += used;
				GotData = true;
				m_pBuf = p;
			}
		}

		if( ReAddCR )
		{
			ASSERT( m_BufAvail == 0 );
			m_pBuf = m_Buffer;
			m_Buffer[m_BufAvail] = '\r';
			++m_BufAvail;
		}

		if( done )
			break;

		/* We need more data. */
		m_pBuf = m_Buffer;

		const int size = FillBuf();

		/* If we've read data already, then don't mark EOF yet.  Wait until the
		 * next time we're called. */
		if( size == 0 && !GotData )
		{
			m_EOF = true;
			return 0;
		}
		if( size == -1 )
			return -1; // error
		if( size == 0 )
			break; // EOF or error
	}
	return GotData? 1:0;
}