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 - [email protected] + +- 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: [email protected] For additional commands, e-mail: [email protected]
