6,7 → 6,6 |
;; ftpc.asm - FTP client for KolibriOS ;; |
;; ;; |
;; Written by hidnplayr@kolibrios.org ;; |
;; Modified by nisargshah323@gmail.com (2016) ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
42,49 → 41,16 |
dd path ; path |
|
include '../../macros.inc' |
macro ijmp reg, addr, method |
{ |
mov reg, [addr] |
add reg, [method] |
jmp dword[reg] |
} |
macro icall reg, addr, method, [arg] |
{ |
mov reg, [addr] |
add reg, [method] |
if ~ arg eq |
pushd arg |
end if |
call dword[reg] |
} |
|
purge mov,add,sub |
|
include '../../proc32.inc' |
include '../../dll.inc' |
include '../../network.inc' |
|
include '../../develop/libraries/box_lib/trunk/box_lib.mac' |
include '../../develop/libraries/box_lib/load_lib.mac' |
|
include 'console.inc' |
include 'gui.inc' |
include 'login_gui.inc' |
include 'usercommands.inc' |
include 'servercommands.inc' |
include 'parser.inc' |
|
; TODO: Add Pasta support to FTPC |
|
;;================================================================================================;; |
start: ;//////////////////////////////////////////////////////////////////////////////////////////;; |
;;------------------------------------------------------------------------------------------------;; |
;? Program entry point - initialize heap, load libraries and settings ;; |
;;------------------------------------------------------------------------------------------------;; |
;> ;; |
;;------------------------------------------------------------------------------------------------;; |
;< none ;; |
;;================================================================================================;; |
start: |
; initialize heap for using dynamic blocks |
mcall 68,11 |
test eax,eax |
96,6 → 62,9 |
stdcall dll.Load, @IMPORT |
test eax, eax |
jnz exit |
; initialize console |
invoke con_start, 1 |
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 |
130,144 → 99,48 |
invoke ini.get_str, path, str_general, str_dir, buf_buffer1, BUFFERSIZE, 0 |
mcall 30, 1, buf_buffer1 ; set working directory |
|
; initialize log file |
invoke ini.get_str, path, str_general, str_logfile, log_file, 512, 0 |
mov [filestruct2.subfn], 2 |
mov [filestruct2.offset], 0 |
mov [filestruct2.size], 0 |
mov [filestruct2.ptr], 0 |
mov [filestruct2.name], log_file |
mcall 70, filestruct2 |
|
; Usage: ftpc [-cli] [ftp://username:password@server:port/path] |
|
; mov dword[buf_cmd], '-cli' ;;;; to test CLI ;;;;; |
|
; 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 |
jne @f |
mov [interface_addr], gui |
jmp .args_ok |
@@: cmp dword[buf_cmd], '-cli' |
jne .error |
mov [interface_addr], console |
jmp .args_ok |
jne resolve |
|
.args_ok: |
main: |
; Clear screen |
invoke con_cls |
; Welcome user |
invoke con_write_asciiz, str_welcome |
; write prompt (in green color) |
invoke con_set_flags, 0x0a |
invoke con_write_asciiz, str_prompt |
; read string |
invoke con_gets, buf_cmd, 256 |
; check for exit |
test eax, eax |
jz done |
cmp byte [buf_cmd], 10 |
jz done |
; reset color back to grey and print newline |
invoke con_set_flags, 0x07 |
invoke con_write_asciiz, str_newline |
|
icall eax, interface_addr, interface.init |
; check for ftp://username:pass@server:port/path urls |
cmp dword[buf_cmd], 'ftp:' |
je parse_args |
cmp dword[buf_cmd+5], 'ftp:' |
je parse_args |
ijmp eax, interface_addr, interface.server_addr |
no_resolve: |
mov [sockaddr1.port], 21 shl 8 |
|
.error: |
call console.init |
invoke con_write_asciiz, str_args_err |
invoke con_getch2 |
call console.exit |
jmp exit |
|
;;================================================================================================;; |
arg_handler: ;////////////////////////////////////////////////////////////////////////////////////;; |
;;------------------------------------------------------------------------------------------------;; |
;? Passes initial connection info from console/GUI to FTP core and the other way around ;; |
;;------------------------------------------------------------------------------------------------;; |
;> esp+4 = pointer to the argument passed to the function ;; |
;;------------------------------------------------------------------------------------------------;; |
;< none ;; |
;;================================================================================================;; |
|
.get_username: |
; request username |
ijmp eax, interface_addr, interface.get_username |
|
.copy_user: |
mov dword[buf_cmd], "USER" |
mov byte[buf_cmd+4], " " |
; copy user name to buf_cmd (for command line args) |
mov edi, buf_cmd+5 |
mov esi, param_user |
; delete terminating '\n' |
mov esi, buf_cmd |
@@: |
movsb |
cmp byte [esi-1], 0 |
jne @b |
mov word[edi-1], 0x0a0d |
|
lea esi, [edi+1-buf_cmd] |
jmp server_connect.send |
|
.get_pass: |
mov dword[buf_cmd], "PASS" |
mov byte[buf_cmd+4], " " |
; copy password to buf_cmd (for command line args) |
mov edi, buf_cmd+5 |
mov esi, param_password |
@@: |
movsb |
cmp byte[esi-1], 0 |
jne @b |
mov word[edi-1], 0x0a0d |
|
lea esi, [edi+1-buf_cmd] |
jmp server_connect.send |
|
.get_path: |
; copy path from param_path to buf_cmd |
mov dword[buf_cmd], "CWD " |
mov edi, buf_cmd+4 |
mov esi, param_path |
@@: |
lodsb |
stosb |
cmp al, ':' |
je .do_port |
cmp al, 0x20 |
ja @b |
mov word[edi-1], 0x0a0d |
|
lea esi, [edi+1-buf_cmd] |
jmp server_connect.send |
|
.connect: |
; copy server address to buf_cmd |
mov esi, param_server_addr |
mov edi, buf_cmd |
@@: |
lodsb |
stosb |
cmp al, 0x20 |
ja @r |
mov byte[edi-1], 0 ; delete terminating '\n' |
mov byte [esi-1], 0 |
jmp .done |
|
cmp [param_port], 0x20 |
jbe server_connect.default_port |
mov esi, param_port |
jmp server_connect.do_port |
|
|
;;================================================================================================;; |
server_connect: ;/////////////////////////////////////////////////////////////////////////////////;; |
;;------------------------------------------------------------------------------------------------;; |
;? Establishes a connection to the FTP server (common block for all interfaces) ;; |
;? .do_port - Port is specified by the user and needs to be converted from ASCII ;; |
;;------------------------------------------------------------------------------------------------;; |
;> esi = pointer to port no. ;; |
;;------------------------------------------------------------------------------------------------;; |
;< none ;; |
;;================================================================================================;; |
|
.send: |
; send username/password/path to the server |
mcall send, [controlsocket], buf_cmd, , 0 |
icall eax, interface_addr, interface.print, str_newline |
icall eax, interface_addr, interface.set_flags, 0x07 ; reset color |
|
jmp wait_for_servercommand |
|
; resolve port if specified |
.do_port: |
xor eax, eax |
xor ebx, ebx |
mov byte [esi-1], 0 |
.portloop: |
lodsb |
cmp al, 0x20 |
288,15 → 161,11 |
.port_done: |
xchg bl, bh |
mov [sockaddr1.port], bx |
jmp .done |
|
.default_port: |
mov [sockaddr1.port], 21 shl 8 |
|
.done: |
; Say to the user that we're resolving |
icall eax, interface_addr, interface.set_flags, 0x07 ; reset color |
icall eax, interface_addr, interface.print, str_resolve, buf_cmd |
invoke con_write_asciiz, str_resolve |
invoke con_write_asciiz, buf_cmd |
; resolve name |
push esp ; reserve stack place |
invoke getaddrinfo, buf_cmd, 0, 0, esp |
308,13 → 177,14 |
jmp error |
@@: |
; write results |
icall eax, interface_addr, interface.print, str8 ; ' (',0 |
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 ; |
icall ebx, interface_addr, interface.print, eax, str9 ; <ip>,')',10,0 |
invoke con_write_asciiz, eax ; print ip |
invoke freeaddrinfo, esi ; free allocated memory |
invoke con_write_asciiz, str9 ; ')',10,0 |
; open the socket |
mcall socket, AF_INET4, SOCK_STREAM, 0 |
cmp eax, -1 |
323,7 → 193,7 |
jmp error |
@@: mov [controlsocket], eax |
; connect to the server |
icall eax, interface_addr, interface.print, str_connect |
invoke con_write_asciiz, str_connect |
mcall connect, [controlsocket], sockaddr1, 18 |
cmp eax, -1 |
jne @f |
331,22 → 201,12 |
jmp error |
@@: mov [status], STATUS_CONNECTING |
; Tell the user we're waiting for the server now. |
icall eax, interface_addr, interface.print, str_waiting |
invoke con_write_asciiz, str_waiting |
|
; Reset 'offset' variable, it's used by the data receiver |
mov [offset], 0 |
|
|
;;================================================================================================;; |
wait_for_servercommand: ;/////////////////////////////////////////////////////////////////////////;; |
;;------------------------------------------------------------------------------------------------;; |
;? Checks if any data received from the server is present in buffer. ;; |
;? If not, receives and processes it ;; |
;;---------------------- |