Subversion Repositories Kolibri OS

Rev

Rev 4922 | Rev 6394 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3701 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4729 hidnplayr 3
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved.    ;;
3701 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ftpc.asm - FTP client for KolibriOS                            ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
15
format binary as ""
16
 
4918 hidnplayr 17
TIMEOUT                 = 3     ; seconds
18
 
3800 hidnplayr 19
BUFFERSIZE              = 4096
3701 hidnplayr 20
 
21
STATUS_CONNECTING       = 0
22
STATUS_CONNECTED        = 1
23
STATUS_NEEDPASSWORD     = 2
24
STATUS_LOGGED_IN        = 3
25
 
3821 hidnplayr 26
OPERATION_NONE          = 0
27
OPERATION_LIST          = 1
28
OPERATION_RETR          = 2
29
OPERATION_STOR          = 3
5011 hidnplayr 30
OPERATION_RDIR          = 4
31
 
3701 hidnplayr 32
use32
33
; standard header
34
        db      'MENUET01'      ; signature
35
        dd      1               ; header version
36
        dd      start           ; entry point
37
        dd      i_end           ; initialized size
38
        dd      mem+0x1000      ; required memory
39
        dd      mem+0x1000      ; stack pointer
4922 ashmew2 40
        dd      buf_cmd         ; parameters
5011 hidnplayr 41
        dd      path            ; path
3701 hidnplayr 42
 
43
include '../../macros.inc'
44
purge mov,add,sub
45
include '../../proc32.inc'
46
include '../../dll.inc'
47
include '../../network.inc'
48
 
49
include 'usercommands.inc'
50
include 'servercommands.inc'
51
 
52
start:
4922 ashmew2 53
; initialize heap for using dynamic blocks
5011 hidnplayr 54
        mcall   68,11
55
        test    eax,eax
56
        je      exit2
57
 
4918 hidnplayr 58
; disable all events except network event
59
        mcall   40, EV_STACK
3701 hidnplayr 60
; load libraries
61
        stdcall dll.Load, @IMPORT
62
        test    eax, eax
63
        jnz     exit
64
; initialize console
3789 hidnplayr 65
        invoke  con_start, 1
3813 hidnplayr 66
        invoke  con_init, 80, 25, 80, 250, str_title
5011 hidnplayr 67
; find path to main settings file (ftpc.ini)
68
        mov     edi, path               ; Calculate the length of zero-terminated string
69
        xor     al, al
70
        mov     ecx, 1024
71
        repne   scasb
72
        dec     edi
73
        mov     esi, str_ini            ; append it with '.ini', 0
74
        movsd
75
        movsb
76
; get settings from ini
77
        invoke  ini.get_str, path, str_active, str_ip, str_active_ip, 16, 0
78
        mov     esi, str_active_ip
79
  .ip_loop:
80
        lodsb
81
        test    al, al
82
        jz      .ip_ok
83
        cmp     al, ' '
84
        je      .ip_ok
85
        cmp     al, '.'
86
        jne     .ip_loop
87
        mov     byte[esi-1], ','
88
        jmp     .ip_loop
89
  .ip_ok:
90
        mov     byte[esi-1], 0
91
 
92
        invoke  ini.get_int, path, str_active, str_port_start, 64000
93
        mov     [acti_port_start], ax
94
 
95
        invoke  ini.get_int, path, str_active, str_port_stop, 65000
96
        mov     [acti_port_stop], ax
97
 
98
        invoke  ini.get_str, path, str_general, str_dir, buf_buffer1, BUFFERSIZE, 0
99
        mcall   30, 1, buf_buffer1                      ; set working directory
100
 
3813 hidnplayr 101
; Check for parameters, if there are some, resolve the address right away
5011 hidnplayr 102
; TODO: parse ftp://user:password@server.com:port/folder/subfolder type urls.
4922 ashmew2 103
        cmp     byte [buf_cmd], 0
3701 hidnplayr 104
        jne     resolve
105
 
106
main:
3813 hidnplayr 107
; Clear screen
3789 hidnplayr 108
        invoke  con_cls
3701 hidnplayr 109
; Welcome user
3813 hidnplayr 110
        invoke  con_write_asciiz, str_welcome
