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