forked from KolibriOS/kolibrios
Implemented Passive mode and LIST command in new FTP daemon (net branch)
git-svn-id: svn://kolibrios.org@2562 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
74a8292f46
commit
0833e5c02d
@ -35,52 +35,38 @@ commands: ; all commands must be in uppercase
|
|||||||
|
|
||||||
db 'ABOR'
|
db 'ABOR'
|
||||||
dd cmdABOR
|
dd cmdABOR
|
||||||
|
|
||||||
db 'CWD', 0
|
db 'CWD', 0
|
||||||
dd cmdCWD
|
dd cmdCWD
|
||||||
|
|
||||||
db 'DELE'
|
db 'DELE'
|
||||||
dd cmdDELE
|
dd cmdDELE
|
||||||
|
|
||||||
db 'LIST'
|
db 'LIST'
|
||||||
dd cmdLIST
|
dd cmdLIST
|
||||||
|
|
||||||
db 'NLST'
|
db 'NLST'
|
||||||
dd cmdNLST
|
dd cmdNLST
|
||||||
|
|
||||||
db 'NOOP'
|
db 'NOOP'
|
||||||
dd cmdNOOP
|
dd cmdNOOP
|
||||||
|
|
||||||
db 'PASS'
|
db 'PASS'
|
||||||
dd cmdPASS
|
dd cmdPASS
|
||||||
|
db 'PASV'
|
||||||
|
dd cmdPASV
|
||||||
db 'PWD', 0 ; Print Working Directory
|
db 'PWD', 0 ; Print Working Directory
|
||||||
dd cmdPWD
|
dd cmdPWD
|
||||||
|
|
||||||
db 'PORT'
|
db 'PORT'
|
||||||
dd cmdPORT
|
dd cmdPORT
|
||||||
|
|
||||||
db 'QUIT'
|
db 'QUIT'
|
||||||
dd cmdQUIT
|
dd cmdQUIT
|
||||||
|
|
||||||
db 'RETR'
|
db 'RETR'
|
||||||
dd cmdRETR
|
dd cmdRETR
|
||||||
|
|
||||||
db 'STOR'
|
db 'STOR'
|
||||||
dd cmdSTOR
|
dd cmdSTOR
|
||||||
|
|
||||||
db 'SYST'
|
db 'SYST'
|
||||||
dd cmdSYST
|
dd cmdSYST
|
||||||
|
|
||||||
db 'TYPE'
|
db 'TYPE'
|
||||||
dd cmdTYPE
|
dd cmdTYPE
|
||||||
|
|
||||||
db 'USER'
|
db 'USER'
|
||||||
dd cmdUSER
|
dd cmdUSER
|
||||||
|
|
||||||
db 'XPWD'
|
db 'XPWD'
|
||||||
dd cmdPWD
|
dd cmdPWD
|
||||||
|
|
||||||
db 0 ; end marker
|
db 0 ; end marker
|
||||||
|
|
||||||
|
|
||||||
@ -102,6 +88,143 @@ cmdDELE:
|
|||||||
align 4
|
align 4
|
||||||
cmdLIST:
|
cmdLIST:
|
||||||
|
|
||||||
|
cmp [mode], MODE_ACTIVE
|
||||||
|
jne @f
|
||||||
|
mcall connect, [datasocketnum], datasock, datasock.length
|
||||||
|
cmp eax, -1
|
||||||
|
je .err
|
||||||
|
@@:
|
||||||
|
|
||||||
|
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
|
||||||
|
|
||||||
|
push FA_READONLY + FA_FOLDER
|
||||||
|
push str_mask
|
||||||
|
push home_dir
|
||||||
|
call [file.find.first]
|
||||||
|
|
||||||
|
mov edi, buffer
|
||||||
|
jmp .parse_file
|
||||||
|
|
||||||
|
.checknextfile:
|
||||||
|
push edx
|
||||||
|
call [file.find.next]
|
||||||
|
|
||||||
|
.parse_file:
|
||||||
|
test eax, eax
|
||||||
|
jz .done
|
||||||
|
|
||||||
|
mov edx, eax
|
||||||
|
|
||||||
|
; first, convert the attributes
|
||||||
|
test [eax + FileInfoA.Attributes], FA_FOLDER
|
||||||
|
jnz .folder
|
||||||
|
|
||||||
|
test [eax + FileInfoA.Attributes], FA_READONLY
|
||||||
|
jnz .readonly
|
||||||
|
|
||||||
|
mov eax, '-rw-'
|
||||||
|
stosd
|
||||||
|
jmp .attr
|
||||||
|
|
||||||
|
.folder:
|
||||||
|
mov eax, 'drwx'
|
||||||
|
stosb
|
||||||
|
jmp .attr
|
||||||
|
|
||||||
|
.readonly:
|
||||||
|
mov eax, '-r--'
|
||||||
|
stosd
|
||||||
|
|
||||||
|
.attr:
|
||||||
|
mov eax, 'rw-r'
|
||||||
|
stosd
|
||||||
|
mov ax, 'w-'
|
||||||
|
stosw
|
||||||
|
mov al, ' '
|
||||||
|
stosb
|
||||||
|
|
||||||
|
; now..
|
||||||
|
mov ax, '1 '
|
||||||
|
stosw
|
||||||
|
|
||||||
|
; now write owner, everything is owned by FTP, woohoo!
|
||||||
|
mov eax, 'FTP '
|
||||||
|
stosd
|
||||||
|
stosd
|
||||||
|
|
||||||
|
; now the filesize in ascii
|
||||||
|
mov ebx, dword [edx + FileInfoA.FileSize]
|
||||||
|
call dword_to_ascii
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
stosb
|
||||||
|
|
||||||
|
; then date (month/day/year)
|
||||||
|
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.month]
|
||||||
|
mov eax, [months + 4*ebx]
|
||||||
|
stosd
|
||||||
|
|
||||||
|
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.day]
|
||||||
|
call dword_to_ascii
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
stosb
|
||||||
|
|
||||||
|
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.year]
|
||||||
|
call dword_to_ascii
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
stosb
|
||||||
|
|
||||||
|
; and last but not least, filename
|
||||||
|
lea esi, [edx + FileInfoA.FileName]
|
||||||
|
mov ecx, 250
|
||||||
|
.nameloop:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .namedone
|
||||||
|
stosb
|
||||||
|
loop .nameloop
|
||||||
|
|
||||||
|
.namedone:
|
||||||
|
mov ax, 0x0d0a
|
||||||
|
stosw
|
||||||
|
jmp .checknextfile
|
||||||
|
|
||||||
|
.done:
|
||||||
|
push edx
|
||||||
|
call [file.find.close]
|
||||||
|
|
||||||
|
xor al, al
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push buffer
|
||||||
|
call [con_write_asciiz]
|
||||||
|
|
||||||
|
lea esi, [edi - buffer]
|
||||||
|
mcall send, [datasocketnum], buffer, , 0
|
||||||
|
|
||||||
|
mcall close, [datasocketnum]
|
||||||
|
|
||||||
|
cmp [mode], MODE_PASSIVE_OK
|
||||||
|
jne @f
|
||||||
|
mov [mode], MODE_PASSIVE_WAIT
|
||||||
|
@@:
|
||||||
|
|
||||||
|
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.err:
|
||||||
|
pushd 0x0c
|
||||||
|
call [con_set_flags]
|
||||||
|
|
||||||
|
push str_err1
|
||||||
|
call [con_write_asciiz]
|
||||||
|
|
||||||
|
pushd 0x07
|
||||||
|
call [con_set_flags]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -129,13 +252,47 @@ cmdPASS:
|
|||||||
align 4
|
align 4
|
||||||
cmdPASV:
|
cmdPASV:
|
||||||
|
|
||||||
mov [mode], MODE_PASSIVE
|
|
||||||
|
|
||||||
; TODO: open the UDP socket and return our IP + port
|
|
||||||
|
|
||||||
; 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
|
; 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
|
||||||
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
|
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
|
||||||
|
|
||||||
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
|
cmp eax, -1
|
||||||
|
; je .err
|
||||||
|
mov [passivesocknum], eax
|
||||||
|
|
||||||
|
mov [datasock.port], 2000
|
||||||
|
mov [datasock.ip], 0
|
||||||
|
|
||||||
|
mcall bind, [passivesocknum], datasock, datasock.length
|
||||||
|
cmp eax, -1
|
||||||
|
je bind_err
|
||||||
|
|
||||||
|
mcall listen, [passivesocknum], 1
|
||||||
|
|
||||||
|
mov [mode], MODE_PASSIVE_WAIT
|
||||||
|
|
||||||
|
mov edi, buffer
|
||||||
|
mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000)
|
||||||
|
stosd
|
||||||
|
mov eax, '(127'
|
||||||
|
stosd
|
||||||
|
mov eax, ',0,0'
|
||||||
|
stosd
|
||||||
|
mov eax, ',1,7'
|
||||||
|
stosd
|
||||||
|
mov eax, ',208'
|
||||||
|
stosd
|
||||||
|
mov al, ')'
|
||||||
|
stosb
|
||||||
|
mov ax, 0x0d0a
|
||||||
|
stosw
|
||||||
|
xor al, al
|
||||||
|
stosb
|
||||||
|
|
||||||
|
lea esi, [edi - buffer]
|
||||||
|
|
||||||
|
mcall send, [socketnum2], buffer, ,0
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -161,6 +318,10 @@ cmdPWD:
|
|||||||
|
|
||||||
mcall send, [socketnum2], buffer, , 0
|
mcall send, [socketnum2], buffer, , 0
|
||||||
|
|
||||||
|
; push work_dir
|
||||||
|
; push str_pwd
|
||||||
|
; call [con_printf]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -198,15 +359,11 @@ cmdPORT:
|
|||||||
|
|
||||||
mov [datasock.port], dx
|
mov [datasock.port], dx
|
||||||
|
|
||||||
mcall socket, AF_INET4, SOCK_DGRAM, 0
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je .err
|
je .err
|
||||||
mov [datasocketnum], eax
|
mov [datasocketnum], eax
|
||||||
|
|
||||||
mcall connect, [datasocketnum], datasock, datasock.length
|
|
||||||
cmp eax, -1
|
|
||||||
je .err
|
|
||||||
|
|
||||||
mcall send, [socketnum2], str225, str225.length, 0
|
mcall send, [socketnum2], str225, str225.length, 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -226,6 +383,23 @@ cmdQUIT:
|
|||||||
align 4
|
align 4
|
||||||
cmdRETR:
|
cmdRETR:
|
||||||
|
|
||||||
|
; mcall connect, [datasocketnum], datasock, datasock.length
|
||||||
|
; cmp eax, -1
|
||||||
|
; je .err
|
||||||
|
|
||||||
|
; push O_READ
|
||||||
|
; push home_dir
|
||||||
|
; call [file.open]
|
||||||
|
; test eax, eax
|
||||||
|
; jz .cannot_open
|
||||||
|
;
|
||||||
|
; push BUFFERSIZE
|
||||||
|
; push buffer
|
||||||
|
; push eax
|
||||||
|
; call [file.read]
|
||||||
|
; cmp eax, -1
|
||||||
|
; jz .cannot_open
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -360,11 +534,20 @@ ascii_to_byte:
|
|||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
align 4
|
||||||
|
dword_to_ascii: ; edi = ptr where to write, ebx is number
|
||||||
|
|
||||||
|
mov eax, '1'
|
||||||
|
stosb
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
str150 db '150 Here it comes...', 13, 10
|
str150 db '150 Here it comes...', 13, 10
|
||||||
|
.length = $ - str150
|
||||||
str200 db '200 Command OK.', 13, 10
|
str200 db '200 Command OK.', 13, 10
|
||||||
.length = $ - str200
|
.length = $ - str200
|
||||||
str215 db '215 UNIX type: L8', 13, 10
|
str215 db '215 UNIX type: L8', 13, 10
|
||||||
@ -376,6 +559,7 @@ str221 db '221 Bye!', 13, 10
|
|||||||
str225 db '225 Data connection open', 13, 10
|
str225 db '225 Data connection open', 13, 10
|
||||||
.length = $ - str225
|
.length = $ - str225
|
||||||
str226 db '226 Transfer OK, Closing connection', 13, 10
|
str226 db '226 Transfer OK, Closing connection', 13, 10
|
||||||
|
.length = $ - str226
|
||||||
str230 db '230 You are now logged in.', 13, 10
|
str230 db '230 You are now logged in.', 13, 10
|
||||||
.length = $ - str230
|
.length = $ - str230
|
||||||
str250 db '250 command successful', 13, 10
|
str250 db '250 command successful', 13, 10
|
||||||
|
@ -28,7 +28,8 @@ TYPE_LOCAL = 10000000b ; bits per byte must be specified
|
|||||||
|
|
||||||
MODE_NOTREADY = 0
|
MODE_NOTREADY = 0
|
||||||
MODE_ACTIVE = 1
|
MODE_ACTIVE = 1
|
||||||
MODE_PASSIVE = 2
|
MODE_PASSIVE_WAIT = 2
|
||||||
|
MODE_PASSIVE_OK = 3
|
||||||
|
|
||||||
use32
|
use32
|
||||||
db 'MENUET01' ; signature
|
db 'MENUET01' ; signature
|
||||||
@ -44,6 +45,8 @@ include '../macros.inc'
|
|||||||
purge mov,add,sub
|
purge mov,add,sub
|
||||||
include '../proc32.inc'
|
include '../proc32.inc'
|
||||||
include '../dll.inc'
|
include '../dll.inc'
|
||||||
|
include '../struct.inc'
|
||||||
|
include '../libio.inc'
|
||||||
|
|
||||||
include '../network.inc'
|
include '../network.inc'
|
||||||
include 'commands.inc'
|
include 'commands.inc'
|
||||||
@ -131,14 +134,27 @@ start:
|
|||||||
.loop:
|
.loop:
|
||||||
mcall 10
|
mcall 10
|
||||||
|
|
||||||
|
cmp [mode], MODE_PASSIVE_WAIT
|
||||||
|
jne @f
|
||||||
|
mcall accept, [passivesocknum], datasock, datasock.length
|
||||||
|
cmp eax, -1
|
||||||
|
je @f
|
||||||
|
mov [datasocketnum], eax
|
||||||
|
mov [mode], MODE_PASSIVE_OK
|
||||||
|
|
||||||
|
push str_datasock
|
||||||
|
call [con_write_asciiz]
|
||||||
|
@@:
|
||||||
|
|
||||||
mcall recv, [socketnum2], buffer, buffer.length
|
mcall recv, [socketnum2], buffer, buffer.length
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je .loop
|
je .loop
|
||||||
|
or eax, eax
|
||||||
|
jz .loop
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
mov byte[buffer+eax], 0
|
mov byte[buffer+eax], 0
|
||||||
|
|
||||||
|
|
||||||
pushd 0x0a
|
pushd 0x0a
|
||||||
call [con_set_flags]
|
call [con_set_flags]
|
||||||
|
|
||||||
@ -213,6 +229,18 @@ str8 db 'Error accepting connection',10,10,0
|
|||||||
|
|
||||||
str_logged_in db 'Login ok',10,10,0
|
str_logged_in db 'Login ok',10,10,0
|
||||||
str_pass_ok db 'Password ok - Logged in',10,10,0
|
str_pass_ok db 'Password ok - Logged in',10,10,0
|
||||||
|
str_pwd db 'Current directory is "%s"\n',0
|
||||||
|
str_err1 db 'ERROR: cannot connect to remote socket',10,10,0
|
||||||
|
str_err2 db 'ERROR: cannot open directory',10,10,0
|
||||||
|
str_datasock db 'Passive data socket connected!',10,10,0
|
||||||
|
|
||||||
|
|
||||||
|
str_mask db '*', 0
|
||||||
|
|
||||||
|
|
||||||
|
months:
|
||||||
|
dd 'Jan ','Feb ','Mar ','Apr ','May ','Jun '
|
||||||
|
dd 'Jul ','Aug ','Sep ','Oct ','Nov ','Dec '
|
||||||
|
|
||||||
filename db '.ini', 0
|
filename db '.ini', 0
|
||||||
str_port db 'port', 0
|
str_port db 'port', 0
|
||||||
@ -255,7 +283,10 @@ import libio, \
|
|||||||
file.size , 'file_size' , \
|
file.size , 'file_size' , \
|
||||||
file.open , 'file_open' , \
|
file.open , 'file_open' , \
|
||||||
file.read , 'file_read' , \
|
file.read , 'file_read' , \
|
||||||
file.close , 'file_close'
|
file.close , 'file_close' , \
|
||||||
|
file.find.first , 'file_find_first', \
|
||||||
|
file.find.next , 'file_find_next', \
|
||||||
|
file.find.close , 'file_find_close'
|
||||||
|
|
||||||
|
|
||||||
i_end:
|
i_end:
|
||||||
@ -266,11 +297,12 @@ socketnum dd ?
|
|||||||
; thread specific data
|
; thread specific data
|
||||||
socketnum2 dd ?
|
socketnum2 dd ?
|
||||||
state dd ?
|
state dd ?
|
||||||
home_dir rb 1024
|
home_dir db '/rd/1/',0
|
||||||
work_dir rb 1024
|
work_dir rb 1024
|
||||||
type db ?
|
type db ?
|
||||||
mode db ? ; active/passive
|
mode db ? ; active/passive
|
||||||
|
|
||||||
|
passivesocknum dd ?
|
||||||
datasocketnum dd ?
|
datasocketnum dd ?
|
||||||
|
|
||||||
datasock:
|
datasock:
|
||||||
|
Loading…
Reference in New Issue
Block a user