xref: /dokuwiki/inc/io.php (revision 90eb8392cdad2d4e8e8b8b6731f5400c37849ed3)
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 *
5315fae107Sandi * Uses gzip if extension is .gz
5415fae107Sandi *
5515fae107Sandi * @author  Andreas Gohr <andi@splitbrain.org>
5615fae107Sandi * @return bool true on success
57f3f0262cSandi */
58f3f0262cSandifunction io_saveFile($file,$content){
59f3f0262cSandi  io_makeFileDir($file);
60*90eb8392Sandi  io_lock($file);
61f3f0262cSandi  if(substr($file,-3) == '.gz'){
62f3f0262cSandi    $fh = @gzopen($file,'wb9');
63f3f0262cSandi    if(!$fh){
64f3f0262cSandi      msg("Writing $file failed",-1);
65f3f0262cSandi      return false;
66f3f0262cSandi    }
67f3f0262cSandi    gzwrite($fh, $content);
68f3f0262cSandi    gzclose($fh);
69f3f0262cSandi  }else{
70f3f0262cSandi    $fh = @fopen($file,'wb');
71f3f0262cSandi    if(!$fh){
72f3f0262cSandi      msg("Writing $file failed",-1);
73f3f0262cSandi      return false;
74f3f0262cSandi    }
75f3f0262cSandi    fwrite($fh, $content);
76f3f0262cSandi    fclose($fh);
77f3f0262cSandi  }
78*90eb8392Sandi  io_unlock($file);
79f3f0262cSandi  return true;
80f3f0262cSandi}
81f3f0262cSandi
82f3f0262cSandi/**
83*90eb8392Sandi * Tries to lock a file
84*90eb8392Sandi *
85*90eb8392Sandi * Locking is only done for io_savefile and uses directories
86*90eb8392Sandi * inside $conf['lockdir']
87*90eb8392Sandi *
88*90eb8392Sandi * It waits maximal 3 seconds for the lock, after this time
89*90eb8392Sandi * the lock is assumed to be stale and the function goes on
90*90eb8392Sandi *
91*90eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org>
92*90eb8392Sandi */
93*90eb8392Sandifunction io_lock($file){
94*90eb8392Sandi  global $conf;
95*90eb8392Sandi  // no locking if safemode hack
96*90eb8392Sandi  if($conf['safemodehack']) return;
97*90eb8392Sandi
98*90eb8392Sandi  $lockDir = $conf['lockdir'].'/'.md5($file);
99*90eb8392Sandi  @ignore_user_abort(1);
100*90eb8392Sandi
101*90eb8392Sandi
102*90eb8392Sandi  $timeStart = time();
103*90eb8392Sandi  do {
104*90eb8392Sandi    //waited longer than 3 seconds? -> stale lock
105*90eb8392Sandi    if ((time() - $timeStart) > 3) break;
106*90eb8392Sandi    $locked = @mkdir($lockDir);
107*90eb8392Sandi  } while ($locked === false);
108*90eb8392Sandi}
109*90eb8392Sandi
110*90eb8392Sandi/**
111*90eb8392Sandi * Unlocks a file
112*90eb8392Sandi *
113*90eb8392Sandi * @author Andreas Gohr <andi@splitbrain.org>
114*90eb8392Sandi */
115*90eb8392Sandifunction io_unlock($file){
116*90eb8392Sandi  global $conf;
117*90eb8392Sandi  // no locking if safemode hack
118*90eb8392Sandi  if($conf['safemodehack']) return;
119*90eb8392Sandi
120*90eb8392Sandi  $lockDir = $conf['lockdir'].'/'.md5($file);
121*90eb8392Sandi  @rmdir($lockDir);
122*90eb8392Sandi  @ignore_user_abort(0);
123*90eb8392Sandi}
124*90eb8392Sandi
125*90eb8392Sandi/**
126f3f0262cSandi * Create the directory needed for the given file
12715fae107Sandi *
12815fae107Sandi * @author  Andreas Gohr <andi@splitbrain.org>
129f3f0262cSandi */
130f3f0262cSandifunction io_makeFileDir($file){
131f3f0262cSandi  global $conf;
132f3f0262cSandi
133f3f0262cSandi  $dir = dirname($file);
1343dc3a5f1Sandi  if($conf['safemodehack']){
135bce5c1daSandi    $dir = preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','',$dir);
1363dc3a5f1Sandi  }
137f3f0262cSandi  umask($conf['dmask']);
138f3f0262cSandi  if(!is_dir($dir)){
139f3f0262cSandi    io_mkdir_p($dir) || msg("Creating directory $dir failed",-1);
140f3f0262cSandi  }
141f3f0262cSandi  umask($conf['umask']);
142f3f0262cSandi}
143f3f0262cSandi
144f3f0262cSandi/**
145f3f0262cSandi * Creates a directory hierachy.
146f3f0262cSandi *
14715fae107Sandi * @link    http://www.php.net/manual/en/function.mkdir.php
148f3f0262cSandi * @author  <saint@corenova.com>
1493dc3a5f1Sandi * @author  Andreas Gohr <andi@splitbrain.org>
150f3f0262cSandi */
151f3f0262cSandifunction io_mkdir_p($target){
1523dc3a5f1Sandi  global $conf;
153f3f0262cSandi  if (is_dir($target)||empty($target)) return 1; // best case check first
154f3f0262cSandi  if (@file_exists($target) && !is_dir($target)) return 0;
1553dc3a5f1Sandi  //recursion
1563dc3a5f1Sandi  if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){
1573dc3a5f1Sandi    if($conf['safemodehack']){
1583dc3a5f1Sandi      return io_mkdir_ftp($target);
1593dc3a5f1Sandi    }else{
160f3f0262cSandi      return @mkdir($target,0777); // crawl back up & create dir tree
1613dc3a5f1Sandi    }
1623dc3a5f1Sandi  }
163f3f0262cSandi  return 0;
164f3f0262cSandi}
165f3f0262cSandi
166f3f0262cSandi/**
1673dc3a5f1Sandi * Creates a directory using FTP
1683dc3a5f1Sandi *
1693dc3a5f1Sandi * This is used when the safemode workaround is enabled
1703dc3a5f1Sandi *
1713dc3a5f1Sandi * @author <andi@splitbrain.org>
1723dc3a5f1Sandi */
1733dc3a5f1Sandifunction io_mkdir_ftp($dir){
1743dc3a5f1Sandi  global $conf;
1753dc3a5f1Sandi
1763dc3a5f1Sandi  if(!function_exists('ftp_connect')){
1773dc3a5f1Sandi    msg("FTP support not found - safemode workaround not usable",-1);
1783dc3a5f1Sandi    return false;
1793dc3a5f1Sandi  }
1803dc3a5f1Sandi
1813dc3a5f1Sandi  $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10);
1823dc3a5f1Sandi  if(!$conn){
1833dc3a5f1Sandi    msg("FTP connection failed",-1);
1843dc3a5f1Sandi    return false;
1853dc3a5f1Sandi  }
1863dc3a5f1Sandi
1873dc3a5f1Sandi  if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){
1883dc3a5f1Sandi    msg("FTP login failed",-1);
1893dc3a5f1Sandi    return false;
1903dc3a5f1Sandi  }
1913dc3a5f1Sandi
1927b7154fbSandi//FIXME silence those commands again!
1933dc3a5f1Sandi  //create directory
1947b7154fbSandi  $ok = ftp_mkdir($conn, $dir);
1953dc3a5f1Sandi  //set permissions (using the directory umask)
1967879fd27Sandi  ftp_site($conn,sprintf("CHMOD %04o %s",(0777 - $conf['dmask']),$dir));
1973dc3a5f1Sandi
1983dc3a5f1Sandi  ftp_close($conn);
1993dc3a5f1Sandi  return $ok;
2003dc3a5f1Sandi}
2013dc3a5f1Sandi
2023dc3a5f1Sandi/**
203b625487dSandi * downloads a file from the net and saves it to the given location
204b625487dSandi *
205b625487dSandi * @author Andreas Gohr <andi@splitbrain.org>
206b625487dSandi * @todo   Add size limit
207b625487dSandi */
208b625487dSandifunction io_download($url,$file){
209b625487dSandi  $fp = @fopen($url,"rb");
210b625487dSandi  if(!$fp) return false;
211b625487dSandi
2120e33fac4Sandi  $kb  = 0;
2130e33fac4Sandi  $now = time();
2140e33fac4Sandi
215b625487dSandi  while(!feof($fp)){
2160e33fac4Sandi    if($kb++ > 2048 || (time() - $now) > 45){
2170e33fac4Sandi      //abort on 2 MB and timeout on 45 sec
2180e33fac4Sandi      return false;
2190e33fac4Sandi    }
220b625487dSandi    $cont.= fread($fp,1024);
221b625487dSandi  }
222b625487dSandi  fclose($fp);
223b625487dSandi
224b625487dSandi  $fp2 = @fopen($file,"w");
225b625487dSandi  if(!$fp2) return false;
226b625487dSandi  fwrite($fp2,$cont);
227b625487dSandi  fclose($fp2);
228b625487dSandi  return true;
229b625487dSandi}
230b625487dSandi
231b625487dSandi/**
232f3f0262cSandi * Runs an external command and returns it's output as string
23315fae107Sandi *
23415fae107Sandi * @author Harry Brueckner <harry_b@eml.cc>
23515fae107Sandi * @author Andreas Gohr <andi@splitbrain.org>
2363dc3a5f1Sandi * @deprecated
237f3f0262cSandi */
238f3f0262cSandifunction io_runcmd($cmd){
239f3f0262cSandi  $fh = popen($cmd, "r");
240f3f0262cSandi  if(!$fh) return false;
241f3f0262cSandi  $ret = '';
242f3f0262cSandi  while (!feof($fh)) {
243f3f0262cSandi    $ret .= fread($fh, 8192);
244f3f0262cSandi  }
245f3f0262cSandi  pclose($fh);
246f3f0262cSandi  return $ret;
247f3f0262cSandi}
248f3f0262cSandi
249340756e4Sandi
250340756e4Sandi//Setup VIM: ex: et ts=2 enc=utf-8 :
251