VFS
[ class tree: VFS ] [ index: VFS ] [ all elements ]

Source for file ftp.php

Documentation is available at ftp.php

  1. <?php
  2. /**
  3.  * VFS implementation for an FTP server.
  4.  *
  5.  * <pre>
  6.  * Required values for $params:
  7.  *      'username'       The username with which to connect to the ftp server.
  8.  *      'password'       The password with which to connect to the ftp server.
  9.  *      'hostspec'       The ftp server to connect to.
  10.  * Optional values for $params:
  11.  *      'pasv'           If true, connection will be set to passive mode.
  12.  *      'port'           The port used to connect to the ftp server if other
  13.  *                       than 21.
  14.  *      'ssl'            If true, and PHP had been compiled with OpenSSL
  15.  *                       support, TLS transport-level encryption will be
  16.  *                       negotiated with the server.
  17.  * </pre>
  18.  *
  19.  * $Horde: framework/VFS/VFS/ftp.php,v 1.80 2005/02/17 21:59:03 jan Exp $
  20.  *
  21.  * Copyright 2002-2005 Chuck Hagenbuch <chuck@horde.org>
  22.  * Copyright 2002-2005 Michael Varghese <mike.varghese@ascellatech.com>
  23.  *
  24.  * See the enclosed file COPYING for license information (LGPL). If you did
  25.  * not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  26.  *
  27.  * @author  Chuck Hagenbuch <chuck@horde.org>
  28.  * @author  Michael Varghese <mike.varghese@ascellatech.com>
  29.  * @since   Horde 2.2
  30.  * @package VFS
  31.  */
  32. class VFS_ftp extends VFS {
  33.  
  34.     /**
  35.      * List of additional credentials required for this VFS backend.
  36.      *
  37.      * @var array $_credentials 
  38.      */
  39.     var $_credentials = array('username''password');
  40.  
  41.     /**
  42.      * List of permissions and if they can be changed in this VFS backend.
  43.      *
  44.      * @var array $_permissions 
  45.      */
  46.     var $_permissions = array(
  47.         'owner' => array('read' => true'write' => true'execute' => true),
  48.         'group' => array('read' => true'write' => true'execute' => true),
  49.         'all'   => array('read' => true'write' => true'execute' => true));
  50.  
  51.     /**
  52.      * Variable holding the connection to the ftp server.
  53.      *
  54.      * @var resource $_stream 
  55.      */
  56.     var $_stream = false;
  57.  
  58.     /**
  59.      * Retrieves a file from the VFS.
  60.      *
  61.      * @access public
  62.      *
  63.      * @param string $path  The pathname to the file.
  64.      * @param string $name  The filename to retrieve.
  65.      *
  66.      * @return string  The file data.
  67.      */
  68.     function read($path$name)
  69.     {
  70.         $conn $this->_connect();
  71.         if (is_a($conn'PEAR_Error')) {
  72.             return $conn;
  73.         }
  74.  
  75.         $tmpFile $this->_getTempFile();
  76.         $fetch @ftp_get($this->_stream$tmpFile,
  77.                           $this->_getPath($path$name)FTP_BINARY);
  78.         if ($fetch === false{
  79.             return PEAR::raiseError(sprintf(_("Unable to open VFS file \"%s\".")$this->_getPath($path$name)));
  80.         }
  81.  
  82.         $size filesize($tmpFile);
  83.         if ($size === 0{
  84.             return '';
  85.         }
  86.  
  87.         if (OS_WINDOWS{
  88.             $mode 'rb';
  89.         else {
  90.             $mode 'r';
  91.         }
  92.         $fp fopen($tmpFile$mode);
  93.         $data fread($fp$size);
  94.         fclose($fp);
  95.         unlink($tmpFile);
  96.  
  97.         return $data;
  98.     }
  99.  
  100.     /**
  101.      * Stores a file in the VFS.
  102.      *
  103.      * @access public
  104.      *
  105.      * @param string $path         The path to store the file in.
  106.      * @param string $name         The filename to use.
  107.      * @param string $tmpFile      The temporary file containing the data to
  108.      *                              be stored.
  109.      * @param boolean $autocreate  Automatically create directories?
  110.      *
  111.      * @return mixed  True on success or a PEAR_Error object on failure.
  112.      */
  113.     function write($path$name$tmpFile$autocreate = false)
  114.     {
  115.         $conn $this->_connect();
  116.         if (is_a($conn'PEAR_Error')) {
  117.             return $conn;
  118.         }
  119.  
  120.         if (!@ftp_put($this->_stream$this->_getPath($path$name)$tmpFileFTP_BINARY)) {
  121.             if ($autocreate{
  122.                 $result $this->autocreatePath($path);
  123.                 if (is_a($result'PEAR_Error')) {
  124.                     return $result;
  125.                 }
  126.                 if (!@ftp_put($this->_stream$this->_getPath($path$name)$tmpFileFTP_BINARY)) {
  127.                     return PEAR::raiseError(sprintf(_("Unable to write VFS file \"%s\".")$this->_getPath($path$name)));
  128.                 }
  129.             else {
  130.                 return PEAR::raiseError(sprintf(_("Unable to write VFS file \"%s\".")$this->_getPath($path$name)));
  131.             }
  132.         }
  133.  
  134.         return true;
  135.     }
  136.  
  137.     /**
  138.      * Stores a file in the VFS from raw data.
  139.      *
  140.      * @access public
  141.      *
  142.      * @param string $path         The path to store the file in.
  143.      * @param string $name         The filename to use.
  144.      * @param string $data         The file data.
  145.      * @param boolean $autocreate  Automatically create directories?
  146.      *
  147.      * @return mixed  True on success or a PEAR_Error object on failure.
  148.      */
  149.     function writeData($path$name$data$autocreate = false)
  150.     {
  151.         $tmpFile $this->_getTempFile();
  152.         $fp fopen($tmpFile'wb');
  153.         fwrite($fp$data);
  154.         fclose($fp);
  155.  
  156.         $result $this->write($path$name$tmpFile$autocreate);
  157.         unlink($tmpFile);
  158.         return $result;
  159.     }
  160.  
  161.     /**
  162.      * Deletes a file from the VFS.
  163.      *
  164.      * @access public
  165.      *
  166.      * @param string $path  The path to delete the file from.
  167.      * @param string $name  The filename to delete.
  168.      *
  169.      * @return mixed  True on success or a PEAR_Error object on failure.
  170.      */
  171.     function deleteFile($path$name)
  172.     {
  173.         $conn $this->_connect();
  174.         if (is_a($conn'PEAR_Error')) {
  175.             return $conn;
  176.         }
  177.  
  178.         if (!@ftp_delete($this->_stream$this->_getPath($path$name))) {
  179.             return PEAR::raiseError(sprintf(_("Unable to delete VFS file \"%s\".")$this->_getPath($path$name)));
  180.         }
  181.  
  182.         return true;
  183.     }
  184.  
  185.     /**
  186.      * Checks if a given item is a folder.
  187.      *
  188.      * @access public
  189.      *
  190.      * @param string $path  The parent folder.
  191.      * @param string $name  The item name.
  192.      *
  193.      * @return boolean  True if it is a folder, false otherwise.
  194.      */
  195.     function isFolder($path$name)
  196.     {
  197.         $conn $this->_connect();
  198.         if (is_a($conn'PEAR_Error')) {
  199.             return $conn;
  200.         }
  201.  
  202.         $result = false;
  203.         $olddir $this->getCurrentDirectory();
  204.  
  205.         /* See if we can change to the given path. */
  206.         if (@ftp_chdir($this->_stream$this->_getPath($path$name))) {
  207.             $result = true;
  208.         }
  209.  
  210.         $this->_setPath($olddir);
  211.  
  212.         return $result;
  213.     }
  214.  
  215.     /**
  216.      * Deletes a folder from the VFS.
  217.      *
  218.      * @access public
  219.      *
  220.      * @param string $path        The parent folder.
  221.      * @param string $name        The name of the folder to delete.
  222.      * @param boolean $recursive  Force a recursive delete?
  223.      *
  224.      * @return mixed  True on success or a PEAR_Error object on failure.
  225.      */
  226.     function deleteFolder($path$name$recursive = false)
  227.     {
  228.         $conn $this->_connect();
  229.         if (is_a($conn'PEAR_Error')) {
  230.             return $conn;
  231.         }
  232.  
  233.         $isDir = false;
  234.         $dirCheck $this->listFolder($path);
  235.         foreach ($dirCheck as $file{
  236.             if ($file['name'== $name && $file['type'== '**dir'{
  237.                 $isDir = true;
  238.                 break;
  239.             }
  240.         }
  241.  
  242.         if ($isDir{
  243.             $file_list $this->listFolder($this->_getPath($path$name));
  244.             if (is_a($file_list'PEAR_Error')) {
  245.                 return $file_list;
  246.             }
  247.  
  248.             if (count($file_list&& !$recursive{
  249.                 return PEAR::raiseError(sprintf(_("Unable to delete \"%s\", the directory is not empty."),
  250.                                                 $this->_getPath($path$name)));
  251.             }
  252.  
  253.             foreach ($file_list as $file{
  254.                 if ($file['type'== '**dir'{
  255.                     $result $this->deleteFolder($this->_getPath($path$name)$file['name']$recursive);
  256.                 else {
  257.                     $result $this->deleteFile($this->_getPath($path$name)$file['name']);
  258.                 }
  259.                 if (is_a($result'PEAR_Error')) {
  260.                     return $result;
  261.                 }
  262.             }
  263.  
  264.             if (!@ftp_rmdir($this->_stream$this->_getPath($path$name))) {
  265.                 return PEAR::raiseError(sprintf(_("Cannot remove directory \"%s\".")$this->_getPath($path$name)));
  266.             }
  267.         else {
  268.             if (!@ftp_delete($this->_stream$this->_getPath($path$name))) {
  269.                 return PEAR::raiseError(sprintf(_("Cannot delete file \"%s\".")$this->_getPath($path$name)));
  270.             }
  271.         }
  272.  
  273.         return true;
  274.     }
  275.  
  276.     /**
  277.      * Renames a file in the VFS.
  278.      *
  279.      * @access public
  280.      *
  281.      * @param string $oldpath  The old path to the file.
  282.      * @param string $oldname  The old filename.
  283.      * @param string $newpath  The new path of the file.
  284.      * @param string $newname  The new filename.
  285.      *
  286.      * @return mixed  True on success or a PEAR_Error object on failure.
  287.      */
  288.     function rename($oldpath$oldname$newpath$newname)
  289.     {
  290.         $conn $this->_connect();
  291.         if (is_a($conn'PEAR_Error')) {
  292.             return $conn;
  293.         }
  294.  
  295.         if (!@ftp_rename($this->_stream$this->_getPath($oldpath$oldname)$this->_getPath($newpath$newname))) {
  296.             return PEAR::raiseError(sprintf(_("Unable to rename VFS file \"%s\".")$this->_getPath($oldpath$oldname)));
  297.         }
  298.  
  299.         return true;
  300.     }
  301.  
  302.     /**
  303.      * Creates a folder on the VFS.
  304.      *
  305.      * @access public
  306.      *
  307.      * @param string $path  The parent folder.
  308.      * @param string $name  The name of the new folder.
  309.      *
  310.      * @return mixed  True on success or a PEAR_Error object on failure.
  311.      */
  312.     function createFolder($path$name)
  313.     {
  314.         $conn $this->_connect();
  315.         if (is_a($conn'PEAR_Error')) {
  316.             return $conn;
  317.         }
  318.  
  319.         if (!@ftp_mkdir($this->_stream$this->_getPath($path$name))) {
  320.             return PEAR::raiseError(sprintf(_("Unable to create VFS directory \"%s\".")$this->_getPath($path$name)));
  321.         }
  322.  
  323.         return true;
  324.     }
  325.  
  326.     /**
  327.      * Changes permissions for an item on the VFS.
  328.      *
  329.      * @access public
  330.      * @abstract
  331.      *
  332.      * @param string $path        The parent folder of the item.
  333.      * @param string $name        The name of the item.
  334.      * @param string $permission  The permission to set.
  335.      *
  336.      * @return mixed  True on success or a PEAR_Error object on failure.
  337.      */
  338.     function changePermissions($path$name$permission)
  339.     {
  340.         $conn $this->_connect();
  341.         if (is_a($conn'PEAR_Error')) {
  342.             return $conn;
  343.         }
  344.  
  345.         if (!@ftp_site($this->_stream'CHMOD ' $permission ' ' $this->_getPath($path$name))) {
  346.             return PEAR::raiseError(sprintf(_("Unable to change permission for VFS file \"%s\".")$this->_getPath($path$name)));
  347.         }
  348.  
  349.         return true;
  350.     }
  351.  
  352.     /**
  353.      * Returns an an unsorted file list of the specified directory.
  354.      *
  355.      * @access public
  356.      * @abstract
  357.      *
  358.      * @param string $path       The path of the directory.
  359.      * @param mixed $filter      String/hash to filter file/dirname on.
  360.      * @param boolean $dotfiles  Show dotfiles?
  361.      * @param boolean $dironly   Show only directories?
  362.      *
  363.      * @return array  File list on success or PEAR_Error on failure.
  364.      */
  365.     function _listFolder($path ''$filter = null$dotfiles = true,
  366.                          $dironly = false)
  367.     {
  368.         $conn $this->_connect();
  369.         if (is_a($conn'PEAR_Error')) {
  370.             return $conn;
  371.         }
  372.  
  373.         $files = array();
  374.         $type VFS::strtolower(@ftp_systype($this->_stream));
  375.         if ($type == 'unknown'{
  376.             // Go with unix-style listings by default.
  377.             $type 'unix';
  378.         elseif (strpos($type'win'!== false{
  379.             $type 'win';
  380.         }
  381.  
  382.         $olddir $this->getCurrentDirectory();
  383.         if (!empty($path)) {
  384.             $res $this->_setPath($path);
  385.             if (is_a($res'PEAR_Error')) {
  386.                 return $res;
  387.             }
  388.         }
  389.  
  390.         if ($type == 'unix'{
  391.             // If we don't want dotfiles, We can save work here by not
  392.             // doing an ls -a and then not doing the check later (by
  393.             // setting $dotfiles to true, the if is short-circuited).
  394.             if ($dotfiles{
  395.                 $list ftp_rawlist($this->_stream'-al');
  396.                 $dotfiles = true;
  397.             else {
  398.                 $list ftp_rawlist($this->_stream'-l');
  399.             }
  400.         else {
  401.            $list ftp_rawlist($this->_stream'');
  402.         }
  403.  
  404.         if (!is_array($list)) {
  405.             if (isset($olddir)) {
  406.                 $res $this->_setPath($olddir);
  407.                 if (is_a($res'PEAR_Error')) {
  408.                     return $res;
  409.                 }
  410.             }
  411.             return array();
  412.         }
  413.  
  414.         foreach ($list as $line{
  415.             $file = array();
  416.             $item preg_split('/\s+/'$line);
  417.             if ($type == 'unix' || ($type == 'win' && !preg_match('|\d\d-\d\d-\d\d|'$item[0]))) {
  418.                 if (count($item< 8 || substr($line05== 'total'{
  419.                     continue;
  420.                 }
  421.                 $file['perms'$item[0];
  422.                 $file['owner'$item[2];
  423.                 $file['group'$item[3];
  424.                 $file['name'substr($linestrpos($linesprintf("%s %2s %5s"$item[5]$item[6]$item[7])) + 13);
  425.  
  426.                 // Filter out '.' and '..' entries.
  427.                 if (preg_match('/^\.\.?\/?$/'$file['name'])) {
  428.                     continue;
  429.                 }
  430.  
  431.                 // Filter out dotfiles if they aren't wanted.
  432.                 if (!$dotfiles && substr($file['name']01== '.'{
  433.                     continue;
  434.                 }
  435.  
  436.                 $p1 substr($file['perms']01);
  437.                 if ($p1 === 'l'{
  438.                     $file['link'substr($file['name']strpos($file['name']'->'+ 3);
  439.                     $file['name'substr($file['name']0strpos($file['name']'->'- 1);
  440.                     $file['type''**sym';
  441.  
  442.                    if ($this->isFolder(''$file['link'])) {
  443.                               $file['linktype''**dir';
  444.                                                     else {
  445.                                                     $parts explode('/'$file['link']);
  446.                                                     $name explode('.'array_pop($parts));
  447.                                                     if (count($name== 1 || ($name[0=== '' && count($name== 2)) {
  448.                                                         $file['linktype''**none';
  449.                                                         else {
  450.                                                             $file['linktype'VFS::strtolower(array_pop($name));
  451.                                                             }
  452.                                                                    }
  453.                 elseif ($p1 === 'd'{
  454.                     $file['type''**dir';
  455.                 else {
  456.                     $name explode('.'$file['name']);
  457.                     if (count($name== 1 || (substr($file['name']01=== '.' && count($name== 2)) {
  458.                         $file['type''**none';
  459.                     else {
  460.                         $file['type'VFS::strtolower($name[count($name- 1]);
  461.                     }
  462.                 }
  463.                 if ($file['type'== '**dir'{
  464.                     $file['size'= -1;
  465.                 else {
  466.                     $file['size'$item[4];
  467.                 }
  468.                 if (strpos($item[7]':'!== false{
  469.                     $file['date'strtotime($item[7':00' $item[5' ' $item[6' ' date('Y'time()));
  470.                     if ($file['date'time()) {
  471.                         $file['date'strtotime($item[7':00' $item[5' ' $item[6' ' (date('Y'time()) - 1));
  472.                     }
  473.                 else {
  474.                     $file['date'strtotime('00:00:00' $item[5' ' $item[6' ' $item[7]);
  475.                 }
  476.             else {
  477.                 /* Handle Windows FTP servers returning DOS-style file
  478.                  * listings. */
  479.                 $file['perms''';
  480.                 $file['owner''';
  481.                 $file['group''';
  482.                 $file['name'$item[3];
  483.                 $index = 4;
  484.                 while ($index count($item)) {
  485.                     $file['name'.= ' ' $item[$index];
  486.                     $index++;
  487.                 }
  488.                 $file['date'strtotime($item[0' ' $item[1]);
  489.                 if ($item[2== '<DIR>'{
  490.                     $file['type''**dir';
  491.                     $file['size'= -1;
  492.                 else {
  493.                     $file['size'$item[2];
  494.                     $name explode('.'$file['name']);
  495.                     if (count($name== 1 || (substr($file['name']01=== '.' && count($name== 2)) {
  496.                         $file['type''**none';
  497.                     else {
  498.                         $file['type'VFS::strtolower($name[count($name- 1]);
  499.                     }
  500.                 }
  501.             }
  502.  
  503.             // Filtering.
  504.             if ($this->_filterMatch($filter$file['name'])) {
  505.                 unset($file);
  506.                 continue;
  507.             }
  508.             if ($dironly && $file['type'!== '**dir'{
  509.                 unset($file);
  510.                 continue;
  511.             }
  512.  
  513.             $files[$file['name']] $file;
  514.             unset($file);
  515.         }
  516.  
  517.         if (isset($olddir)) {
  518.             $res $this->_setPath($olddir);
  519.             if (is_a($res'PEAR_Error')) {
  520.                 return $res;
  521.             }
  522.         }
  523.         return $files;
  524.     }
  525.  
  526.     /**
  527.      * Returns a sorted list of folders in the specified directory.
  528.      *
  529.      * @access public
  530.      * @abstract
  531.      *
  532.      * @param string $path         The path of the directory to get the
  533.      *                              directory list for.
  534.      * @param mixed $filter        Hash of items to filter based on folderlist.
  535.      * @param boolean $dotfolders  Include dotfolders?
  536.      *
  537.      * @return mixed  Folder list on success or a PEAR_Error object on failure.
  538.      */
  539.     function listFolders($path ''$filter = null$dotfolders = true)
  540.     {
  541.         $conn $this->_connect();
  542.         if (is_a($conn'PEAR_Error')) {
  543.             return $conn;
  544.         }
  545.  
  546.         $folders = array();
  547.         $folder = array();
  548.  
  549.         $folderList $this->listFolder($pathnull$dotfolderstrue);
  550.         if (is_a($folderList'PEAR_Error')) {
  551.             return $folderList;
  552.         }
  553.  
  554.         $folder['val'$this->_parentDir($path);
  555.         $folder['abbrev''..';
  556.         $folder['label''..';
  557.  
  558.         $folders[$folder['val']] $folder;
  559.  
  560.         foreach ($folderList as $files{
  561.             $folder['val'$this->_getPath($path$files['name']);
  562.             $folder['abbrev'$files['name'];
  563.             $folder['label'$folder['val'];
  564.  
  565.             $folders[$folder['val']] $folder;
  566.         }
  567.  
  568.         ksort($folders);
  569.         return $folders;
  570.     }
  571.  
  572.     /**
  573.      * Copies a file through the backend.
  574.      *
  575.      * @access public
  576.      *
  577.      * @param string $path  The path of the original file.
  578.      * @param string $name  The name of the original file.
  579.      * @param string $dest  The name of the destination directory.
  580.      *
  581.      * @return mixed  True on success or a PEAR_Error object on failure.
  582.      */
  583.     function copy($path$name$dest)
  584.     {
  585.         $conn $this->_connect();
  586.         if (is_a($conn'PEAR_Error')) {
  587.             return $conn;
  588.         }
  589.  
  590.         $fileCheck $this->listFolder($destnulltrue);
  591.         if (is_a($fileCheck'PEAR_Error')) {
  592.             return $fileCheck;
  593.         }
  594.         foreach ($fileCheck as $file{
  595.             if ($file['name'== $name{
  596.                 return PEAR::raiseError(sprintf(_("%s already exists.")$this->_getPath($dest$name)));
  597.             }
  598.         }
  599.  
  600.         $isDir = false;
  601.         $dirCheck $this->listFolder($pathnullfalse);
  602.         if (is_a($dirCheck'PEAR_Error')) {
  603.             return $dirCheck;
  604.         }
  605.         foreach ($dirCheck as $file{
  606.             if ($file['name'== $name && $file['type'== '**dir'{
  607.                 $isDir = true;
  608.                 break;
  609.             }
  610.         }
  611.  
  612.         if ($isDir{
  613.             $result $this->createFolder($dest$name);
  614.  
  615.             if (is_a($result'PEAR_Error')) {
  616.                 return $result;
  617.             }
  618.  
  619.             $file_list $this->listFolder($this->_getPath($path$name));
  620.             foreach ($file_list as $file{
  621.                 $result $this->copy($this->_getPath($path$name)$file['name']$this->_getPath($dest$name));
  622.                 if (is_a($result'PEAR_Error')) {
  623.                     return $result;
  624.                 }
  625.             }
  626.         else {
  627.             $tmpFile $this->_getTempFile();
  628.             $fetch @ftp_get($this->_stream$tmpFile$this->_getPath($path$name)FTP_BINARY);
  629.             if (!$fetch{
  630.                 unlink($tmpFile);
  631.                 return PEAR::raiseError(sprintf(_("Failed to copy from \"%s\".")$this->_getPath($path$name)));
  632.             }
  633.  
  634.             if (!@ftp_put($this->_stream$this->_getPath($dest$name)$tmpFileFTP_BINARY)) {
  635.                 unlink($tmpFile);
  636.                 return PEAR::raiseError(sprintf(_("Failed to copy to \"%s\".")$this->_getPath($dest$name)));
  637.             }
  638.  
  639.             unlink($tmpFile);
  640.         }
  641.  
  642.         return true;
  643.     }
  644.  
  645.     /**
  646.      * Moves a file through the backend.
  647.      *
  648.      * @access public
  649.      *
  650.      * @param string $path  The path of the original file.
  651.      * @param string $name  The name of the original file.
  652.      * @param string $dest  The destination file name.
  653.      *
  654.      * @return mixed  True on success or a PEAR_Error object on failure.
  655.      */
  656.     function move($path$name$dest)
  657.     {
  658.         $conn $this->_connect();
  659.         if (is_a($conn'PEAR_Error')) {
  660.             return $conn;
  661.         }
  662.  
  663.         $fileCheck $this->listFolder($destnulltrue);
  664.         foreach ($fileCheck as $file{
  665.             if ($file['name'== $name{
  666.                 return PEAR::raiseError(sprintf(_("%s already exists.")$this->_getPath($dest$name)));
  667.             }
  668.         }
  669.  
  670.         if (!@ftp_rename($this->_stream$this->_getPath($path$name)$this->_getPath($dest$name))) {
  671.             return PEAR::raiseError(sprintf(_("Failed to move to \"%s\".")$this->_getPath($dest$name)));
  672.         }
  673.  
  674.         return true;
  675.     }
  676.  
  677.     /**
  678.      * Returns the current working directory on the FTP server.
  679.      *
  680.      * @access public
  681.      *
  682.      * @return string  The current working directory.
  683.      */
  684.     function getCurrentDirectory()
  685.     {
  686.         if (is_a($connected $this->_connect()'PEAR_Error')) {
  687.             return $connected;
  688.         }
  689.         return ftp_pwd($this->_stream);
  690.     }
  691.  
  692.     /**
  693.      * Changes the current directory on the server.
  694.      *
  695.      * @access private
  696.      *
  697.      * @param string $path  The path to change to.
  698.      *
  699.      * @return mixed  True on success, or a PEAR_Error on failure.
  700.      */
  701.     function _setPath($path)
  702.     {
  703.         if (!@ftp_chdir($this->_stream$path)) {
  704.             return PEAR::raiseError(sprintf(_("Unable to change to %s.")$path));
  705.         }
  706.         return true;
  707.     }
  708.  
  709.     /**
  710.      * Returns the full path of an item.
  711.      *
  712.      * @access private
  713.      *
  714.      * @param string $path  The directory of the item.
  715.      * @param string $name  The name of the item.
  716.      *
  717.      * @return mixed  Full path to the file when $path is not empty and just
  718.      *                 $name when not set.
  719.      */
  720.     function _getPath($path$name)
  721.     {
  722.         if ($path !== ''{
  723.              return ($path '/' $name);
  724.         }
  725.         return ($name);
  726.     }
  727.  
  728.     /**
  729.      * Returns the parent directory of the specified path.
  730.      *
  731.      * @access private
  732.      *
  733.      * @param string $path  The path to get the parent of.
  734.      *
  735.      * @return string  The parent directory (string) on success or a PEAR_Error
  736.      *                  object on failure.
  737.      */
  738.     function _parentDir($path)
  739.     {
  740.         $conn $this->_connect();
  741.         if (is_a($conn'PEAR_Error')) {
  742.             return $conn;
  743.         }
  744.  
  745.         $olddir $this->getCurrentDirectory();
  746.         @ftp_cdup($this->_stream);
  747.  
  748.         $parent $this->getCurrentDirectory();
  749.         $this->_setPath($olddir);
  750.  
  751.         if (!$parent{
  752.             return PEAR::raiseError(_("Unable to determine current directory."));
  753.         }
  754.  
  755.         return $parent;
  756.     }
  757.  
  758.     /**
  759.      * Attempts to open a connection to the FTP server.
  760.      *
  761.      * @access private
  762.      *
  763.      * @return mixed  True on success or a PEAR_Error object on failure.
  764.      */
  765.     function _connect()
  766.     {
  767.         if ($this->_stream === false{
  768.             if (!extension_loaded('ftp')) {
  769.                 return PEAR::raiseError(_("The FTP extension is not available."));
  770.             }
  771.  
  772.             if (!is_array($this->_params)) {
  773.                 return PEAR::raiseError(_("No configuration information specified for FTP VFS."));
  774.             }
  775.  
  776.             $required = array('hostspec''username''password');
  777.             foreach ($required as $val{
  778.                 if (!isset($this->_params[$val])) {
  779.                     return PEAR::raiseError(sprintf(_("Required '%s' not specified in VFS configuration.")$val));
  780.                 }
  781.             }
  782.  
  783.             /* Connect to the ftp server using the supplied parameters. */
  784.             if (!empty($this->_params['ssl'])) {
  785.                 if (function_exists('ftp_ssl_connect')) {
  786.                     $this->_stream @ftp_ssl_connect($this->_params['hostspec']$this->_params['port']);
  787.                 else {
  788.                     return PEAR::raiseError(_("Unable to connect with SSL."));
  789.                 }
  790.             else {
  791.                 $this->_stream @ftp_connect($this->_params['hostspec']$this->_params['port']);
  792.             }
  793.             if (!$this->_stream{
  794.                 return PEAR::raiseError(_("Connection to FTP server failed."));
  795.             }
  796.  
  797.             $connected @ftp_login($this->_stream$this->_params['username']$this->_params['password']);
  798.             if (!$connected{
  799.                 $this->_disconnect();
  800.                 return PEAR::raiseError(_("Authentication to FTP server failed."));
  801.             }
  802.  
  803.             if (!empty($this->_params['pasv'])) {
  804.                 @ftp_pasv($this->_streamtrue);
  805.             }
  806.         }
  807.  
  808.         return true;
  809.     }
  810.  
  811.     /**
  812.      * Disconnects from the FTP server and cleans up the connection.
  813.      *
  814.      * @access private
  815.      */
  816.     function _disconnect()
  817.     {
  818.         @ftp_quit($this->_stream);
  819.         $this->_stream = false;
  820.     }
  821.  
  822.     /**
  823.      * Determines the location of the system temporary directory.  If a
  824.      * specific setting cannot be found, it defaults to /tmp
  825.      *
  826.      * @access private
  827.      *
  828.      * @return string  A directory name which can be used for temp files.
  829.      *                  Returns false if one could not be found.
  830.      */
  831.     function _getTempDir()
  832.     {
  833.         $tmp_locations = array('/tmp''/var/tmp''c:\WUTemp''c:\temp''c:\windows\temp''c:\winnt\temp');
  834.  
  835.         /* Try PHP's upload_tmp_dir directive. */
  836.         $tmp ini_get('upload_tmp_dir');
  837.  
  838.         /* Otherwise, try to determine the TMPDIR environment variable. */
  839.         if (empty($tmp)) {
  840.             $tmp getenv('TMPDIR');
  841.         }
  842.  
  843.         /* If we still cannot determine a value, then cycle through a list of
  844.          * preset possibilities. */
  845.         while (empty($tmp&& sizeof($tmp_locations)) {
  846.             $tmp_check array_shift($tmp_locations);
  847.             if (@is_dir($tmp_check)) {
  848.                 $tmp $tmp_check;
  849.             }
  850.         }
  851.  
  852.         /* If it is still empty, we have failed, so return false; otherwise
  853.          * return the directory determined. */
  854.         return empty($tmp? false : $tmp;
  855.     }
  856.  
  857.     /**
  858.      * Creates a temporary file.
  859.      *
  860.      * @access private
  861.      *
  862.      * @return string  Returns the full path-name to the temporary file.
  863.      *                  Returns false if a temp file could not be created.
  864.      */
  865.     function _getTempFile()
  866.     {
  867.         $tmp_dir $this->_getTempDir();
  868.         if (empty($tmp_dir)) {
  869.             return false;
  870.         }
  871.  
  872.         $tmp_file tempnam($tmp_dir'vfs');
  873.  
  874.         /* If the file was created, then register it for deleton and return */
  875.         if (empty($tmp_file)) {
  876.             return false;
  877.         else {
  878.             return $tmp_file;
  879.         }
  880.     }
  881.  
  882. }

Documentation generated on Mon, 11 Mar 2019 14:31:25 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.