Subversion Repositories Kolibri OS

Rev

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

Rev 2892 Rev 2995
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2012. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2012. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  ftpd.asm - FTP Daemon for KolibriOS                            ;;
6
;;  ftpd.asm - FTP Daemon for KolibriOS                            ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
14
 
15
DEBUG                   = 0             ; if set to one, program will run in a single thread
15
DEBUG                   = 0             ; if set to one, program will run in a single thread
16
 
16
 
17
BUFFERSIZE              = 8192
17
BUFFERSIZE              = 8192
18
 
18
 
19
; using multiple's of 4
19
; using multiple's of 4
20
STATE_CONNECTED         = 0*4
20
STATE_CONNECTED         = 0*4
21
STATE_LOGIN             = 1*4
21
STATE_LOGIN             = 1*4
22
STATE_LOGIN_FAIL        = 2*4           ; When an invalid username was given
22
STATE_LOGIN_FAIL        = 2*4           ; When an invalid username was given
23
STATE_ACTIVE            = 3*4
23
STATE_ACTIVE            = 3*4
24
 
24
 
25
TYPE_UNDEF              = 0
25
TYPE_UNDEF              = 0
26
 
26
 
27
TYPE_ASCII              = 00000100b
27
TYPE_ASCII              = 00000100b
28
TYPE_EBDIC              = 00001000b
28
TYPE_EBDIC              = 00001000b
29
; subtypes for ascii & ebdic (np = default)
29
; subtypes for ascii & ebdic (np = default)
30
TYPE_NP                 = 00000001b     ; non printable
30
TYPE_NP                 = 00000001b     ; non printable
31
TYPE_TELNET             = 00000010b
31
TYPE_TELNET             = 00000010b
32
TYPE_ASA                = 00000011b
32
TYPE_ASA                = 00000011b
33
 
33
 
34
TYPE_IMAGE              = 01000000b     ; binary data
34
TYPE_IMAGE              = 01000000b     ; binary data
35
TYPE_LOCAL              = 10000000b     ; bits per byte must be specified
35
TYPE_LOCAL              = 10000000b     ; bits per byte must be specified
36
                                        ; lower 4 bits will hold this value
36
                                        ; lower 4 bits will hold this value
37
MODE_NOTREADY           = 0
37
MODE_NOTREADY           = 0
38
MODE_ACTIVE             = 1
38
MODE_ACTIVE             = 1
39
MODE_PASSIVE_WAIT       = 2
39
MODE_PASSIVE_WAIT       = 2
40
MODE_PASSIVE_OK         = 3
40
MODE_PASSIVE_OK         = 3
41
MODE_PASSIVE_FAILED     = 4
41
MODE_PASSIVE_FAILED     = 4
42
 
42
 
43
PERMISSION_EXEC         = 1b            ; LIST
43
PERMISSION_EXEC         = 1b            ; LIST
44
PERMISSION_READ         = 10b
44
PERMISSION_READ         = 10b
45
PERMISSION_WRITE        = 100b
45
PERMISSION_WRITE        = 100b
46
PERMISSION_DELETE       = 1000b
46
PERMISSION_DELETE       = 1000b
47
PERMISSION_CD           = 10000b        ; Change Directory
47
PERMISSION_CD           = 10000b        ; Change Directory
48
 
48
 
49
ABORT                   = 1 shl 31
49
ABORT                   = 1 shl 31
50
 
50
 
51
format binary as ""
51
format binary as ""
52
 
52
 
53
use32
53
use32
54
        db      'MENUET01'      ; signature
54
        db      'MENUET01'      ; signature
55
        dd      1               ; header version
55
        dd      1               ; header version
56
        dd      start           ; entry point
56
        dd      start           ; entry point
57
        dd      i_end           ; initialized size
57
        dd      i_end           ; initialized size
58
        dd      mem+0x1000      ; required memory
58
        dd      mem+0x1000      ; required memory
59
        dd      mem+0x1000      ; stack pointer
59
        dd      mem+0x1000      ; stack pointer
60
        dd      params          ; parameters
