diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/async_req/async_req.c | 156 | ||||
-rw-r--r-- | lib/async_req/async_req.h | 37 | ||||
-rw-r--r-- | lib/async_req/async_req_ntstatus.c | 70 | ||||
-rw-r--r-- | lib/async_req/async_req_ntstatus.h | 35 | ||||
-rw-r--r-- | lib/async_req/async_sock.c | 703 | ||||
-rw-r--r-- | lib/async_req/async_sock.h | 51 | ||||
-rw-r--r-- | lib/async_req/config.mk | 2 | ||||
-rw-r--r-- | lib/replace/libreplace_network.m4 | 9 | ||||
-rw-r--r-- | lib/replace/repdir.m4 | 3 | ||||
-rw-r--r-- | lib/replace/replace.h | 12 | ||||
-rw-r--r-- | lib/replace/system/network.h | 6 | ||||
-rw-r--r-- | lib/talloc/pytalloc.c | 1 | ||||
-rw-r--r-- | lib/tdb/config.mk | 2 | ||||
-rw-r--r-- | lib/tdb/pytdb.c | 11 | ||||
-rw-r--r-- | lib/tdb/python.mk | 6 | ||||
-rw-r--r-- | lib/tevent/build_macros.m4 | 1 | ||||
-rw-r--r-- | lib/tevent/pytevent.c | 1 | ||||
-rw-r--r-- | lib/tevent/python.mk | 9 | ||||
-rw-r--r-- | lib/tevent/testsuite.c | 12 | ||||
-rw-r--r-- | lib/tevent/tevent.mk | 2 | ||||
-rw-r--r-- | lib/tevent/tevent_signal.c | 2 | ||||
-rw-r--r-- | lib/util/byteorder.h | 2 | ||||
-rw-r--r-- | lib/util/config.mk | 1 | ||||
-rw-r--r-- | lib/util/debug.c | 2 | ||||
-rw-r--r-- | lib/util/idtree.c | 32 | ||||
-rw-r--r-- | lib/util/util_ldb.c | 2 | ||||
-rw-r--r-- | lib/util/xfile.c | 1 |
27 files changed, 1013 insertions, 158 deletions
diff --git a/lib/async_req/async_req.c b/lib/async_req/async_req.c index 011948a158..db47bd93ed 100644 --- a/lib/async_req/async_req.c +++ b/lib/async_req/async_req.c @@ -18,6 +18,14 @@ */ #include "includes.h" +#include "lib/tevent/tevent.h" +#include "lib/talloc/talloc.h" +#include "lib/util/dlinklist.h" +#include "lib/async_req/async_req.h" + +#ifndef TALLOC_FREE +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) +#endif /** * @brief Print an async_req structure @@ -35,8 +43,8 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req) { - return talloc_asprintf(mem_ctx, "async_req: state=%d, status=%s, " - "priv=%s", req->state, nt_errstr(req->status), + return talloc_asprintf(mem_ctx, "async_req: state=%d, error=%d, " + "priv=%s", req->state, (int)req->error, talloc_get_name(req->private_data)); } @@ -53,7 +61,7 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx) { struct async_req *result; - result = TALLOC_ZERO_P(mem_ctx, struct async_req); + result = talloc_zero(mem_ctx, struct async_req); if (result == NULL) { return NULL; } @@ -62,6 +70,14 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx) return result; } +static void async_req_finish(struct async_req *req, enum async_req_state state) +{ + req->state = state; + if (req->async.fn != NULL) { + req->async.fn(req); + } +} + /** * @brief An async request has successfully finished * @param[in] req The finished request @@ -73,30 +89,23 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx) void async_req_done(struct async_req *req) { - req->status = NT_STATUS_OK; - req->state = ASYNC_REQ_DONE; - if (req->async.fn != NULL) { - req->async.fn(req); - } + async_req_finish(req, ASYNC_REQ_DONE); } /** * @brief An async request has seen an error * @param[in] req The request with an error - * @param[in] status The error code + * @param[in] error The error code * * async_req_done is to be used by implementors of async requests. When a * request can not successfully completed, the implementation should call this * function with the appropriate status code. */ -void async_req_error(struct async_req *req, NTSTATUS status) +void async_req_error(struct async_req *req, uint64_t error) { - req->status = status; - req->state = ASYNC_REQ_ERROR; - if (req->async.fn != NULL) { - req->async.fn(req); - } + req->error = error; + async_req_finish(req, ASYNC_REQ_USER_ERROR); } /** @@ -107,43 +116,18 @@ void async_req_error(struct async_req *req, NTSTATUS status) * @param[in] priv The async request to be finished */ -static void async_trigger(struct event_context *ev, struct timed_event *te, +static void async_trigger(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *priv) { struct async_req *req = talloc_get_type_abort(priv, struct async_req); TALLOC_FREE(te); - if (NT_STATUS_IS_OK(req->status)) { + if (req->error == 0) { async_req_done(req); } else { - async_req_error(req, req->status); - } -} - -/** - * @brief Finish a request before it started processing - * @param[in] req The finished request - * @param[in] status The success code - * - * An implementation of an async request might find that it can either finish - * the request without waiting for an external event, or it can't even start - * the engine. To present the illusion of a callback to the user of the API, - * the implementation can call this helper function which triggers an - * immediate timed event. This way the caller can use the same calling - * conventions, independent of whether the request was actually deferred. - */ - -bool async_post_status(struct async_req *req, struct event_context *ev, - NTSTATUS status) -{ - req->status = status; - - if (event_add_timed(ev, req, timeval_zero(), - async_trigger, req) == NULL) { - return false; + async_req_error(req, req->error); } - return true; } /** @@ -157,7 +141,7 @@ bool async_post_status(struct async_req *req, struct event_context *ev, * Call pattern would be * \code * p = talloc(mem_ctx, bla); - * if (async_req_nomem(p, req)) { + * if (async_req_ntnomem(p, req)) { * return; * } * \endcode @@ -168,55 +152,69 @@ bool async_req_nomem(const void *p, struct async_req *req) if (p != NULL) { return false; } - async_req_error(req, NT_STATUS_NO_MEMORY); + async_req_finish(req, ASYNC_REQ_NO_MEMORY); return true; } -bool async_req_is_error(struct async_req *req, NTSTATUS *status) +/** + * @brief Finish a request before it started processing + * @param[in] req The finished request + * @param[in] status The success code + * + * An implementation of an async request might find that it can either finish + * the request without waiting for an external event, or it can't even start + * the engine. To present the illusion of a callback to the user of the API, + * the implementation can call this helper function which triggers an + * immediate timed event. This way the caller can use the same calling + * conventions, independent of whether the request was actually deferred. + */ + +bool async_post_error(struct async_req *req, struct tevent_context *ev, + uint64_t error) { - if (req->state < ASYNC_REQ_DONE) { - *status = NT_STATUS_INTERNAL_ERROR; - return true; - } - if (req->state == ASYNC_REQ_ERROR) { - *status = req->status; - return true; + req->error = error; + + if (tevent_add_timer(ev, req, timeval_zero(), + async_trigger, req) == NULL) { + return false; } - return false; + return true; } -NTSTATUS async_req_simple_recv(struct async_req *req) +bool async_req_is_error(struct async_req *req, enum async_req_state *state, + uint64_t *error) { - NTSTATUS status; - - if (async_req_is_error(req, &status)) { - return status; + if (req->state == ASYNC_REQ_DONE) { + return false; + } + if (req->state == ASYNC_REQ_USER_ERROR) { + *error = req->error; } - return NT_STATUS_OK; + *state = req->state; + return true; } -static void async_req_timedout(struct event_context *ev, - struct timed_event *te, +static void async_req_timedout(struct tevent_context *ev, + struct tevent_timer *te, struct timeval now, void *priv) { - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); + struct async_req *req = talloc_get_type_abort(priv, struct async_req); TALLOC_FREE(te); - async_req_error(req, NT_STATUS_IO_TIMEOUT); + async_req_finish(req, ASYNC_REQ_TIMED_OUT); } -bool async_req_set_timeout(struct async_req *req, struct event_context *ev, +bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev, struct timeval to) { - return (event_add_timed(ev, req, - timeval_current_ofs(to.tv_sec, to.tv_usec), - async_req_timedout, req) + return (tevent_add_timer( + ev, req, timeval_current_ofs(to.tv_sec, to.tv_usec), + async_req_timedout, req) != NULL); } struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, + struct tevent_context *ev, struct timeval to) { struct async_req *result; @@ -232,9 +230,9 @@ struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, return result; } -NTSTATUS async_wait_recv(struct async_req *req) +bool async_wait_recv(struct async_req *req) { - return NT_STATUS_OK; + return true; } struct async_queue_entry { @@ -250,7 +248,7 @@ struct async_req_queue { struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx) { - return TALLOC_ZERO_P(mem_ctx, struct async_req_queue); + return talloc_zero(mem_ctx, struct async_req_queue); } static int async_queue_entry_destructor(struct async_queue_entry *e) @@ -266,8 +264,8 @@ static int async_queue_entry_destructor(struct async_queue_entry *e) return 0; } -static void async_req_immediate_trigger(struct event_context *ev, - struct timed_event *te, +static void async_req_immediate_trigger(struct tevent_context *ev, + struct tevent_timer *te, struct timeval now, void *priv) { @@ -278,7 +276,7 @@ static void async_req_immediate_trigger(struct event_context *ev, e->trigger(e->req); } -bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev, +bool async_req_enqueue(struct async_req_queue *queue, struct tevent_context *ev, struct async_req *req, void (*trigger)(struct async_req *req)) { @@ -300,9 +298,9 @@ bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev, talloc_set_destructor(e, async_queue_entry_destructor); if (!busy) { - struct timed_event *te; + struct tevent_timer *te; - te = event_add_timed(ev, e, timeval_zero(), + te = tevent_add_timer(ev, e, timeval_zero(), async_req_immediate_trigger, e); if (te == NULL) { @@ -330,7 +328,7 @@ bool _async_req_setup(TALLOC_CTX *mem_ctx, struct async_req **preq, TALLOC_FREE(req); return false; } - talloc_set_name(state, typename); + talloc_set_name_const(state, typename); req->private_data = state; *preq = req; diff --git a/lib/async_req/async_req.h b/lib/async_req/async_req.h index 3907a08f67..fc849880cd 100644 --- a/lib/async_req/async_req.h +++ b/lib/async_req/async_req.h @@ -20,7 +20,7 @@ #ifndef __ASYNC_REQ_H__ #define __ASYNC_REQ_H__ -#include "includes.h" +#include "lib/talloc/talloc.h" /** * An async request moves between the following 4 states: @@ -40,9 +40,17 @@ enum async_req_state { */ ASYNC_REQ_DONE, /** - * an error has occured + * A user error has occured */ - ASYNC_REQ_ERROR + ASYNC_REQ_USER_ERROR, + /** + * Request timed out + */ + ASYNC_REQ_TIMED_OUT, + /** + * No memory in between + */ + ASYNC_REQ_NO_MEMORY }; /** @@ -92,9 +100,9 @@ struct async_req { * @brief status code when finished * * This status can be queried in the async completion function. It - * will be set to NT_STATUS_OK when everything went fine. + * will be set to 0 when everything went fine. **/ - NTSTATUS status; + uint64_t error; /** * @brief What to do on completion @@ -121,32 +129,31 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req); void async_req_done(struct async_req *req); -void async_req_error(struct async_req *req, NTSTATUS status); - -bool async_post_status(struct async_req *req, struct event_context *ev, - NTSTATUS status); +void async_req_error(struct async_req *req, uint64_t error); bool async_req_nomem(const void *p, struct async_req *req); -bool async_req_is_error(struct async_req *req, NTSTATUS *status); +bool async_post_error(struct async_req *req, struct tevent_context *ev, + uint64_t error); -NTSTATUS async_req_simple_recv(struct async_req *req); +bool async_req_is_error(struct async_req *req, enum async_req_state *state, + uint64_t *error); -bool async_req_set_timeout(struct async_req *req, struct event_context *ev, +bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev, struct timeval to); struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, + struct tevent_context *ev, struct timeval to); -NTSTATUS async_wait_recv(struct async_req *req); +bool async_wait_recv(struct async_req *req); struct async_req_queue; struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx); bool async_req_enqueue(struct async_req_queue *queue, - struct event_context *ev, + struct tevent_context *ev, struct async_req *req, void (*trigger)(struct async_req *req)); diff --git a/lib/async_req/async_req_ntstatus.c b/lib/async_req/async_req_ntstatus.c new file mode 100644 index 0000000000..65bc0f6510 --- /dev/null +++ b/lib/async_req/async_req_ntstatus.c @@ -0,0 +1,70 @@ +/* + Unix SMB/CIFS implementation. + NTSTATUS wrappers for async_req.h + Copyright (C) Volker Lendecke 2008, 2009 + + 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 "lib/tevent/tevent.h" +#include "lib/talloc/talloc.h" +#include "lib/util/dlinklist.h" +#include "lib/async_req/async_req_ntstatus.h" + +void async_req_nterror(struct async_req *req, NTSTATUS status) +{ + async_req_error(req, NT_STATUS_V(status)); +} + +bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev, + NTSTATUS status) +{ + return async_post_error(req, ev, NT_STATUS_V(status)); +} + +bool async_req_is_nterror(struct async_req *req, NTSTATUS *status) +{ + enum async_req_state state; + uint64_t error; + + if (!async_req_is_error(req, &state, &error)) { + return false; + } + switch (state) { + case ASYNC_REQ_USER_ERROR: + *status = NT_STATUS(error); + break; + case ASYNC_REQ_TIMED_OUT: + *status = NT_STATUS_IO_TIMEOUT; + break; + case ASYNC_REQ_NO_MEMORY: + *status = NT_STATUS_NO_MEMORY; + break; + default: + *status = NT_STATUS_INTERNAL_ERROR; + break; + } + return true; +} + +NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req) +{ + NTSTATUS status; + + if (async_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} diff --git a/lib/async_req/async_req_ntstatus.h b/lib/async_req/async_req_ntstatus.h new file mode 100644 index 0000000000..7555aac603 --- /dev/null +++ b/lib/async_req/async_req_ntstatus.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + NTSTATUS wrappers for async_req.h + Copyright (C) Volker Lendecke 2008, 2009 + + 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 __ASYNC_REQ_NTSTATUS_H__ +#define __ASYNC_REQ_NTSTATUS_H__ + +#include "lib/async_req/async_req.h" +#include "includes.h" + +void async_req_nterror(struct async_req *req, NTSTATUS status); + +bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev, + NTSTATUS status); + +bool async_req_is_nterror(struct async_req *req, NTSTATUS *status); + +NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req); + +#endif diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c new file mode 100644 index 0000000000..b992320669 --- /dev/null +++ b/lib/async_req/async_sock.c @@ -0,0 +1,703 @@ +/* + Unix SMB/CIFS implementation. + async socket syscalls + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "lib/talloc/talloc.h" +#include "lib/tevent/tevent.h" +#include "lib/async_req/async_req.h" +#include "lib/async_req/async_sock.h" +#include <fcntl.h> + +#ifndef TALLOC_FREE +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) +#endif + +/** + * Discriminator for async_syscall_state + */ +enum async_syscall_type { + ASYNC_SYSCALL_SEND, + ASYNC_SYSCALL_SENDALL, + ASYNC_SYSCALL_RECV, + ASYNC_SYSCALL_RECVALL, + ASYNC_SYSCALL_CONNECT +}; + +/** + * Holder for syscall arguments and the result + */ + +struct async_syscall_state { + enum async_syscall_type syscall_type; + struct tevent_fd *fde; + + union { + struct param_send { + int fd; + const void *buffer; + size_t length; + int flags; + } param_send; + struct param_sendall { + int fd; + const void *buffer; + size_t length; + int flags; + size_t sent; + } param_sendall; + struct param_recv { + int fd; + void *buffer; + size_t length; + int flags; + } param_recv; + struct param_recvall { + int fd; + void *buffer; + size_t length; + int flags; + size_t received; + } param_recvall; + struct param_connect { + /** + * connect needs to be done on a nonblocking + * socket. Keep the old flags around + */ + long old_sockflags; + int fd; + const struct sockaddr *address; + socklen_t address_len; + } param_connect; + } param; + + union { + ssize_t result_ssize_t; + size_t result_size_t; + int result_int; + } result; + int sys_errno; +}; + +/** + * @brief Create a new async syscall req + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] type Which syscall will this be + * @param[in] pstate Where to put the newly created private_data state + * @retval The new request + * + * This is a helper function to prepare a new struct async_req with an + * associated struct async_syscall_state. The async_syscall_state will be put + * into the async_req as private_data. + */ + +static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + enum async_syscall_type type, + struct async_syscall_state **pstate) +{ + struct async_req *result; + struct async_syscall_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct async_syscall_state)) { + return NULL; + } + state->syscall_type = type; + + result->private_data = state; + + *pstate = state; + + return result; +} + +/** + * @brief Create a new async syscall req based on a fd + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] type Which syscall will this be + * @param[in] fd The file descriptor we work on + * @param[in] fde_flags TEVENT_FD_READ/WRITE -- what are we interested in? + * @param[in] fde_cb The callback function for the file descriptor event + * @param[in] pstate Where to put the newly created private_data state + * @retval The new request + * + * This is a helper function to prepare a new struct async_req with an + * associated struct async_syscall_state and an associated file descriptor + * event. + */ + +static struct async_req *async_fde_syscall_new( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + enum async_syscall_type type, + int fd, + uint16_t fde_flags, + void (*fde_cb)(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv), + struct async_syscall_state **pstate) +{ + struct async_req *result; + struct async_syscall_state *state; + + result = async_syscall_new(mem_ctx, ev, type, &state); + if (result == NULL) { + return NULL; + } + + state->fde = tevent_add_fd(ev, state, fd, fde_flags, fde_cb, result); + if (state->fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + *pstate = state; + return result; +} + +/** + * Retrieve a ssize_t typed result from an async syscall + * @param[in] req The syscall that has just finished + * @param[out] perrno Where to put the syscall's errno + * @retval The return value from the asynchronously called syscall + */ + +ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno) +{ + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + + *perrno = state->sys_errno; + return state->result.result_ssize_t; +} + +/** + * Retrieve a size_t typed result from an async syscall + * @param[in] req The syscall that has just finished + * @param[out] perrno Where to put the syscall's errno + * @retval The return value from the asynchronously called syscall + */ + +size_t async_syscall_result_size_t(struct async_req *req, int *perrno) +{ + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + + *perrno = state->sys_errno; + return state->result.result_size_t; +} + +/** + * Retrieve a int typed result from an async syscall + * @param[in] req The syscall that has just finished + * @param[out] perrno Where to put the syscall's errno + * @retval The return value from the asynchronously called syscall + */ + +int async_syscall_result_int(struct async_req *req, int *perrno) +{ + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + + *perrno = state->sys_errno; + return state->result.result_int; +} + +/** + * fde event handler for the "send" syscall + * @param[in] ev The event context that sent us here + * @param[in] fde The file descriptor event associated with the send + * @param[in] flags Can only be TEVENT_FD_WRITE here + * @param[in] priv private data, "struct async_req *" in this case + */ + +static void async_send_callback(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + struct param_send *p = &state->param.param_send; + + if (state->syscall_type != ASYNC_SYSCALL_SEND) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + state->result.result_ssize_t = send(p->fd, p->buffer, p->length, + p->flags); + state->sys_errno = errno; + + TALLOC_FREE(state->fde); + + async_req_done(req); +} + +/** + * Async version of send(2) + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] fd The socket to send to + * @param[in] buffer The buffer to send + * @param[in] length How many bytes to send + * @param[in] flags flags passed to send(2) + * + * This function is a direct counterpart of send(2) + */ + +struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, const void *buffer, size_t length, + int flags) +{ + struct async_req *result; + struct async_syscall_state *state; + + result = async_fde_syscall_new( + mem_ctx, ev, ASYNC_SYSCALL_SEND, + fd, TEVENT_FD_WRITE, async_send_callback, + &state); + if (result == NULL) { + return NULL; + } + + state->param.param_send.fd = fd; + state->param.param_send.buffer = buffer; + state->param.param_send.length = length; + state->param.param_send.flags = flags; + + return result; +} + +/** + * fde event handler for the "sendall" syscall group + * @param[in] ev The event context that sent us here + * @param[in] fde The file descriptor event associated with the send + * @param[in] flags Can only be TEVENT_FD_WRITE here + * @param[in] priv private data, "struct async_req *" in this case + */ + +static void async_sendall_callback(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + struct param_sendall *p = &state->param.param_sendall; + + if (state->syscall_type != ASYNC_SYSCALL_SENDALL) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + state->result.result_ssize_t = send(p->fd, + (const char *)p->buffer + p->sent, + p->length - p->sent, p->flags); + state->sys_errno = errno; + + if (state->result.result_ssize_t == -1) { + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); + return; + } + + if (state->result.result_ssize_t == 0) { + async_req_nterror(req, NT_STATUS_END_OF_FILE); + return; + } + + p->sent += state->result.result_ssize_t; + if (p->sent > p->length) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + if (p->sent == p->length) { + TALLOC_FREE(state->fde); + async_req_done(req); + } +} + +/** + * @brief Send all bytes to a socket + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] fd The socket to send to + * @param[in] buffer The buffer to send + * @param[in] length How many bytes to send + * @param[in] flags flags passed to send(2) + * + * async_sendall calls send(2) as long as it is necessary to send all of the + * "length" bytes + */ + +struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, const void *buffer, size_t length, + int flags) +{ + struct async_req *result; + struct async_syscall_state *state; + + result = async_fde_syscall_new( + mem_ctx, ev, ASYNC_SYSCALL_SENDALL, + fd, TEVENT_FD_WRITE, async_sendall_callback, + &state); + if (result == NULL) { + return NULL; + } + + state->param.param_sendall.fd = fd; + state->param.param_sendall.buffer = buffer; + state->param.param_sendall.length = length; + state->param.param_sendall.flags = flags; + state->param.param_sendall.sent = 0; + + return result; +} + +NTSTATUS sendall_recv(struct async_req *req) +{ + return async_req_simple_recv_ntstatus(req); +} + +/** + * fde event handler for the "recv" syscall + * @param[in] ev The event context that sent us here + * @param[in] fde The file descriptor event associated with the recv + * @param[in] flags Can only be TEVENT_FD_READ here + * @param[in] priv private data, "struct async_req *" in this case + */ + +static void async_recv_callback(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + struct param_recv *p = &state->param.param_recv; + + if (state->syscall_type != ASYNC_SYSCALL_RECV) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + state->result.result_ssize_t = recv(p->fd, p->buffer, p->length, + p->flags); + state->sys_errno = errno; + + TALLOC_FREE(state->fde); + + async_req_done(req); +} + +/** + * Async version of recv(2) + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] fd The socket to recv from + * @param[in] buffer The buffer to recv into + * @param[in] length How many bytes to recv + * @param[in] flags flags passed to recv(2) + * + * This function is a direct counterpart of recv(2) + */ + +struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, void *buffer, size_t length, + int flags) +{ + struct async_req *result; + struct async_syscall_state *state; + + result = async_fde_syscall_new( + mem_ctx, ev, ASYNC_SYSCALL_RECV, + fd, TEVENT_FD_READ, async_recv_callback, + &state); + + if (result == NULL) { + return NULL; + } + + state->param.param_recv.fd = fd; + state->param.param_recv.buffer = buffer; + state->param.param_recv.length = length; + state->param.param_recv.flags = flags; + + return result; +} + +/** + * fde event handler for the "recvall" syscall group + * @param[in] ev The event context that sent us here + * @param[in] fde The file descriptor event associated with the recv + * @param[in] flags Can only be TEVENT_FD_READ here + * @param[in] priv private data, "struct async_req *" in this case + */ + +static void async_recvall_callback(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + struct async_syscall_state *state = talloc_get_type_abort( + req->private_data, struct async_syscall_state); + struct param_recvall *p = &state->param.param_recvall; + + if (state->syscall_type != ASYNC_SYSCALL_RECVALL) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + state->result.result_ssize_t = recv(p->fd, + (char *)p->buffer + p->received, + p->length - p->received, p->flags); + state->sys_errno = errno; + + if (state->result.result_ssize_t == -1) { + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); + return; + } + + if (state->result.result_ssize_t == 0) { + async_req_nterror(req, NT_STATUS_END_OF_FILE); + return; + } + + p->received += state->result.result_ssize_t; + if (p->received > p->length) { + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + if (p->received == p->length) { + TALLOC_FREE(state->fde); + async_req_done(req); + } +} + +/** + * Receive a specified number of bytes from a socket + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] fd The socket to recv from + * @param[in] buffer The buffer to recv into + * @param[in] length How many bytes to recv + * @param[in] flags flags passed to recv(2) + * + * async_recvall will call recv(2) until "length" bytes are received + */ + +struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, void *buffer, size_t length, + int flags) +{ + struct async_req *result; + struct async_syscall_state *state; + + result = async_fde_syscall_new( + mem_ctx, ev, ASYNC_SYSCALL_RECVALL, + fd, TEVENT_FD_READ, async_recvall_callback, + &state); + if (result == NULL) { + return NULL; + } + + state->param.param_recvall.fd = fd; + state->param.param_recvall.buffer = buffer; + state->param.param_recvall.length = length; + state->param.param_recvall.flags = flags; + state->param.param_recvall.received = 0; + + return result; +} + +NTSTATUS recvall_recv(struct async_req *req) +{ + return async_req_simple_recv_ntstatus(req); +} + +struct async_connect_state { + int fd; + int result; + int sys_errno; + long old_sockflags; +}; + +static void async_connect_connected(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv); + +/** + * @brief async version of connect(2) + * @param[in] mem_ctx The memory context to hang the result off + * @param[in] ev The event context to work from + * @param[in] fd The socket to recv from + * @param[in] address Where to connect? + * @param[in] address_len Length of *address + * @retval The async request + * + * This function sets the socket into non-blocking state to be able to call + * connect in an async state. This will be reset when the request is finished. + */ + +struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len) +{ + struct async_req *result; + struct async_connect_state *state; + struct tevent_fd *fde; + NTSTATUS status; + + if (!async_req_setup(mem_ctx, &result, &state, + struct async_connect_state)) { + return NULL; + } + + /** + * We have to set the socket to nonblocking for async connect(2). Keep + * the old sockflags around. + */ + + state->fd = fd; + state->sys_errno = 0; + + state->old_sockflags = fcntl(fd, F_GETFL, 0); + if (state->old_sockflags == -1) { + goto post_errno; + } + + set_blocking(fd, false); + + state->result = connect(fd, address, address_len); + if (state->result == 0) { + state->sys_errno = 0; + status = NT_STATUS_OK; + goto post_status; + } + + /** + * A number of error messages show that something good is progressing + * and that we have to wait for readability. + * + * If none of them are present, bail out. + */ + + if (!(errno == EINPROGRESS || errno == EALREADY || +#ifdef EISCONN + errno == EISCONN || +#endif + errno == EAGAIN || errno == EINTR)) { + goto post_errno; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, + async_connect_connected, result); + if (fde == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + return result; + + post_errno: + state->sys_errno = errno; + status = map_nt_error_from_unix(state->sys_errno); + post_status: + fcntl(fd, F_SETFL, state->old_sockflags); + if (!async_post_ntstatus(result, ev, status)) { + goto fail; + } + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +/** + * fde event handler for connect(2) + * @param[in] ev The event context that sent us here + * @param[in] fde The file descriptor event associated with the connect + * @param[in] flags Indicate read/writeability of the socket + * @param[in] priv private data, "struct async_req *" in this case + */ + +static void async_connect_connected(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + struct async_connect_state *state = talloc_get_type_abort( + req->private_data, struct async_connect_state); + + TALLOC_FREE(fde); + + /* + * Stevens, Network Programming says that if there's a + * successful connect, the socket is only writable. Upon an + * error, it's both readable and writable. + */ + if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) + == (TEVENT_FD_READ|TEVENT_FD_WRITE)) { + int sockerr; + socklen_t err_len = sizeof(sockerr); + + if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR, + (void *)&sockerr, &err_len) == 0) { + errno = sockerr; + } + + state->sys_errno = errno; + + DEBUG(10, ("connect returned %s\n", strerror(errno))); + + fcntl(state->fd, F_SETFL, state->old_sockflags); + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); + return; + } + + state->sys_errno = 0; + async_req_done(req); +} + +NTSTATUS async_connect_recv(struct async_req *req, int *perrno) +{ + struct async_connect_state *state = talloc_get_type_abort( + req->private_data, struct async_connect_state); + NTSTATUS status; + + fcntl(state->fd, F_SETFL, state->old_sockflags); + + *perrno = state->sys_errno; + + if (async_req_is_nterror(req, &status)) { + return status; + } + if (state->sys_errno == 0) { + return NT_STATUS_OK; + } + return map_nt_error_from_unix(state->sys_errno); +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h new file mode 100644 index 0000000000..fd41acacbb --- /dev/null +++ b/lib/async_req/async_sock.h @@ -0,0 +1,51 @@ +/* + Unix SMB/CIFS implementation. + async socket operations + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __ASYNC_SOCK_H__ +#define __ASYNC_SOCK_H__ + +#include "includes.h" + +ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno); +size_t async_syscall_result_size_t(struct async_req *req, int *perrno); +int async_syscall_result_int(struct async_req *req, int *perrno); + +struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, const void *buffer, size_t length, + int flags); +struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, void *buffer, size_t length, + int flags); +struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len); +NTSTATUS async_connect_recv(struct async_req *req, int *perrno); + +struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, const void *buffer, size_t length, + int flags); +NTSTATUS sendall_recv(struct async_req *req); + +struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, void *buffer, size_t length, + int flags); +NTSTATUS recvall_recv(struct async_req *req); + +#endif diff --git a/lib/async_req/config.mk b/lib/async_req/config.mk index 08d5288a48..820f890fd0 100644 --- a/lib/async_req/config.mk +++ b/lib/async_req/config.mk @@ -1,3 +1,3 @@ [SUBSYSTEM::LIBASYNC_REQ] -LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_req.o) +LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_req.o async_sock.o async_req_ntstatus.o) diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 index 4edb55c03a..30be30f4ab 100644 --- a/lib/replace/libreplace_network.m4 +++ b/lib/replace/libreplace_network.m4 @@ -7,7 +7,14 @@ LIBREPLACE_NETWORK_OBJS="" LIBREPLACE_NETWORK_LIBS="" AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) -AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) +AC_CHECK_HEADERS(netinet/in_systm.h) +AC_CHECK_HEADERS([netinet/ip.h], [], [],[#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif]) +AC_CHECK_HEADERS(netinet/tcp.h netinet/in_ip.h) AC_CHECK_HEADERS(sys/sockio.h sys/un.h) dnl we need to check that net/if.h really can be used, to cope with hpux diff --git a/lib/replace/repdir.m4 b/lib/replace/repdir.m4 index f53a4c2974..fb3f414c95 100644 --- a/lib/replace/repdir.m4 +++ b/lib/replace/repdir.m4 @@ -7,6 +7,9 @@ AC_CACHE_CHECK([for broken readdir],libreplace_cv_READDIR_NEEDED,[ [libreplace_cv_READDIR_NEEDED="assuming not"]) ]) +AC_CHECK_FUNCS(dirfd) +AC_HAVE_DECL(dirfd, [#include <dirent.h>]) + # # try to replace with getdirentries() if needed # diff --git a/lib/replace/replace.h b/lib/replace/replace.h index 688a7466c3..c5b8676acf 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -503,18 +503,6 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) #define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - -/* - * Some older systems seem not to have MAXHOSTNAMELEN - * defined. - */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN HOST_NAME_MAX -#endif - #ifndef UINT16_MAX #define UINT16_MAX 65535 #endif diff --git a/lib/replace/system/network.h b/lib/replace/system/network.h index 473d79b5f2..40d20db2d4 100644 --- a/lib/replace/system/network.h +++ b/lib/replace/system/network.h @@ -271,7 +271,11 @@ int rep_socketpair(int d, int type, int protocol, int sv[2]); #endif #ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 256 +#define HOST_NAME_MAX 255 +#endif + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN HOST_NAME_MAX #endif #ifndef HAVE_SA_FAMILY_T diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c index 51d087b6d3..30da9ee5c2 100644 --- a/lib/talloc/pytalloc.c +++ b/lib/talloc/pytalloc.c @@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "replace.h" #include <talloc.h> #include <pytalloc.h> diff --git a/lib/tdb/config.mk b/lib/tdb/config.mk index 90c9ba2863..38b03b93b6 100644 --- a/lib/tdb/config.mk +++ b/lib/tdb/config.mk @@ -1,7 +1,7 @@ ################################################ # Start SUBSYSTEM LIBTDB [LIBRARY::LIBTDB] -OUTPUT_TYPE = STATIC_LIBRARY +OUTPUT_TYPE = MERGED_OBJ CFLAGS = -I$(tdbsrcdir)/include # # End SUBSYSTEM ldb diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c index 15a8d8a3e2..159bc4dce5 100644 --- a/lib/tdb/pytdb.c +++ b/lib/tdb/pytdb.c @@ -24,21 +24,16 @@ License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "replace.h" +#include "system/filesys.h" + #include <Python.h> #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif -#ifdef HAVE_FSTAT -#undef HAVE_FSTAT -#endif - /* Include tdb headers */ -#include <stdint.h> -#include <signal.h> #include <tdb.h> -#include <fcntl.h> -#include <stdbool.h> typedef struct { PyObject_HEAD diff --git a/lib/tdb/python.mk b/lib/tdb/python.mk index a4e6037993..1f2d4ca4a8 100644 --- a/lib/tdb/python.mk +++ b/lib/tdb/python.mk @@ -1,8 +1,6 @@ -[PYTHON::swig_tdb] +[PYTHON::pytdb] LIBRARY_REALNAME = tdb.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG -swig_tdb_OBJ_FILES = $(tdbsrcdir)/pytdb.o - -$(swig_tdb_OBJ_FILES): CFLAGS+=$(CFLAG_NO_CAST_QUAL) +pytdb_OBJ_FILES = $(tdbsrcdir)/pytdb.o diff --git a/lib/tevent/build_macros.m4 b/lib/tevent/build_macros.m4 index c036668cd1..bb7fad8f7a 100644 --- a/lib/tevent/build_macros.m4 +++ b/lib/tevent/build_macros.m4 @@ -7,6 +7,7 @@ AC_DEFUN(BUILD_WITH_SHARED_BUILD_DIR, if test x"$with_shared_build_dir" != x; then sharedbuilddir=$with_shared_build_dir CFLAGS="$CFLAGS -I$with_shared_build_dir/include" + CPPFLAGS="$CPPFLAGS -I$with_shared_build_dir/include" LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib" fi AC_SUBST(sharedbuilddir) diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c index 5d10554531..5c34064004 100644 --- a/lib/tevent/pytevent.c +++ b/lib/tevent/pytevent.c @@ -16,6 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "replace.h" #include <Python.h> #ifndef Py_RETURN_NONE diff --git a/lib/tevent/python.mk b/lib/tevent/python.mk index abc60fa2ce..0c1beca675 100644 --- a/lib/tevent/python.mk +++ b/lib/tevent/python.mk @@ -1,10 +1,5 @@ -# TODO: Change python stuff to tevent -[PYTHON::swig_events] +[PYTHON::pytevent] LIBRARY_REALNAME = tevent.$(SHLIBEXT) PRIVATE_DEPENDENCIES = LIBTEVENT PYTALLOC LIBSAMBA-UTIL LIBREPLACE -swig_events_OBJ_FILES = $(libteventsrcdir)/pytevent.o - -$(swig_events_OBJ_FILES): CFLAGS+=$(CFLAG_NO_CAST_QUAL) - -PC_FILES += $(libteventsrcdir)/tevent.pc +pytevent_OBJ_FILES = $(libteventsrcdir)/pytevent.o diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c index 1b811f5fa2..faa18577a7 100644 --- a/lib/tevent/testsuite.c +++ b/lib/tevent/testsuite.c @@ -27,9 +27,9 @@ static int fde_count; static void fde_handler(struct tevent_context *ev_ctx, struct tevent_fd *f, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - int *fd = (int *)private; + int *fd = (int *)private_data; char c; #ifdef SA_SIGINFO kill(getpid(), SIGUSR1); @@ -41,16 +41,16 @@ static void fde_handler(struct tevent_context *ev_ctx, struct tevent_fd *f, } static void finished_handler(struct tevent_context *ev_ctx, struct tevent_timer *te, - struct timeval tval, void *private) + struct timeval tval, void *private_data) { - int *finished = (int *)private; + int *finished = (int *)private_data; (*finished) = 1; } static void count_handler(struct tevent_context *ev_ctx, struct signal_event *te, - int signum, int count, void *info, void *private) + int signum, int count, void *info, void *private_data) { - int *countp = (int *)private; + int *countp = (int *)private_data; (*countp) += count; } diff --git a/lib/tevent/tevent.mk b/lib/tevent/tevent.mk index be7e298218..ac5710ff05 100644 --- a/lib/tevent/tevent.mk +++ b/lib/tevent/tevent.mk @@ -22,8 +22,6 @@ installdirs:: installheaders:: installdirs cp $(srcdir)/tevent.h $(DESTDIR)$(includedir) - cp $(srcdir)/tevent_internal.h $(DESTDIR)$(includedir) - cp $(srcdir)/tevent_util.h $(DESTDIR)$(includedir) installlibs:: installdirs cp tevent.pc $(DESTDIR)$(libdir)/pkgconfig diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c index c21ba209af..04ee6975bd 100644 --- a/lib/tevent/tevent_signal.c +++ b/lib/tevent/tevent_signal.c @@ -29,7 +29,7 @@ #define NUM_SIGNALS 64 /* maximum number of SA_SIGINFO signals to hold in the queue */ -#define SA_INFO_QUEUE_COUNT 10 +#define SA_INFO_QUEUE_COUNT 100 struct sigcounter { uint32_t count; diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h index 894beccabf..b860dea791 100644 --- a/lib/util/byteorder.h +++ b/lib/util/byteorder.h @@ -151,7 +151,7 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val) #if HAVE_ASM_BYTEORDER -#define _PTRPOS(buf,pos) (((const uint8_t *)buf)+(pos)) +#define _PTRPOS(buf,pos) (((const uint8_t *)(buf))+(pos)) #define SVAL(buf,pos) ld_le16((const uint16_t *)_PTRPOS(buf,pos)) #define IVAL(buf,pos) ld_le32((const uint32_t *)_PTRPOS(buf,pos)) #define SSVAL(buf,pos,val) st_le16((uint16_t *)_PTRPOS(buf,pos), val) diff --git a/lib/util/config.mk b/lib/util/config.mk index 22f22b5771..14bdb2a277 100644 --- a/lib/util/config.mk +++ b/lib/util/config.mk @@ -30,6 +30,7 @@ LIBSAMBA-UTIL_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \ params.o) PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \ + dlinklist.h \ attr.h \ byteorder.h \ data_blob.h \ diff --git a/lib/util/debug.c b/lib/util/debug.c index 98aabc554b..578822088f 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -102,7 +102,7 @@ _PUBLIC_ void dbghdr(int level, const char *location, const char *func) } -_PUBLIC_ void dbghdrclass(int level, int class, const char *location, const char *func) +_PUBLIC_ void dbghdrclass(int level, int dclass, const char *location, const char *func) { /* Simple wrapper, Samba 4 doesn't do debug classes */ dbghdr(level, location, func); diff --git a/lib/util/idtree.c b/lib/util/idtree.c index 193922973f..c8a8b6346a 100644 --- a/lib/util/idtree.c +++ b/lib/util/idtree.c @@ -92,10 +92,10 @@ static void free_layer(struct idr_context *idp, struct idr_layer *p) 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) + struct idr_layer *pn = talloc_zero(idp, struct idr_layer); + if(pn == NULL) return (0); - free_layer(idp, new); + free_layer(idp, pn); } return 1; } @@ -103,7 +103,7 @@ static int idr_pre_get(struct idr_context *idp) 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 *p, *pn; struct idr_layer *pa[MAX_LEVEL]; int l, id, oid; uint32_t bm; @@ -155,9 +155,9 @@ restart: * Create the layer below if it is missing. */ if (!p->ary[m]) { - if (!(new = alloc_layer(idp))) + if (!(pn = alloc_layer(idp))) return -1; - p->ary[m] = new; + p->ary[m] = pn; p->count++; } pa[l--] = p; @@ -188,7 +188,7 @@ restart: static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id) { - struct idr_layer *p, *new; + struct idr_layer *p, *pn; int layers, v, id; idr_pre_get(idp); @@ -210,24 +210,24 @@ build_up: layers++; if (!p->count) continue; - if (!(new = alloc_layer(idp))) { + if (!(pn = 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) { + for (pn = p; p && p != idp->top; pn = p) { p = p->ary[0]; - new->ary[0] = NULL; - new->bitmap = new->count = 0; - free_layer(idp, new); + pn->ary[0] = NULL; + pn->bitmap = pn->count = 0; + free_layer(idp, pn); } return -1; } - new->ary[0] = p; - new->count = 1; + pn->ary[0] = p; + pn->count = 1; if (p->bitmap == IDR_FULL) - set_bit(0, new->bitmap); - p = new; + set_bit(0, pn->bitmap); + p = pn; } idp->top = p; idp->layers = layers; diff --git a/lib/util/util_ldb.c b/lib/util/util_ldb.c index 70b18478c6..c11b6879d2 100644 --- a/lib/util/util_ldb.c +++ b/lib/util/util_ldb.c @@ -21,9 +21,7 @@ */ #include "includes.h" -#include "lib/events/events.h" #include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_errors.h" #include "../lib/util/util_ldb.h" /* search the sam for the specified attributes - va_list variant diff --git a/lib/util/xfile.c b/lib/util/xfile.c index cf195706db..16499e1736 100644 --- a/lib/util/xfile.c +++ b/lib/util/xfile.c @@ -112,6 +112,7 @@ XFILE *x_fopen(const char *fname, int flags, mode_t mode) if ((flags & O_ACCMODE) == O_RDWR) { /* we don't support RDWR in XFILE - use file descriptors instead */ + SAFE_FREE(ret); errno = EINVAL; return NULL; } |