Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2554 hidnplayr 1
 
2
 
2578 hidnplayr 3
        stack           rb 0
4
5
        home_dir        rb 1024
2554 hidnplayr 6
 
2578 hidnplayr 7
        fpath           rb 1024*3
8
9
        type            db ?    ; ASCII/EBDIC/IMAGE/..
10
 
11
        socketnum       dd ?    ; Commands socket
12
        state           dd ?    ; disconnected/logging in/logged in/..
13
        passivesocknum  dd ?    ; when in passive mode, this is the listening socket
14
        datasocketnum   dd ?    ; socket used for data transfers
15
16
        datasock        sockaddr_in
17
 
18
        buffer          rb BUFFERSIZE
19
 
20
21
22
 
23
 
24
 
25
 
2554 hidnplayr 26
27
        cmp     byte [esi], 0x20        ; skip all leading characters
28
 
2578 hidnplayr 29
        inc     esi
30
        dec     ecx
31
        cmp     ecx, 3
32
        ja      parse_cmd
33
        ret
34
  .ok:
35
36
        cmp     byte [esi+3], 0x20
37
 
2557 hidnplayr 38
        mov     byte [esi+3], 0
39
       @@:
40
41
        mov     eax, [esi]
42
 
2554 hidnplayr 43
        mov     edi, commands           ; list of commands to scan
44
  .scanloop:
45
        cmp     eax, [edi]
46
        jne     .try_next
47
2557 hidnplayr 48
        jmp     dword [edi+4]
2554 hidnplayr 49
 
50
  .try_next:
51
 
52
        cmp     byte [edi], 0
53
        jne     .scanloop
54
55
  .error:
56
 
57
2578 hidnplayr 58
        ret
2557 hidnplayr 59
 
2554 hidnplayr 60
61
 
62
 
63
2562 hidnplayr 64
        db 'ABOR'
2554 hidnplayr 65
 
66
        db 'CDUP'
67
        dd cmdCDUP
2571 hidnplayr 68
        db 'CWD', 0
69
        dd cmdCWD
2554 hidnplayr 70
        db 'DELE'
71
        dd cmdDELE
72
        db 'LIST'
73
        dd cmdLIST
74
        db 'NLST'
75
        dd cmdNLST
76
        db 'NOOP'
77
        dd cmdNOOP
78
        db 'PASS'
79
        dd cmdPASS
2557 hidnplayr 80
        db 'PASV'
81
        dd cmdPASV
2562 hidnplayr 82
        db 'PWD', 0
83
        dd cmdPWD
2563 hidnplayr 84
        db 'PORT'
2554 hidnplayr 85
        dd cmdPORT
86
        db 'QUIT'
87
        dd cmdQUIT
88
        db 'RETR'
89
        dd cmdRETR
90
        db 'STOR'
91
        dd cmdSTOR
92
        db 'SYST'
93
        dd cmdSYST
94
        db 'TYPE'
95
        dd cmdTYPE
96
        db 'USER'
97
        dd cmdUSER
98
        db 'XPWD'
99
        dd cmdPWD
100
        db 0            ; end marker
101
2562 hidnplayr 102
2554 hidnplayr 103
 
104
 
105
106
        ; TODO: abort the current filetransfer
107
 
2578 hidnplayr 108
        ret
109
 
2554 hidnplayr 110
align 4
111
 
112
2571 hidnplayr 113
        cmp     byte [edx + thread_data.work_dir+1], 0
114
 
2578 hidnplayr 115
2571 hidnplayr 116
        mov     ecx, 1024
117
 
118
        lea     edi, [edx + thread_data.work_dir+1024]
119
        repne   scasb
2578 hidnplayr 120
        std
2571 hidnplayr 121
        dec     edi
122
        mov     al,'/'
123
        scasb
124
        cld
125
        mov     byte[edi], 0
126
127
  .done:
128
 
129
        ret
2578 hidnplayr 130
2571 hidnplayr 131
align 4
132
 
133
2563 hidnplayr 134
        sub     ecx, 4
2554 hidnplayr 135
 
2563 hidnplayr 136
        add     esi, 4
137
138
  .scan:
2571 hidnplayr 139
 
140
        push    ecx
