Subversion Repositories Kolibri OS

Rev

Rev 3821 | Rev 4729 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3821 Rev 3967
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2013. All rights reserved.         ;;
3
;; Copyright (C) KolibriOS team 2013. 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
;;                                                                 ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
14
 
15
format binary as ""
15
format binary as ""
16
 
16
 
17
BUFFERSIZE              = 4096
17
BUFFERSIZE              = 4096
18
 
18
 
19
STATUS_CONNECTING       = 0
19
STATUS_CONNECTING       = 0
20
STATUS_CONNECTED        = 1
20
STATUS_CONNECTED        = 1
21
STATUS_NEEDPASSWORD     = 2
21
STATUS_NEEDPASSWORD     = 2
22
STATUS_LOGGED_IN        = 3
22
STATUS_LOGGED_IN        = 3
23
 
23
 
24
OPERATION_NONE          = 0
24
OPERATION_NONE          = 0
25
OPERATION_LIST          = 1
25
OPERATION_LIST          = 1
26
OPERATION_RETR          = 2
26
OPERATION_RETR          = 2
27
OPERATION_STOR          = 3
27
OPERATION_STOR          = 3
28
 
28
 
29
use32
29
use32
30
; standard header
30
; standard header
31
        db      'MENUET01'      ; signature
31
        db      'MENUET01'      ; signature
32
        dd      1               ; header version
32
        dd      1               ; header version
33
        dd      start           ; entry point
33
        dd      start           ; entry point
34
        dd      i_end           ; initialized size
34
        dd      i_end           ; initialized size
35
        dd      mem+0x1000      ; required memory
35
        dd      mem+0x1000      ; required memory
36
        dd      mem+0x1000      ; stack pointer
36
        dd      mem+0x1000      ; stack pointer
37
        dd      s               ; parameters
37
        dd      s               ; parameters
38
        dd      0               ; path
38
        dd      0               ; path
39
 
39
 
40
include '../../macros.inc'
40
include '../../macros.inc'
41
purge mov,add,sub
41
purge mov,add,sub
42
include '../../proc32.inc'
42
include '../../proc32.inc'
43
include '../../dll.inc'
43
include '../../dll.inc'
44
include '../../network.inc'
44
include '../../network.inc'
45
 
45
 
46
include 'usercommands.inc'
46
include 'usercommands.inc'
47
include 'servercommands.inc'
47
include 'servercommands.inc'
48
 
48
 
49
start:
49
start:
50
; disable all events
50
; disable all events
51
        mcall   40, 0
51
        mcall   40, 0
52
; load libraries
52
; load libraries
53
        stdcall dll.Load, @IMPORT
53
        stdcall dll.Load, @IMPORT
54
        test    eax, eax
54
        test    eax, eax
55
        jnz     exit
55
        jnz     exit
56
; initialize console
56
; initialize console
57
        invoke  con_start, 1
57
        invoke  con_start, 1
58
        invoke  con_init, 80, 25, 80, 250, str_title
58
        invoke  con_init, 80, 25, 80, 250, str_title
59
; Check for parameters, if there are some, resolve the address right away
59
; Check for parameters, if there are some, resolve the address right away
60
        cmp     byte [s], 0
60
        cmp     byte [s], 0
61
        jne     resolve
61
        jne     resolve
62
 
62
 
63
main:
63
main:
64
; Clear screen
64
; Clear screen
65
        invoke  con_cls
65
        invoke  con_cls
66
; Welcome user
66
; Welcome user
67
        invoke  con_write_asciiz, str_welcome
67
        invoke  con_write_asciiz, str_welcome
68
; write prompt (in green color)
68
; write prompt (in green color)
69
        invoke  con_set_flags, 0x0a
69
        invoke  con_set_flags, 0x0a
70
        invoke  con_write_asciiz, str_prompt
70
        invoke  con_write_asciiz, str_prompt
71
; read string
71
; read string
72
        invoke  con_gets, s, 256
72
        invoke  con_gets, s, 256
