summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2004-10-15 09:22:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:55 -0500
commitfe15b46d61ee50f4225458faf963c818cde3e283 (patch)
tree379b76701f6b9b20341953eae9f344c397ee7008 /source4
parent42c810cea660f59cae8c30b12a5419450e923a2b (diff)
downloadsamba-fe15b46d61ee50f4225458faf963c818cde3e283.tar.gz
samba-fe15b46d61ee50f4225458faf963c818cde3e283.tar.bz2
samba-fe15b46d61ee50f4225458faf963c818cde3e283.zip
r2990: Add support to pidl for autogenerating ndr_size_*() functions. Adding
the [gensize] property to a struct or union will make pidl generate a ndr_size_*() function. (not all nasty bits of NDR are completely covered yet by the ndr_size*() functions, support for those will be added when necessary) I also have a local patch (not applied now) that simplifies the pidl output and eliminates the number of functions required. It would, however, make pidl more complex. (This used to be commit 7c823f886afd0c4c6ee838f17882ca0658417011)
Diffstat (limited to 'source4')
-rw-r--r--source4/build/pidl/parser.pm130
-rw-r--r--source4/librpc/idl/epmapper.idl4
-rw-r--r--source4/librpc/ndr/libndr.h5
-rw-r--r--source4/librpc/ndr/ndr_basic.c12
-rw-r--r--source4/librpc/rpc/dcerpc_util.c52
5 files changed, 148 insertions, 55 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index bbebe50cac..7d7ee7a163 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -2,6 +2,7 @@
# Samba4 parser generator for IDL structures
# Copyright tridge@samba.org 2000-2003
# Copyright tpot@samba.org 2001
+# Copyright jelmer@samba.org 2004
# released under the GNU GPL
package IdlParser;
@@ -830,6 +831,65 @@ sub ParseStructPull($)
end_flags($struct);
}
+#####################################################################
+# calculate size of ndr struct
+
+sub ParseStructNdrSize($)
+{
+ my $t = shift;
+ my $static = fn_prefix($t);
+ my $sizevar;
+
+ pidl $static . "size_t ndr_size_$t->{NAME}(int ret, struct $t->{NAME} *r, int flags)\n";
+ pidl "{\n";
+
+ if (util::has_property($t->{DATA}, "flag")) {
+
+ pidl "\tflags = flags | " . $t->{DATA}->{PROPERTIES}->{flag} . ";\n";
+ }
+
+ pidl "\tif(!r) return 0;\n";
+
+ pidl "\tret = NDR_SIZE_ALIGN(ret, " . struct_alignment($t->{DATA}) . ", flags);\n";
+
+ for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+ my $switch = "";
+
+ if (util::has_property($e, "subcontext")) {
+ pidl "\tret += $e->{PROPERTIES}->{subcontext}; /* Subcontext length */\n";
+ }
+
+ if (util::has_property($e, "switch_is")) {
+ $switch = ", r->$e->{PROPERTIES}->{switch_is}";
+ }
+
+ if ($e->{POINTERS} > 0) {
+ pidl "\tret = ndr_size_ptr(ret, &r->$e->{NAME}, flags); \n";
+ } elsif (util::is_inline_array($e)) {
+ $sizevar = find_size_var($e, util::array_size($e), "r->");
+ pidl "\t{\n";
+ pidl "\t\tint i;\n";
+ pidl "\t\tfor(i = 0; i < $sizevar; i++) {\n";
+ pidl "\t\t\tret = ndr_size_$e->{TYPE}(ret, &r->" . $e->{NAME} . "[i], flags);\n";
+ pidl "\t\t}\n";
+ pidl "\t}\n";
+ } else {
+ pidl "\tret = ndr_size_$e->{TYPE}(ret, &r->$e->{NAME}$switch, flags); \n";
+ }
+ }
+
+ # Add lengths of relative members
+ for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+ next unless (util::has_property($e, "relative"));
+
+ pidl "\tif (r->$e->{NAME}) {\n";
+ pidl "\t\tret = ndr_size_$e->{TYPE}(ret, r->$e->{NAME}, flags); \n";
+ pidl "\t}\n";
+ }
+
+ pidl "\treturn ret;\n";
+ pidl "}\n\n";
+}
#####################################################################
# parse a union - push side
@@ -982,6 +1042,43 @@ sub ParseUnionPull($)
}
#####################################################################
+# calculate size of ndr union
+
+sub ParseUnionNdrSize($)
+{
+ my $t = shift;
+ my $static = fn_prefix($t);
+
+ pidl $static . "size_t ndr_size_$t->{NAME}(int ret, union $t->{NAME} *data, uint16 level, int flags)\n";
+ pidl "{\n";
+ if (util::has_property($t->{DATA}, "flag")) {
+ pidl "\tflags = flags | " . $t->{DATA}->{PROPERTIES}->{flag} . ";\n";
+ }
+ pidl "\tif(!data) return 0;\n\n";
+
+ pidl "\tret = NDR_SIZE_ALIGN(ret, " . union_alignment($t->{DATA}) . ", flags);\n";
+
+ pidl "\tswitch(level) {\n";
+
+ for my $e (@{$t->{DATA}->{DATA}}) {
+ if ($e->{TYPE} eq "UNION_ELEMENT") {
+
+ if ($e->{CASE} eq "default") {
+ pidl "\t\tdefault:";
+ } else {
+ pidl "\t\tcase $e->{CASE}:";
+ }
+
+ pidl " return ndr_size_$e->{DATA}->{TYPE}(ret, &data->$e->{DATA}->{NAME}, flags); \n";
+
+ }
+ }
+ pidl "\t}\n";
+ pidl "\treturn ret;\n";
+ pidl "}\n\n";
+}
+
+#####################################################################
# parse a type
sub ParseTypePush($)
{
@@ -1107,6 +1204,23 @@ sub ParseTypedefPrint($)
}
#####################################################################
+## calculate the size of a structure
+sub ParseTypedefNdrSize($)
+{
+ my($t) = shift;
+ if (! $needed{"ndr_size_$t->{NAME}"}) {
+ return;
+ }
+
+ ($t->{DATA}->{TYPE} eq "STRUCT") &&
+ ParseStructNdrSize($t);
+
+ ($t->{DATA}->{TYPE} eq "UNION") &&
+ ParseUnionNdrSize($t);
+
+}
+
+#####################################################################
# parse a function - print side
sub ParseFunctionPrint($)
{
@@ -1413,7 +1527,10 @@ sub ParseInterface($)
}
}
-
+ foreach my $d (@{$data}) {
+ ($d->{TYPE} eq "TYPEDEF") &&
+ ParseTypedefNdrSize($d);
+ }
foreach my $d (@{$data}) {
($d->{TYPE} eq "TYPEDEF") &&
@@ -1461,7 +1578,12 @@ sub NeededTypedef($)
$needed{"pull_$t->{NAME}"} = 1;
$needed{"push_$t->{NAME}"} = 1;
}
+
if ($t->{DATA}->{TYPE} eq "STRUCT") {
+ if (util::has_property($t->{DATA}, "gensize")) {
+ $needed{"ndr_size_$t->{NAME}"} = 1;
+ }
+
for my $e (@{$t->{DATA}->{ELEMENTS}}) {
$e->{PARENT} = $t->{DATA};
if ($needed{"pull_$t->{NAME}"}) {
@@ -1470,6 +1592,9 @@ sub NeededTypedef($)
if ($needed{"push_$t->{NAME}"}) {
$needed{"push_$e->{TYPE}"} = 1;
}
+ if ($needed{"ndr_size_$t->{NAME}"}) {
+ $needed{"ndr_size_$e->{TYPE}"} = 1;
+ }
}
}
if ($t->{DATA}->{TYPE} eq "UNION") {
@@ -1482,6 +1607,9 @@ sub NeededTypedef($)
if ($needed{"push_$t->{NAME}"}) {
$needed{"push_$e->{DATA}->{TYPE}"} = 1;
}
+ if ($needed{"ndr_size_$t->{NAME}"}) {
+ $needed{"ndr_size_$e->{DATA}->{TYPE}"} = 1;
+ }
}
}
}
diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl
index 7ea58e354f..18bb6bf7d7 100644
--- a/source4/librpc/idl/epmapper.idl
+++ b/source4/librpc/idl/epmapper.idl
@@ -193,8 +193,8 @@ interface epmapper
epm_floor floors[num_floors];
} epm_towers;
- typedef struct {
- [value(ndr_size_epm_towers(&r->towers))] uint32 tower_length;
+ typedef [gensize] struct {
+ [value(ndr_size_epm_towers(0, &r->towers,ndr->flags))] uint32 tower_length;
[subcontext(4)] epm_towers towers;
} epm_twr_t;
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 59e8b744df..306e480c98 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -188,6 +188,11 @@ enum ndr_err_code {
} \
} while(0)
+#define NDR_SIZE_ALIGN(t, n, flags) ((flags & LIBNDR_FLAG_NOALIGN)?(t):(((t) + (n-1)) & ~(n-1)))
+#define ndr_size_uint8(t, p, flags) (NDR_SIZE_ALIGN(t, 1, flags) + 1)
+#define ndr_size_uint16(t, p, flags) (NDR_SIZE_ALIGN(t, 2, flags) + 2)
+#define ndr_size_uint32(t, p, flags) (NDR_SIZE_ALIGN(t, 4, flags) + 4)
+#define ndr_size_ptr(t, p, flags) (NDR_SIZE_ALIGN(t, 4, flags) + 4)
/* these are used to make the error checking on each element in libndr
less tedious, hopefully making the code more readable */
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index edb1590489..5808ae7452 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -1130,3 +1130,15 @@ NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
ndr->offset += length;
return NT_STATUS_OK;
}
+
+uint32 ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
+{
+ return ret + data->length;
+}
+
+uint32 ndr_size_string(int ret, const char **string, int flags)
+{
+ /* FIXME: Is this correct for all strings ? */
+ if(!(*string)) return ret;
+ return ret+strlen(*string)+1;
+}
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index fad8417c3f..5f3d911d15 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -23,58 +23,6 @@
#include "includes.h"
/*
- this ndr_size_* stuff should really be auto-generated ....
-*/
-
-static size_t ndr_size_epm_floor(struct epm_floor *fl)
-{
- size_t ret = 5;
- if (fl->lhs.protocol == EPM_PROTOCOL_UUID) {
- ret += 18;
- } else {
- ret += fl->lhs.info.lhs_data.length;
- }
- switch (fl->lhs.protocol) {
- case EPM_PROTOCOL_TCP:
- case EPM_PROTOCOL_UDP:
- case EPM_PROTOCOL_HTTP:
- case EPM_PROTOCOL_UUID:
- ret += 2;
- break;
- case EPM_PROTOCOL_IP:
- ret += 4;
- break;
- case EPM_PROTOCOL_NCADG:
- case EPM_PROTOCOL_NCACN:
- case EPM_PROTOCOL_NCALRPC:
- ret += 2;
- break;
-
- case EPM_PROTOCOL_SMB:
- ret += strlen(fl->rhs.smb.unc)+1;
- break;
- case EPM_PROTOCOL_PIPE:
- ret += strlen(fl->rhs.pipe.path)+1;
- break;
- case EPM_PROTOCOL_NETBIOS:
- ret += strlen(fl->rhs.netbios.name)+1;
- break;
- }
-
- return ret;
-}
-
-size_t ndr_size_epm_towers(struct epm_towers *towers)
-{
- size_t ret = 2;
- int i;
- for (i=0;i<towers->num_floors;i++) {
- ret += ndr_size_epm_floor(&towers->floors[i]);
- }
- return ret;
-}
-
-/*
work out what TCP port to use for a given interface on a given host
*/
NTSTATUS dcerpc_epm_map_tcp_port(const char *server,