r8198: - handled push/pull of simple strings in ejs
authorAndrew Tridgell <tridge@samba.org>
Thu, 7 Jul 2005 08:20:57 +0000 (08:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:19:19 +0000 (13:19 -0500)
- improved the error handling, so the ejs wrappers don't just ignore a type they
  don't handle, instead an exception is issued saying what isn't handled

source/build/pidl/ejs.pm
source/scripting/ejs/ejsrpc.c
source/scripting/ejs/ejsrpc.h
source/scripting/ejs/smbcalls_rpc.c

index 14c0c3668f293ee9787821a22ab24cd5e51037a8..bd35078abdf80fa167877cdd96ed036e0e79498a 100644 (file)
@@ -97,6 +97,18 @@ sub EjsPullScalar($$)
        pidl "\tNDR_CHECK(ejs_pull_$e->{TYPE}(ejs, v, \"$e->{NAME}\", $ptr));\n";
 }
 
+###########################
+# pull a string element
+sub EjsPullString($$$)
+{
+       my $e = shift;
+       my $l = shift;
+       my $env = shift;
+       my $var = util::ParseExpr($e->{NAME}, $env);
+       my $ptr = get_pointer_to($var);
+       pidl "\tNDR_CHECK(ejs_pull_string(ejs, v, \"$e->{NAME}\", $ptr));\n";
+}
+
 
 ###########################
 # pull an arrar element
@@ -109,7 +121,7 @@ sub EjsPullArray($$$)
        my $length = util::ParseExpr($l->{LENGTH_IS}, $env);
        my $var = util::ParseExpr($e->{NAME}, $env);
        my $ptr = get_pointer_to($var);
-       pidl "\tNDR_CHECK(ejs_pull_array(ejs, v, \"$e->{NAME}\", $length, sizeof($ptr\[0]), (void **)$ptr, (ejs_pull_t)ejs_pull_$e->{TYPE}));\n";
+       pidl "\tNDR_CHECK(ejs_pull_array(ejs, v, \"$e->{NAME}\", $length, sizeof($var\[0]), (void **)$ptr, (ejs_pull_t)ejs_pull_$e->{TYPE}));\n";
 }
 
 ###########################
@@ -119,8 +131,15 @@ sub EjsPullElement($$)
        my $e = shift;
        my $env = shift;
        my $l = $e->{LEVELS}[0];
-       ($l->{TYPE} eq "ARRAY") && EjsPullArray($e, $l, $env);
-       ($l->{TYPE} eq "DATA") && EjsPullScalar($e, $env);
+       if (util::has_property($e, "charset")) {
+               EjsPullString($e, $l, $env);
+       } elsif ($l->{TYPE} eq "ARRAY") {
+               EjsPullArray($e, $l, $env);
+       } elsif ($l->{TYPE} eq "DATA") {
+               EjsPullScalar($e, $env);
+       } else {
+               pidl "return ejs_panic(ejs, \"unhandled pull type $l->{TYPE}\");\n";
+       }
 }
 
 ###########################
@@ -169,11 +188,12 @@ sub EjsPullFunction($)
 {
        my $d = shift;
        my $env = GenerateFunctionInEnv($d);
+       my $name = $d->{NAME};
 
-       pidl "\nstatic NTSTATUS ejs_pull_$d->{NAME}(struct ejs_rpc *ejs, struct MprVar *v, struct $d->{NAME} *r)\n";
+       pidl "\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, struct $name *r)\n";
        pidl "{\n";
 
-       pidl "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, \"in\"));\n";
+       pidl "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, \"input\"));\n";
 
        foreach my $e (@{$d->{ELEMENTS}}) {
                next unless (grep(/in/, @{$e->{DIRECTION}}));
@@ -194,14 +214,23 @@ sub EjsPushScalar($$$)
        my $env = shift;
        my $var = util::ParseExpr($e->{NAME}, $env);
 
-       if (not typelist::is_scalar($l->{DATA_TYPE}) or 
-           typelist::scalar_is_reference($l->{DATA_TYPE})) {
-               $var = get_pointer_to($var);
-       }
+       $var = get_pointer_to($var);
 
        pidl "\tNDR_CHECK(ejs_push_$e->{TYPE}(ejs, v, \"$e->{NAME}\", $var));\n";
 }
 
+###########################
+# pull a string element
+sub EjsPushString($$$)
+{
+       my $e = shift;
+       my $l = shift;
+       my $env = shift;
+       my $var = util::ParseExpr($e->{NAME}, $env);
+
+       pidl "\tNDR_CHECK(ejs_push_string(ejs, v, \"$e->{NAME}\", $var));\n";
+}
+
 ###########################
 # pull a pointer element
 sub EjsPushPointer($$$)
@@ -215,9 +244,7 @@ sub EjsPushPointer($$$)
                $var = get_value_of($var);
                $l = Ndr::GetNextLevel($e, $l);
        }
-       if (not typelist::is_scalar($l->{DATA_TYPE})) {
-               $var = get_pointer_to($var);            
-       }
+       $var = get_pointer_to($var);            
 
        pidl "\tNDR_CHECK(ejs_push_$e->{TYPE}(ejs, v, \"$e->{NAME}\", $var));\n";
 }
@@ -243,9 +270,17 @@ sub EjsPushElement($$)
        my $e = shift;
        my $env = shift;
        my $l = $e->{LEVELS}[0];
-       ($l->{TYPE} eq "ARRAY") && EjsPushArray($e, $l, $env);
-       ($l->{TYPE} eq "DATA") && EjsPushScalar($e, $l, $env);
-       ($l->{TYPE} eq "POINTER") && EjsPushPointer($e, $l, $env);
+       if (util::has_property($e, "charset")) {
+               EjsPushString($e, $l, $env);
+       } elsif ($l->{TYPE} eq "ARRAY") {
+               EjsPushArray($e, $l, $env);
+       } elsif ($l->{TYPE} eq "DATA") {
+               EjsPushScalar($e, $l, $env);
+       } elsif (($l->{TYPE} eq "POINTER")) {
+               EjsPushPointer($e, $l, $env);
+       } else {
+               pidl "return ejs_panic(ejs, \"unhandled push type $l->{TYPE}\");\n";
+       }
 }
 
 ###########################
@@ -255,7 +290,7 @@ sub EjsStructPush($$)
        my $name = shift;
        my $d = shift;
        my $env = GenerateStructEnv($d);
