mirror of
https://github.com/kingk85/uFTP.git
synced 2025-07-25 13:16:12 +03:00
Added log function
This commit is contained in:
@ -178,6 +178,12 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
|||||||
// my_printf("\n TOO MANY LOGIN FAILS! \n");
|
// my_printf("\n TOO MANY LOGIN FAILS! \n");
|
||||||
data->clients[socketId].closeTheClient = 1;
|
data->clients[socketId].closeTheClient = 1;
|
||||||
returnCode = socketPrintf(data, socketId, "s", "430 Too many login failure detected, your ip will be blacklisted for 5 minutes\r\n");
|
returnCode = socketPrintf(data, socketId, "s", "430 Too many login failure detected, your ip will be blacklisted for 5 minutes\r\n");
|
||||||
|
|
||||||
|
char *theLogString[STRING_SZ_LARGE];
|
||||||
|
memset(theLogString, 0, STRING_SZ_LARGE);
|
||||||
|
snprintf(theLogString, STRING_SZ_LARGE, "An ip %s has been blacklisted due too many password errors. ", element.ipAddress, data->clients[socketId].clientIpAddress);
|
||||||
|
addLog(theLogString, CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
{
|
{
|
||||||
addLog("socketPrintfError ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
addLog("socketPrintfError ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
@ -561,7 +567,8 @@ int parseCommandPasv(ftpDataType *data, int socketId)
|
|||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
{
|
{
|
||||||
my_printfError("\nError in pthread_create %d", returnCode);
|
my_printfError("\nError in pthread_create %d", returnCode);
|
||||||
addLog("Pthead Create error ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
exit(0);
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +603,8 @@ int parseCommandEpsv(ftpDataType *data, int socketId)
|
|||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
{
|
{
|
||||||
my_printfError("\nError in pthread_create %d", returnCode);
|
my_printfError("\nError in pthread_create %d", returnCode);
|
||||||
addLog("Pthead Create error ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
exit(0);
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +643,8 @@ int parseCommandPort(ftpDataType *data, int socketId)
|
|||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
{
|
{
|
||||||
my_printfError("\nError in pthread_create %d", returnCode);
|
my_printfError("\nError in pthread_create %d", returnCode);
|
||||||
addLog("Pthead Create error ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
exit(0);
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,8 +670,14 @@ void deleteListDataInfoVector(DYNV_VectorGenericDataType *theVector)
|
|||||||
void cancelWorker(ftpDataType *data, int clientId)
|
void cancelWorker(ftpDataType *data, int clientId)
|
||||||
{
|
{
|
||||||
void *pReturn;
|
void *pReturn;
|
||||||
|
addLog("Cancelling thread because is busy", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
int returnCode = pthread_cancel(data->clients[clientId].workerData.workerThread);
|
int returnCode = pthread_cancel(data->clients[clientId].workerData.workerThread);
|
||||||
|
if (returnCode != 0)
|
||||||
|
{
|
||||||
|
addLog("Cancelling thread ERROR", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
}
|
||||||
returnCode = pthread_join(data->clients[clientId].workerData.workerThread, &pReturn);
|
returnCode = pthread_join(data->clients[clientId].workerData.workerThread, &pReturn);
|
||||||
|
|
||||||
data->clients[clientId].workerData.threadHasBeenCreated = 0;
|
data->clients[clientId].workerData.threadHasBeenCreated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STRING_SZ_SMALL 100
|
#define STRING_SZ_SMALL 100
|
||||||
|
#define STRING_SZ_LARGE 4096
|
||||||
|
|
||||||
#define CLIENT_COMMAND_STRING_SIZE 4096
|
#define CLIENT_COMMAND_STRING_SIZE 4096
|
||||||
#define CLIENT_BUFFER_STRING_SIZE 4096
|
#define CLIENT_BUFFER_STRING_SIZE 4096
|
||||||
|
13
ftpServer.c
13
ftpServer.c
@ -122,6 +122,8 @@ void workerCleanup(void *socketId)
|
|||||||
void *connectionWorkerHandle(void * socketId)
|
void *connectionWorkerHandle(void * socketId)
|
||||||
{
|
{
|
||||||
int theSocketId = *(int *)socketId;
|
int theSocketId = *(int *)socketId;
|
||||||
|
// Enable cancellation for this thread
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
pthread_cleanup_push(workerCleanup, (void *) &theSocketId);
|
pthread_cleanup_push(workerCleanup, (void *) &theSocketId);
|
||||||
ftpData.clients[theSocketId].workerData.threadIsAlive = 1;
|
ftpData.clients[theSocketId].workerData.threadIsAlive = 1;
|
||||||
ftpData.clients[theSocketId].workerData.threadHasBeenCreated = 1;
|
ftpData.clients[theSocketId].workerData.threadHasBeenCreated = 1;
|
||||||
@ -538,7 +540,7 @@ void runFtpServer(void)
|
|||||||
respawnProcess();
|
respawnProcess();
|
||||||
|
|
||||||
//Init log
|
//Init log
|
||||||
logInit(ftpData.ftpParameters.logFolder);
|
logInit(ftpData.ftpParameters.logFolder, ftpData.ftpParameters.maximumLogFileCount);
|
||||||
|
|
||||||
//Socket main creator
|
//Socket main creator
|
||||||
ftpData.connectionData.theMainSocket = createSocket(&ftpData);
|
ftpData.connectionData.theMainSocket = createSocket(&ftpData);
|
||||||
@ -549,14 +551,14 @@ void runFtpServer(void)
|
|||||||
|
|
||||||
/* the maximum socket fd is now the main socket descriptor */
|
/* the maximum socket fd is now the main socket descriptor */
|
||||||
ftpData.connectionData.maxSocketFD = ftpData.connectionData.theMainSocket+1;
|
ftpData.connectionData.maxSocketFD = ftpData.connectionData.theMainSocket+1;
|
||||||
|
|
||||||
returnCode = pthread_create(&watchDogThread, NULL, watchDog, NULL);
|
returnCode = pthread_create(&watchDogThread, NULL, watchDog, NULL);
|
||||||
|
|
||||||
if(returnCode != 0)
|
if(returnCode != 0)
|
||||||
{
|
{
|
||||||
my_printf("pthread_create WatchDog Error %d", returnCode);
|
my_printf("pthread_create WatchDog Error %d", returnCode);
|
||||||
exit(0);
|
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
}
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
//Endless loop ftp process
|
//Endless loop ftp process
|
||||||
while (1)
|
while (1)
|
||||||
@ -565,7 +567,6 @@ void runFtpServer(void)
|
|||||||
//Update watchdog timer
|
//Update watchdog timer
|
||||||
updateWatchDogTime((int)time(NULL));
|
updateWatchDogTime((int)time(NULL));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
my_printf("\nUsed memory : %lld", DYNMEM_GetTotalMemory());
|
my_printf("\nUsed memory : %lld", DYNMEM_GetTotalMemory());
|
||||||
int memCount = 0;
|
int memCount = 0;
|
||||||
|
159
library/log.c
159
library/log.c
@ -4,15 +4,20 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "../debugHelper.h"
|
#include "../debugHelper.h"
|
||||||
#include "dynamicVectors.h"
|
#include "dynamicVectors.h"
|
||||||
#include "fileManagement.h"
|
#include "fileManagement.h"
|
||||||
|
|
||||||
|
#define LOG_LINE_SIZE 1024 + PATH_MAX
|
||||||
|
#define LOG_FILENAME_PREFIX "uftpLog_"
|
||||||
#define LOG_LINE_SIZE 1024 + PATH_MAX
|
|
||||||
|
|
||||||
static void logThread(void * arg);
|
static void logThread(void * arg);
|
||||||
|
|
||||||
@ -23,7 +28,136 @@ static sem_t logsem; // Semaphore for controlling log to write
|
|||||||
static pthread_t pLogThread;
|
static pthread_t pLogThread;
|
||||||
static pthread_mutex_t mutex;
|
static pthread_mutex_t mutex;
|
||||||
|
|
||||||
static char logFolder[PATH_MAX]; // Semaphore for controlling log to write
|
static int logFilesNumber;
|
||||||
|
|
||||||
|
static char logFolder[PATH_MAX];
|
||||||
|
|
||||||
|
#define MAX_FILENAME_LENGTH 256
|
||||||
|
|
||||||
|
|
||||||
|
static long long is_date_format(const char* str);
|
||||||
|
static int delete_old_logs(const char* folder_path, int days_to_keep);
|
||||||
|
|
||||||
|
static long long is_date_format(const char* str)
|
||||||
|
{
|
||||||
|
char year[5];
|
||||||
|
char month[3];
|
||||||
|
char day[3];
|
||||||
|
|
||||||
|
memset(year, 0, 5);
|
||||||
|
memset(month, 0, 3);
|
||||||
|
memset(day, 0, 3);
|
||||||
|
|
||||||
|
if (strlen(str) != 10 || str[4] != '-' || str[7] != '-')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for valid digits in year, month, and day components
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!isdigit(str[i])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
year[i] = str[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 5; i < 7; i++) {
|
||||||
|
if (!isdigit(str[i])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 8; i < 10; i++) {
|
||||||
|
if (!isdigit(str[i])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
month[0] = str[5];
|
||||||
|
month[1] = str[6];
|
||||||
|
|
||||||
|
day[0] = str[8];
|
||||||
|
day[1] = str[9];
|
||||||
|
|
||||||
|
return atoll(year)*365 + atoll(month)*31 + atoll(day);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int delete_old_logs(const char* folder_path, int days_to_keep)
|
||||||
|
{
|
||||||
|
unsigned long long n_of_day_file;
|
||||||
|
unsigned long long n_of_day_today;
|
||||||
|
|
||||||
|
struct stat statbuf;
|
||||||
|
DIR* dir;
|
||||||
|
struct dirent* entry;
|
||||||
|
char full_path[PATH_MAX];
|
||||||
|
|
||||||
|
dir = opendir(folder_path);
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
perror("opendir");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm *info = localtime(&now);
|
||||||
|
char timeToday[11];
|
||||||
|
if (strftime(timeToday, sizeof(timeToday), "%Y-%m-%d", info) == 0)
|
||||||
|
{
|
||||||
|
my_printfError("strftime error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_of_day_today = is_date_format(timeToday);
|
||||||
|
|
||||||
|
while ((entry = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||||
|
continue; // Skip . and .. entries
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(full_path, sizeof(full_path), "%s%s", folder_path, entry->d_name);
|
||||||
|
|
||||||
|
if (stat(full_path, &statbuf) == -1)
|
||||||
|
{
|
||||||
|
perror("stat");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISREG(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
continue; // Not a regular file
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(entry->d_name, LOG_FILENAME_PREFIX, strlen(LOG_FILENAME_PREFIX)) != 0)
|
||||||
|
{
|
||||||
|
continue; // Not a log file
|
||||||
|
}
|
||||||
|
|
||||||
|
n_of_day_file = is_date_format(entry->d_name + strlen(LOG_FILENAME_PREFIX));
|
||||||
|
|
||||||
|
if (!n_of_day_file)
|
||||||
|
{
|
||||||
|
continue; // Invalid date format
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_of_day_file+days_to_keep < n_of_day_today)
|
||||||
|
{
|
||||||
|
my_printf("\nRemoving old log file: %s", full_path);
|
||||||
|
|
||||||
|
// File is older than specified days
|
||||||
|
if (remove(full_path) == -1)
|
||||||
|
{
|
||||||
|
perror("remove");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// STATIC SECTION
|
// STATIC SECTION
|
||||||
static void logThread(void * arg)
|
static void logThread(void * arg)
|
||||||
@ -41,7 +175,7 @@ static void logThread(void * arg)
|
|||||||
|
|
||||||
memset(theLogFilename, 0, PATH_MAX);
|
memset(theLogFilename, 0, PATH_MAX);
|
||||||
|
|
||||||
if (strftime(logName, sizeof(logName), "uftpLog_%Y-%m-%d", info) == 0)
|
if (strftime(logName, sizeof(logName), LOG_FILENAME_PREFIX"%Y-%m-%d", info) == 0)
|
||||||
{
|
{
|
||||||
my_printfError("strftime error");
|
my_printfError("strftime error");
|
||||||
return;
|
return;
|
||||||
@ -81,11 +215,18 @@ static void logThread(void * arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int logInit(char * folder)
|
int logInit(char * folder, int numberOfLogFiles)
|
||||||
{
|
{
|
||||||
int returnCode;
|
int returnCode;
|
||||||
my_printf("\n Init logging system..");
|
my_printf("\n Init logging system..");
|
||||||
|
|
||||||
|
logFilesNumber = numberOfLogFiles;
|
||||||
|
|
||||||
|
delete_old_logs(folder, numberOfLogFiles);
|
||||||
|
|
||||||
|
if (logFilesNumber <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
DYNV_VectorString_Init(&logQueue);
|
DYNV_VectorString_Init(&logQueue);
|
||||||
DYNV_VectorString_Init(&workerQueue);
|
DYNV_VectorString_Init(&workerQueue);
|
||||||
|
|
||||||
@ -97,7 +238,8 @@ int logInit(char * folder)
|
|||||||
returnCode = pthread_create(&pLogThread, NULL, &logThread, NULL);
|
returnCode = pthread_create(&pLogThread, NULL, &logThread, NULL);
|
||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
{
|
{
|
||||||
my_printfError("Error while creating log thread.");
|
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
|
exit(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +256,9 @@ int logInit(char * folder)
|
|||||||
void addLog(char* logString, char * currFile, int currLine, char * currFunction)
|
void addLog(char* logString, char * currFile, int currLine, char * currFunction)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (logFilesNumber <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
char theLogString[LOG_LINE_SIZE];
|
char theLogString[LOG_LINE_SIZE];
|
||||||
char debugInfo[LOG_LINE_SIZE];
|
char debugInfo[LOG_LINE_SIZE];
|
||||||
memset(theLogString, 0, LOG_LINE_SIZE);
|
memset(theLogString, 0, LOG_LINE_SIZE);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#ifndef LOG_H
|
#ifndef LOG_H
|
||||||
#define LOG_H
|
#define LOG_H
|
||||||
|
|
||||||
int logInit(char * folder);
|
int logInit(char * folder, int numberOfLogFiles);
|
||||||
void addLog(char* logString, char * currFile, int currLine, char * currFunction);
|
void addLog(char* logString, char * currFile, int currLine, char * currFunction);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -16,6 +16,12 @@ SINGLE_INSTANCE = true
|
|||||||
#Run in background, daemon mode ok
|
#Run in background, daemon mode ok
|
||||||
DAEMON_MODE = true
|
DAEMON_MODE = true
|
||||||
|
|
||||||
|
# Folder where to save the logs, use the same format below, the folder must terminate with /
|
||||||
|
LOG_FOLDER = /var/log/
|
||||||
|
|
||||||
|
# Maximum number of logs to keep, if 0 log functionality is disabled
|
||||||
|
MAXIMUM_LOG_FILES = 0
|
||||||
|
|
||||||
# Idle timeout in seconds, client are disconnected for inactivity after the
|
# Idle timeout in seconds, client are disconnected for inactivity after the
|
||||||
# specified amount of time in seconds, set to 0 to disable
|
# specified amount of time in seconds, set to 0 to disable
|
||||||
IDLE_MAX_TIMEOUT = 3600
|
IDLE_MAX_TIMEOUT = 3600
|
||||||
|
Reference in New Issue
Block a user