Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpop3transport.c
Go to the documentation of this file.
00001 /* 00002 * POP3 Transport 00003 * 00004 * Copyright 2008 Hans Leidekker for CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #define COBJMACROS 00022 #define NONAMELESSUNION 00023 00024 #include <stdarg.h> 00025 #include <stdio.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "winnt.h" 00030 #include "winuser.h" 00031 #include "objbase.h" 00032 #include "mimeole.h" 00033 #include "wine/debug.h" 00034 00035 #include "inetcomm_private.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); 00038 00039 enum parse_state 00040 { 00041 STATE_NONE, 00042 STATE_OK, 00043 STATE_MULTILINE, 00044 STATE_DONE 00045 }; 00046 00047 typedef struct 00048 { 00049 InternetTransport InetTransport; 00050 ULONG refs; 00051 POP3COMMAND command; 00052 POP3CMDTYPE type; 00053 char *response; 00054 char *ptr; 00055 enum parse_state state; 00056 BOOL valid_info; 00057 DWORD msgid; 00058 DWORD preview_lines; 00059 } POP3Transport; 00060 00061 static HRESULT parse_response(POP3Transport *This) 00062 { 00063 switch (This->state) 00064 { 00065 case STATE_NONE: 00066 if (strlen(This->response) < 3) 00067 { 00068 WARN("parse error\n"); 00069 This->state = STATE_DONE; 00070 return S_FALSE; 00071 } 00072 if (!memcmp(This->response, "+OK", 3)) 00073 { 00074 This->ptr = This->response + 3; 00075 This->state = STATE_OK; 00076 return S_OK; 00077 } 00078 This->state = STATE_DONE; 00079 return S_FALSE; 00080 00081 default: return S_OK; 00082 } 00083 } 00084 00085 static HRESULT parse_uidl_response(POP3Transport *This, POP3UIDL *uidl) 00086 { 00087 char *p; 00088 00089 uidl->dwPopId = 0; 00090 uidl->pszUidl = NULL; 00091 switch (This->state) 00092 { 00093 case STATE_OK: 00094 if (This->type == POP3CMD_GET_POPID) 00095 { 00096 if ((p = strchr(This->ptr, ' '))) 00097 { 00098 while (*p == ' ') p++; 00099 sscanf(p, "%u", &uidl->dwPopId); 00100 if ((p = strchr(p, ' '))) 00101 { 00102 while (*p == ' ') p++; 00103 uidl->pszUidl = p; 00104 This->valid_info = TRUE; 00105 } 00106 } 00107 This->state = STATE_DONE; 00108 return S_OK; 00109 } 00110 This->state = STATE_MULTILINE; 00111 return S_OK; 00112 00113 case STATE_MULTILINE: 00114 if (This->response[0] == '.' && !This->response[1]) 00115 { 00116 This->valid_info = FALSE; 00117 This->state = STATE_DONE; 00118 return S_OK; 00119 } 00120 sscanf(This->response, "%u", &uidl->dwPopId); 00121 if ((p = strchr(This->response, ' '))) 00122 { 00123 while (*p == ' ') p++; 00124 uidl->pszUidl = p; 00125 This->valid_info = TRUE; 00126 return S_OK; 00127 } 00128 00129 default: 00130 WARN("parse error\n"); 00131 This->state = STATE_DONE; 00132 return S_FALSE; 00133 } 00134 } 00135 00136 static HRESULT parse_stat_response(POP3Transport *This, POP3STAT *stat) 00137 { 00138 char *p; 00139 00140 stat->cMessages = 0; 00141 stat->cbMessages = 0; 00142 switch (This->state) 00143 { 00144 case STATE_OK: 00145 if ((p = strchr(This->ptr, ' '))) 00146 { 00147 while (*p == ' ') p++; 00148 sscanf(p, "%u %u", &stat->cMessages, &stat->cbMessages); 00149 This->valid_info = TRUE; 00150 This->state = STATE_DONE; 00151 return S_OK; 00152 } 00153 00154 default: 00155 WARN("parse error\n"); 00156 This->state = STATE_DONE; 00157 return S_FALSE; 00158 } 00159 } 00160 00161 static HRESULT parse_list_response(POP3Transport *This, POP3LIST *list) 00162 { 00163 char *p; 00164 00165 list->dwPopId = 0; 00166 list->cbSize = 0; 00167 switch (This->state) 00168 { 00169 case STATE_OK: 00170 if (This->type == POP3CMD_GET_POPID) 00171 { 00172 if ((p = strchr(This->ptr, ' '))) 00173 { 00174 while (*p == ' ') p++; 00175 sscanf(p, "%u %u", &list->dwPopId, &list->cbSize); 00176 This->valid_info = TRUE; 00177 } 00178 This->state = STATE_DONE; 00179 return S_OK; 00180 } 00181 This->state = STATE_MULTILINE; 00182 return S_OK; 00183 00184 case STATE_MULTILINE: 00185 if (This->response[0] == '.' && !This->response[1]) 00186 { 00187 This->valid_info = FALSE; 00188 This->state = STATE_DONE; 00189 return S_OK; 00190 } 00191 sscanf(This->response, "%u", &list->dwPopId); 00192 if ((p = strchr(This->response, ' '))) 00193 { 00194 while (*p == ' ') p++; 00195 sscanf(p, "%u", &list->cbSize); 00196 This->valid_info = TRUE; 00197 return S_OK; 00198 } 00199 00200 default: 00201 WARN("parse error\n"); 00202 This->state = STATE_DONE; 00203 return S_FALSE; 00204 } 00205 } 00206 00207 static HRESULT parse_dele_response(POP3Transport *This, DWORD *dwPopId) 00208 { 00209 switch (This->state) 00210 { 00211 case STATE_OK: 00212 *dwPopId = 0; /* FIXME */ 00213 This->state = STATE_DONE; 00214 return S_OK; 00215 00216 default: 00217 WARN("parse error\n"); 00218 This->state = STATE_DONE; 00219 return S_FALSE; 00220 } 00221 } 00222 00223 static HRESULT parse_retr_response(POP3Transport *This, POP3RETR *retr) 00224 { 00225 switch (This->state) 00226 { 00227 case STATE_OK: 00228 retr->fHeader = FALSE; 00229 retr->fBody = FALSE; 00230 retr->dwPopId = This->msgid; 00231 retr->cbSoFar = 0; 00232 retr->pszLines = This->response; 00233 retr->cbLines = 0; 00234 00235 This->state = STATE_MULTILINE; 00236 This->valid_info = FALSE; 00237 return S_OK; 00238 00239 case STATE_MULTILINE: 00240 { 00241 int len; 00242 00243 if (This->response[0] == '.' && !This->response[1]) 00244 { 00245 retr->cbLines = retr->cbSoFar; 00246 This->state = STATE_DONE; 00247 return S_OK; 00248 } 00249 retr->fHeader = TRUE; 00250 if (!This->response[0]) retr->fBody = TRUE; 00251 00252 len = strlen(This->response); 00253 retr->cbSoFar += len; 00254 retr->pszLines = This->response; 00255 retr->cbLines = len; 00256 00257 This->valid_info = TRUE; 00258 return S_OK; 00259 } 00260 00261 default: 00262 WARN("parse error\n"); 00263 This->state = STATE_DONE; 00264 return S_FALSE; 00265 } 00266 } 00267 00268 static HRESULT parse_top_response(POP3Transport *This, POP3TOP *top) 00269 { 00270 switch (This->state) 00271 { 00272 case STATE_OK: 00273 top->fHeader = FALSE; 00274 top->fBody = FALSE; 00275 top->dwPopId = This->msgid; 00276 top->cPreviewLines = This->preview_lines; 00277 top->cbSoFar = 0; 00278 top->pszLines = This->response; 00279 top->cbLines = 0; 00280 00281 This->state = STATE_MULTILINE; 00282 This->valid_info = FALSE; 00283 return S_OK; 00284 00285 case STATE_MULTILINE: 00286 { 00287 int len; 00288 00289 if (This->response[0] == '.' && !This->response[1]) 00290 { 00291 top->cbLines = top->cbSoFar; 00292 This->state = STATE_DONE; 00293 return S_OK; 00294 } 00295 top->fHeader = TRUE; 00296 if (!This->response[0]) top->fBody = TRUE; 00297 00298 len = strlen(This->response); 00299 top->cbSoFar += len; 00300 top->pszLines = This->response; 00301 top->cbLines = len; 00302 00303 This->valid_info = TRUE; 00304 return S_OK; 00305 } 00306 00307 default: 00308 WARN("parse error\n"); 00309 This->state = STATE_DONE; 00310 return S_FALSE; 00311 } 00312 } 00313 00314 static void init_parser(POP3Transport *This, POP3COMMAND command, POP3CMDTYPE type) 00315 { 00316 This->state = STATE_NONE; 00317 This->command = command; 00318 This->type = type; 00319 } 00320 00321 static HRESULT POP3Transport_ParseResponse(POP3Transport *This, char *pszResponse, POP3RESPONSE *pResponse) 00322 { 00323 HRESULT hr; 00324 00325 TRACE("response: %s\n", debugstr_a(pszResponse)); 00326 00327 This->response = pszResponse; 00328 This->valid_info = FALSE; 00329 TRACE("state %u\n", This->state); 00330 00331 if (SUCCEEDED((hr = parse_response(This)))) 00332 { 00333 switch (This->command) 00334 { 00335 case POP3_UIDL: hr = parse_uidl_response(This, &pResponse->u.rUidlInfo); break; 00336 case POP3_STAT: hr = parse_stat_response(This, &pResponse->u.rStatInfo); break; 00337 case POP3_LIST: hr = parse_list_response(This, &pResponse->u.rListInfo); break; 00338 case POP3_DELE: hr = parse_dele_response(This, &pResponse->u.dwPopId); break; 00339 case POP3_RETR: hr = parse_retr_response(This, &pResponse->u.rRetrInfo); break; 00340 case POP3_TOP: hr = parse_top_response(This, &pResponse->u.rTopInfo); break; 00341 default: 00342 This->state = STATE_DONE; 00343 break; 00344 } 00345 } 00346 pResponse->command = This->command; 00347 pResponse->fDone = (This->state == STATE_DONE); 00348 pResponse->fValidInfo = This->valid_info; 00349 pResponse->rIxpResult.hrResult = hr; 00350 pResponse->rIxpResult.pszResponse = pszResponse; 00351 pResponse->rIxpResult.uiServerError = 0; 00352 pResponse->rIxpResult.hrServerError = pResponse->rIxpResult.hrResult; 00353 pResponse->rIxpResult.dwSocketError = WSAGetLastError(); 00354 pResponse->rIxpResult.pszProblem = NULL; 00355 pResponse->pTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3; 00356 00357 if (This->InetTransport.pCallback && This->InetTransport.fCommandLogging) 00358 { 00359 ITransportCallback_OnCommand(This->InetTransport.pCallback, CMD_RESP, 00360 pResponse->rIxpResult.pszResponse, pResponse->rIxpResult.hrServerError, 00361 (IInternetTransport *)&This->InetTransport.u.vtbl); 00362 } 00363 return S_OK; 00364 } 00365 00366 static void POP3Transport_CallbackProcessDELEResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00367 { 00368 POP3Transport *This = (POP3Transport *)iface; 00369 POP3RESPONSE response; 00370 HRESULT hr; 00371 00372 TRACE("\n"); 00373 00374 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00375 if (FAILED(hr)) 00376 { 00377 /* FIXME: handle error */ 00378 return; 00379 } 00380 00381 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00382 } 00383 00384 static void POP3Transport_CallbackRecvDELEResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00385 { 00386 POP3Transport *This = (POP3Transport *)iface; 00387 00388 TRACE("\n"); 00389 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessDELEResp); 00390 } 00391 00392 static void POP3Transport_CallbackProcessNOOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00393 { 00394 POP3Transport *This = (POP3Transport *)iface; 00395 POP3RESPONSE response; 00396 HRESULT hr; 00397 00398 TRACE("\n"); 00399 00400 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00401 if (FAILED(hr)) 00402 { 00403 /* FIXME: handle error */ 00404 return; 00405 } 00406 00407 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00408 } 00409 00410 static void POP3Transport_CallbackRecvNOOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00411 { 00412 POP3Transport *This = (POP3Transport *)iface; 00413 00414 TRACE("\n"); 00415 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessNOOPResp); 00416 } 00417 00418 static void POP3Transport_CallbackProcessRSETResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00419 { 00420 POP3Transport *This = (POP3Transport *)iface; 00421 POP3RESPONSE response; 00422 HRESULT hr; 00423 00424 TRACE("\n"); 00425 00426 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00427 if (FAILED(hr)) 00428 { 00429 /* FIXME: handle error */ 00430 return; 00431 } 00432 00433 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00434 } 00435 00436 static void POP3Transport_CallbackRecvRSETResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00437 { 00438 POP3Transport *This = (POP3Transport *)iface; 00439 00440 TRACE("\n"); 00441 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRSETResp); 00442 } 00443 00444 static void POP3Transport_CallbackProcessRETRResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00445 { 00446 POP3Transport *This = (POP3Transport *)iface; 00447 POP3RESPONSE response; 00448 HRESULT hr; 00449 00450 TRACE("\n"); 00451 00452 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00453 if (FAILED(hr)) 00454 { 00455 /* FIXME: handle error */ 00456 return; 00457 } 00458 00459 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00460 00461 if (!response.fDone) 00462 { 00463 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRETRResp); 00464 return; 00465 } 00466 00467 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00468 } 00469 00470 static void POP3Transport_CallbackRecvRETRResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00471 { 00472 POP3Transport *This = (POP3Transport *)iface; 00473 00474 TRACE("\n"); 00475 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRETRResp); 00476 } 00477 00478 static void POP3Transport_CallbackProcessTOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00479 { 00480 POP3Transport *This = (POP3Transport *)iface; 00481 POP3RESPONSE response; 00482 HRESULT hr; 00483 00484 TRACE("\n"); 00485 00486 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00487 if (FAILED(hr)) 00488 { 00489 /* FIXME: handle error */ 00490 return; 00491 } 00492 00493 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00494 00495 if (!response.fDone) 00496 { 00497 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessTOPResp); 00498 return; 00499 } 00500 00501 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00502 } 00503 00504 static void POP3Transport_CallbackRecvTOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00505 { 00506 POP3Transport *This = (POP3Transport *)iface; 00507 00508 TRACE("\n"); 00509 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessTOPResp); 00510 } 00511 00512 static void POP3Transport_CallbackProcessLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00513 { 00514 POP3Transport *This = (POP3Transport *)iface; 00515 POP3RESPONSE response; 00516 HRESULT hr; 00517 00518 TRACE("\n"); 00519 00520 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00521 if (FAILED(hr)) 00522 { 00523 /* FIXME: handle error */ 00524 return; 00525 } 00526 00527 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00528 00529 if (!response.fDone) 00530 { 00531 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp); 00532 return; 00533 } 00534 00535 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00536 } 00537 00538 static void POP3Transport_CallbackRecvLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00539 { 00540 POP3Transport *This = (POP3Transport *)iface; 00541 00542 TRACE("\n"); 00543 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp); 00544 } 00545 00546 static void POP3Transport_CallbackProcessUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00547 { 00548 POP3Transport *This = (POP3Transport *)iface; 00549 POP3RESPONSE response; 00550 HRESULT hr; 00551 00552 TRACE("\n"); 00553 00554 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00555 if (FAILED(hr)) 00556 { 00557 /* FIXME: handle error */ 00558 return; 00559 } 00560 00561 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00562 00563 if (!response.fDone) 00564 { 00565 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp); 00566 return; 00567 } 00568 00569 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00570 } 00571 00572 static void POP3Transport_CallbackRecvUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00573 { 00574 POP3Transport *This = (POP3Transport *)iface; 00575 00576 TRACE("\n"); 00577 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp); 00578 } 00579 00580 static void POP3Transport_CallbackProcessSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00581 { 00582 POP3Transport *This = (POP3Transport *)iface; 00583 POP3RESPONSE response; 00584 HRESULT hr; 00585 00586 TRACE("\n"); 00587 00588 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00589 if (FAILED(hr)) 00590 { 00591 /* FIXME: handle error */ 00592 return; 00593 } 00594 00595 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00596 } 00597 00598 static void POP3Transport_CallbackRecvSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00599 { 00600 POP3Transport *This = (POP3Transport *)iface; 00601 00602 TRACE("\n"); 00603 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessSTATResp); 00604 } 00605 00606 static void POP3Transport_CallbackProcessPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00607 { 00608 POP3Transport *This = (POP3Transport *)iface; 00609 POP3RESPONSE response; 00610 HRESULT hr; 00611 00612 TRACE("\n"); 00613 00614 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00615 if (FAILED(hr)) 00616 { 00617 /* FIXME: handle error */ 00618 return; 00619 } 00620 00621 InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED); 00622 InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED); 00623 00624 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00625 } 00626 00627 static void POP3Transport_CallbackRecvPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00628 { 00629 POP3Transport *This = (POP3Transport *)iface; 00630 00631 TRACE("\n"); 00632 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessPASSResp); 00633 } 00634 00635 static void POP3Transport_CallbackProcessUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00636 { 00637 static char pass[] = "PASS "; 00638 POP3Transport *This = (POP3Transport *)iface; 00639 POP3RESPONSE response; 00640 char *command; 00641 int len; 00642 HRESULT hr; 00643 00644 TRACE("\n"); 00645 00646 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00647 if (FAILED(hr)) 00648 { 00649 /* FIXME: handle error */ 00650 return; 00651 } 00652 00653 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00654 00655 len = sizeof(pass) + strlen(This->InetTransport.ServerInfo.szPassword) + 2; /* "\r\n" */ 00656 command = HeapAlloc(GetProcessHeap(), 0, len); 00657 00658 strcpy(command, pass); 00659 strcat(command, This->InetTransport.ServerInfo.szPassword); 00660 strcat(command, "\r\n"); 00661 00662 init_parser(This, POP3_PASS, POP3_NONE); 00663 00664 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp); 00665 HeapFree(GetProcessHeap(), 0, command); 00666 } 00667 00668 static void POP3Transport_CallbackRecvUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00669 { 00670 POP3Transport *This = (POP3Transport *)iface; 00671 00672 TRACE("\n"); 00673 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUSERResp); 00674 } 00675 00676 static void POP3Transport_CallbackSendUSERCmd(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00677 { 00678 static char user[] = "USER "; 00679 POP3Transport *This = (POP3Transport *)iface; 00680 char *command; 00681 int len; 00682 00683 TRACE("\n"); 00684 00685 len = sizeof(user) + strlen(This->InetTransport.ServerInfo.szUserName) + 2; /* "\r\n" */ 00686 command = HeapAlloc(GetProcessHeap(), 0, len); 00687 00688 strcpy(command, user); 00689 strcat(command, This->InetTransport.ServerInfo.szUserName); 00690 strcat(command, "\r\n"); 00691 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp); 00692 00693 HeapFree(GetProcessHeap(), 0, command); 00694 } 00695 00696 static void POP3Transport_CallbackProcessQUITResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00697 { 00698 POP3Transport *This = (POP3Transport *)iface; 00699 POP3RESPONSE response; 00700 HRESULT hr; 00701 00702 TRACE("%s\n", debugstr_an(pBuffer, cbBuffer)); 00703 00704 hr = POP3Transport_ParseResponse(This, pBuffer, &response); 00705 if (FAILED(hr)) 00706 { 00707 /* FIXME: handle error */ 00708 return; 00709 } 00710 00711 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); 00712 InternetTransport_DropConnection(&This->InetTransport); 00713 } 00714 00715 static void POP3Transport_CallbackRecvQUITResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) 00716 { 00717 POP3Transport *This = (POP3Transport *)iface; 00718 00719 TRACE("\n"); 00720 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessQUITResponse); 00721 } 00722 00723 static HRESULT WINAPI POP3Transport_QueryInterface(IPOP3Transport *iface, REFIID riid, void **ppv) 00724 { 00725 TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); 00726 00727 if (IsEqualIID(riid, &IID_IUnknown) || 00728 IsEqualIID(riid, &IID_IInternetTransport) || 00729 IsEqualIID(riid, &IID_IPOP3Transport)) 00730 { 00731 *ppv = iface; 00732 IUnknown_AddRef(iface); 00733 return S_OK; 00734 } 00735 *ppv = NULL; 00736 FIXME("no interface for %s\n", debugstr_guid(riid)); 00737 return E_NOINTERFACE; 00738 } 00739 00740 static ULONG WINAPI POP3Transport_AddRef(IPOP3Transport *iface) 00741 { 00742 POP3Transport *This = (POP3Transport *)iface; 00743 return InterlockedIncrement((LONG *)&This->refs); 00744 } 00745 00746 static ULONG WINAPI POP3Transport_Release(IPOP3Transport *iface) 00747 { 00748 POP3Transport *This = (POP3Transport *)iface; 00749 ULONG refs = InterlockedDecrement((LONG *)&This->refs); 00750 if (!refs) 00751 { 00752 TRACE("destroying %p\n", This); 00753 if (This->InetTransport.Status != IXP_DISCONNECTED) 00754 InternetTransport_DropConnection(&This->InetTransport); 00755 if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback); 00756 HeapFree(GetProcessHeap(), 0, This); 00757 } 00758 return refs; 00759 } 00760 00761 static HRESULT WINAPI POP3Transport_GetServerInfo(IPOP3Transport *iface, 00762 LPINETSERVER pInetServer) 00763 { 00764 POP3Transport *This = (POP3Transport *)iface; 00765 00766 TRACE("(%p)\n", pInetServer); 00767 return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer); 00768 } 00769 00770 static IXPTYPE WINAPI POP3Transport_GetIXPType(IPOP3Transport *iface) 00771 { 00772 TRACE("()\n"); 00773 return IXP_POP3; 00774 } 00775 00776 static HRESULT WINAPI POP3Transport_IsState(IPOP3Transport *iface, IXPISSTATE isstate) 00777 { 00778 FIXME("(%u)\n", isstate); 00779 return E_NOTIMPL; 00780 } 00781 00782 static HRESULT WINAPI POP3Transport_InetServerFromAccount( 00783 IPOP3Transport *iface, IImnAccount *pAccount, LPINETSERVER pInetServer) 00784 { 00785 POP3Transport *This = (POP3Transport *)iface; 00786 00787 TRACE("(%p, %p)\n", pAccount, pInetServer); 00788 return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer); 00789 } 00790 00791 static HRESULT WINAPI POP3Transport_Connect(IPOP3Transport *iface, 00792 LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) 00793 { 00794 POP3Transport *This = (POP3Transport *)iface; 00795 HRESULT hr; 00796 00797 TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE"); 00798 00799 hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging); 00800 if (FAILED(hr)) 00801 return hr; 00802 00803 init_parser(This, POP3_USER, POP3_NONE); 00804 return InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackSendUSERCmd); 00805 } 00806 00807 static HRESULT WINAPI POP3Transport_HandsOffCallback(IPOP3Transport *iface) 00808 { 00809 POP3Transport *This = (POP3Transport *)iface; 00810 00811 TRACE("()\n"); 00812 return InternetTransport_HandsOffCallback(&This->InetTransport); 00813 } 00814 00815 static HRESULT WINAPI POP3Transport_Disconnect(IPOP3Transport *iface) 00816 { 00817 TRACE("()\n"); 00818 return IPOP3Transport_CommandQUIT(iface); 00819 } 00820 00821 static HRESULT WINAPI POP3Transport_DropConnection(IPOP3Transport *iface) 00822 { 00823 POP3Transport *This = (POP3Transport *)iface; 00824 00825 TRACE("()\n"); 00826 return InternetTransport_DropConnection(&This->InetTransport); 00827 } 00828 00829 static HRESULT WINAPI POP3Transport_GetStatus(IPOP3Transport *iface, 00830 IXPSTATUS *pCurrentStatus) 00831 { 00832 POP3Transport *This = (POP3Transport *)iface; 00833 00834 TRACE("()\n"); 00835 return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus); 00836 } 00837 00838 static HRESULT WINAPI POP3Transport_InitNew(IPOP3Transport *iface, 00839 LPSTR pszLogFilePath, IPOP3Callback *pCallback) 00840 { 00841 POP3Transport *This = (POP3Transport *)iface; 00842 00843 TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback); 00844 00845 if (!pCallback) 00846 return E_INVALIDARG; 00847 00848 if (pszLogFilePath) 00849 FIXME("not using log file of %s, use Wine debug logging instead\n", 00850 debugstr_a(pszLogFilePath)); 00851 00852 IPOP3Callback_AddRef(pCallback); 00853 This->InetTransport.pCallback = (ITransportCallback *)pCallback; 00854 This->InetTransport.fInitialised = TRUE; 00855 00856 return S_OK; 00857 } 00858 00859 static HRESULT WINAPI POP3Transport_MarkItem(IPOP3Transport *iface, POP3MARKTYPE marktype, 00860 DWORD dwPopId, boolean fMarked) 00861 { 00862 FIXME("(%u, %u, %d)\n", marktype, dwPopId, fMarked); 00863 return E_NOTIMPL; 00864 } 00865 00866 static HRESULT WINAPI POP3Transport_CommandAUTH(IPOP3Transport *iface, LPSTR pszAuthType) 00867 { 00868 FIXME("(%s)\n", pszAuthType); 00869 return E_NOTIMPL; 00870 } 00871 00872 static HRESULT WINAPI POP3Transport_CommandUSER(IPOP3Transport *iface, LPSTR username) 00873 { 00874 static char user[] = "USER "; 00875 POP3Transport *This = (POP3Transport *)iface; 00876 char *command; 00877 int len; 00878 00879 TRACE("(%s)\n", username); 00880 00881 len = sizeof(user) + strlen(username) + 2; /* "\r\n" */ 00882 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 00883 00884 strcpy(command, user); 00885 strcat(command, username); 00886 strcat(command, "\r\n"); 00887 00888 init_parser(This, POP3_USER, POP3_NONE); 00889 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp); 00890 00891 HeapFree(GetProcessHeap(), 0, command); 00892 return S_OK; 00893 } 00894 00895 static HRESULT WINAPI POP3Transport_CommandPASS(IPOP3Transport *iface, LPSTR password) 00896 { 00897 static char pass[] = "PASS "; 00898 POP3Transport *This = (POP3Transport *)iface; 00899 char *command; 00900 int len; 00901 00902 TRACE("(%p)\n", password); 00903 00904 len = sizeof(pass) + strlen(password) + 2; /* "\r\n" */ 00905 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 00906 00907 strcpy(command, pass); 00908 strcat(command, password); 00909 strcat(command, "\r\n"); 00910 00911 init_parser(This, POP3_PASS, POP3_NONE); 00912 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp); 00913 00914 HeapFree(GetProcessHeap(), 0, command); 00915 return S_OK; 00916 } 00917 00918 static HRESULT WINAPI POP3Transport_CommandLIST( 00919 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) 00920 { 00921 static char list[] = "LIST %u\r\n"; 00922 static char list_all[] = "LIST\r\n"; 00923 POP3Transport *This = (POP3Transport *)iface; 00924 char *command; 00925 int len; 00926 00927 TRACE("(%u, %u)\n", cmdtype, dwPopId); 00928 00929 if (dwPopId) 00930 { 00931 len = sizeof(list) + 10 + 2; /* "4294967296" + "\r\n" */ 00932 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 00933 sprintf(command, list, dwPopId); 00934 } 00935 else command = list_all; 00936 00937 init_parser(This, POP3_LIST, cmdtype); 00938 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvLISTResp); 00939 00940 if (dwPopId) HeapFree(GetProcessHeap(), 0, command); 00941 return S_OK; 00942 } 00943 00944 static HRESULT WINAPI POP3Transport_CommandTOP( 00945 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId, DWORD cPreviewLines) 00946 { 00947 static char top[] = "TOP %u %u\r\n"; 00948 POP3Transport *This = (POP3Transport *)iface; 00949 char *command; 00950 int len; 00951 00952 TRACE("(%u, %u, %u)\n", cmdtype, dwPopId, cPreviewLines); 00953 00954 len = sizeof(top) + 20 + 2; /* 2 * "4294967296" + "\r\n" */ 00955 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 00956 sprintf(command, top, dwPopId, cPreviewLines); 00957 00958 This->preview_lines = cPreviewLines; 00959 init_parser(This, POP3_TOP, cmdtype); 00960 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvTOPResp); 00961 00962 HeapFree(GetProcessHeap(), 0, command); 00963 return S_OK; 00964 } 00965 00966 static HRESULT WINAPI POP3Transport_CommandQUIT(IPOP3Transport *iface) 00967 { 00968 static char command[] = "QUIT\r\n"; 00969 POP3Transport *This = (POP3Transport *)iface; 00970 00971 TRACE("()\n"); 00972 00973 InternetTransport_ChangeStatus(&This->InetTransport, IXP_DISCONNECTING); 00974 00975 init_parser(This, POP3_QUIT, POP3_NONE); 00976 return InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvQUITResp); 00977 } 00978 00979 static HRESULT WINAPI POP3Transport_CommandSTAT(IPOP3Transport *iface) 00980 { 00981 static char stat[] = "STAT\r\n"; 00982 POP3Transport *This = (POP3Transport *)iface; 00983 00984 TRACE("\n"); 00985 00986 init_parser(This, POP3_STAT, POP3_NONE); 00987 InternetTransport_DoCommand(&This->InetTransport, stat, POP3Transport_CallbackRecvSTATResp); 00988 return S_OK; 00989 } 00990 00991 static HRESULT WINAPI POP3Transport_CommandNOOP(IPOP3Transport *iface) 00992 { 00993 static char noop[] = "NOOP\r\n"; 00994 POP3Transport *This = (POP3Transport *)iface; 00995 00996 TRACE("\n"); 00997 00998 init_parser(This, POP3_NOOP, POP3_NONE); 00999 InternetTransport_DoCommand(&This->InetTransport, noop, POP3Transport_CallbackRecvNOOPResp); 01000 return S_OK; 01001 } 01002 01003 static HRESULT WINAPI POP3Transport_CommandRSET(IPOP3Transport *iface) 01004 { 01005 static char rset[] = "RSET\r\n"; 01006 POP3Transport *This = (POP3Transport *)iface; 01007 01008 TRACE("\n"); 01009 01010 init_parser(This, POP3_RSET, POP3_NONE); 01011 InternetTransport_DoCommand(&This->InetTransport, rset, POP3Transport_CallbackRecvRSETResp); 01012 return S_OK; 01013 } 01014 01015 static HRESULT WINAPI POP3Transport_CommandUIDL( 01016 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) 01017 { 01018 static char uidl[] = "UIDL %u\r\n"; 01019 static char uidl_all[] = "UIDL\r\n"; 01020 POP3Transport *This = (POP3Transport *)iface; 01021 char *command; 01022 int len; 01023 01024 TRACE("(%u, %u)\n", cmdtype, dwPopId); 01025 01026 if (dwPopId) 01027 { 01028 len = sizeof(uidl) + 10 + 2; /* "4294967296" + "\r\n" */ 01029 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 01030 sprintf(command, uidl, dwPopId); 01031 } 01032 else command = uidl_all; 01033 01034 init_parser(This, POP3_UIDL, cmdtype); 01035 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUIDLResp); 01036 01037 if (dwPopId) HeapFree(GetProcessHeap(), 0, command); 01038 return S_OK; 01039 } 01040 01041 static HRESULT WINAPI POP3Transport_CommandDELE( 01042 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) 01043 { 01044 static char dele[] = "DELE %u\r\n"; 01045 POP3Transport *This = (POP3Transport *)iface; 01046 char *command; 01047 int len; 01048 01049 TRACE("(%u, %u)\n", cmdtype, dwPopId); 01050 01051 len = sizeof(dele) + 10 + 2; /* "4294967296" + "\r\n" */ 01052 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 01053 sprintf(command, dele, dwPopId); 01054 01055 init_parser(This, POP3_DELE, cmdtype); 01056 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvDELEResp); 01057 01058 HeapFree(GetProcessHeap(), 0, command); 01059 return S_OK; 01060 } 01061 01062 static HRESULT WINAPI POP3Transport_CommandRETR( 01063 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) 01064 { 01065 static char retr[] = "RETR %u\r\n"; 01066 POP3Transport *This = (POP3Transport *)iface; 01067 char *command; 01068 int len; 01069 01070 TRACE("(%u, %u)\n", cmdtype, dwPopId); 01071 01072 len = sizeof(retr) + 10 + 2; /* "4294967296" + "\r\n" */ 01073 if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE; 01074 sprintf(command, retr, dwPopId); 01075 01076 init_parser(This, POP3_RETR, cmdtype); 01077 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvRETRResp); 01078 01079 HeapFree(GetProcessHeap(), 0, command); 01080 return S_OK; 01081 } 01082 01083 static const IPOP3TransportVtbl POP3TransportVtbl = 01084 { 01085 POP3Transport_QueryInterface, 01086 POP3Transport_AddRef, 01087 POP3Transport_Release, 01088 POP3Transport_GetServerInfo, 01089 POP3Transport_GetIXPType, 01090 POP3Transport_IsState, 01091 POP3Transport_InetServerFromAccount, 01092 POP3Transport_Connect, 01093 POP3Transport_HandsOffCallback, 01094 POP3Transport_Disconnect, 01095 POP3Transport_DropConnection, 01096 POP3Transport_GetStatus, 01097 POP3Transport_InitNew, 01098 POP3Transport_MarkItem, 01099 POP3Transport_CommandAUTH, 01100 POP3Transport_CommandUSER, 01101 POP3Transport_CommandPASS, 01102 POP3Transport_CommandLIST, 01103 POP3Transport_CommandTOP, 01104 POP3Transport_CommandQUIT, 01105 POP3Transport_CommandSTAT, 01106 POP3Transport_CommandNOOP, 01107 POP3Transport_CommandRSET, 01108 POP3Transport_CommandUIDL, 01109 POP3Transport_CommandDELE, 01110 POP3Transport_CommandRETR 01111 }; 01112 01113 HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport) 01114 { 01115 HRESULT hr; 01116 POP3Transport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); 01117 if (!This) 01118 return E_OUTOFMEMORY; 01119 01120 This->InetTransport.u.vtblPOP3 = &POP3TransportVtbl; 01121 This->refs = 0; 01122 hr = InternetTransport_Init(&This->InetTransport); 01123 if (FAILED(hr)) 01124 { 01125 HeapFree(GetProcessHeap(), 0, This); 01126 return hr; 01127 } 01128 01129 *ppTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3; 01130 IPOP3Transport_AddRef(*ppTransport); 01131 01132 return S_OK; 01133 } 01134 01135 static HRESULT WINAPI POP3TransportCF_QueryInterface(LPCLASSFACTORY iface, 01136 REFIID riid, LPVOID *ppv) 01137 { 01138 *ppv = NULL; 01139 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) 01140 { 01141 *ppv = iface; 01142 IUnknown_AddRef(iface); 01143 return S_OK; 01144 } 01145 return E_NOINTERFACE; 01146 } 01147 01148 static ULONG WINAPI POP3TransportCF_AddRef(LPCLASSFACTORY iface) 01149 { 01150 return 2; /* non-heap based object */ 01151 } 01152 01153 static ULONG WINAPI POP3TransportCF_Release(LPCLASSFACTORY iface) 01154 { 01155 return 1; /* non-heap based object */ 01156 } 01157 01158 static HRESULT WINAPI POP3TransportCF_CreateInstance(LPCLASSFACTORY iface, 01159 LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) 01160 { 01161 HRESULT hr; 01162 IPOP3Transport *pPop3Transport; 01163 01164 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv); 01165 01166 *ppv = NULL; 01167 01168 if (pUnk) 01169 return CLASS_E_NOAGGREGATION; 01170 01171 hr = CreatePOP3Transport(&pPop3Transport); 01172 if (FAILED(hr)) 01173 return hr; 01174 01175 hr = IPOP3Transport_QueryInterface(pPop3Transport, riid, ppv); 01176 IPOP3Transport_Release(pPop3Transport); 01177 01178 return hr; 01179 } 01180 01181 static HRESULT WINAPI POP3TransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) 01182 { 01183 FIXME("(%d)\n",fLock); 01184 return S_OK; 01185 } 01186 01187 static const IClassFactoryVtbl POP3TransportCFVtbl = 01188 { 01189 POP3TransportCF_QueryInterface, 01190 POP3TransportCF_AddRef, 01191 POP3TransportCF_Release, 01192 POP3TransportCF_CreateInstance, 01193 POP3TransportCF_LockServer 01194 }; 01195 static const IClassFactoryVtbl *POP3TransportCF = &POP3TransportCFVtbl; 01196 01197 HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv) 01198 { 01199 return IClassFactory_QueryInterface((IClassFactory *)&POP3TransportCF, riid, ppv); 01200 } Generated on Fri May 25 2012 04:22:08 for ReactOS by
1.7.6.1
|