void NewsAccount::GetList()
{
	char* request = "LIST\r\n";
	m_pSocket->Write(request, strlen(request));
	StringA response = m_pSocket->ReadLine();

	while (1)
	{
		StringA line = m_pSocket->ReadLine();
		if (!strcmp(line.c_str(), "."))
		{
			break;
		}

		char group[1024];
		int last;
		int first;
		char p;
		sscanf(line.c_str(), "%s", group, &last, &first, &p);

		TRACE("%s\n", group);

		Record pRecord = m_list.NewRecord();

		pRecord.get_Fields()[1].SetData(group);

		pRecord.Update();
	}
}
void NewsAccount::Connect()
{
	int port = 119;
	m_pSocket = new NNTPClient;
	m_pSocket->Create();
	m_pSocket->Connect(m_server.c_str(), port);

	{
		StringA response = m_pSocket->ReadLine();
	}
};
	StringA ReadLine()
	{
		StringA str;

		while (1)
		{
			char c;
			if (Read(&c, 1) != 1)
				break;
			if (c == '\r')
			{
				char c2;
				if (Read(&c2, 1) != 1)
					break;
				if (c2 == '\n')
				{
					break;
				}
				else
				{
					/*
					if (str.length() == 512)
						throw -1;
						*/
					str += c;

					/*
					if (str.length() == 512)
						throw -1;
						*/
					str += c2;
				}
			}
			else
			{
				/*
				if (str.length() == 4096)
					throw -1;
					*/
				str += c;
			}
		}

		TRACE("%s\n", str.c_str());
		return str;
	}
示例#4
0
int main(int argc, char* argv[])
{
	printf("main()\n");

#if WIN32
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/ncrt0.o"));
	//linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/main.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libui.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libdraw.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libxmlparse.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/liblfc.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
//	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));
#else


	if (true)
	{
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o"));

		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/LDebugger.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/mainfrm.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEdit.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEditFrame.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DisassemblyWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/WatchWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/CallStackWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/FileDialog.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DebugSession.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));

		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));
	}
	else
	{
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o"));

		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));

		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));

		/*
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
		linker.m_files.push_back(new StringA("WINHD_C:/MMStudio/Amiga68k/main.o"));
		linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnixmain.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libstubs.a"));
		*/
	}
#endif

	printf("pass1\n");
	linker.pass1();

/*
	GlobalSymbol* pSymbol = linker.m_globsyms[new StringA("_main")];
	pSymbol->m_defined = true;
	pSymbol->ResolvedValue = (DWORD)MyMain;
*/
//	linker.AddSymbol(new StringA("_main"), (DWORD)MyMain);

	printf("loading first object file\n");
#if 1
	linker.LoadObjectFile(linker.m_objectFiles[0]);
	if (true)
	{
		for (int i = 1; i < linker.m_objectFiles.size(); i++)
		{
			printf("loading %d object file\n", i);
			linker.LoadObjectFile(linker.m_objectFiles[i]);
		}
	}

	printf("Here\n");
	TRACE("\n\n");

	{
		for (int i = 0; i < linker.m_loadedObjectFiles.size(); i++)
		{
			OFile2* ofile = linker.m_loadedObjectFiles[i];

			if (ofile->m_afilename)
				TRACE("%s:%s\n", ofile->m_afilename->c_str(), ofile->m_ofilename->c_str());
			else
				TRACE("%s\n", ofile->m_ofilename->c_str());
		}
	}
#endif

	printf("before sets\n");

	linker.sets();

	printf("LoadObjectfile2\n");

	OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]);

	if (true)
	{
		for (int i = 1; i < linker.m_objectFiles.size(); i++)
		{
			linker.LoadObjectFile2(linker.m_objectFiles[i]);
		}
	}

/*
	{
		GlobalSymbol* psym = linker.m_globsyms[new StringA("_DOSBase")];
		int x = *(long*)psym->ResolvedValue;
	}
*/
	printf("done\n");

	if (linker.m_undefinedReferenceCount)
	{
		printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
		TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
	}
	else
	{
#if AMIGA
		GlobalSymbol* sym = linker.m_globsyms[new StringA("_plinker")];
		ASSERT(sym);
		ASSERT(sym->m_syms.size());

		*(Linker**)sym->m_syms[0]->ResolvedValue = &linker;
#endif

#if WIN32
		/*
		{
			gsymmap_t::iterator it2 = linker.m_globsyms.begin();
			while (it2 != linker.m_globsyms.end())
			{
// "__ZTI14red_black_nodeIPN6System7StringAEPNS0_9NamespaceEE"

				GlobalSymbol* sym = (*it2).second;
				if (strstr(sym->m_name->c_str(), "TI") && strstr(sym->m_name->c_str(), "red_black_node") && strstr(sym->m_name->c_str(), "StringA"))
				{
					MessageBeep(-1);
				}

				++it2;
			}
		}
		*/

		TypeArchive* ar = new TypeArchive(TypeArchive::Mode_Load, new FileByteStream(new StringA("C:/test.typeinfo"), FileMode_Read));

		int ntypes;
		*ar >> ntypes;

		printf("%d\n", ntypes);

		for (int i = 0; i < ntypes; i++)
		{
			NamedType* pType;
			*ar >> pType;

			BufferImp<char> buffer;
			StringBuilderA strbuilder(&buffer);
			pType->Write(strbuilder);
			pType->m_qname = buffer.DetachToString();

			if (*pType->m_qname == "second_argument_type")
			{
				MessageBeep(-1);
			}

			//if (pType->m_qname)
			{
				StringBuilderA strbuilder(&buffer);
				strbuilder << "__ZTI";	// type info

				Mangler mangler;
				mangler.MangleType(pType, strbuilder);

				StringA* name = buffer.DetachToString();

				gsymmap_t::iterator it2 = linker.m_globsyms.find(name);
				//map<StringA*, DWORD, Ref_Less<StringA> >::iterator it2 = symbols.find(name);
				if (it2 != linker.m_globsyms.end())
				{
					GlobalSymbol* globsym = (*it2).second;

					//TRACE("%s\n", name->c_str());

					if (!strcmp(globsym->m_name->c_str(), "__ZTI9IAddChild"))
					{
						MessageBeep(-1);

					}

					for (int j = 0; j < globsym->m_syms.size(); j++)
					{
						Symbol* sym = globsym->m_syms[j];

					}

#if AMIGA
					__type_info2* ti = (__type_info2*)sym->ResolvedValue;
					printf("%s\n", ti->__type_name);

				//	int len = strlen(ti->__type_name);
						/*
						char* newname = malloc(len+1+4);
						strcpy(newname+4, ti->__type_name);
						ti->__type_name = newname+4;
						*(Type**)newname = pType;
						*/
#endif
#if 0
					TypeDescriptor* typedesc = (TypeDescriptor*)(*it2).second;

					//VERIFY(typedesc->_m_data == NULL);

					if (pType->GetKind() == type_class)
					{
						((ClassType*)pType)->m_typedesc = (Type_Info*)typedesc;
					}
					else if (pType->GetKind() == type_enum)
					{
						((EnumType*)pType)->m_typedesc = (Type_Info*)typedesc;
					}

					typedesc->_m_data = pType2;

					AddPersistentLiveRoot((Object**)&typedesc->_m_data);
#endif
				}
				else
				{
					TRACE("-----%s\n", name->c_str());
				}
			}
		}
#endif

	{
#if 1
		ULONG heapsize = heap->m_next - (heap->m_data);
#else
		ULONG heapsize = heap->m_next - (heap->m_data+heap->m_size);
#endif

		printf("heapsize: %f MB\n", heapsize / (1024.0*1024));
	}

	#if AMIGA

		printf("Calling");

		char* line = strdup("programname parameter0 parameter1");
		entrypoint_hook(pOFile->m_textdata, line, strlen(line));
	#endif
	}

#if 0
	if (argc <= 1)
	{
		printf("Usage:\n");
		printf("loader objectfile\n");
		return -10;
	}

	Linker linker;

	for (int i = 1; i < argc; i++)
	{
		linker.m_files.Add(new StringA(argv[i]));
	}

	printf("pass1...");
	linker.pass1();
//	linker.pass2();

	/*
	GlobalSymbol* globsym = linker.globsyms["_main2"];

	FileByteStream file(globsym->m_filename);
	linker.LoadObjectFile(file);

	printf("Calling...");
	((dllentrypoint)globsym->Value)();
	printf("done\n");
	*/

	printf("done\n");

	printf("loading...");
	fflush(stdout);

