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