Rev 4920 | Rev 5011 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3701 | hidnplayr | 1 | server_parser: |
2 | |||
3 | ; Commands are always 3 numbers and followed by a space |
||
4 | ; If a server decides it needs multiline output, |
||
5 | ; first lines will have a dash instead of space after numbers, |
||
3789 | hidnplayr | 6 | ; thus they are simply ignored in this simple command parser. |
3701 | hidnplayr | 7 | |
4922 | ashmew2 | 8 | cmp dword[buf_cmd], "150 " |
4920 | hidnplayr | 9 | je data_loop |
3701 | hidnplayr | 10 | |
4922 | ashmew2 | 11 | cmp dword[buf_cmd], "220 " |
3701 | hidnplayr | 12 | je welcome |
13 | |||
4922 | ashmew2 | 14 | ; cmp dword[buf_cmd], "226 " |
3967 | hidnplayr | 15 | ; je transfer_ok |
3789 | hidnplayr | 16 | |
4922 | ashmew2 | 17 | cmp dword[buf_cmd], "227 " |
3701 | hidnplayr | 18 | je pasv_ok |
19 | |||
4922 | ashmew2 | 20 | cmp dword[buf_cmd], "230 " |
3701 | hidnplayr | 21 | je login_ok |
22 | |||
4922 | ashmew2 | 23 | ; cmp dword[buf_cmd], "250" |
3800 | hidnplayr | 24 | ; je op_ok |
3790 | hidnplayr | 25 | |
4922 | ashmew2 | 26 | cmp dword[buf_cmd], "331 " |
3701 | hidnplayr | 27 | je pass |
28 | |||
4922 | ashmew2 | 29 | ; cmp dword[buf_cmd], "421 " |
3789 | hidnplayr | 30 | ; je timeout |
3701 | hidnplayr | 31 | |
4922 | ashmew2 | 32 | cmp dword[buf_cmd], "503 " ; login first |
3818 | hidnplayr | 33 | je welcome |
34 | |||
4922 | ashmew2 | 35 | cmp dword[buf_cmd], "530 " ; password incorrect |
3789 | hidnplayr | 36 | je welcome |
3701 | hidnplayr | 37 | |
4922 | ashmew2 | 38 | cmp dword[buf_cmd], "550 " |
3800 | hidnplayr | 39 | je close_datacon |
40 | |||
4922 | ashmew2 | 41 | cmp byte[buf_cmd+3], "-" |
4729 | hidnplayr | 42 | je wait_for_servercommand |
3789 | hidnplayr | 43 | jmp wait_for_usercommand |
44 | |||
45 | |||
3701 | hidnplayr | 46 | welcome: |
47 | |||
48 | mov [status], STATUS_CONNECTED |
||
3789 | hidnplayr | 49 | jmp wait_for_usercommand |
3701 | hidnplayr | 50 | |
51 | |||
52 | pass: |
||
53 | |||
54 | mov [status], STATUS_NEEDPASSWORD |
||
3789 | hidnplayr | 55 | jmp wait_for_usercommand |
3701 | hidnplayr | 56 | |
57 | |||
58 | login_ok: |
||
59 | |||
60 | mov [status], STATUS_LOGGED_IN |
||
3789 | hidnplayr | 61 | jmp wait_for_usercommand |
3701 | hidnplayr | 62 | |
63 | |||
64 | pasv_ok: |
||
65 | |||
3818 | hidnplayr | 66 | sub ecx, 4 |
3701 | hidnplayr | 67 | jb .fail |
68 | mov al, "(" |
||
4922 | ashmew2 | 69 | mov edi, buf_cmd + 4 |
3701 | hidnplayr | 70 | repne scasb |
71 | |||
72 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
||
73 | cmp eax, -1 |
||
3813 | hidnplayr | 74 | je error_socket |
3701 | hidnplayr | 75 | mov [datasocket], eax |
76 | |||
77 | mov esi, edi |
||
78 | call ascii_dec |
||
79 | mov byte[sockaddr2.ip+0], bl |
||
80 | call ascii_dec |
||
81 | mov byte[sockaddr2.ip+1], bl |
||
82 | call ascii_dec |
||
83 | mov byte[sockaddr2.ip+2], bl |
||
84 | call ascii_dec |
||
85 | mov byte[sockaddr2.ip+3], bl |
||
86 | |||
87 | call ascii_dec |
||
3789 | hidnplayr | 88 | mov byte[sockaddr2.port+0], bl |
89 | call ascii_dec |
||
3701 | hidnplayr | 90 | mov byte[sockaddr2.port+1], bl |
91 | |||
3789 | hidnplayr | 92 | invoke con_write_asciiz, str_open |
3701 | hidnplayr | 93 | mcall connect, [datasocket], sockaddr2, 18 |
3818 | hidnplayr | 94 | ; cmp eax, -1 |
95 | ; je error_socket |
||
96 | jmp wait_for_servercommand |
||
3701 | hidnplayr | 97 | |
98 | .fail: |
||
3818 | hidnplayr | 99 | invoke con_write_asciiz, str_unknown |
3789 | hidnplayr | 100 | jmp wait_for_servercommand |
3701 | hidnplayr | 101 | |
102 | |||
4920 | hidnplayr | 103 | data_loop: |
3701 | hidnplayr | 104 | |
4922 | ashmew2 | 105 | invoke con_write_asciiz, str_dot |
3967 | hidnplayr | 106 | |
3800 | hidnplayr | 107 | cmp [operation], OPERATION_STOR |
108 | je .stor |
||
109 | |||
110 | ; we are receiving data |
||
4922 | ashmew2 | 111 | mcall recv, [datasocket], buf_buffer2, BUFFERSIZE, 0 |
3792 | hidnplayr | 112 | test ebx, ebx |
3800 | hidnplayr | 113 | jnz .done |
4922 | ashmew2 | 114 | mov byte[buf_buffer2 + eax], 0 |
3701 | hidnplayr | 115 | |
3800 | hidnplayr | 116 | cmp [operation], OPERATION_RETR |
117 | je .retr |
||
118 | |||
4922 | ashmew2 | 119 | cmp [operation], OPERATION_RDIR |
120 | je .rdir |
||
121 | |||
3800 | hidnplayr | 122 | ; not retreiving, just print to console |
4922 | ashmew2 | 123 | invoke con_write_asciiz, buf_buffer2 |
4920 | hidnplayr | 124 | jmp data_loop |
3789 | hidnplayr | 125 | |
3800 | hidnplayr | 126 | ; retreiving, save to file |
127 | .retr: |
||
4922 | ashmew2 | 128 | mov [filestruct.ptr], buf_buffer2 |
3800 | hidnplayr | 129 | mov [filestruct.size], eax |
130 | push eax |
||
131 | mcall 70, filestruct |
||
132 | pop eax |
||
133 | add [filestruct.offset], eax |
||
4920 | hidnplayr | 134 | jmp data_loop |
3792 | hidnplayr | 135 | |
3800 | hidnplayr | 136 | ; storing, send all data |
137 | .stor: |
||
138 | mcall 70, filestruct |
||
139 | cmp eax, 6 ; end of file |
||
140 | je .last_call |
||
141 | test eax, eax ; error |
||
142 | ; jne .fileerror |
||
143 | add [filestruct.offset], ebx |
||
144 | mov esi, ebx |
||
4922 | ashmew2 | 145 | mcall send, [datasocket], buf_buffer2, , 0 |
3800 | hidnplayr | 146 | jmp .stor |
147 | |||
148 | .last_call: |
||
149 | mov esi, ebx |
||
4922 | ashmew2 | 150 | mcall send, [datasocket], buf_buffer2, , 0 |
3800 | hidnplayr | 151 | |
152 | .done: |
||
3967 | hidnplayr | 153 | invoke con_write_asciiz, str_close |
3789 | hidnplayr | 154 | mcall close, [datasocket] |
4920 | hidnplayr | 155 | mov [operation], OPERATION_NONE |
3789 | hidnplayr | 156 | jmp wait_for_servercommand |
3701 | hidnplayr | 157 | |
158 | |||
4922 | ashmew2 | 159 | .rdir: |
160 | cmp [size_fname], 0 |
||
161 | jne .realloc |
||
162 | |||
163 | .malloc: ; create a new dynamic block |
||
164 | mov ecx, eax |
||
165 | inc ecx |
||
166 | |||
167 | mcall 68,12 ; eax now points to new buffer |
||
168 | |||
169 | test eax,eax |
||
170 | je error_heap |
||
171 | |||
172 | mov [ptr_fname_start], eax |
||
173 | |||
174 | jmp .rdir_init |
||
175 | |||
176 | .realloc: ; expand block created with .malloc |
||
177 | |||
178 | mov ecx, eax ; eax is size of buffer received |
||
179 | inc ecx |
||
180 | |||
181 | add ecx, [size_fname] ; added old size to form new required size |
||
182 | |||
183 | mcall 68,20,,[ptr_fname_start] |
||
184 | |||
185 | test eax, eax |
||
186 | je error_heap |
||
187 | |||
188 | mov [ptr_fname_start], eax ; eax contains the new block now |
||
189 | add eax, [size_fname] |
||
190 | |||
191 | .rdir_init: ; copies filenames into our buffer |
||
192 | |||
193 | mov esi, buf_buffer2 |
||
194 | mov edi, eax |
||
195 | |||
196 | .copy_buf: |
||
197 | lodsb |
||
198 | cmp al,13 ; ignore any \r character |
||
199 | je .copy_buf |
||
200 | stosb |
||
201 | |||
202 | cmp al, 10 |
||
203 | jne .not_end |
||
204 | inc [queued] |
||
205 | |||
206 | .not_end: |
||
207 | test al,al |
||
208 | jne .copy_buf |
||
209 | |||
210 | dec edi |
||
211 | dec edi |
||
212 | |||
213 | mov eax, [ptr_fname_start] |
||
214 | mov [ptr_queue], eax |
||
215 | |||
216 | sub edi, eax ; edi contains the current size now |
||
217 | mov [size_fname], edi |
||
218 | |||
219 | jmp data_loop |
||
220 | |||
221 | |||
222 | ; files for rdir operation are queued |
||
223 | transfer_queued: |
||
224 | |||
225 | mov esi, [ptr_queue] ; always pointing to current part of ptr_fname_start |
||
226 | mov edi, buf_cmd+5 ; always point to filename for retr command |
||
227 | |||
228 | .build_filename: |
||
229 | lodsb |
||
230 | stosb |
||
231 | |||
232 | cmp al,10 |
||
233 | je .get_file ; filename ends with character 10 |
||
234 | test al,al |
||
235 | jz .null_found ; this should be end of buffer |
||
236 | jmp .build_filename |
||
237 | |||
238 | .null_found: |
||
239 | |||
240 | mov [queued],0 |
||
241 | jmp .free |
||
242 | |||
243 | .get_file: |
||
244 | dec [queued] |
||
245 | jnz .after_free |
||
246 | |||
247 | .free: |
||
248 | mcall 68,13,[ptr_fname_start] ; freeing the buffer |
||
249 | test eax,eax |
||
250 | jz error_heap |
||
251 | jmp wait_for_usercommand |
||
252 | |||
253 | .after_free: |
||
254 | xor al,al ; appending 0 after retr command |
||
255 | stosb |
||
256 | mov eax, esi |
||
257 | mov [ptr_queue], eax |
||
258 | |||
259 | jmp cmd_retr |
||
260 | |||
3800 | hidnplayr | 261 | close_datacon: |
4920 | hidnplayr | 262 | cmp [operation], OPERATION_NONE |
263 | je wait_for_usercommand |
||
3967 | hidnplayr | 264 | invoke con_write_asciiz, str_close |
3800 | hidnplayr | 265 | mcall close, [datasocket] |
266 | jmp wait_for_usercommand |
||
267 | |||
268 | |||
269 | |||
3701 | hidnplayr | 270 | ascii_dec: |
271 | |||
272 | xor ebx, ebx |
||
3789 | hidnplayr | 273 | mov cl, 4 ; max length is 3 digits + 1 separator |
3701 | hidnplayr | 274 | .loop: |
275 | lodsb |
||
276 | sub al, '0' |
||
277 | jb .done |
||
278 | cmp al, 9 |
||
279 | ja .done |
||
3789 | hidnplayr | 280 | lea ebx, [ebx*4+ebx] ; ebx *5 |
281 | shl ebx, 1 ; ebx *2 |
||
3701 | hidnplayr | 282 | add bl, al |
283 | dec cl |
||
284 | jnz .loop |
||
285 | |||
286 | .done: |
||
287 | ret |