//	FileByteStream* file = new FileByteStream(linker.m_files[0]);
//	printf("sdfsdf\n");
//	fflush(stdout);
	linker.LoadObjectFile(linker.m_objectFiles[0]);

	linker.sets();

	OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]);

	printf("done\n");

	if (linker.m_undefinedReferenceCount)
	{
		printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
		TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
	}
	else
	{
	#if AMIGA
		char* line = strdup("programname parameter0 parameter1");
		entrypoint_hook(pOFile->m_textdata, line, strlen(line));
	#endif
	}
#endif

	return 0;
}
示例#5
0
void CallStackWnd::OnRender(UI::Graphics* pGraphics)
{
//	HFONT hOldFont = dc.SelectFont((HFONT)GetStockObject(ANSI_FIXED_FONT));

	{
		LDraw::SolidBrush* brush = new LDraw::SolidBrush(LDraw::Color(255, 255, 255));
		pGraphics->FillRectangle(brush, 0, 0, m_computedSize.Width, m_computedSize.Height);
	}

	for (int i = 0; i < m_callstack.size(); i++)
	{
		DebugFrame* pDebugFrame = m_callstack[i];

	//	if (m_pFrame->m_Eip >= line->u.instr.address && m_pFrame->m_Eip < line->u.instr.address+line->u.instr.nbytes)
	//	{
	//	}
		if (i == 0)
		{
			DrawYellowArrow(pGraphics, i*16 + 8);
		}

		if (m_selected == i)
		{
			if (i != 0)
			{
				DrawGreenArrow(pGraphics, i*16 + 8);
			}
		}

		pGraphics->DrawString(pDebugFrame->m_str, GetFont(), LDraw::PointF(14, i*16), new LDraw::SolidBrush(LDraw::Color::Black));
	}

//	dc.SelectFont(hOldFont);

#if 0
	if (g_pt)
	{
		if (m_pFrame->m_ctx && m_pFrame->m_ctx->m_pDebugProcess && !m_pFrame->m_ctx->m_pDebugProcess->m_bRunning)
		{
			HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pFrame->m_dwProcessId);

			int n = 0;
		//	DWORD eip = g_pt->m_context.Eip;
		//	DWORD ebp = g_pt->m_context.Ebp;

			STACK_FRAME frame;
			frame.Ebp = (STACK_FRAME*)g_pt->m_context.Ebp;
			frame.Ret_Addr = (PBYTE)g_pt->m_context.Eip;

			while (frame.Ebp)
			{
				StringA str = "";
				for (int i = 0; i < m_pFrame->m_ctx->m_modules.size(); i++)
				{
					DebugModule* pModule = m_pFrame->m_ctx->m_modules[i];

					if ((ULONG)frame.Ret_Addr >= pModule->base && (ULONG)frame.Ret_Addr < pModule->base + pModule->size)
					{
						str = pModule->name.c_str();

						tysymbolmap::iterator psymi = NULL;
						tysymbolmap::iterator symi = pModule->symbols.begin();
						while (symi != pModule->symbols.end())
						{
							if ((*symi).first > (ULONG)frame.Ret_Addr)
							{
								break;
							}
							psymi = symi;
							symi++;
						}

						if (psymi != NULL)
						{
							char s[512];
							sprintf(s, "%s + %X", (*psymi).second->m_name.c_str(), frame.Ret_Addr - (*psymi).first);
							str += s;
						}
						
						break;
					}
				}

				if (str.length()==0)
				{
					char buf[64];
					sprintf(buf, "%X", frame.Ret_Addr);
					str = buf;
				}		

				/*
				for (i = 0; i < m_pFrame->m_ctx->sourceFiles.size(); i++)
				{
					SourceFile* sourceFile = m_pFrame->m_ctx->sourceFiles[i];

					if (eip >= sourceFile->startAddress &&
						eip < sourceFile->endAddress)
					{
					//	sprintf(str, "%s() - %X", sourceFile->sourceFileName, eip);
					//	break;
					}
				}
				*/

				dc.TextOut(10, n*16, str.c_str());

			//	if (frame.Ebp == NULL)
			//		break;

				DWORD nRead;
				ReadProcessMemory(hProcess, frame.Ebp, &frame, 8, &nRead);
				if (nRead == 0)
					break;

				//frame eip = oldeip;
				n++;
			}
			//while (n < 20);

			CloseHandle(hProcess);
		}
	}
