we can create links (hard links, symbolic links) now
added winix functions: ln winix function 'default' can be used without redirecting now added new tickets types: TypeProgress, TypeString, TypeMultistring, TypeImages, TypeFiles now tickets are combined with files added winix functions: showtickets fixed mountpoints: when the default root mount was created its parameter table was empty and it caused accessing to a non-existing objects fixed logger: modifiers (log1, log2, log3) were incorrectly treated added modifier: log4 (debug info) now we are moving threads to a new plugin 'thread' created directory: plugins/thread (not finished yet) git-svn-id: svn://ttmath.org/publicrep/winix/trunk@704 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
419
core/system.cpp
419
core/system.cpp
@@ -11,6 +11,7 @@
|
||||
#include "misc.h"
|
||||
#include "error.h"
|
||||
#include "templates/templates.h"
|
||||
#include "functions/functionbase.h"
|
||||
|
||||
|
||||
|
||||
@@ -69,8 +70,9 @@ void System::Init()
|
||||
notify.Init();
|
||||
|
||||
thumb.SetSynchro(synchro);
|
||||
thumb.SetConvertCmd(config->convert_cmd);
|
||||
thumb.SetDb(db);
|
||||
thumb.SetConfig(config);
|
||||
thumb.SetSystem(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,16 +85,13 @@ void System::RedirectTo(const Item & item, const wchar_t * postfix)
|
||||
if( item.type == Item::dir )
|
||||
{
|
||||
// item_id is pointing to a directory
|
||||
dirs.MakePath(item.id, path);
|
||||
request->redirect_to += path;
|
||||
dirs.MakePath(item.id, request->redirect_to, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !dirs.MakePath(item.parent_id, path) )
|
||||
log << log1 << "Content: Can't redirect: no dirs for item id: " << item.id << logend;
|
||||
|
||||
request->redirect_to += path;
|
||||
request->redirect_to += item.url;
|
||||
// item_id is pointing to a file or a symlink
|
||||
if( dirs.MakePath(item.parent_id, request->redirect_to, false) )
|
||||
request->redirect_to += item.url;
|
||||
}
|
||||
|
||||
if( postfix )
|
||||
@@ -103,37 +102,32 @@ void System::RedirectTo(const Item & item, const wchar_t * postfix)
|
||||
|
||||
void System::RedirectTo(long item_id, const wchar_t * postfix)
|
||||
{
|
||||
Item * pdir;
|
||||
|
||||
request->redirect_to = config->base_url;
|
||||
pdir = dirs.GetDir(item_id);
|
||||
|
||||
Item * pdir = dirs.GetDir(item_id);
|
||||
|
||||
if( pdir )
|
||||
{
|
||||
// item_id is pointing to a directory
|
||||
dirs.MakePath(pdir->id, path);
|
||||
request->redirect_to += path;
|
||||
dirs.MakePath(pdir->id, request->redirect_to, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// !! zrobic nowy interfejs
|
||||
// !! GetItem pozamieniac na GetFile
|
||||
// !! i nie uzywac request->item_tab (zrobic sobie lokalny tutaj)
|
||||
db->GetItem(request->item_tab, item_id);
|
||||
|
||||
if( !request->item_tab.empty() )
|
||||
// item_id is pointing to a file
|
||||
DbItemQuery iq;
|
||||
|
||||
iq.SetAllSel(false);
|
||||
iq.WhereId(item_id);
|
||||
iq.sel_parent_id = true;
|
||||
iq.sel_url = true;
|
||||
|
||||
if( db->GetItem(item_temp, iq) == WINIX_ERR_OK )
|
||||
{
|
||||
if( !dirs.MakePath(request->item_tab[0].parent_id, path) )
|
||||
log << log1 << "Content: Can't redirect: no dirs for item id: "
|
||||
<< request->item_tab[0].id << ", requested directory id: "
|
||||
<< request->item_tab[0].parent_id << logend;
|
||||
|
||||
request->redirect_to += path + request->item_tab[0].url;
|
||||
if( dirs.MakePath(item_temp.parent_id, request->redirect_to, false) )
|
||||
request->redirect_to += item_temp.url;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Content: Can't redirect: no such item: id: " << item_id << logend;
|
||||
log << log1 << "System: can't redirect: no such item: id: " << item_id << logend;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +136,66 @@ Item * pdir;
|
||||
}
|
||||
|
||||
|
||||
void System::RedirectTo(const std::wstring & url)
|
||||
{
|
||||
request->redirect_to = config->base_url;
|
||||
|
||||
if( !url.empty() && url[0] == '/' )
|
||||
{
|
||||
// absolute path
|
||||
request->redirect_to += url;
|
||||
}
|
||||
else
|
||||
{
|
||||
// relative path
|
||||
if( !request->dir_tab.empty() )
|
||||
{
|
||||
if( dirs.MakePath(request->dir_tab.back()->id, request->redirect_to, false) )
|
||||
request->redirect_to += url;
|
||||
}
|
||||
else
|
||||
{
|
||||
request->redirect_to += '/';
|
||||
request->redirect_to += url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void System::AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str)
|
||||
{
|
||||
if( clear_str )
|
||||
str.clear();
|
||||
|
||||
for(size_t i=0 ; i<param_tab.size() ; ++i)
|
||||
{
|
||||
str += '/';
|
||||
str += param_tab[i].name;
|
||||
|
||||
if( !param_tab[i].value.empty() )
|
||||
{
|
||||
str += ':';
|
||||
str += param_tab[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void System::RedirectWithFunctionAndParamsTo(const std::wstring & url)
|
||||
{
|
||||
RedirectTo(url);
|
||||
|
||||
if( !request->function )
|
||||
return;
|
||||
|
||||
request->redirect_to += '/';
|
||||
request->redirect_to += request->function->fun.url;
|
||||
|
||||
AddParams(request->param_tab, request->redirect_to, false);
|
||||
}
|
||||
|
||||
|
||||
void System::RedirectToLastDir()
|
||||
{
|
||||
if( !request->dir_tab.empty() )
|
||||
@@ -319,13 +373,11 @@ bool System::HasReadExecAccessToPath(long dir_id)
|
||||
}
|
||||
|
||||
|
||||
bool System::DirsHaveReadExecPerm()
|
||||
bool System::HasReadExecAccessToPath(const std::vector<Item*> & dir_tab)
|
||||
{
|
||||
std::vector<Item*>::iterator i;
|
||||
|
||||
for(i = request->dir_tab.begin() ; i!=request->dir_tab.end() ; ++i)
|
||||
for(size_t i=0 ; i < dir_tab.size() ; ++i)
|
||||
{
|
||||
if( !HasReadExecAccess(**i) )
|
||||
if( !HasReadExecAccess(*dir_tab[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -333,6 +385,12 @@ return true;
|
||||
}
|
||||
|
||||
|
||||
bool System::DirsHaveReadExecPerm()
|
||||
{
|
||||
return HasReadExecAccessToPath(request->dir_tab);
|
||||
}
|
||||
|
||||
|
||||
// if we don't have access we only remove the item from the table
|
||||
void System::CheckAccessToItems(std::vector<Item> & item_tab)
|
||||
{
|
||||
@@ -488,7 +546,7 @@ return res;
|
||||
}
|
||||
|
||||
|
||||
// making a global file path
|
||||
// making a global file path (in the unix file system)
|
||||
// you should call CreateNewFile before
|
||||
bool System::MakeFilePath(const Item & item, std::wstring & path, bool thumb, bool create_dir, int chmod)
|
||||
{
|
||||
@@ -530,12 +588,36 @@ return true;
|
||||
}
|
||||
|
||||
|
||||
// item can be a directory, file or a symlink
|
||||
// if item is a directory then the path will be with a slash at the end
|
||||
bool System::MakePath(const Item & item, std::wstring & path, bool clear_path)
|
||||
{
|
||||
bool res;
|
||||
|
||||
if( clear_path )
|
||||
path.clear();
|
||||
|
||||
if( item.type == Item::dir )
|
||||
{
|
||||
res = dirs.MakePath(item.id, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = dirs.MakePath(item.parent_id, path);
|
||||
|
||||
if( res )
|
||||
path += item.url;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Error System::AddFile(Item & item, int notify_code)
|
||||
{
|
||||
if( item.type == Item::dir )
|
||||
if( item.type != Item::file )
|
||||
return WINIX_ERR_FILE_EXPECTED;
|
||||
|
||||
Error status = db->AddItem(item);
|
||||
@@ -557,7 +639,7 @@ return status;
|
||||
|
||||
Error System::EditFile(Item & item, bool with_url, int notify_code)
|
||||
{
|
||||
if( item.type == Item::dir )
|
||||
if( item.type != Item::file )
|
||||
return WINIX_ERR_FILE_EXPECTED;
|
||||
|
||||
if( request->session && request->session->puser )
|
||||
@@ -613,3 +695,270 @@ tm System::LocalTime(const tm & ptm)
|
||||
{
|
||||
return LocalTime(&ptm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
return codes:
|
||||
ok:
|
||||
0 - the link_to is a path to a directory (out_item skipped, out_dir_tab will not be empty)
|
||||
1 - the link_to is a path to a file or a symlink (out_item is used, out_dir_tab will not be empty)
|
||||
|
||||
error:
|
||||
2 - incorrect link_to
|
||||
3 - there is not a root dir
|
||||
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)
|
||||
*/
|
||||
int System::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
|
||||
std::vector<Item*> & out_dir_tab, Item & out_item)
|
||||
{
|
||||
link_to_temp = link_to; // copy the link because it can be from out_item (and will be cleared)
|
||||
out_item.Clear();
|
||||
|
||||
int res = dirs.FollowLink(current_dir_tab, link_to_temp, out_dir_tab, name_temp);
|
||||
|
||||
if( res == 1 )
|
||||
{
|
||||
if( db->GetItem(out_dir_tab.back()->id, name_temp, out_item) == WINIX_ERR_OK )
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool System::FollowAllLinksDirFound(std::vector<Item*> & out_dir_tab,
|
||||
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
|
||||
{
|
||||
log << log3 << "System: link to a directory: ";
|
||||
dirs.LogDir(out_dir_tab);
|
||||
log << logend;
|
||||
|
||||
if( check_access && !HasReadExecAccessToPath(out_dir_tab) )
|
||||
{
|
||||
log << log1 << "System: no access to the directory structure" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !out_dir_tab.back()->link_to.empty() )
|
||||
{
|
||||
if( follow_dir_default )
|
||||
{
|
||||
if( !(stop_on_link_redirect && out_dir_tab.back()->link_redirect==1) )
|
||||
link_to_temp = out_dir_tab.back()->link_to;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool System::FollowAllLinksFileOrSymlinkFound(std::vector<Item*> & out_dir_tab, Item & out_item,
|
||||
bool stop_on_link_redirect, bool check_access)
|
||||
{
|
||||
if( out_item.type == Item::symlink )
|
||||
log << log3 << "System: link to a symlink: ";
|
||||
else
|
||||
log << log3 << "System: link to a file: ";
|
||||
|
||||
dirs.LogDir(out_dir_tab);
|
||||
log << out_item.url << logend;
|
||||
|
||||
if( check_access && !HasReadExecAccessToPath(out_dir_tab) )
|
||||
{
|
||||
log << log1 << "System: no access to the directory structure" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( out_item.type == Item::symlink )
|
||||
{
|
||||
if( out_item.link_to.empty() )
|
||||
{
|
||||
log << log1 << "System: symlink empty" << logend;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !check_access || HasReadAccess(out_item) )
|
||||
{
|
||||
if( !(stop_on_link_redirect && out_item.link_redirect==1) )
|
||||
link_to_temp = out_item.link_to;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "System: no read access to the symlink" << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
return codes:
|
||||
ok:
|
||||
0 - the link_to is a path to a directory (out_item skipped, out_dir_tab will not be empty)
|
||||
1 - the link_to is a path to a file (out_item is used, out_dir_tab will not be empty)
|
||||
(link_to can be a path to a symlink if stop_on_link_redirect is true)
|
||||
|
||||
error:
|
||||
2 - incorrect link_to
|
||||
3 - there is not a root dir
|
||||
4 - current_dir_tab was empty
|
||||
5 - limit of symlinks exceeded
|
||||
6 - permission denied to a file/symlink or a directory (or a symlink is empty)
|
||||
|
||||
current_dir_tab can be the same container as out_dir_tab
|
||||
link_to can be a relative path (without the first slash)
|
||||
|
||||
if follow_dir_default is true then directories with 'default' flags are followed as well
|
||||
|
||||
if stop_on_link_redirect is true then the method stops on a symbolic link (or a directory
|
||||
with 'default' flag set) where the redirection should be done, you should check then whether
|
||||
the out_item.back()->link_to is not empty (if the result was 0 ) or
|
||||
whether out_item.type is symlink (if the result was 1)
|
||||
to make the redirection
|
||||
*/
|
||||
int System::FollowAllLinks(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
|
||||
std::vector<Item*> & out_dir_tab, Item & out_item,
|
||||
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
|
||||
{
|
||||
int res;
|
||||
size_t level = 0;
|
||||
link_to_temp = link_to;
|
||||
|
||||
if( current_dir_tab.empty() )
|
||||
return 4;
|
||||
|
||||
do
|
||||
{
|
||||
if( ++level > config->symlinks_follow_max )
|
||||
{
|
||||
log << log1 << "System: the number of maximum symlinks exceeded ("
|
||||
<< config->symlinks_follow_max << ")" << logend;
|
||||
|
||||
res = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = FollowLink(current_dir_tab, link_to_temp, out_dir_tab, out_item);
|
||||
link_to_temp.clear();
|
||||
|
||||
if( res == 0 )
|
||||
{
|
||||
out_item.Clear();
|
||||
res = FollowAllLinksDirFound(out_dir_tab, follow_dir_default, stop_on_link_redirect, check_access) ? 0 : 6;
|
||||
}
|
||||
else
|
||||
if( res == 1 )
|
||||
{
|
||||
res = FollowAllLinksFileOrSymlinkFound(out_dir_tab, out_item, stop_on_link_redirect, check_access) ? 1 : 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log2 << "System: incorrect link: " << link_to << logend;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( !link_to_temp.empty() );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// the same as FollowAllLinks but starts from the root directory
|
||||
// link_to must begin with a slash (or can be empty then the root directory is returned)
|
||||
int System::FollowAllLinks(const std::wstring & link_to,
|
||||
std::vector<Item*> & out_dir_tab, Item & out_item,
|
||||
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
|
||||
{
|
||||
if( !link_to.empty() && link_to[0] != '/' )
|
||||
return 2;
|
||||
|
||||
if( root_follow_dir_tab.size() != 1 )
|
||||
root_follow_dir_tab.resize(1);
|
||||
|
||||
Item * root_dir = dirs.GetRootDir();
|
||||
|
||||
if( !root_dir )
|
||||
return 3;
|
||||
|
||||
root_follow_dir_tab[0] = root_dir;
|
||||
|
||||
return FollowAllLinks(root_follow_dir_tab, link_to,
|
||||
out_dir_tab, out_item, follow_dir_default, stop_on_link_redirect, check_access);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the same as FollowAllLinks but operates on request->dir_tab and request->item
|
||||
// and returns bool
|
||||
// the method is making a redirection if needed
|
||||
bool System::FollowAllLinks(const std::wstring & link_to,
|
||||
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
|
||||
{
|
||||
int res = FollowAllLinks(request->dir_tab, link_to, temp_follow_dir_tab, temp_follow_item,
|
||||
follow_dir_default, stop_on_link_redirect, check_access);
|
||||
|
||||
bool ok = (res == 0 || res == 1);
|
||||
|
||||
if( ok )
|
||||
{
|
||||
request->dir_tab = temp_follow_dir_tab;
|
||||
|
||||
if( res == 0 )
|
||||
{
|
||||
request->is_item = false;
|
||||
request->item.Clear();
|
||||
request->last_item = request->dir_tab.back();
|
||||
|
||||
if( !request->dir_tab.back()->link_to.empty() )
|
||||
RedirectTo(request->dir_tab.back()->link_to);
|
||||
|
||||
log << log3 << "System: current directory changed" << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
request->is_item = true;
|
||||
request->item = temp_follow_item;
|
||||
request->last_item = &request->item;
|
||||
|
||||
if( request->item.type == Item::symlink )
|
||||
RedirectTo(request->item.link_to); // request->item.link_to is not empty
|
||||
|
||||
log << log3 << "System: current directory changed and the new file loaded" << logend;
|
||||
}
|
||||
|
||||
mounts.CalcCurMount();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( res == 5 || res == 6 )
|
||||
request->status = WINIX_ERR_PERMISSION_DENIED;
|
||||
else
|
||||
request->status = WINIX_ERR_NO_ITEM;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user