Compare commits

72 Commits

Author SHA1 Message Date
tomasz.sowa 217cf1420b the first part of reimplementing has been done
now we have app object and singletons are only: log logn plugin and app



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@628 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-10 16:12:50 +00:00
tomasz.sowa 6897192364 added: [dir_last_url_is] to templates
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@626 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-02 18:36:17 +00:00
tomasz.sowa 031ace3fe5 changed: the way how plugins work
all your plugin functions can have signature either:
void my_function(PluginInfo & info); or
void my_function();
only the main Init should have:
extern "C" void Init(PluginFunction & info);

added: directory 'plugins' for plugins
added: 'stats' plugin
		  


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@624 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-27 20:41:56 +00:00
tomasz.sowa e4683b9a05 fixed: in htmlfilter: <area> should be treated as single tag
changed: ConfParser is abble to recognize lists


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@623 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-21 17:24:16 +00:00
tomasz.sowa 93da32cfb3 updated to the new version of ezc
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@621 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-19 23:07:34 +00:00
tomasz.sowa 62a0e52092 added: progress bar (image) to tickets table
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@620 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-05 17:22:30 +00:00
tomasz.sowa 262ba10443 small refactoring
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@619 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-05 15:21:06 +00:00
tomasz.sowa 50cb88c5ed added: parameters consist of a name and a value now
sample: /dir/dir2/function/paramname:paramvalue
removed: TemplatesMisc namespace



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@618 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-04 20:27:14 +00:00
tomasz.sowa 76e32703ac fixed: a mount parameter html_template() was not properly read when mountpoints were reloaded
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@617 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-07-01 15:40:18 +00:00
tomasz.sowa d9f5fbaf04 added: "edit" button on threads
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@616 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-30 19:56:32 +00:00
tomasz.sowa 16bb238518 added: bbcode
files: core/bbcodeparser.h core/bbcodeparser.cpp


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@615 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-30 18:42:50 +00:00
tomasz.sowa 759135fd7d struct Item has modification_user_id (long) now
this is the id of a user who has modified the item recently
this is only for information, persmissions don't use it


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@614 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-22 21:09:37 +00:00
tomasz.sowa 56075857f2 debug
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@613 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-22 13:05:49 +00:00
tomasz.sowa 8d3c7500d8 debugging info
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@612 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-22 13:01:56 +00:00
tomasz.sowa 1e3f5e8695 added: mount option: html_template(file.html)
files: indexpatterns.h indexpatterns.cpp
removed: templates/index_root.html
        its content was moved to index.html


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@611 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-21 23:53:19 +00:00
tomasz.sowa 08f5865c72 html templates
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@610 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-21 13:10:53 +00:00
tomasz.sowa ff3c141138 added: a new editor: tinymce (function tinymce)
added: html filter can check orphans: "i", "a", "o" ... in a text


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@607 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-20 22:47:24 +00:00
tomasz.sowa fe31e0e849 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
2010-06-05 19:44:49 +00:00
tomasz.sowa 2a26968c6c added: function cp (only for files)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@605 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-06-03 17:38:18 +00:00
tomasz.sowa fe8774953a changed html templates
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@604 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-05-31 20:42:13 +00:00
tomasz.sowa 4a7f036561 updated to new version of Ezc
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@602 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-05-30 21:07:46 +00:00
tomasz.sowa 612f260938 added function: uname
added function: subject - for changing a subject


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@600 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-05-20 18:28:19 +00:00
tomasz.sowa 2ad666d221 added: sessions data for plugins (plugindata.h plugindata.cpp)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@598 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-05-04 21:58:22 +00:00
tomasz.sowa aff4cc516e added: 'rm' function can remove auth content now
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@597 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-03-15 17:09:45 +00:00
tomasz.sowa 6fbcffe63b 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
2010-03-15 01:47:26 +00:00
tomasz.sowa ebd868fa33 removed: Done class (core/done.h, core/done.cpp)
removed: from Session: done, done_status, timers



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@594 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-28 21:33:06 +00:00
tomasz.sowa 71a63cc70e added: function adduser
changed: errors (removed enum, there are macros now)
added: error messages to locales (winix_err_NN)
removed: templates: err_abuse.html err_others.html


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@593 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-28 00:08:10 +00:00
tomasz.sowa 3702efc5be added: parameter 'l' to 'ls' function
added: Db::ItemQuery struct for querying items
changed: some refactoring (renamed some config variables)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@589 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-22 22:52:09 +00:00
tomasz.sowa 16e51cd4e5 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
2010-02-18 23:30:22 +00:00
tomasz.sowa 87747fab06 added: functions: chmod, chown
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@587 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-16 18:34:41 +00:00
tomasz.sowa 4fe3d4339f added: parameter 'r' to priv function
all directories and files can be changed


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@586 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-16 00:37:00 +00:00
tomasz.sowa a276fb6b79 modified templates
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@585 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-15 18:22:16 +00:00
tomasz.sowa fa8d8f9ea0 fixed: Config::Text() returned a reference to a local variable (std::string)
added: 'static' directory with *.css and images
       we have a default layout
moved: locale from data to templates       
       notification templates have its own locale object
added: reload function reloades locale now too
added: 'nice' form of item_info in templates



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@582 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-15 00:31:14 +00:00
tomasz.sowa c58031cbf4 added static dir
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@581 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-14 14:28:43 +00:00
tomasz.sowa 4aae12fc63 I forgot to commit loadavg.h and loadavg.cpp
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@579 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-13 20:14:44 +00:00
tomasz.sowa 256a8fb5c5 added: calculation of load averages and requests per second
(uptime function shows it)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@577 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-13 20:12:15 +00:00
tomasz.sowa 3c5a7cd664 changed: upload function
select file type by the extension
         param: multi
fixed:   uptime function
         it showed incorrect uptime time (minuts were badly calculated)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@575 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-12 23:16:13 +00:00
tomasz.sowa 796985472a added to config: parameter static_auth_dir_tmp
with a path to directory for tmp files (for upload functino)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@572 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-12 17:05:32 +00:00
tomasz.sowa 7e0014865e added: loggin to upload.cpp
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@571 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-12 16:39:09 +00:00
tomasz.sowa cd74d1887a fixed: sprintf %d in uptime function
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@569 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-11 21:04:53 +00:00
tomasz.sowa adf36e71ce added: functions: ckeditor, uptime
added: for function: login - a html pattern for GET request


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@567 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-11 20:56:52 +00:00
tomasz.sowa fc3c303d30 added: to templates: item_url_is and dir_last_url
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@566 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-08 20:02:16 +00:00
tomasz.sowa 0e50977779 added: 'rm' function can work with tickets
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@565 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-06 14:08:44 +00:00
tomasz.sowa ed9feaf542 changed: log is saved after some requests (config: log_request value) (performance)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@563 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-28 21:09:48 +00:00
tomasz.sowa 09d427b4ba changed: rename cmslu to winix
changed: html templates are a part of winix now
         and the user can provide special html templates for its site
