1<?php 2/** 3 * File IO functions 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); 10 require_once(DOKU_INC.'inc/common.php'); 11 require_once(DOKU_INC.'inc/HTTPClient.php'); 12 13/** 14 * Removes empty directories 15 * 16 * @todo use safemode hack 17 * @author Andreas Gohr <andi@splitbrain.org> 18 */ 19function io_sweepNS($id){ 20 global $conf; 21 22 //scan all namespaces 23 while(($id = getNS($id)) !== false){ 24 $dir = $conf['datadir'].'/'.str_replace(':','/',$id); 25 $dir = utf8_encodeFN($dir); 26 27 //try to delete dir else return 28 if(!@rmdir($dir)) return; 29 } 30} 31 32/** 33 * Returns content of $file as cleaned string. 34 * 35 * Uses gzip if extension is .gz 36 * 37 * @author Andreas Gohr <andi@splitbrain.org> 38 */ 39function io_readFile($file){ 40 $ret = ''; 41 if(@file_exists($file)){ 42 if(substr($file,-3) == '.gz'){ 43 $ret = join('',gzfile($file)); 44 }else{ 45 $ret = join('',file($file)); 46 } 47 } 48 return cleanText($ret); 49} 50 51/** 52 * Saves $content to $file. 53 * 54 * If the third parameter is set to true the given content 55 * will be appended. 56 * 57 * Uses gzip if extension is .gz 58 * 59 * @author Andreas Gohr <andi@splitbrain.org> 60 * @return bool true on success 61 */ 62function io_saveFile($file,$content,$append=false){ 63 $mode = ($append) ? 'ab' : 'wb'; 64 65 io_makeFileDir($file); 66 io_lock($file); 67 if(substr($file,-3) == '.gz'){ 68 $fh = @gzopen($file,$mode.'9'); 69 if(!$fh){ 70 msg("Writing $file failed",-1); 71 return false; 72 } 73 gzwrite($fh, $content); 74 gzclose($fh); 75 }else{ 76 $fh = @fopen($file,$mode); 77 if(!$fh){ 78 msg("Writing $file failed",-1); 79 return false; 80 } 81 fwrite($fh, $content); 82 fclose($fh); 83 } 84 io_unlock($file); 85 return true; 86} 87 88/** 89 * Delete exact linematch for $badline from $file. 90 * 91 * Be sure to include the trailing newline in $badline 92 * 93 * Uses gzip if extension is .gz 94 * 95 * @author Steven Danz <steven-danz@kc.rr.com> 96 * @return bool true on success 97 */ 98function io_deleteFromFile($file,$badline){ 99 if (!@file_exists($file)) return true; 100 101 io_lock($file); 102 103 // load into array 104 if(substr($file,-3) == '.gz'){ 105 $lines = gzfile($file); 106 }else{ 107 $lines = file($file); 108 } 109 110 // remove all matching lines 111 $pos = array_search($badline,$lines); //return null or false if not found 112 while(is_int($pos)){ 113 unset($lines[$pos]); 114 $pos = array_search($badline,$lines); 115 } 116 117 if(count($lines)){ 118 $content = join('',$lines); 119 if(substr($file,-3) == '.gz'){ 120 $fh = @gzopen($file,'wb9'); 121 if(!$fh){ 122 msg("Removing content from $file failed",-1); 123 return false; 124 } 125 gzwrite($fh, $content); 126 gzclose($fh); 127 }else{ 128 $fh = @fopen($file,'wb'); 129 if(!$fh){ 130 msg("Removing content from $file failed",-1); 131 return false; 132 } 133 fwrite($fh, $content); 134 fclose($fh); 135 } 136 }else{ 137 @unlink($file); 138 } 139 140 io_unlock($file); 141 return true; 142} 143 144/** 145 * Tries to lock a file 146 * 147 * Locking is only done for io_savefile and uses directories 148 * inside $conf['lockdir'] 149 * 150 * It waits maximal 3 seconds for the lock, after this time 151 * the lock is assumed to be stale and the function goes on 152 * 153 * @author Andreas Gohr <andi@splitbrain.org> 154 */ 155function io_lock($file){ 156 global $conf; 157 // no locking if safemode hack 158 if($conf['safemodehack']) return; 159 160 $lockDir = $conf['lockdir'].'/'.md5($file); 161 @ignore_user_abort(1); 162 163 164 $timeStart = time(); 165 do { 166 //waited longer than 3 seconds? -> stale lock 167 if ((time() - $timeStart) > 3) break; 168 $locked = @mkdir($lockDir); 169 } while ($locked === false); 170} 171 172/** 173 * Unlocks a file 174 * 175 * @author Andreas Gohr <andi@splitbrain.org> 176 */ 177function io_unlock($file){ 178 global $conf; 179 // no locking if safemode hack 180 if($conf['safemodehack']) return; 181 182 $lockDir = $conf['lockdir'].'/'.md5($file); 183 @rmdir($lockDir); 184 @ignore_user_abort(0); 185} 186 187/** 188 * Create the directory needed for the given file 189 * 190 * @author Andreas Gohr <andi@splitbrain.org> 191 */ 192function io_makeFileDir($file){ 193 global $conf; 194 195 $dir = dirname($file); 196 umask($conf['dmask']); 197 if(!is_dir($dir)){ 198 io_mkdir_p($dir) || msg("Creating directory $dir failed",-1); 199 } 200 umask($conf['umask']); 201} 202 203/** 204 * Creates a directory hierachy. 205 * 206 * @link http://www.php.net/manual/en/function.mkdir.php 207 * @author <saint@corenova.com> 208 * @author Andreas Gohr <andi@splitbrain.org> 209 */ 210function io_mkdir_p($target){ 211 global $conf; 212 if (is_dir($target)||empty($target)) return 1; // best case check first 213 if (@file_exists($target) && !is_dir($target)) return 0; 214 //recursion 215 if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){ 216 if($conf['safemodehack']){ 217 $dir = preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','', $target); 218 return io_mkdir_ftp($dir); 219 }else{ 220 return @mkdir($target,0777); // crawl back up & create dir tree 221 } 222 } 223 return 0; 224} 225 226/** 227 * Creates a directory using FTP 228 * 229 * This is used when the safemode workaround is enabled 230 * 231 * @author <andi@splitbrain.org> 232 */ 233function io_mkdir_ftp($dir){ 234 global $conf; 235 236 if(!function_exists('ftp_connect')){ 237 msg("FTP support not found - safemode workaround not usable",-1); 238 return false; 239 } 240 241 $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10); 242 if(!$conn){ 243 msg("FTP connection failed",-1); 244 return false; 245 } 246 247 if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){ 248 msg("FTP login failed",-1); 249 return false; 250 } 251 252 //create directory 253 $ok = @ftp_mkdir($conn, $dir); 254 //set permissions (using the directory umask) 255 @ftp_site($conn,sprintf("CHMOD %04o %s",(0777 - $conf['dmask']),$dir)); 256 257 @ftp_close($conn); 258 return $ok; 259} 260 261/** 262 * downloads a file from the net and saves it to the given location 263 * 264 * @author Andreas Gohr <andi@splitbrain.org> 265 */ 266function io_download($url,$file){ 267 $http = new DokuHTTPClient(); 268 $http->max_bodysize = 2*1024*1024; //max. 2MB 269 $http->timeout = 25; //max. 25 sec 270 271 $data = $http->get($url); 272 if(!$data) return false; 273 274 $fp = @fopen($file,"w"); 275 if(!$fp) return false; 276 fwrite($fp,$data); 277 fclose($fp); 278 return true; 279} 280 281/** 282 * Runs an external command and returns it's output as string 283 * 284 * @author Harry Brueckner <harry_b@eml.cc> 285 * @author Andreas Gohr <andi@splitbrain.org> 286 * @deprecated 287 */ 288function io_runcmd($cmd){ 289 $fh = popen($cmd, "r"); 290 if(!$fh) return false; 291 $ret = ''; 292 while (!feof($fh)) { 293 $ret .= fread($fh, 8192); 294 } 295 pclose($fh); 296 return $ret; 297} 298 299 300//Setup VIM: ex: et ts=2 enc=utf-8 : 301