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:
patacongo
2011-12-19 19:24:09 +00:00
commit add995c32e
4394 changed files with 1077774 additions and 0 deletions
+113
View File
@@ -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
+81
View File
@@ -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.
*/
+87
View File
@@ -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;
}
+91
View File
@@ -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;
}
+107
View File
@@ -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;
}
+238
View File
@@ -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;
}
+72
View File
@@ -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 */
+250
View File
@@ -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;
}
+102
View File
@@ -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);
}
}
+112
View File
@@ -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;
}
+134
View File
@@ -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(&timestamp, 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",
&timestamp.tm_year, &timestamp.tm_mon, &timestamp.tm_mday,
&timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec);
timestamp.tm_year -= 1900;
timestamp.tm_mon--;
return mktime(&timestamp);
}
+429
View File
@@ -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;
}
+268
View File
@@ -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;
}
+100
View File
@@ -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;
}
+122
View File
@@ -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;
}
+281
View File
@@ -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 */
+412
View File
@@ -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);
}
}
+215
View File
@@ -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;
}
+105
View File
@@ -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;
}
+85
View File
@@ -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");
}
+481
View File
@@ -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;
}
+92
View File
@@ -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;
}
+134
View File
@@ -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;
}
+84
View File
@@ -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);
}
+103
View File
@@ -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;
}
+151
View File
@@ -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;
}
+370
View File
@@ -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;
}
+517
View File
@@ -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;
}
+96
View File
@@ -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;
}
+266
View File
@@ -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;
}