From d277a579f2361dcd780561abd3ce35bf2d928f99 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Wed, 4 Apr 2012 17:19:00 +0000 Subject: [PATCH] Added CWD command to FTP daemon (net branch) git-svn-id: svn://kolibrios.org@2563 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../net/applications/ftpd/commands.inc | 171 +++++++++++--- .../branches/net/applications/ftpd/ftpd.asm | 7 +- kernel/branches/net/applications/struct.inc | 210 +++++++++++------- 3 files changed, 277 insertions(+), 111 deletions(-) diff --git a/kernel/branches/net/applications/ftpd/commands.inc b/kernel/branches/net/applications/ftpd/commands.inc index 92b16bb137..e88078ded5 100644 --- a/kernel/branches/net/applications/ftpd/commands.inc +++ b/kernel/branches/net/applications/ftpd/commands.inc @@ -49,7 +49,7 @@ commands: ; all commands must be in uppercase dd cmdPASS db 'PASV' dd cmdPASV - db 'PWD', 0 ; Print Working Directory + db 'PWD', 0 dd cmdPWD db 'PORT' dd cmdPORT @@ -76,7 +76,39 @@ cmdABOR: ret 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 @@ -88,6 +120,7 @@ cmdDELE: align 4 cmdLIST: +; If we are in active mode, it's time to open a data socket.. cmp [mode], MODE_ACTIVE jne @f mcall connect, [datasocketnum], datasock, datasock.length @@ -95,31 +128,30 @@ cmdLIST: je .err @@: +; Warn the client we're about to send the data 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 str_mask - push home_dir + push fpath call [file.find.first] mov edi, buffer - jmp .parse_file - - .checknextfile: - push edx - call [file.find.next] - .parse_file: - test eax, eax + test eax, eax ; did we find a file? jz .done - mov edx, eax + mov edx, eax ; yes, save the descripter ; first, convert the attributes - test [eax + FileInfoA.Attributes], FA_FOLDER + test [edx + FileInfoA.Attributes], FA_FOLDER jnz .folder - test [eax + FileInfoA.Attributes], FA_READONLY + test [edx + FileInfoA.Attributes], FA_READONLY jnz .readonly mov eax, '-rw-' @@ -128,7 +160,7 @@ cmdLIST: .folder: mov eax, 'drwx' - stosb + stosd jmp .attr .readonly: @@ -153,7 +185,7 @@ cmdLIST: stosd ; now the filesize in ascii - mov ebx, dword [edx + FileInfoA.FileSize] + mov ebx, [edx + FileInfoA.FileSizeLow] call dword_to_ascii mov al, ' ' @@ -186,24 +218,34 @@ cmdLIST: stosb loop .nameloop +; insert a cr lf .namedone: mov ax, 0x0d0a stosw - jmp .checknextfile +; check next file + push edx + call [file.find.next] + jmp .parse_file + +; close file desc .done: push edx call [file.find.close] +; append the string with a 0 xor al, al stosb +; print everything on the console push buffer call [con_write_asciiz] +; and send it to the client lea esi, [edi - buffer] mcall send, [datasocketnum], buffer, , 0 +; close the data socket.. mcall close, [datasocketnum] cmp [mode], MODE_PASSIVE_OK @@ -211,7 +253,8 @@ cmdLIST: 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 @@ -296,7 +339,7 @@ cmdPASV: ret align 4 -cmdPWD: +cmdPWD: ; Print Working Directory mov dword[buffer], '257 ' mov byte[buffer+4], '"' @@ -383,22 +426,51 @@ cmdQUIT: align 4 cmdRETR: -; mcall connect, [datasocketnum], datasock, datasock.length + cmp [mode], MODE_ACTIVE + jne @f + mcall connect, [datasocketnum], datasock, datasock.length ; cmp eax, -1 ; je .err + @@: -; push O_READ -; push home_dir -; call [file.open] + mcall send, [socketnum2], str150, str150.length, 0 ; here it comes.. + + push O_READ + push home_dir + call [file.open] ; test eax, eax ; jz .cannot_open -; -; push BUFFERSIZE -; push buffer -; push eax -; call [file.read] + + mov ebx, eax + + .read_more: + push BUFFERSIZE + push buffer + push ebx + call [file.read] ; 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 @@ -542,6 +614,41 @@ dword_to_ascii: ; edi = ptr where to write, ebx is number 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 .length = $ - str230 str250 db '250 command successful', 13, 10 -;str257 db '257 "' -;.length = $ - str257 -;str257b db '"', 13, 10 -;.length = $ - str257b +.length = $ - str250 str331 db '331 Please specify the password.', 13, 10 .length = $ - str331 str421 db '421 Timeout!', 13, 10 @@ -575,4 +679,5 @@ str425 db '425 Cant open data connection.', 13, 10 .length = $ - str425 str500 db '500 Unsupported command', 13, 10 .length = $ - str500 -str550 db '550 No such file', 13, 10 \ No newline at end of file +str550 db '550 No such file', 13, 10 +.length = $ - str550 \ No newline at end of file diff --git a/kernel/branches/net/applications/ftpd/ftpd.asm b/kernel/branches/net/applications/ftpd/ftpd.asm index c01eeaeec0..b9a7394fa5 100644 --- a/kernel/branches/net/applications/ftpd/ftpd.asm +++ b/kernel/branches/net/applications/ftpd/ftpd.asm @@ -157,10 +157,8 @@ start: pushd 0x0a call [con_set_flags] - push buffer call [con_write_asciiz] - pushd 0x07 call [con_set_flags] @@ -297,8 +295,11 @@ socketnum dd ? ; thread specific data socketnum2 dd ? state dd ? -home_dir db '/rd/1/',0 +home_dir db '/rd/1/', 0 + rb 1024 work_dir rb 1024 +fpath rb 2048 + type db ? mode db ? ; active/passive diff --git a/kernel/branches/net/applications/struct.inc b/kernel/branches/net/applications/struct.inc index 947a84e89a..37f0b65b72 100644 --- a/kernel/branches/net/applications/struct.inc +++ b/kernel/branches/net/applications/struct.inc @@ -2,85 +2,119 @@ ; Macroinstructions for defining data structures macro struct name - { fields@struct equ name + { virtual at 0 + fields@struct equ name match child parent, name \{ fields@struct equ child,fields@\#parent \} sub@struct equ - struc db [val] \{ \common fields@struct equ fields@struct,.,db, \} - struc dw [val] \{ \common fields@struct equ fields@struct,.,dw, \} - struc du [val] \{ \common fields@struct equ fields@struct,.,du, \} - struc dd [val] \{ \common fields@struct equ fields@struct,.,dd, \} - struc dp [val] \{ \common fields@struct equ fields@struct,.,dp, \} - struc dq [val] \{ \common fields@struct equ fields@struct,.,dq, \} - struc dt [val] \{ \common fields@struct equ fields@struct,.,dt, \} - struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} - struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} - struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} - struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} - struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} - struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} + struc db [val] \{ \common define field@struct .,db, + fields@struct equ fields@struct,field@struct \} + struc dw [val] \{ \common define field@struct .,dw, + fields@struct equ fields@struct,field@struct \} + struc du [val] \{ \common define field@struct .,du, + fields@struct equ fields@struct,field@struct \} + struc dd [val] \{ \common define field@struct .,dd, + fields@struct equ fields@struct,field@struct \} + struc dp [val] \{ \common define field@struct .,dp, + fields@struct equ fields@struct,field@struct \} + struc dq [val] \{ \common define field@struct .,dq, + fields@struct equ fields@struct,field@struct \} + struc dt [val] \{ \common define field@struct .,dt, + 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 - fields@struct equ fields@struct,anonymous,db, \} + define field@struct anonymous,db, + fields@struct equ fields@struct,field@struct \} macro dw [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,dw, \} + define field@struct anonymous,dw, + fields@struct equ fields@struct,field@struct \} macro du [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,du, \} + define field@struct anonymous,du, + fields@struct equ fields@struct,field@struct \} macro dd [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,dd, \} + define field@struct anonymous,dd, + fields@struct equ fields@struct,field@struct \} macro dp [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,dp, \} + define field@struct anonymous,dp, + fields@struct equ fields@struct,field@struct \} macro dq [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,dq, \} + define field@struct anonymous,dq, + fields@struct equ fields@struct,field@struct \} macro dt [val] \{ \common \local anonymous - fields@struct equ fields@struct,anonymous,dt, \} + define field@struct anonymous,dt, + fields@struct equ fields@struct,field@struct \} 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 - 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 - 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 - 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 - 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 - 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,< - sub@struct equ union \} + sub@struct equ union \} macro struct \{ fields@struct equ fields@struct,,substruct,< - sub@struct equ substruct \} - virtual at 0 } + sub@struct equ substruct \} } macro ends { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt - restruc rb,rw,rd,rp,rq,rt - purge db,dw,du,dd,dp,dq,dt - purge rb,rw,rd,rp,rq,rt - purge union,struct - match name=,fields,fields@struct \\{ fields@struct equ - make@struct name,fields - fields@\\#name equ fields \\} - end virtual \} + restruc rb,rw,rd,rp,rq,rt + purge db,dw,du,dd,dp,dq,dt + purge rb,rw,rd,rp,rq,rt + 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 + make@struct name,fields + define fields@\\#name fields \\} + end virtual \} match any, sub@struct \{ fields@struct equ fields@struct> \} restore sub@struct } macro make@struct name,[field,type,def] { common - if $ - display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah - err - end if local define define equ name forward local sub match , field \{ make@substruct type,name,sub def - define equ define,.,sub, \} + define equ define,.,sub, \} match any, field \{ define equ define,.#field,type, \} common match fields, define \{ define@struct fields \} } macro define@struct name,[field,type,def] { 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 list equ forward @@ -88,6 +122,7 @@ macro define@struct name,[field,type,def] name#field type def sizeof.#name#field = $ - name#field else + label name#.#type rb sizeof.#type end if local value @@ -97,84 +132,109 @@ macro define@struct name,[field,type,def] sizeof.#name = $ restruc name match values, list \{ - struc name value \\{ + struc name value \\{ \\local \\..base match any, fields@struct \\\{ fields@struct equ fields@struct,.,name, \\\} - match , fields@struct \\\{ label . + match , fields@struct \\\{ label \\..base forward match , value \\\\{ field type def \\\\} match any, value \\\\{ field type value - if ~ field eq . - rb sizeof.#name#field - ($-field) - end if \\\\} + if ~ field eq . + rb sizeof.#name#field - ($-field) + end if \\\\} + common label . at \\..base \\\} + \\} + macro name value \\{ + match any, fields@struct \\\{ \\\local anonymous + fields@struct equ fields@struct,anonymous,name, \\\} + 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 \\\} \\} \} } macro enable@substruct { macro make@substruct substruct,parent,name,[field,type,def] \{ \common - \local define - define equ parent,name + \local define + define equ parent,name \forward - \local sub - match , field \\{ match any, type \\\{ enable@substruct - make@substruct type,name,sub def - purge make@substruct - define equ define,.,sub, \\\} \\} - match any, field \\{ define equ define,.\#field,type, \\} + \local sub + match , field \\{ match any, type \\\{ enable@substruct + make@substruct type,parent,sub def + purge make@substruct + define equ define,.,sub, \\\} \\} + match any, field \\{ define equ define,.\#field,type, \\} \common - match fields, define \\{ define@\#substruct fields \\} \} } + match fields, define \\{ define@\#substruct fields \\} \} } enable@substruct macro define@union parent,name,[field,type,def] { common - virtual at 0 + virtual at parent#.#name forward if ~ field eq . - virtual at 0 + virtual at parent#.#name parent#field type def sizeof.#parent#field = $ - parent#field end virtual - if sizeof.#parent#field > $ - rb sizeof.#parent#field - $ + if sizeof.#parent#field > $ - parent#.#name + 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 - else if sizeof.#type > $ - rb sizeof.#type - $ end if common - sizeof.#name = $ + sizeof.#name = $ - parent#.#name end virtual struc name [value] \{ \common label .\#name last@union equ forward match any, last@union \\{ virtual at .\#name - field type def - end virtual \\} + field type def + end virtual \\} match , last@union \\{ match , value \\\{ field type def \\\} - match any, value \\\{ field type value \\\} \\} + match any, value \\\{ field type value \\\} \\} 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] { common - virtual at 0 + virtual at parent#.#name forward if ~ field eq . parent#field type def sizeof.#parent#field = $ - parent#field else + label parent#.#type rb sizeof.#type end if - local value common - sizeof.#name = $ + sizeof.#name = $ - parent#.#name end virtual struc name value \{ label .\#name forward match , value \\{ field type def \\} match any, value \\{ field type value - if ~ field eq . - rb sizeof.#parent#field - ($-field) - end if \\} - common \} } + if ~ field eq . + rb sizeof.#parent#field - ($-field) + end if \\} + common \} + macro name value \{ \local ..anonymous + ..anonymous name \} }