we can create links (hard links, symbolic links) now
added winix functions: ln winix function 'default' can be used without redirecting now added new tickets types: TypeProgress, TypeString, TypeMultistring, TypeImages, TypeFiles now tickets are combined with files added winix functions: showtickets fixed mountpoints: when the default root mount was created its parameter table was empty and it caused accessing to a non-existing objects fixed logger: modifiers (log1, log2, log3) were incorrectly treated added modifier: log4 (debug info) now we are moving threads to a new plugin 'thread' created directory: plugins/thread (not finished yet) git-svn-id: svn://ttmath.org/publicrep/winix/trunk@704 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
425
functions/mv.cpp
425
functions/mv.cpp
@@ -18,25 +18,38 @@ namespace Fun
|
||||
Mv::Mv()
|
||||
{
|
||||
fun.url = L"mv";
|
||||
follow_symlinks = false;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::MoveCheckAccessFromToDir()
|
||||
bool Mv::HasAccess()
|
||||
{
|
||||
return CheckAccessFrom();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Mv::CheckAccessFromToDir()
|
||||
{
|
||||
Item * last;
|
||||
Item * last_but_one = 0;
|
||||
size_t dir_tab_size;
|
||||
|
||||
last = request->dir_tab[request->dir_tab.size()-1];
|
||||
last = request->dir_tab.back();
|
||||
dir_tab_size = request->dir_tab.size();
|
||||
|
||||
if( request->dir_tab.size() >= 2 )
|
||||
last_but_one = request->dir_tab[request->dir_tab.size()-2];
|
||||
if( dir_tab_size <= 1 )
|
||||
return false; // you cannot move the root directory
|
||||
|
||||
last_but_one = request->dir_tab[dir_tab_size - 2];
|
||||
|
||||
if( request->method != Request::post )
|
||||
{
|
||||
// used in GET or HEAD
|
||||
// we don't now whether we move the last directory or the last but one
|
||||
// it depends on the 'onlycontent' parameter
|
||||
|
||||
if( !system->HasWriteAccess(*last) &&
|
||||
(!last_but_one || !system->HasWriteAccess(*last_but_one)) )
|
||||
if( !system->HasWriteAccess(*last) && !system->HasWriteAccess(*last_but_one) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -46,10 +59,7 @@ Item * last_but_one = 0;
|
||||
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;
|
||||
@@ -57,7 +67,8 @@ return true;
|
||||
|
||||
|
||||
|
||||
bool Mv::MoveCheckAccessFrom()
|
||||
|
||||
bool Mv::CheckAccessFrom()
|
||||
{
|
||||
if( request->is_item )
|
||||
{
|
||||
@@ -71,7 +82,7 @@ bool Mv::MoveCheckAccessFrom()
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !MoveCheckAccessFromToDir() )
|
||||
if( !CheckAccessFromToDir() )
|
||||
{
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
return false;
|
||||
@@ -82,17 +93,11 @@ return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::MoveCheckAccessTo(long dir_id)
|
||||
bool Mv::CheckAccessTo()
|
||||
{
|
||||
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) )
|
||||
if( dir_tab.empty() ||
|
||||
!system->HasReadExecAccessToPath(dir_tab) ||
|
||||
!system->HasWriteAccess(*dir_tab.back()) )
|
||||
{
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
return false;
|
||||
@@ -103,85 +108,222 @@ return true;
|
||||
|
||||
|
||||
|
||||
bool Mv::MoveCheckMountPoints(long dir_id)
|
||||
|
||||
|
||||
bool Mv::ParseDir()
|
||||
{
|
||||
/*
|
||||
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;
|
||||
}
|
||||
const std::wstring & new_dir = request->PostVar(L"to");
|
||||
int res = system->dirs.FollowLink(request->dir_tab, new_dir, dir_tab, file);
|
||||
|
||||
return true;
|
||||
}
|
||||
if( res == 3 )
|
||||
request->status = WINIX_ERR_NO_ROOT_DIR;
|
||||
else
|
||||
if( res != 0 && res != 1 )
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
|
||||
if( new_mount->type != system->mounts.pmount->type )
|
||||
{
|
||||
request->status = WINIX_DIFFERENT_MOUNT_POINTS;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
return res == 0 || res == 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Mv::MoveParseDir(long & dir_id, std::wstring & dir, std::wstring & file)
|
||||
bool Mv::MoveStaticFile(const std::wstring & from, const std::wstring & to)
|
||||
{
|
||||
int res = system->dirs.AnalyzePath(request->PostVar(L"to"), dir_id, dir, file);
|
||||
if( from == to )
|
||||
{
|
||||
log << log3 << "Mv: the same path to a static file: " << to << " (skipped)" << logend;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( res == 1 )
|
||||
request->status = WINIX_ERR_NO_ROOT_DIR;
|
||||
if( RenameFile(from, to) )
|
||||
{
|
||||
log << log2 << "Mv: moved static file from: " << from << ", to: " << to << logend;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if( res != 0 )
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
|
||||
return res == 0;
|
||||
{
|
||||
log << log1 << "Mv: can't move a file from: " << from << ", to: " << to << logend;
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveStaticFile(Item & item)
|
||||
{
|
||||
bool res1 = system->MakeFilePath(item, old_path);
|
||||
bool res2 = system->CreateNewFile(item);
|
||||
bool res3 = system->MakeFilePath(item, mv_new_path, false, true, config->upload_dirs_chmod);
|
||||
bool res1, res2, res3, res4, res5;
|
||||
|
||||
res1 = system->MakeFilePath(item, old_path, false);
|
||||
res2 = !item.has_thumb || system->MakeFilePath(item, old_path_thumb, true);
|
||||
res3 = system->CreateNewFile(item);
|
||||
res4 = system->MakeFilePath(item, new_path, false, true, config->upload_dirs_chmod);
|
||||
res5 = !item.has_thumb || system->MakeFilePath(item, new_path_thumb, true, true, config->upload_dirs_chmod);
|
||||
|
||||
if( !res1 || !res2 || !res3 )
|
||||
if( !res1 || !res2 || !res3 || !res4 || !res5 )
|
||||
{
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
return;
|
||||
}
|
||||
|
||||
if( RenameFile(old_path, mv_new_path) )
|
||||
{
|
||||
log << log1 << "Mv: moved static file from: " << old_path << ", to: " << mv_new_path << logend;
|
||||
request->status = db->EditFileById(item, item.id);
|
||||
}
|
||||
else
|
||||
if( MoveStaticFile(old_path, new_path) )
|
||||
{
|
||||
log << log1 << "Mv: can't move a file from: " << old_path << ", to: " << mv_new_path << logend;
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
request->status = db->EditFileById(item, item.id);
|
||||
|
||||
if( item.has_thumb )
|
||||
MoveStaticFile(old_path_thumb, new_path_thumb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Mv::MoveIsTheSameFile(const Item & item)
|
||||
|
||||
void Mv::MoveFileOrSymlink(Item & item)
|
||||
{
|
||||
if( mv_file.empty() )
|
||||
old_url = item.url;
|
||||
|
||||
if( !file.empty() )
|
||||
{
|
||||
if( item.parent_id == mv_dir_id )
|
||||
item.url = file;
|
||||
functions->PrepareUrl(item);
|
||||
file.clear();
|
||||
}
|
||||
|
||||
item.parent_id = dir_tab.back()->id;
|
||||
request->status = db->EditParentUrlById(item, item.id);
|
||||
|
||||
if( request->status == WINIX_ERR_OK )
|
||||
{
|
||||
if( item.type == Item::file )
|
||||
log << log3 << "Mv: file: ";
|
||||
else
|
||||
log << log3 << "Mv: symlink: ";
|
||||
|
||||
log << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dir_tab);
|
||||
log << item.url << logend;
|
||||
|
||||
if( item.file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
MoveStaticFile(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Mv::MoveDirContent(const Item & dir)
|
||||
{
|
||||
content_dir_iq.WhereParentId(dir.id);
|
||||
db->GetItems(item_tab, content_dir_iq);
|
||||
|
||||
for(size_t i=0 ; i<item_tab.size() ; ++i)
|
||||
{
|
||||
if( item_tab[i].type == Item::dir )
|
||||
MoveDir(item_tab[i]);
|
||||
else
|
||||
MoveFileOrSymlink(item_tab[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Mv::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);
|
||||
}
|
||||
|
||||
|
||||
void Mv::Clear()
|
||||
{
|
||||
dir_tab.clear();
|
||||
static_item_tab.clear();
|
||||
item_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveStaticFilesTree(const Item & dir)
|
||||
{
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(dir.id);
|
||||
|
||||
// go through all directories
|
||||
for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextChild(i) )
|
||||
MoveStaticFilesTree(*(i->second));
|
||||
|
||||
static_iq.WhereParentId(dir.id);
|
||||
db->GetItems(static_item_tab, static_iq);
|
||||
|
||||
for(size_t i=0 ; i<static_item_tab.size() ; ++i)
|
||||
MoveStaticFile(static_item_tab[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveDir(Item & dir)
|
||||
{
|
||||
long dst_dir_id = dir_tab.back()->id;
|
||||
old_url = dir.url;
|
||||
|
||||
if( dst_dir_id == dir.id || system->dirs.HasParent(dst_dir_id, dir.id) )
|
||||
{
|
||||
log << log1 << "Mv: cannot move directory to inside it" << logend;
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !system->dirs.ChangeParent(dir.id, dst_dir_id) )
|
||||
{
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
return;
|
||||
}
|
||||
|
||||
dir.parent_id = dst_dir_id;
|
||||
|
||||
if( !file.empty() )
|
||||
{
|
||||
dir.url = file;
|
||||
functions->PrepareUrl(dir);
|
||||
file.clear();
|
||||
}
|
||||
|
||||
request->status = db->EditParentUrlById(dir, dir.id);
|
||||
|
||||
if( request->status == WINIX_ERR_OK )
|
||||
{
|
||||
log << log3 << "Mv: directory: " << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dir_tab);
|
||||
log << dir.url << logend;
|
||||
|
||||
MoveStaticFilesTree(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Mv::IsTheSameFile(const Item & item)
|
||||
{
|
||||
if( file.empty() )
|
||||
{
|
||||
if( item.parent_id == dir_tab.back()->id )
|
||||
return true; // nothing to do
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item.parent_id == mv_dir_id && item.url == mv_file )
|
||||
if( item.parent_id == dir_tab.back()->id && item.url == file )
|
||||
return true; // nothing to do
|
||||
}
|
||||
|
||||
@@ -190,131 +332,48 @@ return false;
|
||||
|
||||
|
||||
|
||||
void Mv::MoveFile(Item & item, bool redirect)
|
||||
void Mv::PostMoveFile()
|
||||
{
|
||||
if( MoveIsTheSameFile(item) )
|
||||
if( IsTheSameFile(request->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);
|
||||
MoveFileOrSymlink(request->item);
|
||||
|
||||
if( request->status == WINIX_ERR_OK )
|
||||
{
|
||||
log << log2 << "Mv: the file was moved to: " << mv_dir << item.url << logend;
|
||||
|
||||
if( item.file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
MoveStaticFile(item);
|
||||
|
||||
if( redirect )
|
||||
system->RedirectTo(item);
|
||||
}
|
||||
system->RedirectTo(request->item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveContentOfDir()
|
||||
void Mv::PostMoveDirContent()
|
||||
{
|
||||
DbItemQuery iq;
|
||||
|
||||
iq.sel_parent_id = true;
|
||||
iq.sel_type = true;
|
||||
iq.sel_url = true;
|
||||
iq.sel_file = true;
|
||||
iq.WhereParentId(request->dir_tab.back()->id);
|
||||
|
||||
db->GetItems(request->item_tab, iq);
|
||||
|
||||
for(size_t i=0 ; i<request->item_tab.size() ; ++i)
|
||||
if( !file.empty() )
|
||||
{
|
||||
if( request->item_tab[i].type == Item::dir )
|
||||
MoveDir(request->item_tab[i], false);
|
||||
else
|
||||
MoveFile(request->item_tab[i], false);
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
return;
|
||||
}
|
||||
|
||||
if( request->dir_tab.back()->id == dir_tab.back()->id )
|
||||
return; // nothing to do
|
||||
|
||||
MoveDirContent(*request->dir_tab.back());
|
||||
system->RedirectToLastDir();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveAuthPrepareQuery()
|
||||
void Mv::PostMoveDir()
|
||||
{
|
||||
mv_auth_iq.SetAll(false, false);
|
||||
Item & last_dir = *request->dir_tab.back();
|
||||
Item & new_dir = *dir_tab.back();
|
||||
|
||||
mv_auth_iq.sel_parent_id = true;
|
||||
mv_auth_iq.sel_type = true;
|
||||
mv_auth_iq.sel_url = true;
|
||||
mv_auth_iq.sel_file = true;
|
||||
|
||||
mv_auth_iq.WhereType(Item::file);
|
||||
mv_auth_iq.WhereFileType(WINIX_ITEM_FILETYPE_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 ; i<mv_auth.size() ; ++i)
|
||||
MoveStaticFile(mv_auth[i]);
|
||||
|
||||
mv_auth.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveDir(Item & item, bool redirect)
|
||||
{
|
||||
if( mv_file.empty() && mv_dir_id == item.id )
|
||||
if( file.empty() && new_dir.id == last_dir.id )
|
||||
return; // nothing to do
|
||||
|
||||
if( mv_dir_id == item.id || system->dirs.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);
|
||||
MoveDir(last_dir);
|
||||
|
||||
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();
|
||||
}
|
||||
system->RedirectToLastDir();
|
||||
}
|
||||
|
||||
|
||||
@@ -322,41 +381,29 @@ void Mv::MoveDir(Item & item, bool redirect)
|
||||
|
||||
void Mv::MakePost()
|
||||
{
|
||||
if( MoveCheckAccessFrom() &&
|
||||
MoveParseDir(mv_dir_id, mv_dir, mv_file) &&
|
||||
MoveCheckAccessTo(mv_dir_id) &&
|
||||
MoveCheckMountPoints(mv_dir_id) )
|
||||
if( CheckAccessFrom() &&
|
||||
ParseDir() &&
|
||||
CheckAccessTo() )
|
||||
{
|
||||
Prepare();
|
||||
|
||||
if( request->is_item )
|
||||
{
|
||||
MoveFile(request->item);
|
||||
PostMoveFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveAuthPrepareQuery();
|
||||
|
||||
if( request->IsPostVar(L"onlycontent") )
|
||||
{
|
||||
if( mv_file.empty() )
|
||||
MoveContentOfDir();
|
||||
else
|
||||
request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
}
|
||||
PostMoveDirContent();
|
||||
else
|
||||
{
|
||||
MoveDir(*request->dir_tab.back());
|
||||
}
|
||||
PostMoveDir();
|
||||
}
|
||||
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MakeGet()
|
||||
{
|
||||
MoveCheckAccessFrom();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user