BackupPC-XS

 view release on metacpan or  search on metacpan

BackupPC_XS.xs  view on Meta::CPAN

/*
 * XS glue for perl interface to BackupPC libraries.
 *
 * Copyright (C) 2013 Craig Barratt.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, visit the http://fsf.org website.
 */


#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include <backuppc.h>

typedef bpc_fileZIO_fd          *BackupPC__XS__FileZIO;
typedef bpc_refCount_info       *BackupPC__XS__PoolRefCnt;
typedef bpc_deltaCount_info     *BackupPC__XS__DeltaRefCnt;
typedef bpc_poolWrite_info      *BackupPC__XS__PoolWrite;
typedef bpc_attrib_dir          *BackupPC__XS__Attrib;
typedef bpc_attribCache_info    *BackupPC__XS__AttribCache;

#define hv_get_int(hv, key, value)       { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvIV(*svp); }
#define hv_get_uint(hv, key, value)      { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvUV(*svp); }
#define hv_get_str(hv, key, value, len)  { SV** svp = hv_fetch((hv), (key), strlen(key), 0); if ( svp && *svp ) (value) = SvPV(*svp, len); }

static HV* convert_file2hv(bpc_attrib_file *file, char *fileName)
{
    HV *rh;
    size_t listLen, i;

    rh = newHV();
    (void)hv_store(rh, "uid", 3,      newSVuv(file->uid), 0);
    (void)hv_store(rh, "gid", 3,      newSVuv(file->gid), 0);
    (void)hv_store(rh, "name", 4,     newSVpvn(fileName, strlen(fileName)), 0);
    (void)hv_store(rh, "type", 4,     newSVuv(file->type), 0);
    (void)hv_store(rh, "mode", 4,     newSVuv(file->mode), 0);
    (void)hv_store(rh, "size", 4,     newSVuv(file->size), 0);
    (void)hv_store(rh, "mtime", 5,    newSViv(file->mtime), 0);
    (void)hv_store(rh, "inode", 5,    newSVuv(file->inode), 0);
    (void)hv_store(rh, "nlinks", 6,   newSVuv(file->nlinks), 0);
    (void)hv_store(rh, "digest", 6,   newSVpvn((char*)file->digest.digest, file->digest.len), 0);
    (void)hv_store(rh, "compress", 8, newSVuv(file->compress), 0);

    if ( (listLen = bpc_attrib_xattrList(file, NULL, 0, 0)) > 0 ) {
        char *keys = malloc(listLen), *p;

        if ( keys && bpc_attrib_xattrList(file, keys, listLen, 0) > 0 ) {
            HV *rhAttr = newHV();
            for ( i = 0, p = keys ; i < listLen ; ) {
                int len = strlen(p);
                /*
                 * xattr keys include the \0 terminating byte in the length, so add 1 here,
                 * and subtract 1 in the hv_store() below.
                 */
                bpc_attrib_xattr *xattr = bpc_attrib_xattrGet(file, p, len + 1, 0);
                p += len + 1;
                i += len + 1;
                if ( !xattr ) continue;
                (void)hv_store(rhAttr, xattr->key.key, xattr->key.keyLen - 1, newSVpvn(xattr->value, xattr->valueLen), 0);
            }
            (void)hv_store(rh, "xattr", 5, newRV_noinc((SV*)rhAttr), 0);
        }
        if ( keys ) free(keys);
    }
    return rh;
}

static void convert_hv2file(HV *hv, bpc_attrib_file *file)
{
    char *digestStr = "";
    STRLEN digestLen = 0;
    SV** svp;

    hv_get_uint(hv, "uid", file->uid);
    hv_get_uint(hv, "gid", file->gid);
    hv_get_uint(hv, "type", file->type);
    hv_get_uint(hv, "mode", file->mode);
    hv_get_uint(hv, "size", file->size);
    hv_get_int(hv, "mtime", file->mtime);
    hv_get_uint(hv, "inode", file->inode);
    hv_get_uint(hv, "nlinks", file->nlinks);
    hv_get_uint(hv, "compress", file->compress);
    hv_get_str(hv,  "digest", digestStr, digestLen);
    if ( 0 < digestLen && digestLen <= sizeof(file->digest.digest) ) {
        memcpy(file->digest.digest, digestStr, digestLen);
        file->digest.len = digestLen;
    } else {
        file->digest.len = 0;
    }
    if ( (svp = hv_fetch(hv, "xattr", 5, 0)) && *svp ) {
        if ( SvTYPE(SvRV(*svp)) != SVt_PVHV ) {
            bpc_attrib_xattrDeleteAll(file);
        } else {
            HE *he;
            HV *hvXattr = (HV*)SvRV(*svp);
            /*
             * clear out the old xattrs, and copy in the new
             */
            bpc_attrib_xattrDeleteAll(file);
            hv_iterinit(hvXattr);
            while ( (he = hv_iternext(hvXattr)) ) {
                I32 keyLen;
                STRLEN valueLen;
                char *key = hv_iterkey(he, &keyLen), *value;
                SV *valSV = hv_iterval(hvXattr, he);

                value = SvPV(valSV, valueLen);
                bpc_attrib_xattrSetValue(file, key, keyLen + 1, value, valueLen);
            }
        }
    }
}

MODULE = BackupPC::XS		PACKAGE = BackupPC::XS::FileZIO

PROTOTYPES: DISABLE

BackupPC::XS::FileZIO
open(fileName, writeFile, compressLevel)
        char *fileName;
        int writeFile;
        int compressLevel;
    CODE:
    {
        RETVAL = calloc(1, sizeof(bpc_fileZIO_fd));
        if ( bpc_fileZIO_open(RETVAL, fileName, writeFile, compressLevel) < 0 ) {
            free(RETVAL);
            XSRETURN_UNDEF;
        }
    }
    OUTPUT:
        RETVAL

BackupPC::XS::FileZIO
fdopen(stream, writeFile, compressLevel)



( run in 1.541 second using v1.01-cache-2.11-cpan-97f6503c9c8 )