diff --git a/programs/network/ftpc/ftpc.asm b/programs/network/ftpc/ftpc.asm index c747024b68..2abea12494 100644 --- a/programs/network/ftpc/ftpc.asm +++ b/programs/network/ftpc/ftpc.asm @@ -14,13 +14,17 @@ format binary as "" -BUFFERSIZE = 1024 +BUFFERSIZE = 4096 STATUS_CONNECTING = 0 STATUS_CONNECTED = 1 STATUS_NEEDPASSWORD = 2 STATUS_LOGGED_IN = 3 +OPERATION_LIST = 0 +OPERATION_RETR = 1 +OPERATION_STOR = 2 + use32 ; standard header db 'MENUET01' ; signature @@ -97,31 +101,27 @@ resolve: jnz fail ; write results - invoke con_write_asciiz, str8 -; mov edi, esi + invoke con_write_asciiz, str8 ; ' (',0 + mov eax, [esi+addrinfo.ai_addr] ; convert IP address to decimal notation + mov eax, [eax+sockaddr_in.sin_addr] ; + mov [sockaddr1.ip], eax ; + invoke inet_ntoa, eax ; + invoke con_write_asciiz, eax ; print ip + invoke freeaddrinfo, esi ; free allocated memory + invoke con_write_asciiz, str9 ; ')',10,0 -; convert IP address to decimal notation - mov eax, [esi+addrinfo.ai_addr] - mov eax, [eax+sockaddr_in.sin_addr] - mov [sockaddr1.ip], eax - - invoke inet_ntoa, eax -; write result - invoke con_write_asciiz, eax -; free allocated memory - invoke freeaddrinfo, esi - - invoke con_write_asciiz, str9 +; open the socket mcall socket, AF_INET4, SOCK_STREAM, 0 cmp eax, -1 je socket_error mov [socketnum], eax +; connect to the server invoke con_write_asciiz, str11 mcall connect, [socketnum], sockaddr1, 18 mov [status], STATUS_CONNECTING - invoke con_write_asciiz, str12 + invoke con_write_asciiz, str12 ; 'waiting for welcome' mov [offset], 0 @@ -175,7 +175,7 @@ wait_for_servercommand: invoke con_set_flags, 0x03 ; change color invoke con_write_asciiz, s ; print servercommand invoke con_write_asciiz, str4 ; newline - invoke con_set_flags, 0x07 + invoke con_set_flags, 0x07 ; reset color jmp server_parser ; parse command @@ -213,8 +213,14 @@ wait_for_usercommand: cmp dword[s], "pwd" + 10 shl 24 je cmd_pwd -; cmp dword[s], "stor" -; je cmd_stor + cmp dword[s], "stor" + je cmd_stor + + cmp dword[s], "dele" + je cmd_dele + + cmp dword[s], "bye" + 10 shl 24 + je cmd_bye invoke con_write_asciiz, str_unknown jmp wait_for_usercommand @@ -239,20 +245,22 @@ wait_for_usercommand: mov esi, s+5 invoke con_gets, esi, 256 +; find end of string mov edi, s+5 mov ecx, 256 xor al, al repne scasb lea esi, [edi-s-1] +; and send it to the server mcall send, [socketnum], s, , 0 invoke con_write_asciiz, str4 ; newline - invoke con_set_flags, 0x07 + invoke con_set_flags, 0x07 ; reset color jmp wait_for_servercommand -open_dataconnection: +open_dataconnection: ; only passive for now.. cmp [status], STATUS_LOGGED_IN jne .fail @@ -289,7 +297,7 @@ exit: ; data title db 'FTP client',0 -str1 db 'FTP client for KolibriOS v0.04',10,10,'Please enter ftp server address.',10,0 +str1 db 'FTP client for KolibriOS v0.05',10,10,'Please enter ftp server address.',10,0 str2 db '> ',0 str3 db 'Resolving ',0 str4 db 10,0 @@ -303,8 +311,17 @@ str12 db 'Waiting for welcome message.',10,0 str_user db "username: ",0 str_pass db "password: ",0 str_unknown db "unknown command",10,0 + str_help db "available commands:",10 - db "help list cwd retr pwd",10,10,0 + db "help - help",10,10 + db "bye - close connection",10 + db "cwd - change working directoy on server",10 + db "dele - delete file from server",10 + db "list - list files and folders in current directory",10 + db "pwd - print working directory",10 + db "retr - retreive file from server",10 + db "stor - store file on server",10 + db 10,0 str_open db "opening data socket",10,0 @@ -320,7 +337,6 @@ sockaddr2: .ip dd 0 rb 10 - ; import align 4 @IMPORT: @@ -348,15 +364,22 @@ import console, \ i_end: -align 4 status db ? active_passive db ? -align 4 socketnum dd ? datasocket dd ? offset dd ? size dd ? +operation dd ? + +filestruct: +.subfn dd ? +.offset dd ? + dd ? +.size dd ? +.ptr dd ? +.name rb 1024 buffer_ptr rb BUFFERSIZE+1 buffer_ptr2 rb BUFFERSIZE+1 diff --git a/programs/network/ftpc/servercommands.inc b/programs/network/ftpc/servercommands.inc index 40e1f727d7..c4bd0fc361 100644 --- a/programs/network/ftpc/servercommands.inc +++ b/programs/network/ftpc/servercommands.inc @@ -21,7 +21,7 @@ server_parser: je login_ok ; cmp dword[s], "250" -; je dir_ok +; je op_ok cmp dword[s], "331 " je pass @@ -29,9 +29,12 @@ server_parser: ; cmp dword[s], "421 " ; je timeout - cmp dword[s], "530" ; password incorrect + cmp dword[s], "530 " ; password incorrect je welcome + cmp dword[s], "550 " + je close_datacon + jmp wait_for_usercommand @@ -90,20 +93,60 @@ pasv_ok: data_ok: + cmp [operation], OPERATION_STOR + je .stor + +; we are receiving data mcall recv, [datasocket], buffer_ptr2, BUFFERSIZE, 0 test ebx, ebx - jnz .fail + jnz .done mov byte[buffer_ptr2 + eax], 0 - invoke con_write_asciiz, buffer_ptr2 + cmp [operation], OPERATION_RETR + je .retr +; not retreiving, just print to console + invoke con_write_asciiz, buffer_ptr2 jmp data_ok - .fail: +; retreiving, save to file + .retr: + mov [filestruct.ptr], buffer_ptr2 + mov [filestruct.size], eax + push eax + mcall 70, filestruct + pop eax + add [filestruct.offset], eax + jmp data_ok + +; storing, send all data + .stor: + mcall 70, filestruct + cmp eax, 6 ; end of file + je .last_call + test eax, eax ; error +; jne .fileerror + add [filestruct.offset], ebx + mov esi, ebx + mcall send, [datasocket], buffer_ptr2, , 0 + jmp .stor + + .last_call: + mov esi, ebx + mcall send, [datasocket], buffer_ptr2, , 0 + + .done: mcall close, [datasocket] jmp wait_for_servercommand + +close_datacon: + mcall close, [datasocket] + jmp wait_for_usercommand + + + ascii_dec: xor ebx, ebx diff --git a/programs/network/ftpc/usercommands.inc b/programs/network/ftpc/usercommands.inc index 887ae497cb..507458187c 100644 --- a/programs/network/ftpc/usercommands.inc +++ b/programs/network/ftpc/usercommands.inc @@ -1,14 +1,3 @@ -cmd_list: - - call open_dataconnection - - mov dword[s], "LIST" - mov byte[s+4], 0x0a - mcall send, [socketnum], s, 5, 0 - - jmp wait_for_servercommand - - cmd_help: push str_help @@ -16,6 +5,13 @@ cmd_help: jmp wait_for_usercommand +cmd_bye: + + mcall close, [socketnum] + mcall close, [datasocket] + + jmp main + cmd_pwd: mov dword[s], "PWD" + 10 shl 24 @@ -37,13 +33,10 @@ cmd_cwd: jmp wait_for_servercommand +cmd_dele: -cmd_retr: - - call open_dataconnection - - mov dword[s], "RETR" - mov byte[s+4], " " + mov dword[s], "DELE" + mov byte[s], " " mov ecx, 256 xor al, al @@ -55,11 +48,72 @@ cmd_retr: jmp wait_for_servercommand +cmd_list: + + call open_dataconnection + + mov [operation], OPERATION_LIST + + mov dword[s], "LIST" + mov byte[s+4], 0x0a + mcall send, [socketnum], s, 5, 0 + + jmp wait_for_servercommand + + +cmd_retr: + + call open_dataconnection + + mov [operation], OPERATION_RETR + + mov [filestruct.subfn], 2 ; create/rewrite file + mov [filestruct.offset], 0 + mov [filestruct.offset+4], 0 + mov [filestruct.size], 0 + mov [filestruct.ptr], 0 + + lea esi, [s+5] + mov edi, filestruct.name + mov ecx, 256-5 + call set_filename + + mcall 70, filestruct + cmp eax, -1 +; je fileerror + + mov [filestruct.subfn], 3 ; write to file + + mov dword[s], "RETR" + mov byte[s+4], " " + + mov ecx, 256 + xor al, al + mov edi, s + repne scasb + lea esi, [edi - s - 1] + mcall send, [socketnum], s, , 0 + + jmp wait_for_servercommand + cmd_stor: call open_dataconnection + mov [operation], OPERATION_STOR + + mov [filestruct.subfn], 0 ; read file + mov [filestruct.offset], 0 + mov [filestruct.offset+4], 0 + mov [filestruct.size], BUFFERSIZE + mov [filestruct.ptr], buffer_ptr2 + + lea esi, [s+5] + mov edi, filestruct.name + mov ecx, 256-5 + call set_filename + mov dword[s], "STOR" mov byte[s+4], " " @@ -68,7 +122,30 @@ cmd_stor: mov edi, s repne scasb lea esi, [edi - s - 1] - mcall send, [socketnum], s, , 0 - jmp wait_for_servercommand \ No newline at end of file + jmp wait_for_servercommand + + + +; esi = source ptr +; edi = dest ptr +; ecx = max length of source buffer +set_filename: + + .loop: + lodsb + test al, al + jz .done + cmp al, ' ' + je .done + cmp al, 10 + je .done + stosb + loop .loop + .done: + xor al, al ; append a 0 byte + stosb + + ret +