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: |