From 0d44338d5d4a62b3e5bf79439aec4e1eda15776b Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Fri, 6 Apr 2012 18:37:00 +0000 Subject: [PATCH] Added multithread-capabilities to FTPd (net branch) git-svn-id: svn://kolibrios.org@2578 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../net/applications/ftpd/commands.inc | 355 +++++++++++------- .../branches/net/applications/ftpd/ftpd.asm | 255 +++++++------ 2 files changed, 356 insertions(+), 254 deletions(-) diff --git a/kernel/branches/net/applications/ftpd/commands.inc b/kernel/branches/net/applications/ftpd/commands.inc index a88d034d0b..ff4cd055fe 100644 --- a/kernel/branches/net/applications/ftpd/commands.inc +++ b/kernel/branches/net/applications/ftpd/commands.inc @@ -1,9 +1,40 @@ +struct thread_data + rb 1024 + stack rb 0 + + home_dir rb 1024 + work_dir rb 1024 + fpath rb 1024*3 + + type db ? ; ASCII/EBDIC/IMAGE/.. + mode db ? ; active/passive + socketnum dd ? ; Commands socket + state dd ? ; disconnected/logging in/logged in/.. + passivesocknum dd ? ; when in passive mode, this is the listening socket + datasocketnum dd ? ; socket used for data transfers + + datasock sockaddr_in + + buffer rb BUFFERSIZE +ends + + + align 4 parse_cmd: ; esi must point to command + cmp byte [esi], 0x20 ; skip all leading characters + ja .ok + inc esi + dec ecx + cmp ecx, 3 + ja parse_cmd + ret + .ok: + cmp byte [esi+3], 0x20 jae @f mov byte [esi+3], 0 @@ -24,7 +55,7 @@ parse_cmd: ; esi must point to command jne .scanloop .error: - mcall send, [socketnum2], str500, str500.length, 0 + mcall send, [edx + thread_data.socketnum], str500, str500.length, 0 ret @@ -74,17 +105,19 @@ commands: ; all commands must be in uppercase align 4 cmdABOR: + ; TODO: abort the current filetransfer + ret align 4 cmdCDUP: - cmp byte [work_dir+1], 0 + cmp byte [edx + thread_data.work_dir+1], 0 je .done mov ecx, 1024 xor al, al - mov edi, work_dir+1024 + lea edi, [edx + thread_data.work_dir+1024] repne scasb std dec edi @@ -94,9 +127,7 @@ cmdCDUP: mov byte[edi], 0 .done: - mcall send, [socketnum2], str250, str250.length, 0 ; command successful - - + mcall send, [edx + thread_data.socketnum], str250, str250.length, 0 ; command successful ret align 4 @@ -107,7 +138,16 @@ cmdCWD: ; Change Working Directory add esi, 4 .scan: - mov edi, work_dir + 1 + lea edi, [edx + thread_data.work_dir + 1] + push ecx + mov ecx, 1024 + .find_zero: + cmp byte [edi], 0 + je .found_zero + inc edi + loop .find_zero + .found_zero: + pop ecx cmp byte [esi], '/' jne @f @@ -133,7 +173,7 @@ cmdCWD: ; Change Working Directory @@: mov byte [edi], 0 - mcall send, [socketnum2], str250, str250.length, 0 + mcall send, [edx + thread_data.socketnum], str250, str250.length, 0 ret @@ -142,10 +182,11 @@ cmdCWD: ; Change Working Directory cmp al, '.' jne .continue - call cmdCDUP +;;;; call cmdCDUP ;;;;;; FIXME jmp .scan .err: + ; TODO: print correct error message (550?) ret @@ -158,18 +199,23 @@ align 4 cmdLIST: ; If we are in active mode, it's time to open a data socket.. - cmp [mode], MODE_ACTIVE + cmp [edx + thread_data.mode], MODE_ACTIVE jne @f - mcall connect, [datasocketnum], datasock, datasock.length + mov ecx, [edx + thread_data.datasocketnum] + lea edx, [edx + thread_data.datasock] + mov esi, sizeof.thread_data.datasock + mcall connect + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 je socketerror - mov [datasocketnum], eax + mov [edx + thread_data.datasocketnum], eax @@: ; Create fpath from home_dir and work_dir call create_path - push fpath + lea eax, [edx + thread_data.fpath] + push eax call [con_write_asciiz] push str_newline call [con_write_asciiz] @@ -177,21 +223,24 @@ cmdLIST: ; Start the search push FA_ANY push str_mask - push fpath + lea eax, [edx + thread_data.fpath] + push eax call [file.find.first] - mov edi, buffer + test eax, eax + jz .nosuchdir + + lea edi, [edx + thread_data.buffer] .parse_file: test eax, eax ; did we find a file? jz .done - - mov edx, eax ; yes, save the descripter + mov ebx, eax ; yes, save the descripter in ebx ; first, convert the attributes - test [edx + FileInfoA.Attributes], FA_FOLDER + test [ebx + FileInfoA.Attributes], FA_FOLDER jnz .folder - test [edx + FileInfoA.Attributes], FA_READONLY + test [ebx + FileInfoA.Attributes], FA_READONLY jnz .readonly mov eax, '-rw-' @@ -225,32 +274,32 @@ cmdLIST: stosd ; now the filesize in ascii - mov ebx, [edx + FileInfoA.FileSizeLow] + mov eax, [ebx + FileInfoA.FileSizeLow] call dword_to_ascii mov al, ' ' stosb ; then date (month/day/year) - movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.month] - mov eax, [months + 4*ebx] + movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.month] + mov eax, [months + 4*eax] stosd - movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.day] + movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.day] call dword_to_ascii mov al, ' ' stosb - movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.year] + movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.year] call dword_to_ascii mov al, ' ' stosb ; and last but not least, filename - lea esi, [edx + FileInfoA.FileName] - mov ecx, 250 + lea esi, [ebx + FileInfoA.FileName] + mov ecx, 264 .nameloop: lodsb test al, al @@ -264,13 +313,13 @@ cmdLIST: stosw ; check next file - push edx + push ebx call [file.find.next] jmp .parse_file ; close file desc .done: - push edx + push ebx call [file.find.close] ; append the string with a 0 @@ -278,22 +327,33 @@ cmdLIST: stosb ; Warn the client we're about to send the data - mcall send, [socketnum2], str150, str150.length, 0 ; here it comes.. + push edi edx + mcall send, [edx + thread_data.socketnum], str150, str150.length, 0 ; here it comes.. + pop edx esi ; and send it to the client - lea esi, [edi - buffer] - mcall send, [datasocketnum], buffer, , 0 + mov ecx, [edx + thread_data.datasocketnum] + lea edx, [edx + thread_data.buffer] + sub esi, edx + xor edi, edi + mcall send ; close the data socket.. - mcall close, [datasocketnum] + mov edx, [esp+4] ; thread_data pointer + mcall close, [edx + thread_data.datasocketnum] - cmp [mode], MODE_PASSIVE_OK + cmp [edx + thread_data.mode], MODE_PASSIVE_OK jne @f - mov [mode], MODE_PASSIVE_WAIT + mov [edx + thread_data.mode], MODE_NOTREADY @@: ; And send "transfer ok" on the base connection - mcall send, [socketnum2], str226, str226.length, 0 + mcall send, [edx + thread_data.socketnum], str226, str226.length, 0 + + ret + + .nosuchdir: + mcall send, [edx + thread_data.socketnum], str550, str550.length, 0 ret @@ -301,6 +361,8 @@ cmdLIST: align 4 cmdNLST: + ; TODO: same as list but simpler output format + ret align 4 @@ -311,38 +373,51 @@ cmdNOOP: align 4 cmdPASS: - mcall send, [socketnum2], str230, str230.length, 0 + ; TODO: verify password + + mcall send, [edx + thread_data.socketnum], str230, str230.length, 0 push str_pass_ok call [con_write_asciiz] - mov [state], STATE_ACTIVE + mov edx, [esp+4] ; thread_data pointer + mov [edx + thread_data.state], STATE_ACTIVE ret align 4 cmdPASV: -; 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. - +; Open a new TCP socket mcall socket, AF_INET4, SOCK_STREAM, 0 + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 -; je .err - mov [passivesocknum], eax + je socketerror + mov [edx + thread_data.passivesocknum], eax - mov [datasock.port], 2000 - mov [datasock.ip], 0 +; 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 - mcall bind, [passivesocknum], datasock, datasock.length + mov ecx, eax ;[edx + thread_data.passivesocknum] + lea edx, [edx + thread_data.datasock] + mcall bind, , , sizeof.thread_data.datasock + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 je bind_err - mcall listen, [passivesocknum], 1 +; And set it to listen! + mcall listen, [edx + thread_data.passivesocknum], 10 ;;;;; FIXME - mov [mode], MODE_PASSIVE_WAIT +; Tell our thread we are ready to accept incoming calls + mov edx, [esp+4] ; thread_data pointer + mov [edx + thread_data.mode], MODE_PASSIVE_WAIT - mov edi, buffer +; Now tell the client where to connect to in this format: +; 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. + lea edi, [edx + thread_data.buffer] mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000) stosd mov eax, '(127' @@ -360,20 +435,22 @@ cmdPASV: xor al, al stosb - lea esi, [edi - buffer] - - mcall send, [socketnum2], buffer, ,0 + lea esi, [edi - thread_data.buffer] + sub esi, edx + mov ecx, [edx + thread_data.socketnum] + lea edx, [edx + thread_data.buffer] + mcall send, , , ,0 ret align 4 cmdPWD: ; Print Working Directory - mov dword[buffer], '257 ' - mov byte[buffer+4], '"' + mov dword [edx + thread_data.buffer], '257 ' + mov byte [edx + thread_data.buffer+4], '"' - lea edi, [buffer+5] - mov esi, work_dir + lea edi, [edx + thread_data.buffer+5] + lea esi, [edx + thread_data.work_dir] mov ecx, 1024 .loop: lodsb @@ -384,10 +461,12 @@ cmdPWD: ; Print Working Directory jnz .loop .ok: - mov dword[edi], '"' + 0x000a0d00 ; '"',13,10,0 - lea esi, [edi - buffer + 4] - - mcall send, [socketnum2], buffer, , 0 + 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] + mcall send, , , , 0 ; push work_dir ; push str_pwd @@ -401,55 +480,59 @@ cmdPORT: ; PORT a1,a2,a3,a4,p1,p2 ; IP address a1.a2.a3.a4, port p1*256+p2 - mov [mode], MODE_ACTIVE + mov [edx + thread_data.mode], MODE_ACTIVE lea esi, [esi+5] - xor edx, edx - +; Convert the IP call ascii_to_byte - mov dh, bl + mov bh, al + inc esi ; skip past ',' + call ascii_to_byte + mov bl, al + shl ebx, 16 inc esi call ascii_to_byte - mov dl, bl - shl edx, 16 + mov bh, al inc esi call ascii_to_byte - mov dh, bl - inc esi - call ascii_to_byte - mov dl, bl + mov bl, al inc esi - mov [datasock.ip], edx +; And put it in datasock + mov [edx + thread_data.datasock.sin_addr], ebx +; Now the same with portnumber call ascii_to_byte - mov dh, bl + mov bh, al inc esi call ascii_to_byte - mov dl, bl + mov bl, al - mov [datasock.port], dx +; Save it in datasock too + mov [edx + 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 mcall socket, AF_INET4, SOCK_STREAM, 0 + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 - je .err - mov [datasocketnum], eax + je socketerror + mov [edx + thread_data.datasocketnum], eax - mcall send, [socketnum2], str225, str225.length, 0 +; Tell the client we are ready + mov edx, [esp+4] ; thread_data pointer + mcall send, [edx + thread_data.socketnum], str225, str225.length, 0 ret - .err: - - mcall send, [socketnum2], str425, str425.length, 0 - ret align 4 cmdQUIT: - mcall send, [socketnum2], str221, str221.length, 0 - mcall close, [socketnum2] + mcall close, [edx + thread_data.datasocketnum] + mcall send, [edx + thread_data.socketnum], str221, str221.length, 0 ; 221 - bye! + mcall close;, [edx + thread_data.socketnum] - ret + jmp thread_exit ; now close this thread align 4 cmdRETR: @@ -457,14 +540,17 @@ cmdRETR: sub ecx, 5 jb .cannot_open - cmp [mode], MODE_ACTIVE + cmp [edx + thread_data.mode], MODE_ACTIVE jne @f push esi - mcall connect, [datasocketnum], datasock, datasock.length + mov ecx, [edx + thread_data.datasocketnum] + lea edx, [edx + thread_data.datasock] + mcall connect, , , sizeof.thread_data.datasock pop esi + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 je socketerror - mov [datasocketnum], eax + mov [edx + thread_data.datasocketnum], eax @@: push esi @@ -483,24 +569,28 @@ cmdRETR: xor al, al stosb - push fpath + lea eax, [edx + thread_data.fpath] + push eax call [con_write_asciiz] push str_newline call [con_write_asciiz] push O_READ - push fpath + lea eax, [edx + thread_data.fpath] + push eax call [file.open] test eax, eax jz .cannot_open push eax - mcall send, [socketnum2], str150, str150.length, 0 ; here it comes.. + mcall send, [edx + thread_data.socketnum], str150, str150.length, 0 ; here it comes.. pop ebx + mov edx, [esp+4] ; thread_data pointer .read_more: push BUFFERSIZE - push buffer + lea eax, [edx + thread_data.buffer] + push eax push ebx call [file.read] cmp eax, -1 @@ -509,57 +599,58 @@ cmdRETR: push eax push ebx mov esi, eax - mcall send, [datasocketnum], buffer, , 0 + mov ecx, [edx + thread_data.datasocketnum] + lea edx, [edx + thread_data.buffer] + mcall send, , , , 0 pop ebx pop ecx + mov edx, [esp+4] ; thread_data pointer cmp eax, -1 je socketerror cmp ecx, BUFFERSIZE je .read_more - mcall close, [datasocketnum] + mcall close, [edx + thread_data.datasocketnum] - cmp [mode], MODE_PASSIVE_OK + cmp [edx + thread_data.mode], MODE_PASSIVE_OK jne @f - mov [mode], MODE_PASSIVE_WAIT + mov [edx + thread_data.mode], MODE_PASSIVE_WAIT @@: - mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok + mcall send, [edx + thread_data.socketnum], str226, str226.length, 0 ; transfer ok ret .cannot_open: - pushd 0x0c call [con_set_flags] - push str_notfound call [con_write_asciiz] - pushd 0x07 call [con_set_flags] - mcall send, [socketnum2], str550, str550.length, 0 ; file not found + mcall send, [edx + thread_data.socketnum], str550, str550.length, 0 ; file not found ret align 4 cmdSTOR: + ; TODO: check if user has write permission, and write file if so + ret align 4 cmdSYST: - mcall send, [socketnum2], str215, str215.length, 0 + mcall send, [edx + thread_data.socketnum], str215, str215.length, 0 ret align 4 cmdTYPE: - cmp ecx, 6 jb parse_cmd.error @@ -578,11 +669,11 @@ cmdTYPE: jmp parse_cmd.error .ascii: - mov [type], TYPE_ASCII + mov [edx + thread_data.type], TYPE_ASCII jmp .subtype .ebdic: - mov [type], TYPE_EBDIC + mov [edx + thread_data.type], TYPE_EBDIC .subtype: @@ -602,19 +693,19 @@ cmdTYPE: jmp parse_cmd.error .non_print: - or [type], TYPE_NP + or [edx + thread_data.type], TYPE_NP jmp .ok .telnet: - or [type], TYPE_TELNET + or [edx + thread_data.type], TYPE_TELNET jmp .ok .asacc: - or [type], TYPE_ASA + or [edx + thread_data.type], TYPE_ASA jmp .ok .image: - mov [type], TYPE_IMAGE + mov [edx + thread_data.type], TYPE_IMAGE jmp .ok .local: @@ -627,21 +718,24 @@ cmdTYPE: cmp al, 9 ja parse_cmd.error or al, TYPE_LOCAL - mov [type], al + mov [edx + thread_data.type], al .ok: - mcall send, [socketnum2], str200, str200.length, 0 + mcall send, [edx + thread_data.socketnum], str200, str200.length, 0 ret align 4 cmdUSER: - mcall send, [socketnum2], str331, str331.length, 0 - mov [state], STATE_LOGIN + ; TODO: check user and set home directory (and permissions) - mov byte [work_dir], "/" - mov byte [work_dir+1], 0 + mcall send, [edx + thread_data.socketnum], str331, str331.length, 0 + mov edx, [esp+4] ; thread_data pointer + mov [edx + thread_data.state], STATE_LOGIN + + mov byte [edx + thread_data.work_dir], "/" + mov byte [edx + thread_data.work_dir+1], 0 push str_logged_in call [con_write_asciiz] @@ -650,34 +744,31 @@ cmdUSER: - - - - -align 4 ; esi = ptr to str +align 4 ; esi = ptr to str, output in eax ascii_to_byte: - xor ebx, ebx + xor eax, eax + push ebx .loop: - - movzx eax, byte[esi] - sub al, '0' + movzx ebx, byte[esi] + sub bl, '0' jb .done - cmp al, 9 + cmp bl, 9 ja .done - lea ebx, [ebx*4 + ebx] - shl ebx, 1 - add ebx, eax + lea eax, [eax*4 + eax] ; + shl eax, 1 ; eax = eax * 10 + add eax, ebx inc esi jmp .loop .done: + pop ebx ret align 4 -dword_to_ascii: ; edi = ptr where to write, ebx is number +dword_to_ascii: ; edi = ptr where to write, eax is number mov eax, '1' stosb @@ -686,8 +777,8 @@ dword_to_ascii: ; edi = ptr where to write, ebx is number align 4 create_path: ; combine home_dir and work_dir strings into fpath - mov edi, fpath - mov esi, home_dir + lea edi, [edx + thread_data.fpath] + lea esi, [edx + thread_data.home_dir] mov ecx, 1024 .loop1: @@ -703,7 +794,7 @@ create_path: ; combine home_dir and work_dir strings into fpath dec edi @@: - mov esi, work_dir + lea esi, [edx + thread_data.work_dir] mov ecx, 1024 .loop2: @@ -724,14 +815,12 @@ socketerror: pushd 0x0c call [con_set_flags] - push str_sockerr call [con_write_asciiz] - pushd 0x07 call [con_set_flags] - mcall send, [socketnum2], str425, str425.length, 0 ; data connection error + mcall send, [edx + thread_data.socketnum], str425, str425.length, 0 ; data connection error ret diff --git a/kernel/branches/net/applications/ftpd/ftpd.asm b/kernel/branches/net/applications/ftpd/ftpd.asm index 92d84ec4af..1ce3bcc9a0 100644 --- a/kernel/branches/net/applications/ftpd/ftpd.asm +++ b/kernel/branches/net/applications/ftpd/ftpd.asm @@ -38,7 +38,7 @@ use32 dd i_end ; initialized size dd mem+0x1000 ; required memory dd mem+0x1000 ; stack pointer - dd 0 ; parameters + dd params ; parameters dd path ; path include '../macros.inc' @@ -58,13 +58,15 @@ start: test eax, eax jnz exit + mcall 68, 11 ; init heap + ; find path to main settings file - mov edi, path ; Calculate the length of zero-terminated string + mov edi, path ; Calculate the length of zero-terminated string xor al , al mov ecx, 1024 repne scasb dec edi - mov esi, filename + mov esi, filename ; append it with '.ini' movsd movsb @@ -79,7 +81,7 @@ start: push -1 call [con_init] - mcall 40, 1 shl 7 ; we only want network events + mcall 40, 1 shl 7 ; we only want network events invoke ini.get_int, path, str_ftpd, str_port, 21 mov [sockaddr1.port], ax @@ -121,85 +123,99 @@ start: push str2b call [con_write_asciiz] - mcall 10 +mainloop: + mcall 10 ; Wait here for incoming connections on the base socket (socketnum) - mcall accept, [socketnum], sockaddr1, sockaddr1.length + 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 + +threadstart: + mcall 68, 12, sizeof.thread_data ; allocate the thread data struct cmp eax, -1 - je acpt_err + je exit - mov [socketnum2], eax + lea esp, [eax + thread_data.stack] ; init stack + push eax ; save pointer to thread_data on stack - mcall send, [socketnum2], str220, str220.length, 0 ; send welcome string + mcall 40, 1 shl 7 ; we only want network events for this thread - .loop: + push str8 + call [con_write_asciiz] ; print on the console that we have created the new thread successfully + + mcall accept, [socketnum], sockaddr1, sockaddr1.length ; time to accept the awaiting connection.. + cmp eax, -1 + je thread_exit + mov edx, [esp] ; pointer to thread_data + mov [edx + thread_data.socketnum], eax + + mcall send, [edx + thread_data.socketnum], str220, str220.length, 0 ; send welcome string to the FTP client + +threadloop: mcall 10 - cmp [mode], MODE_PASSIVE_WAIT + mov edx, [esp] ; pointer to thread_data + + cmp [edx + thread_data.mode], MODE_PASSIVE_WAIT jne @f - mcall accept, [passivesocknum], datasock, datasock.length + mov ecx, [edx + thread_data.passivesocknum] + lea edx, [edx + thread_data.datasock] + mov esi, sizeof.thread_data.datasock + mcall accept + mov edx, [esp] ; pointer to thread_data cmp eax, -1 je @f - mov [datasocketnum], eax - mov [mode], MODE_PASSIVE_OK + mov [edx + thread_data.datasocketnum], eax + mov [edx + thread_data.mode], MODE_PASSIVE_OK push str_datasock - call [con_write_asciiz] + call [con_write_asciiz] ; print on the console that the datasock is now ready @@: - mcall recv, [socketnum2], buffer, buffer.length - cmp eax, -1 - je .loop - or eax, eax - jz .loop - push eax + mov ecx, [edx + thread_data.socketnum] + lea edx, [edx + thread_data.buffer] + mov esi, sizeof.thread_data.buffer + mcall recv + cmp eax, -1 ; error? + je threadloop + or eax, eax ; 0 bytes read? + jz threadloop + push eax ; save number of bytes read on stack - mov byte[buffer+eax], 0 + mov edx, [esp+4] ; pointer to thread_data + mov byte [edx + thread_data.buffer + eax], 0 ; append received data with a 0 byte - pushd 0x0a + pushd 0x0a ; print received data to console (in green color) call [con_set_flags] - push buffer + lea eax, [edx + thread_data.buffer] + push eax call [con_write_asciiz] pushd 0x07 call [con_set_flags] - pop ecx - mov esi, buffer + pop ecx ; number of bytes read + lea esi, [edx + thread_data.buffer] call parse_cmd - jmp .loop - -acpt_err: - - pushd 0x0c - call [con_set_flags] - - push str8 - call [con_write_asciiz] - jmp done + jmp threadloop 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 @@ -212,18 +228,28 @@ exit: mcall -1 +thread_exit: + push str_bye + call [con_write_asciiz] ; say bye bye + pop ecx ; get the thread_data pointer from stack + mcall 68, 13 ; free the memory + mcall -1 ; and kill the thread -; data -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 -str6 db 'Could not open socket',10,10,0 -str7 db 'Got data!',10,10,0 -str8 db 'Error accepting connection',10,10,0 + + +; initialized data + +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 +str6 db 'Could not open socket',10,10,0 +str7 db 'Got data!',10,10,0 +str8 db 10,'New thread created!',10,10,0 +str_bye db 10,'Closing thread!',10,10,0 str_logged_in db 'Login ok',10,10,0 str_pass_ok db 'Password ok - Logged in',10,10,0 @@ -233,91 +259,78 @@ str_datasock db 'Passive data socket connected!',10,10,0 str_notfound db 'ERROR: file not found',10,10,0 str_sockerr db 'ERROR: socket error',10,10,0 -str_newline db 10,0 - - +str_newline db 10, 0 str_mask db '*', 0 +months dd 'Jan ' + dd 'Feb ' + dd 'Mar ' + dd 'Apr ' + dd 'May ' + dd 'Jun ' + dd 'Jul ' + dd 'Aug ' + dd 'Sep ' + dd 'Oct ' + dd 'Nov ' + dd 'Dec ' -months: - dd 'Jan ','Feb ','Mar ','Apr ','May ','Jun ' - dd 'Jul ','Aug ','Sep ','Oct ','Nov ','Dec ' - -filename db '.ini', 0 -str_port db 'port', 0 -str_ftpd db 'ftpd', 0 -str_conn db 'conn', 0 +filename db '.ini', 0 +str_port db 'port', 0 +str_ftpd db 'ftpd', 0 +str_conn db 'conn', 0 sockaddr1: - dw AF_INET4 -.port dw 21 -.ip dd 0 - rb 10 -.length = $ - sockaddr1 + dw AF_INET4 + .port dw 21 + .ip dd 0 + rb 10 + .length = $ - sockaddr1 ; import + align 4 @IMPORT: -library console, 'console.obj', \ - libini, 'libini.obj', \ - libio, 'libio.obj' +library console, 'console.obj',\ + libini, 'libini.obj', \ + libio, 'libio.obj' -import console, \ - con_start, 'START', \ - con_init, 'con_init', \ - con_write_asciiz, 'con_write_asciiz', \ - con_exit, 'con_exit', \ - con_gets, 'con_gets',\ - con_cls, 'con_cls',\ - con_printf, 'con_printf',\ - con_getch2, 'con_getch2',\ - con_set_cursor_pos, 'con_set_cursor_pos',\ - con_set_flags, 'con_set_flags' +import console,\ + con_start, 'START',\ + con_init, 'con_init',\ + con_write_asciiz, 'con_write_asciiz',\ + con_exit, 'con_exit',\ + con_gets, 'con_gets',\ + con_cls, 'con_cls',\ + con_printf, 'con_printf',\ + con_getch2, 'con_getch2',\ + con_set_cursor_pos, 'con_set_cursor_pos',\ + con_set_flags, 'con_set_flags' -import libini, \ - ini.get_str, 'ini_get_str',\ - ini.get_int, 'ini_get_int' +import libini,\ + ini.get_str, 'ini_get_str',\ + ini.get_int, 'ini_get_int' -import libio, \ - libio.init , 'lib_init' , \ - file.size , 'file_size' , \ - file.open , 'file_open' , \ - file.read , 'file_read' , \ - file.close , 'file_close' , \ - file.find.first , 'file_find_first', \ - file.find.next , 'file_find_next', \ - file.find.close , 'file_find_close' +import libio,\ + libio.init, 'lib_init',\ + file.size, 'file_size',\ + file.open, 'file_open',\ + file.read, 'file_read',\ + file.close, 'file_close',\ + file.find.first, 'file_find_first',\ + file.find.next, 'file_find_next',\ + file.find.close, 'file_find_close' i_end: -socketnum dd ? +; uninitialised data + socketnum dd ? + path rb 1024 + params rb 1024 -; thread specific data -socketnum2 dd ? -state dd ? -home_dir db '/rd/1/', 0 - rb 1024 -work_dir rb 1024 -fpath rb 1024*3 - -type db ? -mode db ? ; active/passive - -passivesocknum dd ? -datasocketnum dd ? - -datasock: - dw AF_INET4 -.port dw ? -.ip dd ? - rb 10 -.length = $ - datasock - -buffer rb BUFFERSIZE -.length = $ - buffer - -path rb 1024 mem: + +