60
        dd      params          ; parameters
61
        dd      path            ; path
61
        dd      path            ; path
62
 
62
 
63
include '../macros.inc'
63
include '../macros.inc'
64
purge mov,add,sub
64
purge mov,add,sub
65
include '../proc32.inc'
65
include '../proc32.inc'
66
include '../dll.inc'
66
include '../dll.inc'
67
include '../struct.inc'
67
include '../struct.inc'
68
include '../libio.inc'
68
include '../libio.inc'
69
 
69
 
70
include '../network.inc'
70
include '../network.inc'
71
 
71
 
72
macro sendFTP str {
72
macro sendFTP str {
73
local string, length
73
local string, length
74
        xor     edi, edi
74
        xor     edi, edi
75
        mcall   send, [ebp + thread_data.socketnum], string, length
75
        mcall   send, [ebp + thread_data.socketnum], string, length
76
 
76
 
77
iglobal
77
iglobal
78
string db str, 13, 10
78
string db str, 13, 10
79
length = $ - string
79
length = $ - string
80
\}
80
\}
81
}
81
}
82
 
82
 
83
include 'commands.inc'
83
include 'commands.inc'
84
 
84
 
85
start:
85
start:
86
        mcall   68, 11                  ; init heap
86
        mcall   68, 11                  ; init heap
87
        mcall   40, 1 shl 7             ; we only want network events
87
        mcall   40, 1 shl 7             ; we only want network events
88
 
88
 
89
; load libraries
89
; load libraries
90
        stdcall dll.Load, @IMPORT
90
        stdcall dll.Load, @IMPORT
91
        test    eax, eax
91
        test    eax, eax
92
        jnz     exit
92
        jnz     exit
93
 
93
 
94
; find path to main settings file (ftpd.ini)
94
; find path to main settings file (ftpd.ini)
95
        mov     edi, path               ; Calculate the length of zero-terminated string
95
        mov     edi, path               ; Calculate the length of zero-terminated string
96
        xor     al, al
96
        xor     al, al
97
        mov     ecx, 1024
97
        mov     ecx, 1024
98
        repne   scasb
98
        repne   scasb
99
        dec     edi
99
        dec     edi
100
        mov     esi, str_ini            ; append it with '.ini', 0
100
        mov     esi, str_ini            ; append it with '.ini', 0
101
        movsd
101
        movsd
102
        movsb
102
        movsb
103
 
103
 
104
; now create the second path (users.ini)
104
; now create the second path (users.ini)
105
        std
105
        std
106
        mov     al, '/'
106
        mov     al, '/'
107
        repne   scasb
107
        repne   scasb
108
        lea     ecx, [edi - path + 2]
108
        lea     ecx, [edi - path + 2]
109
        cld
109
        cld
110
        mov     esi, path
110
        mov     esi, path
111
        mov     edi, path2
111
        mov     edi, path2
112
        rep     movsb
112
        rep     movsb
113
        mov     esi, str_users
113
        mov     esi, str_users
114
        movsd
114
        movsd
115
        movsd
115
        movsd
116
        movsw
116
        movsw
117
 
117
 
118
; initialize console
118
; initialize console
119
        invoke  con_start, 1
119
        invoke  con_start, 1
120
        invoke  con_init, -1, -1, -1, -1, title
120
        invoke  con_init, -1, -1, -1, -1, title
121
 
121
 
122
        invoke  ini.get_str, path, str_ftpd, str_ip, ini_buf, 16, 0
122
        invoke  ini.get_str, path, str_ftpd, str_ip, ini_buf, 16, 0
123
        mov     esi, ini_buf
123
        mov     esi, ini_buf
124
        mov     cl, '.'
124
        mov     cl, '.'
125
        call    ip_to_dword
125
        call    ip_to_dword
126
        mov     [serverip], ebx
126
        mov     [serverip], ebx
127
 
127
 
128
        invoke  ini.get_int, path, str_ftpd, str_port, 21
128
        invoke  ini.get_int, path, str_ftpd, str_port, 21
-
 
129
        xchg    al, ah
129
        mov     [sockaddr1.port], ax
130
        mov     [sockaddr1.port], ax
-
 
131
 
130
 
132
        xchg    al, ah
131
        invoke  con_printf, str1, eax
133
        invoke  con_printf, str1, eax
132
        add     esp, 8
134
        add     esp, 8
133
 
135
 
134
        mcall   socket, AF_INET4, SOCK_STREAM, 0
136
        mcall   socket, AF_INET4, SOCK_STREAM, 0
135
        cmp     eax, -1
137
        cmp     eax, -1
136
        je      sock_err
138
        je      sock_err
137
        mov     [socketnum], eax
139
        mov     [socketnum], eax
138
 
140
 
139
        invoke  con_write_asciiz, str2
141
        invoke  con_write_asciiz, str2
140
 
142
 
141
;        mcall   setsockopt, [socketnum], SOL_SOCKET, SO_REUSEADDR, &yes,
143
;        mcall   setsockopt, [socketnum], SOL_SOCKET, SO_REUSEADDR, &yes,
142
;        cmp     eax, -1
144
;        cmp     eax, -1
143
;        je      opt_err
145
;        je      opt_err
144
 
146
 
145
        mcall   bind, [socketnum], sockaddr1, sockaddr1.length
147
        mcall   bind, [socketnum], sockaddr1, sockaddr1.length
146
        cmp     eax, -1
148
        cmp     eax, -1
147
        je      bind_err
149
        je      bind_err
148
 
150
 
149
        invoke  con_write_asciiz, str2
151
        invoke  con_write_asciiz, str2
150
 
152
 
151
        invoke  ini.get_int, path, str_ftpd, str_conn, 1        ; Backlog (max connections)
153
        invoke  ini.get_int, path, str_ftpd, str_conn, 1        ; Backlog (max connections)
152
        mov     edx, eax
154
        mov     edx, eax
153
 
155
 
154
        invoke  con_write_asciiz, str2
156
        invoke  con_write_asciiz, str2
155
 
157
 
156
        mcall   listen, [socketnum]
158
        mcall   listen, [socketnum]
157
        cmp     eax, -1
159
        cmp     eax, -1
158
        je      listen_err
160
        je      listen_err
159
 
161
 
160
        invoke  con_write_asciiz, str2b
162
        invoke  con_write_asciiz, str2b
161
 
163
 
162
        invoke  ini.get_int, path, str_pasv, str_start, 2000
164
        invoke  ini.get_int, path, str_pasv, str_start, 2000
163
        mov     [pasv_start], ax
165
        mov     [pasv_start], ax
164
        invoke  ini.get_int, path, str_pasv, str_end, 5000
166
        invoke  ini.get_int, path, str_pasv, str_end, 5000
165
        mov     [pasv_end], ax
167
        mov     [pasv_end], ax
166
 
168
 
167
        mov     [alive], 1
169
        mov     [alive], 1
168
 
170
 
169
mainloop:
171
mainloop:
170
        mcall   23, 100                         ; Wait here for incoming connections on the base socket (socketnum)
172
        mcall   23, 100                         ; Wait here for incoming connections on the base socket (socketnum)
171
                                                ; One second timeout, we will use this to check if console is still working
173
                                                ; One second timeout, we will use this to check if console is still working
172
 
174
 
173
        test    eax, eax                        ; network event?
175
        test    eax, eax                        ; network event?
174
        jz      .checkconsole
176
        jz      .checkconsole
175
 
177
 
176
if DEBUG
178
if DEBUG
177
        jmp     threadstart
179
        jmp     threadstart
178
else
180
else
179
        mcall   51, 1, threadstart, 0           ; Start a new thread for every incoming connection
181
        mcall   51, 1, threadstart, 0           ; Start a new thread for every incoming connection
180
                                                ; NOTE: upon initialisation of the thread, stack will not be available!
182
                                                ; NOTE: upon initialisation of the thread, stack will not be available!
181
end if
183
end if
182
        jmp     mainloop
184
        jmp     mainloop
183
 
185
 
184
  .checkconsole:
186
  .checkconsole:
185
 
187
 
186
        invoke  con_get_flags                   ; Is console still running?
188
        invoke  con_get_flags                   ; Is console still running?
187
        test    eax, 0x0200
189
        test    eax, 0x0200
188
        jz      mainloop
190
        jz      mainloop
189
        mcall   close, [socketnum]              ; kill the listening socket
191
        mcall   close, [socketnum]              ; kill the listening socket
190
        mov     [alive], 0
192
        mov     [alive], 0
191
        mcall   -1                              ; and exit
193
        mcall   -1                              ; and exit
192
 
194
 
193
        diff16  "threadstart", 0, $
195
        diff16  "threadstart", 0, $
194
 
196
 
195
threadstart:
197
threadstart:
196
;;;        mcall   68, 11                          ; init heap
198
;;;        mcall   68, 11                          ; init heap
197
        mcall   68, 12, sizeof.thread_data      ; allocate the thread data struct
199
        mcall   68, 12, sizeof.thread_data      ; allocate the thread data struct
198
        test    eax, eax
200
        test    eax, eax
199
        je      exit
201
        je      exit
200
 
202
 
201
        lea     esp, [eax + thread_data.stack]  ; init stack
203
        lea     esp, [eax + thread_data.stack]  ; init stack
202
        mov     ebp, eax
204
        mov     ebp, eax
203
 
205
 
204
        mcall   40, 1 shl 7                     ; we only want network events for this thread
206
        mcall   40, 1 shl 7                     ; we only want network events for this thread
205
 
207
 
206
        lea     ebx, [ebp + thread_data.buffer] ; get information about the current process
208
        lea     ebx, [ebp + thread_data.buffer] ; get information about the current process
207
        or      ecx, -1
209
        or      ecx, -1
208
        mcall   9
210
        mcall   9
209
        mov     eax, dword [ebp + thread_data.buffer + 30]              ; PID is at offset 30
211
        mov     eax, dword [ebp + thread_data.buffer + 30]              ; PID is at offset 30
210
        mov     [ebp + thread_data.pid], eax
212
        mov     [ebp + thread_data.pid], eax
211
 
213
 
212
        invoke  con_set_flags, 0x03
214
        invoke  con_set_flags, 0x03
213
        invoke  con_printf, str8, [ebp + thread_data.pid]               ; print on the console that we have created the new thread successfully
215
        invoke  con_printf, str8, [ebp + thread_data.pid]               ; print on the console that we have created the new thread successfully
214
        add     esp, 8                                                  ; balance stack
216
        add     esp, 8                                                  ; balance stack
215
        invoke  con_set_flags, 0x07
217
        invoke  con_set_flags, 0x07
216
 
218
 
217
        mcall   accept, [socketnum], sockaddr1, sockaddr1.length        ; time to accept the awaiting connection..
219
        mcall   accept, [socketnum], sockaddr1, sockaddr1.length        ; time to accept the awaiting connection..
218
        cmp     eax, -1
220
        cmp     eax, -1
219
        je      thread_exit
221
        je      thread_exit
220
        mov     [ebp + thread_data.socketnum], eax
222
        mov     [ebp + thread_data.socketnum], eax
221
 
223
 
222
if DEBUG
224
if DEBUG
223
        mcall   close, [socketnum]                                      ; close the listening socket
225
        mcall   close, [socketnum]                                      ; close the listening socket
224
end if
226
end if
225
 
227
 
226
        mov     [ebp + thread_data.state], STATE_CONNECTED
228
        mov     [ebp + thread_data.state], STATE_CONNECTED
227
        mov     [ebp + thread_data.permissions], 0
229
        mov     [ebp + thread_data.permissions], 0
228
        mov     [ebp + thread_data.mode], MODE_NOTREADY
230
        mov     [ebp + thread_data.mode], MODE_NOTREADY
229
        lea     eax, [ebp + thread_data.buffer]
231
        lea     eax, [ebp + thread_data.buffer]
