Subversion Repositories Kolibri OS

Rev

Rev 2585 | Go to most recent revision | Details | Compare with Previous | 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       ; Will also be used to temporarily store username
8
2598 hidnplayr 9
        type            db ?    ; ASCII/EBDIC/IMAGE/..
2578 hidnplayr 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
        permissions     dd ?
16
        buffer_ptr      dd ?
2598 hidnplayr 17
18
        datasock        sockaddr_in
2578 hidnplayr 19
 
20
        buffer          rb BUFFERSIZE
21
 
22
23
24
 
25
 
2598 hidnplayr 26
        xor     edi, edi
27
        mcall   send, [edx + thread_data.socketnum], .string, .length
28
        jmp     @f
29
.string db str, 13, 10
30
.length = $ - .string
31
@@:
32
33
}
2578 hidnplayr 34
 
2598 hidnplayr 35
;------------------------------------------------
2578 hidnplayr 36
 
2598 hidnplayr 37
;
38
; Internal function wich uses the 'commands'
39
;  table to call an appropriate cmd_xx function.
40
;
41
; input: esi = ptr to ascii commands
42
;        ecx = number of bytes input
43
;        edx = pointer to thread_data structure
44
;
45
; output: none
46
;
47
;------------------------------------------------
48
align 4
49
parse_cmd:                              ; esi must point to command
2554 hidnplayr 50
51
        cmp     byte [esi], 0x20        ; skip all leading characters
52
 
2578 hidnplayr 53
        inc     esi
54
        dec     ecx
55
        cmp     ecx, 3
56
        jb      .error
57
        jmp     parse_cmd
2598 hidnplayr 58
  .ok:
59
        cmp     byte [esi+3], 0x20
2578 hidnplayr 60
        ja      @f
2557 hidnplayr 61
        mov     byte [esi+3], 0
2598 hidnplayr 62
       @@:
2557 hidnplayr 63
64
        mov     eax, [esi]
65
 
2554 hidnplayr 66
        mov     edi, commands           ; list of commands to scan
67
  .scanloop:
68
        cmp     eax, [edi]
69
        je      .got_it
70
2598 hidnplayr 71
        add     edi, 4+4*4
2554 hidnplayr 72
 
2598 hidnplayr 73
        jne     .scanloop
2554 hidnplayr 74
75
  .error:
76
 
77
        jb      login_first
2598 hidnplayr 78
        sendFTP "500 Unsupported command"
79
        ret
80
2554 hidnplayr 81
  .got_it:
82
 
2598 hidnplayr 83
        jmp     dword [edi + 4 + eax]
84
85
2554 hidnplayr 86
 
2598 hidnplayr 87
 
2554 hidnplayr 88
2562 hidnplayr 89
        dd 'ABOR'
2554 hidnplayr 90
 
2598 hidnplayr 91
;        dd 'ACCT
92
;        dd login_fitst, login_first, login_first, cmd_ACCT
93
;        dd 'APPE'
94
;        dd login_fitst, login_first, login_first, cmd_APPE
95
        dd 'CDUP'
96
        dd login_first, login_first, login_first, cmdCDUP
97
        dd 'CWD'
98
        dd login_first, login_first, login_first, cmdCWD
99
        dd 'DELE'
100
        dd login_first, login_first, login_first, cmdDELE
101
;        dd 'HELP'
102
;        dd login_fitst, login_first, login_first, cmd_HELP
103
        dd 'LIST'
104
        dd login_first, login_first, login_first, cmdLIST
105
;        dd 'MDTM'
106
;        dd login_fitst, login_first, login_first, cmd_MDTM
107
;        dd 'MKD'
108
;        dd login_fitst, login_first, login_first, cmd_MKD
109
;        dd 'MODE'
110
;        dd login_fitst, login_first, login_first, cmd_MODE
111
        dd 'NLST'
112
        dd login_first, login_first, login_first, cmdNLST
113
        dd 'NOOP'
114
        dd login_first, login_first, login_first, cmdNOOP
115
        dd 'PASS'
116
        dd cmdPASS.0,   cmdPASS    , cmdPASS.2,   cmdPASS.3
117
        dd 'PASV'
118
        dd login_first, login_first, login_first, cmdPASV
119
        dd 'PORT'
120
        dd login_first, login_first, login_first, cmdPORT
121
        dd 'PWD'
122
        dd login_first, login_first, login_first, cmdPWD
123
        dd 'QUIT'
124
        dd cmdQUIT,     cmdQUIT,     cmdQUIT,     cmdQUIT
125
;        dd 'REIN'
126
;        dd login_fitst, login_first, login_first, cmd_REIN
127
;        dd 'REST'
128
;        dd login_fitst, login_first, login_first, cmd_REST
129
        dd 'RETR'
130
        dd login_first, login_first, login_first, cmdRETR
131
;        dd 'RMD'
132
;        dd login_fitst, login_first, login_first, cmd_RMD
133
;        dd 'RNFR'
134
;        dd login_fitst, login_first, login_first, cmd_RNFR
135
;        dd 'RNTO'
136
;        dd login_fitst, login_first, login_first, cmd_RNTO
137
;        dd 'SITE'
138
;        dd login_fitst, login_first, login_first, cmd_SITE
139
;        dd 'SIZE'
140
;        dd login_fitst, login_first, login_first, cmd_SIZE
141
;        dd 'STAT'
142
;        dd login_fitst, login_first, login_first, cmd_STAT
143
        dd 'STOR'
144
        dd login_first, login_first, login_first, cmdSTOR
145
;        dd 'STOU'
146
;        dd login_fitst, login_first, login_first, cmd_STOU
147
;        dd 'STRU'
148
;        dd login_fitst, login_first, login_first, cmd_STRU
149
        dd 'SYST'
150
        dd login_first, login_first, login_first, cmdSYST
151
        dd 'TYPE'
152
        dd login_first, login_first, login_first, cmdTYPE
153
        dd 'USER'
154
        dd cmdUSER,     cmdUSER,     cmdUSER,     cmdUSER.2
155
        db 0                                                    ; end marker
156
157
align 4
2554 hidnplayr 158
 
2598 hidnplayr 159
        sendFTP "530 Please login with USER and PASS"
160
        ret
161
162
align 4
2554 hidnplayr 163
 
164
        sendFTP "550 Permission denied"
2598 hidnplayr 165
        ret
166
167
align 4
2554 hidnplayr 168
 
2598 hidnplayr 169
        pushd   0x0c
170
        call    [con_set_flags]
171
        push    str_sockerr
172
        call    [con_write_asciiz]
173
        pushd   0x07
174
        call    [con_set_flags]
175
176
        mov     edx, [ebp]
2578 hidnplayr 177
 
2598 hidnplayr 178
        ret
179
2554 hidnplayr 180
align 4
181
 
182
        and     [edx + thread_data.permissions], not ABORT
2598 hidnplayr 183
        mov     [edx + thread_data.mode], MODE_NOTREADY
184
        push    ebx
185
        call    [file.close]
186
        mcall   close, [edx + thread_data.datasocketnum]
187
        mov     edx, [ebp]
188
        sendFTP "530 Transfer aborted"
189
        ret
190
191
align 4
192
 
193
194
        call    ascii_to_byte
195
 
196
        cmp     byte [esi], cl
197
        jne     .err
198
199
        call    ascii_to_byte
200
 
201
        cmp     byte [esi], cl
202
        jne     .err
203
        shl     ebx, 16
204
205
        call    ascii_to_byte
206
 
207
        cmp     byte [esi], cl
208
        jne     .err
209
210
        call    ascii_to_byte
211
 
212
213
        ror     ebx, 16
214
 
215
216
  .err:
217
 
218
        ret
219
220
align 4         ; esi = ptr to str, output in eax
221
 
222
223
        xor     eax, eax
224
 
225
226
  .loop:
227
 
228
        sub     bl, '0'
229
        jb      .done
230
        cmp     bl, 9
231
        ja      .done
232
        lea     eax, [eax*4 + eax]      ;
233
        shl     eax, 1                  ; eax = eax * 10
234
        add     eax, ebx
235
        inc     esi
236
237
        jmp     .loop
238
 
239
  .done:
240
 
241
        ret
242
243
align 4
244
 
245
246
        push    edx ebx ecx
247
 
248
        xor     ecx, ecx
249
250
       @@:
251
 
252
        div     ebx
253
        add     edx, '0'
254
        pushw   dx
255
        inc     ecx
256
        test    eax, eax
257
        jnz     @r
258
259
       @@:
260
 
261
        stosb
262
        dec     ecx
263
        jnz     @r
264
265
        pop     ecx ebx edx
266
 
267
268
align 4
269
 
270
271
        mov     edx, [ebp]
272
 
273
        lea     esi, [edx + thread_data.home_dir]
274
        mov     ecx, 1024
275
  .loop1:
276
        lodsb
277
        or      al, al
278
        jz      .next
279
        stosb
280
        loop    .loop1
281
  .next:
282
283
        cmp     byte[edi-1], '/'
284
 
285
        dec     edi
286
       @@:
287
288
        lea     esi, [edx + thread_data.work_dir]
289
 
290
  .loop2:
291
        lodsb
292
        or      al, al
293
        jz      .done
294
        stosb
295
        loop    .loop2
296
297
  .done:
298
 
299
        ret
300
301
;------------------------------------------------
302
 
