added: to the Item: auth_path - a path to a static file (if auth is different from auth_none)

added: function 'mv' (move)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@596 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2010-03-15 01:47:26 +00:00
parent ebd868fa33
commit 6fbcffe63b
33 changed files with 1122 additions and 319 deletions

View File

@@ -83,15 +83,15 @@ requestcontroller.o: ../templates/templates.h ../templates/patterncacher.h
requestcontroller.o: misc.h item.h ../templates/ckeditorgetparser.h
requestcontroller.o: ../core/httpsimpleparser.h ../core/log.h
requestcontroller.o: ../core/locale.h ../confparser/confparser.h
requestcontroller.o: ../core/thread.h ../core/ticket.h sessionmanager.h
requestcontroller.o: sessioncontainer.h session.h error.h log.h user.h
requestcontroller.o: rebus.h functionparser.h requesttypes.h data.h dirs.h
requestcontroller.o: dircontainer.h users.h ugcontainer.h groups.h group.h
requestcontroller.o: ../core/thread.h ../core/ticket.h ../core/db.h user.h
requestcontroller.o: group.h thread.h error.h log.h dircontainer.h
requestcontroller.o: ugcontainer.h ticket.h sessionmanager.h
requestcontroller.o: sessioncontainer.h session.h rebus.h functionparser.h
requestcontroller.o: requesttypes.h data.h dirs.h users.h groups.h
requestcontroller.o: functions.h function.h lastcontainer.h mounts.h mount.h
requestcontroller.o: loadavg.h request.h thread.h compress.h
requestcontroller.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
requestcontroller.o: postmultiparser.h ticket.h postparser.h
requestcontroller.o: httpsimpleparser.h cookieparser.h notify.h
requestcontroller.o: loadavg.h request.h compress.h acceptencodingparser.h
requestcontroller.o: acceptbaseparser.h htmlfilter.h postmultiparser.h
requestcontroller.o: postparser.h httpsimpleparser.h cookieparser.h notify.h
requestcontroller.o: ../templatesnotify/templatesnotify.h ../core/mount.h
requestcontroller.o: ../templates/misc.h ../templates/localefilter.h
session.o: session.h item.h error.h log.h user.h rebus.h

View File

@@ -301,7 +301,8 @@ return status;
//!! wywalic z nazwy 'Subject' nic nie jest robione z tytulem
// ta metoda uzywana tez jest w EditParentUrlById()
bool Db::AddItemCreateUrlSubject(Item & item)
{
bool is_that_url;
@@ -455,7 +456,7 @@ Error Db::AddItemIntoItem(Item & item)
AssertConnection();
std::ostringstream query;
query << "insert into core.item (user_id, group_id, privileges, date_creation, date_modification, type, "
"parent_id, content_id, auth, default_item, subject, guest_name, url) values (";
"parent_id, content_id, auth, auth_path, default_item, subject, guest_name, url) values (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
@@ -464,7 +465,8 @@ Error Db::AddItemIntoItem(Item & item)
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "', ";
query << '\'' << item.content_id << "', ";
query << '\'' << static_cast<int>(item.auth) << "', ";
query << '\'' << static_cast<int>(item.auth) << "', ";
query << '\'' << Escape(item.auth_path) << "', ";
query << '\'' << item.default_item << "', ";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.guest_name) << "', ";
@@ -561,7 +563,7 @@ Error Db::EditItemInItem(Item & item, bool with_url)
AssertConnection();
std::ostringstream query;
query << "update core.item set (user_id, group_id, privileges, date_creation, date_modification, type, "
"default_item, parent_id, subject, guest_name, auth";
"default_item, parent_id, subject, guest_name, auth, auth_path";
if( with_url )
query << ", url";
@@ -577,7 +579,8 @@ Error Db::EditItemInItem(Item & item, bool with_url)
query << '\'' << item.parent_id << "', ";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.guest_name) << "', ";
query << '\'' << static_cast<int>(item.auth) << "' ";
query << '\'' << static_cast<int>(item.auth) << "', ";
query << '\'' << Escape(item.auth_path) << "' ";
if( with_url )
{
@@ -802,7 +805,7 @@ PGresult * Db::GetItemsQuery(const ItemQuery & iq)
if( iq.sel_url ) query << " ,url";
if( iq.sel_type ) query << " ,type";
if( iq.sel_default_item ) query << " ,default_item";
if( iq.sel_auth ) query << " ,auth";
if( iq.sel_auth ) query << " ,auth, auth_path";
query << " from core.item";
@@ -818,7 +821,19 @@ PGresult * Db::GetItemsQuery(const ItemQuery & iq)
if( iq.where_id ) { query << if_and << "id='" << iq.id << "'" ; if_and = add_and; }
if( iq.where_parent_id ) { query << if_and << "parent_id='" << iq.parent_id << "'" ; if_and = add_and; }
if( iq.where_type ) { query << if_and << "type='" << static_cast<int>(iq.type) << "'" ; if_and = add_and; }
if( iq.where_auth ) { query << if_and << "auth='" << static_cast<int>(iq.auth) << "'" ; if_and = add_and; }
if( iq.where_auth )
{
query << if_and << "auth";
if(iq.auth_equal )
query << "=";
else
query << "!=";
query << "'" << static_cast<int>(iq.auth) << "'";
if_and = add_and;
}
}
@@ -1138,6 +1153,71 @@ return result;
Error Db::EditParentUrlById(Item & item, long id)
{
PGresult * r = 0;
Error result = WINIX_ERR_OK;
bool url_without_id = false;
try
{
AssertConnection();
std::ostringstream query;
query << "update core.item set (parent_id, url) = (";
query << '\'' << item.parent_id << "', ";
url_without_id = AddItemCreateUrlSubject(item);
if( url_without_id )
query << '\'' << Escape(item.url) << "'";
else
query << '\'' << item.id << "'"; ;
query << ") where id='" << id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
result = e;
}
ClearResult(r);
return result;
}
Error Db::EditAuthById(Item & item, long id)
{
PGresult * r = 0;
Error result = WINIX_ERR_OK;
try
{
AssertConnection();
std::ostringstream query;
query << "update core.item set (auth, auth_path) = (";
query << '\'' << static_cast<int>(item.auth) << "', ";
query << '\'' << Escape(item.auth_path) << "') ";
query << " where id='" << id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
result = e;
}
ClearResult(r);
return result;
}
Error Db::DelDirById(long id)
{
Error result = WINIX_ERR_OK;

View File

@@ -66,7 +66,7 @@ public:
bool sel_url; // url
bool sel_type; // type (dir, file, none)
bool sel_default_item; // default_item
bool sel_auth; // auth
bool sel_auth; // auth, auth_path
bool where_id; //
bool where_parent_id; //
@@ -77,6 +77,7 @@ public:
long parent_id; // if where_parent_id is true
Item::Type type;
Item::Auth auth;
bool auth_equal; // if true means auth should be equal
bool sort_asc;
@@ -102,14 +103,17 @@ public:
where_auth = where_;
}
void WhereId(long id_) { where_id = true; id = id_; }
void WhereParentId(long parent_id_) { where_parent_id = true; parent_id = parent_id_; }
void WhereType(Item::Type type_) { where_type = true; type = type_; }
void WhereAuth(Item::Auth st) { where_auth = true; auth = st; }
void WhereId(long id_) { where_id = true; id = id_; }
void WhereParentId(long parent_id_) { where_parent_id = true; parent_id = parent_id_; }
void WhereType(Item::Type type_) { where_type = true; type = type_; }
void WhereAuth(Item::Auth st,
bool equal = true) { where_auth = true; auth = st; auth_equal = equal; }
ItemQuery()
{
sort_asc = true;
sort_asc = true;
auth_equal = true;
SetAll(true, false);
id = -1;
@@ -131,7 +135,8 @@ public:
bool GetPriv(Item & item, long id);
Error EditPrivById(Item & item, long id);
Error EditParentUrlById(Item & item, long id);
Error EditAuthById(Item & item, long id);
Error DelDirById(long id);
bool DelItem(const Item & item);
@@ -215,7 +220,7 @@ protected:
struct ItemColumns
{
int id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id,
content_id, default_item, subject, content, content_type, guest_name, auth;
content_id, default_item, subject, content, content_type, guest_name, auth, auth_path;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);

View File

@@ -29,7 +29,8 @@ void Db::ItemColumns::SetColumns(PGresult * r)
content = PQfnumber(r, "content");
content_type = PQfnumber(r, "content_type");
guest_name = PQfnumber(r, "guest_name");
auth = PQfnumber(r, "auth");
auth = PQfnumber(r, "auth");
auth_path = PQfnumber(r, "auth_path");
}
@@ -52,6 +53,7 @@ void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
if( content_type != -1 ) item.content_type = static_cast<Item::ContentType>( atoi(Db::AssertValue(r, row, content_type)) );
if( guest_name != -1 ) item.guest_name = Db::AssertValue(r, row, guest_name);
if( auth != -1 ) item.auth = static_cast<Item::Auth>( atoi(Db::AssertValue(r, row, auth)) );
if( auth_path != -1 ) item.auth_path = Db::AssertValue(r, row, auth_path);
}

View File

@@ -131,6 +131,45 @@ return last_iter;
bool DirContainer::ChangeParent(long dir_id, long new_parent_id)
{
Iterator i = FindId(dir_id);
if( i == table.end() )
return false;
if( i->parent_id == new_parent_id )
return true; // nothing to do
ParentIterator p = FindFirstParent(i->parent_id);
bool found = false;
for( ; p != table_parent.end() ; p = NextParent(p) )
{
if( p->second->id == dir_id )
{
table_parent.erase(p);
log << log3 << "DirCont: removed parent index to dir: " << i->id << logend;
i->parent_id = new_parent_id;
table_parent.insert( std::make_pair(new_parent_id, i) );
log << log3 << "DirCont: added parent index to dir, id: " << i->id << ", parent_id: " << i->parent_id << logend;
found = true;
if( i->url == "etc" ) // !! in the future can be more special folders
FindSpecialFolders();
break; // that iterator (p) is only one
}
}
if( !found )
log << log1 << "DirCont: cannot find parent_id: " << i->parent_id << " in parent indexes" << logend;
return found;
}
void DirContainer::Clear()

View File

@@ -40,6 +40,7 @@ public:
SizeType Size();
bool Empty();
Iterator PushBack(const Item & item);
bool ChangeParent(long dir_id, long new_parent_id);
void Clear();
Iterator FindId(long id);

View File

@@ -138,6 +138,7 @@ DirContainer::ParentIterator Dirs::ParentEnd()
// dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
// 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::string & path)
{
DirContainer::Iterator i;
@@ -148,7 +149,8 @@ DirContainer::Iterator i;
{
i = dir_table.FindId(id);
if( i == dir_table.End() )
if( i == dir_table.End() ||
i->parent_id == id ) // means a loop (something wrong in the db)
return false;
if( i->parent_id == -1 )
@@ -164,6 +166,34 @@ DirContainer::Iterator i;
bool Dirs::ChangeParent(long dir_id, long new_parent_id)
{
return dir_table.ChangeParent(dir_id, new_parent_id);
}
/*
checking whether dir_id has a parent parent_id (somewhere in the path)
*/
bool Dirs::HasParent(long dir_id, long parent_id)
{
DirContainer::Iterator i;
while( true )
{
i = dir_table.FindId(dir_id);
if( i==dir_table.End() || i->parent_id==-1 )
return false;
if( i->parent_id == parent_id )
return true;
dir_id = i->parent_id;
}
}
@@ -249,6 +279,85 @@ Item * Dirs::AddDir(const Item & item)
size_t Dirs::AnalyzeDir(Item * pdir, const std::string & path, long & dir_id, std::string & dir)
{
size_t i = 0;
size_t old_i;
while( true )
{
dir_id = pdir->id;
// skipping slashes
for( ; i<path.size() && path[i] == '/' ; ++i );
if( i == path.size() )
return i; // end of the path
// creating a name
old_i = i;
analyze_temp.clear();
for( ; i<path.size() && path[i] != '/' ; ++i)
analyze_temp += path[i];
pdir = data.dirs.GetDir(analyze_temp, pdir->id);
if( !pdir )
return old_i; // analyze_temp is not a directory
dir += analyze_temp;
dir += '/';
}
}
/*
the path should begin with a slash
return values:
0 - directory exists
dir_id - id of the directory
dir - the path to the directory (with a slash at the end)
file - if not empty means a file name (we don't check if the file really exists)
1 - there is not a root dir
2 - the path is empty
3 - there is not such a directory
*/
int Dirs::AnalyzePath(const std::string & path, long & dir_id, std::string & dir, std::string & file)
{
Item * pdir = data.dirs.GetRootDir();
dir = '/';
file.clear();
if( !pdir )
return 1;
if( path.empty() )
return 2;
if( path[0] != '/' )
return 3;
size_t i = AnalyzeDir(pdir, path, dir_id, dir);
if( i < path.size() )
{
// checking if at least one slash has left
for(size_t a=i ; a < path.size() ; ++a)
if( path[a] == '/' )
return 3; // there is not such a directory
// the rest of the path is a file name
file = path.c_str() + i;
}
return 0;
}
void Dirs::SplitPath(const std::string & path, std::string & dir, std::string & file)
{

View File

@@ -34,13 +34,17 @@ public:
bool IsDir(long dir_id);
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_table);
bool MakePath(long dir_id, std::string & path);
bool ChangeParent(long dir_id, long new_parent_id);
bool HasParent(long dir_id, long parent_id);
int AnalyzePath(const std::string & path, long & dir_id, std::string & dir, std::string & file);
static void SplitPath(const std::string & path, std::string & dir, std::string & file);
DirContainer::ParentIterator FindFirstParent(long parent_id);
DirContainer::ParentIterator NextParent(DirContainer::ParentIterator i);
DirContainer::ParentIterator ParentEnd();
// these methods return null if there is no such a dir
Item * GetRootDir();
Item * GetEtcDir();
@@ -57,6 +61,9 @@ private:
DirContainer dir_table;
size_t AnalyzeDir(Item * pdir, const std::string & path, long & dir_id, std::string & dir);
std::string analyze_temp;
bool ExtractName(const char * & s, std::string & name);

View File

@@ -52,6 +52,7 @@
#define WINIX_ERR_PASSWORD_TOO_SHORT 26
#define WINIX_ERR_USER_EXISTS 27
#define WINIX_ERR_LOGIN_EMPTY 28
#define WINIX_DIFFERENT_MOUNT_POINTS 29

View File

@@ -36,7 +36,7 @@
#define FUN_EDITTICKET 19
#define FUN_TICKET 20
#define FUN_UPTIME 21
//#define FUN_MV 23
#define FUN_MV 23
//#define FUN_UNAME 24
#define FUN_CHMOD 25
#define FUN_CHOWN 26

View File

@@ -116,11 +116,11 @@ void Functions::ReadFunctions()
f.item.url = "uptime";
table.insert( std::make_pair(f.item.url, f) );
/*
f.code = FUN_MV;
f.item.url = "mv";
table.insert( std::make_pair(f.item.url, f) );
/*
f.code = FUN_UNAME;
f.item.url = "uname";
table.insert( std::make_pair(f.item.url, f) );

View File

@@ -76,7 +76,7 @@ enum Auth
Auth auth;
std::string auth_path; // path to a file (if auth!=auth_none)
// methods
@@ -125,6 +125,7 @@ void Clear()
content_id = -1;
auth = auth_none;
auth_path.clear();
SetDateToNow();
}

View File

@@ -608,6 +608,54 @@ bool CreateDir(const std::string & dir, int priv)
// creating directories (can be more than one)
// 'dirs' can begin with a slash (will be skipped)
bool CreateDirs(const char * base_dir, const char * dirs, int priv)
{
static std::string temp;
const char * p = dirs;
temp = base_dir; // we start creating from 'base_dir'
if( temp.empty() )
return false;
if( temp[temp.size()-1] != '/' )
temp += '/';
while( true )
{
// skipping slashes
for( ; *p=='/' ; ++p );
if( *p == 0 )
break;
// taking the name
for( ; *p && *p!='/' ; ++p )
temp += *p;
if( !CreateDir(temp.c_str(), priv) )
return false;
temp += '/';
}
return true;
}
bool CreateDirs(const std::string & base_dir, const std::string & dirs, int priv)
{
return CreateDirs(base_dir.c_str(), dirs.c_str(), priv);
}
// if there is not an extension it returns a pointer to the last '\0' character
const char * GetFileExt(const char * name)
{
@@ -642,7 +690,12 @@ Item::Auth SelectFileType(const char * file_name)
// as an image we're using only those types which can be rendered
// by a web browser
if( EqualNoCase(ext, "jpg") ||
EqualNoCase(ext, "jpeg") ||
EqualNoCase(ext, "jpe") ||
EqualNoCase(ext, "pic") ||
EqualNoCase(ext, "tga") ||
EqualNoCase(ext, "gif") ||
EqualNoCase(ext, "bmp") ||
EqualNoCase(ext, "png") )
return Item::auth_image;

View File

@@ -66,6 +66,8 @@ bool IsFile(const char * file);
bool IsFile(const std::string & file);
bool CreateDir(const char * dir, int priv);
bool CreateDir(const std::string & dir, int priv);
bool CreateDirs(const char * base_dir, const char * dirs, int priv);
bool CreateDirs(const std::string & base_dir, const std::string & dirs, int priv);
const char * GetFileExt(const char * name);
Item::Auth SelectFileType(const char * file_name);

View File

@@ -125,3 +125,24 @@ std::vector<Item*>::reverse_iterator i;
log << log2 << "M: current mount point is: " << pmount->TypeToStr() << " (default)"
<< ", fs: " << pmount->FsToStr() << logend;
}
// can return null pointer
// and we don't assume cms as a default mount point if nothing is found
Mount * Mounts::CalcMount(long dir_id)
{
while( true )
{
Item * pdir = data.dirs.GetDir(dir_id);
if( !pdir )
return 0;
std::map<long, Mount>::iterator m = mount_tab.find( pdir->id );
if( m != mount_tab.end() )
return &(m->second);
dir_id = pdir->parent_id;
}
}

View File

@@ -27,7 +27,7 @@ public:
Error ReadMounts();
void CalcCurMount();
Mount * CalcMount(long dir_id);
// current mount point
// will not be null after calling CalcCurMount() or ReadMounts([...])

View File

@@ -505,7 +505,6 @@ bool compressing = data.compression && role == responder && redirect_to.empty()
!browser_msie && !browser_konqueror &&
accept_encoding_parser.AcceptDeflate() && source.size() >= 512;
if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM )
header = h_404;
@@ -695,6 +694,28 @@ bool Request::HasReadExecAccessForRoot(const Item & item)
}
bool Request::HasReadExecAccessToPath(long dir_id)
{
while( true )
{
Item * pdir = data.dirs.GetDir(dir_id);
if( !pdir )
return false;
if( !HasReadExecAccess(*pdir) )
return false;
dir_id = pdir->parent_id;
if( dir_id == -1 )
return true;
}
}
// returning true if we can create a thread in the current directory
bool Request::CanCreateThread(bool check_root)
{
@@ -939,29 +960,21 @@ return false;
bool Request::MakePathSimpleFs(std::string & path, bool create_dir)
bool Request::MakePathSimpleFs(std::string & path, long dir_id, bool create_dir)
{
size_t i;
path = data.auth_simplefs_dir;
if( path.empty() )
if( data.auth_simplefs_dir.empty() )
{
log << log1 << "Request: auth_simplefs_dir is not set in the config file" << logend;
return false;
}
// skipping the first - the first is root
for(i=1 ; i<dir_table.size() ; ++i)
{
path += '/';
path += dir_table[i]->url;
if( !data.dirs.MakePath(dir_id, path) )
return false;
if( create_dir && !CreateDir(path, 0755) )
return false;
}
if( create_dir && !CreateDirs(data.auth_simplefs_dir, path, 0755) )
return false;
path += '/';
path.insert(0, data.auth_simplefs_dir);
return true;
}
@@ -990,10 +1003,10 @@ char * hash = buffer;
// make sure that the length is even
if( (strlen(hash) & 1) != 0 )
hash = buffer + 1; // the first character was our zero
hash = buffer + 1; // the first character was zero
// creating dirs without the last part
// the last part is a part of a file (not a directory)
// the last part is a part of a file
for(size_t i=0 ; hash[i] != 0 ; i+=2)
{
path += hash[i];
@@ -1016,22 +1029,24 @@ return true;
}
// making a complete path to a request.item static file
bool Request::MakePath(std::string & path, bool create_dir)
// making a complete path to a static file
bool Request::MakePath(const Item & item, std::string & path, bool create_dir)
{
bool res;
if( data.mounts.pmount->fs == Mount::hashfs )
Mount * pmount = data.mounts.CalcMount(item.parent_id);
if( !pmount || pmount->fs == Mount::simplefs )
{
res = MakePathHashFs(path, request.item.id, create_dir);
res = MakePathSimpleFs(path, item.parent_id, create_dir);
}
else
{
res = MakePathSimpleFs(path, create_dir);
res = MakePathHashFs(path, item.id, create_dir);
}
if( res )
path += request.item.url;
path += item.url;
else
path.clear();
@@ -1040,3 +1055,7 @@ return res;
bool Request::MakePath(Item & item, bool create_dir)
{
return MakePath(item, item.auth_path, create_dir);
}

View File

@@ -157,6 +157,7 @@ struct Request
bool HasReadWriteAccess(const Item & item);
bool HasReadExecAccess(const Item & item);
bool HasReadExecAccessForRoot(const Item & item);
bool HasReadExecAccessToPath(long dir_id);
bool CanCreateThread(bool check_root = false);
bool CanCreateTicket(bool check_root = false);
@@ -170,9 +171,10 @@ struct Request
bool CanUseBBCode(long user_id);
bool CanUseRaw(long user_id);
bool MakePathSimpleFs(std::string & path, bool create_dir = false);
bool MakePathSimpleFs(std::string & path, long dir_id, bool create_dir = false);
bool MakePathHashFs(std::string & path, long id, bool create_dir = false);
bool MakePath(std::string & path, bool create_dir = false);
bool MakePath(const Item & item, std::string & path, bool create_dir = false);
bool MakePath(Item & item, bool create_dir = false);
private: