2010-08-10 18:12:50 +02:00
|
|
|
/*
|
|
|
|
* This file is a part of Winix
|
|
|
|
* and is not publicly distributed
|
|
|
|
*
|
2011-06-15 01:45:42 +02:00
|
|
|
* Copyright (c) 2010-2011, Tomasz Sowa
|
2010-08-10 18:12:50 +02:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "system.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "error.h"
|
2010-10-19 02:31:20 +02:00
|
|
|
#include "templates/templates.h"
|
2011-01-05 22:24:11 +01:00
|
|
|
#include "functions/functionbase.h"
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void System::SetConfig(Config * pconfig)
|
|
|
|
{
|
|
|
|
config = pconfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void System::SetDb(Db * pdb)
|
|
|
|
{
|
|
|
|
db = pdb;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-02 02:02:02 +01:00
|
|
|
void System::SetSynchro(Synchro * psynchro)
|
|
|
|
{
|
|
|
|
synchro = psynchro;
|
|
|
|
}
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void System::Init()
|
|
|
|
{
|
|
|
|
dirs.SetDb(db);
|
2011-01-23 15:15:30 +01:00
|
|
|
dirs.SetCur(cur);
|
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);
|
2011-01-23 15:15:30 +01:00
|
|
|
mounts.SetCur(cur);
|
2010-09-13 01:33:27 +02:00
|
|
|
mounts.CreateMounts();
|
2010-08-10 18:12:50 +02:00
|
|
|
mounts.ReadMounts();
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
users.SetCur(cur);
|
2010-08-10 18:12:50 +02:00
|
|
|
users.ReadUsers(db);
|
2010-10-24 01:12:47 +02:00
|
|
|
users.SetTimeZoneOffset(config->time_zone_offset);
|
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
|
|
|
|
|
|
|
notify.SetSynchro(synchro);
|
2011-01-23 15:15:30 +01:00
|
|
|
notify.SetCur(cur);
|
2010-12-02 02:02:02 +01:00
|
|
|
notify.SetConfig(config);
|
|
|
|
notify.SetUsers(&users);
|
|
|
|
notify.SetDirs(&dirs);
|
|
|
|
notify.Init();
|
2010-12-11 23:55:48 +01:00
|
|
|
|
|
|
|
thumb.SetSynchro(synchro);
|
|
|
|
thumb.SetDb(db);
|
2011-01-05 22:24:11 +01:00
|
|
|
thumb.SetConfig(config);
|
|
|
|
thumb.SetSystem(this);
|
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
|
|
|
|
|
|
|
crypt.SetConfig(config);
|
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?
|
2010-11-21 01:19:17 +01:00
|
|
|
void System::RedirectTo(const Item & item, const wchar_t * postfix)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01: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;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-21 01:19:17 +01:00
|
|
|
void System::RedirectTo(long item_id, const wchar_t * postfix)
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2011-01-23 15:15:30 +01: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
|
|
|
|
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 )
|
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;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-05 22:24:11 +01:00
|
|
|
void System::RedirectTo(const std::wstring & url)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->redirect_to = config->base_url;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
|
|
|
if( !url.empty() && url[0] == '/' )
|
|
|
|
{
|
|
|
|
// 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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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 += '/';
|
|
|
|
cur->request->redirect_to += cur->request->function->fun.url;
|
2011-01-05 22:24:11 +01:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
void System::RedirectToLastDir()
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->request->dir_tab.empty() )
|
|
|
|
RedirectTo( *cur->request->dir_tab.back() );
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void System::RedirectToLastItem()
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->request->last_item )
|
|
|
|
RedirectTo( *cur->request->last_item );
|
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;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
2010-11-22 02:12:46 +01:00
|
|
|
// !! przeciez to prosciej mozna zapisac
|
|
|
|
// albo dac od razu return false
|
2010-08-10 18:12:50 +02:00
|
|
|
if( item.user_id != new_user_id )
|
|
|
|
// only super user can change the owner of an item
|
|
|
|
return false;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if( item.group_id != new_group_id )
|
|
|
|
{
|
|
|
|
// user is allowed to change the group only if he is an owner of the item
|
|
|
|
// he can change only into a group in which he is a member of, or into a 'no_group'
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session->puser )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser->id != item.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;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if( item.privileges != new_priv )
|
|
|
|
{
|
|
|
|
// the owner of an item is allowed to change the privileges
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->session->puser )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser->id != item.user_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasAccess(const Item & item, int mask)
|
|
|
|
{
|
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;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
// super user is allowed everything
|
|
|
|
return true;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->id == item.user_id )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
// the owner
|
|
|
|
return ((item.privileges >> 6) & mask) == mask;
|
|
|
|
}
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session->puser && cur->session->puser->IsMemberOf(item.group_id) )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
// group
|
|
|
|
return ((item.privileges >> 3) & mask) == mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
// others
|
|
|
|
|
|
|
|
return (item.privileges & mask) == mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasReadAccess(const Item & item)
|
|
|
|
{
|
|
|
|
return HasAccess(item, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasWriteAccess(const Item & item)
|
|
|
|
{
|
|
|
|
return HasAccess(item, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasReadWriteAccess(const Item & item)
|
|
|
|
{
|
|
|
|
return HasAccess(item, 6); // r+w
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::HasReadExecAccess(const Item & item)
|
|
|
|
{
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session && cur->session->puser && cur->session->puser->super_user )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
|
|
|
// there must be at least one 'x' (for the root)
|
|
|
|
|
|
|
|
return (item.privileges & 0111) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return HasAccess(item, 5); // r+x
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool System::CanUseHtml(long user_id)
|
|
|
|
{
|
2010-11-21 01:19:17 +01:00
|
|
|
return 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool System::CanUseRaw(long user_id)
|
|
|
|
{
|
2010-11-21 01:19:17 +01:00
|
|
|
return IsMemberOfGroup(user_id, L"allow_raw");
|
2010-08-10 18:12:50 +02: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;
|
|
|
|
|
|
|
|
if( puser->super_user )
|
2010-11-21 01:19:17 +01:00
|
|
|
return true; // !! ?? zakladamy ze administrator jest czlonkiem wszystkich grup? dlaczego?
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
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
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
bool res = dirs.MakePath(item.parent_id, item.file_path);
|
|
|
|
|
|
|
|
if( res )
|
2010-08-10 18:12:50 +02:00
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
if( !item.file_path.empty() && item.file_path[0] == '/' )
|
|
|
|
item.file_path.erase(0, 1);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2010-12-10 22:07:01 +01:00
|
|
|
item.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)
|
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
item.file_path += hash[i];
|
|
|
|
item.file_path += hash[i+1];
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
if( hash[i+2] != 0 )
|
2010-12-10 22:07:01 +01:00
|
|
|
item.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)
|
2010-12-10 22:07:01 +01:00
|
|
|
item.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);
|
|
|
|
item.file_fs = mounts.MountFsSimplefs();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-12-10 22:07:01 +01:00
|
|
|
res = CreateNewFileHashFs(item);
|
|
|
|
item.file_fs = mounts.MountFsHashfs();
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if( res )
|
2010-12-10 22:07:01 +01:00
|
|
|
item.file_path += item.url;
|
2010-08-10 18:12:50 +02:00
|
|
|
else
|
2010-12-10 22:07:01 +01:00
|
|
|
item.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
|
|
|
|
bool System::MakeFilePath(const Item & item, std::wstring & path, bool thumb, bool create_dir, int chmod)
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( item.file_path.empty() || item.file_type == WINIX_ITEM_FILETYPE_NONE )
|
|
|
|
{
|
|
|
|
log << log1 << "System: MakePath: this item has not a static file" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = config->upload_dir;
|
|
|
|
|
|
|
|
if( item.file_fs == mounts.MountFsHashfs() )
|
|
|
|
path += L"/hashfs";
|
|
|
|
else
|
|
|
|
path += L"/simplefs";
|
|
|
|
|
|
|
|
|
|
|
|
if( thumb )
|
|
|
|
path += L"/thumb";
|
|
|
|
else
|
|
|
|
path += L"/normal";
|
|
|
|
|
|
|
|
|
|
|
|
if( create_dir && !CreateDirs(path, item.file_path, chmod, true) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
path += '/';
|
|
|
|
path += item.file_path;
|
|
|
|
|
|
|
|
return true;
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
2010-12-02 02:02:02 +01:00
|
|
|
Error System::AddFile(Item & item, int notify_code)
|
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;
|
|
|
|
|
|
|
|
Error status = db->AddItem(item);
|
|
|
|
|
|
|
|
if( status == WINIX_ERR_OK )
|
|
|
|
{
|
|
|
|
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);
|
2010-08-10 18:12:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-09 22:27:45 +02:00
|
|
|
|
2010-12-02 02:02:02 +01:00
|
|
|
Error System::EditFile(Item & item, bool with_url, int notify_code)
|
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 )
|
|
|
|
cur->request->item.modification_user_id = cur->session->puser->id;
|
2010-08-10 18:12:50 +02:00
|
|
|
else
|
2011-01-23 15:15:30 +01:00
|
|
|
cur->request->item.modification_user_id = -1;
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
item.SetDateModifyToNow();
|
|
|
|
Error status = db->EditItemById(item, with_url);
|
|
|
|
|
|
|
|
if( status == WINIX_ERR_OK )
|
|
|
|
{
|
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);
|
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
|
|
|
|
|
|
|
|
|
|
|
time_t System::LocalTime(time_t gmt_time)
|
|
|
|
{
|
|
|
|
int time_offset;
|
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( cur->session && cur->session->puser )
|
|
|
|
time_offset = cur->session->puser->time_zone_offset;
|
2010-10-24 01:12:47 +02:00
|
|
|
else
|
|
|
|
time_offset = config->time_zone_offset_guest;
|
|
|
|
|
|
|
|
return gmt_time + (time_t)time_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tm System::LocalTime(const tm * ptm)
|
|
|
|
{
|
|
|
|
time_t t;
|
|
|
|
tm rtm;
|
|
|
|
|
|
|
|
t = Time(ptm);
|
|
|
|
t = LocalTime(t);
|
|
|
|
rtm = Time(t);
|
|
|
|
|
|
|
|
return rtm;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tm System::LocalTime(const tm & ptm)
|
|
|
|
{
|
|
|
|
return LocalTime(&ptm);
|
|
|
|
}
|
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 )
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2011-01-23 15:15:30 +01:00
|
|
|
if( !cur->request->dir_tab.back()->link_to.empty() )
|
|
|
|
RedirectTo(cur->request->dir_tab.back()->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 )
|
|
|
|
RedirectTo(cur->request->item.link_to); // cur->request->item.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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|