/*
- sftp_server.c
+ sftp_server.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 Pekka Riikonen
+ Copyright (C) 2001 - 2007 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
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
#include "silcsftp.h"
+#include "silcsftp_fs.h"
#include "sftp_util.h"
/* SFTP Server context */
typedef struct {
- SilcSocketConnection sock;
- SilcSFTPSendPacketCallback send_packet;
- void *send_context;
+ SilcStream stream;
+ SilcSchedule schedule;
+ SilcSFTPMonitors monitors;
+ SilcSFTPMonitor monitor;
+ void *monitor_context;
SilcSFTPFilesystem fs;
- void *fs_context;
+ SilcBuffer packet;
+ SilcSFTPErrorCallback error;
+ void *context;
} *SilcSFTPServer;
+static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer);
+
/* General routine to send SFTP packet to the SFTP client. */
static void silc_sftp_send_packet(SilcSFTPServer sftp,
- SilcSFTPPacket type,
- uint32 len, ...)
+ SilcSFTPPacket type,
+ SilcUInt32 len, ...)
{
- SilcBuffer packet;
+ SilcBuffer tmp;
va_list vp;
+ int ret;
va_start(vp, len);
- packet = silc_sftp_packet_encode_vp(type, len, vp);
+ tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
va_end(vp);
-
- if (!packet)
+ if (!tmp)
return;
+ sftp->packet = tmp;
- SILC_LOG_HEXDUMP(("SFTP packet to client"), packet->data, packet->len);
+ SILC_LOG_HEXDUMP(("SFTP packet to client"), silc_buffer_data(sftp->packet),
+ silc_buffer_len(sftp->packet));
/* Send the packet */
- (*sftp->send_packet)(sftp->sock, packet, sftp->send_context);
+ while (silc_buffer_len(sftp->packet) > 0) {
+ ret = silc_stream_write(sftp->stream, silc_buffer_data(sftp->packet),
+ silc_buffer_len(sftp->packet));
+ if (ret == -2) {
+ SILC_LOG_ERROR(("Error sending SFTP packet type %d", type));
+ sftp->error((SilcSFTP)sftp, SILC_SFTP_STATUS_NO_CONNECTION,
+ sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+ if (ret == 0) {
+ sftp->error((SilcSFTP)sftp, SILC_SFTP_STATUS_EOF, sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+ if (ret == -1)
+ return;
+
+ silc_buffer_pull(sftp->packet, ret);
+ }
- silc_buffer_free(packet);
+ /* Clear packet */
+ silc_buffer_reset(sftp->packet);
+}
+
+/* Handles stream I/O */
+
+static void silc_sftp_server_io(SilcStream stream, SilcStreamStatus status,
+ void *context)
+{
+ SilcSFTPServer sftp = context;
+ unsigned char inbuf[33792];
+ SilcBufferStruct packet;
+ int ret;
+
+ switch (status) {
+ case SILC_STREAM_CAN_READ:
+ SILC_LOG_DEBUG(("Reading data from stream"));
+
+ /* Read data from stream */
+ ret = silc_stream_read(stream, inbuf, sizeof(inbuf));
+ if (ret <= 0) {
+ if (ret == 0)
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
+ if (ret == -2)
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
+ return;
+ }
+
+ /* Now process the SFTP packet */
+ silc_buffer_set(&packet, inbuf, ret);
+ silc_sftp_server_receive_process(context, &packet);
+ break;
+
+ case SILC_STREAM_CAN_WRITE:
+ if (!silc_buffer_headlen(sftp->packet))
+ return;
+
+ SILC_LOG_DEBUG(("Writing pending data to stream"));
+
+ /* Write pending data to stream */
+ silc_buffer_push(sftp->packet, silc_buffer_headlen(sftp->packet));
+ while (silc_buffer_len(sftp->packet) > 0) {
+ ret = silc_stream_write(stream, sftp->packet->data,
+ silc_buffer_len(sftp->packet));
+ if (ret == 0) {
+ sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+
+ if (ret == -2) {
+ sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
+ silc_buffer_reset(sftp->packet);
+ return;
+ }
+
+ if (ret == -1)
+ return;
+
+ /* Wrote data */
+ silc_buffer_pull(sftp->packet, ret);
+ }
+ break;
+
+ default:
+ break;
+ }
}
/* Sends error to the client */
static void silc_sftp_send_error(SilcSFTPServer sftp,
SilcSFTPStatus status,
- uint32 id)
+ SilcUInt32 id)
{
SILC_LOG_DEBUG(("Send error %d", status));
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
int mlen, llen;
SILC_LOG_DEBUG(("Status callback"));
SILC_LOG_DEBUG(("Request ID: %d", id));
-
+
if (!message)
message = "";
if (!language_tag)
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
unsigned char *hdata;
- uint32 hdata_len;
+ SilcUInt32 hdata_len;
SILC_LOG_DEBUG(("Handle callback"));
SILC_LOG_DEBUG(("Request ID: %d", id));
return;
}
- hdata = server->fs->sftp_encode_handle(server->fs_context, sftp,
- handle, &hdata_len);
+ hdata = server->fs->fs->sftp_encode_handle(server->fs->fs_context, sftp,
+ handle, &hdata_len);
if (!hdata) {
silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
return;
static void silc_sftp_server_data(SilcSFTP sftp,
SilcSFTPStatus status,
const unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
SILC_LOG_DEBUG(("Data callback"));
SILC_LOG_DEBUG(("Request ID: %d", id));
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
SilcBuffer namebuf;
SILC_LOG_DEBUG(("Name callback"));
return;
}
- silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + namebuf->len,
+ silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + silc_buffer_len(namebuf),
SILC_STR_UI_INT(id),
- SILC_STR_UI_XNSTRING(namebuf->data, namebuf->len),
+ SILC_STR_DATA(silc_buffer_data(namebuf),
+ silc_buffer_len(namebuf)),
SILC_STR_END);
}
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
SilcBuffer attr_buf;
SILC_LOG_DEBUG(("Attr callback"));
}
attr_buf = silc_sftp_attr_encode(attrs);
+ if (!attr_buf) {
+ silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
+ return;
+ }
- silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + attr_buf->len,
+ silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + silc_buffer_len(attr_buf),
SILC_STR_UI_INT(id),
- SILC_STR_UI_XNSTRING(attr_buf->data, attr_buf->len),
+ SILC_STR_DATA(silc_buffer_data(attr_buf),
+ silc_buffer_len(attr_buf)),
SILC_STR_END);
silc_buffer_free(attr_buf);
static void silc_sftp_server_extended(SilcSFTP sftp,
SilcSFTPStatus status,
const unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
void *context)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
- uint32 id = (uint32)context;
+ SilcUInt32 id = SILC_PTR_TO_32(context);
SILC_LOG_DEBUG(("Extended callback"));
SILC_LOG_DEBUG(("Request ID: %d", id));
SILC_STR_END);
}
-/* Starts SFTP server by associating the socket connection `sock' to the
- created SFTP server context. This function returns the allocated
- SFTP client context or NULL on error. The `send_packet' is called
+/* Starts SFTP server and returns context to it. This function returns the
+ allocated SFTP client context or NULL on error. The `send_packet' is called
by the library when it needs to send a packet. The `fs' is the
structure containing filesystem access callbacks. */
-SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
- SilcSFTPSendPacketCallback send_packet,
- void *send_context,
- SilcSFTPFilesystem fs,
- void *fs_context)
+SilcSFTP silc_sftp_server_start(SilcStream stream,
+ SilcSchedule schedule,
+ SilcSFTPErrorCallback error_cb,
+ void *context,
+ SilcSFTPFilesystem fs)
{
SilcSFTPServer server;
server = silc_calloc(1, sizeof(*server));
- server->sock = sock;
- server->send_packet = send_packet;
- server->send_context = send_context;
+ if (!server)
+ return NULL;
+ server->stream = stream;
+ server->schedule = schedule;
+ server->error = error_cb;
+ server->context = context;
server->fs = fs;
- server->fs_context = fs_context;
+
+ /* We handle the stream now */
+ silc_stream_set_notifier(stream, schedule, silc_sftp_server_io, server);
SILC_LOG_DEBUG(("Starting SFTP server %p", server));
SILC_LOG_DEBUG(("Stopping SFTP server %p", server));
+ silc_stream_set_notifier(server->stream, server->schedule, NULL, NULL);
+ if (server->packet)
+ silc_buffer_free(server->packet);
silc_free(server);
}
+/* Sets monitor callback */
+
+void silc_sftp_server_set_monitor(SilcSFTP sftp,
+ SilcSFTPMonitors monitors,
+ SilcSFTPMonitor monitor,
+ void *context)
+{
+ SilcSFTPServer server = (SilcSFTPServer)sftp;
+ server->monitors = monitors;
+ server->monitor = monitor;
+ server->monitor_context = context;
+}
+
/* Function that is called to process the incmoing SFTP packet. */
-/* XXX Some day this will go away and we have automatic receive callbacks
- for SilcSocketConnection API or SilcPacketContext API. */
-void silc_sftp_server_receive_process(SilcSFTP sftp,
- SilcSocketConnection sock,
- SilcPacketContext *packet)
+static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer)
{
SilcSFTPServer server = (SilcSFTPServer)sftp;
SilcSFTPPacket type;
char *filename = NULL, *path = NULL;
- const unsigned char *payload = NULL;
- uint32 payload_len;
+ unsigned char *payload = NULL;
+ SilcUInt32 payload_len;
int ret;
SilcBufferStruct buf;
- uint32 id;
+ SilcUInt32 id;
SilcSFTPAttributes attrs;
SilcSFTPHandle handle;
+ SilcSFTPMonitorDataStruct mdata;
SILC_LOG_DEBUG(("Start"));
/* Parse the packet */
- type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
- &payload_len);
- if (!type)
+ type = silc_sftp_packet_decode(buffer, &payload, &payload_len);
+ if (type <= 0)
return;
- silc_buffer_set(&buf, (unsigned char *)payload, payload_len);
+ silc_buffer_set(&buf, payload, payload_len);
+
+ memset(&mdata, 0, sizeof(mdata));
switch (type) {
+ case SILC_SFTP_READ:
+ {
+ unsigned char *hdata;
+ SilcUInt32 hdata_len;
+ SilcUInt64 offset;
+ SilcUInt32 len;
+
+ SILC_LOG_DEBUG(("Read request"));
+
+ ret = silc_buffer_unformat(&buf,
+ SILC_STR_UI_INT(&id),
+ SILC_STR_UI32_NSTRING(&hdata,
+ &hdata_len),
+ SILC_STR_UI_INT64(&offset),
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END);
+ if (ret < 0)
+ goto failure;
+
+ /* Get the handle */
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
+ if (!handle) {
+ silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
+ break;
+ }
+
+ /* Read operation */
+ server->fs->fs->sftp_read(server->fs->fs_context, sftp,
+ handle, offset, len,
+ silc_sftp_server_data, SILC_32_TO_PTR(id));
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_READ && server->monitor) {
+ mdata.offset = offset;
+ mdata.data_len = len;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_READ, &mdata,
+ server->monitor_context);
+ }
+ }
+ break;
+
+ case SILC_SFTP_WRITE:
+ {
+ unsigned char *hdata;
+ SilcUInt32 hdata_len;
+ SilcUInt64 offset;
+ unsigned char *data;
+ SilcUInt32 data_len;
+
+ SILC_LOG_DEBUG(("Read request"));
+
+ ret = silc_buffer_unformat(&buf,
+ SILC_STR_UI_INT(&id),
+ SILC_STR_UI32_NSTRING(&hdata,
+ &hdata_len),
+ SILC_STR_UI_INT64(&offset),
+ SILC_STR_UI32_NSTRING(&data,
+ &data_len),
+ SILC_STR_END);
+ if (ret < 0)
+ goto failure;
+
+ /* Get the handle */
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
+ if (!handle) {
+ silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
+ break;
+ }
+
+ /* Write operation */
+ server->fs->fs->sftp_write(server->fs->fs_context, sftp, handle, offset,
+ (const unsigned char *)data, data_len,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_WRITE && server->monitor) {
+ mdata.offset = offset;
+ mdata.data_len = data_len;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_WRITE, &mdata,
+ server->monitor_context);
+ }
+ }
+ break;
+
case SILC_SFTP_INIT:
{
SilcSFTPVersion version;
if (ret < 0)
break;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_INIT && server->monitor) {
+ mdata.version = version;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_INIT, &mdata,
+ server->monitor_context);
+ }
+
silc_sftp_send_packet(server, SILC_SFTP_VERSION, 4,
SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION),
SILC_STR_END);
{
SilcSFTPFileOperation pflags;
unsigned char *attr_buf;
- uint32 attr_len = 0;
+ SilcUInt32 attr_len = 0;
SilcBufferStruct tmpbuf;
SILC_LOG_DEBUG(("Open request"));
SILC_STR_UI_INT(&id),
SILC_STR_UI32_STRING_ALLOC(&filename),
SILC_STR_UI_INT(&pflags),
- SILC_STR_UI32_NSTRING(&attr_buf,
+ SILC_STR_UI32_NSTRING(&attr_buf,
&attr_len),
SILC_STR_END);
if (ret < 0)
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
+ }
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_OPEN && server->monitor) {
+ mdata.name = filename;
+ mdata.pflags = pflags;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPEN, &mdata,
+ server->monitor_context);
}
/* Open operation */
- server->fs->sftp_open(server->fs_context, sftp, filename, pflags,
- attrs, silc_sftp_server_handle, (void *)id);
+ server->fs->fs->sftp_open(server->fs->fs_context, sftp, filename, pflags,
+ attrs, silc_sftp_server_handle,
+ SILC_32_TO_PTR(id));
silc_free(filename);
silc_sftp_attr_free(attrs);
case SILC_SFTP_CLOSE:
{
unsigned char *hdata;
- uint32 hdata_len;
+ SilcUInt32 hdata_len;
SILC_LOG_DEBUG(("Close request"));
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
+ SILC_STR_UI32_NSTRING(&hdata,
&hdata_len),
SILC_STR_END);
if (ret < 0)
goto failure;
/* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
if (!handle) {
silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
break;
}
- /* Close operation */
- server->fs->sftp_close(server->fs_context, sftp, handle,
- silc_sftp_server_status, (void *)id);
- }
- break;
-
- case SILC_SFTP_READ:
- {
- unsigned char *hdata;
- uint32 hdata_len;
- uint64 offset;
- uint32 len;
-
- SILC_LOG_DEBUG(("Read request"));
-
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
- &hdata_len),
- SILC_STR_UI_INT64(&offset),
- SILC_STR_UI_INT(&len),
- SILC_STR_END);
- if (ret < 0)
- goto failure;
-
- /* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
- if (!handle) {
- silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
- break;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_CLOSE && server->monitor) {
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_CLOSE, &mdata,
+ server->monitor_context);
}
- /* Read operation */
- server->fs->sftp_read(server->fs_context, sftp, handle, offset, len,
- silc_sftp_server_data, (void *)id);
- }
- break;
-
- case SILC_SFTP_WRITE:
- {
- unsigned char *hdata;
- uint32 hdata_len;
- uint64 offset;
- unsigned char *data;
- uint32 data_len;
-
- SILC_LOG_DEBUG(("Read request"));
-
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
- &hdata_len),
- SILC_STR_UI_INT64(&offset),
- SILC_STR_UI32_NSTRING(&data,
- &data_len),
- SILC_STR_END);
- if (ret < 0)
- goto failure;
-
- /* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
- if (!handle) {
- silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
- break;
- }
+ /* Close operation */
+ server->fs->fs->sftp_close(server->fs->fs_context, sftp, handle,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
- /* Write operation */
- server->fs->sftp_write(server->fs_context, sftp, handle, offset,
- (const unsigned char *)data, data_len,
- silc_sftp_server_status, (void *)id);
}
break;
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_REMOVE && server->monitor) {
+ mdata.name = filename;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_REMOVE, &mdata,
+ server->monitor_context);
+ }
+
/* Remove operation */
- server->fs->sftp_remove(server->fs_context, sftp, filename,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_remove(server->fs->fs_context, sftp, filename,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
silc_free(filename);
}
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_RENAME && server->monitor) {
+ mdata.name = filename;
+ mdata.name2 = newname;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_RENAME, &mdata,
+ server->monitor_context);
+ }
+
/* Rename operation */
- server->fs->sftp_rename(server->fs_context, sftp, filename, newname,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_rename(server->fs->fs_context, sftp,
+ filename, newname,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
silc_free(filename);
silc_free(newname);
case SILC_SFTP_MKDIR:
{
unsigned char *attr_buf;
- uint32 attr_len = 0;
+ SilcUInt32 attr_len = 0;
SilcBufferStruct tmpbuf;
SILC_LOG_DEBUG(("Mkdir request"));
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
+ }
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_MKDIR && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_MKDIR, &mdata,
+ server->monitor_context);
}
/* Mkdir operation */
- server->fs->sftp_mkdir(server->fs_context, sftp, path, attrs,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_mkdir(server->fs->fs_context, sftp, path, attrs,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
silc_sftp_attr_free(attrs);
silc_free(path);
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_RMDIR && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_RMDIR, &mdata,
+ server->monitor_context);
+ }
+
/* Rmdir operation */
- server->fs->sftp_rmdir(server->fs_context, sftp, path,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_rmdir(server->fs->fs_context, sftp, path,
+ silc_sftp_server_status, SILC_32_TO_PTR(id));
silc_free(path);
}
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_OPENDIR && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPENDIR, &mdata,
+ server->monitor_context);
+ }
+
/* Opendir operation */
- server->fs->sftp_opendir(server->fs_context, sftp, path,
- silc_sftp_server_handle, (void *)id);
+ server->fs->fs->sftp_opendir(server->fs->fs_context, sftp, path,
+ silc_sftp_server_handle, SILC_32_TO_PTR(id));
silc_free(path);
}
case SILC_SFTP_READDIR:
{
unsigned char *hdata;
- uint32 hdata_len;
+ SilcUInt32 hdata_len;
SILC_LOG_DEBUG(("Readdir request"));
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
+ SILC_STR_UI32_NSTRING(&hdata,
&hdata_len),
SILC_STR_END);
if (ret < 0)
goto failure;
/* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
if (!handle) {
silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
break;
}
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_READDIR && server->monitor) {
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_READDIR, &mdata,
+ server->monitor_context);
+ }
+
/* Readdir operation */
- server->fs->sftp_readdir(server->fs_context, sftp, handle,
- silc_sftp_server_name, (void *)id);
+ server->fs->fs->sftp_readdir(server->fs->fs_context, sftp, handle,
+ silc_sftp_server_name, SILC_32_TO_PTR(id));
}
break;
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_STAT && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_STAT, &mdata,
+ server->monitor_context);
+ }
+
/* Stat operation */
- server->fs->sftp_stat(server->fs_context, sftp, path,
- silc_sftp_server_attr, (void *)id);
+ server->fs->fs->sftp_stat(server->fs->fs_context, sftp, path,
+ silc_sftp_server_attr, SILC_32_TO_PTR(id));
silc_free(path);
}
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_LSTAT && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_LSTAT, &mdata,
+ server->monitor_context);
+ }
+
/* Lstat operation */
- server->fs->sftp_lstat(server->fs_context, sftp, path,
- silc_sftp_server_attr, (void *)id);
+ server->fs->fs->sftp_lstat(server->fs->fs_context, sftp, path,
+ silc_sftp_server_attr, SILC_32_TO_PTR(id));
silc_free(path);
}
case SILC_SFTP_FSTAT:
{
unsigned char *hdata;
- uint32 hdata_len;
+ SilcUInt32 hdata_len;
SILC_LOG_DEBUG(("Fstat request"));
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
+ SILC_STR_UI32_NSTRING(&hdata,
&hdata_len),
SILC_STR_END);
if (ret < 0)
goto failure;
/* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
if (!handle) {
silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
break;
}
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_FSTAT && server->monitor) {
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSTAT, &mdata,
+ server->monitor_context);
+ }
+
/* Fstat operation */
- server->fs->sftp_fstat(server->fs_context, sftp, handle,
- silc_sftp_server_attr, (void *)id);
+ server->fs->fs->sftp_fstat(server->fs->fs_context, sftp, handle,
+ silc_sftp_server_attr, SILC_32_TO_PTR(id));
}
break;
case SILC_SFTP_SETSTAT:
{
unsigned char *attr_buf;
- uint32 attr_len = 0;
+ SilcUInt32 attr_len = 0;
SilcBufferStruct tmpbuf;
SILC_LOG_DEBUG(("Setstat request"));
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
+ }
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_SETSTAT && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_SETSTAT, &mdata,
+ server->monitor_context);
}
/* Setstat operation */
- server->fs->sftp_setstat(server->fs_context, sftp, path, attrs,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_setstat(server->fs->fs_context, sftp, path, attrs,
+ silc_sftp_server_status,
+ SILC_32_TO_PTR(id));
silc_sftp_attr_free(attrs);
silc_free(path);
case SILC_SFTP_FSETSTAT:
{
unsigned char *hdata, *attr_buf;
- uint32 hdata_len, attr_len = 0;
+ SilcUInt32 hdata_len, attr_len = 0;
SilcBufferStruct tmpbuf;
SILC_LOG_DEBUG(("Fsetstat request"));
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_INT(&id),
- SILC_STR_UI32_NSTRING(&hdata,
+ SILC_STR_UI32_NSTRING(&hdata,
&hdata_len),
SILC_STR_UI32_NSTRING(&attr_buf,
&attr_len),
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
}
/* Get the handle */
- handle = server->fs->sftp_get_handle(server->fs_context, sftp,
- (const unsigned char *)hdata,
- hdata_len);
+ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
+ (const unsigned char *)hdata,
+ hdata_len);
if (!handle) {
silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
break;
}
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_FSETSTAT && server->monitor) {
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSETSTAT, &mdata,
+ server->monitor_context);
+ }
+
/* Fsetstat operation */
- server->fs->sftp_fsetstat(server->fs_context, sftp, handle, attrs,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_fsetstat(server->fs->fs_context, sftp,
+ handle, attrs,
+ silc_sftp_server_status,
+ SILC_32_TO_PTR(id));
silc_sftp_attr_free(attrs);
}
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_READLINK && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_READLINK, &mdata,
+ server->monitor_context);
+ }
+
/* Readlink operation */
- server->fs->sftp_readlink(server->fs_context, sftp, path,
- silc_sftp_server_name, (void *)id);
+ server->fs->fs->sftp_readlink(server->fs->fs_context, sftp, path,
+ silc_sftp_server_name, SILC_32_TO_PTR(id));
silc_free(path);
}
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_SYMLINK && server->monitor) {
+ mdata.name = path;
+ mdata.name2 = target;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_SYMLINK, &mdata,
+ server->monitor_context);
+ }
+
/* Symlink operation */
- server->fs->sftp_symlink(server->fs_context, sftp, path, target,
- silc_sftp_server_status, (void *)id);
+ server->fs->fs->sftp_symlink(server->fs->fs_context, sftp, path, target,
+ silc_sftp_server_status,
+ SILC_32_TO_PTR(id));
silc_free(path);
silc_free(target);
if (ret < 0)
goto failure;
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_REALPATH && server->monitor) {
+ mdata.name = path;
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_REALPATH, &mdata,
+ server->monitor_context);
+ }
+
/* Realpath operation */
- server->fs->sftp_realpath(server->fs_context, sftp, path,
- silc_sftp_server_name, (void *)id);
+ server->fs->fs->sftp_realpath(server->fs->fs_context, sftp, path,
+ silc_sftp_server_name, SILC_32_TO_PTR(id));
silc_free(path);
}
{
char *request = NULL;
unsigned char *data;
- uint32 data_len;
+ SilcUInt32 data_len;
SILC_LOG_DEBUG(("Extended request"));
data_len = 8 + strlen(request);
silc_buffer_pull(&buf, data_len);
ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_XNSTRING(&data, buf.len),
+ SILC_STR_DATA(&data, silc_buffer_len(&buf)),
SILC_STR_END);
if (ret < 0)
goto failure;
- data_len = buf.len;
+ data_len = silc_buffer_len(&buf);
+
+ /* Call monitor */
+ if (server->monitors & SILC_SFTP_MONITOR_EXTENDED && server->monitor) {
+ (*server->monitor)(sftp, SILC_SFTP_MONITOR_EXTENDED, &mdata,
+ server->monitor_context);
+ }
/* Extended operation */
- server->fs->sftp_extended(server->fs_context, sftp,
- request, data, data_len,
- silc_sftp_server_extended, (void *)id);
+ server->fs->fs->sftp_extended(server->fs->fs_context, sftp,
+ request, data, data_len,
+ silc_sftp_server_extended,
+ SILC_32_TO_PTR(id));
silc_free(request);
}