mirror of
https://github.com/kingk85/uFTP.git
synced 2025-04-22 01:18:39 +03:00
Merge
This commit is contained in:
BIN
build/modules/connection.o.orig
Normal file
BIN
build/modules/connection.o.orig
Normal file
Binary file not shown.
BIN
build/modules/connection_BACKUP_23916.o
Normal file
BIN
build/modules/connection_BACKUP_23916.o
Normal file
Binary file not shown.
BIN
build/modules/connection_BASE_23916.o
Normal file
BIN
build/modules/connection_BASE_23916.o
Normal file
Binary file not shown.
BIN
build/modules/connection_LOCAL_23916.o
Normal file
BIN
build/modules/connection_LOCAL_23916.o
Normal file
Binary file not shown.
BIN
build/modules/connection_REMOTE_23916.o
Normal file
BIN
build/modules/connection_REMOTE_23916.o
Normal file
Binary file not shown.
BIN
build/modules/fileManagement.o.orig
Normal file
BIN
build/modules/fileManagement.o.orig
Normal file
Binary file not shown.
BIN
build/modules/ftpCommandElaborate.o.orig
Normal file
BIN
build/modules/ftpCommandElaborate.o.orig
Normal file
Binary file not shown.
BIN
build/modules/ftpData.o.orig
Normal file
BIN
build/modules/ftpData.o.orig
Normal file
Binary file not shown.
BIN
build/modules/ftpServer.o.orig
Normal file
BIN
build/modules/ftpServer.o.orig
Normal file
Binary file not shown.
BIN
build/uFTP.orig
Executable file
BIN
build/uFTP.orig
Executable file
Binary file not shown.
@ -379,8 +379,10 @@ int parseCommandProt(ftpDataType * data, int socketId)
|
|||||||
|
|
||||||
int parseCommandCcc(ftpDataType * data, int socketId)
|
int parseCommandCcc(ftpDataType * data, int socketId)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_ENABLED
|
|
||||||
int returnCode;
|
int returnCode;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
|
||||||
returnCode = socketPrintf(data, socketId, "s", "200 TLS connection aborted\r\n");
|
returnCode = socketPrintf(data, socketId, "s", "200 TLS connection aborted\r\n");
|
||||||
SSL_set_shutdown(data->clients[socketId].ssl, SSL_SENT_SHUTDOWN);
|
SSL_set_shutdown(data->clients[socketId].ssl, SSL_SENT_SHUTDOWN);
|
||||||
data->clients[socketId].tlsIsEnabled = 0;
|
data->clients[socketId].tlsIsEnabled = 0;
|
||||||
@ -389,7 +391,7 @@ int parseCommandCcc(ftpDataType * data, int socketId)
|
|||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifndef OPENSSL_ENABLED
|
||||||
returnCode = socketPrintf(data, socketId, "s", "500 command not supported\r\n");
|
returnCode = socketPrintf(data, socketId, "s", "500 command not supported\r\n");
|
||||||
|
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
|
@ -91,8 +91,6 @@ void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theStr
|
|||||||
memcpy(dynamicString->text, theString, stringLen);
|
memcpy(dynamicString->text, theString, stringLen);
|
||||||
dynamicString->textLen = stringLen;
|
dynamicString->textLen = stringLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("\ndynamicString->text = %lld", dynamicString->text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData, DYNMEM_MemoryTable_DataType **memoryTable)
|
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
@ -645,9 +643,9 @@ void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
|
|
||||||
void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isInitialization != 1)
|
if (isInitialization != 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (data->clients[clientId].workerData.threadIsAlive == 1)
|
if (data->clients[clientId].workerData.threadIsAlive == 1)
|
||||||
pthread_cancel(data->clients[clientId].workerData.workerThread);
|
pthread_cancel(data->clients[clientId].workerData.workerThread);
|
||||||
|
|
||||||
|
769
ftpData.c.orig
Normal file
769
ftpData.c.orig
Normal file
@ -0,0 +1,769 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright 2018 Ugo Cirmignani.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "ftpServer.h"
|
||||||
|
#include "ftpCommandsElaborate.h"
|
||||||
|
#include "ftpData.h"
|
||||||
|
#include "library/configRead.h"
|
||||||
|
#include "library/fileManagement.h"
|
||||||
|
#include "library/connection.h"
|
||||||
|
#include "library/dynamicMemory.h"
|
||||||
|
|
||||||
|
void cleanDynamicStringDataType(dynamicStringDataType *dynamicString, int init, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
if (init == 1)
|
||||||
|
{
|
||||||
|
dynamicString->text = 0;
|
||||||
|
dynamicString->textLen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dynamicString->textLen != 0)
|
||||||
|
{
|
||||||
|
if (dynamicString->text != 0) {
|
||||||
|
DYNMEM_free(dynamicString->text, &*memoryTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicString->textLen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanLoginData(loginDataType *loginData, int init, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
loginData->userLoggedIn = 0;
|
||||||
|
cleanDynamicStringDataType(&loginData->homePath, init, &*memoryTable);
|
||||||
|
cleanDynamicStringDataType(&loginData->ftpPath, init, &*memoryTable);
|
||||||
|
cleanDynamicStringDataType(&loginData->name, init, &*memoryTable);
|
||||||
|
cleanDynamicStringDataType(&loginData->password, init, &*memoryTable);
|
||||||
|
cleanDynamicStringDataType(&loginData->absolutePath, init, &*memoryTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theString, int stringLen, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
if (dynamicString->textLen == 0)
|
||||||
|
{
|
||||||
|
//printf("\nMemory data address before memset call : %lld", memoryTable);
|
||||||
|
dynamicString->text = (char *) DYNMEM_malloc (((sizeof(char) * stringLen) + 1), &*memoryTable);
|
||||||
|
//printf("\nMemory data address after memset call : %lld", memoryTable);
|
||||||
|
memset(dynamicString->text, 0, stringLen + 1);
|
||||||
|
memcpy(dynamicString->text, theString, stringLen);
|
||||||
|
dynamicString->textLen = stringLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(stringLen != dynamicString->textLen)
|
||||||
|
{
|
||||||
|
dynamicString->text = (char *) DYNMEM_realloc (dynamicString->text, ((sizeof(char) * stringLen) + 1), &*memoryTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(dynamicString->text, 0, stringLen + 1);
|
||||||
|
memcpy(dynamicString->text, theString, stringLen);
|
||||||
|
dynamicString->textLen = stringLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("\ndynamicString->text = %lld", dynamicString->text);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
#define STRING_SIZE 4096
|
||||||
|
int theLen, i;
|
||||||
|
char * theDirectoryNamePointer;
|
||||||
|
theDirectoryNamePointer = theDirectoryName;
|
||||||
|
|
||||||
|
if (theDirectoryName == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
theLen = strlen(theDirectoryName);
|
||||||
|
|
||||||
|
if (theLen <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (theLen == 2 &&
|
||||||
|
theDirectoryName[0] == '.' &&
|
||||||
|
theDirectoryName[1] == '.')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theLen == 3 &&
|
||||||
|
((theDirectoryName[0] == '.' &&
|
||||||
|
theDirectoryName[1] == '.' &&
|
||||||
|
theDirectoryName[2] == '/') ||
|
||||||
|
(theDirectoryName[0] == '/' &&
|
||||||
|
theDirectoryName[1] == '.' &&
|
||||||
|
theDirectoryName[2] == '.')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check for /../
|
||||||
|
char theDirectoryToCheck[STRING_SIZE];
|
||||||
|
int theDirectoryToCheckIndex = 0;
|
||||||
|
memset(theDirectoryToCheck, 0, STRING_SIZE);
|
||||||
|
|
||||||
|
for (i = 0; i< theLen; i++)
|
||||||
|
{
|
||||||
|
if (theDirectoryName[i] == '/')
|
||||||
|
{
|
||||||
|
if (theDirectoryToCheckIndex == 2 &&
|
||||||
|
theDirectoryToCheck[0] == '.' &&
|
||||||
|
theDirectoryToCheck[1] == '.')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
theDirectoryToCheckIndex = 0;
|
||||||
|
memset(theDirectoryToCheck, 0, STRING_SIZE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theDirectoryToCheckIndex<STRING_SIZE)
|
||||||
|
{
|
||||||
|
theDirectoryToCheck[theDirectoryToCheckIndex++] = theDirectoryName[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0; /* Directory size too long */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theDirectoryName[0] == '/')
|
||||||
|
{
|
||||||
|
while (theDirectoryNamePointer[0] == '/')
|
||||||
|
theDirectoryNamePointer++;
|
||||||
|
|
||||||
|
//printf("\nMemory data address 2nd call : %lld", memoryTable);
|
||||||
|
setDynamicStringDataType(safePath, loginData->homePath.text, loginData->homePath.textLen, &*memoryTable);
|
||||||
|
//printf("\nMemory data address 3rd call : %lld", memoryTable);
|
||||||
|
appendToDynamicStringDataType(safePath, theDirectoryNamePointer, strlen(theDirectoryNamePointer), &*memoryTable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setDynamicStringDataType(safePath, loginData->absolutePath.text, loginData->absolutePath.textLen, &*memoryTable);
|
||||||
|
|
||||||
|
if (loginData->absolutePath.text[loginData->absolutePath.textLen-1] != '/')
|
||||||
|
{
|
||||||
|
appendToDynamicStringDataType(safePath, "/", 1, &*memoryTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendToDynamicStringDataType(safePath, theDirectoryName, strlen(theDirectoryName), &*memoryTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendToDynamicStringDataType(dynamicStringDataType *dynamicString, char *theString, int stringLen, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
//printf("\nRealloc dynamicString->text = %lld", dynamicString->text);
|
||||||
|
int theNewSize = dynamicString->textLen + stringLen;
|
||||||
|
|
||||||
|
dynamicString->text = DYNMEM_realloc(dynamicString->text, theNewSize + 1, &*memoryTable);
|
||||||
|
|
||||||
|
memset(dynamicString->text+dynamicString->textLen, 0, stringLen+1);
|
||||||
|
memcpy(dynamicString->text+dynamicString->textLen, theString, stringLen);
|
||||||
|
|
||||||
|
dynamicString->text[theNewSize] = '\0';
|
||||||
|
dynamicString->textLen = theNewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRandomicPort(ftpDataType *data, int socketPosition)
|
||||||
|
{
|
||||||
|
static unsigned short int randomizeInteger = 0;
|
||||||
|
unsigned short int randomicPort = 5000;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
randomizeInteger += 1;
|
||||||
|
|
||||||
|
if (randomizeInteger > 100 )
|
||||||
|
randomizeInteger = 1;
|
||||||
|
|
||||||
|
while(randomicPort < 10000)
|
||||||
|
randomicPort = ((rand() + socketPosition + randomizeInteger) % (50000)) + 10000;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < data->ftpParameters.maxClients)
|
||||||
|
{
|
||||||
|
if (randomicPort == data->clients[i].workerData.connectionPort ||
|
||||||
|
randomicPort < 10000)
|
||||||
|
{
|
||||||
|
randomicPort = ((rand() + socketPosition + i + randomizeInteger) % (50000)) + 10000;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data->clients[socketPosition].workerData.connectionPort = randomicPort;
|
||||||
|
//printf("data->clients[%d].workerData.connectionPort = %d", socketPosition, data->clients[socketPosition].workerData.connectionPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumber, int commandType, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
int i, x, returnCode;
|
||||||
|
int fileAndFoldersCount = 0;
|
||||||
|
char **fileList = NULL;
|
||||||
|
FILE_GetDirectoryInodeList(ftpData->clients[clientId].listPath.text, &fileList, &fileAndFoldersCount, 0);
|
||||||
|
*filesNumber = fileAndFoldersCount;
|
||||||
|
|
||||||
|
returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n");
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < fileAndFoldersCount; i++)
|
||||||
|
{
|
||||||
|
ftpListDataType data;
|
||||||
|
data.owner = NULL;
|
||||||
|
data.groupOwner = NULL;
|
||||||
|
data.inodePermissionString = NULL;
|
||||||
|
data.fileNameWithPath = NULL;
|
||||||
|
data.finalStringPath = NULL;
|
||||||
|
data.linkPath = NULL;
|
||||||
|
data.isFile = 0;
|
||||||
|
data.isDirectory = 0;
|
||||||
|
|
||||||
|
//printf("\nPROCESSING: %s", fileList[i]);
|
||||||
|
|
||||||
|
if (FILE_IsDirectory(fileList[i]) == 1)
|
||||||
|
{
|
||||||
|
//printf("\nis directory");
|
||||||
|
//fflush(0);
|
||||||
|
data.isDirectory = 1;
|
||||||
|
data.isFile = 0;
|
||||||
|
data.isLink = 0;
|
||||||
|
data.fileSize = 4096;
|
||||||
|
data.numberOfSubDirectories = FILE_GetDirectoryInodeCount(fileList[i]);
|
||||||
|
}
|
||||||
|
else if (FILE_IsFile(fileList[i]) == 1)
|
||||||
|
{
|
||||||
|
//printf("\nis file");
|
||||||
|
//fflush(0);
|
||||||
|
data.isDirectory = 0;
|
||||||
|
data.isFile = 1;
|
||||||
|
data.isLink = 0;
|
||||||
|
data.numberOfSubDirectories = 1; /* to Do*/
|
||||||
|
data.fileSize = FILE_GetFileSizeFromPath(fileList[i]);
|
||||||
|
}
|
||||||
|
if (data.isDirectory == 0 && data.isFile == 0)
|
||||||
|
{
|
||||||
|
//printf("\nNot a directory, not a file, broken link");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//printf("\nFILE SIZE : %lld", data.fileSize);
|
||||||
|
|
||||||
|
data.owner = FILE_GetOwner(fileList[i]);
|
||||||
|
data.groupOwner = FILE_GetGroupOwner(fileList[i]);
|
||||||
|
data.fileNameWithPath = fileList[i];
|
||||||
|
data.fileNameNoPath = FILE_GetFilenameFromPath(fileList[i]);
|
||||||
|
data.inodePermissionString = FILE_GetListPermissionsString(fileList[i]);
|
||||||
|
data.lastModifiedData = FILE_GetLastModifiedData(fileList[i]);
|
||||||
|
|
||||||
|
if (strlen(data.fileNameNoPath) > 0)
|
||||||
|
{
|
||||||
|
data.finalStringPath = (char *) DYNMEM_malloc (strlen(data.fileNameNoPath)+1, &*memoryTable);
|
||||||
|
strcpy(data.finalStringPath, data.fileNameNoPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.inodePermissionString != NULL &&
|
||||||
|
strlen(data.inodePermissionString) > 0 &&
|
||||||
|
data.inodePermissionString[0] == 'l')
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
data.isLink = 1;
|
||||||
|
data.linkPath = (char *) DYNMEM_malloc (CLIENT_COMMAND_STRING_SIZE*sizeof(char), &*memoryTable);
|
||||||
|
if ((len = readlink (fileList[i], data.linkPath, CLIENT_COMMAND_STRING_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
data.linkPath[len] = 0;
|
||||||
|
FILE_AppendToString(&data.finalStringPath, " -> ", &*memoryTable);
|
||||||
|
FILE_AppendToString(&data.finalStringPath, data.linkPath, &*memoryTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(data.lastModifiedDataString, 0, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE);
|
||||||
|
strftime(data.lastModifiedDataString, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE, "%b %d %Y", localtime(&data.lastModifiedData));
|
||||||
|
|
||||||
|
|
||||||
|
switch (commandType)
|
||||||
|
{
|
||||||
|
case COMMAND_TYPE_LIST:
|
||||||
|
{
|
||||||
|
returnCode = socketWorkerPrintf(ftpData, clientId, "ssdssssslsssss",
|
||||||
|
data.inodePermissionString == NULL? "Unknown" : data.inodePermissionString
|
||||||
|
," "
|
||||||
|
,data.numberOfSubDirectories
|
||||||
|
," "
|
||||||
|
,data.owner == NULL? "Unknown" : data.owner
|
||||||
|
," "
|
||||||
|
,data.groupOwner == NULL? "Unknown" : data.groupOwner
|
||||||
|
," "
|
||||||
|
,data.fileSize
|
||||||
|
," "
|
||||||
|
,data.lastModifiedDataString == NULL? "Unknown" : data.lastModifiedDataString
|
||||||
|
," "
|
||||||
|
,data.finalStringPath == NULL? "Unknown" : data.finalStringPath
|
||||||
|
,"\r\n");
|
||||||
|
/*
|
||||||
|
returnCode = dprintf(theSocket, "%s %d %s %s %lld %s %s\r\n",
|
||||||
|
data.inodePermissionString == NULL? "Unknown" : data.inodePermissionString
|
||||||
|
,data.numberOfSubDirectories
|
||||||
|
,data.owner == NULL? "Unknown" : data.owner
|
||||||
|
,data.groupOwner == NULL? "Unknown" : data.groupOwner
|
||||||
|
,data.fileSize
|
||||||
|
,data.lastModifiedDataString == NULL? "Unknown" : data.lastModifiedDataString
|
||||||
|
,data.finalStringPath == NULL? "Unknown" : data.finalStringPath);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_TYPE_NLST:
|
||||||
|
{
|
||||||
|
returnCode = socketWorkerPrintf(ftpData, clientId, "ss", data.fileNameNoPath, "\r\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\nWarning switch default in function writeListDataInfoToSocket (%d)", commandType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (data.fileNameWithPath != NULL)
|
||||||
|
free(data.fileNameWithPath);
|
||||||
|
|
||||||
|
if (data.linkPath != NULL)
|
||||||
|
free(data.linkPath);
|
||||||
|
|
||||||
|
if (data.finalStringPath != NULL)
|
||||||
|
free(data.finalStringPath);
|
||||||
|
|
||||||
|
if (data.owner != NULL)
|
||||||
|
free(data.owner);
|
||||||
|
|
||||||
|
if (data.groupOwner != NULL)
|
||||||
|
free(data.groupOwner);
|
||||||
|
|
||||||
|
if (data.inodePermissionString != NULL)
|
||||||
|
free(data.inodePermissionString);
|
||||||
|
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
for (x = i+1; x < fileAndFoldersCount; x++)
|
||||||
|
free (fileList[x]);
|
||||||
|
free (fileList);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileList != NULL)
|
||||||
|
{
|
||||||
|
free (fileList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int searchInLoginFailsVector(void * loginFailsVector, void *element)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
//printf("((DYNV_VectorGenericDataType *)loginFailsVector)->Size = %d", ((DYNV_VectorGenericDataType *)loginFailsVector)->Size);
|
||||||
|
|
||||||
|
for (i = 0; i < ((DYNV_VectorGenericDataType *)loginFailsVector)->Size; i++)
|
||||||
|
{
|
||||||
|
if (strcmp( ((loginFailsDataType *) element)->ipAddress, (((loginFailsDataType *) ((DYNV_VectorGenericDataType *)loginFailsVector)->Data[i])->ipAddress)) == 0)
|
||||||
|
{
|
||||||
|
//printf("\n\n***IP address found: %s in %d", ((loginFailsDataType *) element)->ipAddress, i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteLoginFailsData(void *element)
|
||||||
|
{
|
||||||
|
; //NOP
|
||||||
|
}
|
||||||
|
|
||||||
|
void getListDataInfo(char * thePath, DYNV_VectorGenericDataType *directoryInfo, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int fileAndFoldersCount = 0;
|
||||||
|
ftpListDataType data;
|
||||||
|
FILE_GetDirectoryInodeList(thePath, &data.fileList, &fileAndFoldersCount, 0);
|
||||||
|
|
||||||
|
//printf("\nNUMBER OF FILES: %d", fileAndFoldersCount);
|
||||||
|
//fflush(0);
|
||||||
|
|
||||||
|
for (i = 0; i < fileAndFoldersCount; i++)
|
||||||
|
{
|
||||||
|
data.owner = NULL;
|
||||||
|
data.groupOwner = NULL;
|
||||||
|
data.inodePermissionString = NULL;
|
||||||
|
data.fileNameWithPath = NULL;
|
||||||
|
data.finalStringPath = NULL;
|
||||||
|
data.linkPath = NULL;
|
||||||
|
|
||||||
|
data.numberOfSubDirectories = 1; /* to Do*/
|
||||||
|
data.isFile = 0;
|
||||||
|
data.isDirectory = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//printf("\nPROCESSING: %s", data.fileList[i]);
|
||||||
|
//fflush(0);
|
||||||
|
|
||||||
|
if (FILE_IsDirectory(data.fileList[i]) == 1)
|
||||||
|
{
|
||||||
|
//printf("\nis file");
|
||||||
|
//fflush(0);
|
||||||
|
data.isDirectory = 1;
|
||||||
|
data.isFile = 0;
|
||||||
|
data.isLink = 0;
|
||||||
|
data.fileSize = 4096;
|
||||||
|
}
|
||||||
|
else if (FILE_IsFile(data.fileList[i]) == 1)
|
||||||
|
{
|
||||||
|
//printf("\nis file");
|
||||||
|
//fflush(0);
|
||||||
|
data.isDirectory = 0;
|
||||||
|
data.isFile = 1;
|
||||||
|
data.isLink = 0;
|
||||||
|
data.fileSize = FILE_GetFileSizeFromPath(data.fileList[i]);
|
||||||
|
}
|
||||||
|
if (data.isDirectory == 0 && data.isFile == 0)
|
||||||
|
{
|
||||||
|
printf("\nNot a directory, not a file, broken link");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nFILE SIZE : %lld", data.fileSize);
|
||||||
|
|
||||||
|
data.owner = FILE_GetOwner(data.fileList[i]);
|
||||||
|
data.groupOwner = FILE_GetGroupOwner(data.fileList[i]);
|
||||||
|
data.fileNameWithPath = data.fileList[i];
|
||||||
|
data.fileNameNoPath = FILE_GetFilenameFromPath(data.fileList[i]);
|
||||||
|
data.inodePermissionString = FILE_GetListPermissionsString(data.fileList[i]);
|
||||||
|
data.lastModifiedData = FILE_GetLastModifiedData(data.fileList[i]);
|
||||||
|
|
||||||
|
if (strlen(data.fileNameNoPath) > 0)
|
||||||
|
{
|
||||||
|
data.finalStringPath = (char *) DYNMEM_malloc (strlen(data.fileNameNoPath)+1, &*memoryTable);
|
||||||
|
strcpy(data.finalStringPath, data.fileNameNoPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.inodePermissionString != NULL &&
|
||||||
|
strlen(data.inodePermissionString) > 0 &&
|
||||||
|
data.inodePermissionString[0] == 'l')
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
data.isLink = 1;
|
||||||
|
data.linkPath = (char *) DYNMEM_malloc (CLIENT_COMMAND_STRING_SIZE*sizeof(char), &*memoryTable);
|
||||||
|
if ((len = readlink (data.fileList[i], data.linkPath, CLIENT_COMMAND_STRING_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
data.linkPath[len] = 0;
|
||||||
|
FILE_AppendToString(&data.finalStringPath, " -> ", &*memoryTable);
|
||||||
|
FILE_AppendToString(&data.finalStringPath, data.linkPath, &*memoryTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(data.lastModifiedDataString, 0, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE);
|
||||||
|
strftime(data.lastModifiedDataString, 80, "%b %d %Y", localtime(&data.lastModifiedData));
|
||||||
|
|
||||||
|
/*
|
||||||
|
-1 List one file per line
|
||||||
|
-A List all files except "." and ".."
|
||||||
|
-a List all files including those whose names start with "."
|
||||||
|
-C List entries by columns
|
||||||
|
-d List directory entries instead of directory contents
|
||||||
|
-F Append file type indicator (one of "*", "/", "=", "@" or "|") to names
|
||||||
|
-h Print file sizes in human-readable format (e.g. 1K, 234M, 2G)
|
||||||
|
-L List files pointed to by symlinks
|
||||||
|
-l Use a long listing format
|
||||||
|
-n List numeric UIDs/GIDs instead of user/group names
|
||||||
|
-R List subdirectories recursively
|
||||||
|
-r Sort filenames in reverse order
|
||||||
|
-S Sort by file size
|
||||||
|
-t Sort by modification time
|
||||||
|
*/
|
||||||
|
|
||||||
|
directoryInfo->PushBack(directoryInfo, &data, sizeof(ftpListDataType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteListDataInfoVector(void *TheElementToDelete)
|
||||||
|
{
|
||||||
|
ftpListDataType *data = (ftpListDataType *)TheElementToDelete;
|
||||||
|
|
||||||
|
if (data->owner != NULL)
|
||||||
|
{
|
||||||
|
free(data->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->groupOwner != NULL)
|
||||||
|
{
|
||||||
|
free(data->groupOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->inodePermissionString != NULL)
|
||||||
|
{
|
||||||
|
free(data->inodePermissionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->fileNameWithPath != NULL)
|
||||||
|
{
|
||||||
|
free(data->fileNameWithPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->finalStringPath != NULL)
|
||||||
|
{
|
||||||
|
free(data->finalStringPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->linkPath != NULL)
|
||||||
|
{
|
||||||
|
free(data->linkPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
|
||||||
|
{
|
||||||
|
|
||||||
|
data->clients[clientId].workerData.connectionPort = 0;
|
||||||
|
data->clients[clientId].workerData.passiveModeOn = 0;
|
||||||
|
data->clients[clientId].workerData.socketIsConnected = 0;
|
||||||
|
data->clients[clientId].workerData.commandIndex = 0;
|
||||||
|
data->clients[clientId].workerData.passiveListeningSocket = 0;
|
||||||
|
data->clients[clientId].workerData.socketConnection = 0;
|
||||||
|
data->clients[clientId].workerData.bufferIndex = 0;
|
||||||
|
data->clients[clientId].workerData.commandReceived = 0;
|
||||||
|
data->clients[clientId].workerData.retrRestartAtByte = 0;
|
||||||
|
data->clients[clientId].workerData.threadIsAlive = 0;
|
||||||
|
data->clients[clientId].workerData.activeModeOn = 0;
|
||||||
|
data->clients[clientId].workerData.passiveModeOn = 0;
|
||||||
|
data->clients[clientId].workerData.activeIpAddressIndex = 0;
|
||||||
|
|
||||||
|
memset(data->clients[clientId].workerData.buffer, 0, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
memset(data->clients[clientId].workerData.activeIpAddress, 0, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
memset(data->clients[clientId].workerData.theCommandReceived, 0, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].workerData.ftpCommand.commandArgs, isInitialization, &data->clients[clientId].workerData.memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].workerData.ftpCommand.commandOps, isInitialization, &data->clients[clientId].workerData.memoryTable);
|
||||||
|
|
||||||
|
/* wait main for action */
|
||||||
|
if (isInitialization != 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("\n Operation is not an initialization! ");
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&data->clients[clientId].workerData.conditionMutex);
|
||||||
|
pthread_cond_destroy(&data->clients[clientId].workerData.conditionVariable);
|
||||||
|
|
||||||
|
if (data->clients[clientId].workerData.theStorFile != NULL)
|
||||||
|
{
|
||||||
|
int returnCode = 0;
|
||||||
|
returnCode = fclose(data->clients[clientId].workerData.theStorFile);
|
||||||
|
data->clients[clientId].workerData.theStorFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
SSL_free(data->clients[clientId].workerData.serverSsl);
|
||||||
|
SSL_free(data->clients[clientId].workerData.clientSsl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DYNV_VectorGeneric_Init(&data->clients[clientId].workerData.directoryInfo);
|
||||||
|
data->clients[clientId].workerData.theStorFile = NULL;
|
||||||
|
data->clients[clientId].workerData.threadHasBeenCreated = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&data->clients[clientId].workerData.conditionMutex, NULL) != 0)
|
||||||
|
{
|
||||||
|
printf("\ndata->clients[clientId].workerData.conditionMutex init failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (pthread_cond_init(&data->clients[clientId].workerData.conditionVariable, NULL) != 0)
|
||||||
|
{
|
||||||
|
printf("\ndata->clients[clientId].workerData.conditionVariable init failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clear the dynamic vector structure
|
||||||
|
int theSize = data->clients[clientId].workerData.directoryInfo.Size;
|
||||||
|
char ** lastToDestroy = NULL;
|
||||||
|
if (theSize > 0)
|
||||||
|
{
|
||||||
|
lastToDestroy = ((ftpListDataType *)data->clients[clientId].workerData.directoryInfo.Data[0])->fileList;
|
||||||
|
data->clients[clientId].workerData.directoryInfo.Destroy(&data->clients[clientId].workerData.directoryInfo, deleteListDataInfoVector);
|
||||||
|
free(lastToDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
data->clients[clientId].workerData.serverSsl = SSL_new(data->serverCtx);
|
||||||
|
data->clients[clientId].workerData.clientSsl = SSL_new(data->clientCtx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
||||||
|
{
|
||||||
|
if (isInitialization != 1)
|
||||||
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> master
|
||||||
|
if (data->clients[clientId].workerData.threadIsAlive == 1)
|
||||||
|
pthread_cancel(data->clients[clientId].workerData.workerThread);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&data->clients[clientId].writeMutex);
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
SSL_free(data->clients[clientId].ssl);
|
||||||
|
//SSL_free(data->clients[clientId].workerData.ssl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&data->clients[clientId].writeMutex, NULL) != 0)
|
||||||
|
{
|
||||||
|
printf("\nclientData->writeMutex init failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->clients[clientId].tlsIsNegotiating = 0;
|
||||||
|
data->clients[clientId].tlsIsEnabled = 0;
|
||||||
|
data->clients[clientId].dataChannelIsTls = 0;
|
||||||
|
data->clients[clientId].socketDescriptor = -1;
|
||||||
|
data->clients[clientId].socketCommandReceived = 0;
|
||||||
|
data->clients[clientId].socketIsConnected = 0;
|
||||||
|
data->clients[clientId].bufferIndex = 0;
|
||||||
|
data->clients[clientId].commandIndex = 0;
|
||||||
|
data->clients[clientId].closeTheClient = 0;
|
||||||
|
data->clients[clientId].sockaddr_in_size = sizeof(struct sockaddr_in);
|
||||||
|
data->clients[clientId].sockaddr_in_server_size = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
data->clients[clientId].serverIpAddressInteger[0] = 0;
|
||||||
|
data->clients[clientId].serverIpAddressInteger[1] = 0;
|
||||||
|
data->clients[clientId].serverIpAddressInteger[2] = 0;
|
||||||
|
data->clients[clientId].serverIpAddressInteger[3] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
memset(&data->clients[clientId].client_sockaddr_in, 0, data->clients[clientId].sockaddr_in_size);
|
||||||
|
memset(&data->clients[clientId].server_sockaddr_in, 0, data->clients[clientId].sockaddr_in_server_size);
|
||||||
|
memset(data->clients[clientId].clientIpAddress, 0, INET_ADDRSTRLEN);
|
||||||
|
memset(data->clients[clientId].buffer, 0, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
memset(data->clients[clientId].theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE);
|
||||||
|
cleanLoginData(&data->clients[clientId].login, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
|
||||||
|
//Rename from and to data init
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].renameFromFile, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].renameToFile, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].fileToStor, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].fileToRetr, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].listPath, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].nlistPath, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].ftpCommand.commandArgs, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
cleanDynamicStringDataType(&data->clients[clientId].ftpCommand.commandOps, isInitialization, &data->clients[clientId].memoryTable);
|
||||||
|
|
||||||
|
data->clients[clientId].connectionTimeStamp = 0;
|
||||||
|
data->clients[clientId].tlsNegotiatingTimeStart = 0;
|
||||||
|
data->clients[clientId].lastActivityTimeStamp = 0;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
//data->clients[clientId].workerData.ssl = SSL_new(data->ctx);
|
||||||
|
data->clients[clientId].ssl = SSL_new(data->serverCtx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int compareStringCaseInsensitive(char * stringIn, char * stringRef, int stringLenght)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char * alfaLowerCase = "qwertyuiopasdfghjklzxcvbnm ";
|
||||||
|
char * alfaUpperCase = "QWERTYUIOPASDFGHJKLZXCVBNM ";
|
||||||
|
|
||||||
|
int stringInIndex;
|
||||||
|
int stringRefIndex;
|
||||||
|
|
||||||
|
for (i = 0; i <stringLenght; i++)
|
||||||
|
{
|
||||||
|
stringInIndex = isCharInString(alfaUpperCase, strlen(alfaUpperCase), stringIn[i]);
|
||||||
|
if (stringInIndex == -1)
|
||||||
|
{
|
||||||
|
stringInIndex = isCharInString(alfaLowerCase, strlen(alfaLowerCase), stringIn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
stringRefIndex = isCharInString(alfaUpperCase, strlen(alfaUpperCase), stringRef[i]);
|
||||||
|
if (stringRefIndex == -1)
|
||||||
|
{
|
||||||
|
stringRefIndex = isCharInString(alfaLowerCase, strlen(alfaLowerCase), stringRef[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringRefIndex == -1 || stringInIndex == -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringRefIndex != stringInIndex)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isCharInString(char *theString, int stringLen, char theChar)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < stringLen; i++)
|
||||||
|
{
|
||||||
|
if (theString[i] == theChar)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
@ -111,8 +111,8 @@ void workerCleanup(void *socketId)
|
|||||||
|
|
||||||
shutdown(ftpData.clients[theSocketId].workerData.socketConnection, SHUT_RDWR);
|
shutdown(ftpData.clients[theSocketId].workerData.socketConnection, SHUT_RDWR);
|
||||||
shutdown(ftpData.clients[theSocketId].workerData.passiveListeningSocket, SHUT_RDWR);
|
shutdown(ftpData.clients[theSocketId].workerData.passiveListeningSocket, SHUT_RDWR);
|
||||||
close(ftpData.clients[theSocketId].workerData.socketConnection);
|
returnCode = close(ftpData.clients[theSocketId].workerData.socketConnection);
|
||||||
close(ftpData.clients[theSocketId].workerData.passiveListeningSocket);
|
returnCode = close(ftpData.clients[theSocketId].workerData.passiveListeningSocket);
|
||||||
resetWorkerData(&ftpData, theSocketId, 0);
|
resetWorkerData(&ftpData, theSocketId, 0);
|
||||||
printf("\nWorker cleaned!");
|
printf("\nWorker cleaned!");
|
||||||
}
|
}
|
||||||
@ -342,7 +342,9 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(ftpData.clients[theSocketId].workerData.theStorFile);
|
|
||||||
|
int theReturnCode;
|
||||||
|
theReturnCode = fclose(ftpData.clients[theSocketId].workerData.theStorFile);
|
||||||
ftpData.clients[theSocketId].workerData.theStorFile = NULL;
|
ftpData.clients[theSocketId].workerData.theStorFile = NULL;
|
||||||
|
|
||||||
if (ftpData.clients[theSocketId].login.ownerShip.ownerShipSet == 1)
|
if (ftpData.clients[theSocketId].login.ownerShip.ownerShipSet == 1)
|
||||||
|
@ -291,6 +291,10 @@ int createSocket(ftpDataType * ftpData)
|
|||||||
|
|
||||||
//Socket creation
|
//Socket creation
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
temp.sin_family = AF_INET;
|
temp.sin_family = AF_INET;
|
||||||
temp.sin_addr.s_addr = INADDR_ANY;
|
temp.sin_addr.s_addr = INADDR_ANY;
|
||||||
temp.sin_port = htons(ftpData->ftpParameters.port);
|
temp.sin_port = htons(ftpData->ftpParameters.port);
|
||||||
@ -311,9 +315,25 @@ int createSocket(ftpDataType * ftpData)
|
|||||||
#endif
|
#endif
|
||||||
//Bind socket
|
//Bind socket
|
||||||
errorCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
errorCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
||||||
|
if (errorCode == -1)
|
||||||
|
{
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//Number of client allowed
|
//Number of client allowed
|
||||||
errorCode = listen(sock, ftpData->ftpParameters.maxClients + 1);
|
errorCode = listen(sock, ftpData->ftpParameters.maxClients + 1);
|
||||||
|
if (errorCode == -1)
|
||||||
|
{
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
@ -325,6 +345,11 @@ int createPassiveSocket(int port)
|
|||||||
|
|
||||||
//Socket creation
|
//Socket creation
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
temp.sin_family = AF_INET;
|
temp.sin_family = AF_INET;
|
||||||
temp.sin_addr.s_addr = INADDR_ANY;
|
temp.sin_addr.s_addr = INADDR_ANY;
|
||||||
temp.sin_port = htons(port);
|
temp.sin_port = htons(port);
|
||||||
@ -345,13 +370,28 @@ int createPassiveSocket(int port)
|
|||||||
returnCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
returnCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
||||||
|
|
||||||
if (returnCode == -1)
|
if (returnCode == -1)
|
||||||
|
{
|
||||||
|
printf("\n Could not bind %d errno = %d", sock, errno);
|
||||||
|
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
return returnCode;
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
//Number of client allowed
|
//Number of client allowed
|
||||||
returnCode = listen(sock, 1);
|
returnCode = listen(sock, 1);
|
||||||
|
|
||||||
if (returnCode == -1)
|
if (returnCode == -1)
|
||||||
|
{
|
||||||
|
printf("\n Could not listen %d errno = %d", sock, errno);
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
return returnCode;
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
@ -379,7 +419,7 @@ int createActiveSocket(int port, char *ipAddress)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("\n sockfd = %d \n", sockfd);
|
printf("\ncreateActiveSocket created socket = %d \n", sockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -398,6 +438,12 @@ int createActiveSocket(int port, char *ipAddress)
|
|||||||
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
||||||
{
|
{
|
||||||
printf("\n3 Error : Connect Failed \n");
|
printf("\n3 Error : Connect Failed \n");
|
||||||
|
|
||||||
|
if (sockfd != -1)
|
||||||
|
{
|
||||||
|
close(sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,9 +483,41 @@ void fdRemove(ftpDataType * ftpData, int index)
|
|||||||
|
|
||||||
void closeSocket(ftpDataType * ftpData, int processingSocket)
|
void closeSocket(ftpDataType * ftpData, int processingSocket)
|
||||||
{
|
{
|
||||||
|
int theReturnCode = 0;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
/*
|
||||||
|
if (ftpData->clients[processingSocket].dataChannelIsTls == 1)
|
||||||
|
{
|
||||||
|
if(ftpData->clients[processingSocket].workerData.passiveModeOn == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("\nSSL worker Shutdown 1");
|
||||||
|
returnCode = SSL_shutdown(ftpData->clients[processingSocket].ssl);
|
||||||
|
printf("\nnSSL worker Shutdown 1 return code : %d", returnCode);
|
||||||
|
|
||||||
|
if (returnCode < 0)
|
||||||
|
{
|
||||||
|
printf("SSL_shutdown failed return code %d", returnCode);
|
||||||
|
}
|
||||||
|
else if (returnCode == 0)
|
||||||
|
{
|
||||||
|
printf("\nSSL worker Shutdown 2");
|
||||||
|
returnCode = SSL_shutdown(ftpData->clients[processingSocket].ssl);
|
||||||
|
printf("\nnSSL worker Shutdown 2 return code : %d", returnCode);
|
||||||
|
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
printf("SSL_shutdown (2nd time) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
|
||||||
//Close the socket
|
//Close the socket
|
||||||
shutdown(ftpData->clients[processingSocket].socketDescriptor, SHUT_RDWR);
|
shutdown(ftpData->clients[processingSocket].socketDescriptor, SHUT_RDWR);
|
||||||
close(ftpData->clients[processingSocket].socketDescriptor);
|
theReturnCode = close(ftpData->clients[processingSocket].socketDescriptor);
|
||||||
|
|
||||||
resetClientData(ftpData, processingSocket, 0);
|
resetClientData(ftpData, processingSocket, 0);
|
||||||
resetWorkerData(ftpData, processingSocket, 0);
|
resetWorkerData(ftpData, processingSocket, 0);
|
||||||
@ -462,9 +540,7 @@ void closeClient(ftpDataType * ftpData, int processingSocket)
|
|||||||
|
|
||||||
if (ftpData->clients[processingSocket].workerData.threadIsAlive == 1)
|
if (ftpData->clients[processingSocket].workerData.threadIsAlive == 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_cancel(ftpData->clients[processingSocket].workerData.workerThread);
|
pthread_cancel(ftpData->clients[processingSocket].workerData.workerThread);
|
||||||
//pthread_join(ftpData->clients[processingSocket].workerData.workerThread, &pReturn);
|
|
||||||
printf("\nQuit command received the Pasv Thread has been cancelled.");
|
printf("\nQuit command received the Pasv Thread has been cancelled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +598,6 @@ int selectWait(ftpDataType * ftpData)
|
|||||||
struct timeval selectMaximumLockTime;
|
struct timeval selectMaximumLockTime;
|
||||||
selectMaximumLockTime.tv_sec = 10;
|
selectMaximumLockTime.tv_sec = 10;
|
||||||
selectMaximumLockTime.tv_usec = 0;
|
selectMaximumLockTime.tv_usec = 0;
|
||||||
|
|
||||||
ftpData->connectionData.rset = ftpData->connectionData.rsetAll;
|
ftpData->connectionData.rset = ftpData->connectionData.rsetAll;
|
||||||
ftpData->connectionData.wset = ftpData->connectionData.wsetAll;
|
ftpData->connectionData.wset = ftpData->connectionData.wsetAll;
|
||||||
ftpData->connectionData.eset = ftpData->connectionData.esetAll;
|
ftpData->connectionData.eset = ftpData->connectionData.esetAll;
|
||||||
@ -640,10 +715,11 @@ int evaluateClientSocketConnection(ftpDataType * ftpData)
|
|||||||
struct sockaddr_in socketRefuse_sockaddr_in;
|
struct sockaddr_in socketRefuse_sockaddr_in;
|
||||||
if ((socketRefuseFd = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&socketRefuse_sockaddr_in, (socklen_t*)&socketRefuse_in_size))!=-1)
|
if ((socketRefuseFd = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&socketRefuse_sockaddr_in, (socklen_t*)&socketRefuse_in_size))!=-1)
|
||||||
{
|
{
|
||||||
|
int theReturnCode = 0;
|
||||||
char *messageToWrite = "10068 Server reached the maximum number of connection, please try later.\r\n";
|
char *messageToWrite = "10068 Server reached the maximum number of connection, please try later.\r\n";
|
||||||
write(socketRefuseFd, messageToWrite, strlen(messageToWrite));
|
write(socketRefuseFd, messageToWrite, strlen(messageToWrite));
|
||||||
shutdown(socketRefuseFd, SHUT_RDWR);
|
shutdown(socketRefuseFd, SHUT_RDWR);
|
||||||
close(socketRefuseFd);
|
theReturnCode = close(socketRefuseFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
733
library/connection.c.orig
Normal file
733
library/connection.c.orig
Normal file
@ -0,0 +1,733 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright 2018 Ugo Cirmignani.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "../ftpData.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __fmt, ...)
|
||||||
|
{
|
||||||
|
#define COMMAND_BUFFER 9600
|
||||||
|
#define SOCKET_PRINTF_BUFFER 2048
|
||||||
|
int bytesWritten = 0;
|
||||||
|
char theBuffer[SOCKET_PRINTF_BUFFER];
|
||||||
|
char commandBuffer[COMMAND_BUFFER];
|
||||||
|
int theStringSize = 0, theCommandSize = 0;
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
memset(&commandBuffer, 0, COMMAND_BUFFER);
|
||||||
|
printf("\nWriting to socket id %d, TLS %d: ", clientId, ftpData->clients[clientId].tlsIsEnabled);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ftpData->clients[clientId].writeMutex);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, __fmt);
|
||||||
|
while (*__fmt != '\0')
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
theStringSize = 0;
|
||||||
|
switch(*__fmt)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
{
|
||||||
|
int theInteger = va_arg(args, int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%d", theInteger);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
{
|
||||||
|
int theCharInteger = va_arg(args, int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%c", theCharInteger);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
{
|
||||||
|
float theDouble = va_arg(args, double);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%f", theDouble);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
{
|
||||||
|
char * theString = va_arg(args, char *);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%s", theString);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
{
|
||||||
|
long long int theLongLongInt = va_arg(args, long long int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%lld", theLongLongInt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\n Switch is default (%c)", *__fmt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <theStringSize; i++)
|
||||||
|
{
|
||||||
|
if (theCommandSize < COMMAND_BUFFER)
|
||||||
|
{
|
||||||
|
commandBuffer[theCommandSize++] = theBuffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++__fmt;
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
|
||||||
|
if (ftpData->clients[clientId].tlsIsEnabled != 1)
|
||||||
|
{
|
||||||
|
bytesWritten = write(ftpData->clients[clientId].socketDescriptor, commandBuffer, theCommandSize);
|
||||||
|
}
|
||||||
|
else if (ftpData->clients[clientId].tlsIsEnabled == 1)
|
||||||
|
{
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
bytesWritten = SSL_write(ftpData->clients[clientId].ssl, commandBuffer, theCommandSize);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n%s", commandBuffer);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ftpData->clients[clientId].writeMutex);
|
||||||
|
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socketWorkerPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __fmt, ...)
|
||||||
|
{
|
||||||
|
#define SOCKET_PRINTF_BUFFER 2048
|
||||||
|
|
||||||
|
int bytesWritten = 0;
|
||||||
|
char theBuffer[SOCKET_PRINTF_BUFFER];
|
||||||
|
int theStringSize = 0;
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
//printf("\nWriting to worker socket id %dd, TLS %d: ", clientId, ftpData->clients[clientId].dataChannelIsTls);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, __fmt);
|
||||||
|
while (*__fmt != '\0')
|
||||||
|
{
|
||||||
|
theStringSize = 0;
|
||||||
|
switch(*__fmt)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
{
|
||||||
|
int theInteger = va_arg(args, int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%d", theInteger);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
{
|
||||||
|
int theCharInteger = va_arg(args, int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%c", theCharInteger);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
{
|
||||||
|
float theDouble = va_arg(args, double);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%f", theDouble);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
{
|
||||||
|
char * theString = va_arg(args, char *);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%s", theString);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
{
|
||||||
|
long long int theLongLongInt = va_arg(args, long long int);
|
||||||
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
|
theStringSize = snprintf(theBuffer, SOCKET_PRINTF_BUFFER, "%lld", theLongLongInt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\n Switch is default (%c)", *__fmt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theStringSize >= SOCKET_PRINTF_BUFFER) {
|
||||||
|
printf("\n String buffer is full!");
|
||||||
|
}
|
||||||
|
else if (theStringSize < SOCKET_PRINTF_BUFFER &&
|
||||||
|
theStringSize > 0)
|
||||||
|
{
|
||||||
|
int theReturnCode = 0;
|
||||||
|
|
||||||
|
if (ftpData->clients[clientId].dataChannelIsTls != 1)
|
||||||
|
{
|
||||||
|
theReturnCode = write(ftpData->clients[clientId].workerData.socketConnection, theBuffer, theStringSize);
|
||||||
|
}
|
||||||
|
else if (ftpData->clients[clientId].dataChannelIsTls == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
if (ftpData->clients[clientId].workerData.passiveModeOn == 1){
|
||||||
|
theReturnCode = SSL_write(ftpData->clients[clientId].workerData.serverSsl, theBuffer, theStringSize);
|
||||||
|
printf("%s", theBuffer);
|
||||||
|
}
|
||||||
|
else if (ftpData->clients[clientId].workerData.activeModeOn == 1){
|
||||||
|
theReturnCode = SSL_write(ftpData->clients[clientId].workerData.clientSsl, theBuffer, theStringSize);
|
||||||
|
printf("%s", theBuffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (theReturnCode > 0)
|
||||||
|
{
|
||||||
|
bytesWritten += theReturnCode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytesWritten = theReturnCode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(theStringSize == 0)
|
||||||
|
{
|
||||||
|
printf("\n Nothing to write.. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
++__fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the higher socket available*/
|
||||||
|
int getMaximumSocketFd(int mainSocket, ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
int toReturn = mainSocket;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ftpData->ftpParameters.maxClients; i++)
|
||||||
|
{
|
||||||
|
if (ftpData->clients[i].socketDescriptor > toReturn) {
|
||||||
|
toReturn = ftpData->clients[i].socketDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Must be incremented by one
|
||||||
|
toReturn++;
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
int createSocket(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
printf("\nCreating main socket on port %d", ftpData->ftpParameters.port);
|
||||||
|
int sock, errorCode;
|
||||||
|
struct sockaddr_in temp;
|
||||||
|
|
||||||
|
//Socket creation
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
temp.sin_family = AF_INET;
|
||||||
|
temp.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
temp.sin_port = htons(ftpData->ftpParameters.port);
|
||||||
|
|
||||||
|
//No blocking socket
|
||||||
|
errorCode = fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
|
||||||
|
#ifdef SO_REUSEADDR
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEADDR) failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEPORT) failed");
|
||||||
|
#endif
|
||||||
|
//Bind socket
|
||||||
|
errorCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
||||||
|
if (errorCode == -1)
|
||||||
|
{
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Number of client allowed
|
||||||
|
errorCode = listen(sock, ftpData->ftpParameters.maxClients + 1);
|
||||||
|
if (errorCode == -1)
|
||||||
|
{
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int createPassiveSocket(int port)
|
||||||
|
{
|
||||||
|
int sock, returnCode;
|
||||||
|
struct sockaddr_in temp;
|
||||||
|
|
||||||
|
//Socket creation
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.sin_family = AF_INET;
|
||||||
|
temp.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
temp.sin_port = htons(port);
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
|
||||||
|
#ifdef SO_REUSEADDR
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEADDR) failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEPORT) failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Bind socket
|
||||||
|
returnCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
||||||
|
|
||||||
|
if (returnCode == -1)
|
||||||
|
{
|
||||||
|
printf("\n Could not bind %d errno = %d", sock, errno);
|
||||||
|
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Number of client allowed
|
||||||
|
returnCode = listen(sock, 1);
|
||||||
|
|
||||||
|
if (returnCode == -1)
|
||||||
|
{
|
||||||
|
printf("\n Could not listen %d errno = %d", sock, errno);
|
||||||
|
if (sock != -1)
|
||||||
|
{
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int createActiveSocket(int port, char *ipAddress)
|
||||||
|
{
|
||||||
|
int sockfd;
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
|
||||||
|
printf("\n Connection socket is going to start ip: %s:%d \n", ipAddress, port);
|
||||||
|
//sleep(100);
|
||||||
|
memset(&serv_addr, 0, sizeof(struct sockaddr_in));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_port = htons(port);
|
||||||
|
if(inet_pton(AF_INET, ipAddress, &serv_addr.sin_addr)<=0)
|
||||||
|
{
|
||||||
|
printf("\n inet_pton error occured\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
{
|
||||||
|
printf("\n2 Error : Could not create socket \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\ncreateActiveSocket created socket = %d \n", sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
#ifdef SO_REUSEADDR
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEADDR) failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||||
|
perror("setsockopt(SO_REUSEPORT) failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
||||||
|
{
|
||||||
|
printf("\n3 Error : Connect Failed \n");
|
||||||
|
|
||||||
|
if (sockfd != -1)
|
||||||
|
{
|
||||||
|
close(sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n Connection socket %d is going to start ip: %s:%d \n",sockfd, ipAddress, port);
|
||||||
|
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fdInit(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
FD_ZERO(&ftpData->connectionData.rset);
|
||||||
|
FD_ZERO(&ftpData->connectionData.wset);
|
||||||
|
FD_ZERO(&ftpData->connectionData.eset);
|
||||||
|
FD_ZERO(&ftpData->connectionData.rsetAll);
|
||||||
|
FD_ZERO(&ftpData->connectionData.wsetAll);
|
||||||
|
FD_ZERO(&ftpData->connectionData.esetAll);
|
||||||
|
|
||||||
|
FD_SET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rsetAll);
|
||||||
|
FD_SET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.wsetAll);
|
||||||
|
FD_SET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.esetAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fdAdd(ftpDataType * ftpData, int index)
|
||||||
|
{
|
||||||
|
FD_SET(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.rsetAll);
|
||||||
|
FD_SET(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.wsetAll);
|
||||||
|
FD_SET(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.esetAll);
|
||||||
|
ftpData->connectionData.maxSocketFD = getMaximumSocketFd(ftpData->connectionData.theMainSocket, ftpData) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fdRemove(ftpDataType * ftpData, int index)
|
||||||
|
{
|
||||||
|
FD_CLR(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.rsetAll);
|
||||||
|
FD_CLR(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.wsetAll);
|
||||||
|
FD_CLR(ftpData->clients[index].socketDescriptor, &ftpData->connectionData.esetAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeSocket(ftpDataType * ftpData, int processingSocket)
|
||||||
|
{
|
||||||
|
int theReturnCode = 0;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
/*
|
||||||
|
if (ftpData->clients[processingSocket].dataChannelIsTls == 1)
|
||||||
|
{
|
||||||
|
if(ftpData->clients[processingSocket].workerData.passiveModeOn == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("\nSSL worker Shutdown 1");
|
||||||
|
returnCode = SSL_shutdown(ftpData->clients[processingSocket].ssl);
|
||||||
|
printf("\nnSSL worker Shutdown 1 return code : %d", returnCode);
|
||||||
|
|
||||||
|
if (returnCode < 0)
|
||||||
|
{
|
||||||
|
printf("SSL_shutdown failed return code %d", returnCode);
|
||||||
|
}
|
||||||
|
else if (returnCode == 0)
|
||||||
|
{
|
||||||
|
printf("\nSSL worker Shutdown 2");
|
||||||
|
returnCode = SSL_shutdown(ftpData->clients[processingSocket].ssl);
|
||||||
|
printf("\nnSSL worker Shutdown 2 return code : %d", returnCode);
|
||||||
|
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
printf("SSL_shutdown (2nd time) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Close the socket
|
||||||
|
shutdown(ftpData->clients[processingSocket].socketDescriptor, SHUT_RDWR);
|
||||||
|
theReturnCode = close(ftpData->clients[processingSocket].socketDescriptor);
|
||||||
|
|
||||||
|
resetClientData(ftpData, processingSocket, 0);
|
||||||
|
resetWorkerData(ftpData, processingSocket, 0);
|
||||||
|
|
||||||
|
//Update client connecteds
|
||||||
|
ftpData->connectedClients--;
|
||||||
|
if (ftpData->connectedClients < 0)
|
||||||
|
{
|
||||||
|
ftpData->connectedClients = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Client id: %d disconnected", processingSocket);
|
||||||
|
printf("\nServer: Clients connected:%d", ftpData->connectedClients);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeClient(ftpDataType * ftpData, int processingSocket)
|
||||||
|
{
|
||||||
|
printf("\nQUIT FLAG SET!\n");
|
||||||
|
|
||||||
|
if (ftpData->clients[processingSocket].workerData.threadIsAlive == 1)
|
||||||
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> master
|
||||||
|
pthread_cancel(ftpData->clients[processingSocket].workerData.workerThread);
|
||||||
|
printf("\nQuit command received the Pasv Thread has been cancelled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_CLR(ftpData->clients[processingSocket].socketDescriptor, &ftpData->connectionData.rsetAll);
|
||||||
|
FD_CLR(ftpData->clients[processingSocket].socketDescriptor, &ftpData->connectionData.wsetAll);
|
||||||
|
FD_CLR(ftpData->clients[processingSocket].socketDescriptor, &ftpData->connectionData.esetAll);
|
||||||
|
|
||||||
|
closeSocket(ftpData, processingSocket);
|
||||||
|
|
||||||
|
ftpData->connectionData.maxSocketFD = ftpData->connectionData.theMainSocket+1;
|
||||||
|
ftpData->connectionData.maxSocketFD = getMaximumSocketFd(ftpData->connectionData.theMainSocket, ftpData) + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkClientConnectionTimeout(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
int processingSock;
|
||||||
|
for (processingSock = 0; processingSock < ftpData->ftpParameters.maxClients; processingSock++)
|
||||||
|
{
|
||||||
|
/* No connection active*/
|
||||||
|
if (ftpData->clients[processingSock].socketDescriptor < 0 ||
|
||||||
|
ftpData->clients[processingSock].socketIsConnected == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Max idle time check, close the connection if time is elapsed */
|
||||||
|
if (ftpData->ftpParameters.maximumIdleInactivity != 0 &&
|
||||||
|
(int)time(NULL) - ftpData->clients[processingSock].lastActivityTimeStamp > ftpData->ftpParameters.maximumIdleInactivity)
|
||||||
|
{
|
||||||
|
ftpData->clients[processingSock].closeTheClient = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void flushLoginWrongTriesData(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
//printf("\n flushLoginWrongTriesData size of the vector : %d", ftpData->loginFailsVector.Size);
|
||||||
|
|
||||||
|
for (i = (ftpData->loginFailsVector.Size-1); i >= 0; i--)
|
||||||
|
{
|
||||||
|
//printf("\n last login fail attempt : %d", ((loginFailsDataType *) ftpData->loginFailsVector.Data[i])->failTimeStamp);
|
||||||
|
|
||||||
|
if ( (time(NULL) - ((loginFailsDataType *) ftpData->loginFailsVector.Data[i])->failTimeStamp) > WRONG_PASSWORD_ALLOWED_RETRY_TIME)
|
||||||
|
{
|
||||||
|
//printf("\n Deleting element : %d", i);
|
||||||
|
ftpData->loginFailsVector.DeleteAt(&ftpData->loginFailsVector, i, deleteLoginFailsData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectWait(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
struct timeval selectMaximumLockTime;
|
||||||
|
selectMaximumLockTime.tv_sec = 10;
|
||||||
|
selectMaximumLockTime.tv_usec = 0;
|
||||||
|
ftpData->connectionData.rset = ftpData->connectionData.rsetAll;
|
||||||
|
ftpData->connectionData.wset = ftpData->connectionData.wsetAll;
|
||||||
|
ftpData->connectionData.eset = ftpData->connectionData.esetAll;
|
||||||
|
return select(ftpData->connectionData.maxSocketFD, &ftpData->connectionData.rset, NULL, &ftpData->connectionData.eset, &selectMaximumLockTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int isClientConnected(ftpDataType * ftpData, int cliendId)
|
||||||
|
{
|
||||||
|
if (ftpData->clients[cliendId].socketDescriptor < 0 ||
|
||||||
|
ftpData->clients[cliendId].socketIsConnected == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getAvailableClientSocketIndex(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
int socketIndex;
|
||||||
|
for (socketIndex = 0; socketIndex < ftpData->ftpParameters.maxClients; socketIndex++)
|
||||||
|
{
|
||||||
|
if (isClientConnected(ftpData, socketIndex) == 0)
|
||||||
|
{
|
||||||
|
return socketIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no socket are available for a new client connection */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rset))
|
||||||
|
{
|
||||||
|
int availableSocketIndex;
|
||||||
|
if ((availableSocketIndex = getAvailableClientSocketIndex(ftpData)) != -1) //get available socket
|
||||||
|
{
|
||||||
|
if ((ftpData->clients[availableSocketIndex].socketDescriptor = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&ftpData->clients[availableSocketIndex].client_sockaddr_in, (socklen_t*)&ftpData->clients[availableSocketIndex].sockaddr_in_size))!=-1)
|
||||||
|
{
|
||||||
|
int error, numberOfConnectionFromSameIp, i;
|
||||||
|
numberOfConnectionFromSameIp = 0;
|
||||||
|
ftpData->connectedClients++;
|
||||||
|
ftpData->clients[availableSocketIndex].socketIsConnected = 1;
|
||||||
|
|
||||||
|
error = fcntl(ftpData->clients[availableSocketIndex].socketDescriptor, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
|
fdAdd(ftpData, availableSocketIndex);
|
||||||
|
|
||||||
|
error = getsockname(ftpData->clients[availableSocketIndex].socketDescriptor, (struct sockaddr *)&ftpData->clients[availableSocketIndex].server_sockaddr_in, (socklen_t*)&ftpData->clients[availableSocketIndex].sockaddr_in_server_size);
|
||||||
|
inet_ntop(AF_INET,
|
||||||
|
&(ftpData->clients[availableSocketIndex].server_sockaddr_in.sin_addr),
|
||||||
|
ftpData->clients[availableSocketIndex].serverIpAddress,
|
||||||
|
INET_ADDRSTRLEN);
|
||||||
|
printf("\n Server IP: %s", ftpData->clients[availableSocketIndex].serverIpAddress);
|
||||||
|
printf("Server: New client connected with id: %d", availableSocketIndex);
|
||||||
|
printf("\nServer: Clients connected: %d", ftpData->connectedClients);
|
||||||
|
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpAddressInteger[0],
|
||||||
|
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[1],
|
||||||
|
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[2],
|
||||||
|
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[3]);
|
||||||
|
|
||||||
|
inet_ntop(AF_INET,
|
||||||
|
&(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_addr),
|
||||||
|
ftpData->clients[availableSocketIndex].clientIpAddress,
|
||||||
|
INET_ADDRSTRLEN);
|
||||||
|
printf("\n Client IP: %s", ftpData->clients[availableSocketIndex].clientIpAddress);
|
||||||
|
ftpData->clients[availableSocketIndex].clientPort = (int) ntohs(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_port);
|
||||||
|
printf("\nClient port is: %d\n", ftpData->clients[availableSocketIndex].clientPort);
|
||||||
|
|
||||||
|
ftpData->clients[availableSocketIndex].connectionTimeStamp = (int)time(NULL);
|
||||||
|
ftpData->clients[availableSocketIndex].lastActivityTimeStamp = (int)time(NULL);
|
||||||
|
|
||||||
|
for (i = 0; i <ftpData->ftpParameters.maxClients; i++)
|
||||||
|
{
|
||||||
|
if (i == availableSocketIndex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(ftpData->clients[availableSocketIndex].clientIpAddress, ftpData->clients[i].clientIpAddress) == 0) {
|
||||||
|
numberOfConnectionFromSameIp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ftpData->ftpParameters.maximumConnectionsPerIp > 0 &&
|
||||||
|
numberOfConnectionFromSameIp >= ftpData->ftpParameters.maximumConnectionsPerIp)
|
||||||
|
{
|
||||||
|
int theReturnCode = socketPrintf(ftpData, availableSocketIndex, "sss", "530 too many connection from your ip address ", ftpData->clients[availableSocketIndex].clientIpAddress, " \r\n");
|
||||||
|
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int returnCode = socketPrintf(ftpData, availableSocketIndex, "s", ftpData->welcomeMessage);
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Errors while accepting, socket will be closed
|
||||||
|
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||||
|
printf("\n2 Errno = %d", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int socketRefuseFd, socketRefuse_in_size;
|
||||||
|
socketRefuse_in_size = sizeof(struct sockaddr_in);
|
||||||
|
struct sockaddr_in socketRefuse_sockaddr_in;
|
||||||
|
if ((socketRefuseFd = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&socketRefuse_sockaddr_in, (socklen_t*)&socketRefuse_in_size))!=-1)
|
||||||
|
{
|
||||||
|
int theReturnCode = 0;
|
||||||
|
char *messageToWrite = "10068 Server reached the maximum number of connection, please try later.\r\n";
|
||||||
|
write(socketRefuseFd, messageToWrite, strlen(messageToWrite));
|
||||||
|
shutdown(socketRefuseFd, SHUT_RDWR);
|
||||||
|
theReturnCode = close(socketRefuseFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//No new socket
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -22,10 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -37,6 +33,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#include "fileManagement.h"
|
#include "fileManagement.h"
|
||||||
#include "dynamicVectors.h"
|
#include "dynamicVectors.h"
|
||||||
@ -59,6 +56,11 @@ static int FILE_CompareStringParameter(const void * a, const void * b)
|
|||||||
return strcmp(typeA->Name, typeB->Name);
|
return strcmp(typeA->Name, typeB->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FILE_fdIsValid(int fd)
|
||||||
|
{
|
||||||
|
return fcntl(fd, F_GETFD);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if inode is a directory */
|
/* Check if inode is a directory */
|
||||||
int FILE_IsDirectory(char *DirectoryPath)
|
int FILE_IsDirectory(char *DirectoryPath)
|
||||||
{
|
{
|
||||||
@ -719,3 +721,57 @@ gid_t FILE_getGID(const char *group_name)
|
|||||||
|
|
||||||
return grp->gr_gid;
|
return grp->gr_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FILE_checkAllOpenedFD(void)
|
||||||
|
{
|
||||||
|
int openedFd = 0, i,ret;
|
||||||
|
|
||||||
|
struct rlimit rl;
|
||||||
|
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
|
||||||
|
printf("%s: can’t get file limit", "");
|
||||||
|
|
||||||
|
if (rl.rlim_max == RLIM_INFINITY)
|
||||||
|
rl.rlim_max = 1024;
|
||||||
|
|
||||||
|
for (i = 0; i < rl.rlim_max; i++)
|
||||||
|
{
|
||||||
|
ret = FILE_fdIsValid(i);
|
||||||
|
//printf("\nret = %d", ret);
|
||||||
|
if (ret != -1)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
fstat(i, &statbuf);
|
||||||
|
if (S_ISSOCK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is socket", i);
|
||||||
|
}
|
||||||
|
else if (S_ISDIR(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is dir", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
else if (S_ISSOCK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is socket", fd);
|
||||||
|
}
|
||||||
|
else if (S_ISSOCK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is socket", fd);
|
||||||
|
}
|
||||||
|
else if (S_ISSOCK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is socket", fd);
|
||||||
|
}
|
||||||
|
else if (S_ISSOCK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
printf("\n fd %d is socket", fd);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
openedFd++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n\nOpened fd : %d", openedFd);
|
||||||
|
}
|
||||||
|
@ -71,5 +71,7 @@
|
|||||||
int FILE_doChownFromUidGid(const char *file_path, uid_t uid, gid_t gid);
|
int FILE_doChownFromUidGid(const char *file_path, uid_t uid, gid_t gid);
|
||||||
uid_t FILE_getUID(const char *user_name);
|
uid_t FILE_getUID(const char *user_name);
|
||||||
gid_t FILE_getGID(const char *group_name);
|
gid_t FILE_getGID(const char *group_name);
|
||||||
|
void FILE_checkAllOpenedFD(void);
|
||||||
|
int fd_is_valid(int fd);
|
||||||
#define GEN_FILE_MANAGEMENT_TYPES
|
#define GEN_FILE_MANAGEMENT_TYPES
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,7 +10,7 @@ MAXIMUM_ALLOWED_FTP_CONNECTION = 30
|
|||||||
FTP_PORT = 21
|
FTP_PORT = 21
|
||||||
#TCP/IP PORT SETTINGS (DEFAULT 21)
|
#TCP/IP PORT SETTINGS (DEFAULT 21)
|
||||||
|
|
||||||
SINGLE_INSTANCE = true
|
SINGLE_INSTANCE = false
|
||||||
#Allow only one server instance (true or false)
|
#Allow only one server instance (true or false)
|
||||||
|
|
||||||
DAEMON_MODE = false
|
DAEMON_MODE = false
|
||||||
|
Reference in New Issue
Block a user