Subversion Repositories Kolibri OS

Rev

Rev 8442 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8442 Rev 9164
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2013-2018. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2013-2021. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  ftpc.asm - FTP client for KolibriOS                            ;;
6
;;  ftpc.asm - FTP client for KolibriOS                            ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;  Modified by nisargshah323@gmail.com (2016)                     ;;
9
;;  Modified by nisargshah323@gmail.com (2016)                     ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;             Version 2, June 1991                                ;;
12
;;             Version 2, June 1991                                ;;
13
;;                                                                 ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
15
 
16
format binary as ""
16
format binary as ""
17
 
17
 
18
TIMEOUT                 = 3     ; seconds
18
TIMEOUT                 = 3     ; seconds
19
 
19
 
20
BUFFERSIZE              = 4096
20
BUFFERSIZE              = 4096
21
 
21
 
22
STATUS_CONNECTING       = 0
22
STATUS_CONNECTING       = 0
23
STATUS_CONNECTED        = 1
23
STATUS_CONNECTED        = 1
24
STATUS_NEEDPASSWORD     = 2
24
STATUS_NEEDPASSWORD     = 2
25
STATUS_LOGGED_IN        = 3
25
STATUS_LOGGED_IN        = 3
26
 
26
 
27
OPERATION_NONE          = 0
27
OPERATION_NONE          = 0
28
OPERATION_LIST          = 1
28
OPERATION_LIST          = 1
29
OPERATION_RETR          = 2
29
OPERATION_RETR          = 2
30
OPERATION_STOR          = 3
30
OPERATION_STOR          = 3
31
OPERATION_RDIR          = 4
31
OPERATION_RDIR          = 4
32
        
32
        
33
use32
33
use32
34
; standard header
34
; standard header
35
        db      'MENUET01'      ; signature
35
        db      'MENUET01'      ; signature
36
        dd      1               ; header version
36
        dd      1               ; header version
37
        dd      start           ; entry point
37
        dd      start           ; entry point
38
        dd      i_end           ; initialized size
38
        dd      i_end           ; initialized size
39
        dd      mem+0x1000      ; required memory
39
        dd      mem+0x1000      ; required memory
40
        dd      mem+0x1000      ; stack pointer
40
        dd      mem+0x1000      ; stack pointer
41
        dd      buf_cmd         ; parameters
41
        dd      buf_cmd         ; parameters
42
        dd      path            ; path
42
        dd      path            ; path
43
 
43
 
44
include '../../macros.inc'
44
include '../../macros.inc'
45
macro ijmp reg, addr, method
45
macro ijmp reg, addr, method
46
{   
46
{   
47
    mov  reg, [addr]
47
    mov  reg, [addr]
48
    add  reg, [method]
48
    add  reg, [method]
49
    jmp  dword[reg]
49
    jmp  dword[reg]
50
}
50
}
51
macro icall reg, addr, method, [arg]
51
macro icall reg, addr, method, [arg]
52
{  
52
{  
53
    mov  reg, [addr]
53
    mov  reg, [addr]
54
    add  reg, [method]
54
    add  reg, [method]
55
    if ~ arg eq
55
    if ~ arg eq
56
      pushd arg
56
      pushd arg
57
    end if
57
    end if
58
    call dword[reg]
58
    call dword[reg]
59
}
59
}
60
 
60
 
61
purge mov,add,sub
61
purge mov,add,sub
62
 
62
 
63
include '../../proc32.inc'
63
include '../../proc32.inc'
64
include '../../network.inc'
64
include '../../network.inc'
65
include '../../KOSfuncs.inc'
65
include '../../KOSfuncs.inc'
66
 
66
 
67
include 'console.inc'
67
include 'console.inc'
68
include 'gui.inc'
68
include 'gui.inc'
69
include 'login_gui.inc'
69
include 'login_gui.inc'
70
include 'usercommands.inc'
70
include 'usercommands.inc'
71
include 'servercommands.inc'
71
include 'servercommands.inc'
72
include 'parser.inc'
72
include 'parser.inc'
73
 
73
 
74
; TODO: Add Pasta support to FTPC
74
; TODO: Add Pasta support to FTPC
75
 
75
 
76
;;================================================================================================;;
76
;;================================================================================================;;
77
start: ;//////////////////////////////////////////////////////////////////////////////////////////;;
77
start: ;//////////////////////////////////////////////////////////////////////////////////////////;;
78
;;------------------------------------------------------------------------------------------------;;
78
;;------------------------------------------------------------------------------------------------;;
79
;? Program entry point - initialize heap, load libraries and settings                             ;;
79
;? Program entry point - initialize heap, load libraries and settings                             ;;
80
;;------------------------------------------------------------------------------------------------;;
80
;;------------------------------------------------------------------------------------------------;;
81
;>                                                                                                ;;
81
;>                                                                                                ;;
82
;;------------------------------------------------------------------------------------------------;;
82
;;------------------------------------------------------------------------------------------------;;
83
;< none                                                                                           ;;
83
;< none                                                                                           ;;
84
;;================================================================================================;;
84
;;================================================================================================;;
85
; initialize heap for using dynamic blocks
85
; initialize heap for using dynamic blocks
86
        mcall   68, 11
86
        mcall   68, 11
87
        test    eax, eax
87
        test    eax, eax
88
        je      exit2
88
        je      exit2
89
        
89
        
90
; disable all events except network event
90
; disable all events except network event
91
        mcall   40, EV_STACK
91
        mcall   40, EV_STACK
92
; load libraries
92
; load libraries
93
        stdcall dll.Load, @IMPORT
93
        stdcall dll.Load, @IMPORT
94
        test    eax, eax
94
        test    eax, eax
95
        jnz     exit
95
        jnz     exit
96
; find path to main settings file (ftpc.ini)
96
; find path to main settings file (ftpc.ini)
97
        mov     edi, path               ; Calculate the length of zero-terminated string
97
        mov     edi, path               ; Calculate the length of zero-terminated string
98
        xor     al, al
98
        xor     al, al
99
        mov     ecx, 1024
99
        mov     ecx, 1024
100
        repne   scasb
100
        repne   scasb
101
        dec     edi
101
        dec     edi
102
        mov     esi, str_ini            ; append it with '.ini', 0
102
        mov     esi, str_ini            ; append it with '.ini', 0
103
        movsd
103
        movsd
104
        movsb
104
        movsb
105
; get settings from ini
105
; get settings from ini
106
        invoke  ini.get_str, path, str_active, str_ip, str_active_ip, 16, 0
106
        invoke  ini.get_str, path, str_active, str_ip, str_active_ip, 16, 0
107
        mov     esi, str_active_ip
107
        mov     esi, str_active_ip
108
  .ip_loop:
108
  .ip_loop:
109
        lodsb
109
        lodsb
110
        test    al, al
110
        test    al, al
111
        jz      .ip_ok
111
        jz      .ip_ok
112
        cmp     al, ' '
112
        cmp     al, ' '
113
        je      .ip_ok
113
        je      .ip_ok
114
        cmp     al, '.'
114
        cmp     al, '.'
115
        jne     .ip_loop
115
        jne     .ip_loop
116
        mov     byte[esi-1], ','
116
        mov     byte[esi-1], ','
117
        jmp     .ip_loop
117
        jmp     .ip_loop
118
  .ip_ok:
118
  .ip_ok:
119
        mov     byte[esi-1], 0
119
        mov     byte[esi-1], 0
120
 
120
 
121
        invoke  ini.get_int, path, str_active, str_port_start, 64000
121
        invoke  ini.get_int, path, str_active, str_port_start, 64000
122
        mov     [acti_port_start], ax
122
        mov     [acti_port_start], ax
123
 
123
 
124
        invoke  ini.get_int, path, str_active, str_port_stop, 65000
124
        invoke  ini.get_int, path, str_active, str_port_stop, 65000
125
        mov     [acti_port_stop], ax
125
        mov     [acti_port_stop], ax
126
 
126
 
127
        invoke  ini.get_str, path, str_general, str_dir, buf_buffer1, BUFFERSIZE, 0
127
        invoke  ini.get_str, path, str_general, str_dir, buf_buffer1, BUFFERSIZE, 0
128
        mcall   30, 1, buf_buffer1                      ; set working directory
128
        mcall   30, 1, buf_buffer1                      ; set working directory
129
 
129
 
130
        ; initialize log file
130
        ; initialize log file
131
        invoke  ini.get_str, path, str_general, str_logfile, log_file, 512, 0
131
        invoke  ini.get_str, path, str_general, str_logfile, log_file, 512, 0
132
        mov     [filestruct2.subfn], 2
132
        mov     [filestruct2.subfn], 2
133
        mov     [filestruct2.offset], 0
133
        mov     [filestruct2.offset], 0
134
        mov     [filestruct2.size], 0
134
        mov     [filestruct2.size], 0
135
        mov     [filestruct2.ptr], 0
135
        mov     [filestruct2.ptr], 0
136
        mov     [filestruct2.name], log_file
136
        mov     [filestruct2.name], log_file
137
        mcall   70, filestruct2
137
        mcall   70, filestruct2
138
 
138
 
139
; Usage: ftpc [-cli] [ftp://username:password@server:port/path]
139
; Usage: ftpc [-cli] [ftp://username:password@server:port/path]
140
 
140
 
141
        ; mov     dword[buf_cmd], '-cli' ;;;; to test CLI ;;;;;
141
        ; mov     dword[buf_cmd], '-cli' ;;;; to test CLI ;;;;;
142
 
142
 
143
        cmp     byte[buf_cmd], 0
143
        cmp     byte[buf_cmd], 0
144
        jne     @f
144
        jne     @f
145
        mov     [interface_addr], gui
145
        mov     [interface_addr], gui
146
        jmp     .args_ok
146
        jmp     .args_ok
147
  @@:   cmp     dword[buf_cmd], '-cli'
147
  @@:   cmp     dword[buf_cmd], '-cli'
148
        jne     .error
148
        jne     .error
149
        mov     [interface_addr], console
149
        mov     [interface_addr], console
150
        jmp     .args_ok
150
        jmp     .args_ok
151
 
151
 
152
  .args_ok:
152
  .args_ok:
153
 
153
 
154
        icall   eax, interface_addr, interface.init
154
        icall   eax, interface_addr, interface.init
155
        ; check for ftp://username:pass@server:port/path urls
155
        ; check for ftp://username:pass@server:port/path urls
156
        cmp     dword[buf_cmd], 'ftp:'
156
        cmp     dword[buf_cmd], 'ftp:'
157
        je      parse_args
157
        je      parse_args
158
        cmp     dword[buf_cmd+5], 'ftp:'
158
        cmp     dword[buf_cmd+5], 'ftp:'
159
        je      parse_args
159
        je      parse_args
160
        ijmp    eax, interface_addr, interface.server_addr
160
        ijmp    eax, interface_addr, interface.server_addr
161
 
161
 
162
  .error:
162
  .error:
163
        call    console.init
163
        call    console.init
164
        invoke  con_write_asciiz, str_args_err
164
        invoke  con_write_asciiz, str_args_err
165
        invoke  con_getch2
165
        invoke  con_getch2
166
        call    console.exit
166
        call    console.exit
167
        jmp     exit
167
        jmp     exit
168
 
168
 
169
;;================================================================================================;;
169
;;================================================================================================;;
170
arg_handler: ;////////////////////////////////////////////////////////////////////////////////////;;
170
arg_handler: ;////////////////////////////////////////////////////////////////////////////////////;;
171
;;------------------------------------------------------------------------------------------------;;
171
;;------------------------------------------------------------------------------------------------;;
172
;? Passes initial connection info from console/GUI to FTP core and the other way around           ;;
172
;? Passes initial connection info from console/GUI to FTP core and the other way around           ;;
173
;;------------------------------------------------------------------------------------------------;;
173
;;------------------------------------------------------------------------------------------------;;
174
;> esp+4 = pointer to the argument passed to the function                                         ;;
174
;> esp+4 = pointer to the argument passed to the function                                         ;;
175
;;------------------------------------------------------------------------------------------------;;
175
;;------------------------------------------------------------------------------------------------;;
176
;< none                                                                                           ;;
176
;< none                                                                                           ;;
177
;;================================================================================================;;
177
;;================================================================================================;;
178
 
178
 
179
  .get_username:
179
  .get_username:
180
; request username
180
; request username
181
        ijmp    eax, interface_addr, interface.get_username
181
        ijmp    eax, interface_addr, interface.get_username
182
 
182
 
183
  .copy_user:
183
  .copy_user:
184
        mov     dword[buf_cmd], "USER"
184
        mov     dword[buf_cmd], "USER"
185
        mov     byte[buf_cmd+4], " "
185
        mov     byte[buf_cmd+4], " "
186
; copy user name to buf_cmd (for command line args)
186
; copy user name to buf_cmd (for command line args)
187
        mov     edi, buf_cmd+5
187
        mov     edi, buf_cmd+5
188
        mov     esi, param_user
188
        mov     esi, param_user
189
  @@:
189
  @@:
190
        movsb
190
        movsb
191
        cmp     byte [esi-1], 0
191
        cmp     byte [esi-1], 0
192
        jne     @b
192
        jne     @b
193
        mov     word[edi-1], 0x0a0d
193
        mov     word[edi-1], 0x0a0d
194
 
194
 
195
        lea     esi, [edi+1-buf_cmd]
195
        lea     esi, [edi+1-buf_cmd]
196
        jmp     server_connect.send
196
        jmp     server_connect.send
197
 
197
 
198
  .get_pass:
198
  .get_pass:
199
        mov     dword[buf_cmd], "PASS"
199
        mov     dword[buf_cmd], "PASS"
200
        mov     byte[buf_cmd+4], " "
200
        mov     byte[buf_cmd+4], " "
201
; copy password to buf_cmd (for command line args)
201
; copy password to buf_cmd (for command line args)
202
        mov     edi, buf_cmd+5
202
        mov     edi, buf_cmd+5
203
        mov     esi, param_password
203
        mov     esi, param_password
204
  @@:
204
  @@:
205
        movsb
205
        movsb
206
        cmp     byte[esi-1], 0
206
        cmp     byte[esi-1], 0
207
        jne     @b
207
        jne     @b
208
        mov     word[edi-1], 0x0a0d
208
        mov     word[edi-1], 0x0a0d
209
 
209
 
210
        lea     esi, [edi+1-buf_cmd]
210
        lea     esi, [edi+1-buf_cmd]
211
        jmp     server_connect.send
211
        jmp     server_connect.send
212
 
212
 
213
  .get_path:
213
  .get_path:
214
; copy path from param_path to buf_cmd
214
; copy path from param_path to buf_cmd
215
        mov     dword[buf_cmd], "CWD "
215
        mov     dword[buf_cmd], "CWD "
216
        mov     edi, buf_cmd+4
216
        mov     edi, buf_cmd+4
217
        mov     esi, param_path
217
        mov     esi, param_path
218
  @@:
218
  @@:
219
        lodsb
219
        lodsb
220
        stosb
220
        stosb
221
        cmp     al, 0x20
221
        cmp     al, 0x20
222
        ja      @b
222
        ja      @b
223
        mov     word[edi-1], 0x0a0d
223
        mov     word[edi-1], 0x0a0d
224
 
224
 
225
        lea     esi, [edi+1-buf_cmd]
225
        lea     esi, [edi+1-buf_cmd]
226
        jmp     server_connect.send
226
        jmp     server_connect.send
227
 
227
 
228
  .connect:
228
  .connect:
229
        ; copy server address to buf_cmd
229
        ; copy server address to buf_cmd
230
        mov     esi, param_server_addr
230
        mov     esi, param_server_addr
231
        mov     edi, buf_cmd
231
        mov     edi, buf_cmd
232
  @@:
232
  @@:
233
        lodsb
233
        lodsb
234
        stosb
234
        stosb
235
        cmp     al, 0x20
235
        cmp     al, 0x20
236
        ja      @r
236
        ja      @r
237
        mov     byte[edi-1], 0 ; delete terminating '\n'
237
        mov     byte[edi-1], 0 ; delete terminating '\n'
238
 
238
 
239
        cmp     [param_port], 0x20
239
        cmp     [param_port], 0x20
240
        jbe     server_connect.default_port
240
        jbe     server_connect.default_port
241
        mov     esi, param_port
241
        mov     esi, param_port
242
        jmp     server_connect.do_port
242
        jmp     server_connect.do_port
243
 
243
 
244
 
244
 
245
;;================================================================================================;;
245
;;================================================================================================;;
246
server_connect: ;/////////////////////////////////////////////////////////////////////////////////;;
246
server_connect: ;/////////////////////////////////////////////////////////////////////////////////;;
247
;;------------------------------------------------------------------------------------------------;;
247
;;------------------------------------------------------------------------------------------------;;
248
;? Establishes a connection to the FTP server (common block for all interfaces)                   ;;
248
;? Establishes a connection to the FTP server (common block for all interfaces)                   ;;
249
;? .do_port - Port is specified by the user and needs to be converted from ASCII                  ;;
249
;? .do_port - Port is specified by the user and needs to be converted from ASCII                  ;;
250
;;------------------------------------------------------------------------------------------------;;
250
;;------------------------------------------------------------------------------------------------;;
251
;> esi = pointer to port no.                                                                      ;;
251
;> esi = pointer to port no.                                                                      ;;
252
;;------------------------------------------------------------------------------------------------;;
252
;;------------------------------------------------------------------------------------------------;;
253
;< none                                                                                           ;;
253
;< none                                                                                           ;;
254
;;================================================================================================;;
254
;;================================================================================================;;
255
 
255
 
256
  .send:
256
  .send:
257
; send username/password/path to the server
257
; send username/password/path to the server
258
        mcall   send, [controlsocket], buf_cmd, , 0
258
        mcall   send, [controlsocket], buf_cmd, , 0
259
        icall   eax, interface_addr, interface.print, str_newline
259
        icall   eax, interface_addr, interface.print, str_newline
260
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
260
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
261
        
261
        
262
        jmp     wait_for_servercommand
262
        jmp     wait_for_servercommand
263
 
263
 
264
; resolve port if specified
264
; resolve port if specified
265
  .do_port:
265
  .do_port:
266
        xor     eax, eax
266
        xor     eax, eax
267
        xor     ebx, ebx
267
        xor     ebx, ebx
268
  .portloop:
268
  .portloop:
269
        lodsb
269
        lodsb
270
        cmp     al, 0x20
270
        cmp     al, 0x20
271
        jbe     .port_done
271
        jbe     .port_done
272
        sub     al, '0'
272
        sub     al, '0'
273
        jnb     @f
273
        jnb     @f
274
        mov     eax, str_err_host
274
        mov     eax, str_err_host
275
        jmp     error
275
        jmp     error
276
    @@: cmp     al, 9
276
    @@: cmp     al, 9
277
        jna     @f
277
        jna     @f
278
        mov     eax, str_err_host
278
        mov     eax, str_err_host
279
        jmp     error
279
        jmp     error
280
    @@: lea     ebx, [ebx*4 + ebx]
280
    @@: lea     ebx, [ebx*4 + ebx]
281
        shl     ebx, 1
281
        shl     ebx, 1
282
        add     ebx, eax
282
        add     ebx, eax
283
        jmp     .portloop
283
        jmp     .portloop
284
 
284
 
285
  .port_done:
285
  .port_done:
286
        xchg    bl, bh
286
        xchg    bl, bh
287
        mov     [sockaddr1.port], bx
287
        mov     [sockaddr1.port], bx
288
        jmp     .done
288
        jmp     .done
289
 
289
 
290
  .default_port:
290
  .default_port:
291
        mov     [sockaddr1.port], 21 shl 8
291
        mov     [sockaddr1.port], 21 shl 8
292
 
292
 
293
  .done:
293
  .done:
294
; Say to the user that we're resolving
294
; Say to the user that we're resolving
295
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
295
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
296
        icall   eax, interface_addr, interface.print, str_resolve, buf_cmd
296
        icall   eax, interface_addr, interface.print, str_resolve, buf_cmd
297
; resolve name
297
; resolve name
298
        push    esp     ; reserve stack place
298
        push    esp     ; reserve stack place
299
        invoke  getaddrinfo, buf_cmd, 0, 0, esp
299
        invoke  getaddrinfo, buf_cmd, 0, 0, esp
300
        pop     esi
300
        pop     esi
301
; test for error
301
; test for error
302
        test    eax, eax
302
        test    eax, eax
303
        jz      @f
303
        jz      @f
304
        mov     eax, str_err_resolve
304
        mov     eax, str_err_resolve
305
        jmp     error
305
        jmp     error
306
    @@:
306
    @@:
307
; write results
307
; write results
308
        icall   eax, interface_addr, interface.print, str8 ; ' (',0
308
        icall   eax, interface_addr, interface.print, str8 ; ' (',0
309
        mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
309
        mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
310
        mov     eax, [eax+sockaddr_in.sin_addr] ;
310
        mov     eax, [eax+sockaddr_in.sin_addr] ;
311
        mov     [sockaddr1.ip], eax             ;
311
        mov     [sockaddr1.ip], eax             ;
312
        invoke  inet_ntoa, eax                  ;
312
        invoke  inet_ntoa, eax                  ;
313
        icall   ebx, interface_addr, interface.print, eax, str9 ; ,')',10,0
313
        icall   ebx, interface_addr, interface.print, eax, str9 ; ,')',10,0
314
        invoke  freeaddrinfo, esi               ; free allocated memory
314
        invoke  freeaddrinfo, esi               ; free allocated memory
315
; open the socket
315
; open the socket
316
        mcall   socket, AF_INET4, SOCK_STREAM, 0
316
        mcall   socket, AF_INET4, SOCK_STREAM, 0
317
        cmp     eax, -1
317
        cmp     eax, -1
318
        jne     @f
318
        jne     @f
319
        mov     eax, str_err_socket
319
        mov     eax, str_err_socket
320
        jmp     error
320
        jmp     error
321
    @@: mov     [controlsocket], eax
321
    @@: mov     [controlsocket], eax
322
; connect to the server
322
; connect to the server
323
        icall   eax, interface_addr, interface.print, str_connect
323
        icall   eax, interface_addr, interface.print, str_connect
324
        mcall   connect, [controlsocket], sockaddr1, 18
324
        mcall   connect, [controlsocket], sockaddr1, 18
325
        cmp     eax, -1
325
        cmp     eax, -1
326
        jne     @f
326
        jne     @f
327
        mov     eax, str_err_connect
327
        mov     eax, str_err_connect
328
        jmp     error
328
        jmp     error
329
    @@: mov     [status], STATUS_CONNECTING
329
    @@: mov     [status], STATUS_CONNECTING
330
; Tell the user we're waiting for the server now.
330
; Tell the user we're waiting for the server now.
331
        icall   eax, interface_addr, interface.print, str_waiting
331
        icall   eax, interface_addr, interface.print, str_waiting
332
 
332
 
333
; Reset 'offset' variable, it's used by the data receiver
333
; Reset 'offset' variable, it's used by the data receiver
334
        mov     [offset], 0
334
        mov     [offset], 0
335
 
335
 
336
 
336
 
337
;;================================================================================================;;
337
;;================================================================================================;;
338
wait_for_servercommand: ;/////////////////////////////////////////////////////////////////////////;;
338
wait_for_servercommand: ;/////////////////////////////////////////////////////////////////////////;;
339
;;------------------------------------------------------------------------------------------------;;
339
;;------------------------------------------------------------------------------------------------;;
340
;? Checks if any data received from the server is present in buffer.                              ;;
340
;? Checks if any data received from the server is present in buffer.                              ;;
341
;? If not, receives and processes it                                                              ;;
341
;? If not, receives and processes it                                                              ;;
342
;;------------------------------------------------------------------------------------------------;;
342
;;------------------------------------------------------------------------------------------------;;
343
;>                                                                                                ;;
343
;>                                                                                                ;;
344
;;------------------------------------------------------------------------------------------------;;
344
;;------------------------------------------------------------------------------------------------;;
345
;< none                                                                                           ;;
345
;< none                                                                                           ;;
346
;;================================================================================================;;
346
;;================================================================================================;;
347
; Any commands still in our buffer?
347
; Any commands still in our buffer?
348
        cmp     [offset], 0
348
        cmp     [offset], 0
349
        je      .receive                        ; nope, receive some more
349
        je      .receive                        ; nope, receive some more
350
        mov     esi, [offset]
350
        mov     esi, [offset]
351
        mov     edi, buf_cmd
351
        mov     edi, buf_cmd
352
        mov     ecx, [size]
352
        mov     ecx, [size]
353
        add     ecx, esi
353
        add     ecx, esi
354
        jmp     .byteloop
354
        jmp     .byteloop
355
 
355
 
356
; receive socket data
356
; receive socket data with timeout
357
  .receive:
357
  .receive:
358
        mcall   26, 9
358
        mcall   26, 9
359
        add     eax, TIMEOUT*100
359
        add     eax, TIMEOUT*100
360
        mov     [timeout], eax
360
        mov     [timeout], eax
361
  .receive_loop:
361
  .again:
362
        mcall   23, 50          ; Wait for event with timeout
362
        mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
363
        mcall   26, 9
-
 
364
        cmp     eax, [timeout]
-
 
365
        jl      @f
-
 
366
        mov     eax, str_err_timeout
-
 
367
        jmp     error
363
        cmp     eax, 0
368
    @@: mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
-
 
369
        test    eax, eax
364
        jg      .got_data
370
        jnz     .got_data
365
        je      .closed
371
        cmp     ebx, EWOULDBLOCK
366
        cmp     ebx, EWOULDBLOCK
-
 
367
        jne     .sock_err
-
 
368
        mcall   26, 9
-
 
369
        mov     ebx, [timeout]
-
 
370
        sub     ebx, eax
-
 
371
        jle     .timeout
-
 
372
        mcall   23      ; Wait for event with timeout
372
        je      @f
373
        jmp     .again
-
 
374
 
-
 
375
  .sock_err:
373
        mov     eax, str_err_recv
376
        mov     eax, str_err_recv
374
        jmp     error
377
        jmp     error
-
 
378
 
-
 
379
  .closed:
-
 
380
        mov     eax, str_err_closed
375
    @@: jmp     .receive_loop
381
        jmp     error
-
 
382
 
-
 
383
  .timeout:
-
 
384
        mov     eax, str_err_timeout
-
 
385
        jmp     error
376
 
386
 
377
  .got_data:
387
  .got_data:
378
        mov     [offset], 0
388
        mov     [offset], 0
379
 
389
 
380
; extract commands, copy them to "buf_cmd" buffer
390
; extract commands, copy them to "buf_cmd" buffer
381
        lea     ecx, [eax + buf_buffer1]         ; ecx = end pointer
391
        lea     ecx, [eax + buf_buffer1]         ; ecx = end pointer
382
        mov     esi, buf_buffer1                 ; esi = current pointer
392
        mov     esi, buf_buffer1                 ; esi = current pointer
383
        mov     edi, buf_cmd
393
        mov     edi, buf_cmd
384
  .byteloop:
394
  .byteloop:
385
        cmp     esi, ecx
395
        cmp     esi, ecx
386
        jae     wait_for_servercommand
396
        jae     wait_for_servercommand
387
        lodsb
397
        lodsb
388
        cmp     al, 10                          ; excellent, we might have a command
398
        cmp     al, 10                          ; excellent, we might have a command
389
        je      .got_command
399
        je      .got_command
390
        cmp     al, 13                          ; just ignore this byte
400
        cmp     al, 13                          ; just ignore this byte
391
        je      .byteloop
401
        je      .byteloop
392
        stosb
402
        stosb
393
        jmp     .byteloop
403
        jmp     .byteloop
394
  .got_command:                                 ; we have a newline check if its a command
404
  .got_command:                                 ; we have a newline check if its a command
395
        cmp     esi, ecx
405
        cmp     esi, ecx
396
        je      .no_more_data
406
        je      .no_more_data
397
        mov     [offset], esi
407
        mov     [offset], esi
398
        sub     ecx, esi
408
        sub     ecx, esi
399
        mov     [size], ecx
409
        mov     [size], ecx
400
        jmp     .go_cmd
410
        jmp     .go_cmd
401
  .no_more_data:
411
  .no_more_data:
402
        mov     [offset], 0
412
        mov     [offset], 0
403
  .go_cmd:
413
  .go_cmd:
404
        lea     ecx, [edi - buf_cmd]                  ; length of command
414
        lea     ecx, [edi - buf_cmd]                  ; length of command
405
        xor     al, al
415
        xor     al, al
406
        stosb
416
        stosb
407
 
417
 
408
        icall   eax, interface_addr, interface.set_flags, 0x03 ; change color
418
        icall   eax, interface_addr, interface.set_flags, 0x03 ; change color
409
        icall   eax, interface_addr, interface.print, buf_cmd, str_newline
419
        icall   eax, interface_addr, interface.print, buf_cmd, str_newline
410
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
420
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color
411
 
421
 
412
        jmp     server_parser                   ; parse command
422
        jmp     server_parser                   ; parse command
413
 
423
 
414
 
424
 
415
 
425
 
416
;;================================================================================================;;
426
;;================================================================================================;;
417
wait_for_usercommand: ;///////////////////////////////////////////////////////////////////////////;;
427
wait_for_usercommand: ;///////////////////////////////////////////////////////////////////////////;;
418
;;------------------------------------------------------------------------------------------------;;
428
;;------------------------------------------------------------------------------------------------;;
419
;? Reads the FTP command entered by the user and compares it with valid FTP commands.             ;;
429
;? Reads the FTP command entered by the user and compares it with valid FTP commands.             ;;
420
;? Jumps to appropriate handling routine in usercommands.inc                                      ;;
430
;? Jumps to appropriate handling routine in usercommands.inc                                      ;;
421
;;------------------------------------------------------------------------------------------------;;
431
;;------------------------------------------------------------------------------------------------;;
422
;> status = socket connection status                                                              ;;
432
;> status = socket connection status                                                              ;;
423
;> buf_cmd = command entered by the user                                                          ;;
433
;> buf_cmd = command entered by the user                                                          ;;
424
;;------------------------------------------------------------------------------------------------;;
434
;;------------------------------------------------------------------------------------------------;;
425
;< none                                                                                           ;;
435
;< none                                                                                           ;;
426
;;================================================================================================;;
436
;;================================================================================================;;
427
 
437
 
428
; Are there any files in the transfer queue?
438
; Are there any files in the transfer queue?
429
 
439
 
430
        cmp     [queued], 0
440
        cmp     [queued], 0
431
        ja      transfer_queued                 ; Yes, transfer those first.
441
        ja      transfer_queued                 ; Yes, transfer those first.
432
 
442
 
433
; change color to green for user input
443
; change color to green for user input
434
        icall   eax, interface_addr, interface.set_flags, 0x0a
444
        icall   eax, interface_addr, interface.set_flags, 0x0a
435
 
445
 
436
; If we are not yet connected, request username/password
446
; If we are not yet connected, request username/password
437
 
447
 
438
        cmp     [status], STATUS_CONNECTED
448
        cmp     [status], STATUS_CONNECTED
439
        je      arg_handler.get_username
449
        je      arg_handler.get_username
440
 
450
 
441
        cmp     [status], STATUS_NEEDPASSWORD
451
        cmp     [status], STATUS_NEEDPASSWORD
442
        je      arg_handler.get_pass
452
        je      arg_handler.get_pass
443
 
453
 
444
        ijmp    eax, interface_addr, interface.get_cmd
454
        ijmp    eax, interface_addr, interface.get_cmd
445
 
455
 
446
  .parse_cmd:
456
  .parse_cmd:
447
        cmp     dword[buf_cmd], "cwd "
457
        cmp     dword[buf_cmd], "cwd "
448
        je      cmd_cwd
458
        je      cmd_cwd
449
 
459
 
450
        cmp     dword[buf_cmd], "mkd "
460
        cmp     dword[buf_cmd], "mkd "
451
        je      cmd_mkd
461
        je      cmd_mkd
452
 
462
 
453
        cmp     dword[buf_cmd], "rmd "
463
        cmp     dword[buf_cmd], "rmd "
454
        je      cmd_rmd
464
        je      cmd_rmd
455
 
465
 
456
        cmp     dword[buf_cmd], "pwd" + 10 shl 24
466
        cmp     dword[buf_cmd], "pwd" + 10 shl 24
457
        je      cmd_pwd
467
        je      cmd_pwd
458
 
468
 
459
        cmp     dword[buf_cmd], "bye" + 10 shl 24
469
        cmp     dword[buf_cmd], "bye" + 10 shl 24
460
        je      cmd_bye
470
        je      cmd_bye
461
 
471
 
462
        cmp     dword[buf_cmd], "rdir"
472
        cmp     dword[buf_cmd], "rdir"
463
        je      cmd_rdir
473
        je      cmd_rdir
464
        
474
        
465
        cmp     byte[buf_cmd+4], " "
475
        cmp     byte[buf_cmd+4], " "
466
        jne     @f
476
        jne     @f
467
 
477
 
468
        cmp     dword[buf_cmd], "lcwd"
478
        cmp     dword[buf_cmd], "lcwd"
469
        je      cmd_lcwd
479
        je      cmd_lcwd
470
 
480
 
471
        cmp     dword[buf_cmd], "retr"
481
        cmp     dword[buf_cmd], "retr"
472
        je      cmd_retr
482
        je      cmd_retr
473
 
483
 
474
        cmp     dword[buf_cmd], "stor"
484
        cmp     dword[buf_cmd], "stor"
475
        je      cmd_stor
485
        je      cmd_stor
476
 
486
 
477
        cmp     dword[buf_cmd], "dele"
487
        cmp     dword[buf_cmd], "dele"
478
        je      cmd_dele
488
        je      cmd_dele
479
 
489
 
480
  @@:
490
  @@:
481
        cmp     byte[buf_cmd+4], 10
491
        cmp     byte[buf_cmd+4], 10
482
        jne     @f
492
        jne     @f
483
 
493
 
484
        cmp     dword[buf_cmd], "list"
494
        cmp     dword[buf_cmd], "list"
485
        je      cmd_list
495
        je      cmd_list
486
 
496
 
487
        cmp     dword[buf_cmd], "help"
497
        cmp     dword[buf_cmd], "help"
488
        je      cmd_help
498
        je      cmd_help
489
 
499
 
490
        cmp     dword[buf_cmd], "cdup"
500
        cmp     dword[buf_cmd], "cdup"
491
        je      cmd_cdup
501
        je      cmd_cdup
492
 
502
 
493
        cmp     dword[buf_cmd], "abor"
503
        cmp     dword[buf_cmd], "abor"
494
        je      cmd_abor
504
        je      cmd_abor
495
 
505
 
496
  @@:
506
  @@:
497
; Uh oh.. unknown command, tell the user and wait for new input
507
; Uh oh.. unknown command, tell the user and wait for new input
498
        icall   eax, interface_addr, interface.print, str_unknown
508
        icall   eax, interface_addr, interface.print, str_unknown
499
        jmp     wait_for_usercommand
509
        jmp     wait_for_usercommand
500
 
510
 
501
 
511
 
502
; files for rdir operation are queued
512
; files for rdir operation are queued
503
transfer_queued:
513
transfer_queued:
504
 
514
 
505
        mov     esi, [ptr_queue]                ; always pointing to current part of ptr_fname_start
515
        mov     esi, [ptr_queue]                ; always pointing to current part of ptr_fname_start
506
        mov     edi, buf_cmd+5                  ; always point to filename for retr command
516
        mov     edi, buf_cmd+5                  ; always point to filename for retr command
507
  .build_filename:
517
  .build_filename:
508
        lodsb   
518
        lodsb   
509
        stosb
519
        stosb
510
        cmp     al, 10
520
        cmp     al, 10
511
        je      .get_file                       ; filename ends with character 10
521
        je      .get_file                       ; filename ends with character 10
512
        test    al, al
522
        test    al, al
513
        jnz     .build_filename
523
        jnz     .build_filename
514
 
524
 
515
        ; Error occured, we reached the end of the buffer before [queued] reached 0
525
        ; Error occured, we reached the end of the buffer before [queued] reached 0
516
        mov     [queued], 0
526
        mov     [queued], 0
517
        mcall   68, 13, [ptr_fname]             ; free buffer
527
        mcall   68, 13, [ptr_fname]             ; free buffer
518
        test    eax, eax
528
        test    eax, eax
519
        jz      error_heap
529
        jz      error_heap
520
        jmp     wait_for_usercommand
530
        jmp     wait_for_usercommand
521
 
531
 
522
  .get_file:
532
  .get_file:
523
        mov     byte[edi], 0                    ; end filename with 0 byte
533
        mov     byte[edi], 0                    ; end filename with 0 byte
524
        mov     [ptr_queue], esi
534
        mov     [ptr_queue], esi
525
        dec     [queued]
535
        dec     [queued]
526
        jnz     cmd_retr
536
        jnz     cmd_retr
527
 
537
 
528
        mcall   68, 13, [ptr_fname]             ; free buffer
538
        mcall   68, 13, [ptr_fname]             ; free buffer
529
        test    eax, eax
539
        test    eax, eax
530
        jz      error_heap
540
        jz      error_heap
531
        jmp     cmd_retr
541
        jmp     cmd_retr
532
 
542
 
533
 
543
 
534
 
544
 
535
open_dataconnection:
545
open_dataconnection:
536
 
546
 
537
        test    [mode], 1
547
        test    [mode], 1
538
        jnz     .active
548
        jnz     .active
539
 
549
 
540
        mcall   send, [controlsocket], str_PASV, str_PASV.length, 0
550
        mcall   send, [controlsocket], str_PASV, str_PASV.length, 0
541
        ret
551
        ret
542
 
552
 
543
  .active:
553
  .active:
544
        mcall   socket, AF_INET4, SOCK_STREAM, 0
554
        mcall   socket, AF_INET4, SOCK_STREAM, 0
545
        cmp     eax, -1
555
        cmp     eax, -1
546
        jne     @f
556
        jne     @f
547
        mov     eax, str_err_socket
557
        mov     eax, str_err_socket
548
        jmp     error
558
        jmp     error
549
    @@: mov     [datasocket], eax
559
    @@: mov     [datasocket], eax
550
 
560
 
551
        mov     ax, [acti_port_start]
561
        mov     ax, [acti_port_start]
552
        xchg    al, ah
562
        xchg    al, ah
553
        mov     [sockaddr2.port], ax
563
        mov     [sockaddr2.port], ax
554
 
564
 
555
        mcall   bind, [datasocket], sockaddr2, 18
565
        mcall   bind, [datasocket], sockaddr2, 18
556
        cmp     eax, -1
566
        cmp     eax, -1
557
        jne     @f
567
        jne     @f
558
        mov     eax, str_err_bind
568
        mov     eax, str_err_bind
559
        jmp     error
569
        jmp     error
560
    @@:
570
    @@:
561
 
571
 
562
        mcall   listen, [datasocket], 1
572
        mcall   listen, [datasocket], 1
563
        cmp     eax, -1
573
        cmp     eax, -1
564
        jne     @f
574
        jne     @f
565
        mov     eax, str_err_listen
575
        mov     eax, str_err_listen
566
        jmp     error
576
        jmp     error
567
    @@:
577
    @@:
568
 
578
 
569
        mov     dword[buf_buffer1], 'PORT'
579
        mov     dword[buf_buffer1], 'PORT'
570
        mov     byte[buf_buffer1+4], ' '
580
        mov     byte[buf_buffer1+4], ' '
571
        mov     edi, buf_buffer1+5
581
        mov     edi, buf_buffer1+5
572
        mov     esi, str_active_ip
582
        mov     esi, str_active_ip
573
  .loop:
583
  .loop:
574
        lodsb
584
        lodsb
575
        test    al, al
585
        test    al, al
576
        jz      .ip_ok
586
        jz      .ip_ok
577
        stosb
587
        stosb
578
        jmp     .loop
588
        jmp     .loop
579
  .ip_ok:
589
  .ip_ok:
580
        mov     al, ','
590
        mov     al, ','
581
        stosb
591
        stosb
582
        movzx   eax, byte[sockaddr2.port+0]
592
        movzx   eax, byte[sockaddr2.port+0]
583
        call    dword_ascii
593
        call    dword_ascii
584
        mov     al, ','
594
        mov     al, ','
585
        stosb
595
        stosb
586
        movzx   eax, byte[sockaddr2.port+1]
596
        movzx   eax, byte[sockaddr2.port+1]
587
        call    dword_ascii
597
        call    dword_ascii
588
        mov     ax, 0x0a0d
598
        mov     ax, 0x0a0d
589
        stosw
599
        stosw
590
        lea     esi, [edi - buf_buffer1]
600
        lea     esi, [edi - buf_buffer1]
591
        mcall   send, [controlsocket], buf_buffer1, , 0
601
        mcall   send, [controlsocket], buf_buffer1, , 0
592
 
602
 
593
        mcall   accept, [datasocket], sockaddr2, 18        ; time to accept the awaiting connection..
603
        mcall   accept, [datasocket], sockaddr2, 18        ; time to accept the awaiting connection..
594
        cmp     eax, -1
604
        cmp     eax, -1
595
        jne     @f
605
        jne     @f
596
        mov     eax, str_err_accept
606
        mov     eax, str_err_accept
597
        jmp     error
607
        jmp     error
598
    @@: push    eax
608
    @@: push    eax
599
        mcall   close, [datasocket]
609
        mcall   close, [datasocket]
600
        pop     [datasocket]
610
        pop     [datasocket]
601
 
611
 
602
        mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, 0
612
        mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, 0
603
 
613
 
604
        ret
614
        ret
605
 
615
 
606
; eax = input
616
; eax = input
607
; edi = ptr where to write
617
; edi = ptr where to write
608
dword_ascii:
618
dword_ascii:
609
 
619
 
610
        push    edx ebx ecx
620
        push    edx ebx ecx
611
        mov     ebx, 10
621
        mov     ebx, 10
612
        xor     ecx, ecx
622
        xor     ecx, ecx
613
 
623
 
614
       @@:
624
       @@:
615
        xor     edx, edx
625
        xor     edx, edx
616
        div     ebx
626
        div     ebx
617
        add     edx, '0'
627
        add     edx, '0'
618
        push    dx
628
        push    dx
619
        inc     ecx
629
        inc     ecx
620
        test    eax, eax
630
        test    eax, eax
621
        jnz     @r
631
        jnz     @r
622
 
632
 
623
       @@:
633
       @@:
624
        pop     ax
634
        pop     ax
625
        stosb
635
        stosb
626
        dec     ecx
636
        dec     ecx
627
        jnz     @r
637
        jnz     @r
628
 
638
 
629
        pop     ecx ebx edx
639
        pop     ecx ebx edx
630
        ret
640
        ret
631
 
641
 
632
 
642
 
633
;;================================================================================================;;
643
;;================================================================================================;;
634
write_to_file: ;//////////////////////////////////////////////////////////////////////////////////;;
644
write_to_file: ;//////////////////////////////////////////////////////////////////////////////////;;
635
;;------------------------------------------------------------------------------------------------;;
645
;;------------------------------------------------------------------------------------------------;;
636
;? Writes input buffer to log file                                                                ;;
646
;? Writes input buffer to log file                                                                ;;
637
;;------------------------------------------------------------------------------------------------;;
647
;;------------------------------------------------------------------------------------------------;;
638
;> eax = pointer to buffer                                                                        ;;
648
;> eax = pointer to buffer                                                                        ;;
639
;> ecx = size of buffer                                                                           ;;
649
;> ecx = size of buffer                                                                           ;;
640
;;------------------------------------------------------------------------------------------------;;
650
;;------------------------------------------------------------------------------------------------;;
641
;< eax = status of SF 70.3                                                                        ;;
651
;< eax = status of SF 70.3                                                                        ;;
642
;;================================================================================================;;
652
;;================================================================================================;;
643
        cmp     [logfile_offset], -1 ; if offset == -1 => logging disabled
653
        cmp     [logfile_offset], -1 ; if offset == -1 => logging disabled
644
        jne     @f
654
        jne     @f
645
        mov     eax, 0
655
        mov     eax, 0
646
        ret
656
        ret
647
      @@:
657
      @@:
648
        mov     [filestruct2.subfn], 3
658
        mov     [filestruct2.subfn], 3
649
        m2m     [filestruct2.offset], [logfile_offset]
659
        m2m     [filestruct2.offset], [logfile_offset]
650
        mov     [filestruct2.size], ecx
660
        mov     [filestruct2.size], ecx
651
        mov     [filestruct2.ptr], eax
661
        mov     [filestruct2.ptr], eax
652
        mov     [filestruct2.name], log_file
662
        mov     [filestruct2.name], log_file
653
        mcall   70, filestruct2
663
        mcall   70, filestruct2
654
        test    eax, eax
664
        test    eax, eax
655
        jz      @f
665
        jz      @f
656
        mov     [logfile_offset], -1 ; disable logging
666
        mov     [logfile_offset], -1 ; disable logging
657
        call    error_fs
667
        call    error_fs
658
        icall   ebx, interface_addr, interface.print, str_no_logging
668
        icall   ebx, interface_addr, interface.print, str_no_logging
659
        ret
669
        ret
660
      @@:
670
      @@:
661
        mov     eax, [logfile_offset]
671
        mov     eax, [logfile_offset]
662
        add     eax, ecx
672
        add     eax, ecx
663
        mov     [logfile_offset], eax
673
        mov     [logfile_offset], eax
664
        ret
674
        ret
665
 
675
 
666
;;================================================================================================;;
676
;;================================================================================================;;
667
error: ;//////////////////////////////////////////////////////////////////////////////////////////;;
677
error: ;//////////////////////////////////////////////////////////////////////////////////////////;;
668
;;------------------------------------------------------------------------------------------------;;
678
;;------------------------------------------------------------------------------------------------;;
669
;? Generic error routine. Prints the error string passed to it.                                   ;;
679
;? Generic error routine. Prints the error string passed to it.                                   ;;
670
;;------------------------------------------------------------------------------------------------;;
680
;;------------------------------------------------------------------------------------------------;;
671
;> eax = pointer to the error string                                                              ;;
681
;> eax = pointer to the error string                                                              ;;
672
;;------------------------------------------------------------------------------------------------;;
682
;;------------------------------------------------------------------------------------------------;;
673
;< none                                                                                           ;;
683
;< none                                                                                           ;;
674
;;================================================================================================;;
684
;;================================================================================================;;
675
        push    eax
685
        push    eax
676
        icall   ebx, interface_addr, interface.set_flags, 0x0c ; print errors in red
686
        icall   ebx, interface_addr, interface.set_flags, 0x0c ; print errors in red
677
        pop     eax
687
        pop     eax
678
        icall   ebx, interface_addr, interface.print, eax
688
        icall   ebx, interface_addr, interface.print, eax
679
        jmp     wait_for_keypress
689
        jmp     wait_for_keypress
680
 
690
 
681
 
691
 
682
; Error handling block for filesystem errors
692
; Error handling block for filesystem errors
683
error_fs:
693
error_fs:
684
        
694
        
685
        cmp     eax, 12
695
        cmp     eax, 12
686
        jne     @f
696
        jne     @f
687
        mov     ebx, str_fs_err_12
697
        mov     ebx, str_fs_err_12
688
  @@:
698
  @@:
689
        cmp     eax, 11
699
        cmp     eax, 11
690
        jne     @f
700
        jne     @f
691
        mov     ebx, str_fs_err_11
701
        mov     ebx, str_fs_err_11
692
  @@:
702
  @@:
693
        cmp     eax, 10
703
        cmp     eax, 10
694
        jne     @f
704
        jne     @f
695
        mov     ebx, str_fs_err_10
705
        mov     ebx, str_fs_err_10
696
  @@:
706
  @@:
697
        cmp     eax, 9
707
        cmp     eax, 9
698
        jne     @f
708
        jne     @f
699
        mov     ebx, str_fs_err_9
709
        mov     ebx, str_fs_err_9
700
  @@:
710
  @@:
701
        cmp     eax, 8
711
        cmp     eax, 8
702
        jne     @f
712
        jne     @f
703
        mov     ebx, str_fs_err_8
713
        mov     ebx, str_fs_err_8
704
  @@:
714
  @@:
705
        cmp     eax, 7
715
        cmp     eax, 7
706
        jne     @f
716
        jne     @f
707
        mov     ebx, str_fs_err_7
717
        mov     ebx, str_fs_err_7
708
  @@:
718
  @@:
709
        cmp     eax, 6
719
        cmp     eax, 6
710
        jne     @f
720
        jne     @f
711
        mov     ebx, str_fs_err_6
721
        mov     ebx, str_fs_err_6
712
  @@:
722
  @@:
713
        cmp     eax, 5
723
        cmp     eax, 5
714
        jne     @f
724
        jne     @f
715
        mov     ebx, str_fs_err_5
725
        mov     ebx, str_fs_err_5
716
  @@:
726
  @@:
717
        cmp     eax, 3
727
        cmp     eax, 3
718
        jne     @f
728
        jne     @f
719
        mov     ebx, str_fs_err_3
729
        mov     ebx, str_fs_err_3
720
  @@:
730
  @@:
721
        cmp     eax, 2
731
        cmp     eax, 2
722
        jne     @f
732
        jne     @f
723
        mov     ebx, str_fs_err_2
733
        mov     ebx, str_fs_err_2
724
  @@:
734
  @@:
725
        mov     edi, fs_error_code
735
        mov     edi, fs_error_code
726
        call    dword_ascii    ; convert error code in eax to ascii
736
        call    dword_ascii    ; convert error code in eax to ascii
727
        icall   eax, interface_addr, interface.set_flags, 0x0c ; print errors in red
737
        icall   eax, interface_addr, interface.set_flags, 0x0c ; print errors in red
728
        icall   eax, interface_addr, interface.print, str_err_fs, fs_error_code, ebx
738
        icall   eax, interface_addr, interface.print, str_err_fs, fs_error_code, ebx
729
        mov     word[fs_error_code], '  '   ; clear error code for next time
739
        mov     word[fs_error_code], '  '   ; clear error code for next time
730
        icall   eax, interface_addr, interface.set_flags, 0x0a
740
        icall   eax, interface_addr, interface.set_flags, 0x0a
731
 
741
 
732
        ret
742
        ret
733
 
743
 
734
error_heap:
744
error_heap:
735
        icall   eax, interface_addr, interface.set_flags, 0x0c ; print errors in red
745
        icall   eax, interface_addr, interface.set_flags, 0x0c ; print errors in red
736
        icall   eax, interface_addr, interface.print, str_err_heap
746
        icall   eax, interface_addr, interface.print, str_err_heap
737
        
747
        
738
wait_for_keypress:
748
wait_for_keypress:
739
        mcall   close, [controlsocket]
749
        mcall   close, [controlsocket]
740
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color to grey
750
        icall   eax, interface_addr, interface.set_flags, 0x07 ; reset color to grey
741
        icall   eax, interface_addr, interface.print, str_push
751
        icall   eax, interface_addr, interface.print, str_push
742
        ijmp    eax, interface_addr, interface.error
752
        ijmp    eax, interface_addr, interface.error
743
 
753
 
744
exit:
754
exit:
745
        mcall   close, [controlsocket]
755
        mcall   close, [controlsocket]
746
exit2:  
756
exit2:  
747
        mcall   -1
757
        mcall   -1
748
 
758
 
749
 
759
 
750
 
760
 
751
; data
761
; data
752
str_title       db 'FTP client for KolibriOS',0
762
str_title       db 'FTP client for KolibriOS',0
753
str_welcome     db 'FTP client for KolibriOS v0.15b',10
763
str_welcome     db 'FTP client for KolibriOS v0.16',10
754
                db 10,0
764
                db 10,0
755
str_srv_addr    db 'Please enter ftp server address.',10,0
765
str_srv_addr    db 'Please enter ftp server address.',10,0
756
 
766
 
757
str_prompt      db '> ',0
767
str_prompt      db '> ',0
758
str_resolve     db 'Resolving ',0
768
str_resolve     db 'Resolving ',0
759
str_newline     db 10,0
769
str_newline     db 10,0
760
str_err_resolve db 10,'Name resolution failed.',10,0
770
str_err_resolve db 10,'Name resolution failed.',10,0
-
 
771
str_err_closed  db 10,'The connection was closed by the remote end',10,0
761
str_err_socket  db 10,'[75,0 socket]: Error creating a socket',10,0
772
str_err_socket  db 10,'[75,0 socket]: Error creating a socket',10,0
762
str_err_bind    db 10,'[75,2 bind]: Error binding to socket',10,0
773
str_err_bind    db 10,'[75,2 bind]: Error binding to socket',10,0
763
str_err_listen  db 10,'[75,3 listen]: Cannot accept incoming connections',10,0
774
str_err_listen  db 10,'[75,3 listen]: Cannot accept incoming connections',10,0
764
str_err_accept  db 10,'[75,5 accept]: Error accepting a connection',10,0
775
str_err_accept  db 10,'[75,5 accept]: Error accepting a connection',10,0
765
str_err_recv    db 10,'[75,7 recv]: Error receiving data from server',10,0
776
str_err_recv    db 10,'[75,7 recv]: Error receiving data from server',10,0
766
str_err_heap    db 10,'Cannot allocate memory from heap.',10,0
777
str_err_heap    db 10,'Cannot allocate memory from heap.',10,0
767
str_err_timeout db 10,'Timeout - no response from server.',10,0
778
str_err_timeout db 10,'Timeout - no response from server.',10,0
768
str_err_connect db 10,'[75,4 connect]: Cannot connect to the server.',10,0
779
str_err_connect db 10,'[75,4 connect]: Cannot connect to the server.',10,0
769
str_err_host    db 10,'Invalid hostname.',10,0
780
str_err_host    db 10,'Invalid hostname.',10,0
770
str_err_params  db 10,'Invalid parameters',10,0
781
str_err_params  db 10,'Invalid parameters',10,0
771
str_err_fs      db 10,'File system error: code ',0
782
str_err_fs      db 10,'File system error: code ',0
772
fs_error_code   db '  ',0    ; file system error code
783
fs_error_code   db '  ',0    ; file system error code
773
str_fs_err_2    db ' [Function is not supported for the given file system]',10,0
784
str_fs_err_2    db ' [Function is not supported for the given file system]',10,0
774
str_fs_err_3    db ' [Unknown file system]',10,0
785
str_fs_err_3    db ' [Unknown file system]',10,0
775
str_fs_err_5    db ' [File/Folder not found]',10,0
786
str_fs_err_5    db ' [File/Folder not found]',10,0
776
str_fs_err_6    db ' [End of file, EOF]',10,0
787
str_fs_err_6    db ' [End of file, EOF]',10,0
777
str_fs_err_7    db ' [Pointer lies outside of application memory]',10,0
788
str_fs_err_7    db ' [Pointer lies outside of application memory]',10,0
778
str_fs_err_8    db ' [Disk is full]',10,0
789
str_fs_err_8    db ' [Disk is full]',10,0
779
str_fs_err_9    db ' [File system error]',10,0
790
str_fs_err_9    db ' [File system error]',10,0
780
str_fs_err_10   db ' [Access denied]',10,0
791
str_fs_err_10   db ' [Access denied]',10,0
781
str_fs_err_11   db ' [Device error]',10,0
792
str_fs_err_11   db ' [Device error]',10,0
782
str_fs_err_12   db ' [File system requires more memory]',10,0
793
str_fs_err_12   db ' [File system requires more memory]',10,0
783
str8            db ' (',0
794
str8            db ' (',0
784
str9            db ')',10,0
795
str9            db ')',10,0
785
str_push        db 'Push any key to continue.',0
796
str_push        db 'Push any key to continue.',0
786
str_connect     db 'Connecting...',10,0
797
str_connect     db 'Connecting...',10,0
787
str_waiting     db 'Waiting for welcome message.',10,0
798
str_waiting     db 'Waiting for welcome message.',10,0
788
str_user        db "username: ",0
799
str_user        db "username: ",0
789
str_pass        db "password: ",0
800
str_pass        db "password: ",0
790
str_port        db "port (default 21): ",0
801
str_port        db "port (default 21): ",0
791
str_path        db "path (optional): ",0
802
str_path        db "path (optional): ",0
792
str_unknown     db "Unknown command or insufficient parameters - type help for more information.",10,0
803
str_unknown     db "Unknown command or insufficient parameters - type help for more information.",10,0
793
str_lcwd        db "Local working directory is now: ",0
804
str_lcwd        db "Local working directory is now: ",0
794
str_bytes_done  db '          ',0
805
str_bytes_done  db '          ',0
795
str_downloaded  db 'Downloaded ',0
806
str_downloaded  db 'Downloaded ',0
796
str_bytes       db ' bytes',13,0
807
str_bytes       db ' bytes',13,0
797
str_args_err    db 'Invalid arguments. USAGE: ftpc [-cli] [ftp://username:password@server:port/path]',10,0
808
str_args_err    db 'Invalid arguments. USAGE: ftpc [-cli] [ftp://username:password@server:port/path]',10,0
798
 
809
 
799
str_open        db "opening data socket",10,0
810
str_open        db "opening data socket",10,0
800
str_close       db 10,"closing data socket",10,0
811
str_close       db 10,"closing data socket",10,0
801
str_dot         db '.',0
812
str_dot         db '.',0
802
 
813
 
803
str_help        db "available commands:",10
814
str_help        db "available commands:",10
804
                db 10
815
                db 10
805
                db "bye             - close the connection",10
816
                db "bye             - close the connection",10
806
                db "cdup            - change to parent of current directory on the server",10
817
                db "cdup            - change to parent of current directory on the server",10
807
                db "cwd  - change working directoy on the server",10
818
                db "cwd  - change working directoy on the server",10
808
                db "dele      - delete file from the server",10
819
                db "dele      - delete file from the server",10
809
                db "list            - list files and folders in current server directory",10
820
                db "list            - list files and folders in current server directory",10
810
                db "lcwd      - change local working directory",10
821
                db "lcwd      - change local working directory",10
811
                db "mkd  - make directory on the server",10
822
                db "mkd  - make directory on the server",10
812
                db "pwd             - print server working directory",10
823
                db "pwd             - print server working directory",10
813
                db "retr      - retreive file from the server",10
824
                db "retr      - retreive file from the server",10
814
                db "rmd  - remove directory from the server",10
825
                db "rmd  - remove directory from the server",10
815
                db "stor      - store file on the server",10
826
                db "stor      - store file on the server",10
816
                db "rdir            - retreive all files from current server dir",10
827
                db "rdir            - retreive all files from current server dir",10
817
                db 10,0
828
                db 10,0
818
 
829
 
819
str_ini         db '.ini', 0
830
str_ini         db '.ini', 0
820
str_active      db 'active', 0
831
str_active      db 'active', 0
821
str_port_start  db 'port_start', 0
832
str_port_start  db 'port_start', 0
822
str_port_stop   db 'port_stop', 0
833
str_port_stop   db 'port_stop', 0
823
str_ip          db 'ip', 0
834
str_ip          db 'ip', 0
824
str_dir         db 'dir', 0
835
str_dir         db 'dir', 0
825
str_general     db 'general', 0
836
str_general     db 'general', 0
826
str_logfile     db 'logfile',0
837
str_logfile     db 'logfile',0
827
str_no_logging  db 'Error writing to log file. Logging disabled',0
838
str_no_logging  db 'Error writing to log file. Logging disabled',0
828
 
839
 
829
queued          dd 0
840
queued          dd 0
830
mode            db 0    ; passive = 0, active = 1
841
mode            db 0    ; passive = 0, active = 1
831
 
842
 
832
 
843
 
833
; FTP strings
844
; FTP strings
834
 
845
 
835
str_PASV        db 'PASV',13,10
846
str_PASV        db 'PASV',13,10
836
.length = $ - str_PASV
847
.length = $ - str_PASV
837
 
848
 
838
sockaddr1:
849
sockaddr1:
839
        dw AF_INET4
850
        dw AF_INET4
840
.port   dw ?
851
.port   dw ?
841
.ip     dd ?
852
.ip     dd ?
842
        rb 10
853
        rb 10
843
 
854
 
844
sockaddr2:
855
sockaddr2:
845
        dw AF_INET4
856
        dw AF_INET4
846
.port   dw ?
857
.port   dw ?
847
.ip     dd ?
858
.ip     dd ?
848
        rb 10
859
        rb 10
849
 
860
 
850
struc interface
861
struc interface
851
{
862
{
852
    .init           dd 0
863
    .init           dd 0
853
    .server_addr    dd 4
864
    .server_addr    dd 4
854
    .get_username   dd 8
865
    .get_username   dd 8
855
    .get_cmd        dd 12
866
    .get_cmd        dd 12
856
    .print          dd 16
867
    .print          dd 16
857
    .set_flags      dd 20
868
    .set_flags      dd 20
858
    .list           dd 24
869
    .list           dd 24
859
    .progress       dd 28
870
    .progress       dd 28
860
    .error          dd 32
871
    .error          dd 32
861
}
872
}
862
interface interface
873
interface interface
863
 
874
 
864
; import
875
; import
865
align 4
876
align 4
866
@IMPORT:
877
@IMPORT:
867
 
878
 
868
library network, 'network.obj', libini, 'libini.obj'
879
library network, 'network.obj', libini, 'libini.obj'
869
 
880
 
870
import  network, \
881
import  network, \
871
        getaddrinfo,    'getaddrinfo', \
882
        getaddrinfo,    'getaddrinfo', \
872
        freeaddrinfo,   'freeaddrinfo', \
883
        freeaddrinfo,   'freeaddrinfo', \
873
        inet_ntoa,      'inet_ntoa'
884
        inet_ntoa,      'inet_ntoa'
874
 
885
 
875
import  libini, \
886
import  libini, \
876
        ini.get_str,    'ini_get_str', \
887
        ini.get_str,    'ini_get_str', \
877
        ini.get_int,    'ini_get_int'
888
        ini.get_int,    'ini_get_int'
878
 
889
 
879
param_user:     db 'anonymous',0
890
param_user:     db 'anonymous',0
880
rb 60
891
rb 60
881
 
892
 
882
param_server_addr db 'kolibrios.org'
893
param_server_addr db 'kolibrios.org'
883
rb 1024
894
rb 1024
884
 
895
 
885
align 4
896
align 4
886
i_end:
897
i_end:
887
; uninitialised data
898
; uninitialised data
888
 
899
 
889
run_file_70 FileInfoBlock ; required for libimg
900
run_file_70 FileInfoBlock ; required for libimg
890
 
901
 
891
new_dir_buf rb 64
902
new_dir_buf rb 64
892
folder_data rb 32+32*304
903
folder_data rb 32+32*304
893
 
904
 
894
remote_list_buf rb 1024
905
remote_list_buf rb 1024
895
file_name   rb 4096 ; required for libimg
906
file_name   rb 4096 ; required for libimg
896
conv_tabl   rb 128
907
conv_tabl   rb 128
897
ed_buffer   rb 100
908
ed_buffer   rb 100
898
tedit_buffer rb 1024
909
tedit_buffer rb 1024
899
el_focus    dd ?
910
el_focus    dd ?
900
;-----------------------
911
;-----------------------
901
 
912
 
902
procinfo        process_information
913
procinfo        process_information
903
 
914
 
904
interface_addr  rd 1
915
interface_addr  rd 1
905
 
916
 
906
status          db ?
917
status          db ?
907
 
918
 
908
file_size       dd ?
919
file_size       dd ?
909
 
920
 
910
controlsocket   dd ?
921
controlsocket   dd ?
911
datasocket      dd ?
922
datasocket      dd ?
912
offset          dd ?
923
offset          dd ?
913
size            dd ?
924
size            dd ?
914
operation       dd ?
925
operation       dd ?
915
timeout         dd ?
926
timeout         dd ?
916
 
927
 
917
ptr_fname       dd ?
928
ptr_fname       dd ?
918
size_fname      dd ?
929
size_fname      dd ?
919
ptr_queue       dd ?
930
ptr_queue       dd ?
920
 
931
 
921
acti_port_start dw ?
932
acti_port_start dw ?
922
acti_port_stop  dw ?
933
acti_port_stop  dw ?
923
acti_port       dw ?
934
acti_port       dw ?
924
 
935
 
925
str_active_ip   rb 16
936
str_active_ip   rb 16
926
 
937
 
927
filestruct:
938
filestruct:
928
  .subfn        dd ?
939
  .subfn        dd ?
929
  .offset       dd ?
940
  .offset       dd ?
930
                dd ?
941
                dd ?
931
  .size         dd ?
942
  .size         dd ?
932
  .ptr          dd ?
943
  .ptr          dd ?
933
  .name         rb 1024
944
  .name         rb 1024
934
 
945
 
935
filestruct2:
946
filestruct2:
936
  .subfn        dd ?
947
  .subfn        dd ?
937
  .offset       dd ?
948
  .offset       dd ?
938
                dd ?
949
                dd ?
939
  .size         dd ?
950
  .size         dd ?
940
  .ptr          dd ?
951
  .ptr          dd ?
941
                db ?
952
                db ?
942
  .name         dd ?
953
  .name         dd ?
943
 
954
 
944
folder_buf      rb 40
955
folder_buf      rb 40
945
 
956
 
946
 
957
 
947
buf_buffer1     rb BUFFERSIZE+1
958
buf_buffer1     rb BUFFERSIZE+1
948
buf_buffer2     rb BUFFERSIZE+1
959
buf_buffer2     rb BUFFERSIZE+1
949
buf_cmd         rb 1024                 ; buffer for holding command string
960
buf_cmd         rb 1024                 ; buffer for holding command string
950
log_file        rb 512 ; holds log file path
961
log_file        rb 512 ; holds log file path
951
logfile_offset  rd 1 
962
logfile_offset  rd 1 
952
 
963
 
953
path            rb 1024
964
path            rb 1024
954
 
965
 
955
initial_login   rb 1
966
initial_login   rb 1
956
 
967
 
957
param_password  rb 1024
968
param_password  rb 1024
958
 
969
 
959
param_path      rb 1024
970
param_path      rb 1024
960
param_port      rb 6
971
param_port      rb 6
961
 
972
 
962
sc system_colors
973
sc system_colors
963
rb 1024
974
rb 1024
964
 
975
 
965
mem:
976
mem: