void EvalXTCPRecv(const void *obj, qCtx *ctx, qStr *out, qArgAry *args) { Sock *s = (Sock *) obj; int len; char *line = NULL; if (args->Count() > 0) { len = ParseInt((*args)[0]); len = s->Read(len); line = s->GetBuf(); } else { len = s->ReadLine(&line); } if (len > 0) out->PutS(line, len); else if (len < 0 ) { if (len == Sock::ERR_TIMEOUT) { ctx->ThrowF(out, 702, "Timeout while waiting to read data from host %s:%d, %y", s->GetHost(), s->GetPort()); } else { ctx->ThrowF(out, 702, "Error while reading data from host %s:%d, %y", s->GetHost(), s->GetPort(), GetLastError()); } } }
int qsmtp(qMailOpts *popts) { Sock *pSock = NULL; int rval = 0; try { if (popts->timeout == 0.0F) popts->timeout = QM_TIMEOUT; else if (popts->timeout < QM_TIMEOUT_MIN) popts->timeout = QM_TIMEOUT_MIN; if (!popts->port) popts->port = QM_SMTP_PORT; if (!popts->smtp) throw qEx(199, "Host was not specified"); if (!popts->rcpt) throw qEx(198, "Must specify recipient."); if (!popts->to && !strchr((const char *)popts->rcpt,';')) popts->to = popts->rcpt; if (!popts->helo) popts->helo = popts->smtp; const char *host = popts->smtp; int port = popts->port; pSock = new Sock; pSock->SetTimeout(popts->timeout); int sock_err = pSock->Open(host, port); if (sock_err == Sock::ERR_GETHOST) throw qEx(QM_ERR_SOCK_GETHOST, QM_ERR_SOCK_GETHOST_RC, host); else if (sock_err == Sock::ERR_CONNECT) throw qEx(QM_ERR_SOCK_CONNECT, QM_ERR_SOCK_CONNECT_RC, host, port); else if (sock_err == Sock::ERR_TIMEOUT) throw qEx(QM_ERR_SOCK_CONNECT, QM_ERR_SOCK_CONNECT_RC, host, port); else if (sock_err) throw qEx(sock_err, "Connect to host %s, error #%d", host, sock_err); qMailState state; int multi; char *line, *pcur; int errs; CStr request; state.opts = popts; state.proto = 1; state.code = 0; pSock->ReadLine(&line); do { errs = smtp_next(&state, request); if (errs > Q_ERRTHRESH) { char *p = request.Length() ? strrchr((const char *) request,'\r') : NULL; if (p) *p = '\0'; throw qEx(QM_ERR_SMTP_THRESH, QM_ERR_SMTP_THRESH_RC, errs, (const char *) request); } if (pSock->Write(request, request.Length()) < 0) throw qEx(QM_ERR_SOCK_WRITE_REQ, QM_ERR_SOCK_WRITE_REQ_RC, host); if (state.proto != qsBlock && state.proto != qsQuit) { do { if (pSock->ReadLine(&line) < 0) throw qEx(QM_ERR_SOCK_READ_REQ, QM_ERR_SOCK_READ_REQ_RC, host); state.code = strtol(line, &pcur, 10); multi = (*pcur++ == '-'); smtp_resp(&state, pcur); } while (multi); } } while (state.proto); } catch (CEx pEx) { if (pSock) delete pSock; pSock = NULL; throw pEx; } catch (...) { rval = 999; } if (pSock) delete pSock; return rval; }