Imported Upstream version 3.1.0
[debian/amanda] / perl / Amanda / NDMP.swg
1 /*
2  * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 %module "Amanda::NDMP"
22 %include "amglue/amglue.swg"
23 %include "exception.i"
24
25 %include "Amanda/NDMP.pod"
26
27 %{
28 #include "ndmpconnobj.h"
29 #include "glib-util.h"
30 %}
31
32 /* initialize glib, and in particular GType */
33 %init %{
34     glib_init();
35 %}
36
37 /* supporting typemaps */
38
39 /* treat all enums in this file as regular UV's - no need for BigInt */
40 %{
41 typedef guint ndmp_enum;
42 %}
43
44 /* Any enumeration, input */
45 %typemap(in) ndmp_enum "$1 = SvIV($input);";
46
47 /* Any enumeration, output argument */
48 %typemap(in,numinputs=0) ndmp_enum * (int temp) "$1 = &temp; temp = 0;";
49 %typemap(argout) ndmp_enum * {
50     if (argvi >= items) {
51         EXTEND(sp,1);
52     }
53
54     $result = sv_newmortal();
55     sv_setuv($result, (UV)(*$1));
56     argvi++;
57 }
58
59 /* gsize, output argument */
60 %typemap(in,numinputs=0) gsize * (gsize temp) "$1 = &temp; temp = 0;"
61 %typemap(argout) gsize * {
62     if (argvi >= items) {
63         EXTEND(sp,1);
64     }
65
66     SP += argvi; PUTBACK;
67     $result = sv_2mortal(amglue_newSVu64(*$1));
68     SP -= argvi; argvi++;
69 }
70
71 /* guint64, output argument */
72 %typemap(in,numinputs=0) guint64 * (guint64 temp) "$1 = &temp; temp = 0;"
73 %typemap(argout) guint64 * {
74     if (argvi >= items) {
75         EXTEND(sp,1);
76     }
77
78     SP += argvi; PUTBACK;
79     $result = sv_2mortal(amglue_newSVu64(*$1));
80     SP -= argvi; argvi++;
81 }
82
83 /* guint, output argument */
84 %typemap(in,numinputs=0) guint * (guint temp) "$1 = &temp; temp = 0;"
85 %typemap(argout) guint * {
86     if (argvi >= items) {
87         EXTEND(sp,1);
88     }
89
90     SP += argvi; PUTBACK;
91     $result = sv_2mortal(amglue_newSVu64(*$1));
92     SP -= argvi; argvi++;
93 }
94
95 typedef struct NDMPConnection {
96     /* methods */
97     %extend {
98         /* constructor */
99         NDMPConnection(
100                 gchar *hostname,
101                 gint port,
102                 gchar *username,
103                 gchar *password,
104                 gchar *auth) {
105             return ndmp_connection_new(
106                     hostname, port, username, password, auth);
107         }
108
109         ~NDMPConnection() {
110             g_object_unref(self);
111         }
112
113         /* error handling */
114
115         int
116         err_code() {
117             return ndmp_connection_err_code(self);
118         }
119
120         %newobject err_msg;
121         gchar *
122         err_msg() {
123             return ndmp_connection_err_msg(self);
124         }
125
126         void
127         set_verbose(gboolean verbose) {
128             ndmp_connection_set_verbose(self, verbose);
129         }
130
131         /* operations */
132
133         gboolean
134         scsi_open(gchar *device) {
135             return ndmp_connection_scsi_open(
136                     self,
137                     device);
138         }
139
140         gboolean
141         scsi_close() {
142             return ndmp_connection_scsi_close(self);
143         }
144
145         /* NOTE: this method is wrapped with a more perlish interface; see below */
146
147         /* handle cdb */
148         %typemap(in) (gpointer cdb, gsize cdb_len) {
149             /* cdb */
150             int alloc = SWIG_OLDOBJ;
151             SWIG_AsCharPtrAndSize($input, (char **)&$1, &$2, &alloc);
152             if ($2) $2--; /* strip trailing NUL byte */
153         }
154
155         /* handle dataout and its response */
156         %typemap(in,numinputs=1)
157             (gpointer dataout, gsize dataout_len, gsize *actual_dataout_len)
158             (gsize dataout_len) {
159             /* dataout */
160
161             /* handle the actual input here */
162             int alloc = SWIG_OLDOBJ;
163             SWIG_AsCharPtrAndSize($input, (char **)&$1, &$2, &alloc);
164             if ($2) $2--; /* strip trailing NUL byte */
165             /* set up for argout typemap, below */
166             dataout_len = 0;
167             $3 = &dataout_len;
168         }
169         %typemap(argout)
170             (gpointer dataout, gsize dataout_len, gsize *actual_dataout_len) {
171             if (argvi >= items) {
172                 EXTEND(sp,1);
173             }
174
175             SP += argvi; PUTBACK;
176             $result = sv_2mortal(amglue_newSVu64(*$3));
177             SP -= argvi; argvi++;
178         }
179
180         /* handle datain and its response */
181         %typemap(in,numinputs=1)
182             (gpointer datain, gsize datain_max_len, gsize *actual_datain_len)
183             (gpointer datain_buf, gsize actual_datain_len) {
184             /* datain */
185             gsize max_size = amglue_SvU64($input);
186             $2 = max_size;
187             if (max_size) {
188                 $1 = g_malloc(max_size);
189             } else {
190                 $1 = NULL;
191             }
192             actual_datain_len = 0;
193             $3 = &actual_datain_len;
194         }
195         %typemap(argout)
196             (gpointer datain, gsize datain_max_len, gsize *actual_datain_len) {
197             if (argvi >= items) {
198                 EXTEND(sp,1);
199             }
200
201             /* convert the value, even if it's NULL */
202             $result = SWIG_FromCharPtrAndSize($1, *$3);
203             argvi++;
204             if ($1) g_free($1);
205         }
206
207         /* handle status */
208         %typemap(in,numinputs=0) (guint8 *status) (guint8 temp) "$1 = &temp;";
209         %typemap(argout) (guint8 *status) {
210             if (argvi >= items) {
211                 EXTEND(sp,1);
212             }
213
214             $result = sv_newmortal();
215             sv_setuv($result, (UV)(*$1));
216             argvi++;
217         }
218
219         /* handle ext_status */
220         %typemap(in,numinputs=0)
221             (gpointer ext_sense, gsize ext_sense_max_len, gsize *actual_ext_sense_len)
222             (guint8 ext_sense_buf[128], gsize actual_ext_sense_len) {
223             $1 = ext_sense_buf;
224             $2 = sizeof(ext_sense_buf); /* always allocate 128 bytes for sense */
225             actual_ext_sense_len = 0;
226             $3 = &actual_ext_sense_len;
227         }
228         %typemap(argout)
229             (gpointer ext_sense, gsize ext_sense_max_len, gsize *actual_ext_sense_len) {
230             if (argvi >= items) {
231                 EXTEND(sp,1);
232             }
233
234             $result = SWIG_FromCharPtrAndSize($1, *$3);
235             argvi++;
236         }
237
238         gboolean
239         scsi_execute_cdb_C(
240                 ndmp_enum flags,
241                 guint32 timeout,
242                 gpointer cdb,
243                 gsize cdb_len,
244                 gpointer dataout,
245                 gsize dataout_len,
246                 gsize *actual_dataout_len,
247                 gpointer datain,
248                 gsize datain_max_len,
249                 gsize *actual_datain_len,
250                 guint8 *status,
251                 gpointer ext_sense,
252                 gsize ext_sense_max_len,
253                 gsize *actual_ext_sense_len
254                 ) {
255             return ndmp_connection_scsi_execute_cdb(
256                     self,
257                     flags,
258                     timeout,
259                     cdb,
260                     cdb_len,
261                     dataout,
262                     dataout_len,
263                     actual_dataout_len,
264                     datain,
265                     datain_max_len,
266                     actual_datain_len,
267                     status,
268                     ext_sense,
269                     ext_sense_max_len,
270                     actual_ext_sense_len
271                     );
272         }
273
274         gboolean
275         tape_open(
276                 gchar *device,
277                 ndmp_enum mode) {
278             return ndmp_connection_tape_open(
279                     self,
280                     device,
281                     mode);
282         }
283
284         gboolean
285         tape_close() {
286             return ndmp_connection_tape_close(self);
287         }
288
289         gboolean
290         tape_mtio(
291                 ndmp_enum tape_op,
292                 gint count,
293                 guint *resid) {
294             return ndmp_connection_tape_mtio(
295                     self,
296                     tape_op,
297                     count,
298                     resid);
299         }
300
301         %typemap(in) (gpointer buf, guint64 len) {
302             int alloc = SWIG_OLDOBJ;
303             size_t len_tmp; /* use a temporary with the right type */
304             SWIG_AsCharPtrAndSize($input, (char **)&$1, &len_tmp, &alloc);
305             if (len_tmp) len_tmp--; /* strip trailing NUL byte */
306             $2 = len_tmp;
307         }
308         gboolean
309         tape_write(
310                 gpointer buf,
311                 guint64 len,
312                 guint64 *count) {
313             return ndmp_connection_tape_write(
314                     self,
315                     buf,
316                     len,
317                     count);
318         }
319
320         %typemap(in,numinputs=1)
321             (gpointer buf, guint64 count, guint64 *out_count)
322             (guint64 out_count) {
323             $2 = amglue_SvU64($input);
324             $1 = $2?g_malloc($2):NULL;
325             out_count = 0;
326             $3 = &out_count;
327         }
328         %typemap(argout)
329             (gpointer buf, guint64 count, guint64 *out_count) {
330             if (argvi >= items) {
331                 EXTEND(sp,1);
332             }
333
334             /* convert the value, even if it's NULL */
335             $result = SWIG_FromCharPtrAndSize($1, *$3);
336             argvi++;
337             if ($1) g_free($1);
338         }
339         gboolean
340         tape_read(
341                 gpointer buf,
342                 guint64 count,
343                 guint64 *out_count) {
344             return ndmp_connection_tape_read(
345                     self,
346                     buf,
347                     count,
348                     out_count);
349         }
350
351         gboolean
352         tape_get_state(
353                 guint64 *blocksize,
354                 guint64 *file_num,
355                 guint64 *blockno) {
356             return ndmp_connection_tape_get_state(
357                     self,
358                     blocksize,
359                     file_num,
360                     blockno);
361         }
362
363         /* mover interface is not yet SWIGged */
364     };
365 } NDMPConnection;
366
367 /* perlish wrappers */
368 %perlcode %{
369 package Amanda::NDMP::NDMPConnection;
370
371 sub scsi_execute_cdb {
372     my $self = shift;
373     my %params = @_;
374
375     die "no 'flags' parameter'" unless defined $params{'flags'};
376     die "no 'timeout' parameter'" unless defined $params{'timeout'};
377     die "no 'cdb' parameter'" unless defined $params{'cdb'};
378     if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_IN) {
379         die "no 'datain_len' parameter'" unless defined $params{'datain_len'};
380     } else {
381         $params{'datain_len'} = 0;
382     }
383     if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_OUT) {
384         die "no 'dataout' parameter'" unless defined $params{'dataout'};
385     } else {
386         $params{'dataout'} = undef;
387     }
388
389     my ($ok, $dataout_len, $datain, $status, $ext_sense) =
390         $self->scsi_execute_cdb_C(
391             $params{'flags'}, $params{'timeout'},
392             $params{'cdb'}, $params{'dataout'},
393             $params{'datain_len'});
394
395     return 0 unless ($ok);
396
397     my %result = (
398         status => $status,
399         ext_sense => $ext_sense);
400     if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_IN) {
401         $result{'datain'} = $datain;
402     }
403     if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_OUT) {
404         $result{'dataout_len'} = $dataout_len;
405     }
406     return \%result;
407 }
408
409 package Amanda::NDMP;
410 %}
411
412 /* selected NDMP constants; note that the "NDMP9_" prfix is required */
413
414 amglue_add_flag_tag_fns(scsi_data_dir);
415 amglue_add_constant_short(NDMP9_SCSI_DATA_DIR_NONE, "NDMP9_SCSI_DATA_DIR_NONE", scsi_data_dir);
416 amglue_add_constant_short(NDMP9_SCSI_DATA_DIR_IN, "NDMP9_SCSI_DATA_DIR_IN", scsi_data_dir);
417 amglue_add_constant_short(NDMP9_SCSI_DATA_DIR_OUT, "NDMP9_SCSI_DATA_DIR_OUT", scsi_data_dir);
418 amglue_copy_to_tag(scsi_data_dir, constants);
419
420 amglue_add_flag_tag_fns(tape_open_mode);
421 amglue_add_constant_short(NDMP9_TAPE_READ_MODE, "NDMP9_TAPE_READ_MODE", tape_open_mode);
422 amglue_add_constant_short(NDMP9_TAPE_RDWR_MODE, "NDMP9_TAPE_RDRW_MODE", tape_open_mode);
423 amglue_add_constant_short(NDMP9_TAPE_RAW_MODE, "NDMP9_TAPE_RAW_MODE", tape_open_mode);
424 amglue_copy_to_tag(tape_open_mode, constants);
425
426 amglue_add_flag_tag_fns(tape_mtio_op);
427 amglue_add_constant_short(NDMP9_MTIO_FSF, "NDMP9_MTIO_FSF", tape_mtio_op);
428 amglue_add_constant_short(NDMP9_MTIO_BSF, "NDMP9_MTIO_BSF", tape_mtio_op);
429 amglue_add_constant_short(NDMP9_MTIO_FSR, "NDMP9_MTIO_FSR", tape_mtio_op);
430 amglue_add_constant_short(NDMP9_MTIO_BSR, "NDMP9_MTIO_BSR", tape_mtio_op);
431 amglue_add_constant_short(NDMP9_MTIO_REW, "NDMP9_MTIO_REW", tape_mtio_op);
432 amglue_add_constant_short(NDMP9_MTIO_EOF, "NDMP9_MTIO_EOF", tape_mtio_op);
433 amglue_add_constant_short(NDMP9_MTIO_OFF, "NDMP9_MTIO_OFF", tape_mtio_op);
434 amglue_copy_to_tag(tape_mtio_op, constants);
435
436 amglue_add_flag_tag_fns(mover_mode);
437 amglue_add_constant_short(NDMP9_MOVER_MODE_READ, "NDMP9_MOVER_MODE_READ", mover_mode);
438 amglue_add_constant_short(NDMP9_MOVER_MODE_WRITE, "NDMP9_MOVER_MODE_WRITE", mover_mode);
439 amglue_copy_to_tag(mover_mode, constants);
440
441 amglue_add_flag_tag_fns(addr_type);
442 amglue_add_constant_short(NDMP9_ADDR_LOCAL, "NDMP9_ADDR_LOCAL", addr_type);
443 amglue_add_constant_short(NDMP9_ADDR_TCP, "NDMP9_ADDR_TCP", addr_type);
444 amglue_add_constant_short(NDMP9_ADDR_AS_CONNECTED, "NDMP9_ADDR_AS_CONNECTED", addr_type);
445 amglue_copy_to_tag(addr_type, constants);
446
447 amglue_add_flag_tag_fns(mover_state);
448 amglue_add_constant_short(NDMP9_MOVER_STATE_IDLE, "NDMP9_MOVER_STATE_IDLE", mover_state);
449 amglue_add_constant_short(NDMP9_MOVER_STATE_LISTEN, "NDMP9_MOVER_STATE_LISTEN", mover_state);
450 amglue_add_constant_short(NDMP9_MOVER_STATE_ACTIVE, "NDMP9_MOVER_STATE_ACTIVE", mover_state);
451 amglue_add_constant_short(NDMP9_MOVER_STATE_PAUSED, "NDMP9_MOVER_STATE_PAUSED", mover_state);
452 amglue_add_constant_short(NDMP9_MOVER_STATE_HALTED, "NDMP9_MOVER_STATE_HALTED", mover_state);
453 amglue_add_constant_short(NDMP9_MOVER_STATE_STANDBY, "NDMP9_MOVER_STATE_STANDBY", mover_state);
454 amglue_copy_to_tag(mover_state, constants);
455
456 amglue_add_flag_tag_fns(data_halt_reason);
457 amglue_add_constant_short(NDMP9_DATA_HALT_NA, "NDMP9_DATA_HALT_NA", data_halt_reason);
458 amglue_add_constant_short(NDMP9_DATA_HALT_SUCCESSFUL, "NDMP9_DATA_HALT_SUCCESSFUL", data_halt_reason);
459 amglue_add_constant_short(NDMP9_DATA_HALT_ABORTED, "NDMP9_DATA_HALT_ABORTED", data_halt_reason);
460 amglue_add_constant_short(NDMP9_DATA_HALT_INTERNAL_ERROR, "NDMP9_DATA_HALT_INTERNAL_ERROR", data_halt_reason);
461 amglue_add_constant_short(NDMP9_DATA_HALT_CONNECT_ERROR, "NDMP9_DATA_HALT_CONNECT_ERROR", data_halt_reason);
462 amglue_copy_to_tag(data_halt_reason, constants);
463
464 amglue_add_flag_tag_fns(mover_halt_reason);
465 amglue_add_constant_short(NDMP9_MOVER_HALT_NA, "NDMP9_MOVER_HALT_NA", mover_halt_reason);
466 amglue_add_constant_short(NDMP9_MOVER_HALT_CONNECT_CLOSED, "NDMP9_MOVER_HALT_CONNECT_CLOSED", mover_halt_reason);
467 amglue_add_constant_short(NDMP9_MOVER_HALT_ABORTED, "NDMP9_MOVER_HALT_ABORTED", mover_halt_reason);
468 amglue_add_constant_short(NDMP9_MOVER_HALT_INTERNAL_ERROR, "NDMP9_MOVER_HALT_INTERNAL_ERROR", mover_halt_reason);
469 amglue_add_constant_short(NDMP9_MOVER_HALT_CONNECT_ERROR, "NDMP9_MOVER_HALT_CONNECT_ERROR", mover_halt_reason);
470 amglue_copy_to_tag(mover_halt_reason, constants);
471
472 amglue_add_flag_tag_fns(mover_pause_reason);
473 amglue_add_constant_short(NDMP9_MOVER_PAUSE_NA, "NDMP9_MOVER_PAUSE_NA", mover_pause_reason);
474 amglue_add_constant_short(NDMP9_MOVER_PAUSE_EOM, "NDMP9_MOVER_PAUSE_EOM", mover_pause_reason);
475 amglue_add_constant_short(NDMP9_MOVER_PAUSE_EOF, "NDMP9_MOVER_PAUSE_EOF", mover_pause_reason);
476 amglue_add_constant_short(NDMP9_MOVER_PAUSE_SEEK, "NDMP9_MOVER_PAUSE_SEEK", mover_pause_reason);
477 amglue_add_constant_short(NDMP9_MOVER_PAUSE_MEDIA_ERROR, "NDMP9_MOVER_PAUSE_MEDIA_ERROR", mover_pause_reason);
478 amglue_add_constant_short(NDMP9_MOVER_PAUSE_EOW, "NDMP9_MOVER_PAUSE_EOW", mover_pause_reason);
479 amglue_copy_to_tag(mover_pause_reason, constants);