1 #include <buffer.h>
2 #include <scan.h>
3 #include <open.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include "strduptab.h"
7 #include "strstorage.h"
8 #include "str.h"
9 
10 /* how many attributes do we allow per record? */
11 #define ATTRIBS 8
12 
13 struct attribute {
14   const char* name,* value;
15 };
16 
17 struct ldaprec {
18   const char* dn,* mail,* sn,* cn;	/* most often encountered records */
19   int n;	/* number of attributes */
20   struct attribute a[ATTRIBS];
21   struct ldaprec* next;
22 };
23 
24 static struct stringduptable tags;
25 static struct stringduptable classes;
26 
27 const char* dn,* mail,* sn,* cn,* objectClass;
28 
parserec(buffer * b,struct ldaprec ** l)29 int parserec(buffer* b, struct ldaprec** l) {
30   char buf[8192];
31   int n,i,eof=0,ofs=0;
32   if (!(*l=malloc(sizeof(struct ldaprec)))) return 2;
33   do {
34     const char* tmp,* val;
35     n=ofs+buffer_get_token(b,buf+ofs,8192-ofs,":",1);
36     i=scan_whitenskip(buf,n);
37     buf[n]=0;
38     if (!(tmp=strduptab_add(&tags,buf+i))) {
39 nomem:
40       buffer_putsflush(buffer_2,"out of memory!\n");
41       return 1;
42     }
43 #if 0
44     buffer_puts(buffer_1,"found tag ");
45     buffer_put(buffer_1,buf+i,n-i);
46     buffer_putsflush(buffer_1,".\n");
47 #endif
48     n=buffer_get_token(b,buf,8192,"\n",1);
49     if (n==0) break;
50     i=scan_whitenskip(buf,n);
51 lookagain:
52     {
53       char c;
54       switch (buffer_getc(b,&c)) {
55       case 0: eof=1; break;
56       case -1: buffer_putsflush(buffer_2,"read error!\n"); return 1;
57       }
58       if (c==' ') {	/* continuation */
59 //	puts("continuation!");
60 	n+=buffer_get_token(b,buf+n,8192-n,"\n",1);
61 	goto lookagain;
62       } else if (c=='\n') {
63 #if 1
64 	struct ldaprec* m=malloc(sizeof(struct ldaprec));
65 	if (!m) return 2;
66 	(*l)->next=m;
67 	m->n=0; m->dn=m->mail=m->sn=m->cn=0; m->next=0;
68 	ofs=0;
69 	l=&((*l)->next);
70 #else
71 	struct ldaprec* m=malloc(sizeof(struct ldaprec));
72 	if (!m) return 2;
73 	m->next=*l;
74 	*l=m;
75 	m->n=0; m->dn=m->mail=m->sn=m->cn=0;
76 	ofs=0;
77 #endif
78       } else {
79 	ofs=1;
80 	buf[0]=c;
81       }
82     }
83     buf[n]=0;
84     if (tmp==objectClass) {
85       if (!(val=strduptab_add(&classes,buf+i))) goto nomem;
86     } else
87       if (!(val=strstorage_add(buf+i,n-i+1))) goto nomem;
88     if (tmp==dn) (*l)->dn=val; else
89     if (tmp==mail) (*l)->mail=val; else
90     if (tmp==sn) (*l)->sn=val; else
91     if (tmp==cn) (*l)->cn=val; else {
92       if ((*l)->n<ATTRIBS) {
93 	(*l)->a[(*l)->n].name=tmp;
94 	(*l)->a[(*l)->n].value=val;
95 	++(*l)->n;
96       }
97     }
98 #if 0
99     buffer_puts(buffer_1,"found value \"");
100     buffer_put(buffer_1,buf+i,n-i);
101     buffer_putsflush(buffer_1,"\".\n");
102 #endif
103 //    write(2,".",1);
104   } while (!eof);
105   if (!(*l)->dn) {
106     struct ldaprec* m=(*l)->next;
107     free((*l));
108     (*l)=m;
109   }
110   return 0;
111 }
112 
113 struct ldaprec *first=0;
114 
parse_ldif(const char * filename)115 int parse_ldif(const char* filename) {
116   char buf[4096];
117   int fd=open_read(filename);
118   buffer in;
119   if (fd<0) return 1;
120   buffer_init(&in,(void*)read,fd,buf,sizeof buf);
121   dn=strduptab_add(&tags,"dn");
122   mail=strduptab_add(&tags,"mail");
123   sn=strduptab_add(&tags,"sn");
124   cn=strduptab_add(&tags,"cn");
125   objectClass=strduptab_add(&tags,"objectClass");
126   parserec(&in,&first);
127   close(fd);
128   return 0;
129 }
130 
131 #ifndef INCLUDE
main()132 int main() {
133   parse_ldif("exp.ldif");
134 //  read(0,buf,1);
135 #if 0
136   /* dump structure */
137   while (first) {
138     printf("dn= %s\n",first->dn);
139     first=first->next;
140   }
141 #endif
142   return 0;
143 }
144 #endif
145