summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIvo De Decker <ivodd@debian.org>2014-10-20 23:42:17 +0200
committerIvo De Decker <ivodd@debian.org>2014-10-20 23:42:17 +0200
commit4a6dca5300f974ce79f17dce6ff2b3685069ea01 (patch)
tree972810e0de5bb7ef187c6e824912e7ca591c7b41 /lib
parent954d864792f2d874e8ebc73a735b6ce0152fd610 (diff)
parent3211982d13637fe3389ab4e6901c9f593555045e (diff)
downloadsamba-4a6dca5300f974ce79f17dce6ff2b3685069ea01.tar.gz
Imported Upstream version 4.1.13+dfsgupstream/4.1.13+dfsg
Diffstat (limited to 'lib')
-rw-r--r--lib/param/param_functions.c1
-rw-r--r--lib/param/param_table.c9
-rw-r--r--lib/replace/replace.h5
-rw-r--r--lib/replace/wscript25
-rw-r--r--lib/tevent/tevent_signal.c6
-rw-r--r--lib/util/become_daemon.c11
-rw-r--r--lib/util/charset/tests/charset.c12
-rw-r--r--lib/util/charset/util_str.c37
-rw-r--r--lib/util/memcache.c421
-rw-r--r--lib/util/memcache.h110
-rw-r--r--lib/util/samba_util.h10
-rw-r--r--lib/util/select.c14
-rw-r--r--lib/util/signal.c8
-rw-r--r--lib/util/string_wrappers.h5
-rwxr-xr-xlib/util/wscript_build2
-rw-r--r--lib/zlib/contrib/dotzlib/DotZLib.chmbin72728 -> 0 bytes
16 files changed, 650 insertions, 26 deletions
diff --git a/lib/param/param_functions.c b/lib/param/param_functions.c
index 61f00448ca..d9d5df6272 100644
--- a/lib/param/param_functions.c
+++ b/lib/param/param_functions.c
@@ -341,6 +341,7 @@ FN_GLOBAL_INTEGER(winbind_cache_time, winbind_cache_time)
FN_GLOBAL_INTEGER(winbind_expand_groups, winbind_expand_groups)
FN_GLOBAL_INTEGER(winbind_max_clients, winbind_max_clients)
FN_GLOBAL_INTEGER(winbind_reconnect_delay, winbind_reconnect_delay)
+FN_GLOBAL_INTEGER(winbind_request_timeout, winbind_request_timeout)
FN_GLOBAL_LIST(auth_methods, AuthMethods)
FN_GLOBAL_LIST(cluster_addresses, szClusterAddresses)
FN_GLOBAL_LIST(dcerpc_endpoint_servers, dcerpc_ep_servers)
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index 7b32998084..8e3f952b6e 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -4018,6 +4018,15 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
+ .label = "winbind request timeout",
+ .type = P_INTEGER,
+ .p_class = P_GLOBAL,
+ .offset = GLOBAL_VAR(winbind_request_timeout),
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
+ {
.label = "winbind max clients",
.type = P_INTEGER,
.p_class = P_GLOBAL,
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index c0b799763a..cd0c25e2af 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -899,4 +899,9 @@ int usleep(useconds_t);
void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
#endif
+/* Needed for Solaris atomic_add_XX functions. */
+#if defined(HAVE_SYS_ATOMIC_H)
+#include <sys/atomic.h>
+#endif
+
#endif /* _LIBREPLACE_REPLACE_H */
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 8451689800..f0040b18e0 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -106,6 +106,7 @@ struct foo bar = { .y = 'X', .x = 1 };
conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h')
conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h malloc.h')
conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h')
+ conf.CHECK_HEADERS('sys/atomic.h')
# Check for process set name support
conf.CHECK_CODE('''
@@ -225,6 +226,30 @@ struct foo bar = { .y = 'X', .x = 1 };
msg="Checking whether we have ucontext_t",
headers='signal.h sys/ucontext.h')
+ # Check for atomic builtins. */
+ conf.CHECK_CODE('''
+ int main(void) {
+ int i;
+ (void)__sync_fetch_and_add(&i, 1);
+ return 0;
+ }
+ ''',
+ 'HAVE___SYNC_FETCH_AND_ADD',
+ msg='Checking for __sync_fetch_and_add compiler builtin')
+
+ conf.CHECK_CODE('''
+ #include <stdint.h>
+ #include <sys/atomic.h>
+ int main(void) {
+ int32_t i;
+ atomic_add_32(&i, 1);
+ return 0;
+ }
+ ''',
+ 'HAVE_ATOMIC_ADD_32',
+ headers='stdint.h sys/atomic.h',
+ msg='Checking for atomic_add_32 compiler builtin')
+
# these may be builtins, so we need the link=False strategy
conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False)
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 0fdf646c8d..95a099d6ab 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -42,7 +42,13 @@ struct tevent_sigcounter {
uint32_t seen;
};
+#if defined(HAVE___SYNC_FETCH_AND_ADD)
+#define TEVENT_SIG_INCREMENT(s) __sync_fetch_and_add(&((s).count), 1)
+#elif defined(HAVE_ATOMIC_ADD_32)
+#define TEVENT_SIG_INCREMENT(s) atomic_add_32(&((s).count), 1)
+#else
#define TEVENT_SIG_INCREMENT(s) (s).count++
+#endif
#define TEVENT_SIG_SEEN(s, n) (s).seen += (n)
#define TEVENT_SIG_PENDING(s) ((s).seen != (s).count)
diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c
index 35c8b3252b..688bedd49a 100644
--- a/lib/util/become_daemon.c
+++ b/lib/util/become_daemon.c
@@ -135,3 +135,14 @@ _PUBLIC_ void daemon_ready(const char *daemon)
#endif
DEBUG(0, ("STATUS=daemon '%s' finished starting up and ready to serve connections", daemon));
}
+
+_PUBLIC_ void daemon_status(const char *name, const char *msg)
+{
+ if (name == NULL) {
+ name = "Samba";
+ }
+#ifdef HAVE_SYSTEMD
+ sd_notifyf(0, "\nSTATUS=%s: %s", name, msg);
+#endif
+ DEBUG(0, ("STATUS=daemon '%s' : %s", name, msg));
+}
diff --git a/lib/util/charset/tests/charset.c b/lib/util/charset/tests/charset.c
index 70b6741876..a47670e666 100644
--- a/lib/util/charset/tests/charset.c
+++ b/lib/util/charset/tests/charset.c
@@ -50,12 +50,18 @@ static bool test_codepoint_cmpi(struct torture_context *tctx)
static bool test_strcasecmp_m(struct torture_context *tctx)
{
+ /* file.{accented e} in iso8859-1 */
+ const char file_iso8859_1[7] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xe9, 0 };
+ /* file.{accented e} in utf8 */
+ const char file_utf8[8] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xc3, 0xa9, 0 };
torture_assert(tctx, strcasecmp_m("foo", "bar") != 0, "different strings");
torture_assert(tctx, strcasecmp_m("foo", "foo") == 0, "same case strings");
torture_assert(tctx, strcasecmp_m("foo", "Foo") == 0, "different case strings");
torture_assert(tctx, strcasecmp_m(NULL, "Foo") != 0, "one NULL");
torture_assert(tctx, strcasecmp_m("foo", NULL) != 0, "other NULL");
torture_assert(tctx, strcasecmp_m(NULL, NULL) == 0, "both NULL");
+ torture_assert(tctx, strcasecmp_m(file_iso8859_1, file_utf8) != 0,
+ "file.{accented e} should differ");
return true;
}
@@ -102,6 +108,10 @@ static bool test_string_replace_m(struct torture_context *tctx)
static bool test_strncasecmp_m(struct torture_context *tctx)
{
+ /* file.{accented e} in iso8859-1 */
+ const char file_iso8859_1[7] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xe9, 0 };
+ /* file.{accented e} in utf8 */
+ const char file_utf8[8] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xc3, 0xa9, 0 };
torture_assert(tctx, strncasecmp_m("foo", "bar", 3) != 0, "different strings");
torture_assert(tctx, strncasecmp_m("foo", "foo", 3) == 0, "same case strings");
torture_assert(tctx, strncasecmp_m("foo", "Foo", 3) == 0, "different case strings");
@@ -111,6 +121,8 @@ static bool test_strncasecmp_m(struct torture_context *tctx)
torture_assert(tctx, strncasecmp_m(NULL, "Foo", 3) != 0, "one NULL");
torture_assert(tctx, strncasecmp_m("foo", NULL, 3) != 0, "other NULL");
torture_assert(tctx, strncasecmp_m(NULL, NULL, 3) == 0, "both NULL");
+ torture_assert(tctx, strncasecmp_m(file_iso8859_1, file_utf8, 6) != 0,
+ "file.{accented e} should differ");
return true;
}
diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c
index 688ab5a0a1..d2e6cbbc62 100644
--- a/lib/util/charset/util_str.c
+++ b/lib/util/charset/util_str.c
@@ -47,6 +47,11 @@ _PUBLIC_ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
c1 = next_codepoint_handle(iconv_handle, s1, &size1);
c2 = next_codepoint_handle(iconv_handle, s2, &size2);
+ if (c1 == INVALID_CODEPOINT ||
+ c2 == INVALID_CODEPOINT) {
+ return strcasecmp(s1, s2);
+ }
+
s1 += size1;
s2 += size2;
@@ -54,12 +59,6 @@ _PUBLIC_ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
continue;
}
- if (c1 == INVALID_CODEPOINT ||
- c2 == INVALID_CODEPOINT) {
- /* what else can we do?? */
- return strcasecmp(s1, s2);
- }
-
if (toupper_m(c1) != toupper_m(c2)) {
return c1 - c2;
}
@@ -97,6 +96,26 @@ _PUBLIC_ int strncasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
c1 = next_codepoint_handle(iconv_handle, s1, &size1);
c2 = next_codepoint_handle(iconv_handle, s2, &size2);
+ if (c1 == INVALID_CODEPOINT ||
+ c2 == INVALID_CODEPOINT) {
+ /*
+ * n was specified in characters,
+ * now we must convert it to bytes.
+ * As bytes are the smallest
+ * character unit, the following
+ * increment and strncasecmp is always
+ * safe.
+ *
+ * The source string was already known
+ * to be n characters long, so we are
+ * guaranteed to be able to look at the
+ * (n remaining + size1) bytes from the
+ * s1 position).
+ */
+ n += size1;
+ return strncasecmp(s1, s2, n);
+ }
+
s1 += size1;
s2 += size2;
@@ -104,12 +123,6 @@ _PUBLIC_ int strncasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
continue;
}
- if (c1 == INVALID_CODEPOINT ||
- c2 == INVALID_CODEPOINT) {
- /* what else can we do?? */
- return strcasecmp(s1, s2);
- }
-
if (toupper_m(c1) != toupper_m(c2)) {
return c1 - c2;
}
diff --git a/lib/util/memcache.c b/lib/util/memcache.c
new file mode 100644
index 0000000000..50e59fc704
--- /dev/null
+++ b/lib/util/memcache.c
@@ -0,0 +1,421 @@
+/*
+ Unix SMB/CIFS implementation.
+ In-memory cache
+ Copyright (C) Volker Lendecke 2007
+
+ 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "../lib/util/samba_util.h"
+#include "../lib/util/debug.h"
+#include "../lib/util/dlinklist.h"
+#include "../lib/util/rbtree.h"
+#include "memcache.h"
+
+static struct memcache *global_cache;
+
+struct memcache_element {
+ struct rb_node rb_node;
+ struct memcache_element *prev, *next;
+ size_t keylength, valuelength;
+ uint8_t n; /* This is really an enum, but save memory */
+ char data[1]; /* placeholder for offsetof */
+};
+
+struct memcache {
+ struct memcache_element *mru;
+ struct rb_root tree;
+ size_t size;
+ size_t max_size;
+};
+
+static void memcache_element_parse(struct memcache_element *e,
+ DATA_BLOB *key, DATA_BLOB *value);
+
+static bool memcache_is_talloc(enum memcache_number n)
+{
+ bool result;
+
+ switch (n) {
+ case GETPWNAM_CACHE:
+ case PDB_GETPWSID_CACHE:
+ case SINGLETON_CACHE_TALLOC:
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
+static int memcache_destructor(struct memcache *cache) {
+ struct memcache_element *e, *next;
+
+ for (e = cache->mru; e != NULL; e = next) {
+ next = e->next;
+ TALLOC_FREE(e);
+ }
+ return 0;
+}
+
+struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size)
+{
+ struct memcache *result;
+
+ result = talloc_zero(mem_ctx, struct memcache);
+ if (result == NULL) {
+ return NULL;
+ }
+ result->max_size = max_size;
+ talloc_set_destructor(result, memcache_destructor);
+ return result;
+}
+
+void memcache_set_global(struct memcache *cache)
+{
+ TALLOC_FREE(global_cache);
+ global_cache = cache;
+}
+
+static struct memcache_element *memcache_node2elem(struct rb_node *node)
+{
+ return (struct memcache_element *)
+ ((char *)node - offsetof(struct memcache_element, rb_node));
+}
+
+static void memcache_element_parse(struct memcache_element *e,
+ DATA_BLOB *key, DATA_BLOB *value)
+{
+ key->data = ((uint8_t *)e) + offsetof(struct memcache_element, data);
+ key->length = e->keylength;
+ value->data = key->data + e->keylength;
+ value->length = e->valuelength;
+}
+
+static size_t memcache_element_size(size_t key_length, size_t value_length)
+{
+ return sizeof(struct memcache_element) - 1 + key_length + value_length;
+}
+
+static int memcache_compare(struct memcache_element *e, enum memcache_number n,
+ DATA_BLOB key)
+{
+ DATA_BLOB this_key, this_value;
+
+ if ((int)e->n < (int)n) return 1;
+ if ((int)e->n > (int)n) return -1;
+
+ if (e->keylength < key.length) return 1;
+ if (e->keylength > key.length) return -1;
+
+ memcache_element_parse(e, &this_key, &this_value);
+ return memcmp(this_key.data, key.data, key.length);
+}
+
+static struct memcache_element *memcache_find(
+ struct memcache *cache, enum memcache_number n, DATA_BLOB key)
+{
+ struct rb_node *node;
+
+ node = cache->tree.rb_node;
+
+ while (node != NULL) {
+ struct memcache_element *elem = memcache_node2elem(node);
+ int cmp;
+
+ cmp = memcache_compare(elem, n, key);
+ if (cmp == 0) {
+ return elem;
+ }
+ node = (cmp < 0) ? node->rb_left : node->rb_right;
+ }
+
+ return NULL;
+}
+
+bool memcache_lookup(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB *value)
+{
+ struct memcache_element *e;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return false;
+ }
+
+ e = memcache_find(cache, n, key);
+ if (e == NULL) {
+ return false;
+ }
+
+ if (cache->size != 0) {
+ DLIST_PROMOTE(cache->mru, e);
+ }
+
+ memcache_element_parse(e, &key, value);
+ return true;
+}
+
+void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key)
+{
+ DATA_BLOB value;
+ void *result;
+
+ if (!memcache_lookup(cache, n, key, &value)) {
+ return NULL;
+ }
+
+ if (value.length != sizeof(result)) {
+ return NULL;
+ }
+
+ memcpy(&result, value.data, sizeof(result));
+
+ return result;
+}
+
+static void memcache_delete_element(struct memcache *cache,
+ struct memcache_element *e)
+{
+ rb_erase(&e->rb_node, &cache->tree);
+
+ DLIST_REMOVE(cache->mru, e);
+
+ if (memcache_is_talloc(e->n)) {
+ DATA_BLOB cache_key, cache_value;
+ void *ptr;
+
+ memcache_element_parse(e, &cache_key, &cache_value);
+ SMB_ASSERT(cache_value.length == sizeof(ptr));
+ memcpy(&ptr, cache_value.data, sizeof(ptr));
+ TALLOC_FREE(ptr);
+ }
+
+ cache->size -= memcache_element_size(e->keylength, e->valuelength);
+
+ TALLOC_FREE(e);
+}
+
+static void memcache_trim(struct memcache *cache)
+{
+ if (cache->max_size == 0) {
+ return;
+ }
+
+ while ((cache->size > cache->max_size) && DLIST_TAIL(cache->mru)) {
+ memcache_delete_element(cache, DLIST_TAIL(cache->mru));
+ }
+}
+
+void memcache_delete(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key)
+{
+ struct memcache_element *e;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ e = memcache_find(cache, n, key);
+ if (e == NULL) {
+ return;
+ }
+
+ memcache_delete_element(cache, e);
+}
+
+void memcache_add(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB value)
+{
+ struct memcache_element *e;
+ struct rb_node **p;
+ struct rb_node *parent;
+ DATA_BLOB cache_key, cache_value;
+ size_t element_size;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ if (key.length == 0) {
+ return;
+ }
+
+ e = memcache_find(cache, n, key);
+
+ if (e != NULL) {
+ memcache_element_parse(e, &cache_key, &cache_value);
+
+ if (value.length <= cache_value.length) {
+ if (memcache_is_talloc(e->n)) {
+ void *ptr;
+ SMB_ASSERT(cache_value.length == sizeof(ptr));
+ memcpy(&ptr, cache_value.data, sizeof(ptr));
+ TALLOC_FREE(ptr);
+ }
+ /*
+ * We can reuse the existing record
+ */
+ memcpy(cache_value.data, value.data, value.length);
+ e->valuelength = value.length;
+ return;
+ }
+
+ memcache_delete_element(cache, e);
+ }
+
+ element_size = memcache_element_size(key.length, value.length);
+
+ e = talloc_size(cache, element_size);
+ if (e == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return;
+ }
+ talloc_set_type(e, struct memcache_element);
+
+ e->n = n;
+ e->keylength = key.length;
+ e->valuelength = value.length;
+
+ memcache_element_parse(e, &cache_key, &cache_value);
+ memcpy(cache_key.data, key.data, key.length);
+ memcpy(cache_value.data, value.data, value.length);
+
+ parent = NULL;
+ p = &cache->tree.rb_node;
+
+ while (*p) {
+ struct memcache_element *elem = memcache_node2elem(*p);
+ int cmp;
+
+ parent = (*p);
+
+ cmp = memcache_compare(elem, n, key);
+
+ p = (cmp < 0) ? &(*p)->rb_left : &(*p)->rb_right;
+ }
+
+ rb_link_node(&e->rb_node, parent, p);
+ rb_insert_color(&e->rb_node, &cache->tree);
+
+ DLIST_ADD(cache->mru, e);
+
+ cache->size += element_size;
+ memcache_trim(cache);
+}
+
+void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, void *pptr)
+{
+ void **ptr = (void **)pptr;
+ void *p;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ p = talloc_move(cache, ptr);
+ memcache_add(cache, n, key, data_blob_const(&p, sizeof(p)));
+}
+
+void memcache_flush(struct memcache *cache, enum memcache_number n)
+{
+ struct rb_node *node;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ /*
+ * Find the smallest element of number n
+ */
+
+ node = cache->tree.rb_node;
+ if (node == NULL) {
+ return;
+ }
+
+ /*
+ * First, find *any* element of number n
+ */
+
+ while (true) {
+ struct memcache_element *elem = memcache_node2elem(node);
+ struct rb_node *next;
+
+ if ((int)elem->n == (int)n) {
+ break;
+ }
+
+ if ((int)elem->n < (int)n) {
+ next = node->rb_right;
+ }
+ else {
+ next = node->rb_left;
+ }
+ if (next == NULL) {
+ break;
+ }
+ node = next;
+ }
+
+ /*
+ * Then, find the leftmost element with number n
+ */
+
+ while (true) {
+ struct rb_node *prev = rb_prev(node);
+ struct memcache_element *elem;
+
+ if (prev == NULL) {
+ break;
+ }
+ elem = memcache_node2elem(prev);
+ if ((int)elem->n != (int)n) {
+ break;
+ }
+ node = prev;
+ }
+
+ while (node != NULL) {
+ struct memcache_element *e = memcache_node2elem(node);
+ struct rb_node *next = rb_next(node);
+
+ if (e->n != n) {
+ break;
+ }
+
+ memcache_delete_element(cache, e);
+ node = next;
+ }
+}
diff --git a/lib/util/memcache.h b/lib/util/memcache.h
new file mode 100644
index 0000000000..11e59718c9
--- /dev/null
+++ b/lib/util/memcache.h
@@ -0,0 +1,110 @@
+/*
+ Unix SMB/CIFS implementation.
+ In-memory cache
+ Copyright (C) Volker Lendecke 2007-2008
+
+ 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MEMCACHE_H__
+#define __MEMCACHE_H__
+
+struct memcache;
+
+/*
+ * A memcache can store different subkeys with overlapping keys, the
+ * memcache_number becomes part of the key. Feel free to add caches of your
+ * own here.
+ *
+ * If you add talloc type caches, also note this in the switch statement in
+ * memcache_is_talloc().
+ */
+
+enum memcache_number {
+ STAT_CACHE,
+ GETWD_CACHE,
+ GETPWNAM_CACHE, /* talloc */
+ MANGLE_HASH2_CACHE,
+ PDB_GETPWSID_CACHE, /* talloc */
+ SINGLETON_CACHE_TALLOC, /* talloc */
+ SINGLETON_CACHE,
+ SMB1_SEARCH_OFFSET_MAP
+};
+
+/*
+ * Create a memcache structure. max_size is in bytes, if you set it 0 it will
+ * not forget anything.
+ */
+
+struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size);
+
+/*
+ * If you set this global memcache, use it as the default cache when NULL is
+ * passed to the memcache functions below. This is a workaround for many
+ * situations where passing the cache everywhere would be a big hassle.
+ */
+
+void memcache_set_global(struct memcache *cache);
+
+/*
+ * Add a data blob to the cache
+ */
+
+void memcache_add(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB value);
+
+/*
+ * Add a talloc object to the cache. The difference to memcache_add() is that
+ * when the objects is to be discared, talloc_free is called for it. Also
+ * talloc_move() ownership of the object to the cache.
+ *
+ * Please note that the current implementation has a fixed relationship
+ * between what cache subtypes store talloc objects and which ones store plain
+ * blobs. We can fix this, but for now we don't have a mixed use of blobs vs
+ * talloc objects in the cache types.
+ */
+
+void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, void *ptr);
+
+/*
+ * Delete an object from the cache
+ */
+
+void memcache_delete(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key);
+
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
+bool memcache_lookup(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB *value);
+
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
+void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key);
+
+/*
+ * Flush a complete cache subset.
+ */
+
+void memcache_flush(struct memcache *cache, enum memcache_number n);
+
+#endif
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index e3fe6a6079..c6eb3496b9 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -107,12 +107,12 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int);
/**
Ignore SIGCLD via whatever means is necessary for this OS.
**/
-void CatchChild(void);
+void (*CatchChild(void))(int);
/**
Catch SIGCLD but leave the child around so it's status can be reaped.
**/
-void CatchChildLeaveStatus(void);
+void (*CatchChildLeaveStatus(void))(int);
struct sockaddr;
@@ -853,6 +853,12 @@ _PUBLIC_ void exit_daemon(const char *msg, int error);
**/
_PUBLIC_ void daemon_ready(const char *daemon);
+/*
+ * Report the daemon status. For example if it is not ready to serve connections
+ * and is waiting for some event to happen.
+ */
+_PUBLIC_ void daemon_status(const char *name, const char *msg);
+
/**
* @brief Get a password from the console.
*
diff --git a/lib/util/select.c b/lib/util/select.c
index 5e66344c9d..99cd772bae 100644
--- a/lib/util/select.c
+++ b/lib/util/select.c
@@ -42,9 +42,19 @@ int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout)
if (errno != EINTR) {
break;
}
+ /* Infinite timeout, no need to adjust. */
+ if (timeout < 0) {
+ continue;
+ }
clock_gettime_mono(&now);
- elapsed = nsec_time_diff(&now, &start);
- timeout = (orig_timeout - elapsed) / 1000000;
+ elapsed = nsec_time_diff(&now, &start) / 1000000;
+ timeout = orig_timeout - elapsed;
+ /* Unlikely, but might happen eg. when getting traced.
+ * Make sure we're not hanging in this case.
+ */
+ if (timeout < 0) {
+ timeout = 0;
+ }
};
return ret;
}
diff --git a/lib/util/signal.c b/lib/util/signal.c
index ead947eb5e..33a9900fb4 100644
--- a/lib/util/signal.c
+++ b/lib/util/signal.c
@@ -129,16 +129,16 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int)
Ignore SIGCLD via whatever means is necessary for this OS.
**/
-void CatchChild(void)
+void (*CatchChild(void))(int)
{
- CatchSignal(SIGCLD, sig_cld);
+ return CatchSignal(SIGCLD, sig_cld);
}
/**
Catch SIGCLD but leave the child around so it's status can be reaped.
**/
-void CatchChildLeaveStatus(void)
+void (*CatchChildLeaveStatus(void))(int)
{
- CatchSignal(SIGCLD, sig_cld_leave_status);
+ return CatchSignal(SIGCLD, sig_cld_leave_status);
}
diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h
index 243fafc27e..fcc088ca04 100644
--- a/lib/util/string_wrappers.h
+++ b/lib/util/string_wrappers.h
@@ -43,11 +43,6 @@ do { \
const char *_fstrcat_src = (const char *)(s); \
strlcat((d),_fstrcat_src ? _fstrcat_src : "",sizeof(fstring)); \
} while (0)
-#define nstrcpy(d,s) \
-do { \
- const char *_nstrcpy_src = (const char *)(s); \
- strlcpy((d),_nstrcpy_src ? _nstrcpy_src : "",sizeof(fstring)); \
-} while (0)
#define unstrcpy(d,s) \
do { \
const char *_unstrcpy_src = (const char *)(s); \
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index 5087116174..f161f96351 100755
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -8,7 +8,7 @@ bld.SAMBA_LIBRARY('samba-util',
util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c
util_str.c util_str_common.c substitute.c ms_fnmatch.c
server_id.c dprintf.c parmlist.c bitmap.c pidfile.c
- tevent_debug.c util_process.c''',
+ tevent_debug.c util_process.c memcache.c''',
deps='DYNCONFIG',
public_deps='talloc tevent execinfo uid_wrapper pthread LIBCRYPTO charset util_setid systemd-daemon',
public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h samba_util.h string_wrappers.h',
diff --git a/lib/zlib/contrib/dotzlib/DotZLib.chm b/lib/zlib/contrib/dotzlib/DotZLib.chm
deleted file mode 100644
index 0bc7df76e4..0000000000
--- a/lib/zlib/contrib/dotzlib/DotZLib.chm
+++ /dev/null
Binary files differ