diff --git a/content/Makefile.dep b/content/Makefile.dep index d91a6eb..133db91 100755 --- a/content/Makefile.dep +++ b/content/Makefile.dep @@ -49,6 +49,21 @@ content.o: ../core/dirs.h ../core/users.h ../core/groups.h content.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h content.o: ../core/mount.h ../core/loadavg.h ../core/misc.h ../core/plugin.h content.o: ../core/request.h ../core/data.h ../core/pluginmsg.h +cp.o: content.h ../core/item.h ../templates/templates.h +cp.o: ../templates/patterncacher.h ../templates/misc.h +cp.o: ../templates/localefilter.h ../core/locale.h ../confparser/confparser.h +cp.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h +cp.o: ../core/log.h ../core/thread.h ../core/ticket.h ../core/db.h +cp.o: ../core/item.h ../core/user.h ../core/group.h ../core/thread.h +cp.o: ../core/error.h ../core/log.h ../core/dircontainer.h +cp.o: ../core/ugcontainer.h ../core/ticket.h ../core/request.h +cp.o: ../core/requesttypes.h ../core/session.h ../core/rebus.h +cp.o: ../core/plugindata.h ../core/function.h ../core/compress.h +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 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/Makefile.o.dep b/content/Makefile.o.dep index e418960..d47e017 100755 --- a/content/Makefile.o.dep +++ b/content/Makefile.o.dep @@ -1 +1 @@ -o = adduser.o cat.o content.o createthread.o createticket.o default.o download.o editticket.o emacs.o last.o login.o logout.o ls.o misc_item.o misc_specialfile.o mkdir.o mv.o node.o priv.o reload.o rm.o run.o subject.o thread.o ticket.o uname.o upload.o who.o +o = adduser.o cat.o content.o cp.o createthread.o createticket.o default.o download.o editticket.o emacs.o last.o login.o logout.o ls.o misc_item.o misc_specialfile.o mkdir.o mv.o node.o priv.o reload.o rm.o run.o subject.o thread.o ticket.o uname.o upload.o who.o diff --git a/content/content.cpp b/content/content.cpp index cdbf79b..0c7e12f 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -112,6 +112,61 @@ void Content::SetDefaultFunction() } +void Content::FunNothing() +{ + /* do nothing */ +} + + +void Content::CallFunction() +{ + static FunItem tab[] = { + {FUN_LOGOUT, &Content::FunLogout}, + {FUN_CAT, &Content::FunCat}, + {FUN_LS, &Content::FunLs}, + {FUN_EMACS, &Content::FunEmacs}, + {FUN_MKDIR, &Content::FunMkdir}, + {FUN_DEFAULT, &Content::FunDefault}, + {FUN_PRIV, &Content::FunPriv}, + {FUN_RM, &Content::FunRm}, + {FUN_RUN, &Content::FunRun}, + {FUN_NODE, &Content::FunNode}, + {FUN_WHO, &Content::FunWho}, + {FUN_LAST, &Content::FunLast}, + {FUN_THREAD, &Content::FunThread}, + {FUN_RELOAD, &Content::FunReload}, + {FUN_UPLOAD, &Content::FunUpload}, + {FUN_TICKET, &Content::FunTicket}, + {FUN_CKEDITOR, &Content::FunEmacs}, + {FUN_LOGIN, &Content::FunLogin}, + {FUN_MV, &Content::FunMv}, + {FUN_UNAME, &Content::FunUname}, + {FUN_CHMOD, &Content::FunPriv}, + {FUN_CHOWN, &Content::FunPriv}, + {FUN_DOWNLOAD, &Content::FunDownload}, + {FUN_ADDUSER, &Content::FunAddUser}, + {FUN_SUBJECT, &Content::FunSubject}, + {FUN_CP, &Content::FunCp}, + {FUN_UPTIME, &Content::FunNothing}, + {FUN_EDITTICKET,&Content::FunEditTicket}, + {FUN_CREATETHREAD, &Content::FunCreateThread}, + {FUN_CREATETICKET, &Content::FunCreateTicket} + }; + + size_t len = sizeof(tab) / sizeof(FunItem); + size_t i; + + for(i=0 ; icode ) + { + (this->*tab[i].fun)(); + return; + } + } + + request.status = WINIX_ERR_PERMISSION_DENIED; +} void Content::MakeStandardFunction() @@ -145,102 +200,51 @@ void Content::MakeStandardFunction() return; } - - if( request.pfunction->code == FUN_LOGOUT ) - FunLogout(); - else - if( request.pfunction->code == FUN_CAT ) - FunCat(); - else - if( request.pfunction->code == FUN_LS ) - FunLs(); - else - if( request.pfunction->code == FUN_EMACS ) - FunEmacs(); - else - if( request.pfunction->code == FUN_MKDIR ) - FunMkdir(); - else - if( request.pfunction->code == FUN_DEFAULT ) - FunDefault(); - else - if( request.pfunction->code == FUN_PRIV ) - FunPriv(); - else - if( request.pfunction->code == FUN_RM ) - FunRm(); - else - if( request.pfunction->code == FUN_RUN ) - FunRun(); - else - if( request.pfunction->code == FUN_NODE ) - FunNode(); - else - if( request.pfunction->code == FUN_WHO ) - FunWho(); - else - if( request.pfunction->code == FUN_LAST ) - FunLast(); - else - if( request.pfunction->code == FUN_THREAD ) - FunThread(); - else - if( request.pfunction->code == FUN_RELOAD ) - FunReload(); - else - if( request.pfunction->code == FUN_CREATETHREAD ) - FunCreateThread(); - else - if( request.pfunction->code == FUN_UPLOAD ) - FunUpload(); - else - if( request.pfunction->code == FUN_CREATETICKET ) - FunCreateTicket(); - else - if( request.pfunction->code == FUN_EDITTICKET ) - FunEditTicket(); - else - if( request.pfunction->code == FUN_TICKET ) - FunTicket(); - else - if( request.pfunction->code == FUN_CKEDITOR ) - FunEmacs(); - else - if( request.pfunction->code == FUN_LOGIN ) - FunLogin(); - else - if( request.pfunction->code == FUN_UPTIME ) - { /* do nothing */ } - else - if( request.pfunction->code == FUN_MV ) - FunMv(); - else - if( request.pfunction->code == FUN_UNAME ) - FunUname(); - else - if( request.pfunction->code == FUN_CHMOD ) - FunPriv(); - else - if( request.pfunction->code == FUN_CHOWN ) - FunPriv(); - else - if( request.pfunction->code == FUN_DOWNLOAD ) - FunDownload(); - else - if( request.pfunction->code == FUN_ADDUSER ) - FunAddUser(); - else - if( request.pfunction->code == FUN_SUBJECT ) - FunSubject(); - else - request.status = WINIX_ERR_PERMISSION_DENIED; - - + CallFunction(); } +void Content::CallPostFunction() +{ + static FunItem tab[] = { + {FUN_RUN, &Content::PostFunRun}, + {FUN_EMACS, &Content::PostFunEmacs}, + {FUN_MKDIR, &Content::PostFunMkdir}, + {FUN_DEFAULT, &Content::PostFunDefault}, + {FUN_PRIV, &Content::PostFunPriv}, + {FUN_CHMOD, &Content::PostFunPriv}, + {FUN_CHOWN, &Content::PostFunPriv}, + {FUN_LOGIN, &Content::PostFunLogin}, + {FUN_UPLOAD, &Content::PostFunUpload}, + {FUN_EDITTICKET,&Content::PostFunEditTicket}, + {FUN_CKEDITOR, &Content::PostFunEmacs}, + {FUN_ADDUSER, &Content::PostFunAddUser}, + {FUN_MV, &Content::PostFunMv}, + {FUN_SUBJECT, &Content::PostFunSubject}, + {FUN_CP, &Content::PostFunCp}, + {FUN_CREATETHREAD, &Content::PostFunCreateThread}, + {FUN_CREATETICKET, &Content::PostFunCreateTicket} + }; + + size_t len = sizeof(tab) / sizeof(FunItem); + size_t i; + + for(i=0 ; icode ) + { + (this->*tab[i].fun)(); + return; + } + } + + log << log1 << "Content: unknown post function" << logend; + request.status = WINIX_ERR_PERMISSION_DENIED; +} + + void Content::MakePost() { if( request.role == Request::authorizer ) @@ -259,70 +263,7 @@ void Content::MakePost() return; } - switch( request.pfunction->code ) - { - case FUN_RUN: - PostFunRun(); - break; - - case FUN_EMACS: - PostFunEmacs(); - break; - - case FUN_MKDIR: - PostFunMkdir(); - break; - - case FUN_DEFAULT: - PostFunDefault(); - break; - - case FUN_PRIV: - case FUN_CHMOD: - case FUN_CHOWN: - PostFunPriv(); - break; - - case FUN_LOGIN: - PostFunLogin(); - break; - - case FUN_CREATETHREAD: - PostFunCreateThread(); - break; - - case FUN_UPLOAD: - PostFunUpload(); - break; - - case FUN_CREATETICKET: - PostFunCreateTicket(); - break; - - case FUN_EDITTICKET: - PostFunEditTicket(); - break; - - case FUN_CKEDITOR: - PostFunEmacs(); - break; - - case FUN_ADDUSER: - PostFunAddUser(); - break; - - case FUN_MV: - PostFunMv(); - break; - - case FUN_SUBJECT: - PostFunSubject(); - break; - - default: - log << log1 << "Content: unknown post function" << logend; - break; - } + CallPostFunction(); } diff --git a/content/content.h b/content/content.h index a65002d..86ace22 100755 --- a/content/content.h +++ b/content/content.h @@ -66,6 +66,15 @@ class Content Db::ItemQuery mv_auth_iq; + /* + cp + */ + bool CpCheckAccessFrom(); + void CpAuth(Item & item); + void CpItem(Item & item, bool redirect = true); + void PostFunCp(); + void FunCp(); + void SetDefaultFunctionForFile(); @@ -73,13 +82,33 @@ class Content void SetDefaultFunction(); bool DirsHaveReadExecPerm(); + + /* + calling functions (standard, post) + */ + typedef void (Content::*Fun)(); + + struct FunItem + { + int code; + Fun fun; + }; + + void FunNothing(); + void CallFunction(); void MakeStandardFunction(); - + void CallPostFunction(); + void MakePost(); + + + + + + void SetUser(Item & item); bool CheckRebus(); - void MakePost(); void FunCat(); void FunLogout(); @@ -145,14 +174,16 @@ class Content void ReadItemContentWithType(Item & item); bool FunEmacsCheckAccess(); - void PostFunEmacsAdd(); + void PostFunEmacsAdd(Item & item); void PostFunEmacsEdit(bool with_url); bool PostEmacsCheckAbuse(bool adding); void PostFunEmacsModifyMountPoint(bool adding); void PostFunEmacs(); bool FunMkdirCheckAccess(); - void PostFunMkdir(bool add_to_dir_table = false, int privileges = 0755 ); + void PostFunMkdir(bool add_to_dir_table, int privileges); + void PostFunMkdir(); + void Mkdir(Item & item, bool add_to_dir_table); long PostFunDefaultParsePath(); void PostFunDefault(); diff --git a/content/cp.cpp b/content/cp.cpp new file mode 100755 index 0000000..21f33d8 --- /dev/null +++ b/content/cp.cpp @@ -0,0 +1,105 @@ +/* + * This file is a part of Winix + * and is not publicly distributed + * + * Copyright (c) 2008-2010, Tomasz Sowa + * All rights reserved. + * + */ + +#include +#include "content.h" +#include "../core/request.h" +#include "../core/data.h" +#include "../core/misc.h" + + +bool Content::CpCheckAccessFrom() +{ + if( request.is_item ) + { + if( !request.HasReadAccess(request.item) ) + { + request.status = WINIX_ERR_PERMISSION_DENIED; + return false; + } + } + + // dirs are checked in function parser + +return true; +} + + +void Content::CpAuth(Item & item) +{ + if( !request.MakePath(item, mv_new_path, true) ) + { + request.status = WINIX_ERR_PERMISSION_DENIED; + return; + } + + if( CopyFile(item.auth_path, mv_new_path) ) + { + log << log1 << "Content: copied static file from: " << item.auth_path << ", to: " << mv_new_path << logend; + item.auth_path = mv_new_path; + request.status = db.EditAuthById(item, item.id); + } + else + { + log << log1 << "Content: can't copy a file from: " << item.auth_path << ", to: " << mv_new_path << logend; + request.status = WINIX_ERR_PERMISSION_DENIED; + } +} + + +void Content::CpItem(Item & item, bool redirect) +{ + if( MoveIsTheSameFile(item) ) + return; + + if( !mv_file.empty() ) + { + item.url = mv_file; + PrepareUrl(item); + } + + item.parent_id = mv_dir_id; + PostFunEmacsAdd(item); + + if( request.status == WINIX_ERR_OK ) + { + if( item.auth != Item::auth_none ) + CpAuth(item); + + if( redirect ) + RedirectTo(item); + } +} + + + +void Content::PostFunCp() +{ + if( CpCheckAccessFrom() && + MoveParseDir(mv_dir_id, mv_dir, mv_file) && + MoveCheckAccessTo(mv_dir_id) ) + { + if( request.is_item ) + { + CpItem(request.item); + } + else + { + /* not implemented yet */ + request.status = WINIX_ERR_PERMISSION_DENIED; + } + } +} + + + +void Content::FunCp() +{ + CpCheckAccessFrom(); +} diff --git a/content/createthread.cpp b/content/createthread.cpp index 8337655..3cf7c84 100755 --- a/content/createthread.cpp +++ b/content/createthread.cpp @@ -111,7 +111,7 @@ void Content::PostFunCreateThread() request.item.type = Item::file; request.item.privileges = 0644; // !! tymczasowo request.item.parent_id = request.dir_table.back()->id; - PostFunEmacsAdd(); + PostFunEmacsAdd(request.item); if( request.status == WINIX_ERR_OK ) AddThread(); diff --git a/content/createticket.cpp b/content/createticket.cpp index 2e24bc4..a8f40a2 100755 --- a/content/createticket.cpp +++ b/content/createticket.cpp @@ -199,7 +199,7 @@ void Content::PostFunCreateTicket() request.item.type = Item::file; request.item.privileges = 0644; // !! tymczasowo request.item.parent_id = request.dir_table.back()->id; - PostFunEmacsAdd(); + PostFunEmacsAdd(request.item); if( request.status == WINIX_ERR_OK ) AddTicket(); diff --git a/content/emacs.cpp b/content/emacs.cpp index f40fc89..930c7c5 100755 --- a/content/emacs.cpp +++ b/content/emacs.cpp @@ -39,9 +39,9 @@ return true; } -void Content::PostFunEmacsAdd() +void Content::PostFunEmacsAdd(Item & item) { - request.status = db.AddItem(request.item); + request.status = db.AddItem(item); if( request.status == WINIX_ERR_OK ) { @@ -129,7 +129,7 @@ void Content::PostFunEmacs() { request.is_item = true; request.item.privileges = 0644; // !! tymczasowo, bedzie uzyte umask - PostFunEmacsAdd(); + PostFunEmacsAdd(request.item); } else { diff --git a/content/mkdir.cpp b/content/mkdir.cpp index d9f2143..61e95e6 100755 --- a/content/mkdir.cpp +++ b/content/mkdir.cpp @@ -67,6 +67,10 @@ void Content::PostFunMkdir(bool add_to_dir_table, int privileges) } +void Content::PostFunMkdir() +{ + PostFunMkdir(false, 0755); +} void Content::FunMkdir() diff --git a/content/mv.cpp b/content/mv.cpp index c6085de..0b558a5 100755 --- a/content/mv.cpp +++ b/content/mv.cpp @@ -49,6 +49,7 @@ return true; } + bool Content::MoveCheckAccessFrom() { if( request.is_item ) @@ -125,7 +126,7 @@ return true; bool Content::MoveParseDir(long & dir_id, std::string & dir, std::string & file) { - std::string * move_to = request.PostVar("moveto"); + std::string * move_to = request.PostVar("to"); if( !move_to ) { diff --git a/content/upload.cpp b/content/upload.cpp index 103aa9d..d69afa1 100755 --- a/content/upload.cpp +++ b/content/upload.cpp @@ -112,7 +112,7 @@ void Content::UploadMulti() request.item.auth = SelectFileType(file_name); PrepareUrl(request.item); - PostFunEmacsAdd(); // always adding a new item + PostFunEmacsAdd(request.item); // always adding a new item if( !UploadCreatePath() ) return; @@ -150,7 +150,7 @@ void Content::UploadSingle() PrepareUrl(request.item); } - PostFunEmacsAdd(); // always adding a new item + PostFunEmacsAdd(request.item); // always adding a new item // url can be changed by PostFunEmacsAdd() if( !UploadCreatePath() ) diff --git a/core/function.h b/core/function.h index a48b667..679ba62 100755 --- a/core/function.h +++ b/core/function.h @@ -44,6 +44,7 @@ #define FUN_DOWNLOAD 28 #define FUN_ADDUSER 29 #define FUN_SUBJECT 30 +#define FUN_CP 31 diff --git a/core/functions.cpp b/core/functions.cpp index 7e5795a..981cc65 100755 --- a/core/functions.cpp +++ b/core/functions.cpp @@ -72,6 +72,7 @@ void Functions::ReadFunctions() AddFun(FUN_DOWNLOAD, "download"); AddFun(FUN_ADDUSER, "adduser"); AddFun(FUN_SUBJECT, "subject"); + AddFun(FUN_CP, "cp"); // functions which need more privileges diff --git a/core/misc.cpp b/core/misc.cpp index eb00600..8800a48 100755 --- a/core/misc.cpp +++ b/core/misc.cpp @@ -653,7 +653,64 @@ bool CreateDirs(const std::string & base_dir, const std::string & dirs, int priv +bool CopyFile(FILE * in, FILE * out) +{ +char buf[1024]; +size_t buflen = sizeof(buf)/sizeof(char); +size_t len; + do + { + len = fread(buf, 1, buflen, in); + + if( len > 0 ) + fwrite(buf, 1, len, out); + + if( ferror(in) || ferror(out) ) + return false; + } + while( !feof(in) ); + +return true; +} + + +bool CopyFile(const char * src, const char * dst) +{ +FILE * in, * out; + + in = fopen(src, "rb"); + + if( !in ) + return false; + + out = fopen(dst, "wb"); + + if( !out ) + { + fclose(in); + return false; + } + + bool res = CopyFile(in, out); + + fclose(in); + fclose(out); + + if( res && ferror(out) ) + res = false; + + if( !res ) + remove(dst); + +return res; +} + + +bool CopyFile(const std::string & src, const std::string & dst) +{ + return CopyFile(src.c_str(), dst.c_str()); +} // if there is not an extension it returns a pointer to the last '\0' character diff --git a/core/misc.h b/core/misc.h index 16fa443..ecf29ed 100755 --- a/core/misc.h +++ b/core/misc.h @@ -15,7 +15,7 @@ #include #include #include "item.h" - +#include void ToString(std::string & s, int value); @@ -64,6 +64,10 @@ 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); +bool CopyFile(FILE * in, FILE * out); +bool CopyFile(const char * src, const char * dst); +bool CopyFile(const std::string & src, const std::string & dst); + const char * GetFileExt(const char * name); Item::Auth SelectFileType(const char * file_name); diff --git a/html/fun_cp.html b/html/fun_cp.html new file mode 100755 index 0000000..55fc05c --- /dev/null +++ b/html/fun_cp.html @@ -0,0 +1,27 @@ +

{cp_header}

+ +[include "error.html"] + +
+
+ {cp_form_legend} + +

+ [if-one item_is]{cp_page} "[item_url]":[else]{cp_dir} "[dir_without_slash]"[end] +

+ + +

{suggested_url}

+ + + + [if-no item_is] + + [end] + + +
+
+ + + diff --git a/html/fun_mv.html b/html/fun_mv.html index 544bbed..0b8e236 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 4dae31f..d628a37 100755 --- a/locale/en +++ b/locale/en @@ -198,6 +198,13 @@ mv_dir = Move directory mv_only_content = Move only content of the directory +cp_header = Copy +cp_form_legeng = Copy form +cp_page = Copy page +cp_dir = Copy directory +cp_only_content = Copy only content of the directory + + subject_header = Edit subject subject_form_legend = Edit subject form diff --git a/locale/pl b/locale/pl index 561ca2c..9abaa72 100755 --- a/locale/pl +++ b/locale/pl @@ -48,6 +48,7 @@ change = Zmie edit = Edytuj add = Dodaj move = Przenieś +copy = Kopiuj user = Użytkownik group = Grupa permissions = Uprawnienia @@ -200,6 +201,14 @@ mv_dir = Przenie mv_only_content = Przenieś tylko zawartość katalogu +cp_header = Kopiuj +cp_form_legeng = Formularz kopiowania +cp_page = Kopiuj stronę +cp_dir = Kopiuj katalog +cp_only_content = Kopiuj tylko zawartość katalogu + + + subject_header = Zmień tytuł subject_form_legend = Formularz zmiany tytułu diff --git a/templates/templates.cpp b/templates/templates.cpp index 3390b0c..2b93621 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -67,7 +67,8 @@ Ezc::Pattern * p = 0; {FUN_UNAME, pat_fun_uname}, {FUN_CKEDITOR, pat_fun_ckeditor}, {FUN_SUBJECT, pat_fun_subject}, - {FUN_ADDUSER, pat_fun_adduser} + {FUN_ADDUSER, pat_fun_adduser}, + {FUN_CP, pat_fun_cp} }; size_t i, len = sizeof(pat_name_tab)/sizeof(PatName); @@ -519,6 +520,7 @@ using namespace TemplatesFunctions; ReadFile(pat_fun_ckeditor, "fun_ckeditor.html"); ReadFile(pat_fun_adduser, "fun_adduser.html"); ReadFile(pat_fun_subject, "fun_subject.html"); + ReadFile(pat_fun_cp, "fun_cp.html"); } diff --git a/templates/templates.h b/templates/templates.h index fe66c1d..889d0f4 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -53,6 +53,7 @@ namespace TemplatesFunctions pat_item_tab_info, pat_dir_last_info, pat_fun_subject, + pat_fun_cp, pat_last // should be last };