Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2608 → Rev 2609

/kernel/branches/net/applications/ftpd/commands.inc
26,7 → 26,7
macro sendFTP str {
local .string, .length, .label
xor edi, edi
mcall send, [edx + thread_data.socketnum], .string, .length
mcall send, [ebp + thread_data.socketnum], .string, .length
jmp @f
.string db str, 13, 10
.length = $ - .string
42,7 → 42,7
;
; input: esi = ptr to ascii commands
; ecx = number of bytes input
; edx = pointer to thread_data structure
; ebp = pointer to thread_data structure
;
; output: none
;
70,18 → 70,18
cmp eax, [edi]
je .got_it
 
add edi, 4+4*4
add edi, 5*4
cmp byte [edi], 0
jne .scanloop
 
.error:
cmp [edx + thread_data.state], STATE_ACTIVE
cmp [ebp + thread_data.state], STATE_ACTIVE
jb login_first
sendFTP "500 Unsupported command"
ret
 
.got_it:
mov eax, [edx + thread_data.state]
mov eax, [ebp + thread_data.state]
jmp dword [edi + 4 + eax]
 
 
88,72 → 88,39
align 4
commands: ; all commands must be in uppercase
 
dd 'ABOR'
dd login_first, login_first, login_first, cmdABOR
; dd 'ACCT
; dd login_first, login_first, login_first, cmd_ACCT
; dd 'APPE'
; dd login_first, login_first, login_first, cmd_APPE
dd 'CDUP'
dd login_first, login_first, login_first, cmdCDUP
dd 'CWD'
dd login_first, login_first, login_first, cmdCWD
dd 'DELE'
dd login_first, login_first, login_first, cmdDELE
; dd 'HELP'
; dd login_first, login_first, login_first, cmd_HELP
dd 'LIST'
dd login_first, login_first, login_first, cmdLIST
; dd 'MDTM'
; dd login_first, login_first, login_first, cmd_MDTM
; dd 'MKD'
; dd login_first, login_first, login_first, cmd_MKD
; dd 'MODE'
; dd login_first, login_first, login_first, cmd_MODE
dd 'NLST'
dd login_first, login_first, login_first, cmdNLST
dd 'NOOP'
dd login_first, login_first, login_first, cmdNOOP
dd 'PASS'
dd cmdPASS.0, cmdPASS , cmdPASS.2, cmdPASS.3
dd 'PASV'
dd login_first, login_first, login_first, cmdPASV
dd 'PORT'
dd login_first, login_first, login_first, cmdPORT
dd 'PWD'
dd login_first, login_first, login_first, cmdPWD
dd 'QUIT'
dd cmdQUIT, cmdQUIT, cmdQUIT, cmdQUIT
; dd 'REIN'
; dd login_first, login_first, login_first, cmd_REIN
; dd 'REST'
; dd login_first, login_first, login_first, cmd_REST
dd 'RETR'
dd login_first, login_first, login_first, cmdRETR
; dd 'RMD'
; dd login_first, login_first, login_first, cmd_RMD
; dd 'RNFR'
; dd login_first, login_first, login_first, cmd_RNFR
; dd 'RNTO'
; dd login_first, login_first, login_first, cmd_RNTO
; dd 'SITE'
; dd login_first, login_first, login_first, cmd_SITE
; dd 'SIZE'
; dd login_first, login_first, login_first, cmd_SIZE
; dd 'STAT'
; dd login_first, login_first, login_first, cmd_STAT
dd 'STOR'
dd login_first, login_first, login_first, cmdSTOR
; dd 'STOU'
; dd login_first, login_first, login_first, cmd_STOU
; dd 'STRU'
; dd login_first, login_first, login_first, cmd_STRU
dd 'SYST'
dd login_first, login_first, login_first, cmdSYST
dd 'TYPE'
dd login_first, login_first, login_first, cmdTYPE
dd 'USER'
dd cmdUSER, cmdUSER, cmdUSER, cmdUSER.2
dd 'ABOR', login_first, login_first, login_first, cmdABOR
; dd 'ACCT', login_first, login_first, login_first, cmd_ACCT
; dd 'APPE', login_first, login_first, login_first, cmd_APPE
dd 'CDUP', login_first, login_first, login_first, cmdCDUP
dd 'CWD', login_first, login_first, login_first, cmdCWD
dd 'DELE', login_first, login_first, login_first, cmdDELE
; dd 'HELP', login_first, login_first, login_first, cmd_HELP
dd 'LIST', login_first, login_first, login_first, cmdLIST
; dd 'MDTM', login_first, login_first, login_first, cmd_MDTM
; dd 'MKD', login_first, login_first, login_first, cmd_MKD
; dd 'MODE', login_first, login_first, login_first, cmd_MODE
dd 'NLST', login_first, login_first, login_first, cmdNLST
dd 'NOOP', login_first, login_first, login_first, cmdNOOP
dd 'PASS', cmdPASS.0, cmdPASS , cmdPASS.2, cmdPASS.3
dd 'PASV', login_first, login_first, login_first, cmdPASV
dd 'PORT', login_first, login_first, login_first, cmdPORT
dd 'PWD', login_first, login_first, login_first, cmdPWD
dd 'QUIT', cmdQUIT, cmdQUIT, cmdQUIT, cmdQUIT
; dd 'REIN', login_first, login_first, login_first, cmd_REIN
; dd 'REST', login_first, login_first, login_first, cmd_REST
dd 'RETR', login_first, login_first, login_first, cmdRETR
; dd 'RMD', login_first, login_first, login_first, cmd_RMD
; dd 'RNFR', login_first, login_first, login_first, cmd_RNFR
; dd 'RNTO', login_first, login_first, login_first, cmd_RNTO
; dd 'SITE', login_first, login_first, login_first, cmd_SITE
; dd 'SIZE', login_first, login_first, login_first, cmd_SIZE
; dd 'STAT', login_first, login_first, login_first, cmd_STAT
dd 'STOR', login_first, login_first, login_first, cmdSTOR
; dd 'STOU', login_first, login_first, login_first, cmd_STOU
; dd 'STRU', login_first, login_first, login_first, cmd_STRU
dd 'SYST', login_first, login_first, login_first, cmdSYST
dd 'TYPE', login_first, login_first, login_first, cmdTYPE
dd 'USER', cmdUSER, cmdUSER, cmdUSER, cmdUSER.2
db 0 ; end marker
 
align 4
177,12 → 144,11
 
align 4
abort_transfer:
and [edx + thread_data.permissions], not ABORT
mov [edx + thread_data.mode], MODE_NOTREADY
and [ebp + thread_data.permissions], not ABORT
mov [ebp + thread_data.mode], MODE_NOTREADY
invoke file.close, ebx
mcall close, [edx + thread_data.datasocketnum]
mcall close, [ebp + thread_data.datasocketnum]
 
mov edx, [ebp]
sendFTP "530 Transfer aborted"
ret
 
270,9 → 236,8
align 4
create_path: ; combine home_dir and work_dir strings into fpath
 
mov edx, [ebp]
lea edi, [edx + thread_data.fpath]
lea esi, [edx + thread_data.home_dir]
lea edi, [ebp + thread_data.fpath]
lea esi, [ebp + thread_data.home_dir]
mov ecx, 1024
.loop1:
lodsb
287,7 → 252,7
dec edi
@@:
 
lea esi, [edx + thread_data.work_dir]
lea esi, [ebp + thread_data.work_dir]
mov ecx, 1024
.loop2:
lodsb
310,7 → 275,7
align 4
cmdABOR:
 
or [edx + thread_data.permissions], ABORT
or [ebp + thread_data.permissions], ABORT
sendFTP "250 Command succesul"
ret
 
323,21 → 288,21
align 4
cmdCDUP:
 
test [edx + thread_data.permissions], PERMISSION_CD
test [ebp + thread_data.permissions], PERMISSION_CD
jz permission_denied
 
cmp byte [edx + thread_data.work_dir+1], 0 ; are we in "/" ?
cmp byte [ebp + thread_data.work_dir+1], 0 ; are we in "/" ?
je .done
 
mov ecx, 1024
xor al, al
lea edi, [edx + thread_data.work_dir]
lea edi, [ebp + thread_data.work_dir]
repne scasb
sub edi, 3
mov al,'/'
std
dec edi
dec edi
dec edi
mov al,'/'
neg ecx
add ecx, 1024
repne scasb
cld
mov byte[edi+1], 0
344,7 → 309,7
 
.done:
; Print the new working dir on the console
lea eax, [edx + thread_data.work_dir]
lea eax, [ebp + thread_data.work_dir]
push eax
call [con_write_asciiz]
push str_newline
362,7 → 327,7
align 4
cmdCWD:
 
test [edx + thread_data.permissions], PERMISSION_CD
test [ebp + thread_data.permissions], PERMISSION_CD
jz permission_denied
 
sub ecx, 4
369,8 → 334,13
jb .err
add esi, 4
 
mov ecx, 1024
lea edi, [ebp + thread_data.work_dir]
cmp byte [esi], '/'
je .loop
 
.scan:
lea edi, [edx + thread_data.work_dir + 1]
lea edi, [ebp + thread_data.work_dir + 1]
push ecx
mov ecx, 1024
.find_zero:
407,7 → 377,7
mov byte [edi], 0
 
; Print the new working dir on the console
lea eax, [edx + thread_data.work_dir]
lea eax, [ebp + thread_data.work_dir]
push eax
call [con_write_asciiz]
push str_newline
439,7 → 409,7
align 4
cmdDELE:
 
test [edx + thread_data.permissions], PERMISSION_DELETE
test [ebp + thread_data.permissions], PERMISSION_DELETE
jz permission_denied
 
ret
453,38 → 423,33
align 4
cmdLIST:
 
test [edx + thread_data.permissions], PERMISSION_EXEC
test [ebp + thread_data.permissions], PERMISSION_EXEC
jz permission_denied
 
; If we are in active mode, it's time to open a data socket..
cmp [edx + thread_data.mode], MODE_ACTIVE
cmp [ebp + thread_data.mode], MODE_ACTIVE
jne @f
mov ecx, [edx + thread_data.datasocketnum]
lea edx, [edx + thread_data.datasock]
mov ecx, [ebp + thread_data.datasocketnum]
lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock
mcall connect
cmp eax, -1
je socketerror
@@:
mov edx, [ebp]
 
; Create fpath from home_dir and work_dir
call create_path
 
lea ebx, [edx + thread_data.fpath]
lea ebx, [ebp + thread_data.fpath]
invoke con_write_asciiz, ebx
invoke con_write_asciiz, str_newline
 
 
mov edx, [ebp] ;;;
lea ebx, [edx + thread_data.fpath] ;;;;
; Start the search
invoke file.find.first, ebx, str_mask, FA_ANY
invoke file.find.first, ebx, str_mask, FA_READONLY+FA_FOLDER+FA_NORMAL+FA_ARCHIVED
test eax, eax
jz .nosuchdir
 
mov edx, [ebp] ;;;
lea edi, [edx + thread_data.buffer]
lea edi, [ebp + thread_data.buffer]
.parse_file:
test eax, eax ; did we find a file?
jz .done
566,17 → 531,17
mov ax, 0x0a0d
stosw
 
test [edx + thread_data.permissions], ABORT ; Did we receive ABOR command from client?
test [ebp + thread_data.permissions], ABORT ; Did we receive ABOR command from client?
;;; jnz .abort ; TODO
 
; check next file
;;; invoke file.find.next, ebx
;;; jmp .parse_file
mov eax, ebx ;;;;;
invoke file.find.next, ebx
jmp .parse_file
;;; mov eax, ebx ;;;;;
 
; close file desc
.done:
invoke file.find.close, eax ; file discriptor is still in eax at this point!
invoke file.find.close, ebx ; ebx is the
 
; append the string with a 0
xor al, al
584,22 → 549,19
 
; Warn the client we're about to send the data
push edi
mov edx, [ebp] ;;;;;;;
sendFTP "150 Here it comes.."
pop esi
 
; and send it to the client
mov edx, [ebp]
mov ecx, [edx + thread_data.datasocketnum]
lea edx, [edx + thread_data.buffer]
mov ecx, [ebp + thread_data.datasocketnum]
lea edx, [ebp + thread_data.buffer]
sub esi, edx
xor edi, edi
mcall send
 
; close the data socket..
mov edx, [ebp] ; thread_data pointer
mov [edx + thread_data.mode], MODE_NOTREADY
mcall close, [edx + thread_data.datasocketnum]
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
 
sendFTP "226 Transfer OK"
ret
617,7 → 579,7
align 4
cmdNLST:
 
test [edx + thread_data.permissions], PERMISSION_EXEC
test [ebp + thread_data.permissions], PERMISSION_EXEC
jz permission_denied
 
; TODO: same as list but simpler output format
647,8 → 609,8
lea esi, [esi + 5]
 
; read the password from users.ini
lea edi, [edx + thread_data.buffer + 512] ; temp pass
lea ebx, [edx + thread_data.fpath] ; temp username
lea edi, [ebp + thread_data.buffer + 512] ; temp pass
lea ebx, [ebp + thread_data.fpath] ; temp username
invoke ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity
test eax, eax
jnz .incorrect
666,17 → 628,16
 
.pass_ok:
invoke ini.get_int, path2, ebx, str_mode, 0
mov edx, [ebp] ; because libini destroys edx!
mov [edx + thread_data.permissions], eax
mov [ebp + thread_data.permissions], eax
 
invoke con_write_asciiz, str_pass_ok
mov [edx + thread_data.state], STATE_ACTIVE
mov [ebp + thread_data.state], STATE_ACTIVE
sendFTP "230 You are now logged in"
ret
 
.2:
.incorrect:
mov [edx + thread_data.state], STATE_CONNECTED
mov [ebp + thread_data.state], STATE_CONNECTED
sendFTP "530 Login incorrect"
ret
 
703,16 → 664,17
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
je socketerror
mov edx, [ebp] ; thread_data pointer
mov [edx + thread_data.passivesocknum], eax
mov [ebp + thread_data.passivesocknum], eax
 
; Bind it to a known local port
mov [edx + thread_data.datasock.sin_family], AF_INET4
mov [edx + thread_data.datasock.sin_port], 2000
mov [edx + thread_data.datasock.sin_addr], 0
mov [ebp + thread_data.datasock.sin_family], AF_INET4
pushw [pasvport]
popw [ebp + thread_data.datasock.sin_port]
inc [pasvport]
mov [ebp + thread_data.datasock.sin_addr], 0
 
mov ecx, eax ; passivesocketnum
lea edx, [edx + thread_data.datasock]
lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock
mcall bind
cmp eax, -1
724,8 → 686,7
; je listen_err ; TODO
 
; Tell our thread we are ready to accept incoming calls
mov edx, [ebp] ; thread_data pointer
mov [edx + thread_data.mode], MODE_PASSIVE_WAIT
mov [ebp + thread_data.mode], MODE_PASSIVE_WAIT
 
; Now tell the client where to connect to in this format:
; 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
732,7 → 693,7
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
 
; '227 ('
lea edi, [edx + thread_data.buffer]
lea edi, [ebp + thread_data.buffer]
mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000)
stosd
mov al, '('
755,11 → 716,11
mov al, ','
stosb
; port
mov eax, 7
movzx eax, byte [ebp + thread_data.datasock.sin_port + 1]
call dword_to_ascii
mov al, ','
stosb
mov eax, 208
movzx eax, byte [ebp + thread_data.datasock.sin_port]
call dword_to_ascii
; ')', 13, 10, 0
mov eax, ')' + 0x000a0d00
766,9 → 727,9
stosd
 