230
        mov     [ebp + thread_data.buffer_ptr], eax
232
        mov     [ebp + thread_data.buffer_ptr], eax
231
        mov     [ebp + thread_data.passivesocknum], -1
233
        mov     [ebp + thread_data.passivesocknum], -1
232
 
234
 
233
        sendFTP "220 Welcome to KolibriOS FTP daemon"
235
        sendFTP "220 Welcome to KolibriOS FTP daemon"
234
 
236
 
235
        diff16  "threadloop", 0, $
237
        diff16  "threadloop", 0, $
236
threadloop:
238
threadloop:
237
; Check if our socket is still connected
239
; Check if our socket is still connected
238
        mcall   send, [ebp + thread_data.socketnum], 0, 0       ; Try to send zero bytes, if socket is closed, this will return -1
240
        mcall   send, [ebp + thread_data.socketnum], 0, 0       ; Try to send zero bytes, if socket is closed, this will return -1
239
        cmp     eax, -1
241
        cmp     eax, -1
240
        je      thread_exit
242
        je      thread_exit
241
 
243
 
242
        cmp     [alive], 0                                      ; Did main thread take a run for it?
244
        cmp     [alive], 0                                      ; Did main thread take a run for it?
243
        je      thread_exit
245
        je      thread_exit
244
 
246
 
245
        mcall   10                                              ; Wait for network event
247
        mcall   10                                              ; Wait for network event
246
 
248
 
247
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_WAIT
249
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_WAIT
248
        jne     .not_passive
250
        jne     .not_passive
249
        mov     ecx, [ebp + thread_data.passivesocknum]
251
        mov     ecx, [ebp + thread_data.passivesocknum]
250
        lea     edx, [ebp + thread_data.datasock]
252
        lea     edx, [ebp + thread_data.datasock]
251
        mov     esi, sizeof.thread_data.datasock
253
        mov     esi, sizeof.thread_data.datasock
252
        mcall   accept
254
        mcall   accept
253
        cmp     eax, -1
255
        cmp     eax, -1
254
        je      .not_passive
256
        je      .not_passive
255
        mov     [ebp + thread_data.datasocketnum], eax
257
        mov     [ebp + thread_data.datasocketnum], eax
256
        mov     [ebp + thread_data.mode], MODE_PASSIVE_OK
258
        mov     [ebp + thread_data.mode], MODE_PASSIVE_OK
257
        mcall   close   ; [ebp + thread_data.passivesocknum]
259
        mcall   close   ; [ebp + thread_data.passivesocknum]
258
        mov     [ebp + thread_data.passivesocknum], -1
260
        mov     [ebp + thread_data.passivesocknum], -1
259
 
261
 
260
        invoke  con_write_asciiz, str_datasock
262
        invoke  con_write_asciiz, str_datasock
261
  .not_passive:
263
  .not_passive:
262
 
264
 
263
        mov     ecx, [ebp + thread_data.socketnum]
265
        mov     ecx, [ebp + thread_data.socketnum]
264
        mov     edx, [ebp + thread_data.buffer_ptr]
266
        mov     edx, [ebp + thread_data.buffer_ptr]
265
        mov     esi, sizeof.thread_data.buffer    ;;; FIXME
267
        mov     esi, sizeof.thread_data.buffer    ;;; FIXME
266
        mcall   recv
268
        mcall   recv
267
        inc     eax                                     ; error? (-1)
269
        inc     eax                                     ; error? (-1)
268
        jz      threadloop
270
        jz      threadloop
269
        dec     eax                                     ; 0 bytes read?
271
        dec     eax                                     ; 0 bytes read?
270
        jz      threadloop
272
        jz      threadloop
271
 
273
 
272
        mov     edi, [ebp + thread_data.buffer_ptr]
274
        mov     edi, [ebp + thread_data.buffer_ptr]
273
        add     [ebp + thread_data.buffer_ptr], eax
275
        add     [ebp + thread_data.buffer_ptr], eax
274
 
276
 
275
; Check if we received a newline character, if not, wait for more data
277
; Check if we received a newline character, if not, wait for more data
276
        mov     ecx, eax
278
        mov     ecx, eax
277
        mov     al, 13
279
        mov     al, 13
278
        repne   scasb
280
        repne   scasb
279
        jne     threadloop
281
        jne     threadloop
280
 
282
 
281
; We got a command!
283
; We got a command!
282
        mov     byte [edi + 1], 0                       ; append string with zero byte
284
        mov     byte [edi + 1], 0                       ; append string with zero byte
283
        lea     esi, [ebp + thread_data.buffer]
285
        lea     esi, [ebp + thread_data.buffer]
284
        mov     ecx, [ebp + thread_data.buffer_ptr]
286
        mov     ecx, [ebp + thread_data.buffer_ptr]
285
        sub     ecx, esi
287
        sub     ecx, esi
286
        mov     [ebp + thread_data.buffer_ptr], esi     ; reset buffer ptr
288
        mov     [ebp + thread_data.buffer_ptr], esi     ; reset buffer ptr
287
 
289
 
288
        invoke  con_set_flags, 0x02                     ; print received data to console (in green color)
290
        invoke  con_set_flags, 0x02                     ; print received data to console (in green color)
289
        invoke  con_write_asciiz, str_newline
291
        invoke  con_write_asciiz, str_newline
290
        invoke  con_write_asciiz, esi
292
        invoke  con_write_asciiz, esi
291
        invoke  con_set_flags, 0x07
293
        invoke  con_set_flags, 0x07
292
 
294
 
293
        push    threadloop
295
        push    threadloop
294
        jmp     parse_cmd
296
        jmp     parse_cmd
295
 
297
 
296
listen_err:
298
listen_err:
297
        invoke  con_set_flags, 0x0c                     ; print errors in red
299
        invoke  con_set_flags, 0x0c                     ; print errors in red
298
        invoke  con_write_asciiz, str3
300
        invoke  con_write_asciiz, str3
299
        jmp     done
301
        jmp     done
300
 
302
 
301
bind_err:
303
bind_err:
302
        invoke  con_set_flags, 0x0c                     ; print errors in red
304
        invoke  con_set_flags, 0x0c                     ; print errors in red
303
        invoke  con_write_asciiz, str4
305
        invoke  con_write_asciiz, str4
304
        jmp     done
306
        jmp     done
305
 
307
 
306
sock_err:
308
sock_err:
307
        invoke  con_set_flags, 0x0c                     ; print errors in red
309
        invoke  con_set_flags, 0x0c                     ; print errors in red
308
        invoke  con_write_asciiz, str6
310
        invoke  con_write_asciiz, str6
309
        jmp     done
311
        jmp     done
310
 
312
 
311
done:
313
done:
312
        invoke  con_exit, 0
314
        invoke  con_exit, 0
313
exit:
315
exit:
314
        mcall   -1
316
        mcall   -1
315
 
317
 
316
 
318
 
317
thread_exit:
319
thread_exit:
318
        invoke  con_set_flags, 0x03                             ; print thread info in blue
320
        invoke  con_set_flags, 0x03                             ; print thread info in blue
319
        invoke  con_printf, str_bye, [ebp + thread_data.pid]    ; print on the console that we are about to kill the thread
321
        invoke  con_printf, str_bye, [ebp + thread_data.pid]    ; print on the console that we are about to kill the thread
320
        add     esp, 8                                          ; balance stack
322
        add     esp, 8                                          ; balance stack
321
        mcall   68, 13, ebp                                     ; free the memory
323
        mcall   68, 13, ebp                                     ; free the memory
322
        mcall   -1                                              ; and kill the thread
324
        mcall   -1                                              ; and kill the thread
323
 
325
 
324
 
326
 
325
; initialized data
327
; initialized data
326
 
328
 
327
title           db 'KolibriOS FTP daemon 0.1', 0
329
title           db 'KolibriOS FTP daemon 0.1', 0
328
str1            db 'Starting FTP daemon on port %u.', 0
330
str1            db 'Starting FTP daemon on port %u.', 0
329
str2            db '.', 0
331
str2            db '.', 0
330
str2b           db ' OK!',10,0
332
str2b           db ' OK!',10,0
331
str3            db 'Listen error',10,0
333
str3            db 'Listen error',10,0
332
str4            db 10,'ERROR: local port is already in use.',10,0
334
str4            db 10,'ERROR: local port is already in use.',10,0
333
;str5            db 'Setsockopt error.',10,10,0
335
;str5            db 'Setsockopt error.',10,10,0
334
str6            db 'ERROR: Could not open socket.',10,0
336
str6            db 'ERROR: Could not open socket.',10,0
335
str7            db 'Got data!',10,10,0
337
str7            db 'Got data!',10,10,0
336
str8            db 10,'Thread %d created',10,0
338
str8            db 10,'Thread %d created',10,0
337
str_bye         db 10,'Thread %d killed',10,0
339
str_bye         db 10,'Thread %d killed',10,0
338
 
340
 
339
str_logged_in   db 'Login ok',10,0
341
str_logged_in   db 'Login ok',10,0
340
str_pass_ok     db 'Password ok',10,0
342
str_pass_ok     db 'Password ok',10,0
341
str_pass_err    db 'Password/Username incorrect',10,0
343
str_pass_err    db 'Password/Username incorrect',10,0
342
str_pwd         db 'Current directory is "%s"\n',0
344
str_pwd         db 'Current directory is "%s"\n',0
343
str_err2        db 'ERROR: cannot open the directory.',10,0
345
str_err2        db 'ERROR: cannot open the directory.',10,0
344
str_datasock    db 'Passive data socket connected.',10,0
346
str_datasock    db 'Passive data socket connected.',10,0
345
str_notfound    db 'ERROR: file not found.',10,0
347
str_notfound    db 'ERROR: file not found.',10,0
346
str_sockerr     db 'ERROR: socket error.',10,0
348
str_sockerr     db 'ERROR: socket error.',10,0
347
 
349
 
348
str_newline     db 10, 0
350
str_newline     db 10, 0
349
str_mask        db '*', 0
351
str_mask        db '*', 0
350
str_infinity    db 0xff, 0xff, 0xff, 0xff, 0
352
str_infinity    db 0xff, 0xff, 0xff, 0xff, 0
351
 
353
 
352
months          dd 'Jan '
354
months          dd 'Jan '
353
                dd 'Feb '
355
                dd 'Feb '
354
                dd 'Mar '
356
                dd 'Mar '
355
                dd 'Apr '
357
                dd 'Apr '
356
                dd 'May '
358
                dd 'May '
357
                dd 'Jun '
359
                dd 'Jun '
358
                dd 'Jul '
360
                dd 'Jul '
359
                dd 'Aug '
361
                dd 'Aug '
360
                dd 'Sep '
362
                dd 'Sep '
361
                dd 'Oct '
363
                dd 'Oct '
362
                dd 'Nov '
364
                dd 'Nov '
363
                dd 'Dec '
365
                dd 'Dec '
364
 
366
 
365
str_users       db 'users'
367
str_users       db 'users'
366
str_ini         db '.ini', 0
368
str_ini         db '.ini', 0
367
str_port        db 'port', 0
369
str_port        db 'port', 0
368
str_ftpd        db 'ftpd', 0
370
str_ftpd        db 'ftpd', 0
369
str_conn        db 'conn', 0
371
str_conn        db 'conn', 0
370
str_ip          db 'ip', 0
372
str_ip          db 'ip', 0
371
str_pass        db 'pass', 0
373
str_pass        db 'pass', 0
372
str_home        db 'home', 0
374
str_home        db 'home', 0
373
str_mode        db 'mode', 0
375
str_mode        db 'mode', 0
374
str_pasv        db 'pasv', 0
376
str_pasv        db 'pasv', 0
375
str_start       db 'start', 0
377
str_start       db 'start', 0
376
str_end         db 'end', 0
378
str_end         db 'end', 0
377
 
379
 
378
 
380
 
379
sockaddr1:
381
sockaddr1:
380
                dw AF_INET4
382
                dw AF_INET4
381
  .port         dw 21
383
  .port         dw 0
382
  .ip           dd 0
384
  .ip           dd 0
383
                rb 10
385
                rb 10
384
  .length       = $ - sockaddr1
386
  .length       = $ - sockaddr1
385
 
387
 
386
; import
388
; import
387
 
389
 
388
align 4
390
align 4
389
@IMPORT:
391
@IMPORT:
390
 
392
 
391
diff16 "import", 0, $
393
diff16 "import", 0, $
392
 
394
 
393
library console,                'console.obj',\
395
library console,                'console.obj',\
394
        libini,                 'libini.obj', \
396
        libini,                 'libini.obj', \
395
        libio,                  'libio.obj'
397
        libio,                  'libio.obj'
396
 
398
 
397
import  console,\
399
import  console,\
398
        con_start,              'START',\
400
        con_start,              'START',\
399
        con_init,               'con_init',\
401
        con_init,               'con_init',\
400
        con_write_asciiz,       'con_write_asciiz',\
402
        con_write_asciiz,       'con_write_asciiz',\
401
        con_exit,               'con_exit',\
403
        con_exit,               'con_exit',\
402
        con_gets,               'con_gets',\
404
        con_gets,               'con_gets',\
403
        con_cls,                'con_cls',\
405
        con_cls,                'con_cls',\
404
        con_printf,             'con_printf',\
406
        con_printf,             'con_printf',\
405
        con_getch2,             'con_getch2',\
407
        con_getch2,             'con_getch2',\
406
        con_set_cursor_pos,     'con_set_cursor_pos',\
408
        con_set_cursor_pos,     'con_set_cursor_pos',\
407
        con_set_flags,          'con_set_flags',\
409
        con_set_flags,          'con_set_flags',\
408
        con_get_flags,          'con_get_flags'
410
        con_get_flags,          'con_get_flags'
409
 
411
 
410
import  libini,\
412
import  libini,\
411
        ini.get_str,            'ini_get_str',\
413
        ini.get_str,            'ini_get_str',\
412
        ini.get_int,            'ini_get_int'
414
        ini.get_int,            'ini_get_int'
413
 
415
 
414
import  libio,\
416
import  libio,\
415
        file.size,              'file_size',\
417
        file.size,              'file_size',\
416
        file.open,              'file_open',\
418
        file.open,              'file_open',\
417
        file.read,              'file_read',\
419
        file.read,              'file_read',\
418
        file.close,             'file_close',\
420
        file.close,             'file_close',\
419
        file.find.first,        'file_find_first',\
421
        file.find.first,        'file_find_first',\
420
        file.find.next,         'file_find_next',\
422
        file.find.next,         'file_find_next',\
421
        file.find.close,        'file_find_close'
423
        file.find.close,        'file_find_close'
422
 
424
 
423
 
425
 
424
IncludeIGlobals
426
IncludeIGlobals
425
 
427
 
426
 
428
 
427
i_end:
429
i_end:
428
 
430
 
429
diff16 "i_end", 0, $
431
diff16 "i_end", 0, $
430
 
432
 
431
; uninitialised data
433
; uninitialised data
432
 
434
 
433
        socketnum       dd ?
435
        socketnum       dd ?
434
        path            rb 1024
436
        path            rb 1024
435
        path2           rb 1024
437
        path2           rb 1024
436
        params          rb 1024
438
        params          rb 1024
437
        serverip        dd ?
439
        serverip        dd ?
438
        pasv_start      dw ?
440
        pasv_start      dw ?
439
        pasv_end        dw ?
441
        pasv_end        dw ?
440
        pasv_port       dw ?
442
        pasv_port       dw ?
441
 
443
 
442
        ini_buf         rb 3*4+3+1
444
        ini_buf         rb 3*4+3+1
443
 
445
 
444
        alive           db ?
446
        alive           db ?
445
 
447
 
446
mem:
448
mem: