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
@ -31,57 +31,43 @@ parse_cmd: ; esi must point to command
|
||||
|
||||
|
||||
align 4
|
||||
commands: ; all commands must be in uppercase
|
||||
commands: ; all commands must be in uppercase
|
||||
|
||||
db 'ABOR'
|
||||
dd cmdABOR
|
||||
|
||||
db 'CWD', 0
|
||||
dd cmdCWD
|
||||
|
||||
db 'DELE'
|
||||
dd cmdDELE
|
||||
|
||||
db 'LIST'
|
||||
dd cmdLIST
|
||||
|
||||
db 'NLST'
|
||||
dd cmdNLST
|
||||
|
||||
db 'NOOP'
|
||||
dd cmdNOOP
|
||||
|
||||
db 'PASS'
|
||||
dd cmdPASS
|
||||
|
||||
db 'PASV'
|
||||
dd cmdPASV
|
||||
db 'PWD', 0 ; Print Working Directory
|
||||
dd cmdPWD
|
||||
|
||||
db 'PORT'
|
||||
dd cmdPORT
|
||||
|
||||
db 'QUIT'
|
||||
dd cmdQUIT
|
||||
|
||||
db 'RETR'
|
||||
dd cmdRETR
|
||||
|
||||
db 'STOR'
|
||||
dd cmdSTOR
|
||||
|
||||
db 'SYST'
|
||||
dd cmdSYST
|
||||
|
||||
db 'TYPE'
|
||||
dd cmdTYPE
|
||||
|
||||
db 'USER'
|
||||
dd cmdUSER
|
||||
|
||||
db 'XPWD'
|
||||
dd cmdPWD
|
||||
|
||||
db 0 ; end marker
|
||||
db 0 ; end marker
|
||||
|
||||
|
||||
align 4
|
||||
@ -102,6 +88,143 @@ cmdDELE:
|
||||
align 4
|
||||
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
|
||||
|
||||
align 4
|
||||
@ -129,13 +252,47 @@ cmdPASS:
|
||||
align 4
|
||||
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)
|
||||
; 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
|
||||
|
||||
align 4
|
||||
@ -161,6 +318,10 @@ cmdPWD:
|
||||
|
||||
mcall send, [socketnum2], buffer, , 0
|
||||
|
||||
; push work_dir
|
||||
; push str_pwd
|
||||
; call [con_printf]
|
||||
|
||||
ret
|
||||
|
||||
align 4
|
||||
@ -198,15 +359,11 @@ cmdPORT:
|
||||
|
||||
mov [datasock.port], dx
|
||||
|
||||
mcall socket, AF_INET4, SOCK_DGRAM, 0
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
cmp eax, -1
|
||||
je .err
|
||||
mov [datasocketnum], eax
|
||||
|
||||
mcall connect, [datasocketnum], datasock, datasock.length
|
||||
cmp eax, -1
|
||||
je .err
|
||||
|
||||
mcall send, [socketnum2], str225, str225.length, 0
|
||||
ret
|
||||
|
||||
@ -226,6 +383,23 @@ cmdQUIT:
|
||||
align 4
|
||||
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
|
||||
|
||||
align 4
|
||||
@ -360,11 +534,20 @@ ascii_to_byte:
|
||||
.done:
|
||||
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
|
||||
.length = $ - str150
|
||||
str200 db '200 Command OK.', 13, 10
|
||||
.length = $ - str200
|
||||
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
|
||||
.length = $ - str225
|
||||
str226 db '226 Transfer OK, Closing connection', 13, 10
|
||||
.length = $ - str226
|
||||
str230 db '230 You are now logged in.', 13, 10
|
||||
.length = $ - str230
|
||||
str250 db '250 command successful', 13, 10
|
||||
|
@ -28,7 +28,8 @@ TYPE_LOCAL = 10000000b ; bits per byte must be specified
|
||||
|
||||
MODE_NOTREADY = 0
|
||||
MODE_ACTIVE = 1
|
||||
MODE_PASSIVE = 2
|
||||
MODE_PASSIVE_WAIT = 2
|
||||
MODE_PASSIVE_OK = 3
|
||||
|
||||
use32
|
||||
db 'MENUET01' ; signature
|
||||
@ -44,6 +45,8 @@ include '../macros.inc'
|
||||
purge mov,add,sub
|
||||
include '../proc32.inc'
|
||||
include '../dll.inc'
|
||||
include '../struct.inc'
|
||||
include '../libio.inc'
|
||||
|
||||
include '../network.inc'
|
||||
include 'commands.inc'
|
||||
@ -131,14 +134,27 @@ start:
|
||||
.loop:
|
||||
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
|
||||
cmp eax, -1
|
||||
je .loop
|
||||
or eax, eax
|
||||
jz .loop
|
||||
push eax
|
||||
|
||||
mov byte[buffer+eax], 0
|
||||
|
||||
|
||||
pushd 0x0a
|
||||
call [con_set_flags]
|
||||
|
||||
@ -211,8 +227,20 @@ str6 db 'Could not open socket',10,10,0
|
||||
str7 db 'Got data!',10,10,0
|
||||
str8 db 'Error accepting connection',10,10,0
|
||||
|
||||
str_logged_in db 'Login ok',10,10,0
|
||||
str_pass_ok db 'Password ok - Logged in',10,10,0
|
||||
str_logged_in db 'Login ok',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
|
||||
str_port db 'port', 0
|
||||
@ -255,7 +283,10 @@ import libio, \
|
||||
file.size , 'file_size' , \
|
||||
file.open , 'file_open' , \
|
||||
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:
|
||||
@ -266,11 +297,12 @@ socketnum dd ?
|
||||
; thread specific data
|
||||
socketnum2 dd ?
|
||||
state dd ?
|
||||
home_dir rb 1024
|
||||
home_dir db '/rd/1/',0
|
||||
work_dir rb 1024
|
||||
type db ?
|
||||
mode db ? ; active/passive
|
||||
|
||||
passivesocknum dd ?
|
||||
datasocketnum dd ?
|
||||
|
||||
datasock:
|
||||
|
Loading…
Reference in New Issue
Block a user