]> git.sur5r.net Git - openldap/blob - servers/slapd/back-tcl/tcl_util.c
Fix objectSubClassIndexer bug
[openldap] / servers / slapd / back-tcl / tcl_util.c
1 /* $OpenLDAP$ */
2 /* result.c - tcl backend utility functions
3  *
4  * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted only
7  * as authorized by the OpenLDAP Public License.  A copy of this
8  * license is available at http://www.OpenLDAP.org/license.html or
9  * in file LICENSE in the top-level directory of the distribution.
10  */
11
12 #include "portable.h"
13
14 #include <stdio.h>
15
16 #include <ac/string.h>
17 #include <ac/socket.h>
18 #include <ac/unistd.h>
19
20 #include "slap.h"
21 #include "tcl_back.h"
22
23 int
24 interp_send_results (
25         Backend * be,
26         Connection * conn,
27         Operation * op,
28         char *result,
29         AttributeName *attrs,
30         int attrsonly
31 )
32 {
33         int bsize, len, argcPtr, i, err, code;
34         char *buf, *bp, **argvPtr, *line, *matched, *info;
35         Entry *e;
36         struct tclinfo *ti = (struct tclinfo *) be->be_private;
37
38         /*
39          * read in the result and send it along 
40          */
41         buf = (char *) ch_malloc (BUFSIZ);
42         buf[0] = '\0';
43         bsize = BUFSIZ;
44         bp = buf;
45         code = Tcl_SplitList (ti->ti_ii->interp, result, &argcPtr, &argvPtr);
46         if (code != TCL_OK) {
47                 argcPtr = 0;
48                 send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
49                         "internal backend error", NULL, NULL );
50                 return -1;
51         }
52         for (i = 0; i < argcPtr; i++) {
53                 line = argvPtr[i];
54
55                 /*
56                  * ignore lines beginning with DEBUG: 
57                  */
58                 if (strncasecmp (line, "DEBUG:", 6) == 0) {
59                         continue;
60                 }
61                 len = strlen (line) + 1;
62                 while (bp + len - buf > bsize) {
63                         bsize += BUFSIZ;
64                         buf = (char *) ch_realloc (buf, bsize);
65                 }
66                 sprintf (bp, "%s\n", line);
67                 bp += len;
68
69                 /*
70                  * line marked the end of an entry or result 
71                  */
72                 if (line[0] == '\0') {
73                         if (strncasecmp (buf, "RESULT", 6) == 0) {
74                                 break;
75                         }
76                         if ((e = str2entry (buf)) == NULL) {
77                                 Debug (LDAP_DEBUG_SHELL,
78                                         "str2entry(%s) failed\n",
79                                         buf, 0, 0);
80                         } else {
81                                 send_search_entry (be, conn, op, e, attrs,
82                                         attrsonly, NULL );
83                                 entry_free (e);
84                         }
85
86                         bp = buf;
87                 }
88         }
89
90         (void) str2result (buf, &err, &matched, &info);
91
92         /*
93          * otherwise, front end will send this result 
94          */
95         if (err != 0 || op->o_tag != LDAP_REQ_BIND) {
96                 send_ldap_result (conn, op, err, matched, info, NULL, NULL );
97         }
98
99         free (buf);
100         Tcl_Free ((char *) argvPtr);
101         return (err);
102 }
103
104 char *
105 tcl_clean_entry (
106         Entry * e
107 )
108 {
109         char *entrystr, *mark1, *mark2, *buf, *bp, *dup;
110         int len, bsize;
111
112         ldap_pvt_thread_mutex_lock(&entry2str_mutex);
113         entrystr = entry2str (e, &len);
114
115         buf = (char *) ch_malloc (BUFSIZ);
116         buf[0] = '\0';
117         bsize = BUFSIZ;
118         bp = buf;
119         bp++[0] = ' ';
120
121         mark1 = entrystr;
122         do {
123                 if (mark1[0] == '\n') {
124                         mark1++;
125                 }
126                 dup = (char *) ch_strdup (mark1);
127                 if (dup[0] != '\0') {
128                         if ((mark2 = (char *) strchr (dup, '\n')) != NULL) {
129                                 mark2[0] = '\0';
130                         }
131                         len = strlen (dup) + 3;
132                         while (bp + len - buf > bsize) {
133                                 bsize += BUFSIZ;
134                                 buf = (char *) ch_realloc (buf, bsize);
135                         }
136                         if (mark1[0] == '\0') {
137                                 sprintf (bp, "{} ");
138                         } else {
139                                 sprintf (bp, "{%s} ", dup);
140                         }
141                         bp += len;
142                         if (mark2 != NULL) {
143                                 mark2[0] = '\n';
144                         }
145                 }
146                 free (dup);
147         } while ((mark1 = (char *) strchr (mark1, '\n')) != NULL);
148
149         ldap_pvt_thread_mutex_unlock (&entry2str_mutex);
150         return buf;
151 }
152
153 int
154 tcl_ldap_debug (
155         ClientData clientData,
156         Tcl_Interp * interp,
157         int argc,
158         char *argv[]
159 )
160 {
161         if (argv[1] != NULL) {
162                 Debug (LDAP_DEBUG_SHELL, "tcl_debug: %s\n", argv[1], 0, 0);
163         }
164         return TCL_OK;
165 }
166
167 void
168 readtclscript (
169         char *script,
170         Tcl_Interp * my_tcl)
171 {
172         int code;
173         FILE *f;
174
175         f = fopen (script, "r");
176         if (f == NULL) {
177                 Debug (LDAP_DEBUG_SHELL, "Could not open scriptpath %s\n", script,
178                         0, 0);
179                 return;
180         }
181         fclose (f);
182         code = Tcl_EvalFile (my_tcl, script);
183         if (code != TCL_OK) {
184                 Debug (LDAP_DEBUG_SHELL, "%s: %s\n", script,
185                         Tcl_GetVar (my_tcl, "errorInfo", TCL_GLOBAL_ONLY), 0);
186                 Debug (LDAP_DEBUG_SHELL, "%s: error at line\n", script,
187                         my_tcl->errorLine, 0);
188                 return;
189         }
190 }
191
192
193 struct berval *
194 tcl_merge_bvlist(
195         BerVarray bvlist, struct berval *out)
196 {
197         struct berval *ret = NULL;
198         int i;
199
200         if (bvlist == NULL)
201                 return NULL;
202
203         if (out == NULL) {
204                 ret = (struct berval *)ch_malloc(sizeof(struct berval));
205                 if (ret == NULL) {
206                         return NULL;
207                 }
208         } else {
209                 ret = out;
210         }
211
212         ret->bv_len = 0;
213         ret->bv_val = NULL;
214
215         for (i = 0; bvlist[i].bv_val != NULL; i++);
216
217         if (i) {
218                 char **strlist = ch_malloc ((i + 1) * sizeof(char *));
219                 if (strlist == NULL) {
220                         if (out == NULL)
221                                 ch_free (ret);
222                         return NULL;
223                 }
224                 for (i = 0; bvlist[i].bv_val != NULL; i++) {
225                         strlist[i] = bvlist[i].bv_val;
226                 }
227                 strlist[i] = NULL;
228                 ret->bv_val = Tcl_Merge(i, strlist);
229                 ret->bv_len = ret->bv_val ? strlen(ret->bv_val) : 0;
230                 ch_free (strlist);
231         }
232
233         return ret;
234 }
235