📄 cpftinternet.cpp
字号:
/*____________________________________________________________________________
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 + -