]> git.sur5r.net Git - openldap/blob - servers/slapd/back-tcl/tcl_util.c
Major API change - (SLAP_OP_BLOCKS) All request parameters are
[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         Operation * op,
26         SlapReply * rs,
27         char *result
28 )
29 {
30         int bsize, len, argcPtr, i, code;
31         char *buf, *bp, **argvPtr, *line;
32         struct tclinfo *ti = (struct tclinfo *) op->o_bd->be_private;
33
34         /*
35          * read in the result and send it along 
36          */
37         buf = (char *) ch_malloc (BUFSIZ);
38         buf[0] = '\0';
39         bsize = BUFSIZ;
40         bp = buf;
41         code = Tcl_SplitList (ti->ti_ii->interp, result, &argcPtr, &argvPtr);
42         if (code != TCL_OK) {
43                 argcPtr = 0;
44                 send_ldap_error (op, rs, LDAP_UNWILLING_TO_PERFORM,
45                         "internal backend error" );
46                 return -1;
47         }
48         for (i = 0; i < argcPtr; i++) {
49                 line = argvPtr[i];
50
51                 /*
52                  * ignore lines beginning with DEBUG: 
53                  */
54                 if (strncasecmp (line, "DEBUG:", 6) == 0) {
55                         continue;
56                 }
57                 len = strlen (line) + 1;
58                 while (bp + len - buf > bsize) {
59                         bsize += BUFSIZ;
60                         buf = (char *) ch_realloc (buf, bsize);
61                 }
62                 sprintf (bp, "%s\n", line);
63                 bp += len;
64
65                 /*
66                  * line marked the end of an entry or result 
67                  */
68                 if (line[0] == '\0') {
69                         if (strncasecmp (buf, "RESULT", 6) == 0) {
70                                 break;
71                         }
72                         if ((rs->sr_entry = str2entry (buf)) == NULL) {
73                                 Debug (LDAP_DEBUG_SHELL,
74                                         "str2entry(%s) failed\n",
75                                         buf, 0, 0);
76                         } else {
77                                 rs->sr_attrs = op->oq_search.rs_attrs;
78                                 send_search_entry (op, rs);
79                                 entry_free (rs->sr_entry);
80                         }
81
82                         bp = buf;
83                 }
84         }
85
86         (void) str2result (buf, &rs->sr_err, (char **)&rs->sr_matched, (char **)&rs->sr_text);
87
88         /*
89          * otherwise, front end will send this result 
90          */
91         if (rs->sr_err != 0 || op->o_tag != LDAP_REQ_BIND) {
92                 send_ldap_result (op, rs);
93         }
94
95         free (buf);
96         Tcl_Free ((char *) argvPtr);
97         return (rs->sr_err);
98 }
99
100 char *
101 tcl_clean_entry (
102         Entry * e
103 )
104 {
105         char *entrystr, *mark1, *mark2, *buf, *bp, *dup;
106         int len, bsize;
107
108         ldap_pvt_thread_mutex_lock(&entry2str_mutex);
109         entrystr = entry2str (e, &len);
110
111         buf = (char *) ch_malloc (BUFSIZ);
112         buf[0] = '\0';
113         bsize = BUFSIZ;
114         bp = buf;
115         bp++[0] = ' ';
116
117         mark1 = entrystr;
118         do {
119                 if (mark1[0] == '\n') {
120                         mark1++;
121                 }
122                 dup = (char *) ch_strdup (mark1);
123                 if (dup[0] != '\0') {
124                         if ((mark2 = (char *) strchr (dup, '\n')) != NULL) {
125                                 mark2[0] = '\0';
126                         }
127                         len = strlen (dup) + 3;
128                         while (bp + len - buf > bsize) {
129                                 bsize += BUFSIZ;
130                                 buf = (char *) ch_realloc (buf, bsize);
131                         }
132                         if (mark1[0] == '\0') {
133                                 sprintf (bp, "{} ");
134                         } else {
135                                 sprintf (bp, "{%s} ", dup);
136                         }
137                         bp += len;
138                         if (mark2 != NULL) {
139                                 mark2[0] = '\n';
140                         }
141                 }
142                 free (dup);
143         } while ((mark1 = (char *) strchr (mark1, '\n')) != NULL);
144
145         ldap_pvt_thread_mutex_unlock (&entry2str_mutex);
146         return buf;
147 }
148
149 int
150 tcl_ldap_debug (
151         ClientData clientData,
152         Tcl_Interp * interp,
153         int argc,
154         char *argv[]
155 )
156 {
157         if (argv[1] != NULL) {
158                 Debug (LDAP_DEBUG_SHELL, "tcl_debug: %s\n", argv[1], 0, 0);
159         }
160         return TCL_OK;
161 }
162
163 void
164 readtclscript (
165         char *script,
166         Tcl_Interp * my_tcl)
167 {
168         int code;
169         FILE *f;
170
171         f = fopen (script, "r");
172         if (f == NULL) {
173                 Debug (LDAP_DEBUG_SHELL, "Could not open scriptpath %s\n", script,
174                         0, 0);
175                 return;
176         }
177         fclose (f);
178         code = Tcl_EvalFile (my_tcl, script);
179         if (code != TCL_OK) {
180                 Debug (LDAP_DEBUG_SHELL, "%s: %s\n", script,
181                         Tcl_GetVar (my_tcl, "errorInfo", TCL_GLOBAL_ONLY), 0);
182                 Debug (LDAP_DEBUG_SHELL, "%s: error at line\n", script,
183                         my_tcl->errorLine, 0);
184                 return;
185         }
186 }
187
188
189 struct berval *
190 tcl_merge_bvlist(
191         BerVarray bvlist, struct berval *out)
192 {
193         struct berval *ret = NULL;
194         int i;
195
196         if (bvlist == NULL)
197                 return NULL;
198
199         if (out == NULL) {
200                 ret = (struct berval *)ch_malloc(sizeof(struct berval));
201                 if (ret == NULL) {
202                         return NULL;
203                 }
204         } else {
205                 ret = out;
206         }
207
208         ret->bv_len = 0;
209         ret->bv_val = NULL;
210
211         for (i = 0; bvlist[i].bv_val != NULL; i++);
212
213         if (i) {
214                 char **strlist = ch_malloc ((i + 1) * sizeof(char *));
215                 if (strlist == NULL) {
216                         if (out == NULL)
217                                 ch_free (ret);
218                         return NULL;
219                 }
220                 for (i = 0; bvlist[i].bv_val != NULL; i++) {
221                         strlist[i] = bvlist[i].bv_val;
222                 }
223                 strlist[i] = NULL;
224                 ret->bv_val = Tcl_Merge(i, strlist);
225                 ret->bv_len = ret->bv_val ? strlen(ret->bv_val) : 0;
226                 ch_free (strlist);
227         }
228
229         return ret;
230 }
231