303
;
304
; This command aborts the current filetransfer.
305
;
306
;------------------------------------------------
307
align 4
308
cmdABOR:
309
310
        or      [edx + thread_data.permissions], ABORT
311
 
312
        ret
313
314
;------------------------------------------------
315
 
316
;
317
; Change the directory to move up one level.
318
;
319
;------------------------------------------------
320
align 4
321
cmdCDUP:
322
2571 hidnplayr 323
        test    [edx + thread_data.permissions], PERMISSION_CD
324
 
2598 hidnplayr 325
326
        cmp     byte [edx + thread_data.work_dir+1], 0                          ; are we in "/" ?
327
 
2585 hidnplayr 328
2571 hidnplayr 329
        mov     ecx, 1024
330
 
331
        lea     edi, [edx + thread_data.work_dir]
332
        repne   scasb
2585 hidnplayr 333
        std
2571 hidnplayr 334
        dec     edi
335
        dec     edi
336
        dec     edi
2585 hidnplayr 337
        mov     al,'/'
338
        repne   scasb
2571 hidnplayr 339
        cld
2585 hidnplayr 340
        mov     byte[edi+1], 0
2571 hidnplayr 341
2585 hidnplayr 342
  .done:
2571 hidnplayr 343
 
344
        lea     eax, [edx + thread_data.work_dir]
2585 hidnplayr 345
        push    eax
346
        call    [con_write_asciiz]
347
        push    str_newline
348
        call    [con_write_asciiz]
349
350
        sendFTP "250 Command succesul"
351
 
2598 hidnplayr 352
2571 hidnplayr 353
;------------------------------------------------
354
 
2598 hidnplayr 355
;
356
; Change Working Directory.
357
;
358
;------------------------------------------------
359
align 4
360
cmdCWD:
2571 hidnplayr 361
2598 hidnplayr 362
        test    [edx + thread_data.permissions], PERMISSION_CD
2554 hidnplayr 363
 
2598 hidnplayr 364
365
        sub     ecx, 4
366
 
2563 hidnplayr 367
        add     esi, 4
368
369
  .scan:
2571 hidnplayr 370
 
371
        push    ecx
2578 hidnplayr 372
        mov     ecx, 1024
373
  .find_zero:
374
        cmp     byte [edi], 0
375
        je      .found_zero
376
        inc     edi
377
        loop    .find_zero
378
  .found_zero:
379
        pop     ecx
380
  .scan2:
381
2581 hidnplayr 382
        cmp     byte [esi], '/'
2563 hidnplayr 383
 
384
        inc     esi
385
        dec     ecx
386
        jz      .done
387
       @@:
388
389
  .loop:
390
 
391
        cmp     al, 0x20
392
        jb      .done
393
        cmp     al, '.'
394
        je      .up
2571 hidnplayr 395
  .continue:
396
        stosb
397
        loop    .loop
2563 hidnplayr 398
  .done:
399
        cmp     byte [edi-1], '/'
400
        je      @f
401
        mov     byte [edi], '/'
402
        inc     edi
403
       @@:
404
        mov     byte [edi], 0
405
406
; Print the new working dir on the console
407
 
2585 hidnplayr 408
        push    eax
409
        call    [con_write_asciiz]
410
        push    str_newline
411
        call    [con_write_asciiz]
412
413
        sendFTP "250 Command succesful"
414
 
2598 hidnplayr 415
2554 hidnplayr 416
  .up:
417
 
2571 hidnplayr 418
        cmp     al, '.'
419
        jne     .continue
420
421
;;;;        TODO: find second last '\' in work_dir and make next char zero
422
 
2581 hidnplayr 423
424
        jmp     .scan2
2571 hidnplayr 425
 
2581 hidnplayr 426
  .err:
427
 
2563 hidnplayr 428
        ret
2598 hidnplayr 429
2563 hidnplayr 430
;------------------------------------------------
431
 
2598 hidnplayr 432
;
433
; Delete a file from the server.
434
;
435
;------------------------------------------------
436
align 4
437
cmdDELE:
2554 hidnplayr 438
439
        test    [edx + thread_data.permissions], PERMISSION_DELETE
440
 
2598 hidnplayr 441
442
        ret
443
 
2554 hidnplayr 444
;------------------------------------------------
445
 
2598 hidnplayr 446
;
447
; List the files in the current working directory.
448
;
449
;------------------------------------------------
450
align 4
451
cmdLIST:
2554 hidnplayr 452
453
        test    [edx + thread_data.permissions], PERMISSION_EXEC
454
 
2598 hidnplayr 455
456
; If we are in active mode, it's time to open a data socket..
457
 
2563 hidnplayr 458
        jne     @f
2578 hidnplayr 459
        mov     ecx, [edx + thread_data.datasocketnum]
2562 hidnplayr 460
        lea     edx, [edx + thread_data.datasock]
