uri; } function uri_str() { return unparse_uri($this->uri); } function file_name() { return NULL; } function last_modification_time() { return $this->last_modification_time; } function is_read_only() { return TRUE; } function __construct($uri) { $this->uri = $uri; } function open() { $this->last_modification_time = time(); } function close() {} function content() { return @file_get_contents($this->uri_str()); } function write($str) {} } class NetResource extends Resource { function __construct($uri) { parent::__construct($uri); } } class ExeResource extends Resource { private $command; private $work_directory; function __construct($uri, $work_directory) { parent::__construct($uri); $this->command = $uri['path']; $this->work_directory = $work_directory; } function content() { $content = array(); $old_cwd = getcwd(); if ($old_cwd === FALSE) { throw new ResourceOpenException ('Cannot get current working directory'); } if (chdir($this->work_directory) === FALSE) { throw new ResourceOpenException ('Cannot change current working directory to "'. $this->work_directory.'"'); } exec($this->command, $content, $result); if (chdir($old_cwd) === FALSE) { throw new ResourceOpenException ('Cannot reset current working directory to "'.$old_cwd.'"'); } if ($result !== 0) { throw new ResourceOpenException ('Executing "'.$this->command.'" returned error '.$result); } return implode($content, "\n"); } } class FileResource extends Resource { private $file_name; private $read_write; private $fd = FALSE; private $is_read_only; private $is_truncated = FALSE; # Getters function file_name() { return $this->file_name; } function is_read_only() { return $this->is_read_only; } function __construct($uri, $file_name, $read_write) { parent::__construct($uri); $this->file_name = $file_name; $this->read_write = $read_write; $this->open(); } function __destruct() { if ($this->fd !== FALSE) { $this->close(); } } function open() { if (!is_file($this->file_name)) { throw new ResourceOpenException('"'.$this->file_name.'" is not a file'); } if ($this->read_write) { $this->fd = @fopen($this->file_name, 'r+'); if ($this->fd !== FALSE) { if (@flock($this->fd, LOCK_EX) === FALSE) { throw new ResourceOpenException ('Error locking file "'.$this->file_name.'"'); } $this->is_read_only = FALSE; } } if ($this->fd === FALSE) { $this->fd = @fopen($this->file_name, 'r'); if ($this->fd === FALSE) { throw new ResourceOpenException ('Error opening file "'.$this->file_name.'"'); } $this->is_read_only = TRUE; } $file_stat = @fstat($this->fd); if ($file_stat === FALSE) { throw new ResourceOpenException ('Error in fstat('.$this->fd.') for file "'. $this->file_name.'"'); } $this->last_modification_time = $file_stat['mtime']; } function content() { $content = @fread($this->fd, MAX_FILE_SIZE); if (!@feof($this->fd)) { throw new ResourceLoadException ('File '.$this->file_name.' too big (>'. MAX_FILE_SIZE.' bytes)'); } if ($this->is_read_only) { $this->close(); } return $content; } function write($str) { if (!$this->is_truncated) { if (@fseek($this->fd, 0) !== 0) { return FALSE; } if (@ftruncate($this->fd, 0) === FALSE) { return FALSE; } $this->is_truncated = TRUE; } return @fwrite($this->fd, $str) !== -1; } function close() { $res = @fclose($this->fd); if ($res) { $this->fd = FALSE; } return $res; } } function resource_factory($uri, $work_directory, $read_write) { switch ($uri['scheme']) { case 'file': if (!ENABLE_FILE_URI) { throw new ResourceUriException ('URI scheme "file" not allowed'); } $file_name = $uri['path']; if ($read_write && !str_end_with($file_name, W2ML_SUFFIX)) { throw new ResourceUriException ('Invalid W2ML file name suffix: "'.$file_name.'"'); } return new FileResource($uri, $file_name, $read_write); case 'site': $file_name = site_uri_to_file_name($uri); if (!is_string($file_name)) { throw new ResourcePathException ('Error converting URI "'.unparse_uri($uri). '" to file name in '.REAL_W2ML_DOC_ROOT); } if ($read_write && !str_end_with($file_name, W2ML_SUFFIX)) { throw new ResourceUriException ('Invalid W2ML file name suffix: "'.$file_name.'"'); } return new FileResource($uri, $file_name, $read_write); case 'http': if (!ENABLE_HTTP_URI) { throw new ResourceUriException ('URI scheme "http" not allowed'); } return new NetResource($uri); case 'exe': if (!ENABLE_EXE_URI) { throw new ResourceUriException ('URI scheme "exe" not allowed'); } return new ExeResource($uri, $work_directory); case NULL: throw new ResourceUriException ('Bad URI: "'.$this->uri_str().'"'); default: throw new ResourceUriException ('Unsupported URI scheme "'.$this->uri['scheme']. '" in "'.$this->uri.'"'); } } ?>