+Sun Oct 21 20:21:02 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Renamed silc_file_read and silc_file_write to functions
+ silc_file_readfile and silc_file_writefile. Added function
+ silc_file_open and silc_file_close. Affected files
+ lib/silcutil/silcutil.[ch].
+
Thu Oct 18 20:58:13 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
* Resolve the client info when received private message or
int silc_key_agreement(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry, char *hostname,
- int port,
- SilcKeyAgreementCallback *completion,
+ uint16 port, SilcKeyAgreementCallback *completion,
void **context)
{
char portstr[12];
SilcProtocol protocol, void *failure);
int silc_key_agreement(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry, char *hostname,
- int port,
- SilcKeyAgreementCallback *completion,
+ uint16 port, SilcKeyAgreementCallback *completion,
void **context);
#endif
SILC_NICK_REC *silc_nicklist_find(SILC_CHANNEL_REC *channel,
SilcClientEntry client)
{
+ if (!client || !client->nickname)
+ return NULL;
+
return (SILC_NICK_REC *)nicklist_find_unique(CHANNEL(channel),
client->nickname, client);
}
if (server->config && server->config->motd &&
server->config->motd->motd_file) {
/* Send motd */
- motd = silc_file_read(server->config->motd->motd_file, &motd_len);
+ motd = silc_file_readfile(server->config->motd->motd_file, &motd_len);
if (!motd)
goto out;
if (server->config && server->config->motd &&
server->config->motd->motd_file) {
- motd = silc_file_read(server->config->motd->motd_file, &motd_len);
+ motd = silc_file_readfile(server->config->motd->motd_file, &motd_len);
if (!motd)
return;
#include "client.h"
#include "command.h"
#include "command_reply.h"
+#include "client_ftp.h"
#include "idlist.h"
#include "protocol.h"
#include "silcapi.h"
client_notify.c \
client_prvmsg.c \
client_channel.c \
+ client_ftp.c \
command.c \
command_reply.c \
idlist.c \
conn->remote_port = port;
conn->context = context;
conn->pending_commands = silc_dlist_init();
+ conn->ftp_sessions = silc_dlist_init();
/* Add the connection to connections table */
for (i = 0; i < client->conns_count; i++)
for (i = 0; i < client->conns_count; i++)
if (client->conns[i] == conn) {
+
+ silc_idcache_free(conn->client_cache);
+ silc_idcache_free(conn->channel_cache);
+ silc_idcache_free(conn->server_cache);
if (conn->pending_commands)
silc_dlist_uninit(conn->pending_commands);
+ silc_free(conn->remote_host);
+ silc_dlist_uninit(conn->ftp_sessions);
silc_free(conn);
+
client->conns[i] = NULL;
}
}
conn, client->params->connauth_request_secs, 0,
SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
-
-/* Called when file transfer packet is received. This will parse the
- packet and give it to the file transfer protocol. */
-
-void silc_client_ftp(SilcClient client,
- SilcSocketConnection sock,
- SilcPacketContext *packet)
-{
- SilcClientConnection conn = (SilcClientConnection)sock->user_data;
- uint8 type;
- int ret;
-
- /* Parse the payload */
- ret = silc_buffer_unformat(packet->buffer,
- SILC_STR_UI_CHAR(&type),
- SILC_STR_END);
- if (ret == -1)
- return;
-
- /* We support only type number 1 (== SFTP) */
- if (type != 1)
- return;
-
- silc_buffer_pull(packet->buffer, 1);
-
- /* Give it to the file transfer protocol processor. */
- //silc_sftp_client_receive_process(xxx, sock, packet);
-}
typedef struct SilcClientPingStruct SilcClientPing;
typedef struct SilcClientAwayStruct SilcClientAway;
typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
+typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
#include "idlist.h"
#include "command.h"
/* Authentication request context. */
SilcClientConnAuthRequest connauth;
+ /* File transmission sessions */
+ SilcDList ftp_sessions;
+ uint32 next_session_id;
+ SilcClientFtpSession active_session;
+
/* Pointer back to the SilcClient. This object is passed to the application
and the actual client object is accesible through this pointer. */
SilcClient client;
silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
client_entry->id, SILC_ID_CLIENT, NULL, NULL,
buffer->data, buffer->len, FALSE);
- silc_free(buffer);
+ silc_buffer_free(buffer);
}
static int
if (entry) {
if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
- client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
+ entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
silc_free(client_id);
silc_buffer_pull(client_id_list, idp_len);
continue;
silc_client_perform_key_agreement). If TRUE is returned also the
`completion' and `context' arguments must be set by the application. */
int (*key_agreement)(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, char *hostname,
- int port,
- SilcKeyAgreementCallback *completion,
+ SilcClientEntry client_entry, const char *hostname,
+ uint16 port, SilcKeyAgreementCallback *completion,
void **context);
+
+ /* Notifies application that file transfer protocol session is being
+ requested by the remote client indicated by the `client_entry' from
+ the `hostname' and `port'. The `session_id' is the file transfer
+ session and it can be used to either accept or reject the file
+ transfer request, by calling the silc_client_file_receive or
+ silc_client_file_close, respectively. */
+ void (*ftp)(SilcClient client, SilcClientConnection conn,
+ SilcClientEntry client_entry, uint32 session_id,
+ const char *hostname, uint16 port);
} SilcClientOperations;
/***/
SilcConnectionAuthRequest callback,
void *context);
+typedef enum {
+ SILC_CLIENT_FILE_MONITOR_SEND,
+ SILC_CLIENT_FILE_MONITOR_RECEIVE,
+ SILC_CLIENT_FILE_MONITOR_GET,
+ SILC_CLIENT_FILE_MONITOR_PUT,
+ SILC_CLIENT_FILE_MONITOR_CLOSE,
+} SilcClientMonitorStatus;
+
+/****f* silcclient/SilcClientAPI/silc_client_file_receive
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcClientFileMonitor)(SilcClient client,
+ * SilcClientConnection conn,
+ * SilcClientMonitorStatus status,
+ * uint64 offset,
+ * uint64 filesize,
+ * SilcClientEntry client_entry,
+ * uint32 session_id,
+ * const char *filepath,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Monitor callback that is called during the file transmission to
+ * monitor the transmission process. The `status' indicates the current
+ * monitoring process. The `offset' is the currently transmitted amount
+ * of total `filesize'. The `client_entry' indicates the remote client,
+ * and the transmission session ID is the `session_id'. The filename
+ * being transmitted is indicated by the `filepath'.
+ *
+ ***/
+typedef void (*SilcClientFileMonitor)(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientMonitorStatus status,
+ uint64 offset,
+ uint64 filesize,
+ SilcClientEntry client_entry,
+ uint32 session_id,
+ const char *filepath,
+ void *context);
+
+/****f* silcclient/SilcClientAPI/silc_client_file_send
+ *
+ * SYNOPSIS
+ *
+ * void silc_client_file_send(SilcClient client,
+ * SilcClientConnection conn,
+ * SilcClientFileMonitor monitor,
+ * void *monitor_context,
+ * SilcClientEntry client_entry,
+ * const char *filepath);
+ *
+ * DESCRIPTION
+ *
+ * Sends a file indicated by the `filepath' to the remote client
+ * 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,
+ SilcClientEntry client_entry,
+ const char *filepath);
+
+/****f* silcclient/SilcClientAPI/silc_client_file_receive
+ *
+ * SYNOPSIS
+ *
+ * bool silc_client_file_receive(SilcClient client,
+ * SilcClientConnection conn,
+ * SilcClientFileMonitor monitor,
+ * void *monitor_context,
+ * SilcClientEntry client_entry,
+ * uint32 session_id);
+ *
+ * DESCRIPTION
+ *
+ * Receives a file from a client indicated by the `client_entry'. The
+ * `session_id' indicates the file transmission session and it has been
+ * 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.
+ *
+ ***/
+bool silc_client_file_receive(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientFileMonitor monitor,
+ void *monitor_context,
+ SilcClientEntry client_entry,
+ uint32 session_id);
+
+/****f* silcclient/SilcClientAPI/silc_client_file_close
+ *
+ * SYNOPSIS
+ *
+ * bool silc_client_file_close(SilcClient client,
+ * SilcClientConnection conn,
+ * uint32 session_id);
+ *
+ * DESCRIPTION
+ *
+ * Closes file transmission session indicated by the `session_id'.
+ * If file transmission is being conducted it will be aborted
+ * automatically. This function is also used to close the session
+ * after successful file transmission. This function can be used
+ * also to reject incoming file transmission request. Returns TRUE
+ * if the session was closed and FALSE if such session does not exist.
+ *
+ ***/
+bool silc_client_file_close(SilcClient client,
+ SilcClientConnection conn,
+ uint32 session_id);
+
#endif
/* Compare the HMAC's (buffer->tail has the packet's HMAC) */
if (memcmp(mac, buffer->tail, mac_len)) {
SILC_LOG_ERROR(("MAC failed"));
+
+ /* XXX Remove */
+ assert(FALSE);
return FALSE;
}
SILC_STR_END);
/* Save into file */
- if (silc_file_write(filename, buf->data, buf->len)) {
+ if (silc_file_writefile(filename, buf->data, buf->len)) {
silc_buffer_free(buf);
return FALSE;
}
SILC_STR_END);
/* Save into a file */
- if (silc_file_write_mode(filename, buf->data, buf->len, 0600)) {
+ if (silc_file_writefile_mode(filename, buf->data, buf->len, 0600)) {
silc_buffer_free(buf);
return FALSE;
}
unsigned char *cp, *old, *data, byte;
uint32 i, data_len, len;
- old = data = silc_file_read(filename, &data_len);
+ old = data = silc_file_readfile(filename, &data_len);
if (!data)
return FALSE;
unsigned char *cp, *old, *data, byte;
uint32 i, data_len, len;
- old = data = silc_file_read(filename, &data_len);
+ old = data = silc_file_readfile(filename, &data_len);
if (!data)
return FALSE;
char *buffer;
uint32 filelen;
- buffer = silc_file_read(filename, &filelen);
+ buffer = silc_file_readfile(filename, &filelen);
if (buffer == NULL)
return;
#include "silcincludes.h"
-/* Reads a file to a buffer. The allocated buffer is returned. Length of
- the file read is returned to the return_len argument. */
+/* Opens a file indicated by the filename `filename' with flags indicated
+ by the `flags'. */
-char *silc_file_read(const char *filename, uint32 *return_len)
+int silc_file_open(const char *filename, int flags)
{
int fd;
- char *buffer;
- int filelen;
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- if (errno == ENOENT)
- return NULL;
- SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
- return NULL;
- }
+ fd = open(filename, flags);
- filelen = lseek(fd, (off_t)0L, SEEK_END);
- if (filelen < 0) {
- close(fd);
- return NULL;
- }
- if (lseek(fd, (off_t)0L, SEEK_SET) < 0) {
- close(fd);
- return NULL;
- }
+ return fd;
+}
- if (filelen < 0) {
- SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
- close(fd);
- return NULL;
- }
-
- buffer = silc_calloc(filelen + 1, sizeof(char));
-
- if ((read(fd, buffer, filelen)) == -1) {
- memset(buffer, 0, sizeof(buffer));
- close(fd);
- SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
- strerror(errno)));
- return NULL;
- }
+/* Reads data from file descriptor `fd' to `buf'. */
- close(fd);
- buffer[filelen] = EOF;
+int silc_file_read(int fd, unsigned char *buf, uint32 buf_len)
+{
+ return read(fd, (void *)buf, buf_len);
+}
- if (return_len)
- *return_len = filelen;
+/* Writes `buffer' of length of `len' to file descriptor `fd. */
- return buffer;
+int silc_file_write(int fd, const char *buffer, uint32 len)
+{
+ return write(fd, (const void *)buffer, len);
+}
+
+/* Closes file descriptor */
+
+int silc_file_close(int fd)
+{
+ return close(fd);
}
/* Writes a buffer to the file. */
-int silc_file_write(const char *filename, const char *buffer, uint32 len)
+int silc_file_writefile(const char *filename, const char *buffer, uint32 len)
{
int fd;
/* Writes a buffer to the file. If the file is created specific mode is
set to the file. */
-int silc_file_write_mode(const char *filename, const char *buffer,
- uint32 len, int mode)
+int silc_file_writefile_mode(const char *filename, const char *buffer,
+ uint32 len, int mode)
{
int fd;
return 0;
}
+/* Reads a file to a buffer. The allocated buffer is returned. Length of
+ the file read is returned to the return_len argument. */
+
+char *silc_file_readfile(const char *filename, uint32 *return_len)
+{
+ int fd;
+ char *buffer;
+ int filelen;
+
+ fd = silc_file_open(filename, O_RDONLY);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ return NULL;
+ SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
+ return NULL;
+ }
+
+ filelen = lseek(fd, (off_t)0L, SEEK_END);
+ if (filelen < 0) {
+ close(fd);
+ return NULL;
+ }
+ if (lseek(fd, (off_t)0L, SEEK_SET) < 0) {
+ close(fd);
+ return NULL;
+ }
+
+ if (filelen < 0) {
+ SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
+ close(fd);
+ return NULL;
+ }
+
+ buffer = silc_calloc(filelen + 1, sizeof(char));
+
+ if ((read(fd, buffer, filelen)) == -1) {
+ memset(buffer, 0, sizeof(buffer));
+ close(fd);
+ SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
+ strerror(errno)));
+ return NULL;
+ }
+
+ close(fd);
+ buffer[filelen] = EOF;
+
+ if (return_len)
+ *return_len = filelen;
+
+ return buffer;
+}
+
/* Gets line from a buffer. Stops reading when a newline or EOF occurs.
This doesn't remove the newline sign from the destination buffer. The
argument begin is returned and should be passed again for the function. */
#define SILCUTIL_H
/* Prototypes */
-char *silc_file_read(const char *filename, uint32 *return_len);
-int silc_file_write(const char *filename, const char *buffer, uint32 len);
-int silc_file_write_mode(const char *filename, const char *buffer,
- uint32 len, int mode);
+int silc_file_open(const char *filename, int flags);
+int silc_file_read(int fd, unsigned char *buf, uint32 buf_len);
+int silc_file_write(int fd, const char *buffer, uint32 len);
+int silc_file_close(int fd);
+char *silc_file_readfile(const char *filename, uint32 *return_len);
+int silc_file_writefile(const char *filename, const char *buffer, uint32 len);
+int silc_file_writefile_mode(const char *filename, const char *buffer,
+ uint32 len, int mode);
int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin);
int silc_check_line(char *buf);
char *silc_get_time();