static HRESULT WINAPI SMTPTransport_CommandQUIT(ISMTPTransport2 *iface) { SMTPTransport *This = (SMTPTransport *)iface; TRACE("()\n"); InternetTransport_ChangeStatus(&This->InetTransport, IXP_DISCONNECTING); return InternetTransport_DoCommand(&This->InetTransport, "QUIT\n", SMTPTransport_CallbackDisconnect); }
static void SMTPTransport_CallbackProcessHelloResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) { SMTPTransport *This = (SMTPTransport *)iface; SMTPRESPONSE response = { 0 }; HRESULT hr; TRACE("\n"); hr = SMTPTransport_ParseResponse(This, pBuffer, &response); if (FAILED(hr)) { /* FIXME: handle error */ return; } response.command = This->fESMTP ? SMTP_EHLO : SMTP_HELO; ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); if (FAILED(response.rIxpResult.hrServerError)) { ERR("server error: %s\n", debugstr_a(pBuffer)); /* FIXME: handle error */ return; } if (!response.fDone) { InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackProcessHelloResp); return; } /* FIXME: try to authorize */ /* always changed to this status, even if authorization not support on server */ InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED); InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED); memset(&response, 0, sizeof(response)); response.command = SMTP_CONNECTED; response.fDone = TRUE; ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); }
HRESULT InternetTransport_DropConnection(InternetTransport *This) { int ret; if (This->Status == IXP_DISCONNECTED) return IXP_E_NOT_CONNECTED; ret = shutdown(This->Socket, SD_BOTH); ret = closesocket(This->Socket); DestroyWindow(This->hwnd); This->hwnd = NULL; InternetTransport_ChangeStatus(This, IXP_DISCONNECTED); return S_OK; }
HRESULT InternetTransport_Connect(InternetTransport *This, LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) { struct addrinfo *ai; struct addrinfo *ai_cur; struct addrinfo hints; int ret; char szPort[10]; if (This->Status != IXP_DISCONNECTED) return IXP_E_ALREADY_CONNECTED; This->ServerInfo = *pInetServer; This->fCommandLogging = fCommandLogging; This->hwnd = CreateWindowW(wszClassName, wszClassName, 0, 0, 0, 0, 0, NULL, NULL, NULL, 0); if (!This->hwnd) return HRESULT_FROM_WIN32(GetLastError()); SetWindowLongPtrW(This->hwnd, GWLP_USERDATA, (LONG_PTR)This); hints.ai_flags = 0; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_addrlen = 0; hints.ai_addr = NULL; hints.ai_canonname = NULL; hints.ai_next = NULL; snprintf(szPort, sizeof(szPort), "%d", (unsigned short)pInetServer->dwPort); InternetTransport_ChangeStatus(This, IXP_FINDINGHOST); ret = getaddrinfo(pInetServer->szServerName, szPort, &hints, &ai); if (ret) { ERR("getaddrinfo failed: %d\n", ret); return IXP_E_CANT_FIND_HOST; } for (ai_cur = ai; ai_cur; ai_cur = ai->ai_next) { int so; if (TRACE_ON(inetcomm)) { char host[256]; char service[256]; getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV); TRACE("trying %s:%s\n", host, service); } InternetTransport_ChangeStatus(This, IXP_CONNECTING); so = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); if (so == -1) { WARN("socket() failed\n"); continue; } This->Socket = so; /* FIXME: set to async */ if (0 > connect(This->Socket, ai_cur->ai_addr, ai_cur->ai_addrlen)) { WARN("connect() failed\n"); closesocket(This->Socket); continue; } InternetTransport_ChangeStatus(This, IXP_CONNECTED); /* FIXME: call WSAAsyncSelect */ freeaddrinfo(ai); TRACE("connected\n"); return S_OK; } freeaddrinfo(ai); return IXP_E_CANT_FIND_HOST; }