X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_ftp.c;h=73681d15d4165b8bfd2881276d9a0faf25df830e;hp=7f85a8db9e03b6176e6fe8f18c20bd6b3eec8e89;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hpb=157f4732888e39853b3de6617eeeffd910a4a06d diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index 7f85a8db..73681d15 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -18,7 +18,8 @@ */ /* $Id$ */ -#include "clientlibincludes.h" +#include "silcincludes.h" +#include "silcclient.h" #include "client_internal.h" static int @@ -33,7 +34,7 @@ static void silc_client_ftp_start_key_agreement(SilcClientFtpSession session, /* File transmission session */ struct SilcClientFtpSessionStruct { - uint32 session_id; + SilcUInt32 session_id; SilcClient client; SilcClientConnection conn; SilcClientEntry client_entry; @@ -42,7 +43,7 @@ struct SilcClientFtpSessionStruct { SilcBuffer packet; char *hostname; - uint16 port; + SilcUInt16 port; int listener; SilcClientFileMonitor monitor; @@ -55,8 +56,8 @@ struct SilcClientFtpSessionStruct { SilcSFTPHandle dir_handle; SilcSFTPHandle read_handle; - uint64 filesize; - uint64 read_offset; + SilcUInt64 filesize; + SilcUInt64 read_offset; int fd; }; @@ -76,12 +77,12 @@ SILC_TASK_CALLBACK(silc_client_ftp_connected) if (opt != 0) { if (ctx->tries < 2) { /* Connection failed but lets try again */ - client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, - "Could not connect to client %s: %s", - ctx->host, strerror(opt)); - client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, - "Connecting to port %d of client %s resumed", - ctx->port, ctx->host); + client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, + "Could not connect to client %s: %s", + ctx->host, strerror(opt)); + client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, + "Connecting to port %d of client %s resumed", + ctx->port, ctx->host); /* Unregister old connection try */ silc_schedule_unset_listen_fd(client->schedule, fd); @@ -93,9 +94,9 @@ SILC_TASK_CALLBACK(silc_client_ftp_connected) ctx->tries++; } else { /* Connection failed and we won't try anymore */ - client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, - "Could not connect to client %s: %s", - ctx->host, strerror(opt)); + client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, + "Could not connect to client %s: %s", + ctx->host, strerror(opt)); silc_schedule_unset_listen_fd(client->schedule, fd); silc_net_close_connection(fd); silc_schedule_task_del(client->schedule, ctx->task); @@ -221,7 +222,7 @@ static void silc_client_ftp_monitor(SilcSFTP sftp, static void silc_client_ftp_data(SilcSFTP sftp, SilcSFTPStatus status, const unsigned char *data, - uint32 data_len, + SilcUInt32 data_len, void *context) { SilcClientFtpSession session = (SilcClientFtpSession)context; @@ -312,10 +313,11 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp, O_RDWR | O_CREAT | O_EXCL); if (session->fd < 0) { /* Call monitor callback */ - session->client->ops->say(session->client, session->conn, - SILC_CLIENT_MESSAGE_ERROR, - "File `%s' open failed: %s", session->filepath, - strerror(errno)); + session->client->internal->ops->say(session->client, session->conn, + SILC_CLIENT_MESSAGE_ERROR, + "File `%s' open failed: %s", + session->filepath, + strerror(errno)); if (session->monitor) (*session->monitor)(session->client, session->conn, @@ -463,6 +465,14 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final) if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + /* Call monitor callback */ + if (session->monitor) + (*session->monitor)(session->client, session->conn, + SILC_CLIENT_FILE_MONITOR_ERROR, + SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED, 0, 0, + session->client_entry, session->session_id, + session->filepath, session->monitor_context); + /* Error occured during protocol */ silc_ske_free_key_material(ctx->keymat); goto out; @@ -762,38 +772,40 @@ void silc_client_ftp_session_free(SilcClientFtpSession session) indicated by the `client_entry'. This will negotiate a secret key with the remote client before actually starting the transmission of the file. The `monitor' callback will be called to monitor the - transmission of the file. - - This returns a file session ID for the file transmission. It can - be used to close the session (and abort the file transmission) by - calling the silc_client_file_close function. The session ID is - also returned in the `monitor' callback. This returns 0 if the - file indicated by the `filepath' is being transmitted to the remote - client indicated by the `client_entry', already. */ - -uint32 silc_client_file_send(SilcClient client, - SilcClientConnection conn, - SilcClientFileMonitor monitor, - void *monitor_context, - const char *local_ip, - uint32 local_port, - SilcClientEntry client_entry, - const char *filepath) + transmission of the file. */ + +SilcClientFileError +silc_client_file_send(SilcClient client, + SilcClientConnection conn, + SilcClientFileMonitor monitor, + void *monitor_context, + const char *local_ip, + SilcUInt32 local_port, + SilcClientEntry client_entry, + const char *filepath, + SilcUInt32 *session_id) { SilcClientFtpSession session; SilcBuffer keyagr, ftp; char *filename, *path; + int fd; SILC_LOG_DEBUG(("Start")); /* Check for existing session for `filepath'. */ silc_dlist_start(conn->ftp_sessions); while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { - if (!strcmp(session->filepath, filepath) && + if (session->filepath && !strcmp(session->filepath, filepath) && session->client_entry == client_entry) - return 0; + return SILC_CLIENT_FILE_ALREADY_STARTED; } + /* See whether the file exists, and can be opened in generally speaking */ + fd = silc_file_open(filepath, O_RDONLY); + if (fd < 0) + return SILC_CLIENT_FILE_NO_SUCH_FILE; + silc_file_close(fd); + /* Add new session */ session = silc_calloc(1, sizeof(*session)); session->session_id = ++conn->next_session_id; @@ -835,6 +847,7 @@ uint32 silc_client_file_send(SilcClient client, SILC_LOG_DEBUG(("Could not create listener")); silc_free(session->hostname); session->hostname = NULL; + session->port = 0; } else { /* Listener ready */ session->port = silc_net_get_local_port(session->listener); @@ -860,7 +873,10 @@ uint32 silc_client_file_send(SilcClient client, silc_buffer_free(ftp); silc_free(path); - return session->session_id; + if (session_id) + *session_id = session->session_id; + + return SILC_CLIENT_FILE_OK; } /* Receives a file from a client indicated by the `client_entry'. The @@ -875,7 +891,7 @@ silc_client_file_receive(SilcClient client, SilcClientConnection conn, SilcClientFileMonitor monitor, void *monitor_context, - uint32 session_id) + SilcUInt32 session_id) { SilcClientFtpSession session; SilcBuffer keyagr, ftp; @@ -918,9 +934,9 @@ silc_client_file_receive(SilcClient client, session->listener = silc_net_create_server(0, session->hostname); if (session->listener < 0) { SILC_LOG_DEBUG(("Could not create listener")); - client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, - "Cannot create listener on %s: %s", - session->hostname, strerror(errno)); + client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, + "Cannot create listener on %s: %s", + session->hostname, strerror(errno)); return SILC_CLIENT_FILE_ERROR; } session->port = silc_net_get_local_port(session->listener); @@ -957,7 +973,7 @@ silc_client_file_receive(SilcClient client, SilcClientFileError silc_client_file_close(SilcClient client, SilcClientConnection conn, - uint32 session_id) + SilcUInt32 session_id) { SilcClientFtpSession session; @@ -989,7 +1005,7 @@ SilcClientFileError silc_client_file_close(SilcClient client, static void silc_client_ftp_resolve_cb(SilcClient client, SilcClientConnection conn, SilcClientEntry *clients, - uint32 clients_count, + SilcUInt32 clients_count, void *context) { SilcPacketContext *packet = (SilcPacketContext *)context; @@ -997,7 +1013,7 @@ static void silc_client_ftp_resolve_cb(SilcClient client, SilcKeyAgreementPayload payload = NULL; SilcClientEntry client_entry; char *hostname; - uint16 port; + SilcUInt16 port; SILC_LOG_DEBUG(("Start")); @@ -1013,12 +1029,17 @@ static void silc_client_ftp_resolve_cb(SilcClient client, } /* Parse the key agreement payload */ - payload = silc_key_agreement_payload_parse(packet->buffer); + payload = silc_key_agreement_payload_parse(packet->buffer->data, + packet->buffer->len); if (!payload) goto out; hostname = silc_key_agreement_get_hostname(payload); port = silc_key_agreement_get_port(payload); + if (!hostname) + port = 0; + if (!port) + hostname = NULL; if (session == SILC_LIST_END || (!hostname && !port)) { /* No session found, create one and let the application know about @@ -1033,8 +1054,8 @@ static void silc_client_ftp_resolve_cb(SilcClient client, silc_dlist_add(conn->ftp_sessions, session); /* Let the application know */ - client->ops->ftp(client, conn, client_entry, - session->session_id, hostname, port); + client->internal->ops->ftp(client, conn, client_entry, + session->session_id, hostname, port); if (hostname && port) { session->hostname = strdup(hostname); @@ -1073,7 +1094,7 @@ void silc_client_ftp(SilcClient client, SilcPacketContext *packet) { SilcClientConnection conn = (SilcClientConnection)sock->user_data; - uint8 type; + SilcUInt8 type; int ret; SILC_LOG_DEBUG(("Start"));