File Coverage

BackupPC_XS.xs
Criterion Covered Total %
statement 0 298 0.0
branch 0 256 0.0
condition n/a
subroutine n/a
pod n/a
total 0 554 0.0


line stmt bran cond sub pod time code
1             /*
2             * XS glue for perl interface to BackupPC libraries.
3             *
4             * Copyright (C) 2013 Craig Barratt.
5             *
6             * This program is free software; you can redistribute it and/or modify
7             * it under the terms of the GNU General Public License as published by
8             * the Free Software Foundation; either version 3 of the License, or
9             * (at your option) any later version.
10             *
11             * This program 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
14             * GNU General Public License for more details.
15             *
16             * You should have received a copy of the GNU General Public License along
17             * with this program; if not, visit the http://fsf.org website.
18             */
19              
20              
21             #include "EXTERN.h"
22             #include "perl.h"
23             #include "XSUB.h"
24              
25             #include "ppport.h"
26              
27             #include
28              
29             typedef bpc_fileZIO_fd *BackupPC__XS__FileZIO;
30             typedef bpc_refCount_info *BackupPC__XS__PoolRefCnt;
31             typedef bpc_deltaCount_info *BackupPC__XS__DeltaRefCnt;
32             typedef bpc_poolWrite_info *BackupPC__XS__PoolWrite;
33             typedef bpc_attrib_dir *BackupPC__XS__Attrib;
34             typedef bpc_attribCache_info *BackupPC__XS__AttribCache;
35              
36             #define hv_get_int(hv, key, value) { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvIV(*svp); }
37             #define hv_get_uint(hv, key, value) { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvUV(*svp); }
38             #define hv_get_str(hv, key, value, len) { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvPV(*svp, len); }
39              
40 0           static HV* convert_file2hv(bpc_attrib_file *file, char *fileName)
41             {
42             HV *rh;
43             size_t listLen, i;
44              
45 0           rh = newHV();
46 0           (void)hv_store(rh, "uid", 3, newSVuv(file->uid), 0);
47 0           (void)hv_store(rh, "gid", 3, newSVuv(file->gid), 0);
48 0           (void)hv_store(rh, "name", 4, newSVpvn(fileName, strlen(fileName)), 0);
49 0           (void)hv_store(rh, "type", 4, newSVuv(file->type), 0);
50 0           (void)hv_store(rh, "mode", 4, newSVuv(file->mode), 0);
51 0           (void)hv_store(rh, "size", 4, newSVuv(file->size), 0);
52 0           (void)hv_store(rh, "mtime", 5, newSViv(file->mtime), 0);
53 0           (void)hv_store(rh, "inode", 5, newSVuv(file->inode), 0);
54 0           (void)hv_store(rh, "nlinks", 6, newSVuv(file->nlinks), 0);
55 0           (void)hv_store(rh, "digest", 6, newSVpvn((char*)file->digest.digest, file->digest.len), 0);
56 0           (void)hv_store(rh, "compress", 8, newSVuv(file->compress), 0);
57              
58 0 0         if ( (listLen = bpc_attrib_xattrList(file, NULL, 0, 0)) > 0 ) {
59 0           char *keys = malloc(listLen), *p;
60              
61 0 0         if ( keys && bpc_attrib_xattrList(file, keys, listLen, 0) > 0 ) {
    0          
62 0           HV *rhAttr = newHV();
63 0 0         for ( i = 0, p = keys ; i < listLen ; ) {
64 0           int len = strlen(p);
65             /*
66             * xattr keys include the \0 terminating byte in the length, so add 1 here,
67             * and subtract 1 in the hv_store() below.
68             */
69 0           bpc_attrib_xattr *xattr = bpc_attrib_xattrGet(file, p, len + 1, 0);
70 0           p += len + 1;
71 0           i += len + 1;
72 0 0         if ( !xattr ) continue;
73 0           (void)hv_store(rhAttr, xattr->key.key, xattr->key.keyLen - 1, newSVpvn(xattr->value, xattr->valueLen), 0);
74             }
75 0           (void)hv_store(rh, "xattr", 5, newRV_noinc((SV*)rhAttr), 0);
76             }
77 0 0         if ( keys ) free(keys);
78             }
79 0           return rh;
80             }
81              
82 0           static void convert_hv2file(HV *hv, bpc_attrib_file *file)
83             {
84 0           char *digestStr = "";
85 0           STRLEN digestLen = 0;
86             SV** svp;
87              
88 0 0         hv_get_uint(hv, "uid", file->uid);
    0          
    0          
89 0 0         hv_get_uint(hv, "gid", file->gid);
    0          
    0          
90 0 0         hv_get_uint(hv, "type", file->type);
    0          
    0          
91 0 0         hv_get_uint(hv, "mode", file->mode);
    0          
    0          
92 0 0         hv_get_uint(hv, "size", file->size);
    0          
    0          
93 0 0         hv_get_int(hv, "mtime", file->mtime);
    0          
    0          
94 0 0         hv_get_uint(hv, "inode", file->inode);
    0          
    0          
95 0 0         hv_get_uint(hv, "nlinks", file->nlinks);
    0          
    0          
96 0 0         hv_get_uint(hv, "compress", file->compress);
    0          
    0          
97 0 0         hv_get_str(hv, "digest", digestStr, digestLen);
    0          
    0          
98 0 0         if ( 0 < digestLen && digestLen <= sizeof(file->digest.digest) ) {
    0          
99 0           memcpy(file->digest.digest, digestStr, digestLen);
100 0           file->digest.len = digestLen;
101             } else {
102 0           file->digest.len = 0;
103             }
104 0 0         if ( (svp = hv_fetch(hv, "xattr", 5, 0)) && *svp ) {
    0          
105             HE *he;
106 0           HV *hvXattr = (HV*)SvRV(*svp);
107             /*
108             * clear out the old xattrs, and copy in the new
109             */
110 0           bpc_attrib_xattrDeleteAll(file);
111 0           hv_iterinit(hvXattr);
112 0 0         while ( (he = hv_iternext(hvXattr)) ) {
113             I32 keyLen;
114             STRLEN valueLen;
115 0           char *key = hv_iterkey(he, &keyLen), *value;
116 0           SV *valSV = hv_iterval(hvXattr, he);
117              
118 0 0         value = SvPV(valSV, valueLen);
119 0           bpc_attrib_xattrSetValue(file, key, keyLen, value, valueLen);
120             }
121             }
122 0           }
123              
124             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::FileZIO
125              
126             PROTOTYPES: DISABLE
127              
128             BackupPC::XS::FileZIO
129             open(fileName, writeFile, compressLevel)
130             char *fileName;
131             int writeFile;
132             int compressLevel;
133             CODE:
134             {
135 0           RETVAL = calloc(1, sizeof(bpc_fileZIO_fd));
136 0 0         if ( bpc_fileZIO_open(RETVAL, fileName, writeFile, compressLevel) < 0 ) {
137 0           free(RETVAL);
138 0           XSRETURN_UNDEF;
139             }
140             }
141             OUTPUT:
142             RETVAL
143              
144             BackupPC::XS::FileZIO
145             fdopen(stream, writeFile, compressLevel)
146             FILE *stream;
147             int writeFile;
148             int compressLevel;
149             CODE:
150             {
151 0           RETVAL = calloc(1, sizeof(bpc_fileZIO_fd));
152 0 0         if ( bpc_fileZIO_fdopen(RETVAL, stream, writeFile, compressLevel) < 0 ) {
153 0           free(RETVAL);
154 0           XSRETURN_UNDEF;
155             }
156             }
157             OUTPUT:
158             RETVAL
159              
160             void
161             DESTROY(fd)
162             BackupPC::XS::FileZIO fd;
163             CODE:
164 0           bpc_fileZIO_close(fd);
165 0           free(fd);
166              
167             void
168             close(fd)
169             BackupPC::XS::FileZIO fd
170             CODE:
171             {
172 0           bpc_fileZIO_close(fd);
173             }
174              
175             int
176             rewind(fd)
177             BackupPC::XS::FileZIO fd
178             CODE:
179             {
180 0           RETVAL = bpc_fileZIO_rewind(fd);
181             }
182             OUTPUT:
183             RETVAL
184              
185             int
186             write(fd, data)
187             BackupPC::XS::FileZIO fd;
188             SV *data;
189             CODE:
190             {
191             char *str;
192             STRLEN len;
193              
194 0 0         if ( SvROK(data) ) {
195 0 0         str = SvPV(SvRV(data), len);
196 0           RETVAL = bpc_fileZIO_write(fd, (unsigned char*)str, len);
197             } else {
198 0           RETVAL = -1;
199             }
200             }
201             OUTPUT:
202             RETVAL
203              
204             int
205             read(fd, data, len)
206             BackupPC::XS::FileZIO fd;
207             SV *data;
208             STRLEN len
209             CODE:
210             {
211             char *str;
212             SV *d;
213             STRLEN dLen;
214              
215 0 0         if ( SvROK(data) ) {
216 0           d = SvRV(data);
217 0 0         if (! SvOK(d))
    0          
    0          
218 0           sv_setpvs(d, "");
219 0 0         SvGROW(d, len);
    0          
220 0 0         str = SvPV(d, dLen);
221 0           RETVAL = bpc_fileZIO_read(fd, (unsigned char*)str, len);
222 0 0         if ( RETVAL >= 0 ) {
223 0           SvCUR_set(d, RETVAL);
224             } else {
225 0           SvCUR_set(d, 0);
226             }
227             } else {
228 0           RETVAL = -1;
229             }
230             }
231             OUTPUT:
232             RETVAL
233              
234             SV*
235             readLine(fd)
236             BackupPC::XS::FileZIO fd;
237             CODE:
238             {
239             char *str;
240             size_t strLen;
241 0 0         if ( bpc_fileZIO_readLine(fd, &str, &strLen) || !str ) XSRETURN_UNDEF;
    0          
242 0           RETVAL = newSVpvn(str, strLen);
243             }
244             OUTPUT:
245             RETVAL
246              
247             void
248             writeTeeStderr(fd, tee)
249             BackupPC::XS::FileZIO fd;
250             int tee;
251             CODE:
252 0           bpc_fileZIO_writeTeeStderr(fd, tee);
253              
254             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::PoolRefCnt
255              
256             BackupPC::XS::PoolRefCnt
257             new(entryCnt = 65536)
258             int entryCnt;
259             CODE:
260             {
261 0           RETVAL = calloc(1, sizeof(bpc_refCount_info));
262 0           bpc_poolRefInit((bpc_refCount_info*)RETVAL, entryCnt);
263             }
264             OUTPUT:
265             RETVAL
266              
267             void
268             DESTROY(info)
269             BackupPC::XS::PoolRefCnt info;
270             CODE:
271             {
272 0           bpc_poolRefDestroy(info);
273 0           free(info);
274             }
275              
276             int
277             get(info, d)
278             BackupPC::XS::PoolRefCnt info;
279             SV *d;
280             CODE:
281             {
282             bpc_digest digest;
283             char *str;
284             STRLEN len;
285             int count;
286              
287 0 0         if ( !SvPOK(d) ) {
288 0           XSRETURN_UNDEF;
289             }
290 0 0         str = SvPV(d, len);
291 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
292 0           memcpy(digest.digest, str, len);
293 0           digest.len = len;
294 0 0         if ( bpc_poolRefGet(info, &digest, &count) ) XSRETURN_UNDEF;
295 0           RETVAL = count;
296             } else {
297 0           XSRETURN_UNDEF;
298             }
299             }
300             OUTPUT:
301             RETVAL
302              
303             int
304             set(info, d, count)
305             BackupPC::XS::PoolRefCnt info;
306             SV *d;
307             int count;
308             CODE:
309             {
310             bpc_digest digest;
311             char *str;
312             STRLEN len;
313              
314 0 0         if ( !SvPOK(d) ) {
315 0           XSRETURN_UNDEF;
316             }
317 0 0         str = SvPV(d, len);
318 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
319 0           memcpy(digest.digest, str, len);
320 0           digest.len = len;
321 0           bpc_poolRefSet(info, &digest, count);
322 0           RETVAL = count;
323             } else {
324 0           XSRETURN_UNDEF;
325             }
326             }
327             OUTPUT:
328             RETVAL
329              
330             int
331             delete(info, d)
332             BackupPC::XS::PoolRefCnt info;
333             SV *d;
334             CODE:
335             {
336             bpc_digest digest;
337             char *str;
338             STRLEN len;
339              
340 0 0         if ( !SvPOK(d) ) {
341 0           XSRETURN_UNDEF;
342             }
343 0 0         str = SvPV(d, len);
344 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
345 0           memcpy(digest.digest, str, len);
346 0           digest.len = len;
347 0 0         if ( bpc_poolRefDelete(info, &digest) ) XSRETURN_UNDEF;
348 0           RETVAL = 1;
349             } else {
350 0           XSRETURN_UNDEF;
351             }
352             }
353             OUTPUT:
354             RETVAL
355              
356             int
357             incr(info, d, delta)
358             BackupPC::XS::PoolRefCnt info;
359             SV *d;
360             int delta;
361             CODE:
362             {
363             bpc_digest digest;
364             char *str;
365             STRLEN len;
366              
367 0 0         if ( !SvPOK(d) ) {
368 0           XSRETURN_UNDEF;
369             }
370 0 0         str = SvPV(d, len);
371 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
372 0           memcpy(digest.digest, str, len);
373 0           digest.len = len;
374 0           RETVAL = bpc_poolRefIncr(info, &digest, delta);
375             } else {
376 0           XSRETURN_UNDEF;
377             }
378             }
379             OUTPUT:
380             RETVAL
381              
382             void
383             iterate(info, idx)
384             BackupPC::XS::PoolRefCnt info;
385             unsigned int idx;
386             PREINIT:
387             bpc_digest digest;
388             int count;
389             PPCODE:
390             {
391 0 0         if ( !bpc_poolRefIterate(info, &digest, &count, &idx) ) {
392 0 0         EXTEND(SP, 3);
393 0           PUSHs(sv_2mortal(newSVpvn((char*)digest.digest, digest.len)));
394 0           PUSHs(sv_2mortal(newSViv(count)));
395 0           PUSHs(sv_2mortal(newSViv(idx)));
396             }
397             }
398              
399             int
400             read(info, fileName)
401             BackupPC::XS::PoolRefCnt info;
402             char *fileName;
403             CODE:
404 0           RETVAL = bpc_poolRefFileRead(info, fileName);
405             OUTPUT:
406             RETVAL
407              
408             int
409             write(info, fileName)
410             BackupPC::XS::PoolRefCnt info;
411             char *fileName;
412             CODE:
413 0           RETVAL = bpc_poolRefFileWrite(info, fileName);
414             OUTPUT:
415             RETVAL
416              
417             void
418             print(info)
419             BackupPC::XS::PoolRefCnt info;
420             CODE:
421 0           bpc_poolRefCountPrint(info);
422              
423             void
424             DeltaFileInit(hostDir)
425             char *hostDir;
426             CODE:
427 0           bpc_poolRefDeltaFileInitOld(hostDir);
428              
429             unsigned int
430             DeltaFileFlush()
431             CODE:
432 0           RETVAL = bpc_poolRefDeltaFileFlushOld();
433             OUTPUT:
434             RETVAL
435              
436             void
437             DeltaUpdate(compress, d, count)
438             int compress;
439             SV *d;
440             int count;
441             CODE:
442             {
443             bpc_digest digest;
444             char *str;
445             STRLEN len;
446              
447 0 0         if ( SvPOK(d) ) {
448 0 0         str = SvPV(d, len);
449 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
450 0           memcpy(digest.digest, str, len);
451 0           digest.len = len;
452 0           bpc_poolRefDeltaUpdateOld(compress, &digest, count);
453             }
454             }
455             }
456              
457             void
458             DeltaPrint()
459             CODE:
460 0           bpc_poolRefDeltaPrintOld();
461              
462             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::DeltaRefCnt
463              
464             BackupPC::XS::DeltaRefCnt
465             new(targetDir)
466             char *targetDir;
467             CODE:
468             {
469 0           RETVAL = calloc(1, sizeof(bpc_deltaCount_info));
470 0           bpc_poolRefDeltaFileInit((bpc_deltaCount_info*)RETVAL, targetDir);
471             }
472             OUTPUT:
473             RETVAL
474              
475             void
476             DESTROY(info)
477             BackupPC::XS::DeltaRefCnt info;
478             CODE:
479             {
480 0           bpc_poolRefDeltaFileDestroy(info);
481 0           free(info);
482             }
483              
484             unsigned int
485             flush(info)
486             BackupPC::XS::DeltaRefCnt info;
487             CODE:
488 0           RETVAL = bpc_poolRefDeltaFileFlush(info);
489             OUTPUT:
490             RETVAL
491              
492             void
493             update(info, compress, d, count)
494             BackupPC::XS::DeltaRefCnt info;
495             int compress;
496             SV *d;
497             int count;
498             CODE:
499             {
500             bpc_digest digest;
501             char *str;
502             STRLEN len;
503              
504 0 0         if ( SvPOK(d) ) {
505 0 0         str = SvPV(d, len);
506 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
507 0           memcpy(digest.digest, str, len);
508 0           digest.len = len;
509 0           bpc_poolRefDeltaUpdate(info, compress, &digest, count);
510             }
511             }
512             }
513              
514             void
515             print(info)
516             BackupPC::XS::DeltaRefCnt info;
517             CODE:
518 0           bpc_poolRefDeltaPrint(info);
519              
520             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::PoolWrite
521              
522             BackupPC::XS::PoolWrite
523             new(compressLevel, d = NULL)
524             int compressLevel;
525             SV *d;
526             CODE:
527             {
528 0           int ret = 0;
529              
530 0           RETVAL = calloc(1, sizeof(bpc_poolWrite_info));
531 0 0         if ( d && SvPOK(d) ) {
    0          
532             bpc_digest digest;
533             char *str;
534             STRLEN len;
535              
536 0 0         str = SvPV(d, len);
537 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
538 0           memcpy(digest.digest, str, len);
539 0           digest.len = len;
540 0           ret = bpc_poolWrite_open(RETVAL, compressLevel, &digest);
541             } else {
542 0           ret = bpc_poolWrite_open(RETVAL, compressLevel, NULL);
543             }
544             } else {
545 0           ret = bpc_poolWrite_open(RETVAL, compressLevel, NULL);
546             }
547 0 0         if ( ret ) {
548 0           free(RETVAL);
549 0           RETVAL = NULL;
550             }
551             }
552             OUTPUT:
553             RETVAL
554              
555             void
556             DESTROY(info)
557             BackupPC::XS::PoolWrite info;
558             CODE:
559             {
560 0           bpc_poolWrite_cleanup(info);
561 0           free(info);
562             }
563              
564             void
565             close(info)
566             BackupPC::XS::PoolWrite info;
567             PREINIT:
568             int match;
569             bpc_digest digest;
570             off_t poolFileSize;
571             int errorCnt;
572              
573             PPCODE:
574             {
575 0           bpc_poolWrite_close(info, &match, &digest, &poolFileSize, &errorCnt);
576 0 0         EXTEND(SP, 4);
577 0           PUSHs(sv_2mortal(newSViv(match)));
578 0           PUSHs(sv_2mortal(newSVpvn((char*)digest.digest, digest.len)));
579 0           PUSHs(sv_2mortal(newSViv(poolFileSize)));
580 0           PUSHs(sv_2mortal(newSViv(errorCnt)));
581             }
582              
583             int
584             write(info, data)
585             BackupPC::XS::PoolWrite info;
586             SV *data;
587             CODE:
588             {
589             char *str;
590             STRLEN len;
591              
592 0 0         if ( SvROK(data) ) {
593 0 0         str = SvPV(SvRV(data), len);
594 0           RETVAL = bpc_poolWrite_write(info, (unsigned char*)str, len);
595             } else {
596 0           RETVAL = -1;
597             }
598             }
599             OUTPUT:
600             RETVAL
601              
602             void
603             addToPool(info, fileName, v3PoolFile)
604             BackupPC::XS::PoolWrite info;
605             char *fileName;
606             int v3PoolFile;
607             CODE:
608 0           bpc_poolWrite_addToPool(info, fileName, v3PoolFile);
609              
610             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::Attrib
611              
612             BackupPC::XS::Attrib
613             new(compressLevel)
614             int compressLevel;
615             CODE:
616             {
617 0           RETVAL = calloc(1, sizeof(bpc_attrib_dir));
618 0           bpc_attrib_dirInit(RETVAL, compressLevel);
619             }
620             OUTPUT:
621             RETVAL
622              
623             void
624             DESTROY(dir)
625             BackupPC::XS::Attrib dir;
626             CODE:
627             {
628 0           bpc_attrib_dirDestroy(dir);
629 0           free(dir);
630             }
631              
632             SV*
633             get(dir, fileName = NULL)
634             BackupPC::XS::Attrib dir;
635             char *fileName;
636             CODE:
637             {
638 0 0         if ( fileName ) {
639 0           bpc_attrib_file *file = bpc_attrib_fileGet(dir, fileName, 0);
640 0 0         if ( !file ) XSRETURN_UNDEF;
641 0           RETVAL = newRV_noinc((SV*)convert_file2hv(file, file->name));
642             } else {
643             ssize_t entrySize, i;
644              
645 0           RETVAL = NULL;
646 0 0         if ( (entrySize = bpc_attrib_getEntries(dir, NULL, 0)) > 0 ) {
647 0           char *entries = malloc(entrySize), *p;
648              
649 0 0         if ( entries && bpc_attrib_getEntries(dir, entries, entrySize) > 0 ) {
    0          
650 0           HV *rh = newHV();
651 0 0         for ( i = 0, p = entries ; i < entrySize ; ) {
652 0           int len = strlen(p);
653             bpc_attrib_file *file;
654              
655 0           file = bpc_attrib_fileGet(dir, p, 0);
656 0           p += len + 1;
657 0           i += len + 1;
658 0 0         if ( !file ) continue;
659 0           (void)hv_store(rh, file->name, strlen(file->name), newRV_noinc((SV*)convert_file2hv(file, file->name)), 0);
660             }
661 0           RETVAL = newRV_noinc((SV*)rh);
662             }
663 0 0         if ( entries ) free(entries);
664             }
665 0 0         if ( !RETVAL ) XSRETURN_UNDEF;
666             }
667             }
668             OUTPUT:
669             RETVAL
670              
671             int
672             set(dir, fileName, hv)
673             BackupPC::XS::Attrib dir;
674             char *fileName;
675             HV *hv;
676             CODE:
677             {
678 0           bpc_attrib_file *file = bpc_attrib_fileGet(dir, fileName, 0);
679              
680 0           RETVAL = file ? 1 : 0;
681 0 0         if ( !file ) {
682 0           file = bpc_attrib_fileGet(dir, fileName, 1);
683 0           bpc_attrib_fileInit(file, fileName, 0);
684             }
685 0           convert_hv2file(hv, file);
686             }
687             OUTPUT:
688             RETVAL
689              
690             void
691             digest(dir)
692             BackupPC::XS::Attrib dir;
693             PREINIT:
694             PPCODE:
695             {
696 0           bpc_digest *digest = bpc_attrib_dirDigestGet(dir);
697 0 0         if ( digest && digest->len > 0 ) {
    0          
698 0 0         EXTEND(SP, 1);
699 0           PUSHs(sv_2mortal(newSVpvn((char*)digest->digest, digest->len)));
700             }
701             }
702              
703             void
704             iterate(dir, idx)
705             BackupPC::XS::Attrib dir;
706             unsigned int idx;
707             PREINIT:
708             bpc_attrib_file *file;
709             PPCODE:
710             {
711 0 0         if ( !bpc_attrib_fileIterate(dir, &file, &idx) && file ) {
    0          
712 0 0         EXTEND(SP, 2);
713 0           PUSHs(sv_2mortal(newRV_noinc((SV*)convert_file2hv(file, file->name))));
714 0           PUSHs(sv_2mortal(newSViv(idx)));
715             }
716             }
717              
718             char*
719             errStr(void)
720             CODE:
721 0           RETVAL = "TODO";
722             OUTPUT:
723             RETVAL
724              
725             int
726             count(dir)
727             BackupPC::XS::Attrib dir;
728             CODE:
729 0           RETVAL = bpc_attrib_fileCount(dir);
730             OUTPUT:
731             RETVAL
732              
733             void
734             delete(dir, fileName)
735             BackupPC::XS::Attrib dir;
736             char *fileName;
737             CODE:
738 0           bpc_attrib_fileDeleteName(dir, fileName);
739              
740             int
741             read(dir, dirPath, attribFileName = "attrib")
742             BackupPC::XS::Attrib dir;
743             char *dirPath;
744             char *attribFileName;
745             CODE:
746 0 0         if ( !*dirPath ) dirPath = NULL;
747 0           RETVAL = !bpc_attrib_dirRead(dir, dirPath, attribFileName, 0);
748             OUTPUT:
749             RETVAL
750              
751             int
752             write(dir, dirPath, attribFileName, d = NULL, deltaInfo = NULL)
753             BackupPC::XS::Attrib dir;
754             char *dirPath;
755             char *attribFileName;
756             SV *d;
757             BackupPC::XS::DeltaRefCnt deltaInfo;
758             CODE:
759 0 0         if ( !*dirPath ) dirPath = NULL;
760 0 0         if ( d && SvPOK(d) ) {
    0          
761             bpc_digest digest;
762             char *str;
763             STRLEN len;
764              
765 0 0         str = SvPV(d, len);
766 0 0         if ( 0 < len && len < sizeof(digest.digest) ) {
    0          
767 0           memcpy(digest.digest, str, len);
768 0           digest.len = len;
769 0           RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, &digest);
770             } else {
771 0           RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, NULL);
772             }
773             } else {
774 0           RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, NULL);
775             }
776             OUTPUT:
777             RETVAL
778              
779             char *
780             fileType2Text(type)
781             int type;
782             CODE:
783 0           RETVAL = bpc_attrib_fileType2Text(type);
784             OUTPUT:
785             RETVAL
786              
787             void
788             backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles)
789             int writeOldStyleAttribFile;
790             int keepOldAttribFiles;
791             CODE:
792 0           bpc_attrib_backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles);
793              
794             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::AttribCache
795              
796             BackupPC::XS::AttribCache
797             new(host, backupNum, shareNameUM, compress)
798             char *host;
799             int backupNum;
800             char *shareNameUM;
801             int compress;
802             CODE:
803             {
804 0           RETVAL = calloc(1, sizeof(bpc_attribCache_info));
805 0           bpc_attribCache_init(RETVAL, host, backupNum, shareNameUM, compress);
806             }
807             OUTPUT:
808             RETVAL
809              
810             void
811             DESTROY(ac)
812             BackupPC::XS::AttribCache ac;
813             CODE:
814             {
815 0           bpc_attribCache_destroy(ac);
816 0           free(ac);
817             }
818              
819             void
820             setDeltaInfo(ac, deltaInfo)
821             BackupPC::XS::AttribCache ac;
822             BackupPC::XS::DeltaRefCnt deltaInfo;
823             CODE:
824             {
825 0           bpc_attribCache_setDeltaInfo(ac, deltaInfo);
826             }
827              
828             SV*
829             get(ac, fileName, allocateIfMissing = 0, dontReadInode = 0)
830             BackupPC::XS::AttribCache ac;
831             char *fileName;
832             int allocateIfMissing;
833             int dontReadInode;
834             CODE:
835             {
836 0           bpc_attrib_file *file = bpc_attribCache_getFile(ac, fileName, allocateIfMissing, dontReadInode);
837              
838 0 0         if ( !file ) XSRETURN_UNDEF;
839              
840 0           RETVAL = newRV_noinc((SV*)convert_file2hv(file, file->name));
841             }
842             OUTPUT:
843             RETVAL
844              
845             int
846             set(ac, fileName, hv, dontOverwriteInode = 0)
847             BackupPC::XS::AttribCache ac;
848             char *fileName;
849             HV *hv;
850             int dontOverwriteInode;
851             CODE:
852             {
853 0           bpc_attrib_file *file = bpc_attribCache_getFile(ac, fileName, 1, 0);
854              
855 0           convert_hv2file(hv, file);
856 0           RETVAL = bpc_attribCache_setFile(ac, fileName, file, dontOverwriteInode);
857             }
858             OUTPUT:
859             RETVAL
860              
861             int
862             delete(ac, fileName)
863             BackupPC::XS::AttribCache ac;
864             char *fileName;
865             CODE:
866 0           RETVAL = bpc_attribCache_deleteFile(ac, fileName);
867             OUTPUT:
868             RETVAL
869              
870             SV*
871             getInode(ac, inode, allocateIfMissing = 0)
872             BackupPC::XS::AttribCache ac;
873             unsigned long inode;
874             int allocateIfMissing;
875             CODE:
876             {
877 0           bpc_attrib_file *file = bpc_attribCache_getInode(ac, inode, allocateIfMissing);
878              
879 0 0         if ( !file ) XSRETURN_UNDEF;
880              
881 0           RETVAL = newRV_noinc((SV*)convert_file2hv(file, file->name));
882             }
883             OUTPUT:
884             RETVAL
885              
886             int
887             setInode(ac, inode, hv)
888             BackupPC::XS::AttribCache ac;
889             unsigned long inode;
890             HV *hv;
891             CODE:
892             {
893 0           bpc_attrib_file *file = bpc_attribCache_getInode(ac, inode, 1);
894              
895 0           convert_hv2file(hv, file);
896 0           RETVAL = bpc_attribCache_setInode(ac, inode, file);
897             }
898             OUTPUT:
899             RETVAL
900              
901             int
902             deleteInode(ac, inode)
903             BackupPC::XS::AttribCache ac;
904             unsigned long inode;
905             CODE:
906 0           RETVAL = bpc_attribCache_deleteInode(ac, inode);
907             OUTPUT:
908             RETVAL
909              
910             int
911             count(ac, path)
912             BackupPC::XS::AttribCache ac;
913             char *path;
914             CODE:
915 0           RETVAL = bpc_attribCache_getDirEntryCnt(ac, path);
916             OUTPUT:
917             RETVAL
918              
919             SV*
920             getAll(ac, path, dontReadInode = 0)
921             BackupPC::XS::AttribCache ac;
922             char *path;
923             int dontReadInode;
924             CODE:
925             {
926             ssize_t entrySize, i;
927             char pathCopy[BPC_MAXPATHLEN];
928              
929 0           snprintf(pathCopy, sizeof(pathCopy), "%s", path);
930 0           RETVAL = NULL;
931 0 0         if ( (entrySize = bpc_attribCache_getDirEntries(ac, pathCopy, NULL, 0)) > 0 ) {
932 0           char *entries = malloc(entrySize), *p;
933              
934 0 0         if ( entries && bpc_attribCache_getDirEntries(ac, pathCopy, entries, entrySize) > 0 ) {
    0          
935 0           HV *rh = newHV();
936 0 0         for ( i = 0, p = entries ; i < entrySize ; ) {
937 0           int len = strlen(p);
938 0           char *fileNameSave = p;
939             char filePath[BPC_MAXPATHLEN];
940             bpc_attrib_file *file;
941              
942 0           snprintf(filePath, sizeof(filePath), "%s/%s", path, p);
943 0           file = bpc_attribCache_getFile(ac, filePath, 0, dontReadInode);
944 0           p += len + 1 + sizeof(ino_t);
945 0           i += len + 1 + sizeof(ino_t);
946 0 0         if ( !file ) continue;
947             /* printf("Storing file name %s for path %s\n", fileNameSave, path); */
948 0           (void)hv_store(rh, fileNameSave, strlen(fileNameSave), newRV_noinc((SV*)convert_file2hv(file, fileNameSave)), 0);
949             }
950 0           RETVAL = newRV_noinc((SV*)rh);
951             }
952 0 0         if ( entries ) free(entries);
953             }
954 0 0         if ( !RETVAL ) XSRETURN_UNDEF;
955             }
956             OUTPUT:
957             RETVAL
958              
959             void
960             flush(ac, all = 1, path = NULL)
961             BackupPC::XS::AttribCache ac;
962             int all
963             char *path;
964             CODE:
965 0           bpc_attribCache_flush(ac, all, path);
966              
967             SV*
968             getFullMangledPath(ac, dirName)
969             BackupPC::XS::AttribCache ac;
970             char *dirName;
971             CODE:
972             {
973             char path[BPC_MAXPATHLEN];
974 0           bpc_attribCache_getFullMangledPath(ac, path, dirName, -1);
975 0           RETVAL = newSVpvn(path, strlen(path));
976             }
977             OUTPUT:
978             RETVAL
979              
980             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::DirOps
981              
982             int
983             path_create(path)
984             char *path;
985             CODE:
986 0           RETVAL = bpc_path_create(path);
987             OUTPUT:
988             RETVAL
989              
990             int
991             path_remove(path, compress, deltaInfo = NULL)
992             char *path;
993             int compress;
994             BackupPC::XS::DeltaRefCnt deltaInfo;
995             CODE:
996 0           RETVAL = bpc_path_remove(deltaInfo, path, compress);
997             OUTPUT:
998             RETVAL
999              
1000             int
1001             refCountAll(path, compress, incr = 1, deltaInfo = NULL)
1002             char *path;
1003             int compress;
1004             int incr;
1005             BackupPC::XS::DeltaRefCnt deltaInfo;
1006             CODE:
1007 0           RETVAL = bpc_path_refCountAll(deltaInfo, path, compress, incr);
1008             OUTPUT:
1009             RETVAL
1010              
1011             void
1012             refCountAllInodeMax(path, compress, incr = 1, deltaInfo = NULL)
1013             char *path;
1014             int compress;
1015             int incr;
1016             BackupPC::XS::DeltaRefCnt deltaInfo;
1017             PREINIT:
1018             int retVal;
1019 0           unsigned int inodeMax = 0;
1020             PPCODE:
1021             {
1022 0           retVal = bpc_path_refCountAllInodeMax(deltaInfo, path, compress, incr, &inodeMax);
1023 0 0         EXTEND(SP, 2);
1024 0           PUSHs(sv_2mortal(newSViv(retVal)));
1025 0           PUSHs(sv_2mortal(newSViv(inodeMax)));
1026             }
1027              
1028             int
1029             lockRangeFd(fd, offset, len, block)
1030             int fd;
1031             unsigned int offset;
1032             unsigned int len;
1033             int block;
1034             CODE:
1035 0           RETVAL = bpc_lockRangeFd(fd, offset, len, block);
1036             OUTPUT:
1037             RETVAL
1038              
1039             int
1040             unlockRangeFd(fd, offset, len)
1041             int fd;
1042             unsigned int offset;
1043             unsigned int len;
1044             CODE:
1045 0           RETVAL = bpc_unlockRangeFd(fd, offset, len);
1046             OUTPUT:
1047             RETVAL
1048              
1049             int
1050             lockRangeFile(lockFile, offset, len, block)
1051             char *lockFile;
1052             unsigned int offset;
1053             unsigned int len;
1054             int block;
1055             CODE:
1056 0           RETVAL = bpc_lockRangeFile(lockFile, offset, len, block);
1057             OUTPUT:
1058             RETVAL
1059              
1060             void
1061             unlockRangeFile(lockFd)
1062             int lockFd;
1063             CODE:
1064 0           bpc_unlockRangeFile(lockFd);
1065            
1066             MODULE = BackupPC::XS PACKAGE = BackupPC::XS::Lib
1067              
1068             void
1069             ConfInit(topDir, hardLinkMax, poolV3Enabled, logLevel = 0)
1070             char *topDir;
1071             int hardLinkMax;
1072             int poolV3Enabled;
1073             int logLevel;
1074             CODE:
1075 0           bpc_lib_conf_init(topDir, hardLinkMax, poolV3Enabled, logLevel);
1076              
1077             SV*
1078             logMsgGet()
1079             CODE:
1080             {
1081             char *mesg, *p;
1082             size_t mesgLen, i;
1083             AV *ra;
1084              
1085 0           RETVAL = NULL;
1086 0           bpc_logMsgGet(&mesg, &mesgLen);
1087 0 0         if ( mesgLen == 0 ) XSRETURN_UNDEF;
1088              
1089 0           ra = newAV();
1090 0 0         for ( i = 0, p = mesg ; i < mesgLen ; ) {
1091 0           int len = strlen(p);
1092              
1093 0           av_push(ra, newSVpvn(p, len));
1094 0           p += len + 1;
1095 0           i += len + 1;
1096             }
1097 0           RETVAL = newRV_noinc((SV*)ra);
1098             }
1099             OUTPUT:
1100             RETVAL
1101              
1102             int
1103             logErrorCntGet()
1104             CODE:
1105             {
1106             unsigned long errorCnt;
1107 0           bpc_logMsgErrorCntGet(&errorCnt);
1108 0           RETVAL = errorCnt;
1109             }
1110             OUTPUT:
1111             RETVAL
1112              
1113             void
1114             logLevelSet(logLevel)
1115             int logLevel;
1116             CODE:
1117 0           bpc_lib_setLogLevel(logLevel);