This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FTP client - stream oriented functions


Added new functions ftp_get_var() and ftp_put_var() which take a 
data function instead of fixed buffer/size.  This allows for creation
of FTP data in a stream oriented fashion.

-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates
Index: net/ftpclient/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos-opt/net/net/ftpclient/current/ChangeLog,v
retrieving revision 1.8
diff -u -5 -p -r1.8 ChangeLog
--- net/ftpclient/current/ChangeLog	11 Jul 2003 09:53:03 -0000	1.8
+++ net/ftpclient/current/ChangeLog	24 May 2004 19:26:14 -0000
@@ -1,5 +1,12 @@
+2004-05-24  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/ftpclient.c: 
+	* include/ftpclient.h:
+	* cdl/ftpclient.cdl: Add new functions 'ftp_get_var()' and 'ftp_put_var()'
+	which allow for streams of data instead of fixed buffers.
+
 2003-07-02  Daniel Néri  <daniel.neri@sigicom.se>
 
 	* src/ftpclient.c (send_cmd): Fix typo in error message.
 	(opendatasock): Use snprintf instead of sprintf.
 
Index: net/ftpclient/current/cdl/ftpclient.cdl
===================================================================
RCS file: /misc/cvsfiles/ecos-opt/net/net/ftpclient/current/cdl/ftpclient.cdl,v
retrieving revision 1.4
diff -u -5 -p -r1.4 ftpclient.cdl
--- net/ftpclient/current/cdl/ftpclient.cdl	24 Feb 2003 14:29:52 -0000	1.4
+++ net/ftpclient/current/cdl/ftpclient.cdl	24 May 2004 19:26:14 -0000
@@ -7,10 +7,11 @@
 # ====================================================================
 #####ECOSGPLCOPYRIGHTBEGIN####
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2004 Gary Thomas
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
 ## the terms of the GNU General Public License as published by the Free
 ## Software Foundation; either version 2 or (at your option) any later version.
 ##
@@ -51,26 +52,37 @@
 
 cdl_package CYGPKG_NET_FTPCLIENT {
     display       "FTP client"
     parent        CYGPKG_NET
     requires      CYGPKG_IO
+    requires      CYGPKG_NET
+    requires      CYGPKG_MEMALLOC
     requires      { 0 != CYGINT_ISO_STRING_STRFUNCS }
     requires      { 0 != CYGINT_ISO_STRING_MEMFUNCS }
     requires      { 0 != CYGINT_ISO_STDLIB_STRCONV }
     requires      { 0 != CYGINT_ISO_STDIO_FORMATTED_IO }
     requires      { 0 != CYGINT_ISO_STRING_STRFUNCS }
     requires      { 0 != CYGINT_ISO_ERRNO }
     requires      { 0 != CYGINT_ISO_ERRNO_CODES }
     requires      { 0 != CYGINT_ISO_CTYPE }
-    requires      CYGPKG_NET
     description   "
         FTP client support. Provides ftp_put and ftp_get to put a file
         onto a remote FTP server and get a file from a remote server. 
         Only binary more is supported."
     doc           ref/net-ftpclient.html
 
     compile       ftpclient.c
+
+    cdl_option CYGNUM_NET_FTPCLIENT_BUFSIZE {
+        display "Size of internal buffers used during FTP transfers"
+        flavor  data
+        default_value 512
+        description "
+          The FTP data transfer functions buffer the data as it
+          passes between systems.  This option controls the size
+          of that buffer, which will be allocated using 'malloc'"
+    }
 
     cdl_component CYGPKG_NET_FTPCLIENT_OPTIONS {
         display "FTP client build options"
         flavor  none
 	no_define
Index: net/ftpclient/current/include/ftpclient.h
===================================================================
RCS file: /misc/cvsfiles/ecos-opt/net/net/ftpclient/current/include/ftpclient.h,v
retrieving revision 1.3
diff -u -5 -p -r1.3 ftpclient.h
--- net/ftpclient/current/include/ftpclient.h	23 May 2002 23:08:04 -0000	1.3
+++ net/ftpclient/current/include/ftpclient.h	24 May 2004 19:26:14 -0000
@@ -10,10 +10,11 @@
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
 //
@@ -51,11 +52,16 @@
 //              
 //####DESCRIPTIONEND####
 //
 //==========================================================================
 
+// User-defined function for printing diagnostic messages
 typedef void (*ftp_printf_t)(unsigned error, const char *, ...);
+// User-defined function used to provide data
+typedef int (*ftp_read_t)(char *buf, int bufsize, void *priv);
+// User-defined function used to process data
+typedef int (*ftp_write_t)(char *buf, int bufsize, void *priv);
 
 /* Use the FTP protocol to retrieve a file from a server. Only binary
    mode is supported. The filename can include a directory name. Only
    use unix style / not M$'s \. The file is placed into buf. buf has
    maximum size buf_size. If the file is bigger than this, the
@@ -69,10 +75,23 @@ int ftp_get(char * hostname, 
             char * filename, 
             char * buf, 
             unsigned buf_size,
             ftp_printf_t ftp_printf);
 
+//
+// Just like 'ftp_get()' except that the "write()" function is called
+// as data arrives instead of using a fixed buffer.  Returns the total
+// amount of data read, or an error indication (negative codes)
+//
+int ftp_get_var(char *hostname,
+                char *username,
+                char *passwd,
+                char *filename,
+                ftp_write_t ftp_write,
+                void *ftp_write_priv,
+                ftp_printf_t ftp_printf);
+
 /*Use the FTP protocol to send a file from a server. Only binary mode
   is supported. The filename can include a directory name. Only use
   unix style / not M$'s \. The contents of buf is placed into the file
   on the server. If an error occurs one of the codes as listed below
   will be returned. If the transfer is succseful zero is returned.*/
@@ -83,10 +102,23 @@ int ftp_put(char * hostname, 
             char * filename, 
             char * buf, 
             unsigned buf_size,
             ftp_printf_t ftp_printf);
 
+//
+// Just like 'ftp_put()' except that the "read()" function is called
+// to fetch the data to write instead of using a fixed buffer.  Returns 
+// the total amount of data written, or an error indication (negative codes)
+//
+int ftp_put_var(char *hostname,
+                char *username,
+                char *passwd,
+                char *filename,
+                ftp_read_t ftp_read,
+                void *ftp_read_priv,
+                ftp_printf_t ftp_printf);
+
 /*ftp_get() and ftp_put take the name of a function to call to print
   out diagnostic and error messages. This is a sample implementation
   which can be used if you don't want to implement the function
   yourself. error will be true when the message to print is an error
   message. Otherwise the message is diagnostic, eg the commands sent
@@ -99,8 +131,9 @@ void ftpclient_printf(unsigned error, co
 #define FTP_BAD         -2 /* Catch all, socket errors etc. */
 #define FTP_NOSUCHHOST  -3 /* The server does not exist. */
 #define FTP_BADUSER     -4 /* Username/Password failed */
 #define FTP_TOOBIG      -5 /* Out of buffer space or disk space */ 
 #define FTP_BADFILENAME -6 /* The file does not exist */
+#define FTP_NOMEMORY    -7 /* Unable to allocate memory for internal buffers */
 
-#endif CYGONCE_NET_FTPCLIENT_FTPCLIENT
+#endif // CYGONCE_NET_FTPCLIENT_FTPCLIENT
 
Index: net/ftpclient/current/src/ftpclient.c
===================================================================
RCS file: /misc/cvsfiles/ecos-opt/net/net/ftpclient/current/src/ftpclient.c,v
retrieving revision 1.7
diff -u -5 -p -r1.7 ftpclient.c
--- net/ftpclient/current/src/ftpclient.c	11 Jul 2003 09:53:04 -0000	1.7
+++ net/ftpclient/current/src/ftpclient.c	24 May 2004 19:26:14 -0000
@@ -8,10 +8,11 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 // Copyright (C) 2002 Andrew Lunn.
+// Copyright (C) 2004 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
 //
@@ -50,10 +51,11 @@
 //####DESCRIPTIONEND####
 //
 //==========================================================================
 
 #include <pkgconf/system.h>
+#include <pkgconf/net_ftpclient.h>
 
 #include <network.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/socket.h>
@@ -86,12 +88,12 @@ build_cmd(char *buf,
 
 /* Read one line from the server, being careful not to overrun the
    buffer. If we do reach the end of the buffer, discard the rest of
    the line. */
 static int 
-get_line(int s, char *buf, unsigned buf_size,ftp_printf_t ftp_printf) {
-  
+get_line(int s, char *buf, unsigned buf_size, ftp_printf_t ftp_printf) 
+{
   int eol = 0;
   int cnt = 0;
   int ret;
   char c;
   
@@ -123,12 +125,12 @@ get_line(int s, char *buf, unsigned buf_
 /* Read the reply from the server and return the MSB from the return
    code. This gives us a basic idea if the command failed/worked. The
    reply can be spread over multiple lines. When this happens the line
    will start with a - to indicate there is more*/
 static int 
-get_reply(int s,ftp_printf_t ftp_printf) {
-
+get_reply(int s, ftp_printf_t ftp_printf) 
+{
   char buf[BUFSIZ];
   int more = 0;
   int ret;
   int first_line=1;
   int code=0;
@@ -159,12 +161,12 @@ get_reply(int s,ftp_printf_t ftp_printf)
   return (buf[0] - '0');
 }
 
 /* Send a command to the server */
 static int 
-send_cmd(int s,char * msgbuf,ftp_printf_t ftp_printf) {
-  
+send_cmd(int s, char * msgbuf, ftp_printf_t ftp_printf) 
+{  
   int len;
   int slen = strlen(msgbuf);
   
   if ((len = write(s,msgbuf,slen)) != slen) {
     if (slen < 0) {
@@ -184,12 +186,12 @@ static int 
 command(char * cmd, 
         char * arg, 
         int s, 
         char *msgbuf, 
         int msgbuflen,
-        ftp_printf_t ftp_printf) {
-
+        ftp_printf_t ftp_printf) 
+{
   int err;
   
   if (!build_cmd(msgbuf,msgbuflen,cmd,arg)) {
     ftp_printf(1,"FTP: %s command to long\n",cmd);
     return FTP_BAD;
@@ -309,182 +311,200 @@ port we are listening on.*/
 static int 
 opendatasock(int ctrl_s,
              struct sockaddr *ctrl, 
              char *msgbuf, 
              unsigned msgbuflen,
-             ftp_printf_t ftp_printf) {
-
-  struct sockaddr local;
-  char name[64];
-  char port[10];
-  socklen_t len;
-  int on = 1;
-  char buf[80];
-  int ret;
-  int s;
+             ftp_printf_t ftp_printf) 
+{
+    struct sockaddr local;
+    char name[64];
+    char port[10];
+    socklen_t len;
+    int on = 1;
+    char buf[80];
+    int ret;
+    int s;
 
-  s = socket(ctrl->sa_family, SOCK_STREAM, 0);
-  if (s < 0) {
-    ftp_printf(1,"socket: %s\n",strerror(errno));
-    return FTP_BAD;
-  }
+    s = socket(ctrl->sa_family, SOCK_STREAM, 0);
+    if (s < 0) {
+        ftp_printf(1,"socket: %s\n",strerror(errno));
+        return FTP_BAD;
+    }
   
-  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
-    ftp_printf(1,"setsockopt: %s\n",strerror(errno));
-    close(s);
-    return FTP_BAD;
-  }
+    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
+        ftp_printf(1,"setsockopt: %s\n",strerror(errno));
+        close(s);
+        return FTP_BAD;
+    }
   
-  memcpy(&local,ctrl,sizeof(struct sockaddr));
-  switch (ctrl->sa_family) {
+    memcpy(&local,ctrl,sizeof(struct sockaddr));
+    switch (ctrl->sa_family) {
     case AF_INET: {
-      struct sockaddr_in * sa4 = (struct sockaddr_in *) &local;
-      sa4->sin_port = 0;
-      break;
+        struct sockaddr_in * sa4 = (struct sockaddr_in *) &local;
+        sa4->sin_port = 0;
+        break;
     }
 #ifdef CYGPKG_NET_INET6
     case AF_INET6: {
-      struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *) &local;
-      sa6->sin6_port = 0;
-      break;
+        struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *) &local;
+        sa6->sin6_port = 0;
+        break;
     }
 #endif
     default:
-      close (s);
-      return FTP_BAD;
-  }
+        close (s);
+        return FTP_BAD;
+    }
 
-  if (bind(s,&local,local.sa_len) < 0) {
-    ftp_printf(1,"bind: %s\n",strerror(errno));
-    close(s);
-    return FTP_BAD;   
-  }
+    if (bind(s,&local,local.sa_len) < 0) {
+        ftp_printf(1,"bind: %s\n",strerror(errno));
+        close(s);
+        return FTP_BAD;   
+    }
   
-  len = sizeof(local);
-  if (getsockname(s,&local,&len) < 0) {
-    ftp_printf(1,"getsockname: %s\n",strerror(errno));
-    close(s);
-    return FTP_BAD;   
-  }
+    len = sizeof(local);
+    if (getsockname(s,&local,&len) < 0) {
+        ftp_printf(1,"getsockname: %s\n",strerror(errno));
+        close(s);
+        return FTP_BAD;   
+    }
   
-  if (listen(s, 1) < 0) {
-    ftp_printf(1,"listen: %s\n",strerror(errno));
-    close(s);
-    return FTP_BAD;   
-  }
+    if (listen(s, 1) < 0) {
+        ftp_printf(1,"listen: %s\n",strerror(errno));
+        close(s);
+        return FTP_BAD;   
+    }
   
-  getnameinfo(&local,sizeof(local),name,sizeof(name), port, sizeof(port),
-              NI_NUMERICHOST|NI_NUMERICSERV);
-  switch (local.sa_family) {
-  case AF_INET: {
-    snprintf(buf, sizeof(buf), "|1|%s|%s|", name, port);
-    break;
-  }
+    getnameinfo(&local, sizeof(local), name, sizeof(name), port, sizeof(port),
+                NI_NUMERICHOST|NI_NUMERICSERV);
+    switch (local.sa_family) {
+    case AF_INET: {
+        snprintf(buf, sizeof(buf), "|1|%s|%s|", name, port);
+        break;
+    }
 #ifdef CYGPKG_NET_INET6
-  case AF_INET6: {
-    snprintf(buf, sizeof(buf), "|2|%s|%s|", name, port);
-    break;
-  }
+    case AF_INET6: {
+        snprintf(buf, sizeof(buf), "|2|%s|%s|", name, port);
+        break;
+    }
 #endif
-  default:
-    close (s);
-    return (FTP_BAD);
-  }
+    default:
+        close (s);
+        return (FTP_BAD);
+    }
 
-  ret = command("EPRT",buf,ctrl_s,msgbuf,msgbuflen,ftp_printf);
-  if (ret < 0) {
-    close(s);
-    return (ret);
-  }
+    ret = command("EPRT",buf,ctrl_s,msgbuf,msgbuflen,ftp_printf);
+    if (ret < 0) {
+        close(s);
+        return (ret);
+    }
 
-  if (ret != 2) {
-    ftp_printf(1,"FTP: PORT failed!\n");
-    close(s);
-    return (FTP_BAD);
-  }
-  return (s);
+    if (ret != 2) {
+        int _port = atoi(port);
+        char *s = name;
+        while (*s) {
+            if (*s == '.') *s = ',';
+            s++;
+        }
+        snprintf(buf, sizeof(buf), "%s,%d,%d", name, _port/256, _port%256);
+        ret = command("PORT",buf,ctrl_s,msgbuf,msgbuflen,ftp_printf);
+        if (ret < 0) {
+            close(s);
+            return (ret);
+        }
+        if (ret != 2) {
+            ftp_printf(1,"FTP: PORT failed!\n");
+            close(s);
+            return (FTP_BAD);
+        }
+    }
+    return (s);
 }
 
 /* Receive the file into the buffer and close the data socket
    afterwards */
 static int 
-receive_file(int data_s, char *buf, int buf_size,ftp_printf_t ftp_printf)
+receive_file(int data_s, ftp_write_t ftp_write, void *ftp_write_priv, ftp_printf_t ftp_printf)
 {
-  int remaining = buf_size;
-  int finished = 0;
-  int total_size=0;
-  char *bufp = buf;
-  int len;
-  int s;
-  
-  s = accept(data_s,NULL,0);
-  if (s<0) {
-    ftp_printf(1,"listen: %s\n",strerror(errno));
-    return FTP_BAD;   
-  }
-  
-  do {
-    len = read(s,bufp,remaining);
-    if (len < 0) {
-      ftp_printf(1,"read: %s\n",strerror(errno));
-      close(s);
-      return FTP_BAD;   
-    }
+    char *buf;
+    int finished = 0;
+    int total_size=0;
+    int len, wlen;
+    int s;
 
-    if (len == 0) {
-      finished = 1;
-    } else {
-      total_size += len;
-      remaining -= len;
-      bufp += len;
-    
-      if (total_size == buf_size) {
-        ftp_printf(1,"FTP: File too big!\n");
-        close(s);
-        return FTP_TOOBIG;
-      }
+    if ((buf = (char *)malloc(CYGNUM_NET_FTPCLIENT_BUFSIZE)) == (char *)0) {
+        return FTP_NOMEMORY;
     }
-  } while (!finished);
+    s = accept(data_s, NULL, 0);
+    if (s < 0) {
+        ftp_printf(1, "listen: %s\n",strerror(errno));
+        free(buf);
+        return FTP_BAD;   
+    }
+  
+    do {
+        len = read(s, buf, CYGNUM_NET_FTPCLIENT_BUFSIZE);
+        if (len < 0) {
+            ftp_printf(1, "read: %s\n",strerror(errno));
+            close(s);
+            free(buf);
+            return FTP_BAD;   
+        }
+
+        if (len == 0) {
+            finished = 1;
+        } else {
+            wlen = (*ftp_write)(buf, len, ftp_write_priv);
+            if (wlen != len) {
+                ftp_printf(1, "FTP: File too big!\n");
+                close(s);
+                free(buf);
+                return FTP_TOOBIG;
+            }
+            total_size += len;
+        }
+    } while (!finished);
   
-  close(s);
-  return total_size;
+    close(s);
+    free(buf);
+    return total_size;
 }
 
 /* Receive the file into the buffer and close the socket afterwards*/
 static int 
-send_file(int data_s, char *buf, int buf_size,ftp_printf_t ftp_printf)
+send_file(int data_s, ftp_read_t ftp_read, void *ftp_read_priv, ftp_printf_t ftp_printf)
 {
-  int remaining=buf_size;
-  int finished = 0;
-  char * bufp = buf;
-  int len;
-  int s;
-  
-  s = accept(data_s,NULL,0);
-  if (s<0) {
-    ftp_printf(1,"listen: %s\n",strerror(errno));
-    return FTP_BAD;   
-  }
+    char *buf;
+    int len, rlen;
+    int s;
+  
+    if ((buf = (char *)malloc(CYGNUM_NET_FTPCLIENT_BUFSIZE)) == (char *)0) {
+        return FTP_NOMEMORY;
+    }
+    s = accept(data_s,NULL,0);
+    if (s<0) {
+        ftp_printf(1,"listen: %s\n",strerror(errno));
+        free(buf);
+        return FTP_BAD;   
+    }
+  
+    do { 
+        rlen = (*ftp_read)(buf, CYGNUM_NET_FTPCLIENT_BUFSIZE, ftp_read_priv);
+        if (rlen > 0) {
+            len = write(s, buf, rlen);
+            if (len < 0) {
+                ftp_printf(1,"write: %s\n",strerror(errno));
+                close(s);
+                free(buf);
+                return FTP_BAD;   
+            }
+        }
+    } while (rlen > 0);
   
-  do { 
-    len = write(s,bufp,remaining);
-    if (len < 0) {
-      ftp_printf(1,"write: %s\n",strerror(errno));
-      close(s);
-      return FTP_BAD;   
-    }
-    
-    if (len == remaining) {
-      finished = 1;
-    } else {
-      remaining -= len;
-      bufp += len;
-    }
-  } while (!finished);
-  
-  close(s);
-  return 0;
+    close(s);
+    free(buf);
+    return 0;
 }
 
 /* All done, say bye, bye */
 static int quit(int s, 
                 char *msgbuf, 
@@ -516,18 +536,76 @@ static int quit(int s, 
    bytes will be retrieved and an error code returned. ftp_printf is a
    function to be called to perform printing. On success the number of
    bytes received is returned. On error a negative value is returned
    indicating the type of error. */
 
+struct _ftp_data{
+    char *buf;
+    int   len;
+    int   max_len;
+};
+
+static int _ftp_read(char *buf, int len, void *priv)
+{
+    struct _ftp_data *dp = (struct _ftp_data *)priv;
+    int res = 0;
+
+    // FTP data channel desires to write 'len' bytes.  Fetch up
+    // to that amount into 'buf'
+    if (dp->len > 0) {
+        res = dp->len;
+        if (res > len) res = len;
+        memcpy(buf, dp->buf, res);
+        dp->buf += len;
+        dp->len -= res;
+    }
+    return res;
+}
+
+static int _ftp_write(char *buf, int len, void *priv)
+{
+    struct _ftp_data *dp = (struct _ftp_data *)priv;
+    int res = 0;
+
+    // FTP data channel has 'len' bytes that have been read.
+    // Move into 'buf', respecting the max size of 'buf'
+    if (dp->len < dp->max_len) {
+        res = dp->max_len - dp->len;
+        if (res > len) {
+            res = len;
+        }
+        memcpy(dp->buf, buf, res);
+        dp->buf += len;
+        dp->len += res;
+    }
+    return res;
+}
+
 int ftp_get(char * hostname, 
             char * username, 
             char * passwd, 
             char * filename, 
             char * buf, 
             unsigned buf_size,
             ftp_printf_t ftp_printf)
 {
+    struct _ftp_data ftp_data;
+
+    ftp_data.buf = buf;
+    ftp_data.len = 0;
+    ftp_data.max_len = buf_size;
+    return ftp_get_var(hostname, username, passwd, filename, _ftp_write, &ftp_data, ftp_printf);
+}
+
+int ftp_get_var(char *hostname,
+                char *username,
+                char *passwd,
+                char *filename,
+                ftp_write_t ftp_write,
+                void *ftp_write_priv,
+                ftp_printf_t ftp_printf)
+{
 
   struct sockaddr local;
   char msgbuf[256];
   int s,data_s;
   int bytes;
@@ -573,11 +651,11 @@ int ftp_get(char * hostname, 
     close (data_s);
     close(s);
     return (FTP_BADFILENAME);
   }
   
-  if ((bytes=receive_file(data_s,buf,buf_size,ftp_printf)) < 0) {
+  if ((bytes=receive_file(data_s,ftp_write,ftp_write_priv,ftp_printf)) < 0) {
     ftp_printf(0,"FTP: Receiving file failed\n");
     close (data_s);
     close(s);
     return (bytes);
   }
@@ -617,10 +695,25 @@ int ftp_put(char * hostname, 
             char * filename, 
             char * buf, 
             unsigned buf_size,
             ftp_printf_t ftp_printf)
 {
+    struct _ftp_data ftp_data;
+
+    ftp_data.buf = buf;
+    ftp_data.len = buf_size;
+    return ftp_put_var(hostname, username, passwd, filename, _ftp_read, &ftp_data, ftp_printf);
+}
+
+int ftp_put_var(char *hostname,
+                char *username,
+                char *passwd,
+                char *filename,
+                ftp_read_t ftp_read,
+                void *ftp_read_priv,
+                ftp_printf_t ftp_printf)
+{
 
   struct sockaddr local;
   char msgbuf[256];
   int s,data_s;
   int ret;
@@ -665,11 +758,11 @@ int ftp_put(char * hostname, 
     close (data_s);
     close(s);
     return (FTP_BADFILENAME);
   }
   
-  if ((ret = send_file(data_s,buf,buf_size,ftp_printf)) < 0) {
+  if ((ret = send_file(data_s,ftp_read,ftp_read_priv,ftp_printf)) < 0) {
     ftp_printf(1,"FTP: Sending file failed\n");
     close (data_s);
     close(s);
     return (ret);
   }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]