forked from KolibriOS/kolibrios
FTPc: send and receive files from applications working directory to servers working directory, also added dele and bye commands.
git-svn-id: svn://kolibrios.org@3800 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
038f3f8566
commit
8f864f395b
@ -14,13 +14,17 @@
|
|||||||
|
|
||||||
format binary as ""
|
format binary as ""
|
||||||
|
|
||||||
BUFFERSIZE = 1024
|
BUFFERSIZE = 4096
|
||||||
|
|
||||||
STATUS_CONNECTING = 0
|
STATUS_CONNECTING = 0
|
||||||
STATUS_CONNECTED = 1
|
STATUS_CONNECTED = 1
|
||||||
STATUS_NEEDPASSWORD = 2
|
STATUS_NEEDPASSWORD = 2
|
||||||
STATUS_LOGGED_IN = 3
|
STATUS_LOGGED_IN = 3
|
||||||
|
|
||||||
|
OPERATION_LIST = 0
|
||||||
|
OPERATION_RETR = 1
|
||||||
|
OPERATION_STOR = 2
|
||||||
|
|
||||||
use32
|
use32
|
||||||
; standard header
|
; standard header
|
||||||
db 'MENUET01' ; signature
|
db 'MENUET01' ; signature
|
||||||
@ -97,31 +101,27 @@ resolve:
|
|||||||
jnz fail
|
jnz fail
|
||||||
|
|
||||||
; write results
|
; write results
|
||||||
invoke con_write_asciiz, str8
|
invoke con_write_asciiz, str8 ; ' (',0
|
||||||
; mov edi, esi
|
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
|
; open the socket
|
||||||
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
|
|
||||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je socket_error
|
je socket_error
|
||||||
mov [socketnum], eax
|
mov [socketnum], eax
|
||||||
|
|
||||||
|
; connect to the server
|
||||||
invoke con_write_asciiz, str11
|
invoke con_write_asciiz, str11
|
||||||
mcall connect, [socketnum], sockaddr1, 18
|
mcall connect, [socketnum], sockaddr1, 18
|
||||||
mov [status], STATUS_CONNECTING
|
mov [status], STATUS_CONNECTING
|
||||||
|
|
||||||
invoke con_write_asciiz, str12
|
invoke con_write_asciiz, str12 ; 'waiting for welcome'
|
||||||
|
|
||||||
mov [offset], 0
|
mov [offset], 0
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ wait_for_servercommand:
|
|||||||
invoke con_set_flags, 0x03 ; change color
|
invoke con_set_flags, 0x03 ; change color
|
||||||
invoke con_write_asciiz, s ; print servercommand
|
invoke con_write_asciiz, s ; print servercommand
|
||||||
invoke con_write_asciiz, str4 ; newline
|
invoke con_write_asciiz, str4 ; newline
|
||||||
invoke con_set_flags, 0x07
|
invoke con_set_flags, 0x07 ; reset color
|
||||||
|
|
||||||
jmp server_parser ; parse command
|
jmp server_parser ; parse command
|
||||||
|
|
||||||
@ -213,8 +213,14 @@ wait_for_usercommand:
|
|||||||
cmp dword[s], "pwd" + 10 shl 24
|
cmp dword[s], "pwd" + 10 shl 24
|
||||||
je cmd_pwd
|
je cmd_pwd
|
||||||
|
|
||||||
; cmp dword[s], "stor"
|
cmp dword[s], "stor"
|
||||||
; je cmd_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
|
invoke con_write_asciiz, str_unknown
|
||||||
jmp wait_for_usercommand
|
jmp wait_for_usercommand
|
||||||
@ -239,20 +245,22 @@ wait_for_usercommand:
|
|||||||
mov esi, s+5
|
mov esi, s+5
|
||||||
invoke con_gets, esi, 256
|
invoke con_gets, esi, 256
|
||||||
|
|
||||||
|
; find end of string
|
||||||
mov edi, s+5
|
mov edi, s+5
|
||||||
mov ecx, 256
|
mov ecx, 256
|
||||||
xor al, al
|
xor al, al
|
||||||
repne scasb
|
repne scasb
|
||||||
lea esi, [edi-s-1]
|
lea esi, [edi-s-1]
|
||||||
|
; and send it to the server
|
||||||
mcall send, [socketnum], s, , 0
|
mcall send, [socketnum], s, , 0
|
||||||
|
|
||||||
invoke con_write_asciiz, str4 ; newline
|
invoke con_write_asciiz, str4 ; newline
|
||||||
invoke con_set_flags, 0x07
|
invoke con_set_flags, 0x07 ; reset color
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
open_dataconnection:
|
open_dataconnection: ; only passive for now..
|
||||||
cmp [status], STATUS_LOGGED_IN
|
cmp [status], STATUS_LOGGED_IN
|
||||||
jne .fail
|
jne .fail
|
||||||
|
|
||||||
@ -289,7 +297,7 @@ exit:
|
|||||||
|
|
||||||
; data
|
; data
|
||||||
title db 'FTP client',0
|
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
|
str2 db '> ',0
|
||||||
str3 db 'Resolving ',0
|
str3 db 'Resolving ',0
|
||||||
str4 db 10,0
|
str4 db 10,0
|
||||||
@ -303,8 +311,17 @@ str12 db 'Waiting for welcome message.',10,0
|
|||||||
str_user db "username: ",0
|
str_user db "username: ",0
|
||||||
str_pass db "password: ",0
|
str_pass db "password: ",0
|
||||||
str_unknown db "unknown command",10,0
|
str_unknown db "unknown command",10,0
|
||||||
|
|
||||||
str_help db "available commands:",10
|
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
|
str_open db "opening data socket",10,0
|
||||||
|
|
||||||
@ -320,7 +337,6 @@ sockaddr2:
|
|||||||
.ip dd 0
|
.ip dd 0
|
||||||
rb 10
|
rb 10
|
||||||
|
|
||||||
|
|
||||||
; import
|
; import
|
||||||
align 4
|
align 4
|
||||||
@IMPORT:
|
@IMPORT:
|
||||||
@ -348,15 +364,22 @@ import console, \
|
|||||||
|
|
||||||
i_end:
|
i_end:
|
||||||
|
|
||||||
align 4
|
|
||||||
status db ?
|
status db ?
|
||||||
active_passive db ?
|
active_passive db ?
|
||||||
|
|
||||||
align 4
|
|
||||||
socketnum dd ?
|
socketnum dd ?
|
||||||
datasocket dd ?
|
datasocket dd ?
|
||||||
offset dd ?
|
offset dd ?
|
||||||
size dd ?
|
size dd ?
|
||||||
|
operation dd ?
|
||||||
|
|
||||||
|
filestruct:
|
||||||
|
.subfn dd ?
|
||||||
|
.offset dd ?
|
||||||
|
dd ?
|
||||||
|
.size dd ?
|
||||||
|
.ptr dd ?
|
||||||
|
.name rb 1024
|
||||||
|
|
||||||
buffer_ptr rb BUFFERSIZE+1
|
buffer_ptr rb BUFFERSIZE+1
|
||||||
buffer_ptr2 rb BUFFERSIZE+1
|
buffer_ptr2 rb BUFFERSIZE+1
|
||||||
|
@ -21,7 +21,7 @@ server_parser:
|
|||||||
je login_ok
|
je login_ok
|
||||||
|
|
||||||
; cmp dword[s], "250"
|
; cmp dword[s], "250"
|
||||||
; je dir_ok
|
; je op_ok
|
||||||
|
|
||||||
cmp dword[s], "331 "
|
cmp dword[s], "331 "
|
||||||
je pass
|
je pass
|
||||||
@ -29,9 +29,12 @@ server_parser:
|
|||||||
; cmp dword[s], "421 "
|
; cmp dword[s], "421 "
|
||||||
; je timeout
|
; je timeout
|
||||||
|
|
||||||
cmp dword[s], "530" ; password incorrect
|
cmp dword[s], "530 " ; password incorrect
|
||||||
je welcome
|
je welcome
|
||||||
|
|
||||||
|
cmp dword[s], "550 "
|
||||||
|
je close_datacon
|
||||||
|
|
||||||
jmp wait_for_usercommand
|
jmp wait_for_usercommand
|
||||||
|
|
||||||
|
|
||||||
@ -90,20 +93,60 @@ pasv_ok:
|
|||||||
|
|
||||||
data_ok:
|
data_ok:
|
||||||
|
|
||||||
|
cmp [operation], OPERATION_STOR
|
||||||
|
je .stor
|
||||||
|
|
||||||
|
; we are receiving data
|
||||||
mcall recv, [datasocket], buffer_ptr2, BUFFERSIZE, 0
|
mcall recv, [datasocket], buffer_ptr2, BUFFERSIZE, 0
|
||||||
test ebx, ebx
|
test ebx, ebx
|
||||||
jnz .fail
|
jnz .done
|
||||||
mov byte[buffer_ptr2 + eax], 0
|
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
|
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]
|
mcall close, [datasocket]
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
close_datacon:
|
||||||
|
mcall close, [datasocket]
|
||||||
|
jmp wait_for_usercommand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ascii_dec:
|
ascii_dec:
|
||||||
|
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
|
@ -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:
|
cmd_help:
|
||||||
|
|
||||||
push str_help
|
push str_help
|
||||||
@ -16,6 +5,13 @@ cmd_help:
|
|||||||
|
|
||||||
jmp wait_for_usercommand
|
jmp wait_for_usercommand
|
||||||
|
|
||||||
|
cmd_bye:
|
||||||
|
|
||||||
|
mcall close, [socketnum]
|
||||||
|
mcall close, [datasocket]
|
||||||
|
|
||||||
|
jmp main
|
||||||
|
|
||||||
cmd_pwd:
|
cmd_pwd:
|
||||||
|
|
||||||
mov dword[s], "PWD" + 10 shl 24
|
mov dword[s], "PWD" + 10 shl 24
|
||||||
@ -37,11 +33,57 @@ cmd_cwd:
|
|||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
cmd_dele:
|
||||||
|
|
||||||
|
mov dword[s], "DELE"
|
||||||
|
mov byte[s], " "
|
||||||
|
|
||||||
|
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_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:
|
cmd_retr:
|
||||||
|
|
||||||
call open_dataconnection
|
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 dword[s], "RETR"
|
||||||
mov byte[s+4], " "
|
mov byte[s+4], " "
|
||||||
|
|
||||||
@ -50,7 +92,6 @@ cmd_retr:
|
|||||||
mov edi, s
|
mov edi, s
|
||||||
repne scasb
|
repne scasb
|
||||||
lea esi, [edi - s - 1]
|
lea esi, [edi - s - 1]
|
||||||
|
|
||||||
mcall send, [socketnum], s, , 0
|
mcall send, [socketnum], s, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
@ -60,6 +101,19 @@ cmd_stor:
|
|||||||
|
|
||||||
call open_dataconnection
|
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 dword[s], "STOR"
|
||||||
mov byte[s+4], " "
|
mov byte[s+4], " "
|
||||||
|
|
||||||
@ -68,7 +122,30 @@ cmd_stor:
|
|||||||
mov edi, s
|
mov edi, s
|
||||||
repne scasb
|
repne scasb
|
||||||
lea esi, [edi - s - 1]
|
lea esi, [edi - s - 1]
|
||||||
|
|
||||||
mcall send, [socketnum], s, , 0
|
mcall send, [socketnum], s, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user