X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdll%2Fwin32%2Fwininet%2Fftp.c;h=d62f87ed0b7ed497f0d1f3341ea5a081deced007;hp=d3b97a9bf749f412cb66c0a727cfeab1b5a8ec94;hb=0dbcea8773792774593189925d63e85ae681933d;hpb=00a55fe1f39331bfab7e70ce66c86cb944c22c45 diff --git a/reactos/dll/win32/wininet/ftp.c b/reactos/dll/win32/wininet/ftp.c index d3b97a9bf74..d62f87ed0b7 100644 --- a/reactos/dll/win32/wininet/ftp.c +++ b/reactos/dll/win32/wininet/ftp.c @@ -29,6 +29,8 @@ #include "internet.h" +#define RESPONSE_TIMEOUT 30 + typedef struct _ftp_session_t ftp_session_t; typedef struct @@ -789,6 +791,7 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, INT nResCode; appinfo_t *hIC = NULL; HINTERNET hFindNext = NULL; + LPWSTR lpszSearchPath = NULL; TRACE("\n"); @@ -804,7 +807,20 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, if (!FTP_SendPortOrPasv(lpwfs)) goto lend; - if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, NULL, + /* split search path into file and path */ + if (lpszSearchFile) + { + LPCWSTR name = lpszSearchFile, p; + if ((p = strrchrW( name, '\\' ))) name = p + 1; + if ((p = strrchrW( name, '/' ))) name = p + 1; + if (name != lpszSearchFile) + { + lpszSearchPath = heap_strndupW(lpszSearchFile, name - lpszSearchFile); + lpszSearchFile = name; + } + } + + if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchPath, lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext)) goto lend; @@ -830,6 +846,8 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, } lend: + heap_free(lpszSearchPath); + if (lpwfs->lstnSocket != -1) { closesocket(lpwfs->lstnSocket); @@ -1181,7 +1199,7 @@ static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD s res = sock_send(lpwh->nDataSocket, buffer, size, 0); *written = res>0 ? res : 0; - return res >= 0 ? ERROR_SUCCESS : sock_get_error(errno); + return res >= 0 ? ERROR_SUCCESS : WSAGetLastError(); } static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif) @@ -1216,17 +1234,14 @@ static void FTPFILE_AsyncQueryDataAvailableProc(task_header_t *task) static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { ftp_file_t *file = (ftp_file_t*) hdr; - int retval, unread = 0; + ULONG unread = 0; + int retval; TRACE("(%p %p %x %lx)\n", file, available, flags, ctx); -#ifdef FIONREAD retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread); if (!retval) TRACE("%d bytes of queued, but unread data\n", unread); -#else - FIXME("FIONREAD not available\n"); -#endif *available = unread; @@ -2271,7 +2286,7 @@ BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags strcat(cmd, szCRLF); len--; - TRACE("Sending (%s) len(%d)\n", cmd, len); + TRACE("Sending (%s) len(%d)\n", debugstr_a(cmd), len); while ((nBytesSent < len) && (nRC != -1)) { nRC = sock_send(lpwfs->sndSocket, cmd + nBytesSent, len - nBytesSent, 0); @@ -2328,11 +2343,11 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr) if (lpwfs->download_in_progress != NULL) lpwfs->download_in_progress->session_deleted = TRUE; - if (lpwfs->sndSocket != -1) - closesocket(lpwfs->sndSocket); + if (lpwfs->sndSocket != -1) + closesocket(lpwfs->sndSocket); - if (lpwfs->lstnSocket != -1) - closesocket(lpwfs->lstnSocket); + if (lpwfs->lstnSocket != -1) + closesocket(lpwfs->lstnSocket); if (lpwfs->pasvSocket != -1) closesocket(lpwfs->pasvSocket); @@ -2409,7 +2424,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, socklen_t sock_namelen; BOOL bSuccess = FALSE; ftp_session_t *lpwfs = NULL; - char szaddr[INET_ADDRSTRLEN]; + char szaddr[INET6_ADDRSTRLEN]; TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n", hIC, debugstr_w(lpszServerName), @@ -2454,7 +2469,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if(hIC->proxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (!lpszUserName || !strlenW(lpszUserName)) { + if (!lpszUserName || !lpszUserName[0]) { HKEY key; WCHAR szPassword[MAX_PATH]; DWORD len = sizeof(szPassword); @@ -2497,7 +2512,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR)); sock_namelen = sizeof(socketAddr); - if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen)) + if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen, szaddr)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); goto lerror; @@ -2510,10 +2525,10 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, goto lerror; } - inet_ntop(socketAddr.sin_family, &socketAddr.sin_addr, szaddr, sizeof(szaddr)); SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED, szaddr, strlen(szaddr)+1); + init_winsock(); nsocket = socket(AF_INET,SOCK_STREAM,0); if (nsocket == -1) { @@ -2526,7 +2541,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0) { - ERR("Unable to connect (%s)\n", strerror(errno)); + ERR("Unable to connect (%d)\n", WSAGetLastError()); INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT); closesocket(nsocket); } @@ -2601,6 +2616,58 @@ lend: return bSuccess; } +/*********************************************************************** + * FTP_GetNextLine (internal) + * + * Parse next line in directory string listing + * + * RETURNS + * Pointer to beginning of next line + * NULL on failure + * + */ + +static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen) +{ + struct timeval tv = {RESPONSE_TIMEOUT,0}; + FD_SET set; + INT nRecv = 0; + LPSTR lpszBuffer = INTERNET_GetResponseBuffer(); + + TRACE("\n"); + + FD_ZERO(&set); + FD_SET(nSocket, &set); + + while (nRecv < MAX_REPLY_LEN) + { + if (select(nSocket+1, &set, NULL, NULL, &tv) > 0) + { + if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0) + { + INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS); + return NULL; + } + + if (lpszBuffer[nRecv] == '\n') + { + lpszBuffer[nRecv] = '\0'; + *dwLen = nRecv - 1; + TRACE(":%d %s\n", nRecv, lpszBuffer); + return lpszBuffer; + } + if (lpszBuffer[nRecv] != '\r') + nRecv++; + } + else + { + INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); + return NULL; + } + } + + return NULL; +} /*********************************************************************** * FTP_SendCommandA (internal) @@ -2638,7 +2705,7 @@ static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam, sprintf(buf, "%s%s%s%s", szFtpCommands[ftpCmd], dwParamLen ? " " : "", dwParamLen ? lpszParam : "", szCRLF); - TRACE("Sending (%s) len(%d)\n", buf, len); + TRACE("Sending (%s) len(%d)\n", debugstr_a(buf), len); while((nBytesSent < len) && (nRC != -1)) { nRC = sock_send(nSocket, buf+nBytesSent, len - nBytesSent, 0); @@ -2700,7 +2767,7 @@ INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext) while(1) { - if (!INTERNET_GetNextLine(lpwfs->sndSocket, &nRecv)) + if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv)) goto lerror; if (nRecv >= 3) @@ -2873,7 +2940,8 @@ static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs) TRACE("\n"); - lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0); + init_winsock(); + lpwfs->lstnSocket = socket(AF_INET, SOCK_STREAM, 0); if (lpwfs->lstnSocket == -1) { TRACE("Unable to create listening socket\n"); @@ -3016,10 +3084,10 @@ static BOOL FTP_SendPort(ftp_session_t *lpwfs) TRACE("\n"); sprintfW(szIPAddress, szIPFormat, - lpwfs->lstnSocketAddress.sin_addr.s_addr&0x000000FF, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x0000FF00)>>8, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x00FF0000)>>16, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0xFF000000)>>24, + lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x000000FF, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x0000FF00)>>8, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x00FF0000)>>16, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0xFF000000)>>24, lpwfs->lstnSocketAddress.sin_port & 0xFF, (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8); @@ -3092,7 +3160,7 @@ static BOOL FTP_DoPassive(ftp_session_t *lpwfs) f[i] = f[i] & 0xff; dataSocketAddress = lpwfs->socketAddress; - pAddr = (char *)&(dataSocketAddress.sin_addr.s_addr); + pAddr = (char *)&(dataSocketAddress.sin_addr.S_un.S_addr); pPort = (char *)&(dataSocketAddress.sin_port); pAddr[0] = f[0]; pAddr[1] = f[1]; @@ -3155,7 +3223,7 @@ static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs) static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) { struct sockaddr_in saddr; - socklen_t addrlen = sizeof(struct sockaddr); + socklen_t addrlen = sizeof(saddr); TRACE("\n"); if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE) @@ -3559,7 +3627,7 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT lpfp->lpszName = NULL; do { - if(!(pszLine = INTERNET_GetNextLine(nSocket, &nBufLen))) + if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen))) return FALSE; pszToken = strtok(pszLine, szSpace);