home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2003 March / VPR0303A.ISO / AIBO / AiboBiff2 / MailChecker / MailChecker.cc next >
C/C++ Source or Header  |  2002-12-25  |  14KB  |  491 lines

  1. //-----------------------------------------------
  2. // MailChecker
  3. // 2002/12/19  Kazuto Sato
  4. //-----------------------------------------------
  5. #include <string.h>
  6. #include <OPENR/OSyslog.h>
  7. #include <OPENR/OPENRAPI.h>
  8. #include <OPENR/core_macro.h>
  9. #include <ant.h>
  10. #include <EndpointTypes.h>
  11. #include <TCPEndpointMsg.h>
  12. #include "MailChecker.h"
  13. #include "entry.h"
  14.  
  15. MailChecker::MailChecker () : pop3State(POP3_IDLE)
  16. {
  17.     // POP3・オ。シ・ミ。シ、ホIP・「・ノ・・ケ
  18.     strcpy(serverip, "202.225.88.136");
  19.     // POP3・オ。シ・ミ。シ、ホ・ン。シ・ネネヨケ
  20.     serverport = 110;
  21.     // ・「・ォ・ヲ・ネ
  22.     strcpy(username, "kazuto");
  23.     // ・ム・ケ・。シ・ノ
  24.     strcpy(password, "********");
  25. }
  26.  
  27. OStatus
  28. MailChecker::DoInit(const OSystemEvent& event)
  29. {
  30.     OSYSDEBUG(("MailChecker::DoInit()\n"));
  31.     NEW_ALL_SUBJECT_AND_OBSERVER;
  32.     REGISTER_ALL_ENTRY;
  33.     SET_ALL_READY_AND_NOTIFY_ENTRY;
  34.     return oSUCCESS;
  35. }
  36.  
  37. OStatus
  38. MailChecker::DoStart(const OSystemEvent& event)
  39. {
  40.     OSYSDEBUG(("MailChecker::DoStart()\n"));
  41.     
  42.     ipstackRef = antStackRef("IPStack");
  43.     for (int index = 0; index < MCHECK_CONNECTION_MAX; index++) {
  44.         OStatus result = InitTCPConnection(index);
  45.         if (result != oSUCCESS) return oFAIL;
  46.     }
  47.     
  48.     ENABLE_ALL_SUBJECT;
  49.     ASSERT_READY_TO_ALL_OBSERVER;
  50.     
  51.     return oSUCCESS;
  52. }
  53.  
  54. OStatus
  55. MailChecker::DoStop(const OSystemEvent& event)
  56. {
  57.     OSYSDEBUG(("MailChecker::DoStop()\n"));
  58.     
  59.     DISABLE_ALL_SUBJECT;
  60.     DEASSERT_READY_TO_ALL_OBSERVER;
  61.     return oSUCCESS;
  62. }
  63.  
  64. OStatus
  65. MailChecker::DoDestroy(const OSystemEvent& event)
  66. {
  67.     DELETE_ALL_SUBJECT_AND_OBSERVER;
  68.     return oSUCCESS;
  69. }
  70.  
  71. //-----------------------------------------------
  72. // AiboBiff、隍ス猜K
  73. //-----------------------------------------------
  74. void MailChecker::ReadyNewMail(const OReadyEvent& event)
  75. {
  76.     OSYSDEBUG(("MailChecker::ReadyNewMail()\n"));
  77. }
  78.  
  79. //-----------------------------------------------
  80. // AiboBiff、隍フソホ皃ア。「・癸シ・・チ・ァ・テ・ッウォサマ
  81. //-----------------------------------------------
  82. void MailChecker::NotifyMailCheck(const ONotifyEvent& event)
  83. {
  84.     OSYSDEBUG(("MailChecker::NotifyMailCheck()\n"));
  85.     
  86.     if(pop3State == POP3_IDLE) Connect(0); // タワツウウォサマ
  87.     
  88.     observer[event.ObsIndex()]->AssertReady();
  89. }
  90.  
  91. //-----------------------------------------------
  92. // ーハイシ。「EchoClient、ウ・ヤ。シ、キ、ニイツ、
  93. //-----------------------------------------------
  94. OStatus
  95. MailChecker::Connect(int index)
  96. {
  97.     OSYSDEBUG(("MailChecker::Connect()\n"));
  98.  
  99.     if (connection[index].state != CONNECTION_CLOSED) return oFAIL;
  100.  
  101.     //
  102.     // Create endpoint
  103.     //
  104.     antEnvCreateEndpointMsg tcpCreateMsg(EndpointType_TCP,
  105.                                     MCHECK_BUFFER_SIZE * 2);
  106.     tcpCreateMsg.Call(ipstackRef, sizeof(tcpCreateMsg));
  107.     if (tcpCreateMsg.error != ANT_SUCCESS) {
  108.         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
  109.                   "MailChecker::Connect()",
  110.                   "Can't create endpoint",
  111.                   index, tcpCreateMsg.error));
  112.         return oFAIL;
  113.     }
  114.     connection[index].endpoint = tcpCreateMsg.moduleRef;
  115.     
  116.     //
  117.     // Connect
  118.     //
  119.     TCPEndpointConnectMsg connectMsg(connection[index].endpoint,
  120.                            IP_ADDR_ANY, IP_PORT_ANY,
  121.                            serverip, serverport);
  122.     connectMsg.continuation = (void*)index;
  123.  
  124.     connectMsg.Send(ipstackRef, myOID_,
  125.                     Extra_Entry[entryConnectCont], sizeof(connectMsg));
  126.     
  127.     connection[index].state = CONNECTION_CONNECTING;
  128.  
  129.     return oSUCCESS;
  130. }
  131.  
  132. void
  133. MailChecker::ConnectCont(void* msg)
  134. {
  135.     OSYSDEBUG(("MailChecker::ConnectCont()\n"));
  136.  
  137.     TCPEndpointConnectMsg* connectMsg = (TCPEndpointConnectMsg*)msg;
  138.     int index = (int)connectMsg->continuation;
  139.  
  140.     if (connectMsg->error != TCP_SUCCESS) {
  141.         OSYSLOG1((osyslogERROR, "%s : %s %d",
  142.                   "MailChecker::ConnectCont()",
  143.                   "FAILED. connectMsg->error", connectMsg->error));
  144.         connection[index].state = CONNECTION_CLOSED;
  145.         return;
  146.     }
  147.  
  148.     connection[index].state = CONNECTION_CONNECTED;
  149.  
  150.     // ショウォサマ
  151.     pop3State = POP3_CONNECTED;
  152.     SetReceiveData(index);
  153.     Receive(index);
  154. }
  155.  
  156. OStatus
  157. MailChecker::Send(int index)
  158. {
  159.     OSYSDEBUG(("MailChecker::Send()\n"));
  160.  
  161.     if (connection[index].sendSize == 0 ||
  162.         connection[index].state != CONNECTION_CONNECTED) return oFAIL;
  163.  
  164.     TCPEndpointSendMsg sendMsg(connection[index].endpoint,
  165.                                connection[index].sendData,
  166.                                connection[index].sendSize);
  167.     sendMsg.continuation = (void*)index;
  168.  
  169.     sendMsg.Send(ipstackRef, myOID_,
  170.                  Extra_Entry[entrySendCont],
  171.                  sizeof(TCPEndpointSendMsg));
  172.  
  173.     connection[index].state = CONNECTION_SENDING;
  174.     connection[index].sendSize = 0;
  175.     return oSUCCESS;
  176. }
  177.  
  178. void
  179. MailChecker::SendCont(void* msg)
  180. {
  181.     OSYSDEBUG(("MailChecker::SendCont()\n"));
  182.  
  183.     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)msg;
  184.     int index = (int)(sendMsg->continuation);
  185.  
  186.     if (sendMsg->error != TCP_SUCCESS) {
  187.         OSYSLOG1((osyslogERROR, "%s : %s %d",
  188.                   "MailChecker::SendCont()",
  189.                   "FAILED. sendMsg->error", sendMsg->error));
  190.         Close(index);
  191.         return;
  192.     }
  193.  
  194.     OSYSPRINT(("sendData : %s", connection[index].sendData));
  195.     
  196.     connection[index].state = CONNECTION_CONNECTED;
  197.  
  198.     SetReceiveData(index);
  199.     Receive(index);
  200. }
  201.  
  202. OStatus
  203. MailChecker::Receive(int index)
  204. {
  205.     OSYSDEBUG(("MailChecker::Receive()\n"));
  206.  
  207.     if (connection[index].state != CONNECTION_CONNECTED &&
  208.         connection[index].state != CONNECTION_SENDING) return oFAIL;
  209.  
  210.     TCPEndpointReceiveMsg receiveMsg(connection[index].endpoint,
  211.                                      connection[index].recvData,
  212.                                      1, connection[index].recvSize);
  213.     receiveMsg.continuation = (void*)index;
  214.  
  215.     receiveMsg.Send(ipstackRef, myOID_,
  216.                     Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
  217.  
  218.     return oSUCCESS;
  219. }
  220.  
  221. void
  222. MailChecker::ReceiveCont(void* msg)
  223. {
  224.     static string bufData = "";
  225.  
  226.     OSYSDEBUG(("MailChecker::ReceiveCont()\n"));
  227.  
  228.     TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*)msg;
  229.     int index = (int)(receiveMsg->continuation);
  230.  
  231.     if (receiveMsg->error != TCP_SUCCESS) {
  232.         OSYSLOG1((osyslogERROR, "%s : %s %d",
  233.                   "MailChecker::ReceiveCont()",
  234.                   "FAILED. receiveMsg->error", receiveMsg->error));
  235.         Close(index);
  236.         return;
  237.     }
  238.     
  239.     connection[index].recvData[receiveMsg->sizeMax] = 0;
  240.     OSYSPRINT(("recvData : "));
  241.     printRecvData((char*)connection[index].recvData);
  242.     if(bufData == "") {
  243.         if(strncmp((char*)connection[index].recvData, "+OK", 3) != 0) {
  244.             OSYSPRINT(("* POP3 Error *\n"));
  245.             Close(index);
  246.             return;
  247.         }
  248.     }
  249.     
  250.     if(pop3State == POP3_CONNECTED) pop3State = POP3_USER;
  251.     else if(pop3State == POP3_USER) pop3State = POP3_PASS;
  252.     else if(pop3State == POP3_PASS) pop3State = POP3_STAT;
  253.     else if(pop3State == POP3_STAT) {
  254.         // ・皈テ・サ。シ・ク、ャ、「、、ォ、ノ、ヲ、ォ・チ・ァ・テ・ッ
  255.         if(CheckStat((char*)connection[index].recvData) > 0)
  256.             pop3State = POP3_UIDL;
  257.         else pop3State = POP3_QUIT;
  258.     }
  259.     else if(pop3State == POP3_UIDL) {
  260.         bufData += (char*)connection[index].recvData;
  261.         if(bufData.rfind("\r\n.\r\n") != string::npos) {
  262.             // UIDL、ォ、鯀キテ螂癸シ・、チ・ァ・テ・ッ
  263.             CheckNewMail(bufData.c_str());
  264.             pop3State = POP3_QUIT;
  265.             bufData = "";
  266.         }
  267.         else { // ツウ、ュ、アシ隍
  268.             SetReceiveData(index);
  269.             Receive(index);
  270.             return;
  271.         }
  272.     }
  273.     else if(pop3State == POP3_QUIT) pop3State = POP3_CLOSE;
  274.     
  275.     if(pop3State != POP3_CLOSE) {
  276.         SetSendData(index);
  277.         Send(index);
  278.     }
  279.     else Close(index);
  280. }
  281.  
  282. OStatus
  283. MailChecker::Close(int index)
  284. {
  285.     OSYSDEBUG(("MailChecker::Close()\n"));
  286.  
  287.     if (connection[index].state == CONNECTION_CLOSED ||
  288.         connection[index].state == CONNECTION_CLOSING) return oSUCCESS;
  289.  
  290.     TCPEndpointCloseMsg closeMsg(connection[index].endpoint);
  291.     closeMsg.continuation = (void*)index;
  292.  
  293.     closeMsg.Send(ipstackRef, myOID_,
  294.                   Extra_Entry[entryCloseCont], sizeof(closeMsg));
  295.  
  296.     connection[index].state = CONNECTION_CLOSING;
  297.  
  298.     return oSUCCESS;
  299. }
  300.  
  301. void
  302. MailChecker::CloseCont(void* msg)
  303. {
  304.     OSYSDEBUG(("MailChecker::CloseCont()\n"));
  305.  
  306.     TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*)msg;
  307.     int index = (int)(closeMsg->continuation);
  308.  
  309.     connection[index].state = CONNECTION_CLOSED;
  310.     
  311.     pop3State = POP3_IDLE;
  312. }
  313.  
  314. OStatus
  315. MailChecker::InitTCPConnection(int index)
  316. {
  317.     OSYSDEBUG(("MailChecker::InitTCPConnection()\n"));
  318.  
  319.     connection[index].state = CONNECTION_CLOSED;
  320.     
  321.     // ・ィ・ノ・ン・、・ネ、ホコ鋿ョ、マ。「Connect() 、ヒーワニー
  322.  
  323.     // 
  324.     // Allocate send buffer
  325.     //
  326.     antEnvCreateSharedBufferMsg sendBufferMsg(MCHECK_BUFFER_SIZE);
  327.  
  328.     sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
  329.     if (sendBufferMsg.error != ANT_SUCCESS) {
  330.         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
  331.                   "MailChecker::InitTCPConnection()",
  332.                   "Can't allocate send buffer",
  333.                   index, sendBufferMsg.error));
  334.         return oFAIL;
  335.     }
  336.  
  337.     connection[index].sendBuffer = sendBufferMsg.buffer;
  338.     connection[index].sendBuffer.Map();
  339.     connection[index].sendData
  340.         = (byte*)(connection[index].sendBuffer.GetAddress());
  341.  
  342.     //
  343.     // Allocate receive buffer
  344.     //
  345.     antEnvCreateSharedBufferMsg recvBufferMsg(MCHECK_BUFFER_SIZE);
  346.  
  347.     recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
  348.     if (recvBufferMsg.error != ANT_SUCCESS) {
  349.         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
  350.                   "MailChecker::InitTCPConnection()",
  351.                   "Can't allocate receive buffer",
  352.                   index, recvBufferMsg.error));
  353.         return oFAIL;
  354.     }
  355.  
  356.     connection[index].recvBuffer = recvBufferMsg.buffer;
  357.     connection[index].recvBuffer.Map();
  358.     connection[index].recvData
  359.         = (byte*)(connection[index].recvBuffer.GetAddress());
  360.  
  361.     return oSUCCESS;
  362. }
  363.  
  364. void MailChecker::SetSendData(int index)
  365. {
  366.     char command[80];
  367.     // pop3State、ヒア、ク、ニ・ウ・゙・ノ、
  368.     if(pop3State == POP3_USER) {
  369.         strcpy(command, "USER ");
  370.         strcat(command, username);
  371.         strcat(command, "\r\n");
  372.     }
  373.     else if(pop3State == POP3_PASS) {
  374.         strcpy(command, "PASS ");
  375.         strcat(command, password);
  376.         strcat(command, "\r\n");
  377.     }
  378.     else if(pop3State == POP3_STAT)
  379.         strcpy(command, "STAT\r\n");
  380.     else if(pop3State == POP3_UIDL)
  381.         strcpy(command, "UIDL\r\n");
  382.     else if(pop3State == POP3_QUIT)
  383.         strcpy(command, "QUIT\r\n");
  384.     
  385.     strcpy((char*)connection[index].sendData, command);
  386.     connection[index].sendSize = strlen(command);
  387. }
  388.  
  389. void
  390. MailChecker::SetReceiveData(int index)
  391. {
  392.     connection[index].recvSize = MCHECK_BUFFER_SIZE-16;
  393. }
  394.  
  395. //-----------------------------------------------
  396. // STAT・ウ・゙・ノ、ホ・・ケ・ン・ケ、チ・ァ・テ・ッ
  397. //-----------------------------------------------
  398. int MailChecker::CheckStat(const char* resp)
  399. {
  400.     OSYSDEBUG(("MailChecker::CheckStat()\n"));
  401.     
  402.     char numstr[10];
  403.     int i, num;
  404.     const char* p = resp;
  405.     p += 3; while(isspace(*p)) p++;
  406.     for(i = 0; isdigit(*p); i++) numstr[i] = *p++;
  407.     numstr[i] = 0;
  408.     num = atoi(numstr);
  409.     return num;
  410. }
  411.  
  412. //-----------------------------------------------
  413. // UIDL・ウ・゙・ノ、ホ・ヌ。シ・ソ、エ、ル。「
  414. // ソキテ螂癸シ・、ャ、「、テ、ソ、鯣ー、ュサマ、皃
  415. //-----------------------------------------------
  416. void MailChecker::CheckNewMail(const char* resp)
  417. {
  418.     list<string> linew;
  419.     GetUIDL(resp, linew);
  420.     if(CheckUIDL(listUID, linew)) {
  421.         char str[20];
  422.         strcpy(str, "new mail");
  423.         // AiboBiff、ヒ・ウ・゙・ノチョ
  424.         subject[sbjNewMail]->SetData(str, sizeof(str));
  425.         subject[sbjNewMail]->NotifyObservers();
  426.     }
  427.     listUID = linew;
  428. }
  429.  
  430. //-----------------------------------------------
  431. // UIDL・ウ・゙・ノ、ホキイフ、ォ、飆D、ホ・・ケ・ネ、隍スミ、ケ
  432. //-----------------------------------------------
  433. void MailChecker::GetUIDL(const char* resp, list<string>& li)
  434. {
  435.     OSYSDEBUG(("MailChecker::GetUIDL()\n"));
  436.     
  437.     const char* p = resp;
  438.     while(*p && *p != '\r') p++; p += 2;
  439.     while(*p) {
  440.         if(!isdigit(*p)) break;
  441.         while(isdigit(*p)) p++;
  442.         while(isspace(*p)) p++;
  443.         const char* sp = p;
  444.         while(*p && !isspace(*p)) p++;
  445.         string s(sp, p - sp);
  446.         li.push_back(s);
  447.         while(isspace(*p)) p++;
  448.     }
  449. }
  450.  
  451. //-----------------------------------------------
  452. // ID、ホ・・ケ・ネ、豕モ、キ。「ソキテ螂癸シ・、エ、ル、
  453. //-----------------------------------------------
  454. int MailChecker::CheckUIDL(list<string>& liold,
  455.     list<string>& linew)
  456. {
  457.     OSYSDEBUG(("MailChecker::CheckUIDL()\n"));
  458.     
  459.     int fnew = 0;
  460.     list<string>::iterator p1 = linew.begin();
  461.     for(; p1 != linew.end(); p1++) {
  462.         list<string>::iterator p2 = liold.begin();
  463.         for(; p2 != liold.end(); p2++) {
  464.             if(*p1 == *p2) break;
  465.         }
  466.         if(p2 == liold.end()) { fnew = 1; break; }
  467.     }
  468.     return fnew;
  469. }
  470.  
  471. //-----------------------------------------------
  472. // トケ、、ハクサ昀ミホマ
  473. //-----------------------------------------------
  474. void MailChecker::printRecvData(const char* src)
  475. {
  476.     char buf[201];
  477.     const char *p = src;
  478.     int len = strlen(src);
  479.     int nokori = len;
  480.     
  481.     while(nokori > 0) {
  482.         int i = 200;
  483.         if(i > nokori) i = nokori;
  484.         strncpy(buf, p, i); buf[i] = 0;
  485.         OSYSPRINT((buf));
  486.         nokori -= i;
  487.         p += i;
  488.     }
  489. }
  490.  
  491.