-       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)\n{\n";
+       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)\n{\n";
        pidl "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, name));\n";
         foreach my $e (@{$d->{ELEMENTS}}) {
                EjsPushElement($e, $env);
@@ -270,7 +305,7 @@ sub EjsUnionPush($$)
 {
        my $name = shift;
        my $d = shift;
-       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)\n{\n";
+       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)\n{\n";
        pidl "\treturn NT_STATUS_OK;\n";
        pidl "}\n\n";
 }
@@ -281,8 +316,9 @@ sub EjsEnumPush($$)
 {
        my $name = shift;
        my $d = shift;
-       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name r)\n{\n";
-       pidl "\tNDR_CHECK(ejs_push_enum(ejs, v, name, r));\n";
+       pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)\n{\n";
+       pidl "\tunsigned e = *r;\n";
+       pidl "\tNDR_CHECK(ejs_push_enum(ejs, v, name, &e));\n";
        pidl "\treturn NT_STATUS_OK;\n";
        pidl "}\n\n";
 }
@@ -309,7 +345,7 @@ sub EjsPushFunction($)
        pidl "\nstatic NTSTATUS ejs_push_$d->{NAME}(struct ejs_rpc *ejs, struct MprVar *v, const struct $d->{NAME} *r)\n";
        pidl "{\n";
 
-       pidl "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, \"out\"));\n";
+       pidl "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, \"output\"));\n";
 
        foreach my $e (@{$d->{ELEMENTS}}) {
                next unless (grep(/out/, @{$e->{DIRECTION}}));
index 4984518c7f43e962999f111e46ed33514d20388f..75f748f1467946daca9f6ffb4cd6687c79b25def 100644 (file)
 #include "lib/ejs/ejs.h"
 #include "scripting/ejs/ejsrpc.h"
 
-NTSTATUS ejs_pull_rpc(struct MprVar *v, void *ptr, ejs_pull_function_t ejs_pull)
+NTSTATUS ejs_pull_rpc(int eid, const char *callname, 
+                     struct MprVar *v, void *ptr, ejs_pull_function_t ejs_pull)
 {
-       struct ejs_rpc *ejs = talloc(ptr, struct ejs_rpc);
+       struct ejs_rpc *ejs = talloc(ptr, struct ejs_rpc);      
+       NT_STATUS_HAVE_NO_MEMORY(ejs);
+       ejs->eid = eid;
+       ejs->callname = callname;
        return ejs_pull(ejs, v, ptr);
 }
 
 
-NTSTATUS ejs_push_rpc(struct MprVar *v, const void *ptr, ejs_push_function_t ejs_push)
+NTSTATUS ejs_push_rpc(int eid, const char *callname, 
+                     struct MprVar *v, const void *ptr, ejs_push_function_t ejs_push)
 {
        struct ejs_rpc *ejs = talloc(ptr, struct ejs_rpc);
+       NT_STATUS_HAVE_NO_MEMORY(ejs);
+       ejs->eid = eid;
+       ejs->callname = callname;
        return ejs_push(ejs, v, ptr);
 }
 
 
+/*
+  panic in the ejs wrapper code
+ */
+NTSTATUS ejs_panic(struct ejs_rpc *ejs, const char *why)
+{
+       ejsSetErrorMsg(ejs->eid, "rpc_call '%s' failed - %s", ejs->callname, why);
+       return NT_STATUS_INTERNAL_ERROR;
+}
+
 /*
   find a mpr component, allowing for sub objects, using the '.' convention
 */
@@ -279,3 +296,27 @@ NTSTATUS ejs_push_array(struct ejs_rpc *ejs,
        return mprSetVar(v, "length", mprCreateIntegerVar(i));
 }
                        
+
+/*
+  pull a string
+*/
+NTSTATUS ejs_pull_string(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, const char **s)
+{
+       struct MprVar *var;
+       var = mprGetVar(v, name);
+       if (var == NULL) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+       *s = mprToString(var);
+       return NT_STATUS_OK;
+}
+
+/*
+  push a string
+*/
+NTSTATUS ejs_push_string(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, const char *s)
+{
+       return mprSetVar(v, name, mprCreateStringVar(s, True));
+}
index 1febb90ad6994051f6f8fec9831b1296fe538570..5fb6ace8630e5a59b41fbd31d169459212ef04a1 100644 (file)
@@ -21,7 +21,8 @@
 */
 
 struct ejs_rpc {
-
+       int eid;
+       const char *callname;
 };
 
 typedef NTSTATUS (*ejs_pull_t)(struct ejs_rpc *, struct MprVar *, const char *, void *);
@@ -29,11 +30,13 @@ typedef NTSTATUS (*ejs_push_t)(struct ejs_rpc *, struct MprVar *, const char *,
 typedef NTSTATUS (*ejs_pull_function_t)(struct ejs_rpc *, struct MprVar *, void *);
 typedef NTSTATUS (*ejs_push_function_t)(struct ejs_rpc *, struct MprVar *, const void *);
 
+NTSTATUS ejs_panic(struct ejs_rpc *ejs, const char *why);
+
 int ejs_rpc_call(int eid, int argc, struct MprVar **argv, const char *callname,
                 ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push);
 
-NTSTATUS ejs_pull_rpc(struct MprVar *v, void *ptr, ejs_pull_function_t ejs_pull);
-NTSTATUS ejs_push_rpc(struct MprVar *v, const void *ptr, ejs_push_function_t ejs_push);
+NTSTATUS ejs_pull_rpc(int eid, const char *callname, struct MprVar *v, void *ptr, ejs_pull_function_t ejs_pull);
+NTSTATUS ejs_push_rpc(int eid, const char *callname, struct MprVar *v, const void *ptr, ejs_push_function_t ejs_push);
 NTSTATUS ejs_pull_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name);
 NTSTATUS ejs_push_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name);
 
@@ -63,4 +66,7 @@ NTSTATUS ejs_pull_array(struct ejs_rpc *ejs,
 NTSTATUS ejs_push_array(struct ejs_rpc *ejs, 
                        struct MprVar *v, const char *name, uint32_t length,
                        size_t elsize, void *r, ejs_push_t ejs_push);
-
+NTSTATUS ejs_pull_string(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, const char **s);
+NTSTATUS ejs_push_string(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, const char *s);
index 631f1c3a37484b43af48ce90ec7f975687bf0591..00675165ea251be16e01bfd3f2fdeade108a97c1 100644 (file)
@@ -128,7 +128,7 @@ done:
        }
 
        /* convert the mpr object into a C structure */
-       status = ejs_pull_rpc(io, ptr, ejs_pull);
+       status = ejs_pull_rpc(eid, callname, io, ptr, ejs_pull);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
@@ -152,7 +152,7 @@ done:
                ndr_print_function_debug(call->ndr_print, call->name, NDR_OUT, ptr);
        }
 
-       status = ejs_push_rpc(io, ptr, ejs_push);
+       status = ejs_push_rpc(eid, callname, io, ptr, ejs_push);
 
        talloc_free(ptr);
 done: