forked from KolibriOS/kolibrios
Preparing for active connections, added ftpc.ini with settings, some housekeeping.
git-svn-id: svn://kolibrios.org@5011 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
73e206ad91
commit
7626be8544
@ -27,8 +27,8 @@ OPERATION_NONE = 0
|
|||||||
OPERATION_LIST = 1
|
OPERATION_LIST = 1
|
||||||
OPERATION_RETR = 2
|
OPERATION_RETR = 2
|
||||||
OPERATION_STOR = 3
|
OPERATION_STOR = 3
|
||||||
OPERATION_RDIR = 4
|
OPERATION_RDIR = 4
|
||||||
|
|
||||||
use32
|
use32
|
||||||
; standard header
|
; standard header
|
||||||
db 'MENUET01' ; signature
|
db 'MENUET01' ; signature
|
||||||
@ -38,7 +38,7 @@ use32
|
|||||||
dd mem+0x1000 ; required memory
|
dd mem+0x1000 ; required memory
|
||||||
dd mem+0x1000 ; stack pointer
|
dd mem+0x1000 ; stack pointer
|
||||||
dd buf_cmd ; parameters
|
dd buf_cmd ; parameters
|
||||||
dd 0 ; path
|
dd path ; path
|
||||||
|
|
||||||
include '../../macros.inc'
|
include '../../macros.inc'
|
||||||
purge mov,add,sub
|
purge mov,add,sub
|
||||||
@ -51,10 +51,10 @@ include 'servercommands.inc'
|
|||||||
|
|
||||||
start:
|
start:
|
||||||
; initialize heap for using dynamic blocks
|
; initialize heap for using dynamic blocks
|
||||||
mcall 68,11
|
mcall 68,11
|
||||||
test eax,eax
|
test eax,eax
|
||||||
je exit2
|
je exit2
|
||||||
|
|
||||||
; disable all events except network event
|
; disable all events except network event
|
||||||
mcall 40, EV_STACK
|
mcall 40, EV_STACK
|
||||||
; load libraries
|
; load libraries
|
||||||
@ -64,7 +64,42 @@ start:
|
|||||||
; initialize console
|
; initialize console
|
||||||
invoke con_start, 1
|
invoke con_start, 1
|
||||||
invoke con_init, 80, 25, 80, 250, str_title
|
invoke con_init, 80, 25, 80, 250, str_title
|
||||||
|
; find path to main settings file (ftpc.ini)
|
||||||
|
mov edi, path ; Calculate the length of zero-terminated string
|
||||||
|
xor al, al
|
||||||
|
mov ecx, 1024
|
||||||
|
repne scasb
|
||||||
|
dec edi
|
||||||
|
mov esi, str_ini ; append it with '.ini', 0
|
||||||
|
movsd
|
||||||
|
movsb
|
||||||
|
; get settings from ini
|
||||||
|
invoke ini.get_str, path, str_active, str_ip, str_active_ip, 16, 0
|
||||||
|
mov esi, str_active_ip
|
||||||
|
.ip_loop:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .ip_ok
|
||||||
|
cmp al, ' '
|
||||||
|
je .ip_ok
|
||||||
|
cmp al, '.'
|
||||||
|
jne .ip_loop
|
||||||
|
mov byte[esi-1], ','
|
||||||
|
jmp .ip_loop
|
||||||
|
.ip_ok:
|
||||||
|
mov byte[esi-1], 0
|
||||||
|
|
||||||
|
invoke ini.get_int, path, str_active, str_port_start, 64000
|
||||||
|
mov [acti_port_start], ax
|
||||||
|
|
||||||
|
invoke ini.get_int, path, str_active, str_port_stop, 65000
|
||||||
|
mov [acti_port_stop], ax
|
||||||
|
|
||||||
|
invoke ini.get_str, path, str_general, str_dir, buf_buffer1, BUFFERSIZE, 0
|
||||||
|
mcall 30, 1, buf_buffer1 ; set working directory
|
||||||
|
|
||||||
; Check for parameters, if there are some, resolve the address right away
|
; Check for parameters, if there are some, resolve the address right away
|
||||||
|
; TODO: parse ftp://user:password@server.com:port/folder/subfolder type urls.
|
||||||
cmp byte [buf_cmd], 0
|
cmp byte [buf_cmd], 0
|
||||||
jne resolve
|
jne resolve
|
||||||
|
|
||||||
@ -88,13 +123,41 @@ main:
|
|||||||
invoke con_write_asciiz, str_newline
|
invoke con_write_asciiz, str_newline
|
||||||
|
|
||||||
resolve:
|
resolve:
|
||||||
|
mov [sockaddr1.port], 21 shl 8
|
||||||
|
|
||||||
; delete terminating '\n'
|
; delete terminating '\n'
|
||||||
mov esi, buf_cmd
|
mov esi, buf_cmd
|
||||||
@@:
|
@@:
|
||||||
lodsb
|
lodsb
|
||||||
|
cmp al, ':'
|
||||||
|
je .do_port
|
||||||
cmp al, 0x20
|
cmp al, 0x20
|
||||||
ja @r
|
ja @r
|
||||||
mov byte [esi-1], 0
|
mov byte [esi-1], 0
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.do_port:
|
||||||
|
xor eax, eax
|
||||||
|
xor ebx, ebx
|
||||||
|
mov byte [esi-1], 0
|
||||||
|
.portloop:
|
||||||
|
lodsb
|
||||||
|
cmp al, 0x20
|
||||||
|
jbe .port_done
|
||||||
|
sub al, '0'
|
||||||
|
jb error_hostname
|
||||||
|
cmp al, 9
|
||||||
|
ja error_hostname
|
||||||
|
lea ebx, [ebx*4 + ebx]
|
||||||
|
shl ebx, 1
|
||||||
|
add ebx, eax
|
||||||
|
jmp .portloop
|
||||||
|
|
||||||
|
.port_done:
|
||||||
|
xchg bl, bh
|
||||||
|
mov [sockaddr1.port], bx
|
||||||
|
|
||||||
|
.done:
|
||||||
; Say to the user that we're resolving
|
; Say to the user that we're resolving
|
||||||
invoke con_write_asciiz, str_resolve
|
invoke con_write_asciiz, str_resolve
|
||||||
invoke con_write_asciiz, buf_cmd
|
invoke con_write_asciiz, buf_cmd
|
||||||
@ -118,10 +181,10 @@ resolve:
|
|||||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je error_socket
|
je error_socket
|
||||||
mov [socketnum], eax
|
mov [controlsocket], eax
|
||||||
; connect to the server
|
; connect to the server
|
||||||
invoke con_write_asciiz, str_connect
|
invoke con_write_asciiz, str_connect
|
||||||
mcall connect, [socketnum], sockaddr1, 18
|
mcall connect, [controlsocket], sockaddr1, 18
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je error_connect
|
je error_connect
|
||||||
mov [status], STATUS_CONNECTING
|
mov [status], STATUS_CONNECTING
|
||||||
@ -151,7 +214,7 @@ wait_for_servercommand:
|
|||||||
mcall 26, 9
|
mcall 26, 9
|
||||||
cmp eax, [timeout]
|
cmp eax, [timeout]
|
||||||
jge error_timeout
|
jge error_timeout
|
||||||
mcall recv, [socketnum], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
|
mcall recv, [controlsocket], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .got_data
|
jnz .got_data
|
||||||
cmp ebx, EWOULDBLOCK
|
cmp ebx, EWOULDBLOCK
|
||||||
@ -202,9 +265,9 @@ wait_for_usercommand:
|
|||||||
|
|
||||||
; Are there any files in the transfer queue?
|
; Are there any files in the transfer queue?
|
||||||
|
|
||||||
cmp [queued], 0
|
cmp [queued], 0
|
||||||
ja transfer_queued ; Yes, transfer those first.
|
ja transfer_queued ; Yes, transfer those first.
|
||||||
|
|
||||||
; change color to green for user input
|
; change color to green for user input
|
||||||
invoke con_set_flags, 0x0a
|
invoke con_set_flags, 0x0a
|
||||||
|
|
||||||
@ -240,8 +303,8 @@ wait_for_usercommand:
|
|||||||
je cmd_bye
|
je cmd_bye
|
||||||
|
|
||||||
cmp dword[buf_cmd], "rdir"
|
cmp dword[buf_cmd], "rdir"
|
||||||
je cmd_rdir
|
je cmd_rdir
|
||||||
|
|
||||||
cmp byte[buf_cmd+4], " "
|
cmp byte[buf_cmd+4], " "
|
||||||
jne @f
|
jne @f
|
||||||
|
|
||||||
@ -289,7 +352,7 @@ wait_for_usercommand:
|
|||||||
invoke con_write_asciiz, str_pass
|
invoke con_write_asciiz, str_pass
|
||||||
mov dword[buf_cmd], "PASS"
|
mov dword[buf_cmd], "PASS"
|
||||||
mov byte[buf_cmd+4], " "
|
mov byte[buf_cmd+4], " "
|
||||||
invoke con_set_flags, 0x00 ; black text on black background for password
|
invoke con_set_flags, 0x00 ; black text on black background for password
|
||||||
|
|
||||||
.send:
|
.send:
|
||||||
; read string
|
; read string
|
||||||
@ -304,29 +367,139 @@ wait_for_usercommand:
|
|||||||
lea esi, [edi-buf_cmd]
|
lea esi, [edi-buf_cmd]
|
||||||
mov word[edi-2], 0x0a0d
|
mov word[edi-2], 0x0a0d
|
||||||
; and send it to the server
|
; and send it to the server
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
invoke con_write_asciiz, str_newline
|
invoke con_write_asciiz, str_newline
|
||||||
invoke con_set_flags, 0x07 ; reset color
|
invoke con_set_flags, 0x07 ; reset color
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
open_dataconnection: ; only passive for now..
|
; files for rdir operation are queued
|
||||||
cmp [status], STATUS_LOGGED_IN
|
transfer_queued:
|
||||||
jne .fail
|
|
||||||
|
|
||||||
mcall send, [socketnum], str_PASV, str_PASV.length, 0
|
mov esi, [ptr_queue] ; always pointing to current part of ptr_fname_start
|
||||||
|
mov edi, buf_cmd+5 ; always point to filename for retr command
|
||||||
|
.build_filename:
|
||||||
|
lodsb
|
||||||
|
stosb
|
||||||
|
cmp al, 10
|
||||||
|
je .get_file ; filename ends with character 10
|
||||||
|
test al, al
|
||||||
|
jnz .build_filename
|
||||||
|
|
||||||
|
; Error occured, we reached the end of the buffer before [queued] reached 0
|
||||||
|
mov [queued], 0
|
||||||
|
mcall 68, 13, [ptr_fname] ; free buffer
|
||||||
|
test eax, eax
|
||||||
|
jz error_heap
|
||||||
|
jmp wait_for_usercommand
|
||||||
|
|
||||||
|
.get_file:
|
||||||
|
mov byte[edi], 0 ; end filename with 0 byte
|
||||||
|
mov [ptr_queue], esi
|
||||||
|
dec [queued]
|
||||||
|
jnz cmd_retr
|
||||||
|
|
||||||
|
mcall 68, 13, [ptr_fname] ; free buffer
|
||||||
|
test eax, eax
|
||||||
|
jz error_heap
|
||||||
|
jmp cmd_retr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open_dataconnection:
|
||||||
|
|
||||||
|
test [mode], 1
|
||||||
|
jnz .active
|
||||||
|
|
||||||
|
mcall send, [controlsocket], str_PASV, str_PASV.length, 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.fail:
|
.active:
|
||||||
invoke con_get_flags
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je error_socket
|
||||||
|
mov [datasocket], eax
|
||||||
|
|
||||||
|
mov ax, [acti_port_start]
|
||||||
|
xchg al, ah
|
||||||
|
mov [sockaddr2.port], ax
|
||||||
|
|
||||||
|
mcall bind, [datasocket], sockaddr2, 18
|
||||||
|
cmp eax, -1
|
||||||
|
je error_socket
|
||||||
|
|
||||||
|
mcall listen, [datasocket], 1
|
||||||
|
cmp eax, -1
|
||||||
|
je error_socket
|
||||||
|
|
||||||
|
mov dword[buf_buffer1], 'PORT'
|
||||||
|
mov byte[buf_buffer1+4], ' '
|
||||||
|
mov edi, buf_buffer1+5
|
||||||
|
mov esi, str_active_ip
|
||||||
|
.loop:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .ip_ok
|
||||||
|
stosb
|
||||||
|
jmp .loop
|
||||||
|
.ip_ok:
|
||||||
|
mov al, ','
|
||||||
|
stosb
|
||||||
|
movzx eax, byte[sockaddr2.port+0]
|
||||||
|
call dword_ascii
|
||||||
|
mov al, ','
|
||||||
|
stosb
|
||||||
|
movzx eax, byte[sockaddr2.port+1]
|
||||||
|
call dword_ascii
|
||||||
|
mov ax, 0x0a0d
|
||||||
|
stosw
|
||||||
|
lea esi, [edi - buf_buffer1]
|
||||||
|
mcall send, [controlsocket], buf_buffer1, , 0
|
||||||
|
|
||||||
|
mcall accept, [datasocket], sockaddr2, 18 ; time to accept the awaiting connection..
|
||||||
|
cmp eax, -1
|
||||||
|
je error_socket
|
||||||
push eax
|
push eax
|
||||||
invoke con_set_flags, 0x0c ; print errors in red
|
mcall close, [datasocket]
|
||||||
invoke con_write_asciiz, str_err_socket
|
pop [datasocket]
|
||||||
invoke con_set_flags ; reset color
|
|
||||||
|
mcall recv, [controlsocket], buf_buffer1, BUFFERSIZE, 0
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; eax = input
|
||||||
|
; edi = ptr where to write
|
||||||
|
dword_ascii:
|
||||||
|
|
||||||
|
push edx ebx ecx
|
||||||
|
mov ebx, 10
|
||||||
|
xor ecx, ecx
|
||||||
|
|
||||||
|
@@:
|
||||||
|
xor edx, edx
|
||||||
|
div ebx
|
||||||
|
add edx, '0'
|
||||||
|
push dx
|
||||||
|
inc ecx
|
||||||
|
test eax, eax
|
||||||
|
jnz @r
|
||||||
|
|
||||||
|
@@:
|
||||||
|
pop ax
|
||||||
|
stosb
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
|
||||||
|
pop ecx ebx edx
|
||||||
|
ret
|
||||||
|
|
||||||
|
error_hostname:
|
||||||
|
invoke con_set_flags, 0x0c ; print errors in red
|
||||||
|
invoke con_write_asciiz, str_err_host
|
||||||
|
jmp wait_for_keypress
|
||||||
|
|
||||||
error_connect:
|
error_connect:
|
||||||
invoke con_set_flags, 0x0c ; print errors in red
|
invoke con_set_flags, 0x0c ; print errors in red
|
||||||
invoke con_write_asciiz, str_err_connect
|
invoke con_write_asciiz, str_err_connect
|
||||||
@ -345,24 +518,25 @@ error_socket:
|
|||||||
error_resolve:
|
error_resolve:
|
||||||
invoke con_set_flags, 0x0c ; print errors in red
|
invoke con_set_flags, 0x0c ; print errors in red
|
||||||
invoke con_write_asciiz, str_err_resolve
|
invoke con_write_asciiz, str_err_resolve
|
||||||
|
jmp wait_for_keypress
|
||||||
|
|
||||||
error_heap:
|
error_heap:
|
||||||
invoke con_set_flags, 0x0c ; print errors in red
|
invoke con_set_flags, 0x0c ; print errors in red
|
||||||
invoke con_write_asciiz, str_err_heap
|
invoke con_write_asciiz, str_err_heap
|
||||||
|
|
||||||
wait_for_keypress:
|
wait_for_keypress:
|
||||||
invoke con_set_flags, 0x07 ; reset color to grey
|
invoke con_set_flags, 0x07 ; reset color to grey
|
||||||
invoke con_write_asciiz, str_push
|
invoke con_write_asciiz, str_push
|
||||||
invoke con_getch2
|
invoke con_getch2
|
||||||
mcall close, [socketnum]
|
mcall close, [controlsocket]
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
done:
|
done:
|
||||||
invoke con_exit, 1
|
invoke con_exit, 1
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mcall close, [socketnum]
|
mcall close, [controlsocket]
|
||||||
exit2:
|
exit2:
|
||||||
mcall -1
|
mcall -1
|
||||||
|
|
||||||
|
|
||||||
@ -378,9 +552,10 @@ str_resolve db 'Resolving ',0
|
|||||||
str_newline db 10,0
|
str_newline db 10,0
|
||||||
str_err_resolve db 10,'Name resolution failed.',10,0
|
str_err_resolve db 10,'Name resolution failed.',10,0
|
||||||
str_err_socket db 10,'Socket error.',10,0
|
str_err_socket db 10,'Socket error.',10,0
|
||||||
str_err_heap db 10,'Cannot allocate memory from heap.',10,0
|
str_err_heap db 10,'Cannot allocate memory from heap.',10,0
|
||||||
str_err_timeout db 10,'Timeout - no response from server.',10,0
|
str_err_timeout db 10,'Timeout - no response from server.',10,0
|
||||||
str_err_connect db 10,'Cannot connect to the server.',10,0
|
str_err_connect db 10,'Cannot connect to the server.',10,0
|
||||||
|
str_err_host db 10,'Invalid hostname.',10,0
|
||||||
str8 db ' (',0
|
str8 db ' (',0
|
||||||
str9 db ')',10,0
|
str9 db ')',10,0
|
||||||
str_push db 'Push any key to continue.',0
|
str_push db 'Push any key to continue.',0
|
||||||
@ -408,10 +583,19 @@ str_help db "available commands:",10
|
|||||||
db "retr <file> - retreive file from the server",10
|
db "retr <file> - retreive file from the server",10
|
||||||
db "rmd <directory> - remove directory from the server",10
|
db "rmd <directory> - remove directory from the server",10
|
||||||
db "stor <file> - store file on the server",10
|
db "stor <file> - store file on the server",10
|
||||||
db "rdir - retreive all files from current server dir",10
|
db "rdir - retreive all files from current server dir",10
|
||||||
db 10,0
|
db 10,0
|
||||||
|
|
||||||
queued dd 0
|
str_ini db '.ini', 0
|
||||||
|
str_active db 'active', 0
|
||||||
|
str_port_start db 'port_start', 0
|
||||||
|
str_port_stop db 'port_stop', 0
|
||||||
|
str_ip db 'ip', 0
|
||||||
|
str_dir db 'dir', 0
|
||||||
|
str_general db 'general', 0
|
||||||
|
|
||||||
|
queued dd 0
|
||||||
|
mode db 0 ; passive = 0, active = 1
|
||||||
|
|
||||||
; FTP strings
|
; FTP strings
|
||||||
|
|
||||||
@ -420,21 +604,21 @@ str_PASV db 'PASV',13,10
|
|||||||
|
|
||||||
sockaddr1:
|
sockaddr1:
|
||||||
dw AF_INET4
|
dw AF_INET4
|
||||||
.port dw 0x1500 ; 21
|
.port dw ?
|
||||||
.ip dd 0
|
.ip dd ?
|
||||||
rb 10
|
rb 10
|
||||||
|
|
||||||
sockaddr2:
|
sockaddr2:
|
||||||
dw AF_INET4
|
dw AF_INET4
|
||||||
.port dw 0
|
.port dw ?
|
||||||
.ip dd 0
|
.ip dd ?
|
||||||
rb 10
|
rb 10
|
||||||
|
|
||||||
; import
|
; import
|
||||||
align 4
|
align 4
|
||||||
@IMPORT:
|
@IMPORT:
|
||||||
|
|
||||||
library network, 'network.obj', console, 'console.obj'
|
library network, 'network.obj', console, 'console.obj', libini, 'libini.obj'
|
||||||
|
|
||||||
import network, \
|
import network, \
|
||||||
getaddrinfo, 'getaddrinfo', \
|
getaddrinfo, 'getaddrinfo', \
|
||||||
@ -454,35 +638,46 @@ import console, \
|
|||||||
con_get_flags, 'con_get_flags', \
|
con_get_flags, 'con_get_flags', \
|
||||||
con_set_flags, 'con_set_flags'
|
con_set_flags, 'con_set_flags'
|
||||||
|
|
||||||
|
import libini, \
|
||||||
|
ini.get_str, 'ini_get_str',\
|
||||||
|
ini.get_int, 'ini_get_int'
|
||||||
|
|
||||||
|
|
||||||
i_end:
|
i_end:
|
||||||
|
|
||||||
; uninitialised data
|
; uninitialised data
|
||||||
|
|
||||||
status db ?
|
status db ?
|
||||||
active_passive db ?
|
|
||||||
|
|
||||||
socketnum dd ?
|
controlsocket dd ?
|
||||||
datasocket dd ?
|
datasocket dd ?
|
||||||
offset dd ?
|
offset dd ?
|
||||||
size dd ?
|
size dd ?
|
||||||
operation dd ?
|
operation dd ?
|
||||||
|
|
||||||
size_fname dd ?
|
|
||||||
ptr_queue dd ?
|
|
||||||
timeout dd ?
|
timeout dd ?
|
||||||
ptr_fname_start dd ?
|
|
||||||
|
ptr_fname dd ?
|
||||||
|
size_fname dd ?
|
||||||
|
ptr_queue dd ?
|
||||||
|
|
||||||
|
acti_port_start dw ?
|
||||||
|
acti_port_stop dw ?
|
||||||
|
acti_port dw ?
|
||||||
|
|
||||||
|
str_active_ip rb 16
|
||||||
|
|
||||||
filestruct:
|
filestruct:
|
||||||
.subfn dd ?
|
.subfn dd ?
|
||||||
.offset dd ?
|
.offset dd ?
|
||||||
dd ?
|
dd ?
|
||||||
.size dd ?
|
.size dd ?
|
||||||
.ptr dd ?
|
.ptr dd ?
|
||||||
.name rb 1024
|
.name rb 1024
|
||||||
|
|
||||||
buf_buffer1 rb BUFFERSIZE+1
|
buf_buffer1 rb BUFFERSIZE+1
|
||||||
buf_buffer2 rb BUFFERSIZE+1
|
buf_buffer2 rb BUFFERSIZE+1
|
||||||
buf_cmd rb 1024 ; buffer for holding command string
|
buf_cmd rb 1024 ; buffer for holding command string
|
||||||
|
|
||||||
|
path rb 1024
|
||||||
|
|
||||||
mem:
|
mem:
|
||||||
|
12
programs/network/ftpc/ftpc.ini
Normal file
12
programs/network/ftpc/ftpc.ini
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
; 0 = passive / 1 = active
|
||||||
|
mode=0
|
||||||
|
dir=/tmp0/1/
|
||||||
|
|
||||||
|
[active]
|
||||||
|
; Local starting port for active connections
|
||||||
|
port_start=2000
|
||||||
|
; end port
|
||||||
|
port_stop=5000
|
||||||
|
; IP (If you're behind a NAT, use external IP)
|
||||||
|
ip=10.0.0.1
|
@ -91,8 +91,8 @@ pasv_ok:
|
|||||||
|
|
||||||
invoke con_write_asciiz, str_open
|
invoke con_write_asciiz, str_open
|
||||||
mcall connect, [datasocket], sockaddr2, 18
|
mcall connect, [datasocket], sockaddr2, 18
|
||||||
; cmp eax, -1
|
cmp eax, -1
|
||||||
; je error_socket
|
je error_socket
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
@ -116,9 +116,9 @@ data_loop:
|
|||||||
cmp [operation], OPERATION_RETR
|
cmp [operation], OPERATION_RETR
|
||||||
je .retr
|
je .retr
|
||||||
|
|
||||||
cmp [operation], OPERATION_RDIR
|
cmp [operation], OPERATION_RDIR
|
||||||
je .rdir
|
je .rdir
|
||||||
|
|
||||||
; not retreiving, just print to console
|
; not retreiving, just print to console
|
||||||
invoke con_write_asciiz, buf_buffer2
|
invoke con_write_asciiz, buf_buffer2
|
||||||
jmp data_loop
|
jmp data_loop
|
||||||
@ -155,109 +155,40 @@ data_loop:
|
|||||||
mov [operation], OPERATION_NONE
|
mov [operation], OPERATION_NONE
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
|
||||||
.rdir:
|
.rdir:
|
||||||
cmp [size_fname], 0
|
; alloc/realloc memory block to store filenames
|
||||||
jne .realloc
|
mov ecx, eax ; eax is size of buffer received
|
||||||
|
inc ecx
|
||||||
|
add ecx, [size_fname] ; added old size to form new required size
|
||||||
|
mcall 68, 20, , [ptr_fname] ; realloc
|
||||||
|
test eax, eax
|
||||||
|
je error_heap
|
||||||
|
mov [ptr_fname], eax ; eax contains the new block now
|
||||||
|
mov [ptr_queue], eax
|
||||||
|
|
||||||
.malloc: ; create a new dynamic block
|
; copy filenames into fname buffer
|
||||||
mov ecx, eax
|
mov esi, buf_buffer2
|
||||||
inc ecx
|
mov edi, eax
|
||||||
|
add edi, [size_fname]
|
||||||
mcall 68,12 ; eax now points to new buffer
|
|
||||||
|
|
||||||
test eax,eax
|
|
||||||
je error_heap
|
|
||||||
|
|
||||||
mov [ptr_fname_start], eax
|
|
||||||
|
|
||||||
jmp .rdir_init
|
|
||||||
|
|
||||||
.realloc: ; expand block created with .malloc
|
|
||||||
|
|
||||||
mov ecx, eax ; eax is size of buffer received
|
|
||||||
inc ecx
|
|
||||||
|
|
||||||
add ecx, [size_fname] ; added old size to form new required size
|
|
||||||
|
|
||||||
mcall 68,20,,[ptr_fname_start]
|
|
||||||
|
|
||||||
test eax, eax
|
|
||||||
je error_heap
|
|
||||||
|
|
||||||
mov [ptr_fname_start], eax ; eax contains the new block now
|
|
||||||
add eax, [size_fname]
|
|
||||||
|
|
||||||
.rdir_init: ; copies filenames into our buffer
|
|
||||||
|
|
||||||
mov esi, buf_buffer2
|
|
||||||
mov edi, eax
|
|
||||||
|
|
||||||
.copy_buf:
|
.copy_buf:
|
||||||
lodsb
|
lodsb
|
||||||
cmp al,13 ; ignore any \r character
|
cmp al, 13 ; ignore any carriage return character
|
||||||
je .copy_buf
|
je .copy_buf
|
||||||
stosb
|
stosb
|
||||||
|
cmp al, 10 ; linefeed marks end of filename
|
||||||
|
je @f
|
||||||
|
inc [queued]
|
||||||
|
@@:
|
||||||
|
test al, al ; 0 marks end of buffer
|
||||||
|
jne .copy_buf
|
||||||
|
|
||||||
cmp al, 10
|
; All received filenames have been copied, calculate new size of fname buffer
|
||||||
jne .not_end
|
dec edi ; dont count the trailing 0 byte
|
||||||
inc [queued]
|
sub edi, [ptr_fname]
|
||||||
|
mov [size_fname], edi
|
||||||
|
jmp data_loop
|
||||||
|
|
||||||
.not_end:
|
|
||||||
test al,al
|
|
||||||
jne .copy_buf
|
|
||||||
|
|
||||||
dec edi
|
|
||||||
dec edi
|
|
||||||
|
|
||||||
mov eax, [ptr_fname_start]
|
|
||||||
mov [ptr_queue], eax
|
|
||||||
|
|
||||||
sub edi, eax ; edi contains the current size now
|
|
||||||
mov [size_fname], edi
|
|
||||||
|
|
||||||
jmp data_loop
|
|
||||||
|
|
||||||
|
|
||||||
; files for rdir operation are queued
|
|
||||||
transfer_queued:
|
|
||||||
|
|
||||||
mov esi, [ptr_queue] ; always pointing to current part of ptr_fname_start
|
|
||||||
mov edi, buf_cmd+5 ; always point to filename for retr command
|
|
||||||
|
|
||||||
.build_filename:
|
|
||||||
lodsb
|
|
||||||
stosb
|
|
||||||
|
|
||||||
cmp al,10
|
|
||||||
je .get_file ; filename ends with character 10
|
|
||||||
test al,al
|
|
||||||
jz .null_found ; this should be end of buffer
|
|
||||||
jmp .build_filename
|
|
||||||
|
|
||||||
.null_found:
|
|
||||||
|
|
||||||
mov [queued],0
|
|
||||||
jmp .free
|
|
||||||
|
|
||||||
.get_file:
|
|
||||||
dec [queued]
|
|
||||||
jnz .after_free
|
|
||||||
|
|
||||||
.free:
|
|
||||||
mcall 68,13,[ptr_fname_start] ; freeing the buffer
|
|
||||||
test eax,eax
|
|
||||||
jz error_heap
|
|
||||||
jmp wait_for_usercommand
|
|
||||||
|
|
||||||
.after_free:
|
|
||||||
xor al,al ; appending 0 after retr command
|
|
||||||
stosb
|
|
||||||
mov eax, esi
|
|
||||||
mov [ptr_queue], eax
|
|
||||||
|
|
||||||
jmp cmd_retr
|
|
||||||
|
|
||||||
close_datacon:
|
close_datacon:
|
||||||
cmp [operation], OPERATION_NONE
|
cmp [operation], OPERATION_NONE
|
||||||
je wait_for_usercommand
|
je wait_for_usercommand
|
||||||
@ -266,7 +197,6 @@ close_datacon:
|
|||||||
jmp wait_for_usercommand
|
jmp wait_for_usercommand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ascii_dec:
|
ascii_dec:
|
||||||
|
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
|
@ -11,10 +11,10 @@ cmd_bye:
|
|||||||
; Send BYE message to the server
|
; Send BYE message to the server
|
||||||
mov dword[buf_cmd], "BYE" + 13 shl 24
|
mov dword[buf_cmd], "BYE" + 13 shl 24
|
||||||
mov byte[buf_cmd+4], 10
|
mov byte[buf_cmd+4], 10
|
||||||
mcall send, [socketnum], buf_cmd, 5, 0
|
mcall send, [controlsocket], buf_cmd, 5, 0
|
||||||
|
|
||||||
; Close the control connection
|
; Close the control connection
|
||||||
mcall close, [socketnum]
|
mcall close, [controlsocket]
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ cmd_pwd:
|
|||||||
|
|
||||||
mov dword[buf_cmd], "PWD" + 13 shl 24
|
mov dword[buf_cmd], "PWD" + 13 shl 24
|
||||||
mov byte[buf_cmd+4], 10
|
mov byte[buf_cmd+4], 10
|
||||||
mcall send, [socketnum], buf_cmd, 5, 0
|
mcall send, [controlsocket], buf_cmd, 5, 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ cmd_cwd:
|
|||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov word [edi - 2], 0x0a0d
|
mov word [edi - 2], 0x0a0d
|
||||||
|
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ cmd_dele:
|
|||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov word [edi - 2], 0x0a0d
|
mov word [edi - 2], 0x0a0d
|
||||||
|
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ cmd_list:
|
|||||||
|
|
||||||
mov dword[buf_cmd], "LIST"
|
mov dword[buf_cmd], "LIST"
|
||||||
mov word[buf_cmd+4], 0x0a0d
|
mov word[buf_cmd+4], 0x0a0d
|
||||||
mcall send, [socketnum], buf_cmd, 6, 0
|
mcall send, [controlsocket], buf_cmd, 6, 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ cmd_retr:
|
|||||||
repne scasb
|
repne scasb
|
||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov dword[edi - 2], 0x0a0d
|
mov dword[edi - 2], 0x0a0d
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
invoke con_write_asciiz, buf_cmd ; print command
|
invoke con_write_asciiz, buf_cmd ; print command
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
@ -120,15 +120,16 @@ cmd_rdir:
|
|||||||
|
|
||||||
; Request filename list from the server
|
; Request filename list from the server
|
||||||
|
|
||||||
call open_dataconnection
|
call open_dataconnection
|
||||||
|
|
||||||
mov [size_fname], 0
|
mov [ptr_fname], 0
|
||||||
|
mov [size_fname], 0
|
||||||
mov dword[buf_cmd], "NLST"
|
mov dword[buf_cmd], "NLST"
|
||||||
mov word[buf_cmd+4], 0x0a0d
|
mov word[buf_cmd+4], 0x0a0d
|
||||||
mcall send, [socketnum], buf_cmd, 6, 0
|
mcall send, [controlsocket], buf_cmd, 6, 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
cmd_stor:
|
cmd_stor:
|
||||||
|
|
||||||
call open_dataconnection
|
call open_dataconnection
|
||||||
@ -154,7 +155,7 @@ cmd_stor:
|
|||||||
repne scasb
|
repne scasb
|
||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov word [edi - 2], 0x0a0d
|
mov word [edi - 2], 0x0a0d
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -162,6 +163,8 @@ cmd_stor:
|
|||||||
cmd_lcwd:
|
cmd_lcwd:
|
||||||
|
|
||||||
mov esi, buf_cmd+5
|
mov esi, buf_cmd+5
|
||||||
|
cmp byte[esi], 10
|
||||||
|
je .print
|
||||||
mov ecx, 256-5
|
mov ecx, 256-5
|
||||||
.loop:
|
.loop:
|
||||||
lodsb
|
lodsb
|
||||||
@ -173,6 +176,7 @@ cmd_lcwd:
|
|||||||
.done:
|
.done:
|
||||||
mov byte[esi-1], 0
|
mov byte[esi-1], 0
|
||||||
mcall 30, 1, buf_cmd+5 ; set working directory
|
mcall 30, 1, buf_cmd+5 ; set working directory
|
||||||
|
.print:
|
||||||
mcall 30, 2, buf_cmd, 256 ; and read it again
|
mcall 30, 2, buf_cmd, 256 ; and read it again
|
||||||
|
|
||||||
invoke con_write_asciiz, str_lcwd
|
invoke con_write_asciiz, str_lcwd
|
||||||
@ -186,7 +190,7 @@ cmd_cdup:
|
|||||||
|
|
||||||
mov dword[buf_cmd], "CDUP"
|
mov dword[buf_cmd], "CDUP"
|
||||||
mov word[buf_cmd+4], 0x0d0a
|
mov word[buf_cmd+4], 0x0d0a
|
||||||
mcall send, [socketnum], buf_cmd, 6, 0
|
mcall send, [controlsocket], buf_cmd, 6, 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -202,7 +206,7 @@ cmd_rmd:
|
|||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov word [edi - 2], 0x0a0d
|
mov word [edi - 2], 0x0a0d
|
||||||
|
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
@ -218,7 +222,7 @@ cmd_mkd:
|
|||||||
lea esi, [edi - buf_cmd]
|
lea esi, [edi - buf_cmd]
|
||||||
mov word [edi - 2], 0x0a0d
|
mov word [edi - 2], 0x0a0d
|
||||||
|
|
||||||
mcall send, [socketnum], buf_cmd, , 0
|
mcall send, [controlsocket], buf_cmd, , 0
|
||||||
|
|
||||||
jmp wait_for_servercommand
|
jmp wait_for_servercommand
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user