lea esi, [edi - thread_data.buffer]
sub esi, edx
mov ecx, [edx + thread_data.socketnum]
lea edx, [edx + thread_data.buffer]
sub esi, ebp
mov ecx, [ebp + thread_data.socketnum]
lea edx, [ebp + thread_data.buffer]
xor edi, edi
mcall send
 
783,11 → 744,11
align 4
cmdPWD:
 
mov dword [edx + thread_data.buffer], '257 '
mov byte [edx + thread_data.buffer+4], '"'
mov dword [ebp + thread_data.buffer], '257 '
mov byte [ebp + thread_data.buffer+4], '"'
 
lea edi, [edx + thread_data.buffer+5]
lea esi, [edx + thread_data.work_dir]
lea edi, [ebp + thread_data.buffer+5]
lea esi, [ebp + thread_data.work_dir]
mov ecx, 1024
.loop:
lodsb
800,15 → 761,14
.ok:
mov dword [edi], '"' + 0x000a0d00 ; '"',13,10,0
lea esi, [edi - thread_data.buffer + 4]
sub esi, edx
mov ecx, [edx + thread_data.socketnum]
lea edx, [edx + thread_data.buffer]
sub esi, ebp
mov ecx, [ebp + thread_data.socketnum]
lea edx, [ebp + thread_data.buffer]
xor edi, edi
mcall send
 