2578 hidnplayr 141
        mov     ecx, 1024
142
  .find_zero:
143
        cmp     byte [edi], 0
144
        je      .found_zero
145
        inc     edi
146
        loop    .find_zero
147
  .found_zero:
148
        pop     ecx
149
  .scan2:
150
2581 hidnplayr 151
        cmp     byte [esi], '/'
2563 hidnplayr 152
 
153
        inc     esi
154
        dec     ecx
155
        jz      .done
156
       @@:
157
158
  .loop:
159
 
160
        cmp     al, 0x20
161
        jb      .done
162
        cmp     al, '.'
163
        je      .up
2571 hidnplayr 164
  .continue:
165
        stosb
166
        loop    .loop
2563 hidnplayr 167
  .done:
168
        cmp     byte [edi-1], '/'
169
        je      @f
170
        mov     byte [edi], '/'
171
        inc     edi
172
       @@:
173
        mov     byte [edi], 0
174
175
        mcall   send, [edx + thread_data.socketnum], str250, str250.length, 0
176
 
2578 hidnplayr 177
        ret
2563 hidnplayr 178
 
2554 hidnplayr 179
  .up:
180
 
2571 hidnplayr 181
        cmp     al, '.'
182
        jne     .continue
183
184
;;;;        TODO: find second last '\' in work_dir and make next char zero
185
 
2581 hidnplayr 186
187
        jmp     .scan2
2571 hidnplayr 188
 
2581 hidnplayr 189
  .err:
190
 
2563 hidnplayr 191
2578 hidnplayr 192
        ret
2563 hidnplayr 193
 
194
align 4
195
 
2554 hidnplayr 196
197
        ret
198
 
199
align 4
200
 
201
202
; If we are in active mode, it's time to open a data socket..
203
 
2563 hidnplayr 204
        jne     @f
2578 hidnplayr 205
        mov     ecx, [edx + thread_data.datasocketnum]
2562 hidnplayr 206
        lea     edx, [edx + thread_data.datasock]
2578 hidnplayr 207
        mov     esi, sizeof.thread_data.datasock
208
        mcall   connect
209
        mov     edx, [esp+4]                                    ; thread_data pointer
210
        cmp     eax, -1
211
        je      socketerror
2562 hidnplayr 212
  @@:
2571 hidnplayr 213
2562 hidnplayr 214
; Create fpath from home_dir and work_dir
215
 
2563 hidnplayr 216
217
        lea     eax, [edx + thread_data.fpath]
218
 
2578 hidnplayr 219
        call    [con_write_asciiz]
220
        push    str_newline
2571 hidnplayr 221
        call    [con_write_asciiz]
222
223
; Start the search
224
 
2563 hidnplayr 225
        push    str_mask
2571 hidnplayr 226
        lea     eax, [edx + thread_data.fpath]
2562 hidnplayr 227
        push    eax
2578 hidnplayr 228
        call    [file.find.first]
229
2562 hidnplayr 230
        test    eax, eax
231
 
2578 hidnplayr 232
233
        lea     edi, [edx + thread_data.buffer]
234
 
235
2562 hidnplayr 236
        test    eax, eax        ; did we find a file?
2581 hidnplayr 237
 
2563 hidnplayr 238
        mov     ebx, eax        ; yes, save the descripter in ebx
2562 hidnplayr 239
2578 hidnplayr 240
; first, convert the attributes
2562 hidnplayr 241
 
242
        jnz     .folder
2578 hidnplayr 243
2562 hidnplayr 244
        test    [ebx + FileInfoA.Attributes], FA_READONLY
245
 
2578 hidnplayr 246
2562 hidnplayr 247
        mov     eax, '-rw-'
248
 
249
        jmp     .attr
250
251
  .folder:
252
 
253
        stosd
254
        jmp     .attr
2563 hidnplayr 255
2562 hidnplayr 256
  .readonly:
257
 
258
        stosd
259
260
  .attr:
261
 
262
        stosd
263
        mov     ax, 'w-'
264
        stosw
265
        mov     al, ' '
266
        stosb
267
268
; now..
269
 
270
        stosw
271
272
; now write owner, everything is owned by FTP, woohoo!
273
 
274
        stosd
275
        stosd
