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'); 11f3f0262cSandi 12f3f0262cSandi/** 1353d6ccfeSandi * Removes empty directories 1453d6ccfeSandi * 1553d6ccfeSandi * @todo use safemode hack 1653d6ccfeSandi * @author Andreas Gohr <andi@splitbrain.org> 1753d6ccfeSandi */ 1853d6ccfeSandifunction io_sweepNS($id){ 1953d6ccfeSandi global $conf; 2053d6ccfeSandi 2153d6ccfeSandi //scan all namespaces 2253d6ccfeSandi while(($id = getNS($id)) !== false){ 2353d6ccfeSandi $dir = $conf['datadir'].'/'.str_replace(':','/',$id); 2453d6ccfeSandi $dir = utf8_encodeFN($dir); 2553d6ccfeSandi 2653d6ccfeSandi //try to delete dir else return 2753d6ccfeSandi if(!@rmdir($dir)) return; 2853d6ccfeSandi } 2953d6ccfeSandi} 3053d6ccfeSandi 3153d6ccfeSandi/** 3215fae107Sandi * Returns content of $file as cleaned string. 3315fae107Sandi * 3415fae107Sandi * Uses gzip if extension is .gz 3515fae107Sandi * 3615fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 37f3f0262cSandi */ 38f3f0262cSandifunction io_readFile($file){ 39f3f0262cSandi $ret = ''; 40f3f0262cSandi if(@file_exists($file)){ 41f3f0262cSandi if(substr($file,-3) == '.gz'){ 42f3f0262cSandi $ret = join('',gzfile($file)); 43f3f0262cSandi }else{ 44f3f0262cSandi $ret = join('',file($file)); 45f3f0262cSandi } 46f3f0262cSandi } 47f3f0262cSandi return cleanText($ret); 48f3f0262cSandi} 49f3f0262cSandi 50f3f0262cSandi/** 5115fae107Sandi * Saves $content to $file. 52f3f0262cSandi * 53*1380fc45SAndreas Gohr * If the third parameter is set to true the given content 54*1380fc45SAndreas Gohr * will be appended. 55*1380fc45SAndreas Gohr * 5615fae107Sandi * Uses gzip if extension is .gz 5715fae107Sandi * 5815fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 5915fae107Sandi * @return bool true on success 60f3f0262cSandi */ 61*1380fc45SAndreas Gohrfunction io_saveFile($file,$content,$append=false){ 62*1380fc45SAndreas Gohr $mode = ($append) ? 'ab' : 'wb'; 63*1380fc45SAndreas Gohr 64f3f0262cSandi io_makeFileDir($file); 6590eb8392Sandi io_lock($file); 66f3f0262cSandi if(substr($file,-3) == '.gz'){ 67*1380fc45SAndreas Gohr $fh = @gzopen($file,$mode.'9'); 68f3f0262cSandi if(!$fh){ 69f3f0262cSandi msg("Writing $file failed",-1); 70f3f0262cSandi return false; 71f3f0262cSandi } 72f3f0262cSandi gzwrite($fh, $content); 73f3f0262cSandi gzclose($fh); 74f3f0262cSandi }else{ 75*1380fc45SAndreas Gohr $fh = @fopen($file,$mode); 76f3f0262cSandi if(!$fh){ 77f3f0262cSandi msg("Writing $file failed",-1); 78f3f0262cSandi return false; 79f3f0262cSandi } 80f3f0262cSandi fwrite($fh, $content); 81f3f0262cSandi fclose($fh); 82f3f0262cSandi } 8390eb8392Sandi io_unlock($file); 84f3f0262cSandi return true; 85f3f0262cSandi} 86f3f0262cSandi 87f3f0262cSandi/** 88*1380fc45SAndreas Gohr * Delete exact linematch for $badline from $file. 89*1380fc45SAndreas Gohr * 90*1380fc45SAndreas Gohr * Be sure to include the trailing newline in $badline 91b158d625SSteven Danz * 92b158d625SSteven Danz * Uses gzip if extension is .gz 93b158d625SSteven Danz * 94b158d625SSteven Danz * @author Steven Danz <steven-danz@kc.rr.com> 95b158d625SSteven Danz * @return bool true on success 96b158d625SSteven Danz */ 97*1380fc45SAndreas Gohrfunction io_deleteFromFile($file,$badline){ 98*1380fc45SAndreas Gohr if (!@file_exists($file)) return true; 99*1380fc45SAndreas Gohr 100b158d625SSteven Danz io_lock($file); 101*1380fc45SAndreas Gohr 102*1380fc45SAndreas Gohr // load into array 103b158d625SSteven Danz if(substr($file,-3) == '.gz'){ 104*1380fc45SAndreas Gohr $lines = gzfile($file); 105b158d625SSteven Danz }else{ 106*1380fc45SAndreas Gohr $lines = file($file); 107b158d625SSteven Danz } 108b158d625SSteven Danz 109*1380fc45SAndreas Gohr // remove all matching lines 110*1380fc45SAndreas Gohr $pos = array_search($badline,$lines); //return null or false if not found 111*1380fc45SAndreas Gohr while(is_int($pos)){ 112*1380fc45SAndreas Gohr unset($lines[$pos]); 113*1380fc45SAndreas Gohr $pos = array_search($badline,$lines); 114b158d625SSteven Danz } 115b158d625SSteven Danz 116*1380fc45SAndreas Gohr if(count($lines)){ 117*1380fc45SAndreas Gohr $content = join('',$lines); 118b158d625SSteven Danz if(substr($file,-3) == '.gz'){ 119b158d625SSteven Danz $fh = @gzopen($file,'wb9'); 120b158d625SSteven Danz if(!$fh){ 121b158d625SSteven Danz msg("Removing content from $file failed",-1); 122b158d625SSteven Danz return false; 123b158d625SSteven Danz } 124b158d625SSteven Danz gzwrite($fh, $content); 125b158d625SSteven Danz gzclose($fh); 126b158d625SSteven Danz }else{ 127b158d625SSteven Danz $fh = @fopen($file,'wb'); 128b158d625SSteven Danz if(!$fh){ 129b158d625SSteven Danz msg("Removing content from $file failed",-1); 130b158d625SSteven Danz return false; 131b158d625SSteven Danz } 132b158d625SSteven Danz fwrite($fh, $content); 133b158d625SSteven Danz fclose($fh); 134b158d625SSteven Danz } 135b158d625SSteven Danz }else{ 136b158d625SSteven Danz @unlink($file); 137b158d625SSteven Danz } 138b158d625SSteven Danz 139b158d625SSteven Danz io_unlock($file); 140b158d625SSteven Danz return true; 141b158d625SSteven Danz} 142b158d625SSteven Danz 143b158d625SSteven Danz/** 14490eb8392Sandi * Tries to lock a file 14590eb8392Sandi * 14690eb8392Sandi * Locking is only done for io_savefile and uses directories 14790eb8392Sandi * inside $conf['lockdir'] 14890eb8392Sandi * 14990eb8392Sandi * It waits maximal 3 seconds for the lock, after this time 15090eb8392Sandi * the lock is assumed to be stale and the function goes on 15190eb8392Sandi * 15290eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org> 15390eb8392Sandi */ 15490eb8392Sandifunction io_lock($file){ 15590eb8392Sandi global $conf; 15690eb8392Sandi // no locking if safemode hack 15790eb8392Sandi if($conf['safemodehack']) return; 15890eb8392Sandi 15990eb8392Sandi $lockDir = $conf['lockdir'].'/'.md5($file); 16090eb8392Sandi @ignore_user_abort(1); 16190eb8392Sandi 16290eb8392Sandi 16390eb8392Sandi $timeStart = time(); 16490eb8392Sandi do { 16590eb8392Sandi //waited longer than 3 seconds? -> stale lock 16690eb8392Sandi if ((time() - $timeStart) > 3) break; 16790eb8392Sandi $locked = @mkdir($lockDir); 16890eb8392Sandi } while ($locked === false); 16990eb8392Sandi} 17090eb8392Sandi 17190eb8392Sandi/** 17290eb8392Sandi * Unlocks a file 17390eb8392Sandi * 17490eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org> 17590eb8392Sandi */ 17690eb8392Sandifunction io_unlock($file){ 17790eb8392Sandi global $conf; 17890eb8392Sandi // no locking if safemode hack 17990eb8392Sandi if($conf['safemodehack']) return; 18090eb8392Sandi 18190eb8392Sandi $lockDir = $conf['lockdir'].'/'.md5($file); 18290eb8392Sandi @rmdir($lockDir); 18390eb8392Sandi @ignore_user_abort(0); 18490eb8392Sandi} 18590eb8392Sandi 18690eb8392Sandi/** 187f3f0262cSandi * Create the directory needed for the given file 18815fae107Sandi * 18915fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 190f3f0262cSandi */ 191f3f0262cSandifunction io_makeFileDir($file){ 192f3f0262cSandi global $conf; 193f3f0262cSandi 194f3f0262cSandi $dir = dirname($file); 195f3f0262cSandi umask($conf['dmask']); 196f3f0262cSandi if(!is_dir($dir)){ 197f3f0262cSandi io_mkdir_p($dir) || msg("Creating directory $dir failed",-1); 198f3f0262cSandi } 199f3f0262cSandi umask($conf['umask']); 200f3f0262cSandi} 201f3f0262cSandi 202f3f0262cSandi/** 203f3f0262cSandi * Creates a directory hierachy. 204f3f0262cSandi * 20515fae107Sandi * @link http://www.php.net/manual/en/function.mkdir.php 206f3f0262cSandi * @author <saint@corenova.com> 2073dc3a5f1Sandi * @author Andreas Gohr <andi@splitbrain.org> 208f3f0262cSandi */ 209f3f0262cSandifunction io_mkdir_p($target){ 2103dc3a5f1Sandi global $conf; 211f3f0262cSandi if (is_dir($target)||empty($target)) return 1; // best case check first 212f3f0262cSandi if (@file_exists($target) && !is_dir($target)) return 0; 2133dc3a5f1Sandi //recursion 2143dc3a5f1Sandi if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){ 2153dc3a5f1Sandi if($conf['safemodehack']){ 216034138e2SRainer Weinhold $dir = preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','', $target); 217034138e2SRainer Weinhold return io_mkdir_ftp($dir); 2183dc3a5f1Sandi }else{ 219f3f0262cSandi return @mkdir($target,0777); // crawl back up & create dir tree 2203dc3a5f1Sandi } 2213dc3a5f1Sandi } 222f3f0262cSandi return 0; 223f3f0262cSandi} 224f3f0262cSandi 225f3f0262cSandi/** 2263dc3a5f1Sandi * Creates a directory using FTP 2273dc3a5f1Sandi * 2283dc3a5f1Sandi * This is used when the safemode workaround is enabled 2293dc3a5f1Sandi * 2303dc3a5f1Sandi * @author <andi@splitbrain.org> 2313dc3a5f1Sandi */ 2323dc3a5f1Sandifunction io_mkdir_ftp($dir){ 2333dc3a5f1Sandi global $conf; 2343dc3a5f1Sandi 2353dc3a5f1Sandi if(!function_exists('ftp_connect')){ 2363dc3a5f1Sandi msg("FTP support not found - safemode workaround not usable",-1); 2373dc3a5f1Sandi return false; 2383dc3a5f1Sandi } 2393dc3a5f1Sandi 2403dc3a5f1Sandi $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10); 2413dc3a5f1Sandi if(!$conn){ 2423dc3a5f1Sandi msg("FTP connection failed",-1); 2433dc3a5f1Sandi return false; 2443dc3a5f1Sandi } 2453dc3a5f1Sandi 2463dc3a5f1Sandi if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){ 2473dc3a5f1Sandi msg("FTP login failed",-1); 2483dc3a5f1Sandi return false; 2493dc3a5f1Sandi } 2503dc3a5f1Sandi 2513dc3a5f1Sandi //create directory 252034138e2SRainer Weinhold $ok = @ftp_mkdir($conn, $dir); 2533dc3a5f1Sandi //set permissions (using the directory umask) 254034138e2SRainer Weinhold @ftp_site($conn,sprintf("CHMOD %04o %s",(0777 - $conf['dmask']),$dir)); 2553dc3a5f1Sandi 256034138e2SRainer Weinhold @ftp_close($conn); 2573dc3a5f1Sandi return $ok; 2583dc3a5f1Sandi} 2593dc3a5f1Sandi 2603dc3a5f1Sandi/** 261b625487dSandi * downloads a file from the net and saves it to the given location 262b625487dSandi * 263b625487dSandi * @author Andreas Gohr <andi@splitbrain.org> 264b625487dSandi * @todo Add size limit 265b625487dSandi */ 266b625487dSandifunction io_download($url,$file){ 267b625487dSandi $fp = @fopen($url,"rb"); 268b625487dSandi if(!$fp) return false; 269b625487dSandi 2700e33fac4Sandi $kb = 0; 2710e33fac4Sandi $now = time(); 2720e33fac4Sandi 273b625487dSandi while(!feof($fp)){ 2740e33fac4Sandi if($kb++ > 2048 || (time() - $now) > 45){ 2750e33fac4Sandi //abort on 2 MB and timeout on 45 sec 2760e33fac4Sandi return false; 2770e33fac4Sandi } 278b625487dSandi $cont.= fread($fp,1024); 279b625487dSandi } 280b625487dSandi fclose($fp); 281b625487dSandi 282b625487dSandi $fp2 = @fopen($file,"w"); 283b625487dSandi if(!$fp2) return false; 284b625487dSandi fwrite($fp2,$cont); 285b625487dSandi fclose($fp2); 286b625487dSandi return true; 287b625487dSandi} 288b625487dSandi 289b625487dSandi/** 290f3f0262cSandi * Runs an external command and returns it's output as string 29115fae107Sandi * 29215fae107Sandi * @author Harry Brueckner <harry_b@eml.cc> 29315fae107Sandi * @author Andreas Gohr <andi@splitbrain.org> 2943dc3a5f1Sandi * @deprecated 295f3f0262cSandi */ 296f3f0262cSandifunction io_runcmd($cmd){ 297f3f0262cSandi $fh = popen($cmd, "r"); 298f3f0262cSandi if(!$fh) return false; 299f3f0262cSandi $ret = ''; 300f3f0262cSandi while (!feof($fh)) { 301f3f0262cSandi $ret .= fread($fh, 8192); 302f3f0262cSandi } 303f3f0262cSandi pclose($fh); 304f3f0262cSandi return $ret; 305f3f0262cSandi} 306f3f0262cSandi 307340756e4Sandi 308340756e4Sandi//Setup VIM: ex: et ts=2 enc=utf-8 : 309