updates.
[silc.git] / lib / silccore / silccommand.c
index e76ad180f69ee55fa415ef82d8f67edd9de47cd8..04f03d6b6a6d1acc02fcbd7e4c22cc50cb6f24fc 100644 (file)
@@ -41,20 +41,23 @@ struct SilcCommandPayloadStruct {
 
 /* Parses command payload returning new command payload structure */
 
-SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer)
+SilcCommandPayload silc_command_payload_parse(const unsigned char *payload,
+                                             uint32 payload_len)
 {
+  SilcBufferStruct buffer;
   SilcCommandPayload new;
   unsigned char args_num;
-  uint16 payload_len;
+  uint16 p_len;
   int ret;
 
   SILC_LOG_DEBUG(("Parsing command payload"));
 
+  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
   new = silc_calloc(1, sizeof(*new));
 
   /* Parse the Command Payload */
-  ret = silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_SHORT(&payload_len),
+  ret = silc_buffer_unformat(&buffer, 
+                            SILC_STR_UI_SHORT(&p_len),
                             SILC_STR_UI_CHAR(&new->cmd),
                             SILC_STR_UI_CHAR(&args_num),
                             SILC_STR_UI_SHORT(&new->ident),
@@ -64,7 +67,7 @@ SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer)
     return NULL;
   }
 
-  if (payload_len != buffer->len) {
+  if (p_len != buffer.len) {
     SILC_LOG_ERROR(("Incorrect command payload in packet, packet dropped"));
     silc_free(new);
     return NULL;
@@ -75,15 +78,15 @@ SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer)
     return NULL;
   }
 
-  silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN);
+  silc_buffer_pull(&buffer, SILC_COMMAND_PAYLOAD_LEN);
   if (args_num) {
-    new->args = silc_argument_payload_parse(buffer, args_num);
+    new->args = silc_argument_payload_parse(buffer.data, buffer.len, args_num);
     if (!new->args) {
       silc_free(new);
       return NULL;
     }
   }
-  silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
+  silc_buffer_push(&buffer, SILC_COMMAND_PAYLOAD_LEN);
 
   return new;
 }
@@ -127,7 +130,7 @@ SilcBuffer silc_command_payload_encode(SilcCommand cmd,
                       SILC_STR_UI_XNSTRING(args->data, args->len),
                       SILC_STR_END);
     silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
-    silc_free(args);
+    silc_buffer_free(args);
   }
 
   return buffer;
@@ -170,7 +173,7 @@ SilcBuffer silc_command_payload_encode_payload(SilcCommandPayload payload)
                       SILC_STR_UI_XNSTRING(args->data, args->len),
                       SILC_STR_END);
     silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
-    silc_free(args);
+    silc_buffer_free(args);
   }
 
   return buffer;
@@ -204,31 +207,32 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
                                           uint16 ident, 
                                           uint32 argc, va_list ap)
 {
-  unsigned char **argv;
+  unsigned char **argv = NULL;
   uint32 *argv_lens = NULL, *argv_types = NULL;
   unsigned char *x;
   uint32 x_len;
   uint32 x_type;
   SilcBuffer buffer;
-  int i, k;
-
-  argv = silc_calloc(argc, sizeof(unsigned char *));
-  argv_lens = silc_calloc(argc, sizeof(uint32));
-  argv_types = silc_calloc(argc, sizeof(uint32));
-
-  for (i = 0, k = 0; i < argc; i++) {
-    x_type = va_arg(ap, uint32);
-    x = va_arg(ap, unsigned char *);
-    x_len = va_arg(ap, uint32);
-
-    if (!x_type || !x || !x_len)
-      continue;
+  int i, k = 0;
 
-    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[k], x, x_len);
-    argv_lens[k] = x_len;
-    argv_types[k] = x_type;
-    k++;
+  if (argc) {
+    argv = silc_calloc(argc, sizeof(unsigned char *));
+    argv_lens = silc_calloc(argc, sizeof(uint32));
+    argv_types = silc_calloc(argc, sizeof(uint32));
+
+    for (i = 0, k = 0; i < argc; i++) {
+      x_type = va_arg(ap, uint32);
+      x = va_arg(ap, unsigned char *);
+      x_len = va_arg(ap, uint32);
+      
+      if (!x_type || !x || !x_len)
+       continue;
+      
+      argv[k] = silc_memdup(x, x_len);
+      argv_lens[k] = x_len;
+      argv_types[k] = x_type;
+      k++;
+    }
   }
 
   buffer = silc_command_payload_encode(cmd, k, argv, argv_lens, 
@@ -255,6 +259,21 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
                                     uint32 argc, ...)
 {
   va_list ap;
+  SilcBuffer buffer;
+
+  va_start(ap, argc);
+  buffer = silc_command_reply_payload_encode_vap(cmd, status, ident, argc, ap);
+  va_end(ap);
+
+  return buffer;
+}
+
+SilcBuffer 
+silc_command_reply_payload_encode_vap(SilcCommand cmd, 
+                                     SilcCommandStatus status,
+                                     uint16 ident, uint32 argc, 
+                                     va_list ap)
+{
   unsigned char **argv;
   uint32 *argv_lens = NULL, *argv_types = NULL;
   unsigned char status_data[2];
@@ -264,16 +283,13 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
   SilcBuffer buffer;
   int i, k;
 
-  va_start(ap, argc);
-
   argc++;
   argv = silc_calloc(argc, sizeof(unsigned char *));
   argv_lens = silc_calloc(argc, sizeof(uint32));
   argv_types = silc_calloc(argc, sizeof(uint32));
 
   SILC_PUT16_MSB(status, status_data);
-  argv[0] = silc_calloc(sizeof(status_data) + 1, sizeof(unsigned char));
-  memcpy(argv[0], status_data, sizeof(status_data));
+  argv[0] = silc_memdup(status_data, sizeof(status_data));
   argv_lens[0] = sizeof(status_data);
   argv_types[0] = 1;
 
@@ -285,8 +301,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
     if (!x_type || !x || !x_len)
       continue;
 
-    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[k], x, x_len);
+    argv[k] = silc_memdup(x, x_len);
     argv_lens[k] = x_len;
     argv_types[k] = x_type;
     k++;
@@ -301,8 +316,6 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
   silc_free(argv_lens);
   silc_free(argv_types);
 
-  va_end(ap);
-
   return buffer;
 }