BackupPC-XS

 view release on metacpan or  search on metacpan

bpc_attrib.c  view on Meta::CPAN

        bufP += keyLen + valueLen;
    }
    return bufP;
}

/*
 * Extract an entire packed file structure, starting with the fileName length varint.
 * Returns next unused buffer location.  It is assumed the file structure is already
 * initialized and has a valid fileName allocated, so we don't allocate it here.
 *
 * If there isn't enough data to extract a complete file structure, the return value
 * will be greater than bufEnd.  You should gather more data and re-call the function.
 * On certain errors, returns NULL;
 */
uchar *bpc_attrib_buf2fileFull(bpc_attrib_file *file, uchar *bufP, uchar *bufEnd)
{
    uint fileNameLen, xattrNumEntries;

    fileNameLen = getVarInt(&bufP, bufEnd);
    if ( fileNameLen > BPC_MAXPATHLEN - 1 ) {
        bpc_logErrf("bpc_attrib_buf2fileFull: got unreasonable file name length %d\n", fileNameLen);
        return NULL;
    }
    bufP += fileNameLen;
    bpc_attrib_xattrDeleteAll(file);
    xattrNumEntries = getVarInt(&bufP, bufEnd);
    if ( BPC_LogLevel >= 6 ) bpc_logMsgf("bpc_attrib_buf2fileFull: xattrNumEntries = %d\n", xattrNumEntries);
    bufP = bpc_attrib_buf2file(file, bufP, bufEnd, xattrNumEntries, NULL);
    return bufP;
}

/*
 * Read the attribute file at dirPath/attribFilePath and populate dir
 */
int bpc_attrib_dirRead(bpc_attrib_dir *dir, char *dirPath, char *attribFilePath, int backupNum)
{
    char attribPath[BPC_MAXPATHLEN];
    bpc_fileZIO_fd fd;
    size_t nRead;
    uint32 magic = 0;
    uchar buf[8 * 65536], *bufP;
    STRUCT_STAT st;
    char *p, *attribFileName;

    bpc_attrib_attribFilePath(attribPath, dirPath, attribFilePath);
    dir->digest.len = 0;

    /*
     * attribFileName points to the last portion of attribFilePath, or the whole
     * string if it doesn't contain '/'
     */
    if ( (attribFileName = strrchr(attribFilePath, '/')) ) {
        attribFileName++;
    } else {
        attribFileName = attribFilePath;
    }

    if ( BPC_LogLevel >= 6 ) bpc_logMsgf("bpc_attrib_dirRead(%s); dirPath = %s, attribFilePath = %s, attribFileName = %s\n",
                                         attribPath, dirPath, attribFilePath, attribFileName);

    if ( (p = strchr(attribFileName, '_')) && !stat(attribPath, &st) && S_ISREG(st.st_mode) ) {
        /*
         * Explicit path name to new-style attrib file, and it exists; extract digest
         */
        if ( !strcmp(p + 1, "0") ) return 0;
        bpc_digest_str2digest(&dir->digest, p + 1);
        if ( BPC_LogLevel >= 6 ) {
            char str[256];
            bpc_digest_digest2str(&dir->digest, str);
            bpc_logMsgf("bpc_attrib_dirRead: called with attrib file %s: digest = %s, len = %d\n",
                                              attribPath, str, dir->digest.len);
        }
        /*
         * Write new type attrib files (since we found a new-style one)
         */
	WriteOldStyleAttribFile = 0;
        magic = BPC_ATTRIB_TYPE_XATTR;
    } else if ( stat(attribPath, &st) || !S_ISREG(st.st_mode) || strchr(attribFileName, '_') ) {
        DIR *dirOs;
        struct dirent *dp;
        int attribFileNameLen = strlen(attribFileName);
        char attribDirPath[BPC_MAXPATHLEN];
        /*
         * Starting in 0.50, the attrib files are zero length with the digest encoded in
         * the file name, so there is no file just called "attrib".  Look in the directory
         * to find it.
         */
        strcpy(attribDirPath, attribPath);
        if ( (p = strrchr(attribDirPath, '/')) ) {
            *p = '\0';
        } else {
            strcpy(attribDirPath, ".");
        }
	if ( !(dirOs = opendir(attribDirPath)) ) {
            /*
             * This is a benign error - just return as though there is an empty attrib file
             */
            if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attrib_dirRead: can't opendir %s (note: this is ok)\n", attribDirPath);
	    return 0;
	}
	while ( (dp = readdir(dirOs)) ) {
	    if ( strncmp(dp->d_name, attribFileName, attribFileNameLen) ) continue;
            p = dp->d_name + attribFileNameLen;
            if ( p[0] != '_' ) continue;
            p++;
	    if ( !strcmp(p, "0") ) {
                /*
                 * An empty attrib file is legit; just return with no entries
                 */
                if ( BPC_LogLevel >= 6 ) {
                    bpc_logMsgf("bpc_attrib_dirRead: Got empty attrib file %s\n", dp->d_name);
                }
		closedir(dirOs);
		return 0;
	    }
            bpc_digest_str2digest(&dir->digest, p);
            if ( BPC_LogLevel >= 6 ) {
                char str[256];
                bpc_digest_digest2str(&dir->digest, str);
                bpc_logMsgf("bpc_attrib_dirRead: Got attrib file %s: digest = %s, len = %d\n",
                                                  dp->d_name, str, dir->digest.len);
            }
            /*
             * Write new type attrib files (since we found a new-style one)
             */
            WriteOldStyleAttribFile = 0;
            break;
	}
	closedir(dirOs);
        if ( dir->digest.len == 0 ) return 0;
        magic = BPC_ATTRIB_TYPE_XATTR;
    } else {
        if ( bpc_fileZIO_open(&fd, attribPath, 0, dir->compress) ) {
            bpc_logErrf("bpc_attrib_dirRead: can't open %s\n", attribPath);
            return -1;
        }
        nRead = bpc_fileZIO_read(&fd, buf, sizeof(buf));
        if ( nRead == 0 ) {



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