Source for file files.php

Documentation is available at files.php

  1. <?php
  2.  
  3. /**
  4.  * files.php
  5.  *
  6.  * This file includes various helper functions for working
  7.  * with the server filesystem.
  8.  *
  9.  * @copyright 2008-2020 The SquirrelMail Project Team
  10.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11.  * @version $Id: files.php 14845 2020-01-07 08:09:34Z pdontthink $
  12.  * @package squirrelmail
  13.  */
  14.  
  15.  
  16. /**
  17.  * Generates a unique file in a specific directory and
  18.  * returns the file name (without the path).
  19.  *
  20.  * @param directory The directory within which to create the file
  21.  *
  22.  * @return mixed FALSE when a failure occurs, otherwise a string
  23.  *                containing the filename of the file only (not
  24.  *                its full path)
  25.  *
  26.  * @since 1.5.2
  27.  *
  28.  */
  29. function sq_create_tempfile($directory)
  30. {
  31.  
  32.     // give up after 1000 tries
  33.     $maximum_tries 1000;
  34.  
  35.     // using PHP >= 4.3.2 we can be truly atomic here
  36.     $filemods check_php_version(432'x' 'w';
  37.  
  38.     for ($try 0$try $maximum_tries++$try{
  39.  
  40.         $localfilename GenerateRandomString(32''7);
  41.         $full_localfilename $directory DIRECTORY_SEPARATOR $localfilename;
  42.  
  43.         // filename collision. try again
  44.         if file_exists($full_localfilename) ) {
  45.             continue;
  46.         }
  47.  
  48.         // try to open for (binary) writing
  49.         $fp @fopen$full_localfilename$filemods);
  50.  
  51.         if ($fp !== FALSE{
  52.             // success! make sure it's not readable, close and return filename
  53.             chmod($full_localfilename0600);
  54.             fclose($fp);
  55.             return $localfilename;
  56.         }
  57.  
  58.     }
  59.  
  60.     // we tried as many times as we could but didn't succeed.
  61.     return FALSE;
  62.  
  63. }
  64.  
  65.  
  66. /**
  67.   * PHP's is_writable() is broken in some versions due to either
  68.   * safe_mode or because of problems correctly determining the
  69.   * actual file permissions under Windows.  Under safe_mode or
  70.   * Windows, we'll try to actually write something in order to
  71.   * see for sure...
  72.   *
  73.   * @param string $path The full path to the file or directory to
  74.   *                      be tested
  75.   *
  76.   * @return boolean Whether or not the file or directory exists
  77.   *                  and is writable
  78.   *
  79.   * @since 1.5.2
  80.   *
  81.   ***/
  82. function sq_is_writable($path{
  83.  
  84.    global $server_os;
  85.  
  86.  
  87.    // under *nix with safe_mode off, use the native is_writable()
  88.    //
  89.    if ($server_os == '*nix' && !(bool)ini_get('safe_mode'))
  90.       return is_writable($path);
  91.  
  92.  
  93.    // if it's a directory, that means we have to create a temporary
  94.    // file therein
  95.    //
  96.    $delete_temp_file FALSE;
  97.    if (@is_dir($path&& ($temp_filename @sq_create_tempfile($path)))
  98.    {
  99.       $path .= DIRECTORY_SEPARATOR $temp_filename;
  100.       $delete_temp_file TRUE;
  101.    }
  102.  
  103.  
  104.    // try to open the file for writing (without trying to create it)
  105.    //
  106.    if (!@is_dir($path&& ($FILE @fopen($path'r+')))
  107.    {
  108.       @fclose($FILE);
  109.  
  110.       // delete temp file if needed
  111.       //
  112.       if ($delete_temp_file)
  113.          @unlink($path);
  114.  
  115.       return TRUE;
  116.    }
  117.  
  118.  
  119.    // delete temp file if needed
  120.    //
  121.    if ($delete_temp_file)
  122.       @unlink($path);
  123.  
  124.    return FALSE;
  125.  
  126. }
  127.  
  128.  
  129. /**
  130.   * Find files and/or directories in a given directory optionally
  131.   * limited to only those with the given file extension.  If the
  132.   * directory is not found or cannot be opened, no error is generated;
  133.   * only an empty file list is returned.
  134. FIXME: do we WANT to throw an error or a notice or... or return FALSE?
  135.   *
  136.   * @param string $directory_path         The path (relative or absolute)
  137.   *                                        to the desired directory.
  138.   * @param mixed  $extension              The file extension filter - either
  139.   *                                        an array of desired extension(s),
  140.   *                                        or a comma-separated list of same
  141.   *                                        (optional; default is to return
  142.   *                                        all files (dirs).
  143.   * @param boolean $return_filenames_only When TRUE, only file/dir names
  144.   *                                        are returned, otherwise the
  145.   *                                        $directory_path string is
  146.   *                                        prepended to each file/dir in
  147.   *                                        the returned list (optional;
  148.   *                                        default is filename/dirname only)
  149.   * @param boolean $include_directories   When TRUE, directories are
  150.   *                                        included (optional; default
  151.   *                                        DO include directories).
  152.   * @param boolean $directories_only      When TRUE, ONLY directories
  153.   *                                        are included (optional; default
  154.   *                                        is to include files too).
  155.   * @param boolean $separate_files_and_directories When TRUE, files and
  156.   *                                                 directories are returned
  157.   *                                                 in separate lists, so
  158.   *                                                 the return value is
  159.   *                                                 formatted as a two-element
  160.   *                                                 array with the two keys
  161.   *                                                 "FILES" and "DIRECTORIES",
  162.   *                                                 where corresponding values
  163.   *                                                 are lists of either all
  164.   *                                                 files or all directories
  165.   *                                                 (optional; default do not
  166.   *                                                 split up return array).
  167.   * @param boolean $only_sm               When TRUE, a security check will
  168.   *                                        limit directory access to only
  169.   *                                        paths within the SquirrelMail
  170.   *                                        installation currently being used
  171.   *                                        (optional; default TRUE)
  172.   *
  173.   * @return array The requested file/directory list(s).
  174.   *
  175.   * @since 1.5.2
  176.   *
  177.   */
  178. function list_files($directory_path$extensions=''$return_filenames_only=TRUE,
  179.                     $include_directories=TRUE$directories_only=FALSE,
  180.                     $separate_files_and_directories=FALSE$only_sm=TRUE{
  181.  
  182.     $files array();
  183.     $directories array();
  184.  
  185.  
  186.     // make sure requested path is under SM_PATH if needed
  187.     //
  188.     if ($only_sm{
  189.         if (strpos(realpath($directory_path)realpath(SM_PATH)) !== 0{
  190.             //plain_error_message(_("Illegal filesystem access was requested"));
  191.             echo _("Illegal filesystem access was requested");
  192.             exit;
  193.         }
  194.     }
  195.  
  196.  
  197.     // validate given directory
  198.     //
  199.     if (empty($directory_path)
  200.      || !is_dir($directory_path)
  201.      || !($DIR opendir($directory_path))) {
  202.         return $files;
  203.     }
  204.  
  205.  
  206.     // ensure extensions is an array and is properly formatted 
  207.     //
  208.     if (!empty($extensions)) {
  209.         if (!is_array($extensions))
  210.             $extensions explode(','$extensions);
  211.         $temp_extensions array();
  212.         foreach ($extensions as $ext)
  213.             $temp_extensions['.' trim(trim($ext)'.');
  214.         $extensions $temp_extensions;
  215.     else $extensions array();
  216.  
  217.  
  218.     $directory_path rtrim($directory_path'/');
  219.  
  220.  
  221.     // parse through the files
  222.     //
  223.     while (($file readdir($DIR)) !== false{
  224.  
  225.         if ($file == '.' || $file == '..'continue;
  226.  
  227.         if (!empty($extensions))
  228.             foreach ($extensions as $ext)
  229.                 if (strrpos($file$ext!== (strlen($filestrlen($ext)))
  230.                     continue 2;
  231.  
  232.         // only use is_dir() if we really need to (be as efficient as possible)
  233.         //
  234.         $is_dir FALSE;
  235.         if (!$include_directories || $directories_only
  236.                                   || $separate_files_and_directories{
  237.             if (is_dir($directory_path '/' $file)) {
  238.                 if (!$include_directoriescontinue;
  239.                 $is_dir TRUE;
  240.                 $directories[($return_filenames_only
  241.                                ? $file
  242.                                : $directory_path '/' $file);
  243.             }
  244.             if ($directories_onlycontinue;
  245.         }
  246.  
  247.         if (!$separate_files_and_directories
  248.          || ($separate_files_and_directories && !$is_dir)) {
  249.             $files[($return_filenames_only
  250.                      ? $file
  251.                      : $directory_path '/' $file);
  252.         }
  253.  
  254.     }
  255.     closedir($DIR);
  256.  
  257.  
  258.     if ($directories_onlyreturn $directories;
  259.     if ($separate_files_and_directoriesreturn array('FILES' => $files,
  260.                                                       'DIRECTORIES' => $directories);
  261.     return $files;
  262.  
  263. }
  264.  
  265.  
  266. /**
  267.  * Determine if there are lines in a file longer than a given length
  268.  *
  269.  * @param string $filename   The full file path of the file to inspect
  270.  * @param int    $max_length If any lines in the file are GREATER THAN
  271.  *                            this number, this function returns TRUE.
  272.  *
  273.  * @return boolean TRUE as explained above, otherwise, (no long lines
  274.  *                  found) FALSE is returned.
  275.  *
  276.  */
  277. function file_has_long_lines($filename$max_length{
  278.  
  279.     $FILE @fopen($filename'rb');
  280.  
  281.     if ($FILE{
  282.         while (!feof($FILE)) {
  283.             $buffer fgets($FILE4096);
  284.             if (strlen($buffer$max_length{
  285.                 fclose($FILE);
  286.                 return TRUE;
  287.             }
  288.         }
  289.         fclose($FILE);
  290.     }
  291.  
  292.     return FALSE;
  293. }

Documentation generated on Mon, 13 Jan 2020 04:22:28 +0100 by phpDocumentor 1.4.3