#include "internet.h"
+#define RESPONSE_TIMEOUT 30
+
typedef struct _ftp_session_t ftp_session_t;
typedef struct
INT nResCode;
appinfo_t *hIC = NULL;
HINTERNET hFindNext = NULL;
+ LPWSTR lpszSearchPath = NULL;
TRACE("\n");
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;
}
lend:
+ heap_free(lpszSearchPath);
+
if (lpwfs->lstnSocket != -1)
{
closesocket(lpwfs->lstnSocket);
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)
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;
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);
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);
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),
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);
(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;
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)
{
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);
}
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)
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);
while(1)
{
- if (!INTERNET_GetNextLine(lpwfs->sndSocket, &nRecv))
+ if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv))
goto lerror;
if (nRecv >= 3)
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");
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);
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];
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)
lpfp->lpszName = NULL;
do {
- if(!(pszLine = INTERNET_GetNextLine(nSocket, &nBufLen)))
+ if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen)))
return FALSE;
pszToken = strtok(pszLine, szSpace);