276
277
; now the filesize in ascii
278
 
279
        call    dword_to_ascii
2578 hidnplayr 280
2562 hidnplayr 281
        mov     al, ' '
282
 
283
284
; then date (month/day/year)
285
 
286
        mov     eax, [months + 4*eax]
2578 hidnplayr 287
        stosd
288
2562 hidnplayr 289
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.day]
290
 
2578 hidnplayr 291
2562 hidnplayr 292
        mov     al, ' '
293
 
294
295
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.year]
296
 
2578 hidnplayr 297
2562 hidnplayr 298
        mov     al, ' '
299
 
300
301
; and last but not least, filename
302
 
303
        mov     ecx, 264
2578 hidnplayr 304
  .nameloop:
305
        lodsb
2562 hidnplayr 306
        test    al, al
307
        jz      .namedone
308
        stosb
309
        loop    .nameloop
310
311
; insert a cr lf
312
 
2563 hidnplayr 313
        mov     ax, 0x0a0d
2562 hidnplayr 314
        stosw
2571 hidnplayr 315
2562 hidnplayr 316
; check next file
317
 
2563 hidnplayr 318
        call    [file.find.next]
2578 hidnplayr 319
        jmp     .parse_file
2563 hidnplayr 320
321
; close file desc
322
 
323
        push    ebx
2562 hidnplayr 324
        call    [file.find.close]
2578 hidnplayr 325
2562 hidnplayr 326
; append the string with a 0
327
 
2563 hidnplayr 328
        stosb
2562 hidnplayr 329
330
; Warn the client we're about to send the data
331
 
2571 hidnplayr 332
        mcall   send, [edx + thread_data.socketnum], str150, str150.length, 0    ; here it comes..
2578 hidnplayr 333
        pop     edx esi
334
335
; and send it to the client
2562 hidnplayr 336
 
2563 hidnplayr 337
        lea     edx, [edx + thread_data.buffer]
2578 hidnplayr 338
        sub     esi, edx
339
        xor     edi, edi
340
        mcall   send
341
342
; close the data socket..
2562 hidnplayr 343
 
2563 hidnplayr 344
        mcall   close, [edx + thread_data.datasocketnum]
2578 hidnplayr 345
346
        cmp     [edx + thread_data.mode], MODE_PASSIVE_OK
2562 hidnplayr 347
 
2578 hidnplayr 348
        mov     [edx + thread_data.mode], MODE_NOTREADY
2562 hidnplayr 349
      @@:
2578 hidnplayr 350
2562 hidnplayr 351
; And send "transfer ok" on the base connection
352
 
2563 hidnplayr 353
2578 hidnplayr 354
        ret
2562 hidnplayr 355
 
2554 hidnplayr 356
  .nosuchdir:
357
 
2578 hidnplayr 358
359
        ret
2562 hidnplayr 360
 
2578 hidnplayr 361
362
 
363
 
2554 hidnplayr 364
365
        ; TODO: same as list but simpler output format
366
 
2578 hidnplayr 367
        ret
368
 
2554 hidnplayr 369
align 4
370
 
371
372
        ret
373
 
374
align 4
375
 
376
2557 hidnplayr 377
        ; TODO: verify password
378
 
2578 hidnplayr 379
        mcall   send, [edx + thread_data.socketnum], str230, str230.length, 0
2560 hidnplayr 380
 
2578 hidnplayr 381
        push    str_pass_ok
382
 
2560 hidnplayr 383
384
        mov     edx, [esp+4]                                    ; thread_data pointer
385
 
2578 hidnplayr 386
387
        ret
2557 hidnplayr 388
 
389
align 4
390
 
391
2560 hidnplayr 392
; Open a new TCP socket
393
 
2578 hidnplayr 394
        mov     edx, [esp+4]                                    ; thread_data pointer
2562 hidnplayr 395
        cmp     eax, -1
2578 hidnplayr 396
        je      socketerror
2562 hidnplayr 397
        mov     [edx + thread_data.passivesocknum], eax
2578 hidnplayr 398
399
; Bind it to a known local port
2562 hidnplayr 400
 
2578 hidnplayr 401
        mov     [edx + thread_data.datasock.sin_port], 2000
402
        mov     [edx + thread_data.datasock.sin_addr], 0
403
404
        mov     ecx, eax ;[edx + thread_data.passivesocknum]
2562 hidnplayr 405
 
2578 hidnplayr 406
        mov     esi, sizeof.thread_data.datasock
407
        mcall   bind
2581 hidnplayr 408
        mov     edx, [esp+4]                                    ; thread_data pointer
409
        cmp     eax, -1
2578 hidnplayr 410
        je      bind_err
2562 hidnplayr 411
412
; And set it to listen!
413
 
2578 hidnplayr 414
415
; Tell our thread we are ready to accept incoming calls
2562 hidnplayr 416
 
2578 hidnplayr 417
        mov     [edx + thread_data.mode], MODE_PASSIVE_WAIT
418
419
; Now tell the client where to connect to in this format:
2562 hidnplayr 420
 
2578 hidnplayr 421
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
422
        lea     edi, [edx + thread_data.buffer]
423
        mov     eax, '227 '     ; FIXME (now hardcoded to 127.0.0.1:2000)
424
        stosd
2562 hidnplayr 425
        mov     eax, '(127'
426
        stosd
427
        mov     eax, ',0,0'
428
        stosd
429
        mov     eax, ',1,7'
430
        stosd
431
        mov     eax, ',208'
432
        stosd
433
        mov     al, ')'
434
        stosb
435
        mov     ax, 0x0a0d
436
        stosw
2571 hidnplayr 437
        xor     al, al
2562 hidnplayr 438
        stosb
439
440
        lea     esi, [edi - thread_data.buffer]
441
 
2578 hidnplayr 442
        mov     ecx, [edx + thread_data.socketnum]
443
        lea     edx, [edx + thread_data.buffer]
444
        xor     esi, esi
445
        mcall   send
2581 hidnplayr 446
447
        ret
2562 hidnplayr 448
 
2560 hidnplayr 449
align 4
450
 
451
2563 hidnplayr 452
        mov     dword [edx + thread_data.buffer], '257 '
2554 hidnplayr 453
 
2578 hidnplayr 454
455
        lea     edi, [edx + thread_data.buffer+5]
2560 hidnplayr 456
 
2578 hidnplayr 457
        mov     ecx, 1024
458
  .loop:
2560 hidnplayr 459
        lodsb
460
        or      al, al
461
        jz      .ok
462
        stosb
463
        dec     ecx
464
        jnz     .loop
465
466
  .ok:
467
 
468
        lea     esi, [edi - thread_data.buffer + 4]
2578 hidnplayr 469
        sub     esi, edx
470
        mov     ecx, [edx + thread_data.socketnum]
471
        lea     edx, [edx + thread_data.buffer]
472
        mcall   send, , , , 0
473
474
;        push    work_dir
2560 hidnplayr 475
 
2562 hidnplayr 476
;        call    [con_printf]
477
478
        ret
479
 
2554 hidnplayr 480
align 4
481
 
482
483
; PORT a1,a2,a3,a4,p1,p2
484
 
2560 hidnplayr 485
486
        mov     [edx + thread_data.mode], MODE_ACTIVE
487
 
2578 hidnplayr 488
        lea     esi, [esi+5]
2560 hidnplayr 489
 
490
        call    ascii_to_byte
2578 hidnplayr 491
        mov     bl, al
2560 hidnplayr 492
        inc     esi             ; skip past ','
2581 hidnplayr 493
        call    ascii_to_byte
2578 hidnplayr 494
        mov     bh, al
2560 hidnplayr 495
        shl     ebx, 16
2581 hidnplayr 496
        inc     esi
2578 hidnplayr 497
        call    ascii_to_byte
2560 hidnplayr 498
        mov     bl, al
499
        inc     esi
2581 hidnplayr 500
        call    ascii_to_byte
2560 hidnplayr 501
        mov     bh, al
502
        inc     esi
2581 hidnplayr 503
        rol     ebx, 16
2560 hidnplayr 504
2581 hidnplayr 505
; And put it in datasock
2560 hidnplayr 506
 
2578 hidnplayr 507
508
; Now the same with portnumber
2560 hidnplayr 509
 
2578 hidnplayr 510
        mov     bh, al
2560 hidnplayr 511
        inc     esi
