switch to V6 XML config format using boost serialization

git-svn-id: http://encfs.googlecode.com/svn/trunk@16 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
Valient Gough 2008-04-13 20:35:57 +00:00
parent 21c7a022d8
commit 6d081f5c99
10 changed files with 500 additions and 90 deletions

View File

@ -14,4 +14,4 @@ AUTOMAKE_OPTIONS = foreign
MAINTAINERCLEANFILES = aclocal.m4
ACLOCAL_AMFLAGS = -I m4
ACLOCAL_AMFLAGS = -I m4 -I m4-local

View File

@ -1,3 +0,0 @@
m4_include([acx_pthread.m4])

View File

@ -43,6 +43,9 @@ AC_PROG_LIBTOOL
ACX_PTHREAD
AX_BOOST_BASE([1.33])
AX_BOOST_SERIALIZATION
dnl Need to include any user specified flags in the tests below, as they might
dnl specify required include directories..
FUSEFLAGS="-D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26"
@ -51,7 +54,7 @@ CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $USER_INCLUDES"
LDFLAGS="$LDFLAGS $PTHREAD_LIBS $USER_LDFLAGS"
if test "$GXX" = "yes"; then
CXXFLAGS="-W -Wall -Wshadow -Wpointer-arith -Wwrite-strings $CXXFLAGS"
CXXFLAGS="-W -Wall -Wpointer-arith -Wwrite-strings $CXXFLAGS"
dnl CXXFLAGS="$CXXFLAGS -Wformat=2 -Wconversion"
fi
@ -181,12 +184,6 @@ PKG_CHECK_MODULES(RLOG, librlog >= 1.3,
AC_CHECK_LIB(rlog, RLogVersion, [RLOG_LIBS="-lrlog"],
[AC_MSG_ERROR([EncFS depends on librlog, by the same author.])]) ])
AC_CHECK_HEADER(boost/shared_ptr.hpp,,
[AC_MSG_ERROR([
Can't find boost/shared_.h - add the boost include dir to CPPFLAGS and
rerun configure, eg:
export CPPFLAGS=-I/usr/local/include ])])
# look for pod2man program for building man pages
AC_PATH_PROG(POD2MAN, pod2man, [no])
AC_PATH_PROG(POD2HTML, pod2html, [no])

View File

