4 * Copyright 2008 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
33 #include "wine/debug.h"
35 #include "inetcomm_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm
);
49 InternetTransport InetTransport
;
55 enum parse_state state
;
61 static HRESULT
parse_response(POP3Transport
*This
)
67 if (strlen(This
->response
) < 3)
69 WARN("parse error\n");
70 This
->state
= STATE_DONE
;
73 if (!memcmp(This
->response
, "+OK", 3))
75 This
->ptr
= This
->response
+ 3;
76 This
->state
= STATE_OK
;
79 This
->state
= STATE_DONE
;
86 static HRESULT
parse_uidl_response(POP3Transport
*This
, POP3UIDL
*uidl
)
96 if (This
->type
== POP3CMD_GET_POPID
)
98 if ((p
= strchr(This
->ptr
, ' ')))
100 while (*p
== ' ') p
++;
101 sscanf(p
, "%u", &uidl
->dwPopId
);
102 if ((p
= strchr(p
, ' ')))
104 while (*p
== ' ') p
++;
106 This
->valid_info
= TRUE
;
109 This
->state
= STATE_DONE
;
112 This
->state
= STATE_MULTILINE
;
115 case STATE_MULTILINE
:
117 if (This
->response
[0] == '.' && !This
->response
[1])
119 This
->valid_info
= FALSE
;
120 This
->state
= STATE_DONE
;
123 sscanf(This
->response
, "%u", &uidl
->dwPopId
);
124 if ((p
= strchr(This
->response
, ' ')))
126 while (*p
== ' ') p
++;
128 This
->valid_info
= TRUE
;
134 WARN("parse error\n");
135 This
->state
= STATE_DONE
;
141 static HRESULT
parse_stat_response(POP3Transport
*This
, POP3STAT
*stat
)
146 stat
->cbMessages
= 0;
151 if ((p
= strchr(This
->ptr
, ' ')))
153 while (*p
== ' ') p
++;
154 sscanf(p
, "%u %u", &stat
->cMessages
, &stat
->cbMessages
);
155 This
->valid_info
= TRUE
;
156 This
->state
= STATE_DONE
;
162 WARN("parse error\n");
163 This
->state
= STATE_DONE
;
169 static HRESULT
parse_list_response(POP3Transport
*This
, POP3LIST
*list
)
179 if (This
->type
== POP3CMD_GET_POPID
)
181 if ((p
= strchr(This
->ptr
, ' ')))
183 while (*p
== ' ') p
++;
184 sscanf(p
, "%u %u", &list
->dwPopId
, &list
->cbSize
);
185 This
->valid_info
= TRUE
;
187 This
->state
= STATE_DONE
;
190 This
->state
= STATE_MULTILINE
;
193 case STATE_MULTILINE
:
195 if (This
->response
[0] == '.' && !This
->response
[1])
197 This
->valid_info
= FALSE
;
198 This
->state
= STATE_DONE
;
201 sscanf(This
->response
, "%u", &list
->dwPopId
);
202 if ((p
= strchr(This
->response
, ' ')))
204 while (*p
== ' ') p
++;
205 sscanf(p
, "%u", &list
->cbSize
);
206 This
->valid_info
= TRUE
;
212 WARN("parse error\n");
213 This
->state
= STATE_DONE
;
219 static HRESULT
parse_dele_response(POP3Transport
*This
, DWORD
*dwPopId
)
225 *dwPopId
= 0; /* FIXME */
226 This
->state
= STATE_DONE
;
231 WARN("parse error\n");
232 This
->state
= STATE_DONE
;
238 static HRESULT
parse_retr_response(POP3Transport
*This
, POP3RETR
*retr
)
244 retr
->fHeader
= FALSE
;
246 retr
->dwPopId
= This
->msgid
;
248 retr
->pszLines
= This
->response
;
251 This
->state
= STATE_MULTILINE
;
252 This
->valid_info
= FALSE
;
255 case STATE_MULTILINE
:
259 if (This
->response
[0] == '.' && !This
->response
[1])
261 retr
->cbLines
= retr
->cbSoFar
;
262 This
->state
= STATE_DONE
;
265 retr
->fHeader
= TRUE
;
266 if (!This
->response
[0]) retr
->fBody
= TRUE
;
268 len
= strlen(This
->response
);
269 retr
->cbSoFar
+= len
;
270 retr
->pszLines
= This
->response
;
273 This
->valid_info
= TRUE
;
278 WARN("parse error\n");
279 This
->state
= STATE_DONE
;
285 static HRESULT
parse_top_response(POP3Transport
*This
, POP3TOP
*top
)
291 top
->fHeader
= FALSE
;
293 top
->dwPopId
= This
->msgid
;
294 top
->cPreviewLines
= This
->preview_lines
;
296 top
->pszLines
= This
->response
;
299 This
->state
= STATE_MULTILINE
;
300 This
->valid_info
= FALSE
;
303 case STATE_MULTILINE
:
307 if (This
->response
[0] == '.' && !This
->response
[1])
309 top
->cbLines
= top
->cbSoFar
;
310 This
->state
= STATE_DONE
;
314 if (!This
->response
[0]) top
->fBody
= TRUE
;
316 len
= strlen(This
->response
);
318 top
->pszLines
= This
->response
;
321 This
->valid_info
= TRUE
;
326 WARN("parse error\n");
327 This
->state
= STATE_DONE
;
333 static void init_parser(POP3Transport
*This
, POP3COMMAND command
, POP3CMDTYPE type
)
335 This
->state
= STATE_NONE
;
336 This
->command
= command
;
340 static HRESULT
POP3Transport_ParseResponse(POP3Transport
*This
, char *pszResponse
, POP3RESPONSE
*pResponse
)
344 TRACE("response: %s\n", debugstr_a(pszResponse
));
346 This
->response
= pszResponse
;
347 This
->valid_info
= FALSE
;
348 TRACE("state %u\n", This
->state
);
350 if (SUCCEEDED((hr
= parse_response(This
))))
352 switch (This
->command
)
354 case POP3_UIDL
: hr
= parse_uidl_response(This
, &pResponse
->u
.rUidlInfo
); break;
355 case POP3_STAT
: hr
= parse_stat_response(This
, &pResponse
->u
.rStatInfo
); break;
356 case POP3_LIST
: hr
= parse_list_response(This
, &pResponse
->u
.rListInfo
); break;
357 case POP3_DELE
: hr
= parse_dele_response(This
, &pResponse
->u
.dwPopId
); break;
358 case POP3_RETR
: hr
= parse_retr_response(This
, &pResponse
->u
.rRetrInfo
); break;
359 case POP3_TOP
: hr
= parse_top_response(This
, &pResponse
->u
.rTopInfo
); break;
361 This
->state
= STATE_DONE
;
365 pResponse
->command
= This
->command
;
366 pResponse
->fDone
= (This
->state
== STATE_DONE
);
367 pResponse
->fValidInfo
= This
->valid_info
;
368 pResponse
->rIxpResult
.hrResult
= hr
;
369 pResponse
->rIxpResult
.pszResponse
= pszResponse
;
370 pResponse
->rIxpResult
.uiServerError
= 0;
371 pResponse
->rIxpResult
.hrServerError
= pResponse
->rIxpResult
.hrResult
;
372 pResponse
->rIxpResult
.dwSocketError
= WSAGetLastError();
373 pResponse
->rIxpResult
.pszProblem
= NULL
;
374 pResponse
->pTransport
= (IPOP3Transport
*)&This
->InetTransport
.u
.vtblPOP3
;
376 if (This
->InetTransport
.pCallback
&& This
->InetTransport
.fCommandLogging
)
378 ITransportCallback_OnCommand(This
->InetTransport
.pCallback
, CMD_RESP
,
379 pResponse
->rIxpResult
.pszResponse
, pResponse
->rIxpResult
.hrServerError
,
380 (IInternetTransport
*)&This
->InetTransport
.u
.vtbl
);
385 static void POP3Transport_CallbackProcessDELEResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
387 POP3Transport
*This
= (POP3Transport
*)iface
;
388 POP3RESPONSE response
;
393 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
396 /* FIXME: handle error */
400 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
403 static void POP3Transport_CallbackRecvDELEResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
405 POP3Transport
*This
= (POP3Transport
*)iface
;
408 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessDELEResp
);
411 static void POP3Transport_CallbackProcessNOOPResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
413 POP3Transport
*This
= (POP3Transport
*)iface
;
414 POP3RESPONSE response
;
419 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
422 /* FIXME: handle error */
426 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
429 static void POP3Transport_CallbackRecvNOOPResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
431 POP3Transport
*This
= (POP3Transport
*)iface
;
434 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessNOOPResp
);
437 static void POP3Transport_CallbackProcessRSETResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
439 POP3Transport
*This
= (POP3Transport
*)iface
;
440 POP3RESPONSE response
;
445 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
448 /* FIXME: handle error */
452 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
455 static void POP3Transport_CallbackRecvRSETResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
457 POP3Transport
*This
= (POP3Transport
*)iface
;
460 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessRSETResp
);
463 static void POP3Transport_CallbackProcessRETRResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
465 POP3Transport
*This
= (POP3Transport
*)iface
;
466 POP3RESPONSE response
;
471 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
474 /* FIXME: handle error */
478 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
482 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessRETRResp
);
486 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
489 static void POP3Transport_CallbackRecvRETRResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
491 POP3Transport
*This
= (POP3Transport
*)iface
;
494 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessRETRResp
);
497 static void POP3Transport_CallbackProcessTOPResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
499 POP3Transport
*This
= (POP3Transport
*)iface
;
500 POP3RESPONSE response
;
505 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
508 /* FIXME: handle error */
512 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
516 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessTOPResp
);
520 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
523 static void POP3Transport_CallbackRecvTOPResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
525 POP3Transport
*This
= (POP3Transport
*)iface
;
528 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessTOPResp
);
531 static void POP3Transport_CallbackProcessLISTResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
533 POP3Transport
*This
= (POP3Transport
*)iface
;
534 POP3RESPONSE response
;
539 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
542 /* FIXME: handle error */
546 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
550 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessLISTResp
);
554 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
557 static void POP3Transport_CallbackRecvLISTResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
559 POP3Transport
*This
= (POP3Transport
*)iface
;
562 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessLISTResp
);
565 static void POP3Transport_CallbackProcessUIDLResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
567 POP3Transport
*This
= (POP3Transport
*)iface
;
568 POP3RESPONSE response
;
573 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
576 /* FIXME: handle error */
580 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
584 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessUIDLResp
);
588 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
591 static void POP3Transport_CallbackRecvUIDLResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
593 POP3Transport
*This
= (POP3Transport
*)iface
;
596 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessUIDLResp
);
599 static void POP3Transport_CallbackProcessSTATResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
601 POP3Transport
*This
= (POP3Transport
*)iface
;
602 POP3RESPONSE response
;
607 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
610 /* FIXME: handle error */
614 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
617 static void POP3Transport_CallbackRecvSTATResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
619 POP3Transport
*This
= (POP3Transport
*)iface
;
622 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessSTATResp
);
625 static void POP3Transport_CallbackProcessPASSResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
627 POP3Transport
*This
= (POP3Transport
*)iface
;
628 POP3RESPONSE response
;
633 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
636 /* FIXME: handle error */
640 InternetTransport_ChangeStatus(&This
->InetTransport
, IXP_AUTHORIZED
);
641 InternetTransport_ChangeStatus(&This
->InetTransport
, IXP_CONNECTED
);
643 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
646 static void POP3Transport_CallbackRecvPASSResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
648 POP3Transport
*This
= (POP3Transport
*)iface
;
651 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessPASSResp
);
654 static void POP3Transport_CallbackProcessUSERResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
656 static char pass
[] = "PASS ";
657 POP3Transport
*This
= (POP3Transport
*)iface
;
658 POP3RESPONSE response
;
665 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
668 /* FIXME: handle error */
672 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
674 len
= sizeof(pass
) + strlen(This
->InetTransport
.ServerInfo
.szPassword
) + 2; /* "\r\n" */
675 command
= HeapAlloc(GetProcessHeap(), 0, len
);
677 strcpy(command
, pass
);
678 strcat(command
, This
->InetTransport
.ServerInfo
.szPassword
);
679 strcat(command
, "\r\n");
681 init_parser(This
, POP3_PASS
, POP3_NONE
);
683 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvPASSResp
);
684 HeapFree(GetProcessHeap(), 0, command
);
687 static void POP3Transport_CallbackRecvUSERResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
689 POP3Transport
*This
= (POP3Transport
*)iface
;
692 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessUSERResp
);
695 static void POP3Transport_CallbackSendUSERCmd(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
697 static char user
[] = "USER ";
698 POP3Transport
*This
= (POP3Transport
*)iface
;
704 len
= sizeof(user
) + strlen(This
->InetTransport
.ServerInfo
.szUserName
) + 2; /* "\r\n" */
705 command
= HeapAlloc(GetProcessHeap(), 0, len
);
707 strcpy(command
, user
);
708 strcat(command
, This
->InetTransport
.ServerInfo
.szUserName
);
709 strcat(command
, "\r\n");
710 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvUSERResp
);
712 HeapFree(GetProcessHeap(), 0, command
);
715 static void POP3Transport_CallbackProcessQUITResponse(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
717 POP3Transport
*This
= (POP3Transport
*)iface
;
718 POP3RESPONSE response
;
721 TRACE("%s\n", debugstr_an(pBuffer
, cbBuffer
));
723 hr
= POP3Transport_ParseResponse(This
, pBuffer
, &response
);
726 /* FIXME: handle error */
730 IPOP3Callback_OnResponse((IPOP3Callback
*)This
->InetTransport
.pCallback
, &response
);
731 InternetTransport_DropConnection(&This
->InetTransport
);
734 static void POP3Transport_CallbackRecvQUITResp(IInternetTransport
*iface
, char *pBuffer
, int cbBuffer
)
736 POP3Transport
*This
= (POP3Transport
*)iface
;
739 InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackProcessQUITResponse
);
742 static HRESULT WINAPI
POP3Transport_QueryInterface(IPOP3Transport
*iface
, REFIID riid
, void **ppv
)
744 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
746 if (IsEqualIID(riid
, &IID_IUnknown
) ||
747 IsEqualIID(riid
, &IID_IInternetTransport
) ||
748 IsEqualIID(riid
, &IID_IPOP3Transport
))
751 IUnknown_AddRef(iface
);
755 FIXME("no interface for %s\n", debugstr_guid(riid
));
756 return E_NOINTERFACE
;
759 static ULONG WINAPI
POP3Transport_AddRef(IPOP3Transport
*iface
)
761 POP3Transport
*This
= (POP3Transport
*)iface
;
762 return InterlockedIncrement((LONG
*)&This
->refs
);
765 static ULONG WINAPI
POP3Transport_Release(IPOP3Transport
*iface
)
767 POP3Transport
*This
= (POP3Transport
*)iface
;
768 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
771 TRACE("destroying %p\n", This
);
772 if (This
->InetTransport
.Status
!= IXP_DISCONNECTED
)
773 InternetTransport_DropConnection(&This
->InetTransport
);
774 if (This
->InetTransport
.pCallback
) ITransportCallback_Release(This
->InetTransport
.pCallback
);
775 HeapFree(GetProcessHeap(), 0, This
);
780 static HRESULT WINAPI
POP3Transport_GetServerInfo(IPOP3Transport
*iface
,
781 LPINETSERVER pInetServer
)
783 POP3Transport
*This
= (POP3Transport
*)iface
;
785 TRACE("(%p)\n", pInetServer
);
786 return InternetTransport_GetServerInfo(&This
->InetTransport
, pInetServer
);
789 static IXPTYPE WINAPI
POP3Transport_GetIXPType(IPOP3Transport
*iface
)
795 static HRESULT WINAPI
POP3Transport_IsState(IPOP3Transport
*iface
, IXPISSTATE isstate
)
797 FIXME("(%u)\n", isstate
);
801 static HRESULT WINAPI
POP3Transport_InetServerFromAccount(
802 IPOP3Transport
*iface
, IImnAccount
*pAccount
, LPINETSERVER pInetServer
)
804 POP3Transport
*This
= (POP3Transport
*)iface
;
806 TRACE("(%p, %p)\n", pAccount
, pInetServer
);
807 return InternetTransport_InetServerFromAccount(&This
->InetTransport
, pAccount
, pInetServer
);
810 static HRESULT WINAPI
POP3Transport_Connect(IPOP3Transport
*iface
,
811 LPINETSERVER pInetServer
, boolean fAuthenticate
, boolean fCommandLogging
)
813 POP3Transport
*This
= (POP3Transport
*)iface
;
816 TRACE("(%p, %s, %s)\n", pInetServer
, fAuthenticate
? "TRUE" : "FALSE", fCommandLogging
? "TRUE" : "FALSE");
818 hr
= InternetTransport_Connect(&This
->InetTransport
, pInetServer
, fAuthenticate
, fCommandLogging
);
822 init_parser(This
, POP3_USER
, POP3_NONE
);
823 return InternetTransport_ReadLine(&This
->InetTransport
, POP3Transport_CallbackSendUSERCmd
);
826 static HRESULT WINAPI
POP3Transport_HandsOffCallback(IPOP3Transport
*iface
)
828 POP3Transport
*This
= (POP3Transport
*)iface
;
831 return InternetTransport_HandsOffCallback(&This
->InetTransport
);
834 static HRESULT WINAPI
POP3Transport_Disconnect(IPOP3Transport
*iface
)
837 return IPOP3Transport_CommandQUIT(iface
);
840 static HRESULT WINAPI
POP3Transport_DropConnection(IPOP3Transport
*iface
)
842 POP3Transport
*This
= (POP3Transport
*)iface
;
845 return InternetTransport_DropConnection(&This
->InetTransport
);
848 static HRESULT WINAPI
POP3Transport_GetStatus(IPOP3Transport
*iface
,
849 IXPSTATUS
*pCurrentStatus
)
851 POP3Transport
*This
= (POP3Transport
*)iface
;
854 return InternetTransport_GetStatus(&This
->InetTransport
, pCurrentStatus
);
857 static HRESULT WINAPI
POP3Transport_InitNew(IPOP3Transport
*iface
,
858 LPSTR pszLogFilePath
, IPOP3Callback
*pCallback
)
860 POP3Transport
*This
= (POP3Transport
*)iface
;
862 TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath
), pCallback
);
868 FIXME("not using log file of %s, use Wine debug logging instead\n",
869 debugstr_a(pszLogFilePath
));
871 IPOP3Callback_AddRef(pCallback
);
872 This
->InetTransport
.pCallback
= (ITransportCallback
*)pCallback
;
873 This
->InetTransport
.fInitialised
= TRUE
;
878 static HRESULT WINAPI
POP3Transport_MarkItem(IPOP3Transport
*iface
, POP3MARKTYPE marktype
,
879 DWORD dwPopId
, boolean fMarked
)
881 FIXME("(%u, %u, %d)\n", marktype
, dwPopId
, fMarked
);
885 static HRESULT WINAPI
POP3Transport_CommandAUTH(IPOP3Transport
*iface
, LPSTR pszAuthType
)
887 FIXME("(%s)\n", pszAuthType
);
891 static HRESULT WINAPI
POP3Transport_CommandUSER(IPOP3Transport
*iface
, LPSTR username
)
893 static char user
[] = "USER ";
894 POP3Transport
*This
= (POP3Transport
*)iface
;
898 TRACE("(%s)\n", username
);
900 len
= sizeof(user
) + strlen(username
) + 2; /* "\r\n" */
901 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
903 strcpy(command
, user
);
904 strcat(command
, username
);
905 strcat(command
, "\r\n");
907 init_parser(This
, POP3_USER
, POP3_NONE
);
908 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvUSERResp
);
910 HeapFree(GetProcessHeap(), 0, command
);
914 static HRESULT WINAPI
POP3Transport_CommandPASS(IPOP3Transport
*iface
, LPSTR password
)
916 static char pass
[] = "PASS ";
917 POP3Transport
*This
= (POP3Transport
*)iface
;
921 TRACE("(%p)\n", password
);
923 len
= sizeof(pass
) + strlen(password
) + 2; /* "\r\n" */
924 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
926 strcpy(command
, pass
);
927 strcat(command
, password
);
928 strcat(command
, "\r\n");
930 init_parser(This
, POP3_PASS
, POP3_NONE
);
931 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvPASSResp
);
933 HeapFree(GetProcessHeap(), 0, command
);
937 static HRESULT WINAPI
POP3Transport_CommandLIST(
938 IPOP3Transport
*iface
, POP3CMDTYPE cmdtype
, DWORD dwPopId
)
940 static char list
[] = "LIST %u\r\n";
941 static char list_all
[] = "LIST\r\n";
942 POP3Transport
*This
= (POP3Transport
*)iface
;
946 TRACE("(%u, %u)\n", cmdtype
, dwPopId
);
950 len
= sizeof(list
) + 10 + 2; /* "4294967296" + "\r\n" */
951 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
952 sprintf(command
, list
, dwPopId
);
954 else command
= list_all
;
956 init_parser(This
, POP3_LIST
, cmdtype
);
957 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvLISTResp
);
959 if (dwPopId
) HeapFree(GetProcessHeap(), 0, command
);
963 static HRESULT WINAPI
POP3Transport_CommandTOP(
964 IPOP3Transport
*iface
, POP3CMDTYPE cmdtype
, DWORD dwPopId
, DWORD cPreviewLines
)
966 static char top
[] = "TOP %u %u\r\n";
967 POP3Transport
*This
= (POP3Transport
*)iface
;
971 TRACE("(%u, %u, %u)\n", cmdtype
, dwPopId
, cPreviewLines
);
973 len
= sizeof(top
) + 20 + 2; /* 2 * "4294967296" + "\r\n" */
974 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
975 sprintf(command
, top
, dwPopId
, cPreviewLines
);
977 This
->preview_lines
= cPreviewLines
;
978 init_parser(This
, POP3_TOP
, cmdtype
);
979 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvTOPResp
);
981 HeapFree(GetProcessHeap(), 0, command
);
985 static HRESULT WINAPI
POP3Transport_CommandQUIT(IPOP3Transport
*iface
)
987 static char command
[] = "QUIT\r\n";
988 POP3Transport
*This
= (POP3Transport
*)iface
;
992 InternetTransport_ChangeStatus(&This
->InetTransport
, IXP_DISCONNECTING
);
994 init_parser(This
, POP3_QUIT
, POP3_NONE
);
995 return InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvQUITResp
);
998 static HRESULT WINAPI
POP3Transport_CommandSTAT(IPOP3Transport
*iface
)
1000 static char stat
[] = "STAT\r\n";
1001 POP3Transport
*This
= (POP3Transport
*)iface
;
1005 init_parser(This
, POP3_STAT
, POP3_NONE
);
1006 InternetTransport_DoCommand(&This
->InetTransport
, stat
, POP3Transport_CallbackRecvSTATResp
);
1010 static HRESULT WINAPI
POP3Transport_CommandNOOP(IPOP3Transport
*iface
)
1012 static char noop
[] = "NOOP\r\n";
1013 POP3Transport
*This
= (POP3Transport
*)iface
;
1017 init_parser(This
, POP3_NOOP
, POP3_NONE
);
1018 InternetTransport_DoCommand(&This
->InetTransport
, noop
, POP3Transport_CallbackRecvNOOPResp
);
1022 static HRESULT WINAPI
POP3Transport_CommandRSET(IPOP3Transport
*iface
)
1024 static char rset
[] = "RSET\r\n";
1025 POP3Transport
*This
= (POP3Transport
*)iface
;
1029 init_parser(This
, POP3_RSET
, POP3_NONE
);
1030 InternetTransport_DoCommand(&This
->InetTransport
, rset
, POP3Transport_CallbackRecvRSETResp
);
1034 static HRESULT WINAPI
POP3Transport_CommandUIDL(
1035 IPOP3Transport
*iface
, POP3CMDTYPE cmdtype
, DWORD dwPopId
)
1037 static char uidl
[] = "UIDL %u\r\n";
1038 static char uidl_all
[] = "UIDL\r\n";
1039 POP3Transport
*This
= (POP3Transport
*)iface
;
1043 TRACE("(%u, %u)\n", cmdtype
, dwPopId
);
1047 len
= sizeof(uidl
) + 10 + 2; /* "4294967296" + "\r\n" */
1048 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
1049 sprintf(command
, uidl
, dwPopId
);
1051 else command
= uidl_all
;
1053 init_parser(This
, POP3_UIDL
, cmdtype
);
1054 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvUIDLResp
);
1056 if (dwPopId
) HeapFree(GetProcessHeap(), 0, command
);
1060 static HRESULT WINAPI
POP3Transport_CommandDELE(
1061 IPOP3Transport
*iface
, POP3CMDTYPE cmdtype
, DWORD dwPopId
)
1063 static char dele
[] = "DELE %u\r\n";
1064 POP3Transport
*This
= (POP3Transport
*)iface
;
1068 TRACE("(%u, %u)\n", cmdtype
, dwPopId
);
1070 len
= sizeof(dele
) + 10 + 2; /* "4294967296" + "\r\n" */
1071 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
1072 sprintf(command
, dele
, dwPopId
);
1074 init_parser(This
, POP3_DELE
, cmdtype
);
1075 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvDELEResp
);
1077 HeapFree(GetProcessHeap(), 0, command
);
1081 static HRESULT WINAPI
POP3Transport_CommandRETR(
1082 IPOP3Transport
*iface
, POP3CMDTYPE cmdtype
, DWORD dwPopId
)
1084 static char retr
[] = "RETR %u\r\n";
1085 POP3Transport
*This
= (POP3Transport
*)iface
;
1089 TRACE("(%u, %u)\n", cmdtype
, dwPopId
);
1091 len
= sizeof(retr
) + 10 + 2; /* "4294967296" + "\r\n" */
1092 if (!(command
= HeapAlloc(GetProcessHeap(), 0, len
))) return S_FALSE
;
1093 sprintf(command
, retr
, dwPopId
);
1095 init_parser(This
, POP3_RETR
, cmdtype
);
1096 InternetTransport_DoCommand(&This
->InetTransport
, command
, POP3Transport_CallbackRecvRETRResp
);
1098 HeapFree(GetProcessHeap(), 0, command
);
1102 static const IPOP3TransportVtbl POP3TransportVtbl
=
1104 POP3Transport_QueryInterface
,
1105 POP3Transport_AddRef
,
1106 POP3Transport_Release
,
1107 POP3Transport_GetServerInfo
,
1108 POP3Transport_GetIXPType
,
1109 POP3Transport_IsState
,
1110 POP3Transport_InetServerFromAccount
,
1111 POP3Transport_Connect
,
1112 POP3Transport_HandsOffCallback
,
1113 POP3Transport_Disconnect
,
1114 POP3Transport_DropConnection
,
1115 POP3Transport_GetStatus
,
1116 POP3Transport_InitNew
,
1117 POP3Transport_MarkItem
,
1118 POP3Transport_CommandAUTH
,
1119 POP3Transport_CommandUSER
,
1120 POP3Transport_CommandPASS
,
1121 POP3Transport_CommandLIST
,
1122 POP3Transport_CommandTOP
,
1123 POP3Transport_CommandQUIT
,
1124 POP3Transport_CommandSTAT
,
1125 POP3Transport_CommandNOOP
,
1126 POP3Transport_CommandRSET
,
1127 POP3Transport_CommandUIDL
,
1128 POP3Transport_CommandDELE
,
1129 POP3Transport_CommandRETR
1132 HRESULT WINAPI
CreatePOP3Transport(IPOP3Transport
**ppTransport
)
1135 POP3Transport
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1137 return E_OUTOFMEMORY
;
1139 This
->InetTransport
.u
.vtblPOP3
= &POP3TransportVtbl
;
1141 hr
= InternetTransport_Init(&This
->InetTransport
);
1144 HeapFree(GetProcessHeap(), 0, This
);
1148 *ppTransport
= (IPOP3Transport
*)&This
->InetTransport
.u
.vtblPOP3
;
1149 IPOP3Transport_AddRef(*ppTransport
);
1154 static HRESULT WINAPI
POP3TransportCF_QueryInterface(LPCLASSFACTORY iface
,
1155 REFIID riid
, LPVOID
*ppv
)
1158 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IClassFactory
))
1161 IUnknown_AddRef(iface
);
1164 return E_NOINTERFACE
;
1167 static ULONG WINAPI
POP3TransportCF_AddRef(LPCLASSFACTORY iface
)
1169 return 2; /* non-heap based object */
1172 static ULONG WINAPI
POP3TransportCF_Release(LPCLASSFACTORY iface
)
1174 return 1; /* non-heap based object */
1177 static HRESULT WINAPI
POP3TransportCF_CreateInstance(LPCLASSFACTORY iface
,
1178 LPUNKNOWN pUnk
, REFIID riid
, LPVOID
*ppv
)
1181 IPOP3Transport
*pPop3Transport
;
1183 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
1188 return CLASS_E_NOAGGREGATION
;
1190 hr
= CreatePOP3Transport(&pPop3Transport
);
1194 hr
= IPOP3Transport_QueryInterface(pPop3Transport
, riid
, ppv
);
1195 IPOP3Transport_Release(pPop3Transport
);
1200 static HRESULT WINAPI
POP3TransportCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
1202 FIXME("(%d)\n",fLock
);
1206 static const IClassFactoryVtbl POP3TransportCFVtbl
=
1208 POP3TransportCF_QueryInterface
,
1209 POP3TransportCF_AddRef
,
1210 POP3TransportCF_Release
,
1211 POP3TransportCF_CreateInstance
,
1212 POP3TransportCF_LockServer
1214 static const IClassFactoryVtbl
*POP3TransportCF
= &POP3TransportCFVtbl
;
1216 HRESULT
POP3TransportCF_Create(REFIID riid
, LPVOID
*ppv
)
1218 return IClassFactory_QueryInterface((IClassFactory
*)&POP3TransportCF
, riid
, ppv
);