f8016b292346b0d890e87e72e24181d5028f6ffc
[samba.git] / source / build / pidl / server.pm
1 ###################################################
2 # server boilerplate generator
3 # Copyright tridge@samba.org 2003
4 # Copyright metze@samba.org 2004
5 # released under the GNU GPL
6
7 package IdlServer;
8
9 use strict;
10
11 my($res);
12
13 sub pidl($)
14 {
15         $res .= shift;
16 }
17
18 #####################################################################
19 # produce boilerplate code for a interface
20 sub Boilerplate_Iface($)
21 {
22         my($interface) = shift;
23         my($data) = $interface->{DATA};
24         my $count = 0;
25         my $name = $interface->{NAME};
26         my $uname = uc $name;
27
28         foreach my $d (@{$data}) {
29                 if ($d->{TYPE} eq "FUNCTION") { $count++; }
30         }
31
32         if ($count == 0) {
33                 return;
34         }
35
36         pidl "static const dcesrv_dispatch_fn_t $name\_dispatch_table[] = {\n";
37         foreach my $d (@{$data}) {
38                 if ($d->{TYPE} eq "FUNCTION") {
39                         pidl "\t(dcesrv_dispatch_fn_t)$d->{NAME},\n";
40                 }
41         }
42         pidl "\tNULL};\n\n";
43
44         pidl "
45 static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
46 {
47 #ifdef DCESRV_INTERFACE_$uname\_BIND
48         return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
49 #else
50         return NT_STATUS_OK;
51 #endif
52 }
53
54 static void $name\__op_unbind(struct dcesrv_connection *dce_conn, const struct dcesrv_interface *iface)
55 {
56 #ifdef DCESRV_INTERFACE_$uname\_UNBIND
57         DCESRV_INTERFACE_$uname\_UNBIND(dce_conn,iface);
58 #else
59         return;
60 #endif
61 }
62
63 static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
64 {
65         uint16 opnum = dce_call->pkt.u.request.opnum;
66
67         return $name\_dispatch_table[opnum](dce_call, mem_ctx, r);      
68 }
69
70 static const struct dcesrv_interface $name\_interface = {
71         &dcerpc_table_$name,
72         $name\__op_bind,
73         $name\__op_unbind,
74         $name\__op_dispatch
75 };
76
77 ";
78 }
79
80 #####################################################################
81 # produce boilerplate code for an endpoint server
82 sub Boilerplate_Ep_Server($)
83 {
84         my($interface) = shift;
85         my($data) = $interface->{DATA};
86         my $count = 0;
87         my $name = $interface->{NAME};
88         my $uname = uc $name;
89
90         foreach my $d (@{$data}) {
91                 if ($d->{TYPE} eq "FUNCTION") { $count++; }
92         }
93
94         if ($count == 0) {
95                 return;
96         }
97
98         pidl "
99 static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
100 {
101         int i;
102
103         for (i=0;i<$name\_interface.ndr->endpoints->count;i++) {
104                 NTSTATUS ret;
105                 const char *name = $name\_interface.ndr->endpoints->names[i];
106
107                 ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL);
108                 if (!NT_STATUS_IS_OK(ret)) {
109                         DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name));
110                         return ret;
111                 }
112         }
113
114         return NT_STATUS_OK;
115 }
116
117 static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32 if_version)
118 {
119         if ($name\_interface.ndr->if_version == if_version &&
120                 strcmp($name\_interface.ndr->uuid, uuid)==0) {
121                 memcpy(iface,&$name\_interface, sizeof(*iface));
122                 return True;
123         }
124
125         return False;
126 }
127
128 static BOOL $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name)
129 {
130         if (strcmp($name\_interface.ndr->name, name)==0) {
131                 memcpy(iface,&$name\_interface, sizeof(*iface));
132                 return True;
133         }
134
135         return False;   
136 }
137         
138 NTSTATUS dcerpc_$name\_init(void)
139 {
140         NTSTATUS ret;
141         struct dcesrv_endpoint_server ep_server;
142
143         /* fill in our name */
144         ep_server.name = \"$name\";
145
146         /* fill in all the operations */
147         ep_server.init_server = $name\__op_init_server;
148
149         ep_server.interface_by_uuid = $name\__op_interface_by_uuid;
150         ep_server.interface_by_name = $name\__op_interface_by_name;
151
152         /* register ourselves with the DCERPC subsystem. */
153         ret = register_backend(\"dcerpc\", &ep_server);
154
155         if (!NT_STATUS_IS_OK(ret)) {
156                 DEBUG(0,(\"Failed to register \'$name\' endpoint server!\\n\"));
157                 return ret;
158         }
159
160         return ret;
161 }
162
163 ";
164 }
165
166
167 #####################################################################
168 # parse a parsed IDL structure back into an IDL file
169 sub Parse($)
170 {
171         my($idl) = shift;
172         $res = "/* dcerpc server boilerplate generated by pidl */\n\n";
173         foreach my $x (@{$idl}) {
174                 if ($x->{TYPE} eq "INTERFACE") { 
175                         Boilerplate_Iface($x);
176                         Boilerplate_Ep_Server($x);
177                 }
178         }
179
180         return $res;
181 }
182
183 1;
184