winix/content/cp.cpp

262 lines
4.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 "content.h"
#include "../core/request.h"
#include "../core/data.h"
#include "../core/misc.h"
bool Content::CpCheckAccessFrom()
{
if( request.is_item )
{
if( !request.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;
}
void Content::CpAuth(Item & item)
{
if( !request.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 Content::CpSetNewAttributes(Item & item)
{
item.user_id = cp_new_user;
item.group_id = cp_new_group;
item.SetDateModifyToNow();
}
void Content::CpItem(Item & item, long dst_dir_id)
{
if( !request.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);
PostFunEmacsAdd(item);
if( request.status == WINIX_ERR_OK )
{
if( item.auth != Item::auth_none )
CpAuth(item);
}
}
void Content::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 = data.dirs.GetDir(mv_dir_id);
if( pdir )
cp_new_group = pdir->group_id;
}
void Content::CpFilesInDir(const Item & dir, long dst_dir_id)
{
cp_iq.WhereParentId(dir.id);
db.GetItems(request.item_table, cp_iq);
for(size_t i=0 ; i<request.item_table.size() ; ++i)
CpItem(request.item_table[i], dst_dir_id);
}
void Content::CpContentOfDir(const Item & item, long dst_dir_id)
{
DirContainer::ParentIterator i = data.dirs.FindFirstParent(item.id);
// go through all directories
for( ; i != data.dirs.ParentEnd() ; i = data.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 data.dirs objects
long Content::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();
PrepareUrl(cp_temp);
}
if( !cp_preserve_attr )
CpSetNewAttributes(cp_temp);
if( cp_remove_defaults )
cp_temp.default_item = -1;
Mkdir(cp_temp, false);
long new_dir_id = cp_temp.id; // remember the new dir_id
if( request.HasReadExecAccess(item) )
CpContentOfDir(item, cp_temp.id);
return new_dir_id; // and return it
}
// here 'item' can be changed in place
void Content::CpItemCheck(Item & item, bool redirect)
{
if( MoveIsTheSameFile(item) )
return;
if( !mv_file.empty() )
{
item.url = mv_file;
PrepareUrl(item);
}
CpItem(item, mv_dir_id);
if( request.status==WINIX_ERR_OK && redirect )
RedirectTo(item);
}
void Content::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( data.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 )
RedirectTo(mv_dir_id);
}
void Content::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 || data.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 )
RedirectTo(new_dir_id);
}
void Content::PostFunCp()
{
if( CpCheckAccessFrom() &&
MoveParseDir(mv_dir_id, mv_dir, mv_file) &&
MoveCheckAccessTo(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_table.back());
else
CpDirCheck(*request.dir_table.back());
}
}
}
void Content::FunCp()
{
CpCheckAccessFrom();
}