111
; write prompt (in green color)
3789 hidnplayr 112
        invoke  con_set_flags, 0x0a
3813 hidnplayr 113
        invoke  con_write_asciiz, str_prompt
3701 hidnplayr 114
; read string
4922 ashmew2 115
        invoke  con_gets, buf_cmd, 256
3701 hidnplayr 116
; check for exit
117
        test    eax, eax
118
        jz      done
4922 ashmew2 119
        cmp     byte [buf_cmd], 10
3701 hidnplayr 120
        jz      done
3813 hidnplayr 121
; reset color back to grey and print newline
122
        invoke  con_set_flags, 0x07
123
        invoke  con_write_asciiz, str_newline
3701 hidnplayr 124
 
125
resolve:
5011 hidnplayr 126
        mov     [sockaddr1.port], 21 shl 8
127
 
3701 hidnplayr 128
; delete terminating '\n'
4922 ashmew2 129
        mov     esi, buf_cmd
3701 hidnplayr 130
  @@:
131
        lodsb
5011 hidnplayr 132
        cmp     al, ':'
133
        je      .do_port
3701 hidnplayr 134
        cmp     al, 0x20
135
        ja      @r
136
        mov     byte [esi-1], 0
5011 hidnplayr 137
        jmp     .done
138
 
139
  .do_port:
140
        xor     eax, eax
141
        xor     ebx, ebx
142
        mov     byte [esi-1], 0
143
  .portloop:
144
        lodsb
145
        cmp     al, 0x20
146
        jbe     .port_done
147
        sub     al, '0'
148
        jb      error_hostname
149
        cmp     al, 9
150
        ja      error_hostname
151
        lea     ebx, [ebx*4 + ebx]
152
        shl     ebx, 1
153
        add     ebx, eax
154
        jmp     .portloop
155
 
156
  .port_done:
157
        xchg    bl, bh
158
        mov     [sockaddr1.port], bx
159
 
160
  .done:
3813 hidnplayr 161
; Say to the user that we're resolving
162
        invoke  con_write_asciiz, str_resolve
4922 ashmew2 163
        invoke  con_write_asciiz, buf_cmd
3701 hidnplayr 164
; resolve name
165
        push    esp     ; reserve stack place
4922 ashmew2 166
        invoke  getaddrinfo, buf_cmd, 0, 0, esp
3701 hidnplayr 167
        pop     esi
168
; test for error
169
        test    eax, eax
3813 hidnplayr 170
        jnz     error_resolve
3701 hidnplayr 171
; write results
3800 hidnplayr 172
        invoke  con_write_asciiz, str8          ; ' (',0
173
        mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
174
        mov     eax, [eax+sockaddr_in.sin_addr] ;
175
        mov     [sockaddr1.ip], eax             ;
176
        invoke  inet_ntoa, eax                  ;
177
        invoke  con_write_asciiz, eax           ; print ip
178
        invoke  freeaddrinfo, esi               ; free allocated memory
179
        invoke  con_write_asciiz, str9          ; ')',10,0
180
; open the socket
3701 hidnplayr 181
        mcall   socket, AF_INET4, SOCK_STREAM, 0
182
        cmp     eax, -1
3813 hidnplayr 183
        je      error_socket
5011 hidnplayr 184
        mov     [controlsocket], eax
3800 hidnplayr 185
; connect to the server
3813 hidnplayr 186
        invoke  con_write_asciiz, str_connect
5011 hidnplayr 187
        mcall   connect, [controlsocket], sockaddr1, 18
4918 hidnplayr 188
        cmp     eax, -1
189
        je      error_connect
3701 hidnplayr 190
        mov     [status], STATUS_CONNECTING
3813 hidnplayr 191
; Tell the user we're waiting for the server now.
192
        invoke  con_write_asciiz, str_waiting
3701 hidnplayr 193
 
3813 hidnplayr 194
; Reset 'offset' variable, it's used by the data receiver
3790 hidnplayr 195
        mov     [offset], 0
196
 
3789 hidnplayr 197
wait_for_servercommand:
3813 hidnplayr 198
; Any commands still in our buffer?
3790 hidnplayr 199
        cmp     [offset], 0
3813 hidnplayr 200
        je      .receive                        ; nope, receive some more
