]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_sbuf_getdelim() and getline().
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 23 Jan 2013 22:24:59 +0000 (23:24 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 23 Jan 2013 22:24:59 +0000 (23:24 +0100)
NEWS
lib/Makefile.am
lib/includes/gnutls/sbuf.h
lib/libgnutls.map
lib/sbuf.c
lib/sbuf.h [new file with mode: 0644]
lib/sbuf_getline.c [new file with mode: 0644]
tests/mini-sbuf.c

diff --git a/NEWS b/NEWS
index 15ad84a9bd7439b74781a3ef5729fbc6ddc85da3..6b1820b80c06df1f88292502661a1ce934d780a6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -30,7 +30,10 @@ gnutls_record_get_random_padding_status: Added
 gnutls_sbuf_deinit: Added
 gnutls_sbuf_init: Added
 gnutls_sbuf_flush: Added
-gnutls_sbuf_queue: Added
+gnutls_sbuf_write: Added
+gnutls_sbuf_getdelim: Added
+gnutls_sbuf_read: Added
+gnutls_sbuf_handshake: Added
 gnutls_x509_crt_set_dn: Added
 gnutls_x509_crt_set_issuer_dn: Added
 gnutls_x509_crq_set_dn: Added
index 816b3c527188d1f071b2e6ee1b753d01a27eb500..70d23f3a730953fd3c8453608d466f36712beb02 100644 (file)
@@ -78,7 +78,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \
        gnutls_rsa_export.c gnutls_helper.c gnutls_supplemental.c       \
        random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c           \
        gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \
-       crypto-backend.c verify-tofu.c pin.c tpm.c sbuf.c
+       crypto-backend.c verify-tofu.c pin.c tpm.c sbuf.c sbuf_getline.c
 
 if ENABLE_PKCS11
 COBJECTS += pkcs11.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c
index 2f755cf55b757a889f1d1976f84ba7119b976fca..cb9100d0eb7b406381bc5e5b3cd658639def5024 100644 (file)
@@ -40,6 +40,11 @@ ssize_t gnutls_sbuf_flush (gnutls_sbuf_t sb);
 int gnutls_sbuf_handshake(gnutls_sbuf_t sb);
 ssize_t gnutls_sbuf_read(gnutls_sbuf_t sb, void* data, size_t data_size);
 
+ssize_t
+gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter);
+
+#define gnutls_sbuf_getline(sbuf, ptr, n) gnutls_sbuf_getdelim(sbuf, ptr, n, '\n')
+
 #define GNUTLS_SBUF_QUEUE_FLUSHES 1
 int gnutls_sbuf_init (gnutls_sbuf_t * sb, gnutls_session_t session,
                       unsigned int flags);
index 8df827aff2e8f3936ab45ad5ed25054118509cf2..ab8a6ce7d2e53513f55818d44eea84bb48326e45 100644 (file)
@@ -880,7 +880,7 @@ GNUTLS_3_1_0 {
        gnutls_sbuf_deinit;
        gnutls_sbuf_init;
        gnutls_sbuf_flush;
-       gnutls_sbuf_queue;
+       gnutls_sbuf_read;
        gnutls_x509_crt_set_dn;
        gnutls_x509_crq_set_dn;
        gnutls_x509_crt_set_issuer_dn;
@@ -889,6 +889,8 @@ GNUTLS_3_1_0 {
        gnutls_range_send_message;
        gnutls_record_set_max_empty_records;
        gnutls_record_send_range;
+       gnutls_sbuf_getdelim;
+       gnutls_sbuf_write;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
index 8871cee85472685ee8695212c211237615c7175f..62bbd10768911cbdd53366d6136c5f918c7c12db 100644 (file)
@@ -5,7 +5,7 @@
  *
  * This file is part of GnuTLS.
  *
- * The libdane library is free software; you can redistribute it
+ * The gnutls library is free software; you can redistribute it
  * and/or modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
 #include <gnutls_num.h>
-#include <gnutls_str.h>
 #include <gnutls/sbuf.h>
 
-struct gnutls_sbuf_st {
-  gnutls_session_t session;
-  gnutls_buffer_st buf;
-  unsigned int flags;
-};
+#include <sbuf.h>
 
 /**
  * gnutls_init:
diff --git a/lib/sbuf.h b/lib/sbuf.h
new file mode 100644 (file)
index 0000000..70e8939
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef SBUF_H
+# define SBUF_H
+
+#include <gnutls_str.h>
+
+struct gnutls_sbuf_st {
+  gnutls_session_t session;
+  gnutls_buffer_st buf;
+  unsigned int flags;
+};
+
+#endif
diff --git a/lib/sbuf_getline.c b/lib/sbuf_getline.c
new file mode 100644 (file)
index 0000000..932d9dc
--- /dev/null
@@ -0,0 +1,127 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+ * Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2012 Free Software
+ * Foundation, Inc.
+ *
+ * This file is part of GnuTLS.
+ *
+ * The gnutls library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/* Ported from glibc by Simon Josefsson. */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls/sbuf.h>
+#include <sbuf.h>
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+/**
+ * gnutls_sbuf_get_delim:
+ * @sb: is a #gnutls_sbuf_t structure.
+ * @lineptr: a pointer.
+ * @n: The size of @lineptr.
+ * @delimiter: The delimiter to stop reading at.
+ *
+ * Read up to (and including) a @delimiter from &sb into *LINEPTR (and
+ * NUL-terminate it).  @lineptr is a pointer returned from gnutls_malloc() 
+ * (or %NULL), pointing to @n characters of space.  It is realloc'ed as
+ * necessary.  
+ *
+ * Only fatal errors are returned by this function.
+ *
+ * Returns the number of characters read (not including
+ * the null terminator), or a negative error code on error. 
+ *
+ * Since: 3.1.7
+ **/
+ssize_t
+gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter)
+{
+  ssize_t result;
+  size_t cur_len = 0;
+
+  if (lineptr == NULL || n == NULL || sbuf == NULL)
+    {
+      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+    }
+
+  if (*lineptr == NULL || *n == 0)
+    {
+      char *new_lineptr;
+      *n = 120;
+      new_lineptr = (char *) gnutls_realloc (*lineptr, *n);
+      if (new_lineptr == NULL)
+        {
+          result = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+          goto fail;
+        }
+      *lineptr = new_lineptr;
+    }
+
+  for (;;)
+    {
+      char c;
+      
+      result = gnutls_sbuf_read(sbuf, &c, 1);
+      if (result < 0)
+        {
+          gnutls_assert();
+          break;
+        }
+
+      /* Make enough space for len+1 (for final NUL) bytes.  */
+      if (cur_len + 1 >= *n)
+        {
+          size_t needed_max =
+            SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+          size_t needed = 2 * *n + 1;   /* Be generous. */
+          char *new_lineptr;
+
+          if (needed_max < needed)
+            needed = needed_max;
+          if (cur_len + 1 >= needed)
+            {
+              result = gnutls_assert_val(GNUTLS_E_LARGE_PACKET);
+              goto fail;
+            }
+
+          new_lineptr = (char *) gnutls_realloc (*lineptr, needed);
+          if (new_lineptr == NULL)
+            {
+              result = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+              goto fail;
+            }
+
+          *lineptr = new_lineptr;
+          *n = needed;
+        }
+
+      (*lineptr)[cur_len] = c;
+      cur_len++;
+
+      if (c == delimiter)
+        break;
+    }
+  (*lineptr)[cur_len] = '\0';
+
+  if (cur_len != 0)
+    result = cur_len;
+
+fail:
+
+  return result;
+}
index 5981c14a767b96f300d1785291529e78b4f9fc0d..5804a0d54f08dc98870505b5a9149322e6c7a054 100644 (file)
@@ -30,6 +30,7 @@
 #include <errno.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
+#include <gnutls/sbuf.h>
 #include "eagain-common.h"
 
 #include "utils.h"
@@ -47,6 +48,9 @@ tls_log_func (int level, const char *str)
 static unsigned char server_buf[MAX_BUF];
 static unsigned char client_buf[MAX_BUF];
 
+#define LINE1 "hello there people\n"
+#define LINE2 "how are you doing today, all well?\n"
+
 void
 doit (void)
 {
@@ -64,6 +68,8 @@ doit (void)
   /* Need to enable anonymous KX specifically. */
   int ret;
   ssize_t left, spos, cpos;
+  char *abuf = NULL;
+  size_t abuf_size = 0;
 
   /* General init. */
   gnutls_global_init ();
@@ -112,20 +118,23 @@ doit (void)
     {
       if (left > SEND_SIZE)
         {
-          ret = gnutls_sbuf_queue(ssbuf, server_buf+spos, SEND_SIZE);
-          left -= SEND_SIZE;
-          spos += SEND_SIZE;
+          ret = gnutls_sbuf_write(ssbuf, server_buf+spos, SEND_SIZE);
         }
       else
         {
-          gnutls_sbuf_queue(ssbuf, server_buf+spos, left);
+          ret = gnutls_sbuf_write(ssbuf, server_buf+spos, left);
+        }
+
+      if (ret >= 0)
+        {
+          left -= ret;
+          spos += ret;
           ret = gnutls_sbuf_flush(ssbuf);
-          left = 0;
         }
-      
+
       if (ret < 0)
         {
-          fail("Error sending\n");
+          fail("Error sending %s\n", gnutls_strerror(ret));
           abort();
         }
       
@@ -137,7 +146,7 @@ doit (void)
 
           if (ret < 0)
             {
-              fail("Error sending\n");
+              fail("Error receiving %s\n", gnutls_strerror(ret));
               abort();
             }
         }
@@ -148,6 +157,35 @@ doit (void)
       fail("Data do not match!\n");
       abort();
     }
+  
+  gnutls_record_send(client, LINE1, sizeof(LINE1)-1);
+  gnutls_record_send(client, LINE2, sizeof(LINE2)-1);
+  
+  ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size);
+  if (ret < 0)
+    {
+      fail("sbuf_getline error %s!\n", gnutls_strerror(ret));
+      abort();
+    }
+
+  if (strcmp(abuf, LINE1) != 0)
+    {
+      fail("LINE1 Data do not match!\n");
+      abort();
+    }
+
+  ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size);
+  if (ret < 0)
+    {
+      fail("sbuf_getline error %s!\n", gnutls_strerror(ret));
+      abort();
+    }
+
+  if (strcmp(abuf, LINE2) != 0)
+    {
+      fail("LINE2 Data do not match!\n");
+      abort();
+    }
 
   gnutls_bye (client, GNUTLS_SHUT_RDWR);
   gnutls_bye (server, GNUTLS_SHUT_RDWR);