73
; check for exit
73
; check for exit
74
        test    eax, eax
74
        test    eax, eax
75
        jz      done
75
        jz      done
76
        cmp     byte [s], 10
76
        cmp     byte [s], 10
77
        jz      done
77
        jz      done
78
; reset color back to grey and print newline
78
; reset color back to grey and print newline
79
        invoke  con_set_flags, 0x07
79
        invoke  con_set_flags, 0x07
80
        invoke  con_write_asciiz, str_newline
80
        invoke  con_write_asciiz, str_newline
81
 
81
 
82
resolve:
82
resolve:
83
; delete terminating '\n'
83
; delete terminating '\n'
84
        mov     esi, s
84
        mov     esi, s
85
  @@:
85
  @@:
86
        lodsb
86
        lodsb
87
        cmp     al, 0x20
87
        cmp     al, 0x20
88
        ja      @r
88
        ja      @r
89
        mov     byte [esi-1], 0
89
        mov     byte [esi-1], 0
90
; Say to the user that we're resolving
90
; Say to the user that we're resolving
91
        invoke  con_write_asciiz, str_resolve
91
        invoke  con_write_asciiz, str_resolve
92
        invoke  con_write_asciiz, s
92
        invoke  con_write_asciiz, s
93
; resolve name
93
; resolve name
94
        push    esp     ; reserve stack place
94
        push    esp     ; reserve stack place
95
        invoke  getaddrinfo, s, 0, 0, esp
95
        invoke  getaddrinfo, s, 0, 0, esp
96
        pop     esi
96
        pop     esi
97
; test for error
97
; test for error
98
        test    eax, eax
98
        test    eax, eax
99
        jnz     error_resolve
99
        jnz     error_resolve
100
; write results
100
; write results
101
        invoke  con_write_asciiz, str8          ; ' (',0
101
        invoke  con_write_asciiz, str8          ; ' (',0
102
        mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
102
        mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
103
        mov     eax, [eax+sockaddr_in.sin_addr] ;
103
        mov     eax, [eax+sockaddr_in.sin_addr] ;
104
        mov     [sockaddr1.ip], eax             ;
104
        mov     [sockaddr1.ip], eax             ;
105
        invoke  inet_ntoa, eax                  ;
105
        invoke  inet_ntoa, eax                  ;
106
        invoke  con_write_asciiz, eax           ; print ip
106
        invoke  con_write_asciiz, eax           ; print ip
107
        invoke  freeaddrinfo, esi               ; free allocated memory
107
        invoke  freeaddrinfo, esi               ; free allocated memory
108
        invoke  con_write_asciiz, str9          ; ')',10,0
108
        invoke  con_write_asciiz, str9          ; ')',10,0
109
; open the socket
109
; open the socket
110
        mcall   socket, AF_INET4, SOCK_STREAM, 0
110
        mcall   socket, AF_INET4, SOCK_STREAM, 0
111
        cmp     eax, -1
111
        cmp     eax, -1
112
        je      error_socket
112
        je      error_socket
113
        mov     [socketnum], eax
113
        mov     [socketnum], eax
114
; connect to the server
114
; connect to the server
115
        invoke  con_write_asciiz, str_connect
115
        invoke  con_write_asciiz, str_connect
116
        mcall   connect, [socketnum], sockaddr1, 18
116
        mcall   connect, [socketnum], sockaddr1, 18
117
        mov     [status], STATUS_CONNECTING
117
        mov     [status], STATUS_CONNECTING
118
; Tell the user we're waiting for the server now.
118
; Tell the user we're waiting for the server now.
119
        invoke  con_write_asciiz, str_waiting
119
        invoke  con_write_asciiz, str_waiting
120
 
120
 
121
; Reset 'offset' variable, it's used by the data receiver
121
; Reset 'offset' variable, it's used by the data receiver
122
        mov     [offset], 0
122
        mov     [offset], 0
123
 
123
 
124
wait_for_servercommand:
124
wait_for_servercommand:
125
; Any commands still in our buffer?
125
; Any commands still in our buffer?
126
        cmp     [offset], 0
126
        cmp     [offset], 0
127
        je      .receive                        ; nope, receive some more
127
        je      .receive                        ; nope, receive some more
128
        mov     esi, [offset]
128
        mov     esi, [offset]
129
        mov     edi, s
129
        mov     edi, s
130
        mov     ecx, [size]
130
        mov     ecx, [size]
131
        add     ecx, esi
131
        add     ecx, esi
132
        jmp     .byteloop
132
        jmp     .byteloop
133
 
133
 
134
; receive socket data
134
; receive socket data
135
  .receive:
135
  .receive:
136
        mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
136
        mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
137
        inc     eax
137
        inc     eax
138
        jz      error_socket
138
        jz      error_socket
139
        dec     eax
139
        dec     eax
140
        jz      wait_for_servercommand
140
        jz      wait_for_servercommand
141
 
141
 
142
        mov     [offset], 0
142
        mov     [offset], 0
143
 
143
 
144
; extract commands, copy them to "s" buffer
144
; extract commands, copy them to "s" buffer
145
        lea     ecx, [eax + buffer_ptr]         ; ecx = end pointer
145
        lea     ecx, [eax + buffer_ptr]         ; ecx = end pointer
146
        mov     esi, buffer_ptr                 ; esi = current pointer
146
        mov     esi, buffer_ptr                 ; esi = current pointer
147
        mov     edi, s
147
        mov     edi, s
148
  .byteloop:
148
  .byteloop:
149
        cmp     esi, ecx
149
        cmp     esi, ecx
150
        jae     wait_for_servercommand
150
        jae     wait_for_servercommand
151
        lodsb
151
        lodsb
152
        cmp     al, 10                          ; excellent, we might have a command
152
        cmp     al, 10                          ; excellent, we might have a command
153
        je      .got_command
153
        je      .got_command
154
        cmp     al, 13                          ; just ignore this byte
154
        cmp     al, 13                          ; just ignore this byte
155
        je      .byteloop
155
        je      .byteloop
156
        stosb
156
        stosb
157
        jmp     .byteloop
157
        jmp     .byteloop
158
  .got_command:                                 ; we have a newline check if its a command
158
  .got_command:                                 ; we have a newline check if its a command
159
        cmp     esi, ecx
159
        cmp     esi, ecx
160
        je      .no_more_data
160
        je      .no_more_data
161
        mov     [offset], esi
161
        mov     [offset], esi
162
        sub     ecx, esi
162
        sub     ecx, esi
163
        mov     [size], ecx
163
        mov     [size], ecx
164
        jmp     .go_cmd
164
        jmp     .go_cmd
165
  .no_more_data:
165
  .no_more_data:
166
        mov     [offset], 0
166
        mov     [offset], 0
167
  .go_cmd:
167
  .go_cmd:
168
        lea     ecx, [edi - s]                  ; length of command
168
        lea     ecx, [edi - s]                  ; length of command
169
        xor     al, al
169
        xor     al, al
170
        stosb
170
        stosb
171
 
171
 
172
        invoke  con_set_flags, 0x03             ; change color
172
        invoke  con_set_flags, 0x03             ; change color
173
        invoke  con_write_asciiz, s             ; print servercommand
173
        invoke  con_write_asciiz, s             ; print servercommand
174
        invoke  con_write_asciiz, str_newline
174
        invoke  con_write_asciiz, str_newline
175
        invoke  con_set_flags, 0x07             ; reset color
175
        invoke  con_set_flags, 0x07             ; reset color
176
 
176
 
177
        jmp     server_parser                   ; parse command
177
        jmp     server_parser                   ; parse command
178
 
178
 
179
 
179
 
180
 
180
 
181
wait_for_usercommand:
181
wait_for_usercommand:
182
 
182
 
183
; change color to green for user input
183
; change color to green for user input
184
        invoke  con_set_flags, 0x0a
184
        invoke  con_set_flags, 0x0a
185
 
185
 
