Auto-generate ChangeLog.
[ocaml-libvirt.git] / libvirt / libvirt_c_epilogue.c
1 /* OCaml bindings for libvirt.
2  * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
3  * http://libvirt.org/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18  */
19
20 /* Please read libvirt/README file. */
21
22 static char *
23 Optstring_val (value strv)
24 {
25   if (strv == Val_int (0))      /* None */
26     return NULL;
27   else                          /* Some string */
28     return String_val (Field (strv, 0));
29 }
30
31 static value
32 Val_opt (void *ptr, Val_ptr_t Val_ptr)
33 {
34   CAMLparam0 ();
35   CAMLlocal2 (optv, ptrv);
36
37   if (ptr) {                    /* Some ptr */
38     optv = caml_alloc (1, 0);
39     ptrv = Val_ptr (ptr);
40     Store_field (optv, 0, ptrv);
41   } else                        /* None */
42     optv = Val_int (0);
43
44   CAMLreturn (optv);
45 }
46
47 #if 0
48 static value
49 option_default (value option, value deflt)
50 {
51   if (option == Val_int (0))    /* "None" */
52     return deflt;
53   else                          /* "Some 'a" */
54     return Field (option, 0);
55 }
56 #endif
57
58 static void
59 _raise_virterror (virConnectPtr conn, const char *fn)
60 {
61   CAMLparam0 ();
62   CAMLlocal1 (rv);
63   virErrorPtr errp;
64   struct _virError err;
65
66   errp = conn ? virConnGetLastError (conn) : virGetLastError ();
67
68   if (!errp) {
69     /* Fake a _virError structure. */
70     memset (&err, 0, sizeof err);
71     err.code = VIR_ERR_INTERNAL_ERROR;
72     err.domain = VIR_FROM_NONE;
73     err.level = VIR_ERR_ERROR;
74     err.message = (char *) fn;
75     errp = &err;
76   }
77
78   rv = Val_virterror (errp);
79   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
80
81   /*NOTREACHED*/
82   /* Suppresses a compiler warning. */
83   (void) caml__frame;
84 }
85
86 /* Raise an error if a function is not supported. */
87 static void
88 not_supported (const char *fn)
89 {
90   CAMLparam0 ();
91   CAMLlocal1 (fnv);
92
93   fnv = caml_copy_string (fn);
94   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
95
96   /*NOTREACHED*/
97   /* Suppresses a compiler warning. */
98   (void) caml__frame;
99 }
100
101 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
102  * into values (longs because they are variants in OCaml).
103  *
104  * The enum values are part of the libvirt ABI so they cannot change,
105  * which means that we can convert these numbers directly into
106  * OCaml variants (which use the same ordering) very fast.
107  *
108  * The tricky part here is when we are linked to a newer version of
109  * libvirt than the one we were compiled against.  If the newer libvirt
110  * generates an error code which we don't know about then we need
111  * to convert it into VIR_*_UNKNOWN (code).
112  */
113
114 #define MAX_VIR_CODE 50 /* VIR_ERR_NO_STORAGE_VOL */
115 #define MAX_VIR_DOMAIN 17 /* VIR_FROM_STORAGE */
116 #define MAX_VIR_LEVEL VIR_ERR_ERROR
117
118 static inline value
119 Val_err_number (virErrorNumber code)
120 {
121   CAMLparam0 ();
122   CAMLlocal1 (rv);
123
124   if (0 <= code && code <= MAX_VIR_CODE)
125     rv = Val_int (code);
126   else {
127     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN (code) */
128     Store_field (rv, 0, Val_int (code));
129   }
130
131   CAMLreturn (rv);
132 }
133
134 static inline value
135 Val_err_domain (virErrorDomain code)
136 {
137   CAMLparam0 ();
138   CAMLlocal1 (rv);
139
140   if (0 <= code && code <= MAX_VIR_DOMAIN)
141     rv = Val_int (code);
142   else {
143     rv = caml_alloc (1, 0);     /* VIR_FROM_UNKNOWN (code) */
144     Store_field (rv, 0, Val_int (code));
145   }
146
147   CAMLreturn (rv);
148 }
149
150 static inline value
151 Val_err_level (virErrorLevel code)
152 {
153   CAMLparam0 ();
154   CAMLlocal1 (rv);
155
156   if (0 <= code && code <= MAX_VIR_LEVEL)
157     rv = Val_int (code);
158   else {
159     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN_LEVEL (code) */
160     Store_field (rv, 0, Val_int (code));
161   }
162
163   CAMLreturn (rv);
164 }
165
166 /* Convert a virterror to a value. */
167 static value
168 Val_virterror (virErrorPtr err)
169 {
170   CAMLparam0 ();
171   CAMLlocal3 (rv, connv, optv);
172
173   rv = caml_alloc (9, 0);
174   Store_field (rv, 0, Val_err_number (err->code));
175   Store_field (rv, 1, Val_err_domain (err->domain));
176   Store_field (rv, 2,
177                Val_opt (err->message, (Val_ptr_t) caml_copy_string));
178   Store_field (rv, 3, Val_err_level (err->level));
179
180   Store_field (rv, 4,
181                Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
182   Store_field (rv, 5,
183                Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
184   Store_field (rv, 6,
185                Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
186   Store_field (rv, 7, caml_copy_int32 (err->int1));
187   Store_field (rv, 8, caml_copy_int32 (err->int2));
188
189   CAMLreturn (rv);
190 }
191
192 static void conn_finalize (value);
193 static void dom_finalize (value);
194 static void net_finalize (value);
195 #ifdef HAVE_VIRSTORAGEPOOLPTR
196 static void pol_finalize (value);
197 #endif
198 #ifdef HAVE_VIRSTORAGEVOLPTR
199 static void vol_finalize (value);
200 #endif
201 #ifdef HAVE_VIRJOBPTR
202 static void jb_finalize (value);
203 #endif
204
205 static struct custom_operations conn_custom_operations = {
206   "conn_custom_operations",
207   conn_finalize,
208   custom_compare_default,
209   custom_hash_default,
210   custom_serialize_default,
211   custom_deserialize_default
212 };
213
214 static struct custom_operations dom_custom_operations = {
215   "dom_custom_operations",
216   dom_finalize,
217   custom_compare_default,
218   custom_hash_default,
219   custom_serialize_default,
220   custom_deserialize_default
221
222 };
223
224 static struct custom_operations net_custom_operations = {
225   "net_custom_operations",
226   net_finalize,
227   custom_compare_default,
228   custom_hash_default,
229   custom_serialize_default,
230   custom_deserialize_default
231 };
232
233 #ifdef HAVE_VIRSTORAGEPOOLPTR
234 static struct custom_operations pol_custom_operations = {
235   "pol_custom_operations",
236   pol_finalize,
237   custom_compare_default,
238   custom_hash_default,
239   custom_serialize_default,
240   custom_deserialize_default
241 };
242 #endif
243
244 #ifdef HAVE_VIRSTORAGEVOLPTR
245 static struct custom_operations vol_custom_operations = {
246   "vol_custom_operations",
247   vol_finalize,
248   custom_compare_default,
249   custom_hash_default,
250   custom_serialize_default,
251   custom_deserialize_default
252 };
253 #endif
254
255 #ifdef HAVE_VIRJOBPTR
256 static struct custom_operations jb_custom_operations = {
257   "jb_custom_operations",
258   jb_finalize,
259   custom_compare_default,
260   custom_hash_default,
261   custom_serialize_default,
262   custom_deserialize_default
263 };
264 #endif
265
266 static value
267 Val_connect (virConnectPtr conn)
268 {
269   CAMLparam0 ();
270   CAMLlocal1 (rv);
271   rv = caml_alloc_custom (&conn_custom_operations,
272                           sizeof (virConnectPtr), 0, 1);
273   Connect_val (rv) = conn;
274   CAMLreturn (rv);
275 }
276
277 static value
278 Val_dom (virDomainPtr dom)
279 {
280   CAMLparam0 ();
281   CAMLlocal1 (rv);
282   rv = caml_alloc_custom (&dom_custom_operations,
283                           sizeof (virDomainPtr), 0, 1);
284   Dom_val (rv) = dom;
285   CAMLreturn (rv);
286 }
287
288 static value
289 Val_net (virNetworkPtr net)
290 {
291   CAMLparam0 ();
292   CAMLlocal1 (rv);
293   rv = caml_alloc_custom (&net_custom_operations,
294                           sizeof (virNetworkPtr), 0, 1);
295   Net_val (rv) = net;
296   CAMLreturn (rv);
297 }
298
299 #ifdef HAVE_VIRSTORAGEPOOLPTR
300 static value
301 Val_pol (virStoragePoolPtr pol)
302 {
303   CAMLparam0 ();
304   CAMLlocal1 (rv);
305   rv = caml_alloc_custom (&pol_custom_operations,
306                           sizeof (virStoragePoolPtr), 0, 1);
307   Pol_val (rv) = pol;
308   CAMLreturn (rv);
309 }
310 #endif
311
312 #ifdef HAVE_VIRSTORAGEVOLPTR
313 static value
314 Val_vol (virStorageVolPtr vol)
315 {
316   CAMLparam0 ();
317   CAMLlocal1 (rv);
318   rv = caml_alloc_custom (&vol_custom_operations,
319                           sizeof (virStorageVolPtr), 0, 1);
320   Vol_val (rv) = vol;
321   CAMLreturn (rv);
322 }
323 #endif
324
325 #ifdef HAVE_VIRJOBPTR
326 static value
327 Val_jb (virJobPtr jb)
328 {
329   CAMLparam0 ();
330   CAMLlocal1 (rv);
331   rv = caml_alloc_custom (&jb_custom_operations,
332                           sizeof (virJobPtr), 0, 1);
333   Jb_val (rv) = jb;
334   CAMLreturn (rv);
335 }
336 #endif
337
338 /* This wraps up the (dom, conn) pair (Domain.t). */
339 static value
340 Val_domain (virDomainPtr dom, value connv)
341 {
342   CAMLparam1 (connv);
343   CAMLlocal2 (rv, v);
344
345   rv = caml_alloc_tuple (2);
346   v = Val_dom (dom);
347   Store_field (rv, 0, v);
348   Store_field (rv, 1, connv);
349   CAMLreturn (rv);
350 }
351
352 /* This wraps up the (net, conn) pair (Network.t). */
353 static value
354 Val_network (virNetworkPtr net, value connv)
355 {
356   CAMLparam1 (connv);
357   CAMLlocal2 (rv, v);
358
359   rv = caml_alloc_tuple (2);
360   v = Val_net (net);
361   Store_field (rv, 0, v);
362   Store_field (rv, 1, connv);
363   CAMLreturn (rv);
364 }
365
366 #ifdef HAVE_VIRSTORAGEPOOLPTR
367 /* This wraps up the (pol, conn) pair (Pool.t). */
368 static value
369 Val_pool (virStoragePoolPtr pol, value connv)
370 {
371   CAMLparam1 (connv);
372   CAMLlocal2 (rv, v);
373
374   rv = caml_alloc_tuple (2);
375   v = Val_pol (pol);
376   Store_field (rv, 0, v);
377   Store_field (rv, 1, connv);
378   CAMLreturn (rv);
379 }
380 #endif
381
382 #ifdef HAVE_VIRSTORAGEVOLPTR
383 /* This wraps up the (vol, conn) pair (Volume.t). */
384 static value
385 Val_volume (virStorageVolPtr vol, value connv)
386 {
387   CAMLparam1 (connv);
388   CAMLlocal2 (rv, v);
389
390   rv = caml_alloc_tuple (2);
391   v = Val_vol (vol);
392   Store_field (rv, 0, v);
393   Store_field (rv, 1, connv);
394   CAMLreturn (rv);
395 }
396 #endif
397
398 #ifdef HAVE_VIRJOBPTR
399 /* This wraps up the (jb, conn) pair (Job.t). */
400 static value
401 Val_job (virJobPtr jb, value connv)
402 {
403   CAMLparam1 (connv);
404   CAMLlocal2 (rv, v);
405
406   rv = caml_alloc_tuple (2);
407   v = Val_jb (jb);
408   Store_field (rv, 0, v);
409   Store_field (rv, 1, connv);
410   CAMLreturn (rv);
411 }
412 #endif
413
414 static void
415 conn_finalize (value connv)
416 {
417   virConnectPtr conn = Connect_val (connv);
418   if (conn) (void) virConnectClose (conn);
419 }
420
421 static void
422 dom_finalize (value domv)
423 {
424   virDomainPtr dom = Dom_val (domv);
425   if (dom) (void) virDomainFree (dom);
426 }
427
428 static void
429 net_finalize (value netv)
430 {
431   virNetworkPtr net = Net_val (netv);
432   if (net) (void) virNetworkFree (net);
433 }
434
435 #ifdef HAVE_VIRSTORAGEPOOLPTR
436 static void
437 pol_finalize (value polv)
438 {
439   virStoragePoolPtr pol = Pol_val (polv);
440   if (pol) (void) virStoragePoolFree (pol);
441 }
442 #endif
443
444 #ifdef HAVE_VIRSTORAGEVOLPTR
445 static void
446 vol_finalize (value volv)
447 {
448   virStorageVolPtr vol = Vol_val (volv);
449   if (vol) (void) virStorageVolFree (vol);
450 }
451 #endif
452
453 #ifdef HAVE_VIRJOBPTR
454 static void
455 jb_finalize (value jbv)
456 {
457   virJobPtr jb = Jb_val (jbv);
458   if (jb) (void) virJobFree (jb);
459 }
460 #endif