From: Pekka Riikonen Date: Thu, 19 Feb 2004 19:10:55 +0000 (+0000) Subject: Added support for asking destination filename in file transfer. X-Git-Tag: silc.server.0.9.17~15 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=8d59ed5056799bc38b34e54a8ca705a072492a57 Added support for asking destination filename in file transfer. --- diff --git a/CHANGES b/CHANGES index 5a820180..fa7f18d3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Fri Feb 19 21:09:22 EET 2004 Pekka Riikonen + + * 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 * Fixed error handling in resuming data processing. Affected diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 0a952318..37a0b9eb 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -888,7 +888,8 @@ static void command_file(const char *data, SILC_SERVER_REC *server, 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, @@ -919,7 +920,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server, 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, diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index 1073ae7f..4806cf62 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -48,6 +48,8 @@ struct SilcClientFtpSessionStruct { SilcClientFileMonitor monitor; void *monitor_context; + SilcClientFileAskName ask_name; + void *ask_name_context; char *filepath; char *path; @@ -329,7 +331,7 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp, 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; @@ -352,6 +354,37 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp, 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. */ @@ -361,7 +394,6 @@ static void silc_client_ftp_readdir_name(SilcSFTP sftp, void *context) { SilcClientFtpSession session = (SilcClientFtpSession)context; - SilcSFTPAttributesStruct attr; SILC_LOG_DEBUG(("Start")); @@ -380,18 +412,21 @@ static void silc_client_ftp_readdir_name(SilcSFTP sftp, 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 @@ -917,7 +952,9 @@ silc_client_file_receive(SilcClient client, 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; @@ -948,6 +985,8 @@ silc_client_file_receive(SilcClient client, 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; diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index 4ff45821..1f89a421 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -2,14 +2,13 @@ protocol.c - Author: Pekka Riikonen + Author: Pekka Riikonen - 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 @@ -17,9 +16,6 @@ GNU General Public License for more details. */ -/* - * Client side of the protocols. - */ /* $Id$ */ #include "silcincludes.h" diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 94f67983..d518c42b 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -654,7 +654,9 @@ typedef struct { /* 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); @@ -2456,6 +2458,54 @@ typedef void (*SilcClientFileMonitor)(SilcClient client, 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 @@ -2521,7 +2571,9 @@ silc_client_file_send(SilcClient client, * SilcClientFileMonitor monitor, * void *monitor_context, * const char *path, - * SilcUInt32 session_id); + * SilcUInt32 session_id, + * SilcClientFileAskName ask_name, + * void *ask_name_context); * * DESCRIPTION * @@ -2530,9 +2582,11 @@ silc_client_file_send(SilcClient client, * 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 @@ -2546,7 +2600,9 @@ silc_client_file_receive(SilcClient client, 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 *