#endif
}
示例#6
0
HRESULT WINAPI CZipFs::ReCreate(__in_opt void* handle, __in_opt ULONG const flags /*= 0*/)
{
	if (flags)
		m_flags = flags;

	if ((HANDLE)handle == m_handle)
		return S_OK;

	m_handle = (HANDLE)handle;

	StringA strNameA = UnicodeToAnsi(m_FileName);

	if (UNZ_OK != unzGetFilePos64((unzFile)m_handle, &m_currentFilePos))
		return E_NOT_SET;

	if (unzLocateFile((unzFile)m_handle, strNameA.c_str(), 0) != UNZ_OK)
		return E_FAIL;

	HRESULT hr = (unzOpenCurrentFile((unzFile)m_handle) == UNZ_OK) ? S_OK : E_FAIL;
	if (FAILED(hr))
	{
		m_handle = INVALID_HANDLE_VALUE;
		return hr;
	}

	if (m_stream)
	{
		m_stream->Release();
		m_stream = NULL;
	}
	m_stream = new CBufferedStream();
	if (m_stream == NULL)
	{
		Close();
		return E_OUTOFMEMORY;
	}

	int err = 0;
	unsigned char *pTemp = new unsigned char[WRITEBUFFERSIZE];
	if (pTemp)
	{
		do
		{
			err = unzReadCurrentFile((unzFile)m_handle, pTemp, WRITEBUFFERSIZE);
			if (err < 0)
			{
				break;
			}
			if (err > 0)
			{
				ULONG writtenSize;
				if (FAILED(m_stream->Write(pTemp, (ULONG)err, &writtenSize)))
					break;
				if (writtenSize == 0)
					break;
			}
		} while (err > 0);
		delete[] pTemp;
	}

	// goto the beginning of file
	ULARGE_INTEGER pos = {};
	LARGE_INTEGER distanceToMove = {};
	m_stream->Seek(&pos, distanceToMove, IFsStream::FsStreamBegin);
	m_attribute->SetFilePath(m_FileName.c_str(), handle);
	return S_OK;
}
void CGnutellaSocket::OnReceive(int nErrorCode)
{
	TRACE("OnRead\n");
	/*
	if (nErrorCode)
	{
		ASSERT(0);
		return;
	}
	*/

	if (m_state == 0 || m_state == 1)
	{
		/*
		time_t timer1;
		time(&timer1);

		double diff = difftime(timer1, m_timer0);

		m_timer0 = timer1;

		ATLTRACE("", diff);
		*/

		ULONG n;
		ioctlsocket(m_socket, FIONREAD, &n);

		char buf[256+1];
		while (n)
		{
			int len = 256;
			if (len > n)
				len = n;

			int nread = Receive(buf, len);
			//if (nread == SOCKET_ERROR)
			if (nread < len)
			{
				m_state = -1;
				Close();
				return;
			}

			n -= nread;

			buf[nread] = 0;
			m_strHandshake += buf;
		}

		/*
		std::string line;
		while (1)
		{
			line = ReadLine();
			m_strHandshake += line + "\r\n";
			if (line.length() == 0)
				break;
		}
		*/

		if (m_strHandshake.length() > 4096)
		{
			// Handshake overflow
			ASSERT(0);
			m_state = -1;
			Close();
			return;//break;
		}

		if (m_state == 0)
		{
			if (m_strHandshake.length() >= 12)
			{
				if (strncmp(m_strHandshake.c_str(), "GNUTELLA/0.6", 12))
				{
					// Not a gnutella peer (disconnect)
					m_state = -1;
					Close();
					return;//break;
				}

				m_state = 1;	// Now we know it's a gnutella peer (keep receiving handshake)
			}
		}

		if (m_state == 1)
		{
			if (strstr(m_strHandshake.c_str(), "\r\n\r\n"))
			{
				m_state = 2;	// Have read entire handshake string
			}
		}

		if (m_state == 2)
		{
			int m_code = ParseHandshake();

			m_pComm->ProcessHeaders(this);

			if (m_code == 200)	// OK
			{
				m_state = 3;

				char* str =
					"GNUTELLA/0.6 200 OK\r\n"
					"\r\n";
			//	char* str = "GNUTELLA OK\n\n";
				int nWritten = Send(str, strlen(str));

				if (nWritten != strlen(str))
				{
					ASSERT(0);
				}

			//	PostMessage(m_pComm->m_hWnd, WM_USER+102, (LPARAM)(IConnection*)this, m_code);
			//	m_pComm->m_client->OnConnection(this);

				// Ping
				{
					GnutellaHeader ping;

					CoCreateGuid(&ping.Guid);	// ???
					ping.PayloadType = GnutellaPing;
					ping.TTL = 7;
					ping.Hops = 0;
					ping.PayloadLength = 0;

					int wrote = Send((const char*)&ping, sizeof(ping));
				}

			}
			else
			{
				Close();


				/*
				char* str =
					"GNUTELLA/0.6 503 FAIL\r\n"
					"\r\n";
				int nWritten = Send(str, strlen(str));

				if (nWritten != strlen(str))
				{
					ASSERT(0);
				}
*/
			}
		}
	}
	else if (m_state == 3)
	{
		int nread = Receive(m_packetbuf+m_nbufbytes, 32768-m_nbufbytes);
		if (nread == -1)
		{
			m_state = -1;
			Close();
			return;
		}

		int nbufbytes = m_nbufbytes + nread;

		// Process all complete packets
		bool bContinue;

		int offset = 0;
		int bytesleft;
		do
		{
			bytesleft = nbufbytes - offset;

			if (bytesleft < sizeof(GnutellaHeader))
			{
				// Incomplete packet
				bContinue = false;
			}
			else
			{
				GnutellaHeader* hdr = (GnutellaHeader*)(m_packetbuf+offset);

				if((hdr->PayloadType == 0x00 && hdr->PayloadLength < 32768)					  ||
					(hdr->PayloadType == 0x01 && hdr->PayloadLength >= 14 && hdr->PayloadLength < 32768)  ||
					(hdr->PayloadType == 0x02 && hdr->PayloadLength > 0 && hdr->PayloadLength < 32768)	||
					(hdr->PayloadType == 0x30 && hdr->PayloadLength > 2 && hdr->PayloadLength < 32768)   ||
					(hdr->PayloadType == 0x31 && hdr->PayloadLength < 32768)   ||
					(hdr->PayloadType == 0x32 && hdr->PayloadLength < 32768)   ||
					(hdr->PayloadType == 0x40 && hdr->PayloadLength >= 26 && hdr->PayloadLength < 32768)  ||
					(hdr->PayloadType == 0x80 && hdr->PayloadLength >  2 && hdr->PayloadLength <= 230)   ||
					(hdr->PayloadType == 0x81 && hdr->PayloadLength > 26 && hdr->PayloadLength <= 32768))
				{
					DWORD packetlen = sizeof(GnutellaHeader) + hdr->PayloadLength;

					if (bytesleft < packetlen)
					{
						// Incomplete packet
						bContinue = false;
					}
					else
					{
						ProcessPacket(hdr);

						offset += packetlen;

						bContinue = true;
					}
				}
				else
				{
					bContinue = false;

					m_state = -1;
					Close();
					return;
				}
			}
		}
		while (bContinue);

		// Move the leftover bytes to the beginning of the buffer
		if (bytesleft)
		{
			memmove(m_packetbuf, m_packetbuf+offset, bytesleft);
		}
		m_nbufbytes = bytesleft;
	}
}
int CGnutellaSocket::ParseHandshake()
{
	const char* p = m_strHandshake.c_str();
	const char* pend = p+m_strHandshake.length();

	if (!strncmp(p, "GNUTELLA/0.6", 12))
	{
		p += 12;
		p++;
		long code = strtol(p, (char**)&p, 10);
		p++;

		StringA codemsg;
		while (p < pend)
		{
			if (p[0] == '\r' && p[1] == '\n')
			{
				break;
			}

			codemsg += *p;
			p++;
		}

		if (*p++ != '\r') ASSERT(0);
		if (*p++ != '\n') ASSERT(0);

	//	HttpHeaders headers;
		m_headers.AddHeaders(p);

		/*
		while (p < pend)
		{
			std::string header;
			while (p < pend)
			{
				if (p[0] == '\r' && p[1] == '\n')
				{
					break;
				}

				header += *p;
				p++;
			}

			if (*p++ != '\r') ASSERT(0);
			if (*p++ != '\n') ASSERT(0);

			m_headers.push_back(header);
		}
		ASSERT(*p == 0);
		*/

		return code;
	}
	else
	{
		ASSERT(0);
		return 0;
	}
}
void MailAccount::GetNewMail(ITable* pTable)
{
	int port = 110;
	POP3Client* pSocket = new POP3Client;
	pSocket->Create();
	pSocket->Connect(m_server.c_str(), port);

	StringA greeting = pSocket->ReadLine();
	if (strncmp(greeting.c_str(), "+OK", 3))
		throw -1;

	{
		char msg[512];
		sprintf(msg, "USER %s\r\n", m_username.c_str());
		pSocket->Write(msg, strlen(msg));
		StringA response = pSocket->ReadLine();
		if (strncmp(response.c_str(), "+OK", 3))
			throw -1;
	}

	{
		char msg[512];
		sprintf(msg, "PASS %s\r\n", m_password.c_str());
		pSocket->Write(msg, strlen(msg));
		StringA response = pSocket->ReadLine();
		if (strncmp(response.c_str(), "+OK", 3))
			throw -1;
	}

	CArray<int, int> message_numbers;
	{
		char* msg = "LIST\r\n";
		pSocket->Write(msg, strlen(msg));
		StringA response = pSocket->ReadLine();
		if (strncmp(response.c_str(), "+OK", 3))
			throw -1;
		while (1)
		{
			StringA line = pSocket->ReadLine();
			if (!strcmp(line.c_str(), "."))
			{
				break;
			}

			int message_number;
			int message_size;

			sscanf(line.c_str(), "%d %d", &message_number, &message_size);
			message_numbers.Add(message_number);

			TRACE("%s\n", line.c_str());
		}

	//	FILE* fp_text = fopen("C:\\mail_text", "a+b");
	//	FILE* fp_index = fopen("C:\\mail_index", "a+b");

		for (int i = 0; i < message_numbers.size(); i++)
		{
			IRecord* pMessage = pTable->NewRecord();

			pMessage->GetField((int)0)->SetValue((long)0);//m_ID;
			pMessage->GetField(5)->SetValue((long)0);
			pMessage->GetField(6)->SetValue(time(NULL));
			pMessage->GetField(7)->SetValue(m_ID);

			{
				char msg[256];
				sprintf(msg, "RETR %d\r\n", message_numbers[i]);
				TRACE(msg);
				pSocket->Write(msg, strlen(msg));
				StringA response = pSocket->ReadLine();
				if (strncmp(response.c_str(), "+OK", 3))
					throw -1;
			}

			// Read the message
			StringA lines;

			while (1)
			{
				StringA line = pSocket->ReadLine();
				if (!strcmp(line.c_str(), "."))	// Multiline message ends with '.\r\n'
				{
					break;
				}

				lines += line;
				lines += "\r\n";
			}

			const char *p = lines.c_str();

			while (*p)
			{
				if (p[0] == '\r' && p[1] == '\n')	// End of headers
					break;

				// field name
				StringA fieldName;
				while (*p)
				{
					if (isspace(*p) || *p == ':')
						break;

					fieldName += *p;
					p++;
				}
				while (isspace(*p)) p++;
				if (*p++ != ':') throw -1;
				while (isspace(*p)) p++;

				// field body
				StringA fieldBody;
				while (*p)
				{
					if (p[0] == '\r' && p[1] == '\n')
					{
						if (p[2] == '\t' || p[2] == ' ')	// continuation on next line
						{
							p += 3;
						}
						else
						{
							p += 2;
							break;	// End of this field
						}
					}
					else
					{
						fieldBody += *p;
						p++;
					}
				}

				if (!stricmp(fieldName.c_str(), "Subject"))
				{
					pMessage->GetField(1)->SetData(fieldBody.c_str(), fieldBody.length());
				}
				else if (!stricmp(fieldName.c_str(), "From"))
				{
					pMessage->GetField(2)->SetData(fieldBody.c_str(), fieldBody.length());
				}
			}

			pMessage->GetField(3)->SetData(lines.c_str(), p - lines.c_str());

			if (p[0] != '\r' || p[1] != '\n')
				throw -1;
			p += 2;

			pMessage->GetField(4)->SetData(p, lines.length() - (p - lines.c_str()));

			pMessage->Write();

			// The message isn't actually deleted from the server until we issue a QUIT command
			{
				char msg[256];
				sprintf(msg, "DELE %d\r\n", message_numbers[i]);
				TRACE(msg);
				pSocket->Write(msg, strlen(msg));
				StringA response = pSocket->ReadLine();
				if (strncmp(response.c_str(), "+OK", 3))
					throw -1;
			}
		}

		/*
		fclose(fp_index);
		fclose(fp_text);
		*/
	}

	{
		char* msg = "QUIT\r\n";
		pSocket->Write(msg, strlen(msg));
		StringA response = pSocket->ReadLine();
		if (strncmp(response.c_str(), "+OK", 3))
			throw -1;
	}
}