agent: Avoid appending a '\0' byte to the response of READKEY
[gnupg.git] / common / strlist.c
index b31e621..6feb3a4 100644 (file)
@@ -1,20 +1,32 @@
 /* strlist.c -  string helpers
  * Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2015  g10 Code GmbH
  *
- * This file is part of JNLIB.
+ * This file is part of GnuPG.
  *
- * JNLIB 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 3 of
- * the License, or (at your option) any later version.
+ * GnuPG is free software; you can redistribute and/or modify this
+ * part of GnuPG under the terms of either
  *
- * JNLIB is distributed in the hope that it will be useful, but
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * GnuPG 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.
+ * 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/>.
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <stdarg.h>
 #include <ctype.h>
 
-#include "libjnlib-config.h"
+#include "util.h"
+#include "common-defs.h"
 #include "strlist.h"
-#ifdef JNLIB_NEED_UTF8CONV
 #include "utf8conv.h"
-#endif
+#include "mischelp.h"
 
 void
 free_strlist( strlist_t sl )
@@ -36,7 +48,20 @@ free_strlist( strlist_t sl )
 
     for(; sl; sl = sl2 ) {
        sl2 = sl->next;
-       jnlib_free(sl);
+       xfree(sl);
+    }
+}
+
+
+void
+free_strlist_wipe (strlist_t sl)
+{
+    strlist_t sl2;
+
+    for(; sl; sl = sl2 ) {
+       sl2 = sl->next;
+        wipememory (sl, sizeof *sl + strlen (sl->d));
+       xfree(sl);
     }
 }
 
@@ -48,7 +73,7 @@ add_to_strlist( strlist_t *list, const char *string )
 {
     strlist_t sl;
 
-    sl = jnlib_xmalloc( sizeof *sl + strlen(string));
+    sl = xmalloc( sizeof *sl + strlen(string));
     sl->flags = 0;
     strcpy(sl->d, string);
     sl->next = *list;
@@ -63,8 +88,8 @@ strlist_t
 add_to_strlist_try (strlist_t *list, const char *string)
 {
   strlist_t sl;
-  
-  sl = jnlib_malloc (sizeof *sl + strlen (string));
+
+  sl = xtrymalloc (sizeof *sl + strlen (string));
   if (sl)
     {
       sl->flags = 0;
@@ -79,23 +104,21 @@ add_to_strlist_try (strlist_t *list, const char *string)
 /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
    to UTF-8 is done.  This function terminates the process on memory
    shortage.  */
-#ifdef JNLIB_NEED_UTF8CONV
 strlist_t
 add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
 {
   strlist_t sl;
-  
+
   if (is_utf8)
     sl = add_to_strlist( list, string );
-  else 
+  else
     {
       char *p = native_to_utf8( string );
       sl = add_to_strlist( list, p );
-      jnlib_free ( p );
+      xfree ( p );
     }
   return sl;
 }
-#endif /* JNLIB_NEED_UTF8CONV*/
 
 
 /* Add STRING to the LIST at the end.  This function terminates the
@@ -103,9 +126,24 @@ add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
 strlist_t
 append_to_strlist( strlist_t *list, const char *string )
 {
+  strlist_t sl;
+  sl = append_to_strlist_try (list, string);
+  if (!sl)
+    xoutofcore ();
+  return sl;
+}
+
+
+/* Add STRING to the LIST at the end.  */
+strlist_t
+append_to_strlist_try (strlist_t *list, const char *string)
+{
     strlist_t r, sl;
 
-    sl = jnlib_xmalloc( sizeof *sl + strlen(string));
+    sl = xtrymalloc( sizeof *sl + strlen(string));
+    if (sl == NULL)
+      return NULL;
+
     sl->flags = 0;
     strcpy(sl->d, string);
     sl->next = NULL;
@@ -120,23 +158,21 @@ append_to_strlist( strlist_t *list, const char *string )
 }
 
 
-#ifdef JNLIB_NEED_UTF8CONV
 strlist_t
 append_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
 {
   strlist_t sl;
-    
+
   if( is_utf8 )
     sl = append_to_strlist( list, string );
   else
     {
       char *p = native_to_utf8 (string);
       sl = append_to_strlist( list, p );
-      jnlib_free( p );
+      xfree( p );
     }
   return sl;
 }
-#endif /* JNLIB_NEED_UTF8CONV */
 
 
 /* Return a copy of LIST.  This function terminates the process on
@@ -149,7 +185,7 @@ strlist_copy (strlist_t list)
   last = &newlist;
   for (; list; list = list->next)
     {
-      sl = jnlib_xmalloc (sizeof *sl + strlen (list->d));
+      sl = xmalloc (sizeof *sl + strlen (list->d));
       sl->flags = list->flags;
       strcpy(sl->d, list->d);
       sl->next = NULL;
@@ -192,13 +228,54 @@ strlist_pop (strlist_t *list)
 
   if(sl)
     {
-      str=jnlib_xmalloc(strlen(sl->d)+1);
+      str = xmalloc(strlen(sl->d)+1);
       strcpy(str,sl->d);
 
       *list=sl->next;
-      jnlib_free(sl);
+      xfree(sl);
     }
 
   return str;
 }
 
+/* Return the first element of the string list HAYSTACK whose string
+   matches NEEDLE.  If no elements match, return NULL.  */
+strlist_t
+strlist_find (strlist_t haystack, const char *needle)
+{
+  for (;
+       haystack;
+       haystack = haystack->next)
+    if (strcmp (haystack->d, needle) == 0)
+      return haystack;
+  return NULL;
+}
+
+int
+strlist_length (strlist_t list)
+{
+  int i;
+  for (i = 0; list; list = list->next)
+    i ++;
+
+  return i;
+}
+
+/* Reverse the list *LIST in place.  */
+strlist_t
+strlist_rev (strlist_t *list)
+{
+  strlist_t l = *list;
+  strlist_t lrev = NULL;
+
+  while (l)
+    {
+      strlist_t tail = l->next;
+      l->next = lrev;
+      lrev = l;
+      l = tail;
+    }
+
+  *list = lrev;
+  return lrev;
+}