ldb:tools - always check if ldb connection has been estabilished
[ira/wip.git] / source4 / lib / ldb / tools / ldbsearch.c
index 24ceb309639d6b81dc7c29f1cd113d4418aa2e12..cd746749d0b1401ae413f9d12b5e2b4b27f1ba2b 100644 (file)
  *  Author: Andrew Tridgell
  */
 
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
+#include "ldb.h"
 #include "tools/cmdline.h"
 
-static void usage(void)
+static void usage(struct ldb_context *ldb)
 {
        printf("Usage: ldbsearch <options> <expression> <attrs...>\n");
-       printf("Options:\n");
-       printf("  -H ldb_url       choose the database (or $LDB_URL)\n");
-       printf("  -s base|sub|one  choose search scope\n");
-       printf("  -b basedn        choose baseDN\n");
-       printf("  -i               read search expressions from stdin\n");
-        printf("  -S               sort returned attributes\n");
-       printf("  -o options       pass options like modules to activate\n");
-       printf("              e.g: -o modules:timestamps\n");
+       ldb_cmdline_help(ldb, "ldbsearch", stdout);
        exit(1);
 }
 
@@ -56,18 +52,19 @@ static int do_compare_msg(struct ldb_message **el1,
 }
 
 struct search_context {
+       struct ldb_context *ldb;
        struct ldb_control **req_ctrls;
 
        int sort;
-       int num_stored;
+       unsigned int num_stored;
        struct ldb_message **store;
-       int refs_stored;
+       unsigned int refs_stored;
        char **refs_store;
 
-       int entries;
-       int refs;
+       unsigned int entries;
+       unsigned int refs;
 
-       int pending;
+       unsigned int pending;
        int status;
 };
 
@@ -101,7 +98,7 @@ static int store_referral(char *referral, struct search_context *sctx) {
        return 0;
 }
 
-static int display_message(struct ldb_context *ldb, struct ldb_message *msg, struct search_context *sctx) {
+static int display_message(struct ldb_message *msg, struct search_context *sctx) {
        struct ldb_ldif ldif;
 
        sctx->entries++;
@@ -119,7 +116,7 @@ static int display_message(struct ldb_context *ldb, struct ldb_message *msg, str
                ldb_msg_sort_elements(ldif.msg);
                }
 
-       ldb_ldif_write_file(ldb, stdout, &ldif);
+       ldb_ldif_write_file(sctx->ldb, stdout, &ldif);
 
        return 0;
 }
@@ -133,18 +130,26 @@ static int display_referral(char *referral, struct search_context *sctx)
        return 0;
 }
 
-static int search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
+static int search_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
-       struct search_context *sctx = talloc_get_type(context, struct search_context);
-       int ret;
+       struct search_context *sctx;
+       int ret = LDB_SUCCESS;
+
+       sctx = talloc_get_type(req->context, struct search_context);
+
+       if (!ares) {
+               return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+       }
+       if (ares->error != LDB_SUCCESS) {
+               return ldb_request_done(req, ares->error);
+       }
        
        switch (ares->type) {
-
        case LDB_REPLY_ENTRY:
                if (sctx->sort) {
                        ret = store_message(ares->message, sctx);
                } else {
-                       ret = display_message(ldb, ares->message, sctx);
+                       ret = display_message(ares->message, sctx);
                }
                break;
 
@@ -154,6 +159,9 @@ static int search_callback(struct ldb_context *ldb, void *context, struct ldb_re
                } else {
                        ret = display_referral(ares->referral, sctx);
                }
+               if (ret) {
+                       return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+               }
                break;
 
        case LDB_REPLY_DONE:
@@ -161,22 +169,13 @@ static int search_callback(struct ldb_context *ldb, void *context, struct ldb_re
                        if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1)
                                sctx->pending = 1;
                }
-               ret = 0;
-               break;
-               
-       default:
-               fprintf(stderr, "unknown Reply Type\n");
-               return LDB_ERR_OTHER;
+               talloc_free(ares);
+               return ldb_request_done(req, LDB_SUCCESS);
        }
 
-       if (talloc_free(ares) == -1) {
-               fprintf(stderr, "talloc_free failed\n");
-               sctx->pending = 0;
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       if (ret) {
-               return LDB_ERR_OPERATIONS_ERROR;
+       talloc_free(ares);
+       if (ret != LDB_SUCCESS) {
+               return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
        }
 
        return LDB_SUCCESS;
@@ -192,66 +191,64 @@ static int do_search(struct ldb_context *ldb,
        struct search_context *sctx;
        int ret;
 
-       req = talloc(ldb, struct ldb_request);
-       if (!req) return -1;
+       req = NULL;
        
-       sctx = talloc(req, struct search_context);
-       if (!sctx) return -1;
+       sctx = talloc_zero(ldb, struct search_context);
+       if (!sctx) return LDB_ERR_OPERATIONS_ERROR;
 
+       sctx->ldb = ldb;
        sctx->sort = options->sorted;
-       sctx->num_stored = 0;
-       sctx->refs_stored = 0;
-       sctx->store = NULL;
        sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls);
        if (options->controls != NULL &&  sctx->req_ctrls== NULL) {
                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
-               return -1;
+               return LDB_ERR_OPERATIONS_ERROR;
        }
-       sctx->entries = 0;
-       sctx->refs = 0;
 
        if (basedn == NULL) {
                basedn = ldb_get_default_basedn(ldb);
        }
 
-       req->operation = LDB_SEARCH;
-       req->op.search.base = basedn;
-       req->op.search.scope = options->scope;
-       req->op.search.tree = ldb_parse_tree(req, expression);
-       if (req->op.search.tree == NULL) return -1;
-       req->op.search.attrs = attrs;
-       req->controls = sctx->req_ctrls;
-       req->context = sctx;
-       req->callback = &search_callback;
-       ldb_set_timeout(ldb, req, 0); /* TODO: make this settable by command line */
-
 again:
+       /* free any previous requests */
+       if (req) talloc_free(req);
+
+       ret = ldb_build_search_req(&req, ldb, ldb,
+                                  basedn, options->scope,
+                                  expression, attrs,
+                                  sctx->req_ctrls,
+                                  sctx, search_callback,
+                                  NULL);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(sctx);
+               printf("allocating request failed: %s\n", ldb_errstring(ldb));
+               return ret;
+       }
+
        sctx->pending = 0;
 
        ret = ldb_request(ldb, req);
        if (ret != LDB_SUCCESS) {
                printf("search failed - %s\n", ldb_errstring(ldb));
-               return -1;
+               return ret;
        }
 
        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
-               if (ret != LDB_SUCCESS) {
+       if (ret != LDB_SUCCESS) {
                printf("search error - %s\n", ldb_errstring(ldb));
-               return -1;
+               return ret;
        }
 
        if (sctx->pending)
                goto again;
 
        if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) {
-               int i;
+               unsigned int i;
 
                if (sctx->num_stored) {
-                       ldb_qsort(sctx->store, sctx->num_stored, sizeof(struct ldb_message *),
-                                 ldb, (ldb_qsort_cmp_fn_t)do_compare_msg);
+                       LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg);
                }
                for (i = 0; i < sctx->num_stored; i++) {
-                       display_message(ldb, sctx->store[i], sctx);
+                       display_message(sctx->store[i], sctx);
                }
 
                for (i = 0; i < sctx->refs_stored; i++) {
@@ -259,12 +256,13 @@ again:
                }
        }
 
-       printf("# returned %d records\n# %d entries\n# %d referrals\n",
+       printf("# returned %u records\n# %u entries\n# %u referrals\n",
                sctx->entries + sctx->refs, sctx->entries, sctx->refs);
 
+       talloc_free(sctx);
        talloc_free(req);
 
-       return 0;
+       return LDB_SUCCESS;
 }
 
 int main(int argc, const char **argv)
@@ -275,10 +273,12 @@ int main(int argc, const char **argv)
        struct ldb_cmdline *options;
        int ret = -1;
        const char *expression = "(|(objectClass=*)(distinguishedName=*))";
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
 
-       ldb_global_init();
-
-       ldb = ldb_init(NULL);
+       ldb = ldb_init(mem_ctx, NULL);
+       if (ldb == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
 
        options = ldb_cmdline_process(ldb, argc, argv, usage);
 
@@ -306,14 +306,13 @@ int main(int argc, const char **argv)
        if (options->interactive) {
                char line[1024];
                while (fgets(line, sizeof(line), stdin)) {
-                       if (do_search(ldb, basedn, options, line, attrs) == -1) {
-                               ret = -1;
-                       }
+                       ret = do_search(ldb, basedn, options, line, attrs);
                }
        } else {
                ret = do_search(ldb, basedn, options, expression, attrs);
        }
 
-       talloc_free(ldb);
+       talloc_free(mem_ctx);
+
        return ret;
 }