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 | |||
2578 | hidnplayr | 3 | stack rb 0 |
4 | |||
5 | home_dir rb 1024 |
||
2554 | hidnplayr | 6 | |
2578 | hidnplayr | 7 | fpath rb 1024*3 |
8 | |||
9 | type db ? ; ASCII/EBDIC/IMAGE/.. |
||
10 | |||
11 | socketnum dd ? ; Commands socket |
||
12 | state dd ? ; disconnected/logging in/logged in/.. |
||
13 | passivesocknum dd ? ; when in passive mode, this is the listening socket |
||
14 | datasocketnum dd ? ; socket used for data transfers |
||
15 | |||
16 | datasock sockaddr_in |
||
17 | |||
18 | buffer rb BUFFERSIZE |
||
19 | |||
20 | |||
21 | |||
22 | |||
23 | |||
24 | |||
25 | |||
2554 | hidnplayr | 26 | |
27 | cmp byte [esi], 0x20 ; skip all leading characters |
||
28 | |||
2578 | hidnplayr | 29 | inc esi |
30 | dec ecx |
||
31 | cmp ecx, 3 |
||
32 | ja parse_cmd |
||
33 | ret |
||
34 | .ok: |
||
35 | |||
36 | cmp byte [esi+3], 0x20 |
||
37 | |||
2557 | hidnplayr | 38 | mov byte [esi+3], 0 |
39 | @@: |
||
40 | |||
41 | mov eax, [esi] |
||
42 | |||
2554 | hidnplayr | 43 | mov edi, commands ; list of commands to scan |
44 | .scanloop: |
||
45 | cmp eax, [edi] |
||
46 | jne .try_next |
||
47 | |||
2557 | hidnplayr | 48 | jmp dword [edi+4] |
2554 | hidnplayr | 49 | |
50 | .try_next: |
||
51 | |||
52 | cmp byte [edi], 0 |
||
53 | jne .scanloop |
||
54 | |||
55 | .error: |
||
56 | |||
57 | |||
2578 | hidnplayr | 58 | ret |
2557 | hidnplayr | 59 | |
2554 | hidnplayr | 60 | |
61 | |||
62 | |||
63 | |||
2562 | hidnplayr | 64 | db 'ABOR' |
2554 | hidnplayr | 65 | |
66 | db 'CDUP' |
||
67 | dd cmdCDUP |
||
2571 | hidnplayr | 68 | db 'CWD', 0 |
69 | dd cmdCWD |
||
2554 | hidnplayr | 70 | db 'DELE' |
71 | dd cmdDELE |
||
72 | db 'LIST' |
||
73 | dd cmdLIST |
||
74 | db 'NLST' |
||
75 | dd cmdNLST |
||
76 | db 'NOOP' |
||
77 | dd cmdNOOP |
||
78 | db 'PASS' |
||
79 | dd cmdPASS |
||
2557 | hidnplayr | 80 | db 'PASV' |
81 | dd cmdPASV |
||
2562 | hidnplayr | 82 | db 'PORT' |
83 | dd cmdPORT |
||
2585 | hidnplayr | 84 | db 'PWD', 0 |
85 | dd cmdPWD |
||
2563 | hidnplayr | 86 | db 'QUIT' |
2554 | hidnplayr | 87 | dd cmdQUIT |
88 | db 'RETR' |
||
89 | dd cmdRETR |
||
90 | db 'STOR' |
||
91 | dd cmdSTOR |
||
92 | db 'SYST' |
||
93 | dd cmdSYST |
||
94 | db 'TYPE' |
||
95 | dd cmdTYPE |
||
96 | db 'USER' |
||
97 | dd cmdUSER |
||
98 | db 0 ; end marker |
||
99 | |||
2562 | hidnplayr | 100 | |
2554 | hidnplayr | 101 | |
102 | |||
103 | |||
104 | ; TODO: abort the current filetransfer |
||
105 | |||
2578 | hidnplayr | 106 | ret |
107 | |||
2554 | hidnplayr | 108 | align 4 |
109 | |||
110 | |||
2571 | hidnplayr | 111 | cmp byte [edx + thread_data.work_dir+1], 0 ; are we in "/" ? |
112 | |||
2585 | hidnplayr | 113 | |
2571 | hidnplayr | 114 | mov ecx, 1024 |
115 | |||
116 | lea edi, [edx + thread_data.work_dir] |
||
117 | repne scasb |
||
2585 | hidnplayr | 118 | std |
2571 | hidnplayr | 119 | dec edi |
120 | dec edi |
||
121 | dec edi |
||
2585 | hidnplayr | 122 | mov al,'/' |
123 | repne scasb |
||
2571 | hidnplayr | 124 | cld |
2585 | hidnplayr | 125 | mov byte[edi+1], 0 |
2571 | hidnplayr | 126 | |
2585 | hidnplayr | 127 | .done: |
2571 | hidnplayr | 128 | |
129 | lea eax, [edx + thread_data.work_dir] |
||
2585 | hidnplayr | 130 | push eax |
131 | call [con_write_asciiz] |
||
132 | push str_newline |
||
133 | call [con_write_asciiz] |
||
134 | |||
135 | mcall send, [edx + thread_data.socketnum], str250, str250.length, 0 ; command successful |
||
136 | |||
137 | |||
2571 | hidnplayr | 138 | |
139 | |||
2585 | hidnplayr | 140 | |
2571 | hidnplayr | 141 | |
2563 | hidnplayr | 142 | sub ecx, 4 |
2554 | hidnplayr | 143 | |
2563 | hidnplayr | 144 | add esi, 4 |
145 | |||
146 | .scan: |
||
2571 | hidnplayr | 147 | |
148 | push ecx |
||
2578 | hidnplayr | 149 | mov ecx, 1024 |
150 | .find_zero: |
||
151 | cmp byte [edi], 0 |
||
152 | je .found_zero |
||
153 | inc edi |
||
154 | loop .find_zero |
||
155 | .found_zero: |
||
156 | pop ecx |
||
157 | .scan2: |
||
158 | |||
2581 | hidnplayr | 159 | cmp byte [esi], '/' |
2563 | hidnplayr | 160 | |
161 | inc esi |
||
162 | dec ecx |
||
163 | jz .done |
||
164 | @@: |
||
165 | |||
166 | .loop: |
||
167 | |||
168 | cmp al, 0x20 |
||
169 | jb .done |
||
170 | cmp al, '.' |
||
171 | je .up |
||
2571 | hidnplayr | 172 | .continue: |
173 | stosb |
||
174 | loop .loop |
||
2563 | hidnplayr | 175 | .done: |
176 | cmp byte [edi-1], '/' |
||
177 | je @f |
||
178 | mov byte [edi], '/' |
||
179 | inc edi |
||
180 | @@: |
||
181 | mov byte [edi], 0 |
||
182 | |||
183 | ; Print the new working dir on the console |
||
184 | |||
2585 | hidnplayr | 185 | push eax |
186 | call [con_write_asciiz] |
||
187 | push str_newline |
||
188 | call [con_write_asciiz] |
||
189 | |||
190 | mcall send, [edx + thread_data.socketnum], str250, str250.length, 0 |
||
191 | |||
2578 | hidnplayr | 192 | ret |
2563 | hidnplayr | 193 | |
2554 | hidnplayr | 194 | .up: |
195 | |||
2571 | hidnplayr | 196 | cmp al, '.' |
197 | jne .continue |
||
198 | |||
199 | ;;;; TODO: find second last '\' in work_dir and make next char zero |
||
200 | |||
2581 | hidnplayr | 201 | |
202 | jmp .scan2 |
||
2571 | hidnplayr | 203 | |
2581 | hidnplayr | 204 | .err: |
205 | |||
2563 | hidnplayr | 206 | |
2578 | hidnplayr | 207 | ret |
2563 | hidnplayr | 208 | |
209 | align 4 |
||
210 | |||
2554 | hidnplayr | 211 | |
212 | ret |
||
213 | |||
214 | |||
215 | |||
2585 | hidnplayr | 216 | |
2554 | hidnplayr | 217 | |
218 | ; If we are in active mode, it's time to open a data socket.. |
||
219 | |||
2563 | hidnplayr | 220 | jne @f |
2578 | hidnplayr | 221 | mov ecx, [edx + thread_data.datasocketnum] |
2562 | hidnplayr | 222 | lea edx, [edx + thread_data.datasock] |
2578 | hidnplayr | 223 | mov esi, sizeof.thread_data.datasock |
224 | mcall connect |
||
225 | mov edx, [esp+4] ; thread_data pointer |
||
226 | cmp eax, -1 |
||
227 | je socketerror |
||
2562 | hidnplayr | 228 | @@: |
2571 | hidnplayr | 229 | |
2562 | hidnplayr | 230 | ; Create fpath from home_dir and work_dir |
231 | |||
2563 | hidnplayr | 232 | |
233 | lea eax, [edx + thread_data.fpath] |
||
234 | |||
2578 | hidnplayr | 235 | call [con_write_asciiz] |
236 | push str_newline |
||
2571 | hidnplayr | 237 | call [con_write_asciiz] |
238 | |||
239 | ; Start the search |
||
240 | |||
2563 | hidnplayr | 241 | push str_mask |
2571 | hidnplayr | 242 | lea eax, [edx + thread_data.fpath] |
2562 | hidnplayr | 243 | push eax |
2578 | hidnplayr | 244 | call [file.find.first] |
245 | |||
2562 | hidnplayr | 246 | test eax, eax |
247 | |||
2578 | hidnplayr | 248 | |
249 | lea edi, [edx + thread_data.buffer] |
||
250 | |||
251 | |||
2562 | hidnplayr | 252 | test eax, eax ; did we find a file? |
2581 | hidnplayr | 253 | |
2563 | hidnplayr | 254 | mov ebx, eax ; yes, save the descripter in ebx |
2562 | hidnplayr | 255 | |
2578 | hidnplayr | 256 | ; first, convert the attributes |
2562 | hidnplayr | 257 | |
258 | jnz .folder |
||
2578 | hidnplayr | 259 | |
2562 | hidnplayr | 260 | test [ebx + FileInfoA.Attributes], FA_READONLY |
261 | |||
2578 | hidnplayr | 262 | |
2562 | hidnplayr | 263 | mov eax, '-rw-' |
264 | |||
265 | jmp .attr |
||
266 | |||
267 | .folder: |
||
268 | |||
269 | stosd |
||
270 | jmp .attr |
||
2563 | hidnplayr | 271 | |
2562 | hidnplayr | 272 | .readonly: |
273 | |||
274 | stosd |
||
275 | |||
276 | .attr: |
||
277 | |||
278 | stosd |
||
279 | mov ax, 'w-' |
||
280 | stosw |
||
281 | mov al, ' ' |
||
282 | stosb |
||
283 | |||
284 | ; now.. |
||
285 | |||
286 | stosw |
||
287 | |||
288 | ; now write owner, everything is owned by FTP, woohoo! |
||
289 | |||
290 | stosd |
||
291 | stosd |
||
292 | |||
293 | ; now the filesize in ascii |
||
294 | |||
295 | call dword_to_ascii |
||
2578 | hidnplayr | 296 | |
2562 | hidnplayr | 297 | mov al, ' ' |
298 | |||
299 | |||
300 | ; then date (month/day/year) |
||
301 | |||
302 | mov eax, [months + 4*eax] |
||
2578 | hidnplayr | 303 | stosd |
304 | |||
2562 | hidnplayr | 305 | movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.day] |
306 | |||
2578 | hidnplayr | 307 | |
2562 | hidnplayr | 308 | mov al, ' ' |
309 | |||
310 | |||
311 | movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.year] |
||
312 | |||
2578 | hidnplayr | 313 | |
2562 | hidnplayr | 314 | mov al, ' ' |
315 | |||
316 | |||
317 | ; and last but not least, filename |
||
318 | |||
319 | mov ecx, 264 |
||
2578 | hidnplayr | 320 | .nameloop: |
321 | lodsb |
||
2562 | hidnplayr | 322 | test al, al |
323 | jz .namedone |
||
324 | stosb |
||
325 | loop .nameloop |
||
326 | |||
327 | ; insert a cr lf |
||
328 | |||
2563 | hidnplayr | 329 | mov ax, 0x0a0d |
2562 | hidnplayr | 330 | stosw |
2571 | hidnplayr | 331 | |
2562 | hidnplayr | 332 | ; check next file |
333 | |||
2563 | hidnplayr | 334 | call [file.find.next] |
2578 | hidnplayr | 335 | jmp .parse_file |
2563 | hidnplayr | 336 | |
337 | ; close file desc |
||
338 | |||
339 | push ebx |
||
2562 | hidnplayr | 340 | call [file.find.close] |
2578 | hidnplayr | 341 | |
2562 | hidnplayr | 342 | ; append the string with a 0 |
343 | |||
2563 | hidnplayr | 344 | stosb |
2562 | hidnplayr | 345 | |
346 | ; Warn the client we're about to send the data |
||
347 | |||
2571 | hidnplayr | 348 | mcall send, [edx + thread_data.socketnum], str150, str150.length, 0 ; here it comes.. |
2578 | hidnplayr | 349 | pop edx esi |
350 | |||
351 | ; and send it to the client |
||
2562 | hidnplayr | 352 | |
2563 | hidnplayr | 353 | lea edx, [edx + thread_data.buffer] |
2578 | hidnplayr | 354 | sub esi, edx |
355 | xor edi, edi |
||
356 | mcall send |
||
357 | |||
358 | ; close the data socket.. |
||
2562 | hidnplayr | 359 | |
2563 | hidnplayr | 360 | mcall close, [edx + thread_data.datasocketnum] |
2578 | hidnplayr | 361 | mov [edx + thread_data.mode], MODE_NOTREADY |
362 | |||
363 | ; And send "transfer ok" on the base connection |
||
2562 | hidnplayr | 364 | |
2563 | hidnplayr | 365 | |
2578 | hidnplayr | 366 | ret |
2562 | hidnplayr | 367 | |
2554 | hidnplayr | 368 | .nosuchdir: |
369 | |||
2578 | hidnplayr | 370 | |
371 | ret |
||
2562 | hidnplayr | 372 | |
2578 | hidnplayr | 373 | |
374 | |||
375 | |||
2554 | hidnplayr | 376 | |
377 | ; TODO: same as list but simpler output format |
||
378 | |||
2578 | hidnplayr | 379 | ret |
380 | |||
2554 | hidnplayr | 381 | align 4 |
382 | |||
383 | |||
384 | ret |
||
385 | |||
386 | align 4 |
||
387 | |||
388 | |||
2557 | hidnplayr | 389 | ; TODO: verify password |
390 | |||
2578 | hidnplayr | 391 | mcall send, [edx + thread_data.socketnum], str230, str230.length, 0 |
2560 | hidnplayr | 392 | |
2578 | hidnplayr | 393 | push str_pass_ok |
394 | |||
2560 | hidnplayr | 395 | |
396 | mov edx, [esp+4] ; thread_data pointer |
||
397 | |||
2578 | hidnplayr | 398 | |
399 | ret |
||
2557 | hidnplayr | 400 | |
401 | align 4 |
||
402 | |||
403 | |||
2560 | hidnplayr | 404 | ; Open a new TCP socket |
405 | |||
2578 | hidnplayr | 406 | mov edx, [esp+4] ; thread_data pointer |
2562 | hidnplayr | 407 | cmp eax, -1 |
2578 | hidnplayr | 408 | je socketerror |
2562 | hidnplayr | 409 | mov [edx + thread_data.passivesocknum], eax |
2578 | hidnplayr | 410 | |
411 | ; Bind it to a known local port |
||
2562 | hidnplayr | 412 | |
2578 | hidnplayr | 413 | mov [edx + thread_data.datasock.sin_port], 2000 |
414 | mov [edx + thread_data.datasock.sin_addr], 0 |
||
415 | |||
416 | mov ecx, eax ;[edx + thread_data.passivesocknum] |
||
2562 | hidnplayr | 417 | |
2578 | hidnplayr | 418 | mov esi, sizeof.thread_data.datasock |
419 | mcall bind |
||
2581 | hidnplayr | 420 | mov edx, [esp+4] ; thread_data pointer |
421 | cmp eax, -1 |
||
2578 | hidnplayr | 422 | je bind_err |
2562 | hidnplayr | 423 | |
424 | ; And set it to listen! |
||
425 | |||
2578 | hidnplayr | 426 | |
427 | ; Tell our thread we are ready to accept incoming calls |
||
2562 | hidnplayr | 428 | |
2578 | hidnplayr | 429 | mov [edx + thread_data.mode], MODE_PASSIVE_WAIT |
430 | |||
431 | ; Now tell the client where to connect to in this format: |
||
2562 | hidnplayr | 432 | |
2578 | hidnplayr | 433 | ; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number. |
434 | lea edi, [edx + thread_data.buffer] |
||
435 | mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000) |
||
436 | stosd |
||
2562 | hidnplayr | 437 | mov eax, '(127' |
438 | stosd |
||
439 | mov eax, ',0,0' |
||
440 | stosd |
||
441 | mov eax, ',1,7' |
||
442 | stosd |
||
443 | mov eax, ',208' |
||
444 | stosd |
||
445 | mov al, ')' |
||
446 | stosb |
||
447 | mov ax, 0x0a0d |
||
448 | stosw |
||
2571 | hidnplayr | 449 | xor al, al |
2562 | hidnplayr | 450 | stosb |
451 | |||
452 | lea esi, [edi - thread_data.buffer] |
||
453 | |||
2578 | hidnplayr | 454 | mov ecx, [edx + thread_data.socketnum] |
455 | lea edx, [edx + thread_data.buffer] |
||
456 | xor esi, esi |
||
457 | mcall send |
||
2581 | hidnplayr | 458 | |
459 | ret |
||
2562 | hidnplayr | 460 | |
2560 | hidnplayr | 461 | |
462 | |||
2585 | hidnplayr | 463 | |
2560 | hidnplayr | 464 | |
2563 | hidnplayr | 465 | mov dword [edx + thread_data.buffer], '257 ' |
2554 | hidnplayr | 466 | |
2578 | hidnplayr | 467 | |
468 | lea edi, [edx + thread_data.buffer+5] |
||
2560 | hidnplayr | 469 | |
2578 | hidnplayr | 470 | mov ecx, 1024 |
471 | .loop: |
||
2560 | hidnplayr | 472 | lodsb |
473 | or al, al |
||
474 | jz .ok |
||
475 | stosb |
||
476 | dec ecx |
||
477 | jnz .loop |
||
478 | |||
479 | .ok: |
||
480 | |||
481 | lea esi, [edi - thread_data.buffer + 4] |
||
2578 | hidnplayr | 482 | sub esi, edx |
483 | mov ecx, [edx + thread_data.socketnum] |
||
484 | lea edx, [edx + thread_data.buffer] |
||
485 | xor edi, edi |
||
486 | mcall send |
||
2585 | hidnplayr | 487 | |
488 | mov edx, [esp+4] |
||
2560 | hidnplayr | 489 | |
2585 | hidnplayr | 490 | lea eax, [edx + thread_data.work_dir] |
491 | push eax |
||
492 | call [con_write_asciiz] |
||
493 | push str_newline |
||
494 | call [con_write_asciiz] |
||
495 | |||
496 | ret |
||
2562 | hidnplayr | 497 | |
2554 | hidnplayr | 498 | |
499 | |||
2585 | hidnplayr | 500 | |
2554 | hidnplayr | 501 | |
502 | ; PORT a1,a2,a3,a4,p1,p2 |
||
503 | |||
2560 | hidnplayr | 504 | |
505 | mov [edx + thread_data.mode], MODE_ACTIVE |
||
506 | |||
2578 | hidnplayr | 507 | lea esi, [esi+5] |
2560 | hidnplayr | 508 | |
509 | call ascii_to_byte |
||
2578 | hidnplayr | 510 | mov bl, al |
2560 | hidnplayr | 511 | inc esi ; skip past ',' |
2581 | hidnplayr | 512 | call ascii_to_byte |
2578 | hidnplayr | 513 | mov bh, al |
2560 | hidnplayr | 514 | shl ebx, 16 |
2581 | hidnplayr | 515 | inc esi |
2578 | hidnplayr | 516 | call ascii_to_byte |
2560 | hidnplayr | 517 | mov bl, al |
518 | inc esi |
||
2581 | hidnplayr | 519 | call ascii_to_byte |
2560 | hidnplayr | 520 | mov bh, al |
521 | inc esi |
||
2581 | hidnplayr | 522 | rol ebx, 16 |
2560 | hidnplayr | 523 | |
2581 | hidnplayr | 524 | ; And put it in datasock |
2560 | hidnplayr | 525 | |
2578 | hidnplayr | 526 | |
527 | ; Now the same with portnumber |
||
2560 | hidnplayr | 528 | |
2578 | hidnplayr | 529 | mov bh, al |
2560 | hidnplayr | 530 | inc esi |
2578 | hidnplayr | 531 | call ascii_to_byte |
2560 | hidnplayr | 532 | mov bl, al |
533 | |||
2578 | hidnplayr | 534 | ; Save it in datasock too |
2560 | hidnplayr | 535 | |
2578 | hidnplayr | 536 | |
537 | ; We will open the socket, but do not connect yet! |
||
2560 | hidnplayr | 538 | |
2578 | hidnplayr | 539 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
540 | mov edx, [esp+4] ; thread_data pointer |
||
2562 | hidnplayr | 541 | cmp eax, -1 |
2578 | hidnplayr | 542 | je socketerror |
2560 | hidnplayr | 543 | mov [edx + thread_data.datasocketnum], eax |
2578 | hidnplayr | 544 | |
545 | ; Tell the client we are ready |
||
2560 | hidnplayr | 546 | |
2578 | hidnplayr | 547 | mcall send, [edx + thread_data.socketnum], str225, str225.length, 0 |
548 | ret |
||
549 | |||
2554 | hidnplayr | 550 | |
551 | |||
2560 | hidnplayr | 552 | |
2554 | hidnplayr | 553 | |
554 | mcall close, [edx + thread_data.datasocketnum] |
||
555 | |||
2578 | hidnplayr | 556 | mcall close;, [edx + thread_data.socketnum] |
557 | |||
558 | add esp, 4 ; get rid of call return address |
||
2557 | hidnplayr | 559 | |
2581 | hidnplayr | 560 | |
561 | align 4 |
||
2554 | hidnplayr | 562 | |
563 | |||
564 | sub ecx, 5 |
||
565 | |||
2571 | hidnplayr | 566 | |
567 | cmp [edx + thread_data.mode], MODE_ACTIVE |
||
568 | |||
2578 | hidnplayr | 569 | push esi |
2563 | hidnplayr | 570 | mov ecx, [edx + thread_data.datasocketnum] |
2571 | hidnplayr | 571 | lea edx, [edx + thread_data.datasock] |
2578 | hidnplayr | 572 | mov esi, sizeof.thread_data.datasock |
573 | mcall connect |
||
2581 | hidnplayr | 574 | pop esi |
575 | mov edx, [esp+4] ; thread_data pointer |
||
2571 | hidnplayr | 576 | cmp eax, -1 |
2578 | hidnplayr | 577 | je socketerror |
2571 | hidnplayr | 578 | @@: |
579 | |||
2563 | hidnplayr | 580 | push esi |
2562 | hidnplayr | 581 | |
2571 | hidnplayr | 582 | pop esi |
583 | dec edi |
||
584 | add esi, 5 |
||
585 | mov ecx, 1024 |
||
586 | .loop: |
||
587 | lodsb |
||
588 | cmp al, 0x20 |
||
589 | jl .done |
||
590 | stosb |
||
591 | loop .loop |
||
592 | .done: |
||
593 | xor al, al |
||
594 | stosb |
||
595 | |||
596 | lea eax, [edx + thread_data.fpath] |
||
2563 | hidnplayr | 597 | |
2578 | hidnplayr | 598 | call [con_write_asciiz] |
599 | push str_newline |
||
2571 | hidnplayr | 600 | call [con_write_asciiz] |
601 | |||
602 | push O_READ |
||
603 | |||
2563 | hidnplayr | 604 | push eax |
2578 | hidnplayr | 605 | call [file.open] |
606 | test eax, eax |
||
2563 | hidnplayr | 607 | jz .cannot_open |
2571 | hidnplayr | 608 | |
609 | push eax |
||
2563 | hidnplayr | 610 | |
2571 | hidnplayr | 611 | pop ebx |
2578 | hidnplayr | 612 | |
2571 | hidnplayr | 613 | mov edx, [esp+4] ; thread_data pointer |
2563 | hidnplayr | 614 | |
2578 | hidnplayr | 615 | push BUFFERSIZE |
2563 | hidnplayr | 616 | lea eax, [edx + thread_data.buffer] |
617 | push eax |
||
2578 | hidnplayr | 618 | push ebx |
619 | call [file.read] |
||
2563 | hidnplayr | 620 | cmp eax, -1 |
621 | je .cannot_open ; fixme: this is not the correct error |
||
2571 | hidnplayr | 622 | |
623 | push eax |
||
2562 | hidnplayr | 624 | |
2563 | hidnplayr | 625 | mov esi, eax |
626 | mov ecx, [edx + thread_data.datasocketnum] |
||
627 | lea edx, [edx + thread_data.buffer] |
||
2578 | hidnplayr | 628 | xor esi, esi |
629 | mcall send |
||
2581 | hidnplayr | 630 | pop ebx |
631 | pop ecx |
||
2563 | hidnplayr | 632 | mov edx, [esp+4] ; thread_data pointer |
633 | cmp eax, -1 |
||
2578 | hidnplayr | 634 | je socketerror |
2571 | hidnplayr | 635 | |
636 | cmp ecx, BUFFERSIZE |
||
2563 | hidnplayr | 637 | |
638 | |||
639 | mcall close, [edx + thread_data.datasocketnum] |
||
640 | |||
2578 | hidnplayr | 641 | |
2585 | hidnplayr | 642 | mcall send, [edx + thread_data.socketnum], str226, str226.length, 0 ; transfer ok |
2563 | hidnplayr | 643 | |
2578 | hidnplayr | 644 | ret |
2563 | hidnplayr | 645 | |
2554 | hidnplayr | 646 | .cannot_open: |
647 | |||
2571 | hidnplayr | 648 | call [con_set_flags] |
649 | push str_notfound |
||
650 | call [con_write_asciiz] |
||
651 | pushd 0x07 |
||
652 | call [con_set_flags] |
||
653 | |||
654 | mcall send, [edx + thread_data.socketnum], str550, str550.length, 0 ; file not found |
||
655 | |||
2578 | hidnplayr | 656 | ret |
2571 | hidnplayr | 657 | |
658 | align 4 |
||
659 | |||
2554 | hidnplayr | 660 | |
661 | ; TODO: check if user has write permission, and write file if so |
||
662 | |||
2578 | hidnplayr | 663 | ret |
664 | |||
2554 | hidnplayr | 665 | align 4 |
666 | |||
667 | |||
668 | mcall send, [edx + thread_data.socketnum], str215, str215.length, 0 |
||
669 | |||
2578 | hidnplayr | 670 | ret |
2557 | hidnplayr | 671 | |
2554 | hidnplayr | 672 | align 4 |
673 | |||
674 | |||
675 | cmp ecx, 6 |
||
676 | |||
2560 | hidnplayr | 677 | |
678 | mov al, byte[esi+5] |
||
679 | |||
680 | |||
681 | cmp al, 'A' |
||
682 | |||
683 | cmp al, 'E' |
||
684 | je .ebdic |
||
685 | cmp al, 'I' |
||
686 | je .image |
||
687 | cmp al, 'L' |
||
688 | je .local |
||
689 | |||
690 | jmp parse_cmd.error |
||
691 | |||
692 | .ascii: |
||
693 | |||
694 | jmp .subtype |
||
2578 | hidnplayr | 695 | |
2560 | hidnplayr | 696 | .ebdic: |
697 | |||
698 | |||
2578 | hidnplayr | 699 | .subtype: |
2560 | hidnplayr | 700 | |
701 | jb .non_print |
||
702 | |||
703 | mov al, byte[esi+7] |
||
704 | |||
705 | |||
706 | cmp al, 'N' |
||
707 | |||
708 | cmp al, 'T' |
||
709 | je .telnet |
||
710 | cmp al, 'C' |
||
711 | je .asacc |
||
712 | |||
713 | jmp parse_cmd.error |
||
714 | |||
715 | .non_print: |
||
716 | |||
717 | jmp .ok |
||
2578 | hidnplayr | 718 | |
2560 | hidnplayr | 719 | .telnet: |
720 | |||
721 | jmp .ok |
||
2578 | hidnplayr | 722 | |
2560 | hidnplayr | 723 | .asacc: |
724 | |||
725 | jmp .ok |
||
2578 | hidnplayr | 726 | |
2560 | hidnplayr | 727 | .image: |
728 | |||
729 | jmp .ok |
||
2578 | hidnplayr | 730 | |
2560 | hidnplayr | 731 | .local: |
732 | |||
733 | jb parse_cmd.error |
||
734 | |||
735 | mov al, byte[esi+7] |
||
736 | |||
737 | jb parse_cmd.error |
||
738 | cmp al, 9 |
||
739 | ja parse_cmd.error |
||
740 | or al, TYPE_LOCAL |
||
741 | mov [edx + thread_data.type], al |
||
742 | |||
2578 | hidnplayr | 743 | .ok: |
2560 | hidnplayr | 744 | |
745 | |||
2578 | hidnplayr | 746 | ret |
2560 | hidnplayr | 747 | |
2554 | hidnplayr | 748 | |
749 | |||
2585 | hidnplayr | 750 | |
2554 | hidnplayr | 751 | |
752 | ; TODO: check user and set home directory (and permissions) |
||
753 | |||
2578 | hidnplayr | 754 | mov [edx + thread_data.state], STATE_LOGIN |
2557 | hidnplayr | 755 | |
2578 | hidnplayr | 756 | mov word [edx + thread_data.work_dir], "/" ; "/", 0 |
2585 | hidnplayr | 757 | |
758 | push str_logged_in |
||
2560 | hidnplayr | 759 | |
760 | |||
761 | mcall send, [edx + thread_data.socketnum], str331, str331.length, 0 ; Now send me the password! |
||
762 | |||
2585 | hidnplayr | 763 | ret |
764 | |||
2554 | hidnplayr | 765 | |
766 | |||
767 | |||
768 | |||
2578 | hidnplayr | 769 | |
2560 | hidnplayr | 770 | xor eax, eax |
771 | |||
2578 | hidnplayr | 772 | |
773 | .loop: |
||
2560 | hidnplayr | 774 | |
775 | sub bl, '0' |
||
2578 | hidnplayr | 776 | jb .done |
777 | cmp bl, 9 |
||
2560 | hidnplayr | 778 | ja .done |
2578 | hidnplayr | 779 | lea eax, [eax*4 + eax] ; |
2560 | hidnplayr | 780 | shl eax, 1 ; eax = eax * 10 |
2578 | hidnplayr | 781 | add eax, ebx |
782 | inc esi |
||
783 | |||
2560 | hidnplayr | 784 | jmp .loop |
785 | |||
786 | .done: |
||
787 | |||
788 | ret |
||
2578 | hidnplayr | 789 | |
2560 | hidnplayr | 790 | align 4 |
791 | |||
2562 | hidnplayr | 792 | |
2578 | hidnplayr | 793 | mov eax, '1' |
2560 | hidnplayr | 794 | |
2562 | hidnplayr | 795 | |
796 | ret |
||
2560 | hidnplayr | 797 | |
2562 | hidnplayr | 798 | align 4 |
2560 | hidnplayr | 799 | |
2563 | hidnplayr | 800 | |
801 | lea edi, [edx + thread_data.fpath] |
||
2581 | hidnplayr | 802 | |
2578 | hidnplayr | 803 | mov ecx, 1024 |
804 | .loop1: |
||
2563 | hidnplayr | 805 | lodsb |
806 | or al, al |
||
807 | jz .next |
||
808 | stosb |
||
809 | loop .loop1 |
||
810 | .next: |
||
811 | |||
812 | cmp byte[edi-1], '/' |
||
2562 | hidnplayr | 813 | |
2563 | hidnplayr | 814 | dec edi |
815 | @@: |
||
816 | |||
817 | lea esi, [edx + thread_data.work_dir] |
||
2562 | hidnplayr | 818 | |
2578 | hidnplayr | 819 | .loop2: |
2563 | hidnplayr | 820 | lodsb |
821 | or al, al |
||
822 | jz .done |
||
823 | stosb |
||
824 | loop .loop2 |
||
825 | |||
826 | .done: |
||
827 | |||
828 | |||
829 | ret |
||
830 | |||
831 | |||
832 | |||
833 | |||
2571 | hidnplayr | 834 | |
835 | pushd 0x0c |
||
2563 | hidnplayr | 836 | |
2571 | hidnplayr | 837 | push str_sockerr |
838 | call [con_write_asciiz] |
||
839 | pushd 0x07 |
||
840 | call [con_set_flags] |
||
841 | |||
842 | mcall send, [edx + thread_data.socketnum], str425, str425.length, 0 ; data connection error |
||
2563 | hidnplayr | 843 | |
2578 | hidnplayr | 844 | ret |
2571 | hidnplayr | 845 | |
846 | |||
847 | |||
848 | |||
849 | |||
850 | |||
2554 | hidnplayr | 851 | str200 db '200 Command OK.', 13, 10 |
2562 | hidnplayr | 852 | .length = $ - str200 |
2554 | hidnplayr | 853 | str215 db '215 UNIX type: L8', 13, 10 |
2560 | hidnplayr | 854 | .length = $ - str215 |
2554 | hidnplayr | 855 | str220 db '220 KolibriOS FTP Daemon 1.0', 13, 10 |
2557 | hidnplayr | 856 | .length = $ - str220 |
2554 | hidnplayr | 857 | str221 db '221 Bye!', 13, 10 |
858 | .length = $ - str221 |
||
859 | str225 db '225 Data connection open', 13, 10 |
||
2557 | hidnplayr | 860 | .length = $ - str225 |
2560 | hidnplayr | 861 | str226 db '226 Transfer OK, Closing connection', 13, 10 |
862 | .length = $ - str226 |
||
2554 | hidnplayr | 863 | str230 db '230 You are now logged in.', 13, 10 |
2562 | hidnplayr | 864 | .length = $ - str230 |
2554 | hidnplayr | 865 | str250 db '250 command successful', 13, 10 |
2557 | hidnplayr | 866 | .length = $ - str250 |
2554 | hidnplayr | 867 | str331 db '331 Please specify the password.', 13, 10 |
2563 | hidnplayr | 868 | .length = $ - str331 |
2554 | hidnplayr | 869 | str421 db '421 Timeout!', 13, 10 |
2557 | hidnplayr | 870 | .length = $ - str421 |
2560 | hidnplayr | 871 | str425 db '425 Cant open data connection.', 13, 10 |
872 | .length = $ - str425 |
||
873 | str500 db '500 Unsupported command', 13, 10 |
||
874 | .length = $ - str500 |
||
2554 | hidnplayr | 875 | str550 db '550 No such file', 13, 10 |
2557 | hidnplayr | 876 | .length = $ - str550 |
2563 | hidnplayr | 877 |