2578 hidnplayr 461
        mov     esi, sizeof.thread_data.datasock
462
        mcall   connect
463
        cmp     eax, -1
464
        je      socketerror
2562 hidnplayr 465
  @@:
2571 hidnplayr 466
2562 hidnplayr 467
; Create fpath from home_dir and work_dir
468
 
2563 hidnplayr 469
470
        lea     eax, [edx + thread_data.fpath]
471
 
2578 hidnplayr 472
        call    [con_write_asciiz]
473
        push    str_newline
2571 hidnplayr 474
        call    [con_write_asciiz]
475
476
; Start the search
477
 
2563 hidnplayr 478
        push    FA_ANY
2598 hidnplayr 479
        push    str_mask
2571 hidnplayr 480
        lea     eax, [edx + thread_data.fpath]
2562 hidnplayr 481
        push    eax
2578 hidnplayr 482
        call    [file.find.first]
483
2562 hidnplayr 484
        test    eax, eax
485
 
2578 hidnplayr 486
487
        mov     edx, [ebp]
488
 
2598 hidnplayr 489
2578 hidnplayr 490
  .parse_file:
2598 hidnplayr 491
 
2562 hidnplayr 492
        jz      .done
2563 hidnplayr 493
        mov     ebx, eax        ; yes, save the descripter in ebx
2562 hidnplayr 494
2578 hidnplayr 495
; first, convert the attributes
2562 hidnplayr 496
 
497
        jnz     .folder
2578 hidnplayr 498
2562 hidnplayr 499
        test    [ebx + FileInfoA.Attributes], FA_READONLY
500
 
2578 hidnplayr 501
2562 hidnplayr 502
        mov     eax, '-rw-'
503
 
504
        jmp     .attr
505
506
  .folder:
507
 
508
        stosd
509
        jmp     .attr
2563 hidnplayr 510
2562 hidnplayr 511
  .readonly:
512
 
513
        stosd
514
515
  .attr:
516
 
517
        stosd
518
        mov     ax, 'w-'
519
        stosw
520
        mov     al, ' '
521
        stosb
522
523
; now..
524
 
525
        stosw
526
527
; now write owner, everything is owned by FTP, woohoo!
528
 
529
        stosd
530
        stosd
531
532
; now the filesize in ascii
533
 
534
        call    dword_to_ascii
2578 hidnplayr 535
2562 hidnplayr 536
        mov     al, ' '
537
 
538
539
; then date (month/day/year)
540
 
541
        mov     eax, [months + 4*eax]
2578 hidnplayr 542
        stosd
543
2562 hidnplayr 544
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.day]
545
 
2578 hidnplayr 546
2562 hidnplayr 547
        mov     al, ' '
548
 
549
550
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.year]
551
 
2578 hidnplayr 552
2562 hidnplayr 553
        mov     al, ' '
554
 
555
556
; and last but not least, filename
557
 
558
        mov     ecx, 264
2578 hidnplayr 559
  .nameloop:
560
        lodsb
2562 hidnplayr 561
        test    al, al
562
        jz      .namedone
563
        stosb
564
        loop    .nameloop
565
566
; insert a cr lf
567
 
2563 hidnplayr 568
        mov     ax, 0x0a0d
2562 hidnplayr 569
        stosw
2571 hidnplayr 570
2562 hidnplayr 571
        test    [edx + thread_data.permissions], ABORT
572
 
2598 hidnplayr 573
574
; check next file
575
 
2563 hidnplayr 576
        call    [file.find.next]
2578 hidnplayr 577
        jmp     .parse_file
2563 hidnplayr 578
579
; close file desc
580
 
581
        push    eax                             ; file discriptor is still in eax at this point!
2562 hidnplayr 582
        call    [file.find.close]
2598 hidnplayr 583
2562 hidnplayr 584
; append the string with a 0
585
 
2563 hidnplayr 586
        stosb
2562 hidnplayr 587
588
; Warn the client we're about to send the data
589
 
2571 hidnplayr 590
        push    edi
2598 hidnplayr 591
        sendFTP "150 Here it comes.."
592
        pop     esi
593
594
; and send it to the client
2562 hidnplayr 595
 
2563 hidnplayr 596
        mov     ecx, [edx + thread_data.datasocketnum]
2598 hidnplayr 597
        lea     edx, [edx + thread_data.buffer]
2578 hidnplayr 598
        sub     esi, edx
599
        xor     edi, edi
600
        mcall   send
601
602
; close the data socket..
2562 hidnplayr 603
 
2563 hidnplayr 604
        mcall   close, [edx + thread_data.datasocketnum]
2598 hidnplayr 605
        mov     [edx + thread_data.mode], MODE_NOTREADY
2578 hidnplayr 606
607
        sendFTP "226 Transfer OK"
2562 hidnplayr 608
 