added:   locales
added:   html templates are using HtmlFilter now (locales)
changed: now we have html templates for each language



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@560 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-28 15:39:01 +00:00
tomasz.sowa 5dac8af300 renaming cmslu to winix
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@559 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-26 19:07:40 +00:00
tomasz.sowa 1493a6180a moving html templates to cmslu
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@558 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-26 19:02:21 +00:00
tomasz.sowa 848ddcebd7 fixed: not logged users cannot edit a ticket
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@557 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-25 07:27:18 +00:00
tomasz.sowa 71763d340e fixed: not logged users are not allowed to remove anything
(temporarily - we're waiting for the sticky bit)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@556 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-25 07:04:34 +00:00
tomasz.sowa 89daf6489d added: issues ticket system
added functions: ticket, createticket, editticket
         (there is no 'rm' function working for tickets yet)
changed: mount parser and mount points
         now we have more parameters (arguments in parameters)
some refactoring in functions 'emacs' and 'mkdir'



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@554 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-25 04:52:17 +00:00
tomasz.sowa 356e93914b fixed: there was a wrong template used for 404 header
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@553 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-11 16:41:23 +00:00
tomasz.sowa 5523d0c27a fixed: access to content type should not be checked when generating a page
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@552 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-11 15:09:31 +00:00
tomasz.sowa 590a94523e fixed: content type was always 'formatted text' (in emacs when creating a new item)
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@551 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-11 14:59:19 +00:00
tomasz.sowa 3c95b84633 added: item content type: raw
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@549 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-11 14:47:52 +00:00
tomasz.sowa 59943c87cd added: default values for variables read from the config file
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@547 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-07 14:45:00 +00:00
tomasz.sowa 3f9a46b1f7 added: static_auth_dir to config
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@545 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-06 19:36:29 +00:00
tomasz.sowa 81faca041a added: parser for multipart forms, files: postmultiparser.h postmultiparser.cpp
added: function: upload




git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@543 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-06 19:17:53 +00:00
tomasz.sowa 60fccea703 fixed: dots in url-es (now only one dot is available in the whole name and it cannot be only one dot ".")
added:   cmslu can act as an authorizer (fast cgi authorize role)
added:   Item::static_auth we can have additional static content on the file system
         this content is authorized through cmslu (fastcgi authorizer mode)
changed: some changes in config
changed: the way how the www server is using cmslu
         added new virtuals: static static_auth
changed: cmslu returns correct http headers (200, 404, 403)
changed: in cookie parser: we get the last cookie (if the server has more than one cookie with the same name)



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@540 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-30 20:46:12 +00:00
tomasz.sowa 118bf1fc65 added: exception for the Konqueror browser
it has a problem with deflate compression


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@539 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-19 19:46:15 +00:00
tomasz.sowa ce7ae3edd4 changed: notification times
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@536 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-09 00:52:00 +00:00
tomasz.sowa 717eb526fb * added: class HTMLFilter
files: htmlfilter.h htmlfilter.cpp
         this is an html filter used to make the html output looking better
         this is a very lightweight filter
         (without using any dynamic memory - some memory is allocated only at the beginning - in ctors)
         this filter has O(n) complexity over the whole html string
* added: antyspamming method
         if the POST request is sent too fast after the GET
         it is treated as a spam
         only for no logged users and only in 'emacs' and 'createthread' functions
       


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@534 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-09 00:42:40 +00:00
tomasz.sowa 9241fddb1e small changes in Makefile
now the binaries are in local 'bin' directory
(use make install)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@532 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-04 05:03:44 +00:00
tomasz.sowa 2dff0bed72 changed: SessionParser::ReadLong() can read negative values
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@531 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-21 00:08:08 +00:00
tomasz.sowa 4827c116f0 added: 'remember me' flag when logging
added: the session file
       sessions can still be available between starting and stopping the cmslu system


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@529 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-20 23:09:52 +00:00
tomasz.sowa 848afac803 removed: hidden variable 'old_url' in emacs template
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@527 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-18 01:58:38 +00:00
tomasz.sowa 13b0204427 I have forgotten to add templates/rebus.cpp to the repository
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@525 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-17 01:07:29 +00:00
tomasz.sowa dc5f002de3 refactoring
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@523 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-17 01:04:01 +00:00
tomasz.sowa 2ca44ec361 added: Rebus
(when no logged user wants to send a message then he is asked a question)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@521 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-16 23:36:38 +00:00
tomasz.sowa c62d48160a fixed: the core didn't test for special folder when system was running
(now mkdir addes correctly special folders)
added: function 'reload'
       param: 'templates' - reloading templates


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@519 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-16 17:43:23 +00:00
tomasz.sowa 9129f1b82a added: mount points are read from db: /etc/fstab
changed: mount points parser allows empty lines (with some white characters)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@518 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-15 23:55:11 +00:00
tomasz.sowa 378cfc0c3d added: plugin mechanism
files: core/plugin.h core/plugin.cpp core/pluginmsg.h
added: directory 'main' with main.cpp (moved from 'core' directory)
changed: the way of building
       nearly everything is in cmslu.so
       only main() is in cmslu and is dynamically linked with cmslu.so



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@516 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-13 20:40:11 +00:00
tomasz.sowa 7db71d43e0 added: acceptbaseparser.h acceptbaseparser.cpp
class AcceptBaseParser for parsing http accept* headers
added: acceptencodingparser.h
       class AcceptEncodingParser for parsing HTTP_ACCEPT_ENCODING header
added: compresion only when HTTP_ACCEPT_ENCODING has 'deflate'
       and the browser is not the Internet Explorer


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@515 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-08 17:59:10 +00:00
293 changed files with 24435 additions and 6282 deletions
+33 -13
View File
@@ -2,33 +2,44 @@
ifndef CXX
CXX = g++
export CXX
endif
ifndef CXXFLAGS
CXXFLAGS = -Wall -pedantic -g -I/usr/local/include -L/usr/local/lib
export CXXFLAGS
#CXXFLAGS = -fPIC -Wall -pedantic -O2 -I/usr/local/include -I/home/tomek/roboczy/winix -I/home/tomek/roboczy/ezc/src -L/usr/local/lib -DEZC_USE_WINIX_LOGGER
CXXFLAGS = -fPIC -Wall -pedantic -O0 -g -I/usr/local/include -I/home/tomek/roboczy/winix -I/home/tomek/roboczy/ezc/src -L/usr/local/lib -DEZC_USE_WINIX_LOGGER
endif
all: cmslu.a
export CXX
export CXXFLAGS
cmslu.a: FORCE
all: winix
winix: FORCE
@cd core ; $(MAKE) -e
@cd content ; $(MAKE) -e
@cd confparser ; $(MAKE) -e
@cd functions ; $(MAKE) -e
@cd templates ; $(MAKE) -e
@cd templatesnotify ; $(MAKE) -e
ar rcs cmslu.a core/*.o content/*.o templates/*.o templatesnotify/*.o confparser/*.o
@cd plugins/stats ; $(MAKE) -e
@cd ../ezc/src ; $(MAKE) -e
$(CXX) -shared -o winix.so $(CXXFLAGS) core/*.o functions/*.o templates/*.o templatesnotify/*.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
clean:
@cd core ; $(MAKE) -e clean
@cd content ; $(MAKE) -e clean
@cd confparser ; $(MAKE) -e clean
@cd functions ; $(MAKE) -e clean
@cd templates ; $(MAKE) -e clean
@cd templatesnotify ; $(MAKE) -e clean
rm -f cmslu.a
@cd plugins/stats ; $(MAKE) -e clean
@cd ../ezc/src ; $(MAKE) -e clean
@cd main ; $(MAKE) -e clean
rm -f winix.so
rm -f winix
FORCE:
@@ -36,7 +47,16 @@ FORCE:
depend:
@cd core ; $(MAKE) -e depend
@cd content ; $(MAKE) -e depend
@cd confparser ; $(MAKE) -e depend
@cd functions ; $(MAKE) -e depend
@cd templates ; $(MAKE) -e depend
@cd templatesnotify ; $(MAKE) -e depend
@cd plugins/stats ; $(MAKE) -e depend
@cd ../ezc/src ; $(MAKE) -e depend
@cd main ; $(MAKE) -e depend
#install: all
# mkdir -p bin
# rm -f bin/winix.so
# rm -f bin/winix
# cp winix.so bin/
# cp winix bin/
-30
View File
@@ -1,30 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfileappcontent
#define headerfileappcontent
namespace AppContent
{
#ifdef APPPREPARE
void PrepareApp();
#endif
}
#endif
-31
View File
@@ -1,31 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfileapptemplates
#define headerfileapptemplates
#include "../../ezc/src/ezc.h"
namespace AppTemplateFunctions
{
//void CreateAppFunctions(Ezc::Functions & functions);
void ReadAppPatterns();
void CreateAppFunctions(Ezc::Functions & functions);
Ezc::Pattern * GetAppPattern();
}
#endif
+1 -1
View File
@@ -12,7 +12,7 @@ all: $(o)
depend:
makedepend $(DEPMACROS) -Y. -f- *.cpp > Makefile.dep
makedepend -Y. -I.. -I../../ezc/src -f- *.cpp > Makefile.dep
echo -n "o = " > Makefile.o.dep
ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep
-2
View File
@@ -1,3 +1 @@
# DO NOT DELETE
confparser.o: confparser.h
+1 -1
View File
@@ -1 +1 @@
o = confparser.o
o =
-208
View File
@@ -1,208 +0,0 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#include "confparser.h"
ConfParser::ConfParser()
{
separator = '=';
commentary = '#';
}
ConfParser::Status ConfParser::Parse(const char * file_name)
{
file.open( file_name );
if( !file )
return cant_open_file;
line = 1;
table.clear();
ReadChar();
status = ParseFile();
file.close();
return status;
}
ConfParser::Status ConfParser::ParseFile()
{
while( lastc != -1 )
{
if( ReadVariable() )
{
if( lastc != separator )
return syntax_error;
ReadChar(); // skipping separator
if( !ReadValue() )
return syntax_error;
table.insert( std::make_pair(variable, value) );
}
if( lastc == commentary )
SkipLine();
if( lastc != -1 && lastc != '\n' )
return syntax_error;
ReadChar(); // skipping '\n' if was
}
return ok;
}
bool ConfParser::IsVariableChar(int c)
{
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9') ||
c=='.' || c==',' || c=='_' )
return true;
return false;
}
bool ConfParser::IsValueSimpleChar(int c)
{
if( c==-1 || c=='\n' || IsWhite(c) || c==commentary )
return false;
return true;
}
bool ConfParser::ReadVariable()
{
variable.clear();
SkipWhite();
while( IsVariableChar(lastc) )
{
variable += lastc;
ReadChar();
}
SkipWhite();
return !variable.empty();
}
bool ConfParser::ReadValue()
{
value.clear();
SkipWhite();
if( lastc == '"' )
// quoted value
return ReadValueQuoted();
else
return ReadValueSimple();
}
bool ConfParser::ReadValueQuoted()
{
ReadChar(); // skipping the first quote
while( lastc != '\n' && lastc != '"' && lastc != -1 )
{
if( lastc == '\\' )
ReadChar();
value += lastc;
ReadChar();
}
if( lastc != '"' )
return false;
ReadChar(); // skipping the last quote
SkipWhite();
return true;
}
bool ConfParser::ReadValueSimple()
{
while( IsValueSimpleChar(lastc) )
{
value += lastc;
ReadChar();
}
SkipWhite();
return true;
}
int ConfParser::ReadChar()
{
lastc = file.get();
if( lastc == '\n' )
++line;
return lastc;
}
bool ConfParser::IsWhite(int c)
{
if( c==' ' || c=='\t' || c==13 )
return true;
return false;
}
void ConfParser::SkipWhite()
{
while( IsWhite(lastc) )
ReadChar();
}
void ConfParser::SkipLine()
{
while( lastc != -1 && lastc != '\n' )
ReadChar();
}
-74
View File
@@ -1,74 +0,0 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfileconfparser
#define headerfileconfparser
#include <fstream>
#include <string>
#include <map>
class ConfParser
{
public:
enum Status { ok, cant_open_file, syntax_error };
ConfParser();
Status Parse(const char * file_name);
// last status
Status status;
// line in which there is a syntax_error
int line;
typedef std::map<std::string, std::string> Table;
Table table;
private:
// last read variable, value
std::string variable, value;
// separator between a variable and a value, usually '='
int separator;
// commentary char
int commentary;
// last read char
int lastc;
// current file
std::ifstream file;
Status ParseFile();
bool IsVariableChar(int c);
bool IsValueSimpleChar(int c);
bool ReadVariable();
bool ReadValue();
bool ReadValueQuoted();
bool ReadValueSimple();
int ReadChar();
bool IsWhite(int c);
void SkipWhite();
void SkipLine();
};
#endif
-131
View File
@@ -1,131 +0,0 @@
# DO NOT DELETE
cat.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
cat.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
cat.o: ../core/request.h ../core/requesttypes.h ../core/session.h
cat.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
cat.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
cat.o: ../core/error.h
content.o: content.h ../core/item.h ../templates/templates.h
content.o: ../../ezc/src/ezc.h ../templates/patterncacher.h
content.o: ../app/templates.h ../core/thread.h ../core/request.h
content.o: ../core/requesttypes.h ../core/session.h ../core/done.h
content.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
content.o: ../core/function.h ../core/thread.h ../core/compress.h
content.o: ../core/error.h ../core/db.h ../core/group.h
content.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
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 ../app/content.h ../core/misc.h
createthread.o: content.h ../core/item.h ../templates/templates.h
createthread.o: ../../ezc/src/ezc.h ../templates/patterncacher.h
createthread.o: ../app/templates.h ../core/thread.h ../core/request.h
createthread.o: ../core/requesttypes.h ../core/session.h ../core/done.h
createthread.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
createthread.o: ../core/function.h ../core/thread.h ../core/compress.h
createthread.o: ../core/error.h ../core/db.h ../core/group.h
createthread.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/mount.h
createthread.o: ../core/data.h ../core/dirs.h ../core/users.h
createthread.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
createthread.o: ../core/mounts.h ../core/mount.h
default.o: content.h ../core/item.h ../templates/templates.h
default.o: ../../ezc/src/ezc.h ../templates/patterncacher.h
default.o: ../app/templates.h ../core/thread.h ../core/request.h
default.o: ../core/requesttypes.h ../core/session.h ../core/done.h
default.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
default.o: ../core/function.h ../core/thread.h ../core/compress.h
default.o: ../core/error.h ../core/db.h ../core/group.h
default.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
default.o: ../core/dirs.h ../core/users.h ../core/groups.h
default.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
default.o: ../core/mount.h
emacs.o: content.h ../core/item.h ../templates/templates.h
emacs.o: ../../ezc/src/ezc.h ../templates/patterncacher.h ../app/templates.h
emacs.o: ../core/thread.h ../core/request.h ../core/requesttypes.h
emacs.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
emacs.o: ../core/log.h ../core/user.h ../core/function.h ../core/thread.h
emacs.o: ../core/compress.h ../core/error.h ../core/db.h ../core/group.h
emacs.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
emacs.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
emacs.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
emacs.o: ../core/notify.h ../templatesnotify/templatesnotify.h
emacs.o: ../core/mount.h
last.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
last.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
login.o: content.h ../core/item.h ../templates/templates.h
login.o: ../../ezc/src/ezc.h ../templates/patterncacher.h ../app/templates.h
login.o: ../core/thread.h ../core/request.h ../core/requesttypes.h
login.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
login.o: ../core/log.h ../core/user.h ../core/function.h ../core/thread.h
login.o: ../core/compress.h ../core/error.h ../core/db.h ../core/group.h
login.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
login.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
login.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
logout.o: content.h ../core/item.h ../templates/templates.h
logout.o: ../../ezc/src/ezc.h ../templates/patterncacher.h ../app/templates.h
logout.o: ../core/thread.h ../core/request.h ../core/requesttypes.h
logout.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
logout.o: ../core/log.h ../core/user.h ../core/function.h ../core/thread.h
logout.o: ../core/compress.h ../core/data.h ../core/dirs.h
logout.o: ../core/dircontainer.h ../core/users.h ../core/ugcontainer.h
logout.o: ../core/groups.h ../core/group.h ../core/functions.h
logout.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
ls.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
ls.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
ls.o: ../core/request.h ../core/requesttypes.h ../core/session.h
ls.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
ls.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
ls.o: ../core/db.h ../core/group.h ../core/dircontainer.h
ls.o: ../core/ugcontainer.h
mkdir.o: content.h ../core/item.h ../templates/templates.h
mkdir.o: ../../ezc/src/ezc.h ../templates/patterncacher.h ../app/templates.h
mkdir.o: ../core/thread.h ../core/request.h ../core/requesttypes.h
mkdir.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
mkdir.o: ../core/log.h ../core/user.h ../core/function.h ../core/thread.h
mkdir.o: ../core/compress.h ../core/error.h ../core/db.h ../core/group.h
mkdir.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
mkdir.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
mkdir.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
mkdir.o: ../core/notify.h ../templatesnotify/templatesnotify.h
mkdir.o: ../core/mount.h
node.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
node.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
node.o: ../core/request.h ../core/requesttypes.h ../core/session.h
node.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
node.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
priv.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
priv.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
priv.o: ../core/request.h ../core/requesttypes.h ../core/session.h
priv.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
priv.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
priv.o: ../core/error.h ../core/db.h ../core/group.h ../core/dircontainer.h
priv.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
priv.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
priv.o: ../core/mounts.h ../core/mount.h
rm.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
rm.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
rm.o: ../core/request.h ../core/requesttypes.h ../core/session.h
rm.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
rm.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
rm.o: ../core/error.h ../core/db.h ../core/group.h ../core/dircontainer.h
rm.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
rm.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
rm.o: ../core/mounts.h ../core/mount.h
run.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
run.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
run.o: ../core/request.h ../core/requesttypes.h ../core/session.h
run.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
run.o: ../core/user.h ../core/function.h ../core/thread.h ../core/compress.h
run.o: ../core/error.h
thread.o: content.h ../core/item.h ../templates/templates.h
thread.o: ../../ezc/src/ezc.h ../templates/patterncacher.h ../app/templates.h
thread.o: ../core/thread.h ../core/request.h ../core/requesttypes.h
thread.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
thread.o: ../core/log.h ../core/user.h ../core/function.h ../core/thread.h
thread.o: ../core/compress.h ../core/db.h ../core/group.h
thread.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
thread.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
thread.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
thread.o: ../core/mount.h
who.o: content.h ../core/item.h ../templates/templates.h ../../ezc/src/ezc.h
who.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
-1
View File
@@ -1 +0,0 @@
o = cat.o content.o createthread.o default.o emacs.o last.o login.o logout.o ls.o mkdir.o node.o priv.o rm.o run.o thread.o who.o
-34
View File
@@ -1,34 +0,0 @@
/*
* 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/error.h"
void Content::FunCat()
{
if( !request.is_item )
{
log << log1 << "Content: Cat function requires an item" << logend;
request.status = Error::item_required;
return;
}
if( !request.HasReadAccess(request.item) )
{
request.status = Error::permision_denied;
return;
}
}
-373
View File
@@ -1,373 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
#include "../app/content.h"
#include "../core/misc.h"
bool Content::Init()
{
templates.Read();
return true;
}
bool Content::DirsHaveReadExecPerm()
{
std::vector<Item*>::iterator i;
for(i = request.dir_table.begin() ; i!=request.dir_table.end() ; ++i)
{
if( !request.HasReadExecAccess(**i) )
return false;
}
return true;
}
void Content::SetDefaultFunctionForFile()
{
if( request.HasReadExecAccess(request.item) )
request.pfunction = data.functions.GetFunction(FUN_RUN);
else
request.pfunction = data.functions.GetFunction(FUN_CAT);
if( request.pfunction )
log << log3 << "Content: default function: " << request.pfunction->item.url << logend;
}
void Content::SetDefaultFunctionForDir()
{
long default_item = request.dir_table.back()->default_item;
if( default_item != -1 )
{
request.session->IncrementTimersIfExist();
log << log3 << "Content: Default item: id: " << default_item << logend;
RedirectTo(default_item);
return;
}
if( data.mounts.CurrentMountType() == Mount::thread )
{
request.pfunction = data.functions.GetFunction(FUN_THREAD);
if( request.pfunction )
log << log3 << "Content: default function: " << request.pfunction->item.url << logend;
}
else
{
// cms
request.pfunction = data.functions.GetFunction(FUN_LS);
if( request.pfunction )
log << log3 << "Content: default function: " << request.pfunction->item.url << logend;
}
}
void Content::SetDefaultFunction()
{
if( request.is_item )
{
SetDefaultFunctionForFile();
}
else
{
SetDefaultFunctionForDir();
}
}
void Content::MakeStandardFunction()
{
if( !request.pfunction )
SetDefaultFunction();
if( request.result == Request::redirect )
return;
if( !request.pfunction )
{
log << log1 << "Content: no function (neither cat nor ls)" << logend;
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_CREATETHREAD )
FunCreateThread();
else
request.status = Error::permision_denied;
}
void Content::MakePost()
{
if( !request.pfunction )
SetDefaultFunction();
if( !request.pfunction )
{
log << log1 << "Content: MakePost: no function" << logend;
request.status = Error::no_function;
return;
}
switch( request.pfunction->code )
{
case FUN_EMACS:
PostFunEmacs();
break;
case FUN_MKDIR:
PostFunMkdir();
break;
case FUN_DEFAULT:
PostFunDefault();
break;
case FUN_PRIV:
PostFunPriv();
break;
case FUN_LOGIN:
PostFunLogin();
break;
case FUN_CREATETHREAD:
PostFunCreateThread();
break;
default:
log << log1 << "Content: unknown post function" << logend;
// !! moze daj tutaj tez access denied?
break;
}
}
void Content::Make()
{
if( request.dir_table.empty() )
{
log << log1 << "Content: there is no a root dir (dir_table is empty)" << logend;
return;
}
// request.status can be changed by function_parser
if( request.status == Error::ok )
{
if( DirsHaveReadExecPerm() )
{
#ifdef APPPREPARE
AppContent::PrepareApp();
#endif
if( request.method == Request::post )
MakePost();
if( request.result == Request::redirect )
return;
if( request.status == Error::ok )
MakeStandardFunction();
}
else
request.status = Error::permision_denied;
}
if( request.result == Request::redirect )
return;
if( request.dir_table.empty() )
{
log << log1 << "Content: there is no a root dir (dir_table is empty -- after calling some standard functions)" << logend;
return;
}
templates.Generate();
//request.PrintGetTable();
//request.PrintEnv();
//request.PrintIn();
}
// !! mozna zrobic jakas obsluge kiedy nie mozemy sie redirectnac, np gdy wystapil blad
// !! moze zwracac jakas wartosc?
void Content::RedirectTo(const Item & item)
{
std::string path;
request.result = Request::redirect;
request.str = data.base_url;
if( item.type == Item::dir )
{
// item_id is pointing to a directory
data.dirs.MakePath(item.id, path);
request.str += path;
}
else
{
if( !data.dirs.MakePath(item.parent_id, path) )
log << log1 << "Content: Can't redirect: no dirs for item id: " << item.id << logend;
request.str += path;
request.str += item.url;
}
}
void Content::RedirectTo(long item_id)
{
std::string path;
Item * pdir;
request.result = Request::redirect;
request.str = data.base_url;
pdir = data.dirs.GetDir(item_id);
if( pdir )
{
// item_id is pointing to a directory
data.dirs.MakePath(pdir->id, path);
request.str += path;
}
else
{
// !! zrobic nowy interfejs
// !! GetItem pozamieniac na GetFile
db.GetItem(request.item_table, item_id);
if( !request.item_table.empty() )
{
if( !data.dirs.MakePath(request.item_table[0].parent_id, path) )
log << log1 << "Content: Can't redirect: no dirs for item id: " << request.item_table[0].id << ", requested directory id: " << request.item_table[0].parent_id << logend;
request.str += path + request.item_table[0].url;
}
else
{
log << log1 << "Content: Can't redirect: no such item: id: " << item_id << logend;
}
}
}
void Content::ReadAdditionalInfo()
{
if( request.dir_table.empty() )
return;
if( data.mounts.CurrentMountType() == Mount::thread )
{
if( db.GetThreadByDirId(request.dir_table.back()->id, request.thread) == Error::ok )
request.is_thread = true;
}
}
void Content::PrepareUrl(Item & item)
{
TrimWhite(item.url);
if( item.url.empty() )
item.url = item.subject; // if the subject is empty then the url will be corrected by CorrectUrl()
CorrectUrl(item);
if( data.functions.GetFunction(item.url) )
{
// the name provided by an user is the same as a name of a function
// we add one underscore character at the beginning
// names of functions should not begin with an underscore '_'
// and we can simply add one '_' at the beginning
// and the name will be unique
item.url.insert(item.url.begin(), '_');
}
}
-93
View File
@@ -1,93 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucontentcontent
#define headerfilecmslucontentcontent
#include <cstdlib>
#include <fcgiapp.h>
#include <ctime>
#include "../core/item.h"
#include "../templates/templates.h"
#include "../core/thread.h"
class Content
{
Templates templates;
void PrepareUrl(Item & item);
void SetDefaultFunctionForFile();
void SetDefaultFunctionForDir();
void SetDefaultFunction();
bool DirsHaveReadExecPerm();
void MakeStandardFunction();
void MakePost();
void FunCat();
void FunLogout();
void FunLs();
void FunEmacs();
void FunPriv();
void FunRmDirRecursive();
void FunRmDir();
void FunRm();
void FunNode();
void FunMkdir();
void FunDefault();
void FunRun();
void FunWho();
void FunLast();
static bool FunThreadSort(const Thread & t1, const Thread & t2);
void FunThread();
void FunCreateThread();
void PostFunLogin();
void PostFunEmacsAdd();
void PostFunEmacsEdit(bool with_url);
void PostFunEmacs();
void PostFunMkdir(bool add_to_dir_table = false, int mask = 0755 );
long PostFunDefaultParsePath();
void PostFunDefault();
void PostFunPriv();
void PostFunPriv(Item & item);
bool FunCreateThreadCheckAccess();
void PostFunCreateThread();
void RedirectTo(const Item & item);
void RedirectTo(long item_id);
public:
bool Init();
void ReadAdditionalInfo();
void Make();
};
#endif
-82
View File
@@ -1,82 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/mount.h"
#include "../core/data.h"
bool Content::FunCreateThreadCheckAccess()
{
if( !request.CanCreateThread() )
{
request.status = Error::permision_denied;
return false;
}
return true;
}
void Content::PostFunCreateThread()
{
if( !FunCreateThreadCheckAccess() )
return;
request.post_table.insert( std::make_pair(std::string("url"), std::string()) ); // !! tymczasowo, zrobic aby mkdir i emacs nie rzucaly wyjatkiem gdy nie ma url zdefiniowanego
request.thread.parent_id = request.dir_table.back()->id;
PostFunMkdir(true, 0777); // !! tymczasowo 777 aby wszyscy mogli wysylac posty
if( request.session->done_status == Error::ok )
{
PostFunEmacs();
if( request.session->done_status == Error::ok )
{
request.thread.dir_id = request.dir_table.back()->id;
request.thread.closed = false;
request.thread.items = 1;
request.thread.last_item = request.item; // set by PostFunEmacs()
request.session->done_status = db.AddThread(request.thread);
}
if( request.session->done_status == Error::ok )
{
request.session->done = Done::added_thread;
RedirectTo(*request.dir_table.back());
}
}
}
void Content::FunCreateThread()
{
FunCreateThreadCheckAccess();
TemplatesFunctions::thread_show_edit_subject_var = true; // !! tymczasowe rozwiazanie
}
-113
View File
@@ -1,113 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
long Content::PostFunDefaultParsePath()
{
Item * pdir, * pdir2;
long defaultid = -1;
std::string & path = request.PostVar("defaultitem");
if( !path.empty() )
{
std::string dir, file;
Dirs::SplitPath(path, dir, file);
pdir = data.dirs.GetDir(dir);
if( !pdir )
throw Error(Error::incorrect_dir);
if( file.empty() )
{
defaultid = pdir->id;
}
else
{
// checking whether the file is a directory too (the method SplitPath does not check it)
pdir2 = data.dirs.GetDir(file, pdir->id);
if( !pdir2 )
{
defaultid = db.GetFileId(pdir->id, file);
if( defaultid == -1 )
throw Error(Error::db_no_item);
}
else
{
// file is a directory
defaultid = pdir2->id;
}
}
}
return defaultid;
}
void Content::PostFunDefault()
{
request.session->done = Done::defaulted_dir;
if( !request.HasWriteAccess(*request.dir_table.back()) )
{
request.status = Error::permision_denied;
return;
}
try
{
long defaultid = PostFunDefaultParsePath();
request.session->done_status = db.EditDefaultItem(request.dir_table.back()->id, defaultid);
if( request.session->done_status == Error::ok )
request.dir_table.back()->default_item = defaultid;
}
catch(const Error & e)
{
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
RedirectTo(*request.dir_table.back());
else
log << log1 << "Content: PostFunDefaultItem: Error: " << request.session->done_status << logend;
}
void Content::FunDefault()
{
if( !request.HasWriteAccess(*request.dir_table.back()) )
{
request.status = Error::permision_denied;
return;
}
}
-184
View File
@@ -1,184 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
#include "../core/notify.h"
void Content::PostFunEmacsAdd()
{
request.session->done = Done::added_item;
request.is_item = true;
if( request.session->puser )
{
request.item.user_id = request.session->puser->id;
}
else
{
request.item.user_id = -1;
request.item.guest_name = request.PostVar("guestname");
}
request.item.group_id = -1;
request.item.privileges = 0644; // !! tymczasowo, bedzie uzyte umask
request.item.parent_id = request.dir_table.back()->id;
request.item.type = Item::file;
request.item.content_type = 1;// !! tymczasowo formatted text
// dates (creation and modification) is set by request.item.Clear() at the beginning
if( !request.CanUseEmacs(*request.dir_table.back() ) )
throw Error(Error::permision_denied);
request.session->done_status = db.AddItem(request.item);
if( request.session->done_status == Error::ok )
{
request.notify_code |= CMSLU_NOTIFY_ITEM_ADD;
}
}
void Content::PostFunEmacsEdit(bool with_url)
{
request.session->done = Done::edited_item;
if( !request.CanUseEmacs(request.item) )
throw Error(Error::permision_denied);
time_t t = std::time(0);
request.item.date_modification = *std::localtime( &t );
request.session->done_status = db.EditItemById(request.item, with_url);
if( request.session->done_status == Error::ok )
{
TemplatesFunctions::pattern_cacher.UpdatePattern(request.item);
request.notify_code |= CMSLU_NOTIFY_ITEM_EDIT;
}
}
void Content::PostFunEmacs()
{
bool adding = true;
if( request.is_item )
adding = false;
try
{
// these old values are ignored (if exists)
//!! tymczasowo, zabezpieczenie przed pustym url-em
try {
request.item.url = request.PostVar("url");
request.item.subject = request.PostVar("subject");
}
catch(...)
{
}
if( request.item.subject.empty() )
request.item.subject = request.dir_table.back()->subject;
// !! dodac skladanie tytuly z ostatniego katalogu i liczby okreslajacej ile jest elementow w srodku
// !! nie bedzie obciazany modul wyszukujacy bardzo
////////
request.item.content = request.PostVar("content");
bool with_url = false;
if( !request.is_item || request.PostVar("old_url") != request.item.url )
with_url = true;
PrepareUrl(request.item);
if( adding )
PostFunEmacsAdd();
else
PostFunEmacsEdit(with_url);
}
catch(const Error & e)
{
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
{
request.session->item = request.item;
if( data.mounts.CurrentMountType() == Mount::thread )
{
if( adding )
db.EditThreadAddItem(request.dir_table.back()->id, request.item.id);
// request.session->item = request.item;
// request.session->done_timer = 2;
RedirectTo(*request.dir_table.back());
}
else
{
request.session->item = request.item;
request.session->done_timer = 2;
RedirectTo(request.item);
}
}
else
{
log << log1 << "Content: PostFunEmacs: Error: " << request.session->done_status << logend;
}
}
void Content::FunEmacs()
{
if( !request.is_item )
{
// adding a new item
if( !request.CanUseEmacs(*request.dir_table.back()) )
request.status = Error::permision_denied;
return;
}
// editing an existing item
if( !request.CanUseEmacs(request.item) )
{
request.status = Error::permision_denied;
return;
}
}
-24
View File
@@ -1,24 +0,0 @@
/*
* 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"
void Content::FunLast()
{
}
-69
View File
@@ -1,69 +0,0 @@
/*
* 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 <arpa/inet.h>
#include "content.h"
#include "../core/request.h"
#include "../core/error.h"
#include "../core/db.h"
#include "../core/data.h"
/*
void Content::PostFunLoginAddLast()
{
}
*/
void Content::PostFunLogin()
{
try
{
std::string & login = request.PostVar("login");
std::string & pass = request.PostVar("password");
long user_id;
if( db.CheckUser(login, pass, user_id) )
{
request.session->puser = data.users.GetUser(user_id);
if( !request.session->puser )
{
log << log1 << "Content: user: " << login << " is in the database but is not in data.users" << logend;
return;
}
data.last.UserLogin(user_id, login, inet_addr(request.env_remote_addr), request.session->id);
log << log2 << "User " << login << " (id: " << user_id << ") logged" << logend;
}
// !! zglosic komunikat o nie poprawnym logowaniu
}
catch(const Error &)
{
}
if( request.is_item )
RedirectTo(request.item);
else
RedirectTo(*request.dir_table.back());
}
-50
View File
@@ -1,50 +0,0 @@
/*
* 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::FunLogout()
{
if( request.session->puser )
{
log << log2 << "User: " << request.session->puser->name << ", id: " << request.session->puser->id << " logged out" << logend;
data.last.UserLogout(request.session->puser->id, request.session->id);
request.session->puser = 0;
}
request.result = Request::redirect;
std::string path;
data.dirs.MakePath(request.dir_table.back()->id, path);
request.str = data.base_url + path;
if( request.is_item )
request.str += request.item.url;
request.session->done = Done::loggedout;
request.session->done_timer = 2;
}
-35
View File
@@ -1,35 +0,0 @@
/*
* 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/db.h"
void Content::FunLs()
{
if( request.is_item )
{
// we're showing only the item
request.item_table.push_back( request.item );
return;
}
// we're reading only files here
db.GetItems(request.item_table, request.dir_table.back()->id, Item::file, false, false, true);
}
-100
View File
@@ -1,100 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
#include "../core/notify.h"
void Content::PostFunMkdir(bool add_to_dir_table, int mask)
{
if( !request.CanUseMkdir(*request.dir_table.back()) )
{
request.status = Error::permision_denied;
return;
}
Item item;
request.session->done = Done::added_dir;
try
{
item.type = Item::dir;
item.subject = request.PostVar("subject");
item.url = request.PostVar("url");
item.parent_id = request.dir_table.back()->id;
if( request.session->puser )
{
item.user_id = request.session->puser->id;
}
else
{
item.user_id = -1;
item.guest_name = request.PostVar("guestname");
}
item.group_id = -1;
item.privileges = mask;
item.default_item = -1;
// dates (creation and modification) is set by the Item() constructor
PrepareUrl(item);
request.session->done_status = db.AddItem(item);
}
catch(const Error & e)
{
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
{
Item * pdir = data.dirs.AddDir(item);
if( add_to_dir_table )
request.dir_table.push_back(pdir);
request.session->item = item;
request.session->done_timer = 2;
request.notify_code |= CMSLU_NOTIFY_DIR_ADD;
RedirectTo(item);
}
else
{
log << log1 << "Content: PostFunMkdir: Error: " << request.session->done_status << logend;
}
}
void Content::FunMkdir()
{
if( !request.CanUseMkdir(*request.dir_table.back()) )
{
request.status = Error::permision_denied;
return;
}
}
-30
View File
@@ -1,30 +0,0 @@
/*
* 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"
void Content::FunNode()
{
if( request.param_table.empty() )
{
//request.status = Error
//!!zglosic 404
return;
}
long id = atol( request.param_table[0]->c_str() );
RedirectTo(id);
}
-83
View File
@@ -1,83 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
void Content::PostFunPriv(Item & item)
{
try
{
long user_id = data.users.GetUserId( request.PostVar("user") );
long group_id = data.groups.GetGroupId( request.PostVar("group") );
int privileges = strtol( request.PostVar("privileges").c_str() , 0, 8);
if( user_id==item.user_id && group_id==item.group_id && privileges==item.privileges )
{
log << log3 << "Content: PostFunPriv: nothing to change" << logend;
throw Error(Error::ok);
}
if( !request.CanChangeUser(item, user_id) )
throw Error(Error::cant_change_user);
if( !request.CanChangeGroup(item, group_id) )
throw Error(Error::cant_change_group);
if( !request.CanChangePrivileges(item, privileges) )
throw Error(Error::cant_change_privileges);
item.user_id = user_id;
item.group_id = group_id;
item.privileges = privileges;
request.session->done = Done::privileged_item;
request.session->done_status = db.EditPrivById(item, item.id);
}
catch(const Error & e)
{
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
{
request.session->item = item;
request.session->done_timer = 2;
RedirectTo(item);
}
else
{
log << log1 << "Content: PostFunPriv: Error: " << static_cast<int>(request.session->done_status) << logend;
}
request.status = request.session->done_status;
}
void Content::PostFunPriv()
{
if( request.is_item )
PostFunPriv( request.item );
else
PostFunPriv( *request.dir_table.back() );
}
void Content::FunPriv()
{
// we do not check permissions here
// permissions depends on the user, group, and privileges
}
-124
View File
@@ -1,124 +0,0 @@
/*
* 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/error.h"
#include "../core/db.h"
#include "../core/data.h"
void Content::FunRmDirRecursive()
{
data.dirs.MakePath(request.dir_table.back()->id, request.session->dir_old);
// this method deletes recursively all directories
data.dirs.DeleteDir(request.dir_table.back()->id);
request.dir_table.erase(--request.dir_table.end());
if( request.dir_table.empty() )
{
// we have deleted the root directory
data.dirs.CheckRootDir();
Item * proot = data.dirs.GetRootDir();
if( proot )
request.dir_table.push_back(proot);
else
// there is no a root dir
// CheckRootDir() didn't add the root dir (probably problem with the database)
// make sure that Content::Make() will check that the dir_table is empty and returns
return;
}
request.session->done = Done::deleted_dir;
request.session->done_status = Error::ok;
request.session->done_timer = 2;
// redirect to the last valid directory
RedirectTo(**(--request.dir_table.end()));
}
void Content::FunRmDir()
{
if( !request.CanRemove(*request.dir_table.back()) )
{
request.status = Error::permision_denied;
return;
}
if( request.param_table.empty() )
request.status = Error::permision_denied;
else
if( request.IsParam("confirm") )
return;
else
if( request.IsParam("r") )
FunRmDirRecursive();
else
request.status = Error::unknown_param;
}
void Content::FunRm()
{
if( !request.is_item )
{
FunRmDir();
return;
}
if( !request.CanRemove(request.item) )
{
request.status = Error::permision_denied;
return;
}
if( request.param_table.empty() )
{
// we'll put some information about the deleted item (on the next page)
request.session->item = request.item;
// !! zmienic interfejs dla db.DelItem
if( db.DelItem( request.item ) )
{
request.session->done_status = Error::ok;
log << log2 << "Content: deleted item: subject: " << request.item.subject << ", id: " << request.item.id << logend;
TemplatesFunctions::pattern_cacher.DeletePattern(request.item);
if( data.mounts.CurrentMountType() == Mount::thread )
db.EditThreadRemoveItem(request.item.parent_id);
}
else
{
request.session->done_status = Error::db_no_item;
}
request.session->done = Done::deleted_item;
RedirectTo(*request.dir_table.back());
request.session->done_timer = 2;
}
else
{
if( !request.IsParam("confirm") )
//request.result = Request::err404;
request.status = Error::unknown_param;
}
}
-35
View File
@@ -1,35 +0,0 @@
/*
* 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/error.h"
void Content::FunRun()
{
if( !request.is_item )
{
log << log1 << "Content: Run function requires an item" << logend;
request.status = Error::item_required;
return;
}
if( !request.HasReadExecAccess(request.item) )
{
request.status = Error::permision_denied;
return;
}
}
-49
View File
@@ -1,49 +0,0 @@
/*
* 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/db.h"
#include "../core/data.h"
#include "../core/mount.h"
#include <algorithm>
bool Content::FunThreadSort(const Thread & t1, const Thread & t2)
{
Item * pdir1 = data.dirs.GetDir(t1.dir_id);
Item * pdir2 = data.dirs.GetDir(t2.dir_id);
if( !pdir1 || !pdir2 )
return false;
time_t time1 = mktime(&pdir1->date_creation);
time_t time2 = mktime(&pdir2->date_creation);
return time1 > time2;
}
void Content::FunThread()
{
bool asc = true;
if( data.mounts.CurrentMountIsParam(Mount::desc) )
asc = false;
db.GetItems(request.item_table, request.dir_table.back()->id, Item::file, true, true, asc);
db.GetThreads(request.dir_table.back()->id, request.thread_tab);
std::sort(request.thread_tab.begin(), request.thread_tab.end(), FunThreadSort);
}
-24
View File
@@ -1,24 +0,0 @@
/*
* 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"
void Content::FunWho()
{
}
+1 -1
View File
@@ -12,7 +12,7 @@ all: $(o)
depend:
makedepend $(DEPMACROS) -Y. -f- *.cpp > Makefile.dep
makedepend -Y. -I.. -I../../ezc/src -f- *.cpp > Makefile.dep
echo -n "o = " > Makefile.o.dep
ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep
+249 -71
View File
@@ -1,83 +1,261 @@
# DO NOT DELETE
Kopia config.o: ../core/log.h ../core/request.h requesttypes.h session.h
Kopia config.o: item.h error.h log.h user.h plugindata.h rebus.h thread.h
Kopia config.o: compress.h acceptencodingparser.h acceptbaseparser.h
Kopia config.o: htmlfilter.h postmultiparser.h config.h confparser.h ticket.h
Kopia config.o: ../core/config.h ../core/db.h group.h dircontainer.h
Kopia config.o: ugcontainer.h
acceptbaseparser.o: acceptbaseparser.h
app.o: app.h config.h confparser.h system.h dirs.h item.h dircontainer.h db.h
app.o: user.h group.h thread.h error.h log.h ugcontainer.h ticket.h request.h
app.o: requesttypes.h session.h plugindata.h rebus.h compress.h
app.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
app.o: postmultiparser.h mounts.h mount.h users.h lastcontainer.h groups.h
app.o: loadavg.h sessionmanager.h sessioncontainer.h notify.h
app.o: ../templatesnotify/templatesnotify.h ../../ezc/src/ezc.h
app.o: ../core/mount.h ../core/locale.h ../core/config.h ../templates/misc.h
app.o: ../templates/localefilter.h ../core/locale.h ../functions/functions.h
app.o: ../functions/functionbase.h ../core/item.h ../core/db.h
app.o: ../core/request.h ../core/system.h ../core/notify.h
app.o: ../functions/functionparser.h ../functions/adduser.h
app.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
app.o: ../functions/chown.h ../functions/cp.h ../functions/createthread.h
app.o: ../functions/createticket.h ../functions/default.h
app.o: ../functions/download.h ../functions/editticket.h ../functions/emacs.h
app.o: ../functions/last.h ../functions/login.h ../functions/logout.h
app.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
app.o: ../functions/node.h ../functions/priv.h ../functions/reload.h
app.o: ../functions/rm.h ../functions/run.h ../functions/subject.h
app.o: ../functions/funthread.h ../core/thread.h ../functions/funticket.h
app.o: ../functions/uname.h ../functions/upload.h ../functions/who.h
app.o: ../templates/templates.h ../templates/patterncacher.h ../core/item.h
app.o: misc.h ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
app.o: ../core/log.h ../templates/indexpatterns.h ../core/sessionmanager.h
app.o: plugin.h pluginmsg.h
bbcodeparser.o: bbcodeparser.h htmlfilter.h
compress.o: compress.h log.h
config.o: config.h ../confparser/confparser.h log.h data.h dirs.h item.h
config.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h
config.o: functions.h function.h lastcontainer.h mounts.h mount.h
data.o: data.h dirs.h item.h dircontainer.h users.h user.h ugcontainer.h
data.o: log.h groups.h group.h functions.h function.h lastcontainer.h
data.o: mounts.h mount.h
config.o: config.h confparser.h log.h plugin.h pluginmsg.h plugindata.h
config.o: request.h requesttypes.h session.h item.h error.h user.h rebus.h
config.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
config.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
config.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h users.h
config.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
config.o: sessioncontainer.h ../functions/functions.h
config.o: ../functions/functionbase.h ../core/item.h ../core/db.h
config.o: ../core/request.h ../core/config.h ../core/system.h
config.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
config.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
config.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
config.o: ../functions/createthread.h ../functions/createticket.h
config.o: ../functions/default.h ../functions/download.h
config.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
config.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
config.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
config.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
config.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
config.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
config.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
config.o: ../templates/patterncacher.h ../core/item.h misc.h
config.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
config.o: ../core/log.h ../templates/indexpatterns.h
config.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
config.o: ../core/sessionmanager.h
confparser.o: confparser.h misc.h item.h
db.o: db.h item.h user.h group.h thread.h error.h log.h dircontainer.h
db.o: ugcontainer.h misc.h
db.o: ugcontainer.h ticket.h misc.h
db_itemcolumns.o: db.h item.h user.h group.h thread.h error.h log.h
db_itemcolumns.o: dircontainer.h ugcontainer.h
db_itemcolumns.o: dircontainer.h ugcontainer.h ticket.h
dircontainer.o: dircontainer.h item.h log.h
dirs.o: dirs.h item.h dircontainer.h error.h log.h db.h user.h group.h
dirs.o: thread.h ugcontainer.h data.h users.h groups.h functions.h function.h
dirs.o: lastcontainer.h mounts.h mount.h
done.o: done.h
error.o: error.h log.h
function.o: function.h item.h
functioncodeparser.o: functioncodeparser.h item.h function.h log.h
functionparser.o: functionparser.h requesttypes.h ../app/content.h log.h
functionparser.o: item.h error.h data.h dirs.h dircontainer.h users.h user.h
functionparser.o: ugcontainer.h groups.h group.h functions.h function.h
functionparser.o: lastcontainer.h mounts.h mount.h db.h thread.h request.h
functionparser.o: session.h done.h compress.h
functions.o: functions.h function.h item.h
dirs.o: dirs.h item.h dircontainer.h db.h user.h group.h thread.h error.h
dirs.o: log.h ugcontainer.h ticket.h request.h requesttypes.h session.h
dirs.o: plugindata.h rebus.h compress.h acceptencodingparser.h
dirs.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
dirs.o: confparser.h
groups.o: groups.h group.h ugcontainer.h log.h db.h item.h user.h thread.h
groups.o: error.h dircontainer.h
groups.o: error.h dircontainer.h ticket.h
htmlfilter.o: htmlfilter.h
httpsimpleparser.o: httpsimpleparser.h
lastcontainer.o: lastcontainer.h log.h
loadavg.o: loadavg.h log.h
locale.o: locale.h confparser.h log.h
log.o: log.h
main.o: requestcontroller.h ../content/content.h ../core/item.h
main.o: ../templates/templates.h ../../ezc/src/ezc.h
main.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
main.o: sessionmanager.h sessioncontainer.h session.h done.h item.h error.h
main.o: log.h user.h functionparser.h requesttypes.h ../app/content.h data.h
main.o: dirs.h dircontainer.h users.h ugcontainer.h groups.h group.h
main.o: functions.h function.h lastcontainer.h mounts.h mount.h request.h
main.o: thread.h compress.h db.h config.h ../confparser/confparser.h notify.h
main.o: ../templatesnotify/templatesnotify.h ../core/mount.h
misc.o: misc.h item.h log.h
mount.o: mount.h
mountparser.o: mountparser.h mount.h item.h error.h log.h data.h dirs.h
mountparser.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h
mountparser.o: functions.h function.h lastcontainer.h mounts.h
mounts.o: mounts.h mount.h data.h dirs.h item.h dircontainer.h users.h user.h
mounts.o: ugcontainer.h log.h groups.h group.h functions.h function.h
mounts.o: lastcontainer.h request.h requesttypes.h session.h done.h error.h
mounts.o: thread.h compress.h mountparser.h
notify.o: log.h notify.h ../templatesnotify/templatesnotify.h ../core/mount.h
notify.o: ../../ezc/src/ezc.h data.h dirs.h item.h dircontainer.h users.h
notify.o: user.h ugcontainer.h groups.h group.h functions.h function.h
notify.o: lastcontainer.h mounts.h mount.h misc.h request.h requesttypes.h
notify.o: session.h done.h error.h thread.h compress.h
request.o: request.h requesttypes.h session.h done.h item.h error.h log.h
request.o: user.h function.h thread.h compress.h getparser.h
request.o: httpsimpleparser.h postparser.h cookieparser.h data.h dirs.h
request.o: dircontainer.h users.h ugcontainer.h groups.h group.h functions.h
request.o: lastcontainer.h mounts.h mount.h
requestcontroller.o: requestcontroller.h ../content/content.h ../core/item.h
requestcontroller.o: ../templates/templates.h ../../ezc/src/ezc.h
requestcontroller.o: ../templates/patterncacher.h ../app/templates.h
requestcontroller.o: ../core/thread.h sessionmanager.h sessioncontainer.h
requestcontroller.o: session.h done.h item.h error.h log.h user.h
requestcontroller.o: functionparser.h requesttypes.h ../app/content.h data.h
requestcontroller.o: dirs.h dircontainer.h users.h ugcontainer.h groups.h
requestcontroller.o: group.h functions.h function.h lastcontainer.h mounts.h
requestcontroller.o: mount.h request.h thread.h compress.h postparser.h
requestcontroller.o: httpsimpleparser.h cookieparser.h notify.h
requestcontroller.o: ../templatesnotify/templatesnotify.h ../core/mount.h
session.o: session.h done.h item.h error.h log.h user.h
sessioncontainer.o: sessioncontainer.h session.h done.h item.h error.h log.h
sessioncontainer.o: user.h data.h dirs.h dircontainer.h users.h ugcontainer.h
sessioncontainer.o: groups.h group.h functions.h function.h lastcontainer.h
sessioncontainer.o: mounts.h mount.h
sessionmanager.o: sessionmanager.h sessioncontainer.h session.h done.h item.h
sessionmanager.o: error.h log.h user.h request.h requesttypes.h function.h
sessionmanager.o: thread.h compress.h data.h dirs.h dircontainer.h users.h
sessionmanager.o: ugcontainer.h groups.h group.h functions.h lastcontainer.h
sessionmanager.o: mounts.h mount.h
users.o: users.h user.h ugcontainer.h log.h db.h item.h group.h thread.h
users.o: error.h dircontainer.h
mountparser.o: mountparser.h mount.h item.h error.h log.h dirs.h
mountparser.o: dircontainer.h db.h user.h group.h thread.h ugcontainer.h
mountparser.o: ticket.h request.h requesttypes.h session.h plugindata.h
mountparser.o: rebus.h compress.h acceptencodingparser.h acceptbaseparser.h
mountparser.o: htmlfilter.h postmultiparser.h config.h confparser.h misc.h
mounts.o: mounts.h mount.h error.h log.h dirs.h item.h dircontainer.h db.h
mounts.o: user.h group.h thread.h ugcontainer.h ticket.h request.h
mounts.o: requesttypes.h session.h plugindata.h rebus.h compress.h
mounts.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
mounts.o: postmultiparser.h config.h confparser.h mountparser.h
notify.o: log.h notify.h ../templatesnotify/templatesnotify.h
notify.o: ../../ezc/src/ezc.h ../core/mount.h ../core/locale.h confparser.h
notify.o: ../core/config.h ../templates/misc.h ../templates/localefilter.h
notify.o: ../core/locale.h request.h requesttypes.h session.h item.h error.h
notify.o: user.h plugindata.h rebus.h thread.h compress.h
notify.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
notify.o: postmultiparser.h config.h ticket.h system.h dirs.h dircontainer.h
notify.o: db.h group.h ugcontainer.h mounts.h mount.h users.h lastcontainer.h
notify.o: groups.h loadavg.h misc.h
plugin.o: plugin.h pluginmsg.h log.h plugindata.h config.h confparser.h
plugin.o: request.h requesttypes.h session.h item.h error.h user.h rebus.h
plugin.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
plugin.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
plugin.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h users.h
plugin.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
plugin.o: sessioncontainer.h ../functions/functions.h
plugin.o: ../functions/functionbase.h ../core/item.h ../core/db.h
plugin.o: ../core/request.h ../core/config.h ../core/system.h
plugin.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
plugin.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
plugin.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
plugin.o: ../functions/createthread.h ../functions/createticket.h
plugin.o: ../functions/default.h ../functions/download.h
plugin.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
plugin.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
plugin.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
plugin.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
plugin.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
plugin.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
plugin.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
plugin.o: ../templates/patterncacher.h ../core/item.h misc.h
plugin.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
plugin.o: ../core/log.h ../templates/indexpatterns.h
plugin.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
plugin.o: ../core/sessionmanager.h
plugindata.o: plugindata.h plugin.h pluginmsg.h log.h config.h confparser.h
plugindata.o: request.h requesttypes.h session.h item.h error.h user.h
plugindata.o: rebus.h thread.h compress.h acceptencodingparser.h
plugindata.o: acceptbaseparser.h htmlfilter.h postmultiparser.h ticket.h
plugindata.o: system.h dirs.h dircontainer.h db.h group.h ugcontainer.h
plugindata.o: mounts.h mount.h users.h lastcontainer.h groups.h loadavg.h
plugindata.o: sessionmanager.h sessioncontainer.h ../functions/functions.h
plugindata.o: ../functions/functionbase.h ../core/item.h ../core/db.h
plugindata.o: ../core/request.h ../core/config.h ../core/system.h
plugindata.o: ../core/notify.h ../../ezc/src/ezc.h
plugindata.o: ../functions/functionparser.h ../functions/adduser.h
plugindata.o: ../functions/cat.h ../functions/chmod.h
plugindata.o: ../functions/privchanger.h ../functions/chown.h
plugindata.o: ../functions/cp.h ../functions/createthread.h
plugindata.o: ../functions/createticket.h ../functions/default.h
plugindata.o: ../functions/download.h ../functions/editticket.h
plugindata.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
plugindata.o: ../functions/logout.h ../functions/ls.h ../functions/mkdir.h
plugindata.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
plugindata.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
plugindata.o: ../functions/subject.h ../functions/funthread.h
plugindata.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
plugindata.o: ../functions/upload.h ../functions/who.h
plugindata.o: ../templates/templates.h ../templates/patterncacher.h
plugindata.o: ../core/item.h misc.h ../templates/ckeditorgetparser.h
plugindata.o: ../core/httpsimpleparser.h ../core/log.h
plugindata.o: ../templates/indexpatterns.h ../templates/localefilter.h
plugindata.o: ../core/locale.h ../core/locale.h ../core/sessionmanager.h
postmultiparser.o: postmultiparser.h error.h log.h requesttypes.h config.h
postmultiparser.o: confparser.h
rebus.o: log.h rebus.h misc.h item.h request.h requesttypes.h session.h
rebus.o: error.h user.h plugindata.h thread.h compress.h
rebus.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
rebus.o: postmultiparser.h config.h confparser.h ticket.h
request.o: request.h requesttypes.h session.h item.h error.h log.h user.h
request.o: plugindata.h rebus.h thread.h compress.h acceptencodingparser.h
request.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
request.o: confparser.h ticket.h getparser.h httpsimpleparser.h postparser.h
request.o: cookieparser.h plugin.h pluginmsg.h system.h dirs.h dircontainer.h
request.o: db.h group.h ugcontainer.h mounts.h mount.h users.h
request.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
request.o: sessioncontainer.h ../functions/functions.h
request.o: ../functions/functionbase.h ../core/item.h ../core/db.h
request.o: ../core/request.h ../core/config.h ../core/system.h
request.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
request.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
request.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
request.o: ../functions/createthread.h ../functions/createticket.h
request.o: ../functions/default.h ../functions/download.h
request.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
request.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
request.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
request.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
request.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
request.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
request.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
request.o: ../templates/patterncacher.h ../core/item.h misc.h
request.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
request.o: ../core/log.h ../templates/indexpatterns.h
request.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
request.o: ../core/sessionmanager.h ../functions/functionbase.h
session.o: session.h item.h error.h log.h user.h plugindata.h rebus.h
sessioncontainer.o: sessioncontainer.h session.h item.h error.h log.h user.h
sessioncontainer.o: plugindata.h rebus.h lastcontainer.h
sessionmanager.o: sessionmanager.h sessioncontainer.h session.h item.h
sessionmanager.o: error.h log.h user.h plugindata.h rebus.h lastcontainer.h
sessionmanager.o: config.h confparser.h request.h requesttypes.h thread.h
sessionmanager.o: compress.h acceptencodingparser.h acceptbaseparser.h
sessionmanager.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
sessionmanager.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h
sessionmanager.o: users.h groups.h loadavg.h sessionparser.h plugin.h
sessionmanager.o: pluginmsg.h ../functions/functions.h
sessionmanager.o: ../functions/functionbase.h ../core/item.h ../core/db.h
sessionmanager.o: ../core/request.h ../core/config.h ../core/system.h
sessionmanager.o: ../core/notify.h ../../ezc/src/ezc.h
sessionmanager.o: ../functions/functionparser.h ../functions/adduser.h
sessionmanager.o: ../functions/cat.h ../functions/chmod.h
sessionmanager.o: ../functions/privchanger.h ../functions/chown.h
sessionmanager.o: ../functions/cp.h ../functions/createthread.h
sessionmanager.o: ../functions/createticket.h ../functions/default.h
sessionmanager.o: ../functions/download.h ../functions/editticket.h
sessionmanager.o: ../functions/emacs.h ../functions/last.h
sessionmanager.o: ../functions/login.h ../functions/logout.h
sessionmanager.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
sessionmanager.o: ../functions/node.h ../functions/priv.h
sessionmanager.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
sessionmanager.o: ../functions/subject.h ../functions/funthread.h
sessionmanager.o: ../core/thread.h ../functions/funticket.h
sessionmanager.o: ../functions/uname.h ../functions/upload.h
sessionmanager.o: ../functions/who.h ../templates/templates.h
sessionmanager.o: ../templates/patterncacher.h ../core/item.h misc.h
sessionmanager.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
sessionmanager.o: ../core/log.h ../templates/indexpatterns.h
sessionmanager.o: ../templates/localefilter.h ../core/locale.h
sessionmanager.o: ../core/locale.h ../core/sessionmanager.h
sessionparser.o: sessionparser.h session.h item.h error.h log.h user.h
sessionparser.o: plugindata.h rebus.h sessioncontainer.h lastcontainer.h
sessionparser.o: users.h ugcontainer.h request.h requesttypes.h thread.h
sessionparser.o: compress.h acceptencodingparser.h acceptbaseparser.h
sessionparser.o: htmlfilter.h postmultiparser.h config.h confparser.h
sessionparser.o: ticket.h db.h group.h dircontainer.h
system.o: system.h dirs.h item.h dircontainer.h db.h user.h group.h thread.h
system.o: error.h log.h ugcontainer.h ticket.h request.h requesttypes.h
system.o: session.h plugindata.h rebus.h compress.h acceptencodingparser.h
system.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
system.o: confparser.h mounts.h mount.h users.h lastcontainer.h groups.h
system.o: loadavg.h misc.h notify.h ../templatesnotify/templatesnotify.h
system.o: ../../ezc/src/ezc.h ../core/mount.h ../core/locale.h
system.o: ../core/config.h ../templates/misc.h ../templates/localefilter.h
system.o: ../core/locale.h ../functions/functions.h
system.o: ../functions/functionbase.h ../core/item.h ../core/db.h
system.o: ../core/request.h ../core/system.h ../core/notify.h
system.o: ../functions/functionparser.h ../functions/adduser.h
system.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
system.o: ../functions/chown.h ../functions/cp.h ../functions/createthread.h
system.o: ../functions/createticket.h ../functions/default.h
system.o: ../functions/download.h ../functions/editticket.h
system.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
system.o: ../functions/logout.h ../functions/ls.h ../functions/mkdir.h
system.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
system.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
system.o: ../functions/subject.h ../functions/funthread.h ../core/thread.h
system.o: ../functions/funticket.h ../functions/uname.h ../functions/upload.h
system.o: ../functions/who.h ../templates/templates.h
system.o: ../templates/patterncacher.h ../core/item.h
system.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
system.o: ../core/log.h ../templates/indexpatterns.h ../core/sessionmanager.h
users.o: users.h user.h ugcontainer.h log.h lastcontainer.h request.h
users.o: requesttypes.h session.h item.h error.h plugindata.h rebus.h
users.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
users.o: htmlfilter.h postmultiparser.h config.h confparser.h ticket.h db.h
users.o: group.h dircontainer.h
+1 -1
View File
@@ -1 +1 @@
o = compress.o config.o data.o db.o db_itemcolumns.o dircontainer.o dirs.o done.o error.o function.o functioncodeparser.o functionparser.o functions.o groups.o httpsimpleparser.o lastcontainer.o log.o main.o misc.o mount.o mountparser.o mounts.o notify.o request.o requestcontroller.o session.o sessioncontainer.o sessionmanager.o users.o
o = Kopia config.o acceptbaseparser.o app.o bbcodeparser.o compress.o config.o confparser.o db.o db_itemcolumns.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o lastcontainer.o loadavg.o locale.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o plugindata.o postmultiparser.o rebus.o request.o session.o sessioncontainer.o sessionmanager.o sessionparser.o system.o users.o
+113
View File
@@ -0,0 +1,113 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "acceptbaseparser.h"
bool AcceptBaseParser::IsWhite(int c)
{
if( c==' ' || c=='\t' )
return true;
return false;
}
void AcceptBaseParser::SkipWhite()
{
while( IsWhite(*text) )
++text;
}
void AcceptBaseParser::RemoveWhiteFromEnd(std::string & str)
{
if( str.empty() )
return;
size_t i = str.size() - 1;
for( ; i!=0 && IsWhite(str[i]) ; --i);
if( !IsWhite(str[i]) )
++i;
if( i < str.size() )
str.erase(i); // erasing until the end of the string
}
void AcceptBaseParser::ReadParameter()
{
param.clear();
SkipWhite();
while( *text!=0 && *text!=',' && *text!=';' )
{
param += *text;
++text;
}
RemoveWhiteFromEnd(param);
}
void AcceptBaseParser::ReadQ()
{
q = 1.0;
SkipWhite();
if( *text != ';' )
return;
++text; // skipping a semicolon
while( *text!=0 && *text!=',' && *text!='=' )
// skipping until ',' or '='
++text;
if( *text==0 || *text==',' )
return;
++text; // skipping '='
SkipWhite();
q = strtod(text, (char**)&text);
}
void AcceptBaseParser::SkipParam()
{
SkipWhite();
if( *text == ',' )
++text;
}
void AcceptBaseParser::Parse(const char * str)
{
text = str;
Init();
while( *text != 0 )
{
ReadParameter();
ReadQ();
SkipParam();
Param(param, q);
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreacceptbaseparser
#define headerfilecmslucoreacceptbaseparser
#include <string>
// sample (you must create your own class derived from this one):
// object.Parse(" text/html ; , ; q = 45, application / xhtml+xml ; q = 0.4 , application/xml ; q = 0.9 , */* ; q = 0.8 ");
class AcceptBaseParser
{
public:
void Parse(const char * str);
private:
virtual void Init() {} ;
virtual void Param(const std::string & param, double q) = 0;
bool IsWhite(int c);
void SkipWhite();
void RemoveWhiteFromEnd(std::string & str);
void ReadParameter();
void ReadQ();
void SkipParam();
const char * text;
std::string param;
double q;
};
#endif
+49
View File
@@ -0,0 +1,49 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreacceptencodingparser
#define headerfilecmslucoreacceptencodingparser
#include "acceptbaseparser.h"
#include "log.h"
class AcceptEncodingParser : public AcceptBaseParser
{
public:
bool AcceptDeflate()
{
return accept_deflate;
}
private:
void Init()
{
accept_deflate = false;
}
void Param(const std::string & param, double q)
{
if( param=="deflate" && q!=0 )
{
accept_deflate = true;
log << log3 << "AEP: accept deflate" << logend;
}
}
bool accept_deflate;
};
#endif
Executable
+398
View File
@@ -0,0 +1,398 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "app.h"
#include "plugin.h"
App::App()
{
stdout_is_closed = false;
last_sessions_save = time(0);
plugin.SetDb(&db);
plugin.SetConfig(&config);
plugin.SetRequest(&request);
plugin.SetSystem(&system);
plugin.SetFunctions(&functions);
plugin.SetTemplates(&templates);
plugin.SetSessionManager(&session_manager);
request.SetConfig(&config);
functions.SetConfig(&config);
functions.SetRequest(&request);
functions.SetDb(&db);
functions.SetSystem(&system);
functions.SetTemplates(&templates);
functions.SetNotify(&notify);
system.SetConfig(&config);
system.SetRequest(&request);
system.SetDb(&db);
system.SetFunctions(&functions); // !! czy model musi cos wiedziec o funkcjach?
system.SetTemplates(&templates);
templates_notify.SetConfig(&config);
notify.SetRequest(&request);
notify.SetConfig(&config);
notify.SetSystem(&system);
notify.SetTemplatesNotify(&templates_notify);
templates.SetConfig(&config);
templates.SetRequest(&request);
templates.SetDb(&db);
templates.SetSystem(&system);
templates.SetFunctions(&functions);
templates.SetSessionManager(&session_manager);
session_manager.SetLastContainer(&system.users.last);
session_manager.SetConfig(&config);
session_manager.SetRequest(&request);
session_manager.SetSystem(&system);
}
bool App::CreateFCGISocket()
{
const char * sock = config.fcgi_socket.c_str();
unlink(sock);
int s = FCGX_OpenSocket(sock, 10);
if( s < 0 )
{
log << log1 << "An error during creating a socket" << logend;
return false;
}
chmod(sock, config.fcgi_socket_chmod);
passwd * pw = getpwnam(config.fcgi_socket_user.c_str());
if( !pw )
{
log << log1 << "There is no user: " << config.fcgi_socket_user << logend;
return false;
}
group * gr = getgrnam(config.fcgi_socket_group.c_str());
if( !gr )
{
log << log1 << "There is no group: " << config.fcgi_socket_group << logend;
return false;
}
chown(sock, pw->pw_uid, gr->gr_gid);
if( setuid(pw->pw_uid) < 0 )
{
log << log1 << "I can't change the user into: " << config.fcgi_socket_user << logend;
return false;
}
/*
if( setgid(gr->gr_gid) < 0 )
{
int e = errno;
log << log1 << "I can't change the group into: " << config.fcgi_socket_group << " " << gr->gr_gid << logend;
log << log1 << "errno: " << e << logend;
return false;
}
*/
dup2(s, 0);
return true;
}
bool App::Init()
{
request.Init();
if( !CreateFCGISocket() )
return false;
system.Init();
functions.Create();
// !! teraz mamy dwa katalogi z templetami
// !! o co chodzilo?
if( !notify.Init() )
return false;
templates.ReadIndexFileNames();
templates.ReadTemplates();
templates.CreateFunctions();
session_manager.LoadSessions();
return true;
}
void App::Close()
{
session_manager.SaveSessions();
session_manager.DeleteAllPluginsData();
}
bool App::BaseUrlRedirect()
{
if( request.role == Request::responder )
{
if( config.base_url_http_host.empty() )
return false;
if( config.base_url_http_host == request.env_http_host )
return false;
request.redirect_to = config.base_url + request.env_request_uri;
}
else
{
// authorizer
if( config.base_url_auth_http_host.empty() )
return false;
if( config.base_url_auth_http_host == request.env_http_host )
return false;
request.redirect_to = config.base_url_auth + request.env_request_uri;
}
log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend;
return true;
}
void App::ProcessRequest()
{
request.Clear();
request.Read();
// when BaseUrlRedirect() return true we didn't have to set everything in request.Read()
// in the future request.Read() can be split and at the beginning only environment variables will be read
// and then BaseUrlRedirect() will be called (for performance)
if( !BaseUrlRedirect() )
{
session_manager.DeleteOldSessions();
session_manager.SetSession(); // set request.session as well
// !! tutaj dodac to ustawianie request.session
functions.Parse();
system.mounts.CalcCurMount();
ReadAdditionalInfo();
Make();
}
request.SendAll(); // !! czemu request sam sie chce wyslac? wrzucic to tutaj do app
notify.ItemChanged(request.notify_code);
}
void App::Start()
{
while( FCGX_Accept(&request.in, &request.out, &request.err, &request.env) == 0 )
{
system.load_avg.StartRequest();
log << log2 << "---------------------------------------------------------------------------------" << logend;
try
{
ProcessRequest();
}
catch(const std::logic_error & e)
{
log << log1 << "std logic exception: " << e.what() << logend;
}
catch(const std::exception & e)
{
log << log1 << "std exception: " << e.what() << logend;
}
catch(const Error & e)
{
log << log1 << "exception: Error: " << e << logend;
}
catch(...)
{
log << log1 << "uncaught unknown exception" << logend;
}
SaveSessionsIfNeeded();
// !! this should be immediately after FCGX_Accept() but signals don't want to break FCGX_Accept
//if( signal_hup )
if( false )
{
log << logsave;
FCGX_Finish();
return;
}
request.ClearPostFileTmp();
system.load_avg.StopRequest();
log << logsave;
}
}
void App::SaveSessionsIfNeeded()
{
time_t t = time(0);
if( last_sessions_save + 86400 > t )
return;
// saving once a day for safety
last_sessions_save = t;
session_manager.SaveSessions();
}
// !! zmienic na lepsza nazwe
void App::MakePage()
{
bool sent = false;
if( !request.redirect_to.empty() || !request.x_sendfile.empty() )
return;
if( request.is_item && request.item.auth == Item::auth_none &&
request.item.content_type == Item::ct_raw && request.status == WINIX_ERR_OK && request.pfunction )
{
if( request.pfunction->fun.url == "cat" )
{
request.page << request.item.content;
sent = true;
}
else
if( request.pfunction->fun.url == "run" )
{
templates.GenerateRunRaw();
sent = true;
}
}
if( !sent )
{
templates.Generate();
}
}
void App::Make()
{
if( request.dir_table.empty() )
{
log << log1 << "Content: there is no a root dir (dir_table is empty)" << logend;
return;
}
// request->status can be changed by function_parser
if( request.status == WINIX_ERR_OK )
{
if( system.DirsHaveReadExecPerm() )
{
if( request.method == Request::post )
functions.MakePost();
if( request.redirect_to.empty() && request.status == WINIX_ERR_OK )
functions.MakeGet();
}
else
request.status = WINIX_ERR_PERMISSION_DENIED;
}
if( request.session->spam_score > 0 )
log << log1 << "App: spam score: " << request.session->spam_score << logend;
if( request.IsParam("noredirect") )
request.redirect_to.clear();
if( !request.redirect_to.empty() )
return;
if( request.dir_table.empty() )
{
log << log1 << "App: there is no a root dir (dir_table is empty -- after calling a function)" << logend;
return;
}
plugin.Call(WINIX_CONTENT_MAKE);
MakePage();
// !! dodac parametr do konfiga wlaczajacy te informacje
//request->PrintGetTable();
//request->PrintEnv();
//request->PrintIn();
}
// !! dac lepsza nazwe i czy napewno w app to ma byc?
void App::ReadAdditionalInfo()
{
if( request.dir_table.empty() )
return;
if( system.mounts.pmount->type == Mount::thread )
{
if( db.GetThreadByDirId(request.dir_table.back()->id, request.thread) == WINIX_ERR_OK )
request.is_thread = true;
}
else
if( system.mounts.pmount->type == Mount::ticket )
{
if( db.GetTicketByDirId(request.dir_table.back()->id, request.ticket) == WINIX_ERR_OK )
{
request.is_ticket = true;
if( !request.is_item && (!request.pfunction || request.pfunction->fun.url == "ticket") )
{
db.GetItemById(request.ticket.item_id, request.item);
// don't set request->is_item here
}
}
}
}
Executable
+111
View File
@@ -0,0 +1,111 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreapp
#define headerfilecmslucoreapp
#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include "config.h"
#include "system.h"
#include "mounts.h"
#include "request.h"
#include "sessionmanager.h"
#include "notify.h"
#include "db.h"
#include "functions/functions.h"
#include "templates/templates.h"
#include "templatesnotify/templatesnotify.h"
class App
{
public:
App();
bool Init();
void Start();
void Close();
// configuration read from a config file
Config config;
// current request
Request request;
// users sessions
SessionManager session_manager;
// notifications (by emails)
Notify notify;
// database
Db db;
/*
model
*/
// file system
System system;
// false at the beginning
bool stdout_is_closed;
/*
controller
*/
// functions (ls, cat, emacs, ...)
Functions functions;
/*
view
*/
Templates templates;
TemplatesNotify templates_notify;
private:
bool CreateFCGISocket();
void ProcessRequest();
bool BaseUrlRedirect();
void DeleteAllPluginsData();
void MakePage();
void Make();
void ReadAdditionalInfo();
void SaveSessionsIfNeeded(); // !! wywalic do managara sesji??
// !! dodac do session managera?
time_t last_sessions_save;
};
#endif
+566
View File
@@ -0,0 +1,566 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "bbcodeparser.h"
bool BBCODEParser::IsValidCharForName(int c)
{
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
c=='*' || c=='_')
return true;
return false;
}
bool BBCODEParser::IsOpeningTagMark()
{
return (*pchar == '[');
}
// there are no commentaries in bbcode
bool BBCODEParser::IsOpeningCommentaryTagMark()
{
return false;
}
bool BBCODEParser::SkipCommentaryTagIfExists()
{
return false;
}
bool BBCODEParser::IsClosingTagMark()
{
return (*pchar == ']');
}
bool BBCODEParser::IsClosingXmlSimpleTagMark()
{
return false;
}
// one enter will generate one <br>
// two enters or more will generate only two br (<br><br>)
void BBCODEParser::PutNormalText(const char * str, const char * end)
{
int br_len;
if( *pchar == 0 )
{
// trimming last white characters at end of the user text
while( str<end && (IsWhite(*(end-1)) || *(end-1)==10) )
--end;
}
while( str < end )
{
if( *str == 10 )
{
++str;
br_len = 1;
// skipping white characters without a new line character
while( str < end && IsWhite(*str) )
++str;
if( str < end && *str == 10 )
{
br_len = 2;
// skipping white characters with new line characters
while( str < end && (IsWhite(*str) || *str==10) )
++str;
}
if( !has_open_ol_tag && !has_open_ul_tag && !has_open_li_tag )
{
for(int i=0 ; i < br_len ; ++i)
(*out_string) += "<br>\n";
}
}
else
{
PrintEscape(*str);
++str;
}
}
}
void BBCODEParser::PutNormalTextTrim(const char * str, const char * end)
{
// we don't use trimming in bbcode parser
PutNormalText(str, end);
}
void BBCODEParser::ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white)
{
}
void BBCODEParser::CheckExceptions()
{
if( stack_len >= 2 )
{
if( pstack[stack_len-1].type == Item::opening &&
pstack[stack_len-2].type == Item::opening &&
IsNameEqual("*", pstack[stack_len-1].name) &&
IsNameEqual("*", pstack[stack_len-2].name) )
{
// removing the last [*] from the stack
// </li> was put automatically
PopStack();
}
}
}
/*
bbcode format:
[bbcodetag=value]some text[/bbcodetag]
the value can be quoted, e.g.
[bbcodetag="value"]some text[/bbcodetag], or
[bbcodetag='value']some text[/bbcodetag]
the third string below (in tags table) is 'html_argument' from Tags,
it can contain a special character % followed by a string which means:
%1 - "value" escaped as for html
%2 - "some text" escaped as for html
%u1 - "value" trimmed and escaped as for url-es
%u2 - "some text" trimmed and escaped as for url-es
%% - one %
if you are using %2 or %u2 then "some text" is not treated as bbcode, e.g.
[bbcodetag=value]some [b]text[/b][/bbcodetag] will produce:
<htmltag arg="value">some [b]text[/b]</htmltag> (the inner tags [b][/b] were not parsed)
also when using %2 or %u2 the closing bbcode tag is skipped
(if you want this tag then you can put it in 'html_argument')
and when using u (%u1 or %u2) the argument is trimmed from whitespaces and new lines
at the beginning and at the end
(because otherwise a space would be changed to %20 and this were probably not what you really wanted)
*/
const BBCODEParser::Tags * BBCODEParser::FindTag(const char * tag)
{
static Tags tags[] = {
{"*", "li", ">", false},
{"b", "em", ">", true},
{"i", "span", " class=\"bbitalic\">", true},
{"u", "span", " class=\"bbunderline\">", true},
{"s", "span", " class=\"bbstrike\">", true},
{"code", "code", " class=\"bbcode\">", false},
{"list", "ul", " class=\"bblist\">", false},
{"color", "span", " class=\"bbcol%1\">", true},
{"url", "a", " href=\"%u1\">", true},
{"img", "img", " alt=\"%1\" src=\"%u2\">", true},
{"quote", "div", " class=\"bbquote\">\n<span class=\"bbquotewho\">%1</span><br>\n", false},
};
size_t i;
size_t len = sizeof(tags) / sizeof(Tags);
for(i=0 ; i<len ; ++i)
{
if( strcmp(tag, tags[i].bbcode) == 0 )
return &tags[i];
}
return 0;
}
void BBCODEParser::PrintArgumentCheckQuotes(const char * & start, const char * & end)
{
// skipping white characters from the argument
while( start<end && IsWhite(*start) )
++start;
// skipping first '=' character if exists
if( start<end && *start == '=' )
++start;
// skipping white characters from the argument
// at the beginning
while( start<end && IsWhite(*start) )
++start;
// and at the end
while( start<end && IsWhite(*(end-1)) )
--end;
if( start<end && (*start=='\'' || *start=='\"') )
{
++start;
if( start<end && *(start-1) == *(end-1) )
--end;
// skipping white characters after a first quote char [url = " ww...."]
while( start<end && IsWhite(*start) )
++start;
}
}
void BBCODEParser::PrintEncode(int c)
{
if( c == '&' )
{
(*out_string) += "&amp;";
}
else
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9') ||
(c=='_' || c=='?' || c=='.' || c==',' || c=='/' || c=='-' ||
c=='+' || c=='*' || c=='(' || c==')' || c=='=' || c==':')
)
{
(*out_string) += c;
}
else
{
char buffer[20];
sprintf(buffer, "%02X", c);
(*out_string) += '%';
(*out_string) += buffer;
}
}
void BBCODEParser::PrintEscape(int c, bool change_quote)
{
if( c == '<' )
{
(*out_string) += "&lt;";
}
else
if( c == '>' )
{
(*out_string) += "&gt;";
}
else
if( c == '&' )
{
(*out_string) += "&amp;";
}
else
if( c == '\"' && change_quote )
{
(*out_string) += "&quot;";
}
else
{
(*out_string) += c;
}
}
void BBCODEParser::PrintArgumentEncode(const char * start, const char * end)
{
PrintArgumentCheckQuotes(start, end);
TrimWhiteWithNewLines(start, end);
for( ; start<end ; ++start )
PrintEncode(*start);
}
void BBCODEParser::PrintArgumentEscape(const char * start, const char * end)
{
PrintArgumentCheckQuotes(start, end);
for( ; start<end ; ++start )
PrintEscape(*start, true); // quotes are escaped as well here
}
void BBCODEParser::CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition)
{
if( strcmp(tag->html_tag, tag_name) == 0 )
{
if( condition )
{
PutClosingTag(tag);
(*out_string) += '\n';
}
condition = true;
}
}
void BBCODEParser::CheckOpeningTag(const Tags * tag)
{
bool has_list_tag = has_open_ul_tag || has_open_ol_tag;
CheckOpeningTag(tag, "li", has_open_li_tag);
CheckOpeningTag(tag, "ul", has_open_ul_tag);
CheckOpeningTag(tag, "ol", has_open_ol_tag);
if( has_open_li_tag && !has_list_tag )
{
(*out_string) += "<ul>\n";
has_open_ul_tag = true;
}
}
void BBCODEParser::PrintEscape(const char * start, const char * end, bool change_quote)
{
for( ; start < end ; ++start)
PrintEscape(*start, change_quote);
}
void BBCODEParser::PrintEncode(const char * start, const char * end)
{
for( ; start < end ; ++start)
PrintEncode(*start);
}
void BBCODEParser::PutOpeningTagFromEzc(const char * start, const char * end)
{
// this can be a tag from Ezc templates system
(*out_string) += '[';
(*out_string) += LastItem().name;
if( start != end )
{
(*out_string) += ' ';
PrintEscape(start, end);
}
(*out_string) += ']';
}
void BBCODEParser::PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u)
{
if( has_u )
PrintArgumentEncode(arg_start, arg_end);
else
PrintArgumentEscape(arg_start, arg_end);
}
void BBCODEParser::TrimWhiteWithNewLines(const char * & start, const char * & end)
{
while( start < end && (IsWhite(*start) || *start==10) )
++start;
while( start < end && (IsWhite(*(end-1)) || *(end-1)==10) )
--end;
}
void BBCODEParser::PutHtmlArgument2(const Tags * tag, bool has_u)
{
const char * start = pchar;
const char * end = pchar;
bool first_tag_removed = false;
while( *pchar != 0 )
{
if( IsOpeningTagMark() )
{
if( IsClosingTagForLastItem() )
{
// the last tag is skipped when using patterns with %2 or %u2
PopStack(); // removing opening tag from the stack
first_tag_removed = true;
break;
}
}
else
{
pchar += 1;
end = pchar;
}
}
if( !first_tag_removed )
PopStack(); // user has forgotten to close the tag
if( has_u )
{
TrimWhiteWithNewLines(start, end);
PrintEncode(start, end);
}
else
{
PrintEscape(start, end);
}
}
void BBCODEParser::PutHtmlArgument(const Tags * tag, const char * arg_start, const char * arg_end)
{
const char * pattern = tag->html_argument;
bool has_u;
while( *pattern )
{
if( *pattern == '%' )
{
++pattern;
has_u = false;
if( *pattern == 'u' )
{
++pattern;
has_u = true;
}
if( *pattern == '1' )
{
++pattern;
PutHtmlArgument1(arg_start, arg_end, has_u);
}
else
if( *pattern == '2' )
{
++pattern;
PutHtmlArgument2(tag, has_u);
}
else
if( *pattern == '%' )
{
(*out_string) += '%';
++pattern;
}
// else unrecognized, will be printed next time as a normal character
}
else
{
(*out_string) += *pattern;
++pattern;
}
}
}
void BBCODEParser::PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end)
{
CheckOpeningTag(tag);
PutOpeningTagMark();
(*out_string) += tag->html_tag;
PutHtmlArgument(tag, start, end);
if( !tag->inline_tag )
{
(*out_string) += "\n";
SkipWhiteLines();
}
}
void BBCODEParser::PutOpeningTag(const char * start, const char * end)
{
const Tags * tag = FindTag(LastItem().name);
if( !tag )
{
PutOpeningTagFromEzc(start, end);
}
else
{
PutOpeningTagFromBBCode(tag, start, end);
}
}
void BBCODEParser::PutClosingTag(const Tags * tag)
{
if( !tag )
return; // skipping the tag
PutOpeningTagMark();
(*out_string) += '/';
(*out_string) += tag->html_tag;
PutClosingTagMark();
if( !tag->inline_tag )
{
(*out_string) += "\n";
SkipWhiteLines();
}
if( strcmp(tag->html_tag, "li") == 0 )
has_open_li_tag = false;
if( strcmp(tag->html_tag, "ol") == 0 )
has_open_ol_tag = false;
if( strcmp(tag->html_tag, "ul") == 0 )
has_open_ul_tag = false;
}
void BBCODEParser::PutClosingTag(const char * tag_name)
{
const Tags * tag = FindTag(tag_name);
PutClosingTag(tag);
}
void BBCODEParser::Init()
{
has_open_li_tag = false;
has_open_ol_tag = false;
has_open_ul_tag = false;
SkipWhiteLines();
}
void BBCODEParser::Deinit()
{
if( has_open_li_tag )
(*out_string) += "</li>\n";
if( has_open_ol_tag )
(*out_string) += "</ol>\n";
if( has_open_ul_tag )
(*out_string) += "</ul>\n";
}
+95
View File
@@ -0,0 +1,95 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorebbcodeparser
#define headerfilecmslucorebbcodeparser
#include "htmlfilter.h"
class BBCODEParser : public HTMLFilter
{
//using HTMLFilter::pchar;
struct Tags
{
/*
const char * bbcode;
const char * html_tag;
const char * html_arg_prefix;
const char * html_arg_postfix;
const char * additional_html_tag_prefix;
const char * additional_html_tag_postfix;
bool inline_tag;
*/
const char * bbcode;
const char * html_tag;
const char * html_argument; // with closing '>'
bool inline_tag;
};
virtual bool IsValidCharForName(int c);
virtual bool IsOpeningTagMark();
virtual bool IsOpeningCommentaryTagMark();
virtual bool SkipCommentaryTagIfExists();
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
void PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u);
void PutHtmlArgument2(const Tags * tag, bool has_u);
void PutHtmlArgument(const Tags * tag, const char * arg_start, const char * arg_end);
void PutOpeningTagFromEzc(const char * start, const char * end);
void PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end);
virtual void PutOpeningTag(const char * start, const char * end);
virtual void PutClosingTag(const char * tag);
const Tags * FindTag(const char * tag);
void PrintArgumentCheckQuotes(const char * & start, const char * & end);
void PrintEscape(int c, bool change_quote = false);
void PrintEncode(int c);
void PrintEscape(const char * start, const char * end, bool change_quote = false);
void PrintEncode(const char * start, const char * end);
void PrintArgumentEncode(const char * start, const char * end);
void PrintArgumentEscape(const char * start, const char * end);
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
virtual void PutNormalText(const char * str, const char * end);
virtual void PutNormalTextTrim(const char * str, const char * end);
virtual void CheckExceptions();
virtual void Init();
virtual void Deinit();
void PutClosingTag(const Tags * tag);
void CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition);
void CheckOpeningTag(const Tags * tag);
void TrimWhiteWithNewLines(const char * & start, const char * & end);
bool has_open_ol_tag; // has open html <ol> tag
bool has_open_ul_tag; // has open html <ul> tag
bool has_open_li_tag; // has open html <li> tag
};
#endif
+7 -4
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -162,8 +162,11 @@ int ret;
if( deflateReset(&strm) != Z_OK )
log << log1 << "Compress: problem with deflateReset()" << logend;
double ratio = (double(last_out_size) / double(source_len) * 100.0);
log << log2 << "Compress: original size: " << source_len << ", compress size: " << (int)last_out_size << ", ratio: " << ratio << "%" << logend;
double ratio = 100.0 - (double(last_out_size) / double(source_len) * 100.0);
char buffer[30];
sprintf(buffer, "%.1f", ratio);
log << log2 << "Compress: original size: " << source_len << ", compress size: " << (int)last_out_size << ", ratio: " << buffer << "%" << logend;
return ret;
}
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
+167 -97
View File
@@ -1,22 +1,21 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "config.h"
#include "log.h"
#include "data.h"
#include "plugin.h"
#include "misc.h"
Config::Config()
{
default_int = 0;
default_bool = false;
errors_to_stdout = true;
}
@@ -29,7 +28,7 @@ Config::Config()
void Config::ShowError()
{
switch( conf_parser.status )
switch( parser.status )
{
case ConfParser::ok:
log << log2 << "Config: syntax ok" << logend;
@@ -37,16 +36,16 @@ void Config::ShowError()
case ConfParser::cant_open_file:
if( errors_to_stdout )
std::cout << "Config: cant open a config file: " << data.config_file << std::endl;
std::cout << "Config: cant open a config file: " << config_file << std::endl;
log << log1 << "Config: cant open a config file: " << data.config_file << logend;
log << log1 << "Config: cant open a config file: " << config_file << logend;
break;
case ConfParser::syntax_error:
if( errors_to_stdout )
std::cout << "Config: syntax error, line: " << conf_parser.line << std::endl;
std::cout << "Config: syntax error, line: " << parser.line << std::endl;
log << log1 << "Config: syntax error, line: " << conf_parser.line << logend;
log << log1 << "Config: syntax error, line: " << parser.line << logend;
break;
}
}
@@ -56,11 +55,11 @@ void Config::ShowError()
bool Config::ReadConfig(bool errors_to_stdout_)
bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed)
{
errors_to_stdout = errors_to_stdout_;
if( data.config_file.empty() )
if( config_file.empty() )
{
log << log2 << "Config: name of the config file is empty" << logend;
return false;
@@ -68,14 +67,14 @@ bool Config::ReadConfig(bool errors_to_stdout_)
log << log2 << "Config: reading a config file" << logend;
ConfParser::Status status = conf_parser.Parse( data.config_file.c_str() );
parser.SplitSingle(true);
ConfParser::Status status = parser.Parse( config_file );
if( status == ConfParser::ok )
{
AssignValues();
data.SetAdditionalVariables();
AssignValues(stdout_is_closed);
SetAdditionalVariables();
return true;
}
else
@@ -87,102 +86,151 @@ bool Config::ReadConfig(bool errors_to_stdout_)
void Config::AssignValues()
{
data.log_file = Text("log_file");
data.log_notify_file = Text("log_notify_file");
data.fcgi_socket = Text("fcgi_socket");
data.fcgi_socket_chmod = Int("fcgi_socket_chmod");
data.fcgi_socket_user = Text("fcgi_socket_user");
data.fcgi_socket_group = Text("fcgi_socket_group");
data.log_level = Int("log_level");
if( !data.stdout_is_closed )
data.log_stdout = Bool("log_stdout");
void Config::AssignValues(bool stdout_is_closed)
{
log_file = Text("log_file");
log_notify_file = Text("log_notify_file");
fcgi_socket = Text("fcgi_socket");
fcgi_socket_chmod = Int("fcgi_socket_chmod", 0770);
fcgi_socket_user = Text("fcgi_socket_user");
fcgi_socket_group = Text("fcgi_socket_group");
log_level = Int("log_level", 1);
log_request = Int("log_request", 1);
log_stdout = Bool("log_stdout", false);
post_file_max = Int("post_file_max", 8388608); // 8 MB
auth_simplefs_dir = Text("auth_simplefs_dir");
auth_hashfs_dir = Text("auth_hashfs_dir");
auth_tmp_dir = Text("auth_tmp_dir");
templates_dir = Text("templates_dir");
templates_dir_default = Text("templates_dir_default");
http_session_id_name = Text("http_session_id_name");
db_database = Text("db_database");
db_user = Text("db_user");
db_pass = Text("db_pass");
item_url_empty = Text("item_url_empty");
base_server = Text("base_server");
base_url = Text("base_url");
base_url_auth = Text("base_url_auth");
base_url_static = Text("base_url_static");
base_url_common = Text("base_url_common");
NoLastSlash(base_server);
NoLastSlash(base_url);
NoLastSlash(base_url_auth);
NoLastSlash(base_url_static);
NoLastSlash(base_url_common);
priv_no_user = Text("priv_no_user", "-- no user --");
priv_no_group = Text("priv_no_group", "-- no group --");
session_max_idle = Int("session_max_idle", 10800); // 3h
session_remember_max_idle = Int("session_remember_max_idle", 16070400); // 3 months
session_file = Text("session_file");
compression = Bool("compression", true);
html_filter = Bool("html_filter", true);
locale_str = Text("locale", "en");
locale_dir = Text("locale_dir");
locale_dir_default = Text("locale_dir_default");
title_separator = Text("title_separator", " / ");
parser.ListText("plugins", plugin_file);
}
void Config::SetAdditionalVariables()
{
SetHttpHost(base_url, base_url_http_host);
SetHttpHost(base_url_auth, base_url_auth_http_host);
}
void Config::SetHttpHost(const std::string & in, std::string & out)
{
if( strncmp(in.c_str(), "http://", 7) == 0 )
out = in.substr(7);
else
data.log_stdout = false;
data.templates = Text("templates");
data.default_index = Text("default_index");
data.http_session_id_name = Text("http_session_id_name");
data.db_database = Text("db_database");
data.db_user = Text("db_user");
data.db_pass = Text("db_pass");
data.base_url = Text("base_url");
NoLastSlash(data.base_url);
data.one_item_is_showed = Bool("one_item_is_showed");
data.priv_no_user = Text("priv_no_user");
data.priv_no_group = Text("priv_no_group");
data.session_max_iddle = Int("session_max_iddle");
data.compression = Bool("compression");
if( strncmp(in.c_str(), "https://", 8) == 0 )
out = in.substr(8);
else
out.clear(); // if empty the RequestController::BaseUrlRedirect() returns false and no redirecting will be done
}
// !! mozna dodac drugi argument -- wartosc domyslna
std::string & Config::Text(const char * name)
std::string Config::Text(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);
if( i == conf_parser.table.end() )
{
log << log2 << "Config: warning: " << name << " is not defined in the config, default will be: \"" << default_str << "\"" << logend;
return default_str;
}
log << log3 << "Config: " << name << "=" << i->second << logend;
return i->second;
return parser.Text(name);
}
std::string Config::Text(const char * name, const char * def)
{
return parser.Text(name, def);
}
std::string Config::Text(const std::string & name, const std::string & def)
{
return parser.Text(name, def);
}
// !! mozna dodac drugi argument -- wartosc domyslna
int Config::Int(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);
if( i == conf_parser.table.end() || i->second.empty() )
{
log << log2 << "Config: warning: " << name << " is not defined in the config, default will be: " << default_int << logend;
return default_int;
}
long res = (i->second[0] == '0')? strtol(i->second.c_str() + 1, 0, 8) : strtol(i->second.c_str(), 0, 10);
log << log3 << "Config: " << name << "=" << res << logend;
return res;
return parser.Int(name);
}
int Config::Int(const char * name, int def)
{
return parser.Int(name, def);
}
int Config::Int(const std::string & name, int def)
{
return parser.Int(name, def);
}
// !! mozna dodac drugi argument -- wartosc domyslna
bool Config::Bool(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);
if( i == conf_parser.table.end() )
{
log << log2 << "Config: warning: " << name << " is not defined in the config, default will be: " << (default_bool?"true":"false") << logend;
return default_int;
}
bool res = default_int;
if( i->second == "true" || i->second == "1" || i->second == "yes" )
res = true;
log << log3 << "Config: " << name << "=" << (res?"true":"false") << logend;
return res;
return parser.Bool(name);
}
bool Config::Bool(const char * name, bool def)
{
return parser.Bool(name, def);
}
bool Config::Bool(const std::string & name, bool def)
{
return parser.Bool(name, def);
}
void Config::ListText(const char * name, std::vector<std::string> & list)
{
parser.ListText(name, list);
}
void Config::ListText(const std::string & name, std::vector<std::string> & list)
{
parser.ListText(name, list);
}
void Config::NoLastSlash(std::string & s)
@@ -190,10 +238,34 @@ void Config::NoLastSlash(std::string & s)
if( s.empty() )
return;
log << log2 << "Config: removing the last slash from: " << s << logend;
if( *(--s.end()) == '/' )
s.erase(--s.end());
size_t i = s.size();
for( ; i>0 && s[i-1]=='/' ; --i);
if( i < s.size() )
s.erase(i);
}
void Config::NoFirstHttp(std::string & s)
{
if( s.empty() )
return;
const char http[] = "http://";
const char https[] = "https://";
if( IsSubStringNoCase(http, s.c_str()) )
{
s.erase(0, sizeof(http)/sizeof(char));
}
else
if( IsSubStringNoCase(https, s.c_str()) )
{
s.erase(0, sizeof(https)/sizeof(char));
}
}
@@ -203,5 +275,3 @@ void Config::NoLastSlash(std::string & s)
+143 -16
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -11,42 +11,169 @@
#define headerfilecmslucoreconfig
#include <string>
#include "confparser.h"
#include "../confparser/confparser.h"
class Config
{
public:
// name of the config file (full path can be)
std::string config_file;
// log file name, log file name for notifications (sending emails, etc)
std::string log_file, log_notify_file;
// 1 - minimum
// 2 - (default)
// 3 - maximum - all logs
int log_level;
// logging to stdout too
bool log_stdout;
// how many requests should be logged in the same time
// default: 1
int log_request;
// fast cgi: socket (unix domain)
std::string fcgi_socket;
// fast cgi: socket permissions
int fcgi_socket_chmod;
// fast cgi: owner of the socket
std::string fcgi_socket_user;
// fast cgi: group of the socket
std::string fcgi_socket_group;
std::string templates_dir;
std::string templates_dir_default; // templates from winix
std::string db_database;
std::string db_user;
std::string db_pass;
std::string http_session_id_name;
// when the HOST_HTTP environment variable doesn't point into 'base_url' (the part 'http://' and the last slash is removed)
// the server will redirect into 'base_url' + 'REQUEST_URI'
// it's useful when you want to redirect from 'mydomain.tld' into 'www.mydomain.tld' etc.
bool base_url_redirect;
// string used in a place where is a user (or group) selected
std::string priv_no_user;
std::string priv_no_group;
// time in seconds when the user will be automatically logged out (iddle time)
int session_max_idle;
// time in seconds when the user will be automatically logged out (when he selected 'remember me' option)
// this time is usually greater than session_max_idle
int session_remember_max_idle;
// this file is used when the program is starting and ending
std::string session_file;
// allow the html ouput to be compressed
bool compression;
// plugins
std::vector<std::string> plugin_file;
// the html code is cleaned by our filter
bool html_filter;
// the url of a new empty item (if there is not the subject too)
std::string item_url_empty;
// maximum length of a file send by post multipart form
// 0 - not used
int post_file_max;
// directories for static files
std::string auth_simplefs_dir;
std::string auth_hashfs_dir;
// temporary directory for static content used by the upload function
// should be on the same partition as auth_simplefs_dir and auth_hashfs_dir
std::string auth_tmp_dir;
// default locale: en pl
std::string locale_str;
// directory with locale files
std::string locale_dir;
// directory with default locale files (those from winix)
std::string locale_dir_default;
// the main address of the server (e.g. someserver.com) (without the 'www' part etc)
std::string base_server;
// the main address of the site (e.g. http://www.someserver.com)
std::string base_url;
// static content authorized by winix
std::string base_url_auth;
// static content not authorized by winix
std::string base_url_static;
// additional static server for common content (not authorized)
std::string base_url_common;
// separator used in <title> html tag
std::string title_separator;
// based on base_url
// set by SetAdditionalVariables()
// without the first part http:// (or https://) or the whole string is empty
std::string base_url_http_host;
std::string base_url_auth_http_host;
Config();
bool ReadConfig(bool errors_to_stdout_);
bool ReadConfig(bool errors_to_stdout_, bool stdout_is_closed = true);
std::string Text(const char * name);
std::string Text(const char * name, const char * def);
std::string Text(const std::string & name, const std::string & def);
int Int(const char *);
int Int(const char * name, int def);
int Int(const std::string & name, int def);
bool Bool(const char *);
bool Bool(const char * name, bool def);
bool Bool(const std::string & name, bool def);
void ListText(const char * name, std::vector<std::string> & list);
void ListText(const std::string & name, std::vector<std::string> & list);
void NoLastSlash(std::string & s);
void NoFirstHttp(std::string & s);
private:
ConfParser conf_parser;
void ShowError();
void AssignValues();
void AssignValues(bool stdout_is_closed);
void SetHttpHost(const std::string & in, std::string & out);
void SetAdditionalVariables();
std::string & Text(const char *);
int Int(const char *);
bool Bool(const char *);
ConfParser parser;
std::string default_str;
int default_int;
bool default_bool;
bool errors_to_stdout;
void NoLastSlash(std::string & s);
};
#endif
+541
View File
@@ -0,0 +1,541 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "confparser.h"
#include "misc.h"
ConfParser::ConfParser()
{
// you can change this separators to what you want
// you shoud not use only white characters here (as expected by IsWhite() method)
// and new line characters ('\n')
separator = '=';
commentary = '#';
list_start = '(';
list_end = ')';
list_delimiter = ',';
split_single = false;
skip_empty = false;
default_str = "";
default_int = 0;
default_bool = false;
}
void ConfParser::SplitSingle(bool split)
{
split_single = split;
}
void ConfParser::SkipEmpty(bool skip)
{
skip_empty = skip;
}
ConfParser::Status ConfParser::Parse(const char * file_name)
{
line = 1;
table.clear();
table_single.clear();
file.clear();
file.open( file_name );
if( file )
{
status = ParseFile();
file.close();
}
else
{
status = cant_open_file;
}
return status;
}
ConfParser::Status ConfParser::Parse(const std::string & file_name)
{
return Parse(file_name.c_str());
}
ConfParser::Status ConfParser::ParseFile()
{
ReadChar();
SkipWhiteLines();
while( lastc != -1 )
{
if( !ReadVariable() )
return syntax_error;
if( lastc != separator )
return syntax_error;
if( !ReadValue() )
return syntax_error;
AddOption();
SkipWhite();
if( lastc != -1 && lastc != '\n' )
return syntax_error; // some characters have left at the end of an option
SkipWhiteLines();
}
return ok;
}
bool ConfParser::IsVariableChar(int c)
{
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9') ||
c=='.' || c==',' || c=='_' )
return true;
return false;
}
void ConfParser::AddOption()
{
if( value.empty() && skip_empty )
{
DeleteFromTable(variable);
DeleteFromTableSingle(variable);
return;
}
if( split_single && value.size() == 1 )
{
table_single[variable] = value[0];
DeleteFromTable(variable);
}
else
{
table[variable] = value;
DeleteFromTableSingle(variable);
}
}
void ConfParser::DeleteFromTable(const std::string & var)
{
Table::iterator i = table.find(var);
if( i != table.end() )
table.erase(i);
}
void ConfParser::DeleteFromTableSingle(const std::string & var)
{
TableSingle::iterator i = table_single.find(var);
if( i != table_single.end() )
table_single.erase(i);
}
bool ConfParser::ReadVariable()
{
variable.clear();
SkipWhite();
while( IsVariableChar(lastc) )
{
variable += lastc;
ReadChar();
}
SkipWhite();
return !variable.empty();
}
bool ConfParser::ReadValue()
{
value.clear();
ReadChar(); // skipping separator '='
SkipWhite();
if( lastc == list_start )
return ReadValueList();
else
return ReadValueNoList();
}
bool ConfParser::ReadValueList()
{
ReadChar(); // skipping first list character '('
SkipWhiteLines(); // lists can be split into several lines
while( lastc != -1 && lastc != list_end )
{
if( !ReadValueNoList(true) )
return false;
if( lastc == list_delimiter )
ReadChar();
SkipWhiteLines();
}
if( lastc != list_end )
return false;
ReadChar(); // skipping last list character ')'
SkipWhite();
return true;
}
bool ConfParser::ReadValueNoList(bool use_list_delimiter)
{
bool res;
value_item.clear();
if( lastc == '"' )
{
res = ReadValueQuoted(); // quoted value
if( res )
value.push_back(value_item);
}
else
{
res = ReadValueSimple(use_list_delimiter);
if( res && !value_item.empty() )
value.push_back(value_item);
}
return res;
}
bool ConfParser::ReadValueQuoted()
{
ReadChar(); // skipping the first quote
while( lastc != '"' && lastc != -1 )
{
if( lastc == '\\' )
ReadChar();
value_item += lastc;
ReadChar();
}
if( lastc != '"' )
return false;
ReadChar(); // skipping the last quote
SkipWhite();
return true;
}
bool ConfParser::ReadValueSimple(bool use_list_delimiter)
{
int list_delimiter1 = -1;
int list_delimiter2 = -1;
if( use_list_delimiter )
{
list_delimiter1 = list_delimiter;
list_delimiter2 = list_end;
}
while( lastc!=-1 && lastc!='\n' && lastc!=commentary &&
lastc!=list_delimiter1 && lastc!=list_delimiter2 )
{
value_item += lastc;
ReadChar();
}
Trim(value_item);
SkipWhite();
return true;
}
int ConfParser::ReadChar()
{
lastc = file.get();
if( lastc == '\n' )
++line;
return lastc;
}
bool ConfParser::IsWhite(int c)
{
// dont use '\n' here
// 13 (\r) is at the end of a line in a dos file \r\n
// 160 is an unbreakable space
if( c==' ' || c=='\t' || c==13 || c==160 )
return true;
return false;
}
void ConfParser::SkipWhite()
{
while( IsWhite(lastc) || lastc == commentary )
{
if( lastc == commentary )
SkipLine();
else
ReadChar();
}
}
void ConfParser::SkipWhiteLines()
{
while( IsWhite(lastc) || lastc == commentary || lastc=='\n' )
{
if( lastc == commentary )
SkipLine();
else
ReadChar();
}
}
void ConfParser::SkipLine()
{
while( lastc != -1 && lastc != '\n' )
ReadChar();
}
void ConfParser::Trim(std::string & s)
{
std::string::size_type i;
if( s.empty() )
return;
// looking for white characters at the end
for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i);
if( i==0 && IsWhite(s[i]) )
{
// the whole string has white characters
s.clear();
return;
}
// deleting white characters at the end
if( i != s.size() - 1 )
s.erase(i+1, std::string::npos);
// looking for white characters at the beginning
for(i=0 ; i<s.size() && IsWhite(s[i]) ; ++i);
// deleting white characters at the beginning
if( i != 0 )
s.erase(0, i);
}
std::string ConfParser::Text(const char * name)
{
return Text(std::string(name), default_str);
}
std::string ConfParser::Text(const char * name, const char * def)
{
return Text(std::string(name), std::string(def));
}
std::string ConfParser::Text(const std::string & name, const std::string & def)
{
TableSingle::iterator i = table_single.find(name);
if( i == table_single.end() )
{
Table::iterator t = table.find(name);
if( t == table.end() || t->second.empty() )
return def;
return t->second[0];
}
return i->second;
}
int ConfParser::Int(const char * name)
{
return Int(std::string(name), default_int);
}
int ConfParser::Int(const char * name, int def)
{
return Int(std::string(name), def);
}
int ConfParser::ToInt(const std::string & value)
{
long res = (value[0] == '0')? strtol(value.c_str() + 1, 0, 8) : strtol(value.c_str(), 0, 10);
return res;
}
int ConfParser::Int(const std::string & name, int def)
{
TableSingle::iterator i = table_single.find(name);
if( i == table_single.end() )
{
Table::iterator t = table.find(name);
if( t == table.end() || t->second.empty() )
return def;
return ToInt(t->second[0]);
}
return ToInt(i->second);
}
bool ConfParser::Bool(const char * name)
{
return Bool(std::string(name), default_bool);
}
bool ConfParser::Bool(const char * name, bool def)
{
return Bool(std::string(name), def);
}
bool ConfParser::ToBool(const std::string & value)
{
return ( EqualNoCase(value.c_str(), "true") ||
EqualNoCase(value.c_str(), "yes") ||
EqualNoCase(value.c_str(), "1")
);
}
bool ConfParser::Bool(const std::string & name, bool def)
{
TableSingle::iterator i = table_single.find(name);
if( i == table_single.end() )
{
Table::iterator t = table.find(name);
if( t == table.end() || t->second.empty() )
return def;
return ToBool(t->second[0]);
}
return ToBool(i->second);
}
void ConfParser::SetDefaultText(const std::string & def)
{
default_str = def;
}
void ConfParser::SetDefaultInt(int def)
{
default_int = def;
}
void ConfParser::SetDefaultBool(bool def)
{
default_bool = def;
}
// in lists we don't use default values
void ConfParser::ListText(const char * name, std::vector<std::string> & list)
{
ListText(std::string(name), list);
}
void ConfParser::ListText(const std::string & name, std::vector<std::string> & list)
{
list.clear();
ConfParser::TableSingle::iterator i = table_single.find(name);
if( i != table_single.end() )
{
list.push_back(i->second);
return;
}
ConfParser::Table::iterator z = table.find(name);
if( z != table.end() )
{
list = z->second;
return;
}
}
+356
View File
@@ -0,0 +1,356 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfileconfparser
#define headerfileconfparser
#include <fstream>
#include <string>
#include <vector>
#include <map>
/*
A parser for parsing config files.
A config file can look like this:
variable1 = value 1
variable2 = " value 2 "
variable3 = (value 1, value 2)
variable4 = (" value 1 " , "value2", value 3)
sample of use:
ConfParser parser;
parser.Parse("/path/to/config");
if( parser.status == ConfParser::ok )
{
// the whole config we have in parser.table (parser.table_single)
}
config syntax:
option = list
list can consists of any number of items, if you're using more than one item you should
use brackets ()
for one item the brackets can be ommited:
option = value
white characters at the beginning of the value (and at the end) will be trimmed,
or you can use quotes:
option = "value"
option2 = "value with spaces at the end "
the form without quotes:
option = value
should be written in one line, so this is not allowed:
option =
value
you can use a new line characters only between brackets and quotes:
option = "this is
a multiline string"
option = ( value1,
value2 )
but there is one requirement: the first character " or ( should be in the same line,
so this is not allowed
option =
"this is wrong"
but this is ok:
option = "
that is ok"
empty lists:
option = ()
this creates an empty list: parser.table['option'].empty() == true
option =
this creates an empty list too (the same as previously)
option = ""
but this doesn't create an empty list, it creates a list with one (empty) item
commentaries:
# this is a commentary (until the end of the line)
option = value # this is a commentary too
commentaries are treated as white characters, other example:
option = ( # this is my list
"value 1" # this is a value one
value 2 # and this is a value two
) # end of my list
overwriting:
option1 = some value
option1 = other value
# always the last option is used so option1 is "other value"
list delimiter:
option1 = (value1, value2, value3)
option2 = ("value1", "value2", "value3")
above we're using a comma ',' as a list delimiter but when using quotes (second line)
the commas can be omitted:
option2 = ("value1" "value2" "value3")
white characters:
the name of an option cannot consist of white characters
some option = value # this is wrong
some_option = value # this is ok
which characters are allowed in an option name is defined by IsVariableChar() method
you can use white characters in values
option = value with spaces or tabs
white characters at the beginning and at the end will be trimmed,
so if you want them use quotes:
option = " other value with spaces "
special characters in quoted strings:
option = "this is a string with \" a quote inside"
the option will be: this is a string with " a quote inside
\\ - means one \
basically: \char produces char
so:
"\a" gives "a"
"\\" gives "\"
"\Z" gives "Z" and so on
*/
class ConfParser
{
public:
ConfParser();
/*
status of parsing
*/
enum Status { ok, cant_open_file, syntax_error };
/*
the last status of parsing, set by Parse() methods
*/
Status status;
/*
the main methods used to parse
file_name is the path to a file
*/
Status Parse(const char * file_name);
Status Parse(const std::string & file_name);
/*
a number of a line in which there is a syntax_error
*/
int line;
/*
this is the table which represents your config file
in the Table map: the first (key) is your 'option' and the second is 'list'
*/
typedef std::vector<std::string> Value;
typedef std::map<std::string, Value> Table;
Table table;
/*
if your config file consists mainly of single forms such as:
option = value
option2 = value2
then you can call SplitSingle(true) for not inserting single values to
previous 'table' but instead to 'table_single'
table_single as the second parameter takes only std::string (instead of the whole std::vector)
so you can save a little memory from not using std::vector
*/
typedef std::map<std::string, std::string> TableSingle;
TableSingle table_single;
/*
if your list consists of only one item, e.g:
option1 = value 1
option2 = "value 2"
option3 = ( "value 3" )
then if you call SplitSingle(true) then such values will be stored in
'table_single' instead of 'table' map
default: false
*/
void SplitSingle(bool split);
/*
if true then empty lists, e.g:
option =
option2 = ()
will be omitted (not inserted to 'table' or 'table_single')
default: false
*/
void SkipEmpty(bool skip);
/*
those methods are used to extract information from table or table_single
as a parameter they take the name of an option
and a default value (if there is no such a parameter),
they return appropriate value (either text, int or boolean)
(in lists they return the first item if exists)
*/
std::string Text(const char * name);
std::string Text(const char * name, const char * def);
std::string Text(const std::string & name, const std::string & def);
int Int(const char *);
int Int(const char * name, int def);
int Int(const std::string & name, int def);
bool Bool(const char *);
bool Bool(const char * name, bool def);
bool Bool(const std::string & name, bool def);
/*
some default values
used in Text() Int() or Bool() when you don't explicitly set the default value
if you don't set it directly then:
default text is: "" (empty)
default int is: 0
default bool is: false
*/
void SetDefaultText(const std::string & def);
void SetDefaultInt(int def);
void SetDefaultBool(bool def);
/*
those methods are used to extract lists
note: if there is one option in table_single they will return it
*/
void ListText(const char * name, std::vector<std::string> & list);
void ListText(const std::string & name, std::vector<std::string> & list);
private:
/*
last read variable (option)
*/
std::string variable;
/*
last read list item
*/
std::string value_item;
/*
last read list
*/
Value value;
/*
separator between a variable and a value, default: '='
*/
int separator;
/*
commentary char, default: '#'
*/
int commentary;
/*
list starting character, default: '('
*/
int list_start;
/*
list ending character, default: ')'
*/
int list_end;
/*
list delimiter, default: ','
*/
int list_delimiter;
/*
last read char
*/
int lastc;
/*
current file
*/
std::ifstream file;
/*
if true then lists with one item will be put into 'table_single' table
default: false
*/
bool split_single;
/*
if true then empty lists, e.g:
option =
option2 = ()
will be omitted (not inserted to 'table' or 'table_single')
default: false
*/
bool skip_empty;
std::string default_str;
int default_int;
bool default_bool;
int ToInt(const std::string & value);
bool ToBool(const std::string & value);
Status ParseFile();
void AddOption();
void DeleteFromTable(const std::string & var);
void DeleteFromTableSingle(const std::string & var);
bool ReadVariable();
bool ReadValue();
bool ReadValueList();
bool ReadValueNoList(bool use_list_delimiter = false);
bool ReadValueQuoted();
bool ReadValueSimple(bool use_list_delimiter = false);
int ReadChar();
bool IsWhite(int c);
bool IsVariableChar(int c);
void SkipWhite();
void SkipWhiteLines();
void SkipLine();
void Trim(std::string & s);
};
#endif
+7 -4
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -46,9 +46,12 @@ protected:
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
if( res.second == false )
log << log2 << " (skipped)";
{
res.first->second = value;
log << " (overwritten)";
}
log << log2 << logend;
log << logend;
}
-42
View File
@@ -1,42 +0,0 @@
/*
* 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 "data.h"
Data::Data()
{
signal_hup = false;
stdout_is_closed = false;
// the rest will be read from a config file
}
void Data::SetAdditionalVariables()
{
SetHttpHost();
}
void Data::SetHttpHost()
{
if( strncmp(base_url.c_str(), "http://", 7) == 0 )
base_url_http_host = base_url.substr(7);
else
if( strncmp(base_url.c_str(), "https://", 8) == 0 )
base_url_http_host = base_url.substr(8);
else
base_url_http_host.clear(); // if empty the RequestController::BaseUrlRedirect() returns false and no redirecting will be done
}
-142
View File
@@ -1,142 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucoredata
#define headerfilecmslucoredata
#include <string>
#include <vector>
#include <map>
#include <string.h>
#include "dirs.h"
#include "users.h"
#include "groups.h"
#include "functions.h"
#include "lastcontainer.h"
#include "mounts.h"
class Data
{
public:
// -----------------------------------------------------------------
// members read from a config file
// name of the config file (full path can be)
std::string config_file;
// log file name, log file name for notifications (sending emails, etc)
std::string log_file, log_notify_file;
// 1 - minimum
// 2 - (default)
// 3 - maximum - all logs
int log_level;
// logging to stdout too
bool log_stdout;
// fast cgi: socket (unix domain)
std::string fcgi_socket;
// fast cgi: socket permissions
int fcgi_socket_chmod;
// fast cgi: owner of the socket
std::string fcgi_socket_user;
// fast cgi: group of the socket
std::string fcgi_socket_group;
std::string templates;
std::string default_index;
std::string db_database;
std::string db_user;
std::string db_pass;
std::string base_url;
std::string http_session_id_name;
// when the HOST_HTTP environment variable doesn't point into 'base_url' (the part 'http://' and the last slash is removed)
// the server will redirect into 'base_url' + 'REQUEST_URI'
// it's useful when you want to redirect from 'mydomain.tld' into 'www.mydomain.tld' etc.
bool base_url_redirect;
// if there is one item in a directory
// it will be showed
// (instead of showing directory contents)
// !! wywalic to, nie bedzie uzywane
bool one_item_is_showed;
// string used in a place where is a user (or group) selected
std::string priv_no_user;
std::string priv_no_group;
// time in second when the user will be automatically logged out (iddle time)
int session_max_iddle;
bool compression;
// end config members
// -----------------------------------------------------------------
// false at the beginning
bool stdout_is_closed;
// true if there was SIGHUP signal
volatile bool signal_hup;
// contains current directories tree
Dirs dirs;
// based on base_url
// set by SetAdditionalVariables()
std::string base_url_http_host;
// call this method after the config file is read
void SetAdditionalVariables();
// users
Users users;
// groups
Groups groups;
// functions (ls, cat, etc)
Functions functions;
// for 'last' function
LastContainer last;
// mount points
Mounts mounts;
Data();
private:
void SetHttpHost();
};
extern Data data;
#endif
+608 -80
View File
File diff suppressed because it is too large Load Diff
+120 -9
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -27,7 +27,7 @@
#include "error.h"
#include "dircontainer.h"
#include "ugcontainer.h"
#include "ticket.h"
class Db
@@ -44,27 +44,121 @@ public:
void Init(const std::string & database, const std::string & user, const std::string & pass);
bool CheckUser(std::string & login, std::string & password, long & user_id);
Error AddUser(User & user, const std::string & password);
Error AddItem(Item & item);
Error EditItemById(Item & item, bool with_url = true);
Error EditItemByUrl(Item & item, bool with_url = true);
void CheckAllUrlSubject();
void GetItems(std::vector<Item> & item_table, long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc);
struct ItemQuery
{
// id is selected always
bool sel_parent_id; // parent_id
bool sel_user_id; // user_id, modification_user_id
bool sel_group_id; // group_id
bool sel_guest_name; // guest_name
bool sel_privileges; // privileges
bool sel_date; // date_creation, date_modification
bool sel_subject; // subject
bool sel_content; // content, content_type, (content_id)
bool sel_url; // url
bool sel_type; // type (dir, file, none)
bool sel_default_item; // default_item
bool sel_auth; // auth, auth_path
bool where_id; //
bool where_parent_id; //
bool where_type;
bool where_auth;
long id; // if where_id is true
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;
void SetAllSel(bool sel)
{
sel_parent_id = sel;
sel_user_id = sel;
sel_group_id = sel;
sel_guest_name = sel;
sel_privileges = sel;
sel_date = sel;
sel_subject = sel;
sel_content = sel;
sel_url = sel;
sel_type = sel;
sel_default_item= sel;
sel_auth = sel;
}
void SetAllWhere(bool where_)
{
where_id = where_;
where_parent_id = where_;
where_type = where_;
where_auth = where_;
}
void SetAll(bool sel, bool where_)
{
SetAllSel(sel);
SetAllWhere(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,
bool equal = true) { where_auth = true; auth = st; auth_equal = equal; }
ItemQuery()
{
sort_asc = true;
auth_equal = true;
SetAll(true, false);
id = -1;
parent_id = -1;
type = Item::none;
auth = Item::auth_none;
}
};
void GetItems(std::vector<Item> & item_table, const ItemQuery & item_query);
void GetItems(std::vector<long> & item_table, const ItemQuery & item_query);
// !! pobiera tylko jeden item (cos wymyslec innego z nazwa albo argumentem)
void GetItem(std::vector<Item> & item_table, long id);
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);
Error EditSubjectById(Item & item, long id);
bool DelItem(const Item & item);
void GetDirs(DirContainer & dir_table);
void GetUsers(UGContainer<User> & user_table);
void GetGroups(UGContainer<Group> & group_table);
// !! nowy interfejs
long Size(long parent_id, Item::Type type = Item::none);
Error GetItemById(long item_id, Item & item);
Error GetItem(long parent_id, const std::string & url, Item & item);
Error EditDefaultItem(long id, long new_default_item);
@@ -87,6 +181,15 @@ public:
Error EditThreadRemoveItem(long dir_id);
Error RemoveThread(long dir_id);
Error GetTicketByDirId(long dir_id, Ticket & ticket);
Error GetTickets(long parent_id, std::vector<Ticket> & ticket_tab);
//bool IsTicket(long dir_id);
Error AddTicket(Ticket & ticket);
Error EditTicketById(Ticket & ticket);
Error EditTicketRemoveItem(long item_id);
Error RemoveTicket(long dir_id);
protected:
PGconn * pg_conn;
@@ -118,7 +221,7 @@ protected:
void CheckAllUrlSubjectModifyItem(Item & item);
PGresult * GetItemsQuery(long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc);
PGresult * GetItemsQuery(const ItemQuery & iq, bool skip_other_sel = false);
bool DelItemDelItem(const Item & item);
void DelItemDelContent(const Item & item);
@@ -127,18 +230,26 @@ 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;
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, auth_path, modification_user_id;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);
};
struct TicketColumns
{
int id, dir_id, parent_id, type, status, priority, category, expected, progress, item_id;
void SetColumns(PGresult * r);
void SetTicket(PGresult * r, long row, Ticket & ticket);
};
}; // class Db
extern Db db;
#endif
+40 -4
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -29,6 +29,9 @@ 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_path = PQfnumber(r, "auth_path");
modification_user_id = PQfnumber(r, "modification_user_id");
}
@@ -42,14 +45,17 @@ void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
if( date_creation != -1 ) item.date_creation = ConvertTime( Db::AssertValue(r, row, date_creation) );
if( date_modification != -1 ) item.date_modification = ConvertTime( Db::AssertValue(r, row, date_modification) );
if( url != -1 ) item.url = Db::AssertValue(r, row, url);
if( type != -1 ) item.type = static_cast<Item::Type>( atoi( Db::AssertValue(r, row, type) ) );
if( type != -1 ) item.type = static_cast<Item::Type>( atoi(Db::AssertValue(r, row, type)) );
if( parent_id != -1 ) item.parent_id = atol( Db::AssertValue(r, row, parent_id) );
if( content_id != -1 ) item.content_id = atol( Db::AssertValue(r, row, content_id) );
if( default_item != -1 ) item.default_item = atol( Db::AssertValue(r, row, default_item) );
if( subject != -1 ) item.subject = Db::AssertValue(r, row, subject);
if( content != -1 ) item.content = Db::AssertValue(r, row, content);
if( content_type != -1 ) item.content_type = atoi( Db::AssertValue(r, row, content_type) );
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);
if( modification_user_id != -1 ) item.modification_user_id = atol( Db::AssertValue(r, row, modification_user_id) );
}
@@ -57,5 +63,35 @@ void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
void Db::TicketColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id");
dir_id = PQfnumber(r, "dir_id");
parent_id = PQfnumber(r, "parent_id");
type = PQfnumber(r, "type");
status = PQfnumber(r, "status");
priority = PQfnumber(r, "priority");
category = PQfnumber(r, "category");
expected = PQfnumber(r, "expected");
progress = PQfnumber(r, "progress");
item_id = PQfnumber(r, "item_id");
}
void Db::TicketColumns::SetTicket(PGresult * r, long row, Ticket & ticket)
{
if( id != -1 ) ticket.id = atol( Db::AssertValue(r, row, id) );
if( dir_id != -1 ) ticket.dir_id = atol( Db::AssertValue(r, row, dir_id) );
if( parent_id != -1 ) ticket.parent_id = atol( Db::AssertValue(r, row, parent_id) );
if( type != -1 ) ticket.type = atoi( Db::AssertValue(r, row, type) );
if( status != -1 ) ticket.status = atoi( Db::AssertValue(r, row, status) );
if( priority != -1 ) ticket.priority = atoi( Db::AssertValue(r, row, priority) );
if( category != -1 ) ticket.category = atoi( Db::AssertValue(r, row, category) );
if( expected != -1 ) ticket.expected = atoi( Db::AssertValue(r, row, expected) );
if( progress != -1 ) ticket.progress = atoi( Db::AssertValue(r, row, progress) );
if( item_id != -1 ) ticket.item_id = atol( Db::AssertValue(r, row, item_id) );
}
+98 -8
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -11,9 +11,13 @@
#include "log.h"
std::string DirContainer::dir_etc = "etc";
DirContainer::DirContainer()
{
is_root = false;
is_etc = false;
}
@@ -27,6 +31,14 @@ return root_iter;
}
DirContainer::Iterator DirContainer::GetEtc()
{
if( !is_etc )
return table.end();
return etc_iter;
}
DirContainer::Iterator DirContainer::Begin()
{
@@ -51,6 +63,50 @@ bool DirContainer::Empty()
}
// looking for '/etc'
// 'root' is found beforehand
// CheckSpecialFolder() may not find everything (when the first is a special folder and then the root)
void DirContainer::FindSpecialFolders()
{
is_etc = false;
if( !is_root )
return;
DirContainer::ParentIterator i = FindFirstParent(root_iter->id);
for( ; i!=ParentEnd() ; i = NextParent(i) )
{
if( i->second->url == dir_etc )
{
is_etc = true;
etc_iter = i->second;
break;
}
}
}
// this is used with PushBack() method
void DirContainer::CheckSpecialFolder(const Item & item, Iterator iter)
{
if( item.parent_id == -1 )
{
is_root = true;
root_iter = iter;
}
if( !is_root )
return;
if( item.parent_id==root_iter->id && item.url==dir_etc )
{
is_etc = true;
etc_iter = iter;
log << log1 << "DirCont: added special folder: /etc" << logend;
}
}
DirContainer::Iterator DirContainer::PushBack(const Item & item)
{
@@ -61,12 +117,7 @@ DirContainer::Iterator DirContainer::PushBack(const Item & item)
}
Iterator last_iter = table.insert(table.end(), item);
if( item.parent_id == -1 )
{
is_root = true;
root_iter = last_iter;
}
CheckSpecialFolder(item, last_iter);
log << log2 << "DirCont: added dir, url: " << item.url << ", id: " << item.id << ", parent_id: " << item.parent_id << logend;
@@ -80,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()
+16 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -33,12 +33,14 @@ public:
DirContainer();
Iterator GetRoot();
Iterator GetEtc();
Iterator Begin();
Iterator End();
SizeType Size();
bool Empty();
Iterator PushBack(const Item & item);
bool ChangeParent(long dir_id, long new_parent_id);
void Clear();
Iterator FindId(long id);
@@ -52,9 +54,12 @@ public:
ParentIterator FindFirstParent(long parent);
ParentIterator NextParent(ParentIterator pi);
void FindSpecialFolders();
private:
void CheckSpecialFolder(const Item & item, Iterator iter);
// main table with dirs
Table table;
@@ -64,9 +69,18 @@ private:
// root
Iterator root_iter;
// true if there is a etc dir in the table
bool is_etc;
// etc
Iterator etc_iter;
// indexes
TableId table_id;
TableParent table_parent;
// names of folders
static std::string dir_etc;
};
+194 -173
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -10,8 +10,19 @@
#include "dirs.h"
#include "error.h"
#include "log.h"
#include "db.h"
#include "data.h"
void Dirs::SetDb(Db * pdb)
{
db = pdb;
}
void Dirs::SetRequest(Request * prequest)
{
request = prequest;
}
void Dirs::Clear()
@@ -20,13 +31,29 @@ void Dirs::Clear()
}
bool Dirs::HasReadExecAccessForRoot(const Item & item)
{
// there must be at least one 'x' (for the root)
return (item.privileges & 01111) != 0; // !! in the future there'll be another 'x'
}
void Dirs::CheckRootDir()
{
DirContainer::Iterator i = dir_table.GetRoot();
if( i != dir_table.End() )
{
if( !HasReadExecAccessForRoot(*i) )
{
i->privileges = 0755;
log << log1 << "Dirs: there is no access for root (admin) to the root dir, setting 0755 for root dir" << logend;
db->EditPrivById(*i, i->id);
}
return;
}
log << log1 << "Dirs: there is no a root dir in the database (creating one)" << logend;
@@ -41,7 +68,7 @@ void Dirs::CheckRootDir()
// !! upewnic sie ze baza nie zmieni url (gdyby wczesniej juz byl w bazie pusty url)
// !! zrobic jakis wyjatek do wprowadzania roota?
if( db.AddItem(root) == Error::ok )
if( db->AddItem(root) == WINIX_ERR_OK )
{
dir_table.PushBack(root);
}
@@ -54,36 +81,9 @@ void Dirs::ReadDirs()
{
Clear();
db.GetDirs(dir_table);
db->GetDirs(dir_table);
CheckRootDir();
}
bool Dirs::GetRootDir(Item ** item)
{
DirContainer::Iterator root = dir_table.GetRoot();
if( root == dir_table.End() )
return false;
*item = &(*root);
return true;
}
bool Dirs::GetDir(const std::string & name, long parent, Item ** item)
{
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
for( ; i!=dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
if( i->second->url == name )
{
*item = &(*i->second);
return true;
}
return false;
dir_table.FindSpecialFolders();
}
@@ -102,62 +102,6 @@ return !name.empty();
// !! moze lepiej zwracac wskaznik do Item i kiedy nie ma katalogu to zwracac 0 ?
bool Dirs::GetDir(const std::string & path, Item ** item)
{
DirContainer::Iterator root = dir_table.GetRoot();
if( root == dir_table.End() )
// ops, we do not have a root dir
return false;
Item * pitem = &(*root);
std::string name;
const char * s = path.c_str();
while( ExtractName(s, name) )
{
if( !GetDir(name, pitem->id, &pitem) )
return false;
}
*item = pitem;
return true;
}
// !! ten interfejs jes bylejaki
// !! moze lepiej zwracac id i kiedy nie ma katalogu to -1 (przeciez to jest wartosc ktora nie moze pojawic sie w indeksie)
bool Dirs::GetDirId(const std::string & path, long * id)
{
Item * pitem;
if( !GetDir(path, &pitem) )
return false;
*id = pitem->id;
return true;
}
bool Dirs::GetDirId(const std::string & name, long parent, long * id)
{
Item * pitem;
if( !GetDir(name, parent, &pitem) )
return false;
*id = pitem->id;
return true;
}
bool Dirs::IsDir(long id)
@@ -173,20 +117,6 @@ return true;
bool Dirs::GetDirChilds(long parent, std::vector<Item> & childs_table)
{
if( parent != -1 && !IsDir(parent) )
return false;
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
for( ; i != dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
childs_table.push_back( *i->second );
return true;
}
bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_table)
{
if( parent != -1 && !IsDir(parent) )
@@ -201,10 +131,30 @@ return true;
}
DirContainer::ParentIterator Dirs::FindFirstParent(long parent_id)
{
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent_id);
return i;
}
DirContainer::ParentIterator Dirs::NextParent(DirContainer::ParentIterator i)
{
return dir_table.NextParent(i);
}
DirContainer::ParentIterator Dirs::ParentEnd()
{
return dir_table.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;
@@ -215,7 +165,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 )
@@ -231,55 +182,34 @@ DirContainer::Iterator i;
// with exceptions
Item * Dirs::GetDirT(const std::string & path)
bool Dirs::ChangeParent(long dir_id, long new_parent_id)
{
Item * pitem;
if( !GetDir(path, &pitem) )
throw Error(Error::incorrect_dir);
return pitem;
}
Item * Dirs::GetDirT(const std::string & name, long parent)
{
Item * pitem;
if( !GetDir(name, parent, &pitem) )
throw Error(Error::incorrect_dir);
return pitem;
}
long Dirs::GetDirIdT(const std::string & path)
{
long id;
if( !GetDirId(path, &id) )
throw Error(Error::incorrect_dir);
return id;
}
long Dirs::GetDirIdT(const std::string & name, long parent)
{
long id;
if( !GetDirId(name, parent, &id) )
throw Error(Error::incorrect_dir);
return id;
return dir_table.ChangeParent(dir_id, new_parent_id);
}
// !! nowy interfejs
/*
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;
}
}
@@ -294,6 +224,17 @@ return &(*root);
}
Item * Dirs::GetEtcDir()
{
DirContainer::Iterator etc = dir_table.GetEtc();
if( etc == dir_table.End() )
return 0;
return &(*etc);
}
Item * Dirs::GetDir(const std::string & name, long parent)
{
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
@@ -354,6 +295,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 = 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 = 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)
{
@@ -382,31 +402,32 @@ void Dirs::SplitPath(const std::string & path, std::string & dir, std::string &
}
void Dirs::DeleteDir(long id)
// !! dodac kasowanie z bazy
bool Dirs::DelDir(long dir_id)
{
DirContainer::ParentIterator pnext, p = dir_table.FindFirstParent(id);
for( ; p != dir_table.ParentEnd() ; p = pnext )
{
// this iterator p will be deleted by the next DeleteDir(p->second->id)
// (the next iterator we must calculate beforehand)
pnext = dir_table.NextParent(p);
DeleteDir(p->second->id);
}
if( db.DelDirById(id) == Error::ok )
dir_table.DelById(id);
if( data.mounts.CurrentMountType() == Mount::thread )
db.RemoveThread(id);
return dir_table.DelById(dir_id);
}
Error Dirs::AddDirectory(Item & item, bool add_to_dir_table)
{
if( item.type != Item::dir )
return WINIX_ERR_DIR_EXPECTED;
Error status = db->AddItem(item);
if( status == WINIX_ERR_OK )
{
Item * pdir = AddDir(item);
if( add_to_dir_table && request->dir_table.back()->id == item.parent_id )
request->dir_table.push_back(pdir);
}
return status;
}
+33 -40
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -17,8 +17,12 @@
#include "item.h"
#include "dircontainer.h"
#include "db.h"
#include "request.h"
// we do not support '..' in a path (for simplicity and security reasons)
class Dirs
{
@@ -27,63 +31,52 @@ public:
void Clear();
void ReadDirs();
// without any exceptions
// these methods return false in a case the path or name (with a specific parent) are invalid
// we do not support '..' in a path (for security reason)
void SetRequest(Request * prequest);
void SetDb(Db * pdb);
bool IsDir(long id);
// these methods return false if there is no such a dir
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);
bool DelDir(long dir_id);
bool GetRootDir(Item ** item);
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);
bool GetDir(const std::string & path, Item ** item);
bool GetDir(const std::string & name, long parent, Item ** item);
bool GetDirId(const std::string & path, long * id);
bool GetDirId(const std::string & name, long parent, long * id);
//!! ta nie bedzie chyba potrzebna
bool GetDirChilds(long parent, std::vector<Item> & childs_table); // only returns dir-children
bool GetDirChilds(long parent, std::vector<Item*> & childs_table); // only returns dir-children
bool MakePath(long id, std::string & path);
DirContainer::ParentIterator FindFirstParent(long parent_id);
DirContainer::ParentIterator NextParent(DirContainer::ParentIterator i);
DirContainer::ParentIterator ParentEnd();
// with an Error exception
// if the path or name are invalid these methods throw an exception
Item * GetDirT(const std::string & path);
Item * GetDirT(const std::string & name, long parent);
long GetDirIdT(const std::string & path);
long GetDirIdT(const std::string & name, long parent);
// !! nowy interfejs
// returns null if there is no a root dir
// these methods return null if there is no such a dir
// !! zmienic nazwy wskazujace ze operujemy tylko na lokalnej tablicy
Item * GetRootDir();
Item * GetEtcDir();
Item * GetDir(const std::string & name, long parent);
Item * GetDir(const std::string & path);
Item * GetDir(long id);
Item * AddDir(const Item & item);
static void SplitPath(const std::string & path, std::string & dir, std::string & file);
void DeleteDir(long id);
void CheckRootDir();
// !! jak juz wczesniejsze nazwy beda zmienione to tutaj damy AddDir()
Error AddDirectory(Item & item, bool add_to_dir_table = false);
private:
Request * request;
Db * db;
DirContainer dir_table;
bool ExtractName(const char * & s, std::string & name);
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);
bool HasReadExecAccessForRoot(const Item & item);
};
-47
View File
@@ -1,47 +0,0 @@
/*
* 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 "done.h"
Done::Done()
{
}
Done::Done(Code c) : code(c)
{
}
Done & Done::operator=(Code c)
{
code = c;
return *this;
}
bool Done::operator==(Code c) const
{
return code == c;
}
bool Done::operator!=(Code c) const
{
return code != c;
}
Done::operator int()
{
return static_cast<int>( code );
}
-51
View File
@@ -1,51 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucoredone
#define headerfilecmslucoredone
// what has been done
class Done
{
public:
enum Code
{
none = 0,
added_item,
edited_item,
deleted_item,
deleted_dir,
privileged_item,
added_dir,
added_thread,
defaulted_dir,
loggedout
};
Done();
Done(Code c);
Done & operator=(Code c);
bool operator==(Code c) const;
bool operator!=(Code c) const;
operator int();
private:
Code code;
};
#endif
-94
View File
@@ -1,94 +0,0 @@
/*
* 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 "error.h"
Error::Error()
{
code = unknown;
}
Error::Error(Code c) : code(c)
{
}
Error::Error(int i)
{
code = static_cast<Code>(i);
}
Error::Error(const Error & e)
{
code = e.code;
}
Error::operator int() const
{
return static_cast<int>(code);
}
Error & Error::operator=(Code c)
{
code = c;
return *this;
}
Error & Error::operator=(const Error & e)
{
code = e.code;
return *this;
}
bool Error::operator==(Code c) const
{
return code == c;
}
bool Error::operator!=(Code c) const
{
return code != c;
}
bool Error::operator==(const Error & e) const
{
return code == e.code;
}
bool Error::operator!=(const Error & e) const
{
return code != e.code;
}
std::ostream & operator<<(std::ostream & out, const Error & e)
{
out << static_cast<int>(e.code);
return out;
}
Log & operator<<(Log & out, const Error & e)
{
out << static_cast<int>(e.code);
return out;
}
+50 -60
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -13,74 +13,64 @@
#include <iostream>
#include "log.h"
#define WINIX_ERR_OK 0
//#define WINIX_ERR_INCORRECT_PATH 1
//#define WINIX_ERR_NO_POSTVAR 2
#define WINIX_ERR_INCORRECT_DIR 3
#define WINIX_ERR_CANT_CHANGE_USER 4
#define WINIX_ERR_CANT_CHANGE_GROUP 5
#define WINIX_ERR_CANT_CHANGE_PRIVILEGES 6
#define WINIX_ERR_PERMISSION_DENIED 7
#define WINIX_ERR_NO_ROOT_DIR 8
#define WINIX_ERR_NO_FUNCTION 9
#define WINIX_ERR_NO_ITEM 10
#define WINIX_ERR_UNKNOWN_PARAM 11
#define WINIX_ERR_MOUNT_UNKNOWN 12
#define WINIX_ERR_UNKNOWN_FILESYSTEM 13
#define WINIX_ERR_NO_MOUNTPOINT 14
//#define WINIX_ERR_MOUNT_NO_PARAM 15
#define WINIX_ERR_NO_THREAD 16
#define WINIX_ERR_EMPTY 17
#define WINIX_ERR_SPAM 18
#define WINIX_ERR_INCORRECT_REBUS 19
class Error
{
#define WINIX_ERR_NO_BOUNDARY 20
#define WINIX_ERR_BROKEN_INPUT 21
#define WINIX_ERR_INPUT_TOO_LARGE 22
#define WINIX_ERR_CANT_CREATE_FILE 23
public:
#define WINIX_ERR_NO_TICKET 24
enum Code
{
ok = 0,
incorrect_path,
db_fatal_error_during_connecting,
db_incorrect_query,
db_incorrent_result_status,
db_no_column,
db_no_item, // !! zamienic na no_item
db_incorrect_login,
db_more_than_one_login,
db_err_currval,
no_postvar,
incorrect_dir,
cant_change_user,
cant_change_group,
cant_change_privileges,
permision_denied, // !! permission_denied (dwa ss)
no_root_dir,
no_function, // !! zamienic na no_function
item_required, // !! zamienic na no_item (i usunac db_no_item)
unknown_param,
mount_unknown,
no_mountpoint,
mount_no_param,
no_thread,
unknown = 1000
};
Error();
Error(Code c);
Error(int i);
Error(const Error & e);
Error & operator=(Code c);
Error & operator=(const Error & e);
operator int() const;
bool operator==(Code c) const;
bool operator!=(Code c) const;
bool operator==(const Error & e) const;
bool operator!=(const Error & e) const;
friend std::ostream & operator<<(std::ostream & out, const Error & e);
friend Log & operator<<(Log & out, const Error & e);
#define WINIX_ERR_PASSWORDS_DIFFERENT 25
#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
private:
#define WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING 100
#define WINIX_ERR_DB_INCORRECT_QUERY 101
#define WINIX_ERR_DB_INCORRENT_RESULT_STATUS 102
#define WINIX_ERR_DB_NO_COLUMN 103
#define WINIX_ERR_DB_INCORRECT_LOGIN 104
#define WINIX_ERR_DB_MORE_THAN_ONE_LOGIN 105
#define WINIX_ERR_DB_ERR_CURRVAL 106
Code code;
#define WINIX_ERR_FILE_EXPECTED 107
#define WINIX_ERR_DIR_EXPECTED 108
};
//#define WINIX_ERR_UNKNOWN 1000
#define WINIX_NOTHING_TO_DO 109
typedef int Error;
-59
View File
@@ -1,59 +0,0 @@
/*
* 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 "function.h"
Function::Function()
{
code = FUN_NONE;
}
void Function::Clear()
{
code = FUN_NONE;
item.Clear();
}
Function::Function(const Function & f)
{
code = f.code;
item = f.item;
}
Function & Function::operator=(const Function & f)
{
code = f.code;
item = f.item;
return *this;
}
-81
View File
@@ -1,81 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucorefunction
#define headerfilecmslucorefunction
#include <iostream>
#include "item.h"
#define FUN_NONE 0
#define FUN_LS 1
#define FUN_CAT 2
#define FUN_NODE 3
#define FUN_EMACS 4
#define FUN_MKDIR 5
#define FUN_DEFAULT 6
#define FUN_PRIV 7
#define FUN_RM 8
#define FUN_LOGIN 9
#define FUN_LOGOUT 10
#define FUN_RUN 11
#define FUN_WHO 12
#define FUN_LAST 13
#define FUN_CREATETHREAD 14
#define FUN_THREAD 15
class Function
{
public:
/*
enum Code
{
none,
ls,
cat,
node,
emacs,
mkdir,
default,
priv,
rm,
login,
logout,
run,
who
};
Code code;
*/
/*
we do not use enum etc. because the code will be used with an application too
(application can set others values)
*/
int code;
Item item;
void Clear();
Function();
Function(const Function & f);
Function & operator=(const Function & f);
};
#endif
-58
View File
@@ -1,58 +0,0 @@
/*
* 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 "functioncodeparser.h"
#include "function.h"
#include "log.h"
bool FunctionCodeParser::ContentHasOneRow(const Item & item)
{
for(size_t i=0 ; i<item.content.size() ; ++i)
if( item.content[i] == '\n' )
return false;
return true;
}
int FunctionCodeParser::ParseValue(const char * s)
{
if( strncmp(s, "[fun:", 5) != 0 )
return FUN_NONE;
const char * send;
int result = strtol(s+5, (char**)&send, 10);
if( send==s+5 || strcmp(send, "]") != 0 )
return FUN_NONE;
log << log2 << "FCP: function code: " << result << logend;
return result;
}
int FunctionCodeParser::Parse(const Item & item)
{
// format: [fun:1]
// minimum size: 7 characters
if( item.content.size() < 7 )
return FUN_NONE;
if( !ContentHasOneRow(item) )
return FUN_NONE;
return ParseValue(item.content.c_str());
}
-34
View File
@@ -1,34 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucorefunctioncodeparser
#define headerfilecmslucorefunctioncodeparser
#include <cstring>
#include <cstdlib>
#include "item.h"
class FunctionCodeParser
{
bool ContentHasOneRow(const Item & item);
int ParseValue(const char * s);
public:
int Parse(const Item & item);
};
#endif
-186
View File
@@ -1,186 +0,0 @@
/*
* 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 "functionparser.h"
#include "log.h"
#include "item.h"
#include "error.h"
#include "data.h"
#include "db.h"
#include "request.h"
void FunctionParser::SkipEmptyString(const char * msg)
{
for( ; get_index != get_table_len && request.get_table[get_index].empty() ; ++get_index )
log << log3 << msg << logend;
}
void FunctionParser::ParseDirectories()
{
Item * pdir = data.dirs.GetRootDir();
if( !pdir )
{
// there is no the root dir
request.status = Error::no_root_dir;
return;
}
while( true )
{
request.dir_table.push_back( pdir );
log << log3 << "FP: Directory: ";
if( pdir->parent_id == -1 )
log << "(root)" << logend;
else
log << pdir->url << logend;
SkipEmptyString("FP: Directory: skipped empty string");
if( get_index == get_table_len )
break;
pdir = data.dirs.GetDir(request.get_table[get_index], pdir->id);
if( !pdir )
break;
++get_index;
}
}
void FunctionParser::ParseItem()
{
SkipEmptyString("FP: Item: skipped empty string");
if( get_index == get_table_len )
return;
// request.dir_table has at least one element
long parent_id = request.dir_table.back()->id;
const std::string & url = request.get_table[get_index];
request.status = db.GetItem(parent_id, url, request.item);
if( request.status == Error::ok )
{
++get_index;
request.is_item = true;
log << log3 << "FP: Item: id: " << request.item.id << ", url: " << request.item.url << logend;
}
else
log << log3 << "FP: No Item: url: " << url << logend;
}
void FunctionParser::ParseFunction()
{
SkipEmptyString("FP: Function: skipped empty string");
if( get_index == get_table_len )
return;
request.pfunction = data.functions.GetFunction(request.get_table[get_index]);
if( request.pfunction )
{
++get_index;
log << log3 << "FP: Function: " << request.pfunction->item.url << logend;
}
}
void FunctionParser::ParseParams()
{
while( true )
{
SkipEmptyString("FP: Params: skipped empty string");
if( get_index == get_table_len )
break;
request.param_table.push_back( &request.get_table[get_index] );
log << log3 << "FP: Params: " << request.get_table[get_index] << logend;
++get_index;
}
}
void FunctionParser::Parse()
{
request.status = Error::ok;
get_index = 0;
get_table_len = request.get_table.size();
request.pfunction = 0;
request.is_item = false;
ParseDirectories();
if( request.status != Error::ok )
return;
ParseFunction();
if( !request.pfunction )
{
ParseItem();
if( request.status != Error::ok )
return;
ParseFunction();
if( !request.pfunction && get_index != get_table_len )
{
request.status = Error::no_function;
log << log3 << "FP: Parse: unknown function: \"" << request.get_table[get_index] << "\"" << logend;
return;
}
}
ParseParams();
}
-147
View File
@@ -1,147 +0,0 @@
/*
* 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 "functions.h"
void Functions::Clear()
{
table.clear();
}
void Functions::ReadFunctions()
{
Clear();
Function f;
f.item.user_id = -1;
f.item.group_id = -1;
f.item.privileges = 0644;
f.item.parent_id = -1; // !! temporarily doesn't matter
f.item.id = -1;
f.item.type = Item::file;
// in the future we will read these functions from the database
f.code = FUN_LS;
f.item.url = "ls";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_CAT;
f.item.url = "cat";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_NODE;
f.item.url = "node";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_EMACS;
f.item.url = "emacs";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_MKDIR;
f.item.url = "mkdir";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_DEFAULT;
f.item.url = "default";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_PRIV;
f.item.url = "priv";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_RM;
f.item.url = "rm";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_LOGOUT;
f.item.url = "logout";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_LOGIN;
f.item.url = "login";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_RUN;
f.item.url = "run";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_WHO;
f.item.url = "who";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_LAST;
f.item.url = "last";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_CREATETHREAD;
f.item.url = "createthread";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_THREAD;
f.item.url = "thread";
table.insert( std::make_pair(f.item.url, f) );
// -----------
// FunctionCodeParser fc;
// fc.Parse(Item()); // temporary for linking
}
Function * Functions::GetFunction(const std::string & name)
{
Table::iterator i = table.find(name);
if( i == table.end() )
return 0;
return &(i->second);
}
// !! in the future there will be a special container where we can search through the Code object
Function * Functions::GetFunction(int code)
{
Table::iterator i = table.begin();
for( ; i != table.end() ; ++i )
{
if( i->second.code == code )
return &(i->second);
}
return 0;
}
-42
View File
@@ -1,42 +0,0 @@
/*
* 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.
*
*/
#ifndef headerfilecmslucorefunctions
#define headerfilecmslucorefunctions
#include <map>
#include <string>
#include "function.h"
class Functions
{
typedef std::map<std::string, Function> Table;
Table table;
public:
void Clear();
void ReadFunctions();
Function * GetFunction(const std::string & name);
Function * GetFunction(int code);
};
#endif
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
+4 -5
View File
@@ -1,14 +1,13 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "groups.h"
#include "db.h"
@@ -25,11 +24,11 @@ void Groups::Clear()
}
void Groups::ReadGroups()
void Groups::ReadGroups(Db * db)
{
Clear();
db.GetGroups(table);
db->GetGroups(table);
}
+5 -3
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -14,6 +14,8 @@
#include "group.h"
#include "ugcontainer.h"
#include "db.h"
class Groups
@@ -29,7 +31,7 @@ public:
Groups();
void Clear();
void ReadGroups();
void ReadGroups(Db * db);
Group * GetGroup(long group_id);
Group * GetGroup(const std::string & name);
long GetGroupId(const std::string & name);
+1208
View File
File diff suppressed because it is too large Load Diff
+221
View File
@@ -0,0 +1,221 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorehtmlfilter
#define headerfilecmslucorehtmlfilter
#include <string>
// max length of a name of a html tag (with terminating null)
#define WINIX_HTMLFILTER_ITEM_MAXLEN 30
// depth of the html tree
#define WINIX_HTMLFILTER_STACK_MAXLEN 100
// length of a buffer used for printing
// it should be at least: WINIX_HTMLFILTER_ITEM_MAXLEN+3
#define WINIX_HTMLFILTER_BUFFER_MAXLEN 2048
/*!
very lightweight filter for html
(without using any dynamic memory - some memory is allocated only at the beginning - in ctors)
this filter has O(n) complexity over the whole html string
such tags as: <script> <pre> <textarea> are treated in a special way
all characters between the opening and closing tag (<script>....</script>) are untouched
if the filter finds that there are not closed tags it will close them,
if the filter finds a closing tag which doesn't have an opening tag - it will skip it
tags which don't need to be closed: meta, input, br, img, link
look at CheckExceptions() method
the filter recognizes xml simple tags (with / at the end) such as: <br />
*/
class HTMLFilter
{
public:
// for checking orphans
enum Lang
{
lang_pl,
lang_cz,
lang_sk,
lang_none
};
enum OrphanMode
{
orphan_nbsp, // putting "&nbsp;" string
orphan_160space // putting 160 ascii code
};
HTMLFilter();
HTMLFilter(const HTMLFilter & f);
HTMLFilter & operator=(const HTMLFilter & f);
~HTMLFilter();
// main methods used for filtering
void Filter(const char * in, std::string & out);
void Filter(const std::string & in, std::string & out);
// insert a white space into long lines
// only between html tags
// skipped in such tags: script, pre, textarea
// break_after - after how many characters insert a space (0 - off)
void BreakLines(size_t break_after_);
// trimming white characters (with new lines)
// at the beginning, at the end and in the middle of a string
// only between html tags
// at the beginning and at the end only one space is left
// skipped in such tags: script, pre, textarea
// false by default
void TrimWhite(bool trim);
// first tabs in a tree
// default: 2 (spaces)
// set 0 to turn off
void InsertTabs(size_t tabsize);
// check 'orphans' for the specicic language
// if an orphan is detected then the non-break space ("&nbsp;" or ascii 160 code) will be put
// default disable (lang_none)
void CheckOrphans(Lang lang_, OrphanMode mode = orphan_nbsp);
// skipping some unsafe tags
// (script, iframe, frame, frameset, applet, head, meta, html, link, body, ...)
void SafeMode(bool safe_mode_);
protected:
struct Item
{
char name[WINIX_HTMLFILTER_ITEM_MAXLEN];
size_t name_len;
enum Type
{
opening,
closing,
simple,
special,
none
} type;
// is there a new line after this tag
bool new_line;
void Clear();
Item();
};
// only this method have direct access to the output string
// you can easily change the output from a std::string to something else
virtual void Put(const char * str, const char * end);
Item & GetItem(size_t i);
Item & LastItem();
int ToLower(int c);
bool IsNameEqual(const char * name1, const char * name2);
bool IsNameEqual(const char * name1, const char * name2, size_t len);
bool IsLastTag(const char * name);
bool IsTagSafe(const char * tag);
int CheckOrphan(const char * str, const char * end, const char * orphan);
bool CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2);
bool CheckOrphanLangPl(const char * str, const char * end);
bool CheckOrphanLangCz(const char * str, const char * end);
bool CheckOrphan(const char * str, const char * end);
bool IsWhite(int c);
void SkipWhite();
void SkipWhiteLines();
void SkipWhiteWithFirstNewLine();
bool IsClosingTagForLastItem();
virtual bool IsOpeningTagMark();
virtual bool IsOpeningCommentaryTagMark();
size_t OpeningCommentaryTagMarkSize();
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
bool SkipCommentaryTagIfExists();
const char * SkipItemCheckXmlSimple();
void PopStack();
bool PushStack();
virtual bool IsValidCharForName(int c);
void CheckNewLine();
virtual void CheckExceptions();
void CheckStackPrintRest();
void AddForgottenTags();
void CheckClosingTags();
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
void ReadNormalText();
bool PrintRest();
void PrintItem(const char * start, const char * end);
void ReadItemName();
bool ReadItem();
virtual void Init();
virtual void Deinit();
void Read();
size_t PutNormalTextTrimFillBuffer(const char * & str, const char * & end);
size_t PutNormalTextFillBuffer(const char * & str, const char * & end);
virtual void PutNormalText(const char * str, const char * end);
virtual void PutNormalTextTrim(const char * str, const char * end);
void PutLastTagWithClosingTag();
virtual void PutOpeningTagMark();
virtual void PutClosingTagMark();
virtual void PutTagName(const char * name);
virtual void PutOpeningTag(const char * start, const char * end);
virtual void PutClosingTag(const char * tag);
size_t PutTabsToBuffer(size_t index, size_t len);
size_t PutNonBreakSpaceToBuffer(size_t index);
void PutTabs(size_t len);
void PutNewLine();
const char * pchar;
Item empty;
Item * pstack; // stack pointer
size_t stack_len; // length of the stack
char * buffer; // buffer used when printing
std::string * out_string;
bool last_new_line;
size_t break_after; // insert a space into long lines after break_after characters
bool trim_white; // trimming white characters
size_t tab_size;
Lang lang; // current language for checking orphans
OrphanMode orphan_mode;
bool safe_mode; // skipping some unsafe tags
};
#endif
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
+54 -20
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -18,28 +18,35 @@
struct Item
{
long id;
long parent_id;
long user_id;
long group_id;
int privileges;
std::string guest_name; // used as a user name when user_id is equal -1
// used as a user name when user_id is equal -1
std::string guest_name;
long modification_user_id; // who has modified the item last (not taken into account when checking permissions)
int privileges;
tm date_creation;
tm date_modification;
std::string subject;
std::string content;
long content_id; // used by the database
std::string url;
enum ContentType
{
ct_text = 0,
ct_formatted_text,
ct_html,
ct_bbcode,
ct_raw
};
// 0 - simple txt
// 1 - formatted txt
// 2 - html
// 3 - bbcode
int content_type;
ContentType content_type;
@@ -48,29 +55,54 @@ enum Type
dir = 0,
file = 1,
none = 1000
none = 1000 // !! pozbyc sie tego
};
Type type;
//item_type;
long parent_id;
long default_item;
// used by the database
// !! moze da sie w ogole z tego zrezygnowac?
long content_id;
// external static file authorized by winix
enum Auth
{
auth_none = 0, /* there is not an external file */
auth_image = 1, /* png, gif, jpg - only types available to render by a web browser*/
auth_document = 2, /* pdf doc xls txt */
auth_other = 3 /* other file */
};
Auth auth;
std::string auth_path; // path to a file (if auth!=auth_none)
// methods
Item()
{
Clear();
}
void SetDateToNow()
{
time_t t = std::time(0);
date_creation = *std::localtime( &t );
date_modification = date_creation;
}
void SetDateModifyToNow()
{
time_t t = std::time(0);
date_modification = *std::localtime( &t );
}
void Clear()
{
@@ -79,6 +111,7 @@ void Clear()
user_id = -1;
group_id = -1;
privileges = 0;
modification_user_id = -1;
guest_name.clear();
@@ -86,7 +119,7 @@ void Clear()
content.clear();
url.clear();
content_type = 0;
content_type = ct_formatted_text;
type = none;
parent_id = -1;
@@ -94,9 +127,10 @@ void Clear()
content_id = -1;
time_t t = std::time(0);
date_creation = *std::localtime( &t );
date_modification = date_creation;
auth = auth_none;
auth_path.clear();
SetDateToNow();
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
+372
View File
@@ -0,0 +1,372 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "loadavg.h"
#include "log.h"
LoadAvg::LoadAvg()
{
current1.Clear();
current5.Clear();
current15.Clear();
cache_load1 = 0.0;
cache_load5 = 0.0;
cache_load15 = 0.0;
cache_req_per_sec1 = 0.0;
cache_req_per_sec5 = 0.0;
cache_req_per_sec15 = 0.0;
was_stop_request = false;
CreateTable();
}
LoadAvg & LoadAvg::operator=(const LoadAvg & l)
{
current1 = l.current1;
current5 = l.current5;
current15 = l.current15;
cache_load1 = l.cache_load1;
cache_load5 = l.cache_load5;
cache_load15 = l.cache_load15;
cache_req_per_sec1 = l.cache_req_per_sec1;
cache_req_per_sec5 = l.cache_req_per_sec5;
cache_req_per_sec15 = l.cache_req_per_sec15;
was_stop_request = l.was_stop_request;
CreateTable();
return *this;
}
LoadAvg::LoadAvg(const LoadAvg & l)
{
operator=(l);
}
LoadAvg::~LoadAvg()
{
delete [] tab1;
delete [] tab5;
delete [] tab15;
}
void LoadAvg::CreateTable(size_t seconds, size_t granularity, Times* & tab, size_t & len)
{
len = (seconds / granularity) + 1; // rounding up (len mininum is 1)
tab = new Times[len];
for(size_t i=0 ; i<len ; ++i)
{
tab[i].Clear();
tab[i].dp = granularity; // at the beginning we assume the pause for all items
}
}
void LoadAvg::CreateTable()
{
CreateTable(60, WINIX_LOADAVG_GRANULARITY1, tab1, len1);
CreateTable(60 * 5, WINIX_LOADAVG_GRANULARITY5, tab5, len5);
CreateTable(60 * 15, WINIX_LOADAVG_GRANULARITY15, tab15, len15);
}
void LoadAvg::MoveTab(Times * tab, size_t len)
{
if( len > 1 )
{
for(size_t i=0 ; i<len-1 ; ++i)
tab[i] = tab[i+1];
}
tab[len-1].Clear();
}
void LoadAvg::UpdateTimer1()
{
MoveTab(tab1, len1);
tab1[len1-1] = current1;
current1.Clear();
cache_load1 = 0.0;
cache_req_per_sec1 = 0.0;
}
void LoadAvg::UpdateTimer5()
{
MoveTab(tab5, len5);
tab5[len5-1] = current5;
current5.Clear();
cache_load5 = 0.0;
cache_req_per_sec5 = 0.0;
}
void LoadAvg::UpdateTimer15()
{
MoveTab(tab15, len15);
tab15[len15-1] = current15;
current15.Clear();
cache_load15 = 0.0;
cache_req_per_sec15 = 0.0;
}
void LoadAvg::CheckTimers()
{
if( current1.dr + current1.dp > (double)WINIX_LOADAVG_GRANULARITY1 )
UpdateTimer1();
if( current5.dr + current5.dp > (double)WINIX_LOADAVG_GRANULARITY5 )
UpdateTimer5();
if( current15.dr + current15.dp > (double)WINIX_LOADAVG_GRANULARITY15 )
UpdateTimer15();
}
void LoadAvg::StartRequest()
{
clock_gettime(CLOCK_REALTIME, &start_req);
if( was_stop_request )
{
double dp = (start_req.tv_sec - stop_req.tv_sec);
dp += double(start_req.tv_nsec - stop_req.tv_nsec) / 1000000000.0; // make sure that tv_nsec has signed type
current1.dp += dp;
current5.dp += dp;
current15.dp += dp;
CheckTimers();
}
}
void LoadAvg::StopRequest()
{
clock_gettime(CLOCK_REALTIME, &stop_req);
double dr = (stop_req.tv_sec - start_req.tv_sec);
dr += double(stop_req.tv_nsec - start_req.tv_nsec) / 1000000000.0; // make sure that tv_nsec has signed type
current1.dr += dr;
current5.dr += dr;
current15.dr += dr;
current1.req += 1;
current5.req += 1;
current15.req += 1;
log << log2 << "LA: request took: " << dr << "s" << logend;
was_stop_request = true;
}
void LoadAvg::SumTab(Times * tab, size_t len, double expected, Times & t)
{
size_t i = len;
while( i-- > 0 && t.dr+t.dp < expected )
{
t.dr += tab[i].dr;
t.dp += tab[i].dp;
t.req += tab[i].req;
}
}
void LoadAvg::Calculate1()
{
Times t = current1;
SumTab(tab1, len1, 60.0, t);
if( t.dr+t.dp == 0.0 )
{
cache_load1 = 0.0;
cache_req_per_sec1 = 0.0;
}
else
{
cache_load1 = t.dr / (t.dr+t.dp);
cache_req_per_sec1 = t.req / (t.dr+t.dp);
}
}
void LoadAvg::Calculate5()
{
Times t = current5;
SumTab(tab5, len5, 60.0 * 5, t);
if( t.dr+t.dp == 0.0 )
{
cache_load5 = 0.0;
cache_req_per_sec5 = 0.0;
}
else
{
cache_load5 = t.dr / (t.dr+t.dp);
cache_req_per_sec5 = t.req / (t.dr+t.dp);
}
}
void LoadAvg::Calculate15()
{
Times t = current15;
SumTab(tab15, len15, 60.0 * 15, t);
if( t.dr+t.dp == 0.0 )
{
cache_load15 = 0.0;
cache_req_per_sec15 = 0.0;
}
else
{
cache_load15 = t.dr / (t.dr+t.dp);
cache_req_per_sec15 = t.req / (t.dr+t.dp);
}
}
double LoadAvg::LoadAvgNow()
{
double load = 0.0;
double dr = current1.dr;
double dp = current1.dp;
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
{
dr += tab1[len1-1].dr;
dp += tab1[len1-1].dp;
}
if( dr + dp != 0.0 )
load = dr / (dr + dp);
return load;
}
double LoadAvg::LoadAvg1()
{
if( cache_load1 != 0.0 )
return cache_load1;
Calculate1();
return cache_load1;
}
double LoadAvg::LoadAvg5()
{
if( cache_load5 != 0.0 )
return cache_load5;
Calculate5();
return cache_load5;
}
double LoadAvg::LoadAvg15()
{
if( cache_load15 != 0.0 )
return cache_load15;
Calculate15();
return cache_load15;
}
double LoadAvg::ReqPerSecNow()
{
double req_per_sec = 0.0;
double dr = current1.dr;
double dp = current1.dp;
double req = current1.req;
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
{
dr += tab1[len1-1].dr;
dp += tab1[len1-1].dp;
req += tab1[len1-1].req;
}
if( dr + dp != 0.0 )
req_per_sec = req / (dr + dp);
return req_per_sec;
}
double LoadAvg::ReqPerSec1()
{
if( cache_req_per_sec1 != 0.0 )
return cache_req_per_sec1;
Calculate1();
return cache_req_per_sec1;
}
double LoadAvg::ReqPerSec5()
{
if( cache_req_per_sec5 != 0.0 )
return cache_req_per_sec5;
Calculate5();
return cache_req_per_sec5;
}
double LoadAvg::ReqPerSec15()
{
if( cache_req_per_sec15 != 0.0 )
return cache_req_per_sec15;
Calculate15();
return cache_req_per_sec15;
}
Executable
+114
View File
@@ -0,0 +1,114 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreloadavg
#define headerfilecmslucoreloadavg
#include <ctime>
// in seconds
#define WINIX_LOADAVG_GRANULARITY1 2
#define WINIX_LOADAVG_GRANULARITY5 15
#define WINIX_LOADAVG_GRANULARITY15 45
class LoadAvg
{
public:
LoadAvg();
~LoadAvg();
LoadAvg & operator=(const LoadAvg & l);
LoadAvg(const LoadAvg & l);
void StartRequest();
void StopRequest();
double LoadAvgNow(); // load average withing last WINIX_LOADAVG_GRANULARITY1 seconds
double LoadAvg1();
double LoadAvg5();
double LoadAvg15();
double ReqPerSecNow();
double ReqPerSec1();
double ReqPerSec5();
double ReqPerSec15();
private:
struct Times
{
double dr; // time for the request (in seconds)
double dp; // time for the pause between requestes (in seconds)
long req; // how many requests
void Clear()
{
dr = 0.0;
dp = 0.0;
req = 0;
}
Times & operator=(const Times & t)
{
dr = t.dr;
dp = t.dp;
req = t.req;
return *this;
}
};
void CheckTimers();
void UpdateTimer1();
void UpdateTimer5();
void UpdateTimer15();
Times current1;
Times current5;
Times current15;
void CreateTable(size_t seconds, size_t granulatiry, Times* & tab, size_t & len);
void CreateTable();
void MoveTab(Times * tab, size_t len);
void SumTab(Times * tab, size_t len, double expected, Times & t);
void Calculate1();
void Calculate5();
void Calculate15();
bool was_stop_request;
timespec start_req, stop_req;
Times * tab1;
size_t len1;
Times * tab5;
size_t len5;
Times * tab15;
size_t len15;
double cache_load1;
double cache_load5;
double cache_load15;
double cache_req_per_sec1;
double cache_req_per_sec5;
double cache_req_per_sec15;
};
#endif
+234
View File
@@ -0,0 +1,234 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "locale.h"
#include "log.h"
Locale::Locale()
{
loc_tab.resize(lang_unknown);
default_lang = lang_en;
current_lang = lang_en;
}
void Locale::AddLocale(Lang lang)
{
ConfParser::TableSingle::iterator i = loc_parser.table_single.begin();
for( ; i != loc_parser.table_single.end() ; ++i)
loc_tab[lang][i->first] = i->second;
}
void Locale::ReadFile(const char * dir, const char * dir_def, Lang lang, const char * file)
{
if( static_cast<size_t>(lang) >= loc_tab.size() )
{
// ops, something wrong
return;
}
loc_tab[lang].clear();
bool read = false;
if( dir_def && ReadFile(dir_def, lang, file) )
read = true;
if( dir && ReadFile(dir, lang, file) )
read = true;
if( !read )
log << log1 << "Locale: can't open locale's file: " << file << logend;
}
bool Locale::ReadFile(const char * dir, Lang lang, const char * file)
{
bool read = false;
file_name = dir;
file_name += '/';
file_name += file;
loc_parser.SplitSingle(true);
if( loc_parser.Parse(file_name) == ConfParser::ok )
{
read = true;
AddLocale(lang);
log << log3 << "Locale: read locale from: " << file_name << logend;
}
return read;
}
void Locale::Read(const char * dir, const char * dir_def)
{
ReadFile(dir, dir_def, lang_pl, "pl");
ReadFile(dir, dir_def, lang_en, "en");
}
void Locale::Read(const std::string & dir, const std::string & dir_def)
{
if( dir_def.empty() )
Read(dir.c_str());
else
Read(dir.c_str(), dir_def.c_str());
}
void Locale::SetLang(Lang lang)
{
current_lang = lang;
}
Locale::Lang Locale::GetLang()
{
return current_lang;
}
void Locale::SetLangDef(Lang lang)
{
default_lang = lang_en;
}
bool Locale::IsKey(const std::string & key) const
{
return IsKey(key, current_lang);
}
bool Locale::IsKey(const std::string & key, Lang lang) const
{
if( static_cast<size_t>(lang) >= loc_tab.size() )
{
// ops, something wrong
return false;
}
// looking in the lang language
ConfParser::TableSingle::const_iterator i = loc_tab[lang].find(key);
if( i != loc_tab[lang].end() )
return true;
if( lang == default_lang )
return false;
if( static_cast<size_t>(default_lang) >= loc_tab.size() )
{
// ops, something wrong
return false;
}
// looking in a default language
i = loc_tab[default_lang].find(key);
if( i != loc_tab[default_lang].end() )
return true;
// there is no such a key
return false;
}
const std::string & Locale::Get(const std::string & key) const
{
return Get(key, current_lang);
}
const std::string & Locale::Get(const std::string & key, Lang lang) const
{
if( static_cast<size_t>(lang) >= loc_tab.size() )
{
// ops, something wrong
return empty;
}
// looking in the lang language
ConfParser::TableSingle::const_iterator i = loc_tab[lang].find(key);
if( i != loc_tab[lang].end() )
return i->second;
if( lang == default_lang )
return empty;
if( static_cast<size_t>(default_lang) >= loc_tab.size() )
{
// ops, something wrong
return empty;
}
// looking in a default language
i = loc_tab[default_lang].find(key);
if( i != loc_tab[default_lang].end() )
return i->second;
// there is no such a key
return empty;
}
Locale::Lang Locale::StrToLang(const std::string & str)
{
if( str == "en" )
return lang_en;
else
if( str == "pl" )
return lang_pl;
return lang_unknown;
}
const char * Locale::LangToStr(Lang lang)
{
static char buffer[30];
switch(lang)
{
case lang_en:
sprintf(buffer, "en");
break;
case lang_pl:
sprintf(buffer, "pl");
break;
default:
sprintf(buffer, "unknown");
}
return buffer;
}
size_t Locale::Size()
{
return loc_tab.size();
}
Executable
+71
View File
@@ -0,0 +1,71 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorelocale
#define headerfilecmslucorelocale
#include "confparser.h"
#include <vector>
#include <string>
// !! locale nie powinny byc w templates?
class Locale
{
public:
enum Lang
{
lang_en = 0,
lang_pl,
lang_unknown // should be last
};
Locale();
void Read(const char * dir, const char * dir_def = 0);
void Read(const std::string & dir, const std::string & dir_def);
bool IsKey(const std::string & key) const;
bool IsKey(const std::string & key, Lang lang) const;
const std::string & Get(const std::string & key) const;
const std::string & Get(const std::string & key, Lang lang) const;
// default is english
void SetLang(Lang lang);
Lang GetLang();
// which language is used instead if there is no a key in an other language
// default: lang_en
void SetLangDef(Lang lang);
static Lang StrToLang(const std::string & str);
static const char * LangToStr(Lang lang);
size_t Size();
private:
void AddLocale(Lang lang);
void ReadFile(const char * dir, const char * dir_def, Lang lang, const char * file);
bool ReadFile(const char * dir, Lang lang, const char * file);
std::vector<ConfParser::TableSingle> loc_tab;
ConfParser loc_parser;
std::string file_name;
std::string empty;
Lang default_lang;
Lang current_lang;
};
#endif
+81 -16
View File
@@ -1,31 +1,44 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "log.h"
#include <ctime>
#include <string.h>
Log::Log()
{
log_level = 3;
current_level = 4; // nothing to log (call Init() first)
item = 0;
item_save = 1;
lines = 0;
}
void Log::Init(int log_l, const std::string & log_f, bool log_std)
void Log::Init(int log_l, const std::string & log_f, bool log_std, int log_request)
{
log_level = log_l;
log_file = log_f;
log_stdout = log_std;
item_save = log_request;
OpenFile();
}
void Log::OpenFile()
{
if( !log_file.empty() )
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
}
void Log::PutDate(Manipulators m)
{
@@ -45,6 +58,7 @@ void Log::PutDate(Manipulators m)
Log & Log::operator<<(const char * s)
{
if( !s )
@@ -56,6 +70,7 @@ return *this;
}
Log & Log::operator<<(const std::string & s)
{
buffer << s;
@@ -64,6 +79,23 @@ Log & Log::operator<<(const std::string & s)
}
Log & Log::operator<<(const std::string * s)
{
buffer << *s;
return *this;
}
Log & Log::operator<<(const void * s)
{
buffer << s;
return *this;
}
Log & Log::operator<<(int s)
{
buffer << s;
@@ -72,6 +104,7 @@ Log & Log::operator<<(int s)
}
Log & Log::operator<<(long s)
{
buffer << s;
@@ -90,6 +123,7 @@ Log & Log::operator<<(char s)
}
Log & Log::operator<<(size_t s)
{
buffer << s;
@@ -98,6 +132,7 @@ Log & Log::operator<<(size_t s)
}
Log & Log::operator<<(double s)
{
buffer << s;
@@ -105,13 +140,34 @@ Log & Log::operator<<(double s)
return *this;
}
Log & Log::operator<<(Manipulators m)
{
switch(m)
{
case logend:
buffer << '\n';
lines += 1;
break;
case logsavenow:
SaveLog();
buffer.str( "" );
item = 0;
lines = 0;
break;
case logsave:
item += 1;
if( item >= item_save || lines > 3000 )
{
SaveLog();
buffer.str( "" );
item = 0;
lines = 0;
}
break;
case log1:
@@ -131,36 +187,45 @@ return *this;
}
void Log::SystemErr(int err)
{
(*this) << "errno: " << err;
const char * err_msg = strerror(err);
if( err_msg )
(*this) << " (" << err_msg << ")";
}
void Log::SaveLog()
{
int attempt = 2;
if( current_level > log_level )
return;
if( log_stdout )
std::cout << buffer.str() << std::endl;
const std::string & source = buffer.str();
if( source.empty() )
return;
if( log_stdout )
std::cout << source;
if( log_file.empty() )
return;
std::ofstream file;
do
if( !file )
{
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
file.close();
file.clear();
// if( !file )
// sleep(1);
}
while( --attempt > 0 && !file );
OpenFile();
if( !file )
return;
}
file << buffer.str() << std::endl;
file << source << std::endl;
}
+13 -4
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -19,7 +19,7 @@
// !! dodac manipulator logsave, logi zostana zapisane pod koniec wykonywania jednego requesta (albo po kilku w zaleznosci od jakiejs opcji w konfigu)
// logsave zostanie wywolane w requestcontroller.cpp przy konczeniu wykonywania requesta
enum Manipulators { logend, log1, log2, log3 };
enum Manipulators { logsave, logsavenow, logend, log1, log2, log3 };
@@ -27,17 +27,24 @@ class Log
{
std::ostringstream buffer;
int log_level, current_level;
int item, item_save;
std::string log_file;
bool log_stdout;
std::ofstream file;
int lines;
void OpenFile();
public:
Log();
void Init(int log_l, const std::string & log_f, bool log_std);
void Init(int log_l, const std::string & log_f, bool log_std, int log_request);
void PutDate(Manipulators m);
Log & operator<<(const char * s);
Log & operator<<(const void * s);
Log & operator<<(const std::string * s);
Log & operator<<(const std::string & s);
Log & operator<<(int s);
Log & operator<<(long s);
@@ -46,6 +53,8 @@ public:
Log & operator<<(double s);
Log & operator<<(Manipulators m);
void SystemErr(int err);
void SaveLog();
};
-124
View File
@@ -1,124 +0,0 @@
/*
* 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 <cstdlib>
#include <ctime>
#include <signal.h>
#include <iostream>
#include "requestcontroller.h"
#include "data.h"
#include "log.h"
#include "request.h"
#include "db.h"
#include "config.h"
#include "notify.h"
// singletons
// first 'data' then 'log' then 'request'
Data data;
Log log;
Log nlog; // notify log (used by another thread)
Request request;
Db db;
Config config;
RequestController req_controller;
Notify notify;
void signal_term(int)
{
log << log1 << "cmslu stopped" << logend;
exit(0);
}
void signal_hup(int)
{
log << log1 << "SIGHUP received" << logend;
data.signal_hup = true;
config.ReadConfig(false); /* errors not to stdout */
}
void print_syntax()
{
std::cout << "Syntax:" << std::endl;
std::cout << " cmslu.fcgi config_file" << std::endl;
}
int main(int argv, char ** argc)
{
std::srand(std::time(0));
if( argv != 2 )
{
print_syntax();
return 1;
}
data.config_file = argc[1];
if( !config.ReadConfig(true) ) /* errors to stdout */
return 2;
// closing descriptors only at the beginning
// !! temporary we do not close standard output for errors
// client postgresql uses it for reporting warnings (I don't know why)
//close(2);
if( !data.log_stdout )
{
close(1);
data.stdout_is_closed = true;
}
log.Init(data.log_level, data.log_file, data.log_stdout);
nlog.Init(data.log_level, data.log_notify_file, false);
db.Init(data.db_database, data.db_user, data.db_pass);
request.Init();
if( !req_controller.Init() )
return 1;
if( !notify.Init(data.templates) )
return 2;
signal(SIGTERM, signal_term);
signal(SIGINT, signal_term);
signal(SIGHUP, signal_hup);
while( true )
{
//log << log2 << "checking for table consistency:" << logend;
// !! zrobic wyjatek dla root
//db.CheckAllUrlSubject();
log << log1 << "cmslu started" << logend;
req_controller.Loop();
if( data.signal_hup )
data.signal_hup = false;
}
return 0;
}
+433 -53
View File
@@ -1,12 +1,14 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include "misc.h"
#include "log.h"
@@ -48,11 +50,33 @@ return false;
}
void CorrectUrl(Item & item)
// this function checks how many dots there are in the url
// if there are more than one (last) dot then the first dots will be changed into '_'
void CorrectUrlDots(std::string & url)
{
size_t i = url.size();
bool was_dot = false;
while( i-- > 0 )
{
if( url[i] == '.' )
{
if( was_dot )
// only one dot is allowed
url[i] = '_';
was_dot = true;
}
}
}
void CorrectUrlChars(std::string & url)
{
std::string::iterator i;
for(i = item.url.begin(); i!=item.url.end() ; ++i)
for(i=url.begin(); i != url.end() ; ++i)
{
if( !CorrectUrlChar(*i) )
{
@@ -64,51 +88,35 @@ std::string::iterator i;
*i = '_';
}
}
ToSmall(item.url);
if( item.url.empty() )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
else
if( item.url[0] >= '0' && item.url[0] <= '9' )
// url must begin with a letter
item.url.insert(item.url.begin(), '_');
}
void SetUrlFromSubject(Item & item)
void CorrectUrlOnlyAllowedChar(std::string & url)
{
item.url = item.subject;
CorrectUrl(item);
CorrectUrlDots(url);
CorrectUrlChars(url);
ToSmall(url);
Trim(url, '_');
/*
std::string::iterator i;
item.url.clear();
for(i = item.subject.begin(); i!=item.subject.end() ; ++i)
if( url.empty() || url == "." )
{
int c = ChangeLocalChar(*i);
// !! brakuje config->
//if( config->item_url_empty.empty() )
url = "unnamed";
//else
//{
// url = config->item_url_empty;
if( (c >= 'a' && c <='z') ||
(c >= 'A' && c <='Z') ||
(c >= '0' && c <='9') ||
(c == '(' || c == ')' || c == '.' || c == ',' || c == '_' )
)
{
item.url += c;
}
else
item.url += '_';
// CorrectUrlDots(url);
// CorrectUrlChars(url);
// ToSmall(url);
// we don't trim here and the string will not be empty
//}
}
if( item.url.empty() )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
else
if( item.url[0] >= '0' && item.url[0] <= '9' )
if( url[0] >= '0' && url[0] <= '9' )
// url must begin with a letter
item.url.insert(item.url.begin(), '_');
*/
url.insert(url.begin(), '_');
}
@@ -211,14 +219,17 @@ void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in)
std::string::const_iterator i;
int was_enter = 0; // how many enteres there were before
if( in.empty() )
return;
out << "<p>";
for(i = in.begin() ; i != in.end() ; ++i)
// skipping first new line characters
for(i = in.begin() ; i != in.end() && (*i==13 || *i==10) ; ++i);
for( ; i != in.end() ; ++i )
{
if( !HtmlTryChar(out, *i) )
{
if( *i == 13 )
// skipping stupid characters (\r\n\ in dos mode)
if( *i == 13 ) // skipping stupid characters (\r\n\ in dos mode)
continue;
if( *i == 10 )
@@ -233,10 +244,11 @@ int was_enter = 0; // how many enteres there were before
if( was_enter > 1 )
out << "</p>\n<p>";
out << *i;
was_enter = 0;
}
}
if( !HtmlTryChar(out, *i) )
out << *i;
}
out << "</p>\n";
@@ -253,6 +265,29 @@ return out.str();
}
const char * DateToStr(int year, int month, int day)
{
static const char * month_letter[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" };
static char buffer[100];
--month;
if( month < 0 )
month = 0;
if( month > 11 )
month = 11;
if( year == 0 )
sprintf(buffer, "%s %02d", month_letter[month], day);
else
sprintf(buffer, "%02d %s %02d", year, month_letter[month], day);
// warning: not thread safe (we do not use threads)
return buffer;
}
const char * DateToStr(int year, int month, int day, int hour, int min, int sec)
{
static const char * month_letter[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" };
@@ -267,9 +302,9 @@ static char buffer[100];
month = 11;
if( year == 0 )
sprintf(buffer, "%s.%02d %02d:%02d:%02d", month_letter[month], day, hour, min, sec);
sprintf(buffer, "%s %02d %02d:%02d:%02d", month_letter[month], day, hour, min, sec);
else
sprintf(buffer, "%02d.%s.%02d %02d:%02d:%02d", year, month_letter[month], day, hour, min, sec);
sprintf(buffer, "%02d %s %02d %02d:%02d:%02d", year, month_letter[month], day, hour, min, sec);
// warning: not thread safe (we do not use threads)
return buffer;
@@ -290,6 +325,55 @@ return DateToStr(ptm);
}
const char * DateToStrWithoutHours(tm * ptm)
{
return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday);
}
const char * DateToStrWithoutHours(time_t t)
{
tm * ptm = std::localtime(&t);
return DateToStrWithoutHours(ptm);
}
// this format is used with cookies
const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec)
{
static const char * month_str[]={ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static char buffer[100];
--month;
if( month < 0 )
month = 0;
if( month > 11 )
month = 11;
sprintf(buffer, "%02d-%s-%04d %02d:%02d:%02d", day, month_str[month], year, hour, min, sec);
return buffer;
}
const char * DateToStrCookie(tm * ptm)
{
return DateToStrCookie(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
}
const char * DateToStrCookie(time_t t)
{
tm * ptm = std::localtime(&t);
return DateToStrCookie(ptm);
}
const char * IpToStr(unsigned int ip_)
{
static char buffer[100];
@@ -308,9 +392,19 @@ return buffer;
}
const char * ToStr(int value)
{
static char buffer[100];
sprintf(buffer, "%d", value);
return buffer;
}
bool IsWhite(int s)
{
if( s==' ' || s=='\t' || s==13 )
if( s==' ' || s=='\t' || s==13 || s==160 )
return true;
return false;
@@ -348,18 +442,107 @@ std::string::size_type i;
}
void Trim(std::string & s, char c)
{
std::string::size_type i;
if( s.empty() )
return;
// looking for the 'c' characters at the end
for(i=s.size()-1 ; i>0 && s[i]==c ; --i);
if( i==0 && s[i]==c )
{
// the whole string has the 'c' characters
s.clear();
return;
}
// deleting 'c' characters at the end
if( i != s.size() - 1 )
s.erase(i+1, std::string::npos);
// looking for the 'c' characters at the beginning
for(i=0 ; i<s.size() && s[i]==c ; ++i);
// deleting the 'c' characters at the beginning
if( i != 0 )
s.erase(0, i);
}
const char * SkipWhite(const char * s)
{
while( IsWhite(*s) )
++s;
return s;
}
int ToSmall(int c)
{
if( c>='A' && c<='Z' )
c = c - 'A' + 'a';
return c;
}
void ToSmall(std::string & s)
{
std::string::size_type i;
for(i=0 ; i<s.size() ; ++i)
{
if( s[i]>='A' && s[i]<='Z' )
s[i] = s[i] - 'A' + 'a';
}
s[i] = ToSmall(s[i]);
}
bool IsSubString(const char * short_str, const char * long_str)
{
while( *short_str && *long_str && *short_str == *long_str )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
bool IsSubStringNoCase(const char * short_str, const char * long_str)
{
while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
bool EqualNoCase(const char * str1, const char * str2)
{
while( *str1 && *str2 && ToSmall(*str1) == ToSmall(*str2) )
{
++str1;
++str2;
}
if( *str1 == 0 && *str2 == 0 )
return true;
return false;
}
bool ValidateEmail(const std::string & email)
{
@@ -402,3 +585,200 @@ bool ValidateEmail(const std::string & email)
return correct;
}
bool IsFile(const char * file)
{
struct stat sb;
return (stat(file, &sb) == 0);
}
bool IsFile(const std::string & file)
{
return IsFile(file.c_str());
}
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);
}
// 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);
}
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
const char * GetFileExt(const char * name)
{
size_t i, ilast;
// looking for the end of the name
for(i=0 ; name[i] != 0 ; ++i);
if( i == 0 )
return name; // ops, the name is empty
// remember the end of the string
ilast = i;
// looking for the last dot
for(--i ; i>0 && name[i] != '.' ; --i);
if( name[i] != '.' )
return name + ilast; // ops, there is not a dot
// the extensions starts from i+1
// and can be empty (if the last character is a dot)
return name + i + 1;
}
Item::Auth SelectFileType(const char * file_name)
{
const char * ext = GetFileExt(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;
if( EqualNoCase(ext, "pdf") ||
EqualNoCase(ext, "doc") ||
EqualNoCase(ext, "xls") ||
EqualNoCase(ext, "txt") ||
EqualNoCase(ext, "ods") ||
EqualNoCase(ext, "odt") )
return Item::auth_document;
return Item::auth_other;
}
+36 -8
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -15,10 +15,7 @@
#include <sstream>
#include <ctime>
#include "item.h"
#define MAJOR_VER 0
#define MINOR_VER 2
#define REVISION_VER 0
#include <cstdio>
void ToString(std::string & s, int value);
@@ -26,23 +23,54 @@ void ToString(std::string & s, long value);
int ChangeLocalChar(unsigned char c);
bool CorrectUrlChar(char c);
void CorrectUrl(Item & item);
void SetUrlFromSubject(Item & item);
void CorrectUrlDots(std::string & url);
void CorrectUrlChars(std::string & url);
void CorrectUrlOnlyAllowedChar(std::string & url);
void HtmlEscape(std::ostringstream & out, const std::string & in);
void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in);
std::string HtmlEscape(const std::string & in);
std::string HtmlEscapeFormTxt(const std::string & in);
const char * DateToStr(int year, int month, int day);
const char * DateToStr(int year, int month, int day, int hour, int min, int sec);
const char * DateToStr(tm * ptm);
const char * DateToStr(time_t t);
const char * DateToStrWithoutHours(tm * ptm);
const char * DateToStrWithoutHours(time_t t);
const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec);
const char * DateToStrCookie(tm * ptm);
const char * DateToStrCookie(time_t t);
const char * IpToStr(unsigned int ip_);
bool IsWhite(int s);
void TrimWhite(std::string & s);
void Trim(std::string & s, char c);
int ToSmall(int c);
void ToSmall(std::string & s);
const char * SkipWhite(const char * s);
const char * ToStr(int value);
bool IsSubString(const char * short_str, const char * long_str);
bool IsSubStringNoCase(const char * short_str, const char * long_str);
bool EqualNoCase(const char * str1, const char * str2);
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);
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);
#endif
+138 -71
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
@@ -16,13 +16,16 @@ Mount::Mount()
{
type = cms;
dir_id = -1;
fs = simplefs;
param.resize(par_none);
}
const char * Mount::TypeToStr()
{
static char buffer[30];
static char buffer[30];
switch( type )
{
@@ -34,8 +37,12 @@ const char * Mount::TypeToStr()
sprintf(buffer, "thread");
break;
case ticket:
sprintf(buffer, "ticket");
break;
default:
sprintf(buffer, "the name is not set");
sprintf(buffer, "unknown");
break;
}
@@ -43,82 +50,142 @@ return buffer;
}
bool Mount::ParseStrParam(const std::string & param, const std::vector<int> & args)
const char * Mount::FsToStr()
{
Param p = none;
static char buffer[30];
if( param == "asc" )
p = asc;
else
if( param == "desc" )
p = desc;
else
if( param == "withheader" )
p = withheader;
else
if( param == "withinfo" )
p = withinfo;
else
if( param == "thread_with_header" )
p = thread_with_header;
else
if( param == "thread_with_info" )
p = thread_with_info;
else
if( param == "restrictcreatethread" )
p = restrictcreatethread;
else
if( param == "only_root_can_remove" )
p = only_root_can_remove;
else
if( param == "can_use_emacs_on" )
p = can_use_emacs_on;
else
if( param == "can_use_mkdir_on" )
p = can_use_mkdir_on;
else
if( param == "none" )
return true;
else
return false;
param_table.insert( std::make_pair(p, args) );
return true;
}
bool Mount::IsParam(Param p)
{
ParamTable::iterator i = param_table.find(p);
if( i == param_table.end() )
return false;
return true;
}
bool Mount::IsParam(Param p, int * first_arg)
{
ParamTable::iterator i = param_table.find(p);
if( i == param_table.end() )
switch( fs )
{
*first_arg = -1;
return false;
case simplefs:
sprintf(buffer, "simplefs");
break;
case hashfs:
sprintf(buffer, "hashfs");
break;
default:
sprintf(buffer, "unknown");
break;
}
if( !i->second.empty() )
*first_arg = i->second[0];
else
*first_arg = -1;
return true;
return buffer;
}
Mount::ParamCode Mount::ParseParam(const char * param_name)
{
struct ParName
{
ParamCode param_code;
const char * name;
};
static ParName par_name_tab[] = {
{ par_page, "page" },
{ par_thread, "thread" },
{ par_ticket, "ticket" },
{ par_ticket_type, "ticket_type" },
{ par_ticket_type_default, "ticket_type_default" },
{ par_ticket_status, "ticket_status" },
{ par_ticket_status_default, "ticket_status_default" },
{ par_ticket_priority, "ticket_priority" },
{ par_ticket_priority_default, "ticket_priority_default" },
{ par_ticket_category, "ticket_category" },
{ par_ticket_category_default, "ticket_category_default" },
{ par_ticket_expected, "ticket_expected" },
{ par_ticket_expected_default, "ticket_expected_default" },
{ par_createthread_on, "createthread_on" },
{ par_createticket_on, "createticket_on" },
{ par_only_root_remove, "only_root_remove" },
{ par_emacs_on, "emacs_on" },
{ par_mkdir_on, "mkdir_on" },
{ par_app, "app" },
{ par_html_template, "html_template" },
};
size_t i, len = sizeof(par_name_tab) / sizeof(ParName);
for(i=0 ; i<len ; ++i)
{
if( strcmp(par_name_tab[i].name, param_name) == 0 )
return par_name_tab[i].param_code;
}
return par_none;
}
void Mount::ClearParams()
{
param_table.clear();
size_t i;
for(i=0 ; i<param.size() ; ++i)
param[i].Clear();
}
bool Mount::IsPar(Mount::ParamCode code)
{
if( !param[code].defined )
return false;
return true;
}
bool Mount::IsArg(Mount::ParamCode code, const char * arg)
{
ParamArg::iterator i;
if( !param[code].defined )
return false;
for(i=param[code].arg.begin() ; i!=param[code].arg.end() ; ++i)
{
if( *i == arg )
return true;
}
return false;
}
bool Mount::IsArg(Mount::ParamCode code, const std::string & arg)
{
return IsArg(code, arg.c_str());
}
bool Mount::IsArg(Mount::ParamCode code, int arg)
{
ParamArg::iterator i;
if( !param[code].defined )
return false;
for(i=param[code].arg.begin() ; i!=param[code].arg.end() ; ++i)
{
if( atoi(i->c_str()) == arg )
return true;
}
return false;
}
const std::string * Mount::HtmlTemplate() const
{
if( !param[par_html_template].defined )
return 0;
if( param[par_html_template].arg.size() != 1 )
return 0;
return & param[par_html_template].arg[0];
}
+66 -22
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
@@ -16,6 +16,8 @@
#include <vector>
class Mount
{
public:
@@ -24,44 +26,86 @@ public:
enum Type
{
cms = 0,
thread
thread,
ticket
};
enum Param
enum Fs
{
none = 0,
asc,
desc,
withheader,
withinfo,
thread_with_header,
thread_with_info,
restrictcreatethread,
only_root_can_remove,
can_use_emacs_on,
can_use_mkdir_on
simplefs = 0,
hashfs
};
// the first should be with 0 index
// the last should be 'none'
enum ParamCode
{
par_page = 0,
par_thread,
par_ticket,
par_ticket_type,
par_ticket_type_default,
par_ticket_status,
par_ticket_status_default,
par_ticket_priority,
par_ticket_priority_default,
par_ticket_category,
par_ticket_category_default,
par_ticket_expected,
par_ticket_expected_default,
par_createthread_on,
par_createticket_on,
par_only_root_remove,
par_emacs_on,
par_mkdir_on,
par_app,
par_html_template,
par_none
};
typedef std::vector<std::string> ParamArg;
struct ParamRow
{
bool defined;
ParamArg arg;
ParamRow() { defined = false; }
void Clear() { defined = false; arg.clear(); }
};
typedef std::vector<ParamRow> Param;
Param param;
long dir_id;
Type type;
Fs fs;
Mount();
const char * TypeToStr();
bool ParseStrParam(const std::string & param, const std::vector<int> & args);
bool IsParam(Param p);
bool IsParam(Param p, int * first_arg);
const char * FsToStr();
static ParamCode ParseParam(const char * param);
void ClearParams();
private:
typedef std::map<Param, std::vector<int> > ParamTable;
ParamTable param_table;
bool IsPar(Mount::ParamCode code);
bool IsArg(Mount::ParamCode code, const char * arg);
bool IsArg(Mount::ParamCode code, const std::string & arg);
bool IsArg(Mount::ParamCode code, int arg);
// returning a name to html template (can be null if not defined)
const std::string * HtmlTemplate() const;
};
#endif
+195 -64
View File
@@ -1,21 +1,26 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "mountparser.h"
#include "data.h"
#include "log.h"
#include "misc.h"
void MountParser::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
}
bool MountParser::IsWhite(int c)
{
if( c==' ' || c=='\t' || c==13 )
if( c==' ' || c=='\t' || c==13 || c==160 )
return true;
return false;
@@ -39,11 +44,38 @@ void MountParser::SkipLine()
}
void MountParser::ReadWord(std::string & res)
void MountParser::ReadWordQuote(std::string & res)
{
res.clear();
++pinput;
while( *pinput && *pinput!=10 && *pinput!='\"' )
{
if( pinput[0]=='\\' && pinput[1]=='\"' )
{
res += '\"';
pinput += 2;
}
else
if( pinput[0]=='\\' && pinput[1]=='\\' )
{
res += '\\';
pinput += 2;
}
else
{
res += *pinput;
pinput += 1;
}
}
if( *pinput == '"' )
++pinput;
}
// a white character is the separator
void MountParser::ReadWordWhite(std::string & res)
{
while( *pinput && *pinput!=10 && !IsWhite(*pinput) )
{
res += *pinput;
@@ -52,35 +84,54 @@ void MountParser::ReadWord(std::string & res)
}
bool MountParser::ReadParamArg(int & out)
// the comma or the second bracket ')' are the separators
void MountParser::ReadWordComma(std::string & res)
{
SkipWhite();
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' )
{
res += *pinput;
++pinput;
}
char * new_pos;
long temp = strtol(pinput, &new_pos, 10);
if( pinput == new_pos )
return false;
pinput = new_pos;
SkipWhite();
// here can we make a test whether the temp is greater from 'int' type
out = (int)temp;
return true;
// trimming last white characters
// (white characters can be in the middle of the string)
TrimWhite(res);
}
void MountParser::ReadParamArgs(std::vector<int> & args)
void MountParser::ReadWord(std::string & res, bool comma_bracket_separator)
{
int arg;
res.clear();
SkipWhite();
while( ReadParamArg(arg) )
if( *pinput == '"' )
{
args.push_back(arg);
ReadWordQuote(res);
}
else
if( comma_bracket_separator )
{
ReadWordComma(res);
}
else
{
ReadWordWhite(res);
}
}
log << log3 << "MP: mount param arg: " << arg << logend;
void MountParser::ReadParamArgsLoop(Mount::ParamArg & args)
{
SkipWhite();
while( *pinput && *pinput!=10 && *pinput!=')' )
{
ReadWord(temp_arg, true);
if( !temp_arg.empty() )
args.push_back(temp_arg);
if( *pinput == ',' )
++pinput;
@@ -88,28 +139,16 @@ int arg;
}
void MountParser::ReadParam(std::string & res, std::vector<int> & args)
void MountParser::ReadParamArgs(Mount::ParamArg & args)
{
SkipWhite();
res.clear();
args.clear();
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) )
{
res += *pinput;
++pinput;
}
if( res.empty() )
return;
// reading arguments
SkipWhite();
if( *pinput == '(' )
{
++pinput;
ReadParamArgs(args);
ReadParamArgsLoop(args);
if( *pinput != ')' )
{
@@ -121,18 +160,50 @@ void MountParser::ReadParam(std::string & res, std::vector<int> & args)
++pinput;
}
}
}
void MountParser::ReadParamName(std::string & res)
{
SkipWhite();
res.clear();
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) )
{
res += *pinput;
++pinput;
}
}
void MountParser::ReadParam(std::string & res, Mount::ParamArg & args)
{
ReadParamName(res);
if( res.empty() )
return;
ReadParamArgs(args);
SkipWhite();
if( *pinput == ',' )
++pinput;
}
void MountParser::ReadMountType()
{
SkipWhite();
ReadWord(temp);
if( temp.empty() )
{
// an empty line (some white characters only)
err = WINIX_ERR_EMPTY;
}
else
if( temp == "cms" )
{
mount.type = Mount::cms;
@@ -145,8 +216,14 @@ void MountParser::ReadMountType()
log << log3 << "MP: mount type: thread" << logend;
}
else
if( temp == "ticket" )
{
err = Error::mount_unknown;
mount.type = Mount::ticket;
log << log3 << "MP: mount type: ticket" << logend;
}
else
{
err = WINIX_ERR_MOUNT_UNKNOWN;
log << log1 << "MP: unknown mount type: " << temp << logend;
}
}
@@ -155,12 +232,9 @@ void MountParser::ReadMountType()
void MountParser::ReadMountPoint()
{
SkipWhite();
// !! narazie bez cudzyslowow
ReadWord(temp);
pdir = data.dirs.GetDir(temp);
pdir = dirs->GetDir(temp);
if( pdir )
{
@@ -169,28 +243,73 @@ void MountParser::ReadMountPoint()
}
else
{
err = Error::no_mountpoint;
err = WINIX_ERR_NO_MOUNTPOINT;
log << log1 << "MP: there is no such a mount point: " << temp << logend;
}
}
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 = WINIX_ERR_UNKNOWN_FILESYSTEM;
log << log1 << "MP: unknown filesystem: " << temp << logend;
}
}
void MountParser::LogMountParams()
{
size_t i;
log << log3 << "MP: mount param: " << temp << "(";
for(i=0 ; i<param_args.size() ; ++i)
{
log << param_args[i];
if( i != param_args.size()-1 )
log << ",";
}
log << ")" << logend;
}
void MountParser::ReadMountParams()
{
mount.ClearParams();
for( ReadParam(temp, param_args) ; !temp.empty() ; ReadParam(temp, param_args) )
{
if( !mount.ParseStrParam(temp, param_args) )
Mount::ParamCode p = Mount::ParseParam(temp.c_str());
if( p != Mount::par_none )
{
log << log1 << "MP: unknown mount param: " << temp << logend;
err = Error::mount_no_param;
return;
mount.param[p].defined = true;
mount.param[p].arg = param_args;
LogMountParams();
}
else
{
log << log3 << "MP: mount param: " << temp << logend;
log << log1 << "MP: unknown mount param: " << temp << " (skipped)" << logend;
}
}
}
@@ -201,17 +320,29 @@ void MountParser::ReadRow(std::map<long, Mount> & output)
{
ReadMountType();
if( err == Error::ok )
ReadMountPoint();
if( err == Error::ok )
ReadMountParams();
if( err == Error::ok )
if( err == WINIX_ERR_EMPTY )
{
output.insert( std::make_pair(mount.dir_id, mount) );
err = WINIX_ERR_OK;
SkipLine();
return;
}
if( err == WINIX_ERR_OK )
ReadMountPoint();
if( err == WINIX_ERR_OK )
ReadFs();
if( err == WINIX_ERR_OK )
ReadMountParams();
if( err == WINIX_ERR_OK )
{
std::pair<std::map<long, Mount>::iterator, bool> res = output.insert( std::make_pair(mount.dir_id, mount) );
if( !res.second )
log << log1 << "MP: this mount point exists (skipped)" << logend;
}
SkipLine();
}
@@ -222,10 +353,10 @@ void MountParser::ReadRow(std::map<long, Mount> & output)
Error MountParser::Parse(const std::string & input, std::map<long, Mount> & output)
{
pinput = input.c_str();
err = Error::ok;
err = WINIX_ERR_OK;
output.clear();
while( *pinput && err == Error::ok )
while( *pinput && err == WINIX_ERR_OK )
ReadRow(output);
return err;
+18 -8
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -19,6 +19,7 @@
#include "mount.h"
#include "item.h"
#include "error.h"
#include "dirs.h"
@@ -27,25 +28,34 @@ class MountParser
public:
Error Parse(const std::string & input, std::map<long, Mount> & output);
void SetDirs(Dirs * pdirs);
private:
Dirs * dirs;
bool IsWhite(int c);
void SkipWhite();
void SkipLine();
void ReadWord(std::string & res);
bool ReadParamArg(int & out);
void ReadParamArgs(std::vector<int> & args);
void ReadParam(std::string & res, std::vector<int> & args);
void ReadWordQuote(std::string & res);
void ReadWordWhite(std::string & res);
void ReadWordComma(std::string & res);
void ReadWord(std::string & res, bool comma_bracket_separator = false);
void ReadParamArgsLoop(Mount::ParamArg & args);
void ReadParamArgs(Mount::ParamArg & args);
void ReadParamName(std::string & res);
void ReadParam(std::string & res, Mount::ParamArg & args);
void ReadMountType();
void ReadMountPoint();
void ReadFs();
void LogMountParams();
void ReadMountParams();
void ReadRow(std::map<long, Mount> & output);
const char * pinput;
std::string temp;
std::vector<int> param_args;
std::string temp_arg;
Mount::ParamArg param_args;
Mount mount;
+115 -47
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
@@ -8,99 +8,167 @@
*/
#include "mounts.h"
#include "data.h"
#include "request.h"
#include "log.h"
#include "mountparser.h"
#include "db.h"
void Mounts::ReadMounts()
Mounts::Mounts()
{
pmount = 0;
}
void Mounts::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
}
void Mounts::SetDb(Db * pdb)
{
db = pdb;
}
void Mounts::SetRequest(Request * prequest)
{
request = prequest;
}
// reading from 'mounts'
Error Mounts::ReadMounts(const std::string & mounts)
{
MountParser mp;
mp.SetDirs(dirs);
Error err = mp.Parse(mounts, mount_tab);
// !! tymczasowo - bedzie odczyt z bazy z /etc/fstab
std::string temp =
"cms / withheader, withinfo \n"
"thread /news desc, withheader, thread_with_header, thread_with_info, restrictcreatethread(-1) \n"
"thread /forum asc, withheader, withinfo, thread_with_info, restrictcreatethread(3), only_root_can_remove, can_use_emacs_on(4), can_use_mkdir_on(3)";
Error err = mp.Parse(temp, mount_table);
if( err != Error::ok )
if( err != WINIX_ERR_OK )
{
log << log1 << "M: some problems with mountpoints (mountpoints table will be empty)" << logend;
mount_table.clear();
mount_tab.clear();
}
CalcCurMount();
return err;
}
/*
Mount Mounts::GetCurrentMountPoint()
// reading from /etc/fstab
Error Mounts::ReadMounts()
{
return current_dir;
}
*/
static std::string file = "fstab";
Mount::Type Mounts::CurrentMountType()
{
return current_dir.type;
}
Item * etc = dirs->GetEtcDir();
bool Mounts::CurrentMountIsParam(Mount::Param p)
{
return current_dir.IsParam(p);
}
if( !etc )
{
log << log1 << "M: there is no /etc directory" << logend;
return WINIX_ERR_NO_ITEM;
}
bool Mounts::CurrentMountIsParam(Mount::Param p, int * first_arg)
{
return current_dir.IsParam(p, first_arg);
Item fstab;
Error err = db->GetItem(etc->id, file, fstab);
if( err == WINIX_ERR_NO_ITEM )
{
log << log1 << "M: there is no /etc/fstab file" << logend;
return err;
}
if( err != WINIX_ERR_OK )
{
log << log1 << "M: cannot read /etc/fstab" << logend;
return err;
}
return ReadMounts(fstab.content);
}
void Mounts::MountCmsForRoot()
{
current_dir.type = Mount::cms;
Mount mount;
mount.type = Mount::cms;
mount.fs = Mount::simplefs;
Item * proot = data.dirs.GetRootDir();
Item * proot = dirs->GetRootDir();
if( proot )
current_dir.dir_id = proot->id;
mount.dir_id = proot->id;
else
{
current_dir.dir_id = -1;
mount.dir_id = -1;
log << log1 << "M: there is no a root dir" << logend;
}
std::pair<MountTab::iterator, bool> res = mount_tab.insert( std::make_pair(mount.dir_id, mount) );
pmount = &(res.first->second);
}
void Mounts::CalculateCurrentMountType()
void Mounts::CalcCurMount()
{
std::vector<Item*>::reverse_iterator i;
// when the program starts (when the dir_table is empty()
// we don't want to call MountCmsForRoot()
if( request->dir_table.empty() )
return;
for(i = request.dir_table.rbegin() ; i!=request.dir_table.rend() ; ++i)
for(i = request->dir_table.rbegin() ; i!=request->dir_table.rend() ; ++i)
{
std::map<long, Mount>::iterator m = mount_table.find( (*i)->id );
std::map<long, Mount>::iterator m = mount_tab.find( (*i)->id );
if( m != mount_table.end() )
if( m != mount_tab.end() )
{
current_dir = m->second;
log << log2 << "M: current mount point is: " << current_dir.TypeToStr() << logend;
pmount = &(m->second);
log << log2 << "M: current mount point is: " << pmount->TypeToStr()
<< ", fs: " << pmount->FsToStr() << logend;
return;
}
}
// 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;
}
// 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 = 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;
}
}
const Mounts::MountTab * Mounts::GetMountTab()
{
return &mount_tab;
}
+26 -13
View File
@@ -1,5 +1,5 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
@@ -13,7 +13,12 @@
#include <map>
#include <string>
#include "mount.h"
#include "error.h"
#include "dirs.h"
#include "db.h"
#include "request.h"
@@ -21,28 +26,36 @@ class Mounts
{
public:
void ReadMounts();
void SetDirs(Dirs * pdirs);
void SetDb(Db * pdb);
void SetRequest(Request * prequest);
void CalculateCurrentMountType();
// dir_id, mount_point
typedef std::map<long, Mount> MountTab;
// !! nie lepiej aby zwracal tutaj referencje albo wskaznik na biezacy punkt?
// !! w Mount mamy strukture std::set
//Mount GetCurrentMountPoint();
Mounts();
Error ReadMounts(const std::string & mounts);
Error ReadMounts();
Mount::Type CurrentMountType();
bool CurrentMountIsParam(Mount::Param p);
bool CurrentMountIsParam(Mount::Param p, int * first_arg);
void CalcCurMount();
Mount * CalcMount(long dir_id);
void MountCmsForRoot();
// current mount point
// will not be null after calling CalcCurMount() or ReadMounts([...])
Mount * pmount;
const MountTab * GetMountTab();
private:
Mount current_dir;
Dirs * dirs;
Db * db;
Request * request;
// dir_id, mount_point
std::map<long, Mount> mount_table;
MountTab mount_tab;
void MountCmsForRoot();
};
+64 -21
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -14,7 +14,6 @@
#include "log.h"
#include "notify.h"
#include "data.h"
#include "misc.h"
#include "request.h"
@@ -26,17 +25,41 @@ Notify * Notify::obj;
void Notify::SetRequest(Request * prequest)
{
request = prequest;
}
void Notify::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Notify::SetSystem(System * psystem)
{
system = psystem;
}
void Notify::SetTemplatesNotify(TemplatesNotify * ptemplates_notify)
{
templates_notify = ptemplates_notify;
}
/*
methods for second thread
methods for the second thread
second thread can reference to 'this' by using 'obj' pointer
the thread can reference to 'this' by using 'obj' pointer
*/
void * Notify::ThreadRoutine(void * arg)
{
obj = (Notify*)arg;
obj->templates_notify.Read(obj->templates_dir);
while( true )
@@ -70,8 +93,11 @@ void Notify::SendEmail(NotifyMsg & n)
{
TemplatesNotifyFunctions::notify_msg = &n;
obj->templates_notify.Generate();
SendEmail(n.email, obj->templates_notify.notify_str.str());
obj->Lock(); // templates can be reloaded from the first thread
obj->templates_notify->Generate(n.lang);
obj->Unlock();
SendEmail(n.email, obj->templates_notify->notify_str.str());
}
@@ -91,7 +117,6 @@ void Notify::SendEmail(const std::string & email, const std::string & message)
if( !sendmail )
{
nlog << "Notify: can't run sendmail" << logend;
return;
}
@@ -100,6 +125,7 @@ void Notify::SendEmail(const std::string & email, const std::string & message)
pclose(sendmail);
nlog << "Notify: email to: " << email << " has been sent" << logend;
nlog << logsave;
}
@@ -133,10 +159,22 @@ Notify::~Notify()
}
bool Notify::Init(const std::string & tdir)
void Notify::ReadTemplates()
{
templates_dir = tdir;
// we are in the first thread here
// the second thread can use our templates and we must Lock()
// (the second thread is using Lock() too)
Lock();
templates_notify->Read();
Unlock();
}
bool Notify::Init()
{
templates_notify->CreateFunctions();
int t = pthread_create(&thread, 0, ThreadRoutine, (void*)this);
@@ -173,9 +211,9 @@ void Notify::CreateItemDir(std::string & dir, bool clear)
if( clear )
dir.clear();
for(size_t a=0 ; a<request.dir_table.size() ; ++a)
for(size_t a=0 ; a<request->dir_table.size() ; ++a)
{
dir += request.dir_table[a]->url;
dir += request->dir_table[a]->url;
dir += '/';
}
}
@@ -183,9 +221,9 @@ void Notify::CreateItemDir(std::string & dir, bool clear)
void Notify::CreateItemLink(std::string & link)
{
link = data.base_url;
link = config->base_url;
CreateItemDir(link, false);
link += request.item.url;
link += request->item.url;
}
@@ -198,8 +236,8 @@ Users::Iterator i;
return;
n.notify_code = notify_code;
n.current_mount_type = data.mounts.CurrentMountType();
n.doc_base_url = data.base_url;
n.current_mount_type = system->mounts.pmount->type;
n.doc_base_url = config->base_url;
CreateItemDir(n.item_dir);
CreateItemLink(n.item_link);
@@ -210,17 +248,17 @@ Users::Iterator i;
{
// don't clear notify_pool here -- it is used (and will be cleared) by the second thread
for(i=data.users.Begin() ; i != data.users.End() ; ++i)
for(i=system->users.Begin() ; i != system->users.End() ; ++i)
{
sending = false;
if( data.mounts.CurrentMountType() == Mount::thread )
if( system->mounts.pmount->type == Mount::thread )
{
if( (i->thread_notify & notify_code) != 0 )
sending = true;
}
else
if( data.mounts.CurrentMountType() == Mount::cms )
if( system->mounts.pmount->type == Mount::cms )
{
if( (i->cms_notify & notify_code) != 0 )
sending = true;
@@ -229,6 +267,11 @@ Users::Iterator i;
if( sending )
{
n.email = i->email;
n.lang = Locale::StrToLang(config->locale_str);// !! bedzie osobno dla kazdego uzytkownika
if( n.lang == Locale::lang_unknown )
n.lang = Locale::lang_en;
notify_pool.insert(notify_pool.end(), n);
}
}
+27 -12
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -13,13 +13,18 @@
#include <list>
#include <string>
#include <cstdio>
#include "../templatesnotify/templatesnotify.h"
#include "templatesnotify/templatesnotify.h"
#include "request.h"
#include "config.h"
#include "system.h"
#include "users.h"
#define CMSLU_NOTIFY_ITEM_ADD 1
#define CMSLU_NOTIFY_ITEM_EDIT 2
#define CMSLU_NOTIFY_ITEM_DELETE 4
#define CMSLU_NOTIFY_DIR_ADD 8
#define WINIX_NOTIFY_ITEM_ADD 1
#define WINIX_NOTIFY_ITEM_EDIT 2
#define WINIX_NOTIFY_ITEM_DELETE 4
#define WINIX_NOTIFY_DIR_ADD 8
@@ -30,10 +35,17 @@ public:
Notify();
~Notify();
bool Init(const std::string & tdir);
void SetRequest(Request * prequest);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
void SetTemplatesNotify(TemplatesNotify * ptemplates_notify);
void ReadTemplates();
bool Init();
/*
this method added an item to our special pool
this method addes an item to our special pool
the pool is used by a second thread
*/
void ItemChanged(int notify_code);
@@ -41,6 +53,10 @@ public:
private:
Request * request;
Config * config;
System * system;
TemplatesNotify * templates_notify;
static void * ThreadRoutine(void * arg);
bool Lock();
@@ -64,13 +80,12 @@ private:
std::list<NotifyMsg> notify_pool;
static Notify * obj;
std::string command;
std::string templates_dir;
TemplatesNotify templates_notify;
};
extern Notify notify;
#endif
+322
View File
@@ -0,0 +1,322 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <dlfcn.h>
#include "plugin.h"
#include "pluginmsg.h"
void Plugin::UnloadPlugins()
{
size_t i;
slots.clear();
for(i=0 ; i<plugins.size() ; ++i)
dlclose(plugins[i].handle);
plugins.clear();
}
Plugin::Plugin()
{
current_plugin = -1;
request = 0;
db = 0;
config = 0;
request = 0;
system = 0;
functions = 0;
templates = 0;
session_manager = 0;
}
Plugin::~Plugin()
{
UnloadPlugins();
}
void Plugin::SetDb(Db * pdb)
{
db = pdb;
}
void Plugin::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Plugin::SetRequest(Request * prequest)
{
request = prequest;
}
void Plugin::SetSystem(System * psystem)
{
system = psystem;
}
void Plugin::SetFunctions(Functions * pfunctions)
{
functions = pfunctions;
}
void Plugin::SetTemplates(Templates * ptemplates)
{
templates = ptemplates;
}
void Plugin::SetSessionManager(SessionManager * psession_manager)
{
session_manager = psession_manager;
}
bool Plugin::SetPointers(PluginInfo & info)
{
// for safety we call a plugin function only when all our pointers are not null
bool res = (db && config && request && system && functions && templates && session_manager);
if( !res )
log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend;
info.db = db;
info.config = config;
info.request = request;
info.system = system;
info.functions = functions;
info.templates = templates;
info.session_manager = session_manager;
return res;
}
void Plugin::LoadPlugins(const std::vector<std::string> & plugins)
{
size_t i;
for(i=0 ; i<plugins.size() ; ++i)
LoadPlugin(plugins[i]);
}
void Plugin::LoadPlugin(const std::string & filename)
{
LoadPlugin(filename.c_str());
}
void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
{
void * p = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
if( !p )
{
log << log1 << "Plugin: cannot load a plugin: \"" << filename << "\"" << logend;
log << log1 << "Plugin: dlerror: " << dlerror() << logend;
return 0;
}
fun_init = (Fun1)dlfunc(p, "Init");
if( !fun_init )
{
log << log1 << "Plugin: cannot load a plugin: " << filename
<< " (there is no Init() function)" << logend;
dlclose(p);
return 0;
}
log << log1 << "Plugin: plugin loaded"
<< ", file: " << filename
<< ", index: " << plugins.size() << logend;
return p;
}
void Plugin::LoadPlugin(const char * filename)
{
Fun1 fun_init;
void * plugin_handle;
int old_current_plugin;
if( !SetPointers(info) )
return;
if( !(plugin_handle = LoadInitFun(filename, fun_init)) )
return;
info.Clear();
old_current_plugin = current_plugin;
current_plugin = (int)plugins.size();
info.plugin_id = current_plugin;
fun_init(info);
PluginsItem item;
item.handle = plugin_handle;
item.plugin_name = reinterpret_cast<const char *>(info.p1);
plugins.push_back(item);
current_plugin = old_current_plugin;
}
void Plugin::Call(int message, Slots::iterator & slot)
{
if( !SetPointers(info) )
return;
current_plugin = slot->second.index;
info.plugin_id = current_plugin;
if( request && request->session && current_plugin != -1 )
info.plugin_data_base = request->session->plugin_data.Get(current_plugin);
else
info.plugin_data_base = 0;
if( !slot->second.is_running )
{
slot->second.is_running = true;
if( slot->second.fun1 )
slot->second.fun1(info);
if( slot->second.fun2 )
slot->second.fun2();
slot->second.is_running = false;
}
else
{
log << log1 << "Plugin: id: " << slot->second.index
<< ", message: " << message
<< ", recurrences are not allowed" << logend;
}
}
void Plugin::Call(int message, void * p1_, void * p2_, long l1_, long l2_)
{
Slots::iterator i = slots.lower_bound(message);
int old_current_plugin = current_plugin;
for( ; i!=slots.end() && i->first==message ; ++i )
{
info.Clear();
info.p1 = p1_;
info.p2 = p2_;
info.l1 = l1_;
info.l2 = l2_;
Call(message, i);
}
current_plugin = old_current_plugin;
}
void Plugin::Call(int message)
{
Call(message, 0, 0, 0, 0);
}
void Plugin::Call(int message, void * p1_)
{
Call(message, p1_, 0, 0, 0);
}
void Plugin::Call(int message, void * p1_, void * p2_)
{
Call(message, p1_, p2_, 0, 0);
}
void Plugin::Call(int message, long l1_)
{
Call(message, 0, 0, l1_, 0);
}
void Plugin::Call(int message, long l1_, long l2_)
{
Call(message, 0, 0, l1_, l2_);
}
void Plugin::Call(int message, void * p1_, long l1_)
{
Call(message, p1_, 0, l1_, 0);
}
void Plugin::Call(int message, void * p1_, long l1_, long l2_)
{
Call(message, p1_, 0, l1_, l2_);
}
void Plugin::Call(int message, void * p1_, void * p2_, long l1_)
{
Call(message, p1_, p2_, l1_, 0);
}
size_t Plugin::Size()
{
return plugins.size();
}
void Plugin::Assign(int message, Fun1 fun1)
{
Slot s;
s.fun1 = fun1;
s.index = current_plugin;
slots.insert( std::make_pair(message, s) );
log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend;
}
void Plugin::Assign(int message, Fun2 fun2)
{
Slot s;
s.fun2 = fun2;
s.index = current_plugin;
slots.insert( std::make_pair(message, s) );
log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend;
}
Executable
+197
View File
@@ -0,0 +1,197 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmsluplugin
#define headerfilecmsluplugin
#include <vector>
#include <string>
#include <map>
#include "pluginmsg.h"
#include "log.h"
#include "plugindata.h"
#include "config.h"
#include "request.h"
#include "system.h"
#include "sessionmanager.h"
#include "functions/functions.h"
#include "templates/templates.h"
/*
all your plugin functions can have signature either:
void my_function(PluginInfo & info); or
void my_function();
only the main Init should have:
extern "C" void Init(PluginFunction & info);
in the Init you can add your own functions by using plugin.Assign() method
and you can set the name of the plugin by setting info.p1 pointer
to a string buffer (const char *)
(this buffer will not be copied so it should not be destroyed after Init finishes)
also in Init you can only use logger (log) info.config and info.db objects
(the rest winix objects are not initialized yet)
*/
struct PluginInfo
{
// these variables are used for some purposes
// depending on a hook in which they are used
void * p1;
void * p2;
long l1;
long l2;
// unique plugin identifier
int plugin_id;
// objects from winix which are accessible from a plugin
Db * db;
Config * config;
Request * request;
System * system;
Functions * functions;
Templates * templates;
SessionManager * session_manager;
// pointer to the plugin session (can be null if not set by the plugin)
// you should use WINIX_SESSION_CREATED and WINIX_SESSION_REMOVE
// to create your plugin's session data
PluginDataBase * plugin_data_base; // !! zmienic nazwe na plugin_session_base ? a moze session_base; a moze plugin_session?
// function return status
// default: false (if not set by the plugin)
bool ret;
void Clear()
{
// pointers to winix objects are not cleared here
p1 = 0;
p2 = 0;
l1 = 0;
l2 = 0;
plugin_id = -1;
plugin_data_base = 0;
ret = false;
}
};
class Plugin
{
public:
// index of a plugin which is called by Call() method
// normally: -1
int current_plugin;
// Fun is a type of a function you should provide in your plugin
typedef void (*Fun1)(PluginInfo &);
typedef void (*Fun2)(void);
struct Slot
{
Fun1 fun1;
Fun2 fun2;
int index; // plugin index (which plugin has inserted the slot)
bool is_running;
Slot()
{
fun1 = 0;
fun2 = 0;
index = -1;
is_running = false;
}
};
Plugin();
~Plugin();
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetRequest(Request * prequest);
void SetSystem(System * psystem);
void SetFunctions(Functions * pfunctions);
void SetTemplates(Templates * ptemplates);
void SetSessionManager(SessionManager * psession_manager);
void LoadPlugin(const char * filename);
void LoadPlugin(const std::string & filename);
void LoadPlugins(const std::vector<std::string> & plugins);
void UnloadPlugins();
void Call(int message);
void Call(int message, void * p1_);
void Call(int message, void * p1_, void * p2_);
void Call(int message, long l1_);
void Call(int message, long l1_, long l2_);
void Call(int message, void * p1_, long l1_);
void Call(int message, void * p1_, long l1_, long l2_);
void Call(int message, void * p1_, void * p2_, long l1_);
void Call(int message, void * p1_, void * p2_, long l1_, long l2_);
// how many plugins there are
size_t Size();
// assign a function to a message
// you can assign more than one function to a specific message
void Assign(int message, Fun1);
void Assign(int message, Fun2);
private:
Db * db;
Config * config;
Request * request;
System * system;
Functions * functions;
Templates * templates;
SessionManager * session_manager;
struct PluginsItem
{
void * handle;
const char * plugin_name; // plugin name (can be null if was not set by the plugin)
};
typedef std::vector<PluginsItem> Plugins;
Plugins plugins;
typedef std::multimap<int, Slot> Slots;
Slots slots;
PluginInfo info;
void * LoadInitFun(const char * filename, Fun1 & fun_init);
void Call(int message, Slots::iterator & slot);
bool SetPointers(PluginInfo & info);
};
extern Plugin plugin;
#endif
+125
View File
@@ -0,0 +1,125 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "plugindata.h"
#include "plugin.h"
#include "log.h"
void PluginData::Assign(size_t index, PluginDataBase * data)
{
if( index >= table.size() )
Resize(index+1);
table[index] = data;
}
void PluginData::Assign(PluginDataBase * data)
{
if( plugin.current_plugin == -1 )
{
log << log1 << "PD: Assign(PluginDataBase*) should be called only from plugins" << logend;
return;
}
Assign(plugin.current_plugin, data);
}
PluginDataBase * PluginData::Get(size_t index)
{
if( index >= table.size() )
Resize(index+1);
return table[index];
}
PluginDataBase * PluginData::Get()
{
if( plugin.current_plugin == -1 )
{
log << log1 << "PD: Get() should be called only from plugins" << logend;
return 0;
}
return Get(plugin.current_plugin);
}
void PluginData::DeleteAll()
{
if( table.empty() )
return;
plugin.Call(WINIX_SESSION_REMOVE);
for(size_t i=0 ; i<table.size() ; ++i)
table[i] = 0;
}
PluginData::PluginData()
{
}
PluginData::PluginData(const PluginData & p)
{
operator=(p);
}
PluginData & PluginData::operator=(const PluginData & p)
{
// we don't copy all pointers - only resize the table
// pointers will be set to zero
Resize(p.Size());
return *this;
}
PluginData::~PluginData()
{
DeleteAll();
}
size_t PluginData::Size() const
{
return table.size();
}
void PluginData::Resize(size_t new_size)
{
size_t old_size = table.size();
if( old_size == new_size )
return;
table.resize(new_size);
for(size_t i = old_size ; i<new_size ; ++i)
table[i] = 0;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreplugindata
#define headerfilecmslucoreplugindata
#include <vector>
struct PluginDataBase
{
virtual ~PluginDataBase() {}
};
class PluginData
{
public:
void Assign(size_t index, PluginDataBase * data);
void Assign(PluginDataBase * data);
PluginDataBase * Get(size_t index);
PluginDataBase * Get();
void DeleteAll();
PluginData();
PluginData(const PluginData & p);
PluginData & operator=(const PluginData & p);
~PluginData();
size_t Size() const;
void Resize(size_t new_size);
private:
std::vector<PluginDataBase*> table;
};
#endif
+50
View File
@@ -0,0 +1,50 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslupluginmsg
#define headerfilecmslupluginmsg
// here you can add your own EZC functions ([function])
// PluginInfo.p1 is a pointer to Ezc::Functions object
#define WINIX_TEMPLATES_CREATEFUNCTIONS 999
#define WINIX_REQUEST_CLEAR 1000
#define WINIX_CONTENT_MAKE 2000
// here you can attach your own session data (based on PluginDataBase class)
// call request.session->plugin_data.Assign(pointer)
#define WINIX_SESSION_CREATED 3000
// here you should remove your session data
#define WINIX_SESSION_REMOVE 3001
// when a session is changed (you can save a pointer to your data here)
#define WINIX_SESSION_CHANGED 3002
// the winix is closing
#define WINIX_CLOSE 3004
// item was removed (rm function)
// PluginInfo::l1 is the file (item) id
#define WINIX_FILE_REMOVED 3005
// directory was removed (rm function)
// PluginInfo::l1 is the dir id
#define WINIX_DIR_REMOVED 3006
// preparing to remove a directory (rm function)
// PluginInfo::l1 is the dir id
#define WINIX_DIR_PREPARE_TO_REMOVE 3007
#endif
+565
View File
@@ -0,0 +1,565 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "postmultiparser.h"
#include "log.h"
PostMultiParser::PostMultiParser()
{
in_buffer = new unsigned char[WINIX_POSTMULTI_INPUT_BUFFER];
}
PostMultiParser::PostMultiParser(const PostMultiParser & p)
{
in_buffer = new unsigned char[WINIX_POSTMULTI_INPUT_BUFFER];
config = p.config;
}
PostMultiParser & PostMultiParser::operator=(const PostMultiParser & p)
{
in_buffer = new unsigned char[WINIX_POSTMULTI_INPUT_BUFFER];
config = p.config;
return *this;
}
PostMultiParser::~PostMultiParser()
{
delete [] in_buffer;
}
void PostMultiParser::SetConfig(Config * pconfig)
{
config = pconfig;
}
void PostMultiParser::ReadBoundary()
{
boundary.clear();
while( last != -1 && last != 10 && last != 13 )
{
boundary += last;
ReadChar();
}
if( last == 13 )
{
ReadChar();
line_end_dos = true;
}
if( last == 10 )
ReadChar();
}
bool PostMultiParser::IsWhite(int c)
{
if( c==' ' || c=='\t' || c==13 )
return true;
return false;
}
void PostMultiParser::SkipWhite()
{
while( IsWhite(last) )
ReadChar();
}
bool PostMultiParser::IsHeader()
{
SkipWhite();
if( last == 10 )
{
ReadChar();
return false;
}
return true;
}
void PostMultiParser::ReadHeaderName()
{
SkipWhite();
while( last!=-1 && last!=':' && last!='=' && !IsWhite(last) && last!=10 )
{
header_name += last;
ReadChar();
}
SkipWhite();
if( last != ':' && last != '=' )
{
err = WINIX_ERR_BROKEN_INPUT;
return;
}
ReadChar();
}
void PostMultiParser::ReadHeaderValue()
{
bool was_apost = false;
SkipWhite();
if( last == '"' )
{
was_apost = true;
ReadChar();
}
while( last!=-1 && last!=10 &&
((!was_apost && last!=';' && !IsWhite(last)) || (was_apost && last!='"')))
{
header_value += last;
ReadChar();
}
if( was_apost )
{
if( last != '"' )
{
err = WINIX_ERR_BROKEN_INPUT;
return;
}
ReadChar();
}
SkipWhite();
if( last != ';' && last != 10 )
{
err = WINIX_ERR_BROKEN_INPUT;
return;
}
ReadChar();
}
void PostMultiParser::ReadPartHeader()
{
header_name.clear();
header_value.clear();
ReadHeaderName();
if( err != WINIX_ERR_OK )
return;
ReadHeaderValue();
if( err != WINIX_ERR_OK )
return;
log << "PMP: " << header_name << ": " << header_value << logend;
if( header_name == "name" )
name = header_value;
if( header_name == "filename" )
filename = header_value;
}
bool PostMultiParser::HasBoundary()
{
if( content.size() < boundary.size() )
return false;
size_t c = content.size() - boundary.size();
size_t b = 0;
for( ; c<content.size() ; ++c, ++b)
{
if( content[c] != boundary[b] )
return false;
}
return true;
}
void PostMultiParser::LogFirst(const std::string & to_log, size_t len)
{
size_t i;
if( len > to_log.size() )
len = to_log.size();
log << log3 << "PMP: Content (";
if( len > 0 )
log << "len: " << to_log.size() << ", first " << len << " bytes";
else
log << "empty";
log << "): \"";
for(i=0 ; i<len ; ++i)
{
if( to_log[i] < 32 )
log << '.';
else
log << to_log[i];
}
log << "\"" << logend;
}
void PostMultiParser::ReadContentSkipBoundary(bool has_boundary)
{
if( has_boundary )
content.erase(content.size()-boundary.size());
// the last new line character doesn't belong to the content
if( !content.empty() && content[content.size()-1] == 10 )
{
content.erase(content.size()-1);
if( line_end_dos && !content.empty() && content[content.size()-1] == 13 )
content.erase(content.size()-1);
}
}
void PostMultiParser::ReadContentToFileLoop()
{
bool has_boundary = false;
while( last!=-1 && !(has_boundary=HasBoundary()) )
{
content += last;
ReadChar();
if( content.size() > WINIX_POSTMULTI_OUTPUT_BUFFER + boundary.size() + 2 ) // +2 for the new line character
{
tmp_file.write(content.c_str(), WINIX_POSTMULTI_OUTPUT_BUFFER);
content_len += WINIX_POSTMULTI_OUTPUT_BUFFER;
content.erase(0, WINIX_POSTMULTI_OUTPUT_BUFFER);
}
if( config->post_file_max != 0 && content_len > (size_t)config->post_file_max )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: content greater than " << config->post_file_max << " (skipping)" << logend;
return;
}
}
ReadContentSkipBoundary(has_boundary);
// saving the rest
if( !content.empty() )
{
tmp_file.write(content.c_str(), content.size());
content_len += content.size();
content.clear();
}
}
void PostMultiParser::ReadContentToFile()
{
time_t t1, t2;
content.clear();
content.reserve(WINIX_POSTMULTI_OUTPUT_BUFFER + boundary.size());
content_len = 0;
t1 = time(0);
ReadContentToFileLoop();
tmp_file.close();
log << log2 << "PMP: content size: " << content_len << " bytes" << logend;
t2 = time(0);
if( t2 - t1 > 1 )
log << log2 << "PMP: content read in " << (t2-t1) << " sec" << logend;
}
void PostMultiParser::ReadContentLoop()
{
bool has_boundary = false;
while( last!=-1 && !(has_boundary=HasBoundary()) )
{
content += last;
content_len += 1;
ReadChar();
if( config->post_file_max != 0 && content_len > (size_t)config->post_file_max )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: content greater than " << config->post_file_max << " (skipping)" << logend;
return;
}
}
ReadContentSkipBoundary(has_boundary);
}
void PostMultiParser::ReadContent()
{
content.clear();
content_len = 0;
ReadContentLoop();
log << log2 << "PMP: content size: " << content_len << " bytes" << logend;
LogFirst(content, 200);
}
void PostMultiParser::AddNormalPostVar()
{
if( post_table->size() >= WINIX_POSTTABLE_MAXSIZE )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: more than " << WINIX_POSTTABLE_MAXSIZE << " post variables (skipping)" << logend;
return;
}
std::pair<PostTable::iterator, bool> res = post_table->insert( std::make_pair(name, content) );
bool added = res.second;
log << log2 << "PMP: POST var, name: \"" << name << "\"";
if( !added )
log << log2 << " (skipped)";
log << logend;
}
void PostMultiParser::AddFilePostVar()
{
if( post_file_table->size() >= WINIX_POSTTABLE_MAXSIZE )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: more than " << WINIX_POSTTABLE_MAXSIZE << " post file variables (skipping)" << logend;
return;
}
post_file_temp.filename = filename;
post_file_temp.tmp_filename = tmp_filename;
std::pair<PostFileTable::iterator, bool> res = post_file_table->insert( std::make_pair(name, post_file_temp) );
bool added = res.second;
log << log2 << "PMP: POST FILE var, name: \"" << name << "\"";
if( !added )
log << log2 << " (skipped)";
log << logend;
}
void PostMultiParser::AddPostVar()
{
if( name.empty() )
return;
if( filename.empty() )
{
AddNormalPostVar();
}
else
{
AddFilePostVar();
}
}
void PostMultiParser::CheckBoundaryEnd()
{
if( last == '-' )
{
ReadChar();
if( last != '-' )
{
err = WINIX_ERR_BROKEN_INPUT;
return;
}
// end of parsing
// the rest input (if exists) is ignored
last = -1;
}
// skipping a new line after the boundary
if( last == 13 )
ReadChar();
if( last == 10 )
ReadChar();
}
void PostMultiParser::CreateTmpFile()
{
char buf[100];
if( config->auth_tmp_dir.empty() )
{
log << log1 << "PMP: auth_tmp_dir is not set in the config" << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
sprintf(buf, "%s/winix_%u_%d_%u", config->auth_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);
tmp_filename = buf;
if( !tmp_file )
{
log << log1 << "PMP: can't create a temporary file: " << tmp_filename << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
log << log3 << "PMP: using temporary file for the content: " << tmp_filename << logend;
}
void PostMultiParser::ReadPart()
{
name.clear();
filename.clear();
while( IsHeader() )
ReadPartHeader();
if( err != WINIX_ERR_OK )
return;
if( !filename.empty() )
CreateTmpFile();
if( err != WINIX_ERR_OK )
return;
if( !filename.empty() )
ReadContentToFile();
else
ReadContent();
if( err == WINIX_ERR_OK )
{
AddPostVar();
CheckBoundaryEnd();
}
if( err != WINIX_ERR_OK && !filename.empty() )
{
log << log1 << "PMP: deleting the tmp file: " << tmp_filename << logend;
unlink(tmp_filename.c_str());
}
}
void PostMultiParser::ReadChar()
{
if( last == -1 )
return;
if( in_buffer_ind >= in_buffer_len )
{
if( in_buffer_len < WINIX_POSTMULTI_INPUT_BUFFER )
{
last = -1;
return;
}
in_buffer_len = FCGX_GetStr((char*)in_buffer, WINIX_POSTMULTI_INPUT_BUFFER, in);
in_buffer_ind = 0;
}
if( in_buffer_len == 0 )
{
last = -1;
}
else
{
last = in_buffer[in_buffer_ind];
in_buffer_ind += 1;
}
}
Error PostMultiParser::Parse(FCGX_Stream * in_, PostTable & post_table_, PostFileTable & post_file_table_)
{
in = in_;
last = 0;
err = WINIX_ERR_OK;
line_end_dos = false;
in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER;
in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER;
post_table = &post_table_;
post_file_table = &post_file_table_;
tmp_filename_postfix = 1;
ReadChar();
ReadBoundary();
if( boundary.empty() )
return WINIX_ERR_NO_BOUNDARY;
while( last!=-1 && err == WINIX_ERR_OK )
ReadPart();
if( err != WINIX_ERR_OK )
{
post_table->clear();
post_file_table->clear();
if( err != WINIX_ERR_INPUT_TOO_LARGE && err != WINIX_ERR_CANT_CREATE_FILE )
log << log1 << "PMP: syntax error" << logend;
}
return err;
}
+98
View File
@@ -0,0 +1,98 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorepostmultiparser
#define headerfilecmslucorepostmultiparser
#include <string>
#include <fcgiapp.h>
#include <fstream>
#include "error.h"
#include "requesttypes.h"
#include "config.h"
// 2 MB
#define WINIX_POSTMULTI_INPUT_BUFFER 2097152
#define WINIX_POSTMULTI_OUTPUT_BUFFER 2097152
class PostMultiParser
{
public:
PostMultiParser();
PostMultiParser(const PostMultiParser &);
PostMultiParser & operator=(const PostMultiParser &);
~PostMultiParser();
void SetConfig(Config * pconfig);
Error Parse(FCGX_Stream * in_, PostTable & post_table_, PostFileTable & post_file_table_);
private:
Config * config;
FCGX_Stream * in;
unsigned char * in_buffer;
std::ofstream tmp_file;
std::string tmp_filename;
int tmp_filename_postfix;
size_t in_buffer_ind;
size_t in_buffer_len;
PostTable * post_table;
PostFileTable * post_file_table;
int last; // last read character
bool line_end_dos;
std::string boundary;
std::string content;
size_t content_len;
std::string header_name, header_value;
Error err;
std::string name, filename;
PostFile post_file_temp;
void LogFirst(const std::string & to_log, size_t len);
bool IsWhite(int c);
void SkipWhite();
void AddNormalPostVar();
void AddFilePostVar();
void AddPostVar();
void ReadBoundary();
bool IsHeader();
void ReadHeaderName();
void ReadHeaderValue();
void ReadPartHeader();
void CreateTmpFile();
bool HasBoundary();
void ReadContentSkipBoundary(bool has_boundary);
void ReadContentToFileLoop();
void ReadContentToFile();
void ReadContentLoop();
void ReadContent();
void CheckBoundaryEnd();
void ReadPart();
void ReadChar();
};
#endif
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/

Some files were not shown because too many files have changed in this diff Show More