186
; If we are not yet connected, request username/password
186
; If we are not yet connected, request username/password
187
        cmp     [status], STATUS_CONNECTED
187
        cmp     [status], STATUS_CONNECTED
188
        je      .connected
188
        je      .connected
189
 
189
 
190
        cmp     [status], STATUS_NEEDPASSWORD
190
        cmp     [status], STATUS_NEEDPASSWORD
191
        je      .needpass
191
        je      .needpass
192
 
192
 
193
; write prompt
193
; write prompt
194
        invoke  con_write_asciiz, str_prompt
194
        invoke  con_write_asciiz, str_prompt
195
; read string
195
; read string
196
        invoke  con_gets, s, 256
196
        invoke  con_gets, s, 256
197
 
197
 
198
; print a newline and reset the color back to grey
198
; print a newline and reset the color back to grey
199
        invoke  con_write_asciiz, str_newline
199
        invoke  con_write_asciiz, str_newline
200
        invoke  con_set_flags, 0x07
200
        invoke  con_set_flags, 0x07
201
 
201
 
202
        cmp     dword[s], "cwd "
202
        cmp     dword[s], "cwd "
203
        je      cmd_cwd
203
        je      cmd_cwd
204
 
204
 
205
        cmp     dword[s], "mkd "
205
        cmp     dword[s], "mkd "
206
        je      cmd_mkd
206
        je      cmd_mkd
207
 
207
 
208
        cmp     dword[s], "rmd "
208
        cmp     dword[s], "rmd "
209
        je      cmd_rmd
209
        je      cmd_rmd
210
 
210
 
211
        cmp     dword[s], "pwd" + 10 shl 24
211
        cmp     dword[s], "pwd" + 10 shl 24
212
        je      cmd_pwd
212
        je      cmd_pwd
213
 
213
 
214
        cmp     dword[s], "bye" + 10 shl 24
214
        cmp     dword[s], "bye" + 10 shl 24
215
        je      cmd_bye
215
        je      cmd_bye
216
 
216
 
217
        cmp     byte[s+4], " "
217
        cmp     byte[s+4], " "
218
        jne     @f
218
        jne     @f
219
 
219
 
220
        cmp     dword[s], "lcwd"
220
        cmp     dword[s], "lcwd"
221
        je      cmd_lcwd
221
        je      cmd_lcwd
222
 
222
 
223
        cmp     dword[s], "retr"
223
        cmp     dword[s], "retr"
224
        je      cmd_retr
224
        je      cmd_retr
225
 
225
 
226
        cmp     dword[s], "stor"
226
        cmp     dword[s], "stor"
227
        je      cmd_stor
227
        je      cmd_stor
228
 
228
 
229
        cmp     dword[s], "dele"
229
        cmp     dword[s], "dele"
230
        je      cmd_dele
230
        je      cmd_dele
231
 
231
 
232
  @@:
232
  @@:
233
        cmp     byte[s+4], 10
233
        cmp     byte[s+4], 10
234
        jne     @f
234
        jne     @f
235
 
235
 
236
        cmp     dword[s], "list"
236
        cmp     dword[s], "list"
237
        je      cmd_list
237
        je      cmd_list
238
 
238
 
239
        cmp     dword[s], "help"
239
        cmp     dword[s], "help"
240
        je      cmd_help
240
        je      cmd_help
241
 
241
 
242
        cmp     dword[s], "cdup"
242
        cmp     dword[s], "cdup"
243
        je      cmd_cdup
243
        je      cmd_cdup
244
 
244
 
245
  @@:
245
  @@:
246
; Uh oh.. unknown command, tell the user and wait for new input
246
; Uh oh.. unknown command, tell the user and wait for new input
247
        invoke  con_write_asciiz, str_unknown
247
        invoke  con_write_asciiz, str_unknown
248
        jmp     wait_for_usercommand
248
        jmp     wait_for_usercommand
249
 
249
 
250
 
250
 
251
  .connected:
251
  .connected:
252
; request username
252
; request username
253
        invoke  con_write_asciiz, str_user
253
        invoke  con_write_asciiz, str_user
254
        mov     dword[s], "USER"
254
        mov     dword[s], "USER"
255
        mov     byte[s+4], " "
255
        mov     byte[s+4], " "
256
        jmp     .send
256
        jmp     .send
257
 
257
 
258
 
258
 
259
  .needpass:
259
  .needpass:
260
; request password
260
; request password
261
        invoke  con_write_asciiz, str_pass
261
        invoke  con_write_asciiz, str_pass
262
        mov     dword[s], "PASS"
262
        mov     dword[s], "PASS"
263
        mov     byte[s+4], " "
263
        mov     byte[s+4], " "
264
        invoke  con_set_flags, 0x00     ; black text on black background for password
264
        invoke  con_set_flags, 0x00     ; black text on black background for password
265
 
265
 
266
  .send:
266
  .send:
267
; read string
267
; read string
268
        mov     esi, s+5
268
        mov     esi, s+5
269
        invoke  con_gets, esi, 256
269
        invoke  con_gets, esi, 256
270
 
270
 
271
; find end of string
271
; find end of string
272
        mov     edi, s+5
272
        mov     edi, s+5
273
        mov     ecx, 256
273
        mov     ecx, 256
274
        xor     al, al
274
        xor     al, al
275
        repne   scasb
275
        repne   scasb
276
        lea     esi, [edi-s]
276
        lea     esi, [edi-s]
277
        mov     word[edi-2], 0x0a0d
277
        mov     word[edi-2], 0x0a0d
278
; and send it to the server
278
; and send it to the server
279
        mcall   send, [socketnum], s, , 0
279
        mcall   send, [socketnum], s, , 0
280
 
280
 
281
        invoke  con_write_asciiz, str_newline
281
        invoke  con_write_asciiz, str_newline
282
        invoke  con_set_flags, 0x07     ; reset color
282
        invoke  con_set_flags, 0x07     ; reset color
283
        jmp     wait_for_servercommand
283
        jmp     wait_for_servercommand
284
 
284
 
285
 
285
 
286
 
286
 
287
open_dataconnection:                    ; only passive for now..
287
open_dataconnection:                    ; only passive for now..
288
        cmp     [status], STATUS_LOGGED_IN
288
        cmp     [status], STATUS_LOGGED_IN
289
        jne     .fail
289
        jne     .fail
290
 
290
 
291
        mcall   send, [socketnum], str_PASV, str_PASV.length, 0
291
        mcall   send, [socketnum], str_PASV, str_PASV.length, 0
292
        ret
292
        ret
293
 
293
 
294
  .fail:
294
  .fail:
295
        invoke  con_get_flags
295
        invoke  con_get_flags
296
        push    eax
296
        push    eax
297
        invoke  con_set_flags, 0x0c                     ; print errors in red
297
        invoke  con_set_flags, 0x0c                     ; print errors in red
298
        invoke  con_write_asciiz, str_err_socket
298
        invoke  con_write_asciiz, str_err_socket
299
        invoke  con_set_flags                           ; reset color
299
        invoke  con_set_flags                           ; reset color
300
        ret
300
        ret
301
 
301
 
302
 
302
 
303
 
303
 
304
error_socket:
304
error_socket:
305
        invoke  con_set_flags, 0x0c                     ; print errors in red
305
        invoke  con_set_flags, 0x0c                     ; print errors in red
306
        invoke  con_write_asciiz, str_err_socket
306
        invoke  con_write_asciiz, str_err_socket
307
        jmp     wait_for_keypress
307
        jmp     wait_for_keypress
308
 
308
 
309
error_resolve:
309
error_resolve:
310
        invoke  con_set_flags, 0x0c                     ; print errors in red
310
        invoke  con_set_flags, 0x0c                     ; print errors in red
311
        invoke  con_write_asciiz, str_err_resolve
311
        invoke  con_write_asciiz, str_err_resolve
312
 
312
 
313
wait_for_keypress:
313
wait_for_keypress:
314
        invoke  con_set_flags, 0x07                     ; reset color to grey
314
        invoke  con_set_flags, 0x07                     ; reset color to grey
315
        invoke  con_write_asciiz, str_push
315
        invoke  con_write_asciiz, str_push
316
        invoke  con_getch2
316
        invoke  con_getch2
317
        mcall   close, [socketnum]
317
        mcall   close, [socketnum]
318
        jmp     main
318
        jmp     main
319
 
319
 
320
done:
320
done:
321
        invoke  con_exit, 1
321
        invoke  con_exit, 1
322
 
322
 
323
exit:
323
exit:
324
        mcall   close, [socketnum]
324
        mcall   close, [socketnum]
325
        mcall   -1
325
        mcall   -1
326
 
326
 
327
 
327
 
328
 
328
 
329
; data
329
; data
330
str_title       db 'FTP client',0
330
str_title       db 'FTP client',0
331
str_welcome     db 'FTP client for KolibriOS v0.10',10
331
str_welcome     db 'FTP client for KolibriOS v0.10',10
332
                db 10
332
                db 10
333
                db 'Please enter ftp server address.',10,0
333
                db 'Please enter ftp server address.',10,0
334
 
334
 
335
str_prompt      db '> ',0
335
str_prompt      db '> ',0
336
str_resolve     db 'Resolving ',0
336
str_resolve     db 'Resolving ',0
337
str_newline     db 10,0
337
str_newline     db 10,0
338
str_err_resolve db 10,'Name resolution failed.',10,0
338
str_err_resolve db 10,'Name resolution failed.',10,0
339
str_err_socket  db 10,'Socket error.',10,0
339
str_err_socket  db 10,'Socket error.',10,0
340
str8            db ' (',0
340
str8            db ' (',0
341
str9            db ')',10,0
341
str9            db ')',10,0
342
str_push        db 'Push any key to continue.',0
342
str_push        db 'Push any key to continue.',0
343
str_connect     db 'Connecting...',10,0
343
str_connect     db 'Connecting...',10,0
344
str_waiting     db 'Waiting for welcome message.',10,0
344
str_waiting     db 'Waiting for welcome message.',10,0
345
str_user        db "username: ",0
345
str_user        db "username: ",0
346
str_pass        db "password: ",0
346
str_pass        db "password: ",0
347
str_unknown     db "Unknown command or insufficient parameters - type help for more information.",10,0
347
str_unknown     db "Unknown command or insufficient parameters - type help for more information.",10,0
348
str_lcwd        db "Local working directory is now: ",0
348
str_lcwd        db "Local working directory is now: ",0
349
 
349
 
350
str_open        db "opening data socket",10,0
350
str_open        db "opening data socket",10,0
-
 
351
str_close       db "closing data socket",10,0
-
 
352
str2b           db '.',0
351
 
353
 
352
str_help        db "available commands:",10
354
str_help        db "available commands:",10
353
                db 10
355
                db 10
354
                db "bye             - close the connection",10
356
                db "bye             - close the connection",10
355
                db "cdup            - change to parent of current directory on the server",10
357
                db "cdup            - change to parent of current directory on the server",10
356
                db "cwd  - change working directoy on the server",10
358
                db "cwd  - change working directoy on the server",10
357
                db "dele      - delete file from the server",10
359
                db "dele      - delete file from the server",10
358
                db "list            - list files and folders in current server directory",10
360
                db "list            - list files and folders in current server directory",10
359
                db "lcwd      - change local working directory",10
361
                db "lcwd      - change local working directory",10
360
                db "mkd  - make directory on the server",10
362
                db "mkd  - make directory on the server",10
361
                db "pwd             - print server working directory",10
363
                db "pwd             - print server working directory",10
362
                db "retr      - retreive file from the server",10
364
                db "retr      - retreive file from the server",10
363
                db "rmd  - remove directory from the server",10
365
                db "rmd  - remove directory from the server",10
364
                db "stor      - store file on the server",10
366
                db "stor      - store file on the server",10
365
                db 10,0
367
                db 10,0
366
 
368
 
367
 
369
 
368
; FTP strings
370
; FTP strings
369
 
371
 
370
str_PASV        db 'PASV',13,10
372
str_PASV        db 'PASV',13,10
371
.length = $ - str_PASV
373
.length = $ - str_PASV
372
 
374
 
373
sockaddr1:
375
sockaddr1:
374
        dw AF_INET4
376
        dw AF_INET4
375
.port   dw 0x1500       ; 21
377
.port   dw 0x1500       ; 21
376
.ip     dd 0
378
.ip     dd 0
377
        rb 10
379
        rb 10
378
 
380
 
379
sockaddr2:
381
sockaddr2:
380
        dw AF_INET4
382
        dw AF_INET4
381
.port   dw 0
383
.port   dw 0
382
.ip     dd 0
384
.ip     dd 0
383
        rb 10
385
        rb 10
384
 
386
 
385
; import
387
; import
386
align 4
388
align 4
387
@IMPORT:
389
@IMPORT:
388
 
390
 
389
library network, 'network.obj', console, 'console.obj'
391
library network, 'network.obj', console, 'console.obj'
390
 
392
 
391
import  network,        \
393
import  network,        \
392
        getaddrinfo,    'getaddrinfo',  \
394
        getaddrinfo,    'getaddrinfo',  \
393
        freeaddrinfo,   'freeaddrinfo', \
395
        freeaddrinfo,   'freeaddrinfo', \
394
        inet_ntoa,      'inet_ntoa'
396
        inet_ntoa,      'inet_ntoa'
395
 
397
 
396
import  console,        \
398
import  console,        \
397
        con_start,      'START',        \
399
        con_start,      'START',        \
398
        con_init,       'con_init',     \
400
        con_init,       'con_init',     \
399
        con_write_asciiz,'con_write_asciiz',     \
401
        con_write_asciiz,'con_write_asciiz',     \
400
        con_exit,       'con_exit',     \
402
        con_exit,       'con_exit',     \
401
        con_gets,       'con_gets',\
403
        con_gets,       'con_gets',\
402
        con_cls,        'con_cls',\
404
        con_cls,        'con_cls',\
403
        con_getch2,     'con_getch2',\
405
        con_getch2,     'con_getch2',\
404
        con_set_cursor_pos, 'con_set_cursor_pos',\
406
        con_set_cursor_pos, 'con_set_cursor_pos',\
405
        con_write_string, 'con_write_string',\
407
        con_write_string, 'con_write_string',\
406
        con_get_flags,  'con_get_flags', \
408
        con_get_flags,  'con_get_flags', \
407
        con_set_flags,  'con_set_flags'
409
        con_set_flags,  'con_set_flags'
408
 
410
 
409
 
411
 
410
i_end:
412
i_end:
411
 
413
 
412
; uninitialised data
414
; uninitialised data
413
 
415
 
414
status          db ?
416
status          db ?
415
active_passive  db ?
417
active_passive  db ?
416
 
418
 
417
socketnum       dd ?
419
socketnum       dd ?
418
datasocket      dd ?
420
datasocket      dd ?
419
offset          dd ?
421
offset          dd ?
420
size            dd ?
422
size            dd ?
421
operation       dd ?
423
operation       dd ?
422
 
424
 
423
filestruct:
425
filestruct:
424
.subfn  dd ?
426
.subfn  dd ?
425
.offset dd ?
427
.offset dd ?
426
        dd ?
428
        dd ?
427
.size   dd ?
429
.size   dd ?
428
.ptr    dd ?
430
.ptr    dd ?
429
.name   rb 1024
431
.name   rb 1024
430
 
432
 
431
buffer_ptr      rb BUFFERSIZE+1
433
buffer_ptr      rb BUFFERSIZE+1
432
buffer_ptr2     rb BUFFERSIZE+1
434
buffer_ptr2     rb BUFFERSIZE+1
433
 
435
 
434
s               rb 1024
436
s               rb 1024
435
 
437
 
436
mem:
438
mem: