Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- TOR_THREADS_METHOD *TORModFtp()
- {
- static TOR_THREADS_METHOD method = {
- "TORModFtp",
- (TOR_THREADS_INIT_PROC*) TORModFtpInit,
- (TOR_THREADS_DESTROY_PROC*) TORModFtpDestroy,
- (TOR_THREADS_ADD_PROC*) TORModFtpAdd,
- (TOR_THREADS_REMOVE_PROC*) TORModFtpRemove,
- (TOR_THREADS_MAIN_PROC*) TORModFtpMain
- };
- return &method;
- }
- TOR_ERROR WINAPI TORModFtpInit(TOR_MOD_FTP **lpModule, TOR_CONF *lpConf)
- {
- TOR_MOD_FTP *lpRet = NULL;
- TOR_CONF_SEC *lpSec;
- TOR_ERROR rError;
- __try {
- if ((rError = TOR_NEW(lpRet)) != ERROR_SUCCESS) {
- return rError;
- }
- if ((lpSec = TORConfGetSec(lpConf, "mod_ftp", NULL)) == NULL) {
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- lpRet->lpTrans = NULL;
- lpRet->dwCommandTimeout = atoi(TORConfGetVar(lpSec, "command_timeout", "300")) * 1000;
- lpRet->dwAcceptTimeout = atoi(TORConfGetVar(lpSec, "accept_timeout", "10")) * 1000;
- lpRet->dwTransTimeout = atoi(TORConfGetVar(lpSec, "trans_timeout", "300")) * 1000;
- if ((rError = TORTransInit(&lpRet->lpTrans, lpConf)) != ERROR_SUCCESS) {
- return rError;
- }
- TOR_RET_PTR(lpModule, lpRet);
- }
- __finally {
- TORModFtpDestroy(lpRet);
- }
- return ERROR_SUCCESS;
- }
- void WINAPI TORModFtpDestroy(TOR_MOD_FTP *lpModule)
- {
- if (lpModule != NULL) {
- if (lpModule->lpTrans != NULL) {
- TORTransDestroy(lpModule->lpTrans);
- }
- TOR_FREE(lpModule);
- }
- return;
- }
- TOR_ERROR WINAPI TORModFtpAdd(TOR_MOD_FTP *lpModule, TOR_MOD_FTP_INST **lpInst, TOR_THREADS_INST *lpThread, TOR_IO *lpIOSocket)
- {
- TOR_MOD_FTP_INST *lpRet = NULL;
- TOR_ERROR rError;
- __try {
- if ((rError = TOR_NEW(lpRet)) != ERROR_SUCCESS) {
- TORIODestroy(lpIOSocket);
- return rError;
- }
- lpRet->lpModule = lpModule;
- lpRet->lpThread = lpThread;
- lpRet->lpCtrlSck = lpIOSocket;
- lpRet->lpTransSck = NULL;
- lpRet->lpTransThread = NULL;
- lpRet->lpEvents = NULL;
- lpRet->lpFile = NULL;
- lpRet->lpFiles = NULL;
- lpRet->lpFSO = NULL;
- lpRet->szRenameFrom[0] = '\0';
- lpRet->qwRestOffset = 0;
- lpRet->bIsLoggedOn = FALSE;
- lpRet->szUser[0] = '\0';
- if (TORIOGetType(lpRet->lpCtrlSck) != TOR_IO_TYPE_SOCKET) {
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- TORSocketSetAbortEvent(
- TOR_IO_SOCKET(lpRet->lpCtrlSck),
- TORThreadsGetAbortEvent(lpRet->lpThread)
- );
- TORSocketSetTimeout(
- TOR_IO_SOCKET(lpRet->lpCtrlSck),
- TOR_SOCKET_TIMEOUT_RECV,
- lpRet->lpModule->dwCommandTimeout
- );
- rError = TORTransCreate(
- &lpRet->lpTransSck,
- lpRet->lpModule->lpTrans
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- TORPipeSetAbortEvent(
- TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
- TORThreadsGetAbortEvent(lpRet->lpThread)
- );
- TORPipeSetTimeout(
- TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
- TOR_PIPE_TIMEOUT_CREATE,
- lpRet->lpModule->dwAcceptTimeout
- );
- TORPipeSetTimeout(
- TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
- TOR_PIPE_TIMEOUT_WRITE,
- lpRet->lpModule->dwTransTimeout
- );
- TORPipeSetTimeout(
- TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
- TOR_PIPE_TIMEOUT_READ,
- lpRet->lpModule->dwTransTimeout
- );
- if ((rError = TORThreadInit(&lpRet->lpTransThread)) != ERROR_SUCCESS) {
- return rError;
- }
- rError = TOREventsInit(
- &lpRet->lpEvents,
- lpRet->lpModule->dwCommandTimeout
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- rError = TOREventsAdd(
- lpRet->lpEvents,
- TOR_MOD_FTP_EVENT_ABORT,
- TORThreadsGetAbortEvent(lpRet->lpThread)
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- rError = TOREventsAdd(
- lpRet->lpEvents,
- TOR_MOD_FTP_EVENT_CTRL_SCK,
- TORIOGetEvent(lpRet->lpCtrlSck)
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- rError = TOREventsAdd(
- lpRet->lpEvents,
- TOR_MOD_FTP_EVENT_TRANS_DONE,
- TORThreadGetFinishEvent(lpRet->lpTransThread)
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- rError = TORIOInit(
- &lpRet->lpFile,
- TORIOFile(),
- NULL,
- TOR_IO_OPT_DESTROY
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- if ((rError = TORFSOFilesInit(&lpRet->lpFiles)) != ERROR_SUCCESS) {
- return rError;
- }
- if ((rError = TORFSOInit(&lpRet->lpFSO)) != ERROR_SUCCESS) {
- return rError;
- }
- TOR_RET_PTR(lpInst, lpRet);
- }
- __finally {
- TORModFtpRemove(lpRet, rError);
- }
- return ERROR_SUCCESS;
- }
- void WINAPI TORModFtpRemove(TOR_MOD_FTP_INST *lpInst, TOR_ERROR rError)
- {
- if (lpInst != NULL) {
- TORModFtpTransStop(lpInst);
- if (lpInst->lpCtrlSck != NULL) {
- TORIODestroy(lpInst->lpCtrlSck);
- }
- if (lpInst->lpTransSck != NULL) {
- TORTransFree(lpInst->lpTransSck);
- }
- if (lpInst->lpTransThread != NULL) {
- TORThreadDestroy(lpInst->lpTransThread);
- }
- if (lpInst->lpEvents != NULL) {
- TOREventsDestroy(lpInst->lpEvents);
- }
- if (lpInst->lpFile != NULL) {
- TORIODestroy(lpInst->lpFile);
- }
- if (lpInst->lpFiles != NULL) {
- TORFSOFilesDestroy(lpInst->lpFiles);
- }
- if (lpInst->lpFSO != NULL) {
- TORFSODestroy(lpInst->lpFSO);
- }
- TOR_FREE(lpInst);
- }
- return;
- }
- TOR_ERROR WINAPI TORModFtpMain(TOR_MOD_FTP_INST *lpInst)
- {
- char *lpCmdLine;
- char szCmdLine[512];
- TOR_ERROR rError;
- DWORD dwLineLength;
- DWORD dwFactualLength;
- if ((rError = TORSocketBeginRecv(TOR_IO_SOCKET(lpInst->lpCtrlSck))) != ERROR_SUCCESS) {
- return rError;
- }
- rError = TORModFtpSend(
- lpInst,
- "220 Welcome to TORRCServer FTP Service!"
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- do {
- if ((rError = TOREventsWait(lpInst->lpEvents, INFINITE)) != ERROR_SUCCESS) {
- switch (rError) {
- case TOR_ERROR_OPERATION_TIMEOUT:
- TORModFtpSend(lpInst, "421 Connection timed out.");
- break;
- default:
- TORModFtpSend(lpInst, "500 Internal server error.");
- break;
- }
- return rError;
- }
- switch (TOREventsGetLastID(lpInst->lpEvents)) {
- case TOR_MOD_FTP_EVENT_ABORT:
- TORModFtpSend(lpInst, "500 Server shutdown.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_OPERATION_ABORTED);
- break;
- case TOR_MOD_FTP_EVENT_CTRL_SCK:
- rError = TORIOReadLine(
- lpInst->lpCtrlSck,
- szCmdLine,
- sizeof(szCmdLine),
- &dwLineLength,
- &dwFactualLength
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case TOR_ERROR_OPERATION_ABORTED:
- TORModFtpSend(lpInst, "500 Server shutdown.");
- break;
- case TOR_ERROR_OPERATION_TIMEOUT:
- TORModFtpSend(lpInst, "421 Connection timed out.");
- break;
- default:
- if (rError != TOR_ERROR_IO_END_OF_STREAM) {
- TORModFtpSend(lpInst, "500 Internal server error.");
- }
- break;
- }
- return rError;
- }
- if (dwFactualLength > dwLineLength) {
- TORModFtpSend(lpInst, "500 Command line too long.");
- }
- else {
- if (*(lpCmdLine = TORTrim(szCmdLine)) != '\0') {
- TORModFtpExecCmd(lpInst, lpCmdLine);
- }
- }
- break;
- case TOR_MOD_FTP_EVENT_TRANS_DONE:
- TORModFtpTransStop(lpInst);
- if (TORThreadGetResult(lpInst->lpTransThread) == ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "226 Transfer OK");
- }
- else {
- TORModFtpSend(lpInst, "426 Connection closed; transfer aborted.");
- }
- break;
- }
- } while (1);
- return ERROR_SUCCESS;
- }
- TOR_TRANS *TORModFtpGetTrans(TOR_MOD_FTP *lpModule)
- {
- return lpModule->lpTrans;
- }
- TOR_ERROR TORModFtpSendFmt(TOR_MOD_FTP_INST *lpInst, const char *lpFormat, ...)
- {
- va_list args;
- TOR_ERROR rError;
- __try {
- TORIOSetOpts(lpInst->lpCtrlSck, TOR_IO_OPT_WRITE_BUFFER);
- va_start(args, lpFormat);
- rError = TORVIOFormatStr(
- lpInst->lpCtrlSck,
- lpFormat,
- args
- );
- va_end(args);
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- if ((rError = TORIOPuts(lpInst->lpCtrlSck, "\r\n")) != ERROR_SUCCESS) {
- return rError;
- }
- if ((rError = TORIOFlush(lpInst->lpCtrlSck)) != ERROR_SUCCESS) {
- return rError;
- }
- }
- __finally {
- TORIOClearOpts(lpInst->lpCtrlSck, TOR_IO_OPT_WRITE_BUFFER);
- }
- return ERROR_SUCCESS;
- }
- TOR_ERROR TORModFtpSend(TOR_MOD_FTP_INST *lpInst, const char *lpResp)
- {
- return TORModFtpSendFmt(lpInst, "%s", lpResp);
- }
- TOR_ERROR TORModFtpExecCmd(TOR_MOD_FTP_INST *lpInst, char *lpCmdLine)
- {
- TOR_MOD_FTP_CMD *lpCmd;
- char *lpCmdArgs;
- char *lpCmdName;
- const char *lpErrStr;
- char szAbsolutePath[MAX_PATH];
- ULARGE_INTEGER ulFileSize;
- TOR_ERROR rError;
- DWORD i;
- DWORD dwAddr;
- WORD wPort;
- static TOR_MOD_FTP_CMD cmds[] = {
- {TOR_MOD_FTP_CMD_USER, "USER", TRUE, FALSE},
- {TOR_MOD_FTP_CMD_PASS, "PASS", FALSE, FALSE},
- {TOR_MOD_FTP_CMD_QUIT, "QUIT", FALSE, FALSE},
- {TOR_MOD_FTP_CMD_CWD, "CWD", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_PWD, "PWD", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_PORT, "PORT", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_PASV, "PASV", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_TYPE, "TYPE", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_LIST, "LIST", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_REST, "REST", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_CDUP, "CDUP", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_RETR, "RETR", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_STOR, "STOR", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_SIZE, "SIZE", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_DELE, "DELE", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_RMD, "RMD", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_MKD, "MKD", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_RNFR, "RNFR", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_RNTO, "RNTO", TRUE, TRUE},
- {TOR_MOD_FTP_CMD_ABOR, "ABOR", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_SYST, "SYST", FALSE, FALSE},
- {TOR_MOD_FTP_CMD_NOOP, "NOOP", FALSE, TRUE},
- {TOR_MOD_FTP_CMD_APPE, "APPE", TRUE, TRUE}
- };
- lpCmd = NULL;
- lpCmdArgs = lpCmdLine;
- lpCmdName = TORToken(&lpCmdArgs);
- for (i = 0; i < sizeof(cmds) / sizeof(TOR_MOD_FTP_CMD); i++) {
- if (stricmp(cmds[i].szCmdName, lpCmdName) == 0) {
- lpCmd = &cmds[i];
- }
- }
- if (lpCmd == NULL) {
- TORModFtpSend(lpInst, "500 Syntax error, command unrecognized.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- if (lpCmd->bRequireArgs && *lpCmdArgs == '\0') {
- TORModFtpSend(lpInst, "501 Syntax error.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- if (lpCmd->bRequireLogon && !lpInst->bIsLoggedOn) {
- TORModFtpSend(lpInst, "530 Please log in with USER and PASS first.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
- }
- switch (lpCmd->dwCmdID) {
- case TOR_MOD_FTP_CMD_USER:
- lpInst->bIsLoggedOn = FALSE;
- TORCopyStr(
- lpInst->szUser,
- lpCmdArgs,
- sizeof(lpInst->szUser)
- );
- TORModFtpSendFmt(lpInst, "331 Password required for %s", lpInst->szUser);
- break;
- case TOR_MOD_FTP_CMD_PASS:
- lpInst->bIsLoggedOn = TRUE;
- TORModFtpSend(lpInst, "230 Logged on");
- break;
- case TOR_MOD_FTP_CMD_QUIT:
- TORModFtpSend(lpInst, "221 Goodbye");
- TORThreadsExit(lpInst->lpThread, ERROR_SUCCESS);
- break;
- case TOR_MOD_FTP_CMD_CWD:
- rError = TORFSOSetCurrentDir(
- lpInst->lpFSO,
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_DIRECTORY:
- lpErrStr = "directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "access denied.";
- break;
- default:
- lpErrStr = "internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 CWD failed, %s", lpErrStr);
- return rError;
- }
- TORModFtpSendFmt(
- lpInst,
- "250 CWD successful. \"%s\" is current directory.",
- TORFSOGetCurrentDir(lpInst->lpFSO)
- );
- break;
- case TOR_MOD_FTP_CMD_PWD:
- TORModFtpSendFmt(
- lpInst,
- "257 \"%s\" is current directory.",
- TORFSOGetCurrentDir(lpInst->lpFSO)
- );
- break;
- case TOR_MOD_FTP_CMD_PORT:
- TORModFtpSend(lpInst, "500 Active mode not supported.");
- break;
- case TOR_MOD_FTP_CMD_PASV:
- TORModFtpTransStop(lpInst);
- if ((rError = TORTransBind(lpInst->lpTransSck)) != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "421 Can't create socket");
- return rError;
- }
- dwAddr = TORTransGetAddr(lpInst->lpTransSck);
- wPort = TORTransGetPort(lpInst->lpTransSck);
- TORModFtpSendFmt(
- lpInst,
- "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u)",
- *(((BYTE*) &dwAddr) + 3),
- *(((BYTE*) &dwAddr) + 2),
- *(((BYTE*) &dwAddr) + 1),
- *(((BYTE*) &dwAddr) + 0),
- *(((BYTE*) &wPort) + 1),
- *(((BYTE*) &wPort) + 0)
- );
- break;
- case TOR_MOD_FTP_CMD_TYPE:
- if (!(stricmp(lpCmdArgs, "I") == 0 || stricmp(lpCmdArgs, "A") == 0|| stricmp(lpCmdArgs, "L 8") == 0)) {
- TORModFtpSend(lpInst, "501 Unsupported type. Supported types are I, A and L 8");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- TORModFtpSendFmt(lpInst, "200 Type set to %s", lpCmdArgs);
- break;
- case TOR_MOD_FTP_CMD_LIST:
- if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "503 Bad sequence of commands.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- rError = TORFSOGetFiles(
- lpInst->lpFSO,
- lpInst->lpFiles,
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "Directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_DIRECTORY:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- TORModFtpTransStop(lpInst);
- return rError;
- }
- rError = TORModFtpTransStart(
- lpInst,
- (TOR_THREAD_PROC*) TORModFtpSendFileList
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "425 Can't open data connection.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- TORModFtpSend(lpInst, "150 Connection accepted");
- break;
- case TOR_MOD_FTP_CMD_REST:
- lpInst->qwRestOffset = 0;
- if (*TORTrim(lpCmdArgs) == '-' || sscanf(lpCmdArgs, "%I64u", &lpInst->qwRestOffset) != 1) {
- TORModFtpSend(lpInst, "501 Bad parameter. Numeric value required.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
- }
- TORModFtpSendFmt(lpInst, "350 Rest supported. Restarting at %llu", lpInst->qwRestOffset);
- break;
- case TOR_MOD_FTP_CMD_CDUP:
- rError = TORFSOSetCurrentDir(
- lpInst->lpFSO,
- ".."
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_DIRECTORY:
- lpErrStr = "directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "access denied.";
- break;
- default:
- lpErrStr = "internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 CDUP failed, %s", lpErrStr);
- return rError;
- }
- TORModFtpSendFmt(
- lpInst,
- "200 CDUP successful. \"%s\" is current directory.",
- TORFSOGetCurrentDir(lpInst->lpFSO)
- );
- break;
- case TOR_MOD_FTP_CMD_RETR:
- if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "503 Bad sequence of commands.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- rError = TORFSOOpenFile(
- lpInst->lpFSO,
- TOR_IO_FILE(lpInst->lpFile),
- lpCmdArgs,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- lpErrStr = "File not found.";
- break;
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- TORModFtpTransStop(lpInst);
- return rError;
- }
- if (lpInst->qwRestOffset != 0) {
- rError = TORFileSetPos(
- TOR_IO_FILE(lpInst->lpFile),
- lpInst->qwRestOffset,
- NULL,
- FILE_BEGIN
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSendFmt(lpInst, "550 Can't restore file position %llu", lpInst->qwRestOffset);
- TORModFtpTransStop(lpInst);
- return rError;
- }
- }
- rError = TORModFtpTransStart(
- lpInst,
- (TOR_THREAD_PROC*) TORModFtpSendFile
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "425 Can't open data connection.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- TORModFtpSend(lpInst, "150 Connection accepted");
- break;
- case TOR_MOD_FTP_CMD_STOR:
- case TOR_MOD_FTP_CMD_APPE:
- if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "503 Bad sequence of commands.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- rError = TORFSOOpenFile(
- lpInst->lpFSO,
- TOR_IO_FILE(lpInst->lpFile),
- lpCmdArgs,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- lpErrStr = "File not found.";
- break;
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- TORModFtpTransStop(lpInst);
- return rError;
- }
- if (lpCmd->dwCmdID == TOR_MOD_FTP_CMD_STOR) {
- if (lpInst->qwRestOffset != 0) {
- rError = TORFileSetPos(
- TOR_IO_FILE(lpInst->lpFile),
- lpInst->qwRestOffset,
- NULL,
- FILE_BEGIN
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSendFmt(lpInst, "550 Can't restore file position %llu", lpInst->qwRestOffset);
- TORModFtpTransStop(lpInst);
- return rError;
- }
- }
- if ((rError = TORFileSetEnd(TOR_IO_FILE(lpInst->lpFile))) != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "550 Can't truncate the file.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- }
- else {
- rError = TORFileSetPos(
- TOR_IO_FILE(lpInst->lpFile),
- 0,
- NULL,
- FILE_END
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "550 Can't set end of the file.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- }
- rError = TORModFtpTransStart(
- lpInst,
- (TOR_THREAD_PROC*) TORModFtpRecvFile
- );
- if (rError != ERROR_SUCCESS) {
- TORModFtpSend(lpInst, "425 Can't open data connection.");
- TORModFtpTransStop(lpInst);
- return rError;
- }
- TORModFtpSend(lpInst, "150 Connection accepted");
- break;
- case TOR_MOD_FTP_CMD_SIZE:
- rError = TORFSOGetFileSize(
- lpInst->lpFSO,
- lpCmdArgs,
- &ulFileSize
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- lpErrStr = "File not found.";
- break;
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- TORModFtpSendFmt(lpInst, "213 %llu", ulFileSize.QuadPart);
- break;
- case TOR_MOD_FTP_CMD_DELE:
- rError = TORFSODeleteFile(
- lpInst->lpFSO,
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- lpErrStr = "File not found.";
- break;
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- TORModFtpSend(lpInst, "250 File deleted successfully");
- break;
- case TOR_MOD_FTP_CMD_RMD:
- rError = TORFSORemoveDir(
- lpInst->lpFSO,
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "Directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_DIRECTORY:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- case ERROR_DIR_NOT_EMPTY:
- lpErrStr = "Directory not empty.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- TORModFtpSend(lpInst, "250 Directory deleted successfully");
- break;
- case TOR_MOD_FTP_CMD_MKD:
- rError = TORFSOCreateDir(
- lpInst->lpFSO,
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "Directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "Directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- case ERROR_ALREADY_EXISTS:
- lpErrStr = "Directory already exists.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- rError = TORFSOGetAbsolutePath(
- lpInst->lpFSO,
- szAbsolutePath,
- sizeof(szAbsolutePath),
- lpCmdArgs
- );
- if (rError != ERROR_SUCCESS) {
- szAbsolutePath[0] = '\0';
- }
- TORModFtpSendFmt(lpInst, "257 \"%s\" created successfully", szAbsolutePath);
- break;
- case TOR_MOD_FTP_CMD_RNFR:
- lpInst->szRenameFrom[0] = '\0';
- rError = TORFSOGetFileAttributes(
- lpInst->lpFSO,
- lpCmdArgs,
- &lpInst->dwFileAttributes
- );
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File or directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "File or directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- TORCopyStr(
- lpInst->szRenameFrom,
- lpCmdArgs,
- sizeof(lpInst->szRenameFrom)
- );
- if (lpInst->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- TORModFtpSend(lpInst, "350 Directory exists, ready for destination name.");
- }
- else {
- TORModFtpSend(lpInst, "350 File exists, ready for destination name.");
- }
- break;
- case TOR_MOD_FTP_CMD_RNTO:
- if (lpInst->szRenameFrom[0] == '\0') {
- TORModFtpSend(lpInst, "503 Bad sequence of commands.");
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
- }
- rError = TORFSOMoveFile(
- lpInst->lpFSO,
- lpInst->szRenameFrom,
- lpCmdArgs
- );
- lpInst->szRenameFrom[0] = '\0';
- if (rError != ERROR_SUCCESS) {
- switch (rError) {
- case ERROR_INVALID_NAME:
- lpErrStr = "File or directory name is incorrect.";
- break;
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- lpErrStr = "File or directory not found.";
- break;
- case ERROR_ACCESS_DENIED:
- lpErrStr = "Access denied.";
- break;
- case ERROR_ALREADY_EXISTS:
- lpErrStr = "File or directory already exists.";
- break;
- default:
- lpErrStr = "Internal server error.";
- break;
- }
- TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
- return rError;
- }
- if (lpInst->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- TORModFtpSend(lpInst, "250 Directory renamed successfully");
- }
- else {
- TORModFtpSend(lpInst, "250 File renamed successfully");
- }
- break;
- case TOR_MOD_FTP_CMD_SYST:
- TORModFtpSend(lpInst, "215 UNIX emulated by TORRCSvr");
- break;
- case TOR_MOD_FTP_CMD_NOOP:
- TORModFtpSend(lpInst, "200 OK");
- break;
- case TOR_MOD_FTP_CMD_ABOR:
- TORModFtpTransStop(lpInst);
- TORModFtpSend(lpInst, "226 ABOR command successful");
- break;
- }
- return ERROR_SUCCESS;
- }
- TOR_ERROR TORModFtpTransReady(TOR_MOD_FTP_INST *lpInst)
- {
- if (TORTransGetPort(lpInst->lpTransSck) == 0 || TORThreadGetThreadID(lpInst->lpTransThread) != 0) {
- return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
- }
- return ERROR_SUCCESS;
- }
- TOR_ERROR TORModFtpTransStart(TOR_MOD_FTP_INST *lpInst, TOR_THREAD_PROC *lpThreadFunc)
- {
- TOR_ERROR rError;
- lpInst->qwRestOffset = 0;
- if ((rError = TORTransAccept(lpInst->lpTransSck)) != ERROR_SUCCESS) {
- return rError;
- }
- TORPipeSetAbortEvent(
- TOR_IO_PIPE(TORTransGetIO(lpInst->lpTransSck)),
- TORThreadGetAbortEvent(lpInst->lpTransThread)
- );
- TOREventsSetTimeout(
- lpInst->lpEvents,
- INFINITE
- );
- rError = TORThreadCreate(
- lpInst->lpTransThread,
- lpThreadFunc,
- lpInst
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- return ERROR_SUCCESS;
- }
- void TORModFtpTransStop(TOR_MOD_FTP_INST *lpInst)
- {
- TORThreadStop(lpInst->lpTransThread);
- TORTransClose(lpInst->lpTransSck);
- TORFileClose(TOR_IO_FILE(lpInst->lpFile));
- TORPipeSetAbortEvent(
- TOR_IO_PIPE(TORTransGetIO(lpInst->lpTransSck)),
- TORThreadsGetAbortEvent(lpInst->lpThread)
- );
- TOREventsSetTimeout(
- lpInst->lpEvents,
- lpInst->lpModule->dwCommandTimeout
- );
- return;
- }
- TOR_ERROR WINAPI TORModFtpSendFileList(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
- {
- TOR_FSO_FILE *lpFile;
- TOR_FSO_FILE_INFO FileInfo;
- SYSTEMTIME stLocalTime;
- FILETIME ftLocalTime;
- FILETIME ftWriteTime;
- ULARGE_INTEGER t1;
- ULARGE_INTEGER t2;
- TOR_ERROR rError;
- const char months[][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- GetLocalTime(&stLocalTime);
- SystemTimeToFileTime(&stLocalTime, &ftLocalTime);
- t1.LowPart = ftLocalTime.dwLowDateTime;
- t1.HighPart = ftLocalTime.dwHighDateTime;
- lpFile = TORFSOFilesGetFirst(lpInst->lpFiles, &FileInfo);
- while (lpFile) {
- rError = TORIOFormatStr(
- TORTransGetIO(lpInst->lpTransSck),
- "%c--------- 1 ftp ftp % 14llu %s %02u ",
- FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 'd' : '-',
- FileInfo.ulFileSize.QuadPart,
- months[FileInfo.stLastWriteTime.wMonth - 1],
- FileInfo.stLastWriteTime.wDay
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- SystemTimeToFileTime(&FileInfo.stLastWriteTime, &ftWriteTime);
- t2.LowPart = ftWriteTime.dwLowDateTime;
- t2.HighPart = ftWriteTime.dwHighDateTime;
- if (t2.QuadPart > t1.QuadPart || (t1.QuadPart - t2.QuadPart) > ((ULONGLONG) 1000000 * 60 * 60 * 24 * 350)) {
- rError = TORIOFormatStr(
- TORTransGetIO(lpInst->lpTransSck),
- " %u ",
- FileInfo.stLastWriteTime.wYear
- );
- }
- else {
- rError = TORIOFormatStr(
- TORTransGetIO(lpInst->lpTransSck),
- "%02u:%02u ",
- FileInfo.stLastWriteTime.wHour,
- FileInfo.stLastWriteTime.wMinute
- );
- }
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- rError = TORIOFormatStr(
- TORTransGetIO(lpInst->lpTransSck),
- "%s\r\n",
- FileInfo.szFileName
- );
- if (rError != ERROR_SUCCESS) {
- return rError;
- }
- lpFile = TORFSOFilesGetNext(lpFile, &FileInfo);
- }
- return ERROR_SUCCESS;
- }
- TOR_ERROR WINAPI TORModFtpSendFile(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
- {
- return TORIOCopyTo(lpInst->lpFile, TORTransGetIO(lpInst->lpTransSck));
- }
- TOR_ERROR WINAPI TORModFtpRecvFile(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
- {
- return TORIOCopyTo(TORTransGetIO(lpInst->lpTransSck), lpInst->lpFile);
- }
Add Comment
Please, Sign In to add comment