2598 hidnplayr 609
2554 hidnplayr 610
  .nosuchdir:
611
 
2578 hidnplayr 612
        ret
2598 hidnplayr 613
2578 hidnplayr 614
;------------------------------------------------
615
 
2598 hidnplayr 616
;
617
; List the filenames of the files in the current working directory.
618
;
619
;------------------------------------------------
620
align 4
621
cmdNLST:
2554 hidnplayr 622
623
        test    [edx + thread_data.permissions], PERMISSION_EXEC
624
 
2598 hidnplayr 625
626
        ; TODO: same as list but simpler output format
627
 
2578 hidnplayr 628
        ret
629
 
2554 hidnplayr 630
;------------------------------------------------
631
 
2598 hidnplayr 632
;
633
; No operation, just keep the connection alive.
634
;
635
;------------------------------------------------
636
align 4
637
cmdNOOP:
2554 hidnplayr 638
639
        ret
640
 
641
;------------------------------------------------
642
 
2598 hidnplayr 643
;
644
; Second phase of login process, client provides password.
645
;
646
;------------------------------------------------
647
align 4
648
cmdPASS:
2554 hidnplayr 649
        lea     esi, [esi + 5]
2557 hidnplayr 650
        lea     edi, [edx + thread_data.buffer + 512]           ; temp pass
2598 hidnplayr 651
        lea     eax, [edx + thread_data.fpath]                  ; temp username
652
        invoke  ini.get_str, path2, eax, str_pass, edi, 512
653
        test    eax, eax
654
        jnz     .incorrect
655
656
        repe    cmpsb
2557 hidnplayr 657
 
2598 hidnplayr 658
        cmp     byte [esi], 0x20
2560 hidnplayr 659
 
2598 hidnplayr 660
661
        cmp     byte [edi], 0
2578 hidnplayr 662
 
2598 hidnplayr 663
664
  .pass_ok:
665
 
666
        invoke  ini.get_int, path2, eax, str_mode, 0
667
        mov     [edx + thread_data.permissions], eax
668
669
        push    str_pass_ok
670
 
2560 hidnplayr 671
672
        mov     edx, [ebp]                                      ; thread_data pointer
673
 
2598 hidnplayr 674
        sendFTP "230 You are now logged in"
2578 hidnplayr 675
        ret
2598 hidnplayr 676
677
  .2:
2557 hidnplayr 678
 
2598 hidnplayr 679
        mov     [edx + thread_data.state], STATE_CONNECTED
680
        sendFTP "530 Login incorrect"
681
        ret
682
2557 hidnplayr 683
align 4
684
 
685
        sendFTP "503 Login with USER first"
2598 hidnplayr 686
        ret
687
688
align 4
689
 
690
        sendFTP "230 Already logged in"
691
        ret
692
693
;------------------------------------------------
694
 
695
;
696
; Initiate a passive dataconnection.
697
;
698
;------------------------------------------------
699
align 4
700
cmdPASV:
701
2560 hidnplayr 702
; Open a new TCP socket
703
 
2578 hidnplayr 704
        cmp     eax, -1
2562 hidnplayr 705
        je      socketerror
706
        mov     edx, [ebp]                                      ; thread_data pointer
2578 hidnplayr 707
        mov     [edx + thread_data.passivesocknum], eax
2598 hidnplayr 708
2578 hidnplayr 709
; Bind it to a known local port
2562 hidnplayr 710
 
2578 hidnplayr 711
        mov     [edx + thread_data.datasock.sin_port], 2000
712
        mov     [edx + thread_data.datasock.sin_addr], 0
713
714
        mov     ecx, eax                                        ; passivesocketnum
2562 hidnplayr 715
 
2598 hidnplayr 716
        mov     esi, sizeof.thread_data.datasock
2578 hidnplayr 717
        mcall   bind
2581 hidnplayr 718
        cmp     eax, -1
719
;        je      bind_err
2562 hidnplayr 720
2598 hidnplayr 721
; And set it to listen!
2562 hidnplayr 722
 
2578 hidnplayr 723
        cmp     eax, -1
2598 hidnplayr 724
;        je      listen_err
725
726
; Tell our thread we are ready to accept incoming calls
2562 hidnplayr 727
 
2578 hidnplayr 728
        mov     [edx + thread_data.mode], MODE_PASSIVE_WAIT
2598 hidnplayr 729
2578 hidnplayr 730
; Now tell the client where to connect to in this format:
2562 hidnplayr 731
 
2578 hidnplayr 732
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
733
734
; '227 ('
2598 hidnplayr 735
 
736
        mov     eax, '227 '     ; FIXME (now hardcoded to 127.0.0.1:2000)
2578 hidnplayr 737
        stosd
2562 hidnplayr 738
        mov     al, '('
739
        stosb
2598 hidnplayr 740
; ip
2562 hidnplayr 741
        mov     eax, 127
2598 hidnplayr 742
        call    dword_to_ascii
743
        mov     al, ','
744
        stosb
745
        mov     eax, 0
2562 hidnplayr 746
        call    dword_to_ascii
2598 hidnplayr 747
        mov     al, ','
748
        stosb
749
        mov     eax, 0
750
        call    dword_to_ascii
751
        mov     al, ','
752
        stosb
753
        mov     eax, 1
754
        call    dword_to_ascii
755
        mov     al, ','
756
        stosb
757
; port
758
        mov     eax, 7
759
        call    dword_to_ascii
760
        mov     al, ','
761
        stosb
762
        mov     eax, 208
763
        call    dword_to_ascii
764
; ')', 13, 10, 0
765
        mov     eax, ')' + 0x000a0d00
766
        stosd
767
768
        lea     esi, [edi - thread_data.buffer]
2562 hidnplayr 769
 
2578 hidnplayr 770
        mov     ecx, [edx + thread_data.socketnum]
771
        lea     edx, [edx + thread_data.buffer]
772
        xor     esi, esi
773
        mcall   send
2581 hidnplayr 774
775
        ret
2562 hidnplayr 776
 
2560 hidnplayr 777
;------------------------------------------------
778
 
2598 hidnplayr 779
;
780
; Print the current working directory.
781
;
782
;------------------------------------------------
783
align 4
784
cmdPWD:
2560 hidnplayr 785
2598 hidnplayr 786
        mov     dword [edx + thread_data.buffer], '257 '
2554 hidnplayr 787
 
2578 hidnplayr 788
789
        lea     edi, [edx + thread_data.buffer+5]
2560 hidnplayr 790
 
2578 hidnplayr 791
        mov     ecx, 1024
792
  .loop:
2560 hidnplayr 793
        lodsb
794
        or      al, al
795
        jz      .ok
796
        stosb
797
        dec     ecx
798
        jnz     .loop
799
800
  .ok:
801
 
802
        lea     esi, [edi - thread_data.buffer + 4]
2578 hidnplayr 803
        sub     esi, edx
804
        mov     ecx, [edx + thread_data.socketnum]
805
        lea     edx, [edx + thread_data.buffer]
806
        xor     edi, edi
807
        mcall   send
2585 hidnplayr 808
809
        mov     edx, [ebp]
2560 hidnplayr 810
 
2598 hidnplayr 811
        lea     eax, [edx + thread_data.work_dir]
2585 hidnplayr 812
        push    eax
813
        call    [con_write_asciiz]
814
        push    str_newline
815
        call    [con_write_asciiz]
816
817
        ret
2562 hidnplayr 818
 
2554 hidnplayr 819
;------------------------------------------------
820
 
2598 hidnplayr 821
;
822
; Initiate an active dataconnection.
823
;
824
;------------------------------------------------
825
align 4
826
cmdPORT:
2554 hidnplayr 827
828
; PORT a1,a2,a3,a4,p1,p2
829
 
2560 hidnplayr 830
831
; Convert the IP
832
 
2598 hidnplayr 833
        mov     cl, ','
2560 hidnplayr 834
        call    ip_to_dword
2598 hidnplayr 835
; And put it in datasock
836
        mov     edx, [ebp]
2578 hidnplayr 837
        mov     [edx + thread_data.datasock.sin_addr], ebx
2598 hidnplayr 838
2578 hidnplayr 839
; Now the same with portnumber
2560 hidnplayr 840
 
2578 hidnplayr 841
        mov     bh, al
2560 hidnplayr 842
        inc     esi
2578 hidnplayr 843
        call    ascii_to_byte
2560 hidnplayr 844
        mov     bl, al
845
2578 hidnplayr 846
; Save it in datasock too
2560 hidnplayr 847
 
2578 hidnplayr 848
849
; We will open the socket, but do not connect yet!
2560 hidnplayr 850
 
2578 hidnplayr 851
        mcall   socket, AF_INET4, SOCK_STREAM, 0
852
        cmp     eax, -1
2562 hidnplayr 853
        je      socketerror
2560 hidnplayr 854
2578 hidnplayr 855
        mov     edx, [ebp]                                      ; thread_data pointer
2598 hidnplayr 856
 
857
        mov     [edx + thread_data.mode], MODE_ACTIVE
2578 hidnplayr 858
2598 hidnplayr 859
        sendFTP "225 Data connection open"
2560 hidnplayr 860
 
2598 hidnplayr 861
2554 hidnplayr 862
;------------------------------------------------
863
 
2598 hidnplayr 864
;
865
; Close the connection with client.
866
;
867
;------------------------------------------------
868
align 4
869
cmdQUIT:
2554 hidnplayr 870
871
        mcall   close, [edx + thread_data.datasocketnum]
872
 
2578 hidnplayr 873
        sendFTP "221 Bye!"
2557 hidnplayr 874
 
2598 hidnplayr 875
876
        add     esp, 4          ; get rid of call return address
877
 
2581 hidnplayr 878
879
2554 hidnplayr 880
 
2598 hidnplayr 881
 
882
;
883
; Retrieve a file from the ftp server.
884
;
885
;------------------------------------------------
886
align 4
887
cmdRETR:
2554 hidnplayr 888
889
        test    [edx + thread_data.permissions], PERMISSION_READ
890
 
2598 hidnplayr 891
892
        sub     ecx, 5
893
 
2571 hidnplayr 894
895
        cmp     [edx + thread_data.mode], MODE_ACTIVE
896
 
2578 hidnplayr 897
        push    esi
2563 hidnplayr 898
        mov     ecx, [edx + thread_data.datasocketnum]
2571 hidnplayr 899
        lea     edx, [edx + thread_data.datasock]
2578 hidnplayr 900
        mov     esi, sizeof.thread_data.datasock
901
        mcall   connect
2581 hidnplayr 902
        pop     esi
903
        cmp     eax, -1
2571 hidnplayr 904
        je      socketerror
905
  @@:
906
2563 hidnplayr 907
        push    esi
2562 hidnplayr 908
 
2571 hidnplayr 909
        pop     esi
910
        dec     edi
911
        add     esi, 5
912
        mov     ecx, 1024
913
  .loop:
914
        lodsb
915
        cmp     al, 0x20
916
        jl      .done
917
        stosb
918
        loop    .loop
919
  .done:
920
        xor     al, al
921
        stosb
922
923
        lea     eax, [edx + thread_data.fpath]
2563 hidnplayr 924
 
2578 hidnplayr 925
        call    [con_write_asciiz]
926
        push    str_newline
2571 hidnplayr 927
        call    [con_write_asciiz]
928
929
        mov     edx, [ebp]
930
 
2598 hidnplayr 931
        lea     eax, [edx + thread_data.fpath]
2563 hidnplayr 932
        push    eax
2578 hidnplayr 933
        call    [file.open]
934
        test    eax, eax
2563 hidnplayr 935
        jz      .cannot_open
2571 hidnplayr 936
937
        mov     edx, [ebp]
2563 hidnplayr 938
 
2598 hidnplayr 939
        sendFTP "150 Here it comes.."
2571 hidnplayr 940
        pop     ebx
2598 hidnplayr 941
2571 hidnplayr 942
  .read_more:
2563 hidnplayr 943
 
944
        test    [edx + thread_data.permissions], ABORT
2598 hidnplayr 945
        jnz     abort_transfer
946
947
        push    BUFFERSIZE
948
 
2563 hidnplayr 949
        push    eax
2578 hidnplayr 950
        push    ebx
951
        call    [file.read]
2563 hidnplayr 952
        cmp     eax, -1
953
        je      .cannot_open    ; fixme: this is not the correct error
2571 hidnplayr 954
955
        mov     edx, [ebp]
2562 hidnplayr 956
 
2598 hidnplayr 957
        mov     esi, eax
958
        mov     ecx, [edx + thread_data.datasocketnum]
2563 hidnplayr 959
        lea     edx, [edx + thread_data.buffer]
2578 hidnplayr 960
        xor     esi, esi
961
        mcall   send
2581 hidnplayr 962
        pop     ebx ecx
963
        mov     edx, [ebp]                                      ; thread_data pointer
2598 hidnplayr 964
        cmp     eax, -1
965
        je      socketerror
2571 hidnplayr 966
967
        cmp     ecx, BUFFERSIZE
2563 hidnplayr 968
 
969
970
        mcall   close, [edx + thread_data.datasocketnum]
971
 
2578 hidnplayr 972
2585 hidnplayr 973
        push    ebx
2563 hidnplayr 974
 
2598 hidnplayr 975
976
        sendFTP "226 Transfer OK, closing connection"
2563 hidnplayr 977
 
2598 hidnplayr 978
2554 hidnplayr 979
  .cannot_open:
980
 
2571 hidnplayr 981
        call    [con_set_flags]
982
        push    str_notfound
983
        call    [con_write_asciiz]
984
        pushd   0x07
985
        call    [con_set_flags]
986
987
        mov     edx, [ebp]
988
 
2598 hidnplayr 989
        ret
990
2571 hidnplayr 991
992
 
2598 hidnplayr 993
 
994
 
995
;
996
; Store a file on the server.
997
;
998
;------------------------------------------------
999
align 4
1000
cmdSTOR:
2554 hidnplayr 1001
1002
        test    [edx + thread_data.permissions], PERMISSION_WRITE
1003
 
2598 hidnplayr 1004
1005
2578 hidnplayr 1006
 
2598 hidnplayr 1007
 
1008
        jnz     abort_transfer
1009
1010
;;;;
1011
 
1012
        ret
1013
 
2554 hidnplayr 1014
;------------------------------------------------
1015
 
2598 hidnplayr 1016
;
1017
; Send information about the system.
1018
;
1019
;------------------------------------------------
1020
align 4
1021
cmdSYST:
2554 hidnplayr 1022
1023
        sendFTP "215 UNIX type: L8"
1024
 
2598 hidnplayr 1025
2554 hidnplayr 1026
;------------------------------------------------
1027
 
2598 hidnplayr 1028
;
1029
; Choose the file transfer type.
1030
;
1031
;------------------------------------------------
1032
align 4
1033
cmdTYPE:
2554 hidnplayr 1034
1035
        cmp     ecx, 6
1036
 
2560 hidnplayr 1037
1038
        mov     al, byte[esi+5]
1039
 
1040
1041
        cmp     al, 'A'
1042
 
1043
        cmp     al, 'E'
1044
        je      .ebdic
1045
        cmp     al, 'I'
1046
        je      .image
1047
        cmp     al, 'L'
1048
        je      .local
1049
1050
        jmp     parse_cmd.error
1051
 
1052
  .ascii:
1053
 
1054
        jmp     .subtype
2578 hidnplayr 1055
2560 hidnplayr 1056
  .ebdic:
1057
 
1058
2578 hidnplayr 1059
  .subtype:
2560 hidnplayr 1060
 
1061
        jb      .non_print
1062
1063
        mov     al, byte[esi+7]
1064
 
1065
1066
        cmp     al, 'N'
1067
 
1068
        cmp     al, 'T'
1069
        je      .telnet
1070
        cmp     al, 'C'
1071
        je      .asacc
1072
1073
        jmp     parse_cmd.error
1074
 
1075
  .non_print:
1076
 
1077
        jmp     .ok
2578 hidnplayr 1078
2560 hidnplayr 1079
  .telnet:
1080
 
1081
        jmp     .ok
2578 hidnplayr 1082
2560 hidnplayr 1083
  .asacc:
1084
 
1085
        jmp     .ok
2578 hidnplayr 1086
2560 hidnplayr 1087
  .image:
1088
 
1089
        jmp     .ok
2578 hidnplayr 1090
2560 hidnplayr 1091
  .local:
1092
 
1093
        jb      parse_cmd.error
1094
1095
        mov     al, byte[esi+7]
1096
 
1097
        jb      parse_cmd.error
1098
        cmp     al, 9
1099
        ja      parse_cmd.error
1100
        or      al, TYPE_LOCAL
1101
        mov     [edx + thread_data.type], al
1102
2578 hidnplayr 1103
  .ok:
2560 hidnplayr 1104
 
1105
        ret
2598 hidnplayr 1106
2554 hidnplayr 1107
;------------------------------------------------
1108
 
2598 hidnplayr 1109
;
1110
; Login to the server, step one of two.
1111
;
1112
;------------------------------------------------
1113
align 4
1114
cmdUSER:
2554 hidnplayr 1115
1116
        lea     esi, [esi + 5]
1117
 
2598 hidnplayr 1118
  .loop:                                         ;;; TODO: prevent buffer overflow!
2578 hidnplayr 1119
        lodsb
2598 hidnplayr 1120
        stosb
2563 hidnplayr 1121
        cmp     al, 0x20
1122
        jae     .loop
2598 hidnplayr 1123
        mov     byte [edi-1], 0
1124
1125
        lea     esi, [edx + thread_data.fpath]
2562 hidnplayr 1126
 
2598 hidnplayr 1127
        invoke  ini.get_str, path2, esi, str_home, eax, 1024
1128
        cmp     eax, -1
1129
        je      .login_fail
1130
1131
        mov     word [edx + thread_data.work_dir], "/"          ; "/", 0
2562 hidnplayr 1132
 
2598 hidnplayr 1133
        push    str_logged_in
2563 hidnplayr 1134
 
2598 hidnplayr 1135
1136
        mov     edx, [ebp]
2563 hidnplayr 1137
 
2598 hidnplayr 1138
  .sendstr:
1139
        sendFTP "331 Please specify the password"
1140
        ret
1141
2563 hidnplayr 1142
  .login_fail:
1143
 
2598 hidnplayr 1144
        call    [con_write_asciiz]
1145
2571 hidnplayr 1146
        mov     edx, [ebp]
2563 hidnplayr 1147
 
2598 hidnplayr 1148
        jmp     .sendstr
1149
1150
align 4
2571 hidnplayr 1151
 
2598 hidnplayr 1152
        sendFTP "530 Can't change to another user"
1153
        ret
1154