mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
ctdb-build: Change from ctdb-util to samba-util
Remove local lib/util and lib/tdb-wrap. Update wscript, packaging and includes.h. The only potentially surprising thing here is a fake samba-util subsystem that just depends on samba-util-core. As explained in a comment: When a combined build is implemented, CTDB will wanted to build against samba-util rather than samba-util-core. Similarly, other Samba subsystems expect samba-util. So, for a standalone build, just define a fake samba-util subsystem that pulls in samba-util-core. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
parent
43266be945
commit
59c3025706
@ -7,7 +7,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
CFLAGS="-Wall -g -D_GNU_SOURCE" ./configure \
|
CFLAGS="-Wall -g -D_GNU_SOURCE" ./configure \
|
||||||
--builtin-libraries=replace,popt \
|
--builtin-libraries=replace,popt,samba-debug,socket-blocking,tdb-wrap \
|
||||||
--bundled-libraries=!talloc,!tevent,!tdb \
|
--bundled-libraries=!talloc,!tevent,!tdb \
|
||||||
--minimum-library-version=talloc:2.0.8,tdb:1.2.11,tevent:0.9.16 \
|
--minimum-library-version=talloc:2.0.8,tdb:1.2.11,tevent:0.9.16 \
|
||||||
--prefix=/usr \
|
--prefix=/usr \
|
||||||
|
@ -38,17 +38,7 @@
|
|||||||
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
|
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct timeval timeval_zero(void);
|
|
||||||
bool timeval_is_zero(const struct timeval *tv);
|
|
||||||
struct timeval timeval_current(void);
|
|
||||||
struct timeval timeval_set(uint32_t secs, uint32_t usecs);
|
|
||||||
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2);
|
|
||||||
struct timeval timeval_until(const struct timeval *tv1,
|
|
||||||
const struct timeval *tv2);
|
|
||||||
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
|
|
||||||
double timeval_elapsed(struct timeval *tv);
|
|
||||||
|
|
||||||
#include "lib/util/debug.h"
|
#include "lib/util/debug.h"
|
||||||
#include "lib/util/util.h"
|
#include "lib/util/samba_util.h"
|
||||||
|
|
||||||
#endif /* _CTDB_INCLUDES_H */
|
#endif /* _CTDB_INCLUDES_H */
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
database wrap functions
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2004
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
the stupidity of the unix fcntl locking design forces us to never
|
|
||||||
allow a database file to be opened twice in the same process. These
|
|
||||||
wrappers provide convenient access to a tdb or ldb, taking advantage
|
|
||||||
of talloc destructors to ensure that only a single open is done
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "replace.h"
|
|
||||||
#include "lib/util/dlinklist.h"
|
|
||||||
#include "lib/util/debug.h"
|
|
||||||
|
|
||||||
#include "ctdb_logging.h"
|
|
||||||
|
|
||||||
#include "tdb_wrap.h"
|
|
||||||
|
|
||||||
static struct tdb_wrap *tdb_list;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* destroy the last connection to a tdb */
|
|
||||||
static int tdb_wrap_destructor(struct tdb_wrap *w)
|
|
||||||
{
|
|
||||||
tdb_close(w->tdb);
|
|
||||||
DLIST_REMOVE(tdb_list, w);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if (level <= TDB_DEBUG_ERROR) {
|
|
||||||
va_list ap;
|
|
||||||
char *ptr = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = vasprintf(&ptr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (ret != -1) {
|
|
||||||
const char *name = tdb_name(tdb);
|
|
||||||
DEBUG(level,
|
|
||||||
("%s:%s", name ? name : "unnamed tdb", ptr));
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
wrapped connection to a tdb database
|
|
||||||
to close just talloc_free() the tdb_wrap pointer
|
|
||||||
*/
|
|
||||||
struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
|
|
||||||
const char *name, int hash_size, int tdb_flags,
|
|
||||||
int open_flags, mode_t mode)
|
|
||||||
{
|
|
||||||
struct tdb_wrap *w;
|
|
||||||
struct tdb_logging_context log_ctx;
|
|
||||||
|
|
||||||
log_ctx.log_fn = log_fn;
|
|
||||||
log_ctx.log_private = NULL;
|
|
||||||
|
|
||||||
for (w=tdb_list;w;w=w->next) {
|
|
||||||
if (strcmp(name, w->name) == 0) {
|
|
||||||
return talloc_reference(mem_ctx, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w = talloc(mem_ctx, struct tdb_wrap);
|
|
||||||
if (w == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
w->name = talloc_strdup(w, name);
|
|
||||||
if (w->name == NULL) {
|
|
||||||
talloc_free(w);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
w->tdb = tdb_open_ex(name, hash_size, tdb_flags,
|
|
||||||
open_flags, mode, &log_ctx, NULL);
|
|
||||||
if (w->tdb == NULL) {
|
|
||||||
talloc_free(w);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
talloc_set_destructor(w, tdb_wrap_destructor);
|
|
||||||
|
|
||||||
DLIST_ADD(tdb_list, w);
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
database wrap headers
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2004
|
|
||||||
|
|
||||||
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 _DB_WRAP_H
|
|
||||||
#define _DB_WRAP_H
|
|
||||||
|
|
||||||
#include <talloc.h>
|
|
||||||
#include <tdb.h>
|
|
||||||
|
|
||||||
struct tdb_wrap {
|
|
||||||
struct tdb_context *tdb;
|
|
||||||
|
|
||||||
const char *name;
|
|
||||||
struct tdb_wrap *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
|
|
||||||
const char *name, int hash_size, int tdb_flags,
|
|
||||||
int open_flags, mode_t mode);
|
|
||||||
|
|
||||||
#endif /* _DB_WRAP_H */
|
|
@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
bld.SAMBA_SUBSYSTEM('tdb-wrap',
|
|
||||||
source='tdb_wrap.c',
|
|
||||||
deps='tdb talloc',
|
|
||||||
local_include=False
|
|
||||||
)
|
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
ctdb debug functions
|
|
||||||
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 "system/filesys.h"
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
int DEBUGLEVEL;
|
|
||||||
|
|
||||||
static void print_asc(int level, const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_data(int level, const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
if (len<=0) return;
|
|
||||||
|
|
||||||
if (!DEBUGLVL(level)) return;
|
|
||||||
|
|
||||||
DEBUG(level, (__location__ " dump data of size %i:\n", (int)len));
|
|
||||||
DEBUGADD(level,("[%03X] ",i));
|
|
||||||
for (i=0;i<len;) {
|
|
||||||
DEBUGADD(level,("%02X ",(int)buf[i]));
|
|
||||||
i++;
|
|
||||||
if (i%8 == 0) DEBUGADD(level,(" "));
|
|
||||||
if (i%16 == 0) {
|
|
||||||
print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
|
|
||||||
print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
|
|
||||||
if (i<len) DEBUGADD(level,("[%03X] ",i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i%16) {
|
|
||||||
int n;
|
|
||||||
n = 16 - (i%16);
|
|
||||||
DEBUGADD(level,(" "));
|
|
||||||
if (n>8) DEBUGADD(level,(" "));
|
|
||||||
while (n--) DEBUGADD(level,(" "));
|
|
||||||
n = MIN(8,i%16);
|
|
||||||
print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
|
|
||||||
n = (i%16) - n;
|
|
||||||
if (n>0) print_asc(level,&buf[i-n],n);
|
|
||||||
DEBUGADD(level,("\n"));
|
|
||||||
}
|
|
||||||
DEBUG(level, (__location__ " dump data of size %i finished\n", (int)len));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* state variables for the debug system */
|
|
||||||
static struct {
|
|
||||||
debug_callback_fn callback;
|
|
||||||
void *callback_private;
|
|
||||||
} state;
|
|
||||||
|
|
||||||
static int current_msg_level = 0;
|
|
||||||
|
|
||||||
void debug_set_callback(void *private_ptr, debug_callback_fn fn)
|
|
||||||
{
|
|
||||||
assert(fn != NULL);
|
|
||||||
|
|
||||||
state.callback_private = private_ptr;
|
|
||||||
state.callback = fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dbghdr(int level, const char *location, const char *func)
|
|
||||||
{
|
|
||||||
current_msg_level = level;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dbgtext( const char *format_str, ... )
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
char *msgbuf = NULL;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
va_start(ap, format_str);
|
|
||||||
res = vasprintf(&msgbuf, format_str, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if (res == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.callback != NULL) {
|
|
||||||
state.callback(state.callback_private,
|
|
||||||
current_msg_level, msgbuf);
|
|
||||||
} else {
|
|
||||||
write(2, msgbuf, strlen(msgbuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
free(msgbuf);
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
ctdb debug functions
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UTIL_DEBUG_H
|
|
||||||
#define UTIL_DEBUG_H
|
|
||||||
|
|
||||||
bool dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
|
|
||||||
bool dbghdr( int level, const char *location, const char *func);
|
|
||||||
void dump_data(int level, const uint8_t *buf1, size_t len);
|
|
||||||
|
|
||||||
extern int DEBUGLEVEL;
|
|
||||||
|
|
||||||
#define DEBUGLVL(lvl) ((lvl) <= DEBUGLEVEL)
|
|
||||||
#define DEBUG( lvl, body ) \
|
|
||||||
(void)( ((lvl) <= DEBUGLEVEL) \
|
|
||||||
&& (dbghdr( lvl, __location__, __FUNCTION__ )) \
|
|
||||||
&& (dbgtext body) )
|
|
||||||
#define DEBUGADD(lvl, body) DEBUG(lvl, body)
|
|
||||||
|
|
||||||
typedef void (*debug_callback_fn)(void *private_ptr, int level, const char *msg);
|
|
||||||
void debug_set_callback(void *private_ptr, debug_callback_fn fn);
|
|
||||||
|
|
||||||
#endif /* UTIL_DEBUG_H */
|
|
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
some simple double linked list macros
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 1998-2010
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* To use these macros you must have a structure containing a next and
|
|
||||||
prev pointer */
|
|
||||||
|
|
||||||
#ifndef _DLINKLIST_H
|
|
||||||
#define _DLINKLIST_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
February 2010 - changed list format to have a prev pointer from the
|
|
||||||
list head. This makes DLIST_ADD_END() O(1) even though we only have
|
|
||||||
one list pointer.
|
|
||||||
|
|
||||||
The scheme is as follows:
|
|
||||||
|
|
||||||
1) with no entries in the list:
|
|
||||||
list_head == NULL
|
|
||||||
|
|
||||||
2) with 1 entry in the list:
|
|
||||||
list_head->next == NULL
|
|
||||||
list_head->prev == list_head
|
|
||||||
|
|
||||||
3) with 2 entries in the list:
|
|
||||||
list_head->next == element2
|
|
||||||
list_head->prev == element2
|
|
||||||
element2->prev == list_head
|
|
||||||
element2->next == NULL
|
|
||||||
|
|
||||||
4) with N entries in the list:
|
|
||||||
list_head->next == element2
|
|
||||||
list_head->prev == elementN
|
|
||||||
elementN->prev == element{N-1}
|
|
||||||
elementN->next == NULL
|
|
||||||
|
|
||||||
This allows us to find the tail of the list by using
|
|
||||||
list_head->prev, which means we can add to the end of the list in
|
|
||||||
O(1) time
|
|
||||||
|
|
||||||
|
|
||||||
Note that the 'type' arguments below are no longer needed, but
|
|
||||||
are kept for now to prevent an incompatible argument change
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
add an element at the front of a list
|
|
||||||
*/
|
|
||||||
#define DLIST_ADD(list, p) \
|
|
||||||
do { \
|
|
||||||
if (!(list)) { \
|
|
||||||
(p)->prev = (list) = (p); \
|
|
||||||
(p)->next = NULL; \
|
|
||||||
} else { \
|
|
||||||
(p)->prev = (list)->prev; \
|
|
||||||
(list)->prev = (p); \
|
|
||||||
(p)->next = (list); \
|
|
||||||
(list) = (p); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
remove an element from a list
|
|
||||||
Note that the element doesn't have to be in the list. If it
|
|
||||||
isn't then this is a no-op
|
|
||||||
*/
|
|
||||||
#define DLIST_REMOVE(list, p) \
|
|
||||||
do { \
|
|
||||||
if ((p) == (list)) { \
|
|
||||||
if ((p)->next) (p)->next->prev = (p)->prev; \
|
|
||||||
(list) = (p)->next; \
|
|
||||||
} else if ((list) && (p) == (list)->prev) { \
|
|
||||||
(p)->prev->next = NULL; \
|
|
||||||
(list)->prev = (p)->prev; \
|
|
||||||
} else { \
|
|
||||||
if ((p)->prev) (p)->prev->next = (p)->next; \
|
|
||||||
if ((p)->next) (p)->next->prev = (p)->prev; \
|
|
||||||
} \
|
|
||||||
if ((p) != (list)) (p)->next = (p)->prev = NULL; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
find the head of the list given any element in it.
|
|
||||||
Note that this costs O(N), so you should avoid this macro
|
|
||||||
if at all possible!
|
|
||||||
*/
|
|
||||||
#define DLIST_HEAD(p, result_head) \
|
|
||||||
do { \
|
|
||||||
(result_head) = (p); \
|
|
||||||
while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/* return the last element in the list */
|
|
||||||
#define DLIST_TAIL(list) ((list)?(list)->prev:NULL)
|
|
||||||
|
|
||||||
/* return the previous element in the list. */
|
|
||||||
#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL)
|
|
||||||
|
|
||||||
/* insert 'p' after the given element 'el' in a list. If el is NULL then
|
|
||||||
this is the same as a DLIST_ADD() */
|
|
||||||
#define DLIST_ADD_AFTER(list, p, el) \
|
|
||||||
do { \
|
|
||||||
if (!(list) || !(el)) { \
|
|
||||||
DLIST_ADD(list, p); \
|
|
||||||
} else { \
|
|
||||||
(p)->prev = (el); \
|
|
||||||
(p)->next = (el)->next; \
|
|
||||||
(el)->next = (p); \
|
|
||||||
if ((p)->next) (p)->next->prev = (p); \
|
|
||||||
if ((list)->prev == (el)) (list)->prev = (p); \
|
|
||||||
}\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
add to the end of a list.
|
|
||||||
Note that 'type' is ignored
|
|
||||||
*/
|
|
||||||
#define DLIST_ADD_END(list, p, type) \
|
|
||||||
do { \
|
|
||||||
if (!(list)) { \
|
|
||||||
DLIST_ADD(list, p); \
|
|
||||||
} else { \
|
|
||||||
DLIST_ADD_AFTER(list, p, (list)->prev); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* promote an element to the front of a list */
|
|
||||||
#define DLIST_PROMOTE(list, p) \
|
|
||||||
do { \
|
|
||||||
DLIST_REMOVE(list, p); \
|
|
||||||
DLIST_ADD(list, p); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
demote an element to the end of a list.
|
|
||||||
Note that 'type' is ignored
|
|
||||||
*/
|
|
||||||
#define DLIST_DEMOTE(list, p, type) \
|
|
||||||
do { \
|
|
||||||
DLIST_REMOVE(list, p); \
|
|
||||||
DLIST_ADD_END(list, p, NULL); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
concatenate two lists - putting all elements of the 2nd list at the
|
|
||||||
end of the first list.
|
|
||||||
Note that 'type' is ignored
|
|
||||||
*/
|
|
||||||
#define DLIST_CONCATENATE(list1, list2, type) \
|
|
||||||
do { \
|
|
||||||
if (!(list1)) { \
|
|
||||||
(list1) = (list2); \
|
|
||||||
} else { \
|
|
||||||
(list1)->prev->next = (list2); \
|
|
||||||
if (list2) { \
|
|
||||||
void *_tmplist = (void *)(list1)->prev; \
|
|
||||||
(list1)->prev = (list2)->prev; \
|
|
||||||
(list2)->prev = _tmplist; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* _DLINKLIST_H */
|
|
@ -1,235 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
Critical Fault handling
|
|
||||||
Copyright (C) Andrew Tridgell 1992-1998
|
|
||||||
|
|
||||||
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 "includes.h"
|
|
||||||
#include "system/wait.h"
|
|
||||||
#include "system/filesys.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Fault handling
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* the registered fault handler */
|
|
||||||
static struct {
|
|
||||||
const char *name;
|
|
||||||
void (*fault_handler)(int sig);
|
|
||||||
} fault_handlers;
|
|
||||||
|
|
||||||
static const char *progname;
|
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
|
||||||
#include <execinfo.h>
|
|
||||||
#elif HAVE_LIBEXC_H
|
|
||||||
#include <libexc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write backtrace to debug log
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void call_backtrace(void)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BACKTRACE
|
|
||||||
#ifndef BACKTRACE_STACK_SIZE
|
|
||||||
#define BACKTRACE_STACK_SIZE 64
|
|
||||||
#endif
|
|
||||||
void *backtrace_stack[BACKTRACE_STACK_SIZE];
|
|
||||||
size_t backtrace_size;
|
|
||||||
char **backtrace_strings;
|
|
||||||
|
|
||||||
/* get the backtrace (stack frames) */
|
|
||||||
backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
|
|
||||||
backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
|
|
||||||
|
|
||||||
DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
|
|
||||||
(unsigned long)backtrace_size));
|
|
||||||
|
|
||||||
if (backtrace_strings) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < backtrace_size; i++)
|
|
||||||
DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
|
|
||||||
|
|
||||||
/* Leak the backtrace_strings, rather than risk what free() might do */
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif HAVE_LIBEXC
|
|
||||||
|
|
||||||
#define NAMESIZE 32 /* Arbitrary */
|
|
||||||
#ifndef BACKTRACE_STACK_SIZE
|
|
||||||
#define BACKTRACE_STACK_SIZE 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The IRIX libexc library provides an API for unwinding the stack. See
|
|
||||||
* libexc(3) for details. Apparantly trace_back_stack leaks memory, but
|
|
||||||
* since we are about to abort anyway, it hardly matters.
|
|
||||||
*
|
|
||||||
* Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this
|
|
||||||
* will fail with a nasty message upon failing to open the /proc entry.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
uint64_t addrs[BACKTRACE_STACK_SIZE];
|
|
||||||
char * names[BACKTRACE_STACK_SIZE];
|
|
||||||
char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int levels;
|
|
||||||
|
|
||||||
ZERO_ARRAY(addrs);
|
|
||||||
ZERO_ARRAY(names);
|
|
||||||
ZERO_ARRAY(namebuf);
|
|
||||||
|
|
||||||
for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
|
|
||||||
names[i] = namebuf + (i * NAMESIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
levels = trace_back_stack(0, addrs, names,
|
|
||||||
BACKTRACE_STACK_SIZE, NAMESIZE);
|
|
||||||
|
|
||||||
DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
|
|
||||||
for (i = 0; i < levels; i++) {
|
|
||||||
DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef NAMESIZE
|
|
||||||
#else
|
|
||||||
DEBUG(0, ("call_backtrace: not implemented\n"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
_PUBLIC_ const char *panic_action = NULL;
|
|
||||||
_PUBLIC_ void (*pre_panic_action_hook)(void) = NULL;
|
|
||||||
_PUBLIC_ void (*post_panic_action_hook)(void) = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Something really nasty happened - panic !
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void smb_panic(const char *why)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (panic_action && *panic_action) {
|
|
||||||
char pidstr[20];
|
|
||||||
char cmdstring[200];
|
|
||||||
strlcpy(cmdstring, panic_action, sizeof(cmdstring));
|
|
||||||
snprintf(pidstr, sizeof(pidstr), "%u", getpid());
|
|
||||||
all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring));
|
|
||||||
if (progname) {
|
|
||||||
all_string_sub(cmdstring, "%PROG%", progname, sizeof(cmdstring));
|
|
||||||
}
|
|
||||||
DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
|
|
||||||
|
|
||||||
if (pre_panic_action_hook) {
|
|
||||||
pre_panic_action_hook();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = system(cmdstring);
|
|
||||||
|
|
||||||
if (post_panic_action_hook) {
|
|
||||||
post_panic_action_hook();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == -1)
|
|
||||||
DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
|
|
||||||
strerror(errno)));
|
|
||||||
else
|
|
||||||
DEBUG(0, ("smb_panic(): action returned status %d\n",
|
|
||||||
WEXITSTATUS(result)));
|
|
||||||
}
|
|
||||||
DEBUG(0,("PANIC: %s\n", why));
|
|
||||||
|
|
||||||
call_backtrace();
|
|
||||||
|
|
||||||
#ifdef SIGABRT
|
|
||||||
CatchSignal(SIGABRT, SIG_DFL);
|
|
||||||
#endif
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
report a fault
|
|
||||||
**/
|
|
||||||
_NORETURN_ static void fault_report(int sig)
|
|
||||||
{
|
|
||||||
static int counter;
|
|
||||||
|
|
||||||
if (counter) _exit(1);
|
|
||||||
|
|
||||||
DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
|
|
||||||
DEBUG(0,("INTERNAL ERROR: Signal %d in %s pid %d",sig, progname, (int)getpid()));
|
|
||||||
DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
|
|
||||||
DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
|
|
||||||
|
|
||||||
smb_panic("internal error");
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
catch serious errors
|
|
||||||
**/
|
|
||||||
_NORETURN_ static void sig_fault(int sig)
|
|
||||||
{
|
|
||||||
if (fault_handlers.fault_handler) {
|
|
||||||
/* we have a fault handler, call it. It may not return. */
|
|
||||||
fault_handlers.fault_handler(sig);
|
|
||||||
}
|
|
||||||
/* If it returns or doesn't exist, use regular reporter */
|
|
||||||
fault_report(sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
setup our fault handlers
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void fault_setup(void)
|
|
||||||
{
|
|
||||||
#ifdef SIGSEGV
|
|
||||||
CatchSignal(SIGSEGV, sig_fault);
|
|
||||||
#endif
|
|
||||||
#ifdef SIGBUS
|
|
||||||
CatchSignal(SIGBUS, sig_fault);
|
|
||||||
#endif
|
|
||||||
#ifdef SIGABRT
|
|
||||||
CatchSignal(SIGABRT, sig_fault);
|
|
||||||
#endif
|
|
||||||
#ifdef SIGFPE
|
|
||||||
CatchSignal(SIGFPE, sig_fault);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
register a fault handler.
|
|
||||||
Should only be called once in the execution of smbd.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool register_fault_handler(const char *name,
|
|
||||||
void (*fault_handler)(int sig))
|
|
||||||
{
|
|
||||||
if (fault_handlers.name != NULL) {
|
|
||||||
/* it's already registered! */
|
|
||||||
DEBUG(2,("fault handler '%s' already registered - failed '%s'\n",
|
|
||||||
fault_handlers.name, name));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fault_handlers.name = name;
|
|
||||||
fault_handlers.fault_handler = fault_handler;
|
|
||||||
|
|
||||||
DEBUG(2,("fault handler '%s' registered\n", name));
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,387 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
very efficient functions to manage mapping a id (such as a fnum) to
|
|
||||||
a pointer. This is used for fnum and search id allocation.
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2004
|
|
||||||
|
|
||||||
This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
|
|
||||||
written by Jim Houston jim.houston@ccur.com, and is
|
|
||||||
Copyright (C) 2002 by Concurrent Computer Corporation
|
|
||||||
|
|
||||||
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 2 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
see the section marked "public interface" below for documentation
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
|
|
||||||
#define IDR_BITS 5
|
|
||||||
#define IDR_FULL 0xfffffffful
|
|
||||||
#if 0 /* unused */
|
|
||||||
#define TOP_LEVEL_FULL (IDR_FULL >> 30)
|
|
||||||
#endif
|
|
||||||
#define IDR_SIZE (1 << IDR_BITS)
|
|
||||||
#define IDR_MASK ((1 << IDR_BITS)-1)
|
|
||||||
#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
|
|
||||||
#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
|
|
||||||
#define MAX_ID_MASK (MAX_ID_BIT - 1)
|
|
||||||
#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
|
|
||||||
#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
|
|
||||||
|
|
||||||
#define set_bit(bit, v) (v) |= (1<<(bit))
|
|
||||||
#define clear_bit(bit, v) (v) &= ~(1<<(bit))
|
|
||||||
#define test_bit(bit, v) ((v) & (1<<(bit)))
|
|
||||||
|
|
||||||
struct idr_layer {
|
|
||||||
uint32_t bitmap;
|
|
||||||
struct idr_layer *ary[IDR_SIZE];
|
|
||||||
int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct idr_context {
|
|
||||||
struct idr_layer *top;
|
|
||||||
struct idr_layer *id_free;
|
|
||||||
int layers;
|
|
||||||
int id_free_cnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct idr_layer *alloc_layer(struct idr_context *idp)
|
|
||||||
{
|
|
||||||
struct idr_layer *p;
|
|
||||||
|
|
||||||
if (!(p = idp->id_free))
|
|
||||||
return NULL;
|
|
||||||
idp->id_free = p->ary[0];
|
|
||||||
idp->id_free_cnt--;
|
|
||||||
p->ary[0] = NULL;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_next_bit(uint32_t bm, int maxid, int n)
|
|
||||||
{
|
|
||||||
while (n<maxid && !test_bit(n, bm)) n++;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_layer(struct idr_context *idp, struct idr_layer *p)
|
|
||||||
{
|
|
||||||
p->ary[0] = idp->id_free;
|
|
||||||
idp->id_free = p;
|
|
||||||
idp->id_free_cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int idr_pre_get(struct idr_context *idp)
|
|
||||||
{
|
|
||||||
while (idp->id_free_cnt < IDR_FREE_MAX) {
|
|
||||||
struct idr_layer *new = talloc_zero(idp, struct idr_layer);
|
|
||||||
if(new == NULL)
|
|
||||||
return (0);
|
|
||||||
free_layer(idp, new);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id)
|
|
||||||
{
|
|
||||||
int n, m, sh;
|
|
||||||
struct idr_layer *p, *new;
|
|
||||||
struct idr_layer *pa[MAX_LEVEL+1];
|
|
||||||
unsigned int l, id, oid;
|
|
||||||
uint32_t bm;
|
|
||||||
|
|
||||||
memset(pa, 0, sizeof(pa));
|
|
||||||
|
|
||||||
id = *starting_id;
|
|
||||||
restart:
|
|
||||||
p = idp->top;
|
|
||||||
l = idp->layers;
|
|
||||||
pa[l--] = NULL;
|
|
||||||
while (1) {
|
|
||||||
/*
|
|
||||||
* We run around this while until we reach the leaf node...
|
|
||||||
*/
|
|
||||||
n = (id >> (IDR_BITS*l)) & IDR_MASK;
|
|
||||||
bm = ~p->bitmap;
|
|
||||||
m = find_next_bit(bm, IDR_SIZE, n);
|
|
||||||
if (m == IDR_SIZE) {
|
|
||||||
/* no space available go back to previous layer. */
|
|
||||||
l++;
|
|
||||||
oid = id;
|
|
||||||
id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
|
|
||||||
|
|
||||||
/* if already at the top layer, we need to grow */
|
|
||||||
if (!(p = pa[l])) {
|
|
||||||
*starting_id = id;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we need to go up one layer, continue the
|
|
||||||
* loop; otherwise, restart from the top.
|
|
||||||
*/
|
|
||||||
sh = IDR_BITS * (l + 1);
|
|
||||||
if (oid >> sh == id >> sh)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
if (m != n) {
|
|
||||||
sh = IDR_BITS*l;
|
|
||||||
id = ((id >> sh) ^ n ^ m) << sh;
|
|
||||||
}
|
|
||||||
if ((id >= MAX_ID_BIT) || (id < 0))
|
|
||||||
return -1;
|
|
||||||
if (l == 0)
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
* Create the layer below if it is missing.
|
|
||||||
*/
|
|
||||||
if (!p->ary[m]) {
|
|
||||||
if (!(new = alloc_layer(idp)))
|
|
||||||
return -1;
|
|
||||||
p->ary[m] = new;
|
|
||||||
p->count++;
|
|
||||||
}
|
|
||||||
pa[l--] = p;
|
|
||||||
p = p->ary[m];
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* We have reached the leaf node, plant the
|
|
||||||
* users pointer and return the raw id.
|
|
||||||
*/
|
|
||||||
p->ary[m] = (struct idr_layer *)ptr;
|
|
||||||
set_bit(m, p->bitmap);
|
|
||||||
p->count++;
|
|
||||||
/*
|
|
||||||
* If this layer is full mark the bit in the layer above
|
|
||||||
* to show that this part of the radix tree is full.
|
|
||||||
* This may complete the layer above and require walking
|
|
||||||
* up the radix tree.
|
|
||||||
*/
|
|
||||||
n = id;
|
|
||||||
while (p->bitmap == IDR_FULL) {
|
|
||||||
if (!(p = pa[++l]))
|
|
||||||
break;
|
|
||||||
n = n >> IDR_BITS;
|
|
||||||
set_bit((n & IDR_MASK), p->bitmap);
|
|
||||||
}
|
|
||||||
return(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id)
|
|
||||||
{
|
|
||||||
struct idr_layer *p, *new;
|
|
||||||
int layers, v, id;
|
|
||||||
|
|
||||||
idr_pre_get(idp);
|
|
||||||
|
|
||||||
id = starting_id;
|
|
||||||
build_up:
|
|
||||||
p = idp->top;
|
|
||||||
layers = idp->layers;
|
|
||||||
if (!p) {
|
|
||||||
if (!(p = alloc_layer(idp)))
|
|
||||||
return -1;
|
|
||||||
layers = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Add a new layer to the top of the tree if the requested
|
|
||||||
* id is larger than the currently allocated space.
|
|
||||||
*/
|
|
||||||
while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
|
|
||||||
layers++;
|
|
||||||
if (!p->count)
|
|
||||||
continue;
|
|
||||||
if (!(new = alloc_layer(idp))) {
|
|
||||||
/*
|
|
||||||
* The allocation failed. If we built part of
|
|
||||||
* the structure tear it down.
|
|
||||||
*/
|
|
||||||
for (new = p; p && p != idp->top; new = p) {
|
|
||||||
p = p->ary[0];
|
|
||||||
new->ary[0] = NULL;
|
|
||||||
new->bitmap = new->count = 0;
|
|
||||||
free_layer(idp, new);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
new->ary[0] = p;
|
|
||||||
new->count = 1;
|
|
||||||
if (p->bitmap == IDR_FULL)
|
|
||||||
set_bit(0, new->bitmap);
|
|
||||||
p = new;
|
|
||||||
}
|
|
||||||
idp->top = p;
|
|
||||||
idp->layers = layers;
|
|
||||||
v = sub_alloc(idp, ptr, &id);
|
|
||||||
if (v == -2)
|
|
||||||
goto build_up;
|
|
||||||
return(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sub_remove(struct idr_context *idp, int shift, int id)
|
|
||||||
{
|
|
||||||
struct idr_layer *p = idp->top;
|
|
||||||
struct idr_layer **pa[1+MAX_LEVEL];
|
|
||||||
struct idr_layer ***paa = &pa[0];
|
|
||||||
int n;
|
|
||||||
|
|
||||||
*paa = NULL;
|
|
||||||
*++paa = &idp->top;
|
|
||||||
|
|
||||||
while ((shift > 0) && p) {
|
|
||||||
n = (id >> shift) & IDR_MASK;
|
|
||||||
clear_bit(n, p->bitmap);
|
|
||||||
*++paa = &p->ary[n];
|
|
||||||
p = p->ary[n];
|
|
||||||
shift -= IDR_BITS;
|
|
||||||
}
|
|
||||||
n = id & IDR_MASK;
|
|
||||||
if (p != NULL && test_bit(n, p->bitmap)) {
|
|
||||||
clear_bit(n, p->bitmap);
|
|
||||||
p->ary[n] = NULL;
|
|
||||||
while(*paa && ! --((**paa)->count)){
|
|
||||||
free_layer(idp, **paa);
|
|
||||||
**paa-- = NULL;
|
|
||||||
}
|
|
||||||
if ( ! *paa )
|
|
||||||
idp->layers = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *_idr_find(struct idr_context *idp, int id)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
struct idr_layer *p;
|
|
||||||
|
|
||||||
n = idp->layers * IDR_BITS;
|
|
||||||
p = idp->top;
|
|
||||||
/*
|
|
||||||
* This tests to see if bits outside the current tree are
|
|
||||||
* present. If so, tain't one of ours!
|
|
||||||
*/
|
|
||||||
if (n + IDR_BITS < 31 &&
|
|
||||||
((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS))) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mask off upper bits we don't use for the search. */
|
|
||||||
id &= MAX_ID_MASK;
|
|
||||||
|
|
||||||
while (n >= IDR_BITS && p) {
|
|
||||||
n -= IDR_BITS;
|
|
||||||
p = p->ary[(id >> n) & IDR_MASK];
|
|
||||||
}
|
|
||||||
return((void *)p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _idr_remove(struct idr_context *idp, int id)
|
|
||||||
{
|
|
||||||
struct idr_layer *p;
|
|
||||||
|
|
||||||
/* Mask off upper bits we don't use for the search. */
|
|
||||||
id &= MAX_ID_MASK;
|
|
||||||
|
|
||||||
if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( idp->top && idp->top->count == 1 &&
|
|
||||||
(idp->layers > 1) &&
|
|
||||||
idp->top->ary[0]) {
|
|
||||||
/* We can drop a layer */
|
|
||||||
p = idp->top->ary[0];
|
|
||||||
idp->top->bitmap = idp->top->count = 0;
|
|
||||||
free_layer(idp, idp->top);
|
|
||||||
idp->top = p;
|
|
||||||
--idp->layers;
|
|
||||||
}
|
|
||||||
while (idp->id_free_cnt >= IDR_FREE_MAX) {
|
|
||||||
p = alloc_layer(idp);
|
|
||||||
talloc_free(p);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
this is the public interface
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
initialise a idr tree. The context return value must be passed to
|
|
||||||
all subsequent idr calls. To destroy the idr tree use talloc_free()
|
|
||||||
on this context
|
|
||||||
*/
|
|
||||||
_PUBLIC_ struct idr_context *idr_init(TALLOC_CTX *mem_ctx)
|
|
||||||
{
|
|
||||||
return talloc_zero(mem_ctx, struct idr_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
allocate the next available id, and assign 'ptr' into its slot.
|
|
||||||
you can retrieve later this pointer using idr_find()
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_get_new(struct idr_context *idp, void *ptr, int limit)
|
|
||||||
{
|
|
||||||
int ret = idr_get_new_above_int(idp, ptr, 0);
|
|
||||||
if (ret > limit) {
|
|
||||||
idr_remove(idp, ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
allocate a new id, giving the first available value greater than or
|
|
||||||
equal to the given starting id
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit)
|
|
||||||
{
|
|
||||||
int ret = idr_get_new_above_int(idp, ptr, starting_id);
|
|
||||||
if (ret > limit) {
|
|
||||||
idr_remove(idp, ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
find a pointer value previously set with idr_get_new given an id
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void *idr_find(struct idr_context *idp, int id)
|
|
||||||
{
|
|
||||||
return _idr_find(idp, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
remove an id from the idr tree
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_remove(struct idr_context *idp, int id)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
ret = _idr_remove((struct idr_context *)idp, id);
|
|
||||||
if (ret != 0) {
|
|
||||||
DEBUG(0,("WARNING: attempt to remove unset id %d in idtree\n", id));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
signal handling functions
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 1998
|
|
||||||
|
|
||||||
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 "includes.h"
|
|
||||||
#include "system/wait.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Signal handling
|
|
||||||
*/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
Catch child exits and reap the child zombie status.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void sig_cld(int signum)
|
|
||||||
{
|
|
||||||
while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Turns out it's *really* important not to
|
|
||||||
* restore the signal handler here if we have real POSIX
|
|
||||||
* signal handling. If we do, then we get the signal re-delivered
|
|
||||||
* immediately - hey presto - instant loop ! JRA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(HAVE_SIGACTION)
|
|
||||||
CatchSignal(SIGCLD, sig_cld);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
catch child exits - leave status;
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void sig_cld_leave_status(int signum)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Turns out it's *really* important not to
|
|
||||||
* restore the signal handler here if we have real POSIX
|
|
||||||
* signal handling. If we do, then we get the signal re-delivered
|
|
||||||
* immediately - hey presto - instant loop ! JRA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(HAVE_SIGACTION)
|
|
||||||
CatchSignal(SIGCLD, sig_cld_leave_status);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Block sigs.
|
|
||||||
**/
|
|
||||||
|
|
||||||
void BlockSignals(bool block, int signum)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_SIGPROCMASK
|
|
||||||
sigset_t set;
|
|
||||||
sigemptyset(&set);
|
|
||||||
sigaddset(&set,signum);
|
|
||||||
sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
|
|
||||||
#elif defined(HAVE_SIGBLOCK)
|
|
||||||
if (block) {
|
|
||||||
sigblock(sigmask(signum));
|
|
||||||
} else {
|
|
||||||
sigsetmask(siggetmask() & ~sigmask(signum));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* yikes! This platform can't block signals? */
|
|
||||||
static int done;
|
|
||||||
if (!done) {
|
|
||||||
DEBUG(0,("WARNING: No signal blocking available\n"));
|
|
||||||
done=1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Catch a signal. This should implement the following semantics:
|
|
||||||
|
|
||||||
1) The handler remains installed after being called.
|
|
||||||
2) The signal should be blocked during handler execution.
|
|
||||||
**/
|
|
||||||
|
|
||||||
void (*CatchSignal(int signum,void (*handler)(int )))(int)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_SIGACTION
|
|
||||||
struct sigaction act;
|
|
||||||
struct sigaction oldact;
|
|
||||||
|
|
||||||
ZERO_STRUCT(act);
|
|
||||||
|
|
||||||
act.sa_handler = handler;
|
|
||||||
#ifdef SA_RESTART
|
|
||||||
/*
|
|
||||||
* We *want* SIGALRM to interrupt a system call.
|
|
||||||
*/
|
|
||||||
if(signum != SIGALRM)
|
|
||||||
act.sa_flags = SA_RESTART;
|
|
||||||
#endif
|
|
||||||
sigemptyset(&act.sa_mask);
|
|
||||||
sigaddset(&act.sa_mask,signum);
|
|
||||||
sigaction(signum,&act,&oldact);
|
|
||||||
return oldact.sa_handler;
|
|
||||||
#else /* !HAVE_SIGACTION */
|
|
||||||
/* FIXME: need to handle sigvec and systems with broken signal() */
|
|
||||||
return signal(signum, handler);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ignore SIGCLD via whatever means is necessary for this OS.
|
|
||||||
**/
|
|
||||||
|
|
||||||
void (*CatchChild(void))(int)
|
|
||||||
{
|
|
||||||
return CatchSignal(SIGCLD, sig_cld);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Catch SIGCLD but leave the child around so it's status can be reaped.
|
|
||||||
**/
|
|
||||||
|
|
||||||
void (*CatchChildLeaveStatus(void))(int)
|
|
||||||
{
|
|
||||||
return CatchSignal(SIGCLD, sig_cld_leave_status);
|
|
||||||
}
|
|
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
Samba utility functions
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 1992-2001
|
|
||||||
Copyright (C) Simo Sorce 2001-2002
|
|
||||||
Copyright (C) Martin Pool 2003
|
|
||||||
Copyright (C) James Peach 2005
|
|
||||||
|
|
||||||
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 "includes.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Substitute utilities.
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
|
||||||
Substitute a string for a pattern in another string. Make sure there is
|
|
||||||
enough room!
|
|
||||||
|
|
||||||
This routine looks for pattern in s and replaces it with
|
|
||||||
insert. It may do multiple replacements.
|
|
||||||
|
|
||||||
Any of " ; ' $ or ` in the insert string are replaced with _
|
|
||||||
if len==0 then the string cannot be extended. This is different from the old
|
|
||||||
use of len==0 which was for no length checks to be done.
|
|
||||||
**/
|
|
||||||
|
|
||||||
_PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_t len)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
ssize_t ls, lp, li, i;
|
|
||||||
|
|
||||||
if (!insert || !pattern || !*pattern || !s)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ls = (ssize_t)strlen(s);
|
|
||||||
lp = (ssize_t)strlen(pattern);
|
|
||||||
li = (ssize_t)strlen(insert);
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
len = ls + 1; /* len is number of *bytes* */
|
|
||||||
|
|
||||||
while (lp <= ls && (p = strstr(s, pattern))) {
|
|
||||||
if (ls + (li-lp) >= len) {
|
|
||||||
DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
|
|
||||||
(int)(ls + (li-lp) - len),
|
|
||||||
pattern, (int)len));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (li != lp) {
|
|
||||||
memmove(p+li,p+lp,strlen(p+lp)+1);
|
|
||||||
}
|
|
||||||
for (i=0;i<li;i++) {
|
|
||||||
switch (insert[i]) {
|
|
||||||
case '`':
|
|
||||||
case '"':
|
|
||||||
case '\'':
|
|
||||||
case ';':
|
|
||||||
case '$':
|
|
||||||
case '%':
|
|
||||||
case '\r':
|
|
||||||
case '\n':
|
|
||||||
p[i] = '_';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
p[i] = insert[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s = p + li;
|
|
||||||
ls += (li-lp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Talloc'ed version of string_sub
|
|
||||||
*/
|
|
||||||
_PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s,
|
|
||||||
const char *pattern, const char *insert)
|
|
||||||
{
|
|
||||||
const char *p;
|
|
||||||
char *ret;
|
|
||||||
size_t len, alloc_len;
|
|
||||||
|
|
||||||
if (insert == NULL || pattern == NULL || !*pattern || s == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* determine length needed */
|
|
||||||
len = strlen(s);
|
|
||||||
|
|
||||||
for (p = strstr(s, pattern); p != NULL;
|
|
||||||
p = strstr(p+strlen(pattern), pattern)) {
|
|
||||||
len += strlen(insert) - strlen(pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
alloc_len = MAX(len, strlen(s))+1;
|
|
||||||
ret = talloc_array(mem_ctx, char, alloc_len);
|
|
||||||
if (ret == NULL)
|
|
||||||
return NULL;
|
|
||||||
strncpy(ret, s, alloc_len);
|
|
||||||
string_sub(ret, pattern, insert, alloc_len);
|
|
||||||
|
|
||||||
ret = talloc_realloc(mem_ctx, ret, char, len+1);
|
|
||||||
if (ret == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
SMB_ASSERT(ret[len] == '\0');
|
|
||||||
|
|
||||||
talloc_set_name_const(ret, ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Similar to string_sub() but allows for any character to be substituted.
|
|
||||||
Use with caution!
|
|
||||||
if len==0 then the string cannot be extended. This is different from the old
|
|
||||||
use of len==0 which was for no length checks to be done.
|
|
||||||
**/
|
|
||||||
|
|
||||||
_PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
ssize_t ls,lp,li;
|
|
||||||
|
|
||||||
if (!insert || !pattern || !s)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ls = (ssize_t)strlen(s);
|
|
||||||
lp = (ssize_t)strlen(pattern);
|
|
||||||
li = (ssize_t)strlen(insert);
|
|
||||||
|
|
||||||
if (!*pattern)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
len = ls + 1; /* len is number of *bytes* */
|
|
||||||
|
|
||||||
while (lp <= ls && (p = strstr(s,pattern))) {
|
|
||||||
if (ls + (li-lp) >= len) {
|
|
||||||
DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
|
|
||||||
(int)(ls + (li-lp) - len),
|
|
||||||
pattern, (int)len));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (li != lp) {
|
|
||||||
memmove(p+li,p+lp,strlen(p+lp)+1);
|
|
||||||
}
|
|
||||||
memcpy(p, insert, li);
|
|
||||||
s = p + li;
|
|
||||||
ls += (li-lp);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2005
|
|
||||||
|
|
||||||
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 "includes.h"
|
|
||||||
#include "system/filesys.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
|
|
||||||
else
|
|
||||||
if SYSV use O_NDELAY
|
|
||||||
if BSD use FNDELAY
|
|
||||||
**/
|
|
||||||
|
|
||||||
_PUBLIC_ int set_blocking(int fd, bool set)
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
#ifdef O_NONBLOCK
|
|
||||||
#define FLAG_TO_SET O_NONBLOCK
|
|
||||||
#else
|
|
||||||
#ifdef SYSV
|
|
||||||
#define FLAG_TO_SET O_NDELAY
|
|
||||||
#else /* BSD */
|
|
||||||
#define FLAG_TO_SET FNDELAY
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
|
||||||
return -1;
|
|
||||||
if(set) /* Turn blocking on - ie. clear nonblock flag */
|
|
||||||
val &= ~FLAG_TO_SET;
|
|
||||||
else
|
|
||||||
val |= FLAG_TO_SET;
|
|
||||||
return fcntl( fd, F_SETFL, val);
|
|
||||||
#undef FLAG_TO_SET
|
|
||||||
}
|
|
@ -1,565 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
Utility functions for Samba
|
|
||||||
Copyright (C) Andrew Tridgell 1992-1999
|
|
||||||
Copyright (C) Jelmer Vernooij 2005
|
|
||||||
|
|
||||||
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 _SAMBA_UTIL_H_
|
|
||||||
#define _SAMBA_UTIL_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Helpful macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct smbsrv_tcon;
|
|
||||||
|
|
||||||
#ifdef _SAMBA_BUILD_
|
|
||||||
extern const char *logfile;
|
|
||||||
#endif
|
|
||||||
extern const char *panic_action;
|
|
||||||
extern void (*pre_panic_action_hook)(void);
|
|
||||||
extern void (*post_panic_action_hook)(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* assert macros
|
|
||||||
*/
|
|
||||||
#ifdef DEVELOPER
|
|
||||||
#define SMB_ASSERT(b) do { if (!(b)) { \
|
|
||||||
DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \
|
|
||||||
__FILE__, __LINE__, #b)); smb_panic("assert failed: " #b); }} while(0)
|
|
||||||
#else
|
|
||||||
/* redefine the assert macro for non-developer builds */
|
|
||||||
#define SMB_ASSERT(b) do { if (!(b)) { \
|
|
||||||
DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \
|
|
||||||
__FILE__, __LINE__, #b)); }} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _SAMBA_BUILD_ == 4
|
|
||||||
#ifdef VALGRIND
|
|
||||||
#define strlen(x) valgrind_strlen(x)
|
|
||||||
size_t valgrind_strlen(const char *s);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ABS
|
|
||||||
#define ABS(a) ((a)>0?(a):(-(a)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write backtrace to debug log
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void call_backtrace(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Something really nasty happened - panic !
|
|
||||||
**/
|
|
||||||
_PUBLIC_ _NORETURN_ void smb_panic(const char *why);
|
|
||||||
|
|
||||||
/**
|
|
||||||
setup our fault handlers
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void fault_setup(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
register a fault handler.
|
|
||||||
Should only be called once in the execution of smbd.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool register_fault_handler(const char *name, void (*fault_handler)(int sig));
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/signal.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Block sigs.
|
|
||||||
**/
|
|
||||||
void BlockSignals(bool block, int signum);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Catch a signal. This should implement the following semantics:
|
|
||||||
|
|
||||||
1) The handler remains installed after being called.
|
|
||||||
2) The signal should be blocked during handler execution.
|
|
||||||
**/
|
|
||||||
void (*CatchSignal(int signum,void (*handler)(int )))(int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ignore SIGCLD via whatever means is necessary for this OS.
|
|
||||||
**/
|
|
||||||
void (*CatchChild(void))(int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Catch SIGCLD but leave the child around so it's status can be reaped.
|
|
||||||
**/
|
|
||||||
void (*CatchChildLeaveStatus(void))(int);
|
|
||||||
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/util_str.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Trim the specified elements off the front and back of a string.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool trim_string(char *s, const char *front, const char *back);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Find the number of 'c' chars in a string
|
|
||||||
**/
|
|
||||||
_PUBLIC_ _PURE_ size_t count_chars(const char *s, char c);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Safe string copy into a known length string. maxlength does not
|
|
||||||
include the terminating zero.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *safe_strcpy(char *dest,const char *src, size_t maxlength);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Safe string cat into a string. maxlength does not
|
|
||||||
include the terminating zero.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Routine to get hex characters and turn them into a 16 byte array.
|
|
||||||
the array can be variable length, and any non-hex-numeric
|
|
||||||
characters are skipped. "0xnn" or "0Xnn" is specially catered
|
|
||||||
for.
|
|
||||||
|
|
||||||
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
|
|
||||||
|
|
||||||
|
|
||||||
**/
|
|
||||||
_PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len);
|
|
||||||
|
|
||||||
#ifdef _SAMBA_BUILD_
|
|
||||||
/**
|
|
||||||
* Parse a hex string and return a data blob.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routine to print a buffer as HEX digits, into an allocated string.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* talloc version of hex_encode()
|
|
||||||
*/
|
|
||||||
_PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Substitute a string for a pattern in another string. Make sure there is
|
|
||||||
enough room!
|
|
||||||
|
|
||||||
This routine looks for pattern in s and replaces it with
|
|
||||||
insert. It may do multiple replacements.
|
|
||||||
|
|
||||||
Any of " ; ' $ or ` in the insert string are replaced with _
|
|
||||||
if len==0 then the string cannot be extended. This is different from the old
|
|
||||||
use of len==0 which was for no length checks to be done.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t len);
|
|
||||||
|
|
||||||
|
|
||||||
_PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s,
|
|
||||||
const char *pattern, const char *insert);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Similar to string_sub() but allows for any character to be substituted.
|
|
||||||
Use with caution!
|
|
||||||
if len==0 then the string cannot be extended. This is different from the old
|
|
||||||
use of len==0 which was for no length checks to be done.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Unescape a URL encoded string, in place.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void rfc1738_unescape(char *buf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
format a string into length-prefixed dotted domain format, as used in NBT
|
|
||||||
and in some ADS structures
|
|
||||||
**/
|
|
||||||
_PUBLIC_ const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a string to an array of strings.
|
|
||||||
*
|
|
||||||
* num should be a pointer to an integer that holds the current
|
|
||||||
* number of elements in strings. It will be updated by this function.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool add_string_to_array(TALLOC_CTX *mem_ctx,
|
|
||||||
const char *str, const char ***strings, int *num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
varient of strcmp() that handles NULL ptrs
|
|
||||||
**/
|
|
||||||
_PUBLIC_ int strcmp_safe(const char *s1, const char *s2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
return the number of bytes occupied by a buffer in ASCII format
|
|
||||||
the result includes the null termination
|
|
||||||
limited by 'n' bytes
|
|
||||||
**/
|
|
||||||
_PUBLIC_ size_t ascii_len_n(const char *src, size_t n);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set a boolean variable from the text value stored in the passed string.
|
|
||||||
Returns true in success, false if the passed string does not correctly
|
|
||||||
represent a boolean.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a string containing a boolean value.
|
|
||||||
*
|
|
||||||
* val will be set to the read value.
|
|
||||||
*
|
|
||||||
* @retval true if a boolean value was parsed, false otherwise.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool conv_str_bool(const char * str, bool * val);
|
|
||||||
|
|
||||||
#if _SAMBA_BUILD_ == 4
|
|
||||||
/**
|
|
||||||
* Convert a size specification like 16K into an integral number of bytes.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool conv_str_size(const char * str, uint64_t * val);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a uint64_t value from a string
|
|
||||||
*
|
|
||||||
* val will be set to the value read.
|
|
||||||
*
|
|
||||||
* @retval true if parsing was successful, false otherwise
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
return the number of bytes occupied by a buffer in CH_UTF16 format
|
|
||||||
the result includes the null termination
|
|
||||||
**/
|
|
||||||
_PUBLIC_ size_t utf16_len(const void *buf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
return the number of bytes occupied by a buffer in CH_UTF16 format
|
|
||||||
the result includes the null termination
|
|
||||||
limited by 'n' bytes
|
|
||||||
**/
|
|
||||||
_PUBLIC_ size_t utf16_len_n(const void *src, size_t n);
|
|
||||||
_PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Do a case-insensitive, whitespace-ignoring string compare.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ int strwicmp(const char *psz1, const char *psz2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
String replace.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void string_replace(char *s, char oldc, char newc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare 2 strings.
|
|
||||||
*
|
|
||||||
* @note The comparison is case-insensitive.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool strequal(const char *s1, const char *s2);
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/util_file.c */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _SAMBA_BUILD_
|
|
||||||
/**
|
|
||||||
read a line from a file with possible \ continuation chars.
|
|
||||||
Blanks at the start or end of a line are stripped.
|
|
||||||
The string will be allocated if s2 is NULL
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *fgets_slash(char *s2,int maxlen,XFILE *f);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read one line (data until next newline or eof) and allocate it
|
|
||||||
*/
|
|
||||||
_PUBLIC_ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint);
|
|
||||||
|
|
||||||
#ifdef _SAMBA_BUILD_
|
|
||||||
/**
|
|
||||||
load a file into memory from a fd.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *fd_load(int fd, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx);
|
|
||||||
|
|
||||||
|
|
||||||
char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
load a file into memory
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *file_load(const char *fname, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
mmap (if possible) or read a file
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void *map_file(const char *fname, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
load a file into memory and return an array of pointers to lines in the file
|
|
||||||
must be freed with talloc_free().
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
load a fd into memory and return an array of pointers to lines in the file
|
|
||||||
must be freed with talloc_free(). If convert is true calls unix_to_dos on
|
|
||||||
the list.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char **fd_lines_load(int fd, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
save a lump of data into a file. Mostly used for debugging
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length);
|
|
||||||
_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0);
|
|
||||||
_PUBLIC_ int fdprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/util.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Find a suitable temporary directory. The result should be copied immediately
|
|
||||||
as it may be overwritten by a subsequent call.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ const char *tmpdir(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check if a file exists - call vfs_file_exist for samba files.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool file_exist(const char *fname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check a files mod time.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ time_t file_modtime(const char *fname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check if a directory exists.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool directory_exist(const char *dname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to create the specified directory if it didn't exist.
|
|
||||||
*
|
|
||||||
* @retval true if the directory already existed and has the right permissions
|
|
||||||
* or was successfully created.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid,
|
|
||||||
mode_t dir_perms);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
|
|
||||||
else
|
|
||||||
if SYSV use O_NDELAY
|
|
||||||
if BSD use FNDELAY
|
|
||||||
**/
|
|
||||||
_PUBLIC_ int set_blocking(int fd, bool set);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Sleep for a specified number of milliseconds.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void msleep(unsigned int t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get my own name, return in malloc'ed storage.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char* get_myname(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Return true if a string could be a pure IP address.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool is_ipaddress(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Interpret an internet address or name into an IP address in 4 byte form.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ uint32_t interpret_addr(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
A convenient addition to interpret_addr().
|
|
||||||
**/
|
|
||||||
_PUBLIC_ struct in_addr interpret_addr2(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check if an IP is the 0.0.0.0.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool is_zero_ip_v4(struct in_addr ip);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Are two IPs on the same subnet?
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
|
|
||||||
|
|
||||||
_PUBLIC_ bool is_ipaddress_v4(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check if a process exists. Does this work on all unixes?
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool process_exists_by_pid(pid_t pid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
|
|
||||||
is dealt with in posix.c
|
|
||||||
**/
|
|
||||||
_PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
malloc that aborts with smb_panic on fail or zero size.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void *smb_xmalloc(size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Memdup with smb_panic on fail.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void *smb_xmemdup(const void *p, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
strdup that aborts on malloc fail.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char *smb_xstrdup(const char *s);
|
|
||||||
|
|
||||||
char *smb_xstrndup(const char *s, size_t n);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Like strdup but for memory.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void *smb_memdup(const void *p, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* see if a range of memory is all zero. A NULL pointer is considered
|
|
||||||
* to be all zero
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
realloc an array, checking for integer overflow in the array size
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail);
|
|
||||||
|
|
||||||
void *malloc_array(size_t el_size, unsigned int count);
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/fsusage.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve amount of free disk space.
|
|
||||||
* this does all of the system specific guff to get the free disk space.
|
|
||||||
* It is derived from code in the GNU fileutils package, but has been
|
|
||||||
* considerably mangled for use here
|
|
||||||
*
|
|
||||||
* results are returned in *dfree and *dsize, in 512 byte units
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize);
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/ms_fnmatch.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief MS-style Filename matching
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if _SAMBA_BUILD_ == 4
|
|
||||||
#include "libcli/smb/smb_constants.h"
|
|
||||||
|
|
||||||
int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol);
|
|
||||||
|
|
||||||
/** a generic fnmatch function - uses for non-CIFS pattern matching */
|
|
||||||
int gen_fnmatch(const char *pattern, const char *string);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/mutex.c */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _SAMBA_BUILD_
|
|
||||||
/**
|
|
||||||
register a set of mutex/rwlock handlers.
|
|
||||||
Should only be called once in the execution of smbd.
|
|
||||||
*/
|
|
||||||
_PUBLIC_ bool register_mutex_handlers(const char *name, struct mutex_ops *ops);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/idtree.c */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
initialise a idr tree. The context return value must be passed to
|
|
||||||
all subsequent idr calls. To destroy the idr tree use talloc_free()
|
|
||||||
on this context
|
|
||||||
*/
|
|
||||||
_PUBLIC_ struct idr_context *idr_init(TALLOC_CTX *mem_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
allocate the next available id, and assign 'ptr' into its slot.
|
|
||||||
you can retrieve later this pointer using idr_find()
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_get_new(struct idr_context *idp, void *ptr, int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
allocate a new id, giving the first available value greater than or
|
|
||||||
equal to the given starting id
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
allocate a new id randomly in the given range
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_get_new_random(struct idr_context *idp, void *ptr, int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
find a pointer value previously set with idr_get_new given an id
|
|
||||||
*/
|
|
||||||
_PUBLIC_ void *idr_find(struct idr_context *idp, int id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
remove an id from the idr tree
|
|
||||||
*/
|
|
||||||
_PUBLIC_ int idr_remove(struct idr_context *idp, int id);
|
|
||||||
|
|
||||||
/* The following definitions come from lib/util/become_daemon.c */
|
|
||||||
|
|
||||||
#if _SAMBA_BUILD_ == 4
|
|
||||||
/**
|
|
||||||
Become a daemon, discarding the controlling terminal.
|
|
||||||
**/
|
|
||||||
_PUBLIC_ void become_daemon(bool fork);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a ini-style file.
|
|
||||||
*/
|
|
||||||
bool pm_process( const char *fileName,
|
|
||||||
bool (*sfunc)(const char *, void *),
|
|
||||||
bool (*pfunc)(const char *, const char *, void *),
|
|
||||||
void *userdata);
|
|
||||||
|
|
||||||
bool unmap_file(void *start, size_t size);
|
|
||||||
|
|
||||||
#define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr)))
|
|
||||||
|
|
||||||
#endif /* _SAMBA_UTIL_H_ */
|
|
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
functions taken from samba4 for quick prototyping of ctdb. These are
|
|
||||||
not intended to remain part of ctdb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
#include "system/filesys.h"
|
|
||||||
|
|
||||||
|
|
||||||
static char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
|
|
||||||
{
|
|
||||||
struct stat sbuf;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (fstat(fd, &sbuf) != 0) return NULL;
|
|
||||||
|
|
||||||
p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
|
|
||||||
if (!p) return NULL;
|
|
||||||
|
|
||||||
if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
|
|
||||||
talloc_free(p);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
p[sbuf.st_size] = 0;
|
|
||||||
|
|
||||||
if (size) *size = sbuf.st_size;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (!fname || !*fname) return NULL;
|
|
||||||
|
|
||||||
fd = open(fname,O_RDONLY);
|
|
||||||
if (fd == -1) return NULL;
|
|
||||||
|
|
||||||
p = fd_load(fd, size, mem_ctx);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
parse a buffer into lines
|
|
||||||
'p' will be freed on error, and otherwise will be made a child of the returned array
|
|
||||||
**/
|
|
||||||
static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *s, **ret;
|
|
||||||
|
|
||||||
if (!p) return NULL;
|
|
||||||
|
|
||||||
for (s = p, i=0; s < p+size; s++) {
|
|
||||||
if (s[0] == '\n') i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = talloc_array(mem_ctx, char *, i+2);
|
|
||||||
if (!ret) {
|
|
||||||
talloc_free(p);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
talloc_steal(ret, p);
|
|
||||||
|
|
||||||
memset(ret, 0, sizeof(ret[0])*(i+2));
|
|
||||||
if (numlines) *numlines = i;
|
|
||||||
|
|
||||||
ret[0] = p;
|
|
||||||
for (s = p, i=0; s < p+size; s++) {
|
|
||||||
if (s[0] == '\n') {
|
|
||||||
s[0] = 0;
|
|
||||||
i++;
|
|
||||||
ret[i] = s+1;
|
|
||||||
}
|
|
||||||
if (s[0] == '\r') s[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
load a file into memory and return an array of pointers to lines in the file
|
|
||||||
must be freed with talloc_free().
|
|
||||||
**/
|
|
||||||
_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
assert(maxsize == 0);
|
|
||||||
|
|
||||||
p = file_load(fname, &size, mem_ctx);
|
|
||||||
if (!p) return NULL;
|
|
||||||
|
|
||||||
return file_lines_parse(p, size, numlines, mem_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *hex_buffer;
|
|
||||||
|
|
||||||
hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
|
|
||||||
|
|
||||||
return hex_buffer;
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
functions taken from samba4 for quick prototyping of ctdb. These are
|
|
||||||
not intended to remain part of ctdb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
#include "system/time.h"
|
|
||||||
#include "system/filesys.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
return a zero timeval
|
|
||||||
*/
|
|
||||||
struct timeval timeval_zero(void)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
return tv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
return True if a timeval is zero
|
|
||||||
*/
|
|
||||||
bool timeval_is_zero(const struct timeval *tv)
|
|
||||||
{
|
|
||||||
return tv->tv_sec == 0 && tv->tv_usec == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
return a timeval for the current time
|
|
||||||
*/
|
|
||||||
struct timeval timeval_current(void)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return tv;
|
|
||||||
}
|
|
||||||
|
|
||||||
double timeval_elapsed(struct timeval *tv)
|
|
||||||
{
|
|
||||||
struct timeval tv2 = timeval_current();
|
|
||||||
return (tv2.tv_sec - tv->tv_sec) +
|
|
||||||
(tv2.tv_usec - tv->tv_usec)*1.0e-6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
return a timeval struct with the given elements
|
|
||||||
*/
|
|
||||||
_PUBLIC_ struct timeval timeval_set(uint32_t secs, uint32_t usecs)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = secs;
|
|
||||||
tv.tv_usec = usecs;
|
|
||||||
return tv;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PUBLIC_ int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
|
|
||||||
{
|
|
||||||
if (tv1->tv_sec > tv2->tv_sec) return 1;
|
|
||||||
if (tv1->tv_sec < tv2->tv_sec) return -1;
|
|
||||||
if (tv1->tv_usec > tv2->tv_usec) return 1;
|
|
||||||
if (tv1->tv_usec < tv2->tv_usec) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PUBLIC_ struct timeval timeval_until(const struct timeval *tv1,
|
|
||||||
const struct timeval *tv2)
|
|
||||||
{
|
|
||||||
struct timeval t;
|
|
||||||
if (timeval_compare(tv1, tv2) >= 0) {
|
|
||||||
return timeval_zero();
|
|
||||||
}
|
|
||||||
t.tv_sec = tv2->tv_sec - tv1->tv_sec;
|
|
||||||
if (tv1->tv_usec > tv2->tv_usec) {
|
|
||||||
t.tv_sec--;
|
|
||||||
t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
|
|
||||||
} else {
|
|
||||||
t.tv_usec = tv2->tv_usec - tv1->tv_usec;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct timeval timeval_add(const struct timeval *tv,
|
|
||||||
uint32_t secs, uint32_t usecs)
|
|
||||||
{
|
|
||||||
struct timeval tv2 = *tv;
|
|
||||||
const unsigned int million = 1000000;
|
|
||||||
tv2.tv_sec += secs;
|
|
||||||
tv2.tv_usec += usecs;
|
|
||||||
tv2.tv_sec += tv2.tv_usec / million;
|
|
||||||
tv2.tv_usec = tv2.tv_usec % million;
|
|
||||||
return tv2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
|
|
||||||
{
|
|
||||||
struct timeval tv = timeval_current();
|
|
||||||
return timeval_add(&tv, secs, usecs);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
bld.SAMBA_SUBSYSTEM('ctdb-util',
|
|
||||||
source='''util.c util_file.c util_time.c
|
|
||||||
debug.c fault.c idtree.c signal.c
|
|
||||||
substitute.c''',
|
|
||||||
deps='tdb talloc tevent execinfo',
|
|
||||||
local_include=False,
|
|
||||||
)
|
|
@ -88,7 +88,7 @@ fi
|
|||||||
export CC
|
export CC
|
||||||
|
|
||||||
CFLAGS="$RPM_OPT_FLAGS $EXTRA -D_GNU_SOURCE" ./buildtools/bin/waf configure \
|
CFLAGS="$RPM_OPT_FLAGS $EXTRA -D_GNU_SOURCE" ./buildtools/bin/waf configure \
|
||||||
--builtin-libraries=replace,popt \
|
--builtin-libraries=replace,popt,samba-debug,socket-blocking,tdb-wrap \
|
||||||
--bundled-libraries=!talloc,!tevent,!tdb \
|
--bundled-libraries=!talloc,!tevent,!tdb \
|
||||||
--minimum-library-version=talloc:%libtalloc_version,tdb:%libtdb_version,tevent:%libtevent_version \
|
--minimum-library-version=talloc:%libtalloc_version,tdb:%libtdb_version,tevent:%libtevent_version \
|
||||||
%if %with_pcp_pmda
|
%if %with_pcp_pmda
|
||||||
|
45
ctdb/wscript
45
ctdb/wscript
@ -32,12 +32,18 @@ samba_dist.DIST_DIRS('''ctdb:. lib/replace:lib/replace lib/talloc:lib/talloc
|
|||||||
lib/tevent:lib/tevent lib/tdb:lib/tdb
|
lib/tevent:lib/tevent lib/tdb:lib/tdb
|
||||||
lib/socket_wrapper:lib/socket_wrapper
|
lib/socket_wrapper:lib/socket_wrapper
|
||||||
third_party/popt:third_party/popt
|
third_party/popt:third_party/popt
|
||||||
|
lib/util:lib/util lib/tdb_wrap:lib/tdb_wrap
|
||||||
|
lib/ccan:lib/ccan libcli/util:libcli/util
|
||||||
buildtools:buildtools''')
|
buildtools:buildtools''')
|
||||||
|
|
||||||
|
|
||||||
def set_options(opt):
|
def set_options(opt):
|
||||||
opt.PRIVATE_EXTENSION_DEFAULT('ctdb')
|
opt.PRIVATE_EXTENSION_DEFAULT('ctdb')
|
||||||
|
|
||||||
opt.RECURSE('lib/replace')
|
opt.RECURSE('lib/replace')
|
||||||
|
|
||||||
|
opt.RECURSE('lib/util')
|
||||||
|
|
||||||
opt.RECURSE('lib/talloc')
|
opt.RECURSE('lib/talloc')
|
||||||
opt.RECURSE('lib/tevent')
|
opt.RECURSE('lib/tevent')
|
||||||
opt.RECURSE('lib/tdb')
|
opt.RECURSE('lib/tdb')
|
||||||
@ -67,6 +73,12 @@ def configure(conf):
|
|||||||
Options.options.disable_python = True
|
Options.options.disable_python = True
|
||||||
|
|
||||||
conf.RECURSE('lib/replace')
|
conf.RECURSE('lib/replace')
|
||||||
|
|
||||||
|
conf.SAMBA_CHECK_PERL(mandatory=True)
|
||||||
|
|
||||||
|
conf.SAMBA_CHECK_PYTHON(mandatory=True, version=(2,5,0))
|
||||||
|
conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=True)
|
||||||
|
|
||||||
if conf.CHECK_FOR_THIRD_PARTY():
|
if conf.CHECK_FOR_THIRD_PARTY():
|
||||||
conf.RECURSE('third_party/popt')
|
conf.RECURSE('third_party/popt')
|
||||||
else:
|
else:
|
||||||
@ -75,6 +87,8 @@ def configure(conf):
|
|||||||
else:
|
else:
|
||||||
conf.define('USING_SYSTEM_POPT', 1)
|
conf.define('USING_SYSTEM_POPT', 1)
|
||||||
|
|
||||||
|
conf.RECURSE('lib/util')
|
||||||
|
|
||||||
conf.RECURSE('lib/talloc')
|
conf.RECURSE('lib/talloc')
|
||||||
conf.RECURSE('lib/tevent')
|
conf.RECURSE('lib/tevent')
|
||||||
conf.RECURSE('lib/tdb')
|
conf.RECURSE('lib/tdb')
|
||||||
@ -180,7 +194,8 @@ def configure(conf):
|
|||||||
'share/ctdb-tests')
|
'share/ctdb-tests')
|
||||||
conf.env.CTDB_TEST_LIBDIR = os.path.join(conf.env.LIBDIR, 'ctdb-tests')
|
conf.env.CTDB_TEST_LIBDIR = os.path.join(conf.env.LIBDIR, 'ctdb-tests')
|
||||||
|
|
||||||
# Allow separate compilation of utilities to find includes
|
# Allow unified compilation and separate compilation of utilities
|
||||||
|
# to find includes
|
||||||
if srcdir == '.':
|
if srcdir == '.':
|
||||||
# Building from tarball
|
# Building from tarball
|
||||||
conf.ADD_EXTRA_INCLUDES('#include')
|
conf.ADD_EXTRA_INCLUDES('#include')
|
||||||
@ -190,8 +205,15 @@ def configure(conf):
|
|||||||
conf.ADD_EXTRA_INCLUDES('#ctdb/include')
|
conf.ADD_EXTRA_INCLUDES('#ctdb/include')
|
||||||
conf.ADD_EXTRA_INCLUDES('#ctdb/include/internal')
|
conf.ADD_EXTRA_INCLUDES('#ctdb/include/internal')
|
||||||
conf.ADD_EXTRA_INCLUDES('#ctdb')
|
conf.ADD_EXTRA_INCLUDES('#ctdb')
|
||||||
|
conf.ADD_EXTRA_INCLUDES('#lib #lib/replace')
|
||||||
|
|
||||||
|
conf.SET_TARGET_TYPE('systemd-daemon', 'EMPTY')
|
||||||
|
|
||||||
|
del(conf.env.defines['PYTHONDIR'])
|
||||||
|
del(conf.env.defines['PYTHONARCHDIR'])
|
||||||
|
|
||||||
conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True)
|
conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True)
|
||||||
|
conf.DEFINE('SAMBA_UTIL_CORE_ONLY', 1, add_to_cflags=True)
|
||||||
conf.SAMBA_CONFIG_H()
|
conf.SAMBA_CONFIG_H()
|
||||||
|
|
||||||
|
|
||||||
@ -223,6 +245,15 @@ def build(bld):
|
|||||||
bld.RECURSE('lib/tdb')
|
bld.RECURSE('lib/tdb')
|
||||||
bld.RECURSE('lib/socket_wrapper')
|
bld.RECURSE('lib/socket_wrapper')
|
||||||
|
|
||||||
|
# When a combined build is implemented, CTDB will wanted to build
|
||||||
|
# against samba-util rather than samba-util-core. Similarly,
|
||||||
|
# other Samba subsystems expect samba-util. So, for a standalone
|
||||||
|
# build, just define a fake samba-util subsystem that pulls in
|
||||||
|
# samba-util-core.
|
||||||
|
bld.SAMBA_SUBSYSTEM('samba-util',
|
||||||
|
source='',
|
||||||
|
deps='samba-util-core')
|
||||||
|
|
||||||
bld.SAMBA_SUBSYSTEM('ctdb-tcp',
|
bld.SAMBA_SUBSYSTEM('ctdb-tcp',
|
||||||
source=bld.SUBDIR('tcp',
|
source=bld.SUBDIR('tcp',
|
||||||
'tcp_connect.c tcp_init.c tcp_io.c'),
|
'tcp_connect.c tcp_init.c tcp_io.c'),
|
||||||
@ -276,7 +307,7 @@ def build(bld):
|
|||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
public_headers='include/ctdb_client.h',
|
public_headers='include/ctdb_client.h',
|
||||||
deps='''replace popt talloc tevent tdb
|
deps='''replace popt talloc tevent tdb
|
||||||
ctdb-util tdb-wrap''')
|
samba-util tdb-wrap''')
|
||||||
|
|
||||||
bld.SAMBA_SUBSYSTEM('ctdb-server',
|
bld.SAMBA_SUBSYSTEM('ctdb-server',
|
||||||
source='server/ctdbd.c ' +
|
source='server/ctdbd.c ' +
|
||||||
@ -326,14 +357,14 @@ def build(bld):
|
|||||||
|
|
||||||
bld.SAMBA_BINARY('ctdb_lock_helper',
|
bld.SAMBA_BINARY('ctdb_lock_helper',
|
||||||
source='server/ctdb_lock_helper.c',
|
source='server/ctdb_lock_helper.c',
|
||||||
deps='ctdb-util ctdb-common-util talloc tdb',
|
deps='samba-util ctdb-common-util talloc tdb',
|
||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
install_path='${BINDIR}')
|
install_path='${BINDIR}')
|
||||||
|
|
||||||
bld.SAMBA_BINARY('ctdb_event_helper',
|
bld.SAMBA_BINARY('ctdb_event_helper',
|
||||||
source='server/ctdb_event_helper.c',
|
source='server/ctdb_event_helper.c',
|
||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
deps='ctdb-util ctdb-common-util replace tdb',
|
deps='samba-util ctdb-common-util replace tdb',
|
||||||
install_path='${BINDIR}')
|
install_path='${BINDIR}')
|
||||||
|
|
||||||
bld.SAMBA_GENERATOR('ctdb-smnotify-h',
|
bld.SAMBA_GENERATOR('ctdb-smnotify-h',
|
||||||
@ -491,7 +522,7 @@ def build(bld):
|
|||||||
bld.SAMBA_BINARY('ctdb_takeover_tests',
|
bld.SAMBA_BINARY('ctdb_takeover_tests',
|
||||||
source='tests/src/ctdb_takeover_tests.c',
|
source='tests/src/ctdb_takeover_tests.c',
|
||||||
deps='''replace popt tdb tevent talloc ctdb-system
|
deps='''replace popt tdb tevent talloc ctdb-system
|
||||||
ctdb-util tdb-wrap''' +
|
samba-util tdb-wrap''' +
|
||||||
ib_deps,
|
ib_deps,
|
||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
install_path='${CTDB_TEST_LIBDIR}')
|
install_path='${CTDB_TEST_LIBDIR}')
|
||||||
@ -499,14 +530,14 @@ def build(bld):
|
|||||||
bld.SAMBA_BINARY('ctdb_functest',
|
bld.SAMBA_BINARY('ctdb_functest',
|
||||||
source='tests/src/ctdb_functest.c',
|
source='tests/src/ctdb_functest.c',
|
||||||
deps='''replace tdb tevent talloc popt ctdb-system
|
deps='''replace tdb tevent talloc popt ctdb-system
|
||||||
ctdb-util tdb-wrap''',
|
samba-util tdb-wrap''',
|
||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
install_path='${CTDB_TEST_LIBDIR}')
|
install_path='${CTDB_TEST_LIBDIR}')
|
||||||
|
|
||||||
bld.SAMBA_BINARY('ctdb_stubtest',
|
bld.SAMBA_BINARY('ctdb_stubtest',
|
||||||
source='tests/src/ctdb_test.c',
|
source='tests/src/ctdb_test.c',
|
||||||
deps='''replace tdb tevent talloc popt ctdb-system
|
deps='''replace tdb tevent talloc popt ctdb-system
|
||||||
ctdb-util tdb-wrap''',
|
samba-util tdb-wrap''',
|
||||||
includes='include include/internal',
|
includes='include include/internal',
|
||||||
install_path='${CTDB_TEST_LIBDIR}')
|
install_path='${CTDB_TEST_LIBDIR}')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user