forked from KolibriOS/kolibrios
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:
parent
9d73147338
commit
742df45545
@ -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
|
||||
str550 db '550 No such file', 13, 10
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user