@ -57,10 +57,16 @@
#include "i18n.h"
#include <boost/filesystem/fstream.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
using namespace rel;
using namespace rlog;
using namespace std;
using namespace gnu;
namespace fs = boost::filesystem;
static const int DefaultBlockSize = 1024;
// The maximum length of text passwords. If longer are needed,
@ -76,10 +82,11 @@ static const char ENCFS_ENV_STDERR[] = "encfs_stderr";
//static int V5SubVersion = 20040518;
//static int V5SubVersion = 20040621; // add external IV chaining
//static int V5SubVersion = 20040813; // fix MACFileIO block size issues
static int V5SubVersion = 20080411; // add zero-block pass-through
static int V5SubVersion = 20040813; // fix MACFileIO block size issues
static int V5SubVersionDefault = 0;
const int V6SubVersion = 20080813; // switch to v6/XML, add allowHoles option
struct ConfigInfo
{
const char *fileName;
@ -91,17 +98,92 @@ struct ConfigInfo
int currentSubVersion;
int defaultSubVersion;
} ConfigFileMapping[] = {
{".encfs6.xml", Config_V6, "ENCFS6_CONFIG", readV6Config, writeV6Config,
V6SubVersion, 0 },
// backward compatible support for older versions
{".encfs5", Config_V5, "ENCFS5_CONFIG", readV5Config, writeV5Config,
V5SubVersion, V5SubVersionDefault },
// backward compatible support for config versions 3 and 4
{".encfs4", Config_V4, NULL, readV4Config, writeV4Config, 0, 0 },
{".encfs3", Config_V3, NULL, readV3Config, writeV3Config, 0, 0 },
// forget about version 2 and 1 - from before the first public release!
// no longer support earlier versions
{".encfs3", Config_V3, NULL, NULL, NULL, 0, 0 },
{".encfs2", Config_Prehistoric, NULL, NULL, NULL, 0, 0 },
{".encfs", Config_Prehistoric, NULL, NULL, NULL, 0, 0 },
{NULL,Config_None, NULL, NULL, NULL, 0, 0}};
// define serialization helpers
namespace boost
{
namespace serialization
{
template<class Archive>
void save(Archive &ar, const EncFSConfig &cfg,
unsigned int version)
{
(void)version;
ar << make_nvp("creator", cfg.creator);
ar << make_nvp("cipherAlg", cfg.cipherIface);
ar << make_nvp("nameAlg", cfg.nameIface);
ar << make_nvp("keySize", cfg.keySize);
ar << make_nvp("blockSize", cfg.blockSize);
ar << make_nvp("uniqueIV", cfg.uniqueIV);
ar << make_nvp("chainedNameIV", cfg.chainedNameIV);
ar << make_nvp("externalIVChaining", cfg.externalIVChaining);
ar << make_nvp("blockMACBytes", cfg.blockMACBytes);
ar << make_nvp("blockMACRandBytes", cfg.blockMACRandBytes);
ar << make_nvp("allowHoles", cfg.allowHoles);
int keyLen = cfg.keyData.length();
ar << make_nvp("encodedKeySize", keyLen);
char key[keyLen];
memcpy(key, cfg.keyData.data(), keyLen);
ar << make_nvp("encodedKeyData", make_binary_object(key, keyLen));
}
template<class Archive>
void load(Archive &ar, EncFSConfig &cfg, unsigned int version)
{
(void)version;
cfg.subVersion = version;
ar >> make_nvp("creator", cfg.creator);
ar >> make_nvp("cipherAlg", cfg.cipherIface);
ar >> make_nvp("nameAlg", cfg.nameIface);
ar >> make_nvp("keySize", cfg.keySize);
ar >> make_nvp("blockSize", cfg.blockSize);
ar >> make_nvp("uniqueIV", cfg.uniqueIV);
ar >> make_nvp("chainedNameIV", cfg.chainedNameIV);
ar >> make_nvp("externalIVChaining", cfg.externalIVChaining);
ar >> make_nvp("blockMACBytes", cfg.blockMACBytes);
ar >> make_nvp("blockMACRandBytes", cfg.blockMACRandBytes);
ar >> make_nvp("allowHoles", cfg.allowHoles);
int encodedKeySize;
ar >> make_nvp("encodedKeySize", encodedKeySize);
char key[encodedKeySize];
ar >> make_nvp("encodedKeyData",
make_binary_object(key, encodedKeySize));
cfg.keyData.assign( (char*)key, encodedKeySize );
}
template<class Archive>
void serialize(Archive &ar, EncFSConfig &cfg, unsigned int version)
{
split_free(ar, cfg, version);
}
template<class Archive>
void serialize(Archive &ar, Interface &i, const unsigned int version)
{
(void)version;
ar & make_nvp("name", i.name());
ar & make_nvp("major", i.current());
ar & make_nvp("minor", i.revision());
}
}
}
BOOST_CLASS_VERSION(EncFSConfig, V6SubVersion)
EncFS_Root::EncFS_Root()
{
}
@ -231,6 +313,32 @@ ConfigType readConfig( const string &rootDir, EncFSConfig *config )
return Config_None;
}
bool readV6Config( const char *configFile, EncFSConfig *config,
ConfigInfo *info)
{
(void)info;
fs::ifstream st(configFile);
if(st.is_open())
{
try
{
boost::archive::xml_iarchive ia( st );
ia >> BOOST_SERIALIZATION_NVP( *config );
return true;
} catch(boost::archive::archive_exception &e)
{
rError("Archive exception: %s", e.what());
return false;
}
} else
{
rInfo("Failed to load config file %s", configFile);
return false;
}
}
bool readV5Config( const char *configFile, EncFSConfig *config,
ConfigInfo *info)
{
@ -273,8 +381,6 @@ bool readV5Config( const char *configFile, EncFSConfig *config,
config->blockMACRandBytes =
cfgRdr["blockMACRandBytes"].readInt(0);
config->allowHoles = cfgRdr["allowHoles"].readBool( false );
ok = true;
} catch( rlog::Error &err)
{
@ -325,44 +431,6 @@ bool readV4Config( const char *configFile, EncFSConfig *config,
return ok;
}
bool readV3Config( const char *configFile, EncFSConfig *config,
ConfigInfo *info)
{
(void)configFile;
// use Config to parse the file and query it..
// fill in default for V3
config->creator = "EncFS 0.x";
config->subVersion = info->defaultSubVersion;
config->cipherIface = Interface("ssl/blowfish-v0.2", 1, 0, 0);
config->nameIface = Interface("nameio/stream", 0, 1, 0);
config->keySize = 160;
config->blockSize = 64;
config->blockMACBytes = 0;
config->blockMACRandBytes = 0;
config->uniqueIV = false;
config->externalIVChaining = false;
config->chainedNameIV = false;
bool ok = false;
int vkeyFD = open( configFile, O_RDONLY );
if( vkeyFD >= 0 )
{
const int headerSize = 22; // 160 bit (20 bytes) + 2 byte checksum
char keyBuf [ headerSize ];
read( vkeyFD, keyBuf, headerSize );
close( vkeyFD );
config->keyData.assign( keyBuf, headerSize );
ok = true;
} else
{
rDebug("Error opening config file %s", configFile );
}
return ok;
}
bool saveConfig( ConfigType type, const string &rootDir,
EncFSConfig *config )
{
@ -398,6 +466,18 @@ bool saveConfig( ConfigType type, const string &rootDir,
return ok;
}
bool writeV6Config( const char *configFile, EncFSConfig *config )
{
fs::ofstream st( configFile );
if(!st.is_open())
return false;
boost::archive::xml_oarchive oa(st);
oa << BOOST_SERIALIZATION_NVP( config );
return true;
}
bool writeV5Config( const char *configFile, EncFSConfig *config )
{
ConfigReader cfg;
@ -414,7 +494,6 @@ bool writeV5Config( const char *configFile, EncFSConfig *config )
cfg["uniqueIV"] << config->uniqueIV;
cfg["chainedIV"] << config->chainedNameIV;
cfg["externalIV"] << config->externalIVChaining;
cfg["allowHoles"] << config->allowHoles;
return cfg.save( configFile );
}
@ -431,25 +510,6 @@ bool writeV4Config( const char *configFile, EncFSConfig *config )
return cfg.save( configFile );
}
bool writeV3Config( const char *configFile, EncFSConfig *config )
{
bool ok = true;
int fd = open( configFile, O_RDWR );
if(fd >= 0)
{
::pwrite(fd, config->keyData.data(), config->keyData.length(), 0);
close( fd );
} else
{
rError(_("Error opening key file %s for write: %s"), configFile,
strerror( errno ));
ok = false;
}
return ok;
}
static
Cipher::CipherAlgorithm findCipherAlgorithm(const char *name,
int keySize )
@ -803,7 +863,7 @@ bool selectZeroBlockPassThrough()
"This avoids writing encrypted blocks when file holes are created."));
}
RootPtr createV5Config( EncFS_Context *ctx, const std::string &rootDir,
RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
bool enableIdleTracking, bool forceDecode,
const std::string &passwordProgram,
bool useStdin, bool reverseEncryption )
@ -956,7 +1016,7 @@ RootPtr createV5Config( EncFS_Context *ctx, const std::string &rootDir,
config.blockSize = blockSize;
config.nameIface = nameIOIface;
config.creator = "EncFS " VERSION;
config.subVersion = V5SubVersion;
config.subVersion = V6SubVersion;
config.blockMACBytes = blockMACBytes;
config.blockMACRandBytes = blockMACRandBytes;
config.uniqueIV = uniqueIV;
@ -1019,7 +1079,7 @@ RootPtr createV5Config( EncFS_Context *ctx, const std::string &rootDir,
return rootInfo;
}
if(!saveConfig( Config_V5, rootDir, &config ))
if(!saveConfig( Config_V6, rootDir, &config ))
return rootInfo;
// fill in config struct
@ -1436,7 +1496,7 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
if(opts->createIfNotFound)
{
// creating a new encrypted filesystem
rootInfo = createV5Config( ctx, opts->rootDir, opts->idleTracking,
rootInfo = createV6Config( ctx, opts->rootDir, opts->idleTracking,
opts->forceDecode, opts->passwordProgram, opts->useStdin,
opts->reverseEncryption );
}

View File

@ -59,6 +59,17 @@ struct EncFSConfig
bool chainedNameIV; // filename IV chaining
bool allowHoles; // allow holes in files (implicit zero blocks)
EncFSConfig()
{
subVersion = 0;
blockMACBytes = 0;
blockMACRandBytes = 0;
uniqueIV = false;
externalIVChaining = false;
chainedNameIV = false;
allowHoles = false;
}
};
enum ConfigType
@ -67,7 +78,8 @@ enum ConfigType
Config_Prehistoric,
Config_V3,
Config_V4,
Config_V5
Config_V5,
Config_V6
};
class Cipher;
@ -130,19 +142,15 @@ class EncFS_Context;
RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts );
RootPtr createV5Config( EncFS_Context *ctx, const std::string &rootDir,
RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
bool enableIdleTracking,
bool forceDecode,
const std::string &passwordProgram, bool reverseEncryption );
const std::string &passwordProgram, bool reverseEncryption,
bool allowHoles );
void showFSInfo( const EncFSConfig &config );
// Read specifically a version 4 configuration file.
bool readV3Config( const char *configFile, EncFSConfig *config,
struct ConfigInfo *);
bool writeV3Config( const char *configFile, EncFSConfig *config);
bool readV4Config( const char *configFile, EncFSConfig *config,
struct ConfigInfo *);
bool writeV4Config( const char *configFile, EncFSConfig *config);
@ -151,6 +159,10 @@ bool readV5Config( const char *configFile, EncFSConfig *config,
struct ConfigInfo *);
bool writeV5Config( const char *configFile, EncFSConfig *config);
bool readV6Config( const char *configFile, EncFSConfig *config,
struct ConfigInfo *);
bool writeV6Config( const char *configFile, EncFSConfig *config);
CipherKey getUserKey(const boost::shared_ptr<Cipher> &cipher, bool useStdin);

