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;

BackupPC_XS.xs  view on Meta::CPAN

    CODE:
        bpc_attrib_fileDeleteName(dir, fileName);

int
read(dir, dirPath, attribFileName = "attrib")
        BackupPC::XS::Attrib dir;
        char *dirPath;
        char *attribFileName;
    CODE:
        if ( !*dirPath ) dirPath = NULL;
        RETVAL = !bpc_attrib_dirRead(dir, dirPath, attribFileName, 0);
    OUTPUT:
        RETVAL

int
write(dir, dirPath, attribFileName, d = NULL, deltaInfo = NULL)
        BackupPC::XS::Attrib dir;
        char *dirPath;
        char *attribFileName;
        SV *d;
        BackupPC::XS::DeltaRefCnt deltaInfo;
    CODE:
        if ( !*dirPath ) dirPath = NULL;
        if ( d && SvPOK(d) ) {
            bpc_digest digest;
            char *str;
            STRLEN len;

            str = SvPV(d, len);
            if ( 0 < len && len < sizeof(digest.digest) ) {
                memcpy(digest.digest, str, len);
                digest.len = len;
                RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, &digest);
            } else {
                RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, NULL);
            }
        } else {
            RETVAL = !bpc_attrib_dirWrite(deltaInfo, dir, dirPath, attribFileName, NULL);
        }
    OUTPUT:
        RETVAL

char *
fileType2Text(type)
        int type;
    CODE:
        RETVAL = bpc_attrib_fileType2Text(type);
    OUTPUT:
        RETVAL

void
backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles)
        int writeOldStyleAttribFile;
        int keepOldAttribFiles;
    CODE:
        bpc_attrib_backwardCompat(writeOldStyleAttribFile, keepOldAttribFiles);

MODULE = BackupPC::XS		PACKAGE = BackupPC::XS::AttribCache

BackupPC::XS::AttribCache
new(host, backupNum, shareNameUM, compress)
        char *host;
        int backupNum;
        char *shareNameUM;
        int compress;
    CODE:
    {
        RETVAL = calloc(1, sizeof(bpc_attribCache_info));
        bpc_attribCache_init(RETVAL, host, backupNum, shareNameUM, compress);
    }
    OUTPUT:
        RETVAL

void
DESTROY(ac)
        BackupPC::XS::AttribCache ac;
    CODE:
    {
        bpc_attribCache_destroy(ac);
        free(ac);
    }

void
setDeltaInfo(ac, deltaInfo)
        BackupPC::XS::AttribCache ac;
        BackupPC::XS::DeltaRefCnt deltaInfo;
    CODE:
    {
        bpc_attribCache_setDeltaInfo(ac, deltaInfo);
    }

SV*
get(ac, fileName, allocateIfMissing = 0, dontReadInode = 0)
        BackupPC::XS::AttribCache ac;
        char *fileName;
        int allocateIfMissing;
        int dontReadInode;
    CODE:
    {
        bpc_attrib_file *file = bpc_attribCache_getFile(ac, fileName, allocateIfMissing, dontReadInode);

        if ( !file ) XSRETURN_UNDEF;

        RETVAL = newRV_noinc((SV*)convert_file2hv(file, file->name));
    }
    OUTPUT:
        RETVAL

int
set(ac, fileName, hv, dontOverwriteInode = 0)
        BackupPC::XS::AttribCache ac;
        char *fileName;
        HV *hv;
        int dontOverwriteInode;
    CODE:
    {
        bpc_attrib_file *file = bpc_attribCache_getFile(ac, fileName, 1, 0);

        convert_hv2file(hv, file);
        RETVAL = bpc_attribCache_setFile(ac, fileName, file, dontOverwriteInode);
    }
    OUTPUT:
        RETVAL

int
delete(ac, fileName)
        BackupPC::XS::AttribCache ac;
        char *fileName;
    CODE:



( run in 0.622 second using v1.01-cache-2.11-cpan-39bf76dae61 )