Update to ncurses-6.0

Change-Id: I98ab2ea8a5e13cca9f8b7cf6277b9b14a4da4299
diff --git a/ncurses/tinfo/hashed_db.c b/ncurses/tinfo/hashed_db.c
index 3fc04ea..b594205 100644
--- a/ncurses/tinfo/hashed_db.c
+++ b/ncurses/tinfo/hashed_db.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2006 Free Software Foundation, Inc.                        *
+ * Copyright (c) 2006-2011,2013 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -27,7 +27,7 @@
  ****************************************************************************/
 
 /****************************************************************************
- *  Author: Thomas E. Dickey                        2006                    *
+ *  Author: Thomas E. Dickey                        2006-on                 *
  ****************************************************************************/
 
 #include <curses.priv.h>
@@ -36,12 +36,81 @@
 
 #if USE_HASHED_DB
 
-MODULE_ID("$Id: hashed_db.c,v 1.13 2006/08/19 19:48:38 tom Exp $")
+MODULE_ID("$Id: hashed_db.c,v 1.17 2013/12/15 00:33:01 tom Exp $")
 
 #if HASHED_DB_API >= 2
 static DBC *cursor;
 #endif
 
+typedef struct _myconn {
+    struct _myconn *next;
+    DB *db;
+    char *path;
+    bool modify;
+} MYCONN;
+
+static MYCONN *connections;
+
+static void
+cleanup(void)
+{
+    while (connections != 0) {
+	_nc_db_close(connections->db);
+    }
+}
+
+static DB *
+find_connection(const char *path, bool modify)
+{
+    DB *result = 0;
+    MYCONN *p;
+
+    for (p = connections; p != 0; p = p->next) {
+	if (!strcmp(p->path, path) && p->modify == modify) {
+	    result = p->db;
+	    break;
+	}
+    }
+
+    return result;
+}
+
+static void
+drop_connection(DB * db)
+{
+    MYCONN *p, *q;
+
+    for (p = connections, q = 0; p != 0; q = p, p = p->next) {
+	if (p->db == db) {
+	    if (q != 0)
+		q->next = p->next;
+	    else
+		connections = p->next;
+	    free(p->path);
+	    free(p);
+	    break;
+	}
+    }
+}
+
+static void
+make_connection(DB * db, const char *path, bool modify)
+{
+    MYCONN *p = typeCalloc(MYCONN, 1);
+
+    if (p != 0) {
+	p->db = db;
+	p->path = strdup(path);
+	p->modify = modify;
+	if (p->path != 0) {
+	    p->next = connections;
+	    connections = p;
+	} else {
+	    free(p);
+	}
+    }
+}
+
 /*
  * Open the database.
  */
@@ -49,49 +118,60 @@
 _nc_db_open(const char *path, bool modify)
 {
     DB *result = 0;
-
-#if HASHED_DB_API >= 4
-    db_create(&result, NULL, 0);
-    result->open(result,
-		 NULL,
-		 path,
-		 NULL,
-		 DB_HASH,
-		 modify ? DB_CREATE : DB_RDONLY,
-		 0644);
-#elif HASHED_DB_API >= 3
-    db_create(&result, NULL, 0);
-    result->open(result,
-		 path,
-		 NULL,
-		 DB_HASH,
-		 modify ? DB_CREATE : DB_RDONLY,
-		 0644);
-#elif HASHED_DB_API >= 2
     int code;
 
-    if ((code = db_open(path,
-			DB_HASH,
-			modify ? DB_CREATE : DB_RDONLY,
-			0644,
-			(DB_ENV *) 0,
-			(DB_INFO *) 0,
-			&result)) != 0) {
-	T(("cannot open %s: %s", path, strerror(code)));
-	result = 0;
-    } else {
-	T(("opened %s", path));
-    }
+    if (connections == 0)
+	atexit(cleanup);
+
+    if ((result = find_connection(path, modify)) == 0) {
+
+#if HASHED_DB_API >= 4
+	db_create(&result, NULL, 0);
+	if ((code = result->open(result,
+				 NULL,
+				 path,
+				 NULL,
+				 DB_HASH,
+				 modify ? DB_CREATE : DB_RDONLY,
+				 0644)) != 0) {
+	    result = 0;
+	}
+#elif HASHED_DB_API >= 3
+	db_create(&result, NULL, 0);
+	if ((code = result->open(result,
+				 path,
+				 NULL,
+				 DB_HASH,
+				 modify ? DB_CREATE : DB_RDONLY,
+				 0644)) != 0) {
+	    result = 0;
+	}
+#elif HASHED_DB_API >= 2
+	if ((code = db_open(path,
+			    DB_HASH,
+			    modify ? DB_CREATE : DB_RDONLY,
+			    0644,
+			    (DB_ENV *) 0,
+			    (DB_INFO *) 0,
+			    &result)) != 0) {
+	    result = 0;
+	}
 #else
-    result = dbopen(path,
-		    modify ? (O_CREAT | O_RDWR) : O_RDONLY,
-		    0644,
-		    DB_HASH,
-		    NULL);
-    if (result != 0) {
-	T(("opened %s", path));
-    }
+	if ((result = dbopen(path,
+			     modify ? (O_CREAT | O_RDWR) : O_RDONLY,
+			     0644,
+			     DB_HASH,
+			     NULL)) == 0) {
+	    code = errno;
+	}
 #endif
+	if (result != 0) {
+	    make_connection(result, path, modify);
+	    T(("opened %s", path));
+	} else {
+	    T(("cannot open %s: %s", path, strerror(code)));
+	}
+    }
     return result;
 }
 
@@ -103,6 +183,7 @@
 {
     int result;
 
+    drop_connection(db);
 #if HASHED_DB_API >= 2
     result = db->close(db, 0);
 #else
@@ -205,7 +286,7 @@
 _nc_db_have_index(DBT * key, DBT * data, char **buffer, int *size)
 {
     bool result = FALSE;
-    int used = data->size - 1;
+    int used = (int) data->size - 1;
     char *have = (char *) data->data;
 
     (void) key;
@@ -228,7 +309,7 @@
 _nc_db_have_data(DBT * key, DBT * data, char **buffer, int *size)
 {
     bool result = FALSE;
-    int used = data->size - 1;
+    int used = (int) data->size - 1;
     char *have = (char *) data->data;
 
     if (*have++ == 0) {