summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldap/servers/slapd/tools/dbscan.c322
1 files changed, 173 insertions, 149 deletions
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c
index 496a2eb5..0e742ddc 100644
--- a/ldap/servers/slapd/tools/dbscan.c
+++ b/ldap/servers/slapd/tools/dbscan.c
@@ -29,6 +29,18 @@ typedef unsigned char uint8_t;
#include <inttypes.h>
#endif
+/* file type */
+#define ENTRYTYPE 0x1
+#define INDEXTYPE 0x2
+#define VLVINDEXTYPE 0x4
+#define CHANGELOGTYPE 0x8
+
+/* display mode */
+#define RAWDATA 0x1
+#define SHOWCOUNT 0x2
+#define SHOWDATA 0x4
+#define SHOWSUMMARY 0x8
+
/* stolen from slapi-plugin.h */
#define SLAPI_OPERATION_BIND 0x00000001UL
#define SLAPI_OPERATION_UNBIND 0x00000002UL
@@ -455,11 +467,9 @@ void print_changelog(unsigned char *data, int len)
}
}
-int indexfile = 0, entryfile = 0, changelogfile = 0;
-int lengths_only = 0;
+uint32 file_type = 0;
uint32 min_display = 0;
-int show_recno = 0;
-int show_cnt = 0;
+uint32 display_mode = 0;
int verbose = 0;
long pres_cnt = 0;
long eq_cnt = 0;
@@ -471,126 +481,148 @@ long allids_cnt = 0;
long other_cnt = 0;
-static void display_item(DBC *cursor, DBT *key, DBT *data)
+static void display_index_item(DBC *cursor, DBT *key, DBT *data)
{
- IDL *idl;
+ IDL *idl = NULL;
int ret = 0;
- if (indexfile) {
- idl = idl_make(data);
- if (idl == NULL) {
- printf("\t(illegal idl)\n");
- return;
- }
- if (show_recno) {
- cursor->c_get(cursor, key, data, DB_GET_RECNO);
- printf("[%5d] ", *(db_recno_t *)(data->data));
+ idl = idl_make(data);
+ if (idl == NULL) {
+ printf("\t(illegal idl)\n");
+ return;
+ }
+
+ if (file_type & VLVINDEXTYPE) { /* vlv index file */
+ if (1 > min_display) { /* recno is always 1 */
+ if (display_mode & SHOWCOUNT) { /* key size=1 */
+ printf("%-40s 1\n", format(key->data, key->size));
+ } else {
+ printf("%-40s\n", format(key->data, key->size));
+ }
+ if (display_mode & SHOWDATA) {
+ cursor->c_get(cursor, key, data, DB_GET_RECNO);
+ printf("\t%5d\n", *(db_recno_t *)(data->data));
+ }
}
+ goto index_done;
+ }
- /* fetch all other id's too */
- while (ret == 0) {
- ret = cursor->c_get(cursor, key, data, DB_NEXT_DUP);
- if (ret == 0)
- idl = idl_append(idl, *(uint32 *)(data->data));
+ /* ordinary index file */
+ /* fetch all other id's too */
+ while (ret == 0) {
+ ret = cursor->c_get(cursor, key, data, DB_NEXT_DUP);
+ if (ret == 0)
+ idl = idl_append(idl, *(uint32 *)(data->data));
+ }
+ if (ret == DB_NOTFOUND)
+ ret = 0;
+ if (ret != 0) {
+ printf("Failure while looping dupes: %s\n", db_strerror(ret));
+ exit(1);
+ }
+
+ if (idl && idl->max == 0) {
+ /* allids; should not exist in the new idl world */
+ if ( allids_cnt == 0 && (display_mode & SHOWSUMMARY)) {
+ printf("The following index keys reached allids:\n");
}
- if (ret == DB_NOTFOUND)
- ret = 0;
- if (ret != 0) {
- printf("Failure while looping dupes: %s\n",
- db_strerror(ret));
- exit(1);
+ printf("%-40s(allids)\n", format(key->data, key->size));
+ allids_cnt++;
+ } else {
+ if (idl->used < min_display) {
+ goto index_done; /* less than minimum display count */
+ } else if (display_mode & SHOWCOUNT) { /* key size */
+ printf("%-40s%d\n", format(key->data, key->size), idl->used);
+ } else if (!(display_mode & SHOWSUMMARY) || (display_mode & SHOWDATA)) {
+ /* show keys only if show summary is not set or
+ * even if it's set, but with show data */
+ printf("%-40s\n", format(key->data, key->size));
}
-
- if (idl->max == 0) {
- /* allids */
- if ( allids_cnt == 0 && show_cnt) {
- printf("The following index keys reached allids:\n");
- }
- printf("%-40s(allids)\n", format(key->data, key->size));
- allids_cnt++;
- } else {
- if (lengths_only) {
- if (idl->used >= min_display)
- printf("%-40s%d\n",
- format(key->data, key->size), idl->used);
- } else if (!show_cnt) {
- char *formatted_idl = NULL;
- int done = 0;
- int isfirsttime = 1;
- printf("%s\n", format(key->data, key->size));
- while (0 == done) {
- formatted_idl = idl_format(idl, isfirsttime, &done);
- if (NULL == formatted_idl) {
- done = 1; /* no more idl */
+ if (display_mode & SHOWDATA) {
+ char *formatted_idl = NULL;
+ int done = 0;
+ int isfirsttime = 1;
+ while (0 == done) {
+ formatted_idl = idl_format(idl, isfirsttime, &done);
+ if (NULL == formatted_idl) {
+ done = 1; /* no more idl */
+ } else {
+ if (1 == isfirsttime) {
+ printf("\t%s", formatted_idl);
+ isfirsttime = 0;
} else {
- if (1 == isfirsttime) {
- printf("\t%s", formatted_idl);
- isfirsttime = 0;
- } else {
- printf("%s", formatted_idl);
- }
+ printf("%s", formatted_idl);
}
}
- printf("\n");
- }
- }
-
- if ( show_cnt ) {
- char firstchar;
-
- firstchar = ((char*)key->data)[0];
-
- switch ( firstchar ) {
- case '+':
- pres_cnt += idl->used;
- break;
-
- case '=':
- eq_cnt += idl->used;
- break;
-
- case '~':
- app_cnt += idl->used;
- break;
-
- case '*':
- sub_cnt += idl->used;
- break;
-
- case ':':
- match_cnt += idl->used;
- break;
-
- case '\\':
- ind_cnt += idl->used;
- break;
-
- default:
- other_cnt += idl->used;
- break;
}
+ printf("\n");
+ }
+ }
+index_done:
+ if ( display_mode & SHOWSUMMARY ) {
+ char firstchar;
+
+ firstchar = ((char*)key->data)[0];
+
+ switch ( firstchar ) {
+ case '+':
+ pres_cnt += idl->used;
+ break;
+
+ case '=':
+ eq_cnt += idl->used;
+ break;
+
+ case '~':
+ app_cnt += idl->used;
+ break;
+
+ case '*':
+ sub_cnt += idl->used;
+ break;
+
+ case ':':
+ match_cnt += idl->used;
+ break;
+
+ case '\\':
+ ind_cnt += idl->used;
+ break;
+
+ default:
+ other_cnt += idl->used;
+ break;
}
- idl_free(idl);
- return;
- }
-
- if (changelogfile) {
- /* changelog db file */
- printf("\ndbid: %s\n", format(key->data, key->size));
- print_changelog(data->data, data->size);
- return;
}
+ idl_free(idl);
+ return;
+}
- if (entryfile) {
- /* id2entry file */
- ID entry_id = id_stored_to_internal(key->data);
- printf("id %d\n", entry_id);
- printf("\t%s\n", format_entry(data->data, data->size));
- } else {
- /* user didn't tell us what kind of file, dump it raw */
+static void display_item(DBC *cursor, DBT *key, DBT *data)
+{
+ if (display_mode & RAWDATA) {
printf("%s\n", format(key->data, key->size));
printf("\t%s\n", format(data->data, data->size));
+ } else {
+ if (file_type & INDEXTYPE) {
+ display_index_item(cursor, key, data);
+ } else if (file_type & CHANGELOGTYPE) {
+ /* changelog db file */
+ printf("\ndbid: %s\n", format(key->data, key->size));
+ print_changelog(data->data, data->size);
+ return;
+ } else if (file_type & ENTRYTYPE) {
+ /* id2entry file */
+ ID entry_id = id_stored_to_internal(key->data);
+ printf("id %d\n", entry_id);
+ printf("\t%s\n", format_entry(data->data, data->size));
+ } else {
+ /* user didn't tell us what kind of file, dump it raw */
+ printf("%s\n", format(key->data, key->size));
+ printf("\t%s\n", format(data->data, data->size));
+ }
}
+ return;
}
static int
@@ -637,20 +669,32 @@ is_changelog(char *filename)
static void usage(char *argv0)
{
printf("\n%s - scan a db file and dump the contents\n", argv0);
+ printf(" common options:\n");
printf(" -f <filename> specify db file\n");
- printf(" -i dump as an index file\n");
- printf(" -e dump as an entry (id2entry) file\n");
- printf(" -c dump as a changelog file\n");
+ printf(" -R dump as raw data\n");
+ printf(" entry file options:\n");
+ printf(" -K <entry_id> lookup only a specific entry id\n");
+ printf(" index file options:\n");
+ printf(" -k <key> lookup only a specific key\n");
printf(" -l <size> max length of dumped id list\n");
printf(" (default %d; 40 bytes <= size <= 1048576 bytes)\n",
MAX_BUFFER);
- printf(" -n display idl lengths only (not contents)\n");
- printf(" -G <n> (when used with -n) only display index entries with\n");
- printf(" more than <n> ids\n");
- printf(" -r show libdb record numbers, too\n");
- printf(" -k <key> lookup only a specific key\n");
- printf(" -K <entry_id> lookup only a specific entry id\n");
+ printf(" -G <n> only display index entries with more than <n> ids\n");
+ printf(" -n display idl lengths\n");
+ printf(" -r display the conents of idl\n");
printf(" -s Summary of index counts\n");
+ printf(" sample usages:\n");
+ printf(" # set <serverroot>/bin/slapd/server:<serverroot>/shared/lib in the library path\n");
+ printf(" # dump the entry file\n");
+ printf(" %s -f id2entry.db\n", argv0);
+ printf(" # display index keys in cn.db4\n");
+ printf(" %s -f cn.db4\n", argv0);
+ printf(" # display index keys and the count of entries having the key in mail.db4\n");
+ printf(" %s -r -f mail.db4\n", argv0);
+ printf(" # display index keys and the IDs having more than 20 IDs in sn.db4\n");
+ printf(" %s -r -G 20 -f sn.db4\n", argv0);
+ printf(" # display summary of objectclass.db4\n");
+ printf(" %s -f objectclass.db4\n", argv0);
printf("\n");
exit(1);
}
@@ -667,19 +711,13 @@ int main(int argc, char **argv)
uint32 entry_id = 0xffffffff;
int c;
- while ((c = getopt(argc, argv, "f:iecl:nG:srk:K:hv")) != EOF) {
+ while ((c = getopt(argc, argv, "f:Rl:nG:srk:K:hv")) != EOF) {
switch (c) {
case 'f':
filename = optarg;
break;
- case 'i':
- indexfile = 1;
- break;
- case 'e':
- entryfile = 1;
- break;
- case 'c':
- changelogfile = 1;
+ case 'R':
+ display_mode |= RAWDATA;
break;
case 'l':
{
@@ -697,16 +735,16 @@ int main(int argc, char **argv)
break;
}
case 'n':
- lengths_only = 1;
+ display_mode |= SHOWCOUNT;
break;
case 'G':
min_display = atoi(optarg)+1;
break;
case 'r':
- show_recno = 1;
+ display_mode |= SHOWDATA;
break;
case 's':
- show_cnt = 1;
+ display_mode |= SHOWSUMMARY;
break;
case 'k':
find_key = optarg;
@@ -724,28 +762,14 @@ int main(int argc, char **argv)
usage(argv[0]);
}
if (NULL != strstr(filename, "id2entry.db")) {
- if (indexfile || changelogfile) {
- printf("WARNING: Specified file %s is not %s file; \n", filename,
- indexfile?"an index":(changelogfile?"a changelog":"unknown"));
- printf(" Changing the file type to entryfile\n");
- indexfile = changelogfile = 0;
- }
- entryfile = 1;
+ file_type |= ENTRYTYPE;
} else if (is_changelog(filename)) {
- if (indexfile || entryfile) {
- printf("WARNING: Specified file %s is not %s file; \n", filename,
- indexfile?"an index":(entryfile?"an entry":"unknown"));
- printf(" Changing the file type to changelogfile\n");
- indexfile = entryfile = 0;
- }
- changelogfile = 1;
+ file_type |= CHANGELOGTYPE;
} else {
- /* most likely an entry file ... */
- if (entryfile || changelogfile) {
- printf("WARNING: Specified file %s is not likely %s file; \n",
- filename, indexfile?"an index":(changelogfile?"a changelog":"unknown"));
- printf(" The output may not be accurate.\n");
- }
+ file_type |= INDEXTYPE;
+ if (0 == strncmp(filename, "vlv#", 4)) {
+ file_type |= VLVINDEXTYPE;
+ }
}
ret = db_env_create(&env, 0);
@@ -849,7 +873,7 @@ int main(int argc, char **argv)
exit(1);
}
- if ( show_cnt ) {
+ if ( display_mode & SHOWSUMMARY) {
if ( allids_cnt > 0 ) {
printf("Index keys that reached ALLIDs threshold: %ld\n", allids_cnt);