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 )