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