297d4e3248aaaa43292fc01f21f3ccdaa513ad7f
[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         return NT_STATUS_OK;    
48 }
49
50 static void $name\_op_unbind(struct dcesrv_connection *dce_conn, const struct dcesrv_interface *iface)
51 {
52         return; 
53 }
54
55 static NTSTATUS $name\_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
56 {
57         uint16 opnum = dce_call->pkt.u.request.opnum;
58
59         return $name\_dispatch_table[opnum](dce_call, mem_ctx, r);      
60 }
61
62 static const struct dcesrv_interface $name\_interface = {
63         &dcerpc_table_$name,
64         $name\_op_bind,
65         $name\_op_unbind,
66         $name\_op_dispatch
67 };
68
69 ";
70 }
71
72 #####################################################################
73 # produce boilerplate code for an endpoint server
74 sub Boilerplate_Ep_Server($)
75 {
76         my($interface) = shift;
77         my($data) = $interface->{DATA};
78         my $count = 0;
79         my $name = $interface->{NAME};
80         my $uname = uc $name;
81
82         foreach my $d (@{$data}) {
83                 if ($d->{TYPE} eq "FUNCTION") { $count++; }
84         }
85
86         if ($count == 0) {
87                 return;
88         }
89
90         pidl "
91 static NTSTATUS $name\_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
92 {
93         int i;
94
95         for (i=0;i<$name\_interface.ndr->endpoints->count;i++) {
96                 NTSTATUS ret;
97                 const char *name = $name\_interface.ndr->endpoints->names[i];
98
99                 ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL);
100                 if (!NT_STATUS_IS_OK(ret)) {
101                         DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name));
102                         return ret;
103                 }
104         }
105
106         return NT_STATUS_OK;
107 }
108
109 static BOOL $name\_op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32 if_version)
110 {
111         if ($name\_interface.ndr->if_version == if_version &&
112                 strcmp($name\_interface.ndr->uuid, uuid)==0) {
113                 memcpy(iface,&$name\_interface, sizeof(*iface));
114                 return True;
115         }
116
117         return False;
118 }
119
120 static BOOL $name\_op_interface_by_name(struct dcesrv_interface *iface, const char *name)
121 {
122         if (strcmp($name\_interface.ndr->name, name)==0) {
123                 memcpy(iface,&$name\_interface, sizeof(*iface));
124                 return True;
125         }
126
127         return False;   
128 }
129         
130 NTSTATUS dcerpc_$name\_init(void)
131 {
132         NTSTATUS ret;
133         struct dcesrv_endpoint_server ep_server;
134
135         /* fill in our name */
136         ep_server.name = \"$name\";
137
138         /* fill in all the operations */
139         ep_server.init_server = $name\_op_init_server;
140
141         ep_server.interface_by_uuid = $name\_op_interface_by_uuid;
142         ep_server.interface_by_name = $name\_op_interface_by_name;
143
144         /* register ourselves with the DCERPC subsystem. */
145         ret = register_backend(\"dcerpc\", &ep_server);
146
147         if (!NT_STATUS_IS_OK(ret)) {
148                 DEBUG(0,(\"Failed to register \'$name\' endpoint server!\\n\"));
149                 return ret;
150         }
151
152         return ret;
153 }
154
155 ";
156 }
157
158
159 #####################################################################
160 # parse a parsed IDL structure back into an IDL file
161 sub Parse($)
162 {
163         my($idl) = shift;
164         $res = "/* dcerpc server boilerplate generated by pidl */\n\n";
165         foreach my $x (@{$idl}) {
166                 if ($x->{TYPE} eq "INTERFACE") { 
167                         Boilerplate_Iface($x);
168                         Boilerplate_Ep_Server($x);
169                 }
170         }
171
172         return $res;
173 }
174
175 1;
176