Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4921 → Rev 4922

/programs/network/ftpc/ftpc.asm
27,6 → 27,7
OPERATION_LIST = 1
OPERATION_RETR = 2
OPERATION_STOR = 3
OPERATION_RDIR = 4
 
use32
; standard header
36,7 → 37,7
dd i_end ; initialized size
dd mem+0x1000 ; required memory
dd mem+0x1000 ; stack pointer
dd s ; parameters
dd buf_cmd ; parameters
dd 0 ; path
 
include '../../macros.inc'
49,6 → 50,11
include 'servercommands.inc'
 
start:
; initialize heap for using dynamic blocks
mcall 68,11
test eax,eax
je exit2
; disable all events except network event
mcall 40, EV_STACK
; load libraries
59,7 → 65,7
invoke con_start, 1
invoke con_init, 80, 25, 80, 250, str_title
; Check for parameters, if there are some, resolve the address right away
cmp byte [s], 0
cmp byte [buf_cmd], 0
jne resolve
 
main:
71,11 → 77,11
invoke con_set_flags, 0x0a
invoke con_write_asciiz, str_prompt
; read string
invoke con_gets, s, 256
invoke con_gets, buf_cmd, 256
; check for exit
test eax, eax
jz done
cmp byte [s], 10
cmp byte [buf_cmd], 10
jz done
; reset color back to grey and print newline
invoke con_set_flags, 0x07
83,7 → 89,7
 
resolve:
; delete terminating '\n'
mov esi, s
mov esi, buf_cmd
@@:
lodsb
cmp al, 0x20
91,10 → 97,10
mov byte [esi-1], 0
; Say to the user that we're resolving
invoke con_write_asciiz, str_resolve
invoke con_write_asciiz, s
invoke con_write_asciiz, buf_cmd
; resolve name
push esp ; reserve stack place
invoke getaddrinfo, s, 0, 0, esp
invoke getaddrinfo, buf_cmd, 0, 0, esp
pop esi
; test for error
test eax, eax
130,7 → 136,7
cmp [offset], 0
je .receive ; nope, receive some more
mov esi, [offset]
mov edi, s
mov edi, buf_cmd
mov ecx, [size]
add ecx, esi
jmp .byteloop
145,7 → 151,7
mcall 26, 9
cmp eax, [timeout]
jge error_timeout
mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT
mcall recv, [socketnum], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
test eax, eax
jnz .got_data
cmp ebx, EWOULDBLOCK
155,10 → 161,10
.got_data:
mov [offset], 0
 
; extract commands, copy them to "s" buffer
lea ecx, [eax + buffer_ptr] ; ecx = end pointer
mov esi, buffer_ptr ; esi = current pointer
mov edi, s
; extract commands, copy them to "buf_cmd" buffer
lea ecx, [eax + buf_buffer1] ; ecx = end pointer
mov esi, buf_buffer1 ; esi = current pointer
mov edi, buf_cmd
.byteloop:
cmp esi, ecx
jae wait_for_servercommand
179,12 → 185,12
.no_more_data:
mov [offset], 0
.go_cmd:
lea ecx, [edi - s] ; length of command
lea ecx, [edi - buf_cmd] ; length of command
xor al, al
stosb
 
invoke con_set_flags, 0x03 ; change color
invoke con_write_asciiz, s ; print servercommand
invoke con_write_asciiz, buf_cmd ; print servercommand
invoke con_write_asciiz, str_newline
invoke con_set_flags, 0x07 ; reset color
 
194,6 → 200,11
 
wait_for_usercommand:
 
; Are there any files in the transfer queue?
 
cmp [queued], 0
ja transfer_queued ; Yes, transfer those first.
; change color to green for user input
invoke con_set_flags, 0x0a
 
207,53 → 218,56
; write prompt
invoke con_write_asciiz, str_prompt
; read string
invoke con_gets, s, 256
invoke con_gets, buf_cmd, 256
 
; print a newline and reset the color back to grey
invoke con_write_asciiz, str_newline
invoke con_set_flags, 0x07
 
cmp dword[s], "cwd "
cmp dword[buf_cmd], "cwd "
je cmd_cwd
 
cmp dword[s], "mkd "
cmp dword[buf_cmd], "mkd "
je cmd_mkd
 
cmp dword[s], "rmd "
cmp dword[buf_cmd], "rmd "
je cmd_rmd
 
