Added CWD command to FTP daemon (net branch)

git-svn-id: svn://kolibrios.org@2563 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-04-04 17:19:00 +00:00
parent 0833e5c02d
commit d277a579f2
3 changed files with 277 additions and 111 deletions

View File

@ -49,7 +49,7 @@ commands: ; all commands must be in uppercase
dd cmdPASS dd cmdPASS
db 'PASV' db 'PASV'
dd cmdPASV dd cmdPASV
db 'PWD', 0 ; Print Working Directory db 'PWD', 0
dd cmdPWD dd cmdPWD
db 'PORT' db 'PORT'
dd cmdPORT dd cmdPORT
@ -76,7 +76,39 @@ cmdABOR:
ret ret
align 4 align 4
cmdCWD: cmdCWD: ; Change Working Directory
sub ecx, 4
jb .err
add esi, 4
mov edi, work_dir + 1
cmp byte [esi], '/'
jne @f
inc esi
dec ecx
jz .done
@@:
.loop:
lodsb
cmp al, 0x20
jb .done
stosb
loop .loop
.done:
cmp byte [edi-1], '/'
je @f
mov byte [edi], '/'
inc edi
@@:
mov byte [edi], 0
mcall send, [socketnum2], str250, str250.length, 0
ret
.err:
ret ret
@ -88,6 +120,7 @@ cmdDELE:
align 4 align 4
cmdLIST: cmdLIST:
; If we are in active mode, it's time to open a data socket..
cmp [mode], MODE_ACTIVE cmp [mode], MODE_ACTIVE
jne @f jne @f
mcall connect, [datasocketnum], datasock, datasock.length mcall connect, [datasocketnum], datasock, datasock.length
@ -95,31 +128,30 @@ cmdLIST:
je .err je .err
@@: @@:
; Warn the client we're about to send the data
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes.. mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
; Create fpath from home_dir and work_dir
call create_path
; Start the search
push FA_READONLY + FA_FOLDER push FA_READONLY + FA_FOLDER
push str_mask push str_mask
push home_dir push fpath
call [file.find.first] call [file.find.first]
mov edi, buffer mov edi, buffer
jmp .parse_file
.checknextfile:
push edx
call [file.find.next]
.parse_file: .parse_file:
test eax, eax test eax, eax ; did we find a file?
jz .done jz .done
mov edx, eax mov edx, eax ; yes, save the descripter
; first, convert the attributes ; first, convert the attributes
test [eax + FileInfoA.Attributes], FA_FOLDER test [edx + FileInfoA.Attributes], FA_FOLDER
jnz .folder jnz .folder
test [eax + FileInfoA.Attributes], FA_READONLY test [edx + FileInfoA.Attributes], FA_READONLY
jnz .readonly jnz .readonly
mov eax, '-rw-' mov eax, '-rw-'
@ -128,7 +160,7 @@ cmdLIST:
.folder: .folder:
mov eax, 'drwx' mov eax, 'drwx'
stosb stosd
jmp .attr jmp .attr
.readonly: .readonly:
@ -153,7 +185,7 @@ cmdLIST:
stosd stosd
; now the filesize in ascii ; now the filesize in ascii
mov ebx, dword [edx + FileInfoA.FileSize] mov ebx, [edx + FileInfoA.FileSizeLow]
call dword_to_ascii call dword_to_ascii
mov al, ' ' mov al, ' '
@ -186,24 +218,34 @@ cmdLIST:
stosb stosb
loop .nameloop loop .nameloop
; insert a cr lf
.namedone: .namedone:
mov ax, 0x0d0a mov ax, 0x0d0a
stosw stosw
jmp .checknextfile
; check next file
push edx
call [file.find.next]
jmp .parse_file
; close file desc
.done: .done:
push edx push edx
call [file.find.close] call [file.find.close]
; append the string with a 0
xor al, al xor al, al
stosb stosb
; print everything on the console
push buffer push buffer
call [con_write_asciiz] call [con_write_asciiz]
; and send it to the client
lea esi, [edi - buffer] lea esi, [edi - buffer]
mcall send, [datasocketnum], buffer, , 0 mcall send, [datasocketnum], buffer, , 0
; close the data socket..
mcall close, [datasocketnum] mcall close, [datasocketnum]
cmp [mode], MODE_PASSIVE_OK cmp [mode], MODE_PASSIVE_OK
@ -211,7 +253,8 @@ cmdLIST:
mov [mode], MODE_PASSIVE_WAIT mov [mode], MODE_PASSIVE_WAIT
@@: @@:
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok ; And send "transfer ok" on the base connection
mcall send, [socketnum2], str226, str226.length, 0
ret ret
@ -296,7 +339,7 @@ cmdPASV:
ret ret
align 4 align 4
cmdPWD: cmdPWD: ; Print Working Directory
mov dword[buffer], '257 ' mov dword[buffer], '257 '
mov byte[buffer+4], '"' mov byte[buffer+4], '"'
@ -383,22 +426,51 @@ cmdQUIT:
align 4 align 4
cmdRETR: cmdRETR:
; mcall connect, [datasocketnum], datasock, datasock.length cmp [mode], MODE_ACTIVE
jne @f
mcall connect, [datasocketnum], datasock, datasock.length
; cmp eax, -1 ; cmp eax, -1
; je .err ; je .err
@@:
; push O_READ mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
; push home_dir
; call [file.open] push O_READ
push home_dir
call [file.open]
; test eax, eax ; test eax, eax
; jz .cannot_open ; jz .cannot_open
;
; push BUFFERSIZE mov ebx, eax
; push buffer
; push eax .read_more:
; call [file.read] push BUFFERSIZE
push buffer
push ebx
call [file.read]
; cmp eax, -1 ; cmp eax, -1
; jz .cannot_open ; je .cannot_open
push eax
push ebx
mov esi, eax
mcall send, [datasocketnum], buffer, , 0
pop ebx
pop ecx
; cmp eax, -1
; je .socketerr
cmp ecx, BUFFERSIZE
je .read_more
mcall close, [datasocketnum]
cmp [mode], MODE_PASSIVE_OK
jne @f
mov [mode], MODE_PASSIVE_WAIT
@@:
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok
ret ret
@ -542,6 +614,41 @@ dword_to_ascii: ; edi = ptr where to write, ebx is number
ret ret
align 4
create_path: ; combine home_dir and work_dir strings into fpath
mov edi, fpath
mov esi, home_dir
mov ecx, 1024
.loop1:
lodsb
or al, al
jz .next
stosb
loop .loop1
.next:
cmp byte[edi-1], '/'
jne @f
dec edi
@@:
mov esi, work_dir
mov ecx, 1024
.loop2:
lodsb
or al, al
jz .done
stosb
loop .loop2
.done:
stosb
ret
@ -563,10 +670,7 @@ str226 db '226 Transfer OK, Closing connection', 13, 10
str230 db '230 You are now logged in.', 13, 10 str230 db '230 You are now logged in.', 13, 10
.length = $ - str230 .length = $ - str230
str250 db '250 command successful', 13, 10 str250 db '250 command successful', 13, 10
;str257 db '257 "' .length = $ - str250
;.length = $ - str257
;str257b db '"', 13, 10
;.length = $ - str257b
str331 db '331 Please specify the password.', 13, 10 str331 db '331 Please specify the password.', 13, 10
.length = $ - str331 .length = $ - str331
str421 db '421 Timeout!', 13, 10 str421 db '421 Timeout!', 13, 10
@ -576,3 +680,4 @@ str425 db '425 Cant open data connection.', 13, 10
str500 db '500 Unsupported command', 13, 10 str500 db '500 Unsupported command', 13, 10
.length = $ - str500 .length = $ - str500
str550 db '550 No such file', 13, 10 str550 db '550 No such file', 13, 10
.length = $ - str550

View File

@ -157,10 +157,8 @@ start:
pushd 0x0a pushd 0x0a
call [con_set_flags] call [con_set_flags]
push buffer push buffer
call [con_write_asciiz] call [con_write_asciiz]
pushd 0x07 pushd 0x07
call [con_set_flags] call [con_set_flags]
@ -298,7 +296,10 @@ socketnum dd ?
socketnum2 dd ? socketnum2 dd ?
state dd ? state dd ?
home_dir db '/rd/1/', 0 home_dir db '/rd/1/', 0
rb 1024
work_dir rb 1024 work_dir rb 1024
fpath rb 2048
type db ? type db ?
mode db ? ; active/passive mode db ? ; active/passive

View File

@ -2,53 +2,79 @@
; Macroinstructions for defining data structures ; Macroinstructions for defining data structures
macro struct name macro struct name
{ fields@struct equ name { virtual at 0
fields@struct equ name
match child parent, name \{ fields@struct equ child,fields@\#parent \} match child parent, name \{ fields@struct equ child,fields@\#parent \}
sub@struct equ sub@struct equ
struc db [val] \{ \common fields@struct equ fields@struct,.,db,<val> \} struc db [val] \{ \common define field@struct .,db,<val>
struc dw [val] \{ \common fields@struct equ fields@struct,.,dw,<val> \} fields@struct equ fields@struct,field@struct \}
struc du [val] \{ \common fields@struct equ fields@struct,.,du,<val> \} struc dw [val] \{ \common define field@struct .,dw,<val>
struc dd [val] \{ \common fields@struct equ fields@struct,.,dd,<val> \} fields@struct equ fields@struct,field@struct \}
struc dp [val] \{ \common fields@struct equ fields@struct,.,dp,<val> \} struc du [val] \{ \common define field@struct .,du,<val>
struc dq [val] \{ \common fields@struct equ fields@struct,.,dq,<val> \} fields@struct equ fields@struct,field@struct \}
struc dt [val] \{ \common fields@struct equ fields@struct,.,dt,<val> \} struc dd [val] \{ \common define field@struct .,dd,<val>
struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} fields@struct equ fields@struct,field@struct \}
struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} struc dp [val] \{ \common define field@struct .,dp,<val>
struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} fields@struct equ fields@struct,field@struct \}
struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} struc dq [val] \{ \common define field@struct .,dq,<val>
struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} fields@struct equ fields@struct,field@struct \}
struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} struc dt [val] \{ \common define field@struct .,dt,<val>
fields@struct equ fields@struct,field@struct \}
struc rb count \{ define field@struct .,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rw count \{ define field@struct .,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rd count \{ define field@struct .,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rp count \{ define field@struct .,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rq count \{ define field@struct .,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rt count \{ define field@struct .,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro db [val] \{ \common \local anonymous macro db [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,db,<val> \} define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
macro dw [val] \{ \common \local anonymous macro dw [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,dw,<val> \} define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
macro du [val] \{ \common \local anonymous macro du [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,du,<val> \} define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
macro dd [val] \{ \common \local anonymous macro dd [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,dd,<val> \} define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
macro dp [val] \{ \common \local anonymous macro dp [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,dp,<val> \} define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
macro dq [val] \{ \common \local anonymous macro dq [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,dq,<val> \} define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
macro dt [val] \{ \common \local anonymous macro dt [val] \{ \common \local anonymous
fields@struct equ fields@struct,anonymous,dt,<val> \} define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
macro rb count \{ \local anonymous macro rb count \{ \local anonymous
fields@struct equ fields@struct,anonymous,db,count dup (?) \} define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rw count \{ \local anonymous macro rw count \{ \local anonymous
fields@struct equ fields@struct,anonymous,dw,count dup (?) \} define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rd count \{ \local anonymous macro rd count \{ \local anonymous
fields@struct equ fields@struct,anonymous,dd,count dup (?) \} define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rp count \{ \local anonymous macro rp count \{ \local anonymous
fields@struct equ fields@struct,anonymous,dp,count dup (?) \} define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rq count \{ \local anonymous macro rq count \{ \local anonymous
fields@struct equ fields@struct,anonymous,dq,count dup (?) \} define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rt count \{ \local anonymous macro rt count \{ \local anonymous
fields@struct equ fields@struct,anonymous,dt,count dup (?) \} define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro union \{ fields@struct equ fields@struct,,union,< macro union \{ fields@struct equ fields@struct,,union,<
sub@struct equ union \} sub@struct equ union \}
macro struct \{ fields@struct equ fields@struct,,substruct,< macro struct \{ fields@struct equ fields@struct,,substruct,<
sub@struct equ substruct \} sub@struct equ substruct \} }
virtual at 0 }
macro ends macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
@ -56,19 +82,19 @@ macro ends
purge db,dw,du,dd,dp,dq,dt purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt purge rb,rw,rd,rp,rq,rt
purge union,struct purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields make@struct name,fields
fields@\\#name equ fields \\} define fields@\\#name fields \\}
end virtual \} end virtual \}
match any, sub@struct \{ fields@struct equ fields@struct> \} match any, sub@struct \{ fields@struct equ fields@struct> \}
restore sub@struct } restore sub@struct }
macro make@struct name,[field,type,def] macro make@struct name,[field,type,def]
{ common { common
if $
display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah
err
end if
local define local define
define equ name define equ name
forward forward
@ -81,6 +107,14 @@ macro make@struct name,[field,type,def]
macro define@struct name,[field,type,def] macro define@struct name,[field,type,def]
{ common { common
virtual
db `name
load initial@struct byte from 0
if initial@struct = '.'
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
err
end if
end virtual
local list local list
list equ list equ
forward forward
@ -88,6 +122,7 @@ macro define@struct name,[field,type,def]
name#field type def name#field type def
sizeof.#name#field = $ - name#field sizeof.#name#field = $ - name#field
else else
label name#.#type
rb sizeof.#type rb sizeof.#type
end if end if
local value local value
@ -97,15 +132,29 @@ macro define@struct name,[field,type,def]
sizeof.#name = $ sizeof.#name = $
restruc name restruc name
match values, list \{ match values, list \{
struc name value \\{ struc name value \\{ \\local \\..base
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\} match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
match , fields@struct \\\{ label . match , fields@struct \\\{ label \\..base
forward forward
match , value \\\\{ field type def \\\\} match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value match any, value \\\\{ field type value
if ~ field eq . if ~ field eq .
rb sizeof.#name#field - ($-field) rb sizeof.#name#field - ($-field)
end if \\\\} end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match any, fields@struct \\\{ \\\local anonymous
fields@struct equ fields@struct,anonymous,name,<values> \\\}
match , fields@struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} } common \\\} \\} \} }
macro enable@substruct macro enable@substruct
@ -116,7 +165,7 @@ macro enable@substruct
\forward \forward
\local sub \local sub
match , field \\{ match any, type \\\{ enable@substruct match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,name,sub def make@substruct type,parent,sub def
purge make@substruct purge make@substruct
define equ define,.,sub, \\\} \\} define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\} match any, field \\{ define equ define,.\#field,type,<def> \\}
@ -127,21 +176,28 @@ enable@substruct
macro define@union parent,name,[field,type,def] macro define@union parent,name,[field,type,def]
{ common { common
virtual at 0 virtual at parent#.#name
forward forward
if ~ field eq . if ~ field eq .
virtual at 0 virtual at parent#.#name
parent#field type def parent#field type def
sizeof.#parent#field = $ - parent#field sizeof.#parent#field = $ - parent#field
end virtual end virtual
if sizeof.#parent#field > $ if sizeof.#parent#field > $ - parent#.#name
rb sizeof.#parent#field - $ rb sizeof.#parent#field - ($ - parent#.#name)
end if
else
virtual at parent#.#name
label parent#.#type
type def
end virtual
label name#.#type at parent#.#name
if sizeof.#type > $ - parent#.#name
rb sizeof.#type - ($ - parent#.#name)
end if end if
else if sizeof.#type > $
rb sizeof.#type - $
end if end if
common common
sizeof.#name = $ sizeof.#name = $ - parent#.#name
end virtual end virtual
struc name [value] \{ \common struc name [value] \{ \common
label .\#name label .\#name
@ -153,21 +209,23 @@ macro define@union parent,name,[field,type,def]
match , last@union \\{ match , value \\\{ field type def \\\} match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\} match any, value \\\{ field type value \\\} \\}
last@union equ field last@union equ field
common rb sizeof.#name - ($ - .\#name) \} } common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
macro define@substruct parent,name,[field,type,def] macro define@substruct parent,name,[field,type,def]
{ common { common
virtual at 0 virtual at parent#.#name
forward forward
if ~ field eq . if ~ field eq .
parent#field type def parent#field type def
sizeof.#parent#field = $ - parent#field sizeof.#parent#field = $ - parent#field
else else
label parent#.#type
rb sizeof.#type rb sizeof.#type
end if end if
local value
common common
sizeof.#name = $ sizeof.#name = $ - parent#.#name
end virtual end virtual
struc name value \{ struc name value \{
label .\#name label .\#name
@ -177,4 +235,6 @@ macro define@substruct parent,name,[field,type,def]
if ~ field eq . if ~ field eq .
rb sizeof.#parent#field - ($-field) rb sizeof.#parent#field - ($-field)
end if \\} end if \\}
common \} } common \}
macro name value \{ \local ..anonymous
..anonymous name \} }