From fe31e0e849719cfa5c266f2835adbb1c36615ce7 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 5 Jun 2010 19:44:49 +0000 Subject: [PATCH] added: cp function for directories added: emacs/mkdir uses group_id of the parent directory when creating new items added: parameter 'dirls' to ls function git-svn-id: svn://ttmath.org/publicrep/winix/trunk@606 e52654a7-88a9-db11-a3e9-0013d4bc506e --- content/Makefile.dep | 2 +- content/content.cpp | 2 + content/content.h | 18 +++- content/cp.cpp | 192 ++++++++++++++++++++++++++++++++++++---- content/emacs.cpp | 4 +- content/mv.cpp | 2 +- html/fun_cp.html | 8 +- html/fun_ls.html | 26 +++++- html/fun_mv.html | 2 +- locale/en | 4 +- locale/pl | 5 +- templates/dir.cpp | 50 ++++++++++- templates/templates.cpp | 3 + templates/templates.h | 3 + 14 files changed, 288 insertions(+), 33 deletions(-) diff --git a/content/Makefile.dep b/content/Makefile.dep index 133db91..b04dd2a 100755 --- a/content/Makefile.dep +++ b/content/Makefile.dep @@ -63,7 +63,7 @@ cp.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h cp.o: ../core/htmlfilter.h ../core/postmultiparser.h ../core/data.h cp.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h cp.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h -cp.o: ../core/loadavg.h +cp.o: ../core/loadavg.h ../core/misc.h createthread.o: content.h ../core/item.h ../templates/templates.h createthread.o: ../templates/patterncacher.h ../templates/misc.h createthread.o: ../templates/localefilter.h ../core/locale.h diff --git a/content/content.cpp b/content/content.cpp index 0c7e12f..8de6f65 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -524,6 +524,8 @@ void Content::SetUser(Item & item) item.user_id = -1; request.PostVar("guestname", item.guest_name); } + + item.group_id = request.dir_table.back()->group_id; } diff --git a/content/content.h b/content/content.h index 86ace22..1a92e22 100755 --- a/content/content.h +++ b/content/content.h @@ -71,9 +71,25 @@ class Content */ bool CpCheckAccessFrom(); void CpAuth(Item & item); - void CpItem(Item & item, bool redirect = true); + void CpSetNewAttributes(Item & item); + void CpItem(Item & item, long dst_dir_id); + void CpFilesInDir(const Item & dir, long dst_dir_id); + void CpContentOfDir(const Item & item, long dst_dir_id); + long CpDir(const Item & item, long dst_dir_id); + void CpItemCheck(Item & item, bool redirect = true); + void CpContentOfDirCheck(const Item & item, bool redirect = true); + void CpDirCheck(const Item & item, bool redirect = true); void PostFunCp(); void FunCp(); + void CpPrepare(); + Item cp_temp; + Db::ItemQuery cp_iq; + bool cp_remove_defaults; + bool cp_preserve_attr; + long cp_new_user; + long cp_new_group; + + diff --git a/content/cp.cpp b/content/cp.cpp index 21f33d8..6c5575b 100755 --- a/content/cp.cpp +++ b/content/cp.cpp @@ -24,8 +24,13 @@ bool Content::CpCheckAccessFrom() return false; } } + else + if( !request.IsParam("r") ) + { + // directories need 'r' parameter + request.status = WINIX_ERR_PERMISSION_DENIED; + } - // dirs are checked in function parser return true; } @@ -53,46 +58,197 @@ void Content::CpAuth(Item & item) } -void Content::CpItem(Item & item, bool redirect) +void Content::CpSetNewAttributes(Item & item) { - if( MoveIsTheSameFile(item) ) - return; - - if( !mv_file.empty() ) - { - item.url = mv_file; - PrepareUrl(item); - } - - item.parent_id = mv_dir_id; + item.user_id = cp_new_user; + item.group_id = cp_new_group; + item.SetDateModifyToNow(); +} + + +void Content::CpItem(Item & item, long dst_dir_id) +{ + if( !request.HasReadAccess(item) ) + return; // !! w przyszlosci bedziemy dodawac komunikaty do specjalnej tablicy (narazie nie zaimplementowane) + + item.parent_id = dst_dir_id; + + if( !cp_preserve_attr ) + CpSetNewAttributes(item); + PostFunEmacsAdd(item); if( request.status == WINIX_ERR_OK ) { if( item.auth != Item::auth_none ) CpAuth(item); - - if( redirect ) - RedirectTo(item); } } + +void Content::CpPrepare() +{ + cp_iq.SetAll(true, false); + cp_iq.WhereType(Item::file); + + cp_new_user = -1; + cp_new_group = -1; + + if( request.session->puser ) + cp_new_user = request.session->puser->id; + + Item * pdir = data.dirs.GetDir(mv_dir_id); + + if( pdir ) + cp_new_group = pdir->group_id; +} + + + +void Content::CpFilesInDir(const Item & dir, long dst_dir_id) +{ + cp_iq.WhereParentId(dir.id); + db.GetItems(request.item_table, cp_iq); + + for(size_t i=0 ; isecond), dst_dir_id); + + CpFilesInDir(item, dst_dir_id); +} + + + +// we shouldn't change 'item' because we have references to our data.dirs objects +long Content::CpDir(const Item & item, long dst_dir_id) +{ + cp_temp = item; + cp_temp.parent_id = dst_dir_id; + + if( !mv_file.empty() ) + { + cp_temp.url = mv_file; + mv_file.clear(); + PrepareUrl(cp_temp); + } + + if( !cp_preserve_attr ) + CpSetNewAttributes(cp_temp); + + if( cp_remove_defaults ) + cp_temp.default_item = -1; + + Mkdir(cp_temp, false); + long new_dir_id = cp_temp.id; // remember the new dir_id + + if( request.HasReadExecAccess(item) ) + CpContentOfDir(item, cp_temp.id); + +return new_dir_id; // and return it +} + + + + +// here 'item' can be changed in place +void Content::CpItemCheck(Item & item, bool redirect) +{ + if( MoveIsTheSameFile(item) ) + return; + + if( !mv_file.empty() ) + { + item.url = mv_file; + PrepareUrl(item); + } + + CpItem(item, mv_dir_id); + + if( request.status==WINIX_ERR_OK && redirect ) + RedirectTo(item); +} + + + +void Content::CpContentOfDirCheck(const Item & item, bool redirect) +{ + if( !mv_file.empty() ) + { + request.status = WINIX_ERR_INCORRECT_DIR; + return; + } + + if( mv_dir_id == item.id ) + return; // nothing to do + + if( data.dirs.HasParent(mv_dir_id, item.id) ) + { + log << log1 << "Content: cannot copy directory to inside it" << logend; + request.status = WINIX_ERR_INCORRECT_DIR; + return; + } + + CpContentOfDir(item, mv_dir_id); + + if( request.status==WINIX_ERR_OK && redirect ) + RedirectTo(mv_dir_id); +} + + + +void Content::CpDirCheck(const Item & item, bool redirect) +{ + if( mv_file.empty() && mv_dir_id == item.id ) + return; // nothing to do + + if( mv_dir_id == item.id || data.dirs.HasParent(mv_dir_id, item.id) ) + { + log << log1 << "Content: cannot copy directory to inside it" << logend; + request.status = WINIX_ERR_INCORRECT_DIR; + return; + } + + long new_dir_id = CpDir(item, mv_dir_id); + + if( request.status==WINIX_ERR_OK && redirect ) + RedirectTo(new_dir_id); +} + + + void Content::PostFunCp() { if( CpCheckAccessFrom() && MoveParseDir(mv_dir_id, mv_dir, mv_file) && MoveCheckAccessTo(mv_dir_id) ) { + CpPrepare(); + cp_preserve_attr = request.IsPostVar("preserveattr"); + if( request.is_item ) { - CpItem(request.item); + CpItemCheck(request.item); } else { - /* not implemented yet */ - request.status = WINIX_ERR_PERMISSION_DENIED; + cp_remove_defaults = request.IsPostVar("removedefaults"); + + if( request.IsPostVar("onlycontent") ) + CpContentOfDirCheck(*request.dir_table.back()); + else + CpDirCheck(*request.dir_table.back()); } } } diff --git a/content/emacs.cpp b/content/emacs.cpp index 930c7c5..f38ec08 100755 --- a/content/emacs.cpp +++ b/content/emacs.cpp @@ -45,7 +45,9 @@ void Content::PostFunEmacsAdd(Item & item) if( request.status == WINIX_ERR_OK ) { - log << log2 << "Content: added a new item" << logend; + log << log2 << "Content: added a new item, url: " << item.url << ", id: " << item.id + << ", parent_id: " << item.parent_id << logend; + request.notify_code |= WINIX_NOTIFY_ITEM_ADD; } } diff --git a/content/mv.cpp b/content/mv.cpp index 0b558a5..04719c1 100755 --- a/content/mv.cpp +++ b/content/mv.cpp @@ -248,7 +248,7 @@ Db::ItemQuery iq; void Content::MoveAuthPrepareQuery() { - mv_auth_iq.SetAll(true, false); + mv_auth_iq.SetAll(false, false); mv_auth_iq.sel_parent_id = true; mv_auth_iq.sel_type = true; diff --git a/html/fun_cp.html b/html/fun_cp.html index 55fc05c..8921994 100755 --- a/html/fun_cp.html +++ b/html/fun_cp.html @@ -2,7 +2,7 @@ [include "error.html"] -
+
{cp_form_legend} @@ -12,12 +12,16 @@

{suggested_url}

- + +

+ [if-no item_is] + [end] +

diff --git a/html/fun_ls.html b/html/fun_ls.html index 14169aa..42cb9da 100755 --- a/html/fun_ls.html +++ b/html/fun_ls.html @@ -23,20 +23,31 @@ [is winix_function_param_is "l"] + [# loading dir childs table with a parent directory] + [dir_childs_tab "with_parent"] + [if-one dir_childs_tab item_tab] [for dir_childs_tab] + - + [end] [for item_tab] + @@ -49,14 +60,23 @@ [else] + [# loading dir childs table with a parent directory] + [dir_childs_tab "with_parent"] + [if-one dir_childs_tab] [end] - + [if-one item_tab]
    [for item_tab] diff --git a/html/fun_mv.html b/html/fun_mv.html index 0b8e236..51cf5de 100755 --- a/html/fun_mv.html +++ b/html/fun_mv.html @@ -12,7 +12,7 @@

    {suggested_url}

    - + [if-no item_is] diff --git a/locale/en b/locale/en index d628a37..b2eb8cf 100755 --- a/locale/en +++ b/locale/en @@ -199,10 +199,12 @@ mv_only_content = Move only content of the directory cp_header = Copy -cp_form_legeng = Copy form +cp_form_legend = Copy form cp_page = Copy page cp_dir = Copy directory cp_only_content = Copy only content of the directory +cp_remove_defaults = Remove 'default' attribute from copied directories +cp_preserve_attr = Preserve attributes: user, group, times subject_header = Edit subject diff --git a/locale/pl b/locale/pl index 9abaa72..992827d 100755 --- a/locale/pl +++ b/locale/pl @@ -202,11 +202,12 @@ mv_only_content = Przenie cp_header = Kopiuj -cp_form_legeng = Formularz kopiowania +cp_form_legend = Formularz kopiowania cp_page = Kopiuj stronę cp_dir = Kopiuj katalog cp_only_content = Kopiuj tylko zawartość katalogu - +cp_remove_defaults = Usuń atrybut 'default' z kopiowanych katalogów +cp_preserve_attr = Zachowaj atrybuty: użytkownik, grupa, czas subject_header = Zmień tytuł diff --git a/templates/dir.cpp b/templates/dir.cpp index edad2c2..4b6fc4c 100755 --- a/templates/dir.cpp +++ b/templates/dir.cpp @@ -43,6 +43,34 @@ void dir_without_slash(Info & i) } +void dir_parent(Info & i) +{ + if( request.dir_table.empty() ) + return; + + for(size_t a=0 ; aurl); + i.out << '/'; + } +} + + +void dir_parent_without_slash(Info & i) +{ + if( request.dir_table.empty() ) + return; + + for(size_t a=0 ; aurl); + + if( request.dir_table.size()>=2 && a dir_childs_table; static size_t dir_childs_index; - // request.id is never 0 and we can start dir_childs_reqid from 0 static size_t dir_childs_reqid = 0; +// is the first directory the parent ('..') +static bool dir_childs_has_parent; void dir_childs_tab(Info & i) @@ -125,9 +154,19 @@ void dir_childs_tab(Info & i) { dir_childs_reqid = request.id; dir_childs_table.clear(); - + dir_childs_has_parent = false; + if( !request.dir_table.empty() ) + { + if( request.dir_table.size() >= 2 && i.par == "with_parent") + { + Item * dir_up = request.dir_table[request.dir_table.size()-2]; + dir_childs_table.push_back(dir_up); + dir_childs_has_parent = true; + } + data.dirs.GetDirChilds(request.dir_table.back()->id, dir_childs_table); + } } dir_childs_index = i.iter; @@ -135,6 +174,13 @@ void dir_childs_tab(Info & i) } +// is this child a parent ('..') +void dir_childs_is_parent(Info & i) +{ + i.res = (dir_childs_has_parent && dir_childs_index == 0); +} + + void dir_childs_tab_url(Info & i) { if( dir_childs_index < dir_childs_table.size() ) diff --git a/templates/templates.cpp b/templates/templates.cpp index 2b93621..8015336 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -249,6 +249,8 @@ void Templates::CreateFunctions() */ functions.Insert("dir", dir); functions.Insert("dir_without_slash", dir_without_slash); + functions.Insert("dir_parent", dir_parent); + functions.Insert("dir_parent_without_slash", dir_parent_without_slash); functions.Insert("dir_can_read_exec", dir_can_read_exec); functions.Insert("dir_can_write", dir_can_write); functions.Insert("dir_can_remove", dir_can_remove); @@ -256,6 +258,7 @@ void Templates::CreateFunctions() functions.Insert("dir_can_use_mkdir", dir_can_use_mkdir); functions.Insert("dir_childs_tab", dir_childs_tab); + functions.Insert("dir_childs_is_parent", dir_childs_is_parent); functions.Insert("dir_childs_tab_url", dir_childs_tab_url); functions.Insert("dir_childs_tab_privileges", dir_childs_tab_privileges); functions.Insert("dir_childs_tab_user", dir_childs_tab_user); diff --git a/templates/templates.h b/templates/templates.h index 889d0f4..3f11ea3 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -161,6 +161,8 @@ namespace TemplatesFunctions */ void dir(Info & i); void dir_without_slash(Info & i); + void dir_parent(Info & i); + void dir_parent_without_slash(Info & i); void dir_can_read_exec(Info & i); void dir_can_write(Info & i); void dir_can_remove(Info & i); @@ -168,6 +170,7 @@ namespace TemplatesFunctions void dir_can_use_mkdir(Info & i); void dir_childs_tab(Info & i); + void dir_childs_is_parent(Info & i); void dir_childs_tab_url(Info & i); void dir_childs_tab_privileges(Info & i); void dir_childs_tab_user(Info & i);
d [dir_childs_tab_privileges] [dir_childs_tab_user] [dir_childs_tab_group][dir_childs_tab_url]/ + [if-one dir_childs_is_parent] + ../ + [else] + [dir_childs_tab_url]/ + [end] +
- [item_tab_privileges] [item_tab_user] [item_tab_group]