1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

r3790: use a registration function that is called from dcerpc_*_init functions

rather then a large table in librpc/gen_ndr/tables.c. This will allow us
to only link in only the required gen_ndr files (speeds up linking quite a
bit, makes binaries smaller).

Each gen_ndr_* file now has a init function that calls the init functions
of the interfaces it contains. I did it this way to keep pidl's code simple,
though it might hurt startup time a bit. I'd be happy to change it if
people like one function better.
(This used to be commit 3c436590ae)
This commit is contained in:
Jelmer Vernooij 2004-11-16 21:07:08 +00:00 committed by Gerald (Jerry) Carter
parent 83d29e9bac
commit 46badf1908
14 changed files with 168 additions and 210 deletions

View File

@ -1480,9 +1480,7 @@ sub FunctionTable($)
if ($d->{TYPE} eq "FUNCTION") { $count++; }
}
if ($count == 0) {
return;
}
return if ($count == 0);
pidl "static const struct dcerpc_interface_call $interface->{NAME}\_calls[] = {\n";
foreach my $d (@{$data}) {
@ -1525,8 +1523,12 @@ sub FunctionTable($)
pidl "\t$interface->{NAME}\_calls,\n";
pidl "\t&$interface->{NAME}\_endpoints\n";
pidl "};\n\n";
}
pidl "static NTSTATUS dcerpc_ndr_$interface->{NAME}_init(void)\n";
pidl "{\n";
pidl "\treturn librpc_register_interface(&dcerpc_table_$interface->{NAME});\n";
pidl "}\n\n";
}
#####################################################################
# parse the interface definitions
@ -1570,7 +1572,43 @@ sub ParseInterface($)
}
FunctionTable($interface);
}
sub RegistrationFunction($$)
{
my $idl = shift;
my $filename = shift;
$filename =~ /.*\/ndr_(.*).c/;
my $basename = $1;
pidl "NTSTATUS dcerpc_$basename\_init(void)\n";
pidl "{\n";
pidl "\tNTSTATUS status = NT_STATUS_OK;\n";
foreach my $interface (@{$idl}) {
next if $interface->{TYPE} ne "INTERFACE";
my $data = $interface->{INHERITED_DATA};
my $count = 0;
foreach my $d (@{$data}) {
if ($d->{TYPE} eq "FUNCTION") { $count++; }
}
next if ($count == 0);
pidl "\tstatus = dcerpc_ndr_$interface->{NAME}_init();\n";
pidl "\tif (NT_STATUS_IS_ERR(status)) {\n";
pidl "\t\treturn status;\n";
pidl "\t}\n\n";
if (util::has_property($interface, "object")) {
pidl "\tstatus = dcom_$interface->{NAME}_init();\n";
pidl "\tif (NT_STATUS_IS_ERR(status)) {\n";
pidl "\t\treturn status;\n";
pidl "\t}\n\n";
}
}
pidl "\treturn status;\n";
pidl "}\n\n";
}
#####################################################################
@ -1604,6 +1642,8 @@ sub Parse($$)
}
}
RegistrationFunction($idl, $filename);
close(OUT);
}

View File

@ -37,7 +37,7 @@ sub ParseRegFunc($)
{
my $interface = shift;
$res .= "NTSTATUS dcom_$interface->{NAME}_init(void)
$res .= "static NTSTATUS dcom_$interface->{NAME}_init(void)
{
struct dcom_interface iface;
";

View File

@ -1,111 +0,0 @@
#!/usr/bin/perl -w
###################################################
# package to produce a table of all idl parsers
# Copyright tridge@samba.org 2003
# released under the GNU GPL
use strict;
use Getopt::Long;
use File::Basename;
my($opt_output);
my($opt_help) = 0;
#########################################
# display help text
sub ShowHelp()
{
print "
perl IDL table generator
Copyright (C) tridge\@samba.org
Usage: tables.pl [options] <idlfile>
Options:
--output OUTNAME put output in OUTNAME.*
\n";
exit(0);
}
# main program
GetOptions (
'help|h|?' => \$opt_help,
'output=s' => \$opt_output,
);
if ($opt_help) {
ShowHelp();
exit(0);
}
###################################
# add include lines to tables.c
sub process_include($)
{
my $name = shift;
print TABLEC "#include \"$name\"\n";
}
###################################
# extract table entries from 1 file
sub process_file($)
{
my $filename = shift;
open(FILE, $filename) || die "unable to open $filename\n";
while (my $line = <FILE>) {
if ($line =~ /extern const struct dcerpc_interface_table dcerpc_table_(\w+);/) {
print TABLEC "\t&dcerpc_table_$1,\n";
print TABLEH "NTSTATUS dcerpc_$1\_init(void);\n";
}
}
close(FILE);
}
print "Creating $opt_output.[ch]\n";
open(TABLEH, ">$opt_output.h") || die "failed to open $opt_output.h\n";
open(TABLEC, ">$opt_output.c") || die "failed to open $opt_output.c\n";
#include "includes.h"
#define NDR_BASE_MARSHALL_SIZE 1024
print TABLEC "
#include \"includes.h\"
";
foreach my $filename (@ARGV) {
process_include($filename);
}
print TABLEC "
/*
generated by pidl IDL table generator
*/
const struct dcerpc_interface_table * const dcerpc_pipes[] = {
";
print TABLEH "
/*
table headers generated by pidl IDL table generator
*/
extern const struct dcerpc_interface_table * const dcerpc_pipes[];
";
foreach my $filename (@ARGV) {
process_file($filename);
}
print TABLEC "\tNULL\n};\n";
close(TABLEH);
close(TABLEC);

View File

@ -32,10 +32,50 @@ REQUIRED_SUBSYSTEMS = SOCKET
################################################
# Start SUBSYSTEM LIBNDR_GEN
[SUBSYSTEM::LIBNDR_GEN]
INIT_FUNCTION = \
dcerpc_audiosrv_init \
dcerpc_dcerpc_init \
dcerpc_echo_init \
dcerpc_exchange_init \
dcerpc_dsbackup_init \
dcerpc_efs_init \
dcerpc_misc_init \
dcerpc_lsa_init \
dcerpc_lsads_init \
dcerpc_dfs_init \
dcerpc_drsuapi_init \
dcerpc_policyagent_init \
dcerpc_samr_init \
dcerpc_spoolss_init \
dcerpc_wkssvc_init \
dcerpc_srvsvc_init \
dcerpc_svcctl_init \
dcerpc_atsvc_init \
dcerpc_eventlog_init \
dcerpc_epmapper_init \
dcerpc_dbgidl_init \
dcerpc_dssetup_init \
dcerpc_msgsvc_init \
dcerpc_wins_init \
dcerpc_winreg_init \
dcerpc_mgmt_init \
dcerpc_protected_storage_init \
dcerpc_dcom_init \
dcerpc_oxidresolver_init \
dcerpc_remact_init \
dcerpc_wzcsvc_init \
dcerpc_browser_init \
dcerpc_w32time_init \
dcerpc_scerpc_init \
dcerpc_ntsvcs_init \
dcerpc_netlogon_init \
dcerpc_trkwks_init \
dcerpc_keysvc_init \
dcerpc_krb5pac_init \
dcerpc_xattr_init \
dcerpc_schannel_init
NOPROTO = YES
INIT_FUNCTION = librpc_init
INIT_OBJ_FILES = \
librpc/gen_ndr/tables.o
ADD_OBJ_FILES = \
librpc/gen_ndr/ndr_audiosrv.o \
librpc/gen_ndr/ndr_dcerpc.o \

View File

@ -24,9 +24,20 @@
#include "dlinklist.h"
#include "librpc/gen_ndr/ndr_epmapper.h"
NTSTATUS librpc_init(void)
struct dcerpc_interface_list *dcerpc_pipes = NULL;
NTSTATUS librpc_register_interface (const struct dcerpc_interface_table *interface)
{
/* FIXME: Register module registration function here */
struct dcerpc_interface_list *l = talloc_p(NULL, struct dcerpc_interface_list);
if (idl_iface_by_name (interface->name) != NULL) {
DEBUG(0, ("Attempt to register interface %s twice\n", interface->name));
return NT_STATUS_OBJECT_NAME_COLLISION;
}
l->table = interface;
DLIST_ADD(dcerpc_pipes, l);
return NT_STATUS_OK;
}

View File

@ -141,6 +141,14 @@ struct dcerpc_interface_table {
const struct dcerpc_endpoint_list *endpoints;
};
struct dcerpc_interface_list
{
struct dcerpc_interface_list *prev, *next;
const struct dcerpc_interface_table *table;
};
extern struct dcerpc_interface_list *dcerpc_pipes;
/* this describes a binding to a particular transport/pipe */
struct dcerpc_binding {

View File

@ -24,18 +24,17 @@
#include "includes.h"
#include "system/network.h"
#include "librpc/gen_ndr/ndr_epmapper.h"
#include "librpc/gen_ndr/tables.h"
/*
find the pipe name for a local IDL interface
*/
const char *idl_pipe_name(const char *uuid, uint32_t if_version)
{
int i;
for (i=0;dcerpc_pipes[i];i++) {
if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0 &&
dcerpc_pipes[i]->if_version == if_version) {
return dcerpc_pipes[i]->name;
struct dcerpc_interface_list *l;
for (l=dcerpc_pipes;l;l=l->next) {
if (strcasecmp(l->table->uuid, uuid) == 0 &&
l->table->if_version == if_version) {
return l->table->name;
}
}
return "UNKNOWN";
@ -46,11 +45,11 @@ const char *idl_pipe_name(const char *uuid, uint32_t if_version)
*/
int idl_num_calls(const char *uuid, uint32_t if_version)
{
int i;
for (i=0;dcerpc_pipes[i];i++) {
if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0 &&
dcerpc_pipes[i]->if_version == if_version) {
return dcerpc_pipes[i]->num_calls;
struct dcerpc_interface_list *l;
for (l=dcerpc_pipes;l;l=l->next){
if (strcasecmp(l->table->uuid, uuid) == 0 &&
l->table->if_version == if_version) {
return l->table->num_calls;
}
}
return -1;
@ -62,10 +61,10 @@ int idl_num_calls(const char *uuid, uint32_t if_version)
*/
const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
{
int i;
for (i=0;dcerpc_pipes[i];i++) {
if (strcasecmp(dcerpc_pipes[i]->name, name) == 0) {
return dcerpc_pipes[i];
struct dcerpc_interface_list *l;
for (l=dcerpc_pipes;l;l=l->next) {
if (strcasecmp(l->table->name, name) == 0) {
return l->table;
}
}
return NULL;
@ -76,17 +75,16 @@ const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
*/
const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
{
int i;
for (i=0;dcerpc_pipes[i];i++) {
if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0) {
return dcerpc_pipes[i];
struct dcerpc_interface_list *l;
for (l=dcerpc_pipes;l;l=l->next) {
if (strcasecmp(l->table->uuid, uuid) == 0) {
return l->table;
}
}
return NULL;
}
/*
push a dcerpc_packet into a blob, potentially with auth info
*/

View File

@ -24,7 +24,6 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_epmapper.h"
#include "librpc/gen_ndr/ndr_oxidresolver.h"
#include "librpc/gen_ndr/tables.h"
#include "auth/auth.h"
#include "dlinklist.h"
#include "rpc_server/dcerpc_server.h"

View File

@ -21,7 +21,6 @@
#include "includes.h"
#include "rpc_server/dcerpc_server.h"
#include "librpc/gen_ndr/tables.h"
struct dcesrv_remote_private {
struct dcerpc_pipe *c_pipe;
@ -158,12 +157,12 @@ static BOOL remote_fill_interface(struct dcesrv_interface *iface, const struct d
static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32_t if_version)
{
int i;
struct dcerpc_interface_list *l;
for (i=0;dcerpc_pipes[i];i++) {
if (dcerpc_pipes[i]->if_version == if_version &&
strcmp(dcerpc_pipes[i]->uuid, uuid)==0) {
return remote_fill_interface(iface, dcerpc_pipes[i]);
for (l=dcerpc_pipes;l;l=l->next) {
if (l->table->if_version == if_version &&
strcmp(l->table->uuid, uuid)==0) {
return remote_fill_interface(iface, l->table);
}
}
@ -172,11 +171,11 @@ static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const ch
static BOOL remote_op_interface_by_name(struct dcesrv_interface *iface, const char *name)
{
int i;
struct dcerpc_interface_list *l;
for (i=0;dcerpc_pipes[i];i++) {
if (strcmp(dcerpc_pipes[i]->name, name)==0) {
return remote_fill_interface(iface, dcerpc_pipes[i]);
for (l=dcerpc_pipes;l;l=l->next) {
if (strcmp(l->table->name, name)==0) {
return remote_fill_interface(iface, l->table);
}
}

View File

@ -6,14 +6,10 @@ FULLBUILD=$1
PIDL="$PERL ./build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server"
EPARSERPIDL="$PERL ./build/pidl/pidl.pl --output $EPARSERPREFIX/ndr_ --parse --header --eparser"
TABLES="$PERL ./build/pidl/tables.pl --output librpc/gen_ndr/tables"
if [ x$FULLBUILD = xFULL ]; then
echo Rebuilding all idl files in librpc/idl
$PIDL librpc/idl/*.idl || exit 1
echo Rebuilding IDL tables
$TABLES librpc/gen_ndr/ndr_*.h || exit 1
exit 0
fi
@ -40,7 +36,6 @@ done
if [ "x$list" != x ]; then
$PIDL $list || exit 1
$TABLES librpc/gen_ndr/ndr_*.h || exit 1
fi
exit 0

View File

@ -47,9 +47,6 @@ BOOL torture_dcom_simple(void)
mem_ctx = talloc_init("torture_dcom_simple");
dcom_IUnknown_init();
dcom_IStream_init();
dcom_init(&ctx, lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "password"));

View File

@ -21,7 +21,6 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_mgmt.h"
#include "librpc/gen_ndr/tables.h"
/*
@ -180,8 +179,8 @@ BOOL torture_rpc_mgmt(void)
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
int i;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_interface_list *l;
struct dcerpc_binding b;
mem_ctx = talloc_init("torture_rpc_mgmt");
@ -197,31 +196,31 @@ BOOL torture_rpc_mgmt(void)
return False;
}
for (i=0;dcerpc_pipes[i];i++) {
for (l=dcerpc_pipes;l;l=l->next) {
/* some interfaces are not mappable */
if (dcerpc_pipes[i]->num_calls == 0 ||
strcmp(dcerpc_pipes[i]->name, "mgmt") == 0) {
if (l->table->num_calls == 0 ||
strcmp(l->table->name, "mgmt") == 0) {
continue;
}
printf("\nTesting pipe '%s'\n", dcerpc_pipes[i]->name);
printf("\nTesting pipe '%s'\n", l->table->name);
if (b.transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, &b,
dcerpc_pipes[i]->uuid,
dcerpc_pipes[i]->if_version);
l->table->uuid,
l->table->if_version);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to map port for uuid %s\n", dcerpc_pipes[i]->uuid);
printf("Failed to map port for uuid %s\n", l->table->uuid);
continue;
}
} else {
b.endpoint = dcerpc_pipes[i]->name;
b.endpoint = l->table->name;
}
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
status = torture_rpc_connection(&p,
dcerpc_pipes[i]->name,
l->table->name,
DCERPC_MGMT_UUID,
DCERPC_MGMT_VERSION);
if (!NT_STATUS_IS_OK(status)) {

View File

@ -22,7 +22,6 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_mgmt.h"
#include "librpc/gen_ndr/tables.h"
/*
work out how many calls there are for an interface
@ -135,7 +134,7 @@ BOOL torture_rpc_scanner(void)
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
int i;
struct dcerpc_interface_list *l;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
@ -152,31 +151,31 @@ BOOL torture_rpc_scanner(void)
return False;
}
for (i=0;dcerpc_pipes[i];i++) {
for (l=dcerpc_pipes;l;l=l->next) {
/* some interfaces are not mappable */
if (dcerpc_pipes[i]->num_calls == 0 ||
strcmp(dcerpc_pipes[i]->name, "mgmt") == 0) {
if (l->table->num_calls == 0 ||
strcmp(l->table->name, "mgmt") == 0) {
continue;
}
printf("\nTesting pipe '%s'\n", dcerpc_pipes[i]->name);
printf("\nTesting pipe '%s'\n", l->table->name);
if (b.transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, &b,
dcerpc_pipes[i]->uuid,
dcerpc_pipes[i]->if_version);
l->table->uuid,
l->table->if_version);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to map port for uuid %s\n", dcerpc_pipes[i]->uuid);
printf("Failed to map port for uuid %s\n", l->table->uuid);
continue;
}
} else {
b.endpoint = dcerpc_pipes[i]->name;
b.endpoint = l->table->name;
}
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
status = torture_rpc_connection(&p,
dcerpc_pipes[i]->name,
l->table->name,
DCERPC_MGMT_UUID,
DCERPC_MGMT_VERSION);
if (!NT_STATUS_IS_OK(status)) {
@ -184,7 +183,7 @@ BOOL torture_rpc_scanner(void)
continue;
}
if (!test_inq_if_ids(p, mem_ctx, dcerpc_pipes[i])) {
if (!test_inq_if_ids(p, mem_ctx, l->table)) {
ret = False;
}

View File

@ -21,22 +21,6 @@
#include "includes.h"
#include "lib/cmdline/popt_common.h"
#include "system/iconv.h"
#include "librpc/gen_ndr/tables.h"
static const struct dcerpc_interface_table *find_pipe(const char *pipe_name)
{
int i;
for (i=0;dcerpc_pipes[i];i++) {
if (strcmp(dcerpc_pipes[i]->name, pipe_name) == 0) {
break;
}
}
if (!dcerpc_pipes[i]) {
printf("pipe '%s' not in table\n", pipe_name);
exit(1);
}
return dcerpc_pipes[i];
}
static const struct dcerpc_interface_call *find_function(
const struct dcerpc_interface_table *p,
@ -62,14 +46,14 @@ static const struct dcerpc_interface_call *find_function(
static void show_pipes(void)
{
int i;
struct dcerpc_interface_list *p;
printf("\nYou must specify a pipe\n");
printf("known pipes are:\n");
for (i=0;dcerpc_pipes[i];i++) {
if(dcerpc_pipes[i]->helpstring) {
printf("\t%s - %s\n", dcerpc_pipes[i]->name, dcerpc_pipes[i]->helpstring);
for (p=dcerpc_pipes;p;p=p->next) {
if(p->table->helpstring) {
printf("\t%s - %s\n", p->table->name, p->table->helpstring);
} else {
printf("\t%s\n", dcerpc_pipes[i]->name);
printf("\t%s\n", p->table->name);
}
}
exit(1);
@ -109,12 +93,12 @@ static void show_functions(const struct dcerpc_interface_table *p)
POPT_TABLEEND
};
ndrdump_init_subsystems;
DEBUGLEVEL = 10;
setup_logging("ndrdump", DEBUG_STDOUT);
ndrdump_init_subsystems;
pc = poptGetContext("ndrdump", argc, argv, long_options, 0);
poptSetOtherOptionHelp(pc, "<pipe> <function> <inout> <filename>");
@ -130,7 +114,7 @@ static void show_functions(const struct dcerpc_interface_table *p)
exit(1);
}
p = find_pipe(pipe_name);
p = idl_iface_by_name(pipe_name);
function = poptGetArg(pc);
inout = poptGetArg(pc);