header.add(_("#"));
header.add(_("Pre #"));
header.add(_("Date"));
+ header.add(_("User"));
header.add(_("Cleanup"));
header.add(_("Description"));
header.add(_("Userdata"));
row.add(decString(it1->getNum()));
row.add(it1->getType() == POST ? decString(it1->getPreNum()) : "");
row.add(it1->isCurrent() ? "" : datetime(it1->getDate(), false, false));
+ row.add(username(it1->getUid()));
row.add(it1->getCleanup());
row.add(it1->getDescription());
row.add(show_userdata(it1->getUserdata()));
TableHeader header;
header.add(_("#"));
header.add(_("Date"));
+ header.add(_("User"));
header.add(_("Description"));
header.add(_("Userdata"));
table.setHeader(header);
TableRow row;
row.add(decString(it1->getNum()));
row.add(it1->isCurrent() ? "" : datetime(it1->getDate(), false, false));
+ row.add(username(it1->getUid()));
row.add(it1->getDescription());
row.add(show_userdata(it1->getUserdata()));
table.add(row);
namespace DBus
{
const char* TypeInfo<XConfigInfo>::signature = "(ssa{ss})";
- const char* TypeInfo<XSnapshot>::signature = "(uqutssa{ss})";
+ const char* TypeInfo<XSnapshot>::signature = "(uqutussa{ss})";
const char* TypeInfo<XFile>::signature = "(su)";
operator>>(Hihi& hihi, XSnapshot& data)
{
hihi.open_recurse();
- hihi >> data.num >> data.type >> data.pre_num >> data.date >> data.description
+ hihi >> data.num >> data.type >> data.pre_num >> data.date >> data.uid >> data.description
>> data.cleanup >> data.userdata;
hihi.close_recurse();
return hihi;
time_t getDate() const { return date; }
+ uid_t getUid() const { return uid; }
+
unsigned int getPreNum() const { return pre_num; }
string getDescription() const { return description; }
SnapshotType type;
unsigned int num;
time_t date;
+ uid_t uid;
unsigned int pre_num;
string description;
string cleanup;
#!/usr/bin/python
+from time import gmtime, asctime
+from pwd import getpwuid
import dbus
bus = dbus.SystemBus()
snapshot = snapper.GetSnapshot("root", 1)
-print snapshot[0], snapshot[1], snapshot[2], snapshot[3], snapshot[4], snapshot[5],
-for k, v in snapshot[6].items():
+print snapshot[0], snapshot[1], snapshot[2], asctime(gmtime(snapshot[3])),
+print getpwuid(snapshot[4])[0], snapshot[5], snapshot[6],
+for k, v in snapshot[7].items():
print "%s=%s" % (k, v),
print
+
#!/usr/bin/python
+from time import gmtime, asctime
+from pwd import getpwuid
import dbus
bus = dbus.SystemBus()
snapshots = snapper.ListSnapshots("root")
for snapshot in snapshots:
- print snapshot[0], snapshot[1], snapshot[2], snapshot[3], snapshot[4], snapshot[5],
- for k, v in snapshot[6].items():
+ print snapshot[0], snapshot[1], snapshot[2],
+
+ if snapshot[3] != 0xFFFFFFFFFFFFFFFF:
+ print asctime(gmtime(snapshot[3])),
+ else:
+ print "now",
+
+ print getpwuid(snapshot[4])[0], snapshot[5], snapshot[6],
+ for k, v in snapshot[7].items():
print "%s=%s" % (k, v),
print
SnapshotType type;
unsigned int pre_num;
QDateTime date;
+ uid_t uid;
QString description;
QString cleanup;
QMap<QString, QString> userdata;
{
argument.beginStructure();
argument << mystruct.num << static_cast<unsigned short>(mystruct.type) << mystruct.pre_num
- << mystruct.date.toTime_t() << mystruct.description << mystruct.cleanup
- << mystruct.userdata;
+ << mystruct.date.toTime_t() << mystruct.uid << mystruct.description
+ << mystruct.cleanup << mystruct.userdata;
argument.endStructure();
return argument;
}
unsigned long long tmp2;
argument.beginStructure();
- argument >> mystruct.num >> tmp1 >> mystruct.pre_num >> tmp2 >> mystruct.description
- >> mystruct.cleanup >> mystruct.userdata;
+ argument >> mystruct.num >> tmp1 >> mystruct.pre_num >> tmp2 >> mystruct.uid
+ >> mystruct.description >> mystruct.cleanup >> mystruct.userdata;
argument.endStructure();
mystruct.type = static_cast<SnapshotType>(tmp1);
printf(" %s", "now");
else
printf(" %s", qPrintable(snapshot.date.toString()));
+ printf(" %d", snapshot.uid);
printf(" %s", qPrintable(snapshot.description));
QMapIterator<QString, QString> it2(snapshot.userdata);
while (it2.hasNext())
" <method name='GetSnapshot'>\n"
" <arg name='config-name' type='s' direction='in'/>\n"
" <arg name='number' type='u' direction='in'/>\n"
- " <arg name='type' type='(uqutssa{ss})' direction='out'/>\n"
+ " <arg name='type' type='(uqutussa{ss})' direction='out'/>\n"
" </method>\n"
" <method name='SetSnapshot'>\n"
Snapper* snapper = it->getSnapper();
Snapshots::iterator snap1 = snapper->createSingleSnapshot(description);
+ snap1->setUid(conn.get_unix_userid(msg));
snap1->setCleanup(cleanup);
snap1->setUserdata(userdata);
snap1->flushInfo();
Snapper* snapper = it->getSnapper();
Snapshots::iterator snap1 = snapper->createPreSnapshot(description);
+ snap1->setUid(conn.get_unix_userid(msg));
snap1->setCleanup(cleanup);
snap1->setUserdata(userdata);
snap1->flushInfo();
Snapshots::iterator snap1 = snapshots.find(pre_num);
Snapshots::iterator snap2 = snapper->createPostSnapshot(description, snap1);
+ snap1->setUid(conn.get_unix_userid(msg));
snap2->setCleanup(cleanup);
snap2->setUserdata(userdata);
snap2->flushInfo();
namespace DBus
{
const char* TypeInfo<ConfigInfo>::signature = "(ssa{ss})";
- const char* TypeInfo<Snapshot>::signature = "(uqutssa{ss})";
+ const char* TypeInfo<Snapshot>::signature = "(uqutussa{ss})";
const char* TypeInfo<File>::signature = "(su)";
{
hoho.open_struct();
hoho << data.getNum() << data.getType() << data.getPreNum() << data.getDate()
- << data.getDescription() << data.getCleanup() << data.getUserdata();
+ << data.getUid() << data.getDescription() << data.getCleanup()
+ << data.getUserdata();
hoho.close_struct();
return hoho;
}
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <pwd.h>
#include <dirent.h>
#include <mntent.h>
#include <string>
}
+ string
+ username(uid_t uid)
+ {
+ struct passwd pwd;
+ struct passwd* result;
+
+ long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ char buf[bufsize];
+
+ if (getpwuid_r(uid, &pwd, buf, bufsize, &result) != 0 || result != &pwd)
+ return "unknown";
+
+ return pwd.pw_name;
+ }
+
+
StopWatch::StopWatch()
{
gettimeofday(&start_tv, NULL);
string datetime(time_t time, bool utc, bool classic);
time_t scan_datetime(const string& str, bool utc);
+ string username(uid_t uid);
+
class StopWatch
{
s << " date:\"" << datetime(snapshot.date, true, true) << "\"";
+ s << "uid:" << snapshot.uid;
+
if (!snapshot.description.empty())
s << " description:\"" << snapshot.description << "\"";
}
+ void
+ Snapshot::setUid(uid_t val)
+ {
+ if (isCurrent())
+ throw IllegalSnapshotException();
+
+ uid = val;
+ info_modified = true;
+ }
+
+
void
Snapshot::setDescription(const string& val)
{
continue;
}
+ getChildValue(node, "uid", snapshot.uid);
+
getChildValue(node, "pre_num", snapshot.pre_num);
getChildValue(node, "description", snapshot.description);
setChildValue(node, "date", datetime(date, true, true));
+ setChildValue(node, "uid", uid);
+
if (type == POST)
setChildValue(node, "pre_num", pre_num);
friend class Snapshots;
Snapshot(const Snapper* snapper, SnapshotType type, unsigned int num, time_t date)
- : snapper(snapper), type(type), num(num), date(date), pre_num(0),
+ : snapper(snapper), type(type), num(num), date(date), uid(0), pre_num(0),
info_modified(false) {}
SnapshotType getType() const { return type; }
time_t getDate() const { return date; }
+ void setUid(uid_t uid);
+ uid_t getUid() const { return uid; }
+
unsigned int getPreNum() const { return pre_num; }
void setDescription(const string& description);
time_t date;
+ uid_t uid;
+
unsigned int pre_num; // valid only for type=POST
string description; // likely empty for type=POST