Subversion Repositories Kolibri OS

Rev

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