adecwatt/adecWattBD.class.php
2023-10-12 19:41:28 +02:00

370 lines
12 KiB
PHP

<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin AdecWatt: file transfert
*/
class adecWattDB {
// ========================================
var $dbDirName;
var $excludeFileName;
var $userDbName;
var $aclDbName;
var $nameDb;
var $idDb;
var $aclDb;
var $login;
var $id;
var $groups;
var $fpLog;
function __construct ($plugin) {
global $conf;
// date_default_timezone_set ("UTC");
$this->dbDirName =
((!$conf['savedir'] || strpos ($conf['savedir'], '.') === 0) ? DOKU_INC : "").
$conf['savedir'].'/'.trim ($plugin->getConf ('dataDir').'/');
$this->excludeFileName = explode ("|", ".|..|timestamp");
$this->userDbName = $this->dbDirName.'users.txt';
$this->aclDbName = $this->dbDirName.'acl.txt';
$this->fpLog = fopen ('/home/parlenet/adec.log', 'a+');
}
function tmpLog ($msg) {
fwrite ($this->fpLog, date ("YmdHis ").$msg.NL);
fflush ($this->fpLog);
}
// ========================================
function getInfos () {
global $INPUT;
$this->login = $INPUT->server->str ('REMOTE_USER');
if (!$this->login)
return;
$this->readUser ();
$this->id = $this->nameDb [$this->login];
if ($this->id === null)
return;
$this->groups = explode (',', $this->idDb[$this->id]);
}
function getRoles ($name) {
$this->getInfos ();
if (!$this->login) {
echo "Not connected!".NL;
return;
}
global $INFO;
if (isset ($INFO['userinfo'] ['grps']) && in_array ('admin', $INFO ['userinfo'] ['grps'])) {
// si admin
}
if (!$this->id) {
"1|Visitor";
}
echo $this->id."|".$this->idDb[$this->id].NL;
}
function readUser () {
$this->nameDb = array ();
$this->idDb = array ();
$user = file ($this->userDbName);
foreach ($user as $line) {
$line = trim ($line);
if (empty ($line) || ($line[0] == '#'))
continue; // skip blank lines & comments
list ($id, $name, $roles) = explode ('|', $line, 3);
// XXX test nom double
$this->nameDb [$name] = $id;
$this->idDb [$id] = $roles;
}
}
// ========================================
function readAcl () {
$this->aclDb = array ();
$acl = file ($this->aclDbName);
foreach ($acl as $line) {
$line = trim ($line);
if (empty ($line) || ($line[0] == '#'))
continue; // skip blank lines & comments
list ($starts, $rest) = preg_split ('/[ \t]+/', $line, 2);
$user = array ();
$group = array ();
foreach (explode (',', $rest) as $word) {
$word = trim ($word);
if ($word[0] == '@')
$group[] = substr ($word, 1);
else
$user[] = $word;
}
$this->aclDb [$starts] = array ("users" => $user, "groups" => $group);
}
}
function checkAcl ($path) {
foreach (array_keys ($this->aclDb) as $starts)
if (substr ($path, 0, strlen ($starts)) === $starts &&
(in_array ($this->login, $this->aclDb[$starts]["users"]) || array_intersect ($this->groups, $this->aclDb[$starts]["groups"])))
return true;
return false;
}
// ========================================
function cleanTmp () {
$tmpDir = sys_get_temp_dir ();
if (!$dh = opendir ($tmpDir))
return;
$today = time ();
$aMoment = 60;
while (($child = readdir ($dh)) !== false) {
$fileName = $tmpDir."/".$child;
if (!is_file ($fileName) || filesize ($fileName))
continue;
if ($today - filemtime ($fileName) < $aMoment)
continue;
@unlink ($fileName);
}
}
function getTreeInfo ($fileName, $name) {
if (is_file ($fileName))
return date ("YmdHis ", filemtime ($fileName)).filesize ($fileName)." ".$name.NL;
if (!is_dir ($fileName))
return "";
$result = "";
if ($dh = opendir ($fileName)) {
while (($child = readdir ($dh)) !== false) {
if (in_array (strtolower ($child), $this->excludeFileName))
continue;
if (is_file ($child) && eregi ('.*\.back', $child, $b))
continue;
$result .= $this->getTreeInfo ($fileName."/".$child, $name."/".$child);
}
closedir($dh);
}
return $result;
}
function getTmpFile () {
return tempnam (sys_get_temp_dir (), "download");
}
function getDataFileName ($version, $fileName) {
return $this->dbDirName."/".$this->checkPath ("/".$version."/".$fileName);
}
function checkPath ($path) {
return trim (str_replace (array ("//", "/./", "/../"), "/", "/".$path), "/");
}
function getPostZipFile ($cmd) {
if (!$_FILES) {
echo "No zip file sended!".NL;
return null;
}
$file = $_FILES [$cmd];
if (!$file)
$file = $_FILES [array_keys ($_FILES)[0]];
if (!$file['tmp_name']) {
echo "Empty zip file!".NL;
return null;
}
$zip = new ZipArchive;
if ($zip->open ($file['tmp_name']) !== TRUE) {
echo "Can't open zip ".$file['tmp_name']."!".NL;
return null;
}
return $zip;
}
function getPostZipFileListContent ($cmd, $name) {
$zip = $this->getPostZipFile ($cmd);
if (!$zip)
return "";
$listFilesName = $zip->getFromName ($name);
$listFilesName = str_replace ("\r", "", $listFilesName);
$zip->close ();
return $listFilesName;
}
// ========================================
// directory
// from name return zip [file:info]
function zipList ($version, $name) {
$this->cleanTmp ();
$fileName = $this->dbDirName."/".$this->checkPath ("/".$version."/".$name);
$this->sendZipText ($name, $this->getTreeInfo ($fileName, $name));
}
// get files
// from zip file contains list
function zipGets ($version, $name) {
$listFilesName = $this->getPostZipFileListContent ('zipGets', $name);
if (!$listFilesName) {
echo "No request!".NL;
return;
}
$tmpFileName = $this->getTmpFile ();
$zip = $this->sendZipOpen ($tmpFileName);
if (!$zip)
return;
foreach (explode ("\n", $listFilesName) as $fileName) {
if (!$fileName)
continue;
$zip->addFile ($this->getDataFileName ($version, $fileName), $fileName);
}
$this->sendZipClose ($zip, $tmpFileName);
}
// put files
// from zip contains all files
function zipPuts ($version, $name) {
$this->cleanTmp ();
$this->getInfos ();
if (!$this->login) {
echo "Not connected!".NL;
return;
}
$this->readAcl ();
$tmpFileName = $this->getTmpFile ();
$zip = new ZipArchive;
if ($zip->open ($tmpFileName, ZipArchive::CREATE) !== TRUE) {
echo "Can't open $tmpFileName".NL;
return;
}
$zip = $this->getPostZipFile ($cmd);
if (!$zip) {
echo "No zip!".NL;
return;
}
$validFiles = array ();
for ($i = 0; $i < $zip->numFiles; $i++) {
$entry = $this->checkPath ("/".$zip->getNameIndex ($i));
if (!$this->checkAcl ($entry))
continue;
$validFiles [] = $entry;
}
if (!$validFiles) {
echo "No file sended!".NL;
return;
}
$pathExtract = $this->dbDirName."/".$version."/";
foreach ($validFiles as $oldFile) {
$filename = realpath ($pathExtract.$oldFile);
if (is_file ($filename))
rename ($filename, dirname ($filename)."/".basename ($filename).".back");
}
$zip->extractTo ($pathExtract, $validFiles);
// change time
for ($i = 0; $i < $zip->numFiles; $i++) {
$entry = $this->checkPath ("/".$zip->getNameIndex ($i));
if (! in_array ($entry, $validFiles))
continue;
$filename = realpath ($pathExtract.$entry);
$this->tmpLog ("coucou touch :".$filename." ".$zip->statIndex ($i)["mtime"]);
touch ($filename, $zip->statIndex ($i)["mtime"]);
}
$this->sendZipText ($name, implode (NL, $validFiles));
$zip->close ();
}
// remove all files
// from zip contains filesname
function zipRemove ($version, $name) {
$this->cleanTmp ();
$listFilesName = $this->getPostZipFileListContent ('zipRemove', $name);
if (!$listFilesName) {
echo "No request!".NL;
return;
}
$this->getInfos ();
if (!$this->login) {
echo "Not connected!".NL;
return;
}
$this->readAcl ();
$succes = array ();
foreach (explode ("\n", $listFilesName) as $fileName) {
if (!$fileName)
continue;
$fileName = $this->checkPath ("/".$fileName);
if (!$this->checkAcl ($fileName))
continue;
unlink ($this->getDataFileName ($version, $fileName));
$succes[] = $fileName;
}
$this->sendZipText ($name, implode (NL, $succes));
}
// get one file
// from querry-string (not used)
function getZip ($version, $name) {
$name = $this->checkPath ($name);
$tmpFileName = $this->getTmpFile ();
$zip = $this->sendZipOpen ($tmpFileName);
if (!$zip)
return;
$zip->addFile ($this->getDataFileName ($version, $name), $name);
$this->sendZipClose ($zip, $tmpFileName);
}
// ========================================
function sendZipOpen ($tmpFileName) {
$zip = new ZipArchive;
if ($zip->open ($tmpFileName, ZipArchive::CREATE) !== TRUE) {
echo "Can't open $tmpFileName".NL;
return null;
}
return $zip;
}
function sendZipClose ($zip, $tmpFileName) {
$zip->close ();
$this->sendAbsFile ($tmpFileName, "application/zip");
unlink ($tmpFileName);
}
function sendZipText ($name, $content) {
$tmpFileName = $this->getTmpFile ();
$zip = $this->sendZipOpen ($tmpFileName);
if (!$zip)
return;
$zip->addFromString ($name, $content);
$this->sendZipClose ($zip, $tmpFileName);
}
function sendAbsFile ($fileName, $mimeType) {
if (!is_file ($fileName)) {
echo "File not found <$fileName> <$mimeType>!".NL;
return;
}
header ("Content-Type: $mimeType");
echo file_get_contents ($fileName);
}
// ========================================
// old API
// ========================================
function sendDataFile ($version, $fileName, $mimeType) {
$this->sendAbsFile ($this->getDataFileName ($version, $fileName), $mimeType);
}
function getDir ($version, $name) {
$this->sendDataFile ($version, $name."/timestamp", "text/plain");
}
function getDataFile ($version, $name) {
$mimeType = "";
if (eregi ('.*\.lpt$', $name, $b))
$mimeType = "application/lpt";
elseif (eregi ('.*\.lpi$', $name, $b))
$mimeType = "text/plain";
elseif (eregi ('.*\.png$', $name, $b))
$mimeType = "image/png";
elseif (eregi ('.*\.jpg$', $name, $b))
$mimeType = "image/jpg";
elseif (eregi ('.*\.jar$', $name, $b))
$mimeType = "application/java";
elseif (eregi ('.*\.xml', $name, $b))
$mimeType = "application/xml";
else {
echo "Bad type $name!".NL;
return;
}
$this->sendDataFile ($version, $name, $mimeType);
}
// ========================================
}