Subversion Repositories Kolibri OS

Rev

Rev 1323 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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