Subversion Repositories Kolibri OS

Rev

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