2 /* modify.c - tcl modify routines
4 * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
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.
26 Modifications * modlist
29 char *command, *bp, *tcl_mods, *results;
30 struct berval suf_tcl;
31 int i, code, err = 0, len, bsize;
32 struct tclinfo *ti = (struct tclinfo *) be->be_private;
34 if (ti->ti_modify.bv_len == 0) {
35 send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
36 "modify not implemented", NULL, NULL );
40 if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
41 send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
46 tcl_mods = (char *) ch_malloc (BUFSIZ);
51 for (; modlist != NULL; modlist = modlist->sml_next) {
52 Modification *mods = &modlist->sml_mod;
54 op_add = { sizeof("add") - 1, "add" },
55 op_delete = { sizeof("delete") - 1, "delete" },
56 op_replace = { sizeof("replace") - 1, "replace" },
59 switch (mods->sm_op & ~LDAP_MOD_BVALUES) {
66 case LDAP_MOD_REPLACE:
73 len = mods->sm_type.bv_len + op->bv_len + 7;
74 while (bp + len - tcl_mods > bsize) {
76 tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
78 sprintf (bp, "{ {%s: %s} ", op->bv_val, mods->sm_type.bv_val);
81 mods->sm_bvalues != NULL && mods->sm_bvalues[i].bv_val
84 len = mods->sm_type.bv_len +
85 mods->sm_bvalues[i].bv_len + 5 +
86 (mods->sm_bvalues[i + 1].bv_val == NULL ? 2 : 0);
87 while (bp + len - tcl_mods > bsize) {
89 tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
91 sprintf (bp, "{%s: %s} %s", mods->sm_type.bv_val,
92 mods->sm_bvalues[i].bv_val,
93 mods->sm_bvalues[i + 1].bv_val ==
99 command = (char *) ch_malloc (ti->ti_modify.bv_len + suf_tcl.bv_len
100 + dn->bv_len + strlen (tcl_mods) + 84);
101 /* This space is simply for aesthetics--\ */
102 sprintf (command, "%s MODIFY {%ld/%ld} {%s} {%s} { %s}",
103 ti->ti_modify.bv_val, op->o_connid, (long) op->o_msgid,
104 suf_tcl.bv_val, dn->bv_val, tcl_mods);
105 Tcl_Free (suf_tcl.bv_val);
108 ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
109 code = Tcl_GlobalEval (ti->ti_ii->interp, command);
110 results = (char *) ch_strdup (ti->ti_ii->interp->result);
111 ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
114 if (code != TCL_OK) {
115 err = LDAP_OPERATIONS_ERROR;
116 Debug (LDAP_DEBUG_SHELL, "tcl_modify_error: %s\n", results,
119 interp_send_results (be, conn, op, results, NULL, 0);
122 if (err != LDAP_SUCCESS)
123 send_ldap_result (conn, op, err, NULL,
124 "internal backend error", NULL, NULL );