--- /dev/null
+<?php
+
+/**
+ *
+ * An alpha interface to samba browsing with the libsmb client.
+ *
+ *
+ */
+
+require_once 'File/Smb/Dir.php';
+
+class File_Smb extends File_Smb_Dir {
+
+
+ const FILE = 1;
+ const DIR = 2;
+ const SHARE = 4;
+
+
+
+
+ /**
+ * static map of server => [ user , pass ]
+ */
+ static $auth = array();
+
+ static $connection = array();
+
+ /**
+ * constructor
+ *
+ * @param: $con (string) - connection string: USER\\WORKGROUP%PASS@/SERVER/SHARE - we use unix paths here (converted to smb by lib.)
+ *
+ *
+ */
+
+
+ function __construct($con)
+ {
+
+ $lr = explode("@", $con);
+ $bits = explode("/", $lr[1]);
+ $this->server = $bits[0];
+ $this->path = $bits[1];
+ $this->name = $bits[1];
+ $this->type = self::DIR + self::SHARE;
+
+
+ $bb = explode('%', $lr[0]);
+ $u = $bb[0];
+ $ws = null;
+ $pass = $bb[1];
+ if (strpos('\\', $bb[0]) > -1) {
+ list($u,$ws) = explode("\\", $bb[0]);
+ }
+
+ $auth = File_Smb::$auth[$this->server] = array($ws, $u, $pass);
+
+ if (!isset(File_Smb::$connection[$this->server])) {
+ $con = File_Smb::$connection[$this->server] = smbclient_state_new();
+ //print_R(array('connect', $auth[0], $auth[1], $auth[2]));
+
+ smbclient_state_init($con , $auth[0], $auth[1], $auth[2]);
+ }
+
+
+ $this->resource = File_Smb::$connection[$this->server];
+
+
+ }
+
+ function ctorDir($path)
+ {
+ $p = substr($path, strlen($this->path)+1);
+ $ret = new File_Smb_Dir($this, $p, basename($p));
+
+ return $ret;
+ }
+
+
+
+}
--- /dev/null
+<?php
+
+
+
+class File_Smb_Dir {
+
+
+ var $server;
+ var $resource; // smblicent resource
+ var $path; // full path excluding server, including share.
+ var $type;
+ var $name;
+ var $namehash; // hash of name
+
+ var $perm_denied = false;
+ var $ino; //inode number ****
+ var $mode; //inode protection mode
+ var $nlink; //number of links
+ var $uid; //userid of owner *
+ var $gid; //groupid of owner *
+ var $rdev; //device type, if inode device
+ var $size; //size in bytes
+ var $atime; //time of last access (Unix timestamp)
+ var $mtime; //time of last modification (Unix timestamp)
+ var $ctime; //time of last inode change (Unix timestamp)
+ var $blksize; //blocksize of filesystem IO **
+ var $blocks;
+
+
+ var $created_dt;
+ var $updated_dt;
+ var $accessed_dt;
+
+
+ /**
+ * constructor
+ *
+ * @param: $dir File_Smb_Dir
+ * @param: string $sub - directory;
+ *
+ *
+ */
+
+
+ function __construct($dir, $sub, $base = false)
+ {
+
+
+ $this->server = $dir->server;
+ $this->path = $dir->path . '/' . $sub;
+ $this->name = $base === false ? $sub : $base; // for overriding ...
+ $this->namehash = sha1($this->name);
+ $this->type = File_Smb::DIR;
+ $this->resource = File_Smb::$connection[$this->server];
+ $this->stat();
+
+
+ }
+
+ function stat()
+ {
+ //if (!is_readable('smb://' . $this->server . '/'. $this->path
+ set_error_handler(function($errno, $errstr, $errfile, $errline) {
+ if (preg_match('/Permission denied/', $errstr)) {
+ $this->perm_denied = true;
+ return;
+ }
+
+ });
+
+ $ar = smbclient_stat($this->resource, 'smb://' . $this->server . '/'. $this->path);
+
+ restore_error_handler();
+ if ($ar == false) {
+ return;
+ }
+
+ foreach($ar as $k=>$v) {
+ if (!is_numeric($k)) {
+ $this->$k = $v;
+ }
+ }
+ if (isset($this->ctime)) {
+ $this->created_dt = date("Y-m-d H:i:s", $this->ctime);
+ }
+ if (isset($this->mtime)) {
+ $this->updated_dt = date("Y-m-d H:i:s", $this->mtime);
+ }
+ if (isset($this->atime)) {
+ $this->accessed_dt = date("Y-m-d H:i:s", $this->atime);
+ }
+ $acls = explode(',',smbclient_getxattr($this->resource, 'smb://' . $this->server . '/'. $this->path, 'system.nt_sec_desc.*+'));
+ $this->acls = array();
+ foreach($acls as $a) {
+ $aa = explode(":", $a);
+ if ($aa[0] == 'ACL') {
+ if (!in_array($aa[1], $this->acls)) {
+ $this->acls[] = $aa[1];
+ }
+
+ } else {
+ $this->{strtolower($aa[0])} = $aa[1];
+ }
+
+
+ }
+
+ }
+
+ /**
+ * return the list of files in a folder.
+ */
+
+ function dir()
+ {
+ require_once 'File/Smb/File.php';
+ set_error_handler(array($this, 'error_handler'));
+ // fixme - path compoenent should be uuencoded..
+ $dh = smbclient_opendir($this->resource, 'smb://' . $this->server . '/'. $this->path);
+ restore_error_handler();
+
+ if (!$dh) {
+ throw new Exception("Directory failed to open");
+ //return array();
+ }
+
+ $ret = array();
+
+ while (($e = smbclient_readdir($this->resource,$dh)) !== false) {
+ // print_R($e);
+ switch($e['type']) {
+
+ case 'file':
+ $ret[] = new File_Smb_File($this, $e['name']);
+ break;
+
+ case 'directory':
+ if ($e['name'] == '.' || $e['name'] == '..') {
+ break;
+ }
+ $ret[] = new File_Smb_Dir($this, $e['name']);
+ break;
+
+ case 'workgroup':
+ case 'server':
+ case 'file share':
+ case 'printer share':
+ case 'communication share':
+ case 'IPC share':
+ case 'link':
+ case 'unknown':
+ echo "Unknown share type?\n";
+ break;
+ }
+ }
+ //print_R($ret);exit;
+
+ return $ret;
+
+
+
+ }
+
+ function error_handler($errno, $errstr, $errfile, $errline) {
+ require_once 'File/Smb/Exception.php';
+ restore_error_handler();
+ switch($errno) {
+ case 2:
+ throw new File_Smb_ExceptionNotExist($errstr, $errno);
+ case 13:
+ throw new File_Smb_ExceptionPermDenied($errstr, $errno);
+
+ }
+
+
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+require_once 'File/Smb.php';
+
+class File_Smb_File extends File_Smb {
+
+
+ var $server;
+ var $resource; // smblicent resource
+ var $path; // full path excluding server, including share.
+ var $type;
+
+
+ /**
+ * constructor
+ *
+ * @param: $con (string) - connection string: USER\WORKGROUP@PASS/SERVER/SHARE - we use unix paths here (converted to smb by lib.)
+ *
+ *
+ */
+
+
+ function __construct($dir, $sub)
+ {
+
+
+ $this->server = $dir->server;
+ $this->path = $dir->path . '/' . $sub;
+ $this->name = $sub;
+ $this->namehash = sha1($this->name);
+ $this->type = File_Smb::FILE;
+ $this->resource = File_Smb::$connection[$this->server];
+ $this->stat();
+
+
+ }
+
+ function download($target)
+ {
+ $fh = smbclient_open( $this->resource, 'smb://' . $this->server . '/'. $this->path, 'r');
+ if ($fh === false) {
+ throw new Exception("SMB download : {$this->path} open Failed");
+ }
+ $fw = fopen($target, 'w');
+ if (!$fw) {
+ throw new Exception("SMB download: {$this->path} open write target Failed");
+ }
+ while (true) {
+ $str = smbclient_read($this->resource, $fh, 4096);
+ if (strlen($str) ==0 ) {
+ break;
+ }
+ fputs($fw,$str);
+ }
+ fclose($fw);
+ smbclient_close($this->resource, $fh);
+
+ }
+
+}
\ No newline at end of file