1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +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:
Martin Schwenke 2014-08-15 16:41:57 +10:00 committed by Volker Lendecke
parent 43266be945
commit 59c3025706
19 changed files with 41 additions and 2295 deletions

View File

@ -7,7 +7,7 @@ else
fi
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 \
--minimum-library-version=talloc:2.0.8,tdb:1.2.11,tevent:0.9.16 \
--prefix=/usr \

View File

@ -38,17 +38,7 @@
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#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/util.h"
#include "lib/util/samba_util.h"
#endif /* _CTDB_INCLUDES_H */

View File

@ -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;
}

View File

@ -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 */

View File

@ -1,7 +0,0 @@
#!/usr/bin/python
bld.SAMBA_SUBSYSTEM('tdb-wrap',
source='tdb_wrap.c',
deps='tdb talloc',
local_include=False
)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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,
)

View File

@ -88,7 +88,7 @@ fi
export CC
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 \
--minimum-library-version=talloc:%libtalloc_version,tdb:%libtdb_version,tevent:%libtevent_version \
%if %with_pcp_pmda

View File

@ -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/socket_wrapper:lib/socket_wrapper
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''')
def set_options(opt):
opt.PRIVATE_EXTENSION_DEFAULT('ctdb')
opt.RECURSE('lib/replace')
opt.RECURSE('lib/util')
opt.RECURSE('lib/talloc')
opt.RECURSE('lib/tevent')
opt.RECURSE('lib/tdb')
@ -67,6 +73,12 @@ def configure(conf):
Options.options.disable_python = True
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():
conf.RECURSE('third_party/popt')
else:
@ -75,6 +87,8 @@ def configure(conf):
else:
conf.define('USING_SYSTEM_POPT', 1)
conf.RECURSE('lib/util')
conf.RECURSE('lib/talloc')
conf.RECURSE('lib/tevent')
conf.RECURSE('lib/tdb')
@ -180,7 +194,8 @@ def configure(conf):
'share/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 == '.':
# Building from tarball
conf.ADD_EXTRA_INCLUDES('#include')
@ -190,8 +205,15 @@ def configure(conf):
conf.ADD_EXTRA_INCLUDES('#ctdb/include')
conf.ADD_EXTRA_INCLUDES('#ctdb/include/internal')
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('SAMBA_UTIL_CORE_ONLY', 1, add_to_cflags=True)
conf.SAMBA_CONFIG_H()
@ -223,6 +245,15 @@ def build(bld):
bld.RECURSE('lib/tdb')
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',
source=bld.SUBDIR('tcp',
'tcp_connect.c tcp_init.c tcp_io.c'),
@ -276,7 +307,7 @@ def build(bld):
includes='include include/internal',
public_headers='include/ctdb_client.h',
deps='''replace popt talloc tevent tdb
ctdb-util tdb-wrap''')
samba-util tdb-wrap''')
bld.SAMBA_SUBSYSTEM('ctdb-server',
source='server/ctdbd.c ' +
@ -326,14 +357,14 @@ def build(bld):
bld.SAMBA_BINARY('ctdb_lock_helper',
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',
install_path='${BINDIR}')
bld.SAMBA_BINARY('ctdb_event_helper',
source='server/ctdb_event_helper.c',
includes='include include/internal',
deps='ctdb-util ctdb-common-util replace tdb',
deps='samba-util ctdb-common-util replace tdb',
install_path='${BINDIR}')
bld.SAMBA_GENERATOR('ctdb-smnotify-h',
@ -491,7 +522,7 @@ def build(bld):
bld.SAMBA_BINARY('ctdb_takeover_tests',
source='tests/src/ctdb_takeover_tests.c',
deps='''replace popt tdb tevent talloc ctdb-system
ctdb-util tdb-wrap''' +
samba-util tdb-wrap''' +
ib_deps,
includes='include include/internal',
install_path='${CTDB_TEST_LIBDIR}')
@ -499,14 +530,14 @@ def build(bld):
bld.SAMBA_BINARY('ctdb_functest',
source='tests/src/ctdb_functest.c',
deps='''replace tdb tevent talloc popt ctdb-system
ctdb-util tdb-wrap''',
samba-util tdb-wrap''',
includes='include include/internal',
install_path='${CTDB_TEST_LIBDIR}')
bld.SAMBA_BINARY('ctdb_stubtest',
source='tests/src/ctdb_test.c',
deps='''replace tdb tevent talloc popt ctdb-system
ctdb-util tdb-wrap''',
samba-util tdb-wrap''',
includes='include include/internal',
install_path='${CTDB_TEST_LIBDIR}')