mov edx, [ebp]
; Print the new working dir on the console
lea eax, [edx + thread_data.work_dir]
lea eax, [ebp + thread_data.work_dir]
invoke con_write_asciiz, eax
invoke con_write_asciiz, str_newline
 
831,8 → 791,7
mov cl, ','
call ip_to_dword
; And put it in datasock
;;; mov edx, [ebp]
mov [edx + thread_data.datasock.sin_addr], ebx
mov [ebp + thread_data.datasock.sin_addr], ebx
 
; Now the same with portnumber
inc esi
843,17 → 802,16
mov bl, al
 
; Save it in datasock too
mov [edx + thread_data.datasock.sin_port], bx
mov [ebp + thread_data.datasock.sin_port], bx
 
; We will open the socket, but do not connect yet!
mov [edx + thread_data.datasock.sin_family], AF_INET4
mov [ebp + thread_data.datasock.sin_family], AF_INET4
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
je socketerror
 
mov edx, [ebp] ; thread_data pointer
mov [edx + thread_data.datasocketnum], eax
mov [edx + thread_data.mode], MODE_ACTIVE
mov [ebp + thread_data.datasocketnum], eax
mov [ebp + thread_data.mode], MODE_ACTIVE
 
sendFTP "225 Data connection open"
ret
868,9 → 826,8
cmdQUIT:
 
