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