Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
481 diamond 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;
3
;    FTPS
4
;    FTP Server
5
;
6
;    Compile with FASM for Menuet
7
;
8
 
9
; note: telnet == 23, ftp cmd == 21, data on 20
10
 
11
use32
12
 
13
    org     0x0
14
 
15
    db      'MENUET01'              ; 8 byte id
16
    dd      1                       ; header version
17
    dd      START                   ; program start
18
    dd      I_END                   ; program image size
19
    dd      0x170000                ; required amount of memory
1325 tsdima 20
    dd      0x16FFF0                ; esp = 0x16FFF0
481 diamond 21
    dd      0, 0                    ; no params, no path
22
 
661 ataualpa 23
include 'macros.inc'
481 diamond 24
; Various states of client connection
25
USER_NONE       equ 0   ; Awaiting a connection
26
USER_CONNECTED  equ 1   ; User just connected, prompt given
27
USER_USERNAME   equ 2   ; User given username
28
USER_LOGGED_IN  equ 3   ; User given password
29
 
30
 
31
 
32
 
33
 
34
START:                          ; start of execution
35
    ; Clear the screen memory
36
    mov     eax, '    '
37
    mov     edi,text
38
    mov     ecx,80*30 /4
39
    cld
40
    rep     stosd
41
 
42
    call    draw_window
43
 
44
    ; init the receive buffer pointer
45
    mov     [buffptr], buff
46
 
47
    ; Init FTP server state machine
48
    mov     [state], USER_NONE
49
 
50
    ; Open the listening socket
51
    call    connect
52
 
53
still:
54
    ; check connection status
55
    mov     eax,53
56
    mov     ebx,6               ; Get socket status
57
    mov     ecx,[CmdSocket]
485 heavyiron 58
    mcall
481 diamond 59
 
60
    mov     ebx, [CmdSocketStatus]
61
    mov     [CmdSocketStatus], eax
62
 
63
    cmp     eax, ebx
64
    je      waitev
65
 
66
    ; If the socket closed by remote host, open it again.
67
    cmp     eax, 7
68
    je      con
661 ataualpa 69
 
481 diamond 70
    ; If socket closed by Reset, open it again
71
    cmp     eax, 11
72
    je      con
73
 
74
    ; If a user has just connected, start by outputting welcome msg
75
    cmp     eax, 4
76
    jne     noc
77
 
78
    mov     esi, loginStr0
79
    mov     edx, loginStr0_end - loginStr0
80
    call    outputStr
81
 
82
    mov     [state], USER_CONNECTED
83
    jmp     noc
84
 
85
 
86
con:
87
    ; Need to call disconnect, since a remote close does not fully
88
    ; close the socket
89
    call    disconnect
1297 tsdima 90
    mov     eax,5
91
    mov     ebx,10          ; Delay for 100ms
92
    mcall
481 diamond 93
    call    connect
94
    jmp     noc
95
 
96
noc:
97
    ; Display the changed connected status
98
    call    draw_window
99
 
100
waitev:
101
    mov     eax,23                 ; wait here for event
102
    mov     ebx,1                 ; Delay for up to 1s
485 heavyiron 103
    mcall
481 diamond 104
 
105
    cmp     eax,1                  ; redraw request ?
106
    je      red
107
    cmp     eax,2                  ; key in buffer ?
108
    je      key
109
    cmp     eax,3                  ; button in buffer ?
110
    je      button
111
 
112
    ; any data from the socket?
113
 
114
    mov     eax, 53
115
    mov     ebx, 2                  ; Get # of bytes in input queue
116
    mov     ecx, [CmdSocket]
485 heavyiron 117
    mcall
481 diamond 118
    test    eax, eax
119
    jz      still
120
 
121
read_input:
122
    mov     eax, 53
123
    mov     ebx, 3                  ; Get a byte from socket in bl
124
    mov     ecx, [CmdSocket]
485 heavyiron 125
    mcall
481 diamond 126
 
127
    call    ftpRxCmdData            ; process incoming ftp command
128
 
129
    ; Keep processing data until there is no more to process
130
    mov     eax, 53
131
    mov     ebx, 2                  ; Get # of bytes in input queue
132
    mov     ecx, [CmdSocket]
485 heavyiron 133
    mcall
481 diamond 134
    cmp     eax, 0
135
    jne     read_input
136
 
137
    ; Now redraw the text text field.
138
    ; Probably not required, since ftp requires no
139
    ; console i/o.
140
    ; Leave in for now, for debugging.
141
; (fall through to "red:")
142
;    call    draw_text
143
;    jmp     still
144
 
145
red:                          ; REDRAW WINDOW
146
    call    draw_window
147
    jmp     still
148
 
149
key:                          ; KEY
150
    mov     eax,2                  ; get but ignore
485 heavyiron 151
    mcall
481 diamond 152
    jmp     still
153
 
154
button:
155
    mov     eax,17
485 heavyiron 156
    mcall
481 diamond 157
    cmp     ah,1
158
    jne     still
159
 
160
    ; Exit button pressed, so close socket and quit
161
    mov     eax,53
162
    mov     ebx,8
163
    mov     ecx,[CmdSocket]
485 heavyiron 164
    mcall
481 diamond 165
 
166
    ; ... terminate program
485 heavyiron 167
    or     eax,-1
168
    mcall
481 diamond 169
    jmp     still
170
 
171
 
172
 
173
;   *********************************************
174
;   *******  WINDOW DEFINITIONS AND DRAW ********
175
;   *********************************************
176
draw_window:
177
    pusha
178
 
179
    mov  eax,12
180
    mov  ebx,1
485 heavyiron 181
    mcall
481 diamond 182
 
183
    xor  eax,eax                   ; DRAW WINDOW
184
    mov  ebx,100*65536+491 + 8 +15
185
    mov  ecx,100*65536+270 + 20     ; 20 for status bar
661 ataualpa 186
    mov  edx,0x14000000
481 diamond 187
    mov  edi,labelt
485 heavyiron 188
    mcall
481 diamond 189
 
190
    ; draw status bar
191
    mov     eax, 13
192
    mov     ebx, 4*65536+484 + 8 +15
193
    mov     ecx, 270*65536 + 3
194
    mov     edx, 0x00557799
485 heavyiron 195
    mcall
481 diamond 196
 
197
 
198
    mov  esi,contlen-contt          ; display connected status
199
    mov     edx, contt
200
    cmp     [CmdSocketStatus], 4    ; 4 is connected
201
    je      pcon
202
    mov     esi,discontlen-discontt
203
    mov     edx, discontt
204
pcon:
205
 
206
    mov  eax,4                      ; status text
207
    mov  ebx,380*65536+276
208
    mov  ecx,0x00ffffff
485 heavyiron 209
    mcall
481 diamond 210
 
211
    ; Draw the text on the screen, clearing it first
212
    ; This can go when we loose debuggin info.
213
    xor  eax,eax
214
    mov  edi,text+80*30
215
    mov  ecx,80*30 /4
216
    cld
217
    rep  stosd
218
 
219
    call draw_text
220
 
221
    mov  eax,12
222
    mov  ebx,2
485 heavyiron 223
    mcall
481 diamond 224
 
225
    popa
226
 
227
    ret
228
 
229
 
230
;***************************************************************************
231
;   Function
232
;      draw_text
233
;
234
;   Description
235
;       Updates the text on the screen. This is part of the debugging code
236
;
237
;   Inputs
238
;       Character to add in bl
239
;
240
;***************************************************************************
241
draw_text:
242
 
243
    pusha
244
 
245
    mov  esi,text
246
    mov  eax,0
247
    mov  ebx,0
248
  newletter:
249
    mov  cl,[esi]
250
    cmp  cl,[esi+30*80]
251
    jz   noletter
252
  yesletter:
253
    mov  [esi+30*80],cl
254
 
255
    ; erase character
256
 
257
    pusha
258
    mov     edx, 0                  ; bg colour
259
    mov     ecx, ebx
260
    add     ecx, 26
261
    shl     ecx, 16
262
    mov     cx, 9
263
    mov     ebx, eax
264
    add     ebx, 6
265
    shl     ebx, 16
266
    mov     bx, 6
267
    mov     eax, 13
485 heavyiron 268
    mcall
481 diamond 269
    popa
270
 
271
    ; draw character
272
 
273
    pusha
274
    mov     ecx, 0x00ffffff
275
    push bx
276
    mov  ebx,eax
277
    add  ebx,6
278
    shl  ebx,16
279
    pop  bx
280
    add  bx,26
281
    mov  eax,4
282
    mov  edx,esi
283
    mov  esi,1
485 heavyiron 284
    mcall
481 diamond 285
    popa
286
 
287
  noletter:
288
 
289
    add  esi,1
290
    add  eax,6
291
    cmp  eax,80*6
292
    jb   newletter
293
    mov  eax,0
294
    add  ebx,10
295
    cmp  ebx,24*10
296
    jb   newletter
297
 
298
    popa
299
    ret
300
 
301
 
302
 
303
;***************************************************************************
304
;   Function
305
;      ftpRxCmdData
306
;
307
;   Description
308
;       Prcoesses incoming command data, calling a handler for each command.
309
;       Commands are built up in buff before being processed.
310
;
311
;   Inputs
312
;       Character to add in bl
313
;
314
;***************************************************************************
315
ftpRxCmdData:
316
    ; Quit if we are not connected
317
    ;( This case shouldn't be necessary, but be safe )
318
    mov     al, [state]
319
    cmp     al, USER_NONE
320
    je      frcd_exit
321
 
322
    ; Store the incoming character
323
    mov     esi, [buffptr]
324
    mov     [esi], bl
325
    inc     esi
326
    mov     [buffptr], esi
327
 
328
    ; For debugging, show the data coming in
329
    pusha
330
    call    printChar
331
    popa
332
 
333
    ; Do we have an end of line? (LF)
334
    ; if not, just exit
335
    cmp     bl, 0x0a
336
    jne     frcd_exit
337
 
338
    ; OK we have a complete command.
339
    ; Process, and send response
340
 
341
    ; There are a number of states involved in ftp,
342
    ; to do with logging in.
343
 
344
    mov     al, [state]
345
    cmp     al, USER_CONNECTED
346
    jne     fs001
347
 
348
    ; This should be the username
349
 
350
    ; TODO validate username
351
 
352
    ; OK, username accepted - ask for password
353
    mov     esi, loginStr1
354
    mov     edx, loginStr1_end - loginStr1
355
    call    outputStr
356
 
357
    mov     [state], USER_USERNAME
358
 
359
    ; init the receive buffer pointer
360
    mov     [buffptr], buff
361
 
362
    jmp     frcd_exit
363
 
364
fs001:
365
    cmp     al, USER_USERNAME
366
    jne     fs002
367
 
368
    ; This should be the password
369
 
370
    ; TODO validate password
371
 
372
    ; OK, password accepted - show they are logged in
373
    mov     esi, loginStr2
374
    mov     edx, loginStr2_end - loginStr2
375
    call    outputStr
376
 
377
    mov     [state], USER_LOGGED_IN
378
 
379
    ; init the receive buffer pointer
380
    mov     [buffptr], buff
381
 
382
    jmp     frcd_exit
383
 
384
fs002:
385
    cmp     al, USER_LOGGED_IN
386
    jne     fs003
387
 
388
    ; This should be a cmd
389
    call    findCmd
390
    mov     eax, [cmdPtr]
391
    cmp     eax, 0
392
 
393
    je      fs002b
394
 
395
    call    [cmdPtr]
396
 
397
fs002a:
398
    ; init the receive buffer pointer
399
    mov     [buffptr], buff
400
 
401
    jmp     frcd_exit
402
 
403
fs002b:
404
    ; an unsupported command was entered.
405
    ; Tell user that the command is not supported
406
 
407
    mov     esi, unsupStr
408
    mov     edx, unsupStr_end - unsupStr
409
    call    outputStr
410
 
411
    jmp     fs002a
412
 
413
fs003:
414
frcd_exit:
415
    ret
416
 
417
 
418
 
419
;***************************************************************************
420
;   Function
421
;      outputStr
422
;
423
;   Description
424
;       Sends a string over the 'Command' socket
425
;
426
;   Inputs
427
;       String in esi
428
;       Length in edx
429
;
430
;***************************************************************************
431
outputStr:
432
    push    esi
433
    push    edx
434
    mov     eax,53
435
    mov     ebx,7
436
    mov     ecx,[CmdSocket]
485 heavyiron 437
    mcall
481 diamond 438
    pop     edx
439
    pop     esi
661 ataualpa 440
 
481 diamond 441
    cmp     eax, 0
442
    je      os_exit
661 ataualpa 443
 
444
    ; The TCP/IP transmit queue is full; Wait a bit, then retry
481 diamond 445
    pusha
446
    mov     eax,5
1301 tsdima 447
    mov     ebx,1                 ; Delay for up 10ms
485 heavyiron 448
    mcall
481 diamond 449
    popa
661 ataualpa 450
    jmp     outputStr
481 diamond 451
os_exit:
452
    ret
453
 
454
 
455
 
456
;***************************************************************************
457
;   Function
458
;      outputDataStr
459
;
460
;   Description
461
;       Sends a string over the 'Data' socket
462
;
463
;   Inputs
464
;       String in esi
465
;       Length in edx
466
;
467
;***************************************************************************
468
outputDataStr:
469
    push    esi
470
    push    edx
471
    mov     eax,53
472
    mov     ebx,7
473
    mov     ecx,[DataSocket]
485 heavyiron 474
    mcall
481 diamond 475
    pop     edx
476
    pop     esi
477
 
478
    cmp     eax, 0
479
    je      ods_exit
480
 
661 ataualpa 481
    ; The TCP/IP transmit queue is full; Wait a bit, then retry
481 diamond 482
    pusha
483
    mov     eax,5
1301 tsdima 484
    mov     ebx,1                 ; Delay for up 10ms
485 heavyiron 485
    mcall
481 diamond 486
    popa
661 ataualpa 487
    jmp     outputDataStr
481 diamond 488
ods_exit:
489
    ret
490
 
491
 
492
 
493
;***************************************************************************
494
;   Function
495
;      printChar
496
;
497
;   Description
498
;       Writes a character to the screen; Used to display the data coming
499
;       in from the user. Really only useful for debugging.
500
;
501
;   Inputs
502
;       Character in bl
503
;
504
;***************************************************************************
505
printChar:
506
    cmp     bl,13                          ; BEGINNING OF LINE
507
    jne     nobol
508
    mov     ecx,[pos]
509
    add     ecx,1
510
boll1:
511
    sub     ecx,1
512
    mov     eax,ecx
513
    xor     edx,edx
514
    mov     ebx,80
515
    div     ebx
516
    cmp     edx,0
517
    jne     boll1
518
    mov     [pos],ecx
519
    jmp     newdata
520
nobol:
521
 
522
    cmp     bl,10                            ; LINE DOWN
523
    jne     nolf
524
addx1:
525
    add     [pos],dword 1
526
    mov     eax,[pos]
527
    xor     edx,edx
528
    mov     ecx,80
529
    div     ecx
530
    cmp     edx,0
531
    jnz     addx1
532
    mov     eax,[pos]
533
    jmp     cm1
534
nolf:
535
 
536
    cmp     bl,8                            ; BACKSPACE
537
    jne     nobasp
538
    mov     eax,[pos]
539
    dec     eax
540
    mov     [pos],eax
541
    mov     [eax+text],byte 32
542
    mov     [eax+text+60*80],byte 0
543
    jmp     newdata
544
nobasp:
545
 
546
    cmp     bl,15                           ; CHARACTER
547
    jbe     newdata
548
putcha:
549
    mov     eax,[pos]
550
    mov     [eax+text],bl
551
    mov     eax,[pos]
552
    add     eax,1
553
cm1:
554
    mov     ebx,[scroll+4]
555
    imul    ebx,80
556
    cmp     eax,ebx
557
    jb      noeaxz
558
    mov     esi,text+80
559
    mov     edi,text
560
    mov     ecx,ebx
561
    cld
562
    rep     movsb
563
    mov     eax,ebx
564
    sub     eax,80
565
noeaxz:
566
    mov     [pos],eax
567
newdata:
568
    ret
569
 
570
 
571
;***************************************************************************
572
;   Function
573
;      disconnect
574
;
575
;   Description
576
;       Closes the command socket
577
;
578
;   Inputs
579
;       None
580
;
581
;***************************************************************************
582
disconnect:
583
    mov     eax, 53         ; Stack Interface
584
    mov     ebx,8           ; Close TCP socket
585
    mov     ecx,[CmdSocket]
485 heavyiron 586
    mcall
481 diamond 587
    ret
588
 
589
 
661 ataualpa 590
 
481 diamond 591
;***************************************************************************
592
;   Function
593
;      disconnectData
594
;
595
;   Description
596
;       Closes the data socket
597
;
598
;   Inputs
599
;       None
600
;
601
;***************************************************************************
602
disconnectData:
603
    ; This delay would be better done by allowing the socket code
604
    ; to wait for all data to pass through the stack before closing
605
    pusha
606
    mov     eax,5
1287 tsdima 607
    mov     ebx,10          ; Delay for 100ms
485 heavyiron 608
    mcall
481 diamond 609
    popa
610
 
611
    mov     eax, 53         ; Stack Interface
612
    mov     ebx,8           ; Close TCP socket
613
    mov     ecx,[DataSocket]
485 heavyiron 614
    mcall
481 diamond 615
    ret
616
 
617
 
618
 
619
 
620
;***************************************************************************
621
;   Function
622
;      connect
623
;
624
;   Description
625
;       Opens the command socket
626
;
627
;   Inputs
628
;       None
629
;
630
;***************************************************************************
631
connect:
632
    pusha
633
 
634
    mov     eax, 53     ; Stack Interface
635
    mov     ebx, 5      ; Open TCP socket
636
    mov     esi, 0      ; No remote IP address
637
    mov     edx, 0      ; No remote port
638
    mov     ecx, 21     ; ftp command port id
639
    mov     edi, 0      ; passive open
485 heavyiron 640
    mcall
481 diamond 641
    mov     [CmdSocket], eax
642
 
643
    popa
644
 
645
    ret
646
 
647
 
648
 
649
;***************************************************************************
650
;   Function
651
;      connectData
652
;
653
;   Description
654
;       Opens the data socket
655
;
656
;   Inputs
657
;       None
658
;
659
;***************************************************************************
660
connectData:
661
    pusha
662
 
663
    mov     eax, 53     ; Stack Interface
664
    mov     ebx, 5      ; Open TCP socket
665
    mov     esi, [DataIP]      ; remote IP address
666
    mov     edx, [DataPort]    ; remote port
1287 tsdima 667
    mov     ecx, 0      ; ftp data port id
481 diamond 668
    mov     edi, 1      ; active open
485 heavyiron 669
    mcall
481 diamond 670
    mov     [DataSocket], eax
671
 
672
    popa
673
 
674
    ret
675
 
676
 
677
 
678
 
679
;***************************************************************************
680
;   Function
681
;      findCmd
682
;
683
;   Description
684
;       Scans the command string for a valid command. The command string
685
;       is in the global variable buff.
686
;
687
;       Returns result in cmdPtr. This will be zero if none found
688
;
689
;   Inputs
690
;       None
691
;
692
;***************************************************************************
693
findCmd:
694
    ; Setup to return 'none' in cmdPtr, if we find no cmd
695
    mov     eax, 0
696
    mov     [cmdPtr], eax
697
    cld
698
    mov     esi, buff
699
    mov     edi, CMDList
700
 
701
fc000:
702
    cmp     [edi], byte 0   ; Are we at the end of the CMDList?
703
    je      fc_exit
704
 
705
fc000a:
706
    cmpsb
707
 
708
    je      fc_nextbyte
709
 
710
    ; Command is different - move to the next entry in cmd table
711
    mov     esi, buff
712
 
713
fc001:
714
    ; skip to the next command in the list
715
    cmp     [edi], byte 0
716
    je      fc002
717
    inc     edi
718
    jmp     fc001
719
fc002:
720
    add     edi, 5
721
    jmp     fc000
722
 
723
fc_nextbyte:
724
    ; Have we reached the end of the CMD text?
725
    cmp     [edi], byte 0
726
    je      fc_got      ; Yes - so we have a match
727
    jmp     fc000a      ; No - loop back
728
 
729
fc_got:
730
    ; Copy the function pointer for the selected command
731
    inc     edi
732
    mov     eax, [edi]
733
    mov     [cmdPtr], eax
734
 
735
fc_exit:
736
    ret
737
 
738
 
739
 
740
;***************************************************************************
741
;   Function
742
;      decStr2Byte
743
;
744
;   Description
745
;       Converts the decimal string pointed to by esi to a byte
746
;
747
;   Inputs
748
;       string ptr in esi
749
;
750
;   Outputs
751
;       esi points to next character not in string
752
;       eax holds result ( 0..255)
753
;
754
;***************************************************************************
755
decStr2Byte:
756
    xor     eax, eax
757
    xor     ebx, ebx
758
    mov     ecx, 3
759
 
760
dsb001:
761
    mov     bl, [esi]
762
 
763
    cmp     bl, '0'
764
    jb      dsb_exit
765
    cmp     bl, '9'
766
    ja      dsb_exit
767
 
768
    imul    eax, 10
769
    add     eax, ebx
770
    sub     eax, '0'
771
    inc     esi
772
    loop    dsb001
773
 
774
dsb_exit:
775
    ret
776
 
777
 
778
 
779
;***************************************************************************
780
;   Function
781
;      parsePortStr
782
;
783
;   Description
784
;       Converts the parameters of the PORT command, and stores them in the
785
;       appropriate variables.
786
;
787
;   Inputs
788
;       None ( string in global variable buff )
789
;
790
;   Outputs
791
;       None
792
;
793
;***************************************************************************
794
parsePortStr:
795
    ; skip past the PORT text to get the the parameters. The command format
796
    ; is
797
    ; PORT i,i,i,i,p,p,0x0d,0x0a
798
    ; where i and p are decimal byte values, high byte first.
799
    xor     eax, eax
800
    mov     [DataIP], eax
801
    mov     [DataPort], eax
802
    mov     esi, buff + 4       ; Start at first space character
803
 
804
pps001:
805
    cmp     [esi], byte ' '     ; Look for first non space character
806
    jne     pps002
807
    inc     esi
808
    jmp     pps001
809
 
810
pps002:
811
    call    decStr2Byte
812
    add     [DataIP], eax
813
    ror     dword [DataIP], 8
814
    inc     esi
815
    call    decStr2Byte
816
    add     [DataIP], eax
817
    ror     dword [DataIP], 8
818
    inc     esi
819
    call    decStr2Byte
820
    add     [DataIP], eax
821
    ror     dword [DataIP], 8
822
    inc     esi
823
    call    decStr2Byte
824
    add     [DataIP], eax
825
    ror     dword [DataIP], 8
826
    inc     esi
827
    call    decStr2Byte
828
    add     [DataPort], eax
829
    shl     [DataPort], 8
830
    inc     esi
831
    call    decStr2Byte
832
    add     [DataPort], eax
833
 
834
    ret
835
 
836
 
837
 
838
;***************************************************************************
839
;   Function
840
;      sendDir
841
;
842
;   Description
843
;       Transmits the directory listing over the data connection.
844
;       The data connection is already open.
845
;
846
;   Inputs
661 ataualpa 847
;       None
481 diamond 848
;
849
;   Outputs
850
;       None
851
;
852
;***************************************************************************
853
sendDir:
1323 tsdima 854
        mov     eax, text+0x4000
855
        mov     [fsize], eax
481 diamond 856
        mov     ebx, dirinfoblock
857
        and     dword [ebx+4], 0        ; start from zero block
858
sd001:
859
; Read the next DirBlocksPerCall (=16) blocks
860
        mov     eax, 70
485 heavyiron 861
        mcall
481 diamond 862
; Did we read anything?
863
        test    eax, eax
864
        jz      @f
865
        cmp     eax, 6
866
        jnz     sd_exit
867
@@:
868
        test    ebx, ebx
869
        jz      sd_exit
870
; Parse these blocks. There could be up to 16 files specified
871
        mov     esi, text + 0x1300 + 0x20
872
sd002:
873
        dec     ebx
874
        js      sd004
875
        push    ebx
876
; OK, lets parse the entry. Ignore volume entries
877
        test    byte [esi], 8
878
        jnz     sd003
879
; Valid file or directory. Start to compose the string we will send
880
        mov     edi, dirStr
881
; If we have been called as a result of an NLST command, we only display
882
; the filename
883
        cmp     [buff], byte 'N'
884
        jz      sd006
885
 
886
        mov     [edi], byte '-'
887
        test    byte [esi], 10h
888
        jz      @f
889
        mov     [edi], byte 'd'
890
@@:
891
; Ok, now copy across the directory listing text that will be constant
892
; ( I dont bother looking at the read only or archive bits )
893
 
894
        mov     ebx, tmplStr
895
@@:
896
        inc     edi
897
        mov     al, [ebx]
898
        test    al, al
899
        jz      @f
900
        mov     [edi], al
901
        inc     ebx
902
        jmp     @b
903
@@:
904
; point to the last character of the string;
905
; We will write the file size here, backwards
906
        push    edi             ; Remember where the string ends
907
 
908
        dec     edi
909
; eax holds the number
910
        mov     eax, [esi+32]
911
        mov     ebx, 10
912
@@:
913
        xor     edx, edx
914
        div     ebx
915
        add     dl, '0'
916
        mov     [edi], dl
917
        dec     edi
918
        test    eax, eax
919
        jnz     @b
920
 
921
        pop     edi
922
; now create the time & date fields
923
;timeStr:            db ' Jan 1    2000 ',0
924
        mov     al, ' '
925
        stosb
926
        movzx   eax, byte [esi+28+1]
927
        mov     eax, dword [months + (eax-1)*4]
928
        stosd
929
        mov     al, byte [esi+28]
930
        aam
931
        test    ah, ah
932
        jz      sd005a
933
        xchg    al, ah
934
        add     ax, '00'
935
        jmp     sd005b
936
sd005a:
937
        add     al, '0'
938
        mov     ah, ' '
939
sd005b:
940
        stosw
941
        mov     al, ' '
942
        mov     ecx, 6
943
        rep     stosb
944
        push    edi
945
        movzx   eax, word [esi+28+2]
946
@@:
947
        xor     edx, edx
948
        div     ebx
949
        add     dl, '0'
950
        mov     [edi], dl
951
        dec     edi
952
        test    eax, eax
953
        jnz     @b
954
        pop     edi
955
        inc     edi
956
        mov     al, ' '
957
        stosb
958
sd006:
959
; ** End of copying
960
 
961
; now copy the filename across
962
        lea     ebx, [esi+40]
963
@@:
964
        mov     al, [ebx]
965
        inc     ebx
966
        test    al, al
967
        jz      @f
968
        stosb
969
        jmp     @b
970
@@:
971
terminate:
972
; Now terminate the line by putting CRLF sequence in
973
        mov     al, 0x0D
974
        stosb
975
        mov     al, 0x0A
976
        stosb
977
; Send the completed line to the user over data socket
978
        push    esi
1323 tsdima 979
        push    edi
481 diamond 980
        mov     esi, dirStr
1323 tsdima 981
        mov     ecx, edi
982
        sub     ecx, esi
983
        mov     edi, [fsize]
984
        cld
985
        rep     movsb
986
        mov     [fsize], edi
987
        cmp     edi, text+0x4400
988
        jb      @f
989
        mov     esi, text+0x4000
990
        mov     edx, [fsize]
481 diamond 991
        sub     edx, esi
1323 tsdima 992
        mov     [fsize], esi
481 diamond 993
        call    outputDataStr
1323 tsdima 994
 
995
@@:
996
        pop     edi
481 diamond 997
        pop     esi
998
 
999
sd003:                  ; Move to next entry in the block
1000
        pop     ebx
1001
        add     esi, 304
1002
        jmp     sd002
1003
sd004:
1004
        mov     ebx, dirinfoblock
1005
        add     dword [ebx+4], DirBlocksPerCall
1006
        jmp     sd001
1007
 
1008
sd_exit:
1323 tsdima 1009
        mov     esi, text+0x4000
1010
        mov     edx, [fsize]
1011
        sub     edx, esi
1012
        call    outputDataStr
481 diamond 1013
        ret
1014
 
1015
 
1016
 
1017
 
1018
 
1019
;***************************************************************************
1020
;   Function
1021
;      setupFilePath
1022
;
1023
;   Description
1024
;       Copies the file name from the input request string into the
1025
;       file descriptor
1026
;
1027
;   Inputs
661 ataualpa 1028
;       None
481 diamond 1029
;
1030
;   Outputs
1031
;       None
1032
;
1033
;***************************************************************************
1034
setupFilePath:
1035
    mov     esi, buff + 4       ; Point to (1 before) first character of file
661 ataualpa 1036
 
481 diamond 1037
    ; Skip any trailing spaces or / character
661 ataualpa 1038
sfp001:
481 diamond 1039
    inc     esi
1040
    cmp     [esi], byte ' '
1041
    je      sfp001
1042
    cmp     [esi], byte '/'
1043
    je      sfp001
661 ataualpa 1044
 
481 diamond 1045
    ; esi points to start of filename.
1325 tsdima 1046
    cld
1047
    push    esi
661 ataualpa 1048
 
481 diamond 1049
    ; Copy across the directory path '/'
1050
    ; into the fileinfoblock
1325 tsdima 1051
    mov     esi, dirpath
481 diamond 1052
    mov     edi, filename
1325 tsdima 1053
sfp003:
1054
    movsb
1055
    cmp     [esi], byte 0
1056
    jne     sfp003
1057
    mov     al, '/'
1058
    stosb
1059
    pop     esi
661 ataualpa 1060
 
481 diamond 1061
    ; Copy across the filename
1062
sfp002:
1063
    movsb
1064
    cmp     [esi], byte 0x0d
1065
    jne     sfp002
661 ataualpa 1066
    mov     [edi], byte 0
481 diamond 1067
    ret
1068
 
1069
 
1070
 
1071
 
1072
;***************************************************************************
1073
;   Function
1074
;      sendFile
1075
;
1076
;   Description
1077
;       Transmits the requested file over the open data socket
1078
;       The file to send is named in the buff string
1079
;
1080
;   Inputs
661 ataualpa 1081
;       None
481 diamond 1082
;
1083
;   Outputs
1084
;       None
1085
;
1086
;***************************************************************************
1087
sendFile:
1088
    call    setupFilePath
1089
 
1090
    ; init fileblock descriptor, for file read
1091
    mov     ebx, fileinfoblock
1092
    and     dword [ebx], 0 ; read cmd
1093
    and     dword [ebx+4], 0 ; first block
1301 tsdima 1094
    mov     dword [ebx+12], 0x400 ; block size
481 diamond 1095
 
1096
sf002a:
661 ataualpa 1097
    ; now read the file..
481 diamond 1098
    mov     eax,70
485 heavyiron 1099
    mcall
481 diamond 1100
    test    eax, eax
1101
    jz      @f
1102
    cmp     eax, 6
1103
    jnz     sf_exit
1104
@@:
1105
    push    eax
1106
    mov     esi, text + 0x1300
1107
    mov     edx, ebx
1108
    call    outputDataStr
1109
    pop     eax
1110
    test    eax, eax
1111
    jnz     sf_exit
1112
; wait a bit
1113
    mov     eax, 5
1301 tsdima 1114
    mov     ebx, 1
485 heavyiron 1115
    mcall
481 diamond 1116
    mov     ebx, fileinfoblock
1117
    add     dword [ebx+4], edx
1118
    jmp     sf002a
1119
 
661 ataualpa 1120
sf_exit:
481 diamond 1121
    ret
1122
 
661 ataualpa 1123
 
481 diamond 1124
;***************************************************************************
1125
;   Function
1126
;      getFile
1127
;
1128
;   Description
1129
;       Receives the specified file over the open data socket
1130
;       The file to receive is named in the buff string
1131
;
1132
;   Inputs
661 ataualpa 1133
;       None
481 diamond 1134
;
1135
;   Outputs
1136
;       None
1137
;
1138
;***************************************************************************
1139
getFile:
1140
    call    setupFilePath
661 ataualpa 1141
 
481 diamond 1142
    ; init fileblock descriptor, for file write
1143
    xor     eax, eax
1144
    mov     [fsize], eax            ; Start filelength at 0
1145
    mov     [fileinfoblock+4], eax    ; set to 0
1146
    inc     eax
1147
    inc     eax
1148
    mov     [fileinfoblock], eax    ; write cmd
661 ataualpa 1149
 
481 diamond 1150
    ; Read data from the socket until the socket closes
1151
    ; loop
1152
    ;   loop
1153
    ;     read byte from socket
1154
    ;     write byte to file buffer
1155
    ;   until no more bytes in socket
1156
    ;   sleep 100ms
1157
    ; until socket no longer connected
1158
    ; write file to ram
661 ataualpa 1159
 
481 diamond 1160
gf000:
1161
    mov     eax, 53
1162
    mov     ebx, 2                  ; Get # of bytes in input queue
1163
    mov     ecx, [DataSocket]
485 heavyiron 1164
    mcall
481 diamond 1165
    test    eax, eax
1166
    je      gf_sleep
661 ataualpa 1167
 
481 diamond 1168
    mov     eax, 53
1325 tsdima 1169
    mov     ebx, 11                 ; Get bytes from socket
481 diamond 1170
    mov     ecx, [DataSocket]
1301 tsdima 1171
    mov     edx, text + 0x1300
1172
    add     edx, dword [fsize]
1323 tsdima 1173
    xor     esi, esi
1301 tsdima 1174
    mcall                           ; returned data len in eax
1175
    add     dword [fsize], eax
661 ataualpa 1176
 
481 diamond 1177
    jmp     gf000
1178
 
1179
gf_sleep:
1180
    ; Check to see if socket closed...
1181
    mov     eax,53
1182
    mov     ebx,6               ; Get socket status
1183
    mov     ecx,[DataSocket]
485 heavyiron 1184
    mcall
481 diamond 1185
 
1186
    cmp     eax, 7
1187
    jne     gf001               ; still open, so just sleep a bit
1188
 
1189
    ; Finished, so write the file
1190
    mov     eax, [fsize]
1191
    mov     [fileinfoblock+12], eax
1192
    mov     eax,70
1193
    mov     ebx,fileinfoblock
485 heavyiron 1194
    mcall
481 diamond 1195
 
1196
    ret                         ; Finished
1197
 
1198
gf001:
1199
    ; wait a bit
1200
    mov     eax,5
1301 tsdima 1201
    mov     ebx,1               ; Delay for up 10ms
485 heavyiron 1202
    mcall
481 diamond 1203
    jmp     gf000               ; try for more data
1204
 
1205
 
1206
 
661 ataualpa 1207
 
1208
 
481 diamond 1209
;***************************************************************************
1210
;   COMMAND HANDLERS FOLLOW
1211
;
1212
;   These handlers implement the functionality of each supported FTP Command
1213
;
1214
;***************************************************************************
1215
 
1216
cmdPWD:
1325 tsdima 1217
    cld
1218
    mov     edi, text+0x1300
1219
 
1220
    mov     esi, curdir_1
1221
    mov     ecx, curdir_2-curdir_1
1222
    rep     movsb
1223
 
1224
    mov     esi, [curdirptr]
1225
    cmp     [esi], byte 0
1226
    jne     cpwd_000
1227
    mov     al, '/'
1228
    stosb
1229
    jmp     cpwd_001
1230
 
1231
cpwd_000:
1232
    movsb
1233
    cmp     [esi], byte 0
1234
    jne     cpwd_000
1235
 
1236
cpwd_001:
1237
    mov     esi, curdir_2
1238
    mov     ecx, curdir_end-curdir_2
1239
    rep     movsb
1240
 
481 diamond 1241
    ; OK, show the directory name text
1325 tsdima 1242
    mov     esi, text+0x1300
1243
    mov     edx, edi
1244
    sub     edx, esi
481 diamond 1245
    call    outputStr
1246
 
1247
    ret
1248
 
1249
 
1250
cmdCWD:
1325 tsdima 1251
    lea     esi, [buff+4]
1252
    mov     edi, [curdirptr]
1253
    mov     ecx, -1
1254
    xor     eax, eax
1255
    repne   scasb
1256
    dec     edi
1257
    cmp     [esi], word '..'
1258
    je      ccwd_002
1259
    test    [esi], byte 0xE0
1260
    je      ccwd_000
1261
    push    edi
1262
    mov     al, '/'
1263
    stosb
1264
@@:
1265
    movsb
1266
    cmp     [esi], byte 0xD
1267
    jne     @b
1268
    xor     al, al
1269
    stosb
1270
 
1271
    mov     eax, 70
1272
    mov     ebx, dirinfoblock
1273
    and     dword [ebx+4], 0
1274
    mcall
1275
    pop     edi
1276
    test    eax, eax
1277
    je      @f
1278
    cmp     eax, 6
481 diamond 1279
    jne     ccwd_000
1325 tsdima 1280
@@:
1281
    test    ebx, ebx
1282
    je      ccwd_000
1283
    mov     esi, text + 0x1300 + 0x20
661 ataualpa 1284
 
1325 tsdima 1285
    mov     al, byte [esi]
1286
    and     al, 0x18
1287
    cmp     al, 0x10
1288
    jne     ccwd_000
1289
 
1290
ccwd_ok:
481 diamond 1291
    ; OK, show the directory name text
1292
    mov     esi, chdir
1293
    mov     edx, chdir_end - chdir
1294
    jmp     ccwd_001
661 ataualpa 1295
 
1325 tsdima 1296
ccwd_002:
1297
    dec     edi
1298
    cmp     byte [edi], '/'
1299
    je      ccwd_003
1300
    cmp     edi, [curdirptr]
1301
    ja      ccwd_002
1302
    jmp     ccwd_ok
1303
ccwd_003:
1304
    mov    byte [edi], 0
1305
    jmp     ccwd_ok
1306
 
481 diamond 1307
ccwd_000:
1325 tsdima 1308
    mov    byte [edi], 0
481 diamond 1309
    ; Tell user there is no such directory
1310
    mov     esi, noFileStr
1311
    mov     edx, noFileStr_end - noFileStr
1312
 
1313
ccwd_001:
1314
    call    outputStr
1315
 
1316
    ret
1317
 
1318
 
1319
cmdQUIT:
1320
    ; The remote end will do the close; We just
1321
    ; say goodbye.
1322
    mov     esi, byeStr
1323
    mov     edx, byeStr_end - byeStr
1324
    call    outputStr
1325
    ret
1326
 
1327
 
1328
cmdABOR:
1329
 
1330
    ; Close port
1331
    call    disconnectData
1332
 
1333
    mov     esi, abortStr
1334
    mov     edx, abortStr_end - abortStr
1335
    call    outputStr
1336
 
1337
    ret
1338
 
1339
cmdPORT:
1340
    ; TODO
1341
    ; Copy the IP and port values to DataIP and DataPort
1342
 
1343
    call    parsePortStr
1344
 
1345
    ; Indicate the command was accepted
1346
    mov     esi, cmdOKStr
1347
    mov     edx, cmdOKStr_end - cmdOKStr
1348
    call    outputStr
1349
    ret
1350
 
1351
cmdnoop:
1352
    ; Indicate the command was accepted
1353
    mov     esi, cmdOKStr
1354
    mov     edx, cmdOKStr_end - cmdOKStr
1355
    call    outputStr
1356
    ret
1357
 
1358
 
1359
cmdTYPE:
1360
    ; TODO
1361
    ; Note the type field selected - reject if needed.
1362
 
1363
    ; Indicate the command was accepted
1364
    mov     esi, cmdOKStr
1365
    mov     edx, cmdOKStr_end - cmdOKStr
1366
    call    outputStr
1367
    ret
1368
 
1369
cmdsyst:
1370
    ; Indicate the system type
1371
    mov     esi, systStr
1372
    mov     edx, systStr_end - systStr
1373
    call    outputStr
1374
    ret
1375
 
1376
 
1377
cmdDELE:
1378
    call    setupFilePath
1379
 
1380
    mov     ebx, fileinfoblock
1381
    mov     dword [ebx], 8
1382
    and     dword [ebx+4], 0
1383
    push    dword [ebx+12]
1384
    push    dword [ebx+16]
1385
    and     dword [ebx+12], 0
1386
    and     dword [ebx+16], 0
1387
    mov     eax, 70
485 heavyiron 1388
    mcall
1302 tsdima 1389
    mov     ebx, fileinfoblock
481 diamond 1390
    pop     dword [ebx+16]
1391
    pop     dword [ebx+12]
661 ataualpa 1392
 
481 diamond 1393
    test    eax, eax
1394
    jne     cmdDele_err
1395
 
1396
    mov     esi, delokStr
1397
    mov     edx, delokStr_end - delokStr
1398
    call    outputStr
661 ataualpa 1399
 
481 diamond 1400
    jmp     cmdDele_exit
661 ataualpa 1401
 
1402
cmdDele_err:
481 diamond 1403
    mov     esi, noFileStr
1404
    mov     edx, noFileStr_end - noFileStr
1405
    call    outputStr
661 ataualpa 1406
 
1407
 
481 diamond 1408
cmdDele_exit:
1409
    ret
1410
 
1411
 
1412
cmdNLST:
1413
cmdLIST:
1414
    ; Indicate the command was accepted
1415
    mov     esi, startStr
1416
    mov     edx, startStr_end - startStr
1417
    call    outputStr
1418
 
1419
    call    connectData
1420
 
1421
    ; Wait for socket to establish
1422
 
1423
cl001:
1424
    ; wait a bit
1425
    mov     eax,5
1426
    mov     ebx,10                ; Delay for up 100ms
485 heavyiron 1427
    mcall
481 diamond 1428
 
1429
    ; check connection status
1430
    mov     eax,53
1431
    mov     ebx,6               ; Get socket status
1432
    mov     ecx,[DataSocket]
485 heavyiron 1433
    mcall
481 diamond 1434
 
1435
    cmp     eax, 4
1436
    jne     cl001
1437
 
1438
    ; send directory listing
1439
    call    sendDir
661 ataualpa 1440
 
481 diamond 1441
    ; Close port
1442
    call    disconnectData
1443
 
1444
    mov     esi, endStr
1445
    mov     edx, endStr_end - endStr
1446
    call    outputStr
1447
    ret
1448
 
1449
cmdRETR:
1450
    ; Indicate the command was accepted
1451
    mov     esi, startStr
1452
    mov     edx, startStr_end - startStr
1453
    call    outputStr
1454
 
1455
    call    connectData
1456
 
1457
    ; Wait for socket to establish
1458
 
1459
cr001:
1460
    ; wait a bit
1461
    mov     eax,5
1462
    mov     ebx,10                ; Delay for up 100ms
485 heavyiron 1463
    mcall
481 diamond 1464
 
1465
    ; check connection status
1466
    mov     eax,53
1467
    mov     ebx,6               ; Get socket status
1468
    mov     ecx,[DataSocket]
485 heavyiron 1469
    mcall
481 diamond 1470
 
1471
    cmp     eax, 4
1472
    jne     cr001
1473
 
1474
    ; send data to remote user
1475
    call    sendFile
661 ataualpa 1476
 
481 diamond 1477
    ; Close port
1478
    call    disconnectData
1479
 
1480
    mov     esi, endStr
1481
    mov     edx, endStr_end - endStr
1482
    call    outputStr
1483
 
1484
 
1485
    ret
1486
 
1487
 
1488
cmdSTOR:
1489
    ; Indicate the command was accepted
1490
    mov     esi, storStr
1491
    mov     edx, storStr_end - storStr
1492
    call    outputStr
1493
 
1494
    call    connectData
1495
 
1496
    ; Wait for socket to establish
1497
 
1498
cs001:
1499
    ; wait a bit
1500
    mov     eax,5
1501
    mov     ebx,10                ; Delay for up 100ms
485 heavyiron 1502
    mcall
481 diamond 1503
 
1504
    ; check connection status
1505
    mov     eax,53
1506
    mov     ebx,6               ; Get socket status
1507
    mov     ecx,[DataSocket]
485 heavyiron 1508
    mcall
481 diamond 1509
 
1510
    cmp     eax, 4
1511
    je      @f
1512
    cmp     eax, 7
1513
    jne     cs001
1514
@@:
1515
 
1516
    ; get data file from remote user
1517
    call    getFile
661 ataualpa 1518
 
481 diamond 1519
    mov     esi, endStr
1520
    mov     edx, endStr_end - endStr
1521
    call    outputStr
1522
 
1523
    ; Close port
1524
    call    disconnectData
1525
 
1526
    ret
1527
 
1528
 
1529
 
1530
; DATA AREA
1531
 
1532
; This is the list of supported commands, and the function to call
1533
; The list end with a NULL.
1534
CMDList:
1535
                    db  'pwd',0
1536
                    dd  cmdPWD
1537
 
1538
                    db  'PWD',0
1539
                    dd  cmdPWD
1540
 
1541
                    db  'XPWD',0
1542
                    dd  cmdPWD
1543
 
1544
                    db  'xpwd',0
1545
                    dd  cmdPWD
1546
 
1547
                    db  'QUIT',0
1548
                    dd  cmdQUIT
1549
 
1550
                    db  'quit',0
1551
                    dd  cmdQUIT
1552
 
1553
                    db  'PORT',0
1554
                    dd  cmdPORT
1555
 
1556
                    db  'port',0
1557
                    dd  cmdPORT
1558
 
1559
                    db  'LIST',0
1560
                    dd  cmdLIST
1561
 
1562
                    db  'list',0
1563
                    dd  cmdLIST
1564
 
1565
                    db  'NLST',0
1566
                    dd  cmdNLST
1567
 
1568
                    db  'nlst',0
1569
                    dd  cmdNLST
1570
 
1571
                    db  'TYPE',0
1572
                    dd  cmdTYPE
1573
 
1574
                    db  'type',0
1575
                    dd  cmdTYPE
1576
 
1577
                    db  'syst',0
1578
                    dd  cmdsyst
1579
 
1580
                    db  'noop',0
1581
                    dd  cmdnoop
1582
 
1583
                    db  'CWD',0
1584
                    dd  cmdCWD
1585
 
1586
                    db  'cwd',0
1587
                    dd  cmdCWD
1588
 
1589
                    db  'RETR',0
1590
                    dd  cmdRETR
1591
 
1592
                    db  'retr',0
1593
                    dd  cmdRETR
1594
 
1595
                    db  'DELE',0
1596
                    dd  cmdDELE
1597
 
1598
                    db  'dele',0
1599
                    dd  cmdDELE
1600
 
1601
                    db  'stor',0
1602
                    dd  cmdSTOR
1603
 
1604
                    db  'STOR',0
1605
                    dd  cmdSTOR
1606
 
1607
                    db  'ABOR',0
1608
                    dd  cmdABOR
1609
 
1610
                    db  'abor',0
1611
                    dd  cmdABOR
1612
 
1613
                    db  0xff,0xf4,0xff,0xf2,'ABOR',0
1614
                    dd  cmdABOR
1615
 
1616
                    db  0
1617
 
1618
 
1619
cmdPtr              dd  0
1620
CmdSocket           dd  0x0
1621
CmdSocketStatus     dd  0x0
1622
DataSocket          dd  0x0
1623
DataSocketStatus    dd  0x0
1624
DataPort            dd  0x00
1625
DataIP              dd  0x00
1626
pos                 dd  80 * 1
1627
scroll              dd  1
1628
                    dd  24
1629
 
1630
labelt              db  'FTP Server v0.1',0
1631
contt               db  'Connected'
1632
contlen:
1633
discontt            db  'Disconnected'
1634
discontlen:
1635
 
1636
cmdOKStr:           db  '200 Command OK',0x0d,0x0a
1637
cmdOKStr_end:
1638
 
1639
loginStr0:          db  '220-  Menuet FTP Server v0.1',0x0d,0x0a
1640
                    db  '220 Username and Password required',0x0d,0x0a
1641
loginStr0_end:
1642
 
1643
loginStr1:          db  '331 Password now required',0x0d,0x0a
1644
loginStr1_end:
1645
 
1646
loginStr2:          db  '230 You are now logged in.',0x0d,0x0a
1647
loginStr2_end:
1648
 
1649
byeStr:             db  '221 Bye bye!',0x0d,0x0a
1650
byeStr_end:
1651
 
1652
systStr:            db  '215 UNIX system type',0x0d,0x0a
1653
systStr_end:
1654
 
1325 tsdima 1655
curdir_1:           db  '257 "'
1656
curdir_2:           db  '"',0x0d,0x0a
1657
curdir_end:
481 diamond 1658
 
1325 tsdima 1659
chdir:              db  '250 CWD command successful',0x0d,0x0a
481 diamond 1660
chdir_end:
1661
 
1662
unsupStr:           db  '500 Unsupported command',0x0d,0x0a
1663
unsupStr_end:
1664
 
1665
noFileStr:          db  '550 No such file',0x0d,0x0a
1666
noFileStr_end:
1667
 
1668
delokStr:           db  '250 DELE command successful',0x0d,0x0a
1669
delokStr_end:
1670
 
1671
startStr:           db  '150 Here it comes...',0x0d,0x0a
1672
startStr_end:
1673
 
1674
storStr:            db  '150 Connecting for STOR',0x0d,0x0a
1675
storStr_end:
1676
 
1677
endStr:             db  '226 Transfer OK, Closing connection',0x0d,0x0a
1678
endStr_end:
1679
 
1680
abortStr:           db  '225 Abort successful',0x0d,0x0a
1681
abortStr_end:
1682
 
1683
 ; This is the buffer used for building up a directory listing line
1684
dirStr:             times 128 db 0
1685
 
1686
; This is template string used in building up a directory listing line
1687
tmplStr:            db 'rw-rw-rw-    1 0        0                ',0
1688
 
1689
months:
1690
        dd     'Jan ','Feb ','Mar ','Apr ','May ','Jun '
1691
        dd     'Jul ','Aug ','Sep ','Oct ','Nov ','Dec '
1692
 
1693
fileinfoblock:
1694
                    dd      0x00
1695
                    dd      0x00
1696
                    dd      0x00
1697
                    dd      0x200         ; bytes to read
1698
                    dd      text + 0x1300 ; data area
1699
filename:           times 256 db 0
1700
 
1701
; The following lines define data for reading a directory block
1702
DirBlocksPerCall = 16
1703
dirinfoblock:
1704
                    dd      1
1705
                    dd      0x00
1706
                    dd      0x00
1707
                    dd      DirBlocksPerCall
1708
                    dd      text + 0x1300   ; data area
1709
; The 'filename' for a directory listing
1325 tsdima 1710
dirpath:            db      '/sys'
1711
                    times 252 db 0
1712
curdirptr:          dd      dirpath+4
481 diamond 1713
 
1714
fsize:              dd      0
661 ataualpa 1715
 
481 diamond 1716
state               db  0
1717
buffptr             dd  0
1718
buff:               times 256 db 0  ; Could put this after iend
1719
 
1720
; Ram use at the end of the application:
1721
; text                  : 2400 bytes for screen memory
1722
; text + 0x1300          : file data area
1723
text:
1724
I_END: