362 lines
6.4 KiB
C++
362 lines
6.4 KiB
C++
|
/*
|
||
|
* This file is a part of Winix
|
||
|
* and is not publicly distributed
|
||
|
*
|
||
|
* Copyright (c) 2008-2010, Tomasz Sowa
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include "content.h"
|
||
|
#include "../core/request.h"
|
||
|
#include "../core/data.h"
|
||
|
|
||
|
|
||
|
|
||
|
bool Content::MoveCheckAccessFromToDir()
|
||
|
{
|
||
|
Item * last;
|
||
|
Item * last_but_one = 0;
|
||
|
|
||
|
last = request.dir_table[request.dir_table.size()-1];
|
||
|
|
||
|
if( request.dir_table.size() >= 2 )
|
||
|
last_but_one = request.dir_table[request.dir_table.size()-2];
|
||
|
|
||
|
if( request.method != Request::post )
|
||
|
{
|
||
|
// used in GET (HEAD in the future?)
|
||
|
|
||
|
if( !request.HasWriteAccess(*last) &&
|
||
|
(!last_but_one || !request.HasWriteAccess(*last_but_one)) )
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// used in POST when the moving is performed
|
||
|
|
||
|
if( request.IsPostVar("onlycontent") )
|
||
|
return request.HasWriteAccess(*last);
|
||
|
else
|
||
|
if( last_but_one )
|
||
|
return request.HasWriteAccess(*last_but_one);
|
||
|
else
|
||
|
return false; // you cannot move the root directory
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool Content::MoveCheckAccessFrom()
|
||
|
{
|
||
|
if( request.is_item )
|
||
|
{
|
||
|
// moving a file
|
||
|
|
||
|
if( !request.HasWriteAccess(*request.dir_table.back()) )
|
||
|
{
|
||
|
request.status = WINIX_ERR_PERMISSION_DENIED;
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( !MoveCheckAccessFromToDir() )
|
||
|
{
|
||
|
request.status = WINIX_ERR_PERMISSION_DENIED;
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool Content::MoveCheckAccessTo(long dir_id)
|
||
|
{
|
||
|
Item * pdir = data.dirs.GetDir(dir_id);
|
||
|
|
||
|
if( !pdir )
|
||
|
{
|
||
|
request.status = WINIX_ERR_INCORRECT_DIR;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if( !request.HasReadExecAccessToPath(dir_id) || !request.HasWriteAccess(*pdir) )
|
||
|
{
|
||
|
request.status = WINIX_ERR_PERMISSION_DENIED;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool Content::MoveCheckMountPoints(long dir_id)
|
||
|
{
|
||
|
/*
|
||
|
Mount * new_mount = data.mounts.CalcMount(dir_id);
|
||
|
|
||
|
if( !new_mount )
|
||
|
{
|
||
|
if( data.mounts.pmount->type != Mount::cms )
|
||
|
{
|
||
|
request.status = WINIX_DIFFERENT_MOUNT_POINTS;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if( new_mount->type != data.mounts.pmount->type )
|
||
|
{
|
||
|
request.status = WINIX_DIFFERENT_MOUNT_POINTS;
|
||
|
return false;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool Content::MoveParseDir(long & dir_id, std::string & dir, std::string & file)
|
||
|
{
|
||
|
std::string * move_to = request.PostVar("moveto");
|
||
|
|
||
|
if( !move_to )
|
||
|
{
|
||
|
request.status = WINIX_ERR_PERMISSION_DENIED;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int res = data.dirs.AnalyzePath(*move_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 Content::MoveAuth(Item & item)
|
||
|
{
|
||
|
if( !request.MakePath(item, mv_new_path, true) )
|
||
|
{
|
||
|
request.status = WINIX_ERR_PERMISSION_DENIED;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( rename(item.auth_path.c_str(), mv_new_path.c_str()) == 0 )
|
||
|
{
|
||
|
log << log1 << "Content: 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 << "Content: 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 Content::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 Content::MoveFile(Item & item, bool redirect)
|
||
|
{
|
||
|
if( MoveIsTheSameFile(item) )
|
||
|
return;
|
||
|
|
||
|
if( !mv_file.empty() )
|
||
|
{
|
||
|
item.url = mv_file;
|
||
|
PrepareUrl(item);
|
||
|
}
|
||
|
|
||
|
item.parent_id = mv_dir_id;
|
||
|
request.status = db.EditParentUrlById(item, item.id);
|
||
|
|
||
|
if( request.status == WINIX_ERR_OK )
|
||
|
{
|
||
|
log << log2 << "Content: the file was moved to: " << mv_dir << item.url << logend;
|
||
|
|
||
|
if( item.auth != Item::auth_none )
|
||
|
MoveAuth(item);
|
||
|
|
||
|
if( redirect )
|
||
|
RedirectTo(item);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Content::MoveContentOfDir()
|
||
|
{
|
||
|
Db::ItemQuery iq;
|
||
|
|
||
|
iq.sel_parent_id = true;
|
||
|
iq.sel_type = true;
|
||
|
iq.sel_url = true;
|
||
|
iq.sel_auth = true;
|
||
|
iq.WhereParentId(request.dir_table.back()->id);
|
||
|
|
||
|
db.GetItems(request.item_table, iq);
|
||
|
|
||
|
for(size_t i=0 ; i<request.item_table.size() ; ++i)
|
||
|
{
|
||
|
if( request.item_table[i].type == Item::dir )
|
||
|
MoveDir(request.item_table[i], false);
|
||
|
else
|
||
|
MoveFile(request.item_table[i], false);
|
||
|
}
|
||
|
|
||
|
RedirectToLastDir();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Content::MoveAuthPrepareQuery()
|
||
|
{
|
||
|
mv_auth_iq.SetAll(true, 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 Content::MoveAuthContentOfDir(const Item & item)
|
||
|
{
|
||
|
DirContainer::ParentIterator i = data.dirs.FindFirstParent(item.id);
|
||
|
|
||
|
// go through all directories
|
||
|
for( ; i != data.dirs.ParentEnd() ; i = data.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)
|
||
|
MoveAuth(mv_auth[i]);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Content::MoveDir(Item & item, bool redirect)
|
||
|
{
|
||
|
if( mv_file.empty() && mv_dir_id == item.id )
|
||
|
return; // nothing to do
|
||
|
|
||
|
if( mv_dir_id == item.id || data.dirs.HasParent(mv_dir_id, item.id) )
|
||
|
{
|
||
|
log << log1 << "Content: cannot move directory to inside it" << logend;
|
||
|
request.status = WINIX_ERR_INCORRECT_DIR;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( !data.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;
|
||
|
PrepareUrl(item);
|
||
|
}
|
||
|
|
||
|
request.status = db.EditParentUrlById(item, item.id);
|
||
|
|
||
|
if( request.status == WINIX_ERR_OK )
|
||
|
{
|
||
|
log << log2 << "Content: the directory was moved to: " << mv_dir << item.url << logend;
|
||
|
MoveAuthContentOfDir(item);
|
||
|
|
||
|
if( redirect )
|
||
|
RedirectToLastDir();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void Content::PostFunMv()
|
||
|
{
|
||
|
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("onlycontent") )
|
||
|
{
|
||
|
if( mv_file.empty() )
|
||
|
MoveContentOfDir();
|
||
|
else
|
||
|
request.status = WINIX_ERR_INCORRECT_DIR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MoveDir(*request.dir_table.back());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Content::FunMv()
|
||
|
{
|
||
|
MoveCheckAccessFrom();
|
||
|
}
|
||
|
|
||
|
|
||
|
|