Added SILC Server library.
[silc.git] / lib / silcsftp / sftp_client.c
index 29ee2076ecd8972852c5e608bb25dce36e7ebf9b..a60437235562fe9baa86484eb4cd634a314cd6f5 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  sftp_client.c 
+  sftp_client.c
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  Copyright (C) 2001 - 2005 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 "sftp_util.h"
 
 /* Request context. Every request will allocate this context and set
    the correct callback function according the `type' field. */
-typedef struct {
-  uint32 id;
+typedef struct SilcSFTPRequestStruct {
+  SilcUInt32 id;
   SilcSFTPPacket type;
   SilcSFTPStatusCallback status;
   SilcSFTPHandleCallback handle;
@@ -34,35 +34,42 @@ typedef struct {
   SilcSFTPAttrCallback attr;
   SilcSFTPExtendedCallback extended;
   void *context;
+  struct SilcSFTPRequestStruct *next;
 } *SilcSFTPRequest;
 
 /* SFTP client context */
 typedef struct {
-  SilcSocketConnection sock;
-  SilcSFTPSendPacketCallback send_packet;
-  void *send_context;
+  SilcStream stream;
   SilcSFTPVersionCallback version;
   void *version_context;
-  uint32 id;
-  SilcDList requests;
+  SilcUInt32 id;
+  SilcList requests;
+  SilcBuffer packet;
 } *SilcSFTPClient;
 
 /* File handle */
 struct SilcSFTPHandleStruct {
   unsigned char *data;
-  uint32 data_len;
+  SilcUInt32 data_len;
 };
 
+static void silc_sftp_client_receive_process(SilcSFTP context,
+                                            SilcBuffer buffer)
+
 /* Creates SilcSFTPHandle and returns pointer to it. The caller must free
    the context. */
 
 static SilcSFTPHandle silc_sftp_handle_create(unsigned char *data,
-                                             uint32 data_len)
+                                             SilcUInt32 data_len)
 {
   SilcSFTPHandle handle;
 
   handle = silc_calloc(1, sizeof(*handle));
+  if (!handle)
+    return NULL;
   handle->data = silc_calloc(data_len, sizeof(*handle->data));
+  if (!handle->data)
+    return NULL;
   memcpy(handle->data, data, data_len);
   handle->data_len = data_len;
 
@@ -79,9 +86,9 @@ static void silc_sftp_handle_delete(SilcSFTPHandle handle)
 
 /* Returns the handle data of the `handle' to the `data' pointer. */
 
-static void silc_sftp_handle_get(SilcSFTPHandle handle, 
+static void silc_sftp_handle_get(SilcSFTPHandle handle,
                                 const unsigned char **data,
-                                uint32 *data_len)
+                                SilcUInt32 *data_len)
 {
   *data = (const unsigned char *)handle->data;
   *data_len = handle->data_len;
@@ -90,37 +97,41 @@ static void silc_sftp_handle_get(SilcSFTPHandle handle,
 /* General routine to send SFTP packet to the SFTP server. */
 
 static void silc_sftp_send_packet(SilcSFTPClient sftp,
-                                 SilcSFTPPacket type, 
-                                 uint32 len, ...)
+                                 SilcSFTPPacket type,
+                                 SilcUInt32 len, ...)
 {
-  SilcBuffer packet;
+  SilcBuffer tmp;
   va_list vp;
 
   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 server"), packet->data, packet->len);
+  SILC_LOG_HEXDUMP(("SFTP packet to server"), sftp->packet->data,
+                  silc_buffer_len(sftp->packet));
 
   /* Send the packet */
-  (*sftp->send_packet)(sftp->sock, packet, sftp->send_context);
+  silc_stream_write(sftp->stream, sftp->packet->data,
+                   silc_buffer_len(sftp->packet));
 
-  silc_buffer_free(packet);
+  /* Clear packet */
+  silc_buffer_reset(sftp->packet);
 }
 
 /* Finds request by request ID. */
 
-static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp, uint32 id)
+static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp,
+                                             SilcUInt32 id)
 {
   SilcSFTPRequest req;
 
   SILC_LOG_DEBUG(("Finding request ID: %d", id));
 
-  silc_dlist_start(sftp->requests);
-  while ((req = silc_dlist_get(sftp->requests)) != SILC_LIST_END) {
+  silc_list_start(sftp->requests);
+  while ((req = silc_list_get(sftp->requests)) != SILC_LIST_END) {
     if (req->id == id)
       return req;
   }
@@ -135,8 +146,8 @@ static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp, uint32 id)
    operation. The variable argument list includes the status and req->type
    specific data. */
 
-static void silc_sftp_call_request(SilcSFTPClient sftp, 
-                                  SilcSFTPRequest req, 
+static void silc_sftp_call_request(SilcSFTPClient sftp,
+                                  SilcSFTPRequest req,
                                   SilcSFTPPacket type,
                                   SilcSFTPStatus status, ...)
 {
@@ -151,7 +162,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
     {
       /* Data returned */
       unsigned char *data;
-      uint32 data_len;
+      SilcUInt32 data_len;
 
       if (status != SILC_SFTP_STATUS_OK) {
        if (req->data)
@@ -160,12 +171,12 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       }
 
       data = (unsigned char *)va_arg(vp, unsigned char *);
-      data_len = (uint32)va_arg(vp, uint32);
+      data_len = (SilcUInt32)va_arg(vp, SilcUInt32);
 
       if (req->data)
-       (*req->data)((SilcSFTP)sftp, status, (const unsigned char *)data, 
+       (*req->data)((SilcSFTP)sftp, status, (const unsigned char *)data,
                     data_len, req->context);
-    }    
+    }
     break;
 
   case SILC_SFTP_OPEN:
@@ -174,7 +185,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       /* Handle returned */
       SilcSFTPHandle handle;
       unsigned char *hdata;
-      uint32 hdata_len;
+      SilcUInt32 hdata_len;
 
       if (status != SILC_SFTP_STATUS_OK) {
        if (req->handle)
@@ -183,8 +194,13 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       }
 
       hdata = (unsigned char *)va_arg(vp, unsigned char *);
-      hdata_len = (uint32)va_arg(vp, uint32);
+      hdata_len = (SilcUInt32)va_arg(vp, SilcUInt32);
       handle = silc_sftp_handle_create(hdata, hdata_len);
+      if (!handle) {
+       if (req->handle)
+         (*req->handle)((SilcSFTP)sftp, status, NULL, req->context);
+       break;
+      }
 
       if (req->handle)
        (*req->handle)((SilcSFTP)sftp, status, handle, req->context);
@@ -208,7 +224,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       language_tag = (char *)va_arg(vp, char *);
 
       if (req->status)
-       (*req->status)((SilcSFTP)sftp, status, (const char *)message, 
+       (*req->status)((SilcSFTP)sftp, status, (const char *)message,
                       (const char *)language_tag, req->context);
     }
     break;
@@ -229,7 +245,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       attr = (SilcSFTPAttributes)va_arg(vp, SilcSFTPAttributes);
 
       if (req->attr)
-       (*req->attr)((SilcSFTP)sftp, status, (const SilcSFTPAttributes)attr, 
+       (*req->attr)((SilcSFTP)sftp, status, (const SilcSFTPAttributes)attr,
                     req->context);
     }
     break;
@@ -258,7 +274,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
     {
       /* Extended reply returned */
       unsigned char *data;
-      uint32 data_len;
+      SilcUInt32 data_len;
 
       if (status != SILC_SFTP_STATUS_OK) {
        if (req->extended)
@@ -267,10 +283,10 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
       }
 
       data = (unsigned char *)va_arg(vp, unsigned char *);
-      data_len = (uint32)va_arg(vp, uint32);
+      data_len = (SilcUInt32)va_arg(vp, SilcUInt32);
 
       if (req->extended)
-       (*req->extended)((SilcSFTP)sftp, status, (const unsigned char *)data, 
+       (*req->extended)((SilcSFTP)sftp, status, (const unsigned char *)data,
                         data_len, req->context);
     }
     break;
@@ -280,40 +296,126 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
   }
 
   /* Remove this request */
-  silc_dlist_del(sftp->requests, req);
+  silc_list_del(sftp->requests, req);
   silc_free(req);
 
   va_end(vp);
 }
 
-/* Starts SFTP client by associating the socket connection `sock' to the
-   created SFTP client context.  The version callback indicated by the
-   `callback' will be called after the SFTP session has been started
-   and server has returned the version of the protocol.  The SFTP client
-   context is returned in the callback too.  This returns the allocated
-   SFTP client context or NULL on error. */
+/* Handles stream IO */
+
+static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
+                               void *context)
+{
+  SilcSFTPClient sftp = context;
+
+  switch (status) {
+
+  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) {
+       /* EOS */
+       /* XXX */
+       silc_buffer_reset(sftp->packet);
+       return;
+      }
+
+      if (i == -2) {
+       /* Error */
+       /* XXX */
+       silc_buffer_reset(sftp->packet);
+       return FALSE;
+      }
+
+      if (ret == -1) {
+       /* Cannot write now, write later. */
+       silc_buffer_pull(sftp->packet, silc_buffer_len(sftp->packet));
+       return;
+      }
+
+      /* Wrote data */
+      silc_buffer_pull(sftp->packet, ret);
+    }
+    break;
+
+  case SILC_STREAM_CAN_READ:
+    SILC_LOG_DEBUG(("Reading data from stream"));
+
+    /* Make sure we have fair amount of free space in inbuf */
+    if (silc_buffer_taillen(&ps->inbuf) < SILC_PACKET_DEFAULT_SIZE)
+      if (!silc_buffer_realloc(&ps->inbuf, silc_buffer_truelen(&ps->inbuf) +
+                              SILC_PACKET_DEFAULT_SIZE * 2))
+       return;
+
+    /* Read data from stream */
+    ret = silc_stream_read(ps->stream, &ps->inbuf.tail,
+                          silc_buffer_taillen(&ps->inbuf));
+
+    if (ret == 0) {
+      /* EOS */
+      SILC_PACKET_CALLBACK_EOS(ps);
+      silc_buffer_reset(&ps->inbuf);
+      return;
+    }
+
+    if (ret == -2) {
+      /* Error */
+      SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
+      silc_buffer_reset(&ps->inbuf);
+      return;
+    }
+
+    if (ret == -1) {
+      /* Cannot read now, do it later. */
+      silc_buffer_pull(&ps->inbuf, silc_buffer_len(&ps->inbuf));
+      return;
+    }
+
+    /* Read some data */
+    silc_buffer_pull_tail(&ps->inbuf, ret);
+
+    /* Now process the data */
+    silc_sftp_client_receive_process(sftp);
+    break;
+
+  default:
+    break;
+  }
+}
+
+/* Starts SFTP client and returns context for it. */
 
