Rev 4920 | Rev 5011 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4920 | Rev 4922 | ||
---|---|---|---|
1 | server_parser: |
1 | server_parser: |
2 | 2 | ||
3 | ; Commands are always 3 numbers and followed by a space |
3 | ; Commands are always 3 numbers and followed by a space |
4 | ; If a server decides it needs multiline output, |
4 | ; If a server decides it needs multiline output, |
5 | ; first lines will have a dash instead of space after numbers, |
5 | ; first lines will have a dash instead of space after numbers, |
6 | ; thus they are simply ignored in this simple command parser. |
6 | ; thus they are simply ignored in this simple command parser. |
7 | 7 | ||
8 | cmp dword[s], "150 " |
8 | cmp dword[buf_cmd], "150 " |
9 | je data_loop |
9 | je data_loop |
10 | 10 | ||
11 | cmp dword[s], "220 " |
11 | cmp dword[buf_cmd], "220 " |
12 | je welcome |
12 | je welcome |
13 | 13 | ||
14 | ; cmp dword[s], "226 " |
14 | ; cmp dword[buf_cmd], "226 " |
15 | ; je transfer_ok |
15 | ; je transfer_ok |
16 | 16 | ||
17 | cmp dword[s], "227 " |
17 | cmp dword[buf_cmd], "227 " |
18 | je pasv_ok |
18 | je pasv_ok |
19 | 19 | ||
20 | cmp dword[s], "230 " |
20 | cmp dword[buf_cmd], "230 " |
21 | je login_ok |
21 | je login_ok |
22 | 22 | ||
23 | ; cmp dword[s], "250" |
23 | ; cmp dword[buf_cmd], "250" |
24 | ; je op_ok |
24 | ; je op_ok |
25 | 25 | ||
26 | cmp dword[s], "331 " |
26 | cmp dword[buf_cmd], "331 " |
27 | je pass |
27 | je pass |
28 | 28 | ||
29 | ; cmp dword[s], "421 " |
29 | ; cmp dword[buf_cmd], "421 " |
30 | ; je timeout |
30 | ; je timeout |
31 | 31 | ||
32 | cmp dword[s], "503 " ; login first |
32 | cmp dword[buf_cmd], "503 " ; login first |
33 | je welcome |
33 | je welcome |
34 | 34 | ||
35 | cmp dword[s], "530 " ; password incorrect |
35 | cmp dword[buf_cmd], "530 " ; password incorrect |
36 | je welcome |
36 | je welcome |
37 | 37 | ||
38 | cmp dword[s], "550 " |
38 | cmp dword[buf_cmd], "550 " |
39 | je close_datacon |
39 | je close_datacon |
40 | 40 | ||
41 | cmp byte[s+3], "-" |
41 | cmp byte[buf_cmd+3], "-" |
42 | je wait_for_servercommand |
42 | je wait_for_servercommand |
43 | jmp wait_for_usercommand |
43 | jmp wait_for_usercommand |
44 | 44 | ||
45 | 45 | ||
46 | welcome: |
46 | welcome: |
47 | 47 | ||
48 | mov [status], STATUS_CONNECTED |
48 | mov [status], STATUS_CONNECTED |
49 | jmp wait_for_usercommand |
49 | jmp wait_for_usercommand |
50 | 50 | ||
51 | 51 | ||
52 | pass: |
52 | pass: |
53 | 53 | ||
54 | mov [status], STATUS_NEEDPASSWORD |
54 | mov [status], STATUS_NEEDPASSWORD |
55 | jmp wait_for_usercommand |
55 | jmp wait_for_usercommand |
56 | 56 | ||
57 | 57 | ||
58 | login_ok: |
58 | login_ok: |
59 | 59 | ||
60 | mov [status], STATUS_LOGGED_IN |
60 | mov [status], STATUS_LOGGED_IN |
61 | jmp wait_for_usercommand |
61 | jmp wait_for_usercommand |
62 | 62 | ||
63 | 63 | ||
64 | pasv_ok: |
64 | pasv_ok: |
65 | 65 | ||
66 | sub ecx, 4 |
66 | sub ecx, 4 |
67 | jb .fail |
67 | jb .fail |
68 | mov al, "(" |
68 | mov al, "(" |
69 | mov edi, s + 4 |
69 | mov edi, buf_cmd + 4 |
70 | repne scasb |
70 | repne scasb |
71 | 71 | ||
72 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
72 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
73 | cmp eax, -1 |
73 | cmp eax, -1 |
74 | je error_socket |
74 | je error_socket |
75 | mov [datasocket], eax |
75 | mov [datasocket], eax |
76 | 76 | ||
77 | mov esi, edi |
77 | mov esi, edi |
78 | call ascii_dec |
78 | call ascii_dec |
79 | mov byte[sockaddr2.ip+0], bl |
79 | mov byte[sockaddr2.ip+0], bl |
80 | call ascii_dec |
80 | call ascii_dec |
81 | mov byte[sockaddr2.ip+1], bl |
81 | mov byte[sockaddr2.ip+1], bl |
82 | call ascii_dec |
82 | call ascii_dec |
83 | mov byte[sockaddr2.ip+2], bl |
83 | mov byte[sockaddr2.ip+2], bl |
84 | call ascii_dec |
84 | call ascii_dec |
85 | mov byte[sockaddr2.ip+3], bl |
85 | mov byte[sockaddr2.ip+3], bl |
86 | 86 | ||
87 | call ascii_dec |
87 | call ascii_dec |
88 | mov byte[sockaddr2.port+0], bl |
88 | mov byte[sockaddr2.port+0], bl |
89 | call ascii_dec |
89 | call ascii_dec |
90 | mov byte[sockaddr2.port+1], bl |
90 | mov byte[sockaddr2.port+1], bl |
91 | 91 | ||
92 | invoke con_write_asciiz, str_open |
92 | invoke con_write_asciiz, str_open |
93 | mcall connect, [datasocket], sockaddr2, 18 |
93 | mcall connect, [datasocket], sockaddr2, 18 |
94 | ; cmp eax, -1 |
94 | ; cmp eax, -1 |
95 | ; je error_socket |
95 | ; je error_socket |
96 | jmp wait_for_servercommand |
96 | jmp wait_for_servercommand |
97 | 97 | ||
98 | .fail: |
98 | .fail: |
99 | invoke con_write_asciiz, str_unknown |
99 | invoke con_write_asciiz, str_unknown |
100 | jmp wait_for_servercommand |
100 | jmp wait_for_servercommand |
101 | 101 | ||
102 | 102 | ||
103 | data_loop: |
103 | data_loop: |
104 | 104 | ||
105 | invoke con_write_asciiz, str2b |
105 | invoke con_write_asciiz, str_dot |
106 | 106 | ||
107 | cmp [operation], OPERATION_STOR |
107 | cmp [operation], OPERATION_STOR |
108 | je .stor |
108 | je .stor |
109 | 109 | ||
110 | ; we are receiving data |
110 | ; we are receiving data |
111 | mcall recv, [datasocket], buffer_ptr2, BUFFERSIZE, 0 |
111 | mcall recv, [datasocket], buf_buffer2, BUFFERSIZE, 0 |
112 | test ebx, ebx |
112 | test ebx, ebx |
113 | jnz .done |
113 | jnz .done |
114 | mov byte[buffer_ptr2 + eax], 0 |
114 | mov byte[buf_buffer2 + eax], 0 |
115 | 115 | ||
116 | cmp [operation], OPERATION_RETR |
116 | cmp [operation], OPERATION_RETR |
117 | je .retr |
117 | je .retr |
- | 118 | ||
- | 119 | cmp [operation], OPERATION_RDIR |
|
- | 120 | je .rdir |
|
118 | 121 | ||
119 | ; not retreiving, just print to console |
122 | ; not retreiving, just print to console |
120 | invoke con_write_asciiz, buffer_ptr2 |
123 | invoke con_write_asciiz, buf_buffer2 |
121 | jmp data_loop |
124 | jmp data_loop |
122 | 125 | ||
123 | ; retreiving, save to file |
126 | ; retreiving, save to file |
124 | .retr: |
127 | .retr: |
125 | mov [filestruct.ptr], buffer_ptr2 |
128 | mov [filestruct.ptr], buf_buffer2 |
126 | mov [filestruct.size], eax |
129 | mov [filestruct.size], eax |
127 | push eax |
130 | push eax |
128 | mcall 70, filestruct |
131 | mcall 70, filestruct |
129 | pop eax |
132 | pop eax |
130 | add [filestruct.offset], eax |
133 | add [filestruct.offset], eax |
131 | jmp data_loop |
134 | jmp data_loop |
132 | 135 | ||
133 | ; storing, send all data |
136 | ; storing, send all data |
134 | .stor: |
137 | .stor: |
135 | mcall 70, filestruct |
138 | mcall 70, filestruct |
136 | cmp eax, 6 ; end of file |
139 | cmp eax, 6 ; end of file |
137 | je .last_call |
140 | je .last_call |
138 | test eax, eax ; error |
141 | test eax, eax ; error |
139 | ; jne .fileerror |
142 | ; jne .fileerror |
140 | add [filestruct.offset], ebx |
143 | add [filestruct.offset], ebx |
141 | mov esi, ebx |
144 | mov esi, ebx |
142 | mcall send, [datasocket], buffer_ptr2, , 0 |
145 | mcall send, [datasocket], buf_buffer2, , 0 |
143 | jmp .stor |
146 | jmp .stor |
144 | 147 | ||
145 | .last_call: |
148 | .last_call: |
146 | mov esi, ebx |
149 | mov esi, ebx |
147 | mcall send, [datasocket], buffer_ptr2, , 0 |
150 | mcall send, [datasocket], buf_buffer2, , 0 |
148 | 151 | ||
149 | .done: |
152 | .done: |
150 | invoke con_write_asciiz, str_close |
153 | invoke con_write_asciiz, str_close |
151 | mcall close, [datasocket] |
154 | mcall close, [datasocket] |
152 | mov [operation], OPERATION_NONE |
155 | mov [operation], OPERATION_NONE |
153 | jmp wait_for_servercommand |
156 | jmp wait_for_servercommand |
154 | 157 | ||
- | 158 | ||
- | 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 |
|
155 | 260 | ||
156 | close_datacon: |
261 | close_datacon: |
157 | cmp [operation], OPERATION_NONE |
262 | cmp [operation], OPERATION_NONE |
158 | je wait_for_usercommand |
263 | je wait_for_usercommand |
159 | invoke con_write_asciiz, str_close |
264 | invoke con_write_asciiz, str_close |
160 | mcall close, [datasocket] |
265 | mcall close, [datasocket] |
161 | jmp wait_for_usercommand |
266 | jmp wait_for_usercommand |
162 | 267 | ||
163 | 268 | ||
164 | 269 | ||
165 | ascii_dec: |
270 | ascii_dec: |
166 | 271 | ||
167 | xor ebx, ebx |
272 | xor ebx, ebx |
168 | mov cl, 4 ; max length is 3 digits + 1 separator |
273 | mov cl, 4 ; max length is 3 digits + 1 separator |
169 | .loop: |
274 | .loop: |
170 | lodsb |
275 | lodsb |
171 | sub al, '0' |
276 | sub al, '0' |
172 | jb .done |
277 | jb .done |
173 | cmp al, 9 |
278 | cmp al, 9 |
174 | ja .done |
279 | ja .done |
175 | lea ebx, [ebx*4+ebx] ; ebx *5 |
280 | lea ebx, [ebx*4+ebx] ; ebx *5 |
176 | shl ebx, 1 ; ebx *2 |
281 | shl ebx, 1 ; ebx *2 |
177 | add bl, al |
282 | add bl, al |
178 | dec cl |
283 | dec cl |
179 | jnz .loop |
284 | jnz .loop |
180 | 285 | ||
181 | .done: |
286 | .done: |
182 | ret |
287 | ret |