home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2003 March
/
VPR0303A.ISO
/
AIBO
/
AiboBiff2
/
MailChecker
/
MailChecker.cc
next >
Wrap
C/C++ Source or Header
|
2002-12-25
|
14KB
|
491 lines
//-----------------------------------------------
// MailChecker
// 2002/12/19 Kazuto Sato
//-----------------------------------------------
#include <string.h>
#include <OPENR/OSyslog.h>
#include <OPENR/OPENRAPI.h>
#include <OPENR/core_macro.h>
#include <ant.h>
#include <EndpointTypes.h>
#include <TCPEndpointMsg.h>
#include "MailChecker.h"
#include "entry.h"
MailChecker::MailChecker () : pop3State(POP3_IDLE)
{
// POP3・オ。シ・ミ。シ、ホIP・「・ノ・・ケ
strcpy(serverip, "202.225.88.136");
// POP3・オ。シ・ミ。シ、ホ・ン。シ・ネネヨケ
serverport = 110;
// ・「・ォ・ヲ・ネ
strcpy(username, "kazuto");
// ・ム・ケ・。シ・ノ
strcpy(password, "********");
}
OStatus
MailChecker::DoInit(const OSystemEvent& event)
{
OSYSDEBUG(("MailChecker::DoInit()\n"));
NEW_ALL_SUBJECT_AND_OBSERVER;
REGISTER_ALL_ENTRY;
SET_ALL_READY_AND_NOTIFY_ENTRY;
return oSUCCESS;
}
OStatus
MailChecker::DoStart(const OSystemEvent& event)
{
OSYSDEBUG(("MailChecker::DoStart()\n"));
ipstackRef = antStackRef("IPStack");
for (int index = 0; index < MCHECK_CONNECTION_MAX; index++) {
OStatus result = InitTCPConnection(index);
if (result != oSUCCESS) return oFAIL;
}
ENABLE_ALL_SUBJECT;
ASSERT_READY_TO_ALL_OBSERVER;
return oSUCCESS;
}
OStatus
MailChecker::DoStop(const OSystemEvent& event)
{
OSYSDEBUG(("MailChecker::DoStop()\n"));
DISABLE_ALL_SUBJECT;
DEASSERT_READY_TO_ALL_OBSERVER;
return oSUCCESS;
}
OStatus
MailChecker::DoDestroy(const OSystemEvent& event)
{
DELETE_ALL_SUBJECT_AND_OBSERVER;
return oSUCCESS;
}
//-----------------------------------------------
// AiboBiff、隍ス猜K
//-----------------------------------------------
void MailChecker::ReadyNewMail(const OReadyEvent& event)
{
OSYSDEBUG(("MailChecker::ReadyNewMail()\n"));
}
//-----------------------------------------------
// AiboBiff、隍フソホ皃ア。「・癸シ・・チ・ァ・テ・ッウォサマ
//-----------------------------------------------
void MailChecker::NotifyMailCheck(const ONotifyEvent& event)
{
OSYSDEBUG(("MailChecker::NotifyMailCheck()\n"));
if(pop3State == POP3_IDLE) Connect(0); // タワツウウォサマ
observer[event.ObsIndex()]->AssertReady();
}
//-----------------------------------------------
// ーハイシ。「EchoClient、ウ・ヤ。シ、キ、ニイツ、
//-----------------------------------------------
OStatus
MailChecker::Connect(int index)
{
OSYSDEBUG(("MailChecker::Connect()\n"));
if (connection[index].state != CONNECTION_CLOSED) return oFAIL;
//
// Create endpoint
//
antEnvCreateEndpointMsg tcpCreateMsg(EndpointType_TCP,
MCHECK_BUFFER_SIZE * 2);
tcpCreateMsg.Call(ipstackRef, sizeof(tcpCreateMsg));
if (tcpCreateMsg.error != ANT_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
"MailChecker::Connect()",
"Can't create endpoint",
index, tcpCreateMsg.error));
return oFAIL;
}
connection[index].endpoint = tcpCreateMsg.moduleRef;
//
// Connect
//
TCPEndpointConnectMsg connectMsg(connection[index].endpoint,
IP_ADDR_ANY, IP_PORT_ANY,
serverip, serverport);
connectMsg.continuation = (void*)index;
connectMsg.Send(ipstackRef, myOID_,
Extra_Entry[entryConnectCont], sizeof(connectMsg));
connection[index].state = CONNECTION_CONNECTING;
return oSUCCESS;
}
void
MailChecker::ConnectCont(void* msg)
{
OSYSDEBUG(("MailChecker::ConnectCont()\n"));
TCPEndpointConnectMsg* connectMsg = (TCPEndpointConnectMsg*)msg;
int index = (int)connectMsg->continuation;
if (connectMsg->error != TCP_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s %d",
"MailChecker::ConnectCont()",
"FAILED. connectMsg->error", connectMsg->error));
connection[index].state = CONNECTION_CLOSED;
return;
}
connection[index].state = CONNECTION_CONNECTED;
// ショウォサマ
pop3State = POP3_CONNECTED;
SetReceiveData(index);
Receive(index);
}
OStatus
MailChecker::Send(int index)
{
OSYSDEBUG(("MailChecker::Send()\n"));
if (connection[index].sendSize == 0 ||
connection[index].state != CONNECTION_CONNECTED) return oFAIL;
TCPEndpointSendMsg sendMsg(connection[index].endpoint,
connection[index].sendData,
connection[index].sendSize);
sendMsg.continuation = (void*)index;
sendMsg.Send(ipstackRef, myOID_,
Extra_Entry[entrySendCont],
sizeof(TCPEndpointSendMsg));
connection[index].state = CONNECTION_SENDING;
connection[index].sendSize = 0;
return oSUCCESS;
}
void
MailChecker::SendCont(void* msg)
{
OSYSDEBUG(("MailChecker::SendCont()\n"));
TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)msg;
int index = (int)(sendMsg->continuation);
if (sendMsg->error != TCP_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s %d",
"MailChecker::SendCont()",
"FAILED. sendMsg->error", sendMsg->error));
Close(index);
return;
}
OSYSPRINT(("sendData : %s", connection[index].sendData));
connection[index].state = CONNECTION_CONNECTED;
SetReceiveData(index);
Receive(index);
}
OStatus
MailChecker::Receive(int index)
{
OSYSDEBUG(("MailChecker::Receive()\n"));
if (connection[index].state != CONNECTION_CONNECTED &&
connection[index].state != CONNECTION_SENDING) return oFAIL;
TCPEndpointReceiveMsg receiveMsg(connection[index].endpoint,
connection[index].recvData,
1, connection[index].recvSize);
receiveMsg.continuation = (void*)index;
receiveMsg.Send(ipstackRef, myOID_,
Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
return oSUCCESS;
}
void
MailChecker::ReceiveCont(void* msg)
{
static string bufData = "";
OSYSDEBUG(("MailChecker::ReceiveCont()\n"));
TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*)msg;
int index = (int)(receiveMsg->continuation);
if (receiveMsg->error != TCP_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s %d",
"MailChecker::ReceiveCont()",
"FAILED. receiveMsg->error", receiveMsg->error));
Close(index);
return;
}
connection[index].recvData[receiveMsg->sizeMax] = 0;
OSYSPRINT(("recvData : "));
printRecvData((char*)connection[index].recvData);
if(bufData == "") {
if(strncmp((char*)connection[index].recvData, "+OK", 3) != 0) {
OSYSPRINT(("* POP3 Error *\n"));
Close(index);
return;
}
}
if(pop3State == POP3_CONNECTED) pop3State = POP3_USER;
else if(pop3State == POP3_USER) pop3State = POP3_PASS;
else if(pop3State == POP3_PASS) pop3State = POP3_STAT;
else if(pop3State == POP3_STAT) {
// ・皈テ・サ。シ・ク、ャ、「、、ォ、ノ、ヲ、ォ・チ・ァ・テ・ッ
if(CheckStat((char*)connection[index].recvData) > 0)
pop3State = POP3_UIDL;
else pop3State = POP3_QUIT;
}
else if(pop3State == POP3_UIDL) {
bufData += (char*)connection[index].recvData;
if(bufData.rfind("\r\n.\r\n") != string::npos) {
// UIDL、ォ、鯀キテ螂癸シ・、チ・ァ・テ・ッ
CheckNewMail(bufData.c_str());
pop3State = POP3_QUIT;
bufData = "";
}
else { // ツウ、ュ、アシ隍
SetReceiveData(index);
Receive(index);
return;
}
}
else if(pop3State == POP3_QUIT) pop3State = POP3_CLOSE;
if(pop3State != POP3_CLOSE) {
SetSendData(index);
Send(index);
}
else Close(index);
}
OStatus
MailChecker::Close(int index)
{
OSYSDEBUG(("MailChecker::Close()\n"));
if (connection[index].state == CONNECTION_CLOSED ||
connection[index].state == CONNECTION_CLOSING) return oSUCCESS;
TCPEndpointCloseMsg closeMsg(connection[index].endpoint);
closeMsg.continuation = (void*)index;
closeMsg.Send(ipstackRef, myOID_,
Extra_Entry[entryCloseCont], sizeof(closeMsg));
connection[index].state = CONNECTION_CLOSING;
return oSUCCESS;
}
void
MailChecker::CloseCont(void* msg)
{
OSYSDEBUG(("MailChecker::CloseCont()\n"));
TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*)msg;
int index = (int)(closeMsg->continuation);
connection[index].state = CONNECTION_CLOSED;
pop3State = POP3_IDLE;
}
OStatus
MailChecker::InitTCPConnection(int index)
{
OSYSDEBUG(("MailChecker::InitTCPConnection()\n"));
connection[index].state = CONNECTION_CLOSED;
// ・ィ・ノ・ン・、・ネ、ホコ鋿ョ、マ。「Connect() 、ヒーワニー
//
// Allocate send buffer
//
antEnvCreateSharedBufferMsg sendBufferMsg(MCHECK_BUFFER_SIZE);
sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
if (sendBufferMsg.error != ANT_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
"MailChecker::InitTCPConnection()",
"Can't allocate send buffer",
index, sendBufferMsg.error));
return oFAIL;
}
connection[index].sendBuffer = sendBufferMsg.buffer;
connection[index].sendBuffer.Map();
connection[index].sendData
= (byte*)(connection[index].sendBuffer.GetAddress());
//
// Allocate receive buffer
//
antEnvCreateSharedBufferMsg recvBufferMsg(MCHECK_BUFFER_SIZE);
recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
if (recvBufferMsg.error != ANT_SUCCESS) {
OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
"MailChecker::InitTCPConnection()",
"Can't allocate receive buffer",
index, recvBufferMsg.error));
return oFAIL;
}
connection[index].recvBuffer = recvBufferMsg.buffer;
connection[index].recvBuffer.Map();
connection[index].recvData
= (byte*)(connection[index].recvBuffer.GetAddress());
return oSUCCESS;
}
void MailChecker::SetSendData(int index)
{
char command[80];
// pop3State、ヒア、ク、ニ・ウ・゙・ノ、
if(pop3State == POP3_USER) {
strcpy(command, "USER ");
strcat(command, username);
strcat(command, "\r\n");
}
else if(pop3State == POP3_PASS) {
strcpy(command, "PASS ");
strcat(command, password);
strcat(command, "\r\n");
}
else if(pop3State == POP3_STAT)
strcpy(command, "STAT\r\n");
else if(pop3State == POP3_UIDL)
strcpy(command, "UIDL\r\n");
else if(pop3State == POP3_QUIT)
strcpy(command, "QUIT\r\n");
strcpy((char*)connection[index].sendData, command);
connection[index].sendSize = strlen(command);
}
void
MailChecker::SetReceiveData(int index)
{
connection[index].recvSize = MCHECK_BUFFER_SIZE-16;
}
//-----------------------------------------------
// STAT・ウ・゙・ノ、ホ・・ケ・ン・ケ、チ・ァ・テ・ッ
//-----------------------------------------------
int MailChecker::CheckStat(const char* resp)
{
OSYSDEBUG(("MailChecker::CheckStat()\n"));
char numstr[10];
int i, num;
const char* p = resp;
p += 3; while(isspace(*p)) p++;
for(i = 0; isdigit(*p); i++) numstr[i] = *p++;
numstr[i] = 0;
num = atoi(numstr);
return num;
}
//-----------------------------------------------
// UIDL・ウ・゙・ノ、ホ・ヌ。シ・ソ、エ、ル。「
// ソキテ螂癸シ・、ャ、「、テ、ソ、鯣ー、ュサマ、皃
//-----------------------------------------------
void MailChecker::CheckNewMail(const char* resp)
{
list<string> linew;
GetUIDL(resp, linew);
if(CheckUIDL(listUID, linew)) {
char str[20];
strcpy(str, "new mail");
// AiboBiff、ヒ・ウ・゙・ノチョ
subject[sbjNewMail]->SetData(str, sizeof(str));
subject[sbjNewMail]->NotifyObservers();
}
listUID = linew;
}
//-----------------------------------------------
// UIDL・ウ・゙・ノ、ホキイフ、ォ、飆D、ホ・・ケ・ネ、隍スミ、ケ
//-----------------------------------------------
void MailChecker::GetUIDL(const char* resp, list<string>& li)
{
OSYSDEBUG(("MailChecker::GetUIDL()\n"));
const char* p = resp;
while(*p && *p != '\r') p++; p += 2;
while(*p) {
if(!isdigit(*p)) break;
while(isdigit(*p)) p++;
while(isspace(*p)) p++;
const char* sp = p;
while(*p && !isspace(*p)) p++;
string s(sp, p - sp);
li.push_back(s);
while(isspace(*p)) p++;
}
}
//-----------------------------------------------
// ID、ホ・・ケ・ネ、豕モ、キ。「ソキテ螂癸シ・、エ、ル、
//-----------------------------------------------
int MailChecker::CheckUIDL(list<string>& liold,
list<string>& linew)
{
OSYSDEBUG(("MailChecker::CheckUIDL()\n"));
int fnew = 0;
list<string>::iterator p1 = linew.begin();
for(; p1 != linew.end(); p1++) {
list<string>::iterator p2 = liold.begin();
for(; p2 != liold.end(); p2++) {
if(*p1 == *p2) break;
}
if(p2 == liold.end()) { fnew = 1; break; }
}
return fnew;
}
//-----------------------------------------------
// トケ、、ハクサ昀ミホマ
//-----------------------------------------------
void MailChecker::printRecvData(const char* src)
{
char buf[201];
const char *p = src;
int len = strlen(src);
int nokori = len;
while(nokori > 0) {
int i = 200;
if(i > nokori) i = nokori;
strncpy(buf, p, i); buf[i] = 0;
OSYSPRINT((buf));
nokori -= i;
p += i;
}
}