2578 hidnplayr 512
        call    ascii_to_byte
2560 hidnplayr 513
        mov     bl, al
514
2578 hidnplayr 515
; Save it in datasock too
2560 hidnplayr 516
 
2578 hidnplayr 517
518
; We will open the socket, but do not connect yet!
2560 hidnplayr 519
 
2578 hidnplayr 520
        mcall   socket, AF_INET4, SOCK_STREAM, 0
521
        mov     edx, [esp+4]                                    ; thread_data pointer
2562 hidnplayr 522
        cmp     eax, -1
2578 hidnplayr 523
        je      socketerror
2560 hidnplayr 524
        mov     [edx + thread_data.datasocketnum], eax
2578 hidnplayr 525
526
; Tell the client we are ready
2560 hidnplayr 527
 
2578 hidnplayr 528
        mcall   send, [edx + thread_data.socketnum], str225, str225.length, 0
529
        ret
530
2554 hidnplayr 531
532
 
2560 hidnplayr 533
 
2554 hidnplayr 534
535
        mcall   close, [edx + thread_data.datasocketnum]
536
 
2578 hidnplayr 537
        mcall   close;, [edx + thread_data.socketnum]
538
539
        add     esp, 4          ; get rid of call return address
2557 hidnplayr 540
 
2581 hidnplayr 541
542
align 4
2554 hidnplayr 543
 
544
545
        sub     ecx, 5
546
 
2571 hidnplayr 547
548
        cmp     [edx + thread_data.mode], MODE_ACTIVE
549
 
2578 hidnplayr 550
        push    esi
2563 hidnplayr 551
        mov     ecx, [edx + thread_data.datasocketnum]
2571 hidnplayr 552
        lea     edx, [edx + thread_data.datasock]
2578 hidnplayr 553
        mov     esi, sizeof.thread_data.datasock
554
        mcall   connect
2581 hidnplayr 555
        pop     esi
556
        mov     edx, [esp+4]                                    ; thread_data pointer
2571 hidnplayr 557
        cmp     eax, -1
2578 hidnplayr 558
        je      socketerror
2571 hidnplayr 559
  @@:
560
2563 hidnplayr 561
        push    esi
2562 hidnplayr 562
 
2571 hidnplayr 563
        pop     esi
564
        dec     edi
565
        add     esi, 5
566
        mov     ecx, 1024
567
  .loop:
568
        lodsb
569
        cmp     al, 0x20
570
        jl      .done
571
        stosb
572
        loop    .loop
573
  .done:
574
        xor     al, al
575
        stosb
576
577
        lea     eax, [edx + thread_data.fpath]
2563 hidnplayr 578
 
2578 hidnplayr 579
        call    [con_write_asciiz]
580
        push    str_newline
2571 hidnplayr 581
        call    [con_write_asciiz]
582
583
        push    O_READ
584
 
2563 hidnplayr 585
        push    eax
2578 hidnplayr 586
        call    [file.open]
587
        test    eax, eax
2563 hidnplayr 588
        jz      .cannot_open
2571 hidnplayr 589
590
        push    eax
2563 hidnplayr 591
 
2571 hidnplayr 592
        pop     ebx
2578 hidnplayr 593
2571 hidnplayr 594
        mov     edx, [esp+4]                                    ; thread_data pointer
2563 hidnplayr 595
 
2578 hidnplayr 596
        push    BUFFERSIZE
2563 hidnplayr 597
        lea     eax, [edx + thread_data.buffer]
598
        push    eax
2578 hidnplayr 599
        push    ebx
600
        call    [file.read]
2563 hidnplayr 601
        cmp     eax, -1
602
        je      .cannot_open    ; fixme: this is not the correct error
2571 hidnplayr 603
604
        push    eax
2562 hidnplayr 605
 
2563 hidnplayr 606
        mov     esi, eax
607
        mov     ecx, [edx + thread_data.datasocketnum]
608
        lea     edx, [edx + thread_data.buffer]
2578 hidnplayr 609
        xor     esi, esi
610
        mcall   send
2581 hidnplayr 611
        pop     ebx
612
        pop     ecx
2563 hidnplayr 613
        mov     edx, [esp+4]                                    ; thread_data pointer
614
        cmp     eax, -1
2578 hidnplayr 615
        je      socketerror
2571 hidnplayr 616
617
        cmp     ecx, BUFFERSIZE
2563 hidnplayr 618
 
619
620
        mcall   close, [edx + thread_data.datasocketnum]
621
 
2578 hidnplayr 622
        cmp     [edx + thread_data.mode], MODE_PASSIVE_OK
2563 hidnplayr 623
 
2578 hidnplayr 624
        mov     [edx + thread_data.mode], MODE_PASSIVE_WAIT
2563 hidnplayr 625
      @@:
2578 hidnplayr 626
2563 hidnplayr 627
        mcall   send, [edx + thread_data.socketnum], str226, str226.length, 0    ; transfer ok
628
 
2578 hidnplayr 629
        ret
2563 hidnplayr 630
 
2554 hidnplayr 631
  .cannot_open:
632
 
2571 hidnplayr 633
        call    [con_set_flags]
634
        push    str_notfound
635
        call    [con_write_asciiz]
636
        pushd   0x07
637
        call    [con_set_flags]
638
639
        mcall   send, [edx + thread_data.socketnum], str550, str550.length, 0    ; file not found
640
 
2578 hidnplayr 641
        ret
2571 hidnplayr 642
 
643
align 4
644
 
2554 hidnplayr 645
646
        ; TODO: check if user has write permission, and write file if so
647
 
2578 hidnplayr 648
        ret
649
 
2554 hidnplayr 650
align 4
651
 
652
653
        mcall   send, [edx + thread_data.socketnum], str215, str215.length, 0
654
 
2578 hidnplayr 655
        ret
2557 hidnplayr 656
 
2554 hidnplayr 657
align 4
658
 
659
660
        cmp     ecx, 6
661
 
2560 hidnplayr 662
663
        mov     al, byte[esi+5]
664
 
665
666
        cmp     al, 'A'
667
 
668
        cmp     al, 'E'
669
        je      .ebdic
670
        cmp     al, 'I'
671
        je      .image
672
        cmp     al, 'L'
673
        je      .local
674
675
        jmp     parse_cmd.error
676
 
677
  .ascii:
678
 
679
        jmp     .subtype
2578 hidnplayr 680
2560 hidnplayr 681
  .ebdic:
682
 
683
2578 hidnplayr 684
  .subtype:
2560 hidnplayr 685
 
686
        cmp     ecx, 8
687
 
688
689
        mov     al, byte[esi+7]
690
 
691
692
        cmp     al, 'N'
693
 
694
        cmp     al, 'T'
695
        je      .telnet
696
        cmp     al, 'C'
697
        je      .asacc
698
699
        jmp     parse_cmd.error
700
 
701
  .non_print:
702
 
703
        jmp     .ok
2578 hidnplayr 704
2560 hidnplayr 705
  .telnet:
706
 
707
        jmp     .ok
2578 hidnplayr 708
2560 hidnplayr 709
  .asacc:
710
 
711
        jmp     .ok
2578 hidnplayr 712
2560 hidnplayr 713
  .image:
714
 
715
        jmp     .ok
2578 hidnplayr 716
2560 hidnplayr 717
  .local:
718
 
719
        jb      parse_cmd.error
720
721
        mov     al, byte[esi+7]
722
 
723
        jb      parse_cmd.error
724
        cmp     al, 9
725
        ja      parse_cmd.error
726
        or      al, TYPE_LOCAL
727
        mov     [edx + thread_data.type], al
728
2578 hidnplayr 729
  .ok:
2560 hidnplayr 730
 
731
2578 hidnplayr 732
        ret
2560 hidnplayr 733
 
2554 hidnplayr 734
align 4
735
 
736
737
        ; TODO: check user and set home directory (and permissions)
738
 
2578 hidnplayr 739
        mcall   send, [edx + thread_data.socketnum], str331, str331.length, 0
2557 hidnplayr 740
 
2578 hidnplayr 741
        mov     [edx + thread_data.state], STATE_LOGIN
742
743
        mov     byte [edx + thread_data.work_dir], "/"
2560 hidnplayr 744
 
2578 hidnplayr 745
746
        push    str_logged_in
747
 
2560 hidnplayr 748
749
        ret
750
 
2554 hidnplayr 751
752
 
753
 
754
 
2578 hidnplayr 755
2560 hidnplayr 756
        xor     eax, eax
757
 
2578 hidnplayr 758
759
  .loop:
2560 hidnplayr 760
 
761
        sub     bl, '0'
2578 hidnplayr 762
        jb      .done
763
        cmp     bl, 9
2560 hidnplayr 764
        ja      .done
2578 hidnplayr 765
        lea     eax, [eax*4 + eax]      ;
2560 hidnplayr 766
        shl     eax, 1                  ; eax = eax * 10
2578 hidnplayr 767
        add     eax, ebx
768
        inc     esi
769
2560 hidnplayr 770
        jmp     .loop
771
 
772
  .done:
773
 
774
        ret
2578 hidnplayr 775
2560 hidnplayr 776
align 4
777
 
2562 hidnplayr 778
2578 hidnplayr 779
        mov     eax, '1'
2560 hidnplayr 780
 
2562 hidnplayr 781
782
        ret
2560 hidnplayr 783
 
2562 hidnplayr 784
align 4
2560 hidnplayr 785
 
2563 hidnplayr 786
787
        lea     edi, [edx + thread_data.fpath]
2581 hidnplayr 788
 
2578 hidnplayr 789
        mov     ecx, 1024
790
  .loop1:
2563 hidnplayr 791
        lodsb
792
        or      al, al
793
        jz      .next
794
        stosb
795
        loop    .loop1
796
  .next:
797
798
        cmp     byte[edi-1], '/'
2562 hidnplayr 799
 
2563 hidnplayr 800
        dec     edi
801
       @@:
802
803
        lea     esi, [edx + thread_data.work_dir]
2562 hidnplayr 804
 
2578 hidnplayr 805
  .loop2:
2563 hidnplayr 806
        lodsb
807
        or      al, al
808
        jz      .done
809
        stosb
810
        loop    .loop2
811
812
  .done:
813
 
814
815
        ret
816
 
817
818
 
819
 
2571 hidnplayr 820
821
        pushd   0x0c
2563 hidnplayr 822
 
2571 hidnplayr 823
        push    str_sockerr
824
        call    [con_write_asciiz]
825
        pushd   0x07
826
        call    [con_set_flags]
827
828
        mcall   send, [edx + thread_data.socketnum], str425, str425.length, 0    ; data connection error
2563 hidnplayr 829
 
2578 hidnplayr 830
        ret
2571 hidnplayr 831
 
832
833
 
834
 
835
 
836
 
2554 hidnplayr 837
str200  db '200 Command OK.', 13, 10
2562 hidnplayr 838
.length = $ - str200
2554 hidnplayr 839
str215  db '215 UNIX type: L8', 13, 10
2560 hidnplayr 840
.length = $ - str215
2554 hidnplayr 841
str220  db '220 KolibriOS FTP Daemon 1.0', 13, 10
2557 hidnplayr 842
.length = $ - str220
2554 hidnplayr 843
str221  db '221 Bye!', 13, 10
844
.length = $ - str221
845
str225  db '225 Data connection open', 13, 10
2557 hidnplayr 846
.length = $ - str225
2560 hidnplayr 847
str226  db '226 Transfer OK, Closing connection', 13, 10
848
.length = $ - str226
2554 hidnplayr 849
str230  db '230 You are now logged in.', 13, 10
2562 hidnplayr 850
.length = $ - str230
2554 hidnplayr 851
str250  db '250 command successful', 13, 10
2557 hidnplayr 852
.length = $ - str250
2554 hidnplayr 853
str331  db '331 Please specify the password.', 13, 10
2563 hidnplayr 854
.length = $ - str331
2554 hidnplayr 855
str421  db '421 Timeout!', 13, 10
2557 hidnplayr 856
.length = $ - str421
2560 hidnplayr 857
str425  db '425 Cant open data connection.', 13, 10
858
.length = $ - str425
859
str500  db '500 Unsupported command', 13, 10
860
.length = $ - str500
2554 hidnplayr 861
str550  db '550 No such file', 13, 10
2557 hidnplayr 862
.length = $ - str550
2563 hidnplayr 863