Added some more commands to the new FTP Daemon (net branch)

git-svn-id: svn://kolibrios.org@2560 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-04-04 09:24:08 +00:00
parent 9d73147338
commit 742df45545
2 changed files with 291 additions and 19 deletions

View File

@ -54,7 +54,7 @@ commands: ; all commands must be in uppercase
db 'PASS'
dd cmdPASS
db 'PWD', 0
db 'PWD', 0 ; Print Working Directory
dd cmdPWD
db 'PORT'
@ -118,18 +118,101 @@ align 4
cmdPASS:
mcall send, [socketnum2], str230, str230.length, 0
push str_pass_ok
call [con_write_asciiz]
mov [state], STATE_ACTIVE
ret
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.
ret
align 4
cmdPWD:
mov dword[buffer], '257 '
mov byte[buffer+4], '"'
lea edi, [buffer+5]
mov esi, work_dir
mov ecx, 1024
.loop:
lodsb
or al, al
jz .ok
stosb
dec ecx
jnz .loop
.ok:
mov dword[edi], '"' + 0x000a0d00 ; '"',13,10,0
lea esi, [edi - buffer + 4]
mcall send, [socketnum2], buffer, , 0
ret
align 4
cmdPORT:
; PORT a1,a2,a3,a4,p1,p2
; IP address a1.a2.a3.a4, port p1*256+p2
mov [mode], MODE_ACTIVE
lea esi, [esi+5]
xor edx, edx
call ascii_to_byte
mov dh, bl
inc esi
call ascii_to_byte
mov dl, bl
shl edx, 16
inc esi
call ascii_to_byte
mov dh, bl
inc esi
call ascii_to_byte
mov dl, bl
inc esi
mov [datasock.ip], edx
call ascii_to_byte
mov dh, bl
inc esi
call ascii_to_byte
mov dl, bl
mov [datasock.port], dx
mcall socket, AF_INET4, SOCK_DGRAM, 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
.err:
mcall send, [socketnum2], str425, str425.length, 0
ret
align 4
@ -160,6 +243,79 @@ cmdSYST:
align 4
cmdTYPE:
cmp ecx, 6
jb parse_cmd.error
mov al, byte[esi+5]
and al, not 0x20
cmp al, 'A'
je .ascii
cmp al, 'E'
je .ebdic
cmp al, 'I'
je .image
cmp al, 'L'
je .local
jmp parse_cmd.error
.ascii:
mov [type], TYPE_ASCII
jmp .subtype
.ebdic:
mov [type], TYPE_EBDIC
.subtype:
cmp ecx, 8
jb .non_print
mov al, byte[esi+7]
and al, not 0x20
cmp al, 'N'
je .non_print
cmp al, 'T'
je .telnet
cmp al, 'C'
je .asacc
jmp parse_cmd.error
.non_print:
or [type], TYPE_NP
jmp .ok
.telnet:
or [type], TYPE_TELNET
jmp .ok
.asacc:
or [type], TYPE_ASA
jmp .ok
.image:
mov [type], TYPE_IMAGE
jmp .ok
.local:
cmp ecx, 8
jb parse_cmd.error
mov al, byte[esi+7]
sub al, '0'
jb parse_cmd.error
cmp al, 9
ja parse_cmd.error
or al, TYPE_LOCAL
mov [type], al
.ok:
mcall send, [socketnum2], str200, str200.length, 0
ret
align 4
@ -168,26 +324,71 @@ cmdUSER:
mcall send, [socketnum2], str331, str331.length, 0
mov [state], STATE_LOGIN
mov byte [work_dir], "/"
mov byte [work_dir+1], 0
push str_logged_in
call [con_write_asciiz]
ret
align 4 ; esi = ptr to str
ascii_to_byte:
xor ebx, ebx
.loop:
movzx eax, byte[esi]
sub al, '0'
jb .done
cmp al, 9
ja .done
lea ebx, [ebx*4 + ebx]
shl ebx, 1
add ebx, eax
inc esi
jmp .loop
.done:
ret
str150 db '150 Here it comes...', 13, 10
str200 db '200 Command OK.', 13, 10
.length = $ - str200
str215 db '215 UNIX type: L8', 13, 10
.length = $ - str215
str220 db '220 KolibriOS FTP Daemon 1.0', 13, 10
.length = $ - str220
str221 db '221 Bye!', 13, 10
.length = $ - str221
str225 db '225 Abort successful', 13, 10
str225 db '225 Data connection open', 13, 10
.length = $ - str225
str226 db '226 Transfer OK, Closing connection', 13, 10
str230 db '230 You are now logged in.', 13, 10
.length = $ - str230
str250 db '250 command successful', 13, 10
str257 db '257 ""', 13, 10
;str257 db '257 "'
;.length = $ - str257
;str257b db '"', 13, 10
;.length = $ - str257b
str331 db '331 Please specify the password.', 13, 10
.length = $ - str331
str421 db '421 Timeout!', 13, 10
.length = $ - str421
str425 db '425 Cant open data connection.', 13, 10
.length = $ - str425
str500 db '500 Unsupported command', 13, 10
.length = $ - str500
str550 db '550 No such file', 13, 10

