2010-08-10 18:12:50 +02:00
|
|
|
/*
|
|
|
|
* This file is a part of Winix
|
2014-10-04 20:04:03 +02:00
|
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2021-02-24 01:19:47 +01:00
|
|
|
* Copyright (c) 2010-2021, Tomasz Sowa
|
2010-08-10 18:12:50 +02:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2014-10-04 20:04:03 +02:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
2010-08-10 18:12:50 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "system.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "error.h"
|
2010-10-19 02:31:20 +02:00
|
|
|
#include "templates/templates.h"
|
2011-09-14 11:56:00 +02:00
|
|
|
#include "functions/functions.h"
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-12 17:30:49 +01:00
|
|
|
namespace Winix
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
void System::SetCur(Cur * pcur)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur = pcur;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-21 12:03:53 +01:00
|
|
|
//void System::SetConfig(Config * pconfig)
|
|
|
|
//{
|
|
|
|
// config = pconfig;
|
|
|
|
//}
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
void System::SetDb(Db * pdb)
|
|
|
|
{
|
|
|
|
db = pdb;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-21 12:03:53 +01:00
|
|
|
//void System::SetSynchro(Synchro * psynchro)
|
|
|
|
//{
|
|
|
|
// synchro = psynchro;
|
|
|
|
//}
|
2010-12-02 02:02:02 +01:00
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2011-09-14 11:56:00 +02:00
|
|
|
void System::SetFunctions(Functions * pfunctions)
|
|
|
|
{
|
|
|
|
functions = pfunctions;
|
|
|
|
}
|
|
|
|
|
2012-03-09 03:36:25 +01:00
|
|
|
void System::SetSessionManager(SessionManager * sm)
|
|
|
|
{
|
|
|
|
session_manager = sm;
|
|
|
|
}
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
2021-06-16 18:07:44 +02:00
|
|
|
void System::set_dependency(WinixModelDeprecated * winix_model)
|
2018-11-21 12:03:53 +01:00
|
|
|
{
|
2021-06-16 18:07:44 +02:00
|
|
|
WinixModelDeprecated::set_dependency(winix_model);
|
2018-11-21 23:53:24 +01:00
|
|
|
|
|
|
|
dirs.set_dependency(this);
|
|
|
|
mounts.set_dependency(this);
|
2021-06-27 23:31:50 +02:00
|
|
|
//users.set_dependency(this);
|
|
|
|
users.set_connector(model_connector);
|
2018-11-21 23:53:24 +01:00
|
|
|
groups.set_dependency(this);
|
|
|
|
rebus.set_dependency(this);
|
|
|
|
load_avg.set_dependency(this);
|
|
|
|
notify.set_dependency(this);
|
|
|
|
image.set_dependency(this);
|
|
|
|
crypt.set_dependency(this);
|
|
|
|
thread_manager.set_dependency(this);
|
2018-11-21 12:03:53 +01:00
|
|
|
job.set_dependency(winix_model);
|
|
|
|
time_zones.set_dependency(winix_model);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-23 01:34:33 +02:00
|
|
|
void System::ReadTimeZones()
|
|
|
|
{
|
|
|
|
if( config->etc_dir.empty() )
|
|
|
|
{
|
|
|
|
log << log1 << "System: I cannot read time zones, set etc_dir directory in the config" << logend;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( config->time_zones_file.empty() )
|
|
|
|
{
|
|
|
|
log << log1 << "System:: I cannot read time zones, set time_zones_file in the config" << logend;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
name_temp = config->etc_dir;
|
|
|
|
name_temp += '/';
|
|
|
|
name_temp += config->time_zones_file;
|
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
time_zones.SetTimeZoneMaxId(config->time_zone_max_id);
|
2012-06-23 01:34:33 +02:00
|
|
|
time_zones.ReadTimeZones(name_temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
void System::Init()
|
|
|
|
{
|
2018-11-21 12:03:53 +01:00
|
|
|
//thread_manager.SetSynchro(synchro);
|
2011-07-29 00:18:10 +02:00
|
|
|
thread_manager.Init();
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
dirs.SetDb(db);
|
2018-11-21 12:03:53 +01:00
|
|
|
dirs.SetCur(cur); // only one method is using cur, can be passed as a parameter to the method
|
2010-12-02 02:02:02 +01:00
|
|
|
dirs.SetNotify(¬ify);
|
2010-08-10 18:12:50 +02:00
|
|
|
dirs.ReadDirs();
|
|
|
|
|
2011-06-15 01:45:42 +02:00
|
|
|
mounts.SkipStaticDirs(config->dont_use_static_dirs);
|
2010-08-10 18:12:50 +02:00
|
|
|
mounts.SetDirs(&dirs);
|
|
|
|
mounts.SetDb(db);
|
2018-11-21 12:03:53 +01:00
|
|
|
mounts.SetCur(cur); // only one method is using cur, can be passed as a parameter to the method
|
2010-09-13 01:33:27 +02:00
|
|
|
mounts.CreateMounts();
|
2010-08-10 18:12:50 +02:00
|
|
|
mounts.ReadMounts();
|
|
|
|
|
2021-06-27 23:31:50 +02:00
|
|
|
// users.SetCur(cur);
|
|
|
|
// users.SetSessionManager(session_manager);
|
|
|
|
users.set_connector(model_connector);
|
2010-08-10 18:12:50 +02:00
|
|
|
users.ReadUsers(db);
|
2018-11-21 12:03:53 +01:00
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
groups.ReadGroups(db); // !! chwilowe przekazanie argumentu, db bedzie zmienione
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
rebus.SetCur(cur);
|
2010-08-10 18:12:50 +02:00
|
|
|
rebus.Init();
|
2010-12-02 02:02:02 +01:00
|
|
|
|
2018-11-21 23:53:24 +01:00
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
notify.SetCur(cur);
|
2018-11-21 12:03:53 +01:00
|
|
|
//notify.SetConfig(config);
|
2010-12-02 02:02:02 +01:00
|
|
|
notify.SetUsers(&users);
|
|
|
|
notify.SetDirs(&dirs);
|
2011-07-29 00:18:10 +02:00
|
|
|
notify.SetThreadManager(&thread_manager);
|
2010-12-02 02:02:02 +01:00
|
|
|
notify.Init();
|
2010-12-11 23:55:48 +01:00
|
|
|
|
2011-09-13 08:08:34 +02:00
|
|
|
image.SetDb(db);
|
|
|
|
image.SetConfig(config);
|
|
|
|
image.SetSystem(this);
|
2012-05-19 19:04:33 +02:00
|
|
|
thread_manager.Add(&image, L"image");
|
changed: when winix demonizes it creates a three new descriptors (0, 1 and 3)
pointing to /dev/null
added: DbBase::AssertValueBin(PGresult * r, int row, int col, std::string & result)
it reads binary (bytea) data
added: DbTextStream can handle 'bool' types now
(is puts 'true' of 'false' to the stream)
changed: now passwords can be stored either as plain text, a hash or can be encrypted
with RSA
currently we have following hashes:
md4, md5, sha1, sha224, sha256, sha384, sha512
we are using openssl to manage them
(look at config options for more info)
changed: winix version to 0.4.7
added: class Run - you can run any program from os and send a buffer to its standard input
and read what the program put on its standard output
added: class Crypt (in System) - calculating hashes, and crypting/decrypting
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@734 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-09 23:22:08 +02:00
|
|
|
|
2018-11-21 23:53:24 +01:00
|
|
|
|
|
|
|
|
2012-04-26 00:24:37 +02:00
|
|
|
|
|
|
|
// SetSynchro will be called by ThreadManager itself
|
|
|
|
// job.ReadFromFile();
|
2012-05-19 19:04:33 +02:00
|
|
|
thread_manager.Add(&job, L"job");
|
2012-06-23 01:34:33 +02:00
|
|
|
|
|
|
|
ReadTimeZones();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-22 23:26:56 +02:00
|
|
|
/*
|
|
|
|
* try_to_use_ssl is to be meant: config->use_ssl, config->use_ssl_static, config->use_ssl_common
|
|
|
|
*/
|
|
|
|
bool System::IsSSLRequired(bool try_to_use_ssl)
|
2011-08-18 01:09:47 +02:00
|
|
|
{
|
2018-04-22 23:26:56 +02:00
|
|
|
bool ssl = false;
|
2011-08-18 01:09:47 +02:00
|
|
|
|
2018-04-22 23:26:56 +02:00
|
|
|
if( try_to_use_ssl )
|
2011-08-18 01:09:47 +02:00
|
|
|
{
|
2011-09-14 11:56:00 +02:00
|
|
|
if( !config->use_ssl_only_for_logged_users ||
|
|
|
|
cur->session->puser ||
|
2012-09-24 22:31:01 +02:00
|
|
|
(cur->request->function && cur->request->function->need_ssl) )
|
2011-08-18 01:09:47 +02:00
|
|
|
{
|
|
|
|
ssl = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-22 23:26:56 +02:00
|
|
|
return ssl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::IsSSLRequired()
|
|
|
|
{
|
|
|
|
return IsSSLRequired(config->use_ssl);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* try_to_use_ssl is to be meant: config->use_ssl, config->use_ssl_static, config->use_ssl_common
|
|
|
|
*/
|
|
|
|
void System::PutUrlProto(bool can_use_ssl, std::wstring & str, bool clear_str)
|
|
|
|
{
|
|
|
|
if( clear_str )
|
|
|
|
str.clear();
|
|
|
|
|
|
|
|
if( IsSSLRequired() )
|
|
|
|
str += config->url_ssl_proto;
|
|
|
|
else
|
2011-08-18 01:09:47 +02:00
|
|
|
str += config->url_proto;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-22 23:26:56 +02:00
|
|
|
/*
|
|
|
|
* try_to_use_ssl is to be meant: config->use_ssl, config->use_ssl_static, config->use_ssl_common
|
|
|
|
*/
|
2021-05-20 20:59:12 +02:00
|
|
|
void System::PutUrlProto(bool can_use_ssl, pt::TextStream & str, bool clear_stream)
|
2018-04-22 23:26:56 +02:00
|
|
|
{
|
|
|
|
if( clear_stream )
|
|
|
|
str.clear();
|
|
|
|
|
|
|
|
if( IsSSLRequired(can_use_ssl) )
|
|
|
|
{
|
|
|
|
str << config->url_ssl_proto;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str << config->url_proto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void System::PutUrlProto(std::wstring & str, bool clear_str)
|
|
|
|
{
|
|
|
|
return PutUrlProto(config->use_ssl, str, clear_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
void System::PutUrlProto(pt::TextStream & str, bool clear_stream)
|
2018-04-22 23:26:56 +02:00
|
|
|
{
|
|
|
|
return PutUrlProto(config->use_ssl, str, clear_stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-14 21:59:23 +01:00
|
|
|
void System::CreateItemLink(long parent_id, const std::wstring & url, const std::wstring & subdomain,
|
|
|
|
std::wstring & link, bool clear_str)
|
|
|
|
{
|
2018-04-22 23:26:56 +02:00
|
|
|
PutUrlProto(link, clear_str);
|
2013-11-14 21:59:23 +01:00
|
|
|
|
|
|
|
if( !subdomain.empty() )
|
|
|
|
{
|
|
|
|
link += subdomain;
|
|
|
|
link += '.';
|
|
|
|
}
|
|
|
|
|
|
|
|
link += config->base_url;
|
|
|
|
dirs.MakePath(parent_id, link, false); // !! IMPROVE ME may some kind of error checks here?
|
|
|
|
link += url;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void System::CreateItemLink(const Item & item, std::wstring & link, bool clear_str)
|
|
|
|
{
|
|
|
|
CreateItemLink(item.parent_id, item.url, cur->request->subdomain, link, clear_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
// !! IMPROVE ME
|
2010-08-10 18:12:50 +02:00
|
|
|
// !! mozna zrobic jakas obsluge kiedy nie mozemy sie redirectnac, np gdy wystapil blad
|
|
|
|
// !! moze zwracac jakas wartosc?
|
2012-02-19 01:59:08 +01:00
|
|
|
/*
|
|
|
|
postfix will not be UrlEncoded
|
|
|
|
*/
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectTo(const Item & item, const wchar_t * postfix, bool use_reqtype)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2018-04-22 23:26:56 +02:00
|
|
|
PutUrlProto(cur->request->redirect_to);
|
2012-04-22 20:23:44 +02:00
|
|
|
|
|
|
|
if( !cur->request->subdomain.empty() )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += cur->request->subdomain;
|
|
|
|
cur->request->redirect_to += '.';
|
|
|
|
}
|
|
|
|
|
2011-08-18 01:09:47 +02:00
|
|
|
cur->request->redirect_to += config->base_url;
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
if( item.type == Item::dir )
|
|
|
|
{
|
|
|
|
// item_id is pointing to a directory
|
2011-01-23 15:15:30 +01:00
|
|
|
dirs.MakePath(item.id, cur->request->redirect_to, false);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
// item_id is pointing to a file or a symlink
|
2011-01-23 15:15:30 +01:00
|
|
|
if( dirs.MakePath(item.parent_id, cur->request->redirect_to, false) )
|
|
|
|
cur->request->redirect_to += item.url;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if( postfix )
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to += postfix;
|
2013-03-26 01:04:01 +01:00
|
|
|
|
|
|
|
if( use_reqtype && cur->request->IsParam(L"reqtype") )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += L"/-/reqtype:";
|
|
|
|
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
|
|
|
|
}
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
/*
|
|
|
|
postfix will not be UrlEncoded
|
|
|
|
*/
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectTo(long item_id, const wchar_t * postfix, bool use_reqtype)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2018-04-22 23:26:56 +02:00
|
|
|
PutUrlProto(cur->request->redirect_to);
|
2012-04-22 20:23:44 +02:00
|
|
|
|
|
|
|
if( !cur->request->subdomain.empty() )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += cur->request->subdomain;
|
|
|
|
cur->request->redirect_to += '.';
|
|
|
|
}
|
|
|
|
|
2011-08-18 01:09:47 +02:00
|
|
|
cur->request->redirect_to += config->base_url;
|
2011-01-05 22:24:11 +01:00
|
|
|
Item * pdir = dirs.GetDir(item_id);
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
if( pdir )
|
|
|
|
{
|
|
|
|
// item_id is pointing to a directory
|
2011-01-23 15:15:30 +01:00
|
|
|
dirs.MakePath(pdir->id, cur->request->redirect_to, false);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
// item_id is pointing to a file
|
2021-02-24 01:19:47 +01:00
|
|
|
// DbItemQuery iq;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
// iq.SetAllSel(false);
|
|
|
|
// iq.WhereId(item_id);
|
|
|
|
// iq.sel_parent_id = true;
|
|
|
|
// iq.sel_url = true;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
morm::Finder<Item> finder(model_connector);
|
|
|
|
|
|
|
|
item_temp = finder.
|
|
|
|
select().
|
|
|
|
where().
|
|
|
|
eq(L"id", item_id).
|
|
|
|
get();
|
|
|
|
|
|
|
|
//if( db->GetItem(item_temp, iq) == WINIX_ERR_OK )
|
|
|
|
if( item_temp.found() )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( dirs.MakePath(item_temp.parent_id, cur->request->redirect_to, false) )
|
|
|
|
cur->request->redirect_to += item_temp.url;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
log << log1 << "System: can't redirect: no such item: id: " << item_id << logend;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( postfix )
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to += postfix;
|
2013-03-26 01:04:01 +01:00
|
|
|
|
|
|
|
if( use_reqtype && cur->request->IsParam(L"reqtype") )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += L"/-/reqtype:";
|
|
|
|
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
|
|
|
|
}
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
url will not be UrlEncoded
|
|
|
|
*/
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectTo(const wchar_t * url, bool use_reqtype)
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
2018-04-22 23:26:56 +02:00
|
|
|
PutUrlProto(cur->request->redirect_to);
|
2012-04-22 20:23:44 +02:00
|
|
|
|
|
|
|
if( !cur->request->subdomain.empty() )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += cur->request->subdomain;
|
|
|
|
cur->request->redirect_to += '.';
|
|
|
|
}
|
|
|
|
|
2011-08-18 01:09:47 +02:00
|
|
|
cur->request->redirect_to += config->base_url;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
if( url[0] == '/' )
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
|
|
|
// absolute path
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to += url;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// relative path
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->request->dir_tab.empty() )
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( dirs.MakePath(cur->request->dir_tab.back()->id, cur->request->redirect_to, false) )
|
|
|
|
cur->request->redirect_to += url;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to += '/';
|
|
|
|
cur->request->redirect_to += url;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
}
|
2013-03-26 01:04:01 +01:00
|
|
|
|
|
|
|
if( use_reqtype && cur->request->IsParam(L"reqtype") )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += L"/-/reqtype:";
|
|
|
|
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
|
|
|
|
}
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
/*
|
|
|
|
url will not be UrlEncoded
|
|
|
|
*/
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectTo(const std::wstring & url, bool use_reqtype)
|
2012-02-19 01:59:08 +01:00
|
|
|
{
|
2013-03-26 01:04:01 +01:00
|
|
|
RedirectTo(url.c_str(), use_reqtype);
|
2012-02-19 01:59:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
params will be UrlEncoded
|
|
|
|
*/
|
2011-01-05 22:24:11 +01:00
|
|
|
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 += '/';
|
2012-02-19 01:59:08 +01:00
|
|
|
UrlEncode(param_tab[i].name, str, false);
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
if( !param_tab[i].value.empty() )
|
|
|
|
{
|
|
|
|
str += ':';
|
2012-02-19 01:59:08 +01:00
|
|
|
UrlEncode(param_tab[i].value, str, false);
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
/*
|
|
|
|
url will not be UrlEncoded
|
|
|
|
params will be UrlEncoded
|
|
|
|
*/
|
|
|
|
void System::RedirectWithFunctionAndParamsTo(const wchar_t * url)
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
|
|
|
RedirectTo(url);
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->request->function )
|
2011-01-05 22:24:11 +01:00
|
|
|
return;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to += '/';
|
2012-02-19 01:59:08 +01:00
|
|
|
cur->request->redirect_to += cur->request->function->fun.url;
|
2011-01-23 15:15:30 +01:00
|
|
|
AddParams(cur->request->param_tab, cur->request->redirect_to, false);
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-19 01:59:08 +01:00
|
|
|
/*
|
|
|
|
url will not be UrlEncoded
|
|
|
|
params will be UrlEncoded
|
|
|
|
*/
|
|
|
|
void System::RedirectWithFunctionAndParamsTo(const std::wstring & url)
|
|
|
|
{
|
|
|
|
RedirectWithFunctionAndParamsTo(url.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectToLastDir(const wchar_t * postfix, bool use_reqtype)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->request->dir_tab.empty() )
|
2013-03-26 01:04:01 +01:00
|
|
|
RedirectTo( *cur->request->dir_tab.back(), postfix, use_reqtype);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectToLastItem(const wchar_t * postfix, bool use_reqtype)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->request->last_item )
|
2013-03-26 01:04:01 +01:00
|
|
|
RedirectTo( *cur->request->last_item, postfix, use_reqtype );
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-26 01:04:01 +01:00
|
|
|
void System::RedirectToLastFunction(const wchar_t * postfix, bool use_reqtype)
|
2012-10-27 11:03:49 +02:00
|
|
|
{
|
2013-03-26 01:04:01 +01:00
|
|
|
RedirectToLastDir(0, false);
|
|
|
|
TrimLast(cur->request->redirect_to, '/');
|
2012-10-27 11:03:49 +02:00
|
|
|
|
|
|
|
if( cur->request->is_item )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += '/';
|
2013-03-26 01:04:01 +01:00
|
|
|
cur->request->redirect_to += cur->request->item.url;
|
2012-10-27 11:03:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if( cur->request->function )
|
2013-03-26 01:04:01 +01:00
|
|
|
{
|
|
|
|
cur->request->redirect_to += '/';
|
2012-10-27 11:03:49 +02:00
|
|
|
cur->request->redirect_to += cur->request->function->fun.url;
|
2013-03-26 01:04:01 +01:00
|
|
|
}
|
2012-10-27 11:03:49 +02:00
|
|
|
|
|
|
|
if( postfix )
|
|
|
|
{
|
|
|
|
cur->request->redirect_to += '/';
|
|
|
|
cur->request->redirect_to += postfix;
|
|
|
|
}
|
2013-03-26 01:04:01 +01:00
|
|
|
|
|
|
|
if( use_reqtype && cur->request->IsParam(L"reqtype") )
|
|
|
|
{
|
|
|
|
if( !cur->request->function && !postfix )
|
|
|
|
cur->request->redirect_to += L"/-";
|
|
|
|
|
|
|
|
cur->request->redirect_to += L"/reqtype:";
|
|
|
|
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
|
|
|
|
}
|
|
|
|
|
2012-10-27 11:03:49 +02:00
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
bool System::CanChangeUser(const Item & item, long new_user_id)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session )
|
2010-08-10 18:12:50 +02:00
|
|
|
// session must be set
|
|
|
|
return false;
|
|
|
|
|
2021-06-27 23:31:50 +02:00
|
|
|
if( cur->session->puser && cur->session->puser->is_super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.user_id == -1 || new_user_id == -1 || item.item_content.user_id != new_user_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
// only super user can change the owner of an item
|
|
|
|
return false;
|
|
|
|
|
2012-01-25 00:03:36 +01:00
|
|
|
// item.user_id is equal new_user_id -- we return true
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::CanChangeGroup(const Item & item, long new_group_id)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session )
|
2010-08-10 18:12:50 +02:00
|
|
|
// session must be set
|
|
|
|
return false;
|
|
|
|
|
2021-06-27 23:31:50 +02:00
|
|
|
if( cur->session->puser && cur->session->puser->is_super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.group_id != new_group_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
// 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'
|
|
|
|
|
2012-01-25 00:03:36 +01:00
|
|
|
if( !cur->session->puser || cur->session->puser->id == -1 )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.user_id == -1 || cur->session->puser->id != item.item_content.user_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if( new_group_id == -1 )
|
|
|
|
return true;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session->puser->IsMemberOf(new_group_id) )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// is logged, is the owner of the item, is the member of the new group
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::CanChangePrivileges(const Item & item, int new_priv)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session )
|
2010-08-10 18:12:50 +02:00
|
|
|
// session must be set
|
|
|
|
return false;
|
|
|
|
|
2021-06-27 23:31:50 +02:00
|
|
|
if( cur->session->puser && cur->session->puser->is_super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.privileges != new_priv )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2012-01-25 00:03:36 +01:00
|
|
|
// the owner of an item is allowed to change the privileges
|
|
|
|
|
|
|
|
if( !cur->session->puser || cur->session->puser->id == -1 )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
2012-01-25 00:03:36 +01:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.user_id == -1 || cur->session->puser->id != item.item_content.user_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-18 19:18:13 +02:00
|
|
|
// DEPRACATED
|
2010-08-10 18:12:50 +02:00
|
|
|
bool System::HasReadAccess(const Item & item)
|
|
|
|
{
|
2021-06-18 19:18:13 +02:00
|
|
|
return item.item_content.has_read_access();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-18 19:18:13 +02:00
|
|
|
// DEPRACATED
|
2010-08-10 18:12:50 +02:00
|
|
|
bool System::HasWriteAccess(const Item & item)
|
|
|
|
{
|
2021-06-18 19:18:13 +02:00
|
|
|
return item.item_content.has_write_access();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-18 19:18:13 +02:00
|
|
|
// DEPRACATED
|
2010-08-10 18:12:50 +02:00
|
|
|
bool System::HasReadWriteAccess(const Item & item)
|
|
|
|
{
|
2021-06-18 19:18:13 +02:00
|
|
|
return item.item_content.has_read_write_access();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-18 19:18:13 +02:00
|
|
|
// DEPRACATED
|
2010-08-10 18:12:50 +02:00
|
|
|
bool System::HasReadExecAccess(const Item & item)
|
|
|
|
{
|
2021-06-18 19:18:13 +02:00
|
|
|
return item.item_content.has_read_exec_access();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasReadExecAccessToPath(long dir_id)
|
|
|
|
{
|
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
Item * pdir = dirs.GetDir(dir_id);
|
|
|
|
|
|
|
|
if( !pdir )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if( !HasReadExecAccess(*pdir) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
dir_id = pdir->parent_id;
|
|
|
|
|
|
|
|
if( dir_id == -1 )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
bool System::HasReadExecAccessToPath(const std::vector<Item*> & dir_tab)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
for(size_t i=0 ; i < dir_tab.size() ; ++i)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
if( !HasReadExecAccess(*dir_tab[i]) )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
bool System::DirsHaveReadExecPerm()
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
return HasReadExecAccessToPath(cur->request->dir_tab);
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
// if we don't have access we only remove the item from the table
|
2011-08-02 02:10:45 +02:00
|
|
|
// !! moze zamienic nazwe na CheckReadAccessToItems ?
|
2010-08-10 22:43:38 +02:00
|
|
|
void System::CheckAccessToItems(std::vector<Item> & item_tab)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
|
2010-08-10 22:43:38 +02:00
|
|
|
while( i < item_tab.size() )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-08-10 22:43:38 +02:00
|
|
|
if( !HasReadAccess(item_tab[i]) )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-08-10 22:43:38 +02:00
|
|
|
item_tab.erase(item_tab.begin() + i);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-08-02 02:10:45 +02:00
|
|
|
void System::CheckWriteAccessToItems(std::vector<Item> & item_tab)
|
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
while( i < item_tab.size() )
|
|
|
|
{
|
|
|
|
if( !HasWriteAccess(item_tab[i]) )
|
|
|
|
{
|
|
|
|
item_tab.erase(item_tab.begin() + i);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2012-01-25 00:03:36 +01:00
|
|
|
int System::NewPrivileges(int creation_mask)
|
|
|
|
{
|
|
|
|
if( cur && cur->session && cur->session->puser )
|
|
|
|
{
|
2021-04-09 17:50:58 +02:00
|
|
|
int umask = cur->session->puser->env.to_int(L"umask", config->umask);
|
2012-01-25 00:03:36 +01:00
|
|
|
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;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( (dir.item_content.privileges & 010000) == 0 )
|
2012-01-25 00:03:36 +01:00
|
|
|
// there is no a sticky bit set to this directory
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if( cur->session->puser )
|
|
|
|
{
|
2021-06-27 23:31:50 +02:00
|
|
|
if( cur->session->puser->is_super_user )
|
2012-01-25 00:03:36 +01:00
|
|
|
return true;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( dir.item_content.user_id != -1 && cur->session->puser->id != -1 && child_item_user_id != -1 )
|
2012-01-25 00:03:36 +01:00
|
|
|
{
|
|
|
|
if( cur->session->puser->id == child_item_user_id ||
|
2021-02-24 01:19:47 +01:00
|
|
|
cur->session->puser->id == dir.item_content.user_id )
|
2012-01-25 00:03:36 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int System::NewFilePrivileges()
|
|
|
|
{
|
|
|
|
return NewPrivileges(06666);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int System::NewDirPrivileges()
|
|
|
|
{
|
|
|
|
return NewPrivileges(07777);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
bool System::CanUseHtml(long user_id)
|
|
|
|
{
|
2015-01-02 09:18:06 +01:00
|
|
|
return IsSuperUser(user_id) || IsMemberOfGroup(user_id, L"allow_html");
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::CanUseBBCode(long user_id)
|
|
|
|
{
|
|
|
|
// logged users can use bbcode
|
|
|
|
return (user_id != -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-07-13 15:13:56 +02:00
|
|
|
// !! IMPROVE ME change to a better name
|
|
|
|
bool System::CanUseOther(long user_id)
|
|
|
|
{
|
|
|
|
return IsSuperUser(user_id) || IsMemberOfGroup(user_id, L"allow_other");
|
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
2015-01-02 09:18:06 +01:00
|
|
|
bool System::IsSuperUser(long user_id)
|
|
|
|
{
|
|
|
|
User * puser = users.GetUser(user_id);
|
|
|
|
|
|
|
|
if( !puser )
|
|
|
|
return false;
|
|
|
|
|
2021-06-27 23:31:50 +02:00
|
|
|
return puser->is_super_user;
|
2015-01-02 09:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-21 01:19:17 +01:00
|
|
|
bool System::IsMemberOfGroup(long user_id, const wchar_t * group_name)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
User * puser = users.GetUser(user_id);
|
|
|
|
|
|
|
|
if( !puser )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
long group = groups.GetGroupId(group_name);
|
|
|
|
|
|
|
|
if( group == -1 )
|
|
|
|
// there is no such a group
|
|
|
|
return false;
|
|
|
|
|
2010-11-21 01:19:17 +01:00
|
|
|
return puser->IsMemberOf(group);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
// the path depends on parent_id
|
|
|
|
bool System::CreateNewFileSimpleFs(Item & item)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
bool res = dirs.MakePath(item.parent_id, item.item_content.file_path);
|
2010-12-10 22:07:01 +01:00
|
|
|
|
|
|
|
if( res )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
if( !item.item_content.file_path.empty() && item.item_content.file_path[0] == '/' )
|
|
|
|
item.item_content.file_path.erase(0, 1);
|
2010-12-10 22:07:01 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log1 << "System: CreateNewFileSimpleFs: can't create a path to item.id: " << item.id
|
|
|
|
<< ", item.parent_id: " << item.parent_id << logend;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
return res;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the path depends on id
|
2010-12-10 22:07:01 +01:00
|
|
|
bool System::CreateNewFileHashFs(Item & item)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-11-21 01:19:17 +01:00
|
|
|
wchar_t buffer[50];
|
|
|
|
wchar_t * hash = buffer;
|
|
|
|
size_t buffer_len = sizeof(buffer)/sizeof(wchar_t);
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
// get 'id' as hexadecimal
|
|
|
|
buffer[0] = '0';
|
2010-12-10 22:07:01 +01:00
|
|
|
swprintf(buffer+1, buffer_len, L"%lx", (unsigned long)item.id);
|
2010-11-21 01:19:17 +01:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path.clear();
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
// make sure that the length is even
|
2010-11-21 01:19:17 +01:00
|
|
|
if( (wcslen(hash) & 1) != 0 )
|
2010-08-10 18:12:50 +02:00
|
|
|
hash = buffer + 1; // the first character was zero
|
|
|
|
|
|
|
|
for(size_t i=0 ; hash[i] != 0 ; i+=2)
|
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path += hash[i];
|
|
|
|
item.item_content.file_path += hash[i+1];
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
if( hash[i+2] != 0 )
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path += '/';
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// one character more to make sure the path is unique
|
|
|
|
// (we can have a directory without the character)
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path += '_';
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
|
|
|
|
// creating item.file_path and item.file_fs
|
|
|
|
// you should set file_type yourself
|
|
|
|
// this method uses: item.id, item.url, item.parent_id (for selecting a mountpoint)
|
|
|
|
bool System::CreateNewFile(Item & item)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
bool res;
|
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
if( item.type != Item::file )
|
|
|
|
{
|
|
|
|
log << log1 << "System: CreateNewFile: the item should be a file" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
Mount * pmount = mounts.CalcMount(item.parent_id);
|
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
if( !pmount || pmount->fs != mounts.MountFsHashfs() )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
res = CreateNewFileSimpleFs(item);
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_fs = mounts.MountFsSimplefs();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
res = CreateNewFileHashFs(item);
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_fs = mounts.MountFsHashfs();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if( res )
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path += item.url;
|
2010-08-10 18:12:50 +02:00
|
|
|
else
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.file_path.clear();
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
// making a global file path (in the unix file system)
|
2010-12-10 22:07:01 +01:00
|
|
|
// you should call CreateNewFile before
|
2014-09-28 19:30:05 +02:00
|
|
|
bool System::MakeFilePath(const Item & item, std::wstring & path, bool thumb, bool create_dir, int chmod, int group)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
path.clear();
|
|
|
|
|
|
|
|
if( config->upload_dir.empty() )
|
|
|
|
{
|
|
|
|
log << log1 << "System: MakePath: upload_dir is not set in the config file" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.file_path.empty() || item.item_content.file_type == WINIX_ITEM_FILETYPE_NONE )
|
2010-12-10 22:07:01 +01:00
|
|
|
{
|
|
|
|
log << log1 << "System: MakePath: this item has not a static file" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = config->upload_dir;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( item.item_content.file_fs == mounts.MountFsHashfs() )
|
2010-12-10 22:07:01 +01:00
|
|
|
path += L"/hashfs";
|
|
|
|
else
|
|
|
|
path += L"/simplefs";
|
|
|
|
|
|
|
|
|
|
|
|
if( thumb )
|
|
|
|
path += L"/thumb";
|
|
|
|
else
|
|
|
|
path += L"/normal";
|
|
|
|
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( create_dir && !CreateDirs(path, item.item_content.file_path, chmod, group, true) )
|
2010-12-10 22:07:01 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
path += '/';
|
2021-02-24 01:19:47 +01:00
|
|
|
path += item.item_content.file_path;
|
2010-12-10 22:07:01 +01:00
|
|
|
|
|
|
|
return true;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-15 20:28:34 +02:00
|
|
|
bool System::MakeRelativeFilePath(const Item & item, const std::wstring & path_prefix, std::wstring & path, bool thumb)
|
|
|
|
{
|
|
|
|
path.clear();
|
|
|
|
|
|
|
|
if( item.item_content.file_path.empty() || item.item_content.file_type == WINIX_ITEM_FILETYPE_NONE )
|
|
|
|
{
|
|
|
|
log << log1 << "System: MakePath: this item has not a static file" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we allow the prefix to be empty
|
|
|
|
if( !path_prefix.empty() )
|
|
|
|
{
|
|
|
|
if( path_prefix[0] != '/' )
|
|
|
|
path += '/';
|
|
|
|
|
|
|
|
path += path_prefix;
|
|
|
|
TrimLast(path, '/');
|
|
|
|
}
|
|
|
|
|
|
|
|
if( item.item_content.file_fs == mounts.MountFsHashfs() )
|
|
|
|
path += L"/hashfs";
|
|
|
|
else
|
|
|
|
path += L"/simplefs";
|
|
|
|
|
|
|
|
if( thumb )
|
|
|
|
path += L"/thumb";
|
|
|
|
else
|
|
|
|
path += L"/normal";
|
|
|
|
|
|
|
|
path += '/';
|
|
|
|
path += item.item_content.file_path;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
bool System::AddFile(Item & item, int notify_code, bool call_plugins)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
if( item.type != Item::file )
|
2010-08-10 18:12:50 +02:00
|
|
|
return WINIX_ERR_FILE_EXPECTED;
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
|
|
|
|
//Error status = db->AddItem(item);
|
2021-05-26 19:55:50 +02:00
|
|
|
item.set_connector(model_connector);
|
2021-02-24 01:19:47 +01:00
|
|
|
bool status = item.insert();
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( status )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
log << log2 << "System: added a new file, url: " << item.url << ", id: " << item.id
|
|
|
|
<< ", parent_id: " << item.parent_id << logend;
|
|
|
|
|
2010-12-02 02:02:02 +01:00
|
|
|
if( notify_code )
|
|
|
|
notify.ItemChanged(notify_code, item);
|
2011-07-29 00:18:10 +02:00
|
|
|
|
2011-09-13 08:08:34 +02:00
|
|
|
if( call_plugins )
|
2018-11-21 12:03:53 +01:00
|
|
|
plugin->Call(WINIX_FILE_ADDED, &item);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-09 22:27:45 +02:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
bool System::EditFile(Item & item, bool with_url, int notify_code, bool call_plugins)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-05 22:24:11 +01:00
|
|
|
if( item.type != Item::file )
|
2010-08-10 18:12:50 +02:00
|
|
|
return WINIX_ERR_FILE_EXPECTED;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session && cur->session->puser )
|
2021-02-24 01:19:47 +01:00
|
|
|
cur->request->item.item_content.modification_user_id = cur->session->puser->id;
|
2010-08-10 18:12:50 +02:00
|
|
|
else
|
2021-02-24 01:19:47 +01:00
|
|
|
cur->request->item.item_content.modification_user_id = -1;
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
item.item_content.SetDateModifyToNow();
|
|
|
|
|
2021-03-08 21:06:50 +01:00
|
|
|
ItemModelData item_model_data;
|
|
|
|
item_model_data.prepare_unique_url = with_url;
|
|
|
|
|
|
|
|
bool status = item.update(item_model_data);
|
2021-02-24 01:19:47 +01:00
|
|
|
//Error status = db->EditItemById(item, with_url);
|
2010-08-10 18:12:50 +02:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( status )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-10-19 02:31:20 +02:00
|
|
|
TemplatesFunctions::pattern_cacher.UpdatePattern(item);
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
log << log2 << "System: modified an item" << logend;
|
2010-10-19 02:31:20 +02:00
|
|
|
|
2010-12-02 02:02:02 +01:00
|
|
|
if( notify_code )
|
|
|
|
notify.ItemChanged(notify_code, item);
|
2011-07-29 00:18:10 +02:00
|
|
|
|
2011-09-13 08:08:34 +02:00
|
|
|
if( call_plugins )
|
2018-11-21 12:03:53 +01:00
|
|
|
plugin->Call(WINIX_FILE_CHANGED, &item);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
2010-10-19 02:31:20 +02:00
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
return status;
|
|
|
|
}
|
2010-10-24 01:12:47 +02:00
|
|
|
|
|
|
|
|
2012-05-30 21:04:18 +02:00
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
time_t System::ToLocal(time_t utc_time)
|
2012-05-30 21:04:18 +02:00
|
|
|
{
|
2012-06-27 01:19:19 +02:00
|
|
|
size_t tz_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
|
|
|
|
if( cur->session && cur->session->puser )
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = cur->session->puser->time_zone_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
else
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = config->time_zone_default_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
TimeZone * tz = time_zones.GetZone(tz_id);
|
|
|
|
|
|
|
|
if( tz )
|
|
|
|
return tz->ToLocal(utc_time);
|
|
|
|
|
|
|
|
return utc_time;
|
2012-05-30 21:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
pt::Date System::ToLocal(const pt::Date & utc_date)
|
2010-10-24 01:12:47 +02:00
|
|
|
{
|
2012-06-27 01:19:19 +02:00
|
|
|
size_t tz_id;
|
2010-10-24 01:12:47 +02:00
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session && cur->session->puser )
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = cur->session->puser->time_zone_id;
|
2010-10-24 01:12:47 +02:00
|
|
|
else
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = config->time_zone_default_id;
|
2010-10-24 01:12:47 +02:00
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
TimeZone * tz = time_zones.GetZone(tz_id);
|
|
|
|
|
|
|
|
if( tz )
|
|
|
|
return tz->ToLocal(utc_date);
|
|
|
|
|
|
|
|
return utc_date;
|
2010-10-24 01:12:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-30 21:04:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
time_t System::ToUTC(time_t local_time)
|
2010-10-24 01:12:47 +02:00
|
|
|
{
|
2012-06-27 01:19:19 +02:00
|
|
|
size_t tz_id;
|
2010-10-24 01:12:47 +02:00
|
|
|
|
2012-05-30 21:04:18 +02:00
|
|
|
if( cur->session && cur->session->puser )
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = cur->session->puser->time_zone_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
else
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = config->time_zone_default_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
TimeZone * tz = time_zones.GetZone(tz_id);
|
|
|
|
|
|
|
|
if( tz )
|
|
|
|
return tz->ToUTC(local_time);
|
|
|
|
|
|
|
|
return local_time;
|
2012-05-30 21:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
pt::Date System::ToUTC(const pt::Date & local_date)
|
2012-05-30 21:04:18 +02:00
|
|
|
{
|
2012-06-27 01:19:19 +02:00
|
|
|
size_t tz_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
|
|
|
|
if( cur->session && cur->session->puser )
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = cur->session->puser->time_zone_id;
|
2012-05-30 21:04:18 +02:00
|
|
|
else
|
2012-06-27 01:19:19 +02:00
|
|
|
tz_id = config->time_zone_default_id;
|
2010-10-24 01:12:47 +02:00
|
|
|
|
2012-06-27 01:19:19 +02:00
|
|
|
TimeZone * tz = time_zones.GetZone(tz_id);
|
|
|
|
|
|
|
|
if( tz )
|
|
|
|
return tz->ToUTC(local_date);
|
|
|
|
|
|
|
|
return local_date;
|
2010-10-24 01:12:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
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 )
|
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
morm::Finder<Item> finder(model_connector);
|
|
|
|
|
|
|
|
bool status = finder.
|
|
|
|
select().
|
|
|
|
where().
|
|
|
|
eq(L"parent_id", out_dir_tab.back()->id).
|
|
|
|
eq(L"url", name_temp).
|
|
|
|
get(out_item);
|
|
|
|
|
|
|
|
//if( db->GetItem(out_dir_tab.back()->id, name_temp, out_item) == WINIX_ERR_OK )
|
|
|
|
if( status )
|
2011-01-05 22:24:11 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( !out_dir_tab.back()->item_content.link_to.empty() )
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
|
|
|
if( follow_dir_default )
|
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
if( !(stop_on_link_redirect && out_dir_tab.back()->item_content.link_redirect==1) )
|
|
|
|
link_to_temp = out_dir_tab.back()->item_content.link_to;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-07-14 01:14:10 +02:00
|
|
|
if( check_access && !HasReadAccess(out_item) )
|
|
|
|
{
|
|
|
|
log << log1 << "System: no read access to the file or symlink" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
if( out_item.type == Item::symlink )
|
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
if( out_item.item_content.link_to.empty() )
|
2011-01-05 22:24:11 +01:00
|
|
|
{
|
|
|
|
log << log1 << "System: symlink empty" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-02-24 01:19:47 +01:00
|
|
|
if( !(stop_on_link_redirect && out_item.item_content.link_redirect==1) )
|
|
|
|
link_to_temp = out_item.item_content.link_to;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2013-12-03 13:33:41 +01:00
|
|
|
// !! CHECK ME
|
|
|
|
// FollowLink is using link_to_temp temporary variable too
|
2011-01-05 22:24:11 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
// the same as FollowAllLinks but operates on cur->request->dir_tab and cur->request->item
|
2011-01-05 22:24:11 +01:00
|
|
|
// 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)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
int res = FollowAllLinks(cur->request->dir_tab, link_to, temp_follow_dir_tab, temp_follow_item,
|
2011-01-05 22:24:11 +01:00
|
|
|
follow_dir_default, stop_on_link_redirect, check_access);
|
|
|
|
|
|
|
|
bool ok = (res == 0 || res == 1);
|
|
|
|
|
|
|
|
if( ok )
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->dir_tab = temp_follow_dir_tab;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
if( res == 0 )
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->is_item = false;
|
|
|
|
cur->request->item.Clear();
|
|
|
|
cur->request->last_item = cur->request->dir_tab.back();
|
2011-01-05 22:24:11 +01:00
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
if( !cur->request->dir_tab.back()->item_content.link_to.empty() )
|
|
|
|
RedirectTo(cur->request->dir_tab.back()->item_content.link_to);
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
log << log3 << "System: current directory changed" << logend;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->is_item = true;
|
|
|
|
cur->request->item = temp_follow_item;
|
|
|
|
cur->request->last_item = &cur->request->item;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->request->item.type == Item::symlink )
|
2021-02-24 01:19:47 +01:00
|
|
|
RedirectTo(cur->request->item.item_content.link_to); // cur->request->item.item_content.link_to is not empty
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
log << log3 << "System: current directory changed and the new file loaded" << logend;
|
|
|
|
}
|
|
|
|
|
|
|
|
mounts.CalcCurMount();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( res == 5 || res == 6 )
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
2011-01-05 22:24:11 +01:00
|
|
|
else
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->status = WINIX_ERR_NO_ITEM;
|
2011-01-05 22:24:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-24 22:53:21 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
adding a new file to winix
|
|
|
|
file_path - a name of a static file (from common directory)
|
|
|
|
url - url of a file which will be inserted (in /var directory)
|
|
|
|
|
|
|
|
current limitation:
|
|
|
|
warning: the url is not prepared by PrepareUrl() (PrepareUrl is from functions)
|
|
|
|
*/
|
2021-10-13 01:27:14 +02:00
|
|
|
bool System::AddCommonFileToVar(const wchar_t * file_path, const wchar_t * url, const wchar_t * mime_type, bool overwrite_existing)
|
2011-06-24 22:53:21 +02:00
|
|
|
{
|
|
|
|
if( config->common_dir.empty() )
|
|
|
|
{
|
|
|
|
log << log1 << "System: can't open a file from common directory, common_dir not set in the config" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
file_name = config->common_dir;
|
|
|
|
file_name += '/';
|
|
|
|
file_name += file_path;
|
|
|
|
|
|
|
|
if( !GetUTF8File(file_name, file_content) )
|
|
|
|
{
|
|
|
|
log << log1 << "System: can't open a file: " << file_name << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Item * var = dirs.CreateVarDir();
|
|
|
|
|
|
|
|
if( !var )
|
|
|
|
{
|
|
|
|
log << log1 << "System: can't create /var directory" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-24 01:19:47 +01:00
|
|
|
morm::Finder<Item> finder(model_connector);
|
|
|
|
|
2021-10-13 01:27:14 +02:00
|
|
|
file_content_item = finder.select().where().eq(L"parent_id", var->id).eq(L"url", url).get();
|
2021-02-24 01:19:47 +01:00
|
|
|
|
2021-10-13 01:27:14 +02:00
|
|
|
if( file_content_item.found() )
|
2011-06-24 22:53:21 +02:00
|
|
|
{
|
2021-10-13 01:27:14 +02:00
|
|
|
if( !overwrite_existing )
|
2011-06-24 22:53:21 +02:00
|
|
|
return true;
|
2021-10-13 01:27:14 +02:00
|
|
|
|
|
|
|
file_content_item.remove();
|
2011-06-24 22:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
file_content_item.Clear();
|
2016-04-04 18:02:36 +02:00
|
|
|
file_content_item.parent_id = var->id;
|
2021-02-24 01:19:47 +01:00
|
|
|
file_content_item.item_content.user_id = var->item_content.user_id;
|
|
|
|
file_content_item.item_content.group_id = var->item_content.group_id;
|
|
|
|
file_content_item.item_content.privileges = 07555; // !! IMPROVE ME: may it should be added as a parameter to this function?
|
2016-04-04 18:02:36 +02:00
|
|
|
file_content_item.subject = url;
|
|
|
|
file_content_item.url = url;
|
|
|
|
file_content_item.type = Item::file;
|
|
|
|
file_content_item.html_template = config->templates_index_raw;
|
2021-02-24 01:19:47 +01:00
|
|
|
file_content_item.item_content.content_raw = file_content;
|
|
|
|
file_content_item.item_content.content_raw_type = ItemContent::ct_other;
|
2011-06-24 22:53:21 +02:00
|
|
|
|
2021-10-13 01:27:14 +02:00
|
|
|
if( mime_type )
|
|
|
|
file_content_item.item_content.file_mime_type = mime_type;
|
|
|
|
|
2021-05-21 17:41:16 +02:00
|
|
|
return AddFile(file_content_item, false);
|
2011-06-24 22:53:21 +02:00
|
|
|
}
|
|
|
|
|
2014-02-12 17:30:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
} // namespace Winix
|
|
|
|
|