1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Duo Component                                                    */
16 /**                                                                       */
17 /**   File Transfer Protocol (FTP)                                        */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_FTP_SOURCE_CODE
23 
24 
25 /* Force error checking to be disabled in this module */
26 
27 #ifndef NX_DISABLE_ERROR_CHECKING
28 #define NX_DISABLE_ERROR_CHECKING
29 #endif
30 
31 /* If FileX is not used in your application, define this option.  Then define the
32    services declared in filex_stub.h elsewhere.
33 #define      NX_FTP_NO_FILEX
34 */
35 
36 /* Include necessary system files.  */
37 
38 #include    "nx_api.h"
39 #include    "nx_ip.h"
40 #ifdef FEATURE_NX_IPV6
41 #include    "nx_ipv6.h"
42 #endif /* FEATURE_NX_IPV6  */
43 #include    "nxd_ftp_client.h"
44 #include    "stdio.h"
45 #include    "string.h"
46 
47 
48 
49 /* Bring in externs for caller checking code.  */
50 
51 NX_CALLER_CHECKING_EXTERNS
52 
53 
54 /**************************************************************************/
55 /*                                                                        */
56 /*  FUNCTION                                               RELEASE        */
57 /*                                                                        */
58 /*    _nxe_ftp_client_connect                             PORTABLE C      */
59 /*                                                           6.1          */
60 /*  AUTHOR                                                                */
61 /*                                                                        */
62 /*    Yuxin Zhou, Microsoft Corporation                                   */
63 /*                                                                        */
64 /*  DESCRIPTION                                                           */
65 /*                                                                        */
66 /*    This function checks for errors in the FTP client connect call.     */
67 /*                                                                        */
68 /*    Note: The string lengths of username and password are limited by    */
69 /*    the packet payload size.                                            */
70 /*                                                                        */
71 /*  INPUT                                                                 */
72 /*                                                                        */
73 /*    ftp_client_ptr                        Pointer to FTP client         */
74 /*    server_ip                             FTP server IPv4 address       */
75 /*    username                              Pointer to login username     */
76 /*    password                              Pointer to login password     */
77 /*    wait_option                           Specifies how long to wait    */
78 /*                                                                        */
79 /*  OUTPUT                                                                */
80 /*                                                                        */
81 /*    status                                Completion status             */
82 /*                                                                        */
83 /*  CALLS                                                                 */
84 /*                                                                        */
85 /*    _nxe_ftp_client_connect               Actual client connect call    */
86 /*                                                                        */
87 /*  CALLED BY                                                             */
88 /*                                                                        */
89 /*    Application Code                                                    */
90 /*                                                                        */
91 /*  RELEASE HISTORY                                                       */
92 /*                                                                        */
93 /*    DATE              NAME                      DESCRIPTION             */
94 /*                                                                        */
95 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
96 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
97 /*                                            resulting in version 6.1    */
98 /*                                                                        */
99 /**************************************************************************/
_nxe_ftp_client_connect(NX_FTP_CLIENT * ftp_client_ptr,ULONG server_ip,CHAR * username,CHAR * password,ULONG wait_option)100 UINT  _nxe_ftp_client_connect(NX_FTP_CLIENT *ftp_client_ptr, ULONG server_ip, CHAR *username,
101                               CHAR *password, ULONG wait_option)
102 {
103 
104 #ifndef NX_DISABLE_IPV4
105 UINT    status;
106 
107 
108     /* Check for invalid input pointers.  */
109     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
110         return(NX_PTR_ERROR);
111 
112     /* Check for an invalid server IP address.  */
113     if (server_ip == 0)
114         return(NX_IP_ADDRESS_ERROR);
115 
116     /* Check for appropriate caller.  */
117     NX_THREADS_ONLY_CALLER_CHECKING
118 
119     /* Call actual client connect function.  */
120     status =  _nx_ftp_client_connect(ftp_client_ptr, server_ip, username, password, wait_option);
121 
122     /* Return completion status.  */
123     return(status);
124 #else
125     NX_PARAMETER_NOT_USED(ftp_client_ptr);
126     NX_PARAMETER_NOT_USED(server_ip);
127     NX_PARAMETER_NOT_USED(username);
128     NX_PARAMETER_NOT_USED(password);
129     NX_PARAMETER_NOT_USED(wait_option);
130 
131     return(NX_NOT_SUPPORTED);
132 #endif /* NX_DISABLE_IPV4 */
133 }
134 
135 
136 /**************************************************************************/
137 /*                                                                        */
138 /*  FUNCTION                                               RELEASE        */
139 /*                                                                        */
140 /*    _nx_ftp_client_connect                              PORTABLE C      */
141 /*                                                           6.1          */
142 /*  AUTHOR                                                                */
143 /*                                                                        */
144 /*    Yuxin Zhou, Microsoft Corporation                                   */
145 /*                                                                        */
146 /*  DESCRIPTION                                                           */
147 /*                                                                        */
148 /*    This function connects a previously created FTP instance with the   */
149 /*    FTP server at the specified IP address.                             */
150 /*                                                                        */
151 /*    Note: The string lengths of username and password are limited by    */
152 /*    the packet payload size.                                            */
153 /*                                                                        */
154 /*  INPUT                                                                 */
155 /*                                                                        */
156 /*    ftp_client_ptr                        Pointer to FTP client         */
157 /*    server_ip                             FTP server IPv4 address       */
158 /*    username                              Pointer to login username     */
159 /*    password                              Pointer to login password     */
160 /*    wait_option                           Specifies how long to wait    */
161 /*                                                                        */
162 /*  OUTPUT                                                                */
163 /*                                                                        */
164 /*    status                                Completion status             */
165 /*                                                                        */
166 /*  CALLS                                                                 */
167 /*                                                                        */
168 /*    _nx_ftp_client_connect_internal       Connect to FTP server using   */
169 /*                                                IP address              */
170 /*                                                                        */
171 /*  CALLED BY                                                             */
172 /*                                                                        */
173 /*    Application Code                                                    */
174 /*                                                                        */
175 /*  RELEASE HISTORY                                                       */
176 /*                                                                        */
177 /*    DATE              NAME                      DESCRIPTION             */
178 /*                                                                        */
179 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
180 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
181 /*                                            resulting in version 6.1    */
182 /*                                                                        */
183 /**************************************************************************/
_nx_ftp_client_connect(NX_FTP_CLIENT * ftp_client_ptr,ULONG server_ip,CHAR * username,CHAR * password,ULONG wait_option)184 UINT  _nx_ftp_client_connect(NX_FTP_CLIENT *ftp_client_ptr, ULONG server_ip, CHAR *username,
185                              CHAR *password, ULONG wait_option)
186 {
187 
188 #ifndef NX_DISABLE_IPV4
189 NXD_ADDRESS server_ipduo;
190 
191     /* Construct an IP address structure, and fill in IPv4 address information. */
192     server_ipduo.nxd_ip_version = NX_IP_VERSION_V4;
193     server_ipduo.nxd_ip_address.v4 = server_ip;
194 
195 
196     /* Invoke the real connection call. */
197     return (_nx_ftp_client_connect_internal(ftp_client_ptr, &server_ipduo, username, password, wait_option));
198 #else
199     NX_PARAMETER_NOT_USED(ftp_client_ptr);
200     NX_PARAMETER_NOT_USED(server_ip);
201     NX_PARAMETER_NOT_USED(username);
202     NX_PARAMETER_NOT_USED(password);
203     NX_PARAMETER_NOT_USED(wait_option);
204 
205     return(NX_NOT_SUPPORTED);
206 #endif /* NX_DISABLE_IPV4 */
207 }
208 
209 
210 /**************************************************************************/
211 /*                                                                        */
212 /*  FUNCTION                                               RELEASE        */
213 /*                                                                        */
214 /*    _nxde_ftp_client_connect                            PORTABLE C      */
215 /*                                                           6.1          */
216 /*  AUTHOR                                                                */
217 /*                                                                        */
218 /*    Yuxin Zhou, Microsoft Corporation                                   */
219 /*                                                                        */
220 /*  DESCRIPTION                                                           */
221 /*                                                                        */
222 /*    This function checks for errors in the FTP client connect call.     */
223 /*                                                                        */
224 /*    Note: The string lengths of username and password are limited by    */
225 /*    the packet payload size.                                            */
226 /*                                                                        */
227 /*  INPUT                                                                 */
228 /*                                                                        */
229 /*    ftp_client_ptr                        Pointer to FTP client         */
230 /*    server_ip                             FTP server IP address         */
231 /*    username                              Pointer to login username     */
232 /*    password                              Pointer to login password     */
233 /*    wait_option                           Specifies how long to wait    */
234 /*                                                                        */
235 /*  OUTPUT                                                                */
236 /*                                                                        */
237 /*    status                                Completion status             */
238 /*                                                                        */
239 /*  CALLS                                                                 */
240 /*                                                                        */
241 /*    _nxe_ftp_client_connect               Actual client connect call    */
242 /*                                                                        */
243 /*  CALLED BY                                                             */
244 /*                                                                        */
245 /*    Application Code                                                    */
246 /*                                                                        */
247 /*  RELEASE HISTORY                                                       */
248 /*                                                                        */
249 /*    DATE              NAME                      DESCRIPTION             */
250 /*                                                                        */
251 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
252 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
253 /*                                            resulting in version 6.1    */
254 /*                                                                        */
255 /**************************************************************************/
_nxde_ftp_client_connect(NX_FTP_CLIENT * ftp_client_ptr,NXD_ADDRESS * server_ipduo,CHAR * username,CHAR * password,ULONG wait_option)256 UINT  _nxde_ftp_client_connect(NX_FTP_CLIENT *ftp_client_ptr, NXD_ADDRESS *server_ipduo, CHAR *username,
257                               CHAR *password, ULONG wait_option)
258 {
259 
260 UINT        status;
261 
262 
263     /* Check for invalid input pointers.  */
264     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
265         return(NX_PTR_ERROR);
266 
267     /* Check for an invalid server IP address.  */
268     if (!server_ipduo)
269         return(NX_IP_ADDRESS_ERROR);
270 
271     /* Check for appropriate caller.  */
272     NX_THREADS_ONLY_CALLER_CHECKING
273 
274     /* Call actual client connect function.  */
275     status =  _nxd_ftp_client_connect(ftp_client_ptr, server_ipduo, username, password, wait_option);
276 
277     return status;
278 }
279 
280 
281 /**************************************************************************/
282 /*                                                                        */
283 /*  FUNCTION                                               RELEASE        */
284 /*                                                                        */
285 /*    _nxd_ftp_client_connect                             PORTABLE C      */
286 /*                                                           6.1          */
287 /*  AUTHOR                                                                */
288 /*                                                                        */
289 /*    Yuxin Zhou, Microsoft Corporation                                   */
290 /*                                                                        */
291 /*  DESCRIPTION                                                           */
292 /*                                                                        */
293 /*    This function connects a previously created FTP instance with the   */
294 /*    FTP server at the specified IP address.                             */
295 /*                                                                        */
296 /*    Note: The string lengths of username and password are limited by    */
297 /*    the packet payload size.                                            */
298 /*                                                                        */
299 /*  INPUT                                                                 */
300 /*                                                                        */
301 /*    ftp_client_ptr                        Pointer to FTP client         */
302 /*    server_ip                             FTP server IP duo address     */
303 /*    username                              Pointer to login username     */
304 /*    password                              Pointer to login password     */
305 /*    wait_option                           Specifies how long to wait    */
306 /*                                                                        */
307 /*  OUTPUT                                                                */
308 /*                                                                        */
309 /*    status                                Completion status             */
310 /*                                                                        */
311 /*  CALLS                                                                 */
312 /*                                                                        */
313 /*    _nx_ftp_client_connect_internal       Acutal connect service        */
314 /*                                                                        */
315 /*  CALLED BY                                                             */
316 /*                                                                        */
317 /*    Application Code                                                    */
318 /*                                                                        */
319 /*  RELEASE HISTORY                                                       */
320 /*                                                                        */
321 /*    DATE              NAME                      DESCRIPTION             */
322 /*                                                                        */
323 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
324 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
325 /*                                            resulting in version 6.1    */
326 /*                                                                        */
327 /**************************************************************************/
_nxd_ftp_client_connect(NX_FTP_CLIENT * ftp_client_ptr,NXD_ADDRESS * server_ipduo,CHAR * username,CHAR * password,ULONG wait_option)328 UINT  _nxd_ftp_client_connect(NX_FTP_CLIENT *ftp_client_ptr, NXD_ADDRESS *server_ipduo, CHAR *username,
329                               CHAR *password, ULONG wait_option)
330 {
331 
332     /* Invoke the real connection call. */
333     return (_nx_ftp_client_connect_internal(ftp_client_ptr, server_ipduo, username, password, wait_option));
334 }
335 
336 
337 /**************************************************************************/
338 /*                                                                        */
339 /*  FUNCTION                                               RELEASE        */
340 /*                                                                        */
341 /*    _nx_ftp_client_connect_internal                     PORTABLE C      */
342 /*                                                           6.3.0        */
343 /*  AUTHOR                                                                */
344 /*                                                                        */
345 /*    Yuxin Zhou, Microsoft Corporation                                   */
346 /*                                                                        */
347 /*  DESCRIPTION                                                           */
348 /*                                                                        */
349 /*    This function connects a previously created FTP instance with the   */
350 /*    FTP server at the specified IP address.                             */
351 /*                                                                        */
352 /*  INPUT                                                                 */
353 /*                                                                        */
354 /*    ftp_client_ptr                        Pointer to FTP client         */
355 /*    server_ip                             FTP server IP address         */
356 /*    username                              Pointer to login username     */
357 /*    password                              Pointer to login password     */
358 /*    wait_option                           Specifies how long to wait    */
359 /*                                                                        */
360 /*  OUTPUT                                                                */
361 /*                                                                        */
362 /*    status                                Completion status             */
363 /*                                                                        */
364 /*  CALLS                                                                 */
365 /*                                                                        */
366 /*    nx_tcp_client_socket_bind             Bind client socket to port    */
367 /*    nxd_tcp_client_socket_connect         Connect to FTP server         */
368 /*    nx_tcp_client_socket_unbind           Unbind client socket from port*/
369 /*    nx_packet_release                     Release packet                */
370 /*    nx_tcp_socket_receive                 Receive server response       */
371 /*    nx_tcp_socket_send                    Send request to server        */
372 /*                                                                        */
373 /*  CALLED BY                                                             */
374 /*                                                                        */
375 /*    Application Code                                                    */
376 /*                                                                        */
377 /*  RELEASE HISTORY                                                       */
378 /*                                                                        */
379 /*    DATE              NAME                      DESCRIPTION             */
380 /*                                                                        */
381 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
382 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
383 /*                                            resulting in version 6.1    */
384 /*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
385 /*                                            corrected length of buffer, */
386 /*                                            resulting in version 6.3.0  */
387 /*                                                                        */
388 /**************************************************************************/
_nx_ftp_client_connect_internal(NX_FTP_CLIENT * ftp_client_ptr,NXD_ADDRESS * server_ip,CHAR * username,CHAR * password,ULONG wait_option)389 UINT  _nx_ftp_client_connect_internal(NX_FTP_CLIENT *ftp_client_ptr, NXD_ADDRESS *server_ip, CHAR *username,
390                                       CHAR *password, ULONG wait_option)
391 {
392 
393 NX_PACKET   *packet_ptr;
394 UCHAR       *buffer_ptr;
395 UINT        length;
396 UINT        i;
397 UINT        status;
398 
399 
400     /* Determine if the client is still in a not connected state.  */
401     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_NOT_CONNECTED)
402     {
403 
404         /* Already connected, return an error.  */
405         return(NX_FTP_NOT_DISCONNECTED);
406     }
407 
408     /* Bind the client control socket.  */
409     status =  nx_tcp_client_socket_bind(&(ftp_client_ptr -> nx_ftp_client_control_socket), NX_FTP_CLIENT_SOURCE_PORT, wait_option);
410 
411     /* Check for an error.  */
412     if ((status != NX_SUCCESS) && (status != NX_ALREADY_BOUND))
413     {
414 
415         /* Unable to bind socket to port. */
416         return(status);
417     }
418 
419     /* Connect the socket to the FTP server.  */
420     status =  nxd_tcp_client_socket_connect(&(ftp_client_ptr -> nx_ftp_client_control_socket), server_ip, NX_FTP_SERVER_CONTROL_PORT, wait_option);
421 
422 
423     /* Check for an error.  */
424     if (status != NX_SUCCESS)
425     {
426 
427         /* Unbind the socket.  */
428         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
429 
430         /* Unable to connect socket to server FTP control port. */
431         return(status);
432     }
433 
434     /* Now wait for the "220 " response from the FTP server to indicate the connection has been
435        established.  */
436     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
437 
438     /* Check to see if no packet was received.  */
439     if (status)
440     {
441 
442         /* Close the socket. */
443         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
444 
445         /* Unbind the socket.  */
446         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
447 
448         /* Unable to connect socket to server FTP control port. */
449         return(status);
450     }
451 
452 #ifndef NX_DISABLE_PACKET_CHAIN
453     if (packet_ptr -> nx_packet_next)
454     {
455 
456         /* Release the packet.  */
457         nx_packet_release(packet_ptr);
458 
459         /* Close the socket. */
460         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
461 
462         /* Unbind the socket.  */
463         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
464 
465         /* Return.  */
466         return(NX_INVALID_PACKET);
467     }
468 #endif /* NX_DISABLE_PACKET_CHAIN */
469 
470     /* We have a packet, setup pointer to the buffer area.  */
471     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
472     length = packet_ptr -> nx_packet_length;
473 
474     /* Check for 220 message.  */
475     if ((length < 3) || (buffer_ptr[0] != '2') || (buffer_ptr[1] != '2'))
476     {
477 
478         /* Close the socket. */
479         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
480 
481         /* Release the packet.  */
482         nx_packet_release(packet_ptr);
483 
484         /* Unbind the socket.  */
485         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
486 
487         /* Unable to connect socket to server FTP control port. */
488         return(NX_FTP_EXPECTED_22X_CODE);
489     }
490 
491     memset(buffer_ptr, 0, length);
492 
493     /* Check if out of boundary.  */
494     if (((!username) && ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 11)) ||
495         ((username) && ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 7)))
496      {
497 
498         /* Release the packet.  */
499         nx_packet_release(packet_ptr);
500 
501         /* Close the socket. */
502         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
503 
504         /* Unbind the socket.  */
505         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
506 
507         /* Set the error status.  */
508         return(NX_FTP_FAILED);
509     }
510 
511     /* Now build the user name message.  */
512     buffer_ptr[0] =  'U';
513     buffer_ptr[1] =  'S';
514     buffer_ptr[2] =  'E';
515     buffer_ptr[3] =  'R';
516     buffer_ptr[4] =  ' ';
517 
518     /* Determine if a user name was supplied.  */
519     if (username == NX_NULL)
520     {
521 
522         /* No username specified, use "USER".  */
523         buffer_ptr[5] =  'U';
524         buffer_ptr[6] =  'S';
525         buffer_ptr[7] =  'E';
526         buffer_ptr[8] =  'R';
527         buffer_ptr[9] =  13;
528         buffer_ptr[10]=  10;
529 
530         /* Set the length of the packet.  */
531         packet_ptr -> nx_packet_length =  11;
532     }
533     else
534     {
535 
536         /* A username was supplied, copy it into the buffer.  */
537         for(i = 0; username[i]; i++)
538         {
539 
540             /* Check if out of boundary.  */
541             if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
542             {
543 
544                 /* Release the packet.  */
545                 nx_packet_release(packet_ptr);
546 
547                 /* Close the socket. */
548                 nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
549 
550                 /* Unbind the socket.  */
551                 nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
552 
553                 /* Set the error status.  */
554                 return(NX_FTP_FAILED);
555             }
556 
557             /* Copy byte of the username.  */
558             buffer_ptr[5+i] =  (UCHAR)username[i];
559         }
560 
561         /* Now insert the CR/LF.  */
562         buffer_ptr[5+i] =  13;
563         buffer_ptr[5+i+1] =  10;
564 
565         /* Setup the length of the packet.  */
566         packet_ptr -> nx_packet_length =  i + 7;
567     }
568 
569     /* Setup the packet append pointer.  */
570     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
571 
572     /* Send the username to the FTP server.  */
573     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
574 
575     /* Check for unsuccessful send.  */
576     if (status)
577     {
578 
579         /* Release the packet.  */
580         nx_packet_release(packet_ptr);
581 
582         /* Close the socket. */
583         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
584 
585         /* Unbind the socket.  */
586         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
587 
588         /* Unable to connect socket to server FTP control port. */
589         return(status);
590     }
591 
592     /* There may be multiple 220 responses from FTP server after establishing connection.
593        Flush mutiple 220 respones and wait for 331 response from the FTP server.  */
594     while(1)
595     {
596 
597         /* Wait for response from the FTP server.  */
598         status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
599 
600         /* Determine if a packet was not received.  */
601         if (status)
602         {
603 
604             /* Close the socket. */
605             nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
606 
607             /* Unbind the socket.  */
608             nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
609 
610             /* Unable to connect socket to server FTP control port. */
611             return(status);
612         }
613 
614 #ifndef NX_DISABLE_PACKET_CHAIN
615         if (packet_ptr -> nx_packet_next)
616         {
617 
618             /* Release the packet.  */
619             nx_packet_release(packet_ptr);
620 
621             /* Close the socket. */
622             nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
623 
624             /* Unbind the socket.  */
625             nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
626 
627             /* Return.  */
628             return(NX_INVALID_PACKET);
629         }
630 #endif /* NX_DISABLE_PACKET_CHAIN */
631 
632         /* We have a packet, setup pointer to the buffer area.  */
633         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
634         length = packet_ptr -> nx_packet_length;
635 
636         /* Check for 220 message.  */
637         if ((packet_ptr -> nx_packet_length >= 3) && (buffer_ptr[0] == '2') && (buffer_ptr[1] == '2'))
638         {
639 
640             /* Release the packet.  */
641             nx_packet_release(packet_ptr);
642             continue;
643         }
644 
645         /* Check to make sure the response is proper.  */
646 
647         /* Check for 331 message.  */
648         if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '3') || (buffer_ptr[1] != '3'))
649         {
650 
651             /* Release the packet.  */
652             nx_packet_release(packet_ptr);
653 
654             /* Close the socket. */
655             nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
656 
657             /* Unbind the socket.  */
658             nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
659 
660             /* Unable to connect socket to server FTP control port. */
661             return(NX_FTP_EXPECTED_33X_CODE);
662         }
663         else
664         {
665             break;
666         }
667     }
668 
669     memset(buffer_ptr, 0, length);
670 
671     /* Check if out of boundary.  */
672     if (((!password) && ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 11)) ||
673         ((password) && ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 7)))
674      {
675 
676         /* Release the packet.  */
677         nx_packet_release(packet_ptr);
678 
679         /* Close the socket. */
680         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
681 
682         /* Unbind the socket.  */
683         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
684 
685         /* Set the error status.  */
686         return(NX_FTP_FAILED);
687     }
688 
689     /* Now build the password message.  */
690     buffer_ptr[0] =  'P';
691     buffer_ptr[1] =  'A';
692     buffer_ptr[2] =  'S';
693     buffer_ptr[3] =  'S';
694     buffer_ptr[4] =  ' ';
695 
696     /* Determine if a password was specified.  */
697     if (password == NX_NULL)
698     {
699 
700         /* No password was specified, use "PASS".  */
701         buffer_ptr[5] =  'P';
702         buffer_ptr[6] =  'A';
703         buffer_ptr[7] =  'S';
704         buffer_ptr[8] =  'S';
705         buffer_ptr[9] =  13;
706         buffer_ptr[10]=  10;
707 
708         /* Setup the packet length.  */
709         packet_ptr -> nx_packet_length =  11;
710     }
711     else
712     {
713 
714         /* Password was specified, copy it into the buffer.  */
715         for(i = 0; password[i]; i++)
716         {
717 
718             /* Check if out of boundary.  */
719             if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
720             {
721 
722                 /* Release the packet.  */
723                 nx_packet_release(packet_ptr);
724 
725                 /* Close the socket. */
726                 nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
727 
728                 /* Unbind the socket.  */
729                 nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
730 
731                 /* Set the error status.  */
732                 return(NX_FTP_FAILED);
733             }
734 
735             /* Copy byte of password.  */
736             buffer_ptr[5+i] =  (UCHAR)password[i];
737         }
738 
739         /* Now insert the CR/LF.  */
740         buffer_ptr[5+i] =  13;
741         buffer_ptr[5+i+1] = 10;
742 
743         /* Setup the length of the packet.  */
744         packet_ptr -> nx_packet_length =  i + 7;
745     }
746 
747     /* Setup the packet append pointer.  */
748     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
749 
750     /* Send the password to the FTP server.  */
751     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
752 
753     /* Check for successful send.  */
754     if (status)
755     {
756 
757         /* Release the packet.  */
758         nx_packet_release(packet_ptr);
759 
760         /* Close the socket. */
761         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
762 
763         /* Unbind the socket.  */
764         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
765 
766         /* Unable to connect socket to server FTP control port. */
767         return(status);
768     }
769 
770     /* Wait for response from the FTP server.  */
771     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
772 
773     /* Determine if a packet was not received.  */
774     if (status)
775     {
776 
777         /* Close the socket. */
778         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
779 
780         /* Unbind the socket.  */
781         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
782 
783         /* Unable to connect socket to server FTP control port. */
784         return(status);
785     }
786 
787     /* We have a packet, setup pointer to the buffer area.  */
788     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
789 
790     /* Check for 230 message, signaling successful login.  */
791     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2') || (buffer_ptr[1] != '3'))
792     {
793 
794         /* Release the packet.  */
795         nx_packet_release(packet_ptr);
796 
797         /* Close the socket. */
798         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
799 
800         /* Unbind the socket.  */
801         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
802 
803         /* Unable to connect socket to server FTP control port. */
804         return(NX_FTP_EXPECTED_23X_CODE);
805     }
806 
807     /* Release the packet.  */
808     nx_packet_release(packet_ptr);
809 
810     /* If we get here, we have a successful connect with the FTP server. */
811     ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_CONNECTED;
812 
813     ftp_client_ptr -> nx_ftp_client_data_port = ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_port;
814 
815     /* Return success to caller.  */
816     return(NX_SUCCESS);
817 }
818 
819 
820 /**************************************************************************/
821 /*                                                                        */
822 /*  FUNCTION                                               RELEASE        */
823 /*                                                                        */
824 /*    _nxe_ftp_client_create                              PORTABLE C      */
825 /*                                                           6.1          */
826 /*  AUTHOR                                                                */
827 /*                                                                        */
828 /*    Yuxin Zhou, Microsoft Corporation                                   */
829 /*                                                                        */
830 /*  DESCRIPTION                                                           */
831 /*                                                                        */
832 /*    This function checks for errors in the FTP client create call.      */
833 /*                                                                        */
834 /*                                                                        */
835 /*  INPUT                                                                 */
836 /*                                                                        */
837 /*    ftp_client_ptr                        Pointer to FTP client         */
838 /*    ftp_client_name                       Name of this FTP client       */
839 /*    ip_ptr                                Pointer to IP instance        */
840 /*    window_size                           Size of TCP receive window    */
841 /*    pool_ptr                              Pointer to packet pool        */
842 /*                                                                        */
843 /*  OUTPUT                                                                */
844 /*                                                                        */
845 /*    status                                Completion status             */
846 /*                                                                        */
847 /*  CALLS                                                                 */
848 /*                                                                        */
849 /*    _nx_ftp_client_create                 Actual client create call     */
850 /*                                                                        */
851 /*  CALLED BY                                                             */
852 /*                                                                        */
853 /*    Application Code                                                    */
854 /*                                                                        */
855 /*  RELEASE HISTORY                                                       */
856 /*                                                                        */
857 /*    DATE              NAME                      DESCRIPTION             */
858 /*                                                                        */
859 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
860 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
861 /*                                            resulting in version 6.1    */
862 /*                                                                        */
863 /**************************************************************************/
_nxe_ftp_client_create(NX_FTP_CLIENT * ftp_client_ptr,CHAR * ftp_client_name,NX_IP * ip_ptr,ULONG window_size,NX_PACKET_POOL * pool_ptr)864 UINT  _nxe_ftp_client_create(NX_FTP_CLIENT *ftp_client_ptr, CHAR *ftp_client_name, NX_IP *ip_ptr,
865                              ULONG window_size, NX_PACKET_POOL *pool_ptr)
866 {
867 
868 UINT    status;
869 
870 
871     /* Check for invalid input pointers.  */
872     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
873         (ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id == NXD_FTP_CLIENT_ID) ||
874         (pool_ptr == NX_NULL))
875         return(NX_PTR_ERROR);
876 
877     /* Call actual client create function.  */
878     status =  _nx_ftp_client_create(ftp_client_ptr, ftp_client_name, ip_ptr, window_size, pool_ptr);
879 
880     /* Return completion status.  */
881     return(status);
882 }
883 
884 
885 /**************************************************************************/
886 /*                                                                        */
887 /*  FUNCTION                                               RELEASE        */
888 /*                                                                        */
889 /*    _nx_ftp_client_create                               PORTABLE C      */
890 /*                                                           6.1          */
891 /*  AUTHOR                                                                */
892 /*                                                                        */
893 /*    Yuxin Zhou, Microsoft Corporation                                   */
894 /*                                                                        */
895 /*  DESCRIPTION                                                           */
896 /*                                                                        */
897 /*    This function creates an FTP client instance.                       */
898 /*                                                                        */
899 /*                                                                        */
900 /*  INPUT                                                                 */
901 /*                                                                        */
902 /*    ftp_client_ptr                        Pointer to FTP client         */
903 /*    ftp_client_name                       Name of this FTP client       */
904 /*    ip_ptr                                Pointer to IP instance        */
905 /*    window_size                           Size of TCP receive window    */
906 /*    pool_ptr                              Pointer to packet pool        */
907 /*                                                                        */
908 /*  OUTPUT                                                                */
909 /*                                                                        */
910 /*    status                                Completion status             */
911 /*                                                                        */
912 /*  CALLS                                                                 */
913 /*                                                                        */
914 /*    nx_tcp_socket_create                  Create TCP socket             */
915 /*    nx_tcp_socket_delete                  Delete TCP socket             */
916 /*                                                                        */
917 /*  CALLED BY                                                             */
918 /*                                                                        */
919 /*    Application Code                                                    */
920 /*                                                                        */
921 /*  RELEASE HISTORY                                                       */
922 /*                                                                        */
923 /*    DATE              NAME                      DESCRIPTION             */
924 /*                                                                        */
925 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
926 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
927 /*                                            resulting in version 6.1    */
928 /*                                                                        */
929 /**************************************************************************/
_nx_ftp_client_create(NX_FTP_CLIENT * ftp_client_ptr,CHAR * ftp_client_name,NX_IP * ip_ptr,ULONG window_size,NX_PACKET_POOL * pool_ptr)930 UINT  _nx_ftp_client_create(NX_FTP_CLIENT *ftp_client_ptr, CHAR *ftp_client_name, NX_IP *ip_ptr,
931                             ULONG window_size, NX_PACKET_POOL *pool_ptr)
932 {
933 
934 UINT    status;
935 
936 
937     /* Clear the client FTP control block.  */
938     memset((void *) ftp_client_ptr, 0, sizeof(NX_FTP_CLIENT));
939 
940     /* Create the TCP control socket.  */
941     status =  nx_tcp_socket_create(ip_ptr, &(ftp_client_ptr -> nx_ftp_client_control_socket), ftp_client_name,
942                                         NX_FTP_CONTROL_TOS, NX_FTP_FRAGMENT_OPTION, NX_FTP_TIME_TO_LIVE, window_size,
943                                         NX_NULL, NX_NULL);
944 
945     /* Check for an error.  */
946     if (status)
947     {
948 
949         /* Return an error.  */
950         return(status);
951     }
952 
953     /* Create the TCP data socket.  */
954     status =  nx_tcp_socket_create(ip_ptr, &(ftp_client_ptr -> nx_ftp_client_data_socket), ftp_client_name,
955                                         NX_FTP_CONTROL_TOS, NX_FTP_FRAGMENT_OPTION, NX_FTP_TIME_TO_LIVE, window_size,
956                                         NX_NULL, _nx_ftp_client_data_disconnect);
957 
958     /* Check for an error.  */
959     if (status)
960     {
961 
962         /* Delete the control socket.  */
963         nx_tcp_socket_delete(&(ftp_client_ptr -> nx_ftp_client_control_socket));
964 
965         /* Return an error.  */
966         return(status);
967     }
968 
969     /* Save off the remaining information.  */
970 
971     /* Save the client name.  */
972     ftp_client_ptr -> nx_ftp_client_name =  ftp_client_name;
973 
974     /* Save the IP pointer.  */
975     ftp_client_ptr -> nx_ftp_client_ip_ptr =  ip_ptr;
976 
977     /* Save the packet pool pointer.  */
978     ftp_client_ptr -> nx_ftp_client_packet_pool_ptr =  pool_ptr;
979 
980     /* Set the initial client state.  */
981     ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_NOT_CONNECTED;
982 
983     /* Set the FTP client id.  */
984     ftp_client_ptr -> nx_ftp_client_id =  NXD_FTP_CLIENT_ID;
985 
986     /* Default to active transfer mode. */
987     ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled = NX_FALSE;
988 
989     /* Default to stream mode. */
990     ftp_client_ptr -> nx_ftp_client_transfer_mode = NX_FTP_TRANSFER_MODE_STREAM;
991 
992     /* Return success to caller.  */
993     return(NX_SUCCESS);
994 }
995 
996 
997 /**************************************************************************/
998 /*                                                                        */
999 /*  FUNCTION                                               RELEASE        */
1000 /*                                                                        */
1001 /*    _nx_ftp_client_data_disconnect                      PORTABLE C      */
1002 /*                                                           6.1          */
1003 /*  AUTHOR                                                                */
1004 /*                                                                        */
1005 /*    Yuxin Zhou, Microsoft Corporation                                   */
1006 /*                                                                        */
1007 /*  DESCRIPTION                                                           */
1008 /*                                                                        */
1009 /*    This function handles the disconnect from the server.               */
1010 /*                                                                        */
1011 /*                                                                        */
1012 /*  INPUT                                                                 */
1013 /*                                                                        */
1014 /*    data_socket_ptr                       Pointer to FTP client data    */
1015 /*                                            socket                      */
1016 /*                                                                        */
1017 /*  OUTPUT                                                                */
1018 /*                                                                        */
1019 /*    None                                                                */
1020 /*                                                                        */
1021 /*  CALLS                                                                 */
1022 /*                                                                        */
1023 /*    nx_tcp_socket_disconnect              Disconnect TCP socket         */
1024 /*                                                                        */
1025 /*  CALLED BY                                                             */
1026 /*                                                                        */
1027 /*    Application Code                                                    */
1028 /*                                                                        */
1029 /*  RELEASE HISTORY                                                       */
1030 /*                                                                        */
1031 /*    DATE              NAME                      DESCRIPTION             */
1032 /*                                                                        */
1033 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1034 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1035 /*                                            resulting in version 6.1    */
1036 /*                                                                        */
1037 /**************************************************************************/
_nx_ftp_client_data_disconnect(NX_TCP_SOCKET * data_socket_ptr)1038 void  _nx_ftp_client_data_disconnect(NX_TCP_SOCKET *data_socket_ptr)
1039 {
1040 
1041     /* Disconnect FTP client data socket.  */
1042     nx_tcp_socket_disconnect(data_socket_ptr, NX_NO_WAIT);
1043 }
1044 
1045 
1046 /**************************************************************************/
1047 /*                                                                        */
1048 /*  FUNCTION                                               RELEASE        */
1049 /*                                                                        */
1050 /*    _nxe_ftp_client_delete                              PORTABLE C      */
1051 /*                                                           6.1          */
1052 /*  AUTHOR                                                                */
1053 /*                                                                        */
1054 /*    Yuxin Zhou, Microsoft Corporation                                   */
1055 /*                                                                        */
1056 /*  DESCRIPTION                                                           */
1057 /*                                                                        */
1058 /*    This function checks for errors in the FTP client delete call.      */
1059 /*                                                                        */
1060 /*                                                                        */
1061 /*  INPUT                                                                 */
1062 /*                                                                        */
1063 /*    ftp_client_ptr                        Pointer to FTP client         */
1064 /*                                                                        */
1065 /*  OUTPUT                                                                */
1066 /*                                                                        */
1067 /*    status                                Completion status             */
1068 /*                                                                        */
1069 /*  CALLS                                                                 */
1070 /*                                                                        */
1071 /*    _nx_ftp_client_delete                 Actual client delete call     */
1072 /*                                                                        */
1073 /*  CALLED BY                                                             */
1074 /*                                                                        */
1075 /*    Application Code                                                    */
1076 /*                                                                        */
1077 /*  RELEASE HISTORY                                                       */
1078 /*                                                                        */
1079 /*    DATE              NAME                      DESCRIPTION             */
1080 /*                                                                        */
1081 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1082 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1083 /*                                            resulting in version 6.1    */
1084 /*                                                                        */
1085 /**************************************************************************/
_nxe_ftp_client_delete(NX_FTP_CLIENT * ftp_client_ptr)1086 UINT  _nxe_ftp_client_delete(NX_FTP_CLIENT *ftp_client_ptr)
1087 {
1088 
1089 UINT    status;
1090 
1091 
1092     /* Check for invalid input pointers.  */
1093     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
1094         return(NX_PTR_ERROR);
1095 
1096     /* Check for appropriate caller.  */
1097     NX_THREADS_ONLY_CALLER_CHECKING
1098 
1099     /* Call actual client delete function.  */
1100     status =  _nx_ftp_client_delete(ftp_client_ptr);
1101 
1102     /* Return completion status.  */
1103     return(status);
1104 }
1105 
1106 
1107 /**************************************************************************/
1108 /*                                                                        */
1109 /*  FUNCTION                                               RELEASE        */
1110 /*                                                                        */
1111 /*    _nx_ftp_client_delete                               PORTABLE C      */
1112 /*                                                           6.2.1        */
1113 /*  AUTHOR                                                                */
1114 /*                                                                        */
1115 /*    Yuxin Zhou, Microsoft Corporation                                   */
1116 /*                                                                        */
1117 /*  DESCRIPTION                                                           */
1118 /*                                                                        */
1119 /*    This function deletes a previously created FTP client instance.     */
1120 /*                                                                        */
1121 /*                                                                        */
1122 /*  INPUT                                                                 */
1123 /*                                                                        */
1124 /*    ftp_client_ptr                        Pointer to FTP client         */
1125 /*                                                                        */
1126 /*  OUTPUT                                                                */
1127 /*                                                                        */
1128 /*    status                                Completion status             */
1129 /*                                                                        */
1130 /*  CALLS                                                                 */
1131 /*                                                                        */
1132 /*    nx_tcp_socket_create                  Create TCP socket             */
1133 /*    nx_tcp_socket_delete                  Delete TCP socket             */
1134 /*                                                                        */
1135 /*  CALLED BY                                                             */
1136 /*                                                                        */
1137 /*    Application Code                                                    */
1138 /*                                                                        */
1139 /*  RELEASE HISTORY                                                       */
1140 /*                                                                        */
1141 /*    DATE              NAME                      DESCRIPTION             */
1142 /*                                                                        */
1143 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1144 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1145 /*                                            resulting in version 6.1    */
1146 /*  03-08-2023     Wenhui Xie               Modified comment(s),          */
1147 /*                                            cleared the client ID,      */
1148 /*                                            resulting in version 6.2.1  */
1149 /*                                                                        */
1150 /**************************************************************************/
_nx_ftp_client_delete(NX_FTP_CLIENT * ftp_client_ptr)1151 UINT  _nx_ftp_client_delete(NX_FTP_CLIENT *ftp_client_ptr)
1152 {
1153 
1154     /* Determine if the client is still in a not connected state.  */
1155     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_NOT_CONNECTED)
1156     {
1157 
1158         /* Already connected, return an error.  */
1159         return(NX_FTP_NOT_DISCONNECTED);
1160     }
1161 
1162     /* Clear the client ID .  */
1163     ftp_client_ptr -> nx_ftp_client_id = 0;
1164 
1165     /* Delete the control and data sockets.  */
1166     nx_tcp_socket_delete(&(ftp_client_ptr -> nx_ftp_client_control_socket));
1167     nx_tcp_socket_delete(&(ftp_client_ptr -> nx_ftp_client_data_socket));
1168 
1169     /* Return success to caller.  */
1170     return(NX_SUCCESS);
1171 }
1172 
1173 /**************************************************************************/
1174 /*                                                                        */
1175 /*  FUNCTION                                               RELEASE        */
1176 /*                                                                        */
1177 /*    _nxe_ftp_client_directory_create                    PORTABLE C      */
1178 /*                                                           6.1          */
1179 /*  AUTHOR                                                                */
1180 /*                                                                        */
1181 /*    Yuxin Zhou, Microsoft Corporation                                   */
1182 /*                                                                        */
1183 /*  DESCRIPTION                                                           */
1184 /*                                                                        */
1185 /*    This function checks for errors in the FTP client directory         */
1186 /*    create call.                                                        */
1187 /*                                                                        */
1188 /*    Note: The string length of directory_name is limited by the packet  */
1189 /*    payload size.                                                       */
1190 /*                                                                        */
1191 /*  INPUT                                                                 */
1192 /*                                                                        */
1193 /*    ftp_client_ptr                        Pointer to FTP client         */
1194 /*    directory_name                        New directory name            */
1195 /*    wait_option                           Specifies how long to wait    */
1196 /*                                                                        */
1197 /*  OUTPUT                                                                */
1198 /*                                                                        */
1199 /*    status                                Completion status             */
1200 /*                                                                        */
1201 /*  CALLS                                                                 */
1202 /*                                                                        */
1203 /*    _nx_ftp_client_directory_create       Actual client directory       */
1204 /*                                            create call                 */
1205 /*                                                                        */
1206 /*  CALLED BY                                                             */
1207 /*                                                                        */
1208 /*    Application Code                                                    */
1209 /*                                                                        */
1210 /*  RELEASE HISTORY                                                       */
1211 /*                                                                        */
1212 /*    DATE              NAME                      DESCRIPTION             */
1213 /*                                                                        */
1214 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1215 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1216 /*                                            resulting in version 6.1    */
1217 /*                                                                        */
1218 /**************************************************************************/
_nxe_ftp_client_directory_create(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_name,ULONG wait_option)1219 UINT  _nxe_ftp_client_directory_create(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_name, ULONG wait_option)
1220 {
1221 
1222 UINT    status;
1223 
1224 
1225     /* Check for invalid input pointers.  */
1226     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (directory_name == NX_NULL))
1227         return(NX_PTR_ERROR);
1228 
1229     /* Check for appropriate caller.  */
1230     NX_THREADS_ONLY_CALLER_CHECKING
1231 
1232     /* Call actual client directory create function.  */
1233     status =  _nx_ftp_client_directory_create(ftp_client_ptr, directory_name, wait_option);
1234 
1235     /* Return completion status.  */
1236     return(status);
1237 }
1238 
1239 
1240 /**************************************************************************/
1241 /*                                                                        */
1242 /*  FUNCTION                                               RELEASE        */
1243 /*                                                                        */
1244 /*    _nx_ftp_client_directory_create                     PORTABLE C      */
1245 /*                                                           6.1          */
1246 /*  AUTHOR                                                                */
1247 /*                                                                        */
1248 /*    Yuxin Zhou, Microsoft Corporation                                   */
1249 /*                                                                        */
1250 /*  DESCRIPTION                                                           */
1251 /*                                                                        */
1252 /*    This function creates the specified directory name on the FTP       */
1253 /*    server.                                                             */
1254 /*                                                                        */
1255 /*    Note: The string length of directory_name is limited by the packet  */
1256 /*    payload size.                                                       */
1257 /*                                                                        */
1258 /*  INPUT                                                                 */
1259 /*                                                                        */
1260 /*    ftp_client_ptr                        Pointer to FTP client         */
1261 /*    directory_name                        New directory name            */
1262 /*    wait_option                           Specifies how long to wait    */
1263 /*                                                                        */
1264 /*  OUTPUT                                                                */
1265 /*                                                                        */
1266 /*    status                                Completion status             */
1267 /*                                                                        */
1268 /*  CALLS                                                                 */
1269 /*                                                                        */
1270 /*    nx_packet_allocate                    Allocate packet               */
1271 /*    nx_packet_release                     Release packet                */
1272 /*    nx_tcp_socket_receive                 Receive packet from server    */
1273 /*    nx_tcp_socket_send                    Send data packet to server    */
1274 /*                                                                        */
1275 /*  CALLED BY                                                             */
1276 /*                                                                        */
1277 /*    Application Code                                                    */
1278 /*                                                                        */
1279 /*  RELEASE HISTORY                                                       */
1280 /*                                                                        */
1281 /*    DATE              NAME                      DESCRIPTION             */
1282 /*                                                                        */
1283 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1284 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1285 /*                                            resulting in version 6.1    */
1286 /*                                                                        */
1287 /**************************************************************************/
_nx_ftp_client_directory_create(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_name,ULONG wait_option)1288 UINT  _nx_ftp_client_directory_create(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_name, ULONG wait_option)
1289 {
1290 
1291 UINT        i;
1292 UCHAR       *buffer_ptr;
1293 NX_PACKET   *packet_ptr;
1294 UINT        status;
1295 
1296         /* Ensure the client is the proper state for directory create request.  */
1297     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
1298         return(NX_FTP_NOT_CONNECTED);
1299 
1300     /* Allocate a packet for sending the directory create command.  */
1301     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
1302 
1303     /* Determine if the packet allocation was successful.  */
1304     if (status)
1305     {
1306 
1307         /* Return error.  */
1308         return(status);
1309     }
1310 
1311     /* Check if out of boundary.  */
1312     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 6)
1313      {
1314 
1315         /* Release the packet.  */
1316         nx_packet_release(packet_ptr);
1317 
1318         /* Set the error status.  */
1319         return(NX_FTP_FAILED);
1320     }
1321 
1322     /* We have a packet, setup pointer to the buffer area.  */
1323     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1324 
1325     /* Now build "MKD" message to indicate directory create.  */
1326     buffer_ptr[0] =  'M';
1327     buffer_ptr[1] =  'K';
1328     buffer_ptr[2] =  'D';
1329     buffer_ptr[3] =  ' ';
1330 
1331     /* Copy the new directory name into the message.  */
1332     for(i = 0; directory_name[i]; i++)
1333     {
1334 
1335         /* Check if out of boundary.  */
1336         if ((i + 6) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
1337         {
1338 
1339             /* Release the packet.  */
1340             nx_packet_release(packet_ptr);
1341 
1342             /* Set the error status.  */
1343             return(NX_FTP_FAILED);
1344         }
1345 
1346         /* Copy character of the directory name.  */
1347         buffer_ptr[4+i] =  (UCHAR)directory_name[i];
1348     }
1349 
1350     /* Set the CR/LF.  */
1351     buffer_ptr[i+4] =  13;
1352     buffer_ptr[i+5] =  10;
1353 
1354     /* Set the packet length.  */
1355     packet_ptr -> nx_packet_length =  i+6;
1356 
1357     /* Setup the packet append pointer.  */
1358     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
1359 
1360     /* Send the MKD message.  */
1361     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
1362 
1363     /* Determine if the send was unsuccessful.  */
1364     if (status)
1365     {
1366 
1367         /* Release the packet.  */
1368         nx_packet_release(packet_ptr);
1369 
1370         /* Return error.  */
1371         return(status);
1372     }
1373 
1374     /* Wait for response from the FTP server.  */
1375     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
1376 
1377     /* Determine if a packet was not received.  */
1378     if (status)
1379     {
1380 
1381         /* MKD error. */
1382         return(status);
1383     }
1384 
1385     /* We have a packet, setup pointer to the buffer area.  */
1386     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1387 
1388     /* Check for 2xx message, signaling the "MKD" was processed successfully.  */
1389     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
1390     {
1391 
1392         /* Release the packet.  */
1393         nx_packet_release(packet_ptr);
1394 
1395         /* Create directory error. */
1396         return(NX_FTP_EXPECTED_2XX_CODE);
1397     }
1398 
1399     /* Yes, the directory was created.  */
1400 
1401     /* Release the packet.  */
1402     nx_packet_release(packet_ptr);
1403 
1404     /* Return success to caller.  */
1405     return(NX_SUCCESS);
1406 }
1407 
1408 
1409 /**************************************************************************/
1410 /*                                                                        */
1411 /*  FUNCTION                                               RELEASE        */
1412 /*                                                                        */
1413 /*    _nxe_ftp_client_directory_default_set               PORTABLE C      */
1414 /*                                                           6.1          */
1415 /*  AUTHOR                                                                */
1416 /*                                                                        */
1417 /*    Yuxin Zhou, Microsoft Corporation                                   */
1418 /*                                                                        */
1419 /*  DESCRIPTION                                                           */
1420 /*                                                                        */
1421 /*    This function checks for errors in the FTP client directory         */
1422 /*    default set.                                                        */
1423 /*                                                                        */
1424 /*    Note: The string length of directory_path is limited by the packet  */
1425 /*    payload size.                                                       */
1426 /*                                                                        */
1427 /*  INPUT                                                                 */
1428 /*                                                                        */
1429 /*    ftp_client_ptr                        Pointer to FTP client         */
1430 /*    directory_path                        New default directory path    */
1431 /*    wait_option                           Specifies how long to wait    */
1432 /*                                                                        */
1433 /*  OUTPUT                                                                */
1434 /*                                                                        */
1435 /*    status                                Completion status             */
1436 /*                                                                        */
1437 /*  CALLS                                                                 */
1438 /*                                                                        */
1439 /*    _nx_ftp_client_directory_default_set  Actual client directory       */
1440 /*                                            default set call            */
1441 /*                                                                        */
1442 /*  CALLED BY                                                             */
1443 /*                                                                        */
1444 /*    Application Code                                                    */
1445 /*                                                                        */
1446 /*  RELEASE HISTORY                                                       */
1447 /*                                                                        */
1448 /*    DATE              NAME                      DESCRIPTION             */
1449 /*                                                                        */
1450 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1451 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1452 /*                                            resulting in version 6.1    */
1453 /*                                                                        */
1454 /**************************************************************************/
_nxe_ftp_client_directory_default_set(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_path,ULONG wait_option)1455 UINT  _nxe_ftp_client_directory_default_set(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, ULONG wait_option)
1456 {
1457 
1458 UINT    status;
1459 
1460 
1461     /* Check for invalid input pointers.  */
1462     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
1463         return(NX_PTR_ERROR);
1464 
1465     /* Check for appropriate caller.  */
1466     NX_THREADS_ONLY_CALLER_CHECKING
1467 
1468     /* Call actual client directory default set function.  */
1469     status =  _nx_ftp_client_directory_default_set(ftp_client_ptr, directory_path, wait_option);
1470 
1471     /* Return completion status.  */
1472     return(status);
1473 }
1474 
1475 
1476 /**************************************************************************/
1477 /*                                                                        */
1478 /*  FUNCTION                                               RELEASE        */
1479 /*                                                                        */
1480 /*    _nx_ftp_client_directory_default_set                PORTABLE C      */
1481 /*                                                           6.1          */
1482 /*  AUTHOR                                                                */
1483 /*                                                                        */
1484 /*    Yuxin Zhou, Microsoft Corporation                                   */
1485 /*                                                                        */
1486 /*  DESCRIPTION                                                           */
1487 /*                                                                        */
1488 /*    This function changes the default working directory on the FTP      */
1489 /*    server.                                                             */
1490 /*                                                                        */
1491 /*    Note: The string length of directory_path is limited by the packet  */
1492 /*    payload size.                                                       */
1493 /*                                                                        */
1494 /*  INPUT                                                                 */
1495 /*                                                                        */
1496 /*    ftp_client_ptr                        Pointer to FTP client         */
1497 /*    directory_path                        New default directory path    */
1498 /*    wait_option                           Specifies how long to wait    */
1499 /*                                                                        */
1500 /*  OUTPUT                                                                */
1501 /*                                                                        */
1502 /*    status                                Completion status             */
1503 /*                                                                        */
1504 /*  CALLS                                                                 */
1505 /*                                                                        */
1506 /*    nx_packet_allocate                    Allocate packet               */
1507 /*    nx_packet_release                     Release packet                */
1508 /*    nx_tcp_socket_receive                 Receive packet from server    */
1509 /*    nx_tcp_socket_send                    Send data packet to server    */
1510 /*                                                                        */
1511 /*  CALLED BY                                                             */
1512 /*                                                                        */
1513 /*    Application Code                                                    */
1514 /*                                                                        */
1515 /*  RELEASE HISTORY                                                       */
1516 /*                                                                        */
1517 /*    DATE              NAME                      DESCRIPTION             */
1518 /*                                                                        */
1519 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1520 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1521 /*                                            resulting in version 6.1    */
1522 /*                                                                        */
1523 /**************************************************************************/
_nx_ftp_client_directory_default_set(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_path,ULONG wait_option)1524 UINT  _nx_ftp_client_directory_default_set(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, ULONG wait_option)
1525 {
1526 
1527 UINT        i;
1528 UCHAR       *buffer_ptr;
1529 NX_PACKET   *packet_ptr;
1530 UINT        status;
1531 
1532 
1533     /* Ensure the client is the proper state for a default directory request.  */
1534     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
1535         return(NX_FTP_NOT_CONNECTED);
1536 
1537     /* Allocate a packet for sending the change directory command.  */
1538     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
1539 
1540     /* Determine if the packet allocation was successful.  */
1541     if (status)
1542     {
1543 
1544         /* Return error.  */
1545         return(status);
1546     }
1547 
1548     /* Check if out of boundary.  */
1549     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 6)
1550      {
1551 
1552         /* Release the packet.  */
1553         nx_packet_release(packet_ptr);
1554 
1555         /* Set the error status.  */
1556         return(NX_FTP_FAILED);
1557     }
1558 
1559     /* We have a packet, setup pointer to the buffer area.  */
1560     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1561 
1562     /* Now build "CWD" message to indicate default directory change.  */
1563     buffer_ptr[0] =  'C';
1564     buffer_ptr[1] =  'W';
1565     buffer_ptr[2] =  'D';
1566     buffer_ptr[3] =  ' ';
1567 
1568     /* Copy the new default directory into the message.  */
1569     for(i = 0; directory_path[i]; i++)
1570     {
1571 
1572         /* Check if out of boundary.  */
1573         if ((i + 6) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
1574         {
1575 
1576             /* Release the packet.  */
1577             nx_packet_release(packet_ptr);
1578 
1579             /* Set the error status.  */
1580             return(NX_FTP_FAILED);
1581         }
1582 
1583         /* Copy character of the directory path.  */
1584         buffer_ptr[4+i] =  (UCHAR)directory_path[i];
1585     }
1586 
1587     /* Set the CR/LF.  */
1588     buffer_ptr[i+4] =  13;
1589     buffer_ptr[i+5] =  10;
1590 
1591     /* Set the packet length.  */
1592     packet_ptr -> nx_packet_length =  i+6;
1593 
1594     /* Setup the packet append pointer.  */
1595     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
1596 
1597     /* Send the CWD message.  */
1598     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
1599 
1600     /* Determine if the send was unsuccessful.  */
1601     if (status)
1602     {
1603 
1604         /* Release the packet.  */
1605         nx_packet_release(packet_ptr);
1606 
1607         /* Return error.  */
1608         return(status);
1609     }
1610 
1611     /* Wait for response from the FTP server.  */
1612     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
1613 
1614     /* Determine if a packet was not received.  */
1615     if (status)
1616     {
1617 
1618         /* RNFR file error. */
1619         return(status);
1620     }
1621 
1622     /* We have a packet, setup pointer to the buffer area.  */
1623     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1624 
1625     /* Check for 2xx message, signaling the "CWD" was processed successfully.  */
1626     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
1627     {
1628 
1629         /* Release the packet.  */
1630         nx_packet_release(packet_ptr);
1631 
1632         /* Change directory error. */
1633         return(NX_FTP_EXPECTED_2XX_CODE);
1634     }
1635 
1636     /* Yes, the default directory was changed.  */
1637 
1638     /* Release the packet.  */
1639     nx_packet_release(packet_ptr);
1640 
1641     /* Return success to caller.  */
1642     return(NX_SUCCESS);
1643 }
1644 
1645 
1646 /**************************************************************************/
1647 /*                                                                        */
1648 /*  FUNCTION                                               RELEASE        */
1649 /*                                                                        */
1650 /*    _nxe_ftp_client_directory_delete                    PORTABLE C      */
1651 /*                                                           6.1          */
1652 /*  AUTHOR                                                                */
1653 /*                                                                        */
1654 /*    Yuxin Zhou, Microsoft Corporation                                   */
1655 /*                                                                        */
1656 /*  DESCRIPTION                                                           */
1657 /*                                                                        */
1658 /*    This function checks for errors in the FTP client directory         */
1659 /*    delete.                                                             */
1660 /*                                                                        */
1661 /*    Note: The string length of directory_name is limited by the packet  */
1662 /*    payload size.                                                       */
1663 /*                                                                        */
1664 /*  INPUT                                                                 */
1665 /*                                                                        */
1666 /*    ftp_client_ptr                        Pointer to FTP client         */
1667 /*    directory_name                        Directory name to delete      */
1668 /*    wait_option                           Specifies how long to wait    */
1669 /*                                                                        */
1670 /*  OUTPUT                                                                */
1671 /*                                                                        */
1672 /*    status                                Completion status             */
1673 /*                                                                        */
1674 /*  CALLS                                                                 */
1675 /*                                                                        */
1676 /*    _nx_ftp_client_directory_delete       Actual client directory       */
1677 /*                                            delete call                 */
1678 /*                                                                        */
1679 /*  CALLED BY                                                             */
1680 /*                                                                        */
1681 /*    Application Code                                                    */
1682 /*                                                                        */
1683 /*  RELEASE HISTORY                                                       */
1684 /*                                                                        */
1685 /*    DATE              NAME                      DESCRIPTION             */
1686 /*                                                                        */
1687 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1688 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1689 /*                                            resulting in version 6.1    */
1690 /*                                                                        */
1691 /**************************************************************************/
_nxe_ftp_client_directory_delete(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_name,ULONG wait_option)1692 UINT  _nxe_ftp_client_directory_delete(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_name, ULONG wait_option)
1693 {
1694 
1695 UINT    status;
1696 
1697 
1698     /* Check for invalid input pointers.  */
1699     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
1700         return(NX_PTR_ERROR);
1701 
1702     /* Check for appropriate caller.  */
1703     NX_THREADS_ONLY_CALLER_CHECKING
1704 
1705     /* Call actual client directory delete function.  */
1706     status =  _nx_ftp_client_directory_delete(ftp_client_ptr, directory_name, wait_option);
1707 
1708     /* Return completion status.  */
1709     return(status);
1710 }
1711 
1712 
1713 /**************************************************************************/
1714 /*                                                                        */
1715 /*  FUNCTION                                               RELEASE        */
1716 /*                                                                        */
1717 /*    _nx_ftp_client_directory_delete                     PORTABLE C      */
1718 /*                                                           6.1          */
1719 /*  AUTHOR                                                                */
1720 /*                                                                        */
1721 /*    Yuxin Zhou, Microsoft Corporation                                   */
1722 /*                                                                        */
1723 /*  DESCRIPTION                                                           */
1724 /*                                                                        */
1725 /*    This function deletes the specified directory on the FTP            */
1726 /*    server.                                                             */
1727 /*                                                                        */
1728 /*    Note: The string length of directory_name is limited by the packet  */
1729 /*    payload size.                                                       */
1730 /*                                                                        */
1731 /*  INPUT                                                                 */
1732 /*                                                                        */
1733 /*    ftp_client_ptr                        Pointer to FTP client         */
1734 /*    directory_name                        Directory name to delete      */
1735 /*    wait_option                           Specifies how long to wait    */
1736 /*                                                                        */
1737 /*  OUTPUT                                                                */
1738 /*                                                                        */
1739 /*    status                                Completion status             */
1740 /*                                                                        */
1741 /*  CALLS                                                                 */
1742 /*                                                                        */
1743 /*    nx_packet_allocate                    Allocate packet               */
1744 /*    nx_packet_release                     Release packet                */
1745 /*    nx_tcp_socket_receive                 Receive packet from server    */
1746 /*    nx_tcp_socket_send                    Send data packet to server    */
1747 /*                                                                        */
1748 /*  CALLED BY                                                             */
1749 /*                                                                        */
1750 /*    Application Code                                                    */
1751 /*                                                                        */
1752 /*  RELEASE HISTORY                                                       */
1753 /*                                                                        */
1754 /*    DATE              NAME                      DESCRIPTION             */
1755 /*                                                                        */
1756 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1757 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1758 /*                                            resulting in version 6.1    */
1759 /*                                                                        */
1760 /**************************************************************************/
_nx_ftp_client_directory_delete(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_name,ULONG wait_option)1761 UINT  _nx_ftp_client_directory_delete(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_name, ULONG wait_option)
1762 {
1763 
1764 UINT        i;
1765 UCHAR       *buffer_ptr;
1766 NX_PACKET   *packet_ptr;
1767 UINT        status;
1768 
1769 
1770     /* Ensure the client is the proper state for directory delete request.  */
1771     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
1772         return(NX_FTP_NOT_CONNECTED);
1773 
1774     /* Allocate a packet for sending the directory delete command.  */
1775     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
1776 
1777     /* Determine if the packet allocation was successful.  */
1778     if (status)
1779     {
1780 
1781         /* Return error.  */
1782         return(status);
1783     }
1784 
1785     /* Check if out of boundary.  */
1786     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 6)
1787      {
1788 
1789         /* Release the packet.  */
1790         nx_packet_release(packet_ptr);
1791 
1792         /* Set the error status.  */
1793         return(NX_FTP_FAILED);
1794     }
1795 
1796     /* We have a packet, setup pointer to the buffer area.  */
1797     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1798 
1799     /* Now build "RMD" message to indicate directory delete.  */
1800     buffer_ptr[0] =  'R';
1801     buffer_ptr[1] =  'M';
1802     buffer_ptr[2] =  'D';
1803     buffer_ptr[3] =  ' ';
1804 
1805     /* Copy the directory name into the message.  */
1806     for(i = 0; directory_name[i]; i++)
1807     {
1808 
1809         /* Check if out of boundary.  */
1810         if ((i + 6) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
1811         {
1812 
1813             /* Release the packet.  */
1814             nx_packet_release(packet_ptr);
1815 
1816             /* Set the error status.  */
1817             return(NX_FTP_FAILED);
1818         }
1819 
1820         /* Copy character of the directory name.  */
1821         buffer_ptr[4+i] =  (UCHAR)directory_name[i];
1822     }
1823 
1824     /* Set the CR/LF.  */
1825     buffer_ptr[i+4] =  13;
1826     buffer_ptr[i+5] =  10;
1827 
1828     /* Set the packet length.  */
1829     packet_ptr -> nx_packet_length =  i+6;
1830 
1831     /* Setup the packet append pointer.  */
1832     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
1833 
1834     /* Send the RMD message.  */
1835     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
1836 
1837     /* Determine if the send was unsuccessful.  */
1838     if (status)
1839     {
1840 
1841         /* Release the packet.  */
1842         nx_packet_release(packet_ptr);
1843 
1844         /* Return error.  */
1845         return(status);
1846     }
1847 
1848     /* Wait for response from the FTP server.  */
1849     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
1850 
1851     /* Determine if a packet was not received.  */
1852     if (status)
1853     {
1854 
1855         /* DELE error. */
1856         return(status);
1857     }
1858 
1859     /* We have a packet, setup pointer to the buffer area.  */
1860     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1861 
1862     /* Check for 2xx message, signaling the "RMD" was processed successfully.  */
1863     if ((packet_ptr -> nx_packet_length < 3) ||(buffer_ptr[0] != '2'))
1864     {
1865 
1866         /* Release the packet.  */
1867         nx_packet_release(packet_ptr);
1868 
1869         /* Delete directory error. */
1870         return(NX_FTP_EXPECTED_2XX_CODE);
1871     }
1872 
1873     /* Yes, the directory was deleted.  */
1874 
1875     /* Release the packet.  */
1876     nx_packet_release(packet_ptr);
1877 
1878     /* Return success to caller.  */
1879     return(NX_SUCCESS);
1880 }
1881 
1882 /**************************************************************************/
1883 /*                                                                        */
1884 /*  FUNCTION                                               RELEASE        */
1885 /*                                                                        */
1886 /*    _nxe_ftp_client_directory_listing_get               PORTABLE C      */
1887 /*                                                           6.1          */
1888 /*  AUTHOR                                                                */
1889 /*                                                                        */
1890 /*    Yuxin Zhou, Microsoft Corporation                                   */
1891 /*                                                                        */
1892 /*  DESCRIPTION                                                           */
1893 /*                                                                        */
1894 /*    This function checks for errors in the FTP client directory         */
1895 /*    listing get.                                                        */
1896 /*                                                                        */
1897 /*    Note: The string length of directory_path is limited by the packet  */
1898 /*    payload size.                                                       */
1899 /*                                                                        */
1900 /*  INPUT                                                                 */
1901 /*                                                                        */
1902 /*    ftp_client_ptr                        Pointer to FTP client         */
1903 /*    directory_path                        Directory to get listing for  */
1904 /*    packet_ptr                            Destination of for the        */
1905 /*                                            received packet pointer     */
1906 /*                                            that contains the listing   */
1907 /*    wait_option                           Specifies how long to wait    */
1908 /*                                                                        */
1909 /*  OUTPUT                                                                */
1910 /*                                                                        */
1911 /*    status                                Completion status             */
1912 /*                                                                        */
1913 /*  CALLS                                                                 */
1914 /*                                                                        */
1915 /*    _nx_ftp_client_directory_listing_get  Actual client directory       */
1916 /*                                            listing get call            */
1917 /*                                                                        */
1918 /*  CALLED BY                                                             */
1919 /*                                                                        */
1920 /*    Application Code                                                    */
1921 /*                                                                        */
1922 /*  RELEASE HISTORY                                                       */
1923 /*                                                                        */
1924 /*    DATE              NAME                      DESCRIPTION             */
1925 /*                                                                        */
1926 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1927 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1928 /*                                            resulting in version 6.1    */
1929 /*                                                                        */
1930 /**************************************************************************/
_nxe_ftp_client_directory_listing_get(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_path,NX_PACKET ** packet_ptr,ULONG wait_option)1931 UINT  _nxe_ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path,
1932                                             NX_PACKET **packet_ptr, ULONG wait_option)
1933 {
1934 
1935 UINT    status;
1936 
1937 
1938     /* Check for invalid input pointers.  */
1939     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (packet_ptr == NX_NULL))
1940         return(NX_PTR_ERROR);
1941 
1942     /* Check for appropriate caller.  */
1943     NX_THREADS_ONLY_CALLER_CHECKING
1944 
1945     /* Call actual client directory listing get function.  */
1946     status =  _nx_ftp_client_directory_listing_get(ftp_client_ptr, directory_path, packet_ptr, wait_option);
1947 
1948     /* Return completion status.  */
1949     return(status);
1950 }
1951 
1952 
1953 /**************************************************************************/
1954 /*                                                                        */
1955 /*  FUNCTION                                               RELEASE        */
1956 /*                                                                        */
1957 /*    _nx_ftp_client_directory_listing_get                PORTABLE C      */
1958 /*                                                           6.1          */
1959 /*  AUTHOR                                                                */
1960 /*                                                                        */
1961 /*    Yuxin Zhou, Microsoft Corporation                                   */
1962 /*                                                                        */
1963 /*  DESCRIPTION                                                           */
1964 /*                                                                        */
1965 /*    This function gets a listing for the specified directory on the     */
1966 /*    FTP server.                                                         */
1967 /*                                                                        */
1968 /*    Note: The string length of directory_path is limited by the packet  */
1969 /*    payload size.                                                       */
1970 /*                                                                        */
1971 /*  INPUT                                                                 */
1972 /*                                                                        */
1973 /*    ftp_client_ptr                        Pointer to FTP client         */
1974 /*    directory_path                        Directory to get listing for  */
1975 /*    packet_ptr                            Destination of for the        */
1976 /*                                            received packet pointer     */
1977 /*                                            that contains the listing   */
1978 /*    wait_option                           Specifies how long to wait    */
1979 /*                                                                        */
1980 /*  OUTPUT                                                                */
1981 /*                                                                        */
1982 /*    status                                Completion status             */
1983 /*                                                                        */
1984 /*  CALLS                                                                 */
1985 /*                                                                        */
1986 /*    _nx_ftp_client_packet_allocate        Allocate packet               */
1987 /*    _nx_ftp_client_active_transfer_setup  Setup active transfer         */
1988 /*    _nx_ftp_client_passive_transfer_setup Setup passive transfer        */
1989 /*    _nx_ftp_client_block_mode_send        Send block mode command       */
1990 /*    _nx_ftp_client_data_socket_cleanup    Cleanup data socket           */
1991 /*    nx_packet_release                     Release packet                */
1992 /*    nx_tcp_server_socket_accept           Connect data socket to server */
1993 /*    nx_tcp_socket_receive                 Receive response from server  */
1994 /*    nx_tcp_socket_send                    Send request to server        */
1995 /*                                                                        */
1996 /*  CALLED BY                                                             */
1997 /*                                                                        */
1998 /*    Application Code                                                    */
1999 /*                                                                        */
2000 /*  RELEASE HISTORY                                                       */
2001 /*                                                                        */
2002 /*    DATE              NAME                      DESCRIPTION             */
2003 /*                                                                        */
2004 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2005 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2006 /*                                            resulting in version 6.1    */
2007 /*                                                                        */
2008 /**************************************************************************/
_nx_ftp_client_directory_listing_get(NX_FTP_CLIENT * ftp_client_ptr,CHAR * directory_path,NX_PACKET ** packet_ptr,ULONG wait_option)2009 UINT  _nx_ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path,
2010                                            NX_PACKET **packet_ptr, ULONG wait_option)
2011 {
2012 
2013 UINT        i;
2014 UCHAR       *buffer_ptr;
2015 NX_PACKET   *new_packet_ptr;
2016 UINT        status;
2017 
2018 
2019     /* Set packet pointer to NULL.  */
2020     *packet_ptr =  NX_NULL;
2021 
2022     /* Ensure the client is the proper state for directory listing request.  */
2023     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
2024         return(NX_FTP_NOT_CONNECTED);
2025 
2026     /* Divert to passive mode operation if passive mode is enabled.  */
2027     if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled)
2028     {
2029 
2030         /* Transfer the data in passive transfer mode.  */
2031         status = _nx_ftp_client_passive_transfer_setup(ftp_client_ptr,  wait_option);
2032     }
2033     else
2034     {
2035 
2036         /* Transfer the data in active transfer mode. */
2037         status = _nx_ftp_client_active_transfer_setup(ftp_client_ptr, wait_option);
2038     }
2039 
2040     /* Determine if set up successful.  */
2041     if (status)
2042     {
2043         return(status);
2044     }
2045 
2046     /* Check if enable block mode.  */
2047     if (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK)
2048     {
2049 
2050         /* Send MODE B command to FTP server.  */
2051         status = _nx_ftp_client_block_mode_send(ftp_client_ptr, wait_option);
2052 
2053         /* Determine if the send was unsuccessful.  */
2054         if (status != NX_SUCCESS)
2055         {
2056 
2057             /* Cleanup data socket.  */
2058             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2059             return(status);
2060         }
2061     }
2062 
2063     /* Allocate a packet for sending the NLST command.  */
2064     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &new_packet_ptr, wait_option);
2065 
2066     /* Determine if the packet allocation was successful.  */
2067     if (status != NX_SUCCESS)
2068     {
2069 
2070         /* Cleanup data socket.  */
2071         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2072 
2073         /* Return error.  */
2074         return(status);
2075     }
2076 
2077     /* Check if out of boundary.  */
2078     if ((UINT)(new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_prepend_ptr) < 7)
2079      {
2080 
2081         /* Cleanup data socket.  */
2082         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2083 
2084         /* Release the packet.  */
2085         nx_packet_release(new_packet_ptr);
2086 
2087         /* Set the error status.  */
2088         return(NX_FTP_FAILED);
2089     }
2090 
2091     /* We have a packet, setup pointer to the buffer area.  */
2092     buffer_ptr =  new_packet_ptr -> nx_packet_prepend_ptr;
2093 
2094     /* Now build the actual NLST request.  */
2095     buffer_ptr[0] =  'N';
2096     buffer_ptr[1] =  'L';
2097     buffer_ptr[2] =  'S';
2098     buffer_ptr[3] =  'T';
2099     buffer_ptr[4] =  ' ';
2100 
2101     /* Copy the directory path into the buffer.  */
2102     for(i = 0; directory_path[i]; i++)
2103     {
2104 
2105         /* Check if out of boundary.  */
2106         if ((i + 7) >= (UINT)(new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_prepend_ptr))
2107         {
2108 
2109             /* Cleanup data socket.  */
2110             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2111 
2112             /* Release the packet.  */
2113             nx_packet_release(new_packet_ptr);
2114 
2115             /* Set the error status.  */
2116             return(NX_FTP_FAILED);
2117         }
2118 
2119         /* Copy character of directory path.  */
2120         buffer_ptr[5+i] =  (UCHAR)directory_path[i];
2121     }
2122 
2123     /* Insert the CR/LF.  */
2124     buffer_ptr[5+i] =   13;
2125     buffer_ptr[5+i+1] = 10;
2126 
2127     /* Setup the length of the packet.  */
2128     new_packet_ptr -> nx_packet_length =  i + 7;
2129 
2130     /* Setup the packet append pointer.  */
2131     new_packet_ptr -> nx_packet_append_ptr =  new_packet_ptr -> nx_packet_prepend_ptr + new_packet_ptr -> nx_packet_length;
2132 
2133     /* Send the NLST message.  */
2134     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket),  new_packet_ptr, wait_option);
2135 
2136     /* Determine if the send was unsuccessful.  */
2137     if (status)
2138     {
2139 
2140         /* Cleanup data socket.  */
2141         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2142 
2143         /* Release the packet.  */
2144         nx_packet_release(new_packet_ptr);
2145 
2146         /* Return error.  */
2147         return(status);
2148     }
2149 
2150     /* Check if enable passive mode.  */
2151     if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled == NX_FALSE)
2152     {
2153 
2154         /* Now wait for the data connection to connect.  */
2155         status =  nx_tcp_server_socket_accept(&(ftp_client_ptr -> nx_ftp_client_data_socket), wait_option);
2156 
2157         /* Determine if the accept was unsuccessful.  */
2158         if (status)
2159         {
2160 
2161             /* Cleanup data socket.  */
2162             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2163 
2164             /* Return error.  */
2165             return(status);
2166         }
2167     }
2168 
2169     /* Now wait for response from the FTP server control port.  */
2170     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &new_packet_ptr, wait_option);
2171 
2172     /* Determine if a packet was not received.  */
2173     if (status)
2174     {
2175 
2176         /* Cleanup data socket.  */
2177         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2178 
2179         /* Error in NLST request to FTP server. */
2180         return(status);
2181     }
2182 
2183     /* We have a packet, setup pointer to the buffer area.  */
2184     buffer_ptr =  new_packet_ptr -> nx_packet_prepend_ptr;
2185 
2186     /* Check for 1xx message, signaling the data port was connected properly and ready for
2187        transfer.  */
2188     if ((new_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '1'))
2189     {
2190 
2191         /* Cleanup data socket.  */
2192         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2193 
2194         /* Release the packet.  */
2195         nx_packet_release(new_packet_ptr);
2196 
2197         /* Error in NLST request to FTP server. */
2198         return(NX_FTP_EXPECTED_1XX_CODE);
2199     }
2200 
2201     /* Release the last packet.  */
2202     nx_packet_release(new_packet_ptr);
2203 
2204     /* Now read a listing packet from the data socket.  */
2205     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option);
2206 
2207     /* Determine if an error occurred.  */
2208     if (status)
2209     {
2210 
2211         /* Cleanup data socket.  */
2212         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2213 
2214         /* Map all unsuccessful status to error.  */
2215         return(status);
2216     }
2217 
2218     /* Determine if the block mode is enabled.  */
2219     if (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK)
2220     {
2221 
2222         /* Retrieve the block header.  */
2223         status = _nx_ftp_client_block_header_retrieve(ftp_client_ptr, (*packet_ptr));
2224 
2225         /* Determine if an error occurred.  */
2226         if (status)
2227         {
2228 
2229             /* Cleanup data socket.  */
2230             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2231         }
2232     }
2233 
2234     /* Return staus to caller.  */
2235     return(status);
2236 }
2237 
2238 
2239 /**************************************************************************/
2240 /*                                                                        */
2241 /*  FUNCTION                                               RELEASE        */
2242 /*                                                                        */
2243 /*    _nxe_ftp_client_directory_listing_continue          PORTABLE C      */
2244 /*                                                           6.1          */
2245 /*  AUTHOR                                                                */
2246 /*                                                                        */
2247 /*    Yuxin Zhou, Microsoft Corporation                                   */
2248 /*                                                                        */
2249 /*  DESCRIPTION                                                           */
2250 /*                                                                        */
2251 /*    This function checks for errors in the FTP client directory         */
2252 /*    listing continue.                                                   */
2253 /*                                                                        */
2254 /*                                                                        */
2255 /*  INPUT                                                                 */
2256 /*                                                                        */
2257 /*    ftp_client_ptr                        Pointer to FTP client         */
2258 /*    packet_ptr                            Destination of for the        */
2259 /*                                            received packet pointer     */
2260 /*                                            that contains the listing   */
2261 /*    wait_option                           Specifies how long to wait    */
2262 /*                                                                        */
2263 /*  OUTPUT                                                                */
2264 /*                                                                        */
2265 /*    status                                Completion status             */
2266 /*                                                                        */
2267 /*  CALLS                                                                 */
2268 /*                                                                        */
2269 /*    _nx_ftp_client_directory_listing_continue  Actual client directory  */
2270 /*                                                 listing continue call  */
2271 /*                                                                        */
2272 /*  CALLED BY                                                             */
2273 /*                                                                        */
2274 /*    Application Code                                                    */
2275 /*                                                                        */
2276 /*  RELEASE HISTORY                                                       */
2277 /*                                                                        */
2278 /*    DATE              NAME                      DESCRIPTION             */
2279 /*                                                                        */
2280 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2281 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2282 /*                                            resulting in version 6.1    */
2283 /*                                                                        */
2284 /**************************************************************************/
_nxe_ftp_client_directory_listing_continue(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)2285 UINT  _nxe_ftp_client_directory_listing_continue(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
2286 {
2287 
2288 UINT    status;
2289 
2290 
2291     /* Check for invalid input pointers.  */
2292     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (packet_ptr == NX_NULL))
2293         return(NX_PTR_ERROR);
2294 
2295     /* Check for appropriate caller.  */
2296     NX_THREADS_ONLY_CALLER_CHECKING
2297 
2298     /* Call actual client directory listing continue function.  */
2299     status =  _nx_ftp_client_directory_listing_continue(ftp_client_ptr, packet_ptr, wait_option);
2300 
2301     /* Return completion status.  */
2302     return(status);
2303 }
2304 
2305 
2306 /**************************************************************************/
2307 /*                                                                        */
2308 /*  FUNCTION                                               RELEASE        */
2309 /*                                                                        */
2310 /*    _nx_ftp_client_directory_listing_continue           PORTABLE C      */
2311 /*                                                           6.1          */
2312 /*  AUTHOR                                                                */
2313 /*                                                                        */
2314 /*    Yuxin Zhou, Microsoft Corporation                                   */
2315 /*                                                                        */
2316 /*  DESCRIPTION                                                           */
2317 /*                                                                        */
2318 /*    This function gets the next listing buffer.  It is assumed that     */
2319 /*    a successful _nx_ftp_client_directory_listing_get immediately       */
2320 /*    preceded this call.                                                 */
2321 /*                                                                        */
2322 /*                                                                        */
2323 /*  INPUT                                                                 */
2324 /*                                                                        */
2325 /*    ftp_client_ptr                        Pointer to FTP client         */
2326 /*    packet_ptr                            Destination of for the        */
2327 /*                                            received packet pointer     */
2328 /*                                            that contains the listing   */
2329 /*    wait_option                           Specifies how long to wait    */
2330 /*                                                                        */
2331 /*  OUTPUT                                                                */
2332 /*                                                                        */
2333 /*    status                                Completion status             */
2334 /*                                                                        */
2335 /*  CALLS                                                                 */
2336 /*                                                                        */
2337 /*    _nx_ftp_client_data_socket_cleanup    Cleanup data socket           */
2338 /*    nx_tcp_server_socket_unaccept         Unaccept server connection    */
2339 /*    nx_tcp_server_socket_unlisten         Unlisten on server port       */
2340 /*    nx_tcp_socket_receive                 Receive packet from server    */
2341 /*                                                                        */
2342 /*  CALLED BY                                                             */
2343 /*                                                                        */
2344 /*    Application Code                                                    */
2345 /*                                                                        */
2346 /*  RELEASE HISTORY                                                       */
2347 /*                                                                        */
2348 /*    DATE              NAME                      DESCRIPTION             */
2349 /*                                                                        */
2350 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2351 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2352 /*                                            resulting in version 6.1    */
2353 /*                                                                        */
2354 /**************************************************************************/
_nx_ftp_client_directory_listing_continue(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)2355 UINT  _nx_ftp_client_directory_listing_continue(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
2356 {
2357 
2358 UINT        status;
2359 NX_PACKET   *response_ptr;
2360 UCHAR       *buffer_ptr;
2361 
2362 
2363     /* Set packet pointer to NULL.  */
2364     *packet_ptr =  NX_NULL;
2365 
2366     /* Ensure the client is the proper state for directory listing request.  */
2367     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
2368         return(NX_FTP_NOT_CONNECTED);
2369 
2370     /* Now read a listing packet from the data socket.  */
2371     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option);
2372 
2373     /* Determine if the block mode is enabled.  */
2374     if ((status == NX_SUCCESS) &&
2375         (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK))
2376     {
2377 
2378         /* Retrieve the block header.  */
2379         status = _nx_ftp_client_block_header_retrieve(ftp_client_ptr, (*packet_ptr));
2380     }
2381 
2382     /* Determine if an error occurred.  */
2383     if (status)
2384     {
2385 
2386         /* Cleanup data socket.  */
2387         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2388 
2389         /* Wait for response from the FTP server on the control socket.  */
2390         status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &response_ptr, wait_option);
2391 
2392         /* Determine if a packet was not received.  */
2393         if (status)
2394         {
2395 
2396             /* Directory listing error. */
2397             return(status);
2398         }
2399 
2400         /* We have a packet, setup pointer to the buffer area.  */
2401         buffer_ptr =  response_ptr -> nx_packet_prepend_ptr;
2402 
2403         /* Check for 2xx message, signaling the "NLST" was processed successfully.  */
2404         if ((response_ptr -> nx_packet_length >= 3) && (buffer_ptr[0] == '2'))
2405         {
2406 
2407             /* Release the packet.  */
2408             nx_packet_release(response_ptr);
2409 
2410             /* Appropriate end of listing error. */
2411             return(NX_FTP_END_OF_LISTING);
2412         }
2413         else
2414         {
2415 
2416             /* Release the packet.  */
2417             nx_packet_release(response_ptr);
2418 
2419             /* Map all other unsuccessful status to error.  */
2420             return(NX_FTP_EXPECTED_2XX_CODE);
2421         }
2422     }
2423 
2424     /* Return success to caller.  */
2425     return(status);
2426 }
2427 
2428 
2429 /**************************************************************************/
2430 /*                                                                        */
2431 /*  FUNCTION                                               RELEASE        */
2432 /*                                                                        */
2433 /*    _nxe_ftp_client_disconnect                          PORTABLE C      */
2434 /*                                                           6.1          */
2435 /*  AUTHOR                                                                */
2436 /*                                                                        */
2437 /*    Yuxin Zhou, Microsoft Corporation                                   */
2438 /*                                                                        */
2439 /*  DESCRIPTION                                                           */
2440 /*                                                                        */
2441 /*    This function checks for errors in the FTP client disconnect.       */
2442 /*                                                                        */
2443 /*                                                                        */
2444 /*  INPUT                                                                 */
2445 /*                                                                        */
2446 /*    ftp_client_ptr                        Pointer to FTP client         */
2447 /*    wait_option                           Specifies how long to wait    */
2448 /*                                                                        */
2449 /*  OUTPUT                                                                */
2450 /*                                                                        */
2451 /*    status                                Completion status             */
2452 /*                                                                        */
2453 /*  CALLS                                                                 */
2454 /*                                                                        */
2455 /*    _nx_ftp_client_disconnect             Actual client disconnect call */
2456 /*                                                                        */
2457 /*  CALLED BY                                                             */
2458 /*                                                                        */
2459 /*    Application Code                                                    */
2460 /*                                                                        */
2461 /*  RELEASE HISTORY                                                       */
2462 /*                                                                        */
2463 /*    DATE              NAME                      DESCRIPTION             */
2464 /*                                                                        */
2465 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2466 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2467 /*                                            resulting in version 6.1    */
2468 /*                                                                        */
2469 /**************************************************************************/
_nxe_ftp_client_disconnect(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)2470 UINT  _nxe_ftp_client_disconnect(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
2471 {
2472 
2473 UINT    status;
2474 
2475 
2476     /* Check for invalid input pointers.  */
2477     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
2478         return(NX_PTR_ERROR);
2479 
2480     /* Check for appropriate caller.  */
2481     NX_THREADS_ONLY_CALLER_CHECKING
2482 
2483     /* Call actual client disconnect function.  */
2484     status =  _nx_ftp_client_disconnect(ftp_client_ptr, wait_option);
2485 
2486     /* Return completion status.  */
2487     return(status);
2488 }
2489 
2490 
2491 /**************************************************************************/
2492 /*                                                                        */
2493 /*  FUNCTION                                               RELEASE        */
2494 /*                                                                        */
2495 /*    _nx_ftp_client_disconnect                           PORTABLE C      */
2496 /*                                                           6.1          */
2497 /*  AUTHOR                                                                */
2498 /*                                                                        */
2499 /*    Yuxin Zhou, Microsoft Corporation                                   */
2500 /*                                                                        */
2501 /*  DESCRIPTION                                                           */
2502 /*                                                                        */
2503 /*    This function disconnects a previously established FTP connection.  */
2504 /*                                                                        */
2505 /*                                                                        */
2506 /*  INPUT                                                                 */
2507 /*                                                                        */
2508 /*    ftp_client_ptr                        Pointer to FTP client         */
2509 /*    wait_option                           Specifies how long to wait    */
2510 /*                                                                        */
2511 /*  OUTPUT                                                                */
2512 /*                                                                        */
2513 /*    status                                Completion status             */
2514 /*                                                                        */
2515 /*  CALLS                                                                 */
2516 /*                                                                        */
2517 /*    nx_packet_allocate                    Allocate packet               */
2518 /*    nx_packet_release                     Release packet                */
2519 /*    nx_tcp_client_socket_unbind           Unbind a socket               */
2520 /*    nx_tcp_socket_disconnect              Disconnect a socket           */
2521 /*    nx_tcp_socket_receive                 Receive response from server  */
2522 /*    nx_tcp_socket_send                    Send request to server        */
2523 /*                                                                        */
2524 /*  CALLED BY                                                             */
2525 /*                                                                        */
2526 /*    Application Code                                                    */
2527 /*                                                                        */
2528 /*  RELEASE HISTORY                                                       */
2529 /*                                                                        */
2530 /*    DATE              NAME                      DESCRIPTION             */
2531 /*                                                                        */
2532 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2533 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2534 /*                                            resulting in version 6.1    */
2535 /*                                                                        */
2536 /**************************************************************************/
_nx_ftp_client_disconnect(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)2537 UINT  _nx_ftp_client_disconnect(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
2538 {
2539 
2540 NX_PACKET   *packet_ptr;
2541 UCHAR       *buffer_ptr;
2542 UINT        status;
2543 
2544 
2545     /* Determine if the client is in a not connected state.  */
2546     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
2547     {
2548 
2549         /* Already connected, return an error.  */
2550         return(NX_FTP_NOT_CONNECTED);
2551     }
2552 
2553     /* Enter the not connected state.  */
2554     ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_NOT_CONNECTED;
2555 
2556     /* Allocate a packet for sending the port and IP address.  */
2557     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
2558 
2559     /* Determine if the packet allocation was successful.  */
2560     if (status)
2561     {
2562 
2563         /* Clean up connection socket.  */
2564         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2565         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2566 
2567         /* Return error.  */
2568         return(status);
2569     }
2570 
2571     /* Check if out of boundary.  */
2572     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 6)
2573      {
2574 
2575         /* Clean up connection socket.  */
2576         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2577         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2578 
2579         /* Release the packet.  */
2580         nx_packet_release(packet_ptr);
2581 
2582         /* Set the error status.  */
2583         return(NX_FTP_FAILED);
2584     }
2585 
2586     /* We have a packet, setup pointer to the buffer area.  */
2587     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2588 
2589     /* Build QUIT message to end the FTP connection.  */
2590     buffer_ptr[0] =  'Q';
2591     buffer_ptr[1] =  'U';
2592     buffer_ptr[2] =  'I';
2593     buffer_ptr[3] =  'T';
2594     buffer_ptr[4] =  13;
2595     buffer_ptr[5] =  10;
2596 
2597     /* Set the packet length.  */
2598     packet_ptr -> nx_packet_length =  6;
2599 
2600     /* Setup the packet append pointer.  */
2601     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
2602 
2603     /* Send the QUIT message.  */
2604     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
2605 
2606     /* Determine if the send was unsuccessful.  */
2607     if (status)
2608     {
2609 
2610         /* Clean up connection socket.  */
2611         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2612         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2613 
2614         /* Release the packet.  */
2615         nx_packet_release(packet_ptr);
2616 
2617         /* Return error.  */
2618         return(status);
2619     }
2620 
2621     /* Wait for response from the FTP server.  */
2622     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
2623 
2624     /* Determine if a packet was not received.  */
2625     if (status)
2626     {
2627 
2628         /* Clean up connection socket.  */
2629         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2630         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2631 
2632         /* Unable to connect socket to server FTP control port. */
2633         return(status);
2634     }
2635 
2636     /* We have a packet, setup pointer to the buffer area.  */
2637     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2638 
2639     /* Check for 2xx message, signaling the disconnect was processed properly.  */
2640     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
2641     {
2642 
2643         /* Clean up connection socket.  */
2644         nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2645         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2646 
2647         /* Release the packet.  */
2648         nx_packet_release(packet_ptr);
2649 
2650         /* Return error.  */
2651         return(NX_FTP_EXPECTED_2XX_CODE);
2652     }
2653 
2654     /* Success.  Disconnect and unbind the control socket.  */
2655     nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_control_socket), wait_option);
2656     nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_control_socket));
2657 
2658     /* Release the packet.  */
2659     nx_packet_release(packet_ptr);
2660 
2661     /* Return success to caller.  */
2662     return(NX_SUCCESS);
2663 }
2664 
2665 
2666 /**************************************************************************/
2667 /*                                                                        */
2668 /*  FUNCTION                                               RELEASE        */
2669 /*                                                                        */
2670 /*    _nxe_ftp_client_file_close                          PORTABLE C      */
2671 /*                                                           6.1          */
2672 /*  AUTHOR                                                                */
2673 /*                                                                        */
2674 /*    Yuxin Zhou, Microsoft Corporation                                   */
2675 /*                                                                        */
2676 /*  DESCRIPTION                                                           */
2677 /*                                                                        */
2678 /*    This function checks for errors in the FTP client file close.       */
2679 /*                                                                        */
2680 /*                                                                        */
2681 /*  INPUT                                                                 */
2682 /*                                                                        */
2683 /*    ftp_client_ptr                        Pointer to FTP client         */
2684 /*    wait_option                           Specifies how long to wait    */
2685 /*                                                                        */
2686 /*  OUTPUT                                                                */
2687 /*                                                                        */
2688 /*    status                                Completion status             */
2689 /*                                                                        */
2690 /*  CALLS                                                                 */
2691 /*                                                                        */
2692 /*    _nx_ftp_client_file_close             Actual client file close call */
2693 /*                                                                        */
2694 /*  CALLED BY                                                             */
2695 /*                                                                        */
2696 /*    Application Code                                                    */
2697 /*                                                                        */
2698 /*  RELEASE HISTORY                                                       */
2699 /*                                                                        */
2700 /*    DATE              NAME                      DESCRIPTION             */
2701 /*                                                                        */
2702 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2703 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2704 /*                                            resulting in version 6.1    */
2705 /*                                                                        */
2706 /**************************************************************************/
_nxe_ftp_client_file_close(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)2707 UINT  _nxe_ftp_client_file_close(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
2708 {
2709 
2710 UINT    status;
2711 
2712 
2713     /* Check for invalid input pointers.  */
2714     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
2715         return(NX_PTR_ERROR);
2716 
2717 
2718     /* Check for appropriate caller.  */
2719     NX_THREADS_ONLY_CALLER_CHECKING
2720 
2721     /* Call actual client file close function.  */
2722     status =  _nx_ftp_client_file_close(ftp_client_ptr, wait_option);
2723 
2724     /* Return completion status.  */
2725     return(status);
2726 }
2727 
2728 
2729 /**************************************************************************/
2730 /*                                                                        */
2731 /*  FUNCTION                                               RELEASE        */
2732 /*                                                                        */
2733 /*    _nx_ftp_client_file_close                           PORTABLE C      */
2734 /*                                                           6.1          */
2735 /*  AUTHOR                                                                */
2736 /*                                                                        */
2737 /*    Yuxin Zhou, Microsoft Corporation                                   */
2738 /*                                                                        */
2739 /*  DESCRIPTION                                                           */
2740 /*                                                                        */
2741 /*    This function closes a previously open client FTP file.             */
2742 /*                                                                        */
2743 /*                                                                        */
2744 /*  INPUT                                                                 */
2745 /*                                                                        */
2746 /*    ftp_client_ptr                        Pointer to FTP client         */
2747 /*    wait_option                           Specifies how long to wait    */
2748 /*                                                                        */
2749 /*  OUTPUT                                                                */
2750 /*                                                                        */
2751 /*    status                                Completion status             */
2752 /*                                                                        */
2753 /*  CALLS                                                                 */
2754 /*                                                                        */
2755 /*    _nx_ftp_client_data_socket_cleanup    Cleanup data socket           */
2756 /*    nx_packet_release                     Release packet                */
2757 /*    nx_tcp_server_socket_unaccept         Unaccept server connection    */
2758 /*    nx_tcp_server_socket_unlisten         Unlisten on server socket     */
2759 /*    nx_tcp_socket_disconnect              Disconnect a socket           */
2760 /*    nx_tcp_socket_receive                 Receive response from server  */
2761 /*                                                                        */
2762 /*  CALLED BY                                                             */
2763 /*                                                                        */
2764 /*    Application Code                                                    */
2765 /*                                                                        */
2766 /*  RELEASE HISTORY                                                       */
2767 /*                                                                        */
2768 /*    DATE              NAME                      DESCRIPTION             */
2769 /*                                                                        */
2770 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2771 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2772 /*                                            resulting in version 6.1    */
2773 /*                                                                        */
2774 /**************************************************************************/
_nx_ftp_client_file_close(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)2775 UINT  _nx_ftp_client_file_close(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
2776 {
2777 
2778 NX_PACKET   *packet_ptr;
2779 UCHAR       *buffer_ptr;
2780 UINT        status;
2781 
2782 
2783     /* Ensure the client is in the proper state for closing the socket.  */
2784     if (ftp_client_ptr -> nx_ftp_client_state == NX_FTP_STATE_NOT_CONNECTED)
2785         return(NX_FTP_NOT_CONNECTED);
2786     else if ((ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_OPEN) &&
2787              (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_WRITE_OPEN))
2788         return(NX_FTP_NOT_OPEN);
2789 
2790     /* Cleanup data socket.  */
2791     _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
2792 
2793     /* Set the state to connected.  */
2794     ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_CONNECTED;
2795 
2796     /* Wait for response from the FTP server.  */
2797     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
2798 
2799     /* Determine if a packet was not received.  */
2800     if (status)
2801     {
2802 
2803         /* Unable to connect socket to server FTP control port. */
2804         return(status);
2805     }
2806 
2807     /* We have a packet, setup pointer to the packet payload area.  */
2808     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2809 
2810     /* Check for 2xx message, signaling the close was processed properly.  */
2811     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
2812     {
2813 
2814         /* Release the packet.  */
2815         nx_packet_release(packet_ptr);
2816 
2817         /* Return error.  */
2818         return(NX_FTP_EXPECTED_2XX_CODE);
2819     }
2820 
2821     /* Release the packet.  */
2822     nx_packet_release(packet_ptr);
2823 
2824     /* Return success to caller.  */
2825     return(NX_SUCCESS);
2826 }
2827 
2828 
2829 /**************************************************************************/
2830 /*                                                                        */
2831 /*  FUNCTION                                               RELEASE        */
2832 /*                                                                        */
2833 /*    _nxe_ftp_client_file_delete                         PORTABLE C      */
2834 /*                                                           6.1          */
2835 /*  AUTHOR                                                                */
2836 /*                                                                        */
2837 /*    Yuxin Zhou, Microsoft Corporation                                   */
2838 /*                                                                        */
2839 /*  DESCRIPTION                                                           */
2840 /*                                                                        */
2841 /*    This function checks for errors in the FTP client file delete.      */
2842 /*                                                                        */
2843 /*    Note: The string length of file_name is limited by the packet       */
2844 /*    payload size.                                                       */
2845 /*                                                                        */
2846 /*  INPUT                                                                 */
2847 /*                                                                        */
2848 /*    ftp_client_ptr                        Pointer to FTP client         */
2849 /*    file_name                             File name to delete           */
2850 /*    wait_option                           Specifies how long to wait    */
2851 /*                                                                        */
2852 /*  OUTPUT                                                                */
2853 /*                                                                        */
2854 /*    status                                Completion status             */
2855 /*                                                                        */
2856 /*  CALLS                                                                 */
2857 /*                                                                        */
2858 /*    _nx_ftp_client_file_delete            Actual client file delete call*/
2859 /*                                                                        */
2860 /*  CALLED BY                                                             */
2861 /*                                                                        */
2862 /*    Application Code                                                    */
2863 /*                                                                        */
2864 /*  RELEASE HISTORY                                                       */
2865 /*                                                                        */
2866 /*    DATE              NAME                      DESCRIPTION             */
2867 /*                                                                        */
2868 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2869 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2870 /*                                            resulting in version 6.1    */
2871 /*                                                                        */
2872 /**************************************************************************/
_nxe_ftp_client_file_delete(NX_FTP_CLIENT * ftp_client_ptr,CHAR * file_name,ULONG wait_option)2873 UINT  _nxe_ftp_client_file_delete(NX_FTP_CLIENT *ftp_client_ptr, CHAR *file_name, ULONG wait_option)
2874 {
2875 
2876 UINT    status;
2877 
2878 
2879     /* Check for invalid input pointers.  */
2880     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (file_name == NX_NULL))
2881         return(NX_PTR_ERROR);
2882 
2883     /* Check for appropriate caller.  */
2884     NX_THREADS_ONLY_CALLER_CHECKING
2885 
2886     /* Call actual client file delete function.  */
2887     status =  _nx_ftp_client_file_delete(ftp_client_ptr, file_name, wait_option);
2888 
2889     /* Return completion status.  */
2890     return(status);
2891 }
2892 
2893 
2894 /**************************************************************************/
2895 /*                                                                        */
2896 /*  FUNCTION                                               RELEASE        */
2897 /*                                                                        */
2898 /*    _nx_ftp_client_file_delete                          PORTABLE C      */
2899 /*                                                           6.1          */
2900 /*  AUTHOR                                                                */
2901 /*                                                                        */
2902 /*    Yuxin Zhou, Microsoft Corporation                                   */
2903 /*                                                                        */
2904 /*  DESCRIPTION                                                           */
2905 /*                                                                        */
2906 /*    This function deletes the specified file on the FTP                 */
2907 /*    server.                                                             */
2908 /*                                                                        */
2909 /*    Note: The string length of file_name is limited by the packet       */
2910 /*    payload size.                                                       */
2911 /*                                                                        */
2912 /*  INPUT                                                                 */
2913 /*                                                                        */
2914 /*    ftp_client_ptr                        Pointer to FTP client         */
2915 /*    file_name                             File name to delete           */
2916 /*    wait_option                           Specifies how long to wait    */
2917 /*                                                                        */
2918 /*  OUTPUT                                                                */
2919 /*                                                                        */
2920 /*    status                                Completion status             */
2921 /*                                                                        */
2922 /*  CALLS                                                                 */
2923 /*                                                                        */
2924 /*    nx_packet_allocate                    Allocate packet               */
2925 /*    nx_packet_release                     Release packet                */
2926 /*    nx_tcp_socket_receive                 Receive packet from server    */
2927 /*    nx_tcp_socket_send                    Send data packet to server    */
2928 /*                                                                        */
2929 /*  CALLED BY                                                             */
2930 /*                                                                        */
2931 /*    Application Code                                                    */
2932 /*                                                                        */
2933 /*  RELEASE HISTORY                                                       */
2934 /*                                                                        */
2935 /*    DATE              NAME                      DESCRIPTION             */
2936 /*                                                                        */
2937 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2938 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2939 /*                                            resulting in version 6.1    */
2940 /*                                                                        */
2941 /**************************************************************************/
_nx_ftp_client_file_delete(NX_FTP_CLIENT * ftp_client_ptr,CHAR * file_name,ULONG wait_option)2942 UINT  _nx_ftp_client_file_delete(NX_FTP_CLIENT *ftp_client_ptr, CHAR *file_name, ULONG wait_option)
2943 {
2944 
2945 UINT        i;
2946 UCHAR       *buffer_ptr;
2947 NX_PACKET   *packet_ptr;
2948 UINT        status;
2949 
2950 
2951     /* Ensure the client is the proper state for file delete request.  */
2952     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
2953         return(NX_FTP_NOT_CONNECTED);
2954 
2955     /* Allocate a packet for sending the file delete command.  */
2956     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
2957 
2958     /* Determine if the packet allocation was successful.  */
2959     if (status)
2960     {
2961 
2962         /* Return error.  */
2963         return(status);
2964     }
2965 
2966     /* Check if out of boundary.  */
2967     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 7)
2968      {
2969 
2970         /* Release the packet.  */
2971         nx_packet_release(packet_ptr);
2972 
2973         /* Set the error status.  */
2974         return(NX_FTP_FAILED);
2975     }
2976 
2977     /* We have a packet, setup pointer to the buffer area.  */
2978     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2979 
2980     /* Now build "DELE" message to indicate file delete.  */
2981     buffer_ptr[0] =  'D';
2982     buffer_ptr[1] =  'E';
2983     buffer_ptr[2] =  'L';
2984     buffer_ptr[3] =  'E';
2985     buffer_ptr[4] =  ' ';
2986 
2987     /* Copy the file name into the message.  */
2988     for(i = 0; file_name[i]; i++)
2989     {
2990 
2991         /* Check if out of boundary.  */
2992         if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
2993         {
2994 
2995             /* Release the packet.  */
2996             nx_packet_release(packet_ptr);
2997 
2998             /* Set the error status.  */
2999             return(NX_FTP_FAILED);
3000         }
3001 
3002         /* Copy character of the file name.  */
3003         buffer_ptr[5+i] =  (UCHAR)file_name[i];
3004     }
3005 
3006     /* Set the CR/LF.  */
3007     buffer_ptr[i+5] =  13;
3008     buffer_ptr[i+6] =  10;
3009 
3010     /* Set the packet length.  */
3011     packet_ptr -> nx_packet_length =  i+7;
3012 
3013     /* Setup the packet append pointer.  */
3014     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3015 
3016     /* Send the DELE message.  */
3017     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
3018 
3019     /* Determine if the send was unsuccessful.  */
3020     if (status)
3021     {
3022 
3023         /* Release the packet.  */
3024         nx_packet_release(packet_ptr);
3025 
3026         /* Return error.  */
3027         return(status);
3028     }
3029 
3030     /* Wait for response from the FTP server.  */
3031     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
3032 
3033     /* Determine if a packet was not received.  */
3034     if (status)
3035     {
3036 
3037         /* DELE error. */
3038         return(status);
3039     }
3040 
3041     /* We have a packet, setup pointer to the buffer area.  */
3042     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3043 
3044     /* Check for 2xx message, signaling the "DELE" was processed successfully.  */
3045     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
3046     {
3047 
3048         /* Release the packet.  */
3049         nx_packet_release(packet_ptr);
3050 
3051         /* File delete error. */
3052         return(NX_FTP_EXPECTED_2XX_CODE);
3053     }
3054 
3055     /* Yes, the file was deleted.  */
3056 
3057     /* Release the packet.  */
3058     nx_packet_release(packet_ptr);
3059 
3060     /* Return success to caller.  */
3061     return(NX_SUCCESS);
3062 }
3063 
3064 /**************************************************************************/
3065 /*                                                                        */
3066 /*  FUNCTION                                               RELEASE        */
3067 /*                                                                        */
3068 /*    _nxe_ftp_client_passive_mode_set                    PORTABLE C      */
3069 /*                                                           6.1          */
3070 /*  AUTHOR                                                                */
3071 /*                                                                        */
3072 /*    Yuxin Zhou, Microsoft Corporation                                   */
3073 /*                                                                        */
3074 /*  DESCRIPTION                                                           */
3075 /*                                                                        */
3076 /*    This function sets the request to passive mode. Once this is set    */
3077 /*    the Client will send a PASV command preceding any FTP Client command*/
3078 /*    involving transferring data on the data socket.                     */
3079 /*                                                                        */
3080 /*  INPUT                                                                 */
3081 /*                                                                        */
3082 /*    ftp_client_ptr                        Pointer to FTP client         */
3083 /*    passive_mode_enabled                  True to enable                */
3084 /*                                          False to disable              */
3085 /*                                                                        */
3086 /*  OUTPUT                                                                */
3087 /*                                                                        */
3088 /*    NX_PTR_ERROR                          Invalid pointer input         */
3089 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
3090 /*    status                                Completion status             */
3091 /*                                                                        */
3092 /*  CALLS                                                                 */
3093 /*     None                                                               */
3094 /*                                                                        */
3095 /*  CALLED BY                                                             */
3096 /*                                                                        */
3097 /*    Application Code                                                    */
3098 /*                                                                        */
3099 /*  RELEASE HISTORY                                                       */
3100 /*                                                                        */
3101 /*    DATE              NAME                      DESCRIPTION             */
3102 /*                                                                        */
3103 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3104 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3105 /*                                            resulting in version 6.1    */
3106 /*                                                                        */
3107 /**************************************************************************/
_nxe_ftp_client_passive_mode_set(NX_FTP_CLIENT * ftp_client_ptr,UINT passive_mode_enabled)3108 UINT  _nxe_ftp_client_passive_mode_set(NX_FTP_CLIENT *ftp_client_ptr, UINT passive_mode_enabled)
3109 {
3110 
3111 UINT status;
3112 
3113     if (ftp_client_ptr == NX_NULL)
3114     {
3115         return NX_PTR_ERROR;
3116     }
3117 
3118     if ((passive_mode_enabled != NX_TRUE) && (passive_mode_enabled != NX_FALSE))
3119     {
3120         return NX_INVALID_PARAMETERS;
3121     }
3122 
3123     status = _nx_ftp_client_passive_mode_set(ftp_client_ptr, passive_mode_enabled);
3124 
3125     return status;
3126 
3127 }
3128 
3129 
3130 /**************************************************************************/
3131 /*                                                                        */
3132 /*  FUNCTION                                               RELEASE        */
3133 /*                                                                        */
3134 /*    _nx_ftp_client_passive_mode_set                     PORTABLE C      */
3135 /*                                                           6.1          */
3136 /*  AUTHOR                                                                */
3137 /*                                                                        */
3138 /*    Yuxin Zhou, Microsoft Corporation                                   */
3139 /*                                                                        */
3140 /*  DESCRIPTION                                                           */
3141 /*                                                                        */
3142 /*    This function sets the request to passive mode. Once this is set    */
3143 /*    the Client will send a PASV command preceding any FTP Client command*/
3144 /*    for accessing a server data port.  If passive mode is not set,      */
3145 /*    the FTP Client will send and receive data via active transfer mode. */
3146 /*                                                                        */
3147 /*  INPUT                                                                 */
3148 /*                                                                        */
3149 /*    ftp_client_ptr                        Pointer to FTP client         */
3150 /*    passive_mode_enabled                  True to enable passive mode   */
3151 /*                                          False to disable passive mode */
3152 /*                                                                        */
3153 /*  OUTPUT                                                                */
3154 /*                                                                        */
3155 /*    NX_SUCCESS                            Successful completion status  */
3156 /*                                                                        */
3157 /*  CALLS                                                                 */
3158 /*     None                                                               */
3159 /*                                                                        */
3160 /*  CALLED BY                                                             */
3161 /*                                                                        */
3162 /*    Application Code                                                    */
3163 /*                                                                        */
3164 /*  RELEASE HISTORY                                                       */
3165 /*                                                                        */
3166 /*    DATE              NAME                      DESCRIPTION             */
3167 /*                                                                        */
3168 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3169 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3170 /*                                            resulting in version 6.1    */
3171 /*                                                                        */
3172 /**************************************************************************/
_nx_ftp_client_passive_mode_set(NX_FTP_CLIENT * ftp_client_ptr,UINT passive_mode_enabled)3173 UINT  _nx_ftp_client_passive_mode_set(NX_FTP_CLIENT *ftp_client_ptr, UINT passive_mode_enabled)
3174 {
3175 
3176     /* Set the transfer status according to the passive mode enabled input.  */
3177     ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled = passive_mode_enabled;
3178 
3179     return(NX_SUCCESS);
3180 }
3181 
3182 
3183 /**************************************************************************/
3184 /*                                                                        */
3185 /*  FUNCTION                                               RELEASE        */
3186 /*                                                                        */
3187 /*    _nxe_ftp_client_transfer_mode_set                   PORTABLE C      */
3188 /*                                                           6.1          */
3189 /*  AUTHOR                                                                */
3190 /*                                                                        */
3191 /*    Yuxin Zhou, Microsoft Corporation                                   */
3192 /*                                                                        */
3193 /*  DESCRIPTION                                                           */
3194 /*                                                                        */
3195 /*    This function checks for errors in the FTP transfer mode set.       */
3196 /*                                                                        */
3197 /*  INPUT                                                                 */
3198 /*                                                                        */
3199 /*    ftp_client_ptr                        Pointer to FTP client         */
3200 /*    transfer_mode                         Transfer mode                 */
3201 /*                                                                        */
3202 /*  OUTPUT                                                                */
3203 /*                                                                        */
3204 /*    NX_PTR_ERROR                          Invalid pointer input         */
3205 /*    status                                Completion status             */
3206 /*                                                                        */
3207 /*  CALLS                                                                 */
3208 /*                                                                        */
3209 /*    _nx_ftp_client_transfer_mode_set      Actual transfer mode set      */
3210 /*                                                                        */
3211 /*  CALLED BY                                                             */
3212 /*                                                                        */
3213 /*    Application Code                                                    */
3214 /*                                                                        */
3215 /*  RELEASE HISTORY                                                       */
3216 /*                                                                        */
3217 /*    DATE              NAME                      DESCRIPTION             */
3218 /*                                                                        */
3219 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3220 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3221 /*                                            resulting in version 6.1    */
3222 /*                                                                        */
3223 /**************************************************************************/
_nxe_ftp_client_transfer_mode_set(NX_FTP_CLIENT * ftp_client_ptr,UINT transfer_mode)3224 UINT  _nxe_ftp_client_transfer_mode_set(NX_FTP_CLIENT *ftp_client_ptr, UINT transfer_mode)
3225 {
3226 
3227 UINT status;
3228 
3229     /* Check for valid pointer.  */
3230     if (ftp_client_ptr == NX_NULL)
3231     {
3232         return(NX_PTR_ERROR);
3233     }
3234 
3235     /* Check for appropriate caller.  */
3236     NX_THREADS_ONLY_CALLER_CHECKING
3237 
3238     /* Call actual transfer mode set function.  */
3239     status = _nx_ftp_client_transfer_mode_set(ftp_client_ptr, transfer_mode);
3240 
3241     return(status);
3242 }
3243 
3244 
3245 /**************************************************************************/
3246 /*                                                                        */
3247 /*  FUNCTION                                               RELEASE        */
3248 /*                                                                        */
3249 /*    _nx_ftp_client_transfer_mode_set                    PORTABLE C      */
3250 /*                                                           6.1          */
3251 /*  AUTHOR                                                                */
3252 /*                                                                        */
3253 /*    Yuxin Zhou, Microsoft Corporation                                   */
3254 /*                                                                        */
3255 /*  DESCRIPTION                                                           */
3256 /*                                                                        */
3257 /*    This function sets the transfer mode.                               */
3258 /*    Note: just support stream mode and block mode yet.                  */
3259 /*                                                                        */
3260 /*  INPUT                                                                 */
3261 /*                                                                        */
3262 /*    ftp_client_ptr                        Pointer to FTP client         */
3263 /*    transfer_mode                         Transfer mode                 */
3264 /*                                                                        */
3265 /*  OUTPUT                                                                */
3266 /*                                                                        */
3267 /*    NX_SUCCESS                            Successful completion status  */
3268 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
3269 /*                                                                        */
3270 /*  CALLS                                                                 */
3271 /*                                                                        */
3272 /*     None                                                               */
3273 /*                                                                        */
3274 /*  CALLED BY                                                             */
3275 /*                                                                        */
3276 /*    Application Code                                                    */
3277 /*                                                                        */
3278 /*  RELEASE HISTORY                                                       */
3279 /*                                                                        */
3280 /*    DATE              NAME                      DESCRIPTION             */
3281 /*                                                                        */
3282 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3283 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3284 /*                                            resulting in version 6.1    */
3285 /*                                                                        */
3286 /**************************************************************************/
_nx_ftp_client_transfer_mode_set(NX_FTP_CLIENT * ftp_client_ptr,UINT transfer_mode)3287 UINT  _nx_ftp_client_transfer_mode_set(NX_FTP_CLIENT *ftp_client_ptr, UINT transfer_mode)
3288 {
3289 
3290     /* Check for transfer mode.  */
3291     if ((transfer_mode != NX_FTP_TRANSFER_MODE_STREAM) &&
3292         (transfer_mode != NX_FTP_TRANSFER_MODE_BLOCK))
3293     {
3294         return(NX_INVALID_PARAMETERS);
3295     }
3296 
3297     /* Set the transfer mode.  */
3298     ftp_client_ptr -> nx_ftp_client_transfer_mode = transfer_mode;
3299 
3300     return(NX_SUCCESS);
3301 }
3302 
3303 
3304 /**************************************************************************/
3305 /*                                                                        */
3306 /*  FUNCTION                                               RELEASE        */
3307 /*                                                                        */
3308 /*    _nxe_ftp_client_file_open                           PORTABLE C      */
3309 /*                                                           6.1          */
3310 /*  AUTHOR                                                                */
3311 /*                                                                        */
3312 /*    Yuxin Zhou, Microsoft Corporation                                   */
3313 /*                                                                        */
3314 /*  DESCRIPTION                                                           */
3315 /*                                                                        */
3316 /*    This function checks for errors in the FTP client file open.        */
3317 /*                                                                        */
3318 /*    Note: The string length of file_name is limited by the packet       */
3319 /*    payload size.                                                       */
3320 /*                                                                        */
3321 /*  INPUT                                                                 */
3322 /*                                                                        */
3323 /*    ftp_client_ptr                        Pointer to FTP client         */
3324 /*    file_name                             Client file name              */
3325 /*    open_type                             Open for read or open for     */
3326 /*                                            write                       */
3327 /*    wait_option                           Specifies how long to wait    */
3328 /*                                                                        */
3329 /*  OUTPUT                                                                */
3330 /*                                                                        */
3331 /*    status                                Completion status             */
3332 /*                                                                        */
3333 /*  CALLS                                                                 */
3334 /*                                                                        */
3335 /*    _nx_ftp_client_file_open              Actual client file open call  */
3336 /*                                                                        */
3337 /*  CALLED BY                                                             */
3338 /*                                                                        */
3339 /*    Application Code                                                    */
3340 /*                                                                        */
3341 /*  RELEASE HISTORY                                                       */
3342 /*                                                                        */
3343 /*    DATE              NAME                      DESCRIPTION             */
3344 /*                                                                        */
3345 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3346 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3347 /*                                            resulting in version 6.1    */
3348 /*                                                                        */
3349 /**************************************************************************/
_nxe_ftp_client_file_open(NX_FTP_CLIENT * ftp_client_ptr,CHAR * file_name,UINT open_type,ULONG wait_option)3350 UINT  _nxe_ftp_client_file_open(NX_FTP_CLIENT *ftp_client_ptr, CHAR *file_name, UINT open_type, ULONG wait_option)
3351 {
3352 
3353 UINT    status;
3354 
3355 
3356     /* Check for invalid input pointers.  */
3357     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (file_name == NX_NULL))
3358         return(NX_PTR_ERROR);
3359 
3360     /* Check for illegal open option type. */
3361     if ((open_type != NX_FTP_OPEN_FOR_READ) && (open_type != NX_FTP_OPEN_FOR_WRITE))
3362         return(NX_OPTION_ERROR);
3363 
3364     /* Check for appropriate caller.  */
3365     NX_THREADS_ONLY_CALLER_CHECKING
3366 
3367     /* Call actual client file open function.  */
3368     status =  _nx_ftp_client_file_open(ftp_client_ptr, file_name, open_type, wait_option);
3369 
3370     /* Return completion status.  */
3371     return(status);
3372 }
3373 
3374 
3375 /**************************************************************************/
3376 /*                                                                        */
3377 /*  FUNCTION                                               RELEASE        */
3378 /*                                                                        */
3379 /*    _nx_ftp_client_file_open                            PORTABLE C      */
3380 /*                                                           6.1          */
3381 /*  AUTHOR                                                                */
3382 /*                                                                        */
3383 /*    Yuxin Zhou, Microsoft Corporation                                   */
3384 /*                                                                        */
3385 /*  DESCRIPTION                                                           */
3386 /*                                                                        */
3387 /*    This function opens a client FTP file.                              */
3388 /*                                                                        */
3389 /*    Note: The string length of file_name is limited by the packet       */
3390 /*    payload size.                                                       */
3391 /*                                                                        */
3392 /*  INPUT                                                                 */
3393 /*                                                                        */
3394 /*    ftp_client_ptr                        Pointer to FTP client         */
3395 /*    file_name                             Client file name              */
3396 /*    open_type                             Open for read or open for     */
3397 /*                                            write                       */
3398 /*    wait_option                           Specifies how long to wait    */
3399 /*                                                                        */
3400 /*  OUTPUT                                                                */
3401 /*                                                                        */
3402 /*    status                                Completion status             */
3403 /*                                                                        */
3404 /*  CALLS                                                                 */
3405 /*                                                                        */
3406 /*    _nx_ftp_client_packet_allocate        Allocate packet               */
3407 /*    _nx_ftp_client_active_transfer_setup  Setup active transfer         */
3408 /*    _nx_ftp_client_passive_transfer_setup Setup passive transfer        */
3409 /*    _nx_ftp_client_block_mode_send        Send block mode command       */
3410 /*    _nx_ftp_client_data_socket_cleanup    Cleanup data socket           */
3411 /*    nx_packet_release                     Release packet                */
3412 /*    nx_tcp_server_socket_accept           Connect data socket to server */
3413 /*    nx_tcp_socket_receive                 Receive response from server  */
3414 /*    nx_tcp_socket_send                    Send request to server        */
3415 /*                                                                        */
3416 /*  CALLED BY                                                             */
3417 /*                                                                        */
3418 /*    Application Code                                                    */
3419 /*                                                                        */
3420 /*  RELEASE HISTORY                                                       */
3421 /*                                                                        */
3422 /*    DATE              NAME                      DESCRIPTION             */
3423 /*                                                                        */
3424 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3425 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3426 /*                                            resulting in version 6.1    */
3427 /*                                                                        */
3428 /**************************************************************************/
_nx_ftp_client_file_open(NX_FTP_CLIENT * ftp_client_ptr,CHAR * file_name,UINT open_type,ULONG wait_option)3429 UINT  _nx_ftp_client_file_open(NX_FTP_CLIENT *ftp_client_ptr, CHAR *file_name, UINT open_type, ULONG wait_option)
3430 {
3431 
3432 UINT        i;
3433 UCHAR       *buffer_ptr;
3434 NX_PACKET   *packet_ptr;
3435 UINT        status;
3436 
3437 
3438     /* Ensure the client is the proper state for an open request.  */
3439     if (ftp_client_ptr -> nx_ftp_client_state == NX_FTP_STATE_NOT_CONNECTED)
3440         return(NX_FTP_NOT_CONNECTED);
3441     else if (ftp_client_ptr -> nx_ftp_client_state == NX_FTP_STATE_OPEN)
3442         return(NX_FTP_NOT_CLOSED);
3443     else if (ftp_client_ptr -> nx_ftp_client_state == NX_FTP_STATE_WRITE_OPEN)
3444         return(NX_FTP_NOT_CLOSED);
3445 
3446     /* Flush the control socket queue for any old messages before starting a new file open request. */
3447     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, 1);
3448 
3449     /* Determine if a packet was received.  */
3450     if (status == NX_SUCCESS)
3451     {
3452 
3453         /* Just discard it. */
3454         nx_packet_release(packet_ptr);
3455     }
3456 
3457     /* Allocate a packet for sending the TYPE command.  */
3458     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
3459 
3460     /* Determine if the packet allocation was successful.  */
3461     if (status != NX_SUCCESS)
3462     {
3463 
3464         /* Return error.  */
3465         return(status);
3466     }
3467 
3468     /* Check if out of boundary.  */
3469     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 8)
3470     {
3471 
3472         /* Release the packet.  */
3473         nx_packet_release(packet_ptr);
3474 
3475         /* Set the error status.  */
3476         return(NX_INVALID_PACKET);
3477     }
3478 
3479     /* We have a packet, setup pointer to the buffer area.  */
3480     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3481 
3482     /* Now build "TYPE I" message to indicate binary file transfer.  */
3483     buffer_ptr[0] =  'T';
3484     buffer_ptr[1] =  'Y';
3485     buffer_ptr[2] =  'P';
3486     buffer_ptr[3] =  'E';
3487     buffer_ptr[4] =  ' ';
3488     buffer_ptr[5] =  'I';
3489 
3490     /* Set the CR/LF.  */
3491     buffer_ptr[6] =  13;
3492     buffer_ptr[7] =  10;
3493 
3494     /* Set the packet length.  */
3495     packet_ptr -> nx_packet_length =  8;
3496 
3497     /* Setup the packet append pointer.  */
3498     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3499 
3500     /* Send the TYPE message.  */
3501     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
3502 
3503     /* Determine if the send was unsuccessful.  */
3504     if (status != NX_SUCCESS)
3505     {
3506 
3507         /* Release the packet.  */
3508         nx_packet_release(packet_ptr);
3509 
3510         /* Return error.  */
3511         return(status);
3512     }
3513 
3514     /* Wait for response from the FTP server.  */
3515     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
3516 
3517     /* Determine if a packet was not received.  */
3518     if (status != NX_SUCCESS)
3519     {
3520 
3521         /* Unable to open file with FTP server. */
3522         return(status);
3523     }
3524 
3525 #ifndef NX_DISABLE_PACKET_CHAIN
3526     if (packet_ptr -> nx_packet_next)
3527     {
3528 
3529         /* Release the packet.  */
3530         nx_packet_release(packet_ptr);
3531 
3532         /* Return.  */
3533         return(NX_INVALID_PACKET);
3534     }
3535 #endif /* NX_DISABLE_PACKET_CHAIN */
3536 
3537     /* We have a packet, setup pointer to the buffer area.  */
3538     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3539 
3540     /* Check for 2xx message, signaling the "TYPE I" was received properly.  */
3541     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
3542     {
3543 
3544         /* Release the packet.  */
3545         nx_packet_release(packet_ptr);
3546 
3547         /* Unable to open file with FTP server. */
3548         return(NX_FTP_EXPECTED_2XX_CODE);
3549     }
3550 
3551     /* Release the packet.  */
3552     nx_packet_release(packet_ptr);
3553 
3554     /* Divert to passive mode operation if passive mode is enabled.  */
3555     if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled)
3556     {
3557 
3558         /* Set up the passive transfer mode:
3559            Send PASV request,
3560            Get server IP and port to connect to,
3561            Open data socket based on server info in PASV response.  */
3562         status = _nx_ftp_client_passive_transfer_setup(ftp_client_ptr,  wait_option);
3563     }
3564     else
3565     {
3566 
3567         /* Open in active transfer mode.  */
3568         status = _nx_ftp_client_active_transfer_setup(ftp_client_ptr, wait_option);
3569     }
3570 
3571     /* Determine if set up successful.  */
3572     if (status)
3573     {
3574         return(status);
3575     }
3576 
3577     /* Check if enable block mode.  */
3578     if (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK)
3579     {
3580 
3581         /* Send MODE B command to FTP server.  */
3582         status = _nx_ftp_client_block_mode_send(ftp_client_ptr, wait_option);
3583 
3584         /* Determine if the send was unsuccessful.  */
3585         if (status != NX_SUCCESS)
3586         {
3587 
3588             /* Cleanup data socket.  */
3589             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3590             return(status);
3591         }
3592     }
3593 
3594     /* Allocate a packet for sending the TYPE command.  */
3595     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
3596 
3597     /* Determine if the packet allocation was successful.  */
3598     if (status != NX_SUCCESS)
3599     {
3600 
3601         /* Cleanup data socket.  */
3602         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3603 
3604         /* Return error.  */
3605         return(status);
3606     }
3607 
3608     /* We have a packet, setup pointer to the buffer area.  */
3609     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3610 
3611     /* Now build the actual open request.  */
3612     if (open_type == NX_FTP_OPEN_FOR_WRITE)
3613     {
3614 
3615         /* File write request, STOR is the command for writing a file.  */
3616         buffer_ptr[0] =  'S';
3617         buffer_ptr[1] =  'T';
3618         buffer_ptr[2] =  'O';
3619         buffer_ptr[3] =  'R';
3620         buffer_ptr[4] =  ' ';
3621     }
3622     else
3623     {
3624 
3625         /* File read request, RETR is the command for reading a file.  */
3626         buffer_ptr[0] =  'R';
3627         buffer_ptr[1] =  'E';
3628         buffer_ptr[2] =  'T';
3629         buffer_ptr[3] =  'R';
3630         buffer_ptr[4] =  ' ';
3631     }
3632 
3633     /* Copy the file name into the buffer.  */
3634     for(i = 0; file_name[i]; i++)
3635     {
3636 
3637         /* Check if out of boundary.  */
3638         if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
3639         {
3640 
3641             /* Cleanup data socket.  */
3642             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3643 
3644             /* Release the packet.  */
3645             nx_packet_release(packet_ptr);
3646 
3647             /* Set the error status.  */
3648             return(NX_FTP_FAILED);
3649         }
3650 
3651         /* Copy character of file name.  */
3652         buffer_ptr[5+i] =  (UCHAR)file_name[i];
3653     }
3654 
3655     /* Insert the CR/LF.  */
3656     buffer_ptr[5+i] =   13;
3657     buffer_ptr[5+i+1] = 10;
3658 
3659     /* Setup the length of the packet.  */
3660     packet_ptr -> nx_packet_length =  i + 7;
3661 
3662     /* Setup the packet append pointer.  */
3663     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3664 
3665     /* Send the STOR/RETR message.  */
3666     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
3667 
3668     /* Determine if the send was unsuccessful.  */
3669     if (status != NX_SUCCESS)
3670     {
3671 
3672         /* Cleanup data socket.  */
3673         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3674 
3675         /* Release the packet.  */
3676         nx_packet_release(packet_ptr);
3677 
3678         /* Return error.  */
3679         return(status);
3680     }
3681 
3682     /* Check if enable passive mode.  */
3683     if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled == NX_FALSE)
3684     {
3685 
3686         /* Active mode. Now wait for the data connection to connect.  */
3687         status =  nx_tcp_server_socket_accept(&(ftp_client_ptr -> nx_ftp_client_data_socket), wait_option);
3688 
3689         /* Determine if the accept was unsuccessful.  */
3690         if (status != NX_SUCCESS)
3691         {
3692 
3693             /* Cleanup data socket.  */
3694             _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3695 
3696             /* Return error.  */
3697             return(status);
3698         }
3699     }
3700 
3701     /* Now wait for response from the FTP server control port.  */
3702     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
3703 
3704     /* Determine if a packet was not received.  */
3705     if (status != NX_SUCCESS)
3706     {
3707 
3708         /* Cleanup data socket.  */
3709         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3710 
3711         /* Unable to open file with FTP server. */
3712         return(status);
3713     }
3714 
3715     /* We have a packet, setup pointer to the buffer area.  */
3716     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3717 
3718     /* Check for 1xx message, signaling the data port was connected properly and ready for transfer.  */
3719     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '1'))
3720     {
3721 
3722         /* Cleanup data socket.  */
3723         _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option);
3724 
3725         /* Release the packet.  */
3726         nx_packet_release(packet_ptr);
3727 
3728         /* Unable to open file with FTP server. */
3729         return(NX_FTP_EXPECTED_1XX_CODE);
3730     }
3731 
3732     /* Release the last packet.  */
3733     nx_packet_release(packet_ptr);
3734 
3735     /* At this point, the client has successfully opened a FTP connection.  */
3736     if (open_type == NX_FTP_OPEN_FOR_WRITE)
3737     {
3738 
3739         /* Set the client state to open for write.  */
3740         ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_WRITE_OPEN;
3741     }
3742     else
3743     {
3744 
3745         /* Set the client state to open for read.  */
3746         ftp_client_ptr -> nx_ftp_client_state =  NX_FTP_STATE_OPEN;
3747     }
3748 
3749     /* Return success to caller.  */
3750     return(NX_SUCCESS);
3751 }
3752 
3753 
3754 /**************************************************************************/
3755 /*                                                                        */
3756 /*  FUNCTION                                               RELEASE        */
3757 /*                                                                        */
3758 /*    _nxe_ftp_client_file_read                           PORTABLE C      */
3759 /*                                                           6.1          */
3760 /*  AUTHOR                                                                */
3761 /*                                                                        */
3762 /*    Yuxin Zhou, Microsoft Corporation                                   */
3763 /*                                                                        */
3764 /*  DESCRIPTION                                                           */
3765 /*                                                                        */
3766 /*    This function checks for errors in the FTP client file read.        */
3767 /*                                                                        */
3768 /*                                                                        */
3769 /*  INPUT                                                                 */
3770 /*                                                                        */
3771 /*    ftp_client_ptr                        Pointer to FTP client         */
3772 /*    packet_ptr                            Destination of for the        */
3773 /*                                            received packet pointer     */
3774 /*    wait_option                           Specifies how long to wait    */
3775 /*                                                                        */
3776 /*  OUTPUT                                                                */
3777 /*                                                                        */
3778 /*    status                                Completion status             */
3779 /*                                                                        */
3780 /*  CALLS                                                                 */
3781 /*                                                                        */
3782 /*    _nx_ftp_client_file_read              Actual client file read call  */
3783 /*                                                                        */
3784 /*  CALLED BY                                                             */
3785 /*                                                                        */
3786 /*    Application Code                                                    */
3787 /*                                                                        */
3788 /*  RELEASE HISTORY                                                       */
3789 /*                                                                        */
3790 /*    DATE              NAME                      DESCRIPTION             */
3791 /*                                                                        */
3792 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3793 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3794 /*                                            resulting in version 6.1    */
3795 /*                                                                        */
3796 /**************************************************************************/
_nxe_ftp_client_file_read(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)3797 UINT  _nxe_ftp_client_file_read(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
3798 {
3799 
3800 UINT    status;
3801 
3802 
3803     /* Check for invalid input pointers.  */
3804     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) || (packet_ptr == NX_NULL))
3805         return(NX_PTR_ERROR);
3806 
3807     /* Check for appropriate caller.  */
3808     NX_THREADS_ONLY_CALLER_CHECKING
3809 
3810     /* Call actual client file read function.  */
3811     status =  _nx_ftp_client_file_read(ftp_client_ptr, packet_ptr, wait_option);
3812 
3813     /* Return completion status.  */
3814     return(status);
3815 }
3816 
3817 
3818 /**************************************************************************/
3819 /*                                                                        */
3820 /*  FUNCTION                                               RELEASE        */
3821 /*                                                                        */
3822 /*    _nx_ftp_client_file_read                            PORTABLE C      */
3823 /*                                                           6.1          */
3824 /*  AUTHOR                                                                */
3825 /*                                                                        */
3826 /*    Yuxin Zhou, Microsoft Corporation                                   */
3827 /*                                                                        */
3828 /*  DESCRIPTION                                                           */
3829 /*                                                                        */
3830 /*    This function reads a packet of the file from the data connection   */
3831 /*    with the FTP server.                                                */
3832 /*                                                                        */
3833 /*                                                                        */
3834 /*  INPUT                                                                 */
3835 /*                                                                        */
3836 /*    ftp_client_ptr                        Pointer to FTP client         */
3837 /*    packet_ptr                            Destination of for the        */
3838 /*                                            received packet pointer     */
3839 /*    wait_option                           Specifies how long to wait    */
3840 /*                                                                        */
3841 /*  OUTPUT                                                                */
3842 /*                                                                        */
3843 /*    status                                Completion status             */
3844 /*                                                                        */
3845 /*  CALLS                                                                 */
3846 /*                                                                        */
3847 /*    nx_tcp_socket_receive                 Receive response from server  */
3848 /*                                                                        */
3849 /*  CALLED BY                                                             */
3850 /*                                                                        */
3851 /*    Application Code                                                    */
3852 /*                                                                        */
3853 /*  RELEASE HISTORY                                                       */
3854 /*                                                                        */
3855 /*    DATE              NAME                      DESCRIPTION             */
3856 /*                                                                        */
3857 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3858 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3859 /*                                            resulting in version 6.1    */
3860 /*                                                                        */
3861 /**************************************************************************/
_nx_ftp_client_file_read(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)3862 UINT  _nx_ftp_client_file_read(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
3863 {
3864 
3865 UINT    status;
3866 
3867 
3868     /* Determine if the file is open for writing.  */
3869     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_OPEN)
3870         return(NX_FTP_NOT_OPEN);
3871 
3872     /* Default the packet pointer to NULL.  */
3873     *packet_ptr =  NX_NULL;
3874 
3875     /* Read the packet from the data connection.  */
3876     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option);
3877 
3878     /* Determine if an error occurred.  */
3879     if (status == NX_NOT_CONNECTED)
3880     {
3881 
3882         /* Map not-connected status to end of file.  */
3883         status =  NX_FTP_END_OF_FILE;
3884     }
3885 
3886     /* Determine if the block mode is enabled.  */
3887     if ((status == NX_SUCCESS) &&
3888         (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK))
3889     {
3890 
3891         /* Retrieve the block header.  */
3892         status = _nx_ftp_client_block_header_retrieve(ftp_client_ptr, (*packet_ptr));
3893     }
3894 
3895     /* Return status to caller.  */
3896     return(status);
3897 }
3898 
3899 
3900 /**************************************************************************/
3901 /*                                                                        */
3902 /*  FUNCTION                                               RELEASE        */
3903 /*                                                                        */
3904 /*    _nxe_ftp_client_file_rename                         PORTABLE C      */
3905 /*                                                           6.1          */
3906 /*  AUTHOR                                                                */
3907 /*                                                                        */
3908 /*    Yuxin Zhou, Microsoft Corporation                                   */
3909 /*                                                                        */
3910 /*  DESCRIPTION                                                           */
3911 /*                                                                        */
3912 /*    This function checks for errors in the FTP client file rename.      */
3913 /*                                                                        */
3914 /*    Note: The string lengths of filename and new_filename are limited   */
3915 /*    by the packet payload size.                                         */
3916 /*                                                                        */
3917 /*  INPUT                                                                 */
3918 /*                                                                        */
3919 /*    ftp_client_ptr                        Pointer to FTP client         */
3920 /*    filename                              Current file name             */
3921 /*    new_filename                          New file name                 */
3922 /*    wait_option                           Specifies how long to wait    */
3923 /*                                                                        */
3924 /*  OUTPUT                                                                */
3925 /*                                                                        */
3926 /*    status                                Completion status             */
3927 /*                                                                        */
3928 /*  CALLS                                                                 */
3929 /*                                                                        */
3930 /*    _nxe_ftp_client_file_rename           Actual client file rename call*/
3931 /*                                                                        */
3932 /*  CALLED BY                                                             */
3933 /*                                                                        */
3934 /*    Application Code                                                    */
3935 /*                                                                        */
3936 /*  RELEASE HISTORY                                                       */
3937 /*                                                                        */
3938 /*    DATE              NAME                      DESCRIPTION             */
3939 /*                                                                        */
3940 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3941 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3942 /*                                            resulting in version 6.1    */
3943 /*                                                                        */
3944 /**************************************************************************/
_nxe_ftp_client_file_rename(NX_FTP_CLIENT * ftp_client_ptr,CHAR * filename,CHAR * new_filename,ULONG wait_option)3945 UINT  _nxe_ftp_client_file_rename(NX_FTP_CLIENT *ftp_client_ptr, CHAR *filename, CHAR *new_filename, ULONG wait_option)
3946 {
3947 
3948 UINT    status;
3949 
3950 
3951     /* Check for invalid input pointers.  */
3952     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) ||
3953         (filename == NX_NULL) || (new_filename == NX_NULL))
3954         return(NX_PTR_ERROR);
3955 
3956     /* Check for appropriate caller.  */
3957     NX_THREADS_ONLY_CALLER_CHECKING
3958 
3959     /* Call actual client file rename function.  */
3960     status =  _nx_ftp_client_file_rename(ftp_client_ptr, filename, new_filename, wait_option);
3961 
3962     /* Return completion status.  */
3963     return(status);
3964 }
3965 
3966 
3967 /**************************************************************************/
3968 /*                                                                        */
3969 /*  FUNCTION                                               RELEASE        */
3970 /*                                                                        */
3971 /*    _nx_ftp_client_file_rename                          PORTABLE C      */
3972 /*                                                           6.1          */
3973 /*  AUTHOR                                                                */
3974 /*                                                                        */
3975 /*    Yuxin Zhou, Microsoft Corporation                                   */
3976 /*                                                                        */
3977 /*  DESCRIPTION                                                           */
3978 /*                                                                        */
3979 /*    This function renames the specified file with the supplied          */
3980 /*    filename.                                                           */
3981 /*                                                                        */
3982 /*    Note: The string lengths of filename and new_filename are limited   */
3983 /*    by the packet payload size.                                         */
3984 /*                                                                        */
3985 /*  INPUT                                                                 */
3986 /*                                                                        */
3987 /*    ftp_client_ptr                        Pointer to FTP client         */
3988 /*    filename                              Current file name             */
3989 /*    new_filename                          New file name                 */
3990 /*    wait_option                           Specifies how long to wait    */
3991 /*                                                                        */
3992 /*  OUTPUT                                                                */
3993 /*                                                                        */
3994 /*    status                                Completion status             */
3995 /*                                                                        */
3996 /*  CALLS                                                                 */
3997 /*                                                                        */
3998 /*    nx_packet_allocate                    Allocate packet               */
3999 /*    nx_packet_release                     Release packet                */
4000 /*    nx_tcp_socket_receive                 Receive packet from server    */
4001 /*    nx_tcp_socket_send                    Send data packet to server    */
4002 /*                                                                        */
4003 /*  CALLED BY                                                             */
4004 /*                                                                        */
4005 /*    Application Code                                                    */
4006 /*                                                                        */
4007 /*  RELEASE HISTORY                                                       */
4008 /*                                                                        */
4009 /*    DATE              NAME                      DESCRIPTION             */
4010 /*                                                                        */
4011 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4012 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4013 /*                                            resulting in version 6.1    */
4014 /*                                                                        */
4015 /**************************************************************************/
_nx_ftp_client_file_rename(NX_FTP_CLIENT * ftp_client_ptr,CHAR * filename,CHAR * new_filename,ULONG wait_option)4016 UINT  _nx_ftp_client_file_rename(NX_FTP_CLIENT *ftp_client_ptr, CHAR *filename, CHAR *new_filename, ULONG wait_option)
4017 {
4018 
4019 UINT        i;
4020 UCHAR       *buffer_ptr;
4021 NX_PACKET   *packet_ptr;
4022 UINT        status;
4023 
4024 
4025     /* Ensure the client is the proper state for a rename file request.  */
4026     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED)
4027         return(NX_FTP_NOT_CONNECTED);
4028 
4029     /* Allocate a packet for sending the file rename command.  */
4030     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
4031 
4032     /* Determine if the packet allocation was successful.  */
4033     if (status)
4034     {
4035 
4036         /* Return error.  */
4037         return(status);
4038     }
4039 
4040     /* Check if out of boundary.  */
4041     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 7)
4042      {
4043 
4044         /* Release the packet.  */
4045         nx_packet_release(packet_ptr);
4046 
4047         /* Set the error status.  */
4048         return(NX_FTP_FAILED);
4049     }
4050 
4051     /* We have a packet, setup pointer to the buffer area.  */
4052     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
4053 
4054     /* Now build "RNFR" message to indicate file rename request.  */
4055     buffer_ptr[0] =  'R';
4056     buffer_ptr[1] =  'N';
4057     buffer_ptr[2] =  'F';
4058     buffer_ptr[3] =  'R';
4059     buffer_ptr[4] =  ' ';
4060 
4061     /* Copy the old file name into the message.  */
4062     for(i = 0; filename[i]; i++)
4063     {
4064 
4065         /* Check if out of boundary.  */
4066         if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
4067         {
4068 
4069             /* Release the packet.  */
4070             nx_packet_release(packet_ptr);
4071 
4072             /* Set the error status.  */
4073             return(NX_FTP_FAILED);
4074         }
4075 
4076         /* Copy character of the file name.  */
4077         buffer_ptr[5+i] =  (UCHAR)filename[i];
4078     }
4079 
4080     /* Set the CR/LF.  */
4081     buffer_ptr[i+5] =  13;
4082     buffer_ptr[i+6] =  10;
4083 
4084     /* Set the packet length.  */
4085     packet_ptr -> nx_packet_length =  i+7;
4086 
4087     /* Setup the packet append pointer.  */
4088     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
4089 
4090     /* Send the RNFR message.  */
4091     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket),  packet_ptr, wait_option);
4092 
4093     /* Determine if the send was unsuccessful.  */
4094     if (status)
4095     {
4096 
4097         /* Release the packet.  */
4098         nx_packet_release(packet_ptr);
4099 
4100         /* Return error.  */
4101         return(status);
4102     }
4103 
4104     /* Wait for response from the FTP server.  */
4105     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
4106 
4107     /* Determine if a packet was not received.  */
4108     if (status)
4109     {
4110 
4111         /* RNFR file error. */
4112         return(status);
4113     }
4114 
4115 #ifndef NX_DISABLE_PACKET_CHAIN
4116     if (packet_ptr -> nx_packet_next)
4117     {
4118 
4119         /* Release the packet.  */
4120         nx_packet_release(packet_ptr);
4121 
4122         /* Return.  */
4123         return(NX_INVALID_PACKET);
4124     }
4125 #endif /* NX_DISABLE_PACKET_CHAIN */
4126 
4127     /* We have a packet, setup pointer to the buffer area.  */
4128     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
4129 
4130     /* Check for 3xx message, signaling the "RNFR" was received properly.  */
4131     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '3'))
4132     {
4133 
4134         /* Release the packet.  */
4135         nx_packet_release(packet_ptr);
4136 
4137         /* Unable to rename file with FTP server. */
4138         return(NX_FTP_EXPECTED_3XX_CODE);
4139     }
4140 
4141     /* Check if out of boundary.  */
4142     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 7)
4143      {
4144 
4145         /* Release the packet.  */
4146         nx_packet_release(packet_ptr);
4147 
4148         /* Set the error status.  */
4149         return(NX_FTP_FAILED);
4150     }
4151 
4152     /* Now build "RNTO" message to specify new file name.  */
4153     buffer_ptr[0] =  'R';
4154     buffer_ptr[1] =  'N';
4155     buffer_ptr[2] =  'T';
4156     buffer_ptr[3] =  'O';
4157     buffer_ptr[4] =  ' ';
4158 
4159     /* Copy the old file name into the message.  */
4160     for(i = 0; new_filename[i]; i++)
4161     {
4162 
4163         /* Check if out of boundary.  */
4164         if ((i + 7) >= (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr))
4165         {
4166 
4167             /* Release the packet.  */
4168             nx_packet_release(packet_ptr);
4169 
4170             /* Set the error status.  */
4171             return(NX_FTP_FAILED);
4172         }
4173 
4174         /* Copy character of the new file name.  */
4175         buffer_ptr[5+i] =  (UCHAR)new_filename[i];
4176     }
4177 
4178     /* Set the CR/LF.  */
4179     buffer_ptr[i+5] =  13;
4180     buffer_ptr[i+6] =  10;
4181 
4182     /* Set the packet length.  */
4183     packet_ptr -> nx_packet_length =  i+7;
4184 
4185     /* Setup the packet append pointer.  */
4186     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
4187 
4188     /* Send the RNTO message.  */
4189     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
4190 
4191     /* Determine if the send was unsuccessful.  */
4192     if (status)
4193     {
4194 
4195         /* Release the packet.  */
4196         nx_packet_release(packet_ptr);
4197 
4198         /* Return error.  */
4199         return(status);
4200     }
4201 
4202     /* Wait for response from the FTP server.  */
4203     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
4204 
4205     /* Determine if a packet was not received.  */
4206     if (status)
4207     {
4208 
4209         /* RNTO file error. */
4210         return(status);
4211     }
4212 
4213     /* We have a packet, setup pointer to the buffer area.  */
4214     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
4215 
4216     /* Check for 2xx message, signaling the "RNTO" was processed properly.  */
4217     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
4218     {
4219 
4220         /* Release the packet.  */
4221         nx_packet_release(packet_ptr);
4222 
4223         /* Unable to rename with FTP server. */
4224         return(NX_FTP_EXPECTED_2XX_CODE);
4225     }
4226 
4227     /* Release packet.  */
4228     nx_packet_release(packet_ptr);
4229 
4230     /* Return success to caller.  */
4231     return(NX_SUCCESS);
4232 }
4233 
4234 
4235 /**************************************************************************/
4236 /*                                                                        */
4237 /*  FUNCTION                                               RELEASE        */
4238 /*                                                                        */
4239 /*    _nxe_ftp_client_file_size_set                       PORTABLE C      */
4240 /*                                                           6.1          */
4241 /*  AUTHOR                                                                */
4242 /*                                                                        */
4243 /*    Yuxin Zhou, Microsoft Corporation                                   */
4244 /*                                                                        */
4245 /*  DESCRIPTION                                                           */
4246 /*                                                                        */
4247 /*    This function checks for errors in the FTP client file size set.    */
4248 /*                                                                        */
4249 /*                                                                        */
4250 /*  INPUT                                                                 */
4251 /*                                                                        */
4252 /*    ftp_client_ptr                        Pointer to FTP client         */
4253 /*    file_size                             The total size of file        */
4254 /*                                                                        */
4255 /*  OUTPUT                                                                */
4256 /*                                                                        */
4257 /*    status                                Completion status             */
4258 /*                                                                        */
4259 /*  CALLS                                                                 */
4260 /*                                                                        */
4261 /*    _nx_ftp_client_file_size_set          Actual file size set call     */
4262 /*                                                                        */
4263 /*  CALLED BY                                                             */
4264 /*                                                                        */
4265 /*    Application Code                                                    */
4266 /*                                                                        */
4267 /*  RELEASE HISTORY                                                       */
4268 /*                                                                        */
4269 /*    DATE              NAME                      DESCRIPTION             */
4270 /*                                                                        */
4271 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4272 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4273 /*                                            resulting in version 6.1    */
4274 /*                                                                        */
4275 /**************************************************************************/
_nxe_ftp_client_file_size_set(NX_FTP_CLIENT * ftp_client_ptr,ULONG file_size)4276 UINT  _nxe_ftp_client_file_size_set(NX_FTP_CLIENT *ftp_client_ptr, ULONG file_size)
4277 {
4278 
4279 UINT    status;
4280 
4281 
4282     /* Check for invalid input pointers.  */
4283     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID))
4284         return(NX_PTR_ERROR);
4285 
4286     /* Check for appropriate caller.  */
4287     NX_THREADS_ONLY_CALLER_CHECKING
4288 
4289     /* Call actual client file size set function.  */
4290     status =  _nx_ftp_client_file_size_set(ftp_client_ptr, file_size);
4291 
4292     /* Return completion status.  */
4293     return(status);
4294 }
4295 
4296 
4297 /**************************************************************************/
4298 /*                                                                        */
4299 /*  FUNCTION                                               RELEASE        */
4300 /*                                                                        */
4301 /*    _nx_ftp_client_file_size_set                        PORTABLE C      */
4302 /*                                                           6.1          */
4303 /*  AUTHOR                                                                */
4304 /*                                                                        */
4305 /*    Yuxin Zhou, Microsoft Corporation                                   */
4306 /*                                                                        */
4307 /*  DESCRIPTION                                                           */
4308 /*                                                                        */
4309 /*    This function sets the file size for block mode before send packets */
4310 /*    to the file on the data connection with the FTP server.             */
4311 /*                                                                        */
4312 /*    Note:a. This API is only used for block mode,                       */
4313 /*         b. Must call this API before call nx_ftp_client_file_write.    */
4314 /*                                                                        */
4315 /*  INPUT                                                                 */
4316 /*                                                                        */
4317 /*    ftp_client_ptr                        Pointer to FTP client         */
4318 /*    file_size                             The total size of file        */
4319 /*                                                                        */
4320 /*  OUTPUT                                                                */
4321 /*                                                                        */
4322 /*    status                                Completion status             */
4323 /*                                                                        */
4324 /*  CALLS                                                                 */
4325 /*                                                                        */
4326 /*    nx_packet_release                     Release packet                */
4327 /*    nx_tcp_socket_send                    Send data packet to server    */
4328 /*                                                                        */
4329 /*  CALLED BY                                                             */
4330 /*                                                                        */
4331 /*    Application Code                                                    */
4332 /*                                                                        */
4333 /*  RELEASE HISTORY                                                       */
4334 /*                                                                        */
4335 /*    DATE              NAME                      DESCRIPTION             */
4336 /*                                                                        */
4337 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4338 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4339 /*                                            resulting in version 6.1    */
4340 /*                                                                        */
4341 /**************************************************************************/
_nx_ftp_client_file_size_set(NX_FTP_CLIENT * ftp_client_ptr,ULONG file_size)4342 UINT  _nx_ftp_client_file_size_set(NX_FTP_CLIENT *ftp_client_ptr, ULONG file_size)
4343 {
4344 
4345 UINT        status;
4346 
4347 
4348     /* Check for invalid file size.  */
4349     if (file_size == 0)
4350         return(NX_FTP_CLIENT_INVALID_SIZE);
4351 
4352     /* Check if already set the file size.  */
4353     if (ftp_client_ptr -> nx_ftp_client_block_total_size != 0)
4354         return(NX_FTP_CLIENT_FILE_SIZE_ALREADY_SET);
4355 
4356     /* Determine if the block mode is enabled.  */
4357     if (ftp_client_ptr -> nx_ftp_client_transfer_mode != NX_FTP_TRANSFER_MODE_BLOCK)
4358         return(NX_FTP_CLIENT_NOT_BLOCK_MODE);
4359 
4360     /* Determine if the file is open for writing.  */
4361     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_WRITE_OPEN)
4362         return(NX_FTP_NOT_OPEN);
4363 
4364     /* Send start block header for file size.  */
4365     status = _nx_ftp_client_block_header_send(ftp_client_ptr, file_size);
4366 
4367     /* Determine if the send was unsuccessful.  */
4368     if (status)
4369     {
4370 
4371         /* Return error.  */
4372         return(status);
4373     }
4374 
4375     /* Store the file size for writing.  */
4376     ftp_client_ptr -> nx_ftp_client_block_total_size = file_size;
4377     ftp_client_ptr -> nx_ftp_client_block_remaining_size = file_size;
4378 
4379     /* Return success to caller.  */
4380     return(NX_SUCCESS);
4381 }
4382 
4383 
4384 /**************************************************************************/
4385 /*                                                                        */
4386 /*  FUNCTION                                               RELEASE        */
4387 /*                                                                        */
4388 /*    _nxe_ftp_client_file_write                          PORTABLE C      */
4389 /*                                                           6.1          */
4390 /*  AUTHOR                                                                */
4391 /*                                                                        */
4392 /*    Yuxin Zhou, Microsoft Corporation                                   */
4393 /*                                                                        */
4394 /*  DESCRIPTION                                                           */
4395 /*                                                                        */
4396 /*    This function checks for errors in the FTP client file write.       */
4397 /*                                                                        */
4398 /*                                                                        */
4399 /*  INPUT                                                                 */
4400 /*                                                                        */
4401 /*    ftp_client_ptr                        Pointer to FTP client         */
4402 /*    packet_ptr                            Pointer to packet to write    */
4403 /*    wait_option                           Specifies how long to wait    */
4404 /*                                                                        */
4405 /*  OUTPUT                                                                */
4406 /*                                                                        */
4407 /*    status                                Completion status             */
4408 /*                                                                        */
4409 /*  CALLS                                                                 */
4410 /*                                                                        */
4411 /*    _nx_ftp_client_file_write             Actual client file write call */
4412 /*                                                                        */
4413 /*  CALLED BY                                                             */
4414 /*                                                                        */
4415 /*    Application Code                                                    */
4416 /*                                                                        */
4417 /*  RELEASE HISTORY                                                       */
4418 /*                                                                        */
4419 /*    DATE              NAME                      DESCRIPTION             */
4420 /*                                                                        */
4421 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4422 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4423 /*                                            resulting in version 6.1    */
4424 /*                                                                        */
4425 /**************************************************************************/
_nxe_ftp_client_file_write(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET * packet_ptr,ULONG wait_option)4426 UINT  _nxe_ftp_client_file_write(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
4427 {
4428 
4429 UINT    status;
4430 
4431 
4432     /* Check for invalid input pointers.  */
4433     if ((ftp_client_ptr == NX_NULL) || (ftp_client_ptr -> nx_ftp_client_id != NXD_FTP_CLIENT_ID) ||
4434         (packet_ptr == NX_NULL))
4435         return(NX_PTR_ERROR);
4436 
4437     /* Check for appropriate caller.  */
4438     NX_THREADS_ONLY_CALLER_CHECKING
4439 
4440     /* Call actual client file write function.  */
4441     status =  _nx_ftp_client_file_write(ftp_client_ptr, packet_ptr, wait_option);
4442 
4443     /* Return completion status.  */
4444     return(status);
4445 }
4446 
4447 
4448 /**************************************************************************/
4449 /*                                                                        */
4450 /*  FUNCTION                                               RELEASE        */
4451 /*                                                                        */
4452 /*    _nx_ftp_client_file_write                           PORTABLE C      */
4453 /*                                                           6.3.0        */
4454 /*  AUTHOR                                                                */
4455 /*                                                                        */
4456 /*    Yuxin Zhou, Microsoft Corporation                                   */
4457 /*                                                                        */
4458 /*  DESCRIPTION                                                           */
4459 /*                                                                        */
4460 /*    This function writes a packet to the file on the data connection    */
4461 /*    with the FTP server.                                                */
4462 /*                                                                        */
4463 /*                                                                        */
4464 /*  INPUT                                                                 */
4465 /*                                                                        */
4466 /*    ftp_client_ptr                        Pointer to FTP client         */
4467 /*    packet_ptr                            Pointer to packet to write    */
4468 /*    wait_option                           Specifies how long to wait    */
4469 /*                                                                        */
4470 /*  OUTPUT                                                                */
4471 /*                                                                        */
4472 /*    status                                Completion status             */
4473 /*                                                                        */
4474 /*  CALLS                                                                 */
4475 /*                                                                        */
4476 /*    nx_packet_release                     Release packet                */
4477 /*    nx_tcp_socket_send                    Send data packet to server    */
4478 /*                                                                        */
4479 /*  CALLED BY                                                             */
4480 /*                                                                        */
4481 /*    Application Code                                                    */
4482 /*                                                                        */
4483 /*  RELEASE HISTORY                                                       */
4484 /*                                                                        */
4485 /*    DATE              NAME                      DESCRIPTION             */
4486 /*                                                                        */
4487 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4488 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4489 /*                                            resulting in version 6.1    */
4490 /*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
4491 /*                                            fixed packet double release,*/
4492 /*                                            resulting in version 6.3.0  */
4493 /*                                                                        */
4494 /**************************************************************************/
_nx_ftp_client_file_write(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET * packet_ptr,ULONG wait_option)4495 UINT  _nx_ftp_client_file_write(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
4496 {
4497 
4498 UINT    status;
4499 ULONG   file_size = 0;
4500 
4501 
4502     /* Determine if the file is open for writing.  */
4503     if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_WRITE_OPEN)
4504         return(NX_FTP_NOT_OPEN);
4505 
4506     /* Determine if the block mode is enabled.  */
4507     if (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK)
4508     {
4509 
4510         /* Record the file size.  */
4511         file_size = packet_ptr -> nx_packet_length;
4512 
4513         /* Check the file size.  */
4514         if (ftp_client_ptr -> nx_ftp_client_block_remaining_size < packet_ptr -> nx_packet_length)
4515             return(NX_FTP_CLIENT_INVALID_SIZE);
4516     }
4517 
4518     /* Write packet payload to the file.  */
4519     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option);
4520 
4521     /* Determine if the send was unsuccessful.  */
4522     if (status)
4523     {
4524 
4525         /* Return error.  */
4526         return(status);
4527     }
4528 
4529     /* Determine if the block mode is enabled.  */
4530     if (ftp_client_ptr -> nx_ftp_client_transfer_mode == NX_FTP_TRANSFER_MODE_BLOCK)
4531     {
4532 
4533         /* Update the file size.  */
4534         ftp_client_ptr -> nx_ftp_client_block_remaining_size -= file_size;
4535 
4536         /* Check if the file is already sent.  */
4537         if (ftp_client_ptr -> nx_ftp_client_block_remaining_size == 0)
4538         {
4539 
4540             /* Send end block header for file size.  */
4541             status = _nx_ftp_client_block_header_send(ftp_client_ptr, 0);
4542         }
4543     }
4544 
4545     /* Return success to caller.  */
4546     return(status);
4547 }
4548 
4549 
4550 #ifdef FEATURE_NX_IPV6
4551 /**************************************************************************/
4552 /*                                                                        */
4553 /*  FUNCTION                                               RELEASE        */
4554 /*                                                                        */
4555 /*    _nx_ftp_utility_convert_IPv6_to_ascii               PORTABLE C      */
4556 /*                                                           6.1          */
4557 /*  AUTHOR                                                                */
4558 /*                                                                        */
4559 /*    Yuxin Zhou, Microsoft Corporation                                   */
4560 /*                                                                        */
4561 /*  DESCRIPTION                                                           */
4562 /*                                                                        */
4563 /*    This function converts an IP address to ascii e.g. for insertion    */
4564 /*     into FTP EPRT or PORT command.                                     */
4565 /*                                                                        */
4566 /*  INPUT                                                                 */
4567 /*                                                                        */
4568 /*    ftp_client_ptr                   Pointer to FTP client              */
4569 /*    buffer                           Pointer to ascii port number string*/
4570 /*    buffer_length                    Size of buffer                     */
4571 /*    size                             IPv6 address string size           */
4572 /*                                                                        */
4573 /*  OUTPUT                                                                */
4574 /*                                                                        */
4575 /*    NX_SUCCESS                       Successful conversion              */
4576 /*                                                                        */
4577 /*  CALLS                                                                 */
4578 /*                                                                        */
4579 /*    _nx_ftp_utility_convert_number_ascii                                */
4580 /*                                     Converts a single number to ascii  */
4581 /*                                                                        */
4582 /*  CALLED BY                                                             */
4583 /*                                                                        */
4584 /*    _nx_ftp_client_file_open         FTP Client file open service       */
4585 /*                                                                        */
4586 /*  RELEASE HISTORY                                                       */
4587 /*                                                                        */
4588 /*    DATE              NAME                      DESCRIPTION             */
4589 /*                                                                        */
4590 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4591 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
4592 /*                                            verified memcpy use cases,  */
4593 /*                                            resulting in version 6.1    */
4594 /*                                                                        */
4595 /**************************************************************************/
4596 
_nx_ftp_utility_convert_IPv6_to_ascii(NX_TCP_SOCKET * socket_ptr,CHAR * buffer,UINT buffer_length,UINT * size)4597 UINT _nx_ftp_utility_convert_IPv6_to_ascii(NX_TCP_SOCKET *socket_ptr, CHAR *buffer, UINT buffer_length, UINT *size)
4598 {
4599 
4600 
4601 CHAR *temp;
4602 CHAR number_buf[10]; /* 0x20010000 -> "2001:0000:" */
4603 
4604 
4605     /* Set a pointer to the start of the buffer. */
4606     temp = buffer;
4607 
4608     /* Clear the buffer. */
4609     memset(temp, 0, buffer_length);
4610 
4611     /* Clear the scratch buffer. */
4612     memset(number_buf, 0, 10);
4613 
4614     _nx_ftp_utility_convert_number_ascii(socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address[0], number_buf);
4615 
4616     /* Append to string buffer. */
4617     memcpy(temp, number_buf, 10); /* Use case of memcpy is verified. */
4618 
4619     /* Move the pointer past this number. */
4620     temp += 10;
4621 
4622     /* Clear the scratch buffer. */
4623     memset(number_buf, 0, 10);
4624 
4625      _nx_ftp_utility_convert_number_ascii(socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address[1], number_buf);
4626 
4627     /* Append to string buffer. */
4628     memcpy(temp, number_buf, 10); /* Use case of memcpy is verified. */
4629 
4630     /* Move the pointer past this number. */
4631     temp += 10;
4632 
4633     /* Clear the scratch buffer. */
4634     memset(number_buf, 0, 10);
4635 
4636     _nx_ftp_utility_convert_number_ascii(socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address[2], number_buf);
4637 
4638     /* Append to string buffer. */
4639     memcpy(temp, number_buf, 10); /* Use case of memcpy is verified. */
4640 
4641     /* Move the pointer past this number. */
4642     temp += 10;
4643 
4644     /* Clear the scratch buffer. */
4645     memset(number_buf, 0, 10);
4646 
4647      _nx_ftp_utility_convert_number_ascii(socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address[3], number_buf);
4648 
4649     /* Append to string buffer. */
4650     memcpy(temp, number_buf, 10); /* Use case of memcpy is verified. */
4651 
4652     /* Move the pointer past this number. */
4653     temp += 10;
4654 
4655     /* Remove the trailing ':'. */
4656     *(temp - 1) = 0x0;
4657     *size = 39;
4658 
4659     return NX_SUCCESS;
4660 }
4661 
4662 
4663 /**************************************************************************/
4664 /*                                                                        */
4665 /*  FUNCTION                                               RELEASE        */
4666 /*                                                                        */
4667 /*    _nx_ftp_utility_convert_number_ascii                PORTABLE C      */
4668 /*                                                           6.1          */
4669 /*  AUTHOR                                                                */
4670 /*                                                                        */
4671 /*    Yuxin Zhou, Microsoft Corporation                                   */
4672 /*                                                                        */
4673 /*  DESCRIPTION                                                           */
4674 /*                                                                        */
4675 /*    This function converts a number to ascii text for inserting IP      */
4676 /*    address and port numbers into FTP EPRT and PORT commands.  It is up */
4677 /*    to the caller to provide a buffer large enough to hold the ascii    */
4678 /*    conversion of the input number.                                     */
4679 /*                                                                        */
4680 /*  INPUT                                                                 */
4681 /*                                                                        */
4682 /*    number                           Number to convert to ASCII         */
4683 /*    numstring                        Pointer to ascii string            */
4684 /*                                                                        */
4685 /*  OUTPUT                                                                */
4686 /*    NX_SUCCESS                       Successful completion              */
4687 /*                                                                        */
4688 /*  CALLS                                                                 */
4689 /*     None                                                               */
4690 /*                                                                        */
4691 /*  CALLED BY                                                             */
4692 /*     _nx_ftp_utility_convert_IPv6_to_ascii                              */
4693 /*                                    Convert IPv6 address to ASCII       */
4694 /*                                                                        */
4695 /*  RELEASE HISTORY                                                       */
4696 /*                                                                        */
4697 /*    DATE              NAME                      DESCRIPTION             */
4698 /*                                                                        */
4699 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4700 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4701 /*                                            resulting in version 6.1    */
4702 /*                                                                        */
4703 /**************************************************************************/
4704 
_nx_ftp_utility_convert_number_ascii(ULONG number,CHAR * numstring)4705 UINT  _nx_ftp_utility_convert_number_ascii(ULONG number, CHAR *numstring)
4706 {
4707 
4708 UINT    j;
4709 UCHAR   c;
4710 
4711     /* Go through each bit of the ULONG to convert. */
4712     for (j = 0; j <=7 ; j++)
4713     {
4714 
4715          /* Save the bit off the most significant end. */
4716          c = (UCHAR)((number & 0xF0000000) >> 28);
4717 
4718          /* Make it the most significant byte. */
4719          number = number << 4;
4720 
4721          /* Convert the digit to an ascii character. */
4722          if (c < 10)
4723          {
4724              *numstring = (CHAR)('0' + c);
4725          }
4726          else /* Handle HEX digits... */
4727          {
4728              *numstring = (CHAR)('A' + (c - 10));
4729          }
4730 
4731          /* Move past the digit. */
4732          numstring++;
4733 
4734          /* Determine if we need to add a colon. */
4735          if (j == 3 || j == 7)
4736          {
4737              /* Yes, append the colon and move the pointer past it. */
4738              *numstring = ':';
4739              numstring++;
4740          }
4741     }
4742 
4743     return NX_SUCCESS;
4744 }
4745 
4746 
4747 /**************************************************************************/
4748 /*                                                                        */
4749 /*  FUNCTION                                               RELEASE        */
4750 /*                                                                        */
4751 /*    _nx_ftp_utility_convert_portnumber_ascii            PORTABLE C      */
4752 /*                                                           6.1          */
4753 /*  AUTHOR                                                                */
4754 /*                                                                        */
4755 /*    Yuxin Zhou, Microsoft Corporation                                   */
4756 /*                                                                        */
4757 /*  DESCRIPTION                                                           */
4758 /*                                                                        */
4759 /*    This function converts a number to ascii text e.g. used by          */
4760 /*    _nx_nat_utility_convert_portnumber_ULONG_to_ascii for inserting     */
4761 /*    changed port numbers back into FTP PORT command .                   */
4762 /*                                                                        */
4763 /*  INPUT                                                                 */
4764 /*                                                                        */
4765 /*    number                         Port number to convert to ASCII      */
4766 /*    numstring                      Pointer to ascii portnumber string   */
4767 /*    numstring_length               Portnumber string length             */
4768 /*                                                                        */
4769 /*  OUTPUT                                                                */
4770 /*                                                                        */
4771 /*    NX_FTP_ERROR                   Unable to convert e.g. overflow error*/
4772 /*    NX_SUCCESS                     Successful conversion                */
4773 /*                                                                        */
4774 /*  CALLS                                                                 */
4775 /*                                                                        */
4776 /*    None                                                                */
4777 /*                                                                        */
4778 /*  CALLED BY                                                             */
4779 /*                                                                        */
4780 /*    _nx_ftp_client_file_open        Processes the FTP file open service */
4781 /*                                                                        */
4782 /*                                                                        */
4783 /*  RELEASE HISTORY                                                       */
4784 /*                                                                        */
4785 /*    DATE              NAME                      DESCRIPTION             */
4786 /*                                                                        */
4787 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4788 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4789 /*                                            resulting in version 6.1    */
4790 /*                                                                        */
4791 /**************************************************************************/
4792 
_nx_ftp_utility_convert_portnumber_ascii(UINT number,CHAR * numstring,UINT * numstring_length)4793 UINT  _nx_ftp_utility_convert_portnumber_ascii(UINT number, CHAR *numstring, UINT *numstring_length)
4794 {
4795 
4796 UINT    j;
4797 UINT    digit;
4798 
4799 
4800     /* Initialize counters.  */
4801     (*numstring_length) =  0;
4802 
4803     /* Loop to convert the number to ASCII.  */
4804     while ((*numstring_length) < 10)
4805     {
4806 
4807         /* Shift the current digits over one.  */
4808         for (j = (*numstring_length); j != 0; j--)
4809         {
4810 
4811             /* Move each digit over one place.  */
4812             numstring[j] =  numstring[j-1];
4813         }
4814 
4815         /* Compute the next decimal digit.  */
4816         digit =  number % 10;
4817 
4818         /* Update the input number.  */
4819         number =  number / 10;
4820 
4821         /* Store the new digit in ASCII form.  */
4822         numstring[0] =  (CHAR) (digit + 0x30);
4823 
4824         /* Increment the size.  */
4825         (*numstring_length)++;
4826 
4827         /* Determine if the number is now zero.  */
4828         if (number == 0)
4829             break;
4830     }
4831 
4832     /* Make the string NULL terminated.  */
4833     numstring[(*numstring_length)] =  (CHAR) NX_NULL;
4834 
4835     /* Determine if there is an overflow error.  */
4836     if (number)
4837     {
4838 
4839         /* Error, return bad values to user.  */
4840         (*numstring_length) =  0;
4841         numstring[0] = '0';
4842         return NX_FTP_INVALID_NUMBER;
4843     }
4844 
4845     /* Return size to caller.  */
4846     return NX_SUCCESS;
4847 }
4848 #endif
4849 
4850 
4851 /**************************************************************************/
4852 /*                                                                        */
4853 /*  FUNCTION                                               RELEASE        */
4854 /*                                                                        */
4855 /*    _nx_ftp_client_packet_allocate                      PORTABLE C      */
4856 /*                                                           6.1          */
4857 /*  AUTHOR                                                                */
4858 /*                                                                        */
4859 /*    Yuxin Zhou, Microsoft Corporation                                   */
4860 /*                                                                        */
4861 /*  DESCRIPTION                                                           */
4862 /*                                                                        */
4863 /*    This function determines which IP TCP packet to allocate based on   */
4864 /*    the FTP connection address IP type and then allocates the packet.   */
4865 /*                                                                        */
4866 /*                                                                        */
4867 /*  INPUT                                                                 */
4868 /*                                                                        */
4869 /*    ftp_client_ptr                        Pointer to FTP client         */
4870 /*    packet_ptr                            Allocated packet to return    */
4871 /*    wait_option                           Packet allocate wait option   */
4872 /*                                                                        */
4873 /*  OUTPUT                                                                */
4874 /*                                                                        */
4875 /*    status                                Completion status             */
4876 /*    NX_NOT_ENABLED                        IPv6 not enabled              */
4877 /*                                                                        */
4878 /*  CALLS                                                                 */
4879 /*                                                                        */
4880 /*    nx_packet_allocate                    Allocate packet               */
4881 /*                                                                        */
4882 /*  CALLED BY                                                             */
4883 /*                                                                        */
4884 /*    Application Code                                                    */
4885 /*                                                                        */
4886 /*  RELEASE HISTORY                                                       */
4887 /*                                                                        */
4888 /*    DATE              NAME                      DESCRIPTION             */
4889 /*                                                                        */
4890 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4891 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4892 /*                                            resulting in version 6.1    */
4893 /*                                                                        */
4894 /**************************************************************************/
_nx_ftp_client_packet_allocate(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)4895 UINT _nx_ftp_client_packet_allocate(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
4896 {
4897 
4898 UINT packet_type;
4899 UINT status;
4900 
4901 
4902     /* Default to IPv4 TCP packet to allocate. */
4903     packet_type = NX_IPv4_TCP_PACKET;
4904 
4905     /* Determine IP version by FTP connection type. */
4906     if (ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
4907     {
4908 
4909 #ifndef FEATURE_NX_IPV6
4910 
4911         return NX_NOT_ENABLED;
4912 #else
4913 
4914         /* Allocate a TCP IPv6 packet. */
4915         packet_type = NX_IPv6_TCP_PACKET;
4916 #endif
4917     }
4918 
4919 
4920     /* Allocate the actual packet. */
4921     status =  nx_packet_allocate(ftp_client_ptr -> nx_ftp_client_packet_pool_ptr, packet_ptr, packet_type, wait_option);
4922 
4923     /* Return completion status. */
4924     return status;
4925 }
4926 
4927 
4928 /**************************************************************************/
4929 /*                                                                        */
4930 /*  FUNCTION                                               RELEASE        */
4931 /*                                                                        */
4932 /*    _nx_ftp_client_active_transfer_setup                PORTABLE C      */
4933 /*                                                           6.1          */
4934 /*  AUTHOR                                                                */
4935 /*                                                                        */
4936 /*    Yuxin Zhou, Microsoft Corporation                                   */
4937 /*                                                                        */
4938 /*  DESCRIPTION                                                           */
4939 /*                                                                        */
4940 /*    This function sets up the Client data socket for active transfer    */
4941 /*    where the Client data socket is the TCP client.                     */
4942 /*                                                                        */
4943 /*    Find free port and listen on it, sends the PORT/EPRT command to     */
4944 /*    server, then wait for a connection from server.                     */
4945 /*                                                                        */
4946 /*  INPUT                                                                 */
4947 /*                                                                        */
4948 /*    ftp_client_ptr                        Pointer to FTP client         */
4949 /*    wait_option                           Specifies how long to wait    */
4950 /*                                                                        */
4951 /*  OUTPUT                                                                */
4952 /*                                                                        */
4953 /*    status                                Completion status             */
4954 /*                                                                        */
4955 /*  CALLS                                                                 */
4956 /*                                                                        */
4957 /*    _nx_ftp_client_packet_allocate        Allocate packet               */
4958 /*    _nx_ftp_utility_convert_IPv6_to_ascii Convert IPv6 address to ASCII */
4959 /*    _nx_ftp_utility_convert_portnumber_ascii Convert port to ASCII      */
4960 /*    nx_packet_release                     Release packet                */
4961 /*    nx_tcp_free_port_find                 Find a free port              */
4962 /*    nx_tcp_server_socket_listen           Listen for TCP data socket    */
4963 /*                                            connection from server      */
4964 /*    nx_tcp_server_socket_unlisten         Unlisten on server socket     */
4965 /*    nx_tcp_socket_receive                 Receive response from server  */
4966 /*    nx_tcp_socket_send                    Send request to server        */
4967 /*                                                                        */
4968 /*  CALLED BY                                                             */
4969 /*                                                                        */
4970 /*    _nx_ftp_client_file_open              Open a file for read or write */
4971 /*    _nx_ftp_client_directory_listing_get  Get directory list            */
4972 /*                                                                        */
4973 /*  RELEASE HISTORY                                                       */
4974 /*                                                                        */
4975 /*    DATE              NAME                      DESCRIPTION             */
4976 /*                                                                        */
4977 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4978 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
4979 /*                                            verified memcpy use cases,  */
4980 /*                                            fixed packet leak,          */
4981 /*                                            resulting in version 6.1    */
4982 /*                                                                        */
4983 /**************************************************************************/
_nx_ftp_client_active_transfer_setup(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)4984 UINT  _nx_ftp_client_active_transfer_setup(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
4985 {
4986 
4987 UINT        status;
4988 UINT        data_port;
4989 #ifndef NX_DISABLE_IPV4
4990 ULONG       ip_address;
4991 #endif /* NX_DISABLE_IPV4 */
4992 UCHAR       *buffer_ptr;
4993 NX_PACKET   *packet_ptr;
4994 #ifdef FEATURE_NX_IPV6
4995 UINT        ipduo_size;
4996 #endif
4997 
4998 
4999     /* Pickup the next free port for the data socket.  */
5000     status = nx_tcp_free_port_find(ftp_client_ptr -> nx_ftp_client_ip_ptr,
5001                                    ftp_client_ptr -> nx_ftp_client_data_port + 1, &data_port);
5002 
5003     /* Determine if the port find was successful.  */
5004     if (status != NX_SUCCESS)
5005     {
5006         return(status);
5007     }
5008 
5009     /* Save the data port to the client record. */
5010     ftp_client_ptr -> nx_ftp_client_data_port = data_port;
5011 
5012     /* Start listening on the data port.  */
5013     status = nx_tcp_server_socket_listen(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port, &(ftp_client_ptr -> nx_ftp_client_data_socket), 5, NX_NULL);
5014 
5015     /* Determine if the listen is successful.  */
5016     if (status != NX_SUCCESS)
5017     {
5018 
5019         /* Return error.  */
5020         return(status);
5021     }
5022 
5023     /* Allocate a packet for sending the PORT/EPRT command.  */
5024     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
5025 
5026     /* Determine if the packet allocation was successful.  */
5027     if (status != NX_SUCCESS)
5028     {
5029 
5030         /* Stop listening on the data port.  */
5031         nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5032 
5033         /* Return error.  */
5034         return(status);
5035     }
5036 
5037     /* We have a packet, setup pointer to the buffer area.  */
5038     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5039 
5040     /* Now build the IP and port number FTP message.  */
5041     if (ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
5042     {
5043 #ifndef FEATURE_NX_IPV6
5044         return NX_NOT_ENABLED;
5045 #else
5046     CHAR        ipduo_buffer[NX_FTP_IPV6_ADDRESS_BUFSIZE];
5047     UINT        index;
5048 
5049         /* EPRT command: EPRT |2|1080::8:800:200C:417A|5282|
5050            RFC2428, Section2, Page3. */
5051 
5052         /* Check if out of boundary.
5053            Max EPRT command sring: 8 ("EPRT |2|") + 39 (IPv6 address string) + 1 ('|') + 5 (Max port string) + 1 ('|') + 2 ("\r\n") = 56.  */
5054         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 56)
5055         {
5056 
5057             /* Stop listening on the data port.  */
5058             nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5059 
5060             /* Release the packet.  */
5061             nx_packet_release(packet_ptr);
5062 
5063             /* Set the error status.  */
5064             return(NX_INVALID_PACKET);
5065         }
5066 
5067         buffer_ptr[0] =  'E';
5068         buffer_ptr[1] =  'P';
5069         buffer_ptr[2] =  'R';
5070         buffer_ptr[3] =  'T';
5071         buffer_ptr[4] =  ' ';
5072         buffer_ptr[5] =  '|';
5073         buffer_ptr[6] =  '2';
5074         buffer_ptr[7] =  '|';
5075 
5076         /* Convert the PORT command ipv6 address and port number format to ascii text. */
5077 
5078         /* Clear our scratch buffer. */
5079         memset(&ipduo_buffer[0], 0, NX_FTP_IPV6_ADDRESS_BUFSIZE);
5080 
5081         /* Convert the IPv6 address to text. */
5082         status = _nx_ftp_utility_convert_IPv6_to_ascii(&(ftp_client_ptr -> nx_ftp_client_control_socket),
5083                                                        &ipduo_buffer[0], NX_FTP_IPV6_ADDRESS_BUFSIZE, &ipduo_size);
5084 
5085         /* Append to the packet buffer . */
5086         memcpy(buffer_ptr + 8, ipduo_buffer, ipduo_size); /* Use case of memcpy is verified. */
5087 
5088         /* Update the index past the IPv6 address. */
5089         index = 8 + ipduo_size;
5090 
5091         /* Add the required space character. */
5092         buffer_ptr[index++] = '|';
5093 
5094         /* Clear the scratch buffer again. */
5095         memset(&ipduo_buffer[0], 0, NX_FTP_IPV6_ADDRESS_BUFSIZE);
5096 
5097         /* Convert the preferred port to ascii. */
5098         status = _nx_ftp_utility_convert_portnumber_ascii(data_port, &ipduo_buffer[0], &ipduo_size);
5099 
5100         /* Append to the packet buffer. */
5101         memcpy(buffer_ptr + index, ipduo_buffer, ipduo_size); /* Use case of memcpy is verified. */
5102 
5103         /* Update the index past the port. */
5104         index += ipduo_size;
5105 
5106         /* Add the required space character. */
5107         buffer_ptr[index++] = '|';
5108 
5109         /* Set the CR/LF.  */
5110         buffer_ptr[index++] = 13;
5111         buffer_ptr[index++] = 10;
5112 
5113         /* Set the packet length.  */
5114         packet_ptr -> nx_packet_length = index;
5115 #endif /*  FEATURE_NX_IPV6 */
5116     }
5117     else
5118     {
5119         /* IPv4 FTP connection */
5120 #ifdef NX_DISABLE_IPV4
5121         return NX_NOT_ENABLED;
5122 #else
5123 
5124         /* Check if out of boundary.  */
5125         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 30)
5126         {
5127 
5128             /* Stop listening on the data port.  */
5129             nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5130 
5131             /* Release the packet.  */
5132             nx_packet_release(packet_ptr);
5133 
5134             /* Set the error status.  */
5135             return(NX_INVALID_PACKET);
5136         }
5137 
5138         /* Pickup the IPv4 address of this IP instance.  */
5139         ip_address =  ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address ;
5140 
5141         /* Now build the IP and port number FTP message.  */
5142         buffer_ptr[0] =  'P';
5143         buffer_ptr[1] =  'O';
5144         buffer_ptr[2] =  'R';
5145         buffer_ptr[3] =  'T';
5146         buffer_ptr[4] =  ' ';
5147 
5148         buffer_ptr[5] =  (UCHAR)('0' + (ip_address >> 24)/100);
5149         buffer_ptr[6] =  (UCHAR)('0' + ((ip_address >> 24)/10)%10);
5150         buffer_ptr[7] =  (UCHAR)('0' + (ip_address >> 24)%10);
5151         buffer_ptr[8] =  ',';
5152 
5153         buffer_ptr[9]  = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)/100);
5154         buffer_ptr[10] = (UCHAR)('0' + (((ip_address >> 16) & 0xFF)/10)%10);
5155         buffer_ptr[11] = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)%10);
5156         buffer_ptr[12] = ',';
5157 
5158         buffer_ptr[13] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)/100);
5159         buffer_ptr[14] = (UCHAR)('0' + (((ip_address >> 8) & 0xFF)/10)%10);
5160         buffer_ptr[15] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)%10);
5161         buffer_ptr[16] = ',';
5162 
5163         buffer_ptr[17] = (UCHAR)('0' + (ip_address & 0xFF)/100);
5164         buffer_ptr[18] = (UCHAR)('0' + ((ip_address & 0xFF)/10)%10);
5165         buffer_ptr[19] = (UCHAR)('0' + (ip_address & 0xFF)%10);
5166         buffer_ptr[20] = ',';
5167 
5168         buffer_ptr[21] = (UCHAR)('0' + (data_port >> 8)/100);
5169         buffer_ptr[22] = (UCHAR)('0' + ((data_port >> 8)/10)%10);
5170         buffer_ptr[23] = (UCHAR)('0' + ((data_port >> 8)%10));
5171         buffer_ptr[24] = ',';
5172 
5173         buffer_ptr[25] = (UCHAR)('0' + (data_port & 255)/100);
5174         buffer_ptr[26] = (UCHAR)('0' + ((data_port & 255)/10)%10);
5175         buffer_ptr[27] = (UCHAR)('0' + ((data_port & 255)%10));
5176 
5177         /* Set the CR/LF.  */
5178         buffer_ptr[28] = 13;
5179         buffer_ptr[29] = 10;
5180 
5181         /* Set the packet length.  */
5182         packet_ptr -> nx_packet_length =  30;
5183 #endif /* NX_DISABLE_IPV4 */
5184     }
5185 
5186     /* Setup the packet append pointer.  */
5187     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
5188 
5189     /* Send the PORT/EPRT message.  */
5190     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
5191 
5192     /* Determine if the send was unsuccessful.  */
5193     if (status != NX_SUCCESS)
5194     {
5195 
5196         /* Stop listening on the data port.  */
5197         nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5198 
5199         /* Release the packet.  */
5200         nx_packet_release(packet_ptr);
5201 
5202         /* Return error.  */
5203         return(status);
5204     }
5205 
5206     /* Wait for response from the FTP server.  */
5207     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
5208 
5209     /* Determine if a packet was not received.  */
5210     if (status != NX_SUCCESS)
5211     {
5212 
5213         /* Stop listening on the data port.  */
5214         nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5215 
5216         /* Unable to open file with FTP server. */
5217         return(status);
5218     }
5219 
5220     /* We have a packet, setup pointer to the buffer area.  */
5221     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5222 
5223     /* Check for 2xx message, signaling the IP/port was received properly.  */
5224     if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2'))
5225     {
5226 
5227         /* Stop listening on the data port.  */
5228         nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port);
5229 
5230         /* Release the packet.  */
5231         nx_packet_release(packet_ptr);
5232 
5233         /* Unable to open file with FTP server. */
5234         return(NX_FTP_EXPECTED_2XX_CODE);
5235     }
5236 
5237     /* Release the packet.  */
5238     nx_packet_release(packet_ptr);
5239 
5240     return(NX_SUCCESS);
5241 }
5242 
5243 
5244 /**************************************************************************/
5245 /*                                                                        */
5246 /*  FUNCTION                                               RELEASE        */
5247 /*                                                                        */
5248 /*    _nx_ftp_client_passive_transfer_setup               PORTABLE C      */
5249 /*                                                           6.1          */
5250 /*  AUTHOR                                                                */
5251 /*                                                                        */
5252 /*    Yuxin Zhou, Microsoft Corporation                                   */
5253 /*                                                                        */
5254 /*  DESCRIPTION                                                           */
5255 /*                                                                        */
5256 /*    This function sets up the Client data socket for passive transfer   */
5257 /*    where the Client data socket is the TCP client.                     */
5258 /*                                                                        */
5259 /*    It sends the PASV command and if the server sends an OK status, it  */
5260 /*    extracts the server connection info from the server response and    */
5261 /*    opens a connection on the data socket.                              */
5262 /*                                                                        */
5263 /*  INPUT                                                                 */
5264 /*                                                                        */
5265 /*    ftp_client_ptr                        Pointer to FTP client         */
5266 /*    wait_option                           Specifies how long to wait    */
5267 /*                                                                        */
5268 /*  OUTPUT                                                                */
5269 /*                                                                        */
5270 /*    status                                Completion status             */
5271 /*                                                                        */
5272 /*  CALLS                                                                 */
5273 /*                                                                        */
5274 /*    _nx_ftp_client_packet_allocate        Allocate packet               */
5275 /*    nx_packet_release                     Release packet                */
5276 /*    nx_tcp_client_socket_bind             Bind the data socket to a port*/
5277 /*    nxd_tcp_client_socket_connect         Connect to server data socket */
5278 /*    nx_tcp_socket_receive                 Receive response from server  */
5279 /*    nx_tcp_socket_send                    Send request to server        */
5280 /*                                                                        */
5281 /*  CALLED BY                                                             */
5282 /*                                                                        */
5283 /*    _nx_ftp_client_file_open              Open a file for read or write */
5284 /*    _nx_ftp_client_directory_listing_get  Get directory list            */
5285 /*                                                                        */
5286 /*  RELEASE HISTORY                                                       */
5287 /*                                                                        */
5288 /*    DATE              NAME                      DESCRIPTION             */
5289 /*                                                                        */
5290 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5291 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5292 /*                                            resulting in version 6.1    */
5293 /*                                                                        */
5294 /**************************************************************************/
_nx_ftp_client_passive_transfer_setup(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)5295 UINT  _nx_ftp_client_passive_transfer_setup(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
5296 {
5297 
5298 UCHAR       *buffer_ptr;
5299 NX_PACKET   *packet_ptr;
5300 UINT        status;
5301 UINT        i;
5302 UINT        data_port;
5303 #ifndef NX_DISABLE_IPV4
5304 UINT        commas =      0;
5305 ULONG       ip_address =  0;
5306 ULONG       temp =        0;
5307 #endif /* NX_DISABLE_IPV4  */
5308 
5309 
5310     /* Send the PASV command to switch to passive mode. */
5311 
5312     /* Allocate a packet for sending the TYPE command.  */
5313     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, wait_option);
5314 
5315     /* Determine if the packet allocation was successful.  */
5316     if (status != NX_SUCCESS)
5317     {
5318 
5319         /* Return error.  */
5320         return(status);
5321     }
5322 
5323     /* Check if out of boundary.  */
5324     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 6)
5325      {
5326 
5327         /* Release the packet.  */
5328         nx_packet_release(packet_ptr);
5329 
5330         /* Set the error status.  */
5331         return(NX_FTP_FAILED);
5332     }
5333 
5334     /* We have a packet, setup pointer to the buffer area.  */
5335     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5336 
5337     if (ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
5338     {
5339 #ifndef FEATURE_NX_IPV6
5340         return(NX_NOT_ENABLED);
5341 #else
5342 
5343         /* Now build "EPSV" message. RFC2428.  */
5344         buffer_ptr[0] =  'E';
5345         buffer_ptr[1] =  'P';
5346         buffer_ptr[2] =  'S';
5347         buffer_ptr[3] =  'V';
5348 #endif /*  FEATURE_NX_IPV6 */
5349     }
5350     else
5351     {
5352 #ifdef NX_DISABLE_IPV4
5353         return(NX_NOT_ENABLED);
5354 #else
5355 
5356         /* Now build "PASV" message .  */
5357         buffer_ptr[0] =  'P';
5358         buffer_ptr[1] =  'A';
5359         buffer_ptr[2] =  'S';
5360         buffer_ptr[3] =  'V';
5361 #endif /* NX_DISABLE_IPV4 */
5362     }
5363 
5364     /* Set the CR/LF.  */
5365     buffer_ptr[4] =  13;
5366     buffer_ptr[5] =  10;
5367 
5368     /* Set the packet length.  */
5369     packet_ptr -> nx_packet_length =  6;
5370 
5371     /* Setup the packet append pointer.  */
5372     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
5373 
5374     /* Send the PASV or EPSV message.  */
5375     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
5376 
5377     /* Determine if the send was unsuccessful.  */
5378     if (status != NX_SUCCESS)
5379     {
5380 
5381         /* Release the packet.  */
5382         nx_packet_release(packet_ptr);
5383 
5384         /* Return error.  */
5385         return(status);
5386     }
5387 
5388     /* Wait for response from the FTP server.  */
5389     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
5390 
5391     /* Determine if a packet was not received.  */
5392     if (status != NX_SUCCESS)
5393     {
5394 
5395         /* Unable to open file with FTP server. */
5396         return(status);
5397     }
5398 
5399     /* Setup pointer to the buffer area.  */
5400     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5401 
5402     if (ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
5403     {
5404 #ifndef FEATURE_NX_IPV6
5405         return(NX_NOT_ENABLED);
5406 #else
5407 
5408         /* EPSV command, RFC2428.  */
5409 
5410         /* Check for 2xx message, signaling the "EPSV" was received properly.  */
5411         if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2') || (buffer_ptr[1] != '2') || (buffer_ptr[2] != '9'))
5412         {
5413 
5414             /* Release the packet.  */
5415             nx_packet_release(packet_ptr);
5416 
5417             /* Unable to open file with FTP server. */
5418             return(NX_FTP_EXPECTED_2XX_CODE);
5419         }
5420 
5421         /* The text returned in response to the EPSV command MUST be:
5422              <text indicating server is entering extended passive mode> \
5423              (<d><d><d><tcp-port><d>)  */
5424 
5425         /* The netowrk address used to establish the data connnection will be the same
5426            network address used for the control connection.
5427            An example response string follows:
5428              Entering Extended Passive Mode (|||6446|)  */
5429 
5430         /* Check the length. command + <sp> + passive key word "(|||"*/
5431         if (packet_ptr -> nx_packet_length < 8)
5432         {
5433 
5434             /* Release the packet.  */
5435             nx_packet_release(packet_ptr);
5436             return(NX_FTP_INVALID_COMMAND);
5437         }
5438 
5439         /* Set the index.  */
5440         i = 7;
5441 
5442         /* Skip the text to locate the key word "(|||". */
5443         while (i < packet_ptr -> nx_packet_length)
5444         {
5445 
5446             /* Check if match the key word.  */
5447             if ((buffer_ptr[i - 3] == '(') &&
5448                 (buffer_ptr[i - 2] == '|') &&
5449                 (buffer_ptr[i - 1] == '|') &&
5450                 (buffer_ptr[i] == '|'))
5451             {
5452                 break;
5453             }
5454 
5455             /* Move to next character.  */
5456             i++;
5457         }
5458 
5459         /* Check for properly formated address command from server. */
5460         if (i >= packet_ptr -> nx_packet_length)
5461         {
5462 
5463             /* Release the packet.  */
5464             nx_packet_release(packet_ptr);
5465             return(NX_FTP_INVALID_COMMAND);
5466         }
5467 
5468         /* Update the index to pickup the port number.  */
5469         data_port =  0;
5470         i++;
5471         while ((i < packet_ptr -> nx_packet_length) && (buffer_ptr[i] != '|'))
5472         {
5473 
5474             /* Is a numeric character present?  */
5475             if ((buffer_ptr[i] < '0') || (buffer_ptr[i] > '9'))
5476             {
5477 
5478                 /* Invalid port number.  */
5479                 break;
5480             }
5481 
5482             /* Yes, numeric character is present. Update the IP port.  */
5483             data_port = (data_port * 10) + (UINT) (buffer_ptr[i] - '0');
5484 
5485             /* Move to next character.  */
5486             i++;
5487         }
5488 
5489         /* At this point we are done with the packet. */
5490         nx_packet_release(packet_ptr);
5491 
5492         /* Determine if an error occurred.  */
5493         if ((buffer_ptr[i] != '|') || (data_port == 0))
5494         {
5495 
5496             /* Set the error status.  */
5497             return(NX_FTP_INVALID_COMMAND);
5498         }
5499 
5500         /* Save the passive IP address and  data port.  */
5501         COPY_NXD_ADDRESS(&(ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip), &(ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_ip));
5502         ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_port = data_port;
5503 #endif /*  FEATURE_NX_IPV6 */
5504     }
5505     else
5506     {
5507 #ifdef NX_DISABLE_IPV4
5508         return(NX_NOT_ENABLED);
5509 #else
5510 
5511         /* Check for 2xx message, signaling the "PASV" was received properly.  */
5512         if ((packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2') || (buffer_ptr[1] != '2') || (buffer_ptr[2] != '7'))
5513         {
5514 
5515             /* Release the packet.  */
5516             nx_packet_release(packet_ptr);
5517 
5518             /* Unable to open file with FTP server. */
5519             return(NX_FTP_EXPECTED_2XX_CODE);
5520         }
5521 
5522         /* Now parse the address and port for the Client to connect to on the data socket.
5523            IP address and port are comma delimited and port number is the last two numbers,
5524            PASV port = (p1 * 256) + p2.  */
5525 
5526         /* Skip non numeric text and whitespace.  */
5527         i = 3;
5528         while (((buffer_ptr[i] > '9') || (buffer_ptr[i] < '0')) && (i < packet_ptr -> nx_packet_length))
5529         {
5530             i++;
5531         }
5532 
5533         /* Check for properly formated command from server.  */
5534         if (i >= packet_ptr -> nx_packet_length)
5535         {
5536 
5537             /* Release the packet.  */
5538             nx_packet_release(packet_ptr);
5539             return NX_FTP_INVALID_COMMAND;
5540         }
5541 
5542         /* First, pickup the IP address.  */
5543         commas =      0;
5544         ip_address =  0;
5545         temp =        0;
5546         status =      NX_SUCCESS;
5547 
5548         while (i < packet_ptr -> nx_packet_length)
5549         {
5550 
5551             /* Is a numeric character present?  */
5552             if ((buffer_ptr[i] >= '0') && (buffer_ptr[i] <= '9'))
5553             {
5554 
5555                 /* Yes, numeric character is present.  Update the IP address.  */
5556                 temp =  (temp*10) + (ULONG) (buffer_ptr[i] - '0');
5557             }
5558 
5559             /* Determine if a CR/LF is present.  */
5560             if ((buffer_ptr[i] == 0x0D) || (buffer_ptr[i] == 0x0A) || (buffer_ptr[i] == 0))
5561             {
5562                 status =  NX_FTP_INVALID_COMMAND;
5563                 break;
5564             }
5565 
5566             /* Determine if a comma is present.  */
5567             if (buffer_ptr[i] == ',')
5568             {
5569 
5570                 /* Increment the comma count. */
5571                 commas++;
5572 
5573                 /* Setup next byte of IP address.  */
5574                 ip_address =  (ip_address << 8) & 0xFFFFFFFF;
5575                 ip_address =  ip_address | (temp & 0xFF);
5576                 temp =  0;
5577 
5578                 /* Have we finished with the IP address?  */
5579                 if (commas == 4)
5580                 {
5581 
5582                     /* Finished with IP address.  */
5583                     i++;
5584                     break;
5585                 }
5586             }
5587 
5588             /* Move to next character.  */
5589             i++;
5590         }
5591 
5592         /* Now pickup the port number.  */
5593         data_port =  0;
5594         temp =  0;
5595         while (i < packet_ptr -> nx_packet_length)
5596         {
5597 
5598             /* Is a numeric character present?  */
5599             if ((buffer_ptr[i] >= '0') && (buffer_ptr[i] <= '9'))
5600             {
5601 
5602                 /* Yes, numeric character is present.  Update the IP port.  */
5603                 temp =  (temp*10) + (UINT) (buffer_ptr[i] - '0');
5604             }
5605 
5606             /* Determine if a CR/LF is present.  */
5607             if ((buffer_ptr[i] == 0x0D) || (buffer_ptr[i] == 0x0A) || (buffer_ptr[i] == 0))
5608             {
5609                 /* Good condition on the port number!  */
5610                 break;
5611             }
5612 
5613             /* Determine if a comma is present.  */
5614             if (buffer_ptr[i] == ',')
5615             {
5616 
5617                 /* Increment the comma count. */
5618                 commas++;
5619 
5620                 /* Move the data port number up.  */
5621                 data_port =  (data_port << 8) & 0xFFFFFFFF;
5622                 data_port =  data_port | (temp & 0xFF);
5623                 temp =  0;
5624 
5625                 /* Have we finished with the port?  */
5626                 if (commas >= 6)
5627                 {
5628 
5629                     /* Error, get out of the loop.  */
5630                     status =  NX_FTP_INVALID_ADDRESS;
5631                     break;
5632                 }
5633             }
5634 
5635             /* Move to next character.  */
5636             i++;
5637         }
5638 
5639         /* Move port number up.  */
5640         data_port =  (data_port << 8) & 0xFFFFFFFF;
5641         data_port =  data_port | (temp & 0xFF);
5642 
5643         /* At this point we are done with the packet. */
5644         nx_packet_release(packet_ptr);
5645 
5646         /* Determine if an error occurred.  */
5647         if ((status != NX_SUCCESS) || (buffer_ptr[i] != 13) || (commas != 5) || (ip_address == 0) || (data_port == 0))
5648         {
5649 
5650             /* Set the error status.  */
5651             return NX_FTP_INVALID_COMMAND;
5652         }
5653 
5654         /* Save the passive IP address and  data port.  */
5655         ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4;
5656         ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = ip_address;
5657         ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_port =  data_port;
5658 
5659 #endif /* NX_DISABLE_IPV4 */
5660     }
5661 
5662     /* Bind the client data socket to any port.  */
5663     status =  nx_tcp_client_socket_bind((&ftp_client_ptr -> nx_ftp_client_data_socket), NX_ANY_PORT, wait_option);
5664 
5665     /* Check for an error.  */
5666     if (status != NX_SUCCESS)
5667     {
5668 
5669         /* Unable to bind socket to port. */
5670         return(status);
5671     }
5672 
5673     /* Now connect to the IP address and port the server asked us to.  */
5674     status =  nxd_tcp_client_socket_connect(&(ftp_client_ptr -> nx_ftp_client_data_socket),
5675                                             &(ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_connect_ip),
5676                                             data_port, wait_option);
5677 
5678     /* Check for an error.  */
5679     if (status != NX_SUCCESS)
5680     {
5681 
5682         /* Unbind the socket.  */
5683         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_data_socket));
5684     }
5685 
5686     return(status);
5687 }
5688 
5689 
5690 /**************************************************************************/
5691 /*                                                                        */
5692 /*  FUNCTION                                               RELEASE        */
5693 /*                                                                        */
5694 /*    _nx_ftp_client_data_socket_cleanup                  PORTABLE C      */
5695 /*                                                           6.1          */
5696 /*  AUTHOR                                                                */
5697 /*                                                                        */
5698 /*    Yuxin Zhou, Microsoft Corporation                                   */
5699 /*                                                                        */
5700 /*  DESCRIPTION                                                           */
5701 /*                                                                        */
5702 /*    This function cleans up the data socket.                            */
5703 /*                                                                        */
5704 /*  INPUT                                                                 */
5705 /*                                                                        */
5706 /*    ftp_client_ptr                        Pointer to FTP client         */
5707 /*                                                                        */
5708 /*  OUTPUT                                                                */
5709 /*                                                                        */
5710 /*    None                                                                */
5711 /*                                                                        */
5712 /*  CALLS                                                                 */
5713 /*                                                                        */
5714 /*    nx_tcp_socket_disconnect              Disconnect a socket           */
5715 /*    nx_tcp_client_socket_unbind           Release the data socket port  */
5716 /*    nx_tcp_server_socket_unaccept         Unaccept server connection    */
5717 /*    nx_tcp_server_socket_unlisten         Unlisten on server socket     */
5718 /*                                                                        */
5719 /*  CALLED BY                                                             */
5720 /*                                                                        */
5721 /*    _nx_ftp_client_file_open              Open a file for read or write */
5722 /*    _nx_ftp_client_file_close             Actual client file close call */
5723 /*    _nx_ftp_client_directory_listing_get  Get directory list            */
5724 /*    _nx_ftp_client_directory_listing_continue                           */
5725 /*                                          Continue to get directory list*/
5726 /*                                                                        */
5727 /*  RELEASE HISTORY                                                       */
5728 /*                                                                        */
5729 /*    DATE              NAME                      DESCRIPTION             */
5730 /*                                                                        */
5731 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5732 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5733 /*                                            resulting in version 6.1    */
5734 /*                                                                        */
5735 /**************************************************************************/
_nx_ftp_client_data_socket_cleanup(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)5736 VOID  _nx_ftp_client_data_socket_cleanup(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
5737 {
5738 
5739 
5740     /* Disconnect the data socket.  */
5741     nx_tcp_socket_disconnect(&(ftp_client_ptr -> nx_ftp_client_data_socket), wait_option);
5742 
5743     /* Check if enable passive mode.  */
5744     if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled == NX_FALSE)
5745     {
5746 
5747         /* Unaccept the data socket.  */
5748         nx_tcp_server_socket_unaccept(&(ftp_client_ptr -> nx_ftp_client_data_socket));
5749 
5750         /* Stop listening on the data port.  */
5751         nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr,
5752                                       ftp_client_ptr -> nx_ftp_client_data_socket.nx_tcp_socket_port);
5753     }
5754     else
5755     {
5756 
5757         /* Release the socket port. */
5758         nx_tcp_client_socket_unbind(&(ftp_client_ptr -> nx_ftp_client_data_socket));
5759     }
5760 
5761     /* Clear the block size.  */
5762     ftp_client_ptr -> nx_ftp_client_block_total_size = 0;
5763     ftp_client_ptr -> nx_ftp_client_block_remaining_size = 0;
5764 }
5765 
5766 
5767 /**************************************************************************/
5768 /*                                                                        */
5769 /*  FUNCTION                                               RELEASE        */
5770 /*                                                                        */
5771 /*    _nx_ftp_client_block_mode_send                      PORTABLE C      */
5772 /*                                                           6.1          */
5773 /*  AUTHOR                                                                */
5774 /*                                                                        */
5775 /*    Yuxin Zhou, Microsoft Corporation                                   */
5776 /*                                                                        */
5777 /*  DESCRIPTION                                                           */
5778 /*                                                                        */
5779 /*    This function sends MODE B command to FTP server for block mode.    */
5780 /*                                                                        */
5781 /*  INPUT                                                                 */
5782 /*                                                                        */
5783 /*    ftp_client_ptr                        Pointer to FTP client         */
5784 /*                                                                        */
5785 /*  OUTPUT                                                                */
5786 /*                                                                        */
5787 /*    status                                Completion status             */
5788 /*                                                                        */
5789 /*  CALLS                                                                 */
5790 /*                                                                        */
5791 /*    nx_packet_release                     Release packet                */
5792 /*    nx_tcp_socket_send                    Send data packet to server    */
5793 /*                                                                        */
5794 /*  CALLED BY                                                             */
5795 /*                                                                        */
5796 /*    _nx_ftp_client_file_open              Open a file for read or write */
5797 /*    _nx_ftp_client_directory_listing_get  Get directory list            */
5798 /*                                                                        */
5799 /*  RELEASE HISTORY                                                       */
5800 /*                                                                        */
5801 /*    DATE              NAME                      DESCRIPTION             */
5802 /*                                                                        */
5803 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5804 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5805 /*                                            resulting in version 6.1    */
5806 /*                                                                        */
5807 /**************************************************************************/
_nx_ftp_client_block_mode_send(NX_FTP_CLIENT * ftp_client_ptr,ULONG wait_option)5808 UINT  _nx_ftp_client_block_mode_send(NX_FTP_CLIENT *ftp_client_ptr, ULONG wait_option)
5809 {
5810 
5811 UINT        status;
5812 NX_PACKET   *packet_ptr;
5813 UCHAR       *buffer_ptr;
5814 
5815 
5816     /* Send MODE B command.  */
5817 
5818     /* Allocate the packet.  */
5819     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, NX_NO_WAIT);
5820 
5821     /* Determine if the send was unsuccessful.  */
5822     if (status)
5823     {
5824 
5825         /* Return error.  */
5826         return(status);
5827     }
5828 
5829     /* We have a packet, setup pointer to the buffer area.  */
5830     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5831 
5832     /* Now build the actual MODE B request.  */
5833     buffer_ptr[0] = 'M';
5834     buffer_ptr[1] = 'O';
5835     buffer_ptr[2] = 'D';
5836     buffer_ptr[3] = 'E';
5837     buffer_ptr[4] = ' ';
5838     buffer_ptr[5] = 'B';
5839 
5840     /* Insert the CR/LF.  */
5841     buffer_ptr[6] = 13;
5842     buffer_ptr[7] = 10;
5843 
5844     /* Setup the length of the packet.  */
5845     packet_ptr -> nx_packet_length = 8;
5846 
5847     /* Setup the packet append pointer.  */
5848     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
5849 
5850     /* Send the MODE B message.  */
5851     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), packet_ptr, wait_option);
5852 
5853     /* Determine if the send was unsuccessful.  */
5854     if (status != NX_SUCCESS)
5855     {
5856 
5857         /* Release the packet.  */
5858         nx_packet_release(packet_ptr);
5859 
5860         /* Return error.  */
5861         return(status);
5862     }
5863 
5864     /* Now wait for response from the FTP server control port.  */
5865     status =  nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &packet_ptr, wait_option);
5866 
5867     /* Determine if a packet was not received.  */
5868     if (status != NX_SUCCESS)
5869     {
5870 
5871         /* Unable to open file with FTP server. */
5872         return(status);
5873     }
5874 
5875     /* We have a packet, setup pointer to the buffer area.  */
5876     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5877 
5878     /* Check for 2xx message, signaling the data port was connected properly and ready for transfer.  */
5879     if (buffer_ptr[0] != '2')
5880     {
5881 
5882         /* Release the packet.  */
5883         nx_packet_release(packet_ptr);
5884 
5885         /* Unable to open file with FTP server. */
5886         return(NX_FTP_EXPECTED_2XX_CODE);
5887     }
5888 
5889     /* Release the packet.  */
5890     nx_packet_release(packet_ptr);
5891 
5892     /* Return success to caller. */
5893     return(NX_SUCCESS);
5894 }
5895 
5896 
5897 /**************************************************************************/
5898 /*                                                                        */
5899 /*  FUNCTION                                               RELEASE        */
5900 /*                                                                        */
5901 /*    _nx_ftp_client_block_header_send                    PORTABLE C      */
5902 /*                                                           6.1          */
5903 /*  AUTHOR                                                                */
5904 /*                                                                        */
5905 /*    Yuxin Zhou, Microsoft Corporation                                   */
5906 /*                                                                        */
5907 /*  DESCRIPTION                                                           */
5908 /*                                                                        */
5909 /*    This function sends the block header for block mode.                */
5910 /*                                                                        */
5911 /*  INPUT                                                                 */
5912 /*                                                                        */
5913 /*    ftp_client_ptr                        Pointer to FTP client         */
5914 /*    block_size                            The size of block data        */
5915 /*                                                                        */
5916 /*  OUTPUT                                                                */
5917 /*                                                                        */
5918 /*    status                                Completion status             */
5919 /*                                                                        */
5920 /*  CALLS                                                                 */
5921 /*                                                                        */
5922 /*    nx_packet_release                     Release packet                */
5923 /*    nx_tcp_socket_send                    Send data packet to server    */
5924 /*                                                                        */
5925 /*  CALLED BY                                                             */
5926 /*                                                                        */
5927 /*    _nx_ftp_client_file_size_set          Set the file size for writing */
5928 /*    _nx_ftp_client_file_write             Send data packet to server    */
5929 /*                                                                        */
5930 /*  RELEASE HISTORY                                                       */
5931 /*                                                                        */
5932 /*    DATE              NAME                      DESCRIPTION             */
5933 /*                                                                        */
5934 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5935 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5936 /*                                            resulting in version 6.1    */
5937 /*                                                                        */
5938 /**************************************************************************/
_nx_ftp_client_block_header_send(NX_FTP_CLIENT * ftp_client_ptr,ULONG block_size)5939 UINT  _nx_ftp_client_block_header_send(NX_FTP_CLIENT *ftp_client_ptr, ULONG block_size)
5940 {
5941 
5942 UINT        status;
5943 NX_PACKET   *packet_ptr;
5944 UCHAR       *buffer_ptr;
5945 
5946 
5947     /* Use block mode to transfer data.  RFC959, Section3.4.2, Page21-22.  */
5948 
5949     /* Allocate the packet.  */
5950     status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &packet_ptr, NX_NO_WAIT);
5951 
5952     /* Determine if the send was unsuccessful.  */
5953     if (status)
5954     {
5955 
5956         /* Return error.  */
5957         return(status);
5958     }
5959 
5960     /* We have a packet, setup pointer to the buffer area.  */
5961     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
5962 
5963     /* Set the block header.  */
5964     if (block_size)
5965     {
5966 
5967         /* Descriptor.  */
5968         buffer_ptr[0] = 0;
5969 
5970         /* Byte count.  */
5971         buffer_ptr[1] = (UCHAR)(block_size >> 8);
5972         buffer_ptr[2] = (UCHAR)(block_size);
5973     }
5974     else
5975     {
5976 
5977         /* Descriptor.  */
5978         buffer_ptr[0] = 64;
5979 
5980         /* Byte count.  */
5981         buffer_ptr[1] = 0;
5982         buffer_ptr[2] = 0;
5983     }
5984 
5985     /* Setup the length of the packet.  */
5986     packet_ptr -> nx_packet_length = 3;
5987 
5988     /* Setup the packet append pointer.  */
5989     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
5990 
5991     /* Write packet payload to the file.  */
5992     status =  nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, NX_NO_WAIT);
5993 
5994     /* Determine if the send was unsuccessful.  */
5995     if (status)
5996     {
5997 
5998         /* Release the packet.  */
5999         nx_packet_release(packet_ptr);
6000     }
6001 
6002     /* Return success to caller.  */
6003     return(status);
6004 }
6005 
6006 
6007 /**************************************************************************/
6008 /*                                                                        */
6009 /*  FUNCTION                                               RELEASE        */
6010 /*                                                                        */
6011 /*    _nx_ftp_client_block_header_retrieve                PORTABLE C      */
6012 /*                                                           6.1          */
6013 /*  AUTHOR                                                                */
6014 /*                                                                        */
6015 /*    Yuxin Zhou, Microsoft Corporation                                   */
6016 /*                                                                        */
6017 /*  DESCRIPTION                                                           */
6018 /*                                                                        */
6019 /*    This function retrieves the block header for block mode.            */
6020 /*                                                                        */
6021 /*  INPUT                                                                 */
6022 /*                                                                        */
6023 /*    ftp_client_ptr                        Pointer to FTP client         */
6024 /*    packet_ptr                            Pointer to packet to write    */
6025 /*                                                                        */
6026 /*  OUTPUT                                                                */
6027 /*                                                                        */
6028 /*    status                                Completion status             */
6029 /*                                                                        */
6030 /*  CALLS                                                                 */
6031 /*                                                                        */
6032 /*    nx_packet_release                     Release packet                */
6033 /*    nx_tcp_socket_send                    Send data packet to server    */
6034 /*                                                                        */
6035 /*  CALLED BY                                                             */
6036 /*                                                                        */
6037 /*    _nx_ftp_client_file_read              Read data from server         */
6038 /*    _nx_ftp_client_directory_listing_get  Get directory list            */
6039 /*    _nx_ftp_client_directory_listing_continue                           */
6040 /*                                          Continue to get directory list*/
6041 /*                                                                        */
6042 /*  RELEASE HISTORY                                                       */
6043 /*                                                                        */
6044 /*    DATE              NAME                      DESCRIPTION             */
6045 /*                                                                        */
6046 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6047 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6048 /*                                            resulting in version 6.1    */
6049 /*                                                                        */
6050 /**************************************************************************/
_nx_ftp_client_block_header_retrieve(NX_FTP_CLIENT * ftp_client_ptr,NX_PACKET * packet_ptr)6051 UINT  _nx_ftp_client_block_header_retrieve(NX_FTP_CLIENT *ftp_client_ptr, NX_PACKET *packet_ptr)
6052 {
6053 
6054 ULONG       delta;
6055 UCHAR       *buffer_ptr;
6056 #ifndef NX_DISABLE_PACKET_CHAIN
6057 NX_PACKET   *before_last_packet;
6058 NX_PACKET   *last_packet;
6059 #endif /* NX_DISABLE_PACKET_CHAIN */
6060 
6061 
6062     /* Check if it is the first packet.  */
6063     if (ftp_client_ptr -> nx_ftp_client_block_total_size == 0)
6064     {
6065 
6066         /* Check the packet length.  */
6067         if ((packet_ptr -> nx_packet_length < 3) ||
6068             (packet_ptr -> nx_packet_prepend_ptr + 3 > packet_ptr -> nx_packet_append_ptr))
6069         {
6070 
6071             /* Release the packet.  */
6072             nx_packet_release(packet_ptr);
6073             return(NX_FTP_CLIENT_INVALID_SIZE);
6074         }
6075 
6076         /* We have a packet, setup pointer to the buffer area.  */
6077         buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
6078 
6079         /* Process block header.  */
6080         ftp_client_ptr -> nx_ftp_client_block_total_size = (ULONG)((buffer_ptr[1] << 8) | buffer_ptr[2]);
6081         ftp_client_ptr -> nx_ftp_client_block_remaining_size = ftp_client_ptr -> nx_ftp_client_block_total_size;
6082 
6083         /* Skip the block header.  */
6084         packet_ptr -> nx_packet_prepend_ptr += 3;
6085         packet_ptr -> nx_packet_length -= 3;
6086     }
6087 
6088     /* Check if have remaining data.  */
6089     if (ftp_client_ptr -> nx_ftp_client_block_remaining_size == 0)
6090     {
6091 
6092         /* Release the packet.  */
6093         nx_packet_release(packet_ptr);
6094         return(NX_FTP_CLIENT_END_OF_BLOCK);
6095     }
6096 
6097     /* Check the data of current packet.  */
6098     if (ftp_client_ptr -> nx_ftp_client_block_remaining_size < packet_ptr -> nx_packet_length)
6099     {
6100 
6101         /* Remove the extra data, such as: end block header.  */
6102 
6103         /* Calculate the difference in the length.  */
6104         delta =  packet_ptr -> nx_packet_length - ftp_client_ptr -> nx_ftp_client_block_remaining_size;
6105 
6106         /* Adjust the packet length.  */
6107         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length - delta;
6108 
6109         /* Adjust the append pointer.  */
6110 
6111 #ifndef NX_DISABLE_PACKET_CHAIN
6112         /* Loop to process adjustment that spans multiple packets.  */
6113         while (delta)
6114         {
6115 
6116             /* Determine if the packet is chained (or still chained after the adjustment).  */
6117             if (packet_ptr -> nx_packet_last == NX_NULL)
6118             {
6119 
6120                 /* No, packet is not chained, simply adjust the append pointer in the packet.  */
6121                 packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr - delta;
6122 
6123                 /* Break out of the loop, since the adjustment is complete.  */
6124                 break;
6125             }
6126 
6127             /* Pickup the pointer to the last packet.  */
6128             last_packet =  packet_ptr -> nx_packet_last;
6129 
6130             /* Determine if the amount to adjust is less than the payload in the last packet.  */
6131             /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
6132             if (((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr)) > delta)
6133             {
6134 
6135                 /* Yes, simply adjust the append pointer of the last packet in the chain.  */
6136                 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
6137                 last_packet -> nx_packet_append_ptr =  last_packet -> nx_packet_append_ptr - delta;
6138 
6139                 /* Get out of the loop, since the adjustment is complete.  */
6140                 break;
6141             }
6142             else
6143             {
6144 
6145                 /* Adjust the delta by the amount in the last packet.  */
6146                 delta =  delta - ((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr));
6147 
6148                 /* Find the packet before the last packet.  */
6149                 before_last_packet =  packet_ptr;
6150                 while (before_last_packet -> nx_packet_next != last_packet)
6151                 {
6152 
6153                     /* Move to the next packet in the chain.  */
6154                     before_last_packet =  before_last_packet -> nx_packet_next;
6155                 }
6156 
6157                 /* At this point, we need to release the last packet and adjust the other packet
6158                     pointers.  */
6159 
6160                 /* Ensure the next packet pointer is NULL in what is now the last packet.  */
6161                 before_last_packet -> nx_packet_next =  NX_NULL;
6162 
6163                 /* Determine if the packet is still chained.  */
6164                 if (packet_ptr != before_last_packet)
6165                 {
6166 
6167                     /* Yes, the packet is still chained, setup the last packet pointer.  */
6168                     packet_ptr -> nx_packet_last =  before_last_packet;
6169                 }
6170                 else
6171                 {
6172 
6173                     /* The packet is no longer chained, set the last packet pointer to NULL.  */
6174                     packet_ptr -> nx_packet_last =  NX_NULL;
6175                 }
6176 
6177                 /* Release the last packet.   */
6178                 _nx_packet_release(last_packet);
6179             }
6180         }
6181 #else
6182 
6183         /* Simply adjust the append pointer in the packet.  */
6184         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr - delta;
6185 #endif /* NX_DISABLE_PACKET_CHAIN */
6186     }
6187 
6188     /* Update the file size.  */
6189     ftp_client_ptr -> nx_ftp_client_block_remaining_size -= packet_ptr -> nx_packet_length;
6190 
6191     /* Return success to caller.  */
6192     return(NX_SUCCESS);
6193 }
6194