309 lines
6.0 KiB
C++
Executable File
309 lines
6.0 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 <cstdio>
|
|
#include <errno.h>
|
|
#include "rm.h"
|
|
#include "core/plugin.h"
|
|
#include "core/misc.h"
|
|
#include "templates/templates.h"
|
|
|
|
|
|
|
|
namespace Fun
|
|
{
|
|
|
|
Rm::Rm()
|
|
{
|
|
fun.url = L"rm";
|
|
follow_symlinks = false;
|
|
}
|
|
|
|
|
|
|
|
bool Rm::HasAccess(const Item & item)
|
|
{
|
|
// !! temporarily (we're waiting for the sticky bit to be implemented)
|
|
// not logged users cannot remove anything
|
|
if( !cur->session->puser )
|
|
return false;
|
|
|
|
if( item.parent_id == -1 )
|
|
{
|
|
// we can only remove the content of the root directory
|
|
// and here we check only access the the root dir
|
|
// "onlycontent" parameter should be check in post method
|
|
if( !system->HasWriteAccess(item) )
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Item * last_but_one_dir = system->dirs.GetDir(item.parent_id);
|
|
|
|
if( !last_but_one_dir )
|
|
// ops, there is no a parent dir
|
|
return false;
|
|
|
|
if( !system->HasWriteAccess(*last_but_one_dir) )
|
|
return false;
|
|
}
|
|
|
|
if( system->mounts.pmount->IsPar(system->mounts.MountParOnlyRootRemove()) )
|
|
if( !cur->session->puser || !cur->session->puser->super_user )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool Rm::HasAccess()
|
|
{
|
|
if( !cur->request->is_item )
|
|
return HasAccess(*cur->request->dir_tab.back());
|
|
else
|
|
return HasAccess(cur->request->item);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
void Rm::Prepare()
|
|
{
|
|
// selecting files and symlinks (without directories)
|
|
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;
|
|
content_dir_iq.WhereType(Item::dir, false);
|
|
|
|
// selecting files, symlinks and directories
|
|
content_dir_iq2.SetAll(false, false);
|
|
content_dir_iq2.sel_parent_id = true;
|
|
content_dir_iq2.sel_type = true;
|
|
content_dir_iq2.sel_url = true;
|
|
content_dir_iq2.sel_file = true;
|
|
}
|
|
|
|
|
|
bool Rm::RemoveStaticFile(const std::wstring & path)
|
|
{
|
|
if( ::RemoveFile(path) )
|
|
{
|
|
log << log2 << "Rm: removed static file: " << path << logend;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
log << log1 << "Rm: can't remove a file: " << path << logend;
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
void Rm::RemoveStaticFile(Item & item)
|
|
{
|
|
if( system->MakeFilePath(item, path, false) )
|
|
{
|
|
if( RemoveStaticFile(path) )
|
|
{
|
|
if( item.has_thumb && system->MakeFilePath(item, path, true) )
|
|
{
|
|
RemoveStaticFile(path);
|
|
item.has_thumb = false;
|
|
}
|
|
|
|
// we don't store it to db (it will be removed or is removed already)
|
|
item.file_path.clear();
|
|
item.file_type = WINIX_ITEM_FILETYPE_NONE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Rm::RemoveFileOrSymlink(Item & item)
|
|
{
|
|
if( db->DelItem(item) == WINIX_ERR_OK )
|
|
{
|
|
if( item.type == Item::file )
|
|
log << log2 << "Rm: deleted file ";
|
|
else
|
|
log << log2 << "Rm: deleted symlink ";
|
|
|
|
log << item.url << logend;
|
|
|
|
TemplatesFunctions::pattern_cacher.DeletePattern(item);
|
|
plugin.Call(WINIX_FILE_REMOVED, item.id);
|
|
|
|
if( item.file_type != WINIX_ITEM_FILETYPE_NONE )
|
|
RemoveStaticFile(item);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// for other uses (plugins etc)
|
|
void Rm::RemoveItemById(long item_id)
|
|
{
|
|
// selecting files, symlinks and directories
|
|
rm_by_id_iq.SetAll(false, false);
|
|
rm_by_id_iq.sel_parent_id = true;
|
|
rm_by_id_iq.sel_type = true;
|
|
rm_by_id_iq.sel_url = true;
|
|
rm_by_id_iq.sel_file = true;
|
|
rm_by_id_iq.WhereId(item_id);
|
|
|
|
if( db->GetItem(rm_by_id_item, rm_by_id_iq) == WINIX_ERR_OK )
|
|
{
|
|
if( rm_by_id_item.type == Item::dir )
|
|
RemoveDir(rm_by_id_item);
|
|
else
|
|
RemoveFileOrSymlink(rm_by_id_item);
|
|
}
|
|
}
|
|
|
|
|
|
void Rm::RemoveDirTree(long dir_id)
|
|
{
|
|
DirContainer::ParentIterator pnext, p = system->dirs.FindFirstChild(dir_id);
|
|
|
|
for( ; p != system->dirs.ParentEnd() ; p = pnext )
|
|
{
|
|
// this iterator p will be deleted by the next DeleteDir(p->second->id)
|
|
// (the next iterator we must calculate beforehand)
|
|
pnext = system->dirs.NextChild(p);
|
|
RemoveDirTree(p->second->id);
|
|
}
|
|
|
|
plugin.Call(WINIX_DIR_PREPARE_TO_REMOVE, dir_id);
|
|
|
|
content_dir_iq.WhereParentId(dir_id);
|
|
db->GetItems(content_item_tab, content_dir_iq);
|
|
|
|
for(size_t i=0 ; i<content_item_tab.size() ; ++i)
|
|
RemoveFileOrSymlink(content_item_tab[i]);
|
|
|
|
if( db->DelDirById(dir_id) == WINIX_ERR_OK )
|
|
{
|
|
system->dirs.DelDir(dir_id);
|
|
plugin.Call(WINIX_DIR_REMOVED, dir_id);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Rm::RemoveDir(const Item & dir)
|
|
{
|
|
old_url = dir.url;
|
|
RemoveDirTree(dir.id);
|
|
|
|
if( cur->request->status == WINIX_ERR_OK )
|
|
log << log3 << "Rm: removed directory " << old_url << logend;
|
|
}
|
|
|
|
|
|
|
|
void Rm::RemoveFile()
|
|
{
|
|
RemoveFileOrSymlink(cur->request->item);
|
|
|
|
if( cur->request->status == WINIX_ERR_OK )
|
|
system->RedirectToLastDir();
|
|
}
|
|
|
|
|
|
|
|
void Rm::RemoveDirContent(const Item & dir)
|
|
{
|
|
content_dir_iq2.WhereParentId(dir.id);
|
|
db->GetItems(content_item_tab2, content_dir_iq2);
|
|
|
|
for(size_t i=0 ; i<content_item_tab2.size() ; ++i)
|
|
{
|
|
if( content_item_tab2[i].type == Item::dir )
|
|
RemoveDir(content_item_tab2[i]);
|
|
else
|
|
RemoveFileOrSymlink(content_item_tab2[i]);
|
|
}
|
|
}
|
|
|
|
|
|
void Rm::RemoveDirContent()
|
|
{
|
|
if( !cur->request->IsParam(L"r") )
|
|
{
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
return;
|
|
}
|
|
|
|
RemoveDirContent(*cur->request->dir_tab.back());
|
|
|
|
if( cur->request->status == WINIX_ERR_OK )
|
|
system->RedirectToLastDir();
|
|
}
|
|
|
|
|
|
|
|
void Rm::RemoveDir()
|
|
{
|
|
if( !cur->request->IsParam(L"r") || cur->request->dir_tab.size() <= 1 )
|
|
{
|
|
// we cannot remove the root directory (dir_tab.size()==1)
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
|
return;
|
|
}
|
|
|
|
RemoveDir(*cur->request->dir_tab.back());
|
|
cur->request->dir_tab.erase(--cur->request->dir_tab.end());
|
|
|
|
if( cur->request->status == WINIX_ERR_OK )
|
|
system->RedirectToLastDir();
|
|
}
|
|
|
|
|
|
|
|
|
|
void Rm::Clear()
|
|
{
|
|
content_item_tab.clear();
|
|
content_item_tab2.clear();
|
|
}
|
|
|
|
|
|
|
|
void Rm::MakePost()
|
|
{
|
|
Prepare();
|
|
|
|
if( cur->request->is_item )
|
|
{
|
|
RemoveFile();
|
|
}
|
|
else
|
|
{
|
|
if( cur->request->IsPostVar(L"onlycontent") )
|
|
RemoveDirContent();
|
|
else
|
|
RemoveDir();
|
|
}
|
|
|
|
Clear();
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|