-SilcSFTP silc_sftp_client_start(SilcSocketConnection sock,
-                               SilcSFTPSendPacketCallback send_packet,
-                               void *send_context,
+SilcSFTP silc_sftp_client_start(SilcStream stream,
                                SilcSFTPVersionCallback callback,
                                void *context)
 {
   SilcSFTPClient sftp;
 
-  if (!send_packet)
+  if (!stream)
     return NULL;
 
   sftp = silc_calloc(1, sizeof(*sftp));
-  sftp->sock = sock;
-  sftp->send_packet = send_packet;
-  sftp->send_context = send_context;
+  if (!sftp)
+    return NULL;
+  sftp->stream = stream;
   sftp->version = callback;
   sftp->version_context = context;
-  sftp->requests = silc_dlist_init();
+  silc_list_init(sftp->requests, struct SilcSFTPRequestStruct, next);
+
+  /* We handle the stream now */
+  silc_stream_set_notifier(stream, silc_sftp_client_io, sftp);
 
   /* Send the SFTP session initialization to the server */
-  silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4, 
+  silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4,
                        SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION),
                        SILC_STR_END);
 
@@ -328,31 +430,28 @@ void silc_sftp_client_shutdown(SilcSFTP context)
 {
   SilcSFTPClient sftp = (SilcSFTPClient)context;
 
-  silc_dlist_uninit(sftp->requests);
+  if (sftp->packet)
+    silc_buffer_free(sftp->packet);
   silc_free(sftp);
 }
 
 /* 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_client_receive_process(SilcSFTP context,
-                                     SilcSocketConnection sock,
-                                     SilcPacketContext *packet)
+void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
 {
   SilcSFTPClient sftp = (SilcSFTPClient)context;
   SilcSFTPRequest req;
   SilcSFTPPacket type;
   const unsigned char *payload = NULL;
-  uint32 payload_len;
+  SilcUInt32 payload_len;
   int ret;
   SilcBufferStruct buf;
-  uint32 id;
+  SilcUInt32 id;
 
   SILC_LOG_DEBUG(("Start"));
 
   /* Parse the packet */
