Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2554 hidnplayr 1
;
2
; Kolibrios FTP Daemon
3
;
4
; hidnplayr@gmail.com
5
;
6
; GPLv2
7
;
8
 
2571 hidnplayr 9
BUFFERSIZE              = 8192
2554 hidnplayr 10
 
2557 hidnplayr 11
STATE_DISCONNECTED      = 0
12
STATE_CONNECTED         = 1
13
STATE_LOGIN             = 2
14
STATE_ACTIVE            = 3
2554 hidnplayr 15
 
2560 hidnplayr 16
TYPE_UNDEF              = 0
2557 hidnplayr 17
 
2560 hidnplayr 18
TYPE_ASCII              = 00000100b
19
TYPE_EBDIC              = 00001000b
20
; subtypes for ascii & ebdic (np = default)
21
TYPE_NP                 = 00000001b     ; non printable
22
TYPE_TELNET             = 00000010b
23
TYPE_ASA                = 00000011b
24
 
25
TYPE_IMAGE              = 01000000b     ; binary data
26
TYPE_LOCAL              = 10000000b     ; bits per byte must be specified
27
                                        ; lower 4 bits will hold this value
28
 
29
MODE_NOTREADY           = 0
30
MODE_ACTIVE             = 1
2562 hidnplayr 31
MODE_PASSIVE_WAIT       = 2
32
MODE_PASSIVE_OK         = 3
2560 hidnplayr 33
 
2554 hidnplayr 34
use32
35
        db      'MENUET01'      ; signature
36
        dd      1               ; header version
37
        dd      start           ; entry point
38
        dd      i_end           ; initialized size
39
        dd      mem+0x1000      ; required memory
40
        dd      mem+0x1000      ; stack pointer
2578 hidnplayr 41
        dd      params          ; parameters
2554 hidnplayr 42
        dd      path            ; path
43
 
44
include '../macros.inc'
45
purge mov,add,sub
46
include '../proc32.inc'
47
include '../dll.inc'
2562 hidnplayr 48
include '../struct.inc'
49
include '../libio.inc'
2554 hidnplayr 50
 
51
include '../network.inc'
52
include 'commands.inc'
53
 
54
align 4
55
start:
56
; load libraries
57
        stdcall dll.Load, @IMPORT
58
        test    eax, eax
59
        jnz     exit
60
 
2578 hidnplayr 61
        mcall   68, 11                  ; init heap
62
 
2554 hidnplayr 63
; find path to main settings file
2578 hidnplayr 64
        mov     edi, path               ; Calculate the length of zero-terminated string
2554 hidnplayr 65
        xor     al , al
66
        mov     ecx, 1024
67
        repne   scasb
68
        dec     edi
2578 hidnplayr 69
        mov     esi, filename           ; append it with '.ini'
2554 hidnplayr 70
        movsd
71
        movsb
72
 
73
; initialize console
74
        push    1
75
        call    [con_start]
2560 hidnplayr 76
 
2554 hidnplayr 77
        push    title
2560 hidnplayr 78
        push    -1
79
        push    -1
80
        push    -1
81
        push    -1
2554 hidnplayr 82
        call    [con_init]
83
 
2578 hidnplayr 84
        mcall   40, 1 shl 7             ; we only want network events
2554 hidnplayr 85
 
2560 hidnplayr 86
        invoke  ini.get_int, path, str_ftpd, str_port, 21
87
        mov     [sockaddr1.port], ax
88
 
89
        push    eax
2554 hidnplayr 90
        push    str1
2560 hidnplayr 91
        call    [con_printf]
2554 hidnplayr 92
 
93
        mcall   socket, AF_INET4, SOCK_STREAM, 0
94
        cmp     eax, -1
95
        je      sock_err
96
 
97
        mov     [socketnum], eax
98
 
2560 hidnplayr 99
        push    str2
100
        call    [con_write_asciiz]
101
 
2554 hidnplayr 102
;;        mcall   setsockopt, [socketnum], SOL_SOCKET, SO_REUSEADDR, &yes,
103
;;        cmp     eax, -1
104
;;        je      opt_err
105
 
106
        mcall   bind, [socketnum], sockaddr1, sockaddr1.length
107
        cmp     eax, -1
108
        je      bind_err
109
 
2560 hidnplayr 110
        push    str2
111
        call    [con_write_asciiz]
112
 
2554 hidnplayr 113
        invoke  ini.get_int, path, str_ftpd, str_conn, 1        ; Backlog (max connections)
114
        mov     edx, eax
2560 hidnplayr 115
 
116
        push    str2
117
        call    [con_write_asciiz]
118
 
2554 hidnplayr 119
        mcall   listen, [socketnum]
120
        cmp     eax, -1
121
        je      listen_err
122
 
2560 hidnplayr 123
        push    str2b
2554 hidnplayr 124
        call    [con_write_asciiz]
125
 
2578 hidnplayr 126
mainloop:
127
        mcall   10                              ; Wait here for incoming connections on the base socket (socketnum)
2554 hidnplayr 128
 
2578 hidnplayr 129
        mcall   51, 1, threadstart, 0           ; Start a new thread for every incoming connection
130
                                                ; NOTE: upon initialisation of the thread, stack will not be available!
131
        jmp     mainloop
132
 
133
threadstart:
134
        mcall   68, 12, sizeof.thread_data      ; allocate the thread data struct
2554 hidnplayr 135
        cmp     eax, -1
2578 hidnplayr 136
        je      exit
2554 hidnplayr 137
 
2578 hidnplayr 138
        lea     esp, [eax + thread_data.stack]  ; init stack
139
        push    eax                             ; save pointer to thread_data on stack
2554 hidnplayr 140
 
2578 hidnplayr 141
        mcall   40, 1 shl 7                     ; we only want network events for this thread
2554 hidnplayr 142
 
2578 hidnplayr 143
        push    str8
144
        call    [con_write_asciiz]                                              ; print on the console that we have created the new thread successfully
145
 
146
        mcall   accept, [socketnum], sockaddr1, sockaddr1.length                ; time to accept the awaiting connection..
147
        cmp     eax, -1
148
        je      thread_exit
149
        mov     edx, [esp]                                                      ; pointer to thread_data
150
        mov     [edx + thread_data.socketnum], eax
151
 
152
        mcall   send, [edx + thread_data.socketnum], str220, str220.length, 0   ; send welcome string to the FTP client
153
 
154
threadloop:
2554 hidnplayr 155
        mcall   10
156
 
2578 hidnplayr 157
        mov     edx, [esp]                                                      ; pointer to thread_data
158
 
159
        cmp     [edx + thread_data.mode], MODE_PASSIVE_WAIT
2562 hidnplayr 160
        jne     @f
2578 hidnplayr 161
        mov     ecx, [edx + thread_data.passivesocknum]
162
        lea     edx, [edx + thread_data.datasock]
163
        mov     esi, sizeof.thread_data.datasock
164
        mcall   accept
165
        mov     edx, [esp]                                                      ; pointer to thread_data
2562 hidnplayr 166
        cmp     eax, -1
167
        je      @f
2578 hidnplayr 168
        mov     [edx + thread_data.datasocketnum], eax
169
        mov     [edx + thread_data.mode], MODE_PASSIVE_OK
2562 hidnplayr 170
 
171
        push    str_datasock
2578 hidnplayr 172
        call    [con_write_asciiz]                                              ; print on the console that the datasock is now ready
2562 hidnplayr 173
       @@:
174
 
2578 hidnplayr 175
        mov     ecx, [edx + thread_data.socketnum]
176
        lea     edx, [edx + thread_data.buffer]
177
        mov     esi, sizeof.thread_data.buffer
178
        mcall   recv
179
        cmp     eax, -1                                                         ; error?
180
        je      threadloop
181
        or      eax, eax                                                        ; 0 bytes read?
182
        jz      threadloop
183
        push    eax                                                             ; save number of bytes read on stack
2554 hidnplayr 184
 
2578 hidnplayr 185
        mov     edx, [esp+4]                                                    ; pointer to thread_data
186
        mov     byte [edx + thread_data.buffer + eax], 0                        ; append received data with a 0 byte
2560 hidnplayr 187
 
2578 hidnplayr 188
        pushd   0x0a                                                            ; print received data to console (in green color)
2560 hidnplayr 189
        call    [con_set_flags]
2578 hidnplayr 190
        lea     eax, [edx + thread_data.buffer]
191
        push    eax
2554 hidnplayr 192
        call    [con_write_asciiz]
2560 hidnplayr 193
        pushd   0x07
194
        call    [con_set_flags]
195
 
2578 hidnplayr 196
        pop     ecx                                                             ; number of bytes read
197
        lea     esi, [edx + thread_data.buffer]
2554 hidnplayr 198
        call    parse_cmd
199
 
2578 hidnplayr 200
        jmp     threadloop
2554 hidnplayr 201
 
202
listen_err:
2560 hidnplayr 203
        pushd   0x0c
204
        call    [con_set_flags]
2554 hidnplayr 205
        push    str3
206
        call    [con_write_asciiz]
207
        jmp     done
208
 
209
bind_err:
2560 hidnplayr 210
        pushd   0x0c
211
        call    [con_set_flags]
2554 hidnplayr 212
        push    str4
213
        call    [con_write_asciiz]
214
        jmp     done
215
 
216
sock_err:
2560 hidnplayr 217
        pushd   0x0c
218
        call    [con_set_flags]
2554 hidnplayr 219
        push    str6
220
        call    [con_write_asciiz]
221
        jmp     done
222
 
223
done:
224
        call    [con_getch2]
225
        push    1
226
        call    [con_exit]
227
exit:
228
        mcall   -1
229
 
230
 
2578 hidnplayr 231
thread_exit:
232
        push    str_bye
233
        call    [con_write_asciiz]      ; say bye bye
234
        pop     ecx                     ; get the thread_data pointer from stack
235
        mcall   68, 13                  ; free the memory
236
        mcall   -1                      ; and kill the thread
2554 hidnplayr 237
 
238
 
2578 hidnplayr 239
 
240
; initialized data
241
 
242
title           db 'KolibriOS FTP daemon 0.1', 0
243
str1            db 'Starting FTP daemon on port %u', 0
244
str2            db '.', 0
245
str2b           db ' OK!',10,10,0
246
str3            db 'Listen error',10,10,0
247
str4            db 'Bind error',10,10,0
248
;str5            db 'Setsockopt error.',10,10,0
249
str6            db 'Could not open socket',10,10,0
250
str7            db 'Got data!',10,10,0
251
str8            db 10,'New thread created!',10,10,0
252
str_bye         db 10,'Closing thread!',10,10,0
253
 
2562 hidnplayr 254
str_logged_in   db 'Login ok',10,10,0
255
str_pass_ok     db 'Password ok - Logged in',10,10,0
256
str_pwd         db 'Current directory is "%s"\n',0
257
str_err2        db 'ERROR: cannot open directory',10,10,0
258
str_datasock    db 'Passive data socket connected!',10,10,0
2571 hidnplayr 259
str_notfound    db 'ERROR: file not found',10,10,0
260
str_sockerr     db 'ERROR: socket error',10,10,0
2560 hidnplayr 261
 
2578 hidnplayr 262
str_newline     db 10, 0
2562 hidnplayr 263
str_mask        db '*', 0
264
 
2578 hidnplayr 265
months          dd 'Jan '
266
                dd 'Feb '
267
                dd 'Mar '
268
                dd 'Apr '
269
                dd 'May '
270
                dd 'Jun '
271
                dd 'Jul '
272
                dd 'Aug '
273
                dd 'Sep '
274
                dd 'Oct '
275
                dd 'Nov '
276
                dd 'Dec '
2562 hidnplayr 277
 
2578 hidnplayr 278
filename        db '.ini', 0
279
str_port        db 'port', 0
280
str_ftpd        db 'ftpd', 0
281
str_conn        db 'conn', 0
2562 hidnplayr 282
 
2554 hidnplayr 283
sockaddr1:
2578 hidnplayr 284
                dw AF_INET4
285
  .port         dw 21
286
  .ip           dd 0
287
                rb 10
288
  .length       = $ - sockaddr1
2554 hidnplayr 289
 
290
; import
2578 hidnplayr 291
 
2554 hidnplayr 292
align 4
293
@IMPORT:
294
 
2578 hidnplayr 295
library console,                'console.obj',\
296
        libini,                 'libini.obj', \
297
        libio,                  'libio.obj'
2554 hidnplayr 298
 
2578 hidnplayr 299
import  console,\
300
        con_start,              'START',\
301
        con_init,               'con_init',\
302
        con_write_asciiz,       'con_write_asciiz',\
303
        con_exit,               'con_exit',\
304
        con_gets,               'con_gets',\
305
        con_cls,                'con_cls',\
306
        con_printf,             'con_printf',\
307
        con_getch2,             'con_getch2',\
308
        con_set_cursor_pos,     'con_set_cursor_pos',\
309
        con_set_flags,          'con_set_flags'
2554 hidnplayr 310
 
2578 hidnplayr 311
import  libini,\
312
        ini.get_str,            'ini_get_str',\
313
        ini.get_int,            'ini_get_int'
2554 hidnplayr 314
 
2578 hidnplayr 315
import  libio,\
316
        libio.init,             'lib_init',\
317
        file.size,              'file_size',\
318
        file.open,              'file_open',\
319
        file.read,              'file_read',\
320
        file.close,             'file_close',\
321
        file.find.first,        'file_find_first',\
322
        file.find.next,         'file_find_next',\
323
        file.find.close,        'file_find_close'
2554 hidnplayr 324
 
325
 
326
i_end:
327
 
2578 hidnplayr 328
; uninitialised data
2557 hidnplayr 329
 
2578 hidnplayr 330
        socketnum       dd ?
331
        path            rb 1024
332
        params          rb 1024
2557 hidnplayr 333
 
2578 hidnplayr 334
mem:
2563 hidnplayr 335