From b4ebddc5ca746fd4ec05d9d6a161b453143e3f68 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Tue, 17 Apr 2012 20:00:07 +0000 Subject: [PATCH] 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 --- .../net/applications/ftpd/commands.inc | 19 +++-- .../branches/net/applications/ftpd/ftpd.asm | 69 +++++++++++++------ 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/kernel/branches/net/applications/ftpd/commands.inc b/kernel/branches/net/applications/ftpd/commands.inc index c1252f48aa..fb828c9594 100644 --- a/kernel/branches/net/applications/ftpd/commands.inc +++ b/kernel/branches/net/applications/ftpd/commands.inc @@ -17,6 +17,7 @@ struct thread_data datasocketnum dd ? ; socket used for data transfers permissions dd ? ; read/write/execute/.... buffer_ptr dd ? + pid dd ? ; Process id of the current thread datasock sockaddr_in @@ -452,7 +453,6 @@ cmdLIST: .not_active: cmp [ebp + thread_data.mode], MODE_PASSIVE_WAIT jne socketerror - mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail .try_now: mov ecx, [ebp + thread_data.passivesocknum] lea edx, [ebp + thread_data.datasock] @@ -460,6 +460,7 @@ cmdLIST: mcall accept cmp eax, -1 jne .pasv_ok + mov [ebp + thread_data.mode], MODE_PASSIVE_FAILED ; assume that we will fail mcall 23, 200 mcall accept cmp eax, -1 @@ -572,11 +573,10 @@ cmdLIST: ; check next file invoke file.find.next, ebx jmp .parse_file -;;; mov eax, ebx ;;;;; ; close file desc .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 xor al, al @@ -588,10 +588,10 @@ cmdLIST: pop esi ; and send it to the client - mov ecx, [ebp + thread_data.datasocketnum] - lea edx, [ebp + thread_data.buffer] - sub esi, edx - xor edi, edi + mov ecx, [ebp + thread_data.datasocketnum] ; socket num + lea edx, [ebp + thread_data.buffer] ; buffer ptr + sub esi, edx ; length + xor edi, edi ; flags mcall send ; close the data socket.. @@ -644,15 +644,14 @@ cmdPASS: ; read the password from users.ini lea edi, [ebp + thread_data.buffer + 512] ; temp pass - mov byte [edi], 0 lea ebx, [ebp + thread_data.fpath] ; temp username invoke ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity test eax, eax ; unable to read password? fail! jnz .incorrect cmp dword [edi], -1 ; no key, section or file found.. fail! je .incorrect - cmp byte [edi], 0 ; zero password? ok! - je .ok +;;; cmp byte [edi], 0 ; zero password? ok! +;;; je .ok add esi, 5 sub ecx, 5 diff --git a/kernel/branches/net/applications/ftpd/ftpd.asm b/kernel/branches/net/applications/ftpd/ftpd.asm index db3f31a22e..1e61015f69 100644 --- a/kernel/branches/net/applications/ftpd/ftpd.asm +++ b/kernel/branches/net/applications/ftpd/ftpd.asm @@ -62,7 +62,6 @@ include '../libio.inc' include '../network.inc' include 'commands.inc' -align 4 start: mcall 68, 11 ; init heap mcall 40, 1 shl 7 ; we only want network events @@ -110,6 +109,7 @@ start: mov [sockaddr1.port], ax invoke con_printf, str1, eax + add esp, 8 mcall socket, AF_INET4, SOCK_STREAM, 0 cmp eax, -1 @@ -145,13 +145,26 @@ start: mov [pasv_end], ax 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 ; NOTE: upon initialisation of the thread, stack will not be available! 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, $ + threadstart: ;;; mcall 68, 11 ; init heap 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 + 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_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 mcall accept, [socketnum], sockaddr1, sockaddr1.length ; time to accept the awaiting connection.. @@ -181,12 +201,17 @@ threadstart: sendFTP "220 Welcome to KolibriOS FTP daemon" + diff16 "threadloop", 0, $ 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 jne .not_passive - 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 @@ -250,42 +275,41 @@ sock_err: jmp done done: - invoke con_getch2 - invoke con_exit, 1 + invoke con_exit, 0 exit: mcall -1 thread_exit: - invoke con_set_flags, 0x02 ; print thread info in blue - invoke con_write_asciiz, str_bye - pop ecx ; get the thread_data pointer from stack - mcall 68, 13 ; free the memory - mcall -1 ; and kill the thread + invoke con_set_flags, 0x03 ; print thread info in blue + invoke con_printf, str_bye, [ebp + thread_data.pid] ; print on the console that we are about to kill the thread + add esp, 8 ; balance stack + mcall 68, 13, ebp ; free the memory + mcall -1 ; and kill the thread ; initialized data 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 str2b db ' OK!',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 -str6 db 'Could not open socket',10,0 +str6 db 'ERROR: Could not open socket.',10,0 str7 db 'Got data!',10,10,0 -str8 db 10,'New thread created!',10,0 -str_bye db 10,'Closing thread!',10,0 +str8 db 10,'Thread %d created',10,0 +str_bye db 10,'Thread %d killed',10,0 str_logged_in db 'Login ok',10,0 str_pass_ok db 'Password ok',10,0 str_pass_err db 'Password/Username incorrect',10,0 str_pwd db 'Current directory is "%s"\n',0 -str_err2 db 'ERROR: cannot open directory',10,0 -str_datasock db 'Passive data socket connected!',10,0 -str_notfound db 'ERROR: file not found',10,0 -str_sockerr db 'ERROR: socket error',10,0 +str_err2 db 'ERROR: cannot open the directory.',10,0 +str_datasock db 'Passive data socket connected.',10,0 +str_notfound db 'ERROR: file not found.',10,0 +str_sockerr db 'ERROR: socket error.',10,0 str_newline db 10, 0 str_mask db '*', 0 @@ -346,7 +370,8 @@ import console,\ con_printf, 'con_printf',\ con_getch2, 'con_getch2',\ 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,\ ini.get_str, 'ini_get_str',\