From 09bad78c80cd5da74b0a2642cffe2f9d6b7e5793 Mon Sep 17 00:00:00 2001 From: "Andrew V. Samoilov" Date: Fri, 17 May 2002 13:32:02 +0000 Subject: [PATCH] * xdirentry.h (vfs_s_super): Add control_connection_buzy field to ftp struct. * ftpfs.c (linear_start): Set control_connection_buzy. (linear_abort): Unset control_connection_buzy. (ftpfs_fh_open): Don't retrieve file if it is opened for writting only. Open data connection as fh->handle and unlink/unset local temporary file if control connection isn't buzy. (ftpfs_fh_close): New function to serve opened in ftpfs_fh_open() data connection. Unset fh->changed to prevent MEDATA->file_store() call from vfs_s_close(). --- vfs/ChangeLog | 19 ++++++++++++--- vfs/ftpfs.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-- vfs/xdirentry.h | 1 + 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/vfs/ChangeLog b/vfs/ChangeLog index 73f3c8b41..314c2eaa7 100644 --- a/vfs/ChangeLog +++ b/vfs/ChangeLog @@ -1,7 +1,20 @@ 2002-05-17 Andrew V. Samoilov + * xdirentry.h (vfs_s_super): Add control_connection_buzy + field to ftp struct. + + * ftpfs.c (linear_start): Set control_connection_buzy. + (linear_abort): Unset control_connection_buzy. + (ftpfs_fh_open): Don't retrieve file if it is + opened for writting only. Open data connection as + fh->handle and unlink/unset local temporary file + if control connection isn't buzy. + (ftpfs_fh_close): New function to serve opened in + ftpfs_fh_open() data connection. Unset fh->changed + to prevent MEDATA->file_store() call from vfs_s_close(). + * direntry.c (vfs_s_read): Move MEDATA->linear_start() ... - * (vfs_s_open): ... here. + (vfs_s_open): ... here. * samba/include/includes.h: Eliminate all references to HAVE_LIBREADLINE. @@ -10,7 +23,7 @@ * Makefile.am (noinst_LIBRARIES): Add samba/libsamba.a if USE_SAMBA_FS is true. - * (libvfs-mc.a): Don't merge object files with libsamba.a. + (libvfs-mc.a): Don't merge object files with libsamba.a. 2002-05-13 Andrew V. Samoilov @@ -18,7 +31,7 @@ * vfs.c (MC_RENAMEOP): Make arguments const. * vfs.h (mc_rename): Adjust declaration. - * (mc_link): Likewise. + (mc_link): Likewise. 2002-05-11 Andrew V. Samoilov diff --git a/vfs/ftpfs.c b/vfs/ftpfs.c index 6c693448a..317017627 100644 --- a/vfs/ftpfs.c +++ b/vfs/ftpfs.c @@ -274,6 +274,8 @@ reconnect (vfs *me, vfs_s_super *super) SUP.sock = sock; SUP.cwdir = NULL; if (login_server (me, super, SUP.password)){ + if (!cwdir) + return 1; sock = ftpfs_chdir_internal (me, super, cwdir); g_free (cwdir); return sock == COMPLETE; @@ -847,11 +849,11 @@ dir_uptodate(vfs *me, vfs_s_inode *ino) { struct timeval tim; - gettimeofday(&tim, NULL); if (force_expiration) { force_expiration = 0; return 0; } + gettimeofday(&tim, NULL); if (tim.tv_sec < ino->u.ftp.timestamp.tv_sec) return 1; return 0; @@ -1026,6 +1028,7 @@ linear_abort (vfs *me, vfs_s_fh *fh) char buf[1024]; int dsock = FH_SOCK; FH_SOCK = -1; + SUP.control_connection_buzy = 0; print_vfs_message(_("ftpfs: aborting transfer.")); if (send(SUP.sock, ipbuf, sizeof(ipbuf), MSG_OOB) != sizeof(ipbuf)) { @@ -1447,6 +1450,7 @@ linear_start(vfs *me, vfs_s_fh *fh, int offset) if (FH_SOCK == -1) ERRNOR (EACCES, 0); fh->linear = LS_LINEAR_OPEN; + FH_SUPER->u.ftp.control_connection_buzy = 1; return 1; } @@ -1683,6 +1687,44 @@ static void my_forget (char *file) static int ftpfs_fh_open (vfs *me, vfs_s_fh *fh, int flags, int mode) { + /* File will be written only, so no need to retrieve it from ftp server */ + if (((flags & O_WRONLY) == O_WRONLY) && !(flags & (O_RDONLY|O_RDWR))){ +#ifdef HAVE_STRUCT_LINGER + struct linger li; +#else + int li = 1; +#endif + char * name; + + /* linear_start() called, so data will be written + * to local temporary file and stored to ftp server + * by vfs_s_close later + */ + if (FH_SUPER->u.ftp.control_connection_buzy) + return 0; + name = vfs_s_fullpath (me, fh->ino); + if (!name) + return -1; + fh->handle = open_data_connection(me, fh->ino->super, + (flags & O_APPEND) ? "APPE" : "STOR", name, TYPE_BINARY, 0); + g_free (name); + + if (fh->handle < 0) + return -1; +#ifdef HAVE_STRUCT_LINGER + li.l_onoff = 1; + li.l_linger = 120; +#endif + setsockopt(fh->handle, SOL_SOCKET, SO_LINGER, &li, sizeof(li)); + + if (fh->ino->localname){ + unlink (fh->ino->localname); + g_free (fh->ino->localname); + fh->ino->localname = NULL; + } + return 0; + } + if (!fh->ino->localname) if (vfs_s_retrieve_file (me, fh->ino)==-1) return -1; @@ -1691,6 +1733,21 @@ static int ftpfs_fh_open (vfs *me, vfs_s_fh *fh, int flags, int mode) return 0; } +static int ftpfs_fh_close (vfs *me, vfs_s_fh *fh) +{ + if (fh->handle != -1 && !fh->ino->localname){ + close (fh->handle); + fh->handle = -1; + /* File is stored to destination already, so + * we prevent MEDATA->file_store() call from vfs_s_close () + */ + fh->changed = 0; + if (get_reply (me, fh->ino->SUP.sock, NULL, 0) != COMPLETE) + ERRNOR (EIO, -1); + } + return 0; +} + static struct vfs_s_data ftp_data = { NULL, 0, @@ -1707,7 +1764,7 @@ static struct vfs_s_data ftp_data = { free_archive, ftpfs_fh_open, /* fh_open */ - NULL, /* fh_close */ + ftpfs_fh_close, /* fh_close */ vfs_s_find_entry_linear, dir_load, diff --git a/vfs/xdirentry.h b/vfs/xdirentry.h index e26ae4182..f388e6ed4 100644 --- a/vfs/xdirentry.h +++ b/vfs/xdirentry.h @@ -113,6 +113,7 @@ typedef struct vfs_s_super { int strict; /* ftp server doesn't understand "LIST -la "; use "CWD "/ "LIST" instead */ + int control_connection_buzy; #define RFC_AUTODETECT 0 #define RFC_DARING 1 #define RFC_STRICT 2