FTPd: closing of threads when client disconnects, main program now also exits when console is closed, + some other bugfixes

git-svn-id: svn://kolibrios.org@2624 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-04-17 20:00:07 +00:00
parent 9c870d827e
commit b4ebddc5ca
2 changed files with 56 additions and 32 deletions

View File

@ -17,6 +17,7 @@ struct thread_data
datasocketnum dd ? ; socket used for data transfers datasocketnum dd ? ; socket used for data transfers
permissions dd ? ; read/write/execute/.... permissions dd ? ; read/write/execute/....
buffer_ptr dd ? buffer_ptr dd ?
pid dd ? ; Process id of the current thread
datasock sockaddr_in datasock sockaddr_in
@ -452,7 +453,6 @@ cmdLIST:
.not_active: .not_active:
cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT
jne socketerror jne socketerror
mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail
.try_now: .try_now:
mov ecx, [ebp + thread_data.passivesocknum] mov ecx, [ebp + thread_data.passivesocknum]
lea edx, [ebp + thread_data.datasock] lea edx, [ebp + thread_data.datasock]
@ -460,6 +460,7 @@ cmdLIST:
mcall accept mcall accept
cmp eax, -1 cmp eax, -1
jne .pasv_ok jne .pasv_ok
mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail
mcall 23, 200 mcall 23, 200
mcall accept mcall accept
cmp eax, -1 cmp eax, -1
@ -572,11 +573,10 @@ cmdLIST:
; check next file ; check next file
invoke file.find.next, ebx invoke file.find.next, ebx
jmp .parse_file jmp .parse_file
;;; mov eax, ebx ;;;;;
; close file desc ; close file desc
.done: .done:
invoke file.find.close, ebx ; ebx is the invoke file.find.close, ebx ; ebx is descriptor of last file, eax will be -1 !!
; append the string with a 0 ; append the string with a 0
xor al, al xor al, al
@ -588,10 +588,10 @@ cmdLIST:
pop esi pop esi
; and send it to the client ; and send it to the client
mov ecx, [ebp + thread_data.datasocketnum] mov ecx, [ebp + thread_data.datasocketnum] ; socket num
lea edx, [ebp + thread_data.buffer] lea edx, [ebp + thread_data.buffer] ; buffer ptr
sub esi, edx sub esi, edx ; length
xor edi, edi xor edi, edi ; flags
mcall send mcall send
; close the data socket.. ; close the data socket..
@ -644,15 +644,14 @@ cmdPASS:
; read the password from users.ini ; read the password from users.ini
lea edi, [ebp + thread_data.buffer + 512] ; temp pass lea edi, [ebp + thread_data.buffer + 512] ; temp pass
mov byte [edi], 0
lea ebx, [ebp + thread_data.fpath] ; temp username lea ebx, [ebp + thread_data.fpath] ; temp username
invoke ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity invoke ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity
test eax, eax ; unable to read password? fail! test eax, eax ; unable to read password? fail!
jnz .incorrect jnz .incorrect
cmp dword [edi], -1 ; no key, section or file found.. fail! cmp dword [edi], -1 ; no key, section or file found.. fail!
je .incorrect je .incorrect
cmp byte [edi], 0 ; zero password? ok! ;;; cmp byte [edi], 0 ; zero password? ok!
je .ok ;;; je .ok
add esi, 5 add esi, 5
sub ecx, 5 sub ecx, 5

View File

@ -62,7 +62,6 @@ include '../libio.inc'
include '../network.inc' include '../network.inc'
include 'commands.inc' include 'commands.inc'
align 4
start: start:
mcall 68, 11 ; init heap mcall 68, 11 ; init heap
mcall 40, 1 shl 7 ; we only want network events mcall 40, 1 shl 7 ; we only want network events
@ -110,6 +109,7 @@ start:
mov [sockaddr1.port], ax mov [sockaddr1.port], ax
invoke con_printf, str1, eax invoke con_printf, str1, eax
add esp, 8
mcall socket, AF_INET4, SOCK_STREAM, 0 mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1 cmp eax, -1
@ -145,13 +145,26 @@ start:
mov [pasv_end], ax mov [pasv_end], ax
mainloop: mainloop:
mcall 10 ; Wait here for incoming connections on the base socket (socketnum) mcall 23, 100 ; Wait here for incoming connections on the base socket (socketnum)
; One second timeout, we sill use this to check if console is still working
test eax, 1 shl 7 ; network event?
jz .checkconsole
mcall 51, 1, threadstart, 0 ; Start a new thread for every incoming connection mcall 51, 1, threadstart, 0 ; Start a new thread for every incoming connection
; NOTE: upon initialisation of the thread, stack will not be available! ; NOTE: upon initialisation of the thread, stack will not be available!
jmp mainloop jmp mainloop
.checkconsole:
invoke con_get_flags ; Is console still running?
test eax, 0x0200
jz mainloop
mcall close, [socketnum] ; kill the listening socket
mcall -1 ; and exit
diff16 "threadstart", 0, $ diff16 "threadstart", 0, $
threadstart: threadstart:
;;; mcall 68, 11 ; init heap ;;; mcall 68, 11 ; init heap
mcall 68, 12, sizeof.thread_data ; allocate the thread data struct mcall 68, 12, sizeof.thread_data ; allocate the thread data struct
@ -163,8 +176,15 @@ threadstart:
mcall 40, 1 shl 7 ; we only want network events for this thread mcall 40, 1 shl 7 ; we only want network events for this thread
lea ebx, [ebp + thread_data.buffer] ; get information about the current process
or ecx, -1
mcall 9
mov eax, dword [ebp + thread_data.buffer + 30] ; PID is at offset 30
mov [ebp + thread_data.pid], eax
invoke con_set_flags, 0x03 invoke con_set_flags, 0x03
invoke con_write_asciiz, str8 ; print on the console that we have created the new thread successfully invoke con_printf, str8, [ebp + thread_data.pid] ; print on the console that we have created the new thread successfully
add esp, 8 ; balance stack
invoke con_set_flags, 0x07 invoke con_set_flags, 0x07
mcall accept, [socketnum], sockaddr1, sockaddr1.length ; time to accept the awaiting connection.. mcall accept, [socketnum], sockaddr1, sockaddr1.length ; time to accept the awaiting connection..
@ -181,12 +201,17 @@ threadstart:
sendFTP "220 Welcome to KolibriOS FTP daemon" sendFTP "220 Welcome to KolibriOS FTP daemon"
diff16 "threadloop", 0, $
threadloop: threadloop:
mcall 10 ; Check if our socket is still connected
mcall send, [ebp + thread_data.socketnum], 0, 0 ; Try to send zero bytes, if socket is closed, this will return -1
cmp eax, -1
je thread_exit
mcall 10 ; Wait for network event
cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT
jne .not_passive jne .not_passive
mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail
mov ecx, [ebp + thread_data.passivesocknum] mov ecx, [ebp + thread_data.passivesocknum]
lea edx, [ebp + thread_data.datasock] lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock mov esi, sizeof.thread_data.datasock
@ -250,42 +275,41 @@ sock_err:
jmp done jmp done
done: done:
invoke con_getch2 invoke con_exit, 0
invoke con_exit, 1
exit: exit:
mcall -1 mcall -1
thread_exit: thread_exit:
invoke con_set_flags, 0x02 ; print thread info in blue invoke con_set_flags, 0x03 ; print thread info in blue
invoke con_write_asciiz, str_bye invoke con_printf, str_bye, [ebp + thread_data.pid] ; print on the console that we are about to kill the thread
pop ecx ; get the thread_data pointer from stack add esp, 8 ; balance stack
mcall 68, 13 ; free the memory mcall 68, 13, ebp ; free the memory
mcall -1 ; and kill the thread mcall -1 ; and kill the thread
; initialized data ; initialized data
title db 'KolibriOS FTP daemon 0.1', 0 title db 'KolibriOS FTP daemon 0.1', 0
str1 db 'Starting FTP daemon on port %u', 0 str1 db 'Starting FTP daemon on port %u.', 0
str2 db '.', 0 str2 db '.', 0
str2b db ' OK!',10,0 str2b db ' OK!',10,0
str3 db 'Listen error',10,0 str3 db 'Listen error',10,0
str4 db 'Bind error',10,0 str4 db 10,'ERROR: local port is already in use.',10,0
;str5 db 'Setsockopt error.',10,10,0 ;str5 db 'Setsockopt error.',10,10,0
str6 db 'Could not open socket',10,0 str6 db 'ERROR: Could not open socket.',10,0
str7 db 'Got data!',10,10,0 str7 db 'Got data!',10,10,0
str8 db 10,'New thread created!',10,0 str8 db 10,'Thread %d created',10,0
str_bye db 10,'Closing thread!',10,0 str_bye db 10,'Thread %d killed',10,0
str_logged_in db 'Login ok',10,0 str_logged_in db 'Login ok',10,0
str_pass_ok db 'Password ok',10,0 str_pass_ok db 'Password ok',10,0
str_pass_err db 'Password/Username incorrect',10,0 str_pass_err db 'Password/Username incorrect',10,0
str_pwd db 'Current directory is "%s"\n',0 str_pwd db 'Current directory is "%s"\n',0
str_err2 db 'ERROR: cannot open directory',10,0 str_err2 db 'ERROR: cannot open the directory.',10,0
str_datasock db 'Passive data socket connected!',10,0 str_datasock db 'Passive data socket connected.',10,0
str_notfound db 'ERROR: file not found',10,0 str_notfound db 'ERROR: file not found.',10,0
str_sockerr db 'ERROR: socket error',10,0 str_sockerr db 'ERROR: socket error.',10,0
str_newline db 10, 0 str_newline db 10, 0
str_mask db '*', 0 str_mask db '*', 0
@ -346,7 +370,8 @@ import console,\
con_printf, 'con_printf',\ con_printf, 'con_printf',\
con_getch2, 'con_getch2',\ 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' con_set_flags, 'con_set_flags',\
con_get_flags, 'con_get_flags'
import libini,\ import libini,\
ini.get_str, 'ini_get_str',\ ini.get_str, 'ini_get_str',\