Subversion Repositories Kolibri OS

Rev

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

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