#include #include #include #include #include #include #include #include "buffer.h" #include "ldif.h" #include "mduptab.h" #include "uint32.h" #include "byte.h" extern mduptab_t attributes,classes; extern mstorage_t stringtable; /* parse exp.ldif and write binary representation to "data". * please read "FORMAT" for a description of the file format */ #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif void dumprec(struct ldaprec* l) { int i; if (l->dn>=0) { buffer_puts(buffer_1,"dn: "); buffer_puts(buffer_1,stringtable.root+l->dn); buffer_puts(buffer_1,"\n"); } else buffer_puts(buffer_1,"no dn?!\n"); for (i=0; in; ++i) { buffer_puts(buffer_1,attributes.strings.root+l->a[i].name); buffer_puts(buffer_1,": "); if (l->a[i].name==objectClass) buffer_puts(buffer_1,classes.strings.root+l->a[i].value); else buffer_puts(buffer_1,stringtable.root+l->a[i].value); buffer_puts(buffer_1,"\n"); } buffer_putsflush(buffer_1,"\n"); } extern mstorage_t stringtable; extern mduptab_t attributes,classes; int main(int argc,char* argv[]) { int fd; long len; char* destname=argc<3?"data":argv[2]; unsigned long size_of_string_table,indices_offset,record_count; long offset_stringtable,offset_classes,offset_attributes; char* map,* dest; if ((fd=open(destname,O_RDWR|O_CREAT|O_TRUNC,0600))<0) { buffer_putsflush(buffer_2,"could not create destination data file"); return 1; } mstorage_init_persistent(&stringtable,fd); mduptab_init(&attributes); mduptab_init(&classes); { char dummy[5*4]; mstorage_add(&stringtable,dummy,5*4); } ldif_parse(argc<2?"exp.ldif":argv[1]); if (!first) { buffer_putsflush(buffer_2,"usage: parse [src-ldif-filename] [dest-bin-filename]\n"); return 1; } size_of_string_table=stringtable.used+classes.strings.used+attributes.strings.used-5*4; size_of_string_table=(size_of_string_table+3)&-4; /* round up to 32 bits */ /* first find out how much space we need */ len = 5*sizeof(uint32_t); /* magic plus four counts */ len += size_of_string_table; /* size of string table */ len += attributes.table.used/sizeof(long)*8; /* attribute_names plus attribute_flags */ // fdprintf(2,"offsets of records: %lu\n",len); /* now for the hard part: the records */ { struct ldaprec* x=first; record_count=0; while (x) { int oc=0,i; // long old=len; /* we add 8 for the pair and we substract 8 * for the two saved pointers ("dn" and "objectClass") */ if (x->dn>=0) len+=8; else { if (x->n==0 && x->next==0) break; buffer_putsflush(buffer_2,"record without dn?!\n"); dumprec(x); return 1; } for (i=0; in; ++i) { len+=8; if (x->a[i].name==objectClass) oc=1; } if (!oc) { buffer_puts(buffer_2,"record \""); buffer_puts(buffer_2,x->dn+stringtable.root); buffer_putsflush(buffer_2,"\" has no objectClass?!\n"); dumprec(x); return 1; } ++record_count; // fdprintf(2,"considering record \"%s\": length %d\n",x->dn+stringtable.root,len-old); x=x->next; } } // fdprintf(2,"offsets of indices: %lu\n",len); indices_offset=len; len+=record_count*4; /* done! we don't create any indices for now. */ munmap(stringtable.root,stringtable.mapped); ftruncate(fd,len); if ((map=mmap(0,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED) { buffer_putsflush(buffer_2,"could not mmap destination data file!\n"); unlink(destname); return 1; } uint32_pack(map ,0xfefe1da9); /* magic */ uint32_pack(map+1*4,attributes.table.used/sizeof(long)); /* attribute_count */ uint32_pack(map+2*4,record_count); /* record_count */ uint32_pack(map+3*4,indices_offset); /* indices_offset */ uint32_pack(map+4*4,size_of_string_table); /* size_of_string_table */ // size_of_string_table=stringtable.used+classes.strings.used+attributes.strings.used; offset_stringtable=5*4; offset_classes= /* offset_stringtable+ */ stringtable.used; offset_attributes=offset_classes+classes.strings.used; // byte_copy(map+offset_stringtable,stringtable.used,stringtable.root); byte_copy(map+offset_classes,classes.strings.used,classes.strings.root); byte_copy(map+offset_attributes,attributes.strings.used,attributes.strings.root); // fdprintf(2,"offset_classes=%lu, offset_attributes=%lu, attributes=%lu\n", // offset_classes,offset_attributes,attributes.strings.used); dest=map+offset_stringtable+size_of_string_table; { unsigned long i; for (i=0; in+1; record_offsets[cur]=dest-map; ++cur; uint32_pack(dest,i); uint32_pack(dest+4,0); dest+=8; uint32_pack(dest,x->dn /* +offset_stringtable */); for (i=0; in; ++i) { if (x->a[i].name==objectClass) { uint32_pack(dest+4,x->a[i].value+offset_classes); x->a[i].name=-1; break; } } dest+=8; for (i=0; in; ++i) { if (x->a[i].name>=0) { uint32_pack(dest,x->a[i].name+offset_attributes); if (x->a[i].name==objectClass) uint32_pack(dest+4,x->a[i].value+offset_classes); else uint32_pack(dest+4,x->a[i].value /* +offset_stringtable */); dest+=8; } } x=x->next; } // fdprintf(2,"actual offset of record_index: %lu\n",dest-map); /* now the record_index */ for (cur=0; cur