1ed7b5f09Sandi<?php 215fae107Sandi/** 315fae107Sandi * File IO functions 415fae107Sandi * 515fae107Sandi * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 615fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 715fae107Sandi */ 815fae107Sandi 9ed7b5f09Sandi if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); 10ed7b5f09Sandi require_once(DOKU_INC.'inc/common.php'); 119b307a83SAndreas Gohr require_once(DOKU_INC.'inc/HTTPClient.php'); 12f3f0262cSandi 13f3f0262cSandi/** 1453d6ccfeSandi * Removes empty directories 1553d6ccfeSandi * 1653d6ccfeSandi * @todo use safemode hack 1753d6ccfeSandi * @author Andreas Gohr <andi@splitbrain.org> 1853d6ccfeSandi */ 1953d6ccfeSandifunction io_sweepNS($id){ 2053d6ccfeSandi global $conf; 2153d6ccfeSandi 2253d6ccfeSandi //scan all namespaces 2353d6ccfeSandi while(($id = getNS($id)) !== false){ 2453d6ccfeSandi $dir = $conf['datadir'].'/'.str_replace(':','/',$id); 2553d6ccfeSandi $dir = utf8_encodeFN($dir); 2653d6ccfeSandi 2753d6ccfeSandi //try to delete dir else return 2853d6ccfeSandi if(!@rmdir($dir)) return; 2953d6ccfeSandi } 3053d6ccfeSandi} 3153d6ccfeSandi 3253d6ccfeSandi/** 3315fae107Sandi * Returns content of $file as cleaned string. 3415fae107Sandi * 3515fae107Sandi * Uses gzip if extension is .gz 3615fae107Sandi * 3715fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 38f3f0262cSandi */ 39f3f0262cSandifunction io_readFile($file){ 40f3f0262cSandi $ret = ''; 41f3f0262cSandi if(@file_exists($file)){ 42f3f0262cSandi if(substr($file,-3) == '.gz'){ 43f3f0262cSandi $ret = join('',gzfile($file)); 44f3f0262cSandi }else{ 45f3f0262cSandi $ret = join('',file($file)); 46f3f0262cSandi } 47f3f0262cSandi } 48f3f0262cSandi return cleanText($ret); 49f3f0262cSandi} 50f3f0262cSandi 51f3f0262cSandi/** 5215fae107Sandi * Saves $content to $file. 53f3f0262cSandi * 541380fc45SAndreas Gohr * If the third parameter is set to true the given content 551380fc45SAndreas Gohr * will be appended. 561380fc45SAndreas Gohr * 5715fae107Sandi * Uses gzip if extension is .gz 5815fae107Sandi * 5915fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 6015fae107Sandi * @return bool true on success 61f3f0262cSandi */ 621380fc45SAndreas Gohrfunction io_saveFile($file,$content,$append=false){ 631380fc45SAndreas Gohr $mode = ($append) ? 'ab' : 'wb'; 641380fc45SAndreas Gohr 65f3f0262cSandi io_makeFileDir($file); 6690eb8392Sandi io_lock($file); 67f3f0262cSandi if(substr($file,-3) == '.gz'){ 681380fc45SAndreas Gohr $fh = @gzopen($file,$mode.'9'); 69f3f0262cSandi if(!$fh){ 70f3f0262cSandi msg("Writing $file failed",-1); 71f3f0262cSandi return false; 72f3f0262cSandi } 73f3f0262cSandi gzwrite($fh, $content); 74f3f0262cSandi gzclose($fh); 75f3f0262cSandi }else{ 761380fc45SAndreas Gohr $fh = @fopen($file,$mode); 77f3f0262cSandi if(!$fh){ 78f3f0262cSandi msg("Writing $file failed",-1); 79f3f0262cSandi return false; 80f3f0262cSandi } 81f3f0262cSandi fwrite($fh, $content); 82f3f0262cSandi fclose($fh); 83f3f0262cSandi } 8490eb8392Sandi io_unlock($file); 85f3f0262cSandi return true; 86f3f0262cSandi} 87f3f0262cSandi 88f3f0262cSandi/** 891380fc45SAndreas Gohr * Delete exact linematch for $badline from $file. 901380fc45SAndreas Gohr * 911380fc45SAndreas Gohr * Be sure to include the trailing newline in $badline 92b158d625SSteven Danz * 93b158d625SSteven Danz * Uses gzip if extension is .gz 94b158d625SSteven Danz * 95*8b06d178Schris * 2005-10-14 : added regex option -- Christopher Smith <chris@jalakai.co.uk> 96*8b06d178Schris * 97b158d625SSteven Danz * @author Steven Danz <steven-danz@kc.rr.com> 98b158d625SSteven Danz * @return bool true on success 99b158d625SSteven Danz */ 100*8b06d178Schrisfunction io_deleteFromFile($file,$badline,$regex=false){ 1011380fc45SAndreas Gohr if (!@file_exists($file)) return true; 1021380fc45SAndreas Gohr 103b158d625SSteven Danz io_lock($file); 1041380fc45SAndreas Gohr 1051380fc45SAndreas Gohr // load into array 106b158d625SSteven Danz if(substr($file,-3) == '.gz'){ 1071380fc45SAndreas Gohr $lines = gzfile($file); 108b158d625SSteven Danz }else{ 1091380fc45SAndreas Gohr $lines = file($file); 110b158d625SSteven Danz } 111b158d625SSteven Danz 1121380fc45SAndreas Gohr // remove all matching lines 113*8b06d178Schris if ($regex) { 114*8b06d178Schris $lines = preg_grep($badline,$lines,PREG_GREP_INVERT); 115*8b06d178Schris } else { 1161380fc45SAndreas Gohr $pos = array_search($badline,$lines); //return null or false if not found 1171380fc45SAndreas Gohr while(is_int($pos)){ 1181380fc45SAndreas Gohr unset($lines[$pos]); 1191380fc45SAndreas Gohr $pos = array_search($badline,$lines); 120b158d625SSteven Danz } 121*8b06d178Schris } 122b158d625SSteven Danz 1231380fc45SAndreas Gohr if(count($lines)){ 1241380fc45SAndreas Gohr $content = join('',$lines); 125b158d625SSteven Danz if(substr($file,-3) == '.gz'){ 126b158d625SSteven Danz $fh = @gzopen($file,'wb9'); 127b158d625SSteven Danz if(!$fh){ 128b158d625SSteven Danz msg("Removing content from $file failed",-1); 129b158d625SSteven Danz return false; 130b158d625SSteven Danz } 131b158d625SSteven Danz gzwrite($fh, $content); 132b158d625SSteven Danz gzclose($fh); 133b158d625SSteven Danz }else{ 134b158d625SSteven Danz $fh = @fopen($file,'wb'); 135b158d625SSteven Danz if(!$fh){ 136b158d625SSteven Danz msg("Removing content from $file failed",-1); 137b158d625SSteven Danz return false; 138b158d625SSteven Danz } 139b158d625SSteven Danz fwrite($fh, $content); 140b158d625SSteven Danz fclose($fh); 141b158d625SSteven Danz } 142b158d625SSteven Danz }else{ 143b158d625SSteven Danz @unlink($file); 144b158d625SSteven Danz } 145b158d625SSteven Danz 146b158d625SSteven Danz io_unlock($file); 147b158d625SSteven Danz return true; 148b158d625SSteven Danz} 149b158d625SSteven Danz 150b158d625SSteven Danz/** 15190eb8392Sandi * Tries to lock a file 15290eb8392Sandi * 15390eb8392Sandi * Locking is only done for io_savefile and uses directories 15490eb8392Sandi * inside $conf['lockdir'] 15590eb8392Sandi * 15690eb8392Sandi * It waits maximal 3 seconds for the lock, after this time 15790eb8392Sandi * the lock is assumed to be stale and the function goes on 15890eb8392Sandi * 15990eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org> 16090eb8392Sandi */ 16190eb8392Sandifunction io_lock($file){ 16290eb8392Sandi global $conf; 16390eb8392Sandi // no locking if safemode hack 16490eb8392Sandi if($conf['safemodehack']) return; 16590eb8392Sandi 16690eb8392Sandi $lockDir = $conf['lockdir'].'/'.md5($file); 16790eb8392Sandi @ignore_user_abort(1); 16890eb8392Sandi 16990eb8392Sandi 17090eb8392Sandi $timeStart = time(); 17190eb8392Sandi do { 17290eb8392Sandi //waited longer than 3 seconds? -> stale lock 17390eb8392Sandi if ((time() - $timeStart) > 3) break; 17490eb8392Sandi $locked = @mkdir($lockDir); 17590eb8392Sandi } while ($locked === false); 17690eb8392Sandi} 17790eb8392Sandi 17890eb8392Sandi/** 17990eb8392Sandi * Unlocks a file 18090eb8392Sandi * 18190eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org> 18290eb8392Sandi */ 18390eb8392Sandifunction io_unlock($file){ 18490eb8392Sandi global $conf; 18590eb8392Sandi // no locking if safemode hack 18690eb8392Sandi if($conf['safemodehack']) return; 18790eb8392Sandi 18890eb8392Sandi $lockDir = $conf['lockdir'].'/'.md5($file); 18990eb8392Sandi @rmdir($lockDir); 19090eb8392Sandi @ignore_user_abort(0); 19190eb8392Sandi} 19290eb8392Sandi 19390eb8392Sandi/** 194f3f0262cSandi * Create the directory needed for the given file 19515fae107Sandi * 19615fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 197f3f0262cSandi */ 198f3f0262cSandifunction io_makeFileDir($file){ 199f3f0262cSandi global $conf; 200f3f0262cSandi 201f3f0262cSandi $dir = dirname($file); 202f3f0262cSandi umask($conf['dmask']); 203f3f0262cSandi if(!is_dir($dir)){ 204f3f0262cSandi io_mkdir_p($dir) || msg("Creating directory $dir failed",-1); 205f3f0262cSandi } 206f3f0262cSandi umask($conf['umask']); 207f3f0262cSandi} 208f3f0262cSandi 209f3f0262cSandi/** 210f3f0262cSandi * Creates a directory hierachy. 211f3f0262cSandi * 21215fae107Sandi * @link http://www.php.net/manual/en/function.mkdir.php 213f3f0262cSandi * @author <saint@corenova.com> 2143dc3a5f1Sandi * @author Andreas Gohr <andi@splitbrain.org> 215f3f0262cSandi */ 216f3f0262cSandifunction io_mkdir_p($target){ 2173dc3a5f1Sandi global $conf; 218f3f0262cSandi if (is_dir($target)||empty($target)) return 1; // best case check first 219f3f0262cSandi if (@file_exists($target) && !is_dir($target)) return 0; 2203dc3a5f1Sandi //recursion 2213dc3a5f1Sandi if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){ 2223dc3a5f1Sandi if($conf['safemodehack']){ 223034138e2SRainer Weinhold $dir = preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','', $target); 224034138e2SRainer Weinhold return io_mkdir_ftp($dir); 2253dc3a5f1Sandi }else{ 226f3f0262cSandi return @mkdir($target,0777); // crawl back up & create dir tree 2273dc3a5f1Sandi } 2283dc3a5f1Sandi } 229f3f0262cSandi return 0; 230f3f0262cSandi} 231f3f0262cSandi 232f3f0262cSandi/** 2333dc3a5f1Sandi * Creates a directory using FTP 2343dc3a5f1Sandi * 2353dc3a5f1Sandi * This is used when the safemode workaround is enabled 2363dc3a5f1Sandi * 2373dc3a5f1Sandi * @author <andi@splitbrain.org> 2383dc3a5f1Sandi */ 2393dc3a5f1Sandifunction io_mkdir_ftp($dir){ 2403dc3a5f1Sandi global $conf; 2413dc3a5f1Sandi 2423dc3a5f1Sandi if(!function_exists('ftp_connect')){ 2433dc3a5f1Sandi msg("FTP support not found - safemode workaround not usable",-1); 2443dc3a5f1Sandi return false; 2453dc3a5f1Sandi } 2463dc3a5f1Sandi 2473dc3a5f1Sandi $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10); 2483dc3a5f1Sandi if(!$conn){ 2493dc3a5f1Sandi msg("FTP connection failed",-1); 2503dc3a5f1Sandi return false; 2513dc3a5f1Sandi } 2523dc3a5f1Sandi 2533dc3a5f1Sandi if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){ 2543dc3a5f1Sandi msg("FTP login failed",-1); 2553dc3a5f1Sandi return false; 2563dc3a5f1Sandi } 2573dc3a5f1Sandi 2583dc3a5f1Sandi //create directory 259034138e2SRainer Weinhold $ok = @ftp_mkdir($conn, $dir); 2603dc3a5f1Sandi //set permissions (using the directory umask) 261034138e2SRainer Weinhold @ftp_site($conn,sprintf("CHMOD %04o %s",(0777 - $conf['dmask']),$dir)); 2623dc3a5f1Sandi 263034138e2SRainer Weinhold @ftp_close($conn); 2643dc3a5f1Sandi return $ok; 2653dc3a5f1Sandi} 2663dc3a5f1Sandi 2673dc3a5f1Sandi/** 26873ccfcb9Schris * downloads a file from the net and saves it 26973ccfcb9Schris * 27073ccfcb9Schris * if $useAttachment is false, 27173ccfcb9Schris * - $file is the full filename to save the file, incl. path 27273ccfcb9Schris * - if successful will return true, false otherwise 27373ccfcb9Schris 27473ccfcb9Schris * if $useAttachment is true, 27573ccfcb9Schris * - $file is the directory where the file should be saved 27673ccfcb9Schris * - if successful will return the name used for the saved file, false otherwise 277b625487dSandi * 278b625487dSandi * @author Andreas Gohr <andi@splitbrain.org> 27973ccfcb9Schris * @author Chris Smith <chris@jalakai.co.uk> 280b625487dSandi */ 28173ccfcb9Schrisfunction io_download($url,$file,$useAttachment=false,$defaultName=''){ 2829b307a83SAndreas Gohr $http = new DokuHTTPClient(); 2839b307a83SAndreas Gohr $http->max_bodysize = 2*1024*1024; //max. 2MB 2849b307a83SAndreas Gohr $http->timeout = 25; //max. 25 sec 2859b307a83SAndreas Gohr 2869b307a83SAndreas Gohr $data = $http->get($url); 2879b307a83SAndreas Gohr if(!$data) return false; 2889b307a83SAndreas Gohr 28973ccfcb9Schris if ($useAttachment) { 29073ccfcb9Schris $name = ''; 29173ccfcb9Schris if (isset($http->resp_headers['content-disposition'])) { 29273ccfcb9Schris $content_disposition = $http->resp_headers['content-disposition']; 29373ccfcb9Schris if (is_string($content_disposition) && 29473ccfcb9Schris preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match=array())) { 29573ccfcb9Schris 29673ccfcb9Schris $name = basename($match[1]); 29773ccfcb9Schris } 29873ccfcb9Schris 29973ccfcb9Schris } 30073ccfcb9Schris 30173ccfcb9Schris if (!$name) { 30273ccfcb9Schris if (!$defaultName) return false; 30373ccfcb9Schris $name = $defaultName; 30473ccfcb9Schris } 30573ccfcb9Schris 30673ccfcb9Schris $file = $file.$name; 30773ccfcb9Schris } 30873ccfcb9Schris 3099b307a83SAndreas Gohr $fp = @fopen($file,"w"); 310b625487dSandi if(!$fp) return false; 3119b307a83SAndreas Gohr fwrite($fp,$data); 312b625487dSandi fclose($fp); 31373ccfcb9Schris if ($useAttachment) return $name; 314b625487dSandi return true; 315b625487dSandi} 316b625487dSandi 317b625487dSandi/** 318f3f0262cSandi * Runs an external command and returns it's output as string 31915fae107Sandi * 32015fae107Sandi * @author Harry Brueckner <harry_b@eml.cc> 32115fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 3223dc3a5f1Sandi * @deprecated 323f3f0262cSandi */ 324f3f0262cSandifunction io_runcmd($cmd){ 325f3f0262cSandi $fh = popen($cmd, "r"); 326f3f0262cSandi if(!$fh) return false; 327f3f0262cSandi $ret = ''; 328f3f0262cSandi while (!feof($fh)) { 329f3f0262cSandi $ret .= fread($fh, 8192); 330f3f0262cSandi } 331f3f0262cSandi pclose($fh); 332f3f0262cSandi return $ret; 333f3f0262cSandi} 334f3f0262cSandi 335340756e4Sandi 336340756e4Sandi//Setup VIM: ex: et ts=2 enc=utf-8 : 337