* * 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); } // ======================================== }