3790 hidnplayr 201
        mov     esi, [offset]
4922 ashmew2 202
        mov     edi, buf_cmd
3790 hidnplayr 203
        mov     ecx, [size]
204
        add     ecx, esi
205
        jmp     .byteloop
3701 hidnplayr 206
 
207
; receive socket data
3790 hidnplayr 208
  .receive:
4918 hidnplayr 209
        mcall   26, 9
210
        add     eax, TIMEOUT*100
211
        mov     [timeout], eax
212
  .receive_loop:
213
        mcall   23, 50          ; Wait for event with timeout
214
        mcall   26, 9
215
        cmp     eax, [timeout]
216
        jge     error_timeout
5011 hidnplayr 217
        mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, MSG_DONTWAIT
4918 hidnplayr 218
        test    eax, eax
219
        jnz     .got_data
220
        cmp     ebx, EWOULDBLOCK
221
        jne     error_socket
222
        jmp     .receive_loop
3701 hidnplayr 223
 
4918 hidnplayr 224
  .got_data:
3790 hidnplayr 225
        mov     [offset], 0
3789 hidnplayr 226
 
4922 ashmew2 227
; extract commands, copy them to "buf_cmd" buffer
228
        lea     ecx, [eax + buf_buffer1]         ; ecx = end pointer
229
        mov     esi, buf_buffer1                 ; esi = current pointer
230
        mov     edi, buf_cmd
3701 hidnplayr 231
  .byteloop:
3789 hidnplayr 232
        cmp     esi, ecx
233
        jae     wait_for_servercommand
3701 hidnplayr 234
        lodsb
235
        cmp     al, 10                          ; excellent, we might have a command
236
        je      .got_command
3789 hidnplayr 237
        cmp     al, 13                          ; just ignore this byte
3701 hidnplayr 238
        je      .byteloop
239
        stosb
240
        jmp     .byteloop
3789 hidnplayr 241
  .got_command:                                 ; we have a newline check if its a command
3790 hidnplayr 242
        cmp     esi, ecx
243
        je      .no_more_data
244
        mov     [offset], esi
245
        sub     ecx, esi
246
        mov     [size], ecx
247
        jmp     .go_cmd
248
  .no_more_data:
249
        mov     [offset], 0
250
  .go_cmd:
4922 ashmew2 251
        lea     ecx, [edi - buf_cmd]                  ; length of command
3701 hidnplayr 252
        xor     al, al
253
        stosb
254
 
3789 hidnplayr 255
        invoke  con_set_flags, 0x03             ; change color
4922 ashmew2 256
        invoke  con_write_asciiz, buf_cmd             ; print servercommand
3813 hidnplayr 257
        invoke  con_write_asciiz, str_newline
3800 hidnplayr 258
        invoke  con_set_flags, 0x07             ; reset color
3701 hidnplayr 259
 
3789 hidnplayr 260
        jmp     server_parser                   ; parse command
3701 hidnplayr 261
 
3813 hidnplayr 262
 
263
 
3789 hidnplayr 264
wait_for_usercommand:
3701 hidnplayr 265
 
4922 ashmew2 266
; Are there any files in the transfer queue?
267
 
5011 hidnplayr 268
        cmp     [queued], 0
4922 ashmew2 269
        ja      transfer_queued                 ; Yes, transfer those first.
5011 hidnplayr 270
 
3813 hidnplayr 271
; change color to green for user input
3789 hidnplayr 272
        invoke  con_set_flags, 0x0a
3701 hidnplayr 273
 
3813 hidnplayr 274
; If we are not yet connected, request username/password
3701 hidnplayr 275
        cmp     [status], STATUS_CONNECTED
276
        je      .connected
277
 
278
        cmp     [status], STATUS_NEEDPASSWORD
279
        je      .needpass
280
 
281
; write prompt
3813 hidnplayr 282
        invoke  con_write_asciiz, str_prompt
3701 hidnplayr 283
; read string
4922 ashmew2 284
        invoke  con_gets, buf_cmd, 256
3794 hidnplayr 285
 
3813 hidnplayr 286
; print a newline and reset the color back to grey
287
        invoke  con_write_asciiz, str_newline
3789 hidnplayr 288
        invoke  con_set_flags, 0x07
3701 hidnplayr 289
 
4922 ashmew2 290
        cmp     dword[buf_cmd], "cwd "
3790 hidnplayr 291
        je      cmd_cwd
292
 
4922 ashmew2 293
        cmp     dword[buf_cmd], "mkd "
3813 hidnplayr 294
        je      cmd_mkd
3793 hidnplayr 295
 
4922 ashmew2 296
        cmp     dword[buf_cmd], "rmd "
3813 hidnplayr 297
        je      cmd_rmd
298
 
4922 ashmew2 299
        cmp     dword[buf_cmd], "pwd" + 10 shl 24
3794 hidnplayr 300
        je      cmd_pwd
301
 
4922 ashmew2 302
        cmp     dword[buf_cmd], "bye" + 10 shl 24
3813 hidnplayr 303
        je      cmd_bye
304
 
4922 ashmew2 305
        cmp     dword[buf_cmd], "rdir"
5011 hidnplayr 306
        je      cmd_rdir
307
 
4922 ashmew2 308
        cmp     byte[buf_cmd+4], " "
3813 hidnplayr 309
        jne     @f
310
 
4922 ashmew2 311
        cmp     dword[buf_cmd], "lcwd"
3813 hidnplayr 312
        je      cmd_lcwd
313
 
4922 ashmew2 314
        cmp     dword[buf_cmd], "retr"
3813 hidnplayr 315
        je      cmd_retr
316
 
4922 ashmew2 317
        cmp     dword[buf_cmd], "stor"
3800 hidnplayr 318
        je      cmd_stor
3793 hidnplayr 319
 
4922 ashmew2 320
        cmp     dword[buf_cmd], "dele"
3800 hidnplayr 321
        je      cmd_dele
322
 
3813 hidnplayr 323
  @@:
4922 ashmew2 324
        cmp     byte[buf_cmd+4], 10
3813 hidnplayr 325
        jne     @f
3800 hidnplayr 326
 
4922 ashmew2 327
        cmp     dword[buf_cmd], "list"
3813 hidnplayr 328
        je      cmd_list
3802 hidnplayr 329
 
4922 ashmew2 330
        cmp     dword[buf_cmd], "help"
3813 hidnplayr 331
        je      cmd_help
3804 hidnplayr 332
 
4922 ashmew2 333
        cmp     dword[buf_cmd], "cdup"
3804 hidnplayr 334
        je      cmd_cdup
335
 
3813 hidnplayr 336
  @@:
337
; Uh oh.. unknown command, tell the user and wait for new input
3789 hidnplayr 338
        invoke  con_write_asciiz, str_unknown
3701 hidnplayr 339
        jmp     wait_for_usercommand
340
 
341
 
342
  .connected:
3813 hidnplayr 343
; request username
3789 hidnplayr 344
        invoke  con_write_asciiz, str_user
4922 ashmew2 345
        mov     dword[buf_cmd], "USER"
346
        mov     byte[buf_cmd+4], " "
3701 hidnplayr 347
        jmp     .send
348
 
349
 
350
  .needpass:
3813 hidnplayr 351
; request password
3789 hidnplayr 352
        invoke  con_write_asciiz, str_pass
4922 ashmew2 353
        mov     dword[buf_cmd], "PASS"
354
        mov     byte[buf_cmd+4], " "
5011 hidnplayr 355
        invoke  con_set_flags, 0x00             ; black text on black background for password
3701 hidnplayr 356
 
357
  .send:
358
; read string
4922 ashmew2 359
        mov     esi, buf_cmd+5
3789 hidnplayr 360
        invoke  con_gets, esi, 256
3701 hidnplayr 361
 
3800 hidnplayr 362
; find end of string
4922 ashmew2 363
        mov     edi, buf_cmd+5
3701 hidnplayr 364
        mov     ecx, 256
365
        xor     al, al
366
        repne   scasb
4922 ashmew2 367
        lea     esi, [edi-buf_cmd]
3814 hidnplayr 368
        mov     word[edi-2], 0x0a0d
3800 hidnplayr 369
; and send it to the server
5011 hidnplayr 370
        mcall   send, [controlsocket], buf_cmd, , 0
3701 hidnplayr 371
 
