zefie icon

Simple crappy apache greyhole trash manager

zefie | PRO | 08/17/13 08:39:18 AM UTC | 0 ⭐ | 742 👁️ | Never ⏰ | []
PHP |

11.58 KB

|

None

|

0 👍

/

0 👎

<?php
header('Content-Type: text/html; charset=utf-8');
set_time_limit(0);
/* Notes:
   This code not designed for public consumption. It may work, but the code is quick and dirty.
   The coding style used in this code is not reflective of my professional work, but rather my
   "lets get it done now" style of work. It is only used by me in my LAN environment. This is not
   secure, so do not use it in a production environment. Protect it with .htaccess/.htpasswd and
   use common sense. The apache user (or suPHP user) will need write access to the Greyhole shares,
   and read access to /etc/greyhole.conf
 
   "Copies", when the result is a directory, is more like "Spanned across X drives". 
   "Copies", when the result is a file, is an accurate representation of how many drives
   that specific file is on.
 
   This was merely created to suit my needs and make it easier to purge/restore deleted items
   from a greyhole share's trash. It is not a complete management system, nor does it have all the
   features that it could. Basically, it does what I need. I share the code in case someone else
   desires the same functionality, or would like to expand it (either for personal or commercial 
   use. My only request is if you expand this code and sell it, that I get a free license ;)
 
   An example gallery can be found here: http://imgur.com/a/rTg3x
 
   Created by Zefie of Zefie Networks. BSD License, or whatever. Do what you want with it.
   
   Updated 2014-02-11, because I started using Greyhole again and noticed some missing features.
   Added: Last Modified, Size, and UTF-8 support.
*/
 
$drives = getDrives();
 
if (@$_GET['path']) $ext = $_GET['path'];
else $ext = "";
 
if (@$_GET['view']) $view = $_GET['view'];
else $view = "";
 
if (@$_GET['drive']) $drive = $_GET['drive'];
else $drive = "";
 
if (@$_GET['action']) $action = $_GET['action'];
else $action = "";
 
if (@$_GET['confirm']) $confirm = $_GET['confirm'];
else $confirm = "";
 
if (($drive == "" || $view == "") && $action == "") {
    $ptitle = "Greyhole Trash Manager";
    if ($ext != "") {
        $ptitle .= " - ".$ext;
    }
 
    echo "<html>\n";
    echo "<head>\n";
    echo "<title>".$ptitle."</title>\n";
    echo "<style type=\"text/css\">\n";
    echo "td, th {\n";
    echo "\tpadding: 7px 5px 7px 5px;\n";
    echo "\tborder: 1px dotted #000;\n";
    echo "}\n";
    echo "th {\n";
    echo "\ttext-align: left;\n";
    echo "\tfont-weight: bold;\n";
    echo "\tfont-style: italic;\n";
    echo "}\n";
    echo "form {\n";
    echo "\tdisplay: inline;\n";
    echo "}\n";
    echo ".ral {\n";
    echo "\ttext-align: right\n";
    echo "}\n";
    echo "</style>\n";
    echo "</head>\n";
    echo "<body>\n";
    echo "<h2>".$ptitle."</h2>\n";
    echo "<table>\n";
    echo "<tr>\n";
    echo "<th>Path</th>\n";
    echo "<th>Size</th>\n";
    echo "<th>Modified</th>\n";
    echo "<th>Copies</th>\n";
    echo "<th>Actions</th>\n";
    echo "</tr>\n";
 
    if ($ext != "") {
        $meh = split("/",$ext);
        $c = (count($meh) - 1);
        $meh2 = "";
        for ($i = 0; $i < $c; $i++) {
            $meh2 .= $meh[$i]."/";
        }
        $meh2 = rtrim($meh2,"/");
        echo "<tr>\n";
        echo "<td><a href=\"?path=".rawurlencode($meh2)."\">Parent Directory</a></td>\n";
        echo "<td> - </td>\n";
        echo "<td> - </td>\n";
        echo "<td> - </td>\n";
        echo "<td> - </td>\n";
        echo "</tr>\n";
    }
 
    foreach ($drives as $d) {
        $path = $d."/.gh_trash/".$ext;
        if ($h = @opendir($path)) {
            while (false !== ($e = readdir($h))) {
            if ($e != "." && $e != "..") {
                $list[] = array($e,$d);
            }
            }
        closedir($h);
        }
    }
 
    if (@count($list) > 0) {
        foreach ($list as $l) {
            if (@in_array($l[0],@$r)) {
                $q[$l[0]] = (@$q[$l[0]] + 1);
            } else {
                $r[] = $l[0];
                // First drive is fine
                if (!isset($z[$l[0]])) {
                    $z[$l[0]] = $l[1];
                    }
            }
        }
    }
 
    if (@count($r) > 0) {
        foreach ($r as $k) {
            echo "<tr>\n";
            if (is_dir($z[$k]."/.gh_trash/".$ext."/".$k)) {
                echo "<td><a href=\"?path=".rawurlencode($ext."/".$k)."\">".$k."</a></td>\n";
                echo "<td>-</td>\n";
                echo "<td>-</td>\n";
                echo "<td>".(@$q[$k]+1)."</td>\n";
            } else {
                $dr = (array_search($z[$k],$drives)+1);
                echo "<td><a href=\"?view=".rawurlencode($ext."/".$k)."&drive=".$dr."\">".$k."</a></td>\n";
                $fsize = filesize($z[$k]."/.gh_trash/".$ext."/".$k);
                echo "<td>".$fsize." bytes (".friendlyBytes($fsize).")</td>\n";
                $ftime = filemtime($z[$k]."/.gh_trash/".$ext."/".$k);
                echo "<td>".strftime("%m/%e/%Y %r",$ftime)."</td>\n";
                echo "<td>".(@$q[$k]+1)."</td>\n";
            }
            echo "<td>\n";
            echo "<form method=\"GET\"><input type=\"hidden\" name=\"path\" value=\"".$ext."/".$k."\" /><input type=\"hidden\" name=\"action\" value=\"remove\" /><input type=\"submit\" value=\"Delete Permanently\" /></form>\n";
            echo "<form method=\"GET\"><input type=\"hidden\" name=\"path\" value=\"".$ext."/".$k."\" /><input type=\"hidden\" name=\"action\" value=\"restore\" /><input type=\"submit\" value=\"Restore\" /></form>\n";
                echo "</td>\n";
                echo "</tr>";
            }
        }
    echo "<tr>\n";
    echo "<td colspan=\"3\" class=\"ral\">\n";
    $space = getSpace(true);
    echo "<strong>Disk Space Status:</strong><br />\n";
    echo "<table class=\"ral\" width=\"100%\">\n";
    echo "<tr><td>Total:</td><td>".$space['total']."</td></tr>\n";
    echo "<tr><td>Used:</td><td>".$space['used']."</td></tr>\n";
    echo "<tr><td>Available:</td><td>".$space['avail']."</td></tr>\n";
    echo "<tr><td>Trash:</td><td>".$space['trash']."</td></tr>\n";
    echo "<tr><td>Possible:</td><td>".$space['possible']."</td></tr>\n";
    echo "</body>\n";
    echo "</table>\n";
    echo "</table>\n";
    echo "</html>\n";
} else {
    if ($view != "" && $drive != "") {
        $dpath = $drives[($drive-1)]."/.gh_trash";
        $fpath = $dpath.$view;
        $meh = split("/",$fpath);
        $file = $meh[(count($meh)-1)];
        $mime = mime_content_type($fpath);
        http_send_content_disposition($file,true);
        http_send_content_type($mime);
        http_send_file($fpath);
        exit();
    }
    if ($action == "remove" && $ext != "") {
        if ($confirm != "Yes") {
            echo "<h2>Removing ".$ext."</h2>\n";
            if (is_dir($ext)) {
                echo "Are you sure you want to recursively destroy all copies of this directory, and the files within it?<br />\n";
            } else {
                echo "Are you sure you want to destroy all copies of this file in the trash?<br />\n";
            }
            echo "This action is not reversable!<br />\n";
            echo "<form method=\"GET\">\n";
            echo "<input type=\"hidden\" name=\"path\" value=\"".$ext."\" />\n";
            echo "<input type=\"hidden\" name=\"action\" value=\"remove\" />\n";
            echo "<input type=\"submit\" name=\"confirm\" value=\"Yes\" />\n";
            echo "<input type=\"button\" onclick=\"history.go(-1)\" value=\"No\" />\n";
            echo "</form>\n";
        } else {
            foreach ($drives as $driv) {
                                $file = $driv."/.gh_trash".$ext;
                                if (is_dir($file)) {
                                        rrmdir($file);
                                        $removed[] = $file;
                                } else {
                                        if (file_exists($file)) {
                                                unlink($file);
                                                $removed[] = $file;
                                        }
                                }
            }
            if (count(@$removed) > 0) {
                echo "<h2>Removed ".$ext."</h2>\n";
                echo "The file has been removed from all Greyhole drives.<br />\n";
                echo "<br />\n";
                echo "Removed from:<br />\n";
                foreach ($removed as $r) {
                    echo $r."<br />\n";
                }
            } else {
                echo "No such file. Perhaps it was already removed, or you refreshed the page.<br />";
            }
            echo "<br />\n";
            $meh = split("/",$ext);
            $c = (count($meh) - 1);
            $meh2 = "";
            for ($i = 0; $i < $c; $i++) {
                $meh2 .= $meh[$i]."/";
            }
            $meh2 = rtrim($meh2,"/");
            echo "<a href=\"?path=".$meh2."\">Back to directory</a>";
        }
    }
    if ($action == "restore" && $ext != "") {
        $dest = "/media/share".$ext;
        foreach ($drives as $driv) {
            $file = $driv."/.gh_trash".$ext;
            if (file_exists($file)) {
                $sources[] = $file;
            }
        }
 
        $meh = split("/",$ext);
        $c = (count($meh) - 1);
        $meh2 = "";
        for ($i = 0; $i < $c; $i++) {
            $meh2 .= $meh[$i]."/";
        }
        $meh2 = rtrim($meh2,"/");
 
        // First one is fine
        $source = @$sources[0];
 
        // Unless its an entire folder...
        if (is_dir($source)) {
            foreach ($sources as $s) {
                xcopy($s,$dest);
            }
        } elseif (file_exists($source)) {
            if (!is_dir(dirname($dest))) {
                mkdir(dirname($dest),0770,true);
            }
            copy($source,$dest);
        } else {
            echo "No such file. If you restored the file, it has been purged from the trash. Did you refresh the page?<br />";
        }
 
 
        // Delete all copies from trash after restoring
        if (file_exists($dest)) {
            foreach ($sources as $s) {
                if (is_dir($s)) {
                    rrmdir($s);
                }
                else {
                    if (file_exists($s)) {
                        unlink($s);
                    }
                }
            }
        } else {
            echo "Internal error: failed to restore file. Trash untouched.\n";
            echo "<br />\n";
            echo "<a href=\"?path=".$meh2."\">Back to directory</a>";
            exit();
        }
        echo "<h2>Restored ".$ext."</h2>\n";
        echo "The file has been restored to the share. It will no longer appear in the trash.<br />\n";
        echo "<br />\n";
        echo "<a href=\"?path=".$meh2."\">Back to directory</a>";
    }
}
 
function rrmdir($dir) {
    if (is_dir($dir)) {
        $objects = scandir($dir);
        foreach ($objects as $object) {
            if ($object != "." && $object != "..") {
                if (filetype($dir."/".$object) == "dir") {
                    rrmdir($dir."/".$object);
                } else {
                    unlink($dir."/".$object);
                }
            }
        }
        reset($objects);
        rmdir($dir);
    }
}
 
function xcopy($src,$dest) {
    if (!is_dir($dest)) {
        mkdir($dest);
    }
    foreach (scandir($src) as $file) {
        if (!is_readable($src.'/'.$file)) continue;
        if (is_dir($src.'/'.$file)) {
            if (($file!='.') && ($file!='..')) {
                if(!is_dir($dest.'/'.$file)) {
                    mkdir($dest . '/' . $file);
                }
                xcopy($src.'/'.$file, $dest.'/'.$file);
            }
        } else {
            if (!file_exists($dest.'/'.$file)) {
                copy($src.'/'.$file, $dest.'/'.$file);
            }
        }
     }
}
 
function getSpace($friendlyBytes = false) {
    $dat = `/usr/bin/greyhole-dfree`;
    $dat = split(" ",$dat);
    $space['total'] = $dat[0];
    $space['avail'] = $dat[1];
    $space['used'] = ($space['total'] - $space['avail']);
    $space['trash'] = 0;
    $drives = getDrives();
    foreach ($drives as $d) {
        $dudat = `du -sk $d/.gh_trash/`;
        $space['trash'] = ($space['trash'] + $dudat);
    }
    $space['possible'] = ($space['avail'] + $space['trash']);
    if ($friendlyBytes) {
        foreach ($space as $k => $v) {
            $space[$k] = friendlyBytes($v * 1024);
        }
    }
    return $space;
}
 
function getDrives() {
    $gh = '/etc/greyhole.conf';
    $dat = "";
    $fp = fopen($gh,'r');
    if (!$fp) die("Access to /etc/greyhole.conf denied");
    while (!feof($fp)) {
        $dat .= fread($fp,128);
    }
    fclose($fp);
    $dat = split("\n",$dat);
    foreach ($dat as $l) {
        if (substr($l,0,10) == "storage_po") {
            $m = split(" = ",$l);
            $n = split(",",$m[1]);
            $drives[] = $n[0];
        }
    }
    return $drives;
}
 
function friendlyBytes($size) {
 
    // Uncomment below to enable rounding to Terabytes.
    // Leave commented to function as shown in example screenshots.
 
//  if ($size > 1099511627776) {
//      return round(($size / 1099511627776),2)."TB";
//  }
 
    if ($size > 1073741824) {
        return round(($size / 1073741824),2)."GB";
    }
    if ($size > 1048576) {
        return round(($size / 1048576),2)."MB";
    }
    if ($size > 1024) {
        return round(($size / 1024),2)."KB";
    }
    return $size."B";
}

Comments