mirror of
https://github.com/kingk85/uFTP.git
synced 2025-04-12 10:48:40 +03:00
STAT okay, some changes with error codes and checksafepath function
This commit is contained in:
@ -1,9 +1,18 @@
|
||||
#ifndef ENABLE_PRINTF_MODULE
|
||||
|
||||
// Uncomment next line to enable debug printf
|
||||
// #define ENABLE_PRINTF
|
||||
#ifdef ENABLE_PRINTF
|
||||
//#define ENABLE_PRINTF
|
||||
//#define ENABLE_PRINTF_ERROR
|
||||
|
||||
#ifdef ENABLE_PRINTF
|
||||
#define my_printf(fmt, args...) fprintf(stderr, " file: %s %d %s()" fmt, __FILE__, __LINE__, __func__, ##args)
|
||||
#else
|
||||
#define my_printf(format, ...) // Empty macro, no action
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_PRINTF_ERROR
|
||||
#define my_printfError(fmt, args...) fprintf(stderr, " file: %s %d %s()" fmt, __FILE__, __LINE__, __func__, ##args)
|
||||
#else
|
||||
#define my_printfError(format, ...) // Empty macro, no action
|
||||
#endif
|
||||
#endif
|
@ -387,7 +387,7 @@ int parseCommandCcc(ftpDataType *data, int socketId)
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_ENABLED
|
||||
returnCode = socketPrintf(data, socketId, "s", "500 command not supported\r\n");
|
||||
returnCode = socketPrintf(data, socketId, "s", "502 command not supported\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
@ -480,7 +480,7 @@ int parseCommandPasv(ftpDataType *data, int socketId)
|
||||
|
||||
if (returnCode != 0)
|
||||
{
|
||||
my_printf("\nError in pthread_create %d", returnCode);
|
||||
my_printfError("\nError in pthread_create %d", returnCode);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ int parseCommandEpsv(ftpDataType *data, int socketId)
|
||||
|
||||
if (returnCode != 0)
|
||||
{
|
||||
// my_printf("\nError in pthread_create %d", returnCode);
|
||||
my_printfError("\nError in pthread_create %d", returnCode);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
@ -552,7 +552,7 @@ int parseCommandPort(ftpDataType *data, int socketId)
|
||||
|
||||
if (returnCode != 0)
|
||||
{
|
||||
// my_printf("\nError in pthread_create %d", returnCode);
|
||||
my_printfError("\nError in pthread_create %d", returnCode);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
@ -679,38 +679,43 @@ int parseCommandList(ftpDataType *data, int socketId)
|
||||
int parseCommandStat(ftpDataType *data, int socketId)
|
||||
{
|
||||
|
||||
return FTP_COMMAND_NOT_RECONIZED;
|
||||
/*
|
||||
-A List all files except "." and ".."
|
||||
-a List all files including those whose names start with "."
|
||||
|
||||
*/
|
||||
|
||||
int isSafePath = 0;
|
||||
int returnCode = 0;
|
||||
char *theNameToList;
|
||||
char *theNameToList = NULL;
|
||||
int theFiles;
|
||||
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0, &data->clients[socketId].workerData.memoryTable);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0, &data->clients[socketId].workerData.memoryTable);
|
||||
|
||||
theNameToList = getFtpCommandArg("STAT", data->clients[socketId].theCommandReceived, 1);
|
||||
getFtpCommandArgWithOptions("STAT", data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.ftpCommand, &data->clients[socketId].workerData.memoryTable);
|
||||
|
||||
if (strnlen(theNameToList, 1) == 0)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n");
|
||||
|
||||
my_printf("\nNo stat argument");
|
||||
returnCode = socketPrintf(data, socketId, "sssssdsss",
|
||||
"211-FTP server status:\r\n",
|
||||
" Logged in as ",
|
||||
data->clients[socketId].login.name.text,
|
||||
"\r\n",
|
||||
" Session timeout in seconds is ",
|
||||
data->ftpParameters.maximumIdleInactivity,
|
||||
"\r\n",
|
||||
" uFTP "UFTP_SERVER_VERSION"\r\n",
|
||||
"211 End of status\r\n"
|
||||
);
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0, &data->clients[socketId].workerData.memoryTable);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0, &data->clients[socketId].workerData.memoryTable);
|
||||
|
||||
theNameToList = getFtpCommandArg("LIST", data->clients[socketId].theCommandReceived, 1);
|
||||
getFtpCommandArgWithOptions("LIST", data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.ftpCommand, &data->clients[socketId].workerData.memoryTable);
|
||||
|
||||
|
||||
if (data->clients[socketId].workerData.ftpCommand.commandArgs.text != NULL)
|
||||
my_printf("\nLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
||||
my_printf("\nSTAT COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
||||
if (data->clients[socketId].workerData.ftpCommand.commandOps.text != NULL)
|
||||
my_printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||
my_printf("\nSTAT COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||
|
||||
|
||||
cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable);
|
||||
@ -723,12 +728,15 @@ int parseCommandStat(ftpDataType *data, int socketId)
|
||||
if (isSafePath == 0)
|
||||
{
|
||||
cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable);
|
||||
setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable);
|
||||
setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable);
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 wrong path\r\n");
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if(FILE_IsDirectory(data->clients[socketId].listPath.text) == 0 && FILE_IsFile(data->clients[socketId].listPath.text) == 0)
|
||||
{
|
||||
my_printf("\nLIST path not file or directoy: %s ", data->clients[socketId].listPath.text);
|
||||
my_printf("\nSTAT path not file or directoy: %s ", data->clients[socketId].listPath.text);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable);
|
||||
setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable);
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 wrong path\r\n");
|
||||
@ -751,12 +759,23 @@ int parseCommandStat(ftpDataType *data, int socketId)
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&data->clients[socketId].conditionMutex);
|
||||
memset(data->clients[socketId].workerData.theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1);
|
||||
strncpy(data->clients[socketId].workerData.theCommandReceived, data->clients[socketId].theCommandReceived, CLIENT_COMMAND_STRING_SIZE);
|
||||
data->clients[socketId].workerData.commandReceived = 1;
|
||||
pthread_cond_signal(&data->clients[socketId].conditionVariable);
|
||||
pthread_mutex_unlock(&data->clients[socketId].conditionMutex);
|
||||
returnCode = socketPrintf(data, socketId, "s", "213-Status follow:\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
returnCode = writeListDataInfoToSocket(data, socketId, &theFiles, COMMAND_TYPE_STAT, &data->clients[socketId].workerData.memoryTable);
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "sds", "213 End of status ", theFiles, " matches total\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
@ -1078,7 +1097,7 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": no permissions\r\n");
|
||||
returnCode = socketPrintf(data, socketId, "sss", "550 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": no permissions\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
@ -1089,7 +1108,7 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": No such file or directory\r\n");
|
||||
returnCode = socketPrintf(data, socketId, "sss", "550 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": No such file or directory\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
@ -1177,8 +1196,11 @@ int parseCommandMkd(ftpDataType *data, int socketId)
|
||||
else if (compareStringCaseInsensitive(data->clients[socketId].theCommandReceived, "XMKD", strlen("XMKD")) == 1)
|
||||
theDirectoryFilename = getFtpCommandArg("XMKD", data->clients[socketId].theCommandReceived, 0);
|
||||
|
||||
my_printf("\ntheDirectoryFilename mkd: %s", theDirectoryFilename);
|
||||
|
||||
cleanDynamicStringDataType(&mkdFileName, 1, &data->clients[socketId].memoryTable);
|
||||
isSafePath = getSafePath(&mkdFileName, theDirectoryFilename, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
my_printf("\nmkdFileName.text: %s", mkdFileName.text);
|
||||
|
||||
if (isSafePath == 1)
|
||||
{
|
||||
|
220
ftpData.c
220
ftpData.c
@ -31,6 +31,7 @@
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "ftpServer.h"
|
||||
#include "ftpCommandsElaborate.h"
|
||||
@ -42,6 +43,59 @@
|
||||
|
||||
#include "debugHelper.h"
|
||||
|
||||
static int is_prefix(const char *str, const char *prefix);
|
||||
static char *my_realpath(const char *path, char *resolved_path);
|
||||
|
||||
static char *my_realpath(const char *path, char *resolved_path)
|
||||
{
|
||||
char temp[PATH_MAX];
|
||||
char *token;
|
||||
char *rest = NULL;
|
||||
|
||||
// Check if the path is absolute or relative
|
||||
if (path[0] == '/')
|
||||
{
|
||||
strcpy(temp, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_printfError("getcwd");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Process tokens separated by '/'
|
||||
token = strtok_r(temp, "/", &rest);
|
||||
while (token != NULL)
|
||||
{
|
||||
if (strcmp(token, "..") == 0)
|
||||
{
|
||||
// Remove the last directory if it's not the root directory
|
||||
char *last_slash = strrchr(resolved_path, '/');
|
||||
if (last_slash != NULL) {
|
||||
*last_slash = '\0';
|
||||
}
|
||||
}
|
||||
else if (strcmp(token, ".") != 0)
|
||||
{
|
||||
// Add valid token to the resolved path
|
||||
strcat(resolved_path, "/");
|
||||
strcat(resolved_path, token);
|
||||
}
|
||||
token = strtok_r(NULL, "/", &rest);
|
||||
}
|
||||
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
static int is_prefix(const char *str, const char *prefix) {
|
||||
int i = 0;
|
||||
while (prefix[i] && str[i] && prefix[i] == str[i]) {
|
||||
i++;
|
||||
}
|
||||
// Check if prefix ended and characters in str matched till then
|
||||
return prefix[i] == '\0';
|
||||
}
|
||||
|
||||
void cleanDynamicStringDataType(dynamicStringDataType *dynamicString, int init, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||
{
|
||||
if (init == 1)
|
||||
@ -96,90 +150,89 @@ void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theStr
|
||||
|
||||
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||
{
|
||||
#define STRING_SIZE 4096
|
||||
size_t theLen, i;
|
||||
size_t theLen;
|
||||
char * theDirectoryNamePointer;
|
||||
theDirectoryNamePointer = theDirectoryName;
|
||||
|
||||
char theDirectoryToCheck[PATH_MAX];
|
||||
int theDirectoryToCheckIndex = 0;
|
||||
char resolved_path[PATH_MAX];
|
||||
char resolved_path_abs[PATH_MAX];
|
||||
|
||||
memset(theDirectoryToCheck, 0, PATH_MAX);
|
||||
memset(resolved_path, 0, PATH_MAX);
|
||||
memset(resolved_path_abs, 0, PATH_MAX);
|
||||
|
||||
//No name provided return false
|
||||
if (theDirectoryName == NULL)
|
||||
return 0;
|
||||
|
||||
theLen = strlen(theDirectoryName);
|
||||
|
||||
theLen = strnlen(theDirectoryName, PATH_MAX);
|
||||
|
||||
//Not a string
|
||||
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 */
|
||||
}
|
||||
|
||||
my_printf("\ninput: %s", theDirectoryName);
|
||||
//Absolute path set in the request, start from home directory
|
||||
if (theDirectoryName[0] == '/')
|
||||
{
|
||||
while (theDirectoryNamePointer[0] == '/')
|
||||
theDirectoryNamePointer++;
|
||||
|
||||
//my_printf("\nMemory data address 2nd call : %lld", memoryTable);
|
||||
setDynamicStringDataType(safePath, loginData->homePath.text, loginData->homePath.textLen, memoryTable);
|
||||
//my_printf("\nMemory data address 3rd call : %lld", memoryTable);
|
||||
appendToDynamicStringDataType(safePath, theDirectoryNamePointer, strlen(theDirectoryNamePointer), memoryTable);
|
||||
//Absolute requests must start from home path
|
||||
strncpy(theDirectoryToCheck, loginData->homePath.text, PATH_MAX);
|
||||
strncat(theDirectoryToCheck, theDirectoryNamePointer, PATH_MAX);
|
||||
my_printf("\nAbsolute string: %s", theDirectoryToCheck);
|
||||
}
|
||||
else
|
||||
{
|
||||
setDynamicStringDataType(safePath, loginData->absolutePath.text, loginData->absolutePath.textLen, memoryTable);
|
||||
//Relative directory, start from the current path
|
||||
strncpy(theDirectoryToCheck, loginData->absolutePath.text, PATH_MAX);
|
||||
|
||||
if (loginData->absolutePath.text[loginData->absolutePath.textLen-1] != '/')
|
||||
{
|
||||
appendToDynamicStringDataType(safePath, "/", 1, memoryTable);
|
||||
strncat(theDirectoryToCheck, "/", PATH_MAX);
|
||||
}
|
||||
|
||||
appendToDynamicStringDataType(safePath, theDirectoryName, strlen(theDirectoryName), memoryTable);
|
||||
|
||||
strncat(theDirectoryToCheck, theDirectoryNamePointer, PATH_MAX);
|
||||
my_printf("\nRelative string: %s", theDirectoryToCheck);
|
||||
}
|
||||
|
||||
|
||||
my_printf("\nrealpath input: %s", theDirectoryToCheck);
|
||||
if (strnlen(theDirectoryToCheck, 2) == 1 && theDirectoryToCheck[0] == '/')
|
||||
{
|
||||
setDynamicStringDataType(safePath, theDirectoryToCheck, strnlen(theDirectoryToCheck, PATH_MAX), memoryTable);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* real_path = my_realpath(theDirectoryToCheck, resolved_path);
|
||||
if (real_path)
|
||||
{
|
||||
my_printf("\nResolved path: %s\n", real_path);
|
||||
my_printf("\nCheck if home path: %s\n", loginData->homePath.text);
|
||||
my_printf("\nIs in resolved path: %s\n", real_path);
|
||||
|
||||
char* real_path_abs = my_realpath(loginData->homePath.text, resolved_path_abs);
|
||||
|
||||
//Check if the home path is still set
|
||||
if (is_prefix(real_path, real_path_abs))
|
||||
{
|
||||
my_printf("\nCheck ok");
|
||||
setDynamicStringDataType(safePath, real_path, strnlen(real_path, PATH_MAX), memoryTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_printfError("\nPath check error: %s check if is in: %s",loginData->homePath.text, real_path);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_printfError("\nRealpath error input %s", theDirectoryName);
|
||||
my_printfError("\ntheDirectoryToCheck error input %s", theDirectoryToCheck);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -238,10 +291,13 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
FILE_GetDirectoryInodeList(ftpData->clients[clientId].listPath.text, &fileList, &fileAndFoldersCount, 0, ftpData->clients[clientId].workerData.ftpCommand.commandOps.text, memoryTable);
|
||||
*filesNumber = fileAndFoldersCount;
|
||||
|
||||
returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n");
|
||||
if (returnCode <= 0)
|
||||
if (commandType != COMMAND_TYPE_STAT)
|
||||
{
|
||||
return -1;
|
||||
returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < fileAndFoldersCount; i++)
|
||||
@ -359,6 +415,35 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TYPE_STAT:
|
||||
{
|
||||
returnCode = socketPrintf(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;
|
||||
|
||||
default:
|
||||
{
|
||||
@ -776,6 +861,9 @@ int compareStringCaseInsensitive(char * stringIn, char * stringRef, int stringLe
|
||||
}
|
||||
}
|
||||
|
||||
if (stringIn[i] != '\0' &&stringIn[i] != ' ')
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
#define COMMAND_TYPE_LIST 0
|
||||
#define COMMAND_TYPE_NLST 1
|
||||
#define COMMAND_TYPE_STAT 2
|
||||
#define WRONG_PASSWORD_ALLOWED_RETRY_TIME 60
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -174,7 +174,7 @@ void *connectionWorkerHandle(void * socketId)
|
||||
else
|
||||
{
|
||||
returnCode = -1;
|
||||
my_printf("\nUnknown passive state, should be PASV or EPSV");
|
||||
my_printfError("\nUnknown passive state, should be PASV or EPSV");
|
||||
perror("Unknown passive state, should be PASV or EPSV");
|
||||
}
|
||||
|
||||
@ -653,7 +653,7 @@ void runFtpServer(void)
|
||||
if (ftpData.clients[processingSock].bufferIndex < 0)
|
||||
{
|
||||
//ftpData.clients[processingSock].closeTheClient = 1;
|
||||
my_printf("\n1 Errno = %d", errno);
|
||||
my_printfError("\n1 Errno = %d", errno);
|
||||
perror("1 Error: ");
|
||||
continue;
|
||||
}
|
||||
@ -845,7 +845,7 @@ static int processCommand(int processingElement)
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "STAT", strlen("STAT")) == 1)
|
||||
{
|
||||
//my_printf("\nSTAT COMMAND RECEIVED");
|
||||
my_printf("\nSTAT COMMAND RECEIVED");
|
||||
toReturn = parseCommandStat(&ftpData, processingElement);
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "CDUP", strlen("CDUP")) == 1 ||
|
||||
|
@ -363,13 +363,20 @@ int createSocket(ftpDataType * ftpData)
|
||||
int reuse = 1;
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("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");
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
}
|
||||
#endif
|
||||
//Bind socket
|
||||
errorCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp));
|
||||
@ -416,12 +423,18 @@ int createPassiveSocket(int port)
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("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");
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
//Bind socket
|
||||
@ -483,12 +496,18 @@ int createActiveSocket(int port, char *ipAddress)
|
||||
int reuse = 1;
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("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");
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ void report_error(const char *msg, const char *file, int line_no, int use_perror
|
||||
if(use_perror != 0)
|
||||
{
|
||||
perror(msg);
|
||||
my_printfError("perror");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -71,7 +71,6 @@ time_t convertToUTC(time_t inputTime)
|
||||
return utc_time;
|
||||
}
|
||||
|
||||
|
||||
int FILE_fdIsValid(int fd)
|
||||
{
|
||||
return fcntl(fd, F_GETFD);
|
||||
@ -89,7 +88,7 @@ int FILE_IsDirectory(char *DirectoryPath)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -600,7 +599,6 @@ int checkParentDirectoryPermissions(char *fileName, int uid, int gid)
|
||||
return checkUserFilePermissions(theFileName, uid, gid);
|
||||
}
|
||||
|
||||
|
||||
int checkUserFilePermissions(char *fileName, int uid, int gid)
|
||||
{
|
||||
|
||||
@ -690,7 +688,6 @@ char * FILE_GetGroupOwner(char *fileName, DYNMEM_MemoryTable_DataType **memoryTa
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
time_t FILE_GetLastModifiedData(char *path)
|
||||
{
|
||||
struct stat statbuf;
|
||||
@ -849,7 +846,6 @@ void FILE_checkAllOpenedFD(void)
|
||||
//my_printf("\n fd %d is dir", i);
|
||||
}
|
||||
|
||||
|
||||
openedFd++;
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +94,10 @@ SSL_CTX *createClientContext(void)
|
||||
if (ctx == NULL)
|
||||
{
|
||||
perror("Unable to create server SSL context");
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
exit(0);
|
||||
my_printfError("Unable to create server SSL context");
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
exit(0);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
@ -41,21 +41,23 @@ void signal_callback_handler(int signum)
|
||||
|
||||
static void ignore_sigpipe(void)
|
||||
{
|
||||
// ignore SIGPIPE (or else it will bring our program down if the client
|
||||
// closes its socket).
|
||||
// NB: if running under gdb, you might need to issue this gdb command:
|
||||
// handle SIGPIPE nostop noprint pass
|
||||
// because, by default, gdb will stop our program execution (which we
|
||||
// might not want).
|
||||
struct sigaction sa;
|
||||
// ignore SIGPIPE (or else it will bring our program down if the client
|
||||
// closes its socket).
|
||||
// NB: if running under gdb, you might need to issue this gdb command:
|
||||
// handle SIGPIPE nostop noprint pass
|
||||
// because, by default, gdb will stop our program execution (which we
|
||||
// might not want).
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
|
||||
if (sigemptyset(&sa.sa_mask) < 0 || sigaction(SIGPIPE, &sa, 0) < 0) {
|
||||
perror("Could not ignore the SIGPIPE signal");
|
||||
exit(0);
|
||||
}
|
||||
if (sigemptyset(&sa.sa_mask) < 0 || sigaction(SIGPIPE, &sa, 0) < 0)
|
||||
{
|
||||
perror("Could not ignore the SIGPIPE signal");
|
||||
my_printfError("Could not ignore the SIGPIPE signal");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void onUftpClose(int sig)
|
||||
|
Reference in New Issue
Block a user