cmp dword[s], "pwd" + 10 shl 24
cmp dword[buf_cmd], "pwd" + 10 shl 24
je cmd_pwd
 
cmp dword[s], "bye" + 10 shl 24
cmp dword[buf_cmd], "bye" + 10 shl 24
je cmd_bye
 
cmp byte[s+4], " "
cmp dword[buf_cmd], "rdir"
je cmd_rdir
cmp byte[buf_cmd+4], " "
jne @f
 
cmp dword[s], "lcwd"
cmp dword[buf_cmd], "lcwd"
je cmd_lcwd
 
cmp dword[s], "retr"
cmp dword[buf_cmd], "retr"
je cmd_retr
 
cmp dword[s], "stor"
cmp dword[buf_cmd], "stor"
je cmd_stor
 
cmp dword[s], "dele"
cmp dword[buf_cmd], "dele"
je cmd_dele
 
@@:
cmp byte[s+4], 10
cmp byte[buf_cmd+4], 10
jne @f
 
cmp dword[s], "list"
cmp dword[buf_cmd], "list"
je cmd_list
 
cmp dword[s], "help"
cmp dword[buf_cmd], "help"
je cmd_help
 
cmp dword[s], "cdup"
cmp dword[buf_cmd], "cdup"
je cmd_cdup
 
@@:
265,8 → 279,8
.connected:
; request username
invoke con_write_asciiz, str_user
mov dword[s], "USER"
mov byte[s+4], " "
mov dword[buf_cmd], "USER"
mov byte[buf_cmd+4], " "
jmp .send
 
 
273,24 → 287,24
.needpass:
; request password
invoke con_write_asciiz, str_pass
mov dword[s], "PASS"
mov byte[s+4], " "
mov dword[buf_cmd], "PASS"
mov byte[buf_cmd+4], " "
invoke con_set_flags, 0x00 ; black text on black background for password
 
.send:
; read string
mov esi, s+5
mov esi, buf_cmd+5
invoke con_gets, esi, 256
 
; find end of string
mov edi, s+5
mov edi, buf_cmd+5
mov ecx, 256
xor al, al
repne scasb
lea esi, [edi-s]
lea esi, [edi-buf_cmd]
mov word[edi-2], 0x0a0d
; and send it to the server
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
invoke con_write_asciiz, str_newline
invoke con_set_flags, 0x07 ; reset color
332,6 → 346,10
invoke con_set_flags, 0x0c ; print errors in red
invoke con_write_asciiz, str_err_resolve
 
error_heap:
invoke con_set_flags, 0x0c ; print errors in red
invoke con_write_asciiz, str_err_heap
wait_for_keypress:
invoke con_set_flags, 0x07 ; reset color to grey
invoke con_write_asciiz, str_push
344,6 → 362,7
 
exit:
mcall close, [socketnum]
exit2:
mcall -1
 
 
359,6 → 378,7
str_newline db 10,0
str_err_resolve db 10,'Name resolution failed.',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_timeout db 10,'Timeout - no response from server.',10,0
str_err_connect db 10,'Cannot connect to the server.',10,0
str8 db ' (',0
372,8 → 392,8
str_lcwd db "Local working directory is now: ",0
 
str_open db "opening data socket",10,0
str_close db "closing data socket",10,0
str2b db '.',0
str_close db 10,"closing data socket",10,0
str_dot db '.',0
 
str_help db "available commands:",10
db 10
388,8 → 408,10
db "retr <file> - retreive file from the server",10
db "rmd <directory> - remove directory from the server",10
db "stor <file> - store file on the server",10
db "rdir - retreive all files from current server dir",10
db 10,0
 
queued dd 0
 
; FTP strings
 
446,7 → 468,10
size dd ?
operation dd ?
 
size_fname dd ?
ptr_queue dd ?
timeout dd ?
ptr_fname_start dd ?
 
filestruct:
.subfn dd ?
456,9 → 481,8
.ptr dd ?
.name rb 1024
 
buffer_ptr rb BUFFERSIZE+1
buffer_ptr2 rb BUFFERSIZE+1
buf_buffer1 rb BUFFERSIZE+1
buf_buffer2 rb BUFFERSIZE+1
buf_cmd rb 1024 ; buffer for holding command string
 
s rb 1024
 
mem:
/programs/network/ftpc/servercommands.inc
5,40 → 5,40
; first lines will have a dash instead of space after numbers,
; thus they are simply ignored in this simple command parser.
 
cmp dword[s], "150 "
cmp dword[buf_cmd], "150 "
je data_loop
 
cmp dword[s], "220 "
cmp dword[buf_cmd], "220 "
je welcome
 
; cmp dword[s], "226 "
; cmp dword[buf_cmd], "226 "
; je transfer_ok
 
cmp dword[s], "227 "
cmp dword[buf_cmd], "227 "
je pasv_ok
 
cmp dword[s], "230 "
cmp dword[buf_cmd], "230 "
je login_ok
 
; cmp dword[s], "250"
; cmp dword[buf_cmd], "250"
; je op_ok
 
cmp dword[s], "331 "
cmp dword[buf_cmd], "331 "
je pass
 
; cmp dword[s], "421 "
; cmp dword[buf_cmd], "421 "
; je timeout
 
cmp dword[s], "503 " ; login first
cmp dword[buf_cmd], "503 " ; login first
je welcome
 
cmp dword[s], "530 " ; password incorrect
cmp dword[buf_cmd], "530 " ; password incorrect
je welcome
 
cmp dword[s], "550 "
cmp dword[buf_cmd], "550 "
je close_datacon
 
cmp byte[s+3], "-"
cmp byte[buf_cmd+3], "-"
je wait_for_servercommand
jmp wait_for_usercommand
 
66,7 → 66,7
sub ecx, 4
jb .fail
mov al, "("
mov edi, s + 4
mov edi, buf_cmd + 4
repne scasb
 
mcall socket, AF_INET4, SOCK_STREAM, 0
102,27 → 102,30
 
data_loop:
 
invoke con_write_asciiz, str2b
invoke con_write_asciiz, str_dot
 
cmp [operation], OPERATION_STOR
je .stor
 
; we are receiving data
mcall recv, [datasocket], buffer_ptr2, BUFFERSIZE, 0
mcall recv, [datasocket], buf_buffer2, BUFFERSIZE, 0
test ebx, ebx
jnz .done
mov byte[buffer_ptr2 + eax], 0
mov byte[buf_buffer2 + eax], 0
 
cmp [operation], OPERATION_RETR
je .retr
 
cmp [operation], OPERATION_RDIR
je .rdir
; not retreiving, just print to console
invoke con_write_asciiz, buffer_ptr2
invoke con_write_asciiz, buf_buffer2
jmp data_loop
 
; retreiving, save to file
.retr:
mov [filestruct.ptr], buffer_ptr2
mov [filestruct.ptr], buf_buffer2
mov [filestruct.size], eax
push eax
mcall 70, filestruct
139,12 → 142,12
; jne .fileerror
add [filestruct.offset], ebx
mov esi, ebx
mcall send, [datasocket], buffer_ptr2, , 0
mcall send, [datasocket], buf_buffer2, , 0
jmp .stor
 
.last_call:
mov esi, ebx
mcall send, [datasocket], buffer_ptr2, , 0
mcall send, [datasocket], buf_buffer2, , 0
 
.done:
invoke con_write_asciiz, str_close
153,6 → 156,108
jmp wait_for_servercommand
 
 
.rdir:
cmp [size_fname], 0
jne .realloc
 
.malloc: ; create a new dynamic block
mov ecx, eax
inc ecx
 
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:
lodsb
cmp al,13 ; ignore any \r character
je .copy_buf
stosb
 
cmp al, 10
jne .not_end
inc [queued]
 
.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:
cmp [operation], OPERATION_NONE
je wait_for_usercommand
/programs/network/ftpc/usercommands.inc
9,9 → 9,9
cmd_bye:
 
; Send BYE message to the server
mov dword[s], "BYE" + 13 shl 24
mov byte[s+4], 10
mcall send, [socketnum], s, 5, 0
mov dword[buf_cmd], "BYE" + 13 shl 24
mov byte[buf_cmd+4], 10
mcall send, [socketnum], buf_cmd, 5, 0
 
; Close the control connection
mcall close, [socketnum]
20,9 → 20,9
 
cmd_pwd:
 
mov dword[s], "PWD" + 13 shl 24
mov byte[s+4], 10
mcall send, [socketnum], s, 5, 0
mov dword[buf_cmd], "PWD" + 13 shl 24
mov byte[buf_cmd+4], 10
mcall send, [socketnum], buf_cmd, 5, 0
 
jmp wait_for_servercommand
 
29,16 → 29,16
 
cmd_cwd:
 
mov dword[s], "CWD "
mov dword[buf_cmd], "CWD "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov word [edi - 2], 0x0a0d
 
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
jmp wait_for_servercommand
 
45,17 → 45,17
 
cmd_dele:
 
mov dword[s], "DELE"
mov byte[s], " "
mov dword[buf_cmd], "DELE"
mov byte[buf_cmd], " "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov word [edi - 2], 0x0a0d
 
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
jmp wait_for_servercommand
 
65,9 → 65,9
 
mov [operation], OPERATION_LIST
 
mov dword[s], "LIST"
mov word[s+4], 0x0a0d
mcall send, [socketnum], s, 6, 0
mov dword[buf_cmd], "LIST"
mov word[buf_cmd+4], 0x0a0d
mcall send, [socketnum], buf_cmd, 6, 0
 
jmp wait_for_servercommand
 
77,7 → 77,9
; Create/open the file
 
mov esi, s+5
; Create/open the file
 
mov esi, buf_cmd+5
mov ecx, 256-5
call set_filename
 
98,21 → 100,35
 
; Request the file from server
 
mov dword[s], "RETR"
mov byte[s+4], " "
mov dword[buf_cmd], "RETR"
mov byte[buf_cmd+4], " "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov dword[edi - 2], 0x0a0d
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
invoke con_write_asciiz, s ; print command
invoke con_write_asciiz, buf_cmd ; print command
jmp wait_for_servercommand
 
cmd_rdir:
 
mov [operation], OPERATION_RDIR
 
; Request filename list from the server
 
call open_dataconnection
mov [size_fname], 0
mov dword[buf_cmd], "NLST"
mov word[buf_cmd+4], 0x0a0d
mcall send, [socketnum], buf_cmd, 6, 0
 
jmp wait_for_servercommand
cmd_stor:
 
call open_dataconnection
123,22 → 139,22
mov [filestruct.offset], 0
mov [filestruct.offset+4], 0
mov [filestruct.size], BUFFERSIZE
mov [filestruct.ptr], buffer_ptr2
mov [filestruct.ptr], buf_buffer2
 
mov esi, s+5
mov esi, buf_cmd+5
mov ecx, 256-5
call set_filename
 
mov dword[s], "STOR"
mov byte[s+4], " "
mov dword[buf_cmd], "STOR"
mov byte[buf_cmd+4], " "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov word [edi - 2], 0x0a0d
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
jmp wait_for_servercommand
 
145,7 → 161,7
 
cmd_lcwd:
 
mov esi, s+5
mov esi, buf_cmd+5
mov ecx, 256-5
.loop:
lodsb
156,11 → 172,11
loop .loop
.done:
mov byte[esi-1], 0
mcall 30, 1, s+5 ; set working directory
mcall 30, 2, s, 256 ; and read it again
mcall 30, 1, buf_cmd+5 ; set working directory
mcall 30, 2, buf_cmd, 256 ; and read it again
 
invoke con_write_asciiz, str_lcwd
invoke con_write_asciiz, s
invoke con_write_asciiz, buf_cmd
invoke con_write_asciiz, str_newline
 
jmp wait_for_usercommand
168,9 → 184,9
 
cmd_cdup:
 
mov dword[s], "CDUP"
mov word[s+4], 0x0d0a
mcall send, [socketnum], s, 6, 0
mov dword[buf_cmd], "CDUP"
mov word[buf_cmd+4], 0x0d0a
mcall send, [socketnum], buf_cmd, 6, 0
 
jmp wait_for_servercommand
 
177,16 → 193,16
 
cmd_rmd:
 
mov dword[s], "RMD "
mov dword[buf_cmd], "RMD "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov word [edi - 2], 0x0a0d
 
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
jmp wait_for_servercommand
 
193,16 → 209,16
 
cmd_mkd:
 
mov dword[s], "MKD "
mov dword[buf_cmd], "MKD "
 
mov ecx, 256
xor al, al
mov edi, s
mov edi, buf_cmd
repne scasb
lea esi, [edi - s]
lea esi, [edi - buf_cmd]
mov word [edi - 2], 0x0a0d
 
mcall send, [socketnum], s, , 0
mcall send, [socketnum], buf_cmd, , 0
 
jmp wait_for_servercommand