3813 hidnplayr 372
        invoke  con_write_asciiz, str_newline
5011 hidnplayr 373
        invoke  con_set_flags, 0x07             ; reset color
3789 hidnplayr 374
        jmp     wait_for_servercommand
3701 hidnplayr 375
 
376
 
377
 
5011 hidnplayr 378
; files for rdir operation are queued
379
transfer_queued:
3701 hidnplayr 380
 
5011 hidnplayr 381
        mov     esi, [ptr_queue]                ; always pointing to current part of ptr_fname_start
382
        mov     edi, buf_cmd+5                  ; always point to filename for retr command
383
  .build_filename:
384
        lodsb
385
        stosb
386
        cmp     al, 10
387
        je      .get_file                       ; filename ends with character 10
388
        test    al, al
389
        jnz     .build_filename
390
 
391
        ; Error occured, we reached the end of the buffer before [queued] reached 0
392
        mov     [queued], 0
393
        mcall   68, 13, [ptr_fname]             ; free buffer
394
        test    eax, eax
395
        jz      error_heap
396
        jmp     wait_for_usercommand
397
 
398
  .get_file:
399
        mov     byte[edi], 0                    ; end filename with 0 byte
400
        mov     [ptr_queue], esi
401
        dec     [queued]
402
        jnz     cmd_retr
403
 
404
        mcall   68, 13, [ptr_fname]             ; free buffer
405
        test    eax, eax
406
        jz      error_heap
407
        jmp     cmd_retr
408
 
409
 
410
 
411
open_dataconnection:
412
 
413
        test    [mode], 1
414
        jnz     .active
415
 
416
        mcall   send, [controlsocket], str_PASV, str_PASV.length, 0
3701 hidnplayr 417
        ret
418
 
5011 hidnplayr 419
  .active:
420
        mcall   socket, AF_INET4, SOCK_STREAM, 0
421
        cmp     eax, -1
422
        je      error_socket
423
        mov     [datasocket], eax
424
 
425
        mov     ax, [acti_port_start]
426
        xchg    al, ah
427
        mov     [sockaddr2.port], ax
428
 
429
        mcall   bind, [datasocket], sockaddr2, 18
430
        cmp     eax, -1
431
        je      error_socket
432
 
433
        mcall   listen, [datasocket], 1
434
        cmp     eax, -1
435
        je      error_socket
436
 
437
        mov     dword[buf_buffer1], 'PORT'
438
        mov     byte[buf_buffer1+4], ' '
439
        mov     edi, buf_buffer1+5
440
        mov     esi, str_active_ip
441
  .loop:
442
        lodsb
443
        test    al, al
444
        jz      .ip_ok
445
        stosb
446
        jmp     .loop
447
  .ip_ok:
448
        mov     al, ','
449
        stosb
450
        movzx   eax, byte[sockaddr2.port+0]
451
        call    dword_ascii
452
        mov     al, ','
453
        stosb
454
        movzx   eax, byte[sockaddr2.port+1]
455
        call    dword_ascii
456
        mov     ax, 0x0a0d
457
        stosw
458
        lea     esi, [edi - buf_buffer1]
459
        mcall   send, [controlsocket], buf_buffer1, , 0
460
 
461
        mcall   accept, [datasocket], sockaddr2, 18        ; time to accept the awaiting connection..
462
        cmp     eax, -1
463
        je      error_socket
3818 hidnplayr 464
        push    eax
5011 hidnplayr 465
        mcall   close, [datasocket]
466
        pop     [datasocket]
467
 
468
        mcall   recv, [controlsocket], buf_buffer1, BUFFERSIZE, 0
469
 
3701 hidnplayr 470
        ret
471
 
5011 hidnplayr 472
; eax = input
473
; edi = ptr where to write
474
dword_ascii:
475
 
476
        push    edx ebx ecx
477
        mov     ebx, 10
478
        xor     ecx, ecx
479
 
480
       @@:
481
        xor     edx, edx
482
        div     ebx
483
        add     edx, '0'
484
        push    dx
485
        inc     ecx
486
        test    eax, eax
487
        jnz     @r
488
 
489
       @@:
490
        pop     ax
491
        stosb
492
        dec     ecx
493
        jnz     @r
494
 
495
        pop     ecx ebx edx
496
        ret
497
 
498
error_hostname:
499
        invoke  con_set_flags, 0x0c                     ; print errors in red
500
        invoke  con_write_asciiz, str_err_host
501
        jmp     wait_for_keypress
502
 
4918 hidnplayr 503
error_connect:
504
        invoke  con_set_flags, 0x0c                     ; print errors in red
505
        invoke  con_write_asciiz, str_err_connect
506
        jmp     wait_for_keypress
3701 hidnplayr 507
 
4918 hidnplayr 508
error_timeout:
509
        invoke  con_set_flags, 0x0c                     ; print errors in red
510
        invoke  con_write_asciiz, str_err_timeout
511
        jmp     wait_for_keypress
3701 hidnplayr 512
 
3813 hidnplayr 513
error_socket:
3818 hidnplayr 514
        invoke  con_set_flags, 0x0c                     ; print errors in red
3813 hidnplayr 515
        invoke  con_write_asciiz, str_err_socket
516
        jmp     wait_for_keypress
3701 hidnplayr 517
 
3813 hidnplayr 518
error_resolve:
3818 hidnplayr 519
        invoke  con_set_flags, 0x0c                     ; print errors in red
3813 hidnplayr 520
        invoke  con_write_asciiz, str_err_resolve
5011 hidnplayr 521
        jmp     wait_for_keypress
3813 hidnplayr 522
 
4922 ashmew2 523
error_heap:
5011 hidnplayr 524
        invoke  con_set_flags, 0x0c                     ; print errors in red
4922 ashmew2 525
        invoke  con_write_asciiz, str_err_heap
5011 hidnplayr 526
 
3813 hidnplayr 527
wait_for_keypress:
3818 hidnplayr 528
        invoke  con_set_flags, 0x07                     ; reset color to grey
3813 hidnplayr 529
        invoke  con_write_asciiz, str_push
3789 hidnplayr 530
        invoke  con_getch2
5011 hidnplayr 531
        mcall   close, [controlsocket]
3701 hidnplayr 532
        jmp     main
533
 
534
done:
3789 hidnplayr 535
        invoke  con_exit, 1
536
 
3701 hidnplayr 537
exit:
5011 hidnplayr 538
        mcall   close, [controlsocket]
539
exit2:
3701 hidnplayr 540
        mcall   -1
541
 
542
 
543
 
544
; data
3813 hidnplayr 545
str_title       db 'FTP client',0
4918 hidnplayr 546
str_welcome     db 'FTP client for KolibriOS v0.12',10
3813 hidnplayr 547
                db 10
548
                db 'Please enter ftp server address.',10,0
3800 hidnplayr 549
 
3813 hidnplayr 550
str_prompt      db '> ',0
551
str_resolve     db 'Resolving ',0
552
str_newline     db 10,0
553
str_err_resolve db 10,'Name resolution failed.',10,0
554
str_err_socket  db 10,'Socket error.',10,0
5011 hidnplayr 555
str_err_heap    db 10,'Cannot allocate memory from heap.',10,0
4918 hidnplayr 556
str_err_timeout db 10,'Timeout - no response from server.',10,0
557
str_err_connect db 10,'Cannot connect to the server.',10,0
5011 hidnplayr 558
str_err_host    db 10,'Invalid hostname.',10,0
3813 hidnplayr 559
str8            db ' (',0
560
str9            db ')',10,0
561
str_push        db 'Push any key to continue.',0
562
str_connect     db 'Connecting...',10,0
563
str_waiting     db 'Waiting for welcome message.',10,0
564
str_user        db "username: ",0
565
str_pass        db "password: ",0
566
str_unknown     db "Unknown command or insufficient parameters - type help for more information.",10,0
567
str_lcwd        db "Local working directory is now: ",0
3701 hidnplayr 568
 
3813 hidnplayr 569
str_open        db "opening data socket",10,0
4922 ashmew2 570
str_close       db 10,"closing data socket",10,0
571
str_dot         db '.',0
3701 hidnplayr 572
 
3813 hidnplayr 573
str_help        db "available commands:",10
574
                db 10
575
                db "bye             - close the connection",10
576
                db "cdup            - change to parent of current directory on the server",10
577
                db "cwd  - change working directoy on the server",10
