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:
2011-01-05 21:24:11 +00:00
parent bb83aed20d
commit 8154c403d8
113 changed files with 5840 additions and 2972 deletions

View File

@@ -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;
}