/** * @brief lineread Handler; understands when to read more POP3 lines, * and when this is a one-lined reply. */ eReadState POP3_C_ReadServerStatus(AsyncIO *IO) { eReadState Finished = eBufferNotEmpty; switch (IO->NextState) { case eSendDNSQuery: case eReadDNSReply: case eDBQuery: case eConnect: case eTerminateConnection: case eAbort: Finished = eReadFail; break; case eSendFile: case eSendReply: case eSendMore: case eReadMore: case eReadMessage: Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf); break; case eReadFile: case eReadPayload: Finished = CtdlReadMessageBodyAsync(IO); break; } return Finished; }
/** * @brief lineread Handler; * understands when to read more SMTP lines, and when this is a one-lined reply. */ eReadState SMTP_C_ReadServerStatus(AsyncIO *IO) { eReadState Finished = eBufferNotEmpty; while (Finished == eBufferNotEmpty) { Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf); switch (Finished) { case eMustReadMore: /// read new from socket... return Finished; break; case eBufferNotEmpty: /* shouldn't happen... */ case eReadSuccess: /// done for now... if (StrLength(IO->IOBuf) < 4) continue; if (ChrPtr(IO->IOBuf)[3] == '-') { SmtpOutMsg *Msg; Msg = (SmtpOutMsg *)IO->Data; if (Msg->MultiLineBuf == NULL) Msg->MultiLineBuf = NewStrBuf (); else StrBufAppendBufPlain(Msg->MultiLineBuf, HKEY("\n"), 0); StrBufAppendBuf(Msg->MultiLineBuf, IO->IOBuf, 0); Finished = eBufferNotEmpty; } else return Finished; break; case eReadFail: /// WHUT? ///todo: shut down! break; } } return Finished; }
eReadState HandleInbound(AsyncIO *IO) { const char *Err = NULL; eReadState Finished = eBufferNotEmpty; become_session(IO->CitContext); while ((Finished == eBufferNotEmpty) && ((IO->NextState == eReadMessage)|| (IO->NextState == eReadMore)|| (IO->NextState == eReadFile)|| (IO->NextState == eReadPayload))) { /* Reading lines... * lex line reply in callback, * or do it ourselves. * i.e. as nnn-blabla means continue reading in SMTP */ if ((IO->NextState == eReadFile) && (Finished == eBufferNotEmpty)) { Finished = WriteIOBAlreadyRead(&IO->IOB, &Err); if (Finished == eReadSuccess) { IO->NextState = eSendReply; } } else if (IO->LineReader) Finished = IO->LineReader(IO); else Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf); switch (Finished) { case eMustReadMore: /// read new from socket... break; case eBufferNotEmpty: /* shouldn't happen... */ case eReadSuccess: /// done for now... break; case eReadFail: /// WHUT? ///todo: shut down! break; } if (Finished != eMustReadMore) { ev_io_stop(event_base, &IO->recv_event); IO->NextState = IO->ReadDone(IO); if (IO->NextState == eDBQuery) { if (QueueAnDBOperation(IO) == eAbort) return eReadFail; else return eReadSuccess; } else { Finished = StrBufCheckBuffer(&IO->RecvBuf); } } } PostInbound(IO); return Finished; }