/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2010, Tomasz Sowa * All rights reserved. * */ #include #include "mv.h" #include "functions.h" namespace Fun { Mv::Mv() { fun.url = L"mv"; } bool Mv::MoveCheckAccessFromToDir() { Item * last; Item * last_but_one = 0; last = request->dir_tab[request->dir_tab.size()-1]; if( request->dir_tab.size() >= 2 ) last_but_one = request->dir_tab[request->dir_tab.size()-2]; if( request->method != Request::post ) { // used in GET or HEAD if( !system->HasWriteAccess(*last) && (!last_but_one || !system->HasWriteAccess(*last_but_one)) ) return false; } else { // used in POST when the moving is performed if( request->IsPostVar(L"onlycontent") ) return system->HasWriteAccess(*last); else if( last_but_one ) return system->HasWriteAccess(*last_but_one); else return false; // you cannot move the root directory } return true; } bool Mv::MoveCheckAccessFrom() { if( request->is_item ) { // moving a file if( !system->HasWriteAccess(*request->dir_tab.back()) ) { request->status = WINIX_ERR_PERMISSION_DENIED; return false; } } else { if( !MoveCheckAccessFromToDir() ) { request->status = WINIX_ERR_PERMISSION_DENIED; return false; } } return true; } bool Mv::MoveCheckAccessTo(long dir_id) { Item * pdir = system->dirs.GetDir(dir_id); if( !pdir ) { request->status = WINIX_ERR_INCORRECT_DIR; return false; } if( !system->HasReadExecAccessToPath(dir_id) || !system->HasWriteAccess(*pdir) ) { request->status = WINIX_ERR_PERMISSION_DENIED; return false; } return true; } bool Mv::MoveCheckMountPoints(long dir_id) { /* Mount * new_mount = system->mounts.CalcMount(dir_id); if( !new_mount ) { if( system->mounts.pmount->type != system->mounts.MountTypeCms() ) { request->status = WINIX_DIFFERENT_MOUNT_POINTS; return false; } return true; } if( new_mount->type != system->mounts.pmount->type ) { request->status = WINIX_DIFFERENT_MOUNT_POINTS; return false; } */ return true; } bool Mv::MoveParseDir(long & dir_id, std::wstring & dir, std::wstring & file) { int res = system->dirs.AnalyzePath(request->PostVar(L"to"), dir_id, dir, file); if( res == 1 ) request->status = WINIX_ERR_NO_ROOT_DIR; else if( res != 0 ) request->status = WINIX_ERR_INCORRECT_DIR; return res == 0; } void Mv::MoveAuth(Item & item) { if( !system->MakePath(item, mv_new_path, true) ) { request->status = WINIX_ERR_PERMISSION_DENIED; return; } if( RenameFile(item.auth_path, mv_new_path) ) { log << log1 << "Mv: moved static file from: " << item.auth_path << ", to: " << mv_new_path << logend; item.auth_path = mv_new_path; request->status = db->EditAuthById(item, item.id); } else { int err = errno; log << log1 << "Mv: can't move a file from: " << item.auth_path << ", to: " << mv_new_path << ", "; log.SystemErr(err); log << logend; request->status = WINIX_ERR_PERMISSION_DENIED; } } bool Mv::MoveIsTheSameFile(const Item & item) { if( mv_file.empty() ) { if( item.parent_id == mv_dir_id ) return true; // nothing to do } else { if( item.parent_id == mv_dir_id && item.url == mv_file ) return true; // nothing to do } return false; } void Mv::MoveFile(Item & item, bool redirect) { if( MoveIsTheSameFile(item) ) return; if( !mv_file.empty() ) { item.url = mv_file; functions->PrepareUrl(item); } item.parent_id = mv_dir_id; request->status = db->EditParentUrlById(item, item.id); if( request->status == WINIX_ERR_OK ) { log << log2 << "Mv: the file was moved to: " << mv_dir << item.url << logend; if( item.auth != Item::auth_none ) MoveAuth(item); if( redirect ) system->RedirectTo(item); } } void Mv::MoveContentOfDir() { DbItemQuery iq; iq.sel_parent_id = true; iq.sel_type = true; iq.sel_url = true; iq.sel_auth = true; iq.WhereParentId(request->dir_tab.back()->id); db->GetItems(request->item_tab, iq); for(size_t i=0 ; iitem_tab.size() ; ++i) { if( request->item_tab[i].type == Item::dir ) MoveDir(request->item_tab[i], false); else MoveFile(request->item_tab[i], false); } system->RedirectToLastDir(); } void Mv::MoveAuthPrepareQuery() { mv_auth_iq.SetAll(false, false); mv_auth_iq.sel_parent_id = true; mv_auth_iq.sel_type = true; mv_auth_iq.sel_url = true; mv_auth_iq.sel_auth = true; mv_auth_iq.WhereType(Item::file); mv_auth_iq.WhereAuth(Item::auth_none, false); } void Mv::MoveAuthContentOfDir(const Item & item) { DirContainer::ParentIterator i = system->dirs.FindFirstParent(item.id); // go through all directories for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextParent(i) ) MoveAuthContentOfDir(*(i->second)); mv_auth_iq.WhereParentId(item.id); // don't use request->item here (is used in MoveContentOfDir()) db->GetItems(mv_auth, mv_auth_iq); for(size_t i=0 ; idirs.HasParent(mv_dir_id, item.id) ) { log << log1 << "Mv: cannot move directory to inside it" << logend; request->status = WINIX_ERR_INCORRECT_DIR; return; } if( !system->dirs.ChangeParent(item.id, mv_dir_id) ) { request->status = WINIX_ERR_INCORRECT_DIR; return; } item.parent_id = mv_dir_id; if( !mv_file.empty() ) { item.url = mv_file; functions->PrepareUrl(item); } request->status = db->EditParentUrlById(item, item.id); if( request->status == WINIX_ERR_OK ) { log << log2 << "Mv: the directory was moved to: " << mv_dir << item.url << logend; MoveAuthContentOfDir(item); if( redirect ) system->RedirectToLastDir(); } } void Mv::MakePost() { if( MoveCheckAccessFrom() && MoveParseDir(mv_dir_id, mv_dir, mv_file) && MoveCheckAccessTo(mv_dir_id) && MoveCheckMountPoints(mv_dir_id) ) { if( request->is_item ) { MoveFile(request->item); } else { MoveAuthPrepareQuery(); if( request->IsPostVar(L"onlycontent") ) { if( mv_file.empty() ) MoveContentOfDir(); else request->status = WINIX_ERR_INCORRECT_DIR; } else { MoveDir(*request->dir_tab.back()); } } } } void Mv::MakeGet() { MoveCheckAccessFrom(); } } // namespace