Subversion Repositories ps2ware

Compare Revisions

Ignore whitespace Rev 311 → Rev 312

/trunk/ps2ftpd/README
54,27 → 54,55
The server understands the following commands:
 
USER <name>
Login using <name> (or 'anonymous' if anonymous logins are allowed)
PASS <password>
Send <pass> as password for account.
PASV
Enter passive transfer-mode.
PORT <ipA>,<ipB>,<ipC>,<ipD>,<pH>,<pL>
Enter active transfer-mode. (ipA.ipB.ipC.ipD:pH*256+pL)
QUIT
Quit session.
SYST
Request system information.
LIST <path>
Request directory listing.
NLST <path>
Request name list.
RETR <file>
TYPE A/I
Retrieve data in <file>. Affected by REST.
TYPE <type>
Set transfer-type, only A & I allowed currently.
MODE <mode>
Set transfer-mode. Only S(Stream) allowed.
STRU <structure>
Set transfer-structure. Only F(File) allowed.
STOR <file>
Save data to <file>. Affected by REST.
APPE <file>
Append data to <file>. Not affected by REST.
PWD
XPWD
Query current path.
XCWD
CWD <dir>
Change current directory.
CDUP
Go to parent directory.
DELE <file>
Unlink <file> from filesystem.
XMKD <dir>
MKD <dir>
Create directory.
XRMD <dir>
RMD <dir>
Delete directory.
SITE <action>
Perform site-specific action. See list below.
NOOP
No operation.
REST <marker>
Set restart-marker (for resuming transfers)
 
The supported site-commands are:
 
85,9 → 113,6
SITE SYNC <device>
Synchronize device. Example: SITE SYNC /pfs/0
 
Authentication is ignored, so be cautious if your PS2 is connected directly
to the internet.
 
The filesystem is unified, so you will find the first memory-card at
'/mc/0/', and a mounted hdd partition at for example '/pfs/0/'. The device
list show all devices present, but you may not access them all depending
/trunk/ps2ftpd/src/FileSystem.c
64,7 → 64,7
FileSystem_Close(pContext);
}
 
int FileSystem_OpenFile( FSContext* pContext, const char* pFile, FileMode eMode )
int FileSystem_OpenFile( FSContext* pContext, const char* pFile, FileMode eMode, int iContinue )
{
int flags;
 
74,9 → 74,8
switch( eMode )
{
case FM_READ: flags = O_RDONLY; break;
case FM_CREATE: flags = O_CREAT|O_TRUNC|O_WRONLY; break;
case FM_WRITE: flags = O_CREAT|O_TRUNC|O_WRONLY; break;
 
case FM_APPEND: // TODO: implement
default:
return -1;
}
94,9 → 93,43
{
case FS_IODEVICE:
{
if( !pContext->m_kFile.device )
break;
if( iContinue )
{
int iOpened = 0;
 
if( flags & O_WRONLY )
{
pContext->m_kFile.mode = O_WRONLY;
if( pContext->m_kFile.device->ops->open( &(pContext->m_kFile), pFile, pContext->m_kFile.mode, 0 ) >= 0 )
iOpened = 1;
}
else
{
pContext->m_kFile.mode = O_RDONLY;
if( pContext->m_kFile.device->ops->open( &(pContext->m_kFile), pFile, pContext->m_kFile.mode, 0 ) >= 0 )
iOpened = 1;
}
 
// seek to position if we successfully opened the file
 
if( iOpened )
{
if( iContinue < 0 )
{
if( pContext->m_kFile.device->ops->lseek( &(pContext->m_kFile), 0, SEEK_END ) >= 0 )
return 0;
}
else
{
if( pContext->m_kFile.device->ops->lseek( &(pContext->m_kFile), iContinue, SEEK_SET ) >= 0 )
return 0;
}
 
// could not seek, close file and open normally
pContext->m_kFile.device->ops->close( &(pContext->m_kFile) );
}
}
 
pContext->m_kFile.mode = flags;
if( pContext->m_kFile.device->ops->open( &(pContext->m_kFile), pFile, flags, 0 ) >= 0 )
return 0;
/trunk/ps2ftpd/src/main.c
14,63 → 14,75
#ifndef LINUX
#include "irx_imports.h"
#else
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#endif
 
int server(void* argv);
 
#ifndef LINUX
 
// placed out here to end up on the heap, not the stack
FtpServer srv;
 
int process_args( FtpServer* pServer, int argc, char* argv[] )
{
argc--; argv++;
int i;
 
while( argc > 0 )
for( i = 1; i < argc; i++ )
{
if(!strcmp("-port",argv[0]))
int arg_avail = i < (argc-1);
 
if(!strcmp("-port",argv[i]))
{
if( argc <= 0 )
if( !arg_avail )
return -1;
 
argc--; argv++;
FtpServer_SetPort( pServer, strtol(argv[0],NULL,10) );
FtpServer_SetPort( pServer, strtol(argv[++i],NULL,10) );
}
else if(!strcmp("-anonymous",argv[0]))
else if(!strcmp("-anonymous",argv[i]))
{
// enable anonymous logins
FtpServer_SetAnonymous( pServer, 1 );
}
else if(!strcmp("-user",argv[0]))
else if(!strcmp("-user",argv[i]))
{
// set new username
 
if( argc <= 0 )
if( !arg_avail )
return -1;
 
argc--; argv++;
FtpServer_SetUsername( pServer, argv[0] );
FtpServer_SetUsername( pServer, argv[++i] );
}
else if(!strcmp("-pass",argv[0]))
{
// set new password
 
if( argc <= 0 )
if( !arg_avail )
return -1;
 
argc--; argv++;
FtpServer_SetPassword( pServer, argv[0] );
FtpServer_SetPassword( pServer, argv[++i] );
}
 
argc--;
argv++;
else
{
printf("ps2ftpd: unknown argument '%s'\n",argv[i]);
return -1;
}
}
 
return 0;
}
 
#ifndef LINUX
 
// placed out here to end up on the heap, not the stack
FtpServer srv;
 
int server(void* argv)
{
// run server
 
while(FtpServer_IsRunning(&srv))
FtpServer_HandleEvents(&srv);
 
FtpServer_Destroy(&srv);
return 0;
}
 
s32 _start(int argc, char* argv[])
{
iop_thread_t mythread;
90,6 → 102,7
 
if( process_args( &srv, argc, argv ) < 0 )
{
FtpServer_Destroy(&srv);
printf("ps2ftpd: could not parse arguments\n" );
return MODULE_NO_RESIDENT_END;
}
98,7 → 111,6
 
FtpServer_SetPort(&srv,21);
 
 
if( -1 == FtpServer_Start(&srv) )
{
FtpServer_Destroy(&srv);
136,17 → 148,6
}
 
 
int server(void* argv)
{
// run server
 
while(FtpServer_IsRunning(&srv))
FtpServer_HandleEvents(&srv);
 
FtpServer_Destroy(&srv);
return 0;
}
 
#else
 
int main(int argc, char* argv[])
157,9 → 158,18
 
FtpServer_Create(&srv);
 
// process arguments
 
FtpServer_SetPort(&srv,2500); // 21 privileged under linux
if( process_args( &srv, argc, argv ) < 0 )
{
printf("ps2ftpd: could not parse arguments\n" );
FtpServer_Destroy(&srv);
return 1;
}
 
// setup server
 
FtpServer_SetPort(&srv,2500); // 21 privileged under linux
if( -1 == FtpServer_Start(&srv) )
{
FtpServer_Destroy(&srv);
/trunk/ps2ftpd/src/FtpClient.c
84,6 → 84,7
pClient->m_iRemoteAddress[2] = 0;
pClient->m_iRemoteAddress[3] = 0;
pClient->m_uiDataOffset = 0;
pClient->m_iRestartMarker = 0;
 
pClient->m_kContainer.m_pClient = pClient;
pClient->m_kContainer.m_pPrev = &pClient->m_kContainer;
149,6 → 150,8
for( i = 0; *c && i < 4; i++ )
result = (result<<8)|tolower(*(c++));
 
// if user has not logged in, we only allow a small subset of commands
 
if( pClient->m_eAuthState != AUTHSTATE_VALID )
{
switch( result )
161,7 → 164,7
if(user)
FtpClient_OnCmdUser(pClient,user);
else
FtpClient_Send( pClient, 500, "USER: Requires a parameter." );
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
237,7 → 240,7
if(6 == i)
FtpClient_OnCmdPort(pClient,ip,port);
else
FtpClient_Send( pClient, 501, "Illegal PORT command." );
FtpClient_Send( pClient, 501, "Illegal command." );
}
break;
 
287,7 → 290,7
if(type)
FtpClient_OnCmdType(pClient,type);
else
FtpClient_Send( pClient, 501, "Illegal TYPE Command." );
FtpClient_Send( pClient, 501, "Illegal Command." );
}
break;
 
299,7 → 302,7
if(file)
FtpClient_OnCmdRetr(pClient,file);
else
FtpClient_Send( pClient, 501, "Illegal RETR Command." );
FtpClient_Send( pClient, 501, "Illegal Command." );
}
break;
 
311,10 → 314,22
if(file)
FtpClient_OnCmdStor(pClient,file);
else
FtpClient_Send( pClient, 501, "Illegal STOR Command." );
FtpClient_Send( pClient, 501, "Illegal Command." );
}
break;
 
// APPE <file>
case FTPCMD_APPE:
{
char* file = strtok(NULL,"");
 
if(file)
FtpClient_OnCmdAppe(pClient,file);
else
FtpClient_Send( pClient, 501, "Illegal Command." );
}
break;
 
case FTPCMD_PWD:
case FTPCMD_XPWD:
{
330,7 → 345,7
if(path)
FtpClient_OnCmdCwd(pClient,path);
else
FtpClient_Send( pClient, 501, "Illegal CWD Command." );
FtpClient_Send( pClient, 501, "Illegal command." );
}
break;
 
347,7 → 362,7
if(file)
FtpClient_OnCmdDele(pClient,file);
else
FtpClient_Send( pClient, 501, "Illegal DELE Command." );
FtpClient_Send( pClient, 501, "Illegal command." );
}
break;
 
359,7 → 374,7
if(dir)
FtpClient_OnCmdMkd(pClient,dir);
else
FtpClient_Send( pClient, 501, "Illegal MKD Command." );
FtpClient_Send( pClient, 501, "Illegal command." );
}
break;
 
371,7 → 386,7
if(dir)
FtpClient_OnCmdRmd(pClient,dir);
else
FtpClient_Send( pClient, 501, "Illegal MKD Command." );
FtpClient_Send( pClient, 501, "Illegal command." );
}
break;
 
382,10 → 397,54
if(cmd)
FtpClient_OnCmdSite(pClient,cmd);
else
FtpClient_Send( pClient, 500, "SITE requires parameters." );
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
case FTPCMD_MODE:
{
char* mode = strtok(NULL,"");
 
if(mode)
FtpClient_OnCmdMode(pClient,mode);
else
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
case FTPCMD_STRU:
{
char* structure = strtok(NULL,"");
 
if(structure)
FtpClient_OnCmdStru(pClient,structure);
else
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
case FTPCMD_REST:
{
char* marker = strtok(NULL,"");
 
if(marker)
{
char* c = marker;
while(*c)
{
if((*c < '0')||(*c > '9'))
break;
c++;
}
 
if(!*c)
FtpClient_OnCmdRest( pClient, (!*c) ? strtol( marker, NULL, 10 ) : -1 );
}
else
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
case FTPCMD_NOOP: FtpClient_Send( pClient, 200, "NOOP command successful." ); break;
 
default:
489,6 → 548,7
}
break;
 
case DATAACTION_APPE:
case DATAACTION_STOR:
{
pClient->m_eDataMode = DATAMODE_READ;
517,6 → 577,7
 
switch( pClient->m_eDataAction )
{
case DATAACTION_APPE:
case DATAACTION_STOR:
{
// read data from socket
671,10 → 732,12
{
switch( pClient->m_eDataAction )
{
case DATAACTION_NLST: FtpClient_Send( pClient, 226, "NLST command successful." ); break;
case DATAACTION_LIST: FtpClient_Send( pClient, 226, "LIST command successful." ); break;
case DATAACTION_RETR: FtpClient_Send( pClient, 226, "RETR command successful." ); break;
case DATAACTION_STOR: FtpClient_Send( pClient, 226, "STOR command successful." ); break;
case DATAACTION_APPE:
case DATAACTION_NLST:
case DATAACTION_LIST:
case DATAACTION_RETR:
case DATAACTION_STOR:
FtpClient_Send( pClient, 226, "Command successful." ); break;
default:
break;
/trunk/ps2ftpd/src/FileSystem.h
34,8 → 34,7
typedef enum
{
FM_READ,
FM_CREATE,
FM_APPEND,
FM_WRITE,
} FileMode;
 
typedef struct FSContext
87,7 → 86,7
void FileSystem_Destroy( FSContext* pContext );
 
//! Open file for readin or writing
int FileSystem_OpenFile( FSContext* pContext, const char* pFile, FileMode eMode );
int FileSystem_OpenFile( FSContext* pContext, const char* pFile, FileMode eMode, int iContinue );
 
//! Open directory for listing
int FileSystem_OpenDir( FSContext* pContext, const char* pDir );
/trunk/ps2ftpd/src/FtpCommands.c
199,10 → 199,10
 
pClient->m_iRemotePort = port;
 
FtpClient_Send( pClient, 200, "PORT command successful." );
FtpClient_Send( pClient, 200, "Command successful." );
}
else
FtpClient_Send( pClient, 500, "Illegal PORT command." );
FtpClient_Send( pClient, 500, "Illegal command." );
}
 
void FtpClient_OnCmdSyst( FtpClient* pClient )
236,23 → 236,40
 
void FtpClient_OnCmdType( FtpClient* pClient, const char* pType )
{
assert( pClient );
if( tolower(*pType) == 'i' )
FtpClient_Send( pClient, 200, "Command successful." );
else if( tolower(*pType) == 'a')
FtpClient_Send( pClient, 200, "Command successful." );
else
FtpClient_Send( pClient, 500, "Illegal command." );
}
 
// TODO: write proper handling of this command
void FtpClient_OnCmdMode( FtpClient* pClient, const char* pMode )
{
// only stream-mode supported
 
if(!strcmp(pType,"I") || !strcmp(pType,"i"))
FtpClient_Send( pClient, 200, "Type set to I." );
else if(!strcmp(pType,"A")||!strcmp(pType,"a"))
FtpClient_Send( pClient, 200, "Type set to A." );
if( tolower(*pMode) == 's' )
FtpClient_Send( pClient, 200, "Command successful." );
else
FtpClient_Send( pClient, 500, "Illegal TYPE Command." );
FtpClient_Send( pClient, 500, "Command failed." );
}
 
void FtpClient_OnCmdStru( FtpClient* pClient, const char* pStructure )
{
// only file-structure supported
 
if( tolower(*pStructure) == 'f' )
FtpClient_Send( pClient, 200, "Command successful." );
else
FtpClient_Send( pClient, 500, "Command failed." );
}
 
void FtpClient_OnCmdRetr( FtpClient* pClient, const char* pFile )
{
assert( pClient );
int iMarker = pClient->m_iRestartMarker;
pClient->m_iRestartMarker = 0;
 
if( FileSystem_OpenFile( &pClient->m_kContext, pFile, FM_READ ) < 0 )
if( FileSystem_OpenFile( &pClient->m_kContext, pFile, FM_READ, iMarker ) < 0 )
{
FtpClient_Send( pClient, 500, "File not found." );
return;
265,9 → 282,10
 
void FtpClient_OnCmdStor( FtpClient* pClient, const char* pFile )
{
assert( pClient );
int iMarker = pClient->m_iRestartMarker;
pClient->m_iRestartMarker = 0;
 
if( FileSystem_OpenFile( &pClient->m_kContext, pFile, FM_CREATE ) < 0 )
if( FileSystem_OpenFile( &pClient->m_kContext, pFile, FM_WRITE, iMarker ) < 0 )
{
FtpClient_Send( pClient, 500, "Could not create file." );
return;
278,6 → 296,35
FtpClient_HandleDataConnect( pClient );
}
 
void FtpClient_OnCmdAppe( FtpClient* pClient, const char* pFile )
{
assert( pClient );
 
if( FileSystem_OpenFile( &pClient->m_kContext, pFile, FM_WRITE, -1 ) < 0 )
{
FtpClient_Send( pClient, 500, "Could not create file." );
return;
}
 
pClient->m_eDataAction = DATAACTION_APPE;
 
FtpClient_HandleDataConnect( pClient );
}
 
void FtpClient_OnCmdRest( FtpClient* pClient, int iMarker )
{
if( iMarker < 0 )
{
pClient->m_iRestartMarker = 0;
FtpClient_Send( pClient, 501, "REST requires a value greater than or equal to 0." );
}
else
{
pClient->m_iRestartMarker = iMarker;
FtpClient_Send( pClient, 350, "Restart set. Send STORE or RETRIEVE to initiate transfer." );
}
}
 
void FtpClient_OnCmdPwd( FtpClient* pClient )
{
char* buf2 = buffer;
293,25 → 340,25
void FtpClient_OnCmdCwd( FtpClient* pClient, const char* pPath )
{
if( FileSystem_ChangeDir(&pClient->m_kContext,pPath) < 0 )
FtpClient_Send( pClient, 550, "No such file or directory" );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 250, "CWD command successful." );
FtpClient_Send( pClient, 250, "Command successful." );
}
 
void FtpClient_OnCmdDele( FtpClient* pClient, const char* pFile )
{
if( FileSystem_DeleteFile(&pClient->m_kContext,pFile) < 0 )
FtpClient_Send( pClient, 550, "No such file or directory" );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 250, "DELE command successful." );
FtpClient_Send( pClient, 250, "Command successful." );
}
 
void FtpClient_OnCmdMkd( FtpClient* pClient, const char* pDir )
{
if( FileSystem_CreateDir(&pClient->m_kContext,pDir) < 0 )
FtpClient_Send( pClient, 550, "Failed creating directory" );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 250, "MKD command successful." );
FtpClient_Send( pClient, 250, "Command successful." );
}
 
void FtpClient_SetBootValue( struct FtpClient* pClient, unsigned int val )
322,9 → 369,9
void FtpClient_OnCmdRmd( FtpClient* pClient, const char* pDir )
{
if( FileSystem_DeleteDir(&pClient->m_kContext,pDir) < 0 )
FtpClient_Send( pClient, 550, "No such file or directory" );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 250, "RMD command successful." );
FtpClient_Send( pClient, 250, "Command successful." );
}
 
void FtpClient_OnCmdSite( FtpClient* pClient, const char* pCmd )
381,7 → 428,7
if(mount_point)
FtpClient_OnSiteUmount(pClient,mount_point);
else
FtpClient_Send( pClient, 500, "SITE UMNT: missing mount-point" );
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
 
393,7 → 440,7
if(devname)
FtpClient_OnSiteSync( pClient, devname );
else
FtpClient_Send( pClient, 500, "SITE SYNC: missing device-name." );
FtpClient_Send( pClient, 500, "Requires parameters." );
}
break;
#endif
400,13 → 447,13
 
default:
{
FtpClient_Send( pClient, 500, "SITE command not supported" );
FtpClient_Send( pClient, 500, "Not supported." );
}
break;
}
}
else
FtpClient_Send( pClient, 500, "SITE command not understood" );
FtpClient_Send( pClient, 500, "Not understood." );
 
}
 
416,9 → 463,9
// mount filesystem
 
if( FileSystem_MountDevice( &(pClient->m_kContext), pMountPoint, pMountFile ) < 0 )
FtpClient_Send( pClient, 550, "SITE MNT failed." );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 214, "SITE MNT succeeded." );
FtpClient_Send( pClient, 214, "Command succesful." );
}
 
