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