-BUILD
+Makefile.in
+Makefile
+.deps
+.libs
+aclocal.m4
+autom4te.cache
+config.*
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+missing
+stamp-h1
--- /dev/null
+Arvin Schnell <aschnell@suse.de>
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null
+#
+# Makefile.am for snapper
+#
+
+SUBDIRS = snapper examples
+
+AUTOMAKE_OPTIONS = foreign dist-bzip2 no-dist-gzip
+
+doc_DATA = AUTHORS COPYING
+
+EXTRA_DIST = $(doc_DATA) VERSION
+
+
+snapper-$(VERSION).tar.bz2: dist-bzip2
+
+package-local: snapper-$(VERSION).tar.bz2
+ rm -f package/snapper-*.tar.bz2
+ rm -f package/*~
+ rm -f package/*.bak
+ mv snapper-$(VERSION).tar.bz2 package/
+
+package: package-local
+
--- /dev/null
+#
+# Makefile.repo for libsnapper
+#
+
+configure: all
+ ./configure
+
+all:
+ aclocal
+ autoconf
+ autoheader
+ autoreconf --force --install
+
+install: configure
+ make
+ make install
+
+reconf: all
+ ./config.status --recheck
+ ./config.status
--- /dev/null
+
+AC_INIT(snapper/Snapper.h)
+
+VERSION=`cat ./VERSION`
+
+AM_INIT_AUTOMAKE(snapper, $VERSION)
+AM_CONFIG_HEADER(config.h)
+
+AC_DISABLE_STATIC
+
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+AM_PROG_LIBTOOL
+
+AC_PREFIX_DEFAULT(/usr)
+
+dnl Automake 1.11 enables silent compilation
+dnl Disable it by "configure --disable-silent-rules" or "make V=1"
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+CFLAGS="${CFLAGS} -Wall -Wformat=2 -Wmissing-prototypes"
+CXXFLAGS="${CXXFLAGS} -std=c++0x -DHAVE_CXX0X -Wall -Wextra -Wformat=2 -Wnon-virtual-dtor -Wno-unused-parameter"
+
+docdir=\${prefix}/share/doc/packages/snapper
+fillupdir=/var/adm/fillup-templates
+
+AC_SUBST(VERSION)
+AC_SUBST(docdir)
+AC_SUBST(fillupdir)
+
+AC_OUTPUT(
+ Makefile
+ snapper/Makefile
+ examples/Makefile
+ package/snapper.spec:snapper.spec.in
+)
--- /dev/null
+List.o
+List
+Create.o
+Create
--- /dev/null
+
+#include <stdlib.h>
+#include <iostream>
+
+#include <snapper/Snapper.h>
+
+using namespace snapper;
+using namespace std;
+
+int
+main(int argc, char** argv)
+{
+ createSingleSnapshot("test");
+
+ unsigned int pre_id = createPreSnapshot("test undo");
+
+ createPostSnapshot(pre_id);
+
+ listSnapshots();
+
+ exit(EXIT_SUCCESS);
+}
--- /dev/null
+
+#include <stdlib.h>
+#include <iostream>
+
+#include <snapper/Snapper.h>
+
+using namespace snapper;
+using namespace std;
+
+int
+main(int argc, char** argv)
+{
+ listSnapshots();
+
+ exit(EXIT_SUCCESS);
+}
--- /dev/null
+#
+# Makefile.am for libsnapper/examples
+#
+
+INCLUDES = -I$(top_srcdir)
+
+LDADD = ../snapper/libsnapper.la
+
+noinst_PROGRAMS = List Create
+
+List_SOURCES = List.cc
+
+Create_SOURCES = Create.cc
+
+exampledir = $(docdir)/examples
+
+example_DATA = List.cc Create.cc
+
+EXTRA_DIST = $(example_DATA) Makefile.example
+
+install-data-local:
+ /usr/bin/install -d -p -m 755 $(DESTDIR)$(exampledir)
+ /usr/bin/install -p -m 644 Makefile.example $(DESTDIR)$(exampledir)/Makefile
--- /dev/null
+
+PROGRAMS = TestDisk TestDiskLog TestProbing TestLvm TestMd TestLoop \
+ SaveGraph ShowBytes
+
+all: $(PROGRAMS)
+
+TestDisk: TestDisk.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+TestDiskLog: TestDiskLog.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+TestProbing: TestProbing.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+TestLvm: TestLvm.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+TestMd: TestMd.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+TestLoop: TestLoop.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+SaveGraph: SaveGraph.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+ShowBytes: ShowBytes.cc
+ g++ $< -o $@ -Wall -O2 -lstorage
+
+clean:
+ rm $(PROGRAMS)
+
--- /dev/null
+snapper-*.tar.bz2
+snapper.spec
+-------------------------------------------------------------------
+Mon Jan 10 14:55:25 CET 2011 - aschnell@suse.de
+
+- started development
+
--- /dev/null
+#
+# spec file for package snapper (Version 0.0.1)
+#
+# norootforbuild
+
+Name: snapper
+Version: 0.0.1
+Release: 0
+License: GPL
+Group: System/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+Source: snapper-%{version}.tar.bz2
+Source1: snapper-rpmlintrc
+
+prefix: /usr
+
+BuildRequires: gcc-c++ boost-devel blocxx-devel doxygen dejagnu libxml2-devel
+
+Requires: btrfs-progs
+
+PreReq: %fillup_prereq
+Summary: Library for snapper management
+
+%description
+This package contains snapper, a library for filesystem snapshot management.
+
+Authors:
+--------
+ Arvin Schnell <aschnell@suse.de>
+
+%prep
+%setup -n snapper-%{version}
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG"
+export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG"
+
+aclocal
+libtoolize --force --automake --copy
+autoheader
+automake --add-missing --copy
+autoconf
+
+%{?suse_update_config:%{suse_update_config -f}}
+./configure --libdir=%{_libdir} --prefix=%{prefix} --mandir=%{_mandir} --disable-silent-rules
+make %{?jobs:-j%jobs}
+
+%check
+LOCALEDIR=$RPM_BUILD_ROOT/usr/share/locale make check
+
+%install
+make install DESTDIR="$RPM_BUILD_ROOT"
+
+install -d -m 755 $RPM_BUILD_ROOT/var/lock/snapper
+
+%{find_lang} snapper
+
+%clean
+rm -rf "$RPM_BUILD_ROOT"
+
+%files -f snapper.lang
+%defattr(-,root,root)
+%{_libdir}/libsnapper.so.*
+%dir /var/lock/libsnapper
+/var/adm/fillup-templates/sysconfig.snapper-libsnapper
+%doc %dir %{prefix}/share/doc/packages/libsnapper
+%doc %{prefix}/share/doc/packages/snapper/AUTHORS
+%doc %{prefix}/share/doc/packages/snapper/COPYING
+
+%post
+/sbin/ldconfig
+%{fillup_only -an snapper}
+
+%postun
+/sbin/ldconfig
+
+%package devel
+Requires: libsnapper = %version
+Requires: gcc-c++ libstdc++-devel boost-devel blocxx-devel libxml2-devel
+Summary: Header files and documentation for libsnapper
+Group: Development/Languages/C and C++
+
+%description devel
+This package contains header files and documentation for developing with
+libsnapper.
+
+Authors:
+--------
+ Arvin Schnell <aschnell@suse.de>
+
+%files devel
+%defattr(-,root,root)
+%{_libdir}/libsnapper.la
+%{_libdir}/libsnapper.so
+%{prefix}/include/snapper
+%doc %{prefix}/share/doc/packages/libsnapper/autodocs
+%doc %{prefix}/share/doc/packages/libsnapper/examples
+
--- /dev/null
+#
+# spec file for package snapper (Version @VERSION@)
+#
+# norootforbuild
+
+Name: snapper
+Version: @VERSION@
+Release: 0
+License: GPL
+Group: System/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+Source: snapper-%{version}.tar.bz2
+Source1: snapper-rpmlintrc
+
+prefix: /usr
+
+BuildRequires: gcc-c++ boost-devel blocxx-devel doxygen dejagnu libxml2-devel
+
+Requires: btrfs-progs
+
+PreReq: %fillup_prereq
+Summary: Library for snapper management
+
+%description
+This package contains snapper, a library for filesystem snapshot management.
+
+Authors:
+--------
+ Arvin Schnell <aschnell@suse.de>
+
+%prep
+%setup -n snapper-%{version}
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG"
+export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG"
+
+aclocal
+libtoolize --force --automake --copy
+autoheader
+automake --add-missing --copy
+autoconf
+
+%{?suse_update_config:%{suse_update_config -f}}
+./configure --libdir=%{_libdir} --prefix=%{prefix} --mandir=%{_mandir} --disable-silent-rules
+make %{?jobs:-j%jobs}
+
+%check
+LOCALEDIR=$RPM_BUILD_ROOT/usr/share/locale make check
+
+%install
+make install DESTDIR="$RPM_BUILD_ROOT"
+
+install -d -m 755 $RPM_BUILD_ROOT/var/lock/snapper
+
+%{find_lang} snapper
+
+%clean
+rm -rf "$RPM_BUILD_ROOT"
+
+%files -f snapper.lang
+%defattr(-,root,root)
+%{_libdir}/libsnapper.so.*
+%dir /var/lock/libsnapper
+/var/adm/fillup-templates/sysconfig.snapper-libsnapper
+%doc %dir %{prefix}/share/doc/packages/libsnapper
+%doc %{prefix}/share/doc/packages/snapper/AUTHORS
+%doc %{prefix}/share/doc/packages/snapper/COPYING
+
+%post
+/sbin/ldconfig
+%{fillup_only -an snapper}
+
+%postun
+/sbin/ldconfig
+
+%package devel
+Requires: libsnapper = %version
+Requires: gcc-c++ libstdc++-devel boost-devel blocxx-devel libxml2-devel
+Summary: Header files and documentation for libsnapper
+Group: Development/Languages/C and C++
+
+%description devel
+This package contains header files and documentation for developing with
+libsnapper.
+
+Authors:
+--------
+ Arvin Schnell <aschnell@suse.de>
+
+%files devel
+%defattr(-,root,root)
+%{_libdir}/libsnapper.la
+%{_libdir}/libsnapper.so
+%{prefix}/include/snapper
+%doc %{prefix}/share/doc/packages/libsnapper/autodocs
+%doc %{prefix}/share/doc/packages/libsnapper/examples
+
--- /dev/null
+*.lo
+*.la
--- /dev/null
+/*
+ * Copyright (c) [2004-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <dirent.h>
+#include <string>
+#include <boost/algorithm/string.hpp>
+
+#include <blocxx/AppenderLogger.hpp>
+#include <blocxx/FileAppender.hpp>
+#include <blocxx/Logger.hpp>
+#include <blocxx/LogMessage.hpp>
+
+#include "snapper/AppUtil.h"
+
+
+namespace snapper
+{
+ using namespace std;
+
+
+void createPath(const string& Path_Cv)
+{
+ string::size_type Pos_ii = 0;
+ while ((Pos_ii = Path_Cv.find('/', Pos_ii + 1)) != string::npos)
+ {
+ string Tmp_Ci = Path_Cv.substr(0, Pos_ii);
+ mkdir(Tmp_Ci.c_str(), 0777);
+ }
+ mkdir(Path_Cv.c_str(), 0777);
+}
+
+
+bool
+checkDir(const string& Path_Cv)
+{
+ struct stat Stat_ri;
+
+ return (stat(Path_Cv.c_str(), &Stat_ri) >= 0 &&
+ S_ISDIR(Stat_ri.st_mode));
+}
+
+
+bool
+getStatMode(const string& Path_Cv, mode_t& val )
+{
+ struct stat Stat_ri;
+ int ret_ii = stat(Path_Cv.c_str(), &Stat_ri);
+
+ if( ret_ii==0 )
+ val = Stat_ri.st_mode;
+ else
+ y2mil( "stat " << Path_Cv << " ret:" << ret_ii );
+
+ return (ret_ii==0);
+}
+
+bool
+setStatMode(const string& Path_Cv, mode_t val )
+{
+ int ret_ii = chmod( Path_Cv.c_str(), val );
+ if( ret_ii!=0 )
+ y2mil( "chmod " << Path_Cv << " ret:" << ret_ii );
+ return( ret_ii==0 );
+}
+
+
+bool
+checkNormalFile(const string& Path_Cv)
+{
+ struct stat Stat_ri;
+
+ return (stat(Path_Cv.c_str(), &Stat_ri) >= 0 &&
+ S_ISREG(Stat_ri.st_mode));
+}
+
+
+ list<string>
+ glob(const string& path, int flags)
+ {
+ list<string> ret;
+
+ glob_t globbuf;
+ if (glob(path.c_str(), flags, 0, &globbuf) == 0)
+ {
+ for (char** p = globbuf.gl_pathv; *p != 0; p++)
+ ret.push_back(*p);
+ }
+ globfree (&globbuf);
+
+ return ret;
+ }
+
+
+static const blocxx::String component = "libsnapper";
+
+
+void createLogger(const string& name, const string& logpath, const string& logfile)
+{
+ using namespace blocxx;
+
+ if (logpath != "NULL" && logfile != "NULL")
+ {
+ String nm = name.c_str();
+ LoggerConfigMap configItems;
+ LogAppenderRef logApp;
+ if (logpath != "STDERR" && logfile != "STDERR" &&
+ logpath != "SYSLOG" && logfile != "SYSLOG")
+ {
+ String StrKey;
+ String StrPath;
+ StrKey.format("log.%s.location", name.c_str());
+ StrPath = (logpath + "/" + logfile).c_str();
+ configItems[StrKey] = StrPath;
+ logApp =
+ LogAppender::createLogAppender(nm, LogAppender::ALL_COMPONENTS,
+ LogAppender::ALL_CATEGORIES,
+ "%d %-5p %c(%P) %F(%M):%L - %m",
+ LogAppender::TYPE_FILE,
+ configItems);
+ }
+ else if (logpath == "STDERR" && logfile == "STDERR")
+ {
+ logApp =
+ LogAppender::createLogAppender(nm, LogAppender::ALL_COMPONENTS,
+ LogAppender::ALL_CATEGORIES,
+ "%d %-5p %c(%P) %F(%M):%L - %m",
+ LogAppender::TYPE_STDERR,
+ configItems);
+ }
+ else
+ {
+ logApp =
+ LogAppender::createLogAppender(nm, LogAppender::ALL_COMPONENTS,
+ LogAppender::ALL_CATEGORIES,
+ "%d %-5p %c(%P) %F(%M):%L - %m",
+ LogAppender::TYPE_SYSLOG,
+ configItems);
+ }
+
+ LogAppender::setDefaultLogAppender(logApp);
+ }
+}
+
+
+bool
+testLogLevel(LogLevel level)
+{
+ using namespace blocxx;
+
+ ELogLevel curLevel = LogAppender::getCurrentLogAppender()->getLogLevel();
+
+ switch (level)
+ {
+ case DEBUG:
+ return curLevel >= ::blocxx::E_DEBUG_LEVEL;
+ case MILESTONE:
+ return curLevel >= ::blocxx::E_INFO_LEVEL;
+ case WARNING:
+ return curLevel >= ::blocxx::E_WARNING_LEVEL;
+ case ERROR:
+ return curLevel >= ::blocxx::E_ERROR_LEVEL;
+ default:
+ return curLevel >= ::blocxx::E_FATAL_ERROR_LEVEL;
+ }
+}
+
+
+void
+prepareLogStream(ostringstream& stream)
+{
+ stream.imbue(std::locale::classic());
+ stream.setf(std::ios::boolalpha);
+ stream.setf(std::ios::showbase);
+}
+
+
+ostringstream*
+logStreamOpen()
+{
+ std::ostringstream* stream = new ostringstream;
+ prepareLogStream(*stream);
+ return stream;
+}
+
+
+void
+logStreamClose(LogLevel level, const char* file, unsigned line, const char* func,
+ ostringstream* stream)
+{
+ using namespace blocxx;
+
+ ELogLevel curLevel = LogAppender::getCurrentLogAppender()->getLogLevel();
+ String category;
+
+ switch (level)
+ {
+ case DEBUG:
+ if (curLevel >= ::blocxx::E_DEBUG_LEVEL)
+ category = Logger::STR_DEBUG_CATEGORY;
+ break;
+ case MILESTONE:
+ if (curLevel >= ::blocxx::E_INFO_LEVEL)
+ category = Logger::STR_INFO_CATEGORY;
+ break;
+ case WARNING:
+ if (curLevel >= ::blocxx::E_WARNING_LEVEL)
+ category = Logger::STR_WARNING_CATEGORY;
+ break;
+ case ERROR:
+ if (curLevel >= ::blocxx::E_ERROR_LEVEL)
+ category = Logger::STR_ERROR_CATEGORY;
+ break;
+ default:
+ if (curLevel >= ::blocxx::E_FATAL_ERROR_LEVEL)
+ category = Logger::STR_FATAL_CATEGORY;
+ break;
+ }
+
+ if (!category.empty())
+ {
+ string tmp = stream->str();
+
+ string::size_type pos1 = 0;
+
+ while (true)
+ {
+ string::size_type pos2 = tmp.find('\n', pos1);
+
+ if (pos2 != string::npos || pos1 != tmp.length())
+ LogAppender::getCurrentLogAppender()->logMessage(LogMessage(component, category,
+ String(tmp.substr(pos1, pos2 - pos1)),
+ file, line, func));
+
+ if (pos2 == string::npos)
+ break;
+
+ pos1 = pos2 + 1;
+ }
+ }
+
+ delete stream;
+}
+
+
+bool
+readlink(const string& path, string& buf)
+{
+ char tmp[1024];
+ int count = ::readlink(path.c_str(), tmp, sizeof(tmp));
+ if (count >= 0)
+ buf = string(tmp, count);
+ return count != -1;
+}
+
+
+ bool
+ readlinkat(int fd, const string& path, string& buf)
+ {
+ char tmp[1024];
+ int count = ::readlinkat(fd, path.c_str(), tmp, sizeof(tmp));
+ if (count >= 0)
+ buf = string(tmp, count);
+ return count != -1;
+ }
+
+
+ void
+ Text::clear()
+ {
+ native.clear();
+ text.clear();
+ }
+
+
+ const Text&
+ Text::operator+=(const Text& a)
+ {
+ native += a.native;
+ text += a.text;
+ return *this;
+ }
+
+
+ string
+ sformat(const string& format, va_list ap)
+ {
+ char* result;
+
+ if (vasprintf(&result, format.c_str(), ap) == -1)
+ return string();
+
+ string str(result);
+ free(result);
+ return str;
+ }
+
+
+ Text
+ sformat(const Text& format, ...)
+ {
+ Text text;
+ va_list ap;
+
+ va_start(ap, format);
+ text.native = sformat(format.native, ap);
+ va_end(ap);
+
+ va_start(ap, format);
+ text.text = sformat(format.text, ap);
+ va_end(ap);
+
+ return text;
+ }
+
+
+ Text _(const char* msgid)
+ {
+ return Text(msgid, dgettext("libsnapper", msgid));
+ }
+
+ Text _(const char* msgid, const char* msgid_plural, unsigned long int n)
+ {
+ return Text(n == 1 ? msgid : msgid_plural, dngettext("libsnapper", msgid, msgid_plural, n));
+ }
+
+
+ string
+ hostname()
+ {
+ struct utsname buf;
+ if (uname(&buf) != 0)
+ return string("unknown");
+ string hostname(buf.nodename);
+ if (strlen(buf.domainname) > 0)
+ hostname += "." + string(buf.domainname);
+ return hostname;
+ }
+
+
+ string
+ datetime()
+ {
+ time_t t1 = time(NULL);
+ struct tm t2;
+ gmtime_r(&t1, &t2);
+ char buf[64 + 1];
+ if (strftime(buf, sizeof(buf), "%F %T %Z", &t2) == 0)
+ return string("unknown");
+ return string(buf);
+ }
+
+
+ StopWatch::StopWatch()
+ {
+ gettimeofday(&start_tv, NULL);
+ }
+
+
+ std::ostream& operator<<(std::ostream& s, const StopWatch& sw)
+ {
+ struct timeval stop_tv;
+ gettimeofday(&stop_tv, NULL);
+
+ struct timeval tv;
+ timersub(&stop_tv, &sw.start_tv, &tv);
+
+ return s << fixed << double(tv.tv_sec) + (double)(tv.tv_usec) / 1000000.0 << "s";
+ }
+
+
+const string app_ws = " \t\n";
+
+}
--- /dev/null
+/*
+ * Copyright (c) [2004-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef APP_UTIL_H
+#define APP_UTIL_H
+
+#include <libintl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sstream>
+#include <locale>
+#include <string>
+#include <list>
+#include <map>
+
+
+namespace snapper
+{
+ using std::string;
+ using std::list;
+ using std::map;
+
+
+void createPath(const string& Path_Cv);
+bool checkNormalFile(const string& Path_Cv);
+bool checkDir(const string& Path_Cv);
+bool getStatMode(const string& Path_Cv, mode_t& val );
+bool setStatMode(const string& Path_Cv, mode_t val );
+
+ list<string> glob(const string& path, int flags);
+
+template<class StreamType>
+void classic(StreamType& stream)
+{
+ stream.imbue(std::locale::classic());
+}
+
+
+enum LogLevel { DEBUG, MILESTONE, WARNING, ERROR };
+
+void createLogger(const string& name, const string& logpath, const string& logfile);
+
+bool testLogLevel(LogLevel level);
+
+void prepareLogStream(std::ostringstream& stream);
+
+std::ostringstream* logStreamOpen();
+
+void logStreamClose(LogLevel level, const char* file, unsigned line,
+ const char* func, std::ostringstream*);
+
+#define y2deb(op) y2log_op(snapper::DEBUG, __FILE__, __LINE__, __FUNCTION__, op)
+#define y2mil(op) y2log_op(snapper::MILESTONE, __FILE__, __LINE__, __FUNCTION__, op)
+#define y2war(op) y2log_op(snapper::WARNING, __FILE__, __LINE__, __FUNCTION__, op)
+#define y2err(op) y2log_op(snapper::ERROR, __FILE__, __LINE__, __FUNCTION__, op)
+
+#define y2log_op(level, file, line, func, op) \
+ do { \
+ if (snapper::testLogLevel(level)) \
+ { \
+ std::ostringstream* __buf = snapper::logStreamOpen(); \
+ *__buf << op; \
+ snapper::logStreamClose(level, file, line, func, __buf); \
+ } \
+ } while (0)
+
+
+ string hostname();
+ string datetime();
+
+
+ class StopWatch
+ {
+ public:
+
+ StopWatch();
+
+ friend std::ostream& operator<<(std::ostream& s, const StopWatch& sw);
+
+ protected:
+
+ struct timeval start_tv;
+
+ };
+
+
+ struct Text
+ {
+ Text() : native(), text() {}
+ Text(const string& native, const string& text) : native(native), text(text) {}
+
+ void clear();
+
+ const Text& operator+=(const Text& a);
+
+ string native;
+ string text;
+ };
+
+
+ Text sformat(const Text& format, ...);
+
+
+ Text _(const char* msgid);
+ Text _(const char* msgid, const char* msgid_plural, unsigned long int n);
+
+
+extern const string app_ws;
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) [2010-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include "snapper/Enum.h"
+#include "snapper/SnapperTmpl.h"
+
+
+namespace snapper
+{
+
+ static const string snapshot_type_names[] = {
+ "single", "pre", "post"
+ };
+
+ const vector<string> EnumInfo<SnapshotType>::names(snapshot_type_names, snapshot_type_names +
+ lengthof(snapshot_type_names));
+
+}
--- /dev/null
+/*
+ * Copyright (c) [2010-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef ENUM_H
+#define ENUM_H
+
+
+#include <assert.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#include "snapper/Snapper.h"
+#include "snapper/AppUtil.h"
+
+
+namespace snapper
+{
+ using std::string;
+ using std::vector;
+
+
+ template <typename EnumType> struct EnumInfo {};
+
+ template <> struct EnumInfo<SnapshotType> { static const vector<string> names; };
+
+
+ template <typename EnumType>
+ const string& toString(EnumType value)
+ {
+ static_assert(std::is_enum<EnumType>::value, "not enum");
+
+ const vector<string>& names = EnumInfo<EnumType>::names;
+
+ // Comparisons must not be done with type of enum since the enum may
+ // define comparison operators.
+ assert((size_t)(value) < names.size());
+
+ return names[value];
+ }
+
+
+ template <typename EnumType>
+ bool toValue(const string& str, EnumType& value, bool log_error = true)
+ {
+ static_assert(std::is_enum<EnumType>::value, "not enum");
+
+ const vector<string>& names = EnumInfo<EnumType>::names;
+
+ vector<string>::const_iterator it = find(names.begin(), names.end(), str);
+
+ if (it == names.end())
+ {
+ if (log_error)
+ y2err("converting '" << str << "' to enum failed");
+ return false;
+ }
+
+ value = EnumType(it - names.begin());
+ return true;
+ }
+
+
+ template <typename EnumType>
+ EnumType toValueWithFallback(const string& str, EnumType fallback, bool log_error = true)
+ {
+ EnumType value;
+
+ if (toValue(str, value, log_error))
+ return value;
+
+ return fallback;
+ }
+
+}
+
+
+#endif
--- /dev/null
+#
+# Makefile.am for libsnapper/snapper
+#
+
+lib_LTLIBRARIES = libsnapper.la
+
+libsnapper_la_SOURCES = \
+ SnapperInterface.h \
+ Snapper.cc Snapper.h \
+ XmlFile.cc XmlFile.h \
+ Enum.cc Enum.h \
+ AppUtil.cc AppUtil.h \
+ SnapperTmpl.h
+
+libsnapper_la_LDFLAGS = -version-info 2:0
+libsnapper_la_LIBADD = -lblocxx -lxml2
+
+pkgincludedir = $(includedir)/snapper
+
+pkginclude_HEADERS = \
+ SnapperInterface.h
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include <glob.h>
+#include <map>
+#include <iostream>
+
+#include "snapper/Snapper.h"
+#include "snapper/AppUtil.h"
+#include "snapper/XmlFile.h"
+#include "snapper/Enum.h"
+#include "snapper/SnapperTmpl.h"
+
+
+namespace snapper
+{
+ using namespace std;
+
+
+ bool initialized = false;
+
+ map<unsigned int, Snapshot> snapshots;
+
+
+ std::ostream& operator<<(std::ostream& s, const Snapshot& x)
+ {
+ s << "type:" << toString(x.type) << " date:" << x.date;
+
+ if (!x.description.empty())
+ s << " description:" << x.description;
+
+ if (x.pre_num != 0)
+ s << " pre-num:" << x.pre_num;
+
+ return s;
+ }
+
+
+ void
+ readSnapshots()
+ {
+ list<string> infos = glob("/snapshots/*/snapshot.info", GLOB_NOSORT);
+ for (list<string>::const_iterator it = infos.begin(); it != infos.end(); ++it)
+ {
+ unsigned int num;
+ it->substr(11) >> num;
+
+ XmlFile file(*it);
+ const xmlNode* root = file.getRootElement();
+ const xmlNode* node = getChildNode(root, "snapshot");
+
+ Snapshot snapshot;
+
+ string tmp;
+
+ if (getChildValue(node, "type", tmp))
+ {
+ if (!toValue(tmp, snapshot.type, true))
+ {
+ }
+ }
+
+ getChildValue(node, "date", snapshot.date);
+
+ getChildValue(node, "description", snapshot.description);
+
+ getChildValue(node, "pre_num", snapshot.pre_num);
+
+ snapshots[num] = snapshot;
+ }
+ }
+
+
+ void
+ initialize()
+ {
+ initialized = true;
+
+ readSnapshots();
+ }
+
+
+ void
+ assertInit()
+ {
+ if (!initialized)
+ initialize();
+ }
+
+
+ const map<unsigned int, Snapshot>&
+ getSnapshots()
+ {
+ assertInit();
+
+ return snapshots;
+ }
+
+
+ void
+ listSnapshots()
+ {
+ assertInit();
+
+ for (map<unsigned int, Snapshot>::const_iterator it = snapshots.begin();
+ it != snapshots.end(); ++it)
+ {
+ cout << it->first << " " << it->second << endl;
+ }
+ }
+
+
+ unsigned int
+ nextSnapshotNumber()
+ {
+ assertInit();
+
+ unsigned int num = 1;
+
+ if (!snapshots.empty())
+ num = snapshots.rbegin()->first + 1;
+
+ return num;
+ }
+
+
+ bool
+ writeInfo(unsigned int num, const Snapshot& snapshot)
+ {
+ createPath("/snapshots/" + decString(num));
+
+ XmlFile xml;
+ xmlNode* node = xmlNewNode("snapshot");
+ xml.setRootElement(node);
+
+ setChildValue(node, "type", toString(snapshot.type));
+
+ setChildValue(node, "date", snapshot.date);
+
+ if (snapshot.type == SINGLE || snapshot.type == PRE)
+ setChildValue(node, "description", snapshot.description);
+
+ if (snapshot.type == POST)
+ setChildValue(node, "pre_num", snapshot.pre_num);
+
+ xml.save("/snapshots/" + decString(num) + "/snapshot.info");
+
+ return true;
+ }
+
+
+ unsigned int
+ createSingleSnapshot(string description)
+ {
+ Snapshot snapshot;
+ snapshot.type = SINGLE;
+ snapshot.date = datetime();
+ snapshot.description = description;
+
+ unsigned int num = nextSnapshotNumber();
+ snapshots[num] = snapshot;
+ writeInfo(num, snapshot);
+ return num;
+ }
+
+
+ unsigned int
+ createPreSnapshot(string description)
+ {
+ Snapshot snapshot;
+ snapshot.type = PRE;
+ snapshot.date = datetime();
+ snapshot.description = description;
+
+ unsigned int num = nextSnapshotNumber();
+ snapshots[num] = snapshot;
+ writeInfo(num, snapshot);
+ return num;
+ }
+
+
+ unsigned int
+ createPostSnapshot(unsigned int pre_num)
+ {
+ Snapshot snapshot;
+ snapshot.type = POST;
+ snapshot.date = datetime();
+ snapshot.pre_num = pre_num;
+
+ unsigned int num = nextSnapshotNumber();
+ snapshots[num] = snapshot;
+ writeInfo(num, snapshot);
+ return num;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef SNAPPER_H
+#define SNAPPER_H
+
+
+#include "snapper/SnapperInterface.h"
+
+
+namespace snapper
+{
+ using namespace std;
+
+
+ extern bool initialized;
+
+ extern map<unsigned int, Snapshot> snapshots;
+
+};
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef SNAPPER_INTERFACE_H
+#define SNAPPER_INTERFACE_H
+
+
+#include <string>
+#include <map>
+#include <list>
+
+
+namespace snapper
+{
+ using std::string;
+ using std::map;
+ using std::list;
+
+
+ enum SnapshotType { SINGLE, PRE, POST };
+
+
+ class Snapshot
+ {
+ public:
+
+ Snapshot() : type(SINGLE), pre_num(0) {}
+
+ SnapshotType type;
+
+ string date;
+
+ string description; // empty for type=POST
+
+ unsigned int pre_num; // valid only for type=POST
+
+ };
+
+
+ const map<unsigned int, Snapshot>& getSnapshots();
+
+ void listSnapshots(); // only for testing
+
+
+ unsigned int createSingleSnapshot(string description);
+
+ unsigned int createPreSnapshot(string description);
+
+ unsigned int createPostSnapshot(unsigned int pre_num);
+
+}
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) [2004-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef SNAPPER_TMPL_H
+#define SNAPPER_TMPL_H
+
+#include <functional>
+#include <ostream>
+#include <fstream>
+#include <sstream>
+#include <list>
+#include <map>
+#include <deque>
+#include <iostream>
+
+#include "snapper/AppUtil.h"
+
+namespace snapper
+{
+ using namespace std;
+
+
+ template<class Num> string decString(Num number)
+ {
+ static_assert(std::is_integral<Num>::value, "not integral");
+
+ std::ostringstream num_str;
+ classic(num_str);
+ num_str << number;
+ return num_str.str();
+ }
+
+ template<class Num> string hexString(Num number)
+ {
+ static_assert(std::is_integral<Num>::value, "not integral");
+
+ std::ostringstream num_str;
+ classic(num_str);
+ num_str << std::hex << number;
+ return num_str.str();
+ }
+
+ template<class Value> void operator>>(const string& d, Value& v)
+ {
+ std::istringstream Data(d);
+ classic(Data);
+ Data >> v;
+ }
+
+ template<class Value> std::ostream& operator<<( std::ostream& s, const std::list<Value>& l )
+ {
+ s << "<";
+ for( typename std::list<Value>::const_iterator i=l.begin(); i!=l.end(); i++ )
+ {
+ if( i!=l.begin() )
+ s << " ";
+ s << *i;
+ }
+ s << ">";
+ return( s );
+ }
+
+ template<class Value> std::ostream& operator<<( std::ostream& s, const std::deque<Value>& l )
+ {
+ s << "<";
+ for( typename std::deque<Value>::const_iterator i=l.begin(); i!=l.end(); i++ )
+ {
+ if( i!=l.begin() )
+ s << " ";
+ s << *i;
+ }
+ s << ">";
+ return( s );
+ }
+
+ template<class F, class S> std::ostream& operator<<( std::ostream& s, const std::pair<F,S>& p )
+ {
+ s << "[" << p.first << ":" << p.second << "]";
+ return( s );
+ }
+
+ template<class Key, class Value> std::ostream& operator<<( std::ostream& s, const std::map<Key,Value>& m )
+ {
+ s << "<";
+ for( typename std::map<Key,Value>::const_iterator i=m.begin(); i!=m.end(); i++ )
+ {
+ if( i!=m.begin() )
+ s << " ";
+ s << i->first << ":" << i->second;
+ }
+ s << ">";
+ return( s );
+ }
+
+
+ template <typename Type>
+ void logDiff(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
+ {
+ static_assert(!std::is_enum<Type>::value, "is enum");
+
+ if (lhs != rhs)
+ log << " " << text << ":" << lhs << "-->" << rhs;
+ }
+
+ template <typename Type>
+ void logDiffHex(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
+ {
+ static_assert(std::is_integral<Type>::value, "not integral");
+
+ if (lhs != rhs)
+ log << " " << text << ":" << std::hex << lhs << "-->" << rhs << std::dec;
+ }
+
+ template <typename Type>
+ void logDiffEnum(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
+ {
+ static_assert(std::is_enum<Type>::value, "not enum");
+
+ if (lhs != rhs)
+ log << " " << text << ":" << toString(lhs) << "-->" << toString(rhs);
+ }
+
+ inline
+ void logDiff(std::ostream& log, const char* text, bool lhs, bool rhs)
+ {
+ if (lhs != rhs)
+ {
+ if (rhs)
+ log << " -->" << text;
+ else
+ log << " " << text << "-->";
+ }
+ }
+
+
+ template<class Type>
+ struct deref_less : public std::binary_function<const Type*, const Type*, bool>
+ {
+ bool operator()(const Type* x, const Type* y) const { return *x < *y; }
+ };
+
+
+ template<class Type>
+ struct deref_equal_to : public std::binary_function<const Type*, const Type*, bool>
+ {
+ bool operator()(const Type* x, const Type* y) const { return *x == *y; }
+ };
+
+
+ template <class Type>
+ void pointerIntoSortedList(list<Type*>& l, Type* e)
+ {
+ l.insert(lower_bound(l.begin(), l.end(), e, deref_less<Type>()), e);
+ }
+
+
+ template <class Type>
+ void clearPointerList(list<Type*>& l)
+ {
+ for (typename list<Type*>::iterator i = l.begin(); i != l.end(); ++i)
+ delete *i;
+ l.clear();
+ }
+
+
+ template <typename ListType, typename Type>
+ bool contains(const ListType& l, const Type& value)
+ {
+ return find(l.begin(), l.end(), value) != l.end();
+ }
+
+
+ template <typename ListType, typename Predicate>
+ bool contains_if(const ListType& l, Predicate pred)
+ {
+ return find_if(l.begin(), l.end(), pred) != l.end();
+ }
+
+
+ template<typename Map, typename Key, typename Value>
+ typename Map::iterator mapInsertOrReplace(Map& m, const Key& k, const Value& v)
+ {
+ typename Map::iterator pos = m.lower_bound(k);
+ if (pos != m.end() && !typename Map::key_compare()(k, pos->first))
+ pos->second = v;
+ else
+ pos = m.insert(pos, typename Map::value_type(k, v));
+ return pos;
+ }
+
+ template<typename List, typename Value>
+ typename List::const_iterator addIfNotThere(List& l, const Value& v)
+ {
+ typename List::const_iterator pos = find( l.begin(), l.end(), v );
+ if (pos == l.end() )
+ pos = l.insert(l.end(), v);
+ return pos;
+ }
+
+
+ template <class T, unsigned int sz>
+ inline unsigned int lengthof(T (&)[sz]) { return sz; }
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) [2010-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include <string.h>
+
+#include "snapper/XmlFile.h"
+
+
+namespace snapper
+{
+
+ XmlFile::XmlFile()
+ : doc(xmlNewDoc((const xmlChar*) "1.0"))
+ {
+ }
+
+
+ XmlFile::XmlFile(const string& filename)
+ : doc(xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS | XML_PARSE_NONET))
+ {
+ }
+
+
+ XmlFile::~XmlFile()
+ {
+ if (doc)
+ xmlFreeDoc(doc);
+ }
+
+
+ xmlNode*
+ xmlNewNode(const char* name)
+ {
+ return ::xmlNewNode(NULL, (const xmlChar*) name);
+ }
+
+
+ xmlNode*
+ xmlNewChild(xmlNode* node, const char* name)
+ {
+ return ::xmlNewChild(node, NULL, (const xmlChar*) name, NULL);
+ }
+
+
+ const xmlNode*
+ getChildNode(const xmlNode* node, const char* name)
+ {
+ for (const xmlNode* cur_node = node; cur_node; cur_node = cur_node->next)
+ {
+ if (strcmp(name, (const char*) cur_node->name) == 0)
+ {
+ if (cur_node->children)
+ return cur_node->children;
+ }
+ }
+
+ return NULL;
+ }
+
+
+ list<const xmlNode*>
+ getChildNodes(const xmlNode* node, const char* name)
+ {
+ list<const xmlNode*> ret;
+
+ for (const xmlNode* cur_node = node; cur_node; cur_node = cur_node->next)
+ {
+ if (cur_node->type == XML_ELEMENT_NODE &&
+ strcmp(name, (const char*) cur_node->name) == 0)
+ {
+ if (cur_node->children)
+ ret.push_back(cur_node->children);
+ }
+ }
+
+ return ret;
+ }
+
+
+ bool
+ getChildValue(const xmlNode* node, const char* name, string& value)
+ {
+ for (const xmlNode* cur_node = node; cur_node; cur_node = cur_node->next)
+ {
+ if (cur_node->type == XML_ELEMENT_NODE &&
+ strcmp(name, (const char*) cur_node->name) == 0)
+ {
+ value = (const char*) cur_node->children->content;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ bool
+ getChildValue(const xmlNode* node, const char* name, bool& value)
+ {
+ string tmp;
+ if (!getChildValue(node, name, tmp))
+ return false;
+
+ value = tmp == "true";
+ return true;
+ }
+
+
+ void
+ setChildValue(xmlNode* node, const char* name, const char* value)
+ {
+ xmlNewTextChild(node, NULL, (const xmlChar*) name, (const xmlChar*) value);
+ }
+
+
+ void
+ setChildValue(xmlNode* node, const char* name, const string& value)
+ {
+ xmlNewTextChild(node, NULL, (const xmlChar*) name, (const xmlChar*) value.c_str());
+ }
+
+
+ void
+ setChildValue(xmlNode* node, const char* name, bool value)
+ {
+ xmlNewTextChild(node, NULL, (const xmlChar*) name, (const xmlChar*)(value ? "true" : "false"));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) [2010-2011] Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef XML_FILE_H
+#define XML_FILE_H
+
+
+#include <libxml/tree.h>
+#include <string>
+#include <list>
+#include <boost/noncopyable.hpp>
+
+#include "snapper/AppUtil.h"
+
+
+namespace snapper
+{
+ using namespace std;
+
+
+ class XmlFile : boost::noncopyable
+ {
+
+ public:
+
+ XmlFile();
+ XmlFile(const string& filename);
+
+ ~XmlFile();
+
+ bool save(const string& filename)
+ { return xmlSaveFormatFile(filename.c_str(), doc, 1); }
+
+ void setRootElement(xmlNode* node)
+ { xmlDocSetRootElement(doc, node); }
+
+ const xmlNode* getRootElement() const
+ { return xmlDocGetRootElement(doc); }
+
+ private:
+
+ xmlDoc* doc;
+
+ };
+
+
+ xmlNode* xmlNewNode(const char* name);
+ xmlNode* xmlNewChild(xmlNode* node, const char* name);
+
+
+ const xmlNode* getChildNode(const xmlNode* node, const char* name);
+ list<const xmlNode*> getChildNodes(const xmlNode* node, const char* name);
+
+
+ bool getChildValue(const xmlNode* node, const char* name, string& value);
+ bool getChildValue(const xmlNode* node, const char* name, bool& value);
+
+ template<typename Type>
+ bool getChildValue(const xmlNode* node, const char* name, Type& value)
+ {
+ string tmp;
+ if (!getChildValue(node, name, tmp))
+ return false;
+
+ std::istringstream istr(tmp);
+ classic(istr);
+ istr >> value;
+ return true;
+ }
+
+
+ void setChildValue(xmlNode* node, const char* name, const char* value);
+ void setChildValue(xmlNode* node, const char* name, const string& value);
+ void setChildValue(xmlNode* node, const char* name, bool value);
+
+ template<typename Type>
+ void setChildValue(xmlNode* node, const char* name, const Type& value)
+ {
+ std::ostringstream ostr;
+ classic(ostr);
+ ostr << value;
+ setChildValue(node, name, ostr.str());
+ }
+
+ template<typename Type>
+ void setChildValue(xmlNode* node, const char* name, const list<Type>& values)
+ {
+ for (typename list<Type>::const_iterator it = values.begin(); it != values.end(); ++it)
+ setChildValue(node, name, *it);
+ }
+
+}
+
+
+#endif