-  type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload, 
+  type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
                                 &payload_len);
   if (!type)
     return;
@@ -370,25 +469,25 @@ void silc_sftp_client_receive_process(SilcSFTP context,
                                 SILC_STR_UI_INT(&version),
                                 SILC_STR_END);
       if (ret < 0) {
-       (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0, 
+       (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0,
                         sftp->version_context);
        break;
       }
 
       /* Call the callback */
-      (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version, 
+      (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version,
                       sftp->version_context);
     }
     break;
 
   case SILC_SFTP_STATUS:
     {
-      uint32 status;
+      SilcUInt32 status;
       char *message = NULL, *language_tag = NULL;
 
       SILC_LOG_DEBUG(("Status packet"));
 
-      ret = silc_buffer_unformat(&buf, 
+      ret = silc_buffer_unformat(&buf,
                                 SILC_STR_UI_INT(&id),
                                 SILC_STR_UI_INT(&status),
                                 SILC_STR_END);
@@ -426,13 +525,13 @@ void silc_sftp_client_receive_process(SilcSFTP context,
   case SILC_SFTP_HANDLE:
     {
       unsigned char *handle = NULL;
-      uint32 handle_len;
+      SilcUInt32 handle_len;
 
       SILC_LOG_DEBUG(("Handle packet"));
 
-      ret = silc_buffer_unformat(&buf, 
+      ret = silc_buffer_unformat(&buf,
                                 SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&handle, 
+                                SILC_STR_UI32_NSTRING(&handle,
                                                       &handle_len),
                                 SILC_STR_END);
       if (ret < 0)
@@ -444,7 +543,7 @@ void silc_sftp_client_receive_process(SilcSFTP context,
        break;
 
       /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, 
+      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
                             handle, handle_len);
     }
     break;
@@ -452,11 +551,11 @@ void silc_sftp_client_receive_process(SilcSFTP context,
   case SILC_SFTP_DATA:
     {
       unsigned char *data = NULL;
-      uint32 data_len = 0;
+      SilcUInt32 data_len = 0;
 
       SILC_LOG_DEBUG(("Data packet"));
 
-      ret = silc_buffer_unformat(&buf, 
+      ret = silc_buffer_unformat(&buf,
                                 SILC_STR_UI_INT(&id),
                                 SILC_STR_UI32_NSTRING(&data, &data_len),
                                 SILC_STR_END);
@@ -469,19 +568,19 @@ void silc_sftp_client_receive_process(SilcSFTP context,
        break;
 
       /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, 
+      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
                             data, data_len);
     }
     break;
 
   case SILC_SFTP_NAME:
     {
-      uint32 count;
+      SilcUInt32 count;
       SilcSFTPName name = NULL;
 
       SILC_LOG_DEBUG(("Name packet"));
 
-      ret = silc_buffer_unformat(&buf, 
+      ret = silc_buffer_unformat(&buf,
                                 SILC_STR_UI_INT(&id),
                                 SILC_STR_UI_INT(&count),
                                 SILC_STR_END);
@@ -513,10 +612,12 @@ void silc_sftp_client_receive_process(SilcSFTP context,
 
       SILC_LOG_DEBUG(("Attributes packet"));
 
-      ret = silc_buffer_unformat(&buf, 
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI_XNSTRING(&data, buf.len - 4),
-                                SILC_STR_END);
+      ret =
+       silc_buffer_unformat(&buf,
+                            SILC_STR_UI_INT(&id),
+                            SILC_STR_UI_XNSTRING(&data,
+                                                 silc_buffer_len(&buf) - 4),
+                            SILC_STR_END);
       if (ret < 0)
        break;
 
@@ -525,7 +626,7 @@ void silc_sftp_client_receive_process(SilcSFTP context,
       if (!req)
        break;
 
-      silc_buffer_set(&tmpbuf, data, buf.len - 4);
+      silc_buffer_set(&tmpbuf, data, silc_buffer_len(&buf) - 4);
       attr = silc_sftp_attr_decode(&tmpbuf);
       if (!attr)
        break;
@@ -541,9 +642,9 @@ void silc_sftp_client_receive_process(SilcSFTP context,
 
       SILC_LOG_DEBUG(("Extended reply packet"));
 
-      ret = silc_buffer_unformat(&buf, 
+      ret = silc_buffer_unformat(&buf,
                                 SILC_STR_UI_INT(&id),
-                                SILC_STR_UI_XNSTRING(&data, buf.len - 4),
+                                SILC_STR_UI_XNSTRING(&data, silc_buffer_len(&buf) - 4),
                                 SILC_STR_END);
       if (ret < 0)
        break;
@@ -554,8 +655,8 @@ void silc_sftp_client_receive_process(SilcSFTP context,
        break;
 
       /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, 
-                            data, buf.len - 4);
+      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
+                            data, silc_buffer_len(&buf) - 4);
     }
     break;
 
@@ -564,7 +665,7 @@ void silc_sftp_client_receive_process(SilcSFTP context,
   }
 }
 
-void silc_sftp_open(SilcSFTP sftp, 
+void silc_sftp_open(SilcSFTP sftp,
                    const char *filename,
                    SilcSFTPFileOperation pflags,
                    SilcSFTPAttributes attrs,
@@ -574,27 +675,31 @@ void silc_sftp_open(SilcSFTP sftp,
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
   SilcBuffer attrs_buf;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Open request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_OPEN;
   req->handle = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   attrs_buf = silc_sftp_attr_encode(attrs);
-  len = 4 + 4 + strlen(filename) + 4 + attrs_buf->len;
+  if (!attrs_buf)
+    return;
+  len = 4 + 4 + strlen(filename) + 4 + silc_buffer_len(attrs_buf);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(filename)),
                        SILC_STR_UI32_STRING(filename),
                        SILC_STR_UI_INT(pflags),
-                       SILC_STR_UI_XNSTRING(attrs_buf->data, 
-                                            attrs_buf->len),
+                       SILC_STR_UI_XNSTRING(attrs_buf->data,
+                                            silc_buffer_len(attrs_buf)),
                        SILC_STR_END);
 
   silc_buffer_free(attrs_buf);
@@ -607,55 +712,60 @@ void silc_sftp_close(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Close request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_CLOSE;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   len = 4 + 4 + hdata_len;
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
                        SILC_STR_END);
+  silc_sftp_handle_delete(handle);
 }
 
 void silc_sftp_read(SilcSFTP sftp,
                    SilcSFTPHandle handle,
-                   uint64 offset, 
-                   uint32 len,
+                   SilcUInt64 offset,
+                   SilcUInt32 len,
                    SilcSFTPDataCallback callback,
                    void *context)
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len2 = 0;
+  SilcUInt32 len2 = 0;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Read request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_READ;
   req->data = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   len2 = 4 + 4 + hdata_len + 8 + 4;
 
-  silc_sftp_send_packet(client, req->type, len2, 
+  silc_sftp_send_packet(client, req->type, len2,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
@@ -666,31 +776,33 @@ void silc_sftp_read(SilcSFTP sftp,
 
 void silc_sftp_write(SilcSFTP sftp,
                     SilcSFTPHandle handle,
-                    uint64 offset,
+                    SilcUInt64 offset,
                     const unsigned char *data,
-                    uint32 data_len,
+                    SilcUInt32 data_len,
                     SilcSFTPStatusCallback callback,
                     void *context)
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Write request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_WRITE;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   len = 4 + 4 + hdata_len + 8 + 4 + data_len;
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
@@ -707,20 +819,22 @@ void silc_sftp_remove(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Remove request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_REMOVE;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(filename);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(filename)),
                        SILC_STR_UI32_STRING(filename),
@@ -735,20 +849,22 @@ void silc_sftp_rename(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Rename request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_RENAME;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(oldname) + 4 + strlen(newname);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(oldname)),
                        SILC_STR_UI32_STRING(oldname),
@@ -765,27 +881,31 @@ void silc_sftp_mkdir(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   SilcBuffer attrs_buf;
 
   SILC_LOG_DEBUG(("Mkdir request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_MKDIR;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   attrs_buf = silc_sftp_attr_encode(attrs);
-  len = 4 + 4 + strlen(path) + attrs_buf->len;
+  if (!attrs_buf)
+    return;
+  len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
                        SILC_STR_UI_XNSTRING(attrs_buf->data,
-                                            attrs_buf->len),
+                                            silc_buffer_len(attrs_buf)),
                        SILC_STR_END);
 
   silc_buffer_free(attrs_buf);
@@ -798,20 +918,22 @@ void silc_sftp_rmdir(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Rmdir request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_RMDIR;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -825,20 +947,22 @@ void silc_sftp_opendir(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Opendir request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_OPENDIR;
   req->handle = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -852,23 +976,25 @@ void silc_sftp_readdir(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Readdir request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_READDIR;
   req->name = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   len = 4 + 4 + hdata_len;
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
@@ -882,20 +1008,22 @@ void silc_sftp_stat(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Stat request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_STAT;
   req->attr = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -909,20 +1037,22 @@ void silc_sftp_lstat(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Lstat request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_LSTAT;
   req->attr = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -936,23 +1066,25 @@ void silc_sftp_fstat(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Fstat request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_FSTAT;
   req->attr = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   len = 4 + 4 + hdata_len;
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
@@ -967,27 +1099,31 @@ void silc_sftp_setstat(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   SilcBuffer attrs_buf;
 
   SILC_LOG_DEBUG(("Setstat request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_SETSTAT;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   attrs_buf = silc_sftp_attr_encode(attrs);
-  len = 4 + 4 + strlen(path) + attrs_buf->len;
+  if (!attrs_buf)
+    return;
+  len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
                        SILC_STR_UI_XNSTRING(attrs_buf->data,
-                                            attrs_buf->len),
+                                            silc_buffer_len(attrs_buf)),
                        SILC_STR_END);
 
   silc_buffer_free(attrs_buf);
@@ -1001,30 +1137,34 @@ void silc_sftp_fsetstat(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
   SilcBuffer attrs_buf;
   const unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Fsetstat request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_FSETSTAT;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   silc_sftp_handle_get(handle, &hdata, &hdata_len);
   attrs_buf = silc_sftp_attr_encode(attrs);
-  len = 4 + 4 + hdata_len + attrs_buf->len;
+  if (!attrs_buf)
+    return;
+  len = 4 + 4 + hdata_len + silc_buffer_len(attrs_buf);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(hdata_len),
                        SILC_STR_UI_XNSTRING(hdata, hdata_len),
                        SILC_STR_UI_XNSTRING(attrs_buf->data,
-                                            attrs_buf->len),
+                                            silc_buffer_len(attrs_buf)),
                        SILC_STR_END);
 
   silc_buffer_free(attrs_buf);
@@ -1037,20 +1177,22 @@ void silc_sftp_readlink(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Readlink request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_READLINK;
   req->name = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -1065,20 +1207,22 @@ void silc_sftp_symlink(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Symlink request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_SYMLINK;
   req->status = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(linkpath) + 4 + strlen(targetpath);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(linkpath)),
                        SILC_STR_UI32_STRING(linkpath),
@@ -1094,20 +1238,22 @@ void silc_sftp_realpath(SilcSFTP sftp,
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Realpath request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_REALPATH;
   req->name = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(path);
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(path)),
                        SILC_STR_UI32_STRING(path),
@@ -1117,26 +1263,28 @@ void silc_sftp_realpath(SilcSFTP sftp,
 void silc_sftp_extended(SilcSFTP sftp,
                        const char *request,
                        const unsigned char *data,
-                       uint32 data_len,
+                       SilcUInt32 data_len,
                        SilcSFTPExtendedCallback callback,
                        void *context)
 {
   SilcSFTPClient client = (SilcSFTPClient)sftp;
   SilcSFTPRequest req;
-  uint32 len = 0;
+  SilcUInt32 len = 0;
 
   SILC_LOG_DEBUG(("Extended request"));
 
   req = silc_calloc(1, sizeof(*req));
+  if (!req)
+    return;
   req->id = client->id++;
   req->type = SILC_SFTP_WRITE;
   req->extended = callback;
   req->context = context;
-  silc_dlist_add(client->requests, req);
+  silc_list_add(client->requests, req);
 
   len = 4 + 4 + strlen(request) + data_len;
 
-  silc_sftp_send_packet(client, req->type, len, 
+  silc_sftp_send_packet(client, req->type, len,
                        SILC_STR_UI_INT(req->id),
                        SILC_STR_UI_INT(strlen(request)),
                        SILC_STR_UI32_STRING(request),