View File

@ -13,6 +13,22 @@ STATE_CONNECTED = 1
STATE_LOGIN = 2
STATE_ACTIVE = 3
TYPE_UNDEF = 0
TYPE_ASCII = 00000100b
TYPE_EBDIC = 00001000b
; subtypes for ascii & ebdic (np = default)
TYPE_NP = 00000001b ; non printable
TYPE_TELNET = 00000010b
TYPE_ASA = 00000011b
TYPE_IMAGE = 01000000b ; binary data
TYPE_LOCAL = 10000000b ; bits per byte must be specified
; lower 4 bits will hold this value
MODE_NOTREADY = 0
MODE_ACTIVE = 1
MODE_PASSIVE = 2
use32
db 'MENUET01' ; signature
@ -52,17 +68,22 @@ start:
; initialize console
push 1
call [con_start]
push title
push 25
push 80
push 25
push 80
push -1
push -1
push -1
push -1
call [con_init]
mcall 40, 1 shl 7 ; we only want network events
invoke ini.get_int, path, str_ftpd, str_port, 21
mov [sockaddr1.port], ax
push eax
push str1
call [con_write_asciiz]
call [con_printf]
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
@ -70,24 +91,31 @@ start:
mov [socketnum], eax
push str2
call [con_write_asciiz]
;; mcall setsockopt, [socketnum], SOL_SOCKET, SO_REUSEADDR, &yes,
;; cmp eax, -1
;; je opt_err
invoke ini.get_int, path, str_ftpd, str_port, 21
mov [sockaddr1.port], ax
mcall bind, [socketnum], sockaddr1, sockaddr1.length
cmp eax, -1
je bind_err
push str2
call [con_write_asciiz]
invoke ini.get_int, path, str_ftpd, str_conn, 1 ; Backlog (max connections)
mov edx, eax
push str2
call [con_write_asciiz]
mcall listen, [socketnum]
cmp eax, -1
je listen_err
push str2
push str2b
call [con_write_asciiz]
mcall 10
@ -108,9 +136,18 @@ start:
je .loop
push eax
mov byte[buffer+eax], 0
pushd 0x0a
call [con_set_flags]
push buffer
call [con_write_asciiz]
pushd 0x07
call [con_set_flags]
pop ecx
mov esi, buffer
call parse_cmd
@ -118,21 +155,37 @@ start:
jmp .loop
acpt_err:
pushd 0x0c
call [con_set_flags]
push str8
call [con_write_asciiz]
jmp done
listen_err:
pushd 0x0c
call [con_set_flags]
push str3
call [con_write_asciiz]
jmp done
bind_err:
pushd 0x0c
call [con_set_flags]
push str4
call [con_write_asciiz]
jmp done
sock_err:
pushd 0x0c
call [con_set_flags]
push str6
call [con_write_asciiz]
jmp done
@ -147,9 +200,10 @@ exit:
; data
title db 'KolibriOS FTP daemon 0.1',0
str1 db 'Opening socket',10, 0
str2 db 'Listening for incoming connections...',10,0
title db 'KolibriOS FTP daemon 0.1', 0
str1 db 'Starting FTP daemon on port %u', 0
str2 db '.', 0
str2b db ' OK!',10,10,0
str3 db 'Listen error',10,10,0
str4 db 'Bind error',10,10,0
str5 db 'Setsockopt error.',10,10,0
@ -157,6 +211,9 @@ 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
filename db '.ini', 0
str_port db 'port', 0
str_ftpd db 'ftpd', 0
@ -186,7 +243,8 @@ import console, \
con_cls, 'con_cls',\
con_printf, 'con_printf',\
con_getch2, 'con_getch2',\
con_set_cursor_pos, 'con_set_cursor_pos'
con_set_cursor_pos, 'con_set_cursor_pos',\
con_set_flags, 'con_set_flags'
import libini, \
ini.get_str, 'ini_get_str',\
@ -208,9 +266,22 @@ socketnum dd ?
; thread specific data
socketnum2 dd ?
state dd ?
home_dir rb 1024
work_dir rb 1024
type db ?
mode db ? ; active/passive
buffer rb BUFFERSIZE
.length = BUFFERSIZE
datasocketnum dd ?
datasock:
dw AF_INET4
.port dw ?
.ip dd ?
rb 10
.length = $ - datasock
buffer rb BUFFERSIZE
.length = $ - buffer
path rb 1024
mem: