Archiving support using Libarchive: Work in progress changes.

Change all perror() calls to use logger.
Make the config script a little verbose.
This commit is contained in:
Moinak Ghosh 2013-10-20 23:54:27 +05:30
parent 28fd9848f9
commit 7f81869874
13 changed files with 477 additions and 146 deletions

View file

@ -28,9 +28,9 @@ LINKLIB=pcompress
LIBVER=1 LIBVER=1
MAINSRCS = utils/utils.c allocator.c lzma_compress.c ppmd_compress.c \ MAINSRCS = utils/utils.c allocator.c lzma_compress.c ppmd_compress.c \
adaptive_compress.c lzfx_compress.c lz4_compress.c none_compress.c \ adaptive_compress.c lzfx_compress.c lz4_compress.c none_compress.c \
utils/xxhash_base.c utils/heap.c utils/cpuid.c pcompress.c utils/xxhash_base.c utils/heap.c utils/cpuid.c archive/pc_archive.c pcompress.c
MAINHDRS = allocator.h pcompress.h utils/utils.h utils/xxhash.h utils/heap.h \ MAINHDRS = allocator.h pcompress.h utils/utils.h utils/xxhash.h utils/heap.h \
utils/cpuid.h utils/xxhash.h utils/cpuid.h utils/xxhash.h archive/pc_archive.h
MAINOBJS = $(MAINSRCS:.c=.o) MAINOBJS = $(MAINSRCS:.c=.o)
PROGSRCS = main.c PROGSRCS = main.c
@ -182,7 +182,8 @@ KECCAK_OBJS_ASM = $(KECCAK_SRCS_ASM:.s=.o)
BAKFILES = *~ lzma/*~ lzfx/*~ lz4/*~ rabin/*~ bsdiff/*~ lzp/*~ utils/*~ crypto/sha2/*~ \ BAKFILES = *~ lzma/*~ lzfx/*~ lz4/*~ rabin/*~ bsdiff/*~ lzp/*~ utils/*~ crypto/sha2/*~ \
crypto/sha2/intel/*~ crypto/aes/*~ crypto/scrypt/*~ crypto/*~ rabin/global/*~ \ crypto/sha2/intel/*~ crypto/aes/*~ crypto/scrypt/*~ crypto/*~ rabin/global/*~ \
delta2/*~ crypto/keccak/*~ transpose/*~ crypto/skein/*~ crypto/keccak/*.o delta2/*~ crypto/keccak/*~ transpose/*~ crypto/skein/*~ crypto/keccak/*.o \
archive/*~
RM = rm -f RM = rm -f
RM_RF = rm -rf RM_RF = rm -rf
@ -191,14 +192,14 @@ COMMON_CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -DNODEFAULT
-I./lzp @LIBBSCCPPFLAGS@ -I./crypto/skein -I./utils -I./crypto/sha2 \ -I./lzp @LIBBSCCPPFLAGS@ -I./crypto/skein -I./utils -I./crypto/sha2 \
-I./crypto/scrypt -I./crypto/aes -I./crypto @KEYLEN@ -I./rabin/global \ -I./crypto/scrypt -I./crypto/aes -I./crypto @KEYLEN@ -I./rabin/global \
-I./crypto/keccak -I./transpose -I./crypto/blake2 $(EXTRA_CPPFLAGS) \ -I./crypto/keccak -I./transpose -I./crypto/blake2 $(EXTRA_CPPFLAGS) \
-I./crypto/xsalsa20 -pedantic -Wall -std=gnu99 \ -I./crypto/xsalsa20 -I./archive -pedantic -Wall -std=gnu99 \
-fno-strict-aliasing -Wno-unused-but-set-variable -Wno-enum-compare \ -fno-strict-aliasing -Wno-unused-but-set-variable -Wno-enum-compare \
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ @COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ -I@LIBARCHIVE_INC@
COMMON_VEC_FLAGS = -ftree-vectorize COMMON_VEC_FLAGS = -ftree-vectorize
COMMON_LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block COMMON_LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block
LDLIBS = -ldl -L./buildtmp -Wl,-R@LIBBZ2_DIR@ -lbz2 -L./buildtmp -Wl,-R@LIBZ_DIR@ -lz -lm @LIBBSCLFLAGS@ \ LDLIBS = -ldl -L./buildtmp -Wl,-R@LIBBZ2_DIR@ -lbz2 -L./buildtmp -Wl,-R@LIBZ_DIR@ -lz -lm @LIBBSCLFLAGS@ \
-L./buildtmp -Wl,-R@OPENSSL_LIBDIR@ -lcrypto -lrt $(EXTRA_LDFLAGS) -Wl,-R/usr/lib,--enable-new-dtags \ -L./buildtmp -Wl,-R@OPENSSL_LIBDIR@ -lcrypto -lrt -Wl,-R@LIBARCHIVE_DIR@ -larchive $(EXTRA_LDFLAGS) \
-Wl,-R/usr/lib64,--enable-new-dtags -Wl,-R/usr/lib,--enable-new-dtags -Wl,-R/usr/lib64,--enable-new-dtags
OBJS = $(MAINOBJS) $(LZMAOBJS) $(PPMDOBJS) $(LZFXOBJS) $(LZ4OBJS) $(CRCOBJS) \ OBJS = $(MAINOBJS) $(LZMAOBJS) $(PPMDOBJS) $(LZFXOBJS) $(LZ4OBJS) $(CRCOBJS) \
$(RABINOBJS) $(BSDIFFOBJS) $(LZPOBJS) $(DELTA2OBJS) @LIBBSCWRAPOBJ@ $(SKEINOBJS) \ $(RABINOBJS) $(BSDIFFOBJS) $(LZPOBJS) $(DELTA2OBJS) @LIBBSCWRAPOBJ@ $(SKEINOBJS) \
$(SKEIN_BLOCK_OBJ) @SHA2ASM_OBJS@ @SHA2_OBJS@ $(KECCAK_OBJS) $(KECCAK_OBJS_ASM) \ $(SKEIN_BLOCK_OBJ) @SHA2ASM_OBJS@ @SHA2_OBJS@ $(KECCAK_OBJS) $(KECCAK_OBJS_ASM) \

View file

@ -32,9 +32,6 @@ Pcompress also supports encryption via AES and uses Scrypt from Tarsnap
for Password Based Key generation. A unique key is generated per session for Password Based Key generation. A unique key is generated per session
even if the same password is used and HMAC is used to do authentication. even if the same password is used and HMAC is used to do authentication.
NOTE: This utility is Not an archiver. It compresses only single files or
datastreams. To archive use something else like tar, cpio or pax.
Links of Interest Links of Interest
================= =================

177
archive/pc_archive.c Normal file
View file

@ -0,0 +1,177 @@
/*
* This file is a part of Pcompress, a chunked parallel multi-
* algorithm lossless compression and decompression program.
*
* Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved.
* Use is subject to license terms.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <utils.h>
#include <archive.h>
#include "pc_archive.h"
#undef _FEATURES_H
#define _XOPEN_SOURCE 700
#include <ftw.h>
#include <stdint.h>
#define ARC_ENTRY_OVRHEAD 500
static struct arc_list_state {
uchar_t *pbuf;
uint64_t bufsiz, bufpos, arc_size;
int fd;
} a_state;
pthread_mutex_t nftw_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Build list of pathnames in a temp file.
*/
static int
add_pathname(const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf)
{
short len;
uchar_t *buf;
if (tflag == FTW_DP) return (0);
if (tflag == FTW_DNR || tflag == FTW_NS) {
log_msg(LOG_WARN, 0, "Cannot access %s\n", fpath);
return (0);
}
a_state.arc_size += (sb->st_size + ARC_ENTRY_OVRHEAD);
len = strlen(fpath);
if (a_state.bufpos + len + 14 > a_state.bufsiz) {
ssize_t wrtn = Write(a_state.fd, a_state.pbuf, a_state.bufpos);
if (wrtn < a_state.bufpos) {
log_msg(LOG_ERR, 1, "Write: ");
return (-1);
}
a_state.bufpos = 0;
}
buf = a_state.pbuf + a_state.bufpos;
*((short *)buf) = len;
buf += 2;
memcpy(buf, fpath, len);
buf += len;
*((int *)buf) = tflag;
buf += 4;
*((uint64_t *)buf) = sb->st_size;
a_state.bufpos += (len + 14);
return (0);
}
/*
* Archiving related functions.
* This one creates a list of files to be included into the archive and
* sets up the libarchive context.
*/
int
setup_archive(pc_ctx_t *pctx, struct stat *sbuf)
{
char *tmpfile, *tmp;
int err, fd, pipefd[2];
uchar_t *pbuf;
struct archive *arc;
tmpfile = pctx->archive_members_file;
tmp = get_temp_dir();
strcpy(tmpfile, tmp);
free(tmp);
strcat(tmpfile, "/.pcompXXXXXX");
if ((fd = mkstemp(tmpfile)) == -1) {
log_msg(LOG_ERR, 1, "mkstemp errored.");
return (-1);
}
add_fname(tmpfile);
pbuf = malloc(pctx->chunksize);
if (pbuf == NULL) {
log_msg(LOG_ERR, 0, "Out of memory.");
close(fd); unlink(tmpfile);
return (-1);
}
/*
* nftw requires using global state variable. So we lock to be mt-safe.
* This means only one directory tree scan can happen at a time.
*/
pthread_mutex_lock(&nftw_mutex);
a_state.pbuf = pbuf;
a_state.bufsiz = pctx->chunksize;
a_state.bufpos = 0;
a_state.arc_size = 0;
a_state.fd = fd;
err = nftw(pctx->filename, add_pathname, 1024, FTW_PHYS); // 'pctx->filename' has dir name here
if (a_state.bufpos > 0) {
ssize_t wrtn = Write(a_state.fd, a_state.pbuf, a_state.bufpos);
if (wrtn < a_state.bufpos) {
log_msg(LOG_ERR, 1, "Write failed.");
close(fd); unlink(tmpfile);
return (-1);
}
a_state.bufpos = 0;
}
pctx->archive_size = a_state.arc_size;
sbuf->st_size = a_state.arc_size;
pthread_mutex_unlock(&nftw_mutex);
lseek(fd, 0, SEEK_SET);
free(pbuf);
if (pipe(pipefd) == -1) {
log_msg(LOG_ERR, 1, "Unable to create archiver pipe.\n");
close(fd); unlink(tmpfile);
return (-1);
}
pctx->uncompfd = pipefd[0]; // Read side
pctx->archive_data_fd = pipefd[1]; // Write side
arc = archive_write_new();
if (!arc) {
log_msg(LOG_ERR, 1, "Unable to create libarchive context.\n");
close(fd); close(pipefd[0]); close(pipefd[1]);
unlink(tmpfile);
return (-1);
}
archive_write_set_format_pax_restricted(arc);
archive_write_open_fd(arc, pctx->archive_data_fd);
pctx->archive_ctx = arc;
return (0);
}
/*
* Thread function. Archive members and write to pipe. The dispatcher thread
* reads from the other end and compresses.
*/
void *
run_archiver(void *dat) {
return (NULL);
}

50
archive/pc_archive.h Normal file
View file

@ -0,0 +1,50 @@
/*
* This file is a part of Pcompress, a chunked parallel multi-
* algorithm lossless compression and decompression program.
*
* Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved.
* Use is subject to license terms.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
*
*/
#ifndef _ARCHIVE_H
#define _ARCHIVE_H
#include <pcompress.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char *fpath;
int typeflag;
size_t size;
} archive_list_entry_t;
/*
* Archiving related functions.
*/
int setup_archive(pc_ctx_t *pctx, struct stat *sbuf);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -76,7 +76,7 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05
#define __IN_BSDIFF__ #define __IN_BSDIFF__
#include "bscommon.h" #include "bscommon.h"
#define MIN(x,y) (((x)<(y)) ? (x) : (y)) #define BDIFF_MIN(x,y) (((x)<(y)) ? (x) : (y))
static void split(bsize_t *I,bsize_t *V,bsize_t start,bsize_t len,bsize_t h) static void split(bsize_t *I,bsize_t *V,bsize_t start,bsize_t len,bsize_t h)
{ {
@ -237,7 +237,7 @@ static bsize_t search(bsize_t *I,u_char *oldbuf,bsize_t oldsize,
}; };
x=st+(en-st)/2; x=st+(en-st)/2;
if(memcmp(oldbuf+I[x],newbuf,MIN(oldsize-I[x],newsize))<0) { if(memcmp(oldbuf+I[x],newbuf,BDIFF_MIN(oldsize-I[x],newsize))<0) {
return search(I,oldbuf,oldsize,newbuf,newsize,x,en,pos); return search(I,oldbuf,oldsize,newbuf,newsize,x,en,pos);
} else { } else {
return search(I,oldbuf,oldsize,newbuf,newsize,st,x,pos); return search(I,oldbuf,oldsize,newbuf,newsize,st,x,pos);

45
config
View file

@ -41,6 +41,8 @@ ${prog} [<options>]
Enable building against an alternate Zlib installation. Enable building against an alternate Zlib installation.
--with-bzlib=<path to Bzip2 library installation tree> (Default: System) --with-bzlib=<path to Bzip2 library installation tree> (Default: System)
Enable building against an alternate Bzip2 and library installation. Enable building against an alternate Bzip2 and library installation.
--with-libarchive=<path to libarchive installation tree> (Default: System)
Enable building against an alternate libarchive installation.
--no-sse-detect Do NOT attempt to probe the system's SSE/AVX capability for build flags. --no-sse-detect Do NOT attempt to probe the system's SSE/AVX capability for build flags.
--no-1.3-archive-compat Disable compatibility with compressed archives created with Pcompress --no-1.3-archive-compat Disable compatibility with compressed archives created with Pcompress
version 1.3 (default: retain compatibility). Hash formats changed from version 1.3 (default: retain compatibility). Hash formats changed from
@ -69,6 +71,7 @@ openssl_libdir=
openssl_incdir= openssl_incdir=
libbz2_libdir= libbz2_libdir=
libz_libdir= libz_libdir=
libarchive_libdir=
sha256asmobjs= sha256asmobjs=
sha256objs= sha256objs=
keylen= keylen=
@ -79,6 +82,7 @@ keccak_srcs_asm=
extra_opt_flags= extra_opt_flags=
zlib_prefix= zlib_prefix=
bzlib_prefix= bzlib_prefix=
libarchive_prefix=
sse_detect=1 sse_detect=1
sse_opt_flags="-msse2" sse_opt_flags="-msse2"
crypto_compat_objs='\$\(CRYPTO_COMPAT_OBJS\)' crypto_compat_objs='\$\(CRYPTO_COMPAT_OBJS\)'
@ -90,6 +94,7 @@ salsa20_debug=
rm -rf ./buildtmp rm -rf ./buildtmp
mkdir ./buildtmp mkdir ./buildtmp
echo "Checking for GCC ..."
# Try a simple compilation # Try a simple compilation
cat << _EOF > tst.c cat << _EOF > tst.c
#include <stdio.h> #include <stdio.h>
@ -115,6 +120,7 @@ then
fi fi
# Check bitness of system/toolchain # Check bitness of system/toolchain
echo "Checking for 32-bit/64-bit platform ..."
bitness=`./tst` bitness=`./tst`
if [ $bitness -lt 8 ] if [ $bitness -lt 8 ]
then then
@ -168,6 +174,9 @@ do
--with-bzlib=*) --with-bzlib=*)
bzlib_prefix=`echo ${arg1} | cut -f2 -d"="` bzlib_prefix=`echo ${arg1} | cut -f2 -d"="`
;; ;;
--with-libarchive=*)
libarchive_prefix=`echo ${arg1} | cut -f2 -d"="`
;;
--use-key256) --use-key256)
keylen='-DDEFAULT_KEYLEN=16' keylen='-DDEFAULT_KEYLEN=16'
;; ;;
@ -198,6 +207,7 @@ else
typ="RELEASE" typ="RELEASE"
fi fi
echo "Checking OS ..."
OS=$(uname) OS=$(uname)
skeinblock='\$\(SKEIN_BLOCK_C\)' skeinblock='\$\(SKEIN_BLOCK_C\)'
if [ "$OS" = "Linux" ] if [ "$OS" = "Linux" ]
@ -212,6 +222,7 @@ else
fi fi
# Check GCC version # Check GCC version
echo "Checking GCC version ..."
vers=`gcc -dumpversion` vers=`gcc -dumpversion`
OIFS="$IFS" OIFS="$IFS"
IFS=. IFS=.
@ -227,6 +238,7 @@ then
fi fi
# SSE Detection # SSE Detection
echo -n "Checking for CPU SSE version ... "
if [ $sse_detect -eq 1 ] if [ $sse_detect -eq 1 ]
then then
gcc -o sse_level ./utils/sse_level.c ./utils/cpuid.c -I./utils gcc -o sse_level ./utils/sse_level.c ./utils/cpuid.c -I./utils
@ -246,6 +258,7 @@ then
echo "" echo ""
exit 1 exit 1
fi fi
echo $sse_ver
rm -f sse_level rm -f sse_level
sse_opt_flags="-m${sse_ver}" sse_opt_flags="-m${sse_ver}"
fi fi
@ -260,6 +273,7 @@ then
# #
# Detect Yasm # Detect Yasm
# #
echo "Checking for Yasm ..."
for bindir in /bin /usr/bin /usr/local/bin for bindir in /bin /usr/bin /usr/local/bin
do do
if [ -x ${bindir}/yasm ] if [ -x ${bindir}/yasm ]
@ -297,6 +311,7 @@ else
fi fi
# Detect OpenSSL library # Detect OpenSSL library
echo "Checking for OpenSSL ..."
for lib in "${openssl_prefix}/lib64" "${openssl_prefix}/usr/lib64" \ for lib in "${openssl_prefix}/lib64" "${openssl_prefix}/usr/lib64" \
"${openssl_prefix}/lib" "${openssl_prefix}/usr/lib" \ "${openssl_prefix}/lib" "${openssl_prefix}/usr/lib" \
"${openssl_prefix}/ssl/lib64" "${openssl_prefix}/ssl/lib" \ "${openssl_prefix}/ssl/lib64" "${openssl_prefix}/ssl/lib" \
@ -354,6 +369,7 @@ fi
# Check for OpenSSL version # Check for OpenSSL version
echo "Checking OpenSSL version ..."
cat << __EOF > tst.c cat << __EOF > tst.c
#include <stdlib.h> #include <stdlib.h>
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
@ -381,6 +397,7 @@ then
fi fi
# Check for HMAC_CTX_copy function # Check for HMAC_CTX_copy function
echo -n "Checking if the OpenSSL library provides HMAC_CTX_copy function ... "
cat << __EOF > tst.c cat << __EOF > tst.c
#include <stdlib.h> #include <stdlib.h>
#include <openssl/sha.h> #include <openssl/sha.h>
@ -407,13 +424,16 @@ gcc ${extra_opt_flags} -I${openssl_incdir} -L${openssl_libdir} -O0 -g tst.c -o t
if [ $? -ne 0 ] if [ $? -ne 0 ]
then then
openssl_incdir="${openssl_incdir} -D__OSSL_OLD__" openssl_incdir="${openssl_incdir} -D__OSSL_OLD__"
echo "No. Using internal variant."
else
echo "Yes."
fi fi
rm -f tst* rm -f tst*
openssl_libdir="${openssl_libdir},--enable-new-dtags" openssl_libdir="${openssl_libdir},--enable-new-dtags"
# Detect other library packages # Detect other library packages
for libspec in "libbz2:${bzlib_prefix}" "libz:${zlib_prefix}" for libspec in "libbz2:${bzlib_prefix}" "libz:${zlib_prefix}" "libarchive:${libarchive_prefix}"
do do
_OIFS="$IFS" _OIFS="$IFS"
IFS=":" IFS=":"
@ -422,6 +442,7 @@ do
pref=$2 pref=$2
IFS="$_OIFS" IFS="$_OIFS"
echo "Checking for $libname ..."
use_prefix="${pref}" use_prefix="${pref}"
if [ "x${pref}" = "x" ] if [ "x${pref}" = "x" ]
then then
@ -477,10 +498,24 @@ then
exit 1 exit 1
fi fi
if [ "x${libarchive_libdir}" = "x" ]
then
if [ "x$libarchive_prefix" = "x" ]
then
echo "ERROR: Libarchive not detected."
echo " You may have to install libarchive-devel or libarchive-dev"
else
echo "ERROR: Libarchive not detected in given prefix."
fi
exit 1
fi
libbz2_inc= libbz2_inc=
libz_inc= libz_inc=
libarchive_inc=
# Detect other library headers # Detect other library headers
for hdr in "libbz2_inc:bzlib.h:${bzlib_prefix}" "libz_inc:zlib.h:${zlib_prefix}" for hdr in "libbz2_inc:bzlib.h:${bzlib_prefix}" "libz_inc:zlib.h:${zlib_prefix}" \
"libarchive_inc:archive.h:${libarchive_prefix}"
do do
_OIFS="$IFS" _OIFS="$IFS"
IFS=":" IFS=":"
@ -490,6 +525,7 @@ do
pref=$3 pref=$3
IFS="$_OIFS" IFS="$_OIFS"
echo "Checking for $hdrf ..."
use_prefix="${pref}" use_prefix="${pref}"
if [ "x${pref}" = "x" ] if [ "x${pref}" = "x" ]
then then
@ -510,6 +546,7 @@ do
done done
done done
echo "Generating Makefile ..."
linkvar="LINK" linkvar="LINK"
compilevar="COMPILE" compilevar="COMPILE"
compilecppvar="COMPILE_cpp" compilecppvar="COMPILE_cpp"
@ -542,6 +579,8 @@ libbz2libdirvar="LIBBZ2_DIR"
libzlibdirvar="LIBZ_DIR" libzlibdirvar="LIBZ_DIR"
libbz2incvar="LIBBZ2_INC" libbz2incvar="LIBBZ2_INC"
libzincvar="LIBZ_INC" libzincvar="LIBZ_INC"
libarchivedirvar="LIBARCHIVE_DIR"
libarchiveincvar="LIBARCHIVE_INC"
keccak_srcs_var="KECCAK_SRCS" keccak_srcs_var="KECCAK_SRCS"
keccak_hdrs_var="KECCAK_HDRS" keccak_hdrs_var="KECCAK_HDRS"
@ -599,5 +638,7 @@ s#@${crypto_compat_flags_var}@#${crypto_compat_flags}#g
s#@${salsa20_stream_c_var}@#${salsa20_stream_c}#g s#@${salsa20_stream_c_var}@#${salsa20_stream_c}#g
s#@${salsa20_stream_asm_var}@#${salsa20_stream_asm}#g s#@${salsa20_stream_asm_var}@#${salsa20_stream_asm}#g
s#@${salsa20_debug_var}@#${salsa20_debug}#g s#@${salsa20_debug_var}@#${salsa20_debug}#g
s#@${libarchivedirvar}@#${libarchive_libdir}#g
s#@${libarchiveincvar}@#${libarchive_inc}#g
" > Makefile " > Makefile

View file

@ -37,7 +37,6 @@
#include <strings.h> #include <strings.h>
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>
#if defined(sun) || defined(__sun) #if defined(sun) || defined(__sun)
#include <sys/byteorder.h> #include <sys/byteorder.h>
#else #else
@ -54,6 +53,7 @@
#include <crypto/crypto_utils.h> #include <crypto/crypto_utils.h>
#include <crypto_xsalsa20.h> #include <crypto_xsalsa20.h>
#include <ctype.h> #include <ctype.h>
#include <pc_archive.h>
/* /*
* We use 8MB chunks by default. * We use 8MB chunks by default.
@ -70,9 +70,6 @@ struct wdata {
}; };
pthread_mutex_t opt_parse = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t opt_parse = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t f_mutex = PTHREAD_MUTEX_INITIALIZER;
static char *f_name_list[512];
static int f_count = 512, f_inited = 0;
static void * writer_thread(void *dat); static void * writer_thread(void *dat);
static int init_algo(pc_ctx_t *pctx, const char *algo, int bail); static int init_algo(pc_ctx_t *pctx, const char *algo, int bail);
@ -190,52 +187,6 @@ show_compression_stats(pc_ctx_t *pctx)
} }
} }
/*
* Temporary file cleanup routines for SIGINT. Maintain a list of
* filenames to be removed in the signal handler.
*/
void
Int_Handler(int signo)
{
int i;
for (i = 0; i < f_count; i++) {
if (f_name_list[i] != NULL) {
unlink(f_name_list[i]);
f_name_list[i] = NULL;
}
}
exit(1);
}
static void
add_fname(char *fn) {
int i;
pthread_mutex_lock(&f_mutex);
for (i = 0; i < f_count; i++) {
if (f_name_list[i] == NULL) {
f_name_list[i] = fn;
break;
}
}
pthread_mutex_unlock(&f_mutex);
}
static void
rm_fname(char *fn) {
int i;
pthread_mutex_lock(&f_mutex);
for (i = 0; i < f_count; i++) {
if (f_name_list[i] != NULL) {
f_name_list[i] = fn;
break;
}
}
pthread_mutex_unlock(&f_mutex);
}
/* /*
* Wrapper functions to pre-process the buffer and then call the main compression routine. * Wrapper functions to pre-process the buffer and then call the main compression routine.
* At present only LZP pre-compression is used below. Some extra metadata is added: * At present only LZP pre-compression is used below. Some extra metadata is added:
@ -721,7 +672,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
if (filename == NULL) { if (filename == NULL) {
compfd = fileno(stdin); compfd = fileno(stdin);
if (compfd == -1) { if (compfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
sbuf.st_size = 0; sbuf.st_size = 0;
@ -747,12 +698,12 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
} else { } else {
compfd = fileno(stdin); compfd = fileno(stdin);
if (compfd == -1) { if (compfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
uncompfd = fileno(stdout); uncompfd = fileno(stdout);
if (uncompfd == -1) { if (uncompfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
} }
@ -761,7 +712,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
* Read file header pieces and verify. * Read file header pieces and verify.
*/ */
if (Read(compfd, algorithm, ALGO_SZ) < ALGO_SZ) { if (Read(compfd, algorithm, ALGO_SZ) < ALGO_SZ) {
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
if (init_algo(pctx, algorithm, 0) != 0) { if (init_algo(pctx, algorithm, 0) != 0) {
@ -777,7 +728,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
Read(compfd, &flags, sizeof (flags)) < sizeof (flags) || Read(compfd, &flags, sizeof (flags)) < sizeof (flags) ||
Read(compfd, &chunksize, sizeof (chunksize)) < sizeof (chunksize) || Read(compfd, &chunksize, sizeof (chunksize)) < sizeof (chunksize) ||
Read(compfd, &level, sizeof (level)) < sizeof (level)) { Read(compfd, &level, sizeof (level)) < sizeof (level)) {
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
@ -908,7 +859,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
UNCOMP_BAIL; UNCOMP_BAIL;
} }
if (Read(compfd, &saltlen, sizeof (saltlen)) < sizeof (saltlen)) { if (Read(compfd, &saltlen, sizeof (saltlen)) < sizeof (saltlen)) {
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
saltlen = ntohl(saltlen); saltlen = ntohl(saltlen);
@ -916,7 +867,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
salt2 = (uchar_t *)malloc(saltlen); salt2 = (uchar_t *)malloc(saltlen);
if (Read(compfd, salt1, saltlen) < saltlen) { if (Read(compfd, salt1, saltlen) < saltlen) {
free(salt1); free(salt2); free(salt1); free(salt2);
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
deserialize_checksum(salt2, salt1, saltlen); deserialize_checksum(salt2, salt1, saltlen);
@ -926,7 +877,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
free(salt2); free(salt2);
memset(salt1, 0, saltlen); memset(salt1, 0, saltlen);
free(salt1); free(salt1);
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
@ -943,7 +894,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
free(salt2); free(salt2);
memset(salt1, 0, saltlen); memset(salt1, 0, saltlen);
free(salt1); free(salt1);
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
pctx->keylen = ntohl(pctx->keylen); pctx->keylen = ntohl(pctx->keylen);
@ -954,7 +905,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
free(salt2); free(salt2);
memset(salt1, 0, saltlen); memset(salt1, 0, saltlen);
free(salt1); free(salt1);
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
deserialize_checksum(hdr_hash2, hdr_hash1, pctx->mac_bytes); deserialize_checksum(hdr_hash2, hdr_hash1, pctx->mac_bytes);
@ -999,7 +950,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
} }
} }
if (pw_len == -1) { if (pw_len == -1) {
perror(" "); log_msg(LOG_ERR, 1, " ");
memset(salt2, 0, saltlen); memset(salt2, 0, saltlen);
free(salt2); free(salt2);
memset(salt1, 0, saltlen); memset(salt1, 0, saltlen);
@ -1089,7 +1040,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
* Verify file header CRC32 in non-crypto mode. * Verify file header CRC32 in non-crypto mode.
*/ */
if (Read(compfd, &crc1, sizeof (crc1)) < sizeof (crc1)) { if (Read(compfd, &crc1, sizeof (crc1)) < sizeof (crc1)) {
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
crc1 = htonl(crc1); crc1 = htonl(crc1);
@ -1175,7 +1126,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
} }
if (pctx->enable_rabin_global) { if (pctx->enable_rabin_global) {
if ((tdat->rctx->out_fd = open(to_filename, O_RDONLY, 0)) == -1) { if ((tdat->rctx->out_fd = open(to_filename, O_RDONLY, 0)) == -1) {
perror("Unable to get new read handle to output file"); log_msg(LOG_ERR, 1, "Unable to get new read handle to output file");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
} }
@ -1192,7 +1143,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
} }
if (pthread_create(&(tdat->thr), NULL, perform_decompress, if (pthread_create(&(tdat->thr), NULL, perform_decompress,
(void *)tdat) != 0) { (void *)tdat) != 0) {
perror("Error in thread creation: "); log_msg(LOG_ERR, 1, "Error in thread creation: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
} }
@ -1218,7 +1169,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
w.chunksize = chunksize; w.chunksize = chunksize;
w.pctx = pctx; w.pctx = pctx;
if (pthread_create(&writer_thr, NULL, writer_thread, (void *)(&w)) != 0) { if (pthread_create(&writer_thr, NULL, writer_thread, (void *)(&w)) != 0) {
perror("Error in thread creation: "); log_msg(LOG_ERR, 1, "Error in thread creation: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} }
@ -1248,7 +1199,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
*/ */
rb = Read(compfd, &tdat->len_cmp, sizeof (tdat->len_cmp)); rb = Read(compfd, &tdat->len_cmp, sizeof (tdat->len_cmp));
if (rb != sizeof (tdat->len_cmp)) { if (rb != sizeof (tdat->len_cmp)) {
if (rb < 0) perror("Read: "); if (rb < 0) log_msg(LOG_ERR, 1, "Read: ");
else else
log_msg(LOG_ERR, 0, "Incomplete chunk %d header," log_msg(LOG_ERR, 0, "Incomplete chunk %d header,"
"file corrupt\n", pctx->chunk_num); "file corrupt\n", pctx->chunk_num);
@ -1311,7 +1262,7 @@ start_decompress(pc_ctx_t *pctx, const char *filename, const char *to_filename)
if (pctx->main_cancel) break; if (pctx->main_cancel) break;
if (tdat->rbytes < tdat->len_cmp + pctx->cksum_bytes + pctx->mac_bytes + CHUNK_FLAG_SZ) { if (tdat->rbytes < tdat->len_cmp + pctx->cksum_bytes + pctx->mac_bytes + CHUNK_FLAG_SZ) {
if (tdat->rbytes < 0) { if (tdat->rbytes < 0) {
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
UNCOMP_BAIL; UNCOMP_BAIL;
} else { } else {
log_msg(LOG_ERR, 0, "Incomplete chunk %d, file corrupt.\n", log_msg(LOG_ERR, 0, "Incomplete chunk %d, file corrupt.\n",
@ -1352,7 +1303,7 @@ uncomp_done:
if (filename != NULL) { if (filename != NULL) {
fchmod(uncompfd, sbuf.st_mode); fchmod(uncompfd, sbuf.st_mode);
if (fchown(uncompfd, sbuf.st_uid, sbuf.st_gid) == -1) if (fchown(uncompfd, sbuf.st_uid, sbuf.st_gid) == -1)
perror("Chown "); log_msg(LOG_ERR, 1, "Chown ");
} }
if (dary != NULL) { if (dary != NULL) {
for (i = 0; i < nprocs; i++) { for (i = 0; i < nprocs; i++) {
@ -1679,7 +1630,7 @@ repeat:
wbytes = Write(w->wfd, tdat->cmp_seg, tdat->len_cmp); wbytes = Write(w->wfd, tdat->cmp_seg, tdat->len_cmp);
if (unlikely(wbytes != tdat->len_cmp)) { if (unlikely(wbytes != tdat->len_cmp)) {
perror("Chunk Write: "); log_msg(LOG_ERR, 1, "Chunk Write: ");
do_cancel: do_cancel:
pctx->main_cancel = 1; pctx->main_cancel = 1;
tdat->cancel = 1; tdat->cancel = 1;
@ -1811,6 +1762,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
/* A host of sanity checks. */ /* A host of sanity checks. */
if (!pctx->pipe_mode) { if (!pctx->pipe_mode) {
char *tmp; char *tmp;
if (!(pctx->archive_mode)) {
if ((uncompfd = open(filename, O_RDONLY, 0)) == -1) { if ((uncompfd = open(filename, O_RDONLY, 0)) == -1) {
log_msg(LOG_ERR, 1, "Cannot open: %s", filename); log_msg(LOG_ERR, 1, "Cannot open: %s", filename);
return (1); return (1);
@ -1832,6 +1784,19 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
close(uncompfd); close(uncompfd);
return (1); return (1);
} }
} else {
if (setup_archive(pctx, &sbuf) == -1) {
log_msg(LOG_ERR, 0, "Setup archive failed for %s\n", pctx->filename);
return (1);
}
/*
* This is a pipe between the libarchive based archiving process and
* the rest of the compression stuff.
*/
uncompfd = pctx->uncompfd;
exit(0);
}
/* /*
* Adjust chunk size for small files. We then get an archive with * Adjust chunk size for small files. We then get an archive with
@ -1882,7 +1847,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
if (pctx->pipe_out) { if (pctx->pipe_out) {
compfd = fileno(stdout); compfd = fileno(stdout);
if (compfd == -1) { if (compfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
COMP_BAIL; COMP_BAIL;
} }
} else { } else {
@ -1890,21 +1855,19 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
strcat(tmpfile1, "/.pcompXXXXXX"); strcat(tmpfile1, "/.pcompXXXXXX");
snprintf(to_filename, sizeof (to_filename), "%s" COMP_EXTN, filename); snprintf(to_filename, sizeof (to_filename), "%s" COMP_EXTN, filename);
if ((compfd = mkstemp(tmpfile1)) == -1) { if ((compfd = mkstemp(tmpfile1)) == -1) {
perror("mkstemp "); log_msg(LOG_ERR, 1, "mkstemp ");
COMP_BAIL; COMP_BAIL;
} }
add_fname(tmpfile1); add_fname(tmpfile1);
} else { } else {
snprintf(to_filename, sizeof (to_filename), "%s" COMP_EXTN, pctx->to_filename); snprintf(to_filename, sizeof (to_filename), "%s" COMP_EXTN, pctx->to_filename);
if ((compfd = open(to_filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) == -1) { if ((compfd = open(to_filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) == -1) {
perror("open "); log_msg(LOG_ERR, 1, "open ");
COMP_BAIL; COMP_BAIL;
} }
add_fname(to_filename); add_fname(to_filename);
} }
} }
signal(SIGINT, Int_Handler);
signal(SIGTERM, Int_Handler);
} else { } else {
char *tmp; char *tmp;
@ -1913,33 +1876,21 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
*/ */
compfd = fileno(stdout); compfd = fileno(stdout);
if (compfd == -1) { if (compfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
COMP_BAIL; COMP_BAIL;
} }
uncompfd = fileno(stdin); uncompfd = fileno(stdin);
if (uncompfd == -1) { if (uncompfd == -1) {
perror("fileno "); log_msg(LOG_ERR, 1, "fileno ");
COMP_BAIL; COMP_BAIL;
} }
/* /*
* Get a workable temporary dir. Required if global dedupe is enabled. * Get a workable temporary dir. Required if global dedupe is enabled.
*/ */
tmp = getenv("PCOMPRESS_CACHE_DIR"); tmp = get_temp_dir();
if (tmp == NULL || !chk_dir(tmp)) {
tmp = getenv("TMPDIR");
if (tmp == NULL || !chk_dir(tmp)) {
tmp = getenv("HOME");
if (tmp == NULL || !chk_dir(tmp)) {
if (getcwd(tmpdir, MAXPATHLEN) == NULL) {
tmp = "/tmp";
} else {
tmp = tmpdir;
}
}
}
}
strcpy(tmpdir, tmp); strcpy(tmpdir, tmp);
free(tmp);
} }
if (pctx->enable_rabin_global) { if (pctx->enable_rabin_global) {
@ -2061,7 +2012,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
} }
if (pthread_create(&(tdat->thr), NULL, perform_compress, if (pthread_create(&(tdat->thr), NULL, perform_compress,
(void *)tdat) != 0) { (void *)tdat) != 0) {
perror("Error in thread creation: "); log_msg(LOG_ERR, 1, "Error in thread creation: ");
COMP_BAIL; COMP_BAIL;
} }
} }
@ -2099,7 +2050,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
w.nprocs = nprocs; w.nprocs = nprocs;
w.pctx = pctx; w.pctx = pctx;
if (pthread_create(&writer_thr, NULL, writer_thread, (void *)(&w)) != 0) { if (pthread_create(&writer_thr, NULL, writer_thread, (void *)(&w)) != 0) {
perror("Error in thread creation: "); log_msg(LOG_ERR, 1, "Error in thread creation: ");
COMP_BAIL; COMP_BAIL;
} }
wthread = 1; wthread = 1;
@ -2146,7 +2097,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
pos += sizeof (int); pos += sizeof (int);
} }
if (Write(compfd, cread_buf, pos - cread_buf) != pos - cread_buf) { if (Write(compfd, cread_buf, pos - cread_buf) != pos - cread_buf) {
perror("Write "); log_msg(LOG_ERR, 1, "Write ");
COMP_BAIL; COMP_BAIL;
} }
@ -2173,7 +2124,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
serialize_checksum(hdr_hash, pos, hlen); serialize_checksum(hdr_hash, pos, hlen);
pos += hlen; pos += hlen;
if (Write(compfd, cread_buf, pos - cread_buf) != pos - cread_buf) { if (Write(compfd, cread_buf, pos - cread_buf) != pos - cread_buf) {
perror("Write "); log_msg(LOG_ERR, 1, "Write ");
COMP_BAIL; COMP_BAIL;
} }
} else { } else {
@ -2183,7 +2134,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
uint32_t crc = lzma_crc32(cread_buf, pos - cread_buf, 0); uint32_t crc = lzma_crc32(cread_buf, pos - cread_buf, 0);
U32_P(cread_buf) = htonl(crc); U32_P(cread_buf) = htonl(crc);
if (Write(compfd, cread_buf, sizeof (uint32_t)) != sizeof (uint32_t)) { if (Write(compfd, cread_buf, sizeof (uint32_t)) != sizeof (uint32_t)) {
perror("Write "); log_msg(LOG_ERR, 1, "Write ");
COMP_BAIL; COMP_BAIL;
} }
} }
@ -2298,7 +2249,7 @@ start_compress(pc_ctx_t *pctx, const char *filename, uint64_t chunksize, int lev
if (rbytes < chunksize) { if (rbytes < chunksize) {
if (rbytes < 0) { if (rbytes < 0) {
bail = 1; bail = 1;
perror("Read: "); log_msg(LOG_ERR, 1, "Read: ");
COMP_BAIL; COMP_BAIL;
} }
} }
@ -2367,7 +2318,7 @@ comp_done:
compressed_chunksize = 0; compressed_chunksize = 0;
if (Write(compfd, &compressed_chunksize, if (Write(compfd, &compressed_chunksize,
sizeof (compressed_chunksize)) < 0) { sizeof (compressed_chunksize)) < 0) {
perror("Write "); log_msg(LOG_ERR, 1, "Write ");
err = 1; err = 1;
} }
@ -2381,12 +2332,12 @@ comp_done:
*/ */
fchmod(compfd, sbuf.st_mode); fchmod(compfd, sbuf.st_mode);
if (fchown(compfd, sbuf.st_uid, sbuf.st_gid) == -1) if (fchown(compfd, sbuf.st_uid, sbuf.st_gid) == -1)
perror("chown "); log_msg(LOG_ERR, 1, "chown ");
close(compfd); close(compfd);
if (pctx->to_filename == NULL) { if (pctx->to_filename == NULL) {
if (rename(tmpfile1, to_filename) == -1) { if (rename(tmpfile1, to_filename) == -1) {
perror("Cannot rename temporary file "); log_msg(LOG_ERR, 1, "Cannot rename temporary file ");
unlink(tmpfile1); unlink(tmpfile1);
} }
rm_fname(tmpfile1); rm_fname(tmpfile1);
@ -2553,11 +2504,6 @@ create_pc_context(void)
{ {
pc_ctx_t *ctx = (pc_ctx_t *)malloc(sizeof (pc_ctx_t)); pc_ctx_t *ctx = (pc_ctx_t *)malloc(sizeof (pc_ctx_t));
pthread_mutex_lock(&f_mutex);
if (!f_inited) {
memset(f_name_list, 0, sizeof (f_name_list));
}
pthread_mutex_unlock(&f_mutex);
slab_init(); slab_init();
init_pcompress(); init_pcompress();
@ -2779,6 +2725,7 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
else else
pctx->rab_blk_size = RAB_BLK_DEFAULT; pctx->rab_blk_size = RAB_BLK_DEFAULT;
} }
/* /*
* Remaining mandatory arguments are the filenames. * Remaining mandatory arguments are the filenames.
*/ */
@ -2915,6 +2862,16 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
*/ */
pctx->cksum_bytes = 0; pctx->cksum_bytes = 0;
} }
if (pctx->do_compress) {
struct stat sbuf;
if (stat(pctx->filename, &sbuf) == -1) {
log_msg(LOG_ERR, 1, "Cannot stat: %s", pctx->filename);
return (1);
}
if (S_ISDIR(sbuf.st_mode)) pctx->archive_mode = 1;
}
pctx->inited = 1; pctx->inited = 1;
return (0); return (0);
@ -2927,6 +2884,8 @@ start_pcompress(pc_ctx_t *pctx)
if (!pctx->inited) if (!pctx->inited)
return (1); return (1);
handle_signals();
err = 0; err = 0;
if (pctx->do_compress) if (pctx->do_compress)
err = start_compress(pctx, pctx->filename, pctx->chunksize, pctx->level); err = start_compress(pctx, pctx->filename, pctx->chunksize, pctx->level);

View file

@ -197,9 +197,14 @@ typedef struct pc_ctx {
int enable_fixed_scan; int enable_fixed_scan;
int lzp_preprocess; int lzp_preprocess;
int encrypt_type; int encrypt_type;
int archive_mode;
char archive_members_file[MAXPATHLEN];
int archive_members_fd, archive_data_fd;
void *archive_ctx;
int uncompfd, compfd;
unsigned int chunk_num; unsigned int chunk_num;
uint64_t largest_chunk, smallest_chunk, avg_chunk; uint64_t largest_chunk, smallest_chunk, avg_chunk;
uint64_t chunksize; uint64_t chunksize, archive_size;
const char *algo, *filename, *to_filename; const char *algo, *filename, *to_filename;
char *exec_name; char *exec_name;
int do_compress, level; int do_compress, level;

View file

@ -204,7 +204,7 @@ read_config(char *configfile, archive_config_t *cfg)
fh = fopen(configfile, "r"); fh = fopen(configfile, "r");
if (fh == NULL) { if (fh == NULL) {
perror(" "); log_msg(LOG_ERR, 1, " ");
return (1); return (1);
} }
while (fgets(line, 255, fh) != NULL) { while (fgets(line, 255, fh) != NULL) {
@ -232,7 +232,7 @@ read_config(char *configfile, archive_config_t *cfg)
struct stat sb; struct stat sb;
if (stat(pos, &sb) == -1) { if (stat(pos, &sb) == -1) {
if (errno != ENOENT) { if (errno != ENOENT) {
perror(" "); log_msg(LOG_ERR, 1, " ");
log_msg(LOG_ERR, 0, "Invalid ROOTDIR.\n"); log_msg(LOG_ERR, 0, "Invalid ROOTDIR.\n");
fclose(fh); fclose(fh);
return (1); return (1);
@ -336,7 +336,7 @@ write_config(char *configfile, archive_config_t *cfg)
fh = fopen(configfile, "w"); fh = fopen(configfile, "w");
if (fh == NULL) { if (fh == NULL) {
perror(" "); log_msg(LOG_ERR, 1, " ");
return (1); return (1);
} }

View file

@ -285,7 +285,7 @@ init_global_db_s(char *path, char *tmppath, uint32_t chunksize, uint64_t user_ch
for (i = 0; i < nthreads; i++) { for (i = 0; i < nthreads; i++) {
cfg->seg_fd_r[i].fd = open(cfg->rootdir, O_RDONLY); cfg->seg_fd_r[i].fd = open(cfg->rootdir, O_RDONLY);
if (cfg->seg_fd_r[i].fd == -1) { if (cfg->seg_fd_r[i].fd == -1) {
perror(" "); log_msg(LOG_ERR, 1, " ");
errored = 1; errored = 1;
break; break;
} }
@ -394,7 +394,7 @@ db_segcache_map(archive_config_t *cfg, int tid, uint32_t *blknum, uint64_t *offs
db_segcache_unmap(cfg, tid); db_segcache_unmap(cfg, tid);
fd = cfg->seg_fd_r[tid].fd; fd = cfg->seg_fd_r[tid].fd;
if (lseek(fd, *offset, SEEK_SET) != *offset) { if (lseek(fd, *offset, SEEK_SET) != *offset) {
perror(" "); log_msg(LOG_ERR, 1, " ");
return (-1); return (-1);
} }
@ -410,7 +410,7 @@ db_segcache_map(archive_config_t *cfg, int tid, uint32_t *blknum, uint64_t *offs
mapbuf = mmap(NULL, len + adj, PROT_READ, MAP_SHARED, fd, *offset - adj); mapbuf = mmap(NULL, len + adj, PROT_READ, MAP_SHARED, fd, *offset - adj);
if (mapbuf == MAP_FAILED) { if (mapbuf == MAP_FAILED) {
perror(" "); log_msg(LOG_ERR, 1, " ");
return (-1); return (-1);
} }

View file

@ -1609,7 +1609,7 @@ dedupe_decompress(dedupe_context_t *ctx, uchar_t *buf, uint64_t *size)
adj = pos1 % ctx->pagesize; adj = pos1 % ctx->pagesize;
src2 = mmap(NULL, len + adj, PROT_READ, MAP_SHARED, ctx->out_fd, pos1 - adj); src2 = mmap(NULL, len + adj, PROT_READ, MAP_SHARED, ctx->out_fd, pos1 - adj);
if (src2 == NULL) { if (src2 == NULL) {
perror("MMAP failed "); log_msg(LOG_ERR, 1, "MMAP failed ");
ctx->valid = 0; ctx->valid = 0;
break; break;
} }

View file

@ -38,6 +38,7 @@
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <link.h> #include <link.h>
#include <signal.h>
#include <rabin_dedup.h> #include <rabin_dedup.h>
#include <cpuid.h> #include <cpuid.h>
#include <xxhash.h> #include <xxhash.h>
@ -48,8 +49,11 @@
#include "utils.h" #include "utils.h"
processor_info_t proc_info; processor_info_t proc_info;
pthread_mutex_t f_mutex = PTHREAD_MUTEX_INITIALIZER;
static int cur_log_level = 1; static int cur_log_level = 1;
static log_dest_t ldest = {LOG_OUTPUT, LOG_INFO, NULL}; static log_dest_t ldest = {LOG_OUTPUT, LOG_INFO, NULL};
static char *f_name_list[512];
static int f_count = 512, f_inited = 0;
void void
init_pcompress() { init_pcompress() {
@ -422,6 +426,10 @@ chk_dir(char *dir)
return (1); return (1);
} }
/*
* Simple logging functions. Used for all error and info messages.
* Default log destination is STDOUT.
*/
void DLL_EXPORT void DLL_EXPORT
set_log_dest(log_dest_t *dest) set_log_dest(log_dest_t *dest)
{ {
@ -464,3 +472,86 @@ log_msg(log_level_t log_level, int show_errno, const char *format, ...)
ldest.cb(msg); ldest.cb(msg);
} }
} }
char *
get_temp_dir()
{
char *tmp;
char tmpdir[MAXPATHLEN];
tmp = getenv("PCOMPRESS_CACHE_DIR");
if (tmp == NULL || !chk_dir(tmp)) {
tmp = getenv("TMPDIR");
if (tmp == NULL || !chk_dir(tmp)) {
tmp = getenv("HOME");
if (tmp == NULL || !chk_dir(tmp)) {
if (getcwd(tmpdir, MAXPATHLEN) == NULL) {
tmp = "/tmp";
} else {
tmp = tmpdir;
}
}
}
}
return (strdup(tmp));
}
/*
* Temporary file cleanup routines for SIGINT. Maintain a list of
* filenames to be removed in the signal handler.
*/
void
Int_Handler(int signo)
{
int i;
for (i = 0; i < f_count; i++) {
if (f_name_list[i] != NULL) {
unlink(f_name_list[i]);
f_name_list[i] = NULL;
}
}
exit(1);
}
void
handle_signals()
{
pthread_mutex_lock(&f_mutex);
if (!f_inited) {
memset(f_name_list, 0, sizeof (f_name_list));
}
pthread_mutex_unlock(&f_mutex);
signal(SIGINT, Int_Handler);
signal(SIGTERM, Int_Handler);
}
void
add_fname(char *fn)
{
int i;
pthread_mutex_lock(&f_mutex);
for (i = 0; i < f_count; i++) {
if (f_name_list[i] == NULL) {
f_name_list[i] = fn;
break;
}
}
pthread_mutex_unlock(&f_mutex);
}
void
rm_fname(char *fn)
{
int i;
pthread_mutex_lock(&f_mutex);
for (i = 0; i < f_count; i++) {
if (f_name_list[i] != NULL) {
f_name_list[i] = fn;
break;
}
}
pthread_mutex_unlock(&f_mutex);
}

View file

@ -35,6 +35,7 @@
#endif #endif
#include <inttypes.h> #include <inttypes.h>
#include <sys/param.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <cpuid.h> #include <cpuid.h>
@ -57,7 +58,7 @@ extern "C" {
#define SIXTEEN_GB (EIGHT_GB * 2) #define SIXTEEN_GB (EIGHT_GB * 2)
#if !defined(sun) && !defined(__sun) #if !defined(sun) && !defined(__sun)
#define uchar_t u_char typedef unsigned char uchar_t ;
#endif #endif
#if ULONG_MAX == 4294967295UL #if ULONG_MAX == 4294967295UL
@ -243,6 +244,7 @@ extern void get_sys_limits(my_sysinfo *msys_info);
extern int chk_dir(char *dir); extern int chk_dir(char *dir);
extern void init_algo_props(algo_props_t *props); extern void init_algo_props(algo_props_t *props);
extern void init_pcompress(); extern void init_pcompress();
extern char *get_temp_dir();
/* Pointer type for compress and decompress functions. */ /* Pointer type for compress and decompress functions. */
typedef int (*compress_func_ptr)(void *src, uint64_t srclen, void *dst, typedef int (*compress_func_ptr)(void *src, uint64_t srclen, void *dst,
@ -287,6 +289,14 @@ void set_log_dest(log_dest_t *dest);
void set_log_level(int level); void set_log_level(int level);
void log_msg(log_level_t log_level, int show_errno, const char *format, ...); void log_msg(log_level_t log_level, int show_errno, const char *format, ...);
/*
* Tempfile cleanup handlers and tempfile registration routines.
*/
void Int_Handler(int signo);
void handle_signals();
void add_fname(char *fn);
void rm_fname(char *fn);
/* /*
* Roundup v to the nearest power of 2. From Bit Twiddling Hacks: * Roundup v to the nearest power of 2. From Bit Twiddling Hacks:
* http://graphics.stanford.edu/~seander/bithacks.html * http://graphics.stanford.edu/~seander/bithacks.html