mirror of
https://github.com/kingk85/uFTP.git
synced 2025-04-20 00:18:57 +03:00
LIST and NLIST support -a and -A parameters
This commit is contained in:
@ -61,7 +61,7 @@ int parseCommandUser(ftpDataType * data, int socketId)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(theUserName) >= 1)
|
||||
if (strnlen(theUserName, 1) >= 1)
|
||||
{
|
||||
setDynamicStringDataType(&data->clients[socketId].login.name, theUserName, strlen(theUserName), &data->clients[socketId].memoryTable);
|
||||
returnCode = socketPrintf(data, socketId, "s", "331 User ok, Waiting for the password.\r\n");
|
||||
@ -91,37 +91,38 @@ int parseCommandSite(ftpDataType *data, int socketId)
|
||||
|
||||
switch (setPermissionsReturnCode)
|
||||
{
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_OK:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "200 Permissions changed\r\n");
|
||||
}
|
||||
break;
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_OK:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "200 Permissions changed\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_NO_FILE:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 chmod no such file\r\n");
|
||||
}
|
||||
break;
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_NO_FILE:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 chmod no such file\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_NO_PERMISSIONS:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Some errors occurred while changing file permissions.\r\n");
|
||||
}
|
||||
break;
|
||||
case FTP_CHMODE_COMMAND_RETURN_CODE_NO_PERMISSIONS:
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Some errors occurred while changing file permissions.\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG:
|
||||
default:
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
case FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG:
|
||||
default:
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "500 unknown extension\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -156,7 +157,7 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(thePass) >= 1)
|
||||
if (strnlen(thePass, 1) >= 1)
|
||||
{
|
||||
|
||||
// my_printf("\nLogin try with user %s, password %s", data->clients[socketId].login.name.text, thePass);
|
||||
@ -217,6 +218,7 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
||||
my_printf("\ndata->clients[socketId].login.ownerShip.uid = %d", data->clients[socketId].login.ownerShip.uid);
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "s", "230 Login Ok.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
@ -239,6 +241,7 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
||||
}
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "s", "430 Invalid username or password\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
return 1;
|
||||
@ -251,6 +254,7 @@ int parseCommandAuth(ftpDataType *data, int socketId)
|
||||
|
||||
#ifndef OPENSSL_ENABLED
|
||||
returnCode = socketPrintf(data, socketId, "s", "502 Security extensions not implemented.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
#endif
|
||||
@ -258,6 +262,7 @@ int parseCommandAuth(ftpDataType *data, int socketId)
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "s", "234 AUTH TLS OK..\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
@ -304,6 +309,7 @@ int parseCommandSyst(ftpDataType *data, int socketId)
|
||||
{
|
||||
int returnCode;
|
||||
returnCode = socketPrintf(data, socketId, "s", "215 UNIX Type: L8\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
@ -328,6 +334,7 @@ int parseCommandFeat(ftpDataType *data, int socketId)
|
||||
#ifndef OPENSSL_ENABLED
|
||||
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nEPSV\r\nUTF8\r\nSIZE\r\nMDTM\r\nREST\r\n211 End.\r\n");
|
||||
#endif
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
@ -396,6 +403,7 @@ int parseCommandPbsz(ftpDataType *data, int socketId)
|
||||
thePbszSize = getFtpCommandArg("PBSZ", data->clients[socketId].theCommandReceived, 0);
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "sss", "200 PBSZ set to ", thePbszSize, "\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
@ -588,20 +596,9 @@ int parseCommandAbor(ftpDataType *data, int socketId)
|
||||
int parseCommandList(ftpDataType *data, int socketId)
|
||||
{
|
||||
/*
|
||||
-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
|
||||
|
||||
*/
|
||||
|
||||
int isSafePath = 0;
|
||||
@ -611,23 +608,29 @@ int parseCommandList(ftpDataType *data, int socketId)
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\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);
|
||||
// if (data->clients[socketId].workerData.ftpCommand.commandOps.text != NULL)
|
||||
// my_printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||
// my_printf("\ntheNameToList: %s", theNameToList);
|
||||
|
||||
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);
|
||||
if (data->clients[socketId].workerData.ftpCommand.commandArgs.text != NULL)
|
||||
my_printf("\nLIST 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);
|
||||
|
||||
|
||||
cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable);
|
||||
|
||||
if (strlen(theNameToList) > 0)
|
||||
if (strnlen(theNameToList, 1) > 0)
|
||||
{
|
||||
isSafePath = getSafePath(&data->clients[socketId].listPath, theNameToList, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
@ -644,6 +647,10 @@ int parseCommandList(ftpDataType *data, int socketId)
|
||||
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");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -652,6 +659,10 @@ int parseCommandList(ftpDataType *data, int socketId)
|
||||
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 no permissions.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -675,17 +686,24 @@ int parseCommandNlst(ftpDataType *data, int socketId)
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\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);
|
||||
|
||||
theNameToNlist = getFtpCommandArg("NLIST", data->clients[socketId].theCommandReceived, 1);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable);
|
||||
|
||||
// my_printf("\nNLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
||||
// my_printf("\nNLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||
// my_printf("\ntheNameToNlist: %s", theNameToNlist);
|
||||
my_printf("\nNLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
||||
my_printf("\nNLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||
my_printf("\ntheNameToNlist: %s", theNameToNlist);
|
||||
|
||||
if (strlen(theNameToNlist) > 0)
|
||||
if (strnlen(theNameToNlist,1) > 0)
|
||||
{
|
||||
isSafePath = getSafePath(&data->clients[socketId].listPath, theNameToNlist, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
@ -701,6 +719,10 @@ int parseCommandNlst(ftpDataType *data, int socketId)
|
||||
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");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -709,6 +731,11 @@ int parseCommandNlst(ftpDataType *data, int socketId)
|
||||
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 no permissions.\r\n");
|
||||
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -732,13 +759,18 @@ int parseCommandRetr(ftpDataType *data, int socketId)
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n");
|
||||
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
theNameToRetr = getFtpCommandArg("RETR", data->clients[socketId].theCommandReceived, 0);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].fileToRetr, 0, &data->clients[socketId].memoryTable);
|
||||
|
||||
if (strlen(theNameToRetr) > 0)
|
||||
if (strnlen(theNameToRetr, 1) > 0)
|
||||
{
|
||||
isSafePath = getSafePath(&data->clients[socketId].fileToRetr, theNameToRetr, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
@ -746,6 +778,17 @@ int parseCommandRetr(ftpDataType *data, int socketId)
|
||||
if (isSafePath == 1 &&
|
||||
FILE_IsFile(data->clients[socketId].fileToRetr.text) == 1)
|
||||
{
|
||||
|
||||
if ((checkUserFilePermissions(data->clients[socketId].fileToRetr.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R)
|
||||
{
|
||||
int writeReturn = socketPrintf(data, socketId, "s", "550 no reading permission on the file\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&data->clients[socketId].conditionMutex);
|
||||
|
||||
memset(data->clients[socketId].workerData.theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1);
|
||||
@ -759,6 +802,10 @@ int parseCommandRetr(ftpDataType *data, int socketId)
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Failed to open file.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -774,20 +821,32 @@ int parseCommandStor(ftpDataType *data, int socketId)
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n");
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
theNameToStor = getFtpCommandArg("STOR", data->clients[socketId].theCommandReceived, 0);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].fileToStor, 0, &data->clients[socketId].memoryTable);
|
||||
|
||||
if (strlen(theNameToStor) > 0)
|
||||
if (strnlen(theNameToStor, 1) > 0)
|
||||
{
|
||||
isSafePath = getSafePath(&data->clients[socketId].fileToStor, theNameToStor, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
|
||||
if (isSafePath == 1)
|
||||
{
|
||||
if ((checkParentDirectoryPermissions(data->clients[socketId].fileToStor.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 No permissions to write the file\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
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);
|
||||
@ -798,6 +857,11 @@ int parseCommandStor(ftpDataType *data, int socketId)
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n");
|
||||
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -813,19 +877,35 @@ int parseCommandAppe(ftpDataType *data, int socketId)
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n");
|
||||
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
theNameToStor = getFtpCommandArg("APPE", data->clients[socketId].theCommandReceived, 0);
|
||||
cleanDynamicStringDataType(&data->clients[socketId].fileToStor, 0, &data->clients[socketId].memoryTable);
|
||||
|
||||
if (strlen(theNameToStor) > 0)
|
||||
if (strnlen(theNameToStor, 1) > 0)
|
||||
{
|
||||
isSafePath = getSafePath(&data->clients[socketId].fileToStor, theNameToStor, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
|
||||
if (isSafePath == 1)
|
||||
{
|
||||
|
||||
if ((checkParentDirectoryPermissions(data->clients[socketId].fileToStor.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 No permissions to write the file\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
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);
|
||||
@ -836,6 +916,10 @@ int parseCommandAppe(ftpDataType *data, int socketId)
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -857,7 +941,7 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
|
||||
//my_printf("\ncdw requested path: %s", thePath);
|
||||
|
||||
if (strlen(thePath) > 0)
|
||||
if (strnlen(thePath, 1) > 0)
|
||||
{
|
||||
// my_printf("Memory data address 1st call : %lld", &data->clients[socketId].memoryTable);
|
||||
isSafePath = getSafePath(&theSafePath, thePath, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
|
||||
@ -902,10 +986,17 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
if ((checkUserFilePermissions(data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_R) == FILE_PERMISSION_R)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "sss", "250 OK. Current directory is ", data->clients[socketId].login.ftpPath.text, "\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": no permissions\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
setDynamicStringDataType(&data->clients[socketId].login.absolutePath, absolutePathPrevious.text, absolutePathPrevious.textLen, &data->clients[socketId].memoryTable);
|
||||
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, ftpPathPrevious.text, ftpPathPrevious.textLen, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
@ -913,6 +1004,10 @@ 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");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
setDynamicStringDataType(&data->clients[socketId].login.absolutePath, absolutePathPrevious.text, absolutePathPrevious.textLen, &data->clients[socketId].memoryTable);
|
||||
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, ftpPathPrevious.text, ftpPathPrevious.textLen, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
@ -932,6 +1027,10 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
cleanDynamicStringDataType(&ftpPathPrevious, 0, &data->clients[socketId].memoryTable);
|
||||
cleanDynamicStringDataType(&theSafePath, 0, &data->clients[socketId].memoryTable);
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
}
|
||||
@ -1050,6 +1149,9 @@ int parseCommandMkd(ftpDataType *data, int socketId)
|
||||
{
|
||||
cleanDynamicStringDataType(&mkdFileName, 0, &data->clients[socketId].memoryTable);
|
||||
returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
functionReturnCode = FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
@ -1449,6 +1551,19 @@ int parseCommandCdup(ftpDataType *data, int socketId)
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
int parseCommandAcct(ftpDataType *data, int socketId)
|
||||
{
|
||||
int returnCode;
|
||||
|
||||
returnCode = socketPrintf(data, socketId, "s", "502 ACCT not implemented.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
long long int writeRetrFile(ftpDataType *data, int theSocketId, long long int startFrom, FILE *retrFP)
|
||||
{
|
||||
long long int readen = 0;
|
||||
|
@ -88,6 +88,8 @@ int parseCommandMdtm(ftpDataType * data, int socketId);
|
||||
int parseCommandOpts(ftpDataType * data, int socketId);
|
||||
int parseCommandRnfr(ftpDataType * data, int socketId);
|
||||
int parseCommandRnto(ftpDataType * data, int socketId);
|
||||
int parseCommandAcct(ftpDataType * data, int socketId);
|
||||
|
||||
|
||||
long long int writeRetrFile(ftpDataType * data, int theSocketId, long long int startFrom, FILE *retrFP);
|
||||
char *getFtpCommandArg(char * theCommand, char *theCommandString, int skipArgs);
|
||||
|
17
ftpData.c
17
ftpData.c
@ -225,13 +225,17 @@ void setRandomicPort(ftpDataType *data, int socketPosition)
|
||||
|
||||
int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumber, int commandType, DYNMEM_MemoryTable_DataType **memoryTable)
|
||||
{
|
||||
|
||||
|
||||
// a --> include . and ..
|
||||
// A --> do not include . and ..
|
||||
// nothing --> no hidden no . and no ..
|
||||
my_printf("\nFILE_GetDirectoryInodeList arg path: %s", ftpData->clients[clientId].listPath.text);
|
||||
my_printf("\nftpData->clients[clientId].workerData.ftpCommand.commandArgs: %s", ftpData->clients[clientId].workerData.ftpCommand.commandArgs.text);
|
||||
my_printf("\nftpData->clients[clientId].workerData.ftpCommand.commandOps: %s", ftpData->clients[clientId].workerData.ftpCommand.commandOps.text);
|
||||
|
||||
int i, x, returnCode;
|
||||
int fileAndFoldersCount = 0;
|
||||
char **fileList = NULL;
|
||||
FILE_GetDirectoryInodeList(ftpData->clients[clientId].listPath.text, &fileList, &fileAndFoldersCount, 0, memoryTable);
|
||||
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");
|
||||
@ -279,8 +283,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
//my_printf("\nNot a directory, not a file, broken link");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//my_printf("\nFILE SIZE : %lld", data.fileSize);
|
||||
|
||||
data.owner = FILE_GetOwner(fileList[i], memoryTable);
|
||||
@ -428,7 +431,7 @@ void getListDataInfo(char * thePath, DYNV_VectorGenericDataType *directoryInfo,
|
||||
int i;
|
||||
int fileAndFoldersCount = 0;
|
||||
ftpListDataType data;
|
||||
FILE_GetDirectoryInodeList(thePath, &data.fileList, &fileAndFoldersCount, 0, memoryTable);
|
||||
FILE_GetDirectoryInodeList(thePath, &data.fileList, &fileAndFoldersCount, 0, "Z", memoryTable);
|
||||
|
||||
//my_printf("\nNUMBER OF FILES: %d", fileAndFoldersCount);
|
||||
//fflush(0);
|
||||
@ -533,7 +536,6 @@ void getListDataInfo(char * thePath, DYNV_VectorGenericDataType *directoryInfo,
|
||||
|
||||
void deleteListDataInfoVector(DYNV_VectorGenericDataType *theVector)
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i = 0; i < theVector->Size; i++)
|
||||
{
|
||||
@ -576,7 +578,6 @@ void cancelWorker(ftpDataType *data, int clientId)
|
||||
|
||||
void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
|
||||
{
|
||||
|
||||
my_printf("\nReset of worker id: %d", clientId);
|
||||
data->clients[clientId].workerData.connectionPort = 0;
|
||||
data->clients[clientId].workerData.passiveModeOn = 0;
|
||||
|
52
ftpServer.c
52
ftpServer.c
@ -289,39 +289,18 @@ void *connectionWorkerHandle(void * socketId)
|
||||
my_printf("\nWorker %d is waiting for commands!", theSocketId);
|
||||
//Conditional lock on tconditionVariablehread actions
|
||||
pthread_mutex_lock(&ftpData.clients[theSocketId].conditionMutex);
|
||||
//int sleepTime = 1000;
|
||||
while (ftpData.clients[theSocketId].workerData.commandReceived == 0)
|
||||
{
|
||||
//usleep(sleepTime);
|
||||
//if (sleepTime < 200000)
|
||||
//{
|
||||
//sleepTime+= 1000;
|
||||
//}
|
||||
pthread_cond_wait(&ftpData.clients[theSocketId].conditionVariable, &ftpData.clients[theSocketId].conditionMutex);
|
||||
}
|
||||
pthread_mutex_unlock(&ftpData.clients[theSocketId].conditionMutex);
|
||||
|
||||
//my_printf("\nWorker %d unlocked", theSocketId);
|
||||
|
||||
if (ftpData.clients[theSocketId].workerData.commandReceived == 1 &&
|
||||
(compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "STOR", strlen("STOR")) == 1 || compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "APPE", strlen("APPE")) == 1) &&
|
||||
ftpData.clients[theSocketId].fileToStor.textLen > 0)
|
||||
{
|
||||
|
||||
if ((checkParentDirectoryPermissions(ftpData.clients[theSocketId].fileToStor.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W)
|
||||
{
|
||||
returnCode = socketPrintf(&ftpData, theSocketId, "s", "550 No permissions to write the file\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||
my_printf("\n Closing the client 6");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "APPE", strlen("APPE")) == 1)
|
||||
{
|
||||
#ifdef LARGE_FILE_SUPPORT_ENABLED
|
||||
@ -438,18 +417,6 @@ void *connectionWorkerHandle(void * socketId)
|
||||
else if (compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "NLST", strlen("NLST")) == 1)
|
||||
theCommandType = COMMAND_TYPE_NLST;
|
||||
|
||||
if ((checkUserFilePermissions(ftpData.clients[theSocketId].listPath.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R)
|
||||
{
|
||||
returnCode = socketPrintf(&ftpData, theSocketId, "s", "550 No permissions\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||
my_printf("\n Closing the client 8");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
returnCode = socketPrintf(&ftpData, theSocketId, "s", "150 Accepted data connection\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
@ -458,7 +425,6 @@ void *connectionWorkerHandle(void * socketId)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
//returnCode = writeListDataInfoToSocket(ftpData.clients[theSocketId].listPath.text, ftpData.clients[theSocketId].workerData.socketConnection, &theFiles, theCommandType);
|
||||
returnCode = writeListDataInfoToSocket(&ftpData, theSocketId, &theFiles, theCommandType, &ftpData.clients[theSocketId].workerData.memoryTable);
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
@ -489,19 +455,6 @@ void *connectionWorkerHandle(void * socketId)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
if ((checkUserFilePermissions(ftpData.clients[theSocketId].fileToRetr.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R)
|
||||
{
|
||||
writeReturn = socketPrintf(&ftpData, theSocketId, "s", "550 no reading permission on the file\r\n");
|
||||
if (writeReturn <= 0)
|
||||
{
|
||||
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||
my_printf("\n Closing the client 12");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
writenSize = writeRetrFile(&ftpData, theSocketId, ftpData.clients[theSocketId].workerData.retrRestartAtByte, ftpData.clients[theSocketId].workerData.theStorFile);
|
||||
ftpData.clients[theSocketId].workerData.retrRestartAtByte = 0;
|
||||
|
||||
@ -985,6 +938,11 @@ static int processCommand(int processingElement)
|
||||
//my_printf("\nNOOP command received");
|
||||
toReturn = parseCommandNoop(&ftpData, processingElement);
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "ACCT", strlen("ACCT")) == 1)
|
||||
{
|
||||
//my_printf("\nNOOP command received");
|
||||
toReturn = parseCommandAcct(&ftpData, processingElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
; //Parse unsupported command not needed
|
||||
|
@ -73,7 +73,7 @@ int isProcessAlreadyRunning(void)
|
||||
//my_printf("\nFILE_LockFile returnCode = %d", returnCode);
|
||||
ftruncate(fd, 0);
|
||||
returnCode = snprintf(buf, 100, "%ld", (long)getpid());
|
||||
returnCode = write(fd, buf, strlen(buf)+1);
|
||||
returnCode = write(fd, buf, strnlen(buf, 100)+1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -202,41 +202,42 @@ int FILE_IsFile(const char *TheFileName)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * FilesandFolders, int Recursive, DYNMEM_MemoryTable_DataType ** memoryTable)
|
||||
void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * FilesandFolders, int Recursive, char * commandOps, DYNMEM_MemoryTable_DataType ** memoryTable)
|
||||
{
|
||||
int FileAndFolderIndex = *FilesandFolders;
|
||||
my_printf("\nLIST DETAILS OF: %s", DirectoryInodeName);
|
||||
my_printf("\ncommandOps: %s", commandOps);
|
||||
|
||||
//Allocate the array for the 1st time
|
||||
if (*InodeList == NULL)
|
||||
{
|
||||
(*InodeList) = (char **) DYNMEM_malloc(sizeof(char *), memoryTable, "InodeList");
|
||||
}
|
||||
|
||||
|
||||
if (FILE_IsDirectory(DirectoryInodeName))
|
||||
{
|
||||
|
||||
|
||||
DIR *TheDirectory;
|
||||
struct dirent *dir;
|
||||
TheDirectory = opendir(DirectoryInodeName);
|
||||
if (TheDirectory)
|
||||
{
|
||||
|
||||
|
||||
while ((dir = readdir(TheDirectory)) != NULL)
|
||||
{
|
||||
if ( dir->d_name[0] == '.' && strlen(dir->d_name) == 1)
|
||||
|
||||
if ( dir->d_name[0] == '.' && strnlen(dir->d_name, 2) == 1)
|
||||
continue;
|
||||
|
||||
if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strlen(dir->d_name) == 2)
|
||||
if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strnlen(dir->d_name, 3) == 2)
|
||||
continue;
|
||||
|
||||
//Skips all files and dir starting with .
|
||||
if ((dir->d_name[0] == '.' && commandOps == NULL) || (dir->d_name[0] == '.' && commandOps[0] != 'a' && commandOps[0] != 'A'))
|
||||
continue;
|
||||
|
||||
//Set the row to needed size
|
||||
int ReallocSize = sizeof(char *) * (FileAndFolderIndex+1)+1;
|
||||
(*InodeList) = (char ** ) DYNMEM_realloc((*InodeList), ReallocSize, memoryTable);
|
||||
size_t nsize = strlen(dir->d_name) * sizeof(char) + strlen(DirectoryInodeName) * sizeof(char) + 2;
|
||||
size_t nsize = strnlen(dir->d_name, 256) * sizeof(char) + strlen(DirectoryInodeName) * sizeof(char) + 2;
|
||||
//Allocate the path string size
|
||||
(*InodeList)[FileAndFolderIndex] = (char *) DYNMEM_malloc (nsize , memoryTable, "InodeList");
|
||||
strcpy((*InodeList)[FileAndFolderIndex], DirectoryInodeName );
|
||||
@ -248,7 +249,7 @@ void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, i
|
||||
|
||||
if ( Recursive == 1 && FILE_IsDirectory((*InodeList)[*FilesandFolders-1]) == 1 )
|
||||
{
|
||||
FILE_GetDirectoryInodeList ( (*InodeList)[FileAndFolderIndex-1], InodeList, FilesandFolders, Recursive, memoryTable);
|
||||
FILE_GetDirectoryInodeList ( (*InodeList)[FileAndFolderIndex-1], InodeList, FilesandFolders, Recursive, "Z", memoryTable);
|
||||
FileAndFolderIndex = (*FilesandFolders);
|
||||
}
|
||||
|
||||
@ -291,10 +292,10 @@ int FILE_GetDirectoryInodeCount(char * DirectoryInodeName)
|
||||
{
|
||||
while ((dir = readdir(TheDirectory)) != NULL)
|
||||
{
|
||||
if ( dir->d_name[0] == '.' && strlen(dir->d_name) == 1)
|
||||
if ( dir->d_name[0] == '.' && strnlen(dir->d_name, 2) == 1)
|
||||
continue;
|
||||
|
||||
if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strlen(dir->d_name) == 2)
|
||||
if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strnlen(dir->d_name, 3) == 2)
|
||||
continue;
|
||||
|
||||
FileAndFolderIndex++;
|
||||
|
@ -60,7 +60,7 @@
|
||||
long long int FILE_GetFileSizeFromPath(char *TheFileName);
|
||||
int FILE_IsFile(const char *theFileName);
|
||||
int FILE_IsDirectory (char *directory_path);
|
||||
void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * filesandfolders, int recursive, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * filesandfolders, int recursive, char* commandOps, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
int FILE_GetDirectoryInodeCount(char * DirectoryInodeName);
|
||||
int FILE_GetStringFromFile(char * filename, char **file_content, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
void FILE_ReadStringParameters(char * filename, DYNV_VectorGenericDataType *ParametersVector);
|
||||
|
Reference in New Issue
Block a user