Subversion Repositories Kolibri OS

Rev

Rev 3789 | Rev 3792 | 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
BUFFERSIZE              = 1024
18
 
19
STATUS_CONNECTING       = 0
20
STATUS_CONNECTED        = 1
21
STATUS_NEEDPASSWORD     = 2
22
STATUS_LOGGED_IN        = 3
23
 
24
use32
25
; standard header
26
        db      'MENUET01'      ; signature
27
        dd      1               ; header version
28
        dd      start           ; entry point
29
        dd      i_end           ; initialized size
30
        dd      mem+0x1000      ; required memory
31
        dd      mem+0x1000      ; stack pointer
32
        dd      s               ; parameters
33
        dd      0               ; path
34
 
35
include '../../macros.inc'
36
purge mov,add,sub
37
include '../../proc32.inc'
38
include '../../dll.inc'
39
include '../../network.inc'
40
 
41
include 'usercommands.inc'
42
include 'servercommands.inc'
43
 
44
; entry point
45
start:
46
 
3789 hidnplayr 47
        mcall   40, 0
3701 hidnplayr 48
; load libraries
49
        stdcall dll.Load, @IMPORT
50
        test    eax, eax
51
        jnz     exit
52
; initialize console
3789 hidnplayr 53
        invoke  con_start, 1
54
        invoke  con_init, 80, 25, 80, 25, title
3701 hidnplayr 55
 
56
; Check for parameters
57
        cmp     byte [s], 0
58
        jne     resolve
59
 
60
main:
3789 hidnplayr 61
        invoke  con_cls
3701 hidnplayr 62
; Welcome user
3789 hidnplayr 63
        invoke  con_write_asciiz, str1
3701 hidnplayr 64
 
65
; write prompt
3789 hidnplayr 66
        invoke  con_set_flags, 0x0a
67
        invoke  con_write_asciiz, str2
3701 hidnplayr 68
; read string
69
        mov     esi, s
3789 hidnplayr 70
        invoke  con_gets, esi, 256
71
        invoke  con_write_asciiz, str4  ; newline
72
        invoke  con_set_flags, 0x07
3701 hidnplayr 73
; check for exit
74
        test    eax, eax
75
        jz      done
76
        cmp     byte [esi], 10
77
        jz      done
78
 
79
resolve:
80
; delete terminating '\n'
81
        mov     esi, s
82
  @@:
83
        lodsb
84
        cmp     al, 0x20
85
        ja      @r
86
        mov     byte [esi-1], 0
87
 
3789 hidnplayr 88
        invoke  con_write_asciiz, str3
89
        invoke  con_write_asciiz, s
3701 hidnplayr 90
 
91
; resolve name
92
        push    esp     ; reserve stack place
3789 hidnplayr 93
        invoke  getaddrinfo, s, 0, 0, esp
3701 hidnplayr 94
        pop     esi
95
; test for error
96
        test    eax, eax
97
        jnz     fail
98
 
99
; write results
3789 hidnplayr 100
        invoke  con_write_asciiz, str8
3701 hidnplayr 101
;        mov     edi, esi
102
 
103
; convert IP address to decimal notation
104
        mov     eax, [esi+addrinfo.ai_addr]
105
        mov     eax, [eax+sockaddr_in.sin_addr]
106
        mov     [sockaddr1.ip], eax
3789 hidnplayr 107
 
108
        invoke  inet_ntoa, eax
3701 hidnplayr 109
; write result
3789 hidnplayr 110
        invoke  con_write_asciiz, eax
3701 hidnplayr 111
; free allocated memory
3789 hidnplayr 112
        invoke  freeaddrinfo, esi
3701 hidnplayr 113
 
3789 hidnplayr 114
        invoke  con_write_asciiz, str9
3701 hidnplayr 115
        mcall   socket, AF_INET4, SOCK_STREAM, 0
116
        cmp     eax, -1
3789 hidnplayr 117
        je      socket_error
3701 hidnplayr 118
        mov     [socketnum], eax
119
 
3789 hidnplayr 120
        invoke  con_write_asciiz, str11
3701 hidnplayr 121
        mcall   connect, [socketnum], sockaddr1, 18
122
        mov     [status], STATUS_CONNECTING
123
 
3789 hidnplayr 124
        invoke  con_write_asciiz, str12
3701 hidnplayr 125
 
3790 hidnplayr 126
        mov     [offset], 0
127
 
3789 hidnplayr 128
wait_for_servercommand:
3701 hidnplayr 129
 
3790 hidnplayr 130
        cmp     [offset], 0
131
        je      .receive
132
        mov     esi, [offset]
133
        mov     edi, s
134
        mov     ecx, [size]
135
        add     ecx, esi
136
        jmp     .byteloop
3701 hidnplayr 137
 
138
; receive socket data
3790 hidnplayr 139
  .receive:
3789 hidnplayr 140
        mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
3701 hidnplayr 141
        inc     eax
3789 hidnplayr 142
        jz      socket_error
3701 hidnplayr 143
        dec     eax
3789 hidnplayr 144
        jz      wait_for_servercommand
3701 hidnplayr 145
 
3790 hidnplayr 146
        mov     [offset], 0
3789 hidnplayr 147
 
3701 hidnplayr 148
; extract commands, copy them to "s" buffer
3789 hidnplayr 149
        lea     ecx, [eax + buffer_ptr]         ; ecx = end pointer
3701 hidnplayr 150
        mov     esi, buffer_ptr                 ; esi = current pointer
151
        mov     edi, s
152
  .byteloop:
3789 hidnplayr 153
        cmp     esi, ecx
154
        jae     wait_for_servercommand
3701 hidnplayr 155
        lodsb
156
        cmp     al, 10                          ; excellent, we might have a command
157
        je      .got_command
3789 hidnplayr 158
        cmp     al, 13                          ; just ignore this byte
3701 hidnplayr 159
        je      .byteloop
160
        stosb
161
        jmp     .byteloop
3789 hidnplayr 162
  .got_command:                                 ; we have a newline check if its a command
3790 hidnplayr 163
        cmp     esi, ecx
164
        je      .no_more_data
165
        mov     [offset], esi
166
        sub     ecx, esi
167
        mov     [size], ecx
168
        jmp     .go_cmd
169
  .no_more_data:
170
        mov     [offset], 0
171
  .go_cmd:
3701 hidnplayr 172
        xor     al, al
173
        stosb
174
 
3789 hidnplayr 175
        invoke  con_set_flags, 0x03             ; change color
176
        invoke  con_write_asciiz, s             ; print servercommand
177
        invoke  con_write_asciiz, str4          ; newline
178
        invoke  con_set_flags, 0x07
3701 hidnplayr 179
 
3789 hidnplayr 180
        jmp     server_parser                   ; parse command
3701 hidnplayr 181
 
3789 hidnplayr 182
wait_for_usercommand:
3701 hidnplayr 183
 
3789 hidnplayr 184
        invoke  con_set_flags, 0x0a
3701 hidnplayr 185
 
186
        cmp     [status], STATUS_CONNECTED
187
        je      .connected
188
 
189
        cmp     [status], STATUS_NEEDPASSWORD
190
        je      .needpass
191
 
192
; write prompt
3789 hidnplayr 193
        invoke  con_write_asciiz, str2
3701 hidnplayr 194
; read string
195
        mov     esi, s
3789 hidnplayr 196
        invoke  con_gets, esi, 256
197
        invoke  con_set_flags, 0x07
3701 hidnplayr 198
 
199
        cmp     dword[s], "list"
200
        je      cmd_list
201
 
202
        cmp     dword[s], "help"
203
        je      cmd_help
204
 
3790 hidnplayr 205
        cmp     dword[s], "cwd "
206
        je      cmd_cwd
207
 
3789 hidnplayr 208
        invoke  con_write_asciiz, str_unknown
3701 hidnplayr 209
        jmp     wait_for_usercommand
210
 
211
 
212
  .connected:
213
 
3789 hidnplayr 214
        invoke  con_write_asciiz, str_user
3701 hidnplayr 215
        mov     dword[s], "USER"
216
        mov     byte[s+4], " "
217
        jmp     .send
218
 
219
 
220
  .needpass:
221
 
3789 hidnplayr 222
        invoke  con_write_asciiz, str_pass
3701 hidnplayr 223
        mov     dword[s], "PASS"
224
        mov     byte[s+4], " "
225
 
226
  .send:
227
; read string
228
        mov     esi, s+5
3789 hidnplayr 229
        invoke  con_gets, esi, 256
3701 hidnplayr 230
 
231
        mov     edi, s+5
232
        mov     ecx, 256
233
        xor     al, al
234
        repne   scasb
235
        lea     esi, [edi-s-1]
3789 hidnplayr 236
        mcall   send, [socketnum], s, , 0
3701 hidnplayr 237
 
3789 hidnplayr 238
        invoke  con_write_asciiz, str4  ; newline
239
        invoke  con_set_flags, 0x07
240
        jmp     wait_for_servercommand
3701 hidnplayr 241
 
242
 
243
 
244
open_dataconnection:
245
        cmp     [status], STATUS_LOGGED_IN
246
        jne     .fail
247
 
248
        mov     dword[s], "PASV"
249
        mov     byte[s+4], 10
3789 hidnplayr 250
        mcall   send, [socketnum], s, 5, 0
3701 hidnplayr 251
        ret
252
 
253
  .fail:
3789 hidnplayr 254
        invoke  con_write_asciiz, str6
3701 hidnplayr 255
        ret
256
 
257
 
258
 
3789 hidnplayr 259
socket_error:
260
        invoke  con_write_asciiz, str6
3701 hidnplayr 261
        jmp     fail.wait
262
 
263
fail:
3789 hidnplayr 264
        invoke  con_write_asciiz, str5
3701 hidnplayr 265
  .wait:
3789 hidnplayr 266
        invoke  con_write_asciiz, str10
267
        invoke  con_getch2
3701 hidnplayr 268
        jmp     main
269
 
270
done:
3789 hidnplayr 271
        invoke  con_exit, 1
272
 
3701 hidnplayr 273
exit:
274
        mcall   close, [socketnum]
275
        mcall   -1
276
 
277
 
278
 
279
; data
280
title   db 'FTP client',0
3789 hidnplayr 281
str1    db 'FTP client for KolibriOS v0.02',10,10,'Please enter ftp server address.',10,0
3701 hidnplayr 282
str2    db '> ',0
283
str3    db 'Resolving ',0
284
str4    db 10,0
285
str5    db 10,'Name resolution failed.',10,0
286
str6    db 10,'Socket error.',10,0
287
str8    db ' (',0
288
str9    db ')',10,0
289
str10   db 'Push any key to continue.',0
3789 hidnplayr 290
str11   db 'Connecting...',10,0
291
str12   db 'Waiting for welcome message.',10,0
3701 hidnplayr 292
str_user db "username: ",0
293
str_pass db "password: ",0
3789 hidnplayr 294
str_unknown db "unknown command",10,0
3701 hidnplayr 295
str_help db "available commands:",10,10
296
         db "help       list",10,0
297
 
298
str_open db "opening data socket",10,0
299
 
300
sockaddr1:
301
        dw AF_INET4
302
.port   dw 0x1500       ; 21
303
.ip     dd 0
304
        rb 10
305
 
306
sockaddr2:
307
        dw AF_INET4
308
.port   dw 0
309
.ip     dd 0
310
        rb 10
311
 
312
 
313
; import
314
align 4
315
@IMPORT:
316
 
317
library network, 'network.obj', console, 'console.obj'
318
 
319
import  network,        \
320
        getaddrinfo,    'getaddrinfo',  \
321
        freeaddrinfo,   'freeaddrinfo', \
322
        inet_ntoa,      'inet_ntoa'
323
 
324
import  console,        \
325
        con_start,      'START',        \
326
        con_init,       'con_init',     \
327
        con_write_asciiz,'con_write_asciiz',     \
328
        con_exit,       'con_exit',     \
329
        con_gets,       'con_gets',\
330
        con_cls,        'con_cls',\
331
        con_getch2,     'con_getch2',\
332
        con_set_cursor_pos, 'con_set_cursor_pos',\
333
        con_write_string, 'con_write_string',\
3789 hidnplayr 334
        con_get_flags,  'con_get_flags', \
335
        con_set_flags,  'con_set_flags'
3701 hidnplayr 336
 
337
 
338
i_end:
339
 
340
active_passive  db ?
341
socketnum       dd ?
342
datasocket      dd ?
3790 hidnplayr 343
buffer_ptr      rb BUFFERSIZE
344
buffer_ptr2     rb BUFFERSIZE
3701 hidnplayr 345
status          db ?
3790 hidnplayr 346
offset          dd ?
347
size            dd ?
3701 hidnplayr 348
 
3790 hidnplayr 349
s               rb 1024
3701 hidnplayr 350
 
351
mem: