From 16e51cd4e5c5986ac4f561c26bd8cf3540db8b68 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Feb 2010 23:30:22 +0000 Subject: [PATCH] added: to mount points: file systems we have two file systems now: - simplefs - the files stored on the hard drive have the same structure as in the database (dir1/dir2/file) - hashfs - files are stored in special directories extented: the mountparser can read file system added: function download this is a default function for items which have static content git-svn-id: svn://ttmath.org/publicrep/winix/trunk@588 e52654a7-88a9-db11-a3e9-0013d4bc506e --- Makefile | 2 +- content/Makefile.dep | 21 +++++- content/Makefile.o.dep | 2 +- content/cat.cpp | 5 +- content/content.cpp | 14 +++- content/content.h | 6 +- content/download.cpp | 48 ++++++++++++ content/upload.cpp | 36 +++------ core/config.cpp | 5 +- core/data.h | 11 +-- core/error.h | 1 + core/function.h | 1 + core/functions.cpp | 4 + core/misc.cpp | 22 ++++++ core/misc.h | 2 + core/mount.cpp | 27 ++++++- core/mount.h | 11 ++- core/mountparser.cpp | 30 +++++++- core/mountparser.h | 3 +- core/mounts.cpp | 9 ++- core/postmultiparser.cpp | 9 ++- core/request.cpp | 159 +++++++++++++++++++++++++++++++-------- core/request.h | 11 ++- html/fun_cat.html | 21 ++---- html/fun_ckeditor.html | 4 +- html/fun_upload.html | 89 +++++++++++----------- static/layout1/winix.css | 4 + templates/Makefile.dep | 9 +++ templates/Makefile.o.dep | 2 +- templates/item.cpp | 12 --- templates/ls.cpp | 6 +- templates/templates.cpp | 8 +- templates/templates.h | 8 +- templates/upload.cpp | 42 +++++++++++ 34 files changed, 487 insertions(+), 157 deletions(-) create mode 100755 content/download.cpp create mode 100755 templates/upload.cpp diff --git a/Makefile b/Makefile index f0791c8..f932385 100755 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ winix: FORCE @cd templates ; $(MAKE) -e @cd templatesnotify ; $(MAKE) -e @cd ../ezc/src ; $(MAKE) -e - $(CXX) -shared -o winix.so $(CXXFLAGS) core/*.o content/*.o templates/*.o templatesnotify/*.o confparser/*.o ../ezc/src/ezc.a -lfcgi -lpq -lz + $(CXX) -shared -o winix.so $(CXXFLAGS) core/*.o content/*.o templates/*.o templatesnotify/*.o confparser/*.o ../ezc/src/ezc.a -lfcgi -lpq -lz -lpthread @cd main ; $(MAKE) -e # use the full path with winix.so $(CXX) -o winix $(CXXFLAGS) main/*.o /home/tomek/roboczy/winix/winix.so diff --git a/content/Makefile.dep b/content/Makefile.dep index db47dc6..2c522e0 100755 --- a/content/Makefile.dep +++ b/content/Makefile.dep @@ -11,7 +11,10 @@ cat.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h cat.o: ../core/function.h ../core/thread.h ../core/compress.h cat.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h cat.o: ../core/htmlfilter.h ../core/postmultiparser.h ../core/ticket.h -cat.o: ../core/error.h +cat.o: ../core/error.h ../core/data.h ../core/dirs.h ../core/dircontainer.h +cat.o: ../core/users.h ../core/ugcontainer.h ../core/groups.h ../core/group.h +cat.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h +cat.o: ../core/mount.h ../core/loadavg.h content.o: content.h ../core/item.h ../templates/templates.h content.o: ../templates/patterncacher.h ../templates/misc.h content.o: ../templates/localefilter.h ../core/locale.h @@ -81,6 +84,22 @@ default.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h default.o: ../core/users.h ../core/groups.h ../core/functions.h default.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h default.o: ../core/loadavg.h +download.o: content.h ../core/item.h ../templates/templates.h +download.o: ../templates/patterncacher.h ../templates/misc.h +download.o: ../templates/localefilter.h ../core/locale.h +download.o: ../confparser/confparser.h ../templates/ckeditorgetparser.h +download.o: ../core/httpsimpleparser.h ../core/log.h ../core/thread.h +download.o: ../core/ticket.h ../core/done.h ../core/request.h +download.o: ../core/requesttypes.h ../core/session.h ../core/done.h +download.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h +download.o: ../core/rebus.h ../core/function.h ../core/thread.h +download.o: ../core/compress.h ../core/acceptencodingparser.h +download.o: ../core/acceptbaseparser.h ../core/htmlfilter.h +download.o: ../core/postmultiparser.h ../core/ticket.h ../core/data.h +download.o: ../core/dirs.h ../core/dircontainer.h ../core/users.h +download.o: ../core/ugcontainer.h ../core/groups.h ../core/group.h +download.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h +download.o: ../core/mount.h ../core/loadavg.h editticket.o: content.h ../core/item.h ../templates/templates.h editticket.o: ../templates/patterncacher.h ../templates/misc.h editticket.o: ../templates/localefilter.h ../core/locale.h diff --git a/content/Makefile.o.dep b/content/Makefile.o.dep index 8186f7f..34d5772 100755 --- a/content/Makefile.o.dep +++ b/content/Makefile.o.dep @@ -1 +1 @@ -o = cat.o content.o createthread.o createticket.o default.o editticket.o emacs.o last.o login.o logout.o ls.o misc_item.o misc_specialfile.o mkdir.o node.o priv.o reload.o rm.o run.o thread.o ticket.o upload.o who.o +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 node.o priv.o reload.o rm.o run.o thread.o ticket.o upload.o who.o diff --git a/content/cat.cpp b/content/cat.cpp index 1d76271..2f068df 100755 --- a/content/cat.cpp +++ b/content/cat.cpp @@ -10,6 +10,7 @@ #include "content.h" #include "../core/request.h" #include "../core/error.h" +#include "../core/data.h" @@ -18,7 +19,7 @@ void Content::FunCat() { if( !request.is_item ) { - log << log1 << "Content: Cat function requires an item" << logend; + log << log1 << "Content: cat function requires an item" << logend; request.status = Error::no_item; return; } @@ -29,6 +30,8 @@ void Content::FunCat() request.status = Error::permission_denied; return; } + + request.send_as_attachment = request.IsParam("attachment"); } diff --git a/content/content.cpp b/content/content.cpp index 5ecb8c7..d88fe2c 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -46,6 +46,9 @@ return true; void Content::SetDefaultFunctionForFile() { + if( request.item.static_auth != Item::static_none ) + request.pfunction = data.functions.GetFunction(FUN_DOWNLOAD); + else if( request.HasReadExecAccess(request.item) ) request.pfunction = data.functions.GetFunction(FUN_RUN); else @@ -223,6 +226,9 @@ void Content::MakeStandardFunction() else if( request.pfunction->code == FUN_CHOWN ) FunPriv(); + else + if( request.pfunction->code == FUN_DOWNLOAD ) + FunDownload(); else request.status = Error::permission_denied; @@ -309,7 +315,13 @@ void Content::MakePage() { bool sent = false; - if( request.is_item && request.item.content_type == Item::ct_raw && request.status == Error::ok && request.pfunction ) + if( !request.redirect_to.empty() || + !request.x_sendfile.empty() ) + return; + + + if( request.is_item && request.item.static_auth == Item::static_none && + request.item.content_type == Item::ct_raw && request.status == Error::ok && request.pfunction ) { if( request.pfunction->code == FUN_CAT ) { diff --git a/content/content.h b/content/content.h index 3e4c80b..158e0d1 100755 --- a/content/content.h +++ b/content/content.h @@ -29,6 +29,8 @@ class Content std::string temp; + void FunDownload(); + void CheckSpecialFile(); void PrepareUrl(Item & item); @@ -53,6 +55,8 @@ class Content void FunEmacs(); + void AddPathToStaticAuth(std::string & path); + void FunCKEditor(); bool FunRmCheckAccess(); @@ -141,7 +145,7 @@ class Content void UploadSingle(); bool FunUploadCheckAbuse(); void PostFunUpload(); - std::string tmp_path, tmp_path2; + std::string tmp_path; bool FunCreateTicketCheckAccess(); void FunCreateTicket(); diff --git a/content/download.cpp b/content/download.cpp new file mode 100755 index 0000000..7c3fa77 --- /dev/null +++ b/content/download.cpp @@ -0,0 +1,48 @@ +/* + * This file is a part of CMSLU -- Content Management System like Unix + * and is not publicly distributed + * + * Copyright (c) 2008-2009, Tomasz Sowa + * All rights reserved. + * + */ + +#include "content.h" +#include "../core/request.h" +#include "../core/data.h" + + + + + +void Content::FunDownload() +{ + // !! moze wywalic to no_item i wszedzie w takich miejscach dac poprostu permission_denied? + if( !request.is_item ) + { + log << log1 << "Content: pv function requires an item" << logend; + request.status = Error::no_item; + return; + } + + + if( !request.HasReadAccess(request.item) || + request.item.static_auth == Item::static_none || + data.static_simplefs_dir.empty() ) + { + request.status = Error::permission_denied; + return; + } + + request.send_as_attachment = request.IsParam("attachment"); + + if( !request.MakePath(request.x_sendfile) ) + { + request.status = Error::permission_denied; + return; + } +} + + + + diff --git a/content/upload.cpp b/content/upload.cpp index 16dc829..8a45916 100755 --- a/content/upload.cpp +++ b/content/upload.cpp @@ -27,12 +27,6 @@ bool Content::FunUploadCheckAccess() return false; } - // !! in the future the 'upload' can be used everywhere - if( data.mounts.pmount->type != Mount::cms ) - { - request.status = Error::permission_denied; - return false; - } return true; } @@ -41,10 +35,7 @@ return true; bool Content::UploadCreatePath(std::string & path) { - path.clear(); - request.MakePath(path); - - if( !request.MakeDirsOnFS() ) + if( !request.MakePath(path, true) ) { request.status = Error::permission_denied; return false; @@ -116,11 +107,6 @@ void Content::UploadMulti() request.item.privileges = 0644; // !! tymczasowo SetUser(request.item); - if( !UploadCreatePath(tmp_path) ) - return; - - tmp_path2 = tmp_path; // remember the path - PostFileTable::iterator i = request.post_file_table.begin(); for( ; i != request.post_file_table.end() ; ++i) @@ -134,14 +120,11 @@ void Content::UploadMulti() PrepareUrl(request.item); PostFunEmacsAdd(); // always adding a new item - if( request.session->done_status == Error::ok ) - { - tmp_path += '/'; - tmp_path += request.item.url; // item.url could have been changed + if( !UploadCreatePath(tmp_path) ) + return; + if( request.session->done_status == Error::ok ) UploadSaveFile(i->second.tmp_filename, tmp_path); - tmp_path = tmp_path2; // restoring the oryginal path - } } RedirectToLastDir(); @@ -180,16 +163,19 @@ void Content::UploadSingle() if( !UploadCreatePath(tmp_path) ) return; - tmp_path += '/'; - tmp_path += request.item.url; // item.url could have been changed - UploadSaveFile(tmp_filename, tmp_path); } + if( request.session->done_status == Error::ok ) - RedirectTo(request.item); + { + if( !request.IsParam("ckeditor_upload") ) + RedirectTo(request.item); + } } + + // !! dodac usuwanie plikow statycznych przez rm void Content::PostFunUpload() { diff --git a/core/config.cpp b/core/config.cpp index 83b43e4..3c84280 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -109,8 +109,9 @@ void Config::AssignValues() data.log_stdout = false; data.post_file_max = Int("post_file_max", 8388608); // 8 MB - data.static_auth_dir = Text("static_auth_dir"); - data.static_auth_dir_tmp = Text("static_auth_dir_tmp"); + data.static_simplefs_dir = Text("static_simplefs_dir"); + data.static_hashfs_dir = Text("static_hashfs_dir"); + data.static_tmp_dir = Text("static_tmp_dir"); data.templates_dir = Text("templates_dir"); data.templates_dir_default = Text("templates_dir_default"); diff --git a/core/data.h b/core/data.h index 22dbefc..ec049bb 100755 --- a/core/data.h +++ b/core/data.h @@ -112,12 +112,13 @@ public: // 0 - not used int post_file_max; - // directory for static files (for fastcgi authorizer mode) - std::string static_auth_dir; + // directories for static files + std::string static_simplefs_dir; + std::string static_hashfs_dir; - // temporary dir for static content used by upload function - // should be on the same partition as static_auth_dir - std::string static_auth_dir_tmp; + // temporary directory for static content used by the upload function + // should be on the same partition as static_simplefs_dir and static_hashfs_dir + std::string static_tmp_dir; // default locale: en pl std::string locale_str; diff --git a/core/error.h b/core/error.h index 058bd7a..fdf73dd 100755 --- a/core/error.h +++ b/core/error.h @@ -45,6 +45,7 @@ public: unknown_param, mount_unknown, + unknown_filesystem, no_mountpoint, mount_no_param, diff --git a/core/function.h b/core/function.h index b5f4c9e..d364189 100755 --- a/core/function.h +++ b/core/function.h @@ -41,6 +41,7 @@ #define FUN_CHMOD 25 #define FUN_CHOWN 26 #define FUN_CKEDITOR 27 +#define FUN_DOWNLOAD 28 diff --git a/core/functions.cpp b/core/functions.cpp index f768e67..5f26ec4 100755 --- a/core/functions.cpp +++ b/core/functions.cpp @@ -139,6 +139,10 @@ void Functions::ReadFunctions() f.item.url = "ckeditor"; table.insert( std::make_pair(f.item.url, f) ); + f.code = FUN_DOWNLOAD; + f.item.url = "download"; + table.insert( std::make_pair(f.item.url, f) ); + // functions which need more privileges diff --git a/core/misc.cpp b/core/misc.cpp index b631ca8..cf0a6ed 100755 --- a/core/misc.cpp +++ b/core/misc.cpp @@ -586,6 +586,28 @@ bool IsFile(const std::string & file) } +bool CreateDir(const char * dir, int priv) +{ + if( !IsFile(dir) ) + { + if( mkdir(dir, priv) < 0 ) + { + log << log1 << "Can't create a directory on fs: " << dir << logend; + return false; + } + } + +return true; +} + + +bool CreateDir(const std::string & dir, int priv) +{ + return CreateDir(dir.c_str(), priv); +} + + + // if there is not an extension it returns a pointer to the last '\0' character const char * GetFileExt(const char * name) { diff --git a/core/misc.h b/core/misc.h index 7c6db3c..0c13d0b 100755 --- a/core/misc.h +++ b/core/misc.h @@ -64,6 +64,8 @@ bool ValidateEmail(const std::string & email); 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); const char * GetFileExt(const char * name); Item::StaticAuth SelectFileType(const char * file_name); diff --git a/core/mount.cpp b/core/mount.cpp index 901dcf1..8bce1dd 100755 --- a/core/mount.cpp +++ b/core/mount.cpp @@ -16,6 +16,7 @@ Mount::Mount() { type = cms; dir_id = -1; + fs = simplefs; param.resize(par_none); } @@ -49,6 +50,29 @@ return buffer; } +const char * Mount::FsToStr() +{ +static char buffer[30]; + + switch( fs ) + { + case simplefs: + sprintf(buffer, "simplefs"); + break; + + case hashfs: + sprintf(buffer, "hashfs"); + break; + + default: + sprintf(buffer, "unknown"); + break; + } + +return buffer; +} + + Mount::ParamCode Mount::ParseParam(const char * param_name) { @@ -76,7 +100,8 @@ Mount::ParamCode Mount::ParseParam(const char * param_name) { par_createticket_on, "createticket_on" }, { par_only_root_remove, "only_root_remove" }, { par_emacs_on, "emacs_on" }, - { par_mkdir_on, "mkdir_on" } + { par_mkdir_on, "mkdir_on" }, + { par_app, "app" } }; size_t i, len = sizeof(par_name_tab) / sizeof(ParName); diff --git a/core/mount.h b/core/mount.h index f9fa30c..f916c23 100755 --- a/core/mount.h +++ b/core/mount.h @@ -30,6 +30,12 @@ public: ticket }; + enum Fs + { + simplefs = 0, + hashfs + }; + // the first should be with 0 index // the last should be 'none' @@ -53,6 +59,7 @@ public: par_only_root_remove, par_emacs_on, par_mkdir_on, + par_app, par_none }; @@ -74,13 +81,15 @@ public: long dir_id; Type type; - + Fs fs; Mount(); const char * TypeToStr(); + const char * FsToStr(); static ParamCode ParseParam(const char * param); + void ClearParams(); diff --git a/core/mountparser.cpp b/core/mountparser.cpp index c8d91c2..2904834 100755 --- a/core/mountparser.cpp +++ b/core/mountparser.cpp @@ -2,7 +2,7 @@ * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * - * Copyright (c) 2009, Tomasz Sowa + * Copyright (c) 2010, Tomasz Sowa * All rights reserved. * */ @@ -245,6 +245,30 @@ void MountParser::ReadMountPoint() +void MountParser::ReadFs() +{ + ReadWord(temp); + + if( temp == "simplefs" ) + { + mount.fs = Mount::simplefs; + log << log1 << "MP: file system: simplefs" << logend; + } + else + if( temp == "hashfs" ) + { + mount.fs = Mount::hashfs; + log << log1 << "MP: file system: hashfs" << logend; + } + else + { + err = Error::unknown_filesystem; + log << log1 << "MP: unknown filesystem: " << temp << logend; + } +} + + + void MountParser::LogMountParams() { size_t i; @@ -263,6 +287,7 @@ size_t i; } + void MountParser::ReadMountParams() { mount.ClearParams(); @@ -300,6 +325,9 @@ void MountParser::ReadRow(std::map & output) if( err == Error::ok ) ReadMountPoint(); + if( err == Error::ok ) + ReadFs(); + if( err == Error::ok ) ReadMountParams(); diff --git a/core/mountparser.h b/core/mountparser.h index 1942d6d..da0049a 100755 --- a/core/mountparser.h +++ b/core/mountparser.h @@ -2,7 +2,7 @@ * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * - * Copyright (c) 2009, Tomasz Sowa + * Copyright (c) 2010, Tomasz Sowa * All rights reserved. * */ @@ -44,6 +44,7 @@ private: void ReadParam(std::string & res, Mount::ParamArg & args); void ReadMountType(); void ReadMountPoint(); + void ReadFs(); void LogMountParams(); void ReadMountParams(); void ReadRow(std::map & output); diff --git a/core/mounts.cpp b/core/mounts.cpp index 841f6e6..fce305b 100755 --- a/core/mounts.cpp +++ b/core/mounts.cpp @@ -78,7 +78,8 @@ void Mounts::MountCmsForRoot() { Mount mount; mount.type = Mount::cms; - + mount.fs = Mount::simplefs; + Item * proot = data.dirs.GetRootDir(); if( proot ) @@ -112,7 +113,8 @@ std::vector::reverse_iterator i; if( m != mount_tab.end() ) { pmount = &(m->second); - log << log2 << "M: current mount point is: " << pmount->TypeToStr() << logend; + log << log2 << "M: current mount point is: " << pmount->TypeToStr() + << ", fs: " << pmount->FsToStr() << logend; return; } } @@ -120,5 +122,6 @@ std::vector::reverse_iterator i; // if nothing was found // we assume that 'cms' mount point is used MountCmsForRoot(); - log << log2 << "M: current mount point is: cms (default)" << logend; + log << log2 << "M: current mount point is: " << pmount->TypeToStr() << " (default)" + << ", fs: " << pmount->FsToStr() << logend; } diff --git a/core/postmultiparser.cpp b/core/postmultiparser.cpp index 26aa0e1..f9d1505 100755 --- a/core/postmultiparser.cpp +++ b/core/postmultiparser.cpp @@ -433,7 +433,14 @@ void PostMultiParser::CreateTmpFile() { char buf[100]; - sprintf(buf, "%s/winix_%u_%d_%u", data.static_auth_dir_tmp.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand()); + if( data.static_tmp_dir.empty() ) + { + log << log1 << "PMP: static_tmp_dir is not set in the config" << logend; + err = Error::cant_create_file; + return; + } + + sprintf(buf, "%s/winix_%u_%d_%u", data.static_tmp_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand()); tmp_filename_postfix += 1; tmp_file.open(buf, std::ios_base::binary | std::ios_base::out); diff --git a/core/request.cpp b/core/request.cpp index b5a53e4..e59fced 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -103,7 +103,8 @@ void Request::Clear() notify_code = 0; browser_msie = false; redirect_to.clear(); - + x_sendfile.clear(); + send_as_attachment = false; plugin.Call(WINIX_REQUEST_CLEAR); } @@ -409,6 +410,9 @@ void Request::SendSessionCookie() void Request::SendHeaders(bool compressing, Header header) { + if( send_as_attachment ) + FCGX_PutS("Content-Disposition: attachment\r\n", out); + if( !redirect_to.empty() ) { FCGX_PutS("Status: 301 Moved Permanently\r\n", out); @@ -416,6 +420,13 @@ void Request::SendHeaders(bool compressing, Header header) log << log2 << "Redirect to: " << redirect_to << logend; } else + if( !x_sendfile.empty() ) + { + FCGX_FPrintF(out, "X-LIGHTTPD-send-file: %s\r\n", x_sendfile.c_str()); + FCGX_PutS("Status: 200 OK\r\n", out); + log << log2 << "Sending file: " << x_sendfile << logend; + } + else { switch(header) { @@ -490,7 +501,7 @@ void Request::SendAll() { const std::string & source = page.str(); Header header = h_200; -bool compressing = data.compression && role == responder && +bool compressing = data.compression && role == responder && redirect_to.empty() && x_sendfile.empty() && !browser_msie && !browser_konqueror && accept_encoding_parser.AcceptDeflate() && source.size() >= 512; @@ -504,8 +515,8 @@ bool compressing = data.compression && role == responder && SendSessionCookie(); SendHeaders(compressing, header); - if( !redirect_to.empty() ) - // if there is a redirect we do not send a content + if( !redirect_to.empty() || !x_sendfile.empty() ) + // if there is a redirect or a file to send then we do not send a content return; if( header == h_200 && role == authorizer && is_item && item.static_auth != Item::static_none ) @@ -852,8 +863,30 @@ bool Request::CanUseUpload(const Item & item, bool check_root) if( item.type != Item::dir ) return false; + // we must know where to store the file + if( !data.mounts.pmount ) + return false; + + if( data.mounts.pmount->fs == Mount::simplefs && data.static_simplefs_dir.empty() ) + { + log << log1 << "Request: can't use upload function, static_simplefs_dir must be set in the config file" << logend; + return false; + } + + if( data.mounts.pmount->fs == Mount::hashfs && data.static_hashfs_dir.empty() ) + { + log << log1 << "Request: can't use upload function, static_hashfs_dir must be set in the config file" << logend; + return false; + } + + if( data.static_tmp_dir.empty() ) + { + log << log1 << "Request: can't use upload function, static_tmp_dir must be set in the config file" << logend; + return false; + } + if( !check_root && request.session->puser && request.session->puser->super_user ) - // super user can use mkdir everywhere + // super user can use upload everywhere return true; if( !request.HasWriteAccess(item) ) @@ -905,41 +938,105 @@ return false; -// !! dobrac lepsze nazwy dla tych dwoch metod -void Request::MakePath(std::string & path) + +bool Request::MakePathSimpleFs(std::string & path, bool create_dir) { - size_t i; - path = data.static_auth_dir; +size_t i; + + path = data.static_simplefs_dir; + + if( path.empty() ) + { + log << log1 << "Request: static_simplefs_dir is not set in the config file" << logend; + return false; + } // skipping the first - the first is root for(i=1 ; iurl; + + if( create_dir && !CreateDir(path, 0755) ) + return false; } -} - -bool Request::MakeDirsOnFS() -{ - size_t i; - std::string path = data.static_auth_dir; - - // skipping the first - the first is root - for(i=1 ; iurl; - - if( !IsFile(path.c_str()) ) - { - if( mkdir(path.c_str(), 0755) < 0 ) - { - log << log1 << "Request: can't create the directory on fs: " << path << logend; - return false; - } - } - } + path += '/'; return true; } + + + + +// the path depends on id +bool Request::MakePathHashFs(std::string & path, long id, bool create_dir) +{ +char buffer[50]; +char * hash = buffer; + + // get 'id' as hexadecimal + buffer[0] = '0'; + sprintf(buffer+1, "%lx", (unsigned long)id); + + path = data.static_hashfs_dir; + if( path.empty() ) + { + log << log1 << "Request: static_hashfs_dir is not set in the config file" << logend; + return false; + } + + path += '/'; + + // make sure that the length is even + if( (strlen(hash) & 1) != 0 ) + hash = buffer + 1; // the first character was our zero + + // creating dirs without the last part + // the last part is a part of a file (not a directory) + for(size_t i=0 ; hash[i] != 0 ; i+=2) + { + path += hash[i]; + path += hash[i+1]; + + if( hash[i+2] != 0 ) + { + if( create_dir && !CreateDir(path, 0755) ) + return false; + + path += '/'; + } + } + + // one character more to make sure the path is unique + // (we can have a directory without the character) + path += "_"; + +return true; +} + + +// making a complete path to a request.item static file +bool Request::MakePath(std::string & path, bool create_dir) +{ +bool res; + + if( data.mounts.pmount->fs == Mount::hashfs ) + { + res = MakePathHashFs(path, request.item.id, create_dir); + } + else + { + res = MakePathSimpleFs(path, create_dir); + } + + if( res ) + path += request.item.url; + else + path.clear(); + +return res; +} + + + diff --git a/core/request.h b/core/request.h index d363af2..fbdfa67 100755 --- a/core/request.h +++ b/core/request.h @@ -113,6 +113,12 @@ struct Request // if not empty means an address for redirecting to std::string redirect_to; + // send header X-LIGHTTPD-send-file with path to a file + std::string x_sendfile; + + // send as attachment (causing header: content-disposition: attachment) + bool send_as_attachment; + // for debugging void PrintGetTable(); void PrintEnv(); @@ -164,8 +170,9 @@ struct Request bool CanUseBBCode(long user_id); bool CanUseRaw(long user_id); - void MakePath(std::string & path); - bool MakeDirsOnFS(); + bool MakePathSimpleFs(std::string & path, bool create_dir = false); + bool MakePathHashFs(std::string & path, long id, bool create_dir = false); + bool MakePath(std::string & path, bool create_dir = false); private: diff --git a/html/fun_cat.html b/html/fun_cat.html index e2d71c4..79d2b31 100755 --- a/html/fun_cat.html +++ b/html/fun_cat.html @@ -1,28 +1,19 @@ -[is mount_page_is "subject"] - -[is mount_page_is "info"]

[else]

[end][item_subject]

[end] - -[is mount_page_is "info"] - [item_info] -[end] +[is mount_page_is "subject"][is mount_page_is "info"]

[else]

[end][item_subject]

[end] +[is mount_page_is "info"][item_info][end] [if-one item_static_auth_is_image] - [item_subject] + [item_subject] [item_print_content] [else] - [if-one item_static_auth_is_other] - {download}: [item_subject] + [if-no item_static_auth_is_none] + {download}: [item_subject] [item_print_content] [else] - [if-one item_static_auth_is_none] - [item_print_content] - [end] + [item_print_content] [end] [end] - - [include "item_options.html"] diff --git a/html/fun_ckeditor.html b/html/fun_ckeditor.html index 2502716..2133f6c 100755 --- a/html/fun_ckeditor.html +++ b/html/fun_ckeditor.html @@ -34,9 +34,9 @@ [is winix_function_param_is "full"] - + [else] - + [end] [if-no user_logged] diff --git a/html/fun_upload.html b/html/fun_upload.html index 1e227fa..4005d6e 100755 --- a/html/fun_upload.html +++ b/html/fun_upload.html @@ -1,44 +1,49 @@ -

{upload_header}

+[is winix_function_param_is "ckeditor_upload"] + +[else] -[include "err_abuse.html"] - -
-
- {upload_form_legend} - - [is winix_function_param_is "multi"] - -

{upload_form_file_multi}

- - - - - - - [else] - -

{upload_form_file}

- - -

{title}:

- - -

{suggested_url}:

- - - [include "fun_emacs_post.html"] - - [end] - - [if-no user_logged] -

{nick}:

- - -

{rebus_how_is_it} [rebus_question]?

- - [end] - - -
-
+

{upload_header}

+ + [include "err_abuse.html"] + +
+
+ {upload_form_legend} + + [is winix_function_param_is "multi"] + +

{upload_form_file_multi}

+ + + + + + + [else] + +

{upload_form_file}

+ + +

{title}:

+ + +

{suggested_url}:

+ + + [include "fun_emacs_post.html"] + + [end] + + [if-no user_logged] +

{nick}:

+ + +

{rebus_how_is_it} [rebus_question]?

+ + [end] + + +
+
+[end] diff --git a/static/layout1/winix.css b/static/layout1/winix.css index 1f8a6a4..4288949 100755 --- a/static/layout1/winix.css +++ b/static/layout1/winix.css @@ -652,3 +652,7 @@ strong { font-weight: bold; } +img.catimage { +max-width: 600px; +} + diff --git a/templates/Makefile.dep b/templates/Makefile.dep index 9298494..5aa4408 100755 --- a/templates/Makefile.dep +++ b/templates/Makefile.dep @@ -168,6 +168,15 @@ ticket.o: ../core/done.h ../core/thread.h ../core/compress.h ticket.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h ticket.o: ../core/htmlfilter.h ../core/postmultiparser.h ../core/ticket.h ticket.o: ../core/misc.h +upload.o: templates.h patterncacher.h ../core/item.h misc.h localefilter.h +upload.o: ../core/locale.h ../confparser/confparser.h ckeditorgetparser.h +upload.o: ../core/httpsimpleparser.h ../core/log.h ../core/request.h +upload.o: ../core/requesttypes.h ../core/session.h ../core/done.h +upload.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h +upload.o: ../core/rebus.h ../core/function.h ../core/thread.h +upload.o: ../core/compress.h ../core/acceptencodingparser.h +upload.o: ../core/acceptbaseparser.h ../core/htmlfilter.h +upload.o: ../core/postmultiparser.h ../core/ticket.h uptime.o: templates.h patterncacher.h ../core/item.h misc.h localefilter.h uptime.o: ../core/locale.h ../confparser/confparser.h ckeditorgetparser.h uptime.o: ../core/httpsimpleparser.h ../core/log.h ../core/data.h diff --git a/templates/Makefile.o.dep b/templates/Makefile.o.dep index 9ef05fb..87d5a9e 100755 --- a/templates/Makefile.o.dep +++ b/templates/Makefile.o.dep @@ -1 +1 @@ -o = dir.o doc.o done.o item.o last.o localefilter.o ls.o misc.o mount.o patterncacher.o priv.o rebus.o sys.o templates.o thread.o ticket.o uptime.o user.o who.o winix.o +o = dir.o doc.o done.o item.o last.o localefilter.o ls.o misc.o mount.o patterncacher.o priv.o rebus.o sys.o templates.o thread.o ticket.o upload.o uptime.o user.o who.o winix.o diff --git a/templates/item.cpp b/templates/item.cpp index 2dc81b3..2f01aad 100755 --- a/templates/item.cpp +++ b/templates/item.cpp @@ -166,12 +166,6 @@ void item_link(Info & i) } -void item_link_static_auth(Info & i) -{ - HtmlEscape(i.out, data.base_url_static_auth); - item_dir(i); - item_url(i); -} void item_static_auth_is_none(Info & i) @@ -186,12 +180,6 @@ void item_static_auth_is_image(Info & i) } -void item_static_auth_is_other(Info & i) -{ - i.result = request.item.static_auth == Item::static_other; -} - - void item_can_read(Info & i) { i.result = request.HasReadAccess(request.item); diff --git a/templates/ls.cpp b/templates/ls.cpp index 33fc035..cefb152 100755 --- a/templates/ls.cpp +++ b/templates/ls.cpp @@ -17,7 +17,7 @@ namespace TemplatesFunctions { static size_t ls_ckeditor_reqid = 0; - +static int ls_ckeditor_funnum = 0; @@ -33,9 +33,11 @@ void ls_ckeditor_funnum_browse(Info & i) const char * str = request.param_table[request.param_table.size()-1]->c_str() + 1; // the first char is '?' ckeditor_getparser.Parse(str); } + + ls_ckeditor_funnum = ckeditor_getparser.fun_num; } - i.out << ckeditor_getparser.fun_num; + i.out << ls_ckeditor_funnum; } diff --git a/templates/templates.cpp b/templates/templates.cpp index 173b270..d9c0029 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -198,10 +198,8 @@ void Templates::CreateFunctions() functions.Insert("item_url", item_url); functions.Insert("item_url_is", item_url_is); functions.Insert("item_link", item_link); - functions.Insert("item_link_static_auth", item_link_static_auth); functions.Insert("item_static_auth_is_none", item_static_auth_is_none); functions.Insert("item_static_auth_is_image", item_static_auth_is_image); - functions.Insert("item_static_auth_is_other", item_static_auth_is_other); functions.Insert("item_can_read", item_can_read); functions.Insert("item_can_write", item_can_write); @@ -449,6 +447,12 @@ void Templates::CreateFunctions() functions.Insert("rebus_question", rebus_question); + /* + upload + */ + functions.Insert("upload_ckeditor_funnum", upload_ckeditor_funnum); + + /* uptime */ diff --git a/templates/templates.h b/templates/templates.h index c29e4f0..5ddca56 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -112,10 +112,8 @@ namespace TemplatesFunctions void item_url(Info & i); void item_url_is(Info & i); void item_link(Info & i); - void item_link_static_auth(Info & i); void item_static_auth_is_none(Info & i); void item_static_auth_is_image(Info & i); - void item_static_auth_is_other(Info & i); void item_can_read(Info & i); void item_can_write(Info & i); void item_can_remove(Info & i); @@ -356,6 +354,12 @@ namespace TemplatesFunctions void rebus_question(Info & i); + /* + upload + */ + void upload_ckeditor_funnum(Info & i); + + /* uptime */ diff --git a/templates/upload.cpp b/templates/upload.cpp new file mode 100755 index 0000000..1a24e8b --- /dev/null +++ b/templates/upload.cpp @@ -0,0 +1,42 @@ +/* + * This file is a part of CMSLU -- Content Management System like Unix + * and is not publicly distributed + * + * Copyright (c) 2008-2010, Tomasz Sowa + * All rights reserved. + * + */ + +#include +#include "templates.h" +#include "../core/request.h" + + +namespace TemplatesFunctions +{ + +static size_t upload_ckeditor_reqid = 0; +static int upload_fun_num = 0; + + + +void upload_ckeditor_funnum(Info & i) +{ + if( upload_ckeditor_reqid != request.id ) + { + upload_ckeditor_reqid = request.id; + ckeditor_getparser.fun_num = 2; // default if there is a problem with parsing info + + if( !request.param_table.empty() ) + { + const char * str = request.param_table[request.param_table.size()-1]->c_str() + 1; // the first char is '?' + ckeditor_getparser.Parse(str); + } + + upload_fun_num = ckeditor_getparser.fun_num; + } + + i.out << upload_fun_num; +} + +} // namespace