View File

@ -1,8 +1,8 @@
include $(top_srcdir)/Makefile.common
ALL_INCLUDES = @RLOG_CFLAGS@ @OPENSSL_CFLAGS@
ALL_LDFLAGS = @RLOG_LIBS@ @OPENSSL_LIBS@ @FUSE_LIBS@
ALL_INCLUDES = @RLOG_CFLAGS@ @OPENSSL_CFLAGS@ @BOOST_CPPFLAGS@
ALL_LDFLAGS = @RLOG_LIBS@ @OPENSSL_LIBS@ @FUSE_LIBS@ @BOOST_SERIALIZATION_LIB@
INCLUDES = $(all_includes) -I../intl

View File

@ -197,6 +197,12 @@ static int showInfo( int argc, char **argv )
"created by %s (revision %i)\n"), config.creator.c_str(),
config.subVersion);
break;
case Config_V6:
// xgroup(diag)
cout << "\n" << autosprintf(_("Version 6 configuration; "
"created by %s (revision %i)\n"), config.creator.c_str(),
config.subVersion);
break;
}
showFSInfo( config );

223
m4-local/ax_boost_base.m4 Normal file
View File

@ -0,0 +1,223 @@
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_base.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_BASE([MINIMUM-VERSION])
#
# DESCRIPTION
#
# Test for the Boost C++ libraries of a particular version (or newer)
#
# If no path to the installed boost library is given the macro searchs
# under /usr, /usr/local, /opt and /opt/local and evaluates the
# $BOOST_ROOT environment variable. Further documentation is available at
# <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
#
# And sets:
#
# HAVE_BOOST
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved.
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ac_boost_path=""
else
want_boost="yes"
ac_boost_path="$withval"
fi
],
[want_boost="yes"])
AC_ARG_WITH([boost-libdir],
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
[
if test -d $withval
then
ac_boost_lib_path="$withval"
else
AC_MSG_ERROR(--with-boost-libdir expected directory name)
fi
],
[ac_boost_lib_path=""]
)
if test "x$want_boost" = "xyes"; then
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
boost_lib_version_req_sub_minor="0"
fi
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
succeeded=no
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
if test "$ac_boost_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_path/lib"
BOOST_CPPFLAGS="-I$ac_boost_path/include"
else
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
break;
fi
done
fi
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_lib_path"
fi
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
_version=0
if test "$ac_boost_path" != ""; then
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
best_path=$ac_boost_path
fi
done
fi
done
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
if test "$ac_boost_lib_path" = ""
then
BOOST_LDFLAGS="-L$best_path/lib"
fi
if test "x$BOOST_ROOT" != "x"; then
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
V_CHECK=`expr $stage_version_shorten \>\= $_version`
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
BOOST_CPPFLAGS="-I$BOOST_ROOT"
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
fi
fi
fi
fi
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
fi
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
fi
else
AC_SUBST(BOOST_CPPFLAGS)
AC_SUBST(BOOST_LDFLAGS)
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

View File

@ -0,0 +1,115 @@
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_serialization.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_SERIALIZATION
#
# DESCRIPTION
#
# Test for Serialization library from the Boost C++ libraries. The macro
# requires a preceding call to AX_BOOST_BASE. Further documentation is
# available at <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_SERIALIZATION_LIB)
#
# And sets:
#
# HAVE_BOOST_SERIALIZATION
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved.
AC_DEFUN([AX_BOOST_SERIALIZATION],
[
AC_ARG_WITH([boost-serialization],
AS_HELP_STRING([--with-boost-serialization@<:@=special-lib@:>@],
[use the Serialization library from boost - it is possible to specify a certain library for the linker
e.g. --with-boost-serialization=boost_serialization-gcc-mt-d-1_33_1 ]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ax_boost_user_serialization_lib=""
else
want_boost="yes"
ax_boost_user_serialization_lib="$withval"
fi
],
[want_boost="yes"]
)
if test "x$want_boost" = "xyes"; then
AC_REQUIRE([AC_PROG_CC])
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
AC_MSG_WARN(BOOST_CPPFLAGS $BOOST_CPPFLAGS)
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_CACHE_CHECK(whether the Boost::Serialization library is available,
ax_cv_boost_serialization,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include <fstream>
@%:@include <boost/archive/text_oarchive.hpp>
@%:@include <boost/archive/text_iarchive.hpp>
]],
[[std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
return 0;
]]),
ax_cv_boost_serialization=yes, ax_cv_boost_serialization=no)
AC_LANG_POP([C++])
])
if test "x$ax_cv_boost_serialization" = "xyes"; then
AC_DEFINE(HAVE_BOOST_SERIALIZATION,,[define if the Boost::Serialization library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
if test "x$ax_boost_user_serialization_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_serialization*.{so,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_serialization.*\)\.so.*$;\1;' -e 's;^lib\(boost_serialization.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_SERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_SERIALIZATION_LIB) link_serialization="yes"; break],
[link_serialization="no"])
done
if test "x$link_serialization" != "xyes"; then
for libextension in `ls $BOOSTLIBDIR/boost_serialization*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_serialization.*\)\.dll.*$;\1;' -e 's;^\(boost_serialization.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_SERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_SERIALIZATION_LIB) link_serialization="yes"; break],
[link_serialization="no"])
done
fi
else
for ax_lib in $ax_boost_user_serialization_lib boost_serialization-$ax_boost_user_serialization_lib; do
AC_CHECK_LIB($ax_lib, main,
[BOOST_SERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_SERIALIZATION_LIB) link_serialization="yes"; break],
[link_serialization="no"])
done
fi
if test "x$link_serialization" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
fi
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])