Version: 1.0 Release date: 08 July 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ class filesystem extends db { var $search_results = array(); var $disable_go_permissions = false; var $action_result = false; function filesystem($disable_go_permissions=false) { $this->db(); $this->disable_go_permissions = $disable_go_permissions; } function get_settings($user_id) { $this->query("SELECT * FROM fs_settings WHERE user_id='$user_id'"); if ($this->next_record()) { return $this->Record; }else { $this->query("INSERT INTO fs_settings (user_id, sort_field, sort_order) VALUES ('$user_id', 'basename', 'ASC')"); return $this->get_settings($user_id); } } function set_sorting($user_id, $sort_field, $sort_order) { $sql = "UPDATE fs_settings SET sort_field='$sort_field' , sort_order='$sort_order' WHERE user_id='$user_id'"; return $this->query($sql); } function is_sub_dir($sub_path, $parent_path) { if (strpos($sub_path, $parent_path) === false) { return false; }else { if (substr($sub_path, strlen($parent_path), 1) != '/') { return false; } } return true; } function is_home_path($user_id, $path) { global $GO_CONFIG, $GO_USERS; if ($user = $GO_USERS->get_user($user_id)) { $home_path = $GO_CONFIG->file_storage_path.$user['username']; if (dirname($path).basename($path) == dirname($home_path).basename($home_path)) { return true; } } return false; } function is_owner($user_id, $path) { global $GO_CONFIG, $GO_USERS; if ($user = $GO_USERS->get_user($user_id)) { $home_path = $GO_CONFIG->file_storage_path.$user['username']; if (strpos($path, $home_path) === 0) { return true; } } return false; } function get_shares($user_id) { //ORDER BY PATH important so higher order shares come first $sql = "SELECT * FROM fsShares WHERE user_id='$user_id' ORDER BY path ASC"; $this->query($sql); return $this->num_rows(); } function get_my_shares() { global $GO_SECURITY; $sql = "SELECT DISTINCT fsShares.user_id FROM fsShares INNER JOIN acl ". "ON (fsShares.acl_read=acl.acl_id OR fsShares.acl_write=acl.acl_id) ". "LEFT JOIN users_groups ON (acl.group_id=users_groups.group_id) ". "WHERE ((users_groups.user_id=".$GO_SECURITY->user_id." AND ". "acl.user_id=0) OR (acl.group_id=0 AND ". "acl.user_id=".$GO_SECURITY->user_id."))"; $this->query($sql); $list = array(); while ( $this->next_record() ) { $list[] = $this->f('user_id'); } return $list; } function get_authorized_sharers($user_id) { global $GO_SECURITY; $sql = "SELECT DISTINCT fsShares.user_id FROM fsShares, acl, users_groups WHERE (". "fsShares.acl_read = acl.acl_id OR fsShares.acl_write = acl.acl_id AND fsShares.user_id != ".$user_id. ") AND ( ( acl.group_id = users_groups.group_id AND users_groups.user_id = ".$user_id." AND acl.user_id = 0 ) OR (". "acl.group_id = 0 AND acl.user_id = ".$user_id." ) )"; $this->query($sql); return $this->num_rows(); } function add_share($user_id, $path) { $path = addslashes($path); global $GO_SECURITY; $acl_read = $GO_SECURITY->get_new_acl('read: '.$path); $acl_write = $GO_SECURITY->get_new_acl('write: '.$path); if($acl_read && $acl_write) { $sql = "INSERT INTO fsShares (user_id, path, acl_read, acl_write) VALUES ('$user_id', '$path', '$acl_read', '$acl_write')"; global $GO_CONFIG; if($GO_CONFIG->dav_switch) { global $GO_DAV; $GO_DAV->add_share($user_id, $path); } return $this->query($sql); }else { $GO_SECURITY->delete_acl($acl_read); $GO_SECURITY->delete_acl($acl_write); } return false; } function delete_share($path) { if ($share = $this->get_share($path)) { $path = addslashes($path); global $GO_SECURITY; $GO_SECURITY->delete_acl($share['acl_read']); $GO_SECURITY->delete_acl($share['acl_write']); $sql = "DELETE FROM fsShares WHERE path='$path'"; global $GO_CONFIG; if($GO_CONFIG->dav_switch) { global $GO_DAV; $GO_DAV->delete_share($path); } return $this->query($sql); } return false; } function update_share($old_path, $new_path) { $new_path = addslashes($new_path); $old_path = addslashes($old_path); $sql = "UPDATE fsShares SET path='$new_path' WHERE path='$old_path'"; global $GO_CONFIG; if($GO_CONFIG->dav_switch) { global $GO_DAV; $GO_DAV->update_share($old_path, $new_path); } return $this->query($sql); } function get_share($path) { $path = addslashes($path); $sql = "SELECT * FROM fsShares WHERE path='$path'"; $this->query($sql); if($this->next_record()) { return $this->Record; } return false; } function find_share($path) { if ($share = $this->get_share($path)) { return $share; }else { global $GO_CONFIG; $parent = dirname($path); if ($parent == $GO_CONFIG->file_storage_path || $parent == '' || $parent == $GO_CONFIG->slash) { return false; }else { return $this->find_share($parent); } } } function has_read_permission($user_id, $path) { global $GO_CONFIG; if ($this->disable_go_permissions || $this->is_owner($user_id, $path) || $path == $GO_CONFIG->file_storage_path) { return is_readable($path); }else { if ($share = $this->find_share($path)) { global $GO_SECURITY; if($GO_SECURITY->has_permission($user_id, $share['acl_read'])) { return is_readable($path); } } global $GO_CONFIG; if (strpos($path, $GO_CONFIG->tmpdir) === 0) { return is_readable($path); } } return false; } function has_write_permission($user_id, $path) { if ($this->disable_go_permissions || $this->is_owner($user_id, $path)) { return is_writable($path); }else { global $GO_SECURITY; if ($share = $this->find_share($path)) { if($GO_SECURITY->has_permission($user_id, $share['acl_write'])) { return is_writable($path); } } global $GO_CONFIG; if (strpos($path, $GO_CONFIG->tmpdir) === 0) { return is_writable($path); } } return false; } function size($path) { if (is_dir($path)) { $size = 0; $children = $this->get_folders($path); while ($child = array_shift($children)) { $size += $this->size($child['path']); } $files = $this->get_files($path); while ($file = array_shift($files)) { $size += $file['size']; } return $size; }else { return filesize($path); } } function move($source_path, $destination_path) { global $GO_CONFIG; //do not move into own path $source_dir_count = count(explode('/',$source_path)); $destination_dir_count = count(explode('/',$destination_path)); if ((strpos($destination_path, $source_path) === 0) && ($destination_dir_count > $source_dir_count)) { return false; }elseif($source_path == $destination_path) { return true; }else { if (is_dir($source_path)) { if (!file_exists($destination_path)) { if (!mkdir($destination_path, $GO_CONFIG->create_mode)) { return false; }else { if ($this->get_share($source_path)) { $this->update_share($source_path, $destination_path); } } } $files = $this->get_files($source_path, true); while ($file = array_shift($files)) { if(!$this->move($file['path'], $destination_path.'/'.$file['name'])) { return false; } } $children = $this->get_folders($source_path); while ($child = array_shift($children)) { if (!$this->move($child['path'], $destination_path.'/'.$child['name'])) { return false; }else { if ($this->get_share($child['path'])) { $this->update_share($child['path'], $destination_path.'/'.$child['name']); } } } //Here we have a little problem with WebDAV... Have to DELETE ALL files //and there are also hidden files in the folders... if($GO_CONFIG->dav_switch) { $cmd = "rm -rf $source_path"; `$cmd`; return true; } else { return rmdir($source_path); } }else { //rename fails when moving accross partitions //return rename($source_path, $destination_path); if (copy($source_path, $destination_path)) { return unlink($source_path); } } } } function copy($source_path, $destination_path) { global $GO_CONFIG; //do not copy into own path if (strpos($destination_path, $source_path) === 0) { // TODO add translation $this->action_result = "source and destination path are the same"; return false; }else { if (is_dir($source_path)) { if (!file_exists($destination_path)) { if (!mkdir($destination_path, $GO_CONFIG->create_mode)) { // TODO add translation $this->action_result = "unable to create destination path"; return false; } } $files = $this->get_files($source_path); while ($file = array_shift($files)) { if(!$this->copy($file['path'], $destination_path.'/'.$file['name'])) { // this->action_result is set by the call itself. return false; } } $children = $this->get_folders($source_path); while ($child = array_shift($children)) { if (!$this->copy($child['path'], $destination_path.'/'.$child['name'])) { // this->action_result is set by the call itself. return false; } } $this->action_result = true; return true; }else { // No directory. Check free space in destination_path. if ( $GO_CONFIG->user_quota != 0 ) { // get file size of $source_path filesize( $source_path ); // extract user-home-path from destination_path if ( strstr( $destination_path, $GO_CONFIG->file_storage_path ) ) { $dest = substr( $destination_path, strlen( $GO_CONFIG->file_storage_path ) ); $dest = substr( $dest, 0, strpos( $dest, "/" ) ); exec( "du ".$GO_CONFIG->file_storage_path.$dest." -s", $retval ); //MKS: Produced warning: //sscanf( $retval[0], "%d", &$usedspace ); //Changed to: list($usedspace) = sscanf( $retval[0], "%d"); if ( ( $usedspace*1024 + filesize( $source_path ) ) >= $GO_CONFIG->user_quota*1024 ) { // TODO add translation $this->action_result = "not enough space (over quota)"; return false; } } } return copy($source_path, $destination_path); } } } function delete($path) { global $GO_SECURITY; if (is_dir($path)) { $children = $this->get_folders($path); while ($child = array_shift($children)) { if (!$this->delete($child['path'])) { return false; } } $files = $this->get_files($path); while ($file = array_shift($files)) { if (!$this->delete($file['path'])) { return false; } } if ($this->disable_go_permissions || $this->has_write_permission($GO_SECURITY->user_id, $path)) { if (!$this->disable_go_permissions && $this->get_share($path)) { $this->delete_share($path); } global $GO_CONFIG; if($GO_CONFIG->dav_switch) { global $GO_DAV; if($GO_DAV->is_share($path)) $GO_DAV->delete_share($path); $cmd = "rm -rf $path/.*"; `$cmd`; } return @rmdir($path); }else { return false; } }else { if ($this->disable_go_permissions || $this->has_write_permission($GO_SECURITY->user_id, $path)) { return @unlink($path); }else { return false; } } } function get_parent_path($path) { $last_folder_pos = strrpos($path, '/'); if (is_integer($last_folder_pos)) { if ($last_folder_pos === 0) { return '/'; }else { return substr($path, 0, $last_folder_pos); } }else { return false; } } //faster then get_folders_sorted function get_folders($path) { global $GO_CONFIG; $slash = stristr(PHP_OS, 'Windows') ? '\\' : '/'; if (substr($path, -1) != $slash) $path .= $slash; $folders = array(); if($dir = opendir($path)) { while($item=readdir($dir)) { $folder_path = $path.$item; if (is_dir($folder_path) && $item != "." && $item != ".." && $item != $GO_CONFIG->name_of_sharedir && !(strpos($item,".") === 0) ) { $folder['path'] = $folder_path; $folder['name'] = basename($folder_path); $folder['mtime'] = filemtime($folder_path); $folder['size'] = filesize($folder_path); $folder['type'] = mime_content_type($folder_path); $folders[] = $folder; } } closedir($dir); } return $folders; } #returns all subfolders of a folder sorted based on the result of a function #passed that is performed on the pathname. (For example filesize();) function get_folders_sorted($path,$sort_field='basename',$sort_direction='ASC') { global $GO_CONFIG; $folders = array(); $slash = stristr(PHP_OS, 'Windows') ? '\\' : '/'; if (substr($path, -1) != $slash) $path .= $slash; if(strstr($path, $GO_CONFIG->root_path)) { $url = str_replace($GO_CONFIG->root_path, $GO_CONFIG->host, $path); if ($slash == '\\') { $url = str_replace('\\','/',$url); } } $sort_field = function_exists($sort_field) ? $sort_field : 'basename'; if (is_dir($path)) { $sorted_list = array(); if(@$dir = opendir($path)) { while($item=readdir($dir)) { $folder_path = $path.$item; if (is_dir($folder_path) && $item != "." && $item != ".." && $item != $GO_CONFIG->name_of_sharedir && !(strpos($item,".")===0) ) { $key_id = 0; $first_key = strtolower($sort_field($folder_path)); $key = $first_key; while (array_key_exists($key, $sorted_list)) { $key = $first_key.'_'.$key_id; $key_id++; } $sorted_list[$key] = $folder_path; } } closedir($dir); if ($sort_direction == 'ASC') { ksort($sorted_list); }else { krsort($sorted_list); } while ($item=array_shift($sorted_list)) { $folder = array(); $folder['path'] = $item; $folder['name'] = basename($item); $folder['mtime'] = filemtime($item); $folder['size'] = filesize($item); $folder['type'] = mime_content_type($item); if(isset($url)) { $folder['url'] = $url.$folder['name']; } $folders[] = $folder; } } } return $folders; } //faster then get_files_sorted function get_files($path, $move=false) { global $GO_CONFIG; $slash = stristr(PHP_OS, 'Windows') ? '\\' : '/'; if (substr($path, -1) != $slash) $path .= $slash; $files = array(); if($dir = @opendir($path)) { while($item=readdir($dir)) { $file_path = $path.$item; if (!is_dir($file_path) && $move) { $file['path'] = $file_path; $file['name'] = basename($file_path); $file['size'] = filesize($file_path); $file['mtime'] = filemtime($file_path); $file['type'] = mime_content_type($file_path); $files[] = $file; } if (!is_dir($file_path) && !$move && $item != $GO_CONFIG->name_of_sharedir && !(strpos($item,".") === 0) ) { $file['path'] = $file_path; $file['name'] = basename($file_path); $file['size'] = filesize($file_path); $file['mtime'] = filemtime($file_path); $file['type'] = mime_content_type($file_path); $files[] = $file; } } closedir($dir); } return $files; } #returns all subfolders of a folder sorted based on the result of a function #passed that is performed on the pathname. (For example filesize();) function get_files_sorted($path,$sort_field='basename',$sort_direction='ASC') { global $GO_CONFIG; $files = array(); $slash = stristr(PHP_OS, 'Windows') ? '\\' : '/'; if (substr($path, -1) != $slash) $path .= $slash; if(strstr($path, $GO_CONFIG->root_path)) { $url = str_replace($GO_CONFIG->root_path, $GO_CONFIG->host, $path); if ($slash == '\\') { $url = str_replace('\\','/',$url); } } $sort_field = function_exists($sort_field) ? $sort_field : 'basename'; if (is_dir($path)) { $sorted_list = array(); if($dir = @opendir($path)) { while($item=readdir($dir)) { $file = $path.$item; if (!is_dir($file) && $item != $GO_CONFIG->name_of_sharedir && !(strpos($item,".") === 0)) { $key_id = 0; $first_key = strtolower($sort_field($file)); $key = $first_key; while (array_key_exists($key, $sorted_list)) { $key = $first_key.'_'.$key_id; $key_id++; } $sorted_list[$key] = $file; } } closedir($dir); if ($sort_direction == 'ASC') { ksort($sorted_list); }else { krsort($sorted_list); } while ($item=array_shift($sorted_list)) { $file = array(); $file['path'] = $item; $file['name'] = basename($item); $file['mtime'] = filemtime($item); $file['size'] = filesize($item); $file['type'] = mime_content_type($item); if(isset($url)) { $file['url'] = $url.$file['name']; } $files[] = $file; } } } return $files; } function search($path, $keyword, $modified_later_then=0, $modified_earlier_then=0) { global $GO_SECURITY; if ($modified_earlier_then == 0) { $modified_earlier_then = time(); } if($this->has_read_permission($GO_SECURITY->user_id, $path)) { $folders = $this->get_folders($path); while ($folder = array_shift($folders)) { $this->search($folder['path'], $keyword, $modified_later_then, $modified_earlier_then); } $folder['path'] = $path; $folder['name'] = basename($path); $folder['mtime'] = filemtime($path); $folder['size'] = filesize($path); $folder['type'] = mime_content_type($path); if (stristr(basename($path), $keyword) && $modified_later_then < $folder['mtime'] && $modified_earlier_then > $folder['mtime']) { $this->search_results[] = $folder; } $files = $this->get_files($path); while ($file = array_shift($files)) { if (stristr($file['name'], $keyword) && $modified_later_then < $file['mtime'] && $modified_earlier_then > $file['mtime']) { $this->search_results[] = $file; } } } return $this->search_results; } function delete_user($user_id) { $fs = new filesystem(); $this->get_shares($user_id); while($this->next_record()) { $fs->delete_share($this->f('path')); } $this->query("DELETE FROM fs_settings WHERE user_id='$user_id'"); } } ?>