|
|
|
@ -43,6 +43,9 @@
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
#include <winsock2.h>
|
|
|
|
|
#include <ws2tcpip.h>
|
|
|
|
|
#include <io.h>
|
|
|
|
|
#define write(sock,buf,len) send(sock,buf,len,0)
|
|
|
|
|
#else
|
|
|
|
|
#ifdef LIBVNCSERVER_HAVE_UNISTD_H
|
|
|
|
@ -72,8 +75,12 @@
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
|
/* readdir() */
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* errno */
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
/* strftime() */
|
|
|
|
@ -83,12 +90,21 @@
|
|
|
|
|
#include "rfbssl.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#define snprintf _snprintf /* Missing in MSVC */
|
|
|
|
|
/* Prevent POSIX deprecation warnings */
|
|
|
|
|
#define close _close
|
|
|
|
|
#define strdup _strdup
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
|
static int compat_mkdir(const char *path, int mode)
|
|
|
|
|
{
|
|
|
|
|
return mkdir(path);
|
|
|
|
|
}
|
|
|
|
|
#define mkdir compat_mkdir
|
|
|
|
|
#define mkdir(path, perms) mkdir(path) /* Omit the perms argument to match POSIX signature */
|
|
|
|
|
#else /* MSVC and other windows compilers */
|
|
|
|
|
#define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */
|
|
|
|
|
#endif /* __MINGW32__ else... */
|
|
|
|
|
#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
|
|
|
|
|
#include <direct.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
|
|
|
|
@ -313,12 +329,14 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
|
|
|
|
|
|
|
|
|
|
if(isUDP) {
|
|
|
|
|
rfbLog(" accepted UDP client\n");
|
|
|
|
|
} else {
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
char host[1024];
|
|
|
|
|
#endif
|
|
|
|
|
int one=1;
|
|
|
|
|
|
|
|
|
|
getpeername(sock, (struct sockaddr *)&addr, &addrlen);
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
char host[1024];
|
|
|
|
|
if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
|
|
|
|
|
rfbLogPerror("rfbNewClient: error in getnameinfo");
|
|
|
|
|
cl->host = strdup("");
|
|
|
|
@ -1287,8 +1305,15 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
|
|
|
|
|
struct stat statbuf;
|
|
|
|
|
RFB_FIND_DATA win32filename;
|
|
|
|
|
int nOptLen = 0, retval=0;
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
WIN32_FIND_DATAA winFindData;
|
|
|
|
|
HANDLE findHandle;
|
|
|
|
|
int pathLen, basePathLength;
|
|
|
|
|
char *basePath;
|
|
|
|
|
#else
|
|
|
|
|
DIR *dirp=NULL;
|
|
|
|
|
struct dirent *direntp=NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE);
|
|
|
|
|
|
|
|
|
@ -1297,23 +1322,67 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
|
|
|
|
|
|
|
|
|
|
if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path);
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
// Create a search string, like C:\folder\*
|
|
|
|
|
|
|
|
|
|
pathLen = strlen(path);
|
|
|
|
|
basePath = malloc(pathLen + 3);
|
|
|
|
|
memcpy(basePath, path, pathLen);
|
|
|
|
|
basePathLength = pathLen;
|
|
|
|
|
basePath[basePathLength] = '\\';
|
|
|
|
|
basePath[basePathLength + 1] = '*';
|
|
|
|
|
basePath[basePathLength + 2] = '\0';
|
|
|
|
|
|
|
|
|
|
// Start a search
|
|
|
|
|
memset(&winFindData, 0, sizeof(winFindData));
|
|
|
|
|
findHandle = FindFirstFileA(path, &winFindData);
|
|
|
|
|
free(basePath);
|
|
|
|
|
|
|
|
|
|
if (findHandle == INVALID_HANDLE_VALUE)
|
|
|
|
|
#else
|
|
|
|
|
dirp=opendir(path);
|
|
|
|
|
if (dirp==NULL)
|
|
|
|
|
#endif
|
|
|
|
|
return rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, 0, NULL);
|
|
|
|
|
|
|
|
|
|
/* send back the path name (necessary for links) */
|
|
|
|
|
if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, length, buffer)==FALSE) return FALSE;
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
while (findHandle != INVALID_HANDLE_VALUE)
|
|
|
|
|
#else
|
|
|
|
|
for (direntp=readdir(dirp); direntp!=NULL; direntp=readdir(dirp))
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
/* get stats */
|
|
|
|
|
snprintf(retfilename,sizeof(retfilename),"%s/%s", path, direntp->d_name);
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
snprintf(retfilename,sizeof(retfilename),"%s/%s", path, winFindData.cFileName);
|
|
|
|
|
#else
|
|
|
|
|
snprintf(retfilename,sizeof(retfilename),"%s/%s", path, direntp->d_name);
|
|
|
|
|
#endif
|
|
|
|
|
retval = stat(retfilename, &statbuf);
|
|
|
|
|
|
|
|
|
|
if (retval==0)
|
|
|
|
|
{
|
|
|
|
|
memset((char *)&win32filename, 0, sizeof(win32filename));
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
win32filename.dwFileAttributes = winFindData.dwFileAttributes;
|
|
|
|
|
win32filename.ftCreationTime.dwLowDateTime = winFindData.ftCreationTime.dwLowDateTime;
|
|
|
|
|
win32filename.ftCreationTime.dwHighDateTime = winFindData.ftCreationTime.dwHighDateTime;
|
|
|
|
|
win32filename.ftLastAccessTime.dwLowDateTime = winFindData.ftLastAccessTime.dwLowDateTime;
|
|
|
|
|
win32filename.ftLastAccessTime.dwHighDateTime = winFindData.ftLastAccessTime.dwHighDateTime;
|
|
|
|
|
win32filename.ftLastWriteTime.dwLowDateTime = winFindData.ftLastWriteTime.dwLowDateTime;
|
|
|
|
|
win32filename.ftLastWriteTime.dwHighDateTime = winFindData.ftLastWriteTime.dwHighDateTime;
|
|
|
|
|
win32filename.nFileSizeLow = winFindData.nFileSizeLow;
|
|
|
|
|
win32filename.nFileSizeHigh = winFindData.nFileSizeHigh;
|
|
|
|
|
win32filename.dwReserved0 = winFindData.dwReserved0;
|
|
|
|
|
win32filename.dwReserved1 = winFindData.dwReserved1;
|
|
|
|
|
strcpy((char *)win32filename.cFileName, winFindData.cFileName);
|
|
|
|
|
strcpy((char *)win32filename.cAlternateFileName, winFindData.cAlternateFileName);
|
|
|
|
|
#else
|
|
|
|
|
win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_NORMAL);
|
|
|
|
|
if (S_ISDIR(statbuf.st_mode))
|
|
|
|
|
win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_DIRECTORY);
|
|
|
|
|
win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_DIRECTORY);
|
|
|
|
|
win32filename.ftCreationTime.dwLowDateTime = Swap32IfBE(statbuf.st_ctime); /* Intel Order */
|
|
|
|
|
win32filename.ftCreationTime.dwHighDateTime = 0;
|
|
|
|
|
win32filename.ftLastAccessTime.dwLowDateTime = Swap32IfBE(statbuf.st_atime); /* Intel Order */
|
|
|
|
@ -1328,9 +1397,10 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
|
|
|
|
|
/* If this had the full path, we would need to translate to DOS format ("C:\") */
|
|
|
|
|
/* rfbFilenameTranslate2DOS(cl, retfilename, win32filename.cFileName); */
|
|
|
|
|
strcpy((char *)win32filename.cFileName, direntp->d_name);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Do not show hidden files (but show how to move up the tree) */
|
|
|
|
|
if ((strcmp(direntp->d_name, "..")==0) || (direntp->d_name[0]!='.'))
|
|
|
|
|
if ((strcmp((char *)win32filename.cFileName, "..")==0) || (win32filename.cFileName[0]!='.'))
|
|
|
|
|
{
|
|
|
|
|
nOptLen = sizeof(RFB_FIND_DATA) - MAX_PATH - 14 + strlen((char *)win32filename.cFileName);
|
|
|
|
|
/*
|
|
|
|
@ -1338,13 +1408,30 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
|
|
|
|
|
*/
|
|
|
|
|
if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, nOptLen, (char *)&win32filename)==FALSE)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
FindClose(findHandle);
|
|
|
|
|
#else
|
|
|
|
|
closedir(dirp);
|
|
|
|
|
#endif
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FindNextFileA(findHandle, &winFindData) == 0)
|
|
|
|
|
{
|
|
|
|
|
FindClose(findHandle);
|
|
|
|
|
findHandle = INVALID_HANDLE_VALUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
if (findHandle != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
FindClose(findHandle);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
closedir(dirp);
|
|
|
|
|
#endif
|
|
|
|
|
/* End of the transfer */
|
|
|
|
|
return rfbSendFileTransferMessage(cl, rfbDirPacket, 0, 0, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|