/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2010, Tomasz Sowa * All rights reserved. * */ #include #include #include "rm.h" #include "core/plugin.h" #include "core/misc.h" #include "templates/templates.h" namespace Fun { Rm::Rm() { fun.url = L"rm"; follow_symlinks = false; } bool Rm::HasAccess(const Item & item) { // !! temporarily (we're waiting for the sticky bit to be implemented) // not logged users cannot remove anything if( !request->session->puser ) return false; if( item.parent_id == -1 ) { // we can only remove the content of the root directory // and here we check only access the the root dir // "onlycontent" parameter should be check in post method if( !system->HasWriteAccess(item) ) return false; } else { Item * last_but_one_dir = system->dirs.GetDir(item.parent_id); if( !last_but_one_dir ) // ops, there is no a parent dir return false; if( !system->HasWriteAccess(*last_but_one_dir) ) return false; } if( system->mounts.pmount->IsPar(system->mounts.MountParOnlyRootRemove()) ) if( !request->session->puser || !request->session->puser->super_user ) return false; return true; } bool Rm::HasAccess() { if( !request->is_item ) return HasAccess(*request->dir_tab.back()); else return HasAccess(request->item); return true; } void Rm::Prepare() { content_dir_iq.SetAll(false, false); content_dir_iq.sel_parent_id = true; content_dir_iq.sel_type = true; content_dir_iq.sel_url = true; content_dir_iq.sel_file = true; static_iq.SetAll(false, false); static_iq.sel_parent_id = true; static_iq.sel_type = true; static_iq.sel_url = true; static_iq.sel_file = true; static_iq.WhereType(Item::file); static_iq.WhereFileType(WINIX_ITEM_FILETYPE_NONE, false); } bool Rm::RemoveStaticFile(const std::wstring & path) { if( ::RemoveFile(path) ) { log << log2 << "Rm: removed static file: " << path << logend; return true; } else { log << log1 << "Rm: can't remove a file: " << path << logend; request->status = WINIX_ERR_PERMISSION_DENIED; return false; } } void Rm::RemoveStaticFile(Item & item) { if( system->MakeFilePath(item, path, false) ) { if( RemoveStaticFile(path) ) { if( item.has_thumb && system->MakeFilePath(item, path, true) ) { RemoveStaticFile(path); item.has_thumb = false; } // we don't store it to db (it will be removed or is removed already) item.file_path.clear(); item.file_type = WINIX_ITEM_FILETYPE_NONE; } } else { request->status = WINIX_ERR_PERMISSION_DENIED; } } void Rm::RemoveFileOrSymlink(Item & item) { if( db->DelItem(item) == WINIX_ERR_OK ) { if( item.type == Item::file ) log << log2 << "Rm: deleted file "; else log << log2 << "Rm: deleted symlink "; log << item.url << logend; TemplatesFunctions::pattern_cacher.DeletePattern(item); plugin.Call(WINIX_FILE_REMOVED, item.id); // !! nie potrzebne //db->EditThreadRemoveItem(item.parent_id); if( item.file_type != WINIX_ITEM_FILETYPE_NONE ) RemoveStaticFile(item); } else { // request->status = WINIX_ERR_NO_ITEM; } } void Rm::RemoveDirTree(long dir_id) { DirContainer::ParentIterator pnext, p = system->dirs.FindFirstChild(dir_id); for( ; p != system->dirs.ParentEnd() ; p = pnext ) { // this iterator p will be deleted by the next DeleteDir(p->second->id) // (the next iterator we must calculate beforehand) pnext = system->dirs.NextChild(p); RemoveDirTree(p->second->id); } plugin.Call(WINIX_DIR_PREPARE_TO_REMOVE, dir_id); static_iq.WhereParentId(dir_id); db->GetItems(static_item_tab, static_iq); for(size_t i=0 ; iDelDirById(dir_id) == WINIX_ERR_OK ) { system->dirs.DelDir(dir_id); // !! nie potrzebne //db->RemoveThread(dir_id); plugin.Call(WINIX_DIR_REMOVED, dir_id); } } void Rm::RemoveDir(const Item & dir) { old_url = dir.url; RemoveDirTree(dir.id); if( request->status == WINIX_ERR_OK ) log << log3 << "Rm: removed directory " << old_url << logend; } void Rm::RemoveFile() { RemoveFileOrSymlink(request->item); if( request->status == WINIX_ERR_OK ) system->RedirectToLastDir(); } void Rm::RemoveDirContent() { if( !request->IsParam(L"r") ) { request->status = WINIX_ERR_PERMISSION_DENIED; return; } content_dir_iq.WhereParentId(request->dir_tab.back()->id); db->GetItems(item_tab, content_dir_iq); for(size_t i=0 ; istatus == WINIX_ERR_OK ) system->RedirectToLastDir(); } void Rm::RemoveDir() { if( !request->IsParam(L"r") || request->dir_tab.size() <= 1 ) { // we cannot remove the root directory (dir_tab.size()==1) request->status = WINIX_ERR_PERMISSION_DENIED; return; } RemoveDir(*request->dir_tab.back()); request->dir_tab.erase(--request->dir_tab.end()); if( request->status == WINIX_ERR_OK ) system->RedirectToLastDir(); } void Rm::Clear() { static_item_tab.clear(); item_tab.clear(); } void Rm::MakePost() { Prepare(); if( request->is_item ) { RemoveFile(); } else { if( request->IsPostVar(L"onlycontent") ) RemoveDirContent(); else RemoveDir(); } Clear(); } } // namespace