r8284: - fixed some uninitialised variables in the irpc code
authorAndrew Tridgell <tridge@samba.org>
Sun, 10 Jul 2005 08:35:18 +0000 (08:35 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:19:31 +0000 (13:19 -0500)
- added code to send multiple irpc calls in parallel, to all servers
  that have registered the given name, with output going in
  io.results[i]. This allows you to make rpc calls to multiple servers
  at once, which is needed for clients like smbstatus
(This used to be commit 061e20e509d95ffe16d7dd6fba7db39fc7a165ed)

source4/lib/messaging/messaging.c
source4/scripting/ejs/mprutil.c
source4/scripting/ejs/smbcalls.h
source4/scripting/ejs/smbcalls_rpc.c
source4/scripting/ejs/smbscript.c

index 5afcf91babe18651c9a2fe815742015746621b06..a29f14f0659a39f573232aa154f503a3286e2461 100644 (file)
@@ -375,6 +375,10 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id
                return NULL;
        }
 
+       if (ev == NULL) {
+               ev = event_context_init(msg);
+       }
+
        /* create the messaging directory if needed */
        path = smbd_tmp_path(msg, "messaging");
        mkdir(path, 0700);
@@ -483,6 +487,7 @@ static void irpc_handler_reply(struct messaging_context *msg_ctx,
                irpc->status = header->status;
        }
        irpc->done = True;
+       talloc_steal(irpc, ndr);
        if (irpc->async.fn) {
                irpc->async.fn(irpc);
        }
@@ -572,7 +577,9 @@ static void irpc_handler(struct messaging_context *msg_ctx, void *private,
                irpc_handler_reply(msg_ctx, ndr, &header);
        } else {
                irpc_handler_request(msg_ctx, ndr, &header, src);
+               talloc_free(ndr);
        }
+       return;
 
 failed:
        talloc_free(ndr);
@@ -674,16 +681,13 @@ failed:
 */
 NTSTATUS irpc_call_recv(struct irpc_request *irpc)
 {
-       NTSTATUS status;
        NT_STATUS_HAVE_NO_MEMORY(irpc);
        while (!irpc->done) {
                if (event_loop_once(irpc->msg_ctx->event.ev) != 0) {
                        return NT_STATUS_CONNECTION_DISCONNECTED;
                }               
        }
-       status = irpc->status;
-       talloc_free(irpc);
-       return status;
+       return irpc->status;
 }
 
 /*
index c614792d8ef353a870a6a555c71bada513f38171..c915174126c2236bbd28248edea030f61f07157b 100644 (file)
 /*
   add an indexed array element to a property
 */
-static void mprAddArray(struct MprVar *var, int i, struct MprVar v)
+ void mprAddArray(struct MprVar *var, int i, struct MprVar v)
 {
        char idx[16];
        mprItoa(i, idx, sizeof(idx));
        mprSetVar(var, idx, v);
+       mprSetVar(var, "length", mprCreateIntegerVar(i+1));
 }
 
 /*
@@ -179,8 +180,7 @@ struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
        for (i=0;i<count;i++) {
                mprAddArray(&res, i, mprLdbMessage(msg[i]));
        }
-       mprSetPropertyValue(&res, "length", mprCreateIntegerVar(i));
-       return res;     
+       return res;
 }
 
 
index c16b65b3c17023eb1a94d76ea943ab1f1d4f181d..5bd7d4e448f2f8569f0817fd9888306cb7b9962f 100644 (file)
@@ -25,5 +25,7 @@
 void mpr_Return(int eid, struct MprVar);
 NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val);
 NTSTATUS mprGetVar(struct MprVar **v, const char *name);
+void mprAddArray(struct MprVar *var, int i, struct MprVar v);
+
 
 
index 735383df08392ff6cf9c695dfde1f0bf701e0f19..bb05eda4267172828cb8ddfcb0b98f3538534d95 100644 (file)
@@ -65,13 +65,14 @@ static int ejs_irpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
                return -1;
        }
 
+       conn           = argv[0];
+
        p = talloc(conn, struct ejs_irpc_connection);
        if (p == NULL) {
                return -1;
        }
 
-       conn           = argv[0];
-       p->server_name = mprToString(argv[2]);
+       p->server_name = mprToString(argv[1]);
 
        ev = talloc_find_parent_bytype(mprMemCtx(), struct event_context);
 
@@ -92,7 +93,8 @@ static int ejs_irpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
                talloc_free(p);
                status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
        } else {
-               mprSetPtrChild(conn, "pipe", p);
+               mprSetPtrChild(conn, "irpc", p);
+               status = NT_STATUS_OK;
        }
 
        mpr_Return(eid, mprNTSTATUS(status));
@@ -170,6 +172,95 @@ static int ejs_irpc_call(int eid, struct MprVar *conn, struct MprVar *io,
                         const struct dcerpc_interface_table *iface, int callnum,
                         ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push)
 {
+       NTSTATUS status;
+       void *ptr;
+       struct ejs_rpc *ejs;
+       const struct dcerpc_interface_call *call;
+       struct ejs_irpc_connection *p;
+       struct irpc_request **reqs;
+       int i, count;
+       struct MprVar *results;
+
+       p = mprGetPtr(conn, "irpc");
+
+       ejs = talloc(mprMemCtx(), struct ejs_rpc);
+       if (ejs == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       call = &iface->calls[callnum];
+
+       ejs->eid = eid;
+       ejs->callname = call->name;
+
+       /* allocate the C structure */
+       ptr = talloc_zero_size(ejs, call->struct_size);
+       if (ptr == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       /* convert the mpr object into a C structure */
+       status = ejs_pull(ejs, io, ptr);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       for (count=0;p->dest_ids[count];count++) /* noop */ ;
+
+       /* we need to make a call per server */
+       reqs = talloc_array(ejs, struct irpc_request *, count);
+       if (reqs == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       /* make the actual calls */
+       for (i=0;i<count;i++) {
+               reqs[i] = irpc_call_send(p->msg_ctx, p->dest_ids[i], 
+                                        iface, callnum, ptr);
+               if (reqs[i] == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
+               talloc_steal(reqs, reqs[i]);
+       }
+       
+       mprSetVar(io, "results", mprCreateObjVar("results", MPR_DEFAULT_HASH_SIZE));
+       results = mprGetProperty(io, "results", NULL);
+
+       /* and receive the results, placing them in io.results[i] */
+       for (i=0;i<count;i++) {
+               struct MprVar *output;
+
+               status = irpc_call_recv(reqs[i]);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+               status = ejs_push(ejs, io, ptr);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+               talloc_free(reqs[i]);
+
+               /* add to the results array */
+               output = mprGetProperty(io, "output", NULL);
+               if (output) {
+                       char idx[16];
+                       mprItoa(i, idx, sizeof(idx));
+                       mprSetProperty(results, idx, output);
+                       mprDeleteProperty(io, "output");
+               }
+       }
+       mprSetVar(results, "length", mprCreateIntegerVar(i));
+
+done:
+       talloc_free(ejs);
+       mpr_Return(eid, mprNTSTATUS(status));
+       if (NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_ERROR)) {
+               return -1;
+       }
        return 0;
 }
 
index 80ef96e1af96cb7f811ee8df4a261f1f475c3139..bf9049af3603ccdb3c376463800a0e490d842744 100644 (file)
@@ -97,7 +97,6 @@ void ejs_exception(const char *reason)
        }
        talloc_steal(mem_ctx, argv_list);
        v = mprList("ARGV", argv_list);
-       mprSetPropertyValue(&v, "length", mprCreateIntegerVar(i-1));
        mprSetVar(ejsGetGlobalObject(eid), "ARGV", v);
 
        /* load the script and advance past interpreter line*/