void FtpClient_OnSiteUmount( struct FtpClient* pClient, const char* pMountPoint )
426,9 → 473,9
// unmount filesystem
 
if( FileSystem_UnmountDevice( &(pClient->m_kContext), pMountPoint ) < 0 )
FtpClient_Send( pClient, 550, "SITE UMNT failed." );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 214, "SITE UMOUNT succeeded." );
FtpClient_Send( pClient, 214, "Command successful." );
 
}
 
437,8 → 484,8
// sync data with filesystem
 
if( FileSystem_SyncDevice( &(pClient->m_kContext), pDeviceName ) < 0 )
FtpClient_Send( pClient, 550, "SITE SYNC failed." );
FtpClient_Send( pClient, 550, "Command failed." );
else
FtpClient_Send( pClient, 214, "SITE SYNC succeeded." );
FtpClient_Send( pClient, 214, "Command successful." );
}
#endif
/trunk/ps2ftpd/src/FtpClient.h
49,6 → 49,7
DATAACTION_NLST,
DATAACTION_RETR,
DATAACTION_STOR,
DATAACTION_APPE,
} DataAction;
#define m_eCOnnState m_pServer->m_iPort
 
62,38 → 63,38
FTPCMD_QUIT = FCOMMAND('q','u','i','t'),
FTPCMD_PORT = FCOMMAND('p','o','r','t'),
FTPCMD_TYPE = FCOMMAND('t','y','p','e'),
FTPCMD_MODE = FCOMMAND('m','o','d','e'), // implement
FTPCMD_STRU = FCOMMAND('s','t','r','u'), // implement
FTPCMD_MODE = FCOMMAND('m','o','d','e'),
FTPCMD_STRU = FCOMMAND('s','t','r','u'),
FTPCMD_RETR = FCOMMAND('r','e','t','r'),
FTPCMD_STOR = FCOMMAND('s','t','o','r'),
FTPCMD_NOOP = FCOMMAND('n','o','o','p'), // implement
FTPCMD_NOOP = FCOMMAND('n','o','o','p'),
 
// additional commands
 
FTPCMD_PASS = FCOMMAND('p','a','s','s'),
FTPCMD_CWD = FCOMMAND(0,'c','w','d'),
FTPCMD_CWD = FCOMMAND( 0,'c','w','d'),
FTPCMD_XCWD = FCOMMAND('x','c','w','d'),
FTPCMD_CDUP = FCOMMAND('c','d','u','p'),
FTPCMD_PASV = FCOMMAND('p','a','s','v'),
FTPCMD_APPE = FCOMMAND('a','p','p','e'), // implement
FTPCMD_APPE = FCOMMAND('a','p','p','e'),
FTPCMD_RNFR = FCOMMAND('r','n','f','r'), // implement
FTPCMD_RNTO = FCOMMAND('r','n','t','o'), // implement
FTPCMD_ABOR = FCOMMAND('a','b','o','r'), // implement
FTPCMD_DELE = FCOMMAND('d','e','l','e'),
FTPCMD_RMD = FCOMMAND(0,'r','m','d'),
FTPCMD_RMD = FCOMMAND( 0,'r','m','d'),
FTPCMD_XRMD = FCOMMAND('x','r','m','d'),
FTPCMD_MKD = FCOMMAND(0,'m','k','d'),
FTPCMD_MKD = FCOMMAND( 0,'m','k','d'),
FTPCMD_XMKD = FCOMMAND('x','m','k','d'),
FTPCMD_PWD = FCOMMAND(0,'p','w','d'),
FTPCMD_PWD = FCOMMAND( 0,'p','w','d'),
FTPCMD_XPWD = FCOMMAND('x','p','w','d'),
FTPCMD_LIST = FCOMMAND('l','i','s','t'),
FTPCMD_NLST = FCOMMAND('n','l','s','t'),
FTPCMD_SITE = FCOMMAND('s','i','t','e'),
FTPCMD_SYST = FCOMMAND('s','y','s','t'),
FTPCMD_REST = FCOMMAND('r','e','s','t'),
 
// possible commands, we'll implement them if it become necessary
 
//FTPCMD_REST = FCOMMAND('r','e','s','t'),
//FTPCMD_STAT = FCOMMAND('s','t','a','t'),
//FTPCMD_HELP = FCOMMAND('h','e','l','p'),
//FTPCMD_SIZE = FCOMMAND('s','i','z','e'),
101,7 → 102,7
 
enum
{
SITECMD_MNT = FCOMMAND(0,'m','n','t'),
SITECMD_MNT = FCOMMAND( 0,'m','n','t'),
SITECMD_UMNT = FCOMMAND('u','m','n','t'),
SITECMD_SYNC = FCOMMAND('s','y','n','c'),
SITECMD_HELP = FCOMMAND('h','e','l','p'),
131,6 → 132,7
DataAction m_eDataAction;
ConnState m_eConnState;
int m_uiDataOffset;
int m_iRestartMarker; // TODO: 64-bit support?
 
FtpClientContainer m_kContainer;
 
163,6 → 165,10
void FtpClient_OnCmdMkd( FtpClient* pClient, const char* pDir );
void FtpClient_OnCmdRmd( FtpClient* pClient, const char* pDir );
void FtpClient_OnCmdSite( FtpClient* pClient, const char* pCmd );
void FtpClient_OnCmdMode( FtpClient* pClient, const char* pMode );
void FtpClient_OnCmdStru( FtpClient* pClient, const char* pStructure );
void FtpClient_OnCmdAppe( FtpClient* pClient, const char* pFile );
void FtpClient_OnCmdRest( FtpClient* pClient, int iMarker );
 
void FtpClient_OnSiteMount( FtpClient* pClient, const char* pMountPoint, const char* pMountFile );
void FtpClient_OnSiteUmount( FtpClient* pClient, const char* pMountPoint );