+Fri Feb 19 21:09:22 EET 2004 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added support for asking the destination filename where
+ the downloaded file is saved in the file transfer. Affected
+ files are lib/silccilent/silcclient.h, client_ftp.c.
+
Wed Feb 18 02:46:17 EET 2004 Pekka Riikonen <priikone@silcnet.org>
* Fixed error handling in resuming data processing. Affected
ret = silc_client_file_receive(silc_client, conn,
silc_client_file_monitor, server, NULL,
- server->current_session->session_id);
+ server->current_session->session_id,
+ NULL, NULL);
if (ret != SILC_CLIENT_FILE_OK) {
if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
printformat_module("fe-common/silc", server, NULL,
if (ftp->client_entry == client_entry && !ftp->filepath) {
ret = silc_client_file_receive(silc_client, conn,
silc_client_file_monitor, server,
- NULL, ftp->session_id);
+ NULL, ftp->session_id, NULL, NULL);
if (ret != SILC_CLIENT_FILE_OK) {
if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
printformat_module("fe-common/silc", server, NULL,
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 2003 Pekka Riikonen
+ Copyright (C) 2001 - 2004 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
SilcClientFileMonitor monitor;
void *monitor_context;
+ SilcClientFileAskName ask_name;
+ void *ask_name_context;
char *filepath;
char *path;
if (session->monitor)
(*session->monitor)(session->client, session->conn,
SILC_CLIENT_FILE_MONITOR_ERROR,
- SILC_CLIENT_FILE_ERROR, 0, 0,
+ SILC_CLIENT_FILE_PERMISSION_DENIED, 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
session->filepath, session->monitor_context);
}
+static void silc_client_ftp_ask_name(const char *filepath,
+ void *context)
+{
+ SilcClientFtpSession session = (SilcClientFtpSession)context;
+ SilcSFTPAttributesStruct attr;
+ char *remote_file = NULL;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ if (filepath) {
+ remote_file = session->filepath;
+ session->filepath = NULL;
+ silc_free(session->path);
+ session->path = NULL;
+ session->filepath = strdup(filepath);
+ } else {
+ remote_file = strdup(session->filepath);
+ }
+
+ /* Now open the file */
+ memset(&attr, 0, sizeof(attr));
+ silc_sftp_open(session->sftp, remote_file, SILC_SFTP_FXF_READ, &attr,
+ silc_client_ftp_open_handle, session);
+
+ /* Close the directory handle */
+ silc_sftp_close(session->sftp, session->dir_handle, NULL, NULL);
+ session->dir_handle = NULL;
+
+ silc_free(remote_file);
+}
+
/* Returns the file name available for download. This is the downloader's
function. */
void *context)
{
SilcClientFtpSession session = (SilcClientFtpSession)context;
- SilcSFTPAttributesStruct attr;
SILC_LOG_DEBUG(("Start"));
return;
}
- /* Now open the file */
- memset(&attr, 0, sizeof(attr));
- silc_sftp_open(sftp, name->filename[0], SILC_SFTP_FXF_READ, &attr,
- silc_client_ftp_open_handle, session);
-
/* Save the important attributes like filename and file size */
session->filepath = strdup(name->filename[0]);
session->filesize = name->attrs[0]->size;
- /* Close the directory handle */
- silc_sftp_close(sftp, session->dir_handle, NULL, NULL);
- session->dir_handle = NULL;
+ /* If the path was not provided, ask from application where to save the
+ downloaded file. */
+ if (!session->path && session->ask_name) {
+ session->ask_name(session->client, session->conn, session->session_id,
+ name->filename[0], silc_client_ftp_ask_name, session,
+ session->ask_name_context);
+ return;
+ }
+
+ /* Start downloading immediately to current directory. */
+ silc_client_ftp_ask_name(NULL, session);
}
/* Returns the file handle after giving opendir command. This is the
SilcClientFileMonitor monitor,
void *monitor_context,
const char *path,
- SilcUInt32 session_id)
+ SilcUInt32 session_id,
+ SilcClientFileAskName ask_name,
+ void *ask_name_context)
{
SilcClientFtpSession session;
SilcBuffer keyagr, ftp;
session->monitor = monitor;
session->monitor_context = monitor_context;
+ session->ask_name = ask_name;
+ session->ask_name_context = ask_name_context;
session->conn = conn;
session->path = path ? strdup(path) : NULL;
protocol.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2004 Pekka Riikonen
This program 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 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
*/
-/*
- * Client side of the protocols.
- */
/* $Id$ */
#include "silcincludes.h"
/* Called to indicate that connection was disconnected to the server.
The `status' may tell the reason of the disconnection, and if the
`message' is non-NULL it may include the disconnection message
- received from server. */
+ received from server. Application must not call the
+ silc_client_close_connection in this callback. The 'conn' is also
+ invalid after this function returns back to library. */
void (*disconnected)(SilcClient client, SilcClientConnection conn,
SilcStatus status, const char *message);
const char *filepath,
void *context);
+/****f* silcclient/SilcClientAPI/SilcClientFileName
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcClientFileName)(SilcUInt32 session_id,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Completion callback for the SilcClientFileAskName callback function.
+ * Application calls this to deliver the filepath and filename where
+ * the downloaded file is to be saved.
+ *
+ ***/
+typedef void (*SilcClientFileName)(const char *filepath,
+ void *context);
+
+/****f* silcclient/SilcClientAPI/SilcClientFileAskName
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcClientFileAskName)(SilcClient client,
+ * SilcClientConnection conn,
+ * SilcUInt32 session_id,
+ * const char *remote_filename,
+ * SilcClientFileName completion,
+ * void *completion_context,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * File name asking callback, that is called if it is given to the
+ * silc_client_file_receive and the path given to that as argument was
+ * NULL. The library calls this to ask the filename and filepath to
+ * where the file is to be saved. The 'remote_filename' is the file
+ * that is being downloaded. Application must call the 'completion'
+ * with 'completion_context' to continue with the file downloading.
+ * It is not mandatory to provide this to the silc_client_file_receive.
+ *
+ ***/
+typedef void (*SilcClientFileAskName)(SilcClient client,
+ SilcClientConnection conn,
+ SilcUInt32 session_id,
+ const char *remote_filename,
+ SilcClientFileName completion,
+ void *completion_context,
+ void *context);
+
/****f* silcclient/SilcClientAPI/silc_client_file_send
*
* SYNOPSIS
* SilcClientFileMonitor monitor,
* void *monitor_context,
* const char *path,
- * SilcUInt32 session_id);
+ * SilcUInt32 session_id,
+ * SilcClientFileAskName ask_name,
+ * void *ask_name_context);
*
* DESCRIPTION
*
* received in the `ftp' client operation function. This will actually
* perform the key agreement protocol with the remote client before
* actually starting the file transmission. The `monitor' callback
- * will be called to monitor the transmission. If `path' is non NULL
+ * will be called to monitor the transmission. If `path' is non-NULL
* the file will be saved into that directory. If NULL the file is
- * saved in the current working directory.
+ * saved in the current working directory, unless the 'ask_name'
+ * callback is non-NULL. In this case the callback is called to ask
+ * the path and filename from application.
*
* If error will occur during the file transfer process the error
* status will be returned in the monitor callback. In this case
SilcClientFileMonitor monitor,
void *monitor_context,
const char *path,
- SilcUInt32 session_id);
+ SilcUInt32 session_id,
+ SilcClientFileAskName ask_name,
+ void *ask_name_context);
/****f* silcclient/SilcClientAPI/silc_client_file_close
*