r8515: ldb_dn_cmp now uses ldb_dn_compare so that the DNs are compared
[bbaumbach/samba-autobuild/.git] / source4 / lib / ldb / tools / ldbsearch.c
index e8275e87c1de167311f4842891909869af7d444a..5604436980be10b6448bf68b145a4ae079c655bb 100644 (file)
  */
 
 #include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_private.h"
+#include "ldb/tools/cmdline.h"
+
+#ifdef _SAMBA_BUILD_
+#include "system/filesys.h"
+#endif
 
 static void usage(void)
 {
@@ -42,14 +49,26 @@ static void usage(void)
        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");
        exit(1);
 }
 
-static void do_search(struct ldb_context *ldb,
-                     const char *basedn,
-                     int scope,
-                     const char *expression,
-                     const char * const *attrs)
+struct ldb_context *ldbsearch_ldb;
+
+static int do_compare_msg(struct ldb_message **el1,
+                         struct ldb_message **el2)
+{
+       return ldb_dn_cmp(ldbsearch_ldb, (*el1)->dn, (*el2)->dn);
+}
+
+static int do_search(struct ldb_context *ldb,
+                    const char *basedn,
+                    int scope,
+                     int sort_attribs,
+                    const char *expression,
+                    const char * const *attrs)
 {
        int ret, i;
        struct ldb_message **msgs;
@@ -57,105 +76,85 @@ static void do_search(struct ldb_context *ldb,
        ret = ldb_search(ldb, basedn, scope, expression, attrs, &msgs);
        if (ret == -1) {
                printf("search failed - %s\n", ldb_errstring(ldb));
-               return;
+               return -1;
        }
 
        printf("# returned %d records\n", ret);
 
+       ldbsearch_ldb = ldb;
+       if (sort_attribs) {
+               qsort(msgs, ret, sizeof(struct ldb_message *),
+                               (comparison_fn_t)do_compare_msg);
+       }
+
        for (i=0;i<ret;i++) {
                struct ldb_ldif ldif;
                printf("# record %d\n", i+1);
 
                ldif.changetype = LDB_CHANGETYPE_NONE;
-               ldif.msg = *msgs[i];
-
-               ldif_write_file(stdout, &ldif);
+               ldif.msg = msgs[i];
+
+                if (sort_attribs) {
+                        /*
+                         * Ensure attributes are always returned in the same
+                         * order.  For testing, this makes comparison of old
+                         * vs. new much easier.
+                         */
+                        ldb_msg_sort_elements(ldif.msg);
+                }
+                
+               ldb_ldif_write_file(ldb, stdout, &ldif);
        }
 
        if (ret > 0) {
-               ret = ldb_search_free(ldb, msgs);
+               ret = talloc_free(msgs);
                if (ret == -1) {
-                       fprintf(stderr, "search_free failed\n");
+                       fprintf(stderr, "talloc_free failed\n");
                        exit(1);
                }
        }
+
+       return 0;
 }
 
- int main(int argc, char * const argv[])
+ int main(int argc, const char **argv)
 {
        struct ldb_context *ldb;
        const char * const * attrs = NULL;
-       const char *ldb_url;
-       const char *basedn = NULL;
-       int opt;
-       enum ldb_scope scope = LDB_SCOPE_SUBTREE;
-       int interactive = 0;
-
-       ldb_url = getenv("LDB_URL");
-
-       while ((opt = getopt(argc, argv, "b:H:s:hi")) != EOF) {
-               switch (opt) {
-               case 'b':
-                       basedn = optarg;
-                       break;
-
-               case 'H':
-                       ldb_url = optarg;
-                       break;
-
-               case 's':
-                       if (strcmp(optarg, "base") == 0) {
-                               scope = LDB_SCOPE_BASE;
-                       } else if (strcmp(optarg, "sub") == 0) {
-                               scope = LDB_SCOPE_SUBTREE;
-                       } else if (strcmp(optarg, "one") == 0) {
-                               scope = LDB_SCOPE_ONELEVEL;
-                       }
-                       break;
-
-               case 'i':
-                       interactive = 1;
-                       break;
-
-               case 'h':
-               default:
-                       usage();
-                       break;
-               }
-       }
+       struct ldb_cmdline *options;
+       int ret = -1;
+       const char *expression = "(|(objectclass=*)(dn=*))";
 
-       if (!ldb_url) {
-               fprintf(stderr, "You must specify a ldb URL\n\n");
-               usage();
-       }
-
-       argc -= optind;
-       argv += optind;
+       ldb = ldb_init(NULL);
 
-       if (argc < 1 && !interactive) {
-               usage();
-               exit(1);
-       }
+       options = ldb_cmdline_process(ldb, argc, argv, usage);
 
-       if (argc > 1) {
-               attrs = argv+1;
+       /* the check for '=' is for compatibility with ldapsearch */
+       if (!options->interactive &&
+           options->argc > 0 && 
+           strchr(options->argv[0], '=')) {
+               expression = options->argv[0];
+               options->argv++;
+               options->argc--;
        }
 
-       ldb = ldb_connect(ldb_url, 0, NULL);
-       if (!ldb) {
-               perror("ldb_connect");
-               exit(1);
+       if (options->argc > 0) {
+               attrs = (const char * const *)(options->argv);
        }
 
-       if (interactive) {
+       if (options->interactive) {
                char line[1024];
                while (fgets(line, sizeof(line), stdin)) {
-                       do_search(ldb, basedn, scope, line, attrs);
+                       if (do_search(ldb, options->basedn, 
+                                     options->scope, options->sorted, line, attrs) == -1) {
+                               ret = -1;
+                       }
                }
        } else {
-               do_search(ldb, basedn, scope, argv[0], attrs);
+               ret = do_search(ldb, options->basedn, options->scope, options->sorted, 
+                               expression, attrs);
        }
 
-       ldb_close(ldb);
-       return 0;
+       talloc_free(ldb);
+       return ret;
 }