327 lines
5.9 KiB
C++
Executable File
327 lines
5.9 KiB
C++
Executable File
/*
|
|
* 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 "cp.h"
|
|
#include "core/misc.h"
|
|
#include "functions.h"
|
|
|
|
|
|
namespace Fun
|
|
{
|
|
|
|
Cp::Cp()
|
|
{
|
|
fun.url = "cp";
|
|
}
|
|
|
|
|
|
bool Cp::CpCheckAccessFrom()
|
|
{
|
|
if( request->is_item )
|
|
{
|
|
if( !system->HasReadAccess(request->item) )
|
|
{
|
|
request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
if( !request->IsParam("r") )
|
|
{
|
|
// directories need 'r' parameter
|
|
request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool Cp::CheckAccessTo(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 Cp::ParseDir(long & dir_id, std::string & dir, std::string & file)
|
|
{
|
|
int res = system->dirs.AnalyzePath(request->PostVar("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 Cp::CpAuth(Item & item)
|
|
{
|
|
if( !system->MakePath(item, mv_new_path, true) )
|
|
{
|
|
request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
return;
|
|
}
|
|
|
|
if( CopyFile(item.auth_path, mv_new_path) )
|
|
{
|
|
log << log1 << "Content: copied 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
|
|
{
|
|
log << log1 << "Content: can't copy a file from: " << item.auth_path << ", to: " << mv_new_path << logend;
|
|
request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
}
|
|
}
|
|
|
|
|
|
void Cp::CpSetNewAttributes(Item & item)
|
|
{
|
|
item.user_id = cp_new_user;
|
|
item.group_id = cp_new_group;
|
|
item.SetDateModifyToNow();
|
|
}
|
|
|
|
|
|
void Cp::CpItem(Item & item, long dst_dir_id)
|
|
{
|
|
if( !system->HasReadAccess(item) )
|
|
return; // !! w przyszlosci bedziemy dodawac komunikaty do specjalnej tablicy (narazie nie zaimplementowane)
|
|
|
|
item.parent_id = dst_dir_id;
|
|
|
|
if( !cp_preserve_attr )
|
|
CpSetNewAttributes(item);
|
|
|
|
request->status = system->AddFile(item);
|
|
|
|
if( request->status == WINIX_ERR_OK )
|
|
{
|
|
if( item.auth != Item::auth_none )
|
|
CpAuth(item);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cp::CpPrepare()
|
|
{
|
|
cp_iq.SetAll(true, false);
|
|
cp_iq.WhereType(Item::file);
|
|
|
|
cp_new_user = -1;
|
|
cp_new_group = -1;
|
|
|
|
if( request->session->puser )
|
|
cp_new_user = request->session->puser->id;
|
|
|
|
Item * pdir = system->dirs.GetDir(mv_dir_id);
|
|
|
|
if( pdir )
|
|
cp_new_group = pdir->group_id;
|
|
}
|
|
|
|
|
|
|
|
void Cp::CpFilesInDir(const Item & dir, long dst_dir_id)
|
|
{
|
|
cp_iq.WhereParentId(dir.id);
|
|
db->GetItems(request->item_tab, cp_iq);
|
|
|
|
for(size_t i=0 ; i<request->item_tab.size() ; ++i)
|
|
CpItem(request->item_tab[i], dst_dir_id);
|
|
}
|
|
|
|
|
|
|
|
void Cp::CpContentOfDir(const Item & item, long dst_dir_id)
|
|
{
|
|
DirContainer::ParentIterator i = system->dirs.FindFirstParent(item.id);
|
|
|
|
// go through all directories
|
|
for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextParent(i) )
|
|
CpDir(*(i->second), dst_dir_id);
|
|
|
|
CpFilesInDir(item, dst_dir_id);
|
|
}
|
|
|
|
|
|
|
|
// we shouldn't change 'item' because we have references to our app.dirs objects
|
|
long Cp::CpDir(const Item & item, long dst_dir_id)
|
|
{
|
|
cp_temp = item;
|
|
cp_temp.parent_id = dst_dir_id;
|
|
|
|
if( !mv_file.empty() )
|
|
{
|
|
cp_temp.url = mv_file;
|
|
mv_file.clear();
|
|
functions->PrepareUrl(cp_temp);
|
|
}
|
|
|
|
if( !cp_preserve_attr )
|
|
CpSetNewAttributes(cp_temp);
|
|
|
|
if( cp_remove_defaults )
|
|
cp_temp.default_item = -1;
|
|
|
|
request->status = system->dirs.AddDirectory(cp_temp);
|
|
long new_dir_id = cp_temp.id; // remember the new dir_id
|
|
|
|
if( system->HasReadExecAccess(item) )
|
|
CpContentOfDir(item, cp_temp.id);
|
|
|
|
return new_dir_id; // and return it
|
|
}
|
|
|
|
|
|
bool Cp::IsTheSameFile(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;
|
|
}
|
|
|
|
|
|
|
|
|
|
// here 'item' can be changed in place
|
|
void Cp::CpItemCheck(Item & item, bool redirect)
|
|
{
|
|
if( IsTheSameFile(item) )
|
|
return;
|
|
|
|
if( !mv_file.empty() )
|
|
{
|
|
item.url = mv_file;
|
|
functions->PrepareUrl(item);
|
|
}
|
|
|
|
CpItem(item, mv_dir_id);
|
|
|
|
if( request->status==WINIX_ERR_OK && redirect )
|
|
system->RedirectTo(item);
|
|
}
|
|
|
|
|
|
|
|
void Cp::CpContentOfDirCheck(const Item & item, bool redirect)
|
|
{
|
|
if( !mv_file.empty() )
|
|
{
|
|
request->status = WINIX_ERR_INCORRECT_DIR;
|
|
return;
|
|
}
|
|
|
|
if( mv_dir_id == item.id )
|
|
return; // nothing to do
|
|
|
|
if( system->dirs.HasParent(mv_dir_id, item.id) )
|
|
{
|
|
log << log1 << "Content: cannot copy directory to inside it" << logend;
|
|
request->status = WINIX_ERR_INCORRECT_DIR;
|
|
return;
|
|
}
|
|
|
|
CpContentOfDir(item, mv_dir_id);
|
|
|
|
if( request->status==WINIX_ERR_OK && redirect )
|
|
system->RedirectTo(mv_dir_id);
|
|
}
|
|
|
|
|
|
|
|
void Cp::CpDirCheck(const Item & item, bool redirect)
|
|
{
|
|
if( mv_file.empty() && mv_dir_id == item.id )
|
|
return; // nothing to do
|
|
|
|
if( mv_dir_id == item.id || system->dirs.HasParent(mv_dir_id, item.id) )
|
|
{
|
|
log << log1 << "Content: cannot copy directory to inside it" << logend;
|
|
request->status = WINIX_ERR_INCORRECT_DIR;
|
|
return;
|
|
}
|
|
|
|
long new_dir_id = CpDir(item, mv_dir_id);
|
|
|
|
if( request->status==WINIX_ERR_OK && redirect )
|
|
system->RedirectTo(new_dir_id);
|
|
}
|
|
|
|
|
|
|
|
void Cp::MakePost()
|
|
{
|
|
if( CpCheckAccessFrom() &&
|
|
ParseDir(mv_dir_id, mv_dir, mv_file) &&
|
|
CheckAccessTo(mv_dir_id) )
|
|
{
|
|
CpPrepare();
|
|
cp_preserve_attr = request->IsPostVar("preserveattr");
|
|
|
|
if( request->is_item )
|
|
{
|
|
CpItemCheck(request->item);
|
|
}
|
|
else
|
|
{
|
|
cp_remove_defaults = request->IsPostVar("removedefaults");
|
|
|
|
if( request->IsPostVar("onlycontent") )
|
|
CpContentOfDirCheck(*request->dir_tab.back());
|
|
else
|
|
CpDirCheck(*request->dir_tab.back());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Cp::MakeGet()
|
|
{
|
|
CpCheckAccessFrom();
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|