Hello community,

here is the log from the commit of package snapper for openSUSE:Factory
checked in at Mon Sep 19 18:04:51 CEST 2011.



--------
--- snapper/snapper.changes     2011-09-02 10:30:22.000000000 +0200
+++ snapper/snapper.changes     2011-09-16 14:03:08.000000000 +0200
@@ -1,0 +2,5 @@
+Thu Sep 15 16:44:26 CEST 2011 - aschn...@suse.de
+
+- added userdata to snapshots
+
+-------------------------------------------------------------------

calling whatdependson for head-i586


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ snapper.spec ++++++
--- /var/tmp/diff_new_pack.sqEARi/_old  2011-09-19 18:04:43.000000000 +0200
+++ /var/tmp/diff_new_pack.sqEARi/_new  2011-09-19 18:04:43.000000000 +0200
@@ -20,7 +20,7 @@
 
 Name:           snapper
 Version:        0.0.7
-Release:        7
+Release:        0
 License:        GPL
 Group:          System/Packages
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -74,7 +74,6 @@
 /etc/cron.daily/suse.de-snapper
 
 %package -n libsnapper1
-
 Summary:        Library for filesystem snapshot management
 Group:          System/Libraries
 Requires:       diffutils util-linux
@@ -113,7 +112,6 @@
 /sbin/ldconfig
 
 %package -n libsnapper-devel
-
 Requires:       libsnapper1 = %version
 Requires:       gcc-c++ libstdc++-devel boost-devel blocxx-devel libxml2-devel
 Summary:        Header files and documentation for libsnapper
@@ -134,7 +132,6 @@
 %{prefix}/include/snapper
 
 %package -n snapper-zypp-plugin
-
 Requires:       snapper libzypp(plugin:commit) zypp-plugin-python
 Summary:        A zypp commit plugin for calling snapper
 Group:          System/Packages
@@ -150,4 +147,5 @@
 %files -n snapper-zypp-plugin
 %defattr(-,root,root)
 /usr/lib/zypp/plugins/commit/snapper.py
+
 %changelog

++++++ snapper-0.0.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/LIBVERSION new/snapper-0.0.7/LIBVERSION
--- old/snapper-0.0.7/LIBVERSION        2011-08-11 14:53:42.000000000 +0200
+++ new/snapper-0.0.7/LIBVERSION        2011-09-16 14:00:26.000000000 +0200
@@ -1 +1 @@
-1.3.0
+1.4.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/doc/snapper.8 
new/snapper-0.0.7/doc/snapper.8
--- old/snapper-0.0.7/doc/snapper.8     2011-09-02 10:28:12.000000000 +0200
+++ new/snapper-0.0.7/doc/snapper.8     2011-09-16 14:01:54.000000000 +0200
@@ -39,6 +39,12 @@
 .LP
 Note that filesystem\-wise all three types are the same.
 
+.SS Snapshot Description und Userdata
+.LP
+With each snapshot a description and some userdata can be associated. The
+description is a string. The userdata is a list of key-value pairs where the
+keys and values are strings.
+
 .SS Automatic Snapshot Creation
 Next to manual snapshot creation snapshots are also created automatically.
 .LP
@@ -130,14 +136,19 @@
 \fI\-\-pre\-number\fR <number>
 For post snapshots the number of the pre snapshot must be provided.
 .TP
-\fI\-d, \-\-description\fR <description>
-Description for the snapshot.
-.TP
 \fI\-p, \-\-print\-number\fR
 Print number of the created snapshot.
 .TP
+\fI\-d, \-\-description\fR <description>
+Description for the snapshot.
+.TP
 \fI\-c, \-\-cleanup\-algorithm\fR <cleanup-algorithm>
-Sets the cleanup-algorithm for the snapshot.
+Set the cleanup-algorithm for the snapshot.
+.TP
+\fI\-u, \-\-userdata\fR <userdata>
+Set userdata for the snapshot. The key-value pairs must be seperated by comma
+and the key and value must be seperated by an equal sign,
+e.g. requestid=42,user=arthur.
 
 .TP
 .B modify [options] <number>
@@ -145,6 +156,14 @@
 .TP
 \fI\-d, \-\-description\fR <description>
 New description for snapshot.
+.TP
+\fI\-c, \-\-cleanup\-algorithm\fR <cleanup-algorithm>
+Set the cleanup-algorithm for the snapshot.
+.TP
+\fI\-u, \-\-userdata\fR <userdata>
+Set userdata for the snapshot. The key-value pairs must be seperated by comma
+and the key and value must be seperated by an equal sign,
+e.g. requestid=42,user=arthur.
 
 .TP
 .B delete <number>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/doc/snapper.8.in 
new/snapper-0.0.7/doc/snapper.8.in
--- old/snapper-0.0.7/doc/snapper.8.in  2011-08-31 15:48:07.000000000 +0200
+++ new/snapper-0.0.7/doc/snapper.8.in  2011-09-15 17:30:03.000000000 +0200
@@ -39,6 +39,12 @@
 .LP
 Note that filesystem\-wise all three types are the same.
 
+.SS Snapshot Description und Userdata
+.LP
+With each snapshot a description and some userdata can be associated. The
+description is a string. The userdata is a list of key-value pairs where the
+keys and values are strings.
+
 .SS Automatic Snapshot Creation
 Next to manual snapshot creation snapshots are also created automatically.
 .LP
@@ -130,14 +136,19 @@
 \fI\-\-pre\-number\fR <number>
 For post snapshots the number of the pre snapshot must be provided.
 .TP
-\fI\-d, \-\-description\fR <description>
-Description for the snapshot.
-.TP
 \fI\-p, \-\-print\-number\fR
 Print number of the created snapshot.
 .TP
+\fI\-d, \-\-description\fR <description>
+Description for the snapshot.
+.TP
 \fI\-c, \-\-cleanup\-algorithm\fR <cleanup-algorithm>
-Sets the cleanup-algorithm for the snapshot.
+Set the cleanup-algorithm for the snapshot.
+.TP
+\fI\-u, \-\-userdata\fR <userdata>
+Set userdata for the snapshot. The key-value pairs must be seperated by comma
+and the key and value must be seperated by an equal sign,
+e.g. requestid=42,user=arthur.
 
 .TP
 .B modify [options] <number>
@@ -145,6 +156,14 @@
 .TP
 \fI\-d, \-\-description\fR <description>
 New description for snapshot.
+.TP
+\fI\-c, \-\-cleanup\-algorithm\fR <cleanup-algorithm>
+Set the cleanup-algorithm for the snapshot.
+.TP
+\fI\-u, \-\-userdata\fR <userdata>
+Set userdata for the snapshot. The key-value pairs must be seperated by comma
+and the key and value must be seperated by an equal sign,
+e.g. requestid=42,user=arthur.
 
 .TP
 .B delete <number>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/examples/ListAll.cc 
new/snapper-0.0.7/examples/ListAll.cc
--- old/snapper-0.0.7/examples/ListAll.cc       1970-01-01 01:00:00.000000000 
+0100
+++ new/snapper-0.0.7/examples/ListAll.cc       2011-09-14 15:42:44.000000000 
+0200
@@ -0,0 +1,29 @@
+
+#include <stdlib.h>
+#include <iostream>
+
+#include <snapper/Factory.h>
+#include <snapper/Snapper.h>
+
+using namespace snapper;
+using namespace std;
+
+int
+main(int argc, char** argv)
+{
+    list<ConfigInfo> c = Snapper::getConfigs();
+
+    list<Snapper*> sh;
+
+    for (list<ConfigInfo>::const_iterator it = c.begin(); it != c.end(); ++it)
+       sh.push_back(new Snapper(it->config_name));
+
+    for (list<Snapper*>::const_iterator it = sh.begin(); it != sh.end(); ++it)
+       cout << (*it)->configName() << " " << (*it)->subvolumeDir() << " "
+            << (*it)->getSnapshots().size() << endl;
+
+    for (list<Snapper*>::const_iterator it = sh.begin(); it != sh.end(); ++it)
+       delete *it;
+
+    exit(EXIT_SUCCESS);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/examples/Makefile.am 
new/snapper-0.0.7/examples/Makefile.am
--- old/snapper-0.0.7/examples/Makefile.am      2011-03-02 17:26:36.000000000 
+0100
+++ new/snapper-0.0.7/examples/Makefile.am      2011-09-14 15:42:44.000000000 
+0200
@@ -6,10 +6,12 @@
 
 LDADD = ../snapper/libsnapper.la
 
-noinst_PROGRAMS = List Create CmpDirs CreateTimeline
+noinst_PROGRAMS = List ListAll Create CmpDirs CreateTimeline
 
 List_SOURCES = List.cc
 
+ListAll_SOURCES = ListAll.cc
+
 Create_SOURCES = Create.cc
 
 CmpDirs_SOURCES = CmpDirs.cc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/examples/Makefile.in 
new/snapper-0.0.7/examples/Makefile.in
--- old/snapper-0.0.7/examples/Makefile.in      2011-09-02 10:28:07.000000000 
+0200
+++ new/snapper-0.0.7/examples/Makefile.in      2011-09-16 14:01:44.000000000 
+0200
@@ -38,8 +38,8 @@
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-noinst_PROGRAMS = List$(EXEEXT) Create$(EXEEXT) CmpDirs$(EXEEXT) \
-       CreateTimeline$(EXEEXT)
+noinst_PROGRAMS = List$(EXEEXT) ListAll$(EXEEXT) Create$(EXEEXT) \
+       CmpDirs$(EXEEXT) CreateTimeline$(EXEEXT)
 subdir = examples
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -70,6 +70,10 @@
 List_OBJECTS = $(am_List_OBJECTS)
 List_LDADD = $(LDADD)
 List_DEPENDENCIES = ../snapper/libsnapper.la
+am_ListAll_OBJECTS = ListAll.$(OBJEXT)
+ListAll_OBJECTS = $(am_ListAll_OBJECTS)
+ListAll_LDADD = $(LDADD)
+ListAll_DEPENDENCIES = ../snapper/libsnapper.la
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -97,9 +101,9 @@
 am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
 am__v_GEN_0 = @echo "  GEN   " $@;
 SOURCES = $(CmpDirs_SOURCES) $(Create_SOURCES) \
-       $(CreateTimeline_SOURCES) $(List_SOURCES)
+       $(CreateTimeline_SOURCES) $(List_SOURCES) $(ListAll_SOURCES)
 DIST_SOURCES = $(CmpDirs_SOURCES) $(Create_SOURCES) \
-       $(CreateTimeline_SOURCES) $(List_SOURCES)
+       $(CreateTimeline_SOURCES) $(List_SOURCES) $(ListAll_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -226,6 +230,7 @@
 INCLUDES = -I$(top_srcdir)
 LDADD = ../snapper/libsnapper.la
 List_SOURCES = List.cc
+ListAll_SOURCES = ListAll.cc
 Create_SOURCES = Create.cc
 CmpDirs_SOURCES = CmpDirs.cc
 CreateTimeline_SOURCES = CreateTimeline.cc
@@ -284,6 +289,9 @@
 List$(EXEEXT): $(List_OBJECTS) $(List_DEPENDENCIES) 
        @rm -f List$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(List_OBJECTS) $(List_LDADD) $(LIBS)
+ListAll$(EXEEXT): $(ListAll_OBJECTS) $(ListAll_DEPENDENCIES) 
+       @rm -f ListAll$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(ListAll_OBJECTS) $(ListAll_LDADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -295,6 +303,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Create.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CreateTimeline.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListAll.Po@am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF 
$(DEPDIR)/$*.Tpo -c -o $@ $<
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Factory.h 
new/snapper-0.0.7/snapper/Factory.h
--- old/snapper-0.0.7/snapper/Factory.h 2011-06-15 11:47:50.000000000 +0200
+++ new/snapper-0.0.7/snapper/Factory.h 2011-09-14 15:42:44.000000000 +0200
@@ -35,7 +35,7 @@
     class Snapper;
 
 
-    // Only one Snapper can be created at a time.
+    // Using the factory functions only one Snapper can exist at a time.
 
     Snapper* createSnapper(const string& config_name = "root", bool 
disable_filters = false);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapper.cc 
new/snapper-0.0.7/snapper/Snapper.cc
--- old/snapper-0.0.7/snapper/Snapper.cc        2011-08-11 14:53:42.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapper.cc        2011-09-15 17:30:03.000000000 
+0200
@@ -83,6 +83,9 @@
     {
        y2mil("Snapper destructor");
 
+       for (Snapshots::iterator it = snapshots.begin(); it != snapshots.end(); 
++it)
+           it->flushInfo();
+
        delete filesystem;
        delete config;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapper.h 
new/snapper-0.0.7/snapper/Snapper.h
--- old/snapper-0.0.7/snapper/Snapper.h 2011-08-11 14:53:42.000000000 +0200
+++ new/snapper-0.0.7/snapper/Snapper.h 2011-09-15 17:30:03.000000000 +0200
@@ -87,6 +87,12 @@
        virtual const char* what() const throw() { return "invalid config"; }
     };
 
+    struct InvalidUserdataException : public std::exception
+    {
+       explicit InvalidUserdataException() throw() {}
+       virtual const char* what() const throw() { return "invalid userdata"; }
+    };
+
     struct ListConfigsFailedException : public std::exception
     {
        explicit ListConfigsFailedException(const char* msg) throw() : msg(msg) 
{}
@@ -109,6 +115,8 @@
        Snapper(const string& config_name = "root", bool disable_filters = 
false);
        ~Snapper();
 
+       string configName() const { return config_name; }
+
        string subvolumeDir() const;
        string infosDir() const;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapshot.cc 
new/snapper-0.0.7/snapper/Snapshot.cc
--- old/snapper-0.0.7/snapper/Snapshot.cc       2011-08-04 10:47:10.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapshot.cc       2011-09-16 12:00:41.000000000 
+0200
@@ -59,6 +59,9 @@
        if (!snapshot.cleanup.empty())
            s << " cleanup:\"" << snapshot.cleanup << "\"";
 
+       if (!snapshot.userdata.empty())
+           s << " userdata:\"" << snapshot.userdata << "\"";
+
        return s;
     }
 
@@ -95,16 +98,39 @@
     void
     Snapshot::setDescription(const string& val)
     {
+       if (isCurrent())
+           throw IllegalSnapshotException();
+
        description = val;
-       writeInfo();
+       info_modified = true;
     }
 
 
     void
     Snapshot::setCleanup(const string& val)
     {
+       if (isCurrent())
+           throw IllegalSnapshotException();
+
        cleanup = val;
-       writeInfo();
+       info_modified = true;
+    }
+
+
+    void
+    Snapshot::setUserdata(const map<string, string>& val)
+    {
+       if (isCurrent())
+           throw IllegalSnapshotException();
+
+       for (map<string, string>::const_iterator it = val.begin(); it != 
val.end(); ++it)
+       {
+           if (it->first.empty())
+               throw InvalidUserdataException();
+       }
+
+       userdata = val;
+       info_modified = true;
     }
 
 
@@ -112,46 +138,63 @@
     Snapshots::read()
     {
        list<string> infos = glob(snapper->infosDir() + "/*/info.xml", 
GLOB_NOSORT);
-       for (list<string>::const_iterator it = infos.begin(); it != 
infos.end(); ++it)
+       for (list<string>::const_iterator it1 = infos.begin(); it1 != 
infos.end(); ++it1)
        {
-           unsigned int num;
-           it->substr(snapper->infosDir().length() + 1) >> num;
-
-           XmlFile file(*it);
+           XmlFile file(*it1);
            const xmlNode* root = file.getRootElement();
            const xmlNode* node = getChildNode(root, "snapshot");
 
-           Snapshot snapshot(snapper);
-
            string tmp;
 
-           if (!getChildValue(node, "type", tmp) || !toValue(tmp, 
snapshot.type, true))
+           SnapshotType type;
+           if (!getChildValue(node, "type", tmp) || !toValue(tmp, type, true))
            {
-               y2err("type missing or invalid. not adding snapshot " << num);
+               y2err("type missing or invalid. not adding snapshot " << *it1);
                continue;
            }
 
-           if (!getChildValue(node, "num", snapshot.num) || num != 
snapshot.num)
+           unsigned int num;
+           if (!getChildValue(node, "num", num) || num == 0)
            {
-               y2err("num missing or invalid. not adding snapshot " << num);
+               y2err("num missing or invalid. not adding snapshot " << *it1);
                continue;
            }
 
-           if (!getChildValue(node, "date", tmp) || (snapshot.date = 
scan_datetime(tmp, true)) == -1)
+           unsigned int date;
+           if (!getChildValue(node, "date", tmp) || (date = scan_datetime(tmp, 
true)) == -1)
            {
-               y2err("date missing or invalid. not adding snapshot " << num);
+               y2err("date missing or invalid. not adding snapshot " << *it1);
                continue;
            }
 
-           getChildValue(node, "description", snapshot.description);
+           Snapshot snapshot(snapper, type, num, date);
+
+           it1->substr(snapper->infosDir().length() + 1) >> num;
+           if (num != snapshot.num)
+           {
+               y2err("num mismatch. not adding snapshot " << *it1);
+               continue;
+           }
 
            getChildValue(node, "pre_num", snapshot.pre_num);
 
+           getChildValue(node, "description", snapshot.description);
+
            getChildValue(node, "cleanup", snapshot.cleanup);
 
-           if (!snapper->getFilesystem()->checkSnapshot(num))
+           const list<const xmlNode*> l = getChildNodes(node, "userdata");
+           for (list<const xmlNode*>::const_iterator it2 = l.begin(); it2 != 
l.end(); ++it2)
+           {
+               string key, value;
+               getChildValue(*it2, "key", key);
+               getChildValue(*it2, "value", value);
+               if (!key.empty())
+                   snapshot.userdata[key] = value;
+           }
+
+           if (!snapper->getFilesystem()->checkSnapshot(snapshot.num))
            {
-               y2err("snapshot check failed. not adding snapshot " << num);
+               y2err("snapshot check failed. not adding snapshot " << *it1);
                continue;
            }
 
@@ -226,10 +269,7 @@
     {
        entries.clear();
 
-       Snapshot snapshot(snapper);
-       snapshot.type = SINGLE;
-       snapshot.num = 0;
-       snapshot.date = (time_t)(-1);
+       Snapshot snapshot(snapper, SINGLE, 0, (time_t)(-1));
        snapshot.description = "current";
        entries.push_back(snapshot);
 
@@ -298,6 +338,20 @@
 
 
     bool
+    Snapshot::flushInfo()
+    {
+       if (!info_modified)
+           return true;
+
+       if (!writeInfo())
+           return false;
+
+       info_modified = false;
+       return true;
+    }
+
+
+    bool
     Snapshot::writeInfo() const
     {
        XmlFile xml;
@@ -310,15 +364,22 @@
 
        setChildValue(node, "date", datetime(date, true, true));
 
-       if (!description.empty())
-           setChildValue(node, "description", description);
-
        if (type == POST)
            setChildValue(node, "pre_num", pre_num);
 
+       if (!description.empty())
+           setChildValue(node, "description", description);
+
        if (!cleanup.empty())
            setChildValue(node, "cleanup", cleanup);
 
+       for (map<string, string>::const_iterator it = userdata.begin(); it != 
userdata.end(); ++it)
+       {
+           xmlNode* userdata_node = xmlNewChild(node, "userdata");
+           setChildValue(userdata_node, "key", it->first);
+           setChildValue(userdata_node, "value", it->second);
+       }
+
        xml.save(infoDir() + "/info.xml");
 
        return true;
@@ -369,13 +430,10 @@
     Snapshots::iterator
     Snapshots::createSingleSnapshot(string description)
     {
-       Snapshot snapshot(snapper);
-       snapshot.type = SINGLE;
-       snapshot.num = nextNumber();
-       snapshot.date = time(NULL);
+       Snapshot snapshot(snapper, SINGLE, nextNumber(), time(NULL));
        snapshot.description = description;
+       snapshot.info_modified = true;
 
-       snapshot.writeInfo();
        snapshot.createFilesystemSnapshot();
 
        return entries.insert(entries.end(), snapshot);
@@ -385,13 +443,10 @@
     Snapshots::iterator
     Snapshots::createPreSnapshot(string description)
     {
-       Snapshot snapshot(snapper);
-       snapshot.type = PRE;
-       snapshot.num = nextNumber();
-       snapshot.date = time(NULL);
+       Snapshot snapshot(snapper, PRE, nextNumber(), time(NULL));
        snapshot.description = description;
+       snapshot.info_modified = true;
 
-       snapshot.writeInfo();
        snapshot.createFilesystemSnapshot();
 
        return entries.insert(entries.end(), snapshot);
@@ -404,13 +459,10 @@
        if (pre == entries.end() || pre->isCurrent() || pre->getType() != PRE)
            throw IllegalSnapshotException();
 
-       Snapshot snapshot(snapper);
-       snapshot.type = POST;
-       snapshot.num = nextNumber();
-       snapshot.date = time(NULL);
+       Snapshot snapshot(snapper, POST, nextNumber(), time(NULL));
        snapshot.pre_num = pre->getNum();
+       snapshot.info_modified = true;
 
-       snapshot.writeInfo();
        snapshot.createFilesystemSnapshot();
 
        return entries.insert(entries.end(), snapshot);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapshot.h 
new/snapper-0.0.7/snapper/Snapshot.h
--- old/snapper-0.0.7/snapper/Snapshot.h        2011-08-04 10:47:10.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapshot.h        2011-09-16 12:01:24.000000000 
+0200
@@ -27,12 +27,14 @@
 #include <time.h>
 #include <string>
 #include <list>
+#include <map>
 
 
 namespace snapper
 {
     using std::string;
     using std::list;
+    using std::map;
 
 
     class Snapper;
@@ -79,8 +81,9 @@
 
        friend class Snapshots;
 
-       Snapshot(const Snapper* snapper)
-           : snapper(snapper), type(SINGLE), num(0), date((time_t)(-1)), 
pre_num(0) {}
+       Snapshot(const Snapper* snapper, SnapshotType type, unsigned int num, 
time_t date)
+           : snapper(snapper), type(type), num(num), date(date), pre_num(0),
+             info_modified(false) {}
 
        SnapshotType getType() const { return type; }
 
@@ -89,14 +92,19 @@
 
        time_t getDate() const { return date; }
 
+       unsigned int getPreNum() const { return pre_num; }
+
        void setDescription(const string& description);
        string getDescription() const { return description; }
 
-       unsigned int getPreNum() const { return pre_num; }
-
        void setCleanup(const string& cleanup);
        string getCleanup() const { return cleanup; }
 
+       void setUserdata(const map<string, string>& userdata);
+       map<string, string> getUserdata() const { return userdata; }
+
+       bool flushInfo();
+
        string infoDir() const;
        string snapshotDir() const;
 
@@ -109,18 +117,22 @@
 
        const Snapper* snapper;
 
-       SnapshotType type;
+       const SnapshotType type;
 
-       unsigned int num;
+       const unsigned int num;
 
-       time_t date;
-
-       string description;     // likely empty for type=POST
+       const time_t date;
 
        unsigned int pre_num;   // valid only for type=POST
 
+       string description;     // likely empty for type=POST
+
        string cleanup;
 
+       map<string, string> userdata;
+
+       bool info_modified;
+
        bool writeInfo() const;
 
        void createFilesystemSnapshot() const;
@@ -145,6 +157,7 @@
 
        typedef list<Snapshot>::iterator iterator;
        typedef list<Snapshot>::const_iterator const_iterator;
+       typedef list<Snapshot>::size_type size_type;
 
        iterator begin() { return entries.begin(); }
        const_iterator begin() const { return entries.begin(); }
@@ -152,6 +165,8 @@
        iterator end() { return entries.end(); }
        const_iterator end() const { return entries.end(); }
 
+       size_type size() const { return entries.size(); }
+
        iterator find(unsigned int num);
        const_iterator find(unsigned int num) const;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/XmlFile.cc 
new/snapper-0.0.7/snapper/XmlFile.cc
--- old/snapper-0.0.7/snapper/XmlFile.cc        2011-02-28 16:48:13.000000000 
+0100
+++ new/snapper-0.0.7/snapper/XmlFile.cc        2011-09-15 17:30:03.000000000 
+0200
@@ -104,7 +104,11 @@
            if (cur_node->type == XML_ELEMENT_NODE &&
                strcmp(name, (const char*) cur_node->name) == 0)
            {
-               value = (const char*) cur_node->children->content;
+               if (cur_node->children && cur_node->children->content)
+                   value = (const char*) cur_node->children->content;
+               else
+                   value = "";
+
                return true;
            }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/tools/snapper.cc 
new/snapper-0.0.7/tools/snapper.cc
--- old/snapper-0.0.7/tools/snapper.cc  2011-08-31 15:48:07.000000000 +0200
+++ new/snapper-0.0.7/tools/snapper.cc  2011-09-15 18:22:18.000000000 +0200
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <iostream>
+#include <boost/algorithm/string.hpp>
 
 #include "config.h"
 #include <snapper/Factory.h>
@@ -169,7 +170,7 @@
 
 
 Snapshots::iterator
-readNum(const string& str)
+read_num(const string& str)
 {
     Snapshots& snapshots = sh->getSnapshots();
 
@@ -195,7 +196,7 @@
 
 
 pair<Snapshots::iterator, Snapshots::iterator>
-readNums(const string& str)
+read_nums(const string& str)
 {
     string::size_type pos = str.find("..");
     if (pos == string::npos)
@@ -204,8 +205,8 @@
        exit(EXIT_FAILURE);
     }
 
-    Snapshots::iterator snap1 = readNum(str.substr(0, pos));
-    Snapshots::iterator snap2 = readNum(str.substr(pos + 2));
+    Snapshots::iterator snap1 = read_num(str.substr(0, pos));
+    Snapshots::iterator snap2 = read_num(str.substr(pos + 2));
 
     if (snap1 == snap2)
     {
@@ -217,6 +218,63 @@
 }
 
 
+map<string, string>
+read_userdata(const string& s, const map<string, string>& old = map<string, 
string>())
+{
+    map<string, string> userdata = old;
+
+    list<string> tmp;
+    boost::split(tmp, s, boost::is_any_of(","), boost::token_compress_on);
+    if (tmp.empty())
+    {
+       cerr << _("Invalid userdata.") << endl;
+       exit(EXIT_FAILURE);
+    }
+
+    for (list<string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
+    {
+       string::size_type pos = it->find("=");
+       if (pos == string::npos)
+       {
+           cerr << _("Invalid userdata.") << endl;
+           exit(EXIT_FAILURE);
+       }
+
+       string key = boost::trim_copy(it->substr(0, pos));
+       string value = boost::trim_copy(it->substr(pos + 1));
+
+       if (key.empty())
+       {
+           cerr << _("Invalid userdata.") << endl;
+           exit(EXIT_FAILURE);
+       }
+
+       if (value.empty())
+           userdata.erase(key);
+       else
+           userdata[key] = value;
+    }
+
+    return userdata;
+}
+
+
+string
+show_userdata(const map<string, string>& userdata)
+{
+    string s;
+
+    for (map<string, string>::const_iterator it = userdata.begin(); it != 
userdata.end(); ++it)
+    {
+       if (!s.empty())
+           s += ", ";
+       s += it->first + "=" + it->second;
+    }
+
+    return s;
+}
+
+
 void
 help_list()
 {
@@ -277,6 +335,7 @@
            header.add(_("Date"));
            header.add(_("Cleanup"));
            header.add(_("Description"));
+           header.add(_("Userdata"));
            table.setHeader(header);
 
            const Snapshots& snapshots = sh->getSnapshots();
@@ -289,6 +348,7 @@
                row.add(it1->isCurrent() ? "" : datetime(it1->getDate(), false, 
false));
                row.add(it1->getCleanup());
                row.add(it1->getDescription());
+               row.add(show_userdata(it1->getUserdata()));
                table.add(row);
            }
        }
@@ -300,6 +360,7 @@
            header.add(_("#"));
            header.add(_("Date"));
            header.add(_("Description"));
+           header.add(_("Userdata"));
            table.setHeader(header);
 
            const Snapshots& snapshots = sh->getSnapshots();
@@ -312,6 +373,7 @@
                row.add(decString(it1->getNum()));
                row.add(it1->isCurrent() ? "" : datetime(it1->getDate(), false, 
false));
                row.add(it1->getDescription());
+               row.add(show_userdata(it1->getUserdata()));
                table.add(row);
            }
        }
@@ -325,6 +387,7 @@
            header.add(_("Pre Date"));
            header.add(_("Post Date"));
            header.add(_("Description"));
+           header.add(_("Userdata"));
            table.setHeader(header);
 
            const Snapshots& snapshots = sh->getSnapshots();
@@ -343,6 +406,7 @@
                row.add(datetime(it1->getDate(), false, false));
                row.add(datetime(it2->getDate(), false, false));
                row.add(it1->getDescription());
+               row.add(show_userdata(it1->getUserdata()));
                table.add(row);
            }
        }
@@ -362,9 +426,10 @@
         << _("    Options for 'create' command:") << endl
         << _("\t--type, -t <type>\t\tType for snapshot.") << endl
         << _("\t--pre-number <number>\t\tNumber of corresponding pre 
snapshot.") << endl
-        << _("\t--description, -d <description>\tDescription for snapshot.") 
<< endl
         << _("\t--print-number, -p\t\tPrint number of created snapshot.") << 
endl
-        << _("\t--cleanup-algorithm, -c\t\tCleanup algorithm for snapshot.") 
<< endl
+        << _("\t--description, -d <description>\tDescription for snapshot.") 
<< endl
+        << _("\t--cleanup-algorithm, -c <algo>\tCleanup algorithm for 
snapshot.") << endl
+        << _("\t--userdata, -u <userdata>\tUserdata for snapshot.") << endl
         << endl;
 }
 
@@ -375,9 +440,10 @@
     const struct option options[] = {
        { "type",               required_argument,      0,      't' },
        { "pre-number",         required_argument,      0,      0 },
-       { "description",        required_argument,      0,      'd' },
        { "print-number",       no_argument,            0,      'p' },
+       { "description",        required_argument,      0,      'd' },
        { "cleanup-algorithm",  required_argument,      0,      'c' },
+       { "userdata",           required_argument,      0,      'u' },
        { 0, 0, 0, 0 }
     };
 
@@ -392,9 +458,10 @@
 
     SnapshotType type = SINGLE;
     Snapshots::const_iterator snap1 = snapshots.end();
-    string description;
     bool print_number = false;
+    string description;
     string cleanup;
+    map<string, string> userdata;
 
     GetOpts::parsed_opts::const_iterator opt;
 
@@ -408,17 +475,20 @@
     }
 
     if ((opt = opts.find("pre-number")) != opts.end())
-       snap1 = readNum(opt->second);
-
-    if ((opt = opts.find("description")) != opts.end())
-       description = opt->second;
+       snap1 = read_num(opt->second);
 
     if ((opt = opts.find("print-number")) != opts.end())
        print_number = true;
 
+    if ((opt = opts.find("description")) != opts.end())
+       description = opt->second;
+
     if ((opt = opts.find("cleanup-algorithm")) != opts.end())
        cleanup = opt->second;
 
+    if ((opt = opts.find("userdata")) != opts.end())
+       userdata = read_userdata(opt->second);
+
     if (type == POST && (snap1 == snapshots.end() || snap1->isCurrent()))
     {
        cerr << _("Missing or invalid pre-number.") << endl;
@@ -430,6 +500,8 @@
        case SINGLE: {
            Snapshots::iterator snap1 = sh->createSingleSnapshot(description);
            snap1->setCleanup(cleanup);
+           snap1->setUserdata(userdata);
+           snap1->flushInfo();
            if (print_number)
                cout << snap1->getNum() << endl;
        } break;
@@ -437,6 +509,8 @@
        case PRE: {
            Snapshots::iterator snap1 = sh->createPreSnapshot(description);
            snap1->setCleanup(cleanup);
+           snap1->setUserdata(userdata);
+           snap1->flushInfo();
            if (print_number)
                cout << snap1->getNum() << endl;
        } break;
@@ -444,6 +518,8 @@
        case POST: {
            Snapshots::iterator snap2 = sh->createPostSnapshot(snap1);
            snap2->setCleanup(cleanup);
+           snap2->setUserdata(userdata);
+           snap2->flushInfo();
            if (print_number)
                cout << snap2->getNum() << endl;
            sh->startBackgroundComparsion(snap1, snap2);
@@ -460,6 +536,8 @@
         << endl
         << _("    Options for 'modify' command:") << endl
         << _("\t--description, -d <description>\tDescription for snapshot.") 
<< endl
+        << _("\t--cleanup-algorithm, -c <algo>\tCleanup algorithm for 
snapshot.") << endl
+        << _("\t--userdata, -u <userdata>\tUserdata for snapshot.") << endl
         << endl;
 }
 
@@ -469,27 +547,41 @@
 {
     const struct option options[] = {
        { "description",        required_argument,      0,      'd' },
+       { "cleanup-algorithm",  required_argument,      0,      'c' },
+       { "userdata",           required_argument,      0,      'u' },
        { 0, 0, 0, 0 }
     };
 
     GetOpts::parsed_opts opts = getopts.parse("modify", options);
-    if (getopts.numArgs() != 1)
+
+    if (!getopts.hasArgs())
     {
-       cerr << _("Command 'modify' needs one argument.") << endl;
+       cerr << _("Command 'modify' needs at least one argument.") << endl;
        exit(EXIT_FAILURE);
     }
 
-    Snapshots::iterator snapshot = readNum(getopts.popArg());
-    if (snapshot->isCurrent())
+    while (getopts.hasArgs())
     {
-       cerr << _("Invalid snapshot.") << endl;
-       exit(EXIT_FAILURE);
-    }
+       Snapshots::iterator snapshot = read_num(getopts.popArg());
+       if (snapshot->isCurrent())
+       {
+           cerr << _("Invalid snapshot.") << endl;
+           exit(EXIT_FAILURE);
+       }
 
-    GetOpts::parsed_opts::const_iterator opt;
+       GetOpts::parsed_opts::const_iterator opt;
 
-    if ((opt = opts.find("description")) != opts.end())
-       snapshot->setDescription(opt->second);
+       if ((opt = opts.find("description")) != opts.end())
+           snapshot->setDescription(opt->second);
+
+       if ((opt = opts.find("cleanup-algorithm")) != opts.end())
+           snapshot->setCleanup(opt->second);
+
+       if ((opt = opts.find("userdata")) != opts.end())
+           snapshot->setUserdata(read_userdata(opt->second, 
snapshot->getUserdata()));
+
+       snapshot->flushInfo();
+    }
 }
 
 
@@ -514,7 +606,7 @@
 
     while (getopts.hasArgs())
     {
-       Snapshots::iterator snapshot = readNum(getopts.popArg());
+       Snapshots::iterator snapshot = read_num(getopts.popArg());
        if (snapshot->isCurrent())
        {
            cerr << _("Invalid snapshot.") << endl;
@@ -547,7 +639,7 @@
 
     while (getopts.hasArgs())
     {
-       Snapshots::iterator snapshot = readNum(getopts.popArg());
+       Snapshots::iterator snapshot = read_num(getopts.popArg());
        if (snapshot->isCurrent())
        {
            cerr << _("Invalid snapshot.") << endl;
@@ -580,7 +672,7 @@
 
     while (getopts.hasArgs())
     {
-       Snapshots::iterator snapshot = readNum(getopts.popArg());
+       Snapshots::iterator snapshot = read_num(getopts.popArg());
        if (snapshot->isCurrent())
        {
            cerr << _("Invalid snapshot.") << endl;
@@ -621,7 +713,7 @@
 
     GetOpts::parsed_opts::const_iterator opt;
 
-    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(readNums(getopts.popArg()));
+    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(read_nums(getopts.popArg()));
 
     Comparison comparison(sh, snaps.first, snaps.second);
 
@@ -664,7 +756,7 @@
 
     GetOpts::parsed_opts::const_iterator opt;
 
-    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(readNums(getopts.popArg()));
+    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(read_nums(getopts.popArg()));
 
     Comparison comparison(sh, snaps.first, snaps.second);
 
@@ -724,7 +816,7 @@
        exit(EXIT_FAILURE);
     }
 
-    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(readNums(getopts.popArg()));
+    pair<Snapshots::const_iterator, Snapshots::const_iterator> 
snaps(read_nums(getopts.popArg()));
 
     FILE* file = NULL;
 


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to