1 #include <stdlib.h>
2 #include "buffer.h"
3 #include "mmap.h"
4 #include "uint32.h"
5 
main(int argc,char * argv[])6 int main(int argc,char* argv[]) {
7   int verbose=0;
8   unsigned long filelen;
9   char* fn=argc<2?"data":argv[1];
10   const char* map=mmap_read(fn,&filelen);
11   uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table;
12   if (!map) {
13     buffer_puts(buffer_2,"could not open \"");
14     buffer_puts(buffer_2,fn);
15     buffer_puts(buffer_2,"\": ");
16     buffer_puterror(buffer_2);
17     buffer_putnlflush(buffer_2);
18     exit(1);
19   }
20   buffer_puts(buffer_1,"magic: ");
21   uint32_unpack(map,&magic);
22   uint32_unpack(map+4,&attribute_count);
23   uint32_unpack(map+2*4,&record_count);
24   uint32_unpack(map+3*4,&indices_offset);
25   uint32_unpack(map+4*4,&size_of_string_table);
26   buffer_putxlong(buffer_1,magic);
27   buffer_puts(buffer_1,"\nattribute_count=");
28   buffer_putulong(buffer_1,attribute_count);
29   buffer_puts(buffer_1,"\nrecord_count=");
30   buffer_putulong(buffer_1,record_count);
31   buffer_puts(buffer_1,"\nindices_offset=");
32   buffer_putulong(buffer_1,indices_offset);
33   buffer_puts(buffer_1,"\nsize_of_string_table=");
34   buffer_putulong(buffer_1,size_of_string_table);
35   buffer_putsflush(buffer_1,"\n");
36 
37   buffer_puts(buffer_1,"\n\nAttributes:\n");
38   /* now print some attributes */
39   {
40     unsigned int i;
41     const char* x=map+5*4+size_of_string_table;
42     for (i=0; i<attribute_count; ++i) {
43       uint32 j;
44       uint32_unpack(x,&j);
45       buffer_puts(buffer_1,map+j);
46       uint32_unpack(x+attribute_count*4,&j);
47       if (j&1) buffer_puts(buffer_1," (case insensitive)");
48       buffer_putsflush(buffer_1,"\n");
49       x+=4;
50     }
51   }
52 
53   if (verbose) {
54     unsigned long i;
55     const char* x=map+5*4+size_of_string_table+attribute_count*8;
56     buffer_puts(buffer_1,"\nRecords:\n");
57     for (i=0; i<record_count; ++i) {
58       uint32 j,k;
59       uint32_unpack(x,&j);
60       buffer_putulong(buffer_1,j);
61       buffer_puts(buffer_1," attributes:\n");
62       x+=8;
63       buffer_puts(buffer_1,"  dn: ");
64       uint32_unpack(x,&k);
65       buffer_puts(buffer_1,map+k);
66       buffer_puts(buffer_1,"\n  objectClass: ");
67       x+=4;
68       uint32_unpack(x,&k);
69       buffer_puts(buffer_1,map+k);
70       buffer_puts(buffer_1,"\n");
71       x+=4;
72       for (; j>2; --j) {
73 	uint32_unpack(x,&k);
74 	buffer_puts(buffer_1,"  ");
75 	buffer_puts(buffer_1,map+k);
76 	buffer_puts(buffer_1,": ");
77 	uint32_unpack(x+4,&k);
78 	buffer_puts(buffer_1,map+k);
79 	buffer_puts(buffer_1,"\n");
80 	x+=8;
81       }
82     }
83   }
84 
85   buffer_puts(buffer_1,"\nIndices:\n");
86   {
87     uint32 ofs;
88     for (ofs=indices_offset+record_count*4; ofs<(unsigned long)filelen;) {
89       uint32 index_type,next,indexed_attribute;
90       uint32_unpack(map+ofs,&index_type);
91       uint32_unpack(map+ofs+4,&next);
92       uint32_unpack(map+ofs+8,&indexed_attribute);
93       buffer_puts(buffer_1,"index type: ");
94       switch (index_type) {
95       case 0:
96 	buffer_puts(buffer_1,"sorted table");
97 	break;
98       case 1:
99 	buffer_puts(buffer_1,"sorted table with record pointer");
100 	break;
101       case 2:
102 	buffer_puts(buffer_1,"acl data");
103 	break;
104       case 3:
105 	buffer_puts(buffer_1,"hash table");
106 	break;
107       default:
108 	buffer_puts(buffer_1,"unknown (");
109 	buffer_putulong(buffer_1,index_type);
110 	buffer_puts(buffer_1,")");
111 	break;
112       }
113       buffer_puts(buffer_1,"\nnext: ");
114       buffer_putulong(buffer_1,next);
115       if (index_type<=1 || index_type==3) {
116 	buffer_puts(buffer_1,"\nattribute: ");
117 	buffer_puts(buffer_1,map+indexed_attribute);
118       }
119       buffer_puts(buffer_1,"\nsize: ");
120       buffer_putulong(buffer_1,(next-ofs)/1024);
121       buffer_puts(buffer_1," KiB\n");
122       ofs=next;
123     }
124   }
125   buffer_flush(buffer_1);
126   return 0;
127 }
128