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

📄 imapserverc.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      SSL_CTX_free(sslCtx);   }      TLSEnabled = False;   return True;#else   return False;#endif}/*------------------------------------------------------------------------ * Method to authenticate against the IMAP server */BooleanImapServerC::DoLogin(){//// Do nothing if already (pre)authenticated//   if ( authenticated ) return True;      StringC	errmsg;      while ( True ) {//// Get user id and password//      if ( !GetLogin(name, user, pass) ) {	 // User cancelled	 return False;      }//// Send login command//      ImapCommandReturn res = Authenticate(user, pass);      switch ( res ) {      case ImapCommandOK:	 return True;         break;      case ImapCommandNoConnect:	 // An error message should be issued by a low-level function         return False;         break;      case ImapCommandCancelled:	 // User cancelled; just return         return False;         break;      case ImapCommandNO:	 // Wrong user/pass         errmsg = "The IMAP server on host ";	 errmsg += name;	 errmsg += "\ndenied access.";         break;      default:	 // ?? Not-supported protocol or our bug         errmsg = "An authentication error ocured while connecting to server.";	 errmsg += name;         break;      }            InvalidateLogin(name);            errmsg += "\n\nRetry?";      if ( !RetryLogin(errmsg) ) {	 return False;      }   } // End while not logged in}/*------------------------------------------------------------------------ * Method to reconnect to the IMAP server */BooleanImapServerC::ReConnect(){   if ( EstablishSession() ) {      ishApp->mainWin->curFolder->Rescan();      return True;   } else      return False;}/*------------------------------------------------------------------------ * Method to determine the IMAP server capabilities */BooleanImapServerC::Capability(){   protocols    = 0L;   authMethods  = 0L;      // STARTTLS may not be announced after switching to TLS   if ( !TLSEnabled ) {      haveStartTLS = False;   }      // all servers support LOGIN unless explicitly said otherwise   Boolean loginDisabled = False; //// Issue the CAPABILITY command//   StringListC	output;   if ( RunCommand("CAPABILITY", output) ) {//// Loop through the output looking for BAD response. If found, this is// an IMAP 2 server. Otherwise, get some valuable info (supported protocols,// authentication schemes etc)//      u_int	count = output.size();      for (int i=0; i<count; i++) {	 StringC	*line = output[i];	 if ( line->StartsWith("BAD", IGNORE_CASE) ) {	    protocols = IMAP_PROTOCOL_IMAP2BIS; // Stick with IMAP2bis            break;         } else {            StringListC tokens;                        ExtractList(*line, tokens);            int ntokens = tokens.size();            for (int j = 0; j < ntokens; j++) {	       StringC *token = tokens[j];               if ( token->Equals("IMAP4", IGNORE_CASE) ) {	          protocols |= IMAP_PROTOCOL_IMAP4;               }               else if ( token->Equals("IMAP4rev1", IGNORE_CASE) ) {	          protocols |= IMAP_PROTOCOL_IMAP4REV1;               }               else if ( token->Equals("AUTH=LOGIN", IGNORE_CASE) ) {	          authMethods |= IMAP_AUTH_LOGIN;               }               else if ( token->Equals("AUTH=ANONYMOUS", IGNORE_CASE) ) {	          authMethods |= IMAP_AUTH_ANONYMOUS;               }#ifdef HAVE_OPENSSL               else if ( token->Equals("AUTH=CRAM-MD5", IGNORE_CASE) ) {	          authMethods |= IMAP_AUTH_CRAM_MD5;               }#endif#if 0               else if ( token->Equals("AUTH=GSSAPI", IGNORE_CASE) ) {	          authMethods |= IMAP_AUTH_GSSAPI;               }               else if ( token->Equals("AUTH=KERBEROS_V4", IGNORE_CASE) ) {	          authMethods |= IMAP_AUTH_KERBEROS_V4;               }#endif               else if ( token->Equals("LOGINDISABLED", IGNORE_CASE) ) {	          loginDisabled = True;               }               else if ( token->Equals("STARTTLS", IGNORE_CASE) ) {	          haveStartTLS = True;               }            }         }      }         if ( !loginDisabled ) {         authMethods |= IMAP_AUTH_CLEAR_TEXT;      }            if ( !protocols ) {         // No supported protocols found         StringC	errmsg;         errmsg = "The IMAP server on host ";         errmsg += name;         errmsg += "\ndoes not support any known IMAP protocol\n";         halApp->PopupMessage(errmsg);         return False;      }      else if ( !authMethods ) {         // No supported authentication methods         StringC	errmsg;         errmsg = "The IMAP server on host ";         errmsg += name;         errmsg += "\nfeatures no supported authentication methods\n";         halApp->PopupMessage(errmsg);         return False;      } else {         return True;      }   } else {      return False;   }} // End Capability/*------------------------------------------------------------------------ * Function to find or open a connection to the specified IMAP server */ImapServerC*FindImapServer(const char *hostname, long port, Boolean imaps, const char *username){//// See if this one is already connected//   if ( !serverList ) serverList = new PtrListC;   u_int	count = serverList->size();   for (int i=0; i<count; i++) {      ImapServerC	*server = (ImapServerC*)*(*serverList)[i];      if ( server->name == hostname &&           server->port == port     &&           server->user == username ) return server;   }//// Create a new server object//   ImapServerC	*server = new ImapServerC(hostname, username, port, imaps);   return server;} // End FindImapServer/*------------------------------------------------------------------------ * An old restricted form of the above. Should be eventually removed */ImapServerC*FindImapServer(const char *hostname){   if ( !serverList ) serverList = new PtrListC;   u_int	count = serverList->size();   for (int i=0; i<count; i++) {      ImapServerC	*server = (ImapServerC*)*(*serverList)[i];      if ( server->name == hostname ) return server;   }   ImapServerC	*server = new ImapServerC(hostname);   return server;} // End FindImapServer/*------------------------------------------------------------------------ * Function to close the connections to all IMAP servers */voidCloseImapServerConnections(){   if ( !serverList ) return;   u_int	count = serverList->size();   for (int i=count-1; i>=0; i--) {      ImapServerC	*server = (ImapServerC*)*(*serverList)[i];      delete server;   }      serverList->removeAll();   delete serverList;} // CloseImapServerConnections/*------------------------------------------------------------------------ * Function to return the next line from the server */BooleanImapServerC::GetLine(StringC& line){   StringC	errmsg;   char		buf[IMAP_MAXLINE+1];      buf[0]	= 0;//// Return the first line in the list//   if ( lineList->size() > 0 ) {      line = *(*lineList)[0];      lineList->remove((u_int)0);      if ( debuglev > 1 ) cout <<"<< [" <<line <<"]" <<endl;      return True;   }   line.Clear();   StringC	curLine(lastBuf);   CharC	bufStr;   int          readCount;#ifdef HAVE_OPENSSL   if ( TLSEnabled ) {      while (True) {         readCount = SSL_read(ssl, buf, IMAP_MAXLINE);         if ( readCount <= 0 ) {            // FIXME: proper check            return False;         }                  buf[readCount] = 0;         bufStr = buf;   //   // If there's no newline, save this buffer and read some more   //         int	pos = bufStr.PosOf('\n');         if ( pos < 0 ) {	    curLine += bufStr;	    bufStr.CutBeg(bufStr.Length());         }   //   // Extract lines from the buffer   //         else while ( pos >= 0 ) {	    curLine += bufStr(0,pos);	// Copy up to newline	    if ( curLine.EndsWith('\r') ) curLine.CutEnd(1);   //   // See if this line is to be returned   //	    if ( line.size() == 0 )	       line = curLine;	    else	       lineList->add(curLine);   //   // Look for another line   //	    lastBuf[0] = 0;	    bufStr.CutBeg(pos+1);	    curLine.Clear();	    pos = bufStr.PosOf('\n');         } // End for each newline in buffer   //   // If we found a match, we're done   //         if ( line.size() > 0 ) {	    if ( debuglev > 1 ) cout <<"<< [" <<line <<"]" <<endl;            strcpy(lastBuf, bufStr.Addr());	    return True;         }   //   // Copy whatever's left into lastBuf   //         //strcpy(lastBuf, bufStr.Addr());         if (bufStr.Length() > 0)            curLine += bufStr(0,bufStr.Length());      }            return True;   }#endif//// Read lines until we find a match//   fd_set	readSet;   FD_ZERO(&readSet);   struct timeval	timeout;   while ( True ) {//// Check the socket//      int rc;      while (True) {         FD_SET(sock, &readSet);         timeout.tv_sec  = 10;         timeout.tv_usec = 0;         rc = select(sock+1/*width*/, &readSet, NULL, NULL, &timeout);	 //	 // data is available on some socket	 //	 if ( rc > 0 )		break;	 //	 // error occurred	 //         else if ( rc < 0) {            if ( errno == EINTR ) {		if (debuglev > 0) cout << "Select got SIGINTR, retrying" << endl;	    } else {	 	StringC	errmsg;	 	int	err = errno;	 	errmsg = "Could not select socket ";	 	errmsg += sock;	 	errmsg += " for IMAP server ";	 	errmsg += name;	 	errmsg += ".\n" + SystemErrorMessage(err);	 	halApp->PopupMessage(errmsg);	 	return False;	    }	 }	 //	 // timeout	 //         else if ( rc == 0 ) {	    CloseSocket();	    errmsg = "Timeout trying to select the IMAP server\n";	    errmsg += "\n\nRetry?";	    if ( RetryLogin(errmsg) ) {	       //	       // Try to reconnect. Regardless of whether it works, return	       // "False" here so the the operation will be re-tried from	       // the beginning.	       //   	       connected = ReConnect();	    }	    return False;	 }      }//// See if there is data for us//      if ( !FD_ISSET(sock, &readSet) ) continue;      readCount = read(sock, buf, IMAP_MAXLINE);      if ( readCount == 0 ) {	  CloseSocket();	  errmsg = "Timeout trying to select the IMAP server\n";	  errmsg += "\n\nRetry?";	  if ( RetryLogin(errmsg) ) {	     //	     // Try to reconnect. Regardless of whether it works, return	     // "False" here so the the operation will be re-tried from	     // the beginning.	     //   	     connected = ReConnect();	  }	  return False;      }      else if ( readCount < 0 ) {	 StringC	errmsg;	 int	err = errno;	 errmsg = "Could not read socket ";	 errmsg += sock;	 errmsg += " for IMAP server ";	 errmsg += name;	 errmsg += ".\n" + SystemErrorMessage(err);	 halApp->PopupMessage(errmsg);	 return False;      }      buf[readCount] = 0;      if ( debuglev > 2 ) cout <<"Buffer [" <<buf <<"]" <<endl;      bufStr = buf;//// If there's no newline, save this buffer and read some more//      int	pos = bufStr.PosOf('\n');      if ( pos < 0 ) {	 curLine += bufStr;	 bufStr.CutBeg(bufStr.Length());      }//// Extract lines from the buffer//      else while ( pos >= 0 ) {	 curLine += bufStr(0,pos);	// Copy up to newline	 if ( curLine.EndsWith('\r') ) curLine.CutEnd(1);//// See if this line is to be returned//	 if ( line.size() == 0 )	    line = curLine;	 else	    lineList->add(curLine);//// Look for another line//	 lastBuf[0] = 0;	 bufStr.CutBeg(pos+1);	 curLine.Clear();	 pos = bufStr.PosOf('\n');      } // End for each newline in buffer//// If we found a match, we're done//      if ( line.size() > 0 ) {	 if ( debuglev > 1 ) cout <<"<< [" <<line <<"]" <<endl;         strcpy(lastBuf, bufStr.Addr());	 return True;      }//// Copy whatever's left into lastBuf//      //strcpy(lastBuf, bufStr.Addr());      if (bufStr.Length() > 0)         curLine += bufStr(0,bufStr.Length());   } // End while no matching line has been read} // End GetLine/*------------------------------------------------------------------------ * Function to send a command to the server */BooleanImapServerC::PutLine(CharC line, Boolean terminate){   StringC		errmsg;   if ( debuglev > 0 ) {      int	pos = -1;      char	*esc;      if ( TLSEnabled ) {         esc = ">> [";      } else {         esc = ">> [";      }      if ( line.Contains(" LOGIN ") ) pos = line.RevPosOf(' ');      cout <<esc << ((pos >= 0) ? line(0,pos):line) <<"]" <<endl;   }      StringC linebuf(line);//

⌨️ 快捷键说明

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