aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core/libLumina')
-rw-r--r--src-qt5/core/libLumina/LFileInfo.cpp118
-rw-r--r--src-qt5/core/libLumina/LFileInfo.h21
-rw-r--r--src-qt5/core/libLumina/LIconCache.cpp3
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.cpp2
4 files changed, 136 insertions, 8 deletions
diff --git a/src-qt5/core/libLumina/LFileInfo.cpp b/src-qt5/core/libLumina/LFileInfo.cpp
index 3b659c75..d4e0cfde 100644
--- a/src-qt5/core/libLumina/LFileInfo.cpp
+++ b/src-qt5/core/libLumina/LFileInfo.cpp
@@ -6,9 +6,12 @@
//===========================================
#include "LFileInfo.h"
#include <LUtils.h>
+#include <QRegExp>
+#include <unistd.h>
LFileInfo::LFileInfo() : QFileInfo(){
desk = 0;
+ c_uid = -1;
}
LFileInfo::LFileInfo(QString filepath) : QFileInfo(){ //overloaded contructor
@@ -30,6 +33,7 @@ LFileInfo::~LFileInfo(){
void LFileInfo::loadExtraInfo(){
if(desk!=0){ desk->deleteLater(); }
desk = 0;
+ c_uid = geteuid();
//Now load the extra information
if(this->absoluteFilePath().startsWith("/net/") || this->isDir() ){
mime = "inode/directory";
@@ -49,7 +53,6 @@ void LFileInfo::loadExtraInfo(){
iconList << "folder";
}else if( this->suffix()=="desktop"){
mime = "application/x-desktop";
- iconList << "application-x-desktop"; //default value
desk = new XDGDesktop(this->absoluteFilePath(), 0);
if(desk->type!=XDGDesktop::BAD){
//use the specific desktop file info (if possible)
@@ -81,8 +84,32 @@ void LFileInfo::getZfsDataset(){
//Use the "atime" property for this check - been around since the earliest versions of ZFS and should take no time to probe
QString out = LUtils::runCommand(ok, "zfs", QStringList() << "get" << "-H" << "atime" << this->canonicalFilePath() );
if(!ok){ zfs_ds = "."; } //just something that is not empty - but is clearly not a valid dataset
- else{ zfs_ds = out.section("\n",0,0).section("\t",0,0).simplified(); }
+ else{
+ zfs_ds = out.section("\n",0,0).section("\t",0,0).simplified();
+ zfs_dspath = this->canonicalFilePath().section(zfs_ds.section("/",1,-1), 1,-1); //relative path
+ if(!zfs_dspath.isEmpty()){ zfs_dspath.prepend(zfs_ds); }
+ else{ zfs_dspath = zfs_ds; } //on the current dataset "root"
+ //qDebug() << "Got ZFS dataset:" << zfs_ds << zfs_dspath;
+ }
//qDebug() << "Found Dataset:" << zfs_ds << out << ok;
+ if(ok){
+ //Also get the list of permissions this user has for modifying the ZFS dataset
+ QStringList perms = LUtils::runCommand(ok, "zfs", QStringList() << "allow" << zfs_ds ).split("\n");
+ //qDebug() << "Permissions:" << perms;
+ if(!perms.isEmpty() && ok){
+ //Now need to filter/combine the permissions for all the groups this user is a part of
+ QStringList gplist = LUtils::runCommand(ok, "id", QStringList() << "-np").split("\n").filter("groups");
+ if(!gplist.isEmpty()){ gplist = gplist.first().replace("\t", " ").split(" ",QString::SkipEmptyParts); gplist.removeAll("groups"); }
+ for(int i=0; i<gplist.length(); i++){
+ QStringList tmp = perms.filter(QRegExp("[user|group] "+gplist[i]));
+ if(tmp.isEmpty()){ continue; }
+ zfs_perms << tmp.first().section(" ",2,2,QString::SectionSkipEmpty).split(",",QString::SkipEmptyParts);
+ }
+ zfs_perms.removeDuplicates();
+ //qDebug() << "Got ZFS Permissions:" << zfs_ds << zfs_perms;
+ }
+ }
+
}
}
@@ -138,7 +165,11 @@ bool LFileInfo::isAVFile(){
return (mime.startsWith("audio/") || mime.startsWith("video/") );
}
-bool LFileInfo::isZfsDataset(){
+bool LFileInfo::isZfsDataset(QString path){
+ if(!path.isEmpty() && zfsAvailable() ){
+ //manual check of a dir
+ return (0 == LUtils::runCmd("zfs", QStringList() << "get" << "-H" << "atime" << path) );
+ }
if(!goodZfsDataset()){ return false; }
return ( ("/"+zfs_ds.section("/",1,-1)) == this->canonicalFilePath());
}
@@ -185,3 +216,84 @@ bool LFileInfo::zfsSetProperty(QString property, QString value){
if(!ok){ qDebug() << "Error Setting ZFS Property:" << property+"="+value << info; }
return ok;
}
+
+//ZFS Permissions/Modifications
+bool LFileInfo::canZFScreate(){
+ if(!goodZfsDataset()){ return false; }
+ return (zfs_perms.contains("create") || (c_uid==0) );
+}
+
+bool LFileInfo::zfsCreateDataset(QString subdir){
+ if(!canZFScreate()){ return false; }
+ if(subdir.startsWith("/")){ qDebug() << "Not a relative path!!"; return false; }
+ if( QFile::exists(this->canonicalFilePath()+"/"+subdir) ){
+ return false;
+ }
+ bool ok = false;
+ QString info = LUtils::runCommand(ok, "zfs", QStringList() << "create" << zfs_dspath+"/"+subdir );
+ if(!ok){ qDebug() << "Error Creating ZFS Dataset:" << subdir << info; }
+ return ok;
+}
+
+bool LFileInfo::canZFSdestroy(){
+ if(!goodZfsDataset()){ return false; }
+ return (zfs_perms.contains("destroy") || (c_uid==0) );
+}
+
+bool LFileInfo::zfsDestroyDataset(QString subdir){
+ if(!canZFSdestroy()){ return false; }
+ if(!subdir.isEmpty() && !subdir.startsWith("/")){
+ if( isZfsDataset(this->canonicalFilePath()+"/"+subdir) ){ subdir = zfs_dspath+"/"+subdir; }
+ }
+ else if(subdir.isEmpty() && (zfs_ds == zfs_dspath) ){ subdir = zfs_ds; }
+ else{ qDebug() << "Invalid subdir:" << subdir; return false; }
+ bool ok = false;
+ QString info = LUtils::runCommand(ok, "zfs", QStringList() << "destroy" << subdir);
+ if(!ok){ qDebug() << "Error Destroying ZFS Dataset:" << subdir << info; }
+ return ok;
+}
+
+bool LFileInfo::zfsDestroySnapshot(QString snapshot){
+ if(!canZFSdestroy()){ return false; }
+ bool ok = false;
+ QString info = LUtils::runCommand(ok, "zfs", QStringList() << "destroy" << zfs_ds+"@"+snapshot);
+ if(!ok){ qDebug() << "Error Destroying ZFS Snapshot:" << snapshot << info; }
+ return ok;
+}
+
+bool LFileInfo::canZFSclone(){
+ if(!goodZfsDataset()){ return false; }
+ return (zfs_perms.contains("clone") || (c_uid==0) );
+}
+
+bool LFileInfo::zfsCloneDataset(QString subdir, QString newsubdir){
+ if(!canZFSclone()){ return false; }
+
+ return false;
+}
+
+bool LFileInfo::canZFSsnapshot(){
+ if(!goodZfsDataset()){ return false; }
+ return (zfs_perms.contains("snapshot") || (c_uid==0) );
+}
+
+bool LFileInfo::zfsSnapshot(QString snapname){
+ if(!canZFSsnapshot()){ return false; }
+ bool ok = false;
+ QString info = LUtils::runCommand(ok, "zfs", QStringList() << "snapshot" << zfs_ds+"@"+snapname);
+ if(!ok){ qDebug() << "Error Creating ZFS Snapshot:" << snapname << info; }
+ return ok;
+}
+
+bool LFileInfo::canZFSrollback(){
+ if(!goodZfsDataset()){ return false; }
+ return (zfs_perms.contains("rollback") || (c_uid==0) );
+}
+
+bool LFileInfo::zfsRollback(QString snapname){
+ if(!canZFSrollback()){ return false; }
+ bool ok = false;
+ QString info = LUtils::runCommand(ok, "zfs", QStringList() << "rollback" << zfs_ds+"@"+snapname);
+ if(!ok){ qDebug() << "Error Rolling back to ZFS Snapshot:" << snapname << info; }
+ return ok;
+}
diff --git a/src-qt5/core/libLumina/LFileInfo.h b/src-qt5/core/libLumina/LFileInfo.h
index f72c8649..21aae19d 100644
--- a/src-qt5/core/libLumina/LFileInfo.h
+++ b/src-qt5/core/libLumina/LFileInfo.h
@@ -17,8 +17,9 @@
class LFileInfo : public QFileInfo{
private:
- QString mime, zfs_ds;
- QStringList iconList;
+ QString mime, zfs_ds, zfs_dspath;
+ QStringList iconList, zfs_perms;
+ int c_uid;
XDGDesktop *desk;
void loadExtraInfo();
@@ -51,12 +52,26 @@ public:
bool isVideo(); //Is a readable video file (for thumbnail support)
bool isAVFile(); //Is an audio/video file
- bool isZfsDataset();
+ //ZFS Information
+ bool isZfsDataset(QString path = "");
QString zfsPool();
QStringList zfsSnapshots(); //Format: "snapshot name::::path/to/snapshot"
QJsonObject zfsProperties();
bool zfsSetProperty(QString property, QString value);
+ //ZFS Permissions/Modifications
+ bool canZFScreate();
+ bool zfsCreateDataset(QString subdir);
+ bool canZFSdestroy();
+ bool zfsDestroyDataset(QString subdir);
+ bool zfsDestroySnapshot(QString snapshot);
+ bool canZFSclone();
+ bool zfsCloneDataset(QString subdir, QString newsubdir);
+ bool canZFSsnapshot();
+ bool zfsSnapshot(QString snapname);
+ bool canZFSrollback();
+ bool zfsRollback(QString snapname);
+
};
typedef QList<LFileInfo> LFileInfoList;
diff --git a/src-qt5/core/libLumina/LIconCache.cpp b/src-qt5/core/libLumina/LIconCache.cpp
index 84428546..c3b0cc1b 100644
--- a/src-qt5/core/libLumina/LIconCache.cpp
+++ b/src-qt5/core/libLumina/LIconCache.cpp
@@ -53,6 +53,7 @@ bool LIconCache::isLoaded(QString icon){
QString LIconCache::findFile(QString icon){
if(icon.isEmpty()){ return ""; }
+
//Get the currently-set theme
QString cTheme = QIcon::themeName();
if(cTheme.isEmpty()){
@@ -328,7 +329,7 @@ void LIconCache::ReadFile(LIconCache *obj, QString id, QString path){
}
bool LIconCache::isThemeIcon(QString id){
- return (!id.contains("/") && !id.contains(".") && !id.contains("libreoffice") );
+ return (!id.contains("/") && !id.contains(".") ); //&& !id.contains("libreoffice") );
}
QIcon LIconCache::iconFromTheme(QString id){
diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp
index 95585f1e..a17f1e7c 100644
--- a/src-qt5/core/libLumina/LuminaXDG.cpp
+++ b/src-qt5/core/libLumina/LuminaXDG.cpp
@@ -851,7 +851,7 @@ void LXDG::setEnvironmentVars(){
QIcon LXDG::findIcon(QString iconName, QString fallback){
//With the addition of the Lumina theme engine (8/3/17), switch back to using the Qt icon from theme method for apps
QIcon tmp;
- if(!iconName.contains("libreoffice")){ //libreoffice is stupid - their svg icons are un-renderable with Qt
+ if(!iconName.contains("libreoffice") || !QIcon::themeName().startsWith("material-design") ){ //libreoffice is stupid - their svg icons are un-renderable with Qt
tmp = QIcon::fromTheme(iconName);
/*if(iconName.contains("start-here")){
qDebug() << "[ICON]" << iconName << "found:" << !tmp.isNull() << tmp.name();
bgstack15