added: now we have a fourth part in permissions (guests)
e.g.: 07555 means: 7 for owner 5 for group 5 for others 5 for guests (not logged users) added: the sticky bit for directories e.g. permissions to a directory with a sticky bit set can be set to: 017555 rewritten: rm/mv winix functions to correctly understand the sticky bit added: Dir::FollowLink() recognizes ".." and "." now consequently System::FollowAllLinks recognizes it too added: umask -- calculating privileges for new files/directories all users have their own umask (in meta) and there is one in the config (for guests and when a user has not definied its own one) removed: mount option: only_root_remove git-svn-id: svn://ttmath.org/publicrep/winix/trunk@801 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
5aaab89cd8
commit
6e2d00bc5b
|
@ -229,6 +229,7 @@ void Config::AssignValues(bool stdout_is_closed)
|
|||
pattern_cacher_how_many_delete = Size(L"pattern_cacher_how_many_delete", 30);
|
||||
|
||||
content_type_header = Int(L"content_type_header", 0);
|
||||
umask = Int(L"umask", 0222);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -453,7 +453,10 @@ public:
|
|||
// if utf8 is true then "; charset=UTF-8" will also be appended
|
||||
int content_type_header;
|
||||
|
||||
|
||||
// global umask
|
||||
// it is used when an user doesn't have your own umask or for guests (not logged users)
|
||||
// default: 0222
|
||||
int umask;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
bool DelById(long id);
|
||||
|
||||
ParentIterator ParentBegin();
|
||||
ParentIterator ParentBegin(); // IMPROVE ME: may it should be renamed to ChildBegin() similarly as FindFirstChild() ?
|
||||
ParentIterator ParentEnd();
|
||||
ParentSizeType ParentSize();
|
||||
bool ParentEmpty();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2011, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -41,7 +41,7 @@ void Dirs::Clear()
|
|||
bool Dirs::HasReadExecAccessForRoot(const Item & item)
|
||||
{
|
||||
// there must be at least one 'x' (for the root)
|
||||
return (item.privileges & 01111) != 0; // !! in the future there'll be another 'x'
|
||||
return (item.privileges & 01111) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,8 +53,8 @@ void Dirs::CheckRootDir()
|
|||
{
|
||||
if( !HasReadExecAccessForRoot(*i) )
|
||||
{
|
||||
i->privileges = 0755;
|
||||
log << log1 << "Dirs: there is no access for root (admin) to the root dir, setting 0755 for root dir" << logend;
|
||||
i->privileges = 07555;
|
||||
log << log1 << "Dirs: there is no access for a root (admin) to the root dir, setting 07555 for the root directory" << logend;
|
||||
db->EditPrivById(*i, i->id);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ void Dirs::CheckRootDir()
|
|||
}
|
||||
|
||||
|
||||
log << log1 << "Dirs: there is no a root dir in the database (creating one)" << logend;
|
||||
log << log1 << "Dirs: there is no a root directory in the database (creating one)" << logend;
|
||||
|
||||
Item root;
|
||||
|
||||
|
@ -70,7 +70,7 @@ void Dirs::CheckRootDir()
|
|||
root.parent_id = -1;
|
||||
root.user_id = -1;
|
||||
root.group_id = -1;
|
||||
root.privileges = 0755;
|
||||
root.privileges = 07555;
|
||||
|
||||
// !! upewnic sie ze baza nie zmieni url (gdyby wczesniej juz byl w bazie pusty url)
|
||||
// !! zrobic jakis wyjatek do wprowadzania roota?
|
||||
|
@ -502,13 +502,13 @@ void Dirs::CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out)
|
|||
|
||||
|
||||
|
||||
size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to)
|
||||
bool Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i)
|
||||
{
|
||||
if( dir_tab.empty() )
|
||||
return 0;
|
||||
|
||||
size_t i = 0;
|
||||
size_t old_i;
|
||||
i = 0;
|
||||
|
||||
if( dir_tab.empty() )
|
||||
return false;
|
||||
|
||||
while( true )
|
||||
{
|
||||
|
@ -516,7 +516,7 @@ size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_
|
|||
for( ; i<link_to.size() && link_to[i] == '/' ; ++i);
|
||||
|
||||
if( i == link_to.size() )
|
||||
return i; // end of the path
|
||||
return true; // end of the path
|
||||
|
||||
// creating a name
|
||||
old_i = i;
|
||||
|
@ -525,14 +525,28 @@ size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_
|
|||
for( ; i<link_to.size() && link_to[i] != '/' ; ++i)
|
||||
analyze_temp += link_to[i];
|
||||
|
||||
if( analyze_temp == L".." )
|
||||
{
|
||||
if( dir_tab.size() <= 1 )
|
||||
return false;
|
||||
|
||||
dir_tab.pop_back();
|
||||
}
|
||||
else
|
||||
if( analyze_temp != L"." )
|
||||
{
|
||||
Item * pdir = GetDir(analyze_temp, dir_tab.back()->id);
|
||||
|
||||
if( !pdir )
|
||||
return old_i; // analyze_temp is not a directory
|
||||
{
|
||||
i = old_i;
|
||||
return true; // analyze_temp is not a directory
|
||||
}
|
||||
|
||||
dir_tab.push_back(pdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -541,7 +555,10 @@ size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_
|
|||
|
||||
int Dirs::FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item)
|
||||
{
|
||||
size_t i = AnalyzeDir(dir_tab, link_to);
|
||||
size_t i;
|
||||
|
||||
if( !AnalyzeDir(dir_tab, link_to, i) )
|
||||
return 2; // incorrect link_to
|
||||
|
||||
if( i < link_to.size() )
|
||||
{
|
||||
|
@ -574,7 +591,7 @@ return 0;
|
|||
4 - current_dir_tab was empty
|
||||
|
||||
current_dir_tab can be the same container as out_dir_tab
|
||||
link_to can be a relative path (without the first slash)
|
||||
link_to can be a relative path (without the first slash) and can contain ".." or "."
|
||||
*/
|
||||
int Dirs::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
|
||||
std::vector<Item*> & out_dir_tab, std::wstring & out_item)
|
||||
|
@ -693,9 +710,9 @@ Item * Dirs::CreateVarDir()
|
|||
if( root )
|
||||
{
|
||||
v.parent_id = root->id;
|
||||
v.user_id = -1;
|
||||
v.group_id = -1;
|
||||
v.privileges = 0755;
|
||||
v.user_id = root->user_id;
|
||||
v.group_id = root->group_id;
|
||||
v.privileges = root->privileges;
|
||||
v.subject = L"var";
|
||||
v.url = L"var";
|
||||
v.type = Item::dir;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2011, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
bool DelDir(long dir_id);
|
||||
|
||||
// if returns true then out_dir_tab is not empty
|
||||
bool CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab);
|
||||
|
||||
void LogDir(const std::vector<Item*> & dir_tab);
|
||||
|
@ -98,7 +99,7 @@ private:
|
|||
std::wstring temp_link_to;
|
||||
|
||||
size_t AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir);
|
||||
size_t AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to);
|
||||
bool AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i);
|
||||
std::wstring analyze_temp;
|
||||
std::wstring get_dir_temp;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2009-2011, Tomasz Sowa
|
||||
* Copyright (c) 2009-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -53,9 +53,6 @@ void Mounts::CreateMountPar()
|
|||
mount_par_image_size = AddMountPar(L"image_size");
|
||||
mount_par_image_mode = AddMountPar(L"image_mode");
|
||||
mount_par_image_quality = AddMountPar(L"image_quality");
|
||||
//mount_par_thread = AddMountPar(L"thread");
|
||||
//mount_par_createthread_on = AddMountPar(L"createthread_on");
|
||||
mount_par_only_root_remove = AddMountPar(L"only_root_remove");
|
||||
mount_par_emacs_on = AddMountPar(L"emacs_on");
|
||||
mount_par_mkdir_on = AddMountPar(L"mkdir_on");
|
||||
mount_par_app = AddMountPar(L"app");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2009-2011, Tomasz Sowa
|
||||
* Copyright (c) 2009-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -73,9 +73,6 @@ public:
|
|||
int MountParImageSize() { return mount_par_image_size; }
|
||||
int MountParImageMode() { return mount_par_image_mode; }
|
||||
int MountParImageQuality() { return mount_par_image_quality; }
|
||||
//int MountParThread() { return mount_par_thread; }
|
||||
//int MountParCreatethreadOn() { return mount_par_createthread_on; }
|
||||
int MountParOnlyRootRemove() { return mount_par_only_root_remove; }
|
||||
int MountParEmacsOn() { return mount_par_emacs_on; }
|
||||
int MountParMkdirOn() { return mount_par_mkdir_on; }
|
||||
int MountParApp() { return mount_par_app; }
|
||||
|
@ -148,9 +145,6 @@ private:
|
|||
int mount_par_image_size;
|
||||
int mount_par_image_mode;
|
||||
int mount_par_image_quality;
|
||||
//int mount_par_thread;
|
||||
//int mount_par_createthread_on;
|
||||
int mount_par_only_root_remove;
|
||||
int mount_par_emacs_on;
|
||||
int mount_par_mkdir_on;
|
||||
int mount_par_app;
|
||||
|
|
|
@ -29,121 +29,137 @@
|
|||
// winix function and parameters have been parsed
|
||||
// the request.status is OK
|
||||
// (the winix function was not called yet)
|
||||
#define WINIX_PREPARE_REQUEST 2000
|
||||
#define WINIX_PREPARE_REQUEST 20000
|
||||
|
||||
// post and get functions have done their jobs
|
||||
// now you can act
|
||||
// this is called only if the request.status is OK
|
||||
#define WINIX_PROCESS_REQUEST 2001
|
||||
#define WINIX_PROCESS_REQUEST 20010
|
||||
|
||||
// prepere your content for displaying
|
||||
// this is called after WINIX_PROCESS_REQUEST
|
||||
// and when there is not a redirect
|
||||
// request.status is not checked here
|
||||
#define WINIX_CONTENT_MAKE 2002
|
||||
#define WINIX_CONTENT_MAKE 20020
|
||||
|
||||
// here you can attach your own session data (based on PluginDataBase class)
|
||||
// call cur->session->plugin_data.Assign(pointer)
|
||||
#define WINIX_SESSION_CREATED 3000
|
||||
#define WINIX_SESSION_CREATED 30000
|
||||
|
||||
// here you should remove your session data
|
||||
// this message can be sent even if you don't assing your plugin data
|
||||
#define WINIX_SESSION_REMOVE 3001
|
||||
#define WINIX_SESSION_REMOVE 30010
|
||||
|
||||
// when a session is changed (you can save a pointer to your data here)
|
||||
#define WINIX_SESSION_CHANGED 3002
|
||||
#define WINIX_SESSION_CHANGED 30020
|
||||
|
||||
// the winix is closing
|
||||
// the is not any session available (cur->session is null)
|
||||
#define WINIX_CLOSE 3004
|
||||
#define WINIX_CLOSE 30040
|
||||
|
||||
// preparing to remove a file (rm function)
|
||||
// in p1 you have a pointer to the Item struct (file)
|
||||
// valid members are:
|
||||
// id, parent_id, type, url, file_path, file_fs, file_type, has_thumb, hash, hash_type, file_size
|
||||
// user_id, group_id, privileges
|
||||
// (sometimes rest members can be valid as well -- when you call directly fun_rm->RemoveFileOrSymlink() method)
|
||||
#define WINIX_FILE_PREPARE_TO_REMOVE 30045
|
||||
|
||||
// a file or symlink was removed (rm function)
|
||||
// in p1 you have a pointer to the Item struct (old file)
|
||||
#define WINIX_FILE_REMOVED 3005
|
||||
|
||||
// directory was removed (rm function)
|
||||
// PluginInfo::l1 is the dir id
|
||||
#define WINIX_DIR_REMOVED 3006
|
||||
// valid members are the same as in WINIX_FILE_PREPARE_TO_REMOVE
|
||||
#define WINIX_FILE_REMOVED 30050
|
||||
|
||||
// preparing to remove a directory (rm function)
|
||||
// in p1 you have a pointer to the Item struct (directory)
|
||||
#define WINIX_DIR_PREPARE_TO_REMOVE 3007
|
||||
// this message is sent after checking the directory permissions
|
||||
// so consequently if there is no any database error then the
|
||||
// directory will be removed
|
||||
// and after removed WINIX_DIR_REMOVED message is sent
|
||||
#define WINIX_DIR_PREPARE_TO_REMOVE 30070
|
||||
|
||||
// directory was removed (rm function)
|
||||
// PluginInfo::l1 is the directory id
|
||||
#define WINIX_DIR_REMOVED 30060
|
||||
|
||||
// winix is initialized,
|
||||
// now you can initialize your plugin
|
||||
#define WINIX_PLUGIN_INIT 3008
|
||||
#define WINIX_PLUGIN_INIT 30080
|
||||
|
||||
// here you can add your own mount point, file systems, mount parameters
|
||||
// for adding a new mount type call: system->mounts.AddMountType("new_mount_name")
|
||||
#define WINIX_ADD_MOUNTS 3009
|
||||
#define WINIX_ADD_MOUNTS 30090
|
||||
|
||||
// add plugin functions (winix functions) here
|
||||
// call info.functions->Add() to add a function
|
||||
#define WINIX_CREATE_FUNCTIONS 3010
|
||||
#define WINIX_CREATE_FUNCTIONS 30100
|
||||
|
||||
// choose a default function
|
||||
// if you do not select it then it will be choosen by winix
|
||||
#define WINIX_SELECT_DEFAULT_FUNCTION 3011
|
||||
#define WINIX_SELECT_DEFAULT_FUNCTION 30110
|
||||
|
||||
// /etc/fstab has been changed
|
||||
// now we have new mount points
|
||||
#define WINIX_FSTAB_CHANGED 3012
|
||||
#define WINIX_FSTAB_CHANGED 30120
|
||||
|
||||
// here you add your own template to notification system
|
||||
// call system->notify.AddTemplate() method
|
||||
// with a template file name
|
||||
#define WINIX_NOTIFY_ADD_TEMPLATE 3013
|
||||
#define WINIX_NOTIFY_ADD_TEMPLATE 30130
|
||||
|
||||
// the request is being ended
|
||||
// you can clear some of your objects here
|
||||
#define WINIX_END_REQUEST 3014
|
||||
#define WINIX_END_REQUEST 30140
|
||||
|
||||
// a new file (page) has been added
|
||||
// in p1 you have a pointer to the Item struct
|
||||
#define WINIX_FILE_ADDED 3015
|
||||
#define WINIX_FILE_ADDED 30150
|
||||
|
||||
// a file (page) has been changed (edited)
|
||||
// in p1 you have a pointer to the Item struct
|
||||
#define WINIX_FILE_CHANGED 3016
|
||||
#define WINIX_FILE_CHANGED 30160
|
||||
|
||||
// a file (page) has been copied
|
||||
// in p1 you have a pointer to the Item struct
|
||||
// not every fields of Item struct are filled
|
||||
#define WINIX_FILE_COPIED 3017
|
||||
#define WINIX_FILE_COPIED 30170
|
||||
|
||||
// a file will be moved
|
||||
// in p1 you have a pointer to the Item struct
|
||||
// not every fields of Item struct are filled
|
||||
#define WINIX_FILE_PREPARE_TO_MOVE 3018
|
||||
// valid members are:
|
||||
// id, parent_id, type, url, file_path, file_fs, file_type, has_thumb, hash, hash_type, file_size
|
||||
// user_id, group_id, privileges, meta
|
||||
// (sometimes rest members can be valid as well -- when you call directly fun_rm->RemoveFileOrSymlink() method)
|
||||
#define WINIX_FILE_PREPARE_TO_MOVE 30180
|
||||
|
||||
// a file has been moved
|
||||
// in p1 you have a pointer to the Item struct (new file)
|
||||
// not every fields of Item struct are filled
|
||||
#define WINIX_FILE_MOVED 3019
|
||||
// valid members are the same as in WINIX_FILE_PREPARE_TO_MOVE
|
||||
#define WINIX_FILE_MOVED 30190
|
||||
|
||||
// a thumbnail was created
|
||||
// this message is called from another thread
|
||||
// the thread is called Lock() before sending this message
|
||||
// in p1 you have a pointer to the Item struct
|
||||
#define WINIX_CREATED_THUMB 3050
|
||||
#define WINIX_CREATED_THUMB 30500
|
||||
|
||||
// an image has been resized
|
||||
// this message is called from another thread
|
||||
// the thread is called Lock() before sending this message
|
||||
// in p1 you have a pointer to the Item struct
|
||||
#define WINIX_IMAGE_RESIZED 3052
|
||||
#define WINIX_IMAGE_RESIZED 30520
|
||||
|
||||
// content of a directory was sorted
|
||||
// (winix 'sort' function was used)
|
||||
// in p1 you have a pointer to the Item struct (of the directory)
|
||||
// this is from system->dirs so you should not change the item
|
||||
#define WINIX_DIR_CONTENT_SORTED 3050
|
||||
#define WINIX_DIR_CONTENT_SORTED 30500
|
||||
|
||||
// a user has been logged
|
||||
// send from 'login' winix function
|
||||
// this message is also called when winix starts and reads sessions
|
||||
// from the session file
|
||||
#define WINIX_USER_LOGGED 3060
|
||||
#define WINIX_USER_LOGGED 30600
|
||||
|
||||
|
||||
// here you add your own html templates
|
||||
|
@ -154,7 +170,7 @@
|
|||
// the message will be sent too whenever 'reload/templates' winix function is called
|
||||
// templates you should add only in this message
|
||||
// in other cases after 'reload' function the indexes would be wrong
|
||||
#define WINIX_ADD_TEMPLATE 3100
|
||||
#define WINIX_ADD_TEMPLATE 31000
|
||||
|
||||
|
||||
|
||||
|
|
112
core/system.cpp
112
core/system.cpp
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010-2011, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -260,12 +260,12 @@ bool System::CanChangeUser(const Item & item, long new_user_id)
|
|||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
// !! przeciez to prosciej mozna zapisac
|
||||
// albo dac od razu return false
|
||||
if( item.user_id != new_user_id )
|
||||
if( item.user_id == -1 || new_user_id == -1 || item.user_id != new_user_id )
|
||||
// only super user can change the owner of an item
|
||||
return false;
|
||||
|
||||
// item.user_id is equal new_user_id -- we return true
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -285,10 +285,10 @@ bool System::CanChangeGroup(const Item & item, long new_group_id)
|
|||
// user is allowed to change the group only if he is an owner of the item
|
||||
// he can change only into a group in which he is a member of, or into a 'no_group'
|
||||
|
||||
if( !cur->session->puser )
|
||||
if( !cur->session->puser || cur->session->puser->id == -1 )
|
||||
return false;
|
||||
|
||||
if( cur->session->puser->id != item.user_id )
|
||||
if( item.user_id == -1 || cur->session->puser->id != item.user_id )
|
||||
return false;
|
||||
|
||||
if( new_group_id == -1 )
|
||||
|
@ -318,10 +318,10 @@ bool System::CanChangePrivileges(const Item & item, int new_priv)
|
|||
{
|
||||
// the owner of an item is allowed to change the privileges
|
||||
|
||||
if( !cur->session->puser )
|
||||
if( !cur->session->puser || cur->session->puser->id == -1 )
|
||||
return false;
|
||||
|
||||
if( cur->session->puser->id != item.user_id )
|
||||
if( item.user_id == -1 || cur->session->puser->id != item.user_id )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ return true;
|
|||
}
|
||||
|
||||
|
||||
|
||||
// private
|
||||
bool System::HasAccess(const Item & item, int mask)
|
||||
{
|
||||
if( !cur->session )
|
||||
|
@ -340,19 +340,25 @@ bool System::HasAccess(const Item & item, int mask)
|
|||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
if( cur->session->puser && cur->session->puser->id == item.user_id )
|
||||
if( cur->session->puser && item.user_id != -1 && cur->session->puser->id == item.user_id )
|
||||
{
|
||||
// the owner
|
||||
return ((item.privileges >> 9) & mask) == mask;
|
||||
}
|
||||
|
||||
if( cur->session->puser && item.group_id != -1 && cur->session->puser->IsMemberOf(item.group_id) )
|
||||
{
|
||||
// group
|
||||
return ((item.privileges >> 6) & mask) == mask;
|
||||
}
|
||||
|
||||
if( cur->session->puser && cur->session->puser->IsMemberOf(item.group_id) )
|
||||
if( cur->session->puser )
|
||||
{
|
||||
// group
|
||||
// others -- others logged people
|
||||
return ((item.privileges >> 3) & mask) == mask;
|
||||
}
|
||||
|
||||
// others
|
||||
// guests -- not logged people
|
||||
|
||||
return (item.privileges & mask) == mask;
|
||||
}
|
||||
|
@ -381,8 +387,8 @@ bool System::HasReadExecAccess(const Item & item)
|
|||
if( cur->session && cur->session->puser && cur->session->puser->super_user )
|
||||
{
|
||||
// there must be at least one 'x' (for the root)
|
||||
|
||||
return (item.privileges & 0111) != 0;
|
||||
// !! CHECK ME: is it applicable to directories too?
|
||||
return (item.privileges & 01111) != 0;
|
||||
}
|
||||
|
||||
return HasAccess(item, 5); // r+x
|
||||
|
@ -468,6 +474,76 @@ size_t i = 0;
|
|||
}
|
||||
|
||||
|
||||
int System::NewPrivileges(int creation_mask)
|
||||
{
|
||||
if( cur && cur->session && cur->session->puser )
|
||||
{
|
||||
int umask = cur->session->puser->env.Int(L"umask", config->umask);
|
||||
return (~umask) & creation_mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (~config->umask) & creation_mask;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
from man sticky:
|
||||
A directory whose `sticky bit' is set becomes an append-only directory,
|
||||
or, more accurately, a directory in which the deletion of files is
|
||||
restricted. A file in a sticky directory may only be removed or renamed
|
||||
by a user if the user has write permission for the directory and the user
|
||||
is the owner of the file, the owner of the directory, or the super-user.
|
||||
This feature is usefully applied to directories such as /tmp which must
|
||||
be publicly writable but should deny users the license to arbitrarily
|
||||
delete or rename each others' files.
|
||||
*/
|
||||
bool System::CanRemoveRenameChild(const Item & dir, long child_item_user_id)
|
||||
{
|
||||
if( dir.type != Item::dir )
|
||||
return false;
|
||||
|
||||
if( !HasWriteAccess(dir) )
|
||||
return false;
|
||||
|
||||
if( (dir.privileges & 010000) == 0 )
|
||||
// there is no a sticky bit set to this directory
|
||||
return true;
|
||||
|
||||
if( cur->session->puser )
|
||||
{
|
||||
if( cur->session->puser->super_user )
|
||||
return true;
|
||||
|
||||
if( dir.user_id != -1 && cur->session->puser->id != -1 && child_item_user_id != -1 )
|
||||
{
|
||||
if( cur->session->puser->id == child_item_user_id ||
|
||||
cur->session->puser->id == dir.user_id )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int System::NewFilePrivileges()
|
||||
{
|
||||
return NewPrivileges(06666);
|
||||
}
|
||||
|
||||
|
||||
int System::NewDirPrivileges()
|
||||
{
|
||||
return NewPrivileges(07777);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool System::CanUseHtml(long user_id)
|
||||
{
|
||||
return IsMemberOfGroup(user_id, L"allow_html");
|
||||
|
@ -1068,9 +1144,9 @@ bool System::AddCommonFileToVar(const wchar_t * file_path, const wchar_t * url,
|
|||
|
||||
file_content_item.Clear();
|
||||
file_content_item.parent_id = var->id;
|
||||
file_content_item.user_id = -1;
|
||||
file_content_item.group_id = -1;
|
||||
file_content_item.privileges = 0755;
|
||||
file_content_item.user_id = var->user_id;
|
||||
file_content_item.group_id = var->group_id;
|
||||
file_content_item.privileges = 07555; // !! IMPROVE ME: may it should be added as a parameter to this function?
|
||||
file_content_item.subject = url;
|
||||
file_content_item.url = url;
|
||||
file_content_item.type = Item::file;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010-2011, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -88,7 +88,8 @@ public:
|
|||
bool CanChangeUser(const Item & item, long new_user_id);
|
||||
bool CanChangeGroup(const Item & item, long new_group_id);
|
||||
bool CanChangePrivileges(const Item & item, int new_priv);
|
||||
bool HasAccess(const Item & item, int mask);
|
||||
|
||||
|
||||
bool HasReadAccess(const Item & item);
|
||||
bool HasWriteAccess(const Item & item);
|
||||
bool HasReadWriteAccess(const Item & item);
|
||||
|
@ -99,6 +100,16 @@ public:
|
|||
void CheckAccessToItems(std::vector<Item> & item_tab);
|
||||
void CheckWriteAccessToItems(std::vector<Item> & item_tab);
|
||||
|
||||
/*
|
||||
this method checks the sticky bit and write permissions
|
||||
it returns true if we can remove/rename an item for the given child_item_user_id user id
|
||||
*/
|
||||
bool CanRemoveRenameChild(const Item & dir, long child_item_user_id);
|
||||
|
||||
int NewFilePrivileges();
|
||||
int NewDirPrivileges();
|
||||
|
||||
|
||||
bool CanUseHtml(long user_id);
|
||||
bool CanUseBBCode(long user_id);
|
||||
bool CanUseRaw(long user_id);
|
||||
|
@ -156,6 +167,9 @@ private:
|
|||
std::vector<Item*> root_follow_dir_tab;
|
||||
Item temp_follow_item;
|
||||
|
||||
bool HasAccess(const Item & item, int mask);
|
||||
int NewPrivileges(int creation_mask);
|
||||
|
||||
bool CreateNewFileSimpleFs(Item & item);
|
||||
bool CreateNewFileHashFs(Item & item);
|
||||
|
||||
|
|
|
@ -29,7 +29,12 @@ adduser.o: ../templates/htmltextstream.h ../core/mounts.h
|
|||
adduser.o: ../core/mountparser.h ../core/crypt.h ../core/users.h
|
||||
adduser.o: ../core/groups.h ../core/group.h ../core/loadavg.h ../core/image.h
|
||||
adduser.o: ../core/basethread.h ../core/threadmanager.h ../core/synchro.h
|
||||
adduser.o: ../core/slog.h
|
||||
adduser.o: ../core/slog.h ../core/plugin.h ../core/pluginmsg.h
|
||||
adduser.o: ../core/system.h ../core/sessionmanager.h
|
||||
adduser.o: ../core/sessioncontainer.h ../functions/functions.h
|
||||
adduser.o: ../templates/templates.h ../templates/patterncacher.h
|
||||
adduser.o: ../templates/indexpatterns.h ../templates/patterns.h
|
||||
adduser.o: ../templates/changepatterns.h ../core/sessionmanager.h
|
||||
cat.o: cat.h functionbase.h ../core/item.h ../db/db.h ../db/dbbase.h
|
||||
cat.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h
|
||||
cat.o: ../core/misc.h ../core/item.h ../core/requesttypes.h ../core/error.h
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "adduser.h"
|
||||
#include "core/slog.h"
|
||||
#include "core/plugin.h"
|
||||
|
||||
|
||||
|
||||
|
@ -112,10 +113,14 @@ void AddUser::MakePost()
|
|||
{
|
||||
if( system->users.AddUser(user) )
|
||||
{
|
||||
if( !cur->session->puser )
|
||||
system->users.LoginUser(user.id, false);
|
||||
|
||||
log << log2 << "AddUser: added a new user: " << user.name << logend;
|
||||
|
||||
if( !cur->session->puser )
|
||||
{
|
||||
system->users.LoginUser(user.id, false);
|
||||
log << log2 << "AddUser: now logged as: " << user.name << logend;
|
||||
plugin.Call(WINIX_USER_LOGGED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -127,7 +127,7 @@ void Emacs::MakePost()
|
|||
{
|
||||
cur->request->is_item = true; // !! moze lepiej nie ustawiac is_item? (bo jak wystapi blad np dodania do bazy danych
|
||||
// to formularz edycji zmieni sie z 'dodaj' na 'edytuj'
|
||||
cur->request->item.privileges = 0644; // !! tymczasowo, bedzie uzyte umask
|
||||
cur->request->item.privileges = system->NewFilePrivileges();
|
||||
cur->request->status = system->AddFile(cur->request->item, NotifyCodeAdd());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010-2011, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -19,8 +19,8 @@ FunctionBase::FunctionBase()
|
|||
|
||||
fun.user_id = -1;
|
||||
fun.group_id = -1;
|
||||
fun.privileges = 0755;
|
||||
fun.parent_id = -1; // !! temporarily doesn't matter
|
||||
fun.privileges = 07555;
|
||||
fun.parent_id = -1;
|
||||
fun.id = -1;
|
||||
fun.type = Item::file;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -37,7 +37,7 @@ void Ln::CreateSymbolicLink(const std::wstring & link_to)
|
|||
item.url = cur->request->PostVar(L"url");
|
||||
item.link_to = link_to;
|
||||
item.link_redirect = cur->request->IsPostVar(L"makeredirect") ? 1 : 0;
|
||||
item.privileges = 0644; // !! tymczasowo, bedzie uzyte umask
|
||||
item.privileges = system->NewFilePrivileges();
|
||||
functions->SetUser(item);
|
||||
functions->PrepareUrl(item);
|
||||
|
||||
|
@ -64,7 +64,7 @@ void Ln::CreateHardLink(const std::wstring & link_to)
|
|||
item.type = Item::file;
|
||||
item.parent_id = cur->request->dir_tab.back()->id;
|
||||
item.url = cur->request->PostVar(L"url");
|
||||
item.privileges = 0644; // !! tymczasowo, bedzie uzyte umask
|
||||
item.privileges = system->NewFilePrivileges();
|
||||
functions->SetUser(item);
|
||||
functions->PrepareUrl(item);
|
||||
cur->request->status = db->AddHardLink(item);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -79,7 +79,7 @@ void Mkdir::PostFunMkdir(bool add_to_dir_tab, int privileges)
|
|||
|
||||
void Mkdir::MakePost()
|
||||
{
|
||||
PostFunMkdir(false, 0755);
|
||||
PostFunMkdir(false, system->NewDirPrivileges());
|
||||
}
|
||||
|
||||
|
||||
|
|
719
functions/mv.cpp
719
functions/mv.cpp
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2011, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -21,87 +21,60 @@ Mv::Mv()
|
|||
{
|
||||
fun.url = L"mv";
|
||||
follow_symlinks = false;
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
|
||||
// !! CHECK ME
|
||||
// check if everywhere correct messages are sent (prepare_to, modified item/dir)
|
||||
|
||||
|
||||
bool Mv::HasAccess()
|
||||
{
|
||||
return CheckAccessFrom();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Mv::CheckAccessFromToDir()
|
||||
{
|
||||
Item * last;
|
||||
Item * last_but_one = 0;
|
||||
size_t dir_tab_size;
|
||||
|
||||
last = cur->request->dir_tab.back();
|
||||
dir_tab_size = cur->request->dir_tab.size();
|
||||
|
||||
if( dir_tab_size <= 1 )
|
||||
return false; // you cannot move the root directory
|
||||
|
||||
last_but_one = cur->request->dir_tab[dir_tab_size - 2];
|
||||
|
||||
if( cur->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) && !system->HasWriteAccess(*last_but_one) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// used in POST when the moving is performed
|
||||
|
||||
if( cur->request->IsPostVar(L"onlycontent") )
|
||||
return system->HasWriteAccess(*last);
|
||||
else
|
||||
return system->HasWriteAccess(*last_but_one);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Mv::CheckAccessFrom()
|
||||
{
|
||||
if( cur->request->is_item )
|
||||
{
|
||||
// moving a file
|
||||
|
||||
if( !system->HasWriteAccess(*cur->request->dir_tab.back()) )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
if( !system->CanRemoveRenameChild(*cur->request->dir_tab.back(), cur->request->item.user_id) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !CheckAccessFromToDir() )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
bool only_content = (cur->request->IsParam(L"c") || cur->request->IsPostVar(L"c"));
|
||||
|
||||
if( !CheckAccessFromToDir(*cur->request->dir_tab.back(), only_content) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::CheckAccessTo()
|
||||
bool Mv::CheckAccessFromToDir(const Item & dir, bool only_content)
|
||||
{
|
||||
if( dir_tab.empty() ||
|
||||
!system->HasReadExecAccessToPath(dir_tab) ||
|
||||
!system->HasWriteAccess(*dir_tab.back()) )
|
||||
if( dir.parent_id == -1 )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
if( !only_content )
|
||||
{
|
||||
// the root directory cannot be moved anywhere
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if( only_content )
|
||||
{
|
||||
// sticky bit for a specified child will be checked later
|
||||
if( !system->HasWriteAccess(dir) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Item * last_but_one_dir = system->dirs.GetDir(dir.parent_id);
|
||||
|
||||
if( !last_but_one_dir )
|
||||
// ops, there is no a parent dir
|
||||
return false;
|
||||
|
||||
if( !system->CanRemoveRenameChild(*last_but_one_dir, dir.user_id) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -111,21 +84,122 @@ return true;
|
|||
|
||||
|
||||
|
||||
|
||||
bool Mv::ParseDir()
|
||||
// !! IMPROVE ME: may a better name?
|
||||
void Mv::Prepare()
|
||||
{
|
||||
const std::wstring & new_dir = cur->request->PostVar(L"to");
|
||||
int res = system->dirs.FollowLink(cur->request->dir_tab, new_dir, dir_tab, file);
|
||||
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.sel_user_id = true;
|
||||
content_dir_iq.sel_group_id = true;
|
||||
content_dir_iq.sel_privileges = true;
|
||||
content_dir_iq.sel_meta = true;
|
||||
|
||||
if( res == 3 )
|
||||
cur->request->status = WINIX_ERR_NO_ROOT_DIR;
|
||||
files_iq.SetAll(false, false);
|
||||
files_iq.sel_parent_id = true;
|
||||
files_iq.sel_type = true;
|
||||
files_iq.sel_url = true;
|
||||
files_iq.sel_file = true;
|
||||
files_iq.sel_user_id = true;
|
||||
files_iq.sel_group_id = true;
|
||||
files_iq.sel_privileges = true;
|
||||
files_iq.sel_meta = true;
|
||||
files_iq.WhereType(Item::dir, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::Clear()
|
||||
{
|
||||
out_dir_tab.clear();
|
||||
out_item.Clear();
|
||||
out_filename.clear();
|
||||
files_item_tab.clear();
|
||||
item_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Mv::ParseDirCheckLastName()
|
||||
{
|
||||
if( out_has_file )
|
||||
{
|
||||
log << log1 << "Mv: incorrent path" << logend;
|
||||
slog << logerror << T("mv_incorrect_path") << logend;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Item * dir = system->dirs.GetDir(out_filename, out_dir_tab.back()->id);
|
||||
|
||||
if( dir )
|
||||
{
|
||||
out_dir_tab.push_back(dir);
|
||||
out_filename.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( db->GetItem(out_dir_tab.back()->id, out_filename, out_item) == WINIX_ERR_OK )
|
||||
{
|
||||
out_has_file = true;
|
||||
out_filename.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::ParseDir(const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( dst_path.empty() )
|
||||
return false;
|
||||
|
||||
// first we should remove the last name from the dst_path
|
||||
// (it may not exist in current file system and FollowAllLinks will fail)
|
||||
size_t last_slash = dst_path.find_last_of('/');
|
||||
out_path = dst_path;
|
||||
out_filename.clear();
|
||||
|
||||
if( last_slash != std::wstring::npos && last_slash + 1 < dst_path.size() )
|
||||
{
|
||||
out_path.erase(last_slash + 1); // leaving the slash at the end
|
||||
out_filename = dst_path.c_str() + last_slash + 1;
|
||||
}
|
||||
|
||||
int res = system->FollowAllLinks(cur->request->dir_tab, out_path, out_dir_tab, out_item, false, false, check_access);
|
||||
|
||||
if( res != 0 && res != 1 )
|
||||
cur->request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
|
||||
return res == 0 || res == 1;
|
||||
{
|
||||
slog << logerror << T("mv_incorrect_dst_path") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
out_has_file = (res == 1);
|
||||
|
||||
if( !out_filename.empty() )
|
||||
return ParseDirCheckLastName();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::CanRemoveRenameChild(const Item & child)
|
||||
{
|
||||
Item * parent_dir = system->dirs.GetDir(child.parent_id);
|
||||
|
||||
if( !parent_dir || !system->CanRemoveRenameChild(*parent_dir, child.user_id) )
|
||||
{
|
||||
log << log1 << "Mv: permission denied to: " << child.url << logend;
|
||||
slog << logerror << T("mv_permission_denied_to") << ": " << child.url << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mv::MoveStaticFile(const std::wstring & from, const std::wstring & to)
|
||||
|
@ -143,8 +217,8 @@ bool Mv::MoveStaticFile(const std::wstring & from, const std::wstring & to)
|
|||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Mv: can't move a file from: " << from << ", to: " << to << logend;
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log1 << "Mv: cannot move a static file from: " << from << ", to: " << to << logend;
|
||||
slog << logerror << T("internal_error") << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -155,124 +229,44 @@ void Mv::MoveStaticFile(Item & item)
|
|||
{
|
||||
bool res1, res2, res3, res4, res5;
|
||||
|
||||
res1 = system->MakeFilePath(item, old_path, false);
|
||||
res2 = !item.has_thumb || system->MakeFilePath(item, old_path_thumb, true);
|
||||
res1 = system->MakeFilePath(item, old_static_path, false);
|
||||
res2 = !item.has_thumb || system->MakeFilePath(item, old_static_thumb_path, 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);
|
||||
res4 = system->MakeFilePath(item, new_static_path, false, true, config->upload_dirs_chmod);
|
||||
res5 = !item.has_thumb || system->MakeFilePath(item, new_static_thumb_path, true, true, config->upload_dirs_chmod);
|
||||
|
||||
if( !res1 || !res2 || !res3 || !res4 || !res5 )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log1 << "Mv: cannot create a static path" << logend;
|
||||
slog << logerror << T("internal_error") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( MoveStaticFile(old_path, new_path) )
|
||||
if( MoveStaticFile(old_static_path, new_static_path) )
|
||||
{
|
||||
cur->request->status = db->EditFileById(item, item.id);
|
||||
if( db->EditFileById(item, item.id) != WINIX_ERR_OK )
|
||||
{
|
||||
log << log1 << "Mv: cannot move static file (database problem)" << logend;
|
||||
slog << logerror << T("internal_error") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( item.has_thumb )
|
||||
MoveStaticFile(old_path_thumb, new_path_thumb);
|
||||
MoveStaticFile(old_static_thumb_path, new_static_thumb_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Mv::MoveFileOrSymlink(Item & item)
|
||||
void Mv::MoveFilesPrepareTreeGo(const Item & src_dir)
|
||||
{
|
||||
plugin.Call(WINIX_FILE_PREPARE_TO_MOVE, &item);
|
||||
|
||||
old_url = item.url;
|
||||
|
||||
if( !file.empty() )
|
||||
{
|
||||
item.url = file;
|
||||
functions->PrepareUrl(item);
|
||||
file.clear();
|
||||
}
|
||||
|
||||
item.parent_id = dir_tab.back()->id;
|
||||
cur->request->status = db->EditParentUrlById(item, item.id);
|
||||
|
||||
if( cur->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);
|
||||
|
||||
plugin.Call(WINIX_FILE_MOVED, &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;
|
||||
|
||||
files_iq.SetAll(false, false);
|
||||
files_iq.sel_parent_id = true;
|
||||
files_iq.sel_type = true;
|
||||
files_iq.sel_url = true;
|
||||
files_iq.sel_file = true;
|
||||
files_iq.WhereType(Item::dir, false);
|
||||
}
|
||||
|
||||
|
||||
void Mv::Clear()
|
||||
{
|
||||
dir_tab.clear();
|
||||
files_item_tab.clear();
|
||||
item_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
void Mv::MoveFilesPrepareTree(const Item & dir)
|
||||
{
|
||||
// we only calling plugins here
|
||||
// so if there is no WINIX_FILE_PREPARE_TO_MOVE message
|
||||
// we can immediately return and the database will not be bothered
|
||||
if( !plugin.HasMessage(WINIX_FILE_PREPARE_TO_MOVE) )
|
||||
return;
|
||||
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(dir.id);
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(src_dir.id);
|
||||
|
||||
// go through all directories
|
||||
for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextChild(i) )
|
||||
MoveFilesPrepareTree(*(i->second));
|
||||
|
||||
files_iq.WhereParentId(dir.id);
|
||||
files_iq.WhereParentId(src_dir.id);
|
||||
db->GetItems(files_item_tab, files_iq);
|
||||
|
||||
for(size_t i=0 ; i<files_item_tab.size() ; ++i)
|
||||
|
@ -280,6 +274,20 @@ void Mv::MoveFilesPrepareTree(const Item & dir)
|
|||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveFilesPrepareTree(const Item & src_dir)
|
||||
{
|
||||
// we only calling plugins here
|
||||
// so if there is no WINIX_FILE_PREPARE_TO_MOVE message
|
||||
// we can immediately return and the database will not be bothered
|
||||
if( plugin.HasMessage(WINIX_FILE_PREPARE_TO_MOVE) )
|
||||
{
|
||||
MoveFilesPrepareTree(src_dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveFilesTree(const Item & dir)
|
||||
{
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(dir.id);
|
||||
|
@ -294,69 +302,193 @@ void Mv::MoveFilesTree(const Item & dir)
|
|||
for(size_t i=0 ; i<files_item_tab.size() ; ++i)
|
||||
{
|
||||
if( files_item_tab[i].file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
{
|
||||
plugin.Call(WINIX_FILE_PREPARE_TO_MOVE, &files_item_tab[i]);
|
||||
MoveStaticFile(files_item_tab[i]);
|
||||
|
||||
plugin.Call(WINIX_FILE_MOVED, &files_item_tab[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::MoveDir(Item & dir)
|
||||
|
||||
|
||||
// private
|
||||
// uses: out_dir_tab, out_filename
|
||||
bool Mv::MoveDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, const std::wstring & dst_name)
|
||||
{
|
||||
long dst_dir_id = dir_tab.back()->id;
|
||||
old_url = dir.url;
|
||||
long dst_dir_id = dst_dir_tab.back()->id;
|
||||
old_url = src_dir.url;
|
||||
|
||||
if( dst_dir_id == dir.id || system->dirs.HasParent(dst_dir_id, dir.id) )
|
||||
if( dst_dir_id == src_dir.id || system->dirs.HasParent(dst_dir_id, src_dir.id) )
|
||||
{
|
||||
log << log1 << "Mv: cannot move directory to inside it" << logend;
|
||||
cur->request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
return;
|
||||
slog << logerror << T("mv_cannot_move_to_inside");
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveFilesPrepareTree(dir);
|
||||
MoveFilesPrepareTree(src_dir);
|
||||
|
||||
if( !system->dirs.ChangeParent(dir.id, dst_dir_id) )
|
||||
if( !system->dirs.ChangeParent(src_dir.id, dst_dir_id) )
|
||||
return false;
|
||||
|
||||
src_dir.parent_id = dst_dir_id;
|
||||
old_url = src_dir.url;
|
||||
|
||||
if( !dst_name.empty() )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
return;
|
||||
src_dir.url = dst_name;
|
||||
functions->PrepareUrl(src_dir);
|
||||
}
|
||||
|
||||
dir.parent_id = dst_dir_id;
|
||||
Error status = db->EditParentUrlById(src_dir, src_dir.id);
|
||||
|
||||
if( !file.empty() )
|
||||
{
|
||||
dir.url = file;
|
||||
functions->PrepareUrl(dir);
|
||||
file.clear();
|
||||
}
|
||||
|
||||
cur->request->status = db->EditParentUrlById(dir, dir.id);
|
||||
|
||||
if( cur->request->status == WINIX_ERR_OK )
|
||||
if( status == WINIX_ERR_OK )
|
||||
{
|
||||
log << log3 << "Mv: directory: " << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dir_tab);
|
||||
log << dir.url << logend;
|
||||
system->dirs.LogDir(dst_dir_tab);
|
||||
log << src_dir.url << logend;
|
||||
|
||||
MoveFilesTree(dir);
|
||||
MoveFilesTree(src_dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Mv::IsTheSameFile(const Item & item)
|
||||
// public
|
||||
bool Mv::MoveDir(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( file.empty() )
|
||||
{
|
||||
if( item.parent_id == dir_tab.back()->id )
|
||||
return true; // nothing to do
|
||||
bool res = MoveDir2(src_dir, dst_dir_id, new_url, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// private
|
||||
bool Mv::MoveDir2(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "Mv: a directory required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "Mv: the root directory cannot be moved anywhere" << logend;
|
||||
slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_dir) )
|
||||
return false;
|
||||
|
||||
if( src_dir.id == dst_dir_id )
|
||||
{
|
||||
if( new_url.empty() || src_dir.url == new_url )
|
||||
return true; // the same directory -- there is nothing to do
|
||||
}
|
||||
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
{
|
||||
log << log1 << "Mv: incorrect directory" << logend;
|
||||
slog << logerror << T("mv_incorrect_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
return MoveDir(src_dir, out_dir_tab, new_url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public
|
||||
bool Mv::MoveDir(Item & src_dir, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
bool res = MoveDir2(src_dir, dst_path, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// private
|
||||
bool Mv::MoveDir2(Item & src_dir, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "Mv: a directory required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "Mv: the root directory cannot be moved anywhere" << logend;
|
||||
slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_dir) )
|
||||
return false;
|
||||
|
||||
if( !ParseDir(dst_path, check_access) )
|
||||
return false;
|
||||
|
||||
if( out_has_file )
|
||||
{
|
||||
log << log1 << "Mv: directory can be moved only to a directory" << logend;
|
||||
slog << logerror << T("mv_dir_can_be_moved_to_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.id == out_dir_tab.back()->id )
|
||||
{
|
||||
if( out_filename.empty() || src_dir.url == out_filename )
|
||||
return true; // the same directory -- there is nothing to do
|
||||
}
|
||||
|
||||
return MoveDir(src_dir, out_dir_tab, out_filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// private
|
||||
bool Mv::MoveFileOrSymlink(Item & src_file, std::vector<Item*> & dst_dir_tab, const std::wstring & new_url)
|
||||
{
|
||||
plugin.Call(WINIX_FILE_PREPARE_TO_MOVE, &src_file);
|
||||
|
||||
old_url = src_file.url;
|
||||
|
||||
if( !new_url.empty() )
|
||||
{
|
||||
src_file.url = new_url;
|
||||
functions->PrepareUrl(src_file);
|
||||
}
|
||||
|
||||
src_file.parent_id = dst_dir_tab.back()->id;
|
||||
Error status = db->EditParentUrlById(src_file, src_file.id);
|
||||
|
||||
if( status == WINIX_ERR_OK )
|
||||
{
|
||||
if( src_file.type == Item::file )
|
||||
log << log3 << "Mv: file: ";
|
||||
else
|
||||
{
|
||||
if( item.parent_id == dir_tab.back()->id && item.url == file )
|
||||
return true; // nothing to do
|
||||
log << log3 << "Mv: symlink: ";
|
||||
|
||||
log << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dst_dir_tab);
|
||||
log << src_file.url << logend;
|
||||
|
||||
if( src_file.file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
MoveStaticFile(src_file);
|
||||
|
||||
plugin.Call(WINIX_FILE_MOVED, &src_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -364,48 +496,164 @@ return false;
|
|||
|
||||
|
||||
|
||||
void Mv::PostMoveFile()
|
||||
// public
|
||||
bool Mv::MoveFileOrSymlink(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( IsTheSameFile(cur->request->item) )
|
||||
return;
|
||||
bool res = MoveFileOrSymlink2(src_file, dst_dir_id, new_url, check_access);
|
||||
Clear();
|
||||
|
||||
MoveFileOrSymlink(cur->request->item);
|
||||
return res;
|
||||
}
|
||||
|
||||
if( cur->request->status == WINIX_ERR_OK )
|
||||
system->RedirectTo(cur->request->item);
|
||||
|
||||
// private
|
||||
bool Mv::MoveFileOrSymlink2(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( src_file.type == Item::dir )
|
||||
{
|
||||
log << "Mv: a file/symlink required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_file) )
|
||||
return false;
|
||||
|
||||
if( src_file.parent_id == dst_dir_id )
|
||||
{
|
||||
if( new_url.empty() || src_file.url == new_url )
|
||||
return true; // the same file -- there is nothing to do
|
||||
}
|
||||
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
return false;
|
||||
|
||||
return MoveFileOrSymlink(src_file, out_dir_tab, new_url);
|
||||
}
|
||||
|
||||
|
||||
// public
|
||||
bool Mv::MoveFileOrSymlink(Item & src_file, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
bool res = MoveFileOrSymlink2(src_file, dst_path, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// private
|
||||
bool Mv::MoveFileOrSymlink2(Item & src_file, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( src_file.type == Item::dir )
|
||||
{
|
||||
log << "Mv: a file/symlink required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_file) )
|
||||
return false;
|
||||
|
||||
if( !ParseDir(dst_path, check_access) )
|
||||
return false;
|
||||
|
||||
if( src_file.parent_id == out_dir_tab.back()->id )
|
||||
{
|
||||
// actually out_filename is here empty
|
||||
// because ParseDir() have been read it to out_item
|
||||
if( out_filename.empty() || src_file.url == out_filename )
|
||||
return true; // the same file -- there is nothing to do
|
||||
}
|
||||
|
||||
return MoveFileOrSymlink(src_file, out_dir_tab, out_filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::PostMoveDirContent()
|
||||
// private
|
||||
void Mv::MoveAllFilesFromDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, bool check_access)
|
||||
{
|
||||
if( !file.empty() )
|
||||
content_dir_iq.WhereParentId(src_dir.id);
|
||||
db->GetItems(item_tab, content_dir_iq);
|
||||
out_filename.clear();
|
||||
|
||||
for(size_t i=0 ; i<item_tab.size() ; ++i)
|
||||
{
|
||||
cur->request->status = WINIX_ERR_INCORRECT_DIR;
|
||||
if( check_access && !system->CanRemoveRenameChild(src_dir, item_tab[i].user_id) )
|
||||
{
|
||||
log << log1 << "Mv: permission denied to: " << src_dir.url << logend;
|
||||
slog << logerror << T("mv_permission_denied_to") << ": " << src_dir.url << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item_tab[i].type == Item::dir )
|
||||
MoveDir(item_tab[i], dst_dir_tab, out_filename);
|
||||
else
|
||||
MoveFileOrSymlink(item_tab[i], dst_dir_tab, out_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public
|
||||
void Mv::MoveDirContent(Item & src_dir, long dst_dir_id, bool check_access)
|
||||
{
|
||||
MoveDirContent2(src_dir, dst_dir_id, check_access);
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// private
|
||||
void Mv::MoveDirContent2(Item & src_dir, long dst_dir_id, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "Mv: a directory required" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( cur->request->dir_tab.back()->id == dir_tab.back()->id )
|
||||
return; // nothing to do
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "Mv: the root directory cannot be moved anywhere" << logend;
|
||||
slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
MoveDirContent(*cur->request->dir_tab.back());
|
||||
system->RedirectToLastDir();
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
{
|
||||
log << log1 << "Mv: incorrect directory" << logend;
|
||||
slog << logerror << T("mv_incorrect_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
MoveAllFilesFromDir(src_dir, out_dir_tab, check_access);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Mv::PostMoveDir()
|
||||
// public
|
||||
void Mv::MoveDirContent(Item & src_dir, const std::wstring & dst_dir, bool check_access)
|
||||
{
|
||||
Item & last_dir = *cur->request->dir_tab.back();
|
||||
Item & new_dir = *dir_tab.back();
|
||||
MoveDirContent2(src_dir, dst_dir, check_access);
|
||||
Clear();
|
||||
}
|
||||
|
||||
if( file.empty() && new_dir.id == last_dir.id )
|
||||
return; // nothing to do
|
||||
|
||||
MoveDir(last_dir);
|
||||
// private
|
||||
void Mv::MoveDirContent2(Item & src_dir, const std::wstring & dst_dir, bool check_access)
|
||||
{
|
||||
if( !ParseDir(dst_dir, check_access) )
|
||||
return;
|
||||
|
||||
if( cur->request->status == WINIX_ERR_OK )
|
||||
system->RedirectToLastDir();
|
||||
if( out_has_file || !out_filename.empty() )
|
||||
{
|
||||
log << log1 << "Mv: directory content can be moved only to a directory" << logend;
|
||||
slog << logerror << T("mv_dir_content_can_be_moved_to_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
MoveDirContent2(src_dir, out_dir_tab.back()->id, check_access);
|
||||
}
|
||||
|
||||
|
||||
|
@ -413,26 +661,23 @@ void Mv::PostMoveDir()
|
|||
|
||||
void Mv::MakePost()
|
||||
{
|
||||
if( CheckAccessFrom() &&
|
||||
ParseDir() &&
|
||||
CheckAccessTo() )
|
||||
{
|
||||
Prepare();
|
||||
const std::wstring & dst_path = cur->request->PostVar(L"dst_path");
|
||||
bool ok = true;
|
||||
|
||||
if( cur->request->is_item )
|
||||
{
|
||||
PostMoveFile();
|
||||
ok = MoveFileOrSymlink(cur->request->item, dst_path, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cur->request->IsPostVar(L"onlycontent") )
|
||||
PostMoveDirContent();
|
||||
if( cur->request->IsParam(L"c") || cur->request->IsPostVar(L"c") )
|
||||
MoveDirContent(*cur->request->dir_tab.back(), dst_path, true);
|
||||
else
|
||||
PostMoveDir();
|
||||
ok = MoveDir(*cur->request->dir_tab.back(), dst_path, true);
|
||||
}
|
||||
|
||||
Clear();
|
||||
}
|
||||
if( ok )
|
||||
system->RedirectToLastItem();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -28,46 +28,74 @@ public:
|
|||
bool HasAccess();
|
||||
void MakePost();
|
||||
|
||||
// moving a directory
|
||||
// new_url can be empty (in such a case the old one is preserved)
|
||||
// src_dir will be accordingly updated
|
||||
bool MoveDir(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access = true);
|
||||
bool MoveDir(Item & src_dir, const std::wstring & dst_path, bool check_access = true);
|
||||
|
||||
// moving only the content of src_dir
|
||||
// dst_path should point to an existing directory
|
||||
// src_dir will be accordingly updated
|
||||
void MoveDirContent(Item & src_dir, long dst_dir_id, bool check_access = true);
|
||||
void MoveDirContent(Item & src_dir, const std::wstring & dst_dir, bool check_access = true);
|
||||
|
||||
// moving a file
|
||||
// new_url can be empty (the old one is used then)
|
||||
// src_file will be accordingly updated
|
||||
bool MoveFileOrSymlink(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access = true);
|
||||
bool MoveFileOrSymlink(Item & src_file, const std::wstring & dst_path, bool check_access = true);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// destination dir
|
||||
std::vector<Item*> dir_tab;
|
||||
|
||||
// destination file (if exists)
|
||||
std::wstring file;
|
||||
// directories parsed by ParseDir()
|
||||
std::vector<Item*> out_dir_tab; // destination directories
|
||||
Item out_item; // destination file/symlink (if out_has_file is true)
|
||||
bool out_has_file; // if true then out_item is set
|
||||
std::wstring out_filename; // the last part in an input path (not an existing directory, file or symlink)
|
||||
// can be empty
|
||||
|
||||
// for copying static files
|
||||
std::wstring new_path, new_path_thumb;
|
||||
std::wstring old_path, old_path_thumb;
|
||||
// temporaries
|
||||
std::wstring out_path;
|
||||
std::wstring old_url;
|
||||
|
||||
// for files in a directory
|
||||
std::wstring old_static_path;
|
||||
std::wstring old_static_thumb_path;
|
||||
std::wstring new_static_path;
|
||||
std::wstring new_static_thumb_path;
|
||||
|
||||
// for files/symlinks in a directory
|
||||
std::vector<Item> files_item_tab;
|
||||
DbItemQuery files_iq;
|
||||
|
||||
// for moving content of a directory
|
||||
// for moving content of a directory (all dirs/files/symlinks)
|
||||
DbItemQuery content_dir_iq;
|
||||
std::vector<Item> item_tab;
|
||||
|
||||
// for logging
|
||||
std::wstring old_url;
|
||||
|
||||
bool CheckAccessFromToDir();
|
||||
bool CheckAccessFrom();
|
||||
bool CheckAccessTo();
|
||||
bool ParseDir();
|
||||
bool CheckAccessFromToDir(const Item & dir, bool only_content);
|
||||
bool CanRemoveRenameChild(const Item & child);
|
||||
void Prepare();
|
||||
bool ParseDirCheckLastName();
|
||||
bool ParseDir(const std::wstring & dst_path, bool check_access);
|
||||
bool MoveStaticFile(const std::wstring & from, const std::wstring & to);
|
||||
void MoveStaticFile(Item & item);
|
||||
void MoveFileOrSymlink(Item & item);
|
||||
void MoveDirContent(const Item & dir);
|
||||
void Prepare();
|
||||
void Clear();
|
||||
void MoveFilesPrepareTree(const Item & dir);
|
||||
void MoveFilesPrepareTreeGo(const Item & src_dir);
|
||||
void MoveFilesPrepareTree(const Item & src_dir);
|
||||
void MoveFilesTree(const Item & dir);
|
||||
void MoveDir(Item & dir);
|
||||
bool IsTheSameFile(const Item & item);
|
||||
void PostMoveFile();
|
||||
void PostMoveDirContent();
|
||||
void PostMoveDir();
|
||||
bool MoveDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, const std::wstring & dst_name);
|
||||
bool MoveFileOrSymlink(Item & src_file, std::vector<Item*> & dst_dir_tab, const std::wstring & new_url);
|
||||
void Clear();
|
||||
bool MoveDir2(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access);
|
||||
bool MoveDir2(Item & src_dir, const std::wstring & dst_path, bool check_access);
|
||||
bool MoveFileOrSymlink2(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access);
|
||||
bool MoveFileOrSymlink2(Item & src_file, const std::wstring & dst_path, bool check_access);
|
||||
void MoveDirContent2(Item & src_dir, long dst_dir_id, bool check_access);
|
||||
void MoveAllFilesFromDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, bool check_access);
|
||||
void MoveDirContent2(Item & src_dir, const std::wstring & dst_dir, bool check_access);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -51,13 +51,13 @@ bool PrivChanger::ChangeOwner(Item & item, long user_id, long group_id)
|
|||
{
|
||||
if( !system->CanChangeUser(item, user_id) )
|
||||
{
|
||||
log << log3 << "Content: can't change the user" << logend;
|
||||
log << log3 << "Priv: can't change the user" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !system->CanChangeGroup(item, group_id) )
|
||||
{
|
||||
log << log3 << "Content: can't change the group" << logend;
|
||||
log << log3 << "Priv: can't change the group" << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ bool PrivChanger::ChangePrivileges(Item & item, int privileges)
|
|||
{
|
||||
if( !system->CanChangePrivileges(item, privileges) )
|
||||
{
|
||||
log << log3 << "Content: can't change privileges" << logend;
|
||||
log << log3 << "Priv: can't change privileges" << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ Item * root = 0;
|
|||
if( id != -1 )
|
||||
root = system->dirs.GetRootDir();
|
||||
|
||||
log << log3 << "Content: " << what;
|
||||
log << log3 << "Priv: " << what;
|
||||
|
||||
if( root && root->id == id )
|
||||
log << "(root)";
|
||||
|
@ -169,7 +169,7 @@ void PrivChanger::PrivFilesInDir(long parent_id)
|
|||
DbItemQuery iq;
|
||||
|
||||
iq.SetAll(false, false);
|
||||
iq.sel_user_id = iq.sel_group_id = iq.sel_guest_name = iq.sel_privileges = true;
|
||||
iq.sel_user_id = iq.sel_group_id = iq.sel_guest_name = iq.sel_privileges = iq.sel_url = true;
|
||||
|
||||
iq.WhereParentId(parent_id);
|
||||
iq.WhereType(Item::dir, false);
|
||||
|
@ -230,8 +230,8 @@ void PrivChanger::PrivDir()
|
|||
ReadPriv(L"userfile", L"groupfile", L"privilegesfile", user_id_file, group_id_file, priv_file);
|
||||
ReadPriv(L"userdir", L"groupdir", L"privilegesdir", user_id_dir, group_id_dir, priv_dir);
|
||||
|
||||
PrivLogStart(L"Content: changes for files: ", user_id_file, group_id_file, priv_file);
|
||||
PrivLogStart(L"Content: changes for dirs: ", user_id_dir, group_id_dir, priv_dir);
|
||||
PrivLogStart(L"Priv: changes for files: ", user_id_file, group_id_file, priv_file);
|
||||
PrivLogStart(L"Priv: changes for dirs: ", user_id_dir, group_id_dir, priv_dir);
|
||||
|
||||
|
||||
if( cur->request->IsPostVar(L"changecurrentdir") )
|
||||
|
@ -256,7 +256,7 @@ void PrivChanger::PrivDir()
|
|||
void PrivChanger::PrivOneItem()
|
||||
{
|
||||
ReadPriv(L"user", L"group", L"privileges", user_id_file, group_id_file, priv_file);
|
||||
PrivLogStart(L"Content: changes: ", user_id_file, group_id_file, priv_file);
|
||||
PrivLogStart(L"Priv: changes: ", user_id_file, group_id_file, priv_file);
|
||||
|
||||
if( cur->request->is_item )
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -18,10 +18,17 @@ namespace Fun
|
|||
Reload::Reload()
|
||||
{
|
||||
fun.url = L"reload";
|
||||
fun.privileges = 0700;
|
||||
fun.privileges = 07000;
|
||||
}
|
||||
|
||||
|
||||
bool Reload::HasAccess()
|
||||
{
|
||||
return cur->session->puser && cur->session->puser->super_user;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Reload::FunReloadTemplates()
|
||||
{
|
||||
log << log1 << "Content: reloading html templates" << logend;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@ class Reload : public FunctionBase
|
|||
public:
|
||||
|
||||
Reload();
|
||||
bool HasAccess();
|
||||
void MakeGet();
|
||||
|
||||
private:
|
||||
|
|
325
functions/rm.cpp
325
functions/rm.cpp
|
@ -2,13 +2,12 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <errno.h>
|
||||
#include "rm.h"
|
||||
#include "core/plugin.h"
|
||||
#include "core/misc.h"
|
||||
|
@ -27,49 +26,70 @@ Rm::Rm()
|
|||
|
||||
|
||||
|
||||
bool Rm::HasAccess(const Item & item)
|
||||
bool Rm::HasAccessToDir(const Item & dir, bool only_content)
|
||||
{
|
||||
// !! 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 )
|
||||
if( dir.parent_id == -1 )
|
||||
{
|
||||
// this is a root directory
|
||||
// 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) )
|
||||
// sticky bit for a specified child will be checked later
|
||||
if( !only_content || !system->HasWriteAccess(dir) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
if( only_content )
|
||||
{
|
||||
// sticky bit for a specified child will be checked later
|
||||
if( !system->HasWriteAccess(dir) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Item * last_but_one_dir = system->dirs.GetDir(item.parent_id);
|
||||
Item * last_but_one_dir = system->dirs.GetDir(dir.parent_id);
|
||||
|
||||
if( !last_but_one_dir )
|
||||
// ops, there is no a parent dir
|
||||
return false;
|
||||
|
||||
if( !system->HasWriteAccess(*last_but_one_dir) )
|
||||
if( !system->CanRemoveRenameChild(*last_but_one_dir, dir.user_id) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( system->mounts.pmount->IsPar(system->mounts.MountParOnlyRootRemove()) )
|
||||
if( !cur->session->puser || !cur->session->puser->super_user )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
here we are making a little test -- this method returns false if
|
||||
we are sure that the permissions is not allowed (consequently the html form
|
||||
will not be displayed)
|
||||
the correct checking for permissions is done later in MakePost() method
|
||||
|
||||
parameter 'c' to rm function means removing only the content of a directory
|
||||
this parameter can be sent either by a get or a post variable
|
||||
*/
|
||||
bool Rm::HasAccess()
|
||||
{
|
||||
bool res;
|
||||
|
||||
if( !cur->request->is_item )
|
||||
res = HasAccess(*cur->request->dir_tab.back());
|
||||
if( cur->request->is_item )
|
||||
{
|
||||
res = system->CanRemoveRenameChild(*cur->request->dir_tab.back(), cur->request->item.user_id);
|
||||
}
|
||||
else
|
||||
res = HasAccess(cur->request->item);
|
||||
{
|
||||
if( cur->request->IsParam(L"r") )
|
||||
{
|
||||
bool only_content = (cur->request->IsParam(L"c") || cur->request->IsPostVar(L"c"));
|
||||
res = HasAccessToDir(*cur->request->dir_tab.back(), only_content);
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log3 << "Rm: directories can be removed only with 'r' parameter" << logend;
|
||||
slog << logerror << T("rm_use_r_option") << logend;
|
||||
}
|
||||
}
|
||||
|
||||
if( !res && cur->request->IsParam(L"jquery_upload") )
|
||||
CreateJSON(res);
|
||||
|
@ -87,62 +107,66 @@ void Rm::Prepare()
|
|||
content_dir_iq.sel_type = true;
|
||||
content_dir_iq.sel_url = true;
|
||||
content_dir_iq.sel_file = true;
|
||||
content_dir_iq.sel_user_id = true;
|
||||
content_dir_iq.sel_group_id = true;
|
||||
content_dir_iq.sel_privileges = true;
|
||||
content_dir_iq.sel_meta = 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)
|
||||
|
||||
void Rm::RemoveStaticFile(const std::wstring & path)
|
||||
{
|
||||
if( ::RemoveFile(path) )
|
||||
{
|
||||
log << log2 << "Rm: removed static file: " << path << logend;
|
||||
return true;
|
||||
log << log2 << "Rm: static file removed: " << path << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Rm: can't remove a file: " << path << logend;
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
return false;
|
||||
log << log1 << "Rm: I can't remove a static file: " << path << logend;
|
||||
slog << logerror << T("rm_cannot_remove_static_file") << ": " << path << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rm::RemoveStaticFile(Item & item)
|
||||
|
||||
void Rm::RemoveStaticFile(const Item & item)
|
||||
{
|
||||
if( system->MakeFilePath(item, path, false) )
|
||||
{
|
||||
if( RemoveStaticFile(path) )
|
||||
{
|
||||
if( item.has_thumb && system->MakeFilePath(item, path, true) )
|
||||
RemoveStaticFile(path);
|
||||
|
||||
// we don't change item.file_path and others file_* variables
|
||||
// they can be used by a plugin
|
||||
}
|
||||
if( item.has_thumb && system->MakeFilePath(item, path, true) )
|
||||
RemoveStaticFile(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log1 << "Rm: I cannot create a path to a static file, url: "
|
||||
<< item.url << ", id: " << item.id << logend;
|
||||
|
||||
slog << logerror << T("rm_cannot_create_static_path") << ": " << item.url << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveFileOrSymlink(Item & item)
|
||||
/*
|
||||
!! IMPROVE ME:
|
||||
plugin.Call(WINIX_FILE_REMOVED, &item) is getting its parameter as non-const
|
||||
in the future we can add a pointer cp1, cp2 (in plugins) but pointing to a const object
|
||||
and this bool Rm::RemoveFile(Item & item) can became bool Rm::RemoveFile(const Item & item)
|
||||
*/
|
||||
bool Rm::RemoveFile(Item & item)
|
||||
{
|
||||
plugin.Call(WINIX_FILE_PREPARE_TO_REMOVE, &item);
|
||||
|
||||
if( db->DelItem(item) == WINIX_ERR_OK )
|
||||
{
|
||||
if( item.type == Item::file )
|
||||
log << log2 << "Rm: deleted file ";
|
||||
log << log2 << "Rm: deleted file: ";
|
||||
else
|
||||
log << log2 << "Rm: deleted symlink ";
|
||||
log << log2 << "Rm: deleted symlink: ";
|
||||
|
||||
log << item.url << logend;
|
||||
|
||||
|
@ -152,13 +176,47 @@ void Rm::RemoveFileOrSymlink(Item & item)
|
|||
RemoveStaticFile(item);
|
||||
|
||||
plugin.Call(WINIX_FILE_REMOVED, &item);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
we do not modify item
|
||||
it is non-const because we use plugin.Call() later with a pointer to this structure
|
||||
(and we want to avoid casting)
|
||||
*/
|
||||
bool Rm::RemoveFileOrSymlink(Item & item, bool check_access)
|
||||
{
|
||||
if( item.type == Item::dir )
|
||||
return false;
|
||||
|
||||
if( check_access )
|
||||
{
|
||||
Item * dir = system->dirs.GetDir(item.parent_id);
|
||||
|
||||
// if there is not 'dir' directory then we can simply remove 'item'
|
||||
if( dir )
|
||||
{
|
||||
if( !system->CanRemoveRenameChild(*dir, item.user_id) )
|
||||
{
|
||||
log << log1 << "Rm: permission denied to remove: " << item.url << ", id: " << item.id << logend;
|
||||
slog << logerror << T("rm_permission_denied_to") << ": " << item.url << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RemoveFile(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for other uses (plugins etc)
|
||||
void Rm::RemoveItemById(long item_id)
|
||||
void Rm::RemoveItemById(long item_id, bool check_access)
|
||||
{
|
||||
// selecting files, symlinks and directories
|
||||
rm_by_id_iq.SetAll(false, false);
|
||||
|
@ -166,107 +224,161 @@ void Rm::RemoveItemById(long item_id)
|
|||
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.sel_user_id = true;
|
||||
rm_by_id_iq.sel_group_id = true;
|
||||
rm_by_id_iq.sel_privileges = true;
|
||||
rm_by_id_iq.sel_meta = 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);
|
||||
RemoveDirTree(rm_by_id_item, true, check_access);
|
||||
else
|
||||
RemoveFileOrSymlink(rm_by_id_item);
|
||||
RemoveFileOrSymlink(rm_by_id_item, check_access);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rm::RemoveDirTree(long dir_id)
|
||||
|
||||
bool Rm::RemoveDirFiles(long dir_id, bool check_access)
|
||||
{
|
||||
DirContainer::ParentIterator pnext, p = system->dirs.FindFirstChild(dir_id);
|
||||
|
||||
for( ; p != system->dirs.ParentEnd() ; p = pnext )
|
||||
{
|
||||
plugin.Call(WINIX_DIR_PREPARE_TO_REMOVE, &(*p->second));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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]);
|
||||
size_t removed = 0;
|
||||
|
||||
if( db->DelDirById(dir_id) == WINIX_ERR_OK )
|
||||
for(size_t i=0 ; i<content_item_tab.size() ; ++i)
|
||||
if( RemoveFileOrSymlink(content_item_tab[i], check_access) )
|
||||
removed += 1;
|
||||
|
||||
return removed == content_item_tab.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
parent_dir can be null (when current_dir is the root directory)
|
||||
*/
|
||||
void Rm::RemoveCurrentDir(Item * parent_dir, Item * current_dir, bool check_access)
|
||||
{
|
||||
if( check_access )
|
||||
{
|
||||
if( !parent_dir || !system->CanRemoveRenameChild(*parent_dir, current_dir->user_id) )
|
||||
{
|
||||
log << log1 << "Rm: permission denied to directory: " << current_dir->url << logend;
|
||||
slog << logerror << T("rm_permission_denied_to") << ": " << current_dir->url << logend;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plugin.Call(WINIX_DIR_PREPARE_TO_REMOVE, current_dir);
|
||||
|
||||
if( db->DelDirById(current_dir->id) == WINIX_ERR_OK )
|
||||
{
|
||||
long dir_id = current_dir->id;
|
||||
old_url = current_dir->url;
|
||||
system->dirs.DelDir(dir_id);
|
||||
// don't use current_dir pointer anymore
|
||||
log << log2 << "Rm: directory removed: " << old_url << logend;
|
||||
plugin.Call(WINIX_DIR_REMOVED, dir_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveDir(const Item & dir)
|
||||
{
|
||||
plugin.Call(WINIX_DIR_PREPARE_TO_REMOVE, const_cast<Item*>(&dir));
|
||||
|
||||
old_url = dir.url;
|
||||
RemoveDirTree(dir.id);
|
||||
|
||||
// warning: 'dir' has been deleted so don't use the 'dir' reference
|
||||
|
||||
if( cur->request->status == WINIX_ERR_OK )
|
||||
log << log3 << "Rm: removed directory " << old_url << logend;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveFile()
|
||||
{
|
||||
RemoveFileOrSymlink(cur->request->item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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]);
|
||||
{
|
||||
log << log1 << "Rm: I cannot remove a directory: " << current_dir->url << " (database error)" << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
parent_dir can be null (when current_dir is pointing to the root directory)
|
||||
current_dir is pointing to the directory which should be deleted
|
||||
(contents of this directory is removed but the directory is deleted only if remove_this_dir is true)
|
||||
*/
|
||||
void Rm::RemoveDirTree(Item * parent_dir, Item * current_dir, bool remove_this_dir, bool check_access)
|
||||
{
|
||||
if( check_access && !system->HasReadExecAccess(*current_dir) )
|
||||
{
|
||||
log << log1 << "Rm: permission denied to directory: " << current_dir->url << logend;
|
||||
slog << logerror << T("rm_permission_denied_to") << ": " << current_dir->url << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
DirContainer::ParentIterator pnext, p = system->dirs.FindFirstChild(current_dir->id);
|
||||
|
||||
for( ; p != system->dirs.ParentEnd() ; p = pnext )
|
||||
{
|
||||
Item * child_dir = &(*p->second);
|
||||
|
||||
// this iterator p will be invalidated by the below RemoveDirTree() call
|
||||
// (the next iterator we must calculate beforehand)
|
||||
pnext = system->dirs.NextChild(p);
|
||||
RemoveDirTree(current_dir, child_dir, true, check_access);
|
||||
}
|
||||
|
||||
bool all_file_removed = RemoveDirFiles(current_dir->id, check_access);
|
||||
|
||||
if( remove_this_dir )
|
||||
{
|
||||
if( all_file_removed )
|
||||
{
|
||||
RemoveCurrentDir(parent_dir, current_dir, check_access);
|
||||
// don't use current_dir pointer anymore
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Rm: " << current_dir->url << " directory not empty" << logend;
|
||||
slog << logerror << current_dir->url << T("rm_directory_not_empty") << logend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveDirTree(Item & dir, bool remove_this_dir, bool check_access)
|
||||
{
|
||||
Item * parent = system->dirs.GetDir(dir.parent_id);
|
||||
RemoveDirTree(parent, &dir, remove_this_dir, check_access);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveDirContent()
|
||||
{
|
||||
if( !cur->request->IsParam(L"r") )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log3 << "Rm: directory content can be removed only with 'r' parameter" << logend;
|
||||
slog << logerror << T("rm_content_use_r_option") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveDirContent(*cur->request->dir_tab.back());
|
||||
RemoveDirTree(*cur->request->dir_tab.back(), false, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rm::RemoveDir()
|
||||
{
|
||||
if( !cur->request->IsParam(L"r") || cur->request->dir_tab.size() <= 1 )
|
||||
if( !cur->request->IsParam(L"r") )
|
||||
{
|
||||
// we cannot remove the root directory (dir_tab.size()==1)
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log3 << "Rm: a directory can be removed only with 'r' parameter" << logend;
|
||||
slog << logerror << T("rm_use_r_option") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveDir(*cur->request->dir_tab.back());
|
||||
if( cur->request->dir_tab.size() <= 1 )
|
||||
{
|
||||
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
log << log1 << "Rm: the root directory cannot be removed" << logend;
|
||||
slog << logerror << T("rm_cannot_remove_root_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveDirTree(*cur->request->dir_tab.back(), true, true);
|
||||
cur->request->dir_tab.erase(--cur->request->dir_tab.end());
|
||||
}
|
||||
|
||||
|
@ -276,7 +388,6 @@ void Rm::RemoveDir()
|
|||
void Rm::Clear()
|
||||
{
|
||||
content_item_tab.clear();
|
||||
content_item_tab2.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,11 +410,11 @@ void Rm::MakePost()
|
|||
|
||||
if( cur->request->is_item )
|
||||
{
|
||||
RemoveFile();
|
||||
RemoveFileOrSymlink(cur->request->item, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cur->request->IsPostVar(L"onlycontent") )
|
||||
if( cur->request->IsParam(L"c") || cur->request->IsPostVar(L"c") )
|
||||
RemoveDirContent();
|
||||
else
|
||||
RemoveDir();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -26,12 +26,16 @@ public:
|
|||
bool HasAccess();
|
||||
void MakePost();
|
||||
|
||||
void RemoveDir(const Item & dir);
|
||||
void RemoveDirContent(const Item & dir);
|
||||
void RemoveFileOrSymlink(Item & item);
|
||||
// removing the whole directory structure
|
||||
// if remove_this_dir is false then only content of dir is removed
|
||||
void RemoveDirTree(Item & dir, bool remove_this_dir, bool check_access = true);
|
||||
|
||||
// removing either a file or a symlink
|
||||
bool RemoveFileOrSymlink(Item & item, bool check_access = true);
|
||||
|
||||
// removing either a directory or a symlink or a file
|
||||
void RemoveItemById(long item_id);
|
||||
// if item_id is a directory then the whole subdirectories are removed too
|
||||
void RemoveItemById(long item_id, bool check_access = true);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -40,10 +44,6 @@ private:
|
|||
std::vector<Item> content_item_tab;
|
||||
std::wstring path;
|
||||
|
||||
// for deleting content in a directory (files, symlinks and directories)
|
||||
DbItemQuery content_dir_iq2;
|
||||
std::vector<Item> content_item_tab2;
|
||||
|
||||
// for logging
|
||||
std::wstring old_url;
|
||||
|
||||
|
@ -51,15 +51,18 @@ private:
|
|||
DbItemQuery rm_by_id_iq;
|
||||
Item rm_by_id_item;
|
||||
|
||||
bool HasAccess(const Item & item);
|
||||
bool HasAccessToDir(const Item & dir, bool only_content);
|
||||
void Prepare();
|
||||
void Clear();
|
||||
bool RemoveStaticFile(const std::wstring & path);
|
||||
void RemoveStaticFile(Item & item);
|
||||
void RemoveDirTree(long dir_id);
|
||||
|
||||
bool RemoveFile(Item & item);
|
||||
bool RemoveDirFiles(long dir_id, bool check_access);
|
||||
void RemoveCurrentDir(Item * parent_dir, Item * current_dir, bool check_access);
|
||||
void RemoveDirTree(Item * parent_dir, Item * current_dir, bool remove_this_dir, bool check_access);
|
||||
void RemoveStaticFile(const std::wstring & path);
|
||||
void RemoveStaticFile(const Item & item);
|
||||
void RemoveDirContent();
|
||||
void RemoveDir();
|
||||
void RemoveFile();
|
||||
void CreateJSON(bool status);
|
||||
|
||||
};
|
||||
|
|
|
@ -224,7 +224,7 @@ void Upload::UploadMulti()
|
|||
cur->request->item.Clear(); // clearing and setting date
|
||||
cur->request->item.parent_id = cur->request->dir_tab.back()->id;
|
||||
cur->request->item.type = Item::file;
|
||||
cur->request->item.privileges = 0644; // !! tymczasowo
|
||||
cur->request->item.privileges = system->NewFilePrivileges();
|
||||
functions->SetUser(cur->request->item);
|
||||
|
||||
PostFileTab::iterator i = cur->request->post_file_tab.begin();
|
||||
|
@ -259,7 +259,7 @@ void Upload::UploadSingle()
|
|||
|
||||
functions->ReadItem(cur->request->item, Item::file); // ReadItem() changes the url if it is empty
|
||||
functions->SetUser(cur->request->item);
|
||||
cur->request->item.privileges = 0644; // !! tymczasowo
|
||||
cur->request->item.privileges = system->NewFilePrivileges();
|
||||
|
||||
PostFile & post_file = cur->request->post_file_tab.begin()->second;
|
||||
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
<legend>{mv_form_legend}</legend>
|
||||
|
||||
<p>
|
||||
[if-one item_is]{mv_page} "[item_url]":[else]{mv_dir} "[dir_without_slash]"[end]
|
||||
[if-one item_is]{mv_page} [item_url]:[else]{mv_dir} [dir][end]
|
||||
</p>
|
||||
|
||||
|
||||
<p class="withnext">{suggested_url}</p>
|
||||
<input class="edit" type="text" name="to" value="[dir_without_slash][if-one item_is]/[item_url][end]">
|
||||
<input class="edit" type="text" name="dst_path" value="[dir_without_slash][if-one item_is]/[item_url][end]">
|
||||
|
||||
|
||||
[if-no item_is]
|
||||
<label><input type="checkbox" name="onlycontent">{mv_only_content}</label>
|
||||
<label><input type="checkbox" name="c"[if winix_function_param_is "c"]checked="checked"[end]>{mv_only_content}</label>
|
||||
[end]
|
||||
|
||||
<input class="submit" type="submit" value="{move}">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<h1>{rm_header}</h1>
|
||||
[include "error.html"]
|
||||
|
||||
<form id="additem" method="post" action="[doc_base_url][dir][if-one item_is][item_url]/[end]rm[if-no item_is]/r[end]">
|
||||
<fieldset>
|
||||
|
@ -28,7 +27,7 @@
|
|||
|
||||
[if-no item_is]
|
||||
<p>
|
||||
<label><input type="checkbox" name="onlycontent">{rm_only_content}</label>
|
||||
<label><input type="checkbox" name="c" [if winix_function_param_is "c"]checked="checked"[end]>{rm_only_content}</label>
|
||||
</p>
|
||||
[end]
|
||||
|
||||
|
|
18
locale/en
18
locale/en
|
@ -25,7 +25,7 @@ by = by
|
|||
error_404 = Error 404
|
||||
error_404_msg = We are sory but there is no such a page in our service.
|
||||
|
||||
|
||||
internal_error = Internal error, check system log for more details
|
||||
|
||||
|
||||
was_errors = We are sory but there were some problems with the operation.
|
||||
|
@ -182,6 +182,14 @@ rm_dir = Do you really want to remove directory
|
|||
rm_only_content = Remove only the content of the directory
|
||||
rm_root = You cannot remove the root directory, you are only allowed to delete the content of the directory
|
||||
rm_submit = Remove
|
||||
rm_cannot_create_static_path = I cannot create a path to a static file
|
||||
rm_cannot_remove_static_file = I cannot remove a static file
|
||||
rm_permission_denied_to = Permission denied to remove
|
||||
rm_directory_not_empty = directory not empty
|
||||
rm_use_r_option = This is a directory, use 'r' parameter to remove it
|
||||
rm_cannot_remove_root_dir = You cannot remove the root directory
|
||||
rm_content_use_r_option = Content of a directory can be removed only with 'r' parameter
|
||||
|
||||
|
||||
thread_create_new = Create a new thread
|
||||
thread_tab_title = Thread title
|
||||
|
@ -306,6 +314,14 @@ mv_form_legend = Move form
|
|||
mv_page = Move page
|
||||
mv_dir = Move directory
|
||||
mv_only_content = Move only content of the directory
|
||||
mv_cant_move_root_dir = the root directory cannot be moved anywhere
|
||||
mv_permission_denied_to = Permission denied to
|
||||
mv_incorrect_path = Incorrent path
|
||||
mv_dir_can_be_moved_to_dir = A directory can be moved only to an other directory
|
||||
mv_dir_content_can_be_moved_to_dir = Directory content can be moved only to an other directory
|
||||
mv_cannot_move_to_inside = A directory cannot be moved to inside it
|
||||
mv_incorrect_dst_path = Incorrect destination path
|
||||
mv_incorrect_dir = Incorrect directory
|
||||
|
||||
|
||||
cp_header = Copy
|
||||
|
|
19
locale/pl
19
locale/pl
|
@ -26,6 +26,8 @@ error_404 = Błąd 404
|
|||
error_404_msg = Przykro nam ale podanej strony nie ma w naszym serwisie.
|
||||
|
||||
|
||||
internal_error = Błąd wewnętrzny, po więcej szczegółów sprawdź dziennik systemowy
|
||||
|
||||
|
||||
was_errors = Przepraszamy ale wystąpiły problemy z wykonaniem tej operacji.
|
||||
error_code = Kod błędu
|
||||
|
@ -201,6 +203,15 @@ rm_dir = Czy napewno usunąć katalog
|
|||
rm_only_content = Usuń jedynie zawartość katalogu
|
||||
rm_root = Nie możesz skasować katalogu głównego, możesz jedynie usunąć jego zawartość
|
||||
rm_submit = Usuń
|
||||
rm_cannot_create_static_path = Nie mogę utworzyć ścieżki do pliku statycznego
|
||||
rm_cannot_remove_static_file = Nie mogę usunąć pliku statycznego
|
||||
rm_permission_denied_to = Brak dostępu do usunięcia
|
||||
rm_directory_not_empty = katalog nie jest pusty
|
||||
rm_use_r_option = To jest katalog, aby go usunąć musisz użyć parametru 'r'
|
||||
rm_cannot_remove_root_dir = Nie możesz usunąć głównego katalogu
|
||||
rm_content_use_r_option = Zawartość katalogu może zostać usunięta tylko z użyciem parametru 'r'
|
||||
|
||||
|
||||
|
||||
thread_create_new = Załóż nowy wątek
|
||||
thread_tab_title = Tytuł wątku
|
||||
|
@ -323,6 +334,14 @@ mv_form_legend = Formularz zmiany
|
|||
mv_page = Przenieś stronę
|
||||
mv_dir = Przenieś katalog
|
||||
mv_only_content = Przenieś tylko zawartość katalogu
|
||||
mv_cant_move_root_dir = Katalog główny nie może być przeniesiony
|
||||
mv_permission_denied_to = Brak dostępu do
|
||||
mv_incorrect_path = Nieprawidłowa ścieżka
|
||||
mv_dir_can_be_moved_to_dir = Katalog może zostać przeniesiony tylko do innego katalogu
|
||||
mv_dir_content_can_be_moved_to_dir = Zawartość katalogu może zostać przeniesiona tylko do innego katalogu
|
||||
mv_cannot_move_to_inside = Nie mogę przenieść katalogu do jego środka
|
||||
mv_incorrect_dst_path = Nieprawidłowa ścieżka docelowa
|
||||
mv_incorrect_dir = Nieprawidłowy katalog
|
||||
|
||||
|
||||
cp_header = Kopiuj
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -72,7 +72,7 @@ void CreateThread::MakePost()
|
|||
functions->SetUser(cur->request->item);
|
||||
functions->PrepareUrl(cur->request->item);
|
||||
cur->request->item.parent_id = cur->request->dir_tab.back()->id;
|
||||
cur->request->item.privileges = 0644; // !! tymczasowo
|
||||
cur->request->item.privileges = system->NewFilePrivileges();
|
||||
|
||||
if( functions->CheckAbuse() )
|
||||
return;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -92,7 +92,7 @@ void Reply::MakePost()
|
|||
functions->SetUser(answer);
|
||||
functions->PrepareUrl(answer);
|
||||
answer.parent_id = files_dir->id;
|
||||
answer.privileges = 0644; // !! tymczasowo
|
||||
answer.privileges = system->NewFilePrivileges();
|
||||
|
||||
if( functions->CheckAbuse() )
|
||||
return;
|
||||
|
|
|
@ -80,7 +80,7 @@ void CreateTicket::Submit(Ticket & ticket, Item & item)
|
|||
return;
|
||||
|
||||
functions->SetUser(item);
|
||||
item.privileges = 0644; // !! tymczasowo
|
||||
item.privileges = system->NewFilePrivileges();
|
||||
item.parent_id = cur->request->dir_tab.back()->id;
|
||||
|
||||
// adding without notificating
|
||||
|
|
|
@ -61,7 +61,7 @@ void SessionData::RemoveAllFiles(PT::Space & new_space)
|
|||
BuildFileList(new_file_tab, new_space);
|
||||
|
||||
for(size_t i=0 ; i<new_file_tab.size() ; ++i)
|
||||
fun_rm->RemoveItemById(new_file_tab[i]);
|
||||
fun_rm->RemoveItemById(new_file_tab[i], false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,7 +86,7 @@ void SessionData::RemoveAllStaleFiles(PT::Space & new_space, PT::Space & old_spa
|
|||
{
|
||||
if( new_file_tab[n] < old_file_tab[o] )
|
||||
{
|
||||
fun_rm->RemoveItemById(new_file_tab[n]);
|
||||
fun_rm->RemoveItemById(new_file_tab[n], false);
|
||||
n += 1;
|
||||
}
|
||||
else
|
||||
|
@ -103,7 +103,7 @@ void SessionData::RemoveAllStaleFiles(PT::Space & new_space, PT::Space & old_spa
|
|||
|
||||
while( n < new_file_tab.size() )
|
||||
{
|
||||
fun_rm->RemoveItemById(new_file_tab[n]);
|
||||
fun_rm->RemoveItemById(new_file_tab[n], false);
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,16 +132,12 @@ bool TicketInfo::ParseTicketConf(long mount_dir_id, const std::wstring & path)
|
|||
{
|
||||
log << log3 << "Ticket: parsing conf file: " << path << logend;
|
||||
|
||||
log << log1 << config_file.content << logend;
|
||||
|
||||
conf_tab[mount_dir_id].file_name = path;
|
||||
conf_parser.UTF8(true);
|
||||
conf_parser.SetSpace(conf_tab[mount_dir_id].conf);
|
||||
conf_parser.SplitSingle(true);
|
||||
conf_tab[mount_dir_id].conf.Clear();
|
||||
|
||||
//log << log1 << "status: " << conf_parser.Parse(config_file.content) << logend;
|
||||
|
||||
return (conf_parser.ParseString(config_file.content) == PT::ConfParser::ok);
|
||||
}
|
||||
|
||||
|
@ -343,7 +339,7 @@ void TicketInfo::ReadTicketValue(PT::Space & space,
|
|||
file.Clear(); // clearing and setting date
|
||||
file.parent_id = upload_dir.id;
|
||||
file.type = Item::file;
|
||||
file.privileges = 0644; // !! tymczasowo
|
||||
file.privileges = system->NewFilePrivileges();
|
||||
file.file_type = SelectFileType(value.filename);
|
||||
file.url = value.filename;
|
||||
functions->PrepareUrl(file);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2008-2010, Tomasz Sowa
|
||||
* Copyright (c) 2008-2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
@ -253,15 +253,13 @@ void priv_privileges(Info & i)
|
|||
|
||||
void priv_privileges_for_files(Info & i)
|
||||
{
|
||||
//!! bedzie uzyte umask
|
||||
i.out << Toa((int)0644, 8);
|
||||
i.out << Toa(system->NewFilePrivileges(), 8);
|
||||
}
|
||||
|
||||
|
||||
void priv_privileges_for_dirs(Info & i)
|
||||
{
|
||||
//!! bedzie uzyte umask
|
||||
i.out << Toa((int)0755, 8);
|
||||
i.out << Toa(system->NewDirPrivileges(), 8);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue