mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-23 05:33:35 +08:00
Completes coding of the PWM module
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4200 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
############################################################################
|
||||
# apps/netutils/ftpc/Makefile
|
||||
#
|
||||
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
# DHCP Daemn Library
|
||||
|
||||
ASRCS =
|
||||
CSRCS =
|
||||
|
||||
ifeq ($(CONFIG_NET_TCP),y)
|
||||
# FTP connection management
|
||||
CSRCS = ftpc_connect.c ftpc_disconnect.c
|
||||
|
||||
# FTP commands
|
||||
CSRCS += ftpc_cdup.c ftpc_chdir.c ftpc_chmod.c ftpc_filesize.c ftpc_filetime.c
|
||||
CSRCS += ftpc_help.c ftpc_idle.c ftpc_listdir.c ftpc_login.c ftpc_mkdir.c
|
||||
CSRCS += ftpc_noop.c ftpc_rpwd.c ftpc_quit.c ftpc_rename.c ftpc_rmdir.c ftpc_unlink.c
|
||||
CSRCS += ftpc_cmd.c
|
||||
|
||||
# FTP transfers
|
||||
CSRCS += ftpc_getfile.c ftpc_putfile.c ftpc_transfer.c
|
||||
|
||||
# FTP responses
|
||||
CSRCS += ftpc_response.c ftpc_getreply.c
|
||||
|
||||
# FTP helpers
|
||||
CSRCS += ftpc_utils.c ftpc_socket.c
|
||||
endif
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||
else
|
||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||
endif
|
||||
|
||||
ROOTDEPPATH = --dep-path .
|
||||
|
||||
# Common build
|
||||
|
||||
VPATH =
|
||||
|
||||
all: .built
|
||||
.PHONY: context depend clean distclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
.built: $(OBJS)
|
||||
@( for obj in $(OBJS) ; do \
|
||||
$(call ARCHIVE, $(BIN), $${obj}); \
|
||||
done ; )
|
||||
@touch .built
|
||||
|
||||
context:
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
@touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@rm -f *.o *~ .*.swp .built
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
@rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
@@ -0,0 +1,81 @@
|
||||
/* FTP Commands *************************************************************/
|
||||
/* Command summary:
|
||||
*
|
||||
* ABOR - abort a file transfer
|
||||
* ACCT - send account information
|
||||
* APPE - append to a remote file
|
||||
* CDUP - CWD to the parent of the current directory
|
||||
* CWD - change working directory
|
||||
* DELE - delete a remote file
|
||||
* HELP - return help on using the server
|
||||
* LIST - list remote files
|
||||
* MDTM - return the modification time of a file
|
||||
* MKD - make a remote directory
|
||||
* MLSD - Standardized directory listing (instead of LIST)
|
||||
* MLST - Standardized object listing (instead of LIST)
|
||||
* MODE - set transfer mode
|
||||
* NLST - name list of remote directory
|
||||
* NOOP - do nothing
|
||||
* PASS - send password
|
||||
* PASV - enter passive mode
|
||||
* PORT - open a data port
|
||||
* PWD - print working directory
|
||||
* QUIT - terminate the connection
|
||||
* REIN - reinitialize the connection
|
||||
* RETR - retrieve a remote file
|
||||
* REST - Sets the point at which a file transfer should start
|
||||
* RMD - remove a remote directory
|
||||
* RNFR - rename from
|
||||
* RNTO - rename to
|
||||
* SITE - site-specific commands
|
||||
* SIZE - return the size of a file
|
||||
* STOR - store a file on the remote host
|
||||
* STOU - store a file uniquely
|
||||
* STRU - set file transfer structure
|
||||
* STAT - return server status
|
||||
* SYST - return system type
|
||||
* TYPE - set transfer type
|
||||
* USER - send username
|
||||
*
|
||||
/* FTP Replies **************************************************************/
|
||||
*
|
||||
* 110 - Restart marker reply.
|
||||
* 120 - Service ready in nnn minutes.
|
||||
* 125 - Data connection already open; transfer starting.
|
||||
* 150 - File status okay; about to open data connection.
|
||||
* 200 - Command okay.
|
||||
* 202 - Command not implemented, superfluous at this site.
|
||||
* 211 - System status, or system help reply.
|
||||
* 212 - Directory status.
|
||||
* 213 - File status.
|
||||
* 214 - Help message.
|
||||
* 215 - NAME system type.
|
||||
* 220 - Service ready for new user.
|
||||
* 221 - Service closing control connection.
|
||||
* 225 - Data connection open; no transfer in progress.
|
||||
* 226 - Closing data connection.
|
||||
* 227 - Entering Passive Mode (h1,h2,h3,h4,p1,p2).
|
||||
* 230 - User logged in, proceed.
|
||||
* 250 - Requested file action okay, completed.
|
||||
* 257 - "PATHNAME" created.
|
||||
* 331 - User name okay, need password.
|
||||
* 332 - Need account for login.
|
||||
* 350 - Requested file action pending further information.
|
||||
* 421 - Service not available, closing control connection.
|
||||
* 425 - Can't open data connection.
|
||||
* 426 - Connection closed; transfer aborted.
|
||||
* 450 - Requested file action not taken.
|
||||
* 451 - Requested action aborted: local error in processing.
|
||||
* 452 - Requested action not taken.
|
||||
* 500 - Syntax error, command unrecognized.
|
||||
* 501 - Syntax error in parameters or arguments.
|
||||
* 502 - Command not implemented.
|
||||
* 503 - Bad sequence of commands.
|
||||
* 504 - Command not implemented for that parameter.
|
||||
* 530 - Not logged in.
|
||||
* 532 - Need account for storing files.
|
||||
* 550 - Requested action not taken.
|
||||
* 551 - Requested action aborted: page type unknown.
|
||||
* 552 - Requested file action aborted.
|
||||
* 553 - Requested action not taken.
|
||||
*/
|
||||
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_cdup.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_cdup
|
||||
*
|
||||
* Description:
|
||||
* Make the parent of the current directory be the new current directory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_cdup(SESSION handle)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret;
|
||||
|
||||
ret = ftpc_cmd(session, "CDUP");
|
||||
session->currdir = ftpc_rpwd(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_chdir.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_chdir
|
||||
*
|
||||
* Description:
|
||||
* Change the current working directory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_chdir(SESSION handle, FAR const char *path)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret;
|
||||
|
||||
ret = ftpc_cmd(session, "CWD %s", path);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
session->currdir = ftpc_rpwd(handle);
|
||||
return OK;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_chmod.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_chmod
|
||||
*
|
||||
* Description:
|
||||
* Change the protections on the remote file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_chmod(SESSION handle, FAR const char *path, FAR const char *mode)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret;
|
||||
|
||||
/* Does the server support the size CHMOD command? */
|
||||
|
||||
if (FTPC_HAS_CHMOD(session))
|
||||
{
|
||||
ret = ftpc_cmd(session, "SITE CHMOD %s %s", path, mode);
|
||||
|
||||
/* Check for "502 Command not implemented" */
|
||||
|
||||
if (session->code == 502)
|
||||
{
|
||||
/* No.. the server does not support the SITE CHMOD command */
|
||||
|
||||
FTPC_CLR_CHMOD(session);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndbg("Server does not support SITE CHMOD\n");
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_cmd.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_restore
|
||||
*
|
||||
* Description:
|
||||
* Restore the connection to the server and log in again.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FTP_AUTORECONNECT
|
||||
static int ftpc_restore(struct ftpc_session_s *session)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (session)
|
||||
{
|
||||
/* Set the initial directory to the last valid current directory */
|
||||
|
||||
free(session->initrdir);
|
||||
session->initrdir = ftpc_dequote(session->currdir);
|
||||
|
||||
/* Reconnect to the server */
|
||||
|
||||
ret = ftpc_reconnect(session);
|
||||
if (ret == 0)
|
||||
{
|
||||
/* Log into the server */
|
||||
|
||||
ret = ftpc_relogin(session);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to reconnect to the server */
|
||||
|
||||
ftpc_reset(session);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_cmd
|
||||
*
|
||||
* Description:
|
||||
* Send the specified command to the server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_cmd(struct ftpc_session_s *session, const char *cmd, ...)
|
||||
{
|
||||
va_list ap;
|
||||
#ifdef CONFIG_FTP_AUTORECONNECT
|
||||
bool reconnect = false;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Verify that we are still connecte to the server */
|
||||
|
||||
if (!ftpc_sockconnected(&session->cmd))
|
||||
{
|
||||
ndbg("Cmd channel si not connected\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Loop, reconnecting as necessary until the command is sent */
|
||||
|
||||
#ifdef CONFIG_FTP_AUTORECONNECT
|
||||
for (;;)
|
||||
#endif
|
||||
{
|
||||
/* Send the command */
|
||||
|
||||
va_start(ap, cmd);
|
||||
ret = ftpc_sockvprintf(&session->cmd, cmd, ap);
|
||||
if (ret >= 0)
|
||||
{
|
||||
ret = ftpc_sockprintf(&session->cmd, "\r\n");
|
||||
if (ret >= 0)
|
||||
{
|
||||
ret = ftpc_sockflush(&session->cmd);
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* Check for an error in sending the data */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("Error sending cmd %s: %d\n", cmd, errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get the response to the command */
|
||||
|
||||
ret = fptc_getreply(session);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("Error getting reply: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check for "421 Service not available, closing control connection" */
|
||||
|
||||
if (session->code == 421)
|
||||
{
|
||||
/* Server is closing the control connection. */
|
||||
|
||||
ndbg("Server closed control connection\n");
|
||||
|
||||
/* If we were previously logged in and this is not a QUIT commnad
|
||||
* then attempt to automatically reconnect to the server.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_FTP_AUTORECONNECT
|
||||
if (ftpc_loggedin(session) && strcasecmp(cmd, "QUIT") != 0)
|
||||
{
|
||||
/* Don't try re-connecting more than once */
|
||||
|
||||
if (reconnect)
|
||||
{
|
||||
ndbg("Reconnect failed\n");
|
||||
goto errout;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to restore the connection and, if successful,
|
||||
* continue the loop and try to send the command again.
|
||||
*/
|
||||
|
||||
ndbg("Reconnecting...\n");
|
||||
reconnect = true;
|
||||
ret = ftpc_restore();
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("Failed to restore the connection");
|
||||
goto errout;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Don't try to connect, just return an error (retaining
|
||||
* the session response code (421)
|
||||
*/
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* The command was successfully sent */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
errout:
|
||||
session->code = -1;
|
||||
return ERROR;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_config.h
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_NETUTILS_FTPC_FTPC_CONFIG_H
|
||||
#define __APPS_NETUTILS_FTPC_FTPC_CONFIG_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* This is a mindless little wrapper around include/nuttx/config.h. Every
|
||||
* file in the ftpc directory includes this file at the very beginning of
|
||||
* of the file (instead of include/nuttx/config.h). The only purpose of
|
||||
* this file is to muck with some of the settings to support some debug
|
||||
* features.
|
||||
*
|
||||
* The FPT client uses common networking debug macros (ndbg and nvdbg).
|
||||
* This can be overwhelming if there is a lot of networking debug output
|
||||
* as well. But by defining CONFIG_DEBUG_FTPC, this file will force
|
||||
* networking debug ON only for the files within this directory.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_FTPC)
|
||||
# define CONFIG_DEBUG_NET 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __APPS_NETUTILS_FTPC_FTPC_CONFIG_H */
|
||||
@@ -0,0 +1,250 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_connect.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_connect
|
||||
*
|
||||
* Description:
|
||||
* Create a session handle and connect to the server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
SESSION ftpc_connect(FAR struct ftpc_connect_s *server)
|
||||
{
|
||||
FAR struct ftpc_session_s *session;
|
||||
int ret;
|
||||
|
||||
/* Allocate a session structure */
|
||||
|
||||
session = (struct ftpc_session_s *)zalloc(sizeof(struct ftpc_session_s));
|
||||
if (!session)
|
||||
{
|
||||
ndbg("Failed to allocate a session\n");
|
||||
set_errno(ENOMEM);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Initialize the session structure with all non-zero and variable values */
|
||||
|
||||
session->addr.s_addr = server->addr.s_addr;
|
||||
session->flags &= ~FTPC_FLAGS_CLEAR;
|
||||
session->flags |= FTPC_FLAGS_SET;
|
||||
session->replytimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
session->conntimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
session->pid = getpid();
|
||||
|
||||
/* Use the default port if the user specified port number zero */
|
||||
|
||||
if (!server->port)
|
||||
{
|
||||
session->port = HTONS(CONFIG_FTP_DEFPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
session->port = htons(server->port);
|
||||
}
|
||||
|
||||
/* Get the local home directory, i.e., the value of the PWD environment
|
||||
* variable at the time of the connection. We keep a local copy so that
|
||||
* we can change the current working directory without effecting any other
|
||||
* logic that may be in same context.
|
||||
*/
|
||||
|
||||
session->homeldir = strdup(ftpc_lpwd());
|
||||
/* session->curldir = strdup(sssion->homeldir); */
|
||||
|
||||
/* Create up a timer to prevent hangs */
|
||||
|
||||
session->wdog = wd_create();
|
||||
|
||||
/* And (Re-)connect to the server */
|
||||
|
||||
ret = ftpc_reconnect(session);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_reconnect() failed: %d\n", errno);
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
return (SESSION)session;
|
||||
|
||||
errout_with_alloc:
|
||||
free(session);
|
||||
errout:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_reconnect
|
||||
*
|
||||
* Description:
|
||||
* re-connect to the server either initially, or after loss of connection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_reconnect(FAR struct ftpc_session_s *session)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
#ifdef CONFIG_DEBUG
|
||||
char *tmp;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Re-initialize the session structure */
|
||||
|
||||
session->replytimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
session->conntimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
session->xfrmode = FTPC_XFRMODE_UNKNOWN;
|
||||
|
||||
/* Set up a timer to prevent hangs */
|
||||
|
||||
ret = wd_start(session->wdog, session->conntimeo, ftpc_timeout, 1, session);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("wd_start() failed\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Initialize a socket */
|
||||
|
||||
ret = ftpc_sockinit(&session->cmd);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_sockinit() failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Connect the socket to the server */
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
tmp = inet_ntoa(session->addr);
|
||||
ndbg("Connecting to server address %s:%d\n", tmp, ntohs(session->port));
|
||||
#endif
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = session->port;
|
||||
addr.sin_addr.s_addr = session->addr.s_addr;
|
||||
|
||||
ret = ftpc_sockconnect(&session->cmd, &addr);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_sockconnect() failed: %d\n", errno);
|
||||
goto errout_with_socket;
|
||||
}
|
||||
|
||||
/* Read startup message from server */
|
||||
|
||||
fptc_getreply(session);
|
||||
|
||||
/* Check for "120 Service ready in nnn minutes" */
|
||||
|
||||
if (session->code == 120)
|
||||
{
|
||||
fptc_getreply(session);
|
||||
}
|
||||
wd_cancel(session->wdog);
|
||||
|
||||
if (!ftpc_sockconnected(&session->cmd))
|
||||
{
|
||||
ftpc_reset(session);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check for "220 Service ready for new user" */
|
||||
|
||||
if (session->code == 220)
|
||||
{
|
||||
FTPC_SET_CONNECTED(session);
|
||||
}
|
||||
|
||||
if (!FTPC_IS_CONNECTED(session))
|
||||
{
|
||||
goto errout_with_socket;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
ndbg("Connected\n");
|
||||
tmp = inet_ntoa(addr.sin_addr);
|
||||
ndbg(" Remote address: %s:%d\n", tmp, ntohs(addr.sin_port));
|
||||
tmp = inet_ntoa(session->cmd.laddr.sin_addr);
|
||||
ndbg(" Local address: %s:%d\n", tmp, ntohs(session->cmd.laddr.sin_port));
|
||||
#endif
|
||||
return OK;
|
||||
|
||||
errout_with_socket:
|
||||
ftpc_sockclose(&session->cmd);
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_disconnect.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_disconnect
|
||||
*
|
||||
* Description:
|
||||
* Disconnect from the server and destroy the session handle..
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_disconnect(SESSION handle)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
if (session)
|
||||
{
|
||||
/* Release sockets */
|
||||
|
||||
ftpc_sockclose(&session->data);
|
||||
ftpc_sockclose(&session->cmd);
|
||||
|
||||
/* Free strings */
|
||||
|
||||
free(session->uname);
|
||||
free(session->pwd);
|
||||
free(session->initrdir);
|
||||
free(session->homerdir);
|
||||
free(session->currdir);
|
||||
|
||||
/* Then destroy the session */
|
||||
|
||||
free(session);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_filesize.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_filesize
|
||||
*
|
||||
* Description:
|
||||
* Return the size of the given file on the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
off_t ftpc_filesize(SESSION handle, FAR const char *path)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
unsigned long ret;
|
||||
|
||||
/* Check if the host supports the SIZE command */
|
||||
|
||||
if (!FTPC_HAS_SIZE(session))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (ftpc_xfrmode(session, FTPC_XFRMODE_ASCII) != 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = ftpc_cmd(session, "SIZE %s", path);
|
||||
|
||||
/* Check for "502 Command not implemented" */
|
||||
|
||||
if (session->code == 502)
|
||||
{
|
||||
/* No.. the host does not support the SIZE command */
|
||||
|
||||
FTPC_CLR_SIZE(session);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
sscanf(session->reply, "%*s %lu", &ret);
|
||||
return (off_t)ret;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_filetime.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_filetime
|
||||
*
|
||||
* Descripton:
|
||||
* Return the timestamp on the remote file. Returned time is UTC
|
||||
* (Universal Coordinated Time).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
time_t ftpc_filetime(SESSION handle, FAR const char *filename)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
struct tm timestamp;
|
||||
int ret;
|
||||
|
||||
/* Make sure that the server is still connected */
|
||||
|
||||
if (!ftpc_connected(session))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Does the server support the MDTM command? */
|
||||
|
||||
if (!FTPC_HAS_MDTM(session))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the file time in UTC */
|
||||
|
||||
memset(×tamp, 0, sizeof(timestamp));
|
||||
ret = ftpc_cmd(session, "MDTM %s", filename);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for "202 Command not implemented, superfluous at this site" */
|
||||
|
||||
if (session->code == 202)
|
||||
{
|
||||
FTPC_CLR_MDTM(session);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for "213 File status" */
|
||||
|
||||
if (session->code != 213)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Time is Universal Coordinated Time */
|
||||
|
||||
sscanf(session->reply, "%*s %04d%02d%02d%02d%02d%02d",
|
||||
×tamp.tm_year, ×tamp.tm_mon, ×tamp.tm_mday,
|
||||
×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec);
|
||||
timestamp.tm_year -= 1900;
|
||||
timestamp.tm_mon--;
|
||||
return mktime(×tamp);
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_getfile.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_recvinit
|
||||
*
|
||||
* Description:
|
||||
* Initialize to receive a file
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_recvinit(struct ftpc_session_s *session, FAR const char *path,
|
||||
uint8_t xfrmode, off_t offset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Reset transfer related variables */
|
||||
|
||||
ftpc_xfrreset(session);
|
||||
|
||||
ret = ftpc_xfrinit(session);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Configure the transfer: Initial file offset and tranfer mode */
|
||||
|
||||
session->offset = 0;
|
||||
ftpc_xfrmode(session, xfrmode);
|
||||
|
||||
/* Handle the resume offset (caller is responsible for fseeking in the
|
||||
* file)
|
||||
*/
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
/* Send the REST command. This command sets the offset where the
|
||||
* transfer should start. This must come after PORT or PASV commands.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "REST %ld", offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("REST command failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
session->size = offset;
|
||||
}
|
||||
|
||||
/* Send the RETR (Retrieve a remote file) command. Normally the server
|
||||
* responds with a mark using code 150:
|
||||
*
|
||||
* - "150 File status okay; about to open data connection"
|
||||
*
|
||||
* It then stops accepting new connections, attempts to send the contents
|
||||
* of the file over the data connection, and closes the data connection.
|
||||
* Finally it either accepts the RETR request with:
|
||||
*
|
||||
* - "226 Closing data connection" if the entire file was successfully
|
||||
* written to the server's TCP buffers
|
||||
*
|
||||
* Or rejects the RETR request with:
|
||||
*
|
||||
* - "425 Can't open data connection" if no TCP connection was established
|
||||
* - "426 Connection closed; transfer aborted" if the TCP connection was
|
||||
* established but then broken by the client or by network failure
|
||||
* - "451 Requested action aborted: local error in processing" or
|
||||
* "551 Requested action aborted: page type unknown" if the server had
|
||||
* trouble reading the file from disk.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "RETR %s", path);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("RETR command failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* In active mode, we need to accept a connection on the data socket
|
||||
* (in passive mode, we have already connected the data channel to
|
||||
* the FTP server).
|
||||
*/
|
||||
|
||||
if (!FTPC_IS_PASSIVE(session))
|
||||
{
|
||||
ret = ftpc_sockaccept(&session->data);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("Data connection not accepted\n");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_recvbinary
|
||||
*
|
||||
* Description:
|
||||
* Receive a binary file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_recvbinary(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *rinstream, FAR FILE *loutstream)
|
||||
{
|
||||
ssize_t nread;
|
||||
ssize_t nwritten;
|
||||
|
||||
/* Loop until the entire file is received */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Read the data from the socket */
|
||||
|
||||
nread = fread(session->buffer, sizeof(char), CONFIG_FTP_BUFSIZE, rinstream);
|
||||
if (nread <= 0)
|
||||
{
|
||||
/* nread < 0 is an error */
|
||||
|
||||
if (nread < 0)
|
||||
{
|
||||
/* errno should already be set by fread */
|
||||
|
||||
(void)ftpc_xfrabort(session, rinstream);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* nread == 0 means end of file. Return success */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Write the data to the file */
|
||||
|
||||
nwritten = fwrite(session->buffer, sizeof(char), nread, loutstream);
|
||||
if (nwritten != nread)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, loutstream);
|
||||
|
||||
/* If nwritten < 0 errno should already be set by fwrite.
|
||||
* What would a short write mean?
|
||||
*/
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Increment the size of the file written */
|
||||
|
||||
session->size += nwritten;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_getfile
|
||||
*
|
||||
* Description:
|
||||
* Get a file from the remote host.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
|
||||
uint8_t how, uint8_t xfrmode)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
struct stat statbuf;
|
||||
FILE *loutstream;
|
||||
FAR char *abslpath;
|
||||
off_t offset;
|
||||
int ret;
|
||||
|
||||
/* Don't call this with a NULL remote file name */
|
||||
|
||||
DEBUGASSERT(rname);
|
||||
|
||||
/* If the local name is not specified, then it is assumed to the same as
|
||||
* the remote file name.
|
||||
*/
|
||||
|
||||
if (!lname)
|
||||
{
|
||||
lname = rname;
|
||||
}
|
||||
|
||||
/* Get the full path to the local file */
|
||||
|
||||
abslpath = ftpc_abslpath(session, lname);
|
||||
if (!abslpath)
|
||||
{
|
||||
ndbg("ftpc_abslpath(%s) failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get information about the local file */
|
||||
|
||||
ret = stat(abslpath, &statbuf);
|
||||
if (ret == 0)
|
||||
{
|
||||
/* It already exists. Is it a directory? */
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
ndbg("'%s' is a directory\n", abslpath);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is it write-able? */
|
||||
|
||||
#ifdef S_IWRITE
|
||||
if (!(statbuf.st_mode & S_IWRITE))
|
||||
{
|
||||
ndbg("'%s' permission denied\n", abslpath);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Are we resuming the transfers? Is so then the starting offset is the
|
||||
* size of the existing, partial file.
|
||||
*/
|
||||
|
||||
if (how == FTPC_GET_RESUME)
|
||||
{
|
||||
offset = statbuf.st_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
/* Setup to receive the file */
|
||||
|
||||
ret = ftpc_recvinit(session, rname, xfrmode, offset);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_recvinit failed\n");
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
|
||||
loutstream = fopen(abslpath, (offset > 0 || (how == FTPC_GET_APPEND)) ? "a" : "w");
|
||||
if (!loutstream)
|
||||
{
|
||||
ndbg("fopen failed: %d\n", errno);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
|
||||
/* If the offset is non-zero, then seek to that offset in the file */
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
ret = fseek(loutstream, offset, SEEK_SET);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("fseek failed: %d\n", errno);
|
||||
goto errout_with_outstream;
|
||||
}
|
||||
}
|
||||
|
||||
/* And receive the new file data */
|
||||
|
||||
if (xfrmode == FTPC_XFRMODE_ASCII)
|
||||
{
|
||||
ret = ftpc_recvtext(session, session->data.instream, loutstream);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ftpc_recvbinary(session, session->data.instream, loutstream);
|
||||
}
|
||||
|
||||
ftpc_sockclose(&session->data);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
fptc_getreply(session);
|
||||
}
|
||||
|
||||
/* Check for success */
|
||||
|
||||
if (ret == OK && !FTPC_INTERRUPTED(session))
|
||||
{
|
||||
fclose(loutstream);
|
||||
free(abslpath);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Various error exits */
|
||||
|
||||
errout_with_outstream:
|
||||
fclose(loutstream);
|
||||
errout_with_abspath:
|
||||
free(abslpath);
|
||||
session->offset = 0;
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_recvtext
|
||||
*
|
||||
* Description:
|
||||
* Receive a text file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_recvtext(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *rinstream, FAR FILE *loutstream)
|
||||
{
|
||||
int ch;
|
||||
|
||||
/* Read the next character from the incoming data stream */
|
||||
|
||||
while ((ch = fgetc(rinstream)) != EOF)
|
||||
{
|
||||
/* Is it a carriage return? Compress \r\n to \n */
|
||||
|
||||
if (ch == '\r')
|
||||
{
|
||||
/* Get the next character */
|
||||
|
||||
ch = fgetc(rinstream);
|
||||
if (ch == EOF)
|
||||
{
|
||||
/* Ooops... */
|
||||
|
||||
(void)ftpc_xfrabort(session, rinstream);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* If its not a newline, then keep the carriage return */
|
||||
|
||||
if (ch != '\n')
|
||||
{
|
||||
ungetc(ch, rinstream);
|
||||
ch = '\r';
|
||||
}
|
||||
}
|
||||
|
||||
/* Then write the character to the output file */
|
||||
|
||||
if (fputc(ch, loutstream) == EOF)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, loutstream);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Increase the actual size of the file by one */
|
||||
|
||||
session->size++;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_getreply.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_gets
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_gets(struct ftpc_session_s *session)
|
||||
{
|
||||
int ch;
|
||||
int ndx = 0;
|
||||
|
||||
/* Start wth an empty response string */
|
||||
|
||||
session->reply[0] = '\0';
|
||||
|
||||
/* Verify that the command channel is still connected */
|
||||
|
||||
if (!ftpc_sockconnected(&session->cmd))
|
||||
{
|
||||
ndbg("Cmd channel disconnected\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Loop until the full line is obtained */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Get the next character from incoming command stream */
|
||||
|
||||
ch = ftpc_sockgetc(&session->cmd);
|
||||
|
||||
/* Check if the command stream was closed */
|
||||
|
||||
if (ch == EOF)
|
||||
{
|
||||
ndbg("EOF: Server closed command stream\n");
|
||||
ftpc_reset(session);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Handle embedded Telnet stuff */
|
||||
|
||||
else if (ch == TELNET_IAC)
|
||||
{
|
||||
/* Handle TELNET commands */
|
||||
|
||||
switch(ch = ftpc_sockgetc(&session->cmd))
|
||||
{
|
||||
case TELNET_WILL:
|
||||
case TELNET_WONT:
|
||||
ch = ftpc_sockgetc(&session->cmd);
|
||||
ftpc_sockprintf(&session->cmd, "%c%c%c", TELNET_IAC, TELNET_DONT, ch);
|
||||
ftpc_sockflush(&session->cmd);
|
||||
break;
|
||||
|
||||
case TELNET_DO:
|
||||
case TELNET_DONT:
|
||||
ch = ftpc_sockgetc(&session->cmd);
|
||||
ftpc_sockprintf(&session->cmd, "%c%c%c", TELNET_IAC, TELNET_WONT, ch);
|
||||
ftpc_sockflush(&session->cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Deal with carriage returns */
|
||||
|
||||
else if (ch == ISO_cr)
|
||||
{
|
||||
/* What follows the carriage return? */
|
||||
|
||||
ch = ftpc_sockgetc(&session->cmd);
|
||||
if (ch == '\0')
|
||||
{
|
||||
/* If it is followed by a NUL then keep it */
|
||||
|
||||
ch = ISO_cr;
|
||||
}
|
||||
|
||||
/* If it is followed by a newline then break out of the loop. */
|
||||
|
||||
else if (ch == ISO_nl)
|
||||
{
|
||||
/* Newline terminates the reply */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we did not lose the connection, then push the character
|
||||
* following the carriage back on the "stack" and continue to
|
||||
* examine it from scratch (if could be part of the Telnet
|
||||
* protocol).
|
||||
*/
|
||||
|
||||
else if (ch != EOF)
|
||||
{
|
||||
ungetc(ch, session->cmd.instream);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if (ch == ISO_nl)
|
||||
{
|
||||
/* The ISO newline character terminates the string. Just break
|
||||
* out of the loop.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Put the character into the response buffer. Is there space for
|
||||
* another character in the reply buffer?
|
||||
*/
|
||||
|
||||
if (ndx < CONFIG_FTP_MAXREPLY)
|
||||
{
|
||||
/* Yes.. put the character in the reply buffer */
|
||||
|
||||
session->reply[ndx++] = (char)ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndbg("Reply truncated\n");
|
||||
}
|
||||
}
|
||||
|
||||
session->reply[ndx] = '\0';
|
||||
session->code = atoi(session->reply);
|
||||
return session->code;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_getreply
|
||||
****************************************************************************/
|
||||
|
||||
int fptc_getreply(struct ftpc_session_s *session)
|
||||
{
|
||||
char tmp[5]="xxx ";
|
||||
int ret;
|
||||
|
||||
/* Set up a timeout */
|
||||
|
||||
if (session->replytimeo)
|
||||
{
|
||||
ret = wd_start(session->wdog, session->replytimeo, ftpc_timeout, 1, session);
|
||||
}
|
||||
|
||||
/* Get the next line from the server */
|
||||
|
||||
ret = ftpc_gets(session);
|
||||
|
||||
/* Do we still have a connection? */
|
||||
|
||||
if (!ftpc_sockconnected(&session->cmd))
|
||||
{
|
||||
/* No.. cancel the timer and return an error */
|
||||
|
||||
wd_cancel(session->wdog);
|
||||
nvdbg("Lost connection\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Did an error occur? */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* No.. cancel the timer and return an error */
|
||||
|
||||
wd_cancel(session->wdog);
|
||||
nvdbg("ftpc_gets failed\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
nvdbg("Reply: %s\n", session->reply);
|
||||
|
||||
if (session->reply[3] == '-')
|
||||
{
|
||||
/* Multi-line response */
|
||||
|
||||
strncpy(tmp, session->reply, 3);
|
||||
do
|
||||
{
|
||||
if (ftpc_gets(session) == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nvdbg("Reply: %s\n", session->reply);
|
||||
}
|
||||
while (strncmp(tmp, session->reply, 4) != 0);
|
||||
}
|
||||
|
||||
wd_cancel(session->wdog);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_help.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_help
|
||||
*
|
||||
* Description:
|
||||
* Request a list of available help commands. This implementation is
|
||||
* fragementary and no ready for any real use at this time.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_help(SESSION handle, FAR const char *arg)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret;
|
||||
|
||||
/* Send the HELP command with or without an argument */
|
||||
|
||||
if (arg)
|
||||
{
|
||||
ret = ftpc_cmd(session, "HELP %s", arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ftpc_cmd(session, "HELP");
|
||||
}
|
||||
|
||||
/* Logic is missing here to return the help string to the caller. The caller
|
||||
* needs to call ftpc_getreply.
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_idle.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_idle
|
||||
*
|
||||
* Description:
|
||||
* This command will change the FTP server's idle time limit with the site
|
||||
* idle ftp command. This is useful if the default time limit is too short
|
||||
* for the transmission of files).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_idle(SESSION handle, unsigned int idletime)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
/* Check if the server supports the SITE IDLE command */
|
||||
|
||||
if (!FTPC_HAS_IDLE(session))
|
||||
{
|
||||
ndbg("Server does not support SITE IDLE\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Did the caller provide an IDLE time? Or is this just a query for the
|
||||
* current IDLE time setting?
|
||||
*/
|
||||
|
||||
if (idletime)
|
||||
{
|
||||
ret = ftpc_cmd(session, "SITE IDLE %u", idletime);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ftpc_cmd(session, "SITE IDLE");
|
||||
}
|
||||
|
||||
/* Check for "502 Command not implemented" or 500 "Unknown SITE command" */
|
||||
|
||||
if (session->code == 500 || session->code == 502)
|
||||
{
|
||||
/* Server does not support SITE IDLE */
|
||||
|
||||
ndbg("Server does not support SITE IDLE\n");
|
||||
FTPC_CLR_IDLE(session);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_internal.h
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_NETUTILS_FTPC_FTPC_INTERNAL_H
|
||||
#define __APPS_NETUTILS_FTPC_FTPC_INTERNAL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <wdog.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* MISC definitions *********************************************************/
|
||||
|
||||
#define ISO_nl 0x0a
|
||||
#define ISO_cr 0x0d
|
||||
|
||||
/* Telnet-related definitions */
|
||||
|
||||
#define TELNET_DM 242
|
||||
#define TELNET_IP 244
|
||||
#define TELNET_IAC 255
|
||||
#define TELNET_WILL 251
|
||||
#define TELNET_WONT 252
|
||||
#define TELNET_DO 253
|
||||
#define TELNET_DONT 254
|
||||
|
||||
/* Session flag bits ********************************************************/
|
||||
|
||||
#define FTPC_FLAG_PASSIVE (1 << 0) /* Passive mode requested */
|
||||
#define FTPC_SESSION_FLAGS (0x0001) /* Persist throughout the session */
|
||||
|
||||
#define FTPC_FLAG_CONNECTED (1 << 1) /* Connected to host */
|
||||
#define FTPC_FLAG_LOGGEDIN (1 << 2) /* Logged in to host */
|
||||
#define FTPC_STATE_FLAGS (0x0006) /* State of connection */
|
||||
|
||||
#define FTPC_FLAG_MDTM (1 << 3) /* Host supports MDTM command */
|
||||
#define FTPC_FLAG_SIZE (1 << 4) /* Host supports SIZE command */
|
||||
#define FTPC_FLAG_PASV (1 << 5) /* Host supports PASV command */
|
||||
#define FTPC_FLAG_STOU (1 << 6) /* Host supports STOU command */
|
||||
#define FTPC_FLAG_CHMOD (1 << 7) /* Host supports SITE CHMOD command */
|
||||
#define FTPC_FLAG_IDLE (1 << 8) /* Host supports SITE IDLE command */
|
||||
#define FTPC_HOSTCAP_FLAGS (0x01f8) /* Host capabilities */
|
||||
|
||||
#define FTPC_FLAG_INTERRUPT (1 << 9) /* Transfer interrupted */
|
||||
#define FTPC_FLAG_PUT (1 << 10) /* Transfer is a PUT operation (upload) */
|
||||
#define FTPC_XFER_FLAGS (0x0600) /* Transfer related */
|
||||
|
||||
/* These are the bits to be set/cleared when the flags are reset */
|
||||
|
||||
#define FTPC_FLAGS_CLEAR (FTPC_STATE_FLAGS | FTPC_XFER_FLAGS)
|
||||
#define FTPC_FLAGS_SET FTPC_HOSTCAP_FLAGS
|
||||
|
||||
/* Macros to set bits */
|
||||
|
||||
#define FTPC_SET_CONNECTED(s) do { (s)->flags |= FTPC_FLAG_CONNECTED; } while (0)
|
||||
#define FTPC_SET_LOGGEDIN(s) do { (s)->flags |= FTPC_FLAG_LOGGEDIN; } while (0)
|
||||
#define FTPC_SET_MDTM(s) do { (s)->flags |= FTPC_FLAG_MDTM; } while (0)
|
||||
#define FTPC_SET_SIZE(s) do { (s)->flags |= FTPC_FLAG_SIZE; } while (0)
|
||||
#define FTPC_SET_PASV(s) do { (s)->flags |= FTPC_FLAG_PASV; } while (0)
|
||||
#define FTPC_SET_STOU(s) do { (s)->flags |= FTPC_FLAG_STOU; } while (0)
|
||||
#define FTPC_SET_CHMOD(s) do { (s)->flags |= FTPC_FLAG_CHMOD; } while (0)
|
||||
#define FTPC_SET_IDLE(s) do { (s)->flags |= FTPC_FLAG_IDLE; } while (0)
|
||||
#define FTPC_SET_INTERRUPT(s) do { (s)->flags |= FTPC_FLAG_INTERRUPT; } while (0)
|
||||
#define FTPC_SET_PUT(s) do { (s)->flags |= FTPC_FLAG_PUT; } while (0)
|
||||
#define FTPC_SET_PASSIVE(s) do { (s)->flags |= FTPC_FLAG_PASSIVE; } while (0)
|
||||
|
||||
/* Macros to clear bits */
|
||||
|
||||
#define FTPC_CLR_CONNECTED(s) do { (s)->flags &= ~FTPC_FLAG_CONNECTED; } while (0)
|
||||
#define FTPC_CLR_LOGGEDIN(s) do { (s)->flags &= ~FTPC_FLAG_LOGGEDIN; } while (0)
|
||||
#define FTPC_CLR_MDTM(s) do { (s)->flags &= ~FTPC_FLAG_MDTM; } while (0)
|
||||
#define FTPC_CLR_SIZE(s) do { (s)->flags &= ~FTPC_FLAG_SIZE; } while (0)
|
||||
#define FTPC_CLR_PASV(s) do { (s)->flags &= ~FTPC_FLAG_PASV; } while (0)
|
||||
#define FTPC_CLR_STOU(s) do { (s)->flags &= ~FTPC_FLAG_STOU; } while (0)
|
||||
#define FTPC_CLR_CHMOD(s) do { (s)->flags &= ~FTPC_FLAG_CHMOD; } while (0)
|
||||
#define FTPC_CLR_IDLE(s) do { (s)->flags &= ~FTPC_FLAG_IDLE; } while (0)
|
||||
#define FTPC_CLR_INTERRUPT(s) do { (s)->flags &= ~FTPC_FLAG_INTERRUPT; } while (0)
|
||||
#define FTPC_CLR_PUT(s) do { (s)->flags &= ~FTPC_FLAG_PUT; } while (0)
|
||||
#define FTPC_CLR_PASSIVE(s) do { (s)->flags &= ~FTPC_FLAG_PASSIVE; } while (0)
|
||||
|
||||
/* Macros to test bits */
|
||||
|
||||
#define FTPC_IS_CONNECTED(s) (((s)->flags & FTPC_FLAG_CONNECTED) != 0)
|
||||
#define FTPC_IS_LOGGEDIN(s) (((s)->flags & FTPC_FLAG_LOGGEDIN) != 0)
|
||||
#define FTPC_HAS_MDTM(s) (((s)->flags & FTPC_FLAG_MDTM) != 0)
|
||||
#define FTPC_HAS_SIZE(s) (((s)->flags & FTPC_FLAG_SIZE) != 0)
|
||||
#define FTPC_HAS_PASV(s) (((s)->flags & FTPC_FLAG_PASV) != 0)
|
||||
#define FTPC_HAS_STOU(s) (((s)->flags & FTPC_FLAG_STOU) != 0)
|
||||
#define FTPC_HAS_CHMOD(s) (((s)->flags & FTPC_FLAG_CHMOD) != 0)
|
||||
#define FTPC_HAS_IDLE(s) (((s)->flags & FTPC_FLAG_IDLE) != 0)
|
||||
#define FTPC_INTERRUPTED(s) (((s)->flags & FTPC_FLAG_INTERRUPT) != 0)
|
||||
#define FTPC_IS_PUT(s) (((s)->flags & FTPC_FLAG_PUT) != 0)
|
||||
#define FTPC_IS_PASSIVE(s) (((s)->flags & FTPC_FLAG_PASSIVE) != 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure represents the state of one socket connection */
|
||||
|
||||
struct ftpc_socket_s
|
||||
{
|
||||
int sd; /* Socket descriptor */
|
||||
FILE *instream; /* Incoming stream */
|
||||
FILE *outstream; /* Outgoing stream */
|
||||
struct sockaddr_in laddr; /* Local address */
|
||||
bool connected; /* True: socket is connected */
|
||||
};
|
||||
|
||||
/* This structure represents the state of an FTP connection */
|
||||
|
||||
struct ftpc_session_s
|
||||
{
|
||||
struct in_addr addr; /* Server/proxy IP address */
|
||||
struct ftpc_socket_s cmd; /* FTP command channel */
|
||||
struct ftpc_socket_s data; /* FTP data channel */
|
||||
WDOG_ID wdog; /* Timer */
|
||||
FAR char *uname; /* Login uname */
|
||||
FAR char *pwd; /* Login pwd */
|
||||
FAR char *initrdir; /* Initial remote directory */
|
||||
FAR char *homerdir; /* Remote home directory (currdir on startup) */
|
||||
FAR char *currdir; /* Remote current directory */
|
||||
FAR char *homeldir; /* Local home directory (PWD on startup) */
|
||||
pid_t pid; /* Task ID of FTP client */
|
||||
uint8_t xfrmode; /* Previous data transfer type (See FTPC_XFRMODE_* defines) */
|
||||
uint16_t port; /* Server/proxy port number (probably 21) */
|
||||
uint16_t flags; /* Connection flags (see FTPC_FLAGS_* defines) */
|
||||
uint16_t code; /* Last 3-digit reply code */
|
||||
uint32_t replytimeo; /* Server reply timeout (ticks) */
|
||||
uint32_t conntimeo; /* Connection timeout (ticks) */
|
||||
off_t offset; /* Transfer file offset */
|
||||
off_t size; /* Number of bytes transferred */
|
||||
|
||||
char reply[CONFIG_FTP_MAXREPLY+1]; /* Last reply string from server */
|
||||
char buffer[CONFIG_FTP_BUFSIZE]; /* Used to buffer file data during transfers */
|
||||
};
|
||||
|
||||
/* There is not yet any want to change the local working directly (an lcd
|
||||
* command), but the following definition is provided to reserve the name
|
||||
* for the storage location for the local current working directory.
|
||||
*/
|
||||
|
||||
#define curldir homeldir
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions/Function-like Macros
|
||||
****************************************************************************/
|
||||
|
||||
#define ftpc_sockconnected(s) \
|
||||
((s) && (s)->connected)
|
||||
#define ftpc_connected(s) \
|
||||
(FTPC_IS_CONNECTED(session) && ftpc_sockconnected(&session->cmd))
|
||||
#define ftpc_loggedin(s) \
|
||||
(ftpc_connected(s) && FTPC_IS_LOGGEDIN(s))
|
||||
|
||||
#define ftpc_sockgetc(s) \
|
||||
fgetc((s)->instream)
|
||||
#define ftpc_sockflush(s) \
|
||||
fflush((s)->outstream)
|
||||
#define ftpc_sockvprintf(s,f,ap) \
|
||||
vfprintf((s)->outstream,f,ap)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
/* Low-level string management */
|
||||
|
||||
EXTERN void ftpc_stripcrlf(FAR char *str);
|
||||
EXTERN void ftpc_stripslash(FAR char *str);
|
||||
EXTERN FAR char *ftpc_dequote(FAR const char *hostname);
|
||||
|
||||
/* Connection helpers */
|
||||
|
||||
EXTERN int ftpc_reconnect(FAR struct ftpc_session_s *session);
|
||||
EXTERN int ftpc_relogin(FAR struct ftpc_session_s *session);
|
||||
|
||||
/* FTP helpers */
|
||||
|
||||
EXTERN void ftpc_reset(struct ftpc_session_s *session);
|
||||
EXTERN int ftpc_cmd(struct ftpc_session_s *session, const char *cmd, ...);
|
||||
EXTERN int fptc_getreply(struct ftpc_session_s *session);
|
||||
EXTERN FAR const char *ftpc_lpwd(void);
|
||||
EXTERN int ftpc_xfrmode(struct ftpc_session_s *session, uint8_t xfrmode);
|
||||
EXTERN FAR char *ftpc_absrpath(FAR struct ftpc_session_s *session,
|
||||
FAR const char *relpath);
|
||||
EXTERN FAR char *ftpc_abslpath(FAR struct ftpc_session_s *session,
|
||||
FAR const char *relpath);
|
||||
|
||||
/* Socket helpers */
|
||||
|
||||
EXTERN int ftpc_sockinit(FAR struct ftpc_socket_s *sock);
|
||||
EXTERN void ftpc_sockclose(FAR struct ftpc_socket_s *sock);
|
||||
EXTERN int ftpc_sockconnect(FAR struct ftpc_socket_s *sock,
|
||||
FAR struct sockaddr_in *addr);
|
||||
EXTERN int ftpc_sockgetsockname(FAR struct ftpc_socket_s *sock,
|
||||
FAR struct sockaddr_in *sa);
|
||||
EXTERN int ftpc_sockaccept(FAR struct ftpc_socket_s *sock);
|
||||
EXTERN int ftpc_socklisten(FAR struct ftpc_socket_s *sock);
|
||||
EXTERN void ftpc_sockcopy(FAR struct ftpc_socket_s *dest,
|
||||
FAR const struct ftpc_socket_s *src);
|
||||
|
||||
/* Socket I/O helpers */
|
||||
|
||||
EXTERN int ftpc_sockprintf(FAR struct ftpc_socket_s *sock, const char *fmt, ...);
|
||||
EXTERN void ftpc_timeout(int argc, uint32_t arg1, ...);
|
||||
|
||||
/* Transfer helpers */
|
||||
|
||||
EXTERN int ftpc_xfrinit(FAR struct ftpc_session_s *session);
|
||||
EXTERN int ftpc_recvtext(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *rinstream, FAR FILE *loutstream);
|
||||
EXTERN int ftpc_waitdata(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *stream, bool rdwait);
|
||||
|
||||
EXTERN void ftpc_xfrreset(struct ftpc_session_s *session);
|
||||
EXTERN int ftpc_xfrabort(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *stream);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __APPS_NETUTILS_FTPC_FTPC_INTERNAL_H */
|
||||
@@ -0,0 +1,412 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_listdir.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef void (*callback_t)(FAR const char *name, FAR void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_dircount
|
||||
*
|
||||
* Description:
|
||||
* This callback simply counts the number of names in the directory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ftpc_dircount(FAR const char *name, FAR void *arg)
|
||||
{
|
||||
FAR unsigned int *dircount = (FAR unsigned int *)arg;
|
||||
(*dircount)++;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_addname
|
||||
*
|
||||
* Description:
|
||||
* This callback adds a name to the directory listing.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ftpc_addname(FAR const char *name, FAR void *arg)
|
||||
{
|
||||
FAR struct ftpc_dirlist_s *dirlist = (FAR struct ftpc_dirlist_s *)arg;
|
||||
unsigned int nnames = dirlist->nnames;
|
||||
dirlist->name[nnames] = strdup(name);
|
||||
dirlist->nnames = nnames + 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_nlstparse
|
||||
*
|
||||
* Description:
|
||||
* Parse the NLST directory response. The NLST response consists of a
|
||||
* sequence of pathnames. Each pathname is terminated by \r\n.
|
||||
*
|
||||
* If a pathname starts with a slash, it represents the pathname. If a
|
||||
* pathname does not start with a slash, it represents the pathname obtained
|
||||
* by concatenating the pathname of the directory and the pathname.
|
||||
*
|
||||
* IF NLST of directory /pub produces foo\r\nbar\r\n, it refers to the
|
||||
* pathnames /pub/foo and /pub/bar.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ftpc_nlstparse(FAR FILE *instream, callback_t callback,
|
||||
FAR void *arg)
|
||||
{
|
||||
char buffer[CONFIG_FTP_MAXPATH+1];
|
||||
|
||||
/* Read every filename from the temporary file */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Read the next line from the file */
|
||||
|
||||
if (!fgets(buffer, CONFIG_FTP_MAXPATH, instream))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Remove any trailing CR-LF from the line */
|
||||
|
||||
ftpc_stripcrlf(buffer);
|
||||
|
||||
/* Check for empty file names */
|
||||
|
||||
if (buffer[0] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
nvdbg("File: %s\n", buffer);
|
||||
|
||||
/* Perform the callback operation */
|
||||
|
||||
callback(buffer, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_recvdir
|
||||
*
|
||||
* Description:
|
||||
* Get the directory listing.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_recvdir(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *outstream)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Verify that we are still connected to the server */
|
||||
|
||||
if (!ftpc_connected(session))
|
||||
{
|
||||
ndbg("Not connected to server\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Setup for the transfer */
|
||||
|
||||
ftpc_xfrreset(session);
|
||||
ret = ftpc_xfrinit(session);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Send the "NLST" command. Normally the server responds with a mark
|
||||
* using code 150:
|
||||
*
|
||||
* - "150 File status okay; about to open data connection"
|
||||
*
|
||||
* It then stops accepting new connections, attempts to
|
||||
* send the contents of the directory over the data connection, and
|
||||
* closes the data connection.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "NLST");
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* In active mode, we need to accept a connection on the data socket
|
||||
* (in passive mode, we have already connected the data channel to
|
||||
* the FTP server).
|
||||
*/
|
||||
|
||||
if (!FTPC_IS_PASSIVE(session))
|
||||
{
|
||||
ret = ftpc_sockaccept(&session->data);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_sockaccept() failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive the NLST directory list */
|
||||
|
||||
ret = ftpc_recvtext(session, session->data.instream, outstream);
|
||||
ftpc_sockclose(&session->data);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the server reply. After closing the data connection, the should
|
||||
* accept the request with:
|
||||
*
|
||||
* - "226 Closing data connection" if the entire directory was
|
||||
* successfully transmitted;
|
||||
*
|
||||
* Or reject it with:
|
||||
*
|
||||
* - "425 Can't open data connection" if no TCP connection was established
|
||||
* - "426 - Connection closed; transfer aborted" if the TCP connection was
|
||||
* established but then broken by the client or by network failure
|
||||
* - "451 - Requested action aborted: local error in processing" if the
|
||||
* server had trouble reading the directory from disk.
|
||||
*
|
||||
* The server may reject the LIST or NLST request (with code 450 or 550)
|
||||
* without first responding with a mark. In this case the server does not
|
||||
* touch the data connection.
|
||||
*/
|
||||
|
||||
fptc_getreply(session);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_listdir
|
||||
*
|
||||
* Description:
|
||||
* Get a simple directory listing using NLST:
|
||||
*
|
||||
* NLST [<SP> <pathname>] <CRLF>
|
||||
*
|
||||
* We could do much, much more here using the LIST or MLST/MLSD commands,
|
||||
* but the parsing is a bitch. See http://cr.yp.to/ftpparse.html
|
||||
*
|
||||
* NOTE: We expect to receive only well structured directory paths. Tilde
|
||||
* expansion "~/xyz" and relative pathes (abc/def) because we do have
|
||||
* special knowledge about the home and current directories. But otherwise
|
||||
* the pathes are expected to be pre-sanitized: No . or .. in paths,
|
||||
* no '//' in paths, etc.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle,
|
||||
FAR const char *dirpath)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
struct ftpc_dirlist_s *dirlist;
|
||||
FILE *filestream;
|
||||
FAR char *absrpath;
|
||||
FAR char *tmpfname;
|
||||
bool iscurrdir;
|
||||
unsigned int nnames;
|
||||
int allocsize;
|
||||
int ret;
|
||||
|
||||
/* Get the absolute path to the directory */
|
||||
|
||||
absrpath = ftpc_absrpath(session, dirpath);
|
||||
ftpc_stripslash(absrpath);
|
||||
|
||||
/* Is the directory also the remote current working directory? */
|
||||
|
||||
iscurrdir = (strcmp(absrpath, session->currdir) == 0);
|
||||
|
||||
/* Create a temporary file to hold the directory listing */
|
||||
|
||||
asprintf(&tmpfname, "%s/TMP%d.dat", CONFIG_FTP_TMPDIR, getpid());
|
||||
filestream = fopen(tmpfname, "w+");
|
||||
if (!filestream)
|
||||
{
|
||||
ndbg("Failed to create %s: %d\n", tmpfname, errno);
|
||||
free(absrpath);
|
||||
free(tmpfname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* "CWD" first so that we get the directory contents, not the
|
||||
* directory itself.
|
||||
*/
|
||||
|
||||
if (!iscurrdir)
|
||||
{
|
||||
ret = ftpc_cmd(session, "CWD %s", absrpath);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("CWD to %s failed\n", absrpath);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the NLST command with no arguments to get the entire contents of
|
||||
* the directory.
|
||||
*/
|
||||
|
||||
ret = ftpc_recvdir(session, filestream);
|
||||
|
||||
/* Go back to the correct current working directory */
|
||||
|
||||
if (!iscurrdir)
|
||||
{
|
||||
int tmpret = ftpc_cmd(session, "CWD %s", session->currdir);
|
||||
if (tmpret != OK)
|
||||
{
|
||||
ndbg("CWD back to to %s failed\n", session->currdir);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we successfully receive the directory listing? */
|
||||
|
||||
dirlist = NULL;
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Count the number of names in the temporary file */
|
||||
|
||||
rewind(filestream);
|
||||
nnames = 0;
|
||||
|
||||
ftpc_nlstparse(filestream, ftpc_dircount, &nnames);
|
||||
if (!nnames)
|
||||
{
|
||||
ndbg("Nothing found in directory\n");
|
||||
goto errout;
|
||||
}
|
||||
nvdbg("nnames: %d\n", nnames);
|
||||
|
||||
/* Allocate and initialize a directory container */
|
||||
|
||||
allocsize = SIZEOF_FTPC_DIRLIST(nnames);
|
||||
dirlist = (struct ftpc_dirlist_s *)malloc(allocsize);
|
||||
if (!dirlist)
|
||||
{
|
||||
ndbg("Failed to allocate dirlist\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Then copy all of the directory strings into the container */
|
||||
|
||||
rewind(filestream);
|
||||
dirlist->nnames = 0;
|
||||
|
||||
ftpc_nlstparse(filestream, ftpc_addname, dirlist);
|
||||
DEBUGASSERT(nnames == dirlist->nnames);
|
||||
}
|
||||
|
||||
errout:
|
||||
fclose(filestream);
|
||||
free(absrpath);
|
||||
unlink(tmpfname);
|
||||
free(tmpfname);
|
||||
return dirlist;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_dirfree
|
||||
*
|
||||
* Description:
|
||||
* Release the allocated directory listing.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_dirfree(FAR struct ftpc_dirlist_s *dirlist)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dirlist)
|
||||
{
|
||||
/* Free each directory name in the directory container */
|
||||
|
||||
for (i = 0; i < dirlist->nnames; i++)
|
||||
{
|
||||
/* NULL means that the caller stole the string */
|
||||
|
||||
if (dirlist->name[i])
|
||||
{
|
||||
free(dirlist->name[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Then free the container itself */
|
||||
|
||||
free(dirlist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_login.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_login
|
||||
*
|
||||
* Description:
|
||||
* Log into the server
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_login(SESSION handle, FAR struct ftpc_login_s *login)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
/* Verify that we are connected to a server */
|
||||
|
||||
if (!ftpc_connected(session))
|
||||
{
|
||||
ndbg("Not connected\n");
|
||||
err = ENOTCONN;
|
||||
goto errout_with_err;
|
||||
}
|
||||
|
||||
/* Verify that we are not already logged in to the server */
|
||||
|
||||
if (ftpc_loggedin(session))
|
||||
{
|
||||
ndbg("Already logged in\n");
|
||||
err = EINVAL;
|
||||
goto errout_with_err;
|
||||
}
|
||||
|
||||
/* Save the login parameter */
|
||||
|
||||
session->uname = ftpc_dequote(login->uname);
|
||||
session->pwd = ftpc_dequote(login->pwd);
|
||||
session->initrdir = ftpc_dequote(login->rdir);
|
||||
|
||||
/* Is passive mode requested? */
|
||||
|
||||
FTPC_CLR_PASSIVE(session);
|
||||
if (login->pasv)
|
||||
{
|
||||
nvdbg("Setting passive mode\n");
|
||||
FTPC_SET_PASSIVE(session);
|
||||
}
|
||||
|
||||
/* The (Re-)login to the server */
|
||||
|
||||
ret = ftpc_relogin(session);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("login failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_err:
|
||||
set_errno(err);
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_relogin
|
||||
*
|
||||
* Description:
|
||||
* Log in again after a loss of connection
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_relogin(FAR struct ftpc_session_s *session)
|
||||
{
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
/* Log into the server. First send the USER command. The server may accept
|
||||
* USER with:
|
||||
*
|
||||
* - "230 User logged in, proceed" meaning that the client has permission to
|
||||
* access files under that username
|
||||
* - "331 "User name okay, need password" or "332 Need account for login"
|
||||
* meaning that permission might be granted after a PASS request.
|
||||
*
|
||||
* Or the server may reject USER with:
|
||||
*
|
||||
* - "530 Not logged in" meaning that the username is unacceptable.
|
||||
*
|
||||
* In practice, the server does not check the username until after a PASS
|
||||
* request
|
||||
*/
|
||||
|
||||
FTPC_CLR_LOGGEDIN(session);
|
||||
ret = ftpc_cmd(session, "USER %s", session->uname);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("USER %s cmd failed: %d\n", session->uname, errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Send the PASS command with the passed. The server may accept PASS with:
|
||||
*
|
||||
* - "230 User logged in, proceed" meaning that the client has permission to
|
||||
* access files under that username
|
||||
* - "202 Command not implemented, superfluous at this site" meaning that
|
||||
* permission was already granted in response to USER
|
||||
* - "332 Need account for login" meaning that permission might be granted
|
||||
* after an ACCT request.
|
||||
*
|
||||
* The server may reject PASS with:
|
||||
*
|
||||
* - "503 Bad sequence of commands" if the previous request was not USER
|
||||
* - "530 - Not logged in" if this username and password are unacceptable.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "PASS %s", session->pwd);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("PASS %s cmd failed: %d\n", session->pwd, errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We are logged in.. the current working directory on login is our "home"
|
||||
* directory.
|
||||
*/
|
||||
|
||||
FTPC_SET_LOGGEDIN(session);
|
||||
session->homerdir = ftpc_rpwd((SESSION)session);
|
||||
session->currdir = strdup(session->homerdir);
|
||||
|
||||
/* If the user has requested a special start up directory, then change to
|
||||
* that directory now.
|
||||
*/
|
||||
|
||||
if (session->initrdir)
|
||||
{
|
||||
ftpc_chdir((SESSION)session, session->initrdir);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_mkdir.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_mkdir
|
||||
*
|
||||
* Description:
|
||||
* Creates the named directory on the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_mkdir(SESSION handle, FAR const char *path)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
char *ptr;
|
||||
int ret;
|
||||
|
||||
ptr = strdup(path);
|
||||
ftpc_stripslash(ptr);
|
||||
|
||||
/* Send the MKD request. The MKD request asks the server to create a new
|
||||
* directory. The server accepts the MKD with either:
|
||||
*
|
||||
* - "257 PATHNAME created" that includes the pathname of the directory
|
||||
* - "250 - Requested file action okay, completed" if the directory was
|
||||
* successfully created.
|
||||
*
|
||||
* The server reject MKD with:
|
||||
*
|
||||
* - "550 Requested action not taken" if the creation failed.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "MKD %s", ptr);
|
||||
free(ptr);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_noop.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_noop
|
||||
*
|
||||
* Description:
|
||||
* No operation command. Using NOOP allows us to make sure that commands
|
||||
* are passed over the control connection without changing the status of
|
||||
* any data transaction or server status. This is useful for (1)
|
||||
* maintaining connections during long IDLE times and (2) It can also be
|
||||
* used as a harmless way of detecting timeouts.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_noop(SESSION handle)
|
||||
{
|
||||
return ftpc_cmd((FAR struct ftpc_session_s *)handle, "NOOP");
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_putfile.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sendbinary
|
||||
*
|
||||
* Description:
|
||||
* Send a binary file to the remote host.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *linstream, FILE *routstream)
|
||||
{
|
||||
ssize_t nread;
|
||||
ssize_t nwritten;
|
||||
|
||||
/* Loop until the entire file is sent */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Read data from the file */
|
||||
|
||||
nread = fread(session->buffer, sizeof(char), CONFIG_FTP_BUFSIZE, linstream);
|
||||
if (nread <= 0)
|
||||
{
|
||||
/* nread == 0 is just EOF */
|
||||
|
||||
if (nread < 0)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, linstream);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Send the data */
|
||||
|
||||
nwritten = fwrite(session->buffer, sizeof(char), nread, routstream);
|
||||
if (nwritten != nread)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, routstream);
|
||||
|
||||
/* Return failue */
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Increment the size of the file sent */
|
||||
|
||||
session->size += nread;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sendtext
|
||||
*
|
||||
* Description:
|
||||
* Send a text file to the remote host.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_sendtext(FAR struct ftpc_session_s *session,
|
||||
FAR FILE *linstream, FAR FILE *routstream)
|
||||
{
|
||||
int ch;
|
||||
int ret = OK;
|
||||
|
||||
/* Write characters one at a time. */
|
||||
|
||||
while ((ch = fgetc(linstream)) != EOF)
|
||||
{
|
||||
/* If it is a newline, send a carriage return too */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
if (fputc('\r', routstream) == EOF)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, routstream);
|
||||
ret = ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment the size of the file sent */
|
||||
|
||||
session->size++;
|
||||
}
|
||||
|
||||
/* Send the character */
|
||||
|
||||
if (fputc(ch, routstream) == EOF)
|
||||
{
|
||||
(void)ftpc_xfrabort(session, routstream);
|
||||
ret = ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment the size of the file sent */
|
||||
|
||||
session->size++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sendfile
|
||||
*
|
||||
* Description:
|
||||
* Send the file to the remote host.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
|
||||
FILE *stream, uint8_t how, uint8_t xfrmode)
|
||||
{
|
||||
long offset = session->offset;
|
||||
#ifdef CONFIG_DEBUG
|
||||
FAR char *rname;
|
||||
FAR char *str;
|
||||
int len;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
session->offset = 0;
|
||||
|
||||
/* Were we asked to store a file uniquely? Does the host support the STOU
|
||||
* command?
|
||||
*/
|
||||
|
||||
if (how == FTPC_PUT_UNIQUE && !FTPC_HAS_STOU(session))
|
||||
{
|
||||
/* We cannot store a file uniquely */
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ftpc_xfrreset(session);
|
||||
FTPC_SET_PUT(session);
|
||||
|
||||
/* Initialize for the transfer */
|
||||
|
||||
ret = ftpc_xfrinit(session);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ftpc_xfrmode(session, xfrmode);
|
||||
|
||||
/* The REST command sets the start position in the file. Some servers
|
||||
* allow REST immediately before STOR for binary files.
|
||||
*/
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
ret = ftpc_cmd(session, "REST %ld", offset);
|
||||
session->size = offset;
|
||||
}
|
||||
|
||||
/* Send the file using STOR, STOU, or APPE:
|
||||
*
|
||||
* - STOR request asks the server to receive the contents of a file from
|
||||
* the data connection already established by the client.
|
||||
* - APPE is just like STOR except that, if the file already exists, the
|
||||
* server appends the client's data to the file.
|
||||
* - STOU is just like STOR except that it asks the server to create a
|
||||
* file under a new pathname selected by the server. If the server
|
||||
* accepts STOU, it provides the pathname in a human-readable format in
|
||||
* the text of its response.
|
||||
*/
|
||||
|
||||
switch (how)
|
||||
{
|
||||
case FTPC_PUT_UNIQUE:
|
||||
{
|
||||
ret = ftpc_cmd(session, "STOU %s", path);
|
||||
|
||||
/* Check for "502 Command not implemented" */
|
||||
|
||||
if (session->code == 502)
|
||||
{
|
||||
/* The host does not support the STOU command */
|
||||
|
||||
FTPC_CLR_STOU(session);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the remote filename from the response */
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
str = strstr(session->reply, " for ");
|
||||
if (str)
|
||||
{
|
||||
str += 5;
|
||||
len = strlen(str);
|
||||
if (len)
|
||||
{
|
||||
if (*str == '\'')
|
||||
{
|
||||
rname = strndup(str+1, len-3);
|
||||
}
|
||||
else
|
||||
{
|
||||
rname = strndup(str, len-1);
|
||||
nvdbg("Unique filename is: %s\n", rname);
|
||||
}
|
||||
free(rname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case FTPC_PUT_APPEND:
|
||||
ret = ftpc_cmd(session, "APPE %s", path);
|
||||
break;
|
||||
|
||||
case FTPC_PUT_NORMAL:
|
||||
default:
|
||||
ret = ftpc_cmd(session, "STOR %s", path);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the server is willing to create a new file under that name, or
|
||||
* replace an existing file under that name, it responds with a mark
|
||||
* using code 150:
|
||||
*
|
||||
* - "150 File status okay; about to open data connection"
|
||||
*
|
||||
* It then attempts to read the contents of the file from the data
|
||||
* connection, and closes the data connection. Finally it accepts the STOR
|
||||
* with:
|
||||
*
|
||||
* - "226 Closing data connection" if the entire file was successfully
|
||||
* received and stored
|
||||
*
|
||||
* Or rejects the STOR with:
|
||||
*
|
||||
* - "425 Can't open data connection" if no TCP connection was established
|
||||
* - "426 Connection closed; transfer aborted" if the TCP connection was
|
||||
* established but then broken by the client or by network failure
|
||||
* - "451 Requested action aborted: local error in processing",
|
||||
* "452 - Requested action not taken", or "552 Requested file action
|
||||
* aborted" if the server had trouble saving the file to disk.
|
||||
*
|
||||
* The server may reject the STOR request with:
|
||||
*
|
||||
* - "450 Requested file action not taken", "452 - Requested action not
|
||||
* taken" or "553 Requested action not taken" without first responding
|
||||
* with a mark.
|
||||
*/
|
||||
|
||||
/* In active mode, we need to accept a connection on the data socket
|
||||
* (in passive mode, we have already connected the data channel to
|
||||
* the FTP server).
|
||||
*/
|
||||
|
||||
if (!FTPC_IS_PASSIVE(session))
|
||||
{
|
||||
ret = ftpc_sockaccept(&session->data);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("Data connection not accepted\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then perform the data transfer */
|
||||
|
||||
if (xfrmode == FTPC_XFRMODE_ASCII)
|
||||
{
|
||||
ret = ftpc_sendtext(session, stream, session->data.outstream);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ftpc_sendbinary(session, stream, session->data.outstream);
|
||||
}
|
||||
|
||||
ftpc_sockflush(&session->data);
|
||||
ftpc_sockclose(&session->data);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
fptc_getreply(session);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_putfile
|
||||
*
|
||||
* Description:
|
||||
* Put a file on the remote host.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftp_putfile(SESSION handle, const char *lname, const char *rname,
|
||||
uint8_t how, uint8_t xfrmode)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
FAR char *abslpath;
|
||||
struct stat statbuf;
|
||||
FILE *finstream;
|
||||
int ret;
|
||||
|
||||
/* Don't call this with a NULL local file name */
|
||||
|
||||
DEBUGASSERT(lname);
|
||||
|
||||
/* If the remote name is not specified, then it is assumed to the same as
|
||||
* the local file name.
|
||||
*/
|
||||
|
||||
if (!rname)
|
||||
{
|
||||
rname = lname;
|
||||
}
|
||||
|
||||
/* Get the full path to the local file */
|
||||
|
||||
abslpath = ftpc_abslpath(session, lname);
|
||||
if (!abslpath)
|
||||
{
|
||||
ndbg("ftpc_abslpath(%s) failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Make sure that the local file exists */
|
||||
|
||||
ret = stat(abslpath, &statbuf);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("stat(%s) failed: %d\n", errno);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
|
||||
/* Make sure that the local name does not refer to a directory */
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
ndbg("%s is a directory\n", abslpath);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
|
||||
/* Open the local file for reading */
|
||||
|
||||
finstream = fopen(abslpath, "r");
|
||||
if (!finstream)
|
||||
{
|
||||
ndbg("fopen() failed: %d\n", errno);
|
||||
goto errout_with_abspath;
|
||||
}
|
||||
|
||||
/* Are we resuming a transfer? */
|
||||
|
||||
session->offset = 0;
|
||||
if (how == FTPC_PUT_RESUME)
|
||||
{
|
||||
/* Yes... Get the size of the file. This will only work if the
|
||||
* server supports the SIZE command.
|
||||
*/
|
||||
|
||||
session->offset = ftpc_filesize(session, rname);
|
||||
if (session->offset == (off_t)ERROR)
|
||||
{
|
||||
ndbg("Failed to get size of remote file: %s\n", rname);
|
||||
goto errout_with_instream;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Seek to the offset in the file corresponding to the size
|
||||
* that we have already sent.
|
||||
*/
|
||||
|
||||
ret = fseek(finstream, session->offset, SEEK_SET);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("fseek failed: %d\n", errno);
|
||||
goto errout_with_instream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the file */
|
||||
|
||||
ret = ftpc_sendfile(session, rname, finstream, how, xfrmode);
|
||||
if (ret == OK)
|
||||
{
|
||||
fclose(finstream);
|
||||
free(abslpath);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Various error exits */
|
||||
|
||||
errout_with_instream:
|
||||
fclose(finstream);
|
||||
errout_with_abspath:
|
||||
free(abslpath);
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_quit.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_quit
|
||||
*
|
||||
* Description:
|
||||
* Ends the FTP session with the remote computer and exits ftp
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_quit(SESSION handle)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
if (ftpc_connected(session))
|
||||
{
|
||||
session->replytimeo = 10 * CLOCKS_PER_SEC;
|
||||
ret = ftpc_cmd(session, "QUIT");
|
||||
}
|
||||
|
||||
ftpc_disconnect(handle);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_rename.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_rename
|
||||
*
|
||||
* Description:
|
||||
* Rename a file on the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_rename(SESSION handle, FAR const char *oldname, FAR const char *newname)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
char *oldcopy;
|
||||
char *newcopy;
|
||||
int ret;
|
||||
|
||||
oldcopy = strdup(oldname);
|
||||
ftpc_stripslash(oldcopy);
|
||||
|
||||
/* A RNFR request asks the server to begin renaming a file. A typical
|
||||
* server accepts RNFR with:
|
||||
*
|
||||
* - "350 Requested file action pending further information" if the file
|
||||
* exists
|
||||
*
|
||||
* Or rejects RNFR with:
|
||||
*
|
||||
* - "450 Requested file action not taken"
|
||||
* - "550 Requested action not taken"
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "RNFR %s", oldcopy);
|
||||
if (ret != OK)
|
||||
{
|
||||
free(oldcopy);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
newcopy = strdup(newname);
|
||||
ftpc_stripslash(newcopy);
|
||||
|
||||
/* A RNTO request asks the server to finish renaming a file. RNTO must
|
||||
* come immediately after RNFR; otherwise the server may reject RNTO with:
|
||||
*
|
||||
* - "503 Bad sequence of commands"
|
||||
*
|
||||
* A typical server accepts RNTO with:
|
||||
*
|
||||
* - "250 Requested file action okay, completed" if the file was renamed
|
||||
* successfully
|
||||
*
|
||||
* Or rejects RMD with:
|
||||
*
|
||||
* - "550 Requested action not taken"
|
||||
* - "553 Requested action not taken"
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "RNTO %s", newcopy);
|
||||
|
||||
free(oldcopy);
|
||||
free(newcopy);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_response.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_response
|
||||
*
|
||||
* Description:
|
||||
* Return the response string from the last command. This is allocated
|
||||
* memory that must be freed using free() when it is no longer needed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *ftpc_response(SESSION handle)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
return strndup(session->reply, CONFIG_FTP_MAXREPLY);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_rmdir.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_rmdir
|
||||
*
|
||||
* Description:
|
||||
* Deletes the named directory on the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
int ftpc_rmdir(SESSION handle, FAR const char *path)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
char *ptr;
|
||||
int ret;
|
||||
|
||||
ptr = strdup(path);
|
||||
ftpc_stripslash(ptr);
|
||||
|
||||
/* An RMD request asks the server to remove a directory. A typical server
|
||||
* accepts RMD with:
|
||||
*
|
||||
* - "250 Requested file action okay, completed" if the directory was
|
||||
* successfully removed
|
||||
*
|
||||
* Or rejects RMD with:
|
||||
*
|
||||
* - "550 Requested action not taken" if the removal failed.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "RMD %s", ptr);
|
||||
free(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_rpwd.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_rpwd
|
||||
*
|
||||
* Descripton:
|
||||
* Returns the current working directory on the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *ftpc_rpwd(SESSION handle)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
FAR char *start;
|
||||
FAR char *end;
|
||||
FAR char *pwd;
|
||||
FAR char *ptr;
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
/* Send the PWD command */
|
||||
|
||||
ret = ftpc_cmd(session, "PWD");
|
||||
|
||||
/* Response is like: 257 "/home/gnutt" (from vsftpd).
|
||||
*
|
||||
* Extract the quoated path name into allocated memory.
|
||||
*/
|
||||
|
||||
start = strchr(session->reply, '\"');
|
||||
if (!start)
|
||||
{
|
||||
ndbg("Opening quote not found\n");
|
||||
return NULL;
|
||||
}
|
||||
start++;
|
||||
|
||||
end = strchr(start, '\"');
|
||||
if (!end)
|
||||
{
|
||||
ndbg("Closing quote not found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for the path name:
|
||||
*
|
||||
* Reply: 257 "/home/gnutt"
|
||||
* ^start ^end
|
||||
*
|
||||
* len = end - start + 1 = 11 (+ NUL terminator)
|
||||
*/
|
||||
|
||||
len = end - start + 1;
|
||||
pwd = (char *)malloc(len + 1);
|
||||
if (!pwd)
|
||||
{
|
||||
ndbg("Failed to allocate string\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy the string into the allocated memory */
|
||||
|
||||
memcpy(pwd, start, len);
|
||||
pwd[len] = '\0';
|
||||
|
||||
/* Remove any trailing slashes that the server may have added */
|
||||
|
||||
ftpc_stripslash(pwd);
|
||||
|
||||
/* Change DOS style directory separator ('\') to UNIX style ('/') */
|
||||
|
||||
for (ptr = pwd; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '\\')
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
}
|
||||
return pwd;
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_socket.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockinit
|
||||
*
|
||||
* Description:
|
||||
* Initialize a socket. Create the socket and "wrap" it as C standard
|
||||
* incoming and outgoing streams.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_sockinit(FAR struct ftpc_socket_s *sock)
|
||||
{
|
||||
/* Initialize the socket structure */
|
||||
|
||||
memset(sock, 0, sizeof(struct ftpc_socket_s));
|
||||
|
||||
/* Create a socket descriptor */
|
||||
|
||||
sock->sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sock->sd < 0)
|
||||
{
|
||||
ndbg("socket() failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Call fdopen to "wrap" the socket descriptor as an input stream using C
|
||||
* buffered I/O.
|
||||
*/
|
||||
|
||||
sock->instream = fdopen(sock->sd, "r");
|
||||
if (!sock->instream)
|
||||
{
|
||||
ndbg("fdopen() failed: %d\n", errno);
|
||||
goto errout_with_sd;
|
||||
}
|
||||
|
||||
/* Call fdopen to "wrap" the socket descriptor as an output stream using C
|
||||
* buffered I/O.
|
||||
*/
|
||||
|
||||
sock->outstream = fdopen(sock->sd, "w");
|
||||
if (!sock->outstream)
|
||||
{
|
||||
ndbg("fdopen() failed: %d\n", errno);
|
||||
goto errout_with_instream;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
/* Close the instream. NOTE: Since the underlying socket descriptor is
|
||||
* *not* dup'ed, the following close should fail harmlessly.
|
||||
*/
|
||||
|
||||
errout_with_instream:
|
||||
fclose(sock->instream);
|
||||
sock->instream = NULL;
|
||||
errout_with_sd:
|
||||
close(sock->sd);
|
||||
sock->sd = -1;
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockclose
|
||||
*
|
||||
* Description:
|
||||
* Close a socket
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_sockclose(struct ftpc_socket_s *sock)
|
||||
{
|
||||
/* Note that the same underlying socket descriptor is used for both streams.
|
||||
* There should be harmless failures on the second fclose and the close.
|
||||
*/
|
||||
|
||||
fclose(sock->instream);
|
||||
fclose(sock->outstream);
|
||||
close(sock->sd);
|
||||
memset(sock, 0, sizeof(struct ftpc_socket_s));
|
||||
sock->sd = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockconnect
|
||||
*
|
||||
* Description:
|
||||
* Connect the socket to the host. On a failure, the caller should call.
|
||||
* ftpc_sockclose() to clean up.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Connect to the server */
|
||||
|
||||
ret = connect(sock->sd, (struct sockaddr *)addr, sizeof(struct sockaddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("connect() failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the local address of the socket */
|
||||
|
||||
ret = ftpc_sockgetsockname(sock, &sock->laddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("ftpc_sockgetsockname() failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
sock->connected = true;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockcopy
|
||||
*
|
||||
* Description:
|
||||
* Copy the socket state from one location to another.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_sockcopy(FAR struct ftpc_socket_s *dest,
|
||||
FAR const struct ftpc_socket_s *src)
|
||||
{
|
||||
memcpy(&dest->laddr, &src->laddr, sizeof(struct sockaddr_in));
|
||||
dest->connected = ftpc_sockconnected(src);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockaccept
|
||||
*
|
||||
* Description:
|
||||
* Accept a connection on the data socket. This function is onlly used
|
||||
* in active mode.
|
||||
*
|
||||
* In active mode FTP the client connects from a random port (N>1023) to the
|
||||
* FTP server's command port, port 21. Then, the client starts listening to
|
||||
* port N+1 and sends the FTP command PORT N+1 to the FTP server. The server
|
||||
* will then connect back to the client's specified data port from its local
|
||||
* data port, which is port 20. In passive mode FTP the client initiates
|
||||
* both connections to the server, solving the problem of firewalls filtering
|
||||
* the incoming data port connection to the client from the server. When
|
||||
* opening an FTP connection, the client opens two random ports locally
|
||||
* (N>1023 and N+1). The first port contacts the server on port 21, but
|
||||
* instead of then issuing a PORT command and allowing the server to connect
|
||||
* back to its data port, the client will issue the PASV command. The result
|
||||
* of this is that the server then opens a random unprivileged port (P >
|
||||
* 1023) and sends the PORT P command back to the client. The client then
|
||||
* initiates the connection from port N+1 to port P on the server to transfer
|
||||
* data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_sockaccept(FAR struct ftpc_socket_s *sock)
|
||||
{
|
||||
struct sockaddr addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
/* Any previous socket should have been uninitialized (0) or explicitly
|
||||
* closed (-1). But the path to this function may include a call to
|
||||
* ftpc_sockinit(). If so... close that socket and call accept to
|
||||
* get a new one.
|
||||
*/
|
||||
|
||||
if (sock->sd > 0)
|
||||
{
|
||||
ftpc_sockclose(sock);
|
||||
}
|
||||
|
||||
addrlen = sizeof(addr);
|
||||
sock->sd = accept(sock->sd, &addr, &addrlen);
|
||||
if (sock->sd == -1)
|
||||
{
|
||||
ndbg("accept() failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
memcpy(&sock->laddr, &addr, sizeof(sock->laddr));
|
||||
|
||||
/* Create in/out C buffer I/O streams on the data channel. First,
|
||||
* create the incoming buffered stream.
|
||||
*/
|
||||
|
||||
sock->instream = fdopen(sock->sd, "r");
|
||||
if (!sock->instream)
|
||||
{
|
||||
ndbg("fdopen() failed: %d\n", errno);
|
||||
goto errout_with_sd;
|
||||
}
|
||||
|
||||
/* Create the outgoing stream */
|
||||
|
||||
sock->outstream = fdopen(sock->sd, "w");
|
||||
if (!sock->outstream)
|
||||
{
|
||||
ndbg("fdopen() failed: %d\n", errno);
|
||||
goto errout_with_instream;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
/* Close the instream. NOTE: Since the underlying socket descriptor is
|
||||
* *not* dup'ed, the following close should fail harmlessly.
|
||||
*/
|
||||
|
||||
errout_with_instream:
|
||||
fclose(sock->instream);
|
||||
sock->instream = NULL;
|
||||
errout_with_sd:
|
||||
close(sock->sd);
|
||||
sock->sd = -1;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_socklisten
|
||||
*
|
||||
* Description:
|
||||
* Bind the socket to local address and wait for connection from the server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_socklisten(struct ftpc_socket_s *sock)
|
||||
{
|
||||
unsigned int addrlen = sizeof(sock->laddr);
|
||||
int ret;
|
||||
|
||||
/* Bind the local socket to the local address */
|
||||
|
||||
sock->laddr.sin_port = 0;
|
||||
ret = bind(sock->sd, (struct sockaddr *)&sock->laddr, addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("bind() failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Wait for the connection to the server */
|
||||
|
||||
if (listen(sock->sd, 1) == -1)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Then get the local address selected by NuttX */
|
||||
|
||||
ret = ftpc_sockgetsockname(sock, &sock->laddr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockprintf
|
||||
*
|
||||
* Description:
|
||||
* printf to a socket stream
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_sockprintf(struct ftpc_socket_s *sock, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = vfprintf(sock->outstream, fmt, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_sockgetsockname
|
||||
*
|
||||
* Description:
|
||||
* Get the address of the local socket
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_sockgetsockname(FAR struct ftpc_socket_s *sock,
|
||||
FAR struct sockaddr_in *addr)
|
||||
{
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
int ret;
|
||||
|
||||
ret = getsockname(sock->sd, (FAR struct sockaddr *)addr, &len);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("getsockname failed: %d\n", errno);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_transfer.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <poll.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftp_pasvmode
|
||||
*
|
||||
* Description:
|
||||
* Enter passive mode.
|
||||
*
|
||||
* In active mode FTP the client connects from a random port (N>1023) to the
|
||||
* FTP server's command port, port 21. Then, the client starts listening to
|
||||
* port N+1 and sends the FTP command PORT N+1 to the FTP server. The server
|
||||
* will then connect back to the client's specified data port from its local
|
||||
* data port, which is port 20. In passive mode FTP the client initiates
|
||||
* both connections to the server, solving the problem of firewalls filtering
|
||||
* the incoming data port connection to the client from the server. When
|
||||
* opening an FTP connection, the client opens two random ports locally
|
||||
* (N>1023 and N+1). The first port contacts the server on port 21, but
|
||||
* instead of then issuing a PORT command and allowing the server to connect
|
||||
* back to its data port, the client will issue the PASV command. The result
|
||||
* of this is that the server then opens a random unprivileged port (P >
|
||||
* 1023) and sends the PORT P command back to the client. The client then
|
||||
* initiates the connection from port N+1 to port P on the server to transfer
|
||||
* data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ftp_pasvmode(struct ftpc_session_s *session,
|
||||
uint8_t addrport[6])
|
||||
{
|
||||
int tmpap[6];
|
||||
char *ptr;
|
||||
int nscan;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Does this host support the PASV command */
|
||||
|
||||
if (!FTPC_HAS_PASV(session))
|
||||
{
|
||||
ndbg("Host doesn't support passive mode\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Request passive mode. The server normally accepts PASV with code 227.
|
||||
* Its response is a single line showing the IP address of the server and
|
||||
* the TCP port number where the server is accepting connections.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "PASV");
|
||||
if (ret < 0 || !ftpc_connected(session))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Skip over any leading stuff before address begins */
|
||||
|
||||
ptr = session->reply + 4;
|
||||
while (!isdigit((int)*ptr))
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* The response is then 6 integer values: four representing the
|
||||
* IP address and two representing the port number.
|
||||
*/
|
||||
|
||||
nscan = sscanf(ptr, "%d,%d,%d,%d,%d,%d",
|
||||
&tmpap[0], &tmpap[1], &tmpap[2],
|
||||
&tmpap[3], &tmpap[4], &tmpap[5]);
|
||||
if (nscan != 6)
|
||||
{
|
||||
ndbg("Error parsing PASV reply: '%s'\n", session->reply);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Then copy the sscanf'ed values as bytes */
|
||||
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
addrport[i] = (uint8_t)(tmpap[i] & 0xff);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_abspath
|
||||
*
|
||||
* Description:
|
||||
* Get the absolute path to a file, handling tilde expansion.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR char *ftpc_abspath(FAR struct ftpc_session_s *session,
|
||||
FAR const char *relpath, FAR const char *homedir,
|
||||
FAR const char *curdir)
|
||||
{
|
||||
FAR char *ptr = NULL;
|
||||
int ret = OK;
|
||||
|
||||
/* If no relative path was provide, then use the current working directory */
|
||||
|
||||
if (!relpath)
|
||||
{
|
||||
return strdup(curdir);
|
||||
}
|
||||
|
||||
/* Handle tilde expansion */
|
||||
|
||||
if (relpath[0] == '~')
|
||||
{
|
||||
/* Is the relative path only '~' */
|
||||
|
||||
if (relpath[1] == '\0')
|
||||
{
|
||||
return strdup(homedir);
|
||||
}
|
||||
|
||||
/* No... then a '/' better follow the tilde */
|
||||
|
||||
else if (relpath[1] == '/')
|
||||
{
|
||||
ret = asprintf(&ptr, "%s%s", homedir, &relpath[1]);
|
||||
}
|
||||
|
||||
/* Hmmm... this pretty much guaranteed to fail */
|
||||
|
||||
else
|
||||
{
|
||||
ptr = strdup(relpath);
|
||||
}
|
||||
}
|
||||
|
||||
/* No tilde expansion. Check for a path relative to the current
|
||||
* directory.
|
||||
*/
|
||||
|
||||
else if (strncmp(relpath, "./", 2) == 0)
|
||||
{
|
||||
ret = asprintf(&ptr, "%s%s", curdir, relpath+1);
|
||||
}
|
||||
|
||||
/* Check for an absolute path */
|
||||
|
||||
else if (relpath[0] == '/' && relpath[1] == ':' && relpath[2] == '\\')
|
||||
{
|
||||
ptr = strdup(relpath);
|
||||
}
|
||||
|
||||
/* Assume it a relative path */
|
||||
|
||||
else
|
||||
{
|
||||
ret = asprintf(&ptr, "%s/%s", curdir, relpath);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_xfrinit
|
||||
*
|
||||
* Description:
|
||||
* Perform common transfer setup logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_xfrinit(FAR struct ftpc_session_s *session)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
uint8_t addrport[6];
|
||||
uint8_t *paddr;
|
||||
uint8_t *pport;
|
||||
int ret;
|
||||
|
||||
/* We must be connected to initiate a transfer */
|
||||
|
||||
if (!ftpc_connected(session))
|
||||
{
|
||||
ndbg("Not connected\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Initialize the data channel */
|
||||
|
||||
ret = ftpc_sockinit(&session->data);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftpc_sockinit() failed: %d\n", errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Duplicate the address and connection information of the command channel */
|
||||
|
||||
ftpc_sockcopy(&session->data, &session->cmd);
|
||||
|
||||
/* Should we enter passive mode? */
|
||||
|
||||
if (FTPC_IS_PASSIVE(session))
|
||||
{
|
||||
/* Yes.. going passive. */
|
||||
|
||||
ret = ftp_pasvmode(session, addrport);
|
||||
if (ret != OK)
|
||||
{
|
||||
ndbg("ftp_pasvmode() failed: %d\n", errno);
|
||||
goto errout_with_data;
|
||||
}
|
||||
|
||||
/* Configure the data socket */
|
||||
|
||||
ftpc_sockgetsockname(&session->cmd, &addr);
|
||||
memcpy(&addr.sin_addr, addrport, 4);
|
||||
memcpy(&addr.sin_port, addrport+4, 2);
|
||||
|
||||
/* Connect the data socket */
|
||||
|
||||
ret = ftpc_sockconnect(&session->data, &addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("ftpc_sockconnect() failed: %d\n", errno);
|
||||
goto errout_with_data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for the connection to be established */
|
||||
|
||||
ftpc_socklisten(&session->data);
|
||||
|
||||
/* Then send our local data channel address to the server */
|
||||
|
||||
paddr = (uint8_t *)&session->data.laddr.sin_addr;
|
||||
pport = (uint8_t *)&session->data.laddr.sin_port;
|
||||
|
||||
ret = ftpc_cmd(session, "PORT %d,%d,%d,%d,%d,%d",
|
||||
paddr[0], paddr[1], paddr[2],
|
||||
paddr[3], pport[0], pport[1]);
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("ftpc_cmd() failed: %d\n", errno);
|
||||
goto errout_with_data;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
||||
errout_with_data:
|
||||
ftpc_sockclose(&session->data);
|
||||
errout:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_xfrreset
|
||||
*
|
||||
* Description:
|
||||
* Reset transfer variables
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_xfrreset(struct ftpc_session_s *session)
|
||||
{
|
||||
session->size = 0;
|
||||
session->flags &= ~FTPC_XFER_FLAGS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_xfrmode
|
||||
*
|
||||
* Description:
|
||||
* Select ASCII or Binary transfer mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_xfrmode(struct ftpc_session_s *session, uint8_t xfrmode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check if we have already selected the requested mode */
|
||||
|
||||
DEBUGASSERT(xfrmode != FTPC_XFRMODE_UNKNOWN);
|
||||
if (session->xfrmode != xfrmode)
|
||||
{
|
||||
/* Send the TYPE request to control the binary flag. Parameters for the
|
||||
* TYPE request include:
|
||||
*
|
||||
* A: Turn the binary flag off.
|
||||
* A N: Turn the binary flag off.
|
||||
* I: Turn the binary flag on.
|
||||
* L 8: Turn the binary flag on.
|
||||
*
|
||||
* The server accepts the TYPE request with code 200.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "TYPE %c", xfrmode == FTPC_XFRMODE_ASCII ? 'A' : 'I');
|
||||
session->xfrmode = xfrmode;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_xfrabort
|
||||
*
|
||||
* Description:
|
||||
* Abort a transfer in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
|
||||
{
|
||||
FAR struct pollfd fds;
|
||||
int ret;
|
||||
|
||||
/* Make sure that we are still connected */
|
||||
|
||||
if (!ftpc_connected(session))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check if there is data waiting to be read from the cmd channel */
|
||||
|
||||
fds.fd = session->cmd.sd;
|
||||
fds.events = POLLIN;
|
||||
ret = poll(&fds, 1, 0);
|
||||
if (ret > 0)
|
||||
{
|
||||
/* Read data from command channel */
|
||||
|
||||
nvdbg("Flush cmd channel data\n");
|
||||
while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
FTPC_SET_INTERRUPT(session);
|
||||
|
||||
/* Send the Telnet interrupt sequence to abort the transfer:
|
||||
* <IAC IP><IAC DM>ABORT<CR><LF>
|
||||
*/
|
||||
|
||||
nvdbg("Telnet ABORt sequence\n");
|
||||
ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_IP); /* Interrupt process */
|
||||
ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_DM); /* Telnet synch signal */
|
||||
ftpc_sockprintf(&session->cmd, "ABOR\r\n"); /* Abort */
|
||||
ftpc_sockflush(&session->cmd);
|
||||
|
||||
/* Read remaining bytes from connection */
|
||||
|
||||
while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
|
||||
while(stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0)
|
||||
|
||||
/* Get the ABORt reply */
|
||||
|
||||
fptc_getreply(session);
|
||||
|
||||
/* Expected replys are: "226 Closing data connection" or
|
||||
* "426 Connection closed; transfer aborted"
|
||||
*/
|
||||
|
||||
if (session->code != 226 && session->code != 426)
|
||||
{
|
||||
nvdbg("Expected 226 or 426 reply\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the next reply */
|
||||
|
||||
fptc_getreply(session);
|
||||
|
||||
/* Expected replys are: or "225 Data connection open; no transfer in progress"
|
||||
* "226 Closing data connection"
|
||||
*/
|
||||
|
||||
if (session->code != 226 && session->code != 225)
|
||||
{
|
||||
nvdbg("Expected 225 or 226 reply\n");
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_timeout
|
||||
*
|
||||
* Description:
|
||||
* A timeout occurred -- either on a specific command or while waiting
|
||||
* for a reply.
|
||||
*
|
||||
* NOTE:
|
||||
* This function executes in the context of a timer interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_timeout(int argc, uint32_t arg1, ...)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)arg1;
|
||||
|
||||
nlldbg("Timeout!\n");
|
||||
DEBUGASSERT(argc == 1 && session);
|
||||
kill(session->pid, CONFIG_FTP_SIGNAL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_absrpath
|
||||
*
|
||||
* Description:
|
||||
* Get the absolute path to a remote file, handling tilde expansion.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *ftpc_absrpath(FAR struct ftpc_session_s *session,
|
||||
FAR const char *relpath)
|
||||
{
|
||||
FAR char *absrpath = ftpc_abspath(session, relpath,
|
||||
session->homerdir, session->currdir);
|
||||
nvdbg("%s -> %s\n", relpath, absrpath);
|
||||
return absrpath;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_abslpath
|
||||
*
|
||||
* Description:
|
||||
* Get the absolute path to a local file, handling tilde expansion.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *ftpc_abslpath(FAR struct ftpc_session_s *session,
|
||||
FAR const char *relpath)
|
||||
{
|
||||
FAR char *abslpath = ftpc_abspath(session, relpath,
|
||||
session->homeldir, session->curldir);
|
||||
nvdbg("%s -> %s\n", relpath, abslpath);
|
||||
return abslpath;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_unlink.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <apps/ftpc.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_unlink
|
||||
*
|
||||
* Descripton:
|
||||
* Delete the given file from the remote server.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_unlink(SESSION handle, FAR const char *path)
|
||||
{
|
||||
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
|
||||
int ret;
|
||||
|
||||
/* A DELE request asks the server to remove a regular file. A typical server
|
||||
* accepts DELE with:
|
||||
*
|
||||
* - "250 Requested file action okay, completed" if the file was
|
||||
* successfully removed
|
||||
*
|
||||
* Or rejects RMD with:
|
||||
*
|
||||
* - "550 Requested action not taken" f the removal failed.
|
||||
*/
|
||||
|
||||
ret = ftpc_cmd(session, "DELE %s", path);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/ftpc/ftpc_utils.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "ftpc_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ftpc_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_nibble
|
||||
*
|
||||
* Description:
|
||||
* Convert a ASCII hex 'digit' to binary
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ftpc_nibble(char ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
return (unsigned int)ch - '0';
|
||||
}
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
{
|
||||
return (unsigned int)ch - 'A' + 10;
|
||||
}
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
{
|
||||
return (unsigned int)ch - 'a' + 10;
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_reset
|
||||
*
|
||||
* Description:
|
||||
* Reset the FTP session.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_reset(struct ftpc_session_s *session)
|
||||
{
|
||||
ftpc_sockclose(&session->data);
|
||||
ftpc_sockclose(&session->cmd);
|
||||
free(session->uname);
|
||||
session->uname = NULL;
|
||||
free(session->pwd);
|
||||
session->pwd = NULL;
|
||||
free(session->initrdir);
|
||||
session->initrdir = NULL;
|
||||
session->flags &= ~FTPC_FLAGS_CLEAR;
|
||||
session->flags |= FTPC_FLAGS_SET;
|
||||
session->xfrmode = FTPC_XFRMODE_UNKNOWN;
|
||||
session->code = 0;
|
||||
session->replytimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
session->conntimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_lpwd
|
||||
*
|
||||
* Description:
|
||||
* Return the local current working directory. NOTE: This is a peek at
|
||||
* a global copy. The caller should call strdup if it wants to keep it.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR const char *ftpc_lpwd(void)
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
FAR const char *val;
|
||||
|
||||
val = getenv("PWD");
|
||||
if (!val)
|
||||
{
|
||||
val = CONFIG_FTP_TMPDIR;
|
||||
}
|
||||
return val;
|
||||
#else
|
||||
return CONFIG_FTP_TMPDIR;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_stripcrlf
|
||||
*
|
||||
* Description:
|
||||
* Strip any trailing carriage returns or line feeds from a string (by
|
||||
* overwriting them with NUL characters).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_stripcrlf(FAR char *str)
|
||||
{
|
||||
FAR char *ptr;
|
||||
int len;
|
||||
|
||||
if (str)
|
||||
{
|
||||
len = strlen(str);
|
||||
if (len > 0)
|
||||
{
|
||||
ptr = str + len - 1;
|
||||
while (*ptr == '\r' || *ptr == '\n')
|
||||
{
|
||||
*ptr = '\0';
|
||||
ptr--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_stripslash
|
||||
*
|
||||
* Description:
|
||||
* Strip any trailing slashes from a string (by overwriting them with NUL
|
||||
* characters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ftpc_stripslash(FAR char *str)
|
||||
{
|
||||
FAR char *ptr;
|
||||
int len;
|
||||
|
||||
if (str)
|
||||
{
|
||||
len = strlen(str);
|
||||
if (len > 1)
|
||||
{
|
||||
ptr = str + len - 1;
|
||||
if (*ptr == '/')
|
||||
{
|
||||
*ptr = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ftpc_dequote
|
||||
*
|
||||
* Description:
|
||||
* Convert quoted hexadecimal constants to binary values.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *ftpc_dequote(FAR const char *str)
|
||||
{
|
||||
FAR char *allocstr = NULL;
|
||||
FAR char *ptr;
|
||||
int ms;
|
||||
int ls;
|
||||
int len;
|
||||
|
||||
if (str)
|
||||
{
|
||||
/* Allocate space for a modifiable copy of the string */
|
||||
|
||||
len = strlen(str);
|
||||
allocstr = (FAR char*)malloc(len+1);
|
||||
if (allocstr)
|
||||
{
|
||||
/* Search the string */
|
||||
|
||||
ptr = allocstr;
|
||||
while (*str)
|
||||
{
|
||||
/* Check for a quoted hex value */
|
||||
|
||||
if (str[0] == '%')
|
||||
{
|
||||
/* Extract the hex value */
|
||||
|
||||
ms = ftpc_nibble(str[1]);
|
||||
if (ms >= 0)
|
||||
{
|
||||
ls = ftpc_nibble(str[2]);
|
||||
if (ls >= 0)
|
||||
{
|
||||
/* Save the binary value and skip ahead by 3 */
|
||||
|
||||
*ptr++ = (char)(ms << 8 | ls);
|
||||
str += 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Just transfer the character */
|
||||
|
||||
*ptr++ = *str++;
|
||||
}
|
||||
|
||||
/* NUL terminate */
|
||||
|
||||
*ptr = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return allocstr;
|
||||
}
|
||||
Reference in New Issue
Block a user