578
                db "dele      - delete file from the server",10
579
                db "list            - list files and folders in current server directory",10
580
                db "lcwd      - change local working directory",10
581
                db "mkd  - make directory on the server",10
582
                db "pwd             - print server working directory",10
583
                db "retr      - retreive file from the server",10
584
                db "rmd  - remove directory from the server",10
585
                db "stor      - store file on the server",10
5011 hidnplayr 586
                    db "rdir            - retreive all files from current server dir",10
3813 hidnplayr 587
                db 10,0
588
 
5011 hidnplayr 589
str_ini         db '.ini', 0
590
str_active      db 'active', 0
591
str_port_start  db 'port_start', 0
592
str_port_stop   db 'port_stop', 0
593
str_ip          db 'ip', 0
594
str_dir         db 'dir', 0
595
str_general     db 'general', 0
3821 hidnplayr 596
 
5011 hidnplayr 597
queued          dd 0
598
mode            db 0    ; passive = 0, active = 1
599
 
3821 hidnplayr 600
; FTP strings
601
 
602
str_PASV        db 'PASV',13,10
603
.length = $ - str_PASV
604
 
3701 hidnplayr 605
sockaddr1:
606
        dw AF_INET4
5011 hidnplayr 607
.port   dw ?
608
.ip     dd ?
3701 hidnplayr 609
        rb 10
610
 
611
sockaddr2:
612
        dw AF_INET4
5011 hidnplayr 613
.port   dw ?
614
.ip     dd ?
3701 hidnplayr 615
        rb 10
616
 
617
; import
618
align 4
619
@IMPORT:
620
 
5011 hidnplayr 621
library network, 'network.obj', console, 'console.obj', libini, 'libini.obj'
3701 hidnplayr 622
 
623
import  network,        \
624
        getaddrinfo,    'getaddrinfo',  \
625
        freeaddrinfo,   'freeaddrinfo', \
626
        inet_ntoa,      'inet_ntoa'
627
 
628
import  console,        \
629
        con_start,      'START',        \
630
        con_init,       'con_init',     \
631
        con_write_asciiz,'con_write_asciiz',     \
632
        con_exit,       'con_exit',     \
633
        con_gets,       'con_gets',\
634
        con_cls,        'con_cls',\
635
        con_getch2,     'con_getch2',\
636
        con_set_cursor_pos, 'con_set_cursor_pos',\
637
        con_write_string, 'con_write_string',\
3789 hidnplayr 638
        con_get_flags,  'con_get_flags', \
639
        con_set_flags,  'con_set_flags'
3701 hidnplayr 640
 
5011 hidnplayr 641
import  libini,         \
642
        ini.get_str,    'ini_get_str',\
643
        ini.get_int,    'ini_get_int'
3701 hidnplayr 644
 
5011 hidnplayr 645
 
3701 hidnplayr 646
i_end:
647
 
3813 hidnplayr 648
; uninitialised data
649
 
3794 hidnplayr 650
status          db ?
651
 
5011 hidnplayr 652
controlsocket   dd ?
3701 hidnplayr 653
datasocket      dd ?
3790 hidnplayr 654
offset          dd ?
655
size            dd ?
3800 hidnplayr 656
operation       dd ?
4918 hidnplayr 657
timeout         dd ?
658
 
5011 hidnplayr 659
ptr_fname       dd ?
660
size_fname      dd ?
661
ptr_queue       dd ?
662
 
663
acti_port_start dw ?
664
acti_port_stop  dw ?
665
acti_port       dw ?
666
 
667
str_active_ip   rb 16
668
 
3800 hidnplayr 669
filestruct:
5011 hidnplayr 670
  .subfn        dd ?
671
  .offset       dd ?
672
                dd ?
673
  .size         dd ?
674
  .ptr          dd ?
675
  .name         rb 1024
3800 hidnplayr 676
 
4922 ashmew2 677
buf_buffer1     rb BUFFERSIZE+1
678
buf_buffer2     rb BUFFERSIZE+1
5011 hidnplayr 679
buf_cmd         rb 1024                 ; buffer for holding command string
3794 hidnplayr 680
 
5011 hidnplayr 681
path            rb 1024
682
 
3701 hidnplayr 683
mem: