+Tue Oct 30 16:58:14 EST 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Send error message to application if opening file for
+ writing during file transfer fails. Affected file is
+ lib/silcclient/client_ftp.c.
+
+ Remove all file transfer sessions for a client that we're
+ removing from ID cache.
+
+ Affected file is lib/silcclient/client_ftp.c.
+
+ * Fixed silc_net_addr2bin to return correct address. Affected
+ file lib/silcutil/[unix/win32]/silc[unix/win32]net.c.
+
+ * Fixed file transfer session removing on signoff notify.
+ Affected file irssi/src/silc/core/silc-servers.c.
+
+ * Added the SilcClientFileError to be returned in the monitor
+ callback. Added NO_SUCH_FILE and PERMISSION_DENIED errors.
+ Affected file lib/silcclient/silcapi.h.
+
Mon Oct 29 17:43:04 EST 2001 Pekka Riikonen <priikone@silcnet.org>
* Fixed a crash in silc_client_ftp_free_sessions and
{ "file_show_header", "File transfers", 0 },
{ "file_show_line", " $0 $1: $2kB of $3kB ($4%%) - $5kB/s - $6", 7, { 0, 0, 1, 1, 1, 3, 0 } },
{ "file_already_started", "File transfer already started with {nick $0}", 1, { 0 } },
- { "file_error", "Error during file transfer with {nick $0}", 1, { 0 } },
- { "file_close", "File transfer closed with {nick $0}", 1, { 0 } },
+ { "file_error", "Error during file transfer with {nick $0}", 1, { 0 } },
+ { "file_error_no_such_file", "Error during file transfer with {nick $0}: $1: No such file", 2, { 0, 0 } },
+ { "file_error_permission_denied", "Error during file transfer with {nick $0}: Permission denied", 1, { 0 } },
+ { "file_close", "File transfer closed with {nick $0} - $1", 2, { 0, 0 } },
{ NULL, NULL, 0 }
};
SILCTXT_FILE_SHOW_LINE,
SILCTXT_FILE_ALREADY_STARTED,
SILCTXT_FILE_ERROR,
+ SILCTXT_FILE_ERROR_NO_SUCH_FILE,
+ SILCTXT_FILE_ERROR_PERMISSION_DENIED,
SILCTXT_FILE_CLOSED,
};
static void silc_client_file_monitor(SilcClient client,
SilcClientConnection conn,
SilcClientMonitorStatus status,
+ SilcClientFileError error,
uint64 offset,
uint64 filesize,
SilcClientEntry client_entry,
FtpSession ftp;
char fsize[32];
- snprintf(fsize, sizeof(fsize) - 1, "%llu", (filesize / 1024));
+ snprintf(fsize, sizeof(fsize) - 1, "%llu", ((filesize + 1023) / 1024));
silc_dlist_start(server->ftp_sessions);
while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) {
- if (ftp->client_entry == client_entry) {
- ftp->session_id = session_id;
-
+ if (ftp->session_id == session_id) {
if (!ftp->filepath && filepath)
ftp->filepath = strdup(filepath);
break;
return;
if (status == SILC_CLIENT_FILE_MONITOR_ERROR) {
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_FILE_ERROR, client_entry->nickname);
+ if (error == SILC_CLIENT_FILE_NO_SUCH_FILE)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_FILE_ERROR_NO_SUCH_FILE,
+ client_entry->nickname,
+ filepath ? filepath : "[N/A]");
+ else if (error == SILC_CLIENT_FILE_PERMISSION_DENIED)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_FILE_ERROR_PERMISSION_DENIED,
+ client_entry->nickname);
+ else
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_FILE_ERROR, client_entry->nickname);
silc_schedule_task_add(silc_client->schedule, 0,
silc_client_file_close_later, ftp,
1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
SILCTXT_FILE_KEY_EXCHANGE, client_entry->nickname);
}
+ /* Save some transmission data */
+ if (offset && filesize) {
+ unsigned long delta = time(NULL) - ftp->starttime;
+
+ ftp->percent = ((double)offset / (double)filesize) * (double)100.0;
+ if (delta)
+ ftp->kps = (double)((offset / (double)delta) + 1023) / (double)1024;
+ else
+ ftp->kps = (double)(offset + 1023) / (double)1024;
+ ftp->offset = offset;
+ ftp->filesize = filesize;
+ }
+
if (status == SILC_CLIENT_FILE_MONITOR_SEND) {
if (offset == 0) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
silc_dlist_del(server->ftp_sessions, ftp);
}
}
-
- /* Save some transmission data */
- if (offset && filesize) {
- ftp->percent = ((double)offset / (double)filesize) * (double)100.0;
- ftp->kps = (double)((offset / (double)(time(NULL) - ftp->starttime)) +
- 1023) / (double)1024;
- ftp->offset = offset;
- ftp->filesize = filesize;
- }
}
typedef struct {
client_entry = entrys[0];
silc_free(entrys);
- silc_client_file_send(silc_client, conn, silc_client_file_monitor,
- server, client_entry, argv[2]);
+ ftp = silc_calloc(1, sizeof(*ftp));
+ ftp->session_id =
+ silc_client_file_send(silc_client, conn, silc_client_file_monitor,
+ server, client_entry, argv[2]);
+
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_FILE_SEND, client_entry->nickname,
argv[2]);
- ftp = silc_calloc(1, sizeof(*ftp));
ftp->client_entry = client_entry;
ftp->filepath = strdup(argv[2]);
ftp->conn = conn;
ret = silc_client_file_receive(silc_client, conn,
silc_client_file_monitor, server,
- server->current_session->client_entry,
server->current_session->session_id);
if (ret != SILC_CLIENT_FILE_OK) {
if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
silc_dlist_start(server->ftp_sessions);
while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) {
- if (ftp->client_entry == client_entry) {
+ if (ftp->client_entry == client_entry && !ftp->filepath) {
ret = silc_client_file_receive(silc_client, conn,
silc_client_file_monitor, server,
- ftp->client_entry,
ftp->session_id);
if (ret != SILC_CLIENT_FILE_OK) {
if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
goto out;
}
- ret = silc_client_file_close(silc_client, conn,
- server->current_session->session_id);
- if (ret != SILC_CLIENT_FILE_OK) {
- if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_ALREADY_STARTED,
- server->current_session->client_entry->nickname);
- else
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_CLIENT_NA,
- server->current_session->client_entry->nickname);
- } else {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_CLOSED,
- server->current_session->client_entry->nickname);
- }
+ silc_client_file_close(silc_client, conn,
+ server->current_session->session_id);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_FILE_CLOSED,
+ server->current_session->client_entry->nickname,
+ server->current_session->filepath ?
+ server->current_session->filepath : "[N/A]");
+ silc_dlist_del(server->ftp_sessions, server->current_session);
+ silc_free(server->current_session->filepath);
+ silc_free(server->current_session);
+ server->current_session = NULL;
goto out;
}
silc_dlist_start(server->ftp_sessions);
while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) {
if (ftp->client_entry == client_entry) {
- ret = silc_client_file_close(silc_client, conn, ftp->session_id);
- if (ret != SILC_CLIENT_FILE_OK) {
- if (ret == SILC_CLIENT_FILE_ALREADY_STARTED)
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_ALREADY_STARTED,
- client_entry->nickname);
- else
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_CLIENT_NA,
- client_entry->nickname);
- } else {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_FILE_CLOSED,
- client_entry->nickname);
- }
-
+ silc_client_file_close(silc_client, conn, ftp->session_id);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_FILE_CLOSED,
+ client_entry->nickname,
+ ftp->filepath ? ftp->filepath : "[N/A]");
+ if (ftp == server->current_session)
+ server->current_session = NULL;
silc_dlist_del(server->ftp_sessions, ftp);
silc_free(ftp->filepath);
silc_free(ftp);
silc_dlist_del(server->ftp_sessions, ftp);
silc_free(ftp->filepath);
silc_free(ftp);
- break;
}
}
}
typedef unsigned long long uint64;
typedef signed long long int64;
#else
-typedef uint32 uint64; /* XXX Use Windows's own 64 bit types */\r
-typedef int32 int64;\r
-#endif\r
+typedef uint32 uint64; /* XXX Use Windows's own 64 bit types */
+typedef int32 int64;
+#endif
#else
typedef uint32 uint64;
typedef int32 int64;
if (session->monitor)
(*session->monitor)(session->client, session->conn,
SILC_CLIENT_FILE_MONITOR_SEND,
+ SILC_CLIENT_FILE_OK,
data->offset, session->filesize,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
+ SILC_CLIENT_FILE_NO_SUCH_FILE :
+ status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
+ SILC_CLIENT_FILE_PERMISSION_DENIED :
+ SILC_CLIENT_FILE_ERROR), 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
if (session->monitor)
(*session->monitor)(session->client, session->conn,
SILC_CLIENT_FILE_MONITOR_RECEIVE,
+ SILC_CLIENT_FILE_OK,
session->read_offset, session->filesize,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
+ SILC_CLIENT_FILE_NO_SUCH_FILE :
+ status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
+ SILC_CLIENT_FILE_PERMISSION_DENIED :
+ SILC_CLIENT_FILE_ERROR), 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
}
/* Open the actual local file */
- session->fd = silc_file_open(session->filepath, O_RDWR | O_CREAT);
+ session->fd = silc_file_open(session->filepath,
+ 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));
+
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ SILC_CLIENT_FILE_ERROR, 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
if (session->monitor)
(*session->monitor)(session->client, session->conn,
SILC_CLIENT_FILE_MONITOR_RECEIVE,
+ SILC_CLIENT_FILE_OK,
session->read_offset, session->filesize,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
+ SILC_CLIENT_FILE_NO_SUCH_FILE :
+ status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
+ SILC_CLIENT_FILE_PERMISSION_DENIED :
+ SILC_CLIENT_FILE_ERROR), 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
+ SILC_CLIENT_FILE_NO_SUCH_FILE :
+ status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
+ SILC_CLIENT_FILE_PERMISSION_DENIED :
+ SILC_CLIENT_FILE_ERROR), 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
+ SILC_CLIENT_FILE_NO_SUCH_FILE :
+ status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
+ SILC_CLIENT_FILE_PERMISSION_DENIED :
+ SILC_CLIENT_FILE_ERROR), 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT,
+ SILC_CLIENT_FILE_OK, 0, 0,
session->client_entry, session->session_id,
NULL, session->monitor_context);
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ SILC_CLIENT_FILE_ERROR, 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ SILC_CLIENT_FILE_ERROR, 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
return;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT,
+ SILC_CLIENT_FILE_OK, 0, 0,
session->client_entry, session->session_id,
NULL, session->monitor_context);
if (session->sock)
session->sock->user_data = NULL;
silc_client_ftp_session_free(session);
- break;
}
}
}
SilcClientConnection conn,
SilcClientFileMonitor monitor,
void *monitor_context,
- SilcClientEntry client_entry,
uint32 session_id)
{
SilcClientFtpSession session;
session->monitor = monitor;
session->monitor_context = monitor_context;
- session->client_entry = client_entry;
session->conn = conn;
/* If the hostname and port already exists then the remote client did
SILC_STR_UI_XNSTRING(keyagr->data, keyagr->len),
SILC_STR_END);
silc_client_packet_send(client, conn->sock, SILC_PACKET_FTP,
- client_entry->id, SILC_ID_CLIENT, NULL, NULL,
+ session->client_entry->id,
+ SILC_ID_CLIENT, NULL, NULL,
ftp->data, ftp->len, FALSE);
silc_buffer_free(keyagr);
hostname = silc_key_agreement_get_hostname(payload);
port = silc_key_agreement_get_port(payload);
- if (session == SILC_LIST_END) {
+ if (session == SILC_LIST_END || (!hostname && !port)) {
/* No session found, create one and let the application know about
incoming file transfer request. */
session->session_id = ++conn->next_session_id;
session->client = client;
session->conn = conn;
+ session->client_entry = client_entry;
silc_dlist_add(conn->ftp_sessions, session);
/* Let the application know */
goto out;
}
- if (!hostname)
- goto out;
-
session->hostname = strdup(hostname);
session->port = port;
/* Call monitor callback */
if (session->monitor)
(*session->monitor)(session->client, session->conn,
- SILC_CLIENT_FILE_MONITOR_ERROR, 0, 0,
+ SILC_CLIENT_FILE_MONITOR_ERROR,
+ SILC_CLIENT_FILE_ERROR, 0, 0,
session->client_entry, session->session_id,
session->filepath, session->monitor_context);
}
SILC_CLIENT_FILE_MONITOR_RECEIVE,
SILC_CLIENT_FILE_MONITOR_GET,
SILC_CLIENT_FILE_MONITOR_PUT,
- SILC_CLIENT_FILE_MONITOR_CLOSE,
+ SILC_CLIENT_FILE_MONITOR_CLOSED,
SILC_CLIENT_FILE_MONITOR_ERROR,
} SilcClientMonitorStatus;
SILC_CLIENT_FILE_ERROR,
SILC_CLIENT_FILE_UNKNOWN_SESSION,
SILC_CLIENT_FILE_ALREADY_STARTED,
+ SILC_CLIENT_FILE_NO_SUCH_FILE,
+ SILC_CLIENT_FILE_PERMISSION_DENIED,
} SilcClientFileError;
/****f* silcclient/SilcClientAPI/silc_client_file_receive
* typedef void (*SilcClientFileMonitor)(SilcClient client,
* SilcClientConnection conn,
* SilcClientMonitorStatus status,
+ * SilcClientFileError error,
* uint64 offset,
* uint64 filesize,
* SilcClientEntry client_entry,
typedef void (*SilcClientFileMonitor)(SilcClient client,
SilcClientConnection conn,
SilcClientMonitorStatus status,
+ SilcClientFileError error,
uint64 offset,
uint64 filesize,
SilcClientEntry client_entry,
* SilcClientConnection conn,
* SilcClientFileMonitor monitor,
* void *monitor_context,
- * SilcClientEntry client_entry,
* uint32 session_id);
*
* DESCRIPTION
SilcClientConnection conn,
SilcClientFileMonitor monitor,
void *monitor_context,
- SilcClientEntry client_entry,
uint32 session_id);
/****f* silcclient/SilcClientAPI/silc_client_file_close
* binary form.
*
***/
-bool silc_net_addr2bin(const char *addr, unsigned char *bin,
- uint32 bin_len);
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len);
/****f* silcutil/SilcNetAPI/silc_net_addr2bin_ne
*
server.sin_port = htons(port);
/* Convert IP address to network byte order */
- if (ip_addr)
+ if (ip_addr) {
silc_net_addr2bin(ip_addr, (unsigned char *)&server.sin_addr.s_addr, len);
+ }
else
server.sin_addr.s_addr = INADDR_ANY;
/* Converts the IP number string from numbers-and-dots notation to
binary form. */
-bool silc_net_addr2bin(const char *addr, unsigned char *bin,
- uint32 bin_len)
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len)
{
struct in_addr tmp;
int ret;
if (bin_len < 4)
return FALSE;
- SILC_PUT32_LSB(tmp.s_addr, bin);
-
+ memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
return ret != 0;
}
/* Converts the IP number string from numbers-and-dots notation to
binary form. */
-bool silc_net_addr2bin(const char *addr, unsigned char *bin,
- uint32 bin_len)
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len);
{
unsigned long ret;
if (bin_len < 4)
return FALSE;
- SILC_PUT32_LSB(ret, bin);
-
+ memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
return ret != INADDR_NONE;
}