Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3701 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2013. All rights reserved.         ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ftpc.asm - FTP client for KolibriOS                            ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
15
format binary as ""
16
 
17
__DEBUG__               = 0
18
__DEBUG_LEVEL__         = 1
19
BUFFERSIZE              = 1024
20
 
21
STATUS_CONNECTING       = 0
22
STATUS_CONNECTED        = 1
23
STATUS_NEEDPASSWORD     = 2
24
STATUS_LOGGED_IN        = 3
25
 
26
use32
27
; standard header
28
        db      'MENUET01'      ; signature
29
        dd      1               ; header version
30
        dd      start           ; entry point
31
        dd      i_end           ; initialized size
32
        dd      mem+0x1000      ; required memory
33
        dd      mem+0x1000      ; stack pointer
34
        dd      s               ; parameters
35
        dd      0               ; path
36
 
37
include '../../macros.inc'
38
purge mov,add,sub
39
include '../../proc32.inc'
40
include '../../dll.inc'
41
include '../../debug-fdo.inc'
42
include '../../network.inc'
43
 
44
include 'usercommands.inc'
45
include 'servercommands.inc'
46
 
47
; entry point
48
start:
49
 
50
        DEBUGF  1, "hello"
51
; load libraries
52
        stdcall dll.Load, @IMPORT
53
        test    eax, eax
54
        jnz     exit
55
; initialize console
56
        push    1
57
        call    [con_start]
58
        push    title
59
        push    25
60
        push    80
61
        push    25
62
        push    80
63
        call    [con_init]
64
 
65
; Check for parameters
66
        cmp     byte [s], 0
67
        jne     resolve
68
 
69
main:
70
        call    [con_cls]
71
; Welcome user
72
        push    str1
73
        call    [con_write_asciiz]
74
 
75
; write prompt
76
        push    str2
77
        call    [con_write_asciiz]
78
; read string
79
        mov     esi, s
80
        push    256
81
        push    esi
82
        call    [con_gets]
83
; check for exit
84
        test    eax, eax
85
        jz      done
86
        cmp     byte [esi], 10
87
        jz      done
88
 
89
resolve:
90
 
91
; delete terminating '\n'
92
        mov     esi, s
93
  @@:
94
        lodsb
95
        cmp     al, 0x20
96
        ja      @r
97
        mov     byte [esi-1], 0
98
 
99
;        call    [con_cls]
100
        push    str3
101
        call    [con_write_asciiz]
102
        push    s
103
        call    [con_write_asciiz]
104
 
105
; resolve name
106
        push    esp     ; reserve stack place
107
        push    esp     ; fourth parameter
108
        push    0       ; third parameter
109
        push    0       ; second parameter
110
        push    s       ; first parameter
111
        call    [getaddrinfo]
112
        pop     esi
113
; test for error
114
        test    eax, eax
115
        jnz     fail
116
 
117
; write results
118
        push    str8
119
        call    [con_write_asciiz]
120
;        mov     edi, esi
121
 
122
; convert IP address to decimal notation
123
        mov     eax, [esi+addrinfo.ai_addr]
124
        mov     eax, [eax+sockaddr_in.sin_addr]
125
        mov     [sockaddr1.ip], eax
126
        push    eax
127
        call    [inet_ntoa]
128
; write result
129
        push    eax
130
        call    [con_write_asciiz]
131
; free allocated memory
132
        push    esi
133
        call    [freeaddrinfo]
134
 
135
        push    str9
136
        call    [con_write_asciiz]
137
 
138
        mcall   socket, AF_INET4, SOCK_STREAM, 0
139
        cmp     eax, -1
140
        je      fail2
141
        mov     [socketnum], eax
142
 
143
        push    str11
144
        call    [con_write_asciiz]
145
 
146
        mcall   connect, [socketnum], sockaddr1, 18
147
 
148
        mcall   40, EVM_STACK
149
 
150
        mov     [status], STATUS_CONNECTING
151
        mov     [offset], buffer_ptr
152
 
153
        push    str12
154
        call    [con_write_asciiz]
155
 
156
wait_for_serverdata:
157
        mcall   10
158
 
159
        call    [con_get_flags]
160
        test    eax, 0x200                      ; con window closed?
161
        jnz     exit
162
 
163
; receive socket data
3704 hidnplayr 164
        mcall   recv, [socketnum], [offset], BUFFERSIZE, MSG_DONTWAIT
3701 hidnplayr 165
        inc     eax
166
        jz      wait_for_serverdata
167
        dec     eax
168
        jz      wait_for_serverdata
169
 
170
; extract commands, copy them to "s" buffer
171
        add     eax, buffer_ptr                 ; eax = end pointer
172
        mov     esi, buffer_ptr                 ; esi = current pointer
173
  .nextcommand:
174
        mov     edi, s
175
  .byteloop:
176
        cmp     esi, eax
177
        jae     wait_for_serverdata
178
        lodsb
179
        cmp     al, 10                          ; excellent, we might have a command
180
        je      .got_command
181
        cmp     al, 13                          ; just ignore this crap
182
        je      .byteloop
183
        stosb
184
        jmp     .byteloop
185
 
186
; we have a newline check if its a command
187
  .got_command:
188
        xor     al, al
189
        stosb
190
;        push    esi eax
191
 
192
; print it to the screen
193
        pushd   s
194
        call    [con_write_asciiz]
195
        pushd   str4                            ; newline
196
        call    [con_write_asciiz]
197
 
198
;        cmp     byte[s+2], " "
199
;        jne     .not_command
200
 
201
        lea     ecx, [edi - s]
202
        call    server_parser
203
 
204
;  .not_command:
205
;        pop     eax esi
206
;        jmp     .nextcommand
207
 
208
 
209
 
210
 
211
wait_for_usercommand:
212
 
213
        cmp     [status], STATUS_CONNECTED
214
        je      .connected
215
 
216
        cmp     [status], STATUS_NEEDPASSWORD
217
        je      .needpass
218
 
219
; write prompt
220
        push    str2
221
        call    [con_write_asciiz]
222
; read string
223
        mov     esi, s
224
        push    256
225
        push    esi
226
        call    [con_gets]
227
 
228
        call    [con_get_flags]
229
        test    eax, 0x200                      ; con window closed?
230
        jnz     exit
231
 
232
        cmp     dword[s], "list"
233
        je      cmd_list
234
 
235
        cmp     dword[s], "help"
236
        je      cmd_help
237
 
238
        push    str_unkown
239
        call    [con_write_asciiz]
240
 
241
        jmp     wait_for_usercommand
242
 
243
 
244
  .connected:
245
 
246
        push    str_user
247
        call    [con_write_asciiz]
248
 
249
        mov     dword[s], "USER"
250
        mov     byte[s+4], " "
251
 
252
;        mov     [status], STATUS_NEEDPASSWORD
253
        inc     [status]
254
 
255
        jmp     .send
256
 
257
 
258
  .needpass:
259
        push    str_pass
260
        call    [con_write_asciiz]
261
 
262
        mov     dword[s], "PASS"
263
        mov     byte[s+4], " "
264
 
265
;        mov     [status], STATUS_LOGGED_IN
266
        inc     [status]
267
 
268
  .send:
269
; read string
270
        mov     esi, s+5
271
        push    256
272
        push    esi
273
        call    [con_gets]
274
 
275
        mov     edi, s+5
276
        mov     ecx, 256
277
        xor     al, al
278
        repne   scasb
279
        lea     esi, [edi-s-1]
280
        mcall   send, [socketnum], s
281
 
282
        jmp     wait_for_usercommand
283
 
284
 
285
 
286
 
287
 
288
 
289
open_dataconnection:
290
        cmp     [status], STATUS_LOGGED_IN
291
        jne     .fail
292
 
293
        mov     dword[s], "PASV"
294
        mov     byte[s+4], 10
295
        mcall   send, [socketnum], s, 5
296
 
297
        ret
298
 
299
  .fail:
300
        push    str6
301
        call    [con_write_asciiz]
302
 
303
        ret
304
 
305
 
306
fail2:
307
        push    str6
308
        call    [con_write_asciiz]
309
 
310
        jmp     fail.wait
311
 
312
fail:
313
        push    str5
314
        call    [con_write_asciiz]
315
  .wait:
316
        push    str10
317
        call    [con_write_asciiz]
318
        call    [con_getch2]
319
        jmp     main
320
 
321
done:
322
        push    1
323
        call    [con_exit]
324
exit:
325
 
326
        mcall   close, [socketnum]
327
        mcall   -1
328
 
329
 
330
 
331
; data
332
title   db 'FTP client',0
333
str1    db 'FTP client for KolibriOS v0.01',10,10,'Please enter ftp server address.',10,0
334
str2    db '> ',0
335
str3    db 'Resolving ',0
336
str4    db 10,0
337
str5    db 10,'Name resolution failed.',10,0
338
str6    db 10,'Socket error.',10,0
339
str8    db ' (',0
340
str9    db ')',10,0
341
str10   db 'Push any key to continue.',0
342
str11   db 'Connecting',10,0
343
str12   db 'Connected!',10,0
344
str_user db "username: ",0
345
str_pass db "password: ",0
346
str_unkown db "unkown command",10,0
347
str_help db "available commands:",10,10
348
         db "help       list",10,0
349
 
350
str_open db "opening data socket",10,0
351
 
352
sockaddr1:
353
        dw AF_INET4
354
.port   dw 0x1500       ; 21
355
.ip     dd 0
356
        rb 10
357
 
358
sockaddr2:
359
        dw AF_INET4
360
.port   dw 0
361
.ip     dd 0
362
        rb 10
363
 
364
include_debug_strings    ; ALWAYS present in data section
365
 
366
 
367
 
368
; import
369
align 4
370
@IMPORT:
371
 
372
library network, 'network.obj', console, 'console.obj'
373
 
374
import  network,        \
375
        getaddrinfo,    'getaddrinfo',  \
376
        freeaddrinfo,   'freeaddrinfo', \
377
        inet_ntoa,      'inet_ntoa'
378
 
379
import  console,        \
380
        con_start,      'START',        \
381
        con_init,       'con_init',     \
382
        con_write_asciiz,'con_write_asciiz',     \
383
        con_exit,       'con_exit',     \
384
        con_gets,       'con_gets',\
385
        con_cls,        'con_cls',\
386
        con_getch2,     'con_getch2',\
387
        con_set_cursor_pos, 'con_set_cursor_pos',\
388
        con_write_string, 'con_write_string',\
389
        con_get_flags,  'con_get_flags'
390
 
391
 
392
i_end:
393
 
394
active_passive  db ?
395
socketnum       dd ?
396
datasocket      dd ?
397
buffer_ptr      rb 2*BUFFERSIZE
398
status          db ?
399
offset          dd ?
400
 
401
s       rb      1024
402
 
403
mem: