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

@@ -23,12 +23,13 @@ app.o: ../functions/functionbase.h ../core/request.h ../core/system.h
app.o: ../core/synchro.h ../functions/functionparser.h ../functions/adduser.h
app.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
app.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
app.o: ../functions/createthread.h ../functions/default.h
app.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
app.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
app.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
app.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
app.o: ../functions/run.h ../functions/specialdefault.h ../functions/stat.h
app.o: ../functions/createthread.h ../functions/functionbase.h
app.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
app.o: ../functions/last.h ../functions/login.h ../functions/logout.h
app.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
app.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
app.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
app.o: ../functions/specialdefault.h ../functions/stat.h
app.o: ../functions/subject.h ../functions/funthread.h
app.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
app.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
@@ -65,13 +66,14 @@ config.o: ../core/request.h ../core/system.h ../core/synchro.h
config.o: ../functions/functionparser.h ../functions/adduser.h
config.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
config.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
config.o: ../functions/createthread.h ../functions/default.h
config.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
config.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
config.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
config.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
config.o: ../functions/run.h ../functions/specialdefault.h
config.o: ../functions/stat.h ../functions/subject.h ../functions/funthread.h
config.o: ../functions/createthread.h ../functions/functionbase.h
config.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
config.o: ../functions/last.h ../functions/login.h ../functions/logout.h
config.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
config.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
config.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
config.o: ../functions/specialdefault.h ../functions/stat.h
config.o: ../functions/subject.h ../functions/funthread.h
config.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
config.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
config.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
@@ -164,13 +166,14 @@ mounts.o: ../core/synchro.h ../functions/functionparser.h
mounts.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
mounts.o: ../functions/privchanger.h ../functions/chown.h
mounts.o: ../functions/ckeditor.h ../functions/cp.h
mounts.o: ../functions/createthread.h ../functions/default.h
mounts.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
mounts.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
mounts.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
mounts.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
mounts.o: ../functions/run.h ../functions/specialdefault.h
mounts.o: ../functions/stat.h ../functions/subject.h ../functions/funthread.h
mounts.o: ../functions/createthread.h ../functions/functionbase.h
mounts.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
mounts.o: ../functions/last.h ../functions/login.h ../functions/logout.h
mounts.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
mounts.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
mounts.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
mounts.o: ../functions/specialdefault.h ../functions/stat.h
mounts.o: ../functions/subject.h ../functions/funthread.h
mounts.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
mounts.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
mounts.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
@@ -201,13 +204,14 @@ plugin.o: ../core/request.h ../core/system.h ../core/synchro.h
plugin.o: ../functions/functionparser.h ../functions/adduser.h
plugin.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
plugin.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
plugin.o: ../functions/createthread.h ../functions/default.h
plugin.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
plugin.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
plugin.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
plugin.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
plugin.o: ../functions/run.h ../functions/specialdefault.h
plugin.o: ../functions/stat.h ../functions/subject.h ../functions/funthread.h
plugin.o: ../functions/createthread.h ../functions/functionbase.h
plugin.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
plugin.o: ../functions/last.h ../functions/login.h ../functions/logout.h
plugin.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
plugin.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
plugin.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
plugin.o: ../functions/specialdefault.h ../functions/stat.h
plugin.o: ../functions/subject.h ../functions/funthread.h
plugin.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
plugin.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
plugin.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
@@ -239,21 +243,22 @@ plugindata.o: ../core/synchro.h ../functions/functionparser.h
plugindata.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
plugindata.o: ../functions/privchanger.h ../functions/chown.h
plugindata.o: ../functions/ckeditor.h ../functions/cp.h
plugindata.o: ../functions/createthread.h ../functions/default.h
plugindata.o: ../functions/download.h ../functions/emacs.h
plugindata.o: ../functions/last.h ../functions/login.h ../functions/logout.h
plugindata.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
plugindata.o: ../functions/node.h ../functions/priv.h ../functions/reload.h
plugindata.o: ../functions/rm.h ../functions/run.h
plugindata.o: ../functions/specialdefault.h ../functions/stat.h
plugindata.o: ../functions/subject.h ../functions/funthread.h
plugindata.o: ../functions/template.h ../functions/tinymce.h
plugindata.o: ../functions/uname.h ../functions/upload.h
plugindata.o: ../functions/uptime.h ../functions/who.h ../functions/vim.h
plugindata.o: ../core/htmlfilter.h ../templates/templates.h
plugindata.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
plugindata.o: ../core/httpsimpleparser.h ../core/log.h
plugindata.o: ../templates/indexpatterns.h ../core/sessionmanager.h
plugindata.o: ../functions/createthread.h ../functions/functionbase.h
plugindata.o: ../functions/default.h ../functions/download.h
plugindata.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
plugindata.o: ../functions/logout.h ../functions/ln.h ../functions/ls.h
plugindata.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
plugindata.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
plugindata.o: ../functions/run.h ../functions/specialdefault.h
plugindata.o: ../functions/stat.h ../functions/subject.h
plugindata.o: ../functions/funthread.h ../functions/template.h
plugindata.o: ../functions/tinymce.h ../functions/uname.h
plugindata.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
plugindata.o: ../functions/vim.h ../core/htmlfilter.h
plugindata.o: ../templates/templates.h ../templates/patterncacher.h
plugindata.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
plugindata.o: ../core/log.h ../templates/indexpatterns.h
plugindata.o: ../core/sessionmanager.h
postmultiparser.o: postmultiparser.h error.h requesttypes.h config.h
postmultiparser.o: confparser.h htmlfilter.h log.h textstream.h
postmultiparser.o: ../../ezc/src/utf8.h misc.h item.h
@@ -284,9 +289,10 @@ request.o: ../core/request.h ../core/system.h ../core/synchro.h
request.o: ../functions/functionparser.h ../functions/adduser.h
request.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
request.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
request.o: ../functions/createthread.h ../functions/default.h
request.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
request.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
request.o: ../functions/createthread.h ../functions/functionbase.h
request.o: ../functions/default.h ../functions/download.h
request.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
request.o: ../functions/logout.h ../functions/ln.h ../functions/ls.h
request.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
request.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
request.o: ../functions/run.h ../functions/specialdefault.h
@@ -332,19 +338,20 @@ sessionmanager.o: ../functions/functionparser.h ../functions/adduser.h
sessionmanager.o: ../functions/cat.h ../functions/chmod.h
sessionmanager.o: ../functions/privchanger.h ../functions/chown.h
sessionmanager.o: ../functions/ckeditor.h ../functions/cp.h
sessionmanager.o: ../functions/createthread.h ../functions/default.h
sessionmanager.o: ../functions/download.h ../functions/emacs.h
sessionmanager.o: ../functions/last.h ../functions/login.h
sessionmanager.o: ../functions/logout.h ../functions/ls.h
sessionmanager.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
sessionmanager.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
sessionmanager.o: ../functions/run.h ../functions/specialdefault.h
sessionmanager.o: ../functions/stat.h ../functions/subject.h
sessionmanager.o: ../functions/funthread.h ../functions/template.h
sessionmanager.o: ../functions/tinymce.h ../functions/uname.h
sessionmanager.o: ../functions/upload.h ../functions/uptime.h
sessionmanager.o: ../functions/who.h ../functions/vim.h ../core/htmlfilter.h
sessionmanager.o: ../templates/templates.h ../templates/patterncacher.h
sessionmanager.o: ../functions/createthread.h ../functions/functionbase.h
sessionmanager.o: ../functions/default.h ../functions/download.h
sessionmanager.o: ../functions/emacs.h ../functions/last.h
sessionmanager.o: ../functions/login.h ../functions/logout.h
sessionmanager.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
sessionmanager.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
sessionmanager.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
sessionmanager.o: ../functions/specialdefault.h ../functions/stat.h
sessionmanager.o: ../functions/subject.h ../functions/funthread.h
sessionmanager.o: ../functions/template.h ../functions/tinymce.h
sessionmanager.o: ../functions/uname.h ../functions/upload.h
sessionmanager.o: ../functions/uptime.h ../functions/who.h ../functions/vim.h
sessionmanager.o: ../core/htmlfilter.h ../templates/templates.h
sessionmanager.o: ../templates/patterncacher.h
sessionmanager.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
sessionmanager.o: ../core/log.h ../templates/indexpatterns.h
sessionmanager.o: ../core/sessionmanager.h
@@ -376,11 +383,24 @@ system.o: ../templates/templates.h ../templates/patterncacher.h
system.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
system.o: ../core/log.h ../templates/indexpatterns.h ../core/request.h
system.o: ../core/system.h ../core/sessionmanager.h
system.o: ../functions/functionbase.h
textstream.o: textstream.h misc.h item.h
thumb.o: thumb.h basethread.h textstream.h ../db/db.h ../db/dbbase.h
thumb.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
thumb.o: item.h ../core/error.h log.h ../db/dbitemquery.h ../core/item.h
thumb.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
thumb.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
thumb.o: ../../ezc/src/utf8.h
thumb.o: ../core/config.h ../../ezc/src/utf8.h system.h dirs.h dircontainer.h
thumb.o: request.h requesttypes.h session.h error.h user.h plugindata.h
thumb.o: rebus.h config.h confparser.h htmlfilter.h
thumb.o: ../templates/htmltextstream.h ../notify/notify.h
thumb.o: ../notify/notifypool.h ../templates/locale.h ../core/confparser.h
thumb.o: ../templates/misc.h ../templates/localefilter.h
thumb.o: ../templates/locale.h ../../ezc/src/ezc.h ../../ezc/src/generator.h
thumb.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
thumb.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
thumb.o: ../templates/htmltextstream.h ../notify/notifythread.h
thumb.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
thumb.o: ../core/users.h ugcontainer.h lastcontainer.h mounts.h mount.h
thumb.o: mountparser.h users.h groups.h group.h loadavg.h
users.o: users.h

View File

@@ -182,7 +182,7 @@ return true;
void App::ProcessRequestThrow()
{
ReadRequest();
ReadRequest();
// when BaseUrlRedirect() return true we didn't have to set everything in request.Read()
// in the future request.Read() can be split and at the beginning only environment variables will be read
@@ -214,15 +214,11 @@ void App::ProcessRequest()
log << log2 << config.log_delimiter << logend;
ProcessRequestThrow();
SaveSessionsIfNeeded();
if( request.function )
request.function->Clear();
SaveSessionsIfNeeded(); // !! przerzucic to na watek sesji
request.Clear();
system.load_avg.StopRequest();
log << logsave;
log << logendrequest;
}
catch(const std::exception & e)
{
@@ -313,20 +309,13 @@ void App::Make()
// request.status can be changed by function_parser
if( request.status == WINIX_ERR_OK )
{
plugin.Call(WINIX_PREPARE_REQUEST);
if( system.DirsHaveReadExecPerm() )
{
if( request.method == Request::post )
functions.MakePost();
if( request.redirect_to.empty() && request.status == WINIX_ERR_OK )
functions.MakeGet();
}
else
request.status = WINIX_ERR_PERMISSION_DENIED;
}
if( request.status == WINIX_ERR_OK )
functions.CheckFunctionAndSymlink();
if( request.status == WINIX_ERR_OK )
functions.MakeFunction();
if( request.session->spam_score > 0 )
log << log1 << "App: spam score: " << request.session->spam_score << logend;
@@ -538,17 +527,17 @@ void App::SendHeaders(bool compressing, Header header)
if( !request.redirect_to.empty() )
{
FCGX_PutS("Status: 301 Moved Permanently\r\n", fcgi_request.out);
AssignString(request.redirect_to, request.aredirect_to);
UrlEncode(request.redirect_to, request.aredirect_to);
FCGX_FPrintF(fcgi_request.out, "Location: %s\r\n", request.aredirect_to.c_str());
log << log2 << "Redirect to: " << request.redirect_to << logend;
log << log2 << "Redirect to: " << request.aredirect_to << logend;
}
else
if( !request.x_sendfile.empty() )
{
static std::string temp, temp2; // !! wrzucic gdzies to
AssignString(config.http_header_send_file, temp);
AssignString(request.x_sendfile, temp2);
Ezc::WideToUTF8(config.http_header_send_file, temp);
Ezc::WideToUTF8(request.x_sendfile, temp2);
FCGX_FPrintF(fcgi_request.out, "%s: %s\r\n", temp.c_str(), temp2.c_str());
FCGX_PutS("Status: 200 OK\r\n", fcgi_request.out);
@@ -833,7 +822,7 @@ bool App::DropPrivileges(const std::string & user, uid_t uid, gid_t gid, bool ad
{
if( initgroups(user.c_str(), gid) < 0 )
{
log << log1 << "App: I can't init groups for user: " << user << logend << logsave;
log << log1 << "App: I can't init groups for user: " << user << logend;
return false;
}
}
@@ -841,7 +830,7 @@ bool App::DropPrivileges(const std::string & user, uid_t uid, gid_t gid, bool ad
{
if( setgroups(1, &gid) < 0 )
{
log << log1 << "App: I can't init groups for user: " << user << logend << logsave;
log << log1 << "App: I can't init groups for user: " << user << logend;
return false;
}
}
@@ -849,20 +838,20 @@ bool App::DropPrivileges(const std::string & user, uid_t uid, gid_t gid, bool ad
// for setting real and saved gid too
if( setgid(gid) )
{
log << log1 << "App: I can't change real and saved gid" << logend << logsave;
log << log1 << "App: I can't change real and saved gid" << logend;
return false;
}
if( setuid(uid) < 0 )
{
log << log1 << "App: I can't drop privileges to user: " << user
<< " (uid:" << (int)uid << ")" << logend << logsave;
<< " (uid:" << (int)uid << ")" << logend;
return false;
}
if( getuid()==0 || geteuid()==0 )
{
log << log1 << "App: sorry, for security reasons you should not run me as the root" << logend << logsave;
log << log1 << "App: sorry, for security reasons you should not run me as the root" << logend;
return false;
}
@@ -880,14 +869,14 @@ bool App::DropPrivileges()
if( config.user.empty() )
{
log << log1 << "App: you should specify user name in the config file "
<< "to which I have to drop privileges" << logend << logsave;
<< "to which I have to drop privileges" << logend;
return false;
}
if( config.group.empty() )
{
log << log1 << "App: you should specify group name in the config file "
<< "to which I have to drop privileges" << logend << logsave;
<< "to which I have to drop privileges" << logend;
return false;
}
@@ -896,13 +885,13 @@ bool App::DropPrivileges()
if( !p )
{
log << log1 << "App: there is no such a user as: \"" << config.user << "\"" << logend << logsave;
log << log1 << "App: there is no such a user as: \"" << config.user << "\"" << logend;
return false;
}
if( !g )
{
log << log1 << "App: there is no such a group as: \"" << config.group << "\"" << logend << logsave;
log << log1 << "App: there is no such a group as: \"" << config.group << "\"" << logend;
return false;
}
@@ -922,7 +911,7 @@ bool App::Demonize()
if( pid == -1 )
{
log << log1 << "App: I can't demonize myself (fork problem)" << logend << logsave;
log << log1 << "App: I can't demonize myself (fork problem)" << logend;
return false;
}
@@ -935,7 +924,7 @@ bool App::Demonize()
// child
if( setsid() == -1 )
{
log << log1 << "App: I can't demonize myself (setsid problem)" << logend << logsave;
log << log1 << "App: I can't demonize myself (setsid problem)" << logend;
return false;
}

View File

@@ -105,6 +105,7 @@ void Config::AssignValues(bool stdout_is_closed)
fcgi_socket_group = AText(L"fcgi_socket_group");
log_level = Int(L"log_level", 1);
log_request = Int(L"log_request", 1);
log_save_each_line = Bool(L"log_save_each_line", false);
log_stdout = Bool(L"log_stdout", false);
log_db_query = Bool(L"log_db_query", false);
log_plugin_call = Bool(L"log_plugin_call", false);
@@ -184,6 +185,9 @@ void Config::AssignValues(bool stdout_is_closed)
time_zone_offset_guest = Int(L"time_zone_offset_guest", 0);
utf8 = Bool(L"utf8", true);
symlinks_follow_max = Size(L"symlinks_follow_max", 20);
ticket_form_prefix = Text(L"ticket_form_prefix", L"ticketparam");
}

View File

@@ -56,10 +56,14 @@ public:
// default: false
bool log_stdout;
// how many requests should be logged in the same time
// how many requests should be saved in the same time
// default: 1
int log_request;
// whether to save each line of the config (use it for debug purposes)
// default: false
bool log_save_each_line;
// logging db queries
// default: false
bool log_db_query;
@@ -285,6 +289,14 @@ public:
// if false it means 8-bit ASCII
bool utf8;
// how many maximum symlinks can be followed
// (symlinks on directories as well)
// default: 20
size_t symlinks_follow_max;
// the prefix of a name of html form controls used in the ticket plugin
// default: ticketparam
std::wstring ticket_form_prefix;
/*
*/

View File

@@ -91,9 +91,9 @@ void DirContainer::FindSpecialFolders()
if( !is_root )
return;
DirContainer::ParentIterator i = FindFirstParent(root_iter->id);
DirContainer::ParentIterator i = FindFirstChild(root_iter->id);
for( ; i!=ParentEnd() ; i = NextParent(i) )
for( ; i!=ParentEnd() ; i = NextChild(i) )
{
if( i->second->url == dir_etc )
{
@@ -126,14 +126,14 @@ void DirContainer::CheckSpecialFolder(const Item & item, Iterator iter)
{
is_etc = true;
etc_iter = iter;
log << log1 << "DirCont: added special folder: /etc" << logend;
log << log2 << "DirCont: added special folder: /etc" << logend;
}
if( item.parent_id==root_iter->id && item.url==dir_var )
{
is_var = true;
var_iter = iter;
log << log1 << "DirCont: added special folder: /var" << logend;
log << log2 << "DirCont: added special folder: /var" << logend;
}
}
@@ -172,10 +172,10 @@ bool DirContainer::ChangeParent(long dir_id, long new_parent_id)
if( i->parent_id == new_parent_id )
return true; // nothing to do
ParentIterator p = FindFirstParent(i->parent_id);
ParentIterator p = FindFirstChild(i->parent_id);
bool found = false;
for( ; p != table_parent.end() ; p = NextParent(p) )
for( ; p != table_parent.end() ; p = NextChild(p) )
{
if( p->second->id == dir_id )
{
@@ -251,7 +251,7 @@ bool DirContainer::ParentEmpty()
}
DirContainer::ParentIterator DirContainer::FindFirstParent(long parent)
DirContainer::ParentIterator DirContainer::FindFirstChild(long parent)
{
ParentIterator i = table_parent.lower_bound(parent);
@@ -262,7 +262,7 @@ return i;
}
DirContainer::ParentIterator DirContainer::NextParent(ParentIterator i)
DirContainer::ParentIterator DirContainer::NextChild(ParentIterator i)
{
if( i == table_parent.end() )
return table_parent.end();

View File

@@ -52,8 +52,8 @@ public:
ParentIterator ParentEnd();
ParentSizeType ParentSize();
bool ParentEmpty();
ParentIterator FindFirstParent(long parent);
ParentIterator NextParent(ParentIterator pi);
ParentIterator FindFirstChild(long parent);
ParentIterator NextChild(ParentIterator pi);
bool IsNameOfSpecialFolder(const std::wstring & name);
void FindSpecialFolders();

View File

@@ -70,7 +70,6 @@ void Dirs::CheckRootDir()
root.user_id = -1;
root.group_id = -1;
root.privileges = 0755;
root.default_item = -1;
// !! upewnic sie ze baza nie zmieni url (gdyby wczesniej juz byl w bazie pusty url)
// !! zrobic jakis wyjatek do wprowadzania roota?
@@ -129,26 +128,26 @@ bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_tab)
if( parent != -1 && !IsDir(parent) )
return false;
DirContainer::ParentIterator i = dir_tab.FindFirstParent(parent);
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
for( ; i != dir_tab.ParentEnd() ; i = dir_tab.NextParent(i) )
for( ; i != dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
childs_tab.push_back( &(*i->second) );
return true;
}
DirContainer::ParentIterator Dirs::FindFirstParent(long parent_id)
DirContainer::ParentIterator Dirs::FindFirstChild(long parent_id)
{
DirContainer::ParentIterator i = dir_tab.FindFirstParent(parent_id);
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent_id);
return i;
}
DirContainer::ParentIterator Dirs::NextParent(DirContainer::ParentIterator i)
DirContainer::ParentIterator Dirs::NextChild(DirContainer::ParentIterator i)
{
return dir_tab.NextParent(i);
return dir_tab.NextChild(i);
}
@@ -162,11 +161,14 @@ DirContainer::ParentIterator Dirs::ParentEnd()
// albo tutaj stringa nie czyscic?
// O(m * log n) (m- how many parts are in 'id')
// path with a slash at the end
bool Dirs::MakePath(long id, std::wstring & path)
bool Dirs::MakePath(long id, std::wstring & path, bool clear_path)
{
DirContainer::Iterator i;
path = '/';
if( clear_path )
path.clear();
temp_path = '/';
while( true )
{
@@ -174,16 +176,21 @@ DirContainer::Iterator i;
if( i == dir_tab.End() ||
i->parent_id == id ) // means a loop (something wrong in the db)
{
// we don't change path if there is no such a directory
return false;
}
if( i->parent_id == -1 )
{
path += temp_path;
return true;
}
id = i->parent_id;
path.insert(0, i->url);
path.insert(path.begin(), '/');
temp_path.insert(0, i->url);
temp_path.insert(temp_path.begin(), '/');
}
}
@@ -220,6 +227,33 @@ DirContainer::Iterator i;
bool Dirs::CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab)
{
DirContainer::Iterator i;
out_dir_tab.clear();
do
{
i = dir_tab.FindId(dir_id);
if( i == dir_tab.End() )
return false;
if( out_dir_tab.empty() )
out_dir_tab.insert(out_dir_tab.end(), &(*i)); // !! I am not sure whether begin() can be used on an empty container
else
out_dir_tab.insert(out_dir_tab.begin(), &(*i));
dir_id = i->parent_id;
}
while( dir_id != -1 );
return true;
}
Item * Dirs::GetRootDir()
{
DirContainer::Iterator root = dir_tab.GetRoot();
@@ -255,9 +289,9 @@ return &(*etc);
Item * Dirs::GetDir(const std::wstring & name, long parent)
{
DirContainer::ParentIterator i = dir_tab.FindFirstParent(parent);
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
for( ; i!=dir_tab.ParentEnd() ; i = dir_tab.NextParent(i) )
for( ; i!=dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
if( i->second->url == name )
return &(*i->second);
@@ -276,7 +310,7 @@ Item * Dirs::GetDir(const std::wstring & path)
Item * pitem = &(*root);
std::wstring name;
std::wstring name; // !! dodac jako skladowa klasy
const wchar_t * s = path.c_str();
while( ExtractName(s, name) )
@@ -287,7 +321,6 @@ Item * Dirs::GetDir(const std::wstring & path)
return 0;
}
return pitem;
}
@@ -392,6 +425,135 @@ return 0;
// current_dir_tab can be the same container as out_dir_tab
void Dirs::CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out)
{
if( &in != &out )
{
out.resize(in.size());
for(size_t i=0 ; i<in.size() ; ++i)
out[i] = in[i];
}
}
size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to)
{
if( dir_tab.empty() )
return 0;
size_t i = 0;
size_t old_i;
while( true )
{
// skipping slashes
for( ; i<link_to.size() && link_to[i] == '/' ; ++i);
if( i == link_to.size() )
return i; // end of the path
// creating a name
old_i = i;
analyze_temp.clear();
for( ; i<link_to.size() && link_to[i] != '/' ; ++i)
analyze_temp += link_to[i];
Item * pdir = GetDir(analyze_temp, dir_tab.back()->id);
if( !pdir )
return old_i; // analyze_temp is not a directory
dir_tab.push_back(pdir);
}
}
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);
if( i < link_to.size() )
{
// checking if at least one slash has left
for(size_t a=i ; a < link_to.size() ; ++a)
if( link_to[a] == '/' )
return 2; // there is not such a directory
// the rest of the path is a file name
out_item = link_to.c_str() + i;
return 1;
}
return 0;
}
/*
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)
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 Dirs::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, std::wstring & out_item)
{
temp_link_to = link_to; // link_to can be from the out_item and would be cleared next
out_item.clear();
if( current_dir_tab.empty() )
return 4;
if( temp_link_to.empty() )
{
CopyDirTab(current_dir_tab, out_dir_tab);
return 0;
}
if( temp_link_to[0] == '/' )
{
// temp_link_to is an absolute path
Item * pdir = GetRootDir();
if( !pdir )
return 3;
out_dir_tab.clear();
out_dir_tab.push_back(pdir);
}
else
{
// temp_link_to is a relative path
CopyDirTab(current_dir_tab, out_dir_tab);
}
return FollowLink(out_dir_tab, temp_link_to, out_item);
}
void Dirs::SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file)
{
@@ -483,5 +645,15 @@ return var;
}
// printing first and last slash
void Dirs::LogDir(const std::vector<Item*> & dir_tab)
{
log << '/';
// skipping the first (root) directory
for(size_t i=1 ; i<dir_tab.size() ; ++i)
log << dir_tab[i]->url << '/';
}

View File

@@ -39,16 +39,24 @@ public:
// these methods return false if there is no such a dir
bool IsDir(long dir_id);
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_tab); // !! zamienic na GetChilds()
bool MakePath(long dir_id, std::wstring & path);
bool MakePath(long dir_id, std::wstring & path, bool clear_path = true);
bool ChangeParent(long dir_id, long new_parent_id);
bool HasParent(long dir_id, long parent_id);
bool DelDir(long dir_id);
bool CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab);
void LogDir(const std::vector<Item*> & dir_tab);
int AnalyzePath(const std::wstring & path, long & dir_id, std::wstring & dir, std::wstring & file);
int FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, std::wstring & out_item);
static void SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file);
DirContainer::ParentIterator FindFirstParent(long parent_id); // !! zmienic w koncu nazwe na FindFirstChild
DirContainer::ParentIterator NextParent(DirContainer::ParentIterator i);
DirContainer::ParentIterator FindFirstChild(long parent_id); // !! zmienic w koncu nazwe na FindFirstChild
DirContainer::ParentIterator NextChild(DirContainer::ParentIterator i);
DirContainer::ParentIterator ParentEnd();
@@ -76,10 +84,16 @@ private:
Notify * notify;
DirContainer dir_tab;
std::wstring temp_path;
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);
std::wstring analyze_temp;
void CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out);
int FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item);
bool ExtractName(const wchar_t * & s, std::wstring & name);
bool HasReadExecAccessForRoot(const Item & item);

View File

@@ -55,7 +55,6 @@
#define WINIX_DIFFERENT_MOUNT_POINTS 29
#define WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING 100
#define WINIX_ERR_DB_INCORRECT_QUERY 101
#define WINIX_ERR_DB_INCORRENT_RESULT_STATUS 102
@@ -70,6 +69,8 @@
//#define WINIX_ERR_UNKNOWN 1000
#define WINIX_NOTHING_TO_DO 109
typedef int Error;

View File

@@ -44,15 +44,19 @@ void Item::Clear()
subject.clear();
content.clear();
modify_index = 0;
url.clear();
content_type = ct_formatted_text;
type = none;
parent_id = -1;
default_item = -1;
link_to.clear();
link_redirect = false;
content_id = -1;
ref = 1;
file_path.clear();
file_fs = -1;

View File

@@ -19,6 +19,8 @@
#define WINIX_ITEM_FILETYPE_UNKNOWN 3
struct Item
{
long id;
@@ -38,8 +40,9 @@ tm date_modification;
std::wstring subject;
std::wstring content;
long content_id; // used by the database
std::wstring url;
int modify_index;
enum ContentType
{
@@ -58,22 +61,24 @@ enum Type
{
dir = 0,
file = 1,
symlink = 2,
none = 1000 // !! pozbyc sie tego
none = 1000
};
Type type;
long default_item;
// used when type is symlink or to a directory too (function 'default')
std::wstring link_to;
int link_redirect;
// static file (if exists)
std::wstring file_path; // relative file path
int file_fs; // file system type where the file was saved
int file_type; // file type (none, image, doc, etc)
bool has_thumb;
@@ -86,6 +91,14 @@ std::wstring html_template;
void SetDateModifyToNow();
void Clear();
private:
// used by the database
long content_id; // content id in 'content' table
int ref; // content references
friend class Db;
friend class DbItemColumns;
};

View File

@@ -15,21 +15,29 @@
Log::Log()
{
log_level = 3;
current_level = 4; // nothing to log (call Init() first)
item = 0;
item_save = 1;
log_level = 1;
current_level = 100; // nothing to log (call Init() first)
request = 0;
max_requests = 1;
lines = 0;
max_lines = 5000;
log_file_open = false;
}
void Log::Init(int log_l, const std::string & log_f, bool log_std, int log_request)
Log::~Log()
{
log_level = log_l;
log_file = log_f;
log_stdout = log_std;
item_save = log_request;
SaveLogAndClear();
}
void Log::Init(int log_level_, bool save_each_line_, const std::string & log_file_, bool log_std, int log_max_requests)
{
log_level = log_level_;
log_file = log_file_;
log_stdout = log_std;
max_requests = log_max_requests;
save_each_line = save_each_line_;
// don't open the file here
// because it would be created with the root as an owner
@@ -67,6 +75,9 @@ void Log::PutDate(Manipulators m)
Log & Log::operator<<(const void * s)
{
if( current_level > log_level )
return *this;
buffer << s;
return *this;
}
@@ -75,6 +86,9 @@ Log & Log::operator<<(const void * s)
Log & Log::operator<<(const char * s)
{
if( current_level > log_level )
return *this;
if( !s )
return *this;
@@ -87,7 +101,10 @@ return *this;
Log & Log::operator<<(const std::string & s)
{
buffer << s;
if( current_level > log_level )
return *this;
buffer << s;
return *this;
}
@@ -95,7 +112,10 @@ Log & Log::operator<<(const std::string & s)
Log & Log::operator<<(const std::string * s)
{
buffer << *s;
if( current_level > log_level )
return *this;
buffer << *s;
return *this;
}
@@ -106,10 +126,11 @@ Log & Log::operator<<(const std::string * s)
Log & Log::operator<<(const wchar_t * s)
{
if( !s )
return *this;
buffer << s;
if( current_level <= log_level )
{
if( s )
buffer << s;
}
return *this;
}
@@ -118,7 +139,11 @@ return *this;
Log & Log::operator<<(const std::wstring & s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -126,7 +151,11 @@ Log & Log::operator<<(const std::wstring & s)
Log & Log::operator<<(const std::wstring * s)
{
buffer << *s;
if( current_level <= log_level )
{
buffer << *s;
}
return *this;
}
@@ -136,7 +165,11 @@ Log & Log::operator<<(const std::wstring * s)
Log & Log::operator<<(int s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -144,7 +177,11 @@ Log & Log::operator<<(int s)
Log & Log::operator<<(long s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -153,7 +190,11 @@ Log & Log::operator<<(long s)
Log & Log::operator<<(char s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -161,7 +202,11 @@ Log & Log::operator<<(char s)
Log & Log::operator<<(size_t s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -169,7 +214,11 @@ Log & Log::operator<<(size_t s)
Log & Log::operator<<(double s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -180,36 +229,23 @@ Log & Log::operator<<(Manipulators m)
switch(m)
{
case logend:
buffer << '\n';
lines += 1;
//if( lines > 3000 )
if( current_level <= log_level )
{
SaveLog();
buffer.Clear();
item = 0;
lines = 0;
buffer << '\n';
lines += 1;
if( save_each_line )
SaveLogAndClear();
}
break;
case logsavenow:
SaveLog();
buffer.Clear();
item = 0;
lines = 0;
break;
case logsave:
item += 1;
SaveLogAndClear();
break;
if( item >= item_save || lines > 3000 )
{
SaveLog();
buffer.Clear();
item = 0;
lines = 0;
}
case logendrequest:
if( ++request >= max_requests || lines > max_lines )
SaveLogAndClear();
break;
case log1:
@@ -223,6 +259,10 @@ Log & Log::operator<<(Manipulators m)
case log3:
current_level = 3;
break;
case log4:
current_level = 4;
break;
}
return *this;
@@ -240,12 +280,18 @@ void Log::SystemErr(int err)
}
void Log::SaveLogAndClear()
{
SaveLog();
buffer.Clear();
request = 0;
lines = 0;
}
void Log::SaveLog()
{
if( current_level > log_level )
return;
if( buffer.Str().empty() )
return;

View File

@@ -18,19 +18,24 @@
#include "textstream.h"
// !! dodac manipulator logsave, logi zostana zapisane pod koniec wykonywania jednego requesta (albo po kilku w zaleznosci od jakiejs opcji w konfigu)
// logsave zostanie wywolane w requestcontroller.cpp przy konczeniu wykonywania requesta
enum Manipulators { logsave, logsavenow, logend, log1, log2, log3 };
// log1 - the first level
// log2
// log3
// log4 - the last level (debug level)
// logend - the end of a line
// logendrequest - end of a current request
// logsave - current log buffer is saved and cleared
enum Manipulators { log1, log2, log3, log4, logend, logendrequest, logsave };
class Log
{
public:
Log();
void Init(int log_l, const std::string & log_f, bool log_std, int log_request);
~Log();
void Init(int log_level_, bool save_each_line_, const std::string & log_file_, bool log_std, int log_max_requests);
void PutDate(Manipulators m);
Log & operator<<(const void * s);
@@ -49,17 +54,46 @@ public:
void SystemErr(int err);
void SaveLog();
void SaveLogAndClear();
private:
// buffer for the log
TextStream<std::wstring> buffer;
int log_level, current_level;
int item, item_save;
// log lovel from the config file
int log_level;
// current level set by a modifier (e.g. log << log3)
int current_level;
// current request for logging
// starts from zero and incremented after logendrequest modifier
int request;
// how many request to save at once
int max_requests;
// file log
std::string log_file;
bool log_stdout;
std::ofstream file;
// logging to stdout
bool log_stdout;
// how many lines there are in the buffer
int lines;
// is the config file already open
bool log_file_open;
// how many lines can be in the config buffer
// default: 5000
int max_lines;
// whether to save each line (for debug)
bool save_each_line;
void OpenFile();
};

View File

@@ -860,6 +860,11 @@ return WINIX_ITEM_FILETYPE_UNKNOWN;
}
int SelectFileType(const std::wstring & file_name)
{
return SelectFileType(file_name.c_str());
}
time_t Time(const tm & par)
{
@@ -904,3 +909,46 @@ tm Time(time_t par)
return res;
}
void UrlEncode(const std::string & in, std::string & out, bool clear_out)
{
char buffer[10];
if( clear_out )
out.clear();
for(size_t i=0 ; i<in.size() ; ++i)
{
if( (in[i] >= 'a' && in[i] <= 'z') ||
(in[i] >= 'A' && in[i] <= 'Z') ||
(in[i] >= '0' && in[i] <= '9') ||
in[i] == '.' || in[i] == ',' || in[i] == '/' || in[i] == ':' || in[i] == '#' ||
in[i] == '-' || in[i] == '_' || in[i] == '(' || in[i] == ')' )
{
out += in[i];
}
else
{
Toa(static_cast<unsigned char>(in[i]), buffer, 10, 16);
out += '%';
if( buffer[1] == 0 )
out += '0'; // there is only one characters in the buffer
out += buffer;
}
}
}
void UrlEncode(const std::wstring & in, std::string & out, bool clear_out)
{
static std::string ain;
Ezc::WideToUTF8(in, ain);
UrlEncode(ain, out, clear_out);
}

View File

@@ -415,9 +415,16 @@ bool RenameFile(const std::wstring & from, const std::wstring & to);
const wchar_t * GetFileExt(const wchar_t * name);
int SelectFileType(const wchar_t * file_name);
int SelectFileType(const std::wstring & file_name);
time_t Time(const tm & par);
time_t Time(const tm * par);
tm Time(time_t par);
void UrlEncode(const std::string & in, std::string & out, bool clear_out = true);
void UrlEncode(const std::wstring & in, std::string & out, bool clear_out = true);
#endif

View File

@@ -232,6 +232,9 @@ void Mounts::MountCmsForRoot()
log << log1 << "M: there is no a root dir" << logend;
}
mount.param.resize(mount_par_tab.size());
mount.ClearParams();
std::pair<MountTab::iterator, bool> res = mount_tab.insert( std::make_pair(mount.dir_id, mount) );
pmount = &(res.first->second);
}

View File

@@ -168,7 +168,7 @@ void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
return 0;
}
log << log1 << "Plugin: plugin loaded"
log << log2 << "Plugin: plugin loaded"
<< ", file: " << filename
<< ", index: " << plugins.size() << logend;
@@ -258,7 +258,7 @@ void Plugin::Call(int message, Slots::iterator & slot)
if( !slot->second.is_running )
{
if( config->log_plugin_call )
log << log3 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
slot->second.is_running = true;
@@ -271,7 +271,7 @@ void Plugin::Call(int message, Slots::iterator & slot)
slot->second.is_running = false;
if( config->log_plugin_call )
log << log3 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message << logend;
log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message << logend;
}
else

View File

@@ -483,7 +483,7 @@ size_t buf_len = sizeof(buf)/sizeof(wchar_t);
return;
}
swprintf(buf, buf_len, L"%ls/tmp/winix_%u_%d_%u", config->upload_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
swprintf(buf, buf_len, L"%ls/tmp/pmp_%u_%d_%u", config->upload_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
tmp_filename_postfix += 1;
tmp_filename = buf;

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

View File

@@ -66,8 +66,12 @@ public:
void SetSynchro(Synchro * psynchro);
void Init();
void AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str = true);
void RedirectTo(const Item & item, const wchar_t * postfix = 0);
void RedirectTo(long item_id, const wchar_t * postfix = 0);
void RedirectTo(const std::wstring & url);
void RedirectWithFunctionAndParamsTo(const std::wstring & url);
void RedirectToLastDir();
void RedirectToLastItem(); // redirect to an item if exists or to the last directory
@@ -80,6 +84,7 @@ public:
bool HasReadWriteAccess(const Item & item);
bool HasReadExecAccess(const Item & item);
bool HasReadExecAccessToPath(long dir_id);
bool HasReadExecAccessToPath(const std::vector<Item*> & dir_tab);
bool DirsHaveReadExecPerm();
void CheckAccessToItems(std::vector<Item> & item_tab);
@@ -93,6 +98,8 @@ public:
bool CreateNewFile(Item & item);
bool MakeFilePath(const Item & item, std::wstring & path, bool thumb = false, bool create_dir = false, int chmod = 0755);
bool MakePath(const Item & item, std::wstring & path, bool clear_path = true);
Error AddFile(Item & item, int notify_code = 0);
Error EditFile(Item & item, bool with_url = true, int notify_code = 0);
@@ -101,7 +108,21 @@ public:
tm LocalTime(const tm * ptm);
tm LocalTime(const tm & ptm);
int FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item);
int 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 = false, bool stop_on_link_redirect = false, bool check_access = true);
// starting from root dir
int FollowAllLinks(const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item,
bool follow_dir_default = false, bool stop_on_link_redirect = false, bool check_access = true);
// using request->dir_tab and request->item
bool FollowAllLinks(const std::wstring & link_to,
bool follow_dir_default = false, bool stop_on_link_redirect = false, bool check_access = true);
private:
Request * request;
@@ -109,10 +130,22 @@ private:
Db * db;
Synchro * synchro;
std::wstring path;
Item item_temp;
std::wstring link_to_temp, name_temp;
// for FollowAllLinks
std::vector<Item*> temp_follow_dir_tab;
std::vector<Item*> root_follow_dir_tab;
Item temp_follow_item;
bool CreateNewFileSimpleFs(Item & item);
bool CreateNewFileHashFs(Item & item);
bool FollowAllLinksDirFound(std::vector<Item*> & out_dir_tab,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access);
bool FollowAllLinksFileOrSymlinkFound(std::vector<Item*> & out_dir_tab, Item & out_item,
bool stop_on_link_redirect, bool check_access);
};

View File

@@ -2,24 +2,30 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorecorethread
#define headerfilecmslucorecorethread
#ifndef headerfile_winix_plugins_thread_thread
#define headerfile_winix_plugins_thread_thread
#include <string>
namespace Thread
{
class Thread
{
public:
long id;
long parent_id;
long file_id;
//long parent_id;
long dir_id;
bool closed;
@@ -50,4 +56,10 @@ public:
};
} // namespace
#endif

View File

@@ -7,17 +7,14 @@
*
*/
#include <ctime>
#include "thumb.h"
#include "utf8.h"
#include "log.h"
#include "system.h"
void Thumb::SetConvertCmd(const std::wstring & cmd)
{
convert_cmd = cmd;
}
void Thumb::SetDb(Db * pdb)
{
@@ -25,12 +22,22 @@ void Thumb::SetDb(Db * pdb)
}
// first thread (objects locked)
void Thumb::CreateThumb(long item_id, const std::wstring & source, const std::wstring & dst, size_t cx, size_t cy, int aspect_mode)
void Thumb::SetConfig(Config * pconfig)
{
item_temp.item_id = item_id;
item_temp.source = source;
item_temp.dst = dst;
config = pconfig;
}
void Thumb::SetSystem(System * psystem)
{
system = psystem;
}
// first thread (objects locked)
void Thumb::CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode)
{
item_temp.file = item;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
@@ -155,33 +162,107 @@ void Thumb::SelectAspect()
}
// second thread (objects are not locked)
void Thumb::CreateThumbnail()
{
command.Clear();
Ezc::WideToUTF8(convert_cmd, tempa);
// second thread (objects are not locked)
bool Thumb::CreateCommand()
{
bool res;
command.Clear();
stream_tmp_path.Clear();
Lock();
Ezc::WideToUTF8(config->convert_cmd, tempa);
command << tempa << " -quiet -strip -thumbnail ";
SelectAspect();
command << " ";
Ezc::WideToUTF8(item_work.source, tempa);
EscapePath(tempa);
Ezc::WideToUTF8(item_work.dst, tempa);
EscapePath(tempa);
if( system(command.CStr()) == 0 )
if( system->MakeFilePath(item_work.file, src_path) )
{
Lock();
log << log3 << "Thumb: created a thumbnail: " << tempa << logend;
db->EditHasThumbById(true, item_work.item_id);
Unlock();
Ezc::WideToUTF8(src_path, tempa);
EscapePath(tempa);
stream_tmp_path << config->upload_dir << L"/tmp/thumb_" << std::time(0);
Ezc::WideToUTF8(stream_tmp_path.Str(), string_tmp_patha);
EscapePath(string_tmp_patha);
res = true;
}
else
{
log << log1 << "Thumb: cannot create a source path" << logend;
res = false;
}
Unlock();
return res;
}
// second thread (objects are not locked)
void Thumb::SaveTmpThumbnail()
{
bool moved = false;
Lock();
// the file could have been changed especially when creating thumbnail lasted too long
iq.SetAll(false, false);
iq.sel_parent_id = true;
iq.sel_file = true;
iq.sel_url = true;
iq.sel_type = true;
iq.WhereId(item_work.file.id);
if( db->GetItem(item_work.file, iq) == WINIX_ERR_OK )
{
if( system->MakeFilePath(item_work.file, dst_path, true, true, config->upload_dirs_chmod) )
{
if( RenameFile(stream_tmp_path.Str(), dst_path) )
{
log << log3 << "Thumb: created a thumbnail: " << dst_path << logend;
db->EditHasThumbById(true, item_work.file.id);
moved = true;
}
else
{
log << log1 << "Thumb: cannot move a temporary file: " << stream_tmp_path.Str() << ", to: " << dst_path << logend;
}
}
else
{
log << log1 << "Thumb: cannot create a destination path" << logend;
}
}
if( !moved )
::RemoveFile(stream_tmp_path.Str());
Unlock();
}
// second thread (objects are not locked)
void Thumb::CreateThumbnail()
{
if( !CreateCommand() )
return;
int res = std::system(command.CStr());
if( res == 0 )
{
SaveTmpThumbnail();
}
else
{
Lock();
log << log3 << "Thumb: some problems with creating a thumbnail: " << tempa << logend;
log << log3 << "Thumb: some problems with creating a thumbnail " << tempa
<< ", 'convert' process returned: " << res << logend;
Unlock();
}
}

View File

@@ -10,11 +10,16 @@
#ifndef headerfilecmslucorethumb
#define headerfilecmslucorethumb
#include "basethread.h"
#include <string>
#include <list>
#include "basethread.h"
#include "textstream.h"
#include "db/db.h"
#include "core/item.h"
#include "core/config.h"
class System;
@@ -46,21 +51,21 @@ class Thumb : public BaseThread
{
public:
void CreateThumb(long item_id, const std::wstring & source, const std::wstring & dst,
size_t cx, size_t cy, int aspect_mode = WINIX_THUMB_MODE_2);
void CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode);
void SetConvertCmd(const std::wstring & cmd);
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
private:
Db * db;
Config * config;
System * system;
struct ThumbItem
{
long item_id;
std::wstring source;
std::wstring dst;
Item file;
size_t cx;
size_t cy;
int aspect_mode;
@@ -71,16 +76,18 @@ private:
ThumbTab thumb_tab;
ThumbItem item_temp;
// this is set before the second thread starts
std::wstring convert_cmd;
// only for second thread
ThumbItem item_work;
std::string tempa;
std::wstring src_path, dst_path;
std::string tempa, string_tmp_patha;
TextStream<std::string> command;
TextStream<std::wstring> stream_tmp_path;
DbItemQuery iq;
virtual bool SignalReceived();
virtual void Do();
bool CreateCommand();
void SaveTmpThumbnail();
void CreateThumbnail();
void SelectAspect();
void EscapePath(const std::string & path);

View File

@@ -185,7 +185,7 @@ void UGContainer<Type>::AddIndexes(UGContainer<Type>::SizeType pos)
table_id.insert( std::make_pair(table[pos].id, pos) );
table_name.insert( std::make_pair(table[pos].name, pos) );
log << log2 << "UGCont: added indexes to: id: " << table[pos].id << ", name: " << table[pos].name << logend;
log << log4 << "UGCont: added indexes to: id: " << table[pos].id << ", name: " << table[pos].name << logend;
}
@@ -193,7 +193,7 @@ void UGContainer<Type>::AddIndexes(UGContainer<Type>::SizeType pos)
template<class Type>
void UGContainer<Type>::RebuildIndexes()
{
log << log2 << "UGCont: rebuilding indexes" << logend;
log << log4 << "UGCont: rebuilding indexes" << logend;
table_id.clear();
table_name.clear();
@@ -204,7 +204,7 @@ void UGContainer<Type>::RebuildIndexes()
for(i=0 ; i!=len ; ++i)
AddIndexes( i );
log << log2 << "UGCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: "
log << log4 << "UGCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: "
<< table_id.size() << ", table_name.size: " << table_name.size() << logend;
}

View File

@@ -13,7 +13,7 @@
#define WINIX_VER_MAJOR 0
#define WINIX_VER_MINOR 4
#define WINIX_VER_REVISION 0
#define WINIX_VER_REVISION 5
#endif