sendFTP "221 Bye!"
mov edx, [ebp]
mcall close, [edx + thread_data.datasocketnum]
mcall close, [edx + thread_data.socketnum]
mcall close, [ebp + thread_data.datasocketnum]
mcall close, [ebp + thread_data.socketnum]
 
add esp, 4 ; get rid of call return address
jmp thread_exit ; now close this thread
885,7 → 842,7
align 4
cmdRETR:
 
test [edx + thread_data.permissions], PERMISSION_READ
test [ebp + thread_data.permissions], PERMISSION_READ
jz permission_denied
 
cmp ecx, 1024 + 5
894,11 → 851,11
sub ecx, 5
jb .cannot_open
 
cmp [edx + thread_data.mode], MODE_ACTIVE
cmp [ebp + thread_data.mode], MODE_ACTIVE
jne @f
push ecx esi
mov ecx, [edx + thread_data.datasocketnum]
lea edx, [edx + thread_data.datasock]
mov ecx, [ebp + thread_data.datasocketnum]
lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock
mcall connect
pop esi ecx
922,7 → 879,7
xor al, al
stosb
 
lea ebx, [edx + thread_data.fpath]
lea ebx, [ebp + thread_data.fpath]
invoke con_write_asciiz, ebx
invoke con_write_asciiz, str_newline
 
931,16 → 888,14
jz .cannot_open
 
push eax
mov edx, [ebp]
sendFTP "150 Here it comes.."
pop ebx
 
.read_more:
mov edx, [ebp]
test [edx + thread_data.permissions], ABORT
test [ebp + thread_data.permissions], ABORT
jnz abort_transfer
 
lea eax, [edx + thread_data.buffer] ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
lea eax, [ebp + thread_data.buffer] ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
invoke file.read, ebx, eax, BUFFERSIZE
cmp eax, -1
je .cannot_open ; FIXME: this is not the correct error
947,13 → 902,13
 
push eax ebx
mov esi, eax
mov ecx, [edx + thread_data.datasocketnum]
lea edx, [edx + thread_data.buffer]
xor esi, esi
mov ecx, [ebp + thread_data.datasocketnum]
lea edx, [ebp + thread_data.buffer]
xor edi, edi
mcall send
pop ebx ecx
cmp eax, -1
je socketerror
je socketerror ; FIXME: not the correct error
 
; cmp eax, ecx
; jne not_all_byes_sent ; TODO
963,11 → 918,9
 
invoke file.close, ebx
 
mov edx, [ebp]
mov [edx + thread_data.mode], MODE_NOTREADY
mcall close, [edx + thread_data.datasocketnum]
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
 
mov edx, [ebp]
sendFTP "226 Transfer OK, closing connection"
ret
 
991,12 → 944,12
align 4
cmdSTOR:
 
test [edx + thread_data.permissions], PERMISSION_WRITE
test [ebp + thread_data.permissions], PERMISSION_WRITE
jz permission_denied
 
 
;;;;
test [edx + thread_data.permissions], ABORT
test [ebp + thread_data.permissions], ABORT
jnz abort_transfer
 
;;;;
1042,11 → 995,11
jmp parse_cmd.error
 
.ascii:
mov [edx + thread_data.type], TYPE_ASCII
mov [ebp + thread_data.type], TYPE_ASCII
jmp .subtype
 
.ebdic:
mov [edx + thread_data.type], TYPE_EBDIC
mov [ebp + thread_data.type], TYPE_EBDIC
 
.subtype:
cmp ecx, 8
1065,19 → 1018,19
jmp parse_cmd.error
 
.non_print:
or [edx + thread_data.type], TYPE_NP
or [ebp + thread_data.type], TYPE_NP
jmp .ok
 
.telnet:
or [edx + thread_data.type], TYPE_TELNET
or [ebp + thread_data.type], TYPE_TELNET
jmp .ok
 
.asacc:
or [edx + thread_data.type], TYPE_ASA
or [ebp + thread_data.type], TYPE_ASA
jmp .ok
 
.image:
mov [edx + thread_data.type], TYPE_IMAGE
mov [ebp + thread_data.type], TYPE_IMAGE
jmp .ok
 
.local:
1090,7 → 1043,7
cmp al, 9
ja parse_cmd.error ; FIXME
or al, TYPE_LOCAL
mov [edx + thread_data.type], al
mov [ebp + thread_data.type], al
 
.ok:
sendFTP "200 Command ok"
1106,7 → 1059,7
cmdUSER:
 
lea esi, [esi + 5]
lea edi, [edx + thread_data.fpath] ; temp buffer for username
lea edi, [ebp + thread_data.fpath] ; temp buffer for username
.loop:
lodsb
stosb
1114,8 → 1067,8
jae .loop
mov byte [edi-1], 0
 
lea esi, [edx + thread_data.fpath]
lea eax, [edx + thread_data.home_dir]
lea esi, [ebp + thread_data.fpath]
lea eax, [ebp + thread_data.home_dir]
invoke ini.get_str, path2, esi, str_home, eax, 1024, str_infinity
cmp eax, -1
je .login_fail
1122,10 → 1075,10
cmp dword [esi], -1
je .login_fail
 
mov word [edx + thread_data.work_dir], "/" ; "/", 0
mov word [ebp + thread_data.work_dir], "/" ; "/", 0
 
invoke con_write_asciiz, str_logged_in
mov [edx + thread_data.state], STATE_LOGIN
mov [ebp + thread_data.state], STATE_LOGIN
.sendstr:
sendFTP "331 Please specify the password"
ret
1132,7 → 1085,7
 
.login_fail:
invoke con_write_asciiz, str_login_invalid
mov [edx + thread_data.state], STATE_LOGIN_FAIL
mov [ebp + thread_data.state], STATE_LOGIN_FAIL
jmp .sendstr
 
align 4
/kernel/branches/net/applications/ftpd/ftpd.asm
64,13 → 64,14
 
align 4
start:
mcall 68, 11 ; init heap
mcall 40, 1 shl 7 ; we only want network events
 
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
 
mcall 68, 11 ; init heap
 
; find path to main settings file (ftpd.ini)
mov edi, path ; Calculate the length of zero-terminated string
xor al, al
99,8 → 100,6
invoke con_start, 1
invoke con_init, -1, -1, -1, -1, title
 
mcall 40, 1 shl 7 ; we only want network events
 
invoke ini.get_str, path, str_ftpd, str_ip, ini_buf, 16, 0
mov esi, ini_buf
call ip_to_dword
139,6 → 138,8
 
invoke con_write_asciiz, str2b
 
mov [pasvport], 2000 ;;;;;; FIXME
 
mainloop:
mcall 10 ; Wait here for incoming connections on the base socket (socketnum)
 
148,13 → 149,13
 
diff16 "threadstart", 0, $
threadstart:
;;; mcall 68, 11 ; init heap
mcall 68, 12, sizeof.thread_data ; allocate the thread data struct
cmp eax, -1
test eax, eax
je exit
 
lea esp, [eax + thread_data.stack] ; init stack
push eax ; save pointer to thread_data on stack
mov ebp, esp
mov ebp, eax
 
mcall 40, 1 shl 7 ; we only want network events for this thread
 
165,14 → 166,13
mcall accept, [socketnum], sockaddr1, sockaddr1.length ; time to accept the awaiting connection..
cmp eax, -1
je thread_exit
mov edx, [ebp] ; pointer to thread_data
mov [edx + thread_data.socketnum], eax
mov [ebp + thread_data.socketnum], eax
 
mov [edx + thread_data.state], STATE_CONNECTED
mov [edx + thread_data.permissions], 0
mov [edx + thread_data.mode], MODE_NOTREADY
lea eax, [edx + thread_data.buffer]
mov [edx + thread_data.buffer_ptr], eax
mov [ebp + thread_data.state], STATE_CONNECTED
mov [ebp + thread_data.permissions], 0
mov [ebp + thread_data.mode], MODE_NOTREADY
lea eax, [ebp + thread_data.buffer]
mov [ebp + thread_data.buffer_ptr], eax
 
sendFTP "220 Welcome to KolibriOS FTP daemon"
 
180,24 → 180,23
mcall 10
mov edx, [ebp] ; pointer to thread_data
 
cmp [edx + thread_data.mode], MODE_PASSIVE_WAIT
cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT
jne .not_passive
mov [edx + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail
mov ecx, [edx + thread_data.passivesocknum]
lea edx, [edx + thread_data.datasock]
mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail
mov ecx, [ebp + thread_data.passivesocknum]
lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock
mcall accept
mov edx, [ebp] ; pointer to thread_data
cmp eax, -1
je .not_passive
mov [edx + thread_data.datasocketnum], eax
mov [edx + thread_data.mode], MODE_PASSIVE_OK
mov [ebp + thread_data.datasocketnum], eax
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
 
invoke con_write_asciiz, str_datasock
.not_passive:
 
mov ecx, [edx + thread_data.socketnum]
mov edx, [edx + thread_data.buffer_ptr]
mov ecx, [ebp + thread_data.socketnum]
mov edx, [ebp + thread_data.buffer_ptr]
mov esi, sizeof.thread_data.buffer ;;; FIXME
mcall recv
inc eax ; error? (-1)
205,9 → 204,8
dec eax ; 0 bytes read?
jz threadloop
 
mov edx, [ebp] ; pointer to thread_data
mov edi, [edx + thread_data.buffer_ptr]
add [edx + thread_data.buffer_ptr], eax
mov edi, [ebp + thread_data.buffer_ptr]
add [ebp + thread_data.buffer_ptr], eax
 
; Check if we received a newline character, if not, wait for more data
mov ecx, eax
217,10 → 215,10
 
; We got a command!
mov byte [edi + 1], 0 ; append string with zero byte
lea esi, [edx + thread_data.buffer]
mov ecx, [edx + thread_data.buffer_ptr]
lea esi, [ebp + thread_data.buffer]
mov ecx, [ebp + thread_data.buffer_ptr]
sub ecx, esi
mov [edx + thread_data.buffer_ptr], esi ; reset buffer ptr
mov [ebp + thread_data.buffer_ptr], esi ; reset buffer ptr
 
invoke con_set_flags, 0x02 ; print received data to console (in green color)
invoke con_write_asciiz, str_newline
285,6 → 283,8
 
str_login_invalid db 'Login invalid',10,0
 
str_test db 'test: %x ', 0
 
str_newline db 10, 0
str_mask db '*', 0
str_infinity db 0xff, 0xff, 0xff, 0xff, 0
325,6 → 325,8
align 4
@IMPORT:
 
diff16 "import", 0, $
 
library console, 'console.obj',\
libini, 'libini.obj', \
libio, 'libio.obj'
358,6 → 360,8
 
i_end:
 
diff16 "i_end", 0, $
 
; uninitialised data
 
socketnum dd ?
365,6 → 369,7
path2 rb 1024
params rb 1024
serverip dd ?
pasvport dw ?
 
ini_buf rb 3*4+3+1
 
/kernel/branches/net/applications/ftpd/ftpd.ini
1,4 → 1,8
[ftpd]
port=21
conn=10
ip=127.0.0.1
ip=127.0.0.1
 
[pasv]
start=2000
end=5000