⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpftinternet.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1996-1999 Network Associates, Inc.
	All rights reserved.

	$Id: CPFTInternet.cpp,v 1.4 1999/03/10 02:36:16 heller Exp $
____________________________________________________________________________*/
#include "CPFTInternet.h"

#include "CPFWindow.h"
#include "CControlThread.h"
#include "CPFPackets.h"
#include "CStatusPane.h"
#include "CPGPFone.h"
#include "LThread.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mmsystem.h>

extern BOOLEAN gHasWinsock;

CPFTInternet::CPFTInternet(CPFWindow *cpfWindow, LThread *thread, short *result)
					:	CPFTransport(cpfWindow)
{
	*result = 0;
	mSocket = mMSocket = mMCSocket = INVALID_SOCKET;
	mPFWindow = cpfWindow;
	mPFWindow->SetLocalAddress("");
	if(!gHasWinsock)
		*result = _pge_PortNotAvail;
	else
	{
		mSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if(mSocket != INVALID_SOCKET)
		{
			in_addr iaLocal;
			char szName[256];

			mLastAddress.sin_addr.s_addr = mRemoteAddress.sin_addr.s_addr = 0;
			mThread = thread;
			iaLocal.s_addr = INADDR_ANY;  // Initialize local addr to 0
			if(gethostname(szName, 256) != SOCKET_ERROR)
			{
				hostent* pHE = gethostbyname(szName);

				if(pHE != NULL)
				{
					// local ip address found
					iaLocal.s_addr = ((in_addr*)(pHE->h_addr_list[0]))->s_addr;
					mPFWindow->SetLocalAddress(inet_ntoa(iaLocal));
				}
			}
		}
		else
			*result = _pge_PortNotAvail;
	}
	if(*result)
		PGFAlert("Internet services could not be opened!", 0);
}

CPFTInternet::~CPFTInternet()
{
	AbortSync();
	mTMutex->Wait(semaphore_WaitForever);
	if(mState == _cs_connected)
		Disconnect();
	if(mSocket != INVALID_SOCKET)
		closesocket(mSocket);
	if(mMSocket != INVALID_SOCKET)
		closesocket(mMSocket);
	if(mMCSocket != INVALID_SOCKET)
		closesocket(mMCSocket);
}

PGErr
CPFTInternet::Connect(ContactEntry *con, short *connectResult)
{
	char buf[MAXPGPFUDPSIZE];
	Boolean found = FALSE;
	long len;
	uchar *p;
	short channel;
	ulong nextTry;
	char remoteDotName[32];
	struct hostent *ihinfo;
	struct in_addr inadr;
	int err;
	
	mTMutex->Wait(semaphore_WaitForever);
	SetState(_cs_connecting);
	*connectResult = _cr_Error;
	if(con->internetAddress[0])
	{
		CStatusPane::GetStatusPane()->AddStatus(0, "Contacting...");
		memset(&mAddress, 0, sizeof(mAddress));
		mAddress.sin_family = PF_INET;
		mAddress.sin_port = htons(CONTROLPORTNUMBER);
		err = bind(mSocket, (struct sockaddr *)&mAddress, sizeof(mAddress));
		if(err)
		{
			err = WSAGetLastError();
			pgpAssertNoErr(err);
		}
		if(!err && !mAbort)
		{
			memset(&mRemoteAddress, 0, sizeof(mRemoteAddress));
			mRemoteAddress.sin_family = PF_INET;
			mRemoteAddress.sin_port = htons(CONTROLPORTNUMBER);
			if(con->internetAddress[0]<'0' || con->internetAddress[0]>'9')
			{
				//Resolve address by name
				if(ihinfo = gethostbyname(con->internetAddress))
				{
					pgp_memcpy(&mRemoteAddress.sin_addr.s_addr, *ihinfo->h_addr_list, 4);
					pgp_memcpy(&inadr, *ihinfo->h_addr_list, 4);
					strcpy(remoteDotName, inet_ntoa(inadr));
					CStatusPane::GetStatusPane()->AddStatus(0, "Host identified as %s...",
						remoteDotName);
				}
				else
				{
					CStatusPane::GetStatusPane()->AddStatus(0, "Name lookup failed.");
					err = -1;
				}
			}
			else
			{
				//Convert numeric address to network order long
				if((mRemoteAddress.sin_addr.s_addr = inet_addr(con->internetAddress))
					== INADDR_NONE)
					err = -1;
			}
			if(!err && !mAbort)
			{
				for(short tries=MAXUDPCALLTRIES;(*connectResult == _cr_Error) && tries>0 && !mAbort;
					tries--)
				{
					buf[0] = _hpt_Setup;
					buf[1] = _ptip_Call;	len = 2;
					if(gPGFOpts.popt.idUnencrypted && gPGFOpts.popt.idOutgoing &&
						gPGFOpts.popt.identity[0])
					{
						len+= (buf[2] = strlen(gPGFOpts.popt.identity)) + 1;
						strcpy(&buf[3], gPGFOpts.popt.identity);
					}
					WriteBlock(buf, &len, _pfc_Control);
					nextTry = pgp_getticks() + 3000;
					while(!mAbort && nextTry > pgp_getticks())
					{
						if(len = Read(buf, MAXPGPFUDPSIZE, &channel))
							if(mLastAddress.sin_addr.s_addr ==
									mRemoteAddress.sin_addr.s_addr)
							{
								p = (uchar *)buf;
								if(*p++ == _hpt_Setup)
									switch(*p++)
									{
										case _ptip_Accept:
											*connectResult = _cr_Connect;
											break;
										case _ptip_Busy:
											CStatusPane::GetStatusPane()->AddStatus(0,
													"Busy.");
											if(gPGFOpts.popt.playRing)
												PlaySound("BUSY.WAV",NULL,
													SND_FILENAME+SND_SYNC);
											*connectResult = _cr_Busy;
											break;
										case _ptip_ProbeResponse:
											if(!found)
											{
												found = TRUE;
												CStatusPane::GetStatusPane()->AddStatus(0,
													"Remote contacted, ringing.");
												if(gPGFOpts.popt.playRing)
													PlaySound("BRING.WAV",NULL,
														SND_FILENAME+SND_SYNC);
											}
											break;
										case _ptip_Message:
											ReceiveUDPMsg(p, len -2);
											break;
									}
									break;
							}
						::Sleep(0);
					}
				}
			}
			if(*connectResult != _cr_Connect)
			{
				//WinSock 1.1 apparently didn't bother to include an unbind
				//call, so we have to hack it by killing the socket and recreating.
				closesocket(mSocket);
				mSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
			}
		}
	}
	else
	{
		PGFAlert("No Internet address has been specified.",0);
		err = _pge_NoSrvrName;
	}
	if(*connectResult != _cr_Connect)
	{
		CStatusPane::GetStatusPane()->AddStatus(0, "Connection failed.");
		SetState(_cs_none);
	}
	else
	{
		CStatusPane::GetStatusPane()->AddStatus(0, "Connected.");
		SetState(_cs_connected);
	}
	mTMutex->Signal();
	return err;
}

PGErr
CPFTInternet::Disconnect()
{
	mTMutex->Wait(semaphore_WaitForever);
	if(mState == _cs_connected)
	{
		SetState(_cs_disconnecting);
		//WinSock 1.1 apparently didn't bother to include an unbind
		//call, so we have to hack it by killing the socket and recreating.
		closesocket(mSocket);
		if(mMSocket != INVALID_SOCKET)
			closesocket(mMSocket);
		if(mMCSocket != INVALID_SOCKET)
			closesocket(mMCSocket);
		mMSocket = mMCSocket = INVALID_SOCKET;
		mSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	}
	SetState(_cs_none);
	mTMutex->Signal();
	return 0;
}

PGErr
CPFTInternet::Listen(Boolean answer)
{
	short result=0, reply=_cr_NoReply, rings, slen, err, channel;
	long resplen;
	ulong nextRingTime, len;
	uchar *p, buf[MAXPGPFUDPSIZE];
	char remoteDotName[32], remoteName[64], responsepkt[128];
	struct in_addr inadr;
	struct sockaddr_in savedAddress;
	Boolean sendResp, goodaddr, noted;

	mTMutex->Wait(semaphore_WaitForever);
	memset(&mAddress, 0, sizeof(mAddress));
	mAddress.sin_family = PF_INET;
	mAddress.sin_port = htons(CONTROLPORTNUMBER);
	err = bind(mSocket, (struct sockaddr FAR *) &mAddress, sizeof(mAddress));
	if(err)
	{
		err = WSAGetLastError();
		pgpAssertNoErr(err);
	}
	if(!err && !mAbort)
	{
		SetState(_cs_listening);
		do
		{
			if(mAnswer)
			{	// accept
				responsepkt[0] = _hpt_Setup;
				responsepkt[1] = _ptip_Accept;	resplen = 2;
				WriteBlockTo(responsepkt, &resplen, &mLastAddress);
				pgp_memcpy(&mRemoteAddress, &mLastAddress, sizeof(mLastAddress));
				CStatusPane::GetStatusPane()->AddStatus(0, "Connected.");
				SetState(_cs_connected);
				break;
			}
			if((mState == _cs_calldetected) && (nextRingTime <= pgp_getticks()))
			{	// ring every 5.5 seconds
				if(rings++ >= MAXUDPRINGS)
					SetState(_cs_listening);
				else
				{
					if(!noted)
					{
						CStatusPane::GetStatusPane()->AddStatus(0,
							"Incoming call from %s(%s)...",
							remoteName, remoteDotName);
						noted = TRUE;
					}
					if(gPGFOpts.popt.playRing)
						PlaySound("RING.WAV",NULL,SND_FILENAME+SND_SYNC);
					nextRingTime = pgp_getticks() + 5500;
				}
			}
			sendResp = FALSE;
			goodaddr = FALSE;
			pgp_memcpy(&savedAddress, &mLastAddress, sizeof(mLastAddress));
			if(len = Read(buf, MAXPGPFUDPSIZE, &channel))
			{
				p=buf;
				if(*p++==_hpt_Setup)
					switch(*p++)
					{
						case _ptip_Call:
							if(mState != _cs_calldetected)
							{
								goodaddr = TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -