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

Source for file smb.php

Documentation is available at smb.php

  1. <?php
  2. /**
  3.  * Stateless VFS implementation for a SMB server, based on smbclient.
  4.  *
  5.  * Required values for $params:
  6.  * <pre>
  7.  *   'username'  - The username with which to connect to the SMB server.
  8.  *   'password'  - The password with which to connect to the SMB server.
  9.  *   'hostspec'  - The SMB server to connect to.
  10.  *   'port'      - The SMB port number to connect to.
  11.  *   'share'     - The share to access on the SMB server.
  12.  *   'smbclient' - The path to the 'smbclient' executable.
  13.  * </pre>
  14.  *
  15.  * Optional values for $params:
  16.  * <pre>
  17.  *   'ipaddress' - The address of the server to connect to.
  18.  * </pre>
  19.  *
  20.  * Functions not implemented:
  21.  *   - changePermissions(): The SMB permission style does not fit with the
  22.  *                          module.
  23.  *
  24.  * $Horde: framework/VFS/lib/VFS/smb.php,v 1.1.2.5 2009/02/06 18:24:20 slusarz Exp $
  25.  *
  26.  * Codebase copyright 2002 Paul Gareau <paul@xhawk.net>.  Adapted with
  27.  * permission by Patrice Levesque <wayne@ptaff.ca> from phpsmb-0.8 code, and
  28.  * converted to the LGPL.  Please do not taunt original author, contact
  29.  * Patrice Levesque or dev@lists.horde.org.
  30.  *
  31.  * See the enclosed file COPYING for license information (LGPL). If you
  32.  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  33.  *
  34.  * @author  Paul Gareau <paul@xhawk.net>
  35.  * @author  Patrice Levesque <wayne@ptaff.ca>
  36.  * @since   Horde 3.1
  37.  * @package VFS
  38.  */
  39. class VFS_smb extends VFS {
  40.  
  41.     /**
  42.      * List of additional credentials required for this VFS backend.
  43.      *
  44.      * @var array 
  45.      */
  46.     var $_credentials = array('username''password');
  47.  
  48.     /**
  49.      * List of permissions and if they can be changed in this VFS backend.
  50.      *
  51.      * @var array 
  52.      */
  53.     var $_permissions = array(
  54.         'owner' => array('read' => false'write' => false'execute' => false),
  55.         'group' => array('read' => false'write' => false'execute' => false),
  56.         'all'   => array('read' => false'write' => false'execute' => false));
  57.  
  58.     /**
  59.      * Authenticates a user on the SMB server and share.
  60.      *
  61.      * @access private
  62.      *
  63.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  64.      */
  65.     function _connect()
  66.     {
  67.         $cmd = array('quit');
  68.         $err $this->_command(''$cmd);
  69.         if (is_a($err'PEAR_Error')) {
  70.             return PEAR::raiseError(_("Authentication to the SMB server failed."));
  71.         }
  72.         return true;
  73.     }
  74.  
  75.     /**
  76.      * Retrieves a file from the VFS.
  77.      *
  78.      * @param string $path  The pathname to the file.
  79.      * @param string $name  The filename to retrieve.
  80.      *
  81.      * @return string  The file data.
  82.      */
  83.     function read($path$name)
  84.     {
  85.         $file $this->readFile($path$name);
  86.         if (is_a($file'PEAR_Error')) {
  87.             return $file;
  88.         }
  89.  
  90.         $size filesize($file);
  91.         if ($size === 0{
  92.             return '';
  93.         }
  94.  
  95.         return file_get_contents($file);
  96.     }
  97.  
  98.     /**
  99.      * Retrieves a file from the VFS as an on-disk local file.
  100.      *
  101.      * This function provides a file on local disk with the data of a VFS file
  102.      * in it. This file <em>cannot</em> be modified! The behavior if you do
  103.      * modify it is undefined. It will be removed at the end of the request.
  104.      *
  105.      * @param string $path  The pathname to the file.
  106.      * @param string $name  The filename to retrieve.
  107.      *
  108.      * @return string A local filename.
  109.      */
  110.     function readFile($path$name)
  111.     {
  112.         // Create a temporary file and register it for deletion at the
  113.         // end of this request.
  114.         $localFile $this->_getTempFile();
  115.         if (!$localFile{
  116.             return PEAR::raiseError(_("Unable to create temporary file."));
  117.         }
  118.         register_shutdown_function(create_function('''unlink(\'' addslashes($localFile'\');'));
  119.  
  120.         list($path$name$this->_escapeShellCommand($path$name);
  121.         $cmd = array('get \"' $name '\" ' $localFile);
  122.         $result $this->_command($path$cmd);
  123.         if (is_a($result'PEAR_Error')) {
  124.             return $result;
  125.         }
  126.         if (!file_exists($localFile)) {
  127.             return PEAR::raiseError(sprintf(_("Unable to open VFS file \"%s\".")$this->_getPath($path$name)));
  128.         }
  129.  
  130.         return $localFile;
  131.     }
  132.  
  133.     /**
  134.      * Open a stream to a file in the VFS.
  135.      *
  136.      * @param string $path  The pathname to the file.
  137.      * @param string $name  The filename to retrieve.
  138.      *
  139.      * @return resource  The stream.
  140.      */
  141.     function readStream($path$name)
  142.     {
  143.         $file $this->readFile($path$name);
  144.         if (is_a($file'PEAR_Error')) {
  145.             return $file;
  146.         }
  147.  
  148.         $mode = OS_WINDOWS ? 'rb' 'r';
  149.         return fopen($file$mode);
  150.     }
  151.  
  152.     /**
  153.      * Stores a file in the VFS.
  154.      *
  155.      * @param string $path         The path to store the file in.
  156.      * @param string $name         The filename to use.
  157.      * @param string $tmpFile      The temporary file containing the data to be
  158.      *                              stored.
  159.      * @param boolean $autocreate  Automatically create directories?
  160.      *
  161.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  162.      */
  163.     function write($path$name$tmpFile$autocreate = false)
  164.     {
  165.         // Double quotes not allowed in SMB filename.
  166.         $name str_replace('"'"'"$name);
  167.  
  168.         list($path$name$this->_escapeShellCommand($path$name);
  169.         $cmd = array('put \"' $tmpFile '\" \"' $name '\"');
  170.         // do we need to first autocreate the directory?
  171.         if ($autocreate{
  172.             $result $this->autocreatePath($path);
  173.             if (is_a($result'PEAR_Error')) {
  174.                 return $result;
  175.             }
  176.         }
  177.         $err $this->_command($path$cmd);
  178.         if (is_a($err'PEAR_Error')) {
  179.             return $err;
  180.         }
  181.         return true;
  182.     }
  183.  
  184.     /**
  185.      * Stores a file in the VFS from raw data.
  186.      *
  187.      * @param string $path         The path to store the file in.
  188.      * @param string $name         The filename to use.
  189.      * @param string $data         The file data.
  190.      * @param boolean $autocreate  Automatically create directories?
  191.      *
  192.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  193.      */
  194.     function writeData($path$name$data$autocreate = false)
  195.     {
  196.         $tmpFile $this->_getTempFile();
  197.         $fp fopen($tmpFile'wb');
  198.         fwrite($fp$data);
  199.         fclose($fp);
  200.         $result $this->write($path$name$tmpFile$autocreate);
  201.         unlink($tmpFile);
  202.         return $result;
  203.     }
  204.  
  205.     /**
  206.      * Deletes a file from the VFS.
  207.      *
  208.      * @param string $path  The path to delete the file from.
  209.      * @param string $name  The filename to use.
  210.      *
  211.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  212.      */
  213.     function deleteFile($path$name)
  214.     {
  215.         // In some samba versions after samba-3.0.25-pre2, $path must
  216.         // end in a trailing slash.
  217.         if (substr($path-1!= '/'{
  218.             $path .= '/';
  219.         }
  220.  
  221.         list($path$name$this->_escapeShellCommand($path$name);
  222.         $cmd = array('del \"' $name '\"');
  223.         $err $this->_command($path$cmd);
  224.         if (is_a($err'PEAR_Error')) {
  225.             return $err;
  226.         }
  227.         return true;
  228.     }
  229.  
  230.     /**
  231.      * Checks if a given pathname is a folder.
  232.      *
  233.      * @param string $path  The path to the folder.
  234.      * @param string $name  The file or folder name.
  235.      *
  236.      * @return boolean  True if it is a folder, false otherwise.
  237.      */
  238.     function isFolder($path$name)
  239.     {
  240.         list($path$name$this->_escapeShellCommand($path$name);
  241.         $cmd = array('quit');
  242.         $err $this->_command($this->_getPath($path$name)$cmd);
  243.         if (is_a($err'PEAR_Error')) {
  244.             return false;
  245.         }
  246.         return true;
  247.     }
  248.  
  249.     /**
  250.      * Deletes a folder from the VFS.
  251.      *
  252.      * @param string $path        The path to delete the folder from.
  253.      * @param string $name        The name of the folder to delete.
  254.      * @param boolean $recursive  Force a recursive delete?
  255.      *
  256.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  257.      */
  258.     function deleteFolder($path$name$recursive = false)
  259.     {
  260.         // In some samba versions after samba-3.0.25-pre2, $path must
  261.         // end in a trailing slash.
  262.         if (substr($path-1!= '/'{
  263.             $path .= '/';
  264.         }
  265.  
  266.         if (!$this->isFolder($path$name)) {
  267.             return PEAR::raiseError(sprintf(_("\"%s\" is not a directory.")$path '/' $name));
  268.         }
  269.  
  270.         $file_list $this->listFolder($this->_getPath($path$name));
  271.         if (is_a($file_list'PEAR_Error')) {
  272.             return $file_list;
  273.         }
  274.  
  275.         if ($file_list && !$recursive{
  276.             return PEAR::raiseError(sprintf(_("Unable to delete \"%s\", the directory is not empty."),
  277.                                             $this->_getPath($path$name)));
  278.         }
  279.  
  280.         foreach ($file_list as $file{
  281.             if ($file['type'== '**dir'{
  282.                 $result $this->deleteFolder($this->_getPath($path$name)$file['name']$recursive);
  283.             else {
  284.                 $result $this->deleteFile($this->_getPath($path$name)$file['name']);
  285.             }
  286.             if (is_a($result'PEAR_Error')) {
  287.                 return $result;
  288.             }
  289.         }
  290.  
  291.         // Really delete the folder.
  292.         list($path$name$this->_escapeShellCommand($path$name);
  293.         $cmd = array('rmdir \"' $name '\"');
  294.         $err $this->_command($path$cmd);
  295.         if (is_a($err'PEAR_Error')) {
  296.             return PEAR::raiseError(sprintf(_("Unable to delete VFS folder \"%s\".")$this->_getPath($path$name)));
  297.         else {
  298.             return true;
  299.         }
  300.     }
  301.  
  302.     /**
  303.      * Renames a file in the VFS.
  304.      *
  305.      * @param string $oldpath  The old path to the file.
  306.      * @param string $oldname  The old filename.
  307.      * @param string $newpath  The new path of the file.
  308.      * @param string $newname  The new filename.
  309.      *
  310.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  311.      */
  312.     function rename($oldpath$oldname$newpath$newname)
  313.     {
  314.         if (is_a($result $this->autocreatePath($newpath)'PEAR_Error')) {
  315.             return $result;
  316.         }
  317.  
  318.         // Double quotes not allowed in SMB filename. The '/' character should
  319.         // also be removed from the beginning/end of the names.
  320.         $oldname str_replace('"'"'"trim($oldname'/'));
  321.         $newname str_replace('"'"'"trim($newname'/'));
  322.  
  323.         if (empty($oldname)) {
  324.             return PEAR::raiseError(_("Unable to rename VFS file to same name."));
  325.         }
  326.  
  327.         /* If the path was not empty (i.e. the path is not the root path),
  328.          * then add the trailing '/' character to path. */
  329.         if (!empty($oldpath)) {
  330.             $oldpath .= '/';
  331.         }
  332.         if (!empty($newpath)) {
  333.             $newpath .= '/';
  334.         }
  335.  
  336.         list($file$name$this->_escapeShellCommand($oldname$newname);
  337.         $cmd = array('rename \"' .  str_replace('/''\\\\'$oldpath$file '\" \"' .
  338.                                     str_replace('/''\\\\'$newpath$name '\"');
  339.         if (is_a($err $this->_command(''$cmd)'PEAR_Error')) {
  340.             return PEAR::raiseError(sprintf(_("Unable to rename VFS file \"%s\".")$this->_getPath($path$name)));
  341.         }
  342.  
  343.         return true;
  344.     }
  345.  
  346.     /**
  347.      * Creates a folder on the VFS.
  348.      *
  349.      * @param string $path  The path of directory to create folder.
  350.      * @param string $name  The name of the new folder.
  351.      *
  352.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  353.      */
  354.     function createFolder($path$name)
  355.     {
  356.         // In some samba versions after samba-3.0.25-pre2, $path must
  357.         // end in a trailing slash.
  358.         if (substr($path-1!= '/'{
  359.             $path .= '/';
  360.         }
  361.  
  362.         // Double quotes not allowed in SMB filename.
  363.         $name str_replace('"'"'"$name);
  364.  
  365.         list($dir$mkdir$this->_escapeShellCommand($path$name);
  366.         $cmd = array('mkdir \"' $mkdir '\"');
  367.         $err $this->_command($dir$cmd);
  368.         if (is_a($err'PEAR_Error')) {
  369.             return PEAR::raiseError(sprintf(_("Unable to create VFS folder \"%s\".")$this->_getPath($path$name)));
  370.         }
  371.         return true;
  372.     }
  373.  
  374.     /**
  375.      * Returns an unsorted file list.
  376.      *
  377.      * @param string $path       The path of the directory to get the file list
  378.      *                            for.
  379.      * @param mixed $filter      Hash of items to filter based on filename.
  380.      * @param boolean $dotfiles  Show dotfiles? This is irrelevant with
  381.      *                            smbclient.
  382.      * @param boolean $dironly   Show directories only?
  383.      *
  384.      * @return boolean|PEAR_Error File list on success or a PEAR_Error on
  385.      *                              failure.
  386.      */
  387.     function listFolder($path ''$filter = null$dotfiles = true$dironly = false)
  388.     {
  389.         list($path$this->_escapeShellCommand($path);
  390.         $cmd = array('ls');
  391.         $res $this->_command($path$cmd);
  392.         if (is_a($res'PEAR_Error')) {
  393.             return $res;
  394.         }
  395.         $num_lines count($res);
  396.         $files = array();
  397.         for ($r = 0; $r $num_lines$r++{
  398.             // Match file listing.
  399.             if (preg_match('/^(\s\s.+\s{6,})/'$res[$r])) {
  400.                 // Split into columns at every six spaces
  401.                 $split1 preg_split('/\s{6,}/'trim($res[$r]));
  402.                 // If the file name isn't . or ..
  403.                 if ($split1[0!= '.' && $split1[0!= '..'{
  404.                     if (isset($split1[2])) {
  405.                         // If there is a small file size, inf could be split
  406.                         // into 3 cols.
  407.                         $split1[1.= ' ' $split1[2];
  408.                     }
  409.                     // Split file inf at every one or more spaces.
  410.                     $split2 preg_split('/\s+/'$split1[1]);
  411.                     if (is_numeric($split2[0])) {
  412.                         // If there is no file attr, shift cols over.
  413.                         array_unshift($split2'');
  414.                     }
  415.                     $my_name $split1[0];
  416.  
  417.                     // Filter out dotfiles if they aren't wanted.
  418.                     if (!$dotfiles && substr($my_name01== '.'{
  419.                         continue;
  420.                     }
  421.  
  422.                     $my_size $split2[1];
  423.                     $ext_name explode('.'$my_name);
  424.  
  425.                     if ((strpos($split2[0]'D'!== false)) {
  426.                         $my_type '**dir';
  427.                         $my_size = -1;
  428.                     else {
  429.                         $my_type VFS::strtolower($ext_name[count($ext_name- 1]);
  430.                     }
  431.                     $my_date strtotime($split2[4' ' $split2[3' ' .
  432.                                          $split2[6' ' $split2[5]);
  433.                     $filedata = array('owner' => '',
  434.                                       'group' => '',
  435.                                       'perms' => '',
  436.                                       'name' => $my_name,
  437.                                       'type' => $my_type,
  438.                                       'date' => $my_date,
  439.                                       'size' => $my_size);
  440.                     // watch for filters and dironly
  441.                     if ($this->_filterMatch($filter$my_name)) {
  442.                         unset($file);
  443.                         continue;
  444.                     }
  445.                     if ($dironly && $my_type !== '**dir'{
  446.                         unset($file);
  447.                         continue;
  448.                     }
  449.  
  450.                     $files[$filedata['name']] $filedata;
  451.                 }
  452.             }
  453.         }
  454.         return $files;
  455.     }
  456.  
  457.     /**
  458.      * Returns a sorted list of folders in specified directory.
  459.      *
  460.      * @param string $path         The path of the directory to get the
  461.      *                              directory list for.
  462.      * @param mixed $filter        Hash of items to filter based on folderlist.
  463.      * @param boolean $dotfolders  Include dotfolders? Irrelevant for SMB.
  464.      *
  465.      * @return boolean|PEAR_Error Folder list on success or a PEAR_Error on
  466.      *                              failure.
  467.      */
  468.     function listFolders($path ''$filter = null$dotfolders = true)
  469.     {
  470.         $folders = array();
  471.         $folder = array();
  472.  
  473.         $folderList $this->listFolder($pathnull$dotfolderstrue);
  474.         if (is_a($folderList'PEAR_Error')) {
  475.             return $folderList;
  476.         }
  477.  
  478.         // dirname will strip last component from path, even on a directory
  479.         $folder['val'dirname($path);
  480.         $folder['abbrev''..';
  481.         $folder['label''..';
  482.  
  483.         $folders[$folder['val']] $folder;
  484.  
  485.         foreach ($folderList as $files{
  486.             $folder['val'$this->_getPath($path$files['name']);
  487.             $folder['abbrev'$files['name'];
  488.             $folder['label'$folder['val'];
  489.  
  490.             $folders[$folder['val']] $folder;
  491.         }
  492.  
  493.         ksort($folders);
  494.         return $folders;
  495.     }
  496.  
  497.     /**
  498.      * Copies a file through the backend.
  499.      *
  500.      * @param string $path         The path to store the file in.
  501.      * @param string $name         The filename to use.
  502.      * @param string $dest         The destination of the file.
  503.      * @param boolean $autocreate  Automatically create directories?
  504.      *
  505.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  506.      */
  507.     function copy($path$name$dest$autocreate = false)
  508.     {
  509.         $orig $this->_getPath($path$name);
  510.         if (preg_match('|^' preg_quote($orig'/?$|'$dest)) {
  511.             return PEAR::raiseError(_("Cannot copy file(s) - source and destination are the same."));
  512.         }
  513.  
  514.         if ($autocreate{
  515.             $result $this->autocreatePath($dest);
  516.             if (is_a($result'PEAR_Error')) {
  517.                 return $result;
  518.             }
  519.         }
  520.  
  521.         $fileCheck $this->listFolder($destnulltrue);
  522.         if (is_a($fileCheck'PEAR_Error')) {
  523.             return $fileCheck;
  524.         }
  525.         foreach ($fileCheck as $file{
  526.             if ($file['name'== $name{
  527.                 return PEAR::raiseError(sprintf(_("%s already exists."),
  528.                                                 $this->_getPath($dest$name)));
  529.             }
  530.         }
  531.  
  532.         if ($this->isFolder($path$name)) {
  533.             if (is_a($result $this->_copyRecursive($path$name$dest)'PEAR_Error')) {
  534.                 return $result;
  535.             }
  536.         else {
  537.             $tmpFile $this->readFile($path$name);
  538.             if (is_a($tmpFile'PEAR_Error')) {
  539.                 return PEAR::raiseError(sprintf(_("Failed to retrieve: %s")$orig));
  540.             }
  541.  
  542.             $result $this->write($dest$name$tmpFile);
  543.             if (is_a($result'PEAR_Error')) {
  544.                 return PEAR::raiseError(sprintf(_("Copy failed: %s"),
  545.                                                 $this->_getPath($dest$name)));
  546.             }
  547.         }
  548.  
  549.         return true;
  550.     }
  551.  
  552.     /**
  553.      * Moves a file through the backend.
  554.      *
  555.      * @param string $path         The path to store the file in.
  556.      * @param string $name         The filename to use.
  557.      * @param string $dest         The destination of the file.
  558.      * @param boolean $autocreate  Automatically create directories?
  559.      *
  560.      * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
  561.      */
  562.     function move($path$name$dest$autocreate = false)
  563.     {
  564.         $orig $this->_getPath($path$name);
  565.         if (preg_match('|^' preg_quote($orig'/?$|'$dest)) {
  566.             return PEAR::raiseError(_("Cannot move file(s) - destination is within source."));
  567.         }
  568.  
  569.         if ($autocreate{
  570.             $result $this->autocreatePath($dest);
  571.             if (is_a($result'PEAR_Error')) {
  572.                 return $result;
  573.             }
  574.         }
  575.  
  576.         $fileCheck $this->listFolder($destnulltrue);
  577.         if (is_a($fileCheck'PEAR_Error')) {
  578.             return $fileCheck;
  579.         }
  580.         foreach ($fileCheck as $file{
  581.             if ($file['name'== $name{
  582.                 return PEAR::raiseError(sprintf(_("%s already exists."),
  583.                                                 $this->_getPath($dest$name)));
  584.             }
  585.         }
  586.  
  587.         $err $this->rename($path$name$dest$name);
  588.         if (is_a($err'PEAR_Error')) {
  589.             return PEAR::raiseError(sprintf(_("Failed to move to \"%s\"."),
  590.                                             $this->_getPath($dest$name)));
  591.         }
  592.         return true;
  593.     }
  594.  
  595.     /**
  596.      * Replacement for escapeshellcmd(), variable length args, as we only want
  597.      * certain characters escaped.
  598.      *
  599.      * @access private
  600.      *
  601.      * @param array $array  Strings to escape.
  602.      *
  603.      * @return array 
  604.      */
  605.     function _escapeShellCommand()
  606.     {
  607.         $ret = array();
  608.         $args func_get_args();
  609.         foreach ($args as $arg{
  610.             $ret[str_replace(array(';''\\')array('\;''\\\\')$arg);
  611.         }
  612.         return $ret;
  613.     }
  614.  
  615.     /**
  616.      * Executes a command and returns output lines in array.
  617.      *
  618.      * @access private
  619.      *
  620.      * @param string $cmd  Command to be executed
  621.      *
  622.      * @return mixed  Array on success, false on failure.
  623.      */
  624.     function _execute($cmd)
  625.     {
  626.         $cmd str_replace('"-U%"''-N'$cmd);
  627.         exec($cmd$out$ret);
  628.  
  629.         // In some cases, (like trying to delete a nonexistant file),
  630.         // smbclient will return success (at least on 2.2.7 version I'm
  631.         // testing on). So try to match error strings, even after success.
  632.         if ($ret != 0{
  633.             $err '';
  634.             foreach ($out as $line{
  635.                 if (strpos($line'Usage:'=== 0{
  636.                     $err 'Command syntax incorrect';
  637.                     break;
  638.                 }
  639.                 if (strpos($line'ERRSRV'!== false ||
  640.                     strpos($line'ERRDOS'!== false{
  641.                     $err preg_replace('/.*\((.+)\).*/''\\1'$line);
  642.                     if (!$err{
  643.                         $err $line;
  644.                     }
  645.                     break;
  646.                 }
  647.             }
  648.             if (!$err{
  649.                 $err $out $out[count($out- 1$ret;
  650.             }
  651.             return PEAR::raiseError($err);
  652.         }
  653.  
  654.         // Check for errors even on success.
  655.         $err '';
  656.         foreach ($out as $line{
  657.             if (strpos($line'NT_STATUS_NO_SUCH_FILE'!== false ||
  658.                 strpos($line'NT_STATUS_OBJECT_NAME_NOT_FOUND'!== false{
  659.                 $err _("No such file");
  660.                 break;
  661.             elseif (strpos($line'NT_STATUS_ACCESS_DENIED'!== false{
  662.                 $err _("Permission Denied");
  663.                 break;
  664.             }
  665.         }
  666.  
  667.         if ($err{
  668.             return PEAR::raiseError($err);
  669.         }
  670.  
  671.         return $out;
  672.     }
  673.  
  674.     /**
  675.      * Executes SMB commands - without authentication - and returns output
  676.      * lines in array.
  677.      *
  678.      * @access private
  679.      *
  680.      * @param array $path  Base path for command.
  681.      * @param array $cmd   Commands to be executed.
  682.      *
  683.      * @return mixed  Array on success, false on failure.
  684.      */
  685.     function _command($path$cmd)
  686.     {
  687.         list($share$this->_escapeShellCommand($this->_params['share']);
  688.         putenv('PASSWD=' $this->_params['password']);
  689.         $ipoption (isset($this->_params['ipaddress'])) (' -I ' $this->_params['ipaddress']: null;
  690.         $fullcmd $this->_params['smbclient'.
  691.             ' "//' $this->_params['hostspec''/' $share '"' .
  692.             ' "-p' $this->_params['port''"' .
  693.             ' "-U' $this->_params['username''"' .
  694.             ' -D "' $path '" ' .
  695.             $ipoption .
  696.             ' -c "';
  697.         foreach ($cmd as $c{
  698.             $fullcmd .= $c ";";
  699.         }
  700.         $fullcmd .= '"';
  701.         return $this->_execute($fullcmd);
  702.     }
  703.  
  704. }

Documentation generated on Mon, 11 Mar 2019 15:34:55 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.