diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2005-08-25 00:41:44 +0000 |
---|---|---|
committer | Noriko Hosoi <nhosoi@redhat.com> | 2005-08-25 00:41:44 +0000 |
commit | d72eb9618271b68dbfde30d28097ce52a4a2e0c9 (patch) | |
tree | 548d8dbb32b7ec98582b72a34bad2a2feadbfc36 | |
parent | ad01ce06fd32da96a90b47659c09393e22d5def8 (diff) | |
download | ds-d72eb9618271b68dbfde30d28097ce52a4a2e0c9.tar.gz ds-d72eb9618271b68dbfde30d28097ce52a4a2e0c9.tar.xz ds-d72eb9618271b68dbfde30d28097ce52a4a2e0c9.zip |
[Bug 166632] dbscan: not to truncate the entry even if it is larger than BUFSIZ
By default, it dumps the entire entry. (it used to be truncated at the BUFSIZ
size). In case no need to dump the entire entry, introduced the truncate option
"-t".
-rw-r--r-- | ldap/servers/slapd/tools/dbscan.c | 550 |
1 files changed, 292 insertions, 258 deletions
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c index 7e1d0a1b..b3f610ef 100644 --- a/ldap/servers/slapd/tools/dbscan.c +++ b/ldap/servers/slapd/tools/dbscan.c @@ -68,25 +68,25 @@ typedef unsigned char uint8_t; #define CHANGELOGTYPE 0x8 /* display mode */ -#define RAWDATA 0x1 -#define SHOWCOUNT 0x2 -#define SHOWDATA 0x4 +#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 -#define SLAPI_OPERATION_SEARCH 0x00000004UL -#define SLAPI_OPERATION_MODIFY 0x00000008UL -#define SLAPI_OPERATION_ADD 0x00000010UL -#define SLAPI_OPERATION_DELETE 0x00000020UL -#define SLAPI_OPERATION_MODDN 0x00000040UL -#define SLAPI_OPERATION_MODRDN SLAPI_OPERATION_MODDN -#define SLAPI_OPERATION_COMPARE 0x00000080UL -#define SLAPI_OPERATION_ABANDON 0x00000100UL -#define SLAPI_OPERATION_EXTENDED 0x00000200UL -#define SLAPI_OPERATION_ANY 0xFFFFFFFFUL -#define SLAPI_OPERATION_NONE 0x00000000UL +#define SLAPI_OPERATION_BIND 0x00000001UL +#define SLAPI_OPERATION_UNBIND 0x00000002UL +#define SLAPI_OPERATION_SEARCH 0x00000004UL +#define SLAPI_OPERATION_MODIFY 0x00000008UL +#define SLAPI_OPERATION_ADD 0x00000010UL +#define SLAPI_OPERATION_DELETE 0x00000020UL +#define SLAPI_OPERATION_MODDN 0x00000040UL +#define SLAPI_OPERATION_MODRDN SLAPI_OPERATION_MODDN +#define SLAPI_OPERATION_COMPARE 0x00000080UL +#define SLAPI_OPERATION_ABANDON 0x00000100UL +#define SLAPI_OPERATION_EXTENDED 0x00000200UL +#define SLAPI_OPERATION_ANY 0xFFFFFFFFUL +#define SLAPI_OPERATION_NONE 0x00000000UL #define ONEMEG (1024*1024) @@ -94,7 +94,7 @@ typedef unsigned char uint8_t; #include <getopt.h> #endif -typedef u_int32_t ID; +typedef u_int32_t ID; typedef unsigned int uint32; @@ -104,29 +104,41 @@ typedef struct { uint32 id[1]; } IDL; +uint32 file_type = 0; +uint32 min_display = 0; +uint32 display_mode = 0; +int truncatesiz = 0; +long pres_cnt = 0; +long eq_cnt = 0; +long app_cnt = 0; +long sub_cnt = 0; +long match_cnt = 0; +long ind_cnt = 0; +long allids_cnt = 0; +long other_cnt = 0; + /** db_printf - functioning same as printf but a place for manipluating output. */ void db_printf(char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); } void db_printfln(char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); - vfprintf(stdout, "\n", NULL); + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + vfprintf(stdout, "\n", NULL); } int MAX_BUFFER = 4096; int MIN_BUFFER = 20; - static IDL *idl_make(DBT *data) { IDL *idl = NULL, *xidl; @@ -174,14 +186,17 @@ static IDL *idl_append(IDL *idl, uint32 id) /* format a string for easy printing */ #define FMT_LF_OK 1 #define FMT_SP_OK 2 -static char *format_raw(unsigned char *s, int len, int flags) +static char *format_raw(unsigned char *s, int len, int flags, + unsigned char *buf, int buflen) { - static unsigned char buf[BUFSIZ]; /* not intended to be threadsafe */ static char hex[] = "0123456789ABCDEF"; - unsigned char *p, *o; + unsigned char *p, *o, *bufend = buf + buflen - 1; int i; - for (p = s, o = buf, i = 0; i < len; p++, i++) { + if (NULL == buf || buflen <= 0) + return NULL; + + for (p = s, o = buf, i = 0; i < len && o < bufend; p++, i++) { if ((*p == '%') || (*p <= ' ') || (*p >= 126)) { /* index keys are stored with their trailing NUL */ if ((*p == 0) && (i == len-1)) @@ -199,24 +214,26 @@ static char *format_raw(unsigned char *s, int len, int flags) } else { *o++ = *p; } - if (o-buf > BUFSIZ-5) { - /* out of space */ + if (truncatesiz > 0 && o > bufend - 5) { + /* truncate it */ strcpy(o, " ..."); i = len; + o += 4; } } *o = 0; return (char *)buf; } -static char *format(unsigned char *s, int len) +static char *format(unsigned char *s, int len, unsigned char *buf, int buflen) { - return format_raw(s, len, 0); + return format_raw(s, len, 0, buf, buflen); } -static char *format_entry(unsigned char *s, int len) +static char *format_entry(unsigned char *s, int len, + unsigned char *buf, int buflen) { - return format_raw(s, len, FMT_LF_OK | FMT_SP_OK); + return format_raw(s, len, FMT_LF_OK | FMT_SP_OK, buf, buflen); } static char *idl_format(IDL *idl, int isfirsttime, int *done) @@ -251,46 +268,46 @@ static char *idl_format(IDL *idl, int isfirsttime, int *done) /*** Copied from cl5_api.c: _cl5ReadString ***/ void _cl5ReadString (char **str, char **buff) { - if (str) - { - int len = strlen (*buff); - - if (len) - { - *str = strdup(*buff); - (*buff) += len + 1; - } - else /* just null char - skip it */ - { - *str = NULL; - (*buff) ++; - } - } - else /* just skip this string */ - { - (*buff) += strlen (*buff) + 1; - } + if (str) + { + int len = strlen (*buff); + + if (len) + { + *str = strdup(*buff); + (*buff) += len + 1; + } + else /* just null char - skip it */ + { + *str = NULL; + (*buff) ++; + } + } + else /* just skip this string */ + { + (*buff) += strlen (*buff) + 1; + } } /** print_attr - print attribute name followed by one value. - assume the value stored as null terminated string. + assume the value stored as null terminated string. */ void print_attr(char *attrname, char **buff) { - char *val = NULL; - - _cl5ReadString(&val, buff); - if(attrname != NULL || val != NULL) { - db_printf("\t"); - } - - if(attrname) { - db_printf("%s: ", attrname); - } - if(val != NULL) { - db_printf("%s\n", val); - free(val); - } + char *val = NULL; + + _cl5ReadString(&val, buff); + if(attrname != NULL || val != NULL) { + db_printf("\t"); + } + + if(attrname) { + db_printf("%s: ", attrname); + } + if(val != NULL) { + db_printf("%s\n", val); + free(val); + } } /*** Copied from cl5_api.c: _cl5ReadMods ***/ @@ -302,34 +319,34 @@ void print_attr(char *attrname, char **buff) ----------- <1 byte modop><null terminated attr name><4 byte count> {<4 byte size><value1><4 byte size><value2>... || - <null terminated str1> <null terminated str2>...} + <null terminated str1> <null terminated str2>...} */ void _cl5ReadMod(char **buff); void _cl5ReadMods(char **buff) { - char *pos = *buff; - uint32 i; - uint32 mod_count; - - /* need to copy first, to skirt around alignment problems on certain - architectures */ - memcpy((char *)&mod_count, *buff, sizeof(mod_count)); - mod_count = ntohl(mod_count); - pos += sizeof (mod_count); - - - for (i = 0; i < mod_count; i++) - { - _cl5ReadMod (&pos); - } + char *pos = *buff; + uint32 i; + uint32 mod_count; + + /* need to copy first, to skirt around alignment problems on certain + architectures */ + memcpy((char *)&mod_count, *buff, sizeof(mod_count)); + mod_count = ntohl(mod_count); + pos += sizeof (mod_count); + + + for (i = 0; i < mod_count; i++) + { + _cl5ReadMod (&pos); + } - *buff = pos; + *buff = pos; } /** print_ber_attr - print one line of attribute, the value was stored - in ber format, length followed by string. + in ber format, length followed by string. */ void print_ber_attr(char* attrname, char** buff) { @@ -341,18 +358,18 @@ void print_ber_attr(char* attrname, char** buff) *buff += sizeof (uint32); if (bv_len > 0) { - db_printf("\t\t"); + db_printf("\t\t"); - if(attrname != NULL) { - db_printf("%s: ", attrname); - } + if(attrname != NULL) { + db_printf("%s: ", attrname); + } - val = malloc(bv_len + 1); - memcpy (val, *buff, bv_len); - val[bv_len] = 0; - *buff += bv_len; - db_printf("%s\n", val); - free(val); + val = malloc(bv_len + 1); + memcpy (val, *buff, bv_len); + val[bv_len] = 0; + *buff += bv_len; + db_printf("%s\n", val); + free(val); } } @@ -362,51 +379,51 @@ void print_ber_attr(char* attrname, char** buff) */ static ID id_stored_to_internal(char* b) { - ID i; - i = (ID)b[3] & 0x000000ff; - i |= (((ID)b[2]) << 8) & 0x0000ff00; - i |= (((ID)b[1]) << 16) & 0x00ff0000; - i |= ((ID)b[0]) << 24; - return i; + ID i; + i = (ID)b[3] & 0x000000ff; + i |= (((ID)b[2]) << 8) & 0x0000ff00; + i |= (((ID)b[1]) << 16) & 0x00ff0000; + i |= ((ID)b[0]) << 24; + return i; } static void id_internal_to_stored(ID i,char *b) { - if ( sizeof(ID) > 4 ) { - memset (b+4, 0, sizeof(ID)-4); - } + if ( sizeof(ID) > 4 ) { + memset (b+4, 0, sizeof(ID)-4); + } - b[0] = (char)(i >> 24); - b[1] = (char)(i >> 16); - b[2] = (char)(i >> 8); - b[3] = (char)i; + b[0] = (char)(i >> 24); + b[1] = (char)(i >> 16); + b[2] = (char)(i >> 8); + b[3] = (char)i; } void _cl5ReadMod(char **buff) { - char *pos = *buff; - uint32 i; - uint32 val_count; - char *type = NULL; - int op; - - op = (*pos) & 0x000000FF; - pos ++; - _cl5ReadString (&type, &pos); - - /* need to do the copy first, to skirt around alignment problems on - certain architectures */ - memcpy((char *)&val_count, pos, sizeof(val_count)); - val_count = ntohl(val_count); - pos += sizeof (uint32); - - for (i = 0; i < val_count; i++) - { - print_ber_attr(type, &pos); - } - - (*buff) = pos; - free(type); + char *pos = *buff; + uint32 i; + uint32 val_count; + char *type = NULL; + int op; + + op = (*pos) & 0x000000FF; + pos ++; + _cl5ReadString (&type, &pos); + + /* need to do the copy first, to skirt around alignment problems on + certain architectures */ + memcpy((char *)&val_count, pos, sizeof(val_count)); + val_count = ntohl(val_count); + pos += sizeof (uint32); + + for (i = 0; i < val_count; i++) + { + print_ber_attr(type, &pos); + } + + (*buff) = pos; + free(type); } /* @@ -427,93 +444,80 @@ width of long (32-bit or 64-bit), it's stored using 4bytes by the server [153306 */ void print_changelog(unsigned char *data, int len) { - uint8_t version; - unsigned long operation_type; - char *pos = (char *)data; - uint32 thetime32; - time_t thetime; - uint32 replgen; - - /* read byte of version */ - version = *((uint8_t *)pos); - if (version != 5) - { - db_printf("Invalid changelog db version %i\nWorks for version 5 only.\n", version); - exit(1); - } - pos += sizeof(version); - - /* read change type */ - operation_type = (unsigned long)(*(uint8_t *)pos); - pos ++; - - /* need to do the copy first, to skirt around alignment problems on - certain architectures */ - memcpy((char *)&thetime32, pos, sizeof(thetime32)); - - replgen = ntohl(thetime32); - pos += sizeof(uint32); - thetime = (time_t)replgen; - db_printf("\treplgen: %ld %s", replgen, ctime((time_t *)&thetime)); - - /* read csn */ - print_attr("csn", &pos); - /* read UniqueID */ - print_attr("uniqueid", &pos); - - /* figure out what else we need to read depending on the operation type */ - switch (operation_type) - { - case SLAPI_OPERATION_ADD: - print_attr("parentuniqueid", &pos); - print_attr("dn", &pos); - /* convert mods to entry */ - db_printf("\toperation: add\n"); - _cl5ReadMods(&pos); - break; - - case SLAPI_OPERATION_MODIFY: - print_attr("dn", &pos); - db_printf("\toperation: modify\n"); - _cl5ReadMods(&pos); - break; - - case SLAPI_OPERATION_MODRDN: - print_attr("dn", &pos); - print_attr("newrdn", &pos); - pos ++; - print_attr("dn", &pos); - print_attr("uniqueid", &pos); - db_printf("\toperation: modrdn\n"); - _cl5ReadMods(&pos); - break; - - case SLAPI_OPERATION_DELETE: - print_attr("dn", &pos); - db_printf("\toperation: delete\n"); - break; - - default: - db_printf("Failed to format entry\n"); - break; - } -} + uint8_t version; + unsigned long operation_type; + char *pos = (char *)data; + uint32 thetime32; + time_t thetime; + uint32 replgen; + + /* read byte of version */ + version = *((uint8_t *)pos); + if (version != 5) + { + db_printf("Invalid changelog db version %i\nWorks for version 5 only.\n", version); + exit(1); + } + pos += sizeof(version); -uint32 file_type = 0; -uint32 min_display = 0; -uint32 display_mode = 0; -int verbose = 0; -long pres_cnt = 0; -long eq_cnt = 0; -long app_cnt = 0; -long sub_cnt = 0; -long match_cnt = 0; -long ind_cnt = 0; -long allids_cnt = 0; -long other_cnt = 0; + /* read change type */ + operation_type = (unsigned long)(*(uint8_t *)pos); + pos ++; + + /* need to do the copy first, to skirt around alignment problems on + certain architectures */ + memcpy((char *)&thetime32, pos, sizeof(thetime32)); + + replgen = ntohl(thetime32); + pos += sizeof(uint32); + thetime = (time_t)replgen; + db_printf("\treplgen: %ld %s", replgen, ctime((time_t *)&thetime)); + + /* read csn */ + print_attr("csn", &pos); + /* read UniqueID */ + print_attr("uniqueid", &pos); + + /* figure out what else we need to read depending on the operation type */ + switch (operation_type) + { + case SLAPI_OPERATION_ADD: + print_attr("parentuniqueid", &pos); + print_attr("dn", &pos); + /* convert mods to entry */ + db_printf("\toperation: add\n"); + _cl5ReadMods(&pos); + break; + + case SLAPI_OPERATION_MODIFY: + print_attr("dn", &pos); + db_printf("\toperation: modify\n"); + _cl5ReadMods(&pos); + break; + + case SLAPI_OPERATION_MODRDN: + print_attr("dn", &pos); + print_attr("newrdn", &pos); + pos ++; + print_attr("dn", &pos); + print_attr("uniqueid", &pos); + db_printf("\toperation: modrdn\n"); + _cl5ReadMods(&pos); + break; + + case SLAPI_OPERATION_DELETE: + print_attr("dn", &pos); + db_printf("\toperation: delete\n"); + break; + default: + db_printf("Failed to format entry\n"); + break; + } +} -static void display_index_item(DBC *cursor, DBT *key, DBT *data) +static void display_index_item(DBC *cursor, DBT *key, DBT *data, + unsigned char *buf, int buflen) { IDL *idl = NULL; int ret = 0; @@ -527,9 +531,10 @@ static void display_index_item(DBC *cursor, DBT *key, DBT *data) 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)); + printf("%-40s 1\n", + format(key->data, key->size, buf, buflen)); } else { - printf("%-40s\n", format(key->data, key->size)); + printf("%-40s\n", format(key->data, key->size, buf, buflen)); } if (display_mode & SHOWDATA) { cursor->c_get(cursor, key, data, DB_GET_RECNO); @@ -558,17 +563,18 @@ static void display_index_item(DBC *cursor, DBT *key, DBT *data) if ( allids_cnt == 0 && (display_mode & SHOWSUMMARY)) { printf("The following index keys reached allids:\n"); } - printf("%-40s(allids)\n", format(key->data, key->size)); + printf("%-40s(allids)\n", format(key->data, key->size, buf, buflen)); 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); + printf("%-40s%d\n", + format(key->data, key->size, buf, buflen), 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)); + * even if it's set, but with show data */ + printf("%-40s\n", format(key->data, key->size, buf, buflen)); } if (display_mode & SHOWDATA) { char *formatted_idl = NULL; @@ -632,26 +638,48 @@ index_done: static void display_item(DBC *cursor, DBT *key, DBT *data) { + static unsigned char *buf = NULL; + static int buflen = 0; + int tmpbuflen; + + if (truncatesiz > 0) { + tmpbuflen = truncatesiz; + } else if (file_type & INDEXTYPE) { + /* +256: extra buffer for '\t' and '%##' */ + tmpbuflen = key->size + 256; + } else { + /* +1024: extra buffer for '\t' and '%##' */ + tmpbuflen = (key->size > data->size ? key->size : data->size) + 1024; + } + if (buflen < tmpbuflen) { + buflen = tmpbuflen; + buf = (unsigned char *)realloc(buf, buflen); + if (NULL == buf) { + printf("\t(malloc failed -- %d bytes)\n", buflen); + return; + } + } + if (display_mode & RAWDATA) { - printf("%s\n", format(key->data, key->size)); - printf("\t%s\n", format(data->data, data->size)); + printf("%s\n", format(key->data, key->size, buf, buflen)); + printf("\t%s\n", format(data->data, data->size, buf, buflen)); } else { if (file_type & INDEXTYPE) { - display_index_item(cursor, key, data); + display_index_item(cursor, key, data, buf, buflen); } else if (file_type & CHANGELOGTYPE) { - /* changelog db file */ - printf("\ndbid: %s\n", format(key->data, key->size)); + /* changelog db file */ + printf("\ndbid: %s\n", format(key->data, key->size, buf, buflen)); 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)); + printf("\t%s\n", format_entry(data->data, data->size, buf, buflen)); } 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)); + printf("%s\n", format(key->data, key->size, buf, buflen)); + printf("\t%s\n", format(data->data, data->size, buf, buflen)); } } return; @@ -704,6 +732,7 @@ static void usage(char *argv0) printf(" common options:\n"); printf(" -f <filename> specify db file\n"); printf(" -R dump as raw data\n"); + printf(" -t <size> entry truncate size (bytes)\n"); printf(" entry file options:\n"); printf(" -K <entry_id> lookup only a specific entry id\n"); printf(" index file options:\n"); @@ -743,7 +772,9 @@ int main(int argc, char **argv) uint32 entry_id = 0xffffffff; int c; - while ((c = getopt(argc, argv, "f:Rl:nG:srk:K:hv")) != EOF) { + key.flags = DB_DBT_REALLOC; + data.flags = DB_DBT_REALLOC; + while ((c = getopt(argc, argv, "f:Rl:nG:srk:K:hvt:")) != EOF) { switch (c) { case 'f': filename = optarg; @@ -782,7 +813,10 @@ int main(int argc, char **argv) find_key = optarg; break; case 'K': - id_internal_to_stored((ID)atoi(optarg), (char *)&entry_id); + id_internal_to_stored((ID)atoi(optarg), (char *)&entry_id); + break; + case 't': + truncatesiz = atoi(optarg); break; case 'h': default: @@ -801,7 +835,7 @@ int main(int argc, char **argv) file_type |= INDEXTYPE; if (0 == strncmp(filename, "vlv#", 4)) { file_type |= VLVINDEXTYPE; - } + } } ret = db_env_create(&env, 0); @@ -907,37 +941,37 @@ int main(int argc, char **argv) if ( display_mode & SHOWSUMMARY) { - if ( allids_cnt > 0 ) { - printf("Index keys that reached ALLIDs threshold: %ld\n", allids_cnt); - } + if ( allids_cnt > 0 ) { + printf("Index keys that reached ALLIDs threshold: %ld\n", allids_cnt); + } - if ( pres_cnt > 0 ) { - printf("Presence index keys: %ld\n", pres_cnt); - } + if ( pres_cnt > 0 ) { + printf("Presence index keys: %ld\n", pres_cnt); + } - if ( eq_cnt > 0 ) { - printf("Equality index keys: %ld\n", eq_cnt); - } + if ( eq_cnt > 0 ) { + printf("Equality index keys: %ld\n", eq_cnt); + } - if ( app_cnt > 0 ) { - printf("Approximate index keys: %ld\n", app_cnt); - } + if ( app_cnt > 0 ) { + printf("Approximate index keys: %ld\n", app_cnt); + } - if ( sub_cnt > 0 ) { - printf("Substring index keys: %ld\n", sub_cnt); - } + if ( sub_cnt > 0 ) { + printf("Substring index keys: %ld\n", sub_cnt); + } - if ( match_cnt > 0 ) { - printf("Match index keys: %ld\n", match_cnt); - } + if ( match_cnt > 0 ) { + printf("Match index keys: %ld\n", match_cnt); + } - if ( ind_cnt > 0 ) { - printf("Indirect index keys: %ld\n", ind_cnt); - } + if ( ind_cnt > 0 ) { + printf("Indirect index keys: %ld\n", ind_cnt); + } - if ( other_cnt > 0 ) { - printf("This file contains %ld number of unknown type ( possible corruption)\n",other_cnt); - } + if ( other_cnt > 0 ) { + printf("This file contains %ld number of